From a6617863601d98009f27e2a48d4e8fe375f68dcd Mon Sep 17 00:00:00 2001 From: Robert Rostohar Date: Mon, 6 Sep 2021 08:49:19 +0200 Subject: [PATCH] Initial commit --- LICENSE | 201 + .../Board_IO/retarget_stdio.c | 44 + .../RTE/CMSIS/RTX_Config.c | 64 + .../RTE/CMSIS/RTX_Config.h | 580 +++ .../RTE/Compiler/EventRecorderConf.h | 34 + .../RTE/Device/SSE-300-MPS3/RTE_Device.h | 95 + .../Device/SSE-300-MPS3/cmsis_driver_config.h | 25 + .../RTE/Device/SSE-300-MPS3/device_cfg.h | 145 + .../Device/SSE-300-MPS3/fvp_sse300_mps3_s.sct | 78 + .../SSE-300-MPS3/platform_base_address.h | 261 + .../RTE/Device/SSE-300-MPS3/region_defs.h | 49 + .../RTE/Device/SSE-300-MPS3/region_limits.h | 51 + .../SSE-300-MPS3/startup_fvp_sse300_mps3.c | 351 ++ .../Device/SSE-300-MPS3/system_SSE300MPS3.c | 79 + .../Device/SSE-300-MPS3/system_core_init.c | 75 + .../RTE/Machine_Learning/debug_log.cc | 43 + .../RTE/Machine_Learning/micro_time.cc | 67 + .../RTE/Machine_Learning/system_setup.cc | 38 + .../debug.ini | 1 + .../fvp_config.txt | 8 + .../main.c | 47 + .../main.h | 25 + .../microspeech.Audio_Provider_Mock.cprj | 134 + .../microspeech.Example.cprj | 133 + .../microspeech.c | 45 + .../microspeech.uvoptx | 1359 ++++++ .../microspeech.uvprojx | 4277 +++++++++++++++++ .../mps3_config.txt | 6 + .../packlist | 8 + .../run_audio_provider_mock.cmd | 2 + .../run_example.cmd | 2 + .../run_example.sh | 2 + .../test.wav | Bin 0 -> 768044 bytes .../Board_IO/retarget_stdio.c | 74 + .../Driver_Audio/Audio_MIMXRT1064-EVK.c | 604 +++ .../Driver_Audio/Audio_MIMXRT1064-EVK.h | 60 + .../Driver_Audio/Config_Audio.h | 22 + .../Driver_Audio/Config_WM8960.h | 24 + Platform_MIMXRT1064-EVK/MIMXRT1064-EVK.mex | 1147 +++++ Platform_MIMXRT1064-EVK/README.md | 105 + .../RTE/Board_Support/MIMXRT1064DVL6A/board.c | 389 ++ .../RTE/Board_Support/MIMXRT1064DVL6A/board.h | 218 + .../MIMXRT1064DVL6A/clock_config.c | 512 ++ .../MIMXRT1064DVL6A/clock_config.h | 122 + .../RTE/Board_Support/MIMXRT1064DVL6A/dcd.c | 315 ++ .../RTE/Board_Support/MIMXRT1064DVL6A/dcd.h | 32 + .../MIMXRT1064DVL6A/peripherals.c | 24 + .../MIMXRT1064DVL6A/peripherals.h | 28 + .../Board_Support/MIMXRT1064DVL6A/pin_mux.c | 808 ++++ .../Board_Support/MIMXRT1064DVL6A/pin_mux.h | 833 ++++ .../RTE/CMSIS/RTX_Config.c | 64 + .../RTE/CMSIS/RTX_Config.h | 580 +++ .../RTE/Compiler/EventRecorderConf.h | 34 + .../MIMXRT1064xxxxx_flexspi_nor.scf | 118 + .../MIMXRT1064xxxxx_flexspi_nor_sdram.scf | 144 + .../MIMXRT1064DVL6A/MIMXRT1064xxxxx_ram.scf | 84 + .../MIMXRT1064DVL6A/MIMXRT1064xxxxx_sdram.scf | 108 + .../MIMXRT1064xxxxx_sdram_txt.scf | 108 + .../RTE/Device/MIMXRT1064DVL6A/RTE_Device.h | 265 + .../RTE/Machine_Learning/debug_log.cc | 43 + .../RTE/Machine_Learning/micro_time.cc | 67 + .../RTE/Machine_Learning/system_setup.cc | 33 + Platform_MIMXRT1064-EVK/main.c | 92 + Platform_MIMXRT1064-EVK/main.h | 34 + .../microspeech.MIMXRT1064-EVK.cprj | 213 + Platform_MIMXRT1064-EVK/microspeech.c | 45 + Platform_MIMXRT1064-EVK/microspeech.uvguix | 1860 +++++++ Platform_MIMXRT1064-EVK/microspeech.uvoptx | 756 +++ Platform_MIMXRT1064-EVK/microspeech.uvprojx | 1818 +++++++ README.md | 78 + VSI/audio/driver/audio_drv.c | 203 + VSI/audio/include/audio_drv.h | 124 + VSI/audio/python/arm_vsi0.py | 234 + VSI/include/arm_vsi.h | 102 + micro_speech/src/audio_provider.cc | 103 + micro_speech/src/audio_provider.h | 46 + micro_speech/src/audio_provider_mock.cc | 55 + micro_speech/src/audio_provider_mock_test.cc | 76 + micro_speech/src/audio_provider_test.cc | 69 + micro_speech/src/command_responder.cc | 28 + micro_speech/src/command_responder.h | 32 + micro_speech/src/command_responder_test.cc | 31 + micro_speech/src/feature_provider.cc | 120 + micro_speech/src/feature_provider.h | 52 + .../src/feature_provider_mock_test.cc | 64 + micro_speech/src/feature_provider_test.cc | 39 + micro_speech/src/main.cc | 27 + micro_speech/src/main_functions.cc | 193 + micro_speech/src/main_functions.h | 37 + .../micro_features_generator.cc | 116 + .../micro_features/micro_features_generator.h | 32 + .../micro_features_generator_test.cc | 104 + .../micro_features/micro_model_settings.cc | 23 + .../src/micro_features/micro_model_settings.h | 43 + micro_speech/src/micro_features/model.cc | 1596 ++++++ micro_speech/src/micro_features/model.h | 27 + .../micro_features/no_feature_data_slice.cc | 24 + .../micro_features/no_feature_data_slice.h | 29 + .../micro_features/no_micro_features_data.cc | 188 + .../micro_features/no_micro_features_data.h | 23 + .../src/micro_features/static_alloc.h | 33 + .../micro_features/yes_feature_data_slice.cc | 24 + .../micro_features/yes_feature_data_slice.h | 29 + .../micro_features/yes_micro_features_data.cc | 188 + .../micro_features/yes_micro_features_data.h | 23 + micro_speech/src/micro_speech_test.cc | 148 + micro_speech/src/microfrontend/lib/bits.h | 102 + micro_speech/src/microfrontend/lib/fft.cc | 53 + micro_speech/src/microfrontend/lib/fft.h | 50 + .../src/microfrontend/lib/fft_util.cc | 72 + micro_speech/src/microfrontend/lib/fft_util.h | 34 + .../src/microfrontend/lib/filterbank.c | 134 + .../src/microfrontend/lib/filterbank.h | 63 + .../src/microfrontend/lib/filterbank_util.c | 220 + .../src/microfrontend/lib/filterbank_util.h | 50 + micro_speech/src/microfrontend/lib/frontend.c | 72 + micro_speech/src/microfrontend/lib/frontend.h | 64 + .../src/microfrontend/lib/frontend_util.c | 85 + .../src/microfrontend/lib/frontend_util.h | 52 + micro_speech/src/microfrontend/lib/log_lut.c | 30 + micro_speech/src/microfrontend/lib/log_lut.h | 40 + .../src/microfrontend/lib/log_scale.c | 83 + .../src/microfrontend/lib/log_scale.h | 39 + .../src/microfrontend/lib/log_scale_util.c | 27 + .../src/microfrontend/lib/log_scale_util.h | 45 + .../src/microfrontend/lib/noise_reduction.c | 51 + .../src/microfrontend/lib/noise_reduction.h | 46 + .../microfrontend/lib/noise_reduction_util.c | 45 + .../microfrontend/lib/noise_reduction_util.h | 50 + .../src/microfrontend/lib/pcan_gain_control.c | 56 + .../src/microfrontend/lib/pcan_gain_control.h | 47 + .../lib/pcan_gain_control_util.c | 92 + .../lib/pcan_gain_control_util.h | 57 + micro_speech/src/microfrontend/lib/window.c | 70 + micro_speech/src/microfrontend/lib/window.h | 49 + .../src/microfrontend/lib/window_util.c | 73 + .../src/microfrontend/lib/window_util.h | 45 + micro_speech/src/no_1000ms_sample_data.cc | 1477 ++++++ micro_speech/src/no_1000ms_sample_data.h | 29 + micro_speech/src/no_30ms_sample_data.cc | 66 + micro_speech/src/no_30ms_sample_data.h | 32 + micro_speech/src/recognize_commands.cc | 142 + micro_speech/src/recognize_commands.h | 159 + micro_speech/src/recognize_commands_test.cc | 213 + micro_speech/src/yes_1000ms_sample_data.cc | 1800 +++++++ micro_speech/src/yes_1000ms_sample_data.h | 29 + micro_speech/src/yes_30ms_sample_data.cc | 70 + micro_speech/src/yes_30ms_sample_data.h | 32 + 148 files changed, 30520 insertions(+) create mode 100644 LICENSE create mode 100644 Platform_FVP_Corstone_SSE-300_Ethos-U55/Board_IO/retarget_stdio.c create mode 100644 Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/CMSIS/RTX_Config.c create mode 100644 Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/CMSIS/RTX_Config.h create mode 100644 Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Compiler/EventRecorderConf.h create mode 100644 Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Device/SSE-300-MPS3/RTE_Device.h create mode 100644 Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Device/SSE-300-MPS3/cmsis_driver_config.h create mode 100644 Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Device/SSE-300-MPS3/device_cfg.h create mode 100644 Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Device/SSE-300-MPS3/fvp_sse300_mps3_s.sct create mode 100644 Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Device/SSE-300-MPS3/platform_base_address.h create mode 100644 Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Device/SSE-300-MPS3/region_defs.h create mode 100644 Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Device/SSE-300-MPS3/region_limits.h create mode 100644 Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Device/SSE-300-MPS3/startup_fvp_sse300_mps3.c create mode 100644 Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Device/SSE-300-MPS3/system_SSE300MPS3.c create mode 100644 Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Device/SSE-300-MPS3/system_core_init.c create mode 100644 Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Machine_Learning/debug_log.cc create mode 100644 Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Machine_Learning/micro_time.cc create mode 100644 Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Machine_Learning/system_setup.cc create mode 100644 Platform_FVP_Corstone_SSE-300_Ethos-U55/debug.ini create mode 100644 Platform_FVP_Corstone_SSE-300_Ethos-U55/fvp_config.txt create mode 100644 Platform_FVP_Corstone_SSE-300_Ethos-U55/main.c create mode 100644 Platform_FVP_Corstone_SSE-300_Ethos-U55/main.h create mode 100644 Platform_FVP_Corstone_SSE-300_Ethos-U55/microspeech.Audio_Provider_Mock.cprj create mode 100644 Platform_FVP_Corstone_SSE-300_Ethos-U55/microspeech.Example.cprj create mode 100644 Platform_FVP_Corstone_SSE-300_Ethos-U55/microspeech.c create mode 100644 Platform_FVP_Corstone_SSE-300_Ethos-U55/microspeech.uvoptx create mode 100644 Platform_FVP_Corstone_SSE-300_Ethos-U55/microspeech.uvprojx create mode 100644 Platform_FVP_Corstone_SSE-300_Ethos-U55/mps3_config.txt create mode 100644 Platform_FVP_Corstone_SSE-300_Ethos-U55/packlist create mode 100644 Platform_FVP_Corstone_SSE-300_Ethos-U55/run_audio_provider_mock.cmd create mode 100644 Platform_FVP_Corstone_SSE-300_Ethos-U55/run_example.cmd create mode 100644 Platform_FVP_Corstone_SSE-300_Ethos-U55/run_example.sh create mode 100644 Platform_FVP_Corstone_SSE-300_Ethos-U55/test.wav create mode 100644 Platform_MIMXRT1064-EVK/Board_IO/retarget_stdio.c create mode 100644 Platform_MIMXRT1064-EVK/Driver_Audio/Audio_MIMXRT1064-EVK.c create mode 100644 Platform_MIMXRT1064-EVK/Driver_Audio/Audio_MIMXRT1064-EVK.h create mode 100644 Platform_MIMXRT1064-EVK/Driver_Audio/Config_Audio.h create mode 100644 Platform_MIMXRT1064-EVK/Driver_Audio/Config_WM8960.h create mode 100644 Platform_MIMXRT1064-EVK/MIMXRT1064-EVK.mex create mode 100644 Platform_MIMXRT1064-EVK/README.md create mode 100644 Platform_MIMXRT1064-EVK/RTE/Board_Support/MIMXRT1064DVL6A/board.c create mode 100644 Platform_MIMXRT1064-EVK/RTE/Board_Support/MIMXRT1064DVL6A/board.h create mode 100644 Platform_MIMXRT1064-EVK/RTE/Board_Support/MIMXRT1064DVL6A/clock_config.c create mode 100644 Platform_MIMXRT1064-EVK/RTE/Board_Support/MIMXRT1064DVL6A/clock_config.h create mode 100644 Platform_MIMXRT1064-EVK/RTE/Board_Support/MIMXRT1064DVL6A/dcd.c create mode 100644 Platform_MIMXRT1064-EVK/RTE/Board_Support/MIMXRT1064DVL6A/dcd.h create mode 100644 Platform_MIMXRT1064-EVK/RTE/Board_Support/MIMXRT1064DVL6A/peripherals.c create mode 100644 Platform_MIMXRT1064-EVK/RTE/Board_Support/MIMXRT1064DVL6A/peripherals.h create mode 100644 Platform_MIMXRT1064-EVK/RTE/Board_Support/MIMXRT1064DVL6A/pin_mux.c create mode 100644 Platform_MIMXRT1064-EVK/RTE/Board_Support/MIMXRT1064DVL6A/pin_mux.h create mode 100644 Platform_MIMXRT1064-EVK/RTE/CMSIS/RTX_Config.c create mode 100644 Platform_MIMXRT1064-EVK/RTE/CMSIS/RTX_Config.h create mode 100644 Platform_MIMXRT1064-EVK/RTE/Compiler/EventRecorderConf.h create mode 100644 Platform_MIMXRT1064-EVK/RTE/Device/MIMXRT1064DVL6A/MIMXRT1064xxxxx_flexspi_nor.scf create mode 100644 Platform_MIMXRT1064-EVK/RTE/Device/MIMXRT1064DVL6A/MIMXRT1064xxxxx_flexspi_nor_sdram.scf create mode 100644 Platform_MIMXRT1064-EVK/RTE/Device/MIMXRT1064DVL6A/MIMXRT1064xxxxx_ram.scf create mode 100644 Platform_MIMXRT1064-EVK/RTE/Device/MIMXRT1064DVL6A/MIMXRT1064xxxxx_sdram.scf create mode 100644 Platform_MIMXRT1064-EVK/RTE/Device/MIMXRT1064DVL6A/MIMXRT1064xxxxx_sdram_txt.scf create mode 100644 Platform_MIMXRT1064-EVK/RTE/Device/MIMXRT1064DVL6A/RTE_Device.h create mode 100644 Platform_MIMXRT1064-EVK/RTE/Machine_Learning/debug_log.cc create mode 100644 Platform_MIMXRT1064-EVK/RTE/Machine_Learning/micro_time.cc create mode 100644 Platform_MIMXRT1064-EVK/RTE/Machine_Learning/system_setup.cc create mode 100644 Platform_MIMXRT1064-EVK/main.c create mode 100644 Platform_MIMXRT1064-EVK/main.h create mode 100644 Platform_MIMXRT1064-EVK/microspeech.MIMXRT1064-EVK.cprj create mode 100644 Platform_MIMXRT1064-EVK/microspeech.c create mode 100644 Platform_MIMXRT1064-EVK/microspeech.uvguix create mode 100644 Platform_MIMXRT1064-EVK/microspeech.uvoptx create mode 100644 Platform_MIMXRT1064-EVK/microspeech.uvprojx create mode 100644 README.md create mode 100644 VSI/audio/driver/audio_drv.c create mode 100644 VSI/audio/include/audio_drv.h create mode 100644 VSI/audio/python/arm_vsi0.py create mode 100644 VSI/include/arm_vsi.h create mode 100644 micro_speech/src/audio_provider.cc create mode 100644 micro_speech/src/audio_provider.h create mode 100644 micro_speech/src/audio_provider_mock.cc create mode 100644 micro_speech/src/audio_provider_mock_test.cc create mode 100644 micro_speech/src/audio_provider_test.cc create mode 100644 micro_speech/src/command_responder.cc create mode 100644 micro_speech/src/command_responder.h create mode 100644 micro_speech/src/command_responder_test.cc create mode 100644 micro_speech/src/feature_provider.cc create mode 100644 micro_speech/src/feature_provider.h create mode 100644 micro_speech/src/feature_provider_mock_test.cc create mode 100644 micro_speech/src/feature_provider_test.cc create mode 100644 micro_speech/src/main.cc create mode 100644 micro_speech/src/main_functions.cc create mode 100644 micro_speech/src/main_functions.h create mode 100644 micro_speech/src/micro_features/micro_features_generator.cc create mode 100644 micro_speech/src/micro_features/micro_features_generator.h create mode 100644 micro_speech/src/micro_features/micro_features_generator_test.cc create mode 100644 micro_speech/src/micro_features/micro_model_settings.cc create mode 100644 micro_speech/src/micro_features/micro_model_settings.h create mode 100644 micro_speech/src/micro_features/model.cc create mode 100644 micro_speech/src/micro_features/model.h create mode 100644 micro_speech/src/micro_features/no_feature_data_slice.cc create mode 100644 micro_speech/src/micro_features/no_feature_data_slice.h create mode 100644 micro_speech/src/micro_features/no_micro_features_data.cc create mode 100644 micro_speech/src/micro_features/no_micro_features_data.h create mode 100644 micro_speech/src/micro_features/static_alloc.h create mode 100644 micro_speech/src/micro_features/yes_feature_data_slice.cc create mode 100644 micro_speech/src/micro_features/yes_feature_data_slice.h create mode 100644 micro_speech/src/micro_features/yes_micro_features_data.cc create mode 100644 micro_speech/src/micro_features/yes_micro_features_data.h create mode 100644 micro_speech/src/micro_speech_test.cc create mode 100644 micro_speech/src/microfrontend/lib/bits.h create mode 100644 micro_speech/src/microfrontend/lib/fft.cc create mode 100644 micro_speech/src/microfrontend/lib/fft.h create mode 100644 micro_speech/src/microfrontend/lib/fft_util.cc create mode 100644 micro_speech/src/microfrontend/lib/fft_util.h create mode 100644 micro_speech/src/microfrontend/lib/filterbank.c create mode 100644 micro_speech/src/microfrontend/lib/filterbank.h create mode 100644 micro_speech/src/microfrontend/lib/filterbank_util.c create mode 100644 micro_speech/src/microfrontend/lib/filterbank_util.h create mode 100644 micro_speech/src/microfrontend/lib/frontend.c create mode 100644 micro_speech/src/microfrontend/lib/frontend.h create mode 100644 micro_speech/src/microfrontend/lib/frontend_util.c create mode 100644 micro_speech/src/microfrontend/lib/frontend_util.h create mode 100644 micro_speech/src/microfrontend/lib/log_lut.c create mode 100644 micro_speech/src/microfrontend/lib/log_lut.h create mode 100644 micro_speech/src/microfrontend/lib/log_scale.c create mode 100644 micro_speech/src/microfrontend/lib/log_scale.h create mode 100644 micro_speech/src/microfrontend/lib/log_scale_util.c create mode 100644 micro_speech/src/microfrontend/lib/log_scale_util.h create mode 100644 micro_speech/src/microfrontend/lib/noise_reduction.c create mode 100644 micro_speech/src/microfrontend/lib/noise_reduction.h create mode 100644 micro_speech/src/microfrontend/lib/noise_reduction_util.c create mode 100644 micro_speech/src/microfrontend/lib/noise_reduction_util.h create mode 100644 micro_speech/src/microfrontend/lib/pcan_gain_control.c create mode 100644 micro_speech/src/microfrontend/lib/pcan_gain_control.h create mode 100644 micro_speech/src/microfrontend/lib/pcan_gain_control_util.c create mode 100644 micro_speech/src/microfrontend/lib/pcan_gain_control_util.h create mode 100644 micro_speech/src/microfrontend/lib/window.c create mode 100644 micro_speech/src/microfrontend/lib/window.h create mode 100644 micro_speech/src/microfrontend/lib/window_util.c create mode 100644 micro_speech/src/microfrontend/lib/window_util.h create mode 100644 micro_speech/src/no_1000ms_sample_data.cc create mode 100644 micro_speech/src/no_1000ms_sample_data.h create mode 100644 micro_speech/src/no_30ms_sample_data.cc create mode 100644 micro_speech/src/no_30ms_sample_data.h create mode 100644 micro_speech/src/recognize_commands.cc create mode 100644 micro_speech/src/recognize_commands.h create mode 100644 micro_speech/src/recognize_commands_test.cc create mode 100644 micro_speech/src/yes_1000ms_sample_data.cc create mode 100644 micro_speech/src/yes_1000ms_sample_data.h create mode 100644 micro_speech/src/yes_30ms_sample_data.cc create mode 100644 micro_speech/src/yes_30ms_sample_data.h diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/LICENSE @@ -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_FVP_Corstone_SSE-300_Ethos-U55/Board_IO/retarget_stdio.c b/Platform_FVP_Corstone_SSE-300_Ethos-U55/Board_IO/retarget_stdio.c new file mode 100644 index 0000000..aeaa39c --- /dev/null +++ b/Platform_FVP_Corstone_SSE-300_Ethos-U55/Board_IO/retarget_stdio.c @@ -0,0 +1,44 @@ +/* ----------------------------------------------------------------------------- + * Copyright (c) 2020 Arm Limited (or its affiliates). All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * -------------------------------------------------------------------------- */ + +#include +#include +#include "device_cfg.h" +#include "Driver_USART.h" + +extern ARM_DRIVER_USART Driver_USART0; + +void stdio_init (void) { + Driver_USART0.Initialize(NULL); + Driver_USART0.Control(ARM_USART_MODE_ASYNCHRONOUS, 115200U); +} + +/** + Put a character to the stdout + + \param[in] ch Character to output + \return The character written, or -1 on write error. +*/ +int stdout_putchar (int ch) { + int32_t ret; + + if (Driver_USART0.Send(&ch, 1U) == ARM_DRIVER_OK) { + return ch; + } + return EOF; +} diff --git a/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/CMSIS/RTX_Config.c b/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/CMSIS/RTX_Config.c new file mode 100644 index 0000000..737078a --- /dev/null +++ b/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/CMSIS/RTX_Config.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2013-2021 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ----------------------------------------------------------------------------- + * + * $Revision: V5.1.1 + * + * Project: CMSIS-RTOS RTX + * Title: RTX Configuration + * + * ----------------------------------------------------------------------------- + */ + +#include "cmsis_compiler.h" +#include "rtx_os.h" + +// OS Idle Thread +__WEAK __NO_RETURN void osRtxIdleThread (void *argument) { + (void)argument; + + for (;;) {} +} + +// OS Error Callback function +__WEAK uint32_t osRtxErrorNotify (uint32_t code, void *object_id) { + (void)object_id; + + switch (code) { + case osRtxErrorStackOverflow: + // 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; + } + for (;;) {} +//return 0U; +} diff --git a/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/CMSIS/RTX_Config.h b/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/CMSIS/RTX_Config.h new file mode 100644 index 0000000..d502762 --- /dev/null +++ b/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/CMSIS/RTX_Config.h @@ -0,0 +1,580 @@ +/* + * Copyright (c) 2013-2021 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ----------------------------------------------------------------------------- + * + * $Revision: V5.5.2 + * + * 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: 32768 +#ifndef OS_DYNAMIC_MEM_SIZE +#define OS_DYNAMIC_MEM_SIZE 32768 +#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: 3072 +#ifndef OS_STACK_SIZE +#define OS_STACK_SIZE 3072 +#endif + +// Idle Thread Stack size [bytes] <72-1073741824:8> +// Defines stack size for Idle thread. +// Default: 512 +#ifndef OS_IDLE_THREAD_STACK_SIZE +#define OS_IDLE_THREAD_STACK_SIZE 512 +#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 (requires RTX source variant). +// Enabling this option increases slightly the execution time of a thread switch. +#ifndef OS_STACK_CHECK +#define OS_STACK_CHECK 0 +#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 1 +#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: 512 +#ifndef OS_TIMER_THREAD_STACK_SIZE +#define OS_TIMER_THREAD_STACK_SIZE 512 +#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 4 +#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 1 +#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 0x81U +#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 0x81U +#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 0x85U +#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 0x81U +#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 0x81U +#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 0x81U +#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 0x81U +#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 0x81U +#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 0x81U +#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 0x81U +#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 0x81U +#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) +#ifndef OS_THREAD_LIBSPACE_NUM +#define OS_THREAD_LIBSPACE_NUM 4 +#endif +#else +#define OS_THREAD_LIBSPACE_NUM OS_THREAD_NUM +#endif + +//------------- <<< end of configuration section >>> --------------------------- + +#endif // RTX_CONFIG_H_ diff --git a/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Compiler/EventRecorderConf.h b/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Compiler/EventRecorderConf.h new file mode 100644 index 0000000..75de150 --- /dev/null +++ b/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Compiler/EventRecorderConf.h @@ -0,0 +1,34 @@ +/*------------------------------------------------------------------------------ + * MDK - Component ::Event Recorder + * Copyright (c) 2016-2018 ARM Germany GmbH. All rights reserved. + *------------------------------------------------------------------------------ + * Name: EventRecorderConf.h + * Purpose: Event Recorder Configuration + * Rev.: V1.1.0 + *----------------------------------------------------------------------------*/ + +//-------- <<< Use Configuration Wizard in Context Menu >>> -------------------- + +// Event Recorder + +// Number of Records +// <8=>8 <16=>16 <32=>32 <64=>64 <128=>128 <256=>256 <512=>512 <1024=>1024 +// <2048=>2048 <4096=>4096 <8192=>8192 <16384=>16384 <32768=>32768 +// <65536=>65536 +// Configures size of Event Record Buffer (each record is 16 bytes) +// Must be 2^n (min=8, max=65536) +#define EVENT_RECORD_COUNT 1024U + +// Time Stamp Source +// <0=> DWT Cycle Counter <1=> SysTick <2=> CMSIS-RTOS2 System Timer +// <3=> User Timer (Normal Reset) <4=> User Timer (Power-On Reset) +// Selects source for 32-bit time stamp +#define EVENT_TIMESTAMP_SOURCE 0 + +// Time Stamp Clock Frequency [Hz] <0-1000000000> +// Defines initial time stamp clock frequency (0 when not used) +#define EVENT_TIMESTAMP_FREQ 25000000U + +// + +//------------- <<< end of configuration section >>> --------------------------- diff --git a/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Device/SSE-300-MPS3/RTE_Device.h b/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Device/SSE-300-MPS3/RTE_Device.h new file mode 100644 index 0000000..8de4d3a --- /dev/null +++ b/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Device/SSE-300-MPS3/RTE_Device.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2019-2020 Arm Limited. All rights reserved. + * + * Licensed under the Apache License, Version 2.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 __RTE_DEVICE_H +#define __RTE_DEVICE_H + +// USART (Universal synchronous - asynchronous receiver transmitter) [Driver_USART0] +// Configuration settings for Driver_USART0 in component ::Drivers:USART +#define RTE_USART0 1 +// USART (Universal synchronous - asynchronous receiver transmitter) [Driver_USART0] + +// USART (Universal synchronous - asynchronous receiver transmitter) [Driver_USART1] +// Configuration settings for Driver_USART1 in component ::Drivers:USART +#define RTE_USART1 1 +// USART (Universal synchronous - asynchronous receiver transmitter) [Driver_USART1] + +// MPC (Memory Protection Controller) [Driver_ISRAM0_MPC] +// Configuration settings for Driver_ISRAM0_MPC in component ::Drivers:MPC +#define RTE_ISRAM0_MPC 1 +// MPC (Memory Protection Controller) [Driver_ISRAM0_MPC] + +// MPC (Memory Protection Controller) [Driver_ISRAM1_MPC] +// Configuration settings for Driver_ISRAM1_MPC in component ::Drivers:MPC +#define RTE_ISRAM1_MPC 1 +// MPC (Memory Protection Controller) [Driver_ISRAM1_MPC] + +// MPC (Memory Protection Controller) [Driver_SRAM_MPC] +// Configuration settings for Driver_SRAM_MPC in component ::Drivers:MPC +#define RTE_SRAM_MPC 1 +// MPC (Memory Protection Controller) [Driver_SRAM_MPC] + +// MPC (Memory Protection Controller) [Driver_QSPI_MPC] +// Configuration settings for Driver_QSPI_MPC in component ::Drivers:MPC +#define RTE_QSPI_MPC 1 +// MPC (Memory Protection Controller) [Driver_QSPI_MPC] + +// PPC (Peripheral Protection Controller) [PPC_SSE300_MAIN0] +// Configuration settings for Driver_PPC_SSE300_MAIN0 in component ::Drivers:PPC +#define RTE_PPC_SSE300_MAIN0 1 +// PPC (Peripheral Protection Controller) [Driver_PPC_SSE300_MAIN0] + +// PPC (Peripheral Protection Controller) [PPC_SSE300_MAIN_EXP0] +// Configuration settings for Driver_PPC_SSE300_MAIN_EXP0 in component ::Drivers:PPC +#define RTE_PPC_SSE300_MAIN_EXP0 1 +// PPC (Peripheral Protection Controller) [Driver_PPC_SSE300_MAIN_EXP0] + +// PPC (Peripheral Protection Controller) [PPC_SSE300_MAIN_EXP1] +// Configuration settings for Driver_PPC_SSE300_MAIN_EXP1 in component ::Drivers:PPC +#define RTE_PPC_SSE300_MAIN_EXP1 1 +// PPC (Peripheral Protection Controller) [Driver_PPC_SSE300_MAIN_EXP1] + +// PPC (Peripheral Protection Controller) [PPC_SSE300_PERIPH0] +// Configuration settings for Driver_PPC_SSE300_PERIPH0 in component ::Drivers:PPC +#define RTE_PPC_SSE300_PERIPH0 1 +// PPC (Peripheral Protection Controller) [Driver_PPC_SSE300_PERIPH0] + +// PPC (Peripheral Protection Controller) [PPC_SSE300_PERIPH1] +// Configuration settings for Driver_PPC_SSE300_PERIPH1 in component ::Drivers:PPC +#define RTE_PPC_SSE300_PERIPH1 1 +// PPC (Peripheral Protection Controller) [Driver_PPC_SSE300_PERIPH1] + +// PPC (Peripheral Protection Controller) [PPC_SSE300_PERIPH_EXP0] +// Configuration settings for Driver_PPC_SSE300_PERIPH_EXP0 in component ::Drivers:PPC +#define RTE_PPC_SSE300_PERIPH_EXP0 1 +// PPC (Peripheral Protection Controller) [Driver_PPC_SSE300_PERIPH_EXP0] + +// PPC (Peripheral Protection Controller) [PPC_SSE300_PERIPH_EXP1] +// Configuration settings for Driver_PPC_SSE300_PERIPH_EXP1 in component ::Drivers:PPC +#define RTE_PPC_SSE300_PERIPH_EXP1 1 +// PPC (Peripheral Protection Controller) [Driver_PPC_SSE300_PERIPH_EXP1] + +// PPC (Peripheral Protection Controller) [PPC_SSE300_PERIPH_EXP2] +// Configuration settings for Driver_PPC_SSE300_PERIPH_EXP2 in component ::Drivers:PPC +#define RTE_PPC_SSE300_PERIPH_EXP2 1 +// PPC (Peripheral Protection Controller) [Driver_PPC_SSE300_PERIPH_EXP2] + +// Flash device emulated by SRAM [Driver_Flash0] +// Configuration settings for Driver_Flash0 in component ::Drivers:Flash +#define RTE_FLASH0 1 +// Flash device emulated by SRAM [Driver_Flash0] + +#endif /* __RTE_DEVICE_H */ diff --git a/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Device/SSE-300-MPS3/cmsis_driver_config.h b/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Device/SSE-300-MPS3/cmsis_driver_config.h new file mode 100644 index 0000000..5ad6fb6 --- /dev/null +++ b/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Device/SSE-300-MPS3/cmsis_driver_config.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2019-2020 Arm Limited. All rights reserved. + * + * Licensed under the Apache License, Version 2.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_DRIVER_CONFIG_H__ +#define __CMSIS_DRIVER_CONFIG_H__ + +#include "system_core_init.h" +#include "device_cfg.h" +#include "device_definition.h" +#include "platform_base_address.h" + +#endif /* __CMSIS_DRIVER_CONFIG_H__ */ diff --git a/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Device/SSE-300-MPS3/device_cfg.h b/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Device/SSE-300-MPS3/device_cfg.h new file mode 100644 index 0000000..d3591f2 --- /dev/null +++ b/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Device/SSE-300-MPS3/device_cfg.h @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2020-2021 Arm Limited. All rights reserved. + * + * Licensed under the Apache License Version 2.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 __DEVICE_CFG_H__ +#define __DEVICE_CFG_H__ + +/** + * \file device_cfg.h + * \brief Configuration file native driver re-targeting + * + * \details This file can be used to add native driver specific macro + * definitions to select which peripherals are available in the build. + * + * This is a default device configuration file with all peripherals enabled. + */ + +/* Secure only peripheral configuration */ + +/* ARM MPS3 IO SCC */ +#define MPS3_IO_S +#define MPS3_IO_DEV MPS3_IO_DEV_S + +/* ARM UART Controller PL011 */ +#define UART0_CMSDK_S +#define UART0_CMSDK_DEV UART0_CMSDK_DEV_S +#define UART1_CMSDK_S +#define UART1_CMSDK_DEV UART1_CMSDK_DEV_S + +#define DEFAULT_UART_BAUDRATE 115200U + +/* To be used as CODE and DATA sram */ +#define MPC_ISRAM0_S +#define MPC_ISRAM0_DEV MPC_ISRAM0_DEV_S + +#define MPC_ISRAM1_S +#define MPC_ISRAM1_DEV MPC_ISRAM0_DEV_S + +#define MPC_SRAM_S +#define MPC_SRAM_DEV MPC_SRAM_DEV_S + +#define MPC_QSPI_S +#define MPC_QSPI_DEV MPC_QSPI_DEV_S + +/** System Counter Armv8-M */ +#define SYSCOUNTER_CNTRL_ARMV8_M_S +#define SYSCOUNTER_CNTRL_ARMV8_M_DEV SYSCOUNTER_CNTRL_ARMV8_M_DEV_S + +#define SYSCOUNTER_READ_ARMV8_M_S +#define SYSCOUNTER_READ_ARMV8_M_DEV SYSCOUNTER_READ_ARMV8_M_DEV_S +/** + * Arbitrary scaling values for test purposes + */ +#define SYSCOUNTER_ARMV8_M_DEFAULT_SCALE0_INT 1u +#define SYSCOUNTER_ARMV8_M_DEFAULT_SCALE0_FRACT 0u +#define SYSCOUNTER_ARMV8_M_DEFAULT_SCALE1_INT 1u +#define SYSCOUNTER_ARMV8_M_DEFAULT_SCALE1_FRACT 0u + +/* System timer */ +#define SYSTIMER0_ARMV8_M_S +#define SYSTIMER0_ARMV8_M_DEV SYSTIMER0_ARMV8_M_DEV_S +#define SYSTIMER1_ARMV8_M_S +#define SYSTIMER1_ARMV8_M_DEV SYSTIMER1_ARMV8_M_DEV_S +#define SYSTIMER2_ARMV8_M_S +#define SYSTIMER2_ARMV8_M_DEV SYSTIMER2_ARMV8_M_DEV_S +#define SYSTIMER3_ARMV8_M_S +#define SYSTIMER3_ARMV8_M_DEV SYSTIMER3_ARMV8_M_DEV_S + +#define SYSTIMER0_ARMV8M_DEFAULT_FREQ_HZ (25000000ul) +#define SYSTIMER1_ARMV8M_DEFAULT_FREQ_HZ (25000000ul) +#define SYSTIMER2_ARMV8M_DEFAULT_FREQ_HZ (25000000ul) +#define SYSTIMER3_ARMV8M_DEFAULT_FREQ_HZ (25000000ul) + +/* CMSDK GPIO driver structures */ +#define GPIO0_CMSDK_S +#define GPIO0_CMSDK_DEV GPIO0_CMSDK_DEV_S +#define GPIO1_CMSDK_S +#define GPIO1_CMSDK_DEV GPIO1_CMSDK_DEV_S +#define GPIO2_CMSDK_S +#define GPIO2_CMSDK_DEV GPIO2_CMSDK_DEV_S +#define GPIO3_CMSDK_S +#define GPIO3_CMSDK_DEV GPIO3_CMSDK_DEV_S + +/* ARM MPS3 IO FPGAIO driver structures */ +#define ARM_MPS3_IO_FPGAIO_S +#define ARM_MPS3_IO_FPGAIO_DEV ARM_MPS3_IO_FPGAIO_DEV_S + +/* System Watchdogs */ +#define SYSWDOG_ARMV8_M_S +#define SYSWDOG_ARMV8_M_DEV SYSWDOG_ARMV8_M_DEV_S + +/* ARM MPC SIE 300 driver structures */ +#define MPC_VM0_S +#define MPC_VM0_DEV MPC_VM0_DEV_S +#define MPC_VM1_S +#define MPC_VM1_DEV MPC_VM1_DEV_S +#define MPC_SSRAM2_S +#define MPC_SSRAM2_DEV MPC_SSRAM2_DEV_S +#define MPC_SSRAM3_S +#define MPC_SSRAM3_DEV MPC_SSRAM3_DEV_S + +/* ARM PPC driver structures */ +#define PPC_SSE300_MAIN0_S +#define PPC_SSE300_MAIN0_DEV PPC_SSE300_MAIN0_DEV_S +#define PPC_SSE300_MAIN_EXP0_S +#define PPC_SSE300_MAIN_EXP0_DEV PPC_SSE300_MAIN_EXP0_DEV_S +#define PPC_SSE300_MAIN_EXP1_S +#define PPC_SSE300_MAIN_EXP1_DEV PPC_SSE300_MAIN_EXP1_DEV_S +#define PPC_SSE300_MAIN_EXP2_S +#define PPC_SSE300_MAIN_EXP2_DEV PPC_SSE300_MAIN_EXP2_DEV_S +#define PPC_SSE300_MAIN_EXP3_S +#define PPC_SSE300_MAIN_EXP3_DEV PPC_SSE300_MAIN_EXP3_DEV_S +#define PPC_SSE300_PERIPH0_S +#define PPC_SSE300_PERIPH0_DEV PPC_SSE300_PERIPH0_DEV_S +#define PPC_SSE300_PERIPH1_S +#define PPC_SSE300_PERIPH1_DEV PPC_SSE300_PERIPH1_DEV_S +#define PPC_SSE300_PERIPH_EXP0_S +#define PPC_SSE300_PERIPH_EXP0_DEV PPC_SSE300_PERIPH_EXP0_DEV_S +#define PPC_SSE300_PERIPH_EXP1_S +#define PPC_SSE300_PERIPH_EXP1_DEV PPC_SSE300_PERIPH_EXP1_DEV_S +#define PPC_SSE300_PERIPH_EXP2_S +#define PPC_SSE300_PERIPH_EXP2_DEV PPC_SSE300_PERIPH_EXP2_DEV_S +#define PPC_SSE300_PERIPH_EXP3_S +#define PPC_SSE300_PERIPH_EXP3_DEV PPC_SSE300_PERIPH_EXP3_DEV_S + +/* ARM SPI PL022 */ +/* Invalid device stubs are not defined */ +#define DEFAULT_SPI_SPEED_HZ 4000000U /* 4MHz */ +#define SPI1_PL022_S +#define SPI1_PL022_DEV SPI1_PL022_DEV_S + + +#endif /* __DEVICE_CFG_H__ */ \ No newline at end of file diff --git a/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Device/SSE-300-MPS3/fvp_sse300_mps3_s.sct b/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Device/SSE-300-MPS3/fvp_sse300_mps3_s.sct new file mode 100644 index 0000000..2f9f930 --- /dev/null +++ b/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Device/SSE-300-MPS3/fvp_sse300_mps3_s.sct @@ -0,0 +1,78 @@ +#! armclang --target=arm-arm-none-eabi -mcpu=cortex-m55+nomve+nofp -E -xc + +;/* +; * Copyright (c) 2018-2021 Arm Limited. All rights reserved. +; * +; * Licensed under the Apache License, Version 2.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 "region_defs.h" + +LR_CODE S_CODE_START { + ER_CODE S_CODE_START { + *.o (RESET +First) + .ANY (+RO) + } + + /* + * Place the CMSE Veneers (containing the SG instruction) after the code, in + * a separate 32 bytes aligned region so that the SAU can programmed to just + * set this region as Non-Secure Callable. The maximum size of this + * executable region makes it only used the space left over by the ER_CODE + * region so that you can rely on code+veneer size combined will not exceed + * the S_CODE_SIZE value. We also substract from the available space the + * area used to align this section on 32 bytes boundary (for SAU conf). + */ + ER_CODE_CMSE_VENEER +0 ALIGN 32 { + *(Veneer$$CMSE) + } + /* + * This dummy region ensures that the next one will be aligned on a 32 bytes + * boundary, so that the following region will not be mistakenly configured + * as Non-Secure Callable by the SAU. + */ + ER_CODE_CMSE_VENEER_DUMMY +0 ALIGN 32 EMPTY 0 {} + + /* This empty, zero long execution region is here to mark the limit address + * of the last execution region that is allocated in SRAM. + */ + CODE_WATERMARK +0 EMPTY 0x0 { + } + /* Make sure that the sections allocated in the SRAM does not exceed the + * size of the SRAM available. + */ + ScatterAssert(ImageLimit(CODE_WATERMARK) <= S_CODE_START + S_CODE_SIZE) + + ER_DATA S_DATA_START { + .ANY (+ZI +RW) + } + + #if HEAP_SIZE > 0 + ARM_LIB_HEAP +0 ALIGN 8 EMPTY HEAP_SIZE { ; Reserve empty region for heap + } + #endif + + ARM_LIB_STACK +0 ALIGN 32 EMPTY STACK_SIZE { ; Reserve empty region for stack + } + + /* This empty, zero long execution region is here to mark the limit address + * of the last execution region that is allocated in SRAM. + */ + SRAM_WATERMARK +0 EMPTY 0x0 { + } + /* Make sure that the sections allocated in the SRAM does not exceed the + * size of the SRAM available. + */ + ScatterAssert(ImageLimit(SRAM_WATERMARK) <= S_DATA_START + S_DATA_SIZE) +} diff --git a/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Device/SSE-300-MPS3/platform_base_address.h b/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Device/SSE-300-MPS3/platform_base_address.h new file mode 100644 index 0000000..c5c3ee7 --- /dev/null +++ b/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Device/SSE-300-MPS3/platform_base_address.h @@ -0,0 +1,261 @@ +/* + * Copyright (c) 2019-2021 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. + */ + +/** + * \file platform_base_address.h + * \brief This file defines all the peripheral base addresses for MPS3 SSE-300 + + * Ethos-U55 AN547 platform. + */ + +#ifndef __PLATFORM_BASE_ADDRESS_H__ +#define __PLATFORM_BASE_ADDRESS_H__ + +/* ======= Defines peripherals memory map addresses ======= */ +/* Non-secure memory map addresses */ +#define ITCM_BASE_NS 0x00000000 /* Instruction TCM Non-Secure base address */ +#define SRAM_BASE_NS 0x01000000 /* CODE SRAM Non-Secure base address */ +#define DTCM0_BASE_NS 0x20000000 /* Data TCM block 0 Non-Secure base address */ +#define DTCM1_BASE_NS 0x20020000 /* Data TCM block 1 Non-Secure base address */ +#define DTCM2_BASE_NS 0x20040000 /* Data TCM block 2 Non-Secure base address */ +#define DTCM3_BASE_NS 0x20060000 /* Data TCM block 3 Non-Secure base address */ +#define ISRAM0_BASE_NS 0x21000000 /* Internal SRAM Area Non-Secure base address */ +#define ISRAM1_BASE_NS 0x21200000 /* Internal SRAM Area Non-Secure base address */ +#define QSPI_SRAM_BASE_NS 0x28000000 /* QSPI SRAM Non-Secure base address */ +/* Non-Secure Subsystem peripheral region */ +#define CPU0_PWRCTRL_BASE_NS 0x40012000 /* CPU 0 Power Control Block Non-Secure base address */ +#define CPU0_IDENTITY_BASE_NS 0x4001F000 /* CPU 0 Identity Block Non-Secure base address */ +#define SSE300_NSACFG_BASE_NS 0x40080000 /* SSE-300 Non-Secure Access Configuration Register Block Non-Secure base address */ +/* Non-Secure MSTEXPPILL Peripheral region */ +#define GPIO0_CMSDK_BASE_NS 0x41100000 /* GPIO 0 Non-Secure base address */ +#define GPIO1_CMSDK_BASE_NS 0x41101000 /* GPIO 1 Non-Secure base address */ +#define GPIO2_CMSDK_BASE_NS 0x41102000 /* GPIO 2 Non-Secure base address */ +#define GPIO3_CMSDK_BASE_NS 0x41103000 /* GPIO 3 Non-Secure base address */ +#define AHB_USER_0_BASE_NS 0x41104000 /* AHB USER 0 Non-Secure base address */ +#define AHB_USER_1_BASE_NS 0x41105000 /* AHB USER 1 Non-Secure base address */ +#define AHB_USER_2_BASE_NS 0x41106000 /* AHB USER 2 Non-Secure base address */ +#define AHB_USER_3_BASE_NS 0x41107000 /* AHB USER 3 Non-Secure base address */ +#define DMA_0_BASE_NS 0x41200000 /* DMA 0 Non-Secure base address */ +#define DMA_1_BASE_NS 0x41201000 /* DMA 1 Non-Secure base address */ +#define DMA_2_BASE_NS 0x41202000 /* DMA 2 Non-Secure base address */ +#define DMA_3_BASE_NS 0x41203000 /* DMA 3 Non-Secure base address */ +#define ETHERNET_BASE_NS 0x41400000 /* Ethernet Non-Secure base address */ +#define USB_BASE_NS 0x41500000 /* USB Non-Secure base address */ +#define USER_APB0_BASE_NS 0x41700000 /* User APB 0 Non-Secure base address */ +#define USER_APB1_BASE_NS 0x41701000 /* User APB 1 Non-Secure base address */ +#define USER_APB2_BASE_NS 0x41702000 /* User APB 2 Non-Secure base address */ +#define USER_APB3_BASE_NS 0x41703000 /* User APB 3 Non-Secure base address */ +#define QSPI_CONFIG_BASE_NS 0x41800000 /* QSPI Config Non-Secure base address */ +#define QSPI_WRITE_BASE_NS 0x41801000 /* QSPI Write Non-Secure base address */ +/* Non-Secure Subsystem peripheral region */ +#define SYSTIMER0_ARMV8_M_BASE_NS 0x48000000 /* System Timer 0 Non-Secure base address */ +#define SYSTIMER1_ARMV8_M_BASE_NS 0x48001000 /* System Timer 1 Non-Secure base address */ +#define SYSTIMER2_ARMV8_M_BASE_NS 0x48002000 /* System Timer 2 Non-Secure base address */ +#define SYSTIMER3_ARMV8_M_BASE_NS 0x48003000 /* System Timer 3 Non-Secure base address */ +#define SSE300_SYSINFO_BASE_NS 0x48020000 /* SSE-300 System info Block Non-Secure base address */ +#define SLOWCLK_TIMER_CMSDK_BASE_NS 0x4802F000 /* CMSDK based SLOWCLK Timer Non-Secure base address */ +#define SYSWDOG_ARMV8_M_CNTRL_BASE_NS 0x48040000 /* Non-Secure Watchdog Timer control frame Non-Secure base address */ +#define SYSWDOG_ARMV8_M_REFRESH_BASE_NS 0x48041000 /* Non-Secure Watchdog Timer refresh frame Non-Secure base address */ +#define SYSCNTR_READ_BASE_NS 0x48101000 /* System Counter Read Secure base address */ +/* Non-Secure MSTEXPPIHL Peripheral region */ +#define ETHOS_U55_APB_BASE_NS 0x48102000 /* Ethos-U55 APB Non-Secure base address */ +#define U55_TIMING_ADAPTER_BASE_NS 0x48103000 /* Ethos-U55 Timing Adapter registers Non-Secure base address */ +#define FPGA_SBCon_I2C_TOUCH_BASE_NS 0x49200000 /* FPGA - SBCon I2C (Touch) Non-Secure base address */ +#define FPGA_SBCon_I2C_AUDIO_BASE_NS 0x49201000 /* FPGA - SBCon I2C (Audio Conf) Non-Secure base address */ +#define FPGA_SPI_ADC_BASE_NS 0x49202000 /* FPGA - PL022 (SPI ADC) Non-Secure base address */ +#define FPGA_SPI_SHIELD0_BASE_NS 0x49203000 /* FPGA - PL022 (SPI Shield0) Non-Secure base address */ +#define FPGA_SPI_SHIELD1_BASE_NS 0x49204000 /* FPGA - PL022 (SPI Shield1) Non-Secure base address */ +#define SBCon_I2C_SHIELD0_BASE_NS 0x49205000 /* SBCon (I2C - Shield0) Non-Secure base address */ +#define SBCon_I2C_SHIELD1_BASE_NS 0x49206000 /* SBCon (I2C – Shield1) Non-Secure base address */ +#define USER_APB_BASE_NS 0x49207000 /* USER APB Non-Secure base address */ +#define FPGA_DDR4_EEPROM_BASE_NS 0x49208000 /* FPGA - SBCon I2C (DDR4 EEPROM) Non-Secure base address */ +#define FPGA_SCC_BASE_NS 0x49300000 /* FPGA - SCC registers Non-Secure base address */ +#define FPGA_I2S_BASE_NS 0x49301000 /* FPGA - I2S (Audio) Non-Secure base address */ +#define FPGA_IO_BASE_NS 0x49302000 /* FPGA - IO (System Ctrl + I/O) Non-Secure base address */ +#define UART0_BASE_NS 0x49303000 /* UART 0 Non-Secure base address */ +#define UART1_BASE_NS 0x49304000 /* UART 1 Non-Secure base address */ +#define UART2_BASE_NS 0x49305000 /* UART 2 Non-Secure base address */ +#define UART3_BASE_NS 0x49306000 /* UART 3 Non-Secure base address */ +#define UART4_BASE_NS 0x49307000 /* UART 4 Non-Secure base address */ +#define UART5_BASE_NS 0x49308000 /* UART 5 Non-Secure base address */ +#define CLCD_Config_Reg_BASE_NS 0x4930A000 /* CLCD Config Reg Non-Secure base address */ +#define RTC_BASE_NS 0x4930B000 /* RTC Non-Secure base address */ +#define DDR4_BLK0_BASE_NS 0x60000000 /* DDR4 block 0 Non-Secure base address */ +#define DDR4_BLK2_BASE_NS 0x80000000 /* DDR4 block 2 Non-Secure base address */ +#define DDR4_BLK4_BASE_NS 0xA0000000 /* DDR4 block 4 Non-Secure base address */ +#define DDR4_BLK6_BASE_NS 0xC0000000 /* DDR4 block 6 Non-Secure base address */ + +/* Secure memory map addresses */ +#define ITCM_BASE_S 0x10000000 /* Instruction TCM Secure base address */ +#define SRAM_BASE_S 0x11000000 /* CODE SRAM Secure base address */ +#define DTCM0_BASE_S 0x30000000 /* Data TCM block 0 Secure base address */ +#define DTCM1_BASE_S 0x30020000 /* Data TCM block 1 Secure base address */ +#define DTCM2_BASE_S 0x30040000 /* Data TCM block 2 Secure base address */ +#define DTCM3_BASE_S 0x30060000 /* Data TCM block 3 Secure base address */ +#define ISRAM0_BASE_S 0x31000000 /* Internal SRAM Area Secure base address */ +#define ISRAM1_BASE_S 0x31200000 /* Internal SRAM Area Secure base address */ +#define QSPI_SRAM_BASE_S 0x38000000 /* QSPI SRAM Secure base address */ +/* Secure Subsystem peripheral region */ +#define CPU0_SECCTRL_BASE_S 0x50011000 /* CPU 0 Local Security Control Block Secure base address */ +#define CPU0_PWRCTRL_BASE_S 0x50012000 /* CPU 0 Power Control Block Secure base address */ +#define CPU0_IDENTITY_BASE_S 0x5001F000 /* CPU 0 Identity Block Secure base address */ +#define SSE300_SACFG_BASE_S 0x50080000 /* SSE-300 Secure Access Configuration Register Secure base address */ +#define MPC_ISRAM0_BASE_S 0x50083000 /* Internal SRAM0 Memory Protection Controller Secure base address */ +#define MPC_ISRAM1_BASE_S 0x50084000 /* Internal SRAM1 Memory Protection Controller Secure base address */ +/* Secure MSTEXPPILL Peripheral region */ +#define GPIO0_CMSDK_BASE_S 0x51100000 /* GPIO 0 Secure base address */ +#define GPIO1_CMSDK_BASE_S 0x51101000 /* GPIO 1 Secure base address */ +#define GPIO2_CMSDK_BASE_S 0x51102000 /* GPIO 2 Secure base address */ +#define GPIO3_CMSDK_BASE_S 0x51103000 /* GPIO 3 Secure base address */ +#define AHB_USER_0_BASE_S 0x51104000 /* AHB USER 0 Secure base address */ +#define AHB_USER_1_BASE_S 0x51105000 /* AHB USER 1 Secure base address */ +#define AHB_USER_2_BASE_S 0x51106000 /* AHB USER 2 Secure base address */ +#define AHB_USER_3_BASE_S 0x51107000 /* AHB USER 3 Secure base address */ +#define DMA_0_BASE_S 0x51200000 /* DMA 0 Secure base address */ +#define DMA_1_BASE_S 0x51201000 /* DMA 1 Secure base address */ +#define DMA_2_BASE_S 0x51202000 /* DMA 2 Secure base address */ +#define DMA_3_BASE_S 0x51203000 /* DMA 3 Secure base address */ +#define ETHERNET_BASE_S 0x51400000 /* Ethernet Secure base address */ +#define USB_BASE_S 0x51500000 /* USB Secure base address */ +#define USER_APB0_BASE_S 0x51700000 /* User APB 0 Secure base address */ +#define USER_APB1_BASE_S 0x51701000 /* User APB 1 Secure base address */ +#define USER_APB2_BASE_S 0x51702000 /* User APB 2 Secure base address */ +#define USER_APB3_BASE_S 0x51703000 /* User APB 3 Secure base address */ +#define QSPI_CONFIG_BASE_S 0x51800000 /* QSPI Config Secure base address */ +#define QSPI_WRITE_BASE_S 0x51801000 /* QSPI Write Secure base address */ +#define MPC_SRAM_BASE_S 0x57000000 /* SRAM Memory Protection Controller Secure base address */ +#define MPC_QSPI_BASE_S 0x57001000 /* QSPI Memory Protection Controller Secure base address */ +#define MPC_DDR4_BASE_S 0x57002000 /* DDR4 Memory Protection Controller Secure base address */ +/* Secure Subsystem peripheral region */ +#define SYSTIMER0_ARMV8_M_BASE_S 0x58000000 /* System Timer 0 Secure base address */ +#define SYSTIMER1_ARMV8_M_BASE_S 0x58001000 /* System Timer 1 Secure base address */ +#define SYSTIMER2_ARMV8_M_BASE_S 0x58002000 /* System Timer 0 Secure base address */ +#define SYSTIMER3_ARMV8_M_BASE_S 0x58003000 /* System Timer 1 Secure base address */ +#define SSE300_SYSINFO_BASE_S 0x58020000 /* SSE-300 System info Block Secure base address */ +#define SSE300_SYSCTRL_BASE_S 0x58021000 /* SSE-300 System control Block Secure base address */ +#define SSE300_SYSPPU_BASE_S 0x58022000 /* SSE-300 System Power Policy Unit Secure base address */ +#define SSE300_CPU0PPU_BASE_S 0x58023000 /* SSE-300 CPU 0 Power Policy Unit Secure base address */ +#define SSE300_MGMTPPU_BASE_S 0x58028000 /* SSE-300 Management Power Policy Unit Secure base address */ +#define SSE300_DBGPPU_BASE_S 0x58029000 /* SSE-300 Debug Power Policy Unit Secure base address */ +#define SLOWCLK_WDOG_CMSDK_BASE_S 0x5802E000 /* CMSDK based SLOWCLK Watchdog Secure base address */ +#define SLOWCLK_TIMER_CMSDK_BASE_S 0x5802F000 /* CMSDK based SLOWCLK Timer Secure base address */ +#define SYSWDOG_ARMV8_M_CNTRL_BASE_S 0x58040000 /* Secure Watchdog Timer control frame Secure base address */ +#define SYSWDOG_ARMV8_M_REFRESH_BASE_S 0x58041000 /* Secure Watchdog Timer refresh frame Secure base address */ +#define SYSCNTR_CNTRL_BASE_S 0x58100000 /* System Counter Control Secure base address */ +#define SYSCNTR_READ_BASE_S 0x58101000 /* System Counter Read Secure base address */ +/* Secure MSTEXPPIHL Peripheral region */ +#define ETHOS_U55_APB_BASE_S 0x58102000 /* Ethos-U55 APB Secure base address */ +#define U55_TIMING_ADAPTER_BASE_S 0x58103000 /* Ethos-U55 Timing Adapter registers Secure base address */ +#define FPGA_SBCon_I2C_TOUCH_BASE_S 0x59200000 /* FPGA - SBCon I2C (Touch) Secure base address */ +#define FPGA_SBCon_I2C_AUDIO_BASE_S 0x59201000 /* FPGA - SBCon I2C (Audio Conf) Secure base address */ +#define FPGA_SPI_ADC_BASE_S 0x59202000 /* FPGA - PL022 (SPI ADC) Secure base address */ +#define FPGA_SPI_SHIELD0_BASE_S 0x59203000 /* FPGA - PL022 (SPI Shield0) Secure base address */ +#define FPGA_SPI_SHIELD1_BASE_S 0x59204000 /* FPGA - PL022 (SPI Shield1) Secure base address */ +#define SBCon_I2C_SHIELD0_BASE_S 0x59205000 /* SBCon (I2C - Shield0) Secure base address */ +#define SBCon_I2C_SHIELD1_BASE_S 0x59206000 /* SBCon (I2C – Shield1) Secure base address */ +#define USER_APB_BASE_S 0x59207000 /* USER APB Secure base address */ +#define FPGA_DDR4_EEPROM_BASE_S 0x59208000 /* FPGA - SBCon I2C (DDR4 EEPROM) Secure base address */ +#define FPGA_SCC_BASE_S 0x59300000 /* FPGA - SCC registers Secure base address */ +#define FPGA_I2S_BASE_S 0x59301000 /* FPGA - I2S (Audio) Secure base address */ +#define FPGA_IO_BASE_S 0x59302000 /* FPGA - IO (System Ctrl + I/O) Secure base address */ +#define UART0_BASE_S 0x59303000 /* UART 0 Secure base address */ +#define UART1_BASE_S 0x59304000 /* UART 1 Secure base address */ +#define UART2_BASE_S 0x59305000 /* UART 2 Secure base address */ +#define UART3_BASE_S 0x59306000 /* UART 3 Secure base address */ +#define UART4_BASE_S 0x59307000 /* UART 4 Secure base address */ +#define UART5_BASE_S 0x59308000 /* UART 5 Secure base address */ +#define CLCD_Config_Reg_BASE_S 0x5930A000 /* CLCD Config Reg Secure base address */ +#define RTC_BASE_S 0x5930B000 /* RTC Secure base address */ +#define DDR4_BLK1_BASE_S 0x70000000 /* DDR4 block 1 Secure base address */ +#define DDR4_BLK3_BASE_S 0x90000000 /* DDR4 block 3 Secure base address */ +#define DDR4_BLK5_BASE_S 0xB0000000 /* DDR4 block 5 Secure base address */ +#define DDR4_BLK7_BASE_S 0xD0000000 /* DDR4 block 7 Secure base address */ + +/* Memory map addresses exempt from memory attribution by both the SAU and IDAU */ +#define SSE300_EWIC_BASE 0xE0047000 /* External Wakeup Interrupt Controller + * Access from Non-secure software is only allowed + * if AIRCR.BFHFNMINS is set to 1 */ + +/* Memory size definitions */ +#define ITCM_SIZE (0x00080000) /* 512 kB */ +#define DTCM_BLK_SIZE (0x00020000) /* 128 kB */ +#define DTCM_BLK_NUM (0x4) /* Number of DTCM blocks */ +#define SRAM_SIZE (0x00200000) /* 2 MB */ +#define ISRAM0_SIZE (0x00200000) /* 2 MB */ +#define ISRAM1_SIZE (0x00200000) /* 2 MB */ +#define QSPI_SRAM_SIZE (0x00800000) /* 8 MB */ +#define DDR4_BLK_SIZE (0x10000000) /* 256 MB */ +#define DDR4_BLK_NUM (0x8) /* Number of DDR4 blocks */ + +/* Defines for Driver MPC's */ +/* SRAM -- 2 MB */ +#define MPC_SRAM_RANGE_BASE_NS (SRAM_BASE_NS) +#define MPC_SRAM_RANGE_LIMIT_NS (SRAM_BASE_NS + SRAM_SIZE-1) +#define MPC_SRAM_RANGE_OFFSET_NS (0x0) +#define MPC_SRAM_RANGE_BASE_S (SRAM_BASE_S) +#define MPC_SRAM_RANGE_LIMIT_S (SRAM_BASE_S + SRAM_SIZE-1) +#define MPC_SRAM_RANGE_OFFSET_S (0x0) + +/* QSPI -- 8 MB*/ +#define MPC_QSPI_RANGE_BASE_NS (QSPI_SRAM_BASE_NS) +#define MPC_QSPI_RANGE_LIMIT_NS (QSPI_SRAM_BASE_NS + QSPI_SRAM_SIZE-1) +#define MPC_QSPI_RANGE_OFFSET_NS (0x0) +#define MPC_QSPI_RANGE_BASE_S (QSPI_SRAM_BASE_S) +#define MPC_QSPI_RANGE_LIMIT_S (QSPI_SRAM_BASE_S + QSPI_SRAM_SIZE-1) +#define MPC_QSPI_RANGE_OFFSET_S (0x0) + +/* ISRAM0 -- 2 MB*/ +#define MPC_ISRAM0_RANGE_BASE_NS (ISRAM0_BASE_NS) +#define MPC_ISRAM0_RANGE_LIMIT_NS (ISRAM0_BASE_NS + ISRAM0_SIZE-1) +#define MPC_ISRAM0_RANGE_OFFSET_NS (0x0) +#define MPC_ISRAM0_RANGE_BASE_S (ISRAM0_BASE_S) +#define MPC_ISRAM0_RANGE_LIMIT_S (ISRAM0_BASE_S + ISRAM0_SIZE-1) +#define MPC_ISRAM0_RANGE_OFFSET_S (0x0) + +/* ISRAM1 -- 2 MB*/ +#define MPC_ISRAM1_RANGE_BASE_NS (ISRAM1_BASE_NS) +#define MPC_ISRAM1_RANGE_LIMIT_NS (ISRAM1_BASE_NS + ISRAM1_SIZE-1) +#define MPC_ISRAM1_RANGE_OFFSET_NS (0x0) +#define MPC_ISRAM1_RANGE_BASE_S (ISRAM1_BASE_S) +#define MPC_ISRAM1_RANGE_LIMIT_S (ISRAM1_BASE_S + ISRAM1_SIZE-1) +#define MPC_ISRAM1_RANGE_OFFSET_S (0x0) + +/* DDR4 -- 2GB (8 * 256 MB) */ +#define MPC_DDR4_BLK0_RANGE_BASE_NS (DDR4_BLK0_BASE_NS) +#define MPC_DDR4_BLK0_RANGE_LIMIT_NS (DDR4_BLK0_BASE_NS + ((DDR4_BLK_SIZE)-1)) +#define MPC_DDR4_BLK0_RANGE_OFFSET_NS (0x0) +#define MPC_DDR4_BLK1_RANGE_BASE_S (DDR4_BLK1_BASE_S) +#define MPC_DDR4_BLK1_RANGE_LIMIT_S (DDR4_BLK1_BASE_S + ((DDR4_BLK_SIZE)-1)) +#define MPC_DDR4_BLK1_RANGE_OFFSET_S (DDR4_BLK1_BASE_S - DDR4_BLK0_BASE_NS) +#define MPC_DDR4_BLK2_RANGE_BASE_NS (DDR4_BLK2_BASE_NS) +#define MPC_DDR4_BLK2_RANGE_LIMIT_NS (DDR4_BLK2_BASE_NS + ((DDR4_BLK_SIZE)-1)) +#define MPC_DDR4_BLK2_RANGE_OFFSET_NS (DDR4_BLK2_BASE_NS - DDR4_BLK0_BASE_NS) +#define MPC_DDR4_BLK3_RANGE_BASE_S (DDR4_BLK3_BASE_S) +#define MPC_DDR4_BLK3_RANGE_LIMIT_S (DDR4_BLK3_BASE_S + ((DDR4_BLK_SIZE)-1)) +#define MPC_DDR4_BLK3_RANGE_OFFSET_S (DDR4_BLK3_BASE_S - DDR4_BLK0_BASE_NS) +#define MPC_DDR4_BLK4_RANGE_BASE_NS (DDR4_BLK4_BASE_NS) +#define MPC_DDR4_BLK4_RANGE_LIMIT_NS (DDR4_BLK4_BASE_NS + ((DDR4_BLK_SIZE)-1)) +#define MPC_DDR4_BLK4_RANGE_OFFSET_NS (DDR4_BLK4_BASE_NS - DDR4_BLK0_BASE_NS) +#define MPC_DDR4_BLK5_RANGE_BASE_S (DDR4_BLK5_BASE_S) +#define MPC_DDR4_BLK5_RANGE_LIMIT_S (DDR4_BLK5_BASE_S + ((DDR4_BLK_SIZE)-1)) +#define MPC_DDR4_BLK5_RANGE_OFFSET_S (DDR4_BLK5_BASE_S - DDR4_BLK0_BASE_NS) +#define MPC_DDR4_BLK6_RANGE_BASE_NS (DDR4_BLK6_BASE_NS) +#define MPC_DDR4_BLK6_RANGE_LIMIT_NS (DDR4_BLK6_BASE_NS + ((DDR4_BLK_SIZE)-1)) +#define MPC_DDR4_BLK6_RANGE_OFFSET_NS (DDR4_BLK6_BASE_NS - DDR4_BLK0_BASE_NS) +#define MPC_DDR4_BLK7_RANGE_BASE_S (DDR4_BLK7_BASE_S) +#define MPC_DDR4_BLK7_RANGE_LIMIT_S (DDR4_BLK7_BASE_S + ((DDR4_BLK_SIZE)-1)) +#define MPC_DDR4_BLK7_RANGE_OFFSET_S (DDR4_BLK7_BASE_S - DDR4_BLK0_BASE_NS) + +#endif /* __PLATFORM_BASE_ADDRESS_H__ */ diff --git a/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Device/SSE-300-MPS3/region_defs.h b/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Device/SSE-300-MPS3/region_defs.h new file mode 100644 index 0000000..c8cd919 --- /dev/null +++ b/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Device/SSE-300-MPS3/region_defs.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2016-2020 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 __REGION_DEFS_H__ +#define __REGION_DEFS_H__ + +#include "region_limits.h" + +/* ************************************************************** + * WARNING: this file is parsed both by the C/C++ compiler + * and the linker. As a result the syntax must be valid not only + * for C/C++ but for the linker scripts too. + * Beware of the following limitations: + * - LD (GCC linker) requires white space around operators. + * - UL postfix for macros is not suported by the linker script + ****************************************************************/ + +/* Secure regions */ +#define S_CODE_START ( S_ROM_ALIAS ) +#define S_CODE_SIZE ( TOTAL_S_ROM_SIZE ) +#define S_CODE_LIMIT ( S_CODE_START + S_CODE_SIZE ) + +#define S_DATA_START ( S_RAM_ALIAS ) +#define S_DATA_SIZE ( TOTAL_S_RAM_SIZE ) +#define S_DATA_LIMIT ( S_DATA_START + S_DATA_SIZE ) + +/* Non-Secure regions */ +#define NS_CODE_START ( NS_ROM_ALIAS ) +#define NS_CODE_SIZE ( TOTAL_NS_ROM_SIZE ) +#define NS_CODE_LIMIT ( NS_CODE_START + NS_CODE_SIZE ) + +#define NS_DATA_START ( NS_RAM_ALIAS ) +#define NS_DATA_SIZE ( TOTAL_NS_RAM_SIZE ) +#define NS_DATA_LIMIT ( NS_DATA_START + NS_DATA_SIZE ) + +#endif /* __REGION_DEFS_H__ */ diff --git a/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Device/SSE-300-MPS3/region_limits.h b/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Device/SSE-300-MPS3/region_limits.h new file mode 100644 index 0000000..74ad482 --- /dev/null +++ b/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Device/SSE-300-MPS3/region_limits.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2018-2020 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 __REGION_LIMITS_H__ +#define __REGION_LIMITS_H__ + +/* ************************************************************** + * WARNING: this file is parsed both by the C/C++ compiler + * and the linker. As a result the syntax must be valid not only + * for C/C++ but for the linker scripts too. + * Beware of the following limitations: + * - LD (GCC linker) requires white space around operators. + * - UL postfix for macros is not suported by the linker script + ****************************************************************/ + +/* Secure Code */ +#define S_ROM_ALIAS (0x10000000) /* ITCM_BASE_S */ +#define TOTAL_S_ROM_SIZE (0x00040000) /* 256 kB */ + +/* Secure Data */ +#define S_RAM_ALIAS (0x30000000) /* DTCM_BASE_S */ +#define TOTAL_S_RAM_SIZE (0x00040000) /* 256 kB */ + + +/* Non-Secure Code */ +#define NS_ROM_ALIAS (0x01000000) /* SRAM_BASE_NS */ +#define TOTAL_NS_ROM_SIZE (0x00040000) /* 256 kB */ + +/* Non-Secure Data */ +#define NS_RAM_ALIAS (0x21000000) /* ISRAM0_BASE_NS */ +#define TOTAL_NS_RAM_SIZE (0x00040000) /* 256 kB */ + + +/* Heap and Stack sizes for secure and nonsecure applications */ +#define HEAP_SIZE (0x0000C000) /* 1 KiB */ +#define STACK_SIZE (0x00008000) /* 1 KiB */ + +#endif /* __REGION_LIMITS_H__ */ diff --git a/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Device/SSE-300-MPS3/startup_fvp_sse300_mps3.c b/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Device/SSE-300-MPS3/startup_fvp_sse300_mps3.c new file mode 100644 index 0000000..a79ab6b --- /dev/null +++ b/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Device/SSE-300-MPS3/startup_fvp_sse300_mps3.c @@ -0,0 +1,351 @@ +/* + * Copyright (c) 2009-2020 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * This file is derivative of CMSIS V5.6.0 startup_ARMv81MML.c + * Git SHA: b5f0603d6a584d1724d952fd8b0737458b90d62b + */ + +#include "cmsis.h" + +/*---------------------------------------------------------------------------- + Exception / Interrupt Handler Function Prototype + *----------------------------------------------------------------------------*/ +typedef void( *pFunc )( void ); + +/*---------------------------------------------------------------------------- + External References + *----------------------------------------------------------------------------*/ +extern uint32_t __INITIAL_SP; +extern uint32_t __STACK_LIMIT; + +#ifdef __FVP_PY +extern void ARM_VSI0_Handler (void); +#endif +extern void __PROGRAM_START(void) __NO_RETURN; + +/*---------------------------------------------------------------------------- + Internal References + *----------------------------------------------------------------------------*/ +void Reset_Handler (void) __NO_RETURN; + +/*---------------------------------------------------------------------------- + Exception / Interrupt Handler + *----------------------------------------------------------------------------*/ +#define DEFAULT_IRQ_HANDLER(handler_name) \ +void __WEAK handler_name(void); \ +void handler_name(void) { \ + while(1); \ +} + +/* Exceptions */ +DEFAULT_IRQ_HANDLER(NMI_Handler) +DEFAULT_IRQ_HANDLER(HardFault_Handler) +DEFAULT_IRQ_HANDLER(MemManage_Handler) +DEFAULT_IRQ_HANDLER(BusFault_Handler) +DEFAULT_IRQ_HANDLER(UsageFault_Handler) +DEFAULT_IRQ_HANDLER(SecureFault_Handler) +DEFAULT_IRQ_HANDLER(SVC_Handler) +DEFAULT_IRQ_HANDLER(DebugMon_Handler) +DEFAULT_IRQ_HANDLER(PendSV_Handler) +DEFAULT_IRQ_HANDLER(SysTick_Handler) + +DEFAULT_IRQ_HANDLER(NONSEC_WATCHDOG_RESET_Handler) +DEFAULT_IRQ_HANDLER(NONSEC_WATCHDOG_Handler) +DEFAULT_IRQ_HANDLER(SLOWCLK_Timer_Handler) +DEFAULT_IRQ_HANDLER(TIMER0_Handler) +DEFAULT_IRQ_HANDLER(TIMER1_Handler) +DEFAULT_IRQ_HANDLER(TIMER2_Handler) +DEFAULT_IRQ_HANDLER(MPC_Handler) +DEFAULT_IRQ_HANDLER(PPC_Handler) +DEFAULT_IRQ_HANDLER(MSC_Handler) +DEFAULT_IRQ_HANDLER(BRIDGE_ERROR_Handler) +DEFAULT_IRQ_HANDLER(MGMT_PPU_Handler) +DEFAULT_IRQ_HANDLER(SYS_PPU_Handler) +DEFAULT_IRQ_HANDLER(CPU0_PPU_Handler) +DEFAULT_IRQ_HANDLER(DEBUG_PPU_Handler) +DEFAULT_IRQ_HANDLER(TIMER3_Handler) +DEFAULT_IRQ_HANDLER(CTI_REQ0_IRQHandler) +DEFAULT_IRQ_HANDLER(CTI_REQ1_IRQHandler) + +DEFAULT_IRQ_HANDLER(System_Timestamp_Counter_Handler) +DEFAULT_IRQ_HANDLER(UARTRX0_Handler) +DEFAULT_IRQ_HANDLER(UARTTX0_Handler) +DEFAULT_IRQ_HANDLER(UARTRX1_Handler) +DEFAULT_IRQ_HANDLER(UARTTX1_Handler) +DEFAULT_IRQ_HANDLER(UARTRX2_Handler) +DEFAULT_IRQ_HANDLER(UARTTX2_Handler) +DEFAULT_IRQ_HANDLER(UARTRX3_Handler) +DEFAULT_IRQ_HANDLER(UARTTX3_Handler) +DEFAULT_IRQ_HANDLER(UARTRX4_Handler) +DEFAULT_IRQ_HANDLER(UARTTX4_Handler) +DEFAULT_IRQ_HANDLER(UART0_Combined_Handler) +DEFAULT_IRQ_HANDLER(UART1_Combined_Handler) +DEFAULT_IRQ_HANDLER(UART2_Combined_Handler) +DEFAULT_IRQ_HANDLER(UART3_Combined_Handler) +DEFAULT_IRQ_HANDLER(UART4_Combined_Handler) +DEFAULT_IRQ_HANDLER(UARTOVF_Handler) +DEFAULT_IRQ_HANDLER(ETHERNET_Handler) +DEFAULT_IRQ_HANDLER(I2S_Handler) +DEFAULT_IRQ_HANDLER(TOUCH_SCREEN_Handler) +DEFAULT_IRQ_HANDLER(USB_Handler) +DEFAULT_IRQ_HANDLER(SPI_ADC_Handler) +DEFAULT_IRQ_HANDLER(SPI_SHIELD0_Handler) +DEFAULT_IRQ_HANDLER(SPI_SHIELD1_Handler) +DEFAULT_IRQ_HANDLER(ETHOS_U55_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_Combined_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_Combined_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_Combined_Handler) +DEFAULT_IRQ_HANDLER(GPIO3_Combined_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_0_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_1_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_2_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_3_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_4_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_5_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_6_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_7_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_8_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_9_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_10_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_11_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_12_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_13_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_14_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_15_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_0_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_1_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_2_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_3_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_4_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_5_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_6_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_7_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_8_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_9_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_10_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_11_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_12_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_13_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_14_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_15_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_0_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_1_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_2_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_3_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_4_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_5_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_6_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_7_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_8_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_9_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_10_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_11_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_12_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_13_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_14_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_15_Handler) +DEFAULT_IRQ_HANDLER(GPIO3_0_Handler) +DEFAULT_IRQ_HANDLER(GPIO3_1_Handler) +DEFAULT_IRQ_HANDLER(GPIO3_2_Handler) +DEFAULT_IRQ_HANDLER(GPIO3_3_Handler) +DEFAULT_IRQ_HANDLER(UARTRX5_Handler) +DEFAULT_IRQ_HANDLER(UARTTX5_Handler) +DEFAULT_IRQ_HANDLER(UART5_Handler) + +/*---------------------------------------------------------------------------- + Exception / Interrupt Vector table + *----------------------------------------------------------------------------*/ + +#if defined ( __GNUC__ ) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpedantic" +#endif + +extern const pFunc __VECTOR_TABLE[496]; + const pFunc __VECTOR_TABLE[496] __VECTOR_TABLE_ATTRIBUTE = { + (pFunc)(&__INITIAL_SP), /* Initial Stack Pointer */ + Reset_Handler, /* Reset Handler */ + NMI_Handler, /* -14: NMI Handler */ + HardFault_Handler, /* -13: Hard Fault Handler */ + MemManage_Handler, /* -12: MPU Fault Handler */ + BusFault_Handler, /* -11: Bus Fault Handler */ + UsageFault_Handler, /* -10: Usage Fault Handler */ + SecureFault_Handler, /* -9: Secure Fault Handler */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + SVC_Handler, /* -5: SVCall Handler */ + DebugMon_Handler, /* -4: Debug Monitor Handler */ + 0, /* Reserved */ + PendSV_Handler, /* -2: PendSV Handler */ + SysTick_Handler, /* -1: SysTick Handler */ + +#ifdef __FVP_PY + ARM_VSI0_Handler, +#else + NONSEC_WATCHDOG_RESET_Handler, /* 0: Non-Secure Watchdog Reset Handler */ +#endif + NONSEC_WATCHDOG_Handler, /* 1: Non-Secure Watchdog Handler */ + SLOWCLK_Timer_Handler, /* 2: SLOWCLK Timer Handler */ + TIMER0_Handler, /* 3: TIMER 0 Handler */ + TIMER1_Handler, /* 4: TIMER 1 Handler */ + TIMER2_Handler, /* 5: TIMER 2 Handler */ + 0, /* 6: Reserved */ + 0, /* 7: Reserved */ + 0, /* 8: Reserved */ + MPC_Handler, /* 9: MPC Combined (Secure) Handler */ + PPC_Handler, /* 10: PPC Combined (Secure) Handler */ + MSC_Handler, /* 11: MSC Combined (Secure) Handler */ + BRIDGE_ERROR_Handler, /* 12: Bridge Error (Secure) Handler */ + 0, /* 13: Reserved */ + MGMT_PPU_Handler, /* 14: MGMT PPU Handler */ + SYS_PPU_Handler, /* 15: SYS PPU Handler */ + CPU0_PPU_Handler, /* 16: CPU0 PPU Handler */ + 0, /* 17: Reserved */ + 0, /* 18: Reserved */ + 0, /* 19: Reserved */ + 0, /* 20: Reserved */ + 0, /* 21: Reserved */ + 0, /* 22: Reserved */ + 0, /* 23: Reserved */ + 0, /* 24: Reserved */ + 0, /* 25: Reserved */ + DEBUG_PPU_Handler, /* 26: DEBUG PPU Handler */ + TIMER3_Handler, /* 27: TIMER 3 Handler */ + CTI_REQ0_IRQHandler, /* 28: CTI request 0 IRQ Handler */ + CTI_REQ1_IRQHandler, /* 29: CTI request 1 IRQ Handler */ + 0, /* 30: Reserved */ + 0, /* 31: Reserved */ + + /* External interrupts */ + System_Timestamp_Counter_Handler, /* 32: System timestamp counter Handler */ + UARTRX0_Handler, /* 33: UART 0 RX Handler */ + UARTTX0_Handler, /* 34: UART 0 TX Handler */ + UARTRX1_Handler, /* 35: UART 1 RX Handler */ + UARTTX1_Handler, /* 36: UART 1 TX Handler */ + UARTRX2_Handler, /* 37: UART 2 RX Handler */ + UARTTX2_Handler, /* 38: UART 2 TX Handler */ + UARTRX3_Handler, /* 39: UART 3 RX Handler */ + UARTTX3_Handler, /* 40: UART 3 TX Handler */ + UARTRX4_Handler, /* 41: UART 4 RX Handler */ + UARTTX4_Handler, /* 42: UART 4 TX Handler */ + UART0_Combined_Handler, /* 43: UART 0 Combined Handler */ + UART1_Combined_Handler, /* 44: UART 1 Combined Handler */ + UART2_Combined_Handler, /* 45: UART 2 Combined Handler */ + UART3_Combined_Handler, /* 46: UART 3 Combined Handler */ + UART4_Combined_Handler, /* 47: UART 4 Combined Handler */ + UARTOVF_Handler, /* 48: UART 0, 1, 2, 3, 4 & 5 Overflow Handler */ + ETHERNET_Handler, /* 49: Ethernet Handler */ + I2S_Handler, /* 50: Audio I2S Handler */ + TOUCH_SCREEN_Handler, /* 51: Touch Screen Handler */ + USB_Handler, /* 52: USB Handler */ + SPI_ADC_Handler, /* 53: SPI ADC Handler */ + SPI_SHIELD0_Handler, /* 54: SPI (Shield 0) Handler */ + SPI_SHIELD1_Handler, /* 55: SPI (Shield 0) Handler */ + ETHOS_U55_Handler, /* 56: Ethos-U55 Handler */ + 0, /* 57: Reserved */ + 0, /* 58: Reserved */ + 0, /* 59: Reserved */ + 0, /* 60: Reserved */ + 0, /* 61: Reserved */ + 0, /* 62: Reserved */ + 0, /* 63: Reserved */ + 0, /* 64: Reserved */ + 0, /* 65: Reserved */ + 0, /* 66: Reserved */ + 0, /* 67: Reserved */ + 0, /* 68: Reserved */ + GPIO0_Combined_Handler, /* 69: GPIO 0 Combined Handler */ + GPIO1_Combined_Handler, /* 70: GPIO 1 Combined Handler */ + GPIO2_Combined_Handler, /* 71: GPIO 2 Combined Handler */ + GPIO3_Combined_Handler, /* 72: GPIO 3 Combined Handler */ + GPIO0_0_Handler, /* 73: GPIO0 Pin 0 Handler */ + GPIO0_1_Handler, /* 74: GPIO0 Pin 1 Handler */ + GPIO0_2_Handler, /* 75: GPIO0 Pin 2 Handler */ + GPIO0_3_Handler, /* 76: GPIO0 Pin 3 Handler */ + GPIO0_4_Handler, /* 77: GPIO0 Pin 4 Handler */ + GPIO0_5_Handler, /* 78: GPIO0 Pin 5 Handler */ + GPIO0_6_Handler, /* 79: GPIO0 Pin 6 Handler */ + GPIO0_7_Handler, /* 80: GPIO0 Pin 7 Handler */ + GPIO0_8_Handler, /* 81: GPIO0 Pin 8 Handler */ + GPIO0_9_Handler, /* 82: GPIO0 Pin 9 Handler */ + GPIO0_10_Handler, /* 83: GPIO0 Pin 10 Handler */ + GPIO0_11_Handler, /* 84: GPIO0 Pin 11 Handler */ + GPIO0_12_Handler, /* 85: GPIO0 Pin 12 Handler */ + GPIO0_13_Handler, /* 86: GPIO0 Pin 13 Handler */ + GPIO0_14_Handler, /* 87: GPIO0 Pin 14 Handler */ + GPIO0_15_Handler, /* 88: GPIO0 Pin 15 Handler */ + GPIO1_0_Handler, /* 89: GPIO1 Pin 0 Handler */ + GPIO1_1_Handler, /* 90: GPIO1 Pin 1 Handler */ + GPIO1_2_Handler, /* 91: GPIO1 Pin 2 Handler */ + GPIO1_3_Handler, /* 92: GPIO1 Pin 3 Handler */ + GPIO1_4_Handler, /* 93: GPIO1 Pin 4 Handler */ + GPIO1_5_Handler, /* 94: GPIO1 Pin 5 Handler */ + GPIO1_6_Handler, /* 95: GPIO1 Pin 6 Handler */ + GPIO1_7_Handler, /* 96: GPIO1 Pin 7 Handler */ + GPIO1_8_Handler, /* 97: GPIO1 Pin 8 Handler */ + GPIO1_9_Handler, /* 98: GPIO1 Pin 9 Handler */ + GPIO1_10_Handler, /* 99: GPIO1 Pin 10 Handler */ + GPIO1_11_Handler, /* 100: GPIO1 Pin 11 Handler */ + GPIO1_12_Handler, /* 101: GPIO1 Pin 12 Handler */ + GPIO1_13_Handler, /* 102: GPIO1 Pin 13 Handler */ + GPIO1_14_Handler, /* 103: GPIO1 Pin 14 Handler */ + GPIO1_15_Handler, /* 104: GPIO1 Pin 15 Handler */ + GPIO2_0_Handler, /* 105: GPIO2 Pin 0 Handler */ + GPIO2_1_Handler, /* 106: GPIO2 Pin 1 Handler */ + GPIO2_2_Handler, /* 107: GPIO2 Pin 2 Handler */ + GPIO2_3_Handler, /* 108: GPIO2 Pin 3 Handler */ + GPIO2_4_Handler, /* 109: GPIO2 Pin 4 Handler */ + GPIO2_5_Handler, /* 110: GPIO2 Pin 5 Handler */ + GPIO2_6_Handler, /* 111: GPIO2 Pin 6 Handler */ + GPIO2_7_Handler, /* 112: GPIO2 Pin 7 Handler */ + GPIO2_8_Handler, /* 113: GPIO2 Pin 8 Handler */ + GPIO2_9_Handler, /* 114: GPIO2 Pin 9 Handler */ + GPIO2_10_Handler, /* 115: GPIO2 Pin 10 Handler */ + GPIO2_11_Handler, /* 116: GPIO2 Pin 11 Handler */ + GPIO2_12_Handler, /* 117: GPIO2 Pin 12 Handler */ + GPIO2_13_Handler, /* 118: GPIO2 Pin 13 Handler */ + GPIO2_14_Handler, /* 119: GPIO2 Pin 14 Handler */ + GPIO2_15_Handler, /* 120: GPIO2 Pin 15 Handler */ + GPIO3_0_Handler, /* 121: GPIO3 Pin 0 Handler */ + GPIO3_1_Handler, /* 122: GPIO3 Pin 1 Handler */ + GPIO3_2_Handler, /* 123: GPIO3 Pin 2 Handler */ + GPIO3_3_Handler, /* 124: GPIO3 Pin 3 Handler */ + UARTRX5_Handler, /* 125: UART 5 RX Interrupt */ + UARTTX5_Handler, /* 126: UART 5 TX Interrupt */ + UART5_Handler, /* 127: UART 5 combined Interrupt */ + 0, /* 128: Reserved */ + 0, /* 129: Reserved */ + 0, /* 130: Reserved */ +}; + +#if defined ( __GNUC__ ) +#pragma GCC diagnostic pop +#endif + +/*---------------------------------------------------------------------------- + Reset Handler called on controller reset + *----------------------------------------------------------------------------*/ +void Reset_Handler(void) +{ + __set_MSPLIM((uint32_t)(&__STACK_LIMIT)); + + SystemInit(); /* CMSIS System Initialization */ + __PROGRAM_START(); /* Enter PreMain (C library entry point) */ +} diff --git a/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Device/SSE-300-MPS3/system_SSE300MPS3.c b/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Device/SSE-300-MPS3/system_SSE300MPS3.c new file mode 100644 index 0000000..a0a2fb0 --- /dev/null +++ b/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Device/SSE-300-MPS3/system_SSE300MPS3.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2009-2020 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * This file is derivative of CMSIS V5.6.0 system_ARMv81MML.c + * Git SHA: b5f0603d6a584d1724d952fd8b0737458b90d62b + */ + +#include "SSE300MPS3.h" + +/*---------------------------------------------------------------------------- + Define clocks + *----------------------------------------------------------------------------*/ + #define XTAL (32000000UL) + #define SYSTEM_CLOCK (XTAL) + #define PERIPHERAL_CLOCK (25000000UL) + +/*---------------------------------------------------------------------------- + Externals + *----------------------------------------------------------------------------*/ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + extern uint32_t __VECTOR_TABLE; +#endif + +/*---------------------------------------------------------------------------- + System Core Clock Variable + *----------------------------------------------------------------------------*/ +uint32_t SystemCoreClock = SYSTEM_CLOCK; +uint32_t PeripheralClock = PERIPHERAL_CLOCK; + +/*---------------------------------------------------------------------------- + System Core Clock update function + *----------------------------------------------------------------------------*/ +void SystemCoreClockUpdate (void) +{ + SystemCoreClock = SYSTEM_CLOCK; + PeripheralClock = PERIPHERAL_CLOCK; +} + +/*---------------------------------------------------------------------------- + System initialization function + *----------------------------------------------------------------------------*/ +void SystemInit (void) +{ + +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + SCB->VTOR = (uint32_t)(&__VECTOR_TABLE); +#endif + +/* CMSIS System Initialization */ +#if (defined (__FPU_USED) && (__FPU_USED == 1U)) || \ + (defined (__ARM_FEATURE_MVE) && (__ARM_FEATURE_MVE > 1U)) + SCB->CPACR |= ((3U << 10U*2U) | /* enable CP10 Full Access */ + (3U << 11U*2U) ); /* enable CP11 Full Access */ +#endif + +#ifdef UNALIGNED_SUPPORT_DISABLE + SCB->CCR |= SCB_CCR_UNALIGN_TRP_Msk; +#endif + +/* Enable Loop and branch info cache */ + SCB->CCR |= SCB_CCR_LOB_Msk; + __ISB(); +} diff --git a/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Device/SSE-300-MPS3/system_core_init.c b/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Device/SSE-300-MPS3/system_core_init.c new file mode 100644 index 0000000..3f46da1 --- /dev/null +++ b/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Device/SSE-300-MPS3/system_core_init.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2009-2020 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * This file is derivative of CMSIS V5.6.0 system_ARMv81MML.c + * Git SHA: b5f0603d6a584d1724d952fd8b0737458b90d62b + */ + +#include "cmsis.h" + +/*---------------------------------------------------------------------------- + Define clocks + *----------------------------------------------------------------------------*/ + #define XTAL (32000000UL) + #define SYSTEM_CLOCK (XTAL) + #define PERIPHERAL_CLOCK (25000000UL) + +/*---------------------------------------------------------------------------- + Externals + *----------------------------------------------------------------------------*/ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + extern uint32_t __VECTOR_TABLE; +#endif + +/*---------------------------------------------------------------------------- + System Core Clock Variable + *----------------------------------------------------------------------------*/ +uint32_t SystemCoreClock = SYSTEM_CLOCK; +uint32_t PeripheralClock = PERIPHERAL_CLOCK; + +/*---------------------------------------------------------------------------- + System Core Clock update function + *----------------------------------------------------------------------------*/ +void SystemCoreClockUpdate (void) +{ + SystemCoreClock = SYSTEM_CLOCK; + PeripheralClock = PERIPHERAL_CLOCK; +} + +/*---------------------------------------------------------------------------- + System initialization function + *----------------------------------------------------------------------------*/ +void SystemInit (void) +{ + +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + SCB->VTOR = (uint32_t)(&__VECTOR_TABLE); +#endif + +/* CMSIS System Initialization */ +#if (defined (__FPU_USED) && (__FPU_USED == 1U)) || \ + (defined (__MVE_USED) && (__MVE_USED == 1U)) + SCB->CPACR |= ((3U << 10U*2U) | /* enable CP10 Full Access */ + (3U << 11U*2U) ); /* enable CP11 Full Access */ +#endif + +#ifdef UNALIGNED_SUPPORT_DISABLE + SCB->CCR |= SCB_CCR_UNALIGN_TRP_Msk; +#endif +} diff --git a/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Machine_Learning/debug_log.cc b/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Machine_Learning/debug_log.cc new file mode 100644 index 0000000..bc79d43 --- /dev/null +++ b/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Machine_Learning/debug_log.cc @@ -0,0 +1,43 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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. +==============================================================================*/ + +// Implementation for the DebugLog() function that prints to the debug logger on +// an generic Cortex-M device. + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +#include "tensorflow/lite/micro/debug_log.h" + +#include "tensorflow/lite/micro/cortex_m_generic/debug_log_callback.h" + +static DebugLogCallback debug_log_callback = nullptr; + +void RegisterDebugLogCallback(void (*cb)(const char* s)) { + debug_log_callback = cb; +} + +void DebugLog(const char* s) { +#ifndef TF_LITE_STRIP_ERROR_STRINGS + if (debug_log_callback != nullptr) { + debug_log_callback(s); + } +#endif +} + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus diff --git a/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Machine_Learning/micro_time.cc b/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Machine_Learning/micro_time.cc new file mode 100644 index 0000000..023ac6d --- /dev/null +++ b/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Machine_Learning/micro_time.cc @@ -0,0 +1,67 @@ +/* Copyright 2021 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 "tensorflow/lite/micro/micro_time.h" + +// DWT (Data Watchpoint and Trace) registers, only exists on ARM Cortex with a +// DWT unit. +#define KIN1_DWT_CONTROL (*((volatile uint32_t*)0xE0001000)) +/*!< DWT Control register */ + +// DWT Control register. +#define KIN1_DWT_CYCCNTENA_BIT (1UL << 0) + +// CYCCNTENA bit in DWT_CONTROL register. +#define KIN1_DWT_CYCCNT (*((volatile uint32_t*)0xE0001004)) + +// DWT Cycle Counter register. +#define KIN1_DEMCR (*((volatile uint32_t*)0xE000EDFC)) + +// DEMCR: Debug Exception and Monitor Control Register. +#define KIN1_TRCENA_BIT (1UL << 24) + +#define KIN1_LAR (*((volatile uint32_t*)0xE0001FB0)) + +#define KIN1_DWT_CONTROL (*((volatile uint32_t*)0xE0001000)) + +// Unlock access to DWT (ITM, etc.)registers. +#define KIN1_UnlockAccessToDWT() KIN1_LAR = 0xC5ACCE55; + +// TRCENA: Enable trace and debug block DEMCR (Debug Exception and Monitor +// Control Register. +#define KIN1_InitCycleCounter() KIN1_DEMCR |= KIN1_TRCENA_BIT + +#define KIN1_ResetCycleCounter() KIN1_DWT_CYCCNT = 0 +#define KIN1_EnableCycleCounter() KIN1_DWT_CONTROL |= KIN1_DWT_CYCCNTENA_BIT +#define KIN1_DisableCycleCounter() KIN1_DWT_CONTROL &= ~KIN1_DWT_CYCCNTENA_BIT +#define KIN1_GetCycleCounter() KIN1_DWT_CYCCNT + +namespace tflite { + +int32_t ticks_per_second() { return 0; } + +int32_t GetCurrentTimeTicks() { + static bool is_initialized = false; + if (!is_initialized) { + KIN1_UnlockAccessToDWT(); + KIN1_InitCycleCounter(); + KIN1_ResetCycleCounter(); + KIN1_EnableCycleCounter(); + is_initialized = true; + } + return KIN1_GetCycleCounter(); +} + +} // namespace tflite diff --git a/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Machine_Learning/system_setup.cc b/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Machine_Learning/system_setup.cc new file mode 100644 index 0000000..b4fe0b1 --- /dev/null +++ b/Platform_FVP_Corstone_SSE-300_Ethos-U55/RTE/Machine_Learning/system_setup.cc @@ -0,0 +1,38 @@ +/* Copyright 2021 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 "tensorflow/lite/micro/system_setup.h" +#include "stdio.h" +#include "tensorflow/lite/micro/cortex_m_generic/debug_log_callback.h" + +extern "C" void stdio_init (void); + +namespace tflite { + +void debug_log_printf(const char* s) { + printf(s); +} + +// To add an equivalent function for your own platform, create your own +// implementation file, and place it in a subfolder named after the target. See +// tensorflow/lite/micro/debug_log.cc for a similar example. +void InitializeTarget() { +#ifdef __TEST + stdio_init(); +#endif + RegisterDebugLogCallback(debug_log_printf); +} + +} // namespace tflite diff --git a/Platform_FVP_Corstone_SSE-300_Ethos-U55/debug.ini b/Platform_FVP_Corstone_SSE-300_Ethos-U55/debug.ini new file mode 100644 index 0000000..52aa313 --- /dev/null +++ b/Platform_FVP_Corstone_SSE-300_Ethos-U55/debug.ini @@ -0,0 +1 @@ +CORE_CLK=200000000 diff --git a/Platform_FVP_Corstone_SSE-300_Ethos-U55/fvp_config.txt b/Platform_FVP_Corstone_SSE-300_Ethos-U55/fvp_config.txt new file mode 100644 index 0000000..7b6f163 --- /dev/null +++ b/Platform_FVP_Corstone_SSE-300_Ethos-U55/fvp_config.txt @@ -0,0 +1,8 @@ +# Parameters: +# instance.parameter=value #(type, mode) default = 'def value' : description : [min..max] +#------------------------------------------------------------------------------ +cpu_core.core_clk.mul=200000000 # (int , init-time) default = '0x17d7840' : Clock Rate Multiplier. This parameter is not exposed via CADI and can only be set in LISA +cpu_core.mps3_board.telnetterminal0.start_telnet=0 # (bool , init-time) default = '1' : Start telnet if nothing connected +cpu_core.mps3_board.uart0.out_file=- # (string, init-time) default = '' : Output file to hold data written by the UART (use '-' to send all output to stdout) +cpu_core.mps3_board.visualisation.disable-visualisation=1 # (bool , init-time) default = '0' : Enable/disable visualisation +#------------------------------------------------------------------------------ diff --git a/Platform_FVP_Corstone_SSE-300_Ethos-U55/main.c b/Platform_FVP_Corstone_SSE-300_Ethos-U55/main.c new file mode 100644 index 0000000..ed834d8 --- /dev/null +++ b/Platform_FVP_Corstone_SSE-300_Ethos-U55/main.c @@ -0,0 +1,47 @@ +/*--------------------------------------------------------------------------- + * Copyright (c) 2020-2021 Arm Limited (or its affiliates). All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *---------------------------------------------------------------------------*/ + +#include "RTE_Components.h" +#include CMSIS_device_header +#include "cmsis_os2.h" +#ifdef RTE_Compiler_EventRecorder +#include "EventRecorder.h" +#endif + +#include "main.h" + +int main (void) { + + // System Initialization + SystemCoreClockUpdate(); + + // Initialize STDIO + stdio_init(); + +#if defined(RTE_Compiler_EventRecorder) && \ + (defined(__MICROLIB) || \ + !(defined(RTE_CMSIS_RTOS2_RTX5) || defined(RTE_CMSIS_RTOS2_FreeRTOS))) + EventRecorderInitialize(EventRecordAll, 1U); +#endif + + osKernelInitialize(); // Initialize CMSIS-RTOS2 + app_initialize(); // Initialize application + osKernelStart(); // Start thread execution + + for (;;) {} +} diff --git a/Platform_FVP_Corstone_SSE-300_Ethos-U55/main.h b/Platform_FVP_Corstone_SSE-300_Ethos-U55/main.h new file mode 100644 index 0000000..50df945 --- /dev/null +++ b/Platform_FVP_Corstone_SSE-300_Ethos-U55/main.h @@ -0,0 +1,25 @@ +/*--------------------------------------------------------------------------- + * Copyright (c) 2020-2021 Arm Limited (or its affiliates). + * All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * 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 MAIN_H__ +#define MAIN_H__ + +extern void stdio_init (void); +extern void app_initialize (void); + +#endif diff --git a/Platform_FVP_Corstone_SSE-300_Ethos-U55/microspeech.Audio_Provider_Mock.cprj b/Platform_FVP_Corstone_SSE-300_Ethos-U55/microspeech.Audio_Provider_Mock.cprj new file mode 100644 index 0000000..f123ad3 --- /dev/null +++ b/Platform_FVP_Corstone_SSE-300_Ethos-U55/microspeech.Audio_Provider_Mock.cprj @@ -0,0 +1,134 @@ + + + + + + + Blinky + + + + + + + + + + + + + + + + + + + + + + + + + ../micro_speech/src + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Platform_FVP_Corstone_SSE-300_Ethos-U55/microspeech.Example.cprj b/Platform_FVP_Corstone_SSE-300_Ethos-U55/microspeech.Example.cprj new file mode 100644 index 0000000..e80e5be --- /dev/null +++ b/Platform_FVP_Corstone_SSE-300_Ethos-U55/microspeech.Example.cprj @@ -0,0 +1,133 @@ + + + + + + + Blinky + + + + + + + + + + + + + + + + + + + + + + + + + ../VSI/audio/include;../VSI/include;../micro_speech/src + __FVP_PY + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Platform_FVP_Corstone_SSE-300_Ethos-U55/microspeech.c b/Platform_FVP_Corstone_SSE-300_Ethos-U55/microspeech.c new file mode 100644 index 0000000..743183d --- /dev/null +++ b/Platform_FVP_Corstone_SSE-300_Ethos-U55/microspeech.c @@ -0,0 +1,45 @@ +/*--------------------------------------------------------------------------- + * Copyright (c) 2020-2021 Arm Limited (or its affiliates). All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *---------------------------------------------------------------------------*/ + +#include "main.h" +#include "main_functions.h" + +#include "cmsis_os2.h" + +static const osThreadAttr_t app_main_attr = { + .stack_size = 4096U +}; + +/*--------------------------------------------------------------------------- + * Application main thread + *---------------------------------------------------------------------------*/ +static void app_main (void *argument) { + (void)argument; + + setup(); + for (;;) { + loop(); + } +} + +/*--------------------------------------------------------------------------- + * Application initialization + *---------------------------------------------------------------------------*/ +void app_initialize (void) { + osThreadNew(app_main, NULL, &app_main_attr); +} diff --git a/Platform_FVP_Corstone_SSE-300_Ethos-U55/microspeech.uvoptx b/Platform_FVP_Corstone_SSE-300_Ethos-U55/microspeech.uvoptx new file mode 100644 index 0000000..e9ea201 --- /dev/null +++ b/Platform_FVP_Corstone_SSE-300_Ethos-U55/microspeech.uvoptx @@ -0,0 +1,1359 @@ + + + + 1.0 + +
### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc; *.md + *.plm + *.cpp; *.cc; *.cxx + 0 + + + + 0 + 0 + + + + Example + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\Listings\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 7 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 15 + + + + + + + + + + .\debug.ini + BIN\DbgFMv8M.DLL + + + + 0 + EVENTREC_CNF + -l0 -a1 -s0 -f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + DLGTARM + (6010=-1,-1,-1,-1,0)(6018=-1,-1,-1,-1,0)(6019=-1,-1,-1,-1,0)(6008=-1,-1,-1,-1,0)(6009=-1,-1,-1,-1,0)(6014=-1,-1,-1,-1,0)(6015=-1,-1,-1,-1,0)(6003=-1,-1,-1,-1,0)(6000=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + 0 + DLGUARM + (105=-1,-1,-1,-1,0)(106=-1,-1,-1,-1,0)(107=-1,-1,-1,-1,0) + + + 0 + DbgFMv8M + -I -S"System Generator:cpu_core" -L"cpu_core.cpu0" -O4102 -C0 -MC"..\..\Program Files\Arm\VHT\models\Win64_VC2017\arm_vsi.exe" -MF"fvp_config.txt" -PF -MA"-V "..\VSI\audio\python" -C cpu_core.mps3_board.telnetterminal0.start_telnet=1" + + + 0 + UL2V8M + UL2V8M(-S0 -C0 -P0 -FD01000000 -FC1000) + + + + + C:\ARM\PACK\ARM\CMSIS\5.8.0\CMSIS\RTOS2\RTX\RTX5.scvd + ARM.CMSIS.5.8.0 + 1 + + + C:\ARM\PACK\Keil\ARM_Compiler\1.6.3\EventRecorder.scvd + Keil.ARM_Compiler.1.6.3 + 1 + + + 0 + + + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + 1 + 1 + 0 + 2 + 10000000 + + + + + + Example Test + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\Listings\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 0 + + 7 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 15 + + + + + + + + + + .\debug.ini + BIN\DbgFMv8M.DLL + + + + 0 + EVENTREC_CNF + -l0 -a1 -s0 -f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + DLGTARM + (6010=-1,-1,-1,-1,0)(6018=-1,-1,-1,-1,0)(6019=-1,-1,-1,-1,0)(6008=-1,-1,-1,-1,0)(6009=-1,-1,-1,-1,0)(6014=-1,-1,-1,-1,0)(6015=-1,-1,-1,-1,0)(6003=-1,-1,-1,-1,0)(6000=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + 0 + DLGUARM + (105=-1,-1,-1,-1,0)(106=-1,-1,-1,-1,0)(107=-1,-1,-1,-1,0) + + + 0 + DbgFMv8M + -I -S"System Generator:cpu_core" -L"cpu_core.cpu0" -O4102 -C0 -MC"..\..\Program Files\Arm\VHT\models\Win64_VC2017\arm_vsi.exe" -MF"fvp_config.txt" -PF -MA"-V "..\VSI\audio\python" -C cpu_core.mps3_board.telnetterminal0.start_telnet=1" + + + 0 + UL2V8M + UL2V8M(-S0 -C0 -P0 -FD01000000 -FC1000) + + + + + C:\ARM\PACK\ARM\CMSIS\5.8.0\CMSIS\RTOS2\RTX\RTX5.scvd + ARM.CMSIS.5.8.0 + 1 + + + C:\ARM\PACK\Keil\ARM_Compiler\1.6.3\EventRecorder.scvd + Keil.ARM_Compiler.1.6.3 + 1 + + + 0 + + + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + 1 + 1 + 0 + 2 + 10000000 + + + + + + Audio Provider Mock + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\Listings\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 0 + + 7 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 15 + + + + + + + + + + .\debug.ini + BIN\DbgFMv8M.DLL + + + + 0 + EVENTREC_CNF + -l0 -a1 -s0 -f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + DLGTARM + (6010=-1,-1,-1,-1,0)(6018=-1,-1,-1,-1,0)(6019=-1,-1,-1,-1,0)(6008=-1,-1,-1,-1,0)(6009=-1,-1,-1,-1,0)(6014=-1,-1,-1,-1,0)(6015=-1,-1,-1,-1,0)(6003=-1,-1,-1,-1,0)(6000=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + 0 + DLGUARM + (105=-1,-1,-1,-1,0)(106=-1,-1,-1,-1,0)(107=-1,-1,-1,-1,0) + + + 0 + DbgFMv8M + -I -S"System Generator:FVP_MPS3_Corstone_SSE_300" -L"cpu0" -O4102 -C0 -MC"..\..\Program Files\Arm\FVP_Corstone_SSE-300\models\Win64_VC2017\FVP_Corstone_SSE-300_Ethos-U55.exe" -MF"mps3_config.txt" -PF -MA + + + 0 + UL2V8M + UL2V8M(-S0 -C0 -P0 -FD01000000 -FC1000) + + + + + C:\ARM\PACK\ARM\CMSIS\5.8.0\CMSIS\RTOS2\RTX\RTX5.scvd + ARM.CMSIS.5.8.0 + 1 + + + C:\ARM\PACK\Keil\ARM_Compiler\1.6.3\EventRecorder.scvd + Keil.ARM_Compiler.1.6.3 + 1 + + + 0 + + + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + 1 + 1 + 0 + 2 + 10000000 + + + + + + Audio Provider Mock Test + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\Listings\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 0 + + 7 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 15 + + + + + + + + + + .\debug.ini + BIN\DbgFMv8M.DLL + + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + DLGTARM + (6010=-1,-1,-1,-1,0)(6018=-1,-1,-1,-1,0)(6019=-1,-1,-1,-1,0)(6008=-1,-1,-1,-1,0)(6009=-1,-1,-1,-1,0)(6014=-1,-1,-1,-1,0)(6015=-1,-1,-1,-1,0)(6003=-1,-1,-1,-1,0)(6000=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + 0 + DLGUARM + (105=-1,-1,-1,-1,0)(106=-1,-1,-1,-1,0)(107=-1,-1,-1,-1,0) + + + 0 + DbgFMv8M + -I -S"System Generator:FVP_MPS3_Corstone_SSE_300" -L"cpu0" -O4102 -C0 -MC"..\..\Program Files\Arm\FVP_Corstone_SSE-300\models\Win64_VC2017\FVP_Corstone_SSE-300_Ethos-U55.exe" -MF"mps3_config.txt" -PF -MA + + + 0 + UL2V8M + UL2V8M(-S0 -C0 -P0 -FD01000000 -FC1000) + + + + + C:\ARM\PACK\ARM\CMSIS\5.8.0\CMSIS\RTOS2\RTX\RTX5.scvd + ARM.CMSIS.5.8.0 + 1 + + + C:\ARM\PACK\Keil\ARM_Compiler\1.6.3\EventRecorder.scvd + Keil.ARM_Compiler.1.6.3 + 1 + + + 0 + + + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + 1 + 1 + 0 + 2 + 10000000 + + + + + + App + 0 + 0 + 0 + 0 + + 1 + 1 + 1 + 0 + 0 + 0 + .\microspeech.c + microspeech.c + 0 + 0 + + + + + Board + 0 + 0 + 0 + 0 + + 2 + 2 + 1 + 0 + 0 + 0 + .\main.c + main.c + 0 + 0 + + + 2 + 3 + 5 + 0 + 0 + 0 + .\main.h + main.h + 0 + 0 + + + + + Board IO + 0 + 0 + 0 + 0 + + 3 + 4 + 1 + 0 + 0 + 0 + .\Board_IO\retarget_stdio.c + retarget_stdio.c + 0 + 0 + + + + + Driver + 0 + 0 + 0 + 0 + + 4 + 5 + 1 + 0 + 0 + 0 + ..\VSI\audio\driver\audio_drv.c + audio_drv.c + 0 + 0 + + + + + TF_micro_frontend + 0 + 0 + 0 + 0 + + 5 + 6 + 8 + 0 + 0 + 0 + ..\micro_speech\src\microfrontend\lib\fft.cc + fft.cc + 0 + 0 + + + 5 + 7 + 8 + 0 + 0 + 0 + ..\micro_speech\src\microfrontend\lib\fft_util.cc + fft_util.cc + 0 + 0 + + + 5 + 8 + 1 + 0 + 0 + 0 + ..\micro_speech\src\microfrontend\lib\filterbank.c + filterbank.c + 0 + 0 + + + 5 + 9 + 1 + 0 + 0 + 0 + ..\micro_speech\src\microfrontend\lib\filterbank_util.c + filterbank_util.c + 0 + 0 + + + 5 + 10 + 1 + 0 + 0 + 0 + ..\micro_speech\src\microfrontend\lib\frontend.c + frontend.c + 0 + 0 + + + 5 + 11 + 1 + 0 + 0 + 0 + ..\micro_speech\src\microfrontend\lib\frontend_util.c + frontend_util.c + 0 + 0 + + + 5 + 12 + 1 + 0 + 0 + 0 + ..\micro_speech\src\microfrontend\lib\log_lut.c + log_lut.c + 0 + 0 + + + 5 + 13 + 1 + 0 + 0 + 0 + ..\micro_speech\src\microfrontend\lib\log_scale.c + log_scale.c + 0 + 0 + + + 5 + 14 + 1 + 0 + 0 + 0 + ..\micro_speech\src\microfrontend\lib\log_scale_util.c + log_scale_util.c + 0 + 0 + + + 5 + 15 + 1 + 0 + 0 + 0 + ..\micro_speech\src\microfrontend\lib\noise_reduction.c + noise_reduction.c + 0 + 0 + + + 5 + 16 + 1 + 0 + 0 + 0 + ..\micro_speech\src\microfrontend\lib\noise_reduction_util.c + noise_reduction_util.c + 0 + 0 + + + 5 + 17 + 1 + 0 + 0 + 0 + ..\micro_speech\src\microfrontend\lib\pcan_gain_control.c + pcan_gain_control.c + 0 + 0 + + + 5 + 18 + 1 + 0 + 0 + 0 + ..\micro_speech\src\microfrontend\lib\pcan_gain_control_util.c + pcan_gain_control_util.c + 0 + 0 + + + 5 + 19 + 1 + 0 + 0 + 0 + ..\micro_speech\src\microfrontend\lib\window.c + window.c + 0 + 0 + + + 5 + 20 + 1 + 0 + 0 + 0 + ..\micro_speech\src\microfrontend\lib\window_util.c + window_util.c + 0 + 0 + + + + + TF_micro_features + 0 + 0 + 0 + 0 + + 6 + 21 + 8 + 0 + 0 + 0 + ..\micro_speech\src\micro_features\micro_features_generator.cc + micro_features_generator.cc + 0 + 0 + + + 6 + 22 + 8 + 0 + 0 + 0 + ..\micro_speech\src\micro_features\micro_model_settings.cc + micro_model_settings.cc + 0 + 0 + + + 6 + 23 + 8 + 0 + 0 + 0 + ..\micro_speech\src\micro_features\model.cc + model.cc + 0 + 0 + + + 6 + 24 + 8 + 0 + 0 + 0 + ..\micro_speech\src\micro_features\no_micro_features_data.cc + no_micro_features_data.cc + 0 + 0 + + + 6 + 25 + 8 + 0 + 0 + 0 + ..\micro_speech\src\micro_features\yes_micro_features_data.cc + yes_micro_features_data.cc + 0 + 0 + + + + + TF_main + 0 + 0 + 0 + 0 + + 7 + 26 + 8 + 0 + 0 + 0 + ..\micro_speech\src\audio_provider.cc + audio_provider.cc + 0 + 0 + + + 7 + 27 + 8 + 0 + 0 + 0 + ..\micro_speech\src\command_responder.cc + command_responder.cc + 0 + 0 + + + 7 + 28 + 8 + 0 + 0 + 0 + ..\micro_speech\src\feature_provider.cc + feature_provider.cc + 0 + 0 + + + 7 + 29 + 8 + 0 + 0 + 0 + ..\micro_speech\src\main.cc + main.cc + 0 + 0 + + + 7 + 30 + 8 + 0 + 0 + 0 + ..\micro_speech\src\main_functions.cc + main_functions.cc + 0 + 0 + + + 7 + 31 + 8 + 0 + 0 + 0 + ..\micro_speech\src\recognize_commands.cc + recognize_commands.cc + 0 + 0 + + + + + TF_test + 0 + 0 + 0 + 0 + + 8 + 32 + 8 + 0 + 0 + 0 + ..\micro_speech\src\audio_provider_mock.cc + audio_provider_mock.cc + 0 + 0 + + + 8 + 33 + 8 + 0 + 0 + 0 + ..\micro_speech\src\micro_speech_test.cc + micro_speech_test.cc + 0 + 0 + + + 8 + 34 + 8 + 0 + 0 + 0 + ..\micro_speech\src\audio_provider_mock_test.cc + audio_provider_mock_test.cc + 0 + 0 + + + 8 + 35 + 8 + 0 + 0 + 0 + ..\micro_speech\src\yes_1000ms_sample_data.cc + yes_1000ms_sample_data.cc + 0 + 0 + + + 8 + 36 + 8 + 0 + 0 + 0 + ..\micro_speech\src\no_1000ms_sample_data.cc + no_1000ms_sample_data.cc + 0 + 0 + + + + + ::CMSIS + 0 + 0 + 0 + 1 + + + + ::CMSIS Driver + 0 + 0 + 0 + 1 + + + + ::Compiler + 0 + 0 + 0 + 1 + + + + ::Data Exchange + 0 + 0 + 0 + 1 + + + + ::Data Processing + 0 + 0 + 0 + 1 + + + + ::Device + 0 + 0 + 0 + 1 + + + + ::Machine Learning + 0 + 0 + 0 + 1 + + + + ::Native Driver + 0 + 0 + 0 + 1 + + +
diff --git a/Platform_FVP_Corstone_SSE-300_Ethos-U55/microspeech.uvprojx b/Platform_FVP_Corstone_SSE-300_Ethos-U55/microspeech.uvprojx new file mode 100644 index 0000000..a15f5ea --- /dev/null +++ b/Platform_FVP_Corstone_SSE-300_Ethos-U55/microspeech.uvprojx @@ -0,0 +1,4277 @@ + + + + 2.1 + +
### uVision Project, (C) Keil Software
+ + + + Example + 0x4 + ARM-ADS + 6160000::V6.16::ARMCLANG + 1 + + + SSE-300-MPS3 + ARM + ARM.V2M_MPS3_SSE_300_BSP.1.2.0 + http://www.keil.com/pack/ + IRAM(0x38000000,0x00200000) IRAM2(0x28000000,0x00200000) IROM(0x10000000,0x00040000) IROM2(0x00000000,0x00040000) XRAM(0x38200000,0x00200000) XRAM2(0x28200000,0x00200000) XRAM3(0x31000000,0x00040000) CPUTYPE("Cortex-M55") FPU3(SFPU) DSP TZ CLOCK(12000000) ESEL ELITTLE + + + UL2V8M(-S0 -C0 -P0 -FD38000000 -FC1000) + 0 + $$Device:SSE-300-MPS3$Board\Platform\platform_description.h + + + + + + + + + + $$Device:SSE-300-MPS3$SVD\SSE300.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\Objects\ + microspeech + 1 + 0 + 1 + 1 + 1 + .\Listings\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + 1 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + + + + + SARMV8M.DLL + -MPU + TCM.DLL + -pCM55 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 0 + 4102 + + 1 + BIN\UL2V8M.DLL + "" () + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M55" + + 1 + 0 + 0 + 1 + 1 + 1 + 0 + 1 + 0 + 0 + 1 + 1 + 8 + 0 + 1 + 0 + 2 + 4 + 4 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 1 + 1 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x38000000 + 0x200000 + + + 1 + 0x10000000 + 0x40000 + + + 1 + 0x38200000 + 0x200000 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x10000000 + 0x40000 + + + 1 + 0x0 + 0x40000 + + + 0 + 0x38200000 + 0x200000 + + + 0 + 0x28200000 + 0x200000 + + + 0 + 0x31000000 + 0x40000 + + + 0 + 0x30000000 + 0x40000 + + + 0 + 0x20000000 + 0x40000 + + + + + + 1 + 6 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 0 + 0 + 0 + 0 + 3 + 6 + 1 + 1 + 0 + 0 + 0 + + + __FVP_PY + + ..\VSI\include;..\VSI\audio\include;..\micro_speech\src + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 2 + + + + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x10000000 + 0x30000000 + + .\RTE\Device\SSE-300-MPS3\fvp_sse300_mps3_s.sct + + + --diag_suppress 6439,6314 + + + + + + + + App + + + microspeech.c + 1 + .\microspeech.c + + + + + Board + + + main.c + 1 + .\main.c + + + main.h + 5 + .\main.h + + + + + Board IO + + + retarget_stdio.c + 1 + .\Board_IO\retarget_stdio.c + + + + + Driver + + + audio_drv.c + 1 + ..\VSI\audio\driver\audio_drv.c + + + + + TF_micro_frontend + + + fft.cc + 8 + ..\micro_speech\src\microfrontend\lib\fft.cc + + + fft_util.cc + 8 + ..\micro_speech\src\microfrontend\lib\fft_util.cc + + + filterbank.c + 1 + ..\micro_speech\src\microfrontend\lib\filterbank.c + + + filterbank_util.c + 1 + ..\micro_speech\src\microfrontend\lib\filterbank_util.c + + + frontend.c + 1 + ..\micro_speech\src\microfrontend\lib\frontend.c + + + frontend_util.c + 1 + ..\micro_speech\src\microfrontend\lib\frontend_util.c + + + log_lut.c + 1 + ..\micro_speech\src\microfrontend\lib\log_lut.c + + + log_scale.c + 1 + ..\micro_speech\src\microfrontend\lib\log_scale.c + + + log_scale_util.c + 1 + ..\micro_speech\src\microfrontend\lib\log_scale_util.c + + + noise_reduction.c + 1 + ..\micro_speech\src\microfrontend\lib\noise_reduction.c + + + noise_reduction_util.c + 1 + ..\micro_speech\src\microfrontend\lib\noise_reduction_util.c + + + pcan_gain_control.c + 1 + ..\micro_speech\src\microfrontend\lib\pcan_gain_control.c + + + pcan_gain_control_util.c + 1 + ..\micro_speech\src\microfrontend\lib\pcan_gain_control_util.c + + + window.c + 1 + ..\micro_speech\src\microfrontend\lib\window.c + + + window_util.c + 1 + ..\micro_speech\src\microfrontend\lib\window_util.c + + + + + TF_micro_features + + + micro_features_generator.cc + 8 + ..\micro_speech\src\micro_features\micro_features_generator.cc + + + micro_model_settings.cc + 8 + ..\micro_speech\src\micro_features\micro_model_settings.cc + + + model.cc + 8 + ..\micro_speech\src\micro_features\model.cc + + + no_micro_features_data.cc + 8 + ..\micro_speech\src\micro_features\no_micro_features_data.cc + + + yes_micro_features_data.cc + 8 + ..\micro_speech\src\micro_features\yes_micro_features_data.cc + + + + + TF_main + + + audio_provider.cc + 8 + ..\micro_speech\src\audio_provider.cc + + + command_responder.cc + 8 + ..\micro_speech\src\command_responder.cc + + + feature_provider.cc + 8 + ..\micro_speech\src\feature_provider.cc + + + main.cc + 8 + ..\micro_speech\src\main.cc + + + 2 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + + + + main_functions.cc + 8 + ..\micro_speech\src\main_functions.cc + + + recognize_commands.cc + 8 + ..\micro_speech\src\recognize_commands.cc + + + + + TF_test + + + audio_provider_mock.cc + 8 + ..\micro_speech\src\audio_provider_mock.cc + + + 2 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + + + + micro_speech_test.cc + 8 + ..\micro_speech\src\micro_speech_test.cc + + + 2 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + + + + audio_provider_mock_test.cc + 8 + ..\micro_speech\src\audio_provider_mock_test.cc + + + 2 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + + + + yes_1000ms_sample_data.cc + 8 + ..\micro_speech\src\yes_1000ms_sample_data.cc + + + 2 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + + + + no_1000ms_sample_data.cc + 8 + ..\micro_speech\src\no_1000ms_sample_data.cc + + + 2 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + + + + + + ::CMSIS + + + ::CMSIS Driver + + + ::Compiler + + + ::Data Exchange + + + ::Data Processing + + + ::Device + + + ::Machine Learning + + + ::Native Driver + + + + + Example Test + 0x4 + ARM-ADS + 6160000::V6.16::ARMCLANG + 1 + + + SSE-300-MPS3 + ARM + ARM.V2M_MPS3_SSE_300_BSP.1.2.0 + http://www.keil.com/pack/ + IRAM(0x38000000,0x00200000) IRAM2(0x28000000,0x00200000) IROM(0x10000000,0x00040000) IROM2(0x00000000,0x00040000) XRAM(0x38200000,0x00200000) XRAM2(0x28200000,0x00200000) XRAM3(0x31000000,0x00040000) CPUTYPE("Cortex-M55") FPU3(SFPU) DSP TZ CLOCK(12000000) ESEL ELITTLE + + + UL2V8M(-S0 -C0 -P0 -FD38000000 -FC1000) + 0 + $$Device:SSE-300-MPS3$Board\Platform\platform_description.h + + + + + + + + + + $$Device:SSE-300-MPS3$SVD\SSE300.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\Objects\ + microspeech + 1 + 0 + 1 + 1 + 1 + .\Listings\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + 1 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + + + + + SARMV8M.DLL + -MPU + TCM.DLL + -pCM55 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 0 + -1 + + 1 + BIN\UL2V8M.DLL + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M55" + + 1 + 0 + 0 + 1 + 1 + 1 + 0 + 1 + 0 + 0 + 1 + 1 + 8 + 0 + 1 + 0 + 2 + 4 + 4 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 1 + 1 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x38000000 + 0x200000 + + + 1 + 0x10000000 + 0x40000 + + + 1 + 0x38200000 + 0x200000 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x10000000 + 0x40000 + + + 1 + 0x0 + 0x40000 + + + 0 + 0x38200000 + 0x200000 + + + 0 + 0x28200000 + 0x200000 + + + 0 + 0x31000000 + 0x40000 + + + 0 + 0x30000000 + 0x40000 + + + 0 + 0x20000000 + 0x40000 + + + + + + 1 + 6 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 0 + 0 + 0 + 0 + 3 + 6 + 1 + 1 + 0 + 0 + 0 + + + __FVP_PY __TEST + + ..\VSI\include;..\VSI\audio\include;..\micro_speech\src + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 2 + + + + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x10000000 + 0x30000000 + + .\RTE\Device\SSE-300-MPS3\fvp_sse300_mps3_s.sct + + + --diag_suppress 6439,6314 + + + + + + + + App + + + microspeech.c + 1 + .\microspeech.c + + + 2 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + + + + + + Board + + + main.c + 1 + .\main.c + + + 2 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + + + + main.h + 5 + .\main.h + + + + + Board IO + + + retarget_stdio.c + 1 + .\Board_IO\retarget_stdio.c + + + + + Driver + + + audio_drv.c + 1 + ..\VSI\audio\driver\audio_drv.c + + + + + TF_micro_frontend + + + fft.cc + 8 + ..\micro_speech\src\microfrontend\lib\fft.cc + + + fft_util.cc + 8 + ..\micro_speech\src\microfrontend\lib\fft_util.cc + + + filterbank.c + 1 + ..\micro_speech\src\microfrontend\lib\filterbank.c + + + filterbank_util.c + 1 + ..\micro_speech\src\microfrontend\lib\filterbank_util.c + + + frontend.c + 1 + ..\micro_speech\src\microfrontend\lib\frontend.c + + + frontend_util.c + 1 + ..\micro_speech\src\microfrontend\lib\frontend_util.c + + + log_lut.c + 1 + ..\micro_speech\src\microfrontend\lib\log_lut.c + + + log_scale.c + 1 + ..\micro_speech\src\microfrontend\lib\log_scale.c + + + log_scale_util.c + 1 + ..\micro_speech\src\microfrontend\lib\log_scale_util.c + + + noise_reduction.c + 1 + ..\micro_speech\src\microfrontend\lib\noise_reduction.c + + + noise_reduction_util.c + 1 + ..\micro_speech\src\microfrontend\lib\noise_reduction_util.c + + + pcan_gain_control.c + 1 + ..\micro_speech\src\microfrontend\lib\pcan_gain_control.c + + + pcan_gain_control_util.c + 1 + ..\micro_speech\src\microfrontend\lib\pcan_gain_control_util.c + + + window.c + 1 + ..\micro_speech\src\microfrontend\lib\window.c + + + window_util.c + 1 + ..\micro_speech\src\microfrontend\lib\window_util.c + + + + + TF_micro_features + + + micro_features_generator.cc + 8 + ..\micro_speech\src\micro_features\micro_features_generator.cc + + + micro_model_settings.cc + 8 + ..\micro_speech\src\micro_features\micro_model_settings.cc + + + model.cc + 8 + ..\micro_speech\src\micro_features\model.cc + + + no_micro_features_data.cc + 8 + ..\micro_speech\src\micro_features\no_micro_features_data.cc + + + yes_micro_features_data.cc + 8 + ..\micro_speech\src\micro_features\yes_micro_features_data.cc + + + + + TF_main + + + audio_provider.cc + 8 + ..\micro_speech\src\audio_provider.cc + + + command_responder.cc + 8 + ..\micro_speech\src\command_responder.cc + + + feature_provider.cc + 8 + ..\micro_speech\src\feature_provider.cc + + + main.cc + 8 + ..\micro_speech\src\main.cc + + + 2 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + + + + main_functions.cc + 8 + ..\micro_speech\src\main_functions.cc + + + 2 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + + + + recognize_commands.cc + 8 + ..\micro_speech\src\recognize_commands.cc + + + + + TF_test + + + audio_provider_mock.cc + 8 + ..\micro_speech\src\audio_provider_mock.cc + + + 2 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + + + + micro_speech_test.cc + 8 + ..\micro_speech\src\micro_speech_test.cc + + + audio_provider_mock_test.cc + 8 + ..\micro_speech\src\audio_provider_mock_test.cc + + + 2 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + + + + yes_1000ms_sample_data.cc + 8 + ..\micro_speech\src\yes_1000ms_sample_data.cc + + + 2 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + + + + no_1000ms_sample_data.cc + 8 + ..\micro_speech\src\no_1000ms_sample_data.cc + + + 2 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + + + + + + ::CMSIS + + + ::CMSIS Driver + + + ::Compiler + + + ::Data Exchange + + + ::Data Processing + + + ::Device + + + ::Machine Learning + + + ::Native Driver + + + + + Audio Provider Mock + 0x4 + ARM-ADS + 6160000::V6.16::ARMCLANG + 1 + + + SSE-300-MPS3 + ARM + ARM.V2M_MPS3_SSE_300_BSP.1.2.0 + http://www.keil.com/pack/ + IRAM(0x38000000,0x00200000) IRAM2(0x28000000,0x00200000) IROM(0x10000000,0x00040000) IROM2(0x00000000,0x00040000) XRAM(0x38200000,0x00200000) XRAM2(0x28200000,0x00200000) XRAM3(0x31000000,0x00040000) CPUTYPE("Cortex-M55") FPU3(SFPU) DSP TZ CLOCK(12000000) ESEL ELITTLE + + + UL2V8M(-S0 -C0 -P0 -FD38000000 -FC1000) + 0 + $$Device:SSE-300-MPS3$Board\Platform\platform_description.h + + + + + + + + + + $$Device:SSE-300-MPS3$SVD\SSE300.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\Objects\ + microspeech + 1 + 0 + 1 + 1 + 1 + .\Listings\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + 1 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + + + + + SARMV8M.DLL + -MPU + TCM.DLL + -pCM55 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 0 + 4102 + + 1 + BIN\UL2V8M.DLL + "" () + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M55" + + 1 + 0 + 0 + 1 + 1 + 1 + 0 + 1 + 0 + 0 + 1 + 1 + 8 + 0 + 1 + 0 + 2 + 4 + 4 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 1 + 1 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x38000000 + 0x200000 + + + 1 + 0x10000000 + 0x40000 + + + 1 + 0x38200000 + 0x200000 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x10000000 + 0x40000 + + + 1 + 0x0 + 0x40000 + + + 0 + 0x38200000 + 0x200000 + + + 0 + 0x28200000 + 0x200000 + + + 0 + 0x31000000 + 0x40000 + + + 0 + 0x30000000 + 0x40000 + + + 0 + 0x20000000 + 0x40000 + + + + + + 1 + 6 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 0 + 0 + 0 + 0 + 3 + 6 + 1 + 1 + 0 + 0 + 0 + + + + + ..\micro_speech\src + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 2 + + + + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x10000000 + 0x30000000 + + .\RTE\Device\SSE-300-MPS3\fvp_sse300_mps3_s.sct + + + --diag_suppress 6439,6314 + + + + + + + + App + + + microspeech.c + 1 + .\microspeech.c + + + + + Board + + + main.c + 1 + .\main.c + + + main.h + 5 + .\main.h + + + + + Board IO + + + retarget_stdio.c + 1 + .\Board_IO\retarget_stdio.c + + + + + Driver + + + audio_drv.c + 1 + ..\VSI\audio\driver\audio_drv.c + + + 2 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + + + + + + TF_micro_frontend + + + fft.cc + 8 + ..\micro_speech\src\microfrontend\lib\fft.cc + + + fft_util.cc + 8 + ..\micro_speech\src\microfrontend\lib\fft_util.cc + + + filterbank.c + 1 + ..\micro_speech\src\microfrontend\lib\filterbank.c + + + filterbank_util.c + 1 + ..\micro_speech\src\microfrontend\lib\filterbank_util.c + + + frontend.c + 1 + ..\micro_speech\src\microfrontend\lib\frontend.c + + + frontend_util.c + 1 + ..\micro_speech\src\microfrontend\lib\frontend_util.c + + + log_lut.c + 1 + ..\micro_speech\src\microfrontend\lib\log_lut.c + + + log_scale.c + 1 + ..\micro_speech\src\microfrontend\lib\log_scale.c + + + log_scale_util.c + 1 + ..\micro_speech\src\microfrontend\lib\log_scale_util.c + + + noise_reduction.c + 1 + ..\micro_speech\src\microfrontend\lib\noise_reduction.c + + + noise_reduction_util.c + 1 + ..\micro_speech\src\microfrontend\lib\noise_reduction_util.c + + + pcan_gain_control.c + 1 + ..\micro_speech\src\microfrontend\lib\pcan_gain_control.c + + + pcan_gain_control_util.c + 1 + ..\micro_speech\src\microfrontend\lib\pcan_gain_control_util.c + + + window.c + 1 + ..\micro_speech\src\microfrontend\lib\window.c + + + window_util.c + 1 + ..\micro_speech\src\microfrontend\lib\window_util.c + + + + + TF_micro_features + + + micro_features_generator.cc + 8 + ..\micro_speech\src\micro_features\micro_features_generator.cc + + + micro_model_settings.cc + 8 + ..\micro_speech\src\micro_features\micro_model_settings.cc + + + model.cc + 8 + ..\micro_speech\src\micro_features\model.cc + + + no_micro_features_data.cc + 8 + ..\micro_speech\src\micro_features\no_micro_features_data.cc + + + yes_micro_features_data.cc + 8 + ..\micro_speech\src\micro_features\yes_micro_features_data.cc + + + + + TF_main + + + audio_provider.cc + 8 + ..\micro_speech\src\audio_provider.cc + + + 2 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + + + + command_responder.cc + 8 + ..\micro_speech\src\command_responder.cc + + + feature_provider.cc + 8 + ..\micro_speech\src\feature_provider.cc + + + main.cc + 8 + ..\micro_speech\src\main.cc + + + 2 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + + + + main_functions.cc + 8 + ..\micro_speech\src\main_functions.cc + + + recognize_commands.cc + 8 + ..\micro_speech\src\recognize_commands.cc + + + + + TF_test + + + audio_provider_mock.cc + 8 + ..\micro_speech\src\audio_provider_mock.cc + + + micro_speech_test.cc + 8 + ..\micro_speech\src\micro_speech_test.cc + + + 2 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + + + + audio_provider_mock_test.cc + 8 + ..\micro_speech\src\audio_provider_mock_test.cc + + + 2 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + + + + yes_1000ms_sample_data.cc + 8 + ..\micro_speech\src\yes_1000ms_sample_data.cc + + + no_1000ms_sample_data.cc + 8 + ..\micro_speech\src\no_1000ms_sample_data.cc + + + + + ::CMSIS + + + ::CMSIS Driver + + + ::Compiler + + + ::Data Exchange + + + ::Data Processing + + + ::Device + + + ::Machine Learning + + + ::Native Driver + + + + + Audio Provider Mock Test + 0x4 + ARM-ADS + 6160000::V6.16::ARMCLANG + 1 + + + SSE-300-MPS3 + ARM + ARM.V2M_MPS3_SSE_300_BSP.1.2.0 + http://www.keil.com/pack/ + IRAM(0x38000000,0x00200000) IRAM2(0x28000000,0x00200000) IROM(0x10000000,0x00040000) IROM2(0x00000000,0x00040000) XRAM(0x38200000,0x00200000) XRAM2(0x28200000,0x00200000) XRAM3(0x31000000,0x00040000) CPUTYPE("Cortex-M55") FPU3(SFPU) DSP TZ CLOCK(12000000) ESEL ELITTLE + + + UL2V8M(-S0 -C0 -P0 -FD38000000 -FC1000) + 0 + $$Device:SSE-300-MPS3$Board\Platform\platform_description.h + + + + + + + + + + $$Device:SSE-300-MPS3$SVD\SSE300.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\Objects\ + microspeech + 1 + 0 + 1 + 1 + 1 + .\Listings\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + 1 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + + + + + SARMV8M.DLL + -MPU + TCM.DLL + -pCM55 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 0 + 4102 + + 1 + BIN\UL2V8M.DLL + "" () + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M55" + + 1 + 0 + 0 + 1 + 1 + 1 + 0 + 1 + 0 + 0 + 1 + 1 + 8 + 0 + 1 + 0 + 2 + 4 + 4 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 1 + 1 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x38000000 + 0x200000 + + + 1 + 0x10000000 + 0x40000 + + + 1 + 0x38200000 + 0x200000 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x10000000 + 0x40000 + + + 1 + 0x0 + 0x40000 + + + 0 + 0x38200000 + 0x200000 + + + 0 + 0x28200000 + 0x200000 + + + 0 + 0x31000000 + 0x40000 + + + 0 + 0x30000000 + 0x40000 + + + 0 + 0x20000000 + 0x40000 + + + + + + 1 + 6 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 0 + 0 + 0 + 0 + 3 + 6 + 1 + 1 + 0 + 0 + 0 + + + __TEST + + ..\micro_speech\src + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 2 + + + + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x10000000 + 0x30000000 + + .\RTE\Device\SSE-300-MPS3\fvp_sse300_mps3_s.sct + + + --diag_suppress 6439,6314 + + + + + + + + App + + + microspeech.c + 1 + .\microspeech.c + + + 2 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + + + + + + Board + + + main.c + 1 + .\main.c + + + 2 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + + + + main.h + 5 + .\main.h + + + + + Board IO + + + retarget_stdio.c + 1 + .\Board_IO\retarget_stdio.c + + + + + Driver + + + audio_drv.c + 1 + ..\VSI\audio\driver\audio_drv.c + + + 2 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + + + + + + TF_micro_frontend + + + fft.cc + 8 + ..\micro_speech\src\microfrontend\lib\fft.cc + + + fft_util.cc + 8 + ..\micro_speech\src\microfrontend\lib\fft_util.cc + + + filterbank.c + 1 + ..\micro_speech\src\microfrontend\lib\filterbank.c + + + filterbank_util.c + 1 + ..\micro_speech\src\microfrontend\lib\filterbank_util.c + + + frontend.c + 1 + ..\micro_speech\src\microfrontend\lib\frontend.c + + + frontend_util.c + 1 + ..\micro_speech\src\microfrontend\lib\frontend_util.c + + + log_lut.c + 1 + ..\micro_speech\src\microfrontend\lib\log_lut.c + + + log_scale.c + 1 + ..\micro_speech\src\microfrontend\lib\log_scale.c + + + log_scale_util.c + 1 + ..\micro_speech\src\microfrontend\lib\log_scale_util.c + + + noise_reduction.c + 1 + ..\micro_speech\src\microfrontend\lib\noise_reduction.c + + + noise_reduction_util.c + 1 + ..\micro_speech\src\microfrontend\lib\noise_reduction_util.c + + + pcan_gain_control.c + 1 + ..\micro_speech\src\microfrontend\lib\pcan_gain_control.c + + + pcan_gain_control_util.c + 1 + ..\micro_speech\src\microfrontend\lib\pcan_gain_control_util.c + + + window.c + 1 + ..\micro_speech\src\microfrontend\lib\window.c + + + window_util.c + 1 + ..\micro_speech\src\microfrontend\lib\window_util.c + + + + + TF_micro_features + + + micro_features_generator.cc + 8 + ..\micro_speech\src\micro_features\micro_features_generator.cc + + + micro_model_settings.cc + 8 + ..\micro_speech\src\micro_features\micro_model_settings.cc + + + model.cc + 8 + ..\micro_speech\src\micro_features\model.cc + + + no_micro_features_data.cc + 8 + ..\micro_speech\src\micro_features\no_micro_features_data.cc + + + yes_micro_features_data.cc + 8 + ..\micro_speech\src\micro_features\yes_micro_features_data.cc + + + + + TF_main + + + audio_provider.cc + 8 + ..\micro_speech\src\audio_provider.cc + + + 2 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + + + + command_responder.cc + 8 + ..\micro_speech\src\command_responder.cc + + + feature_provider.cc + 8 + ..\micro_speech\src\feature_provider.cc + + + main.cc + 8 + ..\micro_speech\src\main.cc + + + 2 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + + + + main_functions.cc + 8 + ..\micro_speech\src\main_functions.cc + + + 2 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + + + + recognize_commands.cc + 8 + ..\micro_speech\src\recognize_commands.cc + + + + + TF_test + + + audio_provider_mock.cc + 8 + ..\micro_speech\src\audio_provider_mock.cc + + + micro_speech_test.cc + 8 + ..\micro_speech\src\micro_speech_test.cc + + + 2 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + + + + audio_provider_mock_test.cc + 8 + ..\micro_speech\src\audio_provider_mock_test.cc + + + yes_1000ms_sample_data.cc + 8 + ..\micro_speech\src\yes_1000ms_sample_data.cc + + + no_1000ms_sample_data.cc + 8 + ..\micro_speech\src\no_1000ms_sample_data.cc + + + + + ::CMSIS + + + ::CMSIS Driver + + + ::Compiler + + + ::Data Exchange + + + ::Data Processing + + + ::Device + + + ::Machine Learning + + + ::Native Driver + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + RTE\CMSIS\RTX_Config.c + + + + + + + + + + + RTE\CMSIS\RTX_Config.h + + + + + + + + + + + RTE\Compiler\EventRecorderConf.h + + + + + + + + + + + RTE\Device\SSE-300-MPS3\RTE_Device.h + + + + + + + + + + + RTE\Device\SSE-300-MPS3\cmsis_driver_config.h + + + + + + + + + + + RTE\Device\SSE-300-MPS3\device_cfg.h + + + + + + + + + + + RTE\Device\SSE-300-MPS3\fvp_sse300_mps3_s.sct + + + + + + + + + + + RTE\Device\SSE-300-MPS3\platform_base_address.h + + + + + + + + + + + RTE\Device\SSE-300-MPS3\region_defs.h + + + + + + + + + + + RTE\Device\SSE-300-MPS3\region_limits.h + + + + + + + + + + + RTE\Device\SSE-300-MPS3\startup_fvp_sse300_mps3.c + + + + + + + + + + + RTE\Device\SSE-300-MPS3\system_SSE300MPS3.c + + + + + + + + + + + RTE\Device\SSE-300-MPS3\system_core_init.c + + + + + + RTE\Machine_Learning\debug_log.cc + + + + + + + + + + + RTE\Machine_Learning\micro_time.cc + + + + + + + + + + + RTE\Machine_Learning\system_setup.cc + + + + + + + + + + + + + + + + Blinky + 0 + 1 + + + + +
diff --git a/Platform_FVP_Corstone_SSE-300_Ethos-U55/mps3_config.txt b/Platform_FVP_Corstone_SSE-300_Ethos-U55/mps3_config.txt new file mode 100644 index 0000000..c83dde3 --- /dev/null +++ b/Platform_FVP_Corstone_SSE-300_Ethos-U55/mps3_config.txt @@ -0,0 +1,6 @@ +# Parameters: +# instance.parameter=value #(type, mode) default = 'def value' : description : [min..max] +#------------------------------------------------------------------------------ +core_clk.mul=200000000 # (int , init-time) default = '0x17d7840' : Clock Rate Multiplier. This parameter is not exposed via CADI and can only be set in LISA +mps3_board.visualisation.disable-visualisation=1 # (bool , init-time) default = '0' : Enable/disable visualisation +#------------------------------------------------------------------------------ diff --git a/Platform_FVP_Corstone_SSE-300_Ethos-U55/packlist b/Platform_FVP_Corstone_SSE-300_Ethos-U55/packlist new file mode 100644 index 0000000..0d69b31 --- /dev/null +++ b/Platform_FVP_Corstone_SSE-300_Ethos-U55/packlist @@ -0,0 +1,8 @@ +https://github.com/MDK-Packs/tensorflow-pack/releases/download/preview-0.3/tensorflow.flatbuffers.0.1.20210719.pack +https://github.com/MDK-Packs/tensorflow-pack/releases/download/preview-0.3/tensorflow.kissfft.0.1.20210719.pack +https://github.com/MDK-Packs/tensorflow-pack/releases/download/preview-0.3/tensorflow.ruy.0.1.20210719.pack +https://github.com/MDK-Packs/tensorflow-pack/releases/download/preview-0.3/tensorflow.gemmlowp.0.0.1.20210719.pack +https://github.com/MDK-Packs/tensorflow-pack/releases/download/preview-0.3/tensorflow.tensorflow-lite-micro.0.2.20210719.pack +https://github.com/MDK-Packs/tensorflow-pack/releases/download/preview-0.3/Arm.ethos-u-core-driver.0.1.20210719.pack +https://www.keil.com/pack/ARM.CMSIS.5.8.0.pack +https://keilpack.azureedge.net/pack/ARM.V2M_MPS3_SSE_300_BSP.1.2.0.pack diff --git a/Platform_FVP_Corstone_SSE-300_Ethos-U55/run_audio_provider_mock.cmd b/Platform_FVP_Corstone_SSE-300_Ethos-U55/run_audio_provider_mock.cmd new file mode 100644 index 0000000..a7c4040 --- /dev/null +++ b/Platform_FVP_Corstone_SSE-300_Ethos-U55/run_audio_provider_mock.cmd @@ -0,0 +1,2 @@ +@echo off +"C:\Program Files\ARM\FVP_Corstone_SSE-300\models\Win64_VC2017\FVP_Corstone_SSE-300_Ethos-U55.exe" -f mps3_config.txt -a Objects\microspeech.axf %* diff --git a/Platform_FVP_Corstone_SSE-300_Ethos-U55/run_example.cmd b/Platform_FVP_Corstone_SSE-300_Ethos-U55/run_example.cmd new file mode 100644 index 0000000..b0eb667 --- /dev/null +++ b/Platform_FVP_Corstone_SSE-300_Ethos-U55/run_example.cmd @@ -0,0 +1,2 @@ +@echo off +"C:\Program Files\ARM\VHT\models\Win64_VC2017\arm_vsi.exe" -V "..\VSI\audio\python" -f fvp_config.txt -a Objects\microspeech.axf --stat --cyclelimit 4000000000 %* diff --git a/Platform_FVP_Corstone_SSE-300_Ethos-U55/run_example.sh b/Platform_FVP_Corstone_SSE-300_Ethos-U55/run_example.sh new file mode 100644 index 0000000..9bcebf5 --- /dev/null +++ b/Platform_FVP_Corstone_SSE-300_Ethos-U55/run_example.sh @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +arm_vsi.x -V "../VSI/audio/python" -f fvp_config.txt -a Objects/microspeech.axf --stat --cyclelimit 4000000000 $* diff --git a/Platform_FVP_Corstone_SSE-300_Ethos-U55/test.wav b/Platform_FVP_Corstone_SSE-300_Ethos-U55/test.wav new file mode 100644 index 0000000000000000000000000000000000000000..f1d06c392cc49648fa870d36162b5cdc66798ca0 GIT binary patch literal 768044 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 +#include "fsl_debug_console.h" // NXP::Device:SDK Utilities:debug_console + +int DbgConsole_SendDataReliable(uint8_t *ch, size_t size); +int DbgConsole_ReadCharacter(uint8_t *ch); + +/** + Put a character to the stderr + + \param[in] ch Character to output + \return The character written, or -1 on write error. +*/ +int stderr_putchar (int ch) { + int32_t ret; + + ret = DbgConsole_SendDataReliable((uint8_t *)(&ch), 1); + + if (ret!= -1) { + ret = ch; + } + return (ret); +} + +/** + Put a character to the stdout + + \param[in] ch Character to output + \return The character written, or -1 on write error. +*/ +int stdout_putchar (int ch) { + int32_t ret; + + ret = DbgConsole_SendDataReliable((uint8_t *)(&ch), 1); + + if (ret!= -1) { + ret = ch; + } + return (ret); +} + +/** + Get a character from the stdio + + \return The next character from the input, or -1 on read error. +*/ +int stdin_getchar (void) { + int32_t ret; + uint8_t ch; + + ret = DbgConsole_ReadCharacter(&ch); + + if (ret!= -1) { + ret = ch; + } + return (ret); +} diff --git a/Platform_MIMXRT1064-EVK/Driver_Audio/Audio_MIMXRT1064-EVK.c b/Platform_MIMXRT1064-EVK/Driver_Audio/Audio_MIMXRT1064-EVK.c new file mode 100644 index 0000000..1a7f13d --- /dev/null +++ b/Platform_MIMXRT1064-EVK/Driver_Audio/Audio_MIMXRT1064-EVK.c @@ -0,0 +1,604 @@ +/*--------------------------------------------------------------------------- + * Copyright (c) 2021 Arm Limited (or its affiliates). + * All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *---------------------------------------------------------------------------*/ + +#include "Audio_MIMXRT1064-EVK.h" + +/* DMA handles */ +edma_handle_t DmaTxHandle = {0}; +edma_handle_t DmaRxHandle = {0}; + +sai_edma_handle_t DmaSaiTxHandle; +sai_edma_handle_t DmaSaiRxHandle; + +sai_handle_t SaiTxHandle = {0}; +sai_handle_t SaiRxHandle = {0}; + +/* SAI transceiver config */ +sai_transceiver_t SaiConfig; + +/* Codec handle */ +codec_handle_t CodecHandle; + +static AUDIO_CB AudioCb = {0}; + +/** + \fn int32_t AudioDrv_Initialize (AudioDrv_Event_t cb_event) + \brief Initialize Audio Interface. + \param[in] cb_event Pointer to \ref AudioDrv_Event_t + \return return code +*/ +int32_t AudioDrv_Initialize (AudioDrv_Event_t cb_event) { + + AudioCb.callback = cb_event; + AudioCb.flags = 0U; + + #if SAI_DMA_ENABLE_TX + AudioCb.flags |= AUDIO_FLAGS_DMA_TX; + #endif + + #if SAI_DMA_ENABLE_RX + AudioCb.flags |= AUDIO_FLAGS_DMA_RX; + #endif + + /* Initialize SAI */ + SAI_Init(SAI_INSTANCE); + + if ((AudioCb.flags & AUDIO_FLAGS_DMA_TX) != 0U) { + /* Setup DMAMUX */ + DMAMUX_SetSource (DMAMUX, SAI_DMA_CHANNEL_TX, (uint8_t)SAI_DMA_SOURCE_TX); + DMAMUX_EnableChannel(DMAMUX, SAI_DMA_CHANNEL_TX); + + /* Initialize DMA handles */ + EDMA_CreateHandle(&DmaTxHandle, DMA0, SAI_DMA_CHANNEL_TX); + + SAI_TransferTxCreateHandleEDMA(SAI_INSTANCE, &DmaSaiTxHandle, DMA_Transmit_Cb, NULL, &DmaTxHandle); + } else { + SAI_TransferTxCreateHandle (SAI_INSTANCE, &SaiTxHandle, IRQ_Transmit_Cb, NULL); + } + + if ((AudioCb.flags & AUDIO_FLAGS_DMA_RX) != 0U) { + /* Setup DMAMUX */ + DMAMUX_SetSource (DMAMUX, SAI_DMA_CHANNEL_RX, (uint8_t)SAI_DMA_SOURCE_RX); + DMAMUX_EnableChannel(DMAMUX, SAI_DMA_CHANNEL_RX); + + /* Initialize DMA handles */ + EDMA_CreateHandle(&DmaRxHandle, DMA0, SAI_DMA_CHANNEL_RX); + + SAI_TransferRxCreateHandleEDMA(SAI_INSTANCE, &DmaSaiRxHandle, DMA_Receive_Cb, NULL, &DmaRxHandle); + } else { + SAI_TransferRxCreateHandle (SAI_INSTANCE, &SaiRxHandle, IRQ_Receive_Cb, NULL); + } + + /* Driver is initialized */ + AudioCb.flags |= AUDIO_FLAGS_INIT; + + return (AUDIO_DRV_OK); +} + +/** + \fn int32_t AudioDrv_Uninitialize (void) + \brief De-initialize Audio Interface. + \return return code +*/ +int32_t AudioDrv_Uninitialize (void) { + int32_t status; + + if (AudioCb.status.tx_active == 1U) { + /* Stop transmit DMA channel */ + SAI_TransferTerminateSendEDMA (SAI_INSTANCE, &DmaSaiTxHandle); + } + + if (AudioCb.status.rx_active == 1U) { + /* Stop receive DMA channel */ + SAI_TransferTerminateReceiveEDMA(SAI_INSTANCE, &DmaSaiRxHandle); + } + + /* Clear all flags */ + AudioCb.flags = 0U; + + return (AUDIO_DRV_OK); +} + +/** + \fn int32_t AudioDrv_Configure (uint32_t interface, uint32_t channels, uint32_t sample_bits, uint32_t sample_freq) + \brief Configure Audio Interface. + \param[in] interface Audio Interface + \param[in] channels Number of channels + \param[in] sample_bits Sample number of bits (8..32) + \param[in] sample_rate Sample rate (samples per second) + \return return code +*/ +int32_t AudioDrv_Configure (uint32_t interface, uint32_t channels, uint32_t sample_bits, uint32_t sample_rate) { + int32_t status; + int32_t i; + uint32_t clock_freq; + sai_mono_stereo_t mode; + + if ((interface != AUDIO_DRV_INTERFACE_TX) && (interface != AUDIO_DRV_INTERFACE_RX)) { + return AUDIO_DRV_ERROR_PARAMETER; + } + + if ((channels < 1U) || (channels > 32U) || + (sample_bits < 8U) || (sample_bits > 32U) || + (sample_rate == 0U)) { + return AUDIO_DRV_ERROR_PARAMETER; + } + + if ((AudioCb.flags & AUDIO_FLAGS_INIT) == 0U) { + /* Not initialized */ + return AUDIO_DRV_ERROR; + } + + if (channels == 1U) { + /* Set left or right mono mode */ + mode = SAI_MODE_MONO; + } + else if (channels == 2U) { + /* Set stereo mode */ + mode = kSAI_Stereo; + } + else { + return AUDIO_DRV_ERROR_UNSUPPORTED; + } + + /* Set initial config */ + SAI_GetClassicI2SConfig(&SaiConfig, sample_bits, mode, 1U); + + if (interface == AUDIO_DRV_INTERFACE_RX) { + /* Configure receiver */ + SaiConfig.syncMode = SAI_SYNC_MODE_RX; + SaiConfig.masterSlave = SAI_MODE_MASTERSLAVE; + + if ((AudioCb.flags & AUDIO_FLAGS_DMA_RX) != 0U) { + SAI_TransferRxSetConfigEDMA (SAI_INSTANCE, &DmaSaiRxHandle, &SaiConfig); + } else { + SAI_TransferRxSetConfig (SAI_INSTANCE, &SaiRxHandle, &SaiConfig); + } + + clock_freq = GetSaiClockFreq (SAI_INSTANCE); + + SAI_RxSetBitClockRate (SAI_INSTANCE, clock_freq, sample_rate, sample_bits, channels); + //} + //else /* if (interface == AUDIO_DRV_INTERFACE_TX) */ { + /* Configure transmitter */ + SaiConfig.syncMode = SAI_SYNC_MODE_TX; + SaiConfig.masterSlave = SAI_MODE_MASTERSLAVE; + + if ((AudioCb.flags & AUDIO_FLAGS_DMA_TX) != 0U) { + SAI_TransferTxSetConfigEDMA (SAI_INSTANCE, &DmaSaiTxHandle, &SaiConfig); + } else { + SAI_TransferTxSetConfig (SAI_INSTANCE, &SaiTxHandle, &SaiConfig); + } + + clock_freq = GetSaiClockFreq (SAI_INSTANCE); + + SAI_TxSetBitClockRate (SAI_INSTANCE, clock_freq, sample_rate, sample_bits, channels); + } + + /* Setup audio codec */ + status = Codec_Setup (clock_freq, sample_rate, sample_bits); + + return (status); +} + +/** + \fn int32_t AudioDrv_SetBuf (uint32_t interface, void *buf, uint32_t block_count, uint32_t block_size) + \brief Set Audio Interface buffer. + \param[in] interface Audio Interface + \param[in] buf Pointer to buffer for audio data + \param[in] block_num Number of blocks in buffer (must be 2^n) + \param[in] block_size Block size in number of samples + \return return code +*/ +int32_t AudioDrv_SetBuf (uint32_t interface, void *buf, uint32_t block_num, uint32_t block_size) { + int32_t status; + AUDIO_BUF *p; + + if ((interface != AUDIO_DRV_INTERFACE_TX) && (interface != AUDIO_DRV_INTERFACE_RX)) { + return AUDIO_DRV_ERROR_PARAMETER; + } + + if (buf == NULL) { + return AUDIO_DRV_ERROR_PARAMETER; + } + + status = AUDIO_DRV_OK; + + if (interface == AUDIO_DRV_INTERFACE_RX) { + if (AudioCb.status.rx_active == 0U) { + /* Set receive buffer */ + p = &AudioCb.rx_buf; + + p->data = buf; + p->block_num = block_num; + p->block_size = block_size; + } + else { + status = AUDIO_DRV_ERROR_BUSY; + } + } + else /* if (interface == AUDIO_DRV_INTERFACE_TX) */ { + if (AudioCb.status.tx_active == 0U) { + /* Set transmit buffer */ + p = &AudioCb.tx_buf; + + p->data = buf; + p->block_num = block_num; + p->block_size = block_size; + } + else { + status = AUDIO_DRV_ERROR_BUSY; + } + } + + return (status); +} + +/** + \fn int32_t AudioDrv_Control (uint32_t control) + \brief Control Audio Interface. + \param[in] control Operation + \return return code +*/ +int32_t AudioDrv_Control (uint32_t control) { + int32_t status; + + if ((AudioCb.flags & AUDIO_FLAGS_INIT) == 0U) { + /* Not initialized */ + return AUDIO_DRV_ERROR; + } + + if ((control & AUDIO_DRV_CONTROL_TX_ENABLE) != 0U) { + AudioCb.status.tx_active = 1U; + AudioCb.tx_cnt = 0U; + + status = TriggerSend (AudioCb.tx_buf.block_num); + } + else if ((control & AUDIO_DRV_CONTROL_RX_ENABLE) != 0U) { + AudioCb.status.rx_active = 1U; + AudioCb.rx_cnt = 0U; + + status = TriggerReceive (AudioCb.rx_buf.block_num); + } + else { + status = AUDIO_DRV_OK; + + if ((control & AUDIO_DRV_CONTROL_TX_DISABLE) != 0U) { + AudioCb.status.tx_active = 0U; + + SAI_TransferTerminateSendEDMA (SAI_INSTANCE, &DmaSaiTxHandle); + } + else if ((control & AUDIO_DRV_CONTROL_RX_DISABLE) != 0U) { + AudioCb.status.rx_active = 0U; + + SAI_TransferTerminateReceiveEDMA (SAI_INSTANCE, &DmaSaiRxHandle); + } + else { + status = AUDIO_DRV_ERROR_UNSUPPORTED; + } + } + + return (status); +} + +/** + \fn uint32_t AudioDrv_GetTxCount (void) + \brief Get transmitted block count. + \return number of transmitted blocks +*/ +uint32_t AudioDrv_GetTxCount (void) { + return (AudioCb.tx_cnt); +} + +/** + \fn uint32_t AudioDrv_GetRxCount (void) + \brief Get received block count. + \return number of received blocks +*/ +uint32_t AudioDrv_GetRxCount (void) { +return (AudioCb.rx_cnt); +} + +/** + \fn AudioDrv_Status_t AudioDrv_GetStatus (void) + \brief Get Audio Interface status. + \return \ref AudioDrv_Status_t +*/ +AudioDrv_Status_t AudioDrv_GetStatus (void) { + return (AudioCb.status); +} + +/** + IRQ receive callback +*/ +static void IRQ_Receive_Cb (I2S_Type *base, sai_handle_t *handle, status_t status, void *userData) { + + if (status == kStatus_SAI_RxIdle) { + /* Increment receiver block count */ + AudioCb.rx_cnt++; + + /* Set new receive buffer */ + TriggerReceive(1U); + + /* Call application callback function */ + if (AudioCb.callback != NULL) { + AudioCb.callback (AUDIO_DRV_EVENT_RX_DATA); + } + } + else { + // kStatus_SAI_QueueFull, kStatus_SAI_RxBusy, kStatus_SAI_RxError + } + +} + +/** + IRQ transmit callback +*/ +static void IRQ_Transmit_Cb (I2S_Type *base, sai_handle_t *handle, status_t status, void *userData) { + + if (status == kStatus_SAI_TxIdle) { + /* Increment transmitter block count */ + AudioCb.tx_cnt++; + + /* Set new transmit buffer */ + TriggerSend(1U); + + /* Call application callback function */ + if (AudioCb.callback != NULL) { + AudioCb.callback (AUDIO_DRV_EVENT_TX_DATA); + } + } + else { + // kStatus_SAI_QueueFull, kStatus_SAI_TxBusy, kStatus_SAI_TxError + } +} + +/** + DMA receive callback +*/ +uint32_t Rx_QueueFull = 0; +static void DMA_Receive_Cb (I2S_Type *base, sai_edma_handle_t *handle, status_t status, void *userData) { + + if (status == kStatus_SAI_RxIdle) { + /* Increment receiver block count */ + AudioCb.rx_cnt++; + + /* Set new receive buffer */ + TriggerReceive(1U); + + /* Call application callback function */ + if (AudioCb.callback != NULL) { + AudioCb.callback (AUDIO_DRV_EVENT_RX_DATA); + } + } + else { + // kStatus_SAI_QueueFull, kStatus_SAI_RxBusy, kStatus_SAI_RxError + Rx_QueueFull++; + } +} + +/** + DMA transmit callback +*/ +uint32_t Tx_QueueFull = 0; +static void DMA_Transmit_Cb (I2S_Type *base, sai_edma_handle_t *handle, status_t status, void *userData) { + + if (status == kStatus_SAI_TxIdle) { + /* Increment transmitter block count */ + AudioCb.tx_cnt++; + + /* Set new transmit buffer */ + TriggerSend(1U); + + /* Call application callback function */ + if (AudioCb.callback != NULL) { + AudioCb.callback (AUDIO_DRV_EVENT_TX_DATA); + } + } + else { + // kStatus_SAI_QueueFull, kStatus_SAI_TxBusy, kStatus_SAI_TxError + Tx_QueueFull++; + } +} + +/** + Get SAI instance clock frequency. +*/ +static uint32_t GetSaiClockFreq (I2S_Type *sai_instance) { + uint32_t clk; + uint32_t clk_pred; + uint32_t clk_podf; + + /* Get audio pll clk */ + clk = CLOCK_GetFreq (kCLOCK_AudioPllClk); + + if (sai_instance == SAI1) { + /* Get clock pre-divider (1 - 8) */ + clk_pred = CLOCK_GetDiv (kCLOCK_Sai1PreDiv); + /* Get clock divider (1 - 64) */ + clk_podf = CLOCK_GetDiv (kCLOCK_Sai1Div); + } + else { + clk = 0U; + } + + return (clk / (clk_pred + 1U) / (clk_podf + 1U)); +} + +/** + Get I2C instance clock frequency. +*/ +static uint32_t GetI2CClockFreq (LPI2C_Type *i2c_instance) { + uint32_t clk; + uint32_t clk_div; + uint32_t clk_podf; + + /* Get USB1 pll clk */ + clk = CLOCK_GetFreq (kCLOCK_Usb1PllClk); + + /* Set static divider value */ + clk_div = 8U; + + if (i2c_instance == LPI2C1) { + /* Get clock divider */ + clk_podf = CLOCK_GetDiv (kCLOCK_Lpi2cDiv); + } + else { + clk = 0U; + } + + return (clk / clk_div / (clk_podf + 1U)); +} + + +/** + Setup audio codec. +*/ +static int32_t Codec_Setup (uint32_t mclk_freq, uint32_t sample_rate, uint32_t bit_depth) { + int32_t status; + wm8960_config_t cfg; + codec_config_t codec_cfg; + LPI2C_Type *i2c_instances[] = LPI2C_BASE_PTRS; + LPI2C_Type *i2c; + + /* Set codec type and config structure */ + codec_cfg.codecDevType = kCODEC_WM8960; + codec_cfg.codecDevConfig = &cfg; + + /* Configure I2C */ + i2c = i2c_instances[WM8960_INSTANCE_I2C]; + + cfg.i2cConfig.codecI2CSourceClock = GetI2CClockFreq(i2c); + cfg.i2cConfig.codecI2CInstance = WM8960_INSTANCE_I2C; + cfg.slaveAddress = WM8960_ADDRESS_I2C; + + /* Configure SAI bus mode */ + cfg.bus = WM8960_BUS_PROTOCOL; + cfg.master_slave = WM8960_MODE_MASTER; + + /* Configure audio data route */ + cfg.route = WM8960_DATA_ROUTE; + cfg.leftInputSource = WM8960_INPUT_LEFT; + cfg.rightInputSource = WM8960_INPUT_RIGHT; + cfg.playSource = WM8960_MIXER_SOURCE; + + /* Configure audio data format */ + cfg.format.mclk_HZ = mclk_freq; + cfg.format.sampleRate = sample_rate; + cfg.format.bitWidth = bit_depth; + + /* Setup codec */ + if (CODEC_Init (&CodecHandle, &codec_cfg) == kStatus_Success) { + status = AUDIO_DRV_OK; + } else { + /* Codec setup failed */ + status = AUDIO_DRV_ERROR; + } + + return (status); +} + +/** + Enqueue data blocks for send transfer and start transferring. + + \param[in] n max number of blocks to enqueue for transfer +*/ +static int32_t TriggerSend (uint32_t n) { + status_t status; + int32_t rval; + sai_transfer_t xfer; + AUDIO_BUF *buf = &AudioCb.tx_buf; + + while (n--) { + xfer.data = &buf->data[buf->block_size * buf->block_idx]; + xfer.dataSize = buf->block_size; + + buf->block_idx = (buf->block_idx + 1U) % buf->block_num; + + if (AudioCb.flags & AUDIO_FLAGS_DMA_TX) { + /* Start DMA transfer */ + status = SAI_TransferSendEDMA(SAI_INSTANCE, &DmaSaiTxHandle, &xfer); + } + else { + /* Start IRQ transfer */ + status = SAI_TransferSendNonBlocking(SAI_INSTANCE, &SaiTxHandle, &xfer); + } + + if (status == kStatus_SAI_QueueFull) { + status = kStatus_Success; + + break; + } + } + + if (status == kStatus_Success) { + rval = AUDIO_DRV_OK; + } + else { + rval = AUDIO_DRV_ERROR; + + AudioCb.status.tx_active = 0U; + } + + return (rval); +} + +/** + Enqueue data blocks for receive transfer and start transferring. + + \param[in] n max number of blocks to receive +*/ +static int32_t TriggerReceive (uint32_t n) { + status_t status; + int32_t rval; + sai_transfer_t xfer; + AUDIO_BUF *buf = &AudioCb.rx_buf; + + while (n--) { + xfer.data = &buf->data[buf->block_size * buf->block_idx]; + xfer.dataSize = buf->block_size; + + buf->block_idx = (buf->block_idx + 1U) % buf->block_num; + + if (AudioCb.flags & AUDIO_FLAGS_DMA_RX) { + /* Start DMA transfer */ + status = SAI_TransferReceiveEDMA(SAI_INSTANCE, &DmaSaiRxHandle, &xfer); + } + else { + /* Start IRQ transfer */ + status = SAI_TransferReceiveNonBlocking(SAI_INSTANCE, &SaiRxHandle, &xfer); + } + + if (status == kStatus_SAI_QueueFull) { + status = kStatus_Success; + + break; + } + } + + if (status == kStatus_Success) { + rval = AUDIO_DRV_OK; + } + else { + rval = AUDIO_DRV_ERROR; + + AudioCb.status.rx_active = 0U; + } + + return (rval); +} diff --git a/Platform_MIMXRT1064-EVK/Driver_Audio/Audio_MIMXRT1064-EVK.h b/Platform_MIMXRT1064-EVK/Driver_Audio/Audio_MIMXRT1064-EVK.h new file mode 100644 index 0000000..5ae4dfa --- /dev/null +++ b/Platform_MIMXRT1064-EVK/Driver_Audio/Audio_MIMXRT1064-EVK.h @@ -0,0 +1,60 @@ +/*--------------------------------------------------------------------------- + * Copyright (c) 2021 Arm Limited (or its affiliates). + * All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *---------------------------------------------------------------------------*/ + +#include "audio_drv.h" + +#include "fsl_sai_edma.h" + +#include "fsl_wm8960.h" +#include "fsl_codec_common.h" +#include "fsl_codec_adapter.h" + +#include "Config_Audio.h" +#include "Config_WM8960.h" + +/* Definitions */ +#define AUDIO_FLAGS_INIT (1U << 0) +#define AUDIO_FLAGS_DMA_TX (1U << 2) +#define AUDIO_FLAGS_DMA_RX (1U << 3) + +typedef struct audio_buf_s { + void *data; + uint32_t block_num; + uint32_t block_size; + uint32_t block_idx; +} AUDIO_BUF; + +typedef struct audio_cb_s { + AudioDrv_Event_t callback; /* Audio criver callback */ + AudioDrv_Status_t status; /* Audio driver status */ + AUDIO_BUF tx_buf; /* Transmit buffer info */ + AUDIO_BUF rx_buf; /* Receive buffer info */ + uint32_t rx_cnt; /* Receiver block count */ + uint32_t tx_cnt; /* Transmitter block count */ + uint8_t flags; /* Audio driver flags */ +} AUDIO_CB; + +static void IRQ_Receive_Cb (I2S_Type *base, sai_handle_t *handle, status_t status, void *userData); +static void IRQ_Transmit_Cb (I2S_Type *base, sai_handle_t *handle, status_t status, void *userData); +static void DMA_Receive_Cb (I2S_Type *base, sai_edma_handle_t *handle, status_t status, void *userData); +static void DMA_Transmit_Cb (I2S_Type *base, sai_edma_handle_t *handle, status_t status, void *userData); + +static uint32_t GetSaiClockFreq (I2S_Type *sai_instance); +static int32_t Codec_Setup (uint32_t mclk_freq, uint32_t sample_rate, uint32_t bit_depth); +static int32_t TriggerReceive (uint32_t n); +static int32_t TriggerSend (uint32_t n); diff --git a/Platform_MIMXRT1064-EVK/Driver_Audio/Config_Audio.h b/Platform_MIMXRT1064-EVK/Driver_Audio/Config_Audio.h new file mode 100644 index 0000000..25f1654 --- /dev/null +++ b/Platform_MIMXRT1064-EVK/Driver_Audio/Config_Audio.h @@ -0,0 +1,22 @@ + +#include "audio_drv.h" + +#include "fsl_sai_edma.h" +#include "fsl_dmamux.h" + +/* Config: SAI */ +#define SAI_INSTANCE SAI1 +#define SAI_DATA_ORDER kSAI_DataMSB /* LSB or MSB transmitted first */ +#define SAI_SYNC_MODE_TX kSAI_ModeAsync /* Synchronous or Asynchronous */ +#define SAI_SYNC_MODE_RX kSAI_ModeSync /* Synchronous or Asynchronous */ +#define SAI_MODE_MASTERSLAVE kSAI_Master /* Master or Slave (BCLK, frame sync) */ +#define SAI_MODE_MONO kSAI_Stereo /* Left or Right Channel */ + +/* Config: DMA for SAI */ +#define SAI_DMA_ENABLE_TX 1U +#define SAI_DMA_CHANNEL_TX 0U +#define SAI_DMA_SOURCE_TX kDmaRequestMuxSai1Tx + +#define SAI_DMA_ENABLE_RX 1U +#define SAI_DMA_CHANNEL_RX 1U +#define SAI_DMA_SOURCE_RX kDmaRequestMuxSai1Rx diff --git a/Platform_MIMXRT1064-EVK/Driver_Audio/Config_WM8960.h b/Platform_MIMXRT1064-EVK/Driver_Audio/Config_WM8960.h new file mode 100644 index 0000000..bc8ebab --- /dev/null +++ b/Platform_MIMXRT1064-EVK/Driver_Audio/Config_WM8960.h @@ -0,0 +1,24 @@ + +// Define I2C instance used to control audio codec device +#define WM8960_INSTANCE_I2C 1U + +// Define I2C address used to address audio codec device +#define WM8960_ADDRESS_I2C WM8960_I2C_ADDR + +// Define codec device operation mode +#define WM8960_MODE_MASTER false + +// Define audio data transfer protocol +#define WM8960_BUS_PROTOCOL kWM8960_BusI2S + +// Define audio data route +#define WM8960_DATA_ROUTE kWM8960_RoutePlaybackandRecord + +// Define left input source +#define WM8960_INPUT_LEFT kWM8960_InputDifferentialMicInput3 + +// Define right input source +#define WM8960_INPUT_RIGHT kWM8960_InputDifferentialMicInput2 + +// Define input source for left and right mixer (i.e. output source to speaker) +#define WM8960_MIXER_SOURCE kWM8960_PlaySourceDAC diff --git a/Platform_MIMXRT1064-EVK/MIMXRT1064-EVK.mex b/Platform_MIMXRT1064-EVK/MIMXRT1064-EVK.mex new file mode 100644 index 0000000..18b2f2a --- /dev/null +++ b/Platform_MIMXRT1064-EVK/MIMXRT1064-EVK.mex @@ -0,0 +1,1147 @@ + + + + MIMXRT1064xxxxA + MIMXRT1064DVL6A + MIMXRT1064-EVK + ksdk2_0 + + + + Configuration imported from D:\Test\CB_Lab4Layer\project\Paho_MQTT_Demo\MIMXRT1064-EVK + + + true + false + false + + + + + + + + + 9.0.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Configures pin routing and optionally pin electrical features. + + true + core0 + true + + + + + true + + + + + + + Configures pin routing and optionally pin electrical features. + + true + core0 + true + + + + + true + + + + + true + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Configures pin routing and optionally pin electrical features. + + false + core0 + true + + + + + true + + + + + true + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Configures pin routing and optionally pin electrical features. + + false + core0 + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Configures pin routing and optionally pin electrical features. + + false + core0 + true + + + + + true + + + + + true + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Configures pin routing and optionally pin electrical features. + + false + core0 + true + + + + + true + + + + + true + + + + + true + + + + + + + + + + Configures pin routing and optionally pin electrical features. + + true + core0 + true + + + + + true + + + + + true + + + + + true + + + + + + + + + + + + + + + + + + Configures pin routing and optionally pin electrical features. + + true + core0 + true + + + + + true + + + + + true + + + + + true + + + + + + + + + + + + + + Configures pin routing and optionally pin electrical features. + + false + core0 + true + + + + + true + + + + + true + + + + + true + + + + + + + + + + + + + + + + + + + + Configures pin routing and optionally pin electrical features. + + true + core0 + true + + + + + true + + + + + true + + + + + true + + + + + + + + + + Configures pin routing and optionally pin electrical features. + + true + core0 + true + + + + + true + + + + + true + + + + + true + + + + + + + + + + + + + + + Configures pin routing and optionally pin electrical features. + + true + core0 + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + + + + + + + + + + Configures pin routing and optionally pin electrical features. + + true + core0 + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 9.0.1 + + + + + + + + + true + + + + + INPUT + + + + + true + + + + + OUTPUT + + + + + true + + + + + INPUT + + + + + true + + + + + OUTPUT + + + + + true + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + N/A + + + + + + + 9.0.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + N/A + + + + + + \ No newline at end of file diff --git a/Platform_MIMXRT1064-EVK/README.md b/Platform_MIMXRT1064-EVK/README.md new file mode 100644 index 0000000..6607280 --- /dev/null +++ b/Platform_MIMXRT1064-EVK/README.md @@ -0,0 +1,105 @@ +Micro Speech Example +==================== + +This example shows how to run a voice recognition model that can recognize 2 keywords, "yes" and "no", +from boards built-in microphone. Recognized keywords are written to the terminal. + +RTOS: Keil RTX5 Real-Time Operating System +------------------------------------------ + +The real-time operating system [Keil RTX5](https://arm-software.github.io/CMSIS_5/RTOS2/html/rtx5_impl.html) implements the resource management. + +It is configured with the following settings: + +- [Global Dynamic Memory size](https://arm-software.github.io/CMSIS_5/RTOS2/html/config_rtx5.html#systemConfig): 24000 bytes +- [Default Thread Stack size](https://arm-software.github.io/CMSIS_5/RTOS2/html/config_rtx5.html#threadConfig): 3072 bytes +- [Event Recorder Configuration](https://arm-software.github.io/CMSIS_5/RTOS2/html/config_rtx5.html#evtrecConfig) + - [Global Initialization](https://arm-software.github.io/CMSIS_5/RTOS2/html/config_rtx5.html#evtrecConfigGlobIni): 1 + - Start Recording: 1 + +Refer to [Configure RTX v5](https://arm-software.github.io/CMSIS_5/RTOS2/html/config_rtx5.html) for a detailed description of all configuration options. + +Board: NXP MIMXRT1064-EVK +------------------------- + +The tables below list the device configuration for this board. The board layer for the NXP MIMXRT1064-EVK is using the software component `::Board Support: SDK Project Template: project_template (Variant: evkmimxrt1064)` from `NXP.EVK-MIMXRT1064_BSP.12.3.0` pack. + +The heap/stack setup and the CMSIS-Driver assignment is in configuration files of related software components. + +The example project can be re-configured to work on custom hardware. Refer to ["Configuring Example Projects with MCUXpresso Config Tools"](https://github.com/MDK-Packs/Documentation/tree/master/Using_MCUXpresso) for information. + +### System Configuration + +| System Component | Setting +|:------------------------|:---------------------------------------- +| Device | MIMXRT1064DVL6A +| Board | MIMXRT1064-EVK +| SDK Version | ksdk2_0 +| Heap | 64 kB (configured in linker script MIMXRT1064xxxxx_*.scf file) +| Stack (MSP) | 1 kB (configured in linker script MIMXRT1064xxxxx_*.scf file) + +### Clock Configuration + +| Clock | Setting +|:------------------------|:---------------------------------------- +| AHB_CLK_ROOT | 600 MHz +| IPG_CLK_ROOT | 150 MHz +| PERCLK_CLK_ROOT | 75 MHz +| USDHC1_CLK_ROOT | 198 MHz +| UART_CLK_ROOT | 80 MHz +| ENET_125M_CLK | 50 MHz +| ENET_25M_REF_CLK | 25 MHz +| ENET_TX_CLK | 50 MHz + +**Note:** configured with Functional Group: `BOARD_BootClockRUN` + +### GPIO Configuration and usage + +| Functional Group | Pin | Peripheral | Signal | Identifier | Pin Settings | Usage +|:-----------------------|:----|:-----------|:------------|:------------|:----------------------------------------------------|:----- +| BOARD_InitDEBUG_UART | K14 | LPUART1 | TX | UART1_TXD | default | UART1 TX for debug console (GPIO_AD_B0_12) +| BOARD_InitDEBUG_UART | L14 | LPUART1 | RX | UART1_RXD | default | UART1 RX for debug console (GPIO_AD_B0_13) +| BOARD_InitENET | A7 | ENET | MDC | ENET_MDC | default | Ethernet KSZ8081RNB pin MDC (GPIO_EMC_40) +| BOARD_InitENET | C7 | ENET | MDIO | ENET_MDIO | default | Ethernet KSZ8081RNB pin MDIO (GPIO_EMC_41) +| BOARD_InitENET | B13 | ENET | REF_CLK | ENET_TX_CLK | default | Ethernet KSZ8081RNB pin XI (GPIO_B1_10) +| BOARD_InitENET | E12 | ENET | RX_DATA, 0 | ENET_RXD0 | default | Ethernet KSZ8081RNB pin RXD0 (GPIO_B1_04) +| BOARD_InitENET | D12 | ENET | RX_DATA, 1 | ENET_RXD1 | default | Ethernet KSZ8081RNB pin RXD1 (GPIO_B1_05) +| BOARD_InitENET | C12 | ENET | RX_EN | ENET_CRS_DV | default | Ethernet KSZ8081RNB pin CRS_DV (GPIO_B1_06) +| BOARD_InitENET | C13 | ENET | RX_ER | ENET_RXER | default | Ethernet KSZ8081RNB pin RXER (GPIO_B1_11) +| BOARD_InitENET | B12 | ENET | TX_DATA, 0 | ENET_TXD0 | default | Ethernet KSZ8081RNB pin TXD0 (GPIO_B1_07) +| BOARD_InitENET | A12 | ENET | TX_DATA, 1 | ENET_TXD1 | default | Ethernet KSZ8081RNB pin TXD1 (GPIO_B1_08) +| BOARD_InitENET | A13 | ENET | TX_EN | ENET_TXEN | default | Ethernet KSZ8081RNB pin TXEN (GPIO_B1_09) +| BOARD_InitUSDHC | J2 | USDHC1 | DATA, 3 | SD1_D3 | default | SD Card pin D3 (GPIO_SD_B0_05) +| BOARD_InitUSDHC | H2 | USDHC1 | DATA, 2 | SD1_D2 | default | SD Card pin D2 (GPIO_SD_B0_04) +| BOARD_InitUSDHC | K1 | USDHC1 | DATA, 1 | SD1_D1 | default | SD Card pin D1 (GPIO_SD_B0_03) +| BOARD_InitUSDHC | J1 | USDHC1 | DATA, 0 | SD1_D0 | default | SD Card pin D0 (GPIO_SD_B0_02) +| BOARD_InitUSDHC | J4 | USDHC1 | CMD | SD1_CMD | default | SD Card pin CMD (GPIO_SD_B0_00) +| BOARD_InitUSDHC | J3 | USDHC1 | CLK | SD1_CLK | default | SD Card pin CLK (GPIO_SD_B0_01) +| BOARD_InitARDUINO_UART | J12 | LPUART3 | TX | LPUART3_TX | default | Arduino UNO R3 pin D1 (GPIO_AD_B1_06) +| BOARD_InitARDUINO_UART | K10 | LPUART3 | RX | LPUART3_RX | default | Arduino UNO R3 pin D0 (GPIO_AD_B1_07) +| BOARD_InitUSER_LED | F14 | GPIO1 | gpio_io, 09 | USER_LED | Direction Output, GPIO initial state 1, mode PullUp | User LED (GPIO_AD_B0_09) +| BOARD_InitUSER_BUTTON | L6 | GPIO5 | gpio_io, 00 | USER_BUTTON | Direction Input, mode PullUp | User Button SW8 (WAKEUP) + +### NVIC Configuration + +| NVIC Interrupt | Priority +|:--------------------|:-------- +| ENET | 8 +| USDHC1 | 8 +| LPUART3 | 8 + +**STDIO** is routed to debug console through Virtual COM port (DAP-Link, peripheral = LPUART1, baudrate = 115200) + +### CMSIS-Driver mapping + +| CMSIS-Driver | Peripheral +|:-------------|:---------- +| ETH_MAC0 | ENET +| ETH_PHY0 | KSZ8081RNB (external) +| MCI0 | USDHC1 +| USART3 | LPUART3 + +| CMSIS-Driver VIO | Physical board hardware +|:------------------|:----------------------- +| vioBUTTON0 | User Button SW8 (WAKEUP) +| vioLED0 | User LED (GPIO_AD_B0_09) diff --git a/Platform_MIMXRT1064-EVK/RTE/Board_Support/MIMXRT1064DVL6A/board.c b/Platform_MIMXRT1064-EVK/RTE/Board_Support/MIMXRT1064DVL6A/board.c new file mode 100644 index 0000000..f7bd556 --- /dev/null +++ b/Platform_MIMXRT1064-EVK/RTE/Board_Support/MIMXRT1064DVL6A/board.c @@ -0,0 +1,389 @@ +/* + * Copyright 2018-2019 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "fsl_common.h" +#include "fsl_debug_console.h" +#include "board.h" +#if defined(SDK_I2C_BASED_COMPONENT_USED) && SDK_I2C_BASED_COMPONENT_USED +#include "fsl_lpi2c.h" +#endif /* SDK_I2C_BASED_COMPONENT_USED */ +#include "fsl_iomuxc.h" + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Code + ******************************************************************************/ + +/* Get debug console frequency. */ +uint32_t BOARD_DebugConsoleSrcFreq(void) +{ + uint32_t freq; + + /* To make it simple, we assume default PLL and divider settings, and the only variable + from application is use PLL3 source or OSC source */ + if (CLOCK_GetMux(kCLOCK_UartMux) == 0) /* PLL3 div6 80M */ + { + freq = (CLOCK_GetPllFreq(kCLOCK_PllUsb1) / 6U) / (CLOCK_GetDiv(kCLOCK_UartDiv) + 1U); + } + else + { + freq = CLOCK_GetOscFreq() / (CLOCK_GetDiv(kCLOCK_UartDiv) + 1U); + } + + return freq; +} + +/* Initialize debug console. */ +void BOARD_InitDebugConsole(void) +{ + uint32_t uartClkSrcFreq = BOARD_DebugConsoleSrcFreq(); + + DbgConsole_Init(BOARD_DEBUG_UART_INSTANCE, BOARD_DEBUG_UART_BAUDRATE, BOARD_DEBUG_UART_TYPE, uartClkSrcFreq); +} + +#if defined(SDK_I2C_BASED_COMPONENT_USED) && SDK_I2C_BASED_COMPONENT_USED +void BOARD_LPI2C_Init(LPI2C_Type *base, uint32_t clkSrc_Hz) +{ + lpi2c_master_config_t lpi2cConfig = {0}; + + /* + * lpi2cConfig.debugEnable = false; + * lpi2cConfig.ignoreAck = false; + * lpi2cConfig.pinConfig = kLPI2C_2PinOpenDrain; + * lpi2cConfig.baudRate_Hz = 100000U; + * lpi2cConfig.busIdleTimeout_ns = 0; + * lpi2cConfig.pinLowTimeout_ns = 0; + * lpi2cConfig.sdaGlitchFilterWidth_ns = 0; + * lpi2cConfig.sclGlitchFilterWidth_ns = 0; + */ + LPI2C_MasterGetDefaultConfig(&lpi2cConfig); + LPI2C_MasterInit(base, &lpi2cConfig, clkSrc_Hz); +} + +status_t BOARD_LPI2C_Send(LPI2C_Type *base, + uint8_t deviceAddress, + uint32_t subAddress, + uint8_t subAddressSize, + uint8_t *txBuff, + uint8_t txBuffSize) +{ + lpi2c_master_transfer_t xfer; + + xfer.flags = kLPI2C_TransferDefaultFlag; + xfer.slaveAddress = deviceAddress; + xfer.direction = kLPI2C_Write; + xfer.subaddress = subAddress; + xfer.subaddressSize = subAddressSize; + xfer.data = txBuff; + xfer.dataSize = txBuffSize; + + return LPI2C_MasterTransferBlocking(base, &xfer); +} + +status_t BOARD_LPI2C_Receive(LPI2C_Type *base, + uint8_t deviceAddress, + uint32_t subAddress, + uint8_t subAddressSize, + uint8_t *rxBuff, + uint8_t rxBuffSize) +{ + lpi2c_master_transfer_t xfer; + + xfer.flags = kLPI2C_TransferDefaultFlag; + xfer.slaveAddress = deviceAddress; + xfer.direction = kLPI2C_Read; + xfer.subaddress = subAddress; + xfer.subaddressSize = subAddressSize; + xfer.data = rxBuff; + xfer.dataSize = rxBuffSize; + + return LPI2C_MasterTransferBlocking(base, &xfer); +} + +status_t BOARD_LPI2C_SendSCCB(LPI2C_Type *base, + uint8_t deviceAddress, + uint32_t subAddress, + uint8_t subAddressSize, + uint8_t *txBuff, + uint8_t txBuffSize) +{ + lpi2c_master_transfer_t xfer; + + xfer.flags = kLPI2C_TransferDefaultFlag; + xfer.slaveAddress = deviceAddress; + xfer.direction = kLPI2C_Write; + xfer.subaddress = subAddress; + xfer.subaddressSize = subAddressSize; + xfer.data = txBuff; + xfer.dataSize = txBuffSize; + + return LPI2C_MasterTransferBlocking(base, &xfer); +} + +status_t BOARD_LPI2C_ReceiveSCCB(LPI2C_Type *base, + uint8_t deviceAddress, + uint32_t subAddress, + uint8_t subAddressSize, + uint8_t *rxBuff, + uint8_t rxBuffSize) +{ + status_t status; + lpi2c_master_transfer_t xfer; + + xfer.flags = kLPI2C_TransferDefaultFlag; + xfer.slaveAddress = deviceAddress; + xfer.direction = kLPI2C_Write; + xfer.subaddress = subAddress; + xfer.subaddressSize = subAddressSize; + xfer.data = NULL; + xfer.dataSize = 0; + + status = LPI2C_MasterTransferBlocking(base, &xfer); + + if (kStatus_Success == status) + { + xfer.subaddressSize = 0; + xfer.direction = kLPI2C_Read; + xfer.data = rxBuff; + xfer.dataSize = rxBuffSize; + + status = LPI2C_MasterTransferBlocking(base, &xfer); + } + + return status; +} + +void BOARD_Accel_I2C_Init(void) +{ + BOARD_LPI2C_Init(BOARD_ACCEL_I2C_BASEADDR, BOARD_ACCEL_I2C_CLOCK_FREQ); +} + +status_t BOARD_Accel_I2C_Send(uint8_t deviceAddress, uint32_t subAddress, uint8_t subaddressSize, uint32_t txBuff) +{ + uint8_t data = (uint8_t)txBuff; + + return BOARD_LPI2C_Send(BOARD_ACCEL_I2C_BASEADDR, deviceAddress, subAddress, subaddressSize, &data, 1); +} + +status_t BOARD_Accel_I2C_Receive( + uint8_t deviceAddress, uint32_t subAddress, uint8_t subaddressSize, uint8_t *rxBuff, uint8_t rxBuffSize) +{ + return BOARD_LPI2C_Receive(BOARD_ACCEL_I2C_BASEADDR, deviceAddress, subAddress, subaddressSize, rxBuff, rxBuffSize); +} + +void BOARD_Codec_I2C_Init(void) +{ + BOARD_LPI2C_Init(BOARD_CODEC_I2C_BASEADDR, BOARD_CODEC_I2C_CLOCK_FREQ); +} + +status_t BOARD_Codec_I2C_Send( + uint8_t deviceAddress, uint32_t subAddress, uint8_t subAddressSize, const uint8_t *txBuff, uint8_t txBuffSize) +{ + return BOARD_LPI2C_Send(BOARD_CODEC_I2C_BASEADDR, deviceAddress, subAddress, subAddressSize, (uint8_t *)txBuff, + txBuffSize); +} + +status_t BOARD_Codec_I2C_Receive( + uint8_t deviceAddress, uint32_t subAddress, uint8_t subAddressSize, uint8_t *rxBuff, uint8_t rxBuffSize) +{ + return BOARD_LPI2C_Receive(BOARD_CODEC_I2C_BASEADDR, deviceAddress, subAddress, subAddressSize, rxBuff, rxBuffSize); +} + +void BOARD_Camera_I2C_Init(void) +{ + CLOCK_SetMux(kCLOCK_Lpi2cMux, BOARD_CAMERA_I2C_CLOCK_SOURCE_SELECT); + CLOCK_SetDiv(kCLOCK_Lpi2cDiv, BOARD_CAMERA_I2C_CLOCK_SOURCE_DIVIDER); + BOARD_LPI2C_Init(BOARD_CAMERA_I2C_BASEADDR, BOARD_CAMERA_I2C_CLOCK_FREQ); +} + +status_t BOARD_Camera_I2C_Send( + uint8_t deviceAddress, uint32_t subAddress, uint8_t subAddressSize, const uint8_t *txBuff, uint8_t txBuffSize) +{ + return BOARD_LPI2C_Send(BOARD_CAMERA_I2C_BASEADDR, deviceAddress, subAddress, subAddressSize, (uint8_t *)txBuff, + txBuffSize); +} + +status_t BOARD_Camera_I2C_Receive( + uint8_t deviceAddress, uint32_t subAddress, uint8_t subAddressSize, uint8_t *rxBuff, uint8_t rxBuffSize) +{ + return BOARD_LPI2C_Receive(BOARD_CAMERA_I2C_BASEADDR, deviceAddress, subAddress, subAddressSize, rxBuff, + rxBuffSize); +} + +status_t BOARD_Camera_I2C_SendSCCB( + uint8_t deviceAddress, uint32_t subAddress, uint8_t subAddressSize, const uint8_t *txBuff, uint8_t txBuffSize) +{ + return BOARD_LPI2C_SendSCCB(BOARD_CAMERA_I2C_BASEADDR, deviceAddress, subAddress, subAddressSize, (uint8_t *)txBuff, + txBuffSize); +} + +status_t BOARD_Camera_I2C_ReceiveSCCB( + uint8_t deviceAddress, uint32_t subAddress, uint8_t subAddressSize, uint8_t *rxBuff, uint8_t rxBuffSize) +{ + return BOARD_LPI2C_ReceiveSCCB(BOARD_CAMERA_I2C_BASEADDR, deviceAddress, subAddress, subAddressSize, rxBuff, + rxBuffSize); +} +#endif /* SDK_I2C_BASED_COMPONENT_USED */ + +/* MPU configuration. */ +void BOARD_ConfigMPU(void) +{ +#if defined(__CC_ARM) || defined(__ARMCC_VERSION) + extern uint32_t Image$$RW_m_ncache$$Base[]; + /* RW_m_ncache_unused is a auxiliary region which is used to get the whole size of noncache section */ + extern uint32_t Image$$RW_m_ncache_unused$$Base[]; + extern uint32_t Image$$RW_m_ncache_unused$$ZI$$Limit[]; + uint32_t nonCacheStart = (uint32_t)Image$$RW_m_ncache$$Base; + uint32_t size = ((uint32_t)Image$$RW_m_ncache_unused$$Base == nonCacheStart) ? + 0 : + ((uint32_t)Image$$RW_m_ncache_unused$$ZI$$Limit - nonCacheStart); +#elif defined(__MCUXPRESSO) + extern uint32_t __base_NCACHE_REGION; + extern uint32_t __top_NCACHE_REGION; + uint32_t nonCacheStart = (uint32_t)(&__base_NCACHE_REGION); + uint32_t size = (uint32_t)(&__top_NCACHE_REGION) - nonCacheStart; +#elif defined(__ICCARM__) || defined(__GNUC__) + extern uint32_t __NCACHE_REGION_START[]; + extern uint32_t __NCACHE_REGION_SIZE[]; + uint32_t nonCacheStart = (uint32_t)__NCACHE_REGION_START; + uint32_t size = (uint32_t)__NCACHE_REGION_SIZE; +#endif + volatile uint32_t i = 0; + + /* Disable I cache and D cache */ + if (SCB_CCR_IC_Msk == (SCB_CCR_IC_Msk & SCB->CCR)) + { + SCB_DisableICache(); + } + if (SCB_CCR_DC_Msk == (SCB_CCR_DC_Msk & SCB->CCR)) + { + SCB_DisableDCache(); + } + + /* Disable MPU */ + ARM_MPU_Disable(); + + /* MPU configure: + * Use ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable, + * SubRegionDisable, Size) + * API in mpu_armv7.h. + * param DisableExec Instruction access (XN) disable bit,0=instruction fetches enabled, 1=instruction fetches + * disabled. + * param AccessPermission Data access permissions, allows you to configure read/write access for User and + * Privileged mode. + * Use MACROS defined in mpu_armv7.h: + * ARM_MPU_AP_NONE/ARM_MPU_AP_PRIV/ARM_MPU_AP_URO/ARM_MPU_AP_FULL/ARM_MPU_AP_PRO/ARM_MPU_AP_RO + * Combine TypeExtField/IsShareable/IsCacheable/IsBufferable to configure MPU memory access attributes. + * TypeExtField IsShareable IsCacheable IsBufferable Memory Attribtue Shareability Cache + * 0 x 0 0 Strongly Ordered shareable + * 0 x 0 1 Device shareable + * 0 0 1 0 Normal not shareable Outer and inner write + * through no write allocate + * 0 0 1 1 Normal not shareable Outer and inner write + * back no write allocate + * 0 1 1 0 Normal shareable Outer and inner write + * through no write allocate + * 0 1 1 1 Normal shareable Outer and inner write + * back no write allocate + * 1 0 0 0 Normal not shareable outer and inner + * noncache + * 1 1 0 0 Normal shareable outer and inner + * noncache + * 1 0 1 1 Normal not shareable outer and inner write + * back write/read acllocate + * 1 1 1 1 Normal shareable outer and inner write + * back write/read acllocate + * 2 x 0 0 Device not shareable + * Above are normal use settings, if your want to see more details or want to config different inner/outter cache + * policy. + * please refer to Table 4-55 /4-56 in arm cortex-M7 generic user guide + * param SubRegionDisable Sub-region disable field. 0=sub-region is enabled, 1=sub-region is disabled. + * param Size Region size of the region to be configured. use ARM_MPU_REGION_SIZE_xxx MACRO in + * mpu_armv7.h. + */ + /* + * Add default region to deny access to whole address space to workaround speculative prefetch. + * Refer to Arm errata 1013783-B for more details. + * + */ + /* Region 0 setting: Instruction access disabled, No data access permission. */ + MPU->RBAR = ARM_MPU_RBAR(0, 0x00000000U); + MPU->RASR = ARM_MPU_RASR(1, ARM_MPU_AP_NONE, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_4GB); + + /* Region 1 setting: Memory with Device type, not shareable, non-cacheable. */ + MPU->RBAR = ARM_MPU_RBAR(1, 0x80000000U); + MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_512MB); + + /* Region 2 setting: Memory with Device type, not shareable, non-cacheable. */ + MPU->RBAR = ARM_MPU_RBAR(2, 0x60000000U); + MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_512MB); + +#if defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1) + /* Region 3 setting: Memory with Normal type, not shareable, outer/inner write back. */ + MPU->RBAR = ARM_MPU_RBAR(3, 0x70000000U); + MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_RO, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_4MB); +#endif + + /* Region 4 setting: Memory with Device type, not shareable, non-cacheable. */ + MPU->RBAR = ARM_MPU_RBAR(4, 0x00000000U); + MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_1GB); + + /* Region 5 setting: Memory with Normal type, not shareable, outer/inner write back */ + MPU->RBAR = ARM_MPU_RBAR(5, 0x00000000U); + MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_128KB); + + /* Region 6 setting: Memory with Normal type, not shareable, outer/inner write back */ + MPU->RBAR = ARM_MPU_RBAR(6, 0x20000000U); + MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_128KB); + + /* Region 7 setting: Memory with Normal type, not shareable, outer/inner write back */ + MPU->RBAR = ARM_MPU_RBAR(7, 0x20200000U); + MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_512KB); + + /* Region 8 setting: Memory with Normal type, not shareable, outer/inner write back */ + MPU->RBAR = ARM_MPU_RBAR(8, 0x20280000U); + MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_256KB); + + /* Region 9 setting: Memory with Normal type, not shareable, outer/inner write back */ + MPU->RBAR = ARM_MPU_RBAR(9, 0x80000000U); + MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_32MB); + + while ((size >> i) > 0x1U) + { + i++; + } + + if (i != 0) + { + /* The MPU region size should be 2^N, 5<=N<=32, region base should be multiples of size. */ + assert(!(nonCacheStart % size)); + assert(size == (uint32_t)(1 << i)); + assert(i >= 5); + + /* Region 10 setting: Memory with Normal type, not shareable, non-cacheable */ + MPU->RBAR = ARM_MPU_RBAR(10, nonCacheStart); + MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 0, 0, 0, 0, i - 1); + } + + /* Region 11 setting: Memory with Device type, not shareable, non-cacheable */ + MPU->RBAR = ARM_MPU_RBAR(11, 0x40000000); + MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_4MB); + + /* Region 12 setting: Memory with Device type, not shareable, non-cacheable */ + MPU->RBAR = ARM_MPU_RBAR(12, 0x42000000); + MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_1MB); + + /* Enable MPU */ + ARM_MPU_Enable(MPU_CTRL_PRIVDEFENA_Msk); + + /* Enable I cache and D cache */ + SCB_EnableDCache(); + SCB_EnableICache(); +} diff --git a/Platform_MIMXRT1064-EVK/RTE/Board_Support/MIMXRT1064DVL6A/board.h b/Platform_MIMXRT1064-EVK/RTE/Board_Support/MIMXRT1064DVL6A/board.h new file mode 100644 index 0000000..6416750 --- /dev/null +++ b/Platform_MIMXRT1064-EVK/RTE/Board_Support/MIMXRT1064DVL6A/board.h @@ -0,0 +1,218 @@ +/* + * Copyright 2018 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _BOARD_H_ +#define _BOARD_H_ + +#include "clock_config.h" +#include "fsl_common.h" +#include "fsl_gpio.h" +#include "fsl_clock.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/*! @brief The board name */ +#define BOARD_NAME "MIMXRT1064-EVK" + +/* The UART to use for debug messages. */ +#define BOARD_DEBUG_UART_TYPE kSerialPort_Uart +#define BOARD_DEBUG_UART_BASEADDR (uint32_t) LPUART1 +#define BOARD_DEBUG_UART_INSTANCE 1U + +#define BOARD_DEBUG_UART_CLK_FREQ BOARD_DebugConsoleSrcFreq() + +#define BOARD_UART_IRQ LPUART1_IRQn +#define BOARD_UART_IRQ_HANDLER LPUART1_IRQHandler + +#ifndef BOARD_DEBUG_UART_BAUDRATE +#define BOARD_DEBUG_UART_BAUDRATE (115200U) +#endif /* BOARD_DEBUG_UART_BAUDRATE */ + +/*! @brief The USER_LED used for board */ +#define LOGIC_LED_ON (0U) +#define LOGIC_LED_OFF (1U) +#ifndef BOARD_USER_LED_GPIO +#define BOARD_USER_LED_GPIO GPIO1 +#endif +#ifndef BOARD_USER_LED_GPIO_PIN +#define BOARD_USER_LED_GPIO_PIN (9U) +#endif + +#define USER_LED_INIT(output) \ + GPIO_PinWrite(BOARD_USER_LED_GPIO, BOARD_USER_LED_GPIO_PIN, output); \ + BOARD_USER_LED_GPIO->GDIR |= (1U << BOARD_USER_LED_GPIO_PIN) /*!< Enable target USER_LED */ +#define USER_LED_ON() \ + GPIO_PortClear(BOARD_USER_LED_GPIO, 1U << BOARD_USER_LED_GPIO_PIN) /*!< Turn off target USER_LED */ +#define USER_LED_OFF() GPIO_PortSet(BOARD_USER_LED_GPIO, 1U << BOARD_USER_LED_GPIO_PIN) /*!OSC_CONFIG2 |= XTALOSC24M_OSC_CONFIG2_ENABLE_1M_MASK; + /* Use free 1MHz clock output. */ + XTALOSC24M->OSC_CONFIG2 &= ~XTALOSC24M_OSC_CONFIG2_MUX_1M_MASK; + /* Set XTAL 24MHz clock frequency. */ + CLOCK_SetXtalFreq(24000000U); + /* Enable XTAL 24MHz clock source. */ + CLOCK_InitExternalClk(0); + /* Enable internal RC. */ + CLOCK_InitRcOsc24M(); + /* Switch clock source to external OSC. */ + CLOCK_SwitchOsc(kCLOCK_XtalOsc); + /* Set Oscillator ready counter value. */ + CCM->CCR = (CCM->CCR & (~CCM_CCR_OSCNT_MASK)) | CCM_CCR_OSCNT(127); + /* Setting PeriphClk2Mux and PeriphMux to provide stable clock before PLLs are initialed */ + CLOCK_SetMux(kCLOCK_PeriphClk2Mux, 1); /* Set PERIPH_CLK2 MUX to OSC */ + CLOCK_SetMux(kCLOCK_PeriphMux, 1); /* Set PERIPH_CLK MUX to PERIPH_CLK2 */ + /* Setting the VDD_SOC to 1.275V. It is necessary to config AHB to 600Mhz. */ + DCDC->REG3 = (DCDC->REG3 & (~DCDC_REG3_TRG_MASK)) | DCDC_REG3_TRG(0x13); + /* Waiting for DCDC_STS_DC_OK bit is asserted */ + while (DCDC_REG0_STS_DC_OK_MASK != (DCDC_REG0_STS_DC_OK_MASK & DCDC->REG0)) + { + } + /* Set AHB_PODF. */ + CLOCK_SetDiv(kCLOCK_AhbDiv, 0); + /* Disable IPG clock gate. */ + CLOCK_DisableClock(kCLOCK_Adc1); + CLOCK_DisableClock(kCLOCK_Adc2); + CLOCK_DisableClock(kCLOCK_Xbar1); + CLOCK_DisableClock(kCLOCK_Xbar2); + CLOCK_DisableClock(kCLOCK_Xbar3); + /* Set IPG_PODF. */ + CLOCK_SetDiv(kCLOCK_IpgDiv, 3); + /* Set ARM_PODF. */ + CLOCK_SetDiv(kCLOCK_ArmDiv, 1); + /* Set PERIPH_CLK2_PODF. */ + CLOCK_SetDiv(kCLOCK_PeriphClk2Div, 0); + /* Disable PERCLK clock gate. */ + CLOCK_DisableClock(kCLOCK_Gpt1); + CLOCK_DisableClock(kCLOCK_Gpt1S); + CLOCK_DisableClock(kCLOCK_Gpt2); + CLOCK_DisableClock(kCLOCK_Gpt2S); + CLOCK_DisableClock(kCLOCK_Pit); + /* Set PERCLK_PODF. */ + CLOCK_SetDiv(kCLOCK_PerclkDiv, 1); + /* Disable USDHC1 clock gate. */ + CLOCK_DisableClock(kCLOCK_Usdhc1); + /* Set USDHC1_PODF. */ + CLOCK_SetDiv(kCLOCK_Usdhc1Div, 1); + /* Set Usdhc1 clock source. */ + CLOCK_SetMux(kCLOCK_Usdhc1Mux, 0); + /* Disable USDHC2 clock gate. */ + CLOCK_DisableClock(kCLOCK_Usdhc2); + /* Set USDHC2_PODF. */ + CLOCK_SetDiv(kCLOCK_Usdhc2Div, 1); + /* Set Usdhc2 clock source. */ + CLOCK_SetMux(kCLOCK_Usdhc2Mux, 0); + /* In SDK projects, SDRAM (configured by SEMC) will be initialized in either debug script or dcd. + * With this macro SKIP_SYSCLK_INIT, system pll (selected to be SEMC source clock in SDK projects) will be left unchanged. + * Note: If another clock source is selected for SEMC, user may want to avoid changing that clock as well.*/ +#ifndef SKIP_SYSCLK_INIT + /* Disable Semc clock gate. */ + CLOCK_DisableClock(kCLOCK_Semc); + /* Set SEMC_PODF. */ + CLOCK_SetDiv(kCLOCK_SemcDiv, 7); + /* Set Semc alt clock source. */ + CLOCK_SetMux(kCLOCK_SemcAltMux, 0); + /* Set Semc clock source. */ + CLOCK_SetMux(kCLOCK_SemcMux, 0); +#endif + /* Disable Flexspi clock gate. */ + CLOCK_DisableClock(kCLOCK_FlexSpi); + /* Set FLEXSPI_PODF. */ + CLOCK_SetDiv(kCLOCK_FlexspiDiv, 1); + /* Set Flexspi clock source. */ + CLOCK_SetMux(kCLOCK_FlexspiMux, 3); + /* In SDK projects, external flash (configured by FLEXSPI2) will be initialized by dcd. + * With this macro XIP_EXTERNAL_FLASH, usb1 pll (selected to be FLEXSPI2 clock source in SDK projects) will be left unchanged. + * Note: If another clock source is selected for FLEXSPI2, user may want to avoid changing that clock as well.*/ +#if !(defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1)) + /* Disable Flexspi2 clock gate. */ + CLOCK_DisableClock(kCLOCK_FlexSpi2); + /* Set FLEXSPI2_PODF. */ + CLOCK_SetDiv(kCLOCK_Flexspi2Div, 1); + /* Set Flexspi2 clock source. */ + CLOCK_SetMux(kCLOCK_Flexspi2Mux, 1); +#endif + /* Disable CSI clock gate. */ + CLOCK_DisableClock(kCLOCK_Csi); + /* Set CSI_PODF. */ + CLOCK_SetDiv(kCLOCK_CsiDiv, 1); + /* Set Csi clock source. */ + CLOCK_SetMux(kCLOCK_CsiMux, 0); + /* Disable LPSPI clock gate. */ + CLOCK_DisableClock(kCLOCK_Lpspi1); + CLOCK_DisableClock(kCLOCK_Lpspi2); + CLOCK_DisableClock(kCLOCK_Lpspi3); + CLOCK_DisableClock(kCLOCK_Lpspi4); + /* Set LPSPI_PODF. */ + CLOCK_SetDiv(kCLOCK_LpspiDiv, 4); + /* Set Lpspi clock source. */ + CLOCK_SetMux(kCLOCK_LpspiMux, 2); + /* Disable TRACE clock gate. */ + CLOCK_DisableClock(kCLOCK_Trace); + /* Set TRACE_PODF. */ + CLOCK_SetDiv(kCLOCK_TraceDiv, 2); + /* Set Trace clock source. */ + CLOCK_SetMux(kCLOCK_TraceMux, 2); + /* Disable SAI1 clock gate. */ + CLOCK_DisableClock(kCLOCK_Sai1); + /* Set SAI1_CLK_PRED. */ + CLOCK_SetDiv(kCLOCK_Sai1PreDiv, 0); + /* Set SAI1_CLK_PODF. */ + CLOCK_SetDiv(kCLOCK_Sai1Div, 63); + /* Set Sai1 clock source. */ + CLOCK_SetMux(kCLOCK_Sai1Mux, 2); + /* Disable SAI2 clock gate. */ + CLOCK_DisableClock(kCLOCK_Sai2); + /* Set SAI2_CLK_PRED. */ + CLOCK_SetDiv(kCLOCK_Sai2PreDiv, 0); + /* Set SAI2_CLK_PODF. */ + CLOCK_SetDiv(kCLOCK_Sai2Div, 62); + /* Set Sai2 clock source. */ + CLOCK_SetMux(kCLOCK_Sai2Mux, 0); + /* Disable SAI3 clock gate. */ + CLOCK_DisableClock(kCLOCK_Sai3); + /* Set SAI3_CLK_PRED. */ + CLOCK_SetDiv(kCLOCK_Sai3PreDiv, 3); + /* Set SAI3_CLK_PODF. */ + CLOCK_SetDiv(kCLOCK_Sai3Div, 1); + /* Set Sai3 clock source. */ + CLOCK_SetMux(kCLOCK_Sai3Mux, 0); + /* Disable Lpi2c clock gate. */ + CLOCK_DisableClock(kCLOCK_Lpi2c1); + CLOCK_DisableClock(kCLOCK_Lpi2c2); + CLOCK_DisableClock(kCLOCK_Lpi2c3); + /* Set LPI2C_CLK_PODF. */ + CLOCK_SetDiv(kCLOCK_Lpi2cDiv, 0); + /* Set Lpi2c clock source. */ + CLOCK_SetMux(kCLOCK_Lpi2cMux, 0); + /* Disable CAN clock gate. */ + CLOCK_DisableClock(kCLOCK_Can1); + CLOCK_DisableClock(kCLOCK_Can2); + CLOCK_DisableClock(kCLOCK_Can3); + CLOCK_DisableClock(kCLOCK_Can1S); + CLOCK_DisableClock(kCLOCK_Can2S); + CLOCK_DisableClock(kCLOCK_Can3S); + /* Set CAN_CLK_PODF. */ + CLOCK_SetDiv(kCLOCK_CanDiv, 1); + /* Set Can clock source. */ + CLOCK_SetMux(kCLOCK_CanMux, 2); + /* Disable UART clock gate. */ + CLOCK_DisableClock(kCLOCK_Lpuart1); + CLOCK_DisableClock(kCLOCK_Lpuart2); + CLOCK_DisableClock(kCLOCK_Lpuart3); + CLOCK_DisableClock(kCLOCK_Lpuart4); + CLOCK_DisableClock(kCLOCK_Lpuart5); + CLOCK_DisableClock(kCLOCK_Lpuart6); + CLOCK_DisableClock(kCLOCK_Lpuart7); + CLOCK_DisableClock(kCLOCK_Lpuart8); + /* Set UART_CLK_PODF. */ + CLOCK_SetDiv(kCLOCK_UartDiv, 0); + /* Set Uart clock source. */ + CLOCK_SetMux(kCLOCK_UartMux, 0); + /* Disable LCDIF clock gate. */ + CLOCK_DisableClock(kCLOCK_LcdPixel); + /* Set LCDIF_PRED. */ + CLOCK_SetDiv(kCLOCK_LcdifPreDiv, 1); + /* Set LCDIF_CLK_PODF. */ + CLOCK_SetDiv(kCLOCK_LcdifDiv, 3); + /* Set Lcdif pre clock source. */ + CLOCK_SetMux(kCLOCK_LcdifPreMux, 5); + /* Disable SPDIF clock gate. */ + CLOCK_DisableClock(kCLOCK_Spdif); + /* Set SPDIF0_CLK_PRED. */ + CLOCK_SetDiv(kCLOCK_Spdif0PreDiv, 1); + /* Set SPDIF0_CLK_PODF. */ + CLOCK_SetDiv(kCLOCK_Spdif0Div, 7); + /* Set Spdif clock source. */ + CLOCK_SetMux(kCLOCK_SpdifMux, 3); + /* Disable Flexio1 clock gate. */ + CLOCK_DisableClock(kCLOCK_Flexio1); + /* Set FLEXIO1_CLK_PRED. */ + CLOCK_SetDiv(kCLOCK_Flexio1PreDiv, 1); + /* Set FLEXIO1_CLK_PODF. */ + CLOCK_SetDiv(kCLOCK_Flexio1Div, 7); + /* Set Flexio1 clock source. */ + CLOCK_SetMux(kCLOCK_Flexio1Mux, 3); + /* Disable Flexio2 clock gate. */ + CLOCK_DisableClock(kCLOCK_Flexio2); + /* Set FLEXIO2_CLK_PRED. */ + CLOCK_SetDiv(kCLOCK_Flexio2PreDiv, 1); + /* Set FLEXIO2_CLK_PODF. */ + CLOCK_SetDiv(kCLOCK_Flexio2Div, 7); + /* Set Flexio2 clock source. */ + CLOCK_SetMux(kCLOCK_Flexio2Mux, 3); + /* Set Pll3 sw clock source. */ + CLOCK_SetMux(kCLOCK_Pll3SwMux, 0); + /* Init ARM PLL. */ + CLOCK_InitArmPll(&armPllConfig_BOARD_BootClockRUN); + /* In SDK projects, SDRAM (configured by SEMC) will be initialized in either debug script or dcd. + * With this macro SKIP_SYSCLK_INIT, system pll (selected to be SEMC source clock in SDK projects) will be left unchanged. + * Note: If another clock source is selected for SEMC, user may want to avoid changing that clock as well.*/ +#ifndef SKIP_SYSCLK_INIT +#if defined(XIP_BOOT_HEADER_DCD_ENABLE) && (XIP_BOOT_HEADER_DCD_ENABLE == 1) + #warning "SKIP_SYSCLK_INIT should be defined to keep system pll (selected to be SEMC source clock in SDK projects) unchanged." +#endif + /* Init System PLL. */ + CLOCK_InitSysPll(&sysPllConfig_BOARD_BootClockRUN); + /* Init System pfd0. */ + CLOCK_InitSysPfd(kCLOCK_Pfd0, 27); + /* Init System pfd1. */ + CLOCK_InitSysPfd(kCLOCK_Pfd1, 16); + /* Init System pfd2. */ + CLOCK_InitSysPfd(kCLOCK_Pfd2, 24); + /* Init System pfd3. */ + CLOCK_InitSysPfd(kCLOCK_Pfd3, 16); +#endif + /* In SDK projects, external flash (configured by FLEXSPI2) will be initialized by dcd. + * With this macro XIP_EXTERNAL_FLASH, usb1 pll (selected to be FLEXSPI2 clock source in SDK projects) will be left unchanged. + * Note: If another clock source is selected for FLEXSPI2, user may want to avoid changing that clock as well.*/ +#if !(defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1)) + /* Init Usb1 PLL. */ + CLOCK_InitUsb1Pll(&usb1PllConfig_BOARD_BootClockRUN); + /* Init Usb1 pfd0. */ + CLOCK_InitUsb1Pfd(kCLOCK_Pfd0, 33); + /* Init Usb1 pfd1. */ + CLOCK_InitUsb1Pfd(kCLOCK_Pfd1, 16); + /* Init Usb1 pfd2. */ + CLOCK_InitUsb1Pfd(kCLOCK_Pfd2, 17); + /* Init Usb1 pfd3. */ + CLOCK_InitUsb1Pfd(kCLOCK_Pfd3, 19); + /* Disable Usb1 PLL output for USBPHY1. */ + CCM_ANALOG->PLL_USB1 &= ~CCM_ANALOG_PLL_USB1_EN_USB_CLKS_MASK; +#endif + /* Init Audio PLL. */ + uint32_t pllAudio; + /* Disable Audio PLL output before initial Audio PLL. */ + CCM_ANALOG->PLL_AUDIO &= ~CCM_ANALOG_PLL_AUDIO_ENABLE_MASK; + /* Bypass PLL first */ + CCM_ANALOG->PLL_AUDIO = (CCM_ANALOG->PLL_AUDIO & (~CCM_ANALOG_PLL_AUDIO_BYPASS_CLK_SRC_MASK)) | + CCM_ANALOG_PLL_AUDIO_BYPASS_MASK | CCM_ANALOG_PLL_AUDIO_BYPASS_CLK_SRC(0); + CCM_ANALOG->PLL_AUDIO_NUM = CCM_ANALOG_PLL_AUDIO_NUM_A(77); + CCM_ANALOG->PLL_AUDIO_DENOM = CCM_ANALOG_PLL_AUDIO_DENOM_B(100); + pllAudio = (CCM_ANALOG->PLL_AUDIO & (~(CCM_ANALOG_PLL_AUDIO_DIV_SELECT_MASK | CCM_ANALOG_PLL_AUDIO_POWERDOWN_MASK))) | + CCM_ANALOG_PLL_AUDIO_ENABLE_MASK | CCM_ANALOG_PLL_AUDIO_DIV_SELECT(32); + pllAudio |= CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(2); + CCM_ANALOG->MISC2 &= ~CCM_ANALOG_MISC2_AUDIO_DIV_LSB_MASK; + CCM_ANALOG->MISC2 &= ~CCM_ANALOG_MISC2_AUDIO_DIV_MSB_MASK; + CCM_ANALOG->PLL_AUDIO = pllAudio; + while ((CCM_ANALOG->PLL_AUDIO & CCM_ANALOG_PLL_AUDIO_LOCK_MASK) == 0) + { + } + /* Disable bypass for Audio PLL. */ + CLOCK_SetPllBypass(CCM_ANALOG, kCLOCK_PllAudio, 0); + /* DeInit Video PLL. */ + CLOCK_DeinitVideoPll(); + /* Bypass Video PLL. */ + CCM_ANALOG->PLL_VIDEO |= CCM_ANALOG_PLL_VIDEO_BYPASS_MASK; + /* Set divider for Video PLL. */ + CCM_ANALOG->MISC2 = (CCM_ANALOG->MISC2 & (~CCM_ANALOG_MISC2_VIDEO_DIV_MASK)) | CCM_ANALOG_MISC2_VIDEO_DIV(0); + /* Enable Video PLL output. */ + CCM_ANALOG->PLL_VIDEO |= CCM_ANALOG_PLL_VIDEO_ENABLE_MASK; + /* Init Enet PLL. */ + CLOCK_InitEnetPll(&enetPllConfig_BOARD_BootClockRUN); + /* DeInit Usb2 PLL. */ + CLOCK_DeinitUsb2Pll(); + /* Bypass Usb2 PLL. */ + CLOCK_SetPllBypass(CCM_ANALOG, kCLOCK_PllUsb2, 1); + /* Enable Usb2 PLL output. */ + CCM_ANALOG->PLL_USB2 |= CCM_ANALOG_PLL_USB2_ENABLE_MASK; + /* Set preperiph clock source. */ + CLOCK_SetMux(kCLOCK_PrePeriphMux, 3); + /* Set periph clock source. */ + CLOCK_SetMux(kCLOCK_PeriphMux, 0); + /* Set periph clock2 clock source. */ + CLOCK_SetMux(kCLOCK_PeriphClk2Mux, 0); + /* Set per clock source. */ + CLOCK_SetMux(kCLOCK_PerclkMux, 0); + /* Set lvds1 clock source. */ + CCM_ANALOG->MISC1 = (CCM_ANALOG->MISC1 & (~CCM_ANALOG_MISC1_LVDS1_CLK_SEL_MASK)) | CCM_ANALOG_MISC1_LVDS1_CLK_SEL(0); + /* Set clock out1 divider. */ + CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO1_DIV_MASK)) | CCM_CCOSR_CLKO1_DIV(0); + /* Set clock out1 source. */ + CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO1_SEL_MASK)) | CCM_CCOSR_CLKO1_SEL(1); + /* Set clock out2 divider. */ + CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO2_DIV_MASK)) | CCM_CCOSR_CLKO2_DIV(0); + /* Set clock out2 source. */ + CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO2_SEL_MASK)) | CCM_CCOSR_CLKO2_SEL(18); + /* Set clock out1 drives clock out1. */ + CCM->CCOSR &= ~CCM_CCOSR_CLK_OUT_SEL_MASK; + /* Disable clock out1. */ + CCM->CCOSR &= ~CCM_CCOSR_CLKO1_EN_MASK; + /* Disable clock out2. */ + CCM->CCOSR &= ~CCM_CCOSR_CLKO2_EN_MASK; + /* Set SAI1 MCLK1 clock source. */ + IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk1Sel, 0); + /* Set SAI1 MCLK2 clock source. */ + IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk2Sel, 0); + /* Set SAI1 MCLK3 clock source. */ + IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk3Sel, 0); + /* Set SAI2 MCLK3 clock source. */ + IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI2MClk3Sel, 0); + /* Set SAI3 MCLK3 clock source. */ + IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI3MClk3Sel, 0); + /* Set MQS configuration. */ + IOMUXC_MQSConfig(IOMUXC_GPR,kIOMUXC_MqsPwmOverSampleRate32, 0); + /* Set ENET1 Tx clock source. */ + IOMUXC_EnableMode(IOMUXC_GPR, kIOMUXC_GPR_ENET1RefClkMode, false); + /* Set ENET2 Tx clock source. */ +#if defined(FSL_IOMUXC_DRIVER_VERSION) && (FSL_IOMUXC_DRIVER_VERSION != (MAKE_VERSION(2, 0, 0))) + IOMUXC_EnableMode(IOMUXC_GPR, kIOMUXC_GPR_ENET2RefClkMode, false); +#else + IOMUXC_EnableMode(IOMUXC_GPR, IOMUXC_GPR_GPR1_ENET2_CLK_SEL_MASK, false); +#endif + /* Set GPT1 High frequency reference clock source. */ + IOMUXC_GPR->GPR5 &= ~IOMUXC_GPR_GPR5_VREF_1M_CLK_GPT1_MASK; + /* Set GPT2 High frequency reference clock source. */ + IOMUXC_GPR->GPR5 &= ~IOMUXC_GPR_GPR5_VREF_1M_CLK_GPT2_MASK; + /* Set SystemCoreClock variable. */ + SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK; +} + diff --git a/Platform_MIMXRT1064-EVK/RTE/Board_Support/MIMXRT1064DVL6A/clock_config.h b/Platform_MIMXRT1064-EVK/RTE/Board_Support/MIMXRT1064DVL6A/clock_config.h new file mode 100644 index 0000000..24e044a --- /dev/null +++ b/Platform_MIMXRT1064-EVK/RTE/Board_Support/MIMXRT1064DVL6A/clock_config.h @@ -0,0 +1,122 @@ +#ifndef _CLOCK_CONFIG_H_ +#define _CLOCK_CONFIG_H_ + +#include "fsl_common.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define BOARD_XTAL0_CLK_HZ 24000000U /*!< Board xtal0 frequency in Hz */ + +#define BOARD_XTAL32K_CLK_HZ 32768U /*!< Board xtal32k frequency in Hz */ +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes default configuration of clocks. + * + */ +void BOARD_InitBootClocks(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ********************** Configuration BOARD_BootClockRUN *********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockRUN configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKRUN_CORE_CLOCK 600000000U /*!< Core clock frequency: 600000000Hz */ + +/* Clock outputs (values are in Hz): */ +#define BOARD_BOOTCLOCKRUN_AHB_CLK_ROOT 600000000UL +#define BOARD_BOOTCLOCKRUN_CAN_CLK_ROOT 40000000UL +#define BOARD_BOOTCLOCKRUN_CKIL_SYNC_CLK_ROOT 32768UL +#define BOARD_BOOTCLOCKRUN_CLKO1_CLK 0UL +#define BOARD_BOOTCLOCKRUN_CLKO2_CLK 0UL +#define BOARD_BOOTCLOCKRUN_CLK_1M 1000000UL +#define BOARD_BOOTCLOCKRUN_CLK_24M 24000000UL +#define BOARD_BOOTCLOCKRUN_CSI_CLK_ROOT 12000000UL +#define BOARD_BOOTCLOCKRUN_ENET1_TX_CLK 50000000UL +#define BOARD_BOOTCLOCKRUN_ENET2_125M_CLK 50000000UL +#define BOARD_BOOTCLOCKRUN_ENET2_TX_CLK 50000000UL +#define BOARD_BOOTCLOCKRUN_ENET_125M_CLK 50000000UL +#define BOARD_BOOTCLOCKRUN_ENET_25M_REF_CLK 25000000UL +#define BOARD_BOOTCLOCKRUN_FLEXIO1_CLK_ROOT 30000000UL +#define BOARD_BOOTCLOCKRUN_FLEXIO2_CLK_ROOT 30000000UL +#define BOARD_BOOTCLOCKRUN_FLEXSPI2_CLK_ROOT 130909090UL +#define BOARD_BOOTCLOCKRUN_FLEXSPI_CLK_ROOT 130909090UL +#define BOARD_BOOTCLOCKRUN_GPT1_IPG_CLK_HIGHFREQ 75000000UL +#define BOARD_BOOTCLOCKRUN_GPT2_IPG_CLK_HIGHFREQ 75000000UL +#define BOARD_BOOTCLOCKRUN_IPG_CLK_ROOT 150000000UL +#define BOARD_BOOTCLOCKRUN_LCDIF_CLK_ROOT 67500000UL +#define BOARD_BOOTCLOCKRUN_LPI2C_CLK_ROOT 60000000UL +#define BOARD_BOOTCLOCKRUN_LPSPI_CLK_ROOT 105600000UL +#define BOARD_BOOTCLOCKRUN_LVDS1_CLK 1200000000UL +#define BOARD_BOOTCLOCKRUN_MQS_MCLK 63529411UL +#define BOARD_BOOTCLOCKRUN_PERCLK_CLK_ROOT 75000000UL +#define BOARD_BOOTCLOCKRUN_PLL7_MAIN_CLK 24000000UL +#define BOARD_BOOTCLOCKRUN_SAI1_CLK_ROOT 12288750UL +#define BOARD_BOOTCLOCKRUN_SAI1_MCLK1 12288750UL +#define BOARD_BOOTCLOCKRUN_SAI1_MCLK2 12288750UL +#define BOARD_BOOTCLOCKRUN_SAI1_MCLK3 30000000UL +#define BOARD_BOOTCLOCKRUN_SAI2_CLK_ROOT 8067226UL +#define BOARD_BOOTCLOCKRUN_SAI2_MCLK1 8067226UL +#define BOARD_BOOTCLOCKRUN_SAI2_MCLK2 0UL +#define BOARD_BOOTCLOCKRUN_SAI2_MCLK3 30000000UL +#define BOARD_BOOTCLOCKRUN_SAI3_CLK_ROOT 63529411UL +#define BOARD_BOOTCLOCKRUN_SAI3_MCLK1 63529411UL +#define BOARD_BOOTCLOCKRUN_SAI3_MCLK2 0UL +#define BOARD_BOOTCLOCKRUN_SAI3_MCLK3 30000000UL +#define BOARD_BOOTCLOCKRUN_SEMC_CLK_ROOT 75000000UL +#define BOARD_BOOTCLOCKRUN_SPDIF0_CLK_ROOT 30000000UL +#define BOARD_BOOTCLOCKRUN_SPDIF0_EXTCLK_OUT 0UL +#define BOARD_BOOTCLOCKRUN_TRACE_CLK_ROOT 117333333UL +#define BOARD_BOOTCLOCKRUN_UART_CLK_ROOT 80000000UL +#define BOARD_BOOTCLOCKRUN_USBPHY1_CLK 0UL +#define BOARD_BOOTCLOCKRUN_USBPHY2_CLK 0UL +#define BOARD_BOOTCLOCKRUN_USDHC1_CLK_ROOT 198000000UL +#define BOARD_BOOTCLOCKRUN_USDHC2_CLK_ROOT 198000000UL + +/*! @brief Arm PLL set for BOARD_BootClockRUN configuration. + */ +extern const clock_arm_pll_config_t armPllConfig_BOARD_BootClockRUN; +/*! @brief Usb1 PLL set for BOARD_BootClockRUN configuration. + */ +extern const clock_usb_pll_config_t usb1PllConfig_BOARD_BootClockRUN; +/*! @brief Sys PLL for BOARD_BootClockRUN configuration. + */ +extern const clock_sys_pll_config_t sysPllConfig_BOARD_BootClockRUN; +/*! @brief Audio PLL set for BOARD_BootClockRUN configuration. + */ +extern const clock_audio_pll_config_t audioPllConfig_BOARD_BootClockRUN; +/*! @brief Enet PLL set for BOARD_BootClockRUN configuration. + */ +extern const clock_enet_pll_config_t enetPllConfig_BOARD_BootClockRUN; + +/******************************************************************************* + * API for BOARD_BootClockRUN configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockRUN(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +#endif /* _CLOCK_CONFIG_H_ */ + diff --git a/Platform_MIMXRT1064-EVK/RTE/Board_Support/MIMXRT1064DVL6A/dcd.c b/Platform_MIMXRT1064-EVK/RTE/Board_Support/MIMXRT1064DVL6A/dcd.c new file mode 100644 index 0000000..72a17c6 --- /dev/null +++ b/Platform_MIMXRT1064-EVK/RTE/Board_Support/MIMXRT1064DVL6A/dcd.c @@ -0,0 +1,315 @@ +/* + * Copyright 2020 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +#include "dcd.h" + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.xip_board" +#endif + +#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(XIP_BOOT_HEADER_DCD_ENABLE) && (XIP_BOOT_HEADER_DCD_ENABLE == 1) +#if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) +__attribute__((section(".boot_hdr.dcd_data"))) +#elif defined(__ICCARM__) +#pragma location = ".boot_hdr.dcd_data" +#endif + +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: DCDx V2.0 +processor: MIMXRT1064xxxxA +package_id: MIMXRT1064DVL6A +mcu_data: ksdk2_0 +processor_version: 0.0.0 +board: MIMXRT1064-EVK +output_format: c_array + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* COMMENTS BELOW ARE USED AS SETTINGS FOR DCD DATA */ +const uint8_t dcd_data[] = { + /* HEADER */ + /* Tag */ + 0xD2, + /* Image Length */ + 0x04, 0x10, + /* Version */ + 0x41, + + /* COMMANDS */ + + /* group: 'Imported Commands' */ + /* #1.1-113, command header bytes for merged 'Write - value' command */ + 0xCC, 0x03, 0x8C, 0x04, + /* #1.1, command: write_value, address: CCM_CCGR0, value: 0xFFFFFFFF, size: 4 */ + 0x40, 0x0F, 0xC0, 0x68, 0xFF, 0xFF, 0xFF, 0xFF, + /* #1.2, command: write_value, address: CCM_CCGR1, value: 0xFFFFFFFF, size: 4 */ + 0x40, 0x0F, 0xC0, 0x6C, 0xFF, 0xFF, 0xFF, 0xFF, + /* #1.3, command: write_value, address: CCM_CCGR2, value: 0xFFFFFFFF, size: 4 */ + 0x40, 0x0F, 0xC0, 0x70, 0xFF, 0xFF, 0xFF, 0xFF, + /* #1.4, command: write_value, address: CCM_CCGR3, value: 0xFFFFFFFF, size: 4 */ + 0x40, 0x0F, 0xC0, 0x74, 0xFF, 0xFF, 0xFF, 0xFF, + /* #1.5, command: write_value, address: CCM_CCGR4, value: 0xFFFFFFFF, size: 4 */ + 0x40, 0x0F, 0xC0, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, + /* #1.6, command: write_value, address: CCM_CCGR5, value: 0xFFFFFFFF, size: 4 */ + 0x40, 0x0F, 0xC0, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, + /* #1.7, command: write_value, address: CCM_CCGR6, value: 0xFFFFFFFF, size: 4 */ + 0x40, 0x0F, 0xC0, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, + /* #1.8, command: write_value, address: CCM_ANALOG_PLL_SYS, value: 0x2001, size: 4 */ + 0x40, 0x0D, 0x80, 0x30, 0x00, 0x00, 0x20, 0x01, + /* #1.9, command: write_value, address: CCM_ANALOG_PFD_528, value: 0x1D0000, size: 4 */ + 0x40, 0x0D, 0x81, 0x00, 0x00, 0x1D, 0x00, 0x00, + /* #1.10, command: write_value, address: CCM_CBCDR, value: 0x10D40, size: 4 */ + 0x40, 0x0F, 0xC0, 0x14, 0x00, 0x01, 0x0D, 0x40, + /* #1.11, command: write_value, address: IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_00, value: 0x00, size: 4 */ + 0x40, 0x1F, 0x80, 0x14, 0x00, 0x00, 0x00, 0x00, + /* #1.12, command: write_value, address: IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_01, value: 0x00, size: 4 */ + 0x40, 0x1F, 0x80, 0x18, 0x00, 0x00, 0x00, 0x00, + /* #1.13, command: write_value, address: IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_02, value: 0x00, size: 4 */ + 0x40, 0x1F, 0x80, 0x1C, 0x00, 0x00, 0x00, 0x00, + /* #1.14, command: write_value, address: IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_03, value: 0x00, size: 4 */ + 0x40, 0x1F, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, + /* #1.15, command: write_value, address: IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_04, value: 0x00, size: 4 */ + 0x40, 0x1F, 0x80, 0x24, 0x00, 0x00, 0x00, 0x00, + /* #1.16, command: write_value, address: IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_05, value: 0x00, size: 4 */ + 0x40, 0x1F, 0x80, 0x28, 0x00, 0x00, 0x00, 0x00, + /* #1.17, command: write_value, address: IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_06, value: 0x00, size: 4 */ + 0x40, 0x1F, 0x80, 0x2C, 0x00, 0x00, 0x00, 0x00, + /* #1.18, command: write_value, address: IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_07, value: 0x00, size: 4 */ + 0x40, 0x1F, 0x80, 0x30, 0x00, 0x00, 0x00, 0x00, + /* #1.19, command: write_value, address: IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_08, value: 0x00, size: 4 */ + 0x40, 0x1F, 0x80, 0x34, 0x00, 0x00, 0x00, 0x00, + /* #1.20, command: write_value, address: IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_09, value: 0x00, size: 4 */ + 0x40, 0x1F, 0x80, 0x38, 0x00, 0x00, 0x00, 0x00, + /* #1.21, command: write_value, address: IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_10, value: 0x00, size: 4 */ + 0x40, 0x1F, 0x80, 0x3C, 0x00, 0x00, 0x00, 0x00, + /* #1.22, command: write_value, address: IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_11, value: 0x00, size: 4 */ + 0x40, 0x1F, 0x80, 0x40, 0x00, 0x00, 0x00, 0x00, + /* #1.23, command: write_value, address: IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_12, value: 0x00, size: 4 */ + 0x40, 0x1F, 0x80, 0x44, 0x00, 0x00, 0x00, 0x00, + /* #1.24, command: write_value, address: IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_13, value: 0x00, size: 4 */ + 0x40, 0x1F, 0x80, 0x48, 0x00, 0x00, 0x00, 0x00, + /* #1.25, command: write_value, address: IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_14, value: 0x00, size: 4 */ + 0x40, 0x1F, 0x80, 0x4C, 0x00, 0x00, 0x00, 0x00, + /* #1.26, command: write_value, address: IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_15, value: 0x00, size: 4 */ + 0x40, 0x1F, 0x80, 0x50, 0x00, 0x00, 0x00, 0x00, + /* #1.27, command: write_value, address: IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_16, value: 0x00, size: 4 */ + 0x40, 0x1F, 0x80, 0x54, 0x00, 0x00, 0x00, 0x00, + /* #1.28, command: write_value, address: IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_17, value: 0x00, size: 4 */ + 0x40, 0x1F, 0x80, 0x58, 0x00, 0x00, 0x00, 0x00, + /* #1.29, command: write_value, address: IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_18, value: 0x00, size: 4 */ + 0x40, 0x1F, 0x80, 0x5C, 0x00, 0x00, 0x00, 0x00, + /* #1.30, command: write_value, address: IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_19, value: 0x00, size: 4 */ + 0x40, 0x1F, 0x80, 0x60, 0x00, 0x00, 0x00, 0x00, + /* #1.31, command: write_value, address: IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_20, value: 0x00, size: 4 */ + 0x40, 0x1F, 0x80, 0x64, 0x00, 0x00, 0x00, 0x00, + /* #1.32, command: write_value, address: IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_21, value: 0x00, size: 4 */ + 0x40, 0x1F, 0x80, 0x68, 0x00, 0x00, 0x00, 0x00, + /* #1.33, command: write_value, address: IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_22, value: 0x00, size: 4 */ + 0x40, 0x1F, 0x80, 0x6C, 0x00, 0x00, 0x00, 0x00, + /* #1.34, command: write_value, address: IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_23, value: 0x00, size: 4 */ + 0x40, 0x1F, 0x80, 0x70, 0x00, 0x00, 0x00, 0x00, + /* #1.35, command: write_value, address: IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_24, value: 0x00, size: 4 */ + 0x40, 0x1F, 0x80, 0x74, 0x00, 0x00, 0x00, 0x00, + /* #1.36, command: write_value, address: IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_25, value: 0x00, size: 4 */ + 0x40, 0x1F, 0x80, 0x78, 0x00, 0x00, 0x00, 0x00, + /* #1.37, command: write_value, address: IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_26, value: 0x00, size: 4 */ + 0x40, 0x1F, 0x80, 0x7C, 0x00, 0x00, 0x00, 0x00, + /* #1.38, command: write_value, address: IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_27, value: 0x00, size: 4 */ + 0x40, 0x1F, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, + /* #1.39, command: write_value, address: IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_28, value: 0x00, size: 4 */ + 0x40, 0x1F, 0x80, 0x84, 0x00, 0x00, 0x00, 0x00, + /* #1.40, command: write_value, address: IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_29, value: 0x00, size: 4 */ + 0x40, 0x1F, 0x80, 0x88, 0x00, 0x00, 0x00, 0x00, + /* #1.41, command: write_value, address: IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_30, value: 0x00, size: 4 */ + 0x40, 0x1F, 0x80, 0x8C, 0x00, 0x00, 0x00, 0x00, + /* #1.42, command: write_value, address: IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_31, value: 0x00, size: 4 */ + 0x40, 0x1F, 0x80, 0x90, 0x00, 0x00, 0x00, 0x00, + /* #1.43, command: write_value, address: IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_32, value: 0x00, size: 4 */ + 0x40, 0x1F, 0x80, 0x94, 0x00, 0x00, 0x00, 0x00, + /* #1.44, command: write_value, address: IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_33, value: 0x00, size: 4 */ + 0x40, 0x1F, 0x80, 0x98, 0x00, 0x00, 0x00, 0x00, + /* #1.45, command: write_value, address: IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_34, value: 0x00, size: 4 */ + 0x40, 0x1F, 0x80, 0x9C, 0x00, 0x00, 0x00, 0x00, + /* #1.46, command: write_value, address: IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_35, value: 0x00, size: 4 */ + 0x40, 0x1F, 0x80, 0xA0, 0x00, 0x00, 0x00, 0x00, + /* #1.47, command: write_value, address: IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_36, value: 0x00, size: 4 */ + 0x40, 0x1F, 0x80, 0xA4, 0x00, 0x00, 0x00, 0x00, + /* #1.48, command: write_value, address: IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_37, value: 0x00, size: 4 */ + 0x40, 0x1F, 0x80, 0xA8, 0x00, 0x00, 0x00, 0x00, + /* #1.49, command: write_value, address: IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_38, value: 0x00, size: 4 */ + 0x40, 0x1F, 0x80, 0xAC, 0x00, 0x00, 0x00, 0x00, + /* #1.50, command: write_value, address: IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_39, value: 0x10, size: 4 */ + 0x40, 0x1F, 0x80, 0xB0, 0x00, 0x00, 0x00, 0x10, + /* #1.51, command: write_value, address: IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_00, value: 0x110F9, size: 4 */ + 0x40, 0x1F, 0x82, 0x04, 0x00, 0x01, 0x10, 0xF9, + /* #1.52, command: write_value, address: IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_01, value: 0x110F9, size: 4 */ + 0x40, 0x1F, 0x82, 0x08, 0x00, 0x01, 0x10, 0xF9, + /* #1.53, command: write_value, address: IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_02, value: 0x110F9, size: 4 */ + 0x40, 0x1F, 0x82, 0x0C, 0x00, 0x01, 0x10, 0xF9, + /* #1.54, command: write_value, address: IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_03, value: 0x110F9, size: 4 */ + 0x40, 0x1F, 0x82, 0x10, 0x00, 0x01, 0x10, 0xF9, + /* #1.55, command: write_value, address: IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_04, value: 0x110F9, size: 4 */ + 0x40, 0x1F, 0x82, 0x14, 0x00, 0x01, 0x10, 0xF9, + /* #1.56, command: write_value, address: IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_05, value: 0x110F9, size: 4 */ + 0x40, 0x1F, 0x82, 0x18, 0x00, 0x01, 0x10, 0xF9, + /* #1.57, command: write_value, address: IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_06, value: 0x110F9, size: 4 */ + 0x40, 0x1F, 0x82, 0x1C, 0x00, 0x01, 0x10, 0xF9, + /* #1.58, command: write_value, address: IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_07, value: 0x110F9, size: 4 */ + 0x40, 0x1F, 0x82, 0x20, 0x00, 0x01, 0x10, 0xF9, + /* #1.59, command: write_value, address: IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_08, value: 0x110F9, size: 4 */ + 0x40, 0x1F, 0x82, 0x24, 0x00, 0x01, 0x10, 0xF9, + /* #1.60, command: write_value, address: IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_09, value: 0x110F9, size: 4 */ + 0x40, 0x1F, 0x82, 0x28, 0x00, 0x01, 0x10, 0xF9, + /* #1.61, command: write_value, address: IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_10, value: 0x110F9, size: 4 */ + 0x40, 0x1F, 0x82, 0x2C, 0x00, 0x01, 0x10, 0xF9, + /* #1.62, command: write_value, address: IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_11, value: 0x110F9, size: 4 */ + 0x40, 0x1F, 0x82, 0x30, 0x00, 0x01, 0x10, 0xF9, + /* #1.63, command: write_value, address: IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_12, value: 0x110F9, size: 4 */ + 0x40, 0x1F, 0x82, 0x34, 0x00, 0x01, 0x10, 0xF9, + /* #1.64, command: write_value, address: IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_13, value: 0x110F9, size: 4 */ + 0x40, 0x1F, 0x82, 0x38, 0x00, 0x01, 0x10, 0xF9, + /* #1.65, command: write_value, address: IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_14, value: 0x110F9, size: 4 */ + 0x40, 0x1F, 0x82, 0x3C, 0x00, 0x01, 0x10, 0xF9, + /* #1.66, command: write_value, address: IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_15, value: 0x110F9, size: 4 */ + 0x40, 0x1F, 0x82, 0x40, 0x00, 0x01, 0x10, 0xF9, + /* #1.67, command: write_value, address: IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_16, value: 0x110F9, size: 4 */ + 0x40, 0x1F, 0x82, 0x44, 0x00, 0x01, 0x10, 0xF9, + /* #1.68, command: write_value, address: IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_17, value: 0x110F9, size: 4 */ + 0x40, 0x1F, 0x82, 0x48, 0x00, 0x01, 0x10, 0xF9, + /* #1.69, command: write_value, address: IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_18, value: 0x110F9, size: 4 */ + 0x40, 0x1F, 0x82, 0x4C, 0x00, 0x01, 0x10, 0xF9, + /* #1.70, command: write_value, address: IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_19, value: 0x110F9, size: 4 */ + 0x40, 0x1F, 0x82, 0x50, 0x00, 0x01, 0x10, 0xF9, + /* #1.71, command: write_value, address: IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_20, value: 0x110F9, size: 4 */ + 0x40, 0x1F, 0x82, 0x54, 0x00, 0x01, 0x10, 0xF9, + /* #1.72, command: write_value, address: IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_21, value: 0x110F9, size: 4 */ + 0x40, 0x1F, 0x82, 0x58, 0x00, 0x01, 0x10, 0xF9, + /* #1.73, command: write_value, address: IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_22, value: 0x110F9, size: 4 */ + 0x40, 0x1F, 0x82, 0x5C, 0x00, 0x01, 0x10, 0xF9, + /* #1.74, command: write_value, address: IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_23, value: 0x110F9, size: 4 */ + 0x40, 0x1F, 0x82, 0x60, 0x00, 0x01, 0x10, 0xF9, + /* #1.75, command: write_value, address: IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_24, value: 0x110F9, size: 4 */ + 0x40, 0x1F, 0x82, 0x64, 0x00, 0x01, 0x10, 0xF9, + /* #1.76, command: write_value, address: IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_25, value: 0x110F9, size: 4 */ + 0x40, 0x1F, 0x82, 0x68, 0x00, 0x01, 0x10, 0xF9, + /* #1.77, command: write_value, address: IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_26, value: 0x110F9, size: 4 */ + 0x40, 0x1F, 0x82, 0x6C, 0x00, 0x01, 0x10, 0xF9, + /* #1.78, command: write_value, address: IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_27, value: 0x110F9, size: 4 */ + 0x40, 0x1F, 0x82, 0x70, 0x00, 0x01, 0x10, 0xF9, + /* #1.79, command: write_value, address: IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_28, value: 0x110F9, size: 4 */ + 0x40, 0x1F, 0x82, 0x74, 0x00, 0x01, 0x10, 0xF9, + /* #1.80, command: write_value, address: IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_29, value: 0x110F9, size: 4 */ + 0x40, 0x1F, 0x82, 0x78, 0x00, 0x01, 0x10, 0xF9, + /* #1.81, command: write_value, address: IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_30, value: 0x110F9, size: 4 */ + 0x40, 0x1F, 0x82, 0x7C, 0x00, 0x01, 0x10, 0xF9, + /* #1.82, command: write_value, address: IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_31, value: 0x110F9, size: 4 */ + 0x40, 0x1F, 0x82, 0x80, 0x00, 0x01, 0x10, 0xF9, + /* #1.83, command: write_value, address: IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_32, value: 0x110F9, size: 4 */ + 0x40, 0x1F, 0x82, 0x84, 0x00, 0x01, 0x10, 0xF9, + /* #1.84, command: write_value, address: IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_33, value: 0x110F9, size: 4 */ + 0x40, 0x1F, 0x82, 0x88, 0x00, 0x01, 0x10, 0xF9, + /* #1.85, command: write_value, address: IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_34, value: 0x110F9, size: 4 */ + 0x40, 0x1F, 0x82, 0x8C, 0x00, 0x01, 0x10, 0xF9, + /* #1.86, command: write_value, address: IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_35, value: 0x110F9, size: 4 */ + 0x40, 0x1F, 0x82, 0x90, 0x00, 0x01, 0x10, 0xF9, + /* #1.87, command: write_value, address: IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_36, value: 0x110F9, size: 4 */ + 0x40, 0x1F, 0x82, 0x94, 0x00, 0x01, 0x10, 0xF9, + /* #1.88, command: write_value, address: IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_37, value: 0x110F9, size: 4 */ + 0x40, 0x1F, 0x82, 0x98, 0x00, 0x01, 0x10, 0xF9, + /* #1.89, command: write_value, address: IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_38, value: 0x110F9, size: 4 */ + 0x40, 0x1F, 0x82, 0x9C, 0x00, 0x01, 0x10, 0xF9, + /* #1.90, command: write_value, address: IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_39, value: 0x110F9, size: 4 */ + 0x40, 0x1F, 0x82, 0xA0, 0x00, 0x01, 0x10, 0xF9, + /* #1.91, command: write_value, address: SEMC_MCR, value: 0x10000004, size: 4 */ + 0x40, 0x2F, 0x00, 0x00, 0x10, 0x00, 0x00, 0x04, + /* #1.92, command: write_value, address: SEMC_BMCR0, value: 0x30524, size: 4 */ + 0x40, 0x2F, 0x00, 0x08, 0x00, 0x03, 0x05, 0x24, + /* #1.93, command: write_value, address: SEMC_BMCR1, value: 0x6030524, size: 4 */ + 0x40, 0x2F, 0x00, 0x0C, 0x06, 0x03, 0x05, 0x24, + /* #1.94, command: write_value, address: SEMC_BR0, value: 0x8000001B, size: 4 */ + 0x40, 0x2F, 0x00, 0x10, 0x80, 0x00, 0x00, 0x1B, + /* #1.95, command: write_value, address: SEMC_BR1, value: 0x8200001B, size: 4 */ + 0x40, 0x2F, 0x00, 0x14, 0x82, 0x00, 0x00, 0x1B, + /* #1.96, command: write_value, address: SEMC_BR2, value: 0x8400001B, size: 4 */ + 0x40, 0x2F, 0x00, 0x18, 0x84, 0x00, 0x00, 0x1B, + /* #1.97, command: write_value, address: SEMC_BR3, value: 0x8600001B, size: 4 */ + 0x40, 0x2F, 0x00, 0x1C, 0x86, 0x00, 0x00, 0x1B, + /* #1.98, command: write_value, address: SEMC_BR4, value: 0x90000021, size: 4 */ + 0x40, 0x2F, 0x00, 0x20, 0x90, 0x00, 0x00, 0x21, + /* #1.99, command: write_value, address: SEMC_BR5, value: 0xA0000019, size: 4 */ + 0x40, 0x2F, 0x00, 0x24, 0xA0, 0x00, 0x00, 0x19, + /* #1.100, command: write_value, address: SEMC_BR6, value: 0xA8000017, size: 4 */ + 0x40, 0x2F, 0x00, 0x28, 0xA8, 0x00, 0x00, 0x17, + /* #1.101, command: write_value, address: SEMC_BR7, value: 0xA900001B, size: 4 */ + 0x40, 0x2F, 0x00, 0x2C, 0xA9, 0x00, 0x00, 0x1B, + /* #1.102, command: write_value, address: SEMC_BR8, value: 0x21, size: 4 */ + 0x40, 0x2F, 0x00, 0x30, 0x00, 0x00, 0x00, 0x21, + /* #1.103, command: write_value, address: SEMC_IOCR, value: 0x79A8, size: 4 */ + 0x40, 0x2F, 0x00, 0x04, 0x00, 0x00, 0x79, 0xA8, + /* #1.104, command: write_value, address: SEMC_SDRAMCR0, value: 0xF31, size: 4 */ + 0x40, 0x2F, 0x00, 0x40, 0x00, 0x00, 0x0F, 0x31, + /* #1.105, command: write_value, address: SEMC_SDRAMCR1, value: 0x652922, size: 4 */ + 0x40, 0x2F, 0x00, 0x44, 0x00, 0x65, 0x29, 0x22, + /* #1.106, command: write_value, address: SEMC_SDRAMCR2, value: 0x10920, size: 4 */ + 0x40, 0x2F, 0x00, 0x48, 0x00, 0x01, 0x09, 0x20, + /* #1.107, command: write_value, address: SEMC_SDRAMCR3, value: 0x50210A08, size: 4 */ + 0x40, 0x2F, 0x00, 0x4C, 0x50, 0x21, 0x0A, 0x08, + /* #1.108, command: write_value, address: SEMC_DBICR0, value: 0x21, size: 4 */ + 0x40, 0x2F, 0x00, 0x80, 0x00, 0x00, 0x00, 0x21, + /* #1.109, command: write_value, address: SEMC_DBICR1, value: 0x888888, size: 4 */ + 0x40, 0x2F, 0x00, 0x84, 0x00, 0x88, 0x88, 0x88, + /* #1.110, command: write_value, address: SEMC_IPCR1, value: 0x02, size: 4 */ + 0x40, 0x2F, 0x00, 0x94, 0x00, 0x00, 0x00, 0x02, + /* #1.111, command: write_value, address: SEMC_IPCR2, value: 0x00, size: 4 */ + 0x40, 0x2F, 0x00, 0x98, 0x00, 0x00, 0x00, 0x00, + /* #1.112, command: write_value, address: SEMC_IPCR0, value: 0x80000000, size: 4 */ + 0x40, 0x2F, 0x00, 0x90, 0x80, 0x00, 0x00, 0x00, + /* #1.113, command: write_value, address: SEMC_IPCMD, value: 0xA55A000F, size: 4 */ + 0x40, 0x2F, 0x00, 0x9C, 0xA5, 0x5A, 0x00, 0x0F, + /* #2, command: check_any_bit_set, address: SEMC_INTR, value: 0x01, size: 4 */ + 0xCF, 0x00, 0x0C, 0x1C, 0x40, 0x2F, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x01, + /* #3.1-2, command header bytes for merged 'Write - value' command */ + 0xCC, 0x00, 0x14, 0x04, + /* #3.1, command: write_value, address: SEMC_IPCR0, value: 0x80000000, size: 4 */ + 0x40, 0x2F, 0x00, 0x90, 0x80, 0x00, 0x00, 0x00, + /* #3.2, command: write_value, address: SEMC_IPCMD, value: 0xA55A000C, size: 4 */ + 0x40, 0x2F, 0x00, 0x9C, 0xA5, 0x5A, 0x00, 0x0C, + /* #4, command: check_any_bit_set, address: SEMC_INTR, value: 0x01, size: 4 */ + 0xCF, 0x00, 0x0C, 0x1C, 0x40, 0x2F, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x01, + /* #5.1-2, command header bytes for merged 'Write - value' command */ + 0xCC, 0x00, 0x14, 0x04, + /* #5.1, command: write_value, address: SEMC_IPCR0, value: 0x80000000, size: 4 */ + 0x40, 0x2F, 0x00, 0x90, 0x80, 0x00, 0x00, 0x00, + /* #5.2, command: write_value, address: SEMC_IPCMD, value: 0xA55A000C, size: 4 */ + 0x40, 0x2F, 0x00, 0x9C, 0xA5, 0x5A, 0x00, 0x0C, + /* #6, command: check_any_bit_set, address: SEMC_INTR, value: 0x01, size: 4 */ + 0xCF, 0x00, 0x0C, 0x1C, 0x40, 0x2F, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x01, + /* #7.1-3, command header bytes for merged 'Write - value' command */ + 0xCC, 0x00, 0x1C, 0x04, + /* #7.1, command: write_value, address: SEMC_IPTXDAT, value: 0x33, size: 4 */ + 0x40, 0x2F, 0x00, 0xA0, 0x00, 0x00, 0x00, 0x33, + /* #7.2, command: write_value, address: SEMC_IPCR0, value: 0x80000000, size: 4 */ + 0x40, 0x2F, 0x00, 0x90, 0x80, 0x00, 0x00, 0x00, + /* #7.3, command: write_value, address: SEMC_IPCMD, value: 0xA55A000A, size: 4 */ + 0x40, 0x2F, 0x00, 0x9C, 0xA5, 0x5A, 0x00, 0x0A, + /* #8, command: check_any_bit_set, address: SEMC_INTR, value: 0x01, size: 4 */ + 0xCF, 0x00, 0x0C, 0x1C, 0x40, 0x2F, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x01, + /* #9, command: write_value, address: SEMC_SDRAMCR3, value: 0x50210A09, size: 4 */ + 0xCC, 0x00, 0x0C, 0x04, 0x40, 0x2F, 0x00, 0x4C, 0x50, 0x21, 0x0A, 0x09 + }; +/* BE CAREFUL MODIFYING THIS SETTINGS - IT IS YAML SETTINGS FOR TOOLS */ + +#else +const uint8_t dcd_data[] = {0x00}; +#endif /* XIP_BOOT_HEADER_DCD_ENABLE */ +#endif /* XIP_BOOT_HEADER_ENABLE */ diff --git a/Platform_MIMXRT1064-EVK/RTE/Board_Support/MIMXRT1064DVL6A/dcd.h b/Platform_MIMXRT1064-EVK/RTE/Board_Support/MIMXRT1064DVL6A/dcd.h new file mode 100644 index 0000000..77de9fa --- /dev/null +++ b/Platform_MIMXRT1064-EVK/RTE/Board_Support/MIMXRT1064DVL6A/dcd.h @@ -0,0 +1,32 @@ +/* + * Copyright 2020 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +#ifndef __DCD__ +#define __DCD__ + +#include + +/*! @name Driver version */ +/*@{*/ +/*! @brief XIP_BOARD driver version 2.0.0. */ +#define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*@}*/ + +/************************************* + * DCD Data + *************************************/ +#define DCD_TAG_HEADER (0xD2) +#define DCD_VERSION (0x41) +#define DCD_TAG_HEADER_SHIFT (24) +#define DCD_ARRAY_SIZE 1 + +#endif /* __DCD__ */ diff --git a/Platform_MIMXRT1064-EVK/RTE/Board_Support/MIMXRT1064DVL6A/peripherals.c b/Platform_MIMXRT1064-EVK/RTE/Board_Support/MIMXRT1064DVL6A/peripherals.c new file mode 100644 index 0000000..54c5a92 --- /dev/null +++ b/Platform_MIMXRT1064-EVK/RTE/Board_Support/MIMXRT1064DVL6A/peripherals.c @@ -0,0 +1,24 @@ +/* + * Copyright 2018 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Peripherals v1.0 + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ + +/******************************************************************************* + * Included files + ******************************************************************************/ +#include "peripherals.h" + +/******************************************************************************* + * BOARD_InitBootPeripherals function + ******************************************************************************/ +void BOARD_InitBootPeripherals(void) +{ + BOARD_ConfigMPU(); +} diff --git a/Platform_MIMXRT1064-EVK/RTE/Board_Support/MIMXRT1064DVL6A/peripherals.h b/Platform_MIMXRT1064-EVK/RTE/Board_Support/MIMXRT1064DVL6A/peripherals.h new file mode 100644 index 0000000..2042c0a --- /dev/null +++ b/Platform_MIMXRT1064-EVK/RTE/Board_Support/MIMXRT1064DVL6A/peripherals.h @@ -0,0 +1,28 @@ +/* + * Copyright 2018 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _PERIPHERALS_H_ +#define _PERIPHERALS_H_ + +#if defined(__cplusplus) +extern "C" { +#endif /*_cplusplus. */ + /******************************************************************************* + * BOARD_InitBootPeripherals function + ******************************************************************************/ +void BOARD_InitBootPeripherals(void); + +/******************************************************************************* + * BOARD_InitConfigMPU function + ******************************************************************************/ +void BOARD_ConfigMPU(void); + +#if defined(__cplusplus) +} +#endif /*_cplusplus. */ + +#endif /* _PERIPHERALS_H_ */ diff --git a/Platform_MIMXRT1064-EVK/RTE/Board_Support/MIMXRT1064DVL6A/pin_mux.c b/Platform_MIMXRT1064-EVK/RTE/Board_Support/MIMXRT1064DVL6A/pin_mux.c new file mode 100644 index 0000000..67f586a --- /dev/null +++ b/Platform_MIMXRT1064-EVK/RTE/Board_Support/MIMXRT1064DVL6A/pin_mux.c @@ -0,0 +1,808 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Pins v9.0 +processor: MIMXRT1064xxxxA +package_id: MIMXRT1064DVL6A +mcu_data: ksdk2_0 +processor_version: 9.0.1 +board: MIMXRT1064-EVK +pin_labels: +- {pin_num: E3, pin_signal: GPIO_EMC_00, label: SEMC_D0, identifier: SEMC_D0} +- {pin_num: F3, pin_signal: GPIO_EMC_01, label: SEMC_D1, identifier: SEMC_D1} +- {pin_num: F4, pin_signal: GPIO_EMC_02, label: SEMC_D2, identifier: SEMC_D2} +- {pin_num: F2, pin_signal: GPIO_EMC_04, label: SEMC_D4, identifier: SEMC_D4} +- {pin_num: G4, pin_signal: GPIO_EMC_03, label: SEMC_D3, identifier: SEMC_D3} +- {pin_num: G5, pin_signal: GPIO_EMC_05, label: SEMC_D5, identifier: SEMC_D5} +- {pin_num: H5, pin_signal: GPIO_EMC_06, label: SEMC_D6, identifier: SEMC_D6} +- {pin_num: H4, pin_signal: GPIO_EMC_07, label: SEMC_D7, identifier: SEMC_D7} +- {pin_num: H3, pin_signal: GPIO_EMC_08, label: SEMC_DM0, identifier: SEMC_DM0} +- {pin_num: C2, pin_signal: GPIO_EMC_09, label: SEMC_A0, identifier: SEMC_A0} +- {pin_num: G1, pin_signal: GPIO_EMC_10, label: SEMC_A1, identifier: SEMC_A1} +- {pin_num: G3, pin_signal: GPIO_EMC_11, label: SEMC_A2, identifier: SEMC_A2} +- {pin_num: H1, pin_signal: GPIO_EMC_12, label: SEMC_A3, identifier: SEMC_A3} +- {pin_num: A6, pin_signal: GPIO_EMC_13, label: SEMC_A4, identifier: SEMC_A4} +- {pin_num: B6, pin_signal: GPIO_EMC_14, label: SEMC_A5, identifier: SEMC_A5} +- {pin_num: B1, pin_signal: GPIO_EMC_15, label: SEMC_A6, identifier: SEMC_A6} +- {pin_num: A5, pin_signal: GPIO_EMC_16, label: SEMC_A7, identifier: SEMC_A7} +- {pin_num: A4, pin_signal: GPIO_EMC_17, label: SEMC_A8, identifier: SEMC_A8} +- {pin_num: B2, pin_signal: GPIO_EMC_18, label: SEMC_A9, identifier: SEMC_A9} +- {pin_num: B4, pin_signal: GPIO_EMC_19, label: SEMC_A11, identifier: SEMC_A11} +- {pin_num: G2, pin_signal: GPIO_EMC_23, label: SEMC_A10, identifier: SEMC_A10} +- {pin_num: A3, pin_signal: GPIO_EMC_20, label: SEMC_A12, identifier: SEMC_A12} +- {pin_num: C1, pin_signal: GPIO_EMC_21, label: SEMC_BA0, identifier: SEMC_BA0} +- {pin_num: F1, pin_signal: GPIO_EMC_22, label: SEMC_BA1, identifier: SEMC_BA1} +- {pin_num: D3, pin_signal: GPIO_EMC_24, label: SEMC_CAS, identifier: SEMC_CAS} +- {pin_num: D2, pin_signal: GPIO_EMC_25, label: SEMC_RAS, identifier: SEMC_RAS} +- {pin_num: B3, pin_signal: GPIO_EMC_26, label: SEMC_CLK, identifier: SEMC_CLK} +- {pin_num: A2, pin_signal: GPIO_EMC_27, label: SEMC_CKE, identifier: SEMC_CKE} +- {pin_num: D1, pin_signal: GPIO_EMC_28, label: SEMC_WE, identifier: SEMC_WE} +- {pin_num: E1, pin_signal: GPIO_EMC_29, label: SEMC_CS0, identifier: SEMC_CS0} +- {pin_num: C6, pin_signal: GPIO_EMC_30, label: SEMC_D8, identifier: SEMC_D8} +- {pin_num: C5, pin_signal: GPIO_EMC_31, label: SEMC_D9, identifier: SEMC_D9} +- {pin_num: D5, pin_signal: GPIO_EMC_32, label: SEMC_D10, identifier: SEMC_D10} +- {pin_num: C4, pin_signal: GPIO_EMC_33, label: SEMC_D11, identifier: SEMC_D11} +- {pin_num: D4, pin_signal: GPIO_EMC_34, label: SEMC_D12, identifier: SEMC_D12} +- {pin_num: E5, pin_signal: GPIO_EMC_35, label: SEMC_D13, identifier: SEMC_D13} +- {pin_num: C3, pin_signal: GPIO_EMC_36, label: SEMC_D14, identifier: SEMC_D14} +- {pin_num: E4, pin_signal: GPIO_EMC_37, label: SEMC_D15, identifier: SEMC_D15} +- {pin_num: D6, pin_signal: GPIO_EMC_38, label: SEMC_DM1, identifier: SEMC_DM1} +- {pin_num: B7, pin_signal: GPIO_EMC_39, label: SEMC_DQS, identifier: SEMC_DQS} +- {pin_num: A7, pin_signal: GPIO_EMC_40, label: ENET_MDC, identifier: ENET_MDC} +- {pin_num: C7, pin_signal: GPIO_EMC_41, label: ENET_MDIO, identifier: ENET_MDIO} +- {pin_num: D7, pin_signal: GPIO_B0_00, label: LCDIF_CLK, identifier: LCDIF_CLK} +- {pin_num: E7, pin_signal: GPIO_B0_01, label: LCDIF_ENABLE, identifier: LCDIF_ENABLE} +- {pin_num: E8, pin_signal: GPIO_B0_02, label: LCDIF_HSYNC, identifier: LCDIF_HSYNC} +- {pin_num: D8, pin_signal: GPIO_B0_03, label: LCDIF_VSYNC, identifier: LCDIF_VSYNC} +- {pin_num: C8, pin_signal: GPIO_B0_04, label: 'LCDIF_D0/BT_CFG[0]', identifier: LCDIF_D0} +- {pin_num: B8, pin_signal: GPIO_B0_05, label: 'LCDIF_D1/BT_CFG[1]', identifier: LCDIF_D1} +- {pin_num: A8, pin_signal: GPIO_B0_06, label: 'LCDIF_D2/BT_CFG[2]', identifier: LCDIF_D2} +- {pin_num: A9, pin_signal: GPIO_B0_07, label: 'LCDIF_D3/BT_CFG[3]', identifier: LCDIF_D3} +- {pin_num: B9, pin_signal: GPIO_B0_08, label: 'LCDIF_D4/BT_CFG[4]', identifier: LCDIF_D4} +- {pin_num: C9, pin_signal: GPIO_B0_09, label: 'LCDIF_D5/BT_CFG[5]', identifier: LCDIF_D5} +- {pin_num: D9, pin_signal: GPIO_B0_10, label: 'LCDIF_D6/BT_CFG[6]', identifier: LCDIF_D6} +- {pin_num: A10, pin_signal: GPIO_B0_11, label: 'LCDIF_D7/BT_CFG[7]', identifier: LCDIF_D7} +- {pin_num: C10, pin_signal: GPIO_B0_12, label: 'LCDIF_D8/BT_CFG[8]', identifier: LCDIF_D8} +- {pin_num: D10, pin_signal: GPIO_B0_13, label: 'LCDIF_D9/BT_CFG[9]', identifier: LCDIF_D9} +- {pin_num: E10, pin_signal: GPIO_B0_14, label: 'LCDIF_D10/BT_CFG[10]', identifier: LCDIF_D10} +- {pin_num: E11, pin_signal: GPIO_B0_15, label: 'LCDIF_D11/BT_CFG[11]', identifier: LCDIF_D11} +- {pin_num: A11, pin_signal: GPIO_B1_00, label: LCDIF_D12, identifier: LCDIF_D12} +- {pin_num: B11, pin_signal: GPIO_B1_01, label: LCDIF_D13, identifier: LCDIF_D13} +- {pin_num: C11, pin_signal: GPIO_B1_02, label: LCDIF_D14, identifier: LCDIF_D14} +- {pin_num: D11, pin_signal: GPIO_B1_03, label: LCDIF_D15, identifier: LCDIF_D15} +- {pin_num: E12, pin_signal: GPIO_B1_04, label: ENET_RXD0, identifier: ENET_RXD0} +- {pin_num: D12, pin_signal: GPIO_B1_05, label: ENET_RXD1, identifier: ENET_RXD1} +- {pin_num: C12, pin_signal: GPIO_B1_06, label: ENET_CRS_DV, identifier: ENET_CRS_DV} +- {pin_num: B12, pin_signal: GPIO_B1_07, label: ENET_TXD0, identifier: ENET_TXD0} +- {pin_num: A12, pin_signal: GPIO_B1_08, label: ENET_TXD1, identifier: ENET_TXD1} +- {pin_num: A13, pin_signal: GPIO_B1_09, label: ENET_TXEN, identifier: ENET_TXEN} +- {pin_num: B13, pin_signal: GPIO_B1_10, label: ENET_TX_CLK, identifier: ENET_TX_CLK} +- {pin_num: C13, pin_signal: GPIO_B1_11, label: ENET_RXER, identifier: ENET_RXER} +- {pin_num: D13, pin_signal: GPIO_B1_12, label: SD_CD_SW, identifier: SD_CD_SW} +- {pin_num: D14, pin_signal: GPIO_B1_13, label: WDOG_B, identifier: WDOG_B} +- {pin_num: C14, pin_signal: GPIO_B1_14, label: SD0_VSELECT, identifier: SD0_VSELECT} +- {pin_num: B14, pin_signal: GPIO_B1_15, label: USB_HOST_PWR/BACKLIGHT_CTL, identifier: BACKLIGHT_CTL} +- {pin_num: E9, pin_signal: NVCC_GPIO0, label: DCDC_3V3/NVCC_GPIO_3V3} +- {pin_num: F10, pin_signal: NVCC_GPIO1, label: DCDC_3V3/NVCC_GPIO_3V3} +- {pin_num: J10, pin_signal: NVCC_GPIO2, label: DCDC_3V3/NVCC_GPIO_3V3} +- {pin_num: M14, pin_signal: GPIO_AD_B0_00, label: 'USB_HOST_OC/J24[10]'} +- {pin_num: H10, pin_signal: GPIO_AD_B0_01, label: 'USB_OTG1_ID/J24[9]'} +- {pin_num: M11, pin_signal: GPIO_AD_B0_02, label: 'USB_OTG1_PWR/J24[2]'} +- {pin_num: G11, pin_signal: GPIO_AD_B0_03, label: 'USB_OTG1_OC/J24[1]'} +- {pin_num: F11, pin_signal: GPIO_AD_B0_04, label: 'CSI_PWDN/J35[17]/BOOT_MODE[0]', identifier: CSI_PWDN} +- {pin_num: G14, pin_signal: GPIO_AD_B0_05, label: 'CAN_STBY/BOOT_MODE[1]/Flash_RST/U12[8]', identifier: CAN_STBY} +- {pin_num: E14, pin_signal: GPIO_AD_B0_06, label: 'JTAG_TMS/J21[7]/SWD_DIO'} +- {pin_num: F12, pin_signal: GPIO_AD_B0_07, label: 'JTAG_TCK/J21[9]/SWD_CLK'} +- {pin_num: F13, pin_signal: GPIO_AD_B0_08, label: JTAG_MOD} +- {pin_num: F14, pin_signal: GPIO_AD_B0_09, label: 'JTAG_TDI/J21[5]/ENET_RST/J22[5]', identifier: USER_LED} +- {pin_num: G13, pin_signal: GPIO_AD_B0_10, label: 'JTAG_TDO/J21[13]/INT1_COMBO/ENET_INT/J22[6]/U32[11]', identifier: INT1_COMBO} +- {pin_num: G10, pin_signal: GPIO_AD_B0_11, label: 'JTAG_nTRST/J21[3]/INT2_COMBO/LCD_TOUCH_INT/J22[3]/U32[9]', identifier: INT2_COMBO} +- {pin_num: K14, pin_signal: GPIO_AD_B0_12, label: UART1_TXD, identifier: UART1_TXD} +- {pin_num: L14, pin_signal: GPIO_AD_B0_13, label: UART1_RXD, identifier: UART1_RXD} +- {pin_num: H14, pin_signal: GPIO_AD_B0_14, label: 'CAN2_TX/U12[1]', identifier: CAN2_TX} +- {pin_num: L10, pin_signal: GPIO_AD_B0_15, label: 'CAN2_RX/U12[4]', identifier: CAN2_RX} +- {pin_num: J11, pin_signal: GPIO_AD_B1_00, label: 'I2C1_SCL/CSI_I2C_SCL/J35[20]/J23[6]/U13[17]/U32[4]', identifier: I2C_SCL_FXOS8700CQ;CSI_I2C_SCL} +- {pin_num: K11, pin_signal: GPIO_AD_B1_01, label: 'I2C1_SDA/CSI_I2C_SDA/J35[22]/J23[5]/U13[18]/U32[6]', identifier: I2C_SDA_FXOS8700CQ;CSI_I2C_SDA} +- {pin_num: L11, pin_signal: GPIO_AD_B1_02, label: 'SPDIF_OUT/J22[7]', identifier: SPDIF_OUT} +- {pin_num: M12, pin_signal: GPIO_AD_B1_03, label: 'SPDIF_IN/J22[8]', identifier: SPDIF_IN} +- {pin_num: H13, pin_signal: GPIO_AD_B1_08, label: 'AUD_INT/CSI_D9//J35[13]/J22[4]', identifier: CSI_D9} +- {pin_num: M13, pin_signal: GPIO_AD_B1_09, label: 'SAI1_MCLK/CSI_D8/J35[11]', identifier: CSI_D8} +- {pin_num: L13, pin_signal: GPIO_AD_B1_10, label: 'SAI1_RX_SYNC/CSI_D7/J35[9]/J23[1]', identifier: CSI_D7} +- {pin_num: J13, pin_signal: GPIO_AD_B1_11, label: 'SAI1_RX_BCLK/CSI_D6/J35[7]/J23[2]', identifier: CSI_D6} +- {pin_num: H12, pin_signal: GPIO_AD_B1_12, label: 'SAI1_RXD/CSI_D5/J35[5]/U13[16]', identifier: CSI_D5} +- {pin_num: H11, pin_signal: GPIO_AD_B1_13, label: 'SAI1_TXD/CSI_D4/J35[3]/U13[14]', identifier: CSI_D4} +- {pin_num: G12, pin_signal: GPIO_AD_B1_14, label: 'SAI1_TX_BCLK/CSI_D3/J35[4]/U13[12]', identifier: CSI_D3} +- {pin_num: J14, pin_signal: GPIO_AD_B1_15, label: 'SAI1_TX_SYNC/CSI_D2/J35[6]/U13[13]', identifier: CSI_D2} +- {pin_num: J4, pin_signal: GPIO_SD_B0_00, label: 'SD1_CMD/J24[6]', identifier: SD1_CMD} +- {pin_num: J3, pin_signal: GPIO_SD_B0_01, label: 'SD1_CLK/J24[3]', identifier: SD1_CLK} +- {pin_num: J1, pin_signal: GPIO_SD_B0_02, label: 'SD1_D0/J24[4]/SPI_MOSI/PWM', identifier: SD1_D0} +- {pin_num: K1, pin_signal: GPIO_SD_B0_03, label: 'SD1_D1/J24[5]/SPI_MISO', identifier: SD1_D1} +- {pin_num: H2, pin_signal: GPIO_SD_B0_04, label: SD1_D2, identifier: SD1_D2} +- {pin_num: J2, pin_signal: GPIO_SD_B0_05, label: SD1_D3, identifier: SD1_D3} +- {pin_num: L5, pin_signal: GPIO_SD_B1_00, label: FlexSPI_D3_B, identifier: FlexSPI_D3_B} +- {pin_num: M5, pin_signal: GPIO_SD_B1_01, label: FlexSPI_D2_B, identifier: FlexSPI_D2_B} +- {pin_num: M3, pin_signal: GPIO_SD_B1_02, label: FlexSPI_D1_B, identifier: FlexSPI_D1_B} +- {pin_num: M4, pin_signal: GPIO_SD_B1_03, label: FlexSPI_D0_B, identifier: FlexSPI_D0_B} +- {pin_num: P2, pin_signal: GPIO_SD_B1_04, label: FlexSPI_CLK_B, identifier: FlexSPI_CLK_B} +- {pin_num: N3, pin_signal: GPIO_SD_B1_05, label: FlexSPI_DQS, identifier: FlexSPI_DQS} +- {pin_num: L3, pin_signal: GPIO_SD_B1_06, label: FlexSPI_SS0, identifier: FlexSPI_SS0} +- {pin_num: L4, pin_signal: GPIO_SD_B1_07, label: FlexSPI_CLK, identifier: FlexSPI_CLK} +- {pin_num: P3, pin_signal: GPIO_SD_B1_08, label: FlexSPI_D0_A, identifier: FlexSPI_D0_A} +- {pin_num: N4, pin_signal: GPIO_SD_B1_09, label: FlexSPI_D1_A, identifier: FlexSPI_D1_A} +- {pin_num: P4, pin_signal: GPIO_SD_B1_10, label: FlexSPI_D2_A, identifier: FlexSPI_D2_A} +- {pin_num: P5, pin_signal: GPIO_SD_B1_11, label: FlexSPI_D3_A, identifier: FlexSPI_D3_A} +- {pin_num: M8, pin_signal: USB_OTG1_DN, label: OTG1_DN, identifier: OTG1_DN} +- {pin_num: L8, pin_signal: USB_OTG1_DP, label: OTG1_DP, identifier: OTG1_DP} +- {pin_num: N7, pin_signal: USB_OTG2_DN, label: OTG2_DN, identifier: OTG2_DN} +- {pin_num: P7, pin_signal: USB_OTG2_DP, label: OTG2_DP, identifier: OTG2_DP} +- {pin_num: K8, pin_signal: VDD_USB_CAP, label: VDD_USB_3V} +- {pin_num: N6, pin_signal: USB_OTG1_VBUS, label: 5V_USB_OTG} +- {pin_num: P6, pin_signal: USB_OTG2_VBUS, label: 5V_USB_HS} +- {pin_num: L12, pin_signal: GPIO_AD_B1_04, label: 'CSI_PIXCLK/J35[8]/J23[3]', identifier: CSI_PIXCLK} +- {pin_num: K12, pin_signal: GPIO_AD_B1_05, label: 'CSI_MCLK/J35[12]/J23[4]', identifier: CSI_MCLK} +- {pin_num: J12, pin_signal: GPIO_AD_B1_06, label: 'CSI_VSYNC/J35[18]/J22[2]/UART_TX', identifier: CSI_VSYNC} +- {pin_num: K10, pin_signal: GPIO_AD_B1_07, label: 'CSI_HSYNC/J35[16]/J22[1]/UART_RX', identifier: CSI_HSYNC} +- {pin_num: M7, pin_signal: POR_B, label: 'RST_TGTMCU_B/POR_B/J21[15]', identifier: RST_TGTMCU_B;POR_B} +- {pin_num: N14, pin_signal: VDDA_ADC_3P3, label: VDDA_ADC_3P3_MCU} +- {pin_num: P12, pin_signal: VDD_HIGH_IN, label: VDD_HIGH_IN_MCU} +- {pin_num: M9, pin_signal: VDD_SNVS_IN, label: VDD_SNVS_IN} +- {pin_num: F6, pin_signal: VDD_SOC_IN0, label: VDD_SOC_IN} +- {pin_num: H6, pin_signal: VDD_SOC_IN2, label: VDD_SOC_IN} +- {pin_num: G6, pin_signal: VDD_SOC_IN1, label: VDD_SOC_IN} +- {pin_num: F7, pin_signal: VDD_SOC_IN3, label: VDD_SOC_IN} +- {pin_num: F8, pin_signal: VDD_SOC_IN4, label: VDD_SOC_IN} +- {pin_num: F9, pin_signal: VDD_SOC_IN5, label: VDD_SOC_IN} +- {pin_num: G9, pin_signal: VDD_SOC_IN6, label: VDD_SOC_IN} +- {pin_num: H9, pin_signal: VDD_SOC_IN7, label: VDD_SOC_IN} +- {pin_num: J9, pin_signal: VDD_SOC_IN8, label: VDD_SOC_IN} +- {pin_num: P1, pin_signal: VSS1, label: GND} +- {pin_num: E2, pin_signal: VSS2, label: GND} +- {pin_num: K2, pin_signal: VSS3, label: GND} +- {pin_num: B5, pin_signal: VSS4, label: GND} +- {pin_num: N5, pin_signal: VSS5, label: GND} +- {pin_num: G7, pin_signal: VSS6, label: GND} +- {pin_num: H7, pin_signal: VSS7, label: GND} +- {pin_num: J7, pin_signal: VSS8, label: GND} +- {pin_num: G8, pin_signal: VSS9, label: GND} +- {pin_num: H8, pin_signal: VSS10, label: GND} +- {pin_num: J8, pin_signal: VSS11, label: GND} +- {pin_num: N8, pin_signal: VSS12, label: GND} +- {pin_num: L9, pin_signal: VSS13, label: GND} +- {pin_num: B10, pin_signal: VSS14, label: GND} +- {pin_num: E13, pin_signal: VSS15, label: GND} +- {pin_num: K13, pin_signal: VSS16, label: GND} +- {pin_num: A14, pin_signal: VSS17, label: GND} +- {pin_num: P14, pin_signal: VSS18, label: GND} +- {pin_num: A1, pin_signal: VSS0, label: GND} +- {pin_num: J6, pin_signal: NVCC_SD0, label: NVCC_SD, identifier: NVCC_SD} +- {pin_num: K5, pin_signal: NVCC_SD1, label: FLASH_VCC, identifier: FLASH_VCC} +- {pin_num: F5, pin_signal: NVCC_EMC0, label: DCDC_3V3} +- {pin_num: E6, pin_signal: NVCC_EMC1, label: DCDC_3V3} +- {pin_num: L6, pin_signal: WAKEUP, label: SD_PWREN, identifier: SD_PWREN;USER_BUTTON} +- {pin_num: L1, pin_signal: DCDC_IN0, label: MCU_DCDC_IN_3V3} +- {pin_num: L2, pin_signal: DCDC_IN1, label: MCU_DCDC_IN_3V3} +- {pin_num: K4, pin_signal: DCDC_IN_Q, label: MCU_DCDC_IN_3V3} +- {pin_num: M1, pin_signal: DCDC_LP0, label: VDD_SOC_IN} +- {pin_num: M2, pin_signal: DCDC_LP1, label: VDD_SOC_IN} +- {pin_num: P11, pin_signal: XTALI, label: XTALI, identifier: XTALI} +- {pin_num: N11, pin_signal: XTALO, label: XTALO, identifier: XTALO} +- {pin_num: N9, pin_signal: RTC_XTALI, label: RTC_XTALI, identifier: RTC_XTALI} +- {pin_num: P9, pin_signal: RTC_XTALO, label: RTC_XTALO, identifier: RTC_XTALO} +- {pin_num: N1, pin_signal: DCDC_GND0, label: GND} +- {pin_num: N2, pin_signal: DCDC_GND1, label: GND} +- {pin_num: J5, pin_signal: DCDC_SENSE, label: VDD_SOC_IN} +- {pin_num: K3, pin_signal: DCDC_PSWITCH, label: MCU_DCDC_IN_3V3} +- {pin_num: K7, pin_signal: PMIC_ON_REQ, label: PMIC_ON_REQ, identifier: PMIC_ON_REQ} +- {pin_num: L7, pin_signal: PMIC_STBY_REQ, label: PERI_PWREN, identifier: PERI_PWREN} +- {pin_num: M6, pin_signal: ONOFF, label: ONOFF, identifier: ONOFF} +- {pin_num: K6, pin_signal: TEST_MODE, label: GND} +- {pin_num: P10, pin_signal: NVCC_PLL, label: VDDA_1P1_CAP} +- {pin_num: P8, pin_signal: VDD_HIGH_CAP, label: VDDA_2P5_CAP} +- {pin_num: K9, pin_signal: NGND_KEL0, label: GND} +- {pin_num: M10, pin_signal: VDD_SNVS_CAP, label: GND} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +#include "fsl_common.h" +#include "fsl_iomuxc.h" +#include "fsl_gpio.h" +#include "pin_mux.h" + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitBootPins + * Description : Calls initialization functions. + * + * END ****************************************************************************************************************/ +void BOARD_InitBootPins(void) { + BOARD_InitPins(); + BOARD_InitDEBUG_UART(); + BOARD_InitENET(); + BOARD_InitUSDHC(); + BOARD_InitARDUINO_UART(); + BOARD_InitUSER_LED(); + BOARD_InitUSER_BUTTON(); + BOARD_InitAudio(); +} + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitPins: +- options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} +- pin_list: [] + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitPins(void) { +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitDEBUG_UART: +- options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: K14, peripheral: LPUART1, signal: TX, pin_signal: GPIO_AD_B0_12, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Down_100K_Ohm, + pull_keeper_select: Keeper, pull_keeper_enable: Enable, open_drain: Disable, speed: MHZ_100, drive_strength: R0_6, slew_rate: Slow} + - {pin_num: L14, peripheral: LPUART1, signal: RX, pin_signal: GPIO_AD_B0_13, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Down_100K_Ohm, + pull_keeper_select: Keeper, pull_keeper_enable: Enable, open_drain: Disable, speed: MHZ_100, drive_strength: R0_6, slew_rate: Slow} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitDEBUG_UART + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitDEBUG_UART(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_12_LPUART1_TX, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_13_LPUART1_RX, 0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_12_LPUART1_TX, 0x10B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_13_LPUART1_RX, 0x10B0U); +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitSDRAM: +- options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: C2, peripheral: SEMC, signal: 'ADDR, 00', pin_signal: GPIO_EMC_09} + - {pin_num: G1, peripheral: SEMC, signal: 'ADDR, 01', pin_signal: GPIO_EMC_10} + - {pin_num: G3, peripheral: SEMC, signal: 'ADDR, 02', pin_signal: GPIO_EMC_11} + - {pin_num: H1, peripheral: SEMC, signal: 'ADDR, 03', pin_signal: GPIO_EMC_12} + - {pin_num: A6, peripheral: SEMC, signal: 'ADDR, 04', pin_signal: GPIO_EMC_13} + - {pin_num: B6, peripheral: SEMC, signal: 'ADDR, 05', pin_signal: GPIO_EMC_14} + - {pin_num: B1, peripheral: SEMC, signal: 'ADDR, 06', pin_signal: GPIO_EMC_15} + - {pin_num: A5, peripheral: SEMC, signal: 'ADDR, 07', pin_signal: GPIO_EMC_16} + - {pin_num: A4, peripheral: SEMC, signal: 'ADDR, 08', pin_signal: GPIO_EMC_17} + - {pin_num: B2, peripheral: SEMC, signal: 'ADDR, 09', pin_signal: GPIO_EMC_18} + - {pin_num: G2, peripheral: SEMC, signal: 'ADDR, 10', pin_signal: GPIO_EMC_23} + - {pin_num: B4, peripheral: SEMC, signal: 'ADDR, 11', pin_signal: GPIO_EMC_19} + - {pin_num: A3, peripheral: SEMC, signal: 'ADDR, 12', pin_signal: GPIO_EMC_20} + - {pin_num: C1, peripheral: SEMC, signal: 'BA, 0', pin_signal: GPIO_EMC_21} + - {pin_num: F1, peripheral: SEMC, signal: 'BA, 1', pin_signal: GPIO_EMC_22} + - {pin_num: D3, peripheral: SEMC, signal: semc_cas, pin_signal: GPIO_EMC_24} + - {pin_num: A2, peripheral: SEMC, signal: semc_cke, pin_signal: GPIO_EMC_27} + - {pin_num: B3, peripheral: SEMC, signal: semc_clk, pin_signal: GPIO_EMC_26} + - {pin_num: E3, peripheral: SEMC, signal: 'DATA, 00', pin_signal: GPIO_EMC_00} + - {pin_num: F3, peripheral: SEMC, signal: 'DATA, 01', pin_signal: GPIO_EMC_01} + - {pin_num: F4, peripheral: SEMC, signal: 'DATA, 02', pin_signal: GPIO_EMC_02} + - {pin_num: G4, peripheral: SEMC, signal: 'DATA, 03', pin_signal: GPIO_EMC_03} + - {pin_num: F2, peripheral: SEMC, signal: 'DATA, 04', pin_signal: GPIO_EMC_04} + - {pin_num: G5, peripheral: SEMC, signal: 'DATA, 05', pin_signal: GPIO_EMC_05} + - {pin_num: H5, peripheral: SEMC, signal: 'DATA, 06', pin_signal: GPIO_EMC_06} + - {pin_num: H4, peripheral: SEMC, signal: 'DATA, 07', pin_signal: GPIO_EMC_07} + - {pin_num: C6, peripheral: SEMC, signal: 'DATA, 08', pin_signal: GPIO_EMC_30} + - {pin_num: C5, peripheral: SEMC, signal: 'DATA, 09', pin_signal: GPIO_EMC_31} + - {pin_num: D5, peripheral: SEMC, signal: 'DATA, 10', pin_signal: GPIO_EMC_32} + - {pin_num: C4, peripheral: SEMC, signal: 'DATA, 11', pin_signal: GPIO_EMC_33} + - {pin_num: D4, peripheral: SEMC, signal: 'DATA, 12', pin_signal: GPIO_EMC_34} + - {pin_num: E5, peripheral: SEMC, signal: 'DATA, 13', pin_signal: GPIO_EMC_35} + - {pin_num: C3, peripheral: SEMC, signal: 'DATA, 14', pin_signal: GPIO_EMC_36} + - {pin_num: E4, peripheral: SEMC, signal: 'DATA, 15', pin_signal: GPIO_EMC_37} + - {pin_num: H3, peripheral: SEMC, signal: 'DM, 0', pin_signal: GPIO_EMC_08} + - {pin_num: D6, peripheral: SEMC, signal: 'DM, 1', pin_signal: GPIO_EMC_38} + - {pin_num: D2, peripheral: SEMC, signal: semc_ras, pin_signal: GPIO_EMC_25} + - {pin_num: D1, peripheral: SEMC, signal: semc_we, pin_signal: GPIO_EMC_28} + - {pin_num: C7, peripheral: SEMC, signal: 'CSX, 0', pin_signal: GPIO_EMC_41} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitSDRAM + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitSDRAM(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_00_SEMC_DATA00, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_01_SEMC_DATA01, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_02_SEMC_DATA02, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_03_SEMC_DATA03, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_04_SEMC_DATA04, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_05_SEMC_DATA05, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_06_SEMC_DATA06, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_07_SEMC_DATA07, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_08_SEMC_DM00, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_09_SEMC_ADDR00, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_10_SEMC_ADDR01, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_11_SEMC_ADDR02, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_12_SEMC_ADDR03, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_13_SEMC_ADDR04, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_14_SEMC_ADDR05, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_15_SEMC_ADDR06, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_16_SEMC_ADDR07, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_17_SEMC_ADDR08, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_18_SEMC_ADDR09, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_19_SEMC_ADDR11, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_20_SEMC_ADDR12, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_21_SEMC_BA0, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_22_SEMC_BA1, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_23_SEMC_ADDR10, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_24_SEMC_CAS, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_25_SEMC_RAS, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_26_SEMC_CLK, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_27_SEMC_CKE, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_28_SEMC_WE, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_30_SEMC_DATA08, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_31_SEMC_DATA09, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_32_SEMC_DATA10, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_33_SEMC_DATA11, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_34_SEMC_DATA12, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_35_SEMC_DATA13, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_36_SEMC_DATA14, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_37_SEMC_DATA15, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_38_SEMC_DM01, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_41_SEMC_CSX00, 0U); +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitCSI: +- options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: H13, peripheral: CSI, signal: 'csi_data, 09', pin_signal: GPIO_AD_B1_08} + - {pin_num: M13, peripheral: CSI, signal: 'csi_data, 08', pin_signal: GPIO_AD_B1_09} + - {pin_num: L13, peripheral: CSI, signal: 'csi_data, 07', pin_signal: GPIO_AD_B1_10} + - {pin_num: J13, peripheral: CSI, signal: 'csi_data, 06', pin_signal: GPIO_AD_B1_11} + - {pin_num: H12, peripheral: CSI, signal: 'csi_data, 05', pin_signal: GPIO_AD_B1_12} + - {pin_num: H11, peripheral: CSI, signal: 'csi_data, 04', pin_signal: GPIO_AD_B1_13} + - {pin_num: J14, peripheral: CSI, signal: 'csi_data, 02', pin_signal: GPIO_AD_B1_15} + - {pin_num: G12, peripheral: CSI, signal: 'csi_data, 03', pin_signal: GPIO_AD_B1_14} + - {pin_num: L12, peripheral: CSI, signal: csi_pixclk, pin_signal: GPIO_AD_B1_04} + - {pin_num: K12, peripheral: CSI, signal: csi_mclk, pin_signal: GPIO_AD_B1_05} + - {pin_num: J12, peripheral: CSI, signal: csi_vsync, pin_signal: GPIO_AD_B1_06} + - {pin_num: K10, peripheral: CSI, signal: csi_hsync, pin_signal: GPIO_AD_B1_07} + - {pin_num: J11, peripheral: LPI2C1, signal: SCL, pin_signal: GPIO_AD_B1_00, identifier: CSI_I2C_SCL, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Up_22K_Ohm, + pull_keeper_select: Keeper, pull_keeper_enable: Enable, open_drain: Enable, speed: MHZ_100, drive_strength: R0_6, slew_rate: Slow} + - {pin_num: K11, peripheral: LPI2C1, signal: SDA, pin_signal: GPIO_AD_B1_01, identifier: CSI_I2C_SDA, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Up_22K_Ohm, + pull_keeper_select: Keeper, pull_keeper_enable: Enable, open_drain: Enable, speed: MHZ_100, drive_strength: R0_6, slew_rate: Slow} + - {pin_num: F11, peripheral: GPIO1, signal: 'gpio_io, 04', pin_signal: GPIO_AD_B0_04} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitCSI + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitCSI(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_04_GPIO1_IO04, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_00_LPI2C1_SCL, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_01_LPI2C1_SDA, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_04_CSI_PIXCLK, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_05_CSI_MCLK, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_06_CSI_VSYNC, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_07_CSI_HSYNC, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_08_CSI_DATA09, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_09_CSI_DATA08, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_10_CSI_DATA07, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_11_CSI_DATA06, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_12_CSI_DATA05, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_13_CSI_DATA04, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_14_CSI_DATA03, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_15_CSI_DATA02, 0U); + IOMUXC_GPR->GPR26 = ((IOMUXC_GPR->GPR26 & + (~(BOARD_INITCSI_IOMUXC_GPR_GPR26_GPIO_MUX1_GPIO_SEL_MASK))) + | IOMUXC_GPR_GPR26_GPIO_MUX1_GPIO_SEL(0x00U) + ); + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B1_00_LPI2C1_SCL, 0xD8B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B1_01_LPI2C1_SDA, 0xD8B0U); +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitLCD: +- options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: C8, peripheral: LCDIF, signal: 'lcdif_data, 00', pin_signal: GPIO_B0_04, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: B8, peripheral: LCDIF, signal: 'lcdif_data, 01', pin_signal: GPIO_B0_05, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: A8, peripheral: LCDIF, signal: 'lcdif_data, 02', pin_signal: GPIO_B0_06, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: D7, peripheral: LCDIF, signal: lcdif_clk, pin_signal: GPIO_B0_00, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: A9, peripheral: LCDIF, signal: 'lcdif_data, 03', pin_signal: GPIO_B0_07, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: B9, peripheral: LCDIF, signal: 'lcdif_data, 04', pin_signal: GPIO_B0_08, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: C9, peripheral: LCDIF, signal: 'lcdif_data, 05', pin_signal: GPIO_B0_09, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: D9, peripheral: LCDIF, signal: 'lcdif_data, 06', pin_signal: GPIO_B0_10, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: A10, peripheral: LCDIF, signal: 'lcdif_data, 07', pin_signal: GPIO_B0_11, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: C10, peripheral: LCDIF, signal: 'lcdif_data, 08', pin_signal: GPIO_B0_12, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: D10, peripheral: LCDIF, signal: 'lcdif_data, 09', pin_signal: GPIO_B0_13, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: E10, peripheral: LCDIF, signal: 'lcdif_data, 10', pin_signal: GPIO_B0_14, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: E11, peripheral: LCDIF, signal: 'lcdif_data, 11', pin_signal: GPIO_B0_15, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: A11, peripheral: LCDIF, signal: 'lcdif_data, 12', pin_signal: GPIO_B1_00, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: B11, peripheral: LCDIF, signal: 'lcdif_data, 13', pin_signal: GPIO_B1_01, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: C11, peripheral: LCDIF, signal: 'lcdif_data, 14', pin_signal: GPIO_B1_02, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: D11, peripheral: LCDIF, signal: 'lcdif_data, 15', pin_signal: GPIO_B1_03, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: E7, peripheral: LCDIF, signal: lcdif_enable, pin_signal: GPIO_B0_01, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: E8, peripheral: LCDIF, signal: lcdif_hsync, pin_signal: GPIO_B0_02, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: D8, peripheral: LCDIF, signal: lcdif_vsync, pin_signal: GPIO_B0_03, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: B14, peripheral: GPIO2, signal: 'gpio_io, 31', pin_signal: GPIO_B1_15, slew_rate: Slow} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitLCD + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitLCD(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_00_LCD_CLK, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_01_LCD_ENABLE, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_02_LCD_HSYNC, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_03_LCD_VSYNC, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_04_LCD_DATA00, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_05_LCD_DATA01, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_06_LCD_DATA02, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_07_LCD_DATA03, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_08_LCD_DATA04, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_09_LCD_DATA05, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_10_LCD_DATA06, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_11_LCD_DATA07, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_12_LCD_DATA08, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_13_LCD_DATA09, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_14_LCD_DATA10, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_15_LCD_DATA11, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_00_LCD_DATA12, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_01_LCD_DATA13, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_02_LCD_DATA14, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_03_LCD_DATA15, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_15_GPIO2_IO31, 0U); + IOMUXC_GPR->GPR27 = ((IOMUXC_GPR->GPR27 & + (~(BOARD_INITLCD_IOMUXC_GPR_GPR27_GPIO_MUX2_GPIO_SEL_MASK))) + | IOMUXC_GPR_GPR27_GPIO_MUX2_GPIO_SEL(0x00U) + ); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_00_LCD_CLK, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_01_LCD_ENABLE, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_02_LCD_HSYNC, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_03_LCD_VSYNC, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_04_LCD_DATA00, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_05_LCD_DATA01, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_06_LCD_DATA02, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_07_LCD_DATA03, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_08_LCD_DATA04, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_09_LCD_DATA05, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_10_LCD_DATA06, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_11_LCD_DATA07, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_12_LCD_DATA08, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_13_LCD_DATA09, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_14_LCD_DATA10, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_15_LCD_DATA11, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_00_LCD_DATA12, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_01_LCD_DATA13, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_02_LCD_DATA14, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_03_LCD_DATA15, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_15_GPIO2_IO31, 0x10B0U); +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitCAN: +- options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: H14, peripheral: CAN2, signal: TX, pin_signal: GPIO_AD_B0_14} + - {pin_num: L10, peripheral: CAN2, signal: RX, pin_signal: GPIO_AD_B0_15} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitCAN + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitCAN(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_14_FLEXCAN2_TX, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_15_FLEXCAN2_RX, 0U); +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitENET: +- options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: A7, peripheral: ENET, signal: enet_mdc, pin_signal: GPIO_EMC_40} + - {pin_num: C7, peripheral: ENET, signal: enet_mdio, pin_signal: GPIO_EMC_41} + - {pin_num: B13, peripheral: ENET, signal: enet_ref_clk, pin_signal: GPIO_B1_10} + - {pin_num: E12, peripheral: ENET, signal: 'enet_rx_data, 0', pin_signal: GPIO_B1_04} + - {pin_num: D12, peripheral: ENET, signal: 'enet_rx_data, 1', pin_signal: GPIO_B1_05} + - {pin_num: C12, peripheral: ENET, signal: enet_rx_en, pin_signal: GPIO_B1_06} + - {pin_num: C13, peripheral: ENET, signal: enet_rx_er, pin_signal: GPIO_B1_11} + - {pin_num: B12, peripheral: ENET, signal: 'enet_tx_data, 0', pin_signal: GPIO_B1_07} + - {pin_num: A12, peripheral: ENET, signal: 'enet_tx_data, 1', pin_signal: GPIO_B1_08} + - {pin_num: A13, peripheral: ENET, signal: enet_tx_en, pin_signal: GPIO_B1_09} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitENET + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitENET(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_04_ENET_RX_DATA00, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_05_ENET_RX_DATA01, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_06_ENET_RX_EN, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_07_ENET_TX_DATA00, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_08_ENET_TX_DATA01, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_09_ENET_TX_EN, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_10_ENET_REF_CLK, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_11_ENET_RX_ER, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_40_ENET_MDC, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_41_ENET_MDIO, 0U); +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitUSDHC: +- options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: J2, peripheral: USDHC1, signal: 'usdhc_data, 3', pin_signal: GPIO_SD_B0_05} + - {pin_num: H2, peripheral: USDHC1, signal: 'usdhc_data, 2', pin_signal: GPIO_SD_B0_04} + - {pin_num: K1, peripheral: USDHC1, signal: 'usdhc_data, 1', pin_signal: GPIO_SD_B0_03} + - {pin_num: J1, peripheral: USDHC1, signal: 'usdhc_data, 0', pin_signal: GPIO_SD_B0_02} + - {pin_num: J4, peripheral: USDHC1, signal: usdhc_cmd, pin_signal: GPIO_SD_B0_00} + - {pin_num: J3, peripheral: USDHC1, signal: usdhc_clk, pin_signal: GPIO_SD_B0_01} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitUSDHC + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitUSDHC(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_00_USDHC1_CMD, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_01_USDHC1_CLK, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_02_USDHC1_DATA0, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_03_USDHC1_DATA1, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_04_USDHC1_DATA2, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_05_USDHC1_DATA3, 0U); +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitHyperFlash: +- options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: L4, peripheral: FLEXSPI, signal: FLEXSPI_A_SCLK, pin_signal: GPIO_SD_B1_07} + - {pin_num: P4, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA2, pin_signal: GPIO_SD_B1_10} + - {pin_num: P3, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA0, pin_signal: GPIO_SD_B1_08} + - {pin_num: N4, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA1, pin_signal: GPIO_SD_B1_09} + - {pin_num: L5, peripheral: FLEXSPI, signal: FLEXSPI_B_DATA3, pin_signal: GPIO_SD_B1_00} + - {pin_num: M5, peripheral: FLEXSPI, signal: FLEXSPI_B_DATA2, pin_signal: GPIO_SD_B1_01} + - {pin_num: M3, peripheral: FLEXSPI, signal: FLEXSPI_B_DATA1, pin_signal: GPIO_SD_B1_02} + - {pin_num: M4, peripheral: FLEXSPI, signal: FLEXSPI_B_DATA0, pin_signal: GPIO_SD_B1_03} + - {pin_num: P2, peripheral: FLEXSPI, signal: FLEXSPI_B_SCLK, pin_signal: GPIO_SD_B1_04} + - {pin_num: L3, peripheral: FLEXSPI, signal: FLEXSPI_A_SS0_B, pin_signal: GPIO_SD_B1_06} + - {pin_num: P5, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA3, pin_signal: GPIO_SD_B1_11} + - {pin_num: N3, peripheral: FLEXSPI, signal: FLEXSPI_A_DQS, pin_signal: GPIO_SD_B1_05} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitHyperFlash + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitHyperFlash(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_00_FLEXSPIB_DATA03, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_01_FLEXSPIB_DATA02, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_02_FLEXSPIB_DATA01, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_03_FLEXSPIB_DATA00, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_04_FLEXSPIB_SCLK, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_05_FLEXSPIA_DQS, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_06_FLEXSPIA_SS0_B, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_07_FLEXSPIA_SCLK, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_08_FLEXSPIA_DATA00, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_09_FLEXSPIA_DATA01, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_10_FLEXSPIA_DATA02, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_11_FLEXSPIA_DATA03, 0U); +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitARDUINO_UART: +- options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: J12, peripheral: LPUART3, signal: TX, pin_signal: GPIO_AD_B1_06} + - {pin_num: K10, peripheral: LPUART3, signal: RX, pin_signal: GPIO_AD_B1_07} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitARDUINO_UART + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitARDUINO_UART(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_06_LPUART3_TX, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_07_LPUART3_RX, 0U); +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitUSER_LED: +- options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: F14, peripheral: GPIO1, signal: 'gpio_io, 09', pin_signal: GPIO_AD_B0_09, direction: OUTPUT, gpio_init_state: 'true', pull_keeper_enable: Disable} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitUSER_LED + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitUSER_LED(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + /* GPIO configuration of USER_LED on GPIO_AD_B0_09 (pin F14) */ + gpio_pin_config_t USER_LED_config = { + .direction = kGPIO_DigitalOutput, + .outputLogic = 1U, + .interruptMode = kGPIO_NoIntmode + }; + /* Initialize GPIO functionality on GPIO_AD_B0_09 (pin F14) */ + GPIO_PinInit(GPIO1, 9U, &USER_LED_config); + + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_09_GPIO1_IO09, 0U); + IOMUXC_GPR->GPR26 = ((IOMUXC_GPR->GPR26 & + (~(BOARD_INITUSER_LED_IOMUXC_GPR_GPR26_GPIO_MUX1_GPIO_SEL_MASK))) + | IOMUXC_GPR_GPR26_GPIO_MUX1_GPIO_SEL(0x00U) + ); + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_09_GPIO1_IO09, 0x60A0U); +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitUSER_BUTTON: +- options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: L6, peripheral: GPIO5, signal: 'gpio_io, 00', pin_signal: WAKEUP, identifier: USER_BUTTON, direction: INPUT} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitUSER_BUTTON + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitUSER_BUTTON(void) { + CLOCK_EnableClock(kCLOCK_IomuxcSnvs); + + /* GPIO configuration of USER_BUTTON on WAKEUP (pin L6) */ + gpio_pin_config_t USER_BUTTON_config = { + .direction = kGPIO_DigitalInput, + .outputLogic = 0U, + .interruptMode = kGPIO_NoIntmode + }; + /* Initialize GPIO functionality on WAKEUP (pin L6) */ + GPIO_PinInit(GPIO5, 0U, &USER_BUTTON_config); + + IOMUXC_SetPinMux(IOMUXC_SNVS_WAKEUP_GPIO5_IO00, 0U); +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitAudio: +- options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: H13, peripheral: GPIO1, signal: 'gpio_io, 24', pin_signal: GPIO_AD_B1_08, direction: INPUT, gpio_interrupt: kGPIO_IntRisingEdge, pull_up_down_config: Pull_Up_47K_Ohm} + - {pin_num: M13, peripheral: SAI1, signal: sai_mclk, pin_signal: GPIO_AD_B1_09, software_input_on: Enable} + - {pin_num: J11, peripheral: LPI2C1, signal: SCL, pin_signal: GPIO_AD_B1_00, software_input_on: Enable, pull_up_down_config: Pull_Up_22K_Ohm, open_drain: Enable} + - {pin_num: K11, peripheral: LPI2C1, signal: SDA, pin_signal: GPIO_AD_B1_01, software_input_on: Enable, pull_up_down_config: Pull_Up_22K_Ohm, open_drain: Enable} + - {pin_num: H12, peripheral: SAI1, signal: sai_rx_data0, pin_signal: GPIO_AD_B1_12, software_input_on: Enable} + - {pin_num: H11, peripheral: SAI1, signal: sai_tx_data0, pin_signal: GPIO_AD_B1_13, software_input_on: Enable} + - {pin_num: G12, peripheral: SAI1, signal: sai_tx_bclk, pin_signal: GPIO_AD_B1_14, software_input_on: Enable} + - {pin_num: J14, peripheral: SAI1, signal: sai_tx_sync, pin_signal: GPIO_AD_B1_15, software_input_on: Enable} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitAudio + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitAudio(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + /* GPIO configuration of CSI_D9 on GPIO_AD_B1_08 (pin H13) */ + gpio_pin_config_t CSI_D9_config = { + .direction = kGPIO_DigitalInput, + .outputLogic = 0U, + .interruptMode = kGPIO_IntRisingEdge + }; + /* Initialize GPIO functionality on GPIO_AD_B1_08 (pin H13) */ + GPIO_PinInit(GPIO1, 24U, &CSI_D9_config); + /* Enable GPIO pin interrupt on GPIO_AD_B1_08 (pin H13) */ + GPIO_PortEnableInterrupts(GPIO1, 1U << 24U); + + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_00_LPI2C1_SCL, 1U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_01_LPI2C1_SDA, 1U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_08_GPIO1_IO24, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_09_SAI1_MCLK, 1U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_12_SAI1_RX_DATA00, 1U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_13_SAI1_TX_DATA00, 1U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_14_SAI1_TX_BCLK, 1U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_15_SAI1_TX_SYNC, 1U); + IOMUXC_GPR->GPR26 = ((IOMUXC_GPR->GPR26 & + (~(BOARD_INITAUDIO_IOMUXC_GPR_GPR26_GPIO_MUX1_GPIO_SEL_MASK))) + | IOMUXC_GPR_GPR26_GPIO_MUX1_GPIO_SEL(0x00U) + ); + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B1_00_LPI2C1_SCL, 0xD8B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B1_01_LPI2C1_SDA, 0xD8B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B1_08_GPIO1_IO24, 0x50B0U); +} + +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ diff --git a/Platform_MIMXRT1064-EVK/RTE/Board_Support/MIMXRT1064DVL6A/pin_mux.h b/Platform_MIMXRT1064-EVK/RTE/Board_Support/MIMXRT1064DVL6A/pin_mux.h new file mode 100644 index 0000000..01c6c9c --- /dev/null +++ b/Platform_MIMXRT1064-EVK/RTE/Board_Support/MIMXRT1064DVL6A/pin_mux.h @@ -0,0 +1,833 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +#ifndef _PIN_MUX_H_ +#define _PIN_MUX_H_ + +/*********************************************************************************************************************** + * Definitions + **********************************************************************************************************************/ + +/*! @brief Direction type */ +typedef enum _pin_mux_direction +{ + kPIN_MUX_DirectionInput = 0U, /* Input direction */ + kPIN_MUX_DirectionOutput = 1U, /* Output direction */ + kPIN_MUX_DirectionInputOrOutput = 2U /* Input or output direction */ +} pin_mux_direction_t; + +/*! + * @addtogroup pin_mux + * @{ + */ + +/*********************************************************************************************************************** + * API + **********************************************************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Calls initialization functions. + * + */ +void BOARD_InitBootPins(void); + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitPins(void); + +/* GPIO_AD_B0_12 (coord K14), UART1_TXD */ +/* Routed pin properties */ +#define BOARD_INITDEBUG_UART_UART1_TXD_PERIPHERAL LPUART1 /*!< Peripheral name */ +#define BOARD_INITDEBUG_UART_UART1_TXD_SIGNAL TX /*!< Signal name */ + +/* GPIO_AD_B0_13 (coord L14), UART1_RXD */ +/* Routed pin properties */ +#define BOARD_INITDEBUG_UART_UART1_RXD_PERIPHERAL LPUART1 /*!< Peripheral name */ +#define BOARD_INITDEBUG_UART_UART1_RXD_SIGNAL RX /*!< Signal name */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitDEBUG_UART(void); + +/* GPIO_EMC_09 (coord C2), SEMC_A0 */ +/* Routed pin properties */ +#define BOARD_INITSDRAM_SEMC_A0_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAM_SEMC_A0_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAM_SEMC_A0_CHANNEL 0U /*!< Signal channel */ + +/* GPIO_EMC_10 (coord G1), SEMC_A1 */ +/* Routed pin properties */ +#define BOARD_INITSDRAM_SEMC_A1_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAM_SEMC_A1_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAM_SEMC_A1_CHANNEL 1U /*!< Signal channel */ + +/* GPIO_EMC_11 (coord G3), SEMC_A2 */ +/* Routed pin properties */ +#define BOARD_INITSDRAM_SEMC_A2_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAM_SEMC_A2_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAM_SEMC_A2_CHANNEL 2U /*!< Signal channel */ + +/* GPIO_EMC_12 (coord H1), SEMC_A3 */ +/* Routed pin properties */ +#define BOARD_INITSDRAM_SEMC_A3_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAM_SEMC_A3_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAM_SEMC_A3_CHANNEL 3U /*!< Signal channel */ + +/* GPIO_EMC_13 (coord A6), SEMC_A4 */ +/* Routed pin properties */ +#define BOARD_INITSDRAM_SEMC_A4_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAM_SEMC_A4_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAM_SEMC_A4_CHANNEL 4U /*!< Signal channel */ + +/* GPIO_EMC_14 (coord B6), SEMC_A5 */ +/* Routed pin properties */ +#define BOARD_INITSDRAM_SEMC_A5_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAM_SEMC_A5_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAM_SEMC_A5_CHANNEL 5U /*!< Signal channel */ + +/* GPIO_EMC_15 (coord B1), SEMC_A6 */ +/* Routed pin properties */ +#define BOARD_INITSDRAM_SEMC_A6_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAM_SEMC_A6_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAM_SEMC_A6_CHANNEL 6U /*!< Signal channel */ + +/* GPIO_EMC_16 (coord A5), SEMC_A7 */ +/* Routed pin properties */ +#define BOARD_INITSDRAM_SEMC_A7_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAM_SEMC_A7_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAM_SEMC_A7_CHANNEL 7U /*!< Signal channel */ + +/* GPIO_EMC_17 (coord A4), SEMC_A8 */ +/* Routed pin properties */ +#define BOARD_INITSDRAM_SEMC_A8_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAM_SEMC_A8_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAM_SEMC_A8_CHANNEL 8U /*!< Signal channel */ + +/* GPIO_EMC_18 (coord B2), SEMC_A9 */ +/* Routed pin properties */ +#define BOARD_INITSDRAM_SEMC_A9_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAM_SEMC_A9_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAM_SEMC_A9_CHANNEL 9U /*!< Signal channel */ + +/* GPIO_EMC_23 (coord G2), SEMC_A10 */ +/* Routed pin properties */ +#define BOARD_INITSDRAM_SEMC_A10_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAM_SEMC_A10_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAM_SEMC_A10_CHANNEL 10U /*!< Signal channel */ + +/* GPIO_EMC_19 (coord B4), SEMC_A11 */ +/* Routed pin properties */ +#define BOARD_INITSDRAM_SEMC_A11_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAM_SEMC_A11_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAM_SEMC_A11_CHANNEL 11U /*!< Signal channel */ + +/* GPIO_EMC_20 (coord A3), SEMC_A12 */ +/* Routed pin properties */ +#define BOARD_INITSDRAM_SEMC_A12_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAM_SEMC_A12_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAM_SEMC_A12_CHANNEL 12U /*!< Signal channel */ + +/* GPIO_EMC_21 (coord C1), SEMC_BA0 */ +/* Routed pin properties */ +#define BOARD_INITSDRAM_SEMC_BA0_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAM_SEMC_BA0_SIGNAL BA /*!< Signal name */ +#define BOARD_INITSDRAM_SEMC_BA0_CHANNEL 0U /*!< Signal channel */ + +/* GPIO_EMC_22 (coord F1), SEMC_BA1 */ +/* Routed pin properties */ +#define BOARD_INITSDRAM_SEMC_BA1_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAM_SEMC_BA1_SIGNAL BA /*!< Signal name */ +#define BOARD_INITSDRAM_SEMC_BA1_CHANNEL 1U /*!< Signal channel */ + +/* GPIO_EMC_24 (coord D3), SEMC_CAS */ +/* Routed pin properties */ +#define BOARD_INITSDRAM_SEMC_CAS_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAM_SEMC_CAS_SIGNAL semc_cas /*!< Signal name */ + +/* GPIO_EMC_27 (coord A2), SEMC_CKE */ +/* Routed pin properties */ +#define BOARD_INITSDRAM_SEMC_CKE_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAM_SEMC_CKE_SIGNAL semc_cke /*!< Signal name */ + +/* GPIO_EMC_26 (coord B3), SEMC_CLK */ +/* Routed pin properties */ +#define BOARD_INITSDRAM_SEMC_CLK_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAM_SEMC_CLK_SIGNAL semc_clk /*!< Signal name */ + +/* GPIO_EMC_00 (coord E3), SEMC_D0 */ +/* Routed pin properties */ +#define BOARD_INITSDRAM_SEMC_D0_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAM_SEMC_D0_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAM_SEMC_D0_CHANNEL 0U /*!< Signal channel */ + +/* GPIO_EMC_01 (coord F3), SEMC_D1 */ +/* Routed pin properties */ +#define BOARD_INITSDRAM_SEMC_D1_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAM_SEMC_D1_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAM_SEMC_D1_CHANNEL 1U /*!< Signal channel */ + +/* GPIO_EMC_02 (coord F4), SEMC_D2 */ +/* Routed pin properties */ +#define BOARD_INITSDRAM_SEMC_D2_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAM_SEMC_D2_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAM_SEMC_D2_CHANNEL 2U /*!< Signal channel */ + +/* GPIO_EMC_03 (coord G4), SEMC_D3 */ +/* Routed pin properties */ +#define BOARD_INITSDRAM_SEMC_D3_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAM_SEMC_D3_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAM_SEMC_D3_CHANNEL 3U /*!< Signal channel */ + +/* GPIO_EMC_04 (coord F2), SEMC_D4 */ +/* Routed pin properties */ +#define BOARD_INITSDRAM_SEMC_D4_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAM_SEMC_D4_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAM_SEMC_D4_CHANNEL 4U /*!< Signal channel */ + +/* GPIO_EMC_05 (coord G5), SEMC_D5 */ +/* Routed pin properties */ +#define BOARD_INITSDRAM_SEMC_D5_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAM_SEMC_D5_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAM_SEMC_D5_CHANNEL 5U /*!< Signal channel */ + +/* GPIO_EMC_06 (coord H5), SEMC_D6 */ +/* Routed pin properties */ +#define BOARD_INITSDRAM_SEMC_D6_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAM_SEMC_D6_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAM_SEMC_D6_CHANNEL 6U /*!< Signal channel */ + +/* GPIO_EMC_07 (coord H4), SEMC_D7 */ +/* Routed pin properties */ +#define BOARD_INITSDRAM_SEMC_D7_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAM_SEMC_D7_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAM_SEMC_D7_CHANNEL 7U /*!< Signal channel */ + +/* GPIO_EMC_30 (coord C6), SEMC_D8 */ +/* Routed pin properties */ +#define BOARD_INITSDRAM_SEMC_D8_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAM_SEMC_D8_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAM_SEMC_D8_CHANNEL 8U /*!< Signal channel */ + +/* GPIO_EMC_31 (coord C5), SEMC_D9 */ +/* Routed pin properties */ +#define BOARD_INITSDRAM_SEMC_D9_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAM_SEMC_D9_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAM_SEMC_D9_CHANNEL 9U /*!< Signal channel */ + +/* GPIO_EMC_32 (coord D5), SEMC_D10 */ +/* Routed pin properties */ +#define BOARD_INITSDRAM_SEMC_D10_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAM_SEMC_D10_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAM_SEMC_D10_CHANNEL 10U /*!< Signal channel */ + +/* GPIO_EMC_33 (coord C4), SEMC_D11 */ +/* Routed pin properties */ +#define BOARD_INITSDRAM_SEMC_D11_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAM_SEMC_D11_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAM_SEMC_D11_CHANNEL 11U /*!< Signal channel */ + +/* GPIO_EMC_34 (coord D4), SEMC_D12 */ +/* Routed pin properties */ +#define BOARD_INITSDRAM_SEMC_D12_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAM_SEMC_D12_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAM_SEMC_D12_CHANNEL 12U /*!< Signal channel */ + +/* GPIO_EMC_35 (coord E5), SEMC_D13 */ +/* Routed pin properties */ +#define BOARD_INITSDRAM_SEMC_D13_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAM_SEMC_D13_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAM_SEMC_D13_CHANNEL 13U /*!< Signal channel */ + +/* GPIO_EMC_36 (coord C3), SEMC_D14 */ +/* Routed pin properties */ +#define BOARD_INITSDRAM_SEMC_D14_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAM_SEMC_D14_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAM_SEMC_D14_CHANNEL 14U /*!< Signal channel */ + +/* GPIO_EMC_37 (coord E4), SEMC_D15 */ +/* Routed pin properties */ +#define BOARD_INITSDRAM_SEMC_D15_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAM_SEMC_D15_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAM_SEMC_D15_CHANNEL 15U /*!< Signal channel */ + +/* GPIO_EMC_08 (coord H3), SEMC_DM0 */ +/* Routed pin properties */ +#define BOARD_INITSDRAM_SEMC_DM0_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAM_SEMC_DM0_SIGNAL DM /*!< Signal name */ +#define BOARD_INITSDRAM_SEMC_DM0_CHANNEL 0U /*!< Signal channel */ + +/* GPIO_EMC_38 (coord D6), SEMC_DM1 */ +/* Routed pin properties */ +#define BOARD_INITSDRAM_SEMC_DM1_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAM_SEMC_DM1_SIGNAL DM /*!< Signal name */ +#define BOARD_INITSDRAM_SEMC_DM1_CHANNEL 1U /*!< Signal channel */ + +/* GPIO_EMC_25 (coord D2), SEMC_RAS */ +/* Routed pin properties */ +#define BOARD_INITSDRAM_SEMC_RAS_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAM_SEMC_RAS_SIGNAL semc_ras /*!< Signal name */ + +/* GPIO_EMC_28 (coord D1), SEMC_WE */ +/* Routed pin properties */ +#define BOARD_INITSDRAM_SEMC_WE_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAM_SEMC_WE_SIGNAL semc_we /*!< Signal name */ + +/* GPIO_EMC_41 (coord C7), ENET_MDIO */ +/* Routed pin properties */ +#define BOARD_INITSDRAM_ENET_MDIO_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAM_ENET_MDIO_SIGNAL CSX /*!< Signal name */ +#define BOARD_INITSDRAM_ENET_MDIO_CHANNEL 0U /*!< Signal channel */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitSDRAM(void); + +#define BOARD_INITCSI_IOMUXC_GPR_GPR26_GPIO_MUX1_GPIO_SEL_MASK 0x10U /*!< GPIO1 and GPIO6 share same IO MUX function, GPIO_MUX1 selects one GPIO function: affected bits mask */ + +/* GPIO_AD_B1_08 (coord H13), AUD_INT/CSI_D9//J35[13]/J22[4] */ +/* Routed pin properties */ +#define BOARD_INITCSI_CSI_D9_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSI_CSI_D9_SIGNAL csi_data /*!< Signal name */ +#define BOARD_INITCSI_CSI_D9_CHANNEL 9U /*!< Signal channel */ + +/* GPIO_AD_B1_09 (coord M13), SAI1_MCLK/CSI_D8/J35[11] */ +/* Routed pin properties */ +#define BOARD_INITCSI_CSI_D8_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSI_CSI_D8_SIGNAL csi_data /*!< Signal name */ +#define BOARD_INITCSI_CSI_D8_CHANNEL 8U /*!< Signal channel */ + +/* GPIO_AD_B1_10 (coord L13), SAI1_RX_SYNC/CSI_D7/J35[9]/J23[1] */ +/* Routed pin properties */ +#define BOARD_INITCSI_CSI_D7_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSI_CSI_D7_SIGNAL csi_data /*!< Signal name */ +#define BOARD_INITCSI_CSI_D7_CHANNEL 7U /*!< Signal channel */ + +/* GPIO_AD_B1_11 (coord J13), SAI1_RX_BCLK/CSI_D6/J35[7]/J23[2] */ +/* Routed pin properties */ +#define BOARD_INITCSI_CSI_D6_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSI_CSI_D6_SIGNAL csi_data /*!< Signal name */ +#define BOARD_INITCSI_CSI_D6_CHANNEL 6U /*!< Signal channel */ + +/* GPIO_AD_B1_12 (coord H12), SAI1_RXD/CSI_D5/J35[5]/U13[16] */ +/* Routed pin properties */ +#define BOARD_INITCSI_CSI_D5_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSI_CSI_D5_SIGNAL csi_data /*!< Signal name */ +#define BOARD_INITCSI_CSI_D5_CHANNEL 5U /*!< Signal channel */ + +/* GPIO_AD_B1_13 (coord H11), SAI1_TXD/CSI_D4/J35[3]/U13[14] */ +/* Routed pin properties */ +#define BOARD_INITCSI_CSI_D4_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSI_CSI_D4_SIGNAL csi_data /*!< Signal name */ +#define BOARD_INITCSI_CSI_D4_CHANNEL 4U /*!< Signal channel */ + +/* GPIO_AD_B1_15 (coord J14), SAI1_TX_SYNC/CSI_D2/J35[6]/U13[13] */ +/* Routed pin properties */ +#define BOARD_INITCSI_CSI_D2_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSI_CSI_D2_SIGNAL csi_data /*!< Signal name */ +#define BOARD_INITCSI_CSI_D2_CHANNEL 2U /*!< Signal channel */ + +/* GPIO_AD_B1_14 (coord G12), SAI1_TX_BCLK/CSI_D3/J35[4]/U13[12] */ +/* Routed pin properties */ +#define BOARD_INITCSI_CSI_D3_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSI_CSI_D3_SIGNAL csi_data /*!< Signal name */ +#define BOARD_INITCSI_CSI_D3_CHANNEL 3U /*!< Signal channel */ + +/* GPIO_AD_B1_04 (coord L12), CSI_PIXCLK/J35[8]/J23[3] */ +/* Routed pin properties */ +#define BOARD_INITCSI_CSI_PIXCLK_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSI_CSI_PIXCLK_SIGNAL csi_pixclk /*!< Signal name */ + +/* GPIO_AD_B1_05 (coord K12), CSI_MCLK/J35[12]/J23[4] */ +/* Routed pin properties */ +#define BOARD_INITCSI_CSI_MCLK_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSI_CSI_MCLK_SIGNAL csi_mclk /*!< Signal name */ + +/* GPIO_AD_B1_06 (coord J12), CSI_VSYNC/J35[18]/J22[2]/UART_TX */ +/* Routed pin properties */ +#define BOARD_INITCSI_CSI_VSYNC_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSI_CSI_VSYNC_SIGNAL csi_vsync /*!< Signal name */ + +/* GPIO_AD_B1_07 (coord K10), CSI_HSYNC/J35[16]/J22[1]/UART_RX */ +/* Routed pin properties */ +#define BOARD_INITCSI_CSI_HSYNC_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSI_CSI_HSYNC_SIGNAL csi_hsync /*!< Signal name */ + +/* GPIO_AD_B1_00 (coord J11), I2C1_SCL/CSI_I2C_SCL/J35[20]/J23[6]/U13[17]/U32[4] */ +/* Routed pin properties */ +#define BOARD_INITCSI_CSI_I2C_SCL_PERIPHERAL LPI2C1 /*!< Peripheral name */ +#define BOARD_INITCSI_CSI_I2C_SCL_SIGNAL SCL /*!< Signal name */ + +/* GPIO_AD_B1_01 (coord K11), I2C1_SDA/CSI_I2C_SDA/J35[22]/J23[5]/U13[18]/U32[6] */ +/* Routed pin properties */ +#define BOARD_INITCSI_CSI_I2C_SDA_PERIPHERAL LPI2C1 /*!< Peripheral name */ +#define BOARD_INITCSI_CSI_I2C_SDA_SIGNAL SDA /*!< Signal name */ + +/* GPIO_AD_B0_04 (coord F11), CSI_PWDN/J35[17]/BOOT_MODE[0] */ +/* Routed pin properties */ +#define BOARD_INITCSI_CSI_PWDN_PERIPHERAL GPIO1 /*!< Peripheral name */ +#define BOARD_INITCSI_CSI_PWDN_SIGNAL gpio_io /*!< Signal name */ +#define BOARD_INITCSI_CSI_PWDN_CHANNEL 4U /*!< Signal channel */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITCSI_CSI_PWDN_GPIO GPIO1 /*!< GPIO peripheral base pointer */ +#define BOARD_INITCSI_CSI_PWDN_GPIO_PIN 4U /*!< GPIO pin number */ +#define BOARD_INITCSI_CSI_PWDN_GPIO_PIN_MASK (1U << 4U) /*!< GPIO pin mask */ +#define BOARD_INITCSI_CSI_PWDN_PORT GPIO1 /*!< PORT peripheral base pointer */ +#define BOARD_INITCSI_CSI_PWDN_PIN 4U /*!< PORT pin number */ +#define BOARD_INITCSI_CSI_PWDN_PIN_MASK (1U << 4U) /*!< PORT pin mask */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitCSI(void); + +#define BOARD_INITLCD_IOMUXC_GPR_GPR27_GPIO_MUX2_GPIO_SEL_MASK 0x80000000U /*!< GPIO2 and GPIO7 share same IO MUX function, GPIO_MUX2 selects one GPIO function: affected bits mask */ + +/* GPIO_B0_04 (coord C8), LCDIF_D0/BT_CFG[0] */ +/* Routed pin properties */ +#define BOARD_INITLCD_LCDIF_D0_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCD_LCDIF_D0_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCD_LCDIF_D0_CHANNEL 0U /*!< Signal channel */ + +/* GPIO_B0_05 (coord B8), LCDIF_D1/BT_CFG[1] */ +/* Routed pin properties */ +#define BOARD_INITLCD_LCDIF_D1_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCD_LCDIF_D1_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCD_LCDIF_D1_CHANNEL 1U /*!< Signal channel */ + +/* GPIO_B0_06 (coord A8), LCDIF_D2/BT_CFG[2] */ +/* Routed pin properties */ +#define BOARD_INITLCD_LCDIF_D2_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCD_LCDIF_D2_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCD_LCDIF_D2_CHANNEL 2U /*!< Signal channel */ + +/* GPIO_B0_00 (coord D7), LCDIF_CLK */ +/* Routed pin properties */ +#define BOARD_INITLCD_LCDIF_CLK_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCD_LCDIF_CLK_SIGNAL lcdif_clk /*!< Signal name */ + +/* GPIO_B0_07 (coord A9), LCDIF_D3/BT_CFG[3] */ +/* Routed pin properties */ +#define BOARD_INITLCD_LCDIF_D3_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCD_LCDIF_D3_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCD_LCDIF_D3_CHANNEL 3U /*!< Signal channel */ + +/* GPIO_B0_08 (coord B9), LCDIF_D4/BT_CFG[4] */ +/* Routed pin properties */ +#define BOARD_INITLCD_LCDIF_D4_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCD_LCDIF_D4_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCD_LCDIF_D4_CHANNEL 4U /*!< Signal channel */ + +/* GPIO_B0_09 (coord C9), LCDIF_D5/BT_CFG[5] */ +/* Routed pin properties */ +#define BOARD_INITLCD_LCDIF_D5_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCD_LCDIF_D5_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCD_LCDIF_D5_CHANNEL 5U /*!< Signal channel */ + +/* GPIO_B0_10 (coord D9), LCDIF_D6/BT_CFG[6] */ +/* Routed pin properties */ +#define BOARD_INITLCD_LCDIF_D6_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCD_LCDIF_D6_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCD_LCDIF_D6_CHANNEL 6U /*!< Signal channel */ + +/* GPIO_B0_11 (coord A10), LCDIF_D7/BT_CFG[7] */ +/* Routed pin properties */ +#define BOARD_INITLCD_LCDIF_D7_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCD_LCDIF_D7_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCD_LCDIF_D7_CHANNEL 7U /*!< Signal channel */ + +/* GPIO_B0_12 (coord C10), LCDIF_D8/BT_CFG[8] */ +/* Routed pin properties */ +#define BOARD_INITLCD_LCDIF_D8_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCD_LCDIF_D8_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCD_LCDIF_D8_CHANNEL 8U /*!< Signal channel */ + +/* GPIO_B0_13 (coord D10), LCDIF_D9/BT_CFG[9] */ +/* Routed pin properties */ +#define BOARD_INITLCD_LCDIF_D9_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCD_LCDIF_D9_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCD_LCDIF_D9_CHANNEL 9U /*!< Signal channel */ + +/* GPIO_B0_14 (coord E10), LCDIF_D10/BT_CFG[10] */ +/* Routed pin properties */ +#define BOARD_INITLCD_LCDIF_D10_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCD_LCDIF_D10_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCD_LCDIF_D10_CHANNEL 10U /*!< Signal channel */ + +/* GPIO_B0_15 (coord E11), LCDIF_D11/BT_CFG[11] */ +/* Routed pin properties */ +#define BOARD_INITLCD_LCDIF_D11_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCD_LCDIF_D11_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCD_LCDIF_D11_CHANNEL 11U /*!< Signal channel */ + +/* GPIO_B1_00 (coord A11), LCDIF_D12 */ +/* Routed pin properties */ +#define BOARD_INITLCD_LCDIF_D12_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCD_LCDIF_D12_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCD_LCDIF_D12_CHANNEL 12U /*!< Signal channel */ + +/* GPIO_B1_01 (coord B11), LCDIF_D13 */ +/* Routed pin properties */ +#define BOARD_INITLCD_LCDIF_D13_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCD_LCDIF_D13_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCD_LCDIF_D13_CHANNEL 13U /*!< Signal channel */ + +/* GPIO_B1_02 (coord C11), LCDIF_D14 */ +/* Routed pin properties */ +#define BOARD_INITLCD_LCDIF_D14_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCD_LCDIF_D14_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCD_LCDIF_D14_CHANNEL 14U /*!< Signal channel */ + +/* GPIO_B1_03 (coord D11), LCDIF_D15 */ +/* Routed pin properties */ +#define BOARD_INITLCD_LCDIF_D15_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCD_LCDIF_D15_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCD_LCDIF_D15_CHANNEL 15U /*!< Signal channel */ + +/* GPIO_B0_01 (coord E7), LCDIF_ENABLE */ +/* Routed pin properties */ +#define BOARD_INITLCD_LCDIF_ENABLE_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCD_LCDIF_ENABLE_SIGNAL lcdif_enable /*!< Signal name */ + +/* GPIO_B0_02 (coord E8), LCDIF_HSYNC */ +/* Routed pin properties */ +#define BOARD_INITLCD_LCDIF_HSYNC_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCD_LCDIF_HSYNC_SIGNAL lcdif_hsync /*!< Signal name */ + +/* GPIO_B0_03 (coord D8), LCDIF_VSYNC */ +/* Routed pin properties */ +#define BOARD_INITLCD_LCDIF_VSYNC_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCD_LCDIF_VSYNC_SIGNAL lcdif_vsync /*!< Signal name */ + +/* GPIO_B1_15 (coord B14), USB_HOST_PWR/BACKLIGHT_CTL */ +/* Routed pin properties */ +#define BOARD_INITLCD_BACKLIGHT_CTL_PERIPHERAL GPIO2 /*!< Peripheral name */ +#define BOARD_INITLCD_BACKLIGHT_CTL_SIGNAL gpio_io /*!< Signal name */ +#define BOARD_INITLCD_BACKLIGHT_CTL_CHANNEL 31U /*!< Signal channel */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITLCD_BACKLIGHT_CTL_GPIO GPIO2 /*!< GPIO peripheral base pointer */ +#define BOARD_INITLCD_BACKLIGHT_CTL_GPIO_PIN 31U /*!< GPIO pin number */ +#define BOARD_INITLCD_BACKLIGHT_CTL_GPIO_PIN_MASK (1U << 31U) /*!< GPIO pin mask */ +#define BOARD_INITLCD_BACKLIGHT_CTL_PORT GPIO2 /*!< PORT peripheral base pointer */ +#define BOARD_INITLCD_BACKLIGHT_CTL_PIN 31U /*!< PORT pin number */ +#define BOARD_INITLCD_BACKLIGHT_CTL_PIN_MASK (1U << 31U) /*!< PORT pin mask */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitLCD(void); + +/* GPIO_AD_B0_14 (coord H14), CAN2_TX/U12[1] */ +/* Routed pin properties */ +#define BOARD_INITCAN_CAN2_TX_PERIPHERAL CAN2 /*!< Peripheral name */ +#define BOARD_INITCAN_CAN2_TX_SIGNAL TX /*!< Signal name */ + +/* GPIO_AD_B0_15 (coord L10), CAN2_RX/U12[4] */ +/* Routed pin properties */ +#define BOARD_INITCAN_CAN2_RX_PERIPHERAL CAN2 /*!< Peripheral name */ +#define BOARD_INITCAN_CAN2_RX_SIGNAL RX /*!< Signal name */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitCAN(void); + +/* GPIO_EMC_40 (coord A7), ENET_MDC */ +/* Routed pin properties */ +#define BOARD_INITENET_ENET_MDC_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENET_ENET_MDC_SIGNAL enet_mdc /*!< Signal name */ + +/* GPIO_EMC_41 (coord C7), ENET_MDIO */ +/* Routed pin properties */ +#define BOARD_INITENET_ENET_MDIO_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENET_ENET_MDIO_SIGNAL enet_mdio /*!< Signal name */ + +/* GPIO_B1_10 (coord B13), ENET_TX_CLK */ +/* Routed pin properties */ +#define BOARD_INITENET_ENET_TX_CLK_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENET_ENET_TX_CLK_SIGNAL enet_ref_clk /*!< Signal name */ + +/* GPIO_B1_04 (coord E12), ENET_RXD0 */ +/* Routed pin properties */ +#define BOARD_INITENET_ENET_RXD0_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENET_ENET_RXD0_SIGNAL enet_rx_data /*!< Signal name */ +#define BOARD_INITENET_ENET_RXD0_CHANNEL 0U /*!< Signal channel */ + +/* GPIO_B1_05 (coord D12), ENET_RXD1 */ +/* Routed pin properties */ +#define BOARD_INITENET_ENET_RXD1_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENET_ENET_RXD1_SIGNAL enet_rx_data /*!< Signal name */ +#define BOARD_INITENET_ENET_RXD1_CHANNEL 1U /*!< Signal channel */ + +/* GPIO_B1_06 (coord C12), ENET_CRS_DV */ +/* Routed pin properties */ +#define BOARD_INITENET_ENET_CRS_DV_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENET_ENET_CRS_DV_SIGNAL enet_rx_en /*!< Signal name */ + +/* GPIO_B1_11 (coord C13), ENET_RXER */ +/* Routed pin properties */ +#define BOARD_INITENET_ENET_RXER_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENET_ENET_RXER_SIGNAL enet_rx_er /*!< Signal name */ + +/* GPIO_B1_07 (coord B12), ENET_TXD0 */ +/* Routed pin properties */ +#define BOARD_INITENET_ENET_TXD0_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENET_ENET_TXD0_SIGNAL enet_tx_data /*!< Signal name */ +#define BOARD_INITENET_ENET_TXD0_CHANNEL 0U /*!< Signal channel */ + +/* GPIO_B1_08 (coord A12), ENET_TXD1 */ +/* Routed pin properties */ +#define BOARD_INITENET_ENET_TXD1_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENET_ENET_TXD1_SIGNAL enet_tx_data /*!< Signal name */ +#define BOARD_INITENET_ENET_TXD1_CHANNEL 1U /*!< Signal channel */ + +/* GPIO_B1_09 (coord A13), ENET_TXEN */ +/* Routed pin properties */ +#define BOARD_INITENET_ENET_TXEN_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENET_ENET_TXEN_SIGNAL enet_tx_en /*!< Signal name */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitENET(void); + +/* GPIO_SD_B0_05 (coord J2), SD1_D3 */ +/* Routed pin properties */ +#define BOARD_INITUSDHC_SD1_D3_PERIPHERAL USDHC1 /*!< Peripheral name */ +#define BOARD_INITUSDHC_SD1_D3_SIGNAL usdhc_data /*!< Signal name */ +#define BOARD_INITUSDHC_SD1_D3_CHANNEL 3U /*!< Signal channel */ + +/* GPIO_SD_B0_04 (coord H2), SD1_D2 */ +/* Routed pin properties */ +#define BOARD_INITUSDHC_SD1_D2_PERIPHERAL USDHC1 /*!< Peripheral name */ +#define BOARD_INITUSDHC_SD1_D2_SIGNAL usdhc_data /*!< Signal name */ +#define BOARD_INITUSDHC_SD1_D2_CHANNEL 2U /*!< Signal channel */ + +/* GPIO_SD_B0_03 (coord K1), SD1_D1/J24[5]/SPI_MISO */ +/* Routed pin properties */ +#define BOARD_INITUSDHC_SD1_D1_PERIPHERAL USDHC1 /*!< Peripheral name */ +#define BOARD_INITUSDHC_SD1_D1_SIGNAL usdhc_data /*!< Signal name */ +#define BOARD_INITUSDHC_SD1_D1_CHANNEL 1U /*!< Signal channel */ + +/* GPIO_SD_B0_02 (coord J1), SD1_D0/J24[4]/SPI_MOSI/PWM */ +/* Routed pin properties */ +#define BOARD_INITUSDHC_SD1_D0_PERIPHERAL USDHC1 /*!< Peripheral name */ +#define BOARD_INITUSDHC_SD1_D0_SIGNAL usdhc_data /*!< Signal name */ +#define BOARD_INITUSDHC_SD1_D0_CHANNEL 0U /*!< Signal channel */ + +/* GPIO_SD_B0_00 (coord J4), SD1_CMD/J24[6] */ +/* Routed pin properties */ +#define BOARD_INITUSDHC_SD1_CMD_PERIPHERAL USDHC1 /*!< Peripheral name */ +#define BOARD_INITUSDHC_SD1_CMD_SIGNAL usdhc_cmd /*!< Signal name */ + +/* GPIO_SD_B0_01 (coord J3), SD1_CLK/J24[3] */ +/* Routed pin properties */ +#define BOARD_INITUSDHC_SD1_CLK_PERIPHERAL USDHC1 /*!< Peripheral name */ +#define BOARD_INITUSDHC_SD1_CLK_SIGNAL usdhc_clk /*!< Signal name */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitUSDHC(void); + +/* GPIO_SD_B1_07 (coord L4), FlexSPI_CLK */ +/* Routed pin properties */ +#define BOARD_INITHYPERFLASH_FlexSPI_CLK_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITHYPERFLASH_FlexSPI_CLK_SIGNAL FLEXSPI_A_SCLK /*!< Signal name */ + +/* GPIO_SD_B1_10 (coord P4), FlexSPI_D2_A */ +/* Routed pin properties */ +#define BOARD_INITHYPERFLASH_FlexSPI_D2_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITHYPERFLASH_FlexSPI_D2_A_SIGNAL FLEXSPI_A_DATA2 /*!< Signal name */ + +/* GPIO_SD_B1_08 (coord P3), FlexSPI_D0_A */ +/* Routed pin properties */ +#define BOARD_INITHYPERFLASH_FlexSPI_D0_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITHYPERFLASH_FlexSPI_D0_A_SIGNAL FLEXSPI_A_DATA0 /*!< Signal name */ + +/* GPIO_SD_B1_09 (coord N4), FlexSPI_D1_A */ +/* Routed pin properties */ +#define BOARD_INITHYPERFLASH_FlexSPI_D1_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITHYPERFLASH_FlexSPI_D1_A_SIGNAL FLEXSPI_A_DATA1 /*!< Signal name */ + +/* GPIO_SD_B1_00 (coord L5), FlexSPI_D3_B */ +/* Routed pin properties */ +#define BOARD_INITHYPERFLASH_FlexSPI_D3_B_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITHYPERFLASH_FlexSPI_D3_B_SIGNAL FLEXSPI_B_DATA3 /*!< Signal name */ + +/* GPIO_SD_B1_01 (coord M5), FlexSPI_D2_B */ +/* Routed pin properties */ +#define BOARD_INITHYPERFLASH_FlexSPI_D2_B_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITHYPERFLASH_FlexSPI_D2_B_SIGNAL FLEXSPI_B_DATA2 /*!< Signal name */ + +/* GPIO_SD_B1_02 (coord M3), FlexSPI_D1_B */ +/* Routed pin properties */ +#define BOARD_INITHYPERFLASH_FlexSPI_D1_B_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITHYPERFLASH_FlexSPI_D1_B_SIGNAL FLEXSPI_B_DATA1 /*!< Signal name */ + +/* GPIO_SD_B1_03 (coord M4), FlexSPI_D0_B */ +/* Routed pin properties */ +#define BOARD_INITHYPERFLASH_FlexSPI_D0_B_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITHYPERFLASH_FlexSPI_D0_B_SIGNAL FLEXSPI_B_DATA0 /*!< Signal name */ + +/* GPIO_SD_B1_04 (coord P2), FlexSPI_CLK_B */ +/* Routed pin properties */ +#define BOARD_INITHYPERFLASH_FlexSPI_CLK_B_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITHYPERFLASH_FlexSPI_CLK_B_SIGNAL FLEXSPI_B_SCLK /*!< Signal name */ + +/* GPIO_SD_B1_06 (coord L3), FlexSPI_SS0 */ +/* Routed pin properties */ +#define BOARD_INITHYPERFLASH_FlexSPI_SS0_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITHYPERFLASH_FlexSPI_SS0_SIGNAL FLEXSPI_A_SS0_B /*!< Signal name */ + +/* GPIO_SD_B1_11 (coord P5), FlexSPI_D3_A */ +/* Routed pin properties */ +#define BOARD_INITHYPERFLASH_FlexSPI_D3_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITHYPERFLASH_FlexSPI_D3_A_SIGNAL FLEXSPI_A_DATA3 /*!< Signal name */ + +/* GPIO_SD_B1_05 (coord N3), FlexSPI_DQS */ +/* Routed pin properties */ +#define BOARD_INITHYPERFLASH_FlexSPI_DQS_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITHYPERFLASH_FlexSPI_DQS_SIGNAL FLEXSPI_A_DQS /*!< Signal name */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitHyperFlash(void); + +/* GPIO_AD_B1_06 (coord J12), CSI_VSYNC/J35[18]/J22[2]/UART_TX */ +/* Routed pin properties */ +#define BOARD_INITARDUINO_UART_CSI_VSYNC_PERIPHERAL LPUART3 /*!< Peripheral name */ +#define BOARD_INITARDUINO_UART_CSI_VSYNC_SIGNAL TX /*!< Signal name */ + +/* GPIO_AD_B1_07 (coord K10), CSI_HSYNC/J35[16]/J22[1]/UART_RX */ +/* Routed pin properties */ +#define BOARD_INITARDUINO_UART_CSI_HSYNC_PERIPHERAL LPUART3 /*!< Peripheral name */ +#define BOARD_INITARDUINO_UART_CSI_HSYNC_SIGNAL RX /*!< Signal name */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitARDUINO_UART(void); + +#define BOARD_INITUSER_LED_IOMUXC_GPR_GPR26_GPIO_MUX1_GPIO_SEL_MASK 0x0200U /*!< GPIO1 and GPIO6 share same IO MUX function, GPIO_MUX1 selects one GPIO function: affected bits mask */ + +/* GPIO_AD_B0_09 (coord F14), JTAG_TDI/J21[5]/ENET_RST/J22[5] */ +/* Routed pin properties */ +#define BOARD_INITUSER_LED_USER_LED_PERIPHERAL GPIO1 /*!< Peripheral name */ +#define BOARD_INITUSER_LED_USER_LED_SIGNAL gpio_io /*!< Signal name */ +#define BOARD_INITUSER_LED_USER_LED_CHANNEL 9U /*!< Signal channel */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITUSER_LED_USER_LED_GPIO GPIO1 /*!< GPIO peripheral base pointer */ +#define BOARD_INITUSER_LED_USER_LED_GPIO_PIN 9U /*!< GPIO pin number */ +#define BOARD_INITUSER_LED_USER_LED_GPIO_PIN_MASK (1U << 9U) /*!< GPIO pin mask */ +#define BOARD_INITUSER_LED_USER_LED_PORT GPIO1 /*!< PORT peripheral base pointer */ +#define BOARD_INITUSER_LED_USER_LED_PIN 9U /*!< PORT pin number */ +#define BOARD_INITUSER_LED_USER_LED_PIN_MASK (1U << 9U) /*!< PORT pin mask */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitUSER_LED(void); + +/* WAKEUP (coord L6), SD_PWREN */ +/* Routed pin properties */ +#define BOARD_INITUSER_BUTTON_USER_BUTTON_PERIPHERAL GPIO5 /*!< Peripheral name */ +#define BOARD_INITUSER_BUTTON_USER_BUTTON_SIGNAL gpio_io /*!< Signal name */ +#define BOARD_INITUSER_BUTTON_USER_BUTTON_CHANNEL 0U /*!< Signal channel */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITUSER_BUTTON_USER_BUTTON_GPIO GPIO5 /*!< GPIO peripheral base pointer */ +#define BOARD_INITUSER_BUTTON_USER_BUTTON_GPIO_PIN 0U /*!< GPIO pin number */ +#define BOARD_INITUSER_BUTTON_USER_BUTTON_GPIO_PIN_MASK (1U << 0U) /*!< GPIO pin mask */ +#define BOARD_INITUSER_BUTTON_USER_BUTTON_PORT GPIO5 /*!< PORT peripheral base pointer */ +#define BOARD_INITUSER_BUTTON_USER_BUTTON_PIN 0U /*!< PORT pin number */ +#define BOARD_INITUSER_BUTTON_USER_BUTTON_PIN_MASK (1U << 0U) /*!< PORT pin mask */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitUSER_BUTTON(void); + +#define BOARD_INITAUDIO_IOMUXC_GPR_GPR26_GPIO_MUX1_GPIO_SEL_MASK 0x01000000U /*!< GPIO1 and GPIO6 share same IO MUX function, GPIO_MUX1 selects one GPIO function: affected bits mask */ + +/* GPIO_AD_B1_08 (coord H13), AUD_INT/CSI_D9//J35[13]/J22[4] */ +/* Routed pin properties */ +#define BOARD_INITAUDIO_CSI_D9_PERIPHERAL GPIO1 /*!< Peripheral name */ +#define BOARD_INITAUDIO_CSI_D9_SIGNAL gpio_io /*!< Signal name */ +#define BOARD_INITAUDIO_CSI_D9_CHANNEL 24U /*!< Signal channel */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITAUDIO_CSI_D9_GPIO GPIO1 /*!< GPIO peripheral base pointer */ +#define BOARD_INITAUDIO_CSI_D9_GPIO_PIN 24U /*!< GPIO pin number */ +#define BOARD_INITAUDIO_CSI_D9_GPIO_PIN_MASK (1U << 24U) /*!< GPIO pin mask */ +#define BOARD_INITAUDIO_CSI_D9_PORT GPIO1 /*!< PORT peripheral base pointer */ +#define BOARD_INITAUDIO_CSI_D9_PIN 24U /*!< PORT pin number */ +#define BOARD_INITAUDIO_CSI_D9_PIN_MASK (1U << 24U) /*!< PORT pin mask */ + +/* GPIO_AD_B1_09 (coord M13), SAI1_MCLK/CSI_D8/J35[11] */ +/* Routed pin properties */ +#define BOARD_INITAUDIO_CSI_D8_PERIPHERAL SAI1 /*!< Peripheral name */ +#define BOARD_INITAUDIO_CSI_D8_SIGNAL sai_mclk /*!< Signal name */ + +/* GPIO_AD_B1_12 (coord H12), SAI1_RXD/CSI_D5/J35[5]/U13[16] */ +/* Routed pin properties */ +#define BOARD_INITAUDIO_CSI_D5_PERIPHERAL SAI1 /*!< Peripheral name */ +#define BOARD_INITAUDIO_CSI_D5_SIGNAL sai_rx_data0 /*!< Signal name */ + +/* GPIO_AD_B1_13 (coord H11), SAI1_TXD/CSI_D4/J35[3]/U13[14] */ +/* Routed pin properties */ +#define BOARD_INITAUDIO_CSI_D4_PERIPHERAL SAI1 /*!< Peripheral name */ +#define BOARD_INITAUDIO_CSI_D4_SIGNAL sai_tx_data0 /*!< Signal name */ + +/* GPIO_AD_B1_14 (coord G12), SAI1_TX_BCLK/CSI_D3/J35[4]/U13[12] */ +/* Routed pin properties */ +#define BOARD_INITAUDIO_CSI_D3_PERIPHERAL SAI1 /*!< Peripheral name */ +#define BOARD_INITAUDIO_CSI_D3_SIGNAL sai_tx_bclk /*!< Signal name */ + +/* GPIO_AD_B1_15 (coord J14), SAI1_TX_SYNC/CSI_D2/J35[6]/U13[13] */ +/* Routed pin properties */ +#define BOARD_INITAUDIO_CSI_D2_PERIPHERAL SAI1 /*!< Peripheral name */ +#define BOARD_INITAUDIO_CSI_D2_SIGNAL sai_tx_sync /*!< Signal name */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitAudio(void); + +#if defined(__cplusplus) +} +#endif + +/*! + * @} + */ +#endif /* _PIN_MUX_H_ */ + +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ diff --git a/Platform_MIMXRT1064-EVK/RTE/CMSIS/RTX_Config.c b/Platform_MIMXRT1064-EVK/RTE/CMSIS/RTX_Config.c new file mode 100644 index 0000000..737078a --- /dev/null +++ b/Platform_MIMXRT1064-EVK/RTE/CMSIS/RTX_Config.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2013-2021 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ----------------------------------------------------------------------------- + * + * $Revision: V5.1.1 + * + * Project: CMSIS-RTOS RTX + * Title: RTX Configuration + * + * ----------------------------------------------------------------------------- + */ + +#include "cmsis_compiler.h" +#include "rtx_os.h" + +// OS Idle Thread +__WEAK __NO_RETURN void osRtxIdleThread (void *argument) { + (void)argument; + + for (;;) {} +} + +// OS Error Callback function +__WEAK uint32_t osRtxErrorNotify (uint32_t code, void *object_id) { + (void)object_id; + + switch (code) { + case osRtxErrorStackOverflow: + // 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; + } + for (;;) {} +//return 0U; +} diff --git a/Platform_MIMXRT1064-EVK/RTE/CMSIS/RTX_Config.h b/Platform_MIMXRT1064-EVK/RTE/CMSIS/RTX_Config.h new file mode 100644 index 0000000..4f5aff3 --- /dev/null +++ b/Platform_MIMXRT1064-EVK/RTE/CMSIS/RTX_Config.h @@ -0,0 +1,580 @@ +/* + * Copyright (c) 2013-2021 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ----------------------------------------------------------------------------- + * + * $Revision: V5.5.2 + * + * 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: 32768 +#ifndef OS_DYNAMIC_MEM_SIZE +#define OS_DYNAMIC_MEM_SIZE 24000 +#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: 3072 +#ifndef OS_STACK_SIZE +#define OS_STACK_SIZE 3072 +#endif + +// Idle Thread Stack size [bytes] <72-1073741824:8> +// Defines stack size for Idle thread. +// Default: 512 +#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 (requires RTX source variant). +// Enabling this option increases slightly the execution time of a thread switch. +#ifndef OS_STACK_CHECK +#define OS_STACK_CHECK 0 +#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 1 +#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: 512 +#ifndef OS_TIMER_THREAD_STACK_SIZE +#define OS_TIMER_THREAD_STACK_SIZE 256 +#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 4 +#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 1 +#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 0x81U +#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 0x81U +#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 0x85U +#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 0x81U +#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 0x81U +#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 0x81U +#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 0x81U +#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 0x81U +#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 0x81U +#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 0x81U +#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 0x81U +#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) +#ifndef OS_THREAD_LIBSPACE_NUM +#define OS_THREAD_LIBSPACE_NUM 4 +#endif +#else +#define OS_THREAD_LIBSPACE_NUM OS_THREAD_NUM +#endif + +//------------- <<< end of configuration section >>> --------------------------- + +#endif // RTX_CONFIG_H_ diff --git a/Platform_MIMXRT1064-EVK/RTE/Compiler/EventRecorderConf.h b/Platform_MIMXRT1064-EVK/RTE/Compiler/EventRecorderConf.h new file mode 100644 index 0000000..b9cb59c --- /dev/null +++ b/Platform_MIMXRT1064-EVK/RTE/Compiler/EventRecorderConf.h @@ -0,0 +1,34 @@ +/*------------------------------------------------------------------------------ + * MDK - Component ::Event Recorder + * Copyright (c) 2016-2018 ARM Germany GmbH. All rights reserved. + *------------------------------------------------------------------------------ + * Name: EventRecorderConf.h + * Purpose: Event Recorder Configuration + * Rev.: V1.1.0 + *----------------------------------------------------------------------------*/ + +//-------- <<< Use Configuration Wizard in Context Menu >>> -------------------- + +// Event Recorder + +// Number of Records +// <8=>8 <16=>16 <32=>32 <64=>64 <128=>128 <256=>256 <512=>512 <1024=>1024 +// <2048=>2048 <4096=>4096 <8192=>8192 <16384=>16384 <32768=>32768 +// <65536=>65536 +// Configures size of Event Record Buffer (each record is 16 bytes) +// Must be 2^n (min=8, max=65536) +#define EVENT_RECORD_COUNT 256U + +// Time Stamp Source +// <0=> DWT Cycle Counter <1=> SysTick <2=> CMSIS-RTOS2 System Timer +// <3=> User Timer (Normal Reset) <4=> User Timer (Power-On Reset) +// Selects source for 32-bit time stamp +#define EVENT_TIMESTAMP_SOURCE 0 + +// Time Stamp Clock Frequency [Hz] <0-1000000000> +// Defines initial time stamp clock frequency (0 when not used) +#define EVENT_TIMESTAMP_FREQ 0U + +// + +//------------- <<< end of configuration section >>> --------------------------- diff --git a/Platform_MIMXRT1064-EVK/RTE/Device/MIMXRT1064DVL6A/MIMXRT1064xxxxx_flexspi_nor.scf b/Platform_MIMXRT1064-EVK/RTE/Device/MIMXRT1064DVL6A/MIMXRT1064xxxxx_flexspi_nor.scf new file mode 100644 index 0000000..b27a61c --- /dev/null +++ b/Platform_MIMXRT1064-EVK/RTE/Device/MIMXRT1064DVL6A/MIMXRT1064xxxxx_flexspi_nor.scf @@ -0,0 +1,118 @@ +#!armclang --target=arm-arm-none-eabi -mcpu=cortex-m7 -E -x c +/* +** ################################################################### +** Processors: MIMXRT1064CVJ5A +** MIMXRT1064CVL5A +** MIMXRT1064DVJ6A +** MIMXRT1064DVL6A +** +** Compiler: Keil ARM C/C++ Compiler +** Reference manual: IMXRT1064RM Rev.0.1, 12/2018 | IMXRT1064SRM Rev.3 +** Version: rev. 0.1, 2018-06-22 +** Build: b191015 +** +** Abstract: +** Linker file for the Keil ARM C/C++ Compiler +** +** Copyright 2016 Freescale Semiconductor, Inc. +** Copyright 2016-2019 NXP +** All rights reserved. +** +** SPDX-License-Identifier: BSD-3-Clause +** +** http: www.nxp.com +** mail: support@nxp.com +** +** ################################################################### +*/ + +/* Modified by Keil */ + +#if (defined(__ram_vector_table__)) + #define __ram_vector_table_size__ 0x00000400 +#else + #define __ram_vector_table_size__ 0x00000000 +#endif + +#define m_flash_config_start 0x70000000 +#define m_flash_config_size 0x00001000 + +#define m_ivt_start 0x70001000 +#define m_ivt_size 0x00001000 + +#define m_interrupts_start 0x70002000 +#define m_interrupts_size 0x00000400 + +#define m_text_start 0x70002400 +#define m_text_size 0x003FDC00 + +#define m_interrupts_ram_start 0x20000000 +#define m_interrupts_ram_size __ram_vector_table_size__ + +#define m_data_start (m_interrupts_ram_start + m_interrupts_ram_size) +#define m_data_size (0x00020000 - m_interrupts_ram_size) + +#define m_data_noinit_size 0x00000500 + +#define m_data2_start 0x20200000 +#define m_data2_size 0x000C0000 + +/* Sizes */ +#if (defined(__stack_size__)) + #define Stack_Size __stack_size__ +#else + #define Stack_Size 0x0400 +#endif + +#if (defined(__heap_size__)) + #define Heap_Size __heap_size__ +#else + #define Heap_Size 0x10000 +#endif + +#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +LR_m_text m_flash_config_start m_text_start+m_text_size-m_flash_config_start { ; load region size_region + RW_m_config_text m_flash_config_start FIXED m_flash_config_size { ; load address = execution address + * (.boot_hdr.conf, +FIRST) + } + + RW_m_ivt_text m_ivt_start FIXED m_ivt_size { ; load address = execution address + * (.boot_hdr.ivt, +FIRST) + * (.boot_hdr.boot_data) + * (.boot_hdr.dcd_data) + } +#else +LR_m_text m_interrupts_start m_text_start+m_text_size-m_interrupts_start { ; load region size_region +#endif + VECTOR_ROM m_interrupts_start FIXED m_interrupts_size { ; load address = execution address + * (.isr_vector,+FIRST) + } + ER_m_text m_text_start FIXED m_text_size { ; load address = execution address + * (InRoot$$Sections) + .ANY (+RO) + } +#if (defined(__ram_vector_table__)) + VECTOR_RAM m_interrupts_ram_start EMPTY m_interrupts_ram_size { + } +#else + VECTOR_RAM m_interrupts_start EMPTY 0 { + } +#endif + RW_m_data m_data_start m_data_size-Stack_Size-Heap_Size-m_data_noinit_size { ; RW data + .ANY (+RW +ZI) + * (RamFunction) + * (NonCacheable.init) + * (*NonCacheable) + } + RW_NOINIT +0 UNINIT { ; RW uninitialized data + * (.bss.noinit) + } + ARM_LIB_HEAP +0 EMPTY Heap_Size { ; Heap region growing up + } + ARM_LIB_STACK m_data_start+m_data_size EMPTY -Stack_Size { ; Stack region growing down + } + RW_m_ncache m_data2_start EMPTY 0 { + } + RW_m_ncache_unused +0 EMPTY m_data2_size-ImageLength(RW_m_ncache) { ; Empty region added for MPU configuration + } +} diff --git a/Platform_MIMXRT1064-EVK/RTE/Device/MIMXRT1064DVL6A/MIMXRT1064xxxxx_flexspi_nor_sdram.scf b/Platform_MIMXRT1064-EVK/RTE/Device/MIMXRT1064DVL6A/MIMXRT1064xxxxx_flexspi_nor_sdram.scf new file mode 100644 index 0000000..d631b01 --- /dev/null +++ b/Platform_MIMXRT1064-EVK/RTE/Device/MIMXRT1064DVL6A/MIMXRT1064xxxxx_flexspi_nor_sdram.scf @@ -0,0 +1,144 @@ +#!armclang --target=arm-arm-none-eabi -mcpu=cortex-m7 -E -x c +/* +** ################################################################### +** Processors: MIMXRT1064CVJ5A +** MIMXRT1064CVL5A +** MIMXRT1064DVJ6A +** MIMXRT1064DVL6A +** +** Compiler: Keil ARM C/C++ Compiler +** Reference manual: IMXRT1064RM Rev.0.1, 12/2018 | IMXRT1064SRM Rev.3 +** Version: rev. 0.1, 2018-06-22 +** Build: b191015 +** +** Abstract: +** Linker file for the Keil ARM C/C++ Compiler +** +** Copyright 2016 Freescale Semiconductor, Inc. +** Copyright 2016-2019 NXP +** All rights reserved. +** +** SPDX-License-Identifier: BSD-3-Clause +** +** http: www.nxp.com +** mail: support@nxp.com +** +** ################################################################### +*/ + +/* Modified by Keil */ + +#if (defined(__ram_vector_table__)) + #define __ram_vector_table_size__ 0x00000400 +#else + #define __ram_vector_table_size__ 0x00000000 +#endif + +#define m_flash_config_start 0x70000000 +#define m_flash_config_size 0x00001000 + +#define m_ivt_start 0x70001000 +#define m_ivt_size 0x00001000 + +#define m_interrupts_start 0x70002000 +#define m_interrupts_size 0x00000400 + +#define m_text_start 0x70002400 +#define m_text_size 0x003FDC00 + +#define m_interrupts_ram_start 0x80000000 +#define m_interrupts_ram_size __ram_vector_table_size__ + +#define m_data_start (m_interrupts_ram_start + m_interrupts_ram_size) +#define m_data_size (0x01E00000 - m_interrupts_ram_size) + +#define m_ncache_start 0x81E00000 +#define m_ncache_size 0x00200000 + +#define m_data_noinit_size 0x00000500 + +#define m_data2_start 0x20000000 +#define m_data2_size 0x00020000 + +#define m_data3_start 0x20200000 +#define m_data3_size 0x000C0000 + +/* Sizes */ +#if (defined(__stack_size__)) + #define Stack_Size __stack_size__ +#else + #define Stack_Size 0x0400 +#endif + +#if (defined(__heap_size__)) + #define Heap_Size __heap_size__ +#else + #define Heap_Size 0x0400 +#endif + +#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +LR_m_text m_flash_config_start m_text_start+m_text_size-m_flash_config_start { ; load region size_region + RW_m_config_text m_flash_config_start FIXED m_flash_config_size { ; load address = execution address + * (.boot_hdr.conf, +FIRST) + } + + RW_m_ivt_text m_ivt_start FIXED m_ivt_size { ; load address = execution address + * (.boot_hdr.ivt, +FIRST) + * (.boot_hdr.boot_data) + * (.boot_hdr.dcd_data) + } +#else +LR_m_text m_interrupts_start m_text_start+m_text_size-m_interrupts_start { ; load region size_region +#endif + VECTOR_ROM m_interrupts_start FIXED m_interrupts_size { ; load address = execution address + * (.isr_vector,+FIRST) + } + ER_m_text m_text_start FIXED m_text_size { ; load address = execution address + * (InRoot$$Sections) + .ANY (+RO) + } +#if (defined(__ram_vector_table__)) + VECTOR_RAM m_interrupts_ram_start EMPTY m_interrupts_ram_size { + } +#else + VECTOR_RAM m_interrupts_start EMPTY 0 { + } +#endif + RW_m_data2 m_data2_start m_data2_size { + * (RamFunction) + } +#if (defined(__heap_noncacheable__)) + RW_m_data m_data_start m_data_size-Stack_Size { ; RW data +#else + RW_m_data m_data_start m_data_size-Stack_Size-Heap_Size-m_ncache_size-m_data_noinit_size { ; RW data +#endif + .ANY (+RW +ZI) + *(*m_usb_dma_init_data) + *(*m_usb_dma_noninit_data) + } + RW_NOINIT +0 UNINIT { ; RW uninitialized data + * (.bss.noinit) + } +#if (!defined(__heap_noncacheable__)) + ARM_LIB_HEAP +0 EMPTY Heap_Size { ; Heap region growing up + } +#endif + ARM_LIB_STACK m_data_start+m_data_size EMPTY -Stack_Size { ; Stack region growing down + } +#if (defined(__heap_noncacheable__)) + RW_m_ncache m_ncache_start m_ncache_size - Heap_Size { ; ncache RW data +#else + RW_m_ncache m_ncache_start m_ncache_size { ; ncache RW data +#endif + * (NonCacheable.init) + * (*NonCacheable) + } +#if (defined(__heap_noncacheable__)) + ARM_LIB_HEAP +0 EMPTY Heap_Size { ; Heap region growing up + } + RW_m_ncache_unused +0 EMPTY m_ncache_size-ImageLength(RW_m_ncache)-Heap_Size { ; Empty region added for MPU configuration +#else + RW_m_ncache_unused +0 EMPTY m_ncache_size-ImageLength(RW_m_ncache) { ; Empty region added for MPU configuration +#endif + } +} diff --git a/Platform_MIMXRT1064-EVK/RTE/Device/MIMXRT1064DVL6A/MIMXRT1064xxxxx_ram.scf b/Platform_MIMXRT1064-EVK/RTE/Device/MIMXRT1064DVL6A/MIMXRT1064xxxxx_ram.scf new file mode 100644 index 0000000..f071278 --- /dev/null +++ b/Platform_MIMXRT1064-EVK/RTE/Device/MIMXRT1064DVL6A/MIMXRT1064xxxxx_ram.scf @@ -0,0 +1,84 @@ +#!armclang --target=arm-arm-none-eabi -mcpu=cortex-m7 -E -x c +/* +** ################################################################### +** Processors: MIMXRT1064CVJ5A +** MIMXRT1064CVL5A +** MIMXRT1064DVJ6A +** MIMXRT1064DVL6A +** +** Compiler: Keil ARM C/C++ Compiler +** Reference manual: IMXRT1064RM Rev.0.1, 12/2018 | IMXRT1064SRM Rev.3 +** Version: rev. 0.1, 2018-06-22 +** Build: b191015 +** +** Abstract: +** Linker file for the Keil ARM C/C++ Compiler +** +** Copyright 2016 Freescale Semiconductor, Inc. +** Copyright 2016-2019 NXP +** All rights reserved. +** +** SPDX-License-Identifier: BSD-3-Clause +** +** http: www.nxp.com +** mail: support@nxp.com +** +** ################################################################### +*/ + +/* Modified by Keil */ + +#define m_interrupts_start 0x00000000 +#define m_interrupts_size 0x00000400 + +#define m_text_start 0x00000400 +#define m_text_size 0x0001FC00 + +#define m_data_start 0x20000000 +#define m_data_size 0x00020000 + +#define m_data_noinit_size 0x00000500 + +#define m_data2_start 0x20200000 +#define m_data2_size 0x000C0000 + +/* Sizes */ +#if (defined(__stack_size__)) + #define Stack_Size __stack_size__ +#else + #define Stack_Size 0x0400 +#endif + +#if (defined(__heap_size__)) + #define Heap_Size __heap_size__ +#else + #define Heap_Size 0x0400 +#endif + +LR_m_text m_interrupts_start m_text_start+m_text_size-m_interrupts_start { ; load region size_region + VECTOR_ROM m_interrupts_start FIXED m_interrupts_size { ; load address = execution address + * (.isr_vector,+FIRST) + } + ER_m_text m_text_start FIXED m_text_size { ; load address = execution address + * (InRoot$$Sections) + .ANY (+RO) + } + VECTOR_RAM m_interrupts_start EMPTY 0 { + } + RW_m_data m_data_start m_data_size-Stack_Size-Heap_Size-m_data_noinit_size { ; RW data + .ANY (+RW +ZI) + * (NonCacheable.init) + * (*NonCacheable) + } + RW_NOINIT +0 UNINIT { ; RW uninitialized data + * (.bss.noinit) + } + ARM_LIB_HEAP +0 EMPTY Heap_Size { ; Heap region growing up + } + ARM_LIB_STACK m_data_start+m_data_size EMPTY -Stack_Size { ; Stack region growing down + } + RW_m_ncache m_data2_start EMPTY 0 { + } + RW_m_ncache_unused +0 EMPTY m_data2_size-ImageLength(RW_m_ncache) { ; Empty region added for MPU configuration + } +} diff --git a/Platform_MIMXRT1064-EVK/RTE/Device/MIMXRT1064DVL6A/MIMXRT1064xxxxx_sdram.scf b/Platform_MIMXRT1064-EVK/RTE/Device/MIMXRT1064DVL6A/MIMXRT1064xxxxx_sdram.scf new file mode 100644 index 0000000..c5e8f90 --- /dev/null +++ b/Platform_MIMXRT1064-EVK/RTE/Device/MIMXRT1064DVL6A/MIMXRT1064xxxxx_sdram.scf @@ -0,0 +1,108 @@ +#!armclang --target=arm-arm-none-eabi -mcpu=cortex-m7 -E -x c +/* +** ################################################################### +** Processors: MIMXRT1064CVJ5A +** MIMXRT1064CVL5A +** MIMXRT1064DVJ6A +** MIMXRT1064DVL6A +** +** Compiler: Keil ARM C/C++ Compiler +** Reference manual: IMXRT1064RM Rev.0.1, 12/2018 | IMXRT1064SRM Rev.3 +** Version: rev. 0.1, 2018-06-22 +** Build: b191015 +** +** Abstract: +** Linker file for the Keil ARM C/C++ Compiler +** +** Copyright 2016 Freescale Semiconductor, Inc. +** Copyright 2016-2019 NXP +** All rights reserved. +** +** SPDX-License-Identifier: BSD-3-Clause +** +** http: www.nxp.com +** mail: support@nxp.com +** +** ################################################################### +*/ + +/* Modified by Keil */ + +#define m_interrupts_start 0x00000000 +#define m_interrupts_size 0x00000400 + +#define m_text_start 0x00000400 +#define m_text_size 0x0001FC00 + +#define m_data_start 0x80000000 +#define m_data_size 0x01E00000 + +#define m_ncache_start 0x81E00000 +#define m_ncache_size 0x00200000 + +#define m_data_noinit_size 0x00000500 + +#define m_data2_start 0x20000000 +#define m_data2_size 0x00020000 + +#define m_data3_start 0x20200000 +#define m_data3_size 0x000C0000 + +/* Sizes */ +#if (defined(__stack_size__)) + #define Stack_Size __stack_size__ +#else + #define Stack_Size 0x0400 +#endif + +#if (defined(__heap_size__)) + #define Heap_Size __heap_size__ +#else + #define Heap_Size 0x0400 +#endif + +LR_m_text m_interrupts_start m_text_start+m_text_size-m_interrupts_start { ; load region size_region + VECTOR_ROM m_interrupts_start FIXED m_interrupts_size { ; load address = execution address + * (.isr_vector,+FIRST) + } + ER_m_text m_text_start FIXED m_text_size { ; load address = execution address + * (InRoot$$Sections) + .ANY (+RO) + } + VECTOR_RAM m_interrupts_start EMPTY 0 { + } +#if (defined(__heap_noncacheable__)) + RW_m_data m_data_start m_data_size-Stack_Size { ; RW data +#else + RW_m_data m_data_start m_data_size-Stack_Size-Heap_Size-m_ncache_size-m_data_noinit_size { ; RW data +#endif + .ANY (+RW +ZI) + *(*m_usb_dma_init_data) + *(*m_usb_dma_noninit_data) + } + RW_NOINIT +0 UNINIT { ; RW uninitialized data + * (.bss.noinit) + } +#if (!defined(__heap_noncacheable__)) + ARM_LIB_HEAP +0 EMPTY Heap_Size { ; Heap region growing up + } +#endif + ARM_LIB_STACK m_data_start+m_data_size EMPTY -Stack_Size { ; Stack region growing down + } +#if (defined(__heap_noncacheable__)) + RW_m_ncache m_ncache_start m_ncache_size - Heap_Size { ; ncache RW data +#else + RW_m_ncache m_ncache_start m_ncache_size { ; ncache RW data +#endif + * (NonCacheable.init) + * (*NonCacheable) + } +#if (defined(__heap_noncacheable__)) + ARM_LIB_HEAP +0 EMPTY Heap_Size { ; Heap region growing up + } + RW_m_ncache_unused +0 EMPTY m_ncache_size-ImageLength(RW_m_ncache)-Heap_Size { ; Empty region added for MPU configuration +#else + RW_m_ncache_unused +0 EMPTY m_ncache_size-ImageLength(RW_m_ncache) { ; Empty region added for MPU configuration +#endif + } +} diff --git a/Platform_MIMXRT1064-EVK/RTE/Device/MIMXRT1064DVL6A/MIMXRT1064xxxxx_sdram_txt.scf b/Platform_MIMXRT1064-EVK/RTE/Device/MIMXRT1064DVL6A/MIMXRT1064xxxxx_sdram_txt.scf new file mode 100644 index 0000000..0202a09 --- /dev/null +++ b/Platform_MIMXRT1064-EVK/RTE/Device/MIMXRT1064DVL6A/MIMXRT1064xxxxx_sdram_txt.scf @@ -0,0 +1,108 @@ +#!armclang --target=arm-arm-none-eabi -mcpu=cortex-m7 -E -x c +/* +** ################################################################### +** Processors: MIMXRT1064CVJ5A +** MIMXRT1064CVL5A +** MIMXRT1064DVJ6A +** MIMXRT1064DVL6A +** +** Compiler: Keil ARM C/C++ Compiler +** Reference manual: IMXRT1064RM Rev.0.1, 12/2018 | IMXRT1064SRM Rev.3 +** Version: rev. 0.1, 2018-06-22 +** Build: b191015 +** +** Abstract: +** Linker file for the Keil ARM C/C++ Compiler +** +** Copyright 2016 Freescale Semiconductor, Inc. +** Copyright 2016-2019 NXP +** All rights reserved. +** +** SPDX-License-Identifier: BSD-3-Clause +** +** http: www.nxp.com +** mail: support@nxp.com +** +** ################################################################### +*/ + +/* Modified by Keil */ + +#define m_interrupts_start 0x80000000 +#define m_interrupts_size 0x00000400 + +#define m_text_start 0x80000400 +#define m_text_size 0x001FFC00 + +#define m_data_start 0x20200000 +#define m_data_size 0x000C0000 + +#define m_data_noinit_size 0x00000500 + +#define m_data2_start 0x20000000 +#define m_data2_size 0x00020000 + +#define m_data3_start 0x80200000 +#define m_data3_size 0x01C00000 + +#define m_ncache_start 0x81E00000 +#define m_ncache_size 0x00200000 + +/* Sizes */ +#if (defined(__stack_size__)) + #define Stack_Size __stack_size__ +#else + #define Stack_Size 0x0400 +#endif + +#if (defined(__heap_size__)) + #define Heap_Size __heap_size__ +#else + #define Heap_Size 0x0400 +#endif + +LR_m_text m_interrupts_start m_text_start+m_text_size-m_interrupts_start { ; load region size_region + VECTOR_ROM m_interrupts_start FIXED m_interrupts_size { ; load address = execution address + * (.isr_vector,+FIRST) + } + ER_m_text m_text_start FIXED m_text_size { ; load address = execution address + * (InRoot$$Sections) + .ANY (+RO) + } + VECTOR_RAM m_interrupts_start EMPTY 0 { + } +#if (defined(__heap_noncacheable__)) + RW_m_data m_data_start m_data_size-Stack_Size { ; RW data +#else + RW_m_data m_data_start m_data_size-Stack_Size-Heap_Size-m_ncache_size-m_data_noinit_size { ; RW data +#endif + .ANY (+RW +ZI) + *(*m_usb_dma_init_data) + *(*m_usb_dma_noninit_data) + } + RW_NOINIT +0 UNINIT { ; RW uninitialized data + * (.bss.noinit) + } +#if (!defined(__heap_noncacheable__)) + ARM_LIB_HEAP +0 EMPTY Heap_Size { ; Heap region growing up + } +#endif + ARM_LIB_STACK m_data_start+m_data_size EMPTY -Stack_Size { ; Stack region growing down + } +#if (defined(__heap_noncacheable__)) + RW_m_ncache m_ncache_start m_ncache_size - Heap_Size { ; ncache RW data +#else + RW_m_ncache m_ncache_start m_ncache_size { ; ncache RW data +#endif + * (NonCacheable.init) + * (*NonCacheable) + } +#if (defined(__heap_noncacheable__)) + ARM_LIB_HEAP +0 EMPTY Heap_Size { ; Heap region growing up + } + RW_m_ncache_unused +0 EMPTY m_ncache_size-ImageLength(RW_m_ncache)-Heap_Size { ; Empty region added for MPU configuration +#else + RW_m_ncache_unused +0 EMPTY m_ncache_size-ImageLength(RW_m_ncache) { ; Empty region added for MPU configuration +#endif + } +} diff --git a/Platform_MIMXRT1064-EVK/RTE/Device/MIMXRT1064DVL6A/RTE_Device.h b/Platform_MIMXRT1064-EVK/RTE/Device/MIMXRT1064DVL6A/RTE_Device.h new file mode 100644 index 0000000..e1af0e2 --- /dev/null +++ b/Platform_MIMXRT1064-EVK/RTE/Device/MIMXRT1064DVL6A/RTE_Device.h @@ -0,0 +1,265 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2020 NXP + * All rights reserved. + * + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _RTE_DEVICE_H +#define _RTE_DEVICE_H + +#include "pin_mux.h" +#include "main.h" + +/* UART Select, UART0 - UART5. */ +/* User needs to provide the implementation of LPUARTX_GetFreq/LPUARTX_InitPins/LPUARTX_DeinitPins for the enabled + * LPUART instance. */ +#define RTE_USART1 1 +#define RTE_USART1_DMA_EN 1 +#define RTE_USART2 0 +#define RTE_USART2_DMA_EN 0 +#define RTE_USART3 1 +#define RTE_USART3_DMA_EN 0 +#define RTE_USART4 0 +#define RTE_USART4_DMA_EN 0 +#define RTE_USART5 0 +#define RTE_USART5_DMA_EN 0 +#define RTE_USART6 0 +#define RTE_USART6_DMA_EN 0 +#define RTE_USART7 0 +#define RTE_USART7_DMA_EN 0 +#define RTE_USART8 0 +#define RTE_USART8_DMA_EN 0 + +/* UART configuration. */ +#define RTE_USART1_PIN_INIT LPUART1_InitPins +#define RTE_USART1_PIN_DEINIT LPUART1_DeinitPins +#define RTE_USART1_DMA_TX_CH 0 +#define RTE_USART1_DMA_TX_PERI_SEL (uint8_t) kDmaRequestMuxLPUART1Tx +#define RTE_USART1_DMA_TX_DMAMUX_BASE DMAMUX +#define RTE_USART1_DMA_TX_DMA_BASE DMA0 +#define RTE_USART1_DMA_RX_CH 1 +#define RTE_USART1_DMA_RX_PERI_SEL (uint8_t) kDmaRequestMuxLPUART1Rx +#define RTE_USART1_DMA_RX_DMAMUX_BASE DMAMUX +#define RTE_USART1_DMA_RX_DMA_BASE DMA0 + +#define RTE_USART2_PIN_INIT LPUART2_InitPins +#define RTE_USART2_PIN_DEINIT LPUART2_DeinitPins +#define RTE_USART2_DMA_TX_CH 2 +#define RTE_USART2_DMA_TX_PERI_SEL (uint8_t) kDmaRequestMuxLPUART2Tx +#define RTE_USART2_DMA_TX_DMAMUX_BASE DMAMUX +#define RTE_USART2_DMA_TX_DMA_BASE DMA0 +#define RTE_USART2_DMA_RX_CH 3 +#define RTE_USART2_DMA_RX_PERI_SEL (uint8_t) kDmaRequestMuxLPUART2Rx +#define RTE_USART2_DMA_RX_DMAMUX_BASE DMAMUX +#define RTE_USART2_DMA_RX_DMA_BASE DMA0 + +#define RTE_USART3_PIN_INIT LPUART3_InitPins +#define RTE_USART3_PIN_DEINIT LPUART3_DeinitPins +#define RTE_USART3_DMA_TX_CH 4 +#define RTE_USART3_DMA_TX_PERI_SEL (uint8_t) kDmaRequestMuxLPUART3Tx +#define RTE_USART3_DMA_TX_DMAMUX_BASE DMAMUX +#define RTE_USART3_DMA_TX_DMA_BASE DMA0 +#define RTE_USART3_DMA_RX_CH 5 +#define RTE_USART3_DMA_RX_PERI_SEL (uint8_t) kDmaRequestMuxLPUART3Rx +#define RTE_USART3_DMA_RX_DMAMUX_BASE DMAMUX +#define RTE_USART3_DMA_RX_DMA_BASE DMA0 + +#define RTE_USART4_PIN_INIT LPUART4_InitPins +#define RTE_USART4_PIN_DEINIT LPUART4_DeinitPins +#define RTE_USART4_DMA_TX_CH 6 +#define RTE_USART4_DMA_TX_PERI_SEL (uint8_t) kDmaRequestMuxLPUART4Tx +#define RTE_USART4_DMA_TX_DMAMUX_BASE DMAMUX +#define RTE_USART4_DMA_TX_DMA_BASE DMA0 +#define RTE_USART4_DMA_RX_CH 7 +#define RTE_USART4_DMA_RX_PERI_SEL (uint8_t) kDmaRequestMuxLPUART4Rx +#define RTE_USART4_DMA_RX_DMAMUX_BASE DMAMUX +#define RTE_USART4_DMA_RX_DMA_BASE DMA0 + +#define RTE_USART5_PIN_INIT LPUART5_InitPins +#define RTE_USART5_PIN_DEINIT LPUART5_DeinitPins +#define RTE_USART5_DMA_TX_CH 8 +#define RTE_USART5_DMA_TX_PERI_SEL (uint8_t) kDmaRequestMuxLPUART5Tx +#define RTE_USART5_DMA_TX_DMAMUX_BASE DMAMUX +#define RTE_USART5_DMA_TX_DMA_BASE DMA0 +#define RTE_USART5_DMA_RX_CH 9 +#define RTE_USART5_DMA_RX_PERI_SEL (uint8_t) kDmaRequestMuxLPUART5Rx +#define RTE_USART5_DMA_RX_DMAMUX_BASE DMAMUX +#define RTE_USART5_DMA_RX_DMA_BASE DMA0 + +#define RTE_USART6_PIN_INIT LPUART6_InitPins +#define RTE_USART6_PIN_DEINIT LPUART6_DeinitPins +#define RTE_USART6_DMA_TX_CH 10 +#define RTE_USART6_DMA_TX_PERI_SEL (uint8_t) kDmaRequestMuxLPUART6Tx +#define RTE_USART6_DMA_TX_DMAMUX_BASE DMAMUX +#define RTE_USART6_DMA_TX_DMA_BASE DMA0 +#define RTE_USART6_DMA_RX_CH 11 +#define RTE_USART6_DMA_RX_PERI_SEL (uint8_t) kDmaRequestMuxLPUART6Rx +#define RTE_USART6_DMA_RX_DMAMUX_BASE DMAMUX +#define RTE_USART6_DMA_RX_DMA_BASE DMA0 + +#define RTE_USART7_PIN_INIT LPUART7_InitPins +#define RTE_USART7_PIN_DEINIT LPUART7_DeinitPins +#define RTE_USART7_DMA_TX_CH 12 +#define RTE_USART7_DMA_TX_PERI_SEL (uint8_t) kDmaRequestMuxLPUART7Tx +#define RTE_USART7_DMA_TX_DMAMUX_BASE DMAMUX +#define RTE_USART7_DMA_TX_DMA_BASE DMA0 +#define RTE_USART7_DMA_RX_CH 13 +#define RTE_USART7_DMA_RX_PERI_SEL (uint8_t) kDmaRequestMuxLPUART7Rx +#define RTE_USART7_DMA_RX_DMAMUX_BASE DMAMUX +#define RTE_USART7_DMA_RX_DMA_BASE DMA0 + +#define RTE_USART8_PIN_INIT LPUART8_InitPins +#define RTE_USART8_PIN_DEINIT LPUART8_DeinitPins +#define RTE_USART8_DMA_TX_CH 14 +#define RTE_USART8_DMA_TX_PERI_SEL (uint8_t) kDmaRequestMuxLPUART8Tx +#define RTE_USART8_DMA_TX_DMAMUX_BASE DMAMUX +#define RTE_USART8_DMA_TX_DMA_BASE DMA0 +#define RTE_USART8_DMA_RX_CH 15 +#define RTE_USART8_DMA_RX_PERI_SEL (uint8_t) kDmaRequestMuxLPUART8Rx +#define RTE_USART8_DMA_RX_DMAMUX_BASE DMAMUX +#define RTE_USART8_DMA_RX_DMA_BASE DMA0 + +/* I2C select, I2C1 - I2C4. */ +/* User needs to provide the implementation of LPI2CX_GetFreq/LPI2CX_InitPins/LPI2CX_DeinitPins for the enabled LPI2C + * instance. */ +#define RTE_I2C1 1 +#define RTE_I2C1_DMA_EN 1 +#define RTE_I2C2 0 +#define RTE_I2C2_DMA_EN 0 +#define RTE_I2C3 0 +#define RTE_I2C3_DMA_EN 0 +#define RTE_I2C4 0 +#define RTE_I2C4_DMA_EN 0 + +/* LPI2C configuration. */ +#define RTE_I2C1_PIN_INIT LPI2C1_InitPins +#define RTE_I2C1_PIN_DEINIT LPI2C1_DeinitPins +#define RTE_I2C1_DMA_TX_CH 0 +#define RTE_I2C1_DMA_TX_PERI_SEL (uint8_t) kDmaRequestMuxLPI2C1 +#define RTE_I2C1_DMA_TX_DMAMUX_BASE DMAMUX +#define RTE_I2C1_DMA_TX_DMA_BASE DMA0 +#define RTE_I2C1_DMA_RX_CH 1 +#define RTE_I2C1_DMA_RX_PERI_SEL (uint8_t) kDmaRequestMuxLPI2C1 +#define RTE_I2C1_DMA_RX_DMAMUX_BASE DMAMUX +#define RTE_I2C1_DMA_RX_DMA_BASE DMA0 + +#define RTE_I2C2_PIN_INIT LPI2C2_InitPins +#define RTE_I2C2_PIN_DEINIT LPI2C2_DeinitPins +#define RTE_I2C2_DMA_TX_CH 2 +#define RTE_I2C2_DMA_TX_PERI_SEL (uint8_t) kDmaRequestMuxLPI2C2 +#define RTE_I2C2_DMA_TX_DMAMUX_BASE DMAMUX +#define RTE_I2C2_DMA_TX_DMA_BASE DMA0 +#define RTE_I2C2_DMA_RX_CH 3 +#define RTE_I2C2_DMA_RX_PERI_SEL (uint8_t) kDmaRequestMuxLPI2C2 +#define RTE_I2C2_DMA_RX_DMAMUX_BASE DMAMUX +#define RTE_I2C2_DMA_RX_DMA_BASE DMA0 + +#define RTE_I2C3_PIN_INIT LPI2C3_InitPins +#define RTE_I2C3_PIN_DEINIT LPI2C3_DeinitPins +#define RTE_I2C3_DMA_TX_CH 4 +#define RTE_I2C3_DMA_TX_PERI_SEL (uint8_t) kDmaRequestMuxLPI2C3 +#define RTE_I2C3_DMA_TX_DMAMUX_BASE DMAMUX +#define RTE_I2C3_DMA_TX_DMA_BASE DMA0 +#define RTE_I2C3_DMA_RX_CH 5 +#define RTE_I2C3_DMA_RX_PERI_SEL (uint8_t) kDmaRequestMuxLPI2C3 +#define RTE_I2C3_DMA_RX_DMAMUX_BASE DMAMUX +#define RTE_I2C3_DMA_RX_DMA_BASE DMA0 + +#define RTE_I2C4_PIN_INIT LPI2C4_InitPins +#define RTE_I2C4_PIN_DEINIT LPI2C4_DeinitPins +#define RTE_I2C4_DMA_TX_CH 6 +#define RTE_I2C4_DMA_TX_PERI_SEL (uint8_t) kDmaRequestMuxLPI2C4 +#define RTE_I2C4_DMA_TX_DMAMUX_BASE DMAMUX +#define RTE_I2C4_DMA_TX_DMA_BASE DMA0 +#define RTE_I2C4_DMA_RX_CH 7 +#define RTE_I2C4_DMA_RX_PERI_SEL (uint8_t) kDmaRequestMuxLPI2C4 +#define RTE_I2C4_DMA_RX_DMAMUX_BASE DMAMUX +#define RTE_I2C4_DMA_RX_DMA_BASE DMA0 + +/*SPI select, SPI1 - SPI4.*/ +/* User needs to provide the implementation of SPIX_GetFreq/SPIX_InitPins/SPIX_DeinitPins for the enabled SPI instance. + */ +#define RTE_SPI1 1 +#define RTE_SPI1_DMA_EN 1 +#define RTE_SPI2 0 +#define RTE_SPI2_DMA_EN 0 +#define RTE_SPI3 0 +#define RTE_SPI3_DMA_EN 0 +#define RTE_SPI4 0 +#define RTE_SPI4_DMA_EN 0 + +/* SPI configuration. */ +#define RTE_SPI1_PCS_TO_SCK_DELAY 1000 +#define RTE_SPI1_SCK_TO_PSC_DELAY 1000 +#define RTE_SPI1_BETWEEN_TRANSFER_DELAY 1000 +#define RTE_SPI1_MASTER_PCS_PIN_SEL (kLPSPI_MasterPcs0) +#define RTE_SPI1_SLAVE_PCS_PIN_SEL (kLPSPI_SlavePcs0) +#define RTE_SPI1_PIN_INIT SPI1_InitPins +#define RTE_SPI1_PIN_DEINIT SPI1_DeinitPins +#define RTE_SPI1_DMA_TX_CH 0 +#define RTE_SPI1_DMA_TX_PERI_SEL (uint8_t) kDmaRequestMuxLPSPI1Tx +#define RTE_SPI1_DMA_TX_DMAMUX_BASE DMAMUX +#define RTE_SPI1_DMA_TX_DMA_BASE DMA0 +#define RTE_SPI1_DMA_RX_CH 1 +#define RTE_SPI1_DMA_RX_PERI_SEL (uint8_t) kDmaRequestMuxLPSPI1Rx +#define RTE_SPI1_DMA_RX_DMAMUX_BASE DMAMUX +#define RTE_SPI1_DMA_RX_DMA_BASE DMA0 + +#define RTE_SPI2_PCS_TO_SCK_DELAY 1000 +#define RTE_SPI2_SCK_TO_PSC_DELAY 1000 +#define RTE_SPI2_BETWEEN_TRANSFER_DELAY 1000 +#define RTE_SPI2_MASTER_PCS_PIN_SEL (kLPSPI_MasterPcs0) +#define RTE_SPI2_SLAVE_PCS_PIN_SEL (kLPSPI_SlavePcs0) +#define RTE_SPI2_PIN_INIT SPI2_InitPins +#define RTE_SPI2_PIN_DEINIT SPI2_DeinitPins +#define RTE_SPI2_DMA_TX_CH 2 +#define RTE_SPI2_DMA_TX_PERI_SEL (uint8_t) kDmaRequestMuxLPSPI2Tx +#define RTE_SPI2_DMA_TX_DMAMUX_BASE DMAMUX +#define RTE_SPI2_DMA_TX_DMA_BASE DMA0 +#define RTE_SPI2_DMA_RX_CH 3 +#define RTE_SPI2_DMA_RX_PERI_SEL (uint8_t) kDmaRequestMuxLPSPI2Tx +#define RTE_SPI2_DMA_RX_DMAMUX_BASE DMAMUX +#define RTE_SPI2_DMA_RX_DMA_BASE DMA0 + +#define RTE_SPI3_PCS_TO_SCK_DELAY 1000 +#define RTE_SPI3_SCK_TO_PSC_DELAY 1000 +#define RTE_SPI3_BETWEEN_TRANSFER_DELAY 1000 +#define RTE_SPI3_MASTER_PCS_PIN_SEL (kLPSPI_MasterPcs0) +#define RTE_SPI3_SLAVE_PCS_PIN_SEL (kLPSPI_SlavePcs0) +#define RTE_SPI3_PIN_INIT SPI3_InitPins +#define RTE_SPI3_PIN_DEINIT SPI3_DeinitPins +#define RTE_SPI3_DMA_TX_CH 4 +#define RTE_SPI3_DMA_TX_PERI_SEL (uint8_t) kDmaRequestMuxLPSPI3Tx +#define RTE_SPI3_DMA_TX_DMAMUX_BASE DMAMUX +#define RTE_SPI3_DMA_TX_DMA_BASE DMA0 +#define RTE_SPI3_DMA_RX_CH 5 +#define RTE_SPI3_DMA_RX_PERI_SEL (uint8_t) kDmaRequestMuxLPSPI3Rx +#define RTE_SPI3_DMA_RX_DMAMUX_BASE DMAMUX +#define RTE_SPI3_DMA_RX_DMA_BASE DMA0 + +#define RTE_SPI4_PCS_TO_SCK_DELAY 1000 +#define RTE_SPI4_SCK_TO_PSC_DELAY 1000 +#define RTE_SPI4_BETWEEN_TRANSFER_DELAY 1000 +#define RTE_SPI4_MASTER_PCS_PIN_SEL (kLPSPI_MasterPcs0) +#define RTE_SPI4_SLAVE_PCS_PIN_SEL (kLPSPI_SlavePcs0) +#define RTE_SPI4_PIN_INIT SPI4_InitPins +#define RTE_SPI4_PIN_DEINIT SPI4_DeinitPins +#define RTE_SPI4_DMA_TX_CH 6 +#define RTE_SPI4_DMA_TX_PERI_SEL (uint8_t) kDmaRequestMuxLPSPI4Tx +#define RTE_SPI4_DMA_TX_DMAMUX_BASE DMAMUX +#define RTE_SPI4_DMA_TX_DMA_BASE DMA0 +#define RTE_SPI4_DMA_RX_CH 7 +#define RTE_SPI4_DMA_RX_PERI_SEL (uint8_t) kDmaRequestMuxLPSPI4Rx +#define RTE_SPI4_DMA_RX_DMAMUX_BASE DMAMUX +#define RTE_SPI4_DMA_RX_DMA_BASE DMA0 + +/* ENET configuration. */ +#define RTE_ENET 1 +#define RTE_ENET_PHY_ADDRESS 2 +#define RTE_ENET_MII 0 +#define RTE_ENET_RMII 1 + +#endif /* _RTE_DEVICE_H */ diff --git a/Platform_MIMXRT1064-EVK/RTE/Machine_Learning/debug_log.cc b/Platform_MIMXRT1064-EVK/RTE/Machine_Learning/debug_log.cc new file mode 100644 index 0000000..bc79d43 --- /dev/null +++ b/Platform_MIMXRT1064-EVK/RTE/Machine_Learning/debug_log.cc @@ -0,0 +1,43 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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. +==============================================================================*/ + +// Implementation for the DebugLog() function that prints to the debug logger on +// an generic Cortex-M device. + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +#include "tensorflow/lite/micro/debug_log.h" + +#include "tensorflow/lite/micro/cortex_m_generic/debug_log_callback.h" + +static DebugLogCallback debug_log_callback = nullptr; + +void RegisterDebugLogCallback(void (*cb)(const char* s)) { + debug_log_callback = cb; +} + +void DebugLog(const char* s) { +#ifndef TF_LITE_STRIP_ERROR_STRINGS + if (debug_log_callback != nullptr) { + debug_log_callback(s); + } +#endif +} + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus diff --git a/Platform_MIMXRT1064-EVK/RTE/Machine_Learning/micro_time.cc b/Platform_MIMXRT1064-EVK/RTE/Machine_Learning/micro_time.cc new file mode 100644 index 0000000..023ac6d --- /dev/null +++ b/Platform_MIMXRT1064-EVK/RTE/Machine_Learning/micro_time.cc @@ -0,0 +1,67 @@ +/* Copyright 2021 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 "tensorflow/lite/micro/micro_time.h" + +// DWT (Data Watchpoint and Trace) registers, only exists on ARM Cortex with a +// DWT unit. +#define KIN1_DWT_CONTROL (*((volatile uint32_t*)0xE0001000)) +/*!< DWT Control register */ + +// DWT Control register. +#define KIN1_DWT_CYCCNTENA_BIT (1UL << 0) + +// CYCCNTENA bit in DWT_CONTROL register. +#define KIN1_DWT_CYCCNT (*((volatile uint32_t*)0xE0001004)) + +// DWT Cycle Counter register. +#define KIN1_DEMCR (*((volatile uint32_t*)0xE000EDFC)) + +// DEMCR: Debug Exception and Monitor Control Register. +#define KIN1_TRCENA_BIT (1UL << 24) + +#define KIN1_LAR (*((volatile uint32_t*)0xE0001FB0)) + +#define KIN1_DWT_CONTROL (*((volatile uint32_t*)0xE0001000)) + +// Unlock access to DWT (ITM, etc.)registers. +#define KIN1_UnlockAccessToDWT() KIN1_LAR = 0xC5ACCE55; + +// TRCENA: Enable trace and debug block DEMCR (Debug Exception and Monitor +// Control Register. +#define KIN1_InitCycleCounter() KIN1_DEMCR |= KIN1_TRCENA_BIT + +#define KIN1_ResetCycleCounter() KIN1_DWT_CYCCNT = 0 +#define KIN1_EnableCycleCounter() KIN1_DWT_CONTROL |= KIN1_DWT_CYCCNTENA_BIT +#define KIN1_DisableCycleCounter() KIN1_DWT_CONTROL &= ~KIN1_DWT_CYCCNTENA_BIT +#define KIN1_GetCycleCounter() KIN1_DWT_CYCCNT + +namespace tflite { + +int32_t ticks_per_second() { return 0; } + +int32_t GetCurrentTimeTicks() { + static bool is_initialized = false; + if (!is_initialized) { + KIN1_UnlockAccessToDWT(); + KIN1_InitCycleCounter(); + KIN1_ResetCycleCounter(); + KIN1_EnableCycleCounter(); + is_initialized = true; + } + return KIN1_GetCycleCounter(); +} + +} // namespace tflite diff --git a/Platform_MIMXRT1064-EVK/RTE/Machine_Learning/system_setup.cc b/Platform_MIMXRT1064-EVK/RTE/Machine_Learning/system_setup.cc new file mode 100644 index 0000000..ac5b197 --- /dev/null +++ b/Platform_MIMXRT1064-EVK/RTE/Machine_Learning/system_setup.cc @@ -0,0 +1,33 @@ +/* Copyright 2021 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 "tensorflow/lite/micro/system_setup.h" +#include "stdio.h" +#include "tensorflow/lite/micro/cortex_m_generic/debug_log_callback.h" + +namespace tflite { + +void debug_log_printf(const char* s) { + printf(s); +} + +// To add an equivalent function for your own platform, create your own +// implementation file, and place it in a subfolder named after the target. See +// tensorflow/lite/micro/debug_log.cc for a similar example. +void InitializeTarget() { + RegisterDebugLogCallback(debug_log_printf); +} + +} // namespace tflite diff --git a/Platform_MIMXRT1064-EVK/main.c b/Platform_MIMXRT1064-EVK/main.c new file mode 100644 index 0000000..82fab45 --- /dev/null +++ b/Platform_MIMXRT1064-EVK/main.c @@ -0,0 +1,92 @@ +/*--------------------------------------------------------------------------- + * Copyright (c) 2020 Arm Limited (or its affiliates). All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *---------------------------------------------------------------------------*/ + +#include "RTE_Components.h" +#include CMSIS_device_header +#include "cmsis_os2.h" +#ifdef RTE_VIO_BOARD +#include "cmsis_vio.h" +#endif +#ifdef RTE_Compiler_EventRecorder +#include "EventRecorder.h" +#endif + +#include "clock_config.h" +#include "board.h" +#include "pin_mux.h" +#include "fsl_iomuxc.h" +#include "fsl_dmamux.h" +#include "fsl_sai_edma.h" +#include "main.h" + +// Callbacks for LPUART1 Driver +uint32_t LPUART1_GetFreq (void) { return BOARD_BOOTCLOCKRUN_UART_CLK_ROOT; } +void LPUART1_InitPins (void) { /* Done in BOARD_InitDEBUG_UART function */ } +void LPUART1_DeinitPins(void) { /* Not implemented */ } + +// Callbacks for LPUART3 Driver +uint32_t LPUART3_GetFreq (void) { return BOARD_BOOTCLOCKRUN_UART_CLK_ROOT; } +void LPUART3_InitPins (void) { /* Done in BOARD_InitARDUINO_UART function */ } +void LPUART3_DeinitPins(void) { /* Not implemented */ } + +int main (void) { + edma_config_t DmaConfig; + + BOARD_InitBootPins(); + BOARD_InitBootClocks(); + BOARD_InitDebugConsole(); + + // GPIO_B1_10 is configured as ENET_REF_CLK + // Software Input On Field: Force input path of pad GPIO_B1_10 + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_10_ENET_REF_CLK, 1U); + + // Enable ENET_REF_CLK output mode + IOMUXC_EnableMode(IOMUXC_GPR, kIOMUXC_GPR_ENET1TxClkOutputDir, true); + + /* Enable SA1_MCLK output */ + IOMUXC_EnableMode (IOMUXC_GPR, kIOMUXC_GPR_SAI1MClkOutputDir, true); + + NVIC_SetPriority(ENET_IRQn, 8U); + NVIC_SetPriority(USDHC1_IRQn, 8U); + NVIC_SetPriority(LPUART3_IRQn, 8U); + + /* Initialize DMAMUX */ + DMAMUX_Init (DMAMUX); + + /* Initialize EDMA */ + EDMA_GetDefaultConfig (&DmaConfig); + EDMA_Init (DMA0, &DmaConfig); + + SystemCoreClockUpdate(); + +#ifdef RTE_VIO_BOARD + vioInit(); // Initialize Virtual I/O +#endif + +#if defined(RTE_Compiler_EventRecorder) && \ + (defined(__MICROLIB) || \ + !(defined(RTE_CMSIS_RTOS2_RTX5) || defined(RTE_CMSIS_RTOS2_FreeRTOS))) + EventRecorderInitialize(EventRecordAll, 1U); +#endif + + osKernelInitialize(); // Initialize CMSIS-RTOS2 + app_initialize(); // Initialize application + osKernelStart(); // Start thread execution + + for (;;) {} +} diff --git a/Platform_MIMXRT1064-EVK/main.h b/Platform_MIMXRT1064-EVK/main.h new file mode 100644 index 0000000..ab7c71d --- /dev/null +++ b/Platform_MIMXRT1064-EVK/main.h @@ -0,0 +1,34 @@ +/*--------------------------------------------------------------------------- + * Copyright (c) 2020-2021 Arm Limited (or its affiliates). + * All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * 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 MAIN_H__ +#define MAIN_H__ + +#include + +/* Prototypes */ +extern uint32_t LPUART1_GetFreq (void); +extern void LPUART1_InitPins (void); +extern void LPUART1_DeinitPins (void); +extern uint32_t LPUART3_GetFreq (void); +extern void LPUART3_InitPins (void); +extern void LPUART3_DeinitPins (void); + +extern void app_initialize (void); + +#endif diff --git a/Platform_MIMXRT1064-EVK/microspeech.MIMXRT1064-EVK.cprj b/Platform_MIMXRT1064-EVK/microspeech.MIMXRT1064-EVK.cprj new file mode 100644 index 0000000..10fe3d0 --- /dev/null +++ b/Platform_MIMXRT1064-EVK/microspeech.MIMXRT1064-EVK.cprj @@ -0,0 +1,213 @@ + + + + + + + Platform + + + + + + Platform is a simple CMSIS RTOS2 example skeleton + Platform + Apache 2.0 + + + + + + Board setup with interfaces + Board + BSD 3-Clause, Apache 2.0 + + + + + + + + + + + + + + Keil RTX5 open-source real-time operating system with CMSIS-RTOS v2 API + https://www2.keil.com/mdk5/cmsis/rtx + RTOS + Apache 2.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + .;../VSI/audio/include;../micro_speech/src + CODEC_WM8960_ENABLE;SKIP_SYSCLK_INIT;XIP_BOOT_HEADER_DCD_ENABLE=1;XIP_BOOT_HEADER_ENABLE=1;XIP_EXTERNAL_FLASH=1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Platform_MIMXRT1064-EVK/microspeech.c b/Platform_MIMXRT1064-EVK/microspeech.c new file mode 100644 index 0000000..743183d --- /dev/null +++ b/Platform_MIMXRT1064-EVK/microspeech.c @@ -0,0 +1,45 @@ +/*--------------------------------------------------------------------------- + * Copyright (c) 2020-2021 Arm Limited (or its affiliates). All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *---------------------------------------------------------------------------*/ + +#include "main.h" +#include "main_functions.h" + +#include "cmsis_os2.h" + +static const osThreadAttr_t app_main_attr = { + .stack_size = 4096U +}; + +/*--------------------------------------------------------------------------- + * Application main thread + *---------------------------------------------------------------------------*/ +static void app_main (void *argument) { + (void)argument; + + setup(); + for (;;) { + loop(); + } +} + +/*--------------------------------------------------------------------------- + * Application initialization + *---------------------------------------------------------------------------*/ +void app_initialize (void) { + osThreadNew(app_main, NULL, &app_main_attr); +} diff --git a/Platform_MIMXRT1064-EVK/microspeech.uvguix b/Platform_MIMXRT1064-EVK/microspeech.uvguix new file mode 100644 index 0000000..072eaf9 --- /dev/null +++ b/Platform_MIMXRT1064-EVK/microspeech.uvguix @@ -0,0 +1,1860 @@ + + + + -6.1 + +
### uVision Project, (C) Keil Software
+ + + + + + + + + + 38003 + Registers + 188 122 + + + 346 + Code Coverage + 1410 160 + + + 204 + Performance Analyzer + 1570 + + + + + + 35141 + Event Statistics + + 200 50 700 + + + 1506 + Symbols + + 106 106 106 + + + 1936 + Watch 1 + + 200 133 133 + + + 1937 + Watch 2 + + 200 133 133 + + + 1935 + Call Stack + Locals + + 200 133 133 + + + 2506 + Trace Data + + 75 135 130 95 70 230 200 150 + + + 466 + Source Browser + 500 + 300 + + + + + + + + 1 + 1 + 0 + 0 + -1 + + + + + + + 44 + 0 + 1 + + -1 + -1 + + + -1 + -1 + + + 1 + 338 + 2566 + 1398 + + + + 0 + + 60 + 010000000400000001000000010000000100000001000000000000000200000000000000010000000100000000000000280000002800000000000000 + + + + 0 + Build + + -1 + -1 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 440100004F000000700700001B010000 + + + 16 + 3C0A00005E000000F40D00002A010000 + + + + 1005 + 1005 + 1 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000660000003D01000052040000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 109 + 109 + 1 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000660000003D01000052040000 + + + 16 + 3C0A00005E000000B80B00008E030000 + + + + 1465 + 1465 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 000000001D03000070070000E9030000 + + + 16 + 3C0A00005E000000F40D00002A010000 + + + + 1466 + 1466 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000200300006D070000BC030000 + + + 16 + 3C0A00005E000000F40D00002A010000 + + + + 1467 + 1467 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000200300006D070000BC030000 + + + 16 + 3C0A00005E000000F40D00002A010000 + + + + 1468 + 1468 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000200300006D070000BC030000 + + + 16 + 3C0A00005E000000F40D00002A010000 + + + + 1506 + 1506 + 0 + 0 + 0 + 0 + 32767 + 0 + 16384 + 0 + + 16 + 33060000660000006D07000045010000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 1913 + 1913 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 47010000660000006D07000002010000 + + + 16 + 3C0A00005E000000F40D00002A010000 + + + + 1935 + 1935 + 0 + 0 + 0 + 0 + 32767 + 0 + 32768 + 0 + + 16 + 03000000200300006D070000D0030000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 1936 + 1936 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000200300006D070000BC030000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 1937 + 1937 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000200300006D070000BC030000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 1939 + 1939 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000200300006D070000BC030000 + + + 16 + 3C0A00005E000000F40D00002A010000 + + + + 1940 + 1940 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000200300006D070000BC030000 + + + 16 + 3C0A00005E000000F40D00002A010000 + + + + 1941 + 1941 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000200300006D070000BC030000 + + + 16 + 3C0A00005E000000F40D00002A010000 + + + + 1942 + 1942 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000200300006D070000BC030000 + + + 16 + 3C0A00005E000000F40D00002A010000 + + + + 195 + 195 + 1 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000660000003D01000052040000 + + + 16 + 3C0A00005E000000B80B00008E030000 + + + + 196 + 196 + 1 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000660000003D01000052040000 + + + 16 + 3C0A00005E000000B80B00008E030000 + + + + 197 + 197 + 1 + 0 + 0 + 0 + 32767 + 0 + 32768 + 0 + + 16 + 0000000083040000A40800003B050000 + + + 16 + 3C0A00005E000000F40D00002A010000 + + + + 198 + 198 + 0 + 0 + 0 + 0 + 32767 + 0 + 32768 + 0 + + 16 + 000000000903000070070000E9030000 + + + 16 + 3C0A00005E000000F40D00002A010000 + + + + 199 + 199 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000860400006D07000022050000 + + + 16 + 3C0A00005E000000F40D00002A010000 + + + + 203 + 203 + 0 + 0 + 0 + 0 + 32767 + 0 + 8192 + 0 + + 16 + 4401000063000000700700001B010000 + + + 16 + 3C0A00005E000000F40D00002A010000 + + + + 204 + 204 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 47010000660000006D07000002010000 + + + 16 + 3C0A00005E000000F40D00002A010000 + + + + 221 + 221 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 00000000000000000000000000000000 + + + 16 + 0A0000000A0000006E0000006E000000 + + + + 2506 + 2506 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 30060000630000007007000019030000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 2507 + 2507 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 000000001D03000070070000D5030000 + + + 16 + 3C0A00005E000000F40D00002A010000 + + + + 343 + 343 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 47010000660000006D07000002010000 + + + 16 + 3C0A00005E000000F40D00002A010000 + + + + 346 + 346 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 47010000660000006D07000002010000 + + + 16 + 3C0A00005E000000F40D00002A010000 + + + + 35141 + 35141 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 4401000063000000700700001B010000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 35824 + 35824 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 47010000660000006D07000002010000 + + + 16 + 3C0A00005E000000F40D00002A010000 + + + + 35885 + 35885 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D07000030020000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 35886 + 35886 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D07000030020000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 35887 + 35887 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D07000030020000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 35888 + 35888 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D07000030020000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 35889 + 35889 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D07000030020000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 35890 + 35890 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D07000030020000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 35891 + 35891 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D07000030020000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 35892 + 35892 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D07000030020000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 35893 + 35893 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D07000030020000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 35894 + 35894 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D07000030020000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 35895 + 35895 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D07000030020000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 35896 + 35896 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D07000030020000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 35897 + 35897 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D07000030020000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 35898 + 35898 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D07000030020000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 35899 + 35899 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D07000030020000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 35900 + 35900 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D07000030020000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 35901 + 35901 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D07000030020000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 35902 + 35902 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D07000030020000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 35903 + 35903 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D07000030020000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 35904 + 35904 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D07000030020000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 35905 + 35905 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D07000030020000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 38003 + 38003 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000660000003D010000D0030000 + + + 16 + 3C0A00005E000000B80B00008E030000 + + + + 38007 + 38007 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 0000000083040000700700003B050000 + + + 16 + 3C0A00005E000000F40D00002A010000 + + + + 436 + 436 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000860400006D07000022050000 + + + 16 + 3C0A00005E000000B80B00008E030000 + + + + 437 + 437 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000200300006D070000BC030000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 440 + 440 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000200300006D070000BC030000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 463 + 463 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000860400006D07000022050000 + + + 16 + 3C0A00005E000000B80B00008E030000 + + + + 466 + 466 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000860400006D07000022050000 + + + 16 + 3C0A00005E000000B80B00008E030000 + + + + 470 + 470 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 47010000660000006D07000002010000 + + + 16 + 3C0A00005E000000F40D00002A010000 + + + + 50000 + 50000 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D07000030020000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 50001 + 50001 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D07000030020000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 50002 + 50002 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D07000030020000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 50003 + 50003 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D07000030020000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 50004 + 50004 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D07000030020000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 50005 + 50005 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D07000030020000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 50006 + 50006 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D07000030020000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 50007 + 50007 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D07000030020000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 50008 + 50008 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D07000030020000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 50009 + 50009 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D07000030020000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 50010 + 50010 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D07000030020000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 50011 + 50011 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D07000030020000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 50012 + 50012 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D07000030020000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 50013 + 50013 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D07000030020000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 50014 + 50014 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D07000030020000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 50015 + 50015 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D07000030020000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 50016 + 50016 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D07000030020000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 50017 + 50017 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D07000030020000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 50018 + 50018 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D07000030020000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 50019 + 50019 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D07000030020000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 59392 + 59392 + 1 + 0 + 0 + 0 + 32767 + 0 + 8192 + 0 + + 16 + 0000000000000000D10300001C000000 + + + 16 + 0A0000000A0000006E0000006E000000 + + + + 59393 + 0 + 1 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 000000003B050000A40800004E050000 + + + 16 + 0A0000000A0000006E0000006E000000 + + + + 59399 + 59399 + 1 + 0 + 0 + 0 + 32767 + 0 + 8192 + 1 + + 16 + 000000001C000000E701000038000000 + + + 16 + 0A0000000A0000006E0000006E000000 + + + + 59400 + 59400 + 0 + 0 + 0 + 0 + 32767 + 0 + 8192 + 2 + + 16 + 00000000380000006F02000054000000 + + + 16 + 0A0000000A0000006E0000006E000000 + + + + 824 + 824 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000200300006D070000BC030000 + + + 16 + 3C0A00005E0000007C0B00006D010000 + + + + 3312 + 000000000B000000000000000020000000000000FFFFFFFFFFFFFFFF440100001B010000700700001F010000000000000100001004000000010000000000000000000000FFFFFFFF08000000CB00000057010000CC000000F08B00005A01000079070000D601000045890000FFFF02000B004354616262656450616E6500200000000000003C0A00005E000000F40D00002A010000440100004F000000700700001B0100000000000040280046080000000B446973617373656D626C7900000000CB00000001000000FFFFFFFFFFFFFFFF14506572666F726D616E636520416E616C797A6572000000005701000001000000FFFFFFFFFFFFFFFF14506572666F726D616E636520416E616C797A657200000000CC00000001000000FFFFFFFFFFFFFFFF0E4C6F67696320416E616C797A657200000000F08B000001000000FFFFFFFFFFFFFFFF0D436F646520436F766572616765000000005A01000001000000FFFFFFFFFFFFFFFF11496E737472756374696F6E205472616365000000007907000001000000FFFFFFFFFFFFFFFF0F53797374656D20416E616C797A657200000000D601000001000000FFFFFFFFFFFFFFFF104576656E742053746174697374696373000000004589000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFFCB00000001000000FFFFFFFFCB000000000000000040000000000000FFFFFFFFFFFFFFFF2C0600004F0000003006000019030000000000000200001004000000010000000000000000000000FFFFFFFF2B000000E2050000CA0900002D8C00002E8C00002F8C0000308C0000318C0000328C0000338C0000348C0000358C0000368C0000378C0000388C0000398C00003A8C00003B8C00003C8C00003D8C00003E8C00003F8C0000408C0000418C000050C3000051C3000052C3000053C3000054C3000055C3000056C3000057C3000058C3000059C300005AC300005BC300005CC300005DC300005EC300005FC3000060C3000061C3000062C3000063C30000018000400000000000003C0A00005E0000007C0B00006D010000300600004F000000700700001903000000000000404100462B0000000753796D626F6C7300000000E205000001000000FFFFFFFFFFFFFFFF0A5472616365204461746100000000CA09000001000000FFFFFFFFFFFFFFFF00000000002D8C000001000000FFFFFFFFFFFFFFFF00000000002E8C000001000000FFFFFFFFFFFFFFFF00000000002F8C000001000000FFFFFFFFFFFFFFFF0000000000308C000001000000FFFFFFFFFFFFFFFF0000000000318C000001000000FFFFFFFFFFFFFFFF0000000000328C000001000000FFFFFFFFFFFFFFFF0000000000338C000001000000FFFFFFFFFFFFFFFF0000000000348C000001000000FFFFFFFFFFFFFFFF0000000000358C000001000000FFFFFFFFFFFFFFFF0000000000368C000001000000FFFFFFFFFFFFFFFF0000000000378C000001000000FFFFFFFFFFFFFFFF0000000000388C000001000000FFFFFFFFFFFFFFFF0000000000398C000001000000FFFFFFFFFFFFFFFF00000000003A8C000001000000FFFFFFFFFFFFFFFF00000000003B8C000001000000FFFFFFFFFFFFFFFF00000000003C8C000001000000FFFFFFFFFFFFFFFF00000000003D8C000001000000FFFFFFFFFFFFFFFF00000000003E8C000001000000FFFFFFFFFFFFFFFF00000000003F8C000001000000FFFFFFFFFFFFFFFF0000000000408C000001000000FFFFFFFFFFFFFFFF0000000000418C000001000000FFFFFFFFFFFFFFFF000000000050C3000001000000FFFFFFFFFFFFFFFF000000000051C3000001000000FFFFFFFFFFFFFFFF000000000052C3000001000000FFFFFFFFFFFFFFFF000000000053C3000001000000FFFFFFFFFFFFFFFF000000000054C3000001000000FFFFFFFFFFFFFFFF000000000055C3000001000000FFFFFFFFFFFFFFFF000000000056C3000001000000FFFFFFFFFFFFFFFF000000000057C3000001000000FFFFFFFFFFFFFFFF000000000058C3000001000000FFFFFFFFFFFFFFFF000000000059C3000001000000FFFFFFFFFFFFFFFF00000000005AC3000001000000FFFFFFFFFFFFFFFF00000000005BC3000001000000FFFFFFFFFFFFFFFF00000000005CC3000001000000FFFFFFFFFFFFFFFF00000000005DC3000001000000FFFFFFFFFFFFFFFF00000000005EC3000001000000FFFFFFFFFFFFFFFF00000000005FC3000001000000FFFFFFFFFFFFFFFF000000000060C3000001000000FFFFFFFFFFFFFFFF000000000061C3000001000000FFFFFFFFFFFFFFFF000000000062C3000001000000FFFFFFFFFFFFFFFF000000000063C3000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFFE205000001000000FFFFFFFFE2050000000000000010000001000000FFFFFFFFFFFFFFFF400100004F000000440100006B040000010000000200001004000000010000000000000000000000FFFFFFFF05000000ED0300006D000000C3000000C400000073940000018000100000010000003C0A00005E0000007C0B00006D010000000000004F000000400100006B0400000000000040410056050000000750726F6A65637401000000ED03000001000000FFFFFFFFFFFFFFFF05426F6F6B73010000006D00000001000000FFFFFFFFFFFFFFFF0946756E6374696F6E7301000000C300000001000000FFFFFFFFFFFFFFFF0954656D706C6174657301000000C400000001000000FFFFFFFFFFFFFFFF09526567697374657273000000007394000001000000FFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000001000000FFFFFFFFED03000001000000FFFFFFFFED030000000000000080000000000000FFFFFFFFFFFFFFFF0000000005030000700700000903000000000000010000100400000001000000000000000000000000000000000000000000000001000000C6000000FFFFFFFF0F0000008F070000930700009407000095070000960700009007000091070000B5010000B801000038030000B9050000BA050000BB050000BC050000CB090000018000800000000000003C0A00005E0000007C0B00006D010000000000000903000070070000E903000000000000404100460F0000001343616C6C20537461636B202B204C6F63616C73000000008F07000001000000FFFFFFFFFFFFFFFF0755415254202331000000009307000001000000FFFFFFFFFFFFFFFF0755415254202332000000009407000001000000FFFFFFFFFFFFFFFF0755415254202333000000009507000001000000FFFFFFFFFFFFFFFF15446562756720287072696E74662920566965776572000000009607000001000000FFFFFFFFFFFFFFFF0757617463682031000000009007000001000000FFFFFFFFFFFFFFFF0757617463682032000000009107000001000000FFFFFFFFFFFFFFFF10547261636520457863657074696F6E7300000000B501000001000000FFFFFFFFFFFFFFFF0E4576656E7420436F756E7465727300000000B801000001000000FFFFFFFFFFFFFFFF09554C494E4B706C7573000000003803000001000000FFFFFFFFFFFFFFFF084D656D6F7279203100000000B905000001000000FFFFFFFFFFFFFFFF084D656D6F7279203200000000BA05000001000000FFFFFFFFFFFFFFFF084D656D6F7279203300000000BB05000001000000FFFFFFFFFFFFFFFF084D656D6F7279203400000000BC05000001000000FFFFFFFFFFFFFFFF105472616365204E617669676174696F6E00000000CB09000001000000FFFFFFFFFFFFFFFFFFFFFFFF0000000001000000000000000000000001000000FFFFFFFFB803000009030000BC030000E903000000000000020000000400000000000000000000000000000000000000000000000000000002000000C6000000FFFFFFFF8F07000001000000FFFFFFFF8F07000001000000C6000000000000000080000001000000FFFFFFFFFFFFFFFF000000006B040000A40800006F040000010000000100001004000000010000000000000000000000FFFFFFFF06000000C5000000C7000000B4010000D2010000CF01000077940000018000800000010000003C0A00005E000000F40D00002A010000000000006F040000A40800003B0500000000000040820056060000000C4275696C64204F757470757401000000C500000001000000FFFFFFFFFFFFFFFF0D46696E6420496E2046696C657300000000C700000001000000FFFFFFFFFFFFFFFF0A4572726F72204C69737400000000B401000001000000FFFFFFFFFFFFFFFF0E536F757263652042726F7773657200000000D201000001000000FFFFFFFFFFFFFFFF0E416C6C205265666572656E63657300000000CF01000001000000FFFFFFFFFFFFFFFF0742726F77736572000000007794000001000000FFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000001000000FFFFFFFFC500000001000000FFFFFFFFC5000000000000000000000000000000 + + + 59392 + File + + 2616 + 00200000010000002800FFFF01001100434D4643546F6F6C426172427574746F6E00E100000000000000000000000000000000000000000000000100000001000000018001E100000000000001000000000000000000000000000000000100000001000000018003E1000000000400020000000000000000000000000000000001000000010000000180CD7F0000000000000300000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018023E100000000040004000000000000000000000000000000000100000001000000018022E100000000040005000000000000000000000000000000000100000001000000018025E10000000004000600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001802BE10000000004000700000000000000000000000000000000010000000100000001802CE10000000004000800000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001807A8A0000000004000900000000000000000000000000000000010000000100000001807B8A0000000004000A00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180D3B00000000004000B000000000000000000000000000000000100000001000000018015B10000000004000C0000000000000000000000000000000001000000010000000180F4B00000000004000D000000000000000000000000000000000100000001000000018036B10000000004000E00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FF88000000000400460000000000000000000000000000000001000000010000000180FE880000000004004500000000000000000000000000000000010000000100000001800B810000000004001300000000000000000000000000000000010000000100000001800C810000000004001400000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180F0880000020000000F000000000000000000000000000000000100000001000000FFFF0100120043555646696E64436F6D626F427574746F6EE803000000000400000000000000000000000000000000000001000000010000009600000002002050000000000B536169547848616E646C65960000000000000004000B536169547848616E646C650A735F7361695278497372175341495F5472616E73666572527848616E646C65495251045443535200000000000000000000000000000000018024E10000000000001100000000000000000000000000000000010000000100000001800A810000000004001200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000FFFF01001500434D4643546F6F6C4261724D656E75427574746F6E2280000002000000150000002153746172742F53746F70202644656275672053657373696F6E094374726C2B46350000000000000000000000000100000001000000000000000000000001000000020021802280000000000000150000002153746172742F53746F70202644656275672053657373696F6E094374726C2B4635000000000000000000000000010000000100000000000000000000000100000000002180E0010000000000007500000021456E65726779204D6561737572656D656E742026776974686F75742044656275670000000000000000000000000100000001000000000000000000000001000000000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C488000000000400160000000000000000000000000000000001000000010000000180C988000000000400180000000000000000000000000000000001000000010000000180C788000000000000190000000000000000000000000000000001000000010000002180C8880000000000001700000027264B696C6C20416C6C20427265616B706F696E747320696E2043757272656E7420546172676574000000000000000000000000010000000100000000000000000000000100000003002180C8880000000000001700000027264B696C6C20416C6C20427265616B706F696E747320696E2043757272656E7420546172676574000000000000000000000000010000000100000000000000000000000100000000002180E50100000000000078000000264B696C6C20416C6C20427265616B706F696E747320696E204163746976652050726F6A656374000000000000000000000000010000000100000000000000000000000100000000002180E601000000000000790000002F4B696C6C20416C6C20427265616B706F696E747320696E204D756C74692D50726F6A65637420576F726B73706163650000000000000000000000000100000001000000000000000000000001000000000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000021804C010000020001001A0000000F2650726F6A6563742057696E646F77000000000000000000000000010000000100000000000000000000000100000008002180DD880000000000001A0000000750726F6A656374000000000000000000000000010000000100000000000000000000000100000000002180DC8B0000000000003A00000005426F6F6B73000000000000000000000000010000000100000000000000000000000100000000002180E18B0000000000003B0000000946756E6374696F6E73000000000000000000000000010000000100000000000000000000000100000000002180E28B000000000000400000000954656D706C6174657300000000000000000000000001000000010000000000000000000000010000000000218018890000000000003D0000000E536F757263652042726F777365720000000000000000000000000100000001000000000000000000000001000000000021800000000000000400FFFFFFFF00000000000000000000000000010000000100000000000000000000000100000000002180D988000000000000390000000C4275696C64204F7574707574000000000000000000000000010000000100000000000000000000000100000000002180E38B000000000000410000000B46696E64204F75747075740000000000000000000000000100000001000000000000000000000001000000000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FB7F0000000000001B000000000000000000000000000000000100000001000000000000000446696C65FF7F0000 + + + 1423 + 2800FFFF01001100434D4643546F6F6C426172427574746F6E00E1000000000000FFFFFFFF000100000000000000010000000000000001000000018001E1000000000000FFFFFFFF000100000000000000010000000000000001000000018003E1000000000000FFFFFFFF0001000000000000000100000000000000010000000180CD7F000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF000000000000000000010000000000000001000000018023E1000000000000FFFFFFFF000100000000000000010000000000000001000000018022E1000000000000FFFFFFFF000100000000000000010000000000000001000000018025E1000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001802BE1000000000000FFFFFFFF00010000000000000001000000000000000100000001802CE1000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001807A8A000000000000FFFFFFFF00010000000000000001000000000000000100000001807B8A000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180D3B0000000000000FFFFFFFF000100000000000000010000000000000001000000018015B1000000000000FFFFFFFF0001000000000000000100000000000000010000000180F4B0000000000000FFFFFFFF000100000000000000010000000000000001000000018036B1000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180FF88000000000000FFFFFFFF0001000000000000000100000000000000010000000180FE88000000000000FFFFFFFF00010000000000000001000000000000000100000001800B81000000000000FFFFFFFF00010000000000000001000000000000000100000001800C81000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180F088000000000000FFFFFFFF0001000000000000000100000000000000010000000180EE7F000000000000FFFFFFFF000100000000000000010000000000000001000000018024E1000000000000FFFFFFFF00010000000000000001000000000000000100000001800A81000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001802280000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180C488000000000000FFFFFFFF0001000000000000000100000000000000010000000180C988000000000000FFFFFFFF0001000000000000000100000000000000010000000180C788000000000000FFFFFFFF0001000000000000000100000000000000010000000180C888000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180DD88000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180FB7F000000000000FFFFFFFF000100000000000000010000000000000001000000 + + + 1423 + 2800FFFF01001100434D4643546F6F6C426172427574746F6E00E100000000000000000000000000000000000000000000000100000001000000018001E100000000000001000000000000000000000000000000000100000001000000018003E1000000000000020000000000000000000000000000000001000000010000000180CD7F0000000000000300000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018023E100000000000004000000000000000000000000000000000100000001000000018022E100000000000005000000000000000000000000000000000100000001000000018025E10000000000000600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001802BE10000000000000700000000000000000000000000000000010000000100000001802CE10000000000000800000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001807A8A0000000000000900000000000000000000000000000000010000000100000001807B8A0000000000000A00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180D3B00000000000000B000000000000000000000000000000000100000001000000018015B10000000000000C0000000000000000000000000000000001000000010000000180F4B00000000000000D000000000000000000000000000000000100000001000000018036B10000000000000E00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FF880000000000000F0000000000000000000000000000000001000000010000000180FE880000000000001000000000000000000000000000000000010000000100000001800B810000000000001100000000000000000000000000000000010000000100000001800C810000000000001200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180F088000000000000130000000000000000000000000000000001000000010000000180EE7F00000000000014000000000000000000000000000000000100000001000000018024E10000000000001500000000000000000000000000000000010000000100000001800A810000000000001600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018022800000000000001700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C488000000000000180000000000000000000000000000000001000000010000000180C988000000000000190000000000000000000000000000000001000000010000000180C7880000000000001A0000000000000000000000000000000001000000010000000180C8880000000000001B00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180DD880000000000001C00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FB7F0000000000001D000000000000000000000000000000000100000001000000 + + + + 59399 + Build + + 988 + 00200000010000001000FFFF01001100434D4643546F6F6C426172427574746F6ECF7F0000000004001C0000000000000000000000000000000001000000010000000180D07F0000000000001D000000000000000000000000000000000100000001000000018030800000000000001E000000000000000000000000000000000100000001000000FFFF01001500434D4643546F6F6C4261724D656E75427574746F6EC7040000000000006A0000000C4261746368204275696C2664000000000000000000000000010000000100000000000000000000000100000004000580C7040000000000006A0000000C4261746368204275696C266400000000000000000000000001000000010000000000000000000000010000000000058046070000000000006B0000000D42617463682052656275696C640000000000000000000000000100000001000000000000000000000001000000000005804707000000000000FFFFFFFF0B426174636820436C65616E0100000000000000000000000100000001000000000000000000000001000000000005809E8A0000000000001F0000000F4261746326682053657475702E2E2E000000000000000000000000010000000100000000000000000000000100000000000180D17F0000000004002000000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001804C8A0000000000002100000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000FFFF01001900434D4643546F6F6C426172436F6D626F426F78427574746F6EBA00000000000000000000000000000000000000000000000001000000010000009600000003002050000000000E4D494D585254313036342D45564B960000000000000001000E4D494D585254313036342D45564B000000000180EB880000000000002200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C07F000000000000230000000000000000000000000000000001000000010000000180B08A000000000400240000000000000000000000000000000001000000010000000180A8010000000000004E00000000000000000000000000000000010000000100000001807202000000000000530000000000000000000000000000000001000000010000000180BE010000000000005000000000000000000000000000000000010000000100000000000000054275696C64FF7F0000 + + + 583 + 1000FFFF01001100434D4643546F6F6C426172427574746F6ECF7F000000000000FFFFFFFF0001000000000000000100000000000000010000000180D07F000000000000FFFFFFFF00010000000000000001000000000000000100000001803080000000000000FFFFFFFF00010000000000000001000000000000000100000001809E8A000000000000FFFFFFFF0001000000000000000100000000000000010000000180D17F000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001804C8A000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001806680000000000000FFFFFFFF0001000000000000000100000000000000010000000180EB88000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180C07F000000000000FFFFFFFF0001000000000000000100000000000000010000000180B08A000000000000FFFFFFFF0001000000000000000100000000000000010000000180A801000000000000FFFFFFFF00010000000000000001000000000000000100000001807202000000000000FFFFFFFF0001000000000000000100000000000000010000000180BE01000000000000FFFFFFFF000100000000000000010000000000000001000000 + + + 583 + 1000FFFF01001100434D4643546F6F6C426172427574746F6ECF7F000000000000000000000000000000000000000000000001000000010000000180D07F00000000000001000000000000000000000000000000000100000001000000018030800000000000000200000000000000000000000000000000010000000100000001809E8A000000000000030000000000000000000000000000000001000000010000000180D17F0000000000000400000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001804C8A0000000000000500000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001806680000000000000060000000000000000000000000000000001000000010000000180EB880000000000000700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C07F000000000000080000000000000000000000000000000001000000010000000180B08A000000000000090000000000000000000000000000000001000000010000000180A8010000000000000A000000000000000000000000000000000100000001000000018072020000000000000B0000000000000000000000000000000001000000010000000180BE010000000000000C000000000000000000000000000000000100000001000000 + + + + 59400 + Debug + + 2373 + 00200000000000001900FFFF01001100434D4643546F6F6C426172427574746F6ECC880000000000002500000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018017800000000000002600000000000000000000000000000000010000000100000001801D800000000000002700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001801A800000000000002800000000000000000000000000000000010000000100000001801B80000000000000290000000000000000000000000000000001000000010000000180E57F0000000000002A00000000000000000000000000000000010000000100000001801C800000000000002B00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018000890000000000002C00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180E48B0000000000002D0000000000000000000000000000000001000000010000000180F07F0000000000002E0000000000000000000000000000000001000000010000000180E8880000000000003700000000000000000000000000000000010000000100000001803B010000000000002F0000000000000000000000000000000001000000010000000180BB8A00000000000030000000000000000000000000000000000100000001000000FFFF01001500434D4643546F6F6C4261724D656E75427574746F6E0E01000000000000310000000D57617463682057696E646F7773000000000000000000000000010000000100000000000000000000000100000003001380D88B00000000000031000000085761746368202631000000000000000000000000010000000100000000000000000000000100000000001380D98B00000000000031000000085761746368202632000000000000000000000000010000000100000000000000000000000100000000001380CE01000000000000FFFFFFFF0C576174636820416E63686F720100000000000000000000000100000001000000000000000000000001000000000013800F01000000000000320000000E4D656D6F72792057696E646F7773000000000000000000000000010000000100000000000000000000000100000004001380D28B00000000000032000000094D656D6F7279202631000000000000000000000000010000000100000000000000000000000100000000001380D38B00000000000032000000094D656D6F7279202632000000000000000000000000010000000100000000000000000000000100000000001380D48B00000000000032000000094D656D6F7279202633000000000000000000000000010000000100000000000000000000000100000000001380D58B00000000000032000000094D656D6F72792026340000000000000000000000000100000001000000000000000000000001000000000013801001000000000000330000000E53657269616C2057696E646F77730000000000000000000000000100000001000000000000000000000001000000040013809307000000000000330000000855415254202326310000000000000000000000000100000001000000000000000000000001000000000013809407000000000000330000000855415254202326320000000000000000000000000100000001000000000000000000000001000000000013809507000000000000330000000855415254202326330000000000000000000000000100000001000000000000000000000001000000000013809607000000000000330000001626446562756720287072696E746629205669657765720000000000000000000000000100000001000000000000000000000001000000000013803C010000000000007200000010416E616C797369732057696E646F7773000000000000000000000000010000000100000000000000000000000100000004001380658A000000000000340000000F264C6F67696320416E616C797A6572000000000000000000000000010000000100000000000000000000000100000000001380DC7F0000000000003E0000001526506572666F726D616E636520416E616C797A6572000000000000000000000000010000000100000000000000000000000100000000001380E788000000000000380000000E26436F646520436F766572616765000000000000000000000000010000000100000000000000000000000100000000001380CD01000000000000FFFFFFFF0F416E616C7973697320416E63686F7201000000000000000000000001000000010000000000000000000000010000000000138053010000000000003F0000000D54726163652057696E646F77730000000000000000000000000100000001000000000000000000000001000000010013805401000000000000FFFFFFFF115472616365204D656E7520416E63686F720100000000000000000000000100000001000000000000000000000001000000000013802901000000000000350000001553797374656D205669657765722057696E646F77730000000000000000000000000100000001000000000000000000000001000000010013804B01000000000000FFFFFFFF1453797374656D2056696577657220416E63686F720100000000000000000000000100000001000000000000000000000001000000000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000013800189000000000000360000000F26546F6F6C626F782057696E646F7700000000000000000000000001000000010000000000000000000000010000000300138044C5000000000000FFFFFFFF0E5570646174652057696E646F77730100000000000000000000000100000001000000000000000000000001000000000013800000000000000400FFFFFFFF000000000000000000000000000100000001000000000000000000000001000000000013805B01000000000000FFFFFFFF12546F6F6C626F78204D656E75416E63686F720100000000000000000000000100000001000000000000000000000001000000000000000000054465627567FF7F0000 + + + 898 + 1900FFFF01001100434D4643546F6F6C426172427574746F6ECC88000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001801780000000000000FFFFFFFF00010000000000000001000000000000000100000001801D80000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001801A80000000000000FFFFFFFF00010000000000000001000000000000000100000001801B80000000000000FFFFFFFF0001000000000000000100000000000000010000000180E57F000000000000FFFFFFFF00010000000000000001000000000000000100000001801C80000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001800089000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180E48B000000000000FFFFFFFF0001000000000000000100000000000000010000000180F07F000000000000FFFFFFFF0001000000000000000100000000000000010000000180E888000000000000FFFFFFFF00010000000000000001000000000000000100000001803B01000000000000FFFFFFFF0001000000000000000100000000000000010000000180BB8A000000000000FFFFFFFF0001000000000000000100000000000000010000000180D88B000000000000FFFFFFFF0001000000000000000100000000000000010000000180D28B000000000000FFFFFFFF00010000000000000001000000000000000100000001809307000000000000FFFFFFFF0001000000000000000100000000000000010000000180658A000000000000FFFFFFFF0001000000000000000100000000000000010000000180C18A000000000000FFFFFFFF0001000000000000000100000000000000010000000180EE8B000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001800189000000000000FFFFFFFF000100000000000000010000000000000001000000 + + + 898 + 1900FFFF01001100434D4643546F6F6C426172427574746F6ECC880000000000000000000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018017800000000000000100000000000000000000000000000000010000000100000001801D800000000000000200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001801A800000000000000300000000000000000000000000000000010000000100000001801B80000000000000040000000000000000000000000000000001000000010000000180E57F0000000000000500000000000000000000000000000000010000000100000001801C800000000000000600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018000890000000000000700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180E48B000000000000080000000000000000000000000000000001000000010000000180F07F000000000000090000000000000000000000000000000001000000010000000180E8880000000000000A00000000000000000000000000000000010000000100000001803B010000000000000B0000000000000000000000000000000001000000010000000180BB8A0000000000000C0000000000000000000000000000000001000000010000000180D88B0000000000000D0000000000000000000000000000000001000000010000000180D28B0000000000000E000000000000000000000000000000000100000001000000018093070000000000000F0000000000000000000000000000000001000000010000000180658A000000000000100000000000000000000000000000000001000000010000000180C18A000000000000110000000000000000000000000000000001000000010000000180EE8B0000000000001200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180018900000000000013000000000000000000000000000000000100000001000000 + + + + 0 + 2560 + 1440 + + + + +
diff --git a/Platform_MIMXRT1064-EVK/microspeech.uvoptx b/Platform_MIMXRT1064-EVK/microspeech.uvoptx new file mode 100644 index 0000000..e94fdef --- /dev/null +++ b/Platform_MIMXRT1064-EVK/microspeech.uvoptx @@ -0,0 +1,756 @@ + + + + 1.0 + +
### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt;*.h;*.inc;*.md + *.plm + *.cpp;*.cc;*.cxx + 0 + + + + 0 + 0 + + + + MIMXRT1064-EVK + 0x4 + ARM-ADS + + 24000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\Listings\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 8 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 3 + + + + + + + + + + + BIN\CMSIS_AGDI.dll + + + + 0 + EVENTREC_CNF + -l0 -a1 -s0 -f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + DLGTARM + (1010=-1,-1,-1,-1,0)(6017=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(6016=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + 0 + DLGUARM + + + + 0 + UL2CM3 + UL2CM3(-S0 -C0 -P0 ) -FN1 -FC8000 -FD20000000 -FF0MIMXRT1064_QSPI_4KB_SEC -FL0400000 -FS070000000 -FP0($$Device:MIMXRT1064DVL6A$arm\MIMXRT1064_QSPI_4KB_SEC.FLM) + + + 0 + CMSIS_AGDI + -X"Any" -UAny -O206 -S8 -C0 -P00000000 -N00("ARM CoreSight SW-DP") -D00(0BD11477) -L00(0) -TO65554 -TC600000000 -TT600000000 -TP20 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC8000 -FN1 -FF0MIMXRT1064_QSPI_4KB_SEC.FLM -FS070000000 -FL0400000 -FP0($$Device:MIMXRT1064DVL6A$arm\MIMXRT1064_QSPI_4KB_SEC.FLM) + + + + + C:\ARM\PACK\ARM\CMSIS\5.8.0\CMSIS\Driver\VIO\cmsis_vio.scvd + ARM.CMSIS.5.8.0 + 1 + + + C:\ARM\PACK\ARM\CMSIS\5.8.0\CMSIS\RTOS2\RTX\RTX5.scvd + ARM.CMSIS.5.8.0 + 1 + + + C:\ARM\PACK\Keil\ARM_Compiler\1.6.3\EventRecorder.scvd + Keil.ARM_Compiler.1.6.3 + 1 + + + 0 + + + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + 1 + 1 + 0 + 2 + 10000000 + + + + + + App + 0 + 0 + 0 + 0 + + 1 + 1 + 1 + 0 + 0 + 0 + .\microspeech.c + microspeech.c + 0 + 0 + + + + + Board + 0 + 0 + 0 + 0 + + 2 + 2 + 1 + 0 + 0 + 0 + .\main.c + main.c + 0 + 0 + + + 2 + 3 + 5 + 0 + 0 + 0 + .\main.h + main.h + 0 + 0 + + + + + Board IO + 0 + 0 + 0 + 0 + + 3 + 4 + 1 + 0 + 0 + 0 + .\Board_IO\retarget_stdio.c + retarget_stdio.c + 0 + 0 + + + + + Driver + 0 + 0 + 0 + 0 + + 4 + 5 + 1 + 0 + 0 + 0 + .\Driver_Audio\Audio_MIMXRT1064-EVK.c + Audio_MIMXRT1064-EVK.c + 0 + 0 + + + + + MCUXpresso + 0 + 0 + 0 + 0 + + 5 + 6 + 5 + 0 + 0 + 0 + .\MIMXRT1064-EVK.mex + MIMXRT1064-EVK.mex + 0 + 0 + + + + + Documentation + 0 + 0 + 0 + 0 + + 6 + 7 + 5 + 0 + 0 + 0 + .\README.md + README.md + 0 + 0 + + + + + TF_micro_frontend + 0 + 0 + 0 + 0 + + 7 + 8 + 8 + 0 + 0 + 0 + ..\micro_speech\src\microfrontend\lib\fft.cc + fft.cc + 0 + 0 + + + 7 + 9 + 8 + 0 + 0 + 0 + ..\micro_speech\src\microfrontend\lib\fft_util.cc + fft_util.cc + 0 + 0 + + + 7 + 10 + 1 + 0 + 0 + 0 + ..\micro_speech\src\microfrontend\lib\filterbank.c + filterbank.c + 0 + 0 + + + 7 + 11 + 1 + 0 + 0 + 0 + ..\micro_speech\src\microfrontend\lib\filterbank_util.c + filterbank_util.c + 0 + 0 + + + 7 + 12 + 1 + 0 + 0 + 0 + ..\micro_speech\src\microfrontend\lib\frontend.c + frontend.c + 0 + 0 + + + 7 + 13 + 1 + 0 + 0 + 0 + ..\micro_speech\src\microfrontend\lib\frontend_util.c + frontend_util.c + 0 + 0 + + + 7 + 14 + 1 + 0 + 0 + 0 + ..\micro_speech\src\microfrontend\lib\log_lut.c + log_lut.c + 0 + 0 + + + 7 + 15 + 1 + 0 + 0 + 0 + ..\micro_speech\src\microfrontend\lib\log_scale.c + log_scale.c + 0 + 0 + + + 7 + 16 + 1 + 0 + 0 + 0 + ..\micro_speech\src\microfrontend\lib\log_scale_util.c + log_scale_util.c + 0 + 0 + + + 7 + 17 + 1 + 0 + 0 + 0 + ..\micro_speech\src\microfrontend\lib\noise_reduction.c + noise_reduction.c + 0 + 0 + + + 7 + 18 + 1 + 0 + 0 + 0 + ..\micro_speech\src\microfrontend\lib\noise_reduction_util.c + noise_reduction_util.c + 0 + 0 + + + 7 + 19 + 1 + 0 + 0 + 0 + ..\micro_speech\src\microfrontend\lib\pcan_gain_control.c + pcan_gain_control.c + 0 + 0 + + + 7 + 20 + 1 + 0 + 0 + 0 + ..\micro_speech\src\microfrontend\lib\pcan_gain_control_util.c + pcan_gain_control_util.c + 0 + 0 + + + 7 + 21 + 1 + 0 + 0 + 0 + ..\micro_speech\src\microfrontend\lib\window.c + window.c + 0 + 0 + + + 7 + 22 + 1 + 0 + 0 + 0 + ..\micro_speech\src\microfrontend\lib\window_util.c + window_util.c + 0 + 0 + + + + + TF_micro_features + 0 + 0 + 0 + 0 + + 8 + 23 + 8 + 0 + 0 + 0 + ..\micro_speech\src\micro_features\micro_features_generator.cc + micro_features_generator.cc + 0 + 0 + + + 8 + 24 + 8 + 0 + 0 + 0 + ..\micro_speech\src\micro_features\micro_model_settings.cc + micro_model_settings.cc + 0 + 0 + + + 8 + 25 + 8 + 0 + 0 + 0 + ..\micro_speech\src\micro_features\model.cc + model.cc + 0 + 0 + + + 8 + 26 + 8 + 0 + 0 + 0 + ..\micro_speech\src\micro_features\no_micro_features_data.cc + no_micro_features_data.cc + 0 + 0 + + + 8 + 27 + 8 + 0 + 0 + 0 + ..\micro_speech\src\micro_features\yes_micro_features_data.cc + yes_micro_features_data.cc + 0 + 0 + + + + + TF_main + 0 + 0 + 0 + 0 + + 9 + 28 + 8 + 0 + 0 + 0 + ..\micro_speech\src\audio_provider.cc + audio_provider.cc + 0 + 0 + + + 9 + 29 + 8 + 0 + 0 + 0 + ..\micro_speech\src\command_responder.cc + command_responder.cc + 0 + 0 + + + 9 + 30 + 8 + 0 + 0 + 0 + ..\micro_speech\src\feature_provider.cc + feature_provider.cc + 0 + 0 + + + 9 + 31 + 8 + 0 + 0 + 0 + ..\micro_speech\src\main.cc + main.cc + 0 + 0 + + + 9 + 32 + 8 + 0 + 0 + 0 + ..\micro_speech\src\main_functions.cc + main_functions.cc + 0 + 0 + + + 9 + 33 + 8 + 0 + 0 + 0 + ..\micro_speech\src\recognize_commands.cc + recognize_commands.cc + 0 + 0 + + + + + ::Board Support + 0 + 0 + 0 + 1 + + + + ::CMSIS + 0 + 0 + 0 + 1 + + + + ::CMSIS Driver + 0 + 0 + 0 + 1 + + + + ::Compiler + 0 + 0 + 0 + 1 + + + + ::Data Exchange + 0 + 0 + 0 + 1 + + + + ::Data Processing + 0 + 0 + 0 + 1 + + + + ::Device + 0 + 0 + 0 + 1 + + + + ::Machine Learning + 0 + 0 + 0 + 1 + + +
diff --git a/Platform_MIMXRT1064-EVK/microspeech.uvprojx b/Platform_MIMXRT1064-EVK/microspeech.uvprojx new file mode 100644 index 0000000..a957541 --- /dev/null +++ b/Platform_MIMXRT1064-EVK/microspeech.uvprojx @@ -0,0 +1,1818 @@ + + + + 2.1 + +
### uVision Project, (C) Keil Software
+ + + + MIMXRT1064-EVK + 0x4 + ARM-ADS + 6160000::V6.16::ARMCLANG + 1 + + + MIMXRT1064DVL6A + NXP + NXP.MIMXRT1064_DFP.13.0.0 + https://mcuxpresso.nxp.com/cmsis_pack/repo/ + IRAM(0x20000000,0x020000) IRAM2(0x00000000,0x020000) IROM(0x70000000,0x400000) XRAM(0x20200000,0x0c0000) CPUTYPE("Cortex-M7") FPU3(DFPU) CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC8000 -FN1 -FF0MIMXRT1064_QSPI_4KB_SEC -FS070000000 -FL0400000 -FP0($$Device:MIMXRT1064DVL6A$arm\MIMXRT1064_QSPI_4KB_SEC.FLM)) + 0 + $$Device:MIMXRT1064DVL6A$fsl_device_registers.h + + + + + + + + + + $$Device:MIMXRT1064DVL6A$MIMXRT1064.xml + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\Objects\ + microspeech + 1 + 0 + 0 + 1 + 1 + .\Listings\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + 1 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -REMAP -MPU + DCM.DLL + -pCM7 + SARMCM3.DLL + -MPU + TCM.DLL + -pCM7 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2CM3.DLL + "" () + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M7" + + 1 + 0 + 0 + 1 + 1 + 1 + 0 + 1 + 0 + 0 + 1 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 4 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 1 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x20000 + + + 1 + 0x70000000 + 0x400000 + + + 1 + 0x20200000 + 0xc0000 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x70000000 + 0x400000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x20200000 + 0xc0000 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x20000 + + + 0 + 0x0 + 0x20000 + + + + + + 1 + 6 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 0 + 1 + 0 + 0 + 3 + 3 + 1 + 1 + 0 + 0 + 0 + + + CODEC_WM8960_ENABLE, SKIP_SYSCLK_INIT, XIP_EXTERNAL_FLASH=1, XIP_BOOT_HEADER_ENABLE=1, XIP_BOOT_HEADER_DCD_ENABLE=1 + + .;..\VSI\audio\include;..\micro_speech\src + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + + + + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + + + + .\RTE\Device\MIMXRT1064DVL6A\MIMXRT1064xxxxx_flexspi_nor.scf + + + --predefine="-DXIP_BOOT_HEADER_ENABLE=1" + + 6314,6329,6439 + + + + + + App + + + microspeech.c + 1 + .\microspeech.c + + + + + Board + + + main.c + 1 + .\main.c + + + main.h + 5 + .\main.h + + + + + Board IO + + + retarget_stdio.c + 1 + .\Board_IO\retarget_stdio.c + + + + + Driver + + + Audio_MIMXRT1064-EVK.c + 1 + .\Driver_Audio\Audio_MIMXRT1064-EVK.c + + + + + MCUXpresso + + + MIMXRT1064-EVK.mex + 5 + .\MIMXRT1064-EVK.mex + + + + + Documentation + + + README.md + 5 + .\README.md + + + + + TF_micro_frontend + + + fft.cc + 8 + ..\micro_speech\src\microfrontend\lib\fft.cc + + + fft_util.cc + 8 + ..\micro_speech\src\microfrontend\lib\fft_util.cc + + + filterbank.c + 1 + ..\micro_speech\src\microfrontend\lib\filterbank.c + + + filterbank_util.c + 1 + ..\micro_speech\src\microfrontend\lib\filterbank_util.c + + + frontend.c + 1 + ..\micro_speech\src\microfrontend\lib\frontend.c + + + frontend_util.c + 1 + ..\micro_speech\src\microfrontend\lib\frontend_util.c + + + log_lut.c + 1 + ..\micro_speech\src\microfrontend\lib\log_lut.c + + + log_scale.c + 1 + ..\micro_speech\src\microfrontend\lib\log_scale.c + + + log_scale_util.c + 1 + ..\micro_speech\src\microfrontend\lib\log_scale_util.c + + + noise_reduction.c + 1 + ..\micro_speech\src\microfrontend\lib\noise_reduction.c + + + noise_reduction_util.c + 1 + ..\micro_speech\src\microfrontend\lib\noise_reduction_util.c + + + pcan_gain_control.c + 1 + ..\micro_speech\src\microfrontend\lib\pcan_gain_control.c + + + pcan_gain_control_util.c + 1 + ..\micro_speech\src\microfrontend\lib\pcan_gain_control_util.c + + + window.c + 1 + ..\micro_speech\src\microfrontend\lib\window.c + + + window_util.c + 1 + ..\micro_speech\src\microfrontend\lib\window_util.c + + + + + TF_micro_features + + + micro_features_generator.cc + 8 + ..\micro_speech\src\micro_features\micro_features_generator.cc + + + micro_model_settings.cc + 8 + ..\micro_speech\src\micro_features\micro_model_settings.cc + + + model.cc + 8 + ..\micro_speech\src\micro_features\model.cc + + + no_micro_features_data.cc + 8 + ..\micro_speech\src\micro_features\no_micro_features_data.cc + + + yes_micro_features_data.cc + 8 + ..\micro_speech\src\micro_features\yes_micro_features_data.cc + + + + + TF_main + + + audio_provider.cc + 8 + ..\micro_speech\src\audio_provider.cc + + + command_responder.cc + 8 + ..\micro_speech\src\command_responder.cc + + + feature_provider.cc + 8 + ..\micro_speech\src\feature_provider.cc + + + main.cc + 8 + ..\micro_speech\src\main.cc + + + 2 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + + + + main_functions.cc + 8 + ..\micro_speech\src\main_functions.cc + + + recognize_commands.cc + 8 + ..\micro_speech\src\recognize_commands.cc + + + + + ::Board Support + + + 0 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + + + + + + + + + + + + ::CMSIS + + + 0 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + + + + + + + + + + + + ::CMSIS Driver + + + ::Compiler + + + 0 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + + + + + + + + + + + + ::Data Exchange + + + ::Data Processing + + + ::Device + + + 0 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + + + + + + + + + + + + ::Machine Learning + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ETH_PHY_REF_CLK_50M=1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ETH_PHY_REF_CLK_50M=1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SDK_DEBUGCONSOLE=1 __MCUXPRESSO + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + RTE\Board_Support\MIMXRT1064DVL6A\board.c + + + + + + + + RTE\Board_Support\MIMXRT1064DVL6A\board.h + + + + + + + + RTE\Board_Support\MIMXRT1064DVL6A\clock_config.c + + + + + + + + RTE\Board_Support\MIMXRT1064DVL6A\clock_config.h + + + + + + + + RTE\Board_Support\MIMXRT1064DVL6A\dcd.c + + + + + + + + RTE\Board_Support\MIMXRT1064DVL6A\dcd.h + + + + + + + + RTE\Board_Support\MIMXRT1064DVL6A\peripherals.c + + + + + + + + RTE\Board_Support\MIMXRT1064DVL6A\peripherals.h + + + + + + + + RTE\Board_Support\MIMXRT1064DVL6A\pin_mux.c + + + + + + + + RTE\Board_Support\MIMXRT1064DVL6A\pin_mux.h + + + + + + + + RTE\CMSIS\RTX_Config.c + + + + + + + + RTE\CMSIS\RTX_Config.h + + + + + + + + RTE\Compiler\EventRecorderConf.h + + + + + + + + RTE\Device\MIMXRT1064DVL6A\MIMXRT1064xxxxx_flexspi_nor.scf + + + + + + + + RTE\Device\MIMXRT1064DVL6A\MIMXRT1064xxxxx_flexspi_nor_sdram.scf + + + + + + + + RTE\Device\MIMXRT1064DVL6A\MIMXRT1064xxxxx_ram.scf + + + + + + + + RTE\Device\MIMXRT1064DVL6A\MIMXRT1064xxxxx_sdram.scf + + + + + + + + RTE\Device\MIMXRT1064DVL6A\MIMXRT1064xxxxx_sdram_txt.scf + + + + + + + + RTE\Device\MIMXRT1064DVL6A\RTE_Device.h + + + + + + + + RTE\Machine_Learning\debug_log.cc + + + + + + + + RTE\Machine_Learning\micro_time.cc + + + + + + + + RTE\Machine_Learning\system_setup.cc + + + + + + + + + + + + + Platform + Layer, CMSIS RTOS + 1 + + + App + Platform is a simple CMSIS RTOS2 example skeleton + Platform + Platform + Apache 2.0 + App + + + + + + Board + Board setup with interfaces + Board, MIMXRT1064-EVK + Board + BSD 3-Clause, Apache 2.0 + 1 + MIMXRT1064-EVK + + + + + + + + + + + + + + RTOS + Keil RTX5 open-source real-time operating system with CMSIS-RTOS v2 API + RTOS + RTOS + Apache 2.0 + RTX + + + + https://www2.keil.com/mdk5/cmsis/rtx + + + + + 3 + Source + App + + + 1 + NXP::Board Support:SDK Project Template:project_template + Board + + + 1 + ARM::CMSIS:CORE + Board + + + 1 + ARM::CMSIS:RTOS2:Keil RTX5 + RTOS + + + 1 + Keil::CMSIS Driver:VIO:Board + Board + + + 1 + Keil.ARM Compiler::Compiler:Event Recorder + Board + + + 1 + NXP::Device:CMSIS:MIMXRT1064_header + Board + + + 1 + NXP::Device:SDK Drivers:clock + Board + + + 1 + NXP::Device:SDK Drivers:common + Board + + + 1 + NXP::Device:SDK Drivers:dmamux + Board + + + 1 + NXP::Device:SDK Drivers:edma + Board + + + 1 + NXP::Device:SDK Drivers:gpio + Board + + + 1 + NXP::Device:SDK Drivers:iomuxc + Board + + + 1 + NXP::Device:SDK Drivers:lists + Board + + + 1 + NXP::Device:SDK Drivers:lpuart + Board + + + 1 + NXP::Device:SDK Drivers:lpuart_adapter + Board + + + 1 + NXP::Device:SDK Drivers:lpuart_edma + Board + + + 1 + NXP::Device:SDK Drivers:xip_board + Board + + + 1 + NXP::Device:SDK Drivers:xip_device + Board + + + 1 + NXP::Device:SDK Project Template:RTE_Device + Board + + + 1 + NXP::Device:SDK Utilities:debug_console + Board + + + 1 + NXP::Device:SDK Utilities:serial_manager + Board + + + 1 + NXP::Device:SDK Utilities:serial_manager_uart + Board + + + 1 + NXP::Device:Startup:MIMXRT1064_startup + Board + + + 2 + .\clock_freq.h + Board + + + 2 + .\microspeech.c + App + + + 2 + .\main.c + Board + + + 2 + .\main.h + Board + + + 2 + .\evkmimxrt1064_flexspi_nor.ini + Board + + + 2 + .\MIMXRT1064-EVK.mex + Board + + + 2 + .\retarget_stdio.c + Board + + + 1 + Keil.ARM Compiler::Compiler:I/O:STDERR + Board + + + 1 + Keil.ARM Compiler::Compiler:I/O:STDIN + Board + + + 1 + Keil.ARM Compiler::Compiler:I/O:STDOUT + Board + + + 1 + NXP::Device:SDK Drivers:enet + Board + + + 1 + Keil::CMSIS Driver:Ethernet MAC + Board + + + 1 + Keil::CMSIS Driver:Ethernet PHY:KSZ8081RNA + Board + + + 1 + Keil::CMSIS Driver:MCI + Board + + + 1 + NXP::Device:SDK Drivers:sdhc + Board + + + 2 + .\Board_IO\retarget_stdio.c + Board + + + 1 + NXP::Device:CMSIS:MIMXRT1064_system + Board + + + 1 + NXP::CMSIS Driver:USART:lpuart_cmsis + Board + + + 2 + .\README.md + App + + + + +
diff --git a/README.md b/README.md new file mode 100644 index 0000000..b397dad --- /dev/null +++ b/README.md @@ -0,0 +1,78 @@ + +# Arm Virtual Hardware Targets - Example + +## Micro speech for TensorFlow Lite + +Derived from [Micro speech example](https://github.com/MDK-Packs/tensorflow-pack/tree/main/examples/micro_speech) +for [TensorFlow Lite for Microcontrollers](https://www.tensorflow.org/lite/microcontrollers). + +### Prerequisites + - toolchain (IDE): + - [MDK Microcontroller Development Kit](https://www.keil.com/mdk5) + - toolchain (alternative: command-line tools): + - [CMSIS-Build](https://github.com/ARM-software/CMSIS_5/releases/download/5.7.0/cbuild_install.0.10.2.sh) + - Fast Models: + - FVP model for Corstone-300 MPS3 with VSI (example for FVP with user Python script) + - [FVP model for Corstone-300 MPS3](https://developer.arm.com/tools-and-software/open-source-software/arm-platforms-software/arm-ecosystem-fvps) + (example for FVP) + - [Python 3](https://www.python.org/downloads/) (example for FVP with user Python script) + - additional CMSIS-Packs (not indexed and therefore not available via Pack Installer): + - [tensorflow.flatbuffers.0.1.20210719](https://github.com/MDK-Packs/tensorflow-pack/releases/download/preview-0.3/tensorflow.flatbuffers.0.1.20210719.pack) + - [kissfft.0.1.20210719](https://github.com/MDK-Packs/tensorflow-pack/releases/download/preview-0.3/tensorflow.kissfft.0.1.20210719.pack) + - [tensorflow.ruy.0.1.20210719](https://github.com/MDK-Packs/tensorflow-pack/releases/download/preview-0.3/tensorflow.ruy.0.1.20210719.pack) + - [tensorflow.gemmlowp.0.0.1.20210719](https://github.com/MDK-Packs/tensorflow-pack/releases/download/preview-0.3/tensorflow.gemmlowp.0.0.1.20210719.pack) + - [tensorflow.tensorflow-lite-micro.0.2.20210719](https://github.com/MDK-Packs/tensorflow-pack/releases/download/preview-0.3/tensorflow.tensorflow-lite-micro.0.2.20210719.pack) + - [Arm.ethos-u-core-driver.0.1.20210719](https://github.com/MDK-Packs/tensorflow-pack/releases/download/preview-0.3/Arm.ethos-u-core-driver.0.1.20210719.pack) (FVP with Ethos-U55) + +## Micro speech for FVP (Fixed Virtual Platform) for Corstone SSE-300 with Ethos-U55 + +Project directory: `./Platform_FVP_Corstone_SSE-300_Ethos-U55/` + +Example has the following targets: + - `Example`: FVP with Python interface (VSI) with audio test data provided through user Python script + - Runs on the special Corstone SSE-300 Ethos-U55 FVP with Python interface providing Virtual Streaming Interface (VSI).
+ It is required to install the model executable and binaries in order to run this example.
+ Expected installation directory on Windows: `C:\Program Files\Arm\VHT\models\Win64_VC2017`
+ If installed in a different directory then this needs to be reflected: + - in uVision project (Options for Target - Debug - Settings for Models Armv8-M Debugger) when running with MDK or + - in script `run_example.cmd` when running standalone + - Audio test data is provided by Python script `./VSI/audio/python/arm_vsi0.py` from WAVE file `test.wav` which contains keywords 'Yes' and 'No' alternating three times. + - Build example with MDK using uVision project `microspeech.uvprojx` target `Example` or CMSIS-Build using `microspeech.Example.cprj` project. + - Run example with MDK or standalone with script `run_example.cmd`. + - When running the example the audio data is processed and any detected keywords are output to the terminal: + ``` + Heard yes (152) @1100ms + Heard no (141) @5500ms + Heard yes (147) @9100ms + Heard no (148) @13600ms + Heard yes (147) @17100ms + Heard no (148) @21600ms + ``` + - `Example Test`: internal test for Example + - `Audio Provider Mock`: public FVP with audio test data embedded in code + - Runs on the public Corstone SSE-300 Ethos-U55 FVP. + - Audio test data is embedded in the test code and contains keywords 'Yes' and 'No' alternating indefinitely. + - Build example with MDK using uVision project `microspeech.uvprojx` target `Audio Provider Mock` or CMSIS-Build using `microspeech.Audio_Provider_Mock.cprj` project. + - Run example with MDK or standalone. + - When running the example the audio data is processed and any detected keywords are output to the terminal: + ``` + Heard silence (149) @400ms + Heard yes (158) @1200ms + Heard no (143) @5600ms + Heard yes (149) @9100ms + Heard no (142) @13600ms + Heard yes (149) @17100ms + Heard no (142) @21600ms + ``` + - `Audio Provider Mock Test`: internal test for Audio Provider Mock + +### Micro speech for MIMXRT1064-EVK board + +Project directory: `./Platform_MIMXRT1064-EVK/` + +This example shows how to run a voice recognition model that can recognize 2 keywords, "yes" and "no", +from boards built-in microphone. Recognized keywords are written to the terminal. + + - Build example with MDK using uVision project `microspeech.uvprojx` or CMSIS-Build using `microspeech.MIMXRT1064-EVK.cprj` project. + - Program and run the example with MDK or use Drag-and-drop programming through the DAP-Link drive. + - Open the DAP-Link Virtual COM port in a terminal (baudrate = 115200) and monitor recognized keywords. diff --git a/VSI/audio/driver/audio_drv.c b/VSI/audio/driver/audio_drv.c new file mode 100644 index 0000000..c4bfdec --- /dev/null +++ b/VSI/audio/driver/audio_drv.c @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2021 Arm Limited. All rights reserved. + */ + +#include +#include "audio_drv.h" +#include "arm_vsi.h" +#ifdef _RTE_ +#include "RTE_Components.h" +#endif +#include CMSIS_device_header + +/* Audio Peripheral definitions */ +#define AudioIn ARM_VSI0 /* Audio Input access struct */ +#define AudioIn_IRQn ARM_VSI0_IRQn /* Audio Input Interrupt number */ +#define AudioIn_Handler ARM_VSI0_Handler /* Audio Input Interrupt handler */ + +/* Audio Peripheral registers */ +#define CONTROL Regs[0] /* Control receiver */ +#define CHANNELS Regs[1] /* Number of channels */ +#define SAMPLE_BITS Regs[2] /* Sample number of bits (8..32) */ +#define SAMPLE_RATE Regs[3] /* Sample rate (samples per second) */ + +/* Audio Control register definitions */ +#define CONTROL_ENABLE_Pos 0U /* CONTROL: ENABLE Position */ +#define CONTROL_ENABLE_Msk (1UL << CONTROL_ENABLE_Pos) /* CONTROL: ENABLE Mask */ + +/* Driver State */ +static uint8_t Initialized = 0U; + +/* Event Callback */ +static AudioDrv_Event_t CB_Event = NULL; + +/* Audio Input Interrupt Handler */ +void AudioIn_Handler (void) { + + AudioIn->IRQ = 0U; /* Clear IRQ */ + __ISB(); + __DSB(); + for (uint32_t n = 0; n < 200U; n++) { + __NOP(); + } + if (CB_Event != NULL) { + CB_Event(AUDIO_DRV_EVENT_RX_DATA); + } +} + +/* Initialize Audio Interface */ +int32_t AudioDrv_Initialize (AudioDrv_Event_t cb_event) { + + CB_Event = cb_event; + + AudioIn->Timer.Control = 0U; + AudioIn->DMA.Control = 0U; + AudioIn->IRQ = 0U; + AudioIn->CONTROL = 0U; + + NVIC_EnableIRQ(AudioIn_IRQn); + + Initialized = 1U; + + return AUDIO_DRV_OK; +} + +/* De-initialize Audio Interface */ +int32_t AudioDrv_Uninitialize (void) { + + NVIC_DisableIRQ(AudioIn_IRQn); + + AudioIn->Timer.Control = 0U; + AudioIn->DMA.Control = 0U; + AudioIn->IRQ = 0U; + AudioIn->CONTROL = 0U; + + Initialized = 0U; + + return AUDIO_DRV_OK; +} + +/* Configure Audio Interface */ +int32_t AudioDrv_Configure (uint32_t interface, uint32_t channels, uint32_t sample_bits, uint32_t sample_rate) { + uint32_t format; + + if (Initialized == 0U) { + return AUDIO_DRV_ERROR; + } + + if ((channels < 1U) || + (channels > 32U) || + (sample_bits < 8U) || + (sample_bits > 32U) || + (sample_rate == 0U)) { + return AUDIO_DRV_ERROR_PARAMETER; + } + + switch (interface) { + case AUDIO_DRV_INTERFACE_TX: + return AUDIO_DRV_ERROR_UNSUPPORTED; + break; + case AUDIO_DRV_INTERFACE_RX: + if ((AudioIn->CONTROL & CONTROL_ENABLE_Msk) != 0U) { + return AUDIO_DRV_ERROR; + } + AudioIn->CHANNELS = channels; + AudioIn->SAMPLE_BITS = sample_bits; + AudioIn->SAMPLE_RATE = sample_rate; + break; + default: + return AUDIO_DRV_ERROR_PARAMETER; + } + + return AUDIO_DRV_OK; +} + +/* Set Audio Interface buffer */ +int32_t AudioDrv_SetBuf (uint32_t interface, void *buf, uint32_t block_num, uint32_t block_size) { + + if (Initialized == 0U) { + return AUDIO_DRV_ERROR; + } + + switch (interface) { + case AUDIO_DRV_INTERFACE_TX: + return AUDIO_DRV_ERROR_UNSUPPORTED; + break; + case AUDIO_DRV_INTERFACE_RX: + if ((AudioIn->DMA.Control & ARM_VSI_DMA_Enable_Msk) != 0U) { + return AUDIO_DRV_ERROR; + } + AudioIn->DMA.Address = (uint32_t)buf; + AudioIn->DMA.BlockNum = block_num; + AudioIn->DMA.BlockSize = block_size; + break; + default: + return AUDIO_DRV_ERROR_PARAMETER; + } + + return AUDIO_DRV_OK; +} + +/* Control Audio Interface */ +int32_t AudioDrv_Control (uint32_t control) { + uint32_t sample_size; + uint32_t sample_rate; + uint32_t block_size; + + if (Initialized == 0U) { + return AUDIO_DRV_ERROR; + } + +//if ((control & AUDIO_DRV_CONTROL_TX_DISABLE) != 0U) { +//} else if ((control & AUDIO_DRV_CONTROL_TX_ENABLE) != 0U) { +//} + + if ((control & AUDIO_DRV_CONTROL_RX_DISABLE) != 0U) { + AudioIn->Timer.Control = 0U; + AudioIn->DMA.Control = 0U; + AudioIn->CONTROL = 0U; + } else if ((control & AUDIO_DRV_CONTROL_RX_ENABLE) != 0U) { + sample_size = AudioIn->CHANNELS * ((AudioIn->SAMPLE_BITS + 7U) / 8U); + sample_rate = AudioIn->SAMPLE_RATE; + if ((sample_size == 0U) || (sample_rate == 0U)) { + AudioIn->Timer.Interval = 0xFFFFFFFFU; + } else { + block_size = AudioIn->DMA.BlockSize; + AudioIn->Timer.Interval = (1000000U * (block_size / sample_size)) / sample_rate; + } + AudioIn->DMA.Control = ARM_VSI_DMA_Direction_P2M | + ARM_VSI_DMA_Enable_Msk; + AudioIn->CONTROL = CONTROL_ENABLE_Msk; + AudioIn->Timer.Control = ARM_VSI_Timer_Trig_IRQ_Msk | + ARM_VSI_Timer_Periodic_Msk | + ARM_VSI_Timer_Run_Msk; + } + + return AUDIO_DRV_OK; +} + +/* Get transmitted block count */ +uint32_t AudioDrv_GetTxCount (void) { + return (0UL); // Unsupported +} + +/* Get received block count */ +uint32_t AudioDrv_GetRxCount (void) { + return (AudioIn->Timer.Count); +} + +/* Get Audio Interface status */ +AudioDrv_Status_t AudioDrv_GetStatus (void) { + AudioDrv_Status_t status; + uint32_t sr; + + status.tx_active = 0U; // Unsupported + + if ((AudioIn->CONTROL & CONTROL_ENABLE_Msk) != 0U) { + status.rx_active = 1U; + } else { + status.rx_active = 0U; + } + + return (status); +} diff --git a/VSI/audio/include/audio_drv.h b/VSI/audio/include/audio_drv.h new file mode 100644 index 0000000..fa2f6c9 --- /dev/null +++ b/VSI/audio/include/audio_drv.h @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2021 Arm Limited. All rights reserved. + */ + +#ifndef __AUDIO_DRV_H +#define __AUDIO_DRV_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include + +/* Audio Interface */ +#define AUDIO_DRV_INTERFACE_TX (1U) ///< Transmitter +#define AUDIO_DRV_INTERFACE_RX (2U) ///< Receiver + +/* Audio Control */ +#define AUDIO_DRV_CONTROL_TX_ENABLE (1UL << 0) ///< Enable Transmitter +#define AUDIO_DRV_CONTROL_RX_ENABLE (1UL << 1) ///< Enable Receiver +#define AUDIO_DRV_CONTROL_TX_DISABLE (1UL << 2) ///< Disable Transmitter +#define AUDIO_DRV_CONTROL_RX_DISABLE (1UL << 3) ///< Disable Receiver + +/* Audio Event */ +#define AUDIO_DRV_EVENT_TX_DATA (1UL << 0) ///< Data block transmitted +#define AUDIO_DRV_EVENT_RX_DATA (1UL << 1) ///< Data block received + +/* Return code */ +#define AUDIO_DRV_OK (0) ///< Operation succeeded +#define AUDIO_DRV_ERROR (-1) ///< Unspecified error +#define AUDIO_DRV_ERROR_BUSY (-2) ///< Driver is busy +#define AUDIO_DRV_ERROR_TIMEOUT (-3) ///< Timeout occurred +#define AUDIO_DRV_ERROR_UNSUPPORTED (-4) ///< Operation not supported +#define AUDIO_DRV_ERROR_PARAMETER (-5) ///< Parameter error + +/** +\brief Audio Status +*/ +typedef struct { + uint32_t tx_active : 1; ///< Transmitter active + uint32_t rx_active : 1; ///< Receiver active + uint32_t reserved : 30; +} AudioDrv_Status_t; + +/** + \fn AudioDrv_Event_t + \brief Audio Events callback function type: void (*AudioDrv_Event_t) (uint32_t event + \param[in] event events notification mask + \return none +*/ +typedef void (*AudioDrv_Event_t) (uint32_t event); + +/** + \fn int32_t AudioDrv_Initialize (AudioDrv_Event_t cb_event) + \brief Initialize Audio Interface. + \param[in] cb_event pointer to \ref AudioDrv_Event_t + \return return code +*/ +int32_t AudioDrv_Initialize (AudioDrv_Event_t cb_event); + +/** + \fn int32_t AudioDrv_Uninitialize (void) + \brief De-initialize Audio Interface. + \return return code +*/ +int32_t AudioDrv_Uninitialize (void); + +/** + \fn int32_t AudioDrv_Configure (uint32_t interface, uint32_t channels, uint32_t sample_bits, uint32_t sample_rate) + \brief Configure Audio Interface. + \param[in] interface audio interface + \param[in] channels number of channels + \param[in] sample_bits sample number of bits (8..32) + \param[in] sample_rate sample rate (samples per second) + \return return code +*/ +int32_t AudioDrv_Configure (uint32_t interface, uint32_t channels, uint32_t sample_bits, uint32_t sample_rate); + +/** + \fn int32_t AudioDrv_SetBuf (uint32_t interface, void *buf, uint32_t block_num, uint32_t block_size) + \brief Set Audio Interface buffer. + \param[in] interface audio interface + \param[in] buf pointer to buffer for audio data + \param[in] block_num number of blocks in buffer (must be 2^n) + \param[in] block_size block size in number of samples + \return return code +*/ +int32_t AudioDrv_SetBuf (uint32_t interface, void *buf, uint32_t block_num, uint32_t block_size); + +/** + \fn int32_t AudioDrv_Control (uint32_t control) + \brief Control Audio Interface. + \param[in] control operation + \return return code +*/ +int32_t AudioDrv_Control (uint32_t control); + +/** + \fn uint32_t AudioDrv_GetTxCount (void) + \brief Get transmitted block count. + \return number of transmitted blocks +*/ +uint32_t AudioDrv_GetTxCount (void); + +/** + \fn uint32_t AudioDrv_GetRxCount (void) + \brief Get received block count. + \return number of received blocks +*/ +uint32_t AudioDrv_GetRxCount (void); + +/** + \fn AudioDrv_Status_t AudioDrv_GetStatus (void) + \brief Get Audio Interface status. + \return \ref AudioDrv_Status_t +*/ +AudioDrv_Status_t AudioDrv_GetStatus (void); + +#ifdef __cplusplus +} +#endif + +#endif /* __AUDIO_DRV_H */ diff --git a/VSI/audio/python/arm_vsi0.py b/VSI/audio/python/arm_vsi0.py new file mode 100644 index 0000000..050d9b2 --- /dev/null +++ b/VSI/audio/python/arm_vsi0.py @@ -0,0 +1,234 @@ +# Copyright (c) 2021 Arm Limited. All rights reserved. + +# Virtual Streaming Interface instance 0 Python script: Audio Input + +import logging +import wave + +# Set verbosity level +#verbosity = logging.DEBUG +#verbosity = logging.INFO +verbosity = logging.ERROR + +# [debugging] Verbosity settings +level = { 10: "DEBUG", 20: "INFO", 30: "WARNING", 40: "ERROR" } +logging.basicConfig(format='Py: [%(levelname)s]\t%(message)s', level = verbosity) +logging.info("Verbosity level is set to " + level[verbosity]) + + +# Data, user registers and IRQ +Data = [0] * 0x2000 # Data buffer +Regs = [0] * 32 # User registers +IRQ = 0 # Interrupt request + +# DMA registers +DMA_Control = 0 +DMA_BlockSize = 0 + +# DMA Control register definitions +DMA_Control_Enable_Msk = 1<<0 +DMA_Control_Direction_Msk = 1<<1 +DMA_Control_Direction_P2M = 0<<1 +DMA_Control_Direction_M2P = 1<<1 + +# Timer registers +Timer_Control = 0 +Timer_Interval = 0 + +# Timer Control register definitions +Timer_Control_Run_Msk = 1<<0 +Timer_Control_Periodic_Msk = 1<<1 +Timer_Control_Trig_IRQ_Msk = 1<<2 + +# User registers +CONTROL = 0 # Regs[0] +CHANNELS = 0 # Regs[1] +SAMPLE_BITS = 0 # Regs[2] +SAMPLE_RATE = 0 # Regs[3] + +# User CONTROL register definitions +CONTROL_ENABLE_Msk = 1<<0 + + +# Write CONTROL register +def wrCONTROL(data): + global CONTROL + if ((data ^ CONTROL) & CONTROL_ENABLE_Msk) != 0: + if (data & CONTROL_ENABLE_Msk) != 0: + logging.info("Enable Receiver") + openWAVE('test.wav') + if ((DMA_Control & DMA_Control_Enable_Msk) != 0): + loadAudioFrames(DMA_BlockSize) + else: + logging.info("Disable Receiver") + closeWAVE() + CONTROL = data + +# Write CHANNELS register +def wrCHANNELS(data): + global CHANNELS + CHANNELS = data + logging.info("Number of channels: {}".format(data)) + +# Write SAMPLE_BITS register +def wrSAMPLE_BITS(data): + global SAMPLE_BITS + SAMPLE_BITS = data + logging.info("Sample bits: {}".format(data)) + +# Write SAMPLE_RATE register +def wrSAMPLE_RATE(data): + global SAMPLE_RATE + SAMPLE_RATE = data + logging.info("Sample rate: {}".format(data)) + + +AudioFrames = bytearray() + +# Open WAVE file +def openWAVE(name): + global WAVE + logging.info("Open WAVE file: {}".format(name)) + WAVE = wave.open(name, 'rb') + logging.info(" Number of channels: {}".format(WAVE.getnchannels())) + logging.info(" Sample bits: {}".format(WAVE.getsampwidth())) + logging.info(" Sample rate: {}".format(WAVE.getframerate())) + logging.info(" Number of frames: {}".format(WAVE.getnframes())) + +# Read WAVE frames +def readWAVE(n): + global WAVE, AudioFrames + logging.info("Read WAVE frames") + AudioFrames = WAVE.readframes(n) + +# Close WAVE file +def closeWAVE(): + global WAVE + logging.info("Close WAVE file") + WAVE.close() + + +# Load audio frames into data buffer +def loadAudioFrames(block_size): + global Data + logging.info("Load audio frames into data buffer") + frame_size = CHANNELS * ((SAMPLE_BITS + 7) // 8) + frames_max = block_size // frame_size + readWAVE(frames_max) + n = len(AudioFrames) + for i in range(n>>2): + Data[i] = ((AudioFrames[(4*i) + 0] << 0) | + (AudioFrames[(4*i) + 1] << 8) | + (AudioFrames[(4*i) + 2] << 16) | + (AudioFrames[(4*i) + 3] << 24)) + for i in range(n>>2, block_size>>2): + Data[i] = 0 + + +# Initialize +def init(): + logging.info("Python function init() called") + + +# Read/Write data buffer +def rwData(cmd, addr, data): + global Data + logging.info("Python function rwData() called") + + if cmd == "read": + data = Data[addr] + logging.debug("Read at index {}: {}".format(addr, data)) + elif cmd == "write": + Data[addr] = data + logging.debug("Write at index {}: {}".format(addr, data)) + else: + logging.error("Unknown command {}".format(cmd)) + + return data + + +# Read/Write user registers +def rwRegs(cmd, addr, data): + global Regs + logging.info("Python function rwRegs() called") + + if cmd == "read": + data = Regs[addr] + logging.debug("Read at index {}: {}".format(addr, data)) + elif cmd == "write": + if addr == 0: + wrCONTROL(data) + elif addr == 1: + wrCHANNELS(data) + elif addr == 2: + wrSAMPLE_BITS(data) + elif addr == 3: + wrSAMPLE_RATE(data) + Regs[addr] = data + logging.debug("Write at index {}: {}".format(addr, data)) + else: + logging.error("Unknown command {}".format(cmd)) + + return data + + +# Read/Write interrupt request +def rwIRQ(cmd, addr, data): + global IRQ + logging.info("Python function rwIRQ() called") + + if cmd == "read": + data = IRQ + logging.debug("Read interrupt request: {}".format(data)) + elif cmd == "write": + IRQ = data + logging.debug("Write interrupt request: {}".format(data)) + else: + logging.error("Unknown command {}".format(cmd)) + + return data + + +# Write DMA registers +def wrDMA(cmd, addr, data): + global DMA_Control, DMA_BlockSize + logging.info("Python function wrDMA() called") + + if addr == 0: + DMA_Control = data + logging.debug("Write DMA_Control: {}".format(data)) + elif addr == 2: + DMA_BlockSize = data + logging.debug("Write DMA_BlockSize: {}".format(data)) + else: + logging.error("Unknown address {}".format(addr)) + + return data + + +# Write Timer registers +def wrTimer(cmd, addr, data): + global Timer_Control, Timer_Interval + logging.info("Python function wrTimer() called") + + if addr == 0: + Timer_Control = data + logging.debug("Write Timer_Control: {}".format(data)) + elif addr == 1: + Timer_Interval = data + logging.debug("Write Timer_Interval: {}".format(data)) + else: + logging.error("Unknown address {}".format(addr)) + + return data + + +# Timer event +def timerEvent(cmd, addr, data): + logging.info("Python function timerEvent() called") + + if ((DMA_Control & DMA_Control_Enable_Msk) != 0): + loadAudioFrames(DMA_BlockSize) + + return data + diff --git a/VSI/include/arm_vsi.h b/VSI/include/arm_vsi.h new file mode 100644 index 0000000..869c0f0 --- /dev/null +++ b/VSI/include/arm_vsi.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2021 Arm Limited. All rights reserved. + */ + +/* + * Virtual Streaming Interface (VSI) + */ + + + +#ifndef __ARM_VSI_H +#define __ARM_VSI_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef __IM +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#endif +#ifndef __OM +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#endif +#ifndef __IOM +#define __IOM volatile /*! Defines 'read/write' structure member permissions */ +#endif + +#include + + +/* IRQ number assignment (should be moved to device header) */ +#define ARM_VSI0_IRQn 0 +#define ARM_VSI1_IRQn 1 +#define ARM_VSI2_IRQn 2 +#define ARM_VSI3_IRQn 3 +#define ARM_VSI4_IRQn 4 +#define ARM_VSI5_IRQn 5 +#define ARM_VSI6_IRQn 6 +#define ARM_VSI7_IRQn 7 + +/** + \brief Structure type to access the virtual streaming interface. + */ +typedef struct +{ + __IOM uint32_t Data[0x2000]; /*!< Offset: 0x0000 (R/W) Data Buffer (32KB) */ + __IOM uint32_t Regs[32]; /*!< Offset: 0x8000 (R/W) User Registers */ + struct { + __IOM uint32_t Control; /*!< Offset: 0x8080 (R/W) Timer Control Register */ + __IOM uint32_t Interval; /*!< Offset: 0x8084 (R/W) Timer Interval Value (in microseconds) */ + __IM uint32_t Count; /*!< Offset: 0x8088 (R/ ) Timer Overflow Count */ + } Timer; /*!< Time counter with 1MHz input frequency */ + struct { + __IOM uint32_t Control; /*!< Offset: 0x808C (R/W) DMA Control */ + __IOM uint32_t Address; /*!< Offset: 0x8090 (R/W) DMA Memory Start Address */ + __IOM uint32_t BlockSize; /*!< Offset: 0x8094 (R/W) DMA Block Size (in bytes) */ + __IOM uint32_t BlockNum; /*!< Offset: 0x8098 (R/W) DMA Number of Blocks (must be 2^n) */ + __IM uint32_t BlockIndex; /*!< Offset: 0x809C (R/ ) DMA Block Index */ + } DMA; /*!< DMA Controller */ + __IOM uint32_t IRQ; /*!< Offset: 0x80A0 (R/W) Interrupt Request */ +} ARM_VSI_Type; + +/* VSI Timer Control Definitions for Timer.Control register */ +#define ARM_VSI_Timer_Run_Pos 0U /*!< Timer Control: Run Position */ +#define ARM_VSI_Timer_Run_Msk (1UL << ARM_VSI_Timer_Run_Pos) /*!< Timer Control: Run Mask */ +#define ARM_VSI_Timer_Periodic_Pos 1U /*!< Timer Control: Periodic Position */ +#define ARM_VSI_Timer_Periodic_Msk (1UL << ARM_VSI_Timer_Periodic_Pos) /*!< Timer Control: Periodic Mask */ +#define ARM_VSI_Timer_Trig_IRQ_Pos 2U /*!< Timer Control: Trig_IRQ Position */ +#define ARM_VSI_Timer_Trig_IRQ_Msk (1UL << ARM_VSI_Timer_Trig_IRQ_Pos) /*!< Timer Control: Trig_IRQ Mask */ + +/* VSI DMA Control Definitions for DMA.Control register */ +#define ARM_VSI_DMA_Enable_Pos 0U /*!< DMA Control: Enable Position */ +#define ARM_VSI_DMA_Enable_Msk (1UL << ARM_VSI_DMA_Enable_Pos) /*!< DMA Control: Enable Mask */ +#define ARM_VSI_DMA_Direction_Pos 1U /*!< DMA Control: Direction Position */ +#define ARM_VSI_DMA_Direction_Msk (1UL << ARM_VSI_DMA_Direction_Pos) /*!< DMA Control: Direction Mask */ +#define ARM_VSI_DMA_Direction_P2M (0UL*ARM_VSI_DMA_Direction_Msk) /*!< DMA Control: Direction P2M */ +#define ARM_VSI_DMA_Direction_M2P (1UL*ARM_VSI_DMA_Direction_Msk) /*!< DMA Control: Direction M2P */ + +/* Memory mapping of 8 VSI peripherals */ +#define ARM_VSI0_BASE (0x5FF00000UL) /*!< VSI 0 Base Address */ +#define ARM_VSI1_BASE (0x5FF10000UL) /*!< VSI 1 Base Address */ +#define ARM_VSI2_BASE (0x5FF20000UL) /*!< VSI 2 Base Address */ +#define ARM_VSI3_BASE (0x5FF30000UL) /*!< VSI 3 Base Address */ +#define ARM_VSI4_BASE (0x5FF40000UL) /*!< VSI 4 Base Address */ +#define ARM_VSI5_BASE (0x5FF50000UL) /*!< VSI 5 Base Address */ +#define ARM_VSI6_BASE (0x5FF60000UL) /*!< VSI 6 Base Address */ +#define ARM_VSI7_BASE (0x5FF70000UL) /*!< VSI 7 Base Address */ +#define ARM_VSI0 ((ARM_VSI_Type *)ARM_VSI0_BASE) /*!< VSI 0 struct */ +#define ARM_VSI1 ((ARM_VSI_Type *)ARM_VSI1_BASE) /*!< VSI 1 struct */ +#define ARM_VSI2 ((ARM_VSI_Type *)ARM_VSI2_BASE) /*!< VSI 2 struct */ +#define ARM_VSI3 ((ARM_VSI_Type *)ARM_VSI3_BASE) /*!< VSI 3 struct */ +#define ARM_VSI4 ((ARM_VSI_Type *)ARM_VSI4_BASE) /*!< VSI 4 struct */ +#define ARM_VSI5 ((ARM_VSI_Type *)ARM_VSI5_BASE) /*!< VSI 5 struct */ +#define ARM_VSI6 ((ARM_VSI_Type *)ARM_VSI6_BASE) /*!< VSI 6 struct */ +#define ARM_VSI7 ((ARM_VSI_Type *)ARM_VSI7_BASE) /*!< VSI 7 struct */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __ARM_VSI_H */ diff --git a/micro_speech/src/audio_provider.cc b/micro_speech/src/audio_provider.cc new file mode 100644 index 0000000..2b1617c --- /dev/null +++ b/micro_speech/src/audio_provider.cc @@ -0,0 +1,103 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 "audio_provider.h" + +#include "micro_features/micro_model_settings.h" +#include "audio_drv.h" + +#define AUDIO_BLOCK_NUM (4) +#define AUDIO_BLOCK_SIZE (3200) +#define AUDIO_BUFFER_SIZE (AUDIO_BLOCK_NUM*AUDIO_BLOCK_SIZE) + +namespace { +bool g_is_audio_initialized = false; +bool g_is_audio_ready = false; +#ifdef __FVP_PY +__attribute__((section(".ARM.__at_0x9FFF0000"))) +#endif +__attribute__((aligned(4))) +int16_t g_audio_buf [AUDIO_BUFFER_SIZE/2]; +int16_t g_audio_data[kMaxAudioSampleSize]; +int32_t g_latest_audio_timestamp = 0; +} // namespace + +static void AudioEvent (uint32_t event) { + if (!g_is_audio_ready) { + g_is_audio_ready = true; + return; + } + if (event & AUDIO_DRV_EVENT_RX_DATA) { + g_latest_audio_timestamp += ((AUDIO_BLOCK_SIZE/2) * 1000) / kAudioSampleFrequency; + } +} + +static int32_t AudioDrv_Setup(void) { + int32_t ret; + + ret = AudioDrv_Initialize(AudioEvent); + if (ret != 0) { + return ret; + } + + ret = AudioDrv_Configure(AUDIO_DRV_INTERFACE_RX, + 1U, /* single channel */ + 16U, /* 16 sample bits */ + static_cast(kAudioSampleFrequency)); + if (ret != 0) { + return ret; + } + + ret = AudioDrv_SetBuf(AUDIO_DRV_INTERFACE_RX, + g_audio_buf, AUDIO_BLOCK_NUM, AUDIO_BLOCK_SIZE); + if (ret != 0) { + return ret; + } + + ret = AudioDrv_Control(AUDIO_DRV_CONTROL_RX_ENABLE); + if (ret != 0) { + return ret; + } + + return 0; +} + +TfLiteStatus GetAudioSamples(tflite::ErrorReporter* error_reporter, + int start_ms, int duration_ms, + int* audio_samples_size, int16_t** audio_samples) { + + if (!g_is_audio_initialized) { + int32_t ret = AudioDrv_Setup(); + if (ret != 0) { + return kTfLiteError; + } + g_is_audio_initialized = true; + } + + const int start_sample = (start_ms * kAudioSampleFrequency) / 1000; + const int duration_samples = (duration_ms * kAudioSampleFrequency) / 1000; + for (int i = 0; i < duration_samples; ++i) { + const int sample_index = (start_sample + i) % (AUDIO_BUFFER_SIZE/2); + g_audio_data[i] = g_audio_buf[sample_index]; + } + *audio_samples_size = kMaxAudioSampleSize; + *audio_samples = g_audio_data; + + return kTfLiteOk; +} + +int32_t LatestAudioTimestamp() { + return g_latest_audio_timestamp; +} diff --git a/micro_speech/src/audio_provider.h b/micro_speech/src/audio_provider.h new file mode 100644 index 0000000..c51cc5f --- /dev/null +++ b/micro_speech/src/audio_provider.h @@ -0,0 +1,46 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_AUDIO_PROVIDER_H_ +#define TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_AUDIO_PROVIDER_H_ + +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/micro/micro_error_reporter.h" + +// This is an abstraction around an audio source like a microphone, and is +// expected to return 16-bit PCM sample data for a given point in time. The +// sample data itself should be used as quickly as possible by the caller, since +// to allow memory optimizations there are no guarantees that the samples won't +// be overwritten by new data in the future. In practice, implementations should +// ensure that there's a reasonable time allowed for clients to access the data +// before any reuse. +// The reference implementation can have no platform-specific dependencies, so +// it just returns an array filled with zeros. For real applications, you should +// ensure there's a specialized implementation that accesses hardware APIs. +TfLiteStatus GetAudioSamples(tflite::ErrorReporter* error_reporter, + int start_ms, int duration_ms, + int* audio_samples_size, int16_t** audio_samples); + +// Returns the time that audio data was last captured in milliseconds. There's +// no contract about what time zero represents, the accuracy, or the granularity +// of the result. Subsequent calls will generally not return a lower value, but +// even that's not guaranteed if there's an overflow wraparound. +// The reference implementation of this function just returns a constantly +// incrementing value for each call, since it would need a non-portable platform +// call to access time information. For real applications, you'll need to write +// your own platform-specific implementation. +int32_t LatestAudioTimestamp(); + +#endif // TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_AUDIO_PROVIDER_H_ diff --git a/micro_speech/src/audio_provider_mock.cc b/micro_speech/src/audio_provider_mock.cc new file mode 100644 index 0000000..79f1a99 --- /dev/null +++ b/micro_speech/src/audio_provider_mock.cc @@ -0,0 +1,55 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 "audio_provider.h" +#include "micro_features/micro_model_settings.h" +#include "no_1000ms_sample_data.h" +#include "yes_1000ms_sample_data.h" + +namespace { +int16_t g_dummy_audio_data[kMaxAudioSampleSize]; +int32_t g_latest_audio_timestamp = 0; +} // namespace + +TfLiteStatus GetAudioSamples(tflite::ErrorReporter* error_reporter, + int start_ms, int duration_ms, + int* audio_samples_size, int16_t** audio_samples) { + const int yes_start = (0 * kAudioSampleFrequency) / 1000; + const int yes_end = (1000 * kAudioSampleFrequency) / 1000; + const int no_start = (4000 * kAudioSampleFrequency) / 1000; + const int no_end = (5000 * kAudioSampleFrequency) / 1000; + const int wraparound = (8000 * kAudioSampleFrequency) / 1000; + const int start_sample = (start_ms * kAudioSampleFrequency) / 1000; + for (int i = 0; i < kMaxAudioSampleSize; ++i) { + const int sample_index = (start_sample + i) % wraparound; + int16_t sample; + if ((sample_index >= yes_start) && (sample_index < yes_end)) { + sample = g_yes_1000ms_sample_data[sample_index - yes_start]; + } else if ((sample_index >= no_start) && (sample_index < no_end)) { + sample = g_no_1000ms_sample_data[sample_index - no_start]; + } else { + sample = 0; + } + g_dummy_audio_data[i] = sample; + } + *audio_samples_size = kMaxAudioSampleSize; + *audio_samples = g_dummy_audio_data; + return kTfLiteOk; +} + +int32_t LatestAudioTimestamp() { + g_latest_audio_timestamp += 100; + return g_latest_audio_timestamp; +} diff --git a/micro_speech/src/audio_provider_mock_test.cc b/micro_speech/src/audio_provider_mock_test.cc new file mode 100644 index 0000000..21e7a23 --- /dev/null +++ b/micro_speech/src/audio_provider_mock_test.cc @@ -0,0 +1,76 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 "tensorflow/lite/c/common.h" +#include "audio_provider.h" +#include "micro_features/micro_model_settings.h" +#include "no_1000ms_sample_data.h" +#include "yes_1000ms_sample_data.h" +#include "tensorflow/lite/micro/micro_error_reporter.h" +#include "tensorflow/lite/micro/testing/micro_test.h" + +TF_LITE_MICRO_TESTS_BEGIN + +TF_LITE_MICRO_TEST(TestAudioProviderMock) { + tflite::MicroErrorReporter micro_error_reporter; + + int audio_samples_size = 0; + int16_t* audio_samples = nullptr; + TfLiteStatus get_status = + GetAudioSamples(µ_error_reporter, 0, kFeatureSliceDurationMs, + &audio_samples_size, &audio_samples); + TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, get_status); + TF_LITE_MICRO_EXPECT_LE(audio_samples_size, kMaxAudioSampleSize); + TF_LITE_MICRO_EXPECT_NE(audio_samples, nullptr); + for (int i = 0; i < audio_samples_size; ++i) { + TF_LITE_MICRO_EXPECT_EQ(g_yes_1000ms_sample_data[i], audio_samples[i]); + } + + get_status = + GetAudioSamples(µ_error_reporter, 500, kFeatureSliceDurationMs, + &audio_samples_size, &audio_samples); + TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, get_status); + TF_LITE_MICRO_EXPECT_LE(audio_samples_size, kMaxAudioSampleSize); + TF_LITE_MICRO_EXPECT_NE(audio_samples, nullptr); + for (int i = 0; i < audio_samples_size; ++i) { + TF_LITE_MICRO_EXPECT_EQ(g_yes_1000ms_sample_data[i + 8000], + audio_samples[i]); + } + + get_status = + GetAudioSamples(µ_error_reporter, 1500, kFeatureSliceDurationMs, + &audio_samples_size, &audio_samples); + TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, get_status); + TF_LITE_MICRO_EXPECT_LE(audio_samples_size, kMaxAudioSampleSize); + TF_LITE_MICRO_EXPECT_NE(audio_samples, nullptr); + for (int i = 0; i < audio_samples_size; ++i) { + TF_LITE_MICRO_EXPECT_EQ(0, audio_samples[i]); + } + + get_status = + GetAudioSamples(µ_error_reporter, 12250, kFeatureSliceDurationMs, + &audio_samples_size, &audio_samples); + TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, get_status); + TF_LITE_MICRO_EXPECT_LE(audio_samples_size, kMaxAudioSampleSize); + TF_LITE_MICRO_EXPECT_NE(audio_samples, nullptr); + for (int i = 0; i < audio_samples_size; ++i) { + TF_LITE_MICRO_EXPECT_EQ(g_no_1000ms_sample_data[i + 4000], + audio_samples[i]); + } +} + +TF_LITE_MICRO_TESTS_END diff --git a/micro_speech/src/audio_provider_test.cc b/micro_speech/src/audio_provider_test.cc new file mode 100644 index 0000000..5416c23 --- /dev/null +++ b/micro_speech/src/audio_provider_test.cc @@ -0,0 +1,69 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 "audio_provider.h" + +#include + +#include "tensorflow/lite/c/common.h" +#include "micro_features/micro_model_settings.h" +#include "tensorflow/lite/micro/micro_error_reporter.h" +#include "tensorflow/lite/micro/testing/micro_test.h" + +TF_LITE_MICRO_TESTS_BEGIN + +TF_LITE_MICRO_TEST(TestAudioProvider) { + tflite::MicroErrorReporter micro_error_reporter; + + int audio_samples_size = 0; + int16_t* audio_samples = nullptr; + TfLiteStatus get_status = + GetAudioSamples(µ_error_reporter, 0, kFeatureSliceDurationMs, + &audio_samples_size, &audio_samples); + TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, get_status); + TF_LITE_MICRO_EXPECT_LE(audio_samples_size, kMaxAudioSampleSize); + TF_LITE_MICRO_EXPECT_NE(audio_samples, nullptr); + + // Make sure we can read all of the returned memory locations. + int total = 0; + for (int i = 0; i < audio_samples_size; ++i) { + total += audio_samples[i]; + } +} + +TF_LITE_MICRO_TEST(TestTimer) { + // Make sure that the technically-undefined overflow behavior we rely on below + // works on this platform. It's still not guaranteed, but at least this is a + // smoke check. Turn off when running with ASan, as it will complain about + // the following undefined behavior. +#ifndef ADDRESS_SANITIZER + int32_t overflow_value = std::numeric_limits::max(); + overflow_value += 1; + TF_LITE_MICRO_EXPECT_EQ(std::numeric_limits::min(), overflow_value); +#endif + + const int32_t first_time = LatestAudioTimestamp(); + const int32_t second_time = LatestAudioTimestamp(); + + // It's possible that the timer may have wrapped around from +BIG_NUM to + // -BIG_NUM between the first and second calls, since we're storing + // milliseconds in a 32-bit integer. It's not reasonable that the call itself + // would have taken more than 2^31 milliseconds though, so look at the + // difference and rely on integer overflow to ensure it's accurate. + const int32_t time_delta = (second_time - first_time); + TF_LITE_MICRO_EXPECT_LE(0, time_delta); +} + +TF_LITE_MICRO_TESTS_END diff --git a/micro_speech/src/command_responder.cc b/micro_speech/src/command_responder.cc new file mode 100644 index 0000000..09310e7 --- /dev/null +++ b/micro_speech/src/command_responder.cc @@ -0,0 +1,28 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 "command_responder.h" + +// The default implementation writes out the name of the recognized command +// to the error console. Real applications will want to take some custom +// action instead, and should implement their own versions of this function. +void RespondToCommand(tflite::ErrorReporter* error_reporter, + int32_t current_time, const char* found_command, + uint8_t score, bool is_new_command) { + if (is_new_command) { + TF_LITE_REPORT_ERROR(error_reporter, "Heard %s (%d) @%dms", found_command, + score, current_time); + } +} diff --git a/micro_speech/src/command_responder.h b/micro_speech/src/command_responder.h new file mode 100644 index 0000000..ac3f448 --- /dev/null +++ b/micro_speech/src/command_responder.h @@ -0,0 +1,32 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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. +==============================================================================*/ + +// Provides an interface to take an action based on an audio command. + +#ifndef TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_COMMAND_RESPONDER_H_ +#define TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_COMMAND_RESPONDER_H_ + +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/micro/micro_error_reporter.h" + +// Called every time the results of an audio recognition run are available. The +// human-readable name of any recognized command is in the `found_command` +// argument, `score` has the numerical confidence, and `is_new_command` is set +// if the previous command was different to this one. +void RespondToCommand(tflite::ErrorReporter* error_reporter, + int32_t current_time, const char* found_command, + uint8_t score, bool is_new_command); + +#endif // TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_COMMAND_RESPONDER_H_ diff --git a/micro_speech/src/command_responder_test.cc b/micro_speech/src/command_responder_test.cc new file mode 100644 index 0000000..6ed8f67 --- /dev/null +++ b/micro_speech/src/command_responder_test.cc @@ -0,0 +1,31 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 "command_responder.h" + +#include "tensorflow/lite/micro/testing/micro_test.h" + +TF_LITE_MICRO_TESTS_BEGIN + +TF_LITE_MICRO_TEST(TestCallability) { + tflite::MicroErrorReporter micro_error_reporter; + + // This will have external side-effects (like printing to the debug console + // or lighting an LED) that are hard to observe, so the most we can do is + // make sure the call doesn't crash. + RespondToCommand(µ_error_reporter, 0, "foo", 0, true); +} + +TF_LITE_MICRO_TESTS_END diff --git a/micro_speech/src/feature_provider.cc b/micro_speech/src/feature_provider.cc new file mode 100644 index 0000000..2050fb5 --- /dev/null +++ b/micro_speech/src/feature_provider.cc @@ -0,0 +1,120 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 "feature_provider.h" + +#include "audio_provider.h" +#include "micro_features/micro_features_generator.h" +#include "micro_features/micro_model_settings.h" + +FeatureProvider::FeatureProvider(int feature_size, int8_t* feature_data) + : feature_size_(feature_size), + feature_data_(feature_data), + is_first_run_(true) { + // Initialize the feature data to default values. + for (int n = 0; n < feature_size_; ++n) { + feature_data_[n] = 0; + } +} + +FeatureProvider::~FeatureProvider() {} + +TfLiteStatus FeatureProvider::PopulateFeatureData( + tflite::ErrorReporter* error_reporter, int32_t last_time_in_ms, + int32_t time_in_ms, int* how_many_new_slices) { + if (feature_size_ != kFeatureElementCount) { + TF_LITE_REPORT_ERROR(error_reporter, + "Requested feature_data_ size %d doesn't match %d", + feature_size_, kFeatureElementCount); + return kTfLiteError; + } + + // Quantize the time into steps as long as each window stride, so we can + // figure out which audio data we need to fetch. + const int last_step = (last_time_in_ms / kFeatureSliceStrideMs); + const int current_step = (time_in_ms / kFeatureSliceStrideMs); + + int slices_needed = current_step - last_step; + // If this is the first call, make sure we don't use any cached information. + if (is_first_run_) { + TfLiteStatus init_status = InitializeMicroFeatures(error_reporter); + if (init_status != kTfLiteOk) { + return init_status; + } + is_first_run_ = false; + slices_needed = kFeatureSliceCount; + } + if (slices_needed > kFeatureSliceCount) { + slices_needed = kFeatureSliceCount; + } + *how_many_new_slices = slices_needed; + + const int slices_to_keep = kFeatureSliceCount - slices_needed; + const int slices_to_drop = kFeatureSliceCount - slices_to_keep; + // If we can avoid recalculating some slices, just move the existing data + // up in the spectrogram, to perform something like this: + // last time = 80ms current time = 120ms + // +-----------+ +-----------+ + // | data@20ms | --> | data@60ms | + // +-----------+ -- +-----------+ + // | data@40ms | -- --> | data@80ms | + // +-----------+ -- -- +-----------+ + // | data@60ms | -- -- | | + // +-----------+ -- +-----------+ + // | data@80ms | -- | | + // +-----------+ +-----------+ + if (slices_to_keep > 0) { + for (int dest_slice = 0; dest_slice < slices_to_keep; ++dest_slice) { + int8_t* dest_slice_data = + feature_data_ + (dest_slice * kFeatureSliceSize); + const int src_slice = dest_slice + slices_to_drop; + const int8_t* src_slice_data = + feature_data_ + (src_slice * kFeatureSliceSize); + for (int i = 0; i < kFeatureSliceSize; ++i) { + dest_slice_data[i] = src_slice_data[i]; + } + } + } + // Any slices that need to be filled in with feature data have their + // appropriate audio data pulled, and features calculated for that slice. + if (slices_needed > 0) { + for (int new_slice = slices_to_keep; new_slice < kFeatureSliceCount; + ++new_slice) { + const int new_step = (current_step - kFeatureSliceCount + 1) + new_slice; + const int32_t slice_start_ms = (new_step * kFeatureSliceStrideMs); + int16_t* audio_samples = nullptr; + int audio_samples_size = 0; + // TODO(petewarden): Fix bug that leads to non-zero slice_start_ms + GetAudioSamples(error_reporter, (slice_start_ms > 0 ? slice_start_ms : 0), + kFeatureSliceDurationMs, &audio_samples_size, + &audio_samples); + if (audio_samples_size < kMaxAudioSampleSize) { + TF_LITE_REPORT_ERROR(error_reporter, + "Audio data size %d too small, want %d", + audio_samples_size, kMaxAudioSampleSize); + return kTfLiteError; + } + int8_t* new_slice_data = feature_data_ + (new_slice * kFeatureSliceSize); + size_t num_samples_read; + TfLiteStatus generate_status = GenerateMicroFeatures( + error_reporter, audio_samples, audio_samples_size, kFeatureSliceSize, + new_slice_data, &num_samples_read); + if (generate_status != kTfLiteOk) { + return generate_status; + } + } + } + return kTfLiteOk; +} diff --git a/micro_speech/src/feature_provider.h b/micro_speech/src/feature_provider.h new file mode 100644 index 0000000..d086e01 --- /dev/null +++ b/micro_speech/src/feature_provider.h @@ -0,0 +1,52 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_FEATURE_PROVIDER_H_ +#define TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_FEATURE_PROVIDER_H_ + +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/micro/micro_error_reporter.h" + +// Binds itself to an area of memory intended to hold the input features for an +// audio-recognition neural network model, and fills that data area with the +// features representing the current audio input, for example from a microphone. +// The audio features themselves are a two-dimensional array, made up of +// horizontal slices representing the frequencies at one point in time, stacked +// on top of each other to form a spectrogram showing how those frequencies +// changed over time. +class FeatureProvider { + public: + // Create the provider, and bind it to an area of memory. This memory should + // remain accessible for the lifetime of the provider object, since subsequent + // calls will fill it with feature data. The provider does no memory + // management of this data. + FeatureProvider(int feature_size, int8_t* feature_data); + ~FeatureProvider(); + + // Fills the feature data with information from audio inputs, and returns how + // many feature slices were updated. + TfLiteStatus PopulateFeatureData(tflite::ErrorReporter* error_reporter, + int32_t last_time_in_ms, int32_t time_in_ms, + int* how_many_new_slices); + + private: + int feature_size_; + int8_t* feature_data_; + // Make sure we don't try to use cached information if this is the first call + // into the provider. + bool is_first_run_; +}; + +#endif // TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_FEATURE_PROVIDER_H_ diff --git a/micro_speech/src/feature_provider_mock_test.cc b/micro_speech/src/feature_provider_mock_test.cc new file mode 100644 index 0000000..35afdac --- /dev/null +++ b/micro_speech/src/feature_provider_mock_test.cc @@ -0,0 +1,64 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 "tensorflow/lite/c/common.h" +#include "feature_provider.h" +#include "micro_features/micro_model_settings.h" +#include "micro_features/no_micro_features_data.h" +#include "micro_features/yes_micro_features_data.h" +#include "tensorflow/lite/micro/micro_error_reporter.h" +#include "tensorflow/lite/micro/testing/micro_test.h" + +TF_LITE_MICRO_TESTS_BEGIN + +TF_LITE_MICRO_TEST(TestFeatureProviderMockYes) { + tflite::MicroErrorReporter micro_error_reporter; + + int8_t feature_data[kFeatureElementCount]; + FeatureProvider feature_provider(kFeatureElementCount, feature_data); + + int how_many_new_slices = 0; + TfLiteStatus populate_status = feature_provider.PopulateFeatureData( + µ_error_reporter, /* last_time_in_ms= */ 0, /* time_in_ms= */ 970, + &how_many_new_slices); + TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, populate_status); + TF_LITE_MICRO_EXPECT_EQ(kFeatureSliceCount, how_many_new_slices); + + for (int i = 0; i < kFeatureElementCount; ++i) { + TF_LITE_MICRO_EXPECT_EQ(g_yes_micro_f2e59fea_nohash_1_data[i], + feature_data[i]); + } +} + +TF_LITE_MICRO_TEST(TestFeatureProviderMockNo) { + tflite::MicroErrorReporter micro_error_reporter; + + int8_t feature_data[kFeatureElementCount]; + FeatureProvider feature_provider(kFeatureElementCount, feature_data); + + int how_many_new_slices = 0; + TfLiteStatus populate_status = feature_provider.PopulateFeatureData( + µ_error_reporter, /* last_time_in_ms= */ 4000, + /* time_in_ms= */ 4970, &how_many_new_slices); + TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, populate_status); + TF_LITE_MICRO_EXPECT_EQ(kFeatureSliceCount, how_many_new_slices); + + for (int i = 0; i < kFeatureElementCount; ++i) { + TF_LITE_MICRO_EXPECT_EQ(g_no_micro_f9643d42_nohash_4_data[i], + feature_data[i]); + } +} + +TF_LITE_MICRO_TESTS_END diff --git a/micro_speech/src/feature_provider_test.cc b/micro_speech/src/feature_provider_test.cc new file mode 100644 index 0000000..1b3076f --- /dev/null +++ b/micro_speech/src/feature_provider_test.cc @@ -0,0 +1,39 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 "feature_provider.h" + +#include "tensorflow/lite/c/common.h" +#include "micro_features/micro_model_settings.h" +#include "tensorflow/lite/micro/micro_error_reporter.h" +#include "tensorflow/lite/micro/testing/micro_test.h" + +TF_LITE_MICRO_TESTS_BEGIN + +TF_LITE_MICRO_TEST(TestFeatureProvider) { + tflite::MicroErrorReporter micro_error_reporter; + + int8_t feature_data[kFeatureElementCount]; + FeatureProvider feature_provider(kFeatureElementCount, feature_data); + + int how_many_new_slices = 0; + TfLiteStatus populate_status = feature_provider.PopulateFeatureData( + µ_error_reporter, /* last_time_in_ms= */ 0, /* time_in_ms= */ 10000, + &how_many_new_slices); + TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, populate_status); + TF_LITE_MICRO_EXPECT_EQ(kFeatureSliceCount, how_many_new_slices); +} + +TF_LITE_MICRO_TESTS_END diff --git a/micro_speech/src/main.cc b/micro_speech/src/main.cc new file mode 100644 index 0000000..e08c300 --- /dev/null +++ b/micro_speech/src/main.cc @@ -0,0 +1,27 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 "main_functions.h" + +// This is the default main used on systems that have the standard C entry +// point. Other devices (for example FreeRTOS or ESP32) that have different +// requirements for entry code (like an app_main function) should specialize +// this main.cc file in a target-specific subfolder. +int main(int argc, char* argv[]) { + setup(); + while (true) { + loop(); + } +} diff --git a/micro_speech/src/main_functions.cc b/micro_speech/src/main_functions.cc new file mode 100644 index 0000000..b15e714 --- /dev/null +++ b/micro_speech/src/main_functions.cc @@ -0,0 +1,193 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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. +==============================================================================*/ + +#ifdef _RTE_ +#include "RTE_Components.h" +#ifdef RTE_Compiler_EventRecorder +#include "EventRecorder.h" +#else +#define EventStartCv(slot, v1, v2) +#define EventStopCv(slot, v1, v2) +#endif +#endif + +#include "main_functions.h" + +#include "audio_provider.h" +#include "command_responder.h" +#include "feature_provider.h" +#include "micro_features/micro_model_settings.h" +#include "micro_features/model.h" +#include "recognize_commands.h" +#include "tensorflow/lite/micro/micro_error_reporter.h" +#include "tensorflow/lite/micro/micro_interpreter.h" +#include "tensorflow/lite/micro/micro_mutable_op_resolver.h" +#include "tensorflow/lite/micro/system_setup.h" +#include "tensorflow/lite/schema/schema_generated.h" + +// Globals, used for compatibility with Arduino-style sketches. +namespace { +tflite::ErrorReporter* error_reporter = nullptr; +const tflite::Model* model = nullptr; +tflite::MicroInterpreter* interpreter = nullptr; +TfLiteTensor* model_input = nullptr; +FeatureProvider* feature_provider = nullptr; +RecognizeCommands* recognizer = nullptr; +int32_t previous_time = 0; + +// Create an area of memory to use for input, output, and intermediate arrays. +// The size of this will depend on the model you're using, and may need to be +// determined by experimentation. +constexpr int kTensorArenaSize = 10 * 1024; +uint8_t tensor_arena[kTensorArenaSize]; +int8_t feature_buffer[kFeatureElementCount]; +int8_t* model_input_buffer = nullptr; +} // namespace + +// The name of this function is important for Arduino compatibility. +void setup() { + tflite::InitializeTarget(); + + // Set up logging. Google style is to avoid globals or statics because of + // lifetime uncertainty, but since this has a trivial destructor it's okay. + // NOLINTNEXTLINE(runtime-global-variables) + static tflite::MicroErrorReporter micro_error_reporter; + error_reporter = µ_error_reporter; + + // Map the model into a usable data structure. This doesn't involve any + // copying or parsing, it's a very lightweight operation. + model = tflite::GetModel(g_model); + if (model->version() != TFLITE_SCHEMA_VERSION) { + TF_LITE_REPORT_ERROR(error_reporter, + "Model provided is schema version %d not equal " + "to supported version %d.", + model->version(), TFLITE_SCHEMA_VERSION); + return; + } + + // Pull in only the operation implementations we need. + // This relies on a complete list of all the ops needed by this graph. + // An easier approach is to just use the AllOpsResolver, but this will + // incur some penalty in code space for op implementations that are not + // needed by this graph. + // + // tflite::AllOpsResolver resolver; + // NOLINTNEXTLINE(runtime-global-variables) + static tflite::MicroMutableOpResolver<4> micro_op_resolver(error_reporter); + if (micro_op_resolver.AddDepthwiseConv2D() != kTfLiteOk) { + return; + } + if (micro_op_resolver.AddFullyConnected() != kTfLiteOk) { + return; + } + if (micro_op_resolver.AddSoftmax() != kTfLiteOk) { + return; + } + if (micro_op_resolver.AddReshape() != kTfLiteOk) { + return; + } + + // Build an interpreter to run the model with. + static tflite::MicroInterpreter static_interpreter( + model, micro_op_resolver, tensor_arena, kTensorArenaSize, error_reporter); + interpreter = &static_interpreter; + + // Allocate memory from the tensor_arena for the model's tensors. + TfLiteStatus allocate_status = interpreter->AllocateTensors(); + if (allocate_status != kTfLiteOk) { + TF_LITE_REPORT_ERROR(error_reporter, "AllocateTensors() failed"); + return; + } + + // Get information about the memory area to use for the model's input. + model_input = interpreter->input(0); + if ((model_input->dims->size != 2) || (model_input->dims->data[0] != 1) || + (model_input->dims->data[1] != + (kFeatureSliceCount * kFeatureSliceSize)) || + (model_input->type != kTfLiteInt8)) { + TF_LITE_REPORT_ERROR(error_reporter, + "Bad input tensor parameters in model"); + return; + } + model_input_buffer = model_input->data.int8; + + // Prepare to access the audio spectrograms from a microphone or other source + // that will provide the inputs to the neural network. + // NOLINTNEXTLINE(runtime-global-variables) + static FeatureProvider static_feature_provider(kFeatureElementCount, + feature_buffer); + feature_provider = &static_feature_provider; + + static RecognizeCommands static_recognizer(error_reporter); + recognizer = &static_recognizer; + + previous_time = 0; +} + +// The name of this function is important for Arduino compatibility. +void loop() { + // Fetch the spectrogram for the current time. + const int32_t current_time = LatestAudioTimestamp(); + int how_many_new_slices = 0; + EventStartCv(0, current_time, previous_time); + TfLiteStatus feature_status = feature_provider->PopulateFeatureData( + error_reporter, previous_time, current_time, &how_many_new_slices); + EventStopCv(0, feature_status, how_many_new_slices); + if (feature_status != kTfLiteOk) { + TF_LITE_REPORT_ERROR(error_reporter, "Feature generation failed"); + return; + } + previous_time = current_time; + // If no new audio samples have been received since last time, don't bother + // running the network model. + if (how_many_new_slices == 0) { + return; + } + + // Copy feature buffer to input tensor + for (int i = 0; i < kFeatureElementCount; i++) { + model_input_buffer[i] = feature_buffer[i]; + } + + // Run the model on the spectrogram input and make sure it succeeds. + EventStartCv(1, current_time, how_many_new_slices); + TfLiteStatus invoke_status = interpreter->Invoke(); + EventStopCv(1, invoke_status, 0U); + if (invoke_status != kTfLiteOk) { + TF_LITE_REPORT_ERROR(error_reporter, "Invoke failed"); + return; + } + + // Obtain a pointer to the output tensor + TfLiteTensor* output = interpreter->output(0); + // Determine whether a command was recognized based on the output of inference + const char* found_command = nullptr; + uint8_t score = 0; + bool is_new_command = false; + EventStartCv(2, current_time, 0U); + TfLiteStatus process_status = recognizer->ProcessLatestResults( + output, current_time, &found_command, &score, &is_new_command); + EventStopCv(2, process_status, score); + if (process_status != kTfLiteOk) { + TF_LITE_REPORT_ERROR(error_reporter, + "RecognizeCommands::ProcessLatestResults() failed"); + return; + } + // Do something based on the recognized command. The default implementation + // just prints to the error console, but you should replace this with your + // own function for a real application. + RespondToCommand(error_reporter, current_time, found_command, score, + is_new_command); +} diff --git a/micro_speech/src/main_functions.h b/micro_speech/src/main_functions.h new file mode 100644 index 0000000..0ac0677 --- /dev/null +++ b/micro_speech/src/main_functions.h @@ -0,0 +1,37 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_MAIN_FUNCTIONS_H_ +#define TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_MAIN_FUNCTIONS_H_ + +// Expose a C friendly interface for main functions. +#ifdef __cplusplus +extern "C" { +#endif + +// Initializes all data needed for the example. The name is important, and needs +// to be setup() for Arduino compatibility. +void setup(); + +// Runs one iteration of data gathering and inference. This should be called +// repeatedly from the application code. The name needs to be loop() for Arduino +// compatibility. +void loop(); + +#ifdef __cplusplus +} +#endif + +#endif // TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_MAIN_FUNCTIONS_H_ diff --git a/micro_speech/src/micro_features/micro_features_generator.cc b/micro_speech/src/micro_features/micro_features_generator.cc new file mode 100644 index 0000000..a8bd680 --- /dev/null +++ b/micro_speech/src/micro_features/micro_features_generator.cc @@ -0,0 +1,116 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 "micro_features/micro_features_generator.h" + +#include +#include + +#include "microfrontend/lib/frontend.h" +#include "microfrontend/lib/frontend_util.h" +#include "micro_features/micro_model_settings.h" + +// Configure FFT to output 16 bit fixed point. +#define FIXED_POINT 16 + +namespace { + +FrontendState g_micro_features_state; +bool g_is_first_time = true; + +} // namespace + +TfLiteStatus InitializeMicroFeatures(tflite::ErrorReporter* error_reporter) { + FrontendConfig config; + config.window.size_ms = kFeatureSliceDurationMs; + config.window.step_size_ms = kFeatureSliceStrideMs; + config.noise_reduction.smoothing_bits = 10; + config.filterbank.num_channels = kFeatureSliceSize; + config.filterbank.lower_band_limit = 125.0; + config.filterbank.upper_band_limit = 7500.0; + config.noise_reduction.smoothing_bits = 10; + config.noise_reduction.even_smoothing = 0.025; + config.noise_reduction.odd_smoothing = 0.06; + config.noise_reduction.min_signal_remaining = 0.05; + config.pcan_gain_control.enable_pcan = 1; + config.pcan_gain_control.strength = 0.95; + config.pcan_gain_control.offset = 80.0; + config.pcan_gain_control.gain_bits = 21; + config.log_scale.enable_log = 1; + config.log_scale.scale_shift = 6; + if (!FrontendPopulateState(&config, &g_micro_features_state, + kAudioSampleFrequency)) { + TF_LITE_REPORT_ERROR(error_reporter, "FrontendPopulateState() failed"); + return kTfLiteError; + } + g_is_first_time = true; + return kTfLiteOk; +} + +// This is not exposed in any header, and is only used for testing, to ensure +// that the state is correctly set up before generating results. +void SetMicroFeaturesNoiseEstimates(const uint32_t* estimate_presets) { + for (int i = 0; i < g_micro_features_state.filterbank.num_channels; ++i) { + g_micro_features_state.noise_reduction.estimate[i] = estimate_presets[i]; + } +} + +TfLiteStatus GenerateMicroFeatures(tflite::ErrorReporter* error_reporter, + const int16_t* input, int input_size, + int output_size, int8_t* output, + size_t* num_samples_read) { + const int16_t* frontend_input; + if (g_is_first_time) { + frontend_input = input; + g_is_first_time = false; + } else { + frontend_input = input + 160; + } + FrontendOutput frontend_output = FrontendProcessSamples( + &g_micro_features_state, frontend_input, input_size, num_samples_read); + + for (size_t i = 0; i < frontend_output.size; ++i) { + // These scaling values are derived from those used in input_data.py in the + // training pipeline. + // The feature pipeline outputs 16-bit signed integers in roughly a 0 to 670 + // range. In training, these are then arbitrarily divided by 25.6 to get + // float values in the rough range of 0.0 to 26.0. This scaling is performed + // for historical reasons, to match up with the output of other feature + // generators. + // The process is then further complicated when we quantize the model. This + // means we have to scale the 0.0 to 26.0 real values to the -128 to 127 + // signed integer numbers. + // All this means that to get matching values from our integer feature + // output into the tensor input, we have to perform: + // input = (((feature / 25.6) / 26.0) * 256) - 128 + // To simplify this and perform it in 32-bit integer math, we rearrange to: + // input = (feature * 256) / (25.6 * 26.0) - 128 + constexpr int32_t value_scale = 256; + constexpr int32_t value_div = static_cast((25.6f * 26.0f) + 0.5f); + int32_t value = + ((frontend_output.values[i] * value_scale) + (value_div / 2)) / + value_div; + value -= 128; + if (value < -128) { + value = -128; + } + if (value > 127) { + value = 127; + } + output[i] = value; + } + + return kTfLiteOk; +} diff --git a/micro_speech/src/micro_features/micro_features_generator.h b/micro_speech/src/micro_features/micro_features_generator.h new file mode 100644 index 0000000..2930423 --- /dev/null +++ b/micro_speech/src/micro_features/micro_features_generator.h @@ -0,0 +1,32 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_MICRO_FEATURES_MICRO_FEATURES_GENERATOR_H_ +#define TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_MICRO_FEATURES_MICRO_FEATURES_GENERATOR_H_ + +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/micro/micro_error_reporter.h" + +// Sets up any resources needed for the feature generation pipeline. +TfLiteStatus InitializeMicroFeatures(tflite::ErrorReporter* error_reporter); + +// Converts audio sample data into a more compact form that's appropriate for +// feeding into a neural network. +TfLiteStatus GenerateMicroFeatures(tflite::ErrorReporter* error_reporter, + const int16_t* input, int input_size, + int output_size, int8_t* output, + size_t* num_samples_read); + +#endif // TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_MICRO_FEATURES_MICRO_FEATURES_GENERATOR_H_ diff --git a/micro_speech/src/micro_features/micro_features_generator_test.cc b/micro_speech/src/micro_features/micro_features_generator_test.cc new file mode 100644 index 0000000..8043170 --- /dev/null +++ b/micro_speech/src/micro_features/micro_features_generator_test.cc @@ -0,0 +1,104 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 "micro_features/micro_features_generator.h" + +#include "tensorflow/lite/c/common.h" +#include "micro_features/no_feature_data_slice.h" +#include "micro_features/yes_feature_data_slice.h" +#include "no_30ms_sample_data.h" +#include "yes_30ms_sample_data.h" +#include "tensorflow/lite/micro/micro_error_reporter.h" +#include "tensorflow/lite/micro/testing/micro_test.h" + +// This is a test-only API, not exposed in any public headers, so declare it. +void SetMicroFeaturesNoiseEstimates(const uint32_t* estimate_presets); + +TF_LITE_MICRO_TESTS_BEGIN + +TF_LITE_MICRO_TEST(TestMicroFeaturesGeneratorYes) { + tflite::MicroErrorReporter micro_error_reporter; + + TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, + InitializeMicroFeatures(µ_error_reporter)); + + // The micro features pipeline retains state from previous calls to help + // estimate the background noise. Unfortunately this makes it harder to + // exactly reproduce results in a test environment, so use a known snapshot + // of the parameters at the point that the golden feature values were + // created. + const uint32_t yes_estimate_presets[] = { + 1062898, 2644477, 1257642, 1864718, 412722, 725703, 395721, 474082, + 173046, 255856, 158966, 153736, 69181, 199100, 144493, 227740, + 110573, 164330, 79666, 144650, 122947, 476799, 398553, 497493, + 322152, 1140005, 566716, 690605, 308902, 347481, 109891, 170457, + 73901, 100975, 42963, 72325, 34183, 20207, 6640, 9468, + }; + SetMicroFeaturesNoiseEstimates(yes_estimate_presets); + + int8_t yes_calculated_data[g_yes_feature_data_slice_size]; + size_t num_samples_read; + TfLiteStatus yes_status = GenerateMicroFeatures( + µ_error_reporter, g_yes_30ms_sample_data, + g_yes_30ms_sample_data_size, g_yes_feature_data_slice_size, + yes_calculated_data, &num_samples_read); + TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, yes_status); + + for (int i = 0; i < g_yes_feature_data_slice_size; ++i) { + const int expected = g_yes_feature_data_slice[i]; + const int actual = yes_calculated_data[i]; + TF_LITE_MICRO_EXPECT_EQ(expected, actual); + if (expected != actual) { + TF_LITE_REPORT_ERROR(µ_error_reporter, + "Expected value %d but found %d", expected, actual); + } + } +} + +TF_LITE_MICRO_TEST(TestMicroFeaturesGeneratorNo) { + tflite::MicroErrorReporter micro_error_reporter; + + TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, + InitializeMicroFeatures(µ_error_reporter)); + // As we did for the previous features, set known good noise state + // parameters. + const uint32_t no_estimate_presets[] = { + 2563964, 1909393, 559801, 538670, 203643, 175959, 75088, 139491, + 59691, 95307, 43865, 129263, 52517, 80058, 51330, 100731, + 76674, 76262, 15497, 22598, 13778, 21460, 8946, 17806, + 10023, 18810, 8002, 10842, 7578, 9983, 6267, 10759, + 8946, 18488, 9691, 39785, 9939, 17835, 9671, 18512, + }; + SetMicroFeaturesNoiseEstimates(no_estimate_presets); + + int8_t no_calculated_data[g_no_feature_data_slice_size]; + size_t num_samples_read; + TfLiteStatus no_status = GenerateMicroFeatures( + µ_error_reporter, g_no_30ms_sample_data, g_no_30ms_sample_data_size, + g_no_feature_data_slice_size, no_calculated_data, &num_samples_read); + TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, no_status); + + for (size_t i = 0; i < g_no_feature_data_slice_size; ++i) { + const int expected = g_no_feature_data_slice[i]; + const int actual = no_calculated_data[i]; + TF_LITE_MICRO_EXPECT_EQ(expected, actual); + if (expected != actual) { + TF_LITE_REPORT_ERROR(µ_error_reporter, + "Expected value %d but found %d", expected, actual); + } + } +} + +TF_LITE_MICRO_TESTS_END diff --git a/micro_speech/src/micro_features/micro_model_settings.cc b/micro_speech/src/micro_features/micro_model_settings.cc new file mode 100644 index 0000000..7080fe1 --- /dev/null +++ b/micro_speech/src/micro_features/micro_model_settings.cc @@ -0,0 +1,23 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 "micro_features/micro_model_settings.h" + +const char* kCategoryLabels[kCategoryCount] = { + "silence", + "unknown", + "yes", + "no", +}; diff --git a/micro_speech/src/micro_features/micro_model_settings.h b/micro_speech/src/micro_features/micro_model_settings.h new file mode 100644 index 0000000..e542213 --- /dev/null +++ b/micro_speech/src/micro_features/micro_model_settings.h @@ -0,0 +1,43 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_MICRO_FEATURES_MICRO_MODEL_SETTINGS_H_ +#define TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_MICRO_FEATURES_MICRO_MODEL_SETTINGS_H_ + +// Keeping these as constant expressions allow us to allocate fixed-sized arrays +// on the stack for our working memory. + +// The size of the input time series data we pass to the FFT to produce the +// frequency information. This has to be a power of two, and since we're dealing +// with 30ms of 16KHz inputs, which means 480 samples, this is the next value. +constexpr int kMaxAudioSampleSize = 512; +constexpr int kAudioSampleFrequency = 16000; + +// The following values are derived from values used during model training. +// If you change the way you preprocess the input, update all these constants. +constexpr int kFeatureSliceSize = 40; +constexpr int kFeatureSliceCount = 49; +constexpr int kFeatureElementCount = (kFeatureSliceSize * kFeatureSliceCount); +constexpr int kFeatureSliceStrideMs = 20; +constexpr int kFeatureSliceDurationMs = 30; + +// Variables for the model's output categories. +constexpr int kSilenceIndex = 0; +constexpr int kUnknownIndex = 1; +// If you modify the output categories, you need to update the following values. +constexpr int kCategoryCount = 4; +extern const char* kCategoryLabels[kCategoryCount]; + +#endif // TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_MICRO_FEATURES_MICRO_MODEL_SETTINGS_H_ diff --git a/micro_speech/src/micro_features/model.cc b/micro_speech/src/micro_features/model.cc new file mode 100644 index 0000000..b53d879 --- /dev/null +++ b/micro_speech/src/micro_features/model.cc @@ -0,0 +1,1596 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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. +==============================================================================*/ + +// This is a standard TensorFlow Lite FlatBuffer model file that has been +// converted into a C data array, so it can be easily compiled into a binary +// for devices that don't have a file system. It was created using the command: +// xxd -i model.tflite > model.cc + +#include "micro_features/model.h" + +// We need to keep the data array aligned on some architectures. +#ifdef __has_attribute +#define HAVE_ATTRIBUTE(x) __has_attribute(x) +#else +#define HAVE_ATTRIBUTE(x) 0 +#endif +#if HAVE_ATTRIBUTE(aligned) || (defined(__GNUC__) && !defined(__clang__)) +#define DATA_ALIGN_ATTRIBUTE __attribute__((aligned(4))) +#else +#define DATA_ALIGN_ATTRIBUTE +#endif + +const unsigned char g_model[] DATA_ALIGN_ATTRIBUTE = { + 0x20, 0x00, 0x00, 0x00, 0x54, 0x46, 0x4c, 0x33, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x12, 0x00, 0x1c, 0x00, 0x04, 0x00, 0x08, 0x00, 0x0c, 0x00, + 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x18, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x94, 0x48, 0x00, 0x00, 0x34, 0x42, 0x00, 0x00, + 0x1c, 0x42, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0c, 0x00, + 0x04, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x0b, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x6d, 0x69, 0x6e, 0x5f, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xd4, 0x41, 0x00, 0x00, + 0xb4, 0x41, 0x00, 0x00, 0x24, 0x03, 0x00, 0x00, 0xf4, 0x02, 0x00, 0x00, + 0xec, 0x02, 0x00, 0x00, 0xe4, 0x02, 0x00, 0x00, 0xc4, 0x02, 0x00, 0x00, + 0xbc, 0x02, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x16, 0xbd, 0xff, 0xff, + 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x31, 0x2e, 0x35, 0x2e, + 0x30, 0x00, 0x00, 0x00, 0x94, 0xba, 0xff, 0xff, 0x98, 0xba, 0xff, 0xff, + 0x32, 0xbd, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, + 0xfa, 0xee, 0x28, 0xc4, 0xee, 0xfe, 0xcf, 0x0f, 0x1e, 0xf7, 0x1f, 0x06, + 0x0d, 0xed, 0xe9, 0x83, 0x5c, 0xc9, 0x18, 0xe3, 0xf9, 0x14, 0x28, 0x2a, + 0x09, 0xf2, 0x18, 0x34, 0x62, 0xea, 0xef, 0xd6, 0x36, 0xb7, 0x1e, 0xf7, + 0x3b, 0x22, 0x28, 0x39, 0xc2, 0x9d, 0xf1, 0x07, 0x5e, 0x0b, 0x1e, 0x2c, + 0x07, 0xdd, 0xfd, 0xc3, 0xd8, 0x4a, 0xf3, 0x28, 0xa7, 0x16, 0xd5, 0xf1, + 0xc3, 0x05, 0xfd, 0x27, 0xcc, 0xba, 0x1e, 0xcb, 0xd7, 0x3d, 0xd4, 0x29, + 0x00, 0xfd, 0x28, 0x44, 0xfb, 0xf2, 0xf3, 0xb6, 0x4f, 0xcf, 0x09, 0xf0, + 0xfa, 0x45, 0x41, 0x49, 0x05, 0xc5, 0x17, 0x5d, 0x64, 0x00, 0xf8, 0xee, + 0x48, 0x17, 0xf4, 0xe9, 0x2e, 0x4b, 0x2e, 0x3f, 0xdf, 0xee, 0xe4, 0x08, + 0x38, 0xf1, 0x16, 0x13, 0x2f, 0x2a, 0xed, 0xc2, 0xbf, 0x36, 0xf4, 0x02, + 0xcf, 0xaa, 0xd2, 0xfa, 0xac, 0x13, 0xf6, 0xe8, 0xb5, 0x68, 0x12, 0xb6, + 0xce, 0x0e, 0xdf, 0x58, 0xe4, 0x49, 0x14, 0x15, 0x03, 0xed, 0xfa, 0xd4, + 0x40, 0xa7, 0xf6, 0xca, 0xfb, 0x00, 0x4d, 0x5e, 0xe4, 0x55, 0x1d, 0x30, + 0x45, 0xe2, 0xfc, 0x01, 0x48, 0x81, 0xe9, 0xf1, 0x1e, 0xfc, 0x21, 0x32, + 0xed, 0x4b, 0xed, 0xfa, 0x2f, 0xd2, 0xfa, 0xfb, 0x4d, 0xa7, 0xed, 0xc7, + 0x92, 0xdf, 0xe6, 0xdb, 0xf8, 0x1f, 0xd9, 0xfa, 0x91, 0xf5, 0xe5, 0xc5, + 0x8c, 0x17, 0x0f, 0xb9, 0xd2, 0xc7, 0xfe, 0x68, 0xd3, 0x51, 0x2e, 0x49, + 0x1f, 0xbd, 0x01, 0xeb, 0x31, 0x17, 0xf0, 0xef, 0xff, 0xb8, 0x5d, 0x62, + 0x02, 0x0f, 0x1f, 0x78, 0x6a, 0xb0, 0xf9, 0xfe, 0x4f, 0xcc, 0xd3, 0xff, + 0x0a, 0x96, 0x1e, 0x2c, 0xed, 0xbc, 0xf4, 0x0b, 0x42, 0xc8, 0xf1, 0xea, + 0x6e, 0x58, 0xec, 0xc4, 0x99, 0xae, 0xdc, 0xd7, 0x12, 0x87, 0xd8, 0x06, + 0xa2, 0xc2, 0xe6, 0xa2, 0x81, 0x24, 0xe9, 0xac, 0xce, 0xb6, 0x15, 0x6b, + 0xba, 0x00, 0x19, 0x58, 0x29, 0xb6, 0xfe, 0x01, 0x25, 0x96, 0xd2, 0xec, + 0x0e, 0x9c, 0x60, 0x5f, 0xe9, 0xf4, 0xf5, 0x69, 0x6b, 0xb5, 0xe1, 0xf6, + 0x5e, 0xb7, 0xb1, 0xe5, 0x11, 0x9b, 0x18, 0x10, 0xe3, 0xe1, 0xe0, 0x0d, + 0x4f, 0xa5, 0xde, 0xe5, 0x6f, 0xe2, 0xfb, 0x99, 0x82, 0xa5, 0xc9, 0xb6, + 0x1f, 0x46, 0xf3, 0x04, 0xc6, 0xca, 0xd6, 0x97, 0x90, 0x1d, 0xc0, 0x95, + 0xf0, 0x19, 0x30, 0x77, 0xc2, 0x3c, 0xfa, 0x24, 0x02, 0x4d, 0x06, 0x07, + 0x15, 0x02, 0xb0, 0xe7, 0x27, 0x22, 0x67, 0x4d, 0xf1, 0xc2, 0xf4, 0x64, + 0x38, 0x40, 0xdf, 0xf6, 0x3a, 0x43, 0xb8, 0xe1, 0x0d, 0x15, 0x11, 0xfe, + 0xf5, 0xec, 0xf9, 0xe5, 0x22, 0x36, 0xe4, 0xfd, 0x6d, 0xbf, 0x0d, 0x8e, + 0xb7, 0x15, 0xbf, 0x9f, 0x16, 0xad, 0x0a, 0x02, 0x8e, 0x14, 0xda, 0x9b, + 0x8e, 0xc3, 0xa6, 0xca, 0xf5, 0x7f, 0x51, 0x56, 0xc1, 0xb3, 0xd9, 0x35, + 0xf8, 0x7f, 0x04, 0x0a, 0x03, 0x3f, 0xbe, 0xee, 0x19, 0x68, 0x78, 0x50, + 0xf9, 0xa7, 0xf7, 0x7f, 0x1d, 0x76, 0xdb, 0xe8, 0x33, 0xb9, 0xd7, 0xe7, + 0xe8, 0x69, 0x15, 0xf7, 0xf5, 0xb2, 0xfe, 0xe8, 0xf3, 0x5b, 0xe2, 0x06, + 0x6e, 0x09, 0x36, 0xb7, 0xcc, 0x38, 0xbf, 0x8a, 0x28, 0x14, 0x2e, 0x18, + 0xa7, 0x26, 0xcb, 0xb2, 0x95, 0x37, 0xac, 0xcd, 0xd7, 0x51, 0x67, 0x44, + 0xcd, 0x31, 0xde, 0x04, 0xe9, 0x6a, 0x00, 0x13, 0x0a, 0x0c, 0xdd, 0x16, + 0xe0, 0x24, 0x7e, 0x49, 0xf1, 0xb5, 0x04, 0x52, 0x01, 0x50, 0xdd, 0xf5, + 0x26, 0xc9, 0xf4, 0xf8, 0xd6, 0x31, 0x1b, 0xd0, 0xef, 0x03, 0x0a, 0xc0, + 0xd4, 0x4f, 0xe2, 0xfd, 0x72, 0xf4, 0x5a, 0xc9, 0xd7, 0x31, 0xc0, 0x8e, + 0x17, 0x5e, 0x57, 0x00, 0xb4, 0x3a, 0xc8, 0xd2, 0x92, 0x32, 0xcb, 0xd8, + 0xc3, 0xa6, 0x63, 0x26, 0xcf, 0xbc, 0xe8, 0x57, 0x9b, 0xe9, 0xf7, 0x1c, + 0xea, 0x12, 0xf1, 0xf7, 0xdb, 0xb9, 0x7f, 0x16, 0xf6, 0xe0, 0x08, 0x70, + 0xa2, 0xed, 0xcc, 0xf1, 0x1e, 0x10, 0x04, 0xf7, 0xa9, 0xb7, 0x34, 0xaa, + 0x0a, 0xdb, 0x2a, 0xa6, 0xb6, 0x10, 0xea, 0xf8, 0x5e, 0x06, 0x72, 0xdd, + 0xd0, 0xb9, 0xd6, 0xa0, 0x10, 0x9f, 0x5a, 0x17, 0xb1, 0xe7, 0xc0, 0x01, + 0x9d, 0x01, 0xe0, 0xe0, 0xaf, 0x9c, 0x46, 0xd8, 0xaf, 0xe8, 0xce, 0x02, + 0x8a, 0xbb, 0xe4, 0xf6, 0xf3, 0x36, 0x07, 0xca, 0xcb, 0x87, 0x6e, 0xcc, + 0xd6, 0x9e, 0x0a, 0x2a, 0x81, 0xd7, 0xcf, 0xc0, 0x04, 0xeb, 0x24, 0xcc, + 0xc9, 0x95, 0x33, 0x81, 0xf7, 0xad, 0x1c, 0x9c, 0xa4, 0xd6, 0xf9, 0xe6, + 0x3d, 0x84, 0x7f, 0xcc, 0xd4, 0xb0, 0xf4, 0xa2, 0xe9, 0x3c, 0x36, 0xee, + 0xd5, 0xcf, 0xcd, 0x2d, 0x28, 0xbd, 0xff, 0xff, 0xc2, 0xbf, 0xff, 0xff, + 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x31, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x48, 0xbd, 0xff, 0xff, 0x4c, 0xbd, 0xff, 0xff, 0xe6, 0xbf, 0xff, 0xff, + 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x8a, 0xfe, 0xff, 0xff, + 0xa9, 0x00, 0x00, 0x00, 0xd0, 0xff, 0xff, 0xff, 0xd0, 0x00, 0x00, 0x00, + 0x52, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4f, 0xfb, 0xff, 0xff, + 0x4a, 0xfd, 0xff, 0xff, 0x12, 0xc0, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, + 0x80, 0x3e, 0x00, 0x00, 0xff, 0xf9, 0xfd, 0x0a, 0x07, 0x08, 0x07, 0x03, + 0x07, 0xf2, 0xd1, 0x09, 0xf0, 0xe9, 0x28, 0x09, 0xdf, 0x05, 0xfa, 0xf0, + 0xe8, 0xe3, 0x13, 0x0e, 0x08, 0xef, 0xd3, 0xee, 0x0f, 0xe8, 0xeb, 0x14, + 0xf7, 0xed, 0xfd, 0x1f, 0xe8, 0xd5, 0xeb, 0xfc, 0x0e, 0xf4, 0xf7, 0x07, + 0x05, 0xea, 0xf6, 0x1f, 0xf8, 0xdb, 0xdc, 0x0b, 0x03, 0xdd, 0xd8, 0xf3, + 0x0f, 0x19, 0xe1, 0x09, 0xfc, 0xe4, 0x02, 0x04, 0xf1, 0x04, 0xeb, 0xf3, + 0x1e, 0x06, 0xfd, 0x11, 0xfc, 0xfa, 0xf6, 0x1f, 0x0f, 0x02, 0xf5, 0xf7, + 0xff, 0x24, 0xdf, 0xf7, 0xf8, 0xf3, 0xf6, 0xe9, 0xef, 0x03, 0xdd, 0xf2, + 0x28, 0xe1, 0xf2, 0x22, 0xf4, 0x09, 0xf7, 0xf9, 0xf0, 0xd4, 0xf9, 0xee, + 0xff, 0x14, 0xda, 0xf3, 0x11, 0xe2, 0xf6, 0x0c, 0xf2, 0xeb, 0xf8, 0xe8, + 0xe3, 0x08, 0x02, 0x17, 0xf4, 0x0b, 0x0c, 0x27, 0xe6, 0x02, 0x03, 0xf9, + 0x14, 0x18, 0xf6, 0xeb, 0x1f, 0x0c, 0xf1, 0xee, 0xfc, 0x08, 0xf0, 0xfe, + 0xfd, 0xee, 0x17, 0xfd, 0x1c, 0xef, 0xfd, 0xde, 0x04, 0x05, 0xf0, 0x31, + 0xfa, 0x0b, 0xdc, 0x0d, 0xed, 0xf5, 0xfa, 0xf4, 0x08, 0x0c, 0xd7, 0x1e, + 0x15, 0x03, 0xf5, 0x02, 0xf4, 0xfb, 0xed, 0x01, 0xfe, 0xd6, 0x1f, 0xfd, + 0xfd, 0x0e, 0xfa, 0x06, 0xf1, 0xf9, 0xe2, 0x16, 0xe9, 0xf1, 0x03, 0x0d, + 0x0d, 0xdf, 0xf9, 0x1a, 0x0e, 0xf6, 0xfc, 0x0a, 0x19, 0xe2, 0xe0, 0x09, + 0x15, 0xf0, 0xf1, 0x06, 0xf1, 0xe1, 0xef, 0x1a, 0x08, 0xe8, 0xfd, 0x12, + 0x14, 0x06, 0xf1, 0xfc, 0xea, 0xfb, 0xf7, 0xea, 0x1d, 0x09, 0xfa, 0xf6, + 0x08, 0xf2, 0xe7, 0xf8, 0xfc, 0x16, 0xf5, 0x0e, 0x08, 0xf9, 0x0a, 0x03, + 0x26, 0xd8, 0x02, 0xf5, 0xf6, 0xf6, 0xef, 0x1f, 0xe4, 0xe2, 0xfb, 0x02, + 0x1b, 0xe6, 0xde, 0x00, 0xf2, 0xed, 0xfb, 0x18, 0xe4, 0x16, 0x1a, 0x1d, + 0xf1, 0xf6, 0xea, 0x16, 0x05, 0xde, 0xfb, 0x18, 0xf5, 0xe4, 0xfe, 0xe2, + 0x1b, 0x1c, 0x0c, 0xe8, 0x02, 0xee, 0xfb, 0x07, 0x24, 0xf2, 0xe9, 0xfa, + 0x0d, 0x05, 0xf1, 0x03, 0xfe, 0xf6, 0x19, 0x06, 0xff, 0xf9, 0x04, 0xfb, + 0x15, 0xef, 0xf1, 0xf8, 0xe9, 0xe1, 0x10, 0x04, 0xfc, 0xe6, 0x1f, 0xed, + 0x0b, 0xef, 0x00, 0x1e, 0xe6, 0x16, 0xf3, 0x09, 0xfd, 0x08, 0x08, 0x06, + 0x06, 0x23, 0xdf, 0xfc, 0x08, 0xf4, 0xea, 0x0c, 0xf2, 0xe6, 0x18, 0xf5, + 0x02, 0xf9, 0x50, 0x09, 0x01, 0xda, 0x0b, 0x05, 0x12, 0x18, 0xef, 0x04, + 0x0e, 0xd9, 0xff, 0xdc, 0xf6, 0x16, 0xf9, 0xf4, 0xec, 0xff, 0xea, 0xe6, + 0xfa, 0x0a, 0xed, 0xef, 0x02, 0xf0, 0x25, 0x21, 0xf1, 0x26, 0xf5, 0xed, + 0x09, 0xea, 0xea, 0x24, 0xfa, 0x11, 0xfc, 0xdf, 0xf3, 0x0a, 0x28, 0x0c, + 0x19, 0xff, 0xf5, 0xd6, 0x0e, 0xe2, 0x2a, 0x06, 0xfa, 0x03, 0xf9, 0xe6, + 0xef, 0x23, 0xf9, 0xfa, 0xe6, 0xfe, 0xfc, 0x03, 0x06, 0x1a, 0xf9, 0x08, + 0xe0, 0xe5, 0xff, 0x05, 0x01, 0xe7, 0x12, 0x02, 0x1d, 0x05, 0x03, 0x05, + 0x0b, 0xee, 0xed, 0xfc, 0x0f, 0xf3, 0x02, 0xe0, 0x15, 0xdf, 0x02, 0xed, + 0x10, 0x26, 0xef, 0x0d, 0x06, 0xee, 0xef, 0xf6, 0xeb, 0x11, 0x09, 0xf4, + 0xf7, 0x06, 0x0f, 0x01, 0x2a, 0x0b, 0x01, 0xdd, 0xfc, 0xf4, 0xf1, 0x17, + 0x03, 0x04, 0x07, 0xfc, 0x22, 0xfc, 0xde, 0xfe, 0x0b, 0x03, 0xf3, 0xfb, + 0x0c, 0x25, 0x04, 0x19, 0x04, 0x03, 0x01, 0xfa, 0xfb, 0xf7, 0xf6, 0x0e, + 0x15, 0x0e, 0x09, 0xff, 0x06, 0xfa, 0xfb, 0x1e, 0xfb, 0x05, 0x22, 0xf9, + 0xfe, 0xf7, 0x1d, 0xed, 0xdf, 0x18, 0x09, 0xeb, 0xef, 0x04, 0x12, 0xea, + 0xdf, 0xfb, 0xda, 0xf6, 0xdf, 0x17, 0xef, 0xef, 0xe1, 0x1a, 0xd9, 0xe2, + 0xe2, 0xfc, 0x05, 0x11, 0xf6, 0xee, 0xe8, 0xf2, 0xe1, 0x08, 0x26, 0x04, + 0xed, 0x03, 0xe0, 0xfb, 0xee, 0x0c, 0xee, 0xf6, 0x04, 0x2d, 0xf2, 0xd3, + 0xf4, 0xe0, 0xf8, 0x0c, 0xfe, 0x11, 0x0b, 0xd7, 0xfd, 0x18, 0x07, 0x0d, + 0x07, 0x08, 0xf4, 0xc6, 0x0a, 0x0a, 0x1f, 0x0c, 0xf4, 0x1d, 0x02, 0x0b, + 0x09, 0x0e, 0x21, 0xff, 0x17, 0x0b, 0x0d, 0xf2, 0xed, 0xd7, 0x0a, 0xf8, + 0x03, 0x06, 0xfa, 0xe5, 0xfd, 0x03, 0x14, 0x0f, 0xe9, 0x1a, 0xf4, 0xda, + 0x01, 0xe6, 0x09, 0x06, 0x11, 0x0d, 0xfd, 0xeb, 0x16, 0x23, 0xfa, 0x00, + 0x0b, 0x17, 0xf7, 0xda, 0xd7, 0x1b, 0xfa, 0x01, 0x03, 0x05, 0xfe, 0xd6, + 0x02, 0xee, 0xee, 0x02, 0xf3, 0x06, 0xed, 0x03, 0xec, 0x01, 0xf2, 0x0f, + 0x05, 0x17, 0x0b, 0xfb, 0x0f, 0x05, 0x03, 0x13, 0xff, 0x06, 0x02, 0xf5, + 0xf4, 0x18, 0x2b, 0xf0, 0x00, 0x17, 0xfc, 0xfd, 0x05, 0x0b, 0x0e, 0x14, + 0xe1, 0x24, 0x08, 0x24, 0xe6, 0xeb, 0x21, 0x12, 0xfb, 0x12, 0xe7, 0xf4, + 0xe8, 0x0e, 0x18, 0xee, 0xf5, 0xf3, 0xd9, 0xf3, 0xdb, 0xec, 0x0c, 0x1e, + 0xcf, 0x14, 0xdb, 0xe3, 0xdc, 0x02, 0x0c, 0xfb, 0xdb, 0x1b, 0xd0, 0xfe, + 0xf9, 0xfe, 0x2a, 0xf5, 0x00, 0x0b, 0xcd, 0xe0, 0xe2, 0x0e, 0x04, 0xf8, + 0xda, 0x1c, 0xe5, 0x0f, 0xe8, 0xf4, 0xf7, 0x15, 0x06, 0xf8, 0x02, 0xf7, + 0x0f, 0xfb, 0x17, 0xf9, 0xda, 0x01, 0xda, 0xd1, 0xf6, 0x02, 0xfd, 0x16, + 0xf1, 0xe4, 0xfa, 0x07, 0xee, 0x0a, 0xf3, 0xfd, 0xf2, 0x23, 0xf0, 0xe1, + 0x0a, 0x1a, 0x12, 0x1f, 0xef, 0x27, 0x09, 0xf1, 0x0c, 0x13, 0x23, 0xfd, + 0xf5, 0x03, 0xfe, 0x09, 0xfd, 0x16, 0xf8, 0x07, 0x08, 0x25, 0x08, 0xf8, + 0xf6, 0x0a, 0xf1, 0xf5, 0x07, 0x09, 0x05, 0xcc, 0xf8, 0x08, 0x13, 0xf9, + 0x1d, 0x11, 0x0f, 0xdc, 0xee, 0xf3, 0x27, 0xf9, 0xf9, 0x22, 0xfa, 0x0d, + 0xe2, 0x13, 0xfb, 0x11, 0x03, 0x1e, 0xff, 0xfb, 0xed, 0xf1, 0x0e, 0x0b, + 0x0f, 0x00, 0x06, 0xe0, 0x15, 0xf3, 0x13, 0xfc, 0x18, 0xf9, 0xff, 0x09, + 0xfa, 0x1f, 0x12, 0xe5, 0xe2, 0x06, 0xf9, 0xf4, 0x07, 0x15, 0x0b, 0x04, + 0xdb, 0x0d, 0xeb, 0xf3, 0xe6, 0x06, 0xe5, 0xee, 0xd8, 0x22, 0xd8, 0x10, + 0xea, 0xf9, 0x1c, 0xf7, 0xd3, 0x11, 0xc3, 0xf8, 0xde, 0x05, 0x00, 0xe6, + 0x07, 0xfd, 0xd3, 0x03, 0xea, 0xe0, 0x13, 0x14, 0xcf, 0xeb, 0xcd, 0xd3, + 0xde, 0xf5, 0xf0, 0x0c, 0x0c, 0xfa, 0xeb, 0xd3, 0xfb, 0xfd, 0x08, 0xf9, + 0xf4, 0x10, 0xfa, 0xd3, 0xf4, 0x11, 0x11, 0xf8, 0xef, 0xf8, 0xf8, 0xf1, + 0xfc, 0xe1, 0xf7, 0x12, 0x04, 0xf4, 0xfb, 0xed, 0xef, 0x0c, 0xfd, 0x1c, + 0xfe, 0x0e, 0xfd, 0xe2, 0xfe, 0x0a, 0x02, 0xfe, 0xe6, 0x1f, 0xef, 0xe5, + 0xe6, 0xf8, 0x16, 0x27, 0xe8, 0x20, 0x05, 0xe3, 0xf1, 0xef, 0xee, 0xed, + 0x0d, 0x11, 0x16, 0xfb, 0xf3, 0xff, 0x14, 0x01, 0xff, 0x15, 0x10, 0x02, + 0xe5, 0x28, 0x29, 0x13, 0x13, 0x16, 0xe6, 0x00, 0xd2, 0x26, 0xfd, 0x03, + 0x04, 0x05, 0x07, 0x06, 0xf1, 0x0e, 0x05, 0x0d, 0xe2, 0x0f, 0x02, 0xe1, + 0x07, 0xf7, 0x1c, 0xfa, 0x14, 0x30, 0xf7, 0xee, 0x00, 0xfa, 0x3d, 0x06, + 0x1c, 0x04, 0x06, 0x07, 0x05, 0x1a, 0x10, 0xf6, 0xee, 0x0a, 0xeb, 0x04, + 0xeb, 0xdf, 0x1d, 0x09, 0xd5, 0xe8, 0xd6, 0xf4, 0xf0, 0x0f, 0x1d, 0xea, + 0xf2, 0xf8, 0xa6, 0x0b, 0xdc, 0x09, 0x08, 0x24, 0xee, 0x24, 0xaa, 0xe4, + 0xcb, 0x15, 0xef, 0xe7, 0xe9, 0x0c, 0xcf, 0x06, 0xe3, 0x12, 0x11, 0x00, + 0x07, 0x14, 0xd7, 0xde, 0xf6, 0x0f, 0x0b, 0x04, 0xfb, 0x0d, 0xf8, 0x0d, + 0xf6, 0x1b, 0xf1, 0x21, 0xdd, 0xfc, 0xf4, 0xe9, 0xf8, 0xe8, 0xf7, 0x06, + 0x03, 0x1e, 0xce, 0xe1, 0xea, 0xf6, 0x05, 0xf9, 0x16, 0x15, 0x04, 0xe0, + 0x14, 0xf7, 0x1e, 0x1c, 0x0a, 0x27, 0xef, 0xf3, 0x0f, 0xf3, 0xee, 0x04, + 0xf8, 0xf1, 0x07, 0xe3, 0x05, 0x0b, 0x00, 0x1c, 0x15, 0x27, 0x07, 0xf7, + 0xfa, 0x0b, 0xfa, 0xfa, 0x17, 0x13, 0xe1, 0xf5, 0xfb, 0x0c, 0x21, 0x2f, + 0xd7, 0xfb, 0xf5, 0xfd, 0xd3, 0xf4, 0x07, 0x0e, 0xfd, 0x0b, 0xfc, 0xfa, + 0xf5, 0x0e, 0x02, 0xfa, 0xfa, 0x19, 0xfd, 0xfa, 0xfc, 0x13, 0x24, 0x0c, + 0xe4, 0x31, 0xf8, 0x12, 0xf4, 0x04, 0x18, 0x29, 0x27, 0x19, 0xfc, 0x08, + 0x11, 0xe3, 0x07, 0xfe, 0x26, 0x40, 0x05, 0x02, 0x04, 0x02, 0x0f, 0xee, + 0xf4, 0x27, 0xea, 0xf4, 0xf5, 0x11, 0x26, 0x0b, 0xe7, 0x05, 0xd2, 0xf6, + 0xea, 0xfa, 0x0b, 0xf9, 0xfa, 0x16, 0xba, 0x00, 0xfb, 0x0d, 0x0b, 0xf9, + 0xe6, 0xf6, 0xc5, 0xf8, 0xf6, 0x01, 0x0f, 0xed, 0xed, 0x13, 0xcd, 0x0d, + 0xda, 0x06, 0x17, 0xee, 0x07, 0x1d, 0xb8, 0xfa, 0xe2, 0xea, 0xf2, 0xee, + 0x04, 0x00, 0xdc, 0xd0, 0xfb, 0xf5, 0xec, 0xfe, 0xf1, 0x0d, 0xf0, 0xdb, + 0xf9, 0x0d, 0x03, 0x03, 0x0e, 0x0a, 0xda, 0xd6, 0x01, 0xf2, 0x06, 0x14, + 0x1c, 0x1f, 0xe8, 0xe8, 0x0e, 0xfd, 0x0c, 0xf5, 0xf3, 0x3d, 0xf3, 0x05, + 0x10, 0xfa, 0x1b, 0x18, 0x08, 0x36, 0x09, 0xf1, 0xeb, 0xf9, 0x22, 0x01, + 0xf3, 0xf7, 0xff, 0xf0, 0x0c, 0xe9, 0x01, 0x29, 0x21, 0x15, 0x03, 0xee, + 0xe9, 0x1a, 0xf7, 0x15, 0x06, 0x25, 0xfa, 0xf0, 0xe4, 0xf1, 0x1f, 0x01, + 0xdc, 0x2d, 0xce, 0xe9, 0xea, 0x0b, 0x06, 0x2c, 0x0a, 0x30, 0xe7, 0x09, + 0xf4, 0xf0, 0x10, 0x29, 0xf9, 0x3d, 0xe7, 0xdc, 0xe4, 0xf7, 0x3b, 0x27, + 0x23, 0x3a, 0x0a, 0x06, 0x0e, 0xfd, 0x2c, 0x07, 0x2b, 0x1c, 0xfa, 0x00, + 0xf9, 0x11, 0xea, 0x14, 0xeb, 0xfc, 0x18, 0x03, 0xf1, 0x16, 0x12, 0x04, + 0xcf, 0x12, 0xdd, 0xe4, 0x0e, 0xf0, 0x09, 0xe8, 0xf3, 0xfb, 0xa8, 0xf9, + 0xee, 0xfb, 0x1e, 0x1d, 0xfd, 0x05, 0xab, 0xe5, 0xff, 0x01, 0xfe, 0x04, + 0xf9, 0x02, 0xb9, 0xdc, 0xdf, 0x05, 0xf1, 0xef, 0xf1, 0x1e, 0xc7, 0xee, + 0xf7, 0x1e, 0x00, 0x00, 0xf8, 0x10, 0xec, 0xe8, 0x04, 0x0f, 0xf6, 0xff, + 0x04, 0x09, 0xe0, 0x0a, 0x0e, 0xe4, 0xf0, 0xf1, 0x16, 0x2b, 0xd3, 0xe1, + 0x0a, 0xef, 0xf9, 0xfe, 0x0b, 0x22, 0xf5, 0x01, 0x0a, 0xf8, 0x02, 0x00, + 0x17, 0x19, 0xf3, 0x05, 0x21, 0xfa, 0xee, 0xee, 0x12, 0xf2, 0xfa, 0xf5, + 0x05, 0x12, 0xee, 0xe4, 0x28, 0xfa, 0xf1, 0x03, 0x15, 0x16, 0x18, 0xfd, + 0x0f, 0x21, 0x04, 0xf4, 0xe5, 0x0c, 0x06, 0x13, 0xde, 0x36, 0xe8, 0xfb, + 0xe7, 0xfd, 0xf6, 0x12, 0x0e, 0x1d, 0xea, 0xf8, 0xd4, 0xe8, 0x19, 0x07, + 0xe5, 0x1c, 0xf7, 0x0c, 0xef, 0x05, 0x0f, 0x09, 0xdd, 0x1a, 0xea, 0xd7, + 0xf9, 0xf9, 0x12, 0x17, 0x2e, 0x10, 0x08, 0xfe, 0x14, 0xf5, 0x1d, 0xfa, + 0x06, 0x33, 0xed, 0xfe, 0xf7, 0x11, 0xf0, 0x15, 0xe2, 0x24, 0xf6, 0x0a, + 0xe2, 0xfc, 0x23, 0x12, 0xdd, 0x11, 0xfd, 0xe5, 0x08, 0xff, 0x15, 0xf6, + 0xf1, 0x1b, 0xae, 0xfe, 0xe6, 0x15, 0x2c, 0x2d, 0x15, 0x15, 0xc5, 0xf8, + 0xea, 0xe7, 0x07, 0x04, 0xfe, 0x28, 0xa1, 0xf2, 0xe1, 0xf9, 0xf8, 0xff, + 0xf4, 0x22, 0xb4, 0xdb, 0x03, 0x20, 0xe6, 0xf3, 0x0e, 0x19, 0xe3, 0x0a, + 0xfa, 0xee, 0xf3, 0xe5, 0xd8, 0xf9, 0xf1, 0xde, 0x06, 0x05, 0xf2, 0xf5, + 0xe7, 0x16, 0xd8, 0xfe, 0x07, 0xea, 0xee, 0x0e, 0xfa, 0xff, 0xdb, 0xe7, + 0x03, 0xed, 0x01, 0xfd, 0x09, 0x1a, 0xfa, 0xe6, 0x05, 0x10, 0xe9, 0x01, + 0x1f, 0x13, 0xf7, 0xf6, 0xfb, 0x13, 0xff, 0xdb, 0xed, 0xfe, 0x0a, 0x10, + 0x09, 0x29, 0xf5, 0x04, 0xf5, 0x26, 0x0d, 0x0c, 0xf9, 0x16, 0xfa, 0x02, + 0xf4, 0x2e, 0xde, 0xf5, 0xe1, 0x1d, 0xfb, 0x02, 0x0b, 0x23, 0x07, 0xea, + 0xd9, 0x0a, 0xf3, 0x0a, 0x0f, 0x1e, 0xe7, 0xf1, 0xd7, 0x0b, 0xf6, 0xff, + 0x0d, 0x24, 0xcc, 0x0a, 0xee, 0xda, 0x14, 0x12, 0x11, 0x29, 0xf4, 0x1a, + 0xef, 0x0b, 0xfa, 0xec, 0x0c, 0x1b, 0xf4, 0xff, 0xf5, 0xef, 0x0f, 0x10, + 0xd4, 0x04, 0xf9, 0xf8, 0xec, 0xf9, 0x21, 0x05, 0xd3, 0x27, 0xf3, 0x17, + 0xff, 0xf6, 0x15, 0xf9, 0xed, 0x0a, 0xac, 0x02, 0xfd, 0xfb, 0x04, 0x29, + 0x06, 0x03, 0xb8, 0xe6, 0xd5, 0x17, 0x09, 0x1b, 0xf6, 0x1b, 0xab, 0xdc, + 0xdf, 0xfd, 0x06, 0x09, 0x09, 0x37, 0xbb, 0xed, 0x19, 0xd7, 0xe2, 0xdd, + 0x05, 0x01, 0xec, 0xfb, 0xe4, 0x0e, 0xeb, 0xf0, 0x03, 0x17, 0x04, 0xeb, + 0x09, 0xee, 0xeb, 0xe7, 0x0c, 0x16, 0xcb, 0x0e, 0x17, 0xd8, 0xe1, 0xf8, + 0x2b, 0x19, 0xde, 0xeb, 0x10, 0xf2, 0xff, 0xf8, 0xee, 0x0e, 0xe7, 0xf0, + 0x15, 0x08, 0xf8, 0xdf, 0x06, 0x0d, 0xf9, 0x14, 0xfa, 0x0b, 0x04, 0xfd, + 0x15, 0x23, 0x20, 0xff, 0xfd, 0x1d, 0x0c, 0xf1, 0xfe, 0x15, 0x0a, 0x02, + 0xed, 0xfe, 0xfb, 0x04, 0xfb, 0x1e, 0xdd, 0x05, 0xe0, 0x16, 0xf9, 0xf6, + 0xfd, 0x32, 0xdc, 0xf2, 0xd3, 0x08, 0xf4, 0xec, 0x17, 0x25, 0xe2, 0xf0, + 0xee, 0xf1, 0x0d, 0xfe, 0x13, 0x2d, 0x01, 0x11, 0xd4, 0xe4, 0x07, 0xfb, + 0x32, 0x11, 0x14, 0x07, 0xd7, 0x02, 0x10, 0xeb, 0x2b, 0x1d, 0x01, 0xfc, + 0xf3, 0xf0, 0x13, 0x1a, 0xdb, 0x20, 0x00, 0xf0, 0xf0, 0x05, 0x16, 0x03, + 0xd4, 0xe3, 0xc2, 0xf0, 0x06, 0x02, 0x1e, 0x0a, 0xec, 0x1f, 0xab, 0xea, + 0xfa, 0xe3, 0x20, 0x22, 0x03, 0x1b, 0xb3, 0x0e, 0xe3, 0xf3, 0x1d, 0x27, + 0xe3, 0x10, 0xa7, 0xda, 0xf3, 0x00, 0x0a, 0x0a, 0x04, 0xfb, 0xb2, 0x0f, + 0x0c, 0xf5, 0x07, 0xff, 0x13, 0x1e, 0xdb, 0xf6, 0xf9, 0xef, 0xe8, 0xe7, + 0xfb, 0x18, 0xeb, 0xec, 0x09, 0xda, 0xf1, 0xf0, 0x0b, 0x04, 0xe1, 0xfa, + 0x1c, 0x25, 0xee, 0x01, 0x0b, 0x29, 0xd7, 0x0c, 0x04, 0x0b, 0xef, 0xfd, + 0x1c, 0xfc, 0xf1, 0xfb, 0x0b, 0x0f, 0xdf, 0xed, 0x17, 0x38, 0x0c, 0xd7, + 0xff, 0xfd, 0x01, 0xfc, 0xfb, 0xfb, 0x18, 0x1a, 0x18, 0xe3, 0xf9, 0xf4, + 0xfa, 0x20, 0x06, 0x09, 0x11, 0x08, 0x1d, 0xf8, 0xfa, 0x1d, 0xf5, 0x1c, + 0xf5, 0xfe, 0x03, 0x07, 0xe4, 0x33, 0xc8, 0x0c, 0xe1, 0x13, 0xff, 0xe5, + 0x10, 0x2c, 0xd3, 0xf0, 0xed, 0x04, 0x07, 0x01, 0xf1, 0x16, 0xe0, 0x13, + 0xfa, 0x11, 0x07, 0xfa, 0x19, 0x16, 0x01, 0x00, 0x07, 0x26, 0x00, 0xec, + 0x1d, 0x23, 0x05, 0xf4, 0x07, 0x17, 0x2c, 0x1d, 0xee, 0xf0, 0x0c, 0x09, + 0xe3, 0x1a, 0x24, 0x0b, 0xf3, 0x1e, 0xce, 0xfe, 0xfe, 0x12, 0x21, 0x1a, + 0xf6, 0x23, 0xc3, 0x03, 0xf4, 0x10, 0x1a, 0x2a, 0xf4, 0x08, 0xbf, 0xff, + 0x04, 0xf4, 0x0b, 0x1d, 0x1a, 0xf8, 0xcc, 0x00, 0xf7, 0x13, 0xf4, 0xfd, + 0xf4, 0x19, 0xbd, 0xef, 0x0c, 0x0d, 0x02, 0xfc, 0x12, 0x13, 0xe9, 0xe7, + 0xf5, 0xfa, 0xfa, 0xf6, 0x1a, 0x2e, 0xce, 0xd4, 0x01, 0x12, 0xfd, 0xfc, + 0x26, 0x10, 0xcc, 0xe7, 0xee, 0x13, 0xee, 0xff, 0xef, 0xea, 0x00, 0x0e, + 0x1a, 0x17, 0x04, 0x0c, 0x04, 0x0c, 0xe6, 0xf3, 0xf6, 0xdb, 0xdd, 0x04, + 0xf4, 0x22, 0x11, 0x16, 0xf3, 0x07, 0xec, 0xf8, 0xf2, 0x07, 0x03, 0x02, + 0xf5, 0x0a, 0xf6, 0x02, 0x1d, 0x1b, 0x11, 0x06, 0xf8, 0x06, 0x02, 0xea, + 0xf3, 0x1d, 0xce, 0x00, 0xed, 0xf9, 0xef, 0xf6, 0xec, 0x22, 0xc7, 0xf0, + 0xed, 0xdb, 0xe0, 0x02, 0x11, 0x07, 0xe8, 0xf0, 0xd1, 0xed, 0xff, 0xfd, + 0x0c, 0x2e, 0xd4, 0xed, 0xec, 0x0e, 0xf1, 0x07, 0x01, 0x0e, 0x0e, 0xfe, + 0xda, 0x0b, 0x0a, 0x0a, 0x1f, 0x2e, 0x13, 0x07, 0x00, 0x07, 0x14, 0x21, + 0xe9, 0xfc, 0xf0, 0x1e, 0xd7, 0xea, 0x34, 0x07, 0xc6, 0x0c, 0xd4, 0xec, + 0xfd, 0x06, 0x24, 0x0a, 0xf3, 0x15, 0xaf, 0xff, 0xe9, 0xf1, 0x0d, 0x3e, + 0xe9, 0x18, 0xba, 0x13, 0xed, 0xd7, 0x0b, 0x31, 0x05, 0x0e, 0xaf, 0x13, + 0xd6, 0x0e, 0x10, 0x02, 0x02, 0x14, 0xcb, 0xd5, 0xf9, 0x0c, 0xf9, 0x0e, + 0x1f, 0x24, 0xd5, 0xeb, 0xff, 0xf1, 0xf5, 0x0c, 0x08, 0x07, 0xf4, 0xd7, + 0x06, 0x10, 0xe8, 0xef, 0xfc, 0x2f, 0xee, 0xf1, 0x18, 0xf8, 0xf4, 0x02, + 0x11, 0x21, 0xd3, 0x12, 0x14, 0xe4, 0xf4, 0x02, 0x05, 0x24, 0xca, 0xf2, + 0xf3, 0xeb, 0xe7, 0xf8, 0x16, 0x1a, 0xeb, 0x0d, 0x05, 0x16, 0xf1, 0xec, + 0x11, 0x1c, 0x09, 0x1e, 0xe0, 0xe6, 0xfa, 0x0e, 0x0d, 0x2a, 0xea, 0x2e, + 0xed, 0xf9, 0xf7, 0x16, 0x09, 0x05, 0xdd, 0xd6, 0x02, 0xeb, 0xf5, 0xf3, + 0xe4, 0x3b, 0xed, 0x04, 0xe0, 0x0e, 0xfd, 0x09, 0xfd, 0x35, 0xdc, 0x18, + 0xf3, 0x04, 0xfa, 0x05, 0x15, 0x34, 0xe5, 0xe1, 0xe4, 0xf4, 0xe0, 0xf9, + 0x08, 0x32, 0x04, 0x08, 0xf4, 0x0f, 0xff, 0x08, 0x09, 0x2f, 0x06, 0x02, + 0xfd, 0x05, 0x0c, 0x24, 0xe3, 0x1e, 0xf5, 0x0c, 0xdd, 0xf8, 0x18, 0x20, + 0xd8, 0x14, 0xef, 0xf4, 0x17, 0x08, 0x25, 0x14, 0x04, 0x06, 0xb0, 0xf5, + 0xf5, 0x09, 0x0f, 0x3e, 0xff, 0x28, 0xb3, 0xf5, 0x19, 0xd8, 0x14, 0x21, + 0xd9, 0xf7, 0xb7, 0xe5, 0xfe, 0xe7, 0x07, 0x1e, 0x04, 0x15, 0xc5, 0xf9, + 0x14, 0x20, 0xeb, 0x01, 0x01, 0x18, 0xce, 0x00, 0xe6, 0xe2, 0xf7, 0xfb, + 0xf3, 0x0d, 0xd3, 0xf3, 0x04, 0xf8, 0xf0, 0x03, 0xf1, 0x25, 0xb5, 0xef, + 0x05, 0xe0, 0x01, 0xf6, 0x04, 0x16, 0xd1, 0x01, 0x0a, 0x21, 0x01, 0x05, + 0x0e, 0x01, 0xf0, 0x0a, 0xf3, 0x00, 0x03, 0xf8, 0xfa, 0x03, 0x0b, 0xde, + 0xfe, 0xff, 0xfb, 0xea, 0x09, 0x02, 0xf5, 0xe8, 0xe7, 0x08, 0x00, 0xf5, + 0xf8, 0x0f, 0x13, 0xfa, 0xeb, 0xe8, 0xfb, 0x1f, 0x08, 0x16, 0xe6, 0xfa, + 0xe1, 0x00, 0x03, 0xdd, 0xf1, 0x26, 0xe5, 0x1d, 0xd9, 0xff, 0xf2, 0xf8, + 0xff, 0x33, 0xea, 0xe5, 0x03, 0x0c, 0x07, 0xf9, 0xf8, 0x0f, 0xe1, 0x1e, + 0xdd, 0x0f, 0x00, 0xf1, 0x06, 0x21, 0x09, 0x05, 0xf3, 0xec, 0xe6, 0x04, + 0x07, 0x32, 0xf1, 0xf9, 0xf2, 0x01, 0x18, 0x1f, 0xd2, 0xe2, 0x0a, 0xf4, + 0xca, 0xfc, 0x28, 0x16, 0xc2, 0x10, 0xf2, 0xfc, 0x08, 0xe9, 0x2a, 0x0f, + 0xfa, 0xf5, 0xa9, 0x07, 0xec, 0xe9, 0x19, 0x43, 0x0b, 0x1c, 0xa6, 0xe9, + 0xf4, 0x16, 0x0d, 0x2b, 0xfc, 0x11, 0x9a, 0xe1, 0xf1, 0x1c, 0xf5, 0x0f, + 0xe4, 0x18, 0xc0, 0xd9, 0x14, 0x26, 0xe6, 0xf8, 0x0a, 0x17, 0xec, 0xfb, + 0xe1, 0x22, 0xdf, 0xf2, 0xfe, 0x1e, 0xd4, 0xeb, 0xd7, 0x0e, 0x08, 0xf6, + 0xef, 0xfc, 0xe6, 0xd4, 0xf7, 0x0b, 0xfb, 0xf5, 0x01, 0x25, 0xd7, 0xfb, + 0x0d, 0xfe, 0xff, 0xf3, 0x1d, 0x32, 0xfe, 0xee, 0x12, 0xf2, 0x0c, 0xec, + 0x02, 0x10, 0xef, 0x01, 0xf2, 0x0b, 0xf3, 0xf7, 0xfa, 0x25, 0xfb, 0x0d, + 0x11, 0x15, 0x04, 0xfc, 0x0c, 0x21, 0x12, 0x29, 0x00, 0xfa, 0xf6, 0xf5, + 0x06, 0x22, 0xea, 0xe2, 0xee, 0x00, 0xfd, 0xf0, 0x0b, 0x1d, 0xd3, 0xe4, + 0xe4, 0x0a, 0xfc, 0xe8, 0xea, 0x2c, 0xed, 0xed, 0xef, 0xe8, 0xf2, 0x05, + 0xfd, 0x15, 0xd8, 0xda, 0xca, 0xee, 0xfa, 0x00, 0xfe, 0x0e, 0xf2, 0xf0, + 0x0e, 0xf5, 0x04, 0x03, 0x1d, 0x2b, 0xee, 0x05, 0x0f, 0x10, 0x13, 0x35, + 0xe2, 0x04, 0x10, 0xdf, 0xcf, 0xeb, 0x40, 0x26, 0xe4, 0x03, 0xf3, 0xf9, + 0xf5, 0x14, 0x24, 0x2a, 0xdf, 0xfe, 0xab, 0xe5, 0xfe, 0x1c, 0x27, 0x35, + 0xdb, 0xff, 0xac, 0x01, 0xf6, 0xfc, 0x19, 0x1a, 0x11, 0x1f, 0xa8, 0xf5, + 0x02, 0x0f, 0x1a, 0x1f, 0xf7, 0xf2, 0xa2, 0x00, 0x15, 0x22, 0xe4, 0x13, + 0x00, 0x09, 0xd9, 0xd5, 0x02, 0x19, 0xfd, 0xf8, 0xe7, 0xff, 0xfb, 0xe0, + 0xef, 0xf7, 0xee, 0xf3, 0xf3, 0x19, 0xb0, 0xdf, 0x00, 0x0f, 0x08, 0xf3, + 0x15, 0x17, 0xec, 0x0f, 0x11, 0x14, 0x02, 0x08, 0x10, 0x17, 0xe6, 0x08, + 0xf7, 0x00, 0xed, 0xf7, 0x29, 0x07, 0x10, 0x05, 0x05, 0xe7, 0xed, 0xf4, + 0xf9, 0x15, 0xf9, 0xf0, 0x08, 0x00, 0x03, 0x09, 0x21, 0x28, 0xf6, 0x0e, + 0xfb, 0xf3, 0x03, 0xf7, 0x0f, 0x0c, 0xf0, 0xf5, 0xe3, 0xd8, 0xf8, 0xf2, + 0x09, 0x1c, 0xe7, 0xfb, 0xe4, 0xf6, 0xfa, 0xf8, 0xf1, 0x42, 0xf6, 0xda, + 0xdd, 0xd7, 0xfa, 0xff, 0x2f, 0x2c, 0xda, 0x0a, 0xde, 0xec, 0xf1, 0x14, + 0xfb, 0x1d, 0xeb, 0xee, 0xf2, 0xeb, 0xf3, 0xed, 0x0e, 0x35, 0xf0, 0x06, + 0x19, 0x04, 0x2f, 0x23, 0xe2, 0x07, 0x13, 0x0f, 0xe9, 0xf0, 0x22, 0x2e, + 0xd9, 0x1a, 0xcb, 0xed, 0xfd, 0x04, 0x27, 0x1e, 0xf6, 0x07, 0x96, 0xd6, + 0xd8, 0x11, 0x18, 0x56, 0xd2, 0xfb, 0x92, 0xfc, 0x0b, 0x0a, 0x17, 0x2c, + 0xe5, 0x04, 0xa2, 0xf8, 0xe2, 0x04, 0x1a, 0x0d, 0xeb, 0x11, 0xa2, 0xe5, + 0xe5, 0xf8, 0x02, 0xf7, 0x17, 0x03, 0xca, 0xe9, 0x0c, 0x1f, 0xfe, 0xf5, + 0x18, 0x12, 0xdd, 0x08, 0x15, 0xff, 0xfc, 0xf6, 0xe1, 0x1d, 0xe2, 0xe1, + 0xfe, 0xfc, 0x03, 0xff, 0xf2, 0x23, 0xd2, 0x01, 0x13, 0xdd, 0xf3, 0xf4, + 0xf2, 0x07, 0xef, 0x03, 0x15, 0x21, 0xd8, 0xf8, 0x09, 0xf3, 0xe8, 0xea, + 0xe8, 0xf2, 0x08, 0xf0, 0x04, 0x1a, 0xf2, 0x19, 0xfb, 0x1b, 0x15, 0xfc, + 0x1d, 0x30, 0xe5, 0x1e, 0x09, 0xe8, 0xe9, 0x09, 0xf7, 0x2a, 0xe1, 0x0e, + 0x00, 0x21, 0xf3, 0xff, 0xfb, 0x01, 0xdf, 0xf2, 0xfe, 0xf4, 0xfc, 0xf0, + 0x0b, 0x0b, 0xdd, 0xe4, 0xd2, 0x14, 0xf7, 0xfe, 0x0b, 0x39, 0x01, 0xe6, + 0xe4, 0x27, 0xfa, 0xe4, 0x04, 0x2c, 0xe2, 0x04, 0xf5, 0x07, 0xf2, 0x03, + 0xf0, 0x10, 0xf5, 0xf6, 0xfc, 0x16, 0x22, 0x1b, 0xf8, 0x11, 0xe4, 0x09, + 0xf6, 0xf0, 0x41, 0x1e, 0xcf, 0x04, 0xea, 0xee, 0x0e, 0xf6, 0x1b, 0x2f, + 0xc7, 0xf1, 0xba, 0xef, 0x0f, 0x16, 0x1e, 0x39, 0x05, 0x1e, 0x90, 0xe6, + 0x0d, 0xfa, 0x22, 0x3f, 0xe3, 0x23, 0xa5, 0xe3, 0xe9, 0x0f, 0x05, 0x27, + 0x02, 0x11, 0x99, 0x05, 0xfa, 0x05, 0x03, 0x01, 0xff, 0x26, 0xd3, 0xf7, + 0xf7, 0xf9, 0x05, 0xf4, 0xef, 0x23, 0xd2, 0xdd, 0x05, 0x08, 0xfa, 0xff, + 0x03, 0x04, 0xbd, 0xd7, 0x14, 0x06, 0xef, 0x06, 0xe5, 0x05, 0xea, 0xea, + 0x02, 0xfd, 0x0d, 0x00, 0x08, 0xff, 0xe7, 0xfb, 0xfe, 0x13, 0xfe, 0xec, + 0xf9, 0x02, 0xf3, 0xff, 0xff, 0x08, 0x04, 0xed, 0x19, 0x1d, 0xfa, 0x0a, + 0x0d, 0xf2, 0x0f, 0xec, 0x25, 0x1c, 0xec, 0x0b, 0x01, 0xff, 0x01, 0xf6, + 0x08, 0x09, 0xe8, 0xe2, 0xec, 0x23, 0xe5, 0xe9, 0xf0, 0x2e, 0xbd, 0xe1, + 0xef, 0x14, 0xe9, 0xf6, 0xf5, 0x1d, 0xdc, 0xe3, 0xd7, 0xfc, 0xf9, 0xf2, + 0xfe, 0x24, 0xf2, 0x05, 0xd5, 0xed, 0xe9, 0xf9, 0xfa, 0x2d, 0xf0, 0xfe, + 0xee, 0xf2, 0xe8, 0xf7, 0x06, 0x14, 0x01, 0x10, 0x06, 0xf3, 0x0e, 0x0e, + 0xc2, 0x1d, 0xf2, 0x1c, 0xed, 0xe3, 0x53, 0x21, 0xb8, 0x0c, 0xde, 0x03, + 0x15, 0xeb, 0x46, 0x39, 0xdf, 0xf6, 0xa3, 0xee, 0xf6, 0xe0, 0x33, 0x50, + 0xdd, 0x27, 0x9f, 0x07, 0x13, 0xe2, 0x1f, 0x35, 0xed, 0x1f, 0xb7, 0x07, + 0x11, 0xed, 0x17, 0x28, 0xf4, 0x20, 0xc1, 0xec, 0xef, 0x16, 0x02, 0xfa, + 0xe0, 0x1b, 0xf7, 0xdb, 0xfd, 0x0a, 0xe7, 0xfb, 0xe7, 0x25, 0xe2, 0xe7, + 0xf8, 0xf0, 0xee, 0xe9, 0x02, 0x06, 0xc9, 0xe4, 0x14, 0xe3, 0xe2, 0xf7, + 0xf8, 0xfd, 0xdd, 0xe2, 0x08, 0x0a, 0xe4, 0x05, 0xf5, 0x16, 0xe7, 0x01, + 0x00, 0x1c, 0xe7, 0xf0, 0xf6, 0x19, 0xfe, 0x0c, 0xf2, 0x06, 0x03, 0xe8, + 0x0b, 0xfe, 0xe3, 0x19, 0x08, 0x1a, 0x10, 0xfd, 0x00, 0x21, 0xf0, 0xeb, + 0x18, 0x02, 0xf3, 0x04, 0xf0, 0x18, 0xdb, 0x05, 0x01, 0xde, 0xed, 0xe9, + 0x23, 0x15, 0xaf, 0xe6, 0xf1, 0x0a, 0xe6, 0xea, 0x01, 0x18, 0xd8, 0xfd, + 0xf1, 0xe6, 0xec, 0xf5, 0x0e, 0x1e, 0xcc, 0xfc, 0xe7, 0x00, 0xe9, 0x11, + 0x00, 0x30, 0xf9, 0x14, 0xf4, 0x19, 0xdd, 0xf7, 0xf7, 0x2f, 0xf4, 0xf2, + 0xff, 0x27, 0x15, 0x1c, 0xbc, 0x2f, 0xe9, 0x14, 0xf5, 0xe8, 0x44, 0x30, + 0xe8, 0x1d, 0xe4, 0x18, 0x11, 0x00, 0x0c, 0x2b, 0xf3, 0x29, 0x96, 0xe0, + 0x06, 0xee, 0x3e, 0x55, 0xdc, 0x13, 0x98, 0xdf, 0xf0, 0xfe, 0x17, 0x33, + 0xe8, 0x09, 0xa3, 0x07, 0xef, 0x0e, 0x1d, 0x37, 0xdd, 0xfe, 0xb5, 0x00, + 0xf7, 0xe0, 0xea, 0xfd, 0xfd, 0x19, 0xbc, 0xfd, 0x15, 0xfe, 0x01, 0xf3, + 0xd5, 0x20, 0xbf, 0xe3, 0x15, 0x0e, 0xf0, 0xf6, 0xf2, 0x14, 0xcc, 0xf0, + 0xf7, 0x04, 0xf2, 0xff, 0x0b, 0x02, 0xd2, 0xd8, 0xfa, 0xfc, 0xe5, 0x02, + 0x00, 0xfb, 0xf0, 0xdc, 0x1e, 0x10, 0x02, 0x01, 0x00, 0x18, 0xe9, 0xdb, + 0x1e, 0xf6, 0xfc, 0x03, 0xef, 0x0a, 0x00, 0x16, 0x00, 0x0f, 0xf4, 0x16, + 0xfa, 0x0b, 0xe2, 0xfa, 0xe0, 0x07, 0xfb, 0x02, 0x21, 0x0e, 0xdd, 0x0b, + 0xea, 0xf0, 0xeb, 0xfb, 0x19, 0x09, 0xd4, 0xf2, 0xef, 0x0b, 0x00, 0xeb, + 0x1a, 0x2f, 0xea, 0x06, 0x03, 0xf6, 0xf8, 0xfb, 0xfe, 0x1d, 0xea, 0xdd, + 0xed, 0xfd, 0xfb, 0xe7, 0xfe, 0x18, 0xf4, 0xfc, 0x0b, 0xf6, 0xfc, 0x0b, + 0xfb, 0x28, 0x07, 0xff, 0x07, 0x1e, 0x03, 0x21, 0xcf, 0x22, 0x05, 0xe6, + 0xea, 0xe7, 0x43, 0x2e, 0xe7, 0x14, 0xfb, 0x0a, 0x1e, 0xfe, 0x2c, 0x24, + 0xd5, 0xfd, 0x9e, 0xd1, 0xf2, 0x1c, 0x32, 0x51, 0x01, 0xf3, 0xac, 0xe1, + 0xf4, 0xe5, 0x1c, 0x37, 0xf1, 0x0f, 0xa7, 0xdb, 0x00, 0xf6, 0x0f, 0x18, + 0xe1, 0x10, 0xc9, 0xc5, 0xe8, 0xeb, 0xf2, 0xfd, 0xf6, 0x02, 0xc2, 0xff, + 0x00, 0x19, 0x03, 0x0f, 0x02, 0x22, 0xd4, 0xe7, 0x07, 0x0f, 0xe5, 0x1a, + 0x09, 0x0b, 0xdc, 0xd2, 0x00, 0x05, 0xee, 0xf8, 0xdc, 0x14, 0xd0, 0x0a, + 0x0a, 0xfa, 0xeb, 0x04, 0xf3, 0x06, 0xde, 0x05, 0xfb, 0xfd, 0xe3, 0xec, + 0xfd, 0x14, 0xd7, 0x11, 0x0e, 0xe6, 0x06, 0xec, 0xde, 0x22, 0xd7, 0x00, + 0x03, 0xf5, 0xf5, 0x0d, 0x01, 0x05, 0xea, 0x0b, 0x16, 0x04, 0xff, 0x13, + 0xf3, 0x12, 0xd2, 0xdf, 0x0b, 0xe4, 0x06, 0xf6, 0x08, 0x2d, 0xd3, 0xd6, + 0xe7, 0x0a, 0xec, 0xff, 0xfe, 0x01, 0xdf, 0xf4, 0xdf, 0x1c, 0xfe, 0xf9, + 0xf7, 0x13, 0xca, 0xff, 0x03, 0x06, 0xe9, 0xf7, 0x06, 0x08, 0xd7, 0xf3, + 0xed, 0x08, 0xe3, 0xfd, 0x0c, 0x11, 0x15, 0xfb, 0x15, 0x08, 0x28, 0x40, + 0xe7, 0x0d, 0x08, 0xec, 0xe8, 0x16, 0x67, 0x46, 0xc8, 0x16, 0xf1, 0x02, + 0x24, 0x00, 0x3a, 0x43, 0xd6, 0x12, 0xae, 0xe7, 0xf4, 0xf8, 0x3a, 0x65, + 0xe4, 0x0c, 0xb2, 0xef, 0x1f, 0xe8, 0x29, 0x59, 0xf8, 0x11, 0xc4, 0xe1, + 0xfe, 0xfa, 0x27, 0x43, 0xc9, 0x1e, 0xbb, 0xfb, 0xf3, 0x13, 0x15, 0x0d, + 0xf1, 0x13, 0xcd, 0xf0, 0x07, 0x19, 0x07, 0x00, 0xd8, 0xeb, 0xbf, 0xf0, + 0xfc, 0xf6, 0xef, 0x16, 0x01, 0x02, 0xc1, 0xdf, 0xfd, 0xe9, 0x06, 0x06, + 0xf1, 0x08, 0xd7, 0xcc, 0xfb, 0x0e, 0xfc, 0x14, 0xf2, 0x1a, 0xe2, 0x0d, + 0xeb, 0x09, 0x07, 0x10, 0xe6, 0x13, 0xeb, 0xf5, 0x15, 0x14, 0xeb, 0xfe, + 0xf9, 0x17, 0xd2, 0xe3, 0x1e, 0xf5, 0x04, 0x0a, 0xf1, 0x0e, 0xde, 0xe7, + 0x01, 0x20, 0x0c, 0xfc, 0xdc, 0xf9, 0xe5, 0xe9, 0xff, 0x1d, 0x0a, 0xfe, + 0xec, 0x25, 0xaf, 0xd2, 0x01, 0x16, 0xfc, 0x17, 0xe8, 0x1e, 0xcd, 0xd9, + 0xe2, 0xf1, 0xeb, 0x08, 0xff, 0x33, 0xe5, 0xfb, 0xeb, 0x04, 0xfe, 0xf7, + 0xfd, 0x1f, 0xee, 0xff, 0xed, 0xf8, 0xe0, 0xff, 0xfd, 0x2b, 0x0a, 0xf5, + 0x15, 0x1d, 0xf3, 0x3f, 0x16, 0xf6, 0xf2, 0xee, 0xf4, 0xef, 0xf0, 0x56, + 0x0a, 0x1a, 0xbc, 0xfc, 0x2f, 0xfb, 0xf0, 0x56, 0x1e, 0x0e, 0xc6, 0xe8, + 0x06, 0x0b, 0x11, 0x62, 0x3e, 0xf9, 0xb8, 0xc9, 0xed, 0xeb, 0x02, 0x63, + 0x2c, 0xfd, 0xc5, 0xe9, 0x00, 0x17, 0x0f, 0x37, 0xfe, 0x20, 0xcc, 0xe0, + 0xe0, 0x0e, 0xe6, 0x20, 0x0a, 0xfd, 0xdf, 0xee, 0x0b, 0x02, 0xee, 0x1f, + 0xfb, 0x06, 0xd2, 0xed, 0xfe, 0xeb, 0xfc, 0x12, 0xfd, 0x14, 0x00, 0xd8, + 0x08, 0xf6, 0xec, 0x17, 0xf9, 0x10, 0x00, 0xd9, 0x18, 0xf1, 0xee, 0x0f, + 0xf4, 0x03, 0xee, 0xeb, 0xf0, 0xef, 0xf2, 0x06, 0x04, 0x00, 0xf4, 0x0f, + 0x09, 0x06, 0xf7, 0x0b, 0xfd, 0x01, 0x03, 0x03, 0xf4, 0xf6, 0xdd, 0x14, + 0x1c, 0xef, 0xf1, 0xdd, 0xf7, 0x13, 0xd9, 0x15, 0xef, 0x02, 0xd2, 0xe7, + 0x05, 0x05, 0xe2, 0x09, 0xf2, 0x11, 0xf5, 0xba, 0xf0, 0x04, 0xe0, 0x01, + 0x06, 0x10, 0xe6, 0xef, 0xfc, 0x12, 0xf9, 0xf4, 0x1b, 0x2f, 0xe3, 0x0f, + 0xd7, 0xf6, 0x0b, 0x11, 0xf7, 0x0c, 0x00, 0x06, 0x18, 0xef, 0x06, 0x03, + 0x0a, 0x09, 0xf6, 0x1a, 0x0d, 0xed, 0xfe, 0x2c, 0x43, 0xf4, 0xe5, 0xde, + 0xf5, 0x02, 0x25, 0x5a, 0x49, 0xd4, 0xe6, 0x24, 0x1e, 0xf7, 0x0e, 0x5c, + 0x5d, 0xf0, 0xf9, 0xe4, 0x1c, 0xeb, 0x28, 0x7f, 0x5b, 0xec, 0xfa, 0xdb, + 0x0c, 0xf5, 0x20, 0x49, 0x51, 0xe1, 0xed, 0xe6, 0x0e, 0x26, 0x28, 0x33, + 0x35, 0x05, 0xe1, 0xe4, 0x1f, 0xfc, 0xf9, 0x39, 0x18, 0x04, 0xed, 0xed, + 0x01, 0xe7, 0xe6, 0x08, 0x09, 0x03, 0xe7, 0xf9, 0x0e, 0x06, 0xec, 0x08, + 0x12, 0x1a, 0xda, 0xef, 0xdf, 0xf9, 0xe2, 0x1e, 0x1c, 0x00, 0x12, 0xd7, + 0x01, 0xf7, 0x21, 0x17, 0x13, 0x19, 0xde, 0xe0, 0xec, 0x16, 0x01, 0x1b, + 0x06, 0x0c, 0xf0, 0xe8, 0x18, 0x03, 0x06, 0x0e, 0x09, 0xfa, 0x03, 0xf3, + 0xdd, 0x01, 0xfb, 0x0a, 0x2a, 0xf4, 0xf6, 0xda, 0xe9, 0xfe, 0xe9, 0x12, + 0x19, 0xe9, 0x05, 0xdf, 0x00, 0xeb, 0xf2, 0x10, 0x0c, 0xe1, 0xcd, 0xcb, + 0xf2, 0x1f, 0xd9, 0x0c, 0xfa, 0xfb, 0xe8, 0xde, 0x00, 0xfc, 0xe5, 0x00, + 0x11, 0x02, 0xe6, 0x17, 0x14, 0x00, 0xf2, 0xfd, 0x00, 0xe1, 0x10, 0x24, + 0x12, 0xec, 0xed, 0x1e, 0x09, 0x18, 0x03, 0x0c, 0x04, 0xf4, 0x15, 0x0f, + 0x10, 0x18, 0xd6, 0x29, 0x10, 0x04, 0x1c, 0xef, 0x0f, 0x0c, 0xc7, 0x04, + 0xfe, 0xeb, 0xff, 0xf5, 0xe3, 0x15, 0xfe, 0xcb, 0x10, 0xff, 0x12, 0xfb, + 0xe4, 0xeb, 0xf9, 0x00, 0x02, 0xf1, 0x14, 0x13, 0x01, 0x02, 0xf9, 0x01, + 0x06, 0x0c, 0xf5, 0x0a, 0x1e, 0x01, 0x19, 0x0e, 0x05, 0xf5, 0x0a, 0xff, + 0xff, 0xf2, 0xfb, 0xdb, 0xf8, 0x06, 0x17, 0xf2, 0xf7, 0x0d, 0x0e, 0xf4, + 0xfa, 0xf7, 0x14, 0xdb, 0xe0, 0xfd, 0x08, 0x16, 0xf7, 0x16, 0xfc, 0x09, + 0x27, 0x07, 0x09, 0xfb, 0x0a, 0xfc, 0x0c, 0xe4, 0xdb, 0xee, 0xff, 0x10, + 0xf3, 0x09, 0xfa, 0xf4, 0x23, 0xf3, 0xf4, 0x19, 0xff, 0xfa, 0xff, 0x19, + 0x0f, 0x11, 0xed, 0xec, 0xf8, 0x0f, 0x10, 0xf3, 0xff, 0x0b, 0xf7, 0x06, + 0x0b, 0x0e, 0x07, 0xe4, 0x18, 0x0a, 0x08, 0x0e, 0x02, 0x0a, 0x05, 0x19, + 0x02, 0xf3, 0xfe, 0xfe, 0x0b, 0x0f, 0xfc, 0xfa, 0x05, 0xf9, 0xe2, 0xf9, + 0x1b, 0xf7, 0x0f, 0x07, 0xfc, 0x12, 0xfe, 0x01, 0xfd, 0xf0, 0x04, 0xf4, + 0xfd, 0x07, 0xf2, 0x04, 0x04, 0x07, 0xef, 0x0c, 0xed, 0x0e, 0xf6, 0xef, + 0x08, 0x07, 0x04, 0xe9, 0xf3, 0x20, 0xda, 0x15, 0xf8, 0xff, 0xec, 0xe0, + 0xf6, 0xff, 0xe9, 0x08, 0x01, 0x10, 0xf0, 0xfc, 0xe9, 0x08, 0xe8, 0xf5, + 0xf8, 0xe5, 0x17, 0xe6, 0x03, 0xfc, 0x09, 0xf5, 0xdd, 0xf2, 0xff, 0x05, + 0xf6, 0xf8, 0xf5, 0x07, 0xfc, 0xf1, 0x04, 0xf3, 0x13, 0xe1, 0x0f, 0xf2, + 0x0a, 0xf9, 0xfd, 0x1c, 0xe0, 0x11, 0x1b, 0xe6, 0xef, 0x05, 0x05, 0x0c, + 0x23, 0x10, 0x09, 0xfe, 0xf7, 0x1a, 0xf1, 0xfc, 0x11, 0x1d, 0xff, 0x03, + 0x03, 0xe6, 0x07, 0x11, 0x0c, 0x0d, 0x16, 0x05, 0x05, 0x25, 0xf3, 0x10, + 0x10, 0x06, 0x09, 0xe8, 0x1a, 0xf0, 0xee, 0x09, 0xff, 0x24, 0xf7, 0xfb, + 0xe6, 0x06, 0xfa, 0x08, 0x03, 0x00, 0xf2, 0x04, 0xf0, 0xeb, 0x14, 0x1c, + 0x03, 0x21, 0x14, 0x1d, 0xfe, 0x03, 0xf6, 0x02, 0x09, 0xff, 0x00, 0x13, + 0xef, 0x10, 0x1e, 0x0b, 0x1d, 0x1c, 0xf1, 0xf6, 0xe7, 0xfd, 0x14, 0x01, + 0xff, 0x13, 0xf7, 0xfc, 0x00, 0x21, 0xe3, 0xeb, 0x07, 0x0e, 0x09, 0xf1, + 0xf8, 0xfd, 0x03, 0xee, 0x19, 0xfd, 0xff, 0xfb, 0xff, 0xea, 0xfb, 0x07, + 0xf0, 0x0a, 0x04, 0x04, 0x0b, 0x12, 0xfe, 0x0b, 0xe0, 0xff, 0xf6, 0xe5, + 0xfc, 0x11, 0xed, 0xfd, 0x15, 0x03, 0xdd, 0xdb, 0x04, 0xfe, 0xff, 0x0e, + 0xff, 0xfa, 0xfb, 0xe5, 0xef, 0xf6, 0xfe, 0x22, 0x0f, 0xe8, 0xfe, 0xf4, + 0xfd, 0xd9, 0x03, 0x0a, 0xdf, 0xcf, 0xf1, 0x14, 0x05, 0xfd, 0xfb, 0xf3, + 0xfb, 0xfb, 0x0f, 0xf8, 0x05, 0x09, 0x03, 0xf7, 0x05, 0x05, 0x13, 0xfb, + 0xeb, 0x23, 0xe7, 0x18, 0xfb, 0x00, 0xfe, 0xdd, 0xe9, 0xea, 0xd3, 0xe8, + 0x1a, 0xef, 0x01, 0xf1, 0x09, 0x1d, 0xd8, 0xfc, 0xda, 0x19, 0x03, 0xec, + 0xe5, 0xf3, 0xed, 0x0a, 0xf4, 0x13, 0x0b, 0xf7, 0x0c, 0x00, 0xf9, 0xea, + 0xe3, 0xfe, 0xff, 0x0d, 0x0a, 0x1b, 0xd7, 0x17, 0xeb, 0xe9, 0x00, 0x0e, + 0xee, 0x24, 0xef, 0x09, 0x07, 0xf0, 0xf5, 0x07, 0xf5, 0xf5, 0x10, 0x17, + 0x06, 0xf7, 0xfc, 0x02, 0xfb, 0xf9, 0xe7, 0x0a, 0x26, 0xf3, 0x01, 0x01, + 0x09, 0x0b, 0x02, 0x27, 0xf8, 0xee, 0xfd, 0x1c, 0xf8, 0xf2, 0x0f, 0xfc, + 0x0d, 0xe0, 0xea, 0x02, 0x0b, 0x00, 0xe0, 0x08, 0xfe, 0x10, 0x04, 0xfe, + 0xeb, 0x13, 0x01, 0x0c, 0x0e, 0xed, 0x09, 0x01, 0x0c, 0xe3, 0x10, 0xdf, + 0xd1, 0x14, 0xf3, 0xef, 0x09, 0xf0, 0xee, 0xe5, 0x11, 0xf4, 0xf6, 0x00, + 0xe8, 0x20, 0x0a, 0xfc, 0xea, 0xf7, 0x02, 0x16, 0xe7, 0xf3, 0x0d, 0xe4, + 0x04, 0xe6, 0xef, 0xf8, 0x0f, 0x23, 0x02, 0xe0, 0x01, 0x01, 0x01, 0x05, + 0xf5, 0x0d, 0xf5, 0xf5, 0xe1, 0xff, 0x04, 0x00, 0xf4, 0x0d, 0xee, 0xf1, + 0xef, 0xf7, 0x0b, 0xff, 0x1b, 0xec, 0x05, 0xe7, 0xf3, 0x13, 0x12, 0xf2, + 0xf3, 0xfc, 0xea, 0x06, 0xfe, 0x13, 0x12, 0xdb, 0x11, 0xe2, 0xfc, 0x0d, + 0x1c, 0xe8, 0x1d, 0xfc, 0xf2, 0xe2, 0x13, 0x1d, 0xda, 0xf6, 0x1c, 0x18, + 0x1e, 0xf4, 0xfa, 0x03, 0xdc, 0x0f, 0xff, 0xff, 0x18, 0x0b, 0xed, 0xf1, + 0xf8, 0x02, 0xf4, 0x10, 0xf9, 0xeb, 0x0b, 0x0e, 0x0f, 0x01, 0x02, 0x1b, + 0x06, 0x10, 0x00, 0xe7, 0x23, 0x0d, 0xf6, 0x11, 0x08, 0xf5, 0x0f, 0x05, + 0x13, 0xf7, 0x01, 0x01, 0x0c, 0xf6, 0xf9, 0xf0, 0x29, 0x01, 0xe9, 0x11, + 0x02, 0xfa, 0xeb, 0x16, 0x0e, 0x10, 0x09, 0x0e, 0x1c, 0x0a, 0xe3, 0xd3, + 0x01, 0xe3, 0x00, 0x06, 0xe2, 0xe9, 0x19, 0xef, 0x12, 0xf3, 0xfc, 0x02, + 0x0b, 0x0c, 0x0d, 0xed, 0xfd, 0xf6, 0xf9, 0xe9, 0xf2, 0x28, 0xfe, 0x03, + 0xec, 0x03, 0x00, 0xf8, 0xde, 0x0d, 0x25, 0x07, 0x1a, 0xe7, 0xfd, 0x29, + 0xd8, 0xf7, 0xfb, 0xde, 0x0c, 0x08, 0x06, 0x22, 0xee, 0x1d, 0x05, 0x07, + 0xf0, 0xfb, 0xfe, 0x07, 0xf1, 0x04, 0xe9, 0x01, 0xfc, 0xf1, 0x00, 0xeb, + 0xe3, 0x08, 0xec, 0xfe, 0x04, 0xeb, 0xfc, 0x01, 0xf6, 0x0e, 0xdf, 0xf8, + 0x12, 0xe3, 0x16, 0xdc, 0x21, 0x0a, 0xe6, 0x06, 0xe5, 0x10, 0x07, 0xf7, + 0x1e, 0xde, 0xe3, 0x07, 0x16, 0xed, 0x23, 0xf2, 0x12, 0x0d, 0xe9, 0xf9, + 0xe8, 0xfe, 0x0e, 0x02, 0x18, 0x0a, 0xea, 0xec, 0xfb, 0xfe, 0x0c, 0x1b, + 0x19, 0x20, 0xfa, 0x07, 0xe5, 0x0c, 0x04, 0x27, 0xdb, 0xe6, 0xfe, 0x0d, + 0x0a, 0x0a, 0xfe, 0x39, 0xdd, 0xde, 0x05, 0xec, 0x09, 0x05, 0x0a, 0x2c, + 0xf4, 0x02, 0x1f, 0xd3, 0x24, 0xee, 0x0f, 0x3c, 0xf5, 0xfd, 0xf8, 0xf8, + 0x12, 0xf5, 0xf3, 0x19, 0xf9, 0xda, 0xf6, 0x0a, 0x0a, 0xf4, 0x09, 0x0f, + 0xfc, 0x00, 0x01, 0x01, 0xf3, 0xf8, 0x05, 0xf3, 0x0c, 0x19, 0x0e, 0xfd, + 0xfa, 0xe1, 0xfc, 0x0c, 0x03, 0xfb, 0x1b, 0x06, 0xcc, 0xe4, 0x08, 0xf9, + 0x10, 0xe9, 0x06, 0x00, 0x17, 0xe8, 0x0d, 0x12, 0xca, 0xf5, 0x23, 0xe4, + 0x21, 0xf6, 0x19, 0x33, 0xdd, 0xfa, 0x0c, 0x01, 0x14, 0x07, 0x00, 0x34, + 0xda, 0x05, 0x07, 0x01, 0x07, 0xe4, 0x06, 0x24, 0x02, 0xff, 0xf0, 0x09, + 0xfc, 0xf4, 0x03, 0x06, 0xee, 0x08, 0xe2, 0x1d, 0xfa, 0x0c, 0xfc, 0x02, + 0x03, 0xe5, 0xf0, 0xe2, 0x0a, 0x18, 0x12, 0x0c, 0x1e, 0x20, 0xed, 0x20, + 0xe4, 0x01, 0x2a, 0x09, 0x0d, 0x0e, 0xd0, 0xf4, 0xdd, 0xfd, 0x2b, 0xf2, + 0x08, 0x0c, 0xf8, 0xf7, 0xfc, 0xf9, 0x15, 0xef, 0x19, 0x1c, 0x01, 0xff, + 0xe2, 0x01, 0xf3, 0x30, 0x0e, 0xfb, 0x15, 0xe8, 0x1c, 0x00, 0xfa, 0x16, + 0xef, 0xea, 0xfb, 0x05, 0xf0, 0x0e, 0x02, 0x13, 0xf4, 0x01, 0x03, 0xe5, + 0x29, 0x07, 0x09, 0x24, 0xf9, 0xe3, 0xf8, 0xde, 0x2d, 0xf4, 0xf5, 0x40, + 0xed, 0xdf, 0x07, 0xef, 0x0f, 0x0a, 0x0b, 0x32, 0x0d, 0xe8, 0x00, 0xe6, + 0xf6, 0xfc, 0xfd, 0x19, 0x11, 0x09, 0xf3, 0x03, 0xea, 0xf1, 0xfb, 0x02, + 0xfd, 0x06, 0xff, 0xfe, 0x09, 0xec, 0x06, 0x0c, 0x15, 0xf9, 0x06, 0xd7, + 0xe3, 0xf7, 0xed, 0x01, 0x03, 0xfd, 0x14, 0x01, 0x0e, 0xe0, 0x37, 0x0d, + 0xd2, 0x18, 0x2f, 0xea, 0x12, 0x0d, 0x05, 0x3a, 0xd5, 0x07, 0x1e, 0xf2, + 0x21, 0x11, 0xf9, 0x36, 0xd3, 0xf5, 0x12, 0xf6, 0xfb, 0xf6, 0x06, 0x0f, + 0xde, 0xf9, 0x06, 0x09, 0xdf, 0xff, 0x0b, 0xf3, 0xf5, 0x01, 0xf1, 0xea, + 0xf2, 0x02, 0x12, 0xfc, 0x0e, 0xee, 0xf8, 0xeb, 0x00, 0xef, 0x21, 0x0f, + 0x09, 0xef, 0xeb, 0x1e, 0xef, 0xf2, 0x26, 0xf9, 0x17, 0xf1, 0xf1, 0xf0, + 0x0c, 0x10, 0x1d, 0xff, 0x1d, 0x06, 0x03, 0xf6, 0xfb, 0x14, 0x1b, 0x03, + 0x22, 0xfd, 0xec, 0x03, 0xfa, 0xf8, 0x01, 0x2b, 0x1e, 0x1b, 0x09, 0x09, + 0x07, 0xff, 0xf0, 0x20, 0xee, 0x14, 0xfb, 0xf6, 0xf8, 0x11, 0xd9, 0x29, + 0xf4, 0xfa, 0x07, 0xef, 0x20, 0xf9, 0xf2, 0x30, 0xee, 0xf0, 0xf3, 0xd6, + 0x0d, 0xfe, 0x03, 0x36, 0xf5, 0xd7, 0x01, 0xe6, 0x04, 0xf0, 0x05, 0x1f, + 0x0f, 0xdd, 0xff, 0xf8, 0x1f, 0xf2, 0x04, 0x37, 0xfa, 0x00, 0xfd, 0xf8, + 0x10, 0xe1, 0xfb, 0x0d, 0xed, 0xf6, 0xe2, 0xfe, 0x08, 0xfe, 0x07, 0x08, + 0x08, 0x11, 0x0a, 0xf0, 0xf8, 0xf5, 0x04, 0xea, 0x08, 0x12, 0x06, 0x0d, + 0x0f, 0x10, 0x40, 0x28, 0xc0, 0xfb, 0x3f, 0x08, 0x1d, 0x09, 0x1b, 0x3d, + 0xee, 0xf4, 0x29, 0x13, 0x20, 0xfc, 0x11, 0x4c, 0xdb, 0x02, 0x15, 0x05, + 0xec, 0xeb, 0x0a, 0x22, 0xe7, 0x00, 0x02, 0x01, 0xd4, 0xea, 0x0a, 0xf3, + 0xe3, 0xf8, 0xf5, 0xfa, 0x01, 0x0d, 0x19, 0x06, 0x24, 0x13, 0x02, 0xf5, + 0xf1, 0xf1, 0x1b, 0x0f, 0x19, 0x04, 0xe3, 0xf9, 0xe7, 0x02, 0x29, 0xfc, + 0x29, 0xec, 0xe9, 0x04, 0xdc, 0x22, 0x1d, 0xfd, 0x1f, 0x01, 0xec, 0xe8, + 0xf5, 0x14, 0x1b, 0x19, 0x06, 0x0e, 0x02, 0x0d, 0xf9, 0x06, 0xfc, 0x15, + 0x07, 0xfa, 0x0c, 0xe1, 0x18, 0x1a, 0xe8, 0x1b, 0xe9, 0xef, 0x0a, 0x18, + 0xfc, 0x05, 0xf9, 0x14, 0xdc, 0x04, 0x01, 0xff, 0x07, 0xfd, 0xf0, 0x2c, + 0xf2, 0xec, 0x0e, 0xe7, 0x1a, 0x05, 0xe8, 0x35, 0x13, 0x09, 0xf9, 0x07, + 0xfe, 0xfa, 0x0d, 0x40, 0x0c, 0xea, 0xf4, 0x04, 0x01, 0x11, 0xfc, 0x23, + 0xeb, 0xf4, 0xe9, 0x04, 0xeb, 0xe7, 0x07, 0x09, 0xfb, 0xf1, 0xf6, 0xfd, + 0x02, 0xfa, 0x02, 0xff, 0x00, 0xff, 0xf1, 0xf1, 0x1a, 0xe9, 0x10, 0xe3, + 0x0b, 0x0c, 0x08, 0x04, 0x1b, 0x0a, 0x2b, 0x10, 0xe1, 0x01, 0x1f, 0x06, + 0x04, 0xec, 0x19, 0x49, 0xee, 0xf8, 0x22, 0x0c, 0x20, 0x02, 0x07, 0x31, + 0xe7, 0xff, 0x0f, 0xf0, 0xfd, 0xea, 0x13, 0x26, 0xce, 0xfa, 0xff, 0xee, + 0xe9, 0xfe, 0x15, 0x08, 0x04, 0x05, 0x0d, 0xfa, 0xdd, 0xf8, 0x07, 0x0b, + 0x33, 0xef, 0xec, 0xf9, 0xd9, 0xe6, 0x1d, 0x10, 0x41, 0xf6, 0xdf, 0x11, + 0xe3, 0x14, 0x1d, 0xfb, 0x2b, 0x15, 0xdc, 0x09, 0xf6, 0x05, 0x16, 0x00, + 0x1c, 0x27, 0xe4, 0xfc, 0xf7, 0x16, 0x08, 0x08, 0x2f, 0xdd, 0xf8, 0xfa, + 0xe9, 0x0e, 0x0b, 0x0b, 0x02, 0x12, 0x02, 0xfd, 0x19, 0x03, 0xeb, 0x11, + 0xf4, 0x09, 0x09, 0x15, 0x12, 0x0d, 0xef, 0x1c, 0xe4, 0xfe, 0x17, 0x0c, + 0x09, 0x04, 0xea, 0x2f, 0xf2, 0x1e, 0x02, 0xfb, 0xfe, 0xe3, 0x00, 0x2e, + 0x04, 0xf9, 0x0c, 0x05, 0x27, 0x0c, 0x07, 0x2d, 0xf7, 0x0b, 0xfb, 0xf9, + 0x1c, 0xdf, 0x11, 0x36, 0x05, 0xf2, 0x02, 0xf8, 0x0b, 0x07, 0x05, 0xfb, + 0xfc, 0x0e, 0x13, 0xfa, 0xfb, 0x09, 0xf5, 0xfd, 0x06, 0x15, 0xf9, 0x03, + 0x18, 0xfd, 0x1a, 0x0a, 0x03, 0xe2, 0xfb, 0x00, 0x1e, 0xfe, 0x4f, 0x27, + 0xe1, 0xf7, 0x31, 0xf0, 0x1b, 0xec, 0x07, 0x5f, 0xe2, 0xf8, 0x40, 0x05, + 0x17, 0x24, 0x0c, 0x3c, 0xf3, 0x10, 0x13, 0xf8, 0x0b, 0xf3, 0xf9, 0x36, + 0xe1, 0xf3, 0xf4, 0xe8, 0xef, 0xf8, 0xfc, 0xeb, 0xe3, 0xfb, 0xf0, 0xee, + 0xdb, 0x06, 0x0c, 0x11, 0x1e, 0x10, 0xe2, 0xe9, 0xeb, 0x0d, 0x34, 0x0f, + 0x43, 0xd9, 0xef, 0x08, 0xec, 0x05, 0x1d, 0x02, 0x33, 0xef, 0xf4, 0xf7, + 0xe6, 0xf9, 0x22, 0x07, 0x04, 0x06, 0xe9, 0x02, 0xf0, 0xfc, 0x24, 0x20, + 0x24, 0x17, 0xe6, 0x0f, 0x05, 0xf6, 0xfc, 0x1f, 0xf2, 0x01, 0x0d, 0xe7, + 0xff, 0x1d, 0xf0, 0xfa, 0xd0, 0x00, 0xff, 0x0e, 0x23, 0xf9, 0xf3, 0x11, + 0xde, 0x0d, 0x05, 0x04, 0x0b, 0x0b, 0xfb, 0x26, 0x0d, 0x0d, 0xff, 0xe8, + 0x16, 0xe8, 0x0b, 0x3c, 0x18, 0xe4, 0x04, 0xff, 0xfa, 0xf3, 0xff, 0x40, + 0xee, 0x06, 0xfc, 0x0d, 0x00, 0xf7, 0x13, 0x3f, 0xf7, 0x13, 0x06, 0x08, + 0xf9, 0x13, 0xf2, 0x19, 0xfd, 0xf9, 0xf3, 0xe6, 0xfc, 0x07, 0xf6, 0xfd, + 0x0a, 0x22, 0x00, 0x01, 0x19, 0xff, 0xe7, 0xff, 0x08, 0xfd, 0x03, 0xfd, + 0x1f, 0xe7, 0x28, 0x08, 0xde, 0xf3, 0x43, 0xf6, 0x0c, 0xfe, 0x1e, 0x52, + 0xf2, 0x04, 0x17, 0xf2, 0x08, 0x0d, 0x04, 0x38, 0xde, 0x0c, 0x10, 0xef, + 0xdf, 0x0f, 0x01, 0x24, 0xde, 0xe1, 0x0d, 0xfd, 0xd4, 0xf6, 0x12, 0x0e, + 0xed, 0x01, 0xf0, 0xf3, 0xfd, 0xff, 0x18, 0xf3, 0x36, 0xda, 0xf6, 0xef, + 0xe8, 0xef, 0x37, 0x27, 0x4e, 0xf8, 0xf4, 0xff, 0xe5, 0xf3, 0x32, 0x0b, + 0x36, 0x08, 0xe9, 0xf6, 0xe2, 0x13, 0x21, 0xfe, 0x12, 0xed, 0xdd, 0xfb, + 0xf8, 0x05, 0x0f, 0x03, 0x1c, 0x04, 0xfc, 0xf2, 0x23, 0x0e, 0x03, 0xfc, + 0xf9, 0x18, 0xf7, 0x01, 0x1b, 0x03, 0xf5, 0xfd, 0xde, 0xf3, 0x19, 0xfc, + 0x11, 0x02, 0xe7, 0x13, 0xde, 0xd8, 0xf2, 0x05, 0x28, 0x02, 0x02, 0x27, + 0x07, 0x08, 0xff, 0x07, 0x27, 0x0e, 0x19, 0x40, 0xfb, 0x02, 0x0c, 0xf6, + 0x0d, 0x07, 0x0f, 0x47, 0xf8, 0x05, 0x0e, 0xfd, 0x03, 0x1e, 0x07, 0x32, + 0xe7, 0xf6, 0x24, 0x01, 0x01, 0x02, 0x0a, 0xff, 0xf6, 0x26, 0x15, 0xf0, + 0x04, 0x13, 0x03, 0xfa, 0xfe, 0xf6, 0xf1, 0x09, 0x2a, 0xe6, 0xea, 0xf6, + 0x17, 0x13, 0xeb, 0xff, 0x15, 0xeb, 0x23, 0x06, 0xc8, 0xf6, 0x33, 0xeb, + 0xf4, 0xe7, 0x12, 0x2a, 0xe3, 0xe6, 0x32, 0xfa, 0x16, 0x15, 0x17, 0x40, + 0xf1, 0x08, 0x1a, 0xf3, 0xf6, 0x0c, 0x0c, 0x11, 0xd0, 0x22, 0x02, 0xee, + 0xea, 0xf4, 0xf8, 0xf9, 0x13, 0x10, 0x17, 0xf5, 0xf1, 0x0a, 0x0e, 0xfd, + 0x32, 0xda, 0xf1, 0xe2, 0xdb, 0xf2, 0x34, 0x1f, 0x53, 0xfc, 0xe4, 0xf2, + 0xf6, 0xf2, 0x1d, 0x04, 0x4a, 0xec, 0xee, 0x06, 0xdf, 0x01, 0x1a, 0x04, + 0x27, 0xfc, 0xe6, 0xfd, 0xd9, 0xfd, 0x0e, 0x00, 0x0c, 0x16, 0xf3, 0x03, + 0xf7, 0xfc, 0x0e, 0x0f, 0x09, 0x06, 0x06, 0x04, 0x08, 0x02, 0xed, 0xf5, + 0xe4, 0xe6, 0x07, 0x06, 0x03, 0x18, 0xea, 0x13, 0xe2, 0xfa, 0x10, 0xf2, + 0x02, 0xec, 0x03, 0x3c, 0xf6, 0xf6, 0x0a, 0x10, 0x09, 0xf8, 0x15, 0x24, + 0xfd, 0x0d, 0x09, 0x01, 0x00, 0xff, 0x00, 0x1a, 0xf0, 0xee, 0x08, 0x03, + 0x1d, 0x05, 0x16, 0x46, 0xe6, 0xf8, 0x08, 0x00, 0x09, 0x09, 0xff, 0x01, + 0xfc, 0x20, 0xfc, 0xec, 0x05, 0x1b, 0x03, 0xf1, 0x12, 0xe4, 0xfa, 0x24, + 0x1c, 0xf5, 0xf2, 0x05, 0x11, 0xe7, 0xfa, 0x02, 0x20, 0xea, 0x31, 0x10, + 0xcf, 0xd8, 0x33, 0xee, 0xff, 0x09, 0x20, 0x3f, 0xe2, 0x0a, 0x29, 0xee, + 0x3a, 0xf2, 0x1e, 0x39, 0x02, 0x1e, 0xfe, 0xf2, 0xef, 0xe2, 0x0d, 0x0f, + 0xf1, 0x19, 0x02, 0xe7, 0xec, 0xff, 0xfe, 0xe4, 0xfe, 0xfb, 0x02, 0xf6, + 0xf1, 0xf4, 0x07, 0x1a, 0x2a, 0xf9, 0x06, 0xf9, 0xda, 0xf4, 0x22, 0x02, + 0x4f, 0x0a, 0xf3, 0xfc, 0xf3, 0xf6, 0x25, 0x0a, 0x28, 0x01, 0xf7, 0x09, + 0xe6, 0x05, 0x28, 0xf7, 0x1e, 0xf2, 0xee, 0x13, 0xee, 0x05, 0x0f, 0x0a, + 0x09, 0xe8, 0xe8, 0x0e, 0x05, 0x12, 0x0f, 0x15, 0x02, 0xec, 0xf8, 0x02, + 0xf7, 0x05, 0xf8, 0xff, 0xdc, 0x00, 0x01, 0x00, 0x12, 0x17, 0xec, 0x19, + 0xfa, 0x09, 0xfa, 0xf3, 0x1d, 0x0b, 0x07, 0x25, 0xea, 0x0c, 0xf5, 0xfa, + 0x04, 0xf7, 0xfe, 0x33, 0xfe, 0x14, 0xef, 0x04, 0xf0, 0x00, 0x00, 0x3a, + 0xea, 0xfa, 0x10, 0x01, 0xe4, 0x00, 0xff, 0x23, 0xe9, 0x26, 0x15, 0x10, + 0x04, 0x14, 0x0d, 0x08, 0xf8, 0xfd, 0x10, 0xfb, 0x00, 0x21, 0x06, 0xfa, + 0x0f, 0x08, 0xf1, 0x09, 0x28, 0xf0, 0xd8, 0x0d, 0x08, 0x09, 0x02, 0xfb, + 0x12, 0x03, 0x0e, 0xfb, 0xce, 0xf0, 0x39, 0xe5, 0x09, 0xf6, 0x1f, 0x35, + 0xdd, 0x1c, 0x25, 0xef, 0x17, 0x0c, 0xf6, 0x3e, 0xf0, 0x21, 0x08, 0xff, + 0xd7, 0xfc, 0xfd, 0x1f, 0xe5, 0x18, 0x12, 0xe9, 0xf5, 0xe9, 0x12, 0xf6, + 0x02, 0x13, 0xf4, 0x0a, 0xfd, 0x03, 0x09, 0x08, 0x2f, 0x07, 0xee, 0xfd, + 0xd7, 0x00, 0x2b, 0x29, 0x3b, 0xdb, 0xde, 0xf1, 0xe1, 0xf7, 0x47, 0x12, + 0x35, 0x0c, 0xe4, 0x09, 0xef, 0x17, 0x2b, 0xea, 0x2d, 0xf8, 0xe8, 0x18, + 0xef, 0x03, 0x11, 0x0a, 0x10, 0xff, 0xe8, 0x07, 0x0c, 0x07, 0x03, 0x18, + 0x05, 0x08, 0xf8, 0xf8, 0x06, 0x18, 0xe9, 0xf9, 0xe0, 0x0f, 0x0d, 0x18, + 0x04, 0x01, 0xf0, 0x1c, 0xf6, 0x14, 0xfd, 0x12, 0x0c, 0x0c, 0x02, 0x34, + 0xf6, 0xe6, 0xfd, 0xf9, 0xf9, 0xfd, 0x00, 0x2a, 0xfc, 0xf9, 0xff, 0x0a, + 0xfe, 0x1b, 0xf5, 0x34, 0xdc, 0xf9, 0x15, 0x13, 0xe7, 0x1b, 0xf7, 0x25, + 0xfd, 0x09, 0x08, 0x0a, 0xf0, 0x17, 0x0f, 0x04, 0xf4, 0xe9, 0x06, 0x07, + 0xf5, 0x02, 0xfc, 0xf5, 0x09, 0xee, 0xf1, 0x07, 0x38, 0x03, 0x05, 0x0f, + 0x16, 0x0f, 0xed, 0xff, 0x21, 0xf8, 0x34, 0x07, 0xd1, 0xf9, 0x27, 0x00, + 0x0c, 0x21, 0x18, 0x42, 0xe6, 0x02, 0x1a, 0xf1, 0x2f, 0xf1, 0x0e, 0x3b, + 0xee, 0xf8, 0x08, 0xea, 0xfe, 0xf9, 0x03, 0x18, 0xf5, 0xf8, 0x0d, 0xeb, + 0x01, 0x10, 0x09, 0x02, 0x15, 0xfb, 0xf1, 0x0b, 0xf2, 0x06, 0x08, 0x09, + 0x2f, 0x19, 0x02, 0xfe, 0xe4, 0x06, 0x1f, 0x17, 0x49, 0xf2, 0xe2, 0x02, + 0xef, 0x04, 0x26, 0x16, 0x3f, 0x08, 0xf1, 0x0a, 0xfd, 0xf9, 0x28, 0x01, + 0x15, 0x0b, 0xf9, 0x10, 0xdc, 0x02, 0x20, 0xf7, 0x16, 0xe6, 0x09, 0x03, + 0xf1, 0xf5, 0x12, 0x1c, 0xfb, 0x2a, 0x08, 0xfa, 0x0a, 0x16, 0xf6, 0x15, + 0xf0, 0x06, 0x11, 0xfd, 0x0e, 0xf9, 0xf6, 0x12, 0xed, 0xf3, 0xfd, 0x1f, + 0x0b, 0xfa, 0x08, 0x30, 0xf8, 0xff, 0x0b, 0xeb, 0x10, 0xff, 0x07, 0x22, + 0x0d, 0x07, 0x09, 0x03, 0xf6, 0xf8, 0xfc, 0x26, 0xf8, 0xee, 0x11, 0x02, + 0x03, 0x0a, 0xef, 0x38, 0xfe, 0x13, 0x1b, 0x09, 0xfe, 0x06, 0x05, 0xf3, + 0x04, 0xdf, 0xfc, 0x00, 0xe7, 0x15, 0xec, 0xf1, 0xf8, 0xfc, 0xed, 0x05, + 0x0e, 0xf3, 0x15, 0x09, 0x01, 0x0d, 0xfd, 0x00, 0x24, 0xe2, 0x31, 0x13, + 0xd5, 0x1b, 0x2b, 0xe8, 0x03, 0x08, 0x1d, 0x33, 0xdc, 0xfd, 0x24, 0xe4, + 0x20, 0xfa, 0x07, 0x33, 0x01, 0x12, 0x06, 0xf5, 0xef, 0xf7, 0xfa, 0x13, + 0x01, 0xec, 0xee, 0xe0, 0xfd, 0x0d, 0xff, 0x09, 0xf6, 0x00, 0xed, 0x07, + 0xea, 0x0e, 0xff, 0x0e, 0x26, 0xfc, 0xf0, 0xe7, 0xe7, 0xfe, 0x30, 0xff, + 0x24, 0x04, 0x06, 0xf4, 0xf5, 0xf8, 0x23, 0x0e, 0x3d, 0xf2, 0xfd, 0x04, + 0xe8, 0xfb, 0x23, 0xfe, 0x33, 0xe1, 0x01, 0xfd, 0xdc, 0xfb, 0x0e, 0xfa, + 0x22, 0xfb, 0x11, 0xfa, 0xff, 0x08, 0x21, 0x30, 0x13, 0x03, 0xf2, 0x03, + 0xf8, 0x0f, 0xec, 0x0d, 0xef, 0x0f, 0x10, 0x10, 0x0f, 0xf6, 0xf9, 0x1e, + 0xf7, 0xe5, 0x08, 0xfa, 0x09, 0xff, 0x00, 0x15, 0x02, 0x00, 0x08, 0xfe, + 0xfb, 0x0e, 0x15, 0x28, 0xfa, 0xfb, 0x13, 0x06, 0xfb, 0x05, 0xf6, 0x11, + 0xf6, 0x0b, 0x06, 0x15, 0xe1, 0x00, 0xe9, 0x0f, 0xe1, 0x1d, 0x18, 0xfd, + 0x0b, 0x0f, 0xff, 0xf2, 0xf5, 0xfd, 0x14, 0xff, 0xf4, 0xfe, 0xe2, 0xf8, + 0x14, 0x0b, 0xeb, 0x07, 0x35, 0xe2, 0xeb, 0x0b, 0x04, 0x22, 0xfe, 0x0e, + 0x1d, 0xf2, 0x24, 0x11, 0xcc, 0xec, 0x25, 0xf7, 0xff, 0xf9, 0x06, 0x29, + 0xe4, 0x07, 0x1c, 0xdb, 0xf8, 0x1d, 0xfa, 0x44, 0xf2, 0x01, 0x0f, 0xe6, + 0x11, 0x03, 0xee, 0x17, 0x06, 0xe0, 0x0c, 0xd8, 0xe9, 0xfd, 0x11, 0xfe, + 0x07, 0xdd, 0xea, 0xff, 0xde, 0xdd, 0x0a, 0x09, 0x30, 0xf2, 0x01, 0xe4, + 0xe0, 0xeb, 0x2d, 0x12, 0x2d, 0xeb, 0xfc, 0xf0, 0xe8, 0xf9, 0x1f, 0x08, + 0x3f, 0xeb, 0x0e, 0x13, 0xf9, 0x0c, 0x1c, 0x02, 0x25, 0xec, 0xf6, 0x05, + 0xf3, 0xf4, 0x18, 0x08, 0x12, 0xe9, 0xfb, 0xfd, 0xf9, 0x08, 0x13, 0x1c, + 0x08, 0xec, 0xfe, 0x02, 0xf1, 0x19, 0xf3, 0x1d, 0xf1, 0x07, 0x11, 0x12, + 0xfa, 0xf2, 0xf6, 0x0d, 0xff, 0x17, 0x0a, 0xfb, 0x1f, 0xf8, 0x11, 0x24, + 0xf6, 0xfc, 0xfe, 0x07, 0xed, 0x05, 0x1c, 0x21, 0xfe, 0xfe, 0x16, 0x0d, + 0x08, 0x0f, 0x09, 0x33, 0xf4, 0x1f, 0x14, 0x0c, 0xfe, 0xf5, 0xeb, 0x2a, + 0xee, 0xf3, 0x12, 0x19, 0xec, 0x01, 0x06, 0xf7, 0x05, 0x22, 0x0b, 0xeb, + 0xeb, 0x06, 0xe1, 0xf5, 0x0d, 0xee, 0xfb, 0x0a, 0x31, 0xff, 0xe3, 0xea, + 0x18, 0x09, 0xe3, 0x07, 0x1a, 0xf8, 0x15, 0xfc, 0xcc, 0xf2, 0x2a, 0xe5, + 0x01, 0xea, 0x10, 0x1f, 0xd9, 0x02, 0x13, 0xf6, 0x16, 0x01, 0x0e, 0x3c, + 0x02, 0x17, 0x04, 0xf1, 0xf7, 0x02, 0x07, 0x0c, 0x02, 0x1f, 0xf4, 0xe6, + 0xf0, 0xe9, 0x05, 0xf4, 0xfd, 0xe4, 0xf7, 0xe9, 0xfc, 0xef, 0x06, 0x02, + 0x26, 0xf1, 0xf1, 0xeb, 0xe9, 0xe6, 0x30, 0x1c, 0x38, 0x0f, 0x03, 0xf1, + 0x10, 0x04, 0x30, 0x19, 0x1f, 0xfb, 0xfc, 0x05, 0xe2, 0xfe, 0x18, 0xf2, + 0x1c, 0xf2, 0xf5, 0x0e, 0xf2, 0x05, 0x1d, 0x28, 0x12, 0xf0, 0xf0, 0x0f, + 0x0a, 0x03, 0x1a, 0x1a, 0xf3, 0x08, 0x13, 0xef, 0xf5, 0x1c, 0x06, 0x00, + 0xee, 0x12, 0x1d, 0x03, 0x18, 0x06, 0x0a, 0x0e, 0xf0, 0xeb, 0xfa, 0x0d, + 0x08, 0xff, 0x06, 0x24, 0x0f, 0x03, 0x0a, 0x0f, 0x0e, 0xff, 0x08, 0x33, + 0xfc, 0x00, 0x0e, 0xfb, 0xfb, 0x05, 0x07, 0x19, 0xe8, 0xe7, 0x12, 0x11, + 0x15, 0xf7, 0x0c, 0x1a, 0xf6, 0x28, 0x08, 0xeb, 0xf2, 0x25, 0xee, 0x01, + 0x03, 0xec, 0xed, 0xfa, 0xf0, 0xf2, 0xef, 0xf1, 0x02, 0x23, 0xef, 0x01, + 0x41, 0xfa, 0xf4, 0xf4, 0x15, 0xf5, 0xf5, 0xf9, 0x28, 0xde, 0x20, 0xf6, + 0xc7, 0xde, 0x21, 0xe4, 0xfe, 0xec, 0x0d, 0x2c, 0xee, 0x24, 0x10, 0xf0, + 0x1d, 0x12, 0x0e, 0x2b, 0x06, 0xf8, 0xfd, 0x01, 0x08, 0xef, 0xfd, 0x0f, + 0xeb, 0xed, 0xe1, 0xdf, 0xf1, 0xe5, 0x16, 0xe3, 0x08, 0xfc, 0xf6, 0xf6, + 0xd8, 0xf0, 0x23, 0xfc, 0x2b, 0xf5, 0xff, 0xe7, 0xf4, 0xe9, 0x29, 0x09, + 0x2b, 0x0c, 0xff, 0x08, 0x0b, 0xed, 0x29, 0x14, 0x3c, 0xf5, 0xeb, 0x18, + 0xf6, 0x10, 0x22, 0xf9, 0x17, 0x23, 0x02, 0x0c, 0xf6, 0xfa, 0x2f, 0xfe, + 0x1e, 0xeb, 0xfd, 0x03, 0xf0, 0x07, 0x1c, 0x09, 0xfa, 0xe1, 0x0d, 0x0f, + 0x18, 0x03, 0xfe, 0xf0, 0xec, 0x0b, 0x10, 0x02, 0x14, 0x06, 0xef, 0xf7, + 0xea, 0x0b, 0x05, 0xfe, 0x1f, 0x06, 0x0e, 0x07, 0x00, 0xe1, 0x01, 0x01, + 0x07, 0x05, 0x09, 0xf7, 0xef, 0x15, 0xf7, 0x12, 0x05, 0x03, 0x04, 0x1d, + 0x04, 0x10, 0x12, 0x06, 0x05, 0x00, 0x08, 0x18, 0xd6, 0xf2, 0xfa, 0x07, + 0xf8, 0x12, 0x07, 0xfd, 0xdd, 0x00, 0x04, 0xfb, 0xf8, 0x09, 0xf3, 0x09, + 0xfb, 0xf0, 0xe8, 0x09, 0x27, 0xf5, 0xf8, 0x06, 0x01, 0x02, 0x0e, 0xf6, + 0x1f, 0xfa, 0x29, 0xf8, 0xd6, 0x01, 0x22, 0xf8, 0x1d, 0xe3, 0x1a, 0x39, + 0x0a, 0x0d, 0x19, 0xf5, 0x12, 0xfb, 0x1d, 0x2a, 0x03, 0xf6, 0x0c, 0xf2, + 0xfd, 0xec, 0x18, 0x13, 0xfe, 0x1a, 0xe8, 0xdd, 0x01, 0xf8, 0x30, 0x01, + 0xf8, 0xfe, 0xe4, 0xe7, 0xff, 0xeb, 0x23, 0xfa, 0x2c, 0xf0, 0xfc, 0xe7, + 0x0a, 0xf8, 0x18, 0x10, 0x23, 0x01, 0xfa, 0xe8, 0xf1, 0xfa, 0x1d, 0x0e, + 0x17, 0xe7, 0xe4, 0xf5, 0xf9, 0x0c, 0x17, 0x0c, 0x13, 0xe8, 0xe1, 0x17, + 0x19, 0x05, 0x0b, 0x0f, 0x23, 0xed, 0xff, 0xfe, 0xe0, 0x14, 0x16, 0x00, + 0x0d, 0x1c, 0x0b, 0xf5, 0xfb, 0x18, 0xee, 0xff, 0xff, 0xf3, 0x18, 0x0c, + 0x05, 0xfa, 0xf6, 0xfe, 0xfe, 0xf8, 0xf8, 0x09, 0xef, 0xf8, 0x0e, 0xf0, + 0x00, 0xf8, 0x0c, 0xf8, 0xf6, 0x07, 0x16, 0x11, 0xf8, 0xea, 0xff, 0xff, + 0x01, 0x20, 0x07, 0x08, 0xfd, 0x1c, 0xfc, 0x06, 0xed, 0x0d, 0x08, 0x15, + 0xf0, 0x25, 0x01, 0x1b, 0x00, 0x02, 0xfe, 0x01, 0x05, 0x01, 0xfd, 0xf1, + 0xe5, 0x0c, 0xe4, 0xe1, 0xf0, 0xfa, 0xee, 0x0e, 0x35, 0xee, 0x15, 0xef, + 0x0a, 0xf9, 0x01, 0xf5, 0x1f, 0x05, 0x1f, 0x0d, 0xe1, 0xf4, 0xff, 0xf5, + 0x23, 0x02, 0x18, 0x30, 0xfc, 0xf0, 0x0d, 0x04, 0x0d, 0x06, 0x29, 0x1d, + 0xf9, 0x08, 0x06, 0xe5, 0x13, 0xfd, 0x0d, 0x26, 0xef, 0x09, 0xdc, 0xf2, + 0x05, 0xdf, 0x0c, 0xf6, 0xf3, 0xd9, 0xf8, 0x08, 0xef, 0xeb, 0x0f, 0xf9, + 0x3a, 0x03, 0xff, 0xe0, 0xf7, 0xf0, 0x15, 0x12, 0x41, 0x0b, 0xf1, 0x04, + 0x04, 0xe2, 0x0e, 0x0b, 0x2c, 0x03, 0xea, 0x02, 0xfb, 0xe7, 0x08, 0xe9, + 0x22, 0xf3, 0xf2, 0x1c, 0xfa, 0xf3, 0x11, 0x04, 0x1f, 0xf5, 0x02, 0x0f, + 0x1a, 0x1f, 0x24, 0x0b, 0x06, 0x1f, 0xf3, 0x06, 0x00, 0x02, 0xe8, 0xf6, + 0xf4, 0xe8, 0x07, 0x2e, 0xfb, 0xf8, 0x10, 0x09, 0xf0, 0x0e, 0xff, 0xfe, + 0x1c, 0x14, 0x17, 0x06, 0xe2, 0xf1, 0xfa, 0x01, 0x11, 0x13, 0x12, 0x29, + 0xf1, 0x0f, 0x1f, 0xfa, 0xfd, 0xfd, 0x02, 0x07, 0x0e, 0xfb, 0x0e, 0x04, + 0x01, 0x01, 0xed, 0xfe, 0xde, 0xfd, 0x08, 0xef, 0xf6, 0x0a, 0xff, 0x0f, + 0xe7, 0xf2, 0x0f, 0x02, 0xea, 0x10, 0xf9, 0xec, 0xfd, 0x09, 0xea, 0x1f, + 0x46, 0xdd, 0xe2, 0xf7, 0x08, 0xf5, 0xf7, 0xe9, 0x33, 0xfb, 0x2f, 0xf6, + 0xb5, 0x1d, 0x15, 0xeb, 0x11, 0xf7, 0x2a, 0x2e, 0x08, 0x1d, 0xf4, 0xfb, + 0x15, 0xfa, 0x22, 0x34, 0xff, 0x06, 0xf6, 0xfd, 0xfa, 0xf9, 0x03, 0xf5, + 0xf4, 0xf4, 0xd5, 0xea, 0x01, 0x08, 0x22, 0xf1, 0xf2, 0x06, 0xd1, 0xe5, + 0x0c, 0xef, 0x12, 0x03, 0x08, 0x02, 0xf7, 0x05, 0x1b, 0x07, 0x39, 0x34, + 0x21, 0xe2, 0xe3, 0x0b, 0x0c, 0xf6, 0x29, 0xf7, 0x24, 0x0a, 0xfc, 0xff, + 0x1a, 0xfd, 0x05, 0xff, 0xff, 0x0e, 0x0a, 0x1a, 0x09, 0xfb, 0x15, 0x04, + 0x03, 0xf7, 0xfe, 0x00, 0xfc, 0xfb, 0x11, 0xfa, 0x1d, 0x0e, 0x06, 0xed, + 0xfc, 0x23, 0xd8, 0xf2, 0x04, 0xe5, 0x0f, 0x16, 0x29, 0xfe, 0xf5, 0xec, + 0xe2, 0x0e, 0xeb, 0x09, 0x1d, 0x11, 0x05, 0x11, 0xe4, 0x29, 0x12, 0x02, + 0x12, 0x19, 0x0e, 0x1a, 0xee, 0xf9, 0x05, 0x09, 0xf5, 0xfd, 0x05, 0x04, + 0xe4, 0xf1, 0x17, 0x01, 0xf2, 0xfe, 0x0b, 0xf4, 0x0d, 0x04, 0x06, 0xfe, + 0xff, 0xec, 0xe9, 0x00, 0xff, 0x03, 0x03, 0xfd, 0xf1, 0x15, 0xfc, 0xf3, + 0xff, 0xfe, 0x09, 0xee, 0x3c, 0x01, 0xec, 0x02, 0xf0, 0xf6, 0x20, 0xeb, + 0x16, 0x07, 0x32, 0xf3, 0xce, 0xf0, 0x02, 0xd4, 0x11, 0xe6, 0x28, 0x0e, + 0xe3, 0x21, 0xee, 0xce, 0x1e, 0xd9, 0x23, 0x26, 0x06, 0xfa, 0xf9, 0xf1, + 0x01, 0xe6, 0x0b, 0x07, 0xdc, 0x21, 0xbc, 0xe3, 0xef, 0xf8, 0x12, 0xfc, + 0xe6, 0xfe, 0xf5, 0xd4, 0x15, 0x0a, 0x00, 0x13, 0xfc, 0xec, 0xf3, 0xd6, + 0x1a, 0xe3, 0x21, 0x36, 0x2a, 0x03, 0xe9, 0xe3, 0xff, 0x00, 0x13, 0x1c, + 0x0e, 0x20, 0xe5, 0xf5, 0x24, 0x0b, 0x20, 0x14, 0x13, 0xf8, 0x04, 0x1b, + 0x2f, 0x0a, 0x15, 0x00, 0xf4, 0x1a, 0x11, 0x0d, 0x03, 0x18, 0x0f, 0x18, + 0x04, 0x1f, 0xfb, 0xf2, 0x1f, 0x15, 0x03, 0xfb, 0x0b, 0x17, 0xfb, 0x0b, + 0x1b, 0x1f, 0xf4, 0x07, 0xf9, 0xf9, 0xf8, 0xf4, 0x14, 0x0f, 0xf6, 0xfe, + 0xdd, 0x0b, 0xff, 0x01, 0x18, 0x04, 0x1b, 0x0a, 0xed, 0xe7, 0xf9, 0x16, + 0x02, 0x01, 0x00, 0xf7, 0xf1, 0x07, 0xf0, 0x06, 0xf8, 0x0b, 0x02, 0xf3, + 0xff, 0x20, 0xfd, 0x01, 0x04, 0xf5, 0xd9, 0xf4, 0xf4, 0xf2, 0xe8, 0xff, + 0x04, 0x00, 0xf0, 0xe2, 0xfe, 0xed, 0x1b, 0xef, 0x20, 0xfa, 0xfb, 0xf4, + 0x02, 0x18, 0x07, 0xfb, 0xef, 0xe4, 0x08, 0x0d, 0xe1, 0x0e, 0x25, 0xc6, + 0xfd, 0x0c, 0x1c, 0x0b, 0xf0, 0x01, 0x1c, 0xd4, 0x11, 0xf5, 0x1b, 0x09, + 0xfb, 0xda, 0x13, 0xe3, 0xf9, 0x10, 0x14, 0xf0, 0xf0, 0xfd, 0x1f, 0xcf, + 0xf4, 0xe4, 0xfb, 0x0e, 0x0a, 0x11, 0xed, 0xdc, 0xfc, 0xe6, 0xf7, 0xfc, + 0x13, 0xe1, 0x0b, 0xe4, 0x04, 0x11, 0xee, 0x21, 0x14, 0xe1, 0x07, 0xe4, + 0xfb, 0x08, 0x03, 0x2b, 0x27, 0xf6, 0x0d, 0x02, 0x1b, 0x09, 0x09, 0xf8, + 0x14, 0x19, 0x0f, 0x0b, 0x01, 0x10, 0x09, 0x12, 0x03, 0xf5, 0x18, 0xf3, + 0xfb, 0xf5, 0x02, 0x0e, 0x0d, 0x00, 0x07, 0xfc, 0x18, 0x25, 0x0b, 0xf0, + 0xf9, 0xe6, 0x08, 0x01, 0x24, 0x14, 0xfa, 0xed, 0xe5, 0x1f, 0x09, 0xfe, + 0x08, 0xee, 0x1a, 0x1a, 0x05, 0x00, 0xff, 0x0c, 0xfe, 0xf9, 0x11, 0x11, + 0xea, 0xfe, 0x08, 0xf9, 0xf0, 0xe4, 0x01, 0x0d, 0xf1, 0x00, 0x0b, 0xea, + 0x19, 0xea, 0xf3, 0xf8, 0x08, 0x12, 0x1c, 0x1f, 0xfb, 0xef, 0xf0, 0xf2, + 0x14, 0xe1, 0x03, 0xfa, 0xf9, 0xda, 0xe9, 0xfc, 0xf3, 0xff, 0x12, 0x04, + 0xf7, 0xfc, 0x17, 0x0f, 0xfc, 0x29, 0x03, 0xe5, 0xf2, 0xee, 0x1e, 0xfa, + 0x04, 0xed, 0x25, 0xf4, 0xe1, 0x15, 0x10, 0x1e, 0xef, 0x1c, 0x04, 0xde, + 0xe5, 0x08, 0x21, 0xfd, 0xfd, 0xea, 0x03, 0xca, 0xda, 0x26, 0x00, 0x0a, + 0xfd, 0x05, 0xf0, 0xd4, 0xe1, 0x1a, 0xe4, 0xf5, 0x07, 0xe7, 0xfa, 0xdf, + 0xd4, 0x03, 0xf0, 0x10, 0x15, 0x0c, 0xf4, 0xed, 0xe3, 0xfb, 0x0f, 0x1e, + 0x16, 0x09, 0x00, 0xec, 0xea, 0x13, 0x16, 0x0b, 0x01, 0xfb, 0xff, 0x00, + 0xfb, 0x07, 0x13, 0x08, 0xf4, 0xe4, 0x12, 0x00, 0xfb, 0xfa, 0xfc, 0x08, + 0xeb, 0x19, 0x02, 0x1c, 0xe8, 0x26, 0xf3, 0x10, 0x09, 0x0f, 0x19, 0x02, + 0xfb, 0xec, 0xf7, 0xe2, 0xfb, 0xfa, 0x11, 0xf3, 0x0b, 0x08, 0xff, 0xd9, + 0xf8, 0x12, 0x18, 0x06, 0x07, 0x22, 0xff, 0x19, 0xf5, 0x0b, 0x0a, 0x13, + 0xf2, 0xfa, 0x02, 0x21, 0xeb, 0x11, 0x17, 0x17, 0xec, 0xe1, 0x0e, 0xf7, + 0xe8, 0xd8, 0x0e, 0x01, 0xf1, 0xed, 0xed, 0xf0, 0x09, 0xf7, 0xe7, 0xfd, + 0xf0, 0xf9, 0xdb, 0xee, 0xdc, 0xfb, 0xf8, 0x0a, 0xf5, 0x0b, 0xd4, 0xd7, + 0x08, 0x06, 0x18, 0x06, 0x0c, 0x13, 0xfd, 0x09, 0x13, 0x26, 0x12, 0xf4, + 0xef, 0x00, 0xf5, 0x28, 0x18, 0xfe, 0x04, 0x0e, 0x21, 0x1a, 0x0a, 0x1e, + 0x09, 0xf0, 0x0d, 0x0f, 0xec, 0xf3, 0x17, 0x22, 0x00, 0xec, 0x0e, 0x01, + 0xe9, 0x08, 0x09, 0xf2, 0xf2, 0x08, 0xf0, 0x0b, 0xd9, 0x09, 0x14, 0xf5, + 0xf6, 0x04, 0x19, 0xf4, 0x11, 0xe9, 0xf2, 0x0d, 0x20, 0x17, 0x0a, 0x05, + 0x0c, 0x04, 0x01, 0xfd, 0xf4, 0xfb, 0x1b, 0x0c, 0xf2, 0x0b, 0xff, 0xfe, + 0x01, 0xd8, 0xfa, 0x0e, 0xf5, 0x14, 0xf9, 0x01, 0x04, 0xf8, 0xfa, 0x02, + 0xe8, 0xf9, 0xf9, 0xea, 0xf1, 0x07, 0xff, 0x1e, 0x01, 0x0b, 0xf7, 0x0a, + 0xf7, 0x0c, 0xfd, 0xec, 0xf3, 0x05, 0xf8, 0xda, 0x0b, 0x15, 0xf6, 0xee, + 0xf9, 0x10, 0xfa, 0xfe, 0x08, 0xf0, 0xe6, 0xec, 0x05, 0xff, 0x15, 0x19, + 0x1f, 0x11, 0xfc, 0x09, 0x08, 0x01, 0x06, 0xfe, 0x04, 0x08, 0xfb, 0xfb, + 0x08, 0xf4, 0xf6, 0x28, 0x10, 0xf9, 0x28, 0x0b, 0xf8, 0x0d, 0x01, 0x00, + 0xff, 0x02, 0x05, 0x08, 0xea, 0xe9, 0xf4, 0xf6, 0x01, 0xea, 0xdf, 0x1f, + 0xfe, 0x0a, 0xf9, 0xf7, 0x0c, 0x1b, 0x06, 0xed, 0xf6, 0xf2, 0x03, 0x03, + 0xfd, 0x04, 0xf5, 0x10, 0x0a, 0x0b, 0xf4, 0xf8, 0xf1, 0xe7, 0x05, 0xfe, + 0xe7, 0x0b, 0xf1, 0xec, 0xf4, 0xec, 0x06, 0xee, 0xde, 0x05, 0x1b, 0xfe, + 0x13, 0xf3, 0xd9, 0xea, 0x04, 0x10, 0x05, 0xed, 0x15, 0x02, 0x0b, 0x10, + 0xfa, 0x02, 0x05, 0x0b, 0x02, 0x07, 0xfc, 0xf5, 0x15, 0x14, 0x05, 0xf7, + 0x0c, 0xfe, 0xf6, 0xf4, 0xfa, 0x06, 0xfc, 0x13, 0xdc, 0xe4, 0x09, 0xfa, + 0x02, 0x23, 0xec, 0x06, 0x11, 0x13, 0xf8, 0xfa, 0x27, 0x28, 0x0b, 0x23, + 0xec, 0xf1, 0x09, 0x17, 0x0f, 0x13, 0xff, 0xf2, 0xfc, 0x0a, 0xf5, 0x0d, + 0x03, 0x26, 0x01, 0x0f, 0xfe, 0xf1, 0xfb, 0xe6, 0xf0, 0x02, 0xf2, 0xff, + 0x02, 0x11, 0xff, 0xfd, 0x1c, 0x02, 0x0b, 0xf6, 0x14, 0x0c, 0x0b, 0x21, + 0x28, 0xf0, 0x11, 0x05, 0x06, 0xed, 0xf9, 0x0a, 0xf2, 0xef, 0xf8, 0xf1, + 0xfe, 0x0d, 0xf9, 0xf7, 0xea, 0x00, 0x08, 0xdb, 0x02, 0x0f, 0xfe, 0x04, + 0xef, 0x20, 0x16, 0x01, 0xe8, 0xed, 0xe4, 0x22, 0xf6, 0x19, 0x00, 0x04, + 0x01, 0x13, 0xeb, 0x0d, 0xec, 0x01, 0x08, 0x05, 0x0c, 0x0e, 0xfe, 0x02, + 0x12, 0xf7, 0x27, 0xf9, 0xfd, 0x18, 0xfe, 0x24, 0xf7, 0x13, 0xed, 0x1e, + 0x09, 0xff, 0xd8, 0xf4, 0x12, 0xf8, 0x04, 0x0c, 0x1c, 0x11, 0xfd, 0x17, + 0x1d, 0x01, 0x13, 0xee, 0x11, 0xf3, 0xf8, 0x06, 0xf6, 0x16, 0xfe, 0x15, + 0x16, 0xdc, 0x1f, 0x00, 0x25, 0xee, 0xff, 0xf7, 0xf6, 0x02, 0xdd, 0x15, + 0xf1, 0x14, 0x08, 0xe8, 0xe5, 0x21, 0xea, 0xf0, 0x1a, 0x07, 0xea, 0x08, + 0xea, 0xe4, 0x1e, 0x00, 0x13, 0x17, 0xec, 0x11, 0xd6, 0x11, 0x18, 0x17, + 0x04, 0x15, 0x03, 0x3a, 0xd6, 0x02, 0x07, 0x04, 0xe6, 0xe5, 0xfe, 0x0e, + 0xff, 0xed, 0xfc, 0xfb, 0xff, 0x1c, 0x06, 0x0a, 0xfb, 0xf9, 0xea, 0x1a, + 0x21, 0xf5, 0x04, 0x06, 0x0a, 0xe3, 0x16, 0xea, 0x04, 0xe2, 0xf9, 0xf9, + 0xe6, 0xfb, 0x0f, 0xfc, 0x06, 0xfb, 0x10, 0x07, 0x07, 0x13, 0x07, 0xfc, + 0x16, 0xef, 0x07, 0xdc, 0x12, 0x1f, 0x08, 0xf4, 0xe9, 0x14, 0x06, 0xf7, + 0xf1, 0x0c, 0x01, 0x0c, 0xe6, 0x04, 0xf3, 0xf2, 0xe5, 0xf3, 0xef, 0x1d, + 0xf6, 0x20, 0x07, 0xfe, 0xf4, 0x05, 0xee, 0x10, 0xfd, 0x0e, 0x0b, 0x02, + 0x0d, 0xd8, 0x07, 0xfb, 0x26, 0x0a, 0x1c, 0x21, 0x06, 0x1f, 0xf4, 0x06, + 0x37, 0x18, 0xfa, 0x16, 0x1e, 0x24, 0xfb, 0xf0, 0x12, 0xf9, 0x02, 0x09, + 0x17, 0x16, 0xf3, 0xf9, 0x17, 0xf2, 0x02, 0x0a, 0x2d, 0xe7, 0xe3, 0x25, + 0xf0, 0xf9, 0x0f, 0xdd, 0x15, 0xe6, 0x04, 0xfc, 0xf1, 0x17, 0x0a, 0xea, + 0x24, 0x07, 0xf1, 0x11, 0x13, 0x29, 0xf4, 0xc5, 0xfb, 0x07, 0xef, 0x13, + 0x0b, 0xe1, 0xf1, 0xeb, 0xf8, 0x1b, 0x09, 0x08, 0x1f, 0x15, 0xf2, 0x05, + 0x02, 0xdd, 0x09, 0x0f, 0x16, 0x10, 0x01, 0x30, 0xf2, 0xe0, 0x27, 0xfe, + 0xf1, 0x0e, 0x0e, 0x07, 0xe6, 0x07, 0x0b, 0x18, 0xfe, 0x0f, 0x01, 0x07, + 0xf4, 0x07, 0x10, 0xe7, 0xfb, 0xf3, 0xf7, 0x0b, 0xf9, 0x15, 0x18, 0x25, + 0x0c, 0x14, 0x02, 0x08, 0x0a, 0x0f, 0x10, 0xec, 0xee, 0x1a, 0x03, 0x14, + 0x0f, 0xfa, 0x25, 0xff, 0x18, 0x0d, 0x0b, 0xea, 0x1f, 0x28, 0x10, 0x0c, + 0xe7, 0xee, 0xf7, 0xfa, 0x03, 0x15, 0x0c, 0x1d, 0x01, 0x00, 0x12, 0xee, + 0x01, 0xf1, 0xf8, 0x0b, 0xf3, 0xfd, 0x04, 0xf8, 0x02, 0x1e, 0x0e, 0xf3, + 0x02, 0x10, 0xfd, 0x07, 0x0b, 0x09, 0x03, 0x10, 0x3e, 0x08, 0x0e, 0x0c, + 0xf4, 0xe7, 0xfd, 0x1c, 0x27, 0x1a, 0xed, 0xe1, 0x08, 0xdc, 0xd9, 0xf1, + 0x1e, 0x07, 0x12, 0xf1, 0x10, 0xfb, 0xc8, 0x08, 0x0f, 0x03, 0x1d, 0xdc, + 0x23, 0x04, 0xf9, 0x0a, 0xff, 0x08, 0x0e, 0xc9, 0x39, 0x0a, 0x01, 0x07, + 0xec, 0xe0, 0x05, 0xe8, 0x14, 0xd8, 0xe1, 0xfa, 0xd6, 0xf8, 0xed, 0xdb, + 0xff, 0x1d, 0xf5, 0x17, 0x0f, 0x1c, 0xdc, 0xed, 0xff, 0xff, 0x04, 0x13, + 0xf5, 0xe7, 0xd2, 0x12, 0xdb, 0xe1, 0x13, 0x11, 0x23, 0x0e, 0xf9, 0x31, + 0xdc, 0xef, 0x07, 0x0a, 0x20, 0xf2, 0xf9, 0x13, 0xff, 0x1c, 0x2a, 0xdf, + 0xdb, 0xe7, 0x11, 0xf2, 0xfd, 0xfb, 0x28, 0x00, 0x15, 0x03, 0x02, 0x20, + 0x07, 0xf7, 0x19, 0x13, 0x13, 0xf6, 0x09, 0xfe, 0xfd, 0x20, 0x14, 0xf5, + 0xf5, 0xfc, 0x14, 0x0e, 0x17, 0xfe, 0x15, 0x04, 0xf9, 0xf6, 0x1d, 0xf6, + 0x1b, 0xe4, 0xee, 0xfd, 0x00, 0xe9, 0xee, 0xce, 0x0f, 0x20, 0x05, 0x02, + 0x0d, 0x06, 0x05, 0xf8, 0xef, 0xdf, 0x16, 0x17, 0xe6, 0xf1, 0x10, 0xf3, + 0x06, 0x04, 0xdb, 0xfb, 0xe7, 0xf8, 0x02, 0x11, 0xff, 0x0d, 0x0a, 0xfa, + 0x27, 0x0a, 0xfc, 0xe8, 0x11, 0x17, 0xf0, 0x0d, 0x0d, 0xee, 0xdf, 0xdd, + 0xf1, 0x15, 0xd6, 0xf7, 0x00, 0xef, 0x2e, 0xe6, 0x24, 0xfd, 0xd5, 0x04, + 0xf0, 0x08, 0x08, 0xed, 0x22, 0x07, 0xe1, 0x09, 0xd0, 0x0b, 0x18, 0xe6, + 0x3f, 0x0a, 0xe5, 0xe2, 0xf9, 0x08, 0x02, 0xd6, 0x13, 0x15, 0xbd, 0x00, + 0x0e, 0xf8, 0xe2, 0xca, 0xec, 0x0e, 0xe6, 0xef, 0x15, 0x11, 0xcb, 0xdf, + 0xf9, 0x03, 0x22, 0x10, 0xfb, 0xf9, 0xe5, 0x08, 0xe1, 0x11, 0x10, 0xfc, + 0xfa, 0x00, 0xf8, 0x30, 0xe5, 0x08, 0x14, 0xe8, 0x12, 0xe2, 0x04, 0x19, + 0x0b, 0xfa, 0x33, 0xf3, 0xec, 0xfe, 0xf8, 0x25, 0xf8, 0x21, 0x28, 0xef, + 0x00, 0xde, 0xff, 0x2b, 0x03, 0xfc, 0x10, 0x0c, 0xcf, 0xfd, 0x19, 0x0a, + 0x0c, 0xf2, 0xf7, 0x0c, 0xfd, 0x02, 0x1c, 0xdf, 0x26, 0x0d, 0xf0, 0x0b, + 0xce, 0x15, 0xfb, 0xec, 0x27, 0xf6, 0xf9, 0xe5, 0xe2, 0xfb, 0xfd, 0xd8, + 0x28, 0xec, 0xe9, 0xf2, 0xca, 0x09, 0x02, 0x06, 0x0c, 0xfa, 0x05, 0x01, + 0xd5, 0x0a, 0x02, 0xfb, 0x04, 0x17, 0xdd, 0xfe, 0xeb, 0xf1, 0x09, 0x10, + 0x12, 0xff, 0x00, 0xe0, 0x26, 0xf7, 0xed, 0xf4, 0x00, 0xf2, 0xfa, 0x07, + 0x02, 0xf5, 0x06, 0xe8, 0x03, 0xfd, 0xdc, 0xf2, 0xc2, 0xff, 0x0b, 0xd6, + 0x25, 0x04, 0xe9, 0xf0, 0xd9, 0x08, 0x09, 0xc5, 0x23, 0x12, 0xf6, 0x13, + 0x11, 0xf3, 0x18, 0xf0, 0x34, 0xfe, 0xfe, 0xed, 0xea, 0x02, 0x17, 0xdc, + 0x1b, 0x1b, 0xea, 0xfe, 0xea, 0xfe, 0xf2, 0xc4, 0xfd, 0x04, 0xe9, 0x0d, + 0x0d, 0x09, 0xca, 0xd4, 0xe1, 0x04, 0x1e, 0xff, 0x0f, 0xef, 0xd6, 0x0f, + 0xd5, 0xf8, 0x26, 0xd6, 0x33, 0xe8, 0xf5, 0x3b, 0xf1, 0xe8, 0x39, 0xe8, + 0x08, 0xe5, 0x01, 0x02, 0x04, 0xf6, 0x19, 0x0a, 0xd0, 0xeb, 0x0b, 0x15, + 0xf7, 0x0e, 0x23, 0xf6, 0xf4, 0xd8, 0xf4, 0x17, 0x23, 0x25, 0x14, 0x01, + 0xd7, 0xfd, 0xf9, 0x1f, 0x1b, 0x11, 0x0a, 0x18, 0xf5, 0xf5, 0x0f, 0xe0, + 0x2e, 0x01, 0xe5, 0xdb, 0xe2, 0xf2, 0x14, 0xfa, 0x2a, 0x00, 0xe2, 0xea, + 0xfd, 0x0e, 0xfc, 0xc1, 0x35, 0x08, 0xf6, 0xf9, 0xec, 0x00, 0x06, 0x00, + 0x0b, 0xf6, 0x01, 0xfe, 0xea, 0x0b, 0x08, 0x05, 0xe4, 0xea, 0xd7, 0xfd, + 0xee, 0xf3, 0x0c, 0x0c, 0x0d, 0x02, 0xfd, 0xee, 0x17, 0x10, 0x13, 0xfd, + 0x07, 0x03, 0xf8, 0x0c, 0xd4, 0xed, 0xfe, 0x07, 0xf4, 0xee, 0xf4, 0x03, + 0xc2, 0x18, 0x2c, 0xd1, 0x33, 0xd8, 0xdb, 0xfa, 0xed, 0x10, 0x1c, 0xe3, + 0x37, 0x0a, 0xea, 0xfe, 0xf6, 0xef, 0x20, 0xed, 0x32, 0xf7, 0xf5, 0xf3, + 0xca, 0xfd, 0x0a, 0xcf, 0x0d, 0x10, 0xde, 0x07, 0x18, 0x10, 0xf0, 0xd6, + 0x0c, 0x04, 0xeb, 0x1a, 0xf9, 0x08, 0xc4, 0xcb, 0xe4, 0x0b, 0x19, 0xfc, + 0x29, 0xf6, 0xec, 0x07, 0xf3, 0xed, 0x2b, 0xe9, 0xfa, 0x02, 0xec, 0x2b, + 0xf0, 0xf2, 0x2d, 0xe8, 0xed, 0x00, 0x12, 0x13, 0xed, 0x1a, 0x3d, 0xf0, + 0x05, 0x04, 0xfc, 0x13, 0x10, 0x01, 0x40, 0xf2, 0x06, 0x02, 0xf9, 0x22, + 0x24, 0xff, 0x18, 0x00, 0xeb, 0xe8, 0x14, 0xf9, 0x25, 0xe0, 0xff, 0x03, + 0xe5, 0xfd, 0x08, 0xea, 0x2e, 0x0b, 0x05, 0xe7, 0xde, 0xe4, 0xf5, 0xea, + 0x3a, 0xf4, 0xf4, 0xe7, 0xed, 0xec, 0xf8, 0xee, 0x30, 0x0a, 0xdb, 0x05, + 0xf7, 0x16, 0xff, 0xf7, 0xfa, 0x1f, 0xef, 0xe4, 0xce, 0xf8, 0x13, 0x04, + 0xf9, 0x01, 0xe1, 0x03, 0xf9, 0xf9, 0x08, 0x04, 0xfa, 0xe4, 0xe7, 0xf7, + 0x28, 0xfd, 0xfd, 0x00, 0xfc, 0xfb, 0xef, 0x0a, 0xec, 0x0c, 0x0a, 0xd2, + 0x05, 0xfb, 0xcd, 0xfb, 0x9d, 0xea, 0x1c, 0xe5, 0x25, 0xe8, 0xea, 0x0b, + 0xf0, 0xf3, 0x0d, 0xab, 0x49, 0x0e, 0xeb, 0x00, 0xe2, 0x03, 0x29, 0xe0, + 0x3d, 0x06, 0xf7, 0xf8, 0xcf, 0x0c, 0x1a, 0xd6, 0x1f, 0xef, 0xfd, 0xff, + 0xef, 0x0c, 0xdb, 0xe0, 0x20, 0x06, 0xdf, 0x1a, 0xe7, 0xfc, 0xb2, 0xd1, + 0xdf, 0x13, 0x07, 0x1f, 0x0c, 0xf7, 0xde, 0x0a, 0xdb, 0xdf, 0x1a, 0xf5, + 0x29, 0x0d, 0xeb, 0x2c, 0xcf, 0x0e, 0x26, 0xfe, 0xef, 0x04, 0xf5, 0x14, + 0x09, 0x13, 0x34, 0xff, 0xfe, 0x0e, 0x06, 0x0e, 0x10, 0xf9, 0x2a, 0x0b, + 0xe6, 0xfe, 0xf1, 0x1a, 0x36, 0x29, 0x29, 0x05, 0x05, 0xd8, 0x14, 0x12, + 0x26, 0x0b, 0x18, 0xff, 0xd7, 0xdf, 0x0f, 0xed, 0x31, 0xf7, 0xfc, 0xec, + 0x0b, 0xef, 0x0c, 0xd2, 0x30, 0xf9, 0x04, 0xfe, 0xef, 0xe4, 0xfb, 0xd1, + 0x32, 0xe5, 0xee, 0xf0, 0x0c, 0xe6, 0x13, 0xed, 0x1e, 0x0b, 0xe4, 0xe0, + 0xfa, 0xf4, 0x14, 0xf4, 0x18, 0xf7, 0xd9, 0xf6, 0xed, 0xea, 0xfc, 0x06, + 0xfc, 0xf5, 0xed, 0xeb, 0x05, 0x03, 0x1b, 0x0b, 0xff, 0x0b, 0xef, 0x01, + 0xf1, 0x16, 0x05, 0x00, 0xee, 0x0a, 0xdb, 0x10, 0xb4, 0x14, 0x0f, 0xe1, + 0x1c, 0xfd, 0xf0, 0xf8, 0xc3, 0x11, 0x17, 0xba, 0x47, 0x15, 0xe6, 0x01, + 0xea, 0xf1, 0x0c, 0x08, 0x4a, 0x15, 0xf0, 0xf7, 0xea, 0x00, 0xf5, 0xd4, + 0xf1, 0xff, 0xe0, 0x0c, 0xf4, 0x17, 0xd8, 0xea, 0x03, 0xff, 0xd5, 0x18, + 0xfb, 0x07, 0xc7, 0xc9, 0xdd, 0xf3, 0x15, 0x0d, 0x22, 0xea, 0xdb, 0x0a, + 0xd6, 0x09, 0x1d, 0xe5, 0x2d, 0x04, 0xfc, 0x35, 0xc6, 0x0e, 0x33, 0xf1, + 0xd7, 0xea, 0x01, 0x1b, 0x0e, 0x01, 0x2a, 0xff, 0xef, 0xf1, 0xf7, 0x0f, + 0xff, 0x00, 0x3b, 0xe8, 0x0a, 0xff, 0xf4, 0x0d, 0x1f, 0x04, 0x17, 0xf7, + 0xdf, 0xec, 0x12, 0x26, 0x36, 0x07, 0x0c, 0x06, 0xe7, 0xd6, 0x13, 0xe3, + 0x30, 0x09, 0x00, 0xf5, 0xe0, 0xf3, 0x11, 0xe2, 0x38, 0x0d, 0xf6, 0x05, + 0xec, 0x05, 0x00, 0xe5, 0x24, 0xef, 0xfe, 0xf8, 0x00, 0xd8, 0x18, 0xf1, + 0x26, 0x0b, 0xf2, 0xfc, 0xe0, 0xe4, 0x06, 0x0b, 0x1a, 0x05, 0xc6, 0xf6, + 0xe8, 0xde, 0xfe, 0x0c, 0x03, 0x09, 0xfe, 0xe2, 0x18, 0x1b, 0xfb, 0xf7, + 0x06, 0xf1, 0xfe, 0xf6, 0xef, 0x1b, 0x07, 0x0d, 0x01, 0x0a, 0xed, 0xf0, + 0xad, 0x1a, 0x17, 0xd6, 0x37, 0xfd, 0xd8, 0xec, 0xca, 0xf1, 0x15, 0xc4, + 0x33, 0xf1, 0xed, 0xf0, 0xe9, 0x15, 0x0d, 0xf2, 0x36, 0xde, 0xfd, 0x0e, + 0xfb, 0x10, 0x0f, 0xf6, 0xf9, 0x0c, 0xea, 0xf0, 0xe5, 0x0b, 0xee, 0xc1, + 0x10, 0xf4, 0xe8, 0x1f, 0xee, 0x00, 0xd0, 0xe4, 0xe7, 0x13, 0x07, 0x27, + 0x12, 0xea, 0xea, 0x0f, 0xea, 0xf4, 0x14, 0xee, 0xfe, 0x09, 0xfb, 0x31, + 0xdb, 0x1b, 0x1c, 0xe7, 0xef, 0xf5, 0xf7, 0x1a, 0x06, 0x01, 0x2c, 0xed, + 0xfb, 0x04, 0xfa, 0x07, 0x19, 0xec, 0x2b, 0x0d, 0xfc, 0xd8, 0xfc, 0x0f, + 0x1f, 0xfc, 0x2d, 0xf3, 0xc9, 0xda, 0x0a, 0xfe, 0x29, 0x00, 0xfa, 0x09, + 0xe8, 0xf6, 0x21, 0xf3, 0x4a, 0x1a, 0xf8, 0x00, 0xe7, 0xf0, 0x21, 0x01, + 0x22, 0xf3, 0x00, 0xe9, 0x06, 0xe3, 0x15, 0xd7, 0x3d, 0x0c, 0x07, 0xf1, + 0xf3, 0xec, 0x17, 0xdf, 0x29, 0x1b, 0xfd, 0xfe, 0xeb, 0xed, 0x17, 0xf6, + 0x23, 0x0a, 0xea, 0xee, 0xf9, 0xf3, 0x0f, 0x0c, 0xf8, 0xf5, 0xed, 0xe8, + 0x1c, 0x14, 0x07, 0x17, 0x0b, 0x0d, 0xed, 0xf7, 0xed, 0x10, 0x07, 0xd5, + 0xf2, 0x09, 0xd6, 0xf7, 0xb5, 0xf6, 0x19, 0xc9, 0x25, 0x15, 0xe8, 0xf5, + 0xc4, 0xf9, 0x2a, 0xb0, 0x39, 0x0e, 0x02, 0x11, 0xf0, 0xf7, 0x1d, 0xeb, + 0x39, 0x10, 0x02, 0x15, 0xe0, 0x08, 0x01, 0xee, 0x1c, 0x1e, 0x08, 0x04, + 0xf2, 0x02, 0xe8, 0xda, 0xfa, 0xfb, 0xe0, 0xfe, 0x05, 0x02, 0xd3, 0xca, + 0xf4, 0xec, 0x10, 0x16, 0x05, 0x0d, 0xd7, 0x09, 0xdc, 0xf6, 0x1e, 0xf8, + 0x10, 0xed, 0xf7, 0x27, 0xf5, 0x08, 0x28, 0xee, 0xec, 0xe0, 0xf8, 0x17, + 0xfb, 0x23, 0x2e, 0xf1, 0xfa, 0xf5, 0xfc, 0x1a, 0x10, 0xf7, 0x32, 0xfb, + 0xfb, 0xe8, 0xf1, 0x03, 0x24, 0xeb, 0x25, 0xf9, 0xca, 0xf1, 0xfe, 0x01, + 0x2e, 0x07, 0x18, 0x03, 0xe5, 0xea, 0x10, 0xfa, 0x3b, 0x07, 0x0f, 0x11, + 0x04, 0xf7, 0x1d, 0xf1, 0x24, 0xd9, 0x08, 0xef, 0x02, 0xdd, 0x07, 0xc8, + 0x2c, 0x0d, 0x06, 0xec, 0x17, 0xda, 0x21, 0xdf, 0x34, 0xd9, 0xfb, 0xf2, + 0xf4, 0xec, 0x0e, 0x0a, 0x0f, 0x0f, 0xdb, 0xf0, 0xfb, 0xe6, 0x0f, 0x00, + 0x04, 0xf9, 0x01, 0x05, 0x05, 0xfe, 0x08, 0xf3, 0x0e, 0xf2, 0xfb, 0x01, + 0xfd, 0x18, 0x1d, 0xf6, 0xee, 0x06, 0xcf, 0xfc, 0xae, 0x27, 0x21, 0xd2, + 0x33, 0x03, 0xe0, 0xe0, 0xc9, 0xfb, 0x3a, 0xbd, 0x4d, 0x04, 0xe8, 0xf5, + 0xe6, 0xeb, 0x19, 0xf2, 0x4b, 0x1d, 0xfc, 0xf7, 0xd9, 0xff, 0xfe, 0xea, + 0x0f, 0x04, 0x0e, 0x00, 0xed, 0x19, 0xe9, 0xe9, 0xff, 0x11, 0xef, 0x14, + 0x01, 0x17, 0xbc, 0xb5, 0xef, 0x0c, 0x22, 0x27, 0x0f, 0x01, 0xd4, 0x03, + 0xce, 0x01, 0x25, 0xff, 0xf9, 0xf0, 0x0a, 0x1c, 0xe5, 0x0f, 0x1c, 0xee, + 0xf4, 0xf1, 0xf4, 0x0c, 0x00, 0x08, 0x1c, 0xf4, 0xd5, 0xf1, 0xfc, 0x1f, + 0x11, 0x00, 0x18, 0x03, 0xf7, 0xe4, 0xff, 0x07, 0x09, 0x1a, 0x18, 0xff, + 0xea, 0xec, 0xfd, 0x13, 0x2b, 0xf8, 0x0c, 0xfa, 0xdf, 0xf6, 0x11, 0xda, + 0x2a, 0xdc, 0xfc, 0xff, 0xff, 0xec, 0x12, 0xe1, 0x37, 0xfd, 0xeb, 0xfe, + 0xea, 0xd1, 0x12, 0xfa, 0x28, 0x1a, 0x0d, 0xf0, 0xf7, 0xe0, 0x0c, 0xeb, + 0x35, 0x14, 0xeb, 0x00, 0xeb, 0xe7, 0x1b, 0xfc, 0x09, 0x00, 0xf2, 0x04, + 0xf9, 0xe5, 0x1a, 0x0e, 0x08, 0x12, 0xf8, 0xfe, 0x09, 0x0f, 0x0d, 0xea, + 0x03, 0xe1, 0xfe, 0xf2, 0xec, 0x0d, 0x02, 0xdb, 0x04, 0x1d, 0xd4, 0x01, + 0xca, 0x13, 0x29, 0xca, 0x28, 0x04, 0xe2, 0xf1, 0xdb, 0x0b, 0x2c, 0xcd, + 0x44, 0x00, 0xe7, 0xf4, 0xd0, 0x12, 0x15, 0xff, 0x42, 0x11, 0x05, 0xfd, + 0xd9, 0x11, 0x1c, 0xf4, 0x15, 0xec, 0xf2, 0x24, 0xd6, 0x1d, 0xec, 0xda, + 0xf5, 0xec, 0xe5, 0x22, 0xf2, 0x0b, 0xbd, 0xd0, 0xeb, 0x05, 0x07, 0x1b, + 0x01, 0xed, 0xf5, 0x02, 0xcf, 0x08, 0x15, 0xfd, 0x1c, 0xe5, 0x04, 0x19, + 0xc7, 0x25, 0x22, 0xf3, 0xde, 0xfb, 0xfb, 0x20, 0xf6, 0xeb, 0x25, 0xfe, + 0xf5, 0x08, 0xf5, 0x17, 0x0e, 0x04, 0x1c, 0xf9, 0xee, 0xec, 0xe1, 0x06, + 0x12, 0xff, 0x2a, 0x13, 0xed, 0xfe, 0x05, 0x18, 0x25, 0x20, 0x09, 0x13, + 0xea, 0xd7, 0x05, 0x06, 0x33, 0x25, 0xff, 0x0a, 0xf0, 0xea, 0x17, 0xe1, + 0x30, 0xfa, 0x0d, 0x0a, 0x04, 0x00, 0x0e, 0xe9, 0x16, 0x20, 0x0d, 0x02, + 0xe8, 0xed, 0x07, 0xe8, 0x3c, 0xf1, 0xd9, 0xfa, 0xe1, 0xed, 0x18, 0xfc, + 0xf0, 0x09, 0xe3, 0x05, 0xfe, 0xd1, 0x0b, 0x0e, 0xf5, 0x25, 0xfd, 0xfb, + 0x30, 0x1e, 0x08, 0xfc, 0x0c, 0x21, 0xea, 0xfc, 0xe5, 0x1e, 0x16, 0xf5, + 0xf4, 0xfc, 0xf0, 0xea, 0xc4, 0x21, 0x27, 0xe9, 0x2b, 0xdb, 0xdb, 0xec, + 0xe5, 0xfe, 0x37, 0xe2, 0x46, 0x25, 0xfa, 0xec, 0xe4, 0xf3, 0x19, 0xf2, + 0x4c, 0x06, 0x00, 0xfb, 0xeb, 0x10, 0x10, 0xf7, 0x2a, 0xf8, 0xe9, 0x18, + 0xee, 0x21, 0xe8, 0xd5, 0xf4, 0x0a, 0xed, 0x24, 0xfe, 0xf9, 0xb2, 0xbc, + 0xf3, 0x1d, 0x00, 0x2f, 0x07, 0x08, 0xe1, 0xf1, 0xed, 0x27, 0x27, 0xfe, + 0x22, 0xfd, 0x02, 0x20, 0xd8, 0x05, 0x25, 0xec, 0xf1, 0xff, 0x0a, 0x0f, + 0xe6, 0xfe, 0x46, 0xfd, 0xe1, 0xca, 0xf7, 0x22, 0x03, 0x08, 0x21, 0xf5, + 0x0f, 0xf7, 0xfb, 0x0c, 0xfb, 0x14, 0x2d, 0x03, 0xe5, 0xe4, 0x09, 0x0b, + 0x1a, 0xe6, 0x01, 0x28, 0xe9, 0xd6, 0x0b, 0xf7, 0x2c, 0xfb, 0x11, 0xee, + 0x0b, 0xed, 0x17, 0xf0, 0x3c, 0xf5, 0x08, 0xfa, 0xf8, 0xcd, 0x17, 0xfa, + 0x39, 0xea, 0x11, 0xf5, 0xed, 0xee, 0x0a, 0xec, 0x41, 0xd6, 0xe7, 0xf9, + 0xfa, 0xc8, 0x15, 0xf7, 0x08, 0x0e, 0xe3, 0x08, 0xe8, 0xec, 0xfd, 0xfe, + 0xf1, 0x00, 0xe9, 0xf4, 0x09, 0x26, 0x02, 0x16, 0xf0, 0x01, 0xef, 0x01, + 0xff, 0x03, 0x22, 0xdb, 0xfc, 0xf5, 0xde, 0xe5, 0xc4, 0x01, 0x28, 0xd4, + 0x38, 0x08, 0xd0, 0xec, 0xd5, 0x04, 0x2f, 0xce, 0x4e, 0xeb, 0xf9, 0xe7, + 0xdf, 0xf0, 0x1b, 0xf5, 0x42, 0xf1, 0xf6, 0x09, 0xd5, 0x0a, 0x0d, 0x08, + 0x04, 0x05, 0xe2, 0x0e, 0xd7, 0x19, 0xdb, 0xda, 0xe1, 0x25, 0xde, 0x15, + 0x0e, 0x14, 0xbd, 0xb0, 0xe3, 0xe5, 0x24, 0x1e, 0xf8, 0x0d, 0xd8, 0xf7, + 0xf2, 0xff, 0x18, 0xf5, 0x07, 0xf0, 0x02, 0x25, 0xd5, 0x1e, 0x2e, 0xdf, + 0xe7, 0x05, 0xef, 0x11, 0xe8, 0xe7, 0x47, 0xf4, 0xe1, 0xde, 0x09, 0x36, + 0x1a, 0x11, 0x11, 0xf5, 0x12, 0xe5, 0xe7, 0x18, 0x01, 0x17, 0x2a, 0x03, + 0x05, 0xea, 0x09, 0x0b, 0x12, 0x04, 0x17, 0xf0, 0xee, 0xd7, 0x11, 0xed, + 0x3c, 0x17, 0x16, 0xff, 0x02, 0xdc, 0x21, 0xf3, 0x2e, 0xe5, 0x13, 0xef, + 0xec, 0xe2, 0x10, 0xd0, 0x2e, 0xee, 0xff, 0x01, 0xe0, 0xe5, 0x0b, 0xda, + 0x1f, 0xf8, 0xf6, 0xfb, 0x07, 0xdb, 0x05, 0xf6, 0x0c, 0xf3, 0xf0, 0x10, + 0xf9, 0xf5, 0xf2, 0x0d, 0x10, 0xf7, 0xf6, 0xff, 0x2b, 0x0d, 0x06, 0x1e, + 0xf3, 0x0c, 0xe9, 0x01, 0xf2, 0x23, 0xfe, 0xe9, 0xdd, 0x12, 0xdd, 0xf7, + 0xbb, 0x22, 0x1b, 0xd4, 0x38, 0x29, 0xd4, 0xcf, 0xf5, 0xf9, 0x27, 0xdd, + 0x47, 0x00, 0xf2, 0xe5, 0x09, 0xfc, 0x0e, 0xf9, 0x34, 0x0a, 0x02, 0xfd, + 0xec, 0x25, 0x1d, 0x03, 0x15, 0x09, 0xf1, 0x1b, 0xd0, 0x17, 0xda, 0xda, + 0xe7, 0x07, 0xe3, 0x15, 0xf1, 0x02, 0xb9, 0xce, 0xe6, 0x0c, 0x10, 0x31, + 0xfe, 0xf7, 0xd9, 0xfa, 0xed, 0xed, 0x33, 0xf4, 0x19, 0xe7, 0xfe, 0x3f, + 0xe5, 0x06, 0x2e, 0xe6, 0xf2, 0xdc, 0xf5, 0x18, 0xe6, 0x01, 0x2f, 0xee, + 0xe7, 0xe4, 0xfe, 0x2c, 0x03, 0xf7, 0x20, 0x05, 0x07, 0xe2, 0x06, 0x1e, + 0x05, 0xed, 0x2f, 0x03, 0xea, 0xf8, 0x0e, 0x0c, 0x1f, 0xff, 0x20, 0xf4, + 0xe8, 0xe1, 0x1c, 0xec, 0x22, 0x1e, 0x05, 0xfd, 0xf5, 0xca, 0x30, 0xe9, + 0x30, 0xe4, 0x14, 0xff, 0xf2, 0xdc, 0x17, 0xf8, 0x26, 0xe1, 0x0b, 0x01, + 0x11, 0xc2, 0x02, 0xf1, 0x36, 0x10, 0x02, 0x05, 0xed, 0xf1, 0x15, 0xfa, + 0x17, 0xf8, 0xf7, 0xf1, 0xe8, 0xd3, 0xfd, 0x08, 0xfb, 0x27, 0xf5, 0xf5, + 0x13, 0x06, 0x0b, 0xf0, 0x01, 0xf9, 0xd7, 0x0e, 0xec, 0x12, 0xfe, 0xfd, + 0xee, 0x25, 0xd8, 0xf1, 0xb2, 0x09, 0x1c, 0xbf, 0x34, 0xea, 0xc8, 0xea, + 0xdb, 0x0e, 0x24, 0xde, 0x47, 0xfe, 0xdc, 0xe0, 0xf3, 0x06, 0x20, 0xfe, + 0x2b, 0xf6, 0x18, 0x14, 0xcd, 0x19, 0x16, 0xfe, 0x1a, 0x15, 0xf8, 0x11, + 0xf4, 0x22, 0xd7, 0xcc, 0xdd, 0x15, 0xdc, 0x14, 0xf9, 0x02, 0xbb, 0xca, + 0xe3, 0xf3, 0x0d, 0x1e, 0x2a, 0x0c, 0xe4, 0x05, 0xe0, 0x18, 0x2a, 0x07, + 0x20, 0xed, 0xf6, 0x17, 0xcf, 0xf4, 0x2a, 0xd6, 0xfb, 0xce, 0x03, 0x37, + 0xe2, 0xfd, 0x1d, 0xfb, 0xe5, 0xe0, 0x05, 0x29, 0xef, 0x16, 0x23, 0xf7, + 0x01, 0xf4, 0x0c, 0x14, 0xff, 0xee, 0x31, 0xf9, 0x12, 0xf9, 0x14, 0xf6, + 0x0c, 0xf6, 0x0b, 0x0f, 0xd8, 0xdc, 0xfe, 0x0f, 0x37, 0xfa, 0x01, 0x09, + 0x04, 0xd1, 0x0b, 0x0c, 0x29, 0xf3, 0x0a, 0xf9, 0xed, 0xc2, 0x18, 0xf4, + 0x25, 0x18, 0x0f, 0x08, 0xf7, 0xed, 0x1f, 0xf7, 0x4f, 0x0e, 0xf0, 0xe4, + 0x00, 0xeb, 0xfa, 0x1a, 0x0c, 0x03, 0xe9, 0xfc, 0xf0, 0xcc, 0x06, 0x05, + 0xf2, 0x12, 0x04, 0xe2, 0x16, 0x0a, 0x0a, 0xf3, 0x0b, 0xf3, 0xdc, 0xfd, + 0x10, 0xfc, 0x0e, 0xe2, 0xe0, 0xfe, 0xf0, 0xff, 0xb1, 0x06, 0x1b, 0xe4, + 0x30, 0x13, 0xc6, 0xc3, 0xfa, 0x0c, 0x1e, 0xd9, 0x57, 0x11, 0xe1, 0xd6, + 0xfa, 0xee, 0x1d, 0xf7, 0x37, 0xea, 0xf0, 0x05, 0xef, 0x24, 0x1e, 0xf1, + 0x10, 0xe8, 0xeb, 0x19, 0xd1, 0x18, 0xf5, 0xc8, 0xf8, 0xec, 0xf5, 0x1f, + 0xf2, 0xff, 0xb3, 0xd2, 0xe6, 0x0e, 0x06, 0x2e, 0x07, 0x17, 0xe0, 0xf5, + 0x02, 0xf9, 0x20, 0x07, 0x16, 0x08, 0xe8, 0x1d, 0xd3, 0x08, 0x34, 0xda, + 0xf2, 0xce, 0xfb, 0x1f, 0xe1, 0x00, 0x2d, 0xdb, 0xdf, 0xcc, 0x05, 0xfb, + 0xf7, 0x00, 0x33, 0xf9, 0x0b, 0x01, 0x13, 0x28, 0xf8, 0x07, 0x24, 0xf8, + 0x0f, 0x03, 0x0d, 0xe9, 0x06, 0xfe, 0x18, 0xf9, 0xed, 0xf5, 0x0c, 0xe0, + 0x2c, 0x0e, 0xf9, 0x06, 0xfb, 0xce, 0x27, 0xe8, 0x29, 0x19, 0xf9, 0x01, + 0x0e, 0xc8, 0x25, 0xed, 0x30, 0xeb, 0x01, 0xfe, 0x10, 0xdc, 0x1e, 0x00, + 0x1e, 0x10, 0xf9, 0x00, 0xfc, 0xc8, 0x0e, 0x04, 0x13, 0x04, 0xf0, 0x02, + 0xfe, 0xd8, 0x0f, 0x1b, 0xf7, 0xe1, 0xf8, 0xde, 0x12, 0xe2, 0xef, 0x0a, + 0x02, 0xe0, 0xdd, 0xf1, 0x0e, 0x2a, 0x25, 0x15, 0xeb, 0x02, 0xf4, 0xf0, + 0xbf, 0xfc, 0x27, 0xdc, 0x42, 0x0f, 0xe9, 0xbf, 0xe8, 0x20, 0x33, 0xc9, + 0x3f, 0x10, 0xec, 0xf3, 0x03, 0x02, 0x2c, 0x04, 0x38, 0x06, 0x0a, 0xf9, + 0xe5, 0x1c, 0x3f, 0x0f, 0x0c, 0x25, 0xe2, 0x06, 0xe6, 0x03, 0xf4, 0xd7, + 0xfe, 0xf6, 0xe7, 0x2f, 0xfa, 0x03, 0xb6, 0xcb, 0xf1, 0x11, 0x0a, 0x2c, + 0xfc, 0x1e, 0xe0, 0xff, 0xc2, 0xdd, 0x1d, 0xf3, 0x10, 0xfa, 0x07, 0x1e, + 0xf6, 0x20, 0x07, 0xe6, 0xf1, 0x0a, 0xe8, 0x27, 0xf1, 0xf5, 0x24, 0xed, + 0xfd, 0xee, 0x13, 0x15, 0xe9, 0xe2, 0x22, 0xe5, 0xf9, 0xdd, 0x1d, 0x32, + 0x04, 0xfa, 0x25, 0x00, 0xee, 0xfd, 0x0b, 0x0e, 0x23, 0xfa, 0x0f, 0x01, + 0xf8, 0xf0, 0x15, 0xe4, 0x21, 0xf7, 0x10, 0xf9, 0xe7, 0xc3, 0x19, 0xe1, + 0x34, 0xff, 0xed, 0xf4, 0xef, 0xd7, 0x21, 0x01, 0x31, 0xee, 0xf7, 0xf2, + 0xf3, 0xe5, 0x0a, 0xee, 0x2e, 0x1e, 0xf2, 0x0c, 0x07, 0xc2, 0x08, 0x0a, + 0x14, 0x14, 0x00, 0xfc, 0xf9, 0xd6, 0xfb, 0xf8, 0xe5, 0xf1, 0xfa, 0xe0, + 0x15, 0x21, 0xef, 0x06, 0xf9, 0x00, 0xf5, 0xf4, 0x0b, 0x0b, 0x18, 0x02, + 0xf5, 0x04, 0xdb, 0xfd, 0xcc, 0x32, 0x1d, 0xc9, 0x3b, 0x12, 0xd9, 0xaf, + 0xcf, 0x0f, 0x26, 0xde, 0x35, 0xe4, 0xdb, 0xd3, 0x22, 0x11, 0x2e, 0xfb, + 0x36, 0xfa, 0xfd, 0x02, 0xeb, 0x0f, 0x37, 0x0b, 0x14, 0x1d, 0xdd, 0x18, + 0xe0, 0x10, 0xe0, 0xdf, 0x14, 0xf9, 0xf0, 0x19, 0xf7, 0xfb, 0xc4, 0xe5, + 0xe7, 0x11, 0x01, 0x31, 0x1a, 0xf7, 0xd8, 0xf1, 0xe9, 0xf3, 0x21, 0xf9, + 0xfe, 0xe4, 0xe9, 0x02, 0xd0, 0x06, 0x14, 0xd7, 0xfc, 0xec, 0x06, 0x10, + 0xfc, 0xf0, 0x1c, 0xe7, 0xec, 0xe3, 0x03, 0x21, 0xe4, 0x04, 0x12, 0xf0, + 0xf3, 0xed, 0x16, 0x36, 0x02, 0xfd, 0x13, 0x11, 0xdf, 0xeb, 0x19, 0x07, + 0x10, 0x0c, 0xf9, 0x08, 0xf8, 0xf4, 0x1d, 0xfd, 0x1d, 0x16, 0xf4, 0x0a, + 0x08, 0xec, 0x0c, 0x09, 0x3d, 0xe0, 0x0b, 0xee, 0x10, 0xd1, 0x1e, 0x15, + 0x43, 0xeb, 0xfa, 0xf3, 0x05, 0xc7, 0xf2, 0xd9, 0x25, 0x20, 0xee, 0xe9, + 0xfd, 0xce, 0x16, 0x0c, 0x27, 0x06, 0x0a, 0x06, 0xf9, 0xd6, 0x0b, 0x05, + 0xe8, 0x02, 0xe8, 0xd2, 0x10, 0x01, 0xf2, 0x15, 0x09, 0x04, 0xd3, 0xe2, + 0xfe, 0xf0, 0x32, 0x1b, 0xd9, 0xf5, 0xea, 0xcc, 0xcb, 0x10, 0x1c, 0xf1, + 0x3b, 0x02, 0xd4, 0xbf, 0xca, 0xfe, 0x12, 0xdb, 0x3b, 0xf8, 0xd5, 0xe7, + 0x13, 0x10, 0x1a, 0xf4, 0x38, 0x09, 0x08, 0xee, 0xf4, 0xf4, 0x3c, 0xf7, + 0x15, 0x04, 0xe4, 0xfa, 0xf4, 0x04, 0xee, 0xf4, 0x07, 0xf8, 0xe9, 0x3b, + 0xe2, 0x1f, 0xd5, 0xed, 0xe6, 0xfd, 0x18, 0x49, 0x21, 0x06, 0xd8, 0xde, + 0xfa, 0xf0, 0x1b, 0xfe, 0xde, 0x08, 0xf7, 0x14, 0xc7, 0x0f, 0x1d, 0xcf, + 0x00, 0xea, 0xff, 0x1b, 0xd5, 0x08, 0x0d, 0xd9, 0xf1, 0xf4, 0x16, 0x23, + 0xd8, 0x0c, 0x29, 0xdc, 0xf1, 0xf2, 0x21, 0x49, 0xfc, 0xe2, 0x08, 0x01, + 0xf0, 0xf8, 0x17, 0xf9, 0x0f, 0xf5, 0xfa, 0x1a, 0xef, 0xec, 0x09, 0xeb, + 0x1a, 0x0c, 0x17, 0x09, 0x11, 0xe9, 0x1a, 0xf7, 0x29, 0xf9, 0xfd, 0x07, + 0x01, 0xdd, 0x0a, 0xec, 0x22, 0x15, 0x03, 0xfd, 0xe2, 0xd2, 0x15, 0xec, + 0x4d, 0xd7, 0xfc, 0xf6, 0x0b, 0xcc, 0x0e, 0x04, 0x03, 0xf7, 0xfb, 0xfb, + 0x0d, 0xeb, 0x19, 0x07, 0xf4, 0xf4, 0xe5, 0xde, 0x22, 0x07, 0xea, 0xf7, + 0xeb, 0x23, 0xc8, 0xee, 0x03, 0x04, 0x0f, 0x19, 0xc3, 0xf8, 0x06, 0xd0, + 0xf7, 0xfe, 0x0e, 0xe7, 0x0a, 0x02, 0xb0, 0xb8, 0x00, 0xfb, 0x18, 0x0f, + 0x22, 0xf7, 0xe9, 0xdc, 0x09, 0x15, 0x23, 0x0d, 0x22, 0x13, 0xe2, 0xed, + 0xeb, 0x18, 0x20, 0x0b, 0x12, 0xfc, 0x02, 0xf1, 0xdb, 0x0e, 0xe1, 0x04, + 0xdb, 0x0f, 0xf3, 0x1a, 0x06, 0xef, 0xdb, 0xdc, 0xdd, 0xfb, 0x00, 0x2a, + 0x20, 0xfd, 0xc1, 0xe3, 0xef, 0x01, 0x14, 0xf2, 0x14, 0x00, 0x0f, 0x28, + 0xd9, 0xff, 0xf4, 0xdc, 0x09, 0xfa, 0x1c, 0x08, 0xd1, 0x03, 0x0a, 0xf4, + 0xe4, 0xdb, 0x20, 0x30, 0xea, 0x06, 0x11, 0xe2, 0x26, 0xf7, 0x16, 0x22, + 0xf9, 0x07, 0x02, 0xf5, 0xf6, 0xfb, 0x1d, 0x0c, 0x16, 0x0a, 0x07, 0xf9, + 0x11, 0xde, 0x20, 0x08, 0x19, 0x04, 0x0a, 0x0b, 0x0c, 0xf7, 0xf4, 0xfc, + 0x41, 0xf1, 0xf8, 0x16, 0x09, 0xdc, 0x0e, 0x1a, 0x2b, 0x1f, 0xe7, 0xfe, + 0x01, 0xe0, 0xfd, 0xe2, 0x34, 0xec, 0xf3, 0xf5, 0x03, 0xec, 0x0b, 0xfb, + 0x04, 0xf6, 0xdd, 0xfd, 0x06, 0x14, 0x0d, 0xfa, 0xfc, 0xf1, 0x0a, 0xca, + 0x01, 0xec, 0x0e, 0x0e, 0xec, 0xd7, 0xee, 0xd4, 0xf2, 0xfe, 0x16, 0xfa, + 0xbd, 0x0d, 0xef, 0xcb, 0xc4, 0xee, 0xed, 0x13, 0x10, 0x19, 0xf8, 0xb1, + 0xf1, 0xe3, 0x00, 0xf3, 0x0c, 0xf6, 0xde, 0xc6, 0x15, 0x27, 0x14, 0x29, + 0x15, 0xf6, 0xf4, 0xf5, 0xe7, 0x00, 0x0b, 0x2f, 0x0c, 0xef, 0x03, 0x0f, + 0xfd, 0x08, 0xf3, 0xf9, 0xf9, 0x05, 0x0d, 0x34, 0x15, 0x1b, 0xc8, 0xd1, + 0xf2, 0x1b, 0x0a, 0x22, 0x12, 0x11, 0xe9, 0xf4, 0xe1, 0x2a, 0x20, 0x03, + 0xf2, 0xf8, 0x14, 0x0b, 0xd0, 0xf4, 0x0e, 0xbf, 0xc6, 0xd8, 0x04, 0x05, + 0xf8, 0xf4, 0x04, 0xc9, 0xea, 0xfd, 0xf7, 0xfa, 0xe3, 0x1b, 0x11, 0xde, + 0x0c, 0x11, 0x25, 0x29, 0xe5, 0x02, 0xef, 0xef, 0x02, 0xfa, 0x1a, 0x21, + 0x19, 0x09, 0x08, 0x05, 0x04, 0xe5, 0xfa, 0xed, 0x2d, 0x26, 0xfa, 0x17, + 0xf6, 0xe8, 0x12, 0x12, 0x31, 0xfc, 0x0d, 0x00, 0xf7, 0xeb, 0x19, 0xf1, + 0x2a, 0x06, 0x14, 0xec, 0x08, 0xd3, 0x21, 0x07, 0x32, 0xe3, 0x02, 0x0b, + 0xfb, 0xd8, 0x27, 0x07, 0x05, 0xe6, 0xf5, 0xf5, 0x0a, 0xf7, 0x2c, 0x2a, + 0xd8, 0x1b, 0xda, 0xf7, 0xea, 0xf6, 0xf9, 0x0e, 0xf8, 0x0c, 0x05, 0xc7, + 0xd6, 0x06, 0x12, 0xe3, 0xe1, 0xe1, 0xd8, 0xdb, 0xc6, 0xf8, 0xe6, 0xfa, + 0x0c, 0x07, 0xf8, 0xe7, 0xe1, 0x0f, 0x00, 0xf3, 0x03, 0xf0, 0xde, 0xcc, + 0xf5, 0xfc, 0xef, 0x1e, 0x16, 0x13, 0xfb, 0xf4, 0x03, 0xe9, 0xfc, 0xfa, + 0x15, 0xe8, 0x15, 0x09, 0xf1, 0x0d, 0xdb, 0x0a, 0xe8, 0x09, 0xf5, 0x1a, + 0x04, 0xf8, 0xd8, 0xd4, 0x04, 0xee, 0x25, 0x29, 0x09, 0xfe, 0xf3, 0xf5, + 0xd4, 0x0a, 0x15, 0x19, 0xf5, 0x12, 0xfe, 0x04, 0xe7, 0x01, 0xeb, 0xde, + 0xbe, 0xfe, 0x09, 0x12, 0xdf, 0x13, 0xe0, 0xef, 0xc7, 0xff, 0x03, 0x08, + 0xfe, 0xf2, 0x19, 0xe0, 0xe4, 0x0c, 0x22, 0x1e, 0x05, 0xf7, 0x16, 0xf2, + 0xf9, 0x06, 0x17, 0xf6, 0x0c, 0x1e, 0x23, 0x08, 0xfe, 0xdc, 0xfd, 0x17, + 0x11, 0xdf, 0xf5, 0x0f, 0x01, 0x03, 0x08, 0xee, 0x1b, 0x02, 0x0b, 0x1b, + 0x0c, 0x16, 0x1a, 0x00, 0x0f, 0x26, 0x14, 0xf8, 0xf4, 0xf3, 0x19, 0x16, + 0x22, 0x0a, 0xd0, 0xf9, 0xf1, 0x05, 0x2b, 0x1e, 0x1e, 0xef, 0xf5, 0x06, + 0x05, 0xe7, 0x3f, 0x2a, 0x06, 0xf0, 0x15, 0x14, 0x13, 0x20, 0x1b, 0xde, + 0x10, 0x05, 0x33, 0xf8, 0x08, 0x04, 0x17, 0x0d, 0x0f, 0xf6, 0x01, 0xed, + 0x28, 0x25, 0x1c, 0x13, 0xfb, 0xea, 0xfb, 0xf3, 0x1c, 0xf9, 0x1f, 0xf0, + 0xfb, 0x17, 0xf8, 0xff, 0x10, 0xf7, 0x0b, 0x24, 0x04, 0x00, 0x0d, 0x0c, + 0xf7, 0x0a, 0x16, 0x13, 0xf8, 0x05, 0x0a, 0xf1, 0xf5, 0xee, 0xf8, 0x14, + 0x0e, 0xed, 0xfe, 0x1b, 0xfe, 0x17, 0x13, 0x10, 0x12, 0x21, 0x1c, 0xfa, + 0xe5, 0x0b, 0x08, 0x0c, 0x10, 0x1b, 0x03, 0xef, 0x0d, 0x05, 0x0a, 0xf0, + 0x04, 0x11, 0x15, 0x00, 0xfd, 0xef, 0x02, 0x18, 0xf4, 0x09, 0xfa, 0xf6, + 0x02, 0xf7, 0xfd, 0x13, 0xef, 0x13, 0xf7, 0xf9, 0x17, 0x0f, 0xfa, 0xf8, + 0x15, 0xff, 0x04, 0xef, 0xf0, 0x15, 0xfa, 0xfe, 0xf0, 0xf4, 0xed, 0x06, + 0x1c, 0x02, 0xfb, 0xf7, 0x05, 0xfb, 0x0c, 0xef, 0xf4, 0xf0, 0xf6, 0xec, + 0x17, 0xf3, 0xf5, 0xef, 0x02, 0xfd, 0xe5, 0x21, 0x0c, 0xf1, 0x1e, 0x08, + 0xf1, 0x0b, 0xf7, 0x09, 0x1d, 0xf2, 0xf9, 0xf2, 0xfb, 0x0e, 0xed, 0xf8, + 0xfa, 0xdd, 0xf0, 0xfd, 0xdb, 0x1a, 0xf4, 0xef, 0x0c, 0x06, 0x0f, 0xdf, + 0xe2, 0x06, 0x06, 0xee, 0xfa, 0x0d, 0x17, 0xfc, 0xf9, 0x15, 0x1a, 0xe4, + 0xfb, 0x0c, 0x1a, 0xfc, 0x1b, 0x04, 0x07, 0x20, 0xff, 0x09, 0x0f, 0xf2, + 0x26, 0x19, 0x1f, 0x0d, 0x02, 0x16, 0x03, 0x03, 0xfd, 0x05, 0x01, 0x1b, + 0x0a, 0x11, 0xfa, 0x21, 0x13, 0xfb, 0x0c, 0x05, 0xf3, 0xdd, 0xe4, 0xdc, + 0x22, 0x1b, 0x15, 0x14, 0x0e, 0xe8, 0x00, 0xf7, 0xf8, 0xf4, 0x0b, 0x0b, + 0xfd, 0x21, 0xe3, 0x0f, 0xe1, 0x22, 0x01, 0x21, 0x0b, 0x1f, 0x09, 0x10, + 0xe2, 0x18, 0x11, 0x0e, 0xed, 0x01, 0x14, 0x12, 0xfd, 0x11, 0xf6, 0xe9, + 0x20, 0xe1, 0xf5, 0x1b, 0x27, 0x22, 0xfa, 0xf7, 0xfe, 0x13, 0xf6, 0xdc, + 0x06, 0x0d, 0xf4, 0x05, 0x20, 0x0d, 0x0b, 0xe4, 0x15, 0x28, 0x0c, 0x00, + 0xf5, 0x07, 0x0c, 0x0a, 0x06, 0x0e, 0xf3, 0xfb, 0xfe, 0x04, 0x08, 0xf4, + 0xef, 0x03, 0xe4, 0xeb, 0x06, 0xee, 0xed, 0xdb, 0xeb, 0x1d, 0xf4, 0xfa, + 0x0c, 0xfc, 0xfe, 0x11, 0xf7, 0xf8, 0xf5, 0xef, 0xe7, 0xfc, 0x1b, 0xdc, + 0x17, 0xfd, 0xfe, 0x00, 0xea, 0xf4, 0xf1, 0xf7, 0x0f, 0x21, 0x04, 0xfd, + 0x0d, 0x0c, 0x0a, 0x14, 0xfd, 0x19, 0x09, 0x01, 0xfd, 0xe2, 0x0c, 0x0c, + 0xe0, 0x25, 0xfb, 0xff, 0x0d, 0x18, 0xf6, 0x0b, 0x19, 0x12, 0x10, 0x09, + 0x0b, 0x06, 0x12, 0x1c, 0x10, 0x03, 0x13, 0x0a, 0x05, 0x0f, 0x09, 0x01, + 0x21, 0xe4, 0x01, 0x26, 0xf9, 0xf4, 0x05, 0x19, 0x00, 0xff, 0x0b, 0xff, + 0x16, 0x09, 0xe7, 0xee, 0xed, 0xf5, 0x0f, 0x2f, 0xee, 0x19, 0x03, 0x0a, + 0x10, 0xee, 0xf7, 0x2e, 0xf4, 0x08, 0xf7, 0xee, 0x07, 0x00, 0xfc, 0x0e, + 0xf0, 0x12, 0x08, 0x05, 0xed, 0x11, 0xfc, 0xfb, 0xf7, 0x25, 0xf1, 0x05, + 0x0c, 0xf9, 0xfa, 0x03, 0x0c, 0x16, 0x04, 0x25, 0xf8, 0xe7, 0xfc, 0x11, + 0x0d, 0x19, 0xd8, 0xfa, 0x0b, 0x06, 0xfd, 0xef, 0x13, 0xf6, 0xff, 0x0e, + 0xf9, 0x04, 0xf1, 0xdc, 0xfb, 0xe1, 0xf6, 0x0b, 0x15, 0x07, 0xf7, 0x02, + 0x0e, 0xf1, 0xfd, 0xe3, 0xeb, 0x07, 0xf1, 0xef, 0x03, 0xfe, 0xf8, 0x07, + 0x10, 0xf7, 0x00, 0xf9, 0xf2, 0x0e, 0xf9, 0xf2, 0x1d, 0xf5, 0xd8, 0xff, + 0xe6, 0x18, 0x2a, 0x1b, 0x03, 0x16, 0xfe, 0xf4, 0xf5, 0xfd, 0x04, 0x01, + 0xfe, 0xfe, 0x07, 0xfc, 0x0e, 0xfa, 0x15, 0xeb, 0x02, 0x15, 0xea, 0xfd, + 0x04, 0xe5, 0xfe, 0xed, 0xfe, 0x1a, 0x09, 0x2a, 0x1b, 0xdf, 0xfb, 0xf8, + 0xf1, 0x04, 0x1a, 0x34, 0x07, 0xf9, 0x0d, 0xf5, 0xef, 0xec, 0x10, 0x1a, + 0x0b, 0x0f, 0x13, 0xfe, 0x10, 0x22, 0x1e, 0x02, 0xe6, 0xf7, 0x11, 0xfa, + 0x11, 0xfc, 0x1b, 0x21, 0x12, 0xf4, 0x18, 0x16, 0x29, 0xe4, 0x0c, 0x2e, + 0x12, 0x07, 0x20, 0xf6, 0x1d, 0xf4, 0x12, 0x33, 0xf4, 0xee, 0xfe, 0x05, + 0x06, 0xfb, 0x13, 0x0c, 0x0e, 0xf0, 0x00, 0xf8, 0xee, 0xf3, 0x17, 0x00, + 0xf7, 0xfb, 0xfc, 0x0f, 0xf4, 0xd5, 0x0a, 0xed, 0xeb, 0xf5, 0xe9, 0xef, + 0xd8, 0xf0, 0xf8, 0xe2, 0x19, 0xf7, 0xf8, 0x0a, 0x0b, 0x09, 0xfa, 0xe7, + 0x0f, 0xfc, 0xe8, 0x02, 0x00, 0x1a, 0xfe, 0xfd, 0x1b, 0xe6, 0xef, 0x0f, + 0xe3, 0x10, 0xf1, 0xe2, 0x0b, 0x0e, 0x06, 0x29, 0x00, 0x01, 0xf3, 0x00, + 0x11, 0x04, 0xf2, 0xf7, 0xea, 0xf8, 0xe0, 0x09, 0x0e, 0x13, 0xf4, 0x00, + 0x09, 0xfa, 0xf5, 0x0c, 0xff, 0x18, 0x08, 0x0d, 0xfa, 0xde, 0xfa, 0x03, + 0xf2, 0xf3, 0x1b, 0xeb, 0x06, 0xea, 0xfb, 0xff, 0x0d, 0xf5, 0x10, 0x17, + 0xf8, 0xe8, 0xf1, 0xf1, 0xf5, 0x00, 0x03, 0x0a, 0x09, 0x0a, 0xf3, 0xfb, + 0x33, 0x26, 0xe7, 0x17, 0xe3, 0xfa, 0x1f, 0x24, 0xfc, 0x07, 0x02, 0xe2, + 0xeb, 0x08, 0x2c, 0xf8, 0x02, 0x1f, 0x04, 0xeb, 0x0b, 0x04, 0x17, 0xf7, + 0xff, 0x1c, 0xed, 0x00, 0x3f, 0xd5, 0x17, 0x1d, 0xfe, 0x03, 0xf1, 0x1c, + 0x17, 0xec, 0x0e, 0x54, 0xee, 0xf5, 0x25, 0xfa, 0x08, 0xee, 0x13, 0x32, + 0x0e, 0xd8, 0x09, 0x0f, 0xee, 0xe5, 0x06, 0x10, 0xf4, 0xfb, 0xe4, 0xfb, + 0x09, 0xde, 0x13, 0xff, 0x02, 0xf9, 0xec, 0x0a, 0x00, 0xe9, 0xfd, 0xdc, + 0x06, 0x04, 0xdb, 0x06, 0x01, 0xf8, 0x09, 0xe2, 0x0c, 0x14, 0xda, 0xfe, + 0x20, 0xe3, 0x09, 0xda, 0x14, 0x12, 0xe1, 0x05, 0xff, 0xf3, 0x00, 0x08, + 0xfb, 0xf1, 0xfd, 0xf3, 0x04, 0xfa, 0x08, 0xff, 0x01, 0x1d, 0x0b, 0xfd, + 0x0a, 0xf4, 0xfb, 0xfc, 0xf9, 0x19, 0xed, 0xfc, 0xf2, 0x06, 0xe7, 0x02, + 0xf6, 0x0c, 0xfc, 0xfb, 0x01, 0x0c, 0xeb, 0x1b, 0xff, 0xff, 0x08, 0x1d, + 0xf7, 0xe8, 0xfc, 0xf4, 0x0c, 0xfa, 0xf1, 0xee, 0xed, 0xdd, 0xfc, 0x06, + 0x05, 0xdc, 0x1a, 0xfc, 0xf9, 0x07, 0xdf, 0x1b, 0x14, 0x0c, 0xfc, 0x01, + 0x16, 0xe1, 0xed, 0x09, 0x34, 0xee, 0xe4, 0x1c, 0x1b, 0xfc, 0x3b, 0x03, + 0x15, 0xf2, 0xeb, 0x14, 0x00, 0xdd, 0x24, 0x04, 0xf1, 0xed, 0xfd, 0xe6, + 0x32, 0xf9, 0x24, 0x04, 0x0e, 0x22, 0x03, 0x14, 0x2f, 0xf5, 0x1a, 0x37, + 0xf4, 0x18, 0x03, 0x0f, 0x4b, 0xe6, 0x0d, 0x5c, 0xf7, 0x1f, 0x1c, 0xe6, + 0x23, 0x0c, 0x15, 0x4e, 0xe0, 0x05, 0x1c, 0xec, 0xff, 0x04, 0x13, 0x15, + 0xee, 0x07, 0xec, 0x0c, 0xdd, 0xf8, 0x0e, 0x03, 0x0c, 0x1f, 0xe8, 0x0e, + 0xf5, 0xec, 0xfc, 0xe2, 0xe8, 0xfb, 0xf6, 0x00, 0xe5, 0xea, 0xf3, 0xd3, + 0xf5, 0xfd, 0xd2, 0xfd, 0x1b, 0xed, 0x09, 0xd1, 0x23, 0xfa, 0xd4, 0xf7, + 0xe9, 0xf0, 0x0a, 0xd6, 0x14, 0x03, 0xe6, 0x10, 0xf4, 0x18, 0xfe, 0xe1, + 0x0b, 0x25, 0xf5, 0xfc, 0xe9, 0xf2, 0xe9, 0xf4, 0x0d, 0xf5, 0x00, 0xf9, + 0x17, 0x02, 0xfd, 0x03, 0x04, 0xf8, 0xf5, 0x14, 0xe3, 0xd3, 0xeb, 0xe7, + 0x09, 0xf3, 0x14, 0x17, 0xee, 0xe6, 0xf6, 0xff, 0x11, 0x26, 0xf4, 0xf7, + 0x02, 0xfa, 0x05, 0x08, 0x16, 0xff, 0x0d, 0xf7, 0xf1, 0xf7, 0xe6, 0xfb, + 0x04, 0x04, 0x07, 0x02, 0x04, 0x09, 0xf5, 0xfc, 0x5f, 0xd6, 0xe7, 0x2a, + 0x23, 0xf4, 0x1b, 0x06, 0x01, 0xea, 0xe7, 0x05, 0x25, 0xe3, 0x25, 0x07, + 0xea, 0xfb, 0xfb, 0x09, 0x25, 0xde, 0x37, 0x04, 0x07, 0xe5, 0xff, 0x14, + 0x2f, 0x0a, 0x30, 0x23, 0x04, 0xf0, 0x23, 0xfe, 0x1c, 0xd2, 0x2b, 0x55, + 0x01, 0xe5, 0x26, 0xfe, 0x14, 0xed, 0x24, 0x46, 0xe6, 0xee, 0x0f, 0xfd, + 0xed, 0xef, 0x0e, 0x1e, 0x05, 0x0a, 0x12, 0xff, 0xe4, 0xf5, 0x0c, 0xed, + 0xfd, 0xea, 0x0d, 0x13, 0x1a, 0xe5, 0xfc, 0xc2, 0xef, 0x0a, 0xe2, 0x0f, + 0xfe, 0xff, 0x0c, 0xf0, 0xff, 0xdf, 0xea, 0x00, 0xf6, 0xe1, 0x04, 0xd8, + 0x26, 0x20, 0xdc, 0xf4, 0x19, 0x06, 0xe8, 0xd2, 0x10, 0x04, 0xf1, 0x02, + 0x0c, 0x06, 0xf0, 0xf0, 0x04, 0x1f, 0xf4, 0xf5, 0xed, 0xf1, 0xfa, 0xf1, + 0x04, 0x02, 0xf8, 0xfb, 0x04, 0xf1, 0xe5, 0xe4, 0x0a, 0xf0, 0xfe, 0xef, + 0x1c, 0xe3, 0xeb, 0xf3, 0x00, 0x17, 0x01, 0x13, 0x19, 0xda, 0xf8, 0x06, + 0xde, 0x11, 0xea, 0xf7, 0xf4, 0xef, 0x03, 0x04, 0x0b, 0xe8, 0x08, 0x0e, + 0xe2, 0xee, 0xde, 0x06, 0x0e, 0x29, 0xfb, 0xfa, 0x00, 0x02, 0xec, 0x1b, + 0x52, 0xff, 0xde, 0x3a, 0x2f, 0x13, 0x30, 0xe9, 0xff, 0xf6, 0xe7, 0x15, + 0x1d, 0xd9, 0x3c, 0x0f, 0xe6, 0x14, 0xee, 0x13, 0x1f, 0xe7, 0x33, 0x08, + 0xfc, 0x06, 0x0c, 0x08, 0x19, 0xd9, 0x2b, 0x1f, 0x07, 0x10, 0x24, 0x16, + 0x29, 0xfc, 0x31, 0x4d, 0xf0, 0xd9, 0x3f, 0xf2, 0x20, 0xe2, 0x25, 0x49, + 0xe5, 0xec, 0x0a, 0xf5, 0xf2, 0xd9, 0x22, 0x1f, 0xed, 0x22, 0x02, 0x0a, + 0x16, 0x08, 0xf7, 0xfb, 0x0e, 0xfb, 0xfb, 0x1d, 0xf3, 0x1c, 0xf6, 0xe1, + 0xcf, 0x19, 0xf4, 0x0f, 0xee, 0xf9, 0x04, 0xd1, 0xf9, 0xe2, 0xda, 0xf1, + 0x24, 0xf5, 0x07, 0xdf, 0x1d, 0xf9, 0xdb, 0x18, 0x0b, 0xea, 0x08, 0xca, + 0xf2, 0xfa, 0xec, 0x04, 0x0e, 0x17, 0xed, 0xf1, 0x06, 0x15, 0xfc, 0xfd, + 0x08, 0xfa, 0xe3, 0xe4, 0x0a, 0xfc, 0xee, 0x08, 0xf5, 0x09, 0xef, 0xee, + 0x06, 0xef, 0xe1, 0x19, 0x07, 0xe8, 0xe6, 0xdf, 0xea, 0x0d, 0xf1, 0x16, + 0xee, 0xed, 0xf8, 0x09, 0xfa, 0xfb, 0x0c, 0xf8, 0xeb, 0xda, 0x00, 0xfc, + 0x04, 0xfe, 0xf5, 0xff, 0xf6, 0xe1, 0x0c, 0x0a, 0x13, 0x0d, 0xf6, 0xf5, + 0x15, 0x07, 0xca, 0xec, 0x50, 0x0e, 0xd0, 0x26, 0x4c, 0xf8, 0x23, 0xeb, + 0xff, 0x08, 0xe3, 0x11, 0x2c, 0xf9, 0x2a, 0xf1, 0xe9, 0x0b, 0xe9, 0x0f, + 0x15, 0xec, 0x33, 0x11, 0x0c, 0x0d, 0x01, 0x01, 0x32, 0xe3, 0x41, 0x27, + 0x11, 0x02, 0x2e, 0x07, 0x09, 0xe3, 0x22, 0x4d, 0xf1, 0x05, 0x27, 0x03, + 0x25, 0xf5, 0x2c, 0x3b, 0xf4, 0x00, 0x16, 0x0b, 0xec, 0xfe, 0x17, 0x0d, + 0xff, 0xe7, 0xfe, 0x24, 0x06, 0xee, 0xf0, 0xe9, 0xfa, 0x1c, 0xf2, 0x19, + 0x08, 0xfa, 0xff, 0xd2, 0x01, 0x02, 0xea, 0x05, 0xf2, 0xf4, 0x0b, 0xd2, + 0xf9, 0x0d, 0xcd, 0x0d, 0x12, 0xf2, 0x0e, 0xe1, 0x1f, 0x00, 0xe7, 0x14, + 0x04, 0xff, 0x09, 0xdb, 0xfc, 0xd9, 0x06, 0xf9, 0xeb, 0x01, 0xef, 0xfa, + 0xfb, 0xf5, 0xfc, 0xfb, 0x14, 0xe2, 0xf9, 0xf5, 0x02, 0xfd, 0xfc, 0x01, + 0xf7, 0xf3, 0x00, 0xec, 0xe7, 0xf2, 0x00, 0xf1, 0x11, 0xec, 0xf0, 0xe9, + 0x11, 0x0a, 0x07, 0x04, 0x01, 0xee, 0xfb, 0xf2, 0x14, 0x01, 0x12, 0xf0, + 0xf2, 0xf1, 0xf0, 0xfb, 0x08, 0x03, 0xf8, 0x01, 0xe8, 0xf9, 0x17, 0x26, + 0x0f, 0xea, 0xf7, 0xf8, 0x1e, 0xfe, 0xf2, 0xf8, 0x3f, 0x00, 0xd4, 0x1c, + 0x53, 0xfe, 0x1e, 0x0f, 0xef, 0xdd, 0xed, 0x10, 0x19, 0xe7, 0x34, 0x0e, + 0xde, 0xdf, 0xfa, 0x0e, 0x29, 0xe3, 0x16, 0x09, 0x06, 0x12, 0xeb, 0xf9, + 0x32, 0xe0, 0x1a, 0x1d, 0xf3, 0xed, 0x10, 0x07, 0x31, 0xf2, 0x12, 0x52, + 0xeb, 0xf7, 0x1e, 0xf7, 0x1a, 0xdc, 0x3e, 0x33, 0xe3, 0xfb, 0x1f, 0x0b, + 0x08, 0xfe, 0x13, 0x1a, 0xf4, 0xf8, 0xfe, 0x08, 0xfc, 0xe9, 0xfe, 0xeb, + 0xe6, 0xf6, 0x02, 0x18, 0x02, 0xe8, 0xfb, 0xf3, 0x01, 0x08, 0xd7, 0x13, + 0x04, 0xe6, 0x02, 0xe6, 0xd7, 0x01, 0xd4, 0xf0, 0x0e, 0x05, 0x18, 0xe5, + 0x08, 0xe5, 0xd2, 0x16, 0x12, 0xfe, 0x0e, 0xd3, 0xfc, 0x1f, 0xe9, 0xf8, + 0x11, 0x06, 0xf3, 0xd5, 0xf8, 0xff, 0xf0, 0x04, 0x0a, 0xd9, 0xf8, 0xfd, + 0xf5, 0x12, 0xff, 0x06, 0x1b, 0xe6, 0xfe, 0xfe, 0xde, 0xee, 0xf6, 0x18, + 0xf1, 0xf8, 0x06, 0xf3, 0x02, 0xea, 0x04, 0x14, 0xfc, 0xee, 0xe6, 0x09, + 0xf9, 0xee, 0xe3, 0xe7, 0xfc, 0xd9, 0xef, 0xfc, 0x0a, 0x0c, 0x03, 0xf6, + 0xe2, 0x11, 0x0f, 0x19, 0x18, 0x10, 0xef, 0xe5, 0x22, 0xf5, 0xe5, 0xe9, + 0x4b, 0xf7, 0xdb, 0x0c, 0x4f, 0xde, 0x22, 0x16, 0x09, 0x16, 0xd1, 0xf8, + 0x19, 0xe0, 0x24, 0xfe, 0xb8, 0xfb, 0xe5, 0x12, 0x1c, 0xe3, 0x22, 0x09, + 0x05, 0x29, 0xf7, 0x10, 0x31, 0xe1, 0x33, 0x3f, 0xfd, 0xed, 0x04, 0x03, + 0x2e, 0xed, 0x30, 0x36, 0xee, 0x16, 0x2f, 0xf5, 0x1b, 0xdc, 0x3a, 0x56, + 0xe5, 0xef, 0x26, 0xff, 0x03, 0xd7, 0x31, 0x16, 0xef, 0xf1, 0x08, 0x13, + 0x01, 0x02, 0x03, 0xf1, 0xf2, 0x08, 0xff, 0x05, 0x12, 0xf2, 0xee, 0xda, + 0xed, 0xec, 0xea, 0xf7, 0x0c, 0xf1, 0x09, 0xe6, 0xe6, 0x00, 0xcc, 0x10, + 0x0d, 0x0d, 0x20, 0xf4, 0x18, 0x23, 0xec, 0xf9, 0x00, 0xe4, 0x07, 0xd4, + 0xfb, 0x16, 0xd2, 0x01, 0xe6, 0x01, 0x06, 0xf0, 0xfe, 0x03, 0xf3, 0x09, + 0x01, 0x0d, 0x05, 0xf7, 0xd4, 0x02, 0xfb, 0xfb, 0x08, 0xf0, 0x1f, 0xf3, + 0xfe, 0xeb, 0x02, 0x0e, 0x1b, 0x0f, 0x04, 0xf5, 0xf0, 0x1f, 0x14, 0xf7, + 0x06, 0xdc, 0xf9, 0xe9, 0x01, 0xff, 0x08, 0xf2, 0x06, 0xff, 0xff, 0xf3, + 0x05, 0x1a, 0xfc, 0xfa, 0xeb, 0xfb, 0xfa, 0x12, 0x20, 0xf6, 0xe0, 0xe8, + 0x1c, 0xfa, 0xd6, 0x0d, 0x2c, 0x04, 0xe1, 0x09, 0x3b, 0xd3, 0x2a, 0xee, + 0xf7, 0xed, 0xf1, 0xf7, 0x0d, 0xf0, 0x32, 0x0f, 0xc9, 0x0e, 0x00, 0x10, + 0x24, 0xfb, 0x31, 0xf0, 0xf4, 0xdd, 0xf5, 0x04, 0x25, 0xc7, 0x27, 0x25, + 0x16, 0x11, 0x2e, 0x09, 0x30, 0xd1, 0x2c, 0x34, 0xe6, 0xf0, 0x21, 0xf5, + 0x21, 0xc8, 0x40, 0x39, 0xde, 0xf0, 0x12, 0xf3, 0x10, 0xe8, 0x1f, 0x18, + 0xfa, 0xea, 0x07, 0x11, 0xdf, 0xed, 0xfa, 0xf0, 0x07, 0xef, 0xf3, 0x05, + 0x10, 0xe5, 0xf3, 0xe9, 0xe9, 0xe8, 0xd6, 0x01, 0xf9, 0x05, 0x0b, 0xee, + 0xf9, 0x12, 0xe3, 0x05, 0xfd, 0xe6, 0x16, 0xe2, 0x1b, 0x12, 0xc5, 0x00, + 0xfd, 0x02, 0x04, 0xd2, 0xff, 0xec, 0xf6, 0xfd, 0x00, 0xe4, 0xf7, 0xf3, + 0xeb, 0xfa, 0xf8, 0x0d, 0x03, 0xfa, 0xfe, 0xe4, 0xdb, 0xe3, 0x06, 0xff, + 0xf4, 0xf2, 0x1b, 0xf1, 0xf7, 0x02, 0x01, 0x04, 0x13, 0xe5, 0x0c, 0x05, + 0xf7, 0x0a, 0x03, 0x03, 0x0b, 0x03, 0xee, 0xf7, 0x21, 0x20, 0xff, 0xf3, + 0x09, 0xe5, 0xff, 0xec, 0x17, 0x00, 0x06, 0x14, 0xeb, 0xf2, 0x18, 0x16, + 0x1f, 0xec, 0xee, 0xe1, 0x1e, 0x03, 0xfa, 0xfe, 0x28, 0x03, 0xc9, 0x0c, + 0x3f, 0xd8, 0x30, 0x16, 0x03, 0xf8, 0xe9, 0xfb, 0x28, 0xe1, 0x36, 0x0a, + 0xdf, 0xe5, 0xeb, 0x08, 0x1c, 0xcd, 0x29, 0xf2, 0xfc, 0x0a, 0xed, 0x01, + 0x29, 0xf1, 0x20, 0x13, 0x04, 0xec, 0x17, 0x0a, 0x35, 0xc3, 0x1a, 0x46, + 0xe0, 0xd7, 0x3c, 0x09, 0x28, 0xd1, 0x22, 0x20, 0xd5, 0xfa, 0x28, 0xfa, + 0xff, 0xea, 0x1d, 0x23, 0xe0, 0x07, 0x07, 0x0f, 0xf1, 0xf1, 0x08, 0xf0, + 0xf8, 0xff, 0x05, 0x1b, 0x05, 0xfa, 0xf0, 0xfb, 0xe3, 0xe4, 0xcc, 0x1a, + 0xf9, 0x09, 0x06, 0xee, 0xf4, 0x03, 0xd0, 0x14, 0xf4, 0xff, 0x1d, 0xe8, + 0x11, 0xf4, 0xd1, 0xf4, 0x04, 0x0b, 0xfb, 0xdc, 0x0a, 0x0c, 0xeb, 0xed, + 0x06, 0xf3, 0x04, 0xdd, 0xdf, 0xf9, 0xea, 0xfc, 0xf5, 0xf2, 0xfb, 0xea, + 0xe3, 0x03, 0xee, 0x0e, 0xff, 0xdb, 0x1e, 0x04, 0xf7, 0x1a, 0x04, 0x0c, + 0x0d, 0xda, 0x04, 0xe9, 0xff, 0x04, 0x00, 0x0c, 0xf9, 0xe4, 0xfb, 0xf6, + 0x14, 0xde, 0x1b, 0x00, 0x0b, 0xfe, 0x06, 0xf8, 0x0f, 0xdc, 0x01, 0xef, + 0xef, 0x0d, 0xf8, 0xf1, 0x0f, 0xf9, 0xf9, 0xdf, 0x0d, 0xe4, 0xd9, 0xf9, + 0x2b, 0xee, 0xe8, 0x09, 0x40, 0xf9, 0x2f, 0x0a, 0xfa, 0xe8, 0xe9, 0x01, + 0x0e, 0xe7, 0x23, 0x0a, 0xd0, 0x19, 0xd3, 0x0e, 0x04, 0xda, 0x2b, 0x0f, + 0xe7, 0xe6, 0xf3, 0xfb, 0x2c, 0xd3, 0x36, 0x19, 0x0e, 0xfe, 0x03, 0x1a, + 0x2e, 0xd0, 0x23, 0x32, 0xf1, 0xe1, 0x2a, 0x09, 0x1b, 0xf6, 0x29, 0x3e, + 0xce, 0x15, 0x0a, 0xe8, 0xec, 0xdf, 0x44, 0x28, 0xd9, 0xfd, 0xfa, 0x09, + 0xff, 0xe7, 0x08, 0xec, 0xf4, 0xef, 0x01, 0x19, 0x11, 0xf3, 0xeb, 0xeb, + 0xed, 0x1a, 0xdd, 0x15, 0x0f, 0x07, 0xfe, 0xeb, 0xff, 0xd6, 0xd5, 0x04, + 0xf5, 0x07, 0x10, 0xe6, 0x0c, 0xe4, 0xda, 0x0c, 0x08, 0xee, 0x06, 0xd8, + 0xf8, 0xf1, 0xe0, 0x01, 0x08, 0xfe, 0xf9, 0xf3, 0xdf, 0x03, 0xe6, 0xf4, + 0x0a, 0xff, 0xf2, 0xe0, 0xd9, 0xeb, 0x01, 0x10, 0x02, 0xfc, 0x0d, 0x14, + 0xea, 0xf8, 0x03, 0x18, 0xf3, 0x09, 0xfc, 0x0c, 0x0b, 0x1f, 0xf5, 0x05, + 0xf7, 0xf9, 0x00, 0xfd, 0x04, 0xfc, 0x16, 0x07, 0x00, 0xdf, 0xf9, 0xfa, + 0x0c, 0xfb, 0xf4, 0xf7, 0xf0, 0xeb, 0x07, 0x17, 0x20, 0xfb, 0xf0, 0xec, + 0x04, 0x00, 0xf8, 0xf2, 0x2d, 0xf9, 0xd9, 0x0b, 0x55, 0xec, 0x33, 0x26, + 0xf8, 0x0a, 0xf2, 0x0b, 0x25, 0xdf, 0x29, 0x05, 0xd1, 0x14, 0xe2, 0xf2, + 0x12, 0xdd, 0x28, 0xfc, 0xec, 0x08, 0xfd, 0x02, 0x3a, 0xe6, 0x29, 0x25, + 0x0d, 0x10, 0x09, 0x0a, 0x32, 0xf5, 0x17, 0x2d, 0xea, 0xfb, 0x35, 0xfc, + 0x28, 0xd0, 0x29, 0x2f, 0xcb, 0x06, 0x0f, 0x04, 0xf2, 0xf3, 0x34, 0x1c, + 0xf4, 0x08, 0x05, 0xfc, 0xfd, 0xed, 0x0f, 0xf8, 0xe9, 0xf0, 0x09, 0x16, + 0xfe, 0x02, 0xff, 0xd4, 0xea, 0x0a, 0xeb, 0x0c, 0xf8, 0xf4, 0x09, 0xf4, + 0xf2, 0x07, 0xd9, 0x0b, 0xfd, 0xe4, 0x1a, 0xef, 0x14, 0x08, 0xd8, 0xfc, + 0xf5, 0xe1, 0x03, 0xcf, 0xf1, 0x11, 0xdb, 0x15, 0x07, 0x10, 0xf8, 0xfc, + 0xe2, 0xf1, 0xf5, 0xde, 0xff, 0xe7, 0x01, 0xea, 0xee, 0xe9, 0x02, 0x0a, + 0x18, 0xec, 0xfe, 0xf9, 0x09, 0xf3, 0x0e, 0x02, 0xf1, 0xfc, 0xf9, 0x16, + 0x05, 0x07, 0x09, 0x0d, 0x0e, 0xf7, 0x04, 0xed, 0x04, 0xdb, 0x04, 0x04, + 0xf6, 0xdc, 0xee, 0xec, 0xf5, 0xfe, 0xf4, 0x02, 0xe4, 0x0b, 0xe0, 0x17, + 0x0a, 0xe0, 0xf7, 0xdc, 0x11, 0xd6, 0xfe, 0xfa, 0x35, 0xde, 0xe6, 0x06, + 0x44, 0xf9, 0x35, 0x0a, 0xfb, 0xff, 0xec, 0xfb, 0x16, 0xd9, 0x23, 0x0f, + 0xd4, 0xef, 0xdf, 0x06, 0x0b, 0xd9, 0x25, 0xff, 0xf8, 0xeb, 0xf4, 0x0a, + 0x20, 0xe5, 0x22, 0x1c, 0xeb, 0xf4, 0x0d, 0x0c, 0x19, 0xe1, 0x1e, 0x31, + 0xe9, 0xfb, 0x20, 0xf0, 0x23, 0xfe, 0x35, 0x28, 0xb4, 0x06, 0x28, 0xe7, + 0xfb, 0xe9, 0x2a, 0x1a, 0xef, 0x15, 0x0c, 0xed, 0xf1, 0x04, 0x0e, 0x0a, + 0xff, 0x16, 0x01, 0x04, 0x17, 0xea, 0xec, 0xdc, 0xf4, 0xf7, 0x04, 0x16, + 0x1f, 0x0a, 0x11, 0xef, 0x12, 0xdf, 0xd9, 0x0c, 0xf5, 0x10, 0x02, 0xf3, + 0x10, 0x03, 0xd3, 0xf5, 0x0b, 0x02, 0x00, 0xcb, 0xf6, 0x23, 0xf6, 0xf1, + 0x1f, 0xf9, 0xfc, 0xf0, 0xf6, 0xfe, 0xfa, 0xf8, 0xf9, 0xf4, 0xfb, 0x0a, + 0xd6, 0x29, 0x09, 0x02, 0x00, 0xfc, 0xfc, 0xee, 0xf5, 0x05, 0xfb, 0x1e, + 0xf1, 0xf1, 0xf3, 0x02, 0xec, 0x1c, 0x0c, 0x0e, 0x0b, 0x04, 0xf6, 0xe7, + 0x14, 0x08, 0x27, 0x01, 0xfe, 0xe5, 0xe7, 0x01, 0x1b, 0xf0, 0xf6, 0xff, + 0xf4, 0xe7, 0xee, 0x18, 0x0d, 0x08, 0xf8, 0xd6, 0x07, 0xf4, 0x08, 0xff, + 0x1d, 0x13, 0xe7, 0x0b, 0x42, 0xef, 0x28, 0x00, 0xf9, 0xf0, 0xf3, 0x00, + 0x15, 0xfd, 0x1a, 0x22, 0xc1, 0xf5, 0xe0, 0xf8, 0x09, 0xe6, 0x0e, 0x05, + 0xf9, 0xf6, 0x01, 0x01, 0x13, 0xdc, 0x1f, 0x0d, 0xfb, 0x04, 0x08, 0x0b, + 0x15, 0xdb, 0x28, 0x34, 0xed, 0x0b, 0x3a, 0xed, 0x16, 0xe3, 0x39, 0x32, + 0xc4, 0x0b, 0x20, 0xe7, 0xf7, 0x02, 0x35, 0x24, 0xfc, 0xe8, 0x1c, 0xf8, + 0xf1, 0xfa, 0x0c, 0x1d, 0xf2, 0x05, 0xff, 0x12, 0x0f, 0x01, 0xec, 0xea, + 0xf0, 0x03, 0xe7, 0x15, 0xfd, 0x05, 0x08, 0xe0, 0x1b, 0xf8, 0xe1, 0x1e, + 0xed, 0xdc, 0x11, 0xeb, 0xfd, 0x1a, 0xeb, 0x09, 0xf9, 0xf3, 0x00, 0xe8, + 0xe6, 0x08, 0xf7, 0xde, 0x1e, 0x00, 0x00, 0x00, 0xe4, 0x09, 0xf2, 0xf8, + 0xe7, 0xf2, 0x0d, 0xfa, 0xe2, 0x0f, 0x04, 0x08, 0xf2, 0x13, 0xf8, 0xf9, + 0xf1, 0xff, 0x03, 0x11, 0x12, 0xe9, 0xf4, 0x13, 0x07, 0x0c, 0x13, 0x2b, + 0xf7, 0xdd, 0xf9, 0xe9, 0xfa, 0xdb, 0x1d, 0xf6, 0xf6, 0xf9, 0xe4, 0xf6, + 0x0d, 0xeb, 0x0d, 0x08, 0xe7, 0xe7, 0xf2, 0x03, 0x1d, 0xd9, 0xd8, 0xe4, + 0xf7, 0xea, 0xdc, 0xdc, 0x26, 0x02, 0xee, 0xfa, 0x38, 0xfc, 0x1a, 0xef, + 0xda, 0xf1, 0xdf, 0x0b, 0x1a, 0xe0, 0x16, 0x16, 0xdc, 0x04, 0xfa, 0xf7, + 0xee, 0x02, 0x25, 0x02, 0xf5, 0xfb, 0x08, 0xf6, 0x11, 0xf5, 0x12, 0x08, + 0xf4, 0xe3, 0x1b, 0xf5, 0x3a, 0xdc, 0x20, 0x2e, 0xe0, 0xf5, 0x30, 0xe4, + 0x09, 0xf8, 0x3c, 0x45, 0xd3, 0x08, 0x23, 0xd8, 0x09, 0xe4, 0x35, 0x30, + 0xe4, 0xfe, 0x07, 0xf6, 0x05, 0x01, 0x05, 0xff, 0xf6, 0x0d, 0x02, 0xfd, + 0x03, 0x05, 0x0d, 0x00, 0xf5, 0xd6, 0xcf, 0x19, 0x06, 0xee, 0x0d, 0xf2, + 0x01, 0x18, 0xef, 0x12, 0x04, 0x02, 0x21, 0xd9, 0x02, 0x0d, 0xeb, 0xe9, + 0x13, 0x08, 0x15, 0xf0, 0xee, 0x03, 0xec, 0x06, 0x17, 0xed, 0x00, 0x1a, + 0xee, 0xf2, 0xfc, 0x09, 0xec, 0xf8, 0xf8, 0x18, 0xf4, 0x13, 0x04, 0xf6, + 0x02, 0xf0, 0xfc, 0xfe, 0xe3, 0x01, 0x0a, 0x1c, 0x1b, 0xec, 0x0e, 0x01, + 0xfb, 0x08, 0x11, 0xf5, 0x00, 0x14, 0xe6, 0x12, 0x07, 0xf4, 0x15, 0x07, + 0xfc, 0xfb, 0xf5, 0xf1, 0x01, 0x21, 0x01, 0xe9, 0xe8, 0xef, 0xdb, 0xdf, + 0x1f, 0x0a, 0xdd, 0xd1, 0x16, 0x04, 0xfd, 0xe1, 0x24, 0xf0, 0xec, 0xf4, + 0x38, 0xe1, 0x16, 0xfd, 0xe0, 0xec, 0xe7, 0x0c, 0x2a, 0x04, 0x0c, 0x17, + 0xdc, 0xe8, 0xf2, 0x03, 0xec, 0xfd, 0x19, 0xfe, 0xf3, 0xf0, 0xf3, 0xfb, + 0x18, 0xdf, 0x1c, 0x00, 0x09, 0xf4, 0x18, 0x0b, 0x1f, 0xf6, 0x34, 0x22, + 0xf4, 0x22, 0x45, 0xeb, 0x23, 0xcf, 0x32, 0x34, 0xf2, 0xf9, 0x29, 0xd4, + 0xf7, 0x0b, 0x38, 0x2a, 0x09, 0xe6, 0x05, 0x01, 0x0b, 0xfe, 0x17, 0xfb, + 0x00, 0xeb, 0x08, 0xfd, 0x0c, 0x02, 0x1d, 0xea, 0xfa, 0x0b, 0xeb, 0x09, + 0xfe, 0xfe, 0x10, 0xe0, 0xf6, 0x06, 0xf0, 0x15, 0xf3, 0x09, 0x11, 0xe4, + 0xf9, 0x07, 0xe1, 0xed, 0x17, 0x05, 0x0c, 0xe1, 0xdb, 0xf2, 0xf8, 0xea, + 0x22, 0xe9, 0x02, 0x00, 0xfd, 0xe7, 0xf2, 0xf8, 0xf9, 0xfc, 0xfa, 0xe8, + 0xe8, 0xeb, 0xe9, 0x0d, 0x04, 0xf8, 0xf8, 0xf7, 0xf8, 0x0d, 0x03, 0x0c, + 0x13, 0xf2, 0x0f, 0xf9, 0xe6, 0xfd, 0x0f, 0x19, 0x08, 0xf7, 0xfa, 0x01, + 0xf3, 0x12, 0x1e, 0x05, 0x0a, 0x09, 0xfd, 0x0b, 0x07, 0x08, 0x02, 0xfc, + 0xd6, 0xe8, 0x14, 0x01, 0x13, 0x19, 0xef, 0xda, 0x0e, 0x0a, 0x07, 0xef, + 0x34, 0xe0, 0x05, 0x1e, 0x4e, 0xe9, 0x19, 0xff, 0xe1, 0x04, 0xfb, 0x0e, + 0x11, 0x05, 0x1f, 0x15, 0xd4, 0xec, 0xf9, 0xe7, 0xf9, 0xfc, 0x25, 0xff, + 0x06, 0xf2, 0x01, 0xf6, 0x2a, 0x17, 0x24, 0x11, 0xf3, 0x1a, 0x1f, 0xfb, + 0x32, 0xeb, 0x33, 0x2f, 0x00, 0x08, 0x2c, 0xf0, 0x26, 0xf4, 0x25, 0x36, + 0xd9, 0xf1, 0x1a, 0xd5, 0xec, 0xf9, 0x32, 0x27, 0xfc, 0xf4, 0xf0, 0xe3, + 0xfa, 0x0c, 0x16, 0x17, 0xfa, 0xf9, 0xe5, 0x1f, 0x1f, 0xfa, 0xff, 0xfd, + 0x0d, 0x02, 0xe9, 0x0e, 0xf0, 0x12, 0x09, 0xda, 0x02, 0xea, 0xe5, 0x0a, + 0xff, 0x03, 0x13, 0xf0, 0x0a, 0xf9, 0xe9, 0xff, 0x10, 0xfc, 0x1a, 0xf3, + 0xf7, 0x0f, 0xf4, 0xfa, 0xf4, 0x05, 0x10, 0x0a, 0xdd, 0x09, 0xf7, 0xf0, + 0xe5, 0x07, 0x07, 0xfa, 0x02, 0xd7, 0xf8, 0xf7, 0x01, 0xfb, 0x0e, 0xf8, + 0x07, 0x0f, 0xfe, 0x03, 0x12, 0x05, 0x09, 0x13, 0xf8, 0xdc, 0xfd, 0x27, + 0x0f, 0xec, 0xf7, 0x07, 0x00, 0xfc, 0x12, 0xf8, 0xfb, 0xea, 0xe4, 0xe9, + 0xe9, 0xe0, 0xff, 0xdc, 0xd6, 0xeb, 0xf2, 0xf7, 0x0d, 0x1b, 0xe9, 0xc4, + 0x06, 0x00, 0xfd, 0x04, 0x46, 0xf9, 0xe9, 0x13, 0x2d, 0x0c, 0x1f, 0xf8, + 0xd3, 0x0c, 0x14, 0x11, 0x05, 0xe5, 0x27, 0x08, 0xc5, 0xef, 0xdf, 0xdd, + 0x04, 0xf8, 0x11, 0x10, 0xf0, 0xe7, 0xfb, 0x03, 0x3c, 0xe7, 0x14, 0x0c, + 0xf4, 0xf6, 0x1b, 0x0a, 0x23, 0xf2, 0x2d, 0x1a, 0x08, 0xff, 0x32, 0xe7, + 0x1a, 0x05, 0x2b, 0x34, 0xf1, 0x0a, 0x00, 0xe8, 0x02, 0xdf, 0x2c, 0x2a, + 0x03, 0xe6, 0xfc, 0xef, 0xfc, 0xe4, 0x03, 0x01, 0x03, 0xee, 0xe9, 0x15, + 0x05, 0x03, 0x13, 0x11, 0x0e, 0xee, 0xf5, 0x22, 0x1b, 0x0e, 0xfd, 0xf3, + 0x0a, 0x02, 0xdd, 0x20, 0xeb, 0x06, 0xf8, 0xe2, 0x06, 0x0e, 0xde, 0x0d, + 0xf9, 0x16, 0x1c, 0x0c, 0xe0, 0xf0, 0xec, 0x0c, 0x0f, 0xf2, 0x27, 0x1d, + 0xde, 0xe6, 0xf0, 0xf9, 0xf0, 0x02, 0x0a, 0x07, 0x06, 0xf9, 0x0f, 0xfa, + 0xf0, 0xee, 0xf1, 0xf7, 0xff, 0x02, 0x0b, 0x0d, 0x1b, 0xee, 0xf6, 0x05, + 0xff, 0x1c, 0x17, 0x04, 0x05, 0x17, 0x00, 0xff, 0x0d, 0xf3, 0x23, 0x10, + 0xfd, 0x05, 0xfb, 0xea, 0x03, 0x10, 0x07, 0xd7, 0xf7, 0xff, 0xf3, 0xf1, + 0x17, 0xed, 0xd3, 0xcb, 0x14, 0x1c, 0xf5, 0x03, 0x47, 0xf6, 0xf7, 0xf2, + 0x3e, 0xf2, 0x22, 0xf4, 0xed, 0xfc, 0xee, 0x0b, 0xf4, 0xf1, 0x25, 0x10, + 0xd0, 0xf6, 0x00, 0xef, 0x10, 0xfc, 0x15, 0xe5, 0xdb, 0xf3, 0xea, 0x10, + 0x22, 0xf2, 0x2b, 0x11, 0xf9, 0x0a, 0xfc, 0xf5, 0x53, 0x16, 0x25, 0x43, + 0xe0, 0x0e, 0x13, 0xfc, 0x2d, 0xe2, 0x55, 0x65, 0xf4, 0x08, 0x01, 0xdf, + 0x0a, 0x00, 0x49, 0x1c, 0xfe, 0xdf, 0xef, 0xf2, 0xf9, 0xf6, 0xfd, 0xff, + 0xf3, 0x02, 0xf6, 0x14, 0x0b, 0xe8, 0x09, 0xfc, 0xfc, 0xe2, 0xe5, 0x11, + 0x03, 0x09, 0xfb, 0x06, 0x10, 0x1a, 0xf3, 0x0d, 0xfa, 0x0a, 0xd5, 0xf5, + 0x1a, 0x11, 0xf2, 0xfc, 0x1f, 0xfe, 0x0e, 0xe4, 0xef, 0xd7, 0xee, 0x06, + 0x1e, 0x04, 0x12, 0x28, 0xf7, 0x0e, 0x06, 0xf8, 0xee, 0xf0, 0x1a, 0x01, + 0xf7, 0xfd, 0x03, 0x11, 0x19, 0x10, 0x04, 0xfb, 0xd7, 0xfa, 0x16, 0x06, + 0x07, 0x23, 0xfa, 0x14, 0x11, 0xf1, 0x12, 0x10, 0x04, 0xe1, 0xee, 0xf7, + 0x21, 0x0e, 0x0a, 0x0a, 0xf8, 0x07, 0x0a, 0xee, 0x03, 0x1f, 0xfa, 0xc4, + 0xec, 0x12, 0x01, 0x1e, 0xfd, 0xf1, 0xe8, 0xcc, 0xf4, 0x17, 0xff, 0xdd, + 0x45, 0x10, 0xee, 0xfa, 0x3d, 0xe7, 0x27, 0xdd, 0xd7, 0xf9, 0xf4, 0xf6, + 0x06, 0xf8, 0x1e, 0x13, 0xe7, 0xe2, 0xf1, 0xe3, 0xf3, 0xf7, 0x18, 0x12, + 0xe4, 0x0a, 0xdb, 0xff, 0xff, 0xfe, 0x20, 0x09, 0x00, 0xf7, 0x23, 0xf6, + 0x2d, 0x14, 0x26, 0x28, 0xe5, 0xff, 0x0f, 0xe3, 0x1d, 0xe8, 0x56, 0x43, + 0xe7, 0xfb, 0xf9, 0xe6, 0xe9, 0xe2, 0x19, 0x19, 0x08, 0xfa, 0xf3, 0xe5, + 0x23, 0x07, 0x0f, 0xf8, 0xf8, 0xf3, 0xfc, 0x11, 0x2a, 0x05, 0xf4, 0xf1, + 0xfa, 0xfb, 0xf1, 0x1e, 0x13, 0x0f, 0xf9, 0xf5, 0xfa, 0x09, 0xf9, 0x03, + 0xf0, 0xf0, 0xe7, 0xec, 0xf1, 0x0c, 0xe6, 0xee, 0xf6, 0x20, 0x0f, 0xe9, + 0x00, 0xf4, 0xfe, 0xf0, 0x13, 0x0a, 0x17, 0x13, 0xee, 0x13, 0xfb, 0xff, + 0xf8, 0xfd, 0xf4, 0xe2, 0xe8, 0x06, 0xfc, 0x14, 0x03, 0x17, 0x00, 0x03, + 0xe6, 0xfd, 0xf2, 0x12, 0x12, 0x20, 0xeb, 0x10, 0x02, 0xf7, 0x13, 0x0d, + 0x11, 0xfd, 0xde, 0xf5, 0x07, 0xf3, 0x04, 0xff, 0x06, 0x05, 0xfb, 0xea, + 0xf0, 0x0a, 0x00, 0xb5, 0xe8, 0x1a, 0x03, 0xfe, 0x0d, 0x1a, 0xe7, 0xc0, + 0xd6, 0xdc, 0xf6, 0xf8, 0x39, 0xf5, 0xd5, 0xf8, 0x22, 0xfa, 0x22, 0x05, + 0xd0, 0xf4, 0x2d, 0xfc, 0x00, 0x0a, 0x1b, 0xfc, 0xe6, 0x09, 0x14, 0xfa, + 0x00, 0x1d, 0x1a, 0xfd, 0xf3, 0x18, 0xfc, 0xeb, 0x15, 0xf5, 0x0e, 0x0a, + 0xf3, 0xf1, 0x1b, 0x05, 0x14, 0x03, 0x2d, 0x27, 0xfb, 0x18, 0x22, 0xef, + 0xf6, 0x06, 0x28, 0x2b, 0xde, 0xec, 0xef, 0xe8, 0xd3, 0xfe, 0x17, 0x12, + 0x01, 0x13, 0x05, 0xf7, 0x00, 0xde, 0xf3, 0xe5, 0x03, 0xfb, 0x07, 0x0b, + 0xfd, 0xdc, 0xdf, 0x03, 0x0c, 0x00, 0xfa, 0x06, 0x0e, 0x02, 0x05, 0xfa, + 0xfd, 0xed, 0x09, 0x0c, 0xfd, 0xfb, 0x0c, 0xf0, 0xe4, 0x04, 0xd6, 0xf3, + 0x09, 0x0a, 0xf9, 0xf8, 0xe2, 0xef, 0xdf, 0xf0, 0xf8, 0x03, 0x0f, 0x20, + 0xf4, 0xe3, 0xf8, 0x02, 0xe2, 0xe5, 0x25, 0x0f, 0xeb, 0xf8, 0xe9, 0xfd, + 0x04, 0x0c, 0x0c, 0xfe, 0x01, 0x08, 0xfc, 0xfc, 0x1b, 0x01, 0xe5, 0x13, + 0xf9, 0xe8, 0x07, 0x20, 0xfe, 0x06, 0xec, 0xfe, 0x09, 0xef, 0x14, 0x04, + 0x0b, 0xf5, 0xe7, 0xff, 0x0a, 0x02, 0x09, 0xe9, 0xc4, 0x16, 0x0d, 0xe7, + 0x15, 0x14, 0xf1, 0xd0, 0xec, 0xe7, 0xf0, 0xf0, 0x33, 0x05, 0xda, 0xf2, + 0x0b, 0x08, 0x38, 0x01, 0x07, 0xfd, 0xd8, 0x06, 0xd9, 0xf0, 0x16, 0x1f, + 0xff, 0xf7, 0xe0, 0xd8, 0xf3, 0xf7, 0x12, 0x08, 0x0e, 0x05, 0xf6, 0x03, + 0xef, 0x1b, 0x12, 0xf4, 0xe8, 0x0f, 0x02, 0xfd, 0xf2, 0x16, 0x26, 0x22, + 0xe0, 0x07, 0xf7, 0xe6, 0xeb, 0x16, 0x22, 0x1a, 0x0b, 0x01, 0xf5, 0xea, + 0xd2, 0x22, 0x0f, 0x13, 0x15, 0x08, 0xf0, 0xfb, 0xed, 0x11, 0xf3, 0xe9, + 0xff, 0xde, 0x0a, 0x18, 0x0f, 0x02, 0xfb, 0xf9, 0xfb, 0xe8, 0x12, 0x18, + 0x01, 0xf4, 0xf6, 0xf8, 0xf0, 0x1f, 0x24, 0x15, 0xf5, 0x00, 0x1c, 0xf9, + 0x01, 0x0a, 0x11, 0xd5, 0x01, 0x12, 0x02, 0xec, 0xfd, 0x07, 0xf2, 0xea, + 0xf9, 0xff, 0xf7, 0xfb, 0x15, 0xec, 0xe5, 0x01, 0xeb, 0x05, 0xf9, 0x10, + 0xfe, 0x28, 0xe5, 0x0a, 0xeb, 0x1b, 0x0e, 0xf9, 0xde, 0x02, 0x15, 0x0a, + 0xff, 0xfe, 0x11, 0x24, 0x03, 0xf8, 0x00, 0x08, 0xfd, 0x0e, 0xeb, 0xf3, + 0xf6, 0xf7, 0x14, 0x0e, 0xfc, 0xf5, 0xde, 0xf5, 0x9e, 0xfe, 0xff, 0xff, + 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xab, 0x01, 0x00, 0x00, + 0xfa, 0xfd, 0xff, 0xff, 0xa2, 0xff, 0xff, 0xff, 0xba, 0x00, 0x00, 0x00, + 0x24, 0xfc, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x54, 0x4f, 0x43, 0x4f, + 0x20, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x65, 0x64, 0x2e, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x24, 0xfb, 0xff, 0xff, + 0x68, 0x01, 0x00, 0x00, 0x5c, 0x01, 0x00, 0x00, 0x50, 0x01, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x00, + 0x90, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0xce, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, 0x03, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x1a, 0xff, 0xff, 0xff, 0x00, 0x00, 0x80, 0x3f, 0x01, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x00, 0x18, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x10, 0x00, + 0x07, 0x00, 0x14, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0xc4, 0xfc, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, + 0x16, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x07, 0x00, 0x10, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x38, 0x00, 0x00, 0x00, + 0x2c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x10, 0x00, 0x07, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, + 0x1a, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x10, 0x00, 0x07, 0x00, 0x14, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x02, 0x00, 0x00, 0x00, + 0x38, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x00, 0x08, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x31, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x34, 0x04, 0x00, 0x00, 0xcc, 0x03, 0x00, 0x00, + 0x4c, 0x03, 0x00, 0x00, 0xdc, 0x02, 0x00, 0x00, 0x60, 0x02, 0x00, 0x00, + 0x20, 0x02, 0x00, 0x00, 0xb0, 0x01, 0x00, 0x00, 0x44, 0x01, 0x00, 0x00, + 0x70, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0xfc, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x09, 0x44, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x28, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xf4, 0xfb, 0xff, 0xff, + 0x14, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x3b, 0x0e, 0x00, 0x00, 0x00, 0x6c, 0x61, 0x62, 0x65, + 0x6c, 0x73, 0x5f, 0x73, 0x6f, 0x66, 0x74, 0x6d, 0x61, 0x78, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x00, 0x1a, 0x00, 0x08, 0x00, 0x07, 0x00, 0x0c, 0x00, + 0x10, 0x00, 0x14, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, + 0xb4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x11, 0x1e, 0x23, 0x3a, 0x9e, 0xa1, 0x15, 0x39, + 0x23, 0x69, 0x45, 0x3a, 0x09, 0xe4, 0xe4, 0x39, 0x65, 0xd7, 0x13, 0x3a, + 0xe0, 0xb2, 0xfd, 0x39, 0x1b, 0xc1, 0x53, 0x3a, 0xc2, 0x50, 0x2d, 0x3a, + 0x12, 0x00, 0x00, 0x00, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x77, 0x65, + 0x69, 0x67, 0x68, 0x74, 0x73, 0x2f, 0x72, 0x65, 0x61, 0x64, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x3a, 0xfd, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x09, 0x54, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x28, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x2c, 0xfd, 0xff, 0xff, + 0x14, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xb5, 0xfa, 0xfa, 0x39, 0x1f, 0x00, 0x00, 0x00, 0x66, 0x69, 0x6e, 0x61, + 0x6c, 0x5f, 0x66, 0x63, 0x5f, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, + 0x2f, 0x72, 0x65, 0x61, 0x64, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, + 0x6f, 0x73, 0x65, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0xa0, 0x0f, 0x00, 0x00, 0xa2, 0xfd, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, + 0x58, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x74, 0xfe, 0xff, 0xff, 0x30, 0x00, 0x00, 0x00, + 0x24, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xf2, 0xdd, 0xbb, 0x3d, + 0x01, 0x00, 0x00, 0x00, 0x32, 0xa3, 0x25, 0x41, 0x01, 0x00, 0x00, 0x00, + 0xf6, 0xa0, 0x50, 0xc1, 0x05, 0x00, 0x00, 0x00, 0x61, 0x64, 0x64, 0x5f, + 0x31, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x0e, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, + 0x2c, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x52, 0x65, 0x73, 0x68, 0x61, 0x70, 0x65, 0x5f, + 0x32, 0x2f, 0x73, 0x68, 0x61, 0x70, 0x65, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x4a, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, + 0x5c, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x1c, 0xff, 0xff, 0xff, 0x30, 0x00, 0x00, 0x00, + 0x24, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x50, 0xd0, 0x3d, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0xcf, 0x41, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x52, 0x65, 0x73, 0x68, + 0x61, 0x70, 0x65, 0x5f, 0x32, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0xc2, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, + 0x58, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x94, 0xff, 0xff, 0xff, 0x2c, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x01, 0x00, 0x00, 0x00, 0x50, 0x50, 0xd0, 0x3d, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x80, 0xcf, 0x41, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x52, 0x65, 0x73, 0x68, 0x61, 0x70, 0x65, 0x5f, + 0x31, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xa8, 0x07, 0x00, 0x00, 0x2e, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, + 0x60, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x14, 0x00, 0x04, 0x00, 0x08, 0x00, + 0x0c, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x01, 0x00, 0x00, 0x00, 0x3a, 0x6a, 0xac, 0x3d, 0x01, 0x00, 0x00, 0x00, + 0xd0, 0xbd, 0xab, 0x41, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x52, 0x65, 0x6c, 0x75, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0xaa, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x02, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x2c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x9c, 0xff, 0xff, 0xff, + 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x96, 0x08, 0x29, 0x38, 0x0b, 0x00, 0x00, 0x00, + 0x4d, 0x61, 0x74, 0x4d, 0x75, 0x6c, 0x5f, 0x62, 0x69, 0x61, 0x73, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, + 0x18, 0x00, 0x08, 0x00, 0x07, 0x00, 0x0c, 0x00, 0x10, 0x00, 0x14, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xa0, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x9a, 0xbb, 0x84, 0x38, 0x83, 0x84, 0x73, 0x37, 0x5b, 0xa3, 0xa0, 0x38, + 0x16, 0x41, 0x3a, 0x38, 0xc7, 0x9a, 0x70, 0x38, 0xed, 0x70, 0x4e, 0x38, + 0x54, 0x4f, 0xac, 0x38, 0xfd, 0x07, 0x8d, 0x38, 0x0b, 0x00, 0x00, 0x00, + 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x44, 0x5f, 0x62, 0x69, 0x61, 0x73, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x4c, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x19, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x00, 0x16, 0x0a, 0x00, 0x0e, 0x00, 0x07, 0x00, + 0x00, 0x00, 0x08, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x0c, 0x00, 0x07, 0x00, + 0x00, 0x00, 0x08, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, + 0x03, 0x00, 0x00, 0x00}; +const int g_model_len = 18712; diff --git a/micro_speech/src/micro_features/model.h b/micro_speech/src/micro_features/model.h new file mode 100644 index 0000000..deec2d6 --- /dev/null +++ b/micro_speech/src/micro_features/model.h @@ -0,0 +1,27 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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. +==============================================================================*/ + +// This is a standard TensorFlow Lite FlatBuffer model file that has been +// converted into a C data array, so it can be easily compiled into a binary +// for devices that don't have a file system. It was created using the command: +// xxd -i model.tflite > model.cc + +#ifndef TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_MICRO_FEATURES_MODEL_H_ +#define TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_MICRO_FEATURES_MODEL_H_ + +extern const unsigned char g_model[]; +extern const int g_model_len; + +#endif // TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_MICRO_FEATURES_MODEL_H_ diff --git a/micro_speech/src/micro_features/no_feature_data_slice.cc b/micro_speech/src/micro_features/no_feature_data_slice.cc new file mode 100644 index 0000000..8170f60 --- /dev/null +++ b/micro_speech/src/micro_features/no_feature_data_slice.cc @@ -0,0 +1,24 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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. +==============================================================================*/ + +// See the header for documentation on the meaning of this data. + +#include "micro_features/no_feature_data_slice.h" + +const int8_t g_no_feature_data_slice[g_no_feature_data_slice_size] = { + 89, 68, 96, 83, 111, 96, 115, 87, 99, 76, 105, 84, 105, 86, + 113, 91, 108, 87, 110, 78, 80, 46, 22, 74, 88, 72, 103, 86, + 80, 68, 48, 24, 68, 48, 55, 36, 108, 90, 90, 63, +}; diff --git a/micro_speech/src/micro_features/no_feature_data_slice.h b/micro_speech/src/micro_features/no_feature_data_slice.h new file mode 100644 index 0000000..01e6605 --- /dev/null +++ b/micro_speech/src/micro_features/no_feature_data_slice.h @@ -0,0 +1,29 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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. +==============================================================================*/ + +// This data was extracted from the larger feature data held in +// no_features_data.cc and consists of the 29th spectrogram slice of 43 values. +// This is the expected result of running the sample data in +// no_30ms_sample_data.cc through the preprocessing pipeline. + +#ifndef TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_MICRO_FEATURES_NO_FEATURE_DATA_SLICE_H_ +#define TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_MICRO_FEATURES_NO_FEATURE_DATA_SLICE_H_ + +#include + +constexpr int g_no_feature_data_slice_size = 40; +extern const int8_t g_no_feature_data_slice[]; + +#endif // TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_MICRO_FEATURES_NO_FEATURE_DATA_SLICE_H_ diff --git a/micro_speech/src/micro_features/no_micro_features_data.cc b/micro_speech/src/micro_features/no_micro_features_data.cc new file mode 100644 index 0000000..2edeeb5 --- /dev/null +++ b/micro_speech/src/micro_features/no_micro_features_data.cc @@ -0,0 +1,188 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 "micro_features/no_micro_features_data.h" + +// Golden test values for the expected spectrogram from a "no" sample file +// speech_commands_test_set_v0.02/no/f9643d42_nohash_4.wav. + +const int g_no_micro_f9643d42_nohash_4_width = 40; +const int g_no_micro_f9643d42_nohash_4_height = 49; +const signed char g_no_micro_f9643d42_nohash_4_data[] = { + 103, 78, 64, 76, 75, 54, 53, 67, 77, 60, 56, 70, + 76, 71, 68, 58, 74, 32, 23, -2, -18, 11, 13, 15, + 9, 20, 5, -7, -18, -2, -10, -18, -10, -12, 9, 7, + -33, -12, -4, -18, 57, 17, 55, 62, 70, 45, 61, 37, + 67, 52, 48, 47, 55, 46, 57, 47, 73, 17, 27, 20, + 19, 8, 15, -6, -1, 10, -12, -29, -6, -23, -18, -3, + -1, 5, 3, -4, -12, -8, -1, -14, 65, 48, 58, 43, + 48, 19, 39, 39, 57, 57, 58, 55, 67, 58, 49, 50, + 70, 27, 9, 16, 37, 4, 25, 4, 11, 9, 7, -33, + -7, -12, 3, -6, -29, -7, -7, -18, -12, -18, -2, -1, + 0, 31, 60, -8, 51, 59, 70, 40, 71, 57, 52, 38, + 66, 48, 17, 6, 59, 8, 15, 7, 18, 4, 18, -23, + -8, -4, -3, -12, -3, -26, 1, 10, 2, -29, -29, -37, + -7, -4, 6, -33, 67, 44, 59, -4, 64, 51, 68, 55, + 74, 9, 40, 15, 57, 33, 60, 18, 40, 25, 27, -20, + 25, -16, 6, 17, -10, -12, -23, -43, -23, -23, -29, -37, + -4, -16, -16, -60, -20, -23, -10, -29, -12, 15, 12, -37, + 27, 15, 61, 44, 50, 8, 48, 22, 49, -18, 46, 33, + 42, 34, 46, -8, 4, -18, -43, -43, -10, 1, -10, -16, + -10, -77, -16, -33, 11, -26, -23, -37, 0, -8, -16, -29, + 42, 40, 68, 24, 47, 46, 53, -128, 30, 2, 42, 21, + 21, -4, 43, 2, 43, 5, 32, -26, 7, -37, -43, -23, + -2, -8, 2, -37, -50, -60, -1, -7, -33, -77, -6, -18, + -16, -50, -12, -33, 53, 8, 52, 18, 51, 35, 69, 26, + 44, 8, 27, -128, 21, -33, 17, -14, 38, -128, -14, -18, + 17, -20, -14, -37, 8, -60, -33, -33, -33, -43, -12, -29, + -12, -128, -33, -60, -26, -77, -26, -50, 57, 29, 11, 30, + 53, -10, 45, 15, 18, -10, 42, 2, 31, -29, 10, -4, + 42, -37, -50, -128, -4, -43, -20, -77, -14, -26, -33, -128, + -12, -43, -8, -33, -33, -60, -43, -77, -12, -60, -26, -50, + 40, -23, 36, 35, 50, -2, 37, 27, 26, -77, 49, -7, + 28, -43, 6, 11, 41, -37, 33, -26, -14, -12, -6, -33, + -16, -26, -20, -77, -14, -43, -8, -50, -14, -37, -26, -77, + -26, -77, -14, -29, 50, -60, 25, -26, 57, 38, 51, 1, + 50, 1, 53, -18, 30, -23, 11, -128, 18, -43, 20, -26, + -10, -26, -12, -128, -50, -60, -37, -77, -20, -43, -50, -128, + -77, -128, -77, -128, -33, -77, -20, -60, 53, -10, -37, -128, + 10, -128, 60, 18, -8, 13, 37, -37, 8, -128, 3, -77, + 32, -29, 14, 10, -12, -77, -37, -77, -37, -60, -23, -128, + -43, -50, -16, -77, -6, -33, 0, -60, -43, -128, -16, -60, + 20, -2, 51, 19, 43, 2, 63, 20, 60, -4, 42, -50, + 4, -128, 2, -3, 32, -33, -26, -128, -18, -128, -33, -43, + -7, -60, -50, -77, -29, -77, -23, -128, -16, -26, -23, -60, + -37, -77, -37, -128, -1, -33, 39, 48, 60, 5, 8, -128, + 44, 11, 4, 0, 13, -77, -2, -20, 33, -128, -33, -77, + -8, -128, -14, -128, -33, -18, -12, -77, -16, -128, -37, -128, + -12, -77, -60, -128, -23, -60, -23, -128, 36, -50, 46, -128, + 66, 39, 18, -14, -12, -77, -20, -6, 24, -128, 28, -26, + 21, -77, -6, -33, 1, -128, -43, -128, -1, -50, -37, -128, + -50, -128, -33, -128, -18, -128, -60, -8, -7, -60, -60, -128, + -6, -29, 20, -1, 73, 40, -43, -14, 33, -43, 33, -3, + 15, -29, 29, -43, 20, -60, -29, -128, -20, -26, 4, -77, + -16, -60, -33, -50, -29, -128, -60, -128, -77, -128, -37, -50, + 0, -77, -33, -128, 39, 8, 47, 10, 62, 16, 2, 1, + 10, 7, 4, -7, 6, -128, -77, -50, 19, -77, -77, -128, + -77, -128, -50, -128, -60, -60, -33, -50, -37, -128, -128, -128, + -60, -128, -37, -60, -18, -128, -33, -77, 37, 23, 29, -128, + -128, -128, -16, -128, -16, -33, 21, -20, -8, -60, -2, -60, + 11, -128, -50, -128, -50, -128, -29, -77, -16, -128, -26, -128, + -50, -77, -43, -128, -128, -128, -50, -128, -33, -128, -33, -50, + -23, -128, 24, -128, -128, -77, 4, -23, 32, -128, 1, -26, + -14, -128, 10, -77, -4, -128, 1, -50, -8, -77, -77, -77, + -23, -128, -50, -43, -33, -128, -43, -128, -128, -128, -43, -128, + -50, -128, -128, -128, 44, 15, 14, -128, 9, -128, 21, 0, + 29, -7, 18, -7, -7, -128, -33, -50, 14, -60, -60, -128, + -60, -128, -37, -128, -43, -128, -20, -128, -50, -128, -43, -77, + -26, -128, -60, -50, -60, -128, -77, -128, -3, -128, 14, -77, + -26, 11, 47, -77, -7, -77, 45, -43, -12, 14, 37, -60, + 22, -4, 5, -77, -14, -128, -10, -60, 22, -77, -12, -60, + -50, -128, -60, -128, -60, -128, -43, -128, -50, -128, -77, -50, + 27, -37, 33, -128, 4, -29, -4, -50, -20, -128, 6, -37, + -33, -128, -50, -128, 34, 15, -43, -128, -20, -50, -3, -37, + -37, -77, -77, -128, -43, -128, -128, -128, 4, -26, -26, 27, + 0, -128, -29, -60, 35, -26, 23, -128, -29, -77, 19, 14, + 28, -128, -16, -7, 31, -1, 17, 11, 60, 44, 8, 11, + 18, -128, -33, -60, -1, -128, -43, -128, -23, -128, -128, -128, + 59, 43, 35, 61, 37, -77, -77, -50, 116, 88, 98, 69, + 78, 53, 78, 40, 48, 7, 29, -18, -2, -14, 5, 12, + 65, 35, 31, -12, 33, -2, -6, -1, 44, -29, -14, -60, + -4, -43, -37, -128, 29, 18, 38, 51, 8, -128, -12, -37, + 115, 91, 113, 77, 89, 36, 60, 44, 49, 36, 27, 31, + 63, 30, 62, 14, 55, 49, 42, 0, 45, 17, -23, 1, + 30, -37, -50, -77, -8, -60, 9, -60, -12, -50, 13, 4, + 23, -6, 28, 13, 107, 78, 101, 73, 89, 46, 63, 17, + 34, -43, -6, 30, 67, 40, 77, 21, 53, 39, 38, 12, + -6, 5, 28, -2, 18, -43, 0, -128, -29, -77, 18, -128, + -2, -77, 39, 35, 38, 35, 50, 29, 100, 70, 94, 69, + 86, 50, 45, 38, 45, 12, 58, 64, 74, 36, 77, 45, + 78, 62, 8, -60, 38, 6, 21, 7, 8, -37, -1, -20, + 48, -37, 8, -10, 8, 13, 45, 39, 38, 22, 49, 25, + 94, 63, 87, 66, 84, -128, 29, 20, 55, 51, 80, 36, + 62, 30, 81, 72, 68, 37, 51, 27, 54, 22, 16, -29, + 4, 9, 57, 15, 35, -43, -77, -20, 4, 6, 37, -1, + 40, 31, 47, 14, 89, 68, 96, 83, 111, 96, 115, 87, + 99, 76, 105, 84, 105, 86, 113, 91, 108, 87, 110, 78, + 80, 46, 22, 74, 88, 72, 103, 86, 80, 68, 48, 24, + 68, 48, 55, 36, 108, 90, 90, 63, 83, 63, 87, 64, + 90, 92, 113, 88, 102, 79, 109, 83, 100, 89, 109, 60, + 56, 21, 75, 62, 81, 45, 63, 73, 93, 65, 94, 80, + 89, 81, 73, 3, 43, 60, 102, 70, 84, 67, 99, 74, + 78, 57, 79, 50, 93, 82, 98, 56, 77, 70, 91, 71, + 85, 82, 86, 13, 45, -18, 48, 40, 53, 28, 85, 60, + 65, 52, 86, 78, 76, 46, 73, 19, 35, 54, 75, 40, + 71, 60, 82, 37, 69, 42, 62, 40, 96, 70, 85, 77, + 70, 68, 103, 84, 94, 69, 81, -128, -128, -128, -43, -37, + 40, 2, 48, 45, 76, 37, 65, 16, 43, 18, 58, 20, + 27, 12, 71, 31, 53, 44, 88, 47, 50, 33, 39, 8, + 89, 57, 88, 69, 72, 63, 100, 68, 81, -77, -10, -128, + -128, -128, -128, -128, 13, -77, 8, 27, 60, 28, 41, -128, + -37, -128, 28, -43, -18, -128, 47, -37, 45, 27, 51, -29, + 15, 39, 52, 30, 49, -33, 65, 15, 76, 71, 90, 19, + 46, -128, -16, -128, -128, -128, -128, -128, -128, -128, -18, -128, + -20, -128, 32, -128, 21, -33, 45, -128, -128, -128, -12, -128, + -6, -14, 43, -128, -128, -128, -128, -128, 52, -18, 69, -43, + 78, 55, 42, -128, -29, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, 14, -128, -16, -128, -128, -128, 7, -128, + -128, -128, -128, -128, -128, -128, 12, -128, -128, -128, -128, -16, + 59, -50, 35, -128, 42, 0, 47, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -33, -128, -23, -128, + -128, -128, -23, -128, -128, -128, -128, -128, -128, -128, -33, -128, + -128, -128, -128, -128, -128, -128, -8, -128, 36, -50, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -37, -128, -128, -60, -10, -128, -128, -128, -128, -128, + -128, -128, 21, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -12, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -77, -128, -128, -128, -29, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -29, -128, -128, -128, -128, -128, -128, -128, -128, -128, -50, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, +}; diff --git a/micro_speech/src/micro_features/no_micro_features_data.h b/micro_speech/src/micro_features/no_micro_features_data.h new file mode 100644 index 0000000..8c1b6d5 --- /dev/null +++ b/micro_speech/src/micro_features/no_micro_features_data.h @@ -0,0 +1,23 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_MICRO_FEATURES_NO_MICRO_FEATURES_DATA_H_ +#define TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_MICRO_FEATURES_NO_MICRO_FEATURES_DATA_H_ + +extern const int g_no_micro_f9643d42_nohash_4_width; +extern const int g_no_micro_f9643d42_nohash_4_height; +extern const signed char g_no_micro_f9643d42_nohash_4_data[]; + +#endif // TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_MICRO_FEATURES_NO_MICRO_FEATURES_DATA_H_ diff --git a/micro_speech/src/micro_features/static_alloc.h b/micro_speech/src/micro_features/static_alloc.h new file mode 100644 index 0000000..602445d --- /dev/null +++ b/micro_speech/src/micro_features/static_alloc.h @@ -0,0 +1,33 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_MICRO_FEATURES_STATIC_ALLOC_H_ +#define TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_MICRO_FEATURES_STATIC_ALLOC_H_ + +// Checks to ensure that the C-style array passed in has a compile-time size of +// at least the number of bytes requested. This doesn't work with raw pointers +// since sizeof() doesn't know their actual length, so only use this to check +// statically-allocated arrays with known sizes. +#define STATIC_ALLOC_ENSURE_ARRAY_SIZE(A, N) \ + do { \ + if (sizeof(A) < (N)) { \ + TF_LITE_REPORT_ERROR(error_reporter, \ + #A " too small (%d bytes, wanted %d) at %s:%d", \ + sizeof(A), (N), __FILE__, __LINE__); \ + return 0; \ + } \ + } while (0) + +#endif // TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_MICRO_FEATURES_STATIC_ALLOC_H_ diff --git a/micro_speech/src/micro_features/yes_feature_data_slice.cc b/micro_speech/src/micro_features/yes_feature_data_slice.cc new file mode 100644 index 0000000..e3f6e20 --- /dev/null +++ b/micro_speech/src/micro_features/yes_feature_data_slice.cc @@ -0,0 +1,24 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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. +==============================================================================*/ + +// See the header for documentation on the meaning of this data. + +#include "micro_features/yes_feature_data_slice.h" + +const int8_t g_yes_feature_data_slice[g_yes_feature_data_slice_size] = { + 86, 88, 108, 75, 108, 76, 98, 64, 75, 61, 71, 66, 85, -1, + -77, -128, 46, 61, 92, 69, 100, 93, 113, 80, 108, 93, 113, 91, + 110, 80, 85, 15, -33, -128, 12, -50, 34, 50, 70, 55, +}; diff --git a/micro_speech/src/micro_features/yes_feature_data_slice.h b/micro_speech/src/micro_features/yes_feature_data_slice.h new file mode 100644 index 0000000..18faadc --- /dev/null +++ b/micro_speech/src/micro_features/yes_feature_data_slice.h @@ -0,0 +1,29 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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. +==============================================================================*/ + +// This data was extracted from the larger feature data held in +// no_micro_features_data.cc and consists of the 26th spectrogram slice of 40 +// values. This is the expected result of running the sample data in +// yes_30ms_sample_data.cc through the preprocessing pipeline. + +#ifndef TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_MICRO_FEATURES_YES_FEATURE_DATA_SLICE_H_ +#define TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_MICRO_FEATURES_YES_FEATURE_DATA_SLICE_H_ + +#include + +constexpr int g_yes_feature_data_slice_size = 40; +extern const int8_t g_yes_feature_data_slice[]; + +#endif // TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_MICRO_FEATURES_YES_FEATURE_DATA_SLICE_H_ diff --git a/micro_speech/src/micro_features/yes_micro_features_data.cc b/micro_speech/src/micro_features/yes_micro_features_data.cc new file mode 100644 index 0000000..09a40cc --- /dev/null +++ b/micro_speech/src/micro_features/yes_micro_features_data.cc @@ -0,0 +1,188 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 "micro_features/yes_micro_features_data.h" + +// Golden test values for the expected spectrogram from a "yes" sample file +// speech_commands_test_set_v0.02/yes/f2e59fea_nohash_1.wav. + +const int g_yes_micro_f2e59fea_nohash_1_width = 40; +const int g_yes_micro_f2e59fea_nohash_1_height = 49; +const signed char g_yes_micro_f2e59fea_nohash_1_data[] = { + 116, 98, 118, 95, 106, 85, 101, 81, 67, -18, -33, -12, + -26, -128, 9, 34, 56, 45, 9, -12, 5, 30, 23, 28, + 0, -18, 0, -128, -60, -50, -50, -37, -60, -60, -50, -26, + -33, -50, -33, -50, 83, 61, 81, 55, 76, 61, 73, 64, + 38, -8, -37, -20, -18, -20, 48, 29, 52, 41, 55, 18, + 25, 37, 44, 37, 8, 15, -6, -60, -128, -50, -37, -37, + -18, -37, -26, -29, -37, -60, -50, -60, 95, 59, 52, -4, + 54, -18, 68, 43, 31, -18, -26, -33, -37, -29, 33, 7, + -3, 8, 26, 24, 36, 6, 36, 23, 14, 8, -29, -37, + -37, -37, -50, -50, -26, -8, -26, -37, -18, -37, -60, -77, + 50, 48, 83, 44, 56, -128, -33, -60, 1, -26, -60, -43, + -14, -23, -18, -43, -26, -33, 13, -77, -43, -77, -33, -37, + 16, -12, -37, -50, -50, -77, -20, -43, -60, -128, -60, -77, + -37, -77, -60, -128, 37, -10, 65, -7, 28, -128, 10, -77, + -37, -128, -77, -128, -77, -43, -128, -128, -77, -128, -128, -128, + -128, -128, -14, -128, -43, -50, -37, -77, -128, -128, -77, -43, + -29, -43, -20, -60, -37, -43, -50, -128, -77, -128, -18, -128, + -60, -128, -128, -128, -77, -128, -77, -128, -128, -128, -60, -37, + -20, -128, -60, -128, -128, -128, -60, -128, -77, -60, -128, -50, + -60, -128, -77, -128, -50, -60, -37, -60, -50, -77, -77, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -37, -128, + -128, -128, -128, -128, -77, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -77, -60, -128, -128, -50, -128, -50, -128, + -50, -128, -77, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -77, -128, -77, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -77, -128, -77, -128, -77, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -77, -128, -128, -128, + -128, -77, -50, -128, -128, -77, -77, -128, -128, -128, -50, -128, + 85, 43, 65, 53, 69, 60, 45, 3, 46, -12, 9, -23, + 32, -1, -128, -128, -128, -128, -1, 37, 38, 33, 43, 36, + 58, 70, 68, 39, 6, 10, 32, 6, 8, -23, -77, -128, + -29, -128, -77, -128, 101, 87, 102, 91, 110, 88, 101, 83, + 110, 95, 111, 83, 81, 84, 106, 90, 93, 82, 98, 91, + 108, 95, 118, 97, 118, 97, 116, 96, 113, 90, 110, 96, + 107, 85, 94, 66, 69, 36, 29, 0, 100, 60, 105, 68, + 92, 93, 113, 92, 107, 85, 107, 83, 104, 91, 105, 85, + 112, 88, 101, 80, 101, 79, 96, 80, 98, 80, 105, 83, + 98, 81, 103, 71, 100, 79, 83, 78, 91, 47, 50, 13, + 108, 81, 93, 78, 98, 76, 105, 76, 98, 40, 77, 72, + 81, 62, 93, 77, 96, 80, 98, 61, 97, 69, 88, 61, + 71, 56, 98, 68, 97, 72, 89, 51, 81, 61, 88, 75, + 86, 56, 48, 13, 71, 22, 84, 66, 76, -7, 48, 61, + 77, 62, 91, 65, 95, 74, 88, 59, 75, 58, 83, 55, + 87, 55, 76, 43, 76, -3, 56, 60, 79, 57, 71, 54, + 82, 33, 74, 71, 91, 45, 18, -7, 61, 56, 77, 41, + 73, 42, 82, 49, 59, 63, 82, 65, 66, 38, 83, 34, + 48, -8, 46, 20, 54, 33, 54, 6, 48, 16, 60, 37, + 58, 22, 58, 14, 65, 53, 75, -4, 42, 16, 16, -50, + 22, -128, 80, 54, 43, -50, 42, -128, -10, -77, 28, -29, + 68, 43, 73, 2, 25, -60, 47, 14, 45, 7, 66, 4, + 62, 37, 71, 7, 46, -10, 44, 22, 55, 53, 57, -29, + 26, -10, -3, -128, 38, -128, 46, -10, 16, -128, -10, -26, + 60, -7, 65, 38, 70, -60, 35, -8, 42, -29, 6, -128, + 34, -128, 36, -60, 44, -12, -2, -128, -7, -60, -60, -128, + -23, -128, 31, -33, 22, -77, -37, -43, -128, -128, 3, -128, + -23, -128, 17, -77, 43, -77, -7, -128, -20, -128, 17, -43, + 32, -128, -43, -128, -128, -77, 21, -128, -50, -128, -128, -128, + -128, -128, -128, -128, -37, -128, -16, -128, -50, -26, -6, -128, + -128, -128, -128, -128, -23, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -16, -128, 36, -7, 16, -128, -128, -128, -128, -128, + -77, -128, -37, -128, -50, -128, -128, -128, -128, -128, -18, -128, + 11, -128, -16, -77, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -26, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -20, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -50, -128, -77, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -77, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -1, -18, 5, -128, + 40, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, 4, -128, 63, 66, 75, -128, + 70, 60, 34, -128, -128, -128, -128, -128, -128, -128, -128, -128, + 87, 86, 95, 76, 91, 62, 72, -6, -50, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, 64, 83, 104, 70, + 98, 90, 111, 89, 109, 80, 71, -128, -128, -128, -128, -128, + -20, -6, 27, 33, 86, 88, 108, 75, 108, 76, 98, 64, + 75, 61, 71, 66, 85, -1, -77, -128, 46, 61, 92, 69, + 100, 93, 113, 80, 108, 93, 113, 91, 110, 80, 85, 15, + -33, -128, 12, -50, 34, 50, 70, 55, 84, 72, 108, 81, + 111, 88, 100, 80, 84, 73, 97, 86, 99, 65, 85, 43, + 96, 78, 107, 94, 118, 98, 115, 92, 118, 94, 111, 93, + 111, 86, 99, 52, 32, -16, 48, 31, 81, 74, 85, 64, + 78, 64, 98, 70, 110, 92, 96, 73, 100, 72, 94, 73, + 98, 76, 85, 67, 101, 83, 101, 83, 112, 89, 98, 85, + 105, 78, 98, 72, 102, 80, 95, 23, 19, -8, 52, 57, + 103, 91, 95, 65, 74, 8, 77, 49, 96, 76, 100, 87, + 105, 81, 94, 62, 94, 78, 81, 72, 99, 82, 101, 78, + 108, 65, 82, 70, 100, 63, 79, 58, 80, 59, 87, 48, + 50, 57, 93, 67, 86, 80, 103, 56, 77, 31, 81, 57, + 62, 41, 96, 85, 91, 71, 101, 76, 89, 78, 95, 76, + 96, 79, 103, 81, 103, 48, 70, 57, 88, 66, 84, 11, + 85, 67, 104, 37, 38, 67, 90, 54, 81, 62, 90, 52, + 78, -60, 54, -8, 68, 40, 55, 8, 77, 52, 66, 31, + 55, 13, 60, 26, 69, 42, 63, -29, 57, -128, -3, -128, + 3, -128, -29, -60, 52, -43, 63, 56, 86, 75, 95, 75, + 85, 63, 82, 10, 50, -128, 31, -77, 0, -77, -23, -128, + 12, -77, 51, -3, 58, -14, 44, 0, 48, 4, 53, 47, + 28, -128, -128, -128, -37, -128, -3, -128, 49, 61, 100, 90, + 117, 88, 107, 94, 112, 64, 96, 83, -128, -128, 7, -128, + -77, -128, -23, -128, -23, -128, 16, -37, 65, -8, 48, 20, + 14, -77, 57, -18, -43, -128, -128, -128, -128, -128, -128, -128, + 24, 12, 74, 76, 105, 76, 99, 80, 108, 79, 103, 85, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + 42, -128, -8, -128, -50, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -60, -128, -128, 5, 73, 53, 93, 70, 101, 73, + 94, 57, 86, 66, -18, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -50, -128, 36, -128, -128, -128, -128, -128, -20, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, 23, 37, + 75, 54, 97, 70, 83, 52, 85, 65, 7, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -43, -128, 23, -128, -43, -128, + -33, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -26, -37, 65, 33, 76, 37, 73, 50, 77, 47, + -12, -128, -128, -128, -128, -128, -128, -128, -128, -128, -7, -14, + -4, -128, -14, -128, 18, -60, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -26, -60, 71, 42, 68, 53, + 81, 49, 73, 36, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -18, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, 15, -26, + 44, -18, 59, 39, 57, 20, 62, 26, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, 49, -128, 30, 8, 69, 27, 62, 38, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -43, -128, 28, -37, 48, -10, + 48, 11, 74, 37, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -77, -128, 11, -128, -7, -60, -77, -4, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -8, -128, -50, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, +}; diff --git a/micro_speech/src/micro_features/yes_micro_features_data.h b/micro_speech/src/micro_features/yes_micro_features_data.h new file mode 100644 index 0000000..cd1ad10 --- /dev/null +++ b/micro_speech/src/micro_features/yes_micro_features_data.h @@ -0,0 +1,23 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_MICRO_FEATURES_YES_MICRO_FEATURES_DATA_H_ +#define TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_MICRO_FEATURES_YES_MICRO_FEATURES_DATA_H_ + +extern const int g_yes_micro_f2e59fea_nohash_1_width; +extern const int g_yes_micro_f2e59fea_nohash_1_height; +extern const signed char g_yes_micro_f2e59fea_nohash_1_data[]; + +#endif // TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_MICRO_FEATURES_YES_MICRO_FEATURES_DATA_H_ diff --git a/micro_speech/src/micro_speech_test.cc b/micro_speech/src/micro_speech_test.cc new file mode 100644 index 0000000..c79dd89 --- /dev/null +++ b/micro_speech/src/micro_speech_test.cc @@ -0,0 +1,148 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 "micro_features/model.h" +#include "micro_features/no_micro_features_data.h" +#include "micro_features/yes_micro_features_data.h" +#include "tensorflow/lite/micro/micro_error_reporter.h" +#include "tensorflow/lite/micro/micro_interpreter.h" +#include "tensorflow/lite/micro/micro_mutable_op_resolver.h" +#include "tensorflow/lite/micro/testing/micro_test.h" +#include "tensorflow/lite/schema/schema_generated.h" + +TF_LITE_MICRO_TESTS_BEGIN + +TF_LITE_MICRO_TEST(TestInvoke) { + // Set up logging. + tflite::MicroErrorReporter micro_error_reporter; + + // Map the model into a usable data structure. This doesn't involve any + // copying or parsing, it's a very lightweight operation. + const tflite::Model* model = ::tflite::GetModel(g_model); + if (model->version() != TFLITE_SCHEMA_VERSION) { + TF_LITE_REPORT_ERROR(µ_error_reporter, + "Model provided is schema version %d not equal " + "to supported version %d.\n", + model->version(), TFLITE_SCHEMA_VERSION); + } + + // Pull in only the operation implementations we need. + // This relies on a complete list of all the ops needed by this graph. + // An easier approach is to just use the AllOpsResolver, but this will + // incur some penalty in code space for op implementations that are not + // needed by this graph. + // + // tflite::AllOpsResolver resolver; + tflite::MicroMutableOpResolver<4> micro_op_resolver; + micro_op_resolver.AddDepthwiseConv2D(); + micro_op_resolver.AddFullyConnected(); + micro_op_resolver.AddReshape(); + micro_op_resolver.AddSoftmax(); + + // Create an area of memory to use for input, output, and intermediate arrays. +#if defined(XTENSA) + constexpr int tensor_arena_size = 15 * 1024; +#else + constexpr int tensor_arena_size = 10 * 1024; +#endif + uint8_t tensor_arena[tensor_arena_size]; + + // Build an interpreter to run the model with. + tflite::MicroInterpreter interpreter(model, micro_op_resolver, tensor_arena, + tensor_arena_size, + µ_error_reporter); + interpreter.AllocateTensors(); + + // Get information about the memory area to use for the model's input. + TfLiteTensor* input = interpreter.input(0); + + // Make sure the input has the properties we expect. + TF_LITE_MICRO_EXPECT_NE(nullptr, input); + TF_LITE_MICRO_EXPECT_EQ(2, input->dims->size); + TF_LITE_MICRO_EXPECT_EQ(1, input->dims->data[0]); + TF_LITE_MICRO_EXPECT_EQ(1960, input->dims->data[1]); + TF_LITE_MICRO_EXPECT_EQ(kTfLiteInt8, input->type); + + // Copy a spectrogram created from a .wav audio file of someone saying "Yes", + // into the memory area used for the input. + const int8_t* yes_features_data = g_yes_micro_f2e59fea_nohash_1_data; + for (size_t i = 0; i < input->bytes; ++i) { + input->data.int8[i] = yes_features_data[i]; + } + + // Run the model on this input and make sure it succeeds. + TfLiteStatus invoke_status = interpreter.Invoke(); + if (invoke_status != kTfLiteOk) { + TF_LITE_REPORT_ERROR(µ_error_reporter, "Invoke failed\n"); + } + TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, invoke_status); + + // Get the output from the model, and make sure it's the expected size and + // type. + TfLiteTensor* output = interpreter.output(0); + TF_LITE_MICRO_EXPECT_EQ(2, output->dims->size); + TF_LITE_MICRO_EXPECT_EQ(1, output->dims->data[0]); + TF_LITE_MICRO_EXPECT_EQ(4, output->dims->data[1]); + TF_LITE_MICRO_EXPECT_EQ(kTfLiteInt8, output->type); + + // There are four possible classes in the output, each with a score. + const int kSilenceIndex = 0; + const int kUnknownIndex = 1; + const int kYesIndex = 2; + const int kNoIndex = 3; + + // Make sure that the expected "Yes" score is higher than the other classes. + uint8_t silence_score = output->data.int8[kSilenceIndex] + 128; + uint8_t unknown_score = output->data.int8[kUnknownIndex] + 128; + uint8_t yes_score = output->data.int8[kYesIndex] + 128; + uint8_t no_score = output->data.int8[kNoIndex] + 128; + TF_LITE_MICRO_EXPECT_GT(yes_score, silence_score); + TF_LITE_MICRO_EXPECT_GT(yes_score, unknown_score); + TF_LITE_MICRO_EXPECT_GT(yes_score, no_score); + + // Now test with a different input, from a recording of "No". + const int8_t* no_features_data = g_no_micro_f9643d42_nohash_4_data; + for (size_t i = 0; i < input->bytes; ++i) { + input->data.int8[i] = no_features_data[i]; + } + + // Run the model on this "No" input. + invoke_status = interpreter.Invoke(); + if (invoke_status != kTfLiteOk) { + TF_LITE_REPORT_ERROR(µ_error_reporter, "Invoke failed\n"); + } + TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, invoke_status); + + // Get the output from the model, and make sure it's the expected size and + // type. + output = interpreter.output(0); + TF_LITE_MICRO_EXPECT_EQ(2, output->dims->size); + TF_LITE_MICRO_EXPECT_EQ(1, output->dims->data[0]); + TF_LITE_MICRO_EXPECT_EQ(4, output->dims->data[1]); + TF_LITE_MICRO_EXPECT_EQ(kTfLiteInt8, output->type); + + // Make sure that the expected "No" score is higher than the other classes. + silence_score = output->data.int8[kSilenceIndex] + 128; + unknown_score = output->data.int8[kUnknownIndex] + 128; + yes_score = output->data.int8[kYesIndex] + 128; + no_score = output->data.int8[kNoIndex] + 128; + TF_LITE_MICRO_EXPECT_GT(no_score, silence_score); + TF_LITE_MICRO_EXPECT_GT(no_score, unknown_score); + TF_LITE_MICRO_EXPECT_GT(no_score, yes_score); + + TF_LITE_REPORT_ERROR(µ_error_reporter, "Ran successfully\n"); +} + +TF_LITE_MICRO_TESTS_END diff --git a/micro_speech/src/microfrontend/lib/bits.h b/micro_speech/src/microfrontend/lib/bits.h new file mode 100644 index 0000000..04b3ba6 --- /dev/null +++ b/micro_speech/src/microfrontend/lib/bits.h @@ -0,0 +1,102 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_BITS_H_ +#define TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_BITS_H_ + +#ifdef __cplusplus +#include + +extern "C" { +#endif + +static inline int CountLeadingZeros32Slow(uint64_t n) { + int zeroes = 28; + if (n >> 16) zeroes -= 16, n >>= 16; + if (n >> 8) zeroes -= 8, n >>= 8; + if (n >> 4) zeroes -= 4, n >>= 4; + return "\4\3\2\2\1\1\1\1\0\0\0\0\0\0\0"[n] + zeroes; +} + +static inline int CountLeadingZeros32(uint32_t n) { +#if defined(_MSC_VER) + unsigned long result = 0; // NOLINT(runtime/int) + if (_BitScanReverse(&result, n)) { + return 31 - result; + } + return 32; +#elif defined(__GNUC__) + + // Handle 0 as a special case because __builtin_clz(0) is undefined. + if (n == 0) { + return 32; + } + return __builtin_clz(n); +#else + return CountLeadingZeros32Slow(n); +#endif +} + +static inline int MostSignificantBit32(uint32_t n) { + return 32 - CountLeadingZeros32(n); +} + +static inline int CountLeadingZeros64Slow(uint64_t n) { + int zeroes = 60; + if (n >> 32) zeroes -= 32, n >>= 32; + if (n >> 16) zeroes -= 16, n >>= 16; + if (n >> 8) zeroes -= 8, n >>= 8; + if (n >> 4) zeroes -= 4, n >>= 4; + return "\4\3\2\2\1\1\1\1\0\0\0\0\0\0\0"[n] + zeroes; +} + +static inline int CountLeadingZeros64(uint64_t n) { +#if defined(_MSC_VER) && defined(_M_X64) + // MSVC does not have __builtin_clzll. Use _BitScanReverse64. + unsigned long result = 0; // NOLINT(runtime/int) + if (_BitScanReverse64(&result, n)) { + return 63 - result; + } + return 64; +#elif defined(_MSC_VER) + // MSVC does not have __builtin_clzll. Compose two calls to _BitScanReverse + unsigned long result = 0; // NOLINT(runtime/int) + if ((n >> 32) && _BitScanReverse(&result, n >> 32)) { + return 31 - result; + } + if (_BitScanReverse(&result, n)) { + return 63 - result; + } + return 64; +#elif defined(__GNUC__) + + // Handle 0 as a special case because __builtin_clzll(0) is undefined. + if (n == 0) { + return 64; + } + return __builtin_clzll(n); +#else + return CountLeadingZeros64Slow(n); +#endif +} + +static inline int MostSignificantBit64(uint64_t n) { + return 64 - CountLeadingZeros64(n); +} + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_BITS_H_ diff --git a/micro_speech/src/microfrontend/lib/fft.cc b/micro_speech/src/microfrontend/lib/fft.cc new file mode 100644 index 0000000..f605b1d --- /dev/null +++ b/micro_speech/src/microfrontend/lib/fft.cc @@ -0,0 +1,53 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 "microfrontend/lib/fft.h" + +#include + +#define FIXED_POINT 16 +#include "kiss_fft.h" +#include "tools/kiss_fftr.h" + +void FftCompute(struct FftState* state, const int16_t* input, + int input_scale_shift) { + const size_t input_size = state->input_size; + const size_t fft_size = state->fft_size; + + int16_t* fft_input = state->input; + // First, scale the input by the given shift. + size_t i; + for (i = 0; i < input_size; ++i) { + fft_input[i] = static_cast(static_cast(input[i]) + << input_scale_shift); + } + // Zero out whatever else remains in the top part of the input. + for (; i < fft_size; ++i) { + fft_input[i] = 0; + } + + // Apply the FFT. + kiss_fftr(reinterpret_cast(state->scratch), + state->input, + reinterpret_cast(state->output)); +} + +void FftInit(struct FftState* state) { + // All the initialization is done in FftPopulateState() +} + +void FftReset(struct FftState* state) { + memset(state->input, 0, state->fft_size * sizeof(*state->input)); + memset(state->output, 0, (state->fft_size / 2 + 1) * sizeof(*state->output)); +} diff --git a/micro_speech/src/microfrontend/lib/fft.h b/micro_speech/src/microfrontend/lib/fft.h new file mode 100644 index 0000000..aaffa69 --- /dev/null +++ b/micro_speech/src/microfrontend/lib/fft.h @@ -0,0 +1,50 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_FFT_H_ +#define TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_FFT_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct complex_int16_t { + int16_t real; + int16_t imag; +}; + +struct FftState { + int16_t* input; + struct complex_int16_t* output; + size_t fft_size; + size_t input_size; + void* scratch; + size_t scratch_size; +}; + +void FftCompute(struct FftState* state, const int16_t* input, + int input_scale_shift); + +void FftInit(struct FftState* state); + +void FftReset(struct FftState* state); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_FFT_H_ diff --git a/micro_speech/src/microfrontend/lib/fft_util.cc b/micro_speech/src/microfrontend/lib/fft_util.cc new file mode 100644 index 0000000..95d618a --- /dev/null +++ b/micro_speech/src/microfrontend/lib/fft_util.cc @@ -0,0 +1,72 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 "microfrontend/lib/fft_util.h" + +#include + +#define FIXED_POINT 16 +#include "kiss_fft.h" +#include "tools/kiss_fftr.h" + +int FftPopulateState(struct FftState* state, size_t input_size) { + state->input_size = input_size; + state->fft_size = 1; + while (state->fft_size < state->input_size) { + state->fft_size <<= 1; + } + + state->input = reinterpret_cast( + malloc(state->fft_size * sizeof(*state->input))); + if (state->input == nullptr) { + fprintf(stderr, "Failed to alloc fft input buffer\n"); + return 0; + } + + state->output = reinterpret_cast( + malloc((state->fft_size / 2 + 1) * sizeof(*state->output) * 2)); + if (state->output == nullptr) { + fprintf(stderr, "Failed to alloc fft output buffer\n"); + return 0; + } + + // Ask kissfft how much memory it wants. + size_t scratch_size = 0; + kiss_fftr_cfg kfft_cfg = kiss_fftr_alloc( + state->fft_size, 0, nullptr, &scratch_size); + if (kfft_cfg != nullptr) { + fprintf(stderr, "Kiss memory sizing failed.\n"); + return 0; + } + state->scratch = malloc(scratch_size); + if (state->scratch == nullptr) { + fprintf(stderr, "Failed to alloc fft scratch buffer\n"); + return 0; + } + state->scratch_size = scratch_size; + // Let kissfft configure the scratch space we just allocated + kfft_cfg = kiss_fftr_alloc(state->fft_size, 0, + state->scratch, &scratch_size); + if (kfft_cfg != state->scratch) { + fprintf(stderr, "Kiss memory preallocation strategy failed.\n"); + return 0; + } + return 1; +} + +void FftFreeStateContents(struct FftState* state) { + free(state->input); + free(state->output); + free(state->scratch); +} diff --git a/micro_speech/src/microfrontend/lib/fft_util.h b/micro_speech/src/microfrontend/lib/fft_util.h new file mode 100644 index 0000000..3e58d71 --- /dev/null +++ b/micro_speech/src/microfrontend/lib/fft_util.h @@ -0,0 +1,34 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_FFT_UTIL_H_ +#define TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_FFT_UTIL_H_ + +#include "microfrontend/lib/fft.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Prepares and FFT for the given input size. +int FftPopulateState(struct FftState* state, size_t input_size); + +// Frees any allocated buffers. +void FftFreeStateContents(struct FftState* state); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_FFT_UTIL_H_ diff --git a/micro_speech/src/microfrontend/lib/filterbank.c b/micro_speech/src/microfrontend/lib/filterbank.c new file mode 100644 index 0000000..4ca79c5 --- /dev/null +++ b/micro_speech/src/microfrontend/lib/filterbank.c @@ -0,0 +1,134 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 "microfrontend/lib/filterbank.h" + +#include + +#include "microfrontend/lib/bits.h" + +void FilterbankConvertFftComplexToEnergy(struct FilterbankState* state, + struct complex_int16_t* fft_output, + int32_t* energy) { + const int end_index = state->end_index; + int i; + energy += state->start_index; + fft_output += state->start_index; + for (i = state->start_index; i < end_index; ++i) { + const int32_t real = fft_output->real; + const int32_t imag = fft_output->imag; + fft_output++; + const uint32_t mag_squared = (real * real) + (imag * imag); + *energy++ = mag_squared; + } +} + +void FilterbankAccumulateChannels(struct FilterbankState* state, + const int32_t* energy) { + uint64_t* work = state->work; + uint64_t weight_accumulator = 0; + uint64_t unweight_accumulator = 0; + + const int16_t* channel_frequency_starts = state->channel_frequency_starts; + const int16_t* channel_weight_starts = state->channel_weight_starts; + const int16_t* channel_widths = state->channel_widths; + + int num_channels_plus_1 = state->num_channels + 1; + int i; + for (i = 0; i < num_channels_plus_1; ++i) { + const int32_t* magnitudes = energy + *channel_frequency_starts++; + const int16_t* weights = state->weights + *channel_weight_starts; + const int16_t* unweights = state->unweights + *channel_weight_starts++; + const int width = *channel_widths++; + int j; + for (j = 0; j < width; ++j) { + weight_accumulator += *weights++ * ((uint64_t)*magnitudes); + unweight_accumulator += *unweights++ * ((uint64_t)*magnitudes); + ++magnitudes; + } + *work++ = weight_accumulator; + weight_accumulator = unweight_accumulator; + unweight_accumulator = 0; + } +} + +static uint16_t Sqrt32(uint32_t num) { + if (num == 0) { + return 0; + } + uint32_t res = 0; + int max_bit_number = 32 - MostSignificantBit32(num); + max_bit_number |= 1; + uint32_t bit = 1U << (31 - max_bit_number); + int iterations = (31 - max_bit_number) / 2 + 1; + while (iterations--) { + if (num >= res + bit) { + num -= res + bit; + res = (res >> 1U) + bit; + } else { + res >>= 1U; + } + bit >>= 2U; + } + // Do rounding - if we have the bits. + if (num > res && res != 0xFFFF) { + ++res; + } + return res; +} + +static uint32_t Sqrt64(uint64_t num) { + // Take a shortcut and just use 32 bit operations if the upper word is all + // clear. This will cause a slight off by one issue for numbers close to 2^32, + // but it probably isn't going to matter (and gives us a big performance win). + if ((num >> 32) == 0) { + return Sqrt32((uint32_t)num); + } + uint64_t res = 0; + int max_bit_number = 64 - MostSignificantBit64(num); + max_bit_number |= 1; + uint64_t bit = 1ULL << (63 - max_bit_number); + int iterations = (63 - max_bit_number) / 2 + 1; + while (iterations--) { + if (num >= res + bit) { + num -= res + bit; + res = (res >> 1U) + bit; + } else { + res >>= 1U; + } + bit >>= 2U; + } + // Do rounding - if we have the bits. + if (num > res && res != 0xFFFFFFFFLL) { + ++res; + } + return res; +} + +uint32_t* FilterbankSqrt(struct FilterbankState* state, int scale_down_shift) { + const int num_channels = state->num_channels; + const uint64_t* work = state->work + 1; + // Reuse the work buffer since we're fine clobbering it at this point to hold + // the output. + uint32_t* output = (uint32_t*)state->work; + int i; + for (i = 0; i < num_channels; ++i) { + *output++ = Sqrt64(*work++) >> scale_down_shift; + } + return (uint32_t*)state->work; +} + +void FilterbankReset(struct FilterbankState* state) { + memset(state->work, 0, (state->num_channels + 1) * sizeof(*state->work)); +} diff --git a/micro_speech/src/microfrontend/lib/filterbank.h b/micro_speech/src/microfrontend/lib/filterbank.h new file mode 100644 index 0000000..5c0ac1c --- /dev/null +++ b/micro_speech/src/microfrontend/lib/filterbank.h @@ -0,0 +1,63 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_FILTERBANK_H_ +#define TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_FILTERBANK_H_ + +#include +#include + +#include "microfrontend/lib/fft.h" + +#define kFilterbankBits 12 + +#ifdef __cplusplus +extern "C" { +#endif + +struct FilterbankState { + int num_channels; + int start_index; + int end_index; + int16_t* channel_frequency_starts; + int16_t* channel_weight_starts; + int16_t* channel_widths; + int16_t* weights; + int16_t* unweights; + uint64_t* work; +}; + +// Converts the relevant complex values of an FFT output into energy (the +// square magnitude). +void FilterbankConvertFftComplexToEnergy(struct FilterbankState* state, + struct complex_int16_t* fft_output, + int32_t* energy); + +// Computes the mel-scale filterbank on the given energy array. Output is cached +// internally - to fetch it, you need to call FilterbankSqrt. +void FilterbankAccumulateChannels(struct FilterbankState* state, + const int32_t* energy); + +// Applies an integer square root to the 64 bit intermediate values of the +// filterbank, and returns a pointer to them. Memory will be invalidated the +// next time FilterbankAccumulateChannels is called. +uint32_t* FilterbankSqrt(struct FilterbankState* state, int scale_down_shift); + +void FilterbankReset(struct FilterbankState* state); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_FILTERBANK_H_ diff --git a/micro_speech/src/microfrontend/lib/filterbank_util.c b/micro_speech/src/microfrontend/lib/filterbank_util.c new file mode 100644 index 0000000..03d500d --- /dev/null +++ b/micro_speech/src/microfrontend/lib/filterbank_util.c @@ -0,0 +1,220 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 "microfrontend/lib/filterbank_util.h" + +#include +#include +#include + +#define kFilterbankIndexAlignment 4 +#define kFilterbankChannelBlockSize 4 + +void FilterbankFillConfigWithDefaults(struct FilterbankConfig* config) { + config->num_channels = 32; + config->lower_band_limit = 125.0f; + config->upper_band_limit = 7500.0f; + config->output_scale_shift = 7; +} + +static float FreqToMel(float freq) { return 1127.0 * log1p(freq / 700.0); } + +static void CalculateCenterFrequencies(const int num_channels, + const float lower_frequency_limit, + const float upper_frequency_limit, + float* center_frequencies) { + assert(lower_frequency_limit >= 0.0f); + assert(upper_frequency_limit > lower_frequency_limit); + + const float mel_low = FreqToMel(lower_frequency_limit); + const float mel_hi = FreqToMel(upper_frequency_limit); + const float mel_span = mel_hi - mel_low; + const float mel_spacing = mel_span / ((float)num_channels); + int i; + for (i = 0; i < num_channels; ++i) { + center_frequencies[i] = mel_low + (mel_spacing * (i + 1)); + } +} + +static void QuantizeFilterbankWeights(const float float_weight, int16_t* weight, + int16_t* unweight) { + *weight = floor(float_weight * (1 << kFilterbankBits) + 0.5); + *unweight = floor((1.0 - float_weight) * (1 << kFilterbankBits) + 0.5); +} + +int FilterbankPopulateState(const struct FilterbankConfig* config, + struct FilterbankState* state, int sample_rate, + int spectrum_size) { + state->num_channels = config->num_channels; + const int num_channels_plus_1 = config->num_channels + 1; + + // How should we align things to index counts given the byte alignment? + const int index_alignment = + (kFilterbankIndexAlignment < sizeof(int16_t) + ? 1 + : kFilterbankIndexAlignment / sizeof(int16_t)); + + state->channel_frequency_starts = + malloc(num_channels_plus_1 * sizeof(*state->channel_frequency_starts)); + state->channel_weight_starts = + malloc(num_channels_plus_1 * sizeof(*state->channel_weight_starts)); + state->channel_widths = + malloc(num_channels_plus_1 * sizeof(*state->channel_widths)); + state->work = malloc(num_channels_plus_1 * sizeof(*state->work)); + + float* center_mel_freqs = + malloc(num_channels_plus_1 * sizeof(*center_mel_freqs)); + int16_t* actual_channel_starts = + malloc(num_channels_plus_1 * sizeof(*actual_channel_starts)); + int16_t* actual_channel_widths = + malloc(num_channels_plus_1 * sizeof(*actual_channel_widths)); + + if (state->channel_frequency_starts == NULL || + state->channel_weight_starts == NULL || state->channel_widths == NULL || + center_mel_freqs == NULL || actual_channel_starts == NULL || + actual_channel_widths == NULL) { + free(center_mel_freqs); + free(actual_channel_starts); + free(actual_channel_widths); + fprintf(stderr, "Failed to allocate channel buffers\n"); + return 0; + } + + CalculateCenterFrequencies(num_channels_plus_1, config->lower_band_limit, + config->upper_band_limit, center_mel_freqs); + + // Always exclude DC. + const float hz_per_sbin = 0.5 * sample_rate / ((float)spectrum_size - 1); + state->start_index = 1.5 + config->lower_band_limit / hz_per_sbin; + state->end_index = 0; // Initialized to zero here, but actually set below. + + // For each channel, we need to figure out what frequencies belong to it, and + // how much padding we need to add so that we can efficiently multiply the + // weights and unweights for accumulation. To simplify the multiplication + // logic, all channels will have some multiplication to do (even if there are + // no frequencies that accumulate to that channel) - they will be directed to + // a set of zero weights. + int chan_freq_index_start = state->start_index; + int weight_index_start = 0; + int needs_zeros = 0; + + int chan; + for (chan = 0; chan < num_channels_plus_1; ++chan) { + // Keep jumping frequencies until we overshoot the bound on this channel. + int freq_index = chan_freq_index_start; + while (FreqToMel((freq_index)*hz_per_sbin) <= center_mel_freqs[chan]) { + ++freq_index; + } + + const int width = freq_index - chan_freq_index_start; + actual_channel_starts[chan] = chan_freq_index_start; + actual_channel_widths[chan] = width; + + if (width == 0) { + // This channel doesn't actually get anything from the frequencies, it's + // always zero. We need then to insert some 'zero' weights into the + // output, and just redirect this channel to do a single multiplication at + // this point. For simplicity, the zeros are placed at the beginning of + // the weights arrays, so we have to go and update all the other + // weight_starts to reflect this shift (but only once). + state->channel_frequency_starts[chan] = 0; + state->channel_weight_starts[chan] = 0; + state->channel_widths[chan] = kFilterbankChannelBlockSize; + if (!needs_zeros) { + needs_zeros = 1; + int j; + for (j = 0; j < chan; ++j) { + state->channel_weight_starts[j] += kFilterbankChannelBlockSize; + } + weight_index_start += kFilterbankChannelBlockSize; + } + } else { + // How far back do we need to go to ensure that we have the proper + // alignment? + const int aligned_start = + (chan_freq_index_start / index_alignment) * index_alignment; + const int aligned_width = (chan_freq_index_start - aligned_start + width); + const int padded_width = + (((aligned_width - 1) / kFilterbankChannelBlockSize) + 1) * + kFilterbankChannelBlockSize; + + state->channel_frequency_starts[chan] = aligned_start; + state->channel_weight_starts[chan] = weight_index_start; + state->channel_widths[chan] = padded_width; + weight_index_start += padded_width; + } + chan_freq_index_start = freq_index; + } + + // Allocate the two arrays to store the weights - weight_index_start contains + // the index of what would be the next set of weights that we would need to + // add, so that's how many weights we need to allocate. + state->weights = calloc(weight_index_start, sizeof(*state->weights)); + state->unweights = calloc(weight_index_start, sizeof(*state->unweights)); + + // If the alloc failed, we also need to nuke the arrays. + if (state->weights == NULL || state->unweights == NULL) { + free(center_mel_freqs); + free(actual_channel_starts); + free(actual_channel_widths); + fprintf(stderr, "Failed to allocate weights or unweights\n"); + return 0; + } + + // Next pass, compute all the weights. Since everything has been memset to + // zero, we only need to fill in the weights that correspond to some frequency + // for a channel. + const float mel_low = FreqToMel(config->lower_band_limit); + for (chan = 0; chan < num_channels_plus_1; ++chan) { + int frequency = actual_channel_starts[chan]; + const int num_frequencies = actual_channel_widths[chan]; + const int frequency_offset = + frequency - state->channel_frequency_starts[chan]; + const int weight_start = state->channel_weight_starts[chan]; + const float denom_val = (chan == 0) ? mel_low : center_mel_freqs[chan - 1]; + + int j; + for (j = 0; j < num_frequencies; ++j, ++frequency) { + const float weight = + (center_mel_freqs[chan] - FreqToMel(frequency * hz_per_sbin)) / + (center_mel_freqs[chan] - denom_val); + + // Make the float into an integer for the weights (and unweights). + const int weight_index = weight_start + frequency_offset + j; + QuantizeFilterbankWeights(weight, state->weights + weight_index, + state->unweights + weight_index); + } + if (frequency > state->end_index) { + state->end_index = frequency; + } + } + + free(center_mel_freqs); + free(actual_channel_starts); + free(actual_channel_widths); + if (state->end_index >= spectrum_size) { + fprintf(stderr, "Filterbank end_index is above spectrum size.\n"); + return 0; + } + return 1; +} + +void FilterbankFreeStateContents(struct FilterbankState* state) { + free(state->channel_frequency_starts); + free(state->channel_weight_starts); + free(state->channel_widths); + free(state->weights); + free(state->unweights); + free(state->work); +} diff --git a/micro_speech/src/microfrontend/lib/filterbank_util.h b/micro_speech/src/microfrontend/lib/filterbank_util.h new file mode 100644 index 0000000..959ba14 --- /dev/null +++ b/micro_speech/src/microfrontend/lib/filterbank_util.h @@ -0,0 +1,50 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_FILTERBANK_UTIL_H_ +#define TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_FILTERBANK_UTIL_H_ + +#include "microfrontend/lib/filterbank.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct FilterbankConfig { + // number of frequency channel buckets for filterbank + int num_channels; + // maximum frequency to include + float upper_band_limit; + // minimum frequency to include + float lower_band_limit; + // unused + int output_scale_shift; +}; + +// Fills the frontendConfig with "sane" defaults. +void FilterbankFillConfigWithDefaults(struct FilterbankConfig* config); + +// Allocates any buffers. +int FilterbankPopulateState(const struct FilterbankConfig* config, + struct FilterbankState* state, int sample_rate, + int spectrum_size); + +// Frees any allocated buffers. +void FilterbankFreeStateContents(struct FilterbankState* state); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_FILTERBANK_UTIL_H_ diff --git a/micro_speech/src/microfrontend/lib/frontend.c b/micro_speech/src/microfrontend/lib/frontend.c new file mode 100644 index 0000000..8a28525 --- /dev/null +++ b/micro_speech/src/microfrontend/lib/frontend.c @@ -0,0 +1,72 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 "microfrontend/lib/frontend.h" + +#include "microfrontend/lib/bits.h" + +struct FrontendOutput FrontendProcessSamples(struct FrontendState* state, + const int16_t* samples, + size_t num_samples, + size_t* num_samples_read) { + struct FrontendOutput output; + output.values = NULL; + output.size = 0; + + // Try to apply the window - if it fails, return and wait for more data. + if (!WindowProcessSamples(&state->window, samples, num_samples, + num_samples_read)) { + return output; + } + + // Apply the FFT to the window's output (and scale it so that the fixed point + // FFT can have as much resolution as possible). + int input_shift = + 15 - MostSignificantBit32(state->window.max_abs_output_value); + FftCompute(&state->fft, state->window.output, input_shift); + + // We can re-ruse the fft's output buffer to hold the energy. + int32_t* energy = (int32_t*)state->fft.output; + + FilterbankConvertFftComplexToEnergy(&state->filterbank, state->fft.output, + energy); + + FilterbankAccumulateChannels(&state->filterbank, energy); + uint32_t* scaled_filterbank = FilterbankSqrt(&state->filterbank, input_shift); + + // Apply noise reduction. + NoiseReductionApply(&state->noise_reduction, scaled_filterbank); + + if (state->pcan_gain_control.enable_pcan) { + PcanGainControlApply(&state->pcan_gain_control, scaled_filterbank); + } + + // Apply the log and scale. + int correction_bits = + MostSignificantBit32(state->fft.fft_size) - 1 - (kFilterbankBits / 2); + uint16_t* logged_filterbank = + LogScaleApply(&state->log_scale, scaled_filterbank, + state->filterbank.num_channels, correction_bits); + + output.size = state->filterbank.num_channels; + output.values = logged_filterbank; + return output; +} + +void FrontendReset(struct FrontendState* state) { + WindowReset(&state->window); + FftReset(&state->fft); + FilterbankReset(&state->filterbank); + NoiseReductionReset(&state->noise_reduction); +} diff --git a/micro_speech/src/microfrontend/lib/frontend.h b/micro_speech/src/microfrontend/lib/frontend.h new file mode 100644 index 0000000..e68b4d1 --- /dev/null +++ b/micro_speech/src/microfrontend/lib/frontend.h @@ -0,0 +1,64 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_FRONTEND_H_ +#define TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_FRONTEND_H_ + +#include +#include + +#include "microfrontend/lib/fft.h" +#include "microfrontend/lib/filterbank.h" +#include "microfrontend/lib/log_scale.h" +#include "microfrontend/lib/noise_reduction.h" +#include "microfrontend/lib/pcan_gain_control.h" +#include "microfrontend/lib/window.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct FrontendState { + struct WindowState window; + struct FftState fft; + struct FilterbankState filterbank; + struct NoiseReductionState noise_reduction; + struct PcanGainControlState pcan_gain_control; + struct LogScaleState log_scale; +}; + +struct FrontendOutput { + const uint16_t* values; + size_t size; +}; + +// Main entry point to processing frontend samples. Updates num_samples_read to +// contain the number of samples that have been consumed from the input array. +// Returns a struct containing the generated output. If not enough samples were +// added to generate a feature vector, the returned size will be 0 and the +// values pointer will be NULL. Note that the output pointer will be invalidated +// as soon as FrontendProcessSamples is called again, so copy the contents +// elsewhere if you need to use them later. +struct FrontendOutput FrontendProcessSamples(struct FrontendState* state, + const int16_t* samples, + size_t num_samples, + size_t* num_samples_read); + +void FrontendReset(struct FrontendState* state); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_FRONTEND_H_ diff --git a/micro_speech/src/microfrontend/lib/frontend_util.c b/micro_speech/src/microfrontend/lib/frontend_util.c new file mode 100644 index 0000000..0e9c3f8 --- /dev/null +++ b/micro_speech/src/microfrontend/lib/frontend_util.c @@ -0,0 +1,85 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 "microfrontend/lib/frontend_util.h" + +#include +#include + +#include "microfrontend/lib/bits.h" + +void FrontendFillConfigWithDefaults(struct FrontendConfig* config) { + WindowFillConfigWithDefaults(&config->window); + FilterbankFillConfigWithDefaults(&config->filterbank); + NoiseReductionFillConfigWithDefaults(&config->noise_reduction); + PcanGainControlFillConfigWithDefaults(&config->pcan_gain_control); + LogScaleFillConfigWithDefaults(&config->log_scale); +} + +int FrontendPopulateState(const struct FrontendConfig* config, + struct FrontendState* state, int sample_rate) { + memset(state, 0, sizeof(*state)); + + if (!WindowPopulateState(&config->window, &state->window, sample_rate)) { + fprintf(stderr, "Failed to populate window state\n"); + return 0; + } + + if (!FftPopulateState(&state->fft, state->window.size)) { + fprintf(stderr, "Failed to populate fft state\n"); + return 0; + } + FftInit(&state->fft); + + if (!FilterbankPopulateState(&config->filterbank, &state->filterbank, + sample_rate, state->fft.fft_size / 2 + 1)) { + fprintf(stderr, "Failed to populate filterbank state\n"); + return 0; + } + + if (!NoiseReductionPopulateState(&config->noise_reduction, + &state->noise_reduction, + state->filterbank.num_channels)) { + fprintf(stderr, "Failed to populate noise reduction state\n"); + return 0; + } + + int input_correction_bits = + MostSignificantBit32(state->fft.fft_size) - 1 - (kFilterbankBits / 2); + if (!PcanGainControlPopulateState( + &config->pcan_gain_control, &state->pcan_gain_control, + state->noise_reduction.estimate, state->filterbank.num_channels, + state->noise_reduction.smoothing_bits, input_correction_bits)) { + fprintf(stderr, "Failed to populate pcan gain control state\n"); + return 0; + } + + if (!LogScalePopulateState(&config->log_scale, &state->log_scale)) { + fprintf(stderr, "Failed to populate log scale state\n"); + return 0; + } + + FrontendReset(state); + + // All good, return a true value. + return 1; +} + +void FrontendFreeStateContents(struct FrontendState* state) { + WindowFreeStateContents(&state->window); + FftFreeStateContents(&state->fft); + FilterbankFreeStateContents(&state->filterbank); + NoiseReductionFreeStateContents(&state->noise_reduction); + PcanGainControlFreeStateContents(&state->pcan_gain_control); +} diff --git a/micro_speech/src/microfrontend/lib/frontend_util.h b/micro_speech/src/microfrontend/lib/frontend_util.h new file mode 100644 index 0000000..0aeab09 --- /dev/null +++ b/micro_speech/src/microfrontend/lib/frontend_util.h @@ -0,0 +1,52 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_FRONTEND_UTIL_H_ +#define TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_FRONTEND_UTIL_H_ + +#include "microfrontend/lib/fft_util.h" +#include "microfrontend/lib/filterbank_util.h" +#include "microfrontend/lib/frontend.h" +#include "microfrontend/lib/log_scale_util.h" +#include "microfrontend/lib/noise_reduction_util.h" +#include "microfrontend/lib/pcan_gain_control_util.h" +#include "microfrontend/lib/window_util.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct FrontendConfig { + struct WindowConfig window; + struct FilterbankConfig filterbank; + struct NoiseReductionConfig noise_reduction; + struct PcanGainControlConfig pcan_gain_control; + struct LogScaleConfig log_scale; +}; + +// Fills the frontendConfig with "sane" defaults. +void FrontendFillConfigWithDefaults(struct FrontendConfig* config); + +// Allocates any buffers. +int FrontendPopulateState(const struct FrontendConfig* config, + struct FrontendState* state, int sample_rate); + +// Frees any allocated buffers. +void FrontendFreeStateContents(struct FrontendState* state); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_FRONTEND_UTIL_H_ diff --git a/micro_speech/src/microfrontend/lib/log_lut.c b/micro_speech/src/microfrontend/lib/log_lut.c new file mode 100644 index 0000000..eff49d3 --- /dev/null +++ b/micro_speech/src/microfrontend/lib/log_lut.c @@ -0,0 +1,30 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 "microfrontend/lib/log_lut.h" +const uint16_t kLogLut[] +#ifndef _MSC_VER + __attribute__((aligned(4))) +#endif // _MSV_VER + = {0, 224, 442, 654, 861, 1063, 1259, 1450, 1636, 1817, 1992, 2163, + 2329, 2490, 2646, 2797, 2944, 3087, 3224, 3358, 3487, 3611, 3732, 3848, + 3960, 4068, 4172, 4272, 4368, 4460, 4549, 4633, 4714, 4791, 4864, 4934, + 5001, 5063, 5123, 5178, 5231, 5280, 5326, 5368, 5408, 5444, 5477, 5507, + 5533, 5557, 5578, 5595, 5610, 5622, 5631, 5637, 5640, 5641, 5638, 5633, + 5626, 5615, 5602, 5586, 5568, 5547, 5524, 5498, 5470, 5439, 5406, 5370, + 5332, 5291, 5249, 5203, 5156, 5106, 5054, 5000, 4944, 4885, 4825, 4762, + 4697, 4630, 4561, 4490, 4416, 4341, 4264, 4184, 4103, 4020, 3935, 3848, + 3759, 3668, 3575, 3481, 3384, 3286, 3186, 3084, 2981, 2875, 2768, 2659, + 2549, 2437, 2323, 2207, 2090, 1971, 1851, 1729, 1605, 1480, 1353, 1224, + 1094, 963, 830, 695, 559, 421, 282, 142, 0, 0}; diff --git a/micro_speech/src/microfrontend/lib/log_lut.h b/micro_speech/src/microfrontend/lib/log_lut.h new file mode 100644 index 0000000..b2448a3 --- /dev/null +++ b/micro_speech/src/microfrontend/lib/log_lut.h @@ -0,0 +1,40 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_LOG_LUT_H_ +#define TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_LOG_LUT_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Number of segments in the log lookup table. The table will be kLogSegments+1 +// in length (with some padding). +#define kLogSegments 128 +#define kLogSegmentsLog2 7 + +// Scale used by lookup table. +#define kLogScale 65536 +#define kLogScaleLog2 16 +#define kLogCoeff 45426 + +extern const uint16_t kLogLut[]; + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_LOG_LUT_H_ diff --git a/micro_speech/src/microfrontend/lib/log_scale.c b/micro_speech/src/microfrontend/lib/log_scale.c new file mode 100644 index 0000000..cd84248 --- /dev/null +++ b/micro_speech/src/microfrontend/lib/log_scale.c @@ -0,0 +1,83 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 "microfrontend/lib/log_scale.h" + +#include "microfrontend/lib/bits.h" +#include "microfrontend/lib/log_lut.h" + +#define kuint16max 0x0000FFFF + +// The following functions implement integer logarithms of various sizes. The +// approximation is calculated according to method described in +// www.inti.gob.ar/electronicaeinformatica/instrumentacion/utic/ +// publicaciones/SPL2007/Log10-spl07.pdf +// It first calculates log2 of the input and then converts it to natural +// logarithm. + +static uint32_t Log2FractionPart(const uint32_t x, const uint32_t log2x) { + // Part 1 + int32_t frac = x - (1LL << log2x); + if (log2x < kLogScaleLog2) { + frac <<= kLogScaleLog2 - log2x; + } else { + frac >>= log2x - kLogScaleLog2; + } + // Part 2 + const uint32_t base_seg = frac >> (kLogScaleLog2 - kLogSegmentsLog2); + const uint32_t seg_unit = + (((uint32_t)1) << kLogScaleLog2) >> kLogSegmentsLog2; + + const int32_t c0 = kLogLut[base_seg]; + const int32_t c1 = kLogLut[base_seg + 1]; + const int32_t seg_base = seg_unit * base_seg; + const int32_t rel_pos = ((c1 - c0) * (frac - seg_base)) >> kLogScaleLog2; + return frac + c0 + rel_pos; +} + +static uint32_t Log(const uint32_t x, const uint32_t scale_shift) { + const uint32_t integer = MostSignificantBit32(x) - 1; + const uint32_t fraction = Log2FractionPart(x, integer); + const uint32_t log2 = (integer << kLogScaleLog2) + fraction; + const uint32_t round = kLogScale / 2; + const uint32_t loge = (((uint64_t)kLogCoeff) * log2 + round) >> kLogScaleLog2; + // Finally scale to our output scale + const uint32_t loge_scaled = ((loge << scale_shift) + round) >> kLogScaleLog2; + return loge_scaled; +} + +uint16_t* LogScaleApply(struct LogScaleState* state, uint32_t* signal, + int signal_size, int correction_bits) { + const int scale_shift = state->scale_shift; + uint16_t* output = (uint16_t*)signal; + uint16_t* ret = output; + int i; + for (i = 0; i < signal_size; ++i) { + uint32_t value = *signal++; + if (state->enable_log) { + if (correction_bits < 0) { + value >>= -correction_bits; + } else { + value <<= correction_bits; + } + if (value > 1) { + value = Log(value, scale_shift); + } else { + value = 0; + } + } + *output++ = (value < kuint16max) ? value : kuint16max; + } + return ret; +} diff --git a/micro_speech/src/microfrontend/lib/log_scale.h b/micro_speech/src/microfrontend/lib/log_scale.h new file mode 100644 index 0000000..a383f32 --- /dev/null +++ b/micro_speech/src/microfrontend/lib/log_scale.h @@ -0,0 +1,39 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_LOG_SCALE_H_ +#define TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_LOG_SCALE_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct LogScaleState { + int enable_log; + int scale_shift; +}; + +// Applies a fixed point logarithm to the signal and converts it to 16 bit. Note +// that the signal array will be modified. +uint16_t* LogScaleApply(struct LogScaleState* state, uint32_t* signal, + int signal_size, int correction_bits); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_LOG_SCALE_H_ diff --git a/micro_speech/src/microfrontend/lib/log_scale_util.c b/micro_speech/src/microfrontend/lib/log_scale_util.c new file mode 100644 index 0000000..b7d8591 --- /dev/null +++ b/micro_speech/src/microfrontend/lib/log_scale_util.c @@ -0,0 +1,27 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 "microfrontend/lib/log_scale_util.h" + +void LogScaleFillConfigWithDefaults(struct LogScaleConfig* config) { + config->enable_log = 1; + config->scale_shift = 6; +} + +int LogScalePopulateState(const struct LogScaleConfig* config, + struct LogScaleState* state) { + state->enable_log = config->enable_log; + state->scale_shift = config->scale_shift; + return 1; +} diff --git a/micro_speech/src/microfrontend/lib/log_scale_util.h b/micro_speech/src/microfrontend/lib/log_scale_util.h new file mode 100644 index 0000000..c3c6c4c --- /dev/null +++ b/micro_speech/src/microfrontend/lib/log_scale_util.h @@ -0,0 +1,45 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_LOG_SCALE_UTIL_H_ +#define TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_LOG_SCALE_UTIL_H_ + +#include +#include + +#include "microfrontend/lib/log_scale.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct LogScaleConfig { + // set to false (0) to disable this module + int enable_log; + // scale results by 2^(scale_shift) + int scale_shift; +}; + +// Populates the LogScaleConfig with "sane" default values. +void LogScaleFillConfigWithDefaults(struct LogScaleConfig* config); + +// Allocates any buffers. +int LogScalePopulateState(const struct LogScaleConfig* config, + struct LogScaleState* state); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_LOG_SCALE_UTIL_H_ diff --git a/micro_speech/src/microfrontend/lib/noise_reduction.c b/micro_speech/src/microfrontend/lib/noise_reduction.c new file mode 100644 index 0000000..58ba860 --- /dev/null +++ b/micro_speech/src/microfrontend/lib/noise_reduction.c @@ -0,0 +1,51 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 "microfrontend/lib/noise_reduction.h" + +#include + +void NoiseReductionApply(struct NoiseReductionState* state, uint32_t* signal) { + int i; + for (i = 0; i < state->num_channels; ++i) { + const uint32_t smoothing = + ((i & 1) == 0) ? state->even_smoothing : state->odd_smoothing; + const uint32_t one_minus_smoothing = (1 << kNoiseReductionBits) - smoothing; + + // Update the estimate of the noise. + const uint32_t signal_scaled_up = signal[i] << state->smoothing_bits; + uint32_t estimate = + (((uint64_t)signal_scaled_up * smoothing) + + ((uint64_t)state->estimate[i] * one_minus_smoothing)) >> + kNoiseReductionBits; + state->estimate[i] = estimate; + + // Make sure that we can't get a negative value for the signal - estimate. + if (estimate > signal_scaled_up) { + estimate = signal_scaled_up; + } + + const uint32_t floor = + ((uint64_t)signal[i] * state->min_signal_remaining) >> + kNoiseReductionBits; + const uint32_t subtracted = + (signal_scaled_up - estimate) >> state->smoothing_bits; + const uint32_t output = subtracted > floor ? subtracted : floor; + signal[i] = output; + } +} + +void NoiseReductionReset(struct NoiseReductionState* state) { + memset(state->estimate, 0, sizeof(*state->estimate) * state->num_channels); +} diff --git a/micro_speech/src/microfrontend/lib/noise_reduction.h b/micro_speech/src/microfrontend/lib/noise_reduction.h new file mode 100644 index 0000000..46d3f52 --- /dev/null +++ b/micro_speech/src/microfrontend/lib/noise_reduction.h @@ -0,0 +1,46 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_NOISE_REDUCTION_H_ +#define TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_NOISE_REDUCTION_H_ + +#define kNoiseReductionBits 14 + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct NoiseReductionState { + int smoothing_bits; + uint16_t even_smoothing; + uint16_t odd_smoothing; + uint16_t min_signal_remaining; + int num_channels; + uint32_t* estimate; +}; + +// Removes stationary noise from each channel of the signal using a low pass +// filter. +void NoiseReductionApply(struct NoiseReductionState* state, uint32_t* signal); + +void NoiseReductionReset(struct NoiseReductionState* state); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_NOISE_REDUCTION_H_ diff --git a/micro_speech/src/microfrontend/lib/noise_reduction_util.c b/micro_speech/src/microfrontend/lib/noise_reduction_util.c new file mode 100644 index 0000000..a40cc14 --- /dev/null +++ b/micro_speech/src/microfrontend/lib/noise_reduction_util.c @@ -0,0 +1,45 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 "microfrontend/lib/noise_reduction_util.h" + +#include + +void NoiseReductionFillConfigWithDefaults(struct NoiseReductionConfig* config) { + config->smoothing_bits = 10; + config->even_smoothing = 0.025; + config->odd_smoothing = 0.06; + config->min_signal_remaining = 0.05; +} + +int NoiseReductionPopulateState(const struct NoiseReductionConfig* config, + struct NoiseReductionState* state, + int num_channels) { + state->smoothing_bits = config->smoothing_bits; + state->odd_smoothing = config->odd_smoothing * (1 << kNoiseReductionBits); + state->even_smoothing = config->even_smoothing * (1 << kNoiseReductionBits); + state->min_signal_remaining = + config->min_signal_remaining * (1 << kNoiseReductionBits); + state->num_channels = num_channels; + state->estimate = calloc(state->num_channels, sizeof(*state->estimate)); + if (state->estimate == NULL) { + fprintf(stderr, "Failed to alloc estimate buffer\n"); + return 0; + } + return 1; +} + +void NoiseReductionFreeStateContents(struct NoiseReductionState* state) { + free(state->estimate); +} diff --git a/micro_speech/src/microfrontend/lib/noise_reduction_util.h b/micro_speech/src/microfrontend/lib/noise_reduction_util.h new file mode 100644 index 0000000..d5aae16 --- /dev/null +++ b/micro_speech/src/microfrontend/lib/noise_reduction_util.h @@ -0,0 +1,50 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_NOISE_REDUCTION_UTIL_H_ +#define TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_NOISE_REDUCTION_UTIL_H_ + +#include "microfrontend/lib/noise_reduction.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct NoiseReductionConfig { + // scale the signal up by 2^(smoothing_bits) before reduction + int smoothing_bits; + // smoothing coefficient for even-numbered channels + float even_smoothing; + // smoothing coefficient for odd-numbered channels + float odd_smoothing; + // fraction of signal to preserve (1.0 disables this module) + float min_signal_remaining; +}; + +// Populates the NoiseReductionConfig with "sane" default values. +void NoiseReductionFillConfigWithDefaults(struct NoiseReductionConfig* config); + +// Allocates any buffers. +int NoiseReductionPopulateState(const struct NoiseReductionConfig* config, + struct NoiseReductionState* state, + int num_channels); + +// Frees any allocated buffers. +void NoiseReductionFreeStateContents(struct NoiseReductionState* state); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_NOISE_REDUCTION_UTIL_H_ diff --git a/micro_speech/src/microfrontend/lib/pcan_gain_control.c b/micro_speech/src/microfrontend/lib/pcan_gain_control.c new file mode 100644 index 0000000..5ccfbe3 --- /dev/null +++ b/micro_speech/src/microfrontend/lib/pcan_gain_control.c @@ -0,0 +1,56 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 "microfrontend/lib/pcan_gain_control.h" + +#include "microfrontend/lib/bits.h" + +int16_t WideDynamicFunction(const uint32_t x, const int16_t* lut) { + if (x <= 2) { + return lut[x]; + } + + const int16_t interval = MostSignificantBit32(x); + lut += 4 * interval - 6; + + const int16_t frac = + ((interval < 11) ? (x << (11 - interval)) : (x >> (interval - 11))) & + 0x3FF; + + int32_t result = ((int32_t)lut[2] * frac) >> 5; + result += (int32_t)((uint32_t)lut[1] << 5); + result *= frac; + result = (result + (1 << 14)) >> 15; + result += lut[0]; + return (int16_t)result; +} + +uint32_t PcanShrink(const uint32_t x) { + if (x < (2 << kPcanSnrBits)) { + return (x * x) >> (2 + 2 * kPcanSnrBits - kPcanOutputBits); + } else { + return (x >> (kPcanSnrBits - kPcanOutputBits)) - (1 << kPcanOutputBits); + } +} + +void PcanGainControlApply(struct PcanGainControlState* state, + uint32_t* signal) { + int i; + for (i = 0; i < state->num_channels; ++i) { + const uint32_t gain = + WideDynamicFunction(state->noise_estimate[i], state->gain_lut); + const uint32_t snr = ((uint64_t)signal[i] * gain) >> state->snr_shift; + signal[i] = PcanShrink(snr); + } +} diff --git a/micro_speech/src/microfrontend/lib/pcan_gain_control.h b/micro_speech/src/microfrontend/lib/pcan_gain_control.h new file mode 100644 index 0000000..3f6222b --- /dev/null +++ b/micro_speech/src/microfrontend/lib/pcan_gain_control.h @@ -0,0 +1,47 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_PCAN_GAIN_CONTROL_H_ +#define TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_PCAN_GAIN_CONTROL_H_ + +#include +#include + +#define kPcanSnrBits 12 +#define kPcanOutputBits 6 + +#ifdef __cplusplus +extern "C" { +#endif + +// Details at https://research.google/pubs/pub45911.pdf +struct PcanGainControlState { + int enable_pcan; + uint32_t* noise_estimate; + int num_channels; + int16_t* gain_lut; + int32_t snr_shift; +}; + +int16_t WideDynamicFunction(const uint32_t x, const int16_t* lut); + +uint32_t PcanShrink(const uint32_t x); + +void PcanGainControlApply(struct PcanGainControlState* state, uint32_t* signal); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_PCAN_GAIN_CONTROL_H_ diff --git a/micro_speech/src/microfrontend/lib/pcan_gain_control_util.c b/micro_speech/src/microfrontend/lib/pcan_gain_control_util.c new file mode 100644 index 0000000..4770aca --- /dev/null +++ b/micro_speech/src/microfrontend/lib/pcan_gain_control_util.c @@ -0,0 +1,92 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 "microfrontend/lib/pcan_gain_control_util.h" + +#include +#include + +#define kint16max 0x00007FFF + +void PcanGainControlFillConfigWithDefaults( + struct PcanGainControlConfig* config) { + config->enable_pcan = 0; + config->strength = 0.95; + config->offset = 80.0; + config->gain_bits = 21; +} + +int16_t PcanGainLookupFunction(const struct PcanGainControlConfig* config, + int32_t input_bits, uint32_t x) { + const float x_as_float = ((float)x) / ((uint32_t)1 << input_bits); + const float gain_as_float = + ((uint32_t)1 << config->gain_bits) * + powf(x_as_float + config->offset, -config->strength); + + if (gain_as_float > kint16max) { + return kint16max; + } + return (int16_t)(gain_as_float + 0.5f); +} + +int PcanGainControlPopulateState(const struct PcanGainControlConfig* config, + struct PcanGainControlState* state, + uint32_t* noise_estimate, + const int num_channels, + const uint16_t smoothing_bits, + const int32_t input_correction_bits) { + state->enable_pcan = config->enable_pcan; + if (!state->enable_pcan) { + return 1; + } + state->noise_estimate = noise_estimate; + state->num_channels = num_channels; + state->gain_lut = malloc(kWideDynamicFunctionLUTSize * sizeof(int16_t)); + if (state->gain_lut == NULL) { + fprintf(stderr, "Failed to allocate gain LUT\n"); + return 0; + } + state->snr_shift = config->gain_bits - input_correction_bits - kPcanSnrBits; + + const int32_t input_bits = smoothing_bits - input_correction_bits; + state->gain_lut[0] = PcanGainLookupFunction(config, input_bits, 0); + state->gain_lut[1] = PcanGainLookupFunction(config, input_bits, 1); + state->gain_lut -= 6; + int interval; + for (interval = 2; interval <= kWideDynamicFunctionBits; ++interval) { + const uint32_t x0 = (uint32_t)1 << (interval - 1); + const uint32_t x1 = x0 + (x0 >> 1); + const uint32_t x2 = + (interval == kWideDynamicFunctionBits) ? x0 + (x0 - 1) : 2 * x0; + + const int16_t y0 = PcanGainLookupFunction(config, input_bits, x0); + const int16_t y1 = PcanGainLookupFunction(config, input_bits, x1); + const int16_t y2 = PcanGainLookupFunction(config, input_bits, x2); + + const int32_t diff1 = (int32_t)y1 - y0; + const int32_t diff2 = (int32_t)y2 - y0; + const int32_t a1 = 4 * diff1 - diff2; + const int32_t a2 = diff2 - a1; + + state->gain_lut[4 * interval] = y0; + state->gain_lut[4 * interval + 1] = (int16_t)a1; + state->gain_lut[4 * interval + 2] = (int16_t)a2; + } + state->gain_lut += 6; + return 1; +} + +void PcanGainControlFreeStateContents(struct PcanGainControlState* state) { + free(state->gain_lut); +} diff --git a/micro_speech/src/microfrontend/lib/pcan_gain_control_util.h b/micro_speech/src/microfrontend/lib/pcan_gain_control_util.h new file mode 100644 index 0000000..89c346b --- /dev/null +++ b/micro_speech/src/microfrontend/lib/pcan_gain_control_util.h @@ -0,0 +1,57 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_PCAN_GAIN_CONTROL_UTIL_H_ +#define TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_PCAN_GAIN_CONTROL_UTIL_H_ + +#include "microfrontend/lib/pcan_gain_control.h" + +#define kWideDynamicFunctionBits 32 +#define kWideDynamicFunctionLUTSize (4 * kWideDynamicFunctionBits - 3) + +#ifdef __cplusplus +extern "C" { +#endif + +struct PcanGainControlConfig { + // set to false (0) to disable this module + int enable_pcan; + // gain normalization exponent (0.0 disables, 1.0 full strength) + float strength; + // positive value added in the normalization denominator + float offset; + // number of fractional bits in the gain + int gain_bits; +}; + +void PcanGainControlFillConfigWithDefaults( + struct PcanGainControlConfig* config); + +int16_t PcanGainLookupFunction(const struct PcanGainControlConfig* config, + int32_t input_bits, uint32_t x); + +int PcanGainControlPopulateState(const struct PcanGainControlConfig* config, + struct PcanGainControlState* state, + uint32_t* noise_estimate, + const int num_channels, + const uint16_t smoothing_bits, + const int32_t input_correction_bits); + +void PcanGainControlFreeStateContents(struct PcanGainControlState* state); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_PCAN_GAIN_CONTROL_UTIL_H_ diff --git a/micro_speech/src/microfrontend/lib/window.c b/micro_speech/src/microfrontend/lib/window.c new file mode 100644 index 0000000..00a3f42 --- /dev/null +++ b/micro_speech/src/microfrontend/lib/window.c @@ -0,0 +1,70 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 "microfrontend/lib/window.h" + +#include + +int WindowProcessSamples(struct WindowState* state, const int16_t* samples, + size_t num_samples, size_t* num_samples_read) { + const int size = state->size; + + // Copy samples from the samples buffer over to our local input. + size_t max_samples_to_copy = state->size - state->input_used; + if (max_samples_to_copy > num_samples) { + max_samples_to_copy = num_samples; + } + memcpy(state->input + state->input_used, samples, + max_samples_to_copy * sizeof(*samples)); + *num_samples_read = max_samples_to_copy; + state->input_used += max_samples_to_copy; + + if (state->input_used < state->size) { + // We don't have enough samples to compute a window. + return 0; + } + + // Apply the window to the input. + const int16_t* coefficients = state->coefficients; + const int16_t* input = state->input; + int16_t* output = state->output; + int i; + int16_t max_abs_output_value = 0; + for (i = 0; i < size; ++i) { + int16_t new_value = + (((int32_t)*input++) * *coefficients++) >> kFrontendWindowBits; + *output++ = new_value; + if (new_value < 0) { + new_value = -new_value; + } + if (new_value > max_abs_output_value) { + max_abs_output_value = new_value; + } + } + // Shuffle the input down by the step size, and update how much we have used. + memmove(state->input, state->input + state->step, + sizeof(*state->input) * (state->size - state->step)); + state->input_used -= state->step; + state->max_abs_output_value = max_abs_output_value; + + // Indicate that the output buffer is valid for the next stage. + return 1; +} + +void WindowReset(struct WindowState* state) { + memset(state->input, 0, state->size * sizeof(*state->input)); + memset(state->output, 0, state->size * sizeof(*state->output)); + state->input_used = 0; + state->max_abs_output_value = 0; +} diff --git a/micro_speech/src/microfrontend/lib/window.h b/micro_speech/src/microfrontend/lib/window.h new file mode 100644 index 0000000..bad8151 --- /dev/null +++ b/micro_speech/src/microfrontend/lib/window.h @@ -0,0 +1,49 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_WINDOW_H_ +#define TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_WINDOW_H_ + +#include +#include + +#define kFrontendWindowBits 12 + +#ifdef __cplusplus +extern "C" { +#endif + +struct WindowState { + size_t size; + int16_t* coefficients; + size_t step; + + int16_t* input; + size_t input_used; + int16_t* output; + int16_t max_abs_output_value; +}; + +// Applies a window to the samples coming in, stepping forward at the given +// rate. +int WindowProcessSamples(struct WindowState* state, const int16_t* samples, + size_t num_samples, size_t* num_samples_read); + +void WindowReset(struct WindowState* state); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_WINDOW_H_ diff --git a/micro_speech/src/microfrontend/lib/window_util.c b/micro_speech/src/microfrontend/lib/window_util.c new file mode 100644 index 0000000..611a5c4 --- /dev/null +++ b/micro_speech/src/microfrontend/lib/window_util.c @@ -0,0 +1,73 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 "microfrontend/lib/window_util.h" + +#include +#include +#include +#include + +// Some platforms don't have M_PI +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +void WindowFillConfigWithDefaults(struct WindowConfig* config) { + config->size_ms = 25; + config->step_size_ms = 10; +} + +int WindowPopulateState(const struct WindowConfig* config, + struct WindowState* state, int sample_rate) { + state->size = config->size_ms * sample_rate / 1000; + state->step = config->step_size_ms * sample_rate / 1000; + + state->coefficients = malloc(state->size * sizeof(*state->coefficients)); + if (state->coefficients == NULL) { + fprintf(stderr, "Failed to allocate window coefficients\n"); + return 0; + } + + // Populate the window values. + const float arg = M_PI * 2.0 / ((float)state->size); + int i; + for (i = 0; i < state->size; ++i) { + float float_value = 0.5 - (0.5 * cos(arg * (i + 0.5))); + // Scale it to fixed point and round it. + state->coefficients[i] = + floor(float_value * (1 << kFrontendWindowBits) + 0.5); + } + + state->input_used = 0; + state->input = malloc(state->size * sizeof(*state->input)); + if (state->input == NULL) { + fprintf(stderr, "Failed to allocate window input\n"); + return 0; + } + + state->output = malloc(state->size * sizeof(*state->output)); + if (state->output == NULL) { + fprintf(stderr, "Failed to allocate window output\n"); + return 0; + } + + return 1; +} + +void WindowFreeStateContents(struct WindowState* state) { + free(state->coefficients); + free(state->input); + free(state->output); +} diff --git a/micro_speech/src/microfrontend/lib/window_util.h b/micro_speech/src/microfrontend/lib/window_util.h new file mode 100644 index 0000000..c7abc8e --- /dev/null +++ b/micro_speech/src/microfrontend/lib/window_util.h @@ -0,0 +1,45 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_WINDOW_UTIL_H_ +#define TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_WINDOW_UTIL_H_ + +#include "microfrontend/lib/window.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct WindowConfig { + // length of window frame in milliseconds + size_t size_ms; + // length of step for next frame in milliseconds + size_t step_size_ms; +}; + +// Populates the WindowConfig with "sane" default values. +void WindowFillConfigWithDefaults(struct WindowConfig* config); + +// Allocates any buffers. +int WindowPopulateState(const struct WindowConfig* config, + struct WindowState* state, int sample_rate); + +// Frees any allocated buffers. +void WindowFreeStateContents(struct WindowState* state); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_WINDOW_UTIL_H_ diff --git a/micro_speech/src/no_1000ms_sample_data.cc b/micro_speech/src/no_1000ms_sample_data.cc new file mode 100644 index 0000000..73824fc --- /dev/null +++ b/micro_speech/src/no_1000ms_sample_data.cc @@ -0,0 +1,1477 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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. +==============================================================================*/ + +// See the header for documentation on the meaning of this data. + +#include "no_1000ms_sample_data.h" + +const int g_no_1000ms_sample_data_size = 16000; +const int16_t g_no_1000ms_sample_data[16000] = { + 5, 1, -10, -16, -14, -10, -4, -5, -10, -15, -13, + -17, -22, -21, -23, -25, -22, -26, -28, -31, -28, -25, + -20, -24, -21, -13, -7, -1, -1, 3, 3, 4, -4, + -6, -8, -10, -13, -4, -2, 5, 8, 11, 26, 28, + 34, 32, 34, 30, 21, 18, 15, 13, 8, 5, 14, + 13, 7, 8, 4, -5, -7, -4, -9, -13, -17, -21, + -16, -14, -12, -12, -14, -11, -9, -2, 5, -1, 2, + 0, 2, 1, -3, -13, -14, -16, -11, -10, -9, -13, + -17, -19, -25, -21, -21, -20, -13, -5, -3, 0, 3, + 6, 5, 1, 0, -1, -7, -10, -11, -9, -6, -7, + -11, -10, -5, -14, -20, -23, -22, -22, -19, -15, -12, + -6, -5, 3, 13, 16, 17, 25, 26, 28, 34, 34, + 33, 34, 30, 21, 22, 18, 13, 20, 22, 24, 27, + 26, 23, 21, 18, 9, 5, -2, -7, -8, -10, -8, + -8, -4, 2, 2, -1, -7, -10, -8, -12, -13, -15, + -9, -5, -4, -3, -6, -11, -11, -18, -16, -13, -10, + -12, -6, 0, -2, 0, -3, -4, -8, -12, -19, -16, + -17, -19, -23, -30, -33, -36, -38, -39, -40, -36, -37, + -32, -27, -25, -31, -38, -41, -47, -52, -50, -42, -32, + -16, -7, -3, 0, -1, -1, -5, -16, -23, -29, -34, + -33, -27, -17, -11, 1, 4, 10, 18, 21, 24, 24, + 25, 30, 34, 30, 29, 26, 23, 20, 15, 14, 13, + 14, 16, 23, 28, 21, 23, 21, 13, 12, 12, 14, + 17, 21, 26, 27, 30, 30, 26, 20, 15, 15, 9, + 8, 9, 10, 7, 8, 7, 1, -2, -6, -10, -10, + -12, -15, -10, -7, -6, -5, 0, -3, -3, -12, -25, + -35, -49, -53, -49, -51, -48, -46, -48, -39, -33, -31, + -37, -42, -47, -49, -46, -47, -47, -46, -42, -39, -33, + -26, -23, -14, -8, -9, -7, -10, -11, -13, -13, -19, + -20, -16, -11, -9, 7, 16, 21, 29, 27, 29, 28, + 21, 14, 13, 17, 19, 20, 18, 13, 17, 16, 18, + 20, 17, 13, 16, 23, 26, 26, 25, 27, 31, 30, + 31, 34, 32, 35, 32, 36, 31, 26, 23, 27, 27, + 29, 27, 26, 32, 31, 28, 26, 23, 14, 6, 0, + -4, -7, -9, -10, -8, -3, 4, 12, 11, 15, 11, + 8, 2, -3, -3, -4, -6, -11, -14, -20, -28, -32, + -38, -46, -42, -44, -40, -34, -26, -29, -25, -23, -24, + -17, -21, -26, -23, -25, -19, -10, -11, -10, -10, -12, + -9, -3, 0, -3, -7, -10, -13, -10, -14, -13, -17, + -22, -22, -30, -28, -29, -26, -18, -6, -1, -3, -4, + -6, -10, -13, -10, -14, -16, -11, -15, -9, -3, -6, + -1, 2, 3, 4, 6, 6, 3, 4, 12, 14, 17, + 21, 19, 20, 16, 17, 15, 21, 21, 22, 20, 17, + 16, 16, 20, 17, 15, 9, 5, 11, 18, 24, 28, + 26, 23, 23, 26, 22, 18, 21, 23, 26, 27, 25, + 27, 29, 26, 20, 10, 7, 11, 8, 16, 25, 33, + 37, 38, 39, 35, 30, 20, 13, 9, 6, 5, 13, + 13, 14, 15, 12, 8, 3, 3, 3, 2, 9, 11, + 10, 5, 5, 0, -7, -11, -12, -15, -17, -12, -13, + -18, -19, -21, -24, -22, -27, -34, -36, -36, -32, -20, + -16, -15, -5, -5, -9, -10, -9, -17, -19, -20, -14, + -13, -10, -4, -7, -7, -14, -19, -28, -31, -30, -31, + -23, -19, -20, -12, -11, -14, -16, -20, -18, -20, -21, + -24, -29, -30, -30, -34, -31, -25, -21, -18, -11, -4, + 2, 2, 3, 3, 2, 4, -1, -4, -8, -3, -1, + 7, 15, 18, 22, 20, 20, 16, 16, 14, 13, 21, + 25, 26, 35, 28, 28, 28, 25, 21, 19, 18, 21, + 24, 20, 25, 28, 19, 16, 15, 8, 3, -1, 3, + 5, 13, 18, 25, 31, 33, 39, 36, 36, 32, 36, + 37, 39, 42, 36, 32, 27, 30, 24, 18, 15, 10, + 7, 5, 6, -1, -4, -10, -17, -15, -19, -15, -7, + -4, 3, 0, 3, 4, -2, -7, -13, -21, -23, -28, + -27, -26, -25, -15, -10, -4, -6, -5, -9, -5, -3, + 1, 2, -1, 1, -4, -7, -8, -17, -17, -15, -14, + -9, -5, -7, -6, -9, -16, -15, -15, -16, -16, -11, + -15, -15, -6, -6, -5, -2, 0, -9, -10, -12, -13, + -10, -4, 0, 8, 5, 4, 2, 0, -5, -8, -16, + -15, -12, -3, 9, 17, 24, 26, 30, 28, 22, 17, + 14, 9, 8, 9, 8, 11, 12, 12, 15, 14, 18, + 20, 17, 19, 22, 21, 12, 5, 0, 3, -3, -4, + -6, -7, 1, 8, 8, 8, 10, 2, -3, -8, -15, + -20, -24, -22, -23, -13, -6, -7, -5, -10, -8, -15, + -19, -22, -20, -17, -18, -13, -10, -1, 6, 5, 3, + 1, -5, -11, -10, -14, -19, -15, -13, -8, -2, -3, + -4, -3, -4, -1, 1, 0, -3, -4, -8, -18, -21, + -25, -24, -16, -9, -2, 1, 5, 1, 3, -2, -7, + -10, -23, -30, -29, -23, -9, -3, 4, 11, 11, 6, + 2, 0, -12, -20, -28, -24, -22, -17, -22, -19, -14, + -21, -17, -17, -12, -8, -3, 2, 0, -6, -5, -8, + -12, -17, -27, -34, -31, -30, -27, -19, -14, -14, -14, + -14, -19, -22, -21, -19, -14, -1, 5, 9, 8, 6, + 5, -4, -2, -3, -3, -1, -2, -3, 2, 7, 8, + 7, 6, 6, 3, 2, 1, -2, 0, 6, 11, 18, + 18, 19, 17, 14, 9, 4, 3, 3, 0, -1, 3, + -1, -5, 0, -2, 0, 1, 7, 7, 8, 20, 29, + 33, 31, 24, 14, 5, -6, -11, -8, -11, -2, 6, + 10, 12, 16, 26, 26, 24, 18, 12, 10, 4, 7, + 6, -2, -12, -17, -17, -20, -23, -23, -18, -8, 1, + 3, 5, 6, 3, 0, -6, -12, -12, -15, -12, -7, + 3, 3, 8, 7, 7, 7, 1, -1, -1, 4, 11, + 17, 25, 32, 35, 42, 50, 52, 56, 50, 55, 53, + 52, 47, 40, 38, 30, 26, 27, 28, 29, 25, 23, + 23, 28, 30, 25, 26, 21, 19, 14, 9, 16, 22, + 25, 33, 39, 45, 49, 48, 55, 51, 43, 35, 20, + 14, 13, 23, 25, 24, 20, 22, 28, 22, 22, 17, + 16, 13, 10, 10, 10, 9, 9, 14, 11, 10, 10, + 4, 0, 0, -2, -3, -5, -7, -3, 1, -8, -8, + -9, -4, 4, 9, 11, 14, 11, 6, 8, 3, -6, + -10, -19, -22, -24, -27, -22, -16, -21, -25, -33, -33, + -32, -30, -21, -13, -6, -5, 2, 1, 4, 9, 7, + 5, 1, 1, 8, 6, 7, 6, 0, -6, -15, -18, + -23, -22, -23, -25, -22, -21, -19, -17, -13, -10, -10, + -16, -17, -15, -13, -8, -9, -14, -13, -17, -20, -26, + -28, -31, -29, -26, -23, -13, -10, -6, -1, 5, 7, + 2, -3, -7, -20, -18, -16, -21, -27, -33, -25, -27, + -22, -22, -21, -16, -11, -7, -2, 2, 11, 18, 11, + 9, 4, 1, -1, -6, -4, -5, -9, -12, -16, -25, + -29, -37, -37, -38, -37, -33, -23, -16, -14, -7, -1, + -4, -3, -4, -5, -11, -14, -8, -8, -8, -8, -9, + -4, -14, -21, -22, -21, -18, -15, -2, 3, -3, 0, + -2, 0, -4, -7, -1, -2, 3, 3, -3, -10, -13, + -10, -16, -19, -17, -17, -14, -7, 5, 5, 7, 8, + 12, 7, 0, -5, -13, -17, -18, -14, -7, -4, 3, + 11, 11, 12, 11, 8, 4, -5, -5, -11, -15, -17, + -23, -22, -18, -14, -14, -12, -6, -4, -1, 3, 1, + -4, -10, -22, -29, -30, -26, -15, -2, 6, 16, 21, + 28, 32, 25, 24, 20, 9, 5, 0, 3, 7, 10, + 11, 13, 17, 15, 16, 13, 11, 11, 8, 7, 1, + 1, -5, -2, -2, -1, 4, 8, 17, 22, 24, 24, + 26, 23, 20, 17, 16, 9, 4, 6, 5, 8, 2, + -1, -5, -4, -10, -14, -14, -17, -19, -18, -16, -14, + -6, -3, 1, 3, 0, -4, -6, -4, -1, -1, 2, + 5, 3, 8, 7, 7, 14, 13, 20, 24, 29, 24, + 12, 7, -1, -6, -15, -22, -20, -27, -22, -14, -6, + 2, 7, 9, 9, 2, -3, -7, -8, -10, -9, -3, + -6, -11, -12, -8, -5, -4, -5, -3, 0, 3, 6, + 6, 7, 5, -7, -10, -14, -13, -14, -17, -11, -7, + -4, 1, 1, 4, -4, -8, -18, -23, -23, -25, -19, + -16, -15, -9, 3, 10, 19, 25, 30, 31, 26, 27, + 23, 19, 16, 8, 7, 2, 0, -1, -1, 1, 5, + 6, 6, 1, 3, -1, -7, -11, -17, -19, -19, -7, + 0, 3, 11, 12, 18, 20, 16, 9, -2, -7, -14, + -19, -22, -30, -33, -34, -36, -26, -14, -11, -9, -3, + 0, -2, 1, -2, -3, -5, -12, -15, -19, -14, -9, + -8, -2, -6, -13, -15, -19, -22, -25, -26, -21, -20, + -11, -1, 1, 5, 9, 13, 15, 12, 11, 3, 1, + -1, 0, 8, 13, 16, 16, 15, 16, 15, 12, 9, + 7, 8, 4, 6, 4, 3, 3, 7, 0, -4, -8, + -11, -18, -18, -15, -20, -23, -21, -22, -21, -27, -25, + -15, -7, -2, 8, 9, 8, 8, 3, 3, 7, 8, + 8, 8, 12, 11, 12, 4, -1, -7, -11, -15, -18, + -17, -17, -20, -19, -13, -11, -3, -3, -1, 1, -3, + 1, 1, 8, 10, 15, 24, 26, 29, 34, 36, 26, + 20, 12, -2, -6, -9, -7, -6, 1, 10, 13, 19, + 22, 22, 18, 21, 24, 28, 35, 37, 34, 33, 34, + 34, 30, 19, 15, 10, 19, 21, 23, 24, 21, 19, + 18, 21, 22, 22, 27, 30, 31, 32, 33, 32, 32, + 24, 18, 10, 8, 10, 10, 6, 2, -7, -14, -22, + -29, -27, -29, -32, -30, -28, -23, -22, -11, -11, -13, + -3, 2, -1, 1, 1, -3, -7, -5, -7, -11, -17, + -23, -25, -26, -27, -26, -23, -14, -5, -3, -1, -2, + -2, -1, 1, -2, -7, -4, 2, 4, 10, 13, 6, + 3, -2, -6, -7, -11, -17, -21, -15, -7, -2, 11, + 16, 22, 25, 25, 23, 24, 23, 21, 22, 25, 23, + 17, 17, 12, 8, -2, -4, 1, 0, 4, 9, 8, + 10, 9, 9, 15, 13, 10, 8, 1, 1, -3, 1, + 4, 11, 10, 9, 5, 5, 4, 1, -1, -4, 0, + 8, 7, 4, 3, 3, 0, -9, -16, -19, -20, -21, + -18, -16, -11, -10, -9, -13, -12, -19, -25, -21, -15, + -5, 8, 14, 21, 24, 18, 20, 17, 6, 1, -2, + -2, 1, 1, 4, 1, -3, 2, 0, -3, -3, -4, + 1, 0, -5, -11, -17, -21, -20, -20, -20, -14, -9, + -3, 3, 7, 5, 3, 1, -1, -3, -4, -1, 1, + -5, -1, -1, -7, -11, -14, -12, -14, -17, -18, -23, + -29, -24, -27, -19, -12, -13, -2, -3, 4, 4, 0, + -3, -5, -2, -1, -5, -6, -7, -7, -7, -9, -13, + -9, -4, 1, 1, 1, -4, -11, -8, -15, -19, -19, + -12, -5, 1, 7, 12, 8, 10, 10, 10, 11, 11, + 19, 12, 9, 9, 2, -4, -13, -22, -24, -25, -24, + -26, -19, -14, -10, -1, 5, 4, -1, -4, -5, -10, + -14, -11, -8, -10, -8, -9, -7, -8, -6, -1, -5, + -10, -18, -27, -29, -24, -19, -11, -7, 1, 10, 8, + 8, 5, 2, -5, -1, -1, 0, 2, 2, -2, -8, + -8, -14, -26, -25, -23, -18, -9, 2, 2, 7, 13, + 6, 7, 5, 4, 3, 2, 1, 7, 2, -1, 1, + -2, 2, 0, -2, -6, -3, 5, 7, 9, 6, 5, + 4, 2, 0, -1, -3, 3, 7, 6, 14, 18, 22, + 20, 22, 19, 13, 9, 2, -8, -11, -6, -2, -3, + -3, 0, 0, 0, 1, -1, -2, 1, 7, 11, 10, + 11, 17, 17, 11, 11, 4, 6, 6, 13, 19, 22, + 23, 27, 25, 24, 22, 14, 11, 13, 7, 0, -3, + -9, -11, -7, -7, -6, -4, 1, 7, 9, 15, 18, + 18, 10, 5, 3, -3, -6, -5, -8, -5, 4, 8, + 8, 11, 10, 9, 4, 4, 1, -3, -10, -11, -8, + -16, -20, -22, -19, -12, -7, -10, -10, -13, -14, -11, + -11, -13, -18, -21, -19, -17, -22, -18, -22, -22, -16, + -9, -3, 0, 3, 6, 3, 3, -3, -6, -9, -14, + -1, 14, 21, 30, 37, 33, 27, 26, 19, 15, 14, + 11, 20, 12, 9, 10, 19, 20, 19, 22, 20, 22, + 17, 13, 14, 10, 8, 12, 15, 13, 12, 12, 12, + 9, 10, 11, 11, 9, 6, 4, 5, -2, 1, 1, + -1, 5, 1, 8, 6, 3, -1, -4, -15, -24, -27, + -26, -23, -19, -9, -3, -4, -9, -9, -10, -16, -22, + -19, -18, -15, -2, 3, 5, 6, 7, 8, 11, 3, + 1, 2, 1, 1, 0, -4, -13, -18, -19, -19, -20, + -23, -15, -10, -5, -3, -1, -1, -1, 3, -1, 0, + -8, -11, -13, -14, -13, -8, -6, -3, 1, 1, 0, + 0, 5, 4, 5, 5, 5, 4, 0, -1, -4, -13, + -22, -21, -28, -26, -22, -28, -23, -23, -14, -11, -10, + -7, -8, -5, -4, 1, 9, 10, 15, 19, 21, 17, + 18, 19, 16, 13, 16, 21, 27, 29, 22, 22, 13, + 4, 1, 0, -5, -6, -2, 3, 5, 8, 6, 9, + 10, 2, -3, -9, -8, -4, -2, -7, -6, -4, -8, + -6, -8, -11, -8, -8, -6, 2, -2, -2, -1, 2, + 4, 8, 5, -1, -8, -10, -7, -6, -5, -6, -5, + 6, 13, 22, 28, 33, 31, 38, 35, 28, 27, 22, + 22, 23, 26, 23, 21, 28, 28, 23, 23, 22, 21, + 20, 14, 6, -1, -5, -8, -5, -1, 2, 5, 5, + 7, 8, 5, 4, 0, 3, 6, 10, 13, 13, 6, + 4, 4, 0, -2, -3, 0, 3, 5, 7, 9, 7, + 6, 10, 8, 3, 4, -1, -4, -2, 0, -2, -2, + -2, -3, 5, 8, 6, 4, -1, -7, -6, -7, -12, + -18, -11, -2, -1, -1, -1, -2, -7, -7, -3, -3, + -5, -6, -6, -6, -6, -6, -9, -12, -9, -5, 1, + 3, 5, 5, 8, 7, 3, -5, -3, -2, 2, 3, + 5, 5, -1, -2, -4, -8, -9, -9, -7, -12, -13, + -17, -19, -16, -19, -21, -21, -19, -11, -6, -3, 7, + 8, 6, 2, 0, 1, 1, -2, -5, 0, -2, 2, + 1, 2, 0, -2, -1, -10, -21, -25, -24, -21, -19, + -14, -8, -3, -5, 0, 0, -5, -6, -3, -6, -9, + -13, -19, -20, -21, -21, -24, -25, -27, -27, -29, -26, + -19, -14, -14, -13, -8, -5, -10, -10, -6, 1, 4, + 14, 22, 23, 24, 20, 20, 18, 14, 11, 9, 6, + 8, 12, 15, 18, 18, 12, 8, 9, 9, 9, 7, + 4, 9, 5, 6, 5, 3, 3, -1, -1, -6, -10, + -6, -8, -3, 0, -2, -3, -2, -6, -6, -7, -3, + -3, -3, -2, 1, -1, -10, -7, -13, -21, -23, -20, + -19, -18, -18, -19, -15, -16, -7, -6, -9, -13, -12, + -6, -1, 3, 6, 7, 5, 3, -3, -11, -18, -20, + -26, -29, -27, -27, -24, -30, -29, -28, -23, -18, -21, + -18, -15, -9, 1, 9, 17, 21, 23, 18, 14, 5, + -1, -2, -1, 0, 3, 6, 5, 4, 4, 0, -1, + 1, -4, -9, -13, -11, -20, -21, -19, -14, -9, -4, + 1, 6, 10, 16, 24, 30, 35, 31, 38, 37, 35, + 39, 36, 36, 32, 30, 33, 31, 24, 19, 12, 4, + -1, -7, -11, -7, -5, -3, 2, 6, 10, 16, 19, + 21, 21, 16, 10, 14, 12, 14, 13, 12, 12, 5, + 6, 2, 0, 1, 3, 4, 6, 9, 6, 2, -1, + -3, -10, -15, -13, -17, -19, -15, -16, -15, -13, -8, + -8, -7, -10, -5, -2, 1, 5, 5, 11, 10, 12, + 10, 9, 9, 15, 23, 33, 35, 33, 34, 34, 35, + 34, 24, 30, 26, 23, 21, 20, 15, 10, 3, 4, + 0, -7, -8, -9, -9, -8, -4, 0, 5, 5, 2, + 3, -2, 0, 0, -1, 0, -1, 1, 2, 6, 3, + 1, -9, -5, -6, -2, -8, -12, -9, -10, -7, -8, + -8, -6, -2, -2, -1, 0, -2, -1, -8, -18, -19, + -27, -37, -42, -40, -39, -33, -30, -23, -16, -16, -9, + -13, -11, -10, -10, -8, -3, -1, 2, 0, -1, 2, + 6, 4, 8, 10, 17, 21, 28, 31, 33, 28, 20, + 12, 8, -3, -5, -4, -3, 2, 6, 9, 8, 2, + 7, 4, -6, -9, -15, -13, -15, -17, -14, -11, -12, + -5, -6, -4, -6, -11, -11, -7, -4, -6, -8, -13, + -10, -7, -12, -11, -12, -13, -12, -9, -9, -10, -10, + -6, -8, -8, -7, -9, -9, -7, 2, 5, 5, 6, + 3, 4, 6, 3, -1, -2, -2, -2, 1, 5, 3, + 4, 2, -2, -7, -9, -13, -11, -8, 2, 12, 23, + 31, 37, 41, 40, 37, 36, 31, 31, 27, 28, 24, + 13, 16, 14, 15, 9, 4, 4, 5, 4, 7, 12, + 16, 14, 11, 13, 6, -2, -4, -1, -3, 3, 6, + 6, 9, 7, 9, 7, 5, 0, 1, -1, -2, -4, + -1, 0, 0, -4, 0, -4, -9, -15, -16, -18, -15, + -10, -6, -8, -5, -2, -2, 0, 4, 7, 0, -2, + -3, 4, 3, 2, -1, -3, -8, -19, -19, -19, -16, + -8, -5, 0, 1, 2, 1, -1, -2, -10, -12, -10, + -4, 3, 4, 2, 7, 8, 4, 1, -5, -5, -4, + -1, 9, 10, 12, 15, 15, 14, 11, 20, 16, 19, + 18, 26, 29, 21, 23, 16, 16, 3, -3, -4, -10, + -12, -10, -6, -7, -12, -17, -14, -16, -19, -13, -10, + -13, -13, -2, 2, 3, 7, 13, 22, 21, 21, 21, + 24, 27, 23, 22, 20, 17, 17, 16, 13, 11, 5, + 1, 1, 5, 5, 3, 2, -1, 2, -5, -6, -3, + -11, -9, -6, -5, -10, -4, -1, 1, 2, -1, -4, + -4, -9, -9, -7, -3, 3, -2, 1, 1, 4, -4, + -8, -8, -17, -17, -13, -13, -18, -18, -25, -27, -21, + -22, -18, -7, -1, 5, 9, 11, 11, 11, 15, 11, + 4, 1, 6, 8, 17, 12, 10, 5, -2, -3, -14, + -17, -25, -26, -22, -20, -13, -12, -12, -13, -10, -4, + -6, -6, -4, -6, -4, 0, -3, -7, -7, -10, -17, + -14, -9, -3, 4, 4, 6, 1, 0, 0, -6, -3, + -4, -3, -6, -9, -9, -5, 0, 1, 2, -2, 3, + -1, -4, -5, -11, -14, -17, -14, -12, -14, -19, -21, + -25, -35, -40, -39, -31, -24, -13, -4, -1, 0, 0, + 2, -2, -5, -8, -8, -9, -6, -2, 0, -5, -6, + 2, 5, 4, 1, 6, 8, 9, 14, 13, 19, 15, + 19, 13, 14, 20, 16, 16, 14, 14, 17, 13, 12, + 11, 6, -1, -7, -9, -10, -11, -2, 8, 12, 12, + 12, 8, 4, 1, -3, -4, -4, -3, 1, 9, 14, + 16, 10, 12, 9, 6, 4, -1, 8, 6, 3, 6, + 1, -11, -10, -10, -13, -9, -6, -2, -2, 9, 13, + 17, 17, 19, 17, 16, 9, -2, -5, -5, -3, -9, + -8, -8, -12, -17, -16, -18, -15, -9, -7, 1, 10, + 17, 18, 23, 25, 23, 20, 15, 17, 18, 23, 33, + 40, 43, 45, 51, 53, 47, 36, 27, 10, 5, 1, + 4, 5, 4, 0, 0, 6, 7, 8, 9, 3, 2, + 1, 0, -1, 3, 5, 5, 13, 7, 4, 4, 3, + 11, 17, 21, 31, 31, 31, 31, 28, 26, 23, 19, + 16, 17, 16, 10, 10, 12, 9, 7, -1, -7, -12, + -15, -15, -15, -13, -13, -16, -19, -19, -23, -31, -34, + -38, -39, -31, -30, -21, -21, -18, -11, -16, -20, -25, + -22, -18, -14, -7, -8, -3, 2, 10, 13, 12, 10, + 6, 2, 0, 0, 0, -6, -4, -1, 0, 0, -1, + -2, 1, 3, 8, 9, 3, 6, 2, -4, -2, -3, + -7, -4, -3, 2, 6, 8, 10, 12, 15, 11, 15, + 12, 13, 14, 15, 18, 14, 8, 4, 4, 3, -4, + -5, -4, -2, -3, -2, 4, 9, 13, 18, 21, 20, + 18, 15, 11, 6, 7, 10, 8, 6, 3, -3, -7, + -14, -21, -29, -33, -32, -26, -17, -12, -11, -9, -3, + -10, -13, -18, -23, -21, -26, -26, -24, -28, -25, -29, + -30, -30, -27, -17, -7, 2, 10, 13, 16, 16, 17, + 18, 17, 19, 19, 20, 15, 14, 16, 14, 10, 5, + 0, -4, -18, -21, -25, -20, -16, -13, -8, -5, 2, + 6, 11, 12, 18, 16, 18, 15, 13, 17, 18, 22, + 21, 25, 26, 25, 26, 28, 31, 27, 20, 10, 3, + -6, -10, -16, -19, -18, -15, -13, -10, -2, 0, 2, + 4, 3, 5, -1, 0, 1, 2, 0, -2, -1, -6, + -5, -7, -12, -10, -9, -4, -1, 3, 4, 2, 4, + 4, 3, -3, -6, -11, -14, -15, -23, -25, -29, -30, + -28, -25, -22, -19, -21, -19, -11, -7, -7, -3, -3, + -6, -8, -13, -10, -10, -5, 1, 4, 9, 7, 6, + 6, 4, -5, -11, -8, -6, -3, 0, 3, 7, 11, + 7, 3, 5, 6, 10, 12, 14, 16, 8, 5, -1, + -1, 4, 0, 0, -3, -5, -5, -4, -2, -2, 1, + 4, 7, 5, 10, 9, 6, 9, 12, 19, 28, 32, + 32, 33, 31, 29, 20, 17, 16, 14, 15, 6, -2, + -5, -7, -10, -10, -11, -9, -6, -3, 8, 10, 10, + 10, 12, 12, 7, 7, 5, 3, 2, 2, -2, -5, + -4, -7, -2, -6, -5, -6, -11, -14, -13, -10, -11, + -15, -16, -11, -11, -11, -10, -16, -15, -15, -16, -10, + -11, -11, -5, -1, 2, 1, 2, 0, 1, 4, 8, + 5, -4, -2, -4, -12, -18, -24, -20, -25, -14, -3, + 4, 11, 13, 13, 7, 4, -4, -9, -13, -17, -10, + -6, -1, 0, 2, 2, -1, 1, -8, -18, -22, -19, + -19, -22, -20, -22, -20, -17, -12, -9, -4, 3, 9, + 9, 9, 7, 6, 13, 10, 11, 8, 4, -1, 5, + 7, 7, 8, 4, 2, 2, -2, -8, -11, -16, -18, + -12, -12, -9, -2, 3, 3, 5, 5, 6, 9, 11, + 20, 22, 26, 30, 28, 22, 15, 15, 10, 11, 9, + 6, 9, 9, 11, 10, 12, 10, 8, 8, 7, 9, + 4, 3, 9, 5, 1, 2, 0, -3, -3, 0, 3, + 0, -2, 1, 4, 6, 4, 0, 1, -4, -13, -13, + -11, -20, -21, -15, -17, -23, -22, -24, -29, -24, -29, + -32, -21, -13, -11, -9, -9, -8, -13, -11, -11, -11, + -11, -17, -17, -21, -23, -27, -32, -33, -32, -31, -35, + -31, -26, -24, -18, -10, -1, 5, 13, 17, 15, 13, + 8, 4, 6, 9, 10, 13, 11, 12, 13, 9, 5, + 6, 8, 12, 21, 25, 24, 23, 16, 8, 7, 0, + -3, -8, -9, -2, 1, 11, 18, 25, 30, 31, 27, + 21, 19, 19, 18, 18, 22, 24, 16, 14, 8, 2, + -4, -9, -7, -10, -6, -8, -8, -13, -14, -11, -13, + -8, -7, 6, 9, 10, 15, 17, 11, 11, 9, 2, + 2, -2, 2, -6, -6, -7, -14, -11, -12, -13, -17, + -22, -25, -30, -24, -16, -4, 5, 2, 7, 5, 2, + -1, 1, -4, -4, 4, 8, 8, 5, 6, 6, 2, + 1, -2, -9, -14, -17, -16, -15, -14, -12, -11, -6, + -6, -2, -3, -3, 6, 13, 18, 27, 27, 26, 24, + 22, 19, 18, 19, 12, 8, 7, -2, 0, -6, -8, + -6, -4, -6, -14, -16, -16, -15, -12, -2, 6, 12, + 16, 18, 14, 16, 13, 12, 17, 16, 17, 17, 12, + 13, 10, 14, 14, 10, 2, -1, -3, -5, -10, -15, + -13, -20, -21, -21, -21, -19, -20, -18, -8, -4, -1, + -1, 4, 2, -3, 0, -5, -5, -3, -1, 0, 6, + 5, 6, 7, 7, 3, 2, 1, -5, -3, 0, 3, + 5, 7, 4, 10, 15, 15, 11, 6, 8, 9, 14, + 19, 18, 14, 12, 16, 15, 11, 9, 9, 5, 4, + 0, -7, -12, -18, -22, -29, -32, -36, -37, -38, -39, + -32, -24, -20, -14, -10, -2, 0, 1, 9, 13, 21, + 26, 31, 35, 40, 38, 32, 33, 25, 14, 11, 7, + 1, -1, -6, -5, -11, -20, -22, -19, -16, -9, 2, + 9, 14, 14, 13, 13, 12, 10, 3, 2, 1, 0, + 6, 5, -1, -4, -13, -17, -21, -25, -29, -30, -23, + -14, -4, 4, 11, 11, 12, 13, 13, 5, 6, 6, + 7, 5, 5, 9, -2, 3, 0, -2, -3, -5, -1, + 3, 9, 16, 18, 17, 17, 11, 5, 1, -4, -13, + -12, -7, -7, 1, 6, 4, 2, 3, 1, 1, 0, + -1, -5, -5, -3, -5, -1, 8, 9, 7, 12, 7, + 6, 4, 3, -1, -1, -4, -14, -16, -18, -24, -34, + -44, -37, -37, -36, -28, -19, -15, -6, -2, -3, 2, + 5, 6, 3, 6, 6, 9, 7, 3, -4, -15, -25, + -34, -37, -41, -41, -38, -33, -27, -22, -14, -15, -18, + -18, -15, -8, -7, -2, 2, 0, 4, 12, 13, 10, + 17, 20, 16, 17, 23, 24, 22, 24, 22, 28, 26, + 24, 22, 26, 28, 27, 23, 17, 10, 4, 4, 1, + -1, 0, 4, 9, 15, 14, 15, 14, 14, 13, 8, + 0, -1, -11, -13, -4, -3, -5, -3, -1, -6, -5, + -7, -4, -2, 2, 7, 15, 20, 14, 13, 8, 2, + -6, -15, -23, -25, -20, -22, -20, -14, -10, -4, -2, + 1, -10, -15, -12, -8, -8, -7, -5, -10, -12, -20, + -28, -26, -24, -16, -8, -5, 3, 8, 9, 12, 12, + 12, 14, 13, 12, 10, 13, 23, 29, 28, 33, 36, + 32, 28, 23, 25, 26, 30, 34, 27, 22, 16, 12, + 3, -6, -13, -13, -15, -14, -9, -11, -13, -13, -16, + -15, -20, -22, -20, -32, -30, -29, -24, -18, -18, -18, + -13, -15, -15, -16, -17, -10, -11, -12, -15, -17, -17, + -19, -21, -22, -26, -28, -21, -18, -14, -5, 2, 6, + 7, 5, 3, -2, 0, -4, -2, -3, -6, -9, -12, + -11, -11, -19, -23, -20, -21, -16, -19, -23, -22, -24, + -21, -22, -17, -15, -8, -1, 4, 14, 18, 23, 24, + 25, 25, 18, 15, 7, 2, 14, 19, 22, 20, 23, + 22, 20, 19, 20, 17, 16, 21, 22, 21, 18, 9, + 3, -6, -14, -19, -30, -36, -40, -32, -22, -21, -16, + -7, -1, 3, 2, 3, 6, 9, 16, 20, 22, 26, + 27, 29, 32, 30, 23, 19, 20, 21, 18, 22, 24, + 15, 14, 9, 9, 7, 6, 9, 9, 16, 22, 20, + 18, 18, 9, -1, -10, -16, -19, -22, -22, -20, -16, + -11, -5, 0, 1, 4, 2, 0, 3, 5, 10, 8, + 12, 10, 11, 9, 8, 7, -3, -4, -10, -11, -5, + 2, 8, 12, 12, 13, 14, 15, 14, 12, 10, 14, + 13, 8, 0, -2, -3, -9, -6, -13, -21, -12, -12, + -8, -9, -14, -16, -19, -23, -22, -23, -30, -26, -17, + -14, -9, -2, 3, 11, 16, 17, 17, 11, 12, 13, + 12, 9, 8, 7, 10, 17, 14, 13, 9, 7, 6, + 5, 10, 10, 6, 10, 9, 1, -5, -10, -12, -17, + -16, -14, -13, -10, -6, -2, 0, -1, 2, 2, -1, + 2, 6, 12, 18, 23, 22, 23, 24, 20, 16, 10, + 6, 9, 16, 15, 15, 16, 14, 8, 4, 0, -3, + -7, -4, -5, -5, 0, -4, 1, 1, 1, -4, -10, + -17, -25, -25, -28, -28, -27, -25, -20, -20, -20, -22, + -14, -11, -4, 4, 6, 11, 10, 12, 9, 6, 2, + -6, -10, -12, -7, -1, -6, 0, 1, 2, 5, 1, + -1, 1, -3, -6, -4, -5, -4, -6, -5, -7, -10, + -10, -8, -11, -9, -2, 9, 15, 14, 20, 19, 19, + 16, 16, 11, 3, 2, 2, 5, 4, 5, 3, -1, + -1, -6, -11, -16, -18, -18, -12, -17, -18, -13, -15, + -5, -4, -3, -1, 2, 6, 7, 11, 14, 17, 17, + 18, 21, 18, 19, 18, 23, 27, 36, 32, 35, 30, + 24, 25, 18, 10, 3, -1, -4, -11, -16, -21, -33, + -37, -35, -36, -35, -30, -26, -26, -21, -10, -7, -3, + -4, -3, -3, -9, -12, -16, -25, -22, -11, -6, 2, + 5, 7, 4, -2, -8, -16, -23, -30, -28, -23, -20, + -11, -11, -8, 5, 2, -3, -1, -11, -15, -10, -13, + -8, -8, -12, -9, -10, -15, -8, -4, -3, 7, 6, + 13, 20, 25, 24, 25, 27, 28, 25, 23, 22, 27, + 28, 27, 30, 28, 26, 20, 16, 13, 7, 2, 1, + 6, 3, -4, -6, -13, -18, -19, -21, -15, -3, -1, + 10, 16, 17, 20, 24, 28, 28, 26, 26, 28, 27, + 24, 23, 20, 20, 24, 20, 17, 14, 6, 0, 2, + 1, 0, -3, -7, -12, -18, -29, -28, -30, -32, -23, + -27, -25, -20, -17, -13, -11, -14, -17, -21, -22, -18, + -11, -12, -6, -8, -9, -5, -6, -10, -18, -19, -16, + -13, -9, -6, -7, -13, -10, -14, -22, -30, -37, -35, + -37, -35, -34, -36, -30, -23, -17, -16, -16, -11, -6, + -2, 3, 7, 7, 6, 7, 7, 13, 21, 20, 22, + 23, 22, 24, 17, 5, -1, -2, -8, -13, -14, -17, + -24, -28, -23, -22, -19, -12, -14, -10, -14, -21, -20, + -21, -22, -13, -6, -1, 6, 4, 10, 11, 8, 10, + 10, 17, 20, 27, 34, 32, 26, 26, 24, 17, 13, + 6, 9, 12, 15, 17, 12, 11, 9, 3, -3, -3, + -8, -9, -4, -2, -2, 2, 1, -1, -3, -7, -8, + -11, -15, -8, -5, 1, 9, 7, 10, 13, 17, 14, + 12, 8, 6, 3, 6, 9, 8, 5, 0, -2, 1, + 1, -3, -6, -12, -17, -17, -23, -28, -33, -31, -29, + -30, -35, -28, -25, -17, -5, 0, 6, 10, 14, 27, + 31, 26, 31, 30, 32, 41, 42, 42, 43, 34, 32, + 21, 12, 2, 1, -3, -1, 8, 13, 20, 19, 18, + 19, 13, 8, 5, 7, 6, 7, 6, 4, 3, -2, + 0, 2, -4, -1, -3, 2, 12, 22, 33, 32, 31, + 35, 35, 34, 32, 26, 27, 26, 21, 17, 10, 1, + -3, -14, -21, -19, -21, -19, -24, -24, -19, -16, -13, + -16, -13, -15, -17, -12, -9, -4, 7, 19, 27, 33, + 37, 34, 35, 30, 24, 23, 25, 21, 20, 18, 15, + 12, 13, 8, 2, -4, -12, -18, -17, -14, -10, -14, + -8, -14, -14, -12, -14, -19, -23, -31, -32, -28, -30, + -22, -20, -13, 1, 0, 6, 14, 15, 20, 22, 20, + 16, 9, 2, 1, 3, 6, 7, 9, 10, 14, 17, + 16, 14, 4, -7, -16, -31, -40, -41, -40, -38, -34, + -40, -37, -33, -28, -22, -17, -11, -10, -12, -5, -5, + -8, -4, 0, -1, 1, 1, 6, 11, 14, 22, 25, + 28, 31, 32, 32, 31, 31, 20, 13, 12, 5, 4, + 4, 2, 0, -3, -6, -8, -4, -4, -4, -1, 7, + 9, 10, 13, 13, 16, 10, 7, 3, 6, 8, 8, + 15, 20, 23, 18, 15, 12, 4, 1, 0, -4, -4, + -1, 8, 11, 13, 21, 24, 19, 12, 2, -5, -11, + -15, -17, -17, -19, -23, -28, -34, -33, -37, -29, -27, + -24, -17, -13, -8, -6, -2, 5, 3, 4, -2, -5, + -4, 0, 2, 3, 1, -5, -5, -6, -11, -11, -15, + -15, -19, -17, -17, -21, -23, -21, -22, -24, -28, -27, + -25, -15, -8, -1, 2, 2, 3, 3, 2, -2, 0, + 1, -1, 2, 5, 7, 2, 0, 2, -6, -9, -8, + -6, -3, -3, 3, 0, 5, 0, 0, -5, -12, -13, + -20, -14, -14, -6, -5, -2, 0, 6, 11, 9, 9, + 11, 10, 13, 19, 26, 29, 36, 37, 40, 35, 27, + 20, 13, 6, 3, -1, -1, -1, -3, -6, -8, -14, + -16, -25, -28, -23, -21, -24, -22, -22, -22, -24, -28, + -35, -43, -42, -37, -29, -20, -5, 2, 10, 23, 28, + 30, 31, 30, 39, 43, 40, 41, 43, 43, 38, 29, + 18, 14, 12, 3, 6, 3, 3, 0, -1, -3, -5, + -5, -8, -8, -10, -6, -1, 1, 5, 1, 2, 6, + 0, -3, -7, -13, -10, -7, -8, -7, -3, -5, -4, + -4, -4, -5, -2, 2, 3, 6, 4, 3, -1, -2, + -5, -16, -22, -31, -39, -38, -42, -47, -42, -42, -35, + -27, -30, -28, -25, -26, -24, -20, -19, -19, -19, -19, + -14, -16, -13, -9, -10, -1, 8, 17, 21, 28, 26, + 28, 24, 14, 8, 2, 0, -4, -4, -13, -16, -16, + -13, -12, -7, -5, 0, -4, -1, 2, 4, 8, 8, + 10, 10, 10, 14, 16, 17, 23, 20, 27, 27, 27, + 21, 14, 11, 0, -4, -8, -8, -1, -1, 1, 6, + 8, 23, 22, 23, 23, 25, 26, 26, 22, 21, 20, + 22, 17, 12, 8, 3, -2, -2, -4, -5, -3, 1, + 7, 6, 8, 9, 12, 6, 1, -4, -8, -6, -3, + -4, -5, -3, -7, -6, -6, -11, -11, -19, -23, -26, + -28, -34, -41, -41, -44, -45, -47, -40, -39, -33, -29, + -21, -14, -16, -6, -7, -3, 1, 6, 8, 11, 14, + 14, 15, 15, 18, 18, 16, 17, 12, 15, 20, 21, + 19, 21, 23, 22, 21, 16, 12, 8, 7, 7, 10, + 13, 13, 16, 16, 16, 16, 15, 15, 12, 14, 14, + 15, 12, 11, 17, 19, 19, 14, 13, 15, 17, 18, + 20, 24, 27, 24, 19, 11, 10, 1, 0, 0, -1, + 3, 8, 16, 18, 17, 22, 22, 21, 19, 7, 0, + 1, -1, -2, -1, -6, -8, -12, -14, -20, -21, -24, + -19, -9, -4, -3, 2, 2, 3, 0, -10, -19, -23, + -29, -31, -35, -29, -33, -28, -25, -25, -19, -22, -23, + -24, -21, -17, -15, -17, -13, -15, -12, -15, -14, -14, + -12, -9, -5, 1, 9, 13, 13, 17, 17, 15, 11, + 12, 8, 13, 20, 24, 30, 29, 33, 30, 26, 23, + 13, 9, 4, 3, 3, 5, 3, 2, 5, 3, 2, + 1, 3, 6, 10, 14, 19, 23, 21, 20, 21, 17, + 11, 5, -3, -7, -12, -15, -16, -13, -15, -13, -7, + -4, -5, -5, -1, 5, 11, 8, 7, -2, -2, -5, + -6, -1, -2, 0, 2, 8, 13, 15, 17, 15, 16, + 10, 13, 3, -1, -4, -4, -4, 0, 8, 13, 15, + 9, 11, 9, 12, 9, 10, 10, 5, 11, 16, 21, + 20, 15, 13, 5, 3, -3, 1, 1, 0, -4, -7, + -9, -7, -9, -10, -7, -6, -3, -2, -3, -3, -6, + -12, -16, -22, -21, -26, -28, -25, -24, -23, -23, -28, + -32, -29, -26, -26, -23, -29, -23, -16, -11, -7, -9, + -10, -12, -18, -20, -20, -26, -23, -16, -17, -10, -7, + 0, 3, -2, 0, -4, -7, -8, -6, -3, -7, -5, + -5, 1, 0, -3, -2, -3, 5, 7, 10, 19, 17, + 22, 21, 20, 16, 8, 9, 10, 12, 20, 28, 31, + 28, 28, 26, 21, 14, 8, 5, 4, 5, 8, 9, + 9, 13, 17, 16, 14, 20, 17, 13, 16, 17, 18, + 18, 15, 11, 5, -2, -8, -15, -17, -17, -24, -24, + -23, -18, -13, -13, -9, -7, -4, 0, 3, 6, 2, + 2, -4, -5, -5, -4, -4, -2, 2, 6, 10, 7, + 4, 2, -2, -3, -8, -10, -14, -27, -29, -37, -36, + -29, -27, -19, -7, -3, 0, -2, 2, 8, 13, 18, + 15, 10, 10, 6, 1, -5, -12, -17, -20, -23, -23, + -22, -19, -17, -10, -6, -3, 2, 0, 4, 11, 14, + 19, 16, 6, 7, 3, 3, 4, 1, 7, 8, 7, + 3, -2, 0, 0, 0, -1, -2, 0, 4, 3, 5, + 9, 9, 12, 7, 5, 0, 0, 1, 0, 2, -6, + -10, -9, -13, -15, -19, -15, -18, -16, -17, -9, -5, + -2, 2, 2, 3, 7, 2, -3, -8, -13, -8, 1, + 8, 12, 15, 17, 17, 11, 7, 0, -4, -8, -8, + -3, -1, -4, -6, -6, -13, -12, -12, -13, -12, -8, + -9, -5, -4, -2, 0, -1, -6, -7, -6, -10, -10, + -8, -6, 1, 5, 6, 15, 18, 16, 12, 12, 12, + 10, 13, 7, 0, -9, -10, -11, -6, -8, -8, -4, + 0, 6, 10, 11, 15, 15, 15, 12, 10, 6, 6, + 11, 12, 20, 25, 23, 25, 18, 12, 6, -1, -4, + -10, -12, -9, -13, -16, -15, -18, -18, -22, -22, -17, + -14, -12, -8, -3, 1, 4, 11, 13, 7, 0, -8, + -11, -11, -13, -14, -12, -11, -9, -6, -5, -2, 1, + 5, 6, 10, 18, 17, 15, 13, 11, 12, 13, 10, + 9, 13, 16, 16, 13, 11, 6, 5, 0, -5, -4, + -3, 2, 6, 5, 6, 11, 14, 20, 23, 28, 27, + 22, 24, 23, 22, 16, 17, 12, 7, -1, -9, -10, + -9, -9, -13, -11, -9, -2, -2, -7, -8, -6, -7, + -12, -12, -10, 0, 5, 11, 13, 11, 10, 7, 3, + 0, 0, 3, 10, 14, 16, 18, 19, 21, 14, 15, + 12, 7, 6, 7, 9, 7, 11, 6, 4, 4, -1, + -9, -12, -12, -14, -9, -9, -6, -5, -4, -6, -7, + -12, -15, -17, -27, -23, -20, -19, -19, -18, -24, -20, + -25, -28, -33, -31, -29, -27, -15, -12, -7, -3, 1, + -3, -3, -5, -8, -6, 0, 13, 17, 24, 25, 23, + 24, 18, 8, -3, -4, -4, -7, -3, 1, 4, 7, + 9, 10, 14, 14, 20, 28, 35, 38, 42, 43, 43, + 39, 30, 27, 19, 15, 8, 10, 12, 19, 25, 26, + 27, 23, 22, 15, 10, 6, 8, 4, 6, 6, 3, + 7, 7, 15, 11, 7, 6, 5, 9, 6, 0, -3, + -14, -21, -21, -30, -39, -42, -40, -37, -37, -36, -32, + -30, -24, -21, -22, -23, -24, -28, -31, -31, -29, -27, + -30, -31, -31, -31, -34, -33, -34, -26, -21, -15, -10, + -5, -3, -2, -3, -6, -5, -11, -14, -10, -5, 0, + 9, 10, 18, 21, 19, 21, 11, 7, 4, 6, 6, + 7, 3, -6, -9, -16, -23, -24, -23, -26, -18, -16, + -11, -8, 0, 6, 5, 6, 10, 8, 8, 16, 24, + 24, 23, 24, 24, 24, 18, 9, 4, -3, -11, -16, + -15, -18, -14, -12, -9, -3, -4, -1, 8, 11, 10, + 19, 21, 21, 23, 20, 22, 15, 9, 7, 5, 3, + 1, 12, 13, 10, 18, 23, 31, 37, 40, 36, 38, + 40, 40, 38, 27, 24, 21, 14, 12, 12, 7, 7, + 15, 18, 19, 18, 17, 18, 14, 12, 11, 7, 5, + 7, 9, 9, 15, 14, 15, 18, 16, 7, 0, -5, + -6, -6, -6, -1, 7, 9, 12, 6, 4, 4, 2, + -1, 2, 3, 3, 5, 4, -1, -13, -19, -29, -34, + -39, -43, -49, -54, -53, -55, -55, -56, -59, -58, -49, + -41, -32, -19, -10, -2, -4, -1, -6, -19, -27, -26, + -27, -27, -21, -22, -20, -26, -26, -20, -20, -20, -21, + -17, -18, -7, -6, -6, -5, -1, 7, 18, 10, 16, + 25, 24, 31, 30, 32, 30, 26, 24, 22, 23, 21, + 23, 21, 24, 19, 17, 13, 12, 15, 6, 2, -5, + -9, -13, -10, -5, 1, 10, 13, 17, 13, 8, 5, + 5, 6, 5, 13, 19, 16, 14, 12, 7, 15, 18, + 19, 16, 4, -1, 0, -1, -2, -9, -15, -19, -21, + -13, -13, -10, -7, -7, -7, -6, -11, -22, -18, -19, + -22, -22, -19, -18, -10, -7, -9, -7, -12, -16, -20, + -27, -35, -37, -37, -33, -24, -14, -4, 8, 14, 19, + 19, 16, 12, 6, 2, -5, -6, -11, -17, -16, -14, + -13, -12, -17, -21, -22, -24, -18, -14, -12, -1, 4, + 9, 17, 14, 9, 13, 14, 13, 14, 14, 12, 11, + 15, 11, 16, 21, 20, 20, 22, 31, 30, 26, 15, + 13, 6, 8, 5, 1, -5, -3, 2, 9, 14, 13, + 16, 17, 18, 13, 10, 8, 7, 9, 12, 21, 23, + 23, 21, 19, 16, 14, 5, -4, -12, -15, -16, -12, + -9, -12, -14, -17, -16, -15, -14, -15, -28, -27, -24, + -12, -8, -3, 3, 9, 15, 18, 25, 25, 31, 32, + 35, 36, 33, 36, 24, 13, 2, -11, -19, -18, -18, + -10, -6, -4, 0, -3, -3, -15, -18, -17, -9, -7, + 2, 5, 7, 6, 2, -2, -12, -16, -16, -9, -3, + 6, 8, 15, 17, 16, 18, 11, 5, -4, -8, -17, + -16, -22, -24, -25, -28, -23, -19, -11, -3, 5, 11, + 22, 26, 29, 24, 14, 12, 7, 6, -2, -1, 2, + 10, 23, 33, 36, 32, 31, 16, 3, -4, -3, -3, + 1, 8, 11, 13, 12, 8, 3, 5, 3, 1, -1, + 4, 2, 3, 8, 5, 5, 1, -2, -1, -3, -1, + 5, 8, 10, 17, 17, 15, 19, 27, 18, 21, 23, + 19, 20, 15, 1, -7, -18, -24, -24, -33, -28, -32, + -30, -30, -30, -30, -29, -30, -41, -43, -50, -51, -49, + -42, -32, -19, -10, 0, 4, -2, 5, 9, 8, 12, + 19, 17, 10, 9, 3, 1, -4, -8, -4, 0, 5, + 7, 10, 9, 12, 0, -6, -7, -13, -16, -10, -10, + -9, -1, -1, -2, -6, -11, -14, -17, -18, -10, -3, + -3, 0, 6, 1, 6, 4, 3, 3, 9, 16, 22, + 28, 27, 32, 18, 21, 25, 20, 21, 18, 18, 22, + 23, 15, 8, -3, -9, -10, -13, -8, 3, 7, 18, + 26, 23, 26, 30, 17, 11, 9, -1, 0, 2, 2, + 12, 15, 6, 1, 0, -5, 2, 1, -3, -1, -6, + -2, -4, -11, -18, -30, -38, -36, -33, -32, -27, -19, + -18, -14, -13, -16, -11, -12, -12, -4, 0, 7, 13, + 13, 10, 11, 6, 3, 3, 3, 4, 10, 4, -1, + -3, -11, -21, -27, -34, -33, -31, -33, -28, -22, -21, + -14, -8, -13, -10, -8, -12, -7, -11, -3, 3, 5, + 7, 7, -1, -12, -13, -17, -21, -8, -2, 4, 7, + 13, 18, 18, 16, 15, 13, 11, 15, 13, 12, 17, + 18, 15, 15, 11, -3, -1, 2, 11, 15, 10, 18, + 13, 10, 12, 9, 2, 2, 4, -1, 6, 9, 11, + 5, 7, 13, 8, 9, 10, 11, 9, 7, 11, 5, + 3, 1, -9, -19, -31, -40, -42, -33, -27, -24, -22, + -20, -25, -20, -12, -17, -23, -23, -25, -25, -20, -18, + -17, -19, -15, -22, -20, -19, -13, -8, -12, 0, 2, + -6, -1, -5, -15, -10, -12, -19, -8, -6, -3, 9, + 5, 12, 22, 10, 9, 12, 5, 8, 28, 13, 20, + 25, 11, 16, 19, 10, 15, 14, 6, 23, 19, 18, + 32, 17, 12, 19, -1, -8, 11, -4, -8, 9, -4, + -6, 0, -10, -7, -3, -8, -11, -11, -23, -7, -4, + -4, 14, 6, 4, 9, 3, -4, 4, 2, 9, 26, + 19, 26, 33, 22, 22, 24, 13, 20, 18, 18, 28, + 28, 19, 24, 16, -1, 1, -12, -34, -28, -25, -27, + -13, 6, 8, 21, 25, 22, 19, 3, 4, 0, -5, + 6, 8, 1, 6, 8, -4, -3, -10, -23, -17, -9, + -10, 3, 6, -1, 3, -10, -22, -28, -49, -49, -36, + -29, -10, 8, -1, 4, 14, -3, -14, -5, -16, -10, + 8, 7, 21, 24, 17, 25, 15, -4, 13, -7, -23, + 0, -7, -14, 12, 1, -18, -10, -27, -43, -31, -34, + -19, -3, -10, 15, 20, -7, 10, 9, -20, 7, 28, + 14, 42, 54, 32, 34, 24, 5, 10, -11, -13, 11, + -6, -4, 31, 7, 0, 34, 3, -9, 5, -24, -33, + -14, -11, -1, 8, 0, 10, 7, -7, 11, 10, -6, + 17, 16, 0, 10, 3, -26, -23, -33, -39, -26, -29, + -18, -6, -9, -1, 5, -11, -6, 7, -6, 1, 13, + 8, 1, 3, -13, -23, -25, -33, -28, -21, -9, 2, + 4, 1, 8, 4, -13, -5, -12, -14, 3, 14, 18, + 26, 30, 21, 20, 15, 15, 10, 5, 13, 11, 20, + 25, 29, 18, 19, 9, -10, -15, -13, -12, 1, 16, + 20, 30, 39, 37, 21, 15, 3, -7, -9, -1, 2, + -6, -7, -10, -20, -19, -19, -31, -25, -12, -15, -13, + -17, -18, -14, -24, -24, -18, -28, -24, -3, 1, 17, + 46, 48, 43, 46, 34, 12, 6, -14, -19, -10, -14, + 3, 15, 3, 7, 7, -13, 4, 9, -2, 3, 22, + 19, 25, 41, 48, 46, 36, 42, 40, 24, 33, 50, + 29, 30, 57, 35, 13, 29, 17, -9, 5, 15, 7, + 13, 38, 47, 40, 56, 72, 42, 29, 40, 18, 14, + 36, 52, 50, 58, 55, 42, 22, 20, 13, -8, 8, + 32, 26, 41, 70, 48, 51, 65, 36, 27, 23, 4, + 5, 1, -3, 2, -8, -23, -6, -30, -46, -24, -40, + -45, -22, -32, -35, -24, -50, -41, -35, -56, -38, -29, + -55, -25, -7, -40, -26, -25, -63, -51, -40, -61, -47, + -38, -38, -5, 2, 3, 26, -1, -7, 8, -20, -17, + 10, -14, -6, 41, 24, 27, 52, 26, 13, 25, 5, + -6, 2, -7, -2, 10, 4, 29, 36, 30, 74, 93, + 91, 131, 150, 132, 167, 177, 158, 189, 188, 178, 200, + 199, 187, 212, 202, 188, 210, 188, 173, 187, 175, 183, + 215, 218, 236, 264, 253, 279, 296, 275, 290, 288, 261, + 261, 261, 230, 216, 199, 157, 160, 147, 115, 108, 84, + 50, 32, 7, -30, -56, -96, -130, -146, -179, -199, -223, + -255, -280, -293, -326, -341, -352, -391, -410, -429, -464, -489, + -507, -538, -559, -577, -602, -634, -656, -679, -696, -702, -700, + -699, -700, -687, -666, -665, -656, -634, -626, -609, -572, -539, + -518, -484, -462, -444, -418, -390, -364, -336, -295, -245, -210, + -175, -127, -97, -63, -28, 10, 45, 83, 121, 167, 222, + 272, 324, 369, 396, 439, 485, 502, 536, 571, 585, 618, + 656, 676, 705, 729, 744, 767, 776, 786, 798, 796, 813, + 849, 855, 865, 883, 862, 843, 834, 794, 781, 778, 767, + 746, 744, 721, 702, 681, 638, 607, 562, 521, 490, 447, + 398, 361, 313, 255, 204, 123, 20, -59, -143, -217, -270, + -328, -400, -462, -529, -607, -666, -737, -797, -854, -906, -936, + -944, -955, -965, -976, -993, -1003, -1007, -1032, -1040, -1045, -1055, + -1039, -1016, -1003, -990, -995, -1026, -1046, -1070, -1079, -1058, -1060, + -1062, -1028, -1010, -1006, -991, -1000, -1004, -987, -981, -958, -921, + -890, -852, -798, -754, -713, -681, -682, -658, -617, -585, -524, + -452, -404, -332, -258, -224, -183, -144, -132, -94, -64, -31, + 37, 99, 147, 219, 280, 329, 389, 439, 483, 563, 632, + 702, 799, 884, 965, 1050, 1107, 1150, 1209, 1260, 1308, 1383, + 1446, 1514, 1582, 1632, 1679, 1727, 1770, 1804, 1837, 1872, 1916, + 1961, 1999, 2038, 2071, 2089, 2097, 2107, 2091, 2084, 2072, 2051, + 2021, 1998, 1940, 1868, 1814, 1734, 1641, 1559, 1480, 1395, 1305, + 1213, 1115, 1015, 901, 785, 667, 520, 381, 256, 110, -26, + -141, -284, -417, -528, -670, -805, -935, -1080, -1206, -1324, -1438, + -1527, -1622, -1725, -1798, -1879, -1956, -2006, -2063, -2128, -2166, -2201, + -2238, -2257, -2292, -2316, -2337, -2357, -2356, -2362, -2382, -2375, -2368, + -2367, -2358, -2337, -2329, -2318, -2296, -2273, -2240, -2195, -2140, -2095, + -2044, -1990, -1932, -1872, -1803, -1737, -1673, -1602, -1520, -1428, -1325, + -1219, -1112, -1006, -896, -780, -681, -591, -481, -388, -294, -189, + -85, 30, 148, 252, 348, 466, 579, 692, 811, 918, 1041, + 1162, 1271, 1389, 1507, 1611, 1735, 1864, 1965, 2085, 2203, 2312, + 2436, 2536, 2614, 2697, 2760, 2812, 2886, 2956, 3010, 3066, 3088, + 3098, 3120, 3110, 3101, 3106, 3108, 3130, 3149, 3139, 3122, 3085, + 3016, 2951, 2874, 2770, 2671, 2559, 2435, 2315, 2198, 2059, 1915, + 1761, 1570, 1387, 1185, 984, 787, 601, 413, 224, 40, -158, + -348, -560, -760, -960, -1147, -1312, -1471, -1621, -1779, -1925, -2069, + -2206, -2333, -2463, -2570, -2664, -2743, -2811, -2860, -2886, -2934, -2976, + -3015, -3057, -3074, -3076, -3079, -3060, -3032, -2998, -2950, -2920, -2893, + -2863, -2837, -2806, -2761, -2715, -2662, -2607, -2554, -2486, -2402, -2325, + -2264, -2190, -2127, -2063, -1989, -1932, -1862, -1788, -1724, -1640, -1545, + -1455, -1346, -1234, -1112, -984, -859, -735, -610, -494, -384, -280, + -176, -68, 40, 140, 244, 363, 478, 596, 739, 876, 1001, + 1128, 1240, 1352, 1474, 1595, 1717, 1853, 1972, 2093, 2215, 2328, + 2432, 2533, 2641, 2744, 2855, 2949, 3055, 3157, 3242, 3329, 3415, + 3479, 3528, 3569, 3588, 3617, 3649, 3676, 3708, 3747, 3751, 3753, + 3744, 3693, 3640, 3576, 3470, 3369, 3248, 3098, 2976, 2838, 2690, + 2557, 2395, 2222, 2055, 1872, 1675, 1488, 1279, 1057, 851, 623, + 393, 180, -74, -315, -537, -771, -979, -1161, -1373, -1558, -1729, + -1932, -2110, -2294, -2478, -2636, -2785, -2917, -3007, -3094, -3183, -3247, + -3319, -3402, -3450, -3510, -3564, -3595, -3622, -3635, -3627, -3635, -3639, + -3620, -3620, -3610, -3596, -3581, -3535, -3495, -3455, -3410, -3361, -3323, + -3265, -3202, -3141, -3078, -3001, -2919, -2830, -2739, -2640, -2540, -2430, + -2320, -2192, -2057, -1909, -1761, -1603, -1422, -1244, -1059, -887, -726, + -570, -425, -256, -92, 69, 238, 411, 557, 728, 910, 1066, + 1229, 1403, 1561, 1727, 1895, 2050, 2208, 2352, 2492, 2638, 2765, + 2893, 3025, 3145, 3263, 3387, 3496, 3595, 3707, 3804, 3884, 3975, + 4046, 4105, 4167, 4204, 4220, 4237, 4243, 4247, 4260, 4255, 4251, + 4246, 4201, 4143, 4092, 3996, 3885, 3772, 3604, 3435, 3283, 3086, + 2923, 2742, 2535, 2341, 2130, 1887, 1649, 1411, 1137, 915, 659, + 398, 163, -81, -351, -580, -814, -1069, -1262, -1476, -1689, -1850, + -2043, -2237, -2395, -2591, -2763, -2918, -3095, -3224, -3319, -3435, -3508, + -3582, -3698, -3772, -3858, -3950, -4008, -4047, -4088, -4093, -4085, -4098, + -4064, -4052, -4057, -4033, -4028, -4018, -3991, -3971, -3933, -3865, -3802, + -3727, -3633, -3562, -3477, -3392, -3300, -3210, -3115, -3018, -2924, -2819, + -2721, -2606, -2490, -2381, -2246, -2111, -1963, -1810, -1638, -1460, -1293, + -1132, -980, -828, -666, -496, -322, -125, 72, 264, 470, 676, + 879, 1087, 1280, 1457, 1633, 1799, 1970, 2152, 2327, 2501, 2678, + 2840, 3007, 3165, 3301, 3434, 3558, 3667, 3791, 3912, 4023, 4140, + 4257, 4359, 4475, 4554, 4614, 4656, 4682, 4697, 4726, 4749, 4775, + 4810, 4812, 4812, 4810, 4768, 4697, 4620, 4502, 4368, 4210, 4031, + 3860, 3663, 3472, 3291, 3076, 2849, 2642, 2392, 2140, 1890, 1610, + 1325, 1064, 782, 494, 231, -50, -329, -593, -861, -1112, -1345, + -1588, -1812, -2022, -2257, -2467, -2682, -2924, -3126, -3317, -3495, -3630, + -3737, -3855, -3941, -4031, -4128, -4200, -4281, -4348, -4388, -4427, -4449, + -4444, -4450, -4458, -4452, -4464, -4460, -4451, -4444, -4425, -4384, -4344, + -4289, -4234, -4160, -4076, -4000, -3917, -3837, -3753, -3669, -3558, -3460, + -3354, -3230, -3111, -2966, -2824, -2665, -2495, -2333, -2151, -1951, -1752, + -1554, -1367, -1222, -1053, -882, -716, -520, -331, -141, 62, 270, + 476, 707, 923, 1133, 1349, 1534, 1735, 1943, 2124, 2317, 2511, + 2668, 2839, 3002, 3140, 3317, 3481, 3615, 3771, 3920, 4050, 4196, + 4319, 4430, 4556, 4657, 4765, 4868, 4945, 4999, 5057, 5075, 5100, + 5123, 5133, 5134, 5127, 5104, 5084, 5058, 4968, 4896, 4750, 4575, + 4381, 4179, 3971, 3776, 3590, 3394, 3209, 2991, 2800, 2535, 2269, + 1972, 1654, 1319, 998, 697, 384, 105, -187, -476, -759, -1047, + -1316, -1579, -1841, -2085, -2317, -2550, -2745, -2938, -3145, -3326, -3523, + -3706, -3859, -3998, -4124, -4218, -4288, -4346, -4386, -4437, -4495, -4550, + -4619, -4680, -4732, -4779, -4813, -4820, -4842, -4825, -4791, -4773, -4742, + -4715, -4709, -4683, -4652, -4605, -4527, -4428, -4315, -4194, -4086, -3978, + -3872, -3779, -3685, -3569, -3458, -3313, -3121, -2921, -2693, -2454, -2230, + -1998, -1783, -1588, -1414, -1240, -1069, -886, -690, -473, -256, -36, + 170, 384, 594, 797, 1015, 1235, 1449, 1664, 1882, 2098, 2311, + 2504, 2681, 2843, 3019, 3171, 3337, 3534, 3709, 3885, 4072, 4235, + 4380, 4524, 4641, 4746, 4864, 4979, 5087, 5213, 5308, 5393, 5450, + 5468, 5475, 5472, 5452, 5462, 5467, 5453, 5451, 5425, 5342, 5255, + 5113, 4914, 4725, 4512, 4273, 4053, 3866, 3632, 3436, 3205, 2955, + 2705, 2420, 2095, 1794, 1503, 1195, 941, 639, 342, 56, -269, + -601, -894, -1208, -1499, -1736, -1994, -2239, -2426, -2652, -2891, -3099, + -3361, -3588, -3793, -4013, -4183, -4302, -4439, -4523, -4613, -4734, -4809, + -4891, -4999, -5056, -5090, -5131, -5092, -5061, -5044, -4987, -4954, -4955, + -4924, -4911, -4873, -4809, -4755, -4673, -4555, -4440, -4316, -4187, -4088, + -3986, -3881, -3802, -3717, -3605, -3495, -3359, -3207, -3063, -2889, -2698, + -2504, -2306, -2088, -1861, -1627, -1415, -1201, -1000, -799, -593, -410, + -220, -7, 203, 412, 634, 865, 1126, 1367, 1602, 1838, 2052, + 2257, 2474, 2659, 2863, 3076, 3255, 3429, 3617, 3773, 3939, 4102, + 4222, 4358, 4501, 4611, 4733, 4846, 4939, 5056, 5147, 5217, 5301, + 5357, 5388, 5428, 5417, 5400, 5430, 5422, 5406, 5442, 5446, 5431, + 5437, 5381, 5304, 5212, 5057, 4874, 4683, 4465, 4249, 4026, 3767, + 3545, 3304, 3021, 2741, 2450, 2113, 1807, 1490, 1151, 841, 544, + 212, -102, -439, -788, -1091, -1413, -1730, -2033, -2336, -2627, -2854, + -3118, -3350, -3560, -3781, -4008, -4194, -4376, -4524, -4640, -4757, -4865, + -4945, -5016, -5083, -5131, -5170, -5184, -5198, -5208, -5211, -5210, -5209, + -5192, -5174, -5154, -5108, -5052, -5002, -4932, -4854, -4780, -4704, -4604, + -4514, -4421, -4309, -4208, -4111, -4004, -3880, -3751, -3622, -3496, -3367, + -3210, -3047, -2867, -2654, -2430, -2177, -1897, -1651, -1417, -1182, -983, + -793, -593, -406, -211, 17, 232, 461, 716, 958, 1197, 1441, + 1674, 1899, 2130, 2355, 2573, 2788, 3004, 3220, 3419, 3612, 3809, + 3973, 4120, 4277, 4433, 4573, 4742, 4902, 5037, 5165, 5282, 5377, + 5460, 5539, 5596, 5654, 5716, 5741, 5759, 5770, 5776, 5762, 5751, + 5737, 5706, 5675, 5644, 5550, 5446, 5324, 5169, 4974, 4767, 4530, + 4289, 4067, 3823, 3621, 3391, 3145, 2878, 2575, 2228, 1890, 1525, + 1149, 807, 473, 145, -152, -454, -769, -1057, -1374, -1703, -2033, + -2372, -2701, -2977, -3258, -3495, -3694, -3897, -4089, -4270, -4483, -4668, + -4840, -5015, -5140, -5225, -5304, -5334, -5350, -5390, -5398, -5403, -5428, + -5438, -5449, -5472, -5463, -5441, -5401, -5333, -5252, -5151, -5051, -4974, + -4880, -4805, -4729, -4626, -4526, -4403, -4248, -4088, -3939, -3778, -3617, + -3464, -3308, -3173, -3027, -2852, -2669, -2461, -2233, -1979, -1713, -1455, + -1216, -996, -796, -610, -397, -198, 21, 272, 517, 775, 1037, + 1295, 1544, 1790, 2007, 2211, 2423, 2634, 2848, 3081, 3319, 3551, + 3792, 4000, 4171, 4303, 4418, 4518, 4596, 4679, 4807, 4913, 5044, + 5172, 5288, 5405, 5518, 5609, 5664, 5713, 5735, 5735, 5737, 5701, + 5691, 5656, 5633, 5611, 5552, 5475, 5394, 5293, 5177, 5064, 4924, + 4737, 4599, 4420, 4237, 4048, 3828, 3623, 3413, 3183, 2915, 2622, + 2308, 1980, 1657, 1261, 901, 549, 205, -85, -383, -688, -969, + -1246, -1530, -1850, -2206, -2561, -2915, -3224, -3482, -3713, -3921, -4107, + -4287, -4470, -4660, -4850, -5057, -5239, -5395, -5540, -5619, -5697, -5724, + -5697, -5675, -5633, -5590, -5579, -5530, -5486, -5442, -5426, -5391, -5348, + -5276, -5197, -5124, -5039, -4925, -4808, -4677, -4581, -4479, -4343, -4218, + -4087, -3970, -3858, -3729, -3570, -3384, -3206, -3020, -2839, -2636, -2453, + -2287, -2185, -2154, -1926, -1562, -1223, -758, -473, -64, 395, 599, + 880, 814, 938, 1172, 1498, 1928, 2127, 2422, 2608, 2841, 2937, + 2886, 2815, 2985, 3324, 3757, 4152, 4481, 4652, 4917, 4965, 4766, + 4583, 4328, 4503, 4815, 5118, 5408, 5682, 5956, 6082, 6055, 5744, + 5426, 5341, 5427, 5606, 5882, 6065, 6226, 6428, 6477, 6385, 6009, + 5728, 5552, 5439, 5339, 5200, 5008, 4947, 4835, 4614, 4330, 3887, + 3521, 3111, 2460, 1983, 1297, 650, 279, -353, -720, -1044, -1518, + -1668, -2117, -2496, -2743, -3266, -3607, -3790, -4149, -4075, -4042, -4096, + -3981, -4138, -4226, -4214, -4503, -4455, -4577, -4642, -4346, -4351, -4270, + -4263, -4522, -4521, -4673, -4814, -4731, -4950, -5011, -5004, -5288, -5341, + -5566, -5833, -5783, -5929, -5847, -5765, -5828, -5644, -5613, -5615, -5428, + -5291, -5014, -4554, -4277, -3964, -3854, -3829, -3612, -3603, -3438, -3137, + -2831, -2164, -1438, -939, -330, -156, 46, 242, 73, 242, 220, + 239, 542, 565, 739, 872, 801, 857, 676, 543, 586, 567, + 828, 1142, 1490, 1985, 2508, 2982, 3438, 3699, 3939, 4069, 4178, + 4420, 4622, 4917, 5338, 5801, 6285, 6658, 6963, 7213, 7233, 7328, + 7176, 7038, 7031, 6860, 6957, 6767, 6599, 6523, 6212, 6147, 6063, + 5860, 6020, 6015, 6033, 6184, 5722, 5607, 5016, 4337, 4063, 3229, + 3080, 3006, 2804, 3035, 2541, 2136, 1879, 1012, 401, -575, -1584, + -1930, -2278, -2485, -2477, -2712, -2747, -2766, -3320, -3592, -4188, -4669, + -4672, -4939, -4789, -4426, -4203, -3674, -3563, -3656, -3759, -4067, -4257, + -4522, -4970, -5204, -5237, -5139, -4907, -4911, -4917, -4921, -5007, -5230, + -5654, -6122, -6464, -6733, -6948, -7067, -6972, -6800, -6520, -6132, -5830, + -5382, -5091, -4797, -4546, -4472, -4362, -4350, -4235, -3851, -3454, -3144, + -2735, -2341, -1845, -1262, -958, -549, -166, 66, 382, 366, 352, + 341, 85, -13, -176, -303, -235, -341, -309, -227, -249, -50, + 143, 384, 874, 1149, 1552, 2155, 2767, 3499, 3994, 4460, 4920, + 5288, 5569, 5704, 5881, 6094, 6461, 6653, 6803, 7115, 7311, 7521, + 7612, 7443, 7380, 7124, 6742, 6495, 5964, 5656, 5415, 5167, 5656, + 5813, 6027, 6401, 6351, 6787, 7019, 6581, 6512, 5965, 5308, 5140, + 4336, 4147, 3899, 3398, 3360, 2830, 2624, 1968, 1026, 395, -699, + -1424, -2327, -3006, -3192, -3435, -3337, -3686, -3513, -3350, -3502, -3261, + -3878, -4005, -4063, -4187, -3767, -3598, -3384, -3300, -3094, -2857, -3023, + -3274, -3851, -4352, -4523, -4943, -5477, -5612, -5682, -5733, -5714, -5965, + -6110, -5950, -6158, -6548, -6897, -7165, -7281, -7352, -7258, -7185, -6659, + -5946, -5470, -4738, -4046, -3707, -3210, -3108, -3270, -3227, -3222, -3218, + -3017, -2943, -2668, -2296, -1593, -1061, -811, -403, -513, -361, -128, + -595, -633, -991, -1205, -1159, -1284, -1330, -1164, -999, -729, -538, + -336, 27, 350, 794, 1245, 1646, 2446, 3210, 4017, 4835, 5271, + 5739, 6028, 6140, 6212, 6161, 6066, 5984, 6081, 5995, 6152, 6301, + 6278, 6424, 6377, 6396, 6362, 6152, 5788, 5309, 5071, 4860, 4704, + 4804, 4919, 5258, 5869, 6121, 6365, 6694, 6692, 6694, 6532, 6187, + 5808, 5704, 5302, 4816, 4611, 4043, 3775, 3249, 2600, 1933, 982, + 336, -848, -1538, -2242, -3103, -3374, -3756, -3975, -4017, -4061, -3972, + -3749, -3609, -3853, -3850, -3714, -3760, -3736, -3914, -3923, -3830, -3541, + -3649, -3757, -3661, -3913, -4038, -4231, -4594, -4769, -5009, -5273, -5588, + -5676, -5937, -5997, -6060, -6164, -6414, -6623, -6765, -6857, -6771, -6921, + -6914, -6535, -6187, -5626, -5206, -4742, -4189, -3618, -3120, -2823, -2606, + -2550, -2703, -2736, -2626, -2498, -2406, -2133, -1852, -1348, -753, -318, + 162, 330, 524, 375, 9, -204, -866, -1249, -1532, -1669, -1455, + -1235, -723, -283, 262, 535, 862, 1340, 1712, 2316, 2625, 3171, + 4015, 4698, 5516, 6006, 6452, 6838, 6921, 7003, 6735, 6339, 6138, + 5768, 5575, 5593, 5568, 5728, 6041, 6233, 6260, 6175, 6048, 5728, + 5366, 4931, 4340, 4194, 4174, 4330, 4743, 5028, 5754, 6250, 6598, + 7120, 7114, 6962, 6675, 6157, 5373, 4797, 4081, 3237, 3153, 2588, + 2143, 1639, 1021, 681, -149, -816, -1987, -3003, -3493, -4138, -4420, + -4607, -4841, -4725, -4254, -4033, -3845, -3842, -4063, -4035, -4099, -4582, + -4718, -4779, -4689, -4437, -4327, -4352, -4119, -3881, -4061, -4345, -4768, + -5248, -5610, -5920, -6383, -6779, -6731, -6673, -6677, -6597, -6659, -6619, + -6417, -6516, -6862, -7017, -7069, -6944, -6715, -6376, -6000, -5162, -4333, + -3577, -2884, -2355, -1807, -1366, -1380, -1590, -1869, -1962, -1945, -2006, + -2141, -1960, -1516, -1025, -471, -135, 85, 348, 239, -8, -475, + -951, -1245, -1520, -1569, -1448, -1188, -517, 134, 827, 1585, 2114, + 2792, 3214, 3651, 4230, 4546, 4894, 5321, 5588, 6105, 6583, 6877, + 7014, 7087, 7068, 6876, 6695, 6280, 5684, 5385, 5205, 5064, 5033, + 5028, 5080, 5322, 5510, 5461, 5390, 5541, 5494, 5443, 5306, 5065, + 5193, 5338, 5513, 5818, 5911, 6345, 6506, 6514, 6543, 5981, 5703, + 5082, 4228, 3517, 2424, 1880, 1245, 562, -130, -864, -1156, -1561, + -1970, -2597, -3357, -3707, -4189, -4521, -4975, -5477, -5478, -5585, -5445, + -5353, -5327, -4971, -4580, -4431, -4469, -4432, -4422, -4275, -4227, -4507, + -4745, -4758, -4752, -4845, -4933, -5118, -5117, -5124, -5324, -5673, -5971, + -6152, -6366, -6702, -6970, -7159, -7136, -6929, -6917, -6703, -6520, -6302, + -5794, -5484, -5123, -4694, -4254, -3722, -3334, -2917, -2410, -1721, -1010, + -584, -312, 27, 321, 327, 214, -17, -363, -402, -550, -638, + -469, -315, -86, 142, 242, 387, 448, 458, 423, 321, 194, + 285, 417, 717, 1176, 1673, 2402, 3144, 3985, 4764, 5406, 6056, + 6507, 6783, 6891, 6868, 6850, 6717, 6532, 6359, 6248, 6303, 6279, + 6140, 6071, 5927, 5687, 5480, 5146, 4835, 4572, 4447, 4481, 4578, + 4840, 4936, 5246, 5659, 5732, 5856, 5658, 5403, 5282, 5004, 4949, + 4843, 4681, 4884, 4886, 4967, 5108, 4781, 4647, 4240, 3443, 2768, + 1830, 983, 309, -769, -1382, -1987, -2553, -2750, -3346, -3555, -4052, + -4400, -4599, -5196, -5437, -5945, -6340, -6343, -6554, -6611, -6381, -6184, + -5681, -5398, -5098, -4751, -4529, -4138, -4100, -4088, -4044, -4186, -4189, + -4263, -4453, -4465, -4598, -4651, -4726, -4919, -4926, -5142, -5286, -5490, + -5831, -6002, -6341, -6492, -6562, -6710, -6553, -6506, -6219, -5766, -5521, + -5008, -4556, -4002, -3293, -2769, -2069, -1467, -824, -34, 509, 1034, + 1385, 1560, 1650, 1664, 1419, 1016, 834, 511, 353, 381, 299, + 523, 833, 956, 1280, 1492, 1425, 1547, 1350, 1143, 1114, 931, + 1054, 1217, 1583, 2217, 2917, 4017, 4965, 5827, 6816, 7393, 7875, + 8197, 8175, 7924, 7578, 7040, 6566, 6242, 5746, 5530, 5334, 5222, + 5237, 5074, 5146, 5011, 4902, 4753, 4442, 4482, 4254, 4247, 4319, + 4187, 4516, 4690, 4935, 5193, 5229, 5350, 5332, 5486, 5386, 5143, + 4999, 4494, 4304, 3961, 3421, 2781, 2032, 1404, 614, -88, -956, + -1714, -2155, -2684, -3038, -3237, -3368, -3423, -3569, -3809, -4213, -4533, + -4973, -5514, -6011, -6663, -7084, -7258, -7158, -6947, -6639, -6111, -5548, + -4887, -4362, -4043, -3895, -3940, -4107, -4452, -4836, -5143, -5500, -5532, + -5510, -5485, -5096, -4739, -4375, -4065, -4063, -4094, -4252, -4576, -4904, + -5431, -5837, -6190, -6402, -6310, -6292, -5992, -5516, -5025, -4342, -3899, + -3386, -2697, -2077, -1493, -994, -392, 232, 931, 1608, 1988, 2360, + 2589, 2639, 2623, 2471, 2121, 1708, 1478, 1181, 1167, 1296, 1279, + 1648, 1859, 2107, 2368, 2359, 2390, 2122, 1904, 1629, 1418, 1502, + 1524, 1859, 2357, 3041, 3909, 4810, 5751, 6449, 7128, 7534, 7767, + 7908, 7699, 7460, 7032, 6647, 6301, 5876, 5556, 5190, 4948, 4762, + 4576, 4464, 4370, 4338, 4275, 4287, 4265, 4320, 4221, 4066, 3947, + 3514, 3379, 3003, 2635, 2534, 2078, 2040, 1950, 1958, 2152, 2085, + 2390, 2321, 2319, 2359, 1851, 1643, 877, 168, -527, -1245, -1704, + -2519, -2739, -3251, -3382, -3236, -3527, -3294, -3523, -3732, -3916, -4434, + -4888, -5615, -6161, -6729, -7283, -7543, -7920, -7865, -7660, -7430, -7034, + -6758, -6224, -5866, -5441, -5076, -4998, -4760, -4673, -4539, -4410, -4308, + -4131, -3992, -3791, -3611, -3448, -3213, -3070, -3046, -3048, -3168, -3244, + -3354, -3607, -3834, -4170, -4439, -4648, -4864, -4892, -4928, -4821, -4524, + -4211, -3576, -2819, -1968, -929, -19, 1029, 2064, 2949, 3716, 4159, + 4450, 4536, 4503, 4301, 3968, 3655, 3242, 2979, 2856, 2744, 2750, + 2771, 2749, 2859, 2850, 2793, 2702, 2402, 2179, 1877, 1672, 1581, + 1543, 1769, 1967, 2485, 3089, 3783, 4662, 5406, 6246, 6950, 7542, + 8016, 8200, 8245, 8027, 7584, 6958, 6241, 5494, 4710, 3974, 3255, + 2653, 2274, 2038, 1986, 1964, 2141, 2321, 2513, 2772, 2756, 2743, + 2636, 2406, 2125, 1836, 1456, 1247, 1145, 995, 1077, 1140, 1290, + 1561, 1685, 1762, 1609, 1391, 1147, 544, 84, -754, -1546, -2107, + -2806, -3137, -3522, -3732, -3826, -3834, -3609, -3493, -3340, -3254, -3499, + -3621, -3981, -4455, -4859, -5513, -6080, -6626, -7061, -7372, -7556, -7573, + -7515, -7366, -7091, -6799, -6366, -5887, -5484, -5098, -4746, -4334, -3941, + -3558, -3269, -3053, -2844, -2663, -2497, -2314, -2227, -2185, -2141, -2139, + -2070, -2037, -2031, -2062, -2205, -2348, -2544, -2774, -2979, -3298, -3520, + -3647, -3622, -3395, -3054, -2513, -1829, -948, 64, 1090, 2169, 3127, + 3987, 4712, 5229, 5560, 5754, 5741, 5619, 5401, 5005, 4666, 4287, + 3967, 3734, 3476, 3322, 3203, 3147, 3144, 3116, 3080, 3011, 2871, + 2735, 2544, 2363, 2245, 2075, 2032, 2118, 2263, 2688, 3066, 3605, + 4244, 4746, 5384, 5819, 6151, 6319, 6194, 5938, 5495, 4929, 4305, + 3581, 2924, 2279, 1713, 1372, 1086, 1006, 983, 1006, 1146, 1249, + 1349, 1360, 1231, 1084, 794, 502, 264, -85, -238, -411, -504, + -394, -322, -51, 188, 420, 589, 624, 666, 573, 338, -86, + -564, -1056, -1560, -1925, -2434, -2806, -3017, -3341, -3320, -3375, -3480, + -3410, -3567, -3553, -3595, -3805, -3919, -4284, -4482, -4754, -5190, -5354, + -5806, -6050, -6136, -6387, -6343, -6330, -6206, -5851, -5468, -4960, -4549, + -4080, -3542, -3150, -2698, -2440, -2318, -2132, -2067, -2081, -2017, -2099, + -2151, -2060, -2067, -1916, -1823, -1718, -1523, -1386, -1221, -1189, -1141, + -1014, -1008, -966, -996, -1015, -916, -809, -648, -467, -128, 237, + 735, 1358, 1969, 2697, 3399, 4060, 4732, 5295, 5720, 6077, 6169, + 6139, 5928, 5614, 5292, 4766, 4247, 3705, 3262, 3030, 2827, 2702, + 2684, 2728, 2887, 3092, 3216, 3310, 3313, 3214, 3098, 2873, 2620, + 2343, 2031, 1799, 1589, 1491, 1537, 1645, 1913, 2210, 2548, 2922, + 3295, 3650, 3951, 4100, 4099, 3972, 3740, 3421, 2948, 2427, 1762, + 1136, 574, 44, -330, -642, -846, -852, -751, -520, -229, 44, + 272, 446, 502, 443, 329, 66, -191, -492, -841, -1002, -1240, + -1237, -1199, -1177, -936, -867, -660, -456, -508, -464, -706, -997, + -1265, -1780, -2178, -2724, -3270, -3735, -4142, -4378, -4609, -4666, -4749, + -4575, -4355, -4137, -3767, -3563, -3218, -2970, -2834, -2630, -2716, -2776, + -2920, -3210, -3363, -3764, -4023, -4125, -4268, -4194, -4223, -4005, -3639, + -3258, -2891, -2644, -2297, -1987, -1751, -1587, -1570, -1485, -1415, -1342, + -1194, -1100, -889, -613, -267, 161, 482, 865, 1269, 1639, 2005, + 2202, 2381, 2549, 2628, 2700, 2625, 2559, 2481, 2357, 2319, 2192, + 2142, 2199, 2283, 2514, 2670, 2919, 3214, 3510, 3830, 3971, 4080, + 4073, 3911, 3700, 3359, 2954, 2549, 2094, 1766, 1556, 1442, 1462, + 1560, 1808, 2070, 2357, 2606, 2730, 2831, 2737, 2582, 2309, 1931, + 1585, 1178, 834, 529, 288, 214, 218, 302, 470, 679, 944, + 1211, 1420, 1562, 1674, 1631, 1548, 1355, 1072, 776, 375, 25, + -320, -614, -818, -992, -991, -906, -755, -525, -291, -17, 225, + 447, 528, 546, 466, 270, 96, -205, -536, -861, -1148, -1383, + -1586, -1688, -1814, -1783, -1772, -1745, -1630, -1611, -1505, -1488, -1462, + -1409, -1519, -1489, -1609, -1723, -1755, -1977, -2042, -2132, -2215, -2184, + -2268, -2205, -2170, -2107, -1978, -1990, -1909, -1886, -1943, -1997, -2152, + -2326, -2500, -2762, -2987, -3227, -3392, -3522, -3630, -3579, -3469, -3262, + -2916, -2555, -2103, -1581, -1090, -531, -20, 457, 873, 1228, 1561, + 1809, 1999, 2105, 2139, 2196, 2201, 2149, 2113, 2038, 1990, 1913, + 1787, 1705, 1595, 1490, 1372, 1201, 1113, 998, 917, 917, 894, + 961, 1007, 1098, 1321, 1470, 1681, 1882, 2067, 2317, 2465, 2626, + 2750, 2777, 2783, 2694, 2569, 2431, 2142, 1843, 1597, 1306, 1069, + 824, 622, 532, 430, 388, 357, 377, 438, 414, 481, 468, + 431, 454, 383, 374, 305, 207, 187, 133, 157, 115, 113, + 206, 244, 382, 475, 591, 753, 821, 916, 908, 855, 754, + 577, 399, 123, -159, -399, -647, -784, -923, -1010, -965, -918, + -806, -647, -504, -355, -253, -179, -130, -138, -156, -262, -339, + -401, -552, -600, -671, -697, -662, -673, -616, -597, -522, -495, + -513, -490, -624, -701, -804, -961, -1073, -1328, -1503, -1656, -1798, + -1801, -1913, -1863, -1785, -1720, -1453, -1309, -1051, -846, -715, -487, + -457, -357, -331, -400, -427, -627, -765, -873, -1021, -1105, -1255, + -1312, -1357, -1370, -1288, -1261, -1165, -1139, -1062, -917, -808, -680, + -597, -452, -277, -104, 122, 312, 558, 771, 919, 1110, 1205, + 1312, 1355, 1302, 1280, 1151, 1049, 946, 818, 733, 569, 451, + 429, 388, 408, 387, 376, 426, 463, 542, 576, 632, 666, + 673, 740, 766, 791, 845, 829, 857, 841, 822, 835, 796, + 773, 671, 600, 560, 484, 460, 371, 311, 284, 242, 277, + 261, 261, 277, 273, 358, 380, 410, 433, 435, 471, 432, + 414, 386, 330, 294, 194, 149, 108, 69, 84, 69, 92, + 83, 75, 88, 53, 12, -96, -194, -269, -369, -438, -523, + -553, -528, -500, -392, -277, -136, 53, 240, 466, 678, 870, + 1050, 1178, 1294, 1336, 1310, 1247, 1080, 916, 677, 387, 120, + -182, -471, -740, -972, -1148, -1273, -1343, -1402, -1363, -1263, -1129, + -922, -724, -518, -288, -79, 111, 250, 364, 405, 405, 395, + 284, 199, 83, -43, -126, -244, -313, -400, -451, -497, -610, + -672, -807, -951, -1087, -1325, -1517, -1736, -1929, -2086, -2260, -2318, + -2356, -2271, -2125, -1967, -1685, -1379, -1000, -598, -238, 149, 481, + 790, 1042, 1185, 1287, 1274, 1195, 1068, 868, 654, 386, 138, + -65, -273, -450, -598, -665, -670, -669, -620, -553, -425, -288, + -179, -72, 15, 122, 205, 263, 324, 357, 435, 518, 603, + 709, 779, 892, 1006, 1107, 1170, 1183, 1190, 1173, 1116, 1016, + 890, 750, 628, 488, 331, 197, 95, 43, 25, 1, 22, + 97, 209, 363, 495, 615, 724, 833, 937, 984, 990, 933, + 884, 851, 747, 678, 573, 497, 469, 401, 391, 352, 339, + 352, 337, 354, 361, 370, 402, 411, 418, 440, 468, 526, + 576, 619, 683, 766, 857, 965, 1038, 1114, 1159, 1172, 1167, + 1106, 1006, 840, 644, 426, 177, -110, -390, -665, -929, -1160, + -1375, -1497, -1550, -1592, -1553, -1507, -1394, -1201, -1084, -863, -685, + -540, -322, -234, -68, 29, 59, 160, 141, 170, 140, 79, + 77, -11, -53, -179, -274, -327, -480, -564, -736, -884, -995, + -1185, -1300, -1461, -1617, -1711, -1832, -1831, -1863, -1865, -1776, -1691, + -1516, -1353, -1168, -954, -729, -490, -305, -93, 81, 211, 322, + 364, 392, 384, 332, 264, 146, 29, -101, -230, -357, -486, + -616, -705, -752, -801, -809, -788, -750, -654, -546, -456, -328, + -200, -78, 45, 137, 232, 316, 388, 447, 485, 528, 578, + 630, 697, 760, 835, 910, 988, 1068, 1124, 1154, 1157, 1166, + 1163, 1116, 1070, 1024, 994, 986, 988, 1030, 1110, 1212, 1303, + 1411, 1498, 1551, 1599, 1587, 1565, 1481, 1336, 1212, 1028, 847, + 669, 466, 330, 187, 61, -9, -54, -55, -20, 11, 69, + 133, 195, 244, 253, 225, 182, 133, 62, -11, -96, -168, + -199, -214, -213, -197, -167, -127, -105, -86, -83, -109, -140, + -217, -323, -448, -588, -717, -854, -971, -1086, -1185, -1211, -1227, + -1180, -1135, -1099, -992, -918, -788, -704, -651, -562, -542, -470, + -421, -431, -391, -429, -386, -344, -336, -260, -257, -162, -61, + -6, 100, 120, 178, 215, 179, 132, 15, -106, -238, -416, + -595, -765, -929, -1066, -1170, -1252, -1278, -1290, -1258, -1173, -1114, + -1012, -945, -868, -741, -695, -612, -547, -494, -388, -332, -225, + -110, 22, 182, 318, 496, 677, 835, 992, 1104, 1162, 1166, + 1133, 1054, 916, 709, 430, 164, -90, -340, -600, -853, -1033, + -1135, -1177, -1146, -1079, -946, -746, -500, -208, 83, 377, 673, + 950, 1183, 1356, 1503, 1627, 1707, 1735, 1708, 1678, 1668, 1645, + 1588, 1494, 1419, 1354, 1291, 1194, 1052, 900, 718, 524, 325, + 110, -114, -330, -500, -630, -729, -803, -834, -795, -727, -627, + -492, -325, -125, 54, 238, 393, 528, 642, 691, 706, 661, + 585, 504, 380, 245, 87, -61, -195, -320, -435, -556, -663, + -742, -814, -883, -952, -1009, -1038, -1047, -1067, -1063, -1050, -1020, + -949, -888, -795, -698, -574, -405, -257, -70, 68, 203, 381, + 479, 580, 619, 623, 645, 565, 492, 364, 206, 106, -71, + -191, -331, -460, -469, -527, -471, -441, -386, -222, -123, 60, + 168, 245, 404, 470, 596, 605, 581, 633, 548, 562, 468, + 355, 334, 192, 161, 62, -36, -39, -146, -121, -167, -243, + -229, -302, -276, -327, -415, -419, -444, -396, -433, -455, -407, + -357, -244, -221, -158, -63, 36, 172, 210, 296, 326, 351, + 424, 367, 369, 300, 224, 235, 124, 54, -39, -122, -118, + -239, -304, -360, -403, -361, -418, -427, -394, -342, -259, -232, + -176, -110, -48, 27, 48, 78, 90, 86, 91, 76, 57, + -1, -34, -53, -103, -151, -209, -239, -261, -319, -354, -372, + -382, -385, -411, -432, -428, -431, -446, -471, -496, -512, -532, + -562, -570, -567, -543, -499, -457, -379, -290, -204, -94, -11, + 78, 155, 196, 234, 222, 198, 160, 113, 64, 5, -57, + -108, -136, -175, -186, -196, -184, -125, -90, -25, 58, 146, + 271, 372, 472, 562, 636, 709, 741, 760, 752, 730, 710, + 688, 655, 608, 595, 570, 556, 540, 517, 513, 511, 497, + 481, 449, 417, 401, 347, 325, 295, 248, 261, 238, 250, + 294, 295, 367, 380, 416, 454, 430, 479, 443, 431, 430, + 386, 397, 333, 292, 238, 176, 153, 54, 24, -37, -84, + -109, -172, -155, -199, -220, -219, -261, -227, -255, -280, -266, + -293, -277, -273, -243, -214, -221, -179, -153, -130, -109, -154, + -149, -151, -155, -186, -243, -253, -311, -326, -358, -434, -427, + -491, -533, -554, -598, -596, -655, -668, -679, -714, -671, -694, + -643, -607, -602, -532, -496, -409, -408, -377, -309, -289, -211, + -223, -196, -145, -147, -104, -157, -123, -125, -177, -152, -229, + -192, -204, -243, -213, -259, -194, -190, -172, -98, -123, -43, + -12, 41, 103, 87, 148, 150, 166, 154, 113, 118, 80, + 54, 8, 4, 25, 12, 59, 70, 162, 260, 305, 387, + 427, 501, 549, 564, 571, 517, 488, 423, 355, 294, 206, + 165, 113, 92, 77, 62, 115, 116, 154, 162, 171, 218, + 210, 221, 208, 192, 215, 176, 169, 114, 89, 89, 52, + 62, 29, 35, 73, 98, 167, 195, 261, 325, 349, 401, + 382, 393, 368, 302, 254, 174, 104, 6, -78, -136, -203, + -229, -291, -303, -284, -294, -241, -235, -222, -186, -187, -156, + -160, -149, -122, -114, -71, -44, -28, 6, 20, 47, 57, + 54, 52, 55, 53, 23, 9, -16, -59, -86, -158, -223, + -292, -372, -421, -498, -532, -561, -570, -531, -512, -456, -367, + -297, -206, -125, -37, 26, 88, 147, 157, 188, 169, 152, + 152, 131, 99, 62, 44, 46, 53, 61, 61, 79, 110, + 159, 175, 185, 237, 220, 278, 276, 239, 264, 203, 190, + 138, 70, 34, -9, 18, 1, 10, 71, 115, 191, 220, + 255, 265, 296, 319, 270, 266, 214, 189, 187, 155, 145, + 123, 149, 166, 172, 186, 179, 195, 213, 201, 182, 161, + 150, 116, 76, 41, -29, -58, -101, -183, -209, -269, -314, + -342, -385, -379, -380, -348, -304, -273, -197, -144, -88, -28, + -5, 11, 20, 27, -5, -24, -22, -61, -73, -87, -124, + -118, -133, -150, -160, -198, -196, -219, -228, -239, -281, -276, + -275, -288, -277, -305, -324, -302, -294, -292, -266, -261, -224, + -203, -210, -190, -198, -176, -180, -201, -196, -198, -175, -166, + -151, -127, -114, -59, -48, -8, 39, 75, 126, 131, 168, + 160, 152, 142, 82, 36, -13, -49, -81, -105, -105, -103, + -65, -38, -16, 19, 33, 67, 82, 95, 110, 98, 111, + 98, 87, 67, 54, 66, 52, 49, 53, 71, 106, 139, + 186, 224, 270, 320, 361, 413, 433, 462, 473, 478, 480, + 459, 441, 391, 339, 298, 239, 206, 159, 149, 120, 114, + 117, 95, 106, 81, 67, 61, 30, 11, -29, -42, -76, + -97, -98, -124, -107, -107, -103, -69, -71, -36, -12, 23, + 69, 86, 129, 152, 158, 162, 152, 127, 81, 48, -9, + -80, -120, -172, -201, -225, -276, -297, -311, -330, -339, -361, + -375, -389, -376, -365, -374, -378, -375, -370, -358, -347, -355, + -338, -314, -289, -244, -212, -168, -129, -80, -26, -12, 47, + 79, 92, 105, 105, 113, 99, 85, 29, -18, -53, -110, + -133, -167, -186, -196, -199, -176, -177, -150, -122, -106, -73, + -61, -30, -34, -29, -40, -68, -63, -85, -84, -71, -65, + -40, -16, 23, 56, 87, 144, 167, 196, 206, 221, 243, + 226, 233, 210, 192, 190, 150, 140, 110, 91, 77, 43, + 27, -10, -5, -5, -22, -9, -7, 27, 48, 59, 64, + 70, 87, 104, 139, 151, 188, 239, 270, 317, 311, 336, + 349, 341, 330, 274, 254, 223, 195, 163, 102, 81, 43, + 20, 8, -37, -28, -31, -29, -21, -39, -16, -22, -11, + -21, -41, -32, -47, -39, -60, -75, -71, -94, -98, -131, + -147, -139, -145, -146, -165, -150, -136, -112, -90, -106, -86, + -91, -87, -98, -136, -121, -135, -124, -132, -144, -114, -108, + -87, -74, -75, -50, -30, -5, -18, -24, -3, -3, -6, + -41, -76, -98, -127, -159, -215, -257, -263, -268, -266, -262, + -237, -194, -144, -113, -99, -61, -28, 12, 21, 46, 76, + 92, 130, 115, 123, 132, 135, 149, 134, 133, 132, 135, + 138, 94, 76, 51, 19, -15, -72, -98, -125, -135, -154, + -174, -171, -164, -139, -130, -99, -74, -40, 9, 34, 86, + 129, 176, 214, 226, 245, 250, 280, 271, 256, 250, 226, + 234, 212, 187, 178, 148, 144, 104, 79, 64, 37, 36, + 9, -10, -23, -38, -35, -62, -67, -67, -82, -70, -80, + -75, -59, -34, -3, 9, 48, 76, 101, 120, 120, 123, + 126, 131, 112, 92, 77, 61, 54, 32, 3, -18, -28, + -39, -56, -71, -91, -92, -100, -124, -134, -142, -144, -155, + -177, -178, -175, -171, -168, -160, -141, -123, -89, -73, -64, + -46, -39, -18, -19, -34, -32, -46, -51, -63, -74, -73, + -81, -70, -83, -71, -49, -39, -12, -1, 30, 48, 65, + 94, 100, 125, 136, 148, 156, 138, 140, 124, 115, 86, + 58, 57, 32, 43, 40, 44, 63, 60, 83, 90, 99, + 115, 113, 135, 140, 148, 164, 172, 187, 182, 190, 183, + 171, 171, 146, 139, 121, 105, 94, 61, 46, 17, -6, + -34, -70, -89, -121, -138, -158, -178, -190, -206, -206, -210, + -214, -204, -196, -173, -154, -128, -97, -81, -58, -51, -46, + -38, -47, -49, -57, -58, -57, -59, -49, -58, -58, -54, + -60, -48, -65, -72, -72, -78, -70, -77, -73, -76, -79, + -76, -90, -90, -91, -88, -76, -67, -43, -16, 6, 27, + 39, 55, 69, 71, 74, 65, 56, 60, 47, 37, 27, + 8, -5, -29, -50, -71, -89, -96, -114, -111, -113, -115, + -105, -112, -90, -78, -68, -49, -46, -26, -14, 5, 18, + 10, 14, 3, 5, -9, -20, -15, -30, -26, -33, -31, + -23, -23, -12, -21, -20, -16, -23, -20, -13, -7, 6, + 28, 47, 69, 96, 115, 134, 147, 154, 166, 174, 186, + 196, 202, 204, 198, 193, 181, 164, 144, 125, 113, 102, + 96, 90, 92, 91, 96, 99, 99, 100, 99, 99, 93, + 94, 86, 68, 55, 44, 36, 22, 13, 15, 13, 15, + 21, 16, 11, 3, -15, -31, -50, -75, -105, -125, -145, + -154, -155, -164, -178, -189, -186, -177, -174, -169, -152, -134, + -114, -93, -65, -42, -23, -4, -1, 6, 6, 2, -4, + -18, -26, -25, -25, -23, -32, -31, -33, -39, -50, -68, + -69, -74, -79, -78, -83, -85, -85, -77, -71, -61, -42, + -27, -3, 28, 59, 95, 123, 146, 155, 160, 162, 144, + 130, 112, 94, 82, 67, 60, 46, 35, 35, 22, 4, + -14, -27, -35, -45, -52, -61, -62, -65, -68, -55, -52, + -43, -38, -34, -20, -8, 8, 18, 24, 34, 36, 37, + 42, 46, 51, 50, 58, 76, 75, 70, 67, 58, 53, + 48, 36, 23, 18, 10, 3, 9, 14, 24, 39, 43, + 53, 62, 63, 66, 62, 66, 64, 59, 51, 25, 19, + 6, -10, -19, -26, -35, -43, -44, -37, -47, -43, -50, + -54, -60, -69, -75, -84, -91, -93, -98, -96, -99, -91, + -87, -91, -88, -84, -80, -75, -61, -48, -44, -40, -37, + -34, -45, -52, -58, -72, -82, -84, -78, -68, -65, -63, + -51, -42, -27, -22, -13, -3, 8, 20, 26, 31, 31, + 37, 33, 29, 33, 31, 32, 31, 34, 44, 55, 68, + 74, 69, 75, 73, 72, 65, 63, 67, 70, 83, 81, + 81, 85, 84, 80, 75, 69, 53, 44, 36, 27, 20, + 11, 1, -4, -19, -26, -27, -25, -21, -14, -12, -12, + -14, -9, -21, -29, -40, -50, -50, -54, -46, -35, -17, + -4, -1, 7, 20, 28, 26, 22, 23, 21, 23, 18, + 13, 12, 7, 6, 3, 2, -1, -1, 4, 6, 17, + 29, 35, 34, 34, 32, 28, 33, 26, 22, 16, 16, + 22, 20, 13, -1, -1, -7, -15, -20, -30, -32, -38, + -39, -45, -45, -53, -63, -70, -83, -96, -107, -113, -122, + -122, -118, -114, -114, -113, -112, -111, -110, -107, -103, -102, + -94, -80, -71, -58, -52, -47, -40, -43, -47, -48, -50, + -39, -46, -44, -44, -44, -43, -45, -41, -40, -34, -32, + -23, -12, -6, -1, -1, 6, 12, 18, 20, 22, 32, + 48, 65, 80, 93, 109, 122, 128, 131, 135, 135, 129, + 126, 130, 127, 124, 125, 121, 122, 115, 118, 122, 128, + 137, 143, 143, 141, 142, 134, 131, 121, 109, 105, 97, + 93, 99, 96, 96, 94, 83, 84, 80, 77, 66, 59, + 46, 42, 44, 32, 28, 20, 12, 8, 4, 4, 5, + 3, -4, -7, -6, -14, -19, -24, -34, -40, -45, -52, + -61, -62, -60, -57, -57, -61, -63, -61, -65, -73, -81, + -89, -94, -93, -89, -87, -82, -82, -84, -81, -86, -82, + -84, -86, -90, -86, -83, -82, -81, -80, -80, -76, -75, + -76, -70, -69, -68, -61, -53, -50, -43, -38, -42, -43, + -41, -41, -39, -34, -27, -21, -16, -20, -22, -27, -36, + -39, -38, -40, -37, -35, -28, -14, -6, -3, -2, 2, + 4, 5, 15, 18, 25, 35, 36, 41, 45, 48, 52, + 54, 52, 50, 60, 67, 76, 85, 85, 90, 86, 83, + 84, 77, 77, 72, 77, 81, 89, 91, 93, 99, 101, + 102, 98, 94, 87, 77, 70, 69, 63, 62, 55, 59, + 58, 54, 51, 53, 57, 62, 65, 60, 54, 48, 45, + 40, 29, 17, 8, -3, -14, -17, -18, -20, -25, -34, + -40, -44, -53, -56, -63, -71, -71, -69, -66, -62, -66, + -67, -68, -71, -75, -79, -79, -73, -67, -60, -49, -46, + -45, -45, -46, -55, -64, -67, -72, -74, -70, -68, -67, + -69, -70, -64, -56, -55, -54, -51, -41, -30, -26, -28, + -29, -30, -28, -25, -27, -20, -12, -5, -2, 2, 3, + -3, 0, -7, -8, -14, -15, -9, -7, 4, 12, 24, + 36, 41, 52, 58, 59, 51, 45, 48, 44, 46, 43, + 40, 42, 47, 53, 52, 52, 63, 69, 74, 75, 80, + 78, 69, 68, 59, 60, 54, 54, 54, 58, 66, 71, + 78, 78, 75, 78, 72, 71, 61, 55, 53, 42, 36, + 31, 28, 29, 23, 19, 25, 27, 27, 23, 29, 29, + 20, 11, 5, -4, -10, -31, -38, -39, -36, -33, -27, + -17, -15, -14, -17, -13, -14, -25, -33, -44, -51, -61, + -63, -63, -65, -67, -66, -63, -59, -52, -48, -45, -44, + -50, -62, -74, -84, -89, -100, -101, -102, -96, -95, -85, + -76, -78, -72, -71, -66, -61, -63, -60, -62, -72, -69, + -69, -58, -56, -50, -37, -28, -17, -17, -16, -17, -18, + -18, -13, -7, -4, 6, 17, 23, 25, 28, 24, 21, + 17, 21, 27, 30, 33, 35, 46, 49, 48, 54, 56, + 57, 58, 60, 64, 62, 64, 66, 67, 64, 70, 77, + 83, 82, 84, 88, 89, 95, 86, 75, 64, 51, 36, + 29, 26, 21, 26, 31, 38, 40, 55, 63, 65, 65, + 64, 60, 54, 54, 49, 41, 34, 26, 21, 9, 6, + 6, 5, -1, 3, 5, 3, 2, -4, -13, -13, -24, + -32, -33, -36, -33, -24, -18, -15, -9, -5, -5, -14, + -17, -24, -34, -36, -42, -43, -36, -42, -43, -43, -38, + -36, -27, -20, -23, -21, -28, -25, -22, -24, -25, -23, + -22, -30, -31, -26, -25, -20, -15, -8, -10, -11, -13, + -18, -22, -30, -36, -35, -39, -35, -34, -27, -24, -19, + -15, -7, -6, -7, -2, 0, 7, 12, 14, 19, 20, + 26, 26, 24, 16, 10, 4, 1, 3, 2, 9, 11, + 17, 19, 27, 31, 31, 32, 30, 27, 25, 28, 27, + 25, 22, 23, 23, 20, 21, 25, 36, 38, 40, 43, + 40, 32, 27, 20, 9, 4, 1, 12, 27, 37, 49, + 63, 73, 72, 73, 70, 67, 53, 39, 33, 26, 23, + 13, 9, 6, 0, -2, -3, 0, -1, 0, -1, -4, + -9, -16, -22, -21, -24, -21, -19, -12, -3, 0, 12, + 14, 13, 3, -6, -13, -27, -34, -42, -41, -44, -42, + -43, -46, -42, -40, -39, -36, -31, -29, -30, -22, -19, + -21, -20, -17, -17, -22, -31, -41, -45, -54, -65, -64, + -68, -70, -74, -70, -64, -62, -61, -60, -58, -52, -46, + -43, -37, -35, -40, -41, -47, -52, -58, -62, -61, -53, + -54, -46, -41, -40, -34, -29, -20, -15, -8, 2, 12, + 28, 35, 41, 42, 42, 43, 41, 43, 39, 45, 44, + 46, 55, 54, 55, 55, 51, 48, 42, 43, 39, 40, + 46, 54, 65, 70, 76, 81, 86, 89, 79, 73, 70, + 62, 56, 52, 39, 32, 28, 17, 18, 19, 18, 15, + 19, 20, 15, 13, 13, 10, 6, 5, 12, 10, 15, + 20, 24, 30, 31, 28, 22, 17, 2, -15, -24, -39, + -52, -53, -55, -46, -40, -34, -26, -21, -22, -31, -32, + -38, -36, -35, -32, -33, -34, -30, -28, -27, -35, -40, + -42, -45, -44, -45, -44, -52, -54, -57, -57, -53, -60, + -63, -63, -65, -51, -45, -40, -40, -39, -39, -43, -44, + -46, -52, -46, -51, -49, -45, -45, -47, -47, -45, -50, + -47, -40, -35, -32, -24, -17, -19, -14, -13, -9, -7, + -7, -7, -9, 0, 3, 7, 13, 12, 14, 15, 13, + 6, -1, -3, -9, -10, -5, -2, 6, 9, 11, 12, + 15, 19, 24, 37, 47, 47, 56, 53, 51, 52, 52, + 47, 39, 38, 40, 41, 43, 44, 42, 43, 42, 41, + 43, 40, 41, 35, 37, 39, 40, 41, 38, 30, 21, + 14, 5, 2, -1, -2, 1, -2, 6, 2, 4, 2, + -1, -11, -16, -23, -25, -20, -18, -25, -27, -32, -27, + -24, -16, -15, -11, -9, -3, -4, -2, -9, -10, -18, + -28, -33, -38, -37, -41, -41, -33, -24, -22, -25, -25, + -25, -24, -33, -38, -42, -52, -57, -55, -50, -51, -53, + -52, -48, -49, -49, -53, -55, -58, -51, -34, -19, -12, + -12, -5, 1, 1, 0, -6, -2, -10, -11, -11, -6, + 0, -6, 2, -2, -6, 2, 5, 16, 18, 18, 21, + 16, 18, 18, 20, 20, 13, 18, 9, 7, 12, 7, + 8, 10, 16, 17, 18, 23, 26, 36, 44, 51, 55, + 60, 64, 69, 68, 71, 70, 62, 58, 52, 44, 35, + 31, 34, 32, 33, 36, 37, 38, 41, 47, 55, 56, + 58, 60, 60, 57, 48, 41, 29, 19, 7, 4, 8, + 9, 10, 8, 13, 15, 13, 8, 8, 6, 4, 10, + 8, -4, -6, -9, -20, -28, -39, -38, -27, -24, -22, + -19, -23, -32, -35, -36, -41, -48, -51, -50, -52, -55, + -60, -67, -72, -76, -84, -82, -80, -81, -75, -64, -50, + -36, -28, -18, -14, -12, -15, -12, -18, -24, -21, -22, + -19, -21, -19, -22, -20, -18, -16, -17, -19, -15, -7, + 1, 0, 0, 9, 14, 20, 24, 20, 16, 17, 20, + 20, 25, 27, 26, 32, 33, 35, 38, 42, 38, 37, + 39, 46, 44, 43, 45, 45, 42, 37, 34, 25, 21, + 22, 33, 44, 49, 54, 53, 58, 54, 51, 46, 40, + 37, 37, 39, 34, 37, 39, 31, 39, 38, 36, 35, + 32, 33, 33, 32, 28, 23, 18, 22, 28, 31, 27, + 18, 3, 4, 0, -4, -7, -15, -18, -24, -32, -34, + -39, -42, -36, -31, -24, -12, -10, -10, -13, -20, -28, + -34, -44, -49, -50, -53, -56, -54, -52, -53, -47, -43, + -41, -45, -41, -38, -38, -33, -32, -34, -35, -33, -40, + -45, -53, -62, -61, -67, -72, -70, -67, -68, -59, -51, + -47, -38, -31, -20, -13, -13, -13, -14, -17, -21, -22, + -29, -31, -27, -23, -13, -6, 4, 12, 17, 25, 23, + 23, 25, 30, 30, 32, 31, 28, 27, 18, 14, 13, + 3, 5, 7, 19, 35, 47, 61, 70, 84, 90, 95, + 92, 94, 89, 77, 71, 66, 59, 50, 51, 50, 51, + 53, 56, 65, 67, 69, 75, 74, 69, 67, 56, 51, + 44, 34, 25, 17, 10, 6, 7, 7, 4, 6, -1, + -1, -2, -9, -9, -9, -7, -5, 1, -2, -5, -11, + -19, -27, -39, -38, -44, -45, -48, -48, -54, -59, -53, + -51, -49, -52, -50, -50, -47, -42, -32, -28, -28, -26, + -27, -34, -40, -40, -36, -37, -37, -34, -37, -36, -41, + -36, -40, -46, -48, -52, -47, -44, -40, -40, -38, -43, + -43, -47, -59, -62, -59, -59, -51, -41, -29, -19, -8, + -2, 1, 1, -4, -9, -19, -23, -29, -29, -25, -23, + -15, -7, -2, 6, 8, 15, 27, 35, 43, 40, 36, + 35, 32, 25, 22, 19, 17, 13, 13, 21, 25, 28, + 36, 44, 50, 57, 56, 58, 59, 62, 66, 70, 73, + 69, 66, 66, 66, 62, 53, 48, 44, 38, 39, 44, + 52, 51, 55, 57, 52, 49, 44, 36, 26, 16, 13, + 13, 14, 14, 17, 14, 10, 6, -5, -14, -23, -24, + -21, -28, -25, -27, -29, -29, -33, -33, -39, -42, -43, + -41, -40, -43, -46, -45, -43, -42, -41, -41, -46, -46, + -52, -52, -52, -59, -63, -70, -68, -73, -77, -73, -68, + -66, -62, -64, -66, -58, -54, -51, -52, -48, -47, -43, + -40, -39, -33, -26, -19, -17, -16, -17, -14, -9, -10, + -3, 5, 5, 9, 5, 9, 8, 4, 3, 0, -5, + -10, -3, 2, 8, 14, 16, 20, 27, 39, 40, 44, + 48, 43, 39, 34, 29, 22, 12, 8, 5, 0, -2, + -3, 5, 12, 16, 19, 22, 25, 28, 35, 28, 30, + 31, 30, 39, 43, 47, 43, 42, 41, 41, 41, 37, + 37, 39, 37, 38, 43, 44, 41, 43, 34, 28, 25, + 23, 30, 34, 32, 33, 29, 21, 18, 13, 14, 11, + 3, 2, 1, 3, 1, -1, 0, -3, -1, -3, -8, + -9, -7, -9, -2, 0, -3, 0, 1, 5, 0, -1, + -9, -13, -8, -11, -18, -23, -25, -29, -29, -26, -27, + -29, -25, -24, -23, -18, -19, -18, -17, -21, -22, -30, + -38, -42, -42, -42, -40, -41, -43, -39, -38, -37, -36, + -33, -31, -28, -27, -18, -15, -7, -8, -8, -1, 1, + 3, -5, 0, -4, -5, -4, -8, -10, -14, -21, -24, + -25, -20, -11, -4, 3, 6, 13, 15, 12, 17, 16, + 17, 17, 15, 21, 28, 33, 36, 35, 35, 29, 31, + 29, 28, 23, 21, 14, 15, 27, 36, 40, 40, 43, + 51, 56, 62, 69, 77, 80, 88, 88, 88, 82, 76, + 63, 52, 44, 36, 26, 23, 25, 24, 27, 26, 31, + 21, 13, 8, -8, -8, -11, -14, -18, -28, -28, -30, + -32, -29, -26, -26, -27, -24, -20, -14, -8, -6, -8, + -5, -10, -14, -18, -26, -34, -36, -38, -44, -51, -57, + -66, -64, -68, -72, -75, -75, -70, -68, -65, -64, -62, + -68, -63, -60, -65, -65, -69, -68, -67, -57, -46, -41, + -38, -34, -31, -39, -40, -45, -45, -48, -47, -40, -39, + -32, -26, -24, -14, -9, -7, -3, -2, 3, 4, 0, + -2, -2, -2, 1, 3, 2, 3, 8, 13, 20, 25, + 29, 31, 26, 17, 11, 3, -5, 2, 6, 9, 11, + 19, 26, 40, 51, 61, 60, 58, 61, 55, 55, 57, + 60, 54, 40, 42, 38, 34, 38, 37, 34, 32, 35, + 36, 35, 41, 36, 32, 29, 23, 22, 23, 22, 14, + 13, 19, 19, 20, 22, 22, 17, 13, 6, 9, 13, + 15, 17, 19, 11, 15, 8, 4, 6, -1, -3, 3, + 7, 11, 8, 10, 7, 6, 4, -4, -5, -11, -9, + -16, -14, -14, -16, -16, -22, -19, -19, -13, -9, -4, + 1, 1, 2, -6, -14, -25, -32, -41, -46, -50, -49, + -42, -39, -34, -24, -14, -18, -15, -17, -21, -23, -21, + -19, -21, -20, -19, -20, -19, -16, -17, -19, -20, -20, + -20, -20, -22, -22, -23, -22, -22, -14, -5, 5, 8, + 13, 16, 19, 23, 19, 21, 16, 16, 18, 13, 18, + 13, 15, 18, 12, 12, 6, 11, 8, 5, 5, 9, + 17, 14, 15, 14, 16, 14, 14, 12, 9, 7, 9, + 11, 13, 15, 15, 19, 17, 14, 8, 7, 4, 0, + 3, 8, 10, 7, 8, 19, 15, 19, 18, 19, 17, + 9, 14, 10, 4, -3, -11, -19, -25, -31, -35, -36, + -28, -21, -8, 5, 8, 11, 13, 7, 4, 1, -7, + -15, -17, -17, -21, -28, -33, -37, -40, -39, -41, -45, + -46, -44, -40, -41, -36, -31, -41, -40, -42, -44, -47, + -50, -49, -55, -52, -52, -52, -45, -50, -52, -56, -58, + -60, -69, -75, -82, -86, -91, -87, -80, -80, -72, -58, + -52, -45, -33, -21, -13, -12, -10, -6, -1, -2, -7, + -7, -5, -6, -3, 9, 15, 25, 36, 35, 39, 28, + 16, 11, 8, 11, 17, 27, 34, 36, 47, 49, 52, + 52, 42, 46, 49, 55, 65, 66, 67, 62, 56, 53, + 49, 50, 55, 53, 62, 69, 72, 73, 68, 61, 54, + 46, 43, 38, 34, 39, 43, 42, 39, 36, 31, 26, + 24, 17, 13, 14, 14, 21, 26, 29, 28, 26, 24, + 18, 19, 16, 11, 6, 2, -2, 1, 3, 2, -4, + -3, -1, -3, -2, -2, -5, -3, 0, 3, -3, -6, + -6, -15, -19, -25, -30, -35, -39, -34, -34, -34, -31, + -17, -17, -8, -2, -2, 8, 14, 25, 24, 26, 22, + 16, 10, 2, -3, -5, -12, -15, -11, -14, -16, -17, + -17, -16, -21, -18, -18, -21, -23, -21, -15, -11, -4, + -2, 3, 8, 10, 17, 18, 25, 24, 24, 24, 21, + 24, 23, 24, 22, 23, 31, 39, 49, 58, 64, 67, + 63, 57, 53, 52, 44, 45, 43, 40, 45, 42, 49, + 50, 49, 52, 51, 48, 46, 38, 37, 35, 36, 37, + 37, 37, 44, 45, 47, 42, 42, 36, 35, 44, 40, + 40, 28, 24, 23, 18, 12, 9, 8, 10, 17, 17, + 18, 12, 5, -2, -12, -16, -20, -27, -29, -29, -26, + -22, -17, -16, -15, -14, -15, -11, -11, -15, -19, -15, + -20, -22, -24, -37, -52, -62, -63, -68, -64, -59, -51, + -43, -42, -36, -32, -33, -33, -33, -41, -48, -51, -49, + -48, -47, -42, -45, -42, -41, -40, -39, -33, -29, -25, + -14, -1, -4, -6, -11, -16, -19, -26, -29, -28, -25, + -17, -10, -1, -1, 3, 7, -1, -3, -8, -18, -20, + -20, -16, -13, -11, -8, 0, 6, 8, 11, 14, 15, + 20, 26, 26, 26, 24, 23, 24, 30, 34, 41, 52, + 61, 70, 80, 85, 86, 89, 84, 87, 79, 67, 60, + 57, 59, 63, 68, 74, 78, 84, 89, 91, 87, 81, + 74, 69, 63, 59, 59, 56, 58, 60, 60, 59, 54, + 49, 41, 40, 34, 25, 19, 11, 1, 0, -1, -4, + -8, -12, -12, -17, -22, -31, -44, -54, -58, -68, -74, + -80, -80, -73, -65, -61, -61, -55, -50, -50, -59, -65, + -69, -73, -73, -78, -79, -83, -87, -87, -88, -94, -103, + -107, -107, -109, -106, -113, -115, -110, -105, -100, -100, -92, + -78, -62, -49, -39, -35, -27, -26, -25, -24, -22, -23, + -28, -26, -22, -15, -11, -4, 4, 13, 21, 32, 31, + 28, 30, 30, 28, 23, 25, 23, 21, 25, 21, 26, + 27, 32, 40, 48, 53, 55, 54, 55, 55, 54, 48, + 44, 47, 48, 54, 60, 71, 79, 79, 74, 72, 59, + 48, 42, 32, 26, 22, 21, 23, 22, 31, 42, 44, + 41, 36, 30, 30, 33, 38, 35, 30, 28, 20, 15, + 8, 4, 6, 9, 16, 26, 27, 23, 19, 16, 10, + 4, -4, -12, -12, -16, -16, -19, -24, -23, -23, -31, + -34, -38, -40, -41, -39, -39, -36, -36, -40, -45, -48, + -53, -66, -73, -76, -76, -78, -75, -71, -65, -59, -58, + -59, -56, -60, -62, -62, -62, -64, -68, -73, -79, -80, + -85, -87, -85, -78, -72, -66, -56, -48, -42, -37, -35, + -32, -33, -31, -25, -26, -27, -16, -18, -18, -13, -14, + -17, -22, -24, -25, -23, -19, -14, -12, -11, -7, -4, + -1, 2, 5, 8, 10, 10, 18, 28, 29, 25, 22, + 29, 21, 20, 21, 22, 30, 32, 41, 41, 45, 46, + 49, 52, 57, 59, 58, 52, 46, 47, 56, 58, 49, + 49, 46, 40, 33, 23, 14, 11, 16, 29, 34, 37, + 41, 42, 48, 54, 60, 61, 62, 62, 69, 79, 76, + 71, 72, 71, 64, 59, 54, 49, 40, 42, 34, 23, + 27, 18, 13, 9, 3, -4, -8, -16, -18, -20, -26, + -28, -30, -32, -29, -32, -35, -39, -41, -38, -34, -31, + -26, -18, -21, -20, -22, -28, -35, -34, -31, -33, -31, + -31, -40, -43, -45, -53, -64, -67, -74, -75, -74, -75, + -70, -61, -56, -45, -37, -30, -33, -35, -32, -31, -27, + -25, -19, -17, -14, -9, -4, -1, -3, -4, 1, 8, + 14, 20, 24, 25, 18, 11, 7, -3, -9, -3, 4, + 15, 30, 29, 33, 33, 36, 35, 31, 33, 34, 42, + 43, 42, 47, 49, 53, 61, 69, 73, 74, 79, 81, + 84, 76, 69, 62, 47, 39, 31, 19, 8, 2, -6, + -5, -3, -3, -1, 1, -2, -3, -3, -6, -12, -13, + -15, -11, -5, -4, -8, -14, -9, -3, 0, -3, -4, + 0, 3, 0, -6, -14, -23, -33, -38, -41, -38, -38, + -34, -30, -29, -29, -26, -31, -33, -41, -49, -50, -56, + -57, -58, -54, -46, -39, -39, -34, -31, -28, -30, -30, + -31, -29, -27, -16, -18, -17, -15, -13, -15, -12, -7, + -11, -9, -9, -4, -11, -7, -7, -8, -9, -10, -7, + -9, 1, 9, 15, 12, 19, 19, 18, 17, 13, 11, + 8, 6, 10, 17, 20, 26, 28, 33, 39, 30, 25, + 25, 18, 16, 21, 26, 30, 33, 32, 36, 42, 49, + 46, 39, 44, 44, 37, 35, 30, 24, 22, 23, 26, + 23, 25, 21, 24, 24, 22, +}; diff --git a/micro_speech/src/no_1000ms_sample_data.h b/micro_speech/src/no_1000ms_sample_data.h new file mode 100644 index 0000000..ab2d67b --- /dev/null +++ b/micro_speech/src/no_1000ms_sample_data.h @@ -0,0 +1,29 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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. +==============================================================================*/ + +// This data was created from the PCM data in a WAV file held in v2 of the +// Speech Commands test dataset, at the path: +// speech_commands_test_set_v0.02/no/f9643d42_nohash_4.wav +// This should contain all 16,000 samples from the one-second file. + +#ifndef TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_NO_1000MS_SAMPLE_DATA_H_ +#define TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_NO_1000MS_SAMPLE_DATA_H_ + +#include + +extern const int g_no_1000ms_sample_data_size; +extern const int16_t g_no_1000ms_sample_data[]; + +#endif // TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_NO_1000MS_SAMPLE_DATA_H_ diff --git a/micro_speech/src/no_30ms_sample_data.cc b/micro_speech/src/no_30ms_sample_data.cc new file mode 100644 index 0000000..674b30a --- /dev/null +++ b/micro_speech/src/no_30ms_sample_data.cc @@ -0,0 +1,66 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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. +==============================================================================*/ + +// See the header for documentation on the meaning of this data. + +#include "no_30ms_sample_data.h" + +const int g_no_30ms_sample_data_size = 480; +const int16_t g_no_30ms_sample_data[480] = { + 5713, 5735, 5735, 5737, 5701, 5691, 5656, 5633, 5611, 5552, 5475, + 5394, 5293, 5177, 5064, 4924, 4737, 4599, 4420, 4237, 4048, 3828, + 3623, 3413, 3183, 2915, 2622, 2308, 1980, 1657, 1261, 901, 549, + 205, -85, -383, -688, -969, -1246, -1530, -1850, -2206, -2561, -2915, + -3224, -3482, -3713, -3921, -4107, -4287, -4470, -4660, -4850, -5057, -5239, + -5395, -5540, -5619, -5697, -5724, -5697, -5675, -5633, -5590, -5579, -5530, + -5486, -5442, -5426, -5391, -5348, -5276, -5197, -5124, -5039, -4925, -4808, + -4677, -4581, -4479, -4343, -4218, -4087, -3970, -3858, -3729, -3570, -3384, + -3206, -3020, -2839, -2636, -2453, -2287, -2185, -2154, -1926, -1562, -1223, + -758, -473, -64, 395, 599, 880, 814, 938, 1172, 1498, 1928, + 2127, 2422, 2608, 2841, 2937, 2886, 2815, 2985, 3324, 3757, 4152, + 4481, 4652, 4917, 4965, 4766, 4583, 4328, 4503, 4815, 5118, 5408, + 5682, 5956, 6082, 6055, 5744, 5426, 5341, 5427, 5606, 5882, 6065, + 6226, 6428, 6477, 6385, 6009, 5728, 5552, 5439, 5339, 5200, 5008, + 4947, 4835, 4614, 4330, 3887, 3521, 3111, 2460, 1983, 1297, 650, + 279, -353, -720, -1044, -1518, -1668, -2117, -2496, -2743, -3266, -3607, + -3790, -4149, -4075, -4042, -4096, -3981, -4138, -4226, -4214, -4503, -4455, + -4577, -4642, -4346, -4351, -4270, -4263, -4522, -4521, -4673, -4814, -4731, + -4950, -5011, -5004, -5288, -5341, -5566, -5833, -5783, -5929, -5847, -5765, + -5828, -5644, -5613, -5615, -5428, -5291, -5014, -4554, -4277, -3964, -3854, + -3829, -3612, -3603, -3438, -3137, -2831, -2164, -1438, -939, -330, -156, + 46, 242, 73, 242, 220, 239, 542, 565, 739, 872, 801, + 857, 676, 543, 586, 567, 828, 1142, 1490, 1985, 2508, 2982, + 3438, 3699, 3939, 4069, 4178, 4420, 4622, 4917, 5338, 5801, 6285, + 6658, 6963, 7213, 7233, 7328, 7176, 7038, 7031, 6860, 6957, 6767, + 6599, 6523, 6212, 6147, 6063, 5860, 6020, 6015, 6033, 6184, 5722, + 5607, 5016, 4337, 4063, 3229, 3080, 3006, 2804, 3035, 2541, 2136, + 1879, 1012, 401, -575, -1584, -1930, -2278, -2485, -2477, -2712, -2747, + -2766, -3320, -3592, -4188, -4669, -4672, -4939, -4789, -4426, -4203, -3674, + -3563, -3656, -3759, -4067, -4257, -4522, -4970, -5204, -5237, -5139, -4907, + -4911, -4917, -4921, -5007, -5230, -5654, -6122, -6464, -6733, -6948, -7067, + -6972, -6800, -6520, -6132, -5830, -5382, -5091, -4797, -4546, -4472, -4362, + -4350, -4235, -3851, -3454, -3144, -2735, -2341, -1845, -1262, -958, -549, + -166, 66, 382, 366, 352, 341, 85, -13, -176, -303, -235, + -341, -309, -227, -249, -50, 143, 384, 874, 1149, 1552, 2155, + 2767, 3499, 3994, 4460, 4920, 5288, 5569, 5704, 5881, 6094, 6461, + 6653, 6803, 7115, 7311, 7521, 7612, 7443, 7380, 7124, 6742, 6495, + 5964, 5656, 5415, 5167, 5656, 5813, 6027, 6401, 6351, 6787, 7019, + 6581, 6512, 5965, 5308, 5140, 4336, 4147, 3899, 3398, 3360, 2830, + 2624, 1968, 1026, 395, -699, -1424, -2327, -3006, -3192, -3435, -3337, + -3686, -3513, -3350, -3502, -3261, -3878, -4005, -4063, -4187, -3767, -3598, + -3384, -3300, -3094, -2857, -3023, -3274, -3851, -4352, -4523, -4943, -5477, + -5612, -5682, -5733, -5714, -5965, -6110, -5950, -6158, -6548, -6897, -7165, + -7281, -7352, -7258, -7185, -6659, -5946, -5470, +}; diff --git a/micro_speech/src/no_30ms_sample_data.h b/micro_speech/src/no_30ms_sample_data.h new file mode 100644 index 0000000..1eecca2 --- /dev/null +++ b/micro_speech/src/no_30ms_sample_data.h @@ -0,0 +1,32 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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. +==============================================================================*/ + +// This data was created from the PCM data in a WAV file held in v2 of the +// Speech Commands test dataset, at the path: +// speech_commands_test_set_v0.02/no/f9643d42_nohash_4.wav +// The data was extracted starting at an offset of 8,960, which corresponds to +// the 29th spectrogram slice. It's designed to be used to test the +// preprocessing pipeline, to ensure that the expected spectrogram slice is +// produced given this input. + +#ifndef TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_NO_30MS_SAMPLE_DATA_H_ +#define TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_NO_30MS_SAMPLE_DATA_H_ + +#include + +extern const int g_no_30ms_sample_data_size; +extern const int16_t g_no_30ms_sample_data[]; + +#endif // TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_NO_30MS_SAMPLE_DATA_H_ diff --git a/micro_speech/src/recognize_commands.cc b/micro_speech/src/recognize_commands.cc new file mode 100644 index 0000000..37e8063 --- /dev/null +++ b/micro_speech/src/recognize_commands.cc @@ -0,0 +1,142 @@ +/* Copyright 2017 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 "recognize_commands.h" + +#include + +RecognizeCommands::RecognizeCommands(tflite::ErrorReporter* error_reporter, + int32_t average_window_duration_ms, + uint8_t detection_threshold, + int32_t suppression_ms, + int32_t minimum_count) + : error_reporter_(error_reporter), + average_window_duration_ms_(average_window_duration_ms), + detection_threshold_(detection_threshold), + suppression_ms_(suppression_ms), + minimum_count_(minimum_count), + previous_results_(error_reporter) { + previous_top_label_ = "silence"; + previous_top_label_time_ = std::numeric_limits::min(); +} + +TfLiteStatus RecognizeCommands::ProcessLatestResults( + const TfLiteTensor* latest_results, const int32_t current_time_ms, + const char** found_command, uint8_t* score, bool* is_new_command) { + if ((latest_results->dims->size != 2) || + (latest_results->dims->data[0] != 1) || + (latest_results->dims->data[1] != kCategoryCount)) { + TF_LITE_REPORT_ERROR( + error_reporter_, + "The results for recognition should contain %d elements, but there are " + "%d in an %d-dimensional shape", + kCategoryCount, latest_results->dims->data[1], + latest_results->dims->size); + return kTfLiteError; + } + + if (latest_results->type != kTfLiteInt8) { + TF_LITE_REPORT_ERROR( + error_reporter_, + "The results for recognition should be int8_t elements, but are %d", + latest_results->type); + return kTfLiteError; + } + + if ((!previous_results_.empty()) && + (current_time_ms < previous_results_.front().time_)) { + TF_LITE_REPORT_ERROR( + error_reporter_, + "Results must be fed in increasing time order, but received a " + "timestamp of %d that was earlier than the previous one of %d", + current_time_ms, previous_results_.front().time_); + return kTfLiteError; + } + + // Add the latest results to the head of the queue. + previous_results_.push_back({current_time_ms, latest_results->data.int8}); + + // Prune any earlier results that are too old for the averaging window. + const int64_t time_limit = current_time_ms - average_window_duration_ms_; + while ((!previous_results_.empty()) && + previous_results_.front().time_ < time_limit) { + previous_results_.pop_front(); + } + + // If there are too few results, assume the result will be unreliable and + // bail. + const int64_t how_many_results = previous_results_.size(); + const int64_t earliest_time = previous_results_.front().time_; + const int64_t samples_duration = current_time_ms - earliest_time; + if ((how_many_results < minimum_count_) || + (samples_duration < (average_window_duration_ms_ / 4))) { + *found_command = previous_top_label_; + *score = 0; + *is_new_command = false; + return kTfLiteOk; + } + + // Calculate the average score across all the results in the window. + int32_t average_scores[kCategoryCount]; + for (int offset = 0; offset < previous_results_.size(); ++offset) { + PreviousResultsQueue::Result previous_result = + previous_results_.from_front(offset); + const int8_t* scores = previous_result.scores; + for (int i = 0; i < kCategoryCount; ++i) { + if (offset == 0) { + average_scores[i] = scores[i] + 128; + } else { + average_scores[i] += scores[i] + 128; + } + } + } + for (int i = 0; i < kCategoryCount; ++i) { + average_scores[i] /= how_many_results; + } + + // Find the current highest scoring category. + int current_top_index = 0; + int32_t current_top_score = 0; + for (int i = 0; i < kCategoryCount; ++i) { + if (average_scores[i] > current_top_score) { + current_top_score = average_scores[i]; + current_top_index = i; + } + } + const char* current_top_label = kCategoryLabels[current_top_index]; + + // If we've recently had another label trigger, assume one that occurs too + // soon afterwards is a bad result. + int64_t time_since_last_top; + if ((previous_top_label_ == kCategoryLabels[0]) || + (previous_top_label_time_ == std::numeric_limits::min())) { + time_since_last_top = std::numeric_limits::max(); + } else { + time_since_last_top = current_time_ms - previous_top_label_time_; + } + if ((current_top_score > detection_threshold_) && + ((current_top_label != previous_top_label_) || + (time_since_last_top > suppression_ms_))) { + previous_top_label_ = current_top_label; + previous_top_label_time_ = current_time_ms; + *is_new_command = true; + } else { + *is_new_command = false; + } + *found_command = current_top_label; + *score = current_top_score; + + return kTfLiteOk; +} diff --git a/micro_speech/src/recognize_commands.h b/micro_speech/src/recognize_commands.h new file mode 100644 index 0000000..615c9cd --- /dev/null +++ b/micro_speech/src/recognize_commands.h @@ -0,0 +1,159 @@ +/* Copyright 2017 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_RECOGNIZE_COMMANDS_H_ +#define TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_RECOGNIZE_COMMANDS_H_ + +#include + +#include "tensorflow/lite/c/common.h" +#include "micro_features/micro_model_settings.h" +#include "tensorflow/lite/micro/micro_error_reporter.h" + +// Partial implementation of std::dequeue, just providing the functionality +// that's needed to keep a record of previous neural network results over a +// short time period, so they can be averaged together to produce a more +// accurate overall prediction. This doesn't use any dynamic memory allocation +// so it's a better fit for microcontroller applications, but this does mean +// there are hard limits on the number of results it can store. +class PreviousResultsQueue { + public: + PreviousResultsQueue(tflite::ErrorReporter* error_reporter) + : error_reporter_(error_reporter), front_index_(0), size_(0) {} + + // Data structure that holds an inference result, and the time when it + // was recorded. + struct Result { + Result() : time_(0), scores() {} + Result(int32_t time, int8_t* input_scores) : time_(time) { + for (int i = 0; i < kCategoryCount; ++i) { + scores[i] = input_scores[i]; + } + } + int32_t time_; + int8_t scores[kCategoryCount]; + }; + + int size() { return size_; } + bool empty() { return size_ == 0; } + Result& front() { return results_[front_index_]; } + Result& back() { + int back_index = front_index_ + (size_ - 1); + if (back_index >= kMaxResults) { + back_index -= kMaxResults; + } + return results_[back_index]; + } + + void push_back(const Result& entry) { + if (size() >= kMaxResults) { + TF_LITE_REPORT_ERROR( + error_reporter_, + "Couldn't push_back latest result, too many already!"); + return; + } + size_ += 1; + back() = entry; + } + + Result pop_front() { + if (size() <= 0) { + TF_LITE_REPORT_ERROR(error_reporter_, + "Couldn't pop_front result, none present!"); + return Result(); + } + Result result = front(); + front_index_ += 1; + if (front_index_ >= kMaxResults) { + front_index_ = 0; + } + size_ -= 1; + return result; + } + + // Most of the functions are duplicates of dequeue containers, but this + // is a helper that makes it easy to iterate through the contents of the + // queue. + Result& from_front(int offset) { + if ((offset < 0) || (offset >= size_)) { + TF_LITE_REPORT_ERROR(error_reporter_, + "Attempt to read beyond the end of the queue!"); + offset = size_ - 1; + } + int index = front_index_ + offset; + if (index >= kMaxResults) { + index -= kMaxResults; + } + return results_[index]; + } + + private: + tflite::ErrorReporter* error_reporter_; + static constexpr int kMaxResults = 50; + Result results_[kMaxResults]; + + int front_index_; + int size_; +}; + +// This class is designed to apply a very primitive decoding model on top of the +// instantaneous results from running an audio recognition model on a single +// window of samples. It applies smoothing over time so that noisy individual +// label scores are averaged, increasing the confidence that apparent matches +// are real. +// To use it, you should create a class object with the configuration you +// want, and then feed results from running a TensorFlow model into the +// processing method. The timestamp for each subsequent call should be +// increasing from the previous, since the class is designed to process a stream +// of data over time. +class RecognizeCommands { + public: + // labels should be a list of the strings associated with each one-hot score. + // The window duration controls the smoothing. Longer durations will give a + // higher confidence that the results are correct, but may miss some commands. + // The detection threshold has a similar effect, with high values increasing + // the precision at the cost of recall. The minimum count controls how many + // results need to be in the averaging window before it's seen as a reliable + // average. This prevents erroneous results when the averaging window is + // initially being populated for example. The suppression argument disables + // further recognitions for a set time after one has been triggered, which can + // help reduce spurious recognitions. + explicit RecognizeCommands(tflite::ErrorReporter* error_reporter, + int32_t average_window_duration_ms = 1000, + uint8_t detection_threshold = 140, + int32_t suppression_ms = 1500, + int32_t minimum_count = 3); + + // Call this with the results of running a model on sample data. + TfLiteStatus ProcessLatestResults(const TfLiteTensor* latest_results, + const int32_t current_time_ms, + const char** found_command, uint8_t* score, + bool* is_new_command); + + private: + // Configuration + tflite::ErrorReporter* error_reporter_; + int32_t average_window_duration_ms_; + uint8_t detection_threshold_; + int32_t suppression_ms_; + int32_t minimum_count_; + + // Working variables + PreviousResultsQueue previous_results_; + const char* previous_top_label_; + int32_t previous_top_label_time_; +}; + +#endif // TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_RECOGNIZE_COMMANDS_H_ diff --git a/micro_speech/src/recognize_commands_test.cc b/micro_speech/src/recognize_commands_test.cc new file mode 100644 index 0000000..5d9888b --- /dev/null +++ b/micro_speech/src/recognize_commands_test.cc @@ -0,0 +1,213 @@ +/* Copyright 2017 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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 "recognize_commands.h" + +#include "tensorflow/lite/micro/test_helpers.h" +#include "tensorflow/lite/micro/testing/micro_test.h" + +TF_LITE_MICRO_TESTS_BEGIN + +TF_LITE_MICRO_TEST(PreviousResultsQueueBasic) { + tflite::MicroErrorReporter micro_error_reporter; + + PreviousResultsQueue queue(µ_error_reporter); + TF_LITE_MICRO_EXPECT_EQ(0, queue.size()); + + int8_t scores_a[4] = {0, 0, 0, 1}; + queue.push_back({0, scores_a}); + TF_LITE_MICRO_EXPECT_EQ(1, queue.size()); + TF_LITE_MICRO_EXPECT_EQ(0, queue.front().time_); + TF_LITE_MICRO_EXPECT_EQ(0, queue.back().time_); + + int8_t scores_b[4] = {0, 0, 1, 0}; + queue.push_back({1, scores_b}); + TF_LITE_MICRO_EXPECT_EQ(2, queue.size()); + TF_LITE_MICRO_EXPECT_EQ(0, queue.front().time_); + TF_LITE_MICRO_EXPECT_EQ(1, queue.back().time_); + + PreviousResultsQueue::Result pop_result = queue.pop_front(); + TF_LITE_MICRO_EXPECT_EQ(0, pop_result.time_); + TF_LITE_MICRO_EXPECT_EQ(1, queue.size()); + TF_LITE_MICRO_EXPECT_EQ(1, queue.front().time_); + TF_LITE_MICRO_EXPECT_EQ(1, queue.back().time_); + + int8_t scores_c[4] = {0, 1, 0, 0}; + queue.push_back({2, scores_c}); + TF_LITE_MICRO_EXPECT_EQ(2, queue.size()); + TF_LITE_MICRO_EXPECT_EQ(1, queue.front().time_); + TF_LITE_MICRO_EXPECT_EQ(2, queue.back().time_); +} + +TF_LITE_MICRO_TEST(PreviousResultsQueuePushPop) { + tflite::MicroErrorReporter micro_error_reporter; + + PreviousResultsQueue queue(µ_error_reporter); + TF_LITE_MICRO_EXPECT_EQ(0, queue.size()); + + for (int i = 0; i < 123; ++i) { + int8_t scores[4] = {0, 0, 0, 1}; + queue.push_back({i, scores}); + TF_LITE_MICRO_EXPECT_EQ(1, queue.size()); + TF_LITE_MICRO_EXPECT_EQ(i, queue.front().time_); + TF_LITE_MICRO_EXPECT_EQ(i, queue.back().time_); + + PreviousResultsQueue::Result pop_result = queue.pop_front(); + TF_LITE_MICRO_EXPECT_EQ(i, pop_result.time_); + TF_LITE_MICRO_EXPECT_EQ(0, queue.size()); + } +} + +TF_LITE_MICRO_TEST(RecognizeCommandsTestBasic) { + tflite::MicroErrorReporter micro_error_reporter; + + RecognizeCommands recognize_commands(µ_error_reporter); + + const int8_t result_data[] = {127, -128, -128, -128}; + int result_dims[] = {2, 1, 4}; + TfLiteTensor results = tflite::testing::CreateQuantizedTensor( + result_data, tflite::testing::IntArrayFromInts(result_dims), -128.0f, + 127.0f); + + const char* found_command; + uint8_t score; + bool is_new_command; + TF_LITE_MICRO_EXPECT_EQ( + kTfLiteOk, recognize_commands.ProcessLatestResults( + &results, 0, &found_command, &score, &is_new_command)); +} + +TF_LITE_MICRO_TEST(RecognizeCommandsTestFindCommands) { + tflite::MicroErrorReporter micro_error_reporter; + + RecognizeCommands recognize_commands(µ_error_reporter, 1000, 51); + + const int8_t yes_data[] = {-128, -128, 127, -128}; + int yes_dims[] = {2, 1, 4}; + TfLiteTensor yes_results = tflite::testing::CreateQuantizedTensor( + yes_data, tflite::testing::IntArrayFromInts(yes_dims), -128.0f, 127.0f); + + bool has_found_new_command = false; + const char* new_command; + for (int i = 0; i < 10; ++i) { + const char* found_command; + uint8_t score; + bool is_new_command; + int32_t current_time_ms = 0 + (i * 100); + TF_LITE_MICRO_EXPECT_EQ( + kTfLiteOk, recognize_commands.ProcessLatestResults( + &yes_results, current_time_ms, &found_command, &score, + &is_new_command)); + if (is_new_command) { + TF_LITE_MICRO_EXPECT(!has_found_new_command); + has_found_new_command = true; + new_command = found_command; + } + } + TF_LITE_MICRO_EXPECT(has_found_new_command); + if (has_found_new_command) { + TF_LITE_MICRO_EXPECT_EQ(0, tflite::testing::TestStrcmp("yes", new_command)); + } + + const int8_t no_data[] = {-128, -128, -128, 127}; + int no_dims[] = {2, 1, 4}; + TfLiteTensor no_results = tflite::testing::CreateQuantizedTensor( + no_data, tflite::testing::IntArrayFromInts(no_dims), -128.0f, 127.0f); + has_found_new_command = false; + new_command = ""; + uint8_t score; + for (int i = 0; i < 10; ++i) { + const char* found_command; + bool is_new_command; + int32_t current_time_ms = 1000 + (i * 100); + TF_LITE_MICRO_EXPECT_EQ( + kTfLiteOk, recognize_commands.ProcessLatestResults( + &no_results, current_time_ms, &found_command, &score, + &is_new_command)); + if (is_new_command) { + TF_LITE_MICRO_EXPECT(!has_found_new_command); + has_found_new_command = true; + new_command = found_command; + } + } + TF_LITE_MICRO_EXPECT(has_found_new_command); + if (has_found_new_command) { + TF_LITE_MICRO_EXPECT_EQ(231, score); + TF_LITE_MICRO_EXPECT_EQ(0, tflite::testing::TestStrcmp("no", new_command)); + } +} + +TF_LITE_MICRO_TEST(RecognizeCommandsTestBadInputLength) { + tflite::MicroErrorReporter micro_error_reporter; + + RecognizeCommands recognize_commands(µ_error_reporter, 1000, 51); + + const int8_t bad_data[] = {-128, -128, 127}; + int bad_dims[] = {2, 1, 3}; + TfLiteTensor bad_results = tflite::testing::CreateQuantizedTensor( + bad_data, tflite::testing::IntArrayFromInts(bad_dims), -128.0f, 127.0f); + + const char* found_command; + uint8_t score; + bool is_new_command; + TF_LITE_MICRO_EXPECT_NE( + kTfLiteOk, recognize_commands.ProcessLatestResults( + &bad_results, 0, &found_command, &score, &is_new_command)); +} + +TF_LITE_MICRO_TEST(RecognizeCommandsTestBadInputTimes) { + tflite::MicroErrorReporter micro_error_reporter; + + RecognizeCommands recognize_commands(µ_error_reporter, 1000, 51); + + const int8_t result_data[] = {-128, -128, 127, -128}; + int result_dims[] = {2, 1, 4}; + TfLiteTensor results = tflite::testing::CreateQuantizedTensor( + result_data, tflite::testing::IntArrayFromInts(result_dims), -128.0f, + 127.0f); + + const char* found_command; + uint8_t score; + bool is_new_command; + TF_LITE_MICRO_EXPECT_EQ( + kTfLiteOk, recognize_commands.ProcessLatestResults( + &results, 100, &found_command, &score, &is_new_command)); + TF_LITE_MICRO_EXPECT_NE( + kTfLiteOk, recognize_commands.ProcessLatestResults( + &results, 0, &found_command, &score, &is_new_command)); +} + +TF_LITE_MICRO_TEST(RecognizeCommandsTestTooFewInputs) { + tflite::MicroErrorReporter micro_error_reporter; + + RecognizeCommands recognize_commands(µ_error_reporter, 1000, 51); + + const int8_t result_data[] = {-128, -128, 127, -128}; + int result_dims[] = {2, 1, 4}; + TfLiteTensor results = tflite::testing::CreateQuantizedTensor( + result_data, tflite::testing::IntArrayFromInts(result_dims), -128.0f, + 127.0f); + + const char* found_command; + uint8_t score; + bool is_new_command; + TF_LITE_MICRO_EXPECT_EQ( + kTfLiteOk, recognize_commands.ProcessLatestResults( + &results, 100, &found_command, &score, &is_new_command)); + TF_LITE_MICRO_EXPECT_EQ(0, score); + TF_LITE_MICRO_EXPECT_EQ(false, is_new_command); +} + +TF_LITE_MICRO_TESTS_END diff --git a/micro_speech/src/yes_1000ms_sample_data.cc b/micro_speech/src/yes_1000ms_sample_data.cc new file mode 100644 index 0000000..f480afb --- /dev/null +++ b/micro_speech/src/yes_1000ms_sample_data.cc @@ -0,0 +1,1800 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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. +==============================================================================*/ + +// See the header for documentation on the meaning of this data. + +#include "yes_1000ms_sample_data.h" + +const int g_yes_1000ms_sample_data_size = 16000; +const int16_t g_yes_1000ms_sample_data[16000] = { + -7, -12, -18, -20, -20, -21, -21, -25, -29, + -31, -31, -30, -30, -29, -30, -30, -29, -28, + -24, -22, -17, -12, -8, -7, -6, -1, 2, + 5, 7, 8, 11, 15, 18, 19, 23, 24, + 24, 27, 27, 26, 25, 28, 30, 32, 33, + 31, 29, 27, 28, 30, 28, 26, 26, 24, + 22, 17, 16, 15, 13, 10, 5, 0, -4, + -4, -7, -9, -12, -14, -14, -13, -11, -10, + -8, -6, -3, 3, 7, 8, 12, 15, 18, + 21, 19, 19, 21, 23, 24, 23, 22, 19, + 17, 11, 5, -3, -12, -22, -28, -35, -45, + -54, -62, -69, -76, -84, -92, -100, -109, -116, + -117, -120, -120, -120, -122, -124, -126, -123, -121, + -116, -113, -107, -97, -88, -75, -61, -50, -41, + -27, -12, 4, 21, 37, 58, 76, 93, 108, + 121, 137, 156, 172, 184, 196, 205, 215, 224, + 235, 242, 245, 242, 240, 238, 231, 223, 214, + 205, 195, 178, 158, 135, 112, 90, 69, 46, + 19, -11, -45, -76, -105, -133, -159, -186, -211, + -236, -260, -280, -294, -308, -320, -331, -336, -338, + -335, -326, -316, -301, -286, -267, -246, -225, -203, + -180, -154, -124, -91, -59, -34, -8, 19, 42, + 64, 87, 103, 119, 134, 148, 162, 174, 182, + 188, 190, 189, 187, 184, 180, 177, 171, 162, + 154, 144, 137, 129, 118, 106, 95, 81, 69, + 58, 48, 37, 26, 14, 3, -7, -22, -31, + -42, -52, -62, -69, -75, -79, -82, -87, -88, + -92, -94, -91, -87, -85, -81, -74, -70, -64, + -55, -47, -40, -33, -25, -19, -12, -6, -4, + -1, 1, 1, -2, -9, -15, -17, -18, -20, + -22, -22, -26, -31, -33, -35, -31, -26, -17, + -4, 8, 19, 31, 44, 54, 64, 71, 79, + 86, 92, 102, 109, 111, 109, 104, 96, 84, + 70, 60, 51, 38, 27, 13, 4, -3, -9, + -13, -18, -26, -33, -32, -27, -20, -10, -4, + 2, 6, 10, 14, 16, 21, 25, 29, 31, + 33, 35, 37, 33, 22, 15, 13, 11, 12, + 9, 5, 2, 1, -3, -9, -17, -27, -32, + -35, -36, -36, -42, -50, -56, -66, -77, -85, + -96, -100, -106, -113, -118, -121, -119, -117, -119, + -122, -124, -123, -112, -94, -77, -64, -51, -37, + -22, -3, 17, 37, 54, 68, 86, 100, 114, + 134, 154, 167, 174, 178, 182, 189, 189, 187, + 185, 179, 177, 174, 171, 157, 138, 123, 108, + 94, 76, 50, 25, 6, -8, -20, -37, -59, + -86, -110, -132, -147, -159, -169, -178, -191, -203, + -213, -217, -215, -208, -199, -194, -195, -190, -178, + -165, -155, -144, -134, -123, -103, -80, -56, -35, + -18, -4, 11, 23, 36, 50, 65, 78, 93, + 111, 122, 129, 132, 131, 127, 125, 126, 126, + 128, 127, 125, 122, 118, 111, 108, 104, 99, + 93, 89, 90, 87, 82, 78, 75, 68, 65, + 67, 69, 66, 61, 54, 39, 28, 15, 3, + -7, -18, -25, -29, -35, -42, -52, -66, -78, + -83, -85, -86, -86, -82, -83, -84, -83, -81, + -75, -62, -57, -53, -49, -46, -41, -34, -26, + -16, -10, -7, -2, 2, 6, 12, 15, 19, + 18, 15, 17, 21, 24, 30, 33, 27, 22, + 21, 20, 23, 24, 21, 15, 13, 8, 3, + 1, -1, -3, -4, -6, -9, -11, -11, -8, + -10, -13, -15, -19, -17, -11, -2, 1, 2, + 6, 9, 10, 12, 13, 9, 8, 10, 13, + 20, 18, 13, 10, 4, 1, -2, -6, -11, + -13, -16, -18, -15, -18, -21, -21, -22, -23, + -25, -23, -22, -20, -19, -16, -12, -10, -9, + -11, -15, -19, -22, -19, -14, -11, -9, -11, + -17, -20, -18, -19, -15, -11, -8, -2, 8, + 19, 30, 36, 37, 36, 38, 45, 57, 69, + 77, 81, 79, 75, 76, 74, 69, 66, 60, + 53, 45, 36, 28, 22, 17, 10, 0, -5, + -11, -15, -18, -26, -31, -33, -34, -34, -35, + -37, -37, -35, -28, -24, -29, -37, -45, -46, + -41, -36, -31, -32, -33, -37, -37, -36, -36, + -34, -27, -19, -14, -11, -8, -1, 6, 14, + 19, 21, 25, 30, 34, 38, 38, 33, 26, + 22, 19, 20, 18, 17, 15, 10, 2, -3, + -5, -10, -13, -13, -13, -16, -16, -16, -15, + -13, -14, -13, -16, -19, -20, -18, -17, -18, + -16, -16, -24, -28, -28, -28, -23, -21, -21, + -20, -24, -27, -23, -18, -14, -7, 4, 11, + 15, 19, 21, 25, 33, 39, 41, 45, 47, + 50, 56, 58, 57, 59, 59, 55, 50, 47, + 39, 34, 30, 24, 18, 11, 8, 3, 0, + -3, -8, -14, -15, -13, -13, -12, -14, -17, + -17, -12, -10, -4, -7, -12, -10, -14, -17, + -17, -19, -25, -28, -27, -29, -30, -31, -35, + -38, -43, -47, -51, -52, -50, -49, -48, -47, + -45, -39, -32, -30, -31, -35, -35, -31, -24, + -17, -12, -11, -14, -15, -17, -16, -9, -5, + -3, -1, 0, 1, 0, 3, 12, 21, 26, + 33, 35, 38, 45, 50, 53, 53, 54, 58, + 61, 64, 69, 67, 66, 64, 58, 54, 51, + 46, 44, 45, 41, 35, 31, 27, 25, 27, + 25, 20, 13, 12, 16, 17, 17, 12, 7, + 3, 2, -2, -4, -8, -14, -19, -25, -29, + -38, -49, -60, -69, -73, -71, -74, -82, -89, + -98, -103, -104, -103, -99, -98, -98, -98, -99, + -97, -94, -91, -85, -82, -78, -74, -74, -71, + -68, -61, -54, -52, -47, -41, -36, -32, -21, + -12, -3, 11, 26, 36, 44, 48, 55, 64, + 77, 92, 100, 108, 117, 120, 122, 128, 130, + 129, 130, 127, 124, 122, 121, 118, 114, 110, + 102, 92, 85, 80, 77, 68, 55, 46, 39, + 36, 34, 31, 27, 15, 5, -1, -5, -11, + -20, -29, -37, -43, -46, -47, -54, -61, -65, + -74, -82, -84, -91, -94, -96, -104, -109, -111, + -111, -112, -113, -111, -112, -110, -104, -99, -96, + -93, -89, -87, -81, -71, -63, -54, -45, -43, + -37, -30, -24, -17, -12, -8, -2, 2, 15, + 23, 28, 35, 41, 42, 44, 52, 58, 66, + 74, 78, 80, 82, 85, 88, 90, 92, 92, + 88, 87, 87, 79, 73, 69, 64, 62, 55, + 50, 45, 41, 36, 29, 24, 20, 16, 12, + 8, 5, 2, 1, 1, 0, 1, -4, -4, + -4, -4, -1, 1, 2, 1, -3, -6, -1, + 5, 6, 7, 8, 4, 2, 0, -2, -3, + 0, -3, -4, -3, -4, -5, -8, -15, -20, + -25, -28, -32, -37, -38, -39, -43, -48, -55, + -62, -69, -75, -75, -78, -81, -83, -89, -89, + -92, -91, -91, -89, -83, -81, -74, -66, -63, + -54, -45, -39, -31, -23, -15, -4, 6, 14, + 23, 29, 35, 41, 45, 49, 55, 61, 69, + 75, 75, 76, 75, 74, 74, 73, 74, 72, + 69, 69, 65, 62, 57, 52, 44, 35, 33, + 29, 24, 14, 7, 3, -4, -12, -17, -20, + -22, -27, -32, -34, -39, -42, -43, -42, -43, + -40, -38, -36, -36, -37, -36, -33, -31, -27, + -24, -23, -22, -17, -11, -7, -7, -7, -3, + 5, 13, 19, 25, 27, 25, 27, 35, 40, + 40, 41, 45, 47, 50, 54, 52, 50, 45, + 43, 44, 40, 34, 28, 24, 18, 11, 6, + -2, -9, -14, -21, -27, -35, -39, -43, -50, + -57, -62, -66, -68, -71, -72, -73, -74, -76, + -76, -77, -75, -75, -74, -67, -61, -55, -49, + -45, -40, -30, -21, -11, -4, 4, 13, 23, + 34, 44, 52, 59, 65, 70, 77, 84, 87, + 88, 90, 91, 90, 89, 85, 80, 75, 72, + 71, 64, 56, 48, 41, 34, 27, 21, 12, + 1, -11, -19, -28, -33, -39, -46, -50, -53, + -58, -63, -66, -71, -73, -76, -76, -74, -73, + -71, -67, -65, -62, -60, -55, -51, -45, -39, + -35, -31, -27, -20, -13, -6, -3, 1, 8, + 12, 18, 24, 26, 30, 35, 38, 44, 47, + 47, 51, 53, 52, 53, 52, 50, 51, 49, + 50, 51, 50, 48, 48, 45, 43, 42, 37, + 34, 31, 31, 30, 26, 24, 21, 15, 12, + 11, 7, 4, 1, -3, -5, -7, -9, -15, + -21, -26, -28, -31, -35, -39, -46, -48, -49, + -53, -58, -63, -67, -69, -71, -72, -74, -75, + -77, -77, -73, -72, -69, -65, -60, -55, -50, + -47, -43, -38, -30, -25, -20, -12, -4, 4, + 9, 16, 20, 24, 28, 35, 43, 50, 58, + 61, 65, 72, 74, 74, 76, 79, 78, 76, + 78, 76, 76, 74, 70, 64, 59, 52, 46, + 41, 33, 26, 19, 12, 5, -2, -8, -15, + -20, -26, -31, -37, -39, -41, -44, -44, -47, + -51, -52, -52, -48, -45, -46, -48, -45, -42, + -40, -36, -32, -27, -24, -22, -18, -16, -11, + -10, -5, 0, 3, 8, 11, 16, 18, 21, + 23, 25, 26, 27, 28, 30, 31, 31, 30, + 29, 27, 26, 23, 19, 17, 13, 10, 6, + 0, -2, -5, -10, -12, -15, -19, -23, -26, + -29, -30, -30, -32, -33, -34, -35, -34, -31, + -29, -29, -28, -28, -23, -19, -17, -12, -12, + -10, -5, -2, 3, 7, 10, 13, 14, 19, + 22, 26, 31, 34, 34, 35, 36, 39, 43, + 45, 47, 47, 48, 49, 51, 48, 47, 50, + 45, 41, 41, 38, 34, 34, 30, 23, 17, + 11, 7, 4, -4, -9, -15, -23, -28, -32, + -35, -39, -45, -46, -49, -53, -52, -53, -55, + -56, -56, -55, -54, -53, -53, -51, -47, -44, + -42, -40, -37, -33, -28, -25, -23, -18, -15, + -8, -6, -2, 3, 8, 15, 18, 23, 26, + 27, 32, 36, 36, 36, 39, 38, 38, 40, + 39, 35, 31, 29, 25, 23, 19, 15, 11, + 7, 5, 3, 1, -1, -6, -8, -7, -10, + -9, -10, -11, -10, -7, -6, -8, -6, -5, + -4, 1, 2, 4, 7, 7, 9, 11, 11, + 9, 9, 10, 11, 13, 17, 15, 15, 15, + 17, 19, 17, 17, 17, 15, 15, 13, 11, + 12, 8, 7, 5, 3, 0, -4, -4, -6, + -9, -12, -14, -15, -15, -16, -20, -19, -20, + -20, -20, -18, -18, -21, -22, -21, -21, -23, + -20, -20, -23, -24, -23, -25, -25, -25, -25, + -26, -24, -23, -23, -23, -23, -22, -19, -18, + -15, -14, -10, -8, -4, -1, 1, 3, 6, + 8, 9, 14, 19, 22, 24, 26, 29, 32, + 31, 34, 39, 42, 42, 46, 49, 50, 50, + 52, 53, 52, 49, 49, 48, 48, 46, 45, + 40, 34, 30, 25, 21, 17, 13, 10, 6, + 2, -4, -9, -12, -15, -18, -21, -26, -28, + -31, -32, -33, -35, -35, -38, -37, -36, -34, + -35, -35, -33, -33, -34, -30, -26, -27, -25, + -23, -22, -18, -15, -16, -12, -9, -9, -6, + -1, 2, 3, 5, 8, 7, 9, 12, 15, + 17, 18, 18, 19, 18, 20, 19, 18, 21, + 20, 19, 18, 16, 15, 15, 15, 14, 12, + 9, 9, 10, 8, 6, 4, 2, 1, -1, + -3, -1, -3, -2, -4, -5, -5, -8, -8, + -10, -10, -8, -8, -8, -7, -8, -8, -8, + -9, -11, -12, -11, -9, -7, -8, -8, -8, + -10, -8, -7, -8, -7, -6, -7, -5, -3, + -3, -3, -3, -2, 0, 3, 3, 5, 7, + 10, 11, 10, 10, 12, 13, 16, 16, 16, + 17, 15, 16, 17, 16, 14, 16, 13, 11, + 11, 9, 9, 6, 4, 4, 3, 0, -2, + -4, -7, -7, -7, -13, -15, -13, -14, -16, + -15, -15, -17, -16, -16, -18, -19, -19, -20, + -19, -16, -15, -13, -12, -10, -7, -6, -4, + -4, -2, 0, 2, 6, 8, 10, 12, 14, + 15, 14, 13, 13, 13, 15, 15, 17, 17, + 17, 18, 17, 16, 15, 15, 14, 11, 9, + 8, 8, 9, 8, 5, 5, 3, -1, -1, + -4, -5, -7, -8, -8, -8, -9, -10, -8, + -11, -12, -12, -12, -12, -13, -11, -11, -9, + -8, -7, -8, -7, -6, -7, -6, -5, -4, + -4, -2, -2, -3, -2, -2, -3, 0, -1, + -3, 1, 1, 2, 4, 3, 5, 6, 3, + 3, 4, 3, 3, 4, 5, 4, 6, 7, + 7, 7, 6, 3, 3, 5, 3, 3, 6, + 6, 7, 6, 4, 5, 2, 1, 1, 0, + 0, 2, 1, 1, 1, -1, -2, -3, -5, + -4, -5, -4, -4, -6, -4, -4, -4, -5, + -6, -5, -6, -5, -4, -5, -4, -3, -4, + 0, 2, 2, 2, 2, 2, 2, 3, 3, + 5, 6, 6, 5, 6, 7, 6, 8, 6, + 5, 5, 5, 6, 6, 6, 5, 5, 2, + 2, 1, 2, 0, -1, -1, -1, -1, 0, + -1, -4, -6, -8, -8, -9, -8, -7, -6, + -5, -5, -6, -3, -4, -5, -4, -7, -6, + -4, -2, -1, -1, 1, 1, 1, 1, 1, + 2, 2, 1, 3, 4, 4, 6, 6, 6, + 6, 4, 4, 4, 4, 3, 2, 2, 2, + 2, 1, 1, 1, 0, 1, 1, 0, -2, + -2, -3, -3, -3, -3, -5, -4, -3, -5, + -5, -3, -5, -4, -4, -2, -2, -2, -1, + -3, -2, -2, -1, -3, -2, -1, -2, -2, + -2, 0, 0, 0, 0, 0, 1, 0, 0, + 1, 2, 3, 3, 3, 4, 5, 4, 3, + 4, 5, 5, 7, 7, 6, 9, 8, 6, + 7, 8, 6, 5, 7, 8, 8, 8, 7, + 6, 5, 4, 4, 4, 5, 4, 2, 1, + 2, 1, 0, -2, -3, -2, -4, -6, -6, + -7, -7, -8, -9, -9, -9, -9, -9, -9, + -9, -10, -10, -10, -8, -7, -8, -6, -5, + -4, -3, -5, -2, -2, -2, -1, -1, 0, + 1, 1, 2, 3, 2, 4, 3, 3, 5, + 3, 3, 5, 4, 5, 6, 5, 4, 5, + 3, 2, 2, 3, 4, 4, 4, 4, 4, + 3, 4, 4, 4, 3, 2, 2, 2, 2, + 2, 2, 2, 2, 1, 1, 1, 2, 1, + 1, 2, 1, 1, 2, 1, 1, 1, -1, + 0, 1, 0, -1, 1, -1, -1, -1, -2, + -1, -1, -1, -1, -1, -1, -1, -1, -2, + -1, 0, -1, -1, 1, 1, 2, 0, -1, + 0, -1, -1, 0, 0, 1, 2, 2, 2, + 1, 1, 0, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, -1, -2, -1, -3, -4, + -4, -4, -4, -4, -4, -4, -3, -3, -5, + -6, -4, -2, -2, -1, -1, -1, -2, 1, + -1, 1, 0, 0, 1, 1, 1, 1, 2, + 1, 2, 2, 3, 3, 3, 3, 4, 5, + 5, 5, 5, 5, 5, 5, 5, 6, 6, + 5, 5, 5, 6, 6, 5, 3, 6, 5, + 4, 5, 3, 2, 2, 2, 2, 1, 1, + 2, 0, -1, 0, -1, -1, -1, -1, -1, + -1, -1, -3, -3, -3, -3, -4, -4, -5, + -6, -6, -6, -6, -6, -6, -5, -5, -6, + -5, -4, -4, -4, -4, -2, -2, -2, -1, + -2, 0, 1, 0, 1, 3, 4, 4, 4, + 4, 4, 4, 5, 4, 4, 4, 5, 7, + 5, 4, 4, 4, 4, 3, 2, 2, 2, + 2, 2, 0, 1, 1, 0, 1, 1, -1, + 0, -1, -2, -1, -3, -4, -4, -3, -5, + -5, -5, -5, -5, -5, -4, -3, -3, -2, + -3, -2, -2, -5, -3, -3, -3, -2, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 3, + 3, 4, 4, 4, 4, 5, 5, 2, 3, + 4, 3, 5, 4, 3, 4, 3, 3, 5, + 5, 3, 4, 2, 1, 1, 3, 4, 3, + 1, 3, 2, 1, 2, 1, 0, 1, 0, + 1, 0, 1, 1, 1, 1, 0, -1, 0, + 0, -1, -1, -2, -1, -1, -2, 0, -1, + -2, -1, -1, -2, -2, -1, -3, -3, -3, + -3, -3, -4, -3, -5, -6, -4, -4, -5, + -4, -3, -5, -6, -4, -5, -6, -4, -3, + -5, -4, -3, -4, -3, -2, -2, -2, 0, + 0, 1, 1, 0, 0, 0, 1, 1, 3, + 3, 3, 4, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, + 1, 1, 1, 1, 1, 1, 1, 0, 0, + 0, 1, -2, -1, 1, 0, -1, -2, -2, + 0, 1, 0, 1, 1, 1, 1, 0, 0, + 1, 0, 0, 2, 1, 0, 1, 1, 1, + 1, 3, 3, 3, 4, 3, 3, 4, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 2, + 2, 2, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -3, -3, -3, -5, -4, -5, -5, + -5, -5, -7, -7, -7, -8, -7, -8, -7, + -8, -8, -7, -8, -8, -8, -8, -7, -6, + -6, -6, -7, -6, -6, -5, -5, -3, -2, + -2, -1, 0, -1, 0, 1, 2, 2, 3, + 3, 3, 6, 7, 7, 7, 8, 9, 8, + 10, 10, 9, 10, 11, 9, 10, 12, 11, + 10, 9, 9, 9, 9, 10, 9, 6, 6, + 5, 5, 6, 3, 1, 1, 0, 1, 0, + 0, 1, -1, -2, -2, -1, -3, -3, -2, + -4, -4, -3, -2, -4, -4, -4, -5, -3, + -3, -5, -3, -3, -5, -4, -2, -2, -3, + -3, -1, 0, -1, 0, 0, 0, -2, -1, + 0, -1, -2, -2, -2, -2, -1, -3, -2, + -3, -4, -3, -3, -3, -3, -3, -3, -3, + -2, -4, -6, -5, -3, -2, -4, -3, -2, + -4, -4, -4, -3, -4, -5, -4, -5, -3, + -2, -5, -2, -4, -4, -3, -2, -1, -1, + -1, 0, 2, 2, 1, 1, 3, 3, 3, + 3, 4, 4, 5, 6, 5, 5, 6, 7, + 7, 7, 8, 8, 7, 9, 9, 9, 9, + 10, 9, 9, 9, 9, 9, 9, 8, 7, + 9, 9, 6, 7, 5, 2, 3, 2, 1, + 1, 0, -2, -2, -2, -3, -3, -2, -2, + -4, -5, -4, -4, -4, -4, -5, -4, -4, + -5, -4, -5, -4, -5, -6, -4, -4, -5, + -5, -5, -5, -6, -4, -4, -4, -3, -2, + -3, -3, -2, -2, -1, -2, -3, -1, 0, + -1, 0, 0, 0, 0, 1, 0, 0, 0, + 0, -1, 1, 1, 1, 0, -2, -2, -3, + -3, -4, -4, -6, -7, -5, -4, -5, -5, + -4, -6, -8, -7, -6, -5, -5, -5, -4, + -4, -5, -4, -3, -3, 0, 0, -2, -1, + 0, 0, 1, 1, 2, 2, 2, 2, 2, + 4, 5, 5, 5, 6, 7, 7, 9, 10, + 10, 10, 12, 12, 13, 14, 14, 14, 15, + 15, 15, 15, 15, 15, 14, 15, 15, 12, + 13, 13, 12, 10, 11, 11, 11, 10, 8, + 6, 5, 7, 6, 6, 4, 3, 4, 5, + 3, 2, 2, 1, 1, 2, 3, 1, 0, + 0, 1, 0, -2, -1, -2, -3, -3, -3, + -3, -4, -6, -8, -9, -9, -10, -12, -14, + -15, -18, -21, -21, -21, -21, -22, -24, -26, + -26, -27, -27, -28, -26, -25, -26, -28, -27, + -24, -23, -23, -24, -21, -17, -17, -15, -12, + -12, -12, -12, -9, -7, -6, -5, -3, -3, + -2, 0, 0, 1, 3, 7, 6, 4, 6, + 7, 8, 11, 10, 10, 13, 15, 14, 13, + 18, 20, 18, 19, 21, 23, 24, 23, 22, + 24, 26, 26, 26, 27, 25, 23, 25, 27, + 28, 28, 28, 23, 19, 23, 24, 20, 20, + 21, 15, 13, 15, 16, 14, 11, 8, 7, + 8, 11, 11, 6, 4, 8, 7, 6, 7, + 6, 4, 7, 13, 12, 7, 8, 8, 4, + 1, 1, 1, 2, -4, -12, -18, -24, -25, + -25, -32, -41, -55, -59, -61, -75, -87, -96, + -109, -122, -133, -141, -148, -157, -168, -180, -191, + -198, -202, -207, -206, -207, -211, -211, -208, -203, + -189, -171, -153, -132, -114, -96, -75, -54, -30, + -5, 19, 43, 61, 77, 93, 106, 123, 143, + 161, 182, 198, 202, 201, 209, 229, 242, 240, + 235, 239, 249, 258, 255, 242, 233, 245, 268, + 278, 256, 223, 223, 253, 263, 235, 198, 178, + 188, 215, 230, 200, 143, 113, 128, 158, 158, + 128, 99, 90, 82, 70, 56, 32, 7, 14, + 46, 36, -23, -71, -76, -54, -36, -39, -74, + -118, -134, -122, -101, -104, -129, -164, -174, -129, + -86, -109, -184, -219, -191, -147, -141, -183, -249, + -290, -269, -236, -266, -346, -394, -366, -325, -353, + -431, -472, -406, -313, -316, -398, -449, -401, -287, + -194, -164, -193, -245, -212, -55, 75, 67, 26, + 67, 165, 237, 269, 293, 319, 333, 368, 414, + 432, 463, 488, 448, 404, 391, 377, 361, 365, + 376, 308, 197, 150, 129, 73, 53, 91, 43, + -107, -165, -54, 1, -148, -312, -273, -125, -62, + -128, -258, -294, -141, 70, 57, -217, -378, -145, + 198, 289, 169, -47, -219, -101, 264, 458, 217, + -163, -199, 13, 121, 101, -51, -293, -319, -62, + 24, -274, -474, -296, -170, -336, -422, -285, -248, + -302, -130, 98, -11, -257, -146, 184, 278, 264, + 331, 192, -35, 235, 805, 830, 315, 82, 322, + 503, 522, 619, 557, 242, 163, 399, 507, 489, + 618, 602, 156, -164, 112, 476, 406, 94, -154, + -242, -132, 56, 5, -325, -566, -527, -478, -624, + -692, -561, -551, -744, -836, -671, -520, -626, -736, + -647, -581, -639, -687, -702, -739, -665, -383, -236, + -414, -513, -321, -114, -43, 32, 65, -98, -236, + 34, 608, 924, 680, 218, 56, 329, 847, 1214, + 1006, 341, 11, 340, 667, 553, 353, 355, 415, + 416, 364, 257, 108, 6, 113, 293, 233, 46, + 4, 25, -10, -12, 55, 40, -65, -56, -26, + -101, -61, 143, 229, 78, -161, -210, 103, 424, + 377, 86, -274, -491, -328, -37, 60, 128, 188, + -105, -625, -823, -464, 138, 389, 111, -343, -526, + -306, 13, 205, 250, -35, -554, -764, -498, -42, + 167, -210, -639, -448, -101, -110, -171, -74, -39, + 47, 424, 616, 324, 98, 367, 853, 942, 416, + -184, -130, 339, 472, 369, 239, -165, -418, 101, + 742, 659, 325, 365, 476, 233, -14, 270, 785, + 719, -29, -533, -220, 237, 305, 179, -190, -644, + -610, -380, -526, -601, -237, 48, -36, -124, -49, + -6, 23, 117, 55, -199, -428, -512, -338, -238, + -424, -323, -135, -464, -657, -189, 100, -379, -964, + -893, -346, -64, -322, -650, -480, 32, 238, 201, + 386, 616, 611, 400, 195, 357, 842, 1051, 832, + 712, 829, 1070, 1307, 1081, 551, 363, 544, 623, + 239, -374, -609, -230, 375, 486, -52, -446, -270, + 181, 645, 601, -135, -654, -256, 567, 840, 380, + -54, 18, 334, 386, 21, -214, 83, 243, -316, + -937, -1074, -1006, -896, -674, -424, -331, -354, -380, + -481, -392, 80, 358, 171, -170, -624, -796, -130, + 706, 803, 381, 152, 367, 620, 685, 655, 347, + 36, 180, 417, 412, 358, 288, 189, 150, 16, + -240, -428, -428, -266, -335, -819, -1150, -946, -587, + -437, -580, -961, -1218, -1065, -704, -431, -350, -315, + -214, -162, -81, 26, -8, -52, -117, -226, -40, + 285, 241, -2, -69, 57, 207, 81, -144, -69, + 65, 84, 49, -168, -248, 126, 502, 472, 192, + 120, 442, 667, 551, 512, 634, 814, 1014, 1098, + 1156, 1112, 974, 1144, 1330, 1099, 825, 847, 877, + 555, 2, -243, -102, -196, -471, -377, -235, -439, + -622, -547, -470, -495, -431, -197, -21, 21, -9, + -246, -438, -238, -31, 0, 96, 137, -25, -211, + -181, -149, -350, -368, -33, 21, -308, -323, 32, + 379, 605, 531, 85, -374, -367, 9, 277, 147, + -356, -698, -494, -140, -126, -354, -549, -673, -642, + -428, -269, -273, -246, -216, -349, -323, -16, 32, + -387, -742, -662, -434, -223, 41, 140, -58, -227, + -80, 93, 20, -166, -360, -536, -555, -305, -33, + -23, -86, -75, -9, 82, -1, -156, 24, 532, + 916, 956, 835, 901, 1127, 1279, 1417, 1435, 1144, + 822, 862, 1214, 1352, 1001, 611, 539, 532, 369, + 189, 170, 308, 465, 430, 232, 64, 14, 51, + -37, -244, -321, -276, -144, 57, 77, -215, -467, + -335, -186, -245, -133, -81, -588, -1130, -959, -520, + -631, -1122, -1270, -971, -873, -1118, -1157, -1078, -1296, + -1365, -1010, -873, -1138, -1061, -379, 89, 51, 177, + 372, 185, -14, 63, 197, 125, -123, -60, 243, + 195, 88, 201, 115, -63, -12, -79, -492, -751, + -489, 49, 163, -293, -424, -52, 229, 302, 212, + 217, 315, 70, -207, -210, -173, 129, 619, 556, + 213, 181, 170, 112, 167, 322, 451, 206, -136, + 58, 426, 526, 524, 394, 387, 568, 481, 297, + 164, 8, 263, 664, 777, 943, 989, 934, 1283, + 1495, 1153, 861, 738, 582, 614, 692, 655, 629, + 432, 127, -119, -338, -313, -138, -204, -561, -994, + -1168, -948, -700, -658, -788, -1053, -1027, -684, -566, + -528, -355, -335, -323, -28, 206, 87, 56, 387, + 585, 296, 24, 261, 492, 248, -132, -469, -674, + -502, -235, -255, -517, -847, -1038, -965, -707, -630, + -767, -639, -298, -193, -290, -310, -118, 74, -77, + -337, -324, -120, 187, 323, -72, -552, -454, -14, + 29, -427, -803, -735, -586, -762, -918, -783, -649, + -723, -857, -786, -626, -591, -417, -83, 167, 262, + 49, -161, 157, 842, 1298, 1356, 1206, 1041, 1194, + 1461, 1323, 1070, 1221, 1687, 2051, 2002, 1673, 1464, + 1550, 1851, 1907, 1531, 1327, 1399, 1342, 1287, 1264, + 1152, 1030, 878, 716, 601, 454, 264, 264, 352, + 151, -193, -296, -161, -93, -215, -423, -617, -668, + -547, -416, -464, -807, -1175, -1174, -1045, -1076, -1023, + -829, -710, -745, -1069, -1443, -1417, -1099, -939, -1165, + -1307, -1056, -843, -638, -304, -190, -334, -578, -770, + -705, -675, -947, -957, -565, -437, -617, -843, -1015, + -813, -489, -584, -904, -1054, -797, -229, -26, -208, + -66, 398, 710, 644, 390, 413, 726, 992, 1204, + 1337, 1234, 1104, 1038, 1001, 1043, 982, 847, 885, + 1024, 1098, 1138, 1108, 1038, 966, 885, 882, 878, + 929, 1005, 944, 1008, 1284, 1415, 1289, 1007, 760, + 812, 947, 806, 455, 111, -72, -290, -611, -626, + -559, -765, -1034, -1375, -1632, -1565, -1588, -1728, -1585, + -1477, -1547, -1533, -1371, -1103, -995, -1090, -1102, -947, + -686, -403, -295, -250, -107, -86, -171, -150, 12, + 234, 283, 185, 300, 461, 393, 382, 434, 378, + 306, 202, 195, 253, -8, -307, -105, 264, 342, + 212, 34, -57, 78, 435, 571, 180, -165, -51, + 339, 705, 683, 464, 658, 958, 825, 579, 465, + 390, 241, 61, 202, 429, 128, -122, 241, 406, + 39, -167, -60, 15, -31, -68, 146, 402, 344, + 227, 208, 87, -25, -31, -66, -169, -249, -87, + 75, -181, -438, -249, 49, 87, -40, -16, 53, + -86, -74, 98, 78, 110, 169, -84, -323, -251, + -102, -172, -513, -750, -675, -568, -587, -583, -523, + -450, -302, -245, -356, -480, -590, -495, -183, -105, + -191, -215, -308, -206, 39, 4, -77, -21, 74, + 186, 218, 356, 611, 489, 83, 13, 246, 371, + 348, 240, 61, -66, -107, -170, -205, -74, 200, + 277, 45, -11, 180, 263, 100, -74, 102, 246, + 6, -154, -162, -197, -128, -189, -227, -49, -238, + -490, -333, -188, 1, 215, 150, 144, 128, -33, + 187, 532, 676, 911, 773, 283, 351, 673, 620, + 349, 105, 205, 425, 325, 295, 372, 340, 511, + 628, 394, 224, 187, 91, -174, -556, -482, -37, + -9, -226, -382, -568, -466, -208, -241, -426, -656, + -814, -788, -902, -1065, -946, -860, -896, -831, -744, + -672, -685, -743, -723, -783, -813, -570, -341, -239, + -57, 137, 348, 576, 593, 454, 429, 503, 449, + 238, 173, 350, 423, 419, 530, 501, 272, 156, + 207, 295, 404, 568, 676, 419, 30, 113, 463, + 550, 473, 349, 126, 33, 144, 207, 193, 267, + 304, 81, -252, -401, -368, -347, -404, -452, -408, + -272, -40, 234, 281, 48, -72, -18, 54, 208, + 309, 285, 245, 164, 38, -20, 148, 430, 563, + 655, 679, 453, 300, 319, 219, 25, -15, 54, + -117, -444, -431, -135, -147, -468, -667, -722, -593, + -301, -217, -428, -642, -598, -400, -422, -602, -628, + -554, -509, -501, -541, -488, -250, -129, -284, -441, + -358, -161, -82, 4, 134, 157, 290, 516, 582, + 702, 859, 871, 858, 759, 615, 616, 754, 839, + 725, 464, 259, 187, 127, 150, 280, 238, 92, + 78, 5, -86, 6, 67, -14, -92, -143, -211, + -89, 213, 300, 107, -91, -154, -153, -238, -355, + -314, -227, -168, -92, -142, -219, -156, -47, 53, + -15, -195, -161, -186, -382, -395, -297, -238, -240, + -390, -502, -336, -97, -29, -116, -290, -289, -67, + 74, 112, 119, 182, 358, 382, 315, 341, 290, + 218, 190, 101, -51, -168, -132, -41, -39, -15, + 104, 186, 151, 68, 89, 154, 67, 10, 143, + 120, -185, -382, -365, -263, -145, -111, -159, -190, + -53, 151, 177, 179, 384, 553, 502, 490, 572, + 600, 573, 442, 119, -212, -260, -166, -318, -506, + -413, -279, -285, -354, -390, -278, -142, -85, -18, + -19, -121, -143, -32, 88, 118, 42, -96, -187, + -167, -113, -172, -270, -256, -178, -192, -249, -128, + 103, 132, -47, -147, -104, -56, -9, 45, 35, + 109, 315, 381, 326, 336, 457, 667, 786, 675, + 489, 460, 569, 595, 470, 303, 272, 448, 620, + 545, 226, -92, -128, 91, 172, -98, -385, -378, + -264, -284, -362, -314, -148, -72, -198, -350, -353, + -344, -389, -353, -292, -327, -413, -473, -519, -588, + -577, -546, -737, -989, -1030, -997, -1010, -861, -683, + -731, -690, -419, -197, -47, 112, 167, 74, 41, + 176, 309, 438, 671, 781, 793, 868, 904, 991, + 1099, 987, 812, 816, 869, 766, 605, 633, 728, + 592, 424, 460, 405, 170, 75, 30, -105, -58, + 63, -58, -242, -359, -415, -255, -44, -127, -266, + -191, -187, -296, -273, -260, -341, -345, -324, -384, + -467, -421, -233, -125, -227, -341, -256, -168, -217, + -249, -302, -447, -425, -274, -289, -299, -229, -275, + -272, -103, -57, -117, -106, -162, -256, -184, -31, + 51, 69, 31, -19, 72, 256, 318, 331, 254, + 28, -7, 121, 48, -64, 58, 183, 152, 161, + 201, 167, 190, 287, 278, 157, 56, 103, 332, + 460, 299, 166, 238, 308, 374, 508, 509, 373, + 275, 270, 298, 229, 185, 192, 23, -160, -80, + 67, 31, -170, -378, -384, -330, -500, -648, -615, + -686, -716, -510, -510, -771, -752, -475, -434, -556, + -480, -403, -515, -464, -255, -177, -105, 29, 95, + 152, 210, 190, 180, 279, 408, 325, 225, 462, + 607, 537, 759, 1022, 973, 945, 964, 846, 818, + 952, 907, 584, 313, 302, 428, 533, 479, 260, + 178, 262, 185, 18, -77, -263, -370, -208, -240, + -589, -739, -572, -444, -405, -357, -475, -738, -771, + -542, -441, -529, -651, -803, -823, -556, -285, -227, + -233, -202, -168, -110, -78, -220, -302, -56, 129, + -60, -149, 54, 130, 169, 324, 231, 24, 89, + 269, 320, 262, 231, 225, 138, 67, 153, 310, + 399, 269, -21, -197, -183, -59, 144, 234, -13, + -274, -168, 32, -37, -277, -417, -441, -416, -324, + -312, -467, -540, -373, -166, -161, -297, -365, -341, + -246, -69, 81, 99, -3, 11, 305, 540, 449, + 394, 586, 667, 606, 685, 665, 425, 410, 585, + 509, 360, 424, 538, 583, 482, 250, 159, 310, + 423, 217, -131, -280, -204, -51, -12, -204, -338, + -232, -143, -201, -306, -374, -336, -229, -257, -453, + -576, -497, -379, -326, -302, -372, -504, -453, -229, + -133, -226, -328, -326, -261, -151, -6, 97, 143, + 164, 143, 138, 267, 433, 500, 470, 297, 143, + 279, 504, 556, 475, 333, 233, 225, 228, 198, + 128, 24, -17, 4, -55, -187, -251, -213, -119, + -94, -214, -357, -349, -246, -195, -183, -261, -440, + -533, -476, -341, -213, -170, -220, -299, -220, -8, + 51, -11, 19, 172, 292, 189, 9, -6, 102, + 238, 384, 477, 448, 353, 304, 354, 473, 543, + 400, 229, 275, 380, 425, 415, 371, 398, 460, + 377, 202, 154, 199, 110, -123, -365, -524, -524, + -360, -134, -47, -182, -348, -453, -542, -503, -376, + -398, -521, -595, -621, -560, -439, -284, -115, -80, + -123, -57, 28, -15, -60, -9, 47, 119, 203, + 288, 435, 571, 635, 706, 750, 627, 436, 345, + 330, 398, 460, 368, 213, 127, 140, 215, 202, + 58, -99, -244, -387, -470, -527, -637, -754, -791, + -768, -742, -739, -735, -704, -649, -552, -479, -491, + -494, -454, -433, -422, -398, -315, -115, 75, 175, + 244, 307, 360, 398, 460, 532, 529, 446, 422, + 497, 541, 504, 541, 702, 803, 744, 645, 621, + 727, 877, 873, 734, 593, 513, 523, 516, 412, + 336, 334, 274, 199, 163, 123, 125, 117, 107, + 140, 72, -73, -114, -68, -15, 13, -122, -338, + -367, -325, -386, -497, -608, -634, -546, -477, -427, + -377, -412, -464, -436, -343, -276, -327, -390, -313, + -149, -17, 2, -93, -146, -104, -76, -87, -131, + -224, -280, -194, -46, 12, -76, -189, -151, 18, + 160, 200, 99, -81, -149, -95, -31, -6, -45, + -93, -97, -71, 0, 73, 34, -82, -129, -102, + -84, -96, -107, -69, -5, 6, 18, 48, 35, + 27, 32, -4, -71, -30, 119, 205, 266, 352, + 325, 237, 282, 352, 358, 342, 265, 203, 200, + 159, 120, 159, 195, 185, 133, 37, 20, 152, + 312, 363, 316, 255, 251, 259, 211, 160, 86, + -4, -30, -79, -154, -213, -271, -243, -146, -147, + -211, -283, -319, -219, -157, -207, -237, -252, -245, + -136, 0, 42, -22, -108, -82, 34, 130, 179, + 152, 98, 105, 110, 116, 180, 175, 66, -9, + -9, 36, 82, 75, 12, -39, -14, 23, 1, + 12, 31, -61, -155, -184, -158, -86, -60, -67, + -63, -84, -100, -81, -115, -171, -157, -150, -179, + -191, -209, -245, -217, -128, -54, -42, -73, -100, + -88, -10, 104, 199, 249, 227, 201, 204, 151, + 83, 75, 87, 84, 67, 34, 18, 44, 110, + 218, 275, 232, 190, 209, 263, 294, 256, 174, + 108, 37, -54, -110, -129, -179, -293, -360, -339, + -282, -190, -135, -188, -239, -234, -227, -182, -127, + -89, -51, -73, -136, -151, -85, 0, 72, 129, + 122, 65, 44, 103, 202, 272, 252, 170, 148, + 167, 152, 130, 127, 79, 14, 70, 157, 142, + 109, 70, -25, -57, -6, 46, 98, 135, 135, + 82, 16, 10, 68, 87, -20, -120, -116, -98, + -102, -129, -204, -271, -282, -252, -216, -215, -221, + -156, -70, -66, -120, -156, -146, -126, -84, -15, + -21, -76, -8, 131, 146, 86, 42, 12, 44, + 110, 169, 171, 91, 68, 173, 262, 248, 160, + 36, -90, -109, -24, -12, -57, -64, -78, -89, + -75, -87, -101, -82, -72, -76, -81, -63, -34, + -4, 61, 87, 46, 23, -1, -8, 40, 63, + 46, 45, 39, 14, -11, -25, -16, 36, 78, + 85, 110, 120, 132, 189, 228, 217, 154, 89, + 57, 14, -14, -6, 0, 13, 8, -50, -68, + -60, -107, -140, -126, -122, -151, -147, -118, -105, + -85, -83, -100, -139, -195, -194, -168, -183, -173, + -148, -166, -168, -123, -59, -11, 20, 64, 98, + 80, 58, 83, 111, 143, 176, 171, 152, 146, + 165, 174, 143, 93, 30, 5, 21, 42, 35, + -37, -94, -61, -12, -5, -27, -58, -85, -81, + -11, 79, 65, -14, -17, 15, -4, -2, 39, + 20, -29, -19, 3, -11, -39, -62, -43, -34, + -60, -77, -119, -163, -128, -5, 87, 73, 51, + 116, 189, 217, 240, 234, 177, 192, 295, 344, + 313, 263, 236, 240, 230, 179, 99, 19, -25, + -16, -9, -35, -66, -53, -16, -40, -70, -81, + -102, -86, -87, -156, -225, -228, -145, -52, -22, + -57, -171, -255, -247, -208, -165, -187, -242, -275, + -261, -168, -75, -13, 8, -62, -125, -136, -133, + -81, -11, -17, -80, -115, -103, -27, 71, 134, + 137, 44, -48, -24, 69, 156, 194, 175, 112, + 55, 54, 101, 148, 157, 142, 100, 44, 27, + 63, 106, 107, 89, 67, 37, 17, 30, 63, + 69, 61, 21, -37, -55, -72, -53, -26, -53, + -77, -87, -109, -119, -80, -36, -29, -38, -48, + -57, -65, -16, 52, 83, 83, 24, -27, -14, + 9, 27, 52, 50, 45, 90, 132, 117, 75, + 16, -1, 60, 95, 55, 25, 26, 20, 61, + 119, 89, 1, -61, -68, -46, -36, -40, -39, + -49, -58, -16, 30, 13, -12, 18, 35, 6, + 3, 30, 22, 25, 52, 32, 12, 9, -5, + -16, -25, -33, -38, -44, -76, -118, -118, -96, + -54, -3, 9, -31, -82, -84, -35, 18, 25, + -26, -72, -48, 8, 25, 8, -20, -66, -105, + -102, -80, -73, -79, -80, -70, -59, -55, -82, + -113, -85, -51, -59, -57, -38, -13, -7, -18, + -6, 20, 51, 55, 18, -8, -7, 24, 78, + 119, 137, 135, 139, 153, 144, 155, 179, 166, + 128, 56, 8, 38, 85, 94, 72, 20, -32, + -9, 25, 17, -15, -84, -123, -106, -82, -62, + -60, -43, -4, -12, -45, -68, -108, -100, -47, + -49, -64, -50, -9, 37, 59, 68, 62, 53, + 49, 25, 13, 32, 40, 60, 109, 82, 18, + 10, -1, 21, 102, 111, 40, -10, -9, 20, + 31, 0, -51, -108, -135, -89, -21, 1, -54, + -125, -129, -113, -144, -205, -227, -167, -118, -114, + -100, -71, 5, 34, -51, -119, -120, -72, 10, + 56, 51, 58, 65, 98, 135, 84, 20, -3, + -1, 57, 135, 137, 90, 88, 107, 102, 45, + -4, 9, 48, 95, 99, 65, 42, 44, 78, + 80, 29, 11, 39, 27, 0, 7, 19, 10, + -45, -99, -86, -77, -74, -57, -74, -84, -92, + -134, -114, -65, -73, -76, -96, -105, -50, -31, + -17, 17, 9, 18, 62, 75, 55, 63, 76, + 61, 61, 80, 103, 107, 110, 131, 134, 120, + 94, 66, 70, 78, 59, 52, 57, 53, 72, + 76, 31, -18, -53, -57, -35, -17, -9, -27, + -34, -7, -17, -26, -13, -60, -86, -53, -42, + -36, -36, -46, -13, 19, -16, -47, -15, 11, + -9, -18, -26, -24, 14, 8, -53, -54, 15, + 43, 15, -9, -5, 5, -12, -40, -57, -74, + -94, -105, -91, -20, 30, -10, -50, -58, -52, + -42, -47, -54, -61, -83, -64, -30, -3, 31, + 9, -35, -43, -31, 6, 50, 54, 55, 67, + 53, 43, 30, 27, 62, 37, -26, -52, -54, + -29, 3, -12, -23, 11, 26, 23, 31, 57, + 66, 46, 32, 35, 83, 124, 111, 124, 157, + 143, 101, 80, 60, 27, 11, 21, 22, 9, + -4, -26, -41, -35, -50, -103, -138, -116, -90, + -89, -90, -79, -74, -58, -18, -12, -29, -36, + -17, 22, 30, -1, -8, 8, 10, 19, 31, + 36, 38, 41, 28, -7, -14, -6, -20, -30, + -11, -2, -9, 0, 25, 56, 78, 68, 40, + 34, 47, 50, 40, 37, 26, 28, 53, 61, + 57, 25, -35, -75, -65, -48, -65, -81, -67, + -53, -41, 3, 19, -3, -9, -2, -1, -24, + -36, -23, -26, -29, -9, 0, -15, -17, -9, + 12, 50, 45, 14, 19, 37, 24, 9, 16, + 13, -16, -19, 3, -3, -12, -10, -23, -43, + -47, -38, -46, -44, -7, 3, -19, -13, -26, + -52, -29, -19, -32, 0, 11, -26, -24, -20, + -41, -30, -24, -53, -67, -26, 23, 20, 9, + 6, -8, 3, 16, 7, 3, -5, 2, 33, + 53, 72, 94, 86, 69, 96, 118, 95, 91, + 78, 32, 26, 48, 48, 37, 21, 7, -6, + -8, 8, 1, -17, -2, 18, 1, -28, -51, + -84, -93, -74, -46, -18, -19, -31, -10, 10, + 10, 7, -5, -30, -39, -28, -9, 10, 17, + 11, 14, 20, -1, 2, 18, 7, 15, 40, + 40, 32, 27, 23, 31, 43, 33, 7, -3, + 18, 51, 53, 31, 21, 14, 16, 14, 4, + 11, 16, 1, -24, -38, -33, -27, -50, -74, + -70, -60, -54, -44, -22, -22, -43, -33, -16, + -35, -36, -18, -27, -42, -46, -36, -17, -15, + -22, -21, -20, -2, 15, 12, 22, 27, 22, + 41, 57, 60, 63, 54, 56, 65, 62, 68, + 58, 34, 53, 70, 58, 60, 51, 33, 41, + 39, 16, -3, -16, -18, -15, -18, -32, -76, + -85, -62, -82, -87, -68, -84, -75, -40, -48, + -55, -45, -42, -24, -14, -1, 27, 23, -1, + -2, 12, 15, 32, 55, 52, 55, 82, 81, + 58, 62, 59, 37, 24, 20, 17, 18, 19, + 15, 14, 5, -18, -27, -20, -19, -34, -39, + -29, -30, -27, -27, -48, -52, -54, -77, -48, + -18, -36, -34, -13, -21, -38, -28, -15, -7, + -6, -20, -18, 2, 4, -11, -5, 7, 1, + 1, 12, -2, -17, 7, 15, 2, 15, 34, + 48, 78, 94, 82, 66, 66, 64, 47, 44, + 57, 64, 74, 65, 34, 26, 31, 32, 33, + 18, 5, -1, -18, -22, -31, -54, -37, -32, + -74, -89, -77, -73, -65, -72, -75, -39, -21, + -31, -31, -24, -19, -8, -4, 7, 26, 22, + 15, 13, 11, 28, 47, 42, 35, 28, 5, + 18, 55, 55, 45, 44, 18, 9, 18, -2, + -5, 6, -15, -16, -12, -20, -4, 4, -15, + -18, -10, -5, -2, -16, -24, -14, -7, -14, + -33, -33, -20, -17, -17, -18, -30, -37, -35, + -34, -13, -3, -28, -28, -10, -21, -17, -4, + -12, -16, -20, -27, -16, -8, -4, 14, 24, + 11, 17, 30, 27, 14, 7, 28, 30, 22, + 45, 47, 23, 31, 23, -5, 10, 17, -5, + 2, 15, 9, 20, 29, 11, -9, -8, 8, + 10, -1, -14, -30, -30, -8, -9, -20, -17, + -17, -12, 1, 6, -7, -18, -6, 10, -6, + -7, 29, 35, 21, 16, 9, 25, 44, 26, + 21, 34, 28, 40, 41, 9, -2, 1, 12, + 34, 18, -12, -10, -16, -29, -24, -25, -20, + -17, -35, -29, -12, -29, -39, -32, -30, -17, + -12, -28, -20, -5, -4, 7, 14, 10, 3, + -3, 0, 19, 27, 4, -21, -18, -7, -4, + 0, 1, -6, -17, -30, -24, -11, -9, 0, + -1, 0, -3, -12, 1, 15, -2, 3, 16, + -3, -8, 7, 3, 13, 32, 23, 10, -6, + -11, 8, 4, -12, -9, 3, 12, -2, -31, + -36, -33, -37, -17, -5, -20, -14, 4, 5, + 4, 6, 17, 31, 27, 23, 16, -1, -4, + 15, 24, 21, 18, 7, -7, -14, 18, 41, + 25, 14, 13, 2, 5, 12, 8, 15, 10, + 2, 13, 10, 3, 5, -1, 0, 11, 10, + 6, 2, 7, 10, -4, -3, 2, -13, -4, + 14, -4, -17, -11, -4, 8, 3, -8, -1, + -7, -20, -4, 23, 23, 8, 5, 24, 21, + -5, -2, 7, -9, -15, -8, -6, 6, 2, + -26, -19, 1, -19, -31, -27, -34, -41, -47, + -39, -12, -12, -29, -32, -41, -36, -26, -36, + -35, -33, -29, -1, 5, -13, -21, -21, -3, + 12, 1, -7, -1, 2, 12, 9, -1, 15, + 21, 18, 25, 4, -13, 5, 12, 16, 33, + 33, 19, 21, 26, 30, 30, 24, 23, 19, + 22, 34, 39, 28, 15, 14, 24, 24, 18, + 12, 10, 4, 8, 28, 29, 2, -7, 6, + 8, 10, 2, -13, -8, -2, 0, 12, 13, + -1, 3, 21, 26, 24, 17, 11, 15, 19, + 19, 19, 11, 1, 3, 3, 0, -5, -11, + -16, -26, -18, 3, -5, -17, 2, 10, 6, + 6, -8, -11, 4, -3, -17, -10, -17, -37, + -31, -17, -26, -37, -42, -53, -49, -34, -40, + -39, -21, -17, -23, -23, -25, -30, -24, -13, + -10, -10, 1, 1, -7, 7, 19, 11, 4, + -3, -8, 1, 6, 7, 25, 22, -5, 3, + 20, 7, -1, 14, 17, 18, 20, 12, 25, + 41, 23, 19, 37, 39, 21, 17, 23, 17, + 6, 9, 15, 4, -15, -8, 8, 7, 1, + -12, -18, -14, -15, -10, 0, -3, 3, 13, + -8, -21, -8, -26, -29, -1, -9, -24, -19, + -22, -24, -18, -25, -27, -28, -34, -26, -9, + -14, -14, -8, -8, -5, 4, 4, -10, -12, + -7, -8, -10, -15, -19, -10, -5, -9, -9, + -19, -33, -27, -14, -15, -14, -16, -25, -10, + 5, -7, -11, 2, 3, 7, 17, 28, 33, + 32, 33, 39, 49, 57, 63, 62, 64, 67, + 59, 55, 67, 71, 58, 53, 53, 44, 38, + 44, 51, 51, 45, 35, 34, 46, 55, 48, + 36, 21, 3, -5, 2, 7, 0, -17, -30, + -34, -48, -62, -64, -66, -66, -62, -79, -90, + -85, -88, -88, -85, -88, -103, -112, -112, -102, + -99, -102, -103, -110, -100, -80, -60, -57, -68, + -59, -45, -35, -6, 9, -3, 2, 32, 45, + 48, 51, 40, 51, 78, 85, 83, 87, 94, + 101, 104, 105, 100, 86, 82, 96, 102, 96, + 85, 68, 63, 65, 55, 50, 46, 28, 32, + 43, 33, 30, 27, 8, 18, 36, 27, 20, + 13, -14, -19, 8, 12, 0, -1, -12, -24, + -20, -27, -39, -39, -39, -44, -38, -32, -42, + -38, -33, -43, -55, -57, -60, -61, -56, -57, + -55, -43, -46, -58, -55, -50, -50, -51, -48, + -46, -44, -36, -26, -20, -13, -11, -8, 1, + 5, 0, 8, 21, 31, 42, 39, 43, 56, + 48, 37, 45, 45, 47, 52, 46, 40, 26, + 18, 28, 30, 22, 14, 0, -3, 8, 0, + -7, 0, -10, -13, -9, -13, -13, -18, -33, + -32, -26, -37, -41, -32, -26, -30, -34, -31, + -38, -40, -24, -25, -29, -15, -18, -23, -4, + 2, -7, 0, 5, 10, 22, 23, 25, 31, + 33, 37, 38, 39, 43, 46, 41, 44, 46, + 37, 35, 46, 63, 67, 52, 38, 30, 35, + 41, 41, 41, 29, 15, 16, 4, -4, 3, + -12, -18, -13, -27, -39, -47, -55, -44, -43, + -53, -45, -36, -37, -37, -38, -40, -49, -57, + -41, -24, -28, -31, -26, -20, -15, -21, -23, + -18, -19, -14, -10, -11, 1, -6, -26, -14, + -1, -7, -10, -11, -9, 0, -4, -9, 3, + 8, 0, -2, 1, 16, 20, 7, 9, 10, + 8, 18, 12, 11, 17, -6, -19, 0, 0, + -10, -6, -12, -14, -11, -9, -2, -10, -19, + -9, -11, -4, 18, 7, -3, 9, 17, 23, + 28, 25, 19, 19, 24, 33, 37, 30, 28, + 35, 44, 43, 33, 31, 30, 26, 33, 39, + 35, 31, 27, 19, 23, 24, 19, 13, 0, + 0, 2, -7, -9, -10, -13, -6, -6, -23, + -28, -15, -9, -20, -34, -30, -15, -12, -11, + -3, -4, -4, 6, 15, 9, -11, -20, 3, + 26, 23, 1, -16, -3, 12, 2, -22, -36, + -35, -28, -20, -13, -19, -38, -43, -29, -11, + -5, -15, -37, -40, -9, 12, -1, -23, -30, + -16, 12, 21, -1, -25, -21, 4, 34, 55, + 34, -12, -11, 47, 99, 107, 58, 0, 8, + 78, 148, 151, 56, -40, -2, 142, 215, 99, + -67, -64, 76, 153, 99, -21, -107, -92, -1, + 106, 107, -123, -395, -334, 60, 274, -69, -597, + -626, -126, 238, 18, -447, -577, -312, -34, 20, + -89, -242, -332, -222, 74, 262, 64, -285, -232, + 259, 563, 294, -138, -130, 312, 642, 515, 189, + 57, 187, 415, 538, 467, 277, 109, 134, 334, + 441, 299, 59, -7, 128, 228, 146, -20, -99, + -34, 60, 24, -108, -188, -147, -57, -48, -142, + -224, -210, -144, -122, -175, -212, -176, -150, -199, + -256, -210, -100, -79, -195, -298, -248, -107, -48, + -110, -192, -224, -189, -112, -40, -31, -124, -238, + -193, -3, 87, -53, -221, -165, 48, 132, -2, + -150, -109, 61, 147, 83, -20, -60, -13, 85, + 157, 130, 17, -68, -10, 147, 217, 116, -20, + -21, 103, 200, 158, 52, 35, 105, 155, 132, + 81, 74, 110, 114, 74, 48, 68, 100, 77, + 27, 30, 48, 19, -15, 7, 63, 53, -56, + -123, -41, 81, 75, -61, -154, -84, 45, 68, + -24, -105, -76, 22, 53, -13, -63, -21, 54, + 59, -1, -34, 16, 80, 81, 48, 37, 61, + 89, 88, 101, 134, 132, 100, 83, 125, 188, + 173, 101, 95, 172, 214, 149, 68, 94, 181, + 177, 103, 83, 132, 165, 122, 83, 140, 191, + 153, 92, 106, 198, 226, 138, 85, 146, 215, + 187, 110, 77, 115, 146, 115, 91, 96, 78, + 27, -3, 42, 102, 71, -23, -46, 30, 95, + 63, -18, -25, 77, 174, 138, 13, -25, 96, + 218, 181, 34, -70, -45, 17, 2, -67, -174, + -346, -516, -553, -446, -455, -789, -1213, -1308, -1046, + -878, -1179, -1691, -1839, -1528, -1219, -1292, -1623, -1772, + -1538, -1147, -921, -951, -1038, -929, -549, -95, 155, + 127, 97, 387, 931, 1339, 1380, 1234, 1276, 1661, + 2102, 2223, 2027, 1848, 1942, 2198, 2295, 2119, 1856, + 1725, 1745, 1752, 1601, 1335, 1102, 993, 952, 830, + 570, 286, 139, 133, 85, -135, -436, -638, -645, + -571, -620, -835, -1064, -1151, -1069, -951, -964, -1109, + -1209, -1162, -1044, -961, -944, -977, -1001, -912, -687, + -517, -623, -887, -897, -469, 10, -35, -590, -934, + -545, 184, 427, -53, -619, -563, 40, 489, 339, + -128, -306, -6, 403, 497, 232, -55, 0, 388, + 704, 584, 145, -76, 260, 816, 942, 485, 2, + 65, 575, 923, 744, 290, 76, 276, 596, 662, + 419, 134, 92, 280, 434, 344, 88, -66, 8, + 151, 126, -81, -239, -176, -29, -74, -351, -574, + -487, -208, -132, -426, -780, -797, -577, -595, -978, + -1169, -667, -36, -548, -2285, -3281, -1756, 927, 1236, + -1911, -5006, -4073, -66, 2017, -295, -3701, -3797, -892, + 975, -165, -1978, -1636, 374, 1482, 679, -567, -591, + 706, 2337, 3224, 2743, 1269, 287, 1221, 3597, 5083, + 4106, 1858, 972, 2334, 4096, 4167, 2806, 1916, 2383, + 3045, 2508, 1220, 820, 1784, 2669, 1981, 204, -876, + -470, 510, 803, 170, -787, -1568, -1893, -1598, -1027, + -992, -1803, -2610, -2484, -1905, -2113, -3113, -3399, -2267, + -1261, -2007, -3637, -3909, -2340, -893, -1158, -2272, -2486, + -1639, -915, -777, -596, -91, 196, 85, 210, 875, + 1373, 1247, 1219, 1958, 2718, 2328, 1196, 1008, 2350, + 3677, 3269, 1503, 366, 922, 2264, 2810, 1996, 608, + -168, 75, 680, 811, 395, -56, -318, -607, -966, + -1108, -925, -613, -368, -369, -919, -1926, -2460, -1685, + -300, 155, -611, -1524, -2204, -3227, -3859, -2037, 1622, + 2382, -2583, -8448, -7544, -84, 4814, 915, -6423, -7558, + -1746, 2515, -59, -4587, -3858, 1260, 3625, 187, -4148, + -3500, 1542, 5467, 4780, 1256, -1127, -403, 2481, 5332, + 6346, 5014, 2536, 1216, 2467, 5039, 6238, 5070, 3381, + 3269, 4173, 3905, 2248, 1586, 3299, 5240, 4362, 1004, + -1382, -489, 2113, 3168, 1620, -742, -1824, -1435, -897, + -1058, -1500, -1545, -1398, -1965, -3266, -4136, -3756, -2609, + -1804, -1986, -3087, -4599, -5296, -4051, -1731, -781, -2228, + -4092, -3977, -2325, -1353, -1568, -1490, -428, 178, -672, + -1650, -1058, 749, 2039, 2079, 1540, 897, 310, 572, + 2266, 4265, 4265, 1869, -231, 559, 3332, 4752, 3229, + 768, 101, 1364, 2463, 1984, 819, 411, 723, 675, + -162, -923, -743, -32, 185, -516, -1653, -2359, -2103, + -986, 42, -205, -1702, -2870, -2337, -809, -221, -982, + -1544, -946, -598, -2117, -4291, -4100, -857, 1948, 338, + -4799, -7972, -5403, 173, 2371, -1063, -5533, -5578, -1777, + 605, -985, -3249, -2213, 1184, 2691, 560, -2356, -2288, + 1233, 5244, 6441, 4004, 370, -663, 2555, 7404, 9282, + 6573, 2612, 1836, 4662, 7467, 7393, 5421, 4262, 4741, + 5362, 4705, 3163, 2397, 3337, 4887, 4810, 2254, -749, + -1316, 772, 2706, 2016, -573, -2552, -2746, -2012, -1647, + -1978, -2579, -3105, -3473, -3911, -4484, -4891, -4795, -4163, + -3543, -3538, -4275, -5356, -5743, -4637, -2614, -1301, -1825, + -3341, -4011, -2937, -751, 1007, 1245, 235, -639, -61, + 1626, 2864, 2967, 2734, 3013, 3329, 2914, 2312, 2666, + 3839, 4308, 3162, 1453, 768, 1255, 1887, 2006, 1715, + 1031, -297, -1660, -1690, -277, 813, -30, -2137, -3370, + -2854, -1553, -593, -413, -1146, -2567, -3440, -2369, -205, + 379, -1258, -2315, -812, 262, -3205, -8576, -7894, 738, + 7492, 1951, -11595, -17098, -6934, 7139, 8065, -4575, -14199, + -8946, 3606, 7504, -547, -8242, -5113, 4406, 8113, 2134, + -5040, -4089, 4157, 10934, 10158, 4167, -565, -192, 4428, + 9765, 12201, 9861, 4512, 1225, 3451, 8483, 10133, 6497, + 2574, 3333, 6806, 6986, 2487, -1214, 623, 5416, 6647, + 2204, -3289, -4556, -1565, 1544, 1525, -1236, -4293, -5695, + -5174, -3995, -3403, -3449, -3750, -4505, -6014, -7296, -6523, + -3849, -2096, -3288, -5722, -6004, -3581, -1497, -1960, -3330, + -2800, -434, 964, -111, -1739, -1136, 1736, 4151, 3736, + 1274, -451, 469, 3386, 5833, 5898, 3646, 1085, 272, + 1743, 4061, 5108, 3837, 1490, 246, 967, 1866, 859, + -1069, -974, 1542, 2835, 47, -4285, -5068, -1567, 1781, + 1223, -1997, -4227, -3747, -1720, 41, 245, -1228, -2972, + -2673, 22, 1980, -930, -7721, -11271, -5725, 4974, 8484, + -2007, -16979, -19255, -4670, 11057, 9690, -6417, -17537, -10841, + 4262, 9292, 206, -9128, -6224, 4828, 10018, 3699, -5183, + -5121, 4702, 14279, 14466, 5778, -2633, -2185, 7036, 16118, + 16305, 8081, 390, 499, 6580, 11150, 10036, 5704, 2902, + 3378, 4664, 3786, 863, -796, 1216, 4609, 4493, -338, + -5670, -6486, -2751, 884, 571, -3095, -6446, -6997, -5770, + -5041, -5016, -4216, -2579, -2468, -5088, -8129, -7964, -4228, + -323, 497, -1556, -3653, -3615, -1718, 464, 1808, 2386, + 2832, 3085, 2905, 2676, 3473, 5501, 7094, 6442, 3929, + 1663, 1436, 3254, 5807, 7100, 5044, -34, -4091, -2992, + 2149, 5333, 2562, -3067, -5877, -4480, -2080, -1793, -3026, + -3838, -3735, -3663, -4472, -5756, -5753, -3576, -640, -274, + -3965, -7787, -6757, -717, 4380, 3595, -1553, -5936, -8603, + -10223, -8952, -922, 9700, 9355, -7788, -25795, -22413, 2268, + 20887, 12133, -11291, -20129, -5899, 10236, 8585, -3645, -6300, + 4667, 14216, 9346, -3593, -8558, 715, 15085, 21179, 14887, + 3733, -2703, -675, 7170, 15131, 18360, 13959, 4205, -2825, + -656, 7594, 11845, 7182, 319, -439, 3255, 3213, -3299, + -8972, -6318, 2300, 7190, 2254, -9247, -17334, -15064, -4452, + 5160, 5127, -4268, -14501, -17256, -11145, -1830, 3786, 2984, + -2498, -8101, -9587, -5703, 622, 4570, 4035, 1442, 729, + 2493, 3534, 2433, 2239, 5944, 11438, 12371, 6496, -211, + -156, 7092, 13566, 11979, 3928, -2545, -2226, 2713, 6150, + 5117, 1270, -1851, -2859, -2376, -1909, -2364, -3401, -4183, + -3897, -2875, -3205, -5503, -7822, -7501, -3934, -942, -1572, + -4262, -5939, -4671, -2353, -1387, -1159, -1270, -1328, -606, + 474, 1044, -2647, -11603, -17081, -10374, 5922, 14849, 2056, + -22033, -31238, -14612, 11094, 17910, 1778, -15538, -15417, -2045, + 6690, 2855, -2559, 473, 8823, 11423, 3782, -4649, -2775, + 9111, 20847, 21610, 11572, 962, -1465, 5731, 15559, 20008, + 16950, 9230, 2204, 114, 3088, 8130, 10523, 7643, 2045, + -2107, -2945, -2538, -3593, -5210, -4403, -857, 1328, -2497, + -11667, -18881, -16866, -6286, 3400, 2835, -7811, -18322, -19279, + -10025, 1525, 6930, 3766, -4647, -11401, -9904, -322, 10100, + 12428, 5874, -274, 926, 6762, 9360, 6778, 5904, 10509, + 15077, 12681, 3846, -1653, 2460, 11036, 14737, 8967, -1021, + -6168, -3899, 2328, 6041, 3404, -2878, -7672, -6869, -1918, + 801, -2188, -7419, -8083, -2687, 1898, -692, -8121, -11198, + -5642, 2830, 5915, 1120, -5666, -8314, -5770, 118, 4614, + 4713, 1482, -2544, -3331, -3779, -8931, -13840, -10273, 3355, + 13432, 2906, -20058, -30890, -17080, 7759, 16047, 2886, -12525, + -15117, -5998, 1614, 2294, 2684, 4610, 6236, 5486, 2514, + 1346, 1962, 4564, 11022, 17438, 18182, 10179, -796, -3019, + 5456, 15942, 18468, 11176, 2796, -143, 1670, 3922, 3836, + 3337, 3330, 1623, -2609, -7177, -7654, -4250, -2210, -3491, + -5312, -4380, -3103, -6738, -13209, -14278, -6529, 3346, 4931, + -2861, -11176, -12097, -5552, 2679, 7102, 6050, 1301, -3350, + -3378, 1785, 7413, 9059, 7013, 5043, 5331, 5197, 3143, + 1862, 3790, 8037, 10159, 7236, 1450, -3393, -3980, 598, + 6251, 7410, 1502, -7144, -10260, -5116, 2386, 4197, -894, + -6255, -6026, -1493, 873, -1639, -4426, -2720, 2252, 4206, + 158, -4631, -4466, 537, 4709, 4528, 1691, -828, -1394, + -455, 756, 2662, 3101, 1730, -3579, -12987, -18531, -12998, + 1944, 11963, 1503, -19826, -29919, -18138, 2254, 7644, -1829, + -9260, -6516, 134, -793, -5234, -2336, 6264, 12828, 11829, + 6589, 3429, 2592, 4795, 11433, 19490, 21681, 13136, 379, + -4138, 3585, 14812, 17633, 10124, 623, -2287, 696, 2273, + -926, -5000, -4391, -386, 139, -4657, -11003, -13946, -11930, + -7460, -1932, 1277, -2311, -10543, -16920, -14512, -4039, 4987, + 7518, 3175, -4213, -7535, -4747, 3590, 12231, 13419, 8429, + 2377, 1080, 5563, 8497, 7304, 5331, 5656, 8235, 6997, + 998, -3131, -1857, 3017, 5883, 3744, -408, -4503, -6489, + -4796, -374, 3254, 1651, -2830, -5206, -3690, -681, -969, + -2819, -2616, 19, 3379, 2359, -2476, -6413, -6111, -463, + 4664, 4106, -565, -4801, -4960, -1242, 2479, 3706, 2168, + -1104, -3048, -1563, 1217, 2013, -5714, -17921, -21743, -10839, + 7751, 13091, -4648, -26509, -29653, -9872, 10100, 9523, -4335, + -12121, -5509, 4923, 6380, 1839, -508, 3312, 10704, 14545, + 12317, 5508, -243, 2421, 11485, 19096, 18306, 8626, -1357, + -5542, -1695, 7815, 13549, 10229, -23, -8373, -7496, -2775, + -1016, -2900, -4868, -4103, -4535, -6851, -8099, -8137, -6414, + -4023, -1790, -45, -1513, -4791, -6160, -4105, 1060, 5970, + 7099, 3934, -996, -2213, 1973, 6975, 7927, 4726, 2474, + 3951, 5221, 2642, -2359, -3579, 1362, 6614, 6282, 116, + -5643, -5733, -1884, 2107, 3418, 2566, 684, -2319, -3803, + -2133, 1512, 2943, 475, -1004, 753, 3095, 1652, -3074, + -4562, -932, 3815, 4486, -22, -4199, -4666, -2201, 284, + 316, -914, -2297, -2441, -1538, -435, 909, 626, -1222, + -1534, -429, 1711, 2386, -1786, -10676, -18200, -16272, -3805, + 9505, 8238, -9397, -24577, -22256, -4907, 8659, 5940, -3701, + -6764, 40, 6190, 4239, 208, 238, 7081, 14458, 15143, + 10726, 3479, -706, 1700, 9131, 17577, 17708, 7959, -5009, + -11508, -5347, 5635, 10789, 6499, -3121, -9303, -9814, -6625, + -3333, -3193, -4349, -5615, -6188, -5123, -4441, -4550, -4074, + -2769, -61, 2441, 2881, 1395, -578, -341, 2509, 6034, + 8202, 6377, 2696, 1272, 2589, 4787, 4611, 2378, 2124, + 3911, 4872, 2049, -3374, -5770, -2705, 3179, 5905, 2589, + -2792, -5419, -3176, 1056, 2875, 2483, 1205, 605, 856, + 1012, 892, 105, -411, 707, 2924, 4184, 1755, -2553, + -4857, -3556, 401, 2466, 945, -2315, -5556, -5549, -2241, + 534, 601, -1774, -3034, -1962, -886, -448, -720, -467, + 864, 760, -22, -2546, -10211, -17121, -15877, -4803, 7993, + 7254, -6563, -18374, -17755, -6143, 3291, 4322, 1822, 416, + 2788, 5190, 4256, 2627, 2590, 6398, 12709, 15757, 12829, + 5542, -667, 167, 7241, 14346, 14826, 6392, -3516, -7434, + -4607, 1054, 2988, 847, -1549, -2641, -3046, -5363, -8256, + -9130, -6906, -1460, 2260, 1568, -2911, -8580, -9418, -3675, + 5021, 10127, 7909, 1478, -4015, -3331, 2450, 7291, 7632, + 2567, -2022, -899, 3418, 5544, 1349, -4117, -3409, 1758, + 6000, 3526, -3975, -7331, -3931, 2747, 7037, 4962, -21, + -2902, -2008, 1306, 4461, 6364, 5956, 3623, 1734, 793, + 44, -893, -1041, 1633, 5264, 4870, -943, -7404, -8611, + -4974, -1192, 185, -1334, -3672, -4910, -5132, -4387, -3532, + -3233, -2430, -469, 1245, 892, -969, -2441, -2140, 320, + 4999, 5954, -4638, -20056, -24424, -8954, 13558, 16089, -3145, + -20665, -19447, -4802, 4488, 3733, 943, 683, 3109, 6219, + 9247, 7736, 782, -1410, 8024, 20877, 20174, 4723, -7148, + -2758, 11240, 17896, 11462, 414, -6134, -4913, 113, 2818, + 98, -5900, -8369, -4446, 924, 1657, -3389, -10569, -13223, + -7690, 2339, 7741, 1634, -9014, -10982, -1172, 9642, 9098, + 1310, -2795, -1040, 2790, 3808, 3559, 3064, -527, -3160, + -1391, 3120, 5224, -144, -6714, -6416, -719, 5630, 7253, + 2735, -2973, -4325, 679, 7146, 8220, 4055, -42, 814, + 5288, 7658, 6592, 3051, -746, -541, 3401, 6030, 1953, + -6340, -8619, -2689, 4076, 3217, -4875, -9612, -7826, -4293, + -2441, -4080, -5740, -5529, -3656, -506, -1035, -5787, -9518, + -7034, 2323, 9287, 6495, -1853, -6110, -3281, -1708, -8958, + -19544, -18870, -2771, 13029, 10762, -7491, -21837, -18923, -4183, + 8733, 12580, 9779, 4597, 738, 1460, 6302, 9711, 8375, + 8143, 12512, 15808, 11272, 389, -5554, 161, 11080, 15851, + 10426, 692, -6372, -6808, -2525, 652, 827, -219, -349, + -622, -3328, -7883, -11020, -8961, -3240, 1884, 4155, 1995, + -3530, -7816, -6444, -218, 6086, 9279, 7901, 3113, -2352, + -5757, -3836, 2022, 4572, 894, -3519, -3311, -534, -618, + -3716, -5515, -3290, 1495, 4374, 4455, 2961, -645, -3247, + -656, 5273, 9838, 9751, 5755, 1863, 158, 1457, 4585, + 6390, 5379, 2894, 2284, 1867, -2279, -7051, -6578, 70, + 4745, 1660, -4524, -8007, -7088, -5690, -5467, -4178, -2679, + -2218, -3422, -4167, -4313, -6105, -6633, -4202, 864, 5119, + 4084, -163, -5331, -8699, -8710, -7313, -4649, -2471, -1419, + -1136, -3199, -6428, -8048, -4902, 1089, 4681, 5723, 5535, + 5146, 4006, 2052, 2314, 5274, 8680, 9907, 8776, 6722, + 2548, -2403, -3303, 1224, 7406, 9468, 5089, -1197, -4384, + -3570, -298, 1776, 2005, 2041, 1326, 971, -180, -2334, + -1170, 1913, 4281, 4732, 2874, 1174, -1341, -3384, -2503, + 368, 4031, 3270, -986, -3519, -5360, -6004, -5576, -3603, + 208, 708, -2137, -4940, -5349, -3588, -2796, -1399, 1017, + 3144, 4196, 2483, 828, 338, 919, 3842, 6202, 7189, + 7499, 6330, 4847, 3252, 2136, 3698, 5845, 5566, 3019, + 267, -55, -1091, -4220, -5041, -3430, -280, 171, -4649, + -8723, -9280, -5975, -3192, -3974, -3912, -4053, -3748, -3570, + -5871, -5499, -3552, -1691, 320, 341, 748, -313, -3436, + -4687, -3681, 21, 2550, 643, -2123, -3254, -2226, -1044, + -1617, -1510, 183, 1250, 726, -1662, -3388, -1759, 933, + 3817, 5242, 3025, 248, -1339, -514, 2022, 3410, 3970, + 3324, 2632, 2603, 2240, 2166, 1271, 487, 1076, 2039, + 3296, 3836, 3610, 2913, 2718, 4213, 5555, 6023, 4769, + 2442, 2067, 2173, 1623, 1201, 348, 52, -124, -1528, + -2834, -3604, -3463, -2357, -2564, -3775, -3801, -1929, -465, + -2109, -3743, -2657, 200, 2580, 954, -1304, -95, 1549, + 2303, 1795, 1633, 3356, 3699, 2361, 792, 1148, 4045, + 4820, 3851, 3197, 2449, 2704, 1722, -652, -1154, -393, + 113, -1010, -3328, -4342, -3939, -3345, -3697, -5115, -5610, + -4202, -3639, -5088, -5351, -3216, -862, -414, -1839, -3996, + -4831, -2467, 147, 1055, 1288, -247, -2225, -2233, -1562, + -1278, -936, -961, -935, -367, -323, -459, -1940, -3974, + -2262, -13, 2, -401, -1825, -2308, -1124, 448, 2154, + 2434, 1300, -812, -1337, 1325, 3374, 3466, 2500, 2156, + 3439, 3549, 2068, 1392, 1986, 3025, 3944, 3898, 3259, + 4467, 6347, 5356, 2893, 1690, 2072, 4136, 5313, 2776, + -236, -1063, -794, 524, 802, -1377, -2879, -2167, -1439, + -1595, -1539, -1666, -2495, -2375, -1253, -515, -187, -1409, + -2847, -511, 2411, 1761, 492, -18, 607, 2350, 3288, + 3505, 2741, 1099, 699, 2017, 3214, 3333, 1567, 33, + 1260, 1925, 808, -377, -2558, -3781, -1677, 164, -580, + -1727, -2619, -3421, -3586, -3957, -4562, -3646, -2285, -3437, + -5293, -4792, -4128, -4012, -2920, -2249, -2439, -3737, -5607, + -4427, -1259, 71, 609, 555, -1039, -3354, -5388, -3760, + 415, 2513, 2513, 819, -1436, -2780, -2740, -501, 2727, + 3936, 1491, -965, -766, -484, -223, 361, 695, 1771, + 1130, -1839, -1764, 797, -31, -2549, -1790, 2108, 4043, + 887, -154, 2411, 2605, 2012, 1977, 3923, 6630, 4176, + 107, -311, 1731, 1910, 1011, 3119, 3219, 998, -1282, + -2832, -1645, -685, 945, 2574, 2543, -267, -5015, -3819, + -342, 1228, 2055, -619, -1233, 2069, 2896, 1095, 62, + 1365, 3366, 4584, 4956, 3323, -19, -50, 4024, 5222, + 3695, 3118, 1933, 1256, 1443, 128, -119, 2043, 2477, + 1823, 1324, 30, -1363, -3023, -3074, -188, 621, -1775, + -2806, -2961, -2753, -4359, -5350, -1220, -116, -4157, -4811, + -2793, -1040, -1957, -2862, -1901, -3192, -3720, -2357, -1727, + -387, -2131, -5011, -3650, -454, 596, -1298, -3716, -3122, + 496, 136, -2415, -1675, -811, -837, 140, -1243, -187, + -1431, -5320, -2121, 100, -467, 2465, 681, -2093, 1224, + 1632, 1428, 1776, 648, 2480, 3622, 876, 259, 1403, + 2139, 3117, 497, -763, -170, 279, 1769, 342, -871, + -25, -1549, -2290, 290, 1042, -796, -4291, -3895, 159, + 1264, -540, -2328, -702, 1972, 852, -2274, -798, 1126, + -579, -480, 3481, 3833, 1004, 901, 1536, 1809, 3103, + 2521, 3183, 5220, 1800, -266, 4663, 4230, -790, 159, + 2274, 5114, 4304, -1998, 344, 4921, -343, -2048, 1180, + 2112, 3109, -10, -1818, 552, -1360, -2889, -1302, -1918, + -37, 1406, -1762, -3054, -1446, -2073, -4292, -3214, 1163, + 2333, -712, -2583, -2058, -1034, -600, -3796, -2395, 2137, + -1122, -1927, 702, -2196, -4374, -3257, -1558, -256, -728, + -395, -176, -1529, -2772, -1121, -340, -1147, -250, -4079, + -473, 4241, -2818, -3523, 3255, 2355, -2550, -1082, 1197, + 2213, -94, -237, 3123, 1314, -1075, 977, 1081, 2045, + 2966, -1328, -1069, -741, -524, -380, -2766, -986, 926, + -3281, -1554, 2554, -3620, -6394, -1680, -321, 2889, 243, + -1567, 2276, -1294, -525, 2010, -4883, -1495, 6778, 2085, + -873, 2496, 418, -1156, -1179, 1604, 6173, 1190, -2381, + 5788, 2431, -4941, -242, 1248, 1023, 4426, 3399, 2726, + 1388, -922, 595, 392, 1414, 6260, 2673, -973, 2237, + 1776, -2393, -757, 4158, 2842, -2327, 505, 1230, -3623, + -917, 336, -1400, -1018, 1771, 2696, -570, -2435, 886, + 2309, -2865, -1328, 2077, -1967, -3486, -411, 961, -1661, + -1979, 1179, -493, -2597, 1995, 284, -3300, -2213, 184, + 312, -1665, -641, -1325, -1276, 90, 69, 476, -778, + -1099, 853, 1515, 1630, 1188, -877, -1751, 702, 2983, + -201, 664, 4018, -352, -1864, 875, 2367, 813, -2463, + -702, 886, -2204, -2216, 399, -1729, -2408, 1412, -2757, + -3530, 449, -2554, -3910, 906, 697, -1696, 566, -1360, + -1991, 81, -1756, -159, 1180, -667, -584, -359, 183, + 1943, -412, -1747, 1659, 1961, 280, 294, 222, 2000, + 2076, 829, -43, -880, 3353, 3615, 1279, 1746, -1031, + 1301, 3477, -777, 2567, 1215, -2344, 3556, 561, -2166, + 1119, 2377, -391, -1825, -2359, 49, 1764, 391, -291, + 325, 1223, 1443, -624, -2828, 1381, 2438, 28, -652, + -166, 581, -2039, -374, -20, -2459, -1149, 1505, 2008, + -1798, -3848, -1796, -2208, -2224, -878, 728, -154, -534, + 1061, 538, -1465, 73, 1147, 82, -119, 3800, 4797, + -873, 784, 1458, -148, 3180, 1319, 908, 4951, 584, + -57, 2394, -967, 586, 405, -1601, 3566, -285, -3949, + -1301, -1953, -1223, -1831, -3477, -779, -389, -3169, -1828, + -1496, -1451, -556, -3327, -209, 534, -4908, 131, -386, + -5232, 1373, 2129, -1740, -1957, -1102, 76, 396, -1426, + -179, 1357, -3276, -1420, 3819, -44, 56, 2777, -1202, + 1908, 1410, 2031, 3495, -2197, -163, 1565, 239, 2803, + 480, -1636, 1180, 616, 1206, 1166, -1579, 1572, 814, + -774, 2310, 740, -2606, 1234, -603, -362, 1562, -2134, + 652, -777, -2353, 5464, 377, -2490, 1012, 157, 680, + -1389, -1898, 1135, -1, -1730, 1800, -1466, -1687, -1469, + -3250, -1081, 1381, -81, -204, -26, 353, 1941, 174, + 104, 2009, 1032, -871, 3280, 3398, -651, -154, 3309, + 1964, 448, 812, -17, 887, 2405, 3295, -54, -2396, + 1410, 1380, -1156, 296, -1706, -1729, 401, -970, -878, + -723, -2285, 1259, 1320, -1960, -1039, -211, -661, -763, + -1599, -43, 308, -1841, 72, -2075, -3010, -497, 506, + -377, 247, 1932, -1788, -2419, 257, 208, -2176, 488, + 2827, -1720, -1649, -619, 520, 1103, -1231, -1327, 2162, + 1535, -383, 315, -1488, -235, 1761, -27, -232, 515, + 127, -2239, 654, 2871, -379, -1274, 2445, 874, -2444, + 514, -206, -1289, 1314, 1869, 1316, 1878, -1454, -982, + 476, 359, 2084, -708, 405, -246, -1071, 1757, -866, + -2331, 783, 501, -853, 896, 36, -2468, -1138, 1445, + -613, -687, 1999, -449, -731, 1478, 384, -45, 96, + 1530, 1919, 186, -94, 1347, -329, -348, 1631, 574, + 1062, 735, -1652, 675, 244, 1241, 1137, -2469, 621, + 45, -612, 1308, -2015, -208, 2392, -1646, -67, 77, + -1558, 113, 1263, -236, -971, -333, -733, -555, 2024, + -135, -3817, -398, 1696, -1179, -1473, 1175, -166, 618, + 1132, -2504, -575, 146, -688, 1323, 150, -2021, 15, + 1673, 347, -1535, -106, 235, -32, 1167, -471, -503, + -1260, 416, -13, -1082, 1036, -790, -1676, 487, 985, + 77, 57, -1175, 1146, 2023, -1706, -404, 3249, -739, + -979, 3044, -514, -168, 2201, -2863, 1009, 1833, -2309, + 1565, 476, -1698, 1667, -496, -2193, 1686, 532, 336, + -1095, -1655, 578, -909, -1263, 2569, -2833, -1808, 2860, + -822, 27, 1098, -1371, 1585, -284, -1074, 2944, -764, + -2871, 2484, 1179, -1213, -670, -1226, 1112, 1837, -299, + -388, -51, 1, 992, -723, -361, 1723, -1115, -2012, + 1261, -9, -127, -510, -1550, 1448, 957, -1930, 171, + 776, -2104, 14, 764, -599, -745, -438, -371, -659, + 1075, 282, -3116, 684, 3747, 22, -2139, 816, 1413, + -333, 458, 906, 483, -1084, 797, 1039, -467, -377, + 1386, -1182, 610, 1787, -1354, -2800, 2638, 424, -2372, + 1153, -51, -689, 290, -2199, 818, 3755, -2674, -1689, + 3497, -507, -1978, 1729, 1413, 215, -76, 53, 759, + 371, -1529, 1005, -770, -685, 1754, -908, -653, 1047, + -1066, -784, -199, -526, 86, -1750, -916, 1839, 580, + -1884, 319, 226, -977, 212, 202, -741, -1013, 2057, + 69, -2961, 974, 1964, -512, -224, 1554, -79, -1142, + 1853, -71, 1009, 1174, -718, 2040, -158, -1508, 1042, + 0, -1219, 1212, 448, -208, -47, -779, -867, 1924, + -254, -1085, -221, -1283, 1543, -584, -951, 225, -1089, + -464, -853, -615, 1576, -2313, -1214, 950, -2548, -314, + 1201, -1527, 952, 764, -1915, 528, 169, -1676, 1742, + 425, -2346, 932, 290, 109, 492, -379, 932, 70, + 582, 135, 769, 1665, -1751, 576, 1013, 366, 2339, + 71, 637, 1500, 576, 111, 494, 765, 1170, 1421, + -5, -892, 2054, -640, 160, 1426, -651, 348, -841, + -558, 1563, 277, -408, -1468, 482, -1538, -2255, 968, + -1307, -454, 1306, -3085, -1680, 2624, -2191, -1719, 1891, + -3826, -1441, 2736, -3694, -266, 1897, -4468, 841, 2828, + -4060, -318, 2305, -1662, 528, 3056, -2429, -156, 2045, + -753, 475, 419, -597, 1100, 1845, 504, 1067, -402, + -824, 1807, 1192, 459, 200, 1728, 50, -497, 678, + -355, 938, 1239, -1223, 360, 1251, -95, 981, 1029, + -1940, 260, 1627, -2387, 3426, 519, -3141, 1822, -506, + -1471, 1101, -2137, 1069, 885, -2618, 1673, -463, -1558, + 1439, -386, -1923, 1538, -1313, -1735, 540, -1433, -915, + 494, -839, -1527, -1143, 480, -1081, 27, 1732, -1285, + -1833, 1952, -667, -1626, 1819, -1293, -1323, 2139, -376, + -1392, 1277, -1172, -240, 2907, -1875, -238, 2573, -1068, + -471, 2065, -686, -1315, 2575, 233, -1005, 1135, 706, + 534, 278, -182, 1091, -21, -222, 1413, -371, -54, + 1108, -103, 382, -70, 787, 894, -108, 1308, 1113, + -1412, 574, 1140, -2032, 500, 569, -1251, 951, -50, + -1398, 772, -474, -1536, 1297, 251, -2321, 109, -703, + -425, 40, -1354, -773, -225, -1743, -1839, 1244, 261, + -3082, -424, 1162, -937, 123, -322, -407, -561, -331, + 1369, -1142, -1050, 1024, 1116, -213, -752, 1521, -383, + -415, 1011, 947, -713, 743, 1945, -237, 881, 600, + -757, 885, -835, 756, 2454, -1985, 699, 1572, -1652, + 673, 232, -42, 1975, -736, -270, 1660, -704, -96, + 1264, -428, 278, 774, -954, -1325, 756, 1275, -594, + -353, 204, -1130, -782, -432, -979, 268, 378, 20, + -870, 405, -357, -1661, 637, 473, 293, -314, -895, + 3, -175, -1016, -643, 204, -588, -1007, -131, 401, + -849, -476, 271, 320, -198, 533, -25, -1994, 1421, + 525, -1611, 1261, 507, -488, 1093, 361, -1814, 2230, + 312, -196, 3242, -803, -962, 1714, -1479, 1426, 1612, + -1953, 1376, -581, -669, 1370, -1251, 426, 1274, -470, + 1757, 807, -589, 1275, 126, -871, 1025, -1331, 287, + 1258, -1813, 146, -839, -1471, 828, -402, -281, 1704, + -1341, -231, 939, -1035, -472, -197, -764, -380, -816, + -266, 382, -497, -1708, -591, 1119, -1941, 178, 969, + -1656, 685, 1004, -1114, -127, -1473, -678, 1610, -1253, + 277, 1807, -1642, -461, 2033, -1449, 392, 98, -157, + 1525, -860, 2455, 413, -2159, 2457, 475, -374, 1532, + -981, 843, 973, 324, 1168, 225, -407, 1487, 681, + -680, 1098, 117, 245, 1238, -223, 1076, -428, -466, + 2593, -663, -1225, 1303, -933, -561, 1190, -1071, -1229, + 406, -284, -13, 198, -1494, -637, 352, -1960, 420, + 49, -1472, -761, -234, -2213, -1750, -521, -1554, -813, + 662, -633, -1388, -15, -947, -391, -152, -894, 631, + -461, -885, 633, -51, -1063, 218, 1149, -61, -274, + 988, -140, 7, 1774, 1558, -623, 755, 1352, -511, + 1106, 744, 17, 2640, -91, 697, 1547, -1757, 1832, + 1859, -206, 1505, 575, -444, 556, 250, 1786, 792, + -125, -266, 407, 501, 798, -536, -1214, 58, 6, + 354, -685, 613, 99, -2022, -116, -236, -182, 263, + -824, -1187, -142, -138, -1228, -1008, 786, -1421, -1127, + -269, -2278, 841, 222, -2423, 678, -1153, -2082, 574, + -570, -729, 180, -777, 212, 270, -274, 1077, -493, + 118, 804, -1260, 349, 799, 545, 481, 971, 1099, + 1146, -273, 34, 1728, 1128, 411, 758, 308, -808, + 950, 1490, 209, -265, 1154, -11, -460, 2644, -122, + -728, 2033, -1100, -305, 1774, -208, -1567, -57, -140, + -670, -454, -1390, -80, 978, -438, -731, -684, 344, + -458, -199, -126, -1663, -883, 642, -1517, -1144, -375, + -422, -452, -1815, -791, 763, -1502, -205, 684, -1641, + 448, 1399, -2160, 804, 1088, -2214, 1030, 1585, -1093, + -11, 1718, -360, -81, 1294, 398, 218, 1225, 644, + 505, 2090, -385, 526, 2111, -303, -316, 1550, 1323, + -459, 881, 1874, -1256, 1429, 2485, -1003, -552, 14, + 432, 952, 471, -633, 408, -358, 140, 554, -1260, + -404, 245, -2572, 954, 1005, -1621, -82, -175, -957, + 112, 106, -1117, -819, -62, -785, 71, 93, -1296, + -1680, 242, -956, -2696, 302, -204, -1404, 254, -558, + -201, -630, 16, -436, -1647, 1649, -1096, -1267, 2273, + -1270, 20, 1749, -2509, 780, 942, -1859, 2762, 304, + -300, 2617, -947, 861, 2601, -1153, 754, 1629, -681, + 686, 1443, -235, 1900, 5, -565, 1559, 285, -170, + 757, 480, 547, 752, -427, 50, 839, -95, -791, + -1698, -291, -62, -1730, 524, 1008, -2176, -369, 165, + -749, -972, -287, 889, -1218, -1712, 833, -855, -995, + -14, -793, -1815, 605, -607, -1890, 769, -781, 230, + 1155, -2000, 876, 1835, -1617, 9, 1058, -1232, 859, + 1486, -1301, 1595, 501, -951, 2935, -921, -634, 2826, + -793, 655, 2660, -232, 235, 1879, 481, -51, 804, + 987, -360, -331, 2099, -302, -149, 1966, -1233, -12, + 1330, -2265, 1256, -116, -1394, 2937, -995, -1572, 2964, + -2257, -2587, 1820, -2132, -1609, 778, -1596, -486, 560, + -1749, 274, -706, -1714, 1304, -360, -2657, 1833, -750, + -1729, 433, -1461, -794, -1545, -892, 385, -891, -374, + 1261, -589, 235, 815, -773, -669, 636, -471, 136, + 871, -392, 782, 677, -472, 1130, 1029, -1262, 1070, + 2171, 575, 675, 600, 2104, 1077, -182, 2621, -604, + -30, 3302, -1331, 599, 742, 291, 1329, -551, 1043, + 1729, -1754, 1220, 1113, -2174, 1281, 743, -2027, 851, + -205, -1576, 214, -1629, -605, -394, -1508, -254, -63, + -489, -847, -26, -997, -1065, -120, -376, -1283, -1393, + 83, -212, -1610, 419, -1120, -590, 395, -1210, -21, + -273, -622, 899, -196, -1059, 1130, 616, -529, -166, + 794, 22, -216, 862, 664, -390, 980, 228, 789, + 182, 402, 2149, -1133, 799, 2637, -799, 176, 1306, + 905, -93, 677, 338, 121, 483, 297, 339, 347, + 249, 731, 40, 66, 112, -889, -128, 582, -1191, + -67, -1364, -233, 488, -1734, -634, 1517, -1657, -1015, + 594, -1422, 1396, -1357, -1617, 1254, -1596, -941, 789, + -1860, -77, 245, -327, 569, -723, 104, 905, -543, + -918, 1387, -42, -440, 619, 68, 45, 1364, -880, + 19, 1491, -561, 1174, 1403, -1411, 1351, 1222, -612, + 864, 877, -658, 382, 864, -552, 1286, 309, -105, + 1083, -170, -289, 1049, -248, -537, 625, -48, 337, + -385, 532, -315, -1398, 588, -628, -1192, 649, -806, + -170, 541, -2267, 1052, 274, -1970, 833, 253, -1345, + -290, -120, -959, -94, -189, -1397, -136, -155, -654, + 207, -706, 617, 415, -1962, 1169, 670, -1132, 319, + 297, -589, 100, 510, -620, 610, -153, -15, 1327, + -99, 229, 281, 169, 1015, -106, 1197, 577, -698, + 577, 931, -964, 1605, 505, -1713, 2369, 115, -1585, + 1839, 664, -1411, 867, 620, 329, 491, -1119, 420, + 266, -1708, 499, -69, -1037, 795, -321, -959, 32, + 235, -1748, 295, -249, -230, 485, -1185, -97, 489, + -2036, 711, 405, -2800, 593, 434, -1038, 536, 347, + -570, 705, -806, -290, 818, -999, 53, 1585, -756, + -657, 1180, 115, -364, 217, -226, 1033, 347, -20, + 611, 658, 590, -128, -451, 1676, -660, -21, 805, + -880, 1481, 412, -1534, 1522, 221, -132, 662, -407, + 613, 1132, -551, -187, 1184, -577, -444, 953, -1034, + -472, 461, -865, -99, 637, -572, 300, 450, -591, + 137, 404, -972, 306, -524, -1167, 433, 124, -1326, + -368, -305, -917, 452, -626, -695, 656, 258, -1401, + 270, 446, -1045, 636, -357, -1072, 913, 512, -1732, + 489, 952, -747, 58, 673, -453, 1125, -488, 46, + 1723, -1244, 417, 1803, -1215, 623, 659, -560, 676, + -9, 92, 701, 1100, -623, 142, 283, -512, 547, + 576, -525, -155, 1143, -1286, -329, 1959, -1302, -459, + 1188, -1199, 1020, -118, -1303, 956, -905, -647, 595, + -356, -1354, -74, 750, -791, -335, 56, -862, -36, + 276, -279, 46, -485, -181, 196, -584, -238, 259, + -314, -77, 383, 509, -386, -180, 859, -542, 955, + 372, -362, 1458, 113, -106, 1495, -534, 63, 1295, + -505, 846, 983, -1097, 1764, 320, -185, 1061, -525, + 115, 217, -328, 326, 312, 374, 179, -683, 485, + -1286, 147, -583, -979, 888, -504, -1235, 715, -1050, + -1111, 848, -828, -1043, -115, -327, 22, -451, -1008, + 98, -262, -545, -363, -48, -257, -731, 878, 96, + -1186, 426, 359, -1101, 1074, -267, 521, -375, -166, + 1398, -994, 780, 550, 124, -298, 581, 236, 305, + -111, 396, 741, -10, 662, 155, 271, 563, 65, + -318, 812, -483, 843, 75, -714, 1152, -26, -190, + -97, 533, -111, -564, 724, -24, -820, 835, -473, + -632, 154, -104, -932, 919, -606, -619, 496, -310, + -271, -360, 120, -630, 126, 65, -931, 548, -207, + -455, 410, -282, -931, 944, -354, 69, 412, -661, + 1068, -969, -443, 1894, -1281, -442, 2003, -1640, 713, + 852, -1344, 1338, -457, 243, 498, -697, -129, 993, + -388, -76, 1039, -768, 492, -104, -58, 951, -854, + 181, 1093, -1111, 491, 544, -1061, 118, 586, -477, + -411, 392, 233, 91, -908, 532, 218, -1176, 670, + -74, -674, 696, -801, 194, 592, -1790, 762, -564, + -791, 595, -145, -727, 228, 434, -246, -232, -169, + 281, -324, 289, -120, -270, -49, 282, 250, -56, + -405, 507, 27, -1060, 1329, -203, -204, 1677, -767, + -313, 1272, -968, 717, 183, -1652, 2157, -75, -1906, + 2590, -428, -1614, 2564, -1511, -240, 1421, -1911, 1420, + 396, -1397, 1691, -694, -1500, 1942, -823, -784, 841, + -635, 759, -447, 351, 44, -946, 227, 441, -564, + 155, -719, 182, 509, -320, -300, 205, -662, 726, + 469, -1240, 191, 664, -269, -152, -18, 214, -149, + -257, 347, 76, -79, -384, 874, -387, -269, 892, + -783, 537, 46, 27, 251, -332, 133, 377, -522, + 232, 626, -362, -499, 1112, -342, -522, 362, -187, + 547, -384, -155, 517, -551, 227, 651, -825, -88, + 579, -758, -40, 456, -774, 542, -164, -482, 968, + -1000, -394, 1094, -885, 431, 74, -348, 403, -959, + 831, -465, -330, 762, -717, -645, 1342, -499, -416, + 944, -417, -438, 737, -368, -42, 740, -1234, 689, + 29, -106, 619, -824, -10, 1047, -824, 146, -59, + 210, 163, -43, 522, -352, 213, 460, -1049, 599, + 308, -843, 632, 223, -504, 296, 530, -931, 751, + -176, -524, 379, 236, -626, 66, 662, -575, 191, + -175, -619, 660, -424, -217, 704, -498, 200, 62, + -543, 280, 91, -378, 54, 168, -554, 670, -215, + -1097, 1805, -1015, -617, 1642, -1560, 727, 61, 7, + -48, -659, 1308, -752, -613, 914, 160, -469, 164, + -167, 274, 326, -667, 497, 333, -757, 1252, -481, + -1257, 2019, -949, -719, 1676, -1078, 250, 323, -1100, + 1550, 145, -1697, 972, 522, -966, 374, -365, 846, + -276, -756, 629, -278, 302, -151, -243, -363, 841, + -7, -1092, 476, 45, 201, -378, -456, 1113, -926, + 97, 178, -240, 326, -597, 472, -10, -190, 394, + -501, -259, 307, 133, 240, -433, -192, 472, -190, + 12, 398, -191, -605, 1295, -576, -154, 474, -661, + 866, -968, 172, 887, -736, 36, 259, -201, 265, + 460, -859, 622, 102, -690, 776, -80, -745, 919, + 140, -750, 224, 134, -236, -196, 456, 409, -1069, + 600, 239, -306, -383, 541, -213, -323, -121, 700, + -735, 179, 222, -613, 653, -711, -81, 592, -694, + 117, 703, -772, -264, 644, -117, -422, 276, 64, + -355, -430, 800, -74, -619, 1207, -1057, 4, 960, + -1219, 977, -78, -1186, 1536, 267, -1388, 1144, -90, + -1052, 1889, -1255, -387, 1815, -1763, 1037, 421, -1003, + 767, -24, -277, -54, 759, -285, -1015, 1422, -581, + -121, 547, -687, 288, 440, -626, -623, 1261, -248, + -1133, 1204, -714, 382, 219, -851, 240, -161, 672, + -261, -855, 1043, -599, 111, -362, 225, 641, -913, + -122, 1075, -1165, 432, 131, -803, 978, 33, -1291, + 992, 224, -1054, 789, -121, -215, 262, -11, 89, + -174, 365, -240, 114, 406, -813, 291, 233, 158, + -377, 194, 216, -477, 635, -228, -512, 599, 23, + -273, 71, 258, 10, -155, -198, 354, 61, -749, + 768, -19, -709, 596, 97, -276, 164, 69, -144, + -20, 529, -897, 188, 480, -703, 836, -874, 259, + 917, -1044, -7, 566, -97, -439, 256, -466, 998, + -360, -1134, 1619, -762, -752, 1446, -707, -177, 652, + -899, 579, 253, -410, 146, -262, 275, 353, -610, + 52, 671, -862, 419, -140, 273, 247, -1062, 1005, + -175, -497, 772, -431, -101, 450, -598, 266, 428, + -842, 477, -11, -554, 642, 17, -787, 544, 445, + -625, -205, 796, -222, -733, 764, -572, 423, 166, + -994, 931, -228, -303, 362, -214, 104, 448, -1091, + 722, 570, -1311, 773, 259, -648, 477, 193, -682, + 302, 459, -464, -383, 1120, -561, -564, 1083, -372, + -354, 864, -586, -200, 502, -331, 27, 446, -657, + 281, 571, -888, 502, 251, -423, 116, 277, -263, + 118, -170, 168, 367, -723, 202, 438, -793, 451, + -30, -292, 202, 38, -188, -66, 221, -90, -105, + 7, 346, -578, 337, 247, -371, -14, 22, 36, + 151, -322, -244, 692, -556, -5, 550, -560, 200, + 161, -347, 191, 258, -520, 441, -212, -215, 584, + -428, -251, 213, 90, -187, 109, 138, -211, -17, + 191, 111, -259, 161, -141, 232, -175, 0, 154, + -369, 539, -171, -438, 484, 43, -375, -37, 249, + 196, -328, -106, 541, -531, 103, 240, -191, 186, + -363, 40, 585, -573, 258, 170, -593, 515, -261, + -86, 407, -339, 164, -214, -34, 464, -377, -206, + 336, -230, 239, -85, -69, 322, -503, 322, 142, + -748, 867, -160, -753, 836, -249, -362, 750, -374, + -222, 448, -82, -246, 399, 13, -429, 441, -47, + -127, -29, 337, -502, 318, 132, -457, 498, -145, + -91, 98, 208, -179, 54, 62, -260, 237, 96, + -161, 32, -150, 93, 21, -31, 74, 75, -322, + 164, 168, -191, 119, -121, -66, -195, 296, -128, + -251, 381, -56, -338, 281, -29, -472, 664, -301, + -275, 423, -285, -77, 258, -82, -139, 160, -54, + -26, 27, 75, -49, -196, 305, -131, -187, 262, + -37, -206, 65, 269, -240, -144, 261, 54, -338, + 355, 3, -503, 535, -253, -210, 433, -290, -33, + 381, -546, 173, 252, -364, 271, -329, 166, 266, + -564, 507, -32, -648, 861, -400, -357, 819, -519, + -74, 392, -423, 426, -306, -93, 691, -991, 537, + 467, -992, 614, 426, -823, 491, 182, -371, 174, + 84, -64, 98, -96, 23, 182, -69, -211, 226, + 18, -134, 334, -514, 352, 378, -623, 363, 266, + -592, 493, -46, -369, 594, -440, -10, 295, -368, + 326, -192, -140, 306, -305, 140, 198, -396, 202, + 154, -341, 208, -8, -169, -76, 106, 20, -347, + 233, 30, -193, 117, -9, -165, 182, -4, -195, + 96, 131, -188, -106, 166, -71, -99, 57, 4, + -31, -131, 101, 63, -199, 225, -25, -281, 342, + -247, -170, 516, -289, -263, 422, -158, -148, 363, + -192, -138, 122, 62, -105, 7, 194, -53, -224, + 83, 173, -182, 20, 178, -274, 182, 74, -109, + -5, 319, -303, -72, 428, -371, 50, 271, -204, + 17, 161, -256, 169, 93, -169, 94, -89, 139, + 80, -199, 325, -67, -83, 202, -154, 16, 202, + -325, 162, 61, -93, 201, -278, 236, 108, -477, + 594, -145, -370, 647, -261, -356, 669, -369, -181, + 420, -266, -154, 159, -25, 53, -40, -22, 68, + -203, 144, -2, -173, 88, -3, -62, 2, 75, + 55, -95, -130, 219, -142, -191, 164, -170, 44, + 0, -246, 249, -27, -413, 461, 27, -490, 292, + 19, -145, 13, 99, 91, -466, 209, 295, -773, + 465, 210, -680, 410, 163, -358, 399, -201, 87, + 23, -212, 270, -230, 86, 159, -353, 381, -73, + -456, 726, -353, -357, 754, -367, -344, 657, -59, + -417, 432, 35, -309, 153, 97, -69, 89, -101, + 63, 107, -127, 106, 112, -26, -236, 376, 43, + -479, 544, -57, -407, 447, -148, -103, 195, -198, + 80, 156, -228, 35, 145, -77, -55, 130, -33, + -190, 123, 41, -170, 74, 114, -241, 67, 192, + -195, -76, 186, -136, -133, 213, -105, -110, 144, + -51, -126, 154, -59, -124, 147, -49, -132, 82, + 26, -130, 63, 68, -211, 97, 131, -224, 59, + 184, -250, 59, 205, -225, -67, 163, -135, -24, + 74, -22, -4, -81, 21, 71, -137, 71, 47, + -120, 71, 34, -65, 138, -6, -116, 112, -47, + -39, 20, -75, 64, -7, 2, 35, 52, -61, + -29, 81, -61, -30, 195, -91, -136, 261, -11, + -186, 162, -86, -35, 152, -106, -32, 126, -4, + 49, 33, -9, -11, 46, 111, -132, -3, 204, + -175, -10, 281, -146, -94, 226, -126, -36, 58, + -14, 61, -172, 48, 193, -221, 83, 149, -279, + 195, 130, -357, 226, 102, -260, 191, 16, -223, + 124, 14, -144, 90, -31, -81, -66, 54, 103, + -181, 29, 174, -281, 92, 81, -226, 139, -133, + -41, 167, -147, 44, 27, -132, 107, -34, -122, + 105, -54, 17, 52, -131, 138, 33, -206, 158, + 43, -80, 24, 10, -27, 33, 43, -71, 15, + 71, -42, 14, 18, 0, -3, -14, -14, 58, + 46, -99, 122, 105, -202, 125, 119, -238, 112, + 133, -242, 113, 129, -301, 52, 161, -177, 82, + 73, -139, 46, 122, -119, 22, 155, -230, 23, + 242, -211, -12, 182, -184, -57, 190, -34, -101, + 58, -20, 6, 103, -61, -78, 12, 18, 12, + 86, -71, -27, 43, -24, 8, 39, -109, 21, + -4, -44, 66, 13, -59, 61, -39, 35, 113, + -179, 19, 171, -158, 14, 112, -133, 26, 9, + -43, -9, 6, 41, -77, 22, 80, -61, -63, + 65, -32, -32, 125, -105, -11, 114, -120, 42, + 42, -92, 45, -56, -25, 131, -83, -24, 97, + -51, -5, 67, -69, 7, 41, -27, 8, 3, + -10, 8, -3, -87, -28, 122, -33, -58, 124, + -53, -50, 67, -115, -17, 111, -112, -30, 101, + -24, -13, 41, 3, 45, -13, -34, 23, 23, + -19, 13, -49, -49, 68, -68, -32, 91, -58, + -18, 73, -19, -27, 17, -33, -35, 99, -38, + -99, 78, -31, -62, 95, -71, -124, 184, -15, + -146, 160, -27, -109, 140, -25, -63, 84, -34, + -18, 58, -68, -16, 22, -87, 86, 23, -130, + 61, 62, -132, 51, 168, -139, 35, 133, -121, + 50, 102, -120, 40, 126, -87, -40, 119, -14, + -59, 78, 11, -68, 41, 24, -25, 55, -2, + 15, 21, -73, 56, 88, -74, -41, 4, -10, + -4, 5, 7, -39, -3, -4, -39, 94, 52, + -135, 42, 90, -86, 12, 21, -55, -70, -37, + 55, -63, -35, 50, -100, 21, 84, -151, 24, + 87, -94, 51, 2, -58, 104, -61, -70, 60, + -25, -42, -31, 55, 35, -129, 47, 69, -65, + 77, 2, -60, 110, -32, -69, 84, -54, -26, + 98, -28, -7, 49, -49, -19, 119, -11, -157, + 20, 106, 29, -8, -38, -30, 72, 30, -3, + 1, -32, -11, -9, 52, 46, -144, -38, 86, + -31, -9, -42, -75, 142, 34, -64, 79, -109, + -55, 195, -69, -80, 48, -49, 62, 25, -111, + -42, 52, 19, -41, 1, -16, -33, 44, 30, + -21, 17, -2, -30, 111, 34, -111, 83, 55, + -119, 66, 62, -89, 63, -39, -143, 168, 21, + -158, 158, 32, -132, 134, -3, -77, 88, -45, + -18, 117, -51, -71, 10, 30, 35, -27, -63, + 13, 34, 23, -23, 19, -4, -92, 34, 74, + -69, -15, 20, -36, 56, -36, -96, 69, -34, + -122, 32, 31, -51, -3, -21, 4, 43, -44, + 6, 81, -39, -35, 26, -38, -24, 29, -16, + -47, -6, 19, -7, -9, 41, 32, 13, -2, + -21, 3, 24, 49, -3, -66, 14, 95, -7, + -52, 80, 68, -72, -14, 39, 2, 24, -6, + -53, 86, 21, -78, 67, 28, -34, 16, -23, + -1, 70, -3, -58, 45, 33, -94, -34, 62, + 41, -11, -27, 27, 46, 14, -33, -12, 44, + -16, -59, 6, 45, -3, -42, 2, 13, 19, + -1, -71, 3, 42, -36, 6, 17, 26, 5, + -46, 6, -68, -75, 86, -20, -90, 80, 4, + -86, 5, 2, -33, -15, -2, -8, -18, 15, + -7, -25, 27, -28, -88, 39, -2, -85, 58, + 40, -45, 3, 17, 0, 11, -4, -3, 84, + 22, -113, 8, 94, 10, 9, 28, 6, -3, + 5, -2, 23, 23, -1, -40, 20, 48, -40, + -21, 72, 7, -40, -1, 27, 16, 30, 31, + -16, 11, 9, -71, -7, 62, 21, -61, -19, + 78, -2, -22, 67, -42, -12, 75, -79, 47, + 86, -124, -42, 21, 4, 23, -32, -7, 19, + 1, -13, -46, 2, 32, -43, -7, 86, -16, + -22, 46, -61, -35, 11, -64, -38, 17, -12, + -27, 20, 41, 6, -58, -61, 58, -51, -77, + 36, -25, 19, 93, -76, 1, 72, -92, 15, + 40, -56, 65, 13, -29, 82, -9, -21, 24, + -83, -5, 4, -63, 77, 80, -58, -6, -19, + -43, 100, 5, -36, 63, 33, -26, -48, 26, + -18, -75, 34, 24, -45, -1, 6, -35, -24, + -23, -22, 47, -15, -46, 31, -40, -41, 74, + -32, -73, 59, -51, -26, 143, -29, -42, 93, + -44, -21, 56, -7, 55, 51, -61, 74, 111, + -71, 35, 124, -123, -3, 62, -79, 100, 49, + -122, 143, 79, -137, 72, 30, -82, 75, -10, + -48, 35, -23, -25, 34, 0, -54, -6, 34, + -46, -59, -7, -72, -6, 70, -41, -39, 23, + -33, 11, 104, -44, -30, 54, -69, -20, 62, + -75, 1, 45, -69, 1, 40, -59, -15, 18, + -16, 38, -1, -52, 8, 14, -32, 11, -15, + -58, 18, -22, -44, 69, 40, -50, -21, 1, + -35, -3, -5, -20, 40, 36, -41, -36, -43, + -11, 48, -34, -40, 51, -10, -9, 30, 10, + 12, 51, 51, -8, -16, 32, -6, 31, 24, + -38, 43, 18, -15, 53, -10, -55, 9, 8, + -28, 21, 10, -26, 21, 10, -9, 5, -29, + -13, 38, -1, -11, 49, 0, -41, 10, 23, + -25, -35, -2, -32, -10, 58, -6, -18, 16, + -9, 4, 11, 17, 21, 21, 12, -2, 49, + -16, -128, 21, 75, -32, 22, 34, -59, 48, + 75, -69, -11, -2, -65, 39, 57, -54, -79, + -11, -20, -13, 38, 4, -9, -22, -22, 33, + -7, -52, 10, -10, -19, 54, 47, -21, -35, + -6, -4, 11, 8, -28, 1, 8, -4, 30, + 1, -22, 26, -7, -24, 56, 25, -45, 13, + 24, -32, 13, 22, -46, -2, 15, -39, 28, + 32, -69, 0, 27, -69, 0, 39, -40, 28, + 55, -27, -13, 0, -14, 37, 25, -25, 34, + -3, -69, 26, 39, -41, -6, 29, -7, 5, + 66, 41, -27, -17, 6, -14, -21, 0, 29, + -9, -26, 32, -5, -34, 60, 15, -60, 20, + 13, 11, 43, -48, -15, 88, -13, -55, 26, + -32, -46, 35, 14, -37, -11, 12, -20, 11, + 9, -64, -16, 17, 5, 38, 7, -30, -9, + -49, -11, 52, -15, -38, -27, -12, 36, 53, + 1, -37, -17, -12, 0, 31, 1, 13, 40, + -15, 2, 47, -15, -17, 28, -2, -4, 25, + -6, -12, 2, -17, -9, 5, -15, 17, 21, + -28, 0, 15, -43, -63, -6, -14, -8, 37, + -34, -40, 30, -12, -14, 37, -13, -16, 26, + -15, -2, 13, -37, -13, 32, 13, -8, -2, + -12, -8, 9, 9, -3, 4, 13, 34, -2, + -22, 40, 19, 29, 25, -48, -17, 23, 17, + 7, 3, 0, 12, 37, -1, -25, 30, 41, + -7, 7, 29, -31, -31, -23, -27, 5, 2, + -18, -2, 22, 9, -6, 5, -7, -24, 9, + 0, -28, 19, 61, -11, -45, 21, -28, -65, + 28, 33, -44, -27, -6, -26, -8, 4, 5, + 9, -10, -46, -20, 20, -7, -7, -33, -26, + 50, 9, -65, -22, -3, -20, 15, 21, 20, + 24, -16, -27, -13, 14, 21, -38, -48, 9, + 35, 28, 21, 3, -31, -8, 57, 32, -35, + -22, 20, 14, 12, 28, 39, 0, -18, 44, + -2, -17, 53, 0, -27, 33, 43, 5, -10, + 25, 47, -3, -4, 36, 15, -12, -3, 29, + 41, 23, 23, -8, -32, 15, 37, 0, 3, + 22, 31, 1, -20, 27, 2, -50, 0, 33, + 16, -16, -17, 18, -26, -34, 31, -27, -84, + -33, 4, -5, -22, -17, -28, -66, -24, 8, + -16, -25, -51, -13, 45, -11, -49, -26, -49, + -38, 21, 10, -52, -58, -19, -4, 9, -31, + -29, 55, 2, -45, 29, 10, -22, 49, 33, + -27, -19, -5, 30, 47, 11, -11, -2, 8, + 5, 17, 8, 3, 57, 63, 28, 24, 11, + 2, 14, 22, 7, 7, 2, 23, 33, -2, + -8, 14, 7, 20, 57, 32, -5, 12, 23, + 10, 17, 26, -18, -72, -6, 74, 61, 13, + -17, -21, -7, 29, 45, 5, -52, -49, 1, + 10, 35, 40, -46, -66, 7, 31, -27, -44, + -12, -41, -22, 32, -12, -32, -3, -17, -22, + -22, -31, -30, -23, -13, 3, 0, -21, -19, + -7, -17, -9, 18, -40, -64, 1, 4, -4, + 8, -17, -28, -1, 9, -7, -9, 27, 6, + -63, -32, 52, 25, -46, -23, -6, -11, 35, + 29, -50, -44, 17, -6, -12, 53, 28, -17, + -9, 28, 34, -20, -18, 22, 43, 28, -6, + 8, 14, 19, 28, 14, 27, 26, 12, 76, + 66, -18, -2, 18, -12, -1, -2, -1, 51, + 30, -18, 5, 14, -12, 2, 13, -25, -9, + 32, 7, -5, 15, -12, -33, -18, -13, 6, + 0, -25, -12, 1, -17, 0, 13, -24, -27, + 4, 35, 14, -22, 5, 13, -18, -30, -10, + -7, -7, 31, 23, -27, -26, 9, 47, 6, + -50, -11, 19, 1, 11, 12, -19, -43, -18, + 10, -6, -3, 12, 2, -12, -16, 10, 9, + -25, -21, -10, -13, 0, 8, -1, -9, 10, + 4, -34, 14, 46, 5, 18, 24, -15, -7, + 20, -1, -13, 7, 11, 14, 11, -2, 8, + 27, 10, -1, 13, -2, -7, 48, 44, -15, + -16, -6, 3, 7, -35, -25, 8, -31, -16, + 30, 36, 22, -13, -21, -10, 8, 2, -58, + -37, 32, 25, -1, -25, -21, 3, 3, -6, + -11, -3, 2, 4, 34, 22, -25, -19, 0, + -6, -10, -8, -35, -32, 8, -3, -20, -11, + -6, 3, 8, -8, 3, 25, 23, -7, -35, + -15, 8, -20, -6, 15, -44, -29, 19, -5, + -1, 18, 28, 6, -21, 9, 11, -20, -10, + 18, 22, 6, -2, 12, 6, 23, 34, -20, + -19, 1, -10, 34, 41, 13, 6, 3, 22, + 11, -4, 4, -12, -8, 17, 18, 12, -1, + 5, 9, -6, -2, 4, 1, 3, 2, -6, + -32, -25, 9, 18, 27, -4, -54, -29, 2, + -3, -18, -38, -28, -10, 9, 20, 5, -9, + -15, -3, 2, -14, -15, -6, 5, 10, 6, + 3, -11, -9, -5, -20, -13, 8, 3, -14, + 6, 20, -15, -21, 9, 19, 21, 12, -4, + -21, -17, 16, 27, -4, -28, -2, 26, 9, + -12, -16, -28, -28, -4, 4, -15, -9, 3, + -10, -16, 2, 17, -10, -26, 3, 16, 26, + 17, -12, -9, 2, -2, -5, -11, 5, 28, + 1, -14, 13, 14, 5, 18, 6, -17, -5, + 7, 2, -3, 11, 10, -1, 50, 36, -28, + 21, 39, -9, -6, 2, 10, 36, 20, -2, + -3, -11, -10, -6, -5, -4, -8, 2, 17, + 1, -13, 11, -13, -36, 11, 14, -19, -6, + 3, 0, 20, -5, -24, 12, 7, -11, 2, + -15, -28, -1, 6, -14, -31, -39, -19, 19, + 37, 3, -32, -27, -6, 13, 31, 15, -41, + -41, 25, 35, -3, -16, -25, -19, -10, -3, + 19, 10, -4, 7, -4, -19, -12, -13, -9, + 6, 2, -12, -6, 12, 6, -1, -5, -19, + -7, 7, 40, 56, -3, -13, 21, 24, 7, + -11, -9, -3, 24, 28, -10, 1, 12, 21, + 24, -16, -15, 4, -7, -2, 19, 13, -11, + -7, -8, 15, 41, 5, -16, -18, -11, 26, + 26, -5, -12, -14, -6, 10, 8, -8, -16, + -16, -3, 10, 1, -3, -3, -2, -15, -18, + 6, -4, -4, 21, 4, -2, 15, 13, 0, + -2, 12, 7, -15, -9, 1, -2, 2, -1, + -9, -15, -17, -14, -10, 1, -4, -16, -17, + -1, 18, 8, 1, 22, 11, -19, -10, 4, + -23, -29, 0, -2, -14, -6, 13, 7, -23, + -13, 10, 9, 11, 10, 4, -4, -4, 1, + 6, 14, 9, 2, 0, 2, 6, 4, -9, + -18, -8, 8, 18, 8, 13, 9, -27, -22, + -10, -24, -9, 17, 11, 2, 9, 3, -13, + -10, -1, -7, -1, 10, -4, 1, 16, 12, + -6, -14, -2, -5, -1, 0, -1, 6, -9, + -3, 12, 4, 1, -2, 2, 17, 24, 22, + 9, 8, 21, 14, -2, -2, 4, -1, -7, + -7, -6, -1, -6, 17, 30, -7, -10, -3, + -19, -18, 2, 21, 4, -20, -6, -1, -18, + -14, -6, -7, -1, 6, 10, 8, -5, 0, + 10, -22, -40, -22, 4, 34, 16, -19, -16, + -12, -17, -16, -17, -29, -28, -4, 10, 16, + 22, 13, 4, -1, -5, 16, 15, -11, -6, + 9, 3, -14, -22, -19, -12, 5, -5, -15, + 3, 9, 27, 17, -4, 8, -2, 1, 16, + 11, 9, 9, 8, -14, -16, 7, -5, -15, + -11, -5, 19, 25, 25, 43, 21, -9, -9, + -19, -10, 14, -11, -19, 8, 3, 1, 11, + -1, -24, -20, -1, 2, 7, 24, 22, 11, + 8, 6, -2, -11, -3, -2, -4, 0, -7, + 0, 6, -1, -16, -35, -8, 8, -11, -6, + 6, 18, 16, 7, 12, 5, -2, -3, -10, + -21, -27, -10, -3, -3, 8, 0, -9, -10, + -3, 0, -5, 6, 9, 19, 23, 8, -5, + -19, -16, -5, -6, -27, -22, 1, 6, 8, + 2, -9, -13, -15, -18, -13, 4, 25, 29, + 26, -2, -22, 1, 8, 1, -6, -6, -7, + -20, 0, 13, -14, -24, -24, -21, 2, 14, + 16, 23, 15, 10, 10, 5, 0, -26, -32, + 3, 19, 5, -8, -7, -8, -3, 17, 27, + -7, -28, 10, 32, 10, 1, 10, 3, -4, + 22, 24, -31, -40, 0, 6, 5, 17, 17, + 1, 10, 30, 8, -12, -6, 9, 6, -12, + -5, 1, -4, 6, 11, 0, -9, -4, -3, + -4, -3, 2, 0, -2, -9, -27, -23, 2, + 13, -6, -9, -3, -12, -2, 10, 6, -7, + -19, -31, -13, 16, 11, -3, -13, -15, 0, + 7, -3, -7, -1, -4, 7, 15, 0, -12, + -8, -1, -7, -12, -21, -17, 5, 30, 25, + -6, -6, 0, -12, -8, 2, 13, 11, 1, + 5, 4, 4, 10, -1, -20, -12, -4, 3, + 15, 11, -7, -24, -4, 8, -2, -14, -25, + -17, 7, 21, 14, 1, 0, 12, 17, 13, + 6, 1, 6, 14, 11, -10, -21, -12, -4, + 3, -2, -21, -24, -2, 12, 14, 17, 4, + -2, 11, 11, 11, 1, -34, -32, -5, 10, + 7, -11, -12, 6, 7, -4, -10, -15, -5, + 17, 21, 0, -15, -15, -1, 5, -18, -18, + -10, -9, 24, 27, -9, -14, 0, 9, 25, + 22, 1, -7, -2, 16, 13, -14, -10, 7, + 0, 2, 15, 2, -9, 5, 10, -5, -3, + 10, 3, 0, 15, 15, -1, -3, 8, 6, + -7, -7, 2, 0, -4, 5, -8, -37, -28, + -1, 8, 6, 10, -1, -12, 12, 28, 8, + -17, -16, -15, -17, 1, 6, -4, -8, -4, + -15, -15, 6, -9, -15, 10, 9, -13, -8, + 5, -2, -10, 5, 12, -27, -33, 9, 8, + -16, -3, 16, -3, -7, 22, 22, 10, 5, + -11, -16, -4, 9, 12, 6, -3, 2, 2, + -1, 4, -7, -8, 1, 8, 19, +}; diff --git a/micro_speech/src/yes_1000ms_sample_data.h b/micro_speech/src/yes_1000ms_sample_data.h new file mode 100644 index 0000000..5d09866 --- /dev/null +++ b/micro_speech/src/yes_1000ms_sample_data.h @@ -0,0 +1,29 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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. +==============================================================================*/ + +// This data was created from the PCM data in a WAV file held in v2 of the +// Speech Commands test dataset, at the path: +// speech_commands_test_set_v0.02/yes/f2e59fea_nohash_1.wav +// This should contain all 16,000 samples from the one-second file. + +#ifndef TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_YES_1000MS_SAMPLE_DATA_H_ +#define TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_YES_1000MS_SAMPLE_DATA_H_ + +#include + +extern const int g_yes_1000ms_sample_data_size; +extern const int16_t g_yes_1000ms_sample_data[]; + +#endif // TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_YES_1000MS_SAMPLE_DATA_H_ diff --git a/micro_speech/src/yes_30ms_sample_data.cc b/micro_speech/src/yes_30ms_sample_data.cc new file mode 100644 index 0000000..56eafa0 --- /dev/null +++ b/micro_speech/src/yes_30ms_sample_data.cc @@ -0,0 +1,70 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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. +==============================================================================*/ + +// See the header for documentation on the meaning of this data. + +#include "yes_30ms_sample_data.h" + +const int g_yes_30ms_sample_data_size = 480; +const int16_t g_yes_30ms_sample_data[480] = { + -876, -470, 510, 803, 170, -787, -1568, -1893, -1598, -1027, + -992, -1803, -2610, -2484, -1905, -2113, -3113, -3399, -2267, -1261, + -2007, -3637, -3909, -2340, -893, -1158, -2272, -2486, -1639, -915, + -777, -596, -91, 196, 85, 210, 875, 1373, 1247, 1219, + 1958, 2718, 2328, 1196, 1008, 2350, 3677, 3269, 1503, 366, + 922, 2264, 2810, 1996, 608, -168, 75, 680, 811, 395, + -56, -318, -607, -966, -1108, -925, -613, -368, -369, -919, + -1926, -2460, -1685, -300, 155, -611, -1524, -2204, -3227, -3859, + -2037, 1622, 2382, -2583, -8448, -7544, -84, 4814, 915, -6423, + -7558, -1746, 2515, -59, -4587, -3858, 1260, 3625, 187, -4148, + -3500, 1542, 5467, 4780, 1256, -1127, -403, 2481, 5332, 6346, + 5014, 2536, 1216, 2467, 5039, 6238, 5070, 3381, 3269, 4173, + 3905, 2248, 1586, 3299, 5240, 4362, 1004, -1382, -489, 2113, + 3168, 1620, -742, -1824, -1435, -897, -1058, -1500, -1545, -1398, + -1965, -3266, -4136, -3756, -2609, -1804, -1986, -3087, -4599, -5296, + -4051, -1731, -781, -2228, -4092, -3977, -2325, -1353, -1568, -1490, + -428, 178, -672, -1650, -1058, 749, 2039, 2079, 1540, 897, + 310, 572, 2266, 4265, 4265, 1869, -231, 559, 3332, 4752, + 3229, 768, 101, 1364, 2463, 1984, 819, 411, 723, 675, + -162, -923, -743, -32, 185, -516, -1653, -2359, -2103, -986, + 42, -205, -1702, -2870, -2337, -809, -221, -982, -1544, -946, + -598, -2117, -4291, -4100, -857, 1948, 338, -4799, -7972, -5403, + 173, 2371, -1063, -5533, -5578, -1777, 605, -985, -3249, -2213, + 1184, 2691, 560, -2356, -2288, 1233, 5244, 6441, 4004, 370, + -663, 2555, 7404, 9282, 6573, 2612, 1836, 4662, 7467, 7393, + 5421, 4262, 4741, 5362, 4705, 3163, 2397, 3337, 4887, 4810, + 2254, -749, -1316, 772, 2706, 2016, -573, -2552, -2746, -2012, + -1647, -1978, -2579, -3105, -3473, -3911, -4484, -4891, -4795, -4163, + -3543, -3538, -4275, -5356, -5743, -4637, -2614, -1301, -1825, -3341, + -4011, -2937, -751, 1007, 1245, 235, -639, -61, 1626, 2864, + 2967, 2734, 3013, 3329, 2914, 2312, 2666, 3839, 4308, 3162, + 1453, 768, 1255, 1887, 2006, 1715, 1031, -297, -1660, -1690, + -277, 813, -30, -2137, -3370, -2854, -1553, -593, -413, -1146, + -2567, -3440, -2369, -205, 379, -1258, -2315, -812, 262, -3205, + -8576, -7894, 738, 7492, 1951, -11595, -17098, -6934, 7139, 8065, + -4575, -14199, -8946, 3606, 7504, -547, -8242, -5113, 4406, 8113, + 2134, -5040, -4089, 4157, 10934, 10158, 4167, -565, -192, 4428, + 9765, 12201, 9861, 4512, 1225, 3451, 8483, 10133, 6497, 2574, + 3333, 6806, 6986, 2487, -1214, 623, 5416, 6647, 2204, -3289, + -4556, -1565, 1544, 1525, -1236, -4293, -5695, -5174, -3995, -3403, + -3449, -3750, -4505, -6014, -7296, -6523, -3849, -2096, -3288, -5722, + -6004, -3581, -1497, -1960, -3330, -2800, -434, 964, -111, -1739, + -1136, 1736, 4151, 3736, 1274, -451, 469, 3386, 5833, 5898, + 3646, 1085, 272, 1743, 4061, 5108, 3837, 1490, 246, 967, + 1866, 859, -1069, -974, 1542, 2835, 47, -4285, -5068, -1567, + 1781, 1223, -1997, -4227, -3747, -1720, 41, 245, -1228, -2972, + -2673, 22, 1980, -930, -7721, -11271, -5725, 4974, 8484, -2007, + -16979, -19255, -4670, 11057, 9690, -6417, -17537, -10841, 4262, 9292, +}; diff --git a/micro_speech/src/yes_30ms_sample_data.h b/micro_speech/src/yes_30ms_sample_data.h new file mode 100644 index 0000000..cfe201a --- /dev/null +++ b/micro_speech/src/yes_30ms_sample_data.h @@ -0,0 +1,32 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.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. +==============================================================================*/ + +// This data was created from the PCM data in a WAV file held in v2 of the +// Speech Commands test dataset, at the path: +// speech_commands_test_set_v0.02/yes/f2e59fea_nohash_1.wav +// The data was extracted starting at an offset of 8,000, which corresponds to +// the 26th spectrogram slice. It's designed to be used to test the +// preprocessing pipeline, to ensure that the expected spectrogram slice is +// produced given this input. + +#ifndef TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_YES_30MS_SAMPLE_DATA_H_ +#define TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_YES_30MS_SAMPLE_DATA_H_ + +#include + +extern const int g_yes_30ms_sample_data_size; +extern const int16_t g_yes_30ms_sample_data[]; + +#endif // TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_YES_30MS_SAMPLE_DATA_H_