From 621d0aa942f8ccfaac6166f53abbc64913eca563 Mon Sep 17 00:00:00 2001 From: laokaiyao Date: Wed, 18 Aug 2021 19:45:51 +0800 Subject: [PATCH 1/3] i2s: Introduced a brand new driver --- components/driver/CMakeLists.txt | 10 +- components/driver/Kconfig | 18 +- components/driver/adc.c | 5 +- .../{include => deprecated}/driver/i2s.h | 144 +-- .../deprecated/driver/i2s_types_legacy.h | 232 +++++ components/driver/i2s/i2s_common.c | 963 ++++++++++++++++++ components/driver/{i2s.c => i2s/i2s_legacy.c} | 317 +++--- components/driver/i2s/i2s_pdm.c | 533 ++++++++++ components/driver/i2s/i2s_private.h | 131 +++ components/driver/i2s/i2s_std.c | 315 ++++++ components/driver/i2s/i2s_tdm.c | 317 ++++++ components/driver/include/driver/i2s_common.h | 266 +++++ .../hal => driver/include/driver}/i2s_pdm.h | 42 +- .../hal => driver/include/driver}/i2s_std.h | 47 +- .../hal => driver/include/driver}/i2s_tdm.h | 37 +- .../driver/include/esp_private/i2s_platform.h | 17 +- .../driver/test/adc_dma_test/test_esp32.c | 159 --- .../driver/test/dac_dma_test/test_esp32.c | 161 --- components/driver/test/test_adc2_with_wifi.c | 74 +- components/driver/test/test_dac.c | 3 +- .../driver/test_apps/i2s/CMakeLists.txt | 5 + components/driver/test_apps/i2s/app_test.py | 30 + .../driver/test_apps/i2s/main/CMakeLists.txt | 16 + .../driver/test_apps/i2s/main/test_app_main.c | 53 + .../test_apps/i2s/main/test_i2s_controller.c | 512 ++++++++++ .../i2s/main/test_i2s_legacy.c} | 37 +- .../driver/test_apps/i2s/sdkconfig.defaults | 3 + components/esp_hw_support/clk_ctrl_os.c | 2 +- .../esp_hw_support/include/clk_ctrl_os.h | 1 + components/esp_lcd/src/esp_lcd_panel_io_i2s.c | 10 +- .../i80_lcd/main/test_i80_lcd_panel.c | 66 +- components/hal/adc_hal.c | 2 +- components/hal/esp32/include/hal/i2s_ll.h | 1 - components/hal/esp32c3/include/hal/i2s_ll.h | 2 +- components/hal/esp32h2/include/hal/i2s_ll.h | 2 +- components/hal/esp32s3/include/hal/i2s_ll.h | 4 +- components/hal/i2s_hal.c | 123 +-- components/hal/include/hal/i2s_hal.h | 84 +- components/hal/include/hal/i2s_types.h | 259 ++--- components/hal/include/hal/i2s_types_priv.h | 116 --- .../diagrams/i2s/i2s_file_structure.png | Bin 0 -> 64258 bytes .../diagrams/i2s/i2s_state_machine.png | Bin 0 -> 55870 bytes docs/_static/diagrams/i2s/pdm.png | Bin 0 -> 81899 bytes docs/_static/diagrams/i2s/std_msb.png | Bin 0 -> 23008 bytes docs/_static/diagrams/i2s/std_pcm.png | Bin 0 -> 20415 bytes docs/_static/diagrams/i2s/std_philip.png | Bin 0 -> 19028 bytes docs/_static/diagrams/i2s/tdm_msb.png | Bin 0 -> 73090 bytes docs/_static/diagrams/i2s/tdm_pcm_long.png | Bin 0 -> 63728 bytes docs/_static/diagrams/i2s/tdm_pcm_short.png | Bin 0 -> 71424 bytes docs/_static/diagrams/i2s/tdm_philip.png | Bin 0 -> 80203 bytes docs/doxygen/Doxyfile | 4 + docs/en/api-reference/peripherals/i2s.rst | 812 ++++++++++----- docs/en/migration-guides/peripherals.rst | 62 +- .../classic_bt/a2dp_sink/main/bt_app_av.c | 45 +- .../classic_bt/a2dp_sink/main/bt_app_core.c | 12 + .../classic_bt/a2dp_sink/main/main.c | 1 - .../classic_bt/a2dp_sink/sdkconfig.defaults | 1 + .../a2dp_sink/tutorial/Example_A2DP_Sink.md | 53 +- .../coex/a2dp_gatts_coex/main/bt_app_av.c | 13 + .../coex/a2dp_gatts_coex/main/bt_app_core.c | 16 +- .../coex/a2dp_gatts_coex/main/main.c | 54 +- .../coex/a2dp_gatts_coex/sdkconfig.defaults | 1 + .../i2s/i2s_adc_dac/main/app_main.c | 11 +- .../i2s/i2s_adc_dac/main/audio_example_file.h | 5 + .../i2s/i2s_adc_dac/sdkconfig.defaults | 5 + .../i2s_adc_dac/tools/generate_audio_file.py | 2 + .../main/i2s_recorder_main.c | 65 +- .../i2s/i2s_basic/main/i2s_example_main.c | 123 +-- examples/peripherals/i2s/i2s_es8311/README.md | 2 +- .../i2s/i2s_es8311/main/i2s_es8311_example.c | 72 +- tools/ci/check_copyright_ignore.txt | 5 - 71 files changed, 4934 insertions(+), 1549 deletions(-) rename components/driver/{include => deprecated}/driver/i2s.h (66%) create mode 100644 components/driver/deprecated/driver/i2s_types_legacy.h create mode 100644 components/driver/i2s/i2s_common.c rename components/driver/{i2s.c => i2s/i2s_legacy.c} (86%) create mode 100644 components/driver/i2s/i2s_pdm.c create mode 100644 components/driver/i2s/i2s_private.h create mode 100644 components/driver/i2s/i2s_std.c create mode 100644 components/driver/i2s/i2s_tdm.c create mode 100644 components/driver/include/driver/i2s_common.h rename components/{hal/include/hal => driver/include/driver}/i2s_pdm.h (88%) rename components/{hal/include/hal => driver/include/driver}/i2s_std.h (80%) rename components/{hal/include/hal => driver/include/driver}/i2s_tdm.h (81%) delete mode 100644 components/driver/test/adc_dma_test/test_esp32.c delete mode 100644 components/driver/test/dac_dma_test/test_esp32.c create mode 100644 components/driver/test_apps/i2s/CMakeLists.txt create mode 100644 components/driver/test_apps/i2s/app_test.py create mode 100644 components/driver/test_apps/i2s/main/CMakeLists.txt create mode 100644 components/driver/test_apps/i2s/main/test_app_main.c create mode 100644 components/driver/test_apps/i2s/main/test_i2s_controller.c rename components/driver/{test/test_i2s.c => test_apps/i2s/main/test_i2s_legacy.c} (97%) create mode 100644 components/driver/test_apps/i2s/sdkconfig.defaults delete mode 100644 components/hal/include/hal/i2s_types_priv.h create mode 100644 docs/_static/diagrams/i2s/i2s_file_structure.png create mode 100644 docs/_static/diagrams/i2s/i2s_state_machine.png create mode 100644 docs/_static/diagrams/i2s/pdm.png create mode 100644 docs/_static/diagrams/i2s/std_msb.png create mode 100644 docs/_static/diagrams/i2s/std_pcm.png create mode 100644 docs/_static/diagrams/i2s/std_philip.png create mode 100644 docs/_static/diagrams/i2s/tdm_msb.png create mode 100644 docs/_static/diagrams/i2s/tdm_pcm_long.png create mode 100644 docs/_static/diagrams/i2s/tdm_pcm_short.png create mode 100644 docs/_static/diagrams/i2s/tdm_philip.png create mode 100644 examples/peripherals/i2s/i2s_adc_dac/sdkconfig.defaults diff --git a/components/driver/CMakeLists.txt b/components/driver/CMakeLists.txt index 168619a024..001e650415 100644 --- a/components/driver/CMakeLists.txt +++ b/components/driver/CMakeLists.txt @@ -58,7 +58,15 @@ if(CONFIG_SOC_SDMMC_HOST_SUPPORTED) endif() if(CONFIG_SOC_I2S_SUPPORTED) - list(APPEND srcs "i2s.c") + list(APPEND srcs "i2s/i2s_common.c" + "i2s/i2s_std.c" + "i2s/i2s_legacy.c") + if(CONFIG_SOC_I2S_SUPPORTS_PDM) + list(APPEND srcs "i2s/i2s_pdm.c") + endif() + if(CONFIG_SOC_I2S_SUPPORTS_TDM) + list(APPEND srcs "i2s/i2s_tdm.c") + endif() endif() if(CONFIG_SOC_TEMP_SENSOR_SUPPORTED) diff --git a/components/driver/Kconfig b/components/driver/Kconfig index 93c0c97c1d..97125ebe23 100644 --- a/components/driver/Kconfig +++ b/components/driver/Kconfig @@ -305,4 +305,20 @@ menu "Driver Configurations" endmenu # MCPWM Configuration -endmenu # Driver Configurations + menu "I2S Configuration" + depends on SOC_I2S_SUPPORTED + config I2S_ISR_IRAM_SAFE + bool "I2S ISR IRAM-Safe" + default n + help + Ensure the I2S interrupt is IRAM-Safe by allowing the interrupt handler to be + executable when the cache is disabled (e.g. SPI Flash write). + + config I2S_SUPPRESS_DEPRECATE_WARN + bool "Suppress leagcy driver deprecated warning" + default n + help + Enable this option will suppress the deprecation warnings of using APIs in deprecated I2S driver. + endmenu # I2S Configuration + +endmenu # Driver configurations diff --git a/components/driver/adc.c b/components/driver/adc.c index 850089dc2f..fc88e89ce4 100644 --- a/components/driver/adc.c +++ b/components/driver/adc.c @@ -37,7 +37,6 @@ #include "hal/spi_types.h" #include "driver/spi_common_internal.h" #elif CONFIG_IDF_TARGET_ESP32 -#include "driver/i2s.h" #include "hal/i2s_types.h" #include "soc/i2s_periph.h" #include "esp_private/i2s_platform.h" @@ -259,7 +258,7 @@ esp_err_t adc_digi_initialize(const adc_digi_init_config_t *init_config) #elif CONFIG_IDF_TARGET_ESP32 //ADC utilises I2S0 DMA on ESP32 uint32_t dma_chan = 0; - ret = i2s_priv_register_object(&s_adc_digi_ctx, I2S_NUM_0); + ret = i2s_platform_acquire_occupation(I2S_NUM_0, "adc"); if (ret != ESP_OK) { goto cleanup; } @@ -541,7 +540,7 @@ esp_err_t adc_digi_deinitialize(void) spicommon_periph_free(s_adc_digi_ctx->spi_host); #elif CONFIG_IDF_TARGET_ESP32 esp_intr_free(s_adc_digi_ctx->intr_hdl); - i2s_priv_deregister_object(s_adc_digi_ctx->i2s_host); + i2s_platform_release_occupation(s_adc_digi_ctx->i2s_host); #endif free(s_adc_digi_ctx); s_adc_digi_ctx = NULL; diff --git a/components/driver/include/driver/i2s.h b/components/driver/deprecated/driver/i2s.h similarity index 66% rename from components/driver/include/driver/i2s.h rename to components/driver/deprecated/driver/i2s.h index 81ac4f2aea..94011c61e9 100644 --- a/components/driver/include/driver/i2s.h +++ b/components/driver/deprecated/driver/i2s.h @@ -4,147 +4,37 @@ * SPDX-License-Identifier: Apache-2.0 */ +/** + * This file is for the backward compatible to the deprecated I2S APIs, + * The deprecated APIs will no longer supported in the future + * Please refer to "driver/i2s_controller.h" for the latest I2S driver + * Note that only one set of I2S APIs is allowed to be used at the same time + */ + #pragma once #include "esp_types.h" #include "esp_err.h" #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" -#include "soc/soc_caps.h" -#include "hal/i2s_types.h" -#include "esp_intr_alloc.h" +#include "soc/i2s_periph.h" +#include "driver/i2s_types_legacy.h" #if SOC_I2S_SUPPORTS_ADC #include "driver/adc.h" #endif +#if !CONFIG_I2S_SUPPRESS_DEPRECATE_WARN +#warning "This set of I2S APIs has been deprecated, \ +please include 'driver/i2s_std.h', 'driver/i2s_pdm' or 'driver/i2s_tdm' instead. \ +if you want to keep using the old APIs and ignore this warning, \ +you can enable 'Suppress leagcy driver deprecated warning' option under 'I2S Configuration' menu in Kconfig" +#endif + #ifdef __cplusplus extern "C" { #endif -#define I2S_PIN_NO_CHANGE (-1) /*!< Use in i2s_pin_config_t for pins which should not be changed */ - -/** - * @brief I2S port number, the max port number is (I2S_NUM_MAX -1). - */ -typedef enum { - I2S_NUM_0 = 0, /*!< I2S port 0 */ -#if SOC_I2S_NUM > 1 - I2S_NUM_1 = 1, /*!< I2S port 1 */ -#endif - I2S_NUM_MAX, /*!< I2S port max */ -} i2s_port_t; - -#if SOC_I2S_SUPPORTS_PCM -/** - * @brief I2S PCM configuration - * - */ -typedef struct { - i2s_pcm_compress_t pcm_type; /*!< I2S PCM a/u-law decompress or compress type */ -} i2s_pcm_cfg_t; -#endif - -#if SOC_I2S_SUPPORTS_PDM_TX -/** - * @brief Default I2S PDM Up-Sampling Rate configuration - */ -#define I2S_PDM_DEFAULT_UPSAMPLE_CONFIG(rate) { \ - .sample_rate = rate, \ - .fp = 960, \ - .fs = (rate) / 100, \ - } - -/** - * @brief I2S PDM up-sample rate configuration - * @note TX PDM can only be set to the following two upsampling rate configurations: - * 1: fp = 960, fs = sample_rate / 100, in this case, Fpdm = 128*48000 - * 2: fp = 960, fs = 480, in this case, Fpdm = 128*Fpcm = 128*sample_rate - * If the pdm receiver do not care the pdm serial clock, it's recommended set Fpdm = 128*48000. - * Otherwise, the second configuration should be applied. - */ -typedef struct { - int sample_rate; /*!< I2S PDM sample rate */ - int fp; /*!< I2S PDM TX upsampling paramater. Normally it should be set to 960 */ - int fs; /*!< I2S PDM TX upsampling paramater. When it is set to 480, the pdm clock frequency Fpdm = 128 * sample_rate, when it is set to sample_rate / 100, Fpdm will be fixed to 128*48000 */ -} i2s_pdm_tx_upsample_cfg_t; -#endif - -/** - * @brief I2S pin number for i2s_set_pin - * - */ -typedef struct { - int mck_io_num; /*!< MCK in out pin. Note that ESP32 supports setting MCK on GPIO0/GPIO1/GPIO3 only*/ - int bck_io_num; /*!< BCK in out pin*/ - int ws_io_num; /*!< WS in out pin*/ - int data_out_num; /*!< DATA out pin*/ - int data_in_num; /*!< DATA in pin*/ -} i2s_pin_config_t; - -/** - * @brief I2S driver configuration parameters - * - */ -typedef struct { - - i2s_mode_t mode; /*!< I2S work mode */ - uint32_t sample_rate; /*!< I2S sample rate */ - i2s_bits_per_sample_t bits_per_sample; /*!< I2S sample bits in one channel */ - i2s_channel_fmt_t channel_format; /*!< I2S channel format.*/ - i2s_comm_format_t communication_format; /*!< I2S communication format */ - int intr_alloc_flags; /*!< Flags used to allocate the interrupt. One or multiple (ORred) ESP_INTR_FLAG_* values. See esp_intr_alloc.h for more info */ - union { - int dma_desc_num; /*!< The total number of descriptors used by I2S DMA to receive/transmit data */ - int dma_buf_count __attribute__((deprecated)); /*!< This is an alias to 'dma_desc_num' for backward compatibility */ - }; - union { - int dma_frame_num; /*!< Number of frames for one-time sampling. The frame here means the total data from all the channels in a WS cycle */ - int dma_buf_len __attribute__((deprecated)); /*!< This is an alias to 'dma_frame_num' for backward compatibility */ - }; - - bool use_apll; /*!< I2S using APLL as main I2S clock, enable it to get accurate clock */ - bool tx_desc_auto_clear; /*!< I2S auto clear tx descriptor if there is underflow condition (helps in avoiding noise in case of data unavailability) */ - int fixed_mclk; /*!< I2S using fixed MCLK output. If use_apll = true and fixed_mclk > 0, then the clock output for i2s is fixed and equal to the fixed_mclk value. If fixed_mclk set, mclk_multiple won't take effect */ - i2s_mclk_multiple_t mclk_multiple; /*!< The multiple of I2S master clock(MCLK) to sample rate */ - i2s_bits_per_chan_t bits_per_chan; /*!< I2S total bits in one channel, only take effect when larger than 'bits_per_sample', default '0' means equal to 'bits_per_sample' */ - -#if SOC_I2S_SUPPORTS_TDM - i2s_channel_t chan_mask; /*!< I2S active channel bit mask, set value in `i2s_channel_t` to enable specific channel, the bit map of active channel can not exceed (0x1< 0, then the clock output for i2s is fixed and equal to the fixed_mclk value. If fixed_mclk set, mclk_multiple won't take effect */ + i2s_mclk_multiple_t mclk_multiple; /*!< The multiple of I2S master clock(MCLK) to sample rate */ + i2s_bits_per_chan_t bits_per_chan; /*!< I2S total bits in one channel, only take effect when larger than 'bits_per_sample', default '0' means equal to 'bits_per_sample' */ + +#if SOC_I2S_SUPPORTS_TDM + i2s_channel_t chan_mask; /*!< I2S active channel bit mask, set value in `i2s_channel_t` to enable specific channel, the bit map of active channel can not exceed (0x1< +#include + +#include "freertos/FreeRTOS.h" +#include "freertos/queue.h" +#include "freertos/task.h" +#include "soc/i2s_periph.h" +#include "soc/soc_caps.h" +#include "soc/soc.h" +#include "hal/gpio_hal.h" +#include "hal/i2s_hal.h" + +#if SOC_I2S_SUPPORTS_ADC_DAC +#include "hal/adc_ll.h" +#endif +#if SOC_I2S_SUPPORTS_APLL +#include "clk_ctrl_os.h" +#endif + +#include "esp_private/i2s_platform.h" +#include "esp_private/periph_ctrl.h" + +#include "driver/gpio.h" +#include "driver/i2s_common.h" +#include "i2s_private.h" + +#include "clk_ctrl_os.h" +#include "esp_intr_alloc.h" +#include "esp_check.h" +#include "esp_attr.h" + +// // #include "esp_efuse.h" +#include "esp_rom_gpio.h" + +#include "sdkconfig.h" + +#define I2S_DMA_BUFFER_MAX_SIZE (4092) + +// If ISR handler is allowed to run whilst cache is disabled, +// Make sure all the code and related variables used by the handler are in the SRAM +#if CONFIG_I2S_ISR_IRAM_SAFE +#define I2S_INTR_ALLOC_FLAGS (ESP_INTR_FLAG_IRAM | ESP_INTR_FLAG_INTRDISABLED | ESP_INTR_FLAG_SHARED) +#define I2S_MEM_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT) +#else +#define I2S_INTR_ALLOC_FLAGS (ESP_INTR_FLAG_INTRDISABLED | ESP_INTR_FLAG_SHARED) +#define I2S_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT +#endif //CONFIG_I2S_ISR_IRAM_SAFE + +/** + * @brief Static i2s platform object + * @note For saving all the I2S related information + */ +i2s_platform_t s_i2s = { + .spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED, + .controller[0 ... (I2S_NUM_MAX - 1)] = NULL, // groups will be lazy installed + .comp_name[0 ... (I2S_NUM_MAX - 1)] = NULL, +}; + +static const char *TAG = "I2S_COMMON"; + +/*--------------------------------------------------------------------------- + I2S Static APIs + ---------------------------------------------------------------------------- + Scope: This file only + ----------------------------------------------------------------------------*/ + +static void i2s_tx_start(i2s_chan_handle_t handle) +{ + /* No lock here beacuse semaphore has been taken while calling this function */ + i2s_hal_tx_reset(&(handle->parent->hal)); + i2s_hal_tx_reset_fifo(&(handle->parent->hal)); +#if SOC_GDMA_SUPPORTED + gdma_reset(handle->dma.dma_chan); + gdma_start(handle->dma.dma_chan, (uint32_t) handle->dma.desc[0]); +#else + i2s_hal_tx_reset_dma(&(handle->parent->hal)); + i2s_hal_tx_enable_intr(&(handle->parent->hal)); + i2s_hal_tx_start_link(&(handle->parent->hal), (uint32_t) handle->dma.desc[0]); +#endif + i2s_hal_tx_start(&(handle->parent->hal)); +} + +static void i2s_rx_start(i2s_chan_handle_t handle) +{ + /* No lock here beacuse semaphore has been taken while calling this function */ + i2s_hal_rx_reset(&(handle->parent->hal)); + i2s_hal_rx_reset_fifo(&(handle->parent->hal)); +#if SOC_GDMA_SUPPORTED + gdma_reset(handle->dma.dma_chan); + gdma_start(handle->dma.dma_chan, (uint32_t) handle->dma.desc[0]); +#else + i2s_hal_rx_reset_dma(&(handle->parent->hal)); + i2s_hal_rx_enable_intr(&(handle->parent->hal)); + i2s_hal_rx_start_link(&(handle->parent->hal), (uint32_t) handle->dma.desc[0]); +#endif + i2s_hal_rx_start(&(handle->parent->hal)); +} + +static void i2s_tx_stop(i2s_chan_handle_t handle) +{ + /* No lock here beacuse semaphore has been taken while calling this function */ +#if SOC_GDMA_SUPPORTED + i2s_hal_tx_stop(&(handle->parent->hal)); + gdma_stop(handle->dma.dma_chan); +#else + i2s_hal_tx_stop(&(handle->parent->hal)); + i2s_hal_tx_stop_link(&(handle->parent->hal)); + i2s_hal_tx_disable_intr(&(handle->parent->hal)); +#endif +} + +static void i2s_rx_stop(i2s_chan_handle_t handle) +{ + /* No lock here beacuse semaphore has been taken while calling this function */ +#if SOC_GDMA_SUPPORTED + i2s_hal_rx_stop(&(handle->parent->hal)); + gdma_stop(handle->dma.dma_chan); +#else + i2s_hal_rx_stop(&(handle->parent->hal)); + i2s_hal_rx_stop_link(&(handle->parent->hal)); + i2s_hal_rx_disable_intr(&(handle->parent->hal)); +#endif +} + +static esp_err_t i2s_destroy_controller_obj(i2s_controller_t **i2s_obj) +{ + I2S_NULL_POINTER_CHECK(TAG, i2s_obj); + I2S_NULL_POINTER_CHECK(TAG, *i2s_obj); + ESP_RETURN_ON_FALSE(!(*i2s_obj)->rx_chan && !(*i2s_obj)->tx_chan, + ESP_ERR_INVALID_STATE, TAG, + "there still have channels under this i2s controller"); + int id = (*i2s_obj)->id; +#if SOC_I2S_HW_VERSION_1 + i2s_ll_enable_dma((*i2s_obj)->hal.dev, false); + esp_intr_disable((*i2s_obj)->i2s_isr_handle); + esp_intr_free((*i2s_obj)->i2s_isr_handle); +#endif + free(*i2s_obj); + *i2s_obj = NULL; + return i2s_platform_release_occupation(id); +} + +/** + * @brief Acquire i2s controller object + * + * @param id i2s port id + * @param search_reverse reverse the sequence of port acquirement + * set false to acquire from I2S_NUM_0 first + * set true to acquire from I2S_NUM_MAX - 1 first + * @return + * - pointer of acquired i2s controller object + */ +static i2s_controller_t *i2s_acquire_controller_obj(int id) +{ + if (id < 0 || id >= I2S_NUM_MAX) { + return NULL; + } + /* pre-alloc controller object */ + i2s_controller_t *pre_alloc = (i2s_controller_t *)heap_caps_calloc(1, sizeof(i2s_controller_t), I2S_MEM_ALLOC_CAPS); + if (pre_alloc == NULL) { + return NULL; + } + pre_alloc->id = id; + i2s_hal_init(&pre_alloc->hal, id); +#if !SOC_GDMA_SUPPORTED + pre_alloc->i2s_isr_handle = NULL; +#endif + pre_alloc->full_duplex = false; + pre_alloc->tx_chan = NULL; + pre_alloc->rx_chan = NULL; + pre_alloc->mclk = I2S_GPIO_UNUSED; + + i2s_controller_t *i2s_obj = NULL; + if (!s_i2s.controller[id]) { + /* Try to occupy this i2s controller + if failed, this controller could be occupied by other components */ + if (i2s_platform_acquire_occupation(id, "i2s_controller") == ESP_OK) { + i2s_obj = pre_alloc; + portENTER_CRITICAL(&s_i2s.spinlock); + s_i2s.controller[id] = i2s_obj; + portEXIT_CRITICAL(&s_i2s.spinlock); + #if SOC_I2S_SUPPORTS_ADC_DAC + if (id == I2S_NUM_0) { + adc_ll_digi_set_data_source(ADC_I2S_DATA_SRC_IO_SIG); + } + #endif + } else { + free(pre_alloc); + ESP_LOGE(TAG, "i2s%d might be occupied by other component", id); + } + } else { + i2s_obj = s_i2s.controller[id]; + free(pre_alloc); + } + + return i2s_obj; +} + +static inline bool i2s_take_available_channel(i2s_controller_t *i2s_obj, uint8_t chan_search_mask) +{ + bool is_available = false; + +#if SOC_I2S_HW_VERSION_1 + /* In ESP32 and ESP32-S2, tx channel and rx channel are not totally separated + * Take both two channels in case one channel can affect another + */ + chan_search_mask = I2S_DIR_RX | I2S_DIR_TX; +#endif + portENTER_CRITICAL(&s_i2s.spinlock); + if (!(chan_search_mask & i2s_obj->chan_occupancy)) { + i2s_obj->chan_occupancy |= chan_search_mask; + is_available = true; + } + portEXIT_CRITICAL(&s_i2s.spinlock); + return is_available; +} + +static esp_err_t i2s_register_channel(i2s_controller_t *i2s_obj, i2s_dir_t dir) +{ + I2S_NULL_POINTER_CHECK(TAG, i2s_obj); + + i2s_chan_handle_t new_chan = (i2s_chan_handle_t)heap_caps_calloc(1, sizeof(struct i2s_channel_t), I2S_MEM_ALLOC_CAPS); + ESP_RETURN_ON_FALSE(new_chan, ESP_ERR_NO_MEM, TAG, "No memory for new channel"); + new_chan->mode = I2S_COMM_MODE_NONE; + new_chan->role = I2S_ROLE_MASTER; // Set default role to master + new_chan->dir = dir; + new_chan->state = I2S_CHAN_STATE_REGISTER; +#if SOC_I2S_SUPPORTS_APLL + new_chan->apll_en = false; +#endif + new_chan->mode_info = NULL; + new_chan->parent = i2s_obj; + new_chan->event_queue = NULL; + new_chan->pm_lock = NULL; // Init in i2s_set_clock according to clock source + new_chan->msg_queue = NULL; + new_chan->mutex = xSemaphoreCreateMutex(); + new_chan->start = NULL; + new_chan->stop = NULL; + + if (!new_chan->mutex) { + ESP_LOGE(TAG, "mutex create failed"); + free(new_chan); + return ESP_ERR_NO_MEM; + } + if (dir == I2S_DIR_TX) { + if (i2s_obj->tx_chan) { + i2s_del_channel(i2s_obj->tx_chan); + } + i2s_obj->tx_chan = new_chan; + + } else { + if (i2s_obj->rx_chan) { + i2s_del_channel(i2s_obj->rx_chan); + } + i2s_obj->rx_chan = new_chan; + } + return ESP_OK; +} + +uint32_t i2s_get_buf_size(i2s_chan_handle_t handle, uint32_t data_bit_width, uint32_t dma_frame_num) +{ + uint32_t active_chan = handle->active_slot; + uint32_t bytes_per_sample = ((data_bit_width + 15) / 16) * 2; + uint32_t bytes_per_frame = bytes_per_sample * active_chan; + uint32_t bufsize = dma_frame_num * bytes_per_frame; + /* Limit DMA buffer size if it is out of range (DMA buffer limitation is 4092 bytes) */ + if (bufsize > I2S_DMA_BUFFER_MAX_SIZE) { + uint32_t frame_num = I2S_DMA_BUFFER_MAX_SIZE / bytes_per_frame; + bufsize = frame_num * bytes_per_frame; + ESP_LOGW(TAG, "dma frame num is out of dma buffer size, limited to %d", frame_num); + } + return bufsize; +} + +esp_err_t i2s_free_dma_desc(i2s_chan_handle_t handle) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + if (!handle->dma.desc) { + return ESP_OK; + } + for (int i = 0; i < handle->dma.desc_num; i++) { + if (handle->dma.bufs[i]) { + free(handle->dma.bufs[i]); + } + if (handle->dma.desc[i]) { + free(handle->dma.desc[i]); + } + } + free(handle->dma.bufs); + free(handle->dma.desc); + handle->dma.desc = NULL; + + return ESP_OK; +} + +esp_err_t i2s_alloc_dma_desc(i2s_chan_handle_t handle, uint32_t num, uint32_t bufsize) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + esp_err_t ret = ESP_OK; + ESP_RETURN_ON_FALSE(bufsize <= I2S_DMA_BUFFER_MAX_SIZE, ESP_ERR_INVALID_ARG, TAG, "dma buffer can't be bigger than %d", I2S_DMA_BUFFER_MAX_SIZE); + handle->dma.desc_num = num; + handle->dma.buf_size = bufsize; + + handle->msg_queue = xQueueCreate(num, sizeof(uint8_t *)); + ESP_GOTO_ON_FALSE(handle->msg_queue, ESP_ERR_NO_MEM, err, TAG, "message queue create failed"); + + handle->dma.desc = (lldesc_t **)heap_caps_calloc(num, sizeof(lldesc_t *), I2S_MEM_ALLOC_CAPS); + ESP_GOTO_ON_FALSE(handle->dma.desc, ESP_ERR_NO_MEM, err, TAG, "create I2S DMA decriptor array failed"); + handle->dma.bufs = (uint8_t **)heap_caps_calloc(num, sizeof(uint8_t *), I2S_MEM_ALLOC_CAPS); + for (int i = 0; i < num; i++) { + /* Allocate DMA descriptor */ + handle->dma.desc[i] = (lldesc_t *) heap_caps_calloc(1, sizeof(lldesc_t), MALLOC_CAP_DMA); + ESP_GOTO_ON_FALSE(handle->dma.desc[i], ESP_ERR_NO_MEM, err, TAG, "allocate DMA description failed"); + handle->dma.desc[i]->owner = 1; + handle->dma.desc[i]->eof = 1; + handle->dma.desc[i]->sosf = 0; + handle->dma.desc[i]->length = bufsize; + handle->dma.desc[i]->size = bufsize; + handle->dma.desc[i]->offset = 0; + handle->dma.bufs[i] = (uint8_t *) heap_caps_calloc(1, bufsize * sizeof(uint8_t), MALLOC_CAP_DMA); + handle->dma.desc[i]->buf = handle->dma.bufs[i]; + ESP_GOTO_ON_FALSE(handle->dma.desc[i]->buf, ESP_ERR_NO_MEM, err, TAG, "allocate DMA buffer failed"); + } + /* Connect DMA descriptor as a circle */ + for (int i = 0; i < num; i++) { + /* Link to the next descriptor */ + handle->dma.desc[i]->empty = (uint32_t)((i < (num - 1)) ? (handle->dma.desc[i + 1]) : handle->dma.desc[0]); + } + if (handle->dir == I2S_DIR_RX) { + i2s_ll_rx_set_eof_num(handle->parent->hal.dev, bufsize); + } + ESP_LOGD(TAG, "DMA malloc info: dma_desc_num = %d, dma_desc_buf_size = dma_frame_num * slot_num * data_bit_width = %d, ", bufsize, num); + return ESP_OK; +err: + i2s_free_dma_desc(handle); + return ret; +} + +#if SOC_I2S_SUPPORTS_APLL +uint32_t i2s_set_get_apll_freq(uint32_t mclk_freq) +{ + /* Calculate the expected APLL */ + int mclk_div = (int)((SOC_APLL_MIN_HZ / mclk_freq) + 1); + /* apll_freq = mclk * div + * when div = 1, hardware will still divide 2 + * when div = 0, the final mclk will be unpredictable + * So the div here should be at least 2 */ + mclk_div = mclk_div < 2 ? 2 : mclk_div; + uint32_t expt_freq = mclk_freq * mclk_div; + uint32_t real_freq = 0; + esp_err_t ret = periph_rtc_apll_freq_set(expt_freq, &real_freq); + if (ret == ESP_ERR_INVALID_ARG) { + ESP_LOGE(TAG, "set APLL freq failed due to invalid argument"); + return 0; + } + if (ret == ESP_ERR_INVALID_STATE) { + ESP_LOGW(TAG, "APLL is occupied already, it is working at %d Hz while the expected frequency is %d Hz", real_freq, expt_freq); + ESP_LOGW(TAG, "Trying to work at %d Hz...", real_freq); + } + ESP_LOGI(TAG, "APLL expected frequency is %d Hz, real frequency is %d Hz", expt_freq, real_freq); + return real_freq; +} +#endif + +static inline void i2s_isr_send_event_queue(QueueHandle_t event_queue, i2s_event_type_t type, portBASE_TYPE *need_yield) +{ + if (event_queue) { + i2s_event_t i2s_event; + portBASE_TYPE _need_yield; + i2s_event.type = type; + xQueueSendFromISR(event_queue, (void * )&i2s_event, &_need_yield); + *need_yield |= _need_yield; + } +} + +#if SOC_GDMA_SUPPORTED +static bool IRAM_ATTR i2s_dma_rx_callback(gdma_channel_handle_t dma_chan, gdma_event_data_t *event_data, void *user_data) +{ + i2s_chan_handle_t handle = (i2s_chan_handle_t)user_data; + portBASE_TYPE need_yield = 0; + BaseType_t ret = 0; + lldesc_t *finish_desc; + + if (handle) { + finish_desc = (lldesc_t *)event_data->rx_eof_desc_addr; + ret = xQueueSendFromISR(handle->msg_queue, &(finish_desc->buf), &need_yield); + i2s_event_type_t type = (ret == pdTRUE) ? I2S_EVENT_RX_DONE : I2S_EVENT_RX_Q_OVF; + i2s_isr_send_event_queue(handle->event_queue, type, &need_yield); + } + return need_yield; +} + +static bool IRAM_ATTR i2s_dma_tx_callback(gdma_channel_handle_t dma_chan, gdma_event_data_t *event_data, void *user_data) +{ + i2s_chan_handle_t handle = (i2s_chan_handle_t)user_data; + portBASE_TYPE need_yield = 0; + BaseType_t ret; + lldesc_t *finish_desc; + if (handle) { + finish_desc = (lldesc_t *)(event_data->tx_eof_desc_addr); + if (handle->dma.auto_clear) { + uint8_t *sent_buf = (uint8_t *)finish_desc->buf; + memset(sent_buf, 0, handle->dma.buf_size); + } + ret = xQueueSendFromISR(handle->msg_queue, &(finish_desc->buf), &need_yield); + i2s_event_type_t type = (ret == pdTRUE) ? I2S_EVENT_TX_DONE : I2S_EVENT_TX_Q_OVF; + i2s_isr_send_event_queue(handle->event_queue, type, &need_yield); + } + return need_yield; +} + +#else +static void IRAM_ATTR i2s_default_intr_handler(void *arg) +{ + portBASE_TYPE tx_need_yield = 0; + portBASE_TYPE rx_need_yield = 0; + lldesc_t *finish_desc = NULL; + BaseType_t ret; + i2s_controller_t *obj = (i2s_controller_t *)arg; + uint32_t status = i2s_hal_get_intr_status(&(obj->hal)); + i2s_hal_clear_intr_status(&(obj->hal), status); + if (!obj || !status) { + return; + } + + if (obj->tx_chan && (status & I2S_LL_EVENT_TX_EOF)) { + i2s_hal_get_out_eof_des_addr(&(obj->hal), (uint32_t *)&finish_desc); + // Auto clear the dma buffer after data sent + if (obj->tx_chan->dma.auto_clear) { + uint8_t *buff = (uint8_t *)finish_desc->buf; + memset(buff, 0, obj->tx_chan->dma.buf_size); + } + ret = xQueueSendFromISR(obj->tx_chan->msg_queue, &(finish_desc->buf), &tx_need_yield); + i2s_event_type_t type = (ret == pdTRUE) ? I2S_EVENT_TX_DONE : I2S_EVENT_TX_Q_OVF; + i2s_isr_send_event_queue(obj->tx_chan->event_queue, type, &tx_need_yield); + } + + if (obj->rx_chan && (status & I2S_LL_EVENT_RX_EOF)) { + i2s_hal_get_in_eof_des_addr(&(obj->hal), (uint32_t *)&finish_desc); + ret = xQueueSendFromISR(obj->rx_chan->msg_queue, &(finish_desc->buf), &rx_need_yield); + i2s_event_type_t type = (ret == pdTRUE) ? I2S_EVENT_RX_DONE : I2S_EVENT_RX_Q_OVF; + i2s_isr_send_event_queue(obj->rx_chan->event_queue, type, &rx_need_yield); + } + + if (tx_need_yield || rx_need_yield) { + portYIELD_FROM_ISR(); + } +} +#endif + +/** + * @brief I2S DMA interrupt initialization + * @note I2S will use GDMA if chip supports, and the interrupt is triggered by GDMA. + * + * @param handle I2S channel handle + * @param intr_flag Interrupt allocation flag + * @return + * - ESP_OK I2S DMA interrupt initialize success + * - ESP_ERR_NOT_FOUND GDMA channel not found + * - ESP_ERR_INVALID_ARG Invalid arguments + * - ESP_ERR_INVALID_STATE GDMA state error + */ +esp_err_t i2s_init_dma_intr(i2s_chan_handle_t handle, int intr_flag) +{ + i2s_port_t port_id = handle->parent->id; + ESP_RETURN_ON_FALSE((port_id >= 0) && (port_id < I2S_NUM_MAX), ESP_ERR_INVALID_ARG, TAG, "invalid handle"); +#if SOC_GDMA_SUPPORTED + /* Set GDMA trigger module */ + gdma_trigger_t trig = {.periph = GDMA_TRIG_PERIPH_I2S}; + + switch (port_id) { +#if SOC_I2S_NUM > 1 + case I2S_NUM_1: + trig.instance_id = SOC_GDMA_TRIG_PERIPH_I2S1; + break; +#endif + default: + trig.instance_id = SOC_GDMA_TRIG_PERIPH_I2S0; + break; + } + + /* Set GDMA config */ + gdma_channel_alloc_config_t dma_cfg = {}; + if (handle->dir & I2S_DIR_TX) { + dma_cfg.direction = GDMA_CHANNEL_DIRECTION_TX; + /* Register a new GDMA tx channel */ + ESP_RETURN_ON_ERROR(gdma_new_channel(&dma_cfg, &handle->dma.dma_chan), TAG, "Register tx dma channel error"); + ESP_RETURN_ON_ERROR(gdma_connect(handle->dma.dma_chan, trig), TAG, "Connect tx dma channel error"); + gdma_tx_event_callbacks_t cb = {.on_trans_eof = i2s_dma_tx_callback}; + /* Set callback function for GDMA, the interrupt is triggered by GDMA, then the GDMA ISR will call the callback function */ + gdma_register_tx_event_callbacks(handle->dma.dma_chan, &cb, handle); + } + if (handle->dir & I2S_DIR_RX) { + dma_cfg.direction = GDMA_CHANNEL_DIRECTION_RX; + /* Register a new GDMA rx channel */ + ESP_RETURN_ON_ERROR(gdma_new_channel(&dma_cfg, &handle->dma.dma_chan), TAG, "Register rx dma channel error"); + ESP_RETURN_ON_ERROR(gdma_connect(handle->dma.dma_chan, trig), TAG, "Connect rx dma channel error"); + gdma_rx_event_callbacks_t cb = {.on_recv_eof = i2s_dma_rx_callback}; + /* Set callback function for GDMA, the interrupt is triggered by GDMA, then the GDMA ISR will call the callback function */ + gdma_register_rx_event_callbacks(handle->dma.dma_chan, &cb, handle); + } +#else + /* Initial I2S module interrupt */ + if (!handle->parent->i2s_isr_handle) { + ESP_RETURN_ON_ERROR(esp_intr_alloc(i2s_periph_signal[port_id].irq, intr_flag, i2s_default_intr_handler, handle->parent, &(handle->parent->i2s_isr_handle)), TAG, "Register I2S Interrupt error"); + esp_intr_enable(handle->parent->i2s_isr_handle); + } + /* Start DMA */ + i2s_ll_enable_dma(handle->parent->hal.dev, true); +#endif // SOC_GDMA_SUPPORTED + return ESP_OK; +} + +void i2s_gpio_check_and_set(gpio_num_t gpio, uint32_t signal_idx, bool is_input) +{ + /* Ignore the pin if pin = -1 */ + if (gpio != I2S_GPIO_UNUSED) { + if (is_input) { + gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[gpio], PIN_FUNC_GPIO); + /* Set direction, for some GPIOs, the input function are not enabled as default */ + gpio_set_direction(gpio, GPIO_MODE_INPUT); + esp_rom_gpio_connect_in_signal(gpio, signal_idx, 0); + } else { + gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[gpio], PIN_FUNC_GPIO); + gpio_set_direction(gpio, GPIO_MODE_OUTPUT); + esp_rom_gpio_connect_out_signal(gpio, signal_idx, 0, 0); + } + } +} + +esp_err_t i2s_check_set_mclk(i2s_port_t id, gpio_num_t gpio_num) +{ + if (gpio_num == -1) { + return ESP_OK; + } +#if CONFIG_IDF_TARGET_ESP32 + ESP_RETURN_ON_FALSE((gpio_num == GPIO_NUM_0 || gpio_num == GPIO_NUM_1 || gpio_num == GPIO_NUM_3), + ESP_ERR_INVALID_ARG, TAG, + "ESP32 only support to set GPIO0/GPIO1/GPIO3 as mclk signal, error GPIO number:%d", gpio_num); + bool is_i2s0 = id == I2S_NUM_0; + if (gpio_num == GPIO_NUM_0) { + PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0_CLK_OUT1); + WRITE_PERI_REG(PIN_CTRL, is_i2s0 ? 0xFFF0 : 0xFFFF); + } else if (gpio_num == GPIO_NUM_1) { + PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD_CLK_OUT3); + WRITE_PERI_REG(PIN_CTRL, is_i2s0 ? 0xF0F0 : 0xF0FF); + } else { + PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD_CLK_OUT2); + WRITE_PERI_REG(PIN_CTRL, is_i2s0 ? 0xFF00 : 0xFF0F); + } +#else + ESP_RETURN_ON_FALSE(GPIO_IS_VALID_GPIO(gpio_num), ESP_ERR_INVALID_ARG, TAG, "mck_io_num invalid"); + gpio_matrix_out_check_and_set(gpio_num, i2s_periph_signal[id].mck_out_sig, 0, 0); +#endif + ESP_LOGI(TAG, "MCLK is pinned to GPIO%d on I2S%d", id, gpio_num); + return ESP_OK; +} + +/*--------------------------------------------------------------------------- + I2S bus Public APIs + ---------------------------------------------------------------------------- + Scope: Public + ----------------------------------------------------------------------------*/ +esp_err_t i2s_new_channel(const i2s_chan_config_t *chan_cfg, i2s_chan_handle_t *tx_handle, i2s_chan_handle_t *rx_handle) +{ + /* Parameter validity check */ + I2S_NULL_POINTER_CHECK(TAG, chan_cfg); + I2S_NULL_POINTER_CHECK(TAG, tx_handle || rx_handle); + ESP_RETURN_ON_FALSE(chan_cfg->id < SOC_I2S_NUM, ESP_ERR_INVALID_ARG, TAG, "invalid I2S port id"); + ESP_RETURN_ON_FALSE(chan_cfg->dma_desc_num >= 2, ESP_ERR_INVALID_ARG, TAG, "there should be at least 2 DMA buffers"); + + esp_err_t ret = ESP_OK; + i2s_controller_t *i2s_obj = NULL; + i2s_port_t id = chan_cfg->id; + bool channel_found = false; + uint8_t chan_search_mask = 0; + chan_search_mask |= tx_handle ? I2S_DIR_TX : 0; + chan_search_mask |= rx_handle ? I2S_DIR_RX : 0; + + /* Channel will be registered to one i2s port automatically if id is I2S_NUM_AUTO + * Otherwise, the channel will be registered to the specific port. */ + if (id == I2S_NUM_AUTO) { + for (int i = 0; i < I2S_NUM_MAX && !channel_found; i++) { + i2s_obj = i2s_acquire_controller_obj(i); + if (!i2s_obj) { + continue; + } + channel_found = i2s_take_available_channel(i2s_obj, chan_search_mask); + } + ESP_RETURN_ON_FALSE(i2s_obj, ESP_ERR_NOT_FOUND, TAG, "get i2s object failed"); + } else { + i2s_obj = i2s_acquire_controller_obj(id); + ESP_RETURN_ON_FALSE(i2s_obj, ESP_ERR_NOT_FOUND, TAG, "get i2s object failed"); + channel_found = i2s_take_available_channel(i2s_obj, chan_search_mask); + } + ESP_GOTO_ON_FALSE(channel_found, ESP_ERR_NOT_FOUND, err, TAG, "no available channel found"); + /* Register and specify the tx handle */ + if (tx_handle) { + ESP_GOTO_ON_ERROR(i2s_register_channel(i2s_obj, I2S_DIR_TX), err, TAG, "register I2S tx channel failed"); + i2s_obj->tx_chan->role = chan_cfg->role; + i2s_obj->tx_chan->dma.auto_clear = chan_cfg->auto_clear; + i2s_obj->tx_chan->dma.desc_num = chan_cfg->dma_desc_num; + i2s_obj->tx_chan->dma.frame_num = chan_cfg->dma_frame_num; + i2s_obj->tx_chan->start = i2s_tx_start; + i2s_obj->tx_chan->stop = i2s_tx_stop; + *tx_handle = i2s_obj->tx_chan; + ESP_LOGI(TAG, "tx channel is registered on I2S%d successfully", i2s_obj->id); + } + /* Register and specify the rx handle */ + if (rx_handle) { + ESP_GOTO_ON_ERROR(i2s_register_channel(i2s_obj, I2S_DIR_RX), err, TAG, "register I2S rx channel failed"); + i2s_obj->rx_chan->role = chan_cfg->role; + i2s_obj->rx_chan->dma.desc_num = chan_cfg->dma_desc_num; + i2s_obj->rx_chan->dma.frame_num = chan_cfg->dma_frame_num; + i2s_obj->rx_chan->start = i2s_rx_start; + i2s_obj->rx_chan->stop = i2s_rx_stop; + *rx_handle = i2s_obj->rx_chan; + ESP_LOGI(TAG, "rx channel is registered on I2S%d successfully", i2s_obj->id); + } + + if ((tx_handle != NULL) && (rx_handle != NULL)) { + i2s_obj->full_duplex = true; + } + + return ESP_OK; +/* i2s_obj allocated but register channel failed */ +err: + /* if the controller object has no channel, find the corresponding global object and destroy it */ + if (i2s_obj != NULL && i2s_obj->rx_chan == NULL && i2s_obj->tx_chan == NULL) { + for (int i = 0; i < I2S_NUM_MAX; i++) { + if (i2s_obj == s_i2s.controller[i]) { + i2s_destroy_controller_obj(&s_i2s.controller[i]); + break; + } + } + } + return ret; +} + +// TODO: finish delete channel +esp_err_t i2s_del_channel(i2s_chan_handle_t handle) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + /* Static mutex to avoid double delete */ + static SemaphoreHandle_t del_mut = NULL; + if (del_mut == NULL) { + del_mut = xSemaphoreCreateMutex(); + } + i2s_controller_t *i2s_obj = handle->parent; + int id = i2s_obj->id; + i2s_dir_t dir = handle->dir; + bool is_bound = true; + + xSemaphoreTake(del_mut, portMAX_DELAY); + /* Stop the channel first */ + if (handle->state > I2S_CHAN_STATE_READY) { + i2s_abort_reading_writing(handle); + i2s_stop_channel(handle); + } +#if SOC_I2S_HW_VERSION_2 + if (dir == I2S_DIR_TX) { + i2s_ll_tx_disable_clock(handle->parent->hal.dev); + } else { + i2s_ll_rx_disable_clock(handle->parent->hal.dev); + } +#endif +#if SOC_I2S_SUPPORTS_APLL + if (handle->apll_en) { + /* Must switch back to D2CLK on ESP32-S2, + * because the clock of some registers are bound to APLL, + * otherwise, once APLL is disabled, the registers can't be updated anymore */ + if (handle->dir == I2S_DIR_TX) { + i2s_ll_tx_clk_set_src(handle->parent->hal.dev, I2S_CLK_160M_PLL); + } else { + i2s_ll_rx_clk_set_src(handle->parent->hal.dev, I2S_CLK_160M_PLL); + } + periph_rtc_apll_release(); + } +#endif + if (handle->mode_info) { + free(handle->mode_info); + } + if (handle->dma.desc) { + i2s_free_dma_desc(handle); + } + if (handle->msg_queue) { + vQueueDelete(handle->msg_queue); + } + if (handle->event_queue) { + vQueueDelete(handle->event_queue); + } + if (handle->mutex) { + vSemaphoreDelete(handle->mutex); + } +#if SOC_I2S_HW_VERSION_1 + i2s_obj->chan_occupancy = 0; +#else + i2s_obj->chan_occupancy &= ~(uint32_t)dir; +#endif +#if SOC_GDMA_SUPPORTED + if (handle->dma.dma_chan) { + gdma_del_channel(handle->dma.dma_chan); + } +#endif + if (handle == i2s_obj->tx_chan) { + free(i2s_obj->tx_chan); + i2s_obj->tx_chan = NULL; + i2s_obj->full_duplex = false; + } else if (handle == i2s_obj->rx_chan) { + free(i2s_obj->rx_chan); + i2s_obj->rx_chan = NULL; + i2s_obj->full_duplex = false; + } else { + /* Indicate the delete channel is an unbound free channel */ + is_bound = false; + free(handle); + } + + /* If the delete channel was bound to a controller before, + we need to destroy this controller object if there is no channel any more */ + if (is_bound) { + if (!(i2s_obj->tx_chan) && !(i2s_obj->rx_chan)) { + i2s_destroy_controller_obj(&s_i2s.controller[i2s_obj->id]); + } + ESP_LOGI(TAG, "%s channel on I2S%d deleted", dir == I2S_DIR_TX ? "tx" : "rx", id); + } + xSemaphoreGive(del_mut); + return ESP_OK; +} + +QueueHandle_t i2s_get_event_queue(i2s_chan_handle_t handle, uint32_t que_len) +{ + QueueHandle_t que; + if (!handle) { + return NULL; + } + xSemaphoreTake(handle->mutex, portMAX_DELAY); + if (handle->event_queue) { + que = handle->event_queue; + } else { + handle->event_queue = xQueueCreate(que_len, sizeof(int *)); + que = handle->event_queue; + } + xSemaphoreGive(handle->mutex); + return que; +} + + +esp_err_t i2s_start_channel(i2s_chan_handle_t handle) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + + esp_err_t ret = ESP_OK; + + xSemaphoreTake(handle->mutex, portMAX_DELAY); + ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "the channel has already started or not initialized"); + + handle->dma.curr_ptr = NULL; + handle->dma.rw_pos = 0; + handle->start(handle); + handle->state = I2S_CHAN_STATE_IDLE; + xSemaphoreGive(handle->mutex); + + ESP_LOGI(TAG, "i2s %s channel started", handle->dir == I2S_DIR_TX ? "tx" : "rx"); + return ret; + +err: + xSemaphoreGive(handle->mutex); + return ret; +} + +esp_err_t i2s_stop_channel(i2s_chan_handle_t handle) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + esp_err_t ret = ESP_OK; + + xSemaphoreTake(handle->mutex, portMAX_DELAY); + ESP_GOTO_ON_FALSE(handle->state > I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "the channel has not started yet"); + handle->stop(handle); + handle->state = I2S_CHAN_STATE_READY; + xSemaphoreGive(handle->mutex); + ESP_LOGI(TAG, "i2s %s channel stopped", handle->dir == I2S_DIR_TX ? "tx" : "rx"); + return ret; + +err: + xSemaphoreGive(handle->mutex); + return ret; +} + +esp_err_t i2s_write_channel(i2s_chan_handle_t handle, const void *src, size_t size, size_t *bytes_written, TickType_t ticks_to_wait) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + ESP_RETURN_ON_FALSE(handle->dir == I2S_DIR_TX, ESP_ERR_INVALID_ARG, TAG, "this channel is not tx channel"); + + esp_err_t ret = ESP_OK; + char *data_ptr, *src_byte; + size_t bytes_can_write; + *bytes_written = 0; + + /* Take the semaphore brefore changing state to ensure only one writing thread running at the same time */ + xSemaphoreTake(handle->mutex, ticks_to_wait); +#ifdef CONFIG_PM_ENABLE + esp_pm_lock_acquire(handle->pm_lock); +#endif + ESP_GOTO_ON_FALSE(handle->state > I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "this channel has not started yet"); + handle->state = I2S_CHAN_STATE_WRITING; + src_byte = (char *)src; + while (size > 0 && handle->state == I2S_CHAN_STATE_WRITING) { + if (handle->dma.rw_pos == handle->dma.buf_size || handle->dma.curr_ptr == NULL) { + if (xQueueReceive(handle->msg_queue, &(handle->dma.curr_ptr), ticks_to_wait) == pdFALSE) { + ret = ESP_ERR_TIMEOUT; + break; + } + handle->dma.rw_pos = 0; + } + ESP_LOGD(TAG, "size: %d, rw_pos: %d, buf_size: %d, curr_ptr: %d", size, handle->dma.rw_pos, handle->dma.buf_size, (int)handle->dma.curr_ptr); + data_ptr = (char *)handle->dma.curr_ptr; + data_ptr += handle->dma.rw_pos; + bytes_can_write = handle->dma.buf_size - handle->dma.rw_pos; + if (bytes_can_write > size) { + bytes_can_write = size; + } + memcpy(data_ptr, src_byte, bytes_can_write); + size -= bytes_can_write; + src_byte += bytes_can_write; + handle->dma.rw_pos += bytes_can_write; + (*bytes_written) += bytes_can_write; + } + /* Need to judge the state before switch back to idle, in case the state has been changed by 'stop' or 'abort' */ + if (handle->state == I2S_CHAN_STATE_WRITING) { + handle->state = I2S_CHAN_STATE_IDLE; + } +err: +#ifdef CONFIG_PM_ENABLE + esp_pm_lock_release(handle->pm_lock); +#endif + xSemaphoreGive(handle->mutex); + + return ret; +} + +esp_err_t i2s_read_channel(i2s_chan_handle_t handle, void *dest, size_t size, size_t *bytes_read, TickType_t ticks_to_wait) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + ESP_RETURN_ON_FALSE(handle->dir == I2S_DIR_RX, ESP_ERR_INVALID_ARG, TAG, "this channel is not rx channel"); + + esp_err_t ret = ESP_OK; + uint8_t *data_ptr, *dest_byte; + int bytes_can_read; + *bytes_read = 0; + dest_byte = (uint8_t *)dest; + /* Take the semaphore brefore changing state to ensure only one reading thread running at the same time */ + xSemaphoreTake(handle->mutex, ticks_to_wait); +#ifdef CONFIG_PM_ENABLE + esp_pm_lock_acquire(handle->pm_lock); +#endif + ESP_GOTO_ON_FALSE(handle->state > I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "this channel has not started yet"); + handle->state = I2S_CHAN_STATE_READING; + while (size > 0 && handle->state == I2S_CHAN_STATE_READING) { + if (handle->dma.rw_pos == handle->dma.buf_size || handle->dma.curr_ptr == NULL) { + if (xQueueReceive(handle->msg_queue, &(handle->dma.curr_ptr), ticks_to_wait) == pdFALSE) { + ret = ESP_ERR_TIMEOUT; + break; + } + handle->dma.rw_pos = 0; + } + data_ptr = (uint8_t *)handle->dma.curr_ptr; + data_ptr += handle->dma.rw_pos; + bytes_can_read = handle->dma.buf_size - handle->dma.rw_pos; + if (bytes_can_read > (int)size) { + bytes_can_read = size; + } + memcpy(dest_byte, data_ptr, bytes_can_read); + size -= bytes_can_read; + dest_byte += bytes_can_read; + handle->dma.rw_pos += bytes_can_read; + (*bytes_read) += bytes_can_read; + } + /* Need to judge the state before switch back to idle, in case the state has been changed by 'stop' or 'abort' */ + if (handle->state == I2S_CHAN_STATE_READING) { + handle->state = I2S_CHAN_STATE_IDLE; + } +err: +#ifdef CONFIG_PM_ENABLE + esp_pm_lock_release(handle->pm_lock); +#endif + xSemaphoreGive(handle->mutex); + + return ret; +} + +esp_err_t i2s_clear_dma_buffer(i2s_chan_handle_t handle) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + ESP_RETURN_ON_FALSE(handle->state > I2S_CHAN_STATE_INIT, ESP_ERR_INVALID_STATE, TAG, "this channel has not initialized yet"); + /* Clear all the DMA buffer */ + for (int desc_num = handle->dma.desc_num; desc_num > 0; desc_num--) { + memset(handle->dma.bufs[desc_num-1], 0, handle->dma.buf_size); + } + return ESP_OK; +} + +esp_err_t i2s_abort_reading_writing(i2s_chan_handle_t handle) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + ESP_RETURN_ON_FALSE(handle->state > I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, TAG, "this channel has not started yet"); + /* No lock here. Force change state to idle when writing or reading */ + handle->state = I2S_CHAN_STATE_IDLE; + + return ESP_OK; +} + + +/*--------------------------------------------------------------------------- + I2S Platform APIs + ---------------------------------------------------------------------------- + Scope: This file and ADC/DAC/LCD driver + ----------------------------------------------------------------------------*/ + +esp_err_t i2s_platform_acquire_occupation(int id, const char *comp_name) +{ + esp_err_t ret = ESP_OK; + const char *occupied_comp = NULL; + ESP_RETURN_ON_FALSE(id < I2S_NUM_MAX, ESP_ERR_INVALID_ARG, TAG, "invalid i2s port id"); + portENTER_CRITICAL(&s_i2s.spinlock); + if ((!s_i2s.controller[id]) && (s_i2s.comp_name[id] == NULL)) { + s_i2s.comp_name[id] = comp_name; + /* Enable module clock */ + periph_module_enable(i2s_periph_signal[id].module); + i2s_ll_enable_clock(I2S_LL_GET_HW(id)); + } else { + occupied_comp = s_i2s.comp_name[id]; + ret = ESP_ERR_NOT_FOUND; + } + portEXIT_CRITICAL(&s_i2s.spinlock); + if (occupied_comp != NULL) { + ESP_LOGE(TAG, "i2s controller %d has been occupied by %s", id, occupied_comp); + } + return ret; +} + +esp_err_t i2s_platform_release_occupation(int id) +{ + esp_err_t ret = ESP_OK; + ESP_RETURN_ON_FALSE(id < I2S_NUM_MAX, ESP_ERR_INVALID_ARG, TAG, "invalid i2s port id"); + portENTER_CRITICAL(&s_i2s.spinlock); + if ((!s_i2s.controller[id])) { + s_i2s.comp_name[id] = NULL; + /* Disable module clock */ + periph_module_disable(i2s_periph_signal[id].module); + i2s_ll_disable_clock(I2S_LL_GET_HW(id)); + } else { + ret = ESP_ERR_INVALID_STATE; + } + portEXIT_CRITICAL(&s_i2s.spinlock); + return ret; +} diff --git a/components/driver/i2s.c b/components/driver/i2s/i2s_legacy.c similarity index 86% rename from components/driver/i2s.c rename to components/driver/i2s/i2s_legacy.c index e5d441b32c..fc834be793 100644 --- a/components/driver/i2s.c +++ b/components/driver/i2s/i2s_legacy.c @@ -16,14 +16,11 @@ #include "driver/gpio.h" #include "hal/gpio_hal.h" #include "hal/i2s_hal.h" -#include "hal/i2s_std.h" -#include "hal/i2s_pdm.h" -#include "hal/i2s_tdm.h" #include "driver/i2s.h" #if SOC_I2S_SUPPORTS_DAC #include "driver/dac.h" #include "driver/adc.h" -#include "adc1_private.h" +#include "../adc1_private.h" #endif // SOC_I2S_SUPPORTS_ADC #if SOC_GDMA_SUPPORTED @@ -57,6 +54,23 @@ static const char *TAG = "I2S"; #define I2S_COMM_MODE_ADC_DAC -1 #endif +/** + * @brief General clock configuration information + * @note It is a general purpose struct, not supposed to be used directly by user + */ +typedef struct { + uint32_t sample_rate_hz; /*!< I2S sample rate */ + i2s_clock_src_t clk_src; /*!< Choose clock source */ + i2s_mclk_multiple_t mclk_multiple; /*!< The multiple of mclk to the sample rate */ +#if SOC_I2S_SUPPORTS_PDM_TX + uint32_t up_sample_fp; /*!< Up-sampling param fp */ + uint32_t up_sample_fs; /*!< Up-sampling param fs */ +#endif +#if SOC_I2S_SUPPORTS_PDM_RX + i2s_pdm_dsr_t dn_sample_mode; /*!< Down-sampling rate mode */ +#endif +} i2s_clk_config_t; + /** * @brief DMA buffer object * @@ -104,8 +118,8 @@ typedef struct { i2s_dir_t dir; i2s_role_t role; i2s_comm_mode_t mode; - void *slot_cfg; - void *clk_cfg; + i2s_hal_slot_config_t slot_cfg; + i2s_clk_config_t clk_cfg; uint32_t active_slot; /*!< Active slot number */ uint32_t total_slot; /*!< Total slot number */ } i2s_obj_t; @@ -113,7 +127,6 @@ typedef struct { static i2s_obj_t *p_i2s[SOC_I2S_NUM] = { [0 ... SOC_I2S_NUM - 1] = NULL, }; -static portMUX_TYPE i2s_platform_spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED; static portMUX_TYPE i2s_spinlock[SOC_I2S_NUM] = { [0 ... SOC_I2S_NUM - 1] = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED, }; @@ -443,7 +456,7 @@ esp_err_t i2s_stop(i2s_port_t i2s_num) -------------------------------------------------------------*/ static inline uint32_t i2s_get_buf_size(i2s_port_t i2s_num) { - i2s_slot_config_t *slot_cfg = (i2s_slot_config_t *)p_i2s[i2s_num]->slot_cfg; + i2s_hal_slot_config_t *slot_cfg = &p_i2s[i2s_num]->slot_cfg; /* Calculate bytes per sample, align to 16 bit */ uint32_t bytes_per_sample = ((slot_cfg->data_bit_width + 15) / 16) * 2; /* The DMA buffer limitation is 4092 bytes */ @@ -623,20 +636,20 @@ static uint32_t i2s_config_source_clock(i2s_port_t i2s_num, bool use_apll, uint3 return I2S_LL_BASE_CLK; #else if (use_apll) { - ESP_LOGW(TAG, "APLL not supported on current chip, use I2S_CLK_D2CLK as default clock source"); + ESP_LOGW(TAG, "APLL not supported on current chip, use I2S_CLK_160M_PLL as default clock source"); } return I2S_LL_BASE_CLK; #endif } #if SOC_I2S_SUPPORTS_ADC || SOC_I2S_SUPPORTS_DAC -static esp_err_t i2s_calculate_adc_dac_clock(int i2s_num, i2s_clock_info_t *clk_info) +static esp_err_t i2s_calculate_adc_dac_clock(int i2s_num, i2s_hal_clock_info_t *clk_info) { /* For ADC/DAC mode, the built-in ADC/DAC is driven by 'mclk' instead of 'bclk' * 'bclk' should be fixed to the double of sample rate * 'bclk_div' is the real coefficient that affects the slot bit */ - i2s_clk_config_t *clk_cfg = (i2s_clk_config_t *)p_i2s[i2s_num]->clk_cfg; - i2s_slot_config_t *slot_cfg = (i2s_slot_config_t *)p_i2s[i2s_num]->slot_cfg; + i2s_clk_config_t *clk_cfg = &p_i2s[i2s_num]->clk_cfg; + i2s_hal_slot_config_t *slot_cfg = &p_i2s[i2s_num]->slot_cfg; uint32_t slot_bits = slot_cfg->slot_bit_width; /* Set I2S bit clock */ clk_info->bclk = clk_cfg->sample_rate_hz * I2S_LL_AD_BCK_FACTOR; @@ -661,9 +674,9 @@ static esp_err_t i2s_calculate_adc_dac_clock(int i2s_num, i2s_clock_info_t *clk_ #endif // SOC_I2S_SUPPORTS_ADC || SOC_I2S_SUPPORTS_DAC #if SOC_I2S_SUPPORTS_PDM_TX -static esp_err_t i2s_calculate_pdm_tx_clock(int i2s_num, i2s_clock_info_t *clk_info) +static esp_err_t i2s_calculate_pdm_tx_clock(int i2s_num, i2s_hal_clock_info_t *clk_info) { - i2s_pdm_tx_clk_config_t *clk_cfg = (i2s_pdm_tx_clk_config_t *)p_i2s[i2s_num]->clk_cfg; + i2s_clk_config_t *clk_cfg = &p_i2s[i2s_num]->clk_cfg; int fp = clk_cfg->up_sample_fp; int fs = clk_cfg->up_sample_fs; @@ -690,9 +703,9 @@ static esp_err_t i2s_calculate_pdm_tx_clock(int i2s_num, i2s_clock_info_t *clk_i #endif // SOC_I2S_SUPPORTS_PDM_TX #if SOC_I2S_SUPPORTS_PDM_RX -static esp_err_t i2s_calculate_pdm_rx_clock(int i2s_num, i2s_clock_info_t *clk_info) +static esp_err_t i2s_calculate_pdm_rx_clock(int i2s_num, i2s_hal_clock_info_t *clk_info) { - i2s_pdm_rx_clk_config_t *clk_cfg = (i2s_pdm_rx_clk_config_t *)p_i2s[i2s_num]->clk_cfg; + i2s_clk_config_t *clk_cfg = &p_i2s[i2s_num]->clk_cfg; i2s_pdm_dsr_t dsr = clk_cfg->dn_sample_mode; /* Set I2S bit clock */ clk_info->bclk = clk_cfg->sample_rate_hz * I2S_LL_PDM_BCK_FACTOR * (dsr == I2S_PDM_DSR_16S ? 2 : 1); @@ -715,10 +728,10 @@ static esp_err_t i2s_calculate_pdm_rx_clock(int i2s_num, i2s_clock_info_t *clk_i return ESP_OK; } #endif // SOC_I2S_SUPPORTS_PDM_RX -static esp_err_t i2s_calculate_common_clock(int i2s_num, i2s_clock_info_t *clk_info) +static esp_err_t i2s_calculate_common_clock(int i2s_num, i2s_hal_clock_info_t *clk_info) { - i2s_clk_config_t *clk_cfg = (i2s_clk_config_t *)p_i2s[i2s_num]->clk_cfg; - i2s_slot_config_t *slot_cfg = (i2s_slot_config_t *)p_i2s[i2s_num]->slot_cfg; + i2s_clk_config_t *clk_cfg = &p_i2s[i2s_num]->clk_cfg; + i2s_hal_slot_config_t *slot_cfg = &p_i2s[i2s_num]->slot_cfg; uint32_t rate = clk_cfg->sample_rate_hz; uint32_t slot_num = p_i2s[i2s_num]->total_slot < 2 ? 2 : p_i2s[i2s_num]->total_slot; uint32_t slot_bits = slot_cfg->slot_bit_width; @@ -745,7 +758,7 @@ static esp_err_t i2s_calculate_common_clock(int i2s_num, i2s_clock_info_t *clk_i } -static esp_err_t i2s_calculate_clock(i2s_port_t i2s_num, i2s_clock_info_t *clk_info) +static esp_err_t i2s_calculate_clock(i2s_port_t i2s_num, i2s_hal_clock_info_t *clk_info) { /* Calculate clock for ADC/DAC mode */ #if SOC_I2S_SUPPORTS_ADC_DAC @@ -782,14 +795,6 @@ static esp_err_t i2s_calculate_clock(i2s_port_t i2s_num, i2s_clock_info_t *clk_i -------------------------------------------------------------*/ #if SOC_I2S_SUPPORTS_TDM -static uint32_t i2s_get_max_channel_num(uint32_t chan_mask) -{ - int max_chan; - for (max_chan = 0; chan_mask; max_chan++, chan_mask >>= 1); - /* Can't be smaller than 2 */ - return max_chan < 2 ? 2 : max_chan; -} - static uint32_t i2s_get_active_channel_num(uint32_t chan_mask) { uint32_t num = 0; @@ -806,7 +811,7 @@ static uint32_t i2s_get_active_channel_num(uint32_t chan_mask) static void i2s_dac_set_slot_legacy(void) { i2s_dev_t *dev = p_i2s[0]->hal.dev; - i2s_slot_config_t *slot_cfg = p_i2s[0]->slot_cfg; + i2s_hal_slot_config_t *slot_cfg = &p_i2s[0]->slot_cfg; i2s_ll_tx_reset(dev); i2s_ll_tx_set_slave_mod(dev, false); @@ -845,7 +850,7 @@ esp_err_t i2s_set_dac_mode(i2s_dac_mode_t dac_mode) static void i2s_adc_set_slot_legacy(void) { i2s_dev_t *dev = p_i2s[0]->hal.dev; - i2s_slot_config_t *slot_cfg = p_i2s[0]->slot_cfg; + i2s_hal_slot_config_t *slot_cfg = &p_i2s[0]->slot_cfg; // When ADC/DAC are installed as duplex mode, ADC will share the WS and BCLK clock by working in slave mode i2s_ll_rx_set_slave_mod(dev, false); i2s_ll_rx_set_sample_bit(dev, slot_cfg->slot_bit_width, slot_cfg->data_bit_width); @@ -958,22 +963,22 @@ static void i2s_set_slot_legacy(i2s_port_t i2s_num) } if (p_i2s[i2s_num]->mode == I2S_COMM_MODE_STD) { if (p_i2s[i2s_num]->dir & I2S_DIR_TX) { - i2s_hal_std_set_tx_slot(&(p_i2s[i2s_num]->hal), is_tx_slave, p_i2s[i2s_num]->slot_cfg ); + i2s_hal_std_set_tx_slot(&(p_i2s[i2s_num]->hal), is_tx_slave, (i2s_hal_slot_config_t *)(&p_i2s[i2s_num]->slot_cfg) ); } if (p_i2s[i2s_num]->dir & I2S_DIR_RX) { - i2s_hal_std_set_rx_slot(&(p_i2s[i2s_num]->hal), is_rx_slave, p_i2s[i2s_num]->slot_cfg ); + i2s_hal_std_set_rx_slot(&(p_i2s[i2s_num]->hal), is_rx_slave, (i2s_hal_slot_config_t *)(&p_i2s[i2s_num]->slot_cfg) ); } } #if SOC_I2S_SUPPORTS_PDM else if (p_i2s[i2s_num]->mode == I2S_COMM_MODE_PDM) { #if SOC_I2S_SUPPORTS_PDM_TX if (p_i2s[i2s_num]->dir & I2S_DIR_TX) { - i2s_hal_pdm_set_tx_slot(&(p_i2s[i2s_num]->hal), is_tx_slave, p_i2s[i2s_num]->slot_cfg ); + i2s_hal_pdm_set_tx_slot(&(p_i2s[i2s_num]->hal), is_tx_slave, (i2s_hal_slot_config_t *)(&p_i2s[i2s_num]->slot_cfg) ); } #endif #if SOC_I2S_SUPPORTS_PDM_RX if (p_i2s[i2s_num]->dir & I2S_DIR_RX) { - i2s_hal_pdm_set_rx_slot(&(p_i2s[i2s_num]->hal), is_rx_slave, p_i2s[i2s_num]->slot_cfg ); + i2s_hal_pdm_set_rx_slot(&(p_i2s[i2s_num]->hal), is_rx_slave, (i2s_hal_slot_config_t *)(&p_i2s[i2s_num]->slot_cfg) ); } #endif } @@ -981,10 +986,10 @@ static void i2s_set_slot_legacy(i2s_port_t i2s_num) #if SOC_I2S_SUPPORTS_TDM else if (p_i2s[i2s_num]->mode == I2S_COMM_MODE_TDM) { if (p_i2s[i2s_num]->dir & I2S_DIR_TX) { - i2s_hal_tdm_set_tx_slot(&(p_i2s[i2s_num]->hal), is_tx_slave, p_i2s[i2s_num]->slot_cfg ); + i2s_hal_tdm_set_tx_slot(&(p_i2s[i2s_num]->hal), is_tx_slave, (i2s_hal_slot_config_t *)(&p_i2s[i2s_num]->slot_cfg) ); } if (p_i2s[i2s_num]->dir & I2S_DIR_RX) { - i2s_hal_tdm_set_rx_slot(&(p_i2s[i2s_num]->hal), is_rx_slave, p_i2s[i2s_num]->slot_cfg ); + i2s_hal_tdm_set_rx_slot(&(p_i2s[i2s_num]->hal), is_rx_slave, (i2s_hal_slot_config_t *)(&p_i2s[i2s_num]->slot_cfg) ); } } #endif @@ -1002,8 +1007,8 @@ static void i2s_set_slot_legacy(i2s_port_t i2s_num) static void i2s_set_clock_legacy(i2s_port_t i2s_num) { - i2s_clk_config_t *clk_cfg = (i2s_clk_config_t *)p_i2s[i2s_num]->clk_cfg; - i2s_clock_info_t clk_info; + i2s_clk_config_t *clk_cfg = &p_i2s[i2s_num]->clk_cfg; + i2s_hal_clock_info_t clk_info; i2s_calculate_clock(i2s_num, &clk_info); if (p_i2s[i2s_num]->dir & I2S_DIR_TX) { i2s_hal_set_tx_clock(&(p_i2s[i2s_num]->hal), &clk_info, clk_cfg->clk_src); @@ -1016,7 +1021,7 @@ static void i2s_set_clock_legacy(i2s_port_t i2s_num) float i2s_get_clk(i2s_port_t i2s_num) { ESP_RETURN_ON_FALSE((i2s_num < I2S_NUM_MAX), ESP_ERR_INVALID_ARG, TAG, "i2s_num error"); - i2s_clk_config_t *clk_cfg = (i2s_clk_config_t *)p_i2s[i2s_num]->clk_cfg; + i2s_clk_config_t *clk_cfg = &p_i2s[i2s_num]->clk_cfg; return (float)clk_cfg->sample_rate_hz; } @@ -1036,8 +1041,8 @@ esp_err_t i2s_set_clk(i2s_port_t i2s_num, uint32_t rate, uint32_t bits_cfg, i2s_ /* Stop I2S */ i2s_stop(i2s_num); - i2s_clk_config_t *clk_cfg = (i2s_clk_config_t *)p_i2s[i2s_num]->clk_cfg; - i2s_slot_config_t *slot_cfg = (i2s_slot_config_t *)p_i2s[i2s_num]->slot_cfg; + i2s_clk_config_t *clk_cfg = &p_i2s[i2s_num]->clk_cfg; + i2s_hal_slot_config_t *slot_cfg = &p_i2s[i2s_num]->slot_cfg; clk_cfg->sample_rate_hz = rate; slot_cfg->data_bit_width = bits_cfg & 0xFFFF; @@ -1053,9 +1058,9 @@ esp_err_t i2s_set_clk(i2s_port_t i2s_num, uint32_t rate, uint32_t bits_cfg, i2s_ if (slot_mask == 0) { slot_mask = (slot_cfg->slot_mode == I2S_SLOT_MODE_MONO) ? 1 : 2; } - ESP_RETURN_ON_FALSE(p_i2s[i2s_num]->total_slot >= i2s_get_max_channel_num(slot_mask), ESP_ERR_INVALID_ARG, TAG, + ESP_RETURN_ON_FALSE(p_i2s[i2s_num]->total_slot >= (32 - __builtin_clz(slot_mask)), ESP_ERR_INVALID_ARG, TAG, "The max channel number can't be greater than CH%d\n", p_i2s[i2s_num]->total_slot); - p_i2s[i2s_num]->active_slot = i2s_get_active_channel_num(slot_mask); + p_i2s[i2s_num]->active_slot = __builtin_popcount(slot_mask); } else #endif { @@ -1102,7 +1107,7 @@ esp_err_t i2s_set_clk(i2s_port_t i2s_num, uint32_t rate, uint32_t bits_cfg, i2s_ esp_err_t i2s_set_sample_rates(i2s_port_t i2s_num, uint32_t rate) { ESP_RETURN_ON_FALSE((i2s_num < I2S_NUM_MAX), ESP_ERR_INVALID_ARG, TAG, "i2s_num error"); - i2s_slot_config_t *slot_cfg = (i2s_slot_config_t *)p_i2s[i2s_num]->slot_cfg; + i2s_hal_slot_config_t *slot_cfg = &p_i2s[i2s_num]->slot_cfg; uint32_t mask = 0; #if SOC_I2S_SUPPORTS_TDM if (p_i2s[i2s_num]->mode == I2S_COMM_MODE_TDM) { @@ -1154,13 +1159,11 @@ esp_err_t i2s_set_pdm_rx_down_sample(i2s_port_t i2s_num, i2s_pdm_dsr_t downsampl ESP_RETURN_ON_FALSE((p_i2s[i2s_num]->mode == I2S_COMM_MODE_PDM), ESP_ERR_INVALID_ARG, TAG, "i2s mode is not PDM mode"); xSemaphoreTake(p_i2s[i2s_num]->rx->mux, portMAX_DELAY); i2s_stop(i2s_num); - i2s_pdm_rx_slot_config_t *slot_cfg = (i2s_pdm_rx_slot_config_t*)p_i2s[i2s_num]->slot_cfg; - i2s_pdm_rx_clk_config_t *clk_cfg = (i2s_pdm_rx_clk_config_t*)p_i2s[i2s_num]->clk_cfg; - clk_cfg->dn_sample_mode = downsample; + p_i2s[i2s_num]->clk_cfg.dn_sample_mode = downsample; i2s_ll_rx_set_pdm_dsr(p_i2s[i2s_num]->hal.dev, downsample); i2s_start(i2s_num); xSemaphoreGive(p_i2s[i2s_num]->rx->mux); - return i2s_set_clk(i2s_num, clk_cfg->sample_rate_hz, slot_cfg->data_bit_width, slot_cfg->slot_mode); + return i2s_set_clk(i2s_num, p_i2s[i2s_num]->clk_cfg.sample_rate_hz, p_i2s[i2s_num]->slot_cfg.data_bit_width, p_i2s[i2s_num]->slot_cfg.slot_mode); } #endif @@ -1172,14 +1175,12 @@ esp_err_t i2s_set_pdm_tx_up_sample(i2s_port_t i2s_num, const i2s_pdm_tx_upsample ESP_ERR_INVALID_ARG, TAG, "i2s mode is not PDM mode"); xSemaphoreTake(p_i2s[i2s_num]->tx->mux, portMAX_DELAY); i2s_stop(i2s_num); - i2s_pdm_tx_clk_config_t *clk_cfg = (i2s_pdm_tx_clk_config_t *)p_i2s[i2s_num]->clk_cfg; - i2s_pdm_tx_slot_config_t *slot_cfg = (i2s_pdm_tx_slot_config_t *)p_i2s[i2s_num]->slot_cfg; - clk_cfg->up_sample_fp = upsample_cfg->fp; - clk_cfg->up_sample_fs = upsample_cfg->fs; + p_i2s[i2s_num]->clk_cfg.up_sample_fp = upsample_cfg->fp; + p_i2s[i2s_num]->clk_cfg.up_sample_fs = upsample_cfg->fs; i2s_ll_tx_set_pdm_fpfs(p_i2s[i2s_num]->hal.dev, upsample_cfg->fp, upsample_cfg->fs); i2s_start(i2s_num); xSemaphoreGive(p_i2s[i2s_num]->tx->mux); - return i2s_set_clk(i2s_num, clk_cfg->sample_rate_hz, slot_cfg->data_bit_width, slot_cfg->slot_mode); + return i2s_set_clk(i2s_num, p_i2s[i2s_num]->clk_cfg.sample_rate_hz, p_i2s[i2s_num]->slot_cfg.data_bit_width, p_i2s[i2s_num]->slot_cfg.slot_mode); } #endif @@ -1237,33 +1238,31 @@ static void i2s_mode_identify(i2s_port_t i2s_num, const i2s_config_t *i2s_config static esp_err_t i2s_config_transfer(i2s_port_t i2s_num, const i2s_config_t *i2s_config) { + #define SLOT_CFG(m) p_i2s[i2s_num]->slot_cfg.m + #define CLK_CFG() p_i2s[i2s_num]->clk_cfg /* Convert legacy configuration into general part of slot and clock configuration */ - i2s_slot_config_t slot_cfg = {}; - slot_cfg.mode = p_i2s[i2s_num]->mode; - slot_cfg.data_bit_width = i2s_config->bits_per_sample; - slot_cfg.slot_bit_width = (int)i2s_config->bits_per_chan < (int)i2s_config->bits_per_sample ? + p_i2s[i2s_num]->slot_cfg.mode = p_i2s[i2s_num]->mode; + p_i2s[i2s_num]->slot_cfg.data_bit_width = i2s_config->bits_per_sample; + p_i2s[i2s_num]->slot_cfg.slot_bit_width = (int)i2s_config->bits_per_chan < (int)i2s_config->bits_per_sample ? i2s_config->bits_per_sample : i2s_config->bits_per_chan; + slot_cfg.slot_mode = i2s_config->channel_format < I2S_CHANNEL_FMT_ONLY_RIGHT ? I2S_SLOT_MODE_STEREO : I2S_SLOT_MODE_MONO; - i2s_clk_config_t clk_cfg = {}; - clk_cfg.sample_rate_hz = i2s_config->sample_rate; - clk_cfg.mclk_multiple = i2s_config->mclk_multiple == 0 ? I2S_MCLK_MULTIPLE_256 : i2s_config->mclk_multiple; - clk_cfg.clk_src = I2S_CLK_D2CLK; + CLK_CFG().sample_rate_hz = i2s_config->sample_rate; + CLK_CFG().mclk_multiple = i2s_config->mclk_multiple == 0 ? I2S_MCLK_MULTIPLE_256 : i2s_config->mclk_multiple; + CLK_CFG().clk_src = I2S_CLK_160M_PLL; p_i2s[i2s_num]->fixed_mclk = i2s_config->fixed_mclk; p_i2s[i2s_num]->use_apll = false; - #if SOC_I2S_SUPPORTS_APLL - clk_cfg.clk_src = i2s_config->use_apll ? I2S_CLK_APLL : I2S_CLK_D2CLK; +#if SOC_I2S_SUPPORTS_APLL + CLK_CFG().clk_src = i2s_config->use_apll ? I2S_CLK_APLL : I2S_CLK_160M_PLL; p_i2s[i2s_num]->use_apll = i2s_config->use_apll; - #endif // SOC_I2S_SUPPORTS_APLL +#endif // SOC_I2S_SUPPORTS_APLL /* Convert legacy configuration into particular part of slot and clock configuration */ if (p_i2s[i2s_num]->mode == I2S_COMM_MODE_STD) { /* Generate STD slot configuration */ - i2s_std_slot_config_t *std_slot = (i2s_std_slot_config_t *)calloc(1, sizeof(i2s_std_slot_config_t)); - ESP_RETURN_ON_FALSE(std_slot, ESP_ERR_NO_MEM, TAG, "no memory for slot configuration struct"); - memcpy(std_slot, &slot_cfg, sizeof(i2s_slot_config_t)); - std_slot->ws_width = i2s_config->bits_per_sample; - std_slot->ws_pol = false; + SLOT_CFG(std).ws_width = i2s_config->bits_per_sample; + SLOT_CFG(std).ws_pol = false; if (i2s_config->channel_format == I2S_CHANNEL_FMT_RIGHT_LEFT) { std_slot->slot_sel = I2S_STD_SLOT_LEFT_RIGHT; } else if (i2s_config->channel_format == I2S_CHANNEL_FMT_ALL_LEFT || @@ -1273,59 +1272,45 @@ static esp_err_t i2s_config_transfer(i2s_port_t i2s_num, const i2s_config_t *i2s std_slot->slot_sel = I2S_STD_SLOT_ONLY_RIGHT; } if (i2s_config->communication_format == I2S_COMM_FORMAT_STAND_I2S) { - std_slot->bit_shift = true; + SLOT_CFG(std).bit_shift = true; } if (i2s_config->communication_format & I2S_COMM_FORMAT_STAND_PCM_SHORT) { - std_slot->bit_shift = true; - std_slot->ws_width = 1; - std_slot->ws_pol = true; + SLOT_CFG(std).bit_shift = true; + SLOT_CFG(std).ws_width = 1; + SLOT_CFG(std).ws_pol = true; } - #if SOC_I2S_HW_VERSION_1 - std_slot->msb_right = false; - #elif SOC_I2S_HW_VERSION_2 - std_slot->left_align = i2s_config->left_align; - std_slot->big_endian = i2s_config->big_edin; - std_slot->bit_order_lsb = i2s_config->bit_order_msb; // The old name is incorrect - #endif // SOC_I2S_HW_VERSION_1 - p_i2s[i2s_num]->slot_cfg = std_slot; + #if SOC_I2S_HW_VERSION_1 + SLOT_CFG(std).msb_right = false; + #elif SOC_I2S_HW_VERSION_2 + SLOT_CFG(std).left_align = i2s_config->left_align; + SLOT_CFG(std).big_endian = i2s_config->big_edin; + SLOT_CFG(std).bit_order_lsb = i2s_config->bit_order_msb; // The old name is incorrect + #endif // SOC_I2S_HW_VERSION_1 - /* Generate STD clock configuration */ - i2s_std_clk_config_t *std_clk = (i2s_std_clk_config_t *)calloc(1, sizeof(i2s_std_clk_config_t)); - ESP_RETURN_ON_FALSE(std_clk, ESP_ERR_NO_MEM, TAG, "no memory for clock configuration struct"); - memcpy(std_clk, &clk_cfg, sizeof(i2s_clk_config_t)); - p_i2s[i2s_num]->clk_cfg = std_clk; - p_i2s[i2s_num]->active_slot = (int)std_slot->slot_mode; + p_i2s[i2s_num]->active_slot = (int)p_i2s[i2s_num]->slot_cfg.slot_mode == I2S_SLOT_MODE_MONO ? 1 : 2; p_i2s[i2s_num]->total_slot = 2; goto finish; } #if SOC_I2S_SUPPORTS_PDM_TX if (p_i2s[i2s_num]->mode == I2S_COMM_MODE_PDM) { /* Generate PDM TX slot configuration */ - i2s_pdm_tx_slot_config_t *pdm_tx_slot = (i2s_pdm_tx_slot_config_t *)calloc(1, sizeof(i2s_pdm_tx_slot_config_t)); - ESP_RETURN_ON_FALSE(pdm_tx_slot, ESP_ERR_NO_MEM, TAG, "no memory for slot configuration struct"); - memcpy(pdm_tx_slot, &slot_cfg, sizeof(i2s_slot_config_t)); - pdm_tx_slot->sd_prescale = 0; - pdm_tx_slot->sd_scale = I2S_PDM_SIG_SCALING_MUL_1; - pdm_tx_slot->hp_scale = I2S_PDM_SIG_SCALING_MUL_1; - pdm_tx_slot->lp_scale = I2S_PDM_SIG_SCALING_MUL_1; - pdm_tx_slot->sinc_scale = I2S_PDM_SIG_SCALING_MUL_1; + SLOT_CFG(pdm_tx).sd_prescale = 0; + SLOT_CFG(pdm_tx).sd_scale = I2S_PDM_SIG_SCALING_MUL_1; + SLOT_CFG(pdm_tx).hp_scale = I2S_PDM_SIG_SCALING_MUL_1; + SLOT_CFG(pdm_tx).lp_scale = I2S_PDM_SIG_SCALING_MUL_1; + SLOT_CFG(pdm_tx).sinc_scale = I2S_PDM_SIG_SCALING_MUL_1; #if SOC_I2S_HW_VERSION_2 - pdm_tx_slot->sd_en = true; - pdm_tx_slot->hp_en = true; - pdm_tx_slot->hp_cut_off_freq_hz = 49; - pdm_tx_slot->sd_dither = 0; - pdm_tx_slot->sd_dither2 = 0; + SLOT_CFG(pdm_tx).sd_en = true; + SLOT_CFG(pdm_tx).hp_en = true; + SLOT_CFG(pdm_tx).hp_cut_off_freq_hz = 49; + SLOT_CFG(pdm_tx).sd_dither = 0; + SLOT_CFG(pdm_tx).sd_dither2 = 0; #endif // SOC_I2S_HW_VERSION_2 - p_i2s[i2s_num]->slot_cfg = pdm_tx_slot; /* Generate PDM TX clock configuration */ - i2s_pdm_tx_clk_config_t *pdm_tx_clk = (i2s_pdm_tx_clk_config_t *)calloc(1, sizeof(i2s_pdm_tx_clk_config_t)); - ESP_RETURN_ON_FALSE(pdm_tx_clk, ESP_ERR_NO_MEM, TAG, "no memory for clock configuration struct"); - memcpy(pdm_tx_clk, &clk_cfg, sizeof(i2s_clk_config_t)); - pdm_tx_clk->up_sample_fp = 960; - pdm_tx_clk->up_sample_fs = i2s_config->sample_rate / 100; - p_i2s[i2s_num]->clk_cfg = pdm_tx_clk; - p_i2s[i2s_num]->active_slot = (int)pdm_tx_slot->slot_mode; + CLK_CFG().up_sample_fp = 960; + CLK_CFG().up_sample_fs = i2s_config->sample_rate / 100; + p_i2s[i2s_num]->active_slot = (int)p_i2s[i2s_num]->slot_cfg.slot_mode == I2S_SLOT_MODE_MONO ? 1 : 2; p_i2s[i2s_num]->total_slot = 2; goto finish; } @@ -1333,20 +1318,9 @@ static esp_err_t i2s_config_transfer(i2s_port_t i2s_num, const i2s_config_t *i2s #if SOC_I2S_SUPPORTS_PDM_RX if (p_i2s[i2s_num]->mode == I2S_COMM_MODE_PDM) { - /* Generate PDM RX slot configuration */ - i2s_pdm_rx_slot_config_t *pdm_rx_slot = (i2s_pdm_rx_slot_config_t *)calloc(1, sizeof(i2s_pdm_rx_slot_config_t)); - ESP_RETURN_ON_FALSE(pdm_rx_slot, ESP_ERR_NO_MEM, TAG, "no memory for slot configuration struct"); - memcpy(pdm_rx_slot, &slot_cfg, sizeof(i2s_slot_config_t)); - p_i2s[i2s_num]->slot_cfg = pdm_rx_slot; - - /* Generate PDM RX clock configuration */ - i2s_pdm_rx_clk_config_t *pdm_rx_clk = (i2s_pdm_rx_clk_config_t *)calloc(1, sizeof(i2s_pdm_rx_clk_config_t)); - ESP_RETURN_ON_FALSE(pdm_rx_clk, ESP_ERR_NO_MEM, TAG, "no memory for clock configuration struct"); - memcpy(pdm_rx_clk, &clk_cfg, sizeof(i2s_clk_config_t)); - pdm_rx_clk->dn_sample_mode = I2S_PDM_DSR_8S; - p_i2s[i2s_num]->clk_cfg = pdm_rx_clk; - p_i2s[i2s_num]->active_slot = (int)pdm_rx_slot->slot_mode; + CLK_CFG().dn_sample_mode = I2S_PDM_DSR_8S; + p_i2s[i2s_num]->active_slot = (int)p_i2s[i2s_num]->slot_cfg.slot_mode == I2S_SLOT_MODE_MONO ? 1 : 2; p_i2s[i2s_num]->total_slot = 2; goto finish; } @@ -1355,55 +1329,42 @@ static esp_err_t i2s_config_transfer(i2s_port_t i2s_num, const i2s_config_t *i2s #if SOC_I2S_SUPPORTS_TDM if (p_i2s[i2s_num]->mode == I2S_COMM_MODE_TDM) { /* Generate TDM slot configuration */ - i2s_tdm_slot_config_t *tdm_slot = (i2s_tdm_slot_config_t *)calloc(1, sizeof(i2s_tdm_slot_config_t)); - ESP_RETURN_ON_FALSE(tdm_slot, ESP_ERR_NO_MEM, TAG, "no memory for slot configuration struct"); - memcpy(tdm_slot, &slot_cfg, sizeof(i2s_slot_config_t)); - tdm_slot->slot_mask = i2s_config->chan_mask >> 16; - uint32_t mx_slot = i2s_get_max_channel_num(tdm_slot->slot_mask); - tdm_slot->total_slot = mx_slot < i2s_config->total_chan ? mx_slot : i2s_config->total_chan; - tdm_slot->ws_width = I2S_TDM_AUTO_WS_WIDTH; - tdm_slot->ws_pol = false; + SLOT_CFG(tdm).slot_mask = i2s_config->chan_mask >> 16; + + SLOT_CFG(tdm).ws_width = I2S_TDM_AUTO_WS_WIDTH; + tdm_slot->slot_mode = I2S_SLOT_MODE_STEREO; + SLOT_CFG(tdm).ws_pol = false; if (i2s_config->communication_format == I2S_COMM_FORMAT_STAND_I2S) { - tdm_slot->bit_shift = true; + SLOT_CFG(tdm).bit_shift = true; } else if (i2s_config->communication_format == I2S_COMM_FORMAT_STAND_PCM_SHORT) { - tdm_slot->bit_shift = true; - tdm_slot->ws_width = 1; - tdm_slot->ws_pol = true; + SLOT_CFG(tdm).bit_shift = true; + SLOT_CFG(tdm).ws_width = 1; + SLOT_CFG(tdm).ws_pol = true; } else if (i2s_config->communication_format == I2S_COMM_FORMAT_STAND_PCM_LONG) { - tdm_slot->bit_shift = true; - tdm_slot->ws_width = tdm_slot->slot_bit_width; - tdm_slot->ws_pol = true; + SLOT_CFG(tdm).bit_shift = true; + SLOT_CFG(tdm).ws_width = SLOT_CFG(tdm).slot_bit_width; + SLOT_CFG(tdm).ws_pol = true; } - tdm_slot->left_align = i2s_config->left_align; - tdm_slot->big_endian = i2s_config->big_edin; - tdm_slot->bit_order_lsb = i2s_config->bit_order_msb; // The old name is incorrect - tdm_slot->skip_mask = i2s_config->skip_msk; - p_i2s[i2s_num]->slot_cfg = tdm_slot; + SLOT_CFG(tdm).left_align = i2s_config->left_align; + SLOT_CFG(tdm).big_endian = i2s_config->big_edin; + SLOT_CFG(tdm).bit_order_lsb = i2s_config->bit_order_msb; // The old name is incorrect + SLOT_CFG(tdm).skip_mask = i2s_config->skip_msk; /* Generate TDM clock configuration */ - i2s_tdm_clk_config_t *tdm_clk = (i2s_tdm_clk_config_t *)calloc(1, sizeof(i2s_tdm_clk_config_t)); - ESP_RETURN_ON_FALSE(tdm_clk, ESP_ERR_NO_MEM, TAG, "no memory for clock configuration struct"); - memcpy(tdm_clk, &clk_cfg, sizeof(i2s_clk_config_t)); - p_i2s[i2s_num]->clk_cfg = tdm_clk; - p_i2s[i2s_num]->active_slot = i2s_get_active_channel_num(tdm_slot->slot_mask); - p_i2s[i2s_num]->total_slot = tdm_slot->total_slot; + p_i2s[i2s_num]->active_slot = __builtin_popcount(tdm_slot->slot_mode); + uint32_t mx_slot = 32 - __builtin_clz(SLOT_CFG(tdm).slot_mask); + mx_slot = mx_slot < 2 ? 2 : mx_slot; + p_i2s[i2s_num]->.total_slot = mx_slot < i2s_config->total_chan ? mx_slot : i2s_config->total_chan; goto finish; } #endif // SOC_I2S_SUPPORTS_TDM #if SOC_I2S_SUPPORTS_ADC_DAC if ((int)p_i2s[i2s_num]->mode == I2S_COMM_MODE_ADC_DAC) { - i2s_slot_config_t *adc_dac_slot = (i2s_slot_config_t *)calloc(1, sizeof(i2s_slot_config_t)); - ESP_RETURN_ON_FALSE(adc_dac_slot, ESP_ERR_NO_MEM, TAG, "no memory for slot configuration struct"); - memcpy(adc_dac_slot, &slot_cfg, sizeof(i2s_slot_config_t)); - p_i2s[i2s_num]->slot_cfg = adc_dac_slot; - - i2s_clk_config_t *adc_dac_clk = (i2s_clk_config_t *)calloc(1, sizeof(i2s_clk_config_t)); - ESP_RETURN_ON_FALSE(adc_dac_clk, ESP_ERR_NO_MEM, TAG, "no memory for clock configuration struct"); - memcpy(adc_dac_clk, &clk_cfg, sizeof(i2s_clk_config_t)); - p_i2s[i2s_num]->clk_cfg = adc_dac_clk; + p_i2s[i2s_num]->slot_cfg.slot_mode = (p_i2s[i2s_num]->dir & I2S_DIR_TX) ? + I2S_SLOT_MODE_STEREO : I2S_SLOT_MODE_MONO; p_i2s[i2s_num]->active_slot = (p_i2s[i2s_num]->dir & I2S_DIR_TX) ? 2 : 1; p_i2s[i2s_num]->total_slot = 2; } @@ -1554,10 +1515,10 @@ esp_err_t i2s_driver_uninstall(i2s_port_t i2s_num) if (obj->use_apll) { // switch back to PLL clock source if (obj->dir & I2S_DIR_TX) { - i2s_ll_tx_clk_set_src(obj->hal.dev, I2S_CLK_D2CLK); + i2s_ll_tx_clk_set_src(obj->hal.dev, I2S_CLK_160M_PLL); } if (obj->dir & I2S_DIR_RX) { - i2s_ll_rx_clk_set_src(obj->hal.dev, I2S_CLK_D2CLK); + i2s_ll_rx_clk_set_src(obj->hal.dev, I2S_CLK_160M_PLL); } periph_rtc_apll_release(); } @@ -1578,15 +1539,7 @@ esp_err_t i2s_driver_uninstall(i2s_port_t i2s_num) } #endif /* Disable module clock */ - i2s_priv_deregister_object(i2s_num); - if (obj->clk_cfg) { - free(obj->clk_cfg); - obj->clk_cfg = NULL; - } - if (obj->slot_cfg) { - free(obj->slot_cfg); - obj->slot_cfg = NULL; - } + i2s_platform_release_occupation(i2s_num); free(obj); p_i2s[i2s_num] = NULL; return ESP_OK; @@ -1603,7 +1556,7 @@ esp_err_t i2s_driver_install(i2s_port_t i2s_num, const i2s_config_t *i2s_config, /* Step 2: Allocate driver object and register to platform */ i2s_obj_t *i2s_obj = calloc(1, sizeof(i2s_obj_t)); ESP_RETURN_ON_FALSE(i2s_obj, ESP_ERR_NO_MEM, TAG, "no mem for I2S driver"); - if (i2s_priv_register_object(i2s_obj, i2s_num) != ESP_OK) { + if (i2s_platform_acquire_occupation(i2s_num, "i2s_legacy") != ESP_OK) { free(i2s_obj); ESP_LOGE(TAG, "register I2S object to platform failed"); return ESP_ERR_INVALID_STATE; @@ -1913,31 +1866,3 @@ esp_err_t i2s_set_pin(i2s_port_t i2s_num, const i2s_pin_config_t *pin) gpio_matrix_in_check_and_set(pin->data_in_num, i2s_periph_signal[i2s_num].data_in_sig, 0); return ESP_OK; } - -esp_err_t i2s_priv_register_object(void *driver_obj, int port_id) -{ - esp_err_t ret = ESP_ERR_NOT_FOUND; - ESP_RETURN_ON_FALSE(driver_obj && (port_id < SOC_I2S_NUM), ESP_ERR_INVALID_ARG, TAG, "invalid arguments"); - portENTER_CRITICAL(&i2s_platform_spinlock); - if (!p_i2s[port_id]) { - ret = ESP_OK; - p_i2s[port_id] = driver_obj; - periph_module_enable(i2s_periph_signal[port_id].module); - } - portEXIT_CRITICAL(&i2s_platform_spinlock); - return ret; -} - -esp_err_t i2s_priv_deregister_object(int port_id) -{ - esp_err_t ret = ESP_ERR_INVALID_STATE; - ESP_RETURN_ON_FALSE(port_id < SOC_I2S_NUM, ESP_ERR_INVALID_ARG, TAG, "invalid arguments"); - portENTER_CRITICAL(&i2s_platform_spinlock); - if (p_i2s[port_id]) { - ret = ESP_OK; - p_i2s[port_id] = NULL; - periph_module_disable(i2s_periph_signal[port_id].module); - } - portEXIT_CRITICAL(&i2s_platform_spinlock); - return ret; -} diff --git a/components/driver/i2s/i2s_pdm.c b/components/driver/i2s/i2s_pdm.c new file mode 100644 index 0000000000..ac7d40ce47 --- /dev/null +++ b/components/driver/i2s/i2s_pdm.c @@ -0,0 +1,533 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" +#include "hal/i2s_hal.h" +#include "driver/gpio.h" +#include "driver/i2s_pdm.h" +#include "i2s_private.h" +#include "clk_ctrl_os.h" +#include "esp_intr_alloc.h" +#include "esp_check.h" + +static const char *TAG = "I2S_PDM"; + +/*--------------------------------------------------------------- + PDM TX + ---------------------------------------------------------------*/ + +#if SOC_I2S_SUPPORTS_PDM_TX +static esp_err_t i2s_pdm_tx_calculate_clock(i2s_chan_handle_t handle, const i2s_pdm_tx_clk_config_t *clk_cfg, i2s_hal_clock_info_t *clk_info) +{ + uint32_t rate = clk_cfg->sample_rate_hz; + i2s_pdm_tx_clk_config_t *pdm_tx_clk = (i2s_pdm_tx_clk_config_t *)clk_cfg; + + clk_info->bclk = rate * I2S_LL_PDM_BCK_FACTOR * pdm_tx_clk->up_sample_fp / pdm_tx_clk->up_sample_fs; + clk_info->bclk_div = 8; + clk_info->mclk = clk_info->bclk * clk_info->bclk_div; +#if SOC_I2S_SUPPORTS_APLL + clk_info->sclk = clk_cfg->clk_src == I2S_CLK_160M_PLL ? I2S_LL_BASE_CLK : i2s_set_get_apll_freq(clk_info->mclk); +#else + clk_info->sclk = I2S_LL_BASE_CLK; +#endif + clk_info->mclk_div = clk_info->sclk / clk_info->mclk; + + /* Check if the configuration is correct */ + ESP_RETURN_ON_FALSE(clk_info->mclk_div, ESP_ERR_INVALID_ARG, TAG, "sample rate is too large"); + /* Set upsampling configuration */ + i2s_ll_tx_set_pdm_fpfs(handle->parent->hal.dev, pdm_tx_clk->up_sample_fp, pdm_tx_clk->up_sample_fs); + + return ESP_OK; +} + +static esp_err_t i2s_pdm_tx_set_clock(i2s_chan_handle_t handle, const i2s_pdm_tx_clk_config_t *clk_cfg) +{ + esp_err_t ret = ESP_OK; + i2s_pdm_tx_config_t *pdm_tx_cfg = (i2s_pdm_tx_config_t *)(handle->mode_info); + + /* If Power Management enabled, a PM lock will be created when there is no PM lock or clock source changed */ +#ifdef CONFIG_PM_ENABLE + // Create/Re-create power management lock + if (handle->pm_lock == NULL || pdm_tx_cfg->clk_cfg.clk_src != clk_cfg->clk_src) { + if (handle->pm_lock) { + ESP_RETURN_ON_ERROR(esp_pm_lock_delete(handle->pm_lock), TAG, "I2S delete old pm lock failed"); + } + esp_pm_lock_type_t pm_type = ESP_PM_APB_FREQ_MAX; +#if SOC_I2S_SUPPORTS_APLL + if (clk_cfg->clk_src == I2S_CLK_APLL) { + pm_type = ESP_PM_NO_LIGHT_SLEEP; + } +#endif // SOC_I2S_SUPPORTS_APLL + ESP_RETURN_ON_ERROR(esp_pm_lock_create(pm_type, 0, "i2s_driver", &handle->pm_lock), err, TAG, "I2S pm lock create failed"); + } +#endif //CONFIG_PM_ENABLE + +#if SOC_I2S_SUPPORTS_APLL + /* Enable APLL and acquire its lock when initializing or clock source changed to APLL */ + if (clk_cfg->clk_src == I2S_CLK_APLL && (handle->state == I2S_CHAN_STATE_INIT || pdm_tx_cfg->clk_cfg.clk_src == I2S_CLK_160M_PLL)) { + periph_rtc_apll_acquire(); + handle->apll_en = true; + } + /* Disable APLL and release its lock when clock source is changed to D2CLK */ + if (clk_cfg->clk_src == I2S_CLK_160M_PLL && pdm_tx_cfg->clk_cfg.clk_src == I2S_CLK_APLL) { + periph_rtc_apll_release(); + handle->apll_en = false; + } +#endif + + i2s_hal_clock_info_t clk_info; + /* Calculate clock parameters */ + ESP_RETURN_ON_ERROR(i2s_pdm_tx_calculate_clock(handle, clk_cfg, &clk_info), TAG, "clock calculate failed"); + ESP_LOGD(TAG, "Clock division info: [sclk] %d Hz [mdiv] %d [mclk] %d Hz [bdiv] %d [bclk] %d Hz", + clk_info.sclk, clk_info.mclk_div, clk_info.mclk, clk_info.bclk_div, clk_info.bclk); + + portENTER_CRITICAL(&s_i2s.spinlock); + /* Set clock configurations in HAL*/ + i2s_hal_set_tx_clock(&handle->parent->hal, &clk_info, clk_cfg->clk_src); + portEXIT_CRITICAL(&s_i2s.spinlock); + + return ret; +} + +static esp_err_t i2s_pdm_tx_set_slot(i2s_chan_handle_t handle, const i2s_pdm_tx_slot_config_t *slot_cfg) +{ + uint32_t buf_size = i2s_get_buf_size(handle, slot_cfg->data_bit_width, handle->dma.frame_num); + /* The DMA buffer need to re-allocate if the buffer size changed */ + if (handle->dma.buf_size != buf_size) { + handle->dma.buf_size = buf_size; + ESP_RETURN_ON_ERROR(i2s_free_dma_desc(handle), TAG, "failed to free the old dma descriptor"); + ESP_RETURN_ON_ERROR(i2s_alloc_dma_desc(handle, handle->dma.desc_num, buf_size), + TAG, "allocate memory for dma descriptor failed"); + } + /* Share bck and ws signal in full-duplex mode */ + i2s_ll_share_bck_ws(handle->parent->hal.dev, handle->parent->full_duplex); + + portENTER_CRITICAL(&s_i2s.spinlock); + /* Configure the hardware to apply PDM format */ + bool is_slave = handle->role == I2S_ROLE_SLAVE; + i2s_hal_pdm_set_tx_slot(&(handle->parent->hal), is_slave, (i2s_hal_slot_config_t*)slot_cfg); + portEXIT_CRITICAL(&s_i2s.spinlock); + + /* Update the total slot num and active slot num */ + handle->total_slot = 2; + handle->active_slot = slot_cfg->slot_mode == I2S_SLOT_MODE_MONO ? 1 : 2; + + return ESP_OK; +} + +static esp_err_t i2s_pdm_tx_set_gpio(i2s_chan_handle_t handle, const i2s_pdm_tx_gpio_config_t *gpio_cfg) +{ + int id = handle->parent->id; + + /* Check validity of selected pins */ + ESP_RETURN_ON_FALSE((gpio_cfg->clk == -1 || GPIO_IS_VALID_GPIO(gpio_cfg->clk)), + ESP_ERR_INVALID_ARG, TAG, "clk gpio is invalid"); + ESP_RETURN_ON_FALSE((gpio_cfg->dout == -1 || GPIO_IS_VALID_GPIO(gpio_cfg->dout)), + ESP_ERR_INVALID_ARG, TAG, "dout gpio is invalid"); + /* Set data output GPIO */ + i2s_gpio_check_and_set(gpio_cfg->dout, i2s_periph_signal[id].data_out_sig, false); + + if (handle->role == I2S_ROLE_SLAVE) { + /* For "tx + slave" mode, select TX signal index for ws and bck */ + if (!handle->parent->full_duplex) { + i2s_gpio_check_and_set(gpio_cfg->clk, i2s_periph_signal[id].s_tx_ws_sig, true); + /* For "tx + rx + slave" or "rx + slave" mode, select RX signal index for ws and bck */ + } else { + i2s_gpio_check_and_set(gpio_cfg->clk, i2s_periph_signal[id].s_rx_ws_sig, true); + } + } else { + i2s_gpio_check_and_set(gpio_cfg->clk, i2s_periph_signal[id].m_tx_ws_sig, false); + } +#if SOC_I2S_HW_VERSION_2 + i2s_ll_mclk_bind_to_tx_clk(handle->parent->hal.dev); +#endif + + return ESP_OK; +} + +esp_err_t i2s_init_pdm_tx_channel(i2s_chan_handle_t handle, const i2s_pdm_tx_config_t *pdm_tx_cfg) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + ESP_RETURN_ON_FALSE(handle->dir == I2S_DIR_TX, ESP_ERR_INVALID_ARG, TAG, "This channel handle is not a TX handle"); + ESP_RETURN_ON_FALSE(handle->parent->id == I2S_NUM_0, ESP_ERR_INVALID_ARG, TAG, "This channel handle is registered on I2S1, but PDM is only supported on I2S0"); + + esp_err_t ret = ESP_OK; + + xSemaphoreTake(handle->mutex, portMAX_DELAY); + ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_REGISTER, ESP_ERR_INVALID_STATE, err, TAG, "the channel has initialized already"); + ESP_GOTO_ON_ERROR(i2s_pdm_tx_set_gpio(handle, &pdm_tx_cfg->gpio_cfg), err, TAG, "initialize channel failed while setting gpio pins"); + /* i2s_set_slot should be called before i2s_set_clock while initializing, because clock is relay on the slot */ + ESP_GOTO_ON_ERROR(i2s_pdm_tx_set_slot(handle, &pdm_tx_cfg->slot_cfg), err, TAG, "initialize channel failed while setting slot"); + ESP_GOTO_ON_ERROR(i2s_pdm_tx_set_clock(handle, &pdm_tx_cfg->clk_cfg), err, TAG, "initialize channel failed while setting clock"); + ESP_GOTO_ON_ERROR(i2s_init_dma_intr(handle, ESP_INTR_FLAG_LEVEL1), err, TAG, "initialize dma interrupt failed"); + /* Store the configurations of standard mode */ + i2s_pdm_tx_config_t *mode_info = calloc(1, sizeof(i2s_pdm_tx_config_t)); + ESP_GOTO_ON_FALSE(mode_info, ESP_ERR_NO_MEM, err, TAG, "no memory for storing the configurations"); + memcpy(mode_info, pdm_tx_cfg, sizeof(i2s_pdm_tx_config_t)); + handle->mode_info = mode_info; + + i2s_ll_tx_enable_pdm(handle->parent->hal.dev); +#if SOC_I2S_HW_VERSION_2 + /* Enable clock to start outputting mclk signal. Some codecs will reset once mclk stop */ + i2s_ll_tx_enable_clock(handle->parent->hal.dev); +#endif + + /* Initialization finished, mark state as ready */ + handle->state = I2S_CHAN_STATE_READY; + xSemaphoreGive(handle->mutex); + return ret; + +err: + xSemaphoreGive(handle->mutex); + return ret; +} + +esp_err_t i2s_reconfig_pdm_tx_clock(i2s_chan_handle_t handle, const i2s_pdm_tx_clk_config_t *clk_cfg) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + I2S_NULL_POINTER_CHECK(TAG, clk_cfg); + ESP_RETURN_ON_FALSE(handle->dir == I2S_DIR_TX, ESP_ERR_INVALID_ARG, TAG, "This channel handle is not a TX handle"); + + esp_err_t ret = ESP_OK; + + xSemaphoreTake(handle->mutex, portMAX_DELAY); + ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_PDM, ESP_ERR_INVALID_ARG, err, TAG, "this handle is not working in standard moded"); + ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "invalid state, I2S should be stopped before reconfiguring the clock"); + + i2s_pdm_tx_config_t *pdm_tx_cfg = (i2s_pdm_tx_config_t*)handle->mode_info; + ESP_GOTO_ON_FALSE(pdm_tx_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); + + ESP_GOTO_ON_ERROR(i2s_pdm_tx_set_clock(handle, &pdm_tx_cfg->clk_cfg), err, TAG, "update clock failed"); + /* Update the stored clock information */ + memcpy(&pdm_tx_cfg->clk_cfg, clk_cfg, sizeof(i2s_pdm_tx_clk_config_t)); + + xSemaphoreGive(handle->mutex); + + return ESP_OK; +err: + xSemaphoreGive(handle->mutex); + return ret; +} + +esp_err_t i2s_reconfig_pdm_tx_slot(i2s_chan_handle_t handle, const i2s_pdm_tx_slot_config_t *slot_cfg) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + I2S_NULL_POINTER_CHECK(TAG, slot_cfg); + ESP_RETURN_ON_FALSE(handle->dir == I2S_DIR_TX, ESP_ERR_INVALID_ARG, TAG, "This channel handle is not a TX handle"); + + esp_err_t ret = ESP_OK; + + xSemaphoreTake(handle->mutex, portMAX_DELAY); + ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_PDM, ESP_ERR_INVALID_ARG, err, TAG, "this handle is not working in standard moded"); + ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "invalid state, I2S should be stopped before reconfiguring the slot"); + + i2s_pdm_tx_config_t *pdm_tx_cfg = (i2s_pdm_tx_config_t*)handle->mode_info; + ESP_GOTO_ON_FALSE(pdm_tx_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); + + ESP_GOTO_ON_ERROR(i2s_pdm_tx_set_slot(handle, slot_cfg), err, TAG, "set i2s standard slot failed"); + /* Update the stored slot information */ + memcpy(&pdm_tx_cfg->slot_cfg, slot_cfg, sizeof(i2s_pdm_tx_slot_config_t)); + + /* If the slot bit width changed, then need to update the clock */ + uint32_t slot_bits = slot_cfg->slot_bit_width == I2S_SLOT_BIT_WIDTH_AUTO ? slot_cfg->data_bit_width : slot_cfg->slot_bit_width; + if (pdm_tx_cfg->slot_cfg.slot_bit_width == slot_bits) { + ESP_GOTO_ON_ERROR(i2s_pdm_tx_set_clock(handle, &pdm_tx_cfg->clk_cfg), err, TAG, "update clock failed"); + } + + xSemaphoreGive(handle->mutex); + + return ESP_OK; +err: + xSemaphoreGive(handle->mutex); + return ret; +} + +esp_err_t i2s_reconfig_pdm_tx_gpio(i2s_chan_handle_t handle, const i2s_pdm_tx_gpio_config_t *gpio_cfg) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + I2S_NULL_POINTER_CHECK(TAG, gpio_cfg); + ESP_RETURN_ON_FALSE(handle->dir == I2S_DIR_TX, ESP_ERR_INVALID_ARG, TAG, "This channel handle is not a TX handle"); + + esp_err_t ret = ESP_OK; + + xSemaphoreTake(handle->mutex, portMAX_DELAY); + ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_PDM, ESP_ERR_INVALID_ARG, err, TAG, "This handle is not working in standard moded"); + ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "Invalid state, I2S should be stopped before reconfiguring the gpio"); + + i2s_pdm_tx_config_t *pdm_tx_cfg = (i2s_pdm_tx_config_t*)handle->mode_info; + ESP_GOTO_ON_FALSE(pdm_tx_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); + + ESP_GOTO_ON_ERROR(i2s_pdm_tx_set_gpio(handle, gpio_cfg), err, TAG, "set i2s standard slot failed"); + + /* Update the stored slot information */ + memcpy(&pdm_tx_cfg->gpio_cfg, gpio_cfg, sizeof(i2s_pdm_tx_gpio_config_t)); + xSemaphoreGive(handle->mutex); + + return ESP_OK; +err: + xSemaphoreGive(handle->mutex); + return ret; +} + +#endif + + +/*--------------------------------------------------------------- + PDM RX + ---------------------------------------------------------------*/ + +#if SOC_I2S_SUPPORTS_PDM_RX +static esp_err_t i2s_pdm_rx_calculate_clock(i2s_chan_handle_t handle, const i2s_pdm_rx_clk_config_t *clk_cfg, i2s_hal_clock_info_t *clk_info) +{ + uint32_t rate = clk_cfg->sample_rate_hz; + i2s_pdm_rx_clk_config_t *pdm_rx_clk = (i2s_pdm_rx_clk_config_t *)clk_cfg; + + clk_info->bclk = rate * I2S_LL_PDM_BCK_FACTOR * (pdm_rx_clk->dn_sample_mode == I2S_PDM_DSR_16S ? 2 : 1); + clk_info->bclk_div = 8; + clk_info->mclk = clk_info->bclk * clk_info->bclk_div; +#if SOC_I2S_SUPPORTS_APLL + clk_info->sclk = clk_cfg->clk_src == I2S_CLK_160M_PLL ? I2S_LL_BASE_CLK : i2s_set_get_apll_freq(clk_info->mclk); +#else + clk_info->sclk = I2S_LL_BASE_CLK; +#endif + clk_info->mclk_div = clk_info->sclk / clk_info->mclk; + + /* Check if the configuration is correct */ + ESP_RETURN_ON_FALSE(clk_info->mclk_div, ESP_ERR_INVALID_ARG, TAG, "sample rate is too large"); + /* Set down-sampling configuration */ + i2s_ll_rx_set_pdm_dsr(handle->parent->hal.dev, pdm_rx_clk->dn_sample_mode); + return ESP_OK; +} + +static esp_err_t i2s_pdm_rx_set_clock(i2s_chan_handle_t handle, const i2s_pdm_rx_clk_config_t *clk_cfg) +{ + esp_err_t ret = ESP_OK; + i2s_pdm_rx_config_t *pdm_rx_cfg = (i2s_pdm_rx_config_t *)(handle->mode_info); + + /* If Power Management enabled, a PM lock will be created when there is no PM lock or clock source changed */ +#ifdef CONFIG_PM_ENABLE + // Create/Re-create power management lock + if (handle->pm_lock == NULL || pdm_rx_cfg->clk_cfg.clk_src != clk_cfg->clk_src) { + if (handle->pm_lock) { + ESP_RETURN_ON_ERROR(esp_pm_lock_delete(handle->pm_lock), TAG, "I2S delete old pm lock failed"); + } + esp_pm_lock_type_t pm_type = ESP_PM_APB_FREQ_MAX; +#if SOC_I2S_SUPPORTS_APLL + if (clk_cfg->clk_src == I2S_CLK_APLL) { + pm_type = ESP_PM_NO_LIGHT_SLEEP; + } +#endif // SOC_I2S_SUPPORTS_APLL + ESP_RETURN_ON_ERROR(esp_pm_lock_create(pm_type, 0, "i2s_driver", &handle->pm_lock), err, TAG, "I2S pm lock create failed"); + } +#endif //CONFIG_PM_ENABLE + +#if SOC_I2S_SUPPORTS_APLL + /* Enable APLL and acquire its lock when initializing or clock source changed to APLL */ + if (clk_cfg->clk_src == I2S_CLK_APLL && (handle->state == I2S_CHAN_STATE_INIT || pdm_rx_cfg->clk_cfg.clk_src == I2S_CLK_160M_PLL)) { + periph_rtc_apll_acquire(); + handle->apll_en = true; + } + /* Disable APLL and release its lock when clock source is changed to D2CLK */ + if (clk_cfg->clk_src == I2S_CLK_160M_PLL && pdm_rx_cfg->clk_cfg.clk_src == I2S_CLK_APLL) { + periph_rtc_apll_release(); + handle->apll_en = false; + } +#endif + + i2s_hal_clock_info_t clk_info; + /* Calculate clock parameters */ + ESP_RETURN_ON_ERROR(i2s_pdm_rx_calculate_clock(handle, clk_cfg, &clk_info), TAG, "clock calculate failed"); + ESP_LOGD(TAG, "Clock division info: [sclk] %d Hz [mdiv] %d [mclk] %d Hz [bdiv] %d [bclk] %d Hz", + clk_info.sclk, clk_info.mclk_div, clk_info.mclk, clk_info.bclk_div, clk_info.bclk); + + portENTER_CRITICAL(&s_i2s.spinlock); + /* Set clock configurations in HAL*/ + i2s_hal_set_rx_clock(&handle->parent->hal, &clk_info, clk_cfg->clk_src); + portEXIT_CRITICAL(&s_i2s.spinlock); + + return ret; +} + +static esp_err_t i2s_pdm_rx_set_slot(i2s_chan_handle_t handle, const i2s_pdm_rx_slot_config_t *slot_cfg) +{ + uint32_t buf_size = i2s_get_buf_size(handle, slot_cfg->data_bit_width, handle->dma.frame_num); + /* The DMA buffer need to re-allocate if the buffer size changed */ + if (handle->dma.buf_size != buf_size) { + handle->dma.buf_size = buf_size; + ESP_RETURN_ON_ERROR(i2s_free_dma_desc(handle), TAG, "failed to free the old dma descriptor"); + ESP_RETURN_ON_ERROR(i2s_alloc_dma_desc(handle, handle->dma.desc_num, buf_size), + TAG, "allocate memory for dma descriptor failed"); + } + /* Share bck and ws signal in full-duplex mode */ + i2s_ll_share_bck_ws(handle->parent->hal.dev, handle->parent->full_duplex); + + portENTER_CRITICAL(&s_i2s.spinlock); + /* Configure the hardware to apply PDM format */ + bool is_slave = (handle->role == I2S_ROLE_SLAVE) | handle->parent->full_duplex; + i2s_hal_pdm_set_rx_slot(&(handle->parent->hal), is_slave, (i2s_hal_slot_config_t*)slot_cfg); + portEXIT_CRITICAL(&s_i2s.spinlock); + + /* Update the total slot num and active slot num */ + handle->total_slot = 2; + handle->active_slot = slot_cfg->slot_mode == I2S_SLOT_MODE_MONO ? 1 : 2; + + return ESP_OK; +} + +static esp_err_t i2s_pdm_rx_set_gpio(i2s_chan_handle_t handle, const i2s_pdm_rx_gpio_config_t *gpio_cfg) +{ + int id = handle->parent->id; + + /* Check validity of selected pins */ + ESP_RETURN_ON_FALSE((gpio_cfg->clk == -1 || GPIO_IS_VALID_GPIO(gpio_cfg->clk)), + ESP_ERR_INVALID_ARG, TAG, "clk gpio is invalid"); + ESP_RETURN_ON_FALSE((gpio_cfg->din == -1 || GPIO_IS_VALID_GPIO(gpio_cfg->din)), + ESP_ERR_INVALID_ARG, TAG, "dout gpio is invalid"); + /* Set data input GPIO */ + i2s_gpio_check_and_set(gpio_cfg->din, i2s_periph_signal[id].data_in_sig, true); + + if (handle->role == I2S_ROLE_SLAVE) { + /* For "tx + rx + slave" or "rx + slave" mode, select RX signal index for ws and bck */ + i2s_gpio_check_and_set(gpio_cfg->clk, i2s_periph_signal[id].s_rx_ws_sig, true); + } else { + if (!handle->parent->full_duplex) { + i2s_gpio_check_and_set(gpio_cfg->clk, i2s_periph_signal[id].m_rx_ws_sig, false); + } else { + i2s_gpio_check_and_set(gpio_cfg->clk, i2s_periph_signal[id].m_tx_ws_sig, false); + } + } +#if SOC_I2S_HW_VERSION_2 + i2s_ll_mclk_bind_to_rx_clk(handle->parent->hal.dev); +#endif + + return ESP_OK; +} + +esp_err_t i2s_init_pdm_rx_channel(i2s_chan_handle_t handle, const i2s_pdm_rx_config_t *pdm_rx_cfg) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + ESP_RETURN_ON_FALSE(handle->dir == I2S_DIR_RX, ESP_ERR_INVALID_ARG, TAG, "This channel handle is not a RX handle"); + ESP_RETURN_ON_FALSE(handle->parent->id == I2S_NUM_0, ESP_ERR_INVALID_ARG, TAG, "This channel handle is registered on I2S1, but PDM is only supported on I2S0"); + + esp_err_t ret = ESP_OK; + + xSemaphoreTake(handle->mutex, portMAX_DELAY); + ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_REGISTER, ESP_ERR_INVALID_STATE, err, TAG, "the channel has initialized already"); + ESP_GOTO_ON_ERROR(i2s_pdm_rx_set_gpio(handle, &pdm_rx_cfg->gpio_cfg), err, TAG, "initialize channel failed while setting gpio pins"); + /* i2s_set_slot should be called before i2s_set_clock while initializing, because clock is relay on the slot */ + ESP_GOTO_ON_ERROR(i2s_pdm_rx_set_slot(handle, &pdm_rx_cfg->slot_cfg), err, TAG, "initialize channel failed while setting slot"); + ESP_GOTO_ON_ERROR(i2s_pdm_rx_set_clock(handle, &pdm_rx_cfg->clk_cfg), err, TAG, "initialize channel failed while setting clock"); + ESP_GOTO_ON_ERROR(i2s_init_dma_intr(handle, ESP_INTR_FLAG_LEVEL1), err, TAG, "initialize dma interrupt failed"); + /* Store the configurations of standard mode */ + i2s_pdm_rx_config_t *mode_info = calloc(1, sizeof(i2s_pdm_rx_config_t)); + ESP_GOTO_ON_FALSE(mode_info, ESP_ERR_NO_MEM, err, TAG, "no memory for storing the configurations"); + memcpy(mode_info, pdm_rx_cfg, sizeof(i2s_pdm_rx_config_t)); + handle->mode_info = mode_info; + + i2s_ll_rx_enable_pdm(handle->parent->hal.dev); +#if SOC_I2S_HW_VERSION_2 + /* Enable clock to start outputting mclk signal. Some codecs will reset once mclk stop */ + i2s_ll_rx_enable_clock(handle->parent->hal.dev); +#endif + + /* Initialization finished, mark state as ready */ + handle->state = I2S_CHAN_STATE_READY; + xSemaphoreGive(handle->mutex); + return ret; + +err: + xSemaphoreGive(handle->mutex); + return ret; +} + +esp_err_t i2s_reconfig_pdm_rx_clock(i2s_chan_handle_t handle, const i2s_pdm_rx_clk_config_t *clk_cfg) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + I2S_NULL_POINTER_CHECK(TAG, clk_cfg); + ESP_RETURN_ON_FALSE(handle->dir == I2S_DIR_RX, ESP_ERR_INVALID_ARG, TAG, "This channel handle is not a RX handle"); + + esp_err_t ret = ESP_OK; + + xSemaphoreTake(handle->mutex, portMAX_DELAY); + ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_PDM, ESP_ERR_INVALID_ARG, err, TAG, "this handle is not working in standard moded"); + ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "invalid state, I2S should be stopped before reconfiguring the clock"); + + i2s_pdm_rx_config_t *pdm_rx_cfg = (i2s_pdm_rx_config_t*)handle->mode_info; + ESP_GOTO_ON_FALSE(pdm_rx_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); + + ESP_GOTO_ON_ERROR(i2s_pdm_rx_set_clock(handle, &pdm_rx_cfg->clk_cfg), err, TAG, "update clock failed"); + /* Update the stored clock information */ + memcpy(&pdm_rx_cfg->clk_cfg, clk_cfg, sizeof(i2s_pdm_rx_clk_config_t)); + + xSemaphoreGive(handle->mutex); + + return ESP_OK; +err: + xSemaphoreGive(handle->mutex); + return ret; +} + +esp_err_t i2s_reconfig_pdm_rx_slot(i2s_chan_handle_t handle, const i2s_pdm_rx_slot_config_t *slot_cfg) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + I2S_NULL_POINTER_CHECK(TAG, slot_cfg); + ESP_RETURN_ON_FALSE(handle->dir == I2S_DIR_RX, ESP_ERR_INVALID_ARG, TAG, "This channel handle is not a RX handle"); + + esp_err_t ret = ESP_OK; + + xSemaphoreTake(handle->mutex, portMAX_DELAY); + ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_PDM, ESP_ERR_INVALID_ARG, err, TAG, "this handle is not working in standard moded"); + ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "invalid state, I2S should be stopped before reconfiguring the slot"); + + i2s_pdm_rx_config_t *pdm_rx_cfg = (i2s_pdm_rx_config_t*)handle->mode_info; + ESP_GOTO_ON_FALSE(pdm_rx_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); + + ESP_GOTO_ON_ERROR(i2s_pdm_rx_set_slot(handle, slot_cfg), err, TAG, "set i2s standard slot failed"); + /* Update the stored slot information */ + memcpy(&pdm_rx_cfg->slot_cfg, slot_cfg, sizeof(i2s_pdm_rx_slot_config_t)); + + /* If the slot bit width changed, then need to update the clock */ + uint32_t slot_bits = slot_cfg->slot_bit_width == I2S_SLOT_BIT_WIDTH_AUTO ? slot_cfg->data_bit_width : slot_cfg->slot_bit_width; + if (pdm_rx_cfg->slot_cfg.slot_bit_width == slot_bits) { + ESP_GOTO_ON_ERROR(i2s_pdm_rx_set_clock(handle, &pdm_rx_cfg->clk_cfg), err, TAG, "update clock failed"); + } + + xSemaphoreGive(handle->mutex); + + return ESP_OK; +err: + xSemaphoreGive(handle->mutex); + return ret; +} + +esp_err_t i2s_reconfig_pdm_rx_gpio(i2s_chan_handle_t handle, const i2s_pdm_rx_gpio_config_t *gpio_cfg) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + I2S_NULL_POINTER_CHECK(TAG, gpio_cfg); + + esp_err_t ret = ESP_OK; + + xSemaphoreTake(handle->mutex, portMAX_DELAY); + ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_PDM, ESP_ERR_INVALID_ARG, err, TAG, "This handle is not working in standard moded"); + ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "Invalid state, I2S should be stopped before reconfiguring the gpio"); + + i2s_pdm_rx_config_t *pdm_rx_cfg = (i2s_pdm_rx_config_t*)handle->mode_info; + ESP_GOTO_ON_FALSE(pdm_rx_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); + + ESP_GOTO_ON_ERROR(i2s_pdm_rx_set_gpio(handle, gpio_cfg), err, TAG, "set i2s standard slot failed"); + + /* Update the stored slot information */ + memcpy(&pdm_rx_cfg->gpio_cfg, gpio_cfg, sizeof(i2s_pdm_rx_gpio_config_t)); + xSemaphoreGive(handle->mutex); + + return ESP_OK; +err: + xSemaphoreGive(handle->mutex); + return ret; +} + +#endif // SOC_I2S_SUPPORTS_PDM_RX diff --git a/components/driver/i2s/i2s_private.h b/components/driver/i2s/i2s_private.h new file mode 100644 index 0000000000..cfd021e904 --- /dev/null +++ b/components/driver/i2s/i2s_private.h @@ -0,0 +1,131 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "freertos/FreeRTOS.h" +#include "soc/lldesc.h" +#include "soc/soc_caps.h" +#include "hal/i2s_types.h" +#include "freertos/semphr.h" +#include "freertos/queue.h" +#if SOC_GDMA_SUPPORTED +#include "esp_private/gdma.h" +#endif +#include "esp_pm.h" +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define I2S_NULL_POINTER_CHECK(tag, p) ESP_RETURN_ON_FALSE((p), ESP_ERR_INVALID_ARG, tag, "[%s:%d] input parameter '"#p"' is NULL",__FUNCTION__,__LINE__) + +/** + * @brief i2s channel state for checking if the operation in under right driver state + */ +typedef enum { + I2S_CHAN_STATE_REGISTER, /*!< i2s channel is registered (not initialized) */ + I2S_CHAN_STATE_INIT, /*!< i2s channel is initializing */ + I2S_CHAN_STATE_READY, /*!< i2s channel is stopped (initialized) */ + I2S_CHAN_STATE_IDLE, /*!< i2s channel is idling (initialized and started) */ + I2S_CHAN_STATE_WRITING, /*!< i2s channel is writing (initialized and started) */ + I2S_CHAN_STATE_READING /*!< i2s channel is reading (initialized and started) */ +} i2s_state_t; + +/** + * @brief i2s channel level configurations + * @note It performs as channel handle + */ +typedef struct { +#if SOC_GDMA_SUPPORTED + gdma_channel_handle_t dma_chan; /*!< gdma channel handler */ +#endif + uint32_t desc_num; /*!< I2S DMA buffer number, it is also the number of DMA descriptor */ + uint32_t frame_num; /*!< I2S frame number in one DMA buffer. One frame means one-time sample data in all slots */ + uint32_t buf_size; /*!< dma buffer size */ + bool auto_clear; /*!< Set to auto clear DMA TX descriptor, i2s will always send zero automatically if no data to send */ + uint32_t rw_pos; /*!< reading/writing pointer position */ + void *curr_ptr; /*!< Pointer to current dma buffer */ + lldesc_t **desc; /*!< dma descriptor array */ + uint8_t **bufs; /*!< dma buffer array */ +} i2s_dma_t; + +/** + * @brief i2s controller level configurations + * @note Both i2s rx and tx channel are under its control + */ +typedef struct { + i2s_port_t id; /*!< i2s port id */ + i2s_hal_context_t hal; /*!< hal context */ + uint32_t chan_occupancy; /*!< channel occupancy (rx/tx) */ + bool full_duplex; /*!< is full_duplex */ + i2s_chan_handle_t tx_chan; /*!< tx channel handler */ + i2s_chan_handle_t rx_chan; /*!< rx channel handler */ + int mclk; /*!< MCK out pin, shared by tx/rx*/ + +#if !SOC_GDMA_SUPPORTED + intr_handle_t i2s_isr_handle; /*!< i2s interrupt handler */ +#endif +} i2s_controller_t; + +struct i2s_channel_t { + /* Channel basic information */ + i2s_controller_t *parent; /*!< Parent pointer to controller object */ + i2s_comm_mode_t mode; /*!< i2s channel communication mode */ + i2s_role_t role; /*!< i2s role */ + i2s_dir_t dir; /*!< i2s channel direction */ + i2s_dma_t dma; /*!< i2s dma object */ + i2s_state_t state; /*!< i2s driver state. Ensuring the driver working in a correct sequence */ + /* Stored configurations */ + void *mode_info; /*!< Slot, clock and gpio information of each mode */ +#if SOC_I2S_SUPPORTS_APLL + bool apll_en; /*!< Flag of wether APLL enabled */ +#endif + uint32_t active_slot; /*!< Active slot number */ + uint32_t total_slot; /*!< Total slot number */ + /* Locks and queues */ + SemaphoreHandle_t mutex; /*!< Mutex for DMA buffer related operations like reading/writing */ + esp_pm_lock_handle_t pm_lock; /*!< Power management lock, to avoid apb clock frequency changes while i2s is working */ + QueueHandle_t msg_queue; /*!< Message queue handler, used for transporting data between interrupt and read/write task */ + QueueHandle_t event_queue; /*!< Event queue handler, used for transporting interrupt event to user */ + + /* Function pointers of the corresponding mode */ + void (*start)(i2s_chan_handle_t); /*!< start tx/rx channel */ + void (*stop)(i2s_chan_handle_t); /*!< stop tx/rx channel */ +}; + +/** + * @brief i2s platform level configurations + * @note All i2s controllers are under its control + */ +typedef struct { + portMUX_TYPE spinlock; /*!< Platform level lock */ + i2s_controller_t *controller[I2S_NUM_MAX]; /*!< Controller object */ + const char *comp_name[I2S_NUM_MAX]; /*!< The component name that occupied i2s controller */ +} i2s_platform_t; + +extern i2s_platform_t s_i2s; + +esp_err_t i2s_init_dma_intr(i2s_chan_handle_t handle, int intr_flag); + +esp_err_t i2s_free_dma_desc(i2s_chan_handle_t handle); + +esp_err_t i2s_alloc_dma_desc(i2s_chan_handle_t handle, uint32_t num, uint32_t bufsize); + +uint32_t i2s_get_buf_size(i2s_chan_handle_t handle, uint32_t data_bit_width, uint32_t dma_frame_num); + +#if SOC_I2S_SUPPORTS_APLL +uint32_t i2s_set_get_apll_freq(uint32_t mclk_freq); +#endif + +void i2s_gpio_check_and_set(gpio_num_t gpio, uint32_t signal_idx, bool is_input); + +esp_err_t i2s_check_set_mclk(i2s_port_t id, gpio_num_t gpio_num); + +#ifdef __cplusplus +} +#endif diff --git a/components/driver/i2s/i2s_std.c b/components/driver/i2s/i2s_std.c new file mode 100644 index 0000000000..9548333643 --- /dev/null +++ b/components/driver/i2s/i2s_std.c @@ -0,0 +1,315 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" +#include "hal/i2s_hal.h" +#include "driver/gpio.h" +#include "driver/i2s_std.h" +#include "i2s_private.h" +#include "clk_ctrl_os.h" +#include "esp_intr_alloc.h" +#include "esp_check.h" + +const static char *TAG = "I2S_STD"; + +static esp_err_t i2s_std_calculate_clock(i2s_chan_handle_t handle, const i2s_std_clk_config_t *clk_cfg, i2s_hal_clock_info_t *clk_info) +{ + uint32_t rate = clk_cfg->sample_rate_hz; + i2s_std_slot_config_t *slot_cfg = &((i2s_std_config_t *)(handle->mode_info))->slot_cfg; + uint32_t slot_bits = (slot_cfg->slot_bit_width == I2S_SLOT_BIT_WIDTH_AUTO) || + ((int)slot_cfg->slot_bit_width < (int)slot_cfg->data_bit_width) ? + slot_cfg->data_bit_width : slot_cfg->slot_bit_width; + /* Calculate multiple + * Fmclk = bck_div*fbck = fsclk/(mclk_div+b/a) */ + if (handle->role == I2S_ROLE_MASTER) { + clk_info->bclk = rate * handle->total_slot * slot_bits; + clk_info->mclk = rate * clk_cfg->mclk_multiple; + clk_info->bclk_div = clk_info->mclk / clk_info->bclk; + } else { + /* For slave mode, mclk >= bclk * 8, so fix bclk_div to 2 first */ + clk_info->bclk_div = 8; + clk_info->bclk = rate * handle->total_slot * slot_bits; + clk_info->mclk = clk_info->bclk * clk_info->bclk_div; + } +#if SOC_I2S_SUPPORTS_APLL + clk_info->sclk = clk_cfg->clk_src == I2S_CLK_160M_PLL ? I2S_LL_BASE_CLK : i2s_set_get_apll_freq(clk_info->mclk); +#else + clk_info->sclk = I2S_LL_BASE_CLK; +#endif + clk_info->mclk_div = clk_info->sclk / clk_info->mclk; + + /* Check if the configuration is correct */ + ESP_RETURN_ON_FALSE(clk_info->mclk_div, ESP_ERR_INVALID_ARG, TAG, "sample rate is too large"); + + return ESP_OK; +} + +static esp_err_t i2s_std_set_clock(i2s_chan_handle_t handle, const i2s_std_clk_config_t *clk_cfg) +{ + esp_err_t ret = ESP_OK; + i2s_std_config_t *std_cfg = (i2s_std_config_t *)(handle->mode_info); + + /* If Power Management enabled, a PM lock will be created when there is no PM lock or clock source changed */ +#ifdef CONFIG_PM_ENABLE + // Create/Re-create power management lock + if (handle->pm_lock == NULL || std_cfg->clk_cfg.clk_src != clk_cfg->clk_src) { + if (handle->pm_lock) { + ESP_RETURN_ON_ERROR(esp_pm_lock_delete(handle->pm_lock), TAG, "I2S delete old pm lock failed"); + } + esp_pm_lock_type_t pm_type = ESP_PM_APB_FREQ_MAX; +#if SOC_I2S_SUPPORTS_APLL + if (clk_cfg->clk_src == I2S_CLK_APLL) { + pm_type = ESP_PM_NO_LIGHT_SLEEP; + } +#endif // SOC_I2S_SUPPORTS_APLL + ESP_RETURN_ON_ERROR(esp_pm_lock_create(pm_type, 0, "i2s_driver", &handle->pm_lock), err, TAG, "I2S pm lock create failed"); + } +#endif //CONFIG_PM_ENABLE + +#if SOC_I2S_SUPPORTS_APLL + /* Enable APLL and acquire its lock when initializing or clock source changed to APLL */ + if (clk_cfg->clk_src == I2S_CLK_APLL && (handle->state == I2S_CHAN_STATE_INIT || std_cfg->clk_cfg.clk_src == I2S_CLK_160M_PLL)) { + periph_rtc_apll_acquire(); + handle->apll_en = true; + } + /* Disable APLL and release its lock when clock source is changed to D2CLK */ + if (clk_cfg->clk_src == I2S_CLK_160M_PLL && std_cfg->clk_cfg.clk_src == I2S_CLK_APLL) { + periph_rtc_apll_release(); + handle->apll_en = false; + } +#endif + + i2s_hal_clock_info_t clk_info; + /* Calculate clock parameters */ + ESP_RETURN_ON_ERROR(i2s_std_calculate_clock(handle, clk_cfg, &clk_info), TAG, "clock calculate failed"); + ESP_LOGD(TAG, "Clock division info: [sclk] %d Hz [mdiv] %d [mclk] %d Hz [bdiv] %d [bclk] %d Hz", + clk_info.sclk, clk_info.mclk_div, clk_info.mclk, clk_info.bclk_div, clk_info.bclk); + + portENTER_CRITICAL(&s_i2s.spinlock); + /* Set clock configurations in HAL*/ + if (handle->dir == I2S_DIR_TX) { + i2s_hal_set_tx_clock(&handle->parent->hal, &clk_info, clk_cfg->clk_src); + } else { + i2s_hal_set_rx_clock(&handle->parent->hal, &clk_info, clk_cfg->clk_src); + } + portEXIT_CRITICAL(&s_i2s.spinlock); + + return ret; +} + +static esp_err_t i2s_std_set_slot(i2s_chan_handle_t handle, const i2s_std_slot_config_t *slot_cfg) +{ + uint32_t buf_size = i2s_get_buf_size(handle, slot_cfg->data_bit_width, handle->dma.frame_num); + /* The DMA buffer need to re-allocate if the buffer size changed */ + if (handle->dma.buf_size != buf_size) { + handle->dma.buf_size = buf_size; + ESP_RETURN_ON_ERROR(i2s_free_dma_desc(handle), TAG, "failed to free the old dma descriptor"); + ESP_RETURN_ON_ERROR(i2s_alloc_dma_desc(handle, handle->dma.desc_num, buf_size), + TAG, "allocate memory for dma descriptor failed"); + } + bool is_slave = handle->role == I2S_ROLE_SLAVE; + /* Share bck and ws signal in full-duplex mode */ + if (handle->parent->full_duplex) { + i2s_ll_share_bck_ws(handle->parent->hal.dev, true); + /* Since bck and ws are shared, only tx or rx can be master + Force to set rx as slave to avoid conflict of clock signal */ + if (handle->dir == I2S_DIR_RX) { + is_slave = true; + } + } else { + i2s_ll_share_bck_ws(handle->parent->hal.dev, false); + } + + portENTER_CRITICAL(&s_i2s.spinlock); + /* Configure the hardware to apply STD format */ + if (handle->dir == I2S_DIR_TX) { + i2s_hal_std_set_tx_slot(&(handle->parent->hal), is_slave, (i2s_hal_slot_config_t*)slot_cfg); + } else { + i2s_hal_std_set_rx_slot(&(handle->parent->hal), is_slave, (i2s_hal_slot_config_t*)slot_cfg); + } + portEXIT_CRITICAL(&s_i2s.spinlock); + + /* Update the total slot num and active slot num */ + handle->total_slot = 2; + handle->active_slot = slot_cfg->slot_mode == I2S_SLOT_MODE_MONO ? 1 : 2; + + return ESP_OK; +} + +static esp_err_t i2s_std_set_gpio(i2s_chan_handle_t handle, const i2s_std_gpio_config_t *gpio_cfg) +{ + int id = handle->parent->id; + + /* Check validity of selected pins */ + ESP_RETURN_ON_FALSE((gpio_cfg->bclk == -1 || GPIO_IS_VALID_GPIO(gpio_cfg->bclk)), + ESP_ERR_INVALID_ARG, TAG, "bclk invalid"); + ESP_RETURN_ON_FALSE((gpio_cfg->ws == -1 || GPIO_IS_VALID_GPIO(gpio_cfg->ws)), + ESP_ERR_INVALID_ARG, TAG, "ws invalid"); + if (handle->dir == I2S_DIR_TX) { + /* Set data output GPIO */ + i2s_gpio_check_and_set(gpio_cfg->dout, i2s_periph_signal[id].data_out_sig, false); + } else { + /* Set data input GPIO */ + i2s_gpio_check_and_set(gpio_cfg->din, i2s_periph_signal[id].data_in_sig, true); + } + + if (handle->role == I2S_ROLE_SLAVE) { + /* For "tx + slave" mode, select TX signal index for ws and bck */ + if (handle->dir == I2S_DIR_TX && !handle->parent->full_duplex) { +#if SOC_I2S_HW_VERSION_2 + i2s_ll_mclk_bind_to_tx_clk(handle->parent->hal.dev); +#endif + i2s_gpio_check_and_set(gpio_cfg->ws, i2s_periph_signal[id].s_tx_ws_sig, true); + i2s_gpio_check_and_set(gpio_cfg->bclk, i2s_periph_signal[id].s_tx_bck_sig, true); + /* For "tx + rx + slave" or "rx + slave" mode, select RX signal index for ws and bck */ + } else { + i2s_gpio_check_and_set(gpio_cfg->ws, i2s_periph_signal[id].s_rx_ws_sig, true); + i2s_gpio_check_and_set(gpio_cfg->bclk, i2s_periph_signal[id].s_rx_bck_sig, true); + } + } else { + /* mclk only available in master mode */ + ESP_RETURN_ON_ERROR(i2s_check_set_mclk(id, handle->parent->mclk), TAG, "mclk config failed"); + /* For "rx + master" mode, select RX signal index for ws and bck */ + if (handle->dir == I2S_DIR_RX && !handle->parent->full_duplex) { +#if SOC_I2S_HW_VERSION_2 + i2s_ll_mclk_bind_to_rx_clk(handle->parent->hal.dev); +#endif + i2s_gpio_check_and_set(gpio_cfg->ws, i2s_periph_signal[id].m_rx_ws_sig, false); + i2s_gpio_check_and_set(gpio_cfg->bclk, i2s_periph_signal[id].m_rx_bck_sig, false); + /* For "tx + rx + master" or "tx + master" mode, select TX signal index for ws and bck */ + } else { + i2s_gpio_check_and_set(gpio_cfg->ws, i2s_periph_signal[id].m_tx_ws_sig, false); + i2s_gpio_check_and_set(gpio_cfg->bclk, i2s_periph_signal[id].m_tx_bck_sig, false); + } + } + + return ESP_OK; +} + +esp_err_t i2s_init_std_channel(i2s_chan_handle_t handle, const i2s_std_config_t *std_cfg) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + esp_err_t ret = ESP_OK; + + xSemaphoreTake(handle->mutex, portMAX_DELAY); + ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_REGISTER, ESP_ERR_INVALID_STATE, err, TAG, "the channel has initialized already"); + ESP_GOTO_ON_ERROR(i2s_std_set_gpio(handle, &std_cfg->gpio_cfg), err, TAG, "initialize channel failed while setting gpio pins"); + /* i2s_set_slot should be called before i2s_set_clock while initializing, because clock is relay on the slot */ + ESP_GOTO_ON_ERROR(i2s_std_set_slot(handle, &std_cfg->slot_cfg), err, TAG, "initialize channel failed while setting slot"); + ESP_GOTO_ON_ERROR(i2s_std_set_clock(handle, &std_cfg->clk_cfg), err, TAG, "initialize channel failed while setting clock"); + ESP_GOTO_ON_ERROR(i2s_init_dma_intr(handle, ESP_INTR_FLAG_LEVEL1), err, TAG, "initialize dma interrupt failed"); + /* Store the configurations of standard mode */ + i2s_std_config_t *mode_info = calloc(1, sizeof(i2s_std_config_t)); + ESP_GOTO_ON_FALSE(mode_info, ESP_ERR_NO_MEM, err, TAG, "no memory for storing the configurations"); + memcpy(mode_info, std_cfg, sizeof(i2s_std_config_t)); + handle->mode_info = mode_info; + +#if SOC_I2S_HW_VERSION_2 + /* Enable clock to start outputting mclk signal. Some codecs will reset once mclk stop */ + if (handle->dir == I2S_DIR_TX) { + i2s_ll_tx_enable_std(handle->parent->hal.dev); + i2s_ll_tx_enable_clock(handle->parent->hal.dev); + } else { + i2s_ll_rx_enable_std(handle->parent->hal.dev); + i2s_ll_rx_enable_clock(handle->parent->hal.dev); + } +#endif + + /* Initialization finished, mark state as ready */ + handle->state = I2S_CHAN_STATE_READY; + xSemaphoreGive(handle->mutex); + return ret; + +err: + xSemaphoreGive(handle->mutex); + return ret; +} + +esp_err_t i2s_reconfig_std_clock(i2s_chan_handle_t handle, const i2s_std_clk_config_t *clk_cfg) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + I2S_NULL_POINTER_CHECK(TAG, clk_cfg); + + esp_err_t ret = ESP_OK; + + xSemaphoreTake(handle->mutex, portMAX_DELAY); + ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_STD, ESP_ERR_INVALID_ARG, err, TAG, "this handle is not working in standard moded"); + ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "invalid state, I2S should be stopped before reconfiguring the clock"); + + i2s_std_config_t *std_cfg = (i2s_std_config_t*)handle->mode_info; + ESP_GOTO_ON_FALSE(std_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); + + ESP_GOTO_ON_ERROR(i2s_std_set_clock(handle, &std_cfg->clk_cfg), err, TAG, "update clock failed"); + /* Update the stored clock information */ + memcpy(&std_cfg->clk_cfg, clk_cfg, sizeof(i2s_std_clk_config_t)); + + xSemaphoreGive(handle->mutex); + + return ESP_OK; +err: + xSemaphoreGive(handle->mutex); + return ret; +} + +esp_err_t i2s_reconfig_std_slot(i2s_chan_handle_t handle, const i2s_std_slot_config_t *slot_cfg) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + I2S_NULL_POINTER_CHECK(TAG, slot_cfg); + + esp_err_t ret = ESP_OK; + + xSemaphoreTake(handle->mutex, portMAX_DELAY); + ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_STD, ESP_ERR_INVALID_ARG, err, TAG, "this handle is not working in standard moded"); + ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "invalid state, I2S should be stopped before reconfiguring the slot"); + + i2s_std_config_t *std_cfg = (i2s_std_config_t*)handle->mode_info; + ESP_GOTO_ON_FALSE(std_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); + + ESP_GOTO_ON_ERROR(i2s_std_set_slot(handle, slot_cfg), err, TAG, "set i2s standard slot failed"); + /* Update the stored slot information */ + memcpy(&std_cfg->slot_cfg, slot_cfg, sizeof(i2s_std_slot_config_t)); + + /* If the slot bit width changed, then need to update the clock */ + uint32_t slot_bits = slot_cfg->slot_bit_width == I2S_SLOT_BIT_WIDTH_AUTO ? slot_cfg->data_bit_width : slot_cfg->slot_bit_width; + if (std_cfg->slot_cfg.slot_bit_width == slot_bits) { + ESP_GOTO_ON_ERROR(i2s_std_set_clock(handle, &std_cfg->clk_cfg), err, TAG, "update clock failed"); + } + + xSemaphoreGive(handle->mutex); + + return ESP_OK; +err: + xSemaphoreGive(handle->mutex); + return ret; +} + +esp_err_t i2s_reconfig_std_gpio(i2s_chan_handle_t handle, const i2s_std_gpio_config_t *gpio_cfg) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + I2S_NULL_POINTER_CHECK(TAG, gpio_cfg); + + esp_err_t ret = ESP_OK; + + xSemaphoreTake(handle->mutex, portMAX_DELAY); + ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_STD, ESP_ERR_INVALID_ARG, err, TAG, "This handle is not working in standard moded"); + ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "Invalid state, I2S should be stopped before reconfiguring the gpio"); + + i2s_std_config_t *std_cfg = (i2s_std_config_t*)handle->mode_info; + ESP_GOTO_ON_FALSE(std_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); + + ESP_GOTO_ON_ERROR(i2s_std_set_gpio(handle, gpio_cfg), err, TAG, "set i2s standard slot failed"); + + /* Update the stored slot information */ + memcpy(&std_cfg->gpio_cfg, gpio_cfg, sizeof(i2s_std_gpio_config_t)); + xSemaphoreGive(handle->mutex); + + return ESP_OK; +err: + xSemaphoreGive(handle->mutex); + return ret; +} diff --git a/components/driver/i2s/i2s_tdm.c b/components/driver/i2s/i2s_tdm.c new file mode 100644 index 0000000000..c8d7c663c5 --- /dev/null +++ b/components/driver/i2s/i2s_tdm.c @@ -0,0 +1,317 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" +#include "hal/i2s_hal.h" +#include "driver/gpio.h" +#include "driver/i2s_tdm.h" +#include "i2s_private.h" +#include "clk_ctrl_os.h" +#include "esp_intr_alloc.h" +#include "esp_check.h" + +const static char *TAG = "I2S_TDM"; + +// Same with standard mode except total slot number +static esp_err_t i2s_tdm_calculate_clock(i2s_chan_handle_t handle, const i2s_tdm_clk_config_t *clk_cfg, i2s_hal_clock_info_t *clk_info) +{ + uint32_t rate = clk_cfg->sample_rate_hz; + i2s_tdm_slot_config_t *slot_cfg = &((i2s_tdm_config_t *)(handle->mode_info))->slot_cfg; + uint32_t slot_bits = (slot_cfg->slot_bit_width == I2S_SLOT_BIT_WIDTH_AUTO) || + ((int)slot_cfg->slot_bit_width < (int)slot_cfg->data_bit_width) ? + slot_cfg->data_bit_width : slot_cfg->slot_bit_width; + /* Calculate multiple + * Fmclk = bck_div*fbck = fsclk/(mclk_div+b/a) */ + if (handle->role == I2S_ROLE_MASTER) { + clk_info->bclk = rate * handle->total_slot * slot_bits; + clk_info->mclk = rate * clk_cfg->mclk_multiple; + clk_info->bclk_div = clk_info->mclk / clk_info->bclk; + } else { + /* For slave mode, mclk >= bclk * 8, so fix bclk_div to 2 first */ + clk_info->bclk_div = 8; + clk_info->bclk = rate * handle->total_slot * slot_bits; + clk_info->mclk = clk_info->bclk * clk_info->bclk_div; + } +#if SOC_I2S_SUPPORTS_APLL + clk_info->sclk = clk_cfg->clk_src == I2S_CLK_160M_PLL ? I2S_LL_BASE_CLK : i2s_set_get_apll_freq(clk_info->mclk); +#else + clk_info->sclk = I2S_LL_BASE_CLK; +#endif + clk_info->mclk_div = clk_info->sclk / clk_info->mclk; + + /* Check if the configuration is correct */ + ESP_RETURN_ON_FALSE(clk_info->mclk_div, ESP_ERR_INVALID_ARG, TAG, "sample rate is too large"); + + return ESP_OK; +} + +static esp_err_t i2s_tdm_set_clock(i2s_chan_handle_t handle, const i2s_tdm_clk_config_t *clk_cfg) +{ + esp_err_t ret = ESP_OK; + i2s_tdm_config_t *tdm_cfg = (i2s_tdm_config_t *)(handle->mode_info); + + /* If Power Management enabled, a PM lock will be created when there is no PM lock or clock source changed */ +#ifdef CONFIG_PM_ENABLE + // Create/Re-create power management lock + if (handle->pm_lock == NULL || tdm_cfg->clk_cfg.clk_src != clk_cfg->clk_src) { + if (handle->pm_lock) { + ESP_RETURN_ON_ERROR(esp_pm_lock_delete(handle->pm_lock), TAG, "I2S delete old pm lock failed"); + } + esp_pm_lock_type_t pm_type = ESP_PM_APB_FREQ_MAX; +#if SOC_I2S_SUPPORTS_APLL + if (clk_cfg->clk_src == I2S_CLK_APLL) { + pm_type = ESP_PM_NO_LIGHT_SLEEP; + } +#endif // SOC_I2S_SUPPORTS_APLL + ESP_RETURN_ON_ERROR(esp_pm_lock_create(pm_type, 0, "i2s_driver", &handle->pm_lock), err, TAG, "I2S pm lock create failed"); + } +#endif //CONFIG_PM_ENABLE + +#if SOC_I2S_SUPPORTS_APLL + /* Enable APLL and acquire its lock when initializing or clock source changed to APLL */ + if (clk_cfg->clk_src == I2S_CLK_APLL && (handle->state == I2S_CHAN_STATE_INIT || tdm_cfg->clk_cfg.clk_src == I2S_CLK_160M_PLL)) { + periph_rtc_apll_acquire(); + handle->apll_en = true; + } + /* Disable APLL and release its lock when clock source is changed to D2CLK */ + if (clk_cfg->clk_src == I2S_CLK_160M_PLL && tdm_cfg->clk_cfg.clk_src == I2S_CLK_APLL) { + periph_rtc_apll_release(); + handle->apll_en = false; + } +#endif + + i2s_hal_clock_info_t clk_info; + /* Calculate clock parameters */ + ESP_RETURN_ON_ERROR(i2s_tdm_calculate_clock(handle, clk_cfg, &clk_info), TAG, "clock calculate failed"); + ESP_LOGD(TAG, "Clock division info: [sclk] %d Hz [mdiv] %d [mclk] %d Hz [bdiv] %d [bclk] %d Hz", + clk_info.sclk, clk_info.mclk_div, clk_info.mclk, clk_info.bclk_div, clk_info.bclk); + + portENTER_CRITICAL(&s_i2s.spinlock); + /* Set clock configurations in HAL*/ + if (handle->dir == I2S_DIR_TX) { + i2s_hal_set_tx_clock(&handle->parent->hal, &clk_info, clk_cfg->clk_src); + } else { + i2s_hal_set_rx_clock(&handle->parent->hal, &clk_info, clk_cfg->clk_src); + } + portEXIT_CRITICAL(&s_i2s.spinlock); + + return ret; +} + +static esp_err_t i2s_tdm_set_slot(i2s_chan_handle_t handle, const i2s_tdm_slot_config_t *slot_cfg) +{ + uint32_t buf_size = i2s_get_buf_size(handle, slot_cfg->data_bit_width, handle->dma.frame_num); + /* The DMA buffer need to re-allocate if the buffer size changed */ + if (handle->dma.buf_size != buf_size) { + handle->dma.buf_size = buf_size; + ESP_RETURN_ON_ERROR(i2s_free_dma_desc(handle), TAG, "failed to free the old dma descriptor"); + ESP_RETURN_ON_ERROR(i2s_alloc_dma_desc(handle, handle->dma.desc_num, buf_size), + TAG, "allocate memory for dma descriptor failed"); + } + bool is_slave = handle->role == I2S_ROLE_SLAVE; + /* Share bck and ws signal in full-duplex mode */ + if (handle->parent->full_duplex) { + i2s_ll_share_bck_ws(handle->parent->hal.dev, true); + /* Since bck and ws are shared, only tx or rx can be master + Force to set rx as slave to avoid conflict of clock signal */ + if (handle->dir == I2S_DIR_RX) { + is_slave = true; + } + } else { + i2s_ll_share_bck_ws(handle->parent->hal.dev, false); + } + + portENTER_CRITICAL(&s_i2s.spinlock); + /* Configure the hardware to apply TDM format */ + if (handle->dir == I2S_DIR_TX) { + i2s_hal_tdm_set_tx_slot(&(handle->parent->hal), is_slave, slot_cfg); + } else { + i2s_hal_tdm_set_rx_slot(&(handle->parent->hal), is_slave, slot_cfg); + } + portEXIT_CRITICAL(&s_i2s.spinlock); + + /* Update the total slot num and active slot num */ + handle->active_slot = slot_cfg->slot_mode == I2S_SLOT_MODE_MONO ? 1 : __builtin_popcount(slot_cfg->slot_mask); + uint32_t max_slot_num = 32 - __builtin_clz(slot_cfg->slot_mask); + handle->total_slot = slot_cfg->total_slot < max_slot_num ? max_slot_num : slot_cfg->total_slot; + handle->total_slot = handle->total_slot < 2 ? 2 : handle->total_slot; // At least two slots in a frame + + return ESP_OK; +} + +static esp_err_t i2s_tdm_set_gpio(i2s_chan_handle_t handle, const i2s_tdm_gpio_config_t *gpio_cfg) +{ + int id = handle->parent->id; + + /* Check validity of selected pins */ + ESP_RETURN_ON_FALSE((gpio_cfg->bclk == -1 || GPIO_IS_VALID_GPIO(gpio_cfg->bclk)), + ESP_ERR_INVALID_ARG, TAG, "bclk invalid"); + ESP_RETURN_ON_FALSE((gpio_cfg->ws == -1 || GPIO_IS_VALID_GPIO(gpio_cfg->ws)), + ESP_ERR_INVALID_ARG, TAG, "ws invalid"); + if (handle->dir == I2S_DIR_TX) { + /* Set data output GPIO */ + i2s_gpio_check_and_set(gpio_cfg->dout, i2s_periph_signal[id].data_out_sig, false); + } else { + /* Set data input GPIO */ + i2s_gpio_check_and_set(gpio_cfg->din, i2s_periph_signal[id].data_in_sig, true); + } + + if (handle->role == I2S_ROLE_SLAVE) { + /* For "tx + slave" mode, select TX signal index for ws and bck */ + if (handle->dir == I2S_DIR_TX && !handle->parent->full_duplex) { +#if SOC_I2S_HW_VERSION_2 + i2s_ll_mclk_bind_to_tx_clk(handle->parent->hal.dev); +#endif + i2s_gpio_check_and_set(gpio_cfg->ws, i2s_periph_signal[id].s_tx_ws_sig, true); + i2s_gpio_check_and_set(gpio_cfg->bclk, i2s_periph_signal[id].s_tx_bck_sig, true); + /* For "tx + rx + slave" or "rx + slave" mode, select RX signal index for ws and bck */ + } else { + i2s_gpio_check_and_set(gpio_cfg->ws, i2s_periph_signal[id].s_rx_ws_sig, true); + i2s_gpio_check_and_set(gpio_cfg->bclk, i2s_periph_signal[id].s_rx_bck_sig, true); + } + } else { + /* mclk only available in master mode */ + ESP_RETURN_ON_ERROR(i2s_check_set_mclk(id, handle->parent->mclk), TAG, "mclk config failed"); + /* For "rx + master" mode, select RX signal index for ws and bck */ + if (handle->dir == I2S_DIR_RX && !handle->parent->full_duplex) { +#if SOC_I2S_HW_VERSION_2 + i2s_ll_mclk_bind_to_rx_clk(handle->parent->hal.dev); +#endif + i2s_gpio_check_and_set(gpio_cfg->ws, i2s_periph_signal[id].m_rx_ws_sig, false); + i2s_gpio_check_and_set(gpio_cfg->bclk, i2s_periph_signal[id].m_rx_bck_sig, false); + /* For "tx + rx + master" or "tx + master" mode, select TX signal index for ws and bck */ + } else { + i2s_gpio_check_and_set(gpio_cfg->ws, i2s_periph_signal[id].m_tx_ws_sig, false); + i2s_gpio_check_and_set(gpio_cfg->bclk, i2s_periph_signal[id].m_tx_bck_sig, false); + } + } + + return ESP_OK; +} + + +esp_err_t i2s_init_tdm_channel(i2s_chan_handle_t handle, const i2s_tdm_config_t *tdm_cfg) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + esp_err_t ret = ESP_OK; + + xSemaphoreTake(handle->mutex, portMAX_DELAY); + ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_REGISTER, ESP_ERR_INVALID_STATE, err, TAG, "the channel has initialized already"); + ESP_GOTO_ON_ERROR(i2s_tdm_set_gpio(handle, &tdm_cfg->gpio_cfg), err, TAG, "initialize channel failed while setting gpio pins"); + /* i2s_set_slot should be called before i2s_set_clock while initializing, because clock is relay on the slot */ + ESP_GOTO_ON_ERROR(i2s_tdm_set_slot(handle, &tdm_cfg->slot_cfg), err, TAG, "initialize channel failed while setting slot"); + ESP_GOTO_ON_ERROR(i2s_tdm_set_clock(handle, &tdm_cfg->clk_cfg), err, TAG, "initialize channel failed while setting clock"); + ESP_GOTO_ON_ERROR(i2s_init_dma_intr(handle, ESP_INTR_FLAG_LEVEL1), err, TAG, "initialize dma interrupt failed"); + /* Store the configurations of standard mode */ + i2s_tdm_config_t *mode_info = calloc(1, sizeof(i2s_tdm_config_t)); + ESP_GOTO_ON_FALSE(mode_info, ESP_ERR_NO_MEM, err, TAG, "no memory for storing the configurations"); + memcpy(mode_info, tdm_cfg, sizeof(i2s_tdm_config_t)); + handle->mode_info = mode_info; + +#if SOC_I2S_HW_VERSION_2 + /* Enable clock to start outputting mclk signal. Some codecs will reset once mclk stop */ + if (handle->dir == I2S_DIR_TX) { + i2s_ll_tx_enable_tdm(handle->parent->hal.dev); + i2s_ll_tx_enable_clock(handle->parent->hal.dev); + } else { + i2s_ll_rx_enable_tdm(handle->parent->hal.dev); + i2s_ll_rx_enable_clock(handle->parent->hal.dev); + } +#endif + + /* Initialization finished, mark state as ready */ + handle->state = I2S_CHAN_STATE_READY; + xSemaphoreGive(handle->mutex); + return ret; + +err: + xSemaphoreGive(handle->mutex); + return ret; +} + +esp_err_t i2s_reconfig_tdm_clock(i2s_chan_handle_t handle, const i2s_tdm_clk_config_t *clk_cfg) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + I2S_NULL_POINTER_CHECK(TAG, clk_cfg); + + esp_err_t ret = ESP_OK; + + xSemaphoreTake(handle->mutex, portMAX_DELAY); + ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_TDM, ESP_ERR_INVALID_ARG, err, TAG, "this handle is not working in standard moded"); + ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "invalid state, I2S should be stopped before reconfiguring the clock"); + + i2s_tdm_config_t *tdm_cfg = (i2s_tdm_config_t*)handle->mode_info; + ESP_GOTO_ON_FALSE(tdm_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); + + ESP_GOTO_ON_ERROR(i2s_tdm_set_clock(handle, &tdm_cfg->clk_cfg), err, TAG, "update clock failed"); + /* Update the stored clock information */ + memcpy(&tdm_cfg->clk_cfg, clk_cfg, sizeof(i2s_tdm_clk_config_t)); + xSemaphoreGive(handle->mutex); + + return ESP_OK; +err: + xSemaphoreGive(handle->mutex); + return ret; +} + +esp_err_t i2s_reconfig_tdm_slot(i2s_chan_handle_t handle, const i2s_tdm_slot_config_t *slot_cfg) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + I2S_NULL_POINTER_CHECK(TAG, slot_cfg); + + esp_err_t ret = ESP_OK; + + xSemaphoreTake(handle->mutex, portMAX_DELAY); + ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_TDM, ESP_ERR_INVALID_ARG, err, TAG, "this handle is not working in standard moded"); + ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "invalid state, I2S should be stopped before reconfiguring the slot"); + + i2s_tdm_config_t *tdm_cfg = (i2s_tdm_config_t*)handle->mode_info; + ESP_GOTO_ON_FALSE(tdm_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); + + ESP_GOTO_ON_ERROR(i2s_tdm_set_slot(handle, slot_cfg), err, TAG, "set i2s standard slot failed"); + /* Update the stored slot information */ + memcpy(&tdm_cfg->slot_cfg, slot_cfg, sizeof(i2s_tdm_slot_config_t)); + + /* If the slot bit width changed, then need to update the clock */ + uint32_t slot_bits = slot_cfg->slot_bit_width == I2S_SLOT_BIT_WIDTH_AUTO ? slot_cfg->data_bit_width : slot_cfg->slot_bit_width; + if (tdm_cfg->slot_cfg.slot_bit_width == slot_bits) { + ESP_GOTO_ON_ERROR(i2s_tdm_set_clock(handle, &tdm_cfg->clk_cfg), err, TAG, "update clock failed"); + } + xSemaphoreGive(handle->mutex); + + return ESP_OK; +err: + xSemaphoreGive(handle->mutex); + return ret; +} + +esp_err_t i2s_reconfig_tdm_gpio(i2s_chan_handle_t handle, const i2s_tdm_gpio_config_t *gpio_cfg) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + I2S_NULL_POINTER_CHECK(TAG, gpio_cfg); + + esp_err_t ret = ESP_OK; + + xSemaphoreTake(handle->mutex, portMAX_DELAY); + ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_TDM, ESP_ERR_INVALID_ARG, err, TAG, "This handle is not working in standard moded"); + ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "Invalid state, I2S should be stopped before reconfiguring the gpio"); + + i2s_tdm_config_t *tdm_cfg = (i2s_tdm_config_t*)handle->mode_info; + ESP_GOTO_ON_FALSE(tdm_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); + + ESP_GOTO_ON_ERROR(i2s_tdm_set_gpio(handle, gpio_cfg), err, TAG, "set i2s standard slot failed"); + + /* Update the stored slot information */ + memcpy(&tdm_cfg->gpio_cfg, gpio_cfg, sizeof(i2s_tdm_gpio_config_t)); + xSemaphoreGive(handle->mutex); + + return ESP_OK; +err: + xSemaphoreGive(handle->mutex); + return ret; +} diff --git a/components/driver/include/driver/i2s_common.h b/components/driver/include/driver/i2s_common.h new file mode 100644 index 0000000000..fdd7fb7beb --- /dev/null +++ b/components/driver/include/driver/i2s_common.h @@ -0,0 +1,266 @@ +/* + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "freertos/FreeRTOS.h" +#include "freertos/queue.h" + +#include "hal/i2s_types.h" + +#include "esp_types.h" +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef I2S_DRIVER_SELECTED + #error "Only one set of APIs is allowed to use" +#else + #define I2S_DRIVER_SELECTED +#endif + +/** + * @brief get default I2S property + */ +#define I2S_CHANNEL_CONFIG(i2s_role, i2s_mode, pin_config) { \ + .id = I2S_NUM_AUTO, \ + .role = i2s_role, \ + .mode = i2s_mode, \ + .io = pin_config, \ +} + +#define I2S_GPIO_UNUSED GPIO_NUM_NC /*!< Used in i2s_gpio_config_t for signals which are not used */ + +/** + * @brief I2S controller channel configuration +*/ +typedef struct { + i2s_port_t id; /*!< I2S port id */ + i2s_role_t role; /*!< I2S role, I2S_ROLE_MASTER or I2S_ROLE_SLAVE */ + + /* DMA configurations */ + uint32_t dma_desc_num; /*!< I2S DMA buffer number, it is also the number of DMA descriptor */ + uint32_t dma_frame_num; /*!< I2S frame number in one DMA buffer. One frame means one-time sample data in all slots */ + bool auto_clear; /*!< Set to auto clear DMA TX descriptor, i2s will always send zero automatically if no data to send */ + +} i2s_chan_config_t; + +/** + * @brief Allocate a new i2s channel + * @note The new i2s channel handle will at REGISTERED state after it is allocated successfully. + * @note When the port id in channel configuration is I2S_NUM_AUTO, driver will allocate i2s port automatically + * Otherwise driver will try to allocate the new channel on the selected port. + * @note If both tx_handle and rx_handle are not NULL, it means this I2S port will work at duplex mode, + * and these rx and tx channel will be allocated on a same I2S port as well. + * Note that tx/rx channel will be affected by each other on ESP32 and ESP32S2, + * so please make sure them are working in same condition and have same status(start/stop). + * @note If tx_handle or rx_handle is NULL, it means this I2S port will work at simplex mode, + * For ESP32 and ESP32S2, the whole I2S port will be occupied as well even if only simplex is working. + * For the other targets, another channel on this port will still available. + * + * @param[in] chan_cfg I2S controller channel configurations + * @param[out] tx_handle I2S channel handler used for managing the sending channel(optional) + * @param[out] rx_handle I2S channel handler used for managing the receiving channel(optional) + * @return + * - ESP_OK Allocate a new channel success + * - ESP_ERR_NOT_SUPPORTED The communication mode is not supported on the current chip + * - ESP_ERR_INVALID_ARG NULL pointer or illegal parameter in i2s_chan_config_t + * - ESP_ERR_NOT_FOUND No available I2S channel found + */ +esp_err_t i2s_new_channel(const i2s_chan_config_t *chan_cfg, i2s_chan_handle_t *tx_handle, i2s_chan_handle_t *rx_handle); + +/** + * @brief Delete the i2s channel + * @note The i2s channel will be stopped to ensure the i2s channel is not at READING or WRITING state. + * @note Resource will be free automatically if all channels in one port are deleted + * + * @param[in] handle I2S channel handler + * - ESP_OK Delete successfully + * - ESP_ERR_INVALID_ARG NULL pointer + */ +esp_err_t i2s_del_channel(i2s_chan_handle_t handle); + +/** + * @brief Initialize i2s channel + * @note Only allowed to be called when the channel state is REGISTERED, (i.e., channel has been allocated, but not initialized) + * and the state will be updated to INITIALIZING while during the initialization, + * finally it will be READY if initialization is success, otherwise the state will return to REGISTERED. + * @note Will initialize i2s channel according to the i2s mode + * For different modes, we should input corresponding configurations. + * + * @param[in] handle I2S channel handler + * @param[in] clk_config Clock configuration, should input correct type of clock configuration according to i2s communication mode that set in 'i2s_chan_config_t'. + * For I2S_COMM_MODE_STD mode, please input 'i2s_std_clk_config_t' type. + * For I2S_COMM_MODE_PDM mode, please input 'i2s_pdm_tx_clk_config_t' type for tx channel and 'i2s_pdm_rx_clk_config_t' type for rx channel. + * For I2S_COMM_MODE_TDM mode, please input 'i2s_tdm_clk_config_t' type. + * @param[in] slot_config Slot configuration, should input correct type of slot configuration according to i2s communication mode that set in 'i2s_chan_config_t'. + * For I2S_COMM_MODE_STD mode, please input 'i2s_std_slot_config_t' type. + * For I2S_COMM_MODE_PDM mode, please input 'i2s_pdm_tx_slot_config_t' type for tx channel and 'i2s_pdm_rx_slot_config_t' type for rx channel. + * For I2S_COMM_MODE_TDM mode, please input 'i2s_tdm_slot_config_t' type. + * @return + * - ESP_OK Initialize successfully + * - ESP_ERR_INVALID_ARG NULL pointer + * - ESP_ERR_INVALID_STATE This channel is not registered + */ +esp_err_t i2s_init_channel(i2s_chan_handle_t handle, const void *clk_config, const void *slot_config); + +/** + * @brief Reconfigure the I2S clock + * @note Only allowed to be called when the channel state is READY, (i.e., channel has been initialized, but not started) + * this function won't change the state. + * @note Normally the clock has been configured after 'i2s_init_channel' is called + * This function is for re-configuring the clock. + * 'i2s_stop_channel' should be called before calling this function if i2s has started. + * + * @param[in] handle I2S channel handler + * @param[in] clk_config Clock configuration, should input correct type of clock configuration according to i2s communication mode + * For I2S_COMM_MODE_STD mode, please input 'i2s_std_clk_config_t' type. + * For I2S_COMM_MODE_PDM mode, please input 'i2s_pdm_tx_clk_config_t' type for tx channel and 'i2s_pdm_rx_clk_config_t' type for rx channel. + * For I2S_COMM_MODE_TDM mode, please input 'i2s_tdm_clk_config_t' type. + * @return + * - ESP_OK Set clock successfully + * - ESP_ERR_NOT_SUPPORTED The input communication mode is not supported + * - ESP_ERR_INVALID_ARG NULL pointer + * - ESP_ERR_INVALID_STATE This channel is not initialized + */ +esp_err_t i2s_set_clock(i2s_chan_handle_t handle, const void *clk_config); + +/** + * @brief Reconfigure the I2S slot + * @note Only allowed to be called when the channel state is READY, (i.e., channel has been initialized, but not started) + * this function won't change the state. + * @note Normally the slot has been configured after 'i2s_init_channel' is called + * This function is for re-configuring the slot + * 'i2s_stop_channel' should be called before calling this function if i2s has started. + * + * @param[in] handle I2S channel handler + * @param[in] slot_config Slot configuration, should input correct type of clock configuration according to i2s communication mode + * For I2S_COMM_MODE_STD mode, please input 'i2s_std_slot_config_t' type. + * For I2S_COMM_MODE_PDM mode, please input 'i2s_pdm_tx_slot_config_t' type for tx channel and 'i2s_pdm_rx_slot_config_t' type for rx channel. + * For I2S_COMM_MODE_TDM mode, please input 'i2s_tdm_slot_config_t' type. + * @return + * - ESP_OK Set slot successfully + * - ESP_ERR_INVALID_ARG NULL pointer or unmatched slot configuration type + * - ESP_ERR_INVALID_STATE This channel is not initialized + */ +esp_err_t i2s_set_slot(i2s_chan_handle_t handle, const void *slot_config); + +/** + * @brief Get I2S event queue handler + * @note Can be called at any time + * + * @param[in] handle I2S channel handler + * @param[in] que_len Queue length (if the queue has not been created yet) + * @return + * - NULL Failed to create the event queue + * - else Event queue handler + */ +QueueHandle_t i2s_get_event_queue(i2s_chan_handle_t handle, uint32_t que_len); + +/** + * @brief Start i2s channel + * @note Only allowed to be called when the channel state is READY, (i.e., channel has been initialized, but not started) + * the channel will enter IDLE state once it is started successfully. + * + * @param[in] handle I2S channel handler + * - ESP_OK Start successfully + * - ESP_ERR_INVALID_ARG NULL pointer + * - ESP_ERR_INVALID_STATE This channel has not initialized or already started + */ +esp_err_t i2s_start_channel(i2s_chan_handle_t handle); + +/** + * @brief Stop i2s channel + * @note Only allowed to be called when the channel state is READY / IDLE / WRITING / READING, (i.e., channel has been initialized) + * the channel will enter READY state once it is stopped successfully. + * @note It will stop bclk and ws signal but not mclk signal + * + * @param[in] handle I2S channel handler + * @return + * - ESP_OK Stop successfully + * - ESP_ERR_INVALID_ARG NULL pointer + * - ESP_ERR_INVALID_STATE This channel has not stated + */ +esp_err_t i2s_stop_channel(i2s_chan_handle_t handle); + +/** + * @brief I2S write data + * @note Only allowed to be called when the channel state is IDLE, (i.e., tx channel has been started and is not writing now) + * the channel will enter WRITING state once start to write, + * and it will switch back to IDLE when quit the writing, + * but the IDLE only stands for the software state, it doesn't mean there is no the signal transporting on line. + * + * @param[in] handle I2S channel handler + * @param[in] src The pointer of sent data buffer + * @param[in] size Max data buffer length + * @param[out] bytes_written Byte number that actually be sent + * @param[in] ticks_to_wait Max block time + * @return + * - ESP_OK Write successfully + * - ESP_ERR_INVALID_ARG NULL pointer or this handle is not tx handle + * - ESP_ERR_TIMEOUT Writing timeout, no writing event received from ISR within ticks_to_wait + * - ESP_ERR_INVALID_STATE I2S is not ready to write + */ +esp_err_t i2s_write_channel(i2s_chan_handle_t handle, const void *src, size_t size, size_t *bytes_written, TickType_t ticks_to_wait); + +/** + * @brief I2S read data + * @note Only allowed to be called when the channel state is IDLE + * the channel will enter READING state once start to read, + * and it will switch back to IDLE when quit the reading, + * but the IDLE only stands for the software state, it doesn't mean there is no the signal transporting on line. + * + * @param[in] handle I2S channel handler + * @param[in] dest The pointer of receiving data buffer + * @param[in] size Max data buffer length + * @param[out] bytes_read Byte number that actually be read + * @param[in] ticks_to_wait Max block time + * @return + * - ESP_OK Read successfully + * - ESP_ERR_INVALID_ARG NULL pointer or this handle is not rx handle + * - ESP_ERR_TIMEOUT Reading timeout, no reading event received from ISR within ticks_to_wait + * - ESP_ERR_INVALID_STATE I2S is not ready to read + */ +esp_err_t i2s_read_channel(i2s_chan_handle_t handle, void *dest, size_t size, size_t *bytes_read, TickType_t ticks_to_wait); + +/** + * @brief Clear the DMA buffer + * @note Only allowed to be called when the channel state is READY / IDLE / WRITING / READING, (i.e., channel has been initialized) + * it won't change the current channel state. + * @note The legacy data in DMA buffer will be cleared immediately once it is called + * That means i2s will keep send zero if no other data to send + * It has same effect with 'auto_clear' field in slot configuration struct + * but it should be called manually and won't lower the interrupt performance + * + * @param[in] handle I2S channel handler + * @return + * - ESP_OK Clear successfully + * - ESP_ERR_INVALID_STATE I2S is not initialized + */ +esp_err_t i2s_clear_dma_buffer(i2s_chan_handle_t handle); + +/** + * @brief Abort i2s reading or writing function + * @note Only allowed to be called when the channel state is IDLE / WRITING / READING, (i.e., channel has been started) + * it will change to IDLE after aborting the current reading or writing. + * @note Since reading or writing will be blocked for a long time while transporting a large quantity of data, + * This function can help to terminate reading/writing in its next reading/writing loop, + * but if reading/writing is bolcked on receiving dma queue(i.e. dma can't send or receive data), this function won't take effect + * And it will only abort for one time, so reading/writing thread won't stop though it is called + * + * @param[in] handle I2S channel handler + * @return + * - ESP_OK Abort successfully + * - ESP_ERR_INVALID_STATE I2S is stopped or not initialized + */ +esp_err_t i2s_abort_reading_writing(i2s_chan_handle_t handle); + + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/include/hal/i2s_pdm.h b/components/driver/include/driver/i2s_pdm.h similarity index 88% rename from components/hal/include/hal/i2s_pdm.h rename to components/driver/include/driver/i2s_pdm.h index 611ff9718d..732265a77c 100644 --- a/components/hal/include/hal/i2s_pdm.h +++ b/components/driver/include/driver/i2s_pdm.h @@ -14,6 +14,7 @@ #pragma once #include "hal/i2s_types.h" +#include "hal/gpio_types.h" #ifdef __cplusplus extern "C" { @@ -29,7 +30,7 @@ extern "C" { #define I2S_PDM_RX_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) { \ .mode = I2S_COMM_MODE_PDM, \ .data_bit_width = bits_per_sample, \ - .slot_bit_width = I2S_SLOT_BIT_WIDTH_DEFAULT, \ + .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \ .slot_mode = mono_or_stereo, \ } @@ -39,7 +40,7 @@ extern "C" { */ #define I2S_PDM_RX_CLK_DEFAULT_CONFIG(rate) { \ .sample_rate_hz = rate, \ - .clk_src = I2S_CLK_D2CLK, \ + .clk_src = I2S_CLK_160M_PLL, \ .mclk_multiple = I2S_MCLK_MULTIPLE_256, \ .dn_sample_mode = I2S_PDM_DSR_8S \ } @@ -69,6 +70,21 @@ typedef struct { i2s_pdm_dsr_t dn_sample_mode; /*!< Down-sampling rate mode */ } i2s_pdm_rx_clk_config_t; +/** + * @brief I2S PDM tx mode GPIO pins configuration + */ +typedef struct { + gpio_num_t clk; /*!< PDM clk pin, output */ + gpio_num_t din; /*!< DATA pin, input */ +} i2s_pdm_rx_gpio_config_t; + +typedef struct +{ + i2s_pdm_rx_clk_config_t clk_cfg; + i2s_pdm_rx_slot_config_t slot_cfg; + i2s_pdm_rx_gpio_config_t gpio_cfg; +} i2s_pdm_rx_config_t; + #endif // SOC_I2S_SUPPORTS_PDM_RX @@ -82,7 +98,7 @@ typedef struct { #define I2S_PDM_TX_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) { \ .mode = I2S_COMM_MODE_PDM, \ .data_bit_width = bits_per_sample, \ - .slot_bit_width = I2S_SLOT_BIT_WIDTH_DEFAULT, \ + .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \ .slot_mode = mono_or_stereo, \ .sd_prescale = 0, \ .sd_scale = I2S_PDM_SIG_SCALING_MUL_1, \ @@ -104,7 +120,7 @@ typedef struct { #define I2S_PDM_TX_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) { \ .mode = I2S_COMM_MODE_PDM, \ .data_bit_width = bits_per_sample, \ - .slot_bit_width = I2S_SLOT_BIT_WIDTH_DEFAULT, \ + .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \ .dma_desc_num = 8, \ .dma_frame_num = 200, \ .auto_clear = false, \ @@ -128,7 +144,7 @@ typedef struct { */ #define I2S_PDM_TX_CLK_DEFAULT_CONFIG(rate) { \ .sample_rate_hz = rate, \ - .clk_src = I2S_CLK_D2CLK, \ + .clk_src = I2S_CLK_160M_PLL, \ .mclk_multiple = I2S_MCLK_MULTIPLE_256, \ .up_sample_fp = 960, \ .up_sample_fs = ((rate) / 100), \ @@ -188,6 +204,22 @@ typedef struct { uint32_t up_sample_fs; /*!< Up-sampling param fs */ } i2s_pdm_tx_clk_config_t; +/** + * @brief I2S PDM tx mode GPIO pins configuration + */ +typedef struct { + gpio_num_t clk; /*!< PDM clk pin, output */ + gpio_num_t dout; /*!< DATA pin, output */ +} i2s_pdm_tx_gpio_config_t; + +typedef struct +{ + i2s_pdm_tx_clk_config_t clk_cfg; + i2s_pdm_tx_slot_config_t slot_cfg; + i2s_pdm_tx_gpio_config_t gpio_cfg; +} i2s_pdm_tx_config_t; + + #endif // SOC_I2S_SUPPORTS_PDM_TX #ifdef __cplusplus diff --git a/components/hal/include/hal/i2s_std.h b/components/driver/include/driver/i2s_std.h similarity index 80% rename from components/hal/include/hal/i2s_std.h rename to components/driver/include/driver/i2s_std.h index 48e1fcf367..c0db201bac 100644 --- a/components/hal/include/hal/i2s_std.h +++ b/components/driver/include/driver/i2s_std.h @@ -13,6 +13,7 @@ #pragma once #include "hal/i2s_types.h" +#include "hal/gpio_types.h" #ifdef __cplusplus extern "C" { @@ -25,9 +26,8 @@ extern "C" { * @param mono_or_stereo I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO */ #define I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) { \ - .mode = I2S_COMM_MODE_STD, \ .data_bit_width = bits_per_sample, \ - .slot_bit_width = I2S_SLOT_BIT_WIDTH_DEFAULT, \ + .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \ .slot_mode = mono_or_stereo, \ .ws_width = bits_per_sample, \ .ws_pol = false, \ @@ -44,9 +44,8 @@ extern "C" { * @param mono_or_stereo I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO */ #define I2S_STD_PCM_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) { \ - .mode = I2S_COMM_MODE_STD, \ .data_bit_width = bits_per_sample, \ - .slot_bit_width = I2S_SLOT_BIT_WIDTH_DEFAULT, \ + .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \ .slot_mode = mono_or_stereo, \ .ws_width = 1, \ .ws_pol = true, \ @@ -62,9 +61,8 @@ extern "C" { * @param mono_or_stereo I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO */ #define I2S_STD_MSB_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) { \ - .mode = I2S_COMM_MODE_STD, \ .data_bit_width = bits_per_sample, \ - .slot_bit_width = I2S_SLOT_BIT_WIDTH_DEFAULT, \ + .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \ .slot_mode = mono_or_stereo, \ .ws_width = bits_per_sample, \ .ws_pol = false, \ @@ -81,9 +79,8 @@ extern "C" { * @param mono_or_stereo I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO */ #define I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) { \ - .mode = I2S_COMM_MODE_STD, \ .data_bit_width = bits_per_sample, \ - .slot_bit_width = I2S_SLOT_BIT_WIDTH_DEFAULT, \ + .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \ .slot_mode = mono_or_stereo, \ .ws_width = bits_per_sample, \ .ws_pol = false, \ @@ -102,9 +99,8 @@ extern "C" { * @param mono_or_stereo I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO */ #define I2S_STD_PCM_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) { \ - .mode = I2S_COMM_MODE_STD, \ .data_bit_width = bits_per_sample, \ - .slot_bit_width = I2S_SLOT_BIT_WIDTH_DEFAULT, \ + .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \ .slot_mode = mono_or_stereo, \ .ws_width = 1, \ .ws_pol = true, \ @@ -122,9 +118,8 @@ extern "C" { * @param mono_or_stereo I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO */ #define I2S_STD_MSB_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) { \ - .mode = I2S_COMM_MODE_STD, \ .data_bit_width = bits_per_sample, \ - .slot_bit_width = I2S_SLOT_BIT_WIDTH_DEFAULT, \ + .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \ .slot_mode = mono_or_stereo, \ .ws_width = bits_per_sample, \ .ws_pol = false, \ @@ -145,7 +140,7 @@ extern "C" { */ #define I2S_STD_CLK_DEFAULT_CONFIG(rate) { \ .sample_rate_hz = rate, \ - .clk_src = I2S_CLK_D2CLK, \ + .clk_src = I2S_CLK_160M_PLL, \ .mclk_multiple = I2S_MCLK_MULTIPLE_256, \ } @@ -154,7 +149,6 @@ extern "C" { */ typedef struct { /* General fields */ - i2s_comm_mode_t mode; /*!< I2S communication mode, this field is for identification (MUST match the communication mode in 'i2s_chan_config_t') */ i2s_data_bit_width_t data_bit_width; /*!< I2S sample data bit width (valid data bits per sample) */ i2s_slot_bit_width_t slot_bit_width; /*!< I2S slot bit width (total bits per slot) */ i2s_slot_mode_t slot_mode; /*!< Set mono or stereo mode with I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO */ @@ -183,6 +177,31 @@ typedef struct { i2s_mclk_multiple_t mclk_multiple; /*!< The multiple of mclk to the sample rate */ } i2s_std_clk_config_t; +/** + * @brief I2S standard mode GPIO pins configuration + */ +typedef struct { + gpio_num_t mclk; /*!< MCK pin, output */ + gpio_num_t bclk; /*!< BCK pin, input in slave role, output in master role */ + gpio_num_t ws; /*!< WS pin, input in slave role, output in master role */ + gpio_num_t dout; /*!< DATA pin, output */ + gpio_num_t din; /*!< DATA pin, input */ +} i2s_std_gpio_config_t; + +typedef struct { + i2s_std_clk_config_t clk_cfg; /*!< Standard mode clock configuration */ + i2s_std_slot_config_t slot_cfg; /*!< Standard mode slot configuration */ + i2s_std_gpio_config_t gpio_cfg; /*!< Standard mode gpio configuration */ +} i2s_std_config_t; + +esp_err_t i2s_init_std_channel(i2s_chan_handle_t handle, const i2s_std_config_t *std_cfg); + +esp_err_t i2s_reconfig_std_clock(i2s_chan_handle_t handle, const i2s_std_clk_config_t *clk_cfg); + +esp_err_t i2s_reconfig_std_slot(i2s_chan_handle_t handle, const i2s_std_slot_config_t *slot_cfg); + +esp_err_t i2s_reconfig_std_gpio(i2s_chan_handle_t handle, const i2s_std_gpio_config_t *gpio_cfg); + #ifdef __cplusplus } #endif diff --git a/components/hal/include/hal/i2s_tdm.h b/components/driver/include/driver/i2s_tdm.h similarity index 81% rename from components/hal/include/hal/i2s_tdm.h rename to components/driver/include/driver/i2s_tdm.h index b5290bc020..e5e1b2ff84 100644 --- a/components/hal/include/hal/i2s_tdm.h +++ b/components/driver/include/driver/i2s_tdm.h @@ -12,6 +12,7 @@ #pragma once #include "hal/i2s_types.h" +#include "hal/gpio_types.h" #if SOC_I2S_SUPPORTS_TDM @@ -31,7 +32,7 @@ extern "C" { #define I2S_TDM_PHILIP_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo, mask) { \ .mode = I2S_COMM_MODE_TDM, \ .data_bit_width = (bits_per_sample), \ - .slot_bit_width = I2S_SLOT_BIT_WIDTH_DEFAULT, \ + .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \ .slot_mode = mono_or_stereo, \ .ws_width = I2S_TDM_AUTO_WS_WIDTH, \ .ws_pol = false, \ @@ -53,7 +54,7 @@ extern "C" { #define I2S_TDM_MSB_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo, mask) { \ .mode = I2S_COMM_MODE_TDM, \ .data_bit_width = (bits_per_sample), \ - .slot_bit_width = I2S_SLOT_BIT_WIDTH_DEFAULT, \ + .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \ .slot_mode = mono_or_stereo, \ .ws_width = I2S_TDM_AUTO_WS_WIDTH, \ .ws_pol = false, \ @@ -75,7 +76,7 @@ extern "C" { #define I2S_TDM_PCM_SHORT_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo, mask) { \ .mode = I2S_COMM_MODE_TDM, \ .data_bit_width = (bits_per_sample), \ - .slot_bit_width = I2S_SLOT_BIT_WIDTH_DEFAULT, \ + .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \ .slot_mode = mono_or_stereo, \ .ws_width = 1, \ .ws_pol = true, \ @@ -97,7 +98,7 @@ extern "C" { #define I2S_TDM_PCM_LONG_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo, mask) { \ .mode = I2S_COMM_MODE_TDM, \ .data_bit_width = (bits_per_sample), \ - .slot_bit_width = I2S_SLOT_BIT_WIDTH_DEFAULT, \ + .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \ .slot_mode = mono_or_stereo, \ .ws_width = (bits_per_sample), \ .ws_pol = true, \ @@ -118,7 +119,7 @@ extern "C" { */ #define I2S_TDM_CLK_DEFAULT_CONFIG(rate) { \ .sample_rate_hz = rate, \ - .clk_src = I2S_CLK_D2CLK, \ + .clk_src = I2S_CLK_160M_PLL, \ .mclk_multiple = I2S_MCLK_MULTIPLE_256, \ } @@ -156,6 +157,32 @@ typedef struct { i2s_mclk_multiple_t mclk_multiple; /*!< The multiple of mclk to the sample rate */ } i2s_tdm_clk_config_t; +/** + * @brief I2S TDM mode GPIO pins configuration + */ +typedef struct { + gpio_num_t mclk; /*!< MCK pin, output */ + gpio_num_t bclk; /*!< BCK pin, input in slave role, output in master role */ + gpio_num_t ws; /*!< WS pin, input in slave role, output in master role */ + gpio_num_t dout; /*!< DATA pin, output */ + gpio_num_t din; /*!< DATA pin, input */ +} i2s_tdm_gpio_config_t; + +typedef struct { + i2s_tdm_clk_config_t clk_cfg; /*!< TDM mode clock configuration */ + i2s_tdm_slot_config_t slot_cfg; /*!< TDM mode slot configuration */ + i2s_tdm_gpio_config_t gpio_cfg; /*!< TDM mode gpio configuration */ +} i2s_tdm_config_t; + +esp_err_t i2s_init_tdm_channel(i2s_chan_handle_t handle, const i2s_tdm_config_t *std_cfg); + +esp_err_t i2s_reconfig_tdm_clock(i2s_chan_handle_t handle, const i2s_tdm_clk_config_t *clk_cfg); + +esp_err_t i2s_reconfig_tdm_slot(i2s_chan_handle_t handle, const i2s_tdm_slot_config_t *slot_cfg); + +esp_err_t i2s_reconfig_tdm_gpio(i2s_chan_handle_t handle, const i2s_tdm_gpio_config_t *gpio_cfg); + + #ifdef __cplusplus } #endif diff --git a/components/driver/include/esp_private/i2s_platform.h b/components/driver/include/esp_private/i2s_platform.h index 6b5d294e76..7b7a07514e 100644 --- a/components/driver/include/esp_private/i2s_platform.h +++ b/components/driver/include/esp_private/i2s_platform.h @@ -10,38 +10,39 @@ #pragma once #include "esp_err.h" +#include "soc/soc_caps.h" #ifdef __cplusplus extern "C" { #endif /** - * @brief Register an I2S or I2S variant driver object to platform + * @brief Hold the I2S port occupation * * @note This private API is used to avoid applications from using the same I2S instance for different purpose. * @note This function will help enable the peripheral APB clock as well. * - * @param driver_obj Driver object - * @param port_id I2S port number + * @param id I2S port number + * @param comp_name The name of compnant that occupied this i2s controller * @return * - ESP_OK: The specific I2S port is free and register the new device object successfully * - ESP_ERR_INVALID_ARG: Invalid argument, e.g. wrong port_id - * - ESP_ERR_NOT_FOUND: Specific I2S port is not available + * - ESP_ERR_NOT_FOUND Specific I2S port is not available */ -esp_err_t i2s_priv_register_object(void *driver_obj, int port_id); +esp_err_t i2s_platform_acquire_occupation(int id, const char *comp_name); /** - * @brief Deregister I2S or I2S variant driver object from platform + * @brief Release the I2S port occupation * * @note This function will help disable the peripheral APB clock as well. * - * @param port_id I2S port number + * @param id I2S port number * @return * - ESP_OK: Deregister I2S port successfully (i.e. that I2S port can used used by other users after this function returns) * - ESP_ERR_INVALID_ARG: Invalid argument, e.g. wrong port_id * - ESP_ERR_INVALID_STATE: Specific I2S port is free already */ -esp_err_t i2s_priv_deregister_object(int port_id); +esp_err_t i2s_platform_release_occupation(int id); #ifdef __cplusplus } diff --git a/components/driver/test/adc_dma_test/test_esp32.c b/components/driver/test/adc_dma_test/test_esp32.c deleted file mode 100644 index 454dc16ce6..0000000000 --- a/components/driver/test/adc_dma_test/test_esp32.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/* - Tests for the adc device driver on ESP32 only -*/ -#include "sdkconfig.h" -#if CONFIG_IDF_TARGET_ESP32 - -#include "esp_system.h" -#include "driver/adc.h" -#include "driver/rtc_io.h" -#include "driver/gpio.h" -#include "unity.h" -#include "esp_system.h" -#include "esp_event.h" -#include "esp_wifi.h" -#include "esp_log.h" -#include "nvs_flash.h" -#include "test_utils.h" -#include "esp_rom_sys.h" -#include "driver/dac.h" - -/* - * ADC DMA testcase - */ -#include "driver/i2s.h" -#include "test/test_common_adc.h" - -//i2s number -#define EXAMPLE_I2S_NUM (0) -//i2s sample rate -#define EXAMPLE_I2S_SAMPLE_RATE (150000) -//i2s data bits -#define EXAMPLE_I2S_SAMPLE_BITS (16) -//enable display buffer for debug -#define EXAMPLE_I2S_BUF_DEBUG (0) -//I2S read buffer length -#define EXAMPLE_I2S_READ_LEN (16 * 1024) -//I2S data format, ADC-I2S only support mono. -#define EXAMPLE_I2S_FORMAT I2S_CHANNEL_FMT_ONLY_RIGHT -//I2S built-in ADC unit -#define I2S_ADC_UNIT ADC_UNIT_1 -//I2S built-in ADC channel -#define I2S_ADC_CHANNEL ADC1_CHANNEL_4 - -/** - * @brief I2S ADC/DAC mode init. - */ -static void example_i2s_init(void) -{ - int i2s_num = EXAMPLE_I2S_NUM; - i2s_config_t i2s_config = { - .mode = I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_ADC_BUILT_IN, - .sample_rate = EXAMPLE_I2S_SAMPLE_RATE, - .bits_per_sample = EXAMPLE_I2S_SAMPLE_BITS, - .channel_format = EXAMPLE_I2S_FORMAT, - .intr_alloc_flags = 0, - .dma_desc_num = 2, - .dma_frame_num = 1024, - .use_apll = 0, - }; - - //install and start i2s driver - TEST_ESP_OK( i2s_driver_install(i2s_num, &i2s_config, 0, NULL) ); - //init ADC pad - TEST_ESP_OK( i2s_set_adc_mode(I2S_ADC_UNIT, I2S_ADC_CHANNEL) ); -} - -static void example_i2s_deinit(void) -{ - TEST_ESP_OK( i2s_driver_uninstall(EXAMPLE_I2S_NUM) ); -} - -/** - * @brief debug buffer data - */ -static void example_disp_buf(uint8_t *buf, int length) -{ - printf("\n======"); - for (int i = 0; i < length; i += 2) { - uint16_t data = ((uint16_t)buf[i+1] << 8) | (uint16_t)buf[i]; - adc_digi_output_data_t *p = (adc_digi_output_data_t *)&data; - if ((i) % 16 == 0) printf("\n"); - printf("[%d_%d] ", p->type1.channel, p->type1.data); - } - printf("\n======\n"); -} - -static esp_err_t adc_dma_data_check(uint8_t *buf, int length, int ideal_level) -{ - for (int i = 0; i < length; i += 2) { - uint16_t data = ((uint16_t)buf[i+1] << 8) | (uint16_t)buf[i]; - adc_digi_output_data_t *p = (adc_digi_output_data_t *)&data; - if (p->type1.channel != I2S_ADC_CHANNEL) { - TEST_FAIL_MESSAGE("I2S-DMA data channel error!"); - } - if (ideal_level == 1) { // high level 3.3v - TEST_ASSERT_EQUAL( 0xFFF, p->type1.data ); - } else if (ideal_level == 0) { // low level 0v - TEST_ASSERT_LESS_THAN( 10, p->type1.data ); - } else if (ideal_level == 2) { // middle level 1.4v - TEST_ASSERT_INT_WITHIN( 128, 1586, p->type1.data ); - } else if (ideal_level == 3) { // normal level - } else { // no check - } - } - return ESP_OK; -} - -static void adc_dma_read(uint8_t *buf, int length) -{ - size_t bytes_read = 0; - int flash_wr_size = 0; - - vTaskDelay(pdTICKS_TO_MS(100)); - while (flash_wr_size < length) { - //read data from I2S bus, in this case, from ADC. - TEST_ESP_OK( i2s_read(EXAMPLE_I2S_NUM, (void *) buf + flash_wr_size, length - flash_wr_size, &bytes_read, portMAX_DELAY) ); - flash_wr_size += bytes_read; - example_disp_buf((uint8_t *) buf, 128); - } -} - -TEST_CASE("ADC DMA read", "[adc dma]") -{ - int i2s_read_len = EXAMPLE_I2S_READ_LEN; - char *i2s_read_buff = (char *) calloc(i2s_read_len, sizeof(char)); - - example_i2s_init(); - TEST_ESP_OK( i2s_adc_enable(EXAMPLE_I2S_NUM) ); - - adc_fake_tie_low(I2S_ADC_UNIT, I2S_ADC_CHANNEL); - adc_dma_read((uint8_t *)i2s_read_buff, i2s_read_len); - adc_dma_data_check((uint8_t *)i2s_read_buff, i2s_read_len, 0); - - adc_fake_tie_middle(I2S_ADC_UNIT, I2S_ADC_CHANNEL); - adc_dma_read((uint8_t *)i2s_read_buff, i2s_read_len); - adc_dma_data_check((uint8_t *)i2s_read_buff, i2s_read_len, 2); - - adc_fake_tie_high(I2S_ADC_UNIT, I2S_ADC_CHANNEL); - adc_dma_read((uint8_t *)i2s_read_buff, i2s_read_len); - adc_dma_data_check((uint8_t *)i2s_read_buff, i2s_read_len, 1); - - adc_io_normal(I2S_ADC_UNIT, I2S_ADC_CHANNEL); - - TEST_ESP_OK( i2s_adc_disable(EXAMPLE_I2S_NUM) ); - if (i2s_read_buff) { - free(i2s_read_buff); - i2s_read_buff = NULL; - } - - example_i2s_deinit(); -} - -#endif // CONFIG_IDF_TARGET_ESP32 diff --git a/components/driver/test/dac_dma_test/test_esp32.c b/components/driver/test/dac_dma_test/test_esp32.c deleted file mode 100644 index c68b5654a6..0000000000 --- a/components/driver/test/dac_dma_test/test_esp32.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/* - Tests for the dac device driver on ESP32 only - Hardware connection: - - ESP32: GPIO25 <---> GPIO26 -*/ -#include "sdkconfig.h" -#if CONFIG_IDF_TARGET_ESP32 - -#include "esp_system.h" -#include "driver/adc.h" -#include "unity.h" -#include "esp_system.h" -#include "esp_event.h" -#include "esp_wifi.h" -#include "esp_log.h" -#include "nvs_flash.h" -#include "test_utils.h" -#include "test_dac_audio_file.h" -#include "driver/i2s.h" -#include "driver/dac.h" - -/* - * DAC DMA config. - */ - -//enable record sound and save in flash -#define RECORD_IN_FLASH_EN (1) -//enable replay recorded sound in flash -#define REPLAY_FROM_FLASH_EN (1) - -//i2s number -#define EXAMPLE_I2S_NUM (0) -//i2s sample rate -#define EXAMPLE_I2S_SAMPLE_RATE (16000) -//i2s data bits -#define EXAMPLE_I2S_SAMPLE_BITS (16) -//enable display buffer for debug -#define EXAMPLE_I2S_BUF_DEBUG (0) -//I2S read buffer length -#define EXAMPLE_I2S_READ_LEN (16 * 1024) -//I2S data format -#define EXAMPLE_I2S_FORMAT (I2S_CHANNEL_FMT_RIGHT_LEFT) -//I2S channel number -#define EXAMPLE_I2S_CHANNEL_NUM ((EXAMPLE_I2S_FORMAT < I2S_CHANNEL_FMT_ONLY_RIGHT) ? (2) : (1)) - -/** - * @brief I2S ADC/DAC mode init. - */ -static void example_i2s_init(void) -{ - int i2s_num = EXAMPLE_I2S_NUM; - i2s_config_t i2s_config = { - .mode = I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN, - .sample_rate = EXAMPLE_I2S_SAMPLE_RATE, - .bits_per_sample = EXAMPLE_I2S_SAMPLE_BITS, - .channel_format = EXAMPLE_I2S_FORMAT, - .intr_alloc_flags = 0, - .dma_desc_num = 2, - .dma_frame_num = 1024, - .use_apll = 0, - }; - //install and start i2s driver - TEST_ESP_OK( i2s_driver_install(i2s_num, &i2s_config, 0, NULL) ); - //init DAC pad - TEST_ESP_OK( i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN) ); -} - -static void example_i2s_deinit(void) -{ - TEST_ESP_OK( i2s_set_dac_mode(I2S_DAC_CHANNEL_DISABLE) ); - TEST_ESP_OK( i2s_driver_uninstall(EXAMPLE_I2S_NUM) ); -} - -/** - * @brief Set i2s clock for example audio file - */ -static void example_set_file_play_mode(void) -{ - TEST_ESP_OK( i2s_set_clk(EXAMPLE_I2S_NUM, 16000, EXAMPLE_I2S_SAMPLE_BITS, 1) ); -} - -/** - * @brief Scale data to 16bit/32bit for I2S DMA output. - * DAC can only output 8bit data value. - * I2S DMA will still send 16 bit or 32bit data, the highest 8bit contains DAC data. - */ -static int example_i2s_dac_data_scale(uint8_t *d_buff, uint8_t *s_buff, uint32_t len) -{ - uint32_t j = 0; -#if (EXAMPLE_I2S_SAMPLE_BITS == 16) - for (int i = 0; i < len; i++) { - d_buff[j++] = 0; - d_buff[j++] = s_buff[i]; - } - return (len * 2); -#else - for (int i = 0; i < len; i++) { - d_buff[j++] = 0; - d_buff[j++] = 0; - d_buff[j++] = 0; - d_buff[j++] = s_buff[i]; - } - return (len * 4); -#endif -} -/** - * @brief debug buffer data - */ -static void example_disp_buf(uint8_t *buf, int length) -{ - printf("======\n"); - for (int i = 0; i < length; i++) { - printf("%02x ", buf[i]); - if ((i + 1) % 8 == 0) { - printf("\n"); - } - } - printf("======\n"); -} - -/** - * @brief Reset i2s clock and mode - */ -static void example_reset_play_mode(void) -{ - TEST_ESP_OK( i2s_set_clk(EXAMPLE_I2S_NUM, EXAMPLE_I2S_SAMPLE_RATE, EXAMPLE_I2S_SAMPLE_BITS, EXAMPLE_I2S_CHANNEL_NUM) ); -} - -TEST_CASE("DAC DMA output", "[dac]") -{ - size_t bytes_written; - int i2s_read_len = EXAMPLE_I2S_READ_LEN; - uint8_t *i2s_write_buff = (uint8_t *) calloc(i2s_read_len, sizeof(char)); - int offset = 0; - int tot_size = sizeof(audio_table); - printf("Playing file example: \n"); - - example_i2s_init(); - example_set_file_play_mode(); - - while (offset < tot_size) { - int play_len = ((tot_size - offset) > (4 * 1024)) ? (4 * 1024) : (tot_size - offset); - int i2s_wr_len = example_i2s_dac_data_scale(i2s_write_buff, (uint8_t *)(audio_table + offset), play_len); - i2s_write(EXAMPLE_I2S_NUM, i2s_write_buff, i2s_wr_len, &bytes_written, portMAX_DELAY); - offset += play_len; - example_disp_buf((uint8_t *) i2s_write_buff, 32); - } - - example_reset_play_mode(); - free(i2s_write_buff); - - example_i2s_deinit(); -} - -#endif // CONFIG_IDF_TARGET_ESP32 diff --git a/components/driver/test/test_adc2_with_wifi.c b/components/driver/test/test_adc2_with_wifi.c index e5c494df20..3d944d3c00 100644 --- a/components/driver/test/test_adc2_with_wifi.c +++ b/components/driver/test/test_adc2_with_wifi.c @@ -219,35 +219,44 @@ TEST_CASE("adc2 work with wifi","[adc]") #ifdef CONFIG_IDF_TARGET_ESP32 -#include "driver/i2s.h" +#include "driver/adc.h" #define ADC1_CHANNEL_4_IO (32) -#define SAMPLE_RATE (36000) -#define SAMPLE_BITS (16) +#define ADC_SAMPLE_RATE (36000) +#define ADC_TEST_CHANNEL ADC1_CHANNEL_4 -static void i2s_adc_init(void) +static void adc_dma_init(void) { - i2s_config_t i2s_config = { - .mode = I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_ADC_BUILT_IN, - .sample_rate = SAMPLE_RATE, - .bits_per_sample = SAMPLE_BITS, - .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, - .intr_alloc_flags = 0, - .dma_desc_num = 2, - .dma_frame_num = 1024, - .use_apll = 0, + adc_digi_init_config_t adc_dma_config = { + .max_store_buf_size = 1024, + .conv_num_each_intr = 256, + .adc1_chan_mask = 1 << ADC_TEST_CHANNEL, + .adc2_chan_mask = 0, }; - // install and start I2S driver - i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL); - // init ADC pad - i2s_set_adc_mode(ADC_UNIT_1, ADC1_CHANNEL_4); - // enable adc sampling, ADC_WIDTH_BIT_12, ADC_ATTEN_DB_11 hard-coded in adc_i2s_mode_init - i2s_adc_enable(I2S_NUM_0); + TEST_ESP_OK(adc_digi_initialize(&adc_dma_config)); + + adc_digi_pattern_config_t adc_pattern = { + .atten = ADC_ATTEN_DB_0, + .channel = ADC_TEST_CHANNEL, + .unit = 0, + .bit_width = SOC_ADC_DIGI_MAX_BITWIDTH + }; + adc_digi_configuration_t dig_cfg = { + .conv_limit_en = 1, + .conv_limit_num = 250, + .sample_freq_hz = ADC_SAMPLE_RATE, + .conv_mode = ADC_CONV_SINGLE_UNIT_1, + .format = ADC_DIGI_OUTPUT_FORMAT_TYPE1, + .pattern_num = 1, + .adc_pattern = &adc_pattern + }; + TEST_ESP_OK(adc_digi_controller_configure(&dig_cfg)); + TEST_ESP_OK(adc_digi_start()); } -static void i2s_adc_test(void) +static void continuous_adc_test(void) { - uint16_t *i2sReadBuffer = (uint16_t *)calloc(1024, sizeof(uint16_t)); + uint16_t *adcReadBuffer = (uint16_t *)calloc(1024, sizeof(uint16_t)); size_t bytesRead; for (int loop = 0; loop < 10; loop++) { for (int level = 0; level <= 1; level++) { @@ -258,12 +267,11 @@ static void i2s_adc_test(void) } vTaskDelay(200 / portTICK_PERIOD_MS); // read data from adc, will block until buffer is full - i2s_read(I2S_NUM_0, (void *)i2sReadBuffer, 1024 * sizeof(uint16_t), &bytesRead, portMAX_DELAY); - + adc_digi_read_bytes((uint8_t *)adcReadBuffer, 1024 * sizeof(uint16_t), &bytesRead, ADC_MAX_DELAY); // calc average int64_t adcSumValue = 0; for (size_t i = 0; i < 1024; i++) { - adcSumValue += i2sReadBuffer[i] & 0xfff; + adcSumValue += adcReadBuffer[i] & 0xfff; } int adcAvgValue = adcSumValue / 1024; printf("adc average val: %d\n", adcAvgValue); @@ -275,19 +283,19 @@ static void i2s_adc_test(void) } } } - free(i2sReadBuffer); + free(adcReadBuffer); } -static void i2s_adc_release(void) +static void adc_deinit(void) { - i2s_adc_disable(I2S_NUM_0); - i2s_driver_uninstall(I2S_NUM_0); + adc_digi_stop(); + TEST_ESP_OK(adc_digi_deinitialize()); } TEST_CASE("adc1 and i2s work with wifi","[adc][ignore]") { - i2s_adc_init(); + adc_dma_init(); //init wifi printf("nvs init\n"); esp_err_t r = nvs_flash_init(); @@ -310,12 +318,12 @@ TEST_CASE("adc1 and i2s work with wifi","[adc][ignore]") }; TEST_ESP_OK(esp_wifi_set_mode(WIFI_MODE_STA)); TEST_ESP_OK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config)); - i2s_adc_test(); + continuous_adc_test(); //now start wifi printf("wifi start...\n"); TEST_ESP_OK(esp_wifi_start()); //test reading during wifi on - i2s_adc_test(); + continuous_adc_test(); //wifi stop again printf("wifi stop...\n"); @@ -326,8 +334,8 @@ TEST_CASE("adc1 and i2s work with wifi","[adc][ignore]") event_deinit(); nvs_flash_deinit(); - i2s_adc_test(); - i2s_adc_release(); + continuous_adc_test(); + adc_deinit(); printf("test passed...\n"); TEST_IGNORE_MESSAGE("this test case is ignored due to the critical memory leak of esp_netif and event_loop."); } diff --git a/components/driver/test/test_dac.c b/components/driver/test/test_dac.c index 2eace253e8..0537f23148 100644 --- a/components/driver/test/test_dac.c +++ b/components/driver/test/test_dac.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -19,7 +19,6 @@ #include "soc/soc_caps.h" #if SOC_DAC_SUPPORTED -#include "driver/i2s.h" #include "driver/dac.h" #include "esp_adc_cal.h" diff --git a/components/driver/test_apps/i2s/CMakeLists.txt b/components/driver/test_apps/i2s/CMakeLists.txt new file mode 100644 index 0000000000..3d2e9717ee --- /dev/null +++ b/components/driver/test_apps/i2s/CMakeLists.txt @@ -0,0 +1,5 @@ +# This is the project CMakeLists.txt file for the test subproject +cmake_minimum_required(VERSION 3.5) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(i2s_test) diff --git a/components/driver/test_apps/i2s/app_test.py b/components/driver/test_apps/i2s/app_test.py new file mode 100644 index 0000000000..1583ff5709 --- /dev/null +++ b/components/driver/test_apps/i2s/app_test.py @@ -0,0 +1,30 @@ +# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Apache-2.0 +import glob +import os + +import ttfw_idf +from tiny_test_fw import Utility + + +@ttfw_idf.idf_component_unit_test(env_tag='COMPONENT_UT_GENERIC', target=['esp32', 'esp32s2', 'esp32s3', 'esp32c3']) +def test_component_ut_i2s(env, _): # type: (ttfw_idf.TinyFW.Env, None) -> None + # Get the names of all configs (sdkconfig.ci.* files) + config_files = glob.glob(os.path.join(os.path.dirname(__file__), 'sdkconfig.ci.*')) + config_names = [os.path.basename(s).replace('sdkconfig.ci.', '') for s in config_files] + + # Run test once with binaries built for each config + for name in config_names: + Utility.console_log(f'Checking config "{name}"... ', end='') + dut = env.get_dut('i2s', 'components/driver/test_apps/i2s', app_config_name=name) + dut.start_app() + stdout = dut.expect('Press ENTER to see the list of tests', full_stdout=True) + dut.write('*') + stdout = dut.expect("Enter next test, or 'enter' to see menu", full_stdout=True, timeout=30) + ttfw_idf.ComponentUTResult.parse_result(stdout,ttfw_idf.TestFormat.UNITY_BASIC) + env.close_dut(dut.name) + Utility.console_log(f'Test config "{name}" done') + + +if __name__ == '__main__': + test_component_ut_i2s() diff --git a/components/driver/test_apps/i2s/main/CMakeLists.txt b/components/driver/test_apps/i2s/main/CMakeLists.txt new file mode 100644 index 0000000000..1eb45d8776 --- /dev/null +++ b/components/driver/test_apps/i2s/main/CMakeLists.txt @@ -0,0 +1,16 @@ +set(srcs "test_app_main.c") + +if(CONFIG_SOC_I2S_SUPPORTED) + list(APPEND srcs "test_i2s_controller.c" + "test_i2s_legacy.c") +endif() + + +idf_component_register(SRCS ${srcs} + PRIV_REQUIRES driver hal soc unity) + +if(CONFIG_SOC_I2S_SUPPORTED) + target_link_libraries(${COMPONENT_LIB} INTERFACE + "-u test_app_include_i2s_controller" + "-u test_app_include_i2s_legacy") +endif() diff --git a/components/driver/test_apps/i2s/main/test_app_main.c b/components/driver/test_apps/i2s/main/test_app_main.c new file mode 100644 index 0000000000..b49226f575 --- /dev/null +++ b/components/driver/test_apps/i2s/main/test_app_main.c @@ -0,0 +1,53 @@ +/* + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "unity.h" +#include "unity_test_runner.h" +#include "esp_heap_caps.h" + +// Some resources are lazy allocated in I2S driver, the threadhold is left for that case +#define TEST_MEMORY_LEAK_THRESHOLD (-300) + +static size_t before_free_8bit; +static size_t before_free_32bit; + +static void check_leak(size_t before_free, size_t after_free, const char *type) +{ + ssize_t delta = after_free - before_free; + printf("MALLOC_CAP_%s: Before %u bytes free, After %u bytes free (delta %d)\n", type, before_free, after_free, delta); + TEST_ASSERT_MESSAGE(delta >= TEST_MEMORY_LEAK_THRESHOLD, "memory leak"); +} + +void setUp(void) +{ + before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); + before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); +} + +void tearDown(void) +{ + size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); + size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); + check_leak(before_free_8bit, after_free_8bit, "8BIT"); + check_leak(before_free_32bit, after_free_32bit, "32BIT"); +} + +void app_main(void) +{ + // ___ ____ ____ _____ _ + // |_ _|___ \/ ___| |_ _|__ ___| |_ + // | | __) \___ \ | |/ _ \/ __| __| + // | | / __/ ___) | | | __/\__ \ |_ + // |___|_____|____/ |_|\___||___/\__| + + printf(" ___ ____ ____ _____ _ \r\n"); + printf(" |_ _|___ \\/ ___| |_ _|__ ___| |_ \r\n"); + printf(" | | __) \\___ \\ | |/ _ \\/ __| __|\r\n"); + printf(" | | / __/ ___) | | | __/\\__ \\ |_ \r\n"); + printf(" |___|_____|____/ |_|\\___||___/\\__|\r\n"); + + unity_run_menu(); +} diff --git a/components/driver/test_apps/i2s/main/test_i2s_controller.c b/components/driver/test_apps/i2s/main/test_i2s_controller.c new file mode 100644 index 0000000000..0c1cf8d00f --- /dev/null +++ b/components/driver/test_apps/i2s/main/test_i2s_controller.c @@ -0,0 +1,512 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * I2S test environment UT_T1_I2S: + * We use internal signals instead of external wiring, but please keep the following IO connections, or connect nothing to prevent the signal from being disturbed. + * connect GPIO15 and GPIO19, GPIO25(ESP32)/GPIO17(ESP32-S2) and GPIO26, GPIO21 and GPIO22(ESP32)/GPIO20(ESP32-S2) + * Please do not connect GPIO32(ESP32) any pull-up resistors externally, it will be used to test i2s adc function. + */ + + +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "freertos/semphr.h" +#include "driver/gpio.h" +#include "hal/gpio_hal.h" +#include "esp_err.h" +#include "unity.h" +#include "math.h" +#include "esp_rom_gpio.h" +#include "soc/i2s_periph.h" +#include "driver/i2s_controller.h" +#include "hal/i2s_hal.h" +#include "esp_private/i2s_platform.h" +#if SOC_PCNT_SUPPORTED +#include "driver/pcnt.h" +#include "soc/pcnt_periph.h" +#endif + +#define SAMPLE_RATE (48000) +#define SAMPLE_BITS (16) + +#if CONFIG_IDF_TARGET_ESP32 +#define MASTER_MCK_IO 0 +#define MASTER_BCK_IO 15 +#define MASTER_WS_IO 25 +#define SLAVE_BCK_IO 19 +#define SLAVE_WS_IO 26 +#define DATA_IN_IO 21 +#define DATA_OUT_IO 22 +#define ADC1_CHANNEL_4_IO 32 +#elif CONFIG_IDF_TARGET_ESP32S2 +#define MASTER_MCK_IO 0 +#define MASTER_BCK_IO 4 +#define MASTER_WS_IO 5 +#define SLAVE_BCK_IO 14 +#define SLAVE_WS_IO 15 +#define DATA_IN_IO 19 +#define DATA_OUT_IO 18 +#elif CONFIG_IDF_TARGET_ESP32C3 +#define MASTER_MCK_IO 0 +#define MASTER_BCK_IO 4 +#define MASTER_WS_IO 5 +#define SLAVE_BCK_IO 14 +#define SLAVE_WS_IO 15 +#define DATA_IN_IO 19 +#define DATA_OUT_IO 18 +#elif CONFIG_IDF_TARGET_ESP32S3 +#define MASTER_MCK_IO 0 +#define MASTER_BCK_IO 4 +#define MASTER_WS_IO 5 +#define SLAVE_BCK_IO 14 +#define SLAVE_WS_IO 15 +#define DATA_IN_IO 19 +#define DATA_OUT_IO 18 +#endif + +#define I2S_TEST_MODE_SLAVE_TO_MASTER 0 +#define I2S_TEST_MODE_MASTER_TO_SLAVE 1 +#define I2S_TEST_MODE_LOOPBACK 2 + +#define I2S_TEST_MASTER_DEFAULT_PIN { \ + .mclk = MASTER_MCK_IO, \ + .bclk = MASTER_BCK_IO, \ + .ws = MASTER_WS_IO, \ + .dout = DATA_OUT_IO, \ + .din = DATA_IN_IO \ + }; + +#define I2S_TEST_SLAVE_DEFAULT_PIN { \ + .mclk = -1, \ + .bclk = SLAVE_BCK_IO, \ + .ws = SLAVE_WS_IO, \ + .dout = DATA_OUT_IO, \ + .din = DATA_IN_IO \ + }; + +// This empty function is used to force the compiler link this file +void test_app_include_i2s_controller(void) +{ +} + +// mode: 0, master rx, slave tx. mode: 1, master tx, slave rx. mode: 2, master tx rx loop-back +// Since ESP32-S2 has only one I2S, only loop back test can be tested. +static void i2s_test_io_config(int mode) +{ + // Connect internal signals using IO matrix. + gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[MASTER_BCK_IO], PIN_FUNC_GPIO); + gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[MASTER_WS_IO], PIN_FUNC_GPIO); + gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[DATA_OUT_IO], PIN_FUNC_GPIO); + + gpio_set_direction(MASTER_BCK_IO, GPIO_MODE_INPUT_OUTPUT); + gpio_set_direction(MASTER_WS_IO, GPIO_MODE_INPUT_OUTPUT); + gpio_set_direction(DATA_OUT_IO, GPIO_MODE_INPUT_OUTPUT); + + switch (mode) { +#if SOC_I2S_NUM > 1 + case I2S_TEST_MODE_SLAVE_TO_MASTER: { + esp_rom_gpio_connect_out_signal(MASTER_BCK_IO, i2s_periph_signal[0].m_rx_bck_sig, 0, 0); + esp_rom_gpio_connect_in_signal(MASTER_BCK_IO, i2s_periph_signal[1].s_tx_bck_sig, 0); + + esp_rom_gpio_connect_out_signal(MASTER_WS_IO, i2s_periph_signal[0].m_rx_ws_sig, 0, 0); + esp_rom_gpio_connect_in_signal(MASTER_WS_IO, i2s_periph_signal[1].s_tx_ws_sig, 0); + + esp_rom_gpio_connect_out_signal(DATA_OUT_IO, i2s_periph_signal[1].data_out_sig, 0, 0); + esp_rom_gpio_connect_in_signal(DATA_OUT_IO, i2s_periph_signal[0].data_in_sig, 0); + } + break; + + case I2S_TEST_MODE_MASTER_TO_SLAVE: { + esp_rom_gpio_connect_out_signal(MASTER_BCK_IO, i2s_periph_signal[0].m_tx_bck_sig, 0, 0); + esp_rom_gpio_connect_in_signal(MASTER_BCK_IO, i2s_periph_signal[1].s_rx_bck_sig, 0); + + esp_rom_gpio_connect_out_signal(MASTER_WS_IO, i2s_periph_signal[0].m_tx_ws_sig, 0, 0); + esp_rom_gpio_connect_in_signal(MASTER_WS_IO, i2s_periph_signal[1].s_rx_ws_sig, 0); + + esp_rom_gpio_connect_out_signal(DATA_OUT_IO, i2s_periph_signal[0].data_out_sig, 0, 0); + esp_rom_gpio_connect_in_signal(DATA_OUT_IO, i2s_periph_signal[1].data_in_sig, 0); + } + break; +#endif + case I2S_TEST_MODE_LOOPBACK: { + esp_rom_gpio_connect_out_signal(DATA_OUT_IO, i2s_periph_signal[0].data_out_sig, 0, 0); + esp_rom_gpio_connect_in_signal(DATA_OUT_IO, i2s_periph_signal[0].data_in_sig, 0); + } + break; + + default: { + TEST_FAIL_MESSAGE("error: mode not supported"); + } + break; + } +} + +static void i2s_read_write_test(i2s_chan_handle_t tx_chan, i2s_chan_handle_t rx_chan) +{ +#define I2S_SEND_BUF_LEN 100 +#define I2S_RECV_BUF_LEN 10000 + + size_t bytes_write = 0; + size_t bytes_read = 0; + + bool is_success = false; + + uint8_t *send_buf = (uint8_t *)calloc(I2S_SEND_BUF_LEN, sizeof(uint8_t)); + TEST_ASSERT_NOT_NULL(send_buf); + uint8_t *recv_buf = (uint8_t *)calloc(I2S_RECV_BUF_LEN, sizeof(uint8_t)); + TEST_ASSERT_NOT_NULL(recv_buf); + + for (int i = 0; i < I2S_SEND_BUF_LEN; i++) { + send_buf[i] = i + 1; + } + + // write data to slave + TEST_ESP_OK(i2s_write_channel(tx_chan, send_buf, I2S_SEND_BUF_LEN, &bytes_write, 1000 / portTICK_PERIOD_MS)); + TEST_ESP_OK(i2s_read_channel(rx_chan, recv_buf, I2S_RECV_BUF_LEN, &bytes_read, 1000 / portTICK_PERIOD_MS)); + TEST_ASSERT_EQUAL_INT32(I2S_SEND_BUF_LEN, bytes_write); + TEST_ASSERT_EQUAL_INT32(I2S_RECV_BUF_LEN, bytes_read); + // test the read data right or not + for (int i = 0, j = 0; i < (I2S_RECV_BUF_LEN - I2S_SEND_BUF_LEN); i++) { + if (recv_buf[i] == 1) { + for (j = 1; (j < I2S_SEND_BUF_LEN) && (recv_buf[i+j] == j + 1); j++) {} + if (j == I2S_SEND_BUF_LEN) { + is_success = true; + goto finish; + } + i += j; + } + } +finish: + free(send_buf); + free(recv_buf); + TEST_ASSERT(is_success); +} + +// To check if the software logic of I2S driver is correct +TEST_CASE("I2S basic driver apply, delete test", "[i2s]") +{ + i2s_gpio_config_t i2s_pin = I2S_TEST_MASTER_DEFAULT_PIN; + + i2s_chan_handle_t tx_handle; + i2s_chan_handle_t rx_handle; + + i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); + i2s_std_slot_config_t slot_cfg = I2S_STD_PHILIP_SLOT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO); + i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(SAMPLE_RATE); + + /* TX channel basic test */ + TEST_ESP_OK(i2s_new_channel(&chan_cfg, &tx_handle, NULL)); + + TEST_ESP_OK(i2s_init_channel(tx_handle, &clk_cfg, &slot_cfg)); + slot_cfg.data_bit_width = I2S_DATA_BIT_WIDTH_32BIT; + TEST_ESP_OK(i2s_set_slot(tx_handle, &slot_cfg)); + clk_cfg.sample_rate = 44100; + TEST_ESP_OK(i2s_set_clock(tx_handle, &clk_cfg)); + TEST_ESP_OK(i2s_start_channel(tx_handle)); + TEST_ESP_OK(i2s_del_channel(tx_handle)); + + /* Duplex channel basic test */ + chan_cfg.id = I2S_NUM_0; // Specify port id to I2S port 0 + TEST_ESP_OK(i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle)); + TEST_ESP_OK(i2s_init_channel(tx_handle, &clk_cfg, &slot_cfg)); + TEST_ESP_OK(i2s_init_channel(rx_handle, &clk_cfg, &slot_cfg)); + TEST_ESP_OK(i2s_del_channel(tx_handle)); + TEST_ESP_OK(i2s_del_channel(rx_handle)); + + /* Repeat to check if a same port can be applied again */ + TEST_ESP_OK(i2s_new_channel(&chan_cfg, NULL, &rx_handle)); + TEST_ESP_OK(i2s_del_channel(rx_handle)); + + /* Hold the occupation */ + TEST_ESP_OK(i2s_platform_acquire_occupation(I2S_NUM_0, "test_i2s")); + TEST_ASSERT(i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle) == ESP_ERR_NOT_FOUND); + TEST_ESP_OK(i2s_platform_release_occupation(I2S_NUM_0)); + TEST_ESP_OK(i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle)); + TEST_ESP_OK(i2s_del_channel(tx_handle)); + TEST_ESP_OK(i2s_del_channel(rx_handle)); +} + +TEST_CASE("I2S memory leak test", "[i2s]") +{ + i2s_gpio_config_t i2s_pin = I2S_TEST_MASTER_DEFAULT_PIN; + + i2s_chan_handle_t tx_handle; + i2s_chan_handle_t rx_handle; + + i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); + + /* The first operation will always take some memory */ + TEST_ESP_OK(i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle)); + TEST_ESP_OK(i2s_del_channel(tx_handle)); + TEST_ESP_OK(i2s_del_channel(rx_handle)); + + int memory_left = esp_get_free_heap_size(); + printf("\r\nHeap size before: %d\n", memory_left); + for (int i = 0; i < 100; i++) { + TEST_ESP_OK(i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle)); + TEST_ESP_OK(i2s_del_channel(tx_handle)); + TEST_ESP_OK(i2s_del_channel(rx_handle)); + TEST_ASSERT(memory_left == esp_get_free_heap_size()); + } + printf("\r\nHeap size after: %d\n", esp_get_free_heap_size()); +} + +TEST_CASE("I2S loopback test", "[i2s]") +{ + i2s_gpio_config_t i2s_pin = I2S_TEST_MASTER_DEFAULT_PIN; + + i2s_chan_handle_t tx_handle; + i2s_chan_handle_t rx_handle; + + i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); + i2s_std_slot_config_t slot_cfg = I2S_STD_PHILIP_SLOT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO); + i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(SAMPLE_RATE); + chan_cfg.id = I2S_NUM_0; + TEST_ESP_OK(i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle)); + TEST_ESP_OK(i2s_init_channel(tx_handle, &clk_cfg, &slot_cfg)); + TEST_ESP_OK(i2s_init_channel(rx_handle, &clk_cfg, &slot_cfg)); + i2s_test_io_config(I2S_TEST_MODE_LOOPBACK); + + TEST_ESP_OK(i2s_start_channel(tx_handle)); + TEST_ESP_OK(i2s_start_channel(rx_handle)); + + i2s_read_write_test(tx_handle, rx_handle); + + TEST_ESP_OK(i2s_del_channel(tx_handle)); + TEST_ESP_OK(i2s_del_channel(rx_handle)); +} + +#if SOC_I2S_NUM > 1 +TEST_CASE("I2S master write slave read test", "[i2s]") +{ + i2s_gpio_config_t mst_pin = I2S_TEST_MASTER_DEFAULT_PIN; + i2s_gpio_config_t slv_pin = I2S_TEST_SLAVE_DEFAULT_PIN; + + i2s_chan_handle_t tx_handle; + i2s_chan_handle_t rx_handle; + + i2s_chan_config_t mst_chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &mst_pin); + mst_chan_cfg.id = I2S_NUM_0; + i2s_chan_config_t slv_chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_SLAVE, I2S_COMM_MODE_STD, &slv_pin); + slv_chan_cfg.id = I2S_NUM_1; + i2s_std_slot_config_t slot_cfg = I2S_STD_PHILIP_SLOT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO); + i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(SAMPLE_RATE); + + TEST_ESP_OK(i2s_new_channel(&mst_chan_cfg, &tx_handle, NULL)); + TEST_ESP_OK(i2s_new_channel(&slv_chan_cfg, NULL, &rx_handle)); + TEST_ESP_OK(i2s_init_channel(tx_handle, &clk_cfg, &slot_cfg)); + TEST_ESP_OK(i2s_init_channel(rx_handle, &clk_cfg, &slot_cfg)); + i2s_test_io_config(I2S_TEST_MODE_MASTER_TO_SLAVE); + + TEST_ESP_OK(i2s_start_channel(tx_handle)); + TEST_ESP_OK(i2s_start_channel(rx_handle)); + + i2s_read_write_test(tx_handle, rx_handle); + + TEST_ESP_OK(i2s_del_channel(tx_handle)); + TEST_ESP_OK(i2s_del_channel(rx_handle)); +} + +TEST_CASE("I2S master read slave write test", "[i2s]") +{ + i2s_gpio_config_t mst_pin = I2S_TEST_MASTER_DEFAULT_PIN; + i2s_gpio_config_t slv_pin = I2S_TEST_SLAVE_DEFAULT_PIN; + + i2s_chan_handle_t tx_handle; + i2s_chan_handle_t rx_handle; + + i2s_chan_config_t mst_chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &mst_pin); + mst_chan_cfg.id = I2S_NUM_0; + i2s_chan_config_t slv_chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_SLAVE, I2S_COMM_MODE_STD, &slv_pin); + slv_chan_cfg.id = I2S_NUM_1; + i2s_std_slot_config_t slot_cfg = I2S_STD_PHILIP_SLOT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO); + i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(SAMPLE_RATE); + + TEST_ESP_OK(i2s_new_channel(&mst_chan_cfg, NULL, &rx_handle)); + TEST_ESP_OK(i2s_new_channel(&slv_chan_cfg, &tx_handle, NULL)); + TEST_ESP_OK(i2s_init_channel(tx_handle, &clk_cfg, &slot_cfg)); + TEST_ESP_OK(i2s_init_channel(rx_handle, &clk_cfg, &slot_cfg)); + i2s_test_io_config(I2S_TEST_MODE_SLAVE_TO_MASTER); + + TEST_ESP_OK(i2s_start_channel(tx_handle)); + TEST_ESP_OK(i2s_start_channel(rx_handle)); + + i2s_read_write_test(tx_handle, rx_handle); + + TEST_ESP_OK(i2s_del_channel(tx_handle)); + TEST_ESP_OK(i2s_del_channel(rx_handle)); +} +#endif + +/*------------------------------ Clock Test --------------------------------*/ +#if SOC_PCNT_SUPPORTED +#define TEST_I2S_PERIOD_MS 100 +static void i2s_test_common_sample_rate(i2s_chan_handle_t rx_chan, i2s_clk_config_t* clk_cfg) +{ + TEST_ASSERT_NOT_NULL(rx_chan); + TEST_ASSERT_NOT_NULL(clk_cfg); + + /* Prepare configuration for the PCNT unit */ + pcnt_config_t pcnt_cfg = { + // Set PCNT input signal and control GPIOs + .pulse_gpio_num = MASTER_WS_IO, + .ctrl_gpio_num = -1, + .channel = PCNT_CHANNEL_0, + .unit = PCNT_UNIT_0, + .pos_mode = PCNT_COUNT_INC, // Count up on the positive edge + .neg_mode = PCNT_COUNT_DIS, // Keep the counter value on the negative edge + .lctrl_mode = PCNT_MODE_KEEP, + .hctrl_mode = PCNT_MODE_KEEP, + .counter_h_lim = (int16_t)0x7fff, + .counter_l_lim = (int16_t)0x8000, + }; + TEST_ESP_OK(pcnt_unit_config(&pcnt_cfg)); + + // Reconfig GPIO signal + gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[MASTER_WS_IO], PIN_FUNC_GPIO); + gpio_set_direction(MASTER_WS_IO, GPIO_MODE_INPUT_OUTPUT); + esp_rom_gpio_connect_out_signal(MASTER_WS_IO, i2s_periph_signal[0].m_rx_ws_sig, 0, 0); + esp_rom_gpio_connect_in_signal(MASTER_WS_IO, pcnt_periph_signals.groups[0].units[0].channels[0].pulse_sig, 0); + + // pcnt_set_filter_value(PCNT_UNIT_0, 10); + pcnt_filter_disable(PCNT_UNIT_0); + + // Test common sample rate + uint32_t test_freq[15] = {8000, 11025, 12000, 16000, 22050, 24000, + 32000, 44100, 48000, 64000, 88200, 96000, + 128000, 144000, 196000}; + int16_t real_pulse = 0; + for (int i = 0; i < 15; i++) { + int16_t expt_pulse = (int16_t)((float)test_freq[i] * (TEST_I2S_PERIOD_MS / 1000.0)); + clk_cfg->sample_rate = test_freq[i]; + TEST_ESP_OK(i2s_set_clock(rx_chan, clk_cfg)); + TEST_ESP_OK(i2s_start_channel(rx_chan)); + vTaskDelay(1); // Waiting for hardware totally started + // pcnt will count the pulse number on WS signal in 100ms + TEST_ESP_OK(pcnt_counter_clear(PCNT_UNIT_0)); + TEST_ESP_OK(pcnt_counter_resume(PCNT_UNIT_0)); + vTaskDelay(pdMS_TO_TICKS(TEST_I2S_PERIOD_MS)); + TEST_ESP_OK(pcnt_counter_pause(PCNT_UNIT_0)); + TEST_ESP_OK(pcnt_get_counter_value(PCNT_UNIT_0, &real_pulse)); + printf("[%d Hz] %d pulses, expected %d, err %d\n", test_freq[i], real_pulse, expt_pulse, real_pulse - expt_pulse); + TEST_ESP_OK(i2s_stop_channel(rx_chan)); + // Check if the error between real pulse number and expected pulse number is within 1% + TEST_ASSERT_INT_WITHIN(expt_pulse * 0.01, expt_pulse, real_pulse); + } +} + +TEST_CASE("I2S D2CLK clock test", "[i2s]") +{ + i2s_gpio_config_t i2s_pin = I2S_TEST_MASTER_DEFAULT_PIN; + + i2s_chan_handle_t rx_handle; + + i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); + i2s_std_slot_config_t slot_cfg = I2S_STD_PHILIP_SLOT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO); + i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(SAMPLE_RATE); + chan_cfg.id = I2S_NUM_0; + + TEST_ESP_OK(i2s_new_channel(&chan_cfg, NULL, &rx_handle)); + TEST_ESP_OK(i2s_init_channel(rx_handle, &clk_cfg, &slot_cfg)); + + i2s_test_common_sample_rate(rx_handle, (i2s_clk_config_t *)&clk_cfg); + TEST_ESP_OK(i2s_del_channel(rx_handle)); +} + +#if SOC_I2S_SUPPORTS_APLL +TEST_CASE("I2S APLL clock test", "[i2s]") +{ + i2s_gpio_config_t i2s_pin = I2S_TEST_MASTER_DEFAULT_PIN; + + i2s_chan_handle_t rx_handle; + + i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); + i2s_std_slot_config_t slot_cfg = I2S_STD_PHILIP_SLOT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO); + i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(SAMPLE_RATE); + chan_cfg.id = I2S_NUM_0; + clk_cfg.clk_src = I2S_CLK_APLL; + + TEST_ESP_OK(i2s_new_channel(&chan_cfg, NULL, &rx_handle)); + TEST_ESP_OK(i2s_init_channel(rx_handle, &clk_cfg, &slot_cfg)); + + i2s_test_common_sample_rate(rx_handle, (i2s_clk_config_t *)&clk_cfg); + TEST_ESP_OK(i2s_del_channel(rx_handle)); +} +#endif // SOC_I2S_SUPPORTS_APLL +#endif // SOC_PCNT_SUPPORTED + +static void i2s_event_monitor(void *args) +{ + i2s_chan_handle_t rx_handle = *((i2s_chan_handle_t *)args); + QueueHandle_t evt_que = i2s_get_event_queue(rx_handle, 16); + TEST_ASSERT_NOT_NULL(evt_que); + i2s_event_t evnet; + while (1) { + xQueueReceive(evt_que, &evnet, portMAX_DELAY); + if (evnet.type == I2S_EVENT_RX_Q_OVF) { + break; + } + } + vTaskDelete(NULL); +} + +TEST_CASE("I2S package lost test", "[i2s]") +{ + /* Steps of calculate appropriate parameters of I2S buffer: + * Known by user: sample_rate = 144k, data_bit_width = 32, slot_num = 2, polling_cycle = 10 ms + * 1. dma_buffer_size = dma_frame_num * slot_num * data_bit_width / 8 <= 4092 + * dma_frame_num <= 511, dma_frame_num is as big as possible. + * interrupt_interval = dma_frame_num / sample_rate = 3.549 ms + * 2. dma_desc_num > polling_cycle / interrupt_interval = cell(2.818) = 3 + * 3. recv_buffer_size > dma_desc_num * dma_buffer_size = 3 * 4092 = 12276 bytes */ + #define TEST_RECV_BUF_LEN 12276 + i2s_gpio_config_t i2s_pin = I2S_TEST_MASTER_DEFAULT_PIN; + i2s_chan_handle_t rx_handle; + + i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); + i2s_std_slot_config_t slot_cfg = I2S_STD_PHILIP_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_STEREO); + slot_cfg.dma_desc_num = 3; + slot_cfg.dma_frame_num = 511; + i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(SAMPLE_RATE); + + TEST_ESP_OK(i2s_new_channel(&chan_cfg, NULL, &rx_handle)); + TEST_ESP_OK(i2s_init_channel(rx_handle, &clk_cfg, &slot_cfg)); + + TaskHandle_t h_monitor_task; + xTaskCreate(i2s_event_monitor, "event monitor task", 4096, &rx_handle, 5, &h_monitor_task); + + uint32_t test_freq[] = {16000, 32000, 48000, 64000, 96000, 128000, 144000}; + uint32_t test_num = sizeof(test_freq) / sizeof(uint32_t); + uint8_t *data = (uint8_t *)calloc(TEST_RECV_BUF_LEN, sizeof(uint8_t)); + size_t bytes_read = 0; + int i; + for (i = 0; i < test_num; i++) { + printf("Testing %d Hz sample rate\n", test_freq[i]); + clk_cfg.sample_rate = test_freq[i]; + TEST_ESP_OK(i2s_set_clock(rx_handle, &clk_cfg)); + TEST_ESP_OK(i2s_start_channel(rx_handle)); + for (int j = 0; j < 10; j++) { + TEST_ESP_OK(i2s_read_channel(rx_handle, (void *)data, TEST_RECV_BUF_LEN, &bytes_read, portMAX_DELAY)); + // To simulate 10ms delay caused by other statements like data process + vTaskDelay(1); + } + TEST_ESP_OK(i2s_stop_channel(rx_handle)); + if (eTaskGetState(h_monitor_task) == eDeleted) { + printf("package lost detected at %d Hz\n", test_freq[i]); + goto finish; + } + } + vTaskDelete(h_monitor_task); +finish: + TEST_ESP_OK(i2s_del_channel(rx_handle)); + free(data); + // Test failed if package lost within 96000 + TEST_ASSERT(i == test_num); +} diff --git a/components/driver/test/test_i2s.c b/components/driver/test_apps/i2s/main/test_i2s_legacy.c similarity index 97% rename from components/driver/test/test_i2s.c rename to components/driver/test_apps/i2s/main/test_i2s_legacy.c index a518b6ac20..03cad7ed12 100644 --- a/components/driver/test/test_i2s.c +++ b/components/driver/test_apps/i2s/main/test_i2s_legacy.c @@ -1,7 +1,7 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Unlicense OR CC0-1.0 + * SPDX-License-Identifier: Apache-2.0 */ /** @@ -11,19 +11,17 @@ * Please do not connect GPIO32(ESP32) any pull-up resistors externally, it will be used to test i2s adc function. */ - #include #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/queue.h" +#include "driver/i2s.h" #include "driver/gpio.h" #include "hal/gpio_hal.h" #include "unity.h" #include "math.h" #include "esp_rom_gpio.h" -#if SOC_I2S_SUPPORTED -#include "driver/i2s.h" #define SAMPLE_RATE (36000) #define SAMPLE_BITS (16) @@ -78,7 +76,12 @@ #define I2S_TEST_MODE_MASTER_TO_SLAVE 1 #define I2S_TEST_MODE_LOOPBACK 2 -// mode: 0, master rx, slave tx. mode: 1, master tx, slave rx. mode: 2, master tx rx loopback +// This empty function is used to force the compiler link this file +void test_app_include_i2s_legacy(void) +{ +} + +// mode: 0, master rx, slave tx. mode: 1, master tx, slave rx. mode: 2, master tx rx loop-back // Since ESP32-S2 has only one I2S, only loop back test can be tested. static void i2s_test_io_config(int mode) { @@ -136,7 +139,7 @@ static void i2s_test_io_config(int mode) * 1. i2s_driver_install * 2. i2s_set_pin */ -TEST_CASE("I2S basic driver install, uninstall, set pin test", "[i2s]") +TEST_CASE("I2S basic driver install, uninstall, set pin test", "[i2s_legacy]") { // dac, adc i2s i2s_config_t i2s_config = { @@ -183,7 +186,7 @@ TEST_CASE("I2S basic driver install, uninstall, set pin test", "[i2s]") TEST_ASSERT_EQUAL(ESP_ERR_INVALID_STATE, i2s_driver_uninstall(I2S_NUM_0)); } -TEST_CASE("I2S Loopback test(master tx and rx)", "[i2s]") +TEST_CASE("I2S Loopback test(master tx and rx)", "[i2s_legacy]") { // master driver installed and send data i2s_config_t master_i2s_config = { @@ -256,7 +259,7 @@ TEST_CASE("I2S Loopback test(master tx and rx)", "[i2s]") } #if SOC_I2S_SUPPORTS_TDM -TEST_CASE("I2S TDM Loopback test(master tx and rx)", "[i2s]") +TEST_CASE("I2S TDM Loopback test(master tx and rx)", "[i2s_legacy]") { // master driver installed and send data i2s_config_t master_i2s_config = { @@ -325,7 +328,7 @@ TEST_CASE("I2S TDM Loopback test(master tx and rx)", "[i2s]") #if SOC_I2S_NUM > 1 /* ESP32S2 and ESP32C3 has only single I2S port and hence following test cases are not applicable */ -TEST_CASE("I2S write and read test(master tx and slave rx)", "[i2s]") +TEST_CASE("I2S write and read test(master tx and slave rx)", "[i2s_legacy]") { // master driver installed and send data i2s_config_t master_i2s_config = { @@ -429,7 +432,7 @@ TEST_CASE("I2S write and read test(master tx and slave rx)", "[i2s]") i2s_driver_uninstall(I2S_NUM_1); } -TEST_CASE("I2S write and read test(master rx and slave tx)", "[i2s]") +TEST_CASE("I2S write and read test(master rx and slave tx)", "[i2s_legacy]") { // master driver installed and send data i2s_config_t master_i2s_config = { @@ -535,7 +538,7 @@ TEST_CASE("I2S write and read test(master rx and slave tx)", "[i2s]") } #endif -TEST_CASE("I2S memory leaking test", "[i2s]") +TEST_CASE("I2S memory leaking test", "[i2s_legacy]") { i2s_config_t master_i2s_config = { .mode = I2S_MODE_MASTER | I2S_MODE_RX, @@ -585,7 +588,7 @@ TEST_CASE("I2S memory leaking test", "[i2s]") * and the APLL clock generate for it. The TEST_CASE passes PERCENT_DIFF variation from the provided sample rate in APLL generated clock * The percentage difference calculated as (mod((obtained clock rate - desired clock rate)/(desired clock rate))) * 100. */ -TEST_CASE("I2S APLL clock variation test", "[i2s]") +TEST_CASE("I2S APLL clock variation test", "[i2s_legacy]") { i2s_pin_config_t pin_config = { .mck_io_num = -1, @@ -643,7 +646,7 @@ TEST_CASE("I2S APLL clock variation test", "[i2s]") #if SOC_I2S_SUPPORTS_ADC /* Only ESP32 need I2S adc/dac test */ -TEST_CASE("I2S adc test", "[i2s]") +TEST_CASE("I2S adc test", "[i2s_legacy]") { // init I2S ADC i2s_config_t i2s_config = { @@ -673,7 +676,7 @@ TEST_CASE("I2S adc test", "[i2s]") } else { gpio_set_pull_mode(ADC1_CHANNEL_4_IO, GPIO_PULLUP_ONLY); } - vTaskDelay(200 / portTICK_PERIOD_MS); + vTaskDelay(pdMS_TO_TICKS(200)); // read data from adc, will block until buffer is full i2s_read(I2S_NUM_0, (void *)i2sReadBuffer, 1024 * sizeof(uint16_t), &bytesRead, portMAX_DELAY); @@ -710,7 +713,7 @@ TEST_CASE("I2S adc test", "[i2s]") #endif #if SOC_I2S_SUPPORTS_DAC -TEST_CASE("I2S dac test", "[i2s]") +TEST_CASE("I2S dac test", "[i2s_legacy]") { // dac, adc i2s i2s_config_t i2s_config = { @@ -733,5 +736,3 @@ TEST_CASE("I2S dac test", "[i2s]") TEST_ESP_OK(i2s_driver_uninstall(I2S_NUM_0)); } #endif - -#endif //SOC_I2S_SUPPORTED diff --git a/components/driver/test_apps/i2s/sdkconfig.defaults b/components/driver/test_apps/i2s/sdkconfig.defaults new file mode 100644 index 0000000000..16e72deaf9 --- /dev/null +++ b/components/driver/test_apps/i2s/sdkconfig.defaults @@ -0,0 +1,3 @@ +CONFIG_I2S_SUPPRESS_DEPRECATE_WARN=y +CONFIG_PCNT_SUPPRESS_DEPRECATE_WARN=y +CONFIG_ESP_TASK_WDT=n diff --git a/components/esp_hw_support/clk_ctrl_os.c b/components/esp_hw_support/clk_ctrl_os.c index 1d6ff03909..3cf14aebc1 100644 --- a/components/esp_hw_support/clk_ctrl_os.c +++ b/components/esp_hw_support/clk_ctrl_os.c @@ -121,4 +121,4 @@ esp_err_t periph_rtc_apll_freq_set(uint32_t expt_freq, uint32_t *real_freq) return ESP_OK; } -#endif // SOC_I2S_SUPPORTS_APLL +#endif // SOC_CLK_APLL_SUPPORTED diff --git a/components/esp_hw_support/include/clk_ctrl_os.h b/components/esp_hw_support/include/clk_ctrl_os.h index 88478663bb..9d1084c149 100644 --- a/components/esp_hw_support/include/clk_ctrl_os.h +++ b/components/esp_hw_support/include/clk_ctrl_os.h @@ -5,6 +5,7 @@ */ #include "soc/rtc.h" +#include "soc/soc_caps.h" #include "esp_err.h" #ifdef __cplusplus diff --git a/components/esp_lcd/src/esp_lcd_panel_io_i2s.c b/components/esp_lcd/src/esp_lcd_panel_io_i2s.c index f722463933..f341f2be36 100644 --- a/components/esp_lcd/src/esp_lcd_panel_io_i2s.c +++ b/components/esp_lcd/src/esp_lcd_panel_io_i2s.c @@ -152,7 +152,7 @@ esp_err_t esp_lcd_new_i80_bus(const esp_lcd_i80_bus_config_t *bus_config, esp_lc // LCD mode can't work with other modes at the same time, we need to register the driver object to the I2S platform int bus_id = -1; for (int i = 0; i < SOC_LCD_I80_BUSES; i++) { - if (i2s_priv_register_object(bus, i) == ESP_OK) { + if (i2s_platform_acquire_occupation(0, "esp_lcd_panel_io_i2s") == ESP_OK) { bus_id = i; break; } @@ -214,7 +214,7 @@ err: esp_intr_free(bus->intr); } if (bus->bus_id >= 0) { - i2s_priv_deregister_object(bus->bus_id); + i2s_platform_release_occupation(bus->bus_id); } if (bus->format_buffer) { free(bus->format_buffer); @@ -233,7 +233,7 @@ esp_err_t esp_lcd_del_i80_bus(esp_lcd_i80_bus_handle_t bus) ESP_GOTO_ON_FALSE(bus, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument"); ESP_GOTO_ON_FALSE(LIST_EMPTY(&bus->device_list), ESP_ERR_INVALID_STATE, err, TAG, "device list not empty"); int bus_id = bus->bus_id; - i2s_priv_deregister_object(bus_id); + i2s_platform_release_occupation(bus_id); esp_intr_free(bus->intr); if (bus->pm_lock) { esp_pm_lock_delete(bus->pm_lock); @@ -593,9 +593,9 @@ static esp_err_t i2s_lcd_select_periph_clock(esp_lcd_i80_bus_handle_t bus, lcd_c switch (src) { case LCD_CLK_SRC_PLL160M: bus->resolution_hz = 160000000 / LCD_PERIPH_CLOCK_PRE_SCALE; - i2s_ll_tx_clk_set_src(bus->hal.dev, I2S_CLK_D2CLK); + i2s_ll_tx_clk_set_src(bus->hal.dev, I2S_CLK_160M_PLL); #if CONFIG_PM_ENABLE - ret = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "i2s_bus_lcd", &bus->pm_lock); + ret = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "i2s_controller_lcd", &bus->pm_lock); ESP_RETURN_ON_ERROR(ret, TAG, "create ESP_PM_APB_FREQ_MAX lock failed"); ESP_LOGD(TAG, "installed ESP_PM_APB_FREQ_MAX lock"); #endif diff --git a/components/esp_lcd/test_apps/i80_lcd/main/test_i80_lcd_panel.c b/components/esp_lcd/test_apps/i80_lcd/main/test_i80_lcd_panel.c index 4d3be8bc5f..4062f7fae1 100644 --- a/components/esp_lcd/test_apps/i80_lcd/main/test_i80_lcd_panel.c +++ b/components/esp_lcd/test_apps/i80_lcd/main/test_i80_lcd_panel.c @@ -1,7 +1,7 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: CC0-1.0 + * SPDX-License-Identifier: Apache-2.0 */ #include @@ -18,7 +18,7 @@ #include "test_i80_board.h" #if SOC_I2S_LCD_I80_VARIANT -#include "driver/i2s.h" +#include "driver/i2s_controller.h" TEST_CASE("i80_and_i2s_driver_co-existence", "[lcd][i2s]") { @@ -42,17 +42,19 @@ TEST_CASE("i80_and_i2s_driver_co-existence", "[lcd][i2s]") }; TEST_ESP_OK(esp_lcd_new_i80_bus(&bus_config, &i80_bus)); - i2s_config_t i2s_config = { - .mode = I2S_MODE_MASTER | I2S_MODE_TX, - .sample_rate = 36000, - .bits_per_sample = 16, - .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, - .communication_format = I2S_COMM_FORMAT_STAND_I2S, - .dma_desc_num = 6, - .dma_frame_num = 60, + + i2s_chan_handle_t tx_handle = NULL; + i2s_gpio_config_t i2s_pin = { + .mclk = I2S_GPIO_UNUSED, + .bclk = I2S_GPIO_UNUSED, + .ws = I2S_GPIO_UNUSED, + .dout = I2S_GPIO_UNUSED, + .din = I2S_GPIO_UNUSED }; + i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); + chan_cfg.id = 0; // I2S driver won't be installed as the same I2S port has been used by LCD - TEST_ASSERT_EQUAL(ESP_ERR_INVALID_STATE, i2s_driver_install(0, &i2s_config, 0, NULL)); + TEST_ASSERT_EQUAL(ESP_ERR_NOT_FOUND, i2s_new_channel(&chan_cfg, &tx_handle, NULL)); TEST_ESP_OK(esp_lcd_del_i80_bus(i80_bus)); } #endif // SOC_I2S_LCD_I80_VARIANT @@ -459,3 +461,43 @@ TEST_CASE("lcd_panel_with_i80_interface_(st7789, 8bits)", "[lcd]") free(img); #undef TEST_IMG_SIZE } + +#if SOC_I2S_LCD_I80_VARIANT +#include "driver/i2s_controller.h" + +TEST_CASE("i80 and i2s driver coexistance", "[lcd][i2s]") +{ + esp_lcd_i80_bus_handle_t i80_bus = NULL; + esp_lcd_i80_bus_config_t bus_config = { + .dc_gpio_num = TEST_LCD_DC_GPIO, + .wr_gpio_num = TEST_LCD_PCLK_GPIO, + .data_gpio_nums = { + TEST_LCD_DATA0_GPIO, + TEST_LCD_DATA1_GPIO, + TEST_LCD_DATA2_GPIO, + TEST_LCD_DATA3_GPIO, + TEST_LCD_DATA4_GPIO, + TEST_LCD_DATA5_GPIO, + TEST_LCD_DATA6_GPIO, + TEST_LCD_DATA7_GPIO, + }, + .bus_width = 8, + .max_transfer_bytes = 20, + }; + TEST_ESP_OK(esp_lcd_new_i80_bus(&bus_config, &i80_bus)); + + i2s_gpio_config_t i2s_pin = { + .mclk = 0, + .bclk = 15, + .ws = 25, + .dout = 21, + .din = 22 + }; + i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); + chan_cfg.id = I2S_NUM_0; + i2s_chan_handle_t tx_handle; + // I2S driver won't be installed as the same I2S port has been used by LCD + TEST_ASSERT_EQUAL(ESP_ERR_NOT_FOUND, i2s_new_channel(&chan_cfg, &tx_handle, NULL)); + TEST_ESP_OK(esp_lcd_del_i80_bus(i80_bus)); +} +#endif // SOC_I2S_LCD_I80_VARIANT diff --git a/components/hal/adc_hal.c b/components/hal/adc_hal.c index 9af9079a76..efb28c154a 100644 --- a/components/hal/adc_hal.c +++ b/components/hal/adc_hal.c @@ -189,7 +189,7 @@ static void adc_hal_digi_sample_freq_config(adc_hal_dma_ctx_t *hal, uint32_t fre adc_ll_digi_controller_clk_div(ADC_LL_CLKM_DIV_NUM_DEFAULT, ADC_LL_CLKM_DIV_B_DEFAULT, ADC_LL_CLKM_DIV_A_DEFAULT); adc_ll_digi_clk_sel(0); //use APB #else - i2s_ll_rx_clk_set_src(hal->dev, I2S_CLK_D2CLK); /*!< Clock from PLL_D2_CLK(160M)*/ + i2s_ll_rx_clk_set_src(hal->dev, I2S_CLK_160M_PLL); /*!< Clock from PLL_D2_CLK(160M)*/ uint32_t bck = I2S_BASE_CLK / (ADC_LL_CLKM_DIV_NUM_DEFAULT + ADC_LL_CLKM_DIV_B_DEFAULT / ADC_LL_CLKM_DIV_A_DEFAULT) / 2 / freq; i2s_ll_set_raw_mclk_div(hal->dev, ADC_LL_CLKM_DIV_NUM_DEFAULT, ADC_LL_CLKM_DIV_A_DEFAULT, ADC_LL_CLKM_DIV_B_DEFAULT); i2s_ll_rx_set_bck_div_num(hal->dev, bck); diff --git a/components/hal/esp32/include/hal/i2s_ll.h b/components/hal/esp32/include/hal/i2s_ll.h index 82f1baffcb..f8f4aa197c 100644 --- a/components/hal/esp32/include/hal/i2s_ll.h +++ b/components/hal/esp32/include/hal/i2s_ll.h @@ -19,7 +19,6 @@ #include "soc/i2s_periph.h" #include "soc/i2s_struct.h" #include "hal/i2s_types.h" -#include "hal/i2s_types_priv.h" #ifdef __cplusplus extern "C" { diff --git a/components/hal/esp32c3/include/hal/i2s_ll.h b/components/hal/esp32c3/include/hal/i2s_ll.h index 686cd6bf50..860214db67 100644 --- a/components/hal/esp32c3/include/hal/i2s_ll.h +++ b/components/hal/esp32c3/include/hal/i2s_ll.h @@ -200,7 +200,7 @@ static inline void i2s_ll_tx_clk_set_src(i2s_dev_t *hw, i2s_clock_src_t src) * @brief Set RX source clock * * @param hw Peripheral I2S hardware instance address. - * @param src I2S source clock, ESP32-C3 only support `I2S_CLK_D2CLK` + * @param src I2S source clock, ESP32-C3 only support `I2S_CLK_160M_PLL` */ static inline void i2s_ll_rx_clk_set_src(i2s_dev_t *hw, i2s_clock_src_t src) { diff --git a/components/hal/esp32h2/include/hal/i2s_ll.h b/components/hal/esp32h2/include/hal/i2s_ll.h index cd8418dda1..f610367dfb 100644 --- a/components/hal/esp32h2/include/hal/i2s_ll.h +++ b/components/hal/esp32h2/include/hal/i2s_ll.h @@ -201,7 +201,7 @@ static inline void i2s_ll_tx_clk_set_src(i2s_dev_t *hw, i2s_clock_src_t src) * @brief Set RX source clock * * @param hw Peripheral I2S hardware instance address. - * @param src I2S source clock, ESP32-H2 only support `I2S_CLK_D2CLK` + * @param src I2S source clock, ESP32-H2 only support `I2S_CLK_160M_PLL` */ static inline void i2s_ll_rx_clk_set_src(i2s_dev_t *hw, i2s_clock_src_t src) { diff --git a/components/hal/esp32s3/include/hal/i2s_ll.h b/components/hal/esp32s3/include/hal/i2s_ll.h index 0d33d13de8..e2712aed7b 100644 --- a/components/hal/esp32s3/include/hal/i2s_ll.h +++ b/components/hal/esp32s3/include/hal/i2s_ll.h @@ -190,7 +190,7 @@ static inline void i2s_ll_rx_reset_fifo(i2s_dev_t *hw) * @brief Set TX source clock * * @param hw Peripheral I2S hardware instance address. - * @param src I2S source clock, ESP32-S3 only support `I2S_CLK_D2CLK` + * @param src I2S source clock, ESP32-S3 only support `I2S_CLK_160M_PLL` * TX and RX share the same clock setting */ static inline void i2s_ll_tx_clk_set_src(i2s_dev_t *hw, i2s_clock_src_t src) @@ -202,7 +202,7 @@ static inline void i2s_ll_tx_clk_set_src(i2s_dev_t *hw, i2s_clock_src_t src) * @brief Set RX source clock * * @param hw Peripheral I2S hardware instance address. - * @param src I2S source clock, ESP32-S3 only support `I2S_CLK_D2CLK` + * @param src I2S source clock, ESP32-S3 only support `I2S_CLK_160M_PLL` * TX and RX share the same clock setting */ static inline void i2s_ll_rx_clk_set_src(i2s_dev_t *hw, i2s_clock_src_t src) diff --git a/components/hal/i2s_hal.c b/components/hal/i2s_hal.c index f0fce8ff69..39af05752b 100644 --- a/components/hal/i2s_hal.c +++ b/components/hal/i2s_hal.c @@ -10,10 +10,6 @@ #include "soc/soc.h" #include "hal/i2s_hal.h" -#include "hal/i2s_std.h" -#include "hal/i2s_pdm.h" -#include "hal/i2s_tdm.h" - #if SOC_I2S_HW_VERSION_2 && SOC_I2S_SUPPORTS_PDM_TX /* PDM tx high pass filter cut-off frequency and coeffecients list * [0]: cut-off frequency; [1]: param0; [2]: param5 */ @@ -33,7 +29,7 @@ void i2s_hal_init(i2s_hal_context_t *hal, int port_id) hal->dev = I2S_LL_GET_HW(port_id); } -void i2s_hal_set_tx_clock(i2s_hal_context_t *hal, const i2s_clock_info_t *clk_info, i2s_clock_src_t clk_src) +void i2s_hal_set_tx_clock(i2s_hal_context_t *hal, const i2s_hal_clock_info_t *clk_info, i2s_clock_src_t clk_src) { #if SOC_I2S_HW_VERSION_2 i2s_ll_tx_enable_clock(hal->dev); @@ -44,7 +40,7 @@ void i2s_hal_set_tx_clock(i2s_hal_context_t *hal, const i2s_clock_info_t *clk_in i2s_ll_tx_set_bck_div_num(hal->dev, clk_info->bclk_div); } -void i2s_hal_set_rx_clock(i2s_hal_context_t *hal, const i2s_clock_info_t *clk_info, i2s_clock_src_t clk_src) +void i2s_hal_set_rx_clock(i2s_hal_context_t *hal, const i2s_hal_clock_info_t *clk_info, i2s_clock_src_t clk_src) { #if SOC_I2S_HW_VERSION_2 i2s_ll_rx_enable_clock(hal->dev); @@ -58,55 +54,52 @@ void i2s_hal_set_rx_clock(i2s_hal_context_t *hal, const i2s_clock_info_t *clk_in /*------------------------------------------------------------------------- | STD Specific Slot Configurations | -------------------------------------------------------------------------*/ -void i2s_hal_std_set_tx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_slot_config_t *slot_config) +void i2s_hal_std_set_tx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_hal_slot_config_t *slot_cfg) { - i2s_std_slot_config_t *slot_cfg = (i2s_std_slot_config_t*)slot_config; uint32_t slot_bit_width = (int)slot_cfg->slot_bit_width < (int)slot_cfg->data_bit_width ? slot_cfg->data_bit_width : slot_cfg->slot_bit_width; i2s_ll_tx_reset(hal->dev); i2s_ll_tx_set_slave_mod(hal->dev, is_slave); //TX Slave i2s_ll_tx_set_sample_bit(hal->dev, slot_bit_width, slot_cfg->data_bit_width); i2s_ll_tx_enable_mono_mode(hal->dev, slot_cfg->slot_mode == I2S_SLOT_MODE_MONO); - i2s_ll_tx_enable_msb_shift(hal->dev, slot_cfg->bit_shift); - i2s_ll_tx_set_ws_width(hal->dev, slot_cfg->ws_width); - i2s_ll_tx_select_slot(hal->dev, slot_cfg->slot_sel); + i2s_ll_tx_enable_msb_shift(hal->dev, slot_cfg->std.bit_shift); + i2s_ll_tx_set_ws_width(hal->dev, slot_cfg->std.ws_width); #if SOC_I2S_HW_VERSION_1 - i2s_ll_tx_enable_msb_right(hal->dev, slot_cfg->msb_right); - i2s_ll_tx_enable_right_first(hal->dev, slot_cfg->ws_pol); + i2s_ll_tx_enable_msb_right(hal->dev, slot_cfg->std.msb_right); + i2s_ll_tx_enable_right_first(hal->dev, slot_cfg->std.ws_pol); /* Should always enable fifo */ i2s_ll_tx_force_enable_fifo_mod(hal->dev, true); #elif SOC_I2S_HW_VERSION_2 i2s_ll_tx_set_half_sample_bit(hal->dev, slot_bit_width); - i2s_ll_tx_set_ws_idle_pol(hal->dev, slot_cfg->ws_pol); - i2s_ll_tx_set_bit_order(hal->dev, slot_cfg->bit_order_lsb); - i2s_ll_tx_enable_left_align(hal->dev, slot_cfg->left_align); - i2s_ll_tx_enable_big_endian(hal->dev, slot_cfg->big_endian); + i2s_ll_tx_set_ws_idle_pol(hal->dev, slot_cfg->std.ws_pol); + i2s_ll_tx_set_bit_order(hal->dev, slot_cfg->std.bit_order_lsb); + i2s_ll_tx_enable_left_align(hal->dev, slot_cfg->std.left_align); + i2s_ll_tx_enable_big_endian(hal->dev, slot_cfg->std.big_endian); #endif } -void i2s_hal_std_set_rx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_slot_config_t *slot_config) +void i2s_hal_std_set_rx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_hal_slot_config_t *slot_cfg) { - i2s_std_slot_config_t *slot_cfg = (i2s_std_slot_config_t*)slot_config; uint32_t slot_bit_width = (int)slot_cfg->slot_bit_width < (int)slot_cfg->data_bit_width ? slot_cfg->data_bit_width : slot_cfg->slot_bit_width; i2s_ll_rx_reset(hal->dev); i2s_ll_rx_set_slave_mod(hal->dev, is_slave); //RX Slave i2s_ll_rx_set_sample_bit(hal->dev, slot_bit_width, slot_cfg->data_bit_width); i2s_ll_rx_enable_mono_mode(hal->dev, slot_cfg->slot_mode == I2S_SLOT_MODE_MONO); - i2s_ll_rx_enable_msb_shift(hal->dev, slot_cfg->bit_shift); - i2s_ll_rx_set_ws_width(hal->dev, slot_cfg->ws_width); - i2s_ll_rx_select_slot(hal->dev, slot_cfg->slot_sel); + i2s_ll_rx_enable_msb_shift(hal->dev, slot_cfg->std.bit_shift); + i2s_ll_rx_set_ws_width(hal->dev, slot_cfg->std.ws_width); + i2s_ll_rx_select_slot(hal->dev, slot_cfg->std.slot_sel); #if SOC_I2S_HW_VERSION_1 - i2s_ll_rx_enable_msb_right(hal->dev, slot_cfg->msb_right); - i2s_ll_rx_enable_right_first(hal->dev, slot_cfg->ws_pol); + i2s_ll_rx_enable_msb_right(hal->dev, slot_cfg->std.msb_right); + i2s_ll_rx_enable_right_first(hal->dev, slot_cfg->std.ws_pol); /* Should always enable fifo */ i2s_ll_rx_force_enable_fifo_mod(hal->dev, true); #elif SOC_I2S_HW_VERSION_2 i2s_ll_rx_set_half_sample_bit(hal->dev, slot_bit_width); - i2s_ll_rx_set_ws_idle_pol(hal->dev, slot_cfg->ws_pol); - i2s_ll_rx_set_bit_order(hal->dev, slot_cfg->bit_order_lsb); - i2s_ll_rx_enable_left_align(hal->dev, slot_cfg->left_align); - i2s_ll_rx_enable_big_endian(hal->dev, slot_cfg->big_endian); + i2s_ll_rx_set_ws_idle_pol(hal->dev, slot_cfg->std.ws_pol); + i2s_ll_rx_set_bit_order(hal->dev, slot_cfg->std.bit_order_lsb); + i2s_ll_rx_enable_left_align(hal->dev, slot_cfg->std.left_align); + i2s_ll_rx_enable_big_endian(hal->dev, slot_cfg->std.big_endian); #endif } @@ -124,9 +117,8 @@ void i2s_hal_std_enable_rx_channel(i2s_hal_context_t *hal) | PDM Specific Slot Configurations | -------------------------------------------------------------------------*/ #if SOC_I2S_SUPPORTS_PDM_TX -void i2s_hal_pdm_set_tx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_slot_config_t *slot_config) +void i2s_hal_pdm_set_tx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_hal_slot_config_t *slot_cfg) { - i2s_pdm_tx_slot_config_t *slot_cfg = (i2s_pdm_tx_slot_config_t *)slot_config; uint32_t slot_bit_width = (int)slot_cfg->slot_bit_width < (int)slot_cfg->data_bit_width ? slot_cfg->data_bit_width : slot_cfg->slot_bit_width; i2s_ll_tx_reset(hal->dev); @@ -134,21 +126,21 @@ void i2s_hal_pdm_set_tx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_sl i2s_ll_tx_set_sample_bit(hal->dev, slot_bit_width, slot_cfg->data_bit_width); i2s_ll_tx_enable_mono_mode(hal->dev, slot_cfg->slot_mode == I2S_SLOT_MODE_MONO); - i2s_ll_tx_set_pdm_prescale(hal->dev, slot_cfg->sd_prescale); - i2s_ll_tx_set_pdm_hp_scale(hal->dev, slot_cfg->hp_scale); - i2s_ll_tx_set_pdm_lp_scale(hal->dev, slot_cfg->lp_scale); - i2s_ll_tx_set_pdm_sinc_scale(hal->dev, slot_cfg->sinc_scale); - i2s_ll_tx_set_pdm_sd_scale(hal->dev, slot_cfg->sd_scale); + i2s_ll_tx_set_pdm_prescale(hal->dev, slot_cfg->pdm_tx.sd_prescale); + i2s_ll_tx_set_pdm_hp_scale(hal->dev, slot_cfg->pdm_tx.hp_scale); + i2s_ll_tx_set_pdm_lp_scale(hal->dev, slot_cfg->pdm_tx.lp_scale); + i2s_ll_tx_set_pdm_sinc_scale(hal->dev, slot_cfg->pdm_tx.sinc_scale); + i2s_ll_tx_set_pdm_sd_scale(hal->dev, slot_cfg->pdm_tx.sd_scale); #if SOC_I2S_HW_VERSION_1 i2s_ll_tx_force_enable_fifo_mod(hal->dev, true); #elif SOC_I2S_HW_VERSION_2 /* Still need to enable the first 2 TDM channel mask to get the correct number of frame */ i2s_ll_tx_set_active_chan_mask(hal->dev, I2S_TDM_SLOT0 | I2S_TDM_SLOT1); - i2s_ll_tx_enable_pdm_hp_filter(hal->dev, slot_cfg->hp_en); + i2s_ll_tx_enable_pdm_hp_filter(hal->dev, slot_cfg->pdm_tx.hp_en); uint8_t cnt = 0; float min = 1000; - float expt_cut_off = slot_cfg->hp_cut_off_freq_hz; + float expt_cut_off = slot_cfg->pdm_tx.hp_cut_off_freq_hz; /* Find the closest cut-off frequency and its coefficients */ for (int i = 0; i < 21; i++) { float tmp = cut_off_coef[i][0] < expt_cut_off ? expt_cut_off - cut_off_coef[i][0] : cut_off_coef[i][0] - expt_cut_off; @@ -159,9 +151,9 @@ void i2s_hal_pdm_set_tx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_sl } i2s_ll_tx_set_pdm_hp_filter_param0(hal->dev, cut_off_coef[cnt][1]); i2s_ll_tx_set_pdm_hp_filter_param5(hal->dev, cut_off_coef[cnt][2]); - i2s_ll_tx_enable_pdm_sd_codec(hal->dev, slot_cfg->sd_en); - i2s_ll_tx_set_pdm_sd_dither(hal->dev, slot_cfg->sd_dither); - i2s_ll_tx_set_pdm_sd_dither2(hal->dev, slot_cfg->sd_dither2); + i2s_ll_tx_enable_pdm_sd_codec(hal->dev, slot_cfg->pdm_tx.sd_en); + i2s_ll_tx_set_pdm_sd_dither(hal->dev, slot_cfg->pdm_tx.sd_dither); + i2s_ll_tx_set_pdm_sd_dither2(hal->dev, slot_cfg->pdm_tx.sd_dither2); #endif } @@ -172,9 +164,8 @@ void i2s_hal_pdm_enable_tx_channel(i2s_hal_context_t *hal) #endif #if SOC_I2S_SUPPORTS_PDM_RX -void i2s_hal_pdm_set_rx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_slot_config_t *slot_config) +void i2s_hal_pdm_set_rx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_hal_slot_config_t *slot_cfg) { - i2s_pdm_rx_slot_config_t *slot_cfg = (i2s_pdm_rx_slot_config_t *)slot_config; uint32_t slot_bit_width = (int)slot_cfg->slot_bit_width < (int)slot_cfg->data_bit_width ? slot_cfg->data_bit_width : slot_cfg->slot_bit_width; i2s_ll_rx_reset(hal->dev); @@ -199,74 +190,72 @@ void i2s_hal_pdm_enable_rx_channel(i2s_hal_context_t *hal) | TDM Specific Slot Configurations | -------------------------------------------------------------------------*/ #if SOC_I2S_SUPPORTS_TDM -void i2s_hal_tdm_set_tx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_slot_config_t *slot_config) +void i2s_hal_tdm_set_tx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_hal_slot_config_t *slot_cfg) { - i2s_tdm_slot_config_t *slot_cfg = (i2s_tdm_slot_config_t*)slot_config; uint32_t slot_bit_width = (int)slot_cfg->slot_bit_width < (int)slot_cfg->data_bit_width ? slot_cfg->data_bit_width : slot_cfg->slot_bit_width; uint32_t cnt; - uint32_t msk = slot_cfg->slot_mask; + uint32_t msk = slot_cfg->tdm.slot_mask; /* Get the maximum slot number */ cnt = 32 - __builtin_clz(msk); /* There should be at least 2 slots in total even for mono mode */ cnt = cnt < 2 ? 2 : cnt; - uint32_t total_slot = slot_cfg->total_slot > cnt ? slot_cfg->total_slot : cnt; + uint32_t total_slot = slot_cfg->tdm.total_slot > cnt ? slot_cfg->tdm.total_slot : cnt; i2s_ll_tx_reset(hal->dev); i2s_ll_tx_set_slave_mod(hal->dev, is_slave); //TX Slave i2s_ll_tx_set_sample_bit(hal->dev, slot_bit_width, slot_cfg->data_bit_width); i2s_ll_tx_enable_mono_mode(hal->dev, slot_cfg->slot_mode == I2S_SLOT_MODE_MONO); - i2s_ll_tx_enable_msb_shift(hal->dev, slot_cfg->bit_shift); - if (slot_cfg->ws_width == I2S_TDM_AUTO_WS_WIDTH) { + i2s_ll_tx_enable_msb_shift(hal->dev, slot_cfg->tdm.bit_shift); + if (slot_cfg->tdm.ws_width == I2S_TDM_AUTO_WS_WIDTH) { i2s_ll_tx_set_ws_width(hal->dev, (total_slot * slot_bit_width) / 2); } else { - i2s_ll_tx_set_ws_width(hal->dev, slot_cfg->ws_width); + i2s_ll_tx_set_ws_width(hal->dev, slot_cfg->tdm.ws_width); } - i2s_ll_tx_set_ws_idle_pol(hal->dev, slot_cfg->ws_pol); + i2s_ll_tx_set_ws_idle_pol(hal->dev, slot_cfg->tdm.ws_pol); i2s_ll_tx_set_chan_num(hal->dev, total_slot); /* In mono mode, there only should be one slot enabled, other inactive slots will transmit same data as enabled slot */ i2s_ll_tx_set_active_chan_mask(hal->dev, (slot_cfg->slot_mode == I2S_SLOT_MODE_MONO) ? - I2S_TDM_SLOT0 : (uint32_t)slot_cfg->slot_mask); - i2s_ll_tx_set_skip_mask(hal->dev, slot_cfg->skip_mask); + I2S_TDM_SLOT0 : (uint32_t)slot_cfg->tdm.slot_mask); + i2s_ll_tx_set_skip_mask(hal->dev, slot_cfg->tdm.skip_mask); i2s_ll_tx_set_half_sample_bit(hal->dev, total_slot * slot_bit_width / 2); - i2s_ll_tx_set_bit_order(hal->dev, slot_cfg->bit_order_lsb); - i2s_ll_tx_enable_left_align(hal->dev, slot_cfg->left_align); - i2s_ll_tx_enable_big_endian(hal->dev, slot_cfg->big_endian); + i2s_ll_tx_set_bit_order(hal->dev, slot_cfg->tdm.bit_order_lsb); + i2s_ll_tx_enable_left_align(hal->dev, slot_cfg->tdm.left_align); + i2s_ll_tx_enable_big_endian(hal->dev, slot_cfg->tdm.big_endian); } -void i2s_hal_tdm_set_rx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_slot_config_t *slot_config) +void i2s_hal_tdm_set_rx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_hal_slot_config_t *slot_cfg) { - i2s_tdm_slot_config_t *slot_cfg = (i2s_tdm_slot_config_t*)slot_config; uint32_t slot_bit_width = (int)slot_cfg->slot_bit_width < (int)slot_cfg->data_bit_width ? slot_cfg->data_bit_width : slot_cfg->slot_bit_width; uint32_t cnt; - uint32_t msk = slot_cfg->slot_mask; + uint32_t msk = slot_cfg->tdm.slot_mask; for (cnt = 0; msk; cnt++, msk >>= 1); /* Get the maximum slot number */ cnt = 32 - __builtin_clz(msk); /* There should be at least 2 slots in total even for mono mode */ cnt = cnt < 2 ? 2 : cnt; - uint32_t total_slot = slot_cfg->total_slot > cnt ? slot_cfg->total_slot : cnt; + uint32_t total_slot = slot_cfg->tdm.total_slot > cnt ? slot_cfg->tdm.total_slot : cnt; i2s_ll_rx_reset(hal->dev); i2s_ll_rx_set_slave_mod(hal->dev, is_slave); //RX Slave i2s_ll_rx_set_sample_bit(hal->dev, slot_bit_width, slot_cfg->data_bit_width); i2s_ll_rx_enable_mono_mode(hal->dev, slot_cfg->slot_mode == I2S_SLOT_MODE_MONO); - i2s_ll_rx_enable_msb_shift(hal->dev, slot_cfg->bit_shift); - if (slot_cfg->ws_width == I2S_TDM_AUTO_WS_WIDTH) { + i2s_ll_rx_enable_msb_shift(hal->dev, slot_cfg->tdm.bit_shift); + if (slot_cfg->tdm.ws_width == I2S_TDM_AUTO_WS_WIDTH) { i2s_ll_rx_set_ws_width(hal->dev, (total_slot * slot_bit_width) / 2); } else { - i2s_ll_rx_set_ws_width(hal->dev, slot_cfg->ws_width); + i2s_ll_rx_set_ws_width(hal->dev, slot_cfg->tdm.ws_width); } - i2s_ll_rx_set_ws_idle_pol(hal->dev, slot_cfg->ws_pol); + i2s_ll_rx_set_ws_idle_pol(hal->dev, slot_cfg->tdm.ws_pol); i2s_ll_rx_set_chan_num(hal->dev, total_slot); /* In mono mode, there only should be one slot enabled, other inactive slots will transmit same data as enabled slot */ i2s_ll_rx_set_active_chan_mask(hal->dev, (slot_cfg->slot_mode == I2S_SLOT_MODE_MONO) ? - I2S_TDM_SLOT0 : (uint32_t)slot_cfg->slot_mask); + I2S_TDM_SLOT0 : (uint32_t)slot_cfg->tdm.slot_mask); i2s_ll_rx_set_half_sample_bit(hal->dev, total_slot * slot_bit_width / 2); - i2s_ll_rx_set_bit_order(hal->dev, slot_cfg->bit_order_lsb); - i2s_ll_rx_enable_left_align(hal->dev, slot_cfg->left_align); - i2s_ll_rx_enable_big_endian(hal->dev, slot_cfg->big_endian); + i2s_ll_rx_set_bit_order(hal->dev, slot_cfg->tdm.bit_order_lsb); + i2s_ll_rx_enable_left_align(hal->dev, slot_cfg->tdm.left_align); + i2s_ll_rx_enable_big_endian(hal->dev, slot_cfg->tdm.big_endian); } void i2s_hal_tdm_enable_tx_channel(i2s_hal_context_t *hal) diff --git a/components/hal/include/hal/i2s_hal.h b/components/hal/include/hal/i2s_hal.h index 0de6904552..54a424b17b 100644 --- a/components/hal/include/hal/i2s_hal.h +++ b/components/hal/include/hal/i2s_hal.h @@ -17,23 +17,12 @@ #include "soc/soc_caps.h" #include "hal/i2s_types.h" -#include "hal/i2s_types_priv.h" #include "hal/i2s_ll.h" #ifdef __cplusplus extern "C" { #endif -/** - * @brief General clock configuration information - * @note It is a general purpose struct, not supposed to be used directly by user - */ -typedef struct { - uint32_t sample_rate_hz; /*!< I2S sample rate */ - i2s_clock_src_t clk_src; /*!< Choose clock source */ - i2s_mclk_multiple_t mclk_multiple; /*!< The multiple of mclk to the sample rate */ -} i2s_clk_config_t; - /** * @brief General slot configuration information * @note It is a general purpose struct, not supposed to be used directly by user @@ -43,7 +32,58 @@ typedef struct { i2s_data_bit_width_t data_bit_width; /*!< I2S sample data bit width (valid data bits per sample) */ i2s_slot_bit_width_t slot_bit_width; /*!< I2S slot bit width (total bits per slot) */ i2s_slot_mode_t slot_mode; /*!< Set mono or stereo mode with I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO */ -} i2s_slot_config_t; + union { + /* STD configurations */ + struct { + uint32_t ws_width; /*!< WS signal width (i.e. the number of bclk ticks that ws signal is high) */ + bool ws_pol; /*!< WS signal polarity, set true to enable high lever first */ + bool bit_shift; /*!< Set to enbale bit shift in Philip mode */ + #if SOC_I2S_HW_VERSION_1 // For esp32/esp32-s2 + bool msb_right; /*!< Set to place right channel data at the MSB in the FIFO */ + #else + bool left_align; /*!< Set to enable left alignment */ + bool big_endian; /*!< Set to enable big endian */ + bool bit_order_lsb; /*!< Set to enable lsb first */ + #endif + } std; + + #if SOC_I2S_SUPPORTS_TDM + /* TDM configurations */ + struct { + uint32_t ws_width; /*!< WS signal width ((i.e. the number of bclk ticks that ws signal is high)) */ + bool ws_pol; /*!< WS signal polarity, set true to enable high lever first */ + bool bit_shift; /*!< Set true to enable bit shift in Philip mode */ + + bool left_align; /*!< Set true to enable left alignment */ + bool big_endian; /*!< Set true to enable big endian */ + bool bit_order_lsb; /*!< Set true to enable lsb first */ + + bool skip_mask; /*!< Set true to enable skip mask. If it is enabled, only the data of the enabled channels will be sent, otherwise all data stored in DMA TX buffer will be sent */ + i2s_tdm_slot_mask_t slot_mask; /*!< Slot mask. Activating slots by setting 1 to corresponding bits. When the activated slots is not consecutive, those data in unactivated slots will be ignored */ + uint32_t total_slot; /*!< I2S total number of slots. If it is smaller than the biggest activated channel number, it will be set to this number automatically. */ + } tdm; + #endif + + #if SOC_I2S_SUPPORTS_PDM_TX + /* PDM TX configurations */ + struct { + uint32_t sd_prescale; /*!< Sigma-delta filter prescale */ + i2s_pdm_sig_scale_t sd_scale; /*!< Sigma-delta filter scaling value */ + i2s_pdm_sig_scale_t hp_scale; /*!< High pass filter scaling value */ + i2s_pdm_sig_scale_t lp_scale; /*!< Low pass filter scaling value */ + i2s_pdm_sig_scale_t sinc_scale; /*!< Sinc filter scaling value */ + #if SOC_I2S_HW_VERSION_2 + bool sd_en; /*!< Sigma-delta filter enable */ + bool hp_en; /*!< High pass filter enable */ + float hp_cut_off_freq_hz; /*!< High pass filter cut-off frequency, range 23.3Hz ~ 185Hz, see cut-off frequency sheet above */ + uint32_t sd_dither; /*!< Sigma-delta filter dither */ + uint32_t sd_dither2; /*!< Sigma-delta filter dither2 */ + #endif // SOC_I2S_HW_VERSION_2 + } pdm_tx; + #endif + }; + +} i2s_hal_slot_config_t; /** * @brief I2S clock configuration @@ -54,7 +94,7 @@ typedef struct { uint32_t bclk; /*!< I2S bit clock */ uint16_t mclk_div; /*!< I2S master clock division */ uint16_t bclk_div; /*!< I2S bit clock division*/ -} i2s_clock_info_t; +} i2s_hal_clock_info_t; /** * Context that should be maintained by both the driver and the HAL @@ -78,7 +118,7 @@ void i2s_hal_init(i2s_hal_context_t *hal, int port_id); * @param clk_info clock information * @param clk_src clock source */ -void i2s_hal_set_tx_clock(i2s_hal_context_t *hal, const i2s_clock_info_t *clk_info, i2s_clock_src_t clk_src); +void i2s_hal_set_tx_clock(i2s_hal_context_t *hal, const i2s_hal_clock_info_t *clk_info, i2s_clock_src_t clk_src); /** * @brief Set rx channel clock @@ -87,7 +127,7 @@ void i2s_hal_set_tx_clock(i2s_hal_context_t *hal, const i2s_clock_info_t *clk_in * @param clk_info clock information * @param clk_src clock source */ -void i2s_hal_set_rx_clock(i2s_hal_context_t *hal, const i2s_clock_info_t *clk_info, i2s_clock_src_t clk_src); +void i2s_hal_set_rx_clock(i2s_hal_context_t *hal, const i2s_hal_clock_info_t *clk_info, i2s_clock_src_t clk_src); /*------------------------------------------------------------------------- @@ -100,7 +140,7 @@ void i2s_hal_set_rx_clock(i2s_hal_context_t *hal, const i2s_clock_info_t *clk_in * @param is_slave If is slave role * @param slot_config General slot configuration pointer, but will specified to i2s standard mode */ -void i2s_hal_std_set_tx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_slot_config_t *slot_config); +void i2s_hal_std_set_tx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_hal_slot_config_t *slot_config); /** * @brief Set rx slot to standard mode @@ -109,7 +149,7 @@ void i2s_hal_std_set_tx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_sl * @param is_slave If is slave role * @param slot_config General slot configuration pointer, but will specified to i2s standard mode */ -void i2s_hal_std_set_rx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_slot_config_t *slot_config); +void i2s_hal_std_set_rx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_hal_slot_config_t *slot_config); /** * @brief Enable tx channel as standard mode @@ -138,7 +178,7 @@ void i2s_hal_std_enable_rx_channel(i2s_hal_context_t *hal); * @param is_slave If is slave role * @param slot_config General slot configuration pointer, but will specified to i2s pdm tx mode */ -void i2s_hal_pdm_set_tx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_slot_config_t *slot_config); +void i2s_hal_pdm_set_tx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_hal_slot_config_t *slot_config); /** * @brief Enable tx channel as pdm mode @@ -156,7 +196,7 @@ void i2s_hal_pdm_enable_tx_channel(i2s_hal_context_t *hal); * @param is_slave If is slave role * @param slot_config General slot configuration pointer, but will specified to i2s pdm rx mode */ -void i2s_hal_pdm_set_rx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_slot_config_t *slot_config); +void i2s_hal_pdm_set_rx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_hal_slot_config_t *slot_config); /** * @brief Enable rx channel as pdm mode @@ -178,7 +218,7 @@ void i2s_hal_pdm_enable_rx_channel(i2s_hal_context_t *hal); * @param is_slave If is slave role * @param slot_config General slot configuration pointer, but will specified to i2s tdm mode */ -void i2s_hal_tdm_set_tx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_slot_config_t *slot_config); +void i2s_hal_tdm_set_tx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_hal_slot_config_t *slot_config); /** * @brief Set rx slot to tdm mode @@ -187,7 +227,7 @@ void i2s_hal_tdm_set_tx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_sl * @param is_slave If is slave role * @param slot_config General slot configuration pointer, but will specified to i2s tdm mode */ -void i2s_hal_tdm_set_rx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_slot_config_t *slot_config); +void i2s_hal_tdm_set_rx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_hal_slot_config_t *slot_config); /** * @brief Enable tx channel as tdm mode @@ -261,7 +301,7 @@ void i2s_hal_tdm_enable_rx_channel(i2s_hal_context_t *hal); #define i2s_hal_rx_reset_fifo(hal) i2s_ll_rx_reset_fifo((hal)->dev) -#if !SOC_GDMA_SUPPORTED +#if !SOC_I2S_SUPPORTS_GDMA /** * @brief Enable I2S TX DMA * diff --git a/components/hal/include/hal/i2s_types.h b/components/hal/include/hal/i2s_types.h index dcf0ab4d0b..5f60a408b2 100644 --- a/components/hal/include/hal/i2s_types.h +++ b/components/hal/include/hal/i2s_types.h @@ -10,6 +10,7 @@ #include #include #include +#include "esp_bit_defs.h" #include "soc/soc_caps.h" #ifdef __cplusplus @@ -17,149 +18,113 @@ extern "C" { #endif /** - * @brief I2S bit width per sample. - * + * @brief I2S controller port number, the max port number is (I2S_NUM_MAX -1). */ typedef enum { - I2S_BITS_PER_SAMPLE_8BIT = 8, /*!< data bit-width: 8 */ - I2S_BITS_PER_SAMPLE_16BIT = 16, /*!< data bit-width: 16 */ - I2S_BITS_PER_SAMPLE_24BIT = 24, /*!< data bit-width: 24 */ - I2S_BITS_PER_SAMPLE_32BIT = 32, /*!< data bit-width: 32 */ -} i2s_bits_per_sample_t; + I2S_NUM_0 = 0, /*!< I2S controller port 0 */ +#if SOC_I2S_NUM > 1 + I2S_NUM_1 = 1, /*!< I2S controller port 1 */ +#endif + I2S_NUM_MAX, /*!< I2S controller port max */ + I2S_NUM_AUTO, /*!< Select whichever port is available */ +} i2s_port_t; /** - * @brief I2S bit width per chan. - * + * @brief I2S controller communication mode */ typedef enum { - I2S_BITS_PER_CHAN_DEFAULT = (0), /*!< channel bit-width equals to data bit-width */ - I2S_BITS_PER_CHAN_8BIT = (8), /*!< channel bit-width: 8 */ - I2S_BITS_PER_CHAN_16BIT = (16), /*!< channel bit-width: 16 */ - I2S_BITS_PER_CHAN_24BIT = (24), /*!< channel bit-width: 24 */ - I2S_BITS_PER_CHAN_32BIT = (32), /*!< channel bit-width: 32 */ -} i2s_bits_per_chan_t; - -/** - * @brief I2S channel. - * - */ -typedef enum { - I2S_CHANNEL_MONO = 1, /*!< I2S channel (mono), one channel activated. In this mode, you only need to send one channel data but the fifo will copy same data for the other unactivated channels automatically, then both channels will transmit same data. */ - I2S_CHANNEL_STEREO = 2, /*!< I2S channel (stereo), two (or more) channels activated. In this mode, these channels will transmit different data. */ + I2S_COMM_MODE_STD, /*!< I2S controller using standard communication mode, support philip/MSB/PCM format */ +#if SOC_I2S_SUPPORTS_PDM + I2S_COMM_MODE_PDM, /*!< I2S controller using PDM communication mode, support PDM output or input */ +#endif #if SOC_I2S_SUPPORTS_TDM - // Bit map of activated chan. - // There are 16 channels in TDM mode. - // For TX module, only the activated channel send the audio data, the unactivated channel send a constant(configurable) or will be skiped if 'skip_msk' is set. - // For RX module, only receive the audio data in activated channels, the data in unactivated channels will be ignored. - // the bit map of activated channel can not exceed the maximum enabled channel number (i.e. 0x10000 << total_chan_num). - // e.g: active_chan_mask = (I2S_TDM_ACTIVE_CH0 | I2S_TDM_ACTIVE_CH3), here the active_chan_number is 2 and total_chan_num is not supposed to be smaller than 4. - I2S_TDM_ACTIVE_CH0 = (0x1 << 16), /*!< I2S channel 0 activated */ - I2S_TDM_ACTIVE_CH1 = (0x1 << 17), /*!< I2S channel 1 activated */ - I2S_TDM_ACTIVE_CH2 = (0x1 << 18), /*!< I2S channel 2 activated */ - I2S_TDM_ACTIVE_CH3 = (0x1 << 19), /*!< I2S channel 3 activated */ - I2S_TDM_ACTIVE_CH4 = (0x1 << 20), /*!< I2S channel 4 activated */ - I2S_TDM_ACTIVE_CH5 = (0x1 << 21), /*!< I2S channel 5 activated */ - I2S_TDM_ACTIVE_CH6 = (0x1 << 22), /*!< I2S channel 6 activated */ - I2S_TDM_ACTIVE_CH7 = (0x1 << 23), /*!< I2S channel 7 activated */ - I2S_TDM_ACTIVE_CH8 = (0x1 << 24), /*!< I2S channel 8 activated */ - I2S_TDM_ACTIVE_CH9 = (0x1 << 25), /*!< I2S channel 9 activated */ - I2S_TDM_ACTIVE_CH10 = (0x1 << 26), /*!< I2S channel 10 activated */ - I2S_TDM_ACTIVE_CH11 = (0x1 << 27), /*!< I2S channel 11 activated */ - I2S_TDM_ACTIVE_CH12 = (0x1 << 28), /*!< I2S channel 12 activated */ - I2S_TDM_ACTIVE_CH13 = (0x1 << 29), /*!< I2S channel 13 activated */ - I2S_TDM_ACTIVE_CH14 = (0x1 << 30), /*!< I2S channel 14 activated */ - I2S_TDM_ACTIVE_CH15 = (0x1 << 31), /*!< I2S channel 15 activated */ + I2S_COMM_MODE_TDM, /*!< I2S controller using TDM communication mode, support up to 16 slots per frame */ #endif -} i2s_channel_t; + I2S_COMM_MODE_NONE, /*!< Unspecific I2S controller mode */ +} i2s_comm_mode_t; /** - * @brief I2S communication standard format + * @brief I2S channel slot mode + */ +typedef enum { + I2S_SLOT_MODE_MONO = 1, /*!< I2S channel slot format mono, transmit same data in all slots for tx mode, only receive the data in the first slots for rx mode. */ + I2S_SLOT_MODE_STEREO = 2, /*!< I2S channel slot format stereo, transmit different data in different slots for tx mode, receive the data in all slots for rx mode. */ +} i2s_slot_mode_t; + +/** + * @brief I2S slot select in standard mode + */ +typedef enum { + I2S_STD_SLOT_ONLY_LEFT = 0x01, /*!< I2S only transmits or receives left slot */ + I2S_STD_SLOT_ONLY_RIGHT = 0x02, /*!< I2S only transmits or receives right slot */ + I2S_STD_SLOT_LEFT_RIGHT = 0x03, /*!< I2S only transmits or receives both left and right slot */ +} i2s_std_slot_sel_t; + +/** + * @brief I2S channel direction + */ +typedef enum { + I2S_DIR_RX = BIT(0), /*!< I2S channel direction RX */ + I2S_DIR_TX = BIT(1), /*!< I2S channel direction TX */ +} i2s_dir_t; + +/** + * @brief I2S controller role + */ +typedef enum { + I2S_ROLE_MASTER, /*!< I2S controller master role, bclk and ws signal will be set to output */ + I2S_ROLE_SLAVE /*!< I2S controller slave role, bclk and ws signal will be set to input */ +} i2s_role_t; + +/** + * @brief Available data bit width in one slot + */ +typedef enum { + I2S_DATA_BIT_WIDTH_8BIT = 8, /*!< I2S channel data bit-width: 8 */ + I2S_DATA_BIT_WIDTH_16BIT = 16, /*!< I2S channel data bit-width: 16 */ + I2S_DATA_BIT_WIDTH_24BIT = 24, /*!< I2S channel data bit-width: 24 */ + I2S_DATA_BIT_WIDTH_32BIT = 32, /*!< I2S channel data bit-width: 32 */ +} i2s_data_bit_width_t; + +/** + * @brief Total slot bit width in one slot * */ typedef enum { - I2S_COMM_FORMAT_STAND_I2S = 0X01, /*!< I2S communication I2S Philips standard, data launch at second BCK*/ - I2S_COMM_FORMAT_STAND_MSB = 0X02, /*!< I2S communication MSB alignment standard, data launch at first BCK*/ - I2S_COMM_FORMAT_STAND_PCM_SHORT = 0x04, /*!< PCM Short standard, also known as DSP mode. The period of synchronization signal (WS) is 1 bck cycle.*/ - I2S_COMM_FORMAT_STAND_PCM_LONG = 0x0C, /*!< PCM Long standard. The period of synchronization signal (WS) is channel_bit*bck cycles.*/ - I2S_COMM_FORMAT_STAND_MAX, /*!< standard max*/ - - //old definition will be removed in the future. - I2S_COMM_FORMAT_I2S __attribute__((deprecated)) = 0x01, /*!< I2S communication format I2S, correspond to `I2S_COMM_FORMAT_STAND_I2S`*/ - I2S_COMM_FORMAT_I2S_MSB __attribute__((deprecated)) = 0x01, /*!< I2S format MSB, (I2S_COMM_FORMAT_I2S |I2S_COMM_FORMAT_I2S_MSB) correspond to `I2S_COMM_FORMAT_STAND_I2S`*/ - I2S_COMM_FORMAT_I2S_LSB __attribute__((deprecated)) = 0x02, /*!< I2S format LSB, (I2S_COMM_FORMAT_I2S |I2S_COMM_FORMAT_I2S_LSB) correspond to `I2S_COMM_FORMAT_STAND_MSB`*/ - I2S_COMM_FORMAT_PCM __attribute__((deprecated)) = 0x04, /*!< I2S communication format PCM, correspond to `I2S_COMM_FORMAT_STAND_PCM_SHORT`*/ - I2S_COMM_FORMAT_PCM_SHORT __attribute__((deprecated)) = 0x04, /*!< PCM Short, (I2S_COMM_FORMAT_PCM | I2S_COMM_FORMAT_PCM_SHORT) correspond to `I2S_COMM_FORMAT_STAND_PCM_SHORT`*/ - I2S_COMM_FORMAT_PCM_LONG __attribute__((deprecated)) = 0x08, /*!< PCM Long, (I2S_COMM_FORMAT_PCM | I2S_COMM_FORMAT_PCM_LONG) correspond to `I2S_COMM_FORMAT_STAND_PCM_LONG`*/ -} i2s_comm_format_t; - -/** - * @brief I2S channel format type - */ -typedef enum { - I2S_CHANNEL_FMT_RIGHT_LEFT, /*!< Separated left and right channel */ - I2S_CHANNEL_FMT_ALL_RIGHT, /*!< Load right channel data in both two channels */ - I2S_CHANNEL_FMT_ALL_LEFT, /*!< Load left channel data in both two channels */ - I2S_CHANNEL_FMT_ONLY_RIGHT, /*!< Only load data in right channel (mono mode) */ - I2S_CHANNEL_FMT_ONLY_LEFT, /*!< Only load data in left channel (mono mode) */ -#if SOC_I2S_SUPPORTS_TDM - // Multiple channels are available with TDM feature - I2S_CHANNEL_FMT_MULTIPLE, /*!< More than two channels are used */ -#endif -} i2s_channel_fmt_t; - -/** - * @brief I2S Mode - */ -typedef enum { - I2S_MODE_MASTER = (0x1 << 0), /*!< Master mode*/ - I2S_MODE_SLAVE = (0x1 << 1), /*!< Slave mode*/ - I2S_MODE_TX = (0x1 << 2), /*!< TX mode*/ - I2S_MODE_RX = (0x1 << 3), /*!< RX mode*/ -#if SOC_I2S_SUPPORTS_DAC - //built-in DAC functions are only supported on I2S0 for ESP32 chip. - I2S_MODE_DAC_BUILT_IN = (0x1 << 4), /*!< Output I2S data to built-in DAC, no matter the data format is 16bit or 32 bit, the DAC module will only take the 8bits from MSB*/ -#endif // SOC_I2S_SUPPORTS_DAC -#if SOC_I2S_SUPPORTS_ADC - I2S_MODE_ADC_BUILT_IN = (0x1 << 5), /*!< Input I2S data from built-in ADC, each data can be 12-bit width at most*/ -#endif // SOC_I2S_SUPPORTS_ADC - // PDM functions are only supported on I2S0 (all chips). - I2S_MODE_PDM = (0x1 << 6), /*!< I2S PDM mode*/ -} i2s_mode_t; - -/** - * @brief I2S source clock - */ -typedef enum { - I2S_CLK_D2CLK = 0, /*!< Clock from PLL_D2_CLK(160M)*/ -#if SOC_I2S_SUPPORTS_APLL - I2S_CLK_APLL, /*!< Clock from APLL*/ -#endif -} i2s_clock_src_t; + I2S_SLOT_BIT_WIDTH_AUTO = (0), /*!< I2S channel slot bit-width equals to data bit-width */ + I2S_SLOT_BIT_WIDTH_8BIT = (8), /*!< I2S channel slot bit-width: 8 */ + I2S_SLOT_BIT_WIDTH_16BIT = (16), /*!< I2S channel slot bit-width: 16 */ + I2S_SLOT_BIT_WIDTH_24BIT = (24), /*!< I2S channel slot bit-width: 24 */ + I2S_SLOT_BIT_WIDTH_32BIT = (32), /*!< I2S channel slot bit-width: 32 */ +} i2s_slot_bit_width_t; /** * @brief The multiple of mclk to sample rate */ typedef enum { - I2S_MCLK_MULTIPLE_DEFAULT = 0, /*!< Default value. mclk = sample_rate * 256 */ I2S_MCLK_MULTIPLE_128 = 128, /*!< mclk = sample_rate * 128 */ I2S_MCLK_MULTIPLE_256 = 256, /*!< mclk = sample_rate * 256 */ I2S_MCLK_MULTIPLE_384 = 384, /*!< mclk = sample_rate * 384 */ } i2s_mclk_multiple_t; -#if SOC_I2S_SUPPORTS_DAC +typedef enum { + I2S_CLK_160M_PLL = 0, /*!< I2S controller clock source PLL_D2_CLK(160M)*/ +#if SOC_I2S_SUPPORTS_APLL + I2S_CLK_APLL, /*!< I2S controller clock source APLL*/ +#endif +} i2s_clock_src_t; + /** - * @brief I2S DAC mode for i2s_set_dac_mode. - * - * @note Built-in DAC functions are only supported on I2S0 for current ESP32 chip. + * @brief I2S event queue types */ typedef enum { - I2S_DAC_CHANNEL_DISABLE = 0, /*!< Disable I2S built-in DAC signals*/ - I2S_DAC_CHANNEL_RIGHT_EN = 1, /*!< Enable I2S built-in DAC right channel, maps to DAC channel 1 on GPIO25*/ - I2S_DAC_CHANNEL_LEFT_EN = 2, /*!< Enable I2S built-in DAC left channel, maps to DAC channel 2 on GPIO26*/ - I2S_DAC_CHANNEL_BOTH_EN = 0x3, /*!< Enable both of the I2S built-in DAC channels.*/ - I2S_DAC_CHANNEL_MAX = 0x4, /*!< I2S built-in DAC mode max index*/ -} i2s_dac_mode_t; -#endif //SOC_I2S_SUPPORTS_DAC + I2S_EVENT_DMA_ERROR, + I2S_EVENT_TX_DONE, /*!< I2S DMA finish sent 1 buffer*/ + I2S_EVENT_RX_DONE, /*!< I2S DMA finish received 1 buffer*/ + I2S_EVENT_TX_Q_OVF, /*!< I2S DMA sent queue overflow*/ + I2S_EVENT_RX_Q_OVF, /*!< I2S DMA receive queue overflow*/ + I2S_EVENT_MAX, /*!< I2S event max index*/ +} i2s_event_type_t; #if SOC_I2S_SUPPORTS_PCM /** @@ -167,33 +132,75 @@ typedef enum { * */ typedef enum { - I2S_PCM_DISABLE = 0, /*!< Disable A/U law decopress or compress*/ + I2S_PCM_DISABLE = 0, /*!< Disable A/U law decompress or compress*/ I2S_PCM_A_DECOMPRESS, /*!< A-law decompress*/ I2S_PCM_A_COMPRESS, /*!< A-law compress*/ I2S_PCM_U_DECOMPRESS, /*!< U-law decompress*/ I2S_PCM_U_COMPRESS, /*!< U-law compress*/ } i2s_pcm_compress_t; -#endif +#endif // SOC_I2S_SUPPORTS_PCM #if SOC_I2S_SUPPORTS_PDM_RX /** - * @brief I2S PDM RX downsample mode + * @brief I2S PDM RX down-sampling mode */ typedef enum { I2S_PDM_DSR_8S = 0, /*!< downsampling number is 8 for PDM RX mode*/ I2S_PDM_DSR_16S, /*!< downsampling number is 16 for PDM RX mode*/ I2S_PDM_DSR_MAX, } i2s_pdm_dsr_t; -#endif +#endif // SOC_I2S_SUPPORTS_PDM_RX #if SOC_I2S_SUPPORTS_PDM_TX +/** + * @brief pdm tx singnal scaling mode + */ typedef enum { - I2S_PDM_SIG_SCALING_DIV_2 = 0, /*!< I2S TX PDM sigmadelta signal scaling: /2 */ - I2S_PDM_SIG_SCALING_MUL_1 = 1, /*!< I2S TX PDM sigmadelta signal scaling: x1 */ - I2S_PDM_SIG_SCALING_MUL_2 = 2, /*!< I2S TX PDM sigmadelta signal scaling: x2 */ - I2S_PDM_SIG_SCALING_MUL_4 = 3, /*!< I2S TX PDM sigmadelta signal scaling: x4 */ + I2S_PDM_SIG_SCALING_DIV_2 = 0, /*!< I2S TX PDM signal scaling: /2 */ + I2S_PDM_SIG_SCALING_MUL_1 = 1, /*!< I2S TX PDM signal scaling: x1 */ + I2S_PDM_SIG_SCALING_MUL_2 = 2, /*!< I2S TX PDM signal scaling: x2 */ + I2S_PDM_SIG_SCALING_MUL_4 = 3, /*!< I2S TX PDM signal scaling: x4 */ } i2s_pdm_sig_scale_t; -#endif +#endif // SOC_I2S_SUPPORTS_PDM_TX + +#if SOC_I2S_SUPPORTS_TDM +/** + * @brief tdm slot number + * @note There are 16 slots in TDM mode. + * For TX module, only the active slot send the audio data, the inactive slot send a constant or will be skipped if 'skip_msk' is set. + * For RX module, only receive the audio data in active slots, the data in inactive slots will be ignored. + * the bit map of active slot can not exceed (0x1<EL9_ejQrvfRbv-bBct;2a=py_l%m9Pz2y8{RU;!+BZJ)h zl+3iu)D(ycBLgENT?1oXLxT_l6IEkJLsL~_M^ghma|^>Li2B6z)I6whrg{ddMg|%Y zhK8!fPO3%*KACx?6{vdrXEkf^b%s!@K_)a@k}bl*stUqAgYr|t3M~WtJW|37K+25_ z@)C2QhN!xlt2#P^kdc9*s*!=JtEH-=p{kQ9NTIQ-d00hMikYvGTY!mST3(=kuzQ87 zkyDjRl3$5?Zc2zxk*}qDxW9{!mtT5;yN_vPZc2oqWk!XwcVK!@dU;AtQGkDtUsXw@ zOIcZpWlD;3sJn$nA;^f}9LGvkBe&eL3SW;@N9Qd6sC1_?r+g>N5MLKnBc}|nppqaL zH^Y#Ebhn}m{~$xJkaANW(~OXuK$DbI1G7};FoOcmAQMA3Bkv%uGLwL!#DYLqKc_%9 zbGM|NfXvK@l$898>{3@R(_&Mn@Pah+Z2!E_l+a+qlwgqYhDK4UAWu~l7CDDkMCO|p zmwOdfm%2N-TX7MRoY2~S|#g*w!sb$HgDVYVTMo!_Cj;2Wwrg?$x;fDTh6=vq4C3z8rsU@a{7J*rg zNo7Wv$rff2AvyVeDHeV%mSv{q5l)U4;YnpKhOQx&SF(^nf@yc~AHVX3&H}ET}O7tsC3a*ND@hdGaH!Dvos|<9?i}H=Kh;lQ|HS{hE z@=eT5OEvKdkMJ@I2>0_Yv8)WuuL{laEDEToC=5$eHF8RGDOWXeGEYtMC@r%v%S{YP zOe%`1$VgT-0{O?>FwLYq&pFd5Gc+;ZJu=(TJUJpTJIlk^CEd3mDI?v?Fr_jsGGoUog)8E4)%C$J%wAi?`)F~pfYQPs#TILJB8J1@)A#V07W*rzno z&mt-!D={OgEGwYczq}+VG^aSvt=QSXA~z|~wcIzzvm!9vz$-8-)XOm|v^3o_-5?;} zHQyuO)6px`C$u8DJlxYAwaCafDa=SptuU)f zEf0=x42m*xa?3PLi43+(EiQL0aLlVTOLqz{_by3H4@)-nPPcIKOf2^b%ye{1%TYCQ z%Fl6(sPss52{um;4)Y0j^sOxR2{tkE@l`c)bF$1z331OgOb(7T2ugD=aCZ&x^ED|m zck-xm$@L5MN(~693@Ix#%g!t-k8%mmPsvU3R5fz4a5WD%3eE}7$P6p=E(!|tPcHHf zOs)uYF)pplPd9Q?HF7d^^D<6}H1ISpOi9m!*LC@HQq_i-#NHL)l# z&Q7mNt}L?%3k=BgGAIr6$t!dZa|{hB%BU>O2~F}SC@ao)POSDo8Q0OmfX}&M!}N%?ZtR zO^+~5^LDpPE%o%u2~P74RW));^EJrK1}Ei$%)9_6!?OG+qi`=16W5H;pzw^ag2+NM zRU@~8f+XWGGq+U3BFl=f%)GQ*ORu8Dq)NZC;G8hCO82~?>uP}>|2<(nU25@A-H6scTPOZY+>k`Q&^fGks4ZP>|GdyfmggH~ zUY3y;W}fH~mRS}NP~u!3mJu1~n^zU+6<+C?7;0SP;#B166lRv2lIu~BuWIBLl$Gh` z=N?t)6qsV_;#gr(5Ksh4clo(lSy6eJUhd&Wj?NWHK2A}Vszz=`hNW&9E~YtIrLM^# z=AL<#L0%^276yJ9piGeKW?B|n80O&-5maK5lVq4_l9dr)>XKYh8I~0iRTY$)ne9}Z z?N{vK}5&Y4jz6;63xegOr}S*c;AA?20 zW(ID>szz>(c?QWvP9_nSA*tb(szy!$NkM6$MR{(Xg@!IpRgMvcrGYMKQC_7PhC!BI zpfV>bz{x*6GdDD)(9+Y~pxCg~$34Qp+#|p;$|%*$$1KOyxx5Ngtta}2Cc7Ku=T;he zRhXOmIws}hyJoqUJ3Dz9B$`Axn^<~fMijahS)`kVB!*-rf*M(F1-`ki=EVVdm2NIs zRVFDuq1oA9RgqQYAz`8ZhK0e|UM7WMu5M1Ar3RrvzKN;jmIbAbg^AgLDaK|_M!s2Y z$)N?A`PpfqroqV(-sJ(Qrg^GHPMJ>mxp|&G$!0-*szz?*WrqIwsi9ffNuCD9=6+QL zi7xKGDW<+Tnc3#v1^GeYt{JLEZh>BbUgeP%CI!V#u2}(YQOTK^TU2fy9G(rVk+ZXVVv1jYHz+}6r8}DXS0xu4W}5pMmZhh9m>7J{1Nr4^24#vWy+j=4c;si2s2 z@~$+?G7K~I39$?}%1`tRD9*|+39|Gv12xAJ%aYBVLDnV*dskWH8Wk9pI;JFoa%FH@ zP`XQam`{p%RI$HhVMVz|W=dIAMVUdGcdn|DQ&LG{YF;JCh=8=blnjuL#FWy?@{B|S zXLC!JiZJJrutb-T@XBKUfbt+y<5VN(vcjCoeAghe;ws3#WAEJ?#*2G zDI!O&AD#b1!ScDvq{Rv=7Bnni@^TXhabV<}RD90z`5X~OM$st?7BC4->1kL15~_bb z?f<-diL~FMUA1a{^`|E%g%cGSg%lbUgnzu*e7-4% zako07kOJdpPM?`ZNB_9pRN|b_pvr0Eo|x*n|AK~4fea(Z>cGWrmU(w%3^*q^yb#K` zysS4MqIF%prIFAF6^F#5GZYwwHn1>qX?yQzbeq7yIm4sj&?%Q0IbAF{4h@G+vH30P zRC&O{BogNL!RWXL(>W!F#HTv-#alpnB}Vm<6IKUT3!a^AK7B{w<5M3V9=`g#U*3M2 zYq!|R@AvEVpP!#UeTrtV*U>J~rDbn#3F$_egiG%(dpoJ}^Rtr+o!g(hy1IIjL88;i zxz^ijzFc&lWSs7|mhtM4((pPs4) zE^;aQ_9jww3!l85PKI*wv7U!~zn-0)9kkR-G*sVjj)hU-BbWUSpG3m!|NU5;a&}f| zT+K(<%fFg6=2(@kTH-f1YU|5>J0Ig|yffVz4xKWYlGDMG>Ja=*DjO`J>9&(AA*bHi|^ar(Jn=H0cwx0&SL z3RxAtUM`U>>*OTWReS6H{_0`Hhkg?chKI=t*ygsQ~aza>e_S#N2ckr z!fHMN-rvOZ39%zAo7{45Z<`vmHS47H`#s9@Yd&?Z-dX?uZ@83M zjz%*ZZ_wX&cXx-UZqo``p|C^jv{30Qmn|Y69v$sA%DZE6b5m+}*5{?u<0gseMtO9J zXim|s|NnRUDYw6$&)a``aFF@r9Lvo@b6vYcCeF1k*9y#-BBbhd;y@$w{K&i=>F4EU z8l`q+J>L0zUhqr@j)3HoDlTdfNtVw#1eHUs>3dF63EE#*YZ@n(Ewo_6re*ONqMSdv z8Cs|AKd~uRNP%%aM?l2S7VQO7ZKpF;mG$XdTRy*T)wJ`9!L6HWeilg@rF881_v`hi zgY5De3m@$JueFF##=b7b?#~D3nI@T&o}8TQp1Lkl6eYv!= zIQ{DJHeTr^{`2iFZA$fC8Mby-*xU~-qQ}@iiYdGCsFr;A{^R50sSQmR4&HyUJmFwd z(E2#rPD$fsQok=P^?tf~{l1__>3@HHZR)w#BWWCROgC;%g+J$NVRb)`W;Wg@Td&6j zC)a&?(s^co6`W6#%X(OR2D;%3@ZZW8h=ets_W>V`7{OuRD}GqG~5m@jKtpO3orL)5sQ9%y9t`k;_KRVUKO(T)42 zwakacqUYyiD}TS;KJ|ch?5-`h^4VtJna;FJKCaPlZNx?=!yZ}dZCQ_heSMv^Q?*5z z?{~unDXWqdLZv@HKMya}i`lVYTF9g4N4v$h=P_8`Fyhi?x1R4@uENNr?Y?Vnvl`=T z!37&O&GYB!J|r9#v5)QGh3)zAQwu-p2!!6=mOJ_F?d_+pt&L`#sgaVfVa{0rt$EiI zb|&^pnO-?4TKf80X>E^=NQ*Sz(E{Yt_ zyBl6#T--iIJN(=(#wQ7 z|Fr)8{vQ6jvxIBf_R{zFVs+m;FFP7-xXI<7o%6HPC*DXb;%r(Hu+VAUtB9g@)uR1> zK6QIXw1%tOB(hH2R`k?MHD{0LjfT_-0s#@nrki92mCD!}h3-1U_50X{E&MWfy*H)4-Vu9a=3sZ^NM?x0JOC3VYuQHa8r8eqw@T)A5K!%eB`S z_-%PRb7ND$>1n#RgC(`ORyVZQPqA9Ep-adv&WC9mr~tQ~elbCa!eoU8BG|BuzRExCWYAu zF#o!L8|As%b03&E>!h1}i+DJp(+}K7tXphWA}zba*M1=UwPcyQ#m!`gU%02 zzhj3F3R>(~lytP~)d8+O3O_zQJ)ISKcbV_(CFSq$W$m1ke$Z(D#l`NcbHx0veAd|^ zC%Ha<-%mH$4-JR4jZ#i5@Vk2W)1h8z^Ht1x1raPqx)s-e!@26mhlN?vNqkMb?cNFT zk}L|FA}yL^llUL4j@X#=ip61%LFM&zu~~NnYAWW7$IZL5t2BFSilO&39e+-3nKO;f zS`$hSJIZ{2e?R>A_Qw+CZ|-`{u`q0%x>8Vf$1#mHOvh*0PHYh62#AP0$i1bJ#iL<4 zQ1?(voH`H@qe^fk2s3Z9%Z=z`2+>U$6rT_j^N?Mn#v1(!V{>CM) zx2CVyf2Pq=BW@>d_SA%xN=HQ0E?Zn+KFy-|uE2t|uerU}Vw&ttv+q5kw+>kEC=gOQ zA~H?n(G&YO8=E+s6OWxbWbR?HEHL8c<@_zPSd_dQ4ry(AQX$JZpX^1l49MF-i+8*s!T_a)uJ8MI%G&RN*~m z3@0^g<_L(eJbhnAmop&3kZn{iwys8gz}X_zs2RMh<<th zG_c6HKG^wu-emWFInON_7iCQI_@;q`Jr3+=(OC26^z^lp89)X^^f0teJu2f=4AQ0G z!VwVB+M#U8BcuT8o7ggmgjLOn=!R$nH8}TuOv;7G%@%IhQ1#(Kb zQgL7kQ*ua5Rn5O322r$Mc)^BG)=6bxxjq$##HSwHi!XqbK8Rrw2|M@I*4+=J?H@?W ze^<_Ih)qQ-3Txio-L1Yc>FB08xh5SD(S0l$Yu>!JjsojY5#VGJ37gn(%p2tJ1{Nh1 zheT0Dr7*C&g*a511j5SS-I-`n_^9R51`CLD8Wn^WY~b3&e8U#x^9c?KoBuwX+`*K$igh|66Y4s|txovreKA5>c`IA!Ju4p@kN;1F&&bSm)OvjjBpKcJK@ zA97O-YzsJ)CophMXjlwN)~D{u=zzpq^cokt_n&%ju=(lo`E`>nFZcI;bfiw}hd>BR2(vU2{>4nb$5^m97z_kN%E<<(VhAyqGtT^lTnAa1?P84xkE zZwl`uuw5*(4uHy3r&g{>I*~@1_x9|3a$=(My7>Ki-qUm@wsMPmU0&v!`shff-e!e0 z-`?HTzP#MO{4b9_@4bDsyLlvyT#BBZ(cJ(4-)@&~G2IK!iS?l9a$qu3bx2GNK7KI= zY-i(tjyrp+!#Aa$*V7DIGNJVKHP0p%&UsG8X=fxd@9x^F6S2V|>*}hdcFh}{+On^& zi#?w($25Cd&8L&|Sxe^OIhMss>i+&JdT@ZT z@?ooZ%%QB?+j7@szq`L*KYDv!=xK)e_5Uhw?krw@E4fviYx563hSM71>*I6_A07Gl zH!02$u!yjK5nb}U9oo#;AMgCCM|9^i!T@8=l zX*I(jv1v`jMyG%Oe&>5mQt><@yV-3Ai^duW1r-M-KV^r+rzZWydsG~lwkbIzif-IJ zp|U9;YHQZiQ)ZRg7JHO3FD?1>`Mmw={=IX#Dt>-St^9aYoKBUK9j<4((%p<(pX1%7rQK0n8B;dgOaA)fW3p!0ni)|>Kc3I8 z_gWLN@e5DF+H_DMs^QVVG6&R^&6Imy;n~2FwfI(t9O=RSghwu_;4>e@T5 z$(m~VySzyD87)t+Qgn6zH`|HtFDc`?@RZF0)iA&#`-FyCPO~hoDH9if8PMx~9FjplZndx17#Dfrnj@jPR^-exM-me<9C8OzN z{N-i7S2_MFuDOuD%x7juy+GoP*Nsh{?>42LR`Hu-@$gdXj6*3qik_ajv?6fvg32c0 zbt@KLe<~iy_)KrjsVSPup#EfPOX!C8j9=>C-?LrIE*bcF)8F-dIe%`}KapYNY!L%B zZa=BJJ2OpFXz;ljoxgW!PUf{WGkIhz0)$k(RK)e;LT)Z$yj=7+(9*>B}-t3;kX2@aQtIP_7>#A*8cJlpe% zQir%c^4L4|IPY1^Vx27druu+*qUb%_go7Ivd4g))2U8hZMVXsfJQRXh4pkrOdRi5+ zEqp_QJ)iqR z*2l%Zy0UWdR*?&}L76-of|vUlmAnX;x^`E=!zP>me?CvLsVti6>AZ|_xs21Bhnl;8 z2OR(nww;=y`Sji0-J6P@dZl&;ZfFr?%KP->FvTuE38on;()j{W0F42_p^K2*C*Vmn#Wx86%s>EaK#*B+fmH+>K zzq(&=@rka5OFSpLr6v{1FZG}QPt(G!hxN6b!7+>4UnK{+5STpGWWc?S44C)oeC!nZ3alR8gE%ne7i`0vwceeH$yKR>0aew(c3s|6a2UKzZ6RZc{|ob8pvY#l3mB#phc z<=lMo;9&Fl0B-+?pTFfCdZd$&yyvhKcQ_Lv>nHM76_K99FYAeP*Wd)64$$q19^*ZrarS`C;51?y%s` z&*$^Ak~%w;xQxQ?*Zt02(kiO9yzud{(Av76Pp5x+*e>t&?99xkH#Q~*E%6XE-PtQ^ zz3tWM&mX#eety0>N75)nz(s?ZjVEBHT907z(IDrJb(>O8b4_zzl<-pdjl5~rlr4F8 zqYN1HFDz*M#nUbqvN}xn&V#NTwN^oC38uCUhk}AroD^4letKFRG{XLV|Nnn04{HnT z?nu<>Zk^FDZ@;gLaZ4hH;h)~uVQZsQpPrgJ*{1T-iWx_1TiY2bIyV-cRi9s@RKf5t z@{n-YzkTd?j(4;xp7`gKu&e*#^=bu!c|3Xgd(JnXp1*f;LnMpFnlnl#%RCMwvK*>9 z)Rn`l)~7K;Vc++A)#oS7G|Qc3l6NPfQ$lC`XPZ4t*B={mEO>f)`s&mmjkX;ZEk!Tf zHqzMAeo~)rOT>eS7Rvx!Qr) zh^wo^{Zn-|%7}Q!D9*X#&zf_8-`*YxL#Hlr{dLoREL5;=eUsY6!Wptmc>ZF!P4N{! z8Y0}MiToDcc;&;bt=X40r~7YRa<#)czGdqE_l(~SAKg3P%yHw5om>3-#ucs&w(FkN z=JDHK^b+dmU}z0>Y54(a$DC(T=rQn=u`F65Bsq`ubTb>j+?sDuvK9poBokYownVVC zZpyr@cKza;imw0PZs)sOC4c>Xzkc;!ISo+fV%7sG$<;@@#aHJv1@4jEp69cuonL<4 zxAvvJv%@$K6hA+=GPO>kf1~-a;xjj_n|bCKt~@i_e0`LcMBu{~Z6&9N_3KXSZ(=$V z8=;t{FmGb%AtT!qP3_QCPptA}y`%T0&gcX zYOA=wOl_M92bftP9-eEc7rQGYHMbP%TTnfaT(V^n%N*y1L#HhFJ@fEXNMKnNvQlY= zjpFLh*W>F~s@A(5d?=4>j0Z`Jx`Xd$U0=8Mn_Hsh{Eu?VJ{=qFxy_{5`6S*Z z-j7@vv^3@rm;Z;2F*=JDY4a#$9bY;B^{2~gpP#%K9PzN2qioM^UP+ylsXgB#N?%-X zR5&&9>Y+xBd92?5d%}eu9Aw%wC*m6WL%u{-#U@URTL+#WTRD9nhj#sa=6A_QnpytH z6`Vhn)N{hdIpXC#X20IpzS%4u2kJn*>*vN%K1|aT1nvo6`}+F&Y3cku3;i}9E>iPh z`FJT_C%tLLp(9+s-3&e+ddPe4UUI9aii>1l_I!iHCMn~2{~nu|#!qKTdMR(@YO$3+ ziFb0;V-dUf7E!(@9ut*Xtvnber@mQzXp)}Ky1*XWunoe(ULrcYM;Ms}X3p@ClGMKI znVO>hXBvkPx5UEPoEgN*Eu^pVBHx}mCm7^{9o{qxM6?l%H{s^r^VO*4W0Wb zUFLG%Wu^LGFV&|qx=LI8VEHaIZIM&J!v-E5+t!TFVSC z&j`(1w>TkE#O(cJ7vncK53mUPe>^-pL`vV?RhGl*&1VNkF^0+ZHGPk|H#pU%Eb94d zc*1F}eSKV~i^vVOgDrm}Ziu%nZCX+N_!#fkpd^{1hp(3yDV^)_Ddu>=WpMu99!~8m znz6gKM6GL2;?VBkNiqHCz*zX{R`z;L#@46x7EQGm7C5f5`xgH2iI2!0m+D7HI$zyC z(WkVztLZm;dw9fKxdQpciT2YzfJ?6fGW^lIr=B=Af2+IeYmWn!EE;R(JTLB>!Q!L1 z!1&?u;4GQYzP~;_Ba(lJi-|}2Vc{*QdDol;5;H~PY;tnG@aG4; z{3kh0OewkLjpVn69s0gsLL(&AH!ZAvY#Z~g_Mt|u&!mm!Jgn+R5+}uMOmh8NAFn>u zYL0KAhIFS$V zkV2z}-~-`n9*LiSD*5fGar<_KwdeARkKL!PRx~uSs|e1mk(_Gh^fc<;^M#K*`wqVZ zg@PQTj6JxmUT{d%^!tlXiy6A5((}WEBVHP({&~4M$yaED(dR37>|kpF7`e2ytJ}9t zWZ<-z*Ral@z-EO3!;4Rs*Senr&1im!+^EJm!68Fn!3Hi~`yvq)fdZzQLsAk?=6rDP z-JCaPQt=fFycO(7uWN>;h}BZu@-Lk+{Y5%|NZ^#y}Rt~pUagT z+fG^V&Ixw!l~Rq}T^9QO@u7_$=56d2FMce_rE^|r!G@#|WdArYDLOIe3;RvenOW6X zxToUd74NAZi=JASzdLcbo&W0pk8=8AwoJQ(!?+A==RLf-tMv6W75{lLoLYNKet&v; zT5DSV{e5eb#Pu)x&9NxFV$F3>Orl=#MF`(X#LSS#fm1BIN?s}{yZ24`{r&y!Gd-f( z)2cdkHZkh_Vkv2znrHiW-rUH|`Sm9d!f1Lx|UHg}_)uW7kLa(d~s&mU)4DyEeX-cI48&U$N1QGh!-3>(o$N=iQ(YNPh##U%Ty+vNezd0@NA6UUspTRw%RN?oLTp=KeN#42@Sj)KU^cWN^HHx z=DfU9CBd$-FxPA5{T0qpPu}ykTiiO5`07snu0vki=dJtMlO7wiFy3F?&v`zRy9d)b zg$L$|S2y{2rVBjL@O)6ua_n5RzTYn<)8CxhYK#8tJ$T!5dc(WF%cPh86A0@`kIiq( zv%PD<8_Ogk$!P&9XgB{kd-2!AhRgdLECs(N8*F^Z!8xOL|4Xh79K65dS?x3~sEXeD zTJreHn;+b{t7K$3Bc?O7PA#o!&e0HhUaU1Pv8F%HX^FpQU8K!{7W)+v*1{SLW4mPrJJ7 z`|NcaF0EZ|9d~TA-pUK>mP;>R=-aqhnejPjh`DdQWstpa!7cF>V7GlOZfJ}6yzBey zyg5M;tq~0oDHgj5vjmGX**GUSh;Rl(xC$!ht1~u3LN4_U`{ah3-)FC5xGZZdFY;m% z*W0RHg;`~PTFpZHKtm6px$k`oQ_YkY{ASJCoYUo)rU){&25hQZ(KjII4j z+s{{AgT&92Lt0xNH!LpZW8~6){$rN%S7XMz`T_Q{6K_AW6x_P@byL!gcYl{zCz?h# z7|v@J5}Woq#N6*}pZ)2^1&%5Y1V95eg(mGU>p?;NZ~KvXwgpOA{`*-^XWjkn8y@lU z+GSb&$C1-RGOl0ly?kNWfr}Fxia{eZ$FIw*oX=_Tmir3WZNDrXoYz#|{q1Y+r@6*S z$3e$P=B~xoj-4i;u5uTP#+pSO6Q)mYa6FJ1zhF+stE2x;?+o(%drWs}zq``xE!x8J`seX%s`q|?kLQERI%Ei1n7u|07+_t|~- zOIT;z((@cN(joXpqZI{lBt$*{qyrf0sxv zPdh$;rNa#g&It`>j9l8eA!|IC9tvOh%fu_%ClXdQ?@!)C@lQ$XY9^`2D^~vbv9Ts% zZOn|zOs1QOyPqbk^(K=YwGs@)LLV< z?sw$7`}@_Go(}yIJ%{C>@2b1{sOn=JvNVQK&EdW|y79GFxDG(nRk zhmLi7Jcwj^==f_&vln-85|OqKCKH=Vmu8Rr`pq>2IY4?*$M?X(8iR99ZU)i?hyW(ztk;=O>YsYkJf#ZJTKeN}@ld&cE|!EPcfCV8YuuwxvCDEXrIS9qCoq z-~Ve@$$NXRpyi(H&z3&lW}o6QpYPN4cXKCccm`Fjzr}uOo40-VnzuJLdA9Mt(W)-b zo&J20>tv?ZF0XdEX4UwEN~`)SH>;n%kyx8@tV#6J>SW`e<^SV6rzuUXxwme2$okm$ zW4!NI|C3mneP8gCSEtdZxS38ywfBr9@9bWDq)XO&+M0XIjLIU^cK_ME{^_Hm#gmLu zrB;S4Ubp4d1@A@2I~LC3@Q-lR=#{@2zwh@i?wtky)-3UzANa~NOHsb=(w(dI7iBb; zxVF#Rl=wC)a(~&>oPV#^sQ66zA(@zZ4VpU37&d?w9Ij;1SmSf_E{o_qx4I z-fQc3`)P5_$8WMu^)Gwn7g1`=xa(_4?-$c~w%;RMMbvMbgByZaq^Oi&Pzp4 zKdDMyTff<+q99&Z`>LjTzx>3mrCg_OzYm*i^>x;X*5dS#HHy`@k`H89R=tR?Tp z`T5%JOG`q0{NIfoVRbS4!-JN3EDX!*wRA+UHNL_&9%huzKGqYt>JymaZ>-Z9X-olH05A&d(*;v)w*j z{*=G;{e{j++Yfke%Kn}9^6JW+yYzc<@+uCkir;>1Q^h?W(a){j`?U72{~!9RJYRV) zTkq8G_Bksi?3txMSH*Xp)4iJAlcs1zJAM+^c_fs}W^A*<;C0=l-eB4KjeMLF8oq)C zl<&K5xuC}Kfz@h@r{UCvMl4s)&NiR=)pL@{#M9IDZ>OkKrOo==a`k%Wig{BHt{0uR z;gImJD%1OuvcuP{@JwG5v2p27b<-!uzGiKdoI^jmN%vi=Cf(zf30drr#9R?q^&s(f=P#PE9yp_UUZX%}s^hJv)Wf*Zq=d zU%zLT{@yJa_nkX+IacSrwVPb&ecfwfl4{7@&FOxpUbh;Z-m<=Kg84li{lmY@Lw|Gh z+J+tPlbKSq{>hZKv$wpD&uhMF8ooYeQuwE(!8bLxWKTI*Yjx_6WpK)Ed+{q4hlRp+ zq<1~{RPK!~nGz;jy?b4IZuI{M{ncjgg6*3#yk=_k)_i^}pJ?PHyZN2^U5l$l6510P zI3wmUv`&2*>%#oji6MT0_;#O(@Av)odv~|`*OXNm7Z>eR)0_ABpwPh+(-LB`zjW@m z{jTO>()Z!b-f31ZrI~-Tik>{!|LN+acva_RYqD}I-Y_j% z@u%AK$y_hfCsQY-sst`ldDtf{e2{Bume+KY6Aqqj%ls2IM^ugKD@?vQ|kGZ(;Ab`$L->oS$a13tKGUlzog@Ri&-XY z4_fY}*(qq-R`c=fdH>p&eJOU8hUs#W#<`8&5pQiOTp!ubcevVomUXl0w1>j`CU{+a z-J-ds!1j^M(|+FUDYo&tk&CBoluAANy?aUNWB!z*`PENa#fw`t*C@=JaPar1+wn_o ztj^!D?*G5pm6!JYJiaOQzoq9Km6<|esrT23V{6CMboKp3gGU4j# zaPK)5g>$+Z9`i9WiG(RWaN#>B#qxpm*7CTztxxjb+}P+iyySG7$|B3!Ut7YR zYem)H^|E}9>TsP?^gNsMbXvUnqJ7__*ZjKIa&_uy@ui7#%b#95JKHGvV3Fr^yUW4P z*8WaidP}=?sSm%r?Ue1>VZq+48}FZr{*SapLXr5q)}kebL|zTbF%XH>bx{cn^t&PylQRy%d>|j z85WyK+9zKOo`1b={Su)-<7ev&I9LBwf4^(m70E+frz5qmuaI80VbRW3>SvTHV z<5(KGEp7Uq8QSYt+s~PHW5G4+O$9&QG=BtbG-$m#>+0#JoBOp^ubKAyy@XEuk$p#} zzW(m9?aj_98@gUxWl6i|4{E<13(;oK3DeBG1DdoD<Bb;&tZ*F~S=XrZSvQOS}$+T}T=WO~O zxb?pa?Ezqn+hx7fA0_^_671dKntkPiNLXx?`INWO<|h|Dl~xISwB)?R&(Hn$ zz1P|NoF8?~G%=+<(x!gfnwwP<4xMsOTsoW6AiCkF)cJXmt2-XCxNmX}5Y-C0BP!gs z<3OC+d7Ty84@h3xK3V5S(yE+W#a@q&^)6qP&@cMU*D>c|u?$<|`Hd+8tm>iDG-d?e zDwkE5Zb9b2{H`y)HSKfl-C4O$u_Xj-Wg z^5yDsspCh)+W8c^8**Hi$2qI|-uhDX>k8+~%Rh@xPTs%4s!w+LzK19Ouz$4+_MR1R zCT5q&S3&k=tap2+Lb@JS@sDrDM!Y=2*=KOP=%Sso+KQ$1=J|IfbS`FJk$kcKZdE|` ze`S_)yO(l#oixh#Ui?gUO2(myFQ00KOuW~8{Pf4g?N^@Xhpy4`jV_<~`}@1o9gVT6 z=hwZ}YHnG&^4LSshq|msI2)7OzD&E>T^D5d_r*o!(u&sI8^l#|n( z>u&v+KI;zOySt8Nf4_Cd>@A9%r0TDkzwht7s(#ULTkq^H5C4=}71y~rEq7O7gzE#% zyB1p~ZMf7a+#%etT7KVL{paWAOnNS?GUbqKd|=_EudQ=#eeBi|@5?N&?+=}Qt~OS3 zm27nV^oPv5PRyHoJLK33kB!%t1g}q=Wb2-HwY_hHRqd-CH9@PJtaLXdZZ3Nj8+orq z)aBd?N86{r^PjK$t>Al$C+PKI|D}c9etHX6{FYn&`T6-3)yv;lPhIN#z46tI@_c^9 zKehIjZ>t@xKkNxvvZ0I1HZEI~NhB=nBg@+jwv5Yb8`-LrvVJ!_WLV^K;LUH}@P?OC zva9&HN{*ke`Y(8)H+b{o^L>9b*SvXQdh3m6!=WxiMpnb=tmuD}$jW+jlp5E~9gvOdLksFtlg4$iz&9|IM10}puoh!~VnH)J| z`n&G3Xu>Xup9>ryy;E?ghtM$8dlBOlQ#o2gGwyTyNy-|B`F%7w{<0j@eXcV zDJ%Fm>&YCXkqS)%ooj2sBNbwY7o_sFP8CxN+hhS+YGB>*>}ESCqHEnmBD^gHd3Ex4 ze_vL;|0S39-Kt%8B+ltc1&VlR7B%7Aa+&x8N0B4edtTBaiiL zRu1LTwyx?ms|F1|`b=o>1dXQnzS4VfHXwraE^D9Jfmh$9Tc<8QeA%=DGHxOJGC1Pq z#q2FJ!HYoZlotGEeYN}@^Sw1U{UZzoQxzHGIeM~#wGO>XJD%Ah`)@rHXguM?^~;^X zT-x)vBz~1Q8M~e6nQHv!OdwlB!{wGxh6$Uvg*uEF?{a2uV2PN*o^g>a@6HZIUMZ6a zpn3cz7EYb4rKM+*{scxus!L^hhHwN#xVFlzS7ih(h~!}x+91amo47Rke3kN+Wv;Qi zN+t>_yLs#`dz*4$f#WrkNnw#)4AYsSPRW|6fi~(WarRB0*r3k1oKxE_@u_VBI}>PF zGIgH$#I;@%m0IuYF85D@j#*wiWwS@|woq&6iCxzMnHO&;nzGw6qF$(A)`mweSLR4)?QOc7!vrlReLTLjp={6f%+H%a3%Nv9 z5`-AJv?n`kk`z*4ye(94K1{MX;hI)b`6oxw*3ct?hos;m%FzNKYlOq1Tb4fVO_{@H z#&TzKsN4B7QLb;8xwN@fcPwr(edEw@=oDYvqTX!^4@?qMxtCw?I4*o)?uMWSSKE*Y zYrUrF%mnqpA06#hpROMt_J4ov?`<|UKLYe(cOBUqmY9(Cr}I{SyF`;fx+3Fl&H3KdM2KmYwi92-`}g6 zjXEk1dKp?pA1jG)w6tuPWnJ9F^WtLIxB0u4*L-?$QF*3uX^+kf>)3PitQ1#XPMt8T zRO*Df@2yqpnL0}P&%IQ?N^hT%mb>ew*zrZ{(>%79%|H2Xa=B_%kA$Oq`{fqV`5V}5 zpJX(!fy=r}4KI^LjlK%bIJ`PI!qSGpDdmTv;u^j`oBhjjZfb0`%UW{BD67DKreR^r zmX~+JKZ(~xZu`42?ikNoUD;jyll*7T{J!PQ>PX?#@8@!jQr`I7Ze?zr`ctoX)`mw* zPX3Wd>OQEvK>I*b`oh0e&)##?&NuwGLnOdHD&q1f7AL2Ooy>J#J}eYDJ2mK)S%%u% zUEj)UudE8pwXFLxp=Nv4>db#HF6~-qQ}<`ap;IP{_L-(E@40$)b$IHnEt!`VIgo%Xxx_D?-n3{mlp;NV*3N7b4liO7bFQrV<2ow_k z?YP(aME`yLX{FYEE9U3k-s9-T_e$^oo7;=0@jW{;IsR6utb%Lz^edmPw}+lSG3|bR z@zu3o6P+XXl`I6ex{h?d{`FJ*^6`@!>S9wKzngq%qigNfl(ilkg^aR4W$Y~ZxaZaO z_ZvJxgJ9Q9Pw$IXn0%aXnlk(UsV$vC-aoxemnNS-xUTH{96QD4>e7I}_xBXWUP?c+ zXxdjvN$a_c6=`d}y}PIA{JU(D{r3E685b9Of4uJHxxG#~^tM~%hod1gZPGSu+Wo-$ z=#ujnI6wJy?lCI56jQl9D>wA*@BC*cdpwn&ym;6wWL+ks8S_Q-<*o9TlrwYAUOi{d zopyRkq4U!(oyn8*oYOMzENTXg*rbX+_mP&?bN*n^rMM>S&o=j6+yDFg`&Hbo;y*Jg zYRh}Yt65hsA56%S&6ixAeSO`@1C7k7S5^dONxqtEUGDSNct-C>&TNC1oAYCtdV*tv zo?TxYaUtCc5d%esPD$saY}A^rt)&0#k3Y+uoweR^+7lc*8>@PwPE1x;ia$F?<9?m3 zd)@8QH=2%O(>~|L>{t7mHD$6-ljmb}reSIDDZmNt?)~E2Gg`a+}JN+s|Q*~v~ z@?iV_e=g73lzKToXkAU}%PZL{K+U3CW-GPb`(>uYoBh|`m~?d7{Asn?x>Eb}d+pzA zT(w`JuHGj*@!i{59v8#CPIYv~uPS?ewZ=R4_S*Lzs(V0ftuJq{c`ZBp*U@W=)^gGO zcZXhGIhp(^Z)MY`OQ+X+?Ow%F?a*)C0*`u*v*wb4d34&gg% zUN+VIKh2kVz3aWW=k8_lUbFT7KDm1R^r>t2>n9)FYklHIX1w=3rq-orPTxG7`ohkF zWA(hbv%D`RsXlq^rmLE~Y>iRj6^6*IMV)JI76pKYfsP(pp8Z5Q(VQy zE49R|Wb*_DPL{p~&^*eSn)xp_neR{kz4gS8#Tz!oU%8Z&&myC^rtQmHmCtFulR#rc zIyZ|}=v=K%R_SO0DAZY|Vt`sP`UcW^7D( zb?5!nuj1$CPo2bSeCkW(>8TGI6QXukwdUL_4|{a9KJKdFkrQWFwL|AhJ&m6@V`I|E zKTBW7m?>~ydHA{N)9t>+UOFOYCpx{VzveY-``dS`n#(Swo=`a%yyViRyRi|9i_P-S zr9^K3+aZ*taiVLg-Xz~P{~u1A7xHqYPw$Ga4>5D;7W2J2)2eO-&-?pVRo5tdJ2&5U z?WO>?xu&b9pH7z#op%5GylE*XgI9fA>OJ4{m{0VBO~QYd`^K_Rtv)sQIP=!=@URV2+QTCba&J*w#o`nf zk@(0y`&5RcdGf+3m9JxuzW(>OI_T$FrJ~o*cvt@R4Au;MrF(Mj_61f_*QP(xToYop z?56vs#OsBsO3%*DTQlw4+PifToV*;XCm-*#*?Ru-m9N-OMIGna82g5 zU8_(1l6ZP&W^mA^05wVb|Jw9 z+wA-9`1x6j?r2+1O?YXTu;ohK`XwqpQ;w)g1%AB$xBBVbORTYnxP(7zCbOS5=YFQq z`1!*@=J0C!yc^mxH}BJ^G&&YseP7Bf`~B5B9TL0ZQ*>DG6h7EwGhbohFAh81FHS=h8y zj%aAen-jz`HJKM?HQ=P=>3w^5tGM;d@aL6&toc8VSJJk0->DBz zPfYda6kDvI{5|U57rn%-1@B5gL#kh-?ILw~TW%aQI{NGVeqDjEm6w-6x7oP6|HISe+;HE>X{GW@xGU$xtuCIBOz>$B>!sp3M9oSlc zsu%Gy%?ev|=9vdi`?n`nR%2nXO{?g-gZGx$m*-6LEZ#Rc{PXhZQ}@4}cqVf5?v|?; z53@gMk1yXf>v-JS>2W^Gj=0VJA0>+|5hKnvnCKUd(y`HLThd{ zZzz-Za+|3eR|Wd%w!Sg1xnw;3SpR$nUHc;u8_x(lHsb2rx&DV+-SiDv5zk{QKRwxa zX2$+Qq3JIlt-oUA#BFM7m)Z)3*Y zU0eIAo1)yyjg~~~uV_wuuHwMtsC?kQ;I9`ayAF9ln;Jn8ju{HkrvHDJf=0K`f3UCo z)A46-e*cu(<&$0;r}QagvGvSQ3cde7;&i%zbY$EKMd#z^imuw1B?B^K#IQr;n&>ok}%KeYBC#mJOE&ryV*j@bX zi|5G+nyVc;67L7KdYP)ao%w&>K+(Ew&Fu$<##?gA#lw`@N+zpzKVQWxf9H0~gEKRp zvTp4We3WtfS?{K_*N)-8E5aqdt(R;MuL=0c>p4+r>#zNR8`85L@0y?b^q1`<-DA7&&+UVY?O+F2U zQa0=_{^@bfYrXbz<{FJPYlM5ZsA#b``9<8_TkU?YN_D!3R#41a$4@#I|EiyFv%k_= zSCLroa=X?lE$wM~lQlTv)$`JmS4MB#Z|%*V z{YBCyF6-LgD_2EYuJ*0n@7;Jv-}`l6?URRx+b^xnRo+?kwQJ42E%BYRLQn6XJgqm& z^Y*&GPuFsVK0WvLcGmq%+jONFO0{!u~v;KYjnVHzB{*ZSY@x zjQxDtu06d+Z?9~)(cE^KBl&pe;%NbW()Yr}*4|ihvdotpe}ZS?jl z)oYwIlb06vZ{Xu(nGLOL{a<3#wN8E!iHG8MzS$h9mHeS%en{7pl~?~QnK{}0)I?|Y zD?w}DSQcqtOqip$Tv%`a-(QQjds0Eq?!qgUMwZF#->3H0&nu8!)nFwMcEUpO zwn^p}1p{O`pvCx`6oV~H+jy^&z_&lY@d9+l)wAd zk&my6m-PyFh^JhSDu1;)!vAN{$|-u`f$QRTYsKC&36a!FS^DZ)zS8`yZ*+QJ?OVp>3F?vG?M%xATM+ytp9kEaTEtp7Ped)c)pEzY^WCvd}`{GYq-dd-*>dMG&~O#WZS z@!Q-@e=qj$zkOvc&qvPH`)vF`*kBQDk<=0#eHu6?%)Vp{6N!%NqHQWAejC&QPsk_$d+qACGtdmc>#h29gn`zzN zUhvaxe*dcPZL#eOJ>PxuHue(^n`81*wdY301dbP68x&@ypU(Sf?Q}o4$6k;1O262( zEk=x7+WhYoxG(=${NMhHlFswLyPh_vc+I);_2a#})=R$aR#naY)$=N%*lq)>$_h$UMxYcwmY-a{&3s|al`Naq!1x9<}1sg80`(X8(5omdk zn2yQ=ZpJ-6Hj9$V=D1y%|Ird@NQP_mh5f>F44t^N(|^od%)q z+imYA&b~V@Z~vNfU8Wx9+WLS9(3-&4ppl7n`580Ma#;9A%(P83*ljzzmH+J5i48YD zF48_wa@ORw-QBv#^HD4%j}N^0v004OHXFRCX4+QJSmJH_E$7@=G}bJ7rgN9m<4V=T zs|%eDy!x0_`rApBZ;c(_U5g8A)4zUnJ8H+Zdc}puTf-C`5>rL}FYw(KE||3e6oTqv z+xD|ESuxzLFtqk7WnY;+Kd*XCxBfff$t{=Z-)4N6u< zw@v3n%!XbrvM@XF6& z(KYV%e4mf#@6ln`)b?qs&6U>EG~e?;q0`pZP8=o(tiD`ZQ9MAhRZEeZ~8}A zGH#4KzS+H=dQcm3ToZz~5V=pC^Jeapc&-*Uw4Os=~#r5*2H$8g#7 za?bCP->J6Qf){$3H$OffCGus>LUeB}*w8g=bBVe_;Oo}#b}q)%$Gfk-<(_J>;g?0p zV~6eYt{#^b{jITPkyHQms8-M_IU7go9DjyGS~s_DjXVDF$w}e;e{HJ1yl7fJH%;`e ze#Peb8(w|OzGiW=Z!hPIW8F6kS9$whx4Zi-;`}@ouz|LkFCu*tmmcrjy2iKR(5YMh z7M7YRF(gj?^UG?z*kkX@(T0zo-`!n4eM3uh$_Lih+;$Ov-P#1#bJ{W9t+=>0eH+8& zx8^@oG8^qVUmR<^`SJOA!=J0)&M-_qHP^aa#jQu;->as#lN#=G21NXnHMB0^YD~~& zz4G_bwXe-L-$rh{|MBs0@7LGXK7Dw&{nQ@!ez}t`E-p@eb!BDIqa&OrCnz@8{Cc?@ zw4KY*?ZO(+E}pCUM-05LaJ)FS^5)l)wb$NW&&Yp&Z|@}ic)Q5`b$h311Umh#xVb6y z()xJ&pRd>NR{`zk+E-I4X_7HP#e161^_~flQh4bGkOH?S2kHFdr^)+@cV@bNLNGYTbb{PKE#e}A7oJ-#l|H?R8J8%@wO z<+r!DXNz@(&1acqc7efUiM0N%!d18Dy}MA8`~K8a?N48?$9qrJ3RNk6b!Ai5RV~#e zpyPGqYd$o}*j9yDmAzT-5z9=B#-1<=5BOlN218VuN)8 z^|P<7d6n2|p4htd%n7O2I*i8A5w;Z{91IqI55EXbtnrUOrtgNFD8lU8a7Zg)$xZ(g z!l2aJT?$IAPxr6BtDX)zE9!7Nzjk5k(=fM#Mh8IWMtyvI{A&M%qpz;5o&DzC-e_MY zZV`}fo5HW7WY z)@n12)2I2(weoCc3rJf1OdK zb=jK53)^aqcIc;_nW6aOOs#(AB9~6k!C66TqfABhcNRSj+Sv6^@cIdr z@|Txfx8>eeyST_TSkfw`uUky_*O|TD@;|El71tHs_nU7QtNY#6OyK*Rbk5gxA5F!; zIePuy+biu_r_SBu8hu#FA@S%91;)wXV*PK6=>%c!^ULqeQ*6))dw8f-HUHiouMKy0 zm3m)V=DS)gac$Jrp!Qau83vAN=jZ9F`_HTKn$Rll_inNShs>Lmm2bCRzp_vA3#VcG zw+$hNese6cK6QC2{L%_tH3hU`ecz8q+?Ev|7R2l*aP-wO)O>q&_4JybPp5;nx~Z}l zCa#Ivx+?q7j)I3y(|>42Z(H-{+wJ^S`W(ln$5nayUbrJ0wPc~vBOs@_PrB(-9Zw0_$0mG6F(yfwb{dE4<*oAp1m?P%&(j62hD zGVScFl@=2N6nEA!Ba=R zyu7SEv2})1ZAZx)VP_ttGQ}MM?77Y@&OO)H#YP)EdvkO1>UMU42++trzs|kt_qM9v zK3rh_7ri;H_s#wN@kf&@B(>*Ob3J}>VPW&G_ZRe!_53K;e|T5FqdLATPv*t7&r9=n zUtPLk)9m9J>p?RqJ={VDouDek^G3{BmZBuVi5m_b;Xb`?!o-skmD^{fBpqUR4BC|9 znQGi3FmK&s&#FBYAGZ|j;MPuQR`Z>;MD3)T8wY!Of{}IkyBO6FgO|>~-#udUK2rDR zqxR(% z*xlS|sJ2l%d|k-=o#HXzP}JdjRVt*~aI zp^>thpt)x7vMGU!-8fmqPW}D;ed>>&Z#JL5a+vkacP42L*~JR`6ao}l1k43|clg)+ zd@3F;`-Zo-Lt+#jhOJNZ$Pqz7+xs!1Ku7OnEF$ zt`Uirw{C5{cmMd){Px+EIW-mA+SJ!rmA_k~Hmh4)Kg|DJ;0Bph0Sldq9v|b~dYmJ&Q(yGt{1Dt&L_hW90A%VxiwMbM$;MbU#0plm~SS3 zk)F4q>%}}Lx2pnSJHmsOczo=!E`29{SHi(I{_%n7+nm>emPS`znfZ9(hN5NnEwk(e zI7Abdb{~7AzNT?bLxphIjDUxlwti`cgEVwz7VA&fiw#O*Z{qg;I6?8yJk^wGCEdF> z9NMJiqho7+PC22rwxH@?FrrmvbqqL*WI9Vvtz{cjr=Jb9cy?Lxne5Zd-s66z^fAN~Qy-~I? z2jZ-caJGmV1zLn&)({BWA@|)YLQ;E9$&SRsY}ZY1+@Go&ZMOBxg}n(k<&q?3-uloI z>hfLWU9NLPV*bqShmA_`2NI}FT74*?toq^38?!e!sc{MG%M|yj20WY!Iw3Fj!|`V| z9m+bwS2W)p;(Ek-nsd3&%ui>Q&Tx5Tz^l^^TI-w8IVEsIIx7?BA+FK@ai>$Ymv|N1 zJdImK`5YYDI7>Io(OT1#bK=?A*`d=Iz1MH(5x8l5zNtrz>)T$I%`;^6cQN^tpV@co zxo?D`+{P3>Z=J#m9XAa-eMG*!bDXjN<1y*;Cj9cs+)rk1Y>GXxK+$c3`6-=5R_P6U zt{5k`+HI&8_}iwwMrqgb4<8hi5|>u*pCQYhc6|Q2+OSpb;FD{noq!)_B?oG?iwW)X zb6I?8_VXt^zr!Z1J#S%sFGc7Ux z-Wl!0zLC2wPorW+eJHckC<{zd*dkZut7ZK;345KtM4H$ zhrGVmUF_w&YjJh$^4sfWUk9Rfydb@(YYu)ochu7@V&5JWj}JNhqKEg-JH^K24MdV{M&z$8O4jF#>!Q;Ns`9ZS$%)&2Lo04w`FD=$esQ5m` zJn^aI;~n}6f0TB`mn1ow^Od}Q`6ctZl}K3GSDCkE;FGmrZI70-SA7)J#okRe_E9iQ z}~hsm-DKrt=Vs>`ng1wqXJZ z@2a<7kheRYBKbbRsg0Y}o9AP(PP7S^QT2w~e{I8V#3!dnmQ=bdod>V!q^E5-%f z{OwE+o0nFk9a*9nr!ep1qr^AGhZ;34^ki9ozgIB0AnszaX@x*?2lwL-VzP->x97)S z)jP&2*r_vT`39$Yfxj8jh21$4Zyf$StaI*s!FsU5JO&a{y2nc2iO>CU71WsaKW?`A z>cS11X1Qnhr+}7Pv`MX3WYh;|MKN$EKWY8yjR)l-HNIayt&s4+DL!S*8J!bViq`Cf z&vWljpIJNe;xzCO!1c1bb)~nHZL5V6WM2I4J>)fCG&>5ht>{4Jp;MsUBn>vwA0o0k zmj8+1>R>kA@J2xWNTQ@@U7p*)AP=4QhZjmz)Qe4%d^9&aOdnPv7a8uhh4lC(*nj<7 zu;Ehr(OK6(YmH*>Uoe^t?tO!c$VM*tH?~IKVq332e|Wh4>c^M+M0EBazT}{D_>iMW zL{Y11Ld2}pYn!Zf<{rAIB_rRzS8d+$GryDa6<*JR6m&glx0m16fA!N?t#)H`>DT^f zbL)R^PRu)WsxNNw*?FKf9m3!>9jjL~@;q}f(VF&H*4E;v&LXCVLMwznD{WF0vD;p? zhvl-}u_dKSF`z^knV#}2+9@&BE_j;+?0^L4DWGN-s3*UXeG z-0Pc@86G>_&ld^%wI<>+=)}1-ucf2Xj6ow=Y4(XvS&pPJ%BK{UK6W+tE4_VLcH7Oj zFTb6xx~2pgq+oBIie->Om~Hdz&5=JY#K?0(s*vkGo8Ml3JN@e#R|j*xGkx~iffqKn z9rEfI&W@bT&^mSNU+333E)9pYvd&$a+u*WRJWf`NWsRJE*mnJpM+aU#zR=5jw<=6N zKjh6~a6=1a!5*jf=J^|nk`jMMD=c8X013(o)Co$FFwmJk-&7!nKTif_58fs3SX8q1 zes~q2xIkJz?fT`X%WtoTj1ToN*X|F*Hiq@LWvZ~iY}T3yXRr2(-?g}!>tB8&ZTs@u z>;3iyFZVk+(>Q&J$3!KotC8wlENf)g10|-#>n+{zi95_pDuJm^IE+z_eYY~Bw}8a; zWg!RNa$FPNe)I1lTQQ*ztp_Hn``4_L%ZrU=Ty|R#KF$YPq8I{REI09Q`a7?8_v%mX z{waKt|7`pPsUvsU`&HjPw+_AgxAv3AxhsW-_T+tA=6xyQT%hIzyLE3~O^jasHzDj( z_Xe(K4L8g=EqWVnGPzHW-|*||R{fAyGtb_9^UbMs^WCpU1iG<|J7qrOJX!hbR6=D*ox)l$wJS)#{Y zZvN5EC#yAGFII>{M=V>Q;8yL+UaQv72T6rLRux}*ID4|utG_F_SNGkYGbM5Lxs!{| zZ}RFr|_q#uF zPwh9)M->-Sv!};=y0}Jp)9WL$CnuZromn|QGVflsPVaNM$|K!iT?fy&te==@bbME8m z@2ZJ&UIbaWGrf#gUHio2>-|sLIkWXoJpbJ9J+-NGsqf8@OGO6@Eern5d*Uk{u2w%I zkSn$0xzy$D*6U9ln411%{pE7ix-}U=YYUPj1C{q?-!WY-GwrDLx)U$H8+)vgIDc}% z)byvf=DG)&g)`0kl&I$UuZBm{s9=ANec5kK^E(pJ9*>UvS^w|O+38P@JpDaM!Ox`9 zwwg&Y#B}bS2}WfzF2>}2Vf(( z_k6p^GqvupPSMM2&M*JG)%=FZ5(&quD) z=SQVZ|Gr#qnt0H$z*@JZuyuyq0vG05L>&m3CBVr9P7+FnOB&)9S;yV2Vl=(yKet!L zGN_>8XosNkpDWC>RT=MdzTjHD&f8Cukzr!cN(ZHzb$_|Z^mW!lq3A68#(e^tvkhHnEGSY zW+p|`MQK%;(PmRug%{p&jNJHrmXOK&C!QJtJoWSTELQt$z5DqzpOZ-^&-98vy{zBo z`Oc*9$+y49KOO7lOnJNC{K<`_zbEOs=KS29FK5cfp~kWNhT*))=e?ItsXu==bkW1T ze>$K1{{J@jSH-o!#sw{Z#q;f^gm1Q8zixNw`;9`in_s6-n`l3O@WU z)8`|(M;G~=YcYDdo%>Y3wAHhKT89m(?>B~T)SaNXPKvog((apW)BoK~had;JMzlC= zP;03MY4&5HBvF9{nL_O?ds~M(-u#E z=RIv*^_BD!3$|#?4NA3{@Y7*tsQ%_F^`t0sC(HpKVN?0^W} z^3OUae5T4*JN*6e?1ocTQ17SPjk7-;`%r&nzkaWd!u9udWt^)IGk@}$_GIJK2bx#v z_pd5Wi>ULQYq0E3;g4y1jGp9Q760X8*dl7=aDrvwn&02srbvBUf9lp9+4zX6y85WL zKP6#ZX?^<9yPlNH%;YfO=(VqYQpVZ-#WU$-=fVG+=2KeMmYwX~-JcTr`i)j`+yBKn zIdei&69abX+pcYyGEvp|$jSDjlTJ;apAuMFCbM5xpZ7<;&v$jPX)`X)|E#rUg9xAG zs+5n(D|`}G%5W~pIoC4Dtnkc+m}N$3Q`Kaqq%93P(ZX+3wKlzD2VefuNei!D{(t=2 zEoRT#h1-8^U%p{gn8wDM%PO;1>*g z^vGNKcACmz^Cv%we0+M*vHzU+Pj8p=Y^?izWz)&m$y|1-Ys$W#(fxVpC~xtceKih= zPq}rksWNg4aa?n;jQAUMfwj)`WX`#??a!|t++4U{K*GLm&!5ld?LjB|@85FXtycZO z@1XY~4sZVd%y=f)DXu;1j#T&w?F=3D!<#nkFkF1{?Z^M|?A2>Oefj4d+nmE^r0#a? z)u|OtTDL!bzqxzT>g)BT?|P2!Tb!Y{vGo_fx~=Y-4J`cL9|JbLS+ilb#_Nq=w)osH z2t4)NS4BJO&ws-w!q?*_Jp0_=t+?cnm7h&%``w~*{Z@;WrgTI*u&MUozq2R^zJJXV>$8N~$Vs ztY2Mt^1o5@Jl3SN?Z`f5b&6%4m;IV=Zuj{5oatiR zemnXq+Rq#KbzCUgDdcrnzwcyEulV67rIjI$Q(v0=sV_`nRMj}EArh7rkRq)j;KFq9 zm(w%hYX>au=KP;^H!eZLWuN%5mz&?H`OHxG{r$Z-qP4Wk?^u@PHxb_-`pKo`PKnp| z$?FL2`TwHxR(b20i4(6j{b=HFHZ=13Vcv2jbbDuMO6%1x{l+Jkum7vAacBC!gJvm{ zC%Aq*6Y({&%&qEwL6q*@!$NkliJ^~LpQ}2a{(tXx%Nl;ZqyqgLt6O`zCvNQO*YMt*GhaD4gy7E;d?A^A<#rZV~OqWaVtZmWX)M(Md;w|dWe|9~Kv7gP6lkEw2 z)?eD}eqj3PxdEwXZCbZV?&sB5b7sK_GY^FhmLIJ$EN^f=fH5J$1Uk=^N?nh3Ri152stS z3RJHNQti=nXMYyT#8bVw?(g%qC7vR|_s+~bu=@Ym9g8*LL06*Q_s>9ZawBMlYuU&0 z^>KTz?EhK(+2X+d1n+YbyH{_`zJ6+!X|@v2|4U1~|I1g0Gu{ok*0TTT-Me>XyLRin zd$((cXfF4ZOVgB&mKI(=8Y@;_uKg}bBTD1L{GESJE>q2opEY~W^ptm&G73A5KA+u_ zvhU2^V#iw9gZQv(``yV`=<6%YD%%+0^AL?pVxKT(mZ= zo1)cR$gx?1By_@s@CHm>&nz4+xE>ql$CyBBq` zEL_r6&zab_nan17q%KYDQ}Ekt*M)WiU##m7>X ze|J9YzI|!X_IC>#Z#vGj&2rhZQi6T$Tzg-iDW`e_j~w$|Nm{uYa>LX-5oSH zF1mCpUB6yeExpl#ntxi-T07cwkeAzeGsk5fAzkX>-7HrSw4CF|pICui=Tawi1pTX{BtsvEgnN4`Ey~_VJUcfx`;f-FQydXu zj7yK4+7zTQJ2qT&!n-4jx@&hDGFh=$Bp=;(fa8V*lZ?jg9gK$s<3WL)e*eYoeEuuGl8Q4TUTg0ow|h+m!d^ z{601B{Jx9Z{ohX0kMCO>y*=sXrqpjM6|z$&a~N#gzrea^iLvS7(=N`R*}cCncZj?`pVmiiX8Y34F>UAh-77y8*Yox8)}Ff{KO^GrIrX2F8`nN>?VNh3r@2Sp z=v=|y_J*~OGheaKUHWyZY(@K*Q18>{Kezuqs(5>!V&~MQAGd$`ob>Xi@6qESl|FCt zSJ@o<6}+u$8{@jz-P1a!9xGFr@rwW3mHC~b!rIZ_(``3$6~{~OKgnUhG|R2w{F#hf zHfh}IxA$#&ZXE46@4zdLHSzo7LRez9=gqx({TZud;{|~S#$j)yzcny~vuTW%d9)&n1M?UJcD+{TLO$V_ZMie-YIp5WnIWybK$K-hMCMT;opwu(4`B|)7aniyX||1UCNq_t% ztclALSwbC0{dKw}*3Kryu)y$HQS?I+2=Js~~S#wP8|NHxU z>DlALhD<#TnH*E}VxuP9k}yn~VRqqMweiMHvCQXfJ_y~NZhzp1Tjqlp)t~uYTcRuY zyZiRK&G$NKu+sAuhj!Kbui+^rJ5`ST_Sb1(*{I}Rq36w;l9Z~MQW@uVzzdWug)V66 z9{v`}Sz#SFt>f#7iONfb%Bs`Du4BaXBQSa7nGJBJ=o0t)=_r$<;HCc z`>Mb9bxxI(T-~65|KYBOoY&@lK0dqu{zOerlP{}g@Wh^0yL$fDkGJMK@+x{{!5-S@pZ9HFMr1`dfvtU=xg87NekY;YOnb9PI}dop7y1(#z|ja znoDf_scFYn=e|0r({Q7wluO?i_LAuPT2DK=`Ib&fcrtDIj_+0imcd63teN&Q&?Y!% z@{5>)eGiHgTT#2 z_41N)WCNA{Dsph;cAlPT#8&r*fopkx>(u48HgOhwyqIp0+R+=j{QiUI{t21w zJsFWY6YF9g-3Xjuk|(l7bDqR)z5T*Qs@>A8-`$_P_Ng*E3DL`E`>* zy`N-~V(g-f9shr6``!7g5x3jU$b4Vjf6nh`{Wm=8*{@J|_mryZ(Km&G>h(-hq^gJOYZCmk1%)H^hD zL-dt@)9ZNC?;hJ#oFAxCs}piYkbg7(J`tA5CsL;ydCrLN{HOEir39nf0S+daird?x zH`Knpy)P@H{LKwR3v27gFD@?5(s}}AyB=hozo*HfBEP;(=j5Wtk3Ph7NSaPk2%Qle+$2em(IYLtfvh<};p)7yrDoyQ$!%N5jJ%tKaQpHB=UwQgp#}&;L)c{s%OY zm$~r8y0ve+__Okva#LiN8XXsuTvp<&*U58d z^T(ebPW+#}Z%1?b-H?K{6NA2-H~2E?LVeWdk{5w?D-{}2kKGk`{o-6i;5LoC_r*-t zzfb1w+Ml`R_p{|5a}`!8BpkbSNjU#P)xX#sA^wc(t5zOX2`gOWE;Mt?m(Ilpi*E-{ zl)e1Yy)1L{1HFC!8TPzhD)c1#$TRg1H$I7k79Tx)&MtChgyo;*>dXf?A{ZI@_N-;t z)aAXQHk9SQ-*mgeM=Za-ylj4ay#Myfwp(G{9ia{m42xX5m*qOH)tP&#=jwyfe#5fo z#uM*aT3NIQYIgsQ5x*&ROUZm&qEzktF5$eS`@P>^#2QMfnftC*4^!G~Y_FTNoC7qWO0?(9wJE$)5ZI{}=zol-98*TfyeGq)O`|(uqiU0Q-ufKF8ddJT{+~;;Y zb6IpF@XL`d4ylPwS*6QnmG0tLG(`PWQ=(u~>L9&+6|i5zmg$x%H|0G?HD@H<$c!?fuhUr*ra?>5KLiDmO}R zGC%PY6`t<)Bq=HNY5Jt;$t*HLjC_0E-hPu4|9jhdsatccO1W&Sz8p9?S^a9ny@%IR zl2Y%mP7zw|*Zn^E-o)^v-BB6Q=Qr`~=GiaaC~;ZAlr7YIVf==Z_sfrnS;#hC6kPHr zGwIQv4Ka)EuW8o5n0u31nnb* ztJraK)UxIv%buyq`~SV+F6!H%wCtbFT7_%#YPF4=7j7+$HC~*sE5hycMDy9j?5q8L zCl_oL`H(r`R>rZeXSQX}m96ylwP*Y9e=&XG=FrQtmOAgA)Y+>SoB7ChqT!y06QfgR z_L$DCvvTsTb$aC4TC3sg{w&IpZe zdAnNbOWE!ZFE1~@xHj5c;NYXQT9y@34}O1tZ<#F0RJHU-)`45@NKY}lHJ4O++S={@r>-eUpVD^KhqK>mWkAlC zQr994#jxu2`^BRbUgq5Rl{d4#I7X?mr0&!WTYs<4sd+)C8f5qW6^z!~E3A4`)7wqb z_L6yu_nrStOwDx)2}O<<^>va`EBZq{l3XLVXid&jteRqPu-Mh=iI1eP^!fcqXUsi+ z;K-?8^Mm&&DL>c%^4a}m>A!Dnuf2NV-J6@6U) zy4m*=O;JA|y*Bn2R1I6gnd`nJx6}V#oip2X?*&26w%qOAws&Vv#TpMj)gxLDPV@hj zT)jEZ(zVp~)T=c%Pxa4v1)BAqOVm^h3z@L!%MEF!>HWdnU5CWB$Fn6JU1`qbziPsY z?2yz6Tp%PU+io^X>b;y}kYT&d%bn_}Stu8k_$;Jk0LWD>e0@frEqQMkS+#r#(`=gk(iG z9T%NB^*Q7HFVT17_VGJ8o?pEvfmw8k#vDDdZSi~p&)Z)x-Hxr@)b;7^vpm)%MNg(I zUHFJA}%Q`vDA0z+kC`V*=t|yKi6*NJq_S+lm zh$<@4n|x(OT~yVCe?NXs=JJTzSNI{lvPZU*^^|O6k@%< zzkYkXYNYXM<${loT({)il@iyB+3@Su9tGjm7ivHw4Ilr_-`AZaG-dB1>s2e>SWSKW zF5Gfwowd}|sPf4F64vY49=u)tzDdTU*sJ5AY49t~rkzK+Ho2`c4dRIGxN@P)X4mm9 zql8_{T=-OvG<)#gm3+GOt)!S-b+7xsc-PGDyI6%1O8#D1WR#F0Id?)dqo>)eAkU{~ zG}{)eow%iRB3D{~s-4y!$JBF^kM?T4o27JyL^z5vWk2uMUnRkJ`-em^|9+vFTWZhUoEh=b;n{=!{eC*F3_q{UGR+RyU6$Lv zr(oiIUGK_izdrx_@zHtCVGb^?pm>RC2l51V)ciD>WuD*XJzei+uiv&M9JZI`?dzWO zgmNsN>9pp`w(W*a%eMLK*=HuOA?jGxj}H$&eE4vo?V3(&tfE2A4Feu26OR`z@e$SE z-W0AlBPy)DyXbksseol&S{=2&zr7AHGk0@fV+vm%=lb|qZ{gEZ>${Tgtm$SD)_z=J zym8Yy`A=EX91mn2(bD<2+;?_c+}*wRQE{ z)r&KKGBY!O{Q5dv@$tF2)~*L0c-&^18IgI*_N-8!QRv2`qnCbfkDUB5!R^6+j+otL zyu8w8EP^_D*W4RAt}geVf5a?4@4w=KBVBtB$_XSSr7CJ0ZQLZV!EKqTN?4!Ax)~9X z=dZ8XE0ntG(UDH(Plb6s4LU4&cXl-HDt-Ov*Vp*z#YLMzJ+_|5zV}nN{EaNnyR|Fq z;Z+GnOOA-%h+ZjEt}UsjBOdoml}WaGrPCJ8SSk_lY?WKD)T8Tl)%iYa-dsO4rL$LD zUv6K`&-a_$eqWttx><~Ad){54+e`EB?a5rLS}DuSG9#kZZ_Szz|K7h71vf}Ag(-(6 zveqvXSY7)1+QHkmqu=oM%UYXBnPf1;$HyP(l@4!k;a8nnG~c#*n}rPMHn1=6?n;Mj zvPeACQt|m&?+f>IaZm^F=jZ2-A0BS^m}#_hM`zuG1C3Q1Cad{&g|Cn6)UE9n*FUx? z^|VW2OWE672Tz~oo~Z0DR{K)HAou%XZ}H1ZJeidy1~2nD`0?@aO6>(lW4`b2Jh`2T ziK%CuOMF7g;VUbHqaB4xrzIpU<$HH6;_Kbrb{4aroUDF)bNcxs)g{ZiIbv^Z$-KBNH`;KX z*99TZ*Z24De=%7v*2-~LMzlQZ3(rX^jDpr#CFMebI#$dRO|!!a&2*gGcr@bo*_6G% zryE!Q?~kRhw)T#?h$F8~PFByjwPmHkp>I{^Me8La51tH(YBCD_(k#H5ct?UU5_FB7 z_*AV>q5Iu;*7P$7YFBM5wLcdX&y>6F#QoG;Te!VbrNB`Z${I3j``r>;u9TT%(jVMD3Ghx&o~(GCiqe6wuEzwR^g)~j}};)yE%w4 zec2nfF2-`VrkE`V*U`%m1WQr?cT|M`(nXhGN+J`}@V0v`Y!j7E<-< zsNcPFXX3?0u1c4$tdF;!cyOg~MS!C1#zi_2$NOZD#t5tVG;H2%>@`iNQ`xoPVFg9W=T{@Vb!Bz9f608)Y_VOXuiKK2c6Ao> z*Z%q<_P=|{u^j;ypNsv~ zIM6FNp_QR_{-yrOTdvNP`hWJA6l^WP--4Ca%XPAO=c$*lWVrLx=6?)3@Ic~Yxum`6 zw}ytR9aDFPGHPzPQ2U`@)>_Q6_!&=|{oTf?*5!GECYQzbuZ`Z`wW{FCiWe@c!`6N| z(sgffj#%vu!A!238qu!NzorOiU+Ugw*>)x(_2eYh5{DVaVbkh;4&COG2x3w?v?cXQ z+_{*K(LoJ=Zwwb)<{wey6bdp`%A#MV>7zUU)}>F<4;1`<0T$ zX&m<#$uqsQ?q0=wDUY9@pa0L_@AotA@7t>xTom8R;WNvG)484R=!=VsFK*9|7pxZ8 zs8kKwH}t0F;@r1k7E5DGlG18r}8kn7VF3+e1n1TV4@MJOnqI32UFW=Svh_Z?J9G-nl!Il2R+> zH$USlIX1cOMyH^1+m6Gh?%$8EpDz0M(BE%wqyH_vJ&SGQkr#vI;!iQlcH zZAypQ&j+usuV>XO*)}D~=$CzZkZF#C*jWvxSxRAF3Id;LrYJvhZdH1bBP!az;BAa< z)E0r~d>uC~unSF%Uq0#OuFp{>?5S&B99;UAFC^m72Cane@9wg`^qi>Fs&UhgRsY2q zk=%!io5a2_u4sw4Xltxu%<3#@oF>BFv{FlprfXHCxCrv0b=L%mo2=zDndK*?T~+;TaCgoeMGXQU!o8MR)yL_g&H+r@ON@bR(6 zeZo5<`4~@e37u=ZU8Ol~p$~8Ba@nncYW;OO%Okw5bBLdM5ZKl)t(=ezs`WHia!E*4 z?E38U#craum$dN2Me)Ti8T4#xcCBqJu@}AT>gs6xclM^x(pOg;H>aI-ar553e9pba zLU*{u^+Z@SA~&Ths!}++RD06GmWYWyCFe!&CcDlwQVK6QFDAO@#=hF>4WHg_dnU6@ zY5mG*M&7TR+Kt0~*5n)wo_hM{kB`Y8D^qXqynh&MC;UBy<)3pymuc$hX}&e)ucT6g zG?EXU-NYfVaFNB~53g8${adJYbW8BDKr?&6s7?e!(u;NRcgZl0#Gr*Eo&!P1IW!-@0kYPHTu-FP)qTP-ZC z$V6M;S$x|0+2;N%GE+hqd}iCFdm&7$b^2yymKW|0zZ?Ufhkr>{60LufR>|_BM`f<| zqBlGfwXE`8KXxuQKfFdXeYMP8>74lb-O6Dl9#fk5xm+~7T^*O_y=J~^=^Ck-_pP;I z=aEy_&c_&T+@xQBEz|jC>8-RspP%~|zH2xqU69Oj#0MuDyVdH(D*+XU&`Q%S)v${`9$Z%_rT!Vs*m)vTfVaY^%SC+@CmQ?IWEPr5BgK z;YnTlf=5s``@uJEMp?ZO)(PjsHiq9Y0_A0yKQ}kc&WQfjA+p|JnczfitI6rv-(x;* zUYh&g#NF!FEuW_|RwikJs~`V)HiE7JFSLYy{dtgP%c5cJd|l&0nU9_G7x{NB+*5xq zm!Bjd{`#l#dKGy_wXjcyPbJs(H0UHP6`uXA;{DCd$J5S%f~D{9+nkvDR@@)8dKi=y z1XgT&_Ptt7nag*5=Wk`JDaS1}n1X*#oxaTS_k0tLrM@bc_q91i_C~aZiUvq|*-Ug+ zQb^WbpjfbNo9=|psik-3b%a)mo4?jMw%UM+ukS!zzW>W3tIE5L`1-U~uNP_5Jk9Tz z_Q3Z@*I$3lU(?>J-`=-MK>PIJBia^POwYvD8??>Vov5uAcI{)0TG+LNGs6>EI2hH! z-mqsWDOi6cHc1|rVcor(bcrIci|BBv*HwR{SPQ4|@yKi64?^RA~EPh;`7JPHE$)@h` zmLtc`pXc|TWx{xO;N7XqxQXxF9xmkrN4jbqa#>Q?@A<5`vQ0x+J2$dn z=|vN!X=-6h_DlmO$G&PKRK+tQR^~FEUZ;P1->Q@~JG2(0&OI_QefyU%2ia{d>sFX% zUGWGmFy6SS&vHgYBzt;Xt6)OXQM(0ZOq-bV&qb`v4YWQJk;xr2?btkl4Iv-9E*LB_ z4v*U9GNW^9>7JP|Ux8+GvOx0|x!e(DwKu9a2G+`dil z!X*1_PqEzSvo$q0vE>FsQ1DaaB zwow(P95jV_#m%AY!Pz5Tx!r8>@!M)c6~k^dT`9UWMK4yW@X?WjeX`a|bSJ5J3VnHd zJ3M}ZqLT3bs;^w0lhuySGR-y#*RxUj^0Ae8H*7()VhADU?q;BN(r877$q4_>`+CF;}xqm7&T zk_|R?S)B7W&v$&cCNjXlozJHFE0^mmGxu*ik_J1Ht66IQ_XQfKKfd|;`i>2Gx{r?b z$$o6*aWmRDiD_}xWP^=Cyj5`$kkq~Hju$u(qO2w-d44w9xJhN#t(no@DQ@1IGLAca zQcX-!WxxE9Tl`@0wVXTmH*_zj&GNY_Zwq`EF~Y zwjO!CIsJUw^y%Vp`)WF!TDcD1zAgRq^mP7hq94x8G?p;Q5a^S)?>jM3d9hO~*9?

1B@&zEFIS~y_2Tv#lHEsklWu;_vhwmDV+S~(RK4XLyxRY z-!b=`y#mAfKlhcgf0g{=ykGyPWl8F(q;DM$GorWi?PFz4ym2KnVt2NA+^^rto`+a6 zB6b?tRDXBcvLaBF)9J{oi=UsrxVnfnX1UM7#p&lKDkr=76iRAslMDL&?{T|ArS|ss z2PRL~pJ?I8bVVzO+1+Mn9oo8L@h9`?@{`5L{@((8lxq=>CqSGm~v&c zJN(#m{dj}IM=mNpGX$!?y>VP0w|7J7>#&fuQCGR*7T;CfGNrL}O1gJ0ILC0excgmu zbF0Z!` zezfBHxw(RtMJj(xi>63a=e^DPxc&X2qY|dYV$Z7kobIiO{P^Lf@gLJm%%$342YxV~ z>*@@>6R|O1V?^MVmC@||^Y=SMi-&Jn70W%johM91yF3Y0g6cvt+Z%APp*z=eMP>V9(sYA31t=Xpw0<_Uv}7p91`lGG&8!Via(!uaRexpq!l>$)uC z+K2f0roMC8AKh)|zhPLttnQ-p_jihy^4z%-o%vNfxTcs$ho_PGBvc>=NQb&(ym2O&Mv87^SUEjHP%7uT= z%}rSEDr0+G=A@+d@h!W7KLQ03Ev0B;tdu!+Sr!3Iz*wqtyv`h5k|JinUsU4u!R`yTk0|Q`ZMA_gkwT=GrB4aA)!JBiCFG zyWQM$tXDeu>Z;Hm|NdHoj$SxdC-|{j+FY;d`#arjqHdi+N1HUV>a%oH6F~KE{EP@! zne^l%uik9UUU7M|xtFL$gX`kGUzT`n=SuBOTOZk6tM1ozs`0CK=%FJAnJ20wI=MDU zXvb}QdqL6U#by5O+w+}YJvn*d+*Mw7zxfB1^!-InPZz(q*tPlh7s(m>6PrDcXr=5d zRmz_I?d|cazS1HmPtC1!Z|D@QZk+|Hhi68t%=EQZ4TDq>v%J>i-QTC%Xmgc~yDHz?o!Xw?ZzZag&^B9J z$+b)5)sy+m%tx>7`ImfrVa7b0h^N+m6BQl`t`0dlNy+o&CW%WcmD#rCFQ318^>GaW zMq}0Fqer|ZdiuONa^#fCjvbp*SY||cvV|mHKDllE!m5}(PMbFRs)m)!G?=?_QL)di z%|2UXTeZHFzPjQ$=cv&gE{ptoHi1+14GaS2n?~)eGF|a&!8)yk-{0PD%)PxWA$`pX z1-6Nbcf&x-zmiT)Qr%JgJ#WJr&}MU2#@_Gm?>BGL30lZ|c#W9grjnPJI*p^zym);= zMBvf=hkR#sB?)@hx;6hXPr1G4Kf|Zg(_LRy2EDxhX`Zoow^`nyUftOuoI-LN7rm|f z*ggG7izD-et)9Y$>T`FV3SB-=p^E>z#(l06XdX>rzc**&q#Om~<�lHBCxo&BJ9v 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 Z7Pe2DC&8osgn@y9!PC{xWt~$(695Zt)a(EN literal 0 HcmV?d00001 diff --git a/docs/_static/diagrams/i2s/i2s_state_machine.png b/docs/_static/diagrams/i2s/i2s_state_machine.png new file mode 100644 index 0000000000000000000000000000000000000000..493e938723b1197549650c9660ba255adbe9b837 GIT binary patch literal 55870 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�^LVVkXGl;m?6>V;NY*8nVGpg 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 literal 0 HcmV?d00001 diff --git a/docs/doxygen/Doxyfile b/docs/doxygen/Doxyfile index 10856b571e..fb57d3e97b 100644 --- a/docs/doxygen/Doxyfile +++ b/docs/doxygen/Doxyfile @@ -158,6 +158,10 @@ INPUT = \ $(PROJECT_PATH)/components/hal/include/hal/i2c_types.h \ $(PROJECT_PATH)/components/hal/include/hal/i2s_types.h \ $(PROJECT_PATH)/components/hal/include/hal/lcd_types.h \ + $(PROJECT_PATH)/components/driver/include/driver/i2s_controller.h \ + $(PROJECT_PATH)/components/hal/include/hal/i2s_std.h \ + $(PROJECT_PATH)/components/hal/include/hal/i2s_pdm.h \ + $(PROJECT_PATH)/components/hal/include/hal/i2s_tdm.h \ $(PROJECT_PATH)/components/hal/include/hal/ledc_types.h \ $(PROJECT_PATH)/components/hal/include/hal/rtc_io_types.h \ $(PROJECT_PATH)/components/hal/include/hal/sdio_slave_types.h \ diff --git a/docs/en/api-reference/peripherals/i2s.rst b/docs/en/api-reference/peripherals/i2s.rst index cae7301292..36f219c031 100644 --- a/docs/en/api-reference/peripherals/i2s.rst +++ b/docs/en/api-reference/peripherals/i2s.rst @@ -3,8 +3,8 @@ Inter-IC Sound (I2S) {IDF_TARGET_I2S_NUM:default="two", esp32s2="one", esp32c3="one"} -Overview --------- +Introduction +------------ I2S (Inter-IC Sound) is a serial, synchronous communication protocol that is usually used for transmitting audio data between two digital audio devices. @@ -12,10 +12,10 @@ I2S (Inter-IC Sound) is a serial, synchronous communication protocol that is usu An I2S bus consists of the following lines: -- Master clock line (operational) -- Bit clock line -- Channel select line -- Serial data line +- MCLK: Master clock line. It's an optional signal depends on slave side, mainly for offering a reference clock to the I2S slave device. +- BCLK: Bit clock line. The bit clock for data line in common I2S applications. +- WS: Word(Slot) select line. It is usually used to identify the vocal tract except PDM mode. +- DIN/DOUT: Serial data input/output line. Each I2S controller has the following features that can be configured using the I2S driver: @@ -23,339 +23,606 @@ Each I2S controller has the following features that can be configured using the - Capable of acting as transmitter or receiver - DMA controller that allows for streaming sample data without requiring the CPU to copy each data sample -Each controller can operate in half-duplex communication mode. Thus, the two controllers can be combined to establish full-duplex communication. +.. only:: SOC_I2S_HW_VERSION_1 -.. only:: esp32 + Each controller can operate in simplex communication mode. Thus, the two controllers can be combined to establish full-duplex communication. - I2S0 output can be routed directly to the digital-to-analog converter's (DAC) output channels (GPIO 25 & GPIO 26) to produce direct analog output without involving any external I2S codecs. I2S0 can also be used for transmitting PDM (Pulse-density modulation) signals. +.. only:: SOC_I2S_HW_VERSION_2 -.. only:: esp32 or esp32s2 + Each controller has separate rx and tx channel. That means they are able to work under different clock and slot configurations with separate GPIO pins. Note that although their internal MCLK are separate, but the output MCLK signal can only be attached to one channel, we can't output two different MCLK at the same time. - The I2S peripherals also support LCD mode for communicating data over a parallel bus, as used by some LCD displays and camera modules. LCD mode has the following operational modes: +I2S Communication Mode +---------------------- - - LCD master transmitting mode - - Camera slave receiving mode - - ADC/DAC mode +Overview of All Modes +^^^^^^^^^^^^^^^^^^^^^ - For more information, see *{IDF_TARGET_NAME} Technical Reference Manual* > *I2S Controller (I2S)* > LCD Mode [`PDF <{IDF_TARGET_TRM_EN_URL}#camlcdctrl>`__]. +========= ======== ======== ======== ======== ======== ========== +Platform Standard PDM TX PDM RX TDM ADC/DAC LCD/Camera +========= ======== ======== ======== ======== ======== ========== +ESP32 port 0/1 port 0 port 0 none port 0 port 0 +ESP32S2 port 0 none none none none port 0 +ESP32C3 port 0 port 0 none port0 none none +ESP32S3 port 0/1 port 0 port 0 port 0/1 none none +========= ======== ======== ======== ======== ======== ========== + +Standard Mode +^^^^^^^^^^^^^ + +Standard mode always has left and right two sound channels which we called 'slots'. These slots can support 8/16/24/32 bits width sample data. And the communication format for the slots mainly includes the following formats: + +- **Philip Format**: Data signal have one bit shift comparing to the WS(word select) signal. And the duty of WS signal is 50%. + +.. figure:: ../../../_static/diagrams/i2s/std_philip.png + :align: center + :alt: Standard Philip Format + +- **MSB Format**: Almost same as philip format, but its data have no shift. + +.. figure:: ../../../_static/diagrams/i2s/std_msb.png + :align: center + :alt: Standard MSB Format + +- **PCM Short Format**: Data have one bit shift and meanwhile WS signal becomes a pulse lasting one BCLK(Bit Clock) cycle. + +.. figure:: ../../../_static/diagrams/i2s/std_pcm.png + :align: center + :alt: Standard PCM (Short Sync) Format + + +.. only:: SOC_I2S_SUPPORTS_PDM_TX + + PDM Mode (TX) + ^^^^^^^^^^^^^ + + PDM mode for tx channel can transfer PCM data into PDM format which always has left and right slots. PDM TX can only support 16 bits width sample data. PDM TX only need WS pin for clock signal and DOUT pin for data signal. This mode allows user to configure the up-sampling parameters :cpp:member:`i2s_pdm_tx_clk_config_t::up_sample_fp` :cpp:member:`i2s_pdm_tx_clk_config_t::up_sample_fs`. The up-sampling rate can be calculated by``up_sample_rate = fp / fs``, there are up-sampling modes in PDM TX: + + - **Fixed Clock Frequency**: In this mode the up-sampling rate will change according to the sample rate. We need to set ``fp = 960`` and ``fs = sample_rate / 100``, then the clock frequency(Fpdm) on WS pin will be fixed to 128 * 48 KHz = 6.144 MHz, note that this frequency is not equal to the sample rate(Fpcm). + - **Fixed Up-sampling Rate**: In this mode the up-sampling rate is fixed to 2. We need to set ``fp = 960`` and ``fs = 480``, then the clock frequency(Fpdm) on WS pin will be ``128 * sample_rate`` + +.. only:: SOC_I2S_SUPPORTS_PDM_RX + + PDM Mode (RX) + ^^^^^^^^^^^^^ + + PDM mode for rx channel can receive PDM format data and transfer the data into PCM format. PDM RX can only support 16 bits width sample data. PDM RX only need WS pin for clock signal and DIN pin for data signal. This mode allows user to configure the down-sampling parameter :cpp:member:`i2s_pdm_rx_slot_config_t::dn_sample_mode`, there are two down-sampling modes in PDM RX: + + - :cpp:member:`i2s_pdm_dsr_t::I2S_PDM_DSR_8S`: In this mode, the clock frequency(Fpdm) on WS pin will be sample_rate(Fpcm) * 64. + - :cpp:member:`i2s_pdm_dsr_t::I2S_PDM_DSR_16S`: In this mode, the clock frequency(Fpdm) on WS pin will be sample_rate(Fpcm) * 128. + +.. only:: SOC_I2S_SUPPORTS_PDM_TX or SOC_I2S_SUPPORTS_PDM_RX + + .. figure:: ../../../_static/diagrams/i2s/pdm.png + :align: center + :alt: PDM Format + +.. only:: SOC_I2S_SUPPORTS_TDM + + TDM Mode + ^^^^^^^^ + + TDM mode supports upto 16 slots, these slots can be enabled by :cpp:member:`i2s_tdm_slot_config_t::slot_mask`. But due to the hardware limitation, only upto 4 slots are supported while the slot is set to 32 bit-width, and 8 slots for 16 bit-width, 16 slots for 8 bit-width. The slot communication format of TDM is almost same as standard mode, but there are some small differences between them. + + - **Philip Format**: Data signal have one bit shift comparing to the WS(word select) signal. And no matter how many slots are contained in one frame, the duty of WS signal will always keep 50%. + + .. figure:: ../../../_static/diagrams/i2s/tdm_philip.png + :align: center + :alt: TDM Philip Format + + - **MSB Format**: Almost same as philip format, but its data have no shift. + + .. figure:: ../../../_static/diagrams/i2s/tdm_msb.png + :align: center + :alt: TDM MSB Format + + - **PCM Short Format**: Data have one bit shift and meanwhile WS signal becomes a pulse lasting one BCLK(Bit Clock) cycle for every frame. + + .. figure:: ../../../_static/diagrams/i2s/tdm_pcm_short.png + :align: center + :alt: TDM PCM (Short Sync) Format + + - **PCM Long Format**: Data have one bit shift and meanwhile WS signal will lasting one slot bit width for every frame. For example, if there are 4 slots enabled, then the duty of WS will be 25%, and if there are 5 slots, it will be 20%. + + .. figure:: ../../../_static/diagrams/i2s/tdm_pcm_long.png + :align: center + :alt: TDM PCM (Long Sync) Format + +.. only:: SOC_I2S_SUPPORTS_LDC_CAMERA + + LCD/Camera Mode + ^^^^^^^^^^^^^^^ + + LCD/Camera mode are only supported on I2S0 over a parallel bus. For LCD mode, I2S0 should working at master tx mode. For camera mode, I2S0 should working at slave rx mode. These two modes won't be implemented in I2S driver, please refer to :doc:`/api-reference/peripherals/lcd` for LCD implementation. For more information, see *{IDF_TARGET_NAME} Technical Reference Manual* > *I2S Controller (I2S)* > LCD Mode [`PDF <{IDF_TARGET_TRM_EN_URL}#camlcdctrl>`__]. + +.. only:: SOC_I2S_SUPPORTS_ADC_DAC + + ADC/DAC Mode + ^^^^^^^^^^^^ + + ADC/DAC mode only exist on ESP32 and are only supported on I2S0. Actually, they are two sub-modes of LCD/Camera mode. I2S0 can be routed directly to the internal analog-to-digital converter(ADC) or digital-to-analog converter(DAC). In other words, ADC/DAC peripherals can read/write continuously via I2S0 DMA. As they are not an actual communication mode, I2S driver will no longer implement them, for the full support of ADC/DAC, please refer to ADC(:doc:`/api-reference/peripherals/adc`) or DAC(:doc:`/api-reference/peripherals/dac`) driver for implementation. + +I2S Clock +--------- + +Clock Source +^^^^^^^^^^^^ + +- :cpp:member:`i2s_clock_src_t::I2S_CLK_160M_PLL`: 160 MHz PLL clock. .. only:: SOC_I2S_SUPPORTS_APLL - .. note:: + - :cpp:member:`i2s_clock_src_t::I2S_CLK_APLL`: Audio PLL clock, more precise than ``I2S_CLK_160M_PLL`` in high sample rate applications. Its frequency is configurable according to the sample rate, but if APLL has been occupied by emac or other channels already, the APLL frequency is not allowed to change, the driver will try to work under this APLL frequency, if this APLL frequency can't meet the requirements of I2S, the clock configuration will fail. - For high accuracy clock applications, use the APLL_CLK clock source, which has the frequency range of 16 ~ 128 MHz. You can enable the APLL_CLK clock source by setting :cpp:member:`i2s_config_t::use_apll` to ``TRUE``. +Clock Concepts +^^^^^^^^^^^^^^ - If :cpp:member:`i2s_config_t::use_apll` = ``TRUE`` and :cpp:member:`i2s_config_t::fixed_mclk` > ``0``, then the master clock output frequency for I2S will be equal to the value of :cpp:member:`i2s_config_t::fixed_mclk`, which means that the mclk frequency is provided by the user, instead of being calculated by the driver. +- **sample rate**: The number of sampled data in one second per slot. +- **sclk**: Source clock frequency. It is the frequency of the clock source. +- **mclk**: Master clock frequency. ``bclk`` is generate from this clock, in some cases, we need to output MCLK signal as a reference clock to synchronize BCLK and WS between I2S master role and slave role. +- **bclk**: Bit clock frequency. Every tick of this clock stands for one data bit on data pin. It means there will be 8/16/24/32 ``bclk`` ticks in one slot, because the number of ``bclk`` ticks in one slot is equal to the :cpp:member:`slot_bit_width` we set. +- **lrck** / **ws**: Left/Right clock or word select clock. For non-PDM mode, its frequency is equal to the sample rate. - The clock rate of the word select line, which is called audio left-right clock rate (LRCK) here, is always the divisor of the master clock output frequency and for which the following is always true: 0 < MCLK/LRCK/channels/bits_per_sample < 64. +.. note:: + Normally ``mclk`` should be the multiple of ``sample rate`` and ``bclk`` at the same time. This field :cpp:member:`i2s_std_clk_config_t::mclk_multiple` means the multiple of ``mclk`` to the ``sample rate``. If ``slot_bit_width`` is set to ``I2S_SLOT_BIT_WIDTH_24BIT``, to keep ``mclk`` a multiple to the ``bclk``, we need to set the :cpp:member:`i2s_std_clk_config_t::mclk_multiple` to ``I2S_MCLK_MULTIPLE_384``, otherwise the ``ws`` will be inaccurate. But in the most cases, ``I2S_MCLK_MULTIPLE_256`` should be enough. Functional Overview ------------------- +The I2S driver offers following services: -Installing the Driver -^^^^^^^^^^^^^^^^^^^^^ +Resources Management +^^^^^^^^^^^^^^^^^^^^ -Install the I2S driver by calling the function :cpp:func:`i2s_driver_install` and passing the following arguments: +There are three levels' resources in I2S driver: -- Port number -- The initialized :cpp:type:`i2s_config_t` struct defining the communication parameters -- Event queue size and handle +- ``platform level``: Resources of all I2S controllers in the current target. +- ``controller level``: Resources in one I2S controller. +- ``channel level``: Resources of tx or rx channel in one I2S controller. -An ``ESP_OK`` return value from :cpp:func:`i2s_driver_install` indictes I2S has started. +The public APIs are all channel level APIs, the channel handle :cpp:type:`i2s_chan_handle_t` can help user to manage the resources under a specific channel without considering the other two levels. The other two upper levels' resources are private and will be managed by the driver automatically. Users can call :cpp:func:`i2s_new_channel` to apply a channel handle and call :cpp:func:`i2s_del_channel` to delete it. -Configuration example: +Power Management +^^^^^^^^^^^^^^^^ -.. only:: not SOC_I2S_SUPPORTS_TDM +When power management is enabled (i.e. :ref:`CONFIG_PM_ENABLE` is on), the system will adjust or stop the source clock of I2S before going into light sleep, thus potentially changing the I2S signals and leading to transmitting or receiving invalid data. - .. code-block:: c +I2S driver can prevent the system from changing or stopping the source clock by acquiring a power management lock. When the source clock is generated from APB, the lock type will be set to :c:member:`ESP_PM_APB_FREQ_MAX` and when the source clock is APLL (if target support APLL), it will be set to :c:member:`ESP_PM_NO_LIGHT_SLEEP`. Whenever user is reading or writing via I2S, the driver will guarantee that the power management lock is acquired. Likewise, the driver releases the lock after reading or writing finished. - static const int i2s_num = 0; // i2s port number +Finite-State Machine +^^^^^^^^^^^^^^^^^^^^ - i2s_config_t i2s_config = { - .mode = I2S_MODE_MASTER | I2S_MODE_TX, - .sample_rate = 44100, - .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, - .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, - .communication_format = I2S_COMM_FORMAT_STAND_I2S - .tx_desc_auto_clear = false, - .dma_desc_num = 8, - .dma_frame_num = 64, - .use_apll = false, - .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1 // Interrupt level 1, default 0 - }; +There are six states for a I2S channel, they are ``registered``, ``initializing``, ``ready``, ``idle``, ``writing`` and ``reading``. Their relationship is shown in the following diagram: - i2s_driver_install(i2s_num, &i2s_config, 0, NULL); +.. figure:: ../../../_static/diagrams/i2s/i2s_state_machine.png + :align: center + :alt: I2S Finite-State Machine -.. only:: SOC_I2S_SUPPORTS_TDM +Data Transport +^^^^^^^^^^^^^^ - .. code-block:: c +The data transport of I2S peripheral, including sending and receiving, is realized by DMA. Before transporting data, we need to call :cpp:func:`i2s_start_channel` to start the specific channel. When we sent or received data reached the size of one DMA buffer, ``I2S_OUT_EOF`` or ``I2S_IN_SUC_EOF`` interrupt will be triggered. Note that the DMA buffer size is not equal to :cpp:member:`i2s_std_slot_config_t::dma_frame_num`, one frame here means all the sampled data in one WS circle. Therefore, ``dma_buffer_size = dma_frame_num * slot_num * slot_bit_width / 8``. For the transmit case, users input the data by :cpp:func:`i2s_write_channel`, ``i2s_write_channel`` will help user to copy the data from source buffer to the DMA tx buffer and waiting for transmit finished and then repeat until sent bytes reached the given size. For the receive case, the rx DMA buffer address will be sent from isr to :cpp:func:`i2s_read_channel`, ``i2s_read_channel`` will help user the copy the data from DMA rx buffer to the destination buffer. - static const int i2s_num = 0; // i2s port number +Configuration Setting +^^^^^^^^^^^^^^^^^^^^^^ - i2s_config_t i2s_config = { - .mode = I2S_MODE_MASTER | I2S_MODE_TX, - .sample_rate = 44100, - .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, - .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, - .communication_format = I2S_COMM_FORMAT_STAND_I2S, - .tx_desc_auto_clear = false, - .dma_desc_num = 8, - .dma_frame_num = 64, - .bits_per_chan = I2S_BITS_PER_SAMPLE_16BIT - }; +Users can initialize a channel by calling :cpp:func:`i2s_init_channel`, it will initialize a channel working at a specific mode by input corresponding clock and slot configurations. If we want to update the configuration after initialization, we need to call :cpp:func:`i2s_stop_channel` first to ensure the channel has stopped, then call :cpp:func:`i2s_set_slot` or :cpp:func:`i2s_set_clock` to update the configuration. - i2s_driver_install(i2s_num, &i2s_config, 0, NULL); +IRAM Safe +^^^^^^^^^ -Setting Communication Pins -^^^^^^^^^^^^^^^^^^^^^^^^^^ +By default, the GPTimer interrupt will be deferred when the Cache is disabled for reasons like writing/erasing Flash. Thus the EOF interrupt will not get executed in time, which is not expected in a real-time application. -Once the driver is installed, configure the physical GPIO pins to which the I2S signals will be routed. This is accomplished by calling the function :cpp:func:`i2s_set_pin` with the following arguments: +There's a Kconfig option :ref:`CONFIG_I2S_ISR_IRAM_SAFE` that will: -- Port number -- The structure :cpp:type:`i2s_pin_config_t` which defines the GPIO pin numbers for the MCK, BCK, WS, DATA out, and DATA in signals. To keep a current pin allocatopm pin for a specific signal, or to indicate an unused signal, pass the macro :c:macro:`I2S_PIN_NO_CHANGE`. See the example below. +1. Enable the interrupt being serviced even when cache is disabled -.. note:: - - MCK only takes effect in `I2S_MODE_MASTER` mode. - -.. code-block:: c - - static const i2s_pin_config_t pin_config = { - .mck_io_num = 0, - .bck_io_num = 4, - .ws_io_num = 5, - .data_out_num = 18, - .data_in_num = I2S_PIN_NO_CHANGE - }; - - i2s_set_pin(I2S_NUM, &pin_config); - -Running I2S Communication -^^^^^^^^^^^^^^^^^^^^^^^^^ - -To send data: - -- Prepare the data for sending -- Call the function :cpp:func:`i2s_write` and pass the data buffer address and data length to it - -The function will write the data to the DMA Tx buffer, and the data will be transmitted automatically by the I2S peripheral. - -.. code-block:: c - - i2s_write(I2S_NUM, samples_data, ((bits+8)/16)*SAMPLE_PER_CYCLE*4, &i2s_bytes_write, 100); - -To retrieve received data, use the function :cpp:func:`i2s_read`. It will retrieve the data from the DMA Rx buffer once the data is received by the I2S peripheral. - -.. code-block:: c - - i2s_read(I2S_NUM, data_recv, ((bits+8)/16)*SAMPLE_PER_CYCLE*4, &i2s_bytes_read, 100); - -You can temporarily halt the I2S driver by calling :cpp:func:`i2s_stop`, which disables the I2S Tx/Rx units until :cpp:func:`i2s_start` is called. The driver automatically starts the I2S peripheral after :cpp:func:`i2s_driver_install` is called, eliminating the need to call :cpp:func:`i2s_start`. - - -Deleting the Driver -^^^^^^^^^^^^^^^^^^^ - -Once I2S communication is no longer required, the driver can be removed to free allocated resources by calling :cpp:func:`i2s_driver_uninstall`. +2. Place driver object into DRAM (in case it's linked to PSRAM by accident) +This will allow the interrupt to run while the cache is disabled but will come at the cost of increased IRAM consumption. Application Example ------------------- -Code examples for the I2S driver can be found in the directory :example:`peripherals/i2s`. +The examples of the I2S driver can be found in the directory :example:`peripherals/i2s`. +Here are some simple usages of each mode: -.. only:: SOC_I2S_SUPPORTS_ADC or SOC_I2S_SUPPORTS_DAC +Standard TX/RX usage +^^^^^^^^^^^^^^^^^^^^ - Additionally, there are two short configuration examples for the I2S driver. +We can choose different helper macros to generate different slot communication format for standard mode. As described above, there are three formats in standard mode, their helper macros are: -.. only:: not SOC_I2S_SUPPORTS_ADC or SOC_I2S_SUPPORTS_DAC +- ``I2S_STD_PHILIP_SLOT_CONFIG(bits_per_sample, mono_or_stereo)`` +- ``I2S_STD_PCM_SLOT_CONFIG(bits_per_sample, mono_or_stereo)`` +- ``I2S_STD_MSB_SLOT_CONFIG(bits_per_sample, mono_or_stereo)`` - Additionally, there is a short configuration examples for the I2S driver. +The clock config helper macro is: -I2S configuration -^^^^^^^^^^^^^^^^^ +- ``I2S_STD_CLK_CONFIG(rate)`` -Example for general usage: +You can refer to :ref:`i2s-api-reference-i2s_std` for STD API information. +And for more details, please refer to :component_file:`hal/include/hal/i2s_std.h`. -.. only:: not SOC_I2S_SUPPORTS_TDM +.. code-block:: c + + #include "driver/i2s_controller.h" + #include "driver/gpio.h" + + i2s_chan_handle_t tx_handle; + i2s_gpio_config_t i2s_pin = { + .mclk = I2S_GPIO_UNUSED, + .bclk = GPIO_NUM_4, + .ws = GPIO_NUM_5, + .dout = GPIO_NUM_18, + .din = I2S_GPIO_UNUSED + }; + /* Get the default channel configuration by helper macro. + * This helper macro is defined in 'i2s_controller.h' and shared by all the i2s communication mode. + * It can help to specify the I2S role, mode and gpio pins */ + i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); + /* Apply a new tx channel and get the handle of this channel */ + i2s_new_channel(&chan_cfg, &tx_handle, NULL); + + /* Get the default std philip format slot config and default std clock config + * These two helper macros is defined in 'i2s_std.h' which can only be used in STD mode. + * They can help to specify the slot and clock configurations for initialization or updating */ + i2s_std_slot_config_t slot_cfg = I2S_STD_PHILIP_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_STEREO); + i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(48000); + /* Initialize the channel */ + i2s_init_channel(tx_handle, &clk_cfg, &slot_cfg); + + /* If we meed to acquire the I2S events, we can apply an event handle for receiving the events */ + // QueueHandle_t evt_que = i2s_get_event_queue(tx_handle, 15); + + /* Before write data, we have to start the tx channel */ + i2s_start_channel(tx_handle); + i2s_write_channel(tx_handle, src_buf, bytes_to_write, bytes_written, ticks_to_wait); + + /* If we need to update the configurations of slot or clock, + * we need to stop the channel first and then update it */ + // i2s_stop_channel(tx_handle); + // slot_cfg.slot_mode = I2S_SLOT_MODE_MONO; // Default is stereo + // i2s_set_slot(tx_handle, &slot_cfg); + // i2s_std_clk_config_t new_clk_cfg = I2S_STD_CLK_CONFIG(96000); + // i2s_set_clock(tx_handle, &new_clk_cfg); + + /* If the handle is not needed any more, we can delete it to release the channel resources */ + i2s_del_channel(tx_handle); + +.. code-block:: c + + #include "driver/i2s_controller.h" + #include "driver/gpio.h" + + i2s_chan_handle_t rx_handle; + i2s_gpio_config_t i2s_pin = { + .mclk = I2S_GPIO_UNUSED, + .bclk = GPIO_NUM_4, + .ws = GPIO_NUM_5, + .dout = I2S_GPIO_UNUSED, + .din = GPIO_NUM_19 + }; + /* Get the default channel configuration by helper macro. + * This helper macro is defined in 'i2s_controller.h' and shared by all the i2s communication mode. + * It can help to specify the I2S role, mode and gpio pins */ + i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); + /* Apply a new rx channel and get the handle of this channel */ + i2s_new_channel(&chan_cfg, NULL, &rx_handle); + + /* Get the default std philip format slot config and default std clock config + * These two helper macros is defined in 'i2s_std.h' which can only be used in STD mode. + * They can help to specify the slot and clock configurations for initialization or updating */ + i2s_std_slot_config_t slot_cfg = I2S_STD_MSB_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_STEREO); // get the default MSB format slot config + i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(48000); + /* Initialize the channel */ + i2s_init_channel(rx_handle, &clk_cfg, &slot_cfg); + + /* Before read data, we have to start the rx channel */ + i2s_start_channel(rx_handle); + i2s_read_channel(rx_handle, desc_buf, bytes_to_read, bytes_read, ticks_to_wait); + + /* If the handle is not needed any more, we can delete it to release the channel resources */ + i2s_del_channel(rx_handle); + +.. only:: SOC_I2S_SUPPORTS_PDM_TX + + PDM TX usage + ^^^^^^^^^^^^ + + For PDM mode in tx channel, the slot configuration helper macro is: + + - ``I2S_PDM_TX_SLOT_CONFIG(bits_per_sample, mono_or_stereo)`` + + The clock configuration helper macro is: + + - ``I2S_PDM_TX_CLK_CONFIG(rate)`` + + You can refer to :ref:`i2s-api-reference-i2s_pdm` for PDM TX API information. + And for more details, please refer to :component_file:`hal/include/hal/i2s_pdm.h`. .. code-block:: c - #include "driver/i2s.h" + #include "driver/i2s_controller.h" + #include "driver/gpio.h" - static const int i2s_num = 0; // i2s port number - - i2s_config_t i2s_config = { - .mode = I2S_MODE_MASTER | I2S_MODE_TX, - .sample_rate = 44100, - .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, - .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, - .communication_format = I2S_COMM_FORMAT_STAND_I2S - .tx_desc_auto_clear = false, - .dma_desc_num = 8, - .dma_frame_num = 64, - .use_apll = false, - .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1 // Interrupt level 1, default 0 + i2s_chan_handle_t tx_handle; + i2s_gpio_config_t i2s_pin = { + .mclk = I2S_GPIO_UNUSED, + .bclk = I2S_GPIO_UNUSED, + .ws = GPIO_NUM_5, + .dout = GPIO_NUM_18, + .din = I2S_GPIO_UNUSED }; - static const i2s_pin_config_t pin_config = { - .bck_io_num = 4, - .ws_io_num = 5, - .data_out_num = 18, - .data_in_num = I2S_PIN_NO_CHANGE + /* Set the channel mode to PDM TX */ + i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_PDM, &i2s_pin); + i2s_new_channel(&chan_cfg, &tx_handle, NULL); + + /* Get the default pdm tx format slot config and default pdm tx config */ + i2s_pdm_tx_slot_config_t tx_slot_cfg = I2S_PDM_TX_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO); + i2s_pdm_tx_clk_config_t tx_clk_cfg = I2S_PDM_TX_CLK_CONFIG(36000); + i2s_init_channel(tx_handle, &tx_clk_cfg, &tx_slot_cfg); + + ... + + +.. only:: SOC_I2S_SUPPORTS_PDM_RX + + PDM RX usage + ^^^^^^^^^^^^ + + For PDM mode in RX channel, the slot configuration helper macro is: + + - ``I2S_PDM_RX_SLOT_CONFIG(bits_per_sample, mono_or_stereo)`` + + The clock configuration helper macro is: + + - ``I2S_PDM_RX_CLK_CONFIG(rate)`` + + You can refer to :ref:`i2s-api-reference-i2s_pdm` for PDM RX API information. + And for more details, please refer to :component_file:`hal/include/hal/i2s_pdm.h`. + + .. code-block:: c + + #include "driver/i2s_controller.h" + #include "driver/gpio.h" + + i2s_chan_handle_t rx_handle; + i2s_gpio_config_t i2s_pin = { + .mclk = I2S_GPIO_UNUSED, + .bclk = I2S_GPIO_UNUSED, + .ws = GPIO_NUM_5, + .dout = I2S_GPIO_UNUSED, + .din = GPIO_NUM_19 }; - i2s_driver_install(i2s_num, &i2s_config, 0, NULL); //install and start i2s driver - i2s_set_pin(i2s_num, &pin_config); + /* Set the channel mode to PDM RX */ + i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_PDM, &i2s_pin); + i2s_new_channel(&chan_cfg, &rx_handle, NULL); + + /* Get the default pdm rx format slot config and default pdm rx clock config */ + i2s_pdm_rx_slot_config_t rx_slot_cfg = I2S_PDM_RX_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO); + // rx_slot_cfg.slot_mode = I2S_SLOT_MODE_STEREO; // Default is mono + i2s_pdm_rx_clk_config_t rx_clk_cfg = I2S_PDM_RX_CLK_CONFIG(36000); + i2s_init_channel(rx_handle, &clk_cfg, &slot_cfg); - ... - /* You can reset parameters by calling 'i2s_set_clk' - * - * The low 16 bits are the valid data bits in one chan and the high 16 bits are - * the total bits in one chan. If high 16 bits is smaller than low 16 bits, it will - * be set to a same value as low 16 bits. - */ - uint32_t bits_cfg = (I2S_BITS_PER_CHAN_32BIT << 16) | I2S_BITS_PER_SAMPLE_16BIT; - i2s_set_clk(i2s_num, 22050, bits_cfg, I2S_CHANNEL_STEREO); ... - i2s_driver_uninstall(i2s_num); //stop & destroy i2s driver .. only:: SOC_I2S_SUPPORTS_TDM - .. code-block:: c + TDM TX/RX usage + ^^^^^^^^^^^^^^^ - #include "driver/i2s.h" + We can choose different helper macros to generate different slot communication format for TDM mode. As described above, there are four formats in TDM mode, their helper macros are: - static const int i2s_num = 0; // i2s port number + - ``I2S_TDM_PHILIP_SLOT_CONFIG(bits_per_sample, mono_or_stereo, mask)`` + - ``I2S_TDM_MSB_SLOT_CONFIG(bits_per_sample, mono_or_stereo, mask)`` + - ``I2S_TDM_PCM_SHORT_SLOT_CONFIG(bits_per_sample, mono_or_stereo, mask)`` + - ``I2S_TDM_PCM_LONG_SLOT_CONFIG(bits_per_sample, mono_or_stereo, mask)`` - i2s_config_t i2s_config = { - .mode = I2S_MODE_MASTER | I2S_MODE_TX, - .sample_rate = 44100, - .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, - .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, - .communication_format = I2S_COMM_FORMAT_STAND_I2S - .tx_desc_auto_clear = false, - .dma_desc_num = 8, - .dma_frame_num = 64 - }; + The clock config helper macro is: - static const i2s_pin_config_t pin_config = { - .bck_io_num = 4, - .ws_io_num = 5, - .data_out_num = 18, - .data_in_num = I2S_PIN_NO_CHANGE - }; + - ``I2S_TDM_CLK_CONFIG(rate)`` - i2s_driver_install(i2s_num, &i2s_config, 0, NULL); //install and start i2s driver - i2s_set_pin(i2s_num, &pin_config); - - ... - /* You can reset parameters by calling 'i2s_set_clk' - * - * The low 16 bits are the valid data bits in one chan and the high 16 bits are - * the total bits in one chan. If high 16 bits is smaller than low 16 bits, it will - * be set to a same value as low 16 bits. - */ - uint32_t bits_cfg = (I2S_BITS_PER_CHAN_32BIT << 16) | I2S_BITS_PER_SAMPLE_16BIT; - i2s_set_clk(i2s_num, 22050, bits_cfg, I2S_CHANNEL_STEREO); - ... - - i2s_driver_uninstall(i2s_num); //stop & destroy i2s driver - - I2S on {IDF_TARGET_NAME} support TDM mode, up to 16 channels are available in TDM mode. If you want to use TDM mode, set field ``channel_format`` of :cpp:type:`i2s_config_t` to ``I2S_CHANNEL_FMT_MULTIPLE``. Then enable the channels by setting ``chan_mask`` using masks in :cpp:type:`i2s_channel_t`, the number of active channels and total channels will be calculate automatically. You can also set a particular total channel number for it, but it shouldn't be smaller than the largest channel you use. - - If active channels are discrete, the inactive channels within total channels will be filled by a constant automatically. But if ``skip_msk`` is enabled, these inactive channels will be skiped. + You can refer to :ref:`i2s-api-reference-i2s_tdm` for TDM API information. + And for more details, please refer to :component_file:`hal/include/hal/i2s_tdm.h`. .. code-block:: c - #include "driver/i2s.h" + #include "driver/i2s_controller.h" + #include "driver/gpio.h" - static const int i2s_num = 0; // i2s port number - - i2s_config_t i2s_config = { - .mode = I2S_MODE_MASTER | I2S_MODE_TX, - .sample_rate = 44100, - .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, - .channel_format = I2S_CHANNEL_FMT_MULTIPLE, - .communication_format = I2S_COMM_FORMAT_STAND_I2S - .tx_desc_auto_clear = false, - .dma_desc_num = 8, - .dma_frame_num = 64, - .chan_mask = I2S_TDM_ACTIVE_CH0 | I2S_TDM_ACTIVE_CH2 + i2s_chan_handle_t tx_handle; + i2s_gpio_config_t i2s_pin = { + .mclk = I2S_GPIO_UNUSED, + .bclk = GPIO_NUM_4, + .ws = GPIO_NUM_5, + .dout = GPIO_NUM_18, + .din = I2S_GPIO_UNUSED }; - static const i2s_pin_config_t pin_config = { - .bck_io_num = 4, - .ws_io_num = 5, - .data_out_num = 18, - .data_in_num = I2S_PIN_NO_CHANGE - }; + /* Set the channel mode to TDM */ + i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_TDM, &i2s_pin); + i2s_new_channel(&chan_cfg, &tx_handle, NULL); - i2s_driver_install(i2s_num, &i2s_config, 0, NULL); //install and start i2s driver - i2s_set_pin(i2s_num, &pin_config); + /* Get the default tdm format slot config and default tdm clock config */ + i2s_tdm_slot_config_t slot_cfg = I2S_TDM_MSB_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO, I2S_TDM_SLOT0 | I2S_TDM_SLOT1 | I2S_TDM_SLOT2 | I2S_TDM_SLOT3); + // slot_cfg.mono = true; // Default is false, set true will let all the active slots send same data + i2s_tdm_clk_config_t clk_cfg = I2S_TDM_CLK_CONFIG(44100); + i2s_init_channel(tx_handle, &clk_cfg, &slot_cfg); ... - /* You can reset parameters by calling 'i2s_set_clk' - * - * The low 16 bits are the valid data bits in one chan and the high 16 bits are - * the total bits in one chan. If high 16 bits is smaller than low 16 bits, it will - * be set to a same value as low 16 bits. - */ - uint32_t bits_cfg = (I2S_BITS_PER_CHAN_32BIT << 16) | I2S_BITS_PER_SAMPLE_16BIT; - i2s_set_clk(i2s_port_t i2s_num, 22050, bits_cfg, I2S_TDM_ACTIVE_CH0 | I2S_TDM_ACTIVE_CH1); // set clock - ... - - i2s_driver_uninstall(i2s_num); //stop & destroy i2s driver - -.. only:: SOC_I2S_SUPPORTS_ADC or SOC_I2S_SUPPORTS_DAC - - Configuring I2S to use internal DAC for analog output - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code-block:: c - #include "driver/i2s.h" - #include "freertos/queue.h" + #include "driver/i2s_controller.h" + #include "driver/gpio.h" - static const int i2s_num = 0; // i2s port number - - static const i2s_config_t i2s_config = { - .mode = I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN, - .sample_rate = 44100, - .bits_per_sample = 16, /* the DAC module will only take the 8bits from MSB */ - .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, - .intr_alloc_flags = 0, // default interrupt priority - .dma_desc_num = 8, - .dma_frame_num = 64, - .use_apll = false + i2s_chan_handle_t rx_handle; + i2s_gpio_config_t i2s_pin = { + .mclk = I2S_GPIO_UNUSED, + .bclk = GPIO_NUM_4, + .ws = GPIO_NUM_5, + .dout = I2S_GPIO_UNUSED, + .din = GPIO_NUM_19 }; + /* Set the channel mode to TDM */ + i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_TDM, &i2s_pin); + i2s_new_channel(&chan_cfg, NULL, &rx_handle); + + /* Get the default tdm format slot config and default tdm clock config */ + i2s_tdm_slot_config_t slot_cfg = I2S_TDM_MSB_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO, I2S_TDM_SLOT0 | I2S_TDM_SLOT1 | I2S_TDM_SLOT2 | I2S_TDM_SLOT3); + i2s_tdm_clk_config_t clk_cfg = I2S_TDM_CLK_CONFIG(44100); + i2s_init_channel(tx_handle, &clk_cfg, &slot_cfg); ... - i2s_driver_install(i2s_num, &i2s_config, 0, NULL); //install and start i2s driver +Full-duplex +^^^^^^^^^^^ - i2s_set_pin(i2s_num, NULL); //for internal DAC, this will enable both of the internal channels +Full-duplex mode will register tx and rx channel in a I2S port at the same time, and they will share the BCLK and WS signal. Currently STD and TDM communication mode are able to apply full-duplex mode in following way, but PDM full-duplex is not supported in this way. - //You can call i2s_set_dac_mode to set built-in DAC output mode. - //i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN); +Note that since the handle is the channel handle, we have to apply same slot and clock configurations for both tx and rx channel one by one. - i2s_set_sample_rates(i2s_num, 22050); //set sample rates +Here is an example of how to apply a pair of full-duplex channels: - i2s_driver_uninstall(i2s_num); //stop & destroy i2s driver +.. code-block:: c + + #include "driver/i2s_controller.h" + #include "driver/gpio.h" + + i2s_chan_handle_t tx_handle; + i2s_chan_handle_t rx_handle; + i2s_gpio_config_t i2s_pin = { + .mclk = I2S_GPIO_UNUSED, + .bclk = GPIO_NUM_4, + .ws = GPIO_NUM_5, + .dout = GPIO_NUM_18, + .din = GPIO_NUM_19 + }; + + /* Set the channel mode to STD */ + i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); + /* Apply for tx and rx channel at the same time, then they will work in full-duplex mode */ + i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle); + + /* Get the default configurations */ + i2s_std_slot_config_t slot_cfg = I2S_STD_PHILIP_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO); + i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(32000); + /* Set the configurations for BOTH TWO channels, since tx and rx channel have to be same in full-duplex mode */ + i2s_init_channle(tx_handle, &clk_cfg, &slot_cfg); + i2s_init_channle(rx_handle, &clk_cfg, &slot_cfg); + + i2s_start_channel(tx_handle); + i2s_start_channel(rx_handle); + + ... + +.. only:: SOC_I2S_HW_VERSION_1 + + Simplex Mode + ^^^^^^^^^^^^ + + To apply the simplex mode, :c:func:`i2s_new_channel` should be called for each channel. The clock and gpio pins of TX/RX channel on {IDF_TARGET_NAME} are not separate, therefore TX and RX channel can't coexist on a same I2S port in simplex mode. + + .. code-block:: c + + #include "driver/i2s_controller.h" + #include "driver/gpio.h" + + i2s_chan_handle_t tx_handle; + i2s_chan_handle_t rx_handle; + i2s_gpio_config_t tx_pin = { + .mclk = GPIO_NUM_0, + .bclk = GPIO_NUM_4, + .ws = GPIO_NUM_5, + .dout = GPIO_NUM_18, + .din = I2S_GPIO_UNUSED + }; + i2s_chan_config_t tx_chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, tx_pin); + i2s_new_channel(&tx_chan_cfg, &tx_handle, NULL); + i2s_std_slot_config_t tx_slot_cfg = I2S_STD_PHILIP_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO); + tx_slot_cfg.auto_clear = false; + i2s_std_clk_config_t tx_clk_cfg = I2S_STD_CLK_CONFIG(48000); + i2s_init_channel(tx_handle, &tx_clk_cfg, &tx_slot_cfg); + i2s_start_channel(tx_handle); + + i2s_gpio_config_t rx_pin = { + .mclk = I2S_GPIO_UNUSED, + .bclk = GPIO_NUM_6, + .ws = GPIO_NUM_7, + .dout = I2S_GPIO_UNUSED, + .din = GPIO_NUM_19 + }; + i2s_chan_config_t rx_chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, rx_pin); + /* rx channel will be registered on another I2S, if no other available I2S unit found + * it will return ESP_ERR_NOT_FOUND */ + i2s_new_channel(&rx_chan_cfg, NULL, &rx_handle); + i2s_std_slot_config_t rx_slot_cfg = I2S_STD_MSB_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_STEREO); + i2s_std_clk_config_t rx_clk_cfg = I2S_STD_CLK_CONFIG(16000); + i2s_init_channel(rx_handle, &rx_clk_cfg, &rx_slot_cfg); + i2s_start_channel(rx_handle); + +.. only:: SOC_I2S_HW_VERSION_2 + + Simplex Mode + ^^^^^^^^^^^^ + + To apply the simplex mode, :c:func:`i2s_new_channel` should be called for each channel. The clock and gpio pins of TX/RX channel on {IDF_TARGET_NAME} are separate, they can be configured in different modes and clocks, and they are able to coexist on a same I2S port in simplex mode. So PDM duplex can be realized by registering PDM TX simplex and PDM RX simplex on a same I2S port. But in this way, PDM TX/RX might work with different clocks, take care when configuring the gpio pins and clocks. + + The following codes offer an example for the simplex mode, but note that, although the internal MCLK signals for tx and rx channel are separate, the output MCLK can only be bound to one of them, if both channel initialized MCLK, it depends on which is initialized later. + +1. Determine the interrupt interval. Generally, when data lost happened, the interval should be the bigger the better, it can help to reduce the interrupt times, i.e., ``dma_frame_num`` should be as big as possible while the DMA buffer size won't exceed its maximum value 4092. The relationships are:: + + #include "driver/i2s_controller.h" + #include "driver/gpio.h" + + i2s_chan_handle_t tx_handle; + i2s_chan_handle_t rx_handle; + i2s_gpio_config_t tx_pin = { + .mclk = GPIO_NUM_0, + .bclk = GPIO_NUM_4, + .ws = GPIO_NUM_5, + .dout = GPIO_NUM_18, + .din = I2S_GPIO_UNUSED + }; + i2s_chan_config_t tx_chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, tx_pin); + tx_chan_cfg.id = I2S_NUM_0; // Specify the port id + i2s_new_channel(&tx_chan_cfg, &tx_handle, NULL); + i2s_std_slot_config_t tx_slot_cfg = I2S_STD_PHILIP_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO); + tx_slot_cfg.auto_clear = false; + i2s_std_clk_config_t tx_clk_cfg = I2S_STD_CLK_CONFIG(48000); + i2s_init_channel(tx_handle, &tx_clk_cfg, &tx_slot_cfg); + i2s_start_channel(tx_handle); + + i2s_gpio_config_t rx_pin = { + .mclk = I2S_GPIO_UNUSED, + .bclk = GPIO_NUM_6, + .ws = GPIO_NUM_7, + .dout = I2S_GPIO_UNUSED, + .din = GPIO_NUM_19 + }; + i2s_chan_config_t rx_chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, rx_pin); + tx_chan_cfg.id = I2S_NUM_0; // Specify the port id + i2s_new_channel(&rx_chan_cfg, NULL, &rx_handle); + i2s_std_slot_config_t rx_slot_cfg = I2S_STD_MSB_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_STEREO); + i2s_std_clk_config_t rx_clk_cfg = I2S_STD_CLK_CONFIG(16000); + i2s_init_channel(rx_handle, &rx_clk_cfg, &rx_slot_cfg); + i2s_start_channel(rx_handle); Application Notes -^^^^^^^^^^^^^^^^^ +----------------- -For the applications that need a high frequency sample rate, sometimes the massive throughput of receiving data may cause data lost. Users can receive data loss event by the event queue, it will trigger an ``I2S_EVENT_RX_Q_OVF`` event.: +How to Prevent Data Lost +^^^^^^^^^^^^^^^^^^^^^^^^ - .. code-block:: c +For the applications that need a high frequency sample rate, sometimes the massive throughput of receiving data may cause data lost. Users can receive data lost event by the event queue: - QueueHandle_t evt_que; - i2s_driver_install(i2s_num, &i2s_config, 10, &evt_que); + dma_desc_num > polling_cycle / interrupt_interval + + QueueHandle_t evt_que = i2s_get_event_queue(rx_handle, 10); ... i2s_event_t evt; xQueueReceive(evt_que, &evt, portMAX_DELAY); @@ -363,31 +630,31 @@ For the applications that need a high frequency sample rate, sometimes the massi printf("RX data dropped\n"); } -Please follow these steps to calculate the parameters that can prevent data lost: +Please follow these steps to prevent data lost: 1. Determine the interrupt interval. Generally, when data lost happened, the interval should be the bigger the better, it can help to reduce the interrupt times, i.e., ``dma_frame_num`` should be as big as possible while the DMA buffer size won't exceed its maximum value 4092. The relationships are:: interrupt_interval(unit: sec) = dma_frame_num / sample_rate - dma_buffer_size = dma_frame_num * channel_num * data_bit_width / 8 <= 4092 + dma_buffer_size = dma_frame_num * slot_num * data_bit_width / 8 <= 4092 -2. Determine the ``dma_desc_num``. The ``dma_desc_num`` is decided by the max time of ``i2s_read`` polling cycle, all the data should be stored between two ``i2s_read``. This cycle can be measured by a timer or an outputting gpio signal. The relationship should be:: +2. Determine the ``dma_desc_num``. The ``dma_desc_num`` is decided by the max time of ``i2s_read_channel`` polling cycle, we need to guarantee all the data can be stored between two ``i2s_read_channel``. This cycle can be measured by a timer or an outputting gpio signal. The relationship is:: dma_desc_num > polling_cycle / interrupt_interval -3. Determine the receiving buffer size. The receiving buffer that offered by user in ``i2s_read`` should be able to take all the data in all dma buffers, that means it should be bigger than the total size of all the dma buffers:: +3. Determine the receiving buffer size. The receiving buffer that offered by user in ``i2s_read_channel`` should be able to take all the data in all dma buffers, that means it should be bigger than the total size of all the dma buffers:: recv_buffer_size > dma_desc_num * dma_buffer_size -For example, if there is a I2S application:: +For example, if there is a I2S application, we have known these values:: sample_rate = 144000 Hz data_bit_width = 32 bits - channel_num = 2 + slot_num = 2 polling_cycle = 10ms -Then we need to calculate ``dma_frame_num``, ``dma_desc_num`` and ``recv_buf_size`` according to the known values:: +Then we need to calculate ``dma_frame_num``, ``dma_desc_num`` and ``recv_buf_size`` according to the given known values:: - dma_frame_num * channel_num * data_bit_width / 8 = dma_buffer_size <= 4092 + dma_frame_num * slot_num * data_bit_width / 8 = dma_buffer_size <= 4092 dma_frame_num <= 511 interrupt_interval = dma_frame_num / sample_rate = 511 / 144000 = 0.003549 s = 3.549 ms dma_desc_num > polling_cycle / interrupt_interval = cell(10 / 3.549) = cell(2.818) = 3 @@ -397,6 +664,41 @@ Then we need to calculate ``dma_frame_num``, ``dma_desc_num`` and ``recv_buf_siz API Reference ------------- -.. include-build-file:: inc/i2s.inc -.. include-build-file:: inc/i2s_types.inc +.. _i2s-api-reference-i2s_std: +Standard Mode +^^^^^^^^^^^^^ + +.. include-build-file:: inc/i2s_std.inc + +.. only:: SOC_I2S_SUPPORTS_PDM + + .. _i2s-api-reference-i2s_pdm: + + PDM Mode + ^^^^^^^^ + + .. include-build-file:: inc/i2s_pdm.inc + +.. only:: SOC_I2S_SUPPORTS_TDM + + .. _i2s-api-reference-i2s_tdm: + + TDM Mode + ^^^^^^^^ + + .. include-build-file:: inc/i2s_tdm.inc + +.. _i2s-api-reference-i2s_driver: + +I2S Driver +^^^^^^^^^^ + +.. include-build-file:: inc/i2s_controller.inc + +.. _i2s-api-reference-i2s_types: + +I2S Types +^^^^^^^^^ + +.. include-build-file:: inc/i2s_types.inc diff --git a/docs/en/migration-guides/peripherals.rst b/docs/en/migration-guides/peripherals.rst index e951ef55cb..479894c145 100644 --- a/docs/en/migration-guides/peripherals.rst +++ b/docs/en/migration-guides/peripherals.rst @@ -254,4 +254,64 @@ LCD Dedicated GPIO Driver --------------------- - - All of the dedicated GPIO related LL functionsn in ``cpu_ll.h`` have been moved to ``dedic_gpio_cpu_ll.h`` and renamed. \ No newline at end of file + - All of the dedicated GPIO related LL functionsn in ``cpu_ll.h`` have been moved to ``dedic_gpio_cpu_ll.h`` and renamed. + +I2S driver +---------- + +Since the old driver is unable to support all the new features on ESP32-C3 & ESP32-S3, I2S driver is re-designed to make it more compatibile and flexibile to all the communication modes. New APIs are available by including :component_file:`driver/include/driver/i2s_controller.h`. Meanwhile, the old APIs in :component_file:`driver/deprecated/driver/i2s.h` are still supported for backward compatibility. But there will be warnings if you keep using the old APIs in your project, these warnings can be suppressed by the Kconfig option :ref:`CONFIG_I2S_SUPPRESS_DEPRECATE_WARN`. Here is the general overview of the current I2S files: + +.. figure:: ../../_static/diagrams/i2s/i2s_file_structure.png + :align: center + :alt: I2S File Structure + +Breaking changes in Concepts +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- The minimum control unit in new I2S driver will be tx/rx channel instead of a whole I2S controller. + + 1. The tx/rx channel in a same I2S controller can be controlled separately, that means they will be initialized, started or stopped separately. Especially for ESP32-C3 and ESP32-S3, tx and rx channels in one controller can be configured to different clocks or modes now, they are able to work in a totally separate way which can help to save the resources of I2S controller. But for ESP32 and ESP32-S2, though their tx/rx can be controlled separately, some hardware resources are still shared by tx and rx, they might affect each other if they are configured to different configurations; + 2. The channels can be registered to an available I2S controller automatically by choosing :cpp:member:`i2s_port_t::I2S_NUM_AUTO` as I2S port id. The driver will help you to search for the available tx/rx channel. Of cause, you can still choose a specific port for it; + 3. :c:type:`i2s_chan_handle_t` is the handle that used for identifying the I2S channels. All the APIs will require the channel handle, users need to maintain the channel handles by themselves; + 4. In order to distinguish tx/rx channel and sound channel, now the word 'channel' is only stand for the tx/rx channel in new driver, meanwhile the sound channel will be called 'slot'. + +- I2S communication modes are extracted into three modes. + + 1. **Standard mode**: Standard mode always has two slots, it can support Philip, MSB and PCM(short sync) format, please refer to :component_file:`hal/include/hal/i2s_std.h` for details; + 2. **PDM mode**: PDM mode only support two slots with 16 bits data width, but the configurations of PDM TX and PDM RX are little bit different. For PDM TX, the sample rate can be set by :cpp:member:`i2s_pdm_tx_clk_config_t::sample_rate`, and its clock frequency is depended on the up-sampling configuration. For PDM RX, the sample rate can be set by :cpp:member:`i2s_pdm_rx_clk_config_t::sample_rate`, and its clock frequency is depended on the down-sampling configuration. Please refer to :component_file:`hal/include/hal/i2s_pdm.h` for details; + 3. **TDM mode**: TDM mode can support upto 16 slots. It can work in Philip, MSB, PCM(short sync) and PCM(long sync) format, please refer to :component_file:`hal/include/hal/i2s_tdm.h` for details; + 4. When we allocate a new channel in a specific mode, we must initialize this channel by corresponding slot configurations and clock configurations. We strongly recommend to use the helper macros to generate the default configurations, in case the default values will be changed one day. + 5. Although there are three modes, they still share some general slot and clock configurations which are defined in :component_file:`hal/include/hal/i2s_hal.h` + +- States and state-machine are adopted in the new I2S driver to avoid APIs are called in wrong state. + +- The slot configurations and clock configurations can be configured separately. + + 1. Calling :func:`i2s_init_channel` to initialize the slot/clock/gpio_pin configurations; + 2. Calling :c:func:`i2s_set_slot` can change the slot configurations after initialization; + 3. Calling :c:func:`i2s_set_clock` can change the clock configurations after initialization. + +- ADC and DAC modes are removed. They will only be supported in their own driver and legacy I2S driver. + +- :c:func:`i2s_write_channel` and :c:func:`i2s_read_channel` can be aborted by :c:func:`i2s_abort_reading_writing` now. + +Breaking Changes in Usage +~~~~~~~~~~~~~~~~~~~~~~~~~ + +To use the new I2S driver, please follow these steps: + +1. Calling :c:func:`i2s_new_channel` to aquire the channel handles. We should specify the GPIO pins, work mode, work role and I2S port in this step. Besides, we need to input the tx or rx handle to acuire the channel handles that generated by the driver. We don't have to input both two tx and rx handles but at least one handle is needed. While we input both two handles, the driver will work in duplex mode, both tx and rx channel will be avaliable on a same port, and they will share the MCLK, BCLK and WS signal, there will be MCLK(optional), BCLK, WS, DATA_IN and DATA_OUT signals in this case. But if we only input tx or rx handle, this channel will only work in simplex mode. + +2. Calling :c:func:`i2s_init_channel` to initialize the channel that specified by the given channel handle. We are supposed to input corresponding slot and clock configurations according to the mode that we set in the first step. + +3. (Optional) We can acquire the event queue handle by :c:func:`i2s_get_event_queue` if we want to monitor the I2S event. + +4. Calling :c:func:`i2s_start_channel` to start the I2S channel. In the new driver, I2S won't start automatically after installed anymore, we are supposed to know clearly whether the channel has started or not. + +5. Reading or writing data by :c:func:`i2s_read_channel` or :c:func:`i2s_write_channel`. Of cause we can only use rx channel handle in :c:func:`i2s_read_channel` and tx channel handle in :c:func:`i2s_write_channel`. + +6. (Optional) We can clear the legacy data in DMA buffer by :c:func:`i2s_clear_dma_buffer`. If we need the driver clear the tx dma buffer automatically, we can set :c:member`auto_clear` in slot configurations. + +7. (Optional) We can change the slot and clock configurations after initialized by :c:func:`i2s_set_slot`, :c:func:`i2s_set_clock`, but we have to call :c:func:`i2s_stop_channel` before we update the configurations. + +8. (Optional) We can delete the i2s channel by calling :c:func:`i2s_del_channel` if we don't need it any more. The related resources will be released if delete function is called. diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_av.c b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_av.c index eaf6f3d47b..6eb9009a9a 100644 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_av.c +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_av.c @@ -20,7 +20,12 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" +#ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC +// DAC DMA mode is only supported by the legacy I2S driver, it will be replaced once DAC has its own DMA dirver #include "driver/i2s.h" +#else +#include "driver/i2s_controller.h" +#endif #include "sys/lock.h" @@ -82,6 +87,9 @@ static _lock_t s_volume_lock; static TaskHandle_t s_vcs_task_hdl = NULL; /* handle for volume change simulation task */ static uint8_t s_volume = 0; /* local volume value */ static bool s_volume_notify; /* notify volume change or not */ +#ifndef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC +i2s_chan_handle_t tx_chan = NULL; +#endif /******************************** * STATIC FUNCTION DEFINITIONS @@ -160,13 +168,10 @@ static void bt_av_notify_evt_handler(uint8_t event_id, esp_avrc_rn_param_t *even void bt_i2s_driver_install(void) { +#ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC /* I2S configuration parameters */ i2s_config_t i2s_config = { -#ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC .mode = I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN, -#else - .mode = I2S_MODE_MASTER | I2S_MODE_TX, /* only TX */ -#endif .sample_rate = 44100, .bits_per_sample = 16, .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, /* 2-channels */ @@ -179,23 +184,35 @@ void bt_i2s_driver_install(void) /* enable I2S */ i2s_driver_install(0, &i2s_config, 0, NULL); -#ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN); i2s_set_pin(0, NULL); #else - i2s_pin_config_t pin_config = { - .bck_io_num = CONFIG_EXAMPLE_I2S_BCK_PIN, - .ws_io_num = CONFIG_EXAMPLE_I2S_LRCK_PIN, - .data_out_num = CONFIG_EXAMPLE_I2S_DATA_PIN, - .data_in_num = -1 /* not used */ + i2s_gpio_config_t i2s_pin = { + .mclk = I2S_GPIO_UNUSED, + .bclk = CONFIG_EXAMPLE_I2S_BCK_PIN, + .ws = CONFIG_EXAMPLE_I2S_LRCK_PIN, + .dout = CONFIG_EXAMPLE_I2S_DATA_PIN, + .din = I2S_GPIO_UNUSED }; - i2s_set_pin(0, &pin_config); + i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); + chan_cfg.id = I2S_NUM_0; + i2s_std_slot_config_t slot_cfg = I2S_STD_MSB_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO); + slot_cfg.auto_clear = true; + i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(44100); + /* enable I2S */ + i2s_new_channel(&chan_cfg, &tx_chan, NULL); + i2s_init_channel(tx_chan, &clk_cfg, &slot_cfg); + i2s_start_channel(tx_chan); #endif } void bt_i2s_driver_uninstall(void) { +#ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC i2s_driver_uninstall(0); +#else + i2s_del_channel(tx_chan); +#endif } static void volume_set_by_controller(uint8_t volume) @@ -286,8 +303,12 @@ static void bt_av_hdl_a2d_evt(uint16_t event, void *p_param) } else if (oct0 & (0x01 << 4)) { sample_rate = 48000; } + #ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC i2s_set_clk(0, sample_rate, 16, 2); - + #else + i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(sample_rate); + i2s_set_clock(tx_chan, &clk_cfg); + #endif ESP_LOGI(BT_AV_TAG, "Configure audio player: %x-%x-%x-%x", a2d->audio_cfg.mcc.cie.sbc[0], a2d->audio_cfg.mcc.cie.sbc[1], diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_core.c b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_core.c index fadec503d7..5ede922e62 100644 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_core.c +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_core.c @@ -14,7 +14,12 @@ #include "freertos/task.h" #include "esp_log.h" #include "bt_app_core.h" +#ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC +// DAC DMA mode is only supported by the legacy I2S driver, it will be replaced once DAC has its own DMA dirver #include "driver/i2s.h" +#else +#include "driver/i2s_controller.h" +#endif #include "freertos/ringbuf.h" /******************************* @@ -38,6 +43,9 @@ static QueueHandle_t s_bt_app_task_queue = NULL; /* handle of work queue */ static TaskHandle_t s_bt_app_task_handle = NULL; /* handle of application task */ static TaskHandle_t s_bt_i2s_task_handle = NULL; /* handle of I2S task */ static RingbufHandle_t s_ringbuf_i2s = NULL; /* handle of ringbuffer for I2S */ +#ifndef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC +extern i2s_chan_handle_t tx_chan; +#endif /******************************* * STATIC FUNCTION DEFINITIONS @@ -99,7 +107,11 @@ static void bt_i2s_task_handler(void *arg) /* receive data from ringbuffer and write it to I2S DMA transmit buffer */ data = (uint8_t *)xRingbufferReceive(s_ringbuf_i2s, &item_size, (TickType_t)portMAX_DELAY); if (item_size != 0){ + #ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC i2s_write(0, data, item_size, &bytes_written, portMAX_DELAY); + #else + i2s_write_channel(tx_chan, data, item_size, &bytes_written, portMAX_DELAY); + #endif vRingbufferReturnItem(s_ringbuf_i2s, (void *)data); } } diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/main.c b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/main.c index b0b1efb7cf..5522979489 100644 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/main.c +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/main.c @@ -23,7 +23,6 @@ #include "esp_gap_bt_api.h" #include "esp_a2dp_api.h" #include "esp_avrc_api.h" -#include "driver/i2s.h" /* device name */ #define LOCAL_DEVICE_NAME "ESP_SPEAKER" diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/sdkconfig.defaults b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/sdkconfig.defaults index bdbd39fdea..b3b61d904d 100644 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/sdkconfig.defaults +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/sdkconfig.defaults @@ -7,3 +7,4 @@ CONFIG_BTDM_CTRL_MODE_BTDM=n CONFIG_BT_BLUEDROID_ENABLED=y CONFIG_BT_CLASSIC_ENABLED=y CONFIG_BT_A2DP_ENABLE=y +CONFIG_I2S_SUPPRESS_DEPRECATE_WARN=y diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/tutorial/Example_A2DP_Sink.md b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/tutorial/Example_A2DP_Sink.md index dc304ef058..80e25c90ef 100644 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/tutorial/Example_A2DP_Sink.md +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/tutorial/Example_A2DP_Sink.md @@ -88,36 +88,29 @@ The main function installs I2S to play the audio. A loudspeaker, additional ADC ```c /* I2S configuration parameters */ - i2s_config_t i2s_config = { -#ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC - .mode = I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN, -#else - .mode = I2S_MODE_MASTER | I2S_MODE_TX, /* only TX */ -#endif - .sample_rate = 44100, - .bits_per_sample = 16, - .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, /* 2-channels */ - .communication_format = I2S_COMM_FORMAT_STAND_MSB, - .dma_buf_count = 6, - .dma_buf_len = 60, - .intr_alloc_flags = 0, /* default interrupt priority */ - .tx_desc_auto_clear = true /* auto clear tx descriptor on underflow */ - }; - - /* enable I2S */ - i2s_driver_install(0, &i2s_config, 0, NULL); -#ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC - i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN); - i2s_set_pin(0, NULL); -#else - i2s_pin_config_t pin_config = { - .bck_io_num = CONFIG_EXAMPLE_I2S_BCK_PIN, - .ws_io_num = CONFIG_EXAMPLE_I2S_LRCK_PIN, - .data_out_num = CONFIG_EXAMPLE_I2S_DATA_PIN, - .data_in_num = -1 /* not used */ - }; - i2s_set_pin(0, &pin_config); -#endif + #ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC + i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_ADC_DAC, NULL); + chan_cfg.id = I2S_NUM_0; + i2s_dac_slot_config_t slot_cfg = I2S_DAC_SLOT_CONFIG(I2S_DAC_CHAN_BOTH); + i2s_adc_dac_clk_config_t clk_cfg = I2S_ADC_DAC_CLK_CONFIG(44100); + #else + i2s_gpio_config_t i2s_pin = { + .mclk = I2S_GPIO_UNUSED, + .bclk = CONFIG_EXAMPLE_I2S_BCK_PIN, + .ws = CONFIG_EXAMPLE_I2S_LRCK_PIN, + .dout = CONFIG_EXAMPLE_I2S_DATA_PIN, + .din = I2S_GPIO_UNUSED + }; + i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); + chan_cfg.id = I2S_NUM_0; + i2s_std_slot_config_t slot_cfg = I2S_STD_MSB_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO); + slot_cfg.auto_clear = true; + i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(44100); + #endif + /* enable I2S */ + i2s_new_channel(&chan_cfg, &tx_chan, NULL); + i2s_init_channel(tx_chan, &clk_cfg, &slot_cfg); + i2s_start_channel(tx_chan); ``` ### Paring Parameter Settings diff --git a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_av.c b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_av.c index 2568928ba9..ee5eb98eae 100644 --- a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_av.c +++ b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_av.c @@ -21,7 +21,12 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" +#ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC +// DAC DMA mode is only supported by the legacy I2S driver, it will be replaced once DAC has its own DMA dirver #include "driver/i2s.h" +#else +#include "driver/i2s_controller.h" +#endif #include "sys/lock.h" @@ -48,6 +53,9 @@ static _lock_t s_volume_lock; static TaskHandle_t s_vcs_task_hdl = NULL; static uint8_t s_volume = 0; static bool s_volume_notify; +#ifndef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC +extern i2s_chan_handle_t tx_chan; +#endif /* callback for A2DP sink */ void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param) @@ -162,7 +170,12 @@ static void bt_av_hdl_a2d_evt(uint16_t event, void *p_param) } else if (oct0 & (0x01 << 4)) { sample_rate = 48000; } + #ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC i2s_set_clk(0, sample_rate, 16, 2); + #else + i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(sample_rate); + i2s_set_clock(tx_chan, &clk_cfg); + #endif ESP_LOGI(BT_AV_TAG, "Configure audio player %x-%x-%x-%x", a2d->audio_cfg.mcc.cie.sbc[0], diff --git a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_core.c b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_core.c index f47551fb40..0263e70144 100644 --- a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_core.c +++ b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_core.c @@ -14,8 +14,13 @@ #include "freertos/task.h" #include "esp_log.h" #include "bt_app_core.h" -#include "driver/i2s.h" #include "freertos/ringbuf.h" +#ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC +// DAC DMA mode is only supported by the legacy I2S driver, it will be replaced once DAC has its own DMA dirver +#include "driver/i2s.h" +#else +#include "driver/i2s_controller.h" +#endif static void bt_app_task_handler(void *arg); static bool bt_app_send_msg(bt_app_msg_t *msg); @@ -24,7 +29,10 @@ static void bt_app_work_dispatched(bt_app_msg_t *msg); static QueueHandle_t s_bt_app_task_queue = NULL; static TaskHandle_t s_bt_app_task_handle = NULL; static TaskHandle_t s_bt_i2s_task_handle = NULL; -static RingbufHandle_t s_ringbuf_i2s = NULL;; +static RingbufHandle_t s_ringbuf_i2s = NULL; +#ifndef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC +extern i2s_chan_handle_t tx_chan; +#endif bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, int param_len, bt_app_copy_cb_t p_copy_cback) { @@ -123,7 +131,11 @@ static void bt_i2s_task_handler(void *arg) for (;;) { data = (uint8_t *)xRingbufferReceive(s_ringbuf_i2s, &item_size, (TickType_t)portMAX_DELAY); if (item_size != 0){ + #ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC i2s_write(0, data, item_size, &bytes_written, portMAX_DELAY); + #else + i2s_write_channel(tx_chan, data, item_size, &bytes_written, portMAX_DELAY); + #endif vRingbufferReturnItem(s_ringbuf_i2s,(void *)data); } } diff --git a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/main.c b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/main.c index 02bdff168a..517ce7f114 100644 --- a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/main.c +++ b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -35,7 +35,12 @@ #include "esp_gap_bt_api.h" #include "esp_a2dp_api.h" #include "esp_avrc_api.h" +#ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC +// DAC DMA mode is only supported by the legacy I2S driver, it will be replaced once DAC has its own DMA dirver #include "driver/i2s.h" +#else +#include "driver/i2s_controller.h" +#endif #include "esp_gap_ble_api.h" #include "esp_gatts_api.h" @@ -70,6 +75,10 @@ typedef struct { static prepare_type_env_t a_prepare_write_env; static prepare_type_env_t b_prepare_write_env; +#ifndef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC +i2s_chan_handle_t tx_chan; +#endif + //Declare the static function static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param); static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param); @@ -681,36 +690,41 @@ void app_main(void) } ESP_ERROR_CHECK(err); - i2s_config_t i2s_config = { #ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC + /* I2S configuration parameters */ + i2s_config_t i2s_config = { .mode = I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN, -#else - .mode = I2S_MODE_MASTER | I2S_MODE_TX, // Only TX -#endif - .communication_format = I2S_COMM_FORMAT_STAND_MSB, .sample_rate = 44100, .bits_per_sample = 16, - .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, //2-channels - .dma_desc_num = 6, - .dma_frame_num = 60, - .intr_alloc_flags = 0, //Default interrupt priority - .tx_desc_auto_clear = true //Auto clear tx descriptor on underflow + .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, /* 2-channels */ + .communication_format = I2S_COMM_FORMAT_STAND_MSB, + .dma_buf_count = 6, + .dma_buf_len = 60, + .intr_alloc_flags = 0, /* default interrupt priority */ + .tx_desc_auto_clear = true /* auto clear tx descriptor on underflow */ }; - + /* enable I2S */ i2s_driver_install(0, &i2s_config, 0, NULL); -#ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN); i2s_set_pin(0, NULL); #else - i2s_pin_config_t pin_config = { - .bck_io_num = CONFIG_EXAMPLE_I2S_BCK_PIN, - .ws_io_num = CONFIG_EXAMPLE_I2S_LRCK_PIN, - .data_out_num = CONFIG_EXAMPLE_I2S_DATA_PIN, - .data_in_num = -1 //Not used + i2s_gpio_config_t i2s_pin = { + .mclk = I2S_GPIO_UNUSED, + .bclk = CONFIG_EXAMPLE_I2S_BCK_PIN, + .ws = CONFIG_EXAMPLE_I2S_LRCK_PIN, + .dout = CONFIG_EXAMPLE_I2S_DATA_PIN, + .din = I2S_GPIO_UNUSED }; - - i2s_set_pin(0, &pin_config); + i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); + chan_cfg.id = I2S_NUM_0; + i2s_std_slot_config_t slot_cfg = I2S_STD_MSB_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO); + slot_cfg.auto_clear = true; + i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(44100); + /* enable I2S */ + i2s_new_channel(&chan_cfg, &tx_chan, NULL); + i2s_init_channel(tx_chan, &clk_cfg, &slot_cfg); + i2s_start_channel(tx_chan); #endif esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); diff --git a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/sdkconfig.defaults b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/sdkconfig.defaults index ee81cabedd..a8ae54ee17 100644 --- a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/sdkconfig.defaults +++ b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/sdkconfig.defaults @@ -29,3 +29,4 @@ CONFIG_BT_ACL_CONNECTIONS=4 CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST=n CONFIG_BT_BLE_DYNAMIC_ENV_MEMORY=n CONFIG_BT_SMP_ENABLE=y +CONFIG_I2S_SUPPRESS_DEPRECATE_WARN=y diff --git a/examples/peripherals/i2s/i2s_adc_dac/main/app_main.c b/examples/peripherals/i2s/i2s_adc_dac/main/app_main.c index 9bb0a0522c..de467a6e0c 100644 --- a/examples/peripherals/i2s/i2s_adc_dac/main/app_main.c +++ b/examples/peripherals/i2s/i2s_adc_dac/main/app_main.c @@ -1,3 +1,13 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +/* ADC/DAC are supported in the new I2S driver, but still available in the legacy I2S driver for backward compatibility + * Please turn to the dedicated ADC/DAC driver instead */ +#pragma message("ADC/DAC on ESP32 will no longer supported via I2S driver") + #include #include #include "freertos/FreeRTOS.h" @@ -13,7 +23,6 @@ #include "esp_rom_sys.h" #if CONFIG_IDF_TARGET_ESP32 - static const char* TAG = "ad/da"; #define V_REF 1100 #define ADC1_TEST_CHANNEL (ADC1_CHANNEL_7) diff --git a/examples/peripherals/i2s/i2s_adc_dac/main/audio_example_file.h b/examples/peripherals/i2s/i2s_adc_dac/main/audio_example_file.h index 6723c6fc2b..b865ad74df 100644 --- a/examples/peripherals/i2s/i2s_adc_dac/main/audio_example_file.h +++ b/examples/peripherals/i2s/i2s_adc_dac/main/audio_example_file.h @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ #include const unsigned char audio_table[] = { 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x80, 0x81, 0x81, 0x7e, 0x7a, 0x79, 0x79, 0x7c, 0x81, 0x82, 0x82, diff --git a/examples/peripherals/i2s/i2s_adc_dac/sdkconfig.defaults b/examples/peripherals/i2s/i2s_adc_dac/sdkconfig.defaults new file mode 100644 index 0000000000..71e36947d0 --- /dev/null +++ b/examples/peripherals/i2s/i2s_adc_dac/sdkconfig.defaults @@ -0,0 +1,5 @@ +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_adc_dac_example.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions_adc_dac_example.csv" +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +CONFIG_I2S_SUPPRESS_DEPRECATE_WARN=y diff --git a/examples/peripherals/i2s/i2s_adc_dac/tools/generate_audio_file.py b/examples/peripherals/i2s/i2s_adc_dac/tools/generate_audio_file.py index faa8d6bf2c..edc4ae3ea0 100644 --- a/examples/peripherals/i2s/i2s_adc_dac/tools/generate_audio_file.py +++ b/examples/peripherals/i2s/i2s_adc_dac/tools/generate_audio_file.py @@ -1,3 +1,5 @@ +# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Unlicense OR CC0-1.0 from __future__ import print_function import os diff --git a/examples/peripherals/i2s/i2s_audio_recorder_sdcard/main/i2s_recorder_main.c b/examples/peripherals/i2s/i2s_audio_recorder_sdcard/main/i2s_recorder_main.c index c8002b62ca..eea6b6cbf3 100644 --- a/examples/peripherals/i2s/i2s_audio_recorder_sdcard/main/i2s_recorder_main.c +++ b/examples/peripherals/i2s/i2s_audio_recorder_sdcard/main/i2s_recorder_main.c @@ -1,11 +1,10 @@ -/* I2S Digital Microphone Recording Example +/* + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ +/* I2S Digital Microphone Recording Example */ #include #include #include @@ -17,7 +16,7 @@ #include "esp_vfs_fat.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#include "driver/i2s.h" +#include "driver/i2s_controller.h" #include "driver/gpio.h" #include "driver/spi_common.h" #include "sdmmc_cmd.h" @@ -36,6 +35,7 @@ static const char* TAG = "pdm_rec_example"; // toggling power to the card. sdmmc_host_t host = SDSPI_HOST_DEFAULT(); sdmmc_card_t* card; +i2s_chan_handle_t rx_handle = NULL; static int16_t i2s_readraw_buff[SAMPLE_SIZE]; size_t bytes_read; @@ -123,6 +123,11 @@ void record_wav(uint32_t rec_time) char wav_header_fmt[WAVE_HEADER_SIZE]; + if (rx_handle == NULL) { + ESP_LOGE(TAG, "I2S channel has not been registered yet"); + return; + } + uint32_t flash_rec_time = BYTE_RATE * rec_time; generate_wav_header(wav_header_fmt, flash_rec_time, CONFIG_EXAMPLE_SAMPLE_RATE); @@ -146,7 +151,7 @@ void record_wav(uint32_t rec_time) // Start recording while (flash_wr_size < flash_rec_time) { // Read the RAW samples from the microphone - i2s_read(CONFIG_EXAMPLE_I2S_CH, (char *)i2s_readraw_buff, SAMPLE_SIZE, &bytes_read, 100); + i2s_read_channel(rx_handle, (char *)i2s_readraw_buff, SAMPLE_SIZE, &bytes_read, 100); // Write the samples to the WAV file fwrite(i2s_readraw_buff, 1, bytes_read, f); flash_wr_size += bytes_read; @@ -165,32 +170,20 @@ void record_wav(uint32_t rec_time) void init_microphone(void) { - // Set the I2S configuration as PDM and 16bits per sample - i2s_config_t i2s_config = { - .mode = I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_PDM, - .sample_rate = CONFIG_EXAMPLE_SAMPLE_RATE, - .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, - .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT, - .communication_format = I2S_COMM_FORMAT_STAND_I2S, - .intr_alloc_flags = ESP_INTR_FLAG_LEVEL2, - .dma_desc_num = 8, - .dma_frame_num = 200, - .use_apll = 0, + i2s_gpio_config_t i2s_pin = { + .mclk = I2S_GPIO_UNUSED, + .bclk = I2S_GPIO_UNUSED, + .ws = CONFIG_EXAMPLE_I2S_CLK_GPIO, + .dout = I2S_GPIO_UNUSED, + .din = CONFIG_EXAMPLE_I2S_DATA_GPIO }; - - // Set the pinout configuration (set using menuconfig) - i2s_pin_config_t pin_config = { - .mck_io_num = I2S_PIN_NO_CHANGE, - .bck_io_num = I2S_PIN_NO_CHANGE, - .ws_io_num = CONFIG_EXAMPLE_I2S_CLK_GPIO, - .data_out_num = I2S_PIN_NO_CHANGE, - .data_in_num = CONFIG_EXAMPLE_I2S_DATA_GPIO, - }; - - // Call driver installation function before any I2S R/W operation. - ESP_ERROR_CHECK( i2s_driver_install(CONFIG_EXAMPLE_I2S_CH, &i2s_config, 0, NULL) ); - ESP_ERROR_CHECK( i2s_set_pin(CONFIG_EXAMPLE_I2S_CH, &pin_config) ); - ESP_ERROR_CHECK( i2s_set_clk(CONFIG_EXAMPLE_I2S_CH, CONFIG_EXAMPLE_SAMPLE_RATE, I2S_BITS_PER_SAMPLE_16BIT, I2S_CHANNEL_MONO) ); + i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_PDM, &i2s_pin); + chan_cfg.id = CONFIG_EXAMPLE_I2S_CH; + i2s_new_channel(&chan_cfg, NULL, &rx_handle); + i2s_pdm_rx_slot_config_t rx_slot_cfg = I2S_PDM_RX_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO); + i2s_pdm_rx_clk_config_t rx_clk_cfg = I2S_PDM_RX_CLK_CONFIG(CONFIG_EXAMPLE_SAMPLE_RATE); + i2s_init_channel(rx_handle, &rx_clk_cfg, &rx_slot_cfg); + i2s_start_channel(rx_handle); } void app_main(void) @@ -198,11 +191,11 @@ void app_main(void) ESP_LOGI(TAG, "PDM microphone recording Example start"); // Mount the SDCard for recording the audio file mount_sdcard(); - // Init the PDM digital microphone + // Acquire a I2S PDM channel for the PDM digital microphone init_microphone(); ESP_LOGI(TAG, "Starting recording for %d seconds!", CONFIG_EXAMPLE_REC_TIME); // Start Recording record_wav(CONFIG_EXAMPLE_REC_TIME); // Stop I2S driver and destroy - ESP_ERROR_CHECK( i2s_driver_uninstall(CONFIG_EXAMPLE_I2S_CH) ); + ESP_ERROR_CHECK( i2s_del_channel(rx_handle) ); } diff --git a/examples/peripherals/i2s/i2s_basic/main/i2s_example_main.c b/examples/peripherals/i2s/i2s_basic/main/i2s_example_main.c index fdb7b08320..c73d2106a5 100644 --- a/examples/peripherals/i2s/i2s_basic/main/i2s_example_main.c +++ b/examples/peripherals/i2s/i2s_basic/main/i2s_example_main.c @@ -1,18 +1,16 @@ -/* I2S Example - - This example code will output 100Hz sine wave and triangle wave to 2-channel of I2S driver - Every 5 seconds, it will change bits_per_sample [16, 24, 32] for i2s data - - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ +/* + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +/* I2S Example + * This example code will output 100Hz sine wave and triangle wave to 2-channel of I2S driver + * Every 5 seconds, it will change bits_per_sample [16, 24, 32] for i2s data + */ #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#include "driver/i2s.h" +#include "driver/i2s_controller.h" #include "driver/gpio.h" #include "esp_system.h" #include "esp_log.h" @@ -30,27 +28,31 @@ #define SAMPLE_PER_CYCLE (SAMPLE_RATE/WAVE_FREQ_HZ) -static const char* TAG = "i2s_example"; +static const char *TAG = "i2s_example"; +static i2s_chan_handle_t tx_handle = NULL; static void setup_triangle_sine_waves(int bits) { - int *samples_data = malloc(((bits+8)/16)*SAMPLE_PER_CYCLE*4); + int *samples_data = malloc(((bits + 8) / 16) * SAMPLE_PER_CYCLE * 4); unsigned int i, sample_val; double sin_float, triangle_float, triangle_step = (double) pow(2, bits) / SAMPLE_PER_CYCLE; size_t i2s_bytes_write = 0; + static i2s_std_slot_config_t slot_cfg = I2S_STD_PHILIP_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO); + static i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(SAMPLE_RATE); - printf("\r\nTest bits=%d free mem=%d, written data=%d\n", bits, esp_get_free_heap_size(), ((bits+8)/16)*SAMPLE_PER_CYCLE*4); + printf("\r\nTest bits=%d free mem=%d, written data=%d\n", bits, esp_get_free_heap_size(), ((bits + 8) / 16)*SAMPLE_PER_CYCLE * 4); - triangle_float = -(pow(2, bits)/2 - 1); + triangle_float = -(pow(2, bits) / 2 - 1); - for(i = 0; i < SAMPLE_PER_CYCLE; i++) { + for (i = 0; i < SAMPLE_PER_CYCLE; i++) { sin_float = sin(i * 2 * PI / SAMPLE_PER_CYCLE); - if(sin_float >= 0) + if (sin_float >= 0) { triangle_float += triangle_step; - else + } else { triangle_float -= triangle_step; + } - sin_float *= (pow(2, bits)/2 - 1); + sin_float *= (pow(2, bits) / 2 - 1); if (bits == 16) { sample_val = 0; @@ -59,26 +61,34 @@ static void setup_triangle_sine_waves(int bits) sample_val += (short) sin_float; samples_data[i] = sample_val; } else if (bits == 24) { //1-bytes unused - samples_data[i*2] = ((int) triangle_float) << 8; - samples_data[i*2 + 1] = ((int) sin_float) << 8; + samples_data[i * 2] = ((int) triangle_float) << 8; + samples_data[i * 2 + 1] = ((int) sin_float) << 8; } else { - samples_data[i*2] = ((int) triangle_float); - samples_data[i*2 + 1] = ((int) sin_float); + samples_data[i * 2] = ((int) triangle_float); + samples_data[i * 2 + 1] = ((int) sin_float); } } - ESP_LOGI(TAG, "set clock"); - i2s_set_clk(I2S_NUM, SAMPLE_RATE, bits, 2); - //Using push - // for(i = 0; i < SAMPLE_PER_CYCLE; i++) { - // if (bits == 16) - // i2s_push_sample(0, &samples_data[i], 100); - // else - // i2s_push_sample(0, &samples_data[i*2], 100); - // } - // or write + ESP_LOGI(TAG, "set data bit width to %d", bits); + /* Updata clock and slot information */ + slot_cfg.data_bit_width = bits; + i2s_stop_channel(tx_handle); + i2s_set_slot(tx_handle, &slot_cfg); + if (bits == 24) { + /** + * Because '24' has factor '3' + * The mclk multiple must be able to divide by '3' as well + * Otherwise the sample rate won't be accurate */ + clk_cfg.mclk_multiple = I2S_MCLK_MULTIPLE_384; + i2s_set_clock(tx_handle, &clk_cfg); + } else { + clk_cfg.mclk_multiple = I2S_MCLK_MULTIPLE_256; + i2s_set_clock(tx_handle, &clk_cfg); + } + i2s_start_channel(tx_handle); + ESP_LOGI(TAG, "write data"); - i2s_write(I2S_NUM, samples_data, ((bits+8)/16)*SAMPLE_PER_CYCLE*4, &i2s_bytes_write, 100); + i2s_write_channel(tx_handle, samples_data, ((bits + 8) / 16)*SAMPLE_PER_CYCLE * 4, &i2s_bytes_write, 100); free(samples_data); } @@ -90,35 +100,32 @@ void app_main(void) //using 6 buffers, we need 60-samples per buffer //if 2-channels, 16-bit each channel, total buffer is 360*4 = 1440 bytes //if 2-channels, 24/32-bit each channel, total buffer is 360*8 = 2880 bytes - i2s_config_t i2s_config = { - .mode = I2S_MODE_MASTER | I2S_MODE_TX, - .sample_rate = SAMPLE_RATE, - .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, - .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, - .communication_format = I2S_COMM_FORMAT_STAND_MSB, - .dma_desc_num = 6, - .dma_frame_num = 60, - .use_apll = false, - .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1 //Interrupt level 1 + i2s_gpio_config_t i2s_pin = { + .mclk = I2S_GPIO_UNUSED, + .bclk = I2S_BCK_IO, + .ws = I2S_WS_IO, + .dout = I2S_DO_IO, + .din = I2S_DI_IO }; - i2s_pin_config_t pin_config = { - .mck_io_num = I2S_PIN_NO_CHANGE, - .bck_io_num = I2S_BCK_IO, - .ws_io_num = I2S_WS_IO, - .data_out_num = I2S_DO_IO, - .data_in_num = I2S_DI_IO //Not used - }; - i2s_driver_install(I2S_NUM, &i2s_config, 0, NULL); - i2s_set_pin(I2S_NUM, &pin_config); + i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); + chan_cfg.id = I2S_NUM; + i2s_new_channel(&chan_cfg, &tx_handle, NULL); + i2s_std_slot_config_t slot_cfg = I2S_STD_PHILIP_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO); + i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(SAMPLE_RATE); +#if SOC_I2S_SUPPORTS_APLL + // APLL clock is more accurate when sample rate is high + clk_cfg.clk_src = I2S_CLK_APLL; +#endif + i2s_init_channel(tx_handle, &clk_cfg, &slot_cfg); + i2s_start_channel(tx_handle); int test_bits = 16; while (1) { setup_triangle_sine_waves(test_bits); - vTaskDelay(5000/portTICK_PERIOD_MS); + vTaskDelay(pdMS_TO_TICKS(5000)); test_bits += 8; - if(test_bits > 32) + if (test_bits > 32) { test_bits = 16; - + } } - } diff --git a/examples/peripherals/i2s/i2s_es8311/README.md b/examples/peripherals/i2s/i2s_es8311/README.md index ba85c38279..fa3a2363ab 100644 --- a/examples/peripherals/i2s/i2s_es8311/README.md +++ b/examples/peripherals/i2s/i2s_es8311/README.md @@ -137,7 +137,7 @@ The example have contained a piece of music in canon.pcm, if you want to play yo 5. Transfer the music format into .pcm. ```ffmpeg -i a_cut.mp3 -f s16ls -ar 16000 -ac -1 -acodec pcm_s16le a.pcm``` 6. Move 'a.pcm' under 'main' directory 7. Replace 'canon.pcm' with 'a.pcm' in 'CMakeLists.txt' under 'main' directory -8. Replace '_binary_canon_pcm_start' and '_binary_canon_pcm_end' with '_binary_a_pcm_start' and '_binary_a_pcm_end' in `i2s_es9311_example.c`(line 46/47) +8. Replace '_binary_canon_pcm_start' and '_binary_canon_pcm_end' with '_binary_a_pcm_start' and '_binary_a_pcm_end' in `i2s_es8311_example.c`(line 46/47) 9. Download the example and enjoy your own music ## Troubleshooting diff --git a/examples/peripherals/i2s/i2s_es8311/main/i2s_es8311_example.c b/examples/peripherals/i2s/i2s_es8311/main/i2s_es8311_example.c index 07afe5b885..be824e3bbe 100644 --- a/examples/peripherals/i2s/i2s_es8311/main/i2s_es8311_example.c +++ b/examples/peripherals/i2s/i2s_es8311/main/i2s_es8311_example.c @@ -8,7 +8,7 @@ #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#include "driver/i2s.h" +#include "driver/i2s_controller.h" #include "esp_system.h" #include "esp_check.h" #include "es8311.h" @@ -34,7 +34,7 @@ /* Example configurations */ #define EXAMPLE_RECV_BUF_SIZE (2048) #define EXAMPLE_SAMPLE_RATE (16000) -#define EXAMPLE_MCLK_MULTIPLE I2S_MCLK_MULTIPLE_256 +#define EXAMPLE_MCLK_MULTIPLE (256) #define EXAMPLE_VOICE_VOLUME CONFIG_EXAMPLE_VOICE_VOLUME #if CONFIG_EXAMPLE_MODE_ECHO #define EXAMPLE_MIC_GAIN CONFIG_EXAMPLE_MIC_GAIN @@ -44,6 +44,8 @@ static const char *TAG = "i2s_es8311"; static const char err_reason[][30] = {"input param is invalid", "operation timeout" }; +static i2s_chan_handle_t tx_handle = NULL; +static i2s_chan_handle_t rx_handle = NULL; /* Import music file as buffer */ #if CONFIG_EXAMPLE_MODE_MUSIC @@ -73,7 +75,7 @@ static esp_err_t es8311_codec_init(void) .sample_frequency = EXAMPLE_SAMPLE_RATE }; - es8311_init(es_handle, &es_clk, ES8311_RESOLUTION_16, ES8311_RESOLUTION_16); + ESP_ERROR_CHECK(es8311_init(es_handle, &es_clk, ES8311_RESOLUTION_16, ES8311_RESOLUTION_16)); ESP_RETURN_ON_ERROR(es8311_sample_frequency_config(es_handle, EXAMPLE_SAMPLE_RATE * EXAMPLE_MCLK_MULTIPLE, EXAMPLE_SAMPLE_RATE), TAG, "set es8311 sample frequency failed"); ESP_RETURN_ON_ERROR(es8311_voice_volume_set(es_handle, EXAMPLE_VOICE_VOLUME, NULL), TAG, "set es8311 volume failed"); ESP_RETURN_ON_ERROR(es8311_microphone_config(es_handle, false), TAG, "set es8311 microphone failed"); @@ -85,37 +87,23 @@ static esp_err_t es8311_codec_init(void) static esp_err_t i2s_driver_init(void) { - i2s_config_t i2s_cfg = { - .mode = I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_RX, - .sample_rate = EXAMPLE_SAMPLE_RATE, - .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, - .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, - .communication_format = I2S_COMM_FORMAT_STAND_I2S, - .tx_desc_auto_clear = true, -#if SOC_I2S_SUPPORTS_TDM - .total_chan = 2, - .chan_mask = I2S_TDM_ACTIVE_CH0 | I2S_TDM_ACTIVE_CH1, - .left_align = false, - .big_edin = false, - .bit_order_msb = false, - .skip_msk = false, -#endif - .dma_desc_num = 8, - .dma_frame_num = 64, - .use_apll = false, - .mclk_multiple = EXAMPLE_MCLK_MULTIPLE, - .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, + i2s_gpio_config_t i2s_pin = { + .mclk = GPIO_NUM_0, + .bclk = GPIO_NUM_4, + .ws = GPIO_NUM_5, + .dout = GPIO_NUM_18, + .din = GPIO_NUM_19 }; - - ESP_RETURN_ON_ERROR(i2s_driver_install(I2S_NUM, &i2s_cfg, 0, NULL), TAG, "install i2s failed"); - i2s_pin_config_t i2s_pin_cfg = { - .mck_io_num = I2S_MCK_IO, - .bck_io_num = I2S_BCK_IO, - .ws_io_num = I2S_WS_IO, - .data_out_num = I2S_DO_IO, - .data_in_num = I2S_DI_IO - }; - ESP_RETURN_ON_ERROR(i2s_set_pin(I2S_NUM, &i2s_pin_cfg), TAG, "set i2s pins failed"); + i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); + chan_cfg.id = I2S_NUM; + ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle)); + i2s_std_slot_config_t slot_cfg = I2S_STD_PHILIP_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO); + slot_cfg.auto_clear = true; + i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(EXAMPLE_SAMPLE_RATE); + ESP_ERROR_CHECK(i2s_init_channel(tx_handle, &clk_cfg, &slot_cfg)); + ESP_ERROR_CHECK(i2s_init_channel(rx_handle, &clk_cfg, &slot_cfg)); + ESP_ERROR_CHECK(i2s_start_channel(tx_handle)); + ESP_ERROR_CHECK(i2s_start_channel(rx_handle)); return ESP_OK; } @@ -124,18 +112,20 @@ static void i2s_music(void *args) { esp_err_t ret = ESP_OK; size_t bytes_write = 0; + if (tx_handle == NULL) { + ESP_LOGE(TAG, "[music] i2s tx channel has not been registered yet"); + abort(); + } while (1) { /* Write music to earphone */ - ret = i2s_write(I2S_NUM, music_pcm_start, music_pcm_end - music_pcm_start, &bytes_write, portMAX_DELAY); + ret = i2s_write_channel(tx_handle, music_pcm_start, music_pcm_end - music_pcm_start, &bytes_write, portMAX_DELAY); if (ret != ESP_OK) { - /* Since we set timeout to 'portMAX_DELAY' in 'i2s_write' + /* Since we set timeout to 'portMAX_DELAY' in 'i2s_write_channel' so you won't reach here unless you set other timeout value, if timeout detected, it means write operation failed. */ ESP_LOGE(TAG, "[music] i2s read failed, %s", err_reason[ret == ESP_ERR_TIMEOUT]); abort(); } - /* Clear DMA buffer to avoid noise from legacy data in buffer */ - i2s_zero_dma_buffer(I2S_NUM); if (bytes_write > 0) { ESP_LOGI(TAG, "[music] i2s music played, %d bytes are written.", bytes_write); } else { @@ -150,6 +140,10 @@ static void i2s_music(void *args) #else static void i2s_echo(void *args) { + if (rx_handle == NULL || tx_handle == NULL) { + ESP_LOGE(TAG, "[echo] i2s rx or tx channel has not been registered yet"); + abort(); + } int *mic_data = malloc(EXAMPLE_RECV_BUF_SIZE); if (!mic_data) { ESP_LOGE(TAG, "[echo] No memory for read data buffer"); @@ -163,13 +157,13 @@ static void i2s_echo(void *args) while (1) { memset(mic_data, 0, EXAMPLE_RECV_BUF_SIZE); /* Read sample data from mic */ - ret = i2s_read(I2S_NUM, mic_data, EXAMPLE_RECV_BUF_SIZE, &bytes_read, 100); + ret = i2s_read_channel(rx_handle, mic_data, EXAMPLE_RECV_BUF_SIZE, &bytes_read, 100); if (ret != ESP_OK) { ESP_LOGE(TAG, "[echo] i2s read failed, %s", err_reason[ret == ESP_ERR_TIMEOUT]); abort(); } /* Write sample data to earphone */ - ret = i2s_write(I2S_NUM, mic_data, EXAMPLE_RECV_BUF_SIZE, &bytes_write, 100); + ret = i2s_write_channel(tx_handle, mic_data, EXAMPLE_RECV_BUF_SIZE, &bytes_write, 100); if (ret != ESP_OK) { ESP_LOGE(TAG, "[echo] i2s write failed, %s", err_reason[ret == ESP_ERR_TIMEOUT]); abort(); diff --git a/tools/ci/check_copyright_ignore.txt b/tools/ci/check_copyright_ignore.txt index e7d5b56ed3..6e3bbe29bd 100644 --- a/tools/ci/check_copyright_ignore.txt +++ b/tools/ci/check_copyright_ignore.txt @@ -1941,11 +1941,6 @@ examples/peripherals/i2c/i2c_simple/main/i2c_simple_main.c examples/peripherals/i2c/i2c_tools/example_test.py examples/peripherals/i2c/i2c_tools/main/cmd_i2ctools.h examples/peripherals/i2c/i2c_tools/main/i2ctools_example_main.c -examples/peripherals/i2s/i2s_adc_dac/main/app_main.c -examples/peripherals/i2s/i2s_adc_dac/main/audio_example_file.h -examples/peripherals/i2s/i2s_adc_dac/tools/generate_audio_file.py -examples/peripherals/i2s/i2s_audio_recorder_sdcard/main/i2s_recorder_main.c -examples/peripherals/i2s/i2s_basic/main/i2s_example_main.c examples/peripherals/ledc/ledc_basic/main/ledc_basic_example_main.c examples/peripherals/ledc/ledc_fade/main/ledc_fade_example_main.c examples/peripherals/mcpwm/mcpwm_brushed_dc_control/main/cmd_mcpwm_motor.c From 0fe3bb8ab76ab53d2c9edcd2956f71caf476420d Mon Sep 17 00:00:00 2001 From: laokaiyao Date: Sat, 2 Apr 2022 21:31:35 +0800 Subject: [PATCH 2/3] i2s: update examples and unit-tests --- components/driver/deprecated/driver/i2s.h | 2 +- components/driver/i2s/i2s_common.c | 12 +- components/driver/i2s/i2s_legacy.c | 38 +-- components/driver/i2s/i2s_pdm.c | 148 ++++++----- components/driver/i2s/i2s_private.h | 1 - components/driver/i2s/i2s_std.c | 81 +++--- components/driver/i2s/i2s_tdm.c | 87 ++++--- components/driver/include/driver/i2s_common.h | 15 +- components/driver/include/driver/i2s_pdm.h | 22 +- components/driver/include/driver/i2s_std.h | 3 +- components/driver/include/driver/i2s_tdm.h | 3 +- .../driver/test_apps/i2s/main/CMakeLists.txt | 4 +- .../{test_i2s_controller.c => test_i2s.c} | 240 ++++++++++-------- components/esp_lcd/src/esp_lcd_panel_io_i2s.c | 2 +- .../i80_lcd/main/test_i80_lcd_panel.c | 24 +- components/hal/adc_hal.c | 2 +- components/hal/esp32c3/include/hal/i2s_ll.h | 2 +- components/hal/esp32h2/include/hal/i2s_ll.h | 2 +- components/hal/esp32s3/include/hal/i2s_ll.h | 4 +- components/hal/i2s_hal.c | 4 +- components/hal/include/hal/i2s_hal.h | 1 - components/hal/include/hal/i2s_types.h | 2 +- docs/doxygen/Doxyfile | 9 +- docs/en/api-reference/peripherals/i2s.rst | 4 +- .../classic_bt/a2dp_sink/main/bt_app_av.c | 31 +-- .../classic_bt/a2dp_sink/main/bt_app_core.c | 2 +- .../a2dp_sink/tutorial/Example_A2DP_Sink.md | 52 ++-- .../coex/a2dp_gatts_coex/main/bt_app_av.c | 6 +- .../coex/a2dp_gatts_coex/main/bt_app_core.c | 2 +- .../coex/a2dp_gatts_coex/main/main.c | 27 +- .../main/i2s_recorder_main.c | 25 +- .../i2s/i2s_basic/main/i2s_example_main.c | 103 ++++---- .../i2s/i2s_basic/sdkconfig.defaults | 1 + .../i2s/i2s_basic_new/CMakeLists.txt | 6 + .../peripherals/i2s/i2s_basic_new/README.md | 98 +++++++ .../i2s/i2s_basic_new/main/CMakeLists.txt | 2 + .../i2s/i2s_basic_new/main/i2s_example_main.c | 166 ++++++++++++ .../i2s/i2s_es8311/main/i2s_es8311_example.c | 31 +-- 38 files changed, 800 insertions(+), 464 deletions(-) rename components/driver/test_apps/i2s/main/{test_i2s_controller.c => test_i2s.c} (67%) create mode 100644 examples/peripherals/i2s/i2s_basic/sdkconfig.defaults create mode 100644 examples/peripherals/i2s/i2s_basic_new/CMakeLists.txt create mode 100644 examples/peripherals/i2s/i2s_basic_new/README.md create mode 100644 examples/peripherals/i2s/i2s_basic_new/main/CMakeLists.txt create mode 100644 examples/peripherals/i2s/i2s_basic_new/main/i2s_example_main.c diff --git a/components/driver/deprecated/driver/i2s.h b/components/driver/deprecated/driver/i2s.h index 94011c61e9..e7c149e153 100644 --- a/components/driver/deprecated/driver/i2s.h +++ b/components/driver/deprecated/driver/i2s.h @@ -7,7 +7,7 @@ /** * This file is for the backward compatible to the deprecated I2S APIs, * The deprecated APIs will no longer supported in the future - * Please refer to "driver/i2s_controller.h" for the latest I2S driver + * Please refer to "driver/i2s_std.h", "driver/i2s_pdm.h" and ""driver/i2s_tdm.h"" for the latest I2S driver * Note that only one set of I2S APIs is allowed to be used at the same time */ diff --git a/components/driver/i2s/i2s_common.c b/components/driver/i2s/i2s_common.c index 11809cd2ae..656485c533 100644 --- a/components/driver/i2s/i2s_common.c +++ b/components/driver/i2s/i2s_common.c @@ -180,7 +180,7 @@ static i2s_controller_t *i2s_acquire_controller_obj(int id) if (!s_i2s.controller[id]) { /* Try to occupy this i2s controller if failed, this controller could be occupied by other components */ - if (i2s_platform_acquire_occupation(id, "i2s_controller") == ESP_OK) { + if (i2s_platform_acquire_occupation(id, "i2s_driver") == ESP_OK) { i2s_obj = pre_alloc; portENTER_CRITICAL(&s_i2s.spinlock); s_i2s.controller[id] = i2s_obj; @@ -556,7 +556,7 @@ esp_err_t i2s_check_set_mclk(i2s_port_t id, gpio_num_t gpio_num) } #else ESP_RETURN_ON_FALSE(GPIO_IS_VALID_GPIO(gpio_num), ESP_ERR_INVALID_ARG, TAG, "mck_io_num invalid"); - gpio_matrix_out_check_and_set(gpio_num, i2s_periph_signal[id].mck_out_sig, 0, 0); + i2s_gpio_check_and_set(gpio_num, i2s_periph_signal[id].mck_out_sig, false); #endif ESP_LOGI(TAG, "MCLK is pinned to GPIO%d on I2S%d", id, gpio_num); return ESP_OK; @@ -572,7 +572,7 @@ esp_err_t i2s_new_channel(const i2s_chan_config_t *chan_cfg, i2s_chan_handle_t * /* Parameter validity check */ I2S_NULL_POINTER_CHECK(TAG, chan_cfg); I2S_NULL_POINTER_CHECK(TAG, tx_handle || rx_handle); - ESP_RETURN_ON_FALSE(chan_cfg->id < SOC_I2S_NUM, ESP_ERR_INVALID_ARG, TAG, "invalid I2S port id"); + ESP_RETURN_ON_FALSE(chan_cfg->id < SOC_I2S_NUM || chan_cfg->id == I2S_NUM_AUTO, ESP_ERR_INVALID_ARG, TAG, "invalid I2S port id"); ESP_RETURN_ON_FALSE(chan_cfg->dma_desc_num >= 2, ESP_ERR_INVALID_ARG, TAG, "there should be at least 2 DMA buffers"); esp_err_t ret = ESP_OK; @@ -676,9 +676,9 @@ esp_err_t i2s_del_channel(i2s_chan_handle_t handle) * because the clock of some registers are bound to APLL, * otherwise, once APLL is disabled, the registers can't be updated anymore */ if (handle->dir == I2S_DIR_TX) { - i2s_ll_tx_clk_set_src(handle->parent->hal.dev, I2S_CLK_160M_PLL); + i2s_ll_tx_clk_set_src(handle->parent->hal.dev, I2S_CLK_PLL_160M); } else { - i2s_ll_rx_clk_set_src(handle->parent->hal.dev, I2S_CLK_160M_PLL); + i2s_ll_rx_clk_set_src(handle->parent->hal.dev, I2S_CLK_PLL_160M); } periph_rtc_apll_release(); } @@ -898,7 +898,7 @@ err: esp_err_t i2s_clear_dma_buffer(i2s_chan_handle_t handle) { I2S_NULL_POINTER_CHECK(TAG, handle); - ESP_RETURN_ON_FALSE(handle->state > I2S_CHAN_STATE_INIT, ESP_ERR_INVALID_STATE, TAG, "this channel has not initialized yet"); + ESP_RETURN_ON_FALSE(handle->state >= I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, TAG, "this channel has not initialized yet"); /* Clear all the DMA buffer */ for (int desc_num = handle->dma.desc_num; desc_num > 0; desc_num--) { memset(handle->dma.bufs[desc_num-1], 0, handle->dma.buf_size); diff --git a/components/driver/i2s/i2s_legacy.c b/components/driver/i2s/i2s_legacy.c index fc834be793..2655d91421 100644 --- a/components/driver/i2s/i2s_legacy.c +++ b/components/driver/i2s/i2s_legacy.c @@ -636,7 +636,7 @@ static uint32_t i2s_config_source_clock(i2s_port_t i2s_num, bool use_apll, uint3 return I2S_LL_BASE_CLK; #else if (use_apll) { - ESP_LOGW(TAG, "APLL not supported on current chip, use I2S_CLK_160M_PLL as default clock source"); + ESP_LOGW(TAG, "APLL not supported on current chip, use I2S_CLK_PLL_160M as default clock source"); } return I2S_LL_BASE_CLK; #endif @@ -793,20 +793,6 @@ static esp_err_t i2s_calculate_clock(i2s_port_t i2s_num, i2s_hal_clock_info_t *c /*------------------------------------------------------------- I2S configuration -------------------------------------------------------------*/ -#if SOC_I2S_SUPPORTS_TDM - -static uint32_t i2s_get_active_channel_num(uint32_t chan_mask) -{ - uint32_t num = 0; - for (int i = 0; chan_mask; i++, chan_mask >>= 1) { - if (chan_mask & 0x01) { - num++; - } - } - return num; -} -#endif - #if SOC_I2S_SUPPORTS_ADC_DAC static void i2s_dac_set_slot_legacy(void) { @@ -1111,7 +1097,7 @@ esp_err_t i2s_set_sample_rates(i2s_port_t i2s_num, uint32_t rate) uint32_t mask = 0; #if SOC_I2S_SUPPORTS_TDM if (p_i2s[i2s_num]->mode == I2S_COMM_MODE_TDM) { - mask = ((i2s_tdm_slot_config_t *)slot_cfg)->slot_mask;; + mask = slot_cfg->tdm.slot_mask; } #endif return i2s_set_clk(i2s_num, rate, slot_cfg->data_bit_width, slot_cfg->slot_mode | (mask << 16)); @@ -1241,7 +1227,6 @@ static esp_err_t i2s_config_transfer(i2s_port_t i2s_num, const i2s_config_t *i2s #define SLOT_CFG(m) p_i2s[i2s_num]->slot_cfg.m #define CLK_CFG() p_i2s[i2s_num]->clk_cfg /* Convert legacy configuration into general part of slot and clock configuration */ - p_i2s[i2s_num]->slot_cfg.mode = p_i2s[i2s_num]->mode; p_i2s[i2s_num]->slot_cfg.data_bit_width = i2s_config->bits_per_sample; p_i2s[i2s_num]->slot_cfg.slot_bit_width = (int)i2s_config->bits_per_chan < (int)i2s_config->bits_per_sample ? i2s_config->bits_per_sample : i2s_config->bits_per_chan; @@ -1250,11 +1235,11 @@ static esp_err_t i2s_config_transfer(i2s_port_t i2s_num, const i2s_config_t *i2s I2S_SLOT_MODE_STEREO : I2S_SLOT_MODE_MONO; CLK_CFG().sample_rate_hz = i2s_config->sample_rate; CLK_CFG().mclk_multiple = i2s_config->mclk_multiple == 0 ? I2S_MCLK_MULTIPLE_256 : i2s_config->mclk_multiple; - CLK_CFG().clk_src = I2S_CLK_160M_PLL; + CLK_CFG().clk_src = I2S_CLK_PLL_160M; p_i2s[i2s_num]->fixed_mclk = i2s_config->fixed_mclk; p_i2s[i2s_num]->use_apll = false; #if SOC_I2S_SUPPORTS_APLL - CLK_CFG().clk_src = i2s_config->use_apll ? I2S_CLK_APLL : I2S_CLK_160M_PLL; + CLK_CFG().clk_src = i2s_config->use_apll ? I2S_CLK_APLL : I2S_CLK_PLL_160M; p_i2s[i2s_num]->use_apll = i2s_config->use_apll; #endif // SOC_I2S_SUPPORTS_APLL @@ -1331,8 +1316,8 @@ static esp_err_t i2s_config_transfer(i2s_port_t i2s_num, const i2s_config_t *i2s /* Generate TDM slot configuration */ SLOT_CFG(tdm).slot_mask = i2s_config->chan_mask >> 16; - SLOT_CFG(tdm).ws_width = I2S_TDM_AUTO_WS_WIDTH; - tdm_slot->slot_mode = I2S_SLOT_MODE_STEREO; + SLOT_CFG(tdm).ws_width = 0; // I2S_TDM_AUTO_WS_WIDTH + p_i2s[i2s_num]->slot_cfg.slot_mode = I2S_SLOT_MODE_STEREO; SLOT_CFG(tdm).ws_pol = false; if (i2s_config->communication_format == I2S_COMM_FORMAT_STAND_I2S) { SLOT_CFG(tdm).bit_shift = true; @@ -1344,7 +1329,7 @@ static esp_err_t i2s_config_transfer(i2s_port_t i2s_num, const i2s_config_t *i2s } else if (i2s_config->communication_format == I2S_COMM_FORMAT_STAND_PCM_LONG) { SLOT_CFG(tdm).bit_shift = true; - SLOT_CFG(tdm).ws_width = SLOT_CFG(tdm).slot_bit_width; + SLOT_CFG(tdm).ws_width = p_i2s[i2s_num]->slot_cfg.slot_bit_width; SLOT_CFG(tdm).ws_pol = true; } SLOT_CFG(tdm).left_align = i2s_config->left_align; @@ -1353,10 +1338,10 @@ static esp_err_t i2s_config_transfer(i2s_port_t i2s_num, const i2s_config_t *i2s SLOT_CFG(tdm).skip_mask = i2s_config->skip_msk; /* Generate TDM clock configuration */ - p_i2s[i2s_num]->active_slot = __builtin_popcount(tdm_slot->slot_mode); + p_i2s[i2s_num]->active_slot = __builtin_popcount(SLOT_CFG(tdm).slot_mask); uint32_t mx_slot = 32 - __builtin_clz(SLOT_CFG(tdm).slot_mask); mx_slot = mx_slot < 2 ? 2 : mx_slot; - p_i2s[i2s_num]->.total_slot = mx_slot < i2s_config->total_chan ? mx_slot : i2s_config->total_chan; + p_i2s[i2s_num]->total_slot = mx_slot < i2s_config->total_chan ? mx_slot : i2s_config->total_chan; goto finish; } #endif // SOC_I2S_SUPPORTS_TDM @@ -1515,10 +1500,10 @@ esp_err_t i2s_driver_uninstall(i2s_port_t i2s_num) if (obj->use_apll) { // switch back to PLL clock source if (obj->dir & I2S_DIR_TX) { - i2s_ll_tx_clk_set_src(obj->hal.dev, I2S_CLK_160M_PLL); + i2s_ll_tx_clk_set_src(obj->hal.dev, I2S_CLK_PLL_160M); } if (obj->dir & I2S_DIR_RX) { - i2s_ll_rx_clk_set_src(obj->hal.dev, I2S_CLK_160M_PLL); + i2s_ll_rx_clk_set_src(obj->hal.dev, I2S_CLK_PLL_160M); } periph_rtc_apll_release(); } @@ -1556,6 +1541,7 @@ esp_err_t i2s_driver_install(i2s_port_t i2s_num, const i2s_config_t *i2s_config, /* Step 2: Allocate driver object and register to platform */ i2s_obj_t *i2s_obj = calloc(1, sizeof(i2s_obj_t)); ESP_RETURN_ON_FALSE(i2s_obj, ESP_ERR_NO_MEM, TAG, "no mem for I2S driver"); + p_i2s[i2s_num] = i2s_obj; if (i2s_platform_acquire_occupation(i2s_num, "i2s_legacy") != ESP_OK) { free(i2s_obj); ESP_LOGE(TAG, "register I2S object to platform failed"); diff --git a/components/driver/i2s/i2s_pdm.c b/components/driver/i2s/i2s_pdm.c index ac7d40ce47..4c1b8aebcb 100644 --- a/components/driver/i2s/i2s_pdm.c +++ b/components/driver/i2s/i2s_pdm.c @@ -30,7 +30,7 @@ static esp_err_t i2s_pdm_tx_calculate_clock(i2s_chan_handle_t handle, const i2s_ clk_info->bclk_div = 8; clk_info->mclk = clk_info->bclk * clk_info->bclk_div; #if SOC_I2S_SUPPORTS_APLL - clk_info->sclk = clk_cfg->clk_src == I2S_CLK_160M_PLL ? I2S_LL_BASE_CLK : i2s_set_get_apll_freq(clk_info->mclk); + clk_info->sclk = clk_cfg->clk_src == I2S_CLK_PLL_160M ? I2S_LL_BASE_CLK : i2s_set_get_apll_freq(clk_info->mclk); #else clk_info->sclk = I2S_LL_BASE_CLK; #endif @@ -66,19 +66,6 @@ static esp_err_t i2s_pdm_tx_set_clock(i2s_chan_handle_t handle, const i2s_pdm_tx } #endif //CONFIG_PM_ENABLE -#if SOC_I2S_SUPPORTS_APLL - /* Enable APLL and acquire its lock when initializing or clock source changed to APLL */ - if (clk_cfg->clk_src == I2S_CLK_APLL && (handle->state == I2S_CHAN_STATE_INIT || pdm_tx_cfg->clk_cfg.clk_src == I2S_CLK_160M_PLL)) { - periph_rtc_apll_acquire(); - handle->apll_en = true; - } - /* Disable APLL and release its lock when clock source is changed to D2CLK */ - if (clk_cfg->clk_src == I2S_CLK_160M_PLL && pdm_tx_cfg->clk_cfg.clk_src == I2S_CLK_APLL) { - periph_rtc_apll_release(); - handle->apll_en = false; - } -#endif - i2s_hal_clock_info_t clk_info; /* Calculate clock parameters */ ESP_RETURN_ON_ERROR(i2s_pdm_tx_calculate_clock(handle, clk_cfg, &clk_info), TAG, "clock calculate failed"); @@ -90,11 +77,18 @@ static esp_err_t i2s_pdm_tx_set_clock(i2s_chan_handle_t handle, const i2s_pdm_tx i2s_hal_set_tx_clock(&handle->parent->hal, &clk_info, clk_cfg->clk_src); portEXIT_CRITICAL(&s_i2s.spinlock); + /* Update the mode info: clock configuration */ + memcpy(&(pdm_tx_cfg->clk_cfg), clk_cfg, sizeof(i2s_pdm_tx_clk_config_t)); + return ret; } static esp_err_t i2s_pdm_tx_set_slot(i2s_chan_handle_t handle, const i2s_pdm_tx_slot_config_t *slot_cfg) { + /* Update the total slot num and active slot num */ + handle->total_slot = 2; + handle->active_slot = slot_cfg->slot_mode == I2S_SLOT_MODE_MONO ? 1 : 2; + uint32_t buf_size = i2s_get_buf_size(handle, slot_cfg->data_bit_width, handle->dma.frame_num); /* The DMA buffer need to re-allocate if the buffer size changed */ if (handle->dma.buf_size != buf_size) { @@ -112,9 +106,9 @@ static esp_err_t i2s_pdm_tx_set_slot(i2s_chan_handle_t handle, const i2s_pdm_tx_ i2s_hal_pdm_set_tx_slot(&(handle->parent->hal), is_slave, (i2s_hal_slot_config_t*)slot_cfg); portEXIT_CRITICAL(&s_i2s.spinlock); - /* Update the total slot num and active slot num */ - handle->total_slot = 2; - handle->active_slot = slot_cfg->slot_mode == I2S_SLOT_MODE_MONO ? 1 : 2; + /* Update the mode info: slot configuration */ + i2s_pdm_tx_config_t *pdm_tx_cfg = (i2s_pdm_tx_config_t *)handle->mode_info; + memcpy(&(pdm_tx_cfg->slot_cfg), slot_cfg, sizeof(i2s_pdm_tx_slot_config_t)); return ESP_OK; } @@ -145,6 +139,9 @@ static esp_err_t i2s_pdm_tx_set_gpio(i2s_chan_handle_t handle, const i2s_pdm_tx_ #if SOC_I2S_HW_VERSION_2 i2s_ll_mclk_bind_to_tx_clk(handle->parent->hal.dev); #endif + /* Update the mode info: gpio configuration */ + i2s_pdm_tx_config_t *pdm_tx_cfg = (i2s_pdm_tx_config_t *)handle->mode_info; + memcpy(&(pdm_tx_cfg->gpio_cfg), gpio_cfg, sizeof(i2s_pdm_tx_gpio_config_t)); return ESP_OK; } @@ -159,16 +156,25 @@ esp_err_t i2s_init_pdm_tx_channel(i2s_chan_handle_t handle, const i2s_pdm_tx_con xSemaphoreTake(handle->mutex, portMAX_DELAY); ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_REGISTER, ESP_ERR_INVALID_STATE, err, TAG, "the channel has initialized already"); + handle->mode = I2S_COMM_MODE_PDM; + /* Allocate memory for storing the configurations of PDM tx mode */ + if (handle->mode_info) { + free(handle->mode_info); + } + handle->mode_info = calloc(1, sizeof(i2s_pdm_tx_config_t)); + ESP_GOTO_ON_FALSE(handle->mode_info, ESP_ERR_NO_MEM, err, TAG, "no memory for storing the configurations"); ESP_GOTO_ON_ERROR(i2s_pdm_tx_set_gpio(handle, &pdm_tx_cfg->gpio_cfg), err, TAG, "initialize channel failed while setting gpio pins"); /* i2s_set_slot should be called before i2s_set_clock while initializing, because clock is relay on the slot */ ESP_GOTO_ON_ERROR(i2s_pdm_tx_set_slot(handle, &pdm_tx_cfg->slot_cfg), err, TAG, "initialize channel failed while setting slot"); +#if SOC_I2S_SUPPORTS_APLL + /* Enable APLL and acquire its lock when the clock source is APLL */ + if (pdm_tx_cfg->clk_cfg.clk_src == I2S_CLK_APLL) { + periph_rtc_apll_acquire(); + handle->apll_en = true; + } +#endif ESP_GOTO_ON_ERROR(i2s_pdm_tx_set_clock(handle, &pdm_tx_cfg->clk_cfg), err, TAG, "initialize channel failed while setting clock"); ESP_GOTO_ON_ERROR(i2s_init_dma_intr(handle, ESP_INTR_FLAG_LEVEL1), err, TAG, "initialize dma interrupt failed"); - /* Store the configurations of standard mode */ - i2s_pdm_tx_config_t *mode_info = calloc(1, sizeof(i2s_pdm_tx_config_t)); - ESP_GOTO_ON_FALSE(mode_info, ESP_ERR_NO_MEM, err, TAG, "no memory for storing the configurations"); - memcpy(mode_info, pdm_tx_cfg, sizeof(i2s_pdm_tx_config_t)); - handle->mode_info = mode_info; i2s_ll_tx_enable_pdm(handle->parent->hal.dev); #if SOC_I2S_HW_VERSION_2 @@ -198,12 +204,22 @@ esp_err_t i2s_reconfig_pdm_tx_clock(i2s_chan_handle_t handle, const i2s_pdm_tx_c ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_PDM, ESP_ERR_INVALID_ARG, err, TAG, "this handle is not working in standard moded"); ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "invalid state, I2S should be stopped before reconfiguring the clock"); +#if SOC_I2S_SUPPORTS_APLL i2s_pdm_tx_config_t *pdm_tx_cfg = (i2s_pdm_tx_config_t*)handle->mode_info; ESP_GOTO_ON_FALSE(pdm_tx_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); + /* Enable APLL and acquire its lock when the clock source is changed to APLL */ + if (clk_cfg->clk_src == I2S_CLK_APLL && pdm_tx_cfg->clk_cfg.clk_src == I2S_CLK_PLL_160M) { + periph_rtc_apll_acquire(); + handle->apll_en = true; + } + /* Disable APLL and release its lock when clock source is changed to 160M_PLL */ + if (clk_cfg->clk_src == I2S_CLK_PLL_160M && pdm_tx_cfg->clk_cfg.clk_src == I2S_CLK_APLL) { + periph_rtc_apll_release(); + handle->apll_en = false; + } +#endif - ESP_GOTO_ON_ERROR(i2s_pdm_tx_set_clock(handle, &pdm_tx_cfg->clk_cfg), err, TAG, "update clock failed"); - /* Update the stored clock information */ - memcpy(&pdm_tx_cfg->clk_cfg, clk_cfg, sizeof(i2s_pdm_tx_clk_config_t)); + ESP_GOTO_ON_ERROR(i2s_pdm_tx_set_clock(handle, clk_cfg), err, TAG, "update clock failed"); xSemaphoreGive(handle->mutex); @@ -229,8 +245,6 @@ esp_err_t i2s_reconfig_pdm_tx_slot(i2s_chan_handle_t handle, const i2s_pdm_tx_sl ESP_GOTO_ON_FALSE(pdm_tx_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); ESP_GOTO_ON_ERROR(i2s_pdm_tx_set_slot(handle, slot_cfg), err, TAG, "set i2s standard slot failed"); - /* Update the stored slot information */ - memcpy(&pdm_tx_cfg->slot_cfg, slot_cfg, sizeof(i2s_pdm_tx_slot_config_t)); /* If the slot bit width changed, then need to update the clock */ uint32_t slot_bits = slot_cfg->slot_bit_width == I2S_SLOT_BIT_WIDTH_AUTO ? slot_cfg->data_bit_width : slot_cfg->slot_bit_width; @@ -258,13 +272,7 @@ esp_err_t i2s_reconfig_pdm_tx_gpio(i2s_chan_handle_t handle, const i2s_pdm_tx_gp ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_PDM, ESP_ERR_INVALID_ARG, err, TAG, "This handle is not working in standard moded"); ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "Invalid state, I2S should be stopped before reconfiguring the gpio"); - i2s_pdm_tx_config_t *pdm_tx_cfg = (i2s_pdm_tx_config_t*)handle->mode_info; - ESP_GOTO_ON_FALSE(pdm_tx_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); - ESP_GOTO_ON_ERROR(i2s_pdm_tx_set_gpio(handle, gpio_cfg), err, TAG, "set i2s standard slot failed"); - - /* Update the stored slot information */ - memcpy(&pdm_tx_cfg->gpio_cfg, gpio_cfg, sizeof(i2s_pdm_tx_gpio_config_t)); xSemaphoreGive(handle->mutex); return ESP_OK; @@ -290,7 +298,7 @@ static esp_err_t i2s_pdm_rx_calculate_clock(i2s_chan_handle_t handle, const i2s_ clk_info->bclk_div = 8; clk_info->mclk = clk_info->bclk * clk_info->bclk_div; #if SOC_I2S_SUPPORTS_APLL - clk_info->sclk = clk_cfg->clk_src == I2S_CLK_160M_PLL ? I2S_LL_BASE_CLK : i2s_set_get_apll_freq(clk_info->mclk); + clk_info->sclk = clk_cfg->clk_src == I2S_CLK_PLL_160M ? I2S_LL_BASE_CLK : i2s_set_get_apll_freq(clk_info->mclk); #else clk_info->sclk = I2S_LL_BASE_CLK; #endif @@ -325,19 +333,6 @@ static esp_err_t i2s_pdm_rx_set_clock(i2s_chan_handle_t handle, const i2s_pdm_rx } #endif //CONFIG_PM_ENABLE -#if SOC_I2S_SUPPORTS_APLL - /* Enable APLL and acquire its lock when initializing or clock source changed to APLL */ - if (clk_cfg->clk_src == I2S_CLK_APLL && (handle->state == I2S_CHAN_STATE_INIT || pdm_rx_cfg->clk_cfg.clk_src == I2S_CLK_160M_PLL)) { - periph_rtc_apll_acquire(); - handle->apll_en = true; - } - /* Disable APLL and release its lock when clock source is changed to D2CLK */ - if (clk_cfg->clk_src == I2S_CLK_160M_PLL && pdm_rx_cfg->clk_cfg.clk_src == I2S_CLK_APLL) { - periph_rtc_apll_release(); - handle->apll_en = false; - } -#endif - i2s_hal_clock_info_t clk_info; /* Calculate clock parameters */ ESP_RETURN_ON_ERROR(i2s_pdm_rx_calculate_clock(handle, clk_cfg, &clk_info), TAG, "clock calculate failed"); @@ -349,11 +344,18 @@ static esp_err_t i2s_pdm_rx_set_clock(i2s_chan_handle_t handle, const i2s_pdm_rx i2s_hal_set_rx_clock(&handle->parent->hal, &clk_info, clk_cfg->clk_src); portEXIT_CRITICAL(&s_i2s.spinlock); + /* Update the mode info: clock configuration */ + memcpy(&(pdm_rx_cfg->clk_cfg), clk_cfg, sizeof(i2s_pdm_rx_clk_config_t)); + return ret; } static esp_err_t i2s_pdm_rx_set_slot(i2s_chan_handle_t handle, const i2s_pdm_rx_slot_config_t *slot_cfg) { + /* Update the total slot num and active slot num */ + handle->total_slot = 2; + handle->active_slot = slot_cfg->slot_mode == I2S_SLOT_MODE_MONO ? 1 : 2; + uint32_t buf_size = i2s_get_buf_size(handle, slot_cfg->data_bit_width, handle->dma.frame_num); /* The DMA buffer need to re-allocate if the buffer size changed */ if (handle->dma.buf_size != buf_size) { @@ -371,9 +373,9 @@ static esp_err_t i2s_pdm_rx_set_slot(i2s_chan_handle_t handle, const i2s_pdm_rx_ i2s_hal_pdm_set_rx_slot(&(handle->parent->hal), is_slave, (i2s_hal_slot_config_t*)slot_cfg); portEXIT_CRITICAL(&s_i2s.spinlock); - /* Update the total slot num and active slot num */ - handle->total_slot = 2; - handle->active_slot = slot_cfg->slot_mode == I2S_SLOT_MODE_MONO ? 1 : 2; + /* Update the mode info: slot configuration */ + i2s_pdm_rx_config_t *pdm_rx_cfg = (i2s_pdm_rx_config_t *)handle->mode_info; + memcpy(&(pdm_rx_cfg->slot_cfg), slot_cfg, sizeof(i2s_pdm_rx_slot_config_t)); return ESP_OK; } @@ -403,6 +405,9 @@ static esp_err_t i2s_pdm_rx_set_gpio(i2s_chan_handle_t handle, const i2s_pdm_rx_ #if SOC_I2S_HW_VERSION_2 i2s_ll_mclk_bind_to_rx_clk(handle->parent->hal.dev); #endif + /* Update the mode info: gpio configuration */ + i2s_pdm_rx_config_t *pdm_rx_cfg = (i2s_pdm_rx_config_t *)handle->mode_info; + memcpy(&(pdm_rx_cfg->gpio_cfg), gpio_cfg, sizeof(i2s_pdm_rx_gpio_config_t)); return ESP_OK; } @@ -417,16 +422,25 @@ esp_err_t i2s_init_pdm_rx_channel(i2s_chan_handle_t handle, const i2s_pdm_rx_con xSemaphoreTake(handle->mutex, portMAX_DELAY); ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_REGISTER, ESP_ERR_INVALID_STATE, err, TAG, "the channel has initialized already"); + handle->mode = I2S_COMM_MODE_PDM; + /* Allocate memory for storing the configurations of PDM rx mode */ + if (handle->mode_info) { + free(handle->mode_info); + } + handle->mode_info = calloc(1, sizeof(i2s_pdm_rx_config_t)); + ESP_GOTO_ON_FALSE(handle->mode_info, ESP_ERR_NO_MEM, err, TAG, "no memory for storing the configurations"); ESP_GOTO_ON_ERROR(i2s_pdm_rx_set_gpio(handle, &pdm_rx_cfg->gpio_cfg), err, TAG, "initialize channel failed while setting gpio pins"); /* i2s_set_slot should be called before i2s_set_clock while initializing, because clock is relay on the slot */ ESP_GOTO_ON_ERROR(i2s_pdm_rx_set_slot(handle, &pdm_rx_cfg->slot_cfg), err, TAG, "initialize channel failed while setting slot"); +#if SOC_I2S_SUPPORTS_APLL + /* Enable APLL and acquire its lock when the clock source is APLL */ + if (pdm_rx_cfg->clk_cfg.clk_src == I2S_CLK_APLL) { + periph_rtc_apll_acquire(); + handle->apll_en = true; + } +#endif ESP_GOTO_ON_ERROR(i2s_pdm_rx_set_clock(handle, &pdm_rx_cfg->clk_cfg), err, TAG, "initialize channel failed while setting clock"); ESP_GOTO_ON_ERROR(i2s_init_dma_intr(handle, ESP_INTR_FLAG_LEVEL1), err, TAG, "initialize dma interrupt failed"); - /* Store the configurations of standard mode */ - i2s_pdm_rx_config_t *mode_info = calloc(1, sizeof(i2s_pdm_rx_config_t)); - ESP_GOTO_ON_FALSE(mode_info, ESP_ERR_NO_MEM, err, TAG, "no memory for storing the configurations"); - memcpy(mode_info, pdm_rx_cfg, sizeof(i2s_pdm_rx_config_t)); - handle->mode_info = mode_info; i2s_ll_rx_enable_pdm(handle->parent->hal.dev); #if SOC_I2S_HW_VERSION_2 @@ -456,12 +470,22 @@ esp_err_t i2s_reconfig_pdm_rx_clock(i2s_chan_handle_t handle, const i2s_pdm_rx_c ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_PDM, ESP_ERR_INVALID_ARG, err, TAG, "this handle is not working in standard moded"); ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "invalid state, I2S should be stopped before reconfiguring the clock"); +#if SOC_I2S_SUPPORTS_APLL i2s_pdm_rx_config_t *pdm_rx_cfg = (i2s_pdm_rx_config_t*)handle->mode_info; ESP_GOTO_ON_FALSE(pdm_rx_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); + /* Enable APLL and acquire its lock when the clock source is changed to APLL */ + if (clk_cfg->clk_src == I2S_CLK_APLL && pdm_rx_cfg->clk_cfg.clk_src == I2S_CLK_PLL_160M) { + periph_rtc_apll_acquire(); + handle->apll_en = true; + } + /* Disable APLL and release its lock when clock source is changed to 160M_PLL */ + if (clk_cfg->clk_src == I2S_CLK_PLL_160M && pdm_rx_cfg->clk_cfg.clk_src == I2S_CLK_APLL) { + periph_rtc_apll_release(); + handle->apll_en = false; + } +#endif - ESP_GOTO_ON_ERROR(i2s_pdm_rx_set_clock(handle, &pdm_rx_cfg->clk_cfg), err, TAG, "update clock failed"); - /* Update the stored clock information */ - memcpy(&pdm_rx_cfg->clk_cfg, clk_cfg, sizeof(i2s_pdm_rx_clk_config_t)); + ESP_GOTO_ON_ERROR(i2s_pdm_rx_set_clock(handle, clk_cfg), err, TAG, "update clock failed"); xSemaphoreGive(handle->mutex); @@ -487,8 +511,6 @@ esp_err_t i2s_reconfig_pdm_rx_slot(i2s_chan_handle_t handle, const i2s_pdm_rx_sl ESP_GOTO_ON_FALSE(pdm_rx_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); ESP_GOTO_ON_ERROR(i2s_pdm_rx_set_slot(handle, slot_cfg), err, TAG, "set i2s standard slot failed"); - /* Update the stored slot information */ - memcpy(&pdm_rx_cfg->slot_cfg, slot_cfg, sizeof(i2s_pdm_rx_slot_config_t)); /* If the slot bit width changed, then need to update the clock */ uint32_t slot_bits = slot_cfg->slot_bit_width == I2S_SLOT_BIT_WIDTH_AUTO ? slot_cfg->data_bit_width : slot_cfg->slot_bit_width; @@ -515,13 +537,7 @@ esp_err_t i2s_reconfig_pdm_rx_gpio(i2s_chan_handle_t handle, const i2s_pdm_rx_gp ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_PDM, ESP_ERR_INVALID_ARG, err, TAG, "This handle is not working in standard moded"); ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "Invalid state, I2S should be stopped before reconfiguring the gpio"); - i2s_pdm_rx_config_t *pdm_rx_cfg = (i2s_pdm_rx_config_t*)handle->mode_info; - ESP_GOTO_ON_FALSE(pdm_rx_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); - ESP_GOTO_ON_ERROR(i2s_pdm_rx_set_gpio(handle, gpio_cfg), err, TAG, "set i2s standard slot failed"); - - /* Update the stored slot information */ - memcpy(&pdm_rx_cfg->gpio_cfg, gpio_cfg, sizeof(i2s_pdm_rx_gpio_config_t)); xSemaphoreGive(handle->mutex); return ESP_OK; diff --git a/components/driver/i2s/i2s_private.h b/components/driver/i2s/i2s_private.h index cfd021e904..acd45d6273 100644 --- a/components/driver/i2s/i2s_private.h +++ b/components/driver/i2s/i2s_private.h @@ -29,7 +29,6 @@ extern "C" { */ typedef enum { I2S_CHAN_STATE_REGISTER, /*!< i2s channel is registered (not initialized) */ - I2S_CHAN_STATE_INIT, /*!< i2s channel is initializing */ I2S_CHAN_STATE_READY, /*!< i2s channel is stopped (initialized) */ I2S_CHAN_STATE_IDLE, /*!< i2s channel is idling (initialized and started) */ I2S_CHAN_STATE_WRITING, /*!< i2s channel is writing (initialized and started) */ diff --git a/components/driver/i2s/i2s_std.c b/components/driver/i2s/i2s_std.c index 9548333643..aa5db23580 100644 --- a/components/driver/i2s/i2s_std.c +++ b/components/driver/i2s/i2s_std.c @@ -37,7 +37,7 @@ static esp_err_t i2s_std_calculate_clock(i2s_chan_handle_t handle, const i2s_std clk_info->mclk = clk_info->bclk * clk_info->bclk_div; } #if SOC_I2S_SUPPORTS_APLL - clk_info->sclk = clk_cfg->clk_src == I2S_CLK_160M_PLL ? I2S_LL_BASE_CLK : i2s_set_get_apll_freq(clk_info->mclk); + clk_info->sclk = clk_cfg->clk_src == I2S_CLK_PLL_160M ? I2S_LL_BASE_CLK : i2s_set_get_apll_freq(clk_info->mclk); #else clk_info->sclk = I2S_LL_BASE_CLK; #endif @@ -71,19 +71,6 @@ static esp_err_t i2s_std_set_clock(i2s_chan_handle_t handle, const i2s_std_clk_c } #endif //CONFIG_PM_ENABLE -#if SOC_I2S_SUPPORTS_APLL - /* Enable APLL and acquire its lock when initializing or clock source changed to APLL */ - if (clk_cfg->clk_src == I2S_CLK_APLL && (handle->state == I2S_CHAN_STATE_INIT || std_cfg->clk_cfg.clk_src == I2S_CLK_160M_PLL)) { - periph_rtc_apll_acquire(); - handle->apll_en = true; - } - /* Disable APLL and release its lock when clock source is changed to D2CLK */ - if (clk_cfg->clk_src == I2S_CLK_160M_PLL && std_cfg->clk_cfg.clk_src == I2S_CLK_APLL) { - periph_rtc_apll_release(); - handle->apll_en = false; - } -#endif - i2s_hal_clock_info_t clk_info; /* Calculate clock parameters */ ESP_RETURN_ON_ERROR(i2s_std_calculate_clock(handle, clk_cfg, &clk_info), TAG, "clock calculate failed"); @@ -99,11 +86,18 @@ static esp_err_t i2s_std_set_clock(i2s_chan_handle_t handle, const i2s_std_clk_c } portEXIT_CRITICAL(&s_i2s.spinlock); + /* Update the mode info: clock configuration */ + memcpy(&(std_cfg->clk_cfg), clk_cfg, sizeof(i2s_std_clk_config_t)); + return ret; } static esp_err_t i2s_std_set_slot(i2s_chan_handle_t handle, const i2s_std_slot_config_t *slot_cfg) { + /* Update the total slot num and active slot num */ + handle->total_slot = 2; + handle->active_slot = slot_cfg->slot_mode == I2S_SLOT_MODE_MONO ? 1 : 2; + uint32_t buf_size = i2s_get_buf_size(handle, slot_cfg->data_bit_width, handle->dma.frame_num); /* The DMA buffer need to re-allocate if the buffer size changed */ if (handle->dma.buf_size != buf_size) { @@ -134,9 +128,9 @@ static esp_err_t i2s_std_set_slot(i2s_chan_handle_t handle, const i2s_std_slot_c } portEXIT_CRITICAL(&s_i2s.spinlock); - /* Update the total slot num and active slot num */ - handle->total_slot = 2; - handle->active_slot = slot_cfg->slot_mode == I2S_SLOT_MODE_MONO ? 1 : 2; + /* Update the mode info: slot configuration */ + i2s_std_config_t *std_cfg = (i2s_std_config_t*)(handle->mode_info); + memcpy(&(std_cfg->slot_cfg), slot_cfg, sizeof(i2s_std_slot_config_t)); return ESP_OK; } @@ -157,6 +151,11 @@ static esp_err_t i2s_std_set_gpio(i2s_chan_handle_t handle, const i2s_std_gpio_c /* Set data input GPIO */ i2s_gpio_check_and_set(gpio_cfg->din, i2s_periph_signal[id].data_in_sig, true); } + /* Loopback if dout = din */ + if (gpio_cfg->dout != -1 && + gpio_cfg->dout == gpio_cfg->din) { + gpio_set_direction(gpio_cfg->dout, GPIO_MODE_INPUT_OUTPUT); + } if (handle->role == I2S_ROLE_SLAVE) { /* For "tx + slave" mode, select TX signal index for ws and bck */ @@ -187,6 +186,9 @@ static esp_err_t i2s_std_set_gpio(i2s_chan_handle_t handle, const i2s_std_gpio_c i2s_gpio_check_and_set(gpio_cfg->bclk, i2s_periph_signal[id].m_tx_bck_sig, false); } } + /* Update the mode info: gpio configuration */ + i2s_std_config_t *std_cfg = (i2s_std_config_t*)(handle->mode_info); + memcpy(&(std_cfg->gpio_cfg), gpio_cfg, sizeof(i2s_std_gpio_config_t)); return ESP_OK; } @@ -197,18 +199,26 @@ esp_err_t i2s_init_std_channel(i2s_chan_handle_t handle, const i2s_std_config_t esp_err_t ret = ESP_OK; xSemaphoreTake(handle->mutex, portMAX_DELAY); + handle->mode = I2S_COMM_MODE_STD; + /* Allocate memory for storing the configurations of standard mode */ + if (handle->mode_info) { + free(handle->mode_info); + } + handle->mode_info = calloc(1, sizeof(i2s_std_config_t)); + ESP_GOTO_ON_FALSE(handle->mode_info, ESP_ERR_NO_MEM, err, TAG, "no memory for storing the configurations"); ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_REGISTER, ESP_ERR_INVALID_STATE, err, TAG, "the channel has initialized already"); ESP_GOTO_ON_ERROR(i2s_std_set_gpio(handle, &std_cfg->gpio_cfg), err, TAG, "initialize channel failed while setting gpio pins"); /* i2s_set_slot should be called before i2s_set_clock while initializing, because clock is relay on the slot */ ESP_GOTO_ON_ERROR(i2s_std_set_slot(handle, &std_cfg->slot_cfg), err, TAG, "initialize channel failed while setting slot"); +#if SOC_I2S_SUPPORTS_APLL + /* Enable APLL and acquire its lock when the clock source is APLL */ + if (std_cfg->clk_cfg.clk_src == I2S_CLK_APLL) { + periph_rtc_apll_acquire(); + handle->apll_en = true; + } +#endif ESP_GOTO_ON_ERROR(i2s_std_set_clock(handle, &std_cfg->clk_cfg), err, TAG, "initialize channel failed while setting clock"); ESP_GOTO_ON_ERROR(i2s_init_dma_intr(handle, ESP_INTR_FLAG_LEVEL1), err, TAG, "initialize dma interrupt failed"); - /* Store the configurations of standard mode */ - i2s_std_config_t *mode_info = calloc(1, sizeof(i2s_std_config_t)); - ESP_GOTO_ON_FALSE(mode_info, ESP_ERR_NO_MEM, err, TAG, "no memory for storing the configurations"); - memcpy(mode_info, std_cfg, sizeof(i2s_std_config_t)); - handle->mode_info = mode_info; - #if SOC_I2S_HW_VERSION_2 /* Enable clock to start outputting mclk signal. Some codecs will reset once mclk stop */ if (handle->dir == I2S_DIR_TX) { @@ -241,12 +251,21 @@ esp_err_t i2s_reconfig_std_clock(i2s_chan_handle_t handle, const i2s_std_clk_con ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_STD, ESP_ERR_INVALID_ARG, err, TAG, "this handle is not working in standard moded"); ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "invalid state, I2S should be stopped before reconfiguring the clock"); +#if SOC_I2S_SUPPORTS_APLL i2s_std_config_t *std_cfg = (i2s_std_config_t*)handle->mode_info; ESP_GOTO_ON_FALSE(std_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); - - ESP_GOTO_ON_ERROR(i2s_std_set_clock(handle, &std_cfg->clk_cfg), err, TAG, "update clock failed"); - /* Update the stored clock information */ - memcpy(&std_cfg->clk_cfg, clk_cfg, sizeof(i2s_std_clk_config_t)); + /* Enable APLL and acquire its lock when the clock source is changed to APLL */ + if (clk_cfg->clk_src == I2S_CLK_APLL && std_cfg->clk_cfg.clk_src == I2S_CLK_PLL_160M) { + periph_rtc_apll_acquire(); + handle->apll_en = true; + } + /* Disable APLL and release its lock when clock source is changed to 160M_PLL */ + if (clk_cfg->clk_src == I2S_CLK_PLL_160M && std_cfg->clk_cfg.clk_src == I2S_CLK_APLL) { + periph_rtc_apll_release(); + handle->apll_en = false; + } +#endif + ESP_GOTO_ON_ERROR(i2s_std_set_clock(handle, clk_cfg), err, TAG, "update clock failed"); xSemaphoreGive(handle->mutex); @@ -271,8 +290,6 @@ esp_err_t i2s_reconfig_std_slot(i2s_chan_handle_t handle, const i2s_std_slot_con ESP_GOTO_ON_FALSE(std_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); ESP_GOTO_ON_ERROR(i2s_std_set_slot(handle, slot_cfg), err, TAG, "set i2s standard slot failed"); - /* Update the stored slot information */ - memcpy(&std_cfg->slot_cfg, slot_cfg, sizeof(i2s_std_slot_config_t)); /* If the slot bit width changed, then need to update the clock */ uint32_t slot_bits = slot_cfg->slot_bit_width == I2S_SLOT_BIT_WIDTH_AUTO ? slot_cfg->data_bit_width : slot_cfg->slot_bit_width; @@ -299,13 +316,7 @@ esp_err_t i2s_reconfig_std_gpio(i2s_chan_handle_t handle, const i2s_std_gpio_con ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_STD, ESP_ERR_INVALID_ARG, err, TAG, "This handle is not working in standard moded"); ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "Invalid state, I2S should be stopped before reconfiguring the gpio"); - i2s_std_config_t *std_cfg = (i2s_std_config_t*)handle->mode_info; - ESP_GOTO_ON_FALSE(std_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); - ESP_GOTO_ON_ERROR(i2s_std_set_gpio(handle, gpio_cfg), err, TAG, "set i2s standard slot failed"); - - /* Update the stored slot information */ - memcpy(&std_cfg->gpio_cfg, gpio_cfg, sizeof(i2s_std_gpio_config_t)); xSemaphoreGive(handle->mutex); return ESP_OK; diff --git a/components/driver/i2s/i2s_tdm.c b/components/driver/i2s/i2s_tdm.c index c8d7c663c5..9245a08261 100644 --- a/components/driver/i2s/i2s_tdm.c +++ b/components/driver/i2s/i2s_tdm.c @@ -38,7 +38,7 @@ static esp_err_t i2s_tdm_calculate_clock(i2s_chan_handle_t handle, const i2s_tdm clk_info->mclk = clk_info->bclk * clk_info->bclk_div; } #if SOC_I2S_SUPPORTS_APLL - clk_info->sclk = clk_cfg->clk_src == I2S_CLK_160M_PLL ? I2S_LL_BASE_CLK : i2s_set_get_apll_freq(clk_info->mclk); + clk_info->sclk = clk_cfg->clk_src == I2S_CLK_PLL_160M ? I2S_LL_BASE_CLK : i2s_set_get_apll_freq(clk_info->mclk); #else clk_info->sclk = I2S_LL_BASE_CLK; #endif @@ -72,19 +72,6 @@ static esp_err_t i2s_tdm_set_clock(i2s_chan_handle_t handle, const i2s_tdm_clk_c } #endif //CONFIG_PM_ENABLE -#if SOC_I2S_SUPPORTS_APLL - /* Enable APLL and acquire its lock when initializing or clock source changed to APLL */ - if (clk_cfg->clk_src == I2S_CLK_APLL && (handle->state == I2S_CHAN_STATE_INIT || tdm_cfg->clk_cfg.clk_src == I2S_CLK_160M_PLL)) { - periph_rtc_apll_acquire(); - handle->apll_en = true; - } - /* Disable APLL and release its lock when clock source is changed to D2CLK */ - if (clk_cfg->clk_src == I2S_CLK_160M_PLL && tdm_cfg->clk_cfg.clk_src == I2S_CLK_APLL) { - periph_rtc_apll_release(); - handle->apll_en = false; - } -#endif - i2s_hal_clock_info_t clk_info; /* Calculate clock parameters */ ESP_RETURN_ON_ERROR(i2s_tdm_calculate_clock(handle, clk_cfg, &clk_info), TAG, "clock calculate failed"); @@ -100,11 +87,20 @@ static esp_err_t i2s_tdm_set_clock(i2s_chan_handle_t handle, const i2s_tdm_clk_c } portEXIT_CRITICAL(&s_i2s.spinlock); + /* Update the mode info: clock configuration */ + memcpy(&(tdm_cfg->clk_cfg), clk_cfg, sizeof(i2s_tdm_clk_config_t)); + return ret; } static esp_err_t i2s_tdm_set_slot(i2s_chan_handle_t handle, const i2s_tdm_slot_config_t *slot_cfg) { + /* Update the total slot num and active slot num */ + handle->active_slot = slot_cfg->slot_mode == I2S_SLOT_MODE_MONO ? 1 : __builtin_popcount(slot_cfg->slot_mask); + uint32_t max_slot_num = 32 - __builtin_clz(slot_cfg->slot_mask); + handle->total_slot = slot_cfg->total_slot < max_slot_num ? max_slot_num : slot_cfg->total_slot; + handle->total_slot = handle->total_slot < 2 ? 2 : handle->total_slot; // At least two slots in a frame + uint32_t buf_size = i2s_get_buf_size(handle, slot_cfg->data_bit_width, handle->dma.frame_num); /* The DMA buffer need to re-allocate if the buffer size changed */ if (handle->dma.buf_size != buf_size) { @@ -129,17 +125,15 @@ static esp_err_t i2s_tdm_set_slot(i2s_chan_handle_t handle, const i2s_tdm_slot_c portENTER_CRITICAL(&s_i2s.spinlock); /* Configure the hardware to apply TDM format */ if (handle->dir == I2S_DIR_TX) { - i2s_hal_tdm_set_tx_slot(&(handle->parent->hal), is_slave, slot_cfg); + i2s_hal_tdm_set_tx_slot(&(handle->parent->hal), is_slave, (i2s_hal_slot_config_t*)slot_cfg); } else { - i2s_hal_tdm_set_rx_slot(&(handle->parent->hal), is_slave, slot_cfg); + i2s_hal_tdm_set_rx_slot(&(handle->parent->hal), is_slave, (i2s_hal_slot_config_t*)slot_cfg); } portEXIT_CRITICAL(&s_i2s.spinlock); - /* Update the total slot num and active slot num */ - handle->active_slot = slot_cfg->slot_mode == I2S_SLOT_MODE_MONO ? 1 : __builtin_popcount(slot_cfg->slot_mask); - uint32_t max_slot_num = 32 - __builtin_clz(slot_cfg->slot_mask); - handle->total_slot = slot_cfg->total_slot < max_slot_num ? max_slot_num : slot_cfg->total_slot; - handle->total_slot = handle->total_slot < 2 ? 2 : handle->total_slot; // At least two slots in a frame + /* Update the mode info: slot configuration */ + i2s_tdm_config_t *tdm_cfg = (i2s_tdm_config_t*)(handle->mode_info); + memcpy(&(tdm_cfg->slot_cfg), slot_cfg, sizeof(i2s_tdm_slot_config_t)); return ESP_OK; } @@ -160,6 +154,11 @@ static esp_err_t i2s_tdm_set_gpio(i2s_chan_handle_t handle, const i2s_tdm_gpio_c /* Set data input GPIO */ i2s_gpio_check_and_set(gpio_cfg->din, i2s_periph_signal[id].data_in_sig, true); } + /* Loopback if dout = din */ + if (gpio_cfg->dout != -1 && + gpio_cfg->dout == gpio_cfg->din) { + gpio_set_direction(gpio_cfg->dout, GPIO_MODE_INPUT_OUTPUT); + } if (handle->role == I2S_ROLE_SLAVE) { /* For "tx + slave" mode, select TX signal index for ws and bck */ @@ -190,6 +189,9 @@ static esp_err_t i2s_tdm_set_gpio(i2s_chan_handle_t handle, const i2s_tdm_gpio_c i2s_gpio_check_and_set(gpio_cfg->bclk, i2s_periph_signal[id].m_tx_bck_sig, false); } } + /* Update the mode info: gpio configuration */ + i2s_tdm_config_t *tdm_cfg = (i2s_tdm_config_t*)(handle->mode_info); + memcpy(&(tdm_cfg->gpio_cfg), gpio_cfg, sizeof(i2s_tdm_gpio_config_t)); return ESP_OK; } @@ -202,16 +204,25 @@ esp_err_t i2s_init_tdm_channel(i2s_chan_handle_t handle, const i2s_tdm_config_t xSemaphoreTake(handle->mutex, portMAX_DELAY); ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_REGISTER, ESP_ERR_INVALID_STATE, err, TAG, "the channel has initialized already"); + handle->mode = I2S_COMM_MODE_TDM; + /* Allocate memory for storing the configurations of TDM mode */ + if (handle->mode_info) { + free(handle->mode_info); + } + handle->mode_info = calloc(1, sizeof(i2s_tdm_config_t)); + ESP_GOTO_ON_FALSE(handle->mode_info, ESP_ERR_NO_MEM, err, TAG, "no memory for storing the configurations"); ESP_GOTO_ON_ERROR(i2s_tdm_set_gpio(handle, &tdm_cfg->gpio_cfg), err, TAG, "initialize channel failed while setting gpio pins"); /* i2s_set_slot should be called before i2s_set_clock while initializing, because clock is relay on the slot */ ESP_GOTO_ON_ERROR(i2s_tdm_set_slot(handle, &tdm_cfg->slot_cfg), err, TAG, "initialize channel failed while setting slot"); +#if SOC_I2S_SUPPORTS_APLL + /* Enable APLL and acquire its lock when the clock source is APLL */ + if (tdm_cfg->clk_cfg.clk_src == I2S_CLK_APLL) { + periph_rtc_apll_acquire(); + handle->apll_en = true; + } ESP_GOTO_ON_ERROR(i2s_tdm_set_clock(handle, &tdm_cfg->clk_cfg), err, TAG, "initialize channel failed while setting clock"); ESP_GOTO_ON_ERROR(i2s_init_dma_intr(handle, ESP_INTR_FLAG_LEVEL1), err, TAG, "initialize dma interrupt failed"); - /* Store the configurations of standard mode */ - i2s_tdm_config_t *mode_info = calloc(1, sizeof(i2s_tdm_config_t)); - ESP_GOTO_ON_FALSE(mode_info, ESP_ERR_NO_MEM, err, TAG, "no memory for storing the configurations"); - memcpy(mode_info, tdm_cfg, sizeof(i2s_tdm_config_t)); - handle->mode_info = mode_info; +#endif #if SOC_I2S_HW_VERSION_2 /* Enable clock to start outputting mclk signal. Some codecs will reset once mclk stop */ @@ -245,12 +256,22 @@ esp_err_t i2s_reconfig_tdm_clock(i2s_chan_handle_t handle, const i2s_tdm_clk_con ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_TDM, ESP_ERR_INVALID_ARG, err, TAG, "this handle is not working in standard moded"); ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "invalid state, I2S should be stopped before reconfiguring the clock"); +#if SOC_I2S_SUPPORTS_APLL i2s_tdm_config_t *tdm_cfg = (i2s_tdm_config_t*)handle->mode_info; ESP_GOTO_ON_FALSE(tdm_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); + /* Enable APLL and acquire its lock when the clock source is changed to APLL */ + if (clk_cfg->clk_src == I2S_CLK_APLL && clk_cfg->clk_cfg.clk_src == I2S_CLK_PLL_160M) { + periph_rtc_apll_acquire(); + handle->apll_en = true; + } + /* Disable APLL and release its lock when clock source is changed to 160M_PLL */ + if (clk_cfg->clk_src == I2S_CLK_PLL_160M && clk_cfg->clk_cfg.clk_src == I2S_CLK_APLL) { + periph_rtc_apll_release(); + handle->apll_en = false; + } +#endif - ESP_GOTO_ON_ERROR(i2s_tdm_set_clock(handle, &tdm_cfg->clk_cfg), err, TAG, "update clock failed"); - /* Update the stored clock information */ - memcpy(&tdm_cfg->clk_cfg, clk_cfg, sizeof(i2s_tdm_clk_config_t)); + ESP_GOTO_ON_ERROR(i2s_tdm_set_clock(handle, clk_cfg), err, TAG, "update clock failed"); xSemaphoreGive(handle->mutex); return ESP_OK; @@ -274,8 +295,6 @@ esp_err_t i2s_reconfig_tdm_slot(i2s_chan_handle_t handle, const i2s_tdm_slot_con ESP_GOTO_ON_FALSE(tdm_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); ESP_GOTO_ON_ERROR(i2s_tdm_set_slot(handle, slot_cfg), err, TAG, "set i2s standard slot failed"); - /* Update the stored slot information */ - memcpy(&tdm_cfg->slot_cfg, slot_cfg, sizeof(i2s_tdm_slot_config_t)); /* If the slot bit width changed, then need to update the clock */ uint32_t slot_bits = slot_cfg->slot_bit_width == I2S_SLOT_BIT_WIDTH_AUTO ? slot_cfg->data_bit_width : slot_cfg->slot_bit_width; @@ -301,13 +320,7 @@ esp_err_t i2s_reconfig_tdm_gpio(i2s_chan_handle_t handle, const i2s_tdm_gpio_con ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_TDM, ESP_ERR_INVALID_ARG, err, TAG, "This handle is not working in standard moded"); ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "Invalid state, I2S should be stopped before reconfiguring the gpio"); - i2s_tdm_config_t *tdm_cfg = (i2s_tdm_config_t*)handle->mode_info; - ESP_GOTO_ON_FALSE(tdm_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); - ESP_GOTO_ON_ERROR(i2s_tdm_set_gpio(handle, gpio_cfg), err, TAG, "set i2s standard slot failed"); - - /* Update the stored slot information */ - memcpy(&tdm_cfg->gpio_cfg, gpio_cfg, sizeof(i2s_tdm_gpio_config_t)); xSemaphoreGive(handle->mutex); return ESP_OK; diff --git a/components/driver/include/driver/i2s_common.h b/components/driver/include/driver/i2s_common.h index fdd7fb7beb..b4f637c751 100644 --- a/components/driver/include/driver/i2s_common.h +++ b/components/driver/include/driver/i2s_common.h @@ -27,11 +27,12 @@ extern "C" { /** * @brief get default I2S property */ -#define I2S_CHANNEL_CONFIG(i2s_role, i2s_mode, pin_config) { \ - .id = I2S_NUM_AUTO, \ +#define I2S_CHANNEL_DEFAULT_CONFIG(i2s_num, i2s_role) { \ + .id = i2s_num, \ .role = i2s_role, \ - .mode = i2s_mode, \ - .io = pin_config, \ + .dma_desc_num = 3, \ + .dma_frame_num = 500, \ + .auto_clear = false, \ } #define I2S_GPIO_UNUSED GPIO_NUM_NC /*!< Used in i2s_gpio_config_t for signals which are not used */ @@ -107,7 +108,7 @@ esp_err_t i2s_del_channel(i2s_chan_handle_t handle); * - ESP_ERR_INVALID_ARG NULL pointer * - ESP_ERR_INVALID_STATE This channel is not registered */ -esp_err_t i2s_init_channel(i2s_chan_handle_t handle, const void *clk_config, const void *slot_config); +// esp_err_t i2s_init_channel(i2s_chan_handle_t handle, const void *clk_config, const void *slot_config); /** * @brief Reconfigure the I2S clock @@ -128,7 +129,7 @@ esp_err_t i2s_init_channel(i2s_chan_handle_t handle, const void *clk_config, con * - ESP_ERR_INVALID_ARG NULL pointer * - ESP_ERR_INVALID_STATE This channel is not initialized */ -esp_err_t i2s_set_clock(i2s_chan_handle_t handle, const void *clk_config); +// esp_err_t i2s_set_clock(i2s_chan_handle_t handle, const void *clk_config); /** * @brief Reconfigure the I2S slot @@ -148,7 +149,7 @@ esp_err_t i2s_set_clock(i2s_chan_handle_t handle, const void *clk_config); * - ESP_ERR_INVALID_ARG NULL pointer or unmatched slot configuration type * - ESP_ERR_INVALID_STATE This channel is not initialized */ -esp_err_t i2s_set_slot(i2s_chan_handle_t handle, const void *slot_config); +// esp_err_t i2s_set_slot(i2s_chan_handle_t handle, const void *slot_config); /** * @brief Get I2S event queue handler diff --git a/components/driver/include/driver/i2s_pdm.h b/components/driver/include/driver/i2s_pdm.h index 732265a77c..4f3ad29f6f 100644 --- a/components/driver/include/driver/i2s_pdm.h +++ b/components/driver/include/driver/i2s_pdm.h @@ -15,6 +15,7 @@ #include "hal/i2s_types.h" #include "hal/gpio_types.h" +#include "driver/i2s_common.h" #ifdef __cplusplus extern "C" { @@ -40,7 +41,7 @@ extern "C" { */ #define I2S_PDM_RX_CLK_DEFAULT_CONFIG(rate) { \ .sample_rate_hz = rate, \ - .clk_src = I2S_CLK_160M_PLL, \ + .clk_src = I2S_CLK_PLL_160M, \ .mclk_multiple = I2S_MCLK_MULTIPLE_256, \ .dn_sample_mode = I2S_PDM_DSR_8S \ } @@ -85,6 +86,16 @@ typedef struct i2s_pdm_rx_gpio_config_t gpio_cfg; } i2s_pdm_rx_config_t; + +esp_err_t i2s_init_pdm_rx_channel(i2s_chan_handle_t handle, const i2s_pdm_rx_config_t *pdm_rx_cfg); + +esp_err_t i2s_reconfig_pdm_rx_clock(i2s_chan_handle_t handle, const i2s_pdm_rx_clk_config_t *clk_cfg); + +esp_err_t i2s_reconfig_pdm_rx_slot(i2s_chan_handle_t handle, const i2s_pdm_rx_slot_config_t *slot_cfg); + +esp_err_t i2s_reconfig_pdm_rx_gpio(i2s_chan_handle_t handle, const i2s_pdm_rx_gpio_config_t *gpio_cfg); + + #endif // SOC_I2S_SUPPORTS_PDM_RX @@ -144,7 +155,7 @@ typedef struct */ #define I2S_PDM_TX_CLK_DEFAULT_CONFIG(rate) { \ .sample_rate_hz = rate, \ - .clk_src = I2S_CLK_160M_PLL, \ + .clk_src = I2S_CLK_PLL_160M, \ .mclk_multiple = I2S_MCLK_MULTIPLE_256, \ .up_sample_fp = 960, \ .up_sample_fs = ((rate) / 100), \ @@ -219,6 +230,13 @@ typedef struct i2s_pdm_tx_gpio_config_t gpio_cfg; } i2s_pdm_tx_config_t; +esp_err_t i2s_init_pdm_tx_channel(i2s_chan_handle_t handle, const i2s_pdm_tx_config_t *pdm_tx_cfg); + +esp_err_t i2s_reconfig_pdm_tx_clock(i2s_chan_handle_t handle, const i2s_pdm_tx_clk_config_t *clk_cfg); + +esp_err_t i2s_reconfig_pdm_tx_slot(i2s_chan_handle_t handle, const i2s_pdm_tx_slot_config_t *slot_cfg); + +esp_err_t i2s_reconfig_pdm_tx_gpio(i2s_chan_handle_t handle, const i2s_pdm_tx_gpio_config_t *gpio_cfg); #endif // SOC_I2S_SUPPORTS_PDM_TX diff --git a/components/driver/include/driver/i2s_std.h b/components/driver/include/driver/i2s_std.h index c0db201bac..12f95130ff 100644 --- a/components/driver/include/driver/i2s_std.h +++ b/components/driver/include/driver/i2s_std.h @@ -14,6 +14,7 @@ #include "hal/i2s_types.h" #include "hal/gpio_types.h" +#include "driver/i2s_common.h" #ifdef __cplusplus extern "C" { @@ -140,7 +141,7 @@ extern "C" { */ #define I2S_STD_CLK_DEFAULT_CONFIG(rate) { \ .sample_rate_hz = rate, \ - .clk_src = I2S_CLK_160M_PLL, \ + .clk_src = I2S_CLK_PLL_160M, \ .mclk_multiple = I2S_MCLK_MULTIPLE_256, \ } diff --git a/components/driver/include/driver/i2s_tdm.h b/components/driver/include/driver/i2s_tdm.h index e5e1b2ff84..56fd9464e7 100644 --- a/components/driver/include/driver/i2s_tdm.h +++ b/components/driver/include/driver/i2s_tdm.h @@ -13,6 +13,7 @@ #include "hal/i2s_types.h" #include "hal/gpio_types.h" +#include "driver/i2s_common.h" #if SOC_I2S_SUPPORTS_TDM @@ -119,7 +120,7 @@ extern "C" { */ #define I2S_TDM_CLK_DEFAULT_CONFIG(rate) { \ .sample_rate_hz = rate, \ - .clk_src = I2S_CLK_160M_PLL, \ + .clk_src = I2S_CLK_PLL_160M, \ .mclk_multiple = I2S_MCLK_MULTIPLE_256, \ } diff --git a/components/driver/test_apps/i2s/main/CMakeLists.txt b/components/driver/test_apps/i2s/main/CMakeLists.txt index 1eb45d8776..89b0c08d6c 100644 --- a/components/driver/test_apps/i2s/main/CMakeLists.txt +++ b/components/driver/test_apps/i2s/main/CMakeLists.txt @@ -1,7 +1,7 @@ set(srcs "test_app_main.c") if(CONFIG_SOC_I2S_SUPPORTED) - list(APPEND srcs "test_i2s_controller.c" + list(APPEND srcs "test_i2s.c" "test_i2s_legacy.c") endif() @@ -11,6 +11,6 @@ idf_component_register(SRCS ${srcs} if(CONFIG_SOC_I2S_SUPPORTED) target_link_libraries(${COMPONENT_LIB} INTERFACE - "-u test_app_include_i2s_controller" + "-u test_app_include_i2s" "-u test_app_include_i2s_legacy") endif() diff --git a/components/driver/test_apps/i2s/main/test_i2s_controller.c b/components/driver/test_apps/i2s/main/test_i2s.c similarity index 67% rename from components/driver/test_apps/i2s/main/test_i2s_controller.c rename to components/driver/test_apps/i2s/main/test_i2s.c index 0c1cf8d00f..07ee608b93 100644 --- a/components/driver/test_apps/i2s/main/test_i2s_controller.c +++ b/components/driver/test_apps/i2s/main/test_i2s.c @@ -25,11 +25,17 @@ #include "math.h" #include "esp_rom_gpio.h" #include "soc/i2s_periph.h" -#include "driver/i2s_controller.h" +#include "driver/i2s_std.h" +#if SOC_I2S_SUPPORTS_PDM +#include "driver/i2s_pdm.h" +#endif +#if SOC_I2S_SUPPORTS_TDM +#include "driver/i2s_tdm.h" +#endif #include "hal/i2s_hal.h" #include "esp_private/i2s_platform.h" #if SOC_PCNT_SUPPORTED -#include "driver/pcnt.h" +#include "driver/pulse_cnt.h" #include "soc/pcnt_periph.h" #endif @@ -38,12 +44,12 @@ #if CONFIG_IDF_TARGET_ESP32 #define MASTER_MCK_IO 0 -#define MASTER_BCK_IO 15 -#define MASTER_WS_IO 25 -#define SLAVE_BCK_IO 19 -#define SLAVE_WS_IO 26 -#define DATA_IN_IO 21 -#define DATA_OUT_IO 22 +#define MASTER_BCK_IO 4 +#define MASTER_WS_IO 5 +#define SLAVE_BCK_IO 21 +#define SLAVE_WS_IO 22 +#define DATA_IN_IO 19 +#define DATA_OUT_IO 18 #define ADC1_CHANNEL_4_IO 32 #elif CONFIG_IDF_TARGET_ESP32S2 #define MASTER_MCK_IO 0 @@ -81,7 +87,7 @@ .ws = MASTER_WS_IO, \ .dout = DATA_OUT_IO, \ .din = DATA_IN_IO \ - }; + } #define I2S_TEST_SLAVE_DEFAULT_PIN { \ .mclk = -1, \ @@ -89,10 +95,10 @@ .ws = SLAVE_WS_IO, \ .dout = DATA_OUT_IO, \ .din = DATA_IN_IO \ - }; + } // This empty function is used to force the compiler link this file -void test_app_include_i2s_controller(void) +void test_app_include_i2s(void) { } @@ -192,35 +198,37 @@ finish: // To check if the software logic of I2S driver is correct TEST_CASE("I2S basic driver apply, delete test", "[i2s]") { - i2s_gpio_config_t i2s_pin = I2S_TEST_MASTER_DEFAULT_PIN; i2s_chan_handle_t tx_handle; i2s_chan_handle_t rx_handle; - i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); - i2s_std_slot_config_t slot_cfg = I2S_STD_PHILIP_SLOT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO); - i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(SAMPLE_RATE); + i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER); + i2s_std_config_t std_cfg = { + .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(SAMPLE_RATE), + .slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO), + .gpio_cfg = I2S_TEST_MASTER_DEFAULT_PIN, + }; /* TX channel basic test */ TEST_ESP_OK(i2s_new_channel(&chan_cfg, &tx_handle, NULL)); - TEST_ESP_OK(i2s_init_channel(tx_handle, &clk_cfg, &slot_cfg)); - slot_cfg.data_bit_width = I2S_DATA_BIT_WIDTH_32BIT; - TEST_ESP_OK(i2s_set_slot(tx_handle, &slot_cfg)); - clk_cfg.sample_rate = 44100; - TEST_ESP_OK(i2s_set_clock(tx_handle, &clk_cfg)); + TEST_ESP_OK(i2s_init_std_channel(tx_handle, &std_cfg)); + std_cfg.slot_cfg.data_bit_width = I2S_DATA_BIT_WIDTH_32BIT; + TEST_ESP_OK(i2s_reconfig_std_slot(tx_handle, &std_cfg.slot_cfg)); + std_cfg.clk_cfg.sample_rate_hz = 44100; + TEST_ESP_OK(i2s_reconfig_std_clock(tx_handle, &std_cfg.clk_cfg)); TEST_ESP_OK(i2s_start_channel(tx_handle)); TEST_ESP_OK(i2s_del_channel(tx_handle)); /* Duplex channel basic test */ chan_cfg.id = I2S_NUM_0; // Specify port id to I2S port 0 TEST_ESP_OK(i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle)); - TEST_ESP_OK(i2s_init_channel(tx_handle, &clk_cfg, &slot_cfg)); - TEST_ESP_OK(i2s_init_channel(rx_handle, &clk_cfg, &slot_cfg)); + TEST_ESP_OK(i2s_init_std_channel(tx_handle, &std_cfg)); + TEST_ESP_OK(i2s_init_std_channel(rx_handle, &std_cfg)); TEST_ESP_OK(i2s_del_channel(tx_handle)); TEST_ESP_OK(i2s_del_channel(rx_handle)); - /* Repeat to check if a same port can be applied again */ + /* Repeat to check if a same port can be allocated again */ TEST_ESP_OK(i2s_new_channel(&chan_cfg, NULL, &rx_handle)); TEST_ESP_OK(i2s_del_channel(rx_handle)); @@ -235,15 +243,20 @@ TEST_CASE("I2S basic driver apply, delete test", "[i2s]") TEST_CASE("I2S memory leak test", "[i2s]") { - i2s_gpio_config_t i2s_pin = I2S_TEST_MASTER_DEFAULT_PIN; - i2s_chan_handle_t tx_handle; i2s_chan_handle_t rx_handle; - i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); + i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER); + i2s_std_config_t std_cfg = { + .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(SAMPLE_RATE), + .slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO), + .gpio_cfg = I2S_TEST_MASTER_DEFAULT_PIN, + }; /* The first operation will always take some memory */ TEST_ESP_OK(i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle)); + TEST_ESP_OK(i2s_init_std_channel(tx_handle, &std_cfg)); + TEST_ESP_OK(i2s_init_std_channel(rx_handle, &std_cfg)); TEST_ESP_OK(i2s_del_channel(tx_handle)); TEST_ESP_OK(i2s_del_channel(rx_handle)); @@ -251,6 +264,8 @@ TEST_CASE("I2S memory leak test", "[i2s]") printf("\r\nHeap size before: %d\n", memory_left); for (int i = 0; i < 100; i++) { TEST_ESP_OK(i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle)); + TEST_ESP_OK(i2s_init_std_channel(tx_handle, &std_cfg)); + TEST_ESP_OK(i2s_init_std_channel(rx_handle, &std_cfg)); TEST_ESP_OK(i2s_del_channel(tx_handle)); TEST_ESP_OK(i2s_del_channel(rx_handle)); TEST_ASSERT(memory_left == esp_get_free_heap_size()); @@ -260,18 +275,18 @@ TEST_CASE("I2S memory leak test", "[i2s]") TEST_CASE("I2S loopback test", "[i2s]") { - i2s_gpio_config_t i2s_pin = I2S_TEST_MASTER_DEFAULT_PIN; - i2s_chan_handle_t tx_handle; i2s_chan_handle_t rx_handle; - i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); - i2s_std_slot_config_t slot_cfg = I2S_STD_PHILIP_SLOT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO); - i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(SAMPLE_RATE); - chan_cfg.id = I2S_NUM_0; + i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER); + i2s_std_config_t std_cfg = { + .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(SAMPLE_RATE), + .slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO), + .gpio_cfg = I2S_TEST_MASTER_DEFAULT_PIN, + }; TEST_ESP_OK(i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle)); - TEST_ESP_OK(i2s_init_channel(tx_handle, &clk_cfg, &slot_cfg)); - TEST_ESP_OK(i2s_init_channel(rx_handle, &clk_cfg, &slot_cfg)); + TEST_ESP_OK(i2s_init_std_channel(tx_handle, &std_cfg)); + TEST_ESP_OK(i2s_init_std_channel(rx_handle, &std_cfg)); i2s_test_io_config(I2S_TEST_MODE_LOOPBACK); TEST_ESP_OK(i2s_start_channel(tx_handle)); @@ -286,23 +301,28 @@ TEST_CASE("I2S loopback test", "[i2s]") #if SOC_I2S_NUM > 1 TEST_CASE("I2S master write slave read test", "[i2s]") { - i2s_gpio_config_t mst_pin = I2S_TEST_MASTER_DEFAULT_PIN; - i2s_gpio_config_t slv_pin = I2S_TEST_SLAVE_DEFAULT_PIN; - i2s_chan_handle_t tx_handle; i2s_chan_handle_t rx_handle; - i2s_chan_config_t mst_chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &mst_pin); - mst_chan_cfg.id = I2S_NUM_0; - i2s_chan_config_t slv_chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_SLAVE, I2S_COMM_MODE_STD, &slv_pin); - slv_chan_cfg.id = I2S_NUM_1; - i2s_std_slot_config_t slot_cfg = I2S_STD_PHILIP_SLOT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO); - i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(SAMPLE_RATE); + i2s_chan_config_t mst_chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER); + i2s_chan_config_t slv_chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_1, I2S_ROLE_SLAVE); + + i2s_std_config_t std_mst_cfg = { + .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(SAMPLE_RATE), + .slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO), + .gpio_cfg = I2S_TEST_MASTER_DEFAULT_PIN, + }; + + i2s_std_config_t std_slv_cfg = { + .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(SAMPLE_RATE), + .slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO), + .gpio_cfg = I2S_TEST_SLAVE_DEFAULT_PIN, + }; TEST_ESP_OK(i2s_new_channel(&mst_chan_cfg, &tx_handle, NULL)); TEST_ESP_OK(i2s_new_channel(&slv_chan_cfg, NULL, &rx_handle)); - TEST_ESP_OK(i2s_init_channel(tx_handle, &clk_cfg, &slot_cfg)); - TEST_ESP_OK(i2s_init_channel(rx_handle, &clk_cfg, &slot_cfg)); + TEST_ESP_OK(i2s_init_std_channel(tx_handle, &std_mst_cfg)); + TEST_ESP_OK(i2s_init_std_channel(rx_handle, &std_slv_cfg)); i2s_test_io_config(I2S_TEST_MODE_MASTER_TO_SLAVE); TEST_ESP_OK(i2s_start_channel(tx_handle)); @@ -316,23 +336,27 @@ TEST_CASE("I2S master write slave read test", "[i2s]") TEST_CASE("I2S master read slave write test", "[i2s]") { - i2s_gpio_config_t mst_pin = I2S_TEST_MASTER_DEFAULT_PIN; - i2s_gpio_config_t slv_pin = I2S_TEST_SLAVE_DEFAULT_PIN; - i2s_chan_handle_t tx_handle; i2s_chan_handle_t rx_handle; - i2s_chan_config_t mst_chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &mst_pin); - mst_chan_cfg.id = I2S_NUM_0; - i2s_chan_config_t slv_chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_SLAVE, I2S_COMM_MODE_STD, &slv_pin); - slv_chan_cfg.id = I2S_NUM_1; - i2s_std_slot_config_t slot_cfg = I2S_STD_PHILIP_SLOT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO); - i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(SAMPLE_RATE); + i2s_chan_config_t mst_chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER); + i2s_chan_config_t slv_chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_1, I2S_ROLE_SLAVE); + i2s_std_config_t std_mst_cfg = { + .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(SAMPLE_RATE), + .slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO), + .gpio_cfg = I2S_TEST_MASTER_DEFAULT_PIN, + }; + + i2s_std_config_t std_slv_cfg = { + .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(SAMPLE_RATE), + .slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO), + .gpio_cfg = I2S_TEST_SLAVE_DEFAULT_PIN, + }; TEST_ESP_OK(i2s_new_channel(&mst_chan_cfg, NULL, &rx_handle)); TEST_ESP_OK(i2s_new_channel(&slv_chan_cfg, &tx_handle, NULL)); - TEST_ESP_OK(i2s_init_channel(tx_handle, &clk_cfg, &slot_cfg)); - TEST_ESP_OK(i2s_init_channel(rx_handle, &clk_cfg, &slot_cfg)); + TEST_ESP_OK(i2s_init_std_channel(tx_handle, &std_slv_cfg)); + TEST_ESP_OK(i2s_init_std_channel(rx_handle, &std_mst_cfg)); i2s_test_io_config(I2S_TEST_MODE_SLAVE_TO_MASTER); TEST_ESP_OK(i2s_start_channel(tx_handle)); @@ -348,26 +372,28 @@ TEST_CASE("I2S master read slave write test", "[i2s]") /*------------------------------ Clock Test --------------------------------*/ #if SOC_PCNT_SUPPORTED #define TEST_I2S_PERIOD_MS 100 -static void i2s_test_common_sample_rate(i2s_chan_handle_t rx_chan, i2s_clk_config_t* clk_cfg) +static void i2s_test_common_sample_rate(i2s_chan_handle_t rx_chan, i2s_std_clk_config_t* clk_cfg) { TEST_ASSERT_NOT_NULL(rx_chan); TEST_ASSERT_NOT_NULL(clk_cfg); /* Prepare configuration for the PCNT unit */ - pcnt_config_t pcnt_cfg = { - // Set PCNT input signal and control GPIOs - .pulse_gpio_num = MASTER_WS_IO, - .ctrl_gpio_num = -1, - .channel = PCNT_CHANNEL_0, - .unit = PCNT_UNIT_0, - .pos_mode = PCNT_COUNT_INC, // Count up on the positive edge - .neg_mode = PCNT_COUNT_DIS, // Keep the counter value on the negative edge - .lctrl_mode = PCNT_MODE_KEEP, - .hctrl_mode = PCNT_MODE_KEEP, - .counter_h_lim = (int16_t)0x7fff, - .counter_l_lim = (int16_t)0x8000, + pcnt_unit_handle_t pcnt_unit = NULL; + pcnt_channel_handle_t pcnt_chan = NULL; + + pcnt_unit_config_t unit_config = { + .high_limit = (int16_t)0x7fff, + .low_limit = (int16_t)0x8000, }; - TEST_ESP_OK(pcnt_unit_config(&pcnt_cfg)); + pcnt_chan_config_t chan_config = { + .edge_gpio_num = MASTER_WS_IO, + .level_gpio_num = -1, + }; + TEST_ESP_OK(pcnt_new_unit(&unit_config, &pcnt_unit)); + TEST_ESP_OK(pcnt_unit_set_glitch_filter(pcnt_unit, NULL)); + TEST_ESP_OK(pcnt_new_channel(pcnt_unit, &chan_config, &pcnt_chan)); + TEST_ESP_OK(pcnt_channel_set_edge_action(pcnt_chan, PCNT_CHANNEL_EDGE_ACTION_INCREASE, PCNT_CHANNEL_EDGE_ACTION_HOLD)); + TEST_ESP_OK(pcnt_channel_set_level_action(pcnt_chan, PCNT_CHANNEL_LEVEL_ACTION_KEEP, PCNT_CHANNEL_LEVEL_ACTION_KEEP)); // Reconfig GPIO signal gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[MASTER_WS_IO], PIN_FUNC_GPIO); @@ -375,26 +401,23 @@ static void i2s_test_common_sample_rate(i2s_chan_handle_t rx_chan, i2s_clk_confi esp_rom_gpio_connect_out_signal(MASTER_WS_IO, i2s_periph_signal[0].m_rx_ws_sig, 0, 0); esp_rom_gpio_connect_in_signal(MASTER_WS_IO, pcnt_periph_signals.groups[0].units[0].channels[0].pulse_sig, 0); - // pcnt_set_filter_value(PCNT_UNIT_0, 10); - pcnt_filter_disable(PCNT_UNIT_0); - // Test common sample rate uint32_t test_freq[15] = {8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000, 128000, 144000, 196000}; - int16_t real_pulse = 0; + int real_pulse = 0; for (int i = 0; i < 15; i++) { - int16_t expt_pulse = (int16_t)((float)test_freq[i] * (TEST_I2S_PERIOD_MS / 1000.0)); - clk_cfg->sample_rate = test_freq[i]; - TEST_ESP_OK(i2s_set_clock(rx_chan, clk_cfg)); + int expt_pulse = (int)((float)test_freq[i] * (TEST_I2S_PERIOD_MS / 1000.0)); + clk_cfg->sample_rate_hz = test_freq[i]; + TEST_ESP_OK(i2s_reconfig_std_clock(rx_chan, clk_cfg)); TEST_ESP_OK(i2s_start_channel(rx_chan)); vTaskDelay(1); // Waiting for hardware totally started // pcnt will count the pulse number on WS signal in 100ms - TEST_ESP_OK(pcnt_counter_clear(PCNT_UNIT_0)); - TEST_ESP_OK(pcnt_counter_resume(PCNT_UNIT_0)); + TEST_ESP_OK(pcnt_unit_clear_count(pcnt_unit)); + TEST_ESP_OK(pcnt_unit_start(pcnt_unit)); vTaskDelay(pdMS_TO_TICKS(TEST_I2S_PERIOD_MS)); - TEST_ESP_OK(pcnt_counter_pause(PCNT_UNIT_0)); - TEST_ESP_OK(pcnt_get_counter_value(PCNT_UNIT_0, &real_pulse)); + TEST_ESP_OK(pcnt_unit_stop(pcnt_unit)); + TEST_ESP_OK(pcnt_unit_get_count(pcnt_unit, &real_pulse)); printf("[%d Hz] %d pulses, expected %d, err %d\n", test_freq[i], real_pulse, expt_pulse, real_pulse - expt_pulse); TEST_ESP_OK(i2s_stop_channel(rx_chan)); // Check if the error between real pulse number and expected pulse number is within 1% @@ -404,39 +427,39 @@ static void i2s_test_common_sample_rate(i2s_chan_handle_t rx_chan, i2s_clk_confi TEST_CASE("I2S D2CLK clock test", "[i2s]") { - i2s_gpio_config_t i2s_pin = I2S_TEST_MASTER_DEFAULT_PIN; - i2s_chan_handle_t rx_handle; - i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); - i2s_std_slot_config_t slot_cfg = I2S_STD_PHILIP_SLOT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO); - i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(SAMPLE_RATE); - chan_cfg.id = I2S_NUM_0; + i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER); + i2s_std_config_t std_cfg = { + .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(SAMPLE_RATE), + .slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO), + .gpio_cfg = I2S_TEST_MASTER_DEFAULT_PIN, + }; TEST_ESP_OK(i2s_new_channel(&chan_cfg, NULL, &rx_handle)); - TEST_ESP_OK(i2s_init_channel(rx_handle, &clk_cfg, &slot_cfg)); + TEST_ESP_OK(i2s_init_std_channel(rx_handle, &std_cfg)); - i2s_test_common_sample_rate(rx_handle, (i2s_clk_config_t *)&clk_cfg); + i2s_test_common_sample_rate(rx_handle, &std_cfg.clk_cfg); TEST_ESP_OK(i2s_del_channel(rx_handle)); } #if SOC_I2S_SUPPORTS_APLL TEST_CASE("I2S APLL clock test", "[i2s]") { - i2s_gpio_config_t i2s_pin = I2S_TEST_MASTER_DEFAULT_PIN; - i2s_chan_handle_t rx_handle; - i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); - i2s_std_slot_config_t slot_cfg = I2S_STD_PHILIP_SLOT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO); - i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(SAMPLE_RATE); - chan_cfg.id = I2S_NUM_0; - clk_cfg.clk_src = I2S_CLK_APLL; + i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER); + i2s_std_config_t std_cfg = { + .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(SAMPLE_RATE), + .slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO), + .gpio_cfg = I2S_TEST_MASTER_DEFAULT_PIN, + }; + std_cfg.clk_cfg.clk_src = I2S_CLK_APLL; TEST_ESP_OK(i2s_new_channel(&chan_cfg, NULL, &rx_handle)); - TEST_ESP_OK(i2s_init_channel(rx_handle, &clk_cfg, &slot_cfg)); + TEST_ESP_OK(i2s_init_std_channel(rx_handle, &std_cfg)); - i2s_test_common_sample_rate(rx_handle, (i2s_clk_config_t *)&clk_cfg); + i2s_test_common_sample_rate(rx_handle, &std_cfg.clk_cfg); TEST_ESP_OK(i2s_del_channel(rx_handle)); } #endif // SOC_I2S_SUPPORTS_APLL @@ -467,17 +490,19 @@ TEST_CASE("I2S package lost test", "[i2s]") * 2. dma_desc_num > polling_cycle / interrupt_interval = cell(2.818) = 3 * 3. recv_buffer_size > dma_desc_num * dma_buffer_size = 3 * 4092 = 12276 bytes */ #define TEST_RECV_BUF_LEN 12276 - i2s_gpio_config_t i2s_pin = I2S_TEST_MASTER_DEFAULT_PIN; i2s_chan_handle_t rx_handle; - i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); - i2s_std_slot_config_t slot_cfg = I2S_STD_PHILIP_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_STEREO); - slot_cfg.dma_desc_num = 3; - slot_cfg.dma_frame_num = 511; - i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(SAMPLE_RATE); + i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER); + chan_cfg.dma_desc_num = 3; + chan_cfg.dma_frame_num = 511; + i2s_std_config_t std_cfg = { + .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(SAMPLE_RATE), + .slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_STEREO), + .gpio_cfg = I2S_TEST_MASTER_DEFAULT_PIN, + }; TEST_ESP_OK(i2s_new_channel(&chan_cfg, NULL, &rx_handle)); - TEST_ESP_OK(i2s_init_channel(rx_handle, &clk_cfg, &slot_cfg)); + TEST_ESP_OK(i2s_init_std_channel(rx_handle, &std_cfg)); TaskHandle_t h_monitor_task; xTaskCreate(i2s_event_monitor, "event monitor task", 4096, &rx_handle, 5, &h_monitor_task); @@ -489,8 +514,9 @@ TEST_CASE("I2S package lost test", "[i2s]") int i; for (i = 0; i < test_num; i++) { printf("Testing %d Hz sample rate\n", test_freq[i]); - clk_cfg.sample_rate = test_freq[i]; - TEST_ESP_OK(i2s_set_clock(rx_handle, &clk_cfg)); + std_cfg.clk_cfg.sample_rate_hz = test_freq[i]; + std_cfg.clk_cfg.sample_rate_hz = test_freq[i]; + TEST_ESP_OK(i2s_reconfig_std_clock(rx_handle, &std_cfg.clk_cfg)); TEST_ESP_OK(i2s_start_channel(rx_handle)); for (int j = 0; j < 10; j++) { TEST_ESP_OK(i2s_read_channel(rx_handle, (void *)data, TEST_RECV_BUF_LEN, &bytes_read, portMAX_DELAY)); diff --git a/components/esp_lcd/src/esp_lcd_panel_io_i2s.c b/components/esp_lcd/src/esp_lcd_panel_io_i2s.c index f341f2be36..dc50ad840e 100644 --- a/components/esp_lcd/src/esp_lcd_panel_io_i2s.c +++ b/components/esp_lcd/src/esp_lcd_panel_io_i2s.c @@ -593,7 +593,7 @@ static esp_err_t i2s_lcd_select_periph_clock(esp_lcd_i80_bus_handle_t bus, lcd_c switch (src) { case LCD_CLK_SRC_PLL160M: bus->resolution_hz = 160000000 / LCD_PERIPH_CLOCK_PRE_SCALE; - i2s_ll_tx_clk_set_src(bus->hal.dev, I2S_CLK_160M_PLL); + i2s_ll_tx_clk_set_src(bus->hal.dev, I2S_CLK_PLL_160M); #if CONFIG_PM_ENABLE ret = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "i2s_controller_lcd", &bus->pm_lock); ESP_RETURN_ON_ERROR(ret, TAG, "create ESP_PM_APB_FREQ_MAX lock failed"); diff --git a/components/esp_lcd/test_apps/i80_lcd/main/test_i80_lcd_panel.c b/components/esp_lcd/test_apps/i80_lcd/main/test_i80_lcd_panel.c index 4062f7fae1..8ab5618f63 100644 --- a/components/esp_lcd/test_apps/i80_lcd/main/test_i80_lcd_panel.c +++ b/components/esp_lcd/test_apps/i80_lcd/main/test_i80_lcd_panel.c @@ -18,7 +18,7 @@ #include "test_i80_board.h" #if SOC_I2S_LCD_I80_VARIANT -#include "driver/i2s_controller.h" +#include "driver/i2s_std.h" TEST_CASE("i80_and_i2s_driver_co-existence", "[lcd][i2s]") { @@ -44,15 +44,7 @@ TEST_CASE("i80_and_i2s_driver_co-existence", "[lcd][i2s]") i2s_chan_handle_t tx_handle = NULL; - i2s_gpio_config_t i2s_pin = { - .mclk = I2S_GPIO_UNUSED, - .bclk = I2S_GPIO_UNUSED, - .ws = I2S_GPIO_UNUSED, - .dout = I2S_GPIO_UNUSED, - .din = I2S_GPIO_UNUSED - }; - i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); - chan_cfg.id = 0; + i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER); // I2S driver won't be installed as the same I2S port has been used by LCD TEST_ASSERT_EQUAL(ESP_ERR_NOT_FOUND, i2s_new_channel(&chan_cfg, &tx_handle, NULL)); TEST_ESP_OK(esp_lcd_del_i80_bus(i80_bus)); @@ -463,7 +455,7 @@ TEST_CASE("lcd_panel_with_i80_interface_(st7789, 8bits)", "[lcd]") } #if SOC_I2S_LCD_I80_VARIANT -#include "driver/i2s_controller.h" +#include "driver/i2s_std.h" TEST_CASE("i80 and i2s driver coexistance", "[lcd][i2s]") { @@ -486,15 +478,7 @@ TEST_CASE("i80 and i2s driver coexistance", "[lcd][i2s]") }; TEST_ESP_OK(esp_lcd_new_i80_bus(&bus_config, &i80_bus)); - i2s_gpio_config_t i2s_pin = { - .mclk = 0, - .bclk = 15, - .ws = 25, - .dout = 21, - .din = 22 - }; - i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); - chan_cfg.id = I2S_NUM_0; + i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER); i2s_chan_handle_t tx_handle; // I2S driver won't be installed as the same I2S port has been used by LCD TEST_ASSERT_EQUAL(ESP_ERR_NOT_FOUND, i2s_new_channel(&chan_cfg, &tx_handle, NULL)); diff --git a/components/hal/adc_hal.c b/components/hal/adc_hal.c index efb28c154a..4e7fc20610 100644 --- a/components/hal/adc_hal.c +++ b/components/hal/adc_hal.c @@ -189,7 +189,7 @@ static void adc_hal_digi_sample_freq_config(adc_hal_dma_ctx_t *hal, uint32_t fre adc_ll_digi_controller_clk_div(ADC_LL_CLKM_DIV_NUM_DEFAULT, ADC_LL_CLKM_DIV_B_DEFAULT, ADC_LL_CLKM_DIV_A_DEFAULT); adc_ll_digi_clk_sel(0); //use APB #else - i2s_ll_rx_clk_set_src(hal->dev, I2S_CLK_160M_PLL); /*!< Clock from PLL_D2_CLK(160M)*/ + i2s_ll_rx_clk_set_src(hal->dev, I2S_CLK_PLL_160M); /*!< Clock from PLL_D2_CLK(160M)*/ uint32_t bck = I2S_BASE_CLK / (ADC_LL_CLKM_DIV_NUM_DEFAULT + ADC_LL_CLKM_DIV_B_DEFAULT / ADC_LL_CLKM_DIV_A_DEFAULT) / 2 / freq; i2s_ll_set_raw_mclk_div(hal->dev, ADC_LL_CLKM_DIV_NUM_DEFAULT, ADC_LL_CLKM_DIV_A_DEFAULT, ADC_LL_CLKM_DIV_B_DEFAULT); i2s_ll_rx_set_bck_div_num(hal->dev, bck); diff --git a/components/hal/esp32c3/include/hal/i2s_ll.h b/components/hal/esp32c3/include/hal/i2s_ll.h index 860214db67..72083a93e6 100644 --- a/components/hal/esp32c3/include/hal/i2s_ll.h +++ b/components/hal/esp32c3/include/hal/i2s_ll.h @@ -200,7 +200,7 @@ static inline void i2s_ll_tx_clk_set_src(i2s_dev_t *hw, i2s_clock_src_t src) * @brief Set RX source clock * * @param hw Peripheral I2S hardware instance address. - * @param src I2S source clock, ESP32-C3 only support `I2S_CLK_160M_PLL` + * @param src I2S source clock, ESP32-C3 only support `I2S_CLK_PLL_160M` */ static inline void i2s_ll_rx_clk_set_src(i2s_dev_t *hw, i2s_clock_src_t src) { diff --git a/components/hal/esp32h2/include/hal/i2s_ll.h b/components/hal/esp32h2/include/hal/i2s_ll.h index f610367dfb..d1e6b62a6f 100644 --- a/components/hal/esp32h2/include/hal/i2s_ll.h +++ b/components/hal/esp32h2/include/hal/i2s_ll.h @@ -201,7 +201,7 @@ static inline void i2s_ll_tx_clk_set_src(i2s_dev_t *hw, i2s_clock_src_t src) * @brief Set RX source clock * * @param hw Peripheral I2S hardware instance address. - * @param src I2S source clock, ESP32-H2 only support `I2S_CLK_160M_PLL` + * @param src I2S source clock, ESP32-H2 only support `I2S_CLK_PLL_160M` */ static inline void i2s_ll_rx_clk_set_src(i2s_dev_t *hw, i2s_clock_src_t src) { diff --git a/components/hal/esp32s3/include/hal/i2s_ll.h b/components/hal/esp32s3/include/hal/i2s_ll.h index e2712aed7b..133b1952cc 100644 --- a/components/hal/esp32s3/include/hal/i2s_ll.h +++ b/components/hal/esp32s3/include/hal/i2s_ll.h @@ -190,7 +190,7 @@ static inline void i2s_ll_rx_reset_fifo(i2s_dev_t *hw) * @brief Set TX source clock * * @param hw Peripheral I2S hardware instance address. - * @param src I2S source clock, ESP32-S3 only support `I2S_CLK_160M_PLL` + * @param src I2S source clock, ESP32-S3 only support `I2S_CLK_PLL_160M` * TX and RX share the same clock setting */ static inline void i2s_ll_tx_clk_set_src(i2s_dev_t *hw, i2s_clock_src_t src) @@ -202,7 +202,7 @@ static inline void i2s_ll_tx_clk_set_src(i2s_dev_t *hw, i2s_clock_src_t src) * @brief Set RX source clock * * @param hw Peripheral I2S hardware instance address. - * @param src I2S source clock, ESP32-S3 only support `I2S_CLK_160M_PLL` + * @param src I2S source clock, ESP32-S3 only support `I2S_CLK_PLL_160M` * TX and RX share the same clock setting */ static inline void i2s_ll_rx_clk_set_src(i2s_dev_t *hw, i2s_clock_src_t src) diff --git a/components/hal/i2s_hal.c b/components/hal/i2s_hal.c index 39af05752b..8db8e27fc6 100644 --- a/components/hal/i2s_hal.c +++ b/components/hal/i2s_hal.c @@ -206,7 +206,7 @@ void i2s_hal_tdm_set_tx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_ha i2s_ll_tx_set_sample_bit(hal->dev, slot_bit_width, slot_cfg->data_bit_width); i2s_ll_tx_enable_mono_mode(hal->dev, slot_cfg->slot_mode == I2S_SLOT_MODE_MONO); i2s_ll_tx_enable_msb_shift(hal->dev, slot_cfg->tdm.bit_shift); - if (slot_cfg->tdm.ws_width == I2S_TDM_AUTO_WS_WIDTH) { + if (slot_cfg->tdm.ws_width == 0) { // 0: I2S_TDM_AUTO_WS_WIDTH i2s_ll_tx_set_ws_width(hal->dev, (total_slot * slot_bit_width) / 2); } else { i2s_ll_tx_set_ws_width(hal->dev, slot_cfg->tdm.ws_width); @@ -241,7 +241,7 @@ void i2s_hal_tdm_set_rx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_ha i2s_ll_rx_set_sample_bit(hal->dev, slot_bit_width, slot_cfg->data_bit_width); i2s_ll_rx_enable_mono_mode(hal->dev, slot_cfg->slot_mode == I2S_SLOT_MODE_MONO); i2s_ll_rx_enable_msb_shift(hal->dev, slot_cfg->tdm.bit_shift); - if (slot_cfg->tdm.ws_width == I2S_TDM_AUTO_WS_WIDTH) { + if (slot_cfg->tdm.ws_width == 0) { // 0: I2S_TDM_AUTO_WS_WIDTH i2s_ll_rx_set_ws_width(hal->dev, (total_slot * slot_bit_width) / 2); } else { i2s_ll_rx_set_ws_width(hal->dev, slot_cfg->tdm.ws_width); diff --git a/components/hal/include/hal/i2s_hal.h b/components/hal/include/hal/i2s_hal.h index 54a424b17b..650e5d4c26 100644 --- a/components/hal/include/hal/i2s_hal.h +++ b/components/hal/include/hal/i2s_hal.h @@ -28,7 +28,6 @@ extern "C" { * @note It is a general purpose struct, not supposed to be used directly by user */ typedef struct { - i2s_comm_mode_t mode; /*!< I2S communication mode, this field is for identification (MUST match the communication mode that applied) */ i2s_data_bit_width_t data_bit_width; /*!< I2S sample data bit width (valid data bits per sample) */ i2s_slot_bit_width_t slot_bit_width; /*!< I2S slot bit width (total bits per slot) */ i2s_slot_mode_t slot_mode; /*!< Set mono or stereo mode with I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO */ diff --git a/components/hal/include/hal/i2s_types.h b/components/hal/include/hal/i2s_types.h index 5f60a408b2..3d370511f3 100644 --- a/components/hal/include/hal/i2s_types.h +++ b/components/hal/include/hal/i2s_types.h @@ -108,7 +108,7 @@ typedef enum { } i2s_mclk_multiple_t; typedef enum { - I2S_CLK_160M_PLL = 0, /*!< I2S controller clock source PLL_D2_CLK(160M)*/ + I2S_CLK_PLL_160M = 0, /*!< I2S controller clock source PLL_D2_CLK(160M)*/ #if SOC_I2S_SUPPORTS_APLL I2S_CLK_APLL, /*!< I2S controller clock source APLL*/ #endif diff --git a/docs/doxygen/Doxyfile b/docs/doxygen/Doxyfile index fb57d3e97b..34b7ba0609 100644 --- a/docs/doxygen/Doxyfile +++ b/docs/doxygen/Doxyfile @@ -158,11 +158,12 @@ INPUT = \ $(PROJECT_PATH)/components/hal/include/hal/i2c_types.h \ $(PROJECT_PATH)/components/hal/include/hal/i2s_types.h \ $(PROJECT_PATH)/components/hal/include/hal/lcd_types.h \ - $(PROJECT_PATH)/components/driver/include/driver/i2s_controller.h \ - $(PROJECT_PATH)/components/hal/include/hal/i2s_std.h \ - $(PROJECT_PATH)/components/hal/include/hal/i2s_pdm.h \ - $(PROJECT_PATH)/components/hal/include/hal/i2s_tdm.h \ + $(PROJECT_PATH)/components/driver/include/driver/i2s_common.h \ + $(PROJECT_PATH)/components/driver/include/driver/i2s_std.h \ + $(PROJECT_PATH)/components/driver/include/driver/i2s_pdm.h \ + $(PROJECT_PATH)/components/driver/include/driver/i2s_tdm.h \ $(PROJECT_PATH)/components/hal/include/hal/ledc_types.h \ + $(PROJECT_PATH)/components/hal/include/hal/rmt_types.h \ $(PROJECT_PATH)/components/hal/include/hal/rtc_io_types.h \ $(PROJECT_PATH)/components/hal/include/hal/sdio_slave_types.h \ $(PROJECT_PATH)/components/hal/include/hal/sigmadelta_types.h \ diff --git a/docs/en/api-reference/peripherals/i2s.rst b/docs/en/api-reference/peripherals/i2s.rst index 36f219c031..d432802ca7 100644 --- a/docs/en/api-reference/peripherals/i2s.rst +++ b/docs/en/api-reference/peripherals/i2s.rst @@ -147,11 +147,11 @@ I2S Clock Clock Source ^^^^^^^^^^^^ -- :cpp:member:`i2s_clock_src_t::I2S_CLK_160M_PLL`: 160 MHz PLL clock. +- :cpp:member:`i2s_clock_src_t::I2S_CLK_PLL_160M`: 160 MHz PLL clock. .. only:: SOC_I2S_SUPPORTS_APLL - - :cpp:member:`i2s_clock_src_t::I2S_CLK_APLL`: Audio PLL clock, more precise than ``I2S_CLK_160M_PLL`` in high sample rate applications. Its frequency is configurable according to the sample rate, but if APLL has been occupied by emac or other channels already, the APLL frequency is not allowed to change, the driver will try to work under this APLL frequency, if this APLL frequency can't meet the requirements of I2S, the clock configuration will fail. + - :cpp:member:`i2s_clock_src_t::I2S_CLK_APLL`: Audio PLL clock, more precise than ``I2S_CLK_PLL_160M`` in high sample rate applications. Its frequency is configurable according to the sample rate, but if APLL has been occupied by emac or other channels already, the APLL frequency is not allowed to change, the driver will try to work under this APLL frequency, if this APLL frequency can't meet the requirements of I2S, the clock configuration will fail. Clock Concepts ^^^^^^^^^^^^^^ diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_av.c b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_av.c index 6eb9009a9a..98e5beff75 100644 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_av.c +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_av.c @@ -24,7 +24,7 @@ // DAC DMA mode is only supported by the legacy I2S driver, it will be replaced once DAC has its own DMA dirver #include "driver/i2s.h" #else -#include "driver/i2s_controller.h" +#include "driver/i2s_std.h" #endif #include "sys/lock.h" @@ -187,21 +187,22 @@ void bt_i2s_driver_install(void) i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN); i2s_set_pin(0, NULL); #else - i2s_gpio_config_t i2s_pin = { - .mclk = I2S_GPIO_UNUSED, - .bclk = CONFIG_EXAMPLE_I2S_BCK_PIN, - .ws = CONFIG_EXAMPLE_I2S_LRCK_PIN, - .dout = CONFIG_EXAMPLE_I2S_DATA_PIN, - .din = I2S_GPIO_UNUSED + i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER); + chan_cfg.auto_clear = true; + i2s_std_config_t std_cfg = { + .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(44100), + .slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO), + .gpio_cfg = { + .mclk = I2S_GPIO_UNUSED, + .bclk = CONFIG_EXAMPLE_I2S_BCK_PIN, + .ws = CONFIG_EXAMPLE_I2S_LRCK_PIN, + .dout = CONFIG_EXAMPLE_I2S_DATA_PIN, + .din = I2S_GPIO_UNUSED, + }, }; - i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); - chan_cfg.id = I2S_NUM_0; - i2s_std_slot_config_t slot_cfg = I2S_STD_MSB_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO); - slot_cfg.auto_clear = true; - i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(44100); /* enable I2S */ i2s_new_channel(&chan_cfg, &tx_chan, NULL); - i2s_init_channel(tx_chan, &clk_cfg, &slot_cfg); + i2s_init_std_channel(tx_chan, &std_cfg); i2s_start_channel(tx_chan); #endif } @@ -306,8 +307,8 @@ static void bt_av_hdl_a2d_evt(uint16_t event, void *p_param) #ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC i2s_set_clk(0, sample_rate, 16, 2); #else - i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(sample_rate); - i2s_set_clock(tx_chan, &clk_cfg); + i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(sample_rate); + i2s_reconfig_std_clock(tx_chan, &clk_cfg); #endif ESP_LOGI(BT_AV_TAG, "Configure audio player: %x-%x-%x-%x", a2d->audio_cfg.mcc.cie.sbc[0], diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_core.c b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_core.c index 5ede922e62..d99e22e68b 100644 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_core.c +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_core.c @@ -18,7 +18,7 @@ // DAC DMA mode is only supported by the legacy I2S driver, it will be replaced once DAC has its own DMA dirver #include "driver/i2s.h" #else -#include "driver/i2s_controller.h" +#include "driver/i2s_std.h" #endif #include "freertos/ringbuf.h" diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/tutorial/Example_A2DP_Sink.md b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/tutorial/Example_A2DP_Sink.md index 80e25c90ef..d672a7decf 100644 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/tutorial/Example_A2DP_Sink.md +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/tutorial/Example_A2DP_Sink.md @@ -87,30 +87,44 @@ For example, after executing `esp_bt_gap_start_discovery()`, an event of `ESP_BT The main function installs I2S to play the audio. A loudspeaker, additional ADC or hardware requirements and possibly an external I2S codec may be needed. ```c - /* I2S configuration parameters */ #ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC - i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_ADC_DAC, NULL); - chan_cfg.id = I2S_NUM_0; - i2s_dac_slot_config_t slot_cfg = I2S_DAC_SLOT_CONFIG(I2S_DAC_CHAN_BOTH); - i2s_adc_dac_clk_config_t clk_cfg = I2S_ADC_DAC_CLK_CONFIG(44100); - #else - i2s_gpio_config_t i2s_pin = { - .mclk = I2S_GPIO_UNUSED, - .bclk = CONFIG_EXAMPLE_I2S_BCK_PIN, - .ws = CONFIG_EXAMPLE_I2S_LRCK_PIN, - .dout = CONFIG_EXAMPLE_I2S_DATA_PIN, - .din = I2S_GPIO_UNUSED + /* I2S configuration parameters */ + i2s_config_t i2s_config = { + .mode = I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN, + .sample_rate = 44100, + .bits_per_sample = 16, + .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, /* 2-channels */ + .communication_format = I2S_COMM_FORMAT_STAND_MSB, + .dma_buf_count = 6, + .dma_buf_len = 60, + .intr_alloc_flags = 0, /* default interrupt priority */ + .tx_desc_auto_clear = true /* auto clear tx descriptor on underflow */ + }; + + /* enable I2S */ + i2s_driver_install(0, &i2s_config, 0, NULL); + i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN); + i2s_set_pin(0, NULL); + #else + + i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER); + chan_cfg.auto_clear = true; + i2s_std_config_t std_cfg = { + .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(44100), + .slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO), + .gpio_cfg = { + .mclk = I2S_GPIO_UNUSED, + .bclk = CONFIG_EXAMPLE_I2S_BCK_PIN, + .ws = CONFIG_EXAMPLE_I2S_LRCK_PIN, + .dout = CONFIG_EXAMPLE_I2S_DATA_PIN, + .din = I2S_GPIO_UNUSED, + }, }; - i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); - chan_cfg.id = I2S_NUM_0; - i2s_std_slot_config_t slot_cfg = I2S_STD_MSB_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO); - slot_cfg.auto_clear = true; - i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(44100); - #endif /* enable I2S */ i2s_new_channel(&chan_cfg, &tx_chan, NULL); - i2s_init_channel(tx_chan, &clk_cfg, &slot_cfg); + i2s_init_std_channel(tx_chan, &std_cfg); i2s_start_channel(tx_chan); + #endif ``` ### Paring Parameter Settings diff --git a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_av.c b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_av.c index ee5eb98eae..86e453115d 100644 --- a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_av.c +++ b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_av.c @@ -25,7 +25,7 @@ // DAC DMA mode is only supported by the legacy I2S driver, it will be replaced once DAC has its own DMA dirver #include "driver/i2s.h" #else -#include "driver/i2s_controller.h" +#include "driver/i2s_std.h" #endif #include "sys/lock.h" @@ -173,8 +173,8 @@ static void bt_av_hdl_a2d_evt(uint16_t event, void *p_param) #ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC i2s_set_clk(0, sample_rate, 16, 2); #else - i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(sample_rate); - i2s_set_clock(tx_chan, &clk_cfg); + i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(sample_rate); + i2s_reconfig_clock(tx_chan, &clk_cfg); #endif ESP_LOGI(BT_AV_TAG, "Configure audio player %x-%x-%x-%x", diff --git a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_core.c b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_core.c index 0263e70144..88008a5a6e 100644 --- a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_core.c +++ b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_core.c @@ -19,7 +19,7 @@ // DAC DMA mode is only supported by the legacy I2S driver, it will be replaced once DAC has its own DMA dirver #include "driver/i2s.h" #else -#include "driver/i2s_controller.h" +#include "driver/i2s_std.h" #endif static void bt_app_task_handler(void *arg); diff --git a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/main.c b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/main.c index 517ce7f114..b1cc5a52cc 100644 --- a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/main.c +++ b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/main.c @@ -39,7 +39,7 @@ // DAC DMA mode is only supported by the legacy I2S driver, it will be replaced once DAC has its own DMA dirver #include "driver/i2s.h" #else -#include "driver/i2s_controller.h" +#include "driver/i2s_std.h" #endif #include "esp_gap_ble_api.h" @@ -709,21 +709,22 @@ void app_main(void) i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN); i2s_set_pin(0, NULL); #else - i2s_gpio_config_t i2s_pin = { - .mclk = I2S_GPIO_UNUSED, - .bclk = CONFIG_EXAMPLE_I2S_BCK_PIN, - .ws = CONFIG_EXAMPLE_I2S_LRCK_PIN, - .dout = CONFIG_EXAMPLE_I2S_DATA_PIN, - .din = I2S_GPIO_UNUSED + i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER); + chan_cfg.auto_clear = true; + i2s_std_config_t std_cfg = { + .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(44100), + .slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO), + .gpio_cfg = { + .mclk = I2S_GPIO_UNUSED, + .bclk = CONFIG_EXAMPLE_I2S_BCK_PIN, + .ws = CONFIG_EXAMPLE_I2S_LRCK_PIN, + .dout = CONFIG_EXAMPLE_I2S_DATA_PIN, + .din = I2S_GPIO_UNUSED, + }, }; - i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); - chan_cfg.id = I2S_NUM_0; - i2s_std_slot_config_t slot_cfg = I2S_STD_MSB_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO); - slot_cfg.auto_clear = true; - i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(44100); /* enable I2S */ i2s_new_channel(&chan_cfg, &tx_chan, NULL); - i2s_init_channel(tx_chan, &clk_cfg, &slot_cfg); + i2s_init_std_channel(tx_chan, &std_cfg); i2s_start_channel(tx_chan); #endif diff --git a/examples/peripherals/i2s/i2s_audio_recorder_sdcard/main/i2s_recorder_main.c b/examples/peripherals/i2s/i2s_audio_recorder_sdcard/main/i2s_recorder_main.c index eea6b6cbf3..de7f702dc2 100644 --- a/examples/peripherals/i2s/i2s_audio_recorder_sdcard/main/i2s_recorder_main.c +++ b/examples/peripherals/i2s/i2s_audio_recorder_sdcard/main/i2s_recorder_main.c @@ -16,7 +16,7 @@ #include "esp_vfs_fat.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#include "driver/i2s_controller.h" +#include "driver/i2s_pdm.h" #include "driver/gpio.h" #include "driver/spi_common.h" #include "sdmmc_cmd.h" @@ -170,19 +170,18 @@ void record_wav(uint32_t rec_time) void init_microphone(void) { - i2s_gpio_config_t i2s_pin = { - .mclk = I2S_GPIO_UNUSED, - .bclk = I2S_GPIO_UNUSED, - .ws = CONFIG_EXAMPLE_I2S_CLK_GPIO, - .dout = I2S_GPIO_UNUSED, - .din = CONFIG_EXAMPLE_I2S_DATA_GPIO - }; - i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_PDM, &i2s_pin); - chan_cfg.id = CONFIG_EXAMPLE_I2S_CH; + i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(CONFIG_EXAMPLE_I2S_CH, I2S_ROLE_MASTER); i2s_new_channel(&chan_cfg, NULL, &rx_handle); - i2s_pdm_rx_slot_config_t rx_slot_cfg = I2S_PDM_RX_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO); - i2s_pdm_rx_clk_config_t rx_clk_cfg = I2S_PDM_RX_CLK_CONFIG(CONFIG_EXAMPLE_SAMPLE_RATE); - i2s_init_channel(rx_handle, &rx_clk_cfg, &rx_slot_cfg); + + i2s_pdm_rx_config_t pdm_rx_cfg = { + .clk_cfg = I2S_PDM_RX_CLK_DEFAULT_CONFIG(CONFIG_EXAMPLE_SAMPLE_RATE), + .slot_cfg = I2S_PDM_RX_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO), + .gpio_cfg = { + .clk = CONFIG_EXAMPLE_I2S_CLK_GPIO, + .din = CONFIG_EXAMPLE_I2S_DATA_GPIO, + }, + }; + i2s_init_pdm_rx_channel(rx_handle, &pdm_rx_cfg); i2s_start_channel(rx_handle); } diff --git a/examples/peripherals/i2s/i2s_basic/main/i2s_example_main.c b/examples/peripherals/i2s/i2s_basic/main/i2s_example_main.c index c73d2106a5..ecf64d6ca3 100644 --- a/examples/peripherals/i2s/i2s_basic/main/i2s_example_main.c +++ b/examples/peripherals/i2s/i2s_basic/main/i2s_example_main.c @@ -10,7 +10,7 @@ #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#include "driver/i2s_controller.h" +#include "driver/i2s.h" #include "driver/gpio.h" #include "esp_system.h" #include "esp_log.h" @@ -28,31 +28,27 @@ #define SAMPLE_PER_CYCLE (SAMPLE_RATE/WAVE_FREQ_HZ) -static const char *TAG = "i2s_example"; -static i2s_chan_handle_t tx_handle = NULL; +static const char* TAG = "i2s_example"; static void setup_triangle_sine_waves(int bits) { - int *samples_data = malloc(((bits + 8) / 16) * SAMPLE_PER_CYCLE * 4); + int *samples_data = malloc(((bits+8)/16)*SAMPLE_PER_CYCLE*4); unsigned int i, sample_val; double sin_float, triangle_float, triangle_step = (double) pow(2, bits) / SAMPLE_PER_CYCLE; size_t i2s_bytes_write = 0; - static i2s_std_slot_config_t slot_cfg = I2S_STD_PHILIP_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO); - static i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(SAMPLE_RATE); - printf("\r\nTest bits=%d free mem=%d, written data=%d\n", bits, esp_get_free_heap_size(), ((bits + 8) / 16)*SAMPLE_PER_CYCLE * 4); + printf("\r\nTest bits=%d free mem=%d, written data=%d\n", bits, esp_get_free_heap_size(), ((bits+8)/16)*SAMPLE_PER_CYCLE*4); - triangle_float = -(pow(2, bits) / 2 - 1); + triangle_float = -(pow(2, bits)/2 - 1); - for (i = 0; i < SAMPLE_PER_CYCLE; i++) { + for(i = 0; i < SAMPLE_PER_CYCLE; i++) { sin_float = sin(i * 2 * PI / SAMPLE_PER_CYCLE); - if (sin_float >= 0) { + if(sin_float >= 0) triangle_float += triangle_step; - } else { + else triangle_float -= triangle_step; - } - sin_float *= (pow(2, bits) / 2 - 1); + sin_float *= (pow(2, bits)/2 - 1); if (bits == 16) { sample_val = 0; @@ -61,34 +57,26 @@ static void setup_triangle_sine_waves(int bits) sample_val += (short) sin_float; samples_data[i] = sample_val; } else if (bits == 24) { //1-bytes unused - samples_data[i * 2] = ((int) triangle_float) << 8; - samples_data[i * 2 + 1] = ((int) sin_float) << 8; + samples_data[i*2] = ((int) triangle_float) << 8; + samples_data[i*2 + 1] = ((int) sin_float) << 8; } else { - samples_data[i * 2] = ((int) triangle_float); - samples_data[i * 2 + 1] = ((int) sin_float); + samples_data[i*2] = ((int) triangle_float); + samples_data[i*2 + 1] = ((int) sin_float); } } - ESP_LOGI(TAG, "set data bit width to %d", bits); - /* Updata clock and slot information */ - slot_cfg.data_bit_width = bits; - i2s_stop_channel(tx_handle); - i2s_set_slot(tx_handle, &slot_cfg); - if (bits == 24) { - /** - * Because '24' has factor '3' - * The mclk multiple must be able to divide by '3' as well - * Otherwise the sample rate won't be accurate */ - clk_cfg.mclk_multiple = I2S_MCLK_MULTIPLE_384; - i2s_set_clock(tx_handle, &clk_cfg); - } else { - clk_cfg.mclk_multiple = I2S_MCLK_MULTIPLE_256; - i2s_set_clock(tx_handle, &clk_cfg); - } - i2s_start_channel(tx_handle); - + ESP_LOGI(TAG, "set clock"); + i2s_set_clk(I2S_NUM, SAMPLE_RATE, bits, 2); + //Using push + // for(i = 0; i < SAMPLE_PER_CYCLE; i++) { + // if (bits == 16) + // i2s_push_sample(0, &samples_data[i], 100); + // else + // i2s_push_sample(0, &samples_data[i*2], 100); + // } + // or write ESP_LOGI(TAG, "write data"); - i2s_write_channel(tx_handle, samples_data, ((bits + 8) / 16)*SAMPLE_PER_CYCLE * 4, &i2s_bytes_write, 100); + i2s_write(I2S_NUM, samples_data, ((bits+8)/16)*SAMPLE_PER_CYCLE*4, &i2s_bytes_write, 100); free(samples_data); } @@ -100,32 +88,35 @@ void app_main(void) //using 6 buffers, we need 60-samples per buffer //if 2-channels, 16-bit each channel, total buffer is 360*4 = 1440 bytes //if 2-channels, 24/32-bit each channel, total buffer is 360*8 = 2880 bytes - i2s_gpio_config_t i2s_pin = { - .mclk = I2S_GPIO_UNUSED, - .bclk = I2S_BCK_IO, - .ws = I2S_WS_IO, - .dout = I2S_DO_IO, - .din = I2S_DI_IO + i2s_config_t i2s_config = { + .mode = I2S_MODE_MASTER | I2S_MODE_TX, + .sample_rate = SAMPLE_RATE, + .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, + .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, + .communication_format = I2S_COMM_FORMAT_STAND_MSB, + .dma_desc_num = 6, + .dma_frame_num = 60, + .use_apll = false, + .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1 //Interrupt level 1 }; - i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); - chan_cfg.id = I2S_NUM; - i2s_new_channel(&chan_cfg, &tx_handle, NULL); - i2s_std_slot_config_t slot_cfg = I2S_STD_PHILIP_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO); - i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(SAMPLE_RATE); -#if SOC_I2S_SUPPORTS_APLL - // APLL clock is more accurate when sample rate is high - clk_cfg.clk_src = I2S_CLK_APLL; -#endif - i2s_init_channel(tx_handle, &clk_cfg, &slot_cfg); - i2s_start_channel(tx_handle); + i2s_pin_config_t pin_config = { + .mck_io_num = I2S_PIN_NO_CHANGE, + .bck_io_num = I2S_BCK_IO, + .ws_io_num = I2S_WS_IO, + .data_out_num = I2S_DO_IO, + .data_in_num = I2S_DI_IO //Not used + }; + i2s_driver_install(I2S_NUM, &i2s_config, 0, NULL); + i2s_set_pin(I2S_NUM, &pin_config); int test_bits = 16; while (1) { setup_triangle_sine_waves(test_bits); - vTaskDelay(pdMS_TO_TICKS(5000)); + vTaskDelay(5000/portTICK_PERIOD_MS); test_bits += 8; - if (test_bits > 32) { + if(test_bits > 32) test_bits = 16; - } + } + } diff --git a/examples/peripherals/i2s/i2s_basic/sdkconfig.defaults b/examples/peripherals/i2s/i2s_basic/sdkconfig.defaults new file mode 100644 index 0000000000..ed0a8a90d9 --- /dev/null +++ b/examples/peripherals/i2s/i2s_basic/sdkconfig.defaults @@ -0,0 +1 @@ +CONFIG_I2S_SUPPRESS_DEPRECATE_WARN=y diff --git a/examples/peripherals/i2s/i2s_basic_new/CMakeLists.txt b/examples/peripherals/i2s/i2s_basic_new/CMakeLists.txt new file mode 100644 index 0000000000..ffc1310d66 --- /dev/null +++ b/examples/peripherals/i2s/i2s_basic_new/CMakeLists.txt @@ -0,0 +1,6 @@ +# The following lines of boilerplate have to be in your project's CMakeLists +# in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.5) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(esp32_i2s_driver_example) diff --git a/examples/peripherals/i2s/i2s_basic_new/README.md b/examples/peripherals/i2s/i2s_basic_new/README.md new file mode 100644 index 0000000000..0b0a9d3913 --- /dev/null +++ b/examples/peripherals/i2s/i2s_basic_new/README.md @@ -0,0 +1,98 @@ +| Supported Targets | ESP32 | ESP32-S2 | ESP32-C3 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | + +# I2S Example + +(See the README.md file in the upper level 'examples' directory for more information about examples.) + +In this example, we generate a 100Hz triangle and sine wave and send it out from left and right channels at a sample rate of 36kHz through the I2S bus. + +## How to Use Example + +### Hardware Required + +* A development board with ESP32/ESP32-S2/ESP32-C3/ESP32-S3 SoC (e.g., ESP32-DevKitC, ESP-WROVER-KIT, etc.) +* A USB cable for power supply and programming + +### Configure the Project + +``` +idf.py menuconfig +``` + +### Build and Flash + +Build the project and flash it to the board, then run monitor tool to view serial output: + +``` +idf.py -p PORT flash monitor +``` + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects. + +## Example Output + +Running this example, you will see I2S start to read and write data, and only the first 4 elements in the receive buffer will be displayed. The output log can be seen below: + +``` +[i2s write] 1440 bytes are written successfully + +[i2s read] 8192 bytes are read successfully +---------------------------------------------- +[0] 0 [1] 0 [2] 0 [3] 0 + +[i2s write] 1440 bytes are written successfully +[i2s write] 1440 bytes are written successfully +[i2s write] 1440 bytes are written successfully + +[i2s read] 8192 bytes are read successfully +---------------------------------------------- +[0] a7d468d9 [1] a88a6a1d [2] a9406b58 [3] a9f66c8b + +[i2s write] 1440 bytes are written successfully +[i2s write] 1440 bytes are written successfully + +[i2s read] 8192 bytes are read successfully +---------------------------------------------- +[0] 8b622120 [1] 8c182347 [2] 8cce256c [3] 8d84278d +``` + +There is a abnormal case that printing `Data dropped`, it is caused by a long polling time of `i2s_read_channel`, please refer to the `Application Notes` section in I2S API reference. + +``` +[i2s read] 8192 bytes are read successfully +---------------------------------------------- +[0] a7d468d9 [1] a88a6a1d [2] a9406b58 [3] a9f66c8b + + +[i2s monitor] Data dropped + + +[i2s monitor] Data dropped + + +[i2s monitor] Data dropped + +[i2s write] 1440 bytes are written successfully + +[i2s monitor] Data dropped +``` + +If you have a logic analyzer, you can use a logic analyzer to grab online data. The following table describes the pins we use by default (Note that you can also use other pins for the same purpose). + +| pin name| function | gpio_num | +|:---:|:---:|:---:| +| WS |word select| GPIO_NUM_15 | +| SCK |continuous serial clock| GPIO_NUM_13 | +| SD |serial data| GPIO_NUM_21 | + +## Troubleshooting + +* Program upload failure + + * Hardware connection is not correct: run `idf.py -p PORT monitor`, and reboot your board to see if there are any output logs. + * The baud rate for downloading is too high: lower your baud rate in the `menuconfig` menu, and try again. + +For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon. diff --git a/examples/peripherals/i2s/i2s_basic_new/main/CMakeLists.txt b/examples/peripherals/i2s/i2s_basic_new/main/CMakeLists.txt new file mode 100644 index 0000000000..4c583513cd --- /dev/null +++ b/examples/peripherals/i2s/i2s_basic_new/main/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "i2s_example_main.c" + INCLUDE_DIRS ".") diff --git a/examples/peripherals/i2s/i2s_basic_new/main/i2s_example_main.c b/examples/peripherals/i2s/i2s_basic_new/main/i2s_example_main.c new file mode 100644 index 0000000000..a9c8e2c0ee --- /dev/null +++ b/examples/peripherals/i2s/i2s_basic_new/main/i2s_example_main.c @@ -0,0 +1,166 @@ +/* + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +/* I2S Example + * This example code will output 100Hz sine wave and triangle wave to 2-channel of I2S driver + * Every 5 seconds, it will change bits_per_sample [16, 24, 32] for i2s data + */ +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "driver/i2s_std.h" +#include "driver/gpio.h" +#include "esp_system.h" +#include "esp_log.h" +#include + +#define EXAMPLE_SAMPLE_RATE (36000) +#define EXAMPLE_DATA_BIT_WIDTH (I2S_DATA_BIT_WIDTH_16BIT) + +#define I2S_NUM (0) +#define WAVE_FREQ_HZ (100) +#define PI (3.14159265) +#define I2S_BCK_IO (GPIO_NUM_4) +#define I2S_WS_IO (GPIO_NUM_5) +#define I2S_DO_IO (GPIO_NUM_18) +#define I2S_DI_IO (GPIO_NUM_18) /// Loopback internally if data_out and data_in signal are bound to a same GPIO + +#define SAMPLE_PER_CYCLE (EXAMPLE_SAMPLE_RATE/WAVE_FREQ_HZ) + +static i2s_chan_handle_t tx_handle = NULL; +static i2s_chan_handle_t rx_handle = NULL; + +static uint32_t* example_generate_triangle_sine_waves(int bits, uint32_t *buf_len) +{ + uint32_t len = ((bits + 8) / 16)*SAMPLE_PER_CYCLE * 4; + uint32_t *samples_data = malloc(len); + + double triangle_float = -(pow(2, bits) / 2 - 1); + double triangle_step = (double) pow(2, bits) / SAMPLE_PER_CYCLE; + + for (int i = 0; i < SAMPLE_PER_CYCLE; i++) { + double sin_float = sin(i * 2 * PI / SAMPLE_PER_CYCLE); + if (sin_float >= 0) { + triangle_float += triangle_step; + } else { + triangle_float -= triangle_step; + } + sin_float *= (pow(2, bits) / 2 - 1); + if (bits == 16) { + samples_data[i] = ((short)triangle_float << 16) | (short)sin_float; + } else if (bits == 24) { //1-bytes unused + samples_data[i * 2] = ((int) triangle_float) << 8; + samples_data[i * 2 + 1] = ((int) sin_float) << 8; + } else { + samples_data[i * 2] = ((int) triangle_float); + samples_data[i * 2 + 1] = ((int) sin_float); + } + + } + *buf_len = len; + return samples_data; +} + +static void example_i2s_monitor_task(void * args) +{ + QueueHandle_t evt_que = *(QueueHandle_t*)args; + i2s_event_t event; + while (1) { + if (xQueueReceive(evt_que, &event, portMAX_DELAY) == pdTRUE) { + if (event.type == I2S_EVENT_RX_Q_OVF) { + /* When the rx message queue is overflow, the data in oldest DMA buffer will be dropped */ + printf("\n[i2s monitor] Data dropped\n\n"); + } + } + } + vTaskDelete(NULL); +} + +static void example_i2s_read_task(void * args) +{ + uint32_t *rx_buf = calloc(1, 8192); + uint32_t bytes_read = 0; + uint32_t cnt = 0; + + while (1) { + if (i2s_read_channel(rx_handle, rx_buf, 8192, &bytes_read, 100) == ESP_OK) { + if (cnt == 0) { + printf("\n[i2s read] %d bytes are read successfully\n", bytes_read); + printf("----------------------------------------------\n"); + printf("[0] %4x [1] %4x [2] %4x [3] %4x\n\n", rx_buf[0], rx_buf[1], rx_buf[2], rx_buf[3]); + } + cnt++; + cnt %= 10; + /* If the polling time is too long, there will be data dropped event */ + // vTaskDelay(10); + } else { + printf("[i2s read] %d bytes are read, timeout triggered\n\n", bytes_read); + } + } + vTaskDelete(NULL); +} + +static void example_i2s_write_task(void * args) +{ + uint32_t buf_len = 0; + uint32_t *tx_buf = example_generate_triangle_sine_waves(EXAMPLE_DATA_BIT_WIDTH, &buf_len); + uint32_t bytes_written = 0; + uint32_t cnt = 0; + + while (1) { + if (i2s_write_channel(tx_handle, tx_buf, buf_len, &bytes_written, 1000) == ESP_OK) { + if (cnt == 0) { + printf("[i2s write] %d bytes are written successfully\n", bytes_written); + } + cnt++; + cnt %= 20; + } else { + printf("[i2s write] %d bytes are written, timeout triggered\n", bytes_written); + } + } + vTaskDelete(NULL); +} + +static void example_i2s_init_std_duplex(void) +{ + i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER); + /* Giving both tx and rx handle will make the i2s works in full-duplex mode and can share the bclk and ws signal */ + ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle)); + i2s_std_config_t std_cfg = { + .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(EXAMPLE_SAMPLE_RATE), + .slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(EXAMPLE_DATA_BIT_WIDTH, I2S_SLOT_MODE_STEREO), + .gpio_cfg = { + .mclk = I2S_GPIO_UNUSED, + .bclk = I2S_BCK_IO, + .ws = I2S_WS_IO, + .dout = I2S_DO_IO, + .din = I2S_DI_IO, + }, + }; +#if SOC_I2S_SUPPORTS_APLL + // APLL clock is more accurate when sample rate is high + std_cfg.clk_cfg.clk_src = I2S_CLK_APLL; +#endif + /* Initialize the tx channel handle to standard mode */ + ESP_ERROR_CHECK(i2s_init_std_channel(tx_handle, &std_cfg)); + /* Initialize the rx channel handle to standard mode */ + ESP_ERROR_CHECK(i2s_init_std_channel(rx_handle, &std_cfg)); + + ESP_ERROR_CHECK(i2s_start_channel(tx_handle)); + ESP_ERROR_CHECK(i2s_start_channel(rx_handle)); +} + +void app_main(void) +{ + //for 36Khz sample rates, we create 100Hz sine wave, every cycle need 36000/100 = 360 samples (4-bytes or 8-bytes each sample) + example_i2s_init_std_duplex(); + + // Acquire I2S rx channel event queue handle for monitoring whether the received data dropped + QueueHandle_t evt_que = i2s_get_event_queue(rx_handle, 16); + + xTaskCreate(example_i2s_write_task, "i2s write task", 4096, NULL, 5, NULL); + xTaskCreate(example_i2s_read_task, "i2s read task", 8192, NULL, 5, NULL); + xTaskCreate(example_i2s_monitor_task, "i2s monitor task", 4096, &evt_que, 5, NULL); +} diff --git a/examples/peripherals/i2s/i2s_es8311/main/i2s_es8311_example.c b/examples/peripherals/i2s/i2s_es8311/main/i2s_es8311_example.c index be824e3bbe..4f3716c7d8 100644 --- a/examples/peripherals/i2s/i2s_es8311/main/i2s_es8311_example.c +++ b/examples/peripherals/i2s/i2s_es8311/main/i2s_es8311_example.c @@ -8,7 +8,7 @@ #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#include "driver/i2s_controller.h" +#include "driver/i2s_std.h" #include "esp_system.h" #include "esp_check.h" #include "es8311.h" @@ -87,21 +87,22 @@ static esp_err_t es8311_codec_init(void) static esp_err_t i2s_driver_init(void) { - i2s_gpio_config_t i2s_pin = { - .mclk = GPIO_NUM_0, - .bclk = GPIO_NUM_4, - .ws = GPIO_NUM_5, - .dout = GPIO_NUM_18, - .din = GPIO_NUM_19 - }; - i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); - chan_cfg.id = I2S_NUM; + i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM, I2S_ROLE_MASTER); ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle)); - i2s_std_slot_config_t slot_cfg = I2S_STD_PHILIP_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO); - slot_cfg.auto_clear = true; - i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(EXAMPLE_SAMPLE_RATE); - ESP_ERROR_CHECK(i2s_init_channel(tx_handle, &clk_cfg, &slot_cfg)); - ESP_ERROR_CHECK(i2s_init_channel(rx_handle, &clk_cfg, &slot_cfg)); + i2s_std_config_t std_cfg = { + .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(EXAMPLE_SAMPLE_RATE), + .slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO), + .gpio_cfg = { + .mclk = GPIO_NUM_0, + .bclk = GPIO_NUM_4, + .ws = GPIO_NUM_5, + .dout = GPIO_NUM_18, + .din = GPIO_NUM_19 + }, + }; + + ESP_ERROR_CHECK(i2s_init_std_channel(tx_handle, &std_cfg)); + ESP_ERROR_CHECK(i2s_init_std_channel(rx_handle, &std_cfg)); ESP_ERROR_CHECK(i2s_start_channel(tx_handle)); ESP_ERROR_CHECK(i2s_start_channel(rx_handle)); return ESP_OK; From 28b8fc6a7e9fdd020dd70ff987c6da858692cf12 Mon Sep 17 00:00:00 2001 From: laokaiyao Date: Thu, 7 Apr 2022 15:32:46 +0800 Subject: [PATCH 3/3] i2s: update documents for driver-NG --- components/driver/CMakeLists.txt | 2 +- components/driver/Kconfig | 9 +- components/driver/adc.c | 1 + components/driver/deprecated/driver/i2s.h | 3 +- .../deprecated/driver/i2s_types_legacy.h | 22 +- .../driver/{i2s => deprecated}/i2s_legacy.c | 205 +- components/driver/i2s/i2s_common.c | 795 ++- components/driver/i2s/i2s_pdm.c | 232 +- components/driver/i2s/i2s_private.h | 123 +- components/driver/i2s/i2s_std.c | 183 +- components/driver/i2s/i2s_tdm.c | 174 +- components/driver/include/driver/i2s_common.h | 237 +- components/driver/include/driver/i2s_pdm.h | 183 +- components/driver/include/driver/i2s_std.h | 118 +- components/driver/include/driver/i2s_tdm.h | 103 +- components/driver/include/driver/i2s_types.h | 79 + .../driver/include/esp_private/i2s_platform.h | 9 +- components/driver/test/test_adc2_with_wifi.c | 2 +- components/driver/test_apps/i2s/app_test.py | 30 - .../driver/test_apps/i2s/main/CMakeLists.txt | 16 - .../driver/test_apps/i2s/main/test_i2s.c | 538 -- .../i2s_test_apps/i2s/CMakeLists.txt | 18 + .../test_apps/i2s_test_apps/i2s/README.md | 2 + .../i2s_test_apps/i2s/main/CMakeLists.txt | 7 + .../i2s/main/test_app_main.c | 0 .../i2s_test_apps/i2s/main/test_i2s.c | 855 +++ .../i2s_test_apps/i2s/main/test_i2s_iram.c | 114 + .../test_apps/i2s_test_apps/i2s/pytest_i2s.py | 24 + .../i2s_test_apps/i2s/sdkconfig.ci.iram_safe | 5 + .../i2s_test_apps/i2s/sdkconfig.ci.release | 5 + .../i2s_test_apps/i2s/sdkconfig.defaults | 2 + .../legacy_i2s_adc_dac/CMakeLists.txt | 5 + .../legacy_i2s_adc_dac/README.md | 2 + .../legacy_i2s_adc_dac/main/CMakeLists.txt | 6 + .../legacy_i2s_adc_dac/main/test_app_main.c | 53 + .../main/test_dac_audio_file.h | 4980 +++++++++++++++++ .../legacy_i2s_adc_dac/main/test_i2s_adc.c | 252 + .../legacy_i2s_adc_dac/main/test_i2s_dac.c | 160 + .../pytest_legacy_i2s_adc_dac.py | 20 + .../legacy_i2s_adc_dac/sdkconfig.ci.release | 9 + .../legacy_i2s_adc_dac}/sdkconfig.defaults | 2 +- .../legacy_i2s_driver}/CMakeLists.txt | 4 +- .../i2s_test_apps/legacy_i2s_driver/README.md | 2 + .../legacy_i2s_driver/main/CMakeLists.txt | 6 + .../legacy_i2s_driver/main/test_app_main.c | 53 + .../legacy_i2s_driver/main/test_legacy_i2s.c} | 532 +- .../legacy_i2s_driver/pytest_legacy_i2s.py | 23 + .../legacy_i2s_driver/sdkconfig.ci.release | 6 + .../legacy_i2s_driver/sdkconfig.defaults | 3 + .../i2s_test_apps/test_inc/test_i2s.h | 51 + components/esp_lcd/src/esp_lcd_panel_io_i2s.c | 6 +- .../i80_lcd/main/test_i80_lcd_panel.c | 36 +- components/hal/adc_hal.c | 2 +- components/hal/esp32/include/hal/gpio_ll.h | 10 + components/hal/esp32/include/hal/i2s_ll.h | 51 +- components/hal/esp32c3/include/hal/i2s_ll.h | 24 +- components/hal/esp32h2/include/hal/i2s_ll.h | 27 +- components/hal/esp32s2/include/hal/i2s_ll.h | 47 +- components/hal/esp32s3/include/hal/i2s_ll.h | 26 +- components/hal/i2s_hal.c | 9 +- components/hal/include/hal/i2s_hal.h | 41 +- components/hal/include/hal/i2s_types.h | 84 +- .../soc/esp32/include/soc/clk_tree_defs.h | 16 + .../soc/esp32c3/include/soc/clk_tree_defs.h | 15 + .../soc/esp32h2/include/soc/clk_tree_defs.h | 24 +- .../soc/esp32s2/include/soc/clk_tree_defs.h | 16 + .../soc/esp32s3/include/soc/clk_tree_defs.h | 15 + .../soc/esp32s3/include/soc/i2s_struct.h | 4 +- .../diagrams/i2s/i2s_file_structure.png | Bin 64258 -> 63575 bytes .../diagrams/i2s/i2s_state_machine.png | Bin 55870 -> 53689 bytes docs/_static/diagrams/i2s/pdm.json | 47 + docs/_static/diagrams/i2s/pdm.png | Bin 81899 -> 0 bytes docs/_static/diagrams/i2s/std_msb.json | 52 + docs/_static/diagrams/i2s/std_msb.png | Bin 23008 -> 0 bytes docs/_static/diagrams/i2s/std_pcm.json | 54 + docs/_static/diagrams/i2s/std_pcm.png | Bin 20415 -> 0 bytes docs/_static/diagrams/i2s/std_philip.json | 54 + docs/_static/diagrams/i2s/std_philip.png | Bin 19028 -> 0 bytes docs/_static/diagrams/i2s/tdm_msb.json | 60 + docs/_static/diagrams/i2s/tdm_msb.png | Bin 73090 -> 0 bytes docs/_static/diagrams/i2s/tdm_pcm_long.json | 57 + docs/_static/diagrams/i2s/tdm_pcm_long.png | Bin 63728 -> 0 bytes docs/_static/diagrams/i2s/tdm_pcm_short.json | 52 + docs/_static/diagrams/i2s/tdm_pcm_short.png | Bin 71424 -> 0 bytes docs/_static/diagrams/i2s/tdm_philip.json | 62 + docs/_static/diagrams/i2s/tdm_philip.png | Bin 80203 -> 0 bytes docs/doxygen/Doxyfile | 7 - docs/doxygen/Doxyfile_esp32 | 5 + docs/doxygen/Doxyfile_esp32c3 | 6 + docs/doxygen/Doxyfile_esp32h2 | 5 + docs/doxygen/Doxyfile_esp32s2 | 4 + docs/doxygen/Doxyfile_esp32s3 | 6 + docs/en/api-reference/peripherals/i2s.rst | 725 ++- docs/en/migration-guides/peripherals.rst | 78 +- .../classic_bt/a2dp_sink/main/bt_app_av.c | 22 +- .../classic_bt/a2dp_sink/main/bt_app_core.c | 2 +- .../a2dp_sink/tutorial/Example_A2DP_Sink.md | 18 +- .../coex/a2dp_gatts_coex/main/bt_app_av.c | 2 +- .../coex/a2dp_gatts_coex/main/bt_app_core.c | 2 +- .../coex/a2dp_gatts_coex/main/main.c | 17 +- .../i2s/i2s_adc_dac/main/app_main.c | 4 +- .../i2s/i2s_adc_dac/pytest_i2s_adc_dac.py | 15 + .../i2s/i2s_adc_dac/sdkconfig.defaults | 1 + .../main/Kconfig.projbuild | 6 - .../main/i2s_recorder_main.c | 44 +- .../pytest_i2s_record.py | 13 + examples/peripherals/i2s/i2s_basic/README.md | 56 +- .../i2s/i2s_basic/main/i2s_example_main.c | 212 +- .../i2s/i2s_basic/pytest_i2s_basic.py | 18 + .../i2s/i2s_basic/sdkconfig.defaults | 1 - .../i2s/i2s_basic_new/CMakeLists.txt | 6 - .../peripherals/i2s/i2s_basic_new/README.md | 98 - .../i2s/i2s_basic_new/main/CMakeLists.txt | 2 - .../i2s/i2s_basic_new/main/i2s_example_main.c | 166 - examples/peripherals/i2s/i2s_es8311/README.md | 4 +- .../i2s/i2s_es8311/main/i2s_es8311_example.c | 38 +- .../i2s/i2s_es8311/pytest_i2s_es8311.py | 16 + 117 files changed, 10098 insertions(+), 2657 deletions(-) rename components/driver/{i2s => deprecated}/i2s_legacy.c (92%) create mode 100644 components/driver/include/driver/i2s_types.h delete mode 100644 components/driver/test_apps/i2s/app_test.py delete mode 100644 components/driver/test_apps/i2s/main/CMakeLists.txt delete mode 100644 components/driver/test_apps/i2s/main/test_i2s.c create mode 100644 components/driver/test_apps/i2s_test_apps/i2s/CMakeLists.txt create mode 100644 components/driver/test_apps/i2s_test_apps/i2s/README.md create mode 100644 components/driver/test_apps/i2s_test_apps/i2s/main/CMakeLists.txt rename components/driver/test_apps/{ => i2s_test_apps}/i2s/main/test_app_main.c (100%) create mode 100644 components/driver/test_apps/i2s_test_apps/i2s/main/test_i2s.c create mode 100644 components/driver/test_apps/i2s_test_apps/i2s/main/test_i2s_iram.c create mode 100644 components/driver/test_apps/i2s_test_apps/i2s/pytest_i2s.py create mode 100644 components/driver/test_apps/i2s_test_apps/i2s/sdkconfig.ci.iram_safe create mode 100644 components/driver/test_apps/i2s_test_apps/i2s/sdkconfig.ci.release create mode 100644 components/driver/test_apps/i2s_test_apps/i2s/sdkconfig.defaults create mode 100644 components/driver/test_apps/i2s_test_apps/legacy_i2s_adc_dac/CMakeLists.txt create mode 100644 components/driver/test_apps/i2s_test_apps/legacy_i2s_adc_dac/README.md create mode 100644 components/driver/test_apps/i2s_test_apps/legacy_i2s_adc_dac/main/CMakeLists.txt create mode 100644 components/driver/test_apps/i2s_test_apps/legacy_i2s_adc_dac/main/test_app_main.c create mode 100644 components/driver/test_apps/i2s_test_apps/legacy_i2s_adc_dac/main/test_dac_audio_file.h create mode 100644 components/driver/test_apps/i2s_test_apps/legacy_i2s_adc_dac/main/test_i2s_adc.c create mode 100644 components/driver/test_apps/i2s_test_apps/legacy_i2s_adc_dac/main/test_i2s_dac.c create mode 100644 components/driver/test_apps/i2s_test_apps/legacy_i2s_adc_dac/pytest_legacy_i2s_adc_dac.py create mode 100644 components/driver/test_apps/i2s_test_apps/legacy_i2s_adc_dac/sdkconfig.ci.release rename components/driver/test_apps/{i2s => i2s_test_apps/legacy_i2s_adc_dac}/sdkconfig.defaults (60%) rename components/driver/test_apps/{i2s => i2s_test_apps/legacy_i2s_driver}/CMakeLists.txt (65%) create mode 100644 components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/README.md create mode 100644 components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/main/CMakeLists.txt create mode 100644 components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/main/test_app_main.c rename components/driver/test_apps/{i2s/main/test_i2s_legacy.c => i2s_test_apps/legacy_i2s_driver/main/test_legacy_i2s.c} (63%) create mode 100644 components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/pytest_legacy_i2s.py create mode 100644 components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/sdkconfig.ci.release create mode 100644 components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/sdkconfig.defaults create mode 100644 components/driver/test_apps/i2s_test_apps/test_inc/test_i2s.h create mode 100644 docs/_static/diagrams/i2s/pdm.json delete mode 100644 docs/_static/diagrams/i2s/pdm.png create mode 100644 docs/_static/diagrams/i2s/std_msb.json delete mode 100644 docs/_static/diagrams/i2s/std_msb.png create mode 100644 docs/_static/diagrams/i2s/std_pcm.json delete mode 100644 docs/_static/diagrams/i2s/std_pcm.png create mode 100644 docs/_static/diagrams/i2s/std_philip.json delete mode 100644 docs/_static/diagrams/i2s/std_philip.png create mode 100644 docs/_static/diagrams/i2s/tdm_msb.json delete mode 100644 docs/_static/diagrams/i2s/tdm_msb.png create mode 100644 docs/_static/diagrams/i2s/tdm_pcm_long.json delete mode 100644 docs/_static/diagrams/i2s/tdm_pcm_long.png create mode 100644 docs/_static/diagrams/i2s/tdm_pcm_short.json delete mode 100644 docs/_static/diagrams/i2s/tdm_pcm_short.png create mode 100644 docs/_static/diagrams/i2s/tdm_philip.json delete mode 100644 docs/_static/diagrams/i2s/tdm_philip.png create mode 100644 examples/peripherals/i2s/i2s_adc_dac/pytest_i2s_adc_dac.py create mode 100644 examples/peripherals/i2s/i2s_audio_recorder_sdcard/pytest_i2s_record.py create mode 100644 examples/peripherals/i2s/i2s_basic/pytest_i2s_basic.py delete mode 100644 examples/peripherals/i2s/i2s_basic/sdkconfig.defaults delete mode 100644 examples/peripherals/i2s/i2s_basic_new/CMakeLists.txt delete mode 100644 examples/peripherals/i2s/i2s_basic_new/README.md delete mode 100644 examples/peripherals/i2s/i2s_basic_new/main/CMakeLists.txt delete mode 100644 examples/peripherals/i2s/i2s_basic_new/main/i2s_example_main.c create mode 100644 examples/peripherals/i2s/i2s_es8311/pytest_i2s_es8311.py diff --git a/components/driver/CMakeLists.txt b/components/driver/CMakeLists.txt index 001e650415..1997c6d757 100644 --- a/components/driver/CMakeLists.txt +++ b/components/driver/CMakeLists.txt @@ -60,7 +60,7 @@ endif() if(CONFIG_SOC_I2S_SUPPORTED) list(APPEND srcs "i2s/i2s_common.c" "i2s/i2s_std.c" - "i2s/i2s_legacy.c") + "deprecated/i2s_legacy.c") if(CONFIG_SOC_I2S_SUPPORTS_PDM) list(APPEND srcs "i2s/i2s_pdm.c") endif() diff --git a/components/driver/Kconfig b/components/driver/Kconfig index 97125ebe23..a04d309270 100644 --- a/components/driver/Kconfig +++ b/components/driver/Kconfig @@ -318,7 +318,14 @@ menu "Driver Configurations" bool "Suppress leagcy driver deprecated warning" default n help - Enable this option will suppress the deprecation warnings of using APIs in deprecated I2S driver. + Enable this option will suppress the deprecation warnings of using APIs in legacy I2S driver. + + config I2S_ENABLE_DEBUG_LOG + bool "Enable I2S debug log" + default n + help + Wether to enable the debug log message for I2S driver. + Note that, this option only controls the I2S driver log, will not affect other drivers. endmenu # I2S Configuration endmenu # Driver configurations diff --git a/components/driver/adc.c b/components/driver/adc.c index fc88e89ce4..077942a051 100644 --- a/components/driver/adc.c +++ b/components/driver/adc.c @@ -38,6 +38,7 @@ #include "driver/spi_common_internal.h" #elif CONFIG_IDF_TARGET_ESP32 #include "hal/i2s_types.h" +#include "driver/i2s_types.h" #include "soc/i2s_periph.h" #include "esp_private/i2s_platform.h" #endif diff --git a/components/driver/deprecated/driver/i2s.h b/components/driver/deprecated/driver/i2s.h index e7c149e153..0d9c686acb 100644 --- a/components/driver/deprecated/driver/i2s.h +++ b/components/driver/deprecated/driver/i2s.h @@ -17,7 +17,6 @@ #include "esp_err.h" #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" -#include "soc/i2s_periph.h" #include "driver/i2s_types_legacy.h" #if SOC_I2S_SUPPORTS_ADC @@ -46,7 +45,7 @@ extern "C" { * * @param pin I2S Pin structure, or NULL to set 2-channel 8-bit internal DAC pin configuration (GPIO25 & GPIO26) * - * Inside the pin configuration structure, set I2S_GPIO_UNUSED for any pin where + * Inside the pin configuration structure, set I2S_PIN_NO_CHANGE for any pin where * the current configuration should not be changed. * * @note if *pin is set as NULL, this function will initialize both of the built-in DAC channels by default. diff --git a/components/driver/deprecated/driver/i2s_types_legacy.h b/components/driver/deprecated/driver/i2s_types_legacy.h index 495394fba4..4f62d6a747 100644 --- a/components/driver/deprecated/driver/i2s_types_legacy.h +++ b/components/driver/deprecated/driver/i2s_types_legacy.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -13,6 +13,7 @@ #pragma once #include "hal/i2s_types.h" +#include "driver/i2s_types.h" #ifdef __cplusplus extern "C" { @@ -141,6 +142,25 @@ typedef enum { } i2s_dac_mode_t; #endif //SOC_I2S_SUPPORTS_DAC +/** + * @brief I2S event queue types + */ +typedef enum { + I2S_EVENT_DMA_ERROR, /*!< I2S DMA has no next descriptor for sending or receiving */ + I2S_EVENT_TX_DONE, /*!< I2S DMA finished sending one DMA buffer */ + I2S_EVENT_RX_DONE, /*!< I2S DMA finished receiving one DMA buffer */ + I2S_EVENT_TX_Q_OVF, /*!< I2S DMA sending queue overflowed, the oldest data has been overwritten by the new data in the DMA buffer */ + I2S_EVENT_RX_Q_OVF, /*!< I2S DMA receive queue overflowed, the oldest data has been overwritten by the new data in the DMA buffer */ +} i2s_event_type_t; + +/** + * @brief Event structure used in I2S event queue + */ +typedef struct { + i2s_event_type_t type; /*!< I2S event type */ + size_t size; /*!< I2S data size for I2S_DATA event*/ +} i2s_event_t; + /** * @brief I2S GPIO pins configuration */ diff --git a/components/driver/i2s/i2s_legacy.c b/components/driver/deprecated/i2s_legacy.c similarity index 92% rename from components/driver/i2s/i2s_legacy.c rename to components/driver/deprecated/i2s_legacy.c index 2655d91421..18c0633707 100644 --- a/components/driver/i2s/i2s_legacy.c +++ b/components/driver/deprecated/i2s_legacy.c @@ -12,11 +12,19 @@ #include "freertos/queue.h" #include "freertos/semphr.h" +#include "sdkconfig.h" + +#if CONFIG_I2S_ENABLE_DEBUG_LOG +// The local log level must be defined before including esp_log.h +// Set the maximum log level for this source file +#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG +#endif + #include "soc/lldesc.h" #include "driver/gpio.h" #include "hal/gpio_hal.h" +#include "driver/i2s_types_legacy.h" #include "hal/i2s_hal.h" -#include "driver/i2s.h" #if SOC_I2S_SUPPORTS_DAC #include "driver/dac.h" #include "driver/adc.h" @@ -36,12 +44,9 @@ #include "esp_pm.h" #include "esp_efuse.h" #include "esp_rom_gpio.h" -#include "esp_private/i2s_platform.h" #include "esp_private/periph_ctrl.h" -#include "sdkconfig.h" - -static const char *TAG = "I2S"; +static const char *TAG = "i2s(legacy)"; #define I2S_ENTER_CRITICAL_ISR(i2s_num) portENTER_CRITICAL_ISR(&i2s_spinlock[i2s_num]) #define I2S_EXIT_CRITICAL_ISR(i2s_num) portEXIT_CRITICAL_ISR(&i2s_spinlock[i2s_num]) @@ -124,13 +129,24 @@ typedef struct { uint32_t total_slot; /*!< Total slot number */ } i2s_obj_t; +// Record the component name that using I2S peripheral +static const char *comp_using_i2s[SOC_I2S_NUM] = {[0 ... SOC_I2S_NUM - 1] = NULL}; + +// Global I2S object pointer static i2s_obj_t *p_i2s[SOC_I2S_NUM] = { [0 ... SOC_I2S_NUM - 1] = NULL, }; + +// Global spin lock for all i2s controllers static portMUX_TYPE i2s_spinlock[SOC_I2S_NUM] = { [0 ... SOC_I2S_NUM - 1] = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED, }; + +__attribute__((weak)) esp_err_t i2s_platform_acquire_occupation(int id, const char *comp_name); + +__attribute__((weak)) esp_err_t i2s_platform_release_occupation(int id); + /*------------------------------------------------------------- I2S DMA operation -------------------------------------------------------------*/ @@ -412,7 +428,7 @@ static void i2s_rx_stop(i2s_port_t i2s_num) esp_err_t i2s_start(i2s_port_t i2s_num) { - ESP_RETURN_ON_FALSE((i2s_num < I2S_NUM_MAX), ESP_ERR_INVALID_ARG, TAG, "i2s_num error"); + ESP_RETURN_ON_FALSE((i2s_num < SOC_I2S_NUM), ESP_ERR_INVALID_ARG, TAG, "i2s_num error"); //start DMA link I2S_ENTER_CRITICAL(i2s_num); @@ -433,7 +449,7 @@ esp_err_t i2s_start(i2s_port_t i2s_num) esp_err_t i2s_stop(i2s_port_t i2s_num) { - ESP_RETURN_ON_FALSE((i2s_num < I2S_NUM_MAX), ESP_ERR_INVALID_ARG, TAG, "i2s_num error"); + ESP_RETURN_ON_FALSE((i2s_num < SOC_I2S_NUM), ESP_ERR_INVALID_ARG, TAG, "i2s_num error"); I2S_ENTER_CRITICAL(i2s_num); #if !SOC_GDMA_SUPPORTED esp_intr_disable(p_i2s[i2s_num]->i2s_isr_handle); @@ -462,7 +478,7 @@ static inline uint32_t i2s_get_buf_size(i2s_port_t i2s_num) /* The DMA buffer limitation is 4092 bytes */ uint32_t bytes_per_frame = bytes_per_sample * p_i2s[i2s_num]->active_slot; p_i2s[i2s_num]->dma_frame_num = (p_i2s[i2s_num]->dma_frame_num * bytes_per_frame > I2S_DMA_BUFFER_MAX_SIZE) ? - I2S_DMA_BUFFER_MAX_SIZE / bytes_per_frame : p_i2s[i2s_num]->dma_frame_num; + I2S_DMA_BUFFER_MAX_SIZE / bytes_per_frame : p_i2s[i2s_num]->dma_frame_num; return p_i2s[i2s_num]->dma_frame_num * bytes_per_frame; } @@ -496,7 +512,6 @@ static esp_err_t i2s_alloc_dma_buffer(i2s_port_t i2s_num, i2s_dma_t *dma_obj) ESP_GOTO_ON_FALSE(dma_obj->buf[cnt], ESP_ERR_NO_MEM, err, TAG, "Error malloc dma buffer"); /* Initialize DMA buffer to 0 */ memset(dma_obj->buf[cnt], 0, dma_obj->buf_size); - ESP_LOGD(TAG, "Addr[%d] = %d", cnt, (int)dma_obj->buf[cnt]); /* Allocate DMA descpriptor */ dma_obj->desc[cnt] = (lldesc_t *) heap_caps_calloc(1, sizeof(lldesc_t), MALLOC_CAP_DMA); @@ -518,7 +533,7 @@ static esp_err_t i2s_alloc_dma_buffer(i2s_port_t i2s_num, i2s_dma_t *dma_obj) if (p_i2s[i2s_num]->dir & I2S_DIR_RX) { i2s_ll_rx_set_eof_num(p_i2s[i2s_num]->hal.dev, dma_obj->buf_size); } - ESP_LOGI(TAG, "DMA Malloc info, datalen=blocksize=%d, dma_desc_num=%d", dma_obj->buf_size, buf_cnt); + ESP_LOGD(TAG, "DMA Malloc info, datalen=blocksize=%d, dma_desc_num=%d", dma_obj->buf_size, buf_cnt); return ESP_OK; err: /* Delete DMA buffer if failed to allocate memory */ @@ -564,7 +579,7 @@ static esp_err_t i2s_destroy_dma_object(i2s_port_t i2s_num, i2s_dma_t **dma) /* Free DMA structure */ free(*dma); *dma = NULL; - ESP_LOGI(TAG, "DMA queue destroyed"); + ESP_LOGD(TAG, "DMA queue destroyed"); return ESP_OK; } @@ -629,14 +644,14 @@ static uint32_t i2s_config_source_clock(i2s_port_t i2s_num, bool use_apll, uint3 if (ret == ESP_ERR_INVALID_STATE) { ESP_LOGW(TAG, "APLL is occupied already, it is working at %d Hz", real_freq); } - ESP_LOGI(TAG, "APLL expected frequency is %d Hz, real frequency is %d Hz", expt_freq, real_freq); + ESP_LOGD(TAG, "APLL expected frequency is %d Hz, real frequency is %d Hz", expt_freq, real_freq); /* In APLL mode, there is no sclk but only mclk, so return 0 here to indicate APLL mode */ return real_freq; } return I2S_LL_BASE_CLK; #else if (use_apll) { - ESP_LOGW(TAG, "APLL not supported on current chip, use I2S_CLK_PLL_160M as default clock source"); + ESP_LOGW(TAG, "APLL not supported on current chip, use I2S_CLK_SRC_DEFAULT as default clock source"); } return I2S_LL_BASE_CLK; #endif @@ -657,7 +672,7 @@ static esp_err_t i2s_calculate_adc_dac_clock(int i2s_num, i2s_hal_clock_info_t * clk_info->bclk_div = slot_bits; /* If fixed_mclk and use_apll are set, use fixed_mclk as mclk frequency, otherwise calculate by mclk = bclk * bclk_div */ clk_info->mclk = (p_i2s[i2s_num]->use_apll && p_i2s[i2s_num]->fixed_mclk) ? - p_i2s[i2s_num]->fixed_mclk : clk_info->bclk * clk_info->bclk_div; + p_i2s[i2s_num]->fixed_mclk : clk_info->bclk * clk_info->bclk_div; /* Calculate bclk_div = mclk / bclk */ clk_info->bclk_div = clk_info->mclk / clk_info->bclk; /* Get I2S system clock by config source clock */ @@ -686,7 +701,7 @@ static esp_err_t i2s_calculate_pdm_tx_clock(int i2s_num, i2s_hal_clock_info_t *c clk_info->bclk_div = 8; /* If fixed_mclk and use_apll are set, use fixed_mclk as mclk frequency, otherwise calculate by mclk = sample_rate_hz * multiple */ clk_info->mclk = (p_i2s[i2s_num]->use_apll && p_i2s[i2s_num]->fixed_mclk) ? - p_i2s[i2s_num]->fixed_mclk : clk_info->bclk * clk_info->bclk_div; + p_i2s[i2s_num]->fixed_mclk : clk_info->bclk * clk_info->bclk_div; /* Calculate bclk_div = mclk / bclk */ clk_info->bclk_div = clk_info->mclk / clk_info->bclk; /* Get I2S system clock by config source clock */ @@ -713,7 +728,7 @@ static esp_err_t i2s_calculate_pdm_rx_clock(int i2s_num, i2s_hal_clock_info_t *c clk_info->bclk_div = 8; /* If fixed_mclk and use_apll are set, use fixed_mclk as mclk frequency, otherwise calculate by mclk = sample_rate_hz * multiple */ clk_info->mclk = (p_i2s[i2s_num]->use_apll && p_i2s[i2s_num]->fixed_mclk) ? - p_i2s[i2s_num]->fixed_mclk : clk_info->bclk * clk_info->bclk_div; + p_i2s[i2s_num]->fixed_mclk : clk_info->bclk * clk_info->bclk_div; /* Calculate bclk_div = mclk / bclk */ clk_info->bclk_div = clk_info->mclk / clk_info->bclk; /* Get I2S system clock by config source clock */ @@ -869,7 +884,7 @@ esp_err_t i2s_set_adc_mode(adc_unit_t adc_unit, adc1_channel_t adc_channel) esp_err_t i2s_adc_enable(i2s_port_t i2s_num) { - ESP_RETURN_ON_FALSE((i2s_num < I2S_NUM_MAX), ESP_ERR_INVALID_ARG, TAG, "i2s_num error"); + ESP_RETURN_ON_FALSE((i2s_num < SOC_I2S_NUM), ESP_ERR_INVALID_ARG, TAG, "i2s_num error"); ESP_RETURN_ON_FALSE((p_i2s[i2s_num] != NULL), ESP_ERR_INVALID_STATE, TAG, "Not initialized yet"); ESP_RETURN_ON_FALSE(((int)p_i2s[i2s_num]->mode == I2S_COMM_MODE_ADC_DAC) && (p_i2s[i2s_num]->dir & I2S_DIR_RX), ESP_ERR_INVALID_STATE, TAG, "i2s built-in adc not enabled"); @@ -882,7 +897,7 @@ esp_err_t i2s_adc_enable(i2s_port_t i2s_num) esp_err_t i2s_adc_disable(i2s_port_t i2s_num) { - ESP_RETURN_ON_FALSE((i2s_num < I2S_NUM_MAX), ESP_ERR_INVALID_ARG, TAG, "i2s_num error"); + ESP_RETURN_ON_FALSE((i2s_num < SOC_I2S_NUM), ESP_ERR_INVALID_ARG, TAG, "i2s_num error"); ESP_RETURN_ON_FALSE((p_i2s[i2s_num] != NULL), ESP_ERR_INVALID_STATE, TAG, "Not initialized yet"); ESP_RETURN_ON_FALSE(((int)p_i2s[i2s_num]->mode == I2S_COMM_MODE_ADC_DAC) && (p_i2s[i2s_num]->dir & I2S_DIR_RX), ESP_ERR_INVALID_STATE, TAG, "i2s built-in adc not enabled"); @@ -897,7 +912,7 @@ static esp_err_t i2s_check_cfg_validity(i2s_port_t i2s_num, const i2s_config_t * { /* Step 1: Check the validity of input parameters */ /* Check the validity of i2s device number */ - ESP_RETURN_ON_FALSE((i2s_num < I2S_NUM_MAX), ESP_ERR_INVALID_ARG, TAG, "i2s_num error"); + ESP_RETURN_ON_FALSE((i2s_num < SOC_I2S_NUM), ESP_ERR_INVALID_ARG, TAG, "i2s_num error"); ESP_RETURN_ON_FALSE(p_i2s[i2s_num] == NULL, ESP_ERR_INVALID_STATE, TAG, "this i2s port is in use"); ESP_RETURN_ON_FALSE(cfg, ESP_ERR_INVALID_ARG, TAG, "I2S configuration must not be NULL"); /* Check the size of DMA buffer */ @@ -957,16 +972,16 @@ static void i2s_set_slot_legacy(i2s_port_t i2s_num) } #if SOC_I2S_SUPPORTS_PDM else if (p_i2s[i2s_num]->mode == I2S_COMM_MODE_PDM) { - #if SOC_I2S_SUPPORTS_PDM_TX +#if SOC_I2S_SUPPORTS_PDM_TX if (p_i2s[i2s_num]->dir & I2S_DIR_TX) { i2s_hal_pdm_set_tx_slot(&(p_i2s[i2s_num]->hal), is_tx_slave, (i2s_hal_slot_config_t *)(&p_i2s[i2s_num]->slot_cfg) ); } - #endif - #if SOC_I2S_SUPPORTS_PDM_RX +#endif +#if SOC_I2S_SUPPORTS_PDM_RX if (p_i2s[i2s_num]->dir & I2S_DIR_RX) { i2s_hal_pdm_set_rx_slot(&(p_i2s[i2s_num]->hal), is_rx_slave, (i2s_hal_slot_config_t *)(&p_i2s[i2s_num]->slot_cfg) ); } - #endif +#endif } #endif #if SOC_I2S_SUPPORTS_TDM @@ -1006,14 +1021,14 @@ static void i2s_set_clock_legacy(i2s_port_t i2s_num) float i2s_get_clk(i2s_port_t i2s_num) { - ESP_RETURN_ON_FALSE((i2s_num < I2S_NUM_MAX), ESP_ERR_INVALID_ARG, TAG, "i2s_num error"); + ESP_RETURN_ON_FALSE((i2s_num < SOC_I2S_NUM), ESP_ERR_INVALID_ARG, TAG, "i2s_num error"); i2s_clk_config_t *clk_cfg = &p_i2s[i2s_num]->clk_cfg; return (float)clk_cfg->sample_rate_hz; } esp_err_t i2s_set_clk(i2s_port_t i2s_num, uint32_t rate, uint32_t bits_cfg, i2s_channel_t ch) { - ESP_RETURN_ON_FALSE((i2s_num < I2S_NUM_MAX), ESP_ERR_INVALID_ARG, TAG, "i2s_num error"); + ESP_RETURN_ON_FALSE((i2s_num < SOC_I2S_NUM), ESP_ERR_INVALID_ARG, TAG, "i2s_num error"); ESP_RETURN_ON_FALSE(p_i2s[i2s_num], ESP_ERR_INVALID_ARG, TAG, "I2S%d has not installed yet", i2s_num); /* Acquire the lock before stop i2s, otherwise reading/writing operation will stuck on receiving the message queue from interrupt */ @@ -1038,6 +1053,19 @@ esp_err_t i2s_set_clk(i2s_port_t i2s_num, uint32_t rate, uint32_t bits_cfg, i2s_ ESP_RETURN_ON_FALSE((slot_cfg->slot_bit_width % 8 == 0), ESP_ERR_INVALID_ARG, TAG, "Invalid bits per channel"); ESP_RETURN_ON_FALSE(((int)slot_cfg->slot_bit_width <= (int)I2S_BITS_PER_SAMPLE_32BIT), ESP_ERR_INVALID_ARG, TAG, "Invalid bits per sample"); slot_cfg->slot_mode = ((ch & 0xFFFF) == I2S_CHANNEL_MONO) ? I2S_SLOT_MODE_MONO : I2S_SLOT_MODE_STEREO; + if (p_i2s[i2s_num]->mode == I2S_COMM_MODE_STD) { + if (slot_cfg->slot_mode == I2S_SLOT_MODE_MONO) { + if (slot_cfg->std.slot_mask == I2S_STD_SLOT_LEFT_RIGHT) { + slot_cfg->std.slot_mask = I2S_STD_SLOT_ONLY_LEFT; +#if SOC_I2S_HW_VERSION_1 + // Enable right first to get correct data sequence + slot_cfg->std.ws_pol = !slot_cfg->std.ws_pol; +#endif + } + } else { + slot_cfg->std.slot_mask = I2S_STD_SLOT_LEFT_RIGHT; + } + } #if SOC_I2S_SUPPORTS_TDM if (p_i2s[i2s_num]->mode == I2S_COMM_MODE_TDM) { uint32_t slot_mask = ch >> 16; @@ -1092,7 +1120,7 @@ esp_err_t i2s_set_clk(i2s_port_t i2s_num, uint32_t rate, uint32_t bits_cfg, i2s_ esp_err_t i2s_set_sample_rates(i2s_port_t i2s_num, uint32_t rate) { - ESP_RETURN_ON_FALSE((i2s_num < I2S_NUM_MAX), ESP_ERR_INVALID_ARG, TAG, "i2s_num error"); + ESP_RETURN_ON_FALSE((i2s_num < SOC_I2S_NUM), ESP_ERR_INVALID_ARG, TAG, "i2s_num error"); i2s_hal_slot_config_t *slot_cfg = &p_i2s[i2s_num]->slot_cfg; uint32_t mask = 0; #if SOC_I2S_SUPPORTS_TDM @@ -1210,7 +1238,7 @@ static void i2s_mode_identify(i2s_port_t i2s_num, const i2s_config_t *i2s_config #if SOC_I2S_SUPPORTS_TDM if (i2s_config->channel_format == I2S_CHANNEL_FMT_MULTIPLE) { - p_i2s[i2s_num]->mode = I2S_COMM_MODE_TDM; + p_i2s[i2s_num]->mode = I2S_COMM_MODE_TDM; } #endif // SOC_I2S_SUPPORTS_TDM @@ -1224,22 +1252,22 @@ static void i2s_mode_identify(i2s_port_t i2s_num, const i2s_config_t *i2s_config static esp_err_t i2s_config_transfer(i2s_port_t i2s_num, const i2s_config_t *i2s_config) { - #define SLOT_CFG(m) p_i2s[i2s_num]->slot_cfg.m - #define CLK_CFG() p_i2s[i2s_num]->clk_cfg +#define SLOT_CFG(m) p_i2s[i2s_num]->slot_cfg.m +#define CLK_CFG() p_i2s[i2s_num]->clk_cfg /* Convert legacy configuration into general part of slot and clock configuration */ p_i2s[i2s_num]->slot_cfg.data_bit_width = i2s_config->bits_per_sample; p_i2s[i2s_num]->slot_cfg.slot_bit_width = (int)i2s_config->bits_per_chan < (int)i2s_config->bits_per_sample ? - i2s_config->bits_per_sample : i2s_config->bits_per_chan; + i2s_config->bits_per_sample : i2s_config->bits_per_chan; - slot_cfg.slot_mode = i2s_config->channel_format < I2S_CHANNEL_FMT_ONLY_RIGHT ? - I2S_SLOT_MODE_STEREO : I2S_SLOT_MODE_MONO; + p_i2s[i2s_num]->slot_cfg.slot_mode = i2s_config->channel_format < I2S_CHANNEL_FMT_ONLY_RIGHT ? + I2S_SLOT_MODE_STEREO : I2S_SLOT_MODE_MONO; CLK_CFG().sample_rate_hz = i2s_config->sample_rate; CLK_CFG().mclk_multiple = i2s_config->mclk_multiple == 0 ? I2S_MCLK_MULTIPLE_256 : i2s_config->mclk_multiple; - CLK_CFG().clk_src = I2S_CLK_PLL_160M; + CLK_CFG().clk_src = I2S_CLK_SRC_DEFAULT; p_i2s[i2s_num]->fixed_mclk = i2s_config->fixed_mclk; p_i2s[i2s_num]->use_apll = false; #if SOC_I2S_SUPPORTS_APLL - CLK_CFG().clk_src = i2s_config->use_apll ? I2S_CLK_APLL : I2S_CLK_PLL_160M; + CLK_CFG().clk_src = i2s_config->use_apll ? I2S_CLK_SRC_APLL : I2S_CLK_SRC_DEFAULT; p_i2s[i2s_num]->use_apll = i2s_config->use_apll; #endif // SOC_I2S_SUPPORTS_APLL @@ -1249,12 +1277,12 @@ static esp_err_t i2s_config_transfer(i2s_port_t i2s_num, const i2s_config_t *i2s SLOT_CFG(std).ws_width = i2s_config->bits_per_sample; SLOT_CFG(std).ws_pol = false; if (i2s_config->channel_format == I2S_CHANNEL_FMT_RIGHT_LEFT) { - std_slot->slot_sel = I2S_STD_SLOT_LEFT_RIGHT; + SLOT_CFG(std).slot_mask = I2S_STD_SLOT_LEFT_RIGHT; } else if (i2s_config->channel_format == I2S_CHANNEL_FMT_ALL_LEFT || i2s_config->channel_format == I2S_CHANNEL_FMT_ONLY_LEFT) { - std_slot->slot_sel = I2S_STD_SLOT_ONLY_LEFT; + SLOT_CFG(std).slot_mask = I2S_STD_SLOT_ONLY_LEFT; } else { - std_slot->slot_sel = I2S_STD_SLOT_ONLY_RIGHT; + SLOT_CFG(std).slot_mask = I2S_STD_SLOT_ONLY_RIGHT; } if (i2s_config->communication_format == I2S_COMM_FORMAT_STAND_I2S) { SLOT_CFG(std).bit_shift = true; @@ -1264,13 +1292,13 @@ static esp_err_t i2s_config_transfer(i2s_port_t i2s_num, const i2s_config_t *i2s SLOT_CFG(std).ws_width = 1; SLOT_CFG(std).ws_pol = true; } - #if SOC_I2S_HW_VERSION_1 - SLOT_CFG(std).msb_right = false; - #elif SOC_I2S_HW_VERSION_2 +#if SOC_I2S_HW_VERSION_1 + SLOT_CFG(std).msb_right = true; +#elif SOC_I2S_HW_VERSION_2 SLOT_CFG(std).left_align = i2s_config->left_align; SLOT_CFG(std).big_endian = i2s_config->big_edin; SLOT_CFG(std).bit_order_lsb = i2s_config->bit_order_msb; // The old name is incorrect - #endif // SOC_I2S_HW_VERSION_1 +#endif // SOC_I2S_HW_VERSION_1 p_i2s[i2s_num]->active_slot = (int)p_i2s[i2s_num]->slot_cfg.slot_mode == I2S_SLOT_MODE_MONO ? 1 : 2; p_i2s[i2s_num]->total_slot = 2; @@ -1284,13 +1312,13 @@ static esp_err_t i2s_config_transfer(i2s_port_t i2s_num, const i2s_config_t *i2s SLOT_CFG(pdm_tx).hp_scale = I2S_PDM_SIG_SCALING_MUL_1; SLOT_CFG(pdm_tx).lp_scale = I2S_PDM_SIG_SCALING_MUL_1; SLOT_CFG(pdm_tx).sinc_scale = I2S_PDM_SIG_SCALING_MUL_1; - #if SOC_I2S_HW_VERSION_2 +#if SOC_I2S_HW_VERSION_2 SLOT_CFG(pdm_tx).sd_en = true; SLOT_CFG(pdm_tx).hp_en = true; SLOT_CFG(pdm_tx).hp_cut_off_freq_hz = 49; SLOT_CFG(pdm_tx).sd_dither = 0; SLOT_CFG(pdm_tx).sd_dither2 = 0; - #endif // SOC_I2S_HW_VERSION_2 +#endif // SOC_I2S_HW_VERSION_2 /* Generate PDM TX clock configuration */ CLK_CFG().up_sample_fp = 960; @@ -1321,13 +1349,11 @@ static esp_err_t i2s_config_transfer(i2s_port_t i2s_num, const i2s_config_t *i2s SLOT_CFG(tdm).ws_pol = false; if (i2s_config->communication_format == I2S_COMM_FORMAT_STAND_I2S) { SLOT_CFG(tdm).bit_shift = true; - } - else if (i2s_config->communication_format == I2S_COMM_FORMAT_STAND_PCM_SHORT) { + } else if (i2s_config->communication_format == I2S_COMM_FORMAT_STAND_PCM_SHORT) { SLOT_CFG(tdm).bit_shift = true; SLOT_CFG(tdm).ws_width = 1; SLOT_CFG(tdm).ws_pol = true; - } - else if (i2s_config->communication_format == I2S_COMM_FORMAT_STAND_PCM_LONG) { + } else if (i2s_config->communication_format == I2S_COMM_FORMAT_STAND_PCM_LONG) { SLOT_CFG(tdm).bit_shift = true; SLOT_CFG(tdm).ws_width = p_i2s[i2s_num]->slot_cfg.slot_bit_width; SLOT_CFG(tdm).ws_pol = true; @@ -1349,12 +1375,15 @@ static esp_err_t i2s_config_transfer(i2s_port_t i2s_num, const i2s_config_t *i2s #if SOC_I2S_SUPPORTS_ADC_DAC if ((int)p_i2s[i2s_num]->mode == I2S_COMM_MODE_ADC_DAC) { p_i2s[i2s_num]->slot_cfg.slot_mode = (p_i2s[i2s_num]->dir & I2S_DIR_TX) ? - I2S_SLOT_MODE_STEREO : I2S_SLOT_MODE_MONO; + I2S_SLOT_MODE_STEREO : I2S_SLOT_MODE_MONO; p_i2s[i2s_num]->active_slot = (p_i2s[i2s_num]->dir & I2S_DIR_TX) ? 2 : 1; p_i2s[i2s_num]->total_slot = 2; } #endif // SOC_I2S_SUPPORTS_ADC_DAC +#undef SLOT_CFG +#undef CLK_CFG + finish: return ESP_OK; } @@ -1389,16 +1418,16 @@ static esp_err_t i2s_init_legacy(i2s_port_t i2s_num, int intr_alloc_flag) } #if SOC_I2S_SUPPORTS_PDM else if (p_i2s[i2s_num]->mode == I2S_COMM_MODE_PDM) { - #if SOC_I2S_SUPPORTS_PDM_TX +#if SOC_I2S_SUPPORTS_PDM_TX if (p_i2s[i2s_num]->dir & I2S_DIR_TX) { i2s_hal_pdm_enable_tx_channel(&(p_i2s[i2s_num]->hal)); } - #endif - #if SOC_I2S_SUPPORTS_PDM_RX +#endif +#if SOC_I2S_SUPPORTS_PDM_RX if (p_i2s[i2s_num]->dir & I2S_DIR_RX) { i2s_hal_pdm_enable_rx_channel(&(p_i2s[i2s_num]->hal)); } - #endif +#endif } #endif #if SOC_I2S_SUPPORTS_TDM @@ -1455,7 +1484,7 @@ static esp_err_t i2s_init_legacy(i2s_port_t i2s_num, int intr_alloc_flag) esp_err_t i2s_driver_uninstall(i2s_port_t i2s_num) { - ESP_RETURN_ON_FALSE(i2s_num < I2S_NUM_MAX, ESP_ERR_INVALID_ARG, TAG, "i2s_num error"); + ESP_RETURN_ON_FALSE(i2s_num < SOC_I2S_NUM, ESP_ERR_INVALID_ARG, TAG, "i2s_num error"); ESP_RETURN_ON_FALSE(p_i2s[i2s_num], ESP_ERR_INVALID_STATE, TAG, "I2S port %d has not installed", i2s_num); i2s_obj_t *obj = p_i2s[i2s_num]; i2s_stop(i2s_num); @@ -1500,10 +1529,10 @@ esp_err_t i2s_driver_uninstall(i2s_port_t i2s_num) if (obj->use_apll) { // switch back to PLL clock source if (obj->dir & I2S_DIR_TX) { - i2s_ll_tx_clk_set_src(obj->hal.dev, I2S_CLK_PLL_160M); + i2s_ll_tx_clk_set_src(obj->hal.dev, I2S_CLK_SRC_DEFAULT); } if (obj->dir & I2S_DIR_RX) { - i2s_ll_rx_clk_set_src(obj->hal.dev, I2S_CLK_PLL_160M); + i2s_ll_rx_clk_set_src(obj->hal.dev, I2S_CLK_SRC_DEFAULT); } periph_rtc_apll_release(); } @@ -1533,6 +1562,9 @@ esp_err_t i2s_driver_uninstall(i2s_port_t i2s_num) esp_err_t i2s_driver_install(i2s_port_t i2s_num, const i2s_config_t *i2s_config, int queue_size, void *i2s_queue) { +#if CONFIG_I2S_ENABLE_DEBUG_LOG + esp_log_level_set(TAG, ESP_LOG_DEBUG); +#endif esp_err_t ret = ESP_OK; /* Step 1: Check the validity of input parameters */ @@ -1541,12 +1573,12 @@ esp_err_t i2s_driver_install(i2s_port_t i2s_num, const i2s_config_t *i2s_config, /* Step 2: Allocate driver object and register to platform */ i2s_obj_t *i2s_obj = calloc(1, sizeof(i2s_obj_t)); ESP_RETURN_ON_FALSE(i2s_obj, ESP_ERR_NO_MEM, TAG, "no mem for I2S driver"); - p_i2s[i2s_num] = i2s_obj; if (i2s_platform_acquire_occupation(i2s_num, "i2s_legacy") != ESP_OK) { free(i2s_obj); ESP_LOGE(TAG, "register I2S object to platform failed"); return ESP_ERR_INVALID_STATE; } + p_i2s[i2s_num] = i2s_obj; i2s_hal_init(&i2s_obj->hal, i2s_num); /* Step 3: Store and assign configarations */ @@ -1564,7 +1596,7 @@ esp_err_t i2s_driver_install(i2s_port_t i2s_num, const i2s_config_t *i2s_config, i2s_obj->i2s_queue = xQueueCreate(queue_size, sizeof(i2s_event_t)); ESP_GOTO_ON_FALSE(i2s_obj->i2s_queue, ESP_ERR_NO_MEM, err, TAG, "I2S queue create failed"); *((QueueHandle_t *) i2s_queue) = i2s_obj->i2s_queue; - ESP_LOGI(TAG, "queue free spaces: %d", uxQueueSpacesAvailable(i2s_obj->i2s_queue)); + ESP_LOGD(TAG, "queue free spaces: %d", uxQueueSpacesAvailable(i2s_obj->i2s_queue)); } else { i2s_obj->i2s_queue = NULL; } @@ -1586,7 +1618,7 @@ esp_err_t i2s_write(i2s_port_t i2s_num, const void *src, size_t size, size_t *by char *src_byte; size_t bytes_can_write; *bytes_written = 0; - ESP_RETURN_ON_FALSE((i2s_num < I2S_NUM_MAX), ESP_ERR_INVALID_ARG, TAG, "i2s_num error"); + ESP_RETURN_ON_FALSE((i2s_num < SOC_I2S_NUM), ESP_ERR_INVALID_ARG, TAG, "i2s_num error"); ESP_RETURN_ON_FALSE((p_i2s[i2s_num]->tx), ESP_ERR_INVALID_ARG, TAG, "TX mode is not enabled"); xSemaphoreTake(p_i2s[i2s_num]->tx->mux, portMAX_DELAY); #ifdef CONFIG_PM_ENABLE @@ -1629,7 +1661,7 @@ esp_err_t i2s_write_expand(i2s_port_t i2s_num, const void *src, size_t size, siz int aim_bytes; int zero_bytes; *bytes_written = 0; - ESP_RETURN_ON_FALSE((i2s_num < I2S_NUM_MAX), ESP_ERR_INVALID_ARG, TAG, "i2s_num error"); + ESP_RETURN_ON_FALSE((i2s_num < SOC_I2S_NUM), ESP_ERR_INVALID_ARG, TAG, "i2s_num error"); ESP_RETURN_ON_FALSE((size > 0), ESP_ERR_INVALID_ARG, TAG, "size must greater than zero"); ESP_RETURN_ON_FALSE((aim_bits >= src_bits), ESP_ERR_INVALID_ARG, TAG, "aim_bits mustn't be less than src_bits"); ESP_RETURN_ON_FALSE((p_i2s[i2s_num]->tx), ESP_ERR_INVALID_ARG, TAG, "TX mode is not enabled"); @@ -1688,11 +1720,11 @@ esp_err_t i2s_write_expand(i2s_port_t i2s_num, const void *src, size_t size, siz esp_err_t i2s_read(i2s_port_t i2s_num, void *dest, size_t size, size_t *bytes_read, TickType_t ticks_to_wait) { char *data_ptr;; - char*dest_byte; + char *dest_byte; int bytes_can_read; *bytes_read = 0; dest_byte = (char *)dest; - ESP_RETURN_ON_FALSE((i2s_num < I2S_NUM_MAX), ESP_ERR_INVALID_ARG, TAG, "i2s_num error"); + ESP_RETURN_ON_FALSE((i2s_num < SOC_I2S_NUM), ESP_ERR_INVALID_ARG, TAG, "i2s_num error"); ESP_RETURN_ON_FALSE((p_i2s[i2s_num]->rx), ESP_ERR_INVALID_ARG, TAG, "RX mode is not enabled"); xSemaphoreTake(p_i2s[i2s_num]->rx->mux, portMAX_DELAY); #ifdef CONFIG_PM_ENABLE @@ -1771,13 +1803,13 @@ static esp_err_t i2s_check_set_mclk(i2s_port_t i2s_num, gpio_num_t gpio_num) ESP_RETURN_ON_FALSE(GPIO_IS_VALID_GPIO(gpio_num), ESP_ERR_INVALID_ARG, TAG, "mck_io_num invalid"); gpio_matrix_out_check_and_set(gpio_num, i2s_periph_signal[i2s_num].mck_out_sig, 0, 0); #endif - ESP_LOGI(TAG, "I2S%d, MCLK output by GPIO%d", i2s_num, gpio_num); + ESP_LOGD(TAG, "I2S%d, MCLK output by GPIO%d", i2s_num, gpio_num); return ESP_OK; } esp_err_t i2s_zero_dma_buffer(i2s_port_t i2s_num) { - ESP_RETURN_ON_FALSE((i2s_num < I2S_NUM_MAX), ESP_ERR_INVALID_ARG, TAG, "i2s_num error"); + ESP_RETURN_ON_FALSE((i2s_num < SOC_I2S_NUM), ESP_ERR_INVALID_ARG, TAG, "i2s_num error"); uint32_t buf_cnt = p_i2s[i2s_num]->dma_desc_num; /* Clear I2S RX DMA buffer */ @@ -1805,7 +1837,7 @@ esp_err_t i2s_zero_dma_buffer(i2s_port_t i2s_num) esp_err_t i2s_set_pin(i2s_port_t i2s_num, const i2s_pin_config_t *pin) { - ESP_RETURN_ON_FALSE((i2s_num < I2S_NUM_MAX), ESP_ERR_INVALID_ARG, TAG, "i2s_num error"); + ESP_RETURN_ON_FALSE((i2s_num < SOC_I2S_NUM), ESP_ERR_INVALID_ARG, TAG, "i2s_num error"); if (pin == NULL) { #if SOC_I2S_SUPPORTS_DAC return i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN); @@ -1852,3 +1884,48 @@ esp_err_t i2s_set_pin(i2s_port_t i2s_num, const i2s_pin_config_t *pin) gpio_matrix_in_check_and_set(pin->data_in_num, i2s_periph_signal[i2s_num].data_in_sig, 0); return ESP_OK; } + +esp_err_t i2s_platform_acquire_occupation(int id, const char *comp_name) +{ + esp_err_t ret = ESP_ERR_NOT_FOUND; + ESP_RETURN_ON_FALSE(id < SOC_I2S_NUM, ESP_ERR_INVALID_ARG, TAG, "invalid i2s port id"); + portENTER_CRITICAL(&i2s_spinlock[id]); + if (!comp_using_i2s[id]) { + ret = ESP_OK; + comp_using_i2s[id] = comp_name; + periph_module_enable(i2s_periph_signal[id].module); + i2s_ll_enable_clock(I2S_LL_GET_HW(id)); + } + portEXIT_CRITICAL(&i2s_spinlock[id]); + return ret; +} + +esp_err_t i2s_platform_release_occupation(int id) +{ + esp_err_t ret = ESP_ERR_INVALID_STATE; + ESP_RETURN_ON_FALSE(id < SOC_I2S_NUM, ESP_ERR_INVALID_ARG, TAG, "invalid i2s port id"); + portENTER_CRITICAL(&i2s_spinlock[id]); + if (comp_using_i2s[id]) { + ret = ESP_OK; + comp_using_i2s[id] = NULL; + /* Disable module clock */ + periph_module_disable(i2s_periph_signal[id].module); + i2s_ll_disable_clock(I2S_LL_GET_HW(id)); + } + portEXIT_CRITICAL(&i2s_spinlock[id]); + return ret; +} + +/** + * @brief This function will be called during start up, to check that pulse_cnt driver is not running along with the legacy i2s driver + */ +static __attribute__((constructor)) void check_i2s_driver_conflict(void) +{ + extern __attribute__((weak)) esp_err_t i2s_del_channel(void *handle); + /* If the new I2S driver is linked, the weak function will point to the actual function in the new driver, otherwise it is NULL*/ + if ((void *)i2s_del_channel != NULL) { + ESP_EARLY_LOGE(TAG, "CONFLICT! The new i2s driver can't work along with the legacy i2s driver"); + abort(); + } + ESP_EARLY_LOGW(TAG, "legacy i2s driver is deprecated, please migrate to use driver/i2s_std.h, driver/i2s_pdm.h or driver/i2s_tdm.h"); +} diff --git a/components/driver/i2s/i2s_common.c b/components/driver/i2s/i2s_common.c index 656485c533..4fcfb3a201 100644 --- a/components/driver/i2s/i2s_common.c +++ b/components/driver/i2s/i2s_common.c @@ -10,9 +10,18 @@ #include "freertos/FreeRTOS.h" #include "freertos/queue.h" #include "freertos/task.h" + +#include "sdkconfig.h" + +#if CONFIG_I2S_ENABLE_DEBUG_LOG +// The local log level must be defined before including esp_log.h +// Set the maximum log level for this source file +#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG +#endif +#include "esp_log.h" + #include "soc/i2s_periph.h" #include "soc/soc_caps.h" -#include "soc/soc.h" #include "hal/gpio_hal.h" #include "hal/i2s_hal.h" @@ -35,11 +44,8 @@ #include "esp_check.h" #include "esp_attr.h" -// // #include "esp_efuse.h" #include "esp_rom_gpio.h" -#include "sdkconfig.h" - #define I2S_DMA_BUFFER_MAX_SIZE (4092) // If ISR handler is allowed to run whilst cache is disabled, @@ -51,18 +57,19 @@ #define I2S_INTR_ALLOC_FLAGS (ESP_INTR_FLAG_INTRDISABLED | ESP_INTR_FLAG_SHARED) #define I2S_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT #endif //CONFIG_I2S_ISR_IRAM_SAFE +#define I2S_DMA_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA) /** - * @brief Static i2s platform object + * @brief Global i2s platform object * @note For saving all the I2S related information */ -i2s_platform_t s_i2s = { +i2s_platform_t g_i2s = { .spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED, - .controller[0 ... (I2S_NUM_MAX - 1)] = NULL, // groups will be lazy installed - .comp_name[0 ... (I2S_NUM_MAX - 1)] = NULL, + .controller[0 ... (SOC_I2S_NUM - 1)] = NULL, // groups will be lazy installed + .comp_name[0 ... (SOC_I2S_NUM - 1)] = NULL, }; -static const char *TAG = "I2S_COMMON"; +static const char *TAG = "i2s_common"; /*--------------------------------------------------------------------------- I2S Static APIs @@ -70,61 +77,69 @@ static const char *TAG = "I2S_COMMON"; Scope: This file only ----------------------------------------------------------------------------*/ -static void i2s_tx_start(i2s_chan_handle_t handle) +static void i2s_tx_channel_start(i2s_chan_handle_t handle) { - /* No lock here beacuse semaphore has been taken while calling this function */ - i2s_hal_tx_reset(&(handle->parent->hal)); - i2s_hal_tx_reset_fifo(&(handle->parent->hal)); + i2s_hal_tx_reset(&(handle->controller->hal)); +#if SOC_GDMA_SUPPORTED + gdma_reset((handle->dma.dma_chan)); +#else + i2s_hal_tx_reset_dma(&(handle->controller->hal)); +#endif + i2s_hal_tx_reset_fifo(&(handle->controller->hal)); +#if SOC_GDMA_SUPPORTED + gdma_start((handle->dma.dma_chan), (uint32_t) handle->dma.desc[0]); +#else + esp_intr_enable(handle->dma.dma_chan); + i2s_hal_tx_enable_intr(&(handle->controller->hal)); + i2s_hal_tx_enable_dma(&(handle->controller->hal)); + i2s_hal_tx_start_link(&(handle->controller->hal), (uint32_t) handle->dma.desc[0]); +#endif + i2s_hal_tx_start(&(handle->controller->hal)); +} + +static void i2s_rx_channel_start(i2s_chan_handle_t handle) +{ + i2s_hal_rx_reset(&(handle->controller->hal)); #if SOC_GDMA_SUPPORTED gdma_reset(handle->dma.dma_chan); +#else + i2s_hal_rx_reset_dma(&(handle->controller->hal)); +#endif + i2s_hal_rx_reset_fifo(&(handle->controller->hal)); +#if SOC_GDMA_SUPPORTED gdma_start(handle->dma.dma_chan, (uint32_t) handle->dma.desc[0]); #else - i2s_hal_tx_reset_dma(&(handle->parent->hal)); - i2s_hal_tx_enable_intr(&(handle->parent->hal)); - i2s_hal_tx_start_link(&(handle->parent->hal), (uint32_t) handle->dma.desc[0]); + esp_intr_enable(handle->dma.dma_chan); + i2s_hal_rx_enable_intr(&(handle->controller->hal)); + i2s_hal_rx_enable_dma(&(handle->controller->hal)); + i2s_hal_rx_start_link(&(handle->controller->hal), (uint32_t) handle->dma.desc[0]); #endif - i2s_hal_tx_start(&(handle->parent->hal)); + i2s_hal_rx_start(&(handle->controller->hal)); } -static void i2s_rx_start(i2s_chan_handle_t handle) +static void i2s_tx_channel_stop(i2s_chan_handle_t handle) { - /* No lock here beacuse semaphore has been taken while calling this function */ - i2s_hal_rx_reset(&(handle->parent->hal)); - i2s_hal_rx_reset_fifo(&(handle->parent->hal)); + i2s_hal_tx_stop(&(handle->controller->hal)); #if SOC_GDMA_SUPPORTED - gdma_reset(handle->dma.dma_chan); - gdma_start(handle->dma.dma_chan, (uint32_t) handle->dma.desc[0]); -#else - i2s_hal_rx_reset_dma(&(handle->parent->hal)); - i2s_hal_rx_enable_intr(&(handle->parent->hal)); - i2s_hal_rx_start_link(&(handle->parent->hal), (uint32_t) handle->dma.desc[0]); -#endif - i2s_hal_rx_start(&(handle->parent->hal)); -} - -static void i2s_tx_stop(i2s_chan_handle_t handle) -{ - /* No lock here beacuse semaphore has been taken while calling this function */ -#if SOC_GDMA_SUPPORTED - i2s_hal_tx_stop(&(handle->parent->hal)); gdma_stop(handle->dma.dma_chan); #else - i2s_hal_tx_stop(&(handle->parent->hal)); - i2s_hal_tx_stop_link(&(handle->parent->hal)); - i2s_hal_tx_disable_intr(&(handle->parent->hal)); + i2s_hal_tx_stop_link(&(handle->controller->hal)); + i2s_hal_tx_disable_intr(&(handle->controller->hal)); + i2s_hal_tx_disable_dma(&(handle->controller->hal)); + esp_intr_disable(handle->dma.dma_chan); #endif } -static void i2s_rx_stop(i2s_chan_handle_t handle) +static void i2s_rx_channel_stop(i2s_chan_handle_t handle) { - /* No lock here beacuse semaphore has been taken while calling this function */ + i2s_hal_rx_stop(&(handle->controller->hal)); #if SOC_GDMA_SUPPORTED - i2s_hal_rx_stop(&(handle->parent->hal)); gdma_stop(handle->dma.dma_chan); #else - i2s_hal_rx_stop(&(handle->parent->hal)); - i2s_hal_rx_stop_link(&(handle->parent->hal)); - i2s_hal_rx_disable_intr(&(handle->parent->hal)); + i2s_hal_rx_stop_link(&(handle->controller->hal)); + i2s_hal_rx_disable_intr(&(handle->controller->hal)); + i2s_hal_rx_disable_dma(&(handle->controller->hal)); + esp_intr_disable(handle->dma.dma_chan); #endif } @@ -138,8 +153,6 @@ static esp_err_t i2s_destroy_controller_obj(i2s_controller_t **i2s_obj) int id = (*i2s_obj)->id; #if SOC_I2S_HW_VERSION_1 i2s_ll_enable_dma((*i2s_obj)->hal.dev, false); - esp_intr_disable((*i2s_obj)->i2s_isr_handle); - esp_intr_free((*i2s_obj)->i2s_isr_handle); #endif free(*i2s_obj); *i2s_obj = NULL; @@ -152,13 +165,13 @@ static esp_err_t i2s_destroy_controller_obj(i2s_controller_t **i2s_obj) * @param id i2s port id * @param search_reverse reverse the sequence of port acquirement * set false to acquire from I2S_NUM_0 first - * set true to acquire from I2S_NUM_MAX - 1 first + * set true to acquire from SOC_I2S_NUM - 1 first * @return * - pointer of acquired i2s controller object */ static i2s_controller_t *i2s_acquire_controller_obj(int id) { - if (id < 0 || id >= I2S_NUM_MAX) { + if (id < 0 || id >= SOC_I2S_NUM) { return NULL; } /* pre-alloc controller object */ @@ -168,35 +181,34 @@ static i2s_controller_t *i2s_acquire_controller_obj(int id) } pre_alloc->id = id; i2s_hal_init(&pre_alloc->hal, id); -#if !SOC_GDMA_SUPPORTED - pre_alloc->i2s_isr_handle = NULL; -#endif pre_alloc->full_duplex = false; pre_alloc->tx_chan = NULL; pre_alloc->rx_chan = NULL; pre_alloc->mclk = I2S_GPIO_UNUSED; i2s_controller_t *i2s_obj = NULL; - if (!s_i2s.controller[id]) { - /* Try to occupy this i2s controller - if failed, this controller could be occupied by other components */ - if (i2s_platform_acquire_occupation(id, "i2s_driver") == ESP_OK) { - i2s_obj = pre_alloc; - portENTER_CRITICAL(&s_i2s.spinlock); - s_i2s.controller[id] = i2s_obj; - portEXIT_CRITICAL(&s_i2s.spinlock); - #if SOC_I2S_SUPPORTS_ADC_DAC - if (id == I2S_NUM_0) { - adc_ll_digi_set_data_source(ADC_I2S_DATA_SRC_IO_SIG); - } - #endif + /* Try to occupy this i2s controller */ + if (i2s_platform_acquire_occupation(id, "i2s_driver") == ESP_OK) { + portENTER_CRITICAL(&g_i2s.spinlock); + i2s_obj = pre_alloc; + g_i2s.controller[id] = i2s_obj; + portEXIT_CRITICAL(&g_i2s.spinlock); +#if SOC_I2S_SUPPORTS_ADC_DAC + if (id == I2S_NUM_0) { + adc_ll_digi_set_data_source(ADC_I2S_DATA_SRC_IO_SIG); + } +#endif + } else { + free(pre_alloc); + portENTER_CRITICAL(&g_i2s.spinlock); + if (g_i2s.controller[id]) { + i2s_obj = g_i2s.controller[id]; } else { - free(pre_alloc); + } + portEXIT_CRITICAL(&g_i2s.spinlock); + if (i2s_obj == NULL) { ESP_LOGE(TAG, "i2s%d might be occupied by other component", id); } - } else { - i2s_obj = s_i2s.controller[id]; - free(pre_alloc); } return i2s_obj; @@ -212,19 +224,21 @@ static inline bool i2s_take_available_channel(i2s_controller_t *i2s_obj, uint8_t */ chan_search_mask = I2S_DIR_RX | I2S_DIR_TX; #endif - portENTER_CRITICAL(&s_i2s.spinlock); + portENTER_CRITICAL(&g_i2s.spinlock); if (!(chan_search_mask & i2s_obj->chan_occupancy)) { i2s_obj->chan_occupancy |= chan_search_mask; is_available = true; } - portEXIT_CRITICAL(&s_i2s.spinlock); + portEXIT_CRITICAL(&g_i2s.spinlock); return is_available; } -static esp_err_t i2s_register_channel(i2s_controller_t *i2s_obj, i2s_dir_t dir) +static esp_err_t i2s_register_channel(i2s_controller_t *i2s_obj, i2s_dir_t dir, uint32_t desc_num) { I2S_NULL_POINTER_CHECK(TAG, i2s_obj); + esp_err_t ret = ESP_OK; + i2s_chan_handle_t new_chan = (i2s_chan_handle_t)heap_caps_calloc(1, sizeof(struct i2s_channel_t), I2S_MEM_ALLOC_CAPS); ESP_RETURN_ON_FALSE(new_chan, ESP_ERR_NO_MEM, TAG, "No memory for new channel"); new_chan->mode = I2S_COMM_MODE_NONE; @@ -235,19 +249,41 @@ static esp_err_t i2s_register_channel(i2s_controller_t *i2s_obj, i2s_dir_t dir) new_chan->apll_en = false; #endif new_chan->mode_info = NULL; - new_chan->parent = i2s_obj; - new_chan->event_queue = NULL; + new_chan->controller = i2s_obj; +#if CONFIG_PM_ENABLE new_chan->pm_lock = NULL; // Init in i2s_set_clock according to clock source - new_chan->msg_queue = NULL; +#endif +#if CONFIG_I2S_ISR_IRAM_SAFE + new_chan->msg_que_storage = (uint8_t *)heap_caps_calloc(desc_num - 1, sizeof(uint8_t *), I2S_MEM_ALLOC_CAPS); + ESP_GOTO_ON_FALSE(new_chan->msg_que_storage, ESP_ERR_NO_MEM, err, TAG, "No memory for message queue storage"); + new_chan->msg_que_struct = (StaticQueue_t *)heap_caps_calloc(1, sizeof(StaticQueue_t), I2S_MEM_ALLOC_CAPS); + ESP_GOTO_ON_FALSE(new_chan->msg_que_struct, ESP_ERR_NO_MEM, err, TAG, "No memory for message queue struct"); + new_chan->msg_queue = xQueueCreateStatic(desc_num - 1, sizeof(uint8_t *), new_chan->msg_que_storage, new_chan->msg_que_struct); + ESP_GOTO_ON_FALSE(new_chan->msg_queue, ESP_ERR_NO_MEM, err, TAG, "No memory for message queue"); + new_chan->mutex_struct = (StaticSemaphore_t *)heap_caps_calloc(1, sizeof(StaticSemaphore_t), I2S_MEM_ALLOC_CAPS); + ESP_GOTO_ON_FALSE(new_chan->mutex_struct, ESP_ERR_NO_MEM, err, TAG, "No memory for mutex struct"); + new_chan->mutex = xSemaphoreCreateMutexStatic(new_chan->mutex_struct); + ESP_GOTO_ON_FALSE(new_chan->mutex, ESP_ERR_NO_MEM, err, TAG, "No memory for mutex"); + new_chan->binary_struct = (StaticSemaphore_t *)heap_caps_calloc(1, sizeof(StaticSemaphore_t), I2S_MEM_ALLOC_CAPS); + ESP_GOTO_ON_FALSE(new_chan->binary_struct, ESP_ERR_NO_MEM, err, TAG, "No memory for binary struct"); + new_chan->binary = xSemaphoreCreateBinaryStatic(new_chan->binary_struct); + ESP_GOTO_ON_FALSE(new_chan->binary, ESP_ERR_NO_MEM, err, TAG, "No memory for binary"); +#else + new_chan->msg_queue = xQueueCreate(desc_num - 1, sizeof(uint8_t *)); + ESP_GOTO_ON_FALSE(new_chan->msg_queue, ESP_ERR_NO_MEM, err, TAG, "No memory for message queue"); new_chan->mutex = xSemaphoreCreateMutex(); + ESP_GOTO_ON_FALSE(new_chan->mutex, ESP_ERR_NO_MEM, err, TAG, "No memory for mutex semaphore"); + new_chan->binary = xSemaphoreCreateBinary(); + ESP_GOTO_ON_FALSE(new_chan->binary, ESP_ERR_NO_MEM, err, TAG, "No memory for binary semaphore"); +#endif + + new_chan->callbacks.on_recv = NULL; + new_chan->callbacks.on_recv_q_ovf = NULL; + new_chan->callbacks.on_sent = NULL; + new_chan->callbacks.on_send_q_ovf = NULL; new_chan->start = NULL; new_chan->stop = NULL; - if (!new_chan->mutex) { - ESP_LOGE(TAG, "mutex create failed"); - free(new_chan); - return ESP_ERR_NO_MEM; - } if (dir == I2S_DIR_TX) { if (i2s_obj->tx_chan) { i2s_del_channel(i2s_obj->tx_chan); @@ -260,7 +296,66 @@ static esp_err_t i2s_register_channel(i2s_controller_t *i2s_obj, i2s_dir_t dir) } i2s_obj->rx_chan = new_chan; } - return ESP_OK; + return ret; +err: +#if CONFIG_I2S_ISR_IRAM_SAFE + if (new_chan->msg_que_storage) { + free(new_chan->msg_que_storage); + } + if (new_chan->msg_que_struct) { + free(new_chan->msg_que_struct); + } + if (new_chan->mutex_struct) { + free(new_chan->mutex_struct); + } + if (new_chan->binary_struct) { + free(new_chan->binary_struct); + } +#endif + if (new_chan->msg_queue) { + vQueueDelete(new_chan->msg_queue); + } + if (new_chan->mutex) { + vSemaphoreDelete(new_chan->mutex); + } + if (new_chan->binary) { + vSemaphoreDelete(new_chan->binary); + } + free(new_chan); + + return ret; +} + +esp_err_t i2s_channel_register_event_callback(i2s_chan_handle_t handle, const i2s_event_callbacks_t *callbacks, void *user_data) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + I2S_NULL_POINTER_CHECK(TAG, callbacks); + esp_err_t ret = ESP_OK; +#if CONFIG_I2S_ISR_IRAM_SAFE + if (callbacks->on_recv) { + ESP_RETURN_ON_FALSE(esp_ptr_in_iram(callbacks->on_recv), ESP_ERR_INVALID_ARG, TAG, "on_recv callback not in IRAM"); + } + if (callbacks->on_recv_q_ovf) { + ESP_RETURN_ON_FALSE(esp_ptr_in_iram(callbacks->on_recv_q_ovf), ESP_ERR_INVALID_ARG, TAG, "on_recv_q_ovf callback not in IRAM"); + } + if (callbacks->on_sent) { + ESP_RETURN_ON_FALSE(esp_ptr_in_iram(callbacks->on_sent), ESP_ERR_INVALID_ARG, TAG, "on_sent callback not in IRAM"); + } + if (callbacks->on_send_q_ovf) { + ESP_RETURN_ON_FALSE(esp_ptr_in_iram(callbacks->on_send_q_ovf), ESP_ERR_INVALID_ARG, TAG, "on_send_q_ovf callback not in IRAM"); + } + if (user_data) { + ESP_RETURN_ON_FALSE(esp_ptr_internal(user_data), ESP_ERR_INVALID_ARG, TAG, "user context not in internal RAM"); + } +#endif + + xSemaphoreTake(handle->mutex, portMAX_DELAY); + ESP_GOTO_ON_FALSE(handle->state < I2S_CHAN_STATE_RUNNING, ESP_ERR_INVALID_STATE, err, TAG, "invalid state, I2S has enabled"); + memcpy(&(handle->callbacks), callbacks, sizeof(i2s_event_callbacks_t)); + handle->user_data = user_data; +err: + xSemaphoreGive(handle->mutex); + return ret; } uint32_t i2s_get_buf_size(i2s_chan_handle_t handle, uint32_t data_bit_width, uint32_t dma_frame_num) @@ -292,8 +387,12 @@ esp_err_t i2s_free_dma_desc(i2s_chan_handle_t handle) free(handle->dma.desc[i]); } } - free(handle->dma.bufs); - free(handle->dma.desc); + if (handle->dma.bufs) { + free(handle->dma.bufs); + } + if (handle->dma.desc) { + free(handle->dma.desc); + } handle->dma.desc = NULL; return ESP_OK; @@ -307,15 +406,12 @@ esp_err_t i2s_alloc_dma_desc(i2s_chan_handle_t handle, uint32_t num, uint32_t bu handle->dma.desc_num = num; handle->dma.buf_size = bufsize; - handle->msg_queue = xQueueCreate(num, sizeof(uint8_t *)); - ESP_GOTO_ON_FALSE(handle->msg_queue, ESP_ERR_NO_MEM, err, TAG, "message queue create failed"); - handle->dma.desc = (lldesc_t **)heap_caps_calloc(num, sizeof(lldesc_t *), I2S_MEM_ALLOC_CAPS); ESP_GOTO_ON_FALSE(handle->dma.desc, ESP_ERR_NO_MEM, err, TAG, "create I2S DMA decriptor array failed"); handle->dma.bufs = (uint8_t **)heap_caps_calloc(num, sizeof(uint8_t *), I2S_MEM_ALLOC_CAPS); for (int i = 0; i < num; i++) { /* Allocate DMA descriptor */ - handle->dma.desc[i] = (lldesc_t *) heap_caps_calloc(1, sizeof(lldesc_t), MALLOC_CAP_DMA); + handle->dma.desc[i] = (lldesc_t *) heap_caps_calloc(1, sizeof(lldesc_t), I2S_DMA_ALLOC_CAPS); ESP_GOTO_ON_FALSE(handle->dma.desc[i], ESP_ERR_NO_MEM, err, TAG, "allocate DMA description failed"); handle->dma.desc[i]->owner = 1; handle->dma.desc[i]->eof = 1; @@ -323,7 +419,7 @@ esp_err_t i2s_alloc_dma_desc(i2s_chan_handle_t handle, uint32_t num, uint32_t bu handle->dma.desc[i]->length = bufsize; handle->dma.desc[i]->size = bufsize; handle->dma.desc[i]->offset = 0; - handle->dma.bufs[i] = (uint8_t *) heap_caps_calloc(1, bufsize * sizeof(uint8_t), MALLOC_CAP_DMA); + handle->dma.bufs[i] = (uint8_t *) heap_caps_calloc(1, bufsize * sizeof(uint8_t), I2S_DMA_ALLOC_CAPS); handle->dma.desc[i]->buf = handle->dma.bufs[i]; ESP_GOTO_ON_FALSE(handle->dma.desc[i]->buf, ESP_ERR_NO_MEM, err, TAG, "allocate DMA buffer failed"); } @@ -333,9 +429,9 @@ esp_err_t i2s_alloc_dma_desc(i2s_chan_handle_t handle, uint32_t num, uint32_t bu handle->dma.desc[i]->empty = (uint32_t)((i < (num - 1)) ? (handle->dma.desc[i + 1]) : handle->dma.desc[0]); } if (handle->dir == I2S_DIR_RX) { - i2s_ll_rx_set_eof_num(handle->parent->hal.dev, bufsize); + i2s_ll_rx_set_eof_num(handle->controller->hal.dev, bufsize); } - ESP_LOGD(TAG, "DMA malloc info: dma_desc_num = %d, dma_desc_buf_size = dma_frame_num * slot_num * data_bit_width = %d, ", bufsize, num); + ESP_LOGD(TAG, "DMA malloc info: dma_desc_num = %d, dma_desc_buf_size = dma_frame_num * slot_num * data_bit_width = %d, ", num, bufsize); return ESP_OK; err: i2s_free_dma_desc(handle); @@ -343,16 +439,16 @@ err: } #if SOC_I2S_SUPPORTS_APLL -uint32_t i2s_set_get_apll_freq(uint32_t mclk_freq) +uint32_t i2s_set_get_apll_freq(uint32_t mclk_freq_hz) { /* Calculate the expected APLL */ - int mclk_div = (int)((SOC_APLL_MIN_HZ / mclk_freq) + 1); + int mclk_div = (int)((SOC_APLL_MIN_HZ / mclk_freq_hz) + 1); /* apll_freq = mclk * div * when div = 1, hardware will still divide 2 * when div = 0, the final mclk will be unpredictable * So the div here should be at least 2 */ mclk_div = mclk_div < 2 ? 2 : mclk_div; - uint32_t expt_freq = mclk_freq * mclk_div; + uint32_t expt_freq = mclk_freq_hz * mclk_div; uint32_t real_freq = 0; esp_err_t ret = periph_rtc_apll_freq_set(expt_freq, &real_freq); if (ret == ESP_ERR_INVALID_ARG) { @@ -360,95 +456,157 @@ uint32_t i2s_set_get_apll_freq(uint32_t mclk_freq) return 0; } if (ret == ESP_ERR_INVALID_STATE) { - ESP_LOGW(TAG, "APLL is occupied already, it is working at %d Hz while the expected frequency is %d Hz", real_freq, expt_freq); - ESP_LOGW(TAG, "Trying to work at %d Hz...", real_freq); + ESP_LOGW(TAG, "APLL is occupied already, it is working at %d Hz while the expected frequency is %d Hz", real_freq, expt_freq); + ESP_LOGW(TAG, "Trying to work at %d Hz...", real_freq); } - ESP_LOGI(TAG, "APLL expected frequency is %d Hz, real frequency is %d Hz", expt_freq, real_freq); + ESP_LOGD(TAG, "APLL expected frequency is %d Hz, real frequency is %d Hz", expt_freq, real_freq); return real_freq; } #endif -static inline void i2s_isr_send_event_queue(QueueHandle_t event_queue, i2s_event_type_t type, portBASE_TYPE *need_yield) -{ - if (event_queue) { - i2s_event_t i2s_event; - portBASE_TYPE _need_yield; - i2s_event.type = type; - xQueueSendFromISR(event_queue, (void * )&i2s_event, &_need_yield); - *need_yield |= _need_yield; - } -} - #if SOC_GDMA_SUPPORTED static bool IRAM_ATTR i2s_dma_rx_callback(gdma_channel_handle_t dma_chan, gdma_event_data_t *event_data, void *user_data) { i2s_chan_handle_t handle = (i2s_chan_handle_t)user_data; - portBASE_TYPE need_yield = 0; - BaseType_t ret = 0; + portBASE_TYPE need_yield1 = 0; + portBASE_TYPE need_yield2 = 0; + portBASE_TYPE user_need_yield = 0; lldesc_t *finish_desc; + uint32_t dummy; - if (handle) { - finish_desc = (lldesc_t *)event_data->rx_eof_desc_addr; - ret = xQueueSendFromISR(handle->msg_queue, &(finish_desc->buf), &need_yield); - i2s_event_type_t type = (ret == pdTRUE) ? I2S_EVENT_RX_DONE : I2S_EVENT_RX_Q_OVF; - i2s_isr_send_event_queue(handle->event_queue, type, &need_yield); + finish_desc = (lldesc_t *)event_data->rx_eof_desc_addr; + i2s_event_data_t evt = { + .data = &(finish_desc->buf), + .size = handle->dma.buf_size, + }; + if (handle->callbacks.on_recv) { + user_need_yield |= handle->callbacks.on_recv(handle, &evt, handle->user_data); } - return need_yield; + if (xQueueIsQueueFullFromISR(handle->msg_queue)) { + xQueueReceiveFromISR(handle->msg_queue, &dummy, &need_yield1); + if (handle->callbacks.on_recv_q_ovf) { + evt.data = NULL; + user_need_yield |= handle->callbacks.on_recv_q_ovf(handle, &evt, handle->user_data); + } + } + xQueueSendFromISR(handle->msg_queue, &(finish_desc->buf), &need_yield2); + + return need_yield1 | need_yield2 | user_need_yield; } static bool IRAM_ATTR i2s_dma_tx_callback(gdma_channel_handle_t dma_chan, gdma_event_data_t *event_data, void *user_data) { i2s_chan_handle_t handle = (i2s_chan_handle_t)user_data; - portBASE_TYPE need_yield = 0; - BaseType_t ret; + portBASE_TYPE need_yield1 = 0; + portBASE_TYPE need_yield2 = 0; + portBASE_TYPE user_need_yield = 0; lldesc_t *finish_desc; - if (handle) { - finish_desc = (lldesc_t *)(event_data->tx_eof_desc_addr); - if (handle->dma.auto_clear) { - uint8_t *sent_buf = (uint8_t *)finish_desc->buf; - memset(sent_buf, 0, handle->dma.buf_size); - } - ret = xQueueSendFromISR(handle->msg_queue, &(finish_desc->buf), &need_yield); - i2s_event_type_t type = (ret == pdTRUE) ? I2S_EVENT_TX_DONE : I2S_EVENT_TX_Q_OVF; - i2s_isr_send_event_queue(handle->event_queue, type, &need_yield); + uint32_t dummy; + + finish_desc = (lldesc_t *)(event_data->tx_eof_desc_addr); + i2s_event_data_t evt = { + .data = &(finish_desc->buf), + .size = handle->dma.buf_size, + }; + if (handle->callbacks.on_sent) { + user_need_yield |= handle->callbacks.on_sent(handle, &evt, handle->user_data); } - return need_yield; + if (xQueueIsQueueFullFromISR(handle->msg_queue)) { + xQueueReceiveFromISR(handle->msg_queue, &dummy, &need_yield1); + if (handle->callbacks.on_send_q_ovf) { + evt.data = NULL; + user_need_yield |= handle->callbacks.on_send_q_ovf(handle, &evt, handle->user_data); + } + } + xQueueSendFromISR(handle->msg_queue, &(finish_desc->buf), &need_yield2); + + if (handle->dma.auto_clear) { + uint8_t *sent_buf = (uint8_t *)finish_desc->buf; + memset(sent_buf, 0, handle->dma.buf_size); + } + + return need_yield1 | need_yield2 | user_need_yield; } #else -static void IRAM_ATTR i2s_default_intr_handler(void *arg) + +static void IRAM_ATTR i2s_dma_rx_callback(void *arg) { - portBASE_TYPE tx_need_yield = 0; - portBASE_TYPE rx_need_yield = 0; + portBASE_TYPE need_yield1 = 0; + portBASE_TYPE need_yield2 = 0; + portBASE_TYPE user_need_yield = 0; lldesc_t *finish_desc = NULL; - BaseType_t ret; - i2s_controller_t *obj = (i2s_controller_t *)arg; - uint32_t status = i2s_hal_get_intr_status(&(obj->hal)); - i2s_hal_clear_intr_status(&(obj->hal), status); - if (!obj || !status) { + i2s_event_data_t evt; + i2s_chan_handle_t handle = (i2s_chan_handle_t)arg; + uint32_t dummy; + + uint32_t status = i2s_hal_get_intr_status(&(handle->controller->hal)); + i2s_hal_clear_intr_status(&(handle->controller->hal), status); + if (!status) { return; } - if (obj->tx_chan && (status & I2S_LL_EVENT_TX_EOF)) { - i2s_hal_get_out_eof_des_addr(&(obj->hal), (uint32_t *)&finish_desc); - // Auto clear the dma buffer after data sent - if (obj->tx_chan->dma.auto_clear) { - uint8_t *buff = (uint8_t *)finish_desc->buf; - memset(buff, 0, obj->tx_chan->dma.buf_size); + if (handle && (status & I2S_LL_EVENT_RX_EOF)) { + i2s_hal_get_in_eof_des_addr(&(handle->controller->hal), (uint32_t *)&finish_desc); + evt.data = &(finish_desc->buf); + evt.size = handle->dma.buf_size; + if (handle->callbacks.on_recv) { + user_need_yield |= handle->callbacks.on_recv(handle, &evt, handle->user_data); } - ret = xQueueSendFromISR(obj->tx_chan->msg_queue, &(finish_desc->buf), &tx_need_yield); - i2s_event_type_t type = (ret == pdTRUE) ? I2S_EVENT_TX_DONE : I2S_EVENT_TX_Q_OVF; - i2s_isr_send_event_queue(obj->tx_chan->event_queue, type, &tx_need_yield); + if (xQueueIsQueueFullFromISR(handle->msg_queue)) { + xQueueReceiveFromISR(handle->msg_queue, &dummy, &need_yield1); + if (handle->callbacks.on_recv_q_ovf) { + evt.data = NULL; + user_need_yield |= handle->callbacks.on_recv_q_ovf(handle, &evt, handle->user_data); + } + } + xQueueSendFromISR(handle->msg_queue, &(finish_desc->buf), &need_yield2); } - if (obj->rx_chan && (status & I2S_LL_EVENT_RX_EOF)) { - i2s_hal_get_in_eof_des_addr(&(obj->hal), (uint32_t *)&finish_desc); - ret = xQueueSendFromISR(obj->rx_chan->msg_queue, &(finish_desc->buf), &rx_need_yield); - i2s_event_type_t type = (ret == pdTRUE) ? I2S_EVENT_RX_DONE : I2S_EVENT_RX_Q_OVF; - i2s_isr_send_event_queue(obj->rx_chan->event_queue, type, &rx_need_yield); + if (need_yield1 || need_yield2 || user_need_yield) { + portYIELD_FROM_ISR(); + } +} + +static void IRAM_ATTR i2s_dma_tx_callback(void *arg) +{ + portBASE_TYPE need_yield1 = 0; + portBASE_TYPE need_yield2 = 0; + portBASE_TYPE user_need_yield = 0; + lldesc_t *finish_desc = NULL; + i2s_event_data_t evt; + i2s_chan_handle_t handle = (i2s_chan_handle_t)arg; + uint32_t dummy; + + uint32_t status = i2s_hal_get_intr_status(&(handle->controller->hal)); + i2s_hal_clear_intr_status(&(handle->controller->hal), status); + if (!status) { + return; } - if (tx_need_yield || rx_need_yield) { + if (handle && (status & I2S_LL_EVENT_TX_EOF)) { + i2s_hal_get_out_eof_des_addr(&(handle->controller->hal), (uint32_t *)&finish_desc); + evt.data = &(finish_desc->buf); + evt.size = handle->dma.buf_size; + if (handle->callbacks.on_sent) { + user_need_yield |= handle->callbacks.on_sent(handle, &evt, handle->user_data); + } + if (xQueueIsQueueFullFromISR(handle->msg_queue)) { + xQueueReceiveFromISR(handle->msg_queue, &dummy, &need_yield1); + if (handle->callbacks.on_send_q_ovf) { + evt.data = NULL; + user_need_yield |= handle->callbacks.on_send_q_ovf(handle, &evt, handle->user_data); + } + } + xQueueSendFromISR(handle->msg_queue, &(finish_desc->buf), &need_yield2); + // Auto clear the dma buffer after data sent + if (handle->dma.auto_clear) { + uint8_t *buff = (uint8_t *)finish_desc->buf; + memset(buff, 0, handle->dma.buf_size); + } + } + + if (need_yield1 || need_yield2 || user_need_yield) { portYIELD_FROM_ISR(); } } @@ -468,8 +626,8 @@ static void IRAM_ATTR i2s_default_intr_handler(void *arg) */ esp_err_t i2s_init_dma_intr(i2s_chan_handle_t handle, int intr_flag) { - i2s_port_t port_id = handle->parent->id; - ESP_RETURN_ON_FALSE((port_id >= 0) && (port_id < I2S_NUM_MAX), ESP_ERR_INVALID_ARG, TAG, "invalid handle"); + i2s_port_t port_id = handle->controller->id; + ESP_RETURN_ON_FALSE((port_id >= 0) && (port_id < SOC_I2S_NUM), ESP_ERR_INVALID_ARG, TAG, "invalid handle"); #if SOC_GDMA_SUPPORTED /* Set GDMA trigger module */ gdma_trigger_t trig = {.periph = GDMA_TRIG_PERIPH_I2S}; @@ -487,7 +645,7 @@ esp_err_t i2s_init_dma_intr(i2s_chan_handle_t handle, int intr_flag) /* Set GDMA config */ gdma_channel_alloc_config_t dma_cfg = {}; - if (handle->dir & I2S_DIR_TX) { + if (handle->dir == I2S_DIR_TX) { dma_cfg.direction = GDMA_CHANNEL_DIRECTION_TX; /* Register a new GDMA tx channel */ ESP_RETURN_ON_ERROR(gdma_new_channel(&dma_cfg, &handle->dma.dma_chan), TAG, "Register tx dma channel error"); @@ -495,8 +653,7 @@ esp_err_t i2s_init_dma_intr(i2s_chan_handle_t handle, int intr_flag) gdma_tx_event_callbacks_t cb = {.on_trans_eof = i2s_dma_tx_callback}; /* Set callback function for GDMA, the interrupt is triggered by GDMA, then the GDMA ISR will call the callback function */ gdma_register_tx_event_callbacks(handle->dma.dma_chan, &cb, handle); - } - if (handle->dir & I2S_DIR_RX) { + } else { dma_cfg.direction = GDMA_CHANNEL_DIRECTION_RX; /* Register a new GDMA rx channel */ ESP_RETURN_ON_ERROR(gdma_new_channel(&dma_cfg, &handle->dma.dma_chan), TAG, "Register rx dma channel error"); @@ -506,37 +663,52 @@ esp_err_t i2s_init_dma_intr(i2s_chan_handle_t handle, int intr_flag) gdma_register_rx_event_callbacks(handle->dma.dma_chan, &cb, handle); } #else - /* Initial I2S module interrupt */ - if (!handle->parent->i2s_isr_handle) { - ESP_RETURN_ON_ERROR(esp_intr_alloc(i2s_periph_signal[port_id].irq, intr_flag, i2s_default_intr_handler, handle->parent, &(handle->parent->i2s_isr_handle)), TAG, "Register I2S Interrupt error"); - esp_intr_enable(handle->parent->i2s_isr_handle); + intr_flag |= ESP_INTR_FLAG_SHARED; + /* Initialize I2S module interrupt */ + if (handle->dir == I2S_DIR_TX) { + esp_intr_alloc_intrstatus(i2s_periph_signal[port_id].irq, intr_flag, + (uint32_t)i2s_ll_get_interrupt_status_reg(handle->controller->hal.dev), I2S_LL_TX_EVENT_MASK, + i2s_dma_tx_callback, handle, &handle->dma.dma_chan); + } else { + esp_intr_alloc_intrstatus(i2s_periph_signal[port_id].irq, intr_flag, + (uint32_t)i2s_ll_get_interrupt_status_reg(handle->controller->hal.dev), I2S_LL_RX_EVENT_MASK, + i2s_dma_rx_callback, handle, &handle->dma.dma_chan); } /* Start DMA */ - i2s_ll_enable_dma(handle->parent->hal.dev, true); + i2s_ll_enable_dma(handle->controller->hal.dev, true); #endif // SOC_GDMA_SUPPORTED return ESP_OK; } -void i2s_gpio_check_and_set(gpio_num_t gpio, uint32_t signal_idx, bool is_input) +void i2s_gpio_check_and_set(gpio_num_t gpio, uint32_t signal_idx, bool is_input, bool is_invert) { - /* Ignore the pin if pin = -1 */ + /* Ignore the pin if pin = I2S_GPIO_UNUSED */ if (gpio != I2S_GPIO_UNUSED) { + gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[gpio], PIN_FUNC_GPIO); if (is_input) { - gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[gpio], PIN_FUNC_GPIO); /* Set direction, for some GPIOs, the input function are not enabled as default */ gpio_set_direction(gpio, GPIO_MODE_INPUT); - esp_rom_gpio_connect_in_signal(gpio, signal_idx, 0); + esp_rom_gpio_connect_in_signal(gpio, signal_idx, is_invert); } else { - gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[gpio], PIN_FUNC_GPIO); gpio_set_direction(gpio, GPIO_MODE_OUTPUT); - esp_rom_gpio_connect_out_signal(gpio, signal_idx, 0, 0); + esp_rom_gpio_connect_out_signal(gpio, signal_idx, is_invert, 0); } } } -esp_err_t i2s_check_set_mclk(i2s_port_t id, gpio_num_t gpio_num) +void i2s_gpio_loopback_set(gpio_num_t gpio, uint32_t out_sig_idx, uint32_t in_sig_idx) { - if (gpio_num == -1) { + if (gpio != I2S_GPIO_UNUSED) { + gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[gpio], PIN_FUNC_GPIO); + gpio_set_direction(gpio, GPIO_MODE_INPUT_OUTPUT); + esp_rom_gpio_connect_out_signal(gpio, out_sig_idx, 0, 0); + esp_rom_gpio_connect_in_signal(gpio, in_sig_idx, 0); + } +} + +esp_err_t i2s_check_set_mclk(i2s_port_t id, gpio_num_t gpio_num, bool is_apll, bool is_invert) +{ + if (gpio_num == I2S_GPIO_UNUSED) { return ESP_OK; } #if CONFIG_IDF_TARGET_ESP32 @@ -545,20 +717,20 @@ esp_err_t i2s_check_set_mclk(i2s_port_t id, gpio_num_t gpio_num) "ESP32 only support to set GPIO0/GPIO1/GPIO3 as mclk signal, error GPIO number:%d", gpio_num); bool is_i2s0 = id == I2S_NUM_0; if (gpio_num == GPIO_NUM_0) { - PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0_CLK_OUT1); - WRITE_PERI_REG(PIN_CTRL, is_i2s0 ? 0xFFF0 : 0xFFFF); + gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0_CLK_OUT1); + gpio_ll_iomux_pin_ctrl(is_apll ? 0xFFF6 : (is_i2s0 ? 0xFFF0 : 0xFFFF)); } else if (gpio_num == GPIO_NUM_1) { - PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD_CLK_OUT3); - WRITE_PERI_REG(PIN_CTRL, is_i2s0 ? 0xF0F0 : 0xF0FF); + gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD_CLK_OUT3); + gpio_ll_iomux_pin_ctrl(is_apll ? 0xF6F6 : (is_i2s0 ? 0xF0F0 : 0xF0FF)); } else { - PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD_CLK_OUT2); - WRITE_PERI_REG(PIN_CTRL, is_i2s0 ? 0xFF00 : 0xFF0F); + gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD_CLK_OUT2); + gpio_ll_iomux_pin_ctrl(is_apll ? 0xFF66 : (is_i2s0 ? 0xFF00 : 0xFF0F)); } #else ESP_RETURN_ON_FALSE(GPIO_IS_VALID_GPIO(gpio_num), ESP_ERR_INVALID_ARG, TAG, "mck_io_num invalid"); - i2s_gpio_check_and_set(gpio_num, i2s_periph_signal[id].mck_out_sig, false); + i2s_gpio_check_and_set(gpio_num, i2s_periph_signal[id].mck_out_sig, false, is_invert); #endif - ESP_LOGI(TAG, "MCLK is pinned to GPIO%d on I2S%d", id, gpio_num); + ESP_LOGD(TAG, "MCLK is pinned to GPIO%d on I2S%d", id, gpio_num); return ESP_OK; } @@ -569,6 +741,9 @@ esp_err_t i2s_check_set_mclk(i2s_port_t id, gpio_num_t gpio_num) ----------------------------------------------------------------------------*/ esp_err_t i2s_new_channel(const i2s_chan_config_t *chan_cfg, i2s_chan_handle_t *tx_handle, i2s_chan_handle_t *rx_handle) { +#if CONFIG_I2S_ENABLE_DEBUG_LOG + esp_log_level_set(TAG, ESP_LOG_DEBUG); +#endif /* Parameter validity check */ I2S_NULL_POINTER_CHECK(TAG, chan_cfg); I2S_NULL_POINTER_CHECK(TAG, tx_handle || rx_handle); @@ -586,7 +761,7 @@ esp_err_t i2s_new_channel(const i2s_chan_config_t *chan_cfg, i2s_chan_handle_t * /* Channel will be registered to one i2s port automatically if id is I2S_NUM_AUTO * Otherwise, the channel will be registered to the specific port. */ if (id == I2S_NUM_AUTO) { - for (int i = 0; i < I2S_NUM_MAX && !channel_found; i++) { + for (int i = 0; i < SOC_I2S_NUM && !channel_found; i++) { i2s_obj = i2s_acquire_controller_obj(i); if (!i2s_obj) { continue; @@ -602,26 +777,28 @@ esp_err_t i2s_new_channel(const i2s_chan_config_t *chan_cfg, i2s_chan_handle_t * ESP_GOTO_ON_FALSE(channel_found, ESP_ERR_NOT_FOUND, err, TAG, "no available channel found"); /* Register and specify the tx handle */ if (tx_handle) { - ESP_GOTO_ON_ERROR(i2s_register_channel(i2s_obj, I2S_DIR_TX), err, TAG, "register I2S tx channel failed"); + ESP_GOTO_ON_ERROR(i2s_register_channel(i2s_obj, I2S_DIR_TX, chan_cfg->dma_desc_num), + err, TAG, "register I2S tx channel failed"); i2s_obj->tx_chan->role = chan_cfg->role; i2s_obj->tx_chan->dma.auto_clear = chan_cfg->auto_clear; i2s_obj->tx_chan->dma.desc_num = chan_cfg->dma_desc_num; i2s_obj->tx_chan->dma.frame_num = chan_cfg->dma_frame_num; - i2s_obj->tx_chan->start = i2s_tx_start; - i2s_obj->tx_chan->stop = i2s_tx_stop; + i2s_obj->tx_chan->start = i2s_tx_channel_start; + i2s_obj->tx_chan->stop = i2s_tx_channel_stop; *tx_handle = i2s_obj->tx_chan; - ESP_LOGI(TAG, "tx channel is registered on I2S%d successfully", i2s_obj->id); + ESP_LOGD(TAG, "tx channel is registered on I2S%d successfully", i2s_obj->id); } /* Register and specify the rx handle */ if (rx_handle) { - ESP_GOTO_ON_ERROR(i2s_register_channel(i2s_obj, I2S_DIR_RX), err, TAG, "register I2S rx channel failed"); + ESP_GOTO_ON_ERROR(i2s_register_channel(i2s_obj, I2S_DIR_RX, chan_cfg->dma_desc_num), + err, TAG, "register I2S rx channel failed"); i2s_obj->rx_chan->role = chan_cfg->role; i2s_obj->rx_chan->dma.desc_num = chan_cfg->dma_desc_num; i2s_obj->rx_chan->dma.frame_num = chan_cfg->dma_frame_num; - i2s_obj->rx_chan->start = i2s_rx_start; - i2s_obj->rx_chan->stop = i2s_rx_stop; + i2s_obj->rx_chan->start = i2s_rx_channel_start; + i2s_obj->rx_chan->stop = i2s_rx_channel_stop; *rx_handle = i2s_obj->rx_chan; - ESP_LOGI(TAG, "rx channel is registered on I2S%d successfully", i2s_obj->id); + ESP_LOGD(TAG, "rx channel is registered on I2S%d successfully", i2s_obj->id); } if ((tx_handle != NULL) && (rx_handle != NULL)) { @@ -629,13 +806,13 @@ esp_err_t i2s_new_channel(const i2s_chan_config_t *chan_cfg, i2s_chan_handle_t * } return ESP_OK; -/* i2s_obj allocated but register channel failed */ + /* i2s_obj allocated but register channel failed */ err: /* if the controller object has no channel, find the corresponding global object and destroy it */ if (i2s_obj != NULL && i2s_obj->rx_chan == NULL && i2s_obj->tx_chan == NULL) { - for (int i = 0; i < I2S_NUM_MAX; i++) { - if (i2s_obj == s_i2s.controller[i]) { - i2s_destroy_controller_obj(&s_i2s.controller[i]); + for (int i = 0; i < SOC_I2S_NUM; i++) { + if (i2s_obj == g_i2s.controller[i]) { + i2s_destroy_controller_obj(&g_i2s.controller[i]); break; } } @@ -643,31 +820,20 @@ err: return ret; } -// TODO: finish delete channel esp_err_t i2s_del_channel(i2s_chan_handle_t handle) { I2S_NULL_POINTER_CHECK(TAG, handle); - /* Static mutex to avoid double delete */ - static SemaphoreHandle_t del_mut = NULL; - if (del_mut == NULL) { - del_mut = xSemaphoreCreateMutex(); - } - i2s_controller_t *i2s_obj = handle->parent; - int id = i2s_obj->id; - i2s_dir_t dir = handle->dir; + ESP_RETURN_ON_FALSE(handle->state < I2S_CHAN_STATE_RUNNING, ESP_ERR_INVALID_STATE, TAG, "the channel can't be deleted unless it is disabled"); + i2s_controller_t *i2s_obj = handle->controller; + int __attribute__((unused)) id = i2s_obj->id; + i2s_dir_t __attribute__((unused)) dir = handle->dir; bool is_bound = true; - xSemaphoreTake(del_mut, portMAX_DELAY); - /* Stop the channel first */ - if (handle->state > I2S_CHAN_STATE_READY) { - i2s_abort_reading_writing(handle); - i2s_stop_channel(handle); - } #if SOC_I2S_HW_VERSION_2 if (dir == I2S_DIR_TX) { - i2s_ll_tx_disable_clock(handle->parent->hal.dev); + i2s_ll_tx_disable_clock(handle->controller->hal.dev); } else { - i2s_ll_rx_disable_clock(handle->parent->hal.dev); + i2s_ll_rx_disable_clock(handle->controller->hal.dev); } #endif #if SOC_I2S_SUPPORTS_APLL @@ -676,12 +842,17 @@ esp_err_t i2s_del_channel(i2s_chan_handle_t handle) * because the clock of some registers are bound to APLL, * otherwise, once APLL is disabled, the registers can't be updated anymore */ if (handle->dir == I2S_DIR_TX) { - i2s_ll_tx_clk_set_src(handle->parent->hal.dev, I2S_CLK_PLL_160M); + i2s_ll_tx_clk_set_src(handle->controller->hal.dev, I2S_CLK_SRC_DEFAULT); } else { - i2s_ll_rx_clk_set_src(handle->parent->hal.dev, I2S_CLK_PLL_160M); + i2s_ll_rx_clk_set_src(handle->controller->hal.dev, I2S_CLK_SRC_DEFAULT); } periph_rtc_apll_release(); } +#endif +#if CONFIG_PM_ENABLE + if (handle->pm_lock) { + esp_pm_lock_delete(handle->pm_lock); + } #endif if (handle->mode_info) { free(handle->mode_info); @@ -689,25 +860,41 @@ esp_err_t i2s_del_channel(i2s_chan_handle_t handle) if (handle->dma.desc) { i2s_free_dma_desc(handle); } +#if CONFIG_I2S_ISR_IRAM_SAFE + if (handle->msg_que_storage) { + free(handle->msg_que_storage); + } + if (handle->msg_que_struct) { + free(handle->msg_que_struct); + } + if (handle->mutex) { + free(handle->mutex_struct); + } + if (handle->binary_struct) { + free(handle->binary_struct); + } +#endif if (handle->msg_queue) { vQueueDelete(handle->msg_queue); } - if (handle->event_queue) { - vQueueDelete(handle->event_queue); - } if (handle->mutex) { vSemaphoreDelete(handle->mutex); } + if (handle->binary) { + vSemaphoreDelete(handle->binary); + } #if SOC_I2S_HW_VERSION_1 i2s_obj->chan_occupancy = 0; #else i2s_obj->chan_occupancy &= ~(uint32_t)dir; #endif -#if SOC_GDMA_SUPPORTED if (handle->dma.dma_chan) { +#if SOC_GDMA_SUPPORTED gdma_del_channel(handle->dma.dma_chan); - } +#else + esp_intr_free(handle->dma.dma_chan); #endif + } if (handle == i2s_obj->tx_chan) { free(i2s_obj->tx_chan); i2s_obj->tx_chan = NULL; @@ -726,48 +913,73 @@ esp_err_t i2s_del_channel(i2s_chan_handle_t handle) we need to destroy this controller object if there is no channel any more */ if (is_bound) { if (!(i2s_obj->tx_chan) && !(i2s_obj->rx_chan)) { - i2s_destroy_controller_obj(&s_i2s.controller[i2s_obj->id]); + i2s_destroy_controller_obj(&g_i2s.controller[i2s_obj->id]); } - ESP_LOGI(TAG, "%s channel on I2S%d deleted", dir == I2S_DIR_TX ? "tx" : "rx", id); + ESP_LOGD(TAG, "%s channel on I2S%d deleted", dir == I2S_DIR_TX ? "tx" : "rx", id); } - xSemaphoreGive(del_mut); + return ESP_OK; } -QueueHandle_t i2s_get_event_queue(i2s_chan_handle_t handle, uint32_t que_len) +esp_err_t i2s_channel_get_info(i2s_chan_handle_t handle, i2s_chan_info_t *chan_info) { - QueueHandle_t que; - if (!handle) { - return NULL; + I2S_NULL_POINTER_CHECK(TAG, handle); + I2S_NULL_POINTER_CHECK(TAG, chan_info); + + /* Find whether the handle is a registered i2s handle or still available */ + for (int i = 0; i < SOC_I2S_NUM; i++) { + if (g_i2s.controller[i] != NULL) { + if (g_i2s.controller[i]->tx_chan == handle || + g_i2s.controller[i]->rx_chan == handle) { + goto found; + } + } } + return ESP_ERR_NOT_FOUND; +found: + /* Assign the handle information */ xSemaphoreTake(handle->mutex, portMAX_DELAY); - if (handle->event_queue) { - que = handle->event_queue; + chan_info->id = handle->controller->id; + chan_info->dir = handle->dir; + chan_info->role = handle->role; + chan_info->mode = handle->mode; + if (handle->controller->full_duplex) { + if (handle->dir == I2S_DIR_TX) { + chan_info->pair_chan = handle->controller->rx_chan; + } else { + chan_info->pair_chan = handle->controller->tx_chan; + } } else { - handle->event_queue = xQueueCreate(que_len, sizeof(int *)); - que = handle->event_queue; + chan_info->pair_chan = NULL; } xSemaphoreGive(handle->mutex); - return que; + + return ESP_OK; } -esp_err_t i2s_start_channel(i2s_chan_handle_t handle) +esp_err_t i2s_channel_enable(i2s_chan_handle_t handle) { I2S_NULL_POINTER_CHECK(TAG, handle); esp_err_t ret = ESP_OK; xSemaphoreTake(handle->mutex, portMAX_DELAY); - ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "the channel has already started or not initialized"); - + ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "the channel has already enabled or not initialized"); +#if CONFIG_PM_ENABLE + esp_pm_lock_acquire(handle->pm_lock); +#endif handle->dma.curr_ptr = NULL; handle->dma.rw_pos = 0; handle->start(handle); - handle->state = I2S_CHAN_STATE_IDLE; + handle->state = I2S_CHAN_STATE_RUNNING; + /* Reset queue */ + xQueueReset(handle->msg_queue); xSemaphoreGive(handle->mutex); + /* Give the binary semaphore to enable reading / writing task */ + xSemaphoreGive(handle->binary); - ESP_LOGI(TAG, "i2s %s channel started", handle->dir == I2S_DIR_TX ? "tx" : "rx"); + ESP_LOGD(TAG, "i2s %s channel enabled", handle->dir == I2S_DIR_TX ? "tx" : "rx"); return ret; err: @@ -775,17 +987,23 @@ err: return ret; } -esp_err_t i2s_stop_channel(i2s_chan_handle_t handle) +esp_err_t i2s_channel_disable(i2s_chan_handle_t handle) { I2S_NULL_POINTER_CHECK(TAG, handle); esp_err_t ret = ESP_OK; xSemaphoreTake(handle->mutex, portMAX_DELAY); - ESP_GOTO_ON_FALSE(handle->state > I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "the channel has not started yet"); - handle->stop(handle); + ESP_GOTO_ON_FALSE(handle->state > I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "the channel has not been enabled yet"); + /* Update the state to force quit the current reading/wrinting operation */ handle->state = I2S_CHAN_STATE_READY; + /* Waiting for reading/wrinting operation quit */ + xSemaphoreTake(handle->binary, portMAX_DELAY); + handle->stop(handle); +#if CONFIG_PM_ENABLE + esp_pm_lock_release(handle->pm_lock); +#endif xSemaphoreGive(handle->mutex); - ESP_LOGI(TAG, "i2s %s channel stopped", handle->dir == I2S_DIR_TX ? "tx" : "rx"); + ESP_LOGD(TAG, "i2s %s channel disabled", handle->dir == I2S_DIR_TX ? "tx" : "rx"); return ret; err: @@ -793,33 +1011,28 @@ err: return ret; } -esp_err_t i2s_write_channel(i2s_chan_handle_t handle, const void *src, size_t size, size_t *bytes_written, TickType_t ticks_to_wait) +esp_err_t i2s_channel_write(i2s_chan_handle_t handle, const void *src, size_t size, size_t *bytes_written, uint32_t timeout_ms) { I2S_NULL_POINTER_CHECK(TAG, handle); ESP_RETURN_ON_FALSE(handle->dir == I2S_DIR_TX, ESP_ERR_INVALID_ARG, TAG, "this channel is not tx channel"); esp_err_t ret = ESP_OK; - char *data_ptr, *src_byte; + char *data_ptr; + char *src_byte; size_t bytes_can_write; *bytes_written = 0; - /* Take the semaphore brefore changing state to ensure only one writing thread running at the same time */ - xSemaphoreTake(handle->mutex, ticks_to_wait); -#ifdef CONFIG_PM_ENABLE - esp_pm_lock_acquire(handle->pm_lock); -#endif - ESP_GOTO_ON_FALSE(handle->state > I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "this channel has not started yet"); - handle->state = I2S_CHAN_STATE_WRITING; + /* The binary semaphore can only be taken when the channel has been enabled and no other writing operation in progress */ + ESP_RETURN_ON_FALSE(xSemaphoreTake(handle->binary, pdMS_TO_TICKS(timeout_ms)) == pdTRUE, ESP_ERR_INVALID_STATE, TAG, "The channel is not enabled"); src_byte = (char *)src; - while (size > 0 && handle->state == I2S_CHAN_STATE_WRITING) { + while (size > 0 && handle->state == I2S_CHAN_STATE_RUNNING) { if (handle->dma.rw_pos == handle->dma.buf_size || handle->dma.curr_ptr == NULL) { - if (xQueueReceive(handle->msg_queue, &(handle->dma.curr_ptr), ticks_to_wait) == pdFALSE) { + if (xQueueReceive(handle->msg_queue, &(handle->dma.curr_ptr), pdMS_TO_TICKS(timeout_ms)) == pdFALSE) { ret = ESP_ERR_TIMEOUT; break; } handle->dma.rw_pos = 0; } - ESP_LOGD(TAG, "size: %d, rw_pos: %d, buf_size: %d, curr_ptr: %d", size, handle->dma.rw_pos, handle->dma.buf_size, (int)handle->dma.curr_ptr); data_ptr = (char *)handle->dma.curr_ptr; data_ptr += handle->dma.rw_pos; bytes_can_write = handle->dma.buf_size - handle->dma.rw_pos; @@ -832,39 +1045,27 @@ esp_err_t i2s_write_channel(i2s_chan_handle_t handle, const void *src, size_t si handle->dma.rw_pos += bytes_can_write; (*bytes_written) += bytes_can_write; } - /* Need to judge the state before switch back to idle, in case the state has been changed by 'stop' or 'abort' */ - if (handle->state == I2S_CHAN_STATE_WRITING) { - handle->state = I2S_CHAN_STATE_IDLE; - } -err: -#ifdef CONFIG_PM_ENABLE - esp_pm_lock_release(handle->pm_lock); -#endif - xSemaphoreGive(handle->mutex); + xSemaphoreGive(handle->binary); return ret; } -esp_err_t i2s_read_channel(i2s_chan_handle_t handle, void *dest, size_t size, size_t *bytes_read, TickType_t ticks_to_wait) +esp_err_t i2s_channel_read(i2s_chan_handle_t handle, void *dest, size_t size, size_t *bytes_read, uint32_t timeout_ms) { I2S_NULL_POINTER_CHECK(TAG, handle); ESP_RETURN_ON_FALSE(handle->dir == I2S_DIR_RX, ESP_ERR_INVALID_ARG, TAG, "this channel is not rx channel"); esp_err_t ret = ESP_OK; - uint8_t *data_ptr, *dest_byte; + uint8_t *data_ptr; + uint8_t *dest_byte; int bytes_can_read; *bytes_read = 0; dest_byte = (uint8_t *)dest; - /* Take the semaphore brefore changing state to ensure only one reading thread running at the same time */ - xSemaphoreTake(handle->mutex, ticks_to_wait); -#ifdef CONFIG_PM_ENABLE - esp_pm_lock_acquire(handle->pm_lock); -#endif - ESP_GOTO_ON_FALSE(handle->state > I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "this channel has not started yet"); - handle->state = I2S_CHAN_STATE_READING; - while (size > 0 && handle->state == I2S_CHAN_STATE_READING) { + /* The binary semaphore can only be taken when the channel has been enabled and no other reading operation in progress */ + ESP_RETURN_ON_FALSE(xSemaphoreTake(handle->binary, pdMS_TO_TICKS(timeout_ms)) == pdTRUE, ESP_ERR_INVALID_STATE, TAG, "The channel is not enabled"); + while (size > 0 && handle->state == I2S_CHAN_STATE_RUNNING) { if (handle->dma.rw_pos == handle->dma.buf_size || handle->dma.curr_ptr == NULL) { - if (xQueueReceive(handle->msg_queue, &(handle->dma.curr_ptr), ticks_to_wait) == pdFALSE) { + if (xQueueReceive(handle->msg_queue, &(handle->dma.curr_ptr), pdMS_TO_TICKS(timeout_ms)) == pdFALSE) { ret = ESP_ERR_TIMEOUT; break; } @@ -882,41 +1083,11 @@ esp_err_t i2s_read_channel(i2s_chan_handle_t handle, void *dest, size_t size, si handle->dma.rw_pos += bytes_can_read; (*bytes_read) += bytes_can_read; } - /* Need to judge the state before switch back to idle, in case the state has been changed by 'stop' or 'abort' */ - if (handle->state == I2S_CHAN_STATE_READING) { - handle->state = I2S_CHAN_STATE_IDLE; - } -err: -#ifdef CONFIG_PM_ENABLE - esp_pm_lock_release(handle->pm_lock); -#endif - xSemaphoreGive(handle->mutex); + xSemaphoreGive(handle->binary); return ret; } -esp_err_t i2s_clear_dma_buffer(i2s_chan_handle_t handle) -{ - I2S_NULL_POINTER_CHECK(TAG, handle); - ESP_RETURN_ON_FALSE(handle->state >= I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, TAG, "this channel has not initialized yet"); - /* Clear all the DMA buffer */ - for (int desc_num = handle->dma.desc_num; desc_num > 0; desc_num--) { - memset(handle->dma.bufs[desc_num-1], 0, handle->dma.buf_size); - } - return ESP_OK; -} - -esp_err_t i2s_abort_reading_writing(i2s_chan_handle_t handle) -{ - I2S_NULL_POINTER_CHECK(TAG, handle); - ESP_RETURN_ON_FALSE(handle->state > I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, TAG, "this channel has not started yet"); - /* No lock here. Force change state to idle when writing or reading */ - handle->state = I2S_CHAN_STATE_IDLE; - - return ESP_OK; -} - - /*--------------------------------------------------------------------------- I2S Platform APIs ---------------------------------------------------------------------------- @@ -927,18 +1098,18 @@ esp_err_t i2s_platform_acquire_occupation(int id, const char *comp_name) { esp_err_t ret = ESP_OK; const char *occupied_comp = NULL; - ESP_RETURN_ON_FALSE(id < I2S_NUM_MAX, ESP_ERR_INVALID_ARG, TAG, "invalid i2s port id"); - portENTER_CRITICAL(&s_i2s.spinlock); - if ((!s_i2s.controller[id]) && (s_i2s.comp_name[id] == NULL)) { - s_i2s.comp_name[id] = comp_name; + ESP_RETURN_ON_FALSE(id < SOC_I2S_NUM, ESP_ERR_INVALID_ARG, TAG, "invalid i2s port id"); + portENTER_CRITICAL(&g_i2s.spinlock); + if ((!g_i2s.controller[id]) && (g_i2s.comp_name[id] == NULL)) { + g_i2s.comp_name[id] = comp_name; /* Enable module clock */ periph_module_enable(i2s_periph_signal[id].module); i2s_ll_enable_clock(I2S_LL_GET_HW(id)); } else { - occupied_comp = s_i2s.comp_name[id]; + occupied_comp = g_i2s.comp_name[id]; ret = ESP_ERR_NOT_FOUND; } - portEXIT_CRITICAL(&s_i2s.spinlock); + portEXIT_CRITICAL(&g_i2s.spinlock); if (occupied_comp != NULL) { ESP_LOGE(TAG, "i2s controller %d has been occupied by %s", id, occupied_comp); } @@ -948,16 +1119,24 @@ esp_err_t i2s_platform_acquire_occupation(int id, const char *comp_name) esp_err_t i2s_platform_release_occupation(int id) { esp_err_t ret = ESP_OK; - ESP_RETURN_ON_FALSE(id < I2S_NUM_MAX, ESP_ERR_INVALID_ARG, TAG, "invalid i2s port id"); - portENTER_CRITICAL(&s_i2s.spinlock); - if ((!s_i2s.controller[id])) { - s_i2s.comp_name[id] = NULL; + ESP_RETURN_ON_FALSE(id < SOC_I2S_NUM, ESP_ERR_INVALID_ARG, TAG, "invalid i2s port id"); + portENTER_CRITICAL(&g_i2s.spinlock); + if (!g_i2s.controller[id]) { + g_i2s.comp_name[id] = NULL; /* Disable module clock */ periph_module_disable(i2s_periph_signal[id].module); i2s_ll_disable_clock(I2S_LL_GET_HW(id)); } else { ret = ESP_ERR_INVALID_STATE; } - portEXIT_CRITICAL(&s_i2s.spinlock); + portEXIT_CRITICAL(&g_i2s.spinlock); return ret; } + +// Only used in `test_i2s_iram.c` to write DMA buffer directly +size_t inline i2s_platform_get_dma_buffer_offset(void) +{ + /* Force to transfer address '0' into 'i2s_chan_handle_t' type, + * then find the corresponding field , the address of this field is the offset of this type */ + return (size_t)&(((i2s_chan_handle_t)0)->dma.bufs); +} diff --git a/components/driver/i2s/i2s_pdm.c b/components/driver/i2s/i2s_pdm.c index 4c1b8aebcb..500f822ed0 100644 --- a/components/driver/i2s/i2s_pdm.c +++ b/components/driver/i2s/i2s_pdm.c @@ -4,8 +4,17 @@ * SPDX-License-Identifier: Apache-2.0 */ #include + #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" +#include "sdkconfig.h" + +#if CONFIG_I2S_ENABLE_DEBUG_LOG +// The local log level must be defined before including esp_log.h +// Set the maximum log level for this source file +#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG +#endif + #include "hal/i2s_hal.h" #include "driver/gpio.h" #include "driver/i2s_pdm.h" @@ -14,7 +23,7 @@ #include "esp_intr_alloc.h" #include "esp_check.h" -static const char *TAG = "I2S_PDM"; +static const char *TAG = "i2s_pdm"; /*--------------------------------------------------------------- PDM TX @@ -30,7 +39,7 @@ static esp_err_t i2s_pdm_tx_calculate_clock(i2s_chan_handle_t handle, const i2s_ clk_info->bclk_div = 8; clk_info->mclk = clk_info->bclk * clk_info->bclk_div; #if SOC_I2S_SUPPORTS_APLL - clk_info->sclk = clk_cfg->clk_src == I2S_CLK_PLL_160M ? I2S_LL_BASE_CLK : i2s_set_get_apll_freq(clk_info->mclk); + clk_info->sclk = (clk_cfg->clk_src == I2S_CLK_SRC_APLL) ? i2s_set_get_apll_freq(clk_info->mclk) : I2S_LL_BASE_CLK; #else clk_info->sclk = I2S_LL_BASE_CLK; #endif @@ -39,7 +48,7 @@ static esp_err_t i2s_pdm_tx_calculate_clock(i2s_chan_handle_t handle, const i2s_ /* Check if the configuration is correct */ ESP_RETURN_ON_FALSE(clk_info->mclk_div, ESP_ERR_INVALID_ARG, TAG, "sample rate is too large"); /* Set upsampling configuration */ - i2s_ll_tx_set_pdm_fpfs(handle->parent->hal.dev, pdm_tx_clk->up_sample_fp, pdm_tx_clk->up_sample_fs); + i2s_ll_tx_set_pdm_fpfs(handle->controller->hal.dev, pdm_tx_clk->up_sample_fp, pdm_tx_clk->up_sample_fs); return ESP_OK; } @@ -49,33 +58,16 @@ static esp_err_t i2s_pdm_tx_set_clock(i2s_chan_handle_t handle, const i2s_pdm_tx esp_err_t ret = ESP_OK; i2s_pdm_tx_config_t *pdm_tx_cfg = (i2s_pdm_tx_config_t *)(handle->mode_info); - /* If Power Management enabled, a PM lock will be created when there is no PM lock or clock source changed */ -#ifdef CONFIG_PM_ENABLE - // Create/Re-create power management lock - if (handle->pm_lock == NULL || pdm_tx_cfg->clk_cfg.clk_src != clk_cfg->clk_src) { - if (handle->pm_lock) { - ESP_RETURN_ON_ERROR(esp_pm_lock_delete(handle->pm_lock), TAG, "I2S delete old pm lock failed"); - } - esp_pm_lock_type_t pm_type = ESP_PM_APB_FREQ_MAX; -#if SOC_I2S_SUPPORTS_APLL - if (clk_cfg->clk_src == I2S_CLK_APLL) { - pm_type = ESP_PM_NO_LIGHT_SLEEP; - } -#endif // SOC_I2S_SUPPORTS_APLL - ESP_RETURN_ON_ERROR(esp_pm_lock_create(pm_type, 0, "i2s_driver", &handle->pm_lock), err, TAG, "I2S pm lock create failed"); - } -#endif //CONFIG_PM_ENABLE - i2s_hal_clock_info_t clk_info; /* Calculate clock parameters */ ESP_RETURN_ON_ERROR(i2s_pdm_tx_calculate_clock(handle, clk_cfg, &clk_info), TAG, "clock calculate failed"); ESP_LOGD(TAG, "Clock division info: [sclk] %d Hz [mdiv] %d [mclk] %d Hz [bdiv] %d [bclk] %d Hz", - clk_info.sclk, clk_info.mclk_div, clk_info.mclk, clk_info.bclk_div, clk_info.bclk); + clk_info.sclk, clk_info.mclk_div, clk_info.mclk, clk_info.bclk_div, clk_info.bclk); - portENTER_CRITICAL(&s_i2s.spinlock); + portENTER_CRITICAL(&g_i2s.spinlock); /* Set clock configurations in HAL*/ - i2s_hal_set_tx_clock(&handle->parent->hal, &clk_info, clk_cfg->clk_src); - portEXIT_CRITICAL(&s_i2s.spinlock); + i2s_hal_set_tx_clock(&handle->controller->hal, &clk_info, clk_cfg->clk_src); + portEXIT_CRITICAL(&g_i2s.spinlock); /* Update the mode info: clock configuration */ memcpy(&(pdm_tx_cfg->clk_cfg), clk_cfg, sizeof(i2s_pdm_tx_clk_config_t)); @@ -98,13 +90,13 @@ static esp_err_t i2s_pdm_tx_set_slot(i2s_chan_handle_t handle, const i2s_pdm_tx_ TAG, "allocate memory for dma descriptor failed"); } /* Share bck and ws signal in full-duplex mode */ - i2s_ll_share_bck_ws(handle->parent->hal.dev, handle->parent->full_duplex); + i2s_ll_share_bck_ws(handle->controller->hal.dev, handle->controller->full_duplex); - portENTER_CRITICAL(&s_i2s.spinlock); + portENTER_CRITICAL(&g_i2s.spinlock); /* Configure the hardware to apply PDM format */ bool is_slave = handle->role == I2S_ROLE_SLAVE; - i2s_hal_pdm_set_tx_slot(&(handle->parent->hal), is_slave, (i2s_hal_slot_config_t*)slot_cfg); - portEXIT_CRITICAL(&s_i2s.spinlock); + i2s_hal_pdm_set_tx_slot(&(handle->controller->hal), is_slave, (i2s_hal_slot_config_t *)slot_cfg); + portEXIT_CRITICAL(&g_i2s.spinlock); /* Update the mode info: slot configuration */ i2s_pdm_tx_config_t *pdm_tx_cfg = (i2s_pdm_tx_config_t *)handle->mode_info; @@ -115,7 +107,7 @@ static esp_err_t i2s_pdm_tx_set_slot(i2s_chan_handle_t handle, const i2s_pdm_tx_ static esp_err_t i2s_pdm_tx_set_gpio(i2s_chan_handle_t handle, const i2s_pdm_tx_gpio_config_t *gpio_cfg) { - int id = handle->parent->id; + int id = handle->controller->id; /* Check validity of selected pins */ ESP_RETURN_ON_FALSE((gpio_cfg->clk == -1 || GPIO_IS_VALID_GPIO(gpio_cfg->clk)), @@ -123,21 +115,21 @@ static esp_err_t i2s_pdm_tx_set_gpio(i2s_chan_handle_t handle, const i2s_pdm_tx_ ESP_RETURN_ON_FALSE((gpio_cfg->dout == -1 || GPIO_IS_VALID_GPIO(gpio_cfg->dout)), ESP_ERR_INVALID_ARG, TAG, "dout gpio is invalid"); /* Set data output GPIO */ - i2s_gpio_check_and_set(gpio_cfg->dout, i2s_periph_signal[id].data_out_sig, false); + i2s_gpio_check_and_set(gpio_cfg->dout, i2s_periph_signal[id].data_out_sig, false, false); if (handle->role == I2S_ROLE_SLAVE) { /* For "tx + slave" mode, select TX signal index for ws and bck */ - if (!handle->parent->full_duplex) { - i2s_gpio_check_and_set(gpio_cfg->clk, i2s_periph_signal[id].s_tx_ws_sig, true); - /* For "tx + rx + slave" or "rx + slave" mode, select RX signal index for ws and bck */ + if (!handle->controller->full_duplex) { + i2s_gpio_check_and_set(gpio_cfg->clk, i2s_periph_signal[id].s_tx_ws_sig, true, gpio_cfg->invert_flags.clk_inv); + /* For "tx + rx + slave" or "rx + slave" mode, select RX signal index for ws and bck */ } else { - i2s_gpio_check_and_set(gpio_cfg->clk, i2s_periph_signal[id].s_rx_ws_sig, true); + i2s_gpio_check_and_set(gpio_cfg->clk, i2s_periph_signal[id].s_rx_ws_sig, true, gpio_cfg->invert_flags.clk_inv); } } else { - i2s_gpio_check_and_set(gpio_cfg->clk, i2s_periph_signal[id].m_tx_ws_sig, false); + i2s_gpio_check_and_set(gpio_cfg->clk, i2s_periph_signal[id].m_tx_ws_sig, false, gpio_cfg->invert_flags.clk_inv); } #if SOC_I2S_HW_VERSION_2 - i2s_ll_mclk_bind_to_tx_clk(handle->parent->hal.dev); + i2s_ll_mclk_bind_to_tx_clk(handle->controller->hal.dev); #endif /* Update the mode info: gpio configuration */ i2s_pdm_tx_config_t *pdm_tx_cfg = (i2s_pdm_tx_config_t *)handle->mode_info; @@ -146,11 +138,14 @@ static esp_err_t i2s_pdm_tx_set_gpio(i2s_chan_handle_t handle, const i2s_pdm_tx_ return ESP_OK; } -esp_err_t i2s_init_pdm_tx_channel(i2s_chan_handle_t handle, const i2s_pdm_tx_config_t *pdm_tx_cfg) +esp_err_t i2s_channel_init_pdm_tx_mode(i2s_chan_handle_t handle, const i2s_pdm_tx_config_t *pdm_tx_cfg) { +#if CONFIG_I2S_ENABLE_DEBUG_LOG + esp_log_level_set(TAG, ESP_LOG_DEBUG); +#endif I2S_NULL_POINTER_CHECK(TAG, handle); ESP_RETURN_ON_FALSE(handle->dir == I2S_DIR_TX, ESP_ERR_INVALID_ARG, TAG, "This channel handle is not a TX handle"); - ESP_RETURN_ON_FALSE(handle->parent->id == I2S_NUM_0, ESP_ERR_INVALID_ARG, TAG, "This channel handle is registered on I2S1, but PDM is only supported on I2S0"); + ESP_RETURN_ON_FALSE(handle->controller->id == I2S_NUM_0, ESP_ERR_INVALID_ARG, TAG, "This channel handle is registered on I2S1, but PDM is only supported on I2S0"); esp_err_t ret = ESP_OK; @@ -164,11 +159,11 @@ esp_err_t i2s_init_pdm_tx_channel(i2s_chan_handle_t handle, const i2s_pdm_tx_con handle->mode_info = calloc(1, sizeof(i2s_pdm_tx_config_t)); ESP_GOTO_ON_FALSE(handle->mode_info, ESP_ERR_NO_MEM, err, TAG, "no memory for storing the configurations"); ESP_GOTO_ON_ERROR(i2s_pdm_tx_set_gpio(handle, &pdm_tx_cfg->gpio_cfg), err, TAG, "initialize channel failed while setting gpio pins"); - /* i2s_set_slot should be called before i2s_set_clock while initializing, because clock is relay on the slot */ + /* i2s_set_pdm_tx_slot should be called before i2s_set_pdm_tx_clock while initializing, because clock is relay on the slot */ ESP_GOTO_ON_ERROR(i2s_pdm_tx_set_slot(handle, &pdm_tx_cfg->slot_cfg), err, TAG, "initialize channel failed while setting slot"); #if SOC_I2S_SUPPORTS_APLL /* Enable APLL and acquire its lock when the clock source is APLL */ - if (pdm_tx_cfg->clk_cfg.clk_src == I2S_CLK_APLL) { + if (pdm_tx_cfg->clk_cfg.clk_src == I2S_CLK_SRC_APLL) { periph_rtc_apll_acquire(); handle->apll_en = true; } @@ -176,10 +171,19 @@ esp_err_t i2s_init_pdm_tx_channel(i2s_chan_handle_t handle, const i2s_pdm_tx_con ESP_GOTO_ON_ERROR(i2s_pdm_tx_set_clock(handle, &pdm_tx_cfg->clk_cfg), err, TAG, "initialize channel failed while setting clock"); ESP_GOTO_ON_ERROR(i2s_init_dma_intr(handle, ESP_INTR_FLAG_LEVEL1), err, TAG, "initialize dma interrupt failed"); - i2s_ll_tx_enable_pdm(handle->parent->hal.dev); + i2s_ll_tx_enable_pdm(handle->controller->hal.dev); #if SOC_I2S_HW_VERSION_2 /* Enable clock to start outputting mclk signal. Some codecs will reset once mclk stop */ - i2s_ll_tx_enable_clock(handle->parent->hal.dev); + i2s_ll_tx_enable_clock(handle->controller->hal.dev); +#endif +#ifdef CONFIG_PM_ENABLE + esp_pm_lock_type_t pm_type = ESP_PM_APB_FREQ_MAX; +#if SOC_I2S_SUPPORTS_APLL + if (pdm_tx_cfg->clk_cfg.clk_src == I2S_CLK_SRC_APLL) { + pm_type = ESP_PM_NO_LIGHT_SLEEP; + } +#endif // SOC_I2S_SUPPORTS_APLL + ESP_RETURN_ON_ERROR(esp_pm_lock_create(pm_type, 0, "i2s_driver", &handle->pm_lock), TAG, "I2S pm lock create failed"); #endif /* Initialization finished, mark state as ready */ @@ -192,7 +196,7 @@ err: return ret; } -esp_err_t i2s_reconfig_pdm_tx_clock(i2s_chan_handle_t handle, const i2s_pdm_tx_clk_config_t *clk_cfg) +esp_err_t i2s_channel_reconfig_pdm_tx_clock(i2s_chan_handle_t handle, const i2s_pdm_tx_clk_config_t *clk_cfg) { I2S_NULL_POINTER_CHECK(TAG, handle); I2S_NULL_POINTER_CHECK(TAG, clk_cfg); @@ -202,24 +206,37 @@ esp_err_t i2s_reconfig_pdm_tx_clock(i2s_chan_handle_t handle, const i2s_pdm_tx_c xSemaphoreTake(handle->mutex, portMAX_DELAY); ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_PDM, ESP_ERR_INVALID_ARG, err, TAG, "this handle is not working in standard moded"); - ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "invalid state, I2S should be stopped before reconfiguring the clock"); + ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "invalid state, I2S should be disabled before reconfiguring the clock"); + i2s_pdm_tx_config_t *pdm_tx_cfg = (i2s_pdm_tx_config_t *)handle->mode_info; + ESP_GOTO_ON_FALSE(pdm_tx_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); #if SOC_I2S_SUPPORTS_APLL - i2s_pdm_tx_config_t *pdm_tx_cfg = (i2s_pdm_tx_config_t*)handle->mode_info; - ESP_GOTO_ON_FALSE(pdm_tx_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); /* Enable APLL and acquire its lock when the clock source is changed to APLL */ - if (clk_cfg->clk_src == I2S_CLK_APLL && pdm_tx_cfg->clk_cfg.clk_src == I2S_CLK_PLL_160M) { + if (clk_cfg->clk_src == I2S_CLK_SRC_APLL && pdm_tx_cfg->clk_cfg.clk_src != I2S_CLK_SRC_APLL) { periph_rtc_apll_acquire(); handle->apll_en = true; } /* Disable APLL and release its lock when clock source is changed to 160M_PLL */ - if (clk_cfg->clk_src == I2S_CLK_PLL_160M && pdm_tx_cfg->clk_cfg.clk_src == I2S_CLK_APLL) { + if (clk_cfg->clk_src != I2S_CLK_SRC_APLL && pdm_tx_cfg->clk_cfg.clk_src == I2S_CLK_SRC_APLL) { periph_rtc_apll_release(); handle->apll_en = false; } #endif ESP_GOTO_ON_ERROR(i2s_pdm_tx_set_clock(handle, clk_cfg), err, TAG, "update clock failed"); +#ifdef CONFIG_PM_ENABLE + // Create/Re-create power management lock + if (pdm_tx_cfg->clk_cfg.clk_src != clk_cfg->clk_src) { + ESP_GOTO_ON_ERROR(esp_pm_lock_delete(handle->pm_lock), err, TAG, "I2S delete old pm lock failed"); + esp_pm_lock_type_t pm_type = ESP_PM_APB_FREQ_MAX; +#if SOC_I2S_SUPPORTS_APLL + if (clk_cfg->clk_src == I2S_CLK_SRC_APLL) { + pm_type = ESP_PM_NO_LIGHT_SLEEP; + } +#endif // SOC_I2S_SUPPORTS_APLL + ESP_GOTO_ON_ERROR(esp_pm_lock_create(pm_type, 0, "i2s_driver", &handle->pm_lock), err, TAG, "I2S pm lock create failed"); + } +#endif //CONFIG_PM_ENABLE xSemaphoreGive(handle->mutex); @@ -229,7 +246,7 @@ err: return ret; } -esp_err_t i2s_reconfig_pdm_tx_slot(i2s_chan_handle_t handle, const i2s_pdm_tx_slot_config_t *slot_cfg) +esp_err_t i2s_channel_reconfig_pdm_tx_slot(i2s_chan_handle_t handle, const i2s_pdm_tx_slot_config_t *slot_cfg) { I2S_NULL_POINTER_CHECK(TAG, handle); I2S_NULL_POINTER_CHECK(TAG, slot_cfg); @@ -239,9 +256,9 @@ esp_err_t i2s_reconfig_pdm_tx_slot(i2s_chan_handle_t handle, const i2s_pdm_tx_sl xSemaphoreTake(handle->mutex, portMAX_DELAY); ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_PDM, ESP_ERR_INVALID_ARG, err, TAG, "this handle is not working in standard moded"); - ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "invalid state, I2S should be stopped before reconfiguring the slot"); + ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "invalid state, I2S should be disabled before reconfiguring the slot"); - i2s_pdm_tx_config_t *pdm_tx_cfg = (i2s_pdm_tx_config_t*)handle->mode_info; + i2s_pdm_tx_config_t *pdm_tx_cfg = (i2s_pdm_tx_config_t *)handle->mode_info; ESP_GOTO_ON_FALSE(pdm_tx_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); ESP_GOTO_ON_ERROR(i2s_pdm_tx_set_slot(handle, slot_cfg), err, TAG, "set i2s standard slot failed"); @@ -260,7 +277,7 @@ err: return ret; } -esp_err_t i2s_reconfig_pdm_tx_gpio(i2s_chan_handle_t handle, const i2s_pdm_tx_gpio_config_t *gpio_cfg) +esp_err_t i2s_channel_reconfig_pdm_tx_gpio(i2s_chan_handle_t handle, const i2s_pdm_tx_gpio_config_t *gpio_cfg) { I2S_NULL_POINTER_CHECK(TAG, handle); I2S_NULL_POINTER_CHECK(TAG, gpio_cfg); @@ -270,7 +287,7 @@ esp_err_t i2s_reconfig_pdm_tx_gpio(i2s_chan_handle_t handle, const i2s_pdm_tx_gp xSemaphoreTake(handle->mutex, portMAX_DELAY); ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_PDM, ESP_ERR_INVALID_ARG, err, TAG, "This handle is not working in standard moded"); - ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "Invalid state, I2S should be stopped before reconfiguring the gpio"); + ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "Invalid state, I2S should be disabled before reconfiguring the gpio"); ESP_GOTO_ON_ERROR(i2s_pdm_tx_set_gpio(handle, gpio_cfg), err, TAG, "set i2s standard slot failed"); xSemaphoreGive(handle->mutex); @@ -298,7 +315,7 @@ static esp_err_t i2s_pdm_rx_calculate_clock(i2s_chan_handle_t handle, const i2s_ clk_info->bclk_div = 8; clk_info->mclk = clk_info->bclk * clk_info->bclk_div; #if SOC_I2S_SUPPORTS_APLL - clk_info->sclk = clk_cfg->clk_src == I2S_CLK_PLL_160M ? I2S_LL_BASE_CLK : i2s_set_get_apll_freq(clk_info->mclk); + clk_info->sclk = (clk_cfg->clk_src == I2S_CLK_SRC_APLL) ? i2s_set_get_apll_freq(clk_info->mclk) : I2S_LL_BASE_CLK; #else clk_info->sclk = I2S_LL_BASE_CLK; #endif @@ -307,7 +324,7 @@ static esp_err_t i2s_pdm_rx_calculate_clock(i2s_chan_handle_t handle, const i2s_ /* Check if the configuration is correct */ ESP_RETURN_ON_FALSE(clk_info->mclk_div, ESP_ERR_INVALID_ARG, TAG, "sample rate is too large"); /* Set down-sampling configuration */ - i2s_ll_rx_set_pdm_dsr(handle->parent->hal.dev, pdm_rx_clk->dn_sample_mode); + i2s_ll_rx_set_pdm_dsr(handle->controller->hal.dev, pdm_rx_clk->dn_sample_mode); return ESP_OK; } @@ -316,33 +333,16 @@ static esp_err_t i2s_pdm_rx_set_clock(i2s_chan_handle_t handle, const i2s_pdm_rx esp_err_t ret = ESP_OK; i2s_pdm_rx_config_t *pdm_rx_cfg = (i2s_pdm_rx_config_t *)(handle->mode_info); - /* If Power Management enabled, a PM lock will be created when there is no PM lock or clock source changed */ -#ifdef CONFIG_PM_ENABLE - // Create/Re-create power management lock - if (handle->pm_lock == NULL || pdm_rx_cfg->clk_cfg.clk_src != clk_cfg->clk_src) { - if (handle->pm_lock) { - ESP_RETURN_ON_ERROR(esp_pm_lock_delete(handle->pm_lock), TAG, "I2S delete old pm lock failed"); - } - esp_pm_lock_type_t pm_type = ESP_PM_APB_FREQ_MAX; -#if SOC_I2S_SUPPORTS_APLL - if (clk_cfg->clk_src == I2S_CLK_APLL) { - pm_type = ESP_PM_NO_LIGHT_SLEEP; - } -#endif // SOC_I2S_SUPPORTS_APLL - ESP_RETURN_ON_ERROR(esp_pm_lock_create(pm_type, 0, "i2s_driver", &handle->pm_lock), err, TAG, "I2S pm lock create failed"); - } -#endif //CONFIG_PM_ENABLE - i2s_hal_clock_info_t clk_info; /* Calculate clock parameters */ ESP_RETURN_ON_ERROR(i2s_pdm_rx_calculate_clock(handle, clk_cfg, &clk_info), TAG, "clock calculate failed"); ESP_LOGD(TAG, "Clock division info: [sclk] %d Hz [mdiv] %d [mclk] %d Hz [bdiv] %d [bclk] %d Hz", - clk_info.sclk, clk_info.mclk_div, clk_info.mclk, clk_info.bclk_div, clk_info.bclk); + clk_info.sclk, clk_info.mclk_div, clk_info.mclk, clk_info.bclk_div, clk_info.bclk); - portENTER_CRITICAL(&s_i2s.spinlock); + portENTER_CRITICAL(&g_i2s.spinlock); /* Set clock configurations in HAL*/ - i2s_hal_set_rx_clock(&handle->parent->hal, &clk_info, clk_cfg->clk_src); - portEXIT_CRITICAL(&s_i2s.spinlock); + i2s_hal_set_rx_clock(&handle->controller->hal, &clk_info, clk_cfg->clk_src); + portEXIT_CRITICAL(&g_i2s.spinlock); /* Update the mode info: clock configuration */ memcpy(&(pdm_rx_cfg->clk_cfg), clk_cfg, sizeof(i2s_pdm_rx_clk_config_t)); @@ -365,13 +365,13 @@ static esp_err_t i2s_pdm_rx_set_slot(i2s_chan_handle_t handle, const i2s_pdm_rx_ TAG, "allocate memory for dma descriptor failed"); } /* Share bck and ws signal in full-duplex mode */ - i2s_ll_share_bck_ws(handle->parent->hal.dev, handle->parent->full_duplex); + i2s_ll_share_bck_ws(handle->controller->hal.dev, handle->controller->full_duplex); - portENTER_CRITICAL(&s_i2s.spinlock); + portENTER_CRITICAL(&g_i2s.spinlock); /* Configure the hardware to apply PDM format */ - bool is_slave = (handle->role == I2S_ROLE_SLAVE) | handle->parent->full_duplex; - i2s_hal_pdm_set_rx_slot(&(handle->parent->hal), is_slave, (i2s_hal_slot_config_t*)slot_cfg); - portEXIT_CRITICAL(&s_i2s.spinlock); + bool is_slave = (handle->role == I2S_ROLE_SLAVE) | handle->controller->full_duplex; + i2s_hal_pdm_set_rx_slot(&(handle->controller->hal), is_slave, (i2s_hal_slot_config_t *)slot_cfg); + portEXIT_CRITICAL(&g_i2s.spinlock); /* Update the mode info: slot configuration */ i2s_pdm_rx_config_t *pdm_rx_cfg = (i2s_pdm_rx_config_t *)handle->mode_info; @@ -382,7 +382,7 @@ static esp_err_t i2s_pdm_rx_set_slot(i2s_chan_handle_t handle, const i2s_pdm_rx_ static esp_err_t i2s_pdm_rx_set_gpio(i2s_chan_handle_t handle, const i2s_pdm_rx_gpio_config_t *gpio_cfg) { - int id = handle->parent->id; + int id = handle->controller->id; /* Check validity of selected pins */ ESP_RETURN_ON_FALSE((gpio_cfg->clk == -1 || GPIO_IS_VALID_GPIO(gpio_cfg->clk)), @@ -390,20 +390,20 @@ static esp_err_t i2s_pdm_rx_set_gpio(i2s_chan_handle_t handle, const i2s_pdm_rx_ ESP_RETURN_ON_FALSE((gpio_cfg->din == -1 || GPIO_IS_VALID_GPIO(gpio_cfg->din)), ESP_ERR_INVALID_ARG, TAG, "dout gpio is invalid"); /* Set data input GPIO */ - i2s_gpio_check_and_set(gpio_cfg->din, i2s_periph_signal[id].data_in_sig, true); + i2s_gpio_check_and_set(gpio_cfg->din, i2s_periph_signal[id].data_in_sig, true, false); if (handle->role == I2S_ROLE_SLAVE) { /* For "tx + rx + slave" or "rx + slave" mode, select RX signal index for ws and bck */ - i2s_gpio_check_and_set(gpio_cfg->clk, i2s_periph_signal[id].s_rx_ws_sig, true); + i2s_gpio_check_and_set(gpio_cfg->clk, i2s_periph_signal[id].s_rx_ws_sig, true, gpio_cfg->invert_flags.clk_inv); } else { - if (!handle->parent->full_duplex) { - i2s_gpio_check_and_set(gpio_cfg->clk, i2s_periph_signal[id].m_rx_ws_sig, false); + if (!handle->controller->full_duplex) { + i2s_gpio_check_and_set(gpio_cfg->clk, i2s_periph_signal[id].m_rx_ws_sig, false, gpio_cfg->invert_flags.clk_inv); } else { - i2s_gpio_check_and_set(gpio_cfg->clk, i2s_periph_signal[id].m_tx_ws_sig, false); + i2s_gpio_check_and_set(gpio_cfg->clk, i2s_periph_signal[id].m_tx_ws_sig, false, gpio_cfg->invert_flags.clk_inv); } } #if SOC_I2S_HW_VERSION_2 - i2s_ll_mclk_bind_to_rx_clk(handle->parent->hal.dev); + i2s_ll_mclk_bind_to_rx_clk(handle->controller->hal.dev); #endif /* Update the mode info: gpio configuration */ i2s_pdm_rx_config_t *pdm_rx_cfg = (i2s_pdm_rx_config_t *)handle->mode_info; @@ -412,11 +412,11 @@ static esp_err_t i2s_pdm_rx_set_gpio(i2s_chan_handle_t handle, const i2s_pdm_rx_ return ESP_OK; } -esp_err_t i2s_init_pdm_rx_channel(i2s_chan_handle_t handle, const i2s_pdm_rx_config_t *pdm_rx_cfg) +esp_err_t i2s_channel_init_pdm_rx_mode(i2s_chan_handle_t handle, const i2s_pdm_rx_config_t *pdm_rx_cfg) { I2S_NULL_POINTER_CHECK(TAG, handle); ESP_RETURN_ON_FALSE(handle->dir == I2S_DIR_RX, ESP_ERR_INVALID_ARG, TAG, "This channel handle is not a RX handle"); - ESP_RETURN_ON_FALSE(handle->parent->id == I2S_NUM_0, ESP_ERR_INVALID_ARG, TAG, "This channel handle is registered on I2S1, but PDM is only supported on I2S0"); + ESP_RETURN_ON_FALSE(handle->controller->id == I2S_NUM_0, ESP_ERR_INVALID_ARG, TAG, "This channel handle is registered on I2S1, but PDM is only supported on I2S0"); esp_err_t ret = ESP_OK; @@ -430,11 +430,11 @@ esp_err_t i2s_init_pdm_rx_channel(i2s_chan_handle_t handle, const i2s_pdm_rx_con handle->mode_info = calloc(1, sizeof(i2s_pdm_rx_config_t)); ESP_GOTO_ON_FALSE(handle->mode_info, ESP_ERR_NO_MEM, err, TAG, "no memory for storing the configurations"); ESP_GOTO_ON_ERROR(i2s_pdm_rx_set_gpio(handle, &pdm_rx_cfg->gpio_cfg), err, TAG, "initialize channel failed while setting gpio pins"); - /* i2s_set_slot should be called before i2s_set_clock while initializing, because clock is relay on the slot */ + /* i2s_set_pdm_rx_slot should be called before i2s_set_pdm_rx_clock while initializing, because clock is relay on the slot */ ESP_GOTO_ON_ERROR(i2s_pdm_rx_set_slot(handle, &pdm_rx_cfg->slot_cfg), err, TAG, "initialize channel failed while setting slot"); #if SOC_I2S_SUPPORTS_APLL /* Enable APLL and acquire its lock when the clock source is APLL */ - if (pdm_rx_cfg->clk_cfg.clk_src == I2S_CLK_APLL) { + if (pdm_rx_cfg->clk_cfg.clk_src == I2S_CLK_SRC_APLL) { periph_rtc_apll_acquire(); handle->apll_en = true; } @@ -442,10 +442,19 @@ esp_err_t i2s_init_pdm_rx_channel(i2s_chan_handle_t handle, const i2s_pdm_rx_con ESP_GOTO_ON_ERROR(i2s_pdm_rx_set_clock(handle, &pdm_rx_cfg->clk_cfg), err, TAG, "initialize channel failed while setting clock"); ESP_GOTO_ON_ERROR(i2s_init_dma_intr(handle, ESP_INTR_FLAG_LEVEL1), err, TAG, "initialize dma interrupt failed"); - i2s_ll_rx_enable_pdm(handle->parent->hal.dev); + i2s_ll_rx_enable_pdm(handle->controller->hal.dev); #if SOC_I2S_HW_VERSION_2 /* Enable clock to start outputting mclk signal. Some codecs will reset once mclk stop */ - i2s_ll_rx_enable_clock(handle->parent->hal.dev); + i2s_ll_rx_enable_clock(handle->controller->hal.dev); +#endif +#ifdef CONFIG_PM_ENABLE + esp_pm_lock_type_t pm_type = ESP_PM_APB_FREQ_MAX; +#if SOC_I2S_SUPPORTS_APLL + if (pdm_rx_cfg->clk_cfg.clk_src == I2S_CLK_SRC_APLL) { + pm_type = ESP_PM_NO_LIGHT_SLEEP; + } +#endif // SOC_I2S_SUPPORTS_APLL + ESP_RETURN_ON_ERROR(esp_pm_lock_create(pm_type, 0, "i2s_driver", &handle->pm_lock), TAG, "I2S pm lock create failed"); #endif /* Initialization finished, mark state as ready */ @@ -458,7 +467,7 @@ err: return ret; } -esp_err_t i2s_reconfig_pdm_rx_clock(i2s_chan_handle_t handle, const i2s_pdm_rx_clk_config_t *clk_cfg) +esp_err_t i2s_channel_reconfig_pdm_rx_clock(i2s_chan_handle_t handle, const i2s_pdm_rx_clk_config_t *clk_cfg) { I2S_NULL_POINTER_CHECK(TAG, handle); I2S_NULL_POINTER_CHECK(TAG, clk_cfg); @@ -468,24 +477,37 @@ esp_err_t i2s_reconfig_pdm_rx_clock(i2s_chan_handle_t handle, const i2s_pdm_rx_c xSemaphoreTake(handle->mutex, portMAX_DELAY); ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_PDM, ESP_ERR_INVALID_ARG, err, TAG, "this handle is not working in standard moded"); - ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "invalid state, I2S should be stopped before reconfiguring the clock"); + ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "invalid state, I2S should be disabled before reconfiguring the clock"); + i2s_pdm_rx_config_t *pdm_rx_cfg = (i2s_pdm_rx_config_t *)handle->mode_info; + ESP_GOTO_ON_FALSE(pdm_rx_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); #if SOC_I2S_SUPPORTS_APLL - i2s_pdm_rx_config_t *pdm_rx_cfg = (i2s_pdm_rx_config_t*)handle->mode_info; - ESP_GOTO_ON_FALSE(pdm_rx_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); /* Enable APLL and acquire its lock when the clock source is changed to APLL */ - if (clk_cfg->clk_src == I2S_CLK_APLL && pdm_rx_cfg->clk_cfg.clk_src == I2S_CLK_PLL_160M) { + if (clk_cfg->clk_src == I2S_CLK_SRC_APLL && pdm_rx_cfg->clk_cfg.clk_src != I2S_CLK_SRC_APLL) { periph_rtc_apll_acquire(); handle->apll_en = true; } /* Disable APLL and release its lock when clock source is changed to 160M_PLL */ - if (clk_cfg->clk_src == I2S_CLK_PLL_160M && pdm_rx_cfg->clk_cfg.clk_src == I2S_CLK_APLL) { + if (clk_cfg->clk_src != I2S_CLK_SRC_APLL && pdm_rx_cfg->clk_cfg.clk_src == I2S_CLK_SRC_APLL) { periph_rtc_apll_release(); handle->apll_en = false; } #endif ESP_GOTO_ON_ERROR(i2s_pdm_rx_set_clock(handle, clk_cfg), err, TAG, "update clock failed"); +#ifdef CONFIG_PM_ENABLE + // Create/Re-create power management lock + if (pdm_rx_cfg->clk_cfg.clk_src != clk_cfg->clk_src) { + ESP_GOTO_ON_ERROR(esp_pm_lock_delete(handle->pm_lock), err, TAG, "I2S delete old pm lock failed"); + esp_pm_lock_type_t pm_type = ESP_PM_APB_FREQ_MAX; +#if SOC_I2S_SUPPORTS_APLL + if (clk_cfg->clk_src == I2S_CLK_SRC_APLL) { + pm_type = ESP_PM_NO_LIGHT_SLEEP; + } +#endif // SOC_I2S_SUPPORTS_APLL + ESP_GOTO_ON_ERROR(esp_pm_lock_create(pm_type, 0, "i2s_driver", &handle->pm_lock), err, TAG, "I2S pm lock create failed"); + } +#endif //CONFIG_PM_ENABLE xSemaphoreGive(handle->mutex); @@ -495,7 +517,7 @@ err: return ret; } -esp_err_t i2s_reconfig_pdm_rx_slot(i2s_chan_handle_t handle, const i2s_pdm_rx_slot_config_t *slot_cfg) +esp_err_t i2s_channel_reconfig_pdm_rx_slot(i2s_chan_handle_t handle, const i2s_pdm_rx_slot_config_t *slot_cfg) { I2S_NULL_POINTER_CHECK(TAG, handle); I2S_NULL_POINTER_CHECK(TAG, slot_cfg); @@ -505,9 +527,9 @@ esp_err_t i2s_reconfig_pdm_rx_slot(i2s_chan_handle_t handle, const i2s_pdm_rx_sl xSemaphoreTake(handle->mutex, portMAX_DELAY); ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_PDM, ESP_ERR_INVALID_ARG, err, TAG, "this handle is not working in standard moded"); - ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "invalid state, I2S should be stopped before reconfiguring the slot"); + ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "invalid state, I2S should be disabled before reconfiguring the slot"); - i2s_pdm_rx_config_t *pdm_rx_cfg = (i2s_pdm_rx_config_t*)handle->mode_info; + i2s_pdm_rx_config_t *pdm_rx_cfg = (i2s_pdm_rx_config_t *)handle->mode_info; ESP_GOTO_ON_FALSE(pdm_rx_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); ESP_GOTO_ON_ERROR(i2s_pdm_rx_set_slot(handle, slot_cfg), err, TAG, "set i2s standard slot failed"); @@ -526,7 +548,7 @@ err: return ret; } -esp_err_t i2s_reconfig_pdm_rx_gpio(i2s_chan_handle_t handle, const i2s_pdm_rx_gpio_config_t *gpio_cfg) +esp_err_t i2s_channel_reconfig_pdm_rx_gpio(i2s_chan_handle_t handle, const i2s_pdm_rx_gpio_config_t *gpio_cfg) { I2S_NULL_POINTER_CHECK(TAG, handle); I2S_NULL_POINTER_CHECK(TAG, gpio_cfg); @@ -535,7 +557,7 @@ esp_err_t i2s_reconfig_pdm_rx_gpio(i2s_chan_handle_t handle, const i2s_pdm_rx_gp xSemaphoreTake(handle->mutex, portMAX_DELAY); ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_PDM, ESP_ERR_INVALID_ARG, err, TAG, "This handle is not working in standard moded"); - ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "Invalid state, I2S should be stopped before reconfiguring the gpio"); + ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "Invalid state, I2S should be disabled before reconfiguring the gpio"); ESP_GOTO_ON_ERROR(i2s_pdm_rx_set_gpio(handle, gpio_cfg), err, TAG, "set i2s standard slot failed"); xSemaphoreGive(handle->mutex); diff --git a/components/driver/i2s/i2s_private.h b/components/driver/i2s/i2s_private.h index acd45d6273..e615be0f1d 100644 --- a/components/driver/i2s/i2s_private.h +++ b/components/driver/i2s/i2s_private.h @@ -10,6 +10,7 @@ #include "soc/lldesc.h" #include "soc/soc_caps.h" #include "hal/i2s_types.h" +#include "driver/i2s_types.h" #include "freertos/semphr.h" #include "freertos/queue.h" #if SOC_GDMA_SUPPORTED @@ -22,17 +23,15 @@ extern "C" { #endif -#define I2S_NULL_POINTER_CHECK(tag, p) ESP_RETURN_ON_FALSE((p), ESP_ERR_INVALID_ARG, tag, "[%s:%d] input parameter '"#p"' is NULL",__FUNCTION__,__LINE__) +#define I2S_NULL_POINTER_CHECK(tag, p) ESP_RETURN_ON_FALSE((p), ESP_ERR_INVALID_ARG, tag, "input parameter '"#p"' is NULL") /** * @brief i2s channel state for checking if the operation in under right driver state */ typedef enum { I2S_CHAN_STATE_REGISTER, /*!< i2s channel is registered (not initialized) */ - I2S_CHAN_STATE_READY, /*!< i2s channel is stopped (initialized) */ - I2S_CHAN_STATE_IDLE, /*!< i2s channel is idling (initialized and started) */ - I2S_CHAN_STATE_WRITING, /*!< i2s channel is writing (initialized and started) */ - I2S_CHAN_STATE_READING /*!< i2s channel is reading (initialized and started) */ + I2S_CHAN_STATE_READY, /*!< i2s channel is disabled (initialized) */ + I2S_CHAN_STATE_RUNNING, /*!< i2s channel is idling (initialized and enabled) */ } i2s_state_t; /** @@ -41,7 +40,9 @@ typedef enum { */ typedef struct { #if SOC_GDMA_SUPPORTED - gdma_channel_handle_t dma_chan; /*!< gdma channel handler */ + gdma_channel_handle_t dma_chan; /*!< gdma channel handle */ +#else + intr_handle_t dma_chan; /*!< interrupt channel handle */ #endif uint32_t desc_num; /*!< I2S DMA buffer number, it is also the number of DMA descriptor */ uint32_t frame_num; /*!< I2S frame number in one DMA buffer. One frame means one-time sample data in all slots */ @@ -65,15 +66,11 @@ typedef struct { i2s_chan_handle_t tx_chan; /*!< tx channel handler */ i2s_chan_handle_t rx_chan; /*!< rx channel handler */ int mclk; /*!< MCK out pin, shared by tx/rx*/ - -#if !SOC_GDMA_SUPPORTED - intr_handle_t i2s_isr_handle; /*!< i2s interrupt handler */ -#endif } i2s_controller_t; struct i2s_channel_t { /* Channel basic information */ - i2s_controller_t *parent; /*!< Parent pointer to controller object */ + i2s_controller_t *controller; /*!< Parent pointer to controller object */ i2s_comm_mode_t mode; /*!< i2s channel communication mode */ i2s_role_t role; /*!< i2s role */ i2s_dir_t dir; /*!< i2s channel direction */ @@ -87,43 +84,125 @@ struct i2s_channel_t { uint32_t active_slot; /*!< Active slot number */ uint32_t total_slot; /*!< Total slot number */ /* Locks and queues */ - SemaphoreHandle_t mutex; /*!< Mutex for DMA buffer related operations like reading/writing */ + SemaphoreHandle_t mutex; /*!< Mutex semaphore for the channel operations */ + SemaphoreHandle_t binary; /*!< Binary semaphore for writing / reading / enabling / disabling */ +#if CONFIG_PM_ENABLE esp_pm_lock_handle_t pm_lock; /*!< Power management lock, to avoid apb clock frequency changes while i2s is working */ +#endif +#if CONFIG_I2S_ISR_IRAM_SAFE + StaticSemaphore_t *mutex_struct; /*!< Static mutex struct */ + StaticSemaphore_t *binary_struct; /*!< Static binary struct */ + StaticQueue_t *msg_que_struct; /*!< Static message queue struct */ + void *msg_que_storage; /*!< Static message queue storage */ +#endif QueueHandle_t msg_queue; /*!< Message queue handler, used for transporting data between interrupt and read/write task */ - QueueHandle_t event_queue; /*!< Event queue handler, used for transporting interrupt event to user */ - - /* Function pointers of the corresponding mode */ + i2s_event_callbacks_t callbacks; /*!< Callback functions */ + void *user_data; /*!< User data for callback functions */ void (*start)(i2s_chan_handle_t); /*!< start tx/rx channel */ void (*stop)(i2s_chan_handle_t); /*!< stop tx/rx channel */ }; /** * @brief i2s platform level configurations - * @note All i2s controllers are under its control + * @note All i2s controllers' resources are involved */ typedef struct { portMUX_TYPE spinlock; /*!< Platform level lock */ - i2s_controller_t *controller[I2S_NUM_MAX]; /*!< Controller object */ - const char *comp_name[I2S_NUM_MAX]; /*!< The component name that occupied i2s controller */ + i2s_controller_t *controller[SOC_I2S_NUM]; /*!< Controller object */ + const char *comp_name[SOC_I2S_NUM]; /*!< The component name that occupied i2s controller */ } i2s_platform_t; -extern i2s_platform_t s_i2s; +extern i2s_platform_t g_i2s; +/** + * @brief Initialize I2S DMA interrupt + * + * @param handle I2S channel handle + * @param intr_flag I2S interrupt flags, `ESP_INTR_FLAG_XXX` defined in `esp_intr_alloc.h` + * @return + * - ESP_OK Initialize interrupt success + * - ESP_ERR_INVALID_ARG Wrong port id or NULL pointer + */ esp_err_t i2s_init_dma_intr(i2s_chan_handle_t handle, int intr_flag); +/** + * @brief Free I2S DMA descriptor and DMA buffer + * + * @param handle I2S channel handle + * @return + * - ESP_OK Free success + * - ESP_ERR_INVALID_ARG NULL pointer + */ esp_err_t i2s_free_dma_desc(i2s_chan_handle_t handle); +/** + * @brief Allocate memory for I2S DMA descriptor and DMA buffer + * + * @param handle I2S channel handle + * @param num Number of DMA descriptors + * @param bufsize The DMA buffer size + * + * @return + * - ESP_OK Allocate memory success + * - ESP_ERR_INVALID_ARG NULL pointer or bufsize is too big + * - ESP_ERR_NO_MEM No memmory for DMA descriptor and DMA buffer + */ esp_err_t i2s_alloc_dma_desc(i2s_chan_handle_t handle, uint32_t num, uint32_t bufsize); +/** + * @brief Get DMA buffer size + * + * @param handle I2S channel handle + * @param data_bit_width Data bit width in one slot + * @param dma_frame_num Frame number in one DMA buffer + * + * @return + * - DMA buffer size + */ uint32_t i2s_get_buf_size(i2s_chan_handle_t handle, uint32_t data_bit_width, uint32_t dma_frame_num); #if SOC_I2S_SUPPORTS_APLL -uint32_t i2s_set_get_apll_freq(uint32_t mclk_freq); +/** + * @brief Set mclk frequency and get the actuall APLL frequency + * + * @param mclk_freq_hz Expected mclk frequenct in Hz + * @return + * - Actuall APLL frequency + */ +uint32_t i2s_set_get_apll_freq(uint32_t mclk_freq_hz); #endif -void i2s_gpio_check_and_set(gpio_num_t gpio, uint32_t signal_idx, bool is_input); +/** + * @brief Check gpio validity and attach to corresponding signal + * + * @param gpio GPIO number + * @param signal_idx Signal index + * @param is_input Is input gpio + * @param is_invert Is invert gpio + */ +void i2s_gpio_check_and_set(gpio_num_t gpio, uint32_t signal_idx, bool is_input, bool is_invert); -esp_err_t i2s_check_set_mclk(i2s_port_t id, gpio_num_t gpio_num); +/** + * @brief Check gpio validity and output mclk signal + * + * @param id I2S port id + * @param gpio_num GPIO number + * @param is_apll Is using APLL as clock source + * @param is_invert Is invert the GPIO + * @return + * - ESP_OK Set mclk output gpio success + * - ESP_ERR_INVALID_ARG Invalid GPIO number + */ +esp_err_t i2s_check_set_mclk(i2s_port_t id, gpio_num_t gpio_num, bool is_apll, bool is_invert); + +/** + * @brief Attach data out signal and data in signal to a same gpio + * + * @param gpio GPIO number + * @param out_sig_idx Data out signal index + * @param in_sig_idx Data in signal index + */ +void i2s_gpio_loopback_set(gpio_num_t gpio, uint32_t out_sig_idx, uint32_t in_sig_idx); #ifdef __cplusplus } diff --git a/components/driver/i2s/i2s_std.c b/components/driver/i2s/i2s_std.c index aa5db23580..f60f8a852c 100644 --- a/components/driver/i2s/i2s_std.c +++ b/components/driver/i2s/i2s_std.c @@ -5,8 +5,17 @@ */ #include + #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" +#include "sdkconfig.h" + +#if CONFIG_I2S_ENABLE_DEBUG_LOG +// The local log level must be defined before including esp_log.h +// Set the maximum log level for this source file +#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG +#endif + #include "hal/i2s_hal.h" #include "driver/gpio.h" #include "driver/i2s_std.h" @@ -15,7 +24,7 @@ #include "esp_intr_alloc.h" #include "esp_check.h" -const static char *TAG = "I2S_STD"; +const static char *TAG = "i2s_std"; static esp_err_t i2s_std_calculate_clock(i2s_chan_handle_t handle, const i2s_std_clk_config_t *clk_cfg, i2s_hal_clock_info_t *clk_info) { @@ -37,7 +46,7 @@ static esp_err_t i2s_std_calculate_clock(i2s_chan_handle_t handle, const i2s_std clk_info->mclk = clk_info->bclk * clk_info->bclk_div; } #if SOC_I2S_SUPPORTS_APLL - clk_info->sclk = clk_cfg->clk_src == I2S_CLK_PLL_160M ? I2S_LL_BASE_CLK : i2s_set_get_apll_freq(clk_info->mclk); + clk_info->sclk = (clk_cfg->clk_src == I2S_CLK_SRC_APLL) ? i2s_set_get_apll_freq(clk_info->mclk) : I2S_LL_BASE_CLK; #else clk_info->sclk = I2S_LL_BASE_CLK; #endif @@ -54,37 +63,20 @@ static esp_err_t i2s_std_set_clock(i2s_chan_handle_t handle, const i2s_std_clk_c esp_err_t ret = ESP_OK; i2s_std_config_t *std_cfg = (i2s_std_config_t *)(handle->mode_info); - /* If Power Management enabled, a PM lock will be created when there is no PM lock or clock source changed */ -#ifdef CONFIG_PM_ENABLE - // Create/Re-create power management lock - if (handle->pm_lock == NULL || std_cfg->clk_cfg.clk_src != clk_cfg->clk_src) { - if (handle->pm_lock) { - ESP_RETURN_ON_ERROR(esp_pm_lock_delete(handle->pm_lock), TAG, "I2S delete old pm lock failed"); - } - esp_pm_lock_type_t pm_type = ESP_PM_APB_FREQ_MAX; -#if SOC_I2S_SUPPORTS_APLL - if (clk_cfg->clk_src == I2S_CLK_APLL) { - pm_type = ESP_PM_NO_LIGHT_SLEEP; - } -#endif // SOC_I2S_SUPPORTS_APLL - ESP_RETURN_ON_ERROR(esp_pm_lock_create(pm_type, 0, "i2s_driver", &handle->pm_lock), err, TAG, "I2S pm lock create failed"); - } -#endif //CONFIG_PM_ENABLE - i2s_hal_clock_info_t clk_info; /* Calculate clock parameters */ ESP_RETURN_ON_ERROR(i2s_std_calculate_clock(handle, clk_cfg, &clk_info), TAG, "clock calculate failed"); ESP_LOGD(TAG, "Clock division info: [sclk] %d Hz [mdiv] %d [mclk] %d Hz [bdiv] %d [bclk] %d Hz", - clk_info.sclk, clk_info.mclk_div, clk_info.mclk, clk_info.bclk_div, clk_info.bclk); + clk_info.sclk, clk_info.mclk_div, clk_info.mclk, clk_info.bclk_div, clk_info.bclk); - portENTER_CRITICAL(&s_i2s.spinlock); + portENTER_CRITICAL(&g_i2s.spinlock); /* Set clock configurations in HAL*/ if (handle->dir == I2S_DIR_TX) { - i2s_hal_set_tx_clock(&handle->parent->hal, &clk_info, clk_cfg->clk_src); + i2s_hal_set_tx_clock(&handle->controller->hal, &clk_info, clk_cfg->clk_src); } else { - i2s_hal_set_rx_clock(&handle->parent->hal, &clk_info, clk_cfg->clk_src); + i2s_hal_set_rx_clock(&handle->controller->hal, &clk_info, clk_cfg->clk_src); } - portEXIT_CRITICAL(&s_i2s.spinlock); + portEXIT_CRITICAL(&g_i2s.spinlock); /* Update the mode info: clock configuration */ memcpy(&(std_cfg->clk_cfg), clk_cfg, sizeof(i2s_std_clk_config_t)); @@ -94,6 +86,10 @@ static esp_err_t i2s_std_set_clock(i2s_chan_handle_t handle, const i2s_std_clk_c static esp_err_t i2s_std_set_slot(i2s_chan_handle_t handle, const i2s_std_slot_config_t *slot_cfg) { + /* Check configuration validity */ + ESP_RETURN_ON_FALSE((slot_cfg->slot_mode == I2S_SLOT_MODE_STEREO) || (slot_cfg->slot_mask != I2S_STD_SLOT_LEFT_RIGHT), + ESP_ERR_INVALID_ARG, TAG, "Can't select both left and right slot in mono mode"); + /* Update the total slot num and active slot num */ handle->total_slot = 2; handle->active_slot = slot_cfg->slot_mode == I2S_SLOT_MODE_MONO ? 1 : 2; @@ -108,28 +104,28 @@ static esp_err_t i2s_std_set_slot(i2s_chan_handle_t handle, const i2s_std_slot_c } bool is_slave = handle->role == I2S_ROLE_SLAVE; /* Share bck and ws signal in full-duplex mode */ - if (handle->parent->full_duplex) { - i2s_ll_share_bck_ws(handle->parent->hal.dev, true); + if (handle->controller->full_duplex) { + i2s_ll_share_bck_ws(handle->controller->hal.dev, true); /* Since bck and ws are shared, only tx or rx can be master Force to set rx as slave to avoid conflict of clock signal */ if (handle->dir == I2S_DIR_RX) { is_slave = true; } } else { - i2s_ll_share_bck_ws(handle->parent->hal.dev, false); + i2s_ll_share_bck_ws(handle->controller->hal.dev, false); } - portENTER_CRITICAL(&s_i2s.spinlock); + portENTER_CRITICAL(&g_i2s.spinlock); /* Configure the hardware to apply STD format */ if (handle->dir == I2S_DIR_TX) { - i2s_hal_std_set_tx_slot(&(handle->parent->hal), is_slave, (i2s_hal_slot_config_t*)slot_cfg); + i2s_hal_std_set_tx_slot(&(handle->controller->hal), is_slave, (i2s_hal_slot_config_t *)slot_cfg); } else { - i2s_hal_std_set_rx_slot(&(handle->parent->hal), is_slave, (i2s_hal_slot_config_t*)slot_cfg); + i2s_hal_std_set_rx_slot(&(handle->controller->hal), is_slave, (i2s_hal_slot_config_t *)slot_cfg); } - portEXIT_CRITICAL(&s_i2s.spinlock); + portEXIT_CRITICAL(&g_i2s.spinlock); /* Update the mode info: slot configuration */ - i2s_std_config_t *std_cfg = (i2s_std_config_t*)(handle->mode_info); + i2s_std_config_t *std_cfg = (i2s_std_config_t *)(handle->mode_info); memcpy(&(std_cfg->slot_cfg), slot_cfg, sizeof(i2s_std_slot_config_t)); return ESP_OK; @@ -137,64 +133,72 @@ static esp_err_t i2s_std_set_slot(i2s_chan_handle_t handle, const i2s_std_slot_c static esp_err_t i2s_std_set_gpio(i2s_chan_handle_t handle, const i2s_std_gpio_config_t *gpio_cfg) { - int id = handle->parent->id; + int id = handle->controller->id; /* Check validity of selected pins */ ESP_RETURN_ON_FALSE((gpio_cfg->bclk == -1 || GPIO_IS_VALID_GPIO(gpio_cfg->bclk)), ESP_ERR_INVALID_ARG, TAG, "bclk invalid"); ESP_RETURN_ON_FALSE((gpio_cfg->ws == -1 || GPIO_IS_VALID_GPIO(gpio_cfg->ws)), ESP_ERR_INVALID_ARG, TAG, "ws invalid"); - if (handle->dir == I2S_DIR_TX) { - /* Set data output GPIO */ - i2s_gpio_check_and_set(gpio_cfg->dout, i2s_periph_signal[id].data_out_sig, false); - } else { - /* Set data input GPIO */ - i2s_gpio_check_and_set(gpio_cfg->din, i2s_periph_signal[id].data_in_sig, true); - } + i2s_std_config_t *std_cfg = (i2s_std_config_t *)(handle->mode_info); + /* Loopback if dout = din */ if (gpio_cfg->dout != -1 && gpio_cfg->dout == gpio_cfg->din) { - gpio_set_direction(gpio_cfg->dout, GPIO_MODE_INPUT_OUTPUT); + i2s_gpio_loopback_set(gpio_cfg->dout, i2s_periph_signal[id].data_out_sig, i2s_periph_signal[id].data_in_sig); + } else if (handle->dir == I2S_DIR_TX) { + /* Set data output GPIO */ + i2s_gpio_check_and_set(gpio_cfg->dout, i2s_periph_signal[id].data_out_sig, false, false); + } else { + /* Set data input GPIO */ + i2s_gpio_check_and_set(gpio_cfg->din, i2s_periph_signal[id].data_in_sig, true, false); } if (handle->role == I2S_ROLE_SLAVE) { /* For "tx + slave" mode, select TX signal index for ws and bck */ - if (handle->dir == I2S_DIR_TX && !handle->parent->full_duplex) { + if (handle->dir == I2S_DIR_TX && !handle->controller->full_duplex) { #if SOC_I2S_HW_VERSION_2 - i2s_ll_mclk_bind_to_tx_clk(handle->parent->hal.dev); + i2s_ll_mclk_bind_to_tx_clk(handle->controller->hal.dev); #endif - i2s_gpio_check_and_set(gpio_cfg->ws, i2s_periph_signal[id].s_tx_ws_sig, true); - i2s_gpio_check_and_set(gpio_cfg->bclk, i2s_periph_signal[id].s_tx_bck_sig, true); - /* For "tx + rx + slave" or "rx + slave" mode, select RX signal index for ws and bck */ + i2s_gpio_check_and_set(gpio_cfg->ws, i2s_periph_signal[id].s_tx_ws_sig, true, gpio_cfg->invert_flags.ws_inv); + i2s_gpio_check_and_set(gpio_cfg->bclk, i2s_periph_signal[id].s_tx_bck_sig, true, gpio_cfg->invert_flags.bclk_inv); + /* For "tx + rx + slave" or "rx + slave" mode, select RX signal index for ws and bck */ } else { - i2s_gpio_check_and_set(gpio_cfg->ws, i2s_periph_signal[id].s_rx_ws_sig, true); - i2s_gpio_check_and_set(gpio_cfg->bclk, i2s_periph_signal[id].s_rx_bck_sig, true); + i2s_gpio_check_and_set(gpio_cfg->ws, i2s_periph_signal[id].s_rx_ws_sig, true, gpio_cfg->invert_flags.ws_inv); + i2s_gpio_check_and_set(gpio_cfg->bclk, i2s_periph_signal[id].s_rx_bck_sig, true, gpio_cfg->invert_flags.bclk_inv); } } else { /* mclk only available in master mode */ - ESP_RETURN_ON_ERROR(i2s_check_set_mclk(id, handle->parent->mclk), TAG, "mclk config failed"); - /* For "rx + master" mode, select RX signal index for ws and bck */ - if (handle->dir == I2S_DIR_RX && !handle->parent->full_duplex) { -#if SOC_I2S_HW_VERSION_2 - i2s_ll_mclk_bind_to_rx_clk(handle->parent->hal.dev); +#if SOC_I2S_SUPPORTS_APLL + bool is_apll = std_cfg->clk_cfg.clk_src == I2S_CLK_SRC_APLL; +#else + bool is_apll = false; #endif - i2s_gpio_check_and_set(gpio_cfg->ws, i2s_periph_signal[id].m_rx_ws_sig, false); - i2s_gpio_check_and_set(gpio_cfg->bclk, i2s_periph_signal[id].m_rx_bck_sig, false); - /* For "tx + rx + master" or "tx + master" mode, select TX signal index for ws and bck */ + ESP_RETURN_ON_ERROR(i2s_check_set_mclk(id, gpio_cfg->mclk, is_apll, gpio_cfg->invert_flags.mclk_inv), TAG, "mclk config failed"); + /* For "rx + master" mode, select RX signal index for ws and bck */ + if (handle->dir == I2S_DIR_RX && !handle->controller->full_duplex) { +#if SOC_I2S_HW_VERSION_2 + i2s_ll_mclk_bind_to_rx_clk(handle->controller->hal.dev); +#endif + i2s_gpio_check_and_set(gpio_cfg->ws, i2s_periph_signal[id].m_rx_ws_sig, false, gpio_cfg->invert_flags.ws_inv); + i2s_gpio_check_and_set(gpio_cfg->bclk, i2s_periph_signal[id].m_rx_bck_sig, false, gpio_cfg->invert_flags.bclk_inv); + /* For "tx + rx + master" or "tx + master" mode, select TX signal index for ws and bck */ } else { - i2s_gpio_check_and_set(gpio_cfg->ws, i2s_periph_signal[id].m_tx_ws_sig, false); - i2s_gpio_check_and_set(gpio_cfg->bclk, i2s_periph_signal[id].m_tx_bck_sig, false); + i2s_gpio_check_and_set(gpio_cfg->ws, i2s_periph_signal[id].m_tx_ws_sig, false, gpio_cfg->invert_flags.ws_inv); + i2s_gpio_check_and_set(gpio_cfg->bclk, i2s_periph_signal[id].m_tx_bck_sig, false, gpio_cfg->invert_flags.bclk_inv); } } /* Update the mode info: gpio configuration */ - i2s_std_config_t *std_cfg = (i2s_std_config_t*)(handle->mode_info); memcpy(&(std_cfg->gpio_cfg), gpio_cfg, sizeof(i2s_std_gpio_config_t)); return ESP_OK; } -esp_err_t i2s_init_std_channel(i2s_chan_handle_t handle, const i2s_std_config_t *std_cfg) +esp_err_t i2s_channel_init_std_mode(i2s_chan_handle_t handle, const i2s_std_config_t *std_cfg) { +#if CONFIG_I2S_ENABLE_DEBUG_LOG + esp_log_level_set(TAG, ESP_LOG_DEBUG); +#endif I2S_NULL_POINTER_CHECK(TAG, handle); esp_err_t ret = ESP_OK; @@ -208,11 +212,11 @@ esp_err_t i2s_init_std_channel(i2s_chan_handle_t handle, const i2s_std_config_t ESP_GOTO_ON_FALSE(handle->mode_info, ESP_ERR_NO_MEM, err, TAG, "no memory for storing the configurations"); ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_REGISTER, ESP_ERR_INVALID_STATE, err, TAG, "the channel has initialized already"); ESP_GOTO_ON_ERROR(i2s_std_set_gpio(handle, &std_cfg->gpio_cfg), err, TAG, "initialize channel failed while setting gpio pins"); - /* i2s_set_slot should be called before i2s_set_clock while initializing, because clock is relay on the slot */ + /* i2s_set_std_slot should be called before i2s_set_std_clock while initializing, because clock is relay on the slot */ ESP_GOTO_ON_ERROR(i2s_std_set_slot(handle, &std_cfg->slot_cfg), err, TAG, "initialize channel failed while setting slot"); #if SOC_I2S_SUPPORTS_APLL /* Enable APLL and acquire its lock when the clock source is APLL */ - if (std_cfg->clk_cfg.clk_src == I2S_CLK_APLL) { + if (std_cfg->clk_cfg.clk_src == I2S_CLK_SRC_APLL) { periph_rtc_apll_acquire(); handle->apll_en = true; } @@ -222,14 +226,24 @@ esp_err_t i2s_init_std_channel(i2s_chan_handle_t handle, const i2s_std_config_t #if SOC_I2S_HW_VERSION_2 /* Enable clock to start outputting mclk signal. Some codecs will reset once mclk stop */ if (handle->dir == I2S_DIR_TX) { - i2s_ll_tx_enable_std(handle->parent->hal.dev); - i2s_ll_tx_enable_clock(handle->parent->hal.dev); + i2s_ll_tx_enable_std(handle->controller->hal.dev); + i2s_ll_tx_enable_clock(handle->controller->hal.dev); } else { - i2s_ll_rx_enable_std(handle->parent->hal.dev); - i2s_ll_rx_enable_clock(handle->parent->hal.dev); + i2s_ll_rx_enable_std(handle->controller->hal.dev); + i2s_ll_rx_enable_clock(handle->controller->hal.dev); } #endif +#ifdef CONFIG_PM_ENABLE + esp_pm_lock_type_t pm_type = ESP_PM_APB_FREQ_MAX; +#if SOC_I2S_SUPPORTS_APLL + if (std_cfg->clk_cfg.clk_src == I2S_CLK_SRC_APLL) { + pm_type = ESP_PM_NO_LIGHT_SLEEP; + } +#endif // SOC_I2S_SUPPORTS_APLL + ESP_RETURN_ON_ERROR(esp_pm_lock_create(pm_type, 0, "i2s_driver", &handle->pm_lock), TAG, "I2S pm lock create failed"); +#endif + /* Initialization finished, mark state as ready */ handle->state = I2S_CHAN_STATE_READY; xSemaphoreGive(handle->mutex); @@ -240,7 +254,7 @@ err: return ret; } -esp_err_t i2s_reconfig_std_clock(i2s_chan_handle_t handle, const i2s_std_clk_config_t *clk_cfg) +esp_err_t i2s_channel_reconfig_std_clock(i2s_chan_handle_t handle, const i2s_std_clk_config_t *clk_cfg) { I2S_NULL_POINTER_CHECK(TAG, handle); I2S_NULL_POINTER_CHECK(TAG, clk_cfg); @@ -249,24 +263,39 @@ esp_err_t i2s_reconfig_std_clock(i2s_chan_handle_t handle, const i2s_std_clk_con xSemaphoreTake(handle->mutex, portMAX_DELAY); ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_STD, ESP_ERR_INVALID_ARG, err, TAG, "this handle is not working in standard moded"); - ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "invalid state, I2S should be stopped before reconfiguring the clock"); + ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "invalid state, I2S should be disabled before reconfiguring the clock"); + + i2s_std_config_t *std_cfg = (i2s_std_config_t *)handle->mode_info; + ESP_GOTO_ON_FALSE(std_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); #if SOC_I2S_SUPPORTS_APLL - i2s_std_config_t *std_cfg = (i2s_std_config_t*)handle->mode_info; - ESP_GOTO_ON_FALSE(std_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); /* Enable APLL and acquire its lock when the clock source is changed to APLL */ - if (clk_cfg->clk_src == I2S_CLK_APLL && std_cfg->clk_cfg.clk_src == I2S_CLK_PLL_160M) { + if (clk_cfg->clk_src == I2S_CLK_SRC_APLL && std_cfg->clk_cfg.clk_src != I2S_CLK_SRC_APLL) { periph_rtc_apll_acquire(); handle->apll_en = true; } /* Disable APLL and release its lock when clock source is changed to 160M_PLL */ - if (clk_cfg->clk_src == I2S_CLK_PLL_160M && std_cfg->clk_cfg.clk_src == I2S_CLK_APLL) { + if (clk_cfg->clk_src != I2S_CLK_SRC_APLL && std_cfg->clk_cfg.clk_src == I2S_CLK_SRC_APLL) { periph_rtc_apll_release(); handle->apll_en = false; } #endif ESP_GOTO_ON_ERROR(i2s_std_set_clock(handle, clk_cfg), err, TAG, "update clock failed"); +#ifdef CONFIG_PM_ENABLE + // Create/Re-create power management lock + if (std_cfg->clk_cfg.clk_src != clk_cfg->clk_src) { + ESP_GOTO_ON_ERROR(esp_pm_lock_delete(handle->pm_lock), err, TAG, "I2S delete old pm lock failed"); + esp_pm_lock_type_t pm_type = ESP_PM_APB_FREQ_MAX; +#if SOC_I2S_SUPPORTS_APLL + if (clk_cfg->clk_src == I2S_CLK_SRC_APLL) { + pm_type = ESP_PM_NO_LIGHT_SLEEP; + } +#endif // SOC_I2S_SUPPORTS_APLL + ESP_GOTO_ON_ERROR(esp_pm_lock_create(pm_type, 0, "i2s_driver", &handle->pm_lock), err, TAG, "I2S pm lock create failed"); + } +#endif //CONFIG_PM_ENABLE + xSemaphoreGive(handle->mutex); return ESP_OK; @@ -275,7 +304,7 @@ err: return ret; } -esp_err_t i2s_reconfig_std_slot(i2s_chan_handle_t handle, const i2s_std_slot_config_t *slot_cfg) +esp_err_t i2s_channel_reconfig_std_slot(i2s_chan_handle_t handle, const i2s_std_slot_config_t *slot_cfg) { I2S_NULL_POINTER_CHECK(TAG, handle); I2S_NULL_POINTER_CHECK(TAG, slot_cfg); @@ -284,9 +313,9 @@ esp_err_t i2s_reconfig_std_slot(i2s_chan_handle_t handle, const i2s_std_slot_con xSemaphoreTake(handle->mutex, portMAX_DELAY); ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_STD, ESP_ERR_INVALID_ARG, err, TAG, "this handle is not working in standard moded"); - ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "invalid state, I2S should be stopped before reconfiguring the slot"); + ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "invalid state, I2S should be disabled before reconfiguring the slot"); - i2s_std_config_t *std_cfg = (i2s_std_config_t*)handle->mode_info; + i2s_std_config_t *std_cfg = (i2s_std_config_t *)handle->mode_info; ESP_GOTO_ON_FALSE(std_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); ESP_GOTO_ON_ERROR(i2s_std_set_slot(handle, slot_cfg), err, TAG, "set i2s standard slot failed"); @@ -305,7 +334,7 @@ err: return ret; } -esp_err_t i2s_reconfig_std_gpio(i2s_chan_handle_t handle, const i2s_std_gpio_config_t *gpio_cfg) +esp_err_t i2s_channel_reconfig_std_gpio(i2s_chan_handle_t handle, const i2s_std_gpio_config_t *gpio_cfg) { I2S_NULL_POINTER_CHECK(TAG, handle); I2S_NULL_POINTER_CHECK(TAG, gpio_cfg); @@ -314,7 +343,7 @@ esp_err_t i2s_reconfig_std_gpio(i2s_chan_handle_t handle, const i2s_std_gpio_con xSemaphoreTake(handle->mutex, portMAX_DELAY); ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_STD, ESP_ERR_INVALID_ARG, err, TAG, "This handle is not working in standard moded"); - ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "Invalid state, I2S should be stopped before reconfiguring the gpio"); + ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "Invalid state, I2S should be disabled before reconfiguring the gpio"); ESP_GOTO_ON_ERROR(i2s_std_set_gpio(handle, gpio_cfg), err, TAG, "set i2s standard slot failed"); xSemaphoreGive(handle->mutex); diff --git a/components/driver/i2s/i2s_tdm.c b/components/driver/i2s/i2s_tdm.c index 9245a08261..ce7a12522d 100644 --- a/components/driver/i2s/i2s_tdm.c +++ b/components/driver/i2s/i2s_tdm.c @@ -5,8 +5,17 @@ */ #include + #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" +#include "sdkconfig.h" + +#if CONFIG_I2S_ENABLE_DEBUG_LOG +// The local log level must be defined before including esp_log.h +// Set the maximum log level for this source file +#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG +#endif + #include "hal/i2s_hal.h" #include "driver/gpio.h" #include "driver/i2s_tdm.h" @@ -15,7 +24,7 @@ #include "esp_intr_alloc.h" #include "esp_check.h" -const static char *TAG = "I2S_TDM"; +const static char *TAG = "i2s_tdm"; // Same with standard mode except total slot number static esp_err_t i2s_tdm_calculate_clock(i2s_chan_handle_t handle, const i2s_tdm_clk_config_t *clk_cfg, i2s_hal_clock_info_t *clk_info) @@ -38,7 +47,7 @@ static esp_err_t i2s_tdm_calculate_clock(i2s_chan_handle_t handle, const i2s_tdm clk_info->mclk = clk_info->bclk * clk_info->bclk_div; } #if SOC_I2S_SUPPORTS_APLL - clk_info->sclk = clk_cfg->clk_src == I2S_CLK_PLL_160M ? I2S_LL_BASE_CLK : i2s_set_get_apll_freq(clk_info->mclk); + clk_info->sclk = clk_cfg->clk_src == I2S_CLK_SRC_APLL ? i2s_set_get_apll_freq(clk_info->mclk) : I2S_LL_BASE_CLK; #else clk_info->sclk = I2S_LL_BASE_CLK; #endif @@ -55,37 +64,20 @@ static esp_err_t i2s_tdm_set_clock(i2s_chan_handle_t handle, const i2s_tdm_clk_c esp_err_t ret = ESP_OK; i2s_tdm_config_t *tdm_cfg = (i2s_tdm_config_t *)(handle->mode_info); - /* If Power Management enabled, a PM lock will be created when there is no PM lock or clock source changed */ -#ifdef CONFIG_PM_ENABLE - // Create/Re-create power management lock - if (handle->pm_lock == NULL || tdm_cfg->clk_cfg.clk_src != clk_cfg->clk_src) { - if (handle->pm_lock) { - ESP_RETURN_ON_ERROR(esp_pm_lock_delete(handle->pm_lock), TAG, "I2S delete old pm lock failed"); - } - esp_pm_lock_type_t pm_type = ESP_PM_APB_FREQ_MAX; -#if SOC_I2S_SUPPORTS_APLL - if (clk_cfg->clk_src == I2S_CLK_APLL) { - pm_type = ESP_PM_NO_LIGHT_SLEEP; - } -#endif // SOC_I2S_SUPPORTS_APLL - ESP_RETURN_ON_ERROR(esp_pm_lock_create(pm_type, 0, "i2s_driver", &handle->pm_lock), err, TAG, "I2S pm lock create failed"); - } -#endif //CONFIG_PM_ENABLE - i2s_hal_clock_info_t clk_info; /* Calculate clock parameters */ ESP_RETURN_ON_ERROR(i2s_tdm_calculate_clock(handle, clk_cfg, &clk_info), TAG, "clock calculate failed"); ESP_LOGD(TAG, "Clock division info: [sclk] %d Hz [mdiv] %d [mclk] %d Hz [bdiv] %d [bclk] %d Hz", - clk_info.sclk, clk_info.mclk_div, clk_info.mclk, clk_info.bclk_div, clk_info.bclk); + clk_info.sclk, clk_info.mclk_div, clk_info.mclk, clk_info.bclk_div, clk_info.bclk); - portENTER_CRITICAL(&s_i2s.spinlock); + portENTER_CRITICAL(&g_i2s.spinlock); /* Set clock configurations in HAL*/ if (handle->dir == I2S_DIR_TX) { - i2s_hal_set_tx_clock(&handle->parent->hal, &clk_info, clk_cfg->clk_src); + i2s_hal_set_tx_clock(&handle->controller->hal, &clk_info, clk_cfg->clk_src); } else { - i2s_hal_set_rx_clock(&handle->parent->hal, &clk_info, clk_cfg->clk_src); + i2s_hal_set_rx_clock(&handle->controller->hal, &clk_info, clk_cfg->clk_src); } - portEXIT_CRITICAL(&s_i2s.spinlock); + portEXIT_CRITICAL(&g_i2s.spinlock); /* Update the mode info: clock configuration */ memcpy(&(tdm_cfg->clk_cfg), clk_cfg, sizeof(i2s_tdm_clk_config_t)); @@ -111,28 +103,28 @@ static esp_err_t i2s_tdm_set_slot(i2s_chan_handle_t handle, const i2s_tdm_slot_c } bool is_slave = handle->role == I2S_ROLE_SLAVE; /* Share bck and ws signal in full-duplex mode */ - if (handle->parent->full_duplex) { - i2s_ll_share_bck_ws(handle->parent->hal.dev, true); + if (handle->controller->full_duplex) { + i2s_ll_share_bck_ws(handle->controller->hal.dev, true); /* Since bck and ws are shared, only tx or rx can be master Force to set rx as slave to avoid conflict of clock signal */ if (handle->dir == I2S_DIR_RX) { is_slave = true; } } else { - i2s_ll_share_bck_ws(handle->parent->hal.dev, false); + i2s_ll_share_bck_ws(handle->controller->hal.dev, false); } - portENTER_CRITICAL(&s_i2s.spinlock); + portENTER_CRITICAL(&g_i2s.spinlock); /* Configure the hardware to apply TDM format */ if (handle->dir == I2S_DIR_TX) { - i2s_hal_tdm_set_tx_slot(&(handle->parent->hal), is_slave, (i2s_hal_slot_config_t*)slot_cfg); + i2s_hal_tdm_set_tx_slot(&(handle->controller->hal), is_slave, (i2s_hal_slot_config_t *)slot_cfg); } else { - i2s_hal_tdm_set_rx_slot(&(handle->parent->hal), is_slave, (i2s_hal_slot_config_t*)slot_cfg); + i2s_hal_tdm_set_rx_slot(&(handle->controller->hal), is_slave, (i2s_hal_slot_config_t *)slot_cfg); } - portEXIT_CRITICAL(&s_i2s.spinlock); + portEXIT_CRITICAL(&g_i2s.spinlock); /* Update the mode info: slot configuration */ - i2s_tdm_config_t *tdm_cfg = (i2s_tdm_config_t*)(handle->mode_info); + i2s_tdm_config_t *tdm_cfg = (i2s_tdm_config_t *)(handle->mode_info); memcpy(&(tdm_cfg->slot_cfg), slot_cfg, sizeof(i2s_tdm_slot_config_t)); return ESP_OK; @@ -140,65 +132,67 @@ static esp_err_t i2s_tdm_set_slot(i2s_chan_handle_t handle, const i2s_tdm_slot_c static esp_err_t i2s_tdm_set_gpio(i2s_chan_handle_t handle, const i2s_tdm_gpio_config_t *gpio_cfg) { - int id = handle->parent->id; + int id = handle->controller->id; /* Check validity of selected pins */ ESP_RETURN_ON_FALSE((gpio_cfg->bclk == -1 || GPIO_IS_VALID_GPIO(gpio_cfg->bclk)), ESP_ERR_INVALID_ARG, TAG, "bclk invalid"); ESP_RETURN_ON_FALSE((gpio_cfg->ws == -1 || GPIO_IS_VALID_GPIO(gpio_cfg->ws)), ESP_ERR_INVALID_ARG, TAG, "ws invalid"); - if (handle->dir == I2S_DIR_TX) { - /* Set data output GPIO */ - i2s_gpio_check_and_set(gpio_cfg->dout, i2s_periph_signal[id].data_out_sig, false); - } else { - /* Set data input GPIO */ - i2s_gpio_check_and_set(gpio_cfg->din, i2s_periph_signal[id].data_in_sig, true); - } /* Loopback if dout = din */ if (gpio_cfg->dout != -1 && gpio_cfg->dout == gpio_cfg->din) { - gpio_set_direction(gpio_cfg->dout, GPIO_MODE_INPUT_OUTPUT); + i2s_gpio_loopback_set(gpio_cfg->dout, i2s_periph_signal[id].data_out_sig, i2s_periph_signal[id].data_in_sig); + } else if (handle->dir == I2S_DIR_TX) { + /* Set data output GPIO */ + i2s_gpio_check_and_set(gpio_cfg->dout, i2s_periph_signal[id].data_out_sig, false, false); + } else { + /* Set data input GPIO */ + i2s_gpio_check_and_set(gpio_cfg->din, i2s_periph_signal[id].data_in_sig, true, false); } if (handle->role == I2S_ROLE_SLAVE) { /* For "tx + slave" mode, select TX signal index for ws and bck */ - if (handle->dir == I2S_DIR_TX && !handle->parent->full_duplex) { + if (handle->dir == I2S_DIR_TX && !handle->controller->full_duplex) { #if SOC_I2S_HW_VERSION_2 - i2s_ll_mclk_bind_to_tx_clk(handle->parent->hal.dev); + i2s_ll_mclk_bind_to_tx_clk(handle->controller->hal.dev); #endif - i2s_gpio_check_and_set(gpio_cfg->ws, i2s_periph_signal[id].s_tx_ws_sig, true); - i2s_gpio_check_and_set(gpio_cfg->bclk, i2s_periph_signal[id].s_tx_bck_sig, true); - /* For "tx + rx + slave" or "rx + slave" mode, select RX signal index for ws and bck */ + i2s_gpio_check_and_set(gpio_cfg->ws, i2s_periph_signal[id].s_tx_ws_sig, true, gpio_cfg->invert_flags.ws_inv); + i2s_gpio_check_and_set(gpio_cfg->bclk, i2s_periph_signal[id].s_tx_bck_sig, true, gpio_cfg->invert_flags.bclk_inv); + /* For "tx + rx + slave" or "rx + slave" mode, select RX signal index for ws and bck */ } else { - i2s_gpio_check_and_set(gpio_cfg->ws, i2s_periph_signal[id].s_rx_ws_sig, true); - i2s_gpio_check_and_set(gpio_cfg->bclk, i2s_periph_signal[id].s_rx_bck_sig, true); + i2s_gpio_check_and_set(gpio_cfg->ws, i2s_periph_signal[id].s_rx_ws_sig, true, gpio_cfg->invert_flags.ws_inv); + i2s_gpio_check_and_set(gpio_cfg->bclk, i2s_periph_signal[id].s_rx_bck_sig, true, gpio_cfg->invert_flags.bclk_inv); } } else { /* mclk only available in master mode */ - ESP_RETURN_ON_ERROR(i2s_check_set_mclk(id, handle->parent->mclk), TAG, "mclk config failed"); + ESP_RETURN_ON_ERROR(i2s_check_set_mclk(id, gpio_cfg->mclk, false, gpio_cfg->invert_flags.mclk_inv), TAG, "mclk config failed"); /* For "rx + master" mode, select RX signal index for ws and bck */ - if (handle->dir == I2S_DIR_RX && !handle->parent->full_duplex) { + if (handle->dir == I2S_DIR_RX && !handle->controller->full_duplex) { #if SOC_I2S_HW_VERSION_2 - i2s_ll_mclk_bind_to_rx_clk(handle->parent->hal.dev); + i2s_ll_mclk_bind_to_rx_clk(handle->controller->hal.dev); #endif - i2s_gpio_check_and_set(gpio_cfg->ws, i2s_periph_signal[id].m_rx_ws_sig, false); - i2s_gpio_check_and_set(gpio_cfg->bclk, i2s_periph_signal[id].m_rx_bck_sig, false); - /* For "tx + rx + master" or "tx + master" mode, select TX signal index for ws and bck */ + i2s_gpio_check_and_set(gpio_cfg->ws, i2s_periph_signal[id].m_rx_ws_sig, false, gpio_cfg->invert_flags.ws_inv); + i2s_gpio_check_and_set(gpio_cfg->bclk, i2s_periph_signal[id].m_rx_bck_sig, false, gpio_cfg->invert_flags.bclk_inv); + /* For "tx + rx + master" or "tx + master" mode, select TX signal index for ws and bck */ } else { - i2s_gpio_check_and_set(gpio_cfg->ws, i2s_periph_signal[id].m_tx_ws_sig, false); - i2s_gpio_check_and_set(gpio_cfg->bclk, i2s_periph_signal[id].m_tx_bck_sig, false); + i2s_gpio_check_and_set(gpio_cfg->ws, i2s_periph_signal[id].m_tx_ws_sig, false, gpio_cfg->invert_flags.ws_inv); + i2s_gpio_check_and_set(gpio_cfg->bclk, i2s_periph_signal[id].m_tx_bck_sig, false, gpio_cfg->invert_flags.bclk_inv); } } /* Update the mode info: gpio configuration */ - i2s_tdm_config_t *tdm_cfg = (i2s_tdm_config_t*)(handle->mode_info); + i2s_tdm_config_t *tdm_cfg = (i2s_tdm_config_t *)(handle->mode_info); memcpy(&(tdm_cfg->gpio_cfg), gpio_cfg, sizeof(i2s_tdm_gpio_config_t)); return ESP_OK; } -esp_err_t i2s_init_tdm_channel(i2s_chan_handle_t handle, const i2s_tdm_config_t *tdm_cfg) +esp_err_t i2s_channel_init_tdm_mode(i2s_chan_handle_t handle, const i2s_tdm_config_t *tdm_cfg) { +#if CONFIG_I2S_ENABLE_DEBUG_LOG + esp_log_level_set(TAG, ESP_LOG_DEBUG); +#endif I2S_NULL_POINTER_CHECK(TAG, handle); esp_err_t ret = ESP_OK; @@ -212,28 +206,37 @@ esp_err_t i2s_init_tdm_channel(i2s_chan_handle_t handle, const i2s_tdm_config_t handle->mode_info = calloc(1, sizeof(i2s_tdm_config_t)); ESP_GOTO_ON_FALSE(handle->mode_info, ESP_ERR_NO_MEM, err, TAG, "no memory for storing the configurations"); ESP_GOTO_ON_ERROR(i2s_tdm_set_gpio(handle, &tdm_cfg->gpio_cfg), err, TAG, "initialize channel failed while setting gpio pins"); - /* i2s_set_slot should be called before i2s_set_clock while initializing, because clock is relay on the slot */ + /* i2s_set_tdm_slot should be called before i2s_set_tdm_clock while initializing, because clock is relay on the slot */ ESP_GOTO_ON_ERROR(i2s_tdm_set_slot(handle, &tdm_cfg->slot_cfg), err, TAG, "initialize channel failed while setting slot"); #if SOC_I2S_SUPPORTS_APLL /* Enable APLL and acquire its lock when the clock source is APLL */ - if (tdm_cfg->clk_cfg.clk_src == I2S_CLK_APLL) { + if (tdm_cfg->clk_cfg.clk_src == I2S_CLK_SRC_APLL) { periph_rtc_apll_acquire(); handle->apll_en = true; } +#endif ESP_GOTO_ON_ERROR(i2s_tdm_set_clock(handle, &tdm_cfg->clk_cfg), err, TAG, "initialize channel failed while setting clock"); ESP_GOTO_ON_ERROR(i2s_init_dma_intr(handle, ESP_INTR_FLAG_LEVEL1), err, TAG, "initialize dma interrupt failed"); -#endif #if SOC_I2S_HW_VERSION_2 /* Enable clock to start outputting mclk signal. Some codecs will reset once mclk stop */ if (handle->dir == I2S_DIR_TX) { - i2s_ll_tx_enable_tdm(handle->parent->hal.dev); - i2s_ll_tx_enable_clock(handle->parent->hal.dev); + i2s_ll_tx_enable_tdm(handle->controller->hal.dev); + i2s_ll_tx_enable_clock(handle->controller->hal.dev); } else { - i2s_ll_rx_enable_tdm(handle->parent->hal.dev); - i2s_ll_rx_enable_clock(handle->parent->hal.dev); + i2s_ll_rx_enable_tdm(handle->controller->hal.dev); + i2s_ll_rx_enable_clock(handle->controller->hal.dev); } #endif +#ifdef CONFIG_PM_ENABLE + esp_pm_lock_type_t pm_type = ESP_PM_APB_FREQ_MAX; +#if SOC_I2S_SUPPORTS_APLL + if (tdm_cfg->clk_cfg.clk_src == I2S_CLK_SRC_APLL) { + pm_type = ESP_PM_NO_LIGHT_SLEEP; + } +#endif // SOC_I2S_SUPPORTS_APLL + ESP_RETURN_ON_ERROR(esp_pm_lock_create(pm_type, 0, "i2s_driver", &handle->pm_lock), TAG, "I2S pm lock create failed"); +#endif /* Initialization finished, mark state as ready */ handle->state = I2S_CHAN_STATE_READY; @@ -245,7 +248,7 @@ err: return ret; } -esp_err_t i2s_reconfig_tdm_clock(i2s_chan_handle_t handle, const i2s_tdm_clk_config_t *clk_cfg) +esp_err_t i2s_channel_reconfig_tdm_clock(i2s_chan_handle_t handle, const i2s_tdm_clk_config_t *clk_cfg) { I2S_NULL_POINTER_CHECK(TAG, handle); I2S_NULL_POINTER_CHECK(TAG, clk_cfg); @@ -254,24 +257,39 @@ esp_err_t i2s_reconfig_tdm_clock(i2s_chan_handle_t handle, const i2s_tdm_clk_con xSemaphoreTake(handle->mutex, portMAX_DELAY); ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_TDM, ESP_ERR_INVALID_ARG, err, TAG, "this handle is not working in standard moded"); - ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "invalid state, I2S should be stopped before reconfiguring the clock"); + ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "invalid state, I2S should be disabled before reconfiguring the clock"); + i2s_tdm_config_t *tdm_cfg = (i2s_tdm_config_t *)handle->mode_info; + ESP_GOTO_ON_FALSE(tdm_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); #if SOC_I2S_SUPPORTS_APLL - i2s_tdm_config_t *tdm_cfg = (i2s_tdm_config_t*)handle->mode_info; - ESP_GOTO_ON_FALSE(tdm_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); /* Enable APLL and acquire its lock when the clock source is changed to APLL */ - if (clk_cfg->clk_src == I2S_CLK_APLL && clk_cfg->clk_cfg.clk_src == I2S_CLK_PLL_160M) { + if (clk_cfg->clk_src == I2S_CLK_SRC_APLL && clk_cfg->clk_cfg.clk_src != I2S_CLK_SRC_APLL) { periph_rtc_apll_acquire(); handle->apll_en = true; } /* Disable APLL and release its lock when clock source is changed to 160M_PLL */ - if (clk_cfg->clk_src == I2S_CLK_PLL_160M && clk_cfg->clk_cfg.clk_src == I2S_CLK_APLL) { + if (clk_cfg->clk_src != I2S_CLK_SRC_APLL && clk_cfg->clk_cfg.clk_src == I2S_CLK_SRC_APLL) { periph_rtc_apll_release(); handle->apll_en = false; } #endif ESP_GOTO_ON_ERROR(i2s_tdm_set_clock(handle, clk_cfg), err, TAG, "update clock failed"); + +#ifdef CONFIG_PM_ENABLE + // Create/Re-create power management lock + if (tdm_cfg->clk_cfg.clk_src != clk_cfg->clk_src) { + ESP_GOTO_ON_ERROR(esp_pm_lock_delete(handle->pm_lock), err, TAG, "I2S delete old pm lock failed"); + esp_pm_lock_type_t pm_type = ESP_PM_APB_FREQ_MAX; +#if SOC_I2S_SUPPORTS_APLL + if (clk_cfg->clk_src == I2S_CLK_SRC_APLL) { + pm_type = ESP_PM_NO_LIGHT_SLEEP; + } +#endif // SOC_I2S_SUPPORTS_APLL + ESP_GOTO_ON_ERROR(esp_pm_lock_create(pm_type, 0, "i2s_driver", &handle->pm_lock), err, TAG, "I2S pm lock create failed"); + } +#endif //CONFIG_PM_ENABLE + xSemaphoreGive(handle->mutex); return ESP_OK; @@ -280,7 +298,7 @@ err: return ret; } -esp_err_t i2s_reconfig_tdm_slot(i2s_chan_handle_t handle, const i2s_tdm_slot_config_t *slot_cfg) +esp_err_t i2s_channel_reconfig_tdm_slot(i2s_chan_handle_t handle, const i2s_tdm_slot_config_t *slot_cfg) { I2S_NULL_POINTER_CHECK(TAG, handle); I2S_NULL_POINTER_CHECK(TAG, slot_cfg); @@ -289,9 +307,9 @@ esp_err_t i2s_reconfig_tdm_slot(i2s_chan_handle_t handle, const i2s_tdm_slot_con xSemaphoreTake(handle->mutex, portMAX_DELAY); ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_TDM, ESP_ERR_INVALID_ARG, err, TAG, "this handle is not working in standard moded"); - ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "invalid state, I2S should be stopped before reconfiguring the slot"); + ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "invalid state, I2S should be disabled before reconfiguring the slot"); - i2s_tdm_config_t *tdm_cfg = (i2s_tdm_config_t*)handle->mode_info; + i2s_tdm_config_t *tdm_cfg = (i2s_tdm_config_t *)handle->mode_info; ESP_GOTO_ON_FALSE(tdm_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); ESP_GOTO_ON_ERROR(i2s_tdm_set_slot(handle, slot_cfg), err, TAG, "set i2s standard slot failed"); @@ -301,6 +319,10 @@ esp_err_t i2s_reconfig_tdm_slot(i2s_chan_handle_t handle, const i2s_tdm_slot_con if (tdm_cfg->slot_cfg.slot_bit_width == slot_bits) { ESP_GOTO_ON_ERROR(i2s_tdm_set_clock(handle, &tdm_cfg->clk_cfg), err, TAG, "update clock failed"); } + + /* Reset queue */ + xQueueReset(handle->msg_queue); + xSemaphoreGive(handle->mutex); return ESP_OK; @@ -309,7 +331,7 @@ err: return ret; } -esp_err_t i2s_reconfig_tdm_gpio(i2s_chan_handle_t handle, const i2s_tdm_gpio_config_t *gpio_cfg) +esp_err_t i2s_channel_reconfig_tdm_gpio(i2s_chan_handle_t handle, const i2s_tdm_gpio_config_t *gpio_cfg) { I2S_NULL_POINTER_CHECK(TAG, handle); I2S_NULL_POINTER_CHECK(TAG, gpio_cfg); @@ -318,7 +340,7 @@ esp_err_t i2s_reconfig_tdm_gpio(i2s_chan_handle_t handle, const i2s_tdm_gpio_con xSemaphoreTake(handle->mutex, portMAX_DELAY); ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_TDM, ESP_ERR_INVALID_ARG, err, TAG, "This handle is not working in standard moded"); - ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "Invalid state, I2S should be stopped before reconfiguring the gpio"); + ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "Invalid state, I2S should be disabled before reconfiguring the gpio"); ESP_GOTO_ON_ERROR(i2s_tdm_set_gpio(handle, gpio_cfg), err, TAG, "set i2s standard slot failed"); xSemaphoreGive(handle->mutex); diff --git a/components/driver/include/driver/i2s_common.h b/components/driver/include/driver/i2s_common.h index b4f637c751..f68f54814c 100644 --- a/components/driver/include/driver/i2s_common.h +++ b/components/driver/include/driver/i2s_common.h @@ -6,9 +6,7 @@ #pragma once -#include "freertos/FreeRTOS.h" -#include "freertos/queue.h" - +#include "driver/i2s_types.h" #include "hal/i2s_types.h" #include "esp_types.h" @@ -18,12 +16,6 @@ extern "C" { #endif -#ifdef I2S_DRIVER_SELECTED - #error "Only one set of APIs is allowed to use" -#else - #define I2S_DRIVER_SELECTED -#endif - /** * @brief get default I2S property */ @@ -37,47 +29,82 @@ extern "C" { #define I2S_GPIO_UNUSED GPIO_NUM_NC /*!< Used in i2s_gpio_config_t for signals which are not used */ +/** + * @brief Group of I2S callbacks + * @note The callbacks are all running under ISR environment + * @note When CONFIG_I2S_ISR_IRAM_SAFE is enabled, the callback itself and functions called by it should be placed in IRAM. + * The variables used in the function should be in the SRAM as well. + */ +typedef struct { + i2s_isr_callback_t on_recv; /**< Callback of data received event, only for rx channel + * The event data includes DMA buffer address and size that just finished receiving data + */ + i2s_isr_callback_t on_recv_q_ovf; /**< Callback of receiving queue overflowed event, only for rx channel + * The event data includes buffer size that has been overwritten + */ + i2s_isr_callback_t on_sent; /**< Callback of data sent event, only for tx channel + * The event data includes DMA buffer address and size that just finished sending data + */ + i2s_isr_callback_t on_send_q_ovf; /**< Callback of sending queue overflowed evnet, only for tx channel + * The event data includes buffer size that has been overwritten + */ +} i2s_event_callbacks_t; + /** * @brief I2S controller channel configuration */ typedef struct { - i2s_port_t id; /*!< I2S port id */ - i2s_role_t role; /*!< I2S role, I2S_ROLE_MASTER or I2S_ROLE_SLAVE */ + i2s_port_t id; /*!< I2S port id */ + i2s_role_t role; /*!< I2S role, I2S_ROLE_MASTER or I2S_ROLE_SLAVE */ /* DMA configurations */ uint32_t dma_desc_num; /*!< I2S DMA buffer number, it is also the number of DMA descriptor */ uint32_t dma_frame_num; /*!< I2S frame number in one DMA buffer. One frame means one-time sample data in all slots */ - bool auto_clear; /*!< Set to auto clear DMA TX descriptor, i2s will always send zero automatically if no data to send */ + bool auto_clear; /*!< Set to auto clear DMA TX buffer, i2s will always send zero automatically if no data to send */ } i2s_chan_config_t; /** - * @brief Allocate a new i2s channel - * @note The new i2s channel handle will at REGISTERED state after it is allocated successfully. - * @note When the port id in channel configuration is I2S_NUM_AUTO, driver will allocate i2s port automatically - * Otherwise driver will try to allocate the new channel on the selected port. - * @note If both tx_handle and rx_handle are not NULL, it means this I2S port will work at duplex mode, - * and these rx and tx channel will be allocated on a same I2S port as well. - * Note that tx/rx channel will be affected by each other on ESP32 and ESP32S2, - * so please make sure them are working in same condition and have same status(start/stop). - * @note If tx_handle or rx_handle is NULL, it means this I2S port will work at simplex mode, - * For ESP32 and ESP32S2, the whole I2S port will be occupied as well even if only simplex is working. - * For the other targets, another channel on this port will still available. + * @brief I2S channel information + */ +typedef struct { + i2s_port_t id; /*!< I2S port id */ + i2s_role_t role; /*!< I2S role, I2S_ROLE_MASTER or I2S_ROLE_SLAVE */ + i2s_dir_t dir; /*!< I2S channel direction */ + i2s_comm_mode_t mode; /*!< I2S channel communication mode */ + i2s_chan_handle_t pair_chan; /*!< I2S pair channel handle in duplex mode, always NULL in simplex mode */ +} i2s_chan_info_t; + +/** + * @brief Allocate new I2S channel(s) + * @note The new created I2S channel handle will be REGISTERED state after it is allocated successfully. + * @note When the port id in channel configuration is I2S_NUM_AUTO, driver will allocate I2S port automatically + * on one of the i2s controller, otherwise driver will try to allocate the new channel on the selected port. + * @note If both tx_handle and rx_handle are not NULL, it means this I2S controller will work at full-duplex mode, + * the rx and tx channels will be allocated on a same I2S port in this case. + * Note that some configurations of tx/rx channel are shared on ESP32 and ESP32S2, + * so please make sure they are working at same condition and under same status(start/stop). + * Currently, full-duplex mode can't guarantee tx/rx channels write/read synchronously, + * they can only share the clock signals for now. + * @note If tx_handle OR rx_handle is NULL, it means this I2S controller will work at simplex mode. + * For ESP32 and ESP32S2, the whole I2S controller (i.e. both rx and tx channel) will be occupied, + * even if only one of rx or tx channel is registered. + * For the other targets, another channel on this controller will still available. * * @param[in] chan_cfg I2S controller channel configurations - * @param[out] tx_handle I2S channel handler used for managing the sending channel(optional) - * @param[out] rx_handle I2S channel handler used for managing the receiving channel(optional) + * @param[out] ret_tx_handle I2S channel handler used for managing the sending channel(optional) + * @param[out] ret_rx_handle I2S channel handler used for managing the receiving channel(optional) * @return - * - ESP_OK Allocate a new channel success + * - ESP_OK Allocate new channel(s) success * - ESP_ERR_NOT_SUPPORTED The communication mode is not supported on the current chip * - ESP_ERR_INVALID_ARG NULL pointer or illegal parameter in i2s_chan_config_t * - ESP_ERR_NOT_FOUND No available I2S channel found */ -esp_err_t i2s_new_channel(const i2s_chan_config_t *chan_cfg, i2s_chan_handle_t *tx_handle, i2s_chan_handle_t *rx_handle); +esp_err_t i2s_new_channel(const i2s_chan_config_t *chan_cfg, i2s_chan_handle_t *ret_tx_handle, i2s_chan_handle_t *ret_rx_handle); /** * @brief Delete the i2s channel - * @note The i2s channel will be stopped to ensure the i2s channel is not at READING or WRITING state. + * @note Only allowed to be called when the i2s channel is at REGISTERED or READY state (i.e., it should stop before deleting it). * @note Resource will be free automatically if all channels in one port are deleted * * @param[in] handle I2S channel handler @@ -87,99 +114,36 @@ esp_err_t i2s_new_channel(const i2s_chan_config_t *chan_cfg, i2s_chan_handle_t * esp_err_t i2s_del_channel(i2s_chan_handle_t handle); /** - * @brief Initialize i2s channel - * @note Only allowed to be called when the channel state is REGISTERED, (i.e., channel has been allocated, but not initialized) - * and the state will be updated to INITIALIZING while during the initialization, - * finally it will be READY if initialization is success, otherwise the state will return to REGISTERED. - * @note Will initialize i2s channel according to the i2s mode - * For different modes, we should input corresponding configurations. + * @brief Get I2S channel information * * @param[in] handle I2S channel handler - * @param[in] clk_config Clock configuration, should input correct type of clock configuration according to i2s communication mode that set in 'i2s_chan_config_t'. - * For I2S_COMM_MODE_STD mode, please input 'i2s_std_clk_config_t' type. - * For I2S_COMM_MODE_PDM mode, please input 'i2s_pdm_tx_clk_config_t' type for tx channel and 'i2s_pdm_rx_clk_config_t' type for rx channel. - * For I2S_COMM_MODE_TDM mode, please input 'i2s_tdm_clk_config_t' type. - * @param[in] slot_config Slot configuration, should input correct type of slot configuration according to i2s communication mode that set in 'i2s_chan_config_t'. - * For I2S_COMM_MODE_STD mode, please input 'i2s_std_slot_config_t' type. - * For I2S_COMM_MODE_PDM mode, please input 'i2s_pdm_tx_slot_config_t' type for tx channel and 'i2s_pdm_rx_slot_config_t' type for rx channel. - * For I2S_COMM_MODE_TDM mode, please input 'i2s_tdm_slot_config_t' type. + * @param[out] chan_info I2S channel basic information * @return - * - ESP_OK Initialize successfully - * - ESP_ERR_INVALID_ARG NULL pointer - * - ESP_ERR_INVALID_STATE This channel is not registered + * - ESP_OK Get i2s channel information success + * - ESP_ERR_NOT_FOUND The input handle doesn't match any registered I2S channels, it may not an i2s channel handle or not available any more + * - ESP_ERR_INVALID_ARG The input handle or chan_info pointer is NULL */ -// esp_err_t i2s_init_channel(i2s_chan_handle_t handle, const void *clk_config, const void *slot_config); +esp_err_t i2s_channel_get_info(i2s_chan_handle_t handle, i2s_chan_info_t *chan_info); /** - * @brief Reconfigure the I2S clock + * @brief Enable the i2s channel * @note Only allowed to be called when the channel state is READY, (i.e., channel has been initialized, but not started) - * this function won't change the state. - * @note Normally the clock has been configured after 'i2s_init_channel' is called - * This function is for re-configuring the clock. - * 'i2s_stop_channel' should be called before calling this function if i2s has started. - * - * @param[in] handle I2S channel handler - * @param[in] clk_config Clock configuration, should input correct type of clock configuration according to i2s communication mode - * For I2S_COMM_MODE_STD mode, please input 'i2s_std_clk_config_t' type. - * For I2S_COMM_MODE_PDM mode, please input 'i2s_pdm_tx_clk_config_t' type for tx channel and 'i2s_pdm_rx_clk_config_t' type for rx channel. - * For I2S_COMM_MODE_TDM mode, please input 'i2s_tdm_clk_config_t' type. - * @return - * - ESP_OK Set clock successfully - * - ESP_ERR_NOT_SUPPORTED The input communication mode is not supported - * - ESP_ERR_INVALID_ARG NULL pointer - * - ESP_ERR_INVALID_STATE This channel is not initialized - */ -// esp_err_t i2s_set_clock(i2s_chan_handle_t handle, const void *clk_config); - -/** - * @brief Reconfigure the I2S slot - * @note Only allowed to be called when the channel state is READY, (i.e., channel has been initialized, but not started) - * this function won't change the state. - * @note Normally the slot has been configured after 'i2s_init_channel' is called - * This function is for re-configuring the slot - * 'i2s_stop_channel' should be called before calling this function if i2s has started. - * - * @param[in] handle I2S channel handler - * @param[in] slot_config Slot configuration, should input correct type of clock configuration according to i2s communication mode - * For I2S_COMM_MODE_STD mode, please input 'i2s_std_slot_config_t' type. - * For I2S_COMM_MODE_PDM mode, please input 'i2s_pdm_tx_slot_config_t' type for tx channel and 'i2s_pdm_rx_slot_config_t' type for rx channel. - * For I2S_COMM_MODE_TDM mode, please input 'i2s_tdm_slot_config_t' type. - * @return - * - ESP_OK Set slot successfully - * - ESP_ERR_INVALID_ARG NULL pointer or unmatched slot configuration type - * - ESP_ERR_INVALID_STATE This channel is not initialized - */ -// esp_err_t i2s_set_slot(i2s_chan_handle_t handle, const void *slot_config); - -/** - * @brief Get I2S event queue handler - * @note Can be called at any time - * - * @param[in] handle I2S channel handler - * @param[in] que_len Queue length (if the queue has not been created yet) - * @return - * - NULL Failed to create the event queue - * - else Event queue handler - */ -QueueHandle_t i2s_get_event_queue(i2s_chan_handle_t handle, uint32_t que_len); - -/** - * @brief Start i2s channel - * @note Only allowed to be called when the channel state is READY, (i.e., channel has been initialized, but not started) - * the channel will enter IDLE state once it is started successfully. + * the channel will enter RUNNING state once it is enabled successfully. + * @note Enbale the channel can start the I2S communication on hardware. It will start outputting bclk and ws signal. + * For mclk signal, it will start to output when initialization is finished * * @param[in] handle I2S channel handler * - ESP_OK Start successfully * - ESP_ERR_INVALID_ARG NULL pointer * - ESP_ERR_INVALID_STATE This channel has not initialized or already started */ -esp_err_t i2s_start_channel(i2s_chan_handle_t handle); +esp_err_t i2s_channel_enable(i2s_chan_handle_t handle); /** - * @brief Stop i2s channel - * @note Only allowed to be called when the channel state is READY / IDLE / WRITING / READING, (i.e., channel has been initialized) - * the channel will enter READY state once it is stopped successfully. - * @note It will stop bclk and ws signal but not mclk signal + * @brief Disable the i2s channel + * @note Only allowed to be called when the channel state is READY / RUNNING, (i.e., channel has been initialized) + * the channel will enter READY state once it is disabled successfully. + * @note Disable the channel can stop the I2S communication on hardware. It will stop bclk and ws signal but not mclk signal * * @param[in] handle I2S channel handler * @return @@ -187,80 +151,61 @@ esp_err_t i2s_start_channel(i2s_chan_handle_t handle); * - ESP_ERR_INVALID_ARG NULL pointer * - ESP_ERR_INVALID_STATE This channel has not stated */ -esp_err_t i2s_stop_channel(i2s_chan_handle_t handle); +esp_err_t i2s_channel_disable(i2s_chan_handle_t handle); /** * @brief I2S write data - * @note Only allowed to be called when the channel state is IDLE, (i.e., tx channel has been started and is not writing now) - * the channel will enter WRITING state once start to write, - * and it will switch back to IDLE when quit the writing, - * but the IDLE only stands for the software state, it doesn't mean there is no the signal transporting on line. + * @note Only allowed to be called when the channel state is RUNNING, (i.e., tx channel has been started and is not writing now) + * but the RUNNING only stands for the software state, it doesn't mean there is no the signal transporting on line. * * @param[in] handle I2S channel handler * @param[in] src The pointer of sent data buffer * @param[in] size Max data buffer length * @param[out] bytes_written Byte number that actually be sent - * @param[in] ticks_to_wait Max block time + * @param[in] timeout_ms Max block time * @return * - ESP_OK Write successfully * - ESP_ERR_INVALID_ARG NULL pointer or this handle is not tx handle * - ESP_ERR_TIMEOUT Writing timeout, no writing event received from ISR within ticks_to_wait * - ESP_ERR_INVALID_STATE I2S is not ready to write */ -esp_err_t i2s_write_channel(i2s_chan_handle_t handle, const void *src, size_t size, size_t *bytes_written, TickType_t ticks_to_wait); +esp_err_t i2s_channel_write(i2s_chan_handle_t handle, const void *src, size_t size, size_t *bytes_written, uint32_t timeout_ms); /** * @brief I2S read data - * @note Only allowed to be called when the channel state is IDLE - * the channel will enter READING state once start to read, - * and it will switch back to IDLE when quit the reading, - * but the IDLE only stands for the software state, it doesn't mean there is no the signal transporting on line. + * @note Only allowed to be called when the channel state is RUNNING + * but the RUNNING only stands for the software state, it doesn't mean there is no the signal transporting on line. * * @param[in] handle I2S channel handler * @param[in] dest The pointer of receiving data buffer * @param[in] size Max data buffer length * @param[out] bytes_read Byte number that actually be read - * @param[in] ticks_to_wait Max block time + * @param[in] timeout_ms Max block time * @return * - ESP_OK Read successfully * - ESP_ERR_INVALID_ARG NULL pointer or this handle is not rx handle * - ESP_ERR_TIMEOUT Reading timeout, no reading event received from ISR within ticks_to_wait * - ESP_ERR_INVALID_STATE I2S is not ready to read */ -esp_err_t i2s_read_channel(i2s_chan_handle_t handle, void *dest, size_t size, size_t *bytes_read, TickType_t ticks_to_wait); +esp_err_t i2s_channel_read(i2s_chan_handle_t handle, void *dest, size_t size, size_t *bytes_read, uint32_t timeout_ms); /** - * @brief Clear the DMA buffer - * @note Only allowed to be called when the channel state is READY / IDLE / WRITING / READING, (i.e., channel has been initialized) - * it won't change the current channel state. - * @note The legacy data in DMA buffer will be cleared immediately once it is called - * That means i2s will keep send zero if no other data to send - * It has same effect with 'auto_clear' field in slot configuration struct - * but it should be called manually and won't lower the interrupt performance + * @brief Set event callbacks for I2S channel * - * @param[in] handle I2S channel handler - * @return - * - ESP_OK Clear successfully - * - ESP_ERR_INVALID_STATE I2S is not initialized - */ -esp_err_t i2s_clear_dma_buffer(i2s_chan_handle_t handle); - -/** - * @brief Abort i2s reading or writing function - * @note Only allowed to be called when the channel state is IDLE / WRITING / READING, (i.e., channel has been started) - * it will change to IDLE after aborting the current reading or writing. - * @note Since reading or writing will be blocked for a long time while transporting a large quantity of data, - * This function can help to terminate reading/writing in its next reading/writing loop, - * but if reading/writing is bolcked on receiving dma queue(i.e. dma can't send or receive data), this function won't take effect - * And it will only abort for one time, so reading/writing thread won't stop though it is called + * @note Only allowed to be called when the channel state is REGISTARED / READY, (i.e., before channel starts) + * @note User can deregister a previously registered callback by calling this function and setting the callback member in the `callbacks` structure to NULL. + * @note When CONFIG_I2S_ISR_IRAM_SAFE is enabled, the callback itself and functions called by it should be placed in IRAM. + * The variables used in the function should be in the SRAM as well. The `user_data` should also reside in SRAM or internal RAM as well. * - * @param[in] handle I2S channel handler + * @param[in] handle I2S channel handler + * @param[in] callbacks Group of callback functions + * @param[in] user_data User data, which will be passed to callback functions directly * @return - * - ESP_OK Abort successfully - * - ESP_ERR_INVALID_STATE I2S is stopped or not initialized + * - ESP_OK Set event callbacks successfully + * - ESP_ERR_INVALID_ARG Set event callbacks failed because of invalid argument + * - ESP_ERR_INVALID_STATE Set event callbacks failed because the current channel state is not REGISTARED or READY */ -esp_err_t i2s_abort_reading_writing(i2s_chan_handle_t handle); - +esp_err_t i2s_channel_register_event_callback(i2s_chan_handle_t handle, const i2s_event_callbacks_t *callbacks, void *user_data); #ifdef __cplusplus } diff --git a/components/driver/include/driver/i2s_pdm.h b/components/driver/include/driver/i2s_pdm.h index 4f3ad29f6f..c07ddeb545 100644 --- a/components/driver/include/driver/i2s_pdm.h +++ b/components/driver/include/driver/i2s_pdm.h @@ -29,7 +29,6 @@ extern "C" { * @param mono_or_stereo I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO */ #define I2S_PDM_RX_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) { \ - .mode = I2S_COMM_MODE_PDM, \ .data_bit_width = bits_per_sample, \ .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \ .slot_mode = mono_or_stereo, \ @@ -41,32 +40,29 @@ extern "C" { */ #define I2S_PDM_RX_CLK_DEFAULT_CONFIG(rate) { \ .sample_rate_hz = rate, \ - .clk_src = I2S_CLK_PLL_160M, \ + .clk_src = I2S_CLK_SRC_DEFAULT, \ .mclk_multiple = I2S_MCLK_MULTIPLE_256, \ .dn_sample_mode = I2S_PDM_DSR_8S \ } /** - * @breif I2S slot configuration for pdm rx mode + * @brief I2S slot configuration for pdm rx mode */ typedef struct { /* General fields */ - i2s_comm_mode_t mode; /*!< I2S communication mode, this field is for identification (MUST match the communication mode in 'i2s_chan_config_t') */ i2s_data_bit_width_t data_bit_width; /*!< I2S sample data bit width (valid data bits per sample), only support 16 bits for PDM mode */ i2s_slot_bit_width_t slot_bit_width; /*!< I2S slot bit width (total bits per slot) , only support 16 bits for PDM mode */ i2s_slot_mode_t slot_mode; /*!< Set mono or stereo mode with I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO */ - } i2s_pdm_rx_slot_config_t; /** - * @breif I2S clock configuration for pdm rx mode + * @brief I2S clock configuration for pdm rx mode */ typedef struct { /* General fields */ uint32_t sample_rate_hz; /*!< I2S sample rate */ i2s_clock_src_t clk_src; /*!< Choose clock source */ i2s_mclk_multiple_t mclk_multiple; /*!< The multiple of mclk to the sample rate */ - /* Particular fields */ i2s_pdm_dsr_t dn_sample_mode; /*!< Down-sampling rate mode */ } i2s_pdm_rx_clk_config_t; @@ -77,23 +73,83 @@ typedef struct { typedef struct { gpio_num_t clk; /*!< PDM clk pin, output */ gpio_num_t din; /*!< DATA pin, input */ + struct { + uint32_t clk_inv: 1; /*!< Set 1 to invert the clk output */ + } invert_flags; /*!< GPIO pin invert flags */ } i2s_pdm_rx_gpio_config_t; -typedef struct -{ - i2s_pdm_rx_clk_config_t clk_cfg; - i2s_pdm_rx_slot_config_t slot_cfg; - i2s_pdm_rx_gpio_config_t gpio_cfg; +/** + * @brief I2S PDM RX mode major configuration that including clock/slot/gpio configuration + */ +typedef struct { + i2s_pdm_rx_clk_config_t clk_cfg; /*!< PDM RX clock configurations, can be genertated by macro I2S_PDM_RX_CLK_DEFAULT_CONFIG */ + i2s_pdm_rx_slot_config_t slot_cfg; /*!< PDM RX slot configurations, can be genertated by macro I2S_PDM_RX_SLOT_DEFAULT_CONFIG */ + i2s_pdm_rx_gpio_config_t gpio_cfg; /*!< PDM RX slot configurations, specified by user */ } i2s_pdm_rx_config_t; +/** + * @brief Initialize i2s channel to PDM RX mode + * @note Only allowed to be called when the channel state is REGISTERED, (i.e., channel has been allocated, but not initialized) + * and the state will be updated to READY if initialization success, otherwise the state will return to REGISTERED. + * + * @param[in] handle I2S rx channel handler + * @param[in] pdm_rx_cfg Configurations for PDM RX mode, including clock, slot and gpio + * The clock configuration can be generated by the helper macro `I2S_PDM_RX_CLK_DEFAULT_CONFIG` + * The slot configuration can be generated by the helper macro `I2S_PDM_RX_SLOT_DEFAULT_CONFIG` + * + * @return + * - ESP_OK Initialize successfully + * - ESP_ERR_NO_MEM No memory for storing the channel information + * - ESP_ERR_INVALID_ARG NULL pointer or invalid configuration + * - ESP_ERR_INVALID_STATE This channel is not registered + */ +esp_err_t i2s_channel_init_pdm_rx_mode(i2s_chan_handle_t handle, const i2s_pdm_rx_config_t *pdm_rx_cfg); -esp_err_t i2s_init_pdm_rx_channel(i2s_chan_handle_t handle, const i2s_pdm_rx_config_t *pdm_rx_cfg); +/** + * @brief Reconfigure the I2S clock for PDM RX mode + * @note Only allowed to be called when the channel state is READY, i.e., channel has been initialized, but not started + * this function won't change the state. 'i2s_channel_disable' should be called before calling this function if i2s has started. + * @note The input channel handle has to be initialized to PDM RX mode, i.e., 'i2s_channel_init_pdm_rx_mode' has been called before reconfigring + * + * @param[in] handle I2S rx channel handler + * @param[in] clk_cfg PDM RX mode clock configuration, can be generated by `I2S_PDM_RX_CLK_DEFAULT_CONFIG` + * @return + * - ESP_OK Set clock successfully + * - ESP_ERR_INVALID_ARG NULL pointer, invalid configuration or not PDM mode + * - ESP_ERR_INVALID_STATE This channel is not initialized or not stopped + */ +esp_err_t i2s_channel_reconfig_pdm_rx_clock(i2s_chan_handle_t handle, const i2s_pdm_rx_clk_config_t *clk_cfg); -esp_err_t i2s_reconfig_pdm_rx_clock(i2s_chan_handle_t handle, const i2s_pdm_rx_clk_config_t *clk_cfg); +/** + * @brief Reconfigure the I2S slot for PDM RX mode + * @note Only allowed to be called when the channel state is READY, i.e., channel has been initialized, but not started + * this function won't change the state. 'i2s_channel_disable' should be called before calling this function if i2s has started. + * @note The input channel handle has to be initialized to PDM RX mode, i.e., 'i2s_channel_init_pdm_rx_mode' has been called before reconfigring + * + * @param[in] handle I2S rx channel handler + * @param[in] slot_cfg PDM RX mode slot configuration, can be generated by `I2S_PDM_RX_SLOT_DEFAULT_CONFIG` + * @return + * - ESP_OK Set clock successfully + * - ESP_ERR_NO_MEM No memory for DMA buffer + * - ESP_ERR_INVALID_ARG NULL pointer, invalid configuration or not PDM mode + * - ESP_ERR_INVALID_STATE This channel is not initialized or not stopped + */ +esp_err_t i2s_channel_reconfig_pdm_rx_slot(i2s_chan_handle_t handle, const i2s_pdm_rx_slot_config_t *slot_cfg); -esp_err_t i2s_reconfig_pdm_rx_slot(i2s_chan_handle_t handle, const i2s_pdm_rx_slot_config_t *slot_cfg); - -esp_err_t i2s_reconfig_pdm_rx_gpio(i2s_chan_handle_t handle, const i2s_pdm_rx_gpio_config_t *gpio_cfg); +/** + * @brief Reconfigure the I2S gpio for PDM RX mode + * @note Only allowed to be called when the channel state is READY, i.e., channel has been initialized, but not started + * this function won't change the state. 'i2s_channel_disable' should be called before calling this function if i2s has started. + * @note The input channel handle has to be initialized to PDM RX mode, i.e., 'i2s_channel_init_pdm_rx_mode' has been called before reconfigring + * + * @param[in] handle I2S rx channel handler + * @param[in] gpio_cfg PDM RX mode gpio configuration, specified by user + * @return + * - ESP_OK Set clock successfully + * - ESP_ERR_INVALID_ARG NULL pointer, invalid configuration or not PDM mode + * - ESP_ERR_INVALID_STATE This channel is not initialized or not stopped + */ +esp_err_t i2s_channel_reconfig_pdm_rx_gpio(i2s_chan_handle_t handle, const i2s_pdm_rx_gpio_config_t *gpio_cfg); #endif // SOC_I2S_SUPPORTS_PDM_RX @@ -107,7 +163,6 @@ esp_err_t i2s_reconfig_pdm_rx_gpio(i2s_chan_handle_t handle, const i2s_pdm_rx_gp * @param mono_or_stereo I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO */ #define I2S_PDM_TX_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) { \ - .mode = I2S_COMM_MODE_PDM, \ .data_bit_width = bits_per_sample, \ .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \ .slot_mode = mono_or_stereo, \ @@ -129,12 +184,8 @@ esp_err_t i2s_reconfig_pdm_rx_gpio(i2s_chan_handle_t handle, const i2s_pdm_rx_gp * @param mono_or_stereo I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO */ #define I2S_PDM_TX_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) { \ - .mode = I2S_COMM_MODE_PDM, \ .data_bit_width = bits_per_sample, \ .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \ - .dma_desc_num = 8, \ - .dma_frame_num = 200, \ - .auto_clear = false, \ .slot_mode = mono_or_stereo, \ .sd_prescale = 0, \ .sd_scale = I2S_PDM_SIG_SCALING_MUL_1, \ @@ -150,12 +201,12 @@ esp_err_t i2s_reconfig_pdm_rx_gpio(i2s_chan_handle_t handle, const i2s_pdm_rx_gp * 1: fp = 960, fs = sample_rate_hz / 100, in this case, Fpdm = 128*48000 * 2: fp = 960, fs = 480, in this case, Fpdm = 128*Fpcm = 128*sample_rate_hz * If the pdm receiver do not care the pdm serial clock, it's recommended set Fpdm = 128*48000. - * Otherwise, the second configuration should be applied. + * Otherwise, the second configuration should be adopted. * @param rate sample rate */ #define I2S_PDM_TX_CLK_DEFAULT_CONFIG(rate) { \ .sample_rate_hz = rate, \ - .clk_src = I2S_CLK_PLL_160M, \ + .clk_src = I2S_CLK_SRC_DEFAULT, \ .mclk_multiple = I2S_MCLK_MULTIPLE_256, \ .up_sample_fp = 960, \ .up_sample_fs = ((rate) / 100), \ @@ -181,11 +232,9 @@ esp_err_t i2s_reconfig_pdm_rx_gpio(i2s_chan_handle_t handle, const i2s_pdm_rx_gp */ typedef struct { /* General fields */ - i2s_comm_mode_t mode; /*!< I2S communication mode, this field is for identification (MUST match the communication mode in 'i2s_chan_config_t') */ i2s_data_bit_width_t data_bit_width; /*!< I2S sample data bit width (valid data bits per sample), only support 16 bits for PDM mode */ i2s_slot_bit_width_t slot_bit_width; /*!< I2S slot bit width (total bits per slot), only support 16 bits for PDM mode */ i2s_slot_mode_t slot_mode; /*!< Set mono or stereo mode with I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO */ - /* Particular fields */ uint32_t sd_prescale; /*!< Sigma-delta filter prescale */ i2s_pdm_sig_scale_t sd_scale; /*!< Sigma-delta filter scaling value */ @@ -202,14 +251,13 @@ typedef struct { } i2s_pdm_tx_slot_config_t; /** - * @breif I2S clock configuration for pdm tx mode + * @brief I2S clock configuration for pdm tx mode */ typedef struct { /* General fields */ uint32_t sample_rate_hz; /*!< I2S sample rate */ i2s_clock_src_t clk_src; /*!< Choose clock source */ i2s_mclk_multiple_t mclk_multiple; /*!< The multiple of mclk to the sample rate */ - /* Particular fields */ uint32_t up_sample_fp; /*!< Up-sampling param fp */ uint32_t up_sample_fs; /*!< Up-sampling param fs */ @@ -221,22 +269,83 @@ typedef struct { typedef struct { gpio_num_t clk; /*!< PDM clk pin, output */ gpio_num_t dout; /*!< DATA pin, output */ + struct { + uint32_t clk_inv: 1; /*!< Set 1 to invert the clk output */ + } invert_flags; /*!< GPIO pin invert flags */ } i2s_pdm_tx_gpio_config_t; -typedef struct -{ - i2s_pdm_tx_clk_config_t clk_cfg; - i2s_pdm_tx_slot_config_t slot_cfg; - i2s_pdm_tx_gpio_config_t gpio_cfg; +/** + * @brief I2S PDM TX mode major configuration that including clock/slot/gpio configuration + */ +typedef struct { + i2s_pdm_tx_clk_config_t clk_cfg; /*!< PDM TX clock configurations, can be genertated by macro I2S_PDM_TX_CLK_DEFAULT_CONFIG */ + i2s_pdm_tx_slot_config_t slot_cfg; /*!< PDM TX slot configurations, can be genertated by macro I2S_PDM_TX_SLOT_DEFAULT_CONFIG */ + i2s_pdm_tx_gpio_config_t gpio_cfg; /*!< PDM TX gpio configurations, specified by user */ } i2s_pdm_tx_config_t; -esp_err_t i2s_init_pdm_tx_channel(i2s_chan_handle_t handle, const i2s_pdm_tx_config_t *pdm_tx_cfg); +/** + * @brief Initialize i2s channel to PDM TX mode + * @note Only allowed to be called when the channel state is REGISTERED, (i.e., channel has been allocated, but not initialized) + * and the state will be updated to READY if initialization success, otherwise the state will return to REGISTERED. + * + * @param[in] handle I2S tx channel handler + * @param[in] pdm_tx_cfg Configurations for PDM TX mode, including clock, slot and gpio + * The clock configuration can be generated by the helper macro `I2S_PDM_TX_CLK_DEFAULT_CONFIG` + * The slot configuration can be generated by the helper macro `I2S_PDM_TX_SLOT_DEFAULT_CONFIG` + * + * @return + * - ESP_OK Initialize successfully + * - ESP_ERR_NO_MEM No memory for storing the channel information + * - ESP_ERR_INVALID_ARG NULL pointer or invalid configuration + * - ESP_ERR_INVALID_STATE This channel is not registered + */ +esp_err_t i2s_channel_init_pdm_tx_mode(i2s_chan_handle_t handle, const i2s_pdm_tx_config_t *pdm_tx_cfg); -esp_err_t i2s_reconfig_pdm_tx_clock(i2s_chan_handle_t handle, const i2s_pdm_tx_clk_config_t *clk_cfg); +/** + * @brief Reconfigure the I2S clock for PDM TX mode + * @note Only allowed to be called when the channel state is READY, i.e., channel has been initialized, but not started + * this function won't change the state. 'i2s_channel_disable' should be called before calling this function if i2s has started. + * @note The input channel handle has to be initialized to PDM TX mode, i.e., 'i2s_channel_init_pdm_tx_mode' has been called before reconfigring + * + * @param[in] handle I2S tx channel handler + * @param[in] clk_cfg PDM TX mode clock configuration, can be generated by `I2S_PDM_TX_CLK_DEFAULT_CONFIG` + * @return + * - ESP_OK Set clock successfully + * - ESP_ERR_INVALID_ARG NULL pointer, invalid configuration or not PDM mode + * - ESP_ERR_INVALID_STATE This channel is not initialized or not stopped + */ +esp_err_t i2s_channel_reconfig_pdm_tx_clock(i2s_chan_handle_t handle, const i2s_pdm_tx_clk_config_t *clk_cfg); -esp_err_t i2s_reconfig_pdm_tx_slot(i2s_chan_handle_t handle, const i2s_pdm_tx_slot_config_t *slot_cfg); +/** + * @brief Reconfigure the I2S slot for PDM TX mode + * @note Only allowed to be called when the channel state is READY, i.e., channel has been initialized, but not started + * this function won't change the state. 'i2s_channel_disable' should be called before calling this function if i2s has started. + * @note The input channel handle has to be initialized to PDM TX mode, i.e., 'i2s_channel_init_pdm_tx_mode' has been called before reconfigring + * + * @param[in] handle I2S tx channel handler + * @param[in] slot_cfg PDM TX mode slot configuration, can be generated by `I2S_PDM_TX_SLOT_DEFAULT_CONFIG` + * @return + * - ESP_OK Set clock successfully + * - ESP_ERR_NO_MEM No memory for DMA buffer + * - ESP_ERR_INVALID_ARG NULL pointer, invalid configuration or not PDM mode + * - ESP_ERR_INVALID_STATE This channel is not initialized or not stopped + */ +esp_err_t i2s_channel_reconfig_pdm_tx_slot(i2s_chan_handle_t handle, const i2s_pdm_tx_slot_config_t *slot_cfg); -esp_err_t i2s_reconfig_pdm_tx_gpio(i2s_chan_handle_t handle, const i2s_pdm_tx_gpio_config_t *gpio_cfg); +/** + * @brief Reconfigure the I2S gpio for PDM TX mode + * @note Only allowed to be called when the channel state is READY, i.e., channel has been initialized, but not started + * this function won't change the state. 'i2s_channel_disable' should be called before calling this function if i2s has started. + * @note The input channel handle has to be initialized to PDM TX mode, i.e., 'i2s_channel_init_pdm_tx_mode' has been called before reconfigring + * + * @param[in] handle I2S tx channel handler + * @param[in] gpio_cfg PDM TX mode gpio configuration, specified by user + * @return + * - ESP_OK Set clock successfully + * - ESP_ERR_INVALID_ARG NULL pointer, invalid configuration or not PDM mode + * - ESP_ERR_INVALID_STATE This channel is not initialized or not stopped + */ +esp_err_t i2s_channel_reconfig_pdm_tx_gpio(i2s_chan_handle_t handle, const i2s_pdm_tx_gpio_config_t *gpio_cfg); #endif // SOC_I2S_SUPPORTS_PDM_TX diff --git a/components/driver/include/driver/i2s_std.h b/components/driver/include/driver/i2s_std.h index 12f95130ff..06cbf58b69 100644 --- a/components/driver/include/driver/i2s_std.h +++ b/components/driver/include/driver/i2s_std.h @@ -30,12 +30,12 @@ extern "C" { .data_bit_width = bits_per_sample, \ .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \ .slot_mode = mono_or_stereo, \ + .slot_mask = (mono_or_stereo == I2S_SLOT_MODE_MONO) ? \ + I2S_STD_SLOT_ONLY_LEFT : I2S_STD_SLOT_LEFT_RIGHT, \ .ws_width = bits_per_sample, \ .ws_pol = false, \ .bit_shift = true, \ - .slot_sel = (mono_or_stereo == I2S_SLOT_MODE_MONO) ? \ - I2S_STD_SLOT_ONLY_LEFT : I2S_STD_SLOT_LEFT_RIGHT, \ - .msb_right = false, \ + .msb_right = true, \ } /** @@ -48,12 +48,12 @@ extern "C" { .data_bit_width = bits_per_sample, \ .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \ .slot_mode = mono_or_stereo, \ + .slot_mask = (mono_or_stereo == I2S_SLOT_MODE_MONO) ? \ + I2S_STD_SLOT_ONLY_LEFT : I2S_STD_SLOT_LEFT_RIGHT, \ .ws_width = 1, \ .ws_pol = true, \ .bit_shift = true, \ - .slot_sel = (mono_or_stereo == I2S_SLOT_MODE_MONO) ? \ - I2S_STD_SLOT_ONLY_LEFT : I2S_STD_SLOT_LEFT_RIGHT, \ - .msb_right = false, \ + .msb_right = true, \ } /** @@ -65,12 +65,12 @@ extern "C" { .data_bit_width = bits_per_sample, \ .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \ .slot_mode = mono_or_stereo, \ + .slot_mask = (mono_or_stereo == I2S_SLOT_MODE_MONO) ? \ + I2S_STD_SLOT_ONLY_LEFT : I2S_STD_SLOT_LEFT_RIGHT, \ .ws_width = bits_per_sample, \ .ws_pol = false, \ .bit_shift = false, \ - .slot_sel = (mono_or_stereo == I2S_SLOT_MODE_MONO) ? \ - I2S_STD_SLOT_ONLY_LEFT : I2S_STD_SLOT_LEFT_RIGHT, \ - .msb_right = false, \ + .msb_right = true, \ } #else @@ -83,11 +83,11 @@ extern "C" { .data_bit_width = bits_per_sample, \ .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \ .slot_mode = mono_or_stereo, \ + .slot_mask = (mono_or_stereo == I2S_SLOT_MODE_MONO) ? \ + I2S_STD_SLOT_ONLY_LEFT : I2S_STD_SLOT_LEFT_RIGHT, \ .ws_width = bits_per_sample, \ .ws_pol = false, \ .bit_shift = true, \ - .slot_sel = (mono_or_stereo == I2S_SLOT_MODE_MONO) ? \ - I2S_STD_SLOT_ONLY_LEFT : I2S_STD_SLOT_LEFT_RIGHT, \ .left_align = false, \ .big_endian = false, \ .bit_order_lsb = false \ @@ -103,11 +103,11 @@ extern "C" { .data_bit_width = bits_per_sample, \ .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \ .slot_mode = mono_or_stereo, \ + .slot_mask = (mono_or_stereo == I2S_SLOT_MODE_MONO) ? \ + I2S_STD_SLOT_ONLY_LEFT : I2S_STD_SLOT_LEFT_RIGHT, \ .ws_width = 1, \ .ws_pol = true, \ .bit_shift = true, \ - .slot_sel = (mono_or_stereo == I2S_SLOT_MODE_MONO) ? \ - I2S_STD_SLOT_ONLY_LEFT : I2S_STD_SLOT_LEFT_RIGHT, \ .left_align = false, \ .big_endian = false, \ .bit_order_lsb = false \ @@ -122,11 +122,11 @@ extern "C" { .data_bit_width = bits_per_sample, \ .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \ .slot_mode = mono_or_stereo, \ + .slot_mask = (mono_or_stereo == I2S_SLOT_MODE_MONO) ? \ + I2S_STD_SLOT_ONLY_LEFT : I2S_STD_SLOT_LEFT_RIGHT, \ .ws_width = bits_per_sample, \ .ws_pol = false, \ .bit_shift = false, \ - .slot_sel = (mono_or_stereo == I2S_SLOT_MODE_MONO) ? \ - I2S_STD_SLOT_ONLY_LEFT : I2S_STD_SLOT_LEFT_RIGHT, \ .left_align = false, \ .big_endian = false, \ .bit_order_lsb = false \ @@ -141,12 +141,12 @@ extern "C" { */ #define I2S_STD_CLK_DEFAULT_CONFIG(rate) { \ .sample_rate_hz = rate, \ - .clk_src = I2S_CLK_PLL_160M, \ + .clk_src = I2S_CLK_SRC_DEFAULT, \ .mclk_multiple = I2S_MCLK_MULTIPLE_256, \ } /** - * @breif I2S slot configuration for standard mode + * @brief I2S slot configuration for standard mode */ typedef struct { /* General fields */ @@ -155,10 +155,10 @@ typedef struct { i2s_slot_mode_t slot_mode; /*!< Set mono or stereo mode with I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO */ /* Particular fields */ + i2s_std_slot_mask_t slot_mask; /*!< Select the left, right or both slot */ uint32_t ws_width; /*!< WS signal width (i.e. the number of bclk ticks that ws signal is high) */ bool ws_pol; /*!< WS signal polarity, set true to enable high lever first */ bool bit_shift; /*!< Set to enbale bit shift in Philip mode */ - i2s_std_slot_sel_t slot_sel; /*!< Select the left, right or both slot */ #if SOC_I2S_HW_VERSION_1 // For esp32/esp32-s2 bool msb_right; /*!< Set to place right channel data at the MSB in the FIFO */ #else @@ -169,7 +169,7 @@ typedef struct { } i2s_std_slot_config_t; /** - * @breif I2S clock configuration for standard mode + * @brief I2S clock configuration for standard mode */ typedef struct { /* General fields */ @@ -187,21 +187,87 @@ typedef struct { gpio_num_t ws; /*!< WS pin, input in slave role, output in master role */ gpio_num_t dout; /*!< DATA pin, output */ gpio_num_t din; /*!< DATA pin, input */ + struct { + uint32_t mclk_inv: 1; /*!< Set 1 to invert the mclk output */ + uint32_t bclk_inv: 1; /*!< Set 1 to invert the bclk input/output */ + uint32_t ws_inv: 1; /*!< Set 1 to invert the ws input/output */ + } invert_flags; /*!< GPIO pin invert flags */ } i2s_std_gpio_config_t; +/** + * @brief I2S standard mode major configuration that including clock/slot/gpio configuration + */ typedef struct { - i2s_std_clk_config_t clk_cfg; /*!< Standard mode clock configuration */ - i2s_std_slot_config_t slot_cfg; /*!< Standard mode slot configuration */ - i2s_std_gpio_config_t gpio_cfg; /*!< Standard mode gpio configuration */ + i2s_std_clk_config_t clk_cfg; /*!< Standard mode clock configuration, can be generated by macro I2S_STD_CLK_DEFAULT_CONFIG */ + i2s_std_slot_config_t slot_cfg; /*!< Standard mode slot configuration, can be generated by macros I2S_STD_[mode]_SLOT_DEFAULT_CONFIG, [mode] can be replaced with PHILIP/MSB/PCM */ + i2s_std_gpio_config_t gpio_cfg; /*!< Standard mode gpio configuration, specified by user */ } i2s_std_config_t; -esp_err_t i2s_init_std_channel(i2s_chan_handle_t handle, const i2s_std_config_t *std_cfg); +/** + * @brief Initialize i2s channel to standard mode + * @note Only allowed to be called when the channel state is REGISTERED, (i.e., channel has been allocated, but not initialized) + * and the state will be updated to READY if initialization success, otherwise the state will return to REGISTERED. + * + * @param[in] handle I2S channel handler + * @param[in] std_cfg Configurations for standard mode, including clock, slot and gpio + * The clock configuration can be generated by the helper macro `I2S_STD_CLK_DEFAULT_CONFIG` + * The slot configuration can be generated by the helper macro `I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG`, + * `I2S_STD_PCM_SLOT_DEFAULT_CONFIG` or `I2S_STD_MSB_SLOT_DEFAULT_CONFIG` + * + * @return + * - ESP_OK Initialize successfully + * - ESP_ERR_NO_MEM No memory for storing the channel information + * - ESP_ERR_INVALID_ARG NULL pointer or invalid configuration + * - ESP_ERR_INVALID_STATE This channel is not registered + */ +esp_err_t i2s_channel_init_std_mode(i2s_chan_handle_t handle, const i2s_std_config_t *std_cfg); -esp_err_t i2s_reconfig_std_clock(i2s_chan_handle_t handle, const i2s_std_clk_config_t *clk_cfg); +/** + * @brief Reconfigure the I2S clock for standard mode + * @note Only allowed to be called when the channel state is READY, i.e., channel has been initialized, but not started + * this function won't change the state. 'i2s_channel_disable' should be called before calling this function if i2s has started. + * @note The input channel handle has to be initialized to standard mode, i.e., 'i2s_channel_init_std_mode' has been called before reconfigring + * + * @param[in] handle I2S channel handler + * @param[in] clk_cfg Standard mode clock configuration, can be generated by `I2S_STD_CLK_DEFAULT_CONFIG` + * @return + * - ESP_OK Set clock successfully + * - ESP_ERR_INVALID_ARG NULL pointer, invalid configuration or not standard mode + * - ESP_ERR_INVALID_STATE This channel is not initialized or not stopped + */ +esp_err_t i2s_channel_reconfig_std_clock(i2s_chan_handle_t handle, const i2s_std_clk_config_t *clk_cfg); -esp_err_t i2s_reconfig_std_slot(i2s_chan_handle_t handle, const i2s_std_slot_config_t *slot_cfg); +/** + * @brief Reconfigure the I2S slot for standard mode + * @note Only allowed to be called when the channel state is READY, i.e., channel has been initialized, but not started + * this function won't change the state. 'i2s_channel_disable' should be called before calling this function if i2s has started. + * @note The input channel handle has to be initialized to standard mode, i.e., 'i2s_channel_init_std_mode' has been called before reconfigring + * + * @param[in] handle I2S channel handler + * @param[in] slot_cfg Standard mode slot configuration, can be generated by `I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG`, + * `I2S_STD_PCM_SLOT_DEFAULT_CONFIG` and `I2S_STD_MSB_SLOT_DEFAULT_CONFIG`. + * @return + * - ESP_OK Set clock successfully + * - ESP_ERR_NO_MEM No memory for DMA buffer + * - ESP_ERR_INVALID_ARG NULL pointer, invalid configuration or not standard mode + * - ESP_ERR_INVALID_STATE This channel is not initialized or not stopped + */ +esp_err_t i2s_channel_reconfig_std_slot(i2s_chan_handle_t handle, const i2s_std_slot_config_t *slot_cfg); -esp_err_t i2s_reconfig_std_gpio(i2s_chan_handle_t handle, const i2s_std_gpio_config_t *gpio_cfg); +/** + * @brief Reconfigure the I2S gpio for standard mode + * @note Only allowed to be called when the channel state is READY, i.e., channel has been initialized, but not started + * this function won't change the state. 'i2s_channel_disable' should be called before calling this function if i2s has started. + * @note The input channel handle has to be initialized to standard mode, i.e., 'i2s_channel_init_std_mode' has been called before reconfigring + * + * @param[in] handle I2S channel handler + * @param[in] gpio_cfg Standard mode gpio configuration, specified by user + * @return + * - ESP_OK Set clock successfully + * - ESP_ERR_INVALID_ARG NULL pointer, invalid configuration or not standard mode + * - ESP_ERR_INVALID_STATE This channel is not initialized or not stopped + */ +esp_err_t i2s_channel_reconfig_std_gpio(i2s_chan_handle_t handle, const i2s_std_gpio_config_t *gpio_cfg); #ifdef __cplusplus } diff --git a/components/driver/include/driver/i2s_tdm.h b/components/driver/include/driver/i2s_tdm.h index 56fd9464e7..9a7db55478 100644 --- a/components/driver/include/driver/i2s_tdm.h +++ b/components/driver/include/driver/i2s_tdm.h @@ -31,10 +31,10 @@ extern "C" { * @param mask active slot mask */ #define I2S_TDM_PHILIP_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo, mask) { \ - .mode = I2S_COMM_MODE_TDM, \ .data_bit_width = (bits_per_sample), \ .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \ .slot_mode = mono_or_stereo, \ + .slot_mask = (mask), \ .ws_width = I2S_TDM_AUTO_WS_WIDTH, \ .ws_pol = false, \ .bit_shift = true, \ @@ -42,7 +42,6 @@ extern "C" { .big_endian = false, \ .bit_order_lsb = false, \ .skip_mask = false, \ - .slot_mask = (mask), \ .total_slot = I2S_TDM_AUTO_SLOT_NUM \ } @@ -53,10 +52,10 @@ extern "C" { * @param mask active slot mask */ #define I2S_TDM_MSB_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo, mask) { \ - .mode = I2S_COMM_MODE_TDM, \ .data_bit_width = (bits_per_sample), \ .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \ .slot_mode = mono_or_stereo, \ + .slot_mask = (mask), \ .ws_width = I2S_TDM_AUTO_WS_WIDTH, \ .ws_pol = false, \ .bit_shift = false, \ @@ -64,7 +63,6 @@ extern "C" { .big_endian = false, \ .bit_order_lsb = false, \ .skip_mask = false ,\ - .slot_mask = (mask), \ .total_slot = I2S_TDM_AUTO_SLOT_NUM \ } @@ -75,10 +73,10 @@ extern "C" { * @param mask active slot mask */ #define I2S_TDM_PCM_SHORT_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo, mask) { \ - .mode = I2S_COMM_MODE_TDM, \ .data_bit_width = (bits_per_sample), \ .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \ .slot_mode = mono_or_stereo, \ + .slot_mask = (mask), \ .ws_width = 1, \ .ws_pol = true, \ .bit_shift = true, \ @@ -86,7 +84,6 @@ extern "C" { .big_endian = false, \ .bit_order_lsb = false, \ .skip_mask = false, \ - .slot_mask = (mask), \ .total_slot = I2S_TDM_AUTO_SLOT_NUM \ } @@ -97,10 +94,10 @@ extern "C" { * @param mask active slot mask */ #define I2S_TDM_PCM_LONG_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo, mask) { \ - .mode = I2S_COMM_MODE_TDM, \ .data_bit_width = (bits_per_sample), \ .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \ .slot_mode = mono_or_stereo, \ + .slot_mask = (mask), \ .ws_width = (bits_per_sample), \ .ws_pol = true, \ .bit_shift = true, \ @@ -108,7 +105,6 @@ extern "C" { .big_endian = false, \ .bit_order_lsb = false, \ .skip_mask = false, \ - .slot_mask = (mask), \ .total_slot = I2S_TDM_AUTO_SLOT_NUM \ } @@ -120,22 +116,22 @@ extern "C" { */ #define I2S_TDM_CLK_DEFAULT_CONFIG(rate) { \ .sample_rate_hz = rate, \ - .clk_src = I2S_CLK_PLL_160M, \ + .clk_src = I2S_CLK_SRC_DEFAULT, \ .mclk_multiple = I2S_MCLK_MULTIPLE_256, \ } /** - * @breif I2S slot configuration for tdm mode + * @brief I2S slot configuration for tdm mode */ typedef struct { /* General fields */ - i2s_comm_mode_t mode; /*!< I2S communication mode, this field is for identification (MUST match the communication mode in 'i2s_chan_config_t') */ i2s_data_bit_width_t data_bit_width; /*!< I2S sample data bit width (valid data bits per sample) */ i2s_slot_bit_width_t slot_bit_width; /*!< I2S slot bit width (total bits per slot) */ i2s_slot_mode_t slot_mode; /*!< Set mono or stereo mode with I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO */ /* Particular fields */ - uint32_t ws_width; /*!< WS signal width ((i.e. the number of bclk ticks that ws signal is high)) */ + i2s_tdm_slot_mask_t slot_mask; /*!< Slot mask. Activating slots by setting 1 to corresponding bits. When the activated slots is not consecutive, those data in unactivated slots will be ignored */ + uint32_t ws_width; /*!< WS signal width (i.e. the number of bclk ticks that ws signal is high) */ bool ws_pol; /*!< WS signal polarity, set true to enable high lever first */ bool bit_shift; /*!< Set true to enable bit shift in Philip mode */ @@ -144,12 +140,11 @@ typedef struct { bool bit_order_lsb; /*!< Set true to enable lsb first */ bool skip_mask; /*!< Set true to enable skip mask. If it is enabled, only the data of the enabled channels will be sent, otherwise all data stored in DMA TX buffer will be sent */ - i2s_tdm_slot_mask_t slot_mask; /*!< Slot mask. Activating slots by setting 1 to corresponding bits. When the activated slots is not consecutive, those data in unactivated slots will be ignored */ uint32_t total_slot; /*!< I2S total number of slots. If it is smaller than the biggest activated channel number, it will be set to this number automatically. */ } i2s_tdm_slot_config_t; /** - * @breif I2S clock configuration for tdm mode + * @brief I2S clock configuration for tdm mode */ typedef struct { /* General fields */ @@ -167,21 +162,87 @@ typedef struct { gpio_num_t ws; /*!< WS pin, input in slave role, output in master role */ gpio_num_t dout; /*!< DATA pin, output */ gpio_num_t din; /*!< DATA pin, input */ + struct { + uint32_t mclk_inv: 1; /*!< Set 1 to invert the mclk output */ + uint32_t bclk_inv: 1; /*!< Set 1 to invert the bclk input/output */ + uint32_t ws_inv: 1; /*!< Set 1 to invert the ws input/output */ + } invert_flags; /*!< GPIO pin invert flags */ } i2s_tdm_gpio_config_t; +/** + * @brief I2S TDM mode major configuration that including clock/slot/gpio configuration + */ typedef struct { - i2s_tdm_clk_config_t clk_cfg; /*!< TDM mode clock configuration */ - i2s_tdm_slot_config_t slot_cfg; /*!< TDM mode slot configuration */ - i2s_tdm_gpio_config_t gpio_cfg; /*!< TDM mode gpio configuration */ + i2s_tdm_clk_config_t clk_cfg; /*!< TDM mode clock configuration, can be generated by macro I2S_TDM_CLK_DEFAULT_CONFIG */ + i2s_tdm_slot_config_t slot_cfg; /*!< TDM mode slot configuration, can be generated by macros I2S_TDM_[mode]_SLOT_DEFAULT_CONFIG, [mode] can be replaced with PHILIP/MSB/PCM_SHORT/PCM_LONG */ + i2s_tdm_gpio_config_t gpio_cfg; /*!< TDM mode gpio configuration, specified by user */ } i2s_tdm_config_t; -esp_err_t i2s_init_tdm_channel(i2s_chan_handle_t handle, const i2s_tdm_config_t *std_cfg); +/** + * @brief Initialize i2s channel to TDM mode + * @note Only allowed to be called when the channel state is REGISTERED, (i.e., channel has been allocated, but not initialized) + * and the state will be updated to READY if initialization success, otherwise the state will return to REGISTERED. + * + * @param[in] handle I2S channel handler + * @param[in] tdm_cfg Configurations for TDM mode, including clock, slot and gpio + * The clock configuration can be generated by the helper macro `I2S_TDM_CLK_DEFAULT_CONFIG` + * The slot configuration can be generated by the helper macro `I2S_TDM_PHILIP_SLOT_DEFAULT_CONFIG`, + * `I2S_TDM_PCM_SHORT_SLOT_DEFAULT_CONFIG`, `I2S_TDM_PCM_LONG_SLOT_DEFAULT_CONFIG` or `I2S_TDM_MSB_SLOT_DEFAULT_CONFIG` + * + * @return + * - ESP_OK Initialize successfully + * - ESP_ERR_NO_MEM No memory for storing the channel information + * - ESP_ERR_INVALID_ARG NULL pointer or invalid configuration + * - ESP_ERR_INVALID_STATE This channel is not registered + */ +esp_err_t i2s_channel_init_tdm_mode(i2s_chan_handle_t handle, const i2s_tdm_config_t *tdm_cfg); -esp_err_t i2s_reconfig_tdm_clock(i2s_chan_handle_t handle, const i2s_tdm_clk_config_t *clk_cfg); +/** + * @brief Reconfigure the I2S clock for TDM mode + * @note Only allowed to be called when the channel state is READY, i.e., channel has been initialized, but not started + * this function won't change the state. 'i2s_channel_disable' should be called before calling this function if i2s has started. + * @note The input channel handle has to be initialized to TDM mode, i.e., 'i2s_channel_init_tdm_mode' has been called before reconfigring + * + * @param[in] handle I2S channel handler + * @param[in] clk_cfg Standard mode clock configuration, can be generated by `I2S_TDM_CLK_DEFAULT_CONFIG` + * @return + * - ESP_OK Set clock successfully + * - ESP_ERR_INVALID_ARG NULL pointer, invalid configuration or not TDM mode + * - ESP_ERR_INVALID_STATE This channel is not initialized or not stopped + */ +esp_err_t i2s_channel_reconfig_tdm_clock(i2s_chan_handle_t handle, const i2s_tdm_clk_config_t *clk_cfg); -esp_err_t i2s_reconfig_tdm_slot(i2s_chan_handle_t handle, const i2s_tdm_slot_config_t *slot_cfg); +/** + * @brief Reconfigure the I2S slot for TDM mode + * @note Only allowed to be called when the channel state is READY, i.e., channel has been initialized, but not started + * this function won't change the state. 'i2s_channel_disable' should be called before calling this function if i2s has started. + * @note The input channel handle has to be initialized to TDM mode, i.e., 'i2s_channel_init_tdm_mode' has been called before reconfigring + * + * @param[in] handle I2S channel handler + * @param[in] slot_cfg Standard mode slot configuration, can be generated by `I2S_TDM_PHILIP_SLOT_DEFAULT_CONFIG`, + * `I2S_TDM_PCM_SHORT_SLOT_DEFAULT_CONFIG`, `I2S_TDM_PCM_LONG_SLOT_DEFAULT_CONFIG` or `I2S_TDM_MSB_SLOT_DEFAULT_CONFIG`. + * @return + * - ESP_OK Set clock successfully + * - ESP_ERR_NO_MEM No memory for DMA buffer + * - ESP_ERR_INVALID_ARG NULL pointer, invalid configuration or not TDM mode + * - ESP_ERR_INVALID_STATE This channel is not initialized or not stopped + */ +esp_err_t i2s_channel_reconfig_tdm_slot(i2s_chan_handle_t handle, const i2s_tdm_slot_config_t *slot_cfg); -esp_err_t i2s_reconfig_tdm_gpio(i2s_chan_handle_t handle, const i2s_tdm_gpio_config_t *gpio_cfg); +/** + * @brief Reconfigure the I2S gpio for TDM mode + * @note Only allowed to be called when the channel state is READY, i.e., channel has been initialized, but not started + * this function won't change the state. 'i2s_channel_disable' should be called before calling this function if i2s has started. + * @note The input channel handle has to be initialized to TDM mode, i.e., 'i2s_channel_init_tdm_mode' has been called before reconfigring + * + * @param[in] handle I2S channel handler + * @param[in] gpio_cfg Standard mode gpio configuration, specified by user + * @return + * - ESP_OK Set clock successfully + * - ESP_ERR_INVALID_ARG NULL pointer, invalid configuration or not TDM mode + * - ESP_ERR_INVALID_STATE This channel is not initialized or not stopped + */ +esp_err_t i2s_channel_reconfig_tdm_gpio(i2s_chan_handle_t handle, const i2s_tdm_gpio_config_t *gpio_cfg); #ifdef __cplusplus diff --git a/components/driver/include/driver/i2s_types.h b/components/driver/include/driver/i2s_types.h new file mode 100644 index 0000000000..9709d91c71 --- /dev/null +++ b/components/driver/include/driver/i2s_types.h @@ -0,0 +1,79 @@ +/* + * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include +#include "soc/soc_caps.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief I2S controller port number, the max port number is (SOC_I2S_NUM -1). + */ +typedef enum { + I2S_NUM_0 = 0, /*!< I2S controller port 0 */ +#if SOC_I2S_NUM > 1 + I2S_NUM_1 = 1, /*!< I2S controller port 1 */ +#endif + I2S_NUM_AUTO, /*!< Select whichever port is available */ +} i2s_port_t; + +/** + * @brief I2S controller communication mode + */ +typedef enum { + I2S_COMM_MODE_STD, /*!< I2S controller using standard communication mode, support philip/MSB/PCM format */ +#if SOC_I2S_SUPPORTS_PDM + I2S_COMM_MODE_PDM, /*!< I2S controller using PDM communication mode, support PDM output or input */ +#endif +#if SOC_I2S_SUPPORTS_TDM + I2S_COMM_MODE_TDM, /*!< I2S controller using TDM communication mode, support up to 16 slots per frame */ +#endif + I2S_COMM_MODE_NONE, /*!< Unspecified I2S controller mode */ +} i2s_comm_mode_t; + +/** + * @brief The multiple of mclk to sample rate + */ +typedef enum { + I2S_MCLK_MULTIPLE_128 = 128, /*!< mclk = sample_rate * 128 */ + I2S_MCLK_MULTIPLE_256 = 256, /*!< mclk = sample_rate * 256 */ + I2S_MCLK_MULTIPLE_384 = 384, /*!< mclk = sample_rate * 384 */ +} i2s_mclk_multiple_t; + +/** + * @brief Event structure used in I2S event queue + */ +typedef struct { + void *data; /**< The pointer of DMA buffer that just finished sending or receiving for `on_recv` and `on_sent` callback + * NULL for `on_recv_q_ovf` and `on_send_q_ovf` callback + */ + size_t size; /**< The buffer size of DMA buffer when success to send or receive, + * also the buffer size that dropped when queue overflow. + * It is related to the dma_frame_num and data_bit_width, typically it is fixed when data_bit_width is not changed. + */ +} i2s_event_data_t; + +typedef struct i2s_channel_t *i2s_chan_handle_t; /*!< i2s channel handle, the control unit of the i2s driver*/ + +/** + * @brief I2S event callback + * @param[in] handle I2S channel handle, created from `i2s_new_channel()` + * @param[in] event I2S event data + * @param[in] user_ctx User registered context, passed from `i2s_channel_register_event_callback()` + * + * @return Whether a high priority task has been waken up by this callback function + */ +typedef bool (*i2s_isr_callback_t)(i2s_chan_handle_t handle, i2s_event_data_t *event, void *user_ctx); + +#ifdef __cplusplus +} +#endif diff --git a/components/driver/include/esp_private/i2s_platform.h b/components/driver/include/esp_private/i2s_platform.h index 7b7a07514e..8deea86a0e 100644 --- a/components/driver/include/esp_private/i2s_platform.h +++ b/components/driver/include/esp_private/i2s_platform.h @@ -10,7 +10,6 @@ #pragma once #include "esp_err.h" -#include "soc/soc_caps.h" #ifdef __cplusplus extern "C" { @@ -44,6 +43,14 @@ esp_err_t i2s_platform_acquire_occupation(int id, const char *comp_name); */ esp_err_t i2s_platform_release_occupation(int id); +/** + * @brief This function is only used for getting DMA buffer offset in `test_i2s_iram.c` + * + * @return + * - The offset of DMA buffers in the `i2s_chan_handle_t` struct (unit: bytes) + */ +size_t i2s_platform_get_dma_buffer_offset(void); + #ifdef __cplusplus } #endif diff --git a/components/driver/test/test_adc2_with_wifi.c b/components/driver/test/test_adc2_with_wifi.c index 3d944d3c00..d03fc63126 100644 --- a/components/driver/test/test_adc2_with_wifi.c +++ b/components/driver/test/test_adc2_with_wifi.c @@ -257,7 +257,7 @@ static void adc_dma_init(void) static void continuous_adc_test(void) { uint16_t *adcReadBuffer = (uint16_t *)calloc(1024, sizeof(uint16_t)); - size_t bytesRead; + uint32_t bytesRead; for (int loop = 0; loop < 10; loop++) { for (int level = 0; level <= 1; level++) { if (level == 0) { diff --git a/components/driver/test_apps/i2s/app_test.py b/components/driver/test_apps/i2s/app_test.py deleted file mode 100644 index 1583ff5709..0000000000 --- a/components/driver/test_apps/i2s/app_test.py +++ /dev/null @@ -1,30 +0,0 @@ -# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD -# SPDX-License-Identifier: Apache-2.0 -import glob -import os - -import ttfw_idf -from tiny_test_fw import Utility - - -@ttfw_idf.idf_component_unit_test(env_tag='COMPONENT_UT_GENERIC', target=['esp32', 'esp32s2', 'esp32s3', 'esp32c3']) -def test_component_ut_i2s(env, _): # type: (ttfw_idf.TinyFW.Env, None) -> None - # Get the names of all configs (sdkconfig.ci.* files) - config_files = glob.glob(os.path.join(os.path.dirname(__file__), 'sdkconfig.ci.*')) - config_names = [os.path.basename(s).replace('sdkconfig.ci.', '') for s in config_files] - - # Run test once with binaries built for each config - for name in config_names: - Utility.console_log(f'Checking config "{name}"... ', end='') - dut = env.get_dut('i2s', 'components/driver/test_apps/i2s', app_config_name=name) - dut.start_app() - stdout = dut.expect('Press ENTER to see the list of tests', full_stdout=True) - dut.write('*') - stdout = dut.expect("Enter next test, or 'enter' to see menu", full_stdout=True, timeout=30) - ttfw_idf.ComponentUTResult.parse_result(stdout,ttfw_idf.TestFormat.UNITY_BASIC) - env.close_dut(dut.name) - Utility.console_log(f'Test config "{name}" done') - - -if __name__ == '__main__': - test_component_ut_i2s() diff --git a/components/driver/test_apps/i2s/main/CMakeLists.txt b/components/driver/test_apps/i2s/main/CMakeLists.txt deleted file mode 100644 index 89b0c08d6c..0000000000 --- a/components/driver/test_apps/i2s/main/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -set(srcs "test_app_main.c") - -if(CONFIG_SOC_I2S_SUPPORTED) - list(APPEND srcs "test_i2s.c" - "test_i2s_legacy.c") -endif() - - -idf_component_register(SRCS ${srcs} - PRIV_REQUIRES driver hal soc unity) - -if(CONFIG_SOC_I2S_SUPPORTED) - target_link_libraries(${COMPONENT_LIB} INTERFACE - "-u test_app_include_i2s" - "-u test_app_include_i2s_legacy") -endif() diff --git a/components/driver/test_apps/i2s/main/test_i2s.c b/components/driver/test_apps/i2s/main/test_i2s.c deleted file mode 100644 index 07ee608b93..0000000000 --- a/components/driver/test_apps/i2s/main/test_i2s.c +++ /dev/null @@ -1,538 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * I2S test environment UT_T1_I2S: - * We use internal signals instead of external wiring, but please keep the following IO connections, or connect nothing to prevent the signal from being disturbed. - * connect GPIO15 and GPIO19, GPIO25(ESP32)/GPIO17(ESP32-S2) and GPIO26, GPIO21 and GPIO22(ESP32)/GPIO20(ESP32-S2) - * Please do not connect GPIO32(ESP32) any pull-up resistors externally, it will be used to test i2s adc function. - */ - - -#include -#include -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/queue.h" -#include "freertos/semphr.h" -#include "driver/gpio.h" -#include "hal/gpio_hal.h" -#include "esp_err.h" -#include "unity.h" -#include "math.h" -#include "esp_rom_gpio.h" -#include "soc/i2s_periph.h" -#include "driver/i2s_std.h" -#if SOC_I2S_SUPPORTS_PDM -#include "driver/i2s_pdm.h" -#endif -#if SOC_I2S_SUPPORTS_TDM -#include "driver/i2s_tdm.h" -#endif -#include "hal/i2s_hal.h" -#include "esp_private/i2s_platform.h" -#if SOC_PCNT_SUPPORTED -#include "driver/pulse_cnt.h" -#include "soc/pcnt_periph.h" -#endif - -#define SAMPLE_RATE (48000) -#define SAMPLE_BITS (16) - -#if CONFIG_IDF_TARGET_ESP32 -#define MASTER_MCK_IO 0 -#define MASTER_BCK_IO 4 -#define MASTER_WS_IO 5 -#define SLAVE_BCK_IO 21 -#define SLAVE_WS_IO 22 -#define DATA_IN_IO 19 -#define DATA_OUT_IO 18 -#define ADC1_CHANNEL_4_IO 32 -#elif CONFIG_IDF_TARGET_ESP32S2 -#define MASTER_MCK_IO 0 -#define MASTER_BCK_IO 4 -#define MASTER_WS_IO 5 -#define SLAVE_BCK_IO 14 -#define SLAVE_WS_IO 15 -#define DATA_IN_IO 19 -#define DATA_OUT_IO 18 -#elif CONFIG_IDF_TARGET_ESP32C3 -#define MASTER_MCK_IO 0 -#define MASTER_BCK_IO 4 -#define MASTER_WS_IO 5 -#define SLAVE_BCK_IO 14 -#define SLAVE_WS_IO 15 -#define DATA_IN_IO 19 -#define DATA_OUT_IO 18 -#elif CONFIG_IDF_TARGET_ESP32S3 -#define MASTER_MCK_IO 0 -#define MASTER_BCK_IO 4 -#define MASTER_WS_IO 5 -#define SLAVE_BCK_IO 14 -#define SLAVE_WS_IO 15 -#define DATA_IN_IO 19 -#define DATA_OUT_IO 18 -#endif - -#define I2S_TEST_MODE_SLAVE_TO_MASTER 0 -#define I2S_TEST_MODE_MASTER_TO_SLAVE 1 -#define I2S_TEST_MODE_LOOPBACK 2 - -#define I2S_TEST_MASTER_DEFAULT_PIN { \ - .mclk = MASTER_MCK_IO, \ - .bclk = MASTER_BCK_IO, \ - .ws = MASTER_WS_IO, \ - .dout = DATA_OUT_IO, \ - .din = DATA_IN_IO \ - } - -#define I2S_TEST_SLAVE_DEFAULT_PIN { \ - .mclk = -1, \ - .bclk = SLAVE_BCK_IO, \ - .ws = SLAVE_WS_IO, \ - .dout = DATA_OUT_IO, \ - .din = DATA_IN_IO \ - } - -// This empty function is used to force the compiler link this file -void test_app_include_i2s(void) -{ -} - -// mode: 0, master rx, slave tx. mode: 1, master tx, slave rx. mode: 2, master tx rx loop-back -// Since ESP32-S2 has only one I2S, only loop back test can be tested. -static void i2s_test_io_config(int mode) -{ - // Connect internal signals using IO matrix. - gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[MASTER_BCK_IO], PIN_FUNC_GPIO); - gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[MASTER_WS_IO], PIN_FUNC_GPIO); - gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[DATA_OUT_IO], PIN_FUNC_GPIO); - - gpio_set_direction(MASTER_BCK_IO, GPIO_MODE_INPUT_OUTPUT); - gpio_set_direction(MASTER_WS_IO, GPIO_MODE_INPUT_OUTPUT); - gpio_set_direction(DATA_OUT_IO, GPIO_MODE_INPUT_OUTPUT); - - switch (mode) { -#if SOC_I2S_NUM > 1 - case I2S_TEST_MODE_SLAVE_TO_MASTER: { - esp_rom_gpio_connect_out_signal(MASTER_BCK_IO, i2s_periph_signal[0].m_rx_bck_sig, 0, 0); - esp_rom_gpio_connect_in_signal(MASTER_BCK_IO, i2s_periph_signal[1].s_tx_bck_sig, 0); - - esp_rom_gpio_connect_out_signal(MASTER_WS_IO, i2s_periph_signal[0].m_rx_ws_sig, 0, 0); - esp_rom_gpio_connect_in_signal(MASTER_WS_IO, i2s_periph_signal[1].s_tx_ws_sig, 0); - - esp_rom_gpio_connect_out_signal(DATA_OUT_IO, i2s_periph_signal[1].data_out_sig, 0, 0); - esp_rom_gpio_connect_in_signal(DATA_OUT_IO, i2s_periph_signal[0].data_in_sig, 0); - } - break; - - case I2S_TEST_MODE_MASTER_TO_SLAVE: { - esp_rom_gpio_connect_out_signal(MASTER_BCK_IO, i2s_periph_signal[0].m_tx_bck_sig, 0, 0); - esp_rom_gpio_connect_in_signal(MASTER_BCK_IO, i2s_periph_signal[1].s_rx_bck_sig, 0); - - esp_rom_gpio_connect_out_signal(MASTER_WS_IO, i2s_periph_signal[0].m_tx_ws_sig, 0, 0); - esp_rom_gpio_connect_in_signal(MASTER_WS_IO, i2s_periph_signal[1].s_rx_ws_sig, 0); - - esp_rom_gpio_connect_out_signal(DATA_OUT_IO, i2s_periph_signal[0].data_out_sig, 0, 0); - esp_rom_gpio_connect_in_signal(DATA_OUT_IO, i2s_periph_signal[1].data_in_sig, 0); - } - break; -#endif - case I2S_TEST_MODE_LOOPBACK: { - esp_rom_gpio_connect_out_signal(DATA_OUT_IO, i2s_periph_signal[0].data_out_sig, 0, 0); - esp_rom_gpio_connect_in_signal(DATA_OUT_IO, i2s_periph_signal[0].data_in_sig, 0); - } - break; - - default: { - TEST_FAIL_MESSAGE("error: mode not supported"); - } - break; - } -} - -static void i2s_read_write_test(i2s_chan_handle_t tx_chan, i2s_chan_handle_t rx_chan) -{ -#define I2S_SEND_BUF_LEN 100 -#define I2S_RECV_BUF_LEN 10000 - - size_t bytes_write = 0; - size_t bytes_read = 0; - - bool is_success = false; - - uint8_t *send_buf = (uint8_t *)calloc(I2S_SEND_BUF_LEN, sizeof(uint8_t)); - TEST_ASSERT_NOT_NULL(send_buf); - uint8_t *recv_buf = (uint8_t *)calloc(I2S_RECV_BUF_LEN, sizeof(uint8_t)); - TEST_ASSERT_NOT_NULL(recv_buf); - - for (int i = 0; i < I2S_SEND_BUF_LEN; i++) { - send_buf[i] = i + 1; - } - - // write data to slave - TEST_ESP_OK(i2s_write_channel(tx_chan, send_buf, I2S_SEND_BUF_LEN, &bytes_write, 1000 / portTICK_PERIOD_MS)); - TEST_ESP_OK(i2s_read_channel(rx_chan, recv_buf, I2S_RECV_BUF_LEN, &bytes_read, 1000 / portTICK_PERIOD_MS)); - TEST_ASSERT_EQUAL_INT32(I2S_SEND_BUF_LEN, bytes_write); - TEST_ASSERT_EQUAL_INT32(I2S_RECV_BUF_LEN, bytes_read); - // test the read data right or not - for (int i = 0, j = 0; i < (I2S_RECV_BUF_LEN - I2S_SEND_BUF_LEN); i++) { - if (recv_buf[i] == 1) { - for (j = 1; (j < I2S_SEND_BUF_LEN) && (recv_buf[i+j] == j + 1); j++) {} - if (j == I2S_SEND_BUF_LEN) { - is_success = true; - goto finish; - } - i += j; - } - } -finish: - free(send_buf); - free(recv_buf); - TEST_ASSERT(is_success); -} - -// To check if the software logic of I2S driver is correct -TEST_CASE("I2S basic driver apply, delete test", "[i2s]") -{ - - i2s_chan_handle_t tx_handle; - i2s_chan_handle_t rx_handle; - - i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER); - i2s_std_config_t std_cfg = { - .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(SAMPLE_RATE), - .slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO), - .gpio_cfg = I2S_TEST_MASTER_DEFAULT_PIN, - }; - - /* TX channel basic test */ - TEST_ESP_OK(i2s_new_channel(&chan_cfg, &tx_handle, NULL)); - - TEST_ESP_OK(i2s_init_std_channel(tx_handle, &std_cfg)); - std_cfg.slot_cfg.data_bit_width = I2S_DATA_BIT_WIDTH_32BIT; - TEST_ESP_OK(i2s_reconfig_std_slot(tx_handle, &std_cfg.slot_cfg)); - std_cfg.clk_cfg.sample_rate_hz = 44100; - TEST_ESP_OK(i2s_reconfig_std_clock(tx_handle, &std_cfg.clk_cfg)); - TEST_ESP_OK(i2s_start_channel(tx_handle)); - TEST_ESP_OK(i2s_del_channel(tx_handle)); - - /* Duplex channel basic test */ - chan_cfg.id = I2S_NUM_0; // Specify port id to I2S port 0 - TEST_ESP_OK(i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle)); - TEST_ESP_OK(i2s_init_std_channel(tx_handle, &std_cfg)); - TEST_ESP_OK(i2s_init_std_channel(rx_handle, &std_cfg)); - TEST_ESP_OK(i2s_del_channel(tx_handle)); - TEST_ESP_OK(i2s_del_channel(rx_handle)); - - /* Repeat to check if a same port can be allocated again */ - TEST_ESP_OK(i2s_new_channel(&chan_cfg, NULL, &rx_handle)); - TEST_ESP_OK(i2s_del_channel(rx_handle)); - - /* Hold the occupation */ - TEST_ESP_OK(i2s_platform_acquire_occupation(I2S_NUM_0, "test_i2s")); - TEST_ASSERT(i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle) == ESP_ERR_NOT_FOUND); - TEST_ESP_OK(i2s_platform_release_occupation(I2S_NUM_0)); - TEST_ESP_OK(i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle)); - TEST_ESP_OK(i2s_del_channel(tx_handle)); - TEST_ESP_OK(i2s_del_channel(rx_handle)); -} - -TEST_CASE("I2S memory leak test", "[i2s]") -{ - i2s_chan_handle_t tx_handle; - i2s_chan_handle_t rx_handle; - - i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER); - i2s_std_config_t std_cfg = { - .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(SAMPLE_RATE), - .slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO), - .gpio_cfg = I2S_TEST_MASTER_DEFAULT_PIN, - }; - - /* The first operation will always take some memory */ - TEST_ESP_OK(i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle)); - TEST_ESP_OK(i2s_init_std_channel(tx_handle, &std_cfg)); - TEST_ESP_OK(i2s_init_std_channel(rx_handle, &std_cfg)); - TEST_ESP_OK(i2s_del_channel(tx_handle)); - TEST_ESP_OK(i2s_del_channel(rx_handle)); - - int memory_left = esp_get_free_heap_size(); - printf("\r\nHeap size before: %d\n", memory_left); - for (int i = 0; i < 100; i++) { - TEST_ESP_OK(i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle)); - TEST_ESP_OK(i2s_init_std_channel(tx_handle, &std_cfg)); - TEST_ESP_OK(i2s_init_std_channel(rx_handle, &std_cfg)); - TEST_ESP_OK(i2s_del_channel(tx_handle)); - TEST_ESP_OK(i2s_del_channel(rx_handle)); - TEST_ASSERT(memory_left == esp_get_free_heap_size()); - } - printf("\r\nHeap size after: %d\n", esp_get_free_heap_size()); -} - -TEST_CASE("I2S loopback test", "[i2s]") -{ - i2s_chan_handle_t tx_handle; - i2s_chan_handle_t rx_handle; - - i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER); - i2s_std_config_t std_cfg = { - .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(SAMPLE_RATE), - .slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO), - .gpio_cfg = I2S_TEST_MASTER_DEFAULT_PIN, - }; - TEST_ESP_OK(i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle)); - TEST_ESP_OK(i2s_init_std_channel(tx_handle, &std_cfg)); - TEST_ESP_OK(i2s_init_std_channel(rx_handle, &std_cfg)); - i2s_test_io_config(I2S_TEST_MODE_LOOPBACK); - - TEST_ESP_OK(i2s_start_channel(tx_handle)); - TEST_ESP_OK(i2s_start_channel(rx_handle)); - - i2s_read_write_test(tx_handle, rx_handle); - - TEST_ESP_OK(i2s_del_channel(tx_handle)); - TEST_ESP_OK(i2s_del_channel(rx_handle)); -} - -#if SOC_I2S_NUM > 1 -TEST_CASE("I2S master write slave read test", "[i2s]") -{ - i2s_chan_handle_t tx_handle; - i2s_chan_handle_t rx_handle; - - i2s_chan_config_t mst_chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER); - i2s_chan_config_t slv_chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_1, I2S_ROLE_SLAVE); - - i2s_std_config_t std_mst_cfg = { - .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(SAMPLE_RATE), - .slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO), - .gpio_cfg = I2S_TEST_MASTER_DEFAULT_PIN, - }; - - i2s_std_config_t std_slv_cfg = { - .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(SAMPLE_RATE), - .slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO), - .gpio_cfg = I2S_TEST_SLAVE_DEFAULT_PIN, - }; - - TEST_ESP_OK(i2s_new_channel(&mst_chan_cfg, &tx_handle, NULL)); - TEST_ESP_OK(i2s_new_channel(&slv_chan_cfg, NULL, &rx_handle)); - TEST_ESP_OK(i2s_init_std_channel(tx_handle, &std_mst_cfg)); - TEST_ESP_OK(i2s_init_std_channel(rx_handle, &std_slv_cfg)); - i2s_test_io_config(I2S_TEST_MODE_MASTER_TO_SLAVE); - - TEST_ESP_OK(i2s_start_channel(tx_handle)); - TEST_ESP_OK(i2s_start_channel(rx_handle)); - - i2s_read_write_test(tx_handle, rx_handle); - - TEST_ESP_OK(i2s_del_channel(tx_handle)); - TEST_ESP_OK(i2s_del_channel(rx_handle)); -} - -TEST_CASE("I2S master read slave write test", "[i2s]") -{ - i2s_chan_handle_t tx_handle; - i2s_chan_handle_t rx_handle; - - i2s_chan_config_t mst_chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER); - i2s_chan_config_t slv_chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_1, I2S_ROLE_SLAVE); - i2s_std_config_t std_mst_cfg = { - .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(SAMPLE_RATE), - .slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO), - .gpio_cfg = I2S_TEST_MASTER_DEFAULT_PIN, - }; - - i2s_std_config_t std_slv_cfg = { - .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(SAMPLE_RATE), - .slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO), - .gpio_cfg = I2S_TEST_SLAVE_DEFAULT_PIN, - }; - - TEST_ESP_OK(i2s_new_channel(&mst_chan_cfg, NULL, &rx_handle)); - TEST_ESP_OK(i2s_new_channel(&slv_chan_cfg, &tx_handle, NULL)); - TEST_ESP_OK(i2s_init_std_channel(tx_handle, &std_slv_cfg)); - TEST_ESP_OK(i2s_init_std_channel(rx_handle, &std_mst_cfg)); - i2s_test_io_config(I2S_TEST_MODE_SLAVE_TO_MASTER); - - TEST_ESP_OK(i2s_start_channel(tx_handle)); - TEST_ESP_OK(i2s_start_channel(rx_handle)); - - i2s_read_write_test(tx_handle, rx_handle); - - TEST_ESP_OK(i2s_del_channel(tx_handle)); - TEST_ESP_OK(i2s_del_channel(rx_handle)); -} -#endif - -/*------------------------------ Clock Test --------------------------------*/ -#if SOC_PCNT_SUPPORTED -#define TEST_I2S_PERIOD_MS 100 -static void i2s_test_common_sample_rate(i2s_chan_handle_t rx_chan, i2s_std_clk_config_t* clk_cfg) -{ - TEST_ASSERT_NOT_NULL(rx_chan); - TEST_ASSERT_NOT_NULL(clk_cfg); - - /* Prepare configuration for the PCNT unit */ - pcnt_unit_handle_t pcnt_unit = NULL; - pcnt_channel_handle_t pcnt_chan = NULL; - - pcnt_unit_config_t unit_config = { - .high_limit = (int16_t)0x7fff, - .low_limit = (int16_t)0x8000, - }; - pcnt_chan_config_t chan_config = { - .edge_gpio_num = MASTER_WS_IO, - .level_gpio_num = -1, - }; - TEST_ESP_OK(pcnt_new_unit(&unit_config, &pcnt_unit)); - TEST_ESP_OK(pcnt_unit_set_glitch_filter(pcnt_unit, NULL)); - TEST_ESP_OK(pcnt_new_channel(pcnt_unit, &chan_config, &pcnt_chan)); - TEST_ESP_OK(pcnt_channel_set_edge_action(pcnt_chan, PCNT_CHANNEL_EDGE_ACTION_INCREASE, PCNT_CHANNEL_EDGE_ACTION_HOLD)); - TEST_ESP_OK(pcnt_channel_set_level_action(pcnt_chan, PCNT_CHANNEL_LEVEL_ACTION_KEEP, PCNT_CHANNEL_LEVEL_ACTION_KEEP)); - - // Reconfig GPIO signal - gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[MASTER_WS_IO], PIN_FUNC_GPIO); - gpio_set_direction(MASTER_WS_IO, GPIO_MODE_INPUT_OUTPUT); - esp_rom_gpio_connect_out_signal(MASTER_WS_IO, i2s_periph_signal[0].m_rx_ws_sig, 0, 0); - esp_rom_gpio_connect_in_signal(MASTER_WS_IO, pcnt_periph_signals.groups[0].units[0].channels[0].pulse_sig, 0); - - // Test common sample rate - uint32_t test_freq[15] = {8000, 11025, 12000, 16000, 22050, 24000, - 32000, 44100, 48000, 64000, 88200, 96000, - 128000, 144000, 196000}; - int real_pulse = 0; - for (int i = 0; i < 15; i++) { - int expt_pulse = (int)((float)test_freq[i] * (TEST_I2S_PERIOD_MS / 1000.0)); - clk_cfg->sample_rate_hz = test_freq[i]; - TEST_ESP_OK(i2s_reconfig_std_clock(rx_chan, clk_cfg)); - TEST_ESP_OK(i2s_start_channel(rx_chan)); - vTaskDelay(1); // Waiting for hardware totally started - // pcnt will count the pulse number on WS signal in 100ms - TEST_ESP_OK(pcnt_unit_clear_count(pcnt_unit)); - TEST_ESP_OK(pcnt_unit_start(pcnt_unit)); - vTaskDelay(pdMS_TO_TICKS(TEST_I2S_PERIOD_MS)); - TEST_ESP_OK(pcnt_unit_stop(pcnt_unit)); - TEST_ESP_OK(pcnt_unit_get_count(pcnt_unit, &real_pulse)); - printf("[%d Hz] %d pulses, expected %d, err %d\n", test_freq[i], real_pulse, expt_pulse, real_pulse - expt_pulse); - TEST_ESP_OK(i2s_stop_channel(rx_chan)); - // Check if the error between real pulse number and expected pulse number is within 1% - TEST_ASSERT_INT_WITHIN(expt_pulse * 0.01, expt_pulse, real_pulse); - } -} - -TEST_CASE("I2S D2CLK clock test", "[i2s]") -{ - i2s_chan_handle_t rx_handle; - - i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER); - i2s_std_config_t std_cfg = { - .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(SAMPLE_RATE), - .slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO), - .gpio_cfg = I2S_TEST_MASTER_DEFAULT_PIN, - }; - - TEST_ESP_OK(i2s_new_channel(&chan_cfg, NULL, &rx_handle)); - TEST_ESP_OK(i2s_init_std_channel(rx_handle, &std_cfg)); - - i2s_test_common_sample_rate(rx_handle, &std_cfg.clk_cfg); - TEST_ESP_OK(i2s_del_channel(rx_handle)); -} - -#if SOC_I2S_SUPPORTS_APLL -TEST_CASE("I2S APLL clock test", "[i2s]") -{ - i2s_chan_handle_t rx_handle; - - i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER); - i2s_std_config_t std_cfg = { - .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(SAMPLE_RATE), - .slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO), - .gpio_cfg = I2S_TEST_MASTER_DEFAULT_PIN, - }; - std_cfg.clk_cfg.clk_src = I2S_CLK_APLL; - - TEST_ESP_OK(i2s_new_channel(&chan_cfg, NULL, &rx_handle)); - TEST_ESP_OK(i2s_init_std_channel(rx_handle, &std_cfg)); - - i2s_test_common_sample_rate(rx_handle, &std_cfg.clk_cfg); - TEST_ESP_OK(i2s_del_channel(rx_handle)); -} -#endif // SOC_I2S_SUPPORTS_APLL -#endif // SOC_PCNT_SUPPORTED - -static void i2s_event_monitor(void *args) -{ - i2s_chan_handle_t rx_handle = *((i2s_chan_handle_t *)args); - QueueHandle_t evt_que = i2s_get_event_queue(rx_handle, 16); - TEST_ASSERT_NOT_NULL(evt_que); - i2s_event_t evnet; - while (1) { - xQueueReceive(evt_que, &evnet, portMAX_DELAY); - if (evnet.type == I2S_EVENT_RX_Q_OVF) { - break; - } - } - vTaskDelete(NULL); -} - -TEST_CASE("I2S package lost test", "[i2s]") -{ - /* Steps of calculate appropriate parameters of I2S buffer: - * Known by user: sample_rate = 144k, data_bit_width = 32, slot_num = 2, polling_cycle = 10 ms - * 1. dma_buffer_size = dma_frame_num * slot_num * data_bit_width / 8 <= 4092 - * dma_frame_num <= 511, dma_frame_num is as big as possible. - * interrupt_interval = dma_frame_num / sample_rate = 3.549 ms - * 2. dma_desc_num > polling_cycle / interrupt_interval = cell(2.818) = 3 - * 3. recv_buffer_size > dma_desc_num * dma_buffer_size = 3 * 4092 = 12276 bytes */ - #define TEST_RECV_BUF_LEN 12276 - i2s_chan_handle_t rx_handle; - - i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER); - chan_cfg.dma_desc_num = 3; - chan_cfg.dma_frame_num = 511; - i2s_std_config_t std_cfg = { - .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(SAMPLE_RATE), - .slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_STEREO), - .gpio_cfg = I2S_TEST_MASTER_DEFAULT_PIN, - }; - - TEST_ESP_OK(i2s_new_channel(&chan_cfg, NULL, &rx_handle)); - TEST_ESP_OK(i2s_init_std_channel(rx_handle, &std_cfg)); - - TaskHandle_t h_monitor_task; - xTaskCreate(i2s_event_monitor, "event monitor task", 4096, &rx_handle, 5, &h_monitor_task); - - uint32_t test_freq[] = {16000, 32000, 48000, 64000, 96000, 128000, 144000}; - uint32_t test_num = sizeof(test_freq) / sizeof(uint32_t); - uint8_t *data = (uint8_t *)calloc(TEST_RECV_BUF_LEN, sizeof(uint8_t)); - size_t bytes_read = 0; - int i; - for (i = 0; i < test_num; i++) { - printf("Testing %d Hz sample rate\n", test_freq[i]); - std_cfg.clk_cfg.sample_rate_hz = test_freq[i]; - std_cfg.clk_cfg.sample_rate_hz = test_freq[i]; - TEST_ESP_OK(i2s_reconfig_std_clock(rx_handle, &std_cfg.clk_cfg)); - TEST_ESP_OK(i2s_start_channel(rx_handle)); - for (int j = 0; j < 10; j++) { - TEST_ESP_OK(i2s_read_channel(rx_handle, (void *)data, TEST_RECV_BUF_LEN, &bytes_read, portMAX_DELAY)); - // To simulate 10ms delay caused by other statements like data process - vTaskDelay(1); - } - TEST_ESP_OK(i2s_stop_channel(rx_handle)); - if (eTaskGetState(h_monitor_task) == eDeleted) { - printf("package lost detected at %d Hz\n", test_freq[i]); - goto finish; - } - } - vTaskDelete(h_monitor_task); -finish: - TEST_ESP_OK(i2s_del_channel(rx_handle)); - free(data); - // Test failed if package lost within 96000 - TEST_ASSERT(i == test_num); -} diff --git a/components/driver/test_apps/i2s_test_apps/i2s/CMakeLists.txt b/components/driver/test_apps/i2s_test_apps/i2s/CMakeLists.txt new file mode 100644 index 0000000000..1b4b47dae4 --- /dev/null +++ b/components/driver/test_apps/i2s_test_apps/i2s/CMakeLists.txt @@ -0,0 +1,18 @@ +# This is the project CMakeLists.txt file for the test subproject +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(i2s_test) + +if(CONFIG_COMPILER_DUMP_RTL_FILES) + add_custom_target(check_test_app_sections ALL + COMMAND ${PYTHON} $ENV{IDF_PATH}/tools/ci/check_callgraph.py + --rtl-dir ${CMAKE_BINARY_DIR}/esp-idf/driver/ + --elf-file ${CMAKE_BINARY_DIR}/i2s_test.elf + find-refs + --from-sections=.iram0.text + --to-sections=.flash.text,.flash.rodata + --exit-code + DEPENDS ${elf} + ) +endif() diff --git a/components/driver/test_apps/i2s_test_apps/i2s/README.md b/components/driver/test_apps/i2s_test_apps/i2s/README.md new file mode 100644 index 0000000000..36802259d0 --- /dev/null +++ b/components/driver/test_apps/i2s_test_apps/i2s/README.md @@ -0,0 +1,2 @@ +| Supported Targets | ESP32 | ESP32-S2 | ESP32-S3 | ESP32-C3 | +| ----------------- | ----- | -------- | -------- | -------- | \ No newline at end of file diff --git a/components/driver/test_apps/i2s_test_apps/i2s/main/CMakeLists.txt b/components/driver/test_apps/i2s_test_apps/i2s/main/CMakeLists.txt new file mode 100644 index 0000000000..3abecadcbd --- /dev/null +++ b/components/driver/test_apps/i2s_test_apps/i2s/main/CMakeLists.txt @@ -0,0 +1,7 @@ +set(srcs "test_app_main.c" + "test_i2s.c" + "test_i2s_iram.c") + +idf_component_register(SRCS ${srcs} + PRIV_INCLUDE_DIRS "../../" + WHOLE_ARCHIVE) diff --git a/components/driver/test_apps/i2s/main/test_app_main.c b/components/driver/test_apps/i2s_test_apps/i2s/main/test_app_main.c similarity index 100% rename from components/driver/test_apps/i2s/main/test_app_main.c rename to components/driver/test_apps/i2s_test_apps/i2s/main/test_app_main.c diff --git a/components/driver/test_apps/i2s_test_apps/i2s/main/test_i2s.c b/components/driver/test_apps/i2s_test_apps/i2s/main/test_i2s.c new file mode 100644 index 0000000000..bc7badeb80 --- /dev/null +++ b/components/driver/test_apps/i2s_test_apps/i2s/main/test_i2s.c @@ -0,0 +1,855 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "freertos/semphr.h" +#include "driver/gpio.h" +#include "hal/gpio_hal.h" +#include "esp_err.h" +#include "esp_attr.h" +#include "unity.h" +#include "math.h" +#include "esp_rom_gpio.h" +#include "soc/i2s_periph.h" +#include "driver/i2s_std.h" +#if SOC_I2S_SUPPORTS_PDM +#include "driver/i2s_pdm.h" +#endif +#if SOC_I2S_SUPPORTS_TDM +#include "driver/i2s_tdm.h" +#endif +#include "hal/i2s_hal.h" +#include "esp_private/i2s_platform.h" +#if SOC_PCNT_SUPPORTED +#include "driver/pulse_cnt.h" +#include "soc/pcnt_periph.h" +#endif + +#include "test_inc/test_i2s.h" + +#define I2S_TEST_MODE_SLAVE_TO_MASTER 0 +#define I2S_TEST_MODE_MASTER_TO_SLAVE 1 +#define I2S_TEST_MODE_LOOPBACK 2 + +#define I2S_TEST_MASTER_DEFAULT_PIN { \ + .mclk = MASTER_MCK_IO, \ + .bclk = MASTER_BCK_IO, \ + .ws = MASTER_WS_IO, \ + .dout = DATA_OUT_IO, \ + .din = DATA_IN_IO, \ + .invert_flags = { \ + .mclk_inv = false, \ + .bclk_inv = false, \ + .ws_inv = false, \ + }, \ + } + +#define I2S_TEST_SLAVE_DEFAULT_PIN { \ + .mclk = -1, \ + .bclk = SLAVE_BCK_IO, \ + .ws = SLAVE_WS_IO, \ + .dout = DATA_OUT_IO, \ + .din = DATA_IN_IO, \ + .invert_flags = { \ + .mclk_inv = false, \ + .bclk_inv = false, \ + .ws_inv = false, \ + }, \ + } + +// mode: 0, master rx, slave tx. mode: 1, master tx, slave rx. mode: 2, master tx rx loop-back +// Since ESP32-S2 has only one I2S, only loop back test can be tested. +static void i2s_test_io_config(int mode) +{ + // Connect internal signals using IO matrix. + gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[MASTER_BCK_IO], PIN_FUNC_GPIO); + gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[MASTER_WS_IO], PIN_FUNC_GPIO); + gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[DATA_OUT_IO], PIN_FUNC_GPIO); + + gpio_set_direction(MASTER_BCK_IO, GPIO_MODE_INPUT_OUTPUT); + gpio_set_direction(MASTER_WS_IO, GPIO_MODE_INPUT_OUTPUT); + gpio_set_direction(DATA_OUT_IO, GPIO_MODE_INPUT_OUTPUT); + + switch (mode) { +#if SOC_I2S_NUM > 1 + case I2S_TEST_MODE_SLAVE_TO_MASTER: { + esp_rom_gpio_connect_out_signal(MASTER_BCK_IO, i2s_periph_signal[0].m_rx_bck_sig, 0, 0); + esp_rom_gpio_connect_in_signal(MASTER_BCK_IO, i2s_periph_signal[1].s_tx_bck_sig, 0); + + esp_rom_gpio_connect_out_signal(MASTER_WS_IO, i2s_periph_signal[0].m_rx_ws_sig, 0, 0); + esp_rom_gpio_connect_in_signal(MASTER_WS_IO, i2s_periph_signal[1].s_tx_ws_sig, 0); + + esp_rom_gpio_connect_out_signal(DATA_OUT_IO, i2s_periph_signal[1].data_out_sig, 0, 0); + esp_rom_gpio_connect_in_signal(DATA_OUT_IO, i2s_periph_signal[0].data_in_sig, 0); + } + break; + + case I2S_TEST_MODE_MASTER_TO_SLAVE: { + esp_rom_gpio_connect_out_signal(MASTER_BCK_IO, i2s_periph_signal[0].m_tx_bck_sig, 0, 0); + esp_rom_gpio_connect_in_signal(MASTER_BCK_IO, i2s_periph_signal[1].s_rx_bck_sig, 0); + + esp_rom_gpio_connect_out_signal(MASTER_WS_IO, i2s_periph_signal[0].m_tx_ws_sig, 0, 0); + esp_rom_gpio_connect_in_signal(MASTER_WS_IO, i2s_periph_signal[1].s_rx_ws_sig, 0); + + esp_rom_gpio_connect_out_signal(DATA_OUT_IO, i2s_periph_signal[0].data_out_sig, 0, 0); + esp_rom_gpio_connect_in_signal(DATA_OUT_IO, i2s_periph_signal[1].data_in_sig, 0); + } + break; +#endif + case I2S_TEST_MODE_LOOPBACK: { + esp_rom_gpio_connect_out_signal(DATA_OUT_IO, i2s_periph_signal[0].data_out_sig, 0, 0); + esp_rom_gpio_connect_in_signal(DATA_OUT_IO, i2s_periph_signal[0].data_in_sig, 0); + } + break; + + default: { + TEST_FAIL_MESSAGE("error: mode not supported"); + } + break; + } +} + +static void i2s_read_write_test(i2s_chan_handle_t tx_chan, i2s_chan_handle_t rx_chan) +{ +#define I2S_SEND_BUF_LEN 100 +#define I2S_RECV_BUF_LEN 10000 + + size_t bytes_write = 0; + size_t bytes_read = 0; + + bool is_success = false; + + uint8_t *send_buf = (uint8_t *)calloc(I2S_SEND_BUF_LEN, sizeof(uint8_t)); + TEST_ASSERT_NOT_NULL(send_buf); + uint8_t *recv_buf = (uint8_t *)calloc(I2S_RECV_BUF_LEN, sizeof(uint8_t)); + TEST_ASSERT_NOT_NULL(recv_buf); + + for (int i = 0; i < I2S_SEND_BUF_LEN; i++) { + send_buf[i] = i + 1; + } + + // write data to slave + TEST_ESP_OK(i2s_channel_write(tx_chan, send_buf, I2S_SEND_BUF_LEN, &bytes_write, 1000)); + TEST_ESP_OK(i2s_channel_read(rx_chan, recv_buf, I2S_RECV_BUF_LEN, &bytes_read, 1000)); + TEST_ASSERT_EQUAL_INT32(I2S_SEND_BUF_LEN, bytes_write); + TEST_ASSERT_EQUAL_INT32(I2S_RECV_BUF_LEN, bytes_read); + // test the read data right or not + for (int i = 0, j = 0; i < (I2S_RECV_BUF_LEN - I2S_SEND_BUF_LEN); i++) { + if (recv_buf[i] == 1) { + for (j = 1; (j < I2S_SEND_BUF_LEN) && (recv_buf[i+j] == j + 1); j++) {} + if (j == I2S_SEND_BUF_LEN) { + is_success = true; + goto finish; + } + i += j; + } + } +finish: + free(send_buf); + free(recv_buf); + TEST_ASSERT(is_success); +} + +// To check if the software logic of I2S driver is correct +TEST_CASE("I2S_basic_channel_allocation_reconfig_deleting_test", "[i2s]") +{ + + i2s_chan_handle_t tx_handle; + i2s_chan_handle_t rx_handle; + + i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER); + i2s_std_config_t std_cfg = { + .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(SAMPLE_RATE), + .slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO), + .gpio_cfg = I2S_TEST_MASTER_DEFAULT_PIN, + }; + + i2s_chan_info_t chan_info; + + /* TX channel basic test */ + TEST_ESP_OK(i2s_new_channel(&chan_cfg, &tx_handle, NULL)); + TEST_ESP_OK(i2s_channel_get_info(tx_handle, &chan_info)); + TEST_ASSERT(chan_info.mode == I2S_COMM_MODE_NONE); + + TEST_ESP_OK(i2s_channel_init_std_mode(tx_handle, &std_cfg)); + TEST_ESP_OK(i2s_channel_get_info(tx_handle, &chan_info)); + TEST_ASSERT(chan_info.mode == I2S_COMM_MODE_STD); + std_cfg.slot_cfg.data_bit_width = I2S_DATA_BIT_WIDTH_32BIT; + TEST_ESP_OK(i2s_channel_reconfig_std_slot(tx_handle, &std_cfg.slot_cfg)); + std_cfg.clk_cfg.sample_rate_hz = 44100; + TEST_ESP_OK(i2s_channel_reconfig_std_clock(tx_handle, &std_cfg.clk_cfg)); + TEST_ESP_OK(i2s_channel_enable(tx_handle)); + TEST_ESP_OK(i2s_channel_disable(tx_handle)); + TEST_ESP_OK(i2s_del_channel(tx_handle)); + TEST_ASSERT(i2s_channel_get_info(tx_handle, &chan_info) == ESP_ERR_NOT_FOUND); + + /* Duplex channel basic test */ + chan_cfg.id = I2S_NUM_0; // Specify port id to I2S port 0 + TEST_ESP_OK(i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle)); + TEST_ESP_OK(i2s_channel_get_info(tx_handle, &chan_info)); + TEST_ASSERT(chan_info.pair_chan == rx_handle); + TEST_ESP_OK(i2s_channel_init_std_mode(tx_handle, &std_cfg)); + TEST_ESP_OK(i2s_channel_init_std_mode(rx_handle, &std_cfg)); + TEST_ESP_OK(i2s_del_channel(tx_handle)); + TEST_ESP_OK(i2s_del_channel(rx_handle)); + + /* Repeat to check if a same port can be allocated again */ + TEST_ESP_OK(i2s_new_channel(&chan_cfg, NULL, &rx_handle)); + TEST_ESP_OK(i2s_del_channel(rx_handle)); + + /* Hold the occupation */ + TEST_ESP_OK(i2s_platform_acquire_occupation(I2S_NUM_0, "test_i2s")); + TEST_ASSERT(i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle) == ESP_ERR_NOT_FOUND); + TEST_ESP_OK(i2s_platform_release_occupation(I2S_NUM_0)); + TEST_ESP_OK(i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle)); + TEST_ESP_OK(i2s_del_channel(tx_handle)); + TEST_ESP_OK(i2s_del_channel(rx_handle)); +} + +static volatile bool task_run_flag; + +static void i2s_read_task(void *args) { + i2s_chan_handle_t rx_handle = (i2s_chan_handle_t)args; + uint8_t *recv_buf = (uint8_t *)calloc(1, 2000); + TEST_ASSERT(recv_buf); + size_t recv_size = 0; + esp_err_t ret = ESP_OK; + uint32_t cnt = 1; + + while (task_run_flag) { + ret = i2s_channel_read(rx_handle, recv_buf, 2000, &recv_size, 300); + if (ret == ESP_ERR_TIMEOUT) { + printf("Read timeout count: %d\n", cnt++); + } + } + + free(recv_buf); + vTaskDelete(NULL); +} + +static void i2s_write_task(void *args) { + i2s_chan_handle_t tx_handle = (i2s_chan_handle_t)args; + uint8_t *send_buf = (uint8_t *)calloc(1, 2000); + TEST_ASSERT(send_buf); + size_t send_size = 0; + esp_err_t ret = ESP_OK; + uint32_t cnt = 1; + + while (task_run_flag) { + ret = i2s_channel_write(tx_handle, send_buf, 2000, &send_size, 300); + if (ret == ESP_ERR_TIMEOUT) { + printf("Write timeout count: %d\n", cnt++); + } + } + + free(send_buf); + vTaskDelete(NULL); +} + +static void i2s_reconfig_task(void *args) { + i2s_chan_handle_t tx_handle = (i2s_chan_handle_t)args; + i2s_chan_info_t chan_info; + TEST_ESP_OK(i2s_channel_get_info(tx_handle, &chan_info)); + i2s_chan_handle_t rx_handle = chan_info.pair_chan; + int cnt = 1; + + while (task_run_flag) { + /* Reconfig the slot while reading / writing */ + i2s_std_slot_config_t slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO); + TEST_ESP_OK(i2s_channel_disable(tx_handle)); + TEST_ESP_OK(i2s_channel_disable(rx_handle)); + printf("[%d] Reconfiguring the slot...\n", cnt); + TEST_ESP_OK(i2s_channel_reconfig_std_slot(tx_handle, &slot_cfg)); + TEST_ESP_OK(i2s_channel_reconfig_std_slot(rx_handle, &slot_cfg)); + TEST_ESP_OK(i2s_channel_enable(tx_handle)); + TEST_ESP_OK(i2s_channel_enable(rx_handle)); + vTaskDelay(pdMS_TO_TICKS(200)); + + /* Reconfig the clock while reading / writing */ + i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(SAMPLE_RATE / 2); + TEST_ESP_OK(i2s_channel_disable(tx_handle)); + TEST_ESP_OK(i2s_channel_disable(rx_handle)); + printf("[%d] Reconfiguring the clock...\n", cnt); + TEST_ESP_OK(i2s_channel_reconfig_std_clock(tx_handle, &clk_cfg)); + TEST_ESP_OK(i2s_channel_reconfig_std_clock(rx_handle, &clk_cfg)); + TEST_ESP_OK(i2s_channel_enable(tx_handle)); + TEST_ESP_OK(i2s_channel_enable(rx_handle)); + vTaskDelay(pdMS_TO_TICKS(200)); + + /* Reconfig the gpio while reading / writing */ + i2s_std_gpio_config_t gpio_cfg = { + .mclk = MASTER_MCK_IO, + .bclk = MASTER_WS_IO, + .ws = MASTER_BCK_IO, + .dout = DATA_IN_IO, + .din = DATA_IN_IO, + .invert_flags = { + .mclk_inv = false, + .bclk_inv = false, + .ws_inv = false, + }, + }; + TEST_ESP_OK(i2s_channel_disable(tx_handle)); + TEST_ESP_OK(i2s_channel_disable(rx_handle)); + printf("[%d] Reconfiguring the gpio...\n", cnt); + TEST_ESP_OK(i2s_channel_reconfig_std_gpio(tx_handle, &gpio_cfg)); + TEST_ESP_OK(i2s_channel_reconfig_std_gpio(rx_handle, &gpio_cfg)); + TEST_ESP_OK(i2s_channel_enable(tx_handle)); + TEST_ESP_OK(i2s_channel_enable(rx_handle)); + vTaskDelay(pdMS_TO_TICKS(200)); + + cnt++; + } + + vTaskDelete(NULL); +} + +TEST_CASE("I2S_thread_concurrent_safety_test", "[i2s]") +{ + i2s_chan_handle_t tx_handle; + i2s_chan_handle_t rx_handle; + i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER); + i2s_std_config_t std_cfg = { + .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(SAMPLE_RATE), + .slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO), + .gpio_cfg = { + .mclk = MASTER_MCK_IO, + .bclk = MASTER_BCK_IO, + .ws = MASTER_WS_IO, + .dout = DATA_OUT_IO, + .din = DATA_OUT_IO, + .invert_flags = { + .mclk_inv = false, + .bclk_inv = false, + .ws_inv = false, + }, + }, + }; + TEST_ESP_OK(i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle)); + TEST_ESP_OK(i2s_channel_init_std_mode(tx_handle, &std_cfg)); + TEST_ESP_OK(i2s_channel_init_std_mode(rx_handle, &std_cfg)); + /* Enable the channels before creating reading/writing task*/ + TEST_ESP_OK(i2s_channel_enable(tx_handle)); + TEST_ESP_OK(i2s_channel_enable(rx_handle)); + + task_run_flag = true; + /* reading task to keep reading */ + xTaskCreate(i2s_read_task, "i2s_read_task", 4096, rx_handle, 5, NULL); + /* writing task to keep writing */ + xTaskCreate(i2s_write_task, "i2s_write_task", 4096, tx_handle, 5, NULL); + /* reconfig taks to reconfigurate the settings every 200 ms */ + xTaskCreate(i2s_reconfig_task, "i2s_reconfig_task", 4096, tx_handle, 6, NULL); + + /* Wait 3 seconds to see if any failures occur */ + vTaskDelay(pdMS_TO_TICKS(4000)); + + /* Stop those three tasks */ + task_run_flag = false; + + /* Wait for the three thread deleted */ + vTaskDelay(pdMS_TO_TICKS(1000)); + + /* Disable the channels, they will keep waiting until the current reading / writing finished */ + TEST_ESP_OK(i2s_channel_disable(tx_handle)); + TEST_ESP_OK(i2s_channel_disable(rx_handle)); + /* Delete the channels */ + TEST_ESP_OK(i2s_del_channel(tx_handle)); + TEST_ESP_OK(i2s_del_channel(rx_handle)); +} + +static uint32_t get_start_index(uint16_t *buf, uint32_t len, uint32_t start_val) +{ + uint32_t i = 0; + for (i = 0; i < len; i++) { + if (buf[i] == start_val) { + printf("%d %d %d %d %d %d %d %d\n", + buf[i], buf[i+1], buf[i+2], buf[i+3], + buf[i+4], buf[i+5], buf[i+6], buf[i+7]); + break; + } + } + return i; +} + +/** + * @brief Test mono and stereo mode of I2S by loopback + * @note Only rx channel distinguish left mono and right mono, tx channel does not + * @note 1. Check switch mono/stereo by 'i2s_set_clk' + * 2. Check rx right mono and left mono (requiring tx works in stereo mode) + * 3. Check tx mono (requiring rx works in stereo mode) + */ +TEST_CASE("I2S_mono_stereo_loopback_test", "[i2s]") +{ +#define WRITE_BUF_LEN 2000 +#define READ_BUF_LEN 4000 +#define RETEY_TIMES 3 + + i2s_chan_handle_t tx_handle; + i2s_chan_handle_t rx_handle; + + i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER); + chan_cfg.dma_desc_num = 8; + chan_cfg.dma_frame_num = 128; + i2s_std_config_t tx_std_cfg = { + .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(SAMPLE_RATE), + // In stereo mode + .slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO), + .gpio_cfg = { + .mclk = MASTER_MCK_IO, + .bclk = MASTER_BCK_IO, + .ws = MASTER_WS_IO, + .dout = DATA_OUT_IO, + .din = DATA_OUT_IO, + .invert_flags = { + .mclk_inv = false, + .bclk_inv = false, + .ws_inv = false, + }, + }, + }; + i2s_std_config_t rx_std_cfg = tx_std_cfg; + rx_std_cfg.slot_cfg.slot_mode = I2S_SLOT_MODE_MONO; + rx_std_cfg.slot_cfg.slot_mask = I2S_STD_SLOT_ONLY_RIGHT; + + /* TX channel basic test */ + TEST_ESP_OK(i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle)); + TEST_ESP_OK(i2s_channel_init_std_mode(rx_handle, &rx_std_cfg)); + TEST_ESP_OK(i2s_channel_init_std_mode(tx_handle, &tx_std_cfg)); + TEST_ESP_OK(i2s_channel_enable(tx_handle)); + TEST_ESP_OK(i2s_channel_enable(rx_handle)); + + uint16_t *w_buf = calloc(1, WRITE_BUF_LEN); + uint16_t *r_buf = calloc(1, READ_BUF_LEN); + size_t w_bytes = 0; + size_t r_bytes = 0; + uint32_t index = 0; + uint32_t retry = 0; + for (int n = 0; n < WRITE_BUF_LEN / 2; n++) { + w_buf[n] = n%100; + } + + /* rx right mono test + * tx format: 0x00[L] 0x01[R] 0x02[L] 0x03[R] ... + * rx receive: 0x01[R] 0x03[R] ... */ + TEST_ESP_OK(i2s_channel_write(tx_handle, w_buf, WRITE_BUF_LEN, &w_bytes, portMAX_DELAY)); + for (retry = 0, index = READ_BUF_LEN / 2; (retry < RETEY_TIMES) && (index >= READ_BUF_LEN / 2 - 50); retry++) { + TEST_ESP_OK(i2s_channel_read(rx_handle, r_buf, READ_BUF_LEN, &r_bytes, portMAX_DELAY)); +#if CONFIG_IDF_TARGET_ESP32 + /* The data of tx/rx channels are flipped on ESP32 */ + for (int n = 0; n < READ_BUF_LEN / 2; n += 2) { + int16_t temp = r_buf[n]; + r_buf[n] = r_buf[n+1]; + r_buf[n+1] = temp; + } +#endif + index = get_start_index(r_buf, READ_BUF_LEN / 2, 1); + } + printf("Data start index: %d\n", index); + TEST_ASSERT(index < READ_BUF_LEN / 2 - 50); + for (int16_t j = 1; j < 100; j += 2) { + TEST_ASSERT_EQUAL_INT16(r_buf[index++], j); + } + printf("rx right mono test passed\n"); + + /* rx left mono test + * tx format: 0x00[L] 0x01[R] 0x02[L] 0x03[R] ... + * rx receive: 0x00[R] 0x02[R] ... */ + TEST_ESP_OK(i2s_channel_disable(tx_handle)); + TEST_ESP_OK(i2s_channel_disable(rx_handle)); + rx_std_cfg.slot_cfg.slot_mask = I2S_STD_SLOT_ONLY_LEFT; + TEST_ESP_OK(i2s_channel_reconfig_std_slot(rx_handle, &rx_std_cfg.slot_cfg)); + TEST_ESP_OK(i2s_channel_enable(tx_handle)); + TEST_ESP_OK(i2s_channel_enable(rx_handle)); + TEST_ESP_OK(i2s_channel_write(tx_handle, w_buf, WRITE_BUF_LEN, &w_bytes, portMAX_DELAY)); + for (retry = 0, index = READ_BUF_LEN / 2; (retry < RETEY_TIMES) && (index >= READ_BUF_LEN / 2 - 50); retry++) { + TEST_ESP_OK(i2s_channel_read(rx_handle, r_buf, READ_BUF_LEN, &r_bytes, portMAX_DELAY)); +#if CONFIG_IDF_TARGET_ESP32 + /* The data of tx/rx channels are flipped on ESP32 */ + for (int n = 0; n < READ_BUF_LEN / 2; n += 2) { + int16_t temp = r_buf[n]; + r_buf[n] = r_buf[n+1]; + r_buf[n+1] = temp; + } +#endif + index = get_start_index(r_buf, READ_BUF_LEN / 2, 2); + } + printf("Data start index: %d\n", index); + TEST_ASSERT(index < READ_BUF_LEN / 2 - 50); + for (int16_t j = 2; j < 100; j += 2) { + TEST_ASSERT_EQUAL_INT16(r_buf[index++], j); + } + printf("rx left mono test passed\n"); + + /* tx/rx stereo test + * tx format: 0x00[L] 0x01[R] 0x02[L] 0x03[R] ... + * rx receive: 0x00[L] 0x01[R] 0x02[L] 0x03[R] ... */ + TEST_ESP_OK(i2s_channel_disable(tx_handle)); + TEST_ESP_OK(i2s_channel_disable(rx_handle)); + rx_std_cfg.slot_cfg.slot_mode = I2S_SLOT_MODE_STEREO; + rx_std_cfg.slot_cfg.slot_mask = I2S_STD_SLOT_LEFT_RIGHT; + TEST_ESP_OK(i2s_channel_reconfig_std_slot(rx_handle, &rx_std_cfg.slot_cfg)); + TEST_ESP_OK(i2s_channel_enable(tx_handle)); + TEST_ESP_OK(i2s_channel_enable(rx_handle)); + TEST_ESP_OK(i2s_channel_write(tx_handle, w_buf, WRITE_BUF_LEN, &w_bytes, portMAX_DELAY)); + for (retry = 0, index = READ_BUF_LEN / 2; (retry < RETEY_TIMES) && (index >= READ_BUF_LEN / 2 - 100); retry++) { + TEST_ESP_OK(i2s_channel_read(rx_handle, r_buf, READ_BUF_LEN, &r_bytes, portMAX_DELAY)); + index = get_start_index(r_buf, READ_BUF_LEN / 2, 1); + } + + printf("Data start index: %d\n", index); + TEST_ASSERT(index < READ_BUF_LEN / 2 - 100); + for (int16_t j = 1; j < 100; j ++) { + TEST_ASSERT_EQUAL_INT16(r_buf[index++], j); // receive all number + } + printf("tx/rx stereo test passed\n"); + +#if !CONFIG_IDF_TARGET_ESP32 // the 16 bit channel sequence on ESP32 is incorrect + /* tx mono rx stereo test + * tx format: 0x01[L] 0x01[R] 0x02[L] 0x02[R] ... + * rx receive: 0x01[L] 0x01[R] 0x02[L] 0x02[R] ... */ + TEST_ESP_OK(i2s_channel_disable(tx_handle)); + TEST_ESP_OK(i2s_channel_disable(rx_handle)); + i2s_std_slot_config_t std_slot = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO); + TEST_ESP_OK(i2s_channel_reconfig_std_slot(tx_handle, &std_slot)); + TEST_ESP_OK(i2s_channel_reconfig_std_slot(rx_handle, &rx_std_cfg.slot_cfg)); + TEST_ESP_OK(i2s_channel_enable(tx_handle)); + TEST_ESP_OK(i2s_channel_enable(rx_handle)); + TEST_ESP_OK(i2s_channel_write(tx_handle, w_buf, WRITE_BUF_LEN, &w_bytes, portMAX_DELAY)); + for (retry = 0, index = READ_BUF_LEN / 2; (retry < RETEY_TIMES) && (index >= READ_BUF_LEN / 2 - 100); retry++) { + TEST_ESP_OK(i2s_channel_read(rx_handle, r_buf, READ_BUF_LEN, &r_bytes, portMAX_DELAY)); + index = get_start_index(r_buf, READ_BUF_LEN / 2, 1); + } + printf("Data start index: %d\n", index); + TEST_ASSERT(index < READ_BUF_LEN / 2 - 200); + for (int16_t j = 1; j < 100; j ++) { + TEST_ASSERT_EQUAL_INT16(r_buf[index], j); + index += 2; + } + printf("tx mono rx stereo test passed\n"); +#endif + + free(w_buf); + free(r_buf); + TEST_ESP_OK(i2s_channel_disable(tx_handle)); + TEST_ESP_OK(i2s_channel_disable(rx_handle)); + TEST_ESP_OK(i2s_del_channel(tx_handle)); + TEST_ESP_OK(i2s_del_channel(rx_handle)); +} + +TEST_CASE("I2S_memory_leak_test", "[i2s]") +{ + i2s_chan_handle_t tx_handle; + i2s_chan_handle_t rx_handle; + + i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER); + i2s_std_config_t std_cfg = { + .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(SAMPLE_RATE), + .slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO), + .gpio_cfg = I2S_TEST_MASTER_DEFAULT_PIN, + }; + + /* The first operation will always take some memory */ + TEST_ESP_OK(i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle)); + TEST_ESP_OK(i2s_channel_init_std_mode(tx_handle, &std_cfg)); + TEST_ESP_OK(i2s_channel_init_std_mode(rx_handle, &std_cfg)); + std_cfg.slot_cfg.data_bit_width = I2S_DATA_BIT_WIDTH_32BIT; + TEST_ESP_OK(i2s_channel_reconfig_std_slot(tx_handle, &std_cfg.slot_cfg)); + std_cfg.clk_cfg.sample_rate_hz = 44100; + TEST_ESP_OK(i2s_channel_reconfig_std_clock(tx_handle, &std_cfg.clk_cfg)); + TEST_ESP_OK(i2s_del_channel(tx_handle)); + TEST_ESP_OK(i2s_del_channel(rx_handle)); + + int memory_left = esp_get_free_heap_size(); + printf("\r\nHeap size before: %d\n", memory_left); + for (int i = 0; i < 30; i++) { + TEST_ESP_OK(i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle)); + TEST_ESP_OK(i2s_channel_init_std_mode(tx_handle, &std_cfg)); + TEST_ESP_OK(i2s_channel_init_std_mode(rx_handle, &std_cfg)); + std_cfg.slot_cfg.data_bit_width = I2S_DATA_BIT_WIDTH_32BIT; + TEST_ESP_OK(i2s_channel_reconfig_std_slot(tx_handle, &std_cfg.slot_cfg)); + std_cfg.clk_cfg.sample_rate_hz = 44100; + TEST_ESP_OK(i2s_channel_reconfig_std_clock(tx_handle, &std_cfg.clk_cfg)); + TEST_ESP_OK(i2s_del_channel(tx_handle)); + TEST_ESP_OK(i2s_del_channel(rx_handle)); + TEST_ASSERT(memory_left == esp_get_free_heap_size()); + } + printf("\r\nHeap size after: %d\n", esp_get_free_heap_size()); +} + +TEST_CASE("I2S_loopback_test", "[i2s]") +{ + i2s_chan_handle_t tx_handle; + i2s_chan_handle_t rx_handle; + + i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER); + i2s_std_config_t std_cfg = { + .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(SAMPLE_RATE), + .slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO), + .gpio_cfg = I2S_TEST_MASTER_DEFAULT_PIN, + }; + TEST_ESP_OK(i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle)); + TEST_ESP_OK(i2s_channel_init_std_mode(tx_handle, &std_cfg)); + TEST_ESP_OK(i2s_channel_init_std_mode(rx_handle, &std_cfg)); + i2s_test_io_config(I2S_TEST_MODE_LOOPBACK); + + TEST_ESP_OK(i2s_channel_enable(tx_handle)); + TEST_ESP_OK(i2s_channel_enable(rx_handle)); + + i2s_read_write_test(tx_handle, rx_handle); + + TEST_ESP_OK(i2s_channel_disable(tx_handle)); + TEST_ESP_OK(i2s_channel_disable(rx_handle)); + TEST_ESP_OK(i2s_del_channel(tx_handle)); + TEST_ESP_OK(i2s_del_channel(rx_handle)); +} + +#if SOC_I2S_NUM > 1 +TEST_CASE("I2S_master_write_slave_read_test", "[i2s]") +{ + i2s_chan_handle_t tx_handle; + i2s_chan_handle_t rx_handle; + + i2s_chan_config_t mst_chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER); + i2s_chan_config_t slv_chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_1, I2S_ROLE_SLAVE); + + i2s_std_config_t std_mst_cfg = { + .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(SAMPLE_RATE), + .slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO), + .gpio_cfg = I2S_TEST_MASTER_DEFAULT_PIN, + }; + + i2s_std_config_t std_slv_cfg = { + .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(SAMPLE_RATE), + .slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO), + .gpio_cfg = I2S_TEST_SLAVE_DEFAULT_PIN, + }; + + TEST_ESP_OK(i2s_new_channel(&mst_chan_cfg, &tx_handle, NULL)); + TEST_ESP_OK(i2s_new_channel(&slv_chan_cfg, NULL, &rx_handle)); + TEST_ESP_OK(i2s_channel_init_std_mode(tx_handle, &std_mst_cfg)); + TEST_ESP_OK(i2s_channel_init_std_mode(rx_handle, &std_slv_cfg)); + i2s_test_io_config(I2S_TEST_MODE_MASTER_TO_SLAVE); + + TEST_ESP_OK(i2s_channel_enable(tx_handle)); + TEST_ESP_OK(i2s_channel_enable(rx_handle)); + + i2s_read_write_test(tx_handle, rx_handle); + + TEST_ESP_OK(i2s_channel_disable(tx_handle)); + TEST_ESP_OK(i2s_channel_disable(rx_handle)); + TEST_ESP_OK(i2s_del_channel(tx_handle)); + TEST_ESP_OK(i2s_del_channel(rx_handle)); +} + +TEST_CASE("I2S_master_read_slave_write_test", "[i2s]") +{ + i2s_chan_handle_t tx_handle; + i2s_chan_handle_t rx_handle; + + i2s_chan_config_t mst_chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER); + i2s_chan_config_t slv_chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_1, I2S_ROLE_SLAVE); + i2s_std_config_t std_mst_cfg = { + .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(SAMPLE_RATE), + .slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO), + .gpio_cfg = I2S_TEST_MASTER_DEFAULT_PIN, + }; + + i2s_std_config_t std_slv_cfg = { + .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(SAMPLE_RATE), + .slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO), + .gpio_cfg = I2S_TEST_SLAVE_DEFAULT_PIN, + }; + + TEST_ESP_OK(i2s_new_channel(&mst_chan_cfg, NULL, &rx_handle)); + TEST_ESP_OK(i2s_new_channel(&slv_chan_cfg, &tx_handle, NULL)); + TEST_ESP_OK(i2s_channel_init_std_mode(tx_handle, &std_slv_cfg)); + TEST_ESP_OK(i2s_channel_init_std_mode(rx_handle, &std_mst_cfg)); + i2s_test_io_config(I2S_TEST_MODE_SLAVE_TO_MASTER); + + TEST_ESP_OK(i2s_channel_enable(tx_handle)); + TEST_ESP_OK(i2s_channel_enable(rx_handle)); + + i2s_read_write_test(tx_handle, rx_handle); + + TEST_ESP_OK(i2s_channel_disable(tx_handle)); + TEST_ESP_OK(i2s_channel_disable(rx_handle)); + TEST_ESP_OK(i2s_del_channel(tx_handle)); + TEST_ESP_OK(i2s_del_channel(rx_handle)); +} +#endif + +/*------------------------------ Clock Test --------------------------------*/ +#if SOC_PCNT_SUPPORTED +#define TEST_I2S_PERIOD_MS 100 +static void i2s_test_common_sample_rate(i2s_chan_handle_t rx_chan, i2s_std_clk_config_t* clk_cfg) +{ + TEST_ASSERT_NOT_NULL(rx_chan); + TEST_ASSERT_NOT_NULL(clk_cfg); + + /* Prepare configuration for the PCNT unit */ + pcnt_unit_handle_t pcnt_unit = NULL; + pcnt_channel_handle_t pcnt_chan = NULL; + + pcnt_unit_config_t unit_config = { + .high_limit = (int16_t)0x7fff, + .low_limit = (int16_t)0x8000, + }; + pcnt_chan_config_t chan_config = { + .edge_gpio_num = MASTER_WS_IO, + .level_gpio_num = -1, + }; + TEST_ESP_OK(pcnt_new_unit(&unit_config, &pcnt_unit)); + TEST_ESP_OK(pcnt_unit_set_glitch_filter(pcnt_unit, NULL)); + TEST_ESP_OK(pcnt_new_channel(pcnt_unit, &chan_config, &pcnt_chan)); + TEST_ESP_OK(pcnt_channel_set_edge_action(pcnt_chan, PCNT_CHANNEL_EDGE_ACTION_INCREASE, PCNT_CHANNEL_EDGE_ACTION_HOLD)); + TEST_ESP_OK(pcnt_channel_set_level_action(pcnt_chan, PCNT_CHANNEL_LEVEL_ACTION_KEEP, PCNT_CHANNEL_LEVEL_ACTION_KEEP)); + TEST_ESP_OK(pcnt_unit_enable(pcnt_unit)); + + // Reconfig GPIO signal + gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[MASTER_WS_IO], PIN_FUNC_GPIO); + gpio_set_direction(MASTER_WS_IO, GPIO_MODE_INPUT_OUTPUT); + esp_rom_gpio_connect_out_signal(MASTER_WS_IO, i2s_periph_signal[0].m_rx_ws_sig, 0, 0); + esp_rom_gpio_connect_in_signal(MASTER_WS_IO, pcnt_periph_signals.groups[0].units[0].channels[0].pulse_sig, 0); + + // Test common sample rate + uint32_t test_freq[15] = {8000, 11025, 12000, 16000, 22050, 24000, + 32000, 44100, 48000, 64000, 88200, 96000, + 128000, 144000, 196000}; + int real_pulse = 0; + for (int i = 0; i < 15; i++) { + int expt_pulse = (int)((float)test_freq[i] * (TEST_I2S_PERIOD_MS / 1000.0)); + clk_cfg->sample_rate_hz = test_freq[i]; + TEST_ESP_OK(i2s_channel_reconfig_std_clock(rx_chan, clk_cfg)); + TEST_ESP_OK(i2s_channel_enable(rx_chan)); + vTaskDelay(1); // Waiting for hardware totally started + // pcnt will count the pulse number on WS signal in 100ms + TEST_ESP_OK(pcnt_unit_clear_count(pcnt_unit)); + TEST_ESP_OK(pcnt_unit_start(pcnt_unit)); + vTaskDelay(pdMS_TO_TICKS(TEST_I2S_PERIOD_MS)); + TEST_ESP_OK(pcnt_unit_stop(pcnt_unit)); + TEST_ESP_OK(pcnt_unit_get_count(pcnt_unit, &real_pulse)); + printf("[%d Hz] %d pulses, expected %d, err %d\n", test_freq[i], real_pulse, expt_pulse, real_pulse - expt_pulse); + TEST_ESP_OK(i2s_channel_disable(rx_chan)); + // Check if the error between real pulse number and expected pulse number is within 1% + TEST_ASSERT_INT_WITHIN(expt_pulse * 0.01, expt_pulse, real_pulse); + } + TEST_ESP_OK(pcnt_del_channel(pcnt_chan)); + TEST_ESP_OK(pcnt_unit_stop(pcnt_unit)); + TEST_ESP_OK(pcnt_unit_disable(pcnt_unit)); + TEST_ESP_OK(pcnt_del_unit(pcnt_unit)); +} + +TEST_CASE("I2S_default_PLL_clock_test", "[i2s]") +{ + i2s_chan_handle_t rx_handle; + + i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER); + i2s_std_config_t std_cfg = { + .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(SAMPLE_RATE), + .slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO), + .gpio_cfg = I2S_TEST_MASTER_DEFAULT_PIN, + }; + + TEST_ESP_OK(i2s_new_channel(&chan_cfg, NULL, &rx_handle)); + TEST_ESP_OK(i2s_channel_init_std_mode(rx_handle, &std_cfg)); + + i2s_test_common_sample_rate(rx_handle, &std_cfg.clk_cfg); + TEST_ESP_OK(i2s_del_channel(rx_handle)); +} + +#if SOC_I2S_SUPPORTS_APLL +TEST_CASE("I2S_APLL_clock_test", "[i2s]") +{ + i2s_chan_handle_t rx_handle; + + i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER); + i2s_std_config_t std_cfg = { + .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(SAMPLE_RATE), + .slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO), + .gpio_cfg = I2S_TEST_MASTER_DEFAULT_PIN, + }; + std_cfg.clk_cfg.clk_src = I2S_CLK_SRC_APLL; + + TEST_ESP_OK(i2s_new_channel(&chan_cfg, NULL, &rx_handle)); + TEST_ESP_OK(i2s_channel_init_std_mode(rx_handle, &std_cfg)); + + i2s_test_common_sample_rate(rx_handle, &std_cfg.clk_cfg); + TEST_ESP_OK(i2s_del_channel(rx_handle)); +} +#endif // SOC_I2S_SUPPORTS_APLL +#endif // SOC_PCNT_SUPPORTED + +static IRAM_ATTR bool i2s_rx_queue_overflow_callback(i2s_chan_handle_t handle, i2s_event_data_t *event, void *user_ctx) +{ + int *cnt = (int *)user_ctx; + (*cnt)++; + return false; +} + +TEST_CASE("I2S_package_lost_test", "[i2s]") +{ + /* Steps of calculate appropriate parameters of I2S buffer: + * Known by user: sample_rate = 144k, data_bit_width = 32, slot_num = 2, polling_cycle = 10 ms + * 1. dma_buffer_size = dma_frame_num * slot_num * data_bit_width / 8 <= 4092 + * dma_frame_num <= 511, dma_frame_num is as big as possible. + * interrupt_interval = dma_frame_num / sample_rate = 3.549 ms + * 2. dma_desc_num > polling_cycle / interrupt_interval = cell(2.818) = 3 + * 3. recv_buffer_size > dma_desc_num * dma_buffer_size = 3 * 4092 = 12276 bytes */ + #define TEST_RECV_BUF_LEN 12276 + i2s_chan_handle_t rx_handle; + + i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER); + chan_cfg.dma_desc_num = 3; + chan_cfg.dma_frame_num = 511; + i2s_std_config_t std_cfg = { + .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(SAMPLE_RATE), + .slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_STEREO), + .gpio_cfg = I2S_TEST_MASTER_DEFAULT_PIN, + }; + + TEST_ESP_OK(i2s_new_channel(&chan_cfg, NULL, &rx_handle)); + TEST_ESP_OK(i2s_channel_init_std_mode(rx_handle, &std_cfg)); + i2s_event_callbacks_t cbs = { + .on_recv = NULL, + .on_recv_q_ovf = i2s_rx_queue_overflow_callback, + .on_sent = NULL, + .on_send_q_ovf = NULL, + }; + int count = 0; + TEST_ESP_OK(i2s_channel_register_event_callback(rx_handle, &cbs, &count)); + + uint32_t test_freq[] = {16000, 32000, 48000, 64000, 96000, 128000, 144000}; + uint32_t test_num = sizeof(test_freq) / sizeof(uint32_t); + uint8_t *data = (uint8_t *)calloc(TEST_RECV_BUF_LEN, sizeof(uint8_t)); + size_t bytes_read = 0; + int i; + for (i = 0; i < test_num; i++) { + printf("Testing %d Hz sample rate\n", test_freq[i]); + std_cfg.clk_cfg.sample_rate_hz = test_freq[i]; + std_cfg.clk_cfg.sample_rate_hz = test_freq[i]; + TEST_ESP_OK(i2s_channel_reconfig_std_clock(rx_handle, &std_cfg.clk_cfg)); + TEST_ESP_OK(i2s_channel_enable(rx_handle)); + for (int j = 0; j < 10; j++) { + TEST_ESP_OK(i2s_channel_read(rx_handle, (void *)data, TEST_RECV_BUF_LEN, &bytes_read, portMAX_DELAY)); + // To simulate 10ms delay caused by other statements like data process + vTaskDelay(1); + } + TEST_ESP_OK(i2s_channel_disable(rx_handle)); + if (count > 0) { + printf("package lost detected at %d Hz\n", test_freq[i]); + goto finish; + } + } +finish: + TEST_ESP_OK(i2s_del_channel(rx_handle)); + free(data); + // Test failed if package lost within 96000 + TEST_ASSERT(i == test_num); +} diff --git a/components/driver/test_apps/i2s_test_apps/i2s/main/test_i2s_iram.c b/components/driver/test_apps/i2s_test_apps/i2s/main/test_i2s_iram.c new file mode 100644 index 0000000000..f53912461e --- /dev/null +++ b/components/driver/test_apps/i2s_test_apps/i2s/main/test_i2s_iram.c @@ -0,0 +1,114 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "sdkconfig.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/semphr.h" +#include "unity.h" +#include "driver/i2s_std.h" +#include "esp_spi_flash.h" +#include "esp_attr.h" +#include "soc/soc_caps.h" +#include "esp_private/i2s_platform.h" +#include "test_inc/test_i2s.h" + +#if CONFIG_I2S_ISR_IRAM_SAFE + +#define GET_DMA_BUFFERS_BY_OFFSET(base_addr, offset) (uint8_t **)(*((uint32_t *)base_addr + offset)) + +static bool IRAM_ATTR test_i2s_tx_done_callback(i2s_chan_handle_t handle, i2s_event_data_t *event, void *user_ctx) +{ + int *is_triggered = (int *)user_ctx; + if (*(uint8_t *)(event->data) != 0) { + *is_triggered = 1; + } + return false; +} + +static void IRAM_ATTR test_i2s_iram_write(i2s_chan_handle_t tx_handle) +{ + // Get the DMA buf pointer via the offset of 'bufs' field in i2s_channel_t struct + size_t offset = i2s_platform_get_dma_buffer_offset() / sizeof(uint32_t); // Get the offset and transfer to unit 'uint32_t' (i.e. 4 bytes) + uint8_t **dma_bufs = GET_DMA_BUFFERS_BY_OFFSET(tx_handle, offset); + + // disable cache and non-iram ISR handlers + spi_flash_guard_get()->start(); + // write data into dma buffer directly, the data in dma buffer will be sent automatically + for (int i=0; i < 100; i++) { + dma_bufs[0][i] = i + 1; + } + // enable cache and non-iram ISR handlers + spi_flash_guard_get()->end(); +} + +TEST_CASE("i2s_iram_interrupt_safe", "[i2s]") +{ + i2s_chan_handle_t tx_chan = NULL; + i2s_chan_handle_t rx_chan = NULL; + + i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER); + chan_cfg.dma_desc_num = 6; + chan_cfg.dma_frame_num = 200; + TEST_ESP_OK(i2s_new_channel(&chan_cfg, &tx_chan, &rx_chan)); + i2s_std_config_t std_cfg = { + .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(16000), + .slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO), + .gpio_cfg = { + .mclk = MASTER_MCK_IO, + .bclk = MASTER_BCK_IO, + .ws = MASTER_WS_IO, + .dout = DATA_OUT_IO, + .din = DATA_OUT_IO, // same gpio to loopback + .invert_flags = { + .mclk_inv = false, + .bclk_inv = false, + .ws_inv = false, + }, + }, + }; + TEST_ESP_OK(i2s_channel_init_std_mode(tx_chan, &std_cfg)); + TEST_ESP_OK(i2s_channel_init_std_mode(rx_chan, &std_cfg)); + int is_triggerred = 0; + i2s_event_callbacks_t cbs = { + .on_recv = NULL, + .on_recv_q_ovf = NULL, + .on_sent = test_i2s_tx_done_callback, + .on_send_q_ovf = NULL, + }; + TEST_ESP_OK(i2s_channel_register_event_callback(tx_chan, &cbs, &is_triggerred)); + TEST_ESP_OK(i2s_channel_enable(tx_chan)); + TEST_ESP_OK(i2s_channel_enable(rx_chan)); + + uint8_t *recv_buf = (uint8_t *)calloc(1, 2000); + TEST_ASSERT(recv_buf != NULL); + size_t r_bytes; + int i = 0; + test_i2s_iram_write(tx_chan); + for (int retry = 0; retry < 3; retry++) { + i2s_channel_read(rx_chan, recv_buf, 2000, &r_bytes, pdMS_TO_TICKS(1000)); + for (i = 0; i < 2000 - 100; i++) { + if (recv_buf[i] != 0) { + goto finish; + } + } + } +finish: + TEST_ESP_OK(i2s_channel_disable(tx_chan)); + TEST_ESP_OK(i2s_channel_disable(rx_chan)); + TEST_ESP_OK(i2s_del_channel(tx_chan)); + TEST_ESP_OK(i2s_del_channel(rx_chan)); + + TEST_ASSERT(i < (2000 - 100)); + for (int j = 1; j <= 100; j++) { + TEST_ASSERT_EQUAL_UINT8(recv_buf[i++], j); + } + TEST_ASSERT(is_triggerred); + free(recv_buf); +} + +#endif // CONFIG_PCNT_ISR_IRAM_SAFE diff --git a/components/driver/test_apps/i2s_test_apps/i2s/pytest_i2s.py b/components/driver/test_apps/i2s_test_apps/i2s/pytest_i2s.py new file mode 100644 index 0000000000..f715d67eef --- /dev/null +++ b/components/driver/test_apps/i2s_test_apps/i2s/pytest_i2s.py @@ -0,0 +1,24 @@ +# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Apache-2.0 + +import pytest +from pytest_embedded import Dut + + +@pytest.mark.esp32 +@pytest.mark.esp32s2 +@pytest.mark.esp32c3 +@pytest.mark.esp32s3 +@pytest.mark.generic +@pytest.mark.parametrize( + 'config', + [ + 'iram_safe', + 'release', + ], + indirect=True, +) +def test_i2s(dut: Dut) -> None: + dut.expect_exact('Press ENTER to see the list of tests') + dut.write('*') + dut.expect_unity_test_output() diff --git a/components/driver/test_apps/i2s_test_apps/i2s/sdkconfig.ci.iram_safe b/components/driver/test_apps/i2s_test_apps/i2s/sdkconfig.ci.iram_safe new file mode 100644 index 0000000000..350ce3b2ca --- /dev/null +++ b/components/driver/test_apps/i2s_test_apps/i2s/sdkconfig.ci.iram_safe @@ -0,0 +1,5 @@ +CONFIG_COMPILER_DUMP_RTL_FILES=y +CONFIG_I2S_ISR_IRAM_SAFE=y + +# silent the error check, as the error string are stored in rodata, causing RTL check failure +CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT=y diff --git a/components/driver/test_apps/i2s_test_apps/i2s/sdkconfig.ci.release b/components/driver/test_apps/i2s_test_apps/i2s/sdkconfig.ci.release new file mode 100644 index 0000000000..91d93f163e --- /dev/null +++ b/components/driver/test_apps/i2s_test_apps/i2s/sdkconfig.ci.release @@ -0,0 +1,5 @@ +CONFIG_PM_ENABLE=y +CONFIG_FREERTOS_USE_TICKLESS_IDLE=y +CONFIG_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y diff --git a/components/driver/test_apps/i2s_test_apps/i2s/sdkconfig.defaults b/components/driver/test_apps/i2s_test_apps/i2s/sdkconfig.defaults new file mode 100644 index 0000000000..b1692edbce --- /dev/null +++ b/components/driver/test_apps/i2s_test_apps/i2s/sdkconfig.defaults @@ -0,0 +1,2 @@ +CONFIG_I2S_ENABLE_DEBUG_LOG=y +CONFIG_ESP_TASK_WDT=n diff --git a/components/driver/test_apps/i2s_test_apps/legacy_i2s_adc_dac/CMakeLists.txt b/components/driver/test_apps/i2s_test_apps/legacy_i2s_adc_dac/CMakeLists.txt new file mode 100644 index 0000000000..af458843d5 --- /dev/null +++ b/components/driver/test_apps/i2s_test_apps/legacy_i2s_adc_dac/CMakeLists.txt @@ -0,0 +1,5 @@ +# This is the project CMakeLists.txt file for the test subproject +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(i2s_adc_dac_test) diff --git a/components/driver/test_apps/i2s_test_apps/legacy_i2s_adc_dac/README.md b/components/driver/test_apps/i2s_test_apps/legacy_i2s_adc_dac/README.md new file mode 100644 index 0000000000..d00f700643 --- /dev/null +++ b/components/driver/test_apps/i2s_test_apps/legacy_i2s_adc_dac/README.md @@ -0,0 +1,2 @@ +| Supported Targets | ESP32 | +| ----------------- | ----- | \ No newline at end of file diff --git a/components/driver/test_apps/i2s_test_apps/legacy_i2s_adc_dac/main/CMakeLists.txt b/components/driver/test_apps/i2s_test_apps/legacy_i2s_adc_dac/main/CMakeLists.txt new file mode 100644 index 0000000000..b50ed4fa22 --- /dev/null +++ b/components/driver/test_apps/i2s_test_apps/legacy_i2s_adc_dac/main/CMakeLists.txt @@ -0,0 +1,6 @@ +set(srcs "test_app_main.c" + "test_i2s_adc.c" + "test_i2s_dac.c") + +idf_component_register(SRCS ${srcs} + WHOLE_ARCHIVE) diff --git a/components/driver/test_apps/i2s_test_apps/legacy_i2s_adc_dac/main/test_app_main.c b/components/driver/test_apps/i2s_test_apps/legacy_i2s_adc_dac/main/test_app_main.c new file mode 100644 index 0000000000..530b0dc98e --- /dev/null +++ b/components/driver/test_apps/i2s_test_apps/legacy_i2s_adc_dac/main/test_app_main.c @@ -0,0 +1,53 @@ +/* + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "unity.h" +#include "unity_test_runner.h" +#include "esp_heap_caps.h" + +// Some resources are lazy allocated in I2S driver, the threadhold is left for that case +#define TEST_MEMORY_LEAK_THRESHOLD (-400) + +static size_t before_free_8bit; +static size_t before_free_32bit; + +static void check_leak(size_t before_free, size_t after_free, const char *type) +{ + ssize_t delta = after_free - before_free; + printf("MALLOC_CAP_%s: Before %u bytes free, After %u bytes free (delta %d)\n", type, before_free, after_free, delta); + TEST_ASSERT_MESSAGE(delta >= TEST_MEMORY_LEAK_THRESHOLD, "memory leak"); +} + +void setUp(void) +{ + before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); + before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); +} + +void tearDown(void) +{ + size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); + size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); + check_leak(before_free_8bit, after_free_8bit, "8BIT"); + check_leak(before_free_32bit, after_free_32bit, "32BIT"); +} + +void app_main(void) +{ + // ___ ____ ____ _____ _ + // |_ _|___ \/ ___| |_ _|__ ___| |_ + // | | __) \___ \ | |/ _ \/ __| __| + // | | / __/ ___) | | | __/\__ \ |_ + // |___|_____|____/ |_|\___||___/\__| + + printf(" ___ ____ ____ _____ _ \r\n"); + printf(" |_ _|___ \\/ ___| |_ _|__ ___| |_ \r\n"); + printf(" | | __) \\___ \\ | |/ _ \\/ __| __|\r\n"); + printf(" | | / __/ ___) | | | __/\\__ \\ |_ \r\n"); + printf(" |___|_____|____/ |_|\\___||___/\\__|(ADC/DAC)\r\n"); + + unity_run_menu(); +} diff --git a/components/driver/test_apps/i2s_test_apps/legacy_i2s_adc_dac/main/test_dac_audio_file.h b/components/driver/test_apps/i2s_test_apps/legacy_i2s_adc_dac/main/test_dac_audio_file.h new file mode 100644 index 0000000000..fbe62c647c --- /dev/null +++ b/components/driver/test_apps/i2s_test_apps/legacy_i2s_adc_dac/main/test_dac_audio_file.h @@ -0,0 +1,4980 @@ +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +const unsigned char audio_table[] = { + 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x80, 0x81, 0x81, 0x7e, 0x7a, 0x79, 0x79, 0x7c, 0x81, 0x82, 0x82, + 0x81, 0x7e, 0x7d, 0x7b, 0x7a, 0x7a, 0x7b, 0x7e, 0x82, 0x84, 0x84, 0x85, 0x84, 0x80, 0x7d, 0x7a, + 0x78, 0x78, 0x7a, 0x80, 0x84, 0x87, 0x86, 0x80, 0x7a, 0x77, 0x79, 0x7d, 0x82, 0x85, 0x84, 0x82, + 0x7d, 0x7a, 0x77, 0x76, 0x77, 0x79, 0x80, 0x84, 0x86, 0x88, 0x87, 0x84, 0x7e, 0x77, 0x74, 0x75, + 0x79, 0x81, 0x88, 0x8b, 0x89, 0x87, 0x84, 0x7e, 0x78, 0x73, 0x72, 0x78, 0x82, 0x8b, 0x8f, 0x8e, + 0x88, 0x7e, 0x71, 0x69, 0x6d, 0x79, 0x88, 0x8f, 0x8c, 0x85, 0x80, 0x80, 0x81, 0x7d, 0x77, 0x73, + 0x76, 0x7e, 0x88, 0x8f, 0x8d, 0x85, 0x7e, 0x7b, 0x7b, 0x7e, 0x81, 0x80, 0x7d, 0x7c, 0x7c, 0x80, + 0x83, 0x82, 0x80, 0x7d, 0x7d, 0x80, 0x82, 0x84, 0x83, 0x80, 0x7c, 0x7b, 0x7d, 0x81, 0x84, 0x84, + 0x80, 0x7d, 0x7c, 0x7c, 0x7d, 0x7c, 0x7a, 0x79, 0x7c, 0x83, 0x87, 0x87, 0x83, 0x7e, 0x79, 0x78, + 0x78, 0x79, 0x7b, 0x7c, 0x7d, 0x81, 0x82, 0x83, 0x84, 0x83, 0x7e, 0x7a, 0x77, 0x78, 0x7b, 0x7e, + 0x81, 0x82, 0x80, 0x7e, 0x7e, 0x81, 0x82, 0x80, 0x7e, 0x80, 0x82, 0x82, 0x81, 0x7e, 0x7c, 0x7b, + 0x7b, 0x7c, 0x80, 0x83, 0x84, 0x83, 0x82, 0x80, 0x7e, 0x7a, 0x77, 0x77, 0x78, 0x7c, 0x82, 0x85, + 0x86, 0x85, 0x84, 0x82, 0x7e, 0x7b, 0x77, 0x75, 0x78, 0x7e, 0x83, 0x85, 0x85, 0x85, 0x84, 0x83, + 0x81, 0x7c, 0x7a, 0x7a, 0x7c, 0x7e, 0x81, 0x82, 0x83, 0x84, 0x84, 0x82, 0x80, 0x7e, 0x7c, 0x7a, + 0x7a, 0x7c, 0x80, 0x83, 0x86, 0x87, 0x84, 0x80, 0x7c, 0x7c, 0x7d, 0x7e, 0x7d, 0x7c, 0x7c, 0x7d, + 0x83, 0x87, 0x88, 0x87, 0x82, 0x7c, 0x78, 0x79, 0x7b, 0x7c, 0x7d, 0x81, 0x85, 0x8a, 0x8a, 0x85, + 0x7e, 0x79, 0x78, 0x79, 0x7a, 0x7c, 0x7c, 0x7e, 0x81, 0x82, 0x83, 0x81, 0x7e, 0x7d, 0x7c, 0x7d, + 0x80, 0x7e, 0x7b, 0x7a, 0x7b, 0x7c, 0x81, 0x83, 0x83, 0x84, 0x81, 0x7d, 0x7a, 0x77, 0x78, 0x7a, + 0x7d, 0x80, 0x83, 0x85, 0x85, 0x83, 0x7e, 0x7a, 0x7c, 0x80, 0x82, 0x81, 0x7e, 0x7c, 0x7c, 0x7e, + 0x81, 0x82, 0x84, 0x84, 0x84, 0x84, 0x83, 0x82, 0x80, 0x7d, 0x7c, 0x7c, 0x7b, 0x7b, 0x7c, 0x7d, + 0x7d, 0x82, 0x86, 0x89, 0x89, 0x85, 0x7a, 0x6f, 0x69, 0x64, 0x62, 0x6f, 0x8f, 0xb2, 0xc9, 0xcc, + 0xb1, 0x80, 0x4f, 0x2c, 0x18, 0x24, 0x53, 0x8c, 0xb3, 0xc9, 0xd0, 0xbe, 0x9c, 0x78, 0x5b, 0x4b, + 0x4e, 0x5d, 0x76, 0x8b, 0x92, 0x9d, 0x9d, 0x90, 0x87, 0x7a, 0x70, 0x6c, 0x70, 0x7a, 0x86, 0x8b, + 0x8e, 0x8b, 0x83, 0x7b, 0x77, 0x78, 0x7a, 0x80, 0x82, 0x82, 0x83, 0x81, 0x7a, 0x79, 0x7e, 0x84, + 0x89, 0x8b, 0x85, 0x7b, 0x71, 0x6f, 0x71, 0x73, 0x79, 0x88, 0x94, 0x99, 0x96, 0x8f, 0x82, 0x6c, + 0x5f, 0x60, 0x67, 0x77, 0x8f, 0xa1, 0xa6, 0x9c, 0x85, 0x67, 0x56, 0x58, 0x69, 0x83, 0x99, 0xa7, + 0xa7, 0x97, 0x82, 0x6a, 0x57, 0x54, 0x5e, 0x74, 0x90, 0xa5, 0xa9, 0x9c, 0x86, 0x6f, 0x60, 0x5d, + 0x67, 0x7b, 0x8f, 0x98, 0x98, 0x8e, 0x7d, 0x6b, 0x60, 0x63, 0x70, 0x84, 0x99, 0xa5, 0xa4, 0x94, + 0x7d, 0x67, 0x58, 0x59, 0x63, 0x75, 0x89, 0x93, 0x96, 0x98, 0x96, 0x90, 0x86, 0x77, 0x69, 0x5f, + 0x5d, 0x69, 0x7c, 0x8d, 0x99, 0x9a, 0x92, 0x86, 0x74, 0x68, 0x68, 0x74, 0x84, 0x93, 0x9b, 0x98, + 0x8d, 0x7a, 0x69, 0x60, 0x61, 0x6a, 0x7a, 0x8d, 0x9e, 0xa4, 0x98, 0x83, 0x6c, 0x5e, 0x60, 0x6c, + 0x7d, 0x91, 0x98, 0x94, 0x8b, 0x79, 0x6c, 0x67, 0x6a, 0x78, 0x88, 0x92, 0x98, 0x8e, 0x7b, 0x69, + 0x61, 0x69, 0x7a, 0x8f, 0x9e, 0xa1, 0x97, 0x87, 0x78, 0x6d, 0x6a, 0x6e, 0x74, 0x7c, 0x82, 0x80, + 0x7c, 0x7d, 0x81, 0x85, 0x8b, 0x91, 0x92, 0x8b, 0x7d, 0x70, 0x64, 0x5d, 0x5c, 0x67, 0x80, 0x9a, + 0xb1, 0xbd, 0xb7, 0x9f, 0x7a, 0x53, 0x36, 0x31, 0x45, 0x6a, 0x99, 0xc5, 0xd8, 0xca, 0xa4, 0x73, + 0x46, 0x2a, 0x2d, 0x50, 0x83, 0xad, 0xc1, 0xba, 0xa3, 0x8a, 0x70, 0x5c, 0x53, 0x57, 0x67, 0x79, + 0x89, 0x9b, 0xa7, 0xa3, 0x93, 0x81, 0x71, 0x6a, 0x68, 0x69, 0x6d, 0x75, 0x78, 0x78, 0x80, 0x8c, + 0x9b, 0xaa, 0xb0, 0xa7, 0x91, 0x71, 0x4c, 0x34, 0x35, 0x4d, 0x78, 0xa9, 0xcc, 0xd8, 0xcd, 0xa7, + 0x73, 0x41, 0x19, 0xf, 0x29, 0x5f, 0xa5, 0xe3, 0xff, 0xf8, 0xc1, 0x6c, 0x22, 0x0, 0x9, 0x34, + 0x74, 0xb3, 0xdc, 0xe3, 0xca, 0x98, 0x64, 0x42, 0x36, 0x44, 0x6a, 0x96, 0xb6, 0xbb, 0xa5, 0x83, + 0x64, 0x57, 0x57, 0x5e, 0x71, 0x8d, 0x9f, 0xa4, 0x98, 0x85, 0x75, 0x6b, 0x6a, 0x73, 0x81, 0x8d, + 0x97, 0x94, 0x7a, 0x5e, 0x53, 0x5e, 0x7a, 0x91, 0xa1, 0xa6, 0x9c, 0x91, 0x78, 0x66, 0x66, 0x6c, + 0x7b, 0x82, 0x84, 0x93, 0x9c, 0x93, 0x85, 0x74, 0x62, 0x58, 0x62, 0x7a, 0x8f, 0xa3, 0xb3, 0xaf, + 0x92, 0x63, 0x40, 0x3c, 0x55, 0x81, 0xa8, 0xbb, 0xb4, 0x90, 0x65, 0x50, 0x58, 0x74, 0x8a, 0x95, + 0x96, 0x91, 0x87, 0x80, 0x7a, 0x70, 0x68, 0x68, 0x6f, 0x7e, 0x95, 0xa8, 0xa7, 0x98, 0x7d, 0x60, + 0x54, 0x5c, 0x6d, 0x81, 0x95, 0xa3, 0xa4, 0x99, 0x7d, 0x68, 0x5d, 0x5d, 0x67, 0x76, 0x88, 0x96, + 0x9f, 0xa2, 0x9d, 0x87, 0x6a, 0x53, 0x4d, 0x5e, 0x7a, 0x99, 0xad, 0xb1, 0xa3, 0x81, 0x62, 0x59, + 0x5d, 0x67, 0x77, 0x8d, 0x9c, 0x9b, 0x91, 0x83, 0x70, 0x64, 0x69, 0x7b, 0x93, 0xa1, 0x9e, 0x89, + 0x74, 0x64, 0x50, 0x4d, 0x69, 0x96, 0xbd, 0xc5, 0xad, 0x8a, 0x5c, 0x3d, 0x38, 0x46, 0x6c, 0x99, + 0xbb, 0xce, 0xc8, 0xa7, 0x72, 0x3e, 0x21, 0x27, 0x4f, 0x8b, 0xbc, 0xd1, 0xc7, 0xa5, 0x76, 0x50, + 0x3d, 0x41, 0x5e, 0x84, 0xa9, 0xc0, 0xb7, 0xa0, 0x82, 0x66, 0x58, 0x58, 0x60, 0x6e, 0x7e, 0x8e, + 0x9b, 0xa1, 0x9e, 0x97, 0x87, 0x71, 0x62, 0x57, 0x54, 0x61, 0x7c, 0xa1, 0xbb, 0xbd, 0xa9, 0x84, + 0x59, 0x3c, 0x3b, 0x57, 0x81, 0xa8, 0xc2, 0xc4, 0xac, 0x81, 0x58, 0x3d, 0x3a, 0x52, 0x75, 0x98, + 0xb4, 0xc2, 0xbb, 0xa1, 0x7b, 0x5a, 0x44, 0x3c, 0x4d, 0x6e, 0x93, 0xb0, 0xbc, 0xba, 0xa4, 0x80, + 0x5c, 0x45, 0x42, 0x52, 0x72, 0x98, 0xb2, 0xba, 0xaf, 0x92, 0x6e, 0x52, 0x45, 0x48, 0x5a, 0x7a, + 0x9c, 0xb1, 0xb8, 0xaf, 0x99, 0x7b, 0x60, 0x51, 0x51, 0x63, 0x7b, 0x96, 0xa8, 0xa8, 0x99, 0x82, + 0x6c, 0x5e, 0x59, 0x61, 0x76, 0x90, 0xa3, 0xa6, 0x9c, 0x89, 0x6f, 0x5a, 0x4d, 0x4f, 0x64, 0x82, + 0xa0, 0xb5, 0xb8, 0xad, 0x93, 0x72, 0x58, 0x49, 0x4d, 0x64, 0x83, 0x9f, 0xb3, 0xb5, 0xa5, 0x8b, + 0x6f, 0x59, 0x54, 0x5b, 0x67, 0x77, 0x8b, 0x98, 0x9d, 0x97, 0x8c, 0x7e, 0x71, 0x6a, 0x68, 0x6c, + 0x76, 0x86, 0x92, 0x9a, 0x9d, 0x98, 0x8a, 0x75, 0x61, 0x54, 0x55, 0x65, 0x83, 0xa0, 0xaf, 0xaa, + 0x99, 0x86, 0x75, 0x69, 0x5f, 0x5e, 0x67, 0x79, 0x8c, 0x96, 0x95, 0x8b, 0x80, 0x78, 0x76, 0x78, + 0x79, 0x76, 0x77, 0x80, 0x88, 0x89, 0x86, 0x86, 0x86, 0x84, 0x81, 0x7b, 0x78, 0x78, 0x7e, 0x83, + 0x81, 0x7c, 0x79, 0x7b, 0x84, 0x88, 0x86, 0x83, 0x80, 0x80, 0x82, 0x7e, 0x77, 0x74, 0x7b, 0x89, + 0x91, 0x89, 0x7a, 0x6f, 0x6c, 0x70, 0x7a, 0x84, 0x85, 0x81, 0x84, 0x89, 0x8e, 0x90, 0x8e, 0x8a, + 0x84, 0x7b, 0x6e, 0x63, 0x62, 0x71, 0x8c, 0xa5, 0xad, 0xa1, 0x8a, 0x73, 0x62, 0x58, 0x57, 0x5f, + 0x70, 0x8d, 0xa7, 0xb3, 0xae, 0x9c, 0x83, 0x68, 0x51, 0x41, 0x3e, 0x4f, 0x75, 0xa3, 0xc6, 0xd2, + 0xc3, 0x9b, 0x6b, 0x46, 0x35, 0x3a, 0x55, 0x7d, 0xa9, 0xc3, 0xc4, 0xb4, 0x95, 0x73, 0x5b, 0x4a, + 0x44, 0x4b, 0x5c, 0x79, 0x9b, 0xb7, 0xc2, 0xb5, 0x99, 0x7a, 0x5f, 0x4b, 0x45, 0x4d, 0x62, 0x7d, + 0x9a, 0xae, 0xb1, 0xaa, 0x9a, 0x8a, 0x7b, 0x64, 0x4d, 0x45, 0x50, 0x6b, 0x8e, 0xaa, 0xb4, 0xad, + 0x9d, 0x82, 0x68, 0x58, 0x53, 0x5b, 0x6d, 0x85, 0x97, 0xa4, 0xa9, 0xa4, 0x97, 0x81, 0x66, 0x56, + 0x54, 0x62, 0x78, 0x8e, 0x9d, 0xa3, 0x9c, 0x8e, 0x80, 0x75, 0x6d, 0x65, 0x63, 0x6a, 0x77, 0x89, + 0x97, 0x9d, 0x98, 0x8c, 0x7c, 0x6f, 0x67, 0x65, 0x67, 0x6e, 0x7d, 0x92, 0xa3, 0xa8, 0xa2, 0x95, + 0x84, 0x71, 0x63, 0x5d, 0x5f, 0x68, 0x78, 0x8a, 0x95, 0x98, 0x93, 0x88, 0x7e, 0x79, 0x76, 0x76, + 0x77, 0x7a, 0x81, 0x84, 0x85, 0x84, 0x82, 0x80, 0x7e, 0x81, 0x82, 0x81, 0x7b, 0x77, 0x75, 0x77, + 0x7c, 0x85, 0x8e, 0x96, 0x96, 0x8c, 0x7e, 0x6f, 0x64, 0x61, 0x66, 0x75, 0x85, 0x8c, 0x91, 0x90, + 0x8b, 0x86, 0x80, 0x7a, 0x78, 0x78, 0x7c, 0x81, 0x81, 0x7b, 0x79, 0x79, 0x7d, 0x82, 0x83, 0x80, + 0x79, 0x76, 0x79, 0x82, 0x8a, 0x90, 0x92, 0x8e, 0x88, 0x7c, 0x6e, 0x66, 0x66, 0x6b, 0x7b, 0x8f, + 0x99, 0x97, 0x8e, 0x86, 0x7e, 0x79, 0x75, 0x71, 0x6f, 0x73, 0x7b, 0x85, 0x8b, 0x8d, 0x8b, 0x88, + 0x82, 0x7a, 0x72, 0x6f, 0x72, 0x78, 0x7d, 0x81, 0x79, 0x69, 0x5b, 0x56, 0x64, 0x83, 0xa7, 0xc6, + 0xce, 0xc2, 0xa4, 0x7e, 0x5d, 0x48, 0x45, 0x52, 0x67, 0x7e, 0x91, 0x9c, 0xa1, 0x9d, 0x91, 0x7e, + 0x66, 0x4f, 0x3f, 0x3f, 0x51, 0x75, 0xa0, 0xc1, 0xd2, 0xc7, 0xa7, 0x80, 0x5b, 0x49, 0x4c, 0x5d, + 0x7b, 0x97, 0xa9, 0xaf, 0xa7, 0x9a, 0x87, 0x72, 0x60, 0x52, 0x49, 0x4b, 0x58, 0x71, 0x92, 0xaa, + 0xb4, 0xac, 0x97, 0x7c, 0x65, 0x5a, 0x5f, 0x6e, 0x82, 0x93, 0x9f, 0xa0, 0x9a, 0x90, 0x85, 0x7a, + 0x6f, 0x64, 0x5d, 0x5b, 0x61, 0x70, 0x84, 0x93, 0x9b, 0x9d, 0x97, 0x8b, 0x80, 0x76, 0x70, 0x70, + 0x6e, 0x6c, 0x6c, 0x6f, 0x7b, 0x8c, 0x9d, 0xa6, 0xa3, 0x98, 0x89, 0x7a, 0x6b, 0x5f, 0x5c, 0x62, + 0x6e, 0x80, 0x8e, 0x99, 0xa2, 0xa5, 0x9c, 0x84, 0x66, 0x53, 0x50, 0x5d, 0x74, 0x8e, 0x9e, 0xa2, + 0x9a, 0x8e, 0x84, 0x80, 0x7d, 0x7b, 0x74, 0x65, 0x5a, 0x5d, 0x72, 0x90, 0xa7, 0xb1, 0xa9, 0x95, + 0x7b, 0x69, 0x62, 0x64, 0x6c, 0x78, 0x84, 0x89, 0x8b, 0x8d, 0x8e, 0x8c, 0x8a, 0x84, 0x7a, 0x73, + 0x6d, 0x6b, 0x6f, 0x72, 0x6e, 0x66, 0x5d, 0x5b, 0x6b, 0x89, 0xab, 0xc3, 0xc7, 0xba, 0xa1, 0x83, + 0x6d, 0x63, 0x62, 0x67, 0x6d, 0x70, 0x72, 0x77, 0x7d, 0x85, 0x8b, 0x8a, 0x84, 0x7b, 0x72, 0x6a, + 0x67, 0x69, 0x6e, 0x75, 0x7a, 0x7c, 0x82, 0x8c, 0x96, 0x9e, 0xa2, 0x9e, 0x95, 0x8a, 0x81, 0x7b, + 0x7a, 0x7b, 0x79, 0x75, 0x71, 0x6e, 0x71, 0x79, 0x7d, 0x7e, 0x7a, 0x72, 0x70, 0x72, 0x76, 0x83, + 0x8e, 0x93, 0x93, 0x8c, 0x80, 0x77, 0x71, 0x70, 0x76, 0x7e, 0x87, 0x8d, 0x92, 0x95, 0x93, 0x8c, + 0x80, 0x71, 0x66, 0x60, 0x60, 0x66, 0x72, 0x81, 0x8d, 0x93, 0x96, 0x96, 0x94, 0x8f, 0x87, 0x7e, + 0x74, 0x69, 0x61, 0x62, 0x6e, 0x7c, 0x86, 0x8d, 0x8f, 0x8c, 0x89, 0x89, 0x8c, 0x8d, 0x8a, 0x82, + 0x78, 0x6c, 0x67, 0x6a, 0x70, 0x78, 0x81, 0x86, 0x8c, 0x90, 0x92, 0x93, 0x8e, 0x85, 0x79, 0x6e, + 0x67, 0x66, 0x6b, 0x75, 0x84, 0x90, 0x96, 0x96, 0x91, 0x8c, 0x85, 0x79, 0x6f, 0x66, 0x63, 0x67, + 0x6f, 0x7c, 0x8c, 0x99, 0x9e, 0x9d, 0x96, 0x89, 0x79, 0x6f, 0x69, 0x67, 0x6b, 0x74, 0x7e, 0x88, + 0x8b, 0x8a, 0x85, 0x7b, 0x71, 0x6a, 0x6a, 0x71, 0x80, 0x8e, 0x98, 0x9f, 0x9f, 0x95, 0x8b, 0x7c, + 0x6f, 0x69, 0x66, 0x68, 0x70, 0x78, 0x83, 0x8b, 0x90, 0x92, 0x8e, 0x87, 0x7c, 0x72, 0x6d, 0x6c, + 0x70, 0x78, 0x83, 0x8d, 0x93, 0x94, 0x90, 0x8a, 0x83, 0x7a, 0x73, 0x6f, 0x6f, 0x73, 0x79, 0x82, + 0x88, 0x8b, 0x8c, 0x8a, 0x85, 0x80, 0x7c, 0x78, 0x76, 0x76, 0x77, 0x7a, 0x7d, 0x80, 0x83, 0x87, + 0x8b, 0x8b, 0x8c, 0x8a, 0x84, 0x7c, 0x74, 0x6d, 0x6c, 0x6f, 0x76, 0x82, 0x8b, 0x93, 0x96, 0x95, + 0x8f, 0x87, 0x7b, 0x70, 0x69, 0x66, 0x69, 0x70, 0x7a, 0x86, 0x8e, 0x93, 0x94, 0x8d, 0x85, 0x7c, + 0x75, 0x72, 0x72, 0x74, 0x77, 0x7b, 0x80, 0x83, 0x87, 0x87, 0x87, 0x84, 0x80, 0x7d, 0x7a, 0x77, + 0x77, 0x7a, 0x7d, 0x80, 0x83, 0x83, 0x81, 0x7d, 0x7b, 0x7a, 0x7c, 0x7d, 0x82, 0x85, 0x87, 0x87, + 0x85, 0x82, 0x7c, 0x78, 0x75, 0x75, 0x78, 0x80, 0x86, 0x8a, 0x8e, 0x8e, 0x89, 0x83, 0x7b, 0x72, + 0x6e, 0x6e, 0x70, 0x77, 0x80, 0x88, 0x8e, 0x90, 0x8d, 0x87, 0x7e, 0x74, 0x6e, 0x6c, 0x70, 0x79, + 0x85, 0x8a, 0x8e, 0x8e, 0x88, 0x83, 0x7c, 0x77, 0x74, 0x75, 0x77, 0x7b, 0x83, 0x87, 0x88, 0x87, + 0x82, 0x7d, 0x7d, 0x7c, 0x7c, 0x7e, 0x80, 0x80, 0x80, 0x7d, 0x7c, 0x7a, 0x7a, 0x7d, 0x80, 0x83, + 0x85, 0x86, 0x83, 0x81, 0x7c, 0x7a, 0x7a, 0x7a, 0x7c, 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7e, 0x81, + 0x83, 0x84, 0x83, 0x83, 0x82, 0x7e, 0x7a, 0x77, 0x73, 0x73, 0x76, 0x79, 0x80, 0x87, 0x8b, 0x8d, + 0x8a, 0x85, 0x81, 0x7a, 0x75, 0x74, 0x74, 0x76, 0x7a, 0x7e, 0x84, 0x88, 0x8a, 0x8a, 0x88, 0x84, + 0x7d, 0x77, 0x73, 0x72, 0x75, 0x7b, 0x83, 0x88, 0x8c, 0x8b, 0x86, 0x81, 0x7a, 0x76, 0x75, 0x76, + 0x78, 0x7b, 0x81, 0x86, 0x89, 0x89, 0x87, 0x82, 0x7b, 0x76, 0x74, 0x75, 0x78, 0x7d, 0x83, 0x84, + 0x85, 0x84, 0x82, 0x80, 0x7c, 0x7b, 0x7c, 0x7b, 0x7d, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7d, 0x7d, + 0x7e, 0x80, 0x82, 0x83, 0x82, 0x82, 0x80, 0x7d, 0x7c, 0x7d, 0x7d, 0x7e, 0x81, 0x81, 0x7e, 0x7e, + 0x7e, 0x7c, 0x7d, 0x7d, 0x7d, 0x80, 0x82, 0x83, 0x82, 0x80, 0x7e, 0x7b, 0x7a, 0x7c, 0x7e, 0x83, + 0x83, 0x82, 0x82, 0x80, 0x80, 0x81, 0x83, 0x85, 0x84, 0x82, 0x80, 0x7d, 0x7b, 0x79, 0x78, 0x78, + 0x7a, 0x7d, 0x82, 0x87, 0x88, 0x87, 0x83, 0x7d, 0x79, 0x79, 0x79, 0x7c, 0x80, 0x83, 0x83, 0x82, + 0x81, 0x7c, 0x7c, 0x7d, 0x7d, 0x80, 0x81, 0x82, 0x82, 0x82, 0x82, 0x7e, 0x7c, 0x7c, 0x7c, 0x7e, + 0x80, 0x81, 0x82, 0x83, 0x81, 0x7e, 0x7c, 0x7b, 0x7c, 0x7d, 0x81, 0x85, 0x86, 0x85, 0x83, 0x80, + 0x7b, 0x78, 0x77, 0x77, 0x76, 0x79, 0x81, 0x86, 0x8a, 0x8b, 0x88, 0x81, 0x7b, 0x79, 0x78, 0x7b, + 0x7d, 0x7c, 0x7b, 0x7c, 0x7d, 0x82, 0x87, 0x88, 0x86, 0x81, 0x7c, 0x7a, 0x7b, 0x7e, 0x82, 0x83, + 0x81, 0x7d, 0x7c, 0x7d, 0x81, 0x82, 0x81, 0x80, 0x81, 0x80, 0x7d, 0x7c, 0x7b, 0x7a, 0x7c, 0x80, + 0x81, 0x7e, 0x7b, 0x7c, 0x7c, 0x79, 0x78, 0x7b, 0x7d, 0x80, 0x83, 0x84, 0x84, 0x83, 0x7e, 0x7a, + 0x79, 0x78, 0x76, 0x77, 0x7b, 0x84, 0x88, 0x87, 0x85, 0x83, 0x80, 0x7d, 0x7c, 0x7d, 0x7c, 0x7b, + 0x7c, 0x80, 0x80, 0x7e, 0x7e, 0x7d, 0x7e, 0x82, 0x86, 0x88, 0x86, 0x81, 0x7b, 0x79, 0x79, 0x78, + 0x79, 0x7a, 0x7c, 0x80, 0x84, 0x87, 0x86, 0x87, 0x85, 0x81, 0x7a, 0x75, 0x74, 0x77, 0x7b, 0x81, + 0x84, 0x84, 0x84, 0x81, 0x82, 0x82, 0x81, 0x82, 0x82, 0x80, 0x7b, 0x7b, 0x7b, 0x7a, 0x7c, 0x80, + 0x81, 0x81, 0x80, 0x7e, 0x7e, 0x7e, 0x81, 0x81, 0x80, 0x7e, 0x7e, 0x7d, 0x7e, 0x80, 0x81, 0x80, + 0x7e, 0x7e, 0x7d, 0x7d, 0x80, 0x80, 0x80, 0x81, 0x83, 0x82, 0x83, 0x82, 0x80, 0x7d, 0x7b, 0x79, + 0x77, 0x76, 0x77, 0x7b, 0x83, 0x8a, 0x8f, 0x8f, 0x87, 0x80, 0x78, 0x74, 0x73, 0x74, 0x7b, 0x80, + 0x83, 0x86, 0x85, 0x85, 0x84, 0x83, 0x80, 0x7c, 0x7a, 0x7b, 0x7c, 0x81, 0x85, 0x87, 0x87, 0x88, + 0x87, 0x83, 0x7e, 0x78, 0x77, 0x77, 0x77, 0x7b, 0x7e, 0x85, 0x89, 0x8b, 0x8c, 0x89, 0x82, 0x79, + 0x71, 0x70, 0x73, 0x76, 0x76, 0x76, 0x78, 0x80, 0x88, 0x8e, 0x90, 0x8b, 0x83, 0x78, 0x70, 0x6f, + 0x70, 0x77, 0x83, 0x88, 0x8a, 0x89, 0x85, 0x82, 0x81, 0x7e, 0x7a, 0x77, 0x7b, 0x82, 0x88, 0x87, + 0x7e, 0x76, 0x72, 0x75, 0x7b, 0x84, 0x8b, 0x8c, 0x87, 0x81, 0x79, 0x78, 0x7c, 0x81, 0x83, 0x7d, + 0x7a, 0x79, 0x7c, 0x85, 0x88, 0x85, 0x7e, 0x77, 0x74, 0x79, 0x7d, 0x81, 0x84, 0x83, 0x80, 0x7e, + 0x7d, 0x7a, 0x7c, 0x82, 0x80, 0x7c, 0x79, 0x78, 0x7e, 0x84, 0x84, 0x83, 0x82, 0x81, 0x7e, 0x7d, + 0x7c, 0x7d, 0x7e, 0x7a, 0x7b, 0x7e, 0x7e, 0x80, 0x82, 0x84, 0x87, 0x89, 0x86, 0x82, 0x81, 0x7d, + 0x7a, 0x78, 0x7a, 0x7e, 0x81, 0x82, 0x84, 0x83, 0x82, 0x82, 0x82, 0x80, 0x80, 0x7e, 0x79, 0x78, + 0x79, 0x7c, 0x7e, 0x7e, 0x7e, 0x81, 0x80, 0x7c, 0x7b, 0x7c, 0x7e, 0x81, 0x81, 0x83, 0x83, 0x82, + 0x82, 0x7e, 0x7d, 0x7b, 0x79, 0x7b, 0x80, 0x83, 0x84, 0x88, 0x86, 0x82, 0x7d, 0x77, 0x76, 0x79, + 0x7d, 0x82, 0x85, 0x87, 0x89, 0x88, 0x87, 0x84, 0x79, 0x74, 0x6f, 0x6c, 0x74, 0x7c, 0x87, 0x8d, + 0x8b, 0x8a, 0x84, 0x7d, 0x7a, 0x77, 0x74, 0x74, 0x76, 0x77, 0x7d, 0x84, 0x87, 0x87, 0x85, 0x80, + 0x7d, 0x81, 0x81, 0x81, 0x7e, 0x78, 0x78, 0x77, 0x79, 0x7e, 0x84, 0x85, 0x83, 0x82, 0x7e, 0x7e, + 0x84, 0x87, 0x87, 0x86, 0x81, 0x79, 0x76, 0x7a, 0x7c, 0x80, 0x82, 0x80, 0x80, 0x82, 0x88, 0x8e, + 0x8e, 0x8b, 0x83, 0x7a, 0x72, 0x6e, 0x6d, 0x72, 0x7c, 0x86, 0x8a, 0x8c, 0x8d, 0x8a, 0x88, 0x83, + 0x7b, 0x72, 0x6b, 0x6a, 0x6d, 0x77, 0x84, 0x8c, 0x91, 0x8f, 0x87, 0x80, 0x7d, 0x7c, 0x7d, 0x7e, + 0x7a, 0x78, 0x77, 0x77, 0x7b, 0x82, 0x85, 0x87, 0x88, 0x85, 0x86, 0x86, 0x85, 0x84, 0x80, 0x7b, + 0x78, 0x76, 0x77, 0x7a, 0x80, 0x80, 0x81, 0x83, 0x83, 0x85, 0x87, 0x87, 0x85, 0x80, 0x7b, 0x76, + 0x75, 0x77, 0x76, 0x78, 0x7c, 0x7e, 0x81, 0x84, 0x86, 0x87, 0x8a, 0x8a, 0x87, 0x81, 0x7c, 0x78, + 0x73, 0x74, 0x75, 0x78, 0x84, 0x8d, 0x8e, 0x8c, 0x87, 0x7e, 0x79, 0x7a, 0x7c, 0x81, 0x80, 0x7d, + 0x7a, 0x7a, 0x7e, 0x83, 0x87, 0x89, 0x86, 0x84, 0x80, 0x7b, 0x78, 0x73, 0x72, 0x74, 0x77, 0x81, + 0x8b, 0x8f, 0x8e, 0x86, 0x7b, 0x73, 0x6e, 0x71, 0x78, 0x7b, 0x7e, 0x81, 0x80, 0x82, 0x86, 0x89, + 0x8a, 0x86, 0x7c, 0x75, 0x74, 0x77, 0x7b, 0x81, 0x84, 0x83, 0x82, 0x7e, 0x81, 0x85, 0x87, 0x88, + 0x86, 0x80, 0x7a, 0x77, 0x77, 0x7b, 0x7e, 0x82, 0x84, 0x83, 0x83, 0x83, 0x83, 0x83, 0x80, 0x7d, + 0x7c, 0x7b, 0x7c, 0x81, 0x83, 0x83, 0x80, 0x79, 0x74, 0x70, 0x70, 0x74, 0x7a, 0x86, 0x8f, 0x92, + 0x90, 0x89, 0x7d, 0x74, 0x71, 0x70, 0x74, 0x78, 0x7a, 0x7c, 0x7d, 0x7c, 0x7d, 0x82, 0x86, 0x8c, + 0x8f, 0x8d, 0x88, 0x7d, 0x74, 0x73, 0x72, 0x76, 0x7a, 0x7b, 0x82, 0x86, 0x89, 0x8e, 0x8e, 0x8b, + 0x86, 0x7b, 0x76, 0x75, 0x78, 0x7e, 0x85, 0x86, 0x83, 0x80, 0x7c, 0x7c, 0x80, 0x84, 0x87, 0x87, + 0x84, 0x82, 0x80, 0x80, 0x7e, 0x7a, 0x75, 0x73, 0x72, 0x76, 0x7c, 0x82, 0x86, 0x87, 0x85, 0x86, + 0x88, 0x86, 0x81, 0x7b, 0x75, 0x6f, 0x6e, 0x72, 0x7a, 0x82, 0x8a, 0x90, 0x91, 0x8e, 0x88, 0x84, + 0x7b, 0x76, 0x72, 0x6f, 0x70, 0x78, 0x84, 0x8b, 0x8e, 0x8a, 0x7d, 0x73, 0x71, 0x76, 0x82, 0x8e, + 0x92, 0x8b, 0x7e, 0x71, 0x6c, 0x70, 0x78, 0x81, 0x82, 0x7e, 0x7a, 0x7b, 0x80, 0x89, 0x92, 0x92, + 0x89, 0x7c, 0x70, 0x6b, 0x6f, 0x76, 0x7b, 0x7e, 0x80, 0x82, 0x87, 0x8d, 0x92, 0x91, 0x8c, 0x82, + 0x75, 0x6f, 0x6d, 0x6f, 0x73, 0x79, 0x80, 0x86, 0x8d, 0x93, 0x93, 0x8d, 0x84, 0x76, 0x6b, 0x6a, + 0x73, 0x7c, 0x88, 0x8d, 0x8b, 0x88, 0x83, 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, 0x7c, 0x7a, 0x78, 0x78, + 0x78, 0x76, 0x78, 0x7c, 0x85, 0x91, 0x96, 0x91, 0x85, 0x72, 0x67, 0x68, 0x6f, 0x77, 0x80, 0x82, + 0x80, 0x7e, 0x81, 0x88, 0x93, 0x99, 0x94, 0x88, 0x78, 0x69, 0x66, 0x6e, 0x78, 0x80, 0x84, 0x82, + 0x82, 0x86, 0x8d, 0x91, 0x92, 0x8e, 0x84, 0x7b, 0x74, 0x6e, 0x71, 0x77, 0x7c, 0x7e, 0x80, 0x81, + 0x82, 0x86, 0x87, 0x87, 0x85, 0x83, 0x80, 0x7c, 0x7b, 0x7b, 0x7a, 0x77, 0x76, 0x77, 0x79, 0x7b, + 0x7e, 0x81, 0x84, 0x86, 0x86, 0x85, 0x86, 0x85, 0x81, 0x80, 0x79, 0x75, 0x73, 0x71, 0x75, 0x7a, + 0x80, 0x88, 0x8f, 0x95, 0x93, 0x85, 0x74, 0x67, 0x65, 0x74, 0x8c, 0x9c, 0x9e, 0x89, 0x69, 0x53, + 0x50, 0x66, 0x89, 0xa6, 0xae, 0x9d, 0x81, 0x6a, 0x65, 0x76, 0x8d, 0x97, 0x8b, 0x6f, 0x5b, 0x5a, + 0x6c, 0x88, 0x9e, 0xa2, 0x91, 0x7e, 0x74, 0x76, 0x83, 0x8f, 0x8f, 0x83, 0x71, 0x65, 0x64, 0x73, + 0x89, 0x97, 0x9a, 0x90, 0x80, 0x76, 0x76, 0x7b, 0x7e, 0x7d, 0x77, 0x74, 0x78, 0x81, 0x8a, 0x8f, + 0x8c, 0x83, 0x77, 0x70, 0x6e, 0x76, 0x84, 0x8e, 0x94, 0x92, 0x8c, 0x87, 0x84, 0x84, 0x83, 0x7c, + 0x72, 0x66, 0x58, 0x4b, 0x44, 0x46, 0x5b, 0x81, 0xad, 0xce, 0xd4, 0xba, 0x93, 0x73, 0x66, 0x66, + 0x6b, 0x6c, 0x67, 0x66, 0x69, 0x72, 0x84, 0x9e, 0xba, 0xc7, 0xb8, 0x93, 0x67, 0x54, 0x57, 0x68, + 0x73, 0x6d, 0x60, 0x57, 0x62, 0x7c, 0x98, 0xa6, 0xa9, 0xa2, 0x92, 0x7b, 0x68, 0x63, 0x6b, 0x78, + 0x83, 0x85, 0x80, 0x7d, 0x86, 0x92, 0x98, 0x94, 0x87, 0x7c, 0x77, 0x76, 0x78, 0x7a, 0x7b, 0x7a, + 0x7b, 0x7d, 0x7c, 0x7a, 0x79, 0x7d, 0x80, 0x80, 0x80, 0x7c, 0x7c, 0x83, 0x8a, 0x8d, 0x8c, 0x8a, + 0x87, 0x86, 0x85, 0x80, 0x7a, 0x79, 0x7b, 0x7c, 0x7b, 0x7c, 0x80, 0x84, 0x8a, 0x8b, 0x89, 0x84, + 0x77, 0x68, 0x59, 0x53, 0x55, 0x64, 0x81, 0x9b, 0xa9, 0xab, 0xa5, 0x9a, 0x8e, 0x87, 0x7c, 0x73, + 0x6d, 0x6b, 0x69, 0x6d, 0x76, 0x83, 0x91, 0x96, 0x94, 0x89, 0x77, 0x6e, 0x6c, 0x6e, 0x72, 0x73, + 0x76, 0x7a, 0x7d, 0x86, 0x8d, 0x8e, 0x8f, 0x8a, 0x84, 0x7c, 0x75, 0x76, 0x7e, 0x88, 0x8f, 0x90, + 0x8a, 0x85, 0x7e, 0x79, 0x76, 0x73, 0x74, 0x77, 0x79, 0x81, 0x86, 0x87, 0x89, 0x88, 0x85, 0x83, + 0x80, 0x7a, 0x75, 0x70, 0x69, 0x5f, 0x56, 0x54, 0x60, 0x7e, 0xa4, 0xc7, 0xd1, 0xc3, 0xa9, 0x86, + 0x6b, 0x5d, 0x57, 0x56, 0x57, 0x5e, 0x68, 0x75, 0x86, 0x95, 0xa1, 0xa5, 0x9a, 0x84, 0x68, 0x53, + 0x50, 0x59, 0x6c, 0x7b, 0x83, 0x8c, 0x97, 0xa3, 0xab, 0xa6, 0x9b, 0x8d, 0x79, 0x6b, 0x5e, 0x5b, + 0x66, 0x76, 0x85, 0x8e, 0x8f, 0x8c, 0x86, 0x81, 0x7b, 0x70, 0x64, 0x5f, 0x64, 0x71, 0x85, 0x96, + 0xa1, 0xa5, 0xa1, 0x93, 0x81, 0x6f, 0x62, 0x5e, 0x63, 0x6f, 0x79, 0x87, 0x94, 0x99, 0x98, 0x93, + 0x8b, 0x82, 0x7c, 0x79, 0x75, 0x71, 0x68, 0x5d, 0x5a, 0x63, 0x73, 0x8a, 0xa2, 0xb6, 0xba, 0xae, + 0x99, 0x7a, 0x5a, 0x40, 0x30, 0x2c, 0x3b, 0x5e, 0x8b, 0xb8, 0xd9, 0xe6, 0xdd, 0xc1, 0x99, 0x6a, + 0x43, 0x2e, 0x2c, 0x3c, 0x59, 0x77, 0x92, 0xa8, 0xb5, 0xb8, 0xaf, 0x9a, 0x7c, 0x5d, 0x42, 0x34, + 0x38, 0x50, 0x75, 0xa6, 0xd0, 0xe1, 0xd9, 0xba, 0x90, 0x64, 0x47, 0x3b, 0x3c, 0x4b, 0x5f, 0x77, + 0x91, 0xa7, 0xb3, 0xad, 0x9d, 0x86, 0x68, 0x51, 0x48, 0x4f, 0x64, 0x7e, 0x9b, 0xb2, 0xbb, 0xba, + 0xb1, 0x9c, 0x82, 0x6a, 0x55, 0x4b, 0x49, 0x4f, 0x5a, 0x69, 0x75, 0x7c, 0x7e, 0x87, 0x9b, 0xb3, + 0xc4, 0xbe, 0x9d, 0x70, 0x53, 0x4d, 0x5b, 0x74, 0x85, 0x8e, 0x95, 0x99, 0x9a, 0x91, 0x81, 0x76, + 0x6c, 0x62, 0x57, 0x4e, 0x53, 0x69, 0x8a, 0xa5, 0xb0, 0xa9, 0x9b, 0x8c, 0x83, 0x80, 0x74, 0x6d, + 0x6f, 0x73, 0x78, 0x7e, 0x87, 0x91, 0x97, 0x98, 0x90, 0x7e, 0x6e, 0x61, 0x60, 0x68, 0x71, 0x7a, + 0x84, 0x8f, 0x99, 0x9d, 0x9b, 0x93, 0x89, 0x80, 0x74, 0x6b, 0x64, 0x63, 0x6d, 0x7c, 0x8c, 0x96, + 0x9a, 0x99, 0x91, 0x89, 0x7d, 0x72, 0x6f, 0x72, 0x79, 0x83, 0x8a, 0x8b, 0x87, 0x82, 0x7a, 0x6f, + 0x64, 0x5e, 0x61, 0x70, 0x83, 0x97, 0xab, 0xbb, 0xc1, 0xb5, 0x93, 0x61, 0x39, 0x28, 0x30, 0x4e, + 0x79, 0xa2, 0xbd, 0xc9, 0xc2, 0xaa, 0x86, 0x62, 0x4a, 0x40, 0x44, 0x57, 0x72, 0x94, 0xb5, 0xcb, + 0xcd, 0xb5, 0x90, 0x6a, 0x4a, 0x39, 0x3a, 0x4b, 0x65, 0x8a, 0xaa, 0xbb, 0xbe, 0xb2, 0x98, 0x7a, + 0x5d, 0x43, 0x39, 0x40, 0x5b, 0x83, 0xac, 0xca, 0xd3, 0xc5, 0xa3, 0x79, 0x53, 0x36, 0x30, 0x3d, + 0x5a, 0x81, 0xa1, 0xb8, 0xc4, 0xba, 0xa6, 0x89, 0x67, 0x50, 0x45, 0x45, 0x50, 0x5f, 0x73, 0x84, + 0x97, 0xab, 0xbd, 0xc7, 0xbf, 0xa4, 0x74, 0x48, 0x33, 0x36, 0x53, 0x78, 0x93, 0xa5, 0xac, 0xa9, + 0x9a, 0x86, 0x6f, 0x5d, 0x52, 0x51, 0x56, 0x64, 0x7b, 0x98, 0xaf, 0xb8, 0xb1, 0x99, 0x7a, 0x64, + 0x5a, 0x5c, 0x66, 0x72, 0x82, 0x92, 0x9a, 0x98, 0x92, 0x88, 0x81, 0x77, 0x6b, 0x64, 0x62, 0x67, + 0x78, 0x8a, 0x94, 0x97, 0x92, 0x8d, 0x86, 0x7d, 0x77, 0x76, 0x78, 0x7c, 0x81, 0x81, 0x7e, 0x7b, + 0x7a, 0x7c, 0x7e, 0x7e, 0x84, 0x88, 0x89, 0x88, 0x85, 0x84, 0x85, 0x89, 0x8d, 0x8e, 0x87, 0x75, + 0x63, 0x57, 0x5a, 0x6a, 0x80, 0x93, 0x9d, 0x98, 0x8c, 0x83, 0x80, 0x85, 0x8c, 0x8b, 0x78, 0x59, + 0x3f, 0x39, 0x51, 0x81, 0xb8, 0xde, 0xe0, 0xc2, 0x92, 0x60, 0x3a, 0x2a, 0x33, 0x4e, 0x6e, 0x8f, + 0xa9, 0xba, 0xc1, 0xb6, 0x9b, 0x75, 0x51, 0x38, 0x38, 0x50, 0x76, 0xa0, 0xbd, 0xc9, 0xc0, 0xa5, + 0x84, 0x62, 0x4d, 0x44, 0x4a, 0x5d, 0x75, 0x8f, 0xa7, 0xb1, 0xab, 0x9c, 0x83, 0x6c, 0x5e, 0x5a, + 0x5f, 0x6d, 0x82, 0x94, 0xa0, 0xa3, 0x9c, 0x8f, 0x7c, 0x6a, 0x61, 0x5f, 0x65, 0x6c, 0x75, 0x7d, + 0x81, 0x84, 0x82, 0x85, 0x90, 0x99, 0xa0, 0x99, 0x88, 0x73, 0x65, 0x68, 0x73, 0x7c, 0x83, 0x85, + 0x86, 0x89, 0x88, 0x83, 0x7a, 0x72, 0x6f, 0x6d, 0x6c, 0x70, 0x7a, 0x8a, 0x98, 0x9d, 0x96, 0x8a, + 0x7d, 0x73, 0x6f, 0x70, 0x74, 0x7a, 0x82, 0x89, 0x8c, 0x89, 0x84, 0x80, 0x7c, 0x76, 0x6e, 0x66, + 0x67, 0x73, 0x81, 0x8f, 0x97, 0x93, 0x8c, 0x85, 0x81, 0x7a, 0x76, 0x79, 0x81, 0x87, 0x89, 0x87, + 0x82, 0x7b, 0x73, 0x6c, 0x69, 0x6c, 0x72, 0x82, 0x90, 0x96, 0x96, 0x94, 0x94, 0x96, 0x90, 0x82, + 0x73, 0x68, 0x65, 0x66, 0x68, 0x6b, 0x6f, 0x72, 0x73, 0x71, 0x6f, 0x7c, 0x99, 0xb2, 0xb6, 0xa5, + 0x8d, 0x77, 0x66, 0x5f, 0x60, 0x64, 0x6c, 0x81, 0x9c, 0xab, 0xa7, 0x97, 0x7b, 0x5b, 0x46, 0x45, + 0x55, 0x71, 0x8f, 0xa2, 0xac, 0xaa, 0x9e, 0x8e, 0x7c, 0x6f, 0x63, 0x61, 0x6e, 0x87, 0xa0, 0xad, + 0xa8, 0x96, 0x78, 0x5b, 0x4c, 0x49, 0x55, 0x69, 0x85, 0x9f, 0xab, 0xa7, 0x97, 0x82, 0x6d, 0x63, + 0x65, 0x71, 0x83, 0x92, 0x9c, 0x9c, 0x92, 0x82, 0x74, 0x6a, 0x63, 0x60, 0x64, 0x6d, 0x77, 0x7b, + 0x78, 0x6e, 0x69, 0x7b, 0xa2, 0xc6, 0xcf, 0xb0, 0x7a, 0x4f, 0x45, 0x59, 0x7c, 0x99, 0xa1, 0x9b, + 0x8e, 0x7a, 0x66, 0x58, 0x53, 0x5e, 0x70, 0x80, 0x87, 0x90, 0x9d, 0xa5, 0x9f, 0x87, 0x69, 0x57, + 0x56, 0x68, 0x81, 0x97, 0xab, 0xb1, 0xac, 0x9e, 0x7b, 0x55, 0x41, 0x46, 0x5b, 0x74, 0x90, 0xa5, + 0xaf, 0xac, 0x98, 0x79, 0x5d, 0x4d, 0x50, 0x62, 0x7e, 0x9c, 0xb1, 0xbe, 0xba, 0x9c, 0x6f, 0x48, + 0x38, 0x3e, 0x57, 0x78, 0x95, 0xac, 0xb6, 0xb3, 0xa2, 0x84, 0x63, 0x4d, 0x4b, 0x5b, 0x78, 0x99, + 0xb0, 0xb3, 0xa1, 0x7e, 0x5a, 0x45, 0x4c, 0x65, 0x81, 0x8f, 0x94, 0x9b, 0xa2, 0x9d, 0x8b, 0x73, + 0x5c, 0x48, 0x46, 0x5b, 0x7e, 0xa6, 0xc0, 0xc3, 0xa7, 0x7d, 0x5e, 0x57, 0x62, 0x73, 0x82, 0x8a, + 0x91, 0x92, 0x8f, 0x83, 0x70, 0x63, 0x5e, 0x6a, 0x7c, 0x92, 0x9e, 0xa2, 0x9d, 0x89, 0x6f, 0x60, + 0x61, 0x6f, 0x80, 0x8e, 0x98, 0x9c, 0x9a, 0x91, 0x82, 0x6c, 0x5d, 0x5c, 0x65, 0x74, 0x85, 0x91, + 0x96, 0x93, 0x8e, 0x83, 0x77, 0x70, 0x6a, 0x6a, 0x75, 0x84, 0x90, 0x9a, 0x9d, 0x95, 0x89, 0x77, + 0x68, 0x61, 0x5a, 0x5d, 0x6c, 0x86, 0xa5, 0xbc, 0xbd, 0xa1, 0x73, 0x50, 0x41, 0x4e, 0x70, 0x95, + 0xab, 0xac, 0xa0, 0x8e, 0x79, 0x69, 0x61, 0x5e, 0x62, 0x6f, 0x82, 0x93, 0xa0, 0xa5, 0x9d, 0x88, + 0x6b, 0x51, 0x46, 0x51, 0x70, 0x97, 0xb4, 0xbe, 0xb2, 0x96, 0x72, 0x57, 0x53, 0x5d, 0x6d, 0x81, + 0x8e, 0x93, 0x8d, 0x84, 0x7a, 0x75, 0x76, 0x79, 0x7d, 0x82, 0x86, 0x87, 0x86, 0x83, 0x7d, 0x79, + 0x76, 0x76, 0x7b, 0x83, 0x87, 0x89, 0x87, 0x7e, 0x76, 0x73, 0x72, 0x76, 0x7b, 0x82, 0x88, 0x8d, + 0x93, 0x93, 0x8d, 0x82, 0x74, 0x6c, 0x6a, 0x6d, 0x76, 0x84, 0x8c, 0x8c, 0x82, 0x75, 0x71, 0x75, + 0x7c, 0x86, 0x8b, 0x8c, 0x89, 0x80, 0x79, 0x7c, 0x83, 0x89, 0x8d, 0x89, 0x81, 0x7b, 0x73, 0x6e, + 0x6d, 0x6e, 0x73, 0x80, 0x8f, 0x97, 0x96, 0x8f, 0x83, 0x76, 0x6d, 0x6a, 0x70, 0x7a, 0x88, 0x91, + 0x93, 0x92, 0x89, 0x7b, 0x72, 0x6d, 0x6d, 0x71, 0x7a, 0x87, 0x8f, 0x8f, 0x8f, 0x89, 0x80, 0x79, + 0x75, 0x72, 0x71, 0x70, 0x71, 0x79, 0x87, 0x98, 0xa5, 0xa6, 0x96, 0x79, 0x5a, 0x4d, 0x59, 0x74, + 0x94, 0xa6, 0xa2, 0x91, 0x7a, 0x67, 0x61, 0x67, 0x72, 0x7e, 0x89, 0x90, 0x94, 0x8f, 0x88, 0x7e, + 0x74, 0x6d, 0x6c, 0x74, 0x82, 0x8d, 0x97, 0x95, 0x86, 0x73, 0x68, 0x68, 0x71, 0x82, 0x8d, 0x94, + 0x92, 0x8a, 0x81, 0x77, 0x70, 0x6c, 0x6d, 0x75, 0x81, 0x8b, 0x91, 0x8f, 0x86, 0x7b, 0x74, 0x70, + 0x70, 0x77, 0x82, 0x88, 0x8c, 0x8b, 0x85, 0x7b, 0x74, 0x70, 0x6f, 0x73, 0x7c, 0x85, 0x8b, 0x91, + 0x8e, 0x88, 0x81, 0x76, 0x72, 0x71, 0x73, 0x7b, 0x84, 0x89, 0x89, 0x87, 0x86, 0x81, 0x7a, 0x76, + 0x77, 0x77, 0x76, 0x77, 0x7a, 0x7c, 0x7d, 0x81, 0x87, 0x8b, 0x8c, 0x87, 0x81, 0x7a, 0x73, 0x70, + 0x72, 0x79, 0x82, 0x86, 0x86, 0x83, 0x80, 0x80, 0x83, 0x85, 0x80, 0x7b, 0x7c, 0x7e, 0x85, 0x88, + 0x84, 0x79, 0x67, 0x4f, 0x43, 0x55, 0x8c, 0xca, 0xef, 0xe4, 0x9c, 0x44, 0x13, 0x1c, 0x55, 0x99, + 0xbf, 0xc4, 0xb0, 0x94, 0x77, 0x5c, 0x4b, 0x4a, 0x5c, 0x75, 0x8e, 0x9f, 0xa9, 0xae, 0xa5, 0x88, + 0x60, 0x48, 0x4c, 0x6b, 0x91, 0xa8, 0xac, 0x9e, 0x8b, 0x77, 0x69, 0x63, 0x67, 0x73, 0x80, 0x8a, + 0x8f, 0x87, 0x7d, 0x7a, 0x78, 0x76, 0x77, 0x83, 0x8c, 0x8d, 0x89, 0x81, 0x77, 0x73, 0x76, 0x7d, + 0x88, 0x8c, 0x8c, 0x8d, 0x8a, 0x81, 0x73, 0x6c, 0x6f, 0x76, 0x81, 0x8b, 0x92, 0x92, 0x8a, 0x7a, + 0x69, 0x64, 0x6c, 0x7e, 0x8f, 0x97, 0x96, 0x90, 0x88, 0x7a, 0x6b, 0x65, 0x6a, 0x74, 0x80, 0x8a, + 0x95, 0x98, 0x92, 0x88, 0x78, 0x68, 0x5c, 0x5a, 0x67, 0x81, 0x96, 0xa8, 0xaf, 0xa4, 0x89, 0x6a, + 0x57, 0x52, 0x5c, 0x72, 0x90, 0xa5, 0xac, 0xa5, 0x90, 0x76, 0x60, 0x53, 0x5c, 0x72, 0x8c, 0x9f, + 0xa7, 0xa2, 0x91, 0x7d, 0x6b, 0x60, 0x62, 0x6e, 0x81, 0x91, 0x97, 0x94, 0x8e, 0x83, 0x77, 0x71, + 0x72, 0x74, 0x74, 0x72, 0x6e, 0x6a, 0x6f, 0x82, 0x9e, 0xb6, 0xb8, 0x9f, 0x6f, 0x44, 0x37, 0x50, + 0x85, 0xb3, 0xc1, 0xaa, 0x7d, 0x58, 0x4f, 0x5a, 0x72, 0x89, 0x91, 0x90, 0x8d, 0x89, 0x83, 0x79, + 0x71, 0x6d, 0x6f, 0x77, 0x86, 0x95, 0xa2, 0xa1, 0x8f, 0x75, 0x5f, 0x59, 0x63, 0x75, 0x8a, 0x98, + 0x97, 0x8d, 0x81, 0x75, 0x72, 0x73, 0x75, 0x7b, 0x7d, 0x80, 0x88, 0x90, 0x91, 0x88, 0x7c, 0x74, + 0x72, 0x76, 0x7e, 0x87, 0x89, 0x86, 0x81, 0x7b, 0x78, 0x75, 0x75, 0x7b, 0x83, 0x85, 0x83, 0x7e, + 0x7b, 0x77, 0x76, 0x79, 0x7e, 0x86, 0x8d, 0x92, 0x8f, 0x85, 0x75, 0x6a, 0x69, 0x6d, 0x77, 0x85, + 0x8b, 0x86, 0x7d, 0x77, 0x7a, 0x81, 0x86, 0x88, 0x81, 0x79, 0x71, 0x6c, 0x6f, 0x79, 0x86, 0x8c, + 0x89, 0x83, 0x81, 0x82, 0x84, 0x81, 0x78, 0x71, 0x74, 0x80, 0x8e, 0x96, 0x92, 0x86, 0x75, 0x6a, + 0x69, 0x73, 0x85, 0x92, 0x95, 0x8e, 0x81, 0x75, 0x72, 0x74, 0x79, 0x81, 0x86, 0x8c, 0x90, 0x90, + 0x8a, 0x7d, 0x6e, 0x5e, 0x53, 0x59, 0x72, 0x9e, 0xc5, 0xd3, 0xbc, 0x82, 0x41, 0x1c, 0x2a, 0x62, + 0xab, 0xdb, 0xd9, 0xad, 0x6c, 0x3b, 0x32, 0x45, 0x69, 0x8e, 0xa2, 0xab, 0xa7, 0x9a, 0x83, 0x6a, + 0x56, 0x50, 0x5c, 0x75, 0x94, 0xac, 0xb4, 0xa4, 0x84, 0x61, 0x4b, 0x50, 0x67, 0x85, 0x9b, 0xa4, + 0x9e, 0x8b, 0x73, 0x65, 0x5e, 0x65, 0x77, 0x8a, 0x97, 0x9d, 0x97, 0x8a, 0x78, 0x6a, 0x65, 0x6b, + 0x78, 0x89, 0x93, 0x93, 0x8c, 0x80, 0x74, 0x6e, 0x6f, 0x76, 0x81, 0x8b, 0x91, 0x90, 0x85, 0x78, + 0x6f, 0x6e, 0x73, 0x7c, 0x87, 0x8e, 0x8f, 0x8a, 0x81, 0x77, 0x71, 0x73, 0x7b, 0x83, 0x88, 0x8a, + 0x86, 0x7e, 0x7a, 0x7a, 0x7c, 0x7b, 0x79, 0x7a, 0x7e, 0x84, 0x89, 0x8b, 0x84, 0x7a, 0x75, 0x77, + 0x7b, 0x7a, 0x76, 0x76, 0x79, 0x7d, 0x82, 0x86, 0x8c, 0x8b, 0x85, 0x81, 0x7c, 0x7a, 0x7d, 0x84, + 0x86, 0x85, 0x84, 0x83, 0x83, 0x82, 0x7c, 0x78, 0x76, 0x77, 0x7b, 0x80, 0x87, 0x8a, 0x86, 0x82, + 0x7c, 0x78, 0x77, 0x76, 0x77, 0x76, 0x75, 0x7a, 0x88, 0x98, 0xa5, 0xa7, 0x95, 0x71, 0x51, 0x47, + 0x58, 0x7e, 0xa9, 0xc3, 0xbb, 0x97, 0x67, 0x45, 0x3f, 0x53, 0x79, 0x9a, 0xa7, 0xa4, 0x96, 0x88, + 0x7a, 0x6f, 0x69, 0x67, 0x6e, 0x7c, 0x8e, 0x9b, 0x9b, 0x90, 0x7d, 0x6b, 0x63, 0x68, 0x77, 0x88, + 0x93, 0x96, 0x8d, 0x7e, 0x72, 0x6c, 0x6e, 0x74, 0x7e, 0x87, 0x8d, 0x90, 0x8d, 0x83, 0x7a, 0x74, + 0x73, 0x79, 0x81, 0x86, 0x86, 0x83, 0x7d, 0x79, 0x7a, 0x7e, 0x83, 0x85, 0x84, 0x82, 0x82, 0x7e, + 0x7a, 0x76, 0x75, 0x7a, 0x80, 0x85, 0x89, 0x8a, 0x85, 0x7c, 0x74, 0x71, 0x75, 0x7e, 0x89, 0x8d, + 0x8d, 0x86, 0x7a, 0x74, 0x73, 0x76, 0x7c, 0x82, 0x8b, 0x92, 0x92, 0x8a, 0x7a, 0x6f, 0x6d, 0x72, + 0x75, 0x79, 0x82, 0x89, 0x89, 0x84, 0x7e, 0x7d, 0x7d, 0x7d, 0x80, 0x84, 0x85, 0x7d, 0x70, 0x57, + 0x42, 0x4b, 0x7e, 0xc4, 0xef, 0xde, 0x9b, 0x4c, 0x1f, 0x2c, 0x5b, 0x93, 0xb7, 0xc2, 0xbd, 0x9d, + 0x6b, 0x46, 0x40, 0x54, 0x6c, 0x7d, 0x8f, 0xa3, 0xae, 0xa6, 0x89, 0x62, 0x4a, 0x4a, 0x63, 0x8b, + 0xab, 0xb8, 0xae, 0x92, 0x6f, 0x56, 0x50, 0x5b, 0x74, 0x91, 0xa1, 0x9e, 0x90, 0x80, 0x6e, 0x5e, + 0x58, 0x61, 0x73, 0x8c, 0xa5, 0xac, 0x9a, 0x7c, 0x68, 0x60, 0x5e, 0x6a, 0x86, 0xa3, 0xab, 0x9f, + 0x8e, 0x7c, 0x6e, 0x67, 0x6c, 0x74, 0x7a, 0x84, 0x8b, 0x86, 0x7a, 0x73, 0x76, 0x7a, 0x80, 0x87, + 0x8d, 0x8e, 0x87, 0x7c, 0x76, 0x75, 0x7a, 0x84, 0x8d, 0x90, 0x8d, 0x81, 0x72, 0x6b, 0x6a, 0x72, + 0x80, 0x89, 0x8d, 0x8b, 0x85, 0x79, 0x6e, 0x6a, 0x70, 0x7d, 0x89, 0x93, 0x96, 0x93, 0x87, 0x79, + 0x71, 0x6e, 0x72, 0x7c, 0x86, 0x8a, 0x8a, 0x85, 0x7e, 0x7b, 0x77, 0x77, 0x7a, 0x7a, 0x7a, 0x7b, + 0x7c, 0x7b, 0x7d, 0x7d, 0x81, 0x84, 0x86, 0x85, 0x82, 0x7c, 0x7a, 0x78, 0x7a, 0x80, 0x87, 0x8b, + 0x89, 0x7e, 0x6e, 0x61, 0x5f, 0x6f, 0x8d, 0xa9, 0xb3, 0xa1, 0x78, 0x4f, 0x40, 0x55, 0x81, 0xa9, + 0xb8, 0xa9, 0x89, 0x6a, 0x5e, 0x63, 0x6d, 0x79, 0x84, 0x8c, 0x91, 0x93, 0x90, 0x87, 0x78, 0x6b, + 0x65, 0x66, 0x73, 0x8c, 0x9e, 0xa1, 0x91, 0x78, 0x67, 0x65, 0x6d, 0x7a, 0x89, 0x8f, 0x8f, 0x8a, + 0x83, 0x7a, 0x72, 0x6b, 0x6c, 0x73, 0x7e, 0x8a, 0x92, 0x94, 0x8b, 0x7d, 0x71, 0x6b, 0x6d, 0x77, + 0x85, 0x8d, 0x8d, 0x86, 0x83, 0x7e, 0x78, 0x75, 0x75, 0x7b, 0x82, 0x89, 0x8e, 0x8e, 0x86, 0x79, + 0x6e, 0x6a, 0x6e, 0x79, 0x87, 0x8f, 0x8f, 0x87, 0x7a, 0x74, 0x72, 0x76, 0x80, 0x87, 0x8a, 0x89, + 0x85, 0x7c, 0x75, 0x6f, 0x6e, 0x73, 0x7c, 0x86, 0x8b, 0x89, 0x7e, 0x72, 0x69, 0x6b, 0x77, 0x85, + 0x90, 0x96, 0x93, 0x89, 0x7d, 0x76, 0x71, 0x70, 0x76, 0x83, 0x8d, 0x91, 0x8d, 0x87, 0x7e, 0x75, + 0x6f, 0x70, 0x76, 0x7c, 0x83, 0x86, 0x86, 0x85, 0x82, 0x7e, 0x7a, 0x75, 0x70, 0x6f, 0x77, 0x85, + 0x97, 0xa4, 0xa7, 0x97, 0x79, 0x5e, 0x52, 0x5e, 0x7a, 0x98, 0xa7, 0x9e, 0x81, 0x64, 0x59, 0x65, + 0x81, 0x9b, 0xa0, 0x94, 0x7e, 0x6e, 0x6a, 0x6b, 0x70, 0x74, 0x77, 0x83, 0x94, 0xa6, 0xae, 0xa2, + 0x86, 0x66, 0x54, 0x53, 0x62, 0x7c, 0x97, 0xa4, 0xa0, 0x90, 0x7b, 0x6c, 0x67, 0x6a, 0x71, 0x77, + 0x7c, 0x85, 0x8c, 0x8d, 0x86, 0x7c, 0x72, 0x70, 0x77, 0x85, 0x92, 0x94, 0x8b, 0x7d, 0x6f, 0x6c, + 0x70, 0x7a, 0x87, 0x8b, 0x8a, 0x84, 0x7a, 0x73, 0x71, 0x74, 0x7a, 0x84, 0x8e, 0x94, 0x91, 0x88, + 0x78, 0x69, 0x65, 0x6b, 0x77, 0x85, 0x8e, 0x91, 0x8e, 0x89, 0x83, 0x7d, 0x77, 0x71, 0x70, 0x74, + 0x7e, 0x89, 0x8d, 0x8a, 0x85, 0x81, 0x7b, 0x77, 0x7a, 0x80, 0x82, 0x7e, 0x7a, 0x79, 0x7b, 0x7d, + 0x82, 0x88, 0x8c, 0x8d, 0x89, 0x80, 0x6f, 0x58, 0x43, 0x43, 0x6a, 0xad, 0xe6, 0xeb, 0xb4, 0x60, + 0x24, 0x23, 0x50, 0x87, 0xad, 0xba, 0xb5, 0xa5, 0x8d, 0x6f, 0x55, 0x47, 0x4b, 0x5e, 0x7b, 0x9b, + 0xae, 0xb1, 0xa2, 0x81, 0x5b, 0x44, 0x47, 0x69, 0x96, 0xb3, 0xb7, 0x9f, 0x82, 0x6e, 0x66, 0x66, + 0x6e, 0x7c, 0x8d, 0x97, 0x99, 0x92, 0x81, 0x69, 0x59, 0x57, 0x64, 0x7b, 0x95, 0xa4, 0xa4, 0x96, + 0x7e, 0x67, 0x5b, 0x5b, 0x6b, 0x83, 0x94, 0x9c, 0x9e, 0x9c, 0x8f, 0x7b, 0x6b, 0x64, 0x6b, 0x77, + 0x89, 0x95, 0x95, 0x8a, 0x78, 0x6b, 0x68, 0x70, 0x7b, 0x86, 0x8d, 0x90, 0x8e, 0x8a, 0x84, 0x79, + 0x70, 0x6d, 0x70, 0x7a, 0x87, 0x91, 0x94, 0x8e, 0x85, 0x79, 0x72, 0x70, 0x6f, 0x73, 0x79, 0x7e, + 0x82, 0x87, 0x8d, 0x90, 0x8b, 0x81, 0x76, 0x71, 0x72, 0x7d, 0x8c, 0x93, 0x92, 0x89, 0x7e, 0x77, + 0x77, 0x7c, 0x83, 0x85, 0x84, 0x81, 0x7d, 0x7d, 0x7b, 0x7c, 0x7d, 0x80, 0x83, 0x82, 0x82, 0x82, + 0x81, 0x7d, 0x78, 0x74, 0x76, 0x7c, 0x87, 0x8f, 0x94, 0x92, 0x8a, 0x7b, 0x69, 0x5b, 0x53, 0x5c, + 0x76, 0x9e, 0xc3, 0xce, 0xb1, 0x74, 0x37, 0x1b, 0x36, 0x7a, 0xbb, 0xdd, 0xc7, 0x8d, 0x5b, 0x48, + 0x58, 0x72, 0x81, 0x7b, 0x75, 0x81, 0x9a, 0xaf, 0xab, 0x8a, 0x5f, 0x43, 0x44, 0x63, 0x8f, 0xab, + 0xb1, 0xa2, 0x8a, 0x70, 0x60, 0x5f, 0x68, 0x77, 0x85, 0x8d, 0x90, 0x90, 0x8c, 0x84, 0x77, 0x6a, + 0x64, 0x69, 0x79, 0x8d, 0x9a, 0x99, 0x8d, 0x7a, 0x6d, 0x69, 0x70, 0x7e, 0x8a, 0x8f, 0x8e, 0x8b, + 0x88, 0x81, 0x78, 0x71, 0x71, 0x78, 0x84, 0x8f, 0x94, 0x91, 0x83, 0x70, 0x66, 0x69, 0x77, 0x88, + 0x93, 0x96, 0x90, 0x84, 0x76, 0x6d, 0x6b, 0x70, 0x78, 0x84, 0x8f, 0x97, 0x99, 0x93, 0x83, 0x71, + 0x62, 0x5b, 0x62, 0x71, 0x86, 0x94, 0x97, 0x93, 0x87, 0x78, 0x6f, 0x6c, 0x6f, 0x74, 0x7e, 0x87, + 0x8b, 0x8c, 0x88, 0x84, 0x7e, 0x7e, 0x83, 0x84, 0x82, 0x78, 0x6e, 0x67, 0x6a, 0x7c, 0x96, 0xad, + 0xb1, 0x9b, 0x74, 0x4d, 0x41, 0x59, 0x82, 0xa9, 0xb5, 0xa1, 0x80, 0x65, 0x62, 0x72, 0x87, 0x8c, + 0x7c, 0x6d, 0x6c, 0x82, 0x9e, 0xad, 0xa1, 0x7b, 0x57, 0x49, 0x5b, 0x81, 0xa0, 0xa7, 0x9a, 0x82, + 0x72, 0x73, 0x79, 0x81, 0x81, 0x79, 0x74, 0x76, 0x81, 0x8d, 0x91, 0x8b, 0x7c, 0x71, 0x6f, 0x79, + 0x88, 0x90, 0x8e, 0x84, 0x77, 0x6f, 0x70, 0x7b, 0x87, 0x8e, 0x8b, 0x86, 0x83, 0x82, 0x81, 0x7c, + 0x77, 0x73, 0x74, 0x7d, 0x89, 0x91, 0x93, 0x8a, 0x7a, 0x6e, 0x6b, 0x6f, 0x79, 0x83, 0x87, 0x85, + 0x83, 0x82, 0x83, 0x83, 0x80, 0x7a, 0x75, 0x75, 0x7b, 0x84, 0x8a, 0x8c, 0x87, 0x80, 0x7a, 0x7a, + 0x7e, 0x82, 0x83, 0x7d, 0x77, 0x76, 0x7a, 0x84, 0x8c, 0x8e, 0x8a, 0x81, 0x7a, 0x77, 0x78, 0x7a, + 0x7b, 0x7c, 0x7b, 0x80, 0x85, 0x87, 0x88, 0x85, 0x80, 0x7b, 0x77, 0x74, 0x73, 0x74, 0x79, 0x7e, + 0x86, 0x8f, 0x94, 0x90, 0x83, 0x73, 0x66, 0x66, 0x71, 0x80, 0x8d, 0x8e, 0x88, 0x80, 0x7b, 0x7c, + 0x7e, 0x7e, 0x7b, 0x77, 0x75, 0x79, 0x82, 0x8a, 0x8e, 0x8c, 0x86, 0x7b, 0x74, 0x73, 0x77, 0x80, + 0x85, 0x86, 0x85, 0x83, 0x82, 0x82, 0x80, 0x7e, 0x7d, 0x7d, 0x7c, 0x7c, 0x7d, 0x80, 0x80, 0x7c, + 0x79, 0x78, 0x79, 0x7c, 0x82, 0x86, 0x87, 0x83, 0x7d, 0x79, 0x77, 0x77, 0x79, 0x7c, 0x7e, 0x7e, + 0x80, 0x82, 0x83, 0x83, 0x82, 0x80, 0x7a, 0x78, 0x78, 0x79, 0x7d, 0x83, 0x84, 0x84, 0x83, 0x81, + 0x80, 0x7e, 0x7c, 0x7a, 0x7a, 0x7a, 0x81, 0x87, 0x8c, 0x8b, 0x85, 0x7e, 0x78, 0x75, 0x76, 0x7a, + 0x7d, 0x81, 0x84, 0x86, 0x87, 0x86, 0x82, 0x7e, 0x79, 0x78, 0x78, 0x7a, 0x7b, 0x7c, 0x7e, 0x82, + 0x85, 0x86, 0x87, 0x84, 0x7d, 0x77, 0x74, 0x76, 0x79, 0x7e, 0x84, 0x89, 0x8b, 0x89, 0x82, 0x7c, + 0x7a, 0x79, 0x78, 0x79, 0x7d, 0x85, 0x8b, 0x8d, 0x8c, 0x86, 0x80, 0x7b, 0x75, 0x74, 0x75, 0x79, + 0x80, 0x85, 0x8c, 0x8e, 0x89, 0x82, 0x77, 0x75, 0x77, 0x7d, 0x83, 0x82, 0x7d, 0x78, 0x76, 0x79, + 0x81, 0x8a, 0x90, 0x8c, 0x80, 0x74, 0x71, 0x74, 0x7d, 0x84, 0x83, 0x80, 0x79, 0x7a, 0x80, 0x85, + 0x89, 0x87, 0x80, 0x73, 0x70, 0x76, 0x80, 0x89, 0x8b, 0x85, 0x80, 0x7d, 0x7e, 0x82, 0x82, 0x7d, + 0x78, 0x75, 0x78, 0x80, 0x86, 0x8c, 0x8e, 0x88, 0x7d, 0x74, 0x6f, 0x72, 0x78, 0x80, 0x85, 0x88, + 0x87, 0x83, 0x80, 0x80, 0x7d, 0x7a, 0x77, 0x79, 0x7d, 0x81, 0x84, 0x84, 0x82, 0x7e, 0x7a, 0x77, + 0x78, 0x7c, 0x81, 0x83, 0x82, 0x81, 0x7e, 0x7d, 0x7e, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x7d, 0x7b, + 0x7c, 0x7d, 0x7e, 0x7e, 0x7e, 0x81, 0x82, 0x83, 0x81, 0x7d, 0x79, 0x77, 0x78, 0x7b, 0x7d, 0x80, + 0x81, 0x82, 0x84, 0x84, 0x83, 0x81, 0x7c, 0x77, 0x75, 0x77, 0x7a, 0x7c, 0x7e, 0x80, 0x84, 0x88, + 0x88, 0x85, 0x7c, 0x77, 0x76, 0x79, 0x81, 0x89, 0x8a, 0x85, 0x7d, 0x77, 0x78, 0x80, 0x86, 0x8a, + 0x87, 0x7d, 0x79, 0x7a, 0x82, 0x8a, 0x8a, 0x85, 0x7a, 0x72, 0x71, 0x76, 0x80, 0x86, 0x86, 0x82, + 0x7a, 0x79, 0x80, 0x85, 0x88, 0x85, 0x7c, 0x76, 0x74, 0x77, 0x7e, 0x86, 0x89, 0x87, 0x80, 0x78, + 0x77, 0x7b, 0x81, 0x82, 0x7d, 0x7b, 0x7c, 0x80, 0x83, 0x85, 0x82, 0x7b, 0x76, 0x75, 0x78, 0x80, + 0x85, 0x87, 0x84, 0x80, 0x7c, 0x79, 0x7b, 0x7d, 0x82, 0x83, 0x80, 0x7c, 0x7b, 0x7e, 0x81, 0x80, + 0x7e, 0x7d, 0x7d, 0x80, 0x83, 0x86, 0x86, 0x83, 0x7d, 0x7b, 0x78, 0x78, 0x7a, 0x7c, 0x83, 0x87, + 0x8a, 0x8b, 0x87, 0x82, 0x7d, 0x7a, 0x79, 0x77, 0x77, 0x7b, 0x82, 0x87, 0x87, 0x84, 0x82, 0x7e, + 0x7a, 0x78, 0x77, 0x77, 0x79, 0x7b, 0x80, 0x86, 0x8b, 0x8c, 0x88, 0x83, 0x7d, 0x79, 0x76, 0x72, + 0x71, 0x75, 0x7b, 0x85, 0x8d, 0x90, 0x8c, 0x84, 0x7b, 0x77, 0x78, 0x7b, 0x7e, 0x80, 0x80, 0x7d, + 0x7d, 0x81, 0x85, 0x88, 0x88, 0x86, 0x82, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7c, 0x7b, 0x7d, 0x82, + 0x88, 0x8b, 0x89, 0x83, 0x7b, 0x76, 0x74, 0x75, 0x79, 0x80, 0x83, 0x84, 0x84, 0x85, 0x87, 0x85, + 0x82, 0x7c, 0x78, 0x76, 0x77, 0x7a, 0x80, 0x85, 0x85, 0x82, 0x7e, 0x7c, 0x7c, 0x7e, 0x7d, 0x7b, + 0x79, 0x78, 0x7a, 0x7e, 0x84, 0x88, 0x88, 0x85, 0x81, 0x7b, 0x78, 0x7a, 0x7c, 0x7e, 0x7e, 0x7e, + 0x7d, 0x7c, 0x7c, 0x7e, 0x83, 0x86, 0x88, 0x8a, 0x87, 0x82, 0x7b, 0x77, 0x77, 0x77, 0x78, 0x7c, + 0x84, 0x8a, 0x8e, 0x8e, 0x89, 0x81, 0x77, 0x72, 0x71, 0x74, 0x7b, 0x83, 0x89, 0x8a, 0x88, 0x83, + 0x7d, 0x7b, 0x7a, 0x78, 0x76, 0x77, 0x7c, 0x82, 0x86, 0x87, 0x86, 0x83, 0x7d, 0x79, 0x78, 0x7a, + 0x7e, 0x82, 0x84, 0x84, 0x86, 0x86, 0x84, 0x82, 0x7d, 0x7a, 0x77, 0x78, 0x7d, 0x84, 0x89, 0x89, + 0x84, 0x7e, 0x7a, 0x79, 0x7c, 0x82, 0x85, 0x83, 0x7b, 0x77, 0x77, 0x7d, 0x83, 0x85, 0x86, 0x82, + 0x80, 0x80, 0x81, 0x84, 0x83, 0x7e, 0x79, 0x74, 0x74, 0x7a, 0x84, 0x8a, 0x8b, 0x87, 0x7e, 0x79, + 0x77, 0x7a, 0x7e, 0x81, 0x81, 0x7e, 0x7c, 0x7c, 0x82, 0x87, 0x87, 0x85, 0x80, 0x7a, 0x78, 0x79, + 0x7d, 0x81, 0x81, 0x7d, 0x7b, 0x7b, 0x7e, 0x82, 0x84, 0x83, 0x82, 0x7e, 0x7b, 0x7b, 0x7d, 0x82, + 0x84, 0x83, 0x7e, 0x7d, 0x7d, 0x80, 0x81, 0x82, 0x82, 0x81, 0x80, 0x81, 0x80, 0x81, 0x82, 0x83, + 0x81, 0x81, 0x82, 0x84, 0x84, 0x83, 0x81, 0x7c, 0x7a, 0x79, 0x7d, 0x82, 0x84, 0x84, 0x82, 0x81, + 0x7e, 0x7d, 0x7d, 0x7c, 0x7b, 0x7b, 0x7c, 0x80, 0x82, 0x83, 0x82, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7e, 0x7e, 0x7c, 0x7b, 0x7a, 0x7b, 0x7e, 0x84, 0x88, 0x88, 0x84, 0x7c, 0x74, 0x6f, 0x70, 0x77, + 0x80, 0x87, 0x88, 0x87, 0x83, 0x80, 0x7d, 0x7c, 0x7b, 0x79, 0x77, 0x78, 0x7d, 0x86, 0x8b, 0x8d, + 0x8b, 0x83, 0x79, 0x72, 0x74, 0x78, 0x7d, 0x82, 0x84, 0x84, 0x84, 0x84, 0x83, 0x83, 0x80, 0x7a, + 0x76, 0x74, 0x76, 0x7d, 0x85, 0x8b, 0x8b, 0x88, 0x82, 0x7b, 0x78, 0x78, 0x79, 0x7c, 0x7e, 0x80, + 0x81, 0x83, 0x83, 0x81, 0x7e, 0x7c, 0x79, 0x77, 0x79, 0x7d, 0x83, 0x86, 0x84, 0x80, 0x7d, 0x7b, + 0x7b, 0x7e, 0x82, 0x82, 0x81, 0x7e, 0x7b, 0x7b, 0x7c, 0x7e, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x7e, 0x7e, 0x7e, 0x80, 0x83, 0x85, 0x85, 0x83, 0x7e, 0x7b, 0x7a, 0x7a, 0x7c, 0x81, 0x84, + 0x85, 0x85, 0x84, 0x80, 0x7c, 0x79, 0x77, 0x77, 0x7a, 0x7c, 0x80, 0x83, 0x83, 0x82, 0x7d, 0x7b, + 0x7a, 0x79, 0x7a, 0x7c, 0x7e, 0x80, 0x7e, 0x7c, 0x7b, 0x7d, 0x80, 0x82, 0x80, 0x7c, 0x7c, 0x7c, + 0x7e, 0x81, 0x84, 0x84, 0x82, 0x80, 0x7d, 0x7c, 0x7a, 0x77, 0x77, 0x7b, 0x83, 0x86, 0x85, 0x82, + 0x7d, 0x7b, 0x7c, 0x7d, 0x7d, 0x7c, 0x79, 0x78, 0x7b, 0x80, 0x85, 0x87, 0x87, 0x84, 0x80, 0x7b, + 0x78, 0x7a, 0x7e, 0x83, 0x85, 0x82, 0x80, 0x7e, 0x7e, 0x81, 0x84, 0x84, 0x81, 0x7e, 0x7b, 0x7b, + 0x80, 0x84, 0x84, 0x83, 0x80, 0x7d, 0x7d, 0x7e, 0x82, 0x84, 0x84, 0x83, 0x7e, 0x7a, 0x79, 0x7a, + 0x7d, 0x80, 0x82, 0x84, 0x84, 0x84, 0x82, 0x7e, 0x7a, 0x75, 0x72, 0x73, 0x78, 0x80, 0x86, 0x89, + 0x86, 0x81, 0x7c, 0x7b, 0x7a, 0x7a, 0x7c, 0x7e, 0x7e, 0x80, 0x81, 0x81, 0x81, 0x80, 0x7d, 0x7c, + 0x7c, 0x7e, 0x81, 0x83, 0x82, 0x82, 0x81, 0x7d, 0x7b, 0x7b, 0x7d, 0x80, 0x82, 0x83, 0x83, 0x83, + 0x82, 0x81, 0x80, 0x7c, 0x7a, 0x7a, 0x7b, 0x7e, 0x81, 0x83, 0x83, 0x82, 0x82, 0x82, 0x81, 0x7c, + 0x76, 0x71, 0x72, 0x78, 0x81, 0x87, 0x88, 0x86, 0x80, 0x78, 0x74, 0x76, 0x7c, 0x81, 0x83, 0x83, + 0x81, 0x7e, 0x7d, 0x7c, 0x7d, 0x7b, 0x7a, 0x7c, 0x80, 0x86, 0x8c, 0x90, 0x8e, 0x85, 0x7a, 0x72, + 0x6f, 0x71, 0x77, 0x80, 0x89, 0x8d, 0x8e, 0x8e, 0x8b, 0x85, 0x78, 0x68, 0x67, 0x75, 0x95, 0xae, + 0xaa, 0x8c, 0x5f, 0x3f, 0x41, 0x66, 0x95, 0xb2, 0xb9, 0xad, 0x99, 0x87, 0x78, 0x6c, 0x5e, 0x53, + 0x51, 0x60, 0x79, 0x92, 0xa0, 0x9e, 0x92, 0x86, 0x7b, 0x79, 0x7a, 0x79, 0x75, 0x6c, 0x65, 0x67, + 0x73, 0x88, 0x9d, 0xa8, 0xa6, 0x97, 0x7b, 0x63, 0x53, 0x54, 0x63, 0x7b, 0x93, 0xa3, 0xa7, 0x9d, + 0x8a, 0x75, 0x64, 0x5e, 0x63, 0x73, 0x88, 0x98, 0x9f, 0x9a, 0x8f, 0x80, 0x70, 0x64, 0x60, 0x66, + 0x72, 0x87, 0x97, 0x9d, 0x9a, 0x8a, 0x78, 0x6c, 0x69, 0x71, 0x7d, 0x86, 0x88, 0x84, 0x7e, 0x7b, + 0x7c, 0x7d, 0x7c, 0x7b, 0x7a, 0x7b, 0x7d, 0x80, 0x82, 0x84, 0x84, 0x82, 0x7e, 0x7b, 0x79, 0x7a, + 0x7a, 0x79, 0x79, 0x7a, 0x7c, 0x80, 0x87, 0x90, 0x93, 0x8d, 0x81, 0x71, 0x6c, 0x6f, 0x79, 0x88, + 0x91, 0x92, 0x8c, 0x83, 0x7d, 0x7c, 0x7d, 0x7b, 0x77, 0x75, 0x76, 0x7b, 0x84, 0x89, 0x89, 0x84, + 0x7b, 0x75, 0x74, 0x77, 0x80, 0x87, 0x8a, 0x89, 0x82, 0x7a, 0x76, 0x74, 0x76, 0x7b, 0x80, 0x82, + 0x80, 0x7e, 0x83, 0x89, 0x89, 0x85, 0x7c, 0x71, 0x6b, 0x6f, 0x7a, 0x87, 0x8c, 0x8a, 0x84, 0x7e, + 0x7a, 0x78, 0x78, 0x78, 0x7b, 0x81, 0x85, 0x86, 0x86, 0x83, 0x80, 0x7d, 0x7c, 0x7c, 0x7b, 0x7b, + 0x7c, 0x7c, 0x7c, 0x7d, 0x80, 0x85, 0x87, 0x86, 0x7e, 0x72, 0x6d, 0x73, 0x7e, 0x8a, 0x8b, 0x88, + 0x84, 0x84, 0x8a, 0x8a, 0x7e, 0x6f, 0x61, 0x60, 0x6f, 0x86, 0x96, 0x95, 0x87, 0x79, 0x73, 0x7b, + 0x8a, 0x91, 0x8b, 0x7d, 0x72, 0x72, 0x78, 0x7b, 0x71, 0x5a, 0x47, 0x4a, 0x6e, 0xa4, 0xd5, 0xe1, + 0xbd, 0x7e, 0x42, 0x25, 0x2e, 0x53, 0x7d, 0x9d, 0xab, 0xaf, 0xb0, 0xaa, 0x9a, 0x82, 0x62, 0x47, + 0x42, 0x55, 0x7c, 0xa6, 0xc0, 0xc6, 0xb4, 0x8c, 0x5e, 0x3d, 0x32, 0x3e, 0x5d, 0x87, 0xad, 0xc1, + 0xbc, 0xa5, 0x86, 0x67, 0x51, 0x48, 0x4e, 0x62, 0x80, 0x9a, 0xb0, 0xb7, 0xaa, 0x8f, 0x6d, 0x53, + 0x4a, 0x50, 0x63, 0x81, 0x99, 0xa8, 0xab, 0xa1, 0x8d, 0x74, 0x5f, 0x54, 0x56, 0x63, 0x77, 0x8b, + 0x9a, 0xa1, 0x9e, 0x96, 0x8b, 0x7e, 0x74, 0x68, 0x5f, 0x60, 0x69, 0x7d, 0x94, 0xa3, 0xa7, 0x97, + 0x7c, 0x63, 0x55, 0x59, 0x6c, 0x8c, 0xa8, 0xb3, 0xac, 0x96, 0x76, 0x5e, 0x58, 0x61, 0x72, 0x81, + 0x89, 0x8b, 0x8b, 0x88, 0x83, 0x7a, 0x72, 0x70, 0x76, 0x7d, 0x81, 0x81, 0x80, 0x81, 0x87, 0x8d, + 0x8c, 0x83, 0x75, 0x6c, 0x6b, 0x74, 0x84, 0x92, 0x97, 0x8f, 0x83, 0x79, 0x74, 0x75, 0x79, 0x80, + 0x84, 0x85, 0x88, 0x89, 0x88, 0x85, 0x81, 0x7a, 0x74, 0x6c, 0x65, 0x63, 0x6e, 0x89, 0xa5, 0xb7, + 0xb1, 0x90, 0x66, 0x47, 0x41, 0x5a, 0x81, 0xa1, 0xab, 0xa0, 0x91, 0x84, 0x7c, 0x7a, 0x74, 0x6b, + 0x65, 0x66, 0x72, 0x86, 0x96, 0x9d, 0x9b, 0x92, 0x85, 0x72, 0x64, 0x5d, 0x60, 0x6f, 0x86, 0x99, + 0x9f, 0x97, 0x87, 0x76, 0x6e, 0x6e, 0x73, 0x78, 0x7d, 0x7e, 0x82, 0x86, 0x8a, 0x8b, 0x88, 0x81, + 0x7a, 0x78, 0x79, 0x7c, 0x80, 0x84, 0x87, 0x88, 0x86, 0x82, 0x7b, 0x76, 0x76, 0x79, 0x81, 0x88, + 0x8a, 0x86, 0x80, 0x79, 0x76, 0x76, 0x77, 0x7b, 0x81, 0x84, 0x88, 0x89, 0x87, 0x82, 0x7c, 0x77, + 0x77, 0x7a, 0x7e, 0x82, 0x86, 0x86, 0x86, 0x86, 0x85, 0x80, 0x78, 0x73, 0x74, 0x7b, 0x85, 0x89, + 0x8a, 0x87, 0x82, 0x81, 0x83, 0x88, 0x89, 0x81, 0x6d, 0x54, 0x3f, 0x42, 0x65, 0x9d, 0xd1, 0xec, + 0xda, 0xa0, 0x55, 0x20, 0x13, 0x32, 0x6a, 0xa0, 0xc8, 0xd6, 0xc6, 0xa8, 0x82, 0x60, 0x4b, 0x46, + 0x55, 0x6a, 0x81, 0x93, 0xa1, 0xa9, 0xa9, 0x9f, 0x8b, 0x6c, 0x4e, 0x3b, 0x3f, 0x5e, 0x87, 0xaa, + 0xbd, 0xb9, 0xa2, 0x80, 0x5e, 0x4b, 0x49, 0x57, 0x72, 0x92, 0xa8, 0xaf, 0xa7, 0x94, 0x7e, 0x6c, + 0x62, 0x62, 0x68, 0x73, 0x80, 0x8e, 0x9c, 0xa3, 0x9e, 0x8f, 0x79, 0x65, 0x5b, 0x5b, 0x65, 0x77, + 0x88, 0x95, 0x9c, 0x9a, 0x90, 0x80, 0x71, 0x6b, 0x6d, 0x76, 0x80, 0x85, 0x82, 0x7b, 0x78, 0x7a, + 0x83, 0x89, 0x89, 0x85, 0x82, 0x81, 0x83, 0x87, 0x89, 0x87, 0x82, 0x7c, 0x78, 0x76, 0x74, 0x73, + 0x72, 0x76, 0x7d, 0x86, 0x8a, 0x89, 0x82, 0x7a, 0x76, 0x74, 0x75, 0x79, 0x81, 0x89, 0x8b, 0x8a, + 0x85, 0x7c, 0x76, 0x74, 0x79, 0x82, 0x89, 0x8b, 0x89, 0x85, 0x81, 0x7e, 0x7c, 0x7d, 0x7d, 0x7d, + 0x80, 0x81, 0x82, 0x81, 0x7d, 0x7b, 0x7d, 0x81, 0x84, 0x87, 0x87, 0x82, 0x74, 0x68, 0x5f, 0x5f, + 0x6e, 0x8a, 0xa6, 0xb9, 0xb1, 0x92, 0x67, 0x46, 0x40, 0x57, 0x7b, 0x9d, 0xb0, 0xb2, 0xa3, 0x8c, + 0x74, 0x60, 0x57, 0x5b, 0x6d, 0x88, 0x9e, 0xa4, 0x98, 0x86, 0x77, 0x6f, 0x70, 0x76, 0x78, 0x77, + 0x77, 0x7a, 0x83, 0x8a, 0x8d, 0x8c, 0x86, 0x7e, 0x78, 0x71, 0x6c, 0x6d, 0x73, 0x7e, 0x8e, 0x99, + 0x98, 0x8e, 0x80, 0x73, 0x6c, 0x6e, 0x76, 0x80, 0x88, 0x8d, 0x8f, 0x8b, 0x84, 0x78, 0x70, 0x6f, + 0x76, 0x80, 0x89, 0x8d, 0x8b, 0x86, 0x81, 0x7c, 0x7a, 0x76, 0x75, 0x77, 0x7b, 0x82, 0x88, 0x8a, + 0x88, 0x84, 0x80, 0x7c, 0x78, 0x77, 0x78, 0x7c, 0x84, 0x8c, 0x91, 0x8e, 0x86, 0x7a, 0x71, 0x6d, + 0x72, 0x7a, 0x84, 0x8d, 0x93, 0x93, 0x8e, 0x83, 0x70, 0x58, 0x42, 0x3d, 0x51, 0x7b, 0xae, 0xd1, + 0xdd, 0xc6, 0x92, 0x5a, 0x2e, 0x1d, 0x2a, 0x56, 0x94, 0xcb, 0xeb, 0xe7, 0xc1, 0x83, 0x48, 0x24, + 0x23, 0x40, 0x6f, 0x9d, 0xbc, 0xc7, 0xbb, 0x9e, 0x7a, 0x5b, 0x47, 0x45, 0x55, 0x6d, 0x84, 0x96, + 0x9f, 0xa1, 0x9c, 0x92, 0x84, 0x71, 0x5f, 0x56, 0x5a, 0x66, 0x7b, 0x92, 0xa2, 0xad, 0xa9, 0x98, + 0x80, 0x66, 0x57, 0x53, 0x5e, 0x76, 0x93, 0xa7, 0xad, 0xa5, 0x91, 0x77, 0x61, 0x55, 0x56, 0x64, + 0x7a, 0x90, 0x9f, 0xa0, 0x95, 0x86, 0x78, 0x70, 0x6f, 0x71, 0x75, 0x79, 0x7c, 0x80, 0x82, 0x83, + 0x86, 0x8a, 0x8d, 0x8d, 0x88, 0x7d, 0x74, 0x6e, 0x6f, 0x7a, 0x8d, 0x9a, 0x9e, 0x97, 0x87, 0x72, + 0x5f, 0x58, 0x5e, 0x70, 0x88, 0x9c, 0xa8, 0xa2, 0x8c, 0x6f, 0x5a, 0x55, 0x5f, 0x74, 0x8d, 0xa2, + 0xa8, 0x9d, 0x88, 0x70, 0x60, 0x5c, 0x65, 0x7a, 0x90, 0x9e, 0xa2, 0x99, 0x8a, 0x7a, 0x6e, 0x69, + 0x6f, 0x79, 0x84, 0x8c, 0x8d, 0x89, 0x83, 0x7d, 0x7c, 0x7c, 0x80, 0x81, 0x80, 0x79, 0x6f, 0x67, + 0x65, 0x6c, 0x7e, 0x94, 0xa5, 0xa9, 0x9b, 0x81, 0x64, 0x50, 0x4e, 0x61, 0x80, 0x9f, 0xb2, 0xb2, + 0xa5, 0x8d, 0x6e, 0x56, 0x4e, 0x56, 0x6e, 0x8e, 0xa7, 0xb0, 0xa7, 0x92, 0x78, 0x65, 0x5b, 0x5d, + 0x69, 0x78, 0x89, 0x95, 0x9a, 0x93, 0x86, 0x77, 0x70, 0x6f, 0x73, 0x78, 0x7b, 0x7d, 0x7e, 0x81, + 0x84, 0x86, 0x88, 0x89, 0x87, 0x84, 0x7d, 0x76, 0x72, 0x72, 0x77, 0x7e, 0x8a, 0x90, 0x90, 0x8b, + 0x80, 0x76, 0x71, 0x6e, 0x72, 0x7a, 0x85, 0x8e, 0x90, 0x8c, 0x83, 0x76, 0x6e, 0x6c, 0x71, 0x79, + 0x84, 0x8c, 0x90, 0x8e, 0x88, 0x7e, 0x76, 0x71, 0x72, 0x78, 0x81, 0x87, 0x88, 0x87, 0x83, 0x80, + 0x7e, 0x7c, 0x7c, 0x7c, 0x7d, 0x81, 0x86, 0x87, 0x7e, 0x6e, 0x5d, 0x54, 0x5a, 0x71, 0x92, 0xb0, + 0xc0, 0xba, 0xa0, 0x7c, 0x56, 0x3b, 0x37, 0x48, 0x72, 0xa5, 0xcd, 0xdd, 0xcd, 0xa2, 0x6d, 0x40, + 0x29, 0x2e, 0x4c, 0x7c, 0xab, 0xcc, 0xd3, 0xbc, 0x93, 0x63, 0x41, 0x35, 0x3e, 0x5c, 0x81, 0xa0, + 0xb3, 0xb5, 0xa7, 0x8d, 0x72, 0x5f, 0x56, 0x5c, 0x6a, 0x7b, 0x8b, 0x94, 0x98, 0x97, 0x91, 0x88, + 0x7e, 0x75, 0x6f, 0x6e, 0x73, 0x78, 0x80, 0x88, 0x90, 0x96, 0x96, 0x8e, 0x82, 0x73, 0x67, 0x62, + 0x65, 0x71, 0x80, 0x8d, 0x9a, 0x9e, 0x97, 0x8a, 0x76, 0x67, 0x5f, 0x60, 0x6b, 0x7a, 0x89, 0x93, + 0x98, 0x95, 0x8e, 0x83, 0x78, 0x71, 0x6d, 0x6d, 0x73, 0x7c, 0x87, 0x90, 0x97, 0x99, 0x93, 0x88, + 0x77, 0x69, 0x62, 0x61, 0x6a, 0x77, 0x86, 0x92, 0x97, 0x94, 0x8a, 0x7a, 0x6e, 0x69, 0x6b, 0x74, + 0x80, 0x89, 0x8e, 0x8d, 0x8a, 0x83, 0x7b, 0x78, 0x76, 0x79, 0x7e, 0x83, 0x87, 0x88, 0x85, 0x82, + 0x7e, 0x7e, 0x82, 0x83, 0x83, 0x83, 0x82, 0x7e, 0x7a, 0x76, 0x73, 0x73, 0x75, 0x7c, 0x85, 0x8e, + 0x94, 0x92, 0x87, 0x77, 0x69, 0x63, 0x66, 0x71, 0x82, 0x92, 0x9c, 0x9b, 0x92, 0x85, 0x73, 0x66, + 0x62, 0x68, 0x78, 0x8a, 0x96, 0x9c, 0x98, 0x8c, 0x7d, 0x6e, 0x66, 0x67, 0x6f, 0x7c, 0x8b, 0x94, + 0x95, 0x90, 0x85, 0x78, 0x70, 0x6d, 0x70, 0x76, 0x7d, 0x83, 0x86, 0x86, 0x85, 0x84, 0x83, 0x82, + 0x82, 0x81, 0x7e, 0x7c, 0x79, 0x78, 0x79, 0x79, 0x7c, 0x81, 0x85, 0x88, 0x88, 0x86, 0x82, 0x7c, + 0x78, 0x76, 0x77, 0x7a, 0x80, 0x83, 0x84, 0x84, 0x82, 0x80, 0x7d, 0x7c, 0x7b, 0x7d, 0x7e, 0x80, + 0x81, 0x7e, 0x7c, 0x7a, 0x7b, 0x7d, 0x81, 0x85, 0x86, 0x85, 0x82, 0x7c, 0x78, 0x77, 0x7a, 0x82, + 0x8a, 0x8e, 0x89, 0x79, 0x65, 0x54, 0x4e, 0x5c, 0x78, 0x9d, 0xbd, 0xcb, 0xc2, 0xa1, 0x74, 0x46, + 0x24, 0x23, 0x3f, 0x74, 0xb2, 0xde, 0xf0, 0xdc, 0xa9, 0x6c, 0x35, 0x13, 0x10, 0x35, 0x70, 0xac, + 0xdc, 0xee, 0xd7, 0xa6, 0x6b, 0x39, 0x1b, 0x1d, 0x3c, 0x6e, 0xa5, 0xca, 0xd6, 0xc8, 0xa3, 0x74, + 0x51, 0x3b, 0x3b, 0x51, 0x72, 0x94, 0xad, 0xb8, 0xad, 0x96, 0x7c, 0x65, 0x5c, 0x5e, 0x68, 0x78, + 0x88, 0x94, 0x9a, 0x97, 0x8d, 0x80, 0x74, 0x6e, 0x6d, 0x6d, 0x6f, 0x70, 0x72, 0x79, 0x84, 0x8c, + 0x93, 0x94, 0x90, 0x86, 0x77, 0x69, 0x5d, 0x5a, 0x5f, 0x70, 0x87, 0x9c, 0xa9, 0xaa, 0x9e, 0x8b, + 0x73, 0x5e, 0x55, 0x58, 0x68, 0x83, 0x9c, 0xad, 0xb0, 0xa1, 0x89, 0x6d, 0x57, 0x4c, 0x52, 0x65, + 0x81, 0x9b, 0xac, 0xae, 0x9f, 0x87, 0x6c, 0x58, 0x51, 0x59, 0x6b, 0x83, 0x9a, 0xa7, 0xa7, 0x9c, + 0x87, 0x70, 0x60, 0x59, 0x5b, 0x64, 0x74, 0x88, 0x9b, 0xaa, 0xaf, 0xa7, 0x94, 0x7b, 0x65, 0x56, + 0x4f, 0x55, 0x69, 0x86, 0xa3, 0xb8, 0xbc, 0xaf, 0x93, 0x73, 0x56, 0x44, 0x43, 0x52, 0x6e, 0x92, + 0xaf, 0xbd, 0xb8, 0xa2, 0x82, 0x61, 0x4b, 0x43, 0x4d, 0x65, 0x83, 0xa0, 0xb3, 0xb4, 0xa6, 0x8c, + 0x6f, 0x5a, 0x52, 0x57, 0x65, 0x7c, 0x95, 0xa6, 0xac, 0xa4, 0x91, 0x79, 0x66, 0x5c, 0x5f, 0x6b, + 0x7a, 0x8b, 0x98, 0x9c, 0x99, 0x8e, 0x7e, 0x72, 0x6a, 0x6a, 0x6f, 0x77, 0x7e, 0x86, 0x8b, 0x8c, + 0x8a, 0x85, 0x7e, 0x79, 0x76, 0x75, 0x76, 0x78, 0x7b, 0x82, 0x87, 0x8a, 0x8b, 0x88, 0x84, 0x7e, + 0x79, 0x74, 0x71, 0x72, 0x77, 0x81, 0x8a, 0x8f, 0x90, 0x8b, 0x82, 0x78, 0x72, 0x71, 0x74, 0x7b, + 0x84, 0x88, 0x85, 0x79, 0x69, 0x5c, 0x5a, 0x66, 0x80, 0x9d, 0xb4, 0xbf, 0xb5, 0x9b, 0x75, 0x4d, + 0x33, 0x2f, 0x47, 0x75, 0xa8, 0xd4, 0xe7, 0xdb, 0xb7, 0x7e, 0x44, 0x1e, 0x14, 0x29, 0x5d, 0x9b, + 0xd2, 0xed, 0xe5, 0xc0, 0x87, 0x4b, 0x20, 0x10, 0x22, 0x4f, 0x88, 0xbc, 0xdb, 0xdc, 0xc0, 0x90, + 0x5e, 0x39, 0x26, 0x33, 0x53, 0x7e, 0xac, 0xc7, 0xcc, 0xbb, 0x99, 0x74, 0x56, 0x47, 0x49, 0x5b, + 0x76, 0x93, 0xa8, 0xaf, 0xa8, 0x96, 0x81, 0x6c, 0x5f, 0x5b, 0x5f, 0x6b, 0x7b, 0x8c, 0x97, 0x9a, + 0x97, 0x8f, 0x85, 0x78, 0x6e, 0x66, 0x64, 0x67, 0x70, 0x7d, 0x8c, 0x96, 0x9b, 0x99, 0x91, 0x83, + 0x73, 0x66, 0x5e, 0x61, 0x6e, 0x83, 0x96, 0xa5, 0xa8, 0xa0, 0x8e, 0x76, 0x60, 0x51, 0x51, 0x5e, + 0x75, 0x93, 0xaa, 0xb1, 0xa8, 0x94, 0x74, 0x58, 0x48, 0x49, 0x5c, 0x7c, 0x9d, 0xb5, 0xba, 0xa8, + 0x86, 0x5d, 0x42, 0x38, 0x47, 0x6b, 0x9a, 0xc3, 0xd8, 0xcf, 0xad, 0x78, 0x47, 0x28, 0x22, 0x3d, + 0x6b, 0xa4, 0xd3, 0xe6, 0xda, 0xb5, 0x7b, 0x43, 0x1e, 0x17, 0x30, 0x61, 0x99, 0xc9, 0xe0, 0xd9, + 0xb8, 0x85, 0x4d, 0x29, 0x20, 0x34, 0x5e, 0x8f, 0xba, 0xd1, 0xd0, 0xb6, 0x8c, 0x61, 0x40, 0x35, + 0x41, 0x5f, 0x85, 0xa5, 0xba, 0xbb, 0xa9, 0x8c, 0x6f, 0x58, 0x4e, 0x53, 0x65, 0x7e, 0x97, 0xa2, + 0xa4, 0x9a, 0x88, 0x77, 0x68, 0x63, 0x68, 0x72, 0x81, 0x8c, 0x90, 0x8e, 0x86, 0x7b, 0x75, 0x73, + 0x75, 0x7b, 0x84, 0x89, 0x8a, 0x86, 0x7d, 0x74, 0x6f, 0x6f, 0x76, 0x82, 0x8e, 0x97, 0x9a, 0x94, + 0x89, 0x7a, 0x6e, 0x66, 0x66, 0x6f, 0x7e, 0x8d, 0x99, 0x9d, 0x99, 0x8e, 0x81, 0x70, 0x60, 0x53, + 0x4d, 0x53, 0x64, 0x7e, 0x9b, 0xb2, 0xbe, 0xba, 0xa7, 0x89, 0x63, 0x42, 0x2f, 0x34, 0x50, 0x78, + 0xa8, 0xcf, 0xe0, 0xdb, 0xbb, 0x8c, 0x56, 0x2c, 0x1a, 0x22, 0x46, 0x79, 0xac, 0xd2, 0xe4, 0xd7, + 0xb2, 0x80, 0x4c, 0x28, 0x1a, 0x27, 0x4b, 0x7b, 0xab, 0xcb, 0xd5, 0xc5, 0xa3, 0x78, 0x50, 0x36, + 0x30, 0x41, 0x60, 0x87, 0xa7, 0xbc, 0xbf, 0xb0, 0x95, 0x76, 0x5d, 0x51, 0x51, 0x5e, 0x72, 0x86, + 0x97, 0xa0, 0xa0, 0x98, 0x8a, 0x7b, 0x6f, 0x66, 0x65, 0x69, 0x71, 0x7b, 0x85, 0x8e, 0x93, 0x93, + 0x90, 0x89, 0x80, 0x76, 0x6f, 0x6b, 0x6b, 0x6f, 0x76, 0x81, 0x8a, 0x91, 0x95, 0x94, 0x8e, 0x85, + 0x7a, 0x71, 0x6d, 0x6e, 0x72, 0x79, 0x81, 0x86, 0x88, 0x87, 0x83, 0x7e, 0x7b, 0x78, 0x79, 0x7b, + 0x7e, 0x81, 0x82, 0x81, 0x80, 0x7d, 0x7b, 0x7b, 0x7c, 0x80, 0x83, 0x83, 0x81, 0x7a, 0x74, 0x70, + 0x72, 0x78, 0x82, 0x8c, 0x94, 0x99, 0x97, 0x8e, 0x7e, 0x6f, 0x62, 0x5e, 0x64, 0x72, 0x87, 0x98, + 0xa4, 0xa7, 0x9e, 0x8d, 0x77, 0x63, 0x56, 0x55, 0x5f, 0x72, 0x87, 0x9a, 0xa7, 0xa8, 0x9f, 0x8d, + 0x76, 0x62, 0x57, 0x58, 0x62, 0x72, 0x88, 0x97, 0xa0, 0xa0, 0x97, 0x88, 0x78, 0x6b, 0x64, 0x64, + 0x6b, 0x75, 0x83, 0x8c, 0x92, 0x95, 0x91, 0x8a, 0x82, 0x79, 0x74, 0x72, 0x73, 0x75, 0x7a, 0x7d, + 0x83, 0x86, 0x87, 0x88, 0x89, 0x89, 0x89, 0x88, 0x84, 0x7d, 0x77, 0x72, 0x70, 0x71, 0x77, 0x80, + 0x8a, 0x91, 0x96, 0x95, 0x8d, 0x82, 0x76, 0x6c, 0x66, 0x67, 0x70, 0x7c, 0x8a, 0x96, 0x9b, 0x99, + 0x90, 0x84, 0x75, 0x69, 0x64, 0x65, 0x6d, 0x7b, 0x8c, 0x98, 0x9b, 0x93, 0x80, 0x67, 0x52, 0x47, + 0x4b, 0x61, 0x82, 0xa5, 0xc2, 0xcb, 0xc1, 0xa4, 0x7b, 0x51, 0x35, 0x2e, 0x3b, 0x5b, 0x87, 0xb1, + 0xd1, 0xdc, 0xcf, 0xae, 0x84, 0x5a, 0x3b, 0x2f, 0x36, 0x50, 0x75, 0x9a, 0xb8, 0xc5, 0xbe, 0xa9, + 0x8b, 0x6b, 0x54, 0x48, 0x49, 0x57, 0x6b, 0x83, 0x95, 0x9d, 0x9c, 0x96, 0x8b, 0x80, 0x78, 0x74, + 0x72, 0x74, 0x76, 0x79, 0x7a, 0x7a, 0x7b, 0x7d, 0x82, 0x88, 0x8e, 0x92, 0x93, 0x91, 0x8b, 0x81, + 0x73, 0x67, 0x5f, 0x5f, 0x68, 0x79, 0x8d, 0x9e, 0xa9, 0xaa, 0x9f, 0x8a, 0x72, 0x5d, 0x52, 0x52, + 0x5e, 0x71, 0x84, 0x94, 0x9e, 0xa0, 0x9b, 0x8e, 0x7e, 0x71, 0x6b, 0x6d, 0x74, 0x7e, 0x89, 0x91, + 0x93, 0x8f, 0x84, 0x75, 0x68, 0x64, 0x68, 0x72, 0x80, 0x8d, 0x94, 0x94, 0x8e, 0x82, 0x73, 0x68, + 0x63, 0x68, 0x72, 0x80, 0x8d, 0x95, 0x98, 0x95, 0x8d, 0x80, 0x6f, 0x60, 0x58, 0x59, 0x62, 0x71, + 0x85, 0x96, 0xa2, 0xaa, 0xa9, 0xa0, 0x90, 0x7d, 0x6c, 0x5f, 0x5b, 0x5f, 0x6a, 0x78, 0x88, 0x95, + 0x9e, 0x9f, 0x9a, 0x91, 0x84, 0x79, 0x71, 0x6d, 0x6d, 0x71, 0x76, 0x7a, 0x7c, 0x7d, 0x7d, 0x7e, + 0x83, 0x87, 0x89, 0x8a, 0x88, 0x84, 0x7e, 0x79, 0x73, 0x6e, 0x6e, 0x71, 0x77, 0x7d, 0x84, 0x89, + 0x8d, 0x8d, 0x8b, 0x86, 0x81, 0x7c, 0x7a, 0x7a, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x80, 0x82, + 0x84, 0x82, 0x80, 0x7b, 0x77, 0x75, 0x74, 0x77, 0x80, 0x8a, 0x93, 0x98, 0x95, 0x8d, 0x81, 0x73, + 0x68, 0x63, 0x64, 0x6b, 0x78, 0x87, 0x92, 0x97, 0x95, 0x90, 0x87, 0x7d, 0x76, 0x72, 0x74, 0x79, + 0x80, 0x85, 0x87, 0x86, 0x84, 0x81, 0x7b, 0x7a, 0x7b, 0x80, 0x84, 0x85, 0x7e, 0x72, 0x66, 0x5f, + 0x5e, 0x67, 0x76, 0x88, 0x99, 0xa5, 0xa9, 0xa3, 0x94, 0x81, 0x6f, 0x63, 0x5f, 0x62, 0x6b, 0x76, + 0x82, 0x8a, 0x8d, 0x8b, 0x88, 0x82, 0x7d, 0x7c, 0x7e, 0x82, 0x86, 0x89, 0x89, 0x84, 0x7d, 0x76, + 0x71, 0x6f, 0x70, 0x75, 0x7b, 0x83, 0x88, 0x8b, 0x8b, 0x88, 0x83, 0x7d, 0x79, 0x76, 0x75, 0x77, + 0x7a, 0x7d, 0x81, 0x82, 0x82, 0x82, 0x82, 0x82, 0x80, 0x7e, 0x7c, 0x7a, 0x79, 0x7a, 0x7b, 0x7d, + 0x80, 0x82, 0x84, 0x84, 0x83, 0x81, 0x7c, 0x79, 0x78, 0x78, 0x7b, 0x7e, 0x83, 0x86, 0x86, 0x85, + 0x82, 0x7d, 0x7b, 0x7a, 0x7a, 0x7b, 0x7d, 0x81, 0x83, 0x85, 0x85, 0x85, 0x83, 0x81, 0x7d, 0x7c, + 0x7c, 0x7c, 0x7d, 0x7e, 0x81, 0x83, 0x83, 0x83, 0x82, 0x81, 0x7f, 0x7e, 0x7d, 0x7c, 0x7d, 0x7d, + 0x7e, 0x80, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7d, 0x7c, 0x7a, 0x79, 0x79, + 0x7a, 0x7c, 0x80, 0x82, 0x82, 0x82, 0x81, 0x7e, 0x7d, 0x7c, 0x7c, 0x7c, 0x7e, 0x80, 0x80, 0x80, + 0x7e, 0x7c, 0x7c, 0x7b, 0x7c, 0x7d, 0x7e, 0x81, 0x82, 0x82, 0x83, 0x82, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x81, 0x82, 0x82, 0x82, 0x81, 0x80, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x82, 0x82, 0x81, 0x7e, + 0x7d, 0x7c, 0x7d, 0x7e, 0x81, 0x83, 0x83, 0x84, 0x83, 0x82, 0x80, 0x7d, 0x7b, 0x7b, 0x7c, 0x7e, + 0x81, 0x84, 0x85, 0x85, 0x84, 0x82, 0x7e, 0x7c, 0x7a, 0x7a, 0x7b, 0x7e, 0x82, 0x85, 0x86, 0x84, + 0x81, 0x7c, 0x79, 0x79, 0x79, 0x7b, 0x7e, 0x81, 0x83, 0x83, 0x82, 0x81, 0x7e, 0x7d, 0x7e, 0x81, + 0x82, 0x82, 0x81, 0x7e, 0x7d, 0x7b, 0x7c, 0x7d, 0x80, 0x82, 0x83, 0x82, 0x80, 0x7c, 0x7b, 0x7b, + 0x7b, 0x7c, 0x80, 0x83, 0x84, 0x84, 0x83, 0x82, 0x80, 0x7d, 0x7c, 0x7c, 0x7d, 0x7e, 0x80, 0x81, + 0x81, 0x82, 0x81, 0x80, 0x80, 0x7e, 0x7d, 0x7c, 0x7c, 0x7d, 0x80, 0x82, 0x82, 0x82, 0x81, 0x7e, + 0x7c, 0x7b, 0x7b, 0x7b, 0x7d, 0x7e, 0x81, 0x82, 0x82, 0x81, 0x80, 0x7d, 0x7c, 0x7c, 0x7c, 0x7e, + 0x80, 0x82, 0x84, 0x85, 0x84, 0x83, 0x82, 0x7e, 0x7c, 0x7b, 0x7c, 0x7e, 0x81, 0x83, 0x84, 0x84, + 0x83, 0x80, 0x7d, 0x7b, 0x7b, 0x7c, 0x7c, 0x7e, 0x82, 0x84, 0x84, 0x84, 0x82, 0x7e, 0x7c, 0x7a, + 0x7a, 0x7a, 0x7b, 0x7e, 0x82, 0x84, 0x85, 0x85, 0x83, 0x82, 0x80, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, + 0x7e, 0x80, 0x82, 0x84, 0x85, 0x84, 0x83, 0x81, 0x7d, 0x7b, 0x7a, 0x7a, 0x7b, 0x80, 0x84, 0x86, + 0x85, 0x83, 0x7e, 0x7c, 0x7b, 0x7a, 0x7a, 0x7d, 0x81, 0x84, 0x86, 0x88, 0x87, 0x83, 0x7e, 0x79, + 0x77, 0x77, 0x7a, 0x7e, 0x82, 0x84, 0x85, 0x85, 0x83, 0x80, 0x7c, 0x7b, 0x7b, 0x7c, 0x7d, 0x80, + 0x81, 0x81, 0x80, 0x7e, 0x7d, 0x7c, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7d, 0x7e, 0x7e, 0x80, + 0x80, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7c, 0x7d, 0x7e, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x80, 0x7e, 0x7d, 0x7d, 0x7e, 0x80, 0x82, 0x83, 0x84, 0x84, 0x83, 0x82, 0x80, 0x7d, 0x7b, 0x7a, + 0x7a, 0x7b, 0x7d, 0x81, 0x82, 0x83, 0x82, 0x80, 0x7d, 0x7b, 0x7a, 0x7b, 0x80, 0x83, 0x84, 0x85, + 0x84, 0x81, 0x7d, 0x7b, 0x7a, 0x7b, 0x7e, 0x82, 0x85, 0x85, 0x83, 0x80, 0x7b, 0x78, 0x77, 0x78, + 0x7c, 0x80, 0x84, 0x86, 0x85, 0x84, 0x80, 0x7c, 0x7a, 0x7b, 0x7c, 0x7e, 0x82, 0x82, 0x83, 0x83, + 0x81, 0x80, 0x7d, 0x7c, 0x7c, 0x7d, 0x80, 0x81, 0x82, 0x83, 0x82, 0x81, 0x7e, 0x7d, 0x7d, 0x80, + 0x81, 0x83, 0x84, 0x83, 0x81, 0x7e, 0x7d, 0x7d, 0x7e, 0x80, 0x81, 0x82, 0x83, 0x83, 0x83, 0x81, + 0x7d, 0x7b, 0x7b, 0x7b, 0x7c, 0x80, 0x82, 0x83, 0x82, 0x80, 0x7d, 0x7b, 0x7a, 0x7a, 0x7b, 0x7d, + 0x80, 0x82, 0x82, 0x82, 0x81, 0x7d, 0x7b, 0x7a, 0x7b, 0x7c, 0x7e, 0x81, 0x82, 0x82, 0x82, 0x82, + 0x81, 0x80, 0x7e, 0x7e, 0x7e, 0x7d, 0x7c, 0x7c, 0x7c, 0x7d, 0x7e, 0x80, 0x81, 0x82, 0x80, 0x7d, + 0x7c, 0x7b, 0x7b, 0x7c, 0x7d, 0x80, 0x82, 0x82, 0x83, 0x82, 0x7f, 0x7c, 0x7a, 0x78, 0x79, 0x7b, + 0x7d, 0x80, 0x82, 0x84, 0x84, 0x83, 0x81, 0x7d, 0x7b, 0x79, 0x78, 0x79, 0x7b, 0x7e, 0x82, 0x84, + 0x84, 0x82, 0x80, 0x7d, 0x7c, 0x7c, 0x7c, 0x7e, 0x81, 0x83, 0x84, 0x84, 0x84, 0x82, 0x7e, 0x7d, + 0x7c, 0x7c, 0x7d, 0x80, 0x83, 0x84, 0x84, 0x83, 0x82, 0x80, 0x7d, 0x7c, 0x7d, 0x7e, 0x7e, 0x80, + 0x81, 0x81, 0x80, 0x80, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7d, 0x7c, 0x7b, 0x7b, 0x7c, 0x7d, 0x7e, 0x7e, 0x80, 0x80, 0x7e, 0x7d, 0x7c, + 0x7b, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x81, 0x81, 0x80, 0x7e, 0x7d, 0x7c, 0x7b, 0x7b, 0x7c, 0x7d, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7c, 0x7c, + 0x7d, 0x80, 0x82, 0x83, 0x82, 0x81, 0x7e, 0x7b, 0x7a, 0x79, 0x79, 0x7b, 0x7d, 0x80, 0x81, 0x82, + 0x81, 0x80, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x80, 0x81, 0x81, 0x81, + 0x81, 0x80, 0x80, 0x7e, 0x7e, 0x7d, 0x7e, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x7e, 0x7d, 0x7d, + 0x7e, 0x80, 0x81, 0x81, 0x82, 0x82, 0x81, 0x7e, 0x7e, 0x7d, 0x7e, 0x80, 0x81, 0x81, 0x80, 0x80, + 0x7e, 0x7d, 0x7e, 0x80, 0x81, 0x82, 0x81, 0x80, 0x7d, 0x7c, 0x7b, 0x7a, 0x7b, 0x7d, 0x7e, 0x80, + 0x82, 0x83, 0x85, 0x85, 0x83, 0x80, 0x7c, 0x7a, 0x7a, 0x7b, 0x7c, 0x7e, 0x81, 0x83, 0x84, 0x84, + 0x83, 0x82, 0x81, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x81, 0x81, 0x82, 0x82, 0x81, 0x81, + 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x83, 0x83, 0x83, 0x82, 0x7e, 0x7c, 0x7a, 0x79, 0x7b, + 0x7d, 0x82, 0x84, 0x84, 0x82, 0x7e, 0x7b, 0x7a, 0x79, 0x7b, 0x7e, 0x81, 0x83, 0x84, 0x84, 0x82, + 0x80, 0x7c, 0x7b, 0x7b, 0x7c, 0x7d, 0x7e, 0x81, 0x83, 0x82, 0x82, 0x82, 0x81, 0x80, 0x80, 0x80, + 0x7e, 0x7d, 0x7c, 0x7b, 0x7b, 0x7c, 0x7e, 0x80, 0x82, 0x83, 0x83, 0x82, 0x81, 0x80, 0x80, 0x7e, + 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, 0x80, 0x80, 0x81, 0x82, 0x82, 0x82, 0x81, 0x80, 0x80, 0x7e, 0x7e, + 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x81, 0x82, + 0x81, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, 0x80, 0x81, 0x81, 0x81, 0x81, 0x7e, + 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x85, 0x88, 0x86, 0x82, 0x7c, 0x78, + 0x77, 0x7a, 0x7d, 0x81, 0x84, 0x87, 0x89, 0x87, 0x82, 0x7b, 0x79, 0x79, 0x7b, 0x7d, 0x7e, 0x80, + 0x81, 0x81, 0x82, 0x82, 0x81, 0x80, 0x7e, 0x80, 0x80, 0x7e, 0x7d, 0x7d, 0x7e, 0x80, 0x81, 0x81, + 0x81, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, + 0x7e, 0x7e, 0x7e, 0x80, 0x81, 0x81, 0x81, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7e, 0x7e, 0x80, 0x81, 0x81, 0x80, 0x80, 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, 0x80, 0x80, 0x81, + 0x82, 0x82, 0x81, 0x7e, 0x7c, 0x7b, 0x7c, 0x7d, 0x7d, 0x80, 0x81, 0x82, 0x82, 0x82, 0x81, 0x7e, + 0x7d, 0x7c, 0x7c, 0x7e, 0x80, 0x81, 0x82, 0x82, 0x81, 0x81, 0x81, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, + 0x7d, 0x7e, 0x81, 0x82, 0x82, 0x81, 0x81, 0x80, 0x7e, 0x7d, 0x7c, 0x7b, 0x7b, 0x7c, 0x7d, 0x80, + 0x81, 0x82, 0x82, 0x80, 0x7d, 0x7b, 0x7a, 0x7a, 0x7b, 0x7d, 0x80, 0x82, 0x83, 0x83, 0x81, 0x7d, + 0x7b, 0x7a, 0x7b, 0x7c, 0x80, 0x82, 0x84, 0x84, 0x83, 0x81, 0x7e, 0x7c, 0x7b, 0x7b, 0x7c, 0x7e, + 0x81, 0x83, 0x83, 0x83, 0x81, 0x80, 0x7e, 0x7d, 0x7d, 0x80, 0x81, 0x82, 0x83, 0x83, 0x82, 0x80, + 0x7e, 0x7d, 0x7d, 0x7e, 0x80, 0x81, 0x81, 0x81, 0x81, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, + 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, 0x80, 0x82, 0x82, 0x82, 0x81, 0x80, 0x7e, 0x7d, 0x7c, + 0x7d, 0x7e, 0x80, 0x81, 0x82, 0x82, 0x81, 0x7e, 0x7d, 0x7b, 0x7c, 0x7d, 0x7e, 0x80, 0x82, 0x83, + 0x83, 0x80, 0x7d, 0x7d, 0x7c, 0x7c, 0x7d, 0x7e, 0x81, 0x82, 0x82, 0x81, 0x81, 0x80, 0x7e, 0x7d, + 0x7e, 0x80, 0x81, 0x81, 0x82, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x81, 0x81, + 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, + 0x80, 0x80, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7e, 0x80, 0x80, 0x81, 0x81, 0x81, + 0x81, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x7e, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x80, 0x80, 0x7e, 0x7e, 0x7d, 0x7d, 0x7c, + 0x7c, 0x7d, 0x80, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7e, 0x7e, 0x7e, 0x7d, 0x7c, 0x7c, 0x7c, 0x7d, 0x7e, 0x80, 0x81, + 0x81, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x80, 0x81, 0x82, 0x83, 0x82, 0x81, 0x80, 0x7d, 0x7d, 0x7e, 0x7e, 0x80, 0x82, 0x83, + 0x83, 0x83, 0x82, 0x80, 0x7e, 0x7d, 0x7d, 0x7e, 0x81, 0x82, 0x83, 0x83, 0x84, 0x83, 0x81, 0x7e, + 0x7c, 0x7b, 0x7b, 0x7c, 0x7d, 0x80, 0x82, 0x82, 0x82, 0x81, 0x80, 0x80, 0x80, 0x7e, 0x7d, 0x7e, + 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, + 0x80, 0x81, 0x80, 0x80, 0x80, 0x7e, 0x7d, 0x7c, 0x7c, 0x7b, 0x7b, 0x7d, 0x80, 0x81, 0x81, 0x81, + 0x81, 0x80, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x80, 0x80, 0x80, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, + 0x80, 0x81, 0x81, 0x81, 0x80, 0x7e, 0x7d, 0x7d, 0x7c, 0x7d, 0x7e, 0x7e, 0x80, 0x81, 0x80, 0x7e, + 0x7c, 0x7a, 0x78, 0x79, 0x80, 0x88, 0x8d, 0x8d, 0x86, 0x7b, 0x71, 0x6c, 0x6d, 0x73, 0x7b, 0x85, + 0x8c, 0x8e, 0x8d, 0x87, 0x80, 0x77, 0x71, 0x70, 0x72, 0x77, 0x7e, 0x86, 0x8a, 0x8c, 0x8b, 0x86, + 0x80, 0x79, 0x77, 0x75, 0x77, 0x7b, 0x7e, 0x83, 0x86, 0x87, 0x87, 0x85, 0x83, 0x7e, 0x78, 0x75, + 0x76, 0x7a, 0x81, 0x85, 0x88, 0x89, 0x86, 0x83, 0x7e, 0x7b, 0x78, 0x78, 0x7a, 0x7c, 0x80, 0x83, + 0x85, 0x85, 0x84, 0x82, 0x7e, 0x7c, 0x7c, 0x7b, 0x7c, 0x7e, 0x81, 0x83, 0x83, 0x82, 0x80, 0x7c, + 0x7a, 0x79, 0x79, 0x7a, 0x7d, 0x81, 0x85, 0x87, 0x88, 0x85, 0x80, 0x7a, 0x74, 0x71, 0x73, 0x79, + 0x80, 0x85, 0x88, 0x8a, 0x88, 0x84, 0x80, 0x7b, 0x78, 0x75, 0x75, 0x76, 0x7b, 0x81, 0x86, 0x89, + 0x89, 0x86, 0x81, 0x7b, 0x76, 0x73, 0x74, 0x79, 0x7e, 0x86, 0x8a, 0x8c, 0x88, 0x83, 0x7d, 0x79, + 0x78, 0x7c, 0x80, 0x82, 0x82, 0x80, 0x7c, 0x7b, 0x7a, 0x7c, 0x80, 0x83, 0x85, 0x85, 0x82, 0x7c, + 0x78, 0x76, 0x79, 0x7c, 0x80, 0x83, 0x83, 0x83, 0x82, 0x80, 0x7c, 0x7a, 0x7a, 0x7b, 0x7e, 0x81, + 0x82, 0x83, 0x82, 0x81, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x82, 0x84, 0x84, 0x83, 0x80, 0x7d, + 0x7b, 0x7b, 0x7e, 0x81, 0x82, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7d, 0x7c, 0x7b, 0x7d, 0x80, 0x83, 0x85, 0x84, 0x82, + 0x7e, 0x7c, 0x7b, 0x7b, 0x7b, 0x7c, 0x7d, 0x7e, 0x81, 0x82, 0x81, 0x81, 0x80, 0x81, 0x7e, 0x7b, + 0x79, 0x77, 0x78, 0x7a, 0x7d, 0x82, 0x85, 0x86, 0x85, 0x83, 0x80, 0x7c, 0x79, 0x77, 0x79, 0x7c, + 0x82, 0x85, 0x86, 0x85, 0x82, 0x80, 0x7e, 0x7d, 0x7e, 0x80, 0x7e, 0x80, 0x7e, 0x7e, 0x7d, 0x7c, + 0x7d, 0x7e, 0x80, 0x83, 0x85, 0x84, 0x82, 0x7e, 0x7b, 0x7a, 0x79, 0x7a, 0x7c, 0x80, 0x83, 0x85, + 0x85, 0x84, 0x82, 0x7e, 0x7c, 0x7a, 0x7a, 0x7b, 0x7d, 0x81, 0x82, 0x82, 0x83, 0x83, 0x82, 0x80, + 0x7c, 0x7b, 0x7b, 0x7c, 0x7d, 0x7e, 0x80, 0x81, 0x83, 0x84, 0x84, 0x83, 0x81, 0x7d, 0x7c, 0x7c, + 0x7b, 0x7c, 0x7d, 0x80, 0x81, 0x82, 0x82, 0x83, 0x82, 0x80, 0x7e, 0x7b, 0x79, 0x7a, 0x7b, 0x7c, + 0x80, 0x82, 0x83, 0x82, 0x80, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x80, 0x81, 0x82, 0x81, 0x80, 0x7e, + 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x80, 0x81, 0x82, 0x82, 0x81, 0x80, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x7e, 0x7d, 0x7c, 0x7c, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x80, 0x7e, 0x80, 0x81, 0x81, 0x81, 0x81, 0x80, 0x7d, 0x7c, 0x7b, 0x7b, 0x7c, 0x7d, 0x7e, + 0x80, 0x81, 0x82, 0x82, 0x80, 0x7c, 0x7b, 0x7a, 0x7b, 0x7c, 0x80, 0x83, 0x83, 0x83, 0x82, 0x80, + 0x7d, 0x7b, 0x7a, 0x79, 0x7b, 0x7c, 0x7d, 0x80, 0x82, 0x83, 0x84, 0x83, 0x81, 0x7e, 0x7c, 0x7a, + 0x79, 0x7a, 0x7b, 0x7d, 0x81, 0x83, 0x84, 0x84, 0x83, 0x81, 0x7c, 0x7a, 0x78, 0x78, 0x7a, 0x7d, + 0x81, 0x84, 0x85, 0x85, 0x84, 0x81, 0x7d, 0x7a, 0x79, 0x7a, 0x7b, 0x7e, 0x82, 0x83, 0x85, 0x85, + 0x83, 0x81, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x80, 0x81, 0x82, 0x82, 0x83, 0x83, 0x82, 0x82, 0x81, + 0x81, 0x81, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x80, 0x7e, 0x7e, 0x7d, 0x7d, + 0x7d, 0x7e, 0x7e, 0x7e, 0x80, 0x81, 0x82, 0x81, 0x81, 0x80, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, + 0x80, 0x81, 0x81, 0x80, 0x7e, 0x7d, 0x7c, 0x7d, 0x7d, 0x7d, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x7e, + 0x7d, 0x7c, 0x7d, 0x7e, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x81, 0x80, + 0x80, 0x81, 0x82, 0x81, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x81, 0x80, 0x80, 0x7e, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x7e, 0x7e, 0x7d, 0x7c, 0x7d, 0x7e, + 0x7d, 0x7d, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7d, 0x7e, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x81, 0x80, 0x80, + 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, + 0x7e, 0x81, 0x82, 0x82, 0x82, 0x81, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x80, 0x81, 0x81, + 0x80, 0x7d, 0x7d, 0x7c, 0x7c, 0x7d, 0x7e, 0x80, 0x81, 0x80, 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x81, 0x80, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7e, 0x80, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x80, 0x81, 0x81, 0x80, 0x7e, 0x7e, 0x7d, 0x7e, 0x80, + 0x81, 0x82, 0x81, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x80, 0x80, 0x81, + 0x81, 0x82, 0x81, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x81, 0x82, 0x82, 0x81, 0x80, 0x80, 0x7e, + 0x7e, 0x7d, 0x7e, 0x80, 0x80, 0x81, 0x80, 0x80, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7d, + 0x7d, 0x7e, 0x80, 0x82, 0x83, 0x82, 0x80, 0x7d, 0x7c, 0x7b, 0x7b, 0x7d, 0x80, 0x81, 0x82, 0x82, + 0x82, 0x81, 0x80, 0x80, 0x7d, 0x7c, 0x7c, 0x7d, 0x7e, 0x81, 0x82, 0x83, 0x82, 0x80, 0x7e, 0x7d, + 0x7d, 0x7d, 0x80, 0x82, 0x82, 0x83, 0x82, 0x80, 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, 0x81, 0x82, 0x82, + 0x81, 0x80, 0x7d, 0x7d, 0x7e, 0x7d, 0x7e, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x7e, 0x7d, 0x7c, + 0x7c, 0x7d, 0x80, 0x80, 0x81, 0x82, 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, + 0x7d, 0x7d, 0x7d, 0x7e, 0x81, 0x82, 0x83, 0x82, 0x81, 0x7e, 0x7c, 0x7b, 0x7b, 0x7d, 0x81, 0x83, + 0x84, 0x84, 0x83, 0x7e, 0x7c, 0x7a, 0x7a, 0x7e, 0x82, 0x84, 0x85, 0x83, 0x81, 0x7e, 0x7d, 0x7d, + 0x7e, 0x80, 0x82, 0x83, 0x82, 0x82, 0x82, 0x82, 0x81, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x81, 0x83, + 0x83, 0x81, 0x7e, 0x7d, 0x7c, 0x7c, 0x7d, 0x80, 0x82, 0x82, 0x81, 0x7e, 0x7c, 0x7b, 0x7c, 0x7c, + 0x7e, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, 0x82, 0x81, 0x7d, 0x7b, 0x7a, 0x7b, 0x7d, 0x82, 0x85, + 0x87, 0x87, 0x84, 0x81, 0x7d, 0x7a, 0x78, 0x78, 0x79, 0x7e, 0x83, 0x87, 0x89, 0x88, 0x84, 0x80, + 0x7a, 0x77, 0x76, 0x77, 0x7a, 0x7e, 0x83, 0x86, 0x87, 0x86, 0x83, 0x7d, 0x7a, 0x78, 0x78, 0x7a, + 0x7d, 0x81, 0x83, 0x84, 0x84, 0x84, 0x82, 0x7e, 0x7b, 0x79, 0x77, 0x78, 0x7c, 0x80, 0x84, 0x86, + 0x86, 0x83, 0x7e, 0x7a, 0x78, 0x78, 0x7a, 0x7d, 0x82, 0x85, 0x86, 0x84, 0x82, 0x80, 0x7d, 0x7c, + 0x7d, 0x7d, 0x7e, 0x81, 0x83, 0x82, 0x82, 0x82, 0x80, 0x7d, 0x7c, 0x7c, 0x7e, 0x81, 0x81, 0x81, + 0x7e, 0x7d, 0x7c, 0x7c, 0x7d, 0x80, 0x81, 0x81, 0x80, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, + 0x7d, 0x7d, 0x7d, 0x7e, 0x82, 0x83, 0x84, 0x83, 0x81, 0x7e, 0x7e, 0x7e, 0x80, 0x81, 0x81, 0x82, + 0x82, 0x82, 0x82, 0x82, 0x81, 0x80, 0x7e, 0x7e, 0x80, 0x81, 0x81, 0x82, 0x82, 0x81, 0x80, 0x7e, + 0x7e, 0x80, 0x80, 0x80, 0x81, 0x81, 0x82, 0x81, 0x81, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, + 0x81, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7d, 0x7c, 0x7d, 0x7e, 0x80, 0x81, + 0x80, 0x7e, 0x7e, 0x7e, 0x80, 0x81, 0x82, 0x81, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, + 0x7e, 0x7e, 0x7d, 0x7e, 0x81, 0x81, 0x82, 0x81, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, + 0x7e, 0x81, 0x83, 0x85, 0x85, 0x83, 0x7e, 0x79, 0x76, 0x76, 0x79, 0x7e, 0x84, 0x87, 0x86, 0x83, + 0x7e, 0x7b, 0x7a, 0x7b, 0x7c, 0x7e, 0x81, 0x83, 0x84, 0x84, 0x82, 0x80, 0x7e, 0x7d, 0x7c, 0x7c, + 0x7d, 0x80, 0x80, 0x81, 0x81, 0x81, 0x80, 0x80, 0x7e, 0x7e, 0x7d, 0x7c, 0x7b, 0x7b, 0x7b, 0x7e, + 0x81, 0x82, 0x82, 0x81, 0x7d, 0x7b, 0x7b, 0x7b, 0x7d, 0x80, 0x81, 0x81, 0x80, 0x7e, 0x7c, 0x7c, + 0x7c, 0x7d, 0x7e, 0x81, 0x82, 0x83, 0x82, 0x81, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x80, + 0x7e, 0x7d, 0x7e, 0x80, 0x82, 0x82, 0x81, 0x7e, 0x7d, 0x7c, 0x7c, 0x7d, 0x7e, 0x80, 0x80, 0x81, + 0x81, 0x82, 0x81, 0x7e, 0x7e, 0x7d, 0x7e, 0x80, 0x81, 0x81, 0x80, 0x7e, 0x7d, 0x7e, 0x80, 0x7e, + 0x7d, 0x7e, 0x7e, 0x80, 0x81, 0x81, 0x81, 0x80, 0x7e, 0x7d, 0x7d, 0x7e, 0x80, 0x7e, 0x7e, 0x80, + 0x80, 0x81, 0x81, 0x81, 0x80, 0x7e, 0x7e, 0x7d, 0x7e, 0x80, 0x80, 0x81, 0x81, 0x80, 0x7e, 0x7e, + 0x7e, 0x7e, 0x80, 0x81, 0x81, 0x82, 0x82, 0x81, 0x80, 0x7d, 0x7d, 0x7e, 0x80, 0x81, 0x82, 0x82, + 0x81, 0x81, 0x7e, 0x7b, 0x78, 0x77, 0x78, 0x7c, 0x82, 0x87, 0x88, 0x86, 0x81, 0x79, 0x74, 0x71, + 0x73, 0x7a, 0x83, 0x89, 0x8e, 0x8e, 0x87, 0x7e, 0x76, 0x72, 0x73, 0x78, 0x7e, 0x86, 0x88, 0x88, + 0x84, 0x81, 0x7d, 0x7a, 0x7a, 0x7a, 0x7c, 0x7e, 0x80, 0x81, 0x82, 0x81, 0x82, 0x82, 0x82, 0x81, + 0x7e, 0x7b, 0x79, 0x77, 0x79, 0x7c, 0x81, 0x85, 0x87, 0x86, 0x82, 0x7c, 0x78, 0x78, 0x7b, 0x81, + 0x85, 0x87, 0x85, 0x81, 0x7b, 0x77, 0x76, 0x78, 0x7b, 0x82, 0x86, 0x88, 0x87, 0x83, 0x7c, 0x78, + 0x76, 0x76, 0x7b, 0x81, 0x86, 0x8a, 0x8a, 0x87, 0x81, 0x7a, 0x75, 0x72, 0x73, 0x78, 0x80, 0x87, + 0x8a, 0x89, 0x84, 0x7c, 0x77, 0x75, 0x76, 0x7a, 0x80, 0x84, 0x86, 0x85, 0x82, 0x7d, 0x7c, 0x7b, + 0x7c, 0x7d, 0x7d, 0x7e, 0x80, 0x81, 0x83, 0x84, 0x83, 0x80, 0x7b, 0x78, 0x76, 0x77, 0x7b, 0x82, + 0x87, 0x89, 0x86, 0x81, 0x7a, 0x77, 0x76, 0x78, 0x7d, 0x82, 0x84, 0x83, 0x80, 0x7d, 0x7a, 0x7a, + 0x7c, 0x80, 0x81, 0x81, 0x80, 0x7e, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x81, 0x81, 0x81, + 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7d, + 0x7c, 0x7c, 0x7e, 0x80, 0x80, 0x81, 0x81, 0x80, 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x80, 0x80, + 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x80, 0x82, 0x81, 0x7d, 0x79, 0x77, 0x77, 0x7c, 0x82, 0x83, 0x83, + 0x81, 0x7e, 0x7d, 0x7a, 0x78, 0x78, 0x7a, 0x7d, 0x83, 0x86, 0x86, 0x87, 0x85, 0x81, 0x7c, 0x79, + 0x75, 0x75, 0x78, 0x80, 0x86, 0x8a, 0x88, 0x81, 0x78, 0x74, 0x77, 0x7d, 0x84, 0x87, 0x86, 0x83, + 0x7d, 0x79, 0x74, 0x72, 0x74, 0x78, 0x80, 0x85, 0x89, 0x8b, 0x8a, 0x85, 0x7d, 0x74, 0x70, 0x71, + 0x77, 0x82, 0x8c, 0x8f, 0x8d, 0x8a, 0x85, 0x7e, 0x75, 0x6e, 0x6d, 0x76, 0x83, 0x8f, 0x95, 0x93, + 0x8c, 0x7d, 0x6c, 0x61, 0x65, 0x77, 0x8b, 0x95, 0x91, 0x87, 0x80, 0x80, 0x81, 0x7c, 0x74, 0x6e, + 0x72, 0x7e, 0x8c, 0x96, 0x93, 0x88, 0x7e, 0x79, 0x7a, 0x7e, 0x82, 0x80, 0x7d, 0x7b, 0x7c, 0x81, + 0x84, 0x83, 0x80, 0x7b, 0x7c, 0x81, 0x83, 0x85, 0x84, 0x81, 0x7b, 0x7a, 0x7d, 0x82, 0x85, 0x85, + 0x80, 0x7c, 0x7b, 0x7b, 0x7d, 0x7b, 0x78, 0x77, 0x7b, 0x84, 0x8a, 0x8a, 0x85, 0x7d, 0x78, 0x75, + 0x76, 0x77, 0x7a, 0x7b, 0x7d, 0x81, 0x82, 0x84, 0x86, 0x85, 0x80, 0x79, 0x75, 0x75, 0x79, 0x7d, + 0x81, 0x82, 0x7e, 0x7d, 0x7e, 0x81, 0x83, 0x81, 0x7e, 0x80, 0x82, 0x82, 0x81, 0x7d, 0x7b, 0x7a, + 0x7a, 0x7b, 0x80, 0x85, 0x85, 0x85, 0x83, 0x81, 0x7e, 0x78, 0x75, 0x74, 0x76, 0x7b, 0x83, 0x88, + 0x89, 0x86, 0x84, 0x82, 0x7e, 0x7a, 0x74, 0x72, 0x76, 0x7e, 0x85, 0x87, 0x86, 0x86, 0x85, 0x84, + 0x81, 0x7c, 0x79, 0x7a, 0x7c, 0x7e, 0x82, 0x82, 0x84, 0x85, 0x85, 0x83, 0x81, 0x80, 0x7c, 0x79, + 0x78, 0x7a, 0x80, 0x84, 0x87, 0x89, 0x85, 0x80, 0x7c, 0x7b, 0x7d, 0x80, 0x7d, 0x7a, 0x79, 0x7c, + 0x83, 0x8a, 0x8c, 0x8b, 0x85, 0x7c, 0x77, 0x77, 0x79, 0x79, 0x7c, 0x81, 0x86, 0x8d, 0x8e, 0x88, + 0x81, 0x78, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7c, 0x81, 0x84, 0x86, 0x84, 0x81, 0x7d, 0x7b, 0x7b, + 0x7d, 0x7c, 0x7a, 0x78, 0x7a, 0x7c, 0x83, 0x86, 0x85, 0x85, 0x81, 0x7b, 0x76, 0x73, 0x75, 0x79, + 0x7e, 0x83, 0x86, 0x88, 0x86, 0x81, 0x7b, 0x77, 0x7a, 0x81, 0x84, 0x82, 0x80, 0x7d, 0x7b, 0x7d, + 0x81, 0x83, 0x84, 0x84, 0x84, 0x85, 0x86, 0x85, 0x81, 0x7d, 0x7b, 0x7a, 0x79, 0x78, 0x78, 0x7b, + 0x7e, 0x85, 0x8b, 0x8e, 0x8e, 0x89, 0x7e, 0x72, 0x6b, 0x67, 0x6c, 0x74, 0x7d, 0x89, 0x92, 0x97, + 0x94, 0x8c, 0x81, 0x75, 0x6c, 0x6a, 0x6c, 0x73, 0x7c, 0x87, 0x8f, 0x92, 0x90, 0x8b, 0x82, 0x75, + 0x71, 0x73, 0x78, 0x7d, 0x7e, 0x81, 0x85, 0x88, 0x89, 0x88, 0x81, 0x79, 0x75, 0x78, 0x81, 0x8c, + 0x92, 0x8f, 0x84, 0x75, 0x6d, 0x6d, 0x72, 0x7b, 0x88, 0x91, 0x93, 0x8e, 0x83, 0x78, 0x74, 0x74, + 0x77, 0x7b, 0x7e, 0x7e, 0x7e, 0x7e, 0x81, 0x89, 0x8d, 0x8a, 0x83, 0x7b, 0x76, 0x75, 0x75, 0x7a, + 0x80, 0x82, 0x81, 0x81, 0x85, 0x89, 0x8b, 0x87, 0x7d, 0x76, 0x74, 0x76, 0x79, 0x7d, 0x80, 0x82, + 0x83, 0x85, 0x8a, 0x8b, 0x84, 0x7b, 0x72, 0x70, 0x74, 0x78, 0x7e, 0x83, 0x84, 0x85, 0x85, 0x85, + 0x87, 0x85, 0x7d, 0x75, 0x71, 0x74, 0x79, 0x80, 0x85, 0x86, 0x83, 0x7d, 0x7c, 0x7c, 0x80, 0x82, + 0x83, 0x81, 0x7b, 0x78, 0x76, 0x76, 0x7b, 0x81, 0x85, 0x8a, 0x8e, 0x8e, 0x8a, 0x7c, 0x6d, 0x63, + 0x60, 0x6d, 0x81, 0x91, 0x9c, 0x9c, 0x92, 0x85, 0x75, 0x69, 0x66, 0x68, 0x70, 0x7e, 0x8f, 0x98, + 0x99, 0x93, 0x87, 0x79, 0x6c, 0x65, 0x68, 0x72, 0x81, 0x8f, 0x95, 0x93, 0x8a, 0x7c, 0x71, 0x6d, + 0x6e, 0x76, 0x7e, 0x86, 0x8b, 0x89, 0x87, 0x81, 0x77, 0x74, 0x74, 0x7a, 0x83, 0x88, 0x89, 0x85, + 0x80, 0x7c, 0x77, 0x78, 0x7b, 0x7d, 0x80, 0x84, 0x88, 0x8a, 0x89, 0x82, 0x7a, 0x75, 0x70, 0x6c, + 0x71, 0x7b, 0x86, 0x90, 0x96, 0x98, 0x92, 0x85, 0x75, 0x67, 0x61, 0x69, 0x77, 0x84, 0x8e, 0x96, + 0x9a, 0x97, 0x8b, 0x80, 0x75, 0x6b, 0x65, 0x64, 0x6c, 0x7a, 0x8a, 0x99, 0xa0, 0x9c, 0x8f, 0x7b, + 0x6b, 0x63, 0x60, 0x69, 0x75, 0x84, 0x90, 0x99, 0x9d, 0x98, 0x8a, 0x76, 0x67, 0x5f, 0x60, 0x69, + 0x7a, 0x8c, 0x96, 0x9a, 0x98, 0x91, 0x83, 0x77, 0x73, 0x6d, 0x66, 0x68, 0x71, 0x7d, 0x8c, 0x98, + 0xa0, 0xa3, 0x9b, 0x89, 0x75, 0x63, 0x57, 0x59, 0x67, 0x76, 0x8a, 0xa0, 0xaa, 0xa7, 0x9b, 0x89, + 0x73, 0x60, 0x55, 0x52, 0x58, 0x67, 0x7e, 0x97, 0xa9, 0xb0, 0xaa, 0x98, 0x80, 0x67, 0x58, 0x54, + 0x59, 0x62, 0x72, 0x88, 0x9b, 0xa6, 0xaa, 0xa0, 0x8c, 0x76, 0x65, 0x5a, 0x5c, 0x6c, 0x7d, 0x8d, + 0x9a, 0x9f, 0x9c, 0x90, 0x78, 0x65, 0x5c, 0x5b, 0x65, 0x77, 0x8f, 0xa0, 0xa7, 0xa3, 0x93, 0x7b, + 0x68, 0x5b, 0x58, 0x60, 0x70, 0x82, 0x91, 0x9a, 0x9c, 0x99, 0x91, 0x84, 0x76, 0x6d, 0x69, 0x6a, + 0x73, 0x7b, 0x86, 0x8e, 0x92, 0x94, 0x90, 0x88, 0x7e, 0x76, 0x6f, 0x6d, 0x6d, 0x75, 0x83, 0x8d, + 0x95, 0x98, 0x93, 0x88, 0x7a, 0x6b, 0x66, 0x69, 0x6e, 0x7b, 0x84, 0x8b, 0x92, 0x8e, 0x8a, 0x87, + 0x84, 0x7c, 0x74, 0x75, 0x76, 0x74, 0x77, 0x7c, 0x80, 0x81, 0x86, 0x8c, 0x8b, 0x8a, 0x88, 0x80, + 0x7a, 0x7b, 0x7b, 0x75, 0x76, 0x80, 0x83, 0x81, 0x81, 0x82, 0x81, 0x7d, 0x81, 0x82, 0x7d, 0x81, + 0x85, 0x85, 0x7d, 0x78, 0x7a, 0x7c, 0x7c, 0x7b, 0x7b, 0x83, 0x85, 0x82, 0x84, 0x89, 0x8a, 0x85, + 0x7d, 0x79, 0x73, 0x72, 0x73, 0x79, 0x82, 0x8a, 0x93, 0x96, 0x90, 0x87, 0x79, 0x6a, 0x62, 0x65, + 0x73, 0x84, 0x93, 0x9a, 0x99, 0x94, 0x86, 0x75, 0x6a, 0x67, 0x69, 0x6d, 0x79, 0x88, 0x8e, 0x8e, + 0x8f, 0x8b, 0x86, 0x80, 0x77, 0x72, 0x70, 0x6d, 0x6f, 0x77, 0x82, 0x8a, 0x8f, 0x94, 0x91, 0x89, + 0x7e, 0x75, 0x6f, 0x6a, 0x6b, 0x74, 0x80, 0x8e, 0x99, 0xa0, 0xa0, 0x91, 0x7c, 0x6b, 0x5c, 0x55, + 0x5b, 0x6f, 0x87, 0x9b, 0xab, 0xaf, 0xa7, 0x92, 0x73, 0x5a, 0x52, 0x54, 0x62, 0x78, 0x8e, 0x9f, + 0xa8, 0xa6, 0x9d, 0x89, 0x73, 0x67, 0x61, 0x5f, 0x68, 0x78, 0x87, 0x91, 0x96, 0x95, 0x91, 0x85, + 0x79, 0x71, 0x6a, 0x6e, 0x77, 0x82, 0x8d, 0x94, 0x92, 0x88, 0x7c, 0x74, 0x6d, 0x6b, 0x74, 0x82, + 0x8c, 0x93, 0x93, 0x8b, 0x7d, 0x73, 0x6b, 0x6d, 0x78, 0x84, 0x8a, 0x8a, 0x8a, 0x85, 0x78, 0x74, + 0x75, 0x73, 0x75, 0x7e, 0x8b, 0x91, 0x8f, 0x8f, 0x8a, 0x7b, 0x6f, 0x6b, 0x6d, 0x74, 0x76, 0x79, + 0x88, 0x96, 0x93, 0x8e, 0x8f, 0x8c, 0x80, 0x70, 0x69, 0x65, 0x61, 0x66, 0x75, 0x86, 0x95, 0x9c, + 0xa2, 0xa4, 0x94, 0x7c, 0x6a, 0x63, 0x5d, 0x59, 0x69, 0x86, 0x99, 0x9e, 0xa2, 0xa3, 0x8e, 0x72, + 0x63, 0x5f, 0x66, 0x70, 0x7c, 0x8f, 0x9d, 0x9a, 0x8e, 0x84, 0x7b, 0x6d, 0x61, 0x6b, 0x7d, 0x86, + 0x87, 0x91, 0x9a, 0x8f, 0x7d, 0x79, 0x78, 0x6f, 0x6a, 0x72, 0x7b, 0x80, 0x83, 0x8a, 0x90, 0x8e, + 0x88, 0x84, 0x7e, 0x78, 0x74, 0x75, 0x79, 0x7e, 0x7d, 0x7c, 0x80, 0x82, 0x83, 0x82, 0x83, 0x84, + 0x80, 0x7c, 0x7e, 0x82, 0x82, 0x86, 0x88, 0x81, 0x77, 0x74, 0x74, 0x76, 0x7c, 0x86, 0x8f, 0x8f, + 0x8b, 0x89, 0x80, 0x71, 0x6c, 0x6d, 0x71, 0x7a, 0x86, 0x90, 0x96, 0x94, 0x8c, 0x7e, 0x73, 0x6e, + 0x6e, 0x70, 0x7a, 0x86, 0x8c, 0x90, 0x91, 0x89, 0x7c, 0x76, 0x76, 0x75, 0x75, 0x7d, 0x87, 0x8b, + 0x8c, 0x8a, 0x85, 0x7c, 0x72, 0x70, 0x7a, 0x7e, 0x84, 0x8c, 0x8f, 0x8b, 0x7d, 0x74, 0x70, 0x68, + 0x65, 0x75, 0x89, 0x91, 0x97, 0x9b, 0x99, 0x88, 0x6e, 0x60, 0x5e, 0x61, 0x6d, 0x83, 0x96, 0x9f, + 0x9f, 0x96, 0x8a, 0x75, 0x61, 0x5f, 0x67, 0x70, 0x7d, 0x8d, 0x9a, 0xa2, 0x95, 0x85, 0x80, 0x74, + 0x65, 0x5e, 0x68, 0x77, 0x7a, 0x82, 0x96, 0xa1, 0x9c, 0x91, 0x8a, 0x80, 0x6d, 0x5e, 0x5d, 0x64, + 0x6a, 0x71, 0x83, 0x9b, 0xa5, 0xa4, 0x9e, 0x93, 0x83, 0x65, 0x50, 0x55, 0x64, 0x6a, 0x76, 0x94, + 0xa8, 0xa4, 0x99, 0x96, 0x8a, 0x6b, 0x5c, 0x65, 0x70, 0x75, 0x7a, 0x89, 0x9a, 0x95, 0x89, 0x8a, + 0x8c, 0x7b, 0x66, 0x68, 0x7a, 0x7d, 0x7a, 0x8a, 0x9d, 0x98, 0x87, 0x83, 0x7c, 0x6e, 0x60, 0x64, + 0x7a, 0x8c, 0x8a, 0x8b, 0x98, 0x99, 0x87, 0x77, 0x78, 0x77, 0x66, 0x5e, 0x6d, 0x7e, 0x83, 0x8a, + 0x97, 0xa1, 0x9b, 0x8b, 0x83, 0x74, 0x61, 0x55, 0x5f, 0x6f, 0x76, 0x85, 0x9f, 0xaa, 0x9f, 0x95, + 0x90, 0x7c, 0x60, 0x57, 0x61, 0x69, 0x6b, 0x7d, 0x9f, 0xab, 0x9e, 0x94, 0x91, 0x82, 0x61, 0x4f, + 0x59, 0x6c, 0x71, 0x7b, 0x9f, 0xb4, 0xa5, 0x90, 0x8e, 0x83, 0x5e, 0x48, 0x55, 0x69, 0x6d, 0x72, + 0x96, 0xb4, 0xa8, 0x94, 0x99, 0x95, 0x70, 0x53, 0x5e, 0x70, 0x68, 0x64, 0x83, 0xa1, 0x9a, 0x8d, + 0x94, 0x96, 0x7d, 0x66, 0x6b, 0x80, 0x7d, 0x6d, 0x7d, 0x99, 0x8f, 0x76, 0x79, 0x89, 0x7b, 0x68, + 0x75, 0x8e, 0x90, 0x87, 0x8c, 0x96, 0x88, 0x68, 0x5f, 0x6a, 0x6f, 0x73, 0x80, 0x92, 0x9c, 0x99, + 0x93, 0x87, 0x75, 0x6c, 0x67, 0x60, 0x68, 0x78, 0x84, 0x91, 0x9a, 0x9a, 0x94, 0x86, 0x7b, 0x70, + 0x63, 0x64, 0x69, 0x70, 0x7d, 0x8c, 0x94, 0x93, 0x8e, 0x8b, 0x89, 0x7d, 0x72, 0x6d, 0x6d, 0x67, + 0x64, 0x6c, 0x7c, 0x90, 0xa0, 0xaa, 0xa7, 0x9b, 0x86, 0x69, 0x54, 0x4c, 0x4d, 0x59, 0x73, 0x8f, + 0xa8, 0xae, 0xac, 0xab, 0x9a, 0x7c, 0x67, 0x59, 0x54, 0x57, 0x64, 0x7a, 0x8c, 0x99, 0xa8, 0xac, + 0xa0, 0x89, 0x6f, 0x5e, 0x56, 0x54, 0x5c, 0x77, 0x98, 0xa7, 0xa4, 0xa1, 0x9f, 0x87, 0x61, 0x52, + 0x55, 0x5b, 0x68, 0x7c, 0x97, 0xb0, 0xb3, 0xa2, 0x8f, 0x7c, 0x67, 0x52, 0x52, 0x5d, 0x66, 0x7d, + 0x9c, 0xa7, 0xa0, 0x9f, 0x9f, 0x89, 0x6f, 0x63, 0x62, 0x67, 0x6d, 0x74, 0x83, 0x94, 0x9e, 0x97, + 0x95, 0x98, 0x85, 0x69, 0x65, 0x75, 0x77, 0x6d, 0x74, 0x8a, 0x92, 0x8b, 0x87, 0x88, 0x7e, 0x73, + 0x73, 0x7a, 0x7a, 0x79, 0x7c, 0x85, 0x8a, 0x81, 0x77, 0x7c, 0x89, 0x8e, 0x8d, 0x8b, 0x84, 0x7b, + 0x6e, 0x66, 0x69, 0x6f, 0x74, 0x7e, 0x91, 0xa7, 0xaa, 0x9b, 0x8c, 0x76, 0x65, 0x5a, 0x54, 0x5c, + 0x6e, 0x85, 0x9a, 0xa3, 0xa5, 0xa9, 0x9c, 0x80, 0x6f, 0x63, 0x57, 0x58, 0x65, 0x75, 0x7b, 0x80, + 0x96, 0xab, 0xa3, 0x91, 0x86, 0x7a, 0x6d, 0x64, 0x60, 0x60, 0x62, 0x6d, 0x86, 0x9a, 0x9a, 0x93, + 0x99, 0x9b, 0x88, 0x74, 0x6c, 0x68, 0x63, 0x67, 0x72, 0x7b, 0x7d, 0x85, 0x9b, 0xa2, 0x94, 0x87, + 0x84, 0x7e, 0x6e, 0x66, 0x6d, 0x73, 0x77, 0x81, 0x8d, 0x8f, 0x82, 0x76, 0x80, 0x88, 0x84, 0x80, + 0x80, 0x84, 0x89, 0x7d, 0x71, 0x77, 0x77, 0x73, 0x7c, 0x89, 0x8a, 0x80, 0x7e, 0x8a, 0x89, 0x78, + 0x70, 0x7a, 0x83, 0x85, 0x88, 0x8b, 0x88, 0x7a, 0x73, 0x75, 0x6f, 0x6a, 0x75, 0x83, 0x93, 0x98, + 0x92, 0x92, 0x88, 0x7b, 0x75, 0x6f, 0x68, 0x68, 0x72, 0x83, 0x8f, 0x8f, 0x90, 0x92, 0x98, 0x8a, + 0x71, 0x6e, 0x72, 0x72, 0x6d, 0x72, 0x80, 0x85, 0x85, 0x90, 0x98, 0x8b, 0x82, 0x84, 0x80, 0x74, + 0x66, 0x69, 0x72, 0x6f, 0x75, 0x8b, 0x9b, 0x98, 0x8d, 0x8b, 0x8f, 0x7d, 0x65, 0x64, 0x69, 0x6b, + 0x6f, 0x76, 0x8c, 0xa3, 0xa0, 0x98, 0x90, 0x84, 0x73, 0x63, 0x62, 0x6b, 0x6e, 0x75, 0x8b, 0x99, + 0x96, 0x95, 0x95, 0x8d, 0x75, 0x62, 0x67, 0x6a, 0x6e, 0x7d, 0x87, 0x95, 0x9d, 0x8b, 0x88, 0x87, + 0x77, 0x6b, 0x68, 0x74, 0x7a, 0x78, 0x81, 0x8b, 0x8e, 0x8a, 0x8b, 0x88, 0x7b, 0x75, 0x74, 0x6e, + 0x71, 0x7d, 0x84, 0x87, 0x92, 0x99, 0x8c, 0x81, 0x7e, 0x73, 0x6f, 0x72, 0x71, 0x75, 0x7b, 0x89, + 0x91, 0x8a, 0x87, 0x90, 0x88, 0x7c, 0x80, 0x77, 0x71, 0x6e, 0x6f, 0x79, 0x7e, 0x7d, 0x86, 0x90, + 0x93, 0x95, 0x94, 0x89, 0x82, 0x76, 0x66, 0x62, 0x63, 0x67, 0x75, 0x8f, 0x9b, 0x9b, 0x99, 0x9c, + 0x94, 0x7e, 0x6e, 0x6e, 0x67, 0x5e, 0x65, 0x70, 0x7d, 0x85, 0x8e, 0x99, 0x99, 0x93, 0x8c, 0x7d, + 0x74, 0x70, 0x6e, 0x71, 0x70, 0x74, 0x86, 0x8a, 0x88, 0x86, 0x8b, 0x8c, 0x7b, 0x73, 0x7c, 0x7b, + 0x7a, 0x7a, 0x7b, 0x82, 0x85, 0x81, 0x7d, 0x79, 0x7b, 0x7b, 0x78, 0x80, 0x85, 0x87, 0x89, 0x89, + 0x85, 0x7c, 0x7a, 0x7b, 0x71, 0x6d, 0x7b, 0x83, 0x84, 0x86, 0x90, 0x97, 0x86, 0x80, 0x82, 0x76, + 0x6a, 0x65, 0x73, 0x80, 0x7c, 0x7c, 0x8e, 0x9b, 0x8e, 0x7a, 0x7a, 0x7d, 0x71, 0x5e, 0x65, 0x87, + 0x8a, 0x7d, 0x8d, 0xa4, 0x94, 0x7a, 0x7b, 0x7a, 0x6d, 0x63, 0x70, 0x7e, 0x81, 0x8c, 0x94, 0x8b, + 0x7c, 0x7d, 0x84, 0x7d, 0x76, 0x7d, 0x83, 0x7b, 0x7c, 0x7b, 0x78, 0x79, 0x78, 0x77, 0x82, 0x8f, + 0x89, 0x7c, 0x85, 0x8e, 0x80, 0x6c, 0x75, 0x82, 0x7b, 0x76, 0x7a, 0x84, 0x85, 0x80, 0x7a, 0x84, + 0x8b, 0x83, 0x7e, 0x7d, 0x87, 0x86, 0x72, 0x70, 0x72, 0x75, 0x78, 0x75, 0x80, 0x90, 0x94, 0x8a, + 0x89, 0x87, 0x84, 0x7b, 0x6e, 0x72, 0x76, 0x6f, 0x74, 0x85, 0x88, 0x84, 0x91, 0x94, 0x83, 0x82, + 0x7e, 0x76, 0x6b, 0x68, 0x7b, 0x7e, 0x7d, 0x8c, 0x91, 0x91, 0x84, 0x78, 0x7d, 0x7a, 0x70, 0x6e, + 0x75, 0x7c, 0x85, 0x87, 0x86, 0x91, 0x8d, 0x78, 0x76, 0x7c, 0x76, 0x69, 0x6e, 0x82, 0x93, 0x82, + 0x75, 0x92, 0x9b, 0x78, 0x64, 0x87, 0x8f, 0x6f, 0x69, 0x8b, 0x8f, 0x76, 0x7a, 0x81, 0x88, 0x86, + 0x7b, 0x6e, 0x76, 0x90, 0x83, 0x71, 0x7e, 0x91, 0x8a, 0x6f, 0x7a, 0x8e, 0x7e, 0x6a, 0x77, 0x8a, + 0x7b, 0x73, 0x83, 0x86, 0x7c, 0x81, 0x85, 0x7c, 0x7a, 0x83, 0x7e, 0x78, 0x7d, 0x80, 0x7c, 0x83, + 0x88, 0x83, 0x7c, 0x7c, 0x85, 0x83, 0x85, 0x84, 0x87, 0x86, 0x7a, 0x82, 0x80, 0x72, 0x71, 0x79, + 0x80, 0x84, 0x81, 0x84, 0x8d, 0x88, 0x80, 0x78, 0x77, 0x79, 0x7c, 0x82, 0x7c, 0x7c, 0x85, 0x87, + 0x7c, 0x78, 0x81, 0x7d, 0x75, 0x7d, 0x8c, 0x85, 0x7c, 0x81, 0x86, 0x82, 0x76, 0x77, 0x86, 0x83, + 0x7b, 0x80, 0x84, 0x85, 0x7e, 0x74, 0x77, 0x82, 0x80, 0x7e, 0x82, 0x8c, 0x8f, 0x84, 0x7d, 0x7e, + 0x7a, 0x6f, 0x73, 0x7c, 0x7e, 0x7e, 0x83, 0x8c, 0x89, 0x7d, 0x80, 0x86, 0x82, 0x7a, 0x77, 0x7b, + 0x7c, 0x78, 0x79, 0x80, 0x83, 0x82, 0x88, 0x89, 0x7e, 0x7e, 0x82, 0x7a, 0x76, 0x7e, 0x83, 0x7b, + 0x75, 0x82, 0x8d, 0x81, 0x75, 0x80, 0x88, 0x80, 0x77, 0x7a, 0x7e, 0x7d, 0x7c, 0x7c, 0x7b, 0x7c, + 0x82, 0x82, 0x7a, 0x78, 0x7e, 0x82, 0x7d, 0x78, 0x7b, 0x7e, 0x80, 0x81, 0x83, 0x84, 0x7e, 0x7d, + 0x83, 0x80, 0x78, 0x79, 0x7e, 0x81, 0x7c, 0x7c, 0x84, 0x85, 0x7d, 0x7c, 0x84, 0x87, 0x80, 0x7a, + 0x7a, 0x7d, 0x79, 0x75, 0x7a, 0x7e, 0x81, 0x82, 0x83, 0x88, 0x87, 0x81, 0x7d, 0x7b, 0x7b, 0x77, + 0x75, 0x79, 0x80, 0x82, 0x84, 0x86, 0x86, 0x85, 0x83, 0x80, 0x7d, 0x7b, 0x79, 0x79, 0x7d, 0x7e, + 0x80, 0x82, 0x84, 0x82, 0x84, 0x82, 0x80, 0x80, 0x81, 0x81, 0x7d, 0x80, 0x7e, 0x7b, 0x7b, 0x7d, + 0x7e, 0x7e, 0x7e, 0x80, 0x7d, 0x7c, 0x7c, 0x7c, 0x7e, 0x82, 0x84, 0x83, 0x84, 0x82, 0x7e, 0x7b, + 0x78, 0x79, 0x7a, 0x7b, 0x80, 0x7e, 0x7d, 0x81, 0x85, 0x88, 0x8b, 0x8a, 0x86, 0x80, 0x7a, 0x74, + 0x70, 0x70, 0x74, 0x7a, 0x82, 0x8b, 0x91, 0x91, 0x8e, 0x89, 0x82, 0x7c, 0x75, 0x71, 0x74, 0x74, + 0x78, 0x7e, 0x81, 0x84, 0x88, 0x89, 0x87, 0x84, 0x81, 0x7e, 0x7d, 0x80, 0x80, 0x7d, 0x7d, 0x81, + 0x82, 0x83, 0x83, 0x7e, 0x7d, 0x7b, 0x7a, 0x7c, 0x7d, 0x84, 0x88, 0x87, 0x88, 0x86, 0x80, 0x7b, + 0x76, 0x73, 0x73, 0x75, 0x78, 0x7e, 0x82, 0x85, 0x87, 0x85, 0x82, 0x7e, 0x7d, 0x7b, 0x7b, 0x7e, + 0x7d, 0x7e, 0x82, 0x82, 0x84, 0x84, 0x81, 0x7e, 0x7d, 0x7c, 0x7b, 0x7b, 0x7e, 0x81, 0x82, 0x82, + 0x80, 0x7d, 0x7c, 0x7b, 0x79, 0x77, 0x7a, 0x7c, 0x7e, 0x83, 0x83, 0x83, 0x83, 0x82, 0x7e, 0x78, + 0x77, 0x78, 0x7b, 0x82, 0x83, 0x84, 0x85, 0x81, 0x7e, 0x7e, 0x7a, 0x76, 0x79, 0x7e, 0x84, 0x86, + 0x86, 0x83, 0x81, 0x7e, 0x7c, 0x7c, 0x7c, 0x7c, 0x81, 0x83, 0x82, 0x7e, 0x7d, 0x7d, 0x7c, 0x7b, + 0x7b, 0x7e, 0x82, 0x81, 0x84, 0x84, 0x81, 0x81, 0x7e, 0x7c, 0x7c, 0x7d, 0x7e, 0x7e, 0x81, 0x82, + 0x81, 0x81, 0x82, 0x83, 0x80, 0x7e, 0x81, 0x7e, 0x7d, 0x7e, 0x80, 0x7d, 0x7e, 0x80, 0x7d, 0x7e, + 0x81, 0x81, 0x80, 0x81, 0x80, 0x81, 0x7e, 0x7a, 0x77, 0x76, 0x79, 0x80, 0x84, 0x89, 0x8a, 0x89, + 0x86, 0x7e, 0x7b, 0x77, 0x74, 0x76, 0x7b, 0x7e, 0x82, 0x89, 0x88, 0x85, 0x83, 0x7b, 0x78, 0x78, + 0x7a, 0x7b, 0x82, 0x87, 0x8a, 0x87, 0x84, 0x82, 0x79, 0x78, 0x76, 0x74, 0x78, 0x7b, 0x82, 0x88, + 0x89, 0x8c, 0x87, 0x7e, 0x7b, 0x78, 0x75, 0x77, 0x7a, 0x7a, 0x7e, 0x83, 0x85, 0x85, 0x87, 0x83, + 0x81, 0x83, 0x7d, 0x7c, 0x7a, 0x77, 0x7a, 0x7b, 0x7a, 0x7c, 0x7e, 0x80, 0x81, 0x83, 0x81, 0x7e, + 0x81, 0x81, 0x80, 0x81, 0x84, 0x80, 0x7e, 0x81, 0x7c, 0x7a, 0x79, 0x78, 0x7c, 0x82, 0x88, 0x8b, + 0x8a, 0x87, 0x84, 0x81, 0x7b, 0x79, 0x76, 0x76, 0x7d, 0x84, 0x86, 0x89, 0x8a, 0x84, 0x81, 0x7d, + 0x79, 0x78, 0x78, 0x7a, 0x7d, 0x82, 0x85, 0x87, 0x88, 0x86, 0x81, 0x7c, 0x7c, 0x79, 0x78, 0x78, + 0x79, 0x7e, 0x84, 0x84, 0x86, 0x86, 0x83, 0x82, 0x81, 0x7a, 0x79, 0x79, 0x79, 0x7d, 0x7e, 0x83, + 0x85, 0x86, 0x85, 0x82, 0x81, 0x7b, 0x79, 0x7a, 0x79, 0x7c, 0x81, 0x83, 0x84, 0x83, 0x83, 0x7d, + 0x7c, 0x7d, 0x79, 0x78, 0x7c, 0x7c, 0x7c, 0x80, 0x82, 0x84, 0x88, 0x89, 0x88, 0x83, 0x81, 0x80, + 0x7a, 0x7a, 0x78, 0x76, 0x7d, 0x83, 0x84, 0x87, 0x89, 0x86, 0x83, 0x82, 0x7e, 0x7d, 0x7b, 0x79, + 0x7b, 0x7d, 0x81, 0x81, 0x82, 0x86, 0x85, 0x84, 0x82, 0x7e, 0x7d, 0x79, 0x79, 0x7c, 0x7b, 0x7d, + 0x80, 0x7e, 0x81, 0x80, 0x7e, 0x81, 0x7d, 0x7d, 0x7d, 0x7a, 0x7d, 0x82, 0x82, 0x82, 0x84, 0x83, + 0x81, 0x7e, 0x79, 0x77, 0x78, 0x7b, 0x7b, 0x7e, 0x82, 0x85, 0x86, 0x83, 0x84, 0x83, 0x80, 0x7d, + 0x7c, 0x79, 0x78, 0x78, 0x77, 0x7b, 0x7d, 0x82, 0x85, 0x86, 0x87, 0x86, 0x84, 0x82, 0x7d, 0x79, + 0x77, 0x75, 0x76, 0x7a, 0x7d, 0x81, 0x83, 0x83, 0x82, 0x82, 0x82, 0x80, 0x7d, 0x7e, 0x82, 0x82, + 0x81, 0x7e, 0x7b, 0x7c, 0x80, 0x80, 0x82, 0x82, 0x80, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x80, + 0x81, 0x82, 0x84, 0x82, 0x7d, 0x7e, 0x7b, 0x7c, 0x7e, 0x7c, 0x82, 0x84, 0x82, 0x84, 0x81, 0x7e, + 0x7e, 0x7b, 0x7b, 0x7d, 0x80, 0x83, 0x87, 0x89, 0x88, 0x86, 0x81, 0x7d, 0x7b, 0x7b, 0x7c, 0x7b, + 0x7d, 0x7e, 0x81, 0x83, 0x85, 0x81, 0x7c, 0x7a, 0x77, 0x77, 0x7c, 0x81, 0x83, 0x84, 0x80, 0x7e, + 0x81, 0x7d, 0x79, 0x78, 0x77, 0x78, 0x7c, 0x82, 0x88, 0x89, 0x89, 0x89, 0x86, 0x80, 0x78, 0x76, + 0x73, 0x76, 0x79, 0x7c, 0x81, 0x87, 0x8a, 0x87, 0x86, 0x82, 0x7b, 0x79, 0x7b, 0x7a, 0x7b, 0x7e, + 0x81, 0x81, 0x83, 0x83, 0x83, 0x82, 0x80, 0x7d, 0x7c, 0x7b, 0x7b, 0x80, 0x7e, 0x80, 0x82, 0x81, + 0x81, 0x81, 0x7d, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7d, 0x82, 0x85, 0x87, 0x85, 0x82, 0x80, 0x7a, + 0x75, 0x74, 0x76, 0x79, 0x7b, 0x82, 0x88, 0x88, 0x88, 0x87, 0x82, 0x7b, 0x79, 0x76, 0x73, 0x78, + 0x80, 0x83, 0x88, 0x8a, 0x89, 0x87, 0x83, 0x7c, 0x78, 0x75, 0x75, 0x79, 0x7b, 0x7e, 0x81, 0x84, + 0x84, 0x82, 0x84, 0x82, 0x7e, 0x80, 0x80, 0x7e, 0x81, 0x7e, 0x7c, 0x7d, 0x7a, 0x79, 0x7d, 0x82, + 0x83, 0x86, 0x85, 0x85, 0x86, 0x83, 0x7c, 0x7c, 0x7d, 0x7a, 0x7a, 0x7d, 0x7e, 0x83, 0x87, 0x86, + 0x84, 0x82, 0x81, 0x7c, 0x7b, 0x7b, 0x79, 0x7e, 0x83, 0x83, 0x85, 0x85, 0x83, 0x7e, 0x7b, 0x78, + 0x77, 0x78, 0x7a, 0x80, 0x83, 0x85, 0x84, 0x80, 0x7e, 0x80, 0x7e, 0x7c, 0x7b, 0x7c, 0x7c, 0x7b, + 0x7c, 0x7b, 0x7b, 0x7d, 0x7d, 0x7d, 0x82, 0x83, 0x82, 0x83, 0x80, 0x7e, 0x7e, 0x7a, 0x7b, 0x7b, + 0x7b, 0x7d, 0x7e, 0x84, 0x85, 0x82, 0x85, 0x83, 0x80, 0x7e, 0x7a, 0x79, 0x7d, 0x7d, 0x7c, 0x7e, + 0x81, 0x83, 0x82, 0x82, 0x83, 0x82, 0x82, 0x80, 0x7e, 0x81, 0x82, 0x82, 0x7e, 0x7b, 0x7c, 0x80, + 0x81, 0x81, 0x85, 0x85, 0x80, 0x7d, 0x7c, 0x7a, 0x7c, 0x7e, 0x7d, 0x7e, 0x81, 0x83, 0x83, 0x81, + 0x7e, 0x7b, 0x7a, 0x7c, 0x7c, 0x7c, 0x7e, 0x82, 0x83, 0x83, 0x81, 0x81, 0x80, 0x7c, 0x7a, 0x7b, + 0x7e, 0x81, 0x83, 0x83, 0x7d, 0x7c, 0x7a, 0x79, 0x7a, 0x7b, 0x81, 0x84, 0x86, 0x87, 0x84, 0x81, + 0x7b, 0x78, 0x75, 0x76, 0x7c, 0x81, 0x84, 0x86, 0x84, 0x85, 0x86, 0x82, 0x7e, 0x7d, 0x7b, 0x7a, + 0x7c, 0x7a, 0x78, 0x7a, 0x7c, 0x80, 0x82, 0x83, 0x86, 0x86, 0x83, 0x82, 0x7e, 0x7d, 0x7e, 0x7e, + 0x7c, 0x7b, 0x7b, 0x7c, 0x7d, 0x82, 0x86, 0x86, 0x85, 0x84, 0x82, 0x81, 0x7e, 0x7c, 0x7c, 0x7c, + 0x7e, 0x81, 0x82, 0x82, 0x81, 0x80, 0x7e, 0x80, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x81, 0x83, 0x81, + 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x81, 0x81, 0x82, 0x84, 0x81, 0x7d, 0x7b, 0x7b, 0x7b, 0x7b, 0x7e, + 0x80, 0x82, 0x83, 0x82, 0x82, 0x80, 0x80, 0x80, 0x81, 0x83, 0x81, 0x80, 0x82, 0x81, 0x83, 0x84, + 0x81, 0x7e, 0x7d, 0x80, 0x80, 0x7c, 0x7e, 0x80, 0x7e, 0x80, 0x82, 0x7e, 0x7e, 0x7e, 0x7d, 0x7a, + 0x7b, 0x7e, 0x7d, 0x81, 0x82, 0x82, 0x83, 0x7e, 0x80, 0x80, 0x79, 0x78, 0x79, 0x78, 0x7b, 0x7d, + 0x82, 0x87, 0x84, 0x84, 0x83, 0x7d, 0x7d, 0x7b, 0x7c, 0x7d, 0x7c, 0x80, 0x83, 0x84, 0x86, 0x85, + 0x84, 0x84, 0x82, 0x80, 0x7e, 0x7d, 0x80, 0x80, 0x7b, 0x7e, 0x81, 0x80, 0x82, 0x82, 0x7e, 0x7d, + 0x80, 0x7d, 0x7b, 0x7b, 0x7b, 0x7c, 0x7d, 0x7e, 0x80, 0x7e, 0x7d, 0x80, 0x7e, 0x7e, 0x7e, 0x7b, + 0x7b, 0x7a, 0x7a, 0x75, 0x70, 0x7d, 0x8a, 0x83, 0x82, 0x89, 0x80, 0x6b, 0x63, 0x75, 0x91, 0x9c, + 0x91, 0x75, 0x6f, 0x7e, 0x81, 0x79, 0x74, 0x75, 0x7b, 0x80, 0x90, 0x9c, 0x8a, 0x74, 0x71, 0x7b, + 0x7c, 0x72, 0x76, 0x89, 0x8d, 0x84, 0x7d, 0x81, 0x83, 0x72, 0x68, 0x78, 0x90, 0x96, 0x83, 0x70, + 0x7a, 0x8e, 0x8c, 0x73, 0x70, 0x7e, 0x7c, 0x71, 0x75, 0x88, 0x89, 0x78, 0x76, 0x8a, 0x99, 0x8e, + 0x7b, 0x74, 0x77, 0x73, 0x6e, 0x70, 0x72, 0x72, 0x85, 0xa2, 0xa9, 0x8e, 0x77, 0x7e, 0x7e, 0x6f, + 0x6a, 0x73, 0x79, 0x7c, 0x82, 0x87, 0x82, 0x76, 0x76, 0x83, 0x8f, 0x8d, 0x85, 0x7e, 0x79, 0x70, + 0x6d, 0x77, 0x82, 0x82, 0x86, 0x8f, 0x90, 0x85, 0x79, 0x79, 0x7b, 0x73, 0x6e, 0x76, 0x81, 0x88, + 0x8a, 0x85, 0x79, 0x73, 0x7b, 0x83, 0x82, 0x86, 0x8a, 0x7d, 0x71, 0x76, 0x83, 0x86, 0x7c, 0x78, + 0x78, 0x7b, 0x81, 0x89, 0x90, 0x86, 0x7a, 0x7d, 0x81, 0x7a, 0x77, 0x80, 0x88, 0x82, 0x73, 0x77, + 0x8a, 0x8a, 0x81, 0x81, 0x84, 0x82, 0x7b, 0x7a, 0x7d, 0x7a, 0x75, 0x74, 0x7b, 0x86, 0x8e, 0x8b, + 0x83, 0x80, 0x7c, 0x78, 0x78, 0x76, 0x7b, 0x85, 0x85, 0x83, 0x85, 0x89, 0x88, 0x7c, 0x75, 0x7d, + 0x83, 0x7c, 0x79, 0x7b, 0x81, 0x7e, 0x79, 0x80, 0x87, 0x83, 0x80, 0x7c, 0x7a, 0x7e, 0x7e, 0x80, + 0x83, 0x82, 0x81, 0x82, 0x83, 0x84, 0x82, 0x80, 0x7d, 0x7c, 0x83, 0x84, 0x81, 0x80, 0x82, 0x85, + 0x83, 0x80, 0x7e, 0x80, 0x80, 0x7c, 0x7d, 0x82, 0x86, 0x88, 0x87, 0x86, 0x82, 0x7c, 0x79, 0x79, + 0x80, 0x82, 0x7e, 0x80, 0x85, 0x86, 0x87, 0x87, 0x84, 0x81, 0x7e, 0x7c, 0x79, 0x7c, 0x83, 0x85, + 0x86, 0x84, 0x7e, 0x80, 0x7e, 0x7e, 0x7d, 0x7a, 0x7c, 0x7e, 0x81, 0x82, 0x84, 0x86, 0x84, 0x81, + 0x7e, 0x7d, 0x7d, 0x81, 0x82, 0x80, 0x7d, 0x7c, 0x7d, 0x80, 0x83, 0x88, 0x88, 0x88, 0x87, 0x87, + 0x86, 0x7d, 0x72, 0x69, 0x64, 0x68, 0x76, 0x8e, 0x9e, 0x9f, 0x91, 0x7b, 0x70, 0x71, 0x75, 0x7e, + 0x82, 0x80, 0x80, 0x7d, 0x7c, 0x7e, 0x82, 0x85, 0x87, 0x89, 0x8e, 0x8f, 0x84, 0x73, 0x68, 0x60, + 0x63, 0x74, 0x89, 0x97, 0x9a, 0x92, 0x88, 0x7b, 0x6e, 0x6b, 0x6d, 0x6e, 0x71, 0x7d, 0x8e, 0x90, + 0x8f, 0x91, 0x8c, 0x85, 0x81, 0x82, 0x7b, 0x71, 0x6d, 0x6c, 0x6f, 0x76, 0x85, 0x96, 0x9c, 0x99, + 0x8e, 0x7a, 0x6b, 0x60, 0x5f, 0x66, 0x70, 0x83, 0x91, 0x95, 0x91, 0x89, 0x7d, 0x73, 0x70, 0x75, + 0x7b, 0x82, 0x86, 0x84, 0x82, 0x86, 0x87, 0x86, 0x84, 0x7e, 0x7c, 0x7d, 0x7d, 0x81, 0x81, 0x7c, + 0x7e, 0x81, 0x7c, 0x79, 0x76, 0x77, 0x76, 0x76, 0x7d, 0x88, 0x8a, 0x84, 0x7a, 0x75, 0x78, 0x7e, + 0x83, 0x89, 0x8e, 0x8d, 0x8b, 0x83, 0x79, 0x77, 0x7b, 0x83, 0x8b, 0x8f, 0x8d, 0x87, 0x7e, 0x75, + 0x73, 0x75, 0x7a, 0x82, 0x87, 0x89, 0x89, 0x84, 0x7b, 0x71, 0x6a, 0x6c, 0x73, 0x7b, 0x85, 0x8a, + 0x8b, 0x84, 0x7e, 0x80, 0x81, 0x83, 0x83, 0x7e, 0x7b, 0x78, 0x75, 0x6c, 0x60, 0x5d, 0x73, 0xa3, + 0xcd, 0xd0, 0xa2, 0x54, 0x1d, 0x23, 0x62, 0xb0, 0xcd, 0xb6, 0x89, 0x68, 0x67, 0x77, 0x78, 0x6c, + 0x69, 0x78, 0x94, 0xa5, 0xa3, 0x8b, 0x66, 0x4b, 0x50, 0x75, 0xa8, 0xc2, 0xac, 0x80, 0x60, 0x56, + 0x5a, 0x6c, 0x8a, 0x9d, 0x9c, 0x93, 0x8f, 0x8b, 0x73, 0x5a, 0x5d, 0x70, 0x7c, 0x8b, 0xa4, 0xa5, + 0x7c, 0x5d, 0x5f, 0x6d, 0x76, 0x8b, 0xa3, 0x9b, 0x7d, 0x70, 0x70, 0x6c, 0x6e, 0x81, 0x90, 0x8c, + 0x8b, 0x92, 0x8a, 0x77, 0x72, 0x78, 0x7e, 0x84, 0x8d, 0x8d, 0x7a, 0x6c, 0x6d, 0x72, 0x78, 0x87, + 0x96, 0x92, 0x85, 0x79, 0x70, 0x66, 0x61, 0x6a, 0x7b, 0x8c, 0x99, 0xa0, 0x9a, 0x88, 0x79, 0x69, + 0x5c, 0x5e, 0x6d, 0x84, 0x94, 0x94, 0x92, 0x8b, 0x80, 0x75, 0x71, 0x79, 0x83, 0x88, 0x89, 0x84, + 0x7e, 0x7b, 0x7a, 0x78, 0x7b, 0x82, 0x82, 0x82, 0x81, 0x7d, 0x7c, 0x7c, 0x7e, 0x82, 0x83, 0x82, + 0x82, 0x7a, 0x76, 0x79, 0x7e, 0x86, 0x8b, 0x8c, 0x86, 0x75, 0x60, 0x56, 0x60, 0x82, 0xb3, 0xcd, + 0xb5, 0x7a, 0x40, 0x27, 0x44, 0x86, 0xc0, 0xcf, 0xad, 0x73, 0x4e, 0x4d, 0x69, 0x85, 0x89, 0x81, + 0x7e, 0x8d, 0x9e, 0x9c, 0x81, 0x58, 0x42, 0x52, 0x7e, 0xac, 0xba, 0xab, 0x87, 0x62, 0x58, 0x63, + 0x7d, 0x97, 0x98, 0x88, 0x78, 0x70, 0x73, 0x76, 0x7c, 0x87, 0x8d, 0x93, 0x93, 0x88, 0x71, 0x5c, + 0x55, 0x5e, 0x75, 0x92, 0xab, 0xb1, 0x99, 0x74, 0x5c, 0x52, 0x59, 0x6c, 0x84, 0x97, 0x9d, 0x9c, + 0x97, 0x8a, 0x77, 0x6d, 0x68, 0x66, 0x69, 0x75, 0x83, 0x8a, 0x91, 0x95, 0x96, 0x92, 0x8b, 0x80, + 0x6e, 0x5e, 0x56, 0x5d, 0x6d, 0x88, 0xa6, 0xb1, 0xa9, 0x9c, 0x88, 0x6b, 0x54, 0x4c, 0x54, 0x65, + 0x7b, 0x97, 0xae, 0xb3, 0xa9, 0x91, 0x75, 0x64, 0x5b, 0x5a, 0x62, 0x6f, 0x83, 0x9a, 0xa8, 0xa7, + 0x9e, 0x8d, 0x76, 0x64, 0x5b, 0x5a, 0x61, 0x73, 0x8f, 0xa6, 0xa3, 0x80, 0x5b, 0x5e, 0x88, 0xb3, + 0xb6, 0x7d, 0x36, 0x1e, 0x53, 0xb6, 0xef, 0xdf, 0x9f, 0x5d, 0x3a, 0x3d, 0x55, 0x67, 0x74, 0x8a, + 0xaa, 0xc0, 0xbb, 0x9d, 0x6d, 0x40, 0x27, 0x33, 0x61, 0xa2, 0xca, 0xca, 0xac, 0x82, 0x64, 0x5a, + 0x5f, 0x6c, 0x81, 0x91, 0x91, 0x88, 0x88, 0x88, 0x7e, 0x71, 0x72, 0x7d, 0x83, 0x89, 0x92, 0x89, + 0x6b, 0x57, 0x65, 0x7c, 0x87, 0x90, 0x9a, 0x94, 0x7d, 0x71, 0x74, 0x79, 0x7c, 0x84, 0x8b, 0x87, + 0x7c, 0x7c, 0x81, 0x81, 0x86, 0x90, 0x94, 0x8c, 0x80, 0x76, 0x6e, 0x63, 0x64, 0x77, 0x8b, 0x98, + 0x9f, 0x99, 0x86, 0x6a, 0x5b, 0x5f, 0x69, 0x7a, 0x91, 0x9c, 0x96, 0x89, 0x7a, 0x6c, 0x6d, 0x77, + 0x87, 0x9b, 0x9a, 0x8b, 0x77, 0x6e, 0x73, 0x7c, 0x83, 0x85, 0x88, 0x8a, 0x7d, 0x71, 0x72, 0x79, + 0x81, 0x84, 0x88, 0x8b, 0x88, 0x80, 0x75, 0x71, 0x76, 0x7e, 0x86, 0x8c, 0x93, 0x92, 0x85, 0x71, + 0x5f, 0x55, 0x5b, 0x6f, 0x83, 0x91, 0x9d, 0xa6, 0x9e, 0x83, 0x6c, 0x63, 0x6c, 0x85, 0x99, 0x9b, + 0x8a, 0x76, 0x6b, 0x69, 0x6f, 0x7e, 0x90, 0x99, 0x95, 0x87, 0x73, 0x61, 0x5a, 0x5b, 0x65, 0x79, + 0x91, 0x9f, 0xa3, 0x98, 0x84, 0x73, 0x6a, 0x6b, 0x7a, 0x8f, 0x96, 0x93, 0x8a, 0x7e, 0x72, 0x6e, + 0x78, 0x87, 0x8b, 0x86, 0x82, 0x79, 0x6a, 0x60, 0x6a, 0x7a, 0x86, 0x92, 0x9c, 0x96, 0x83, 0x74, + 0x6f, 0x6c, 0x6a, 0x75, 0x8a, 0x93, 0x95, 0x99, 0x95, 0x84, 0x7a, 0x78, 0x76, 0x77, 0x77, 0x7a, + 0x7b, 0x7a, 0x7d, 0x87, 0x8b, 0x88, 0x85, 0x80, 0x78, 0x74, 0x73, 0x74, 0x77, 0x7d, 0x88, 0x90, + 0x90, 0x8f, 0x86, 0x78, 0x6d, 0x6d, 0x76, 0x80, 0x82, 0x82, 0x80, 0x7b, 0x7d, 0x81, 0x84, 0x8a, + 0x88, 0x80, 0x7c, 0x7b, 0x7a, 0x7b, 0x83, 0x8a, 0x8c, 0x8b, 0x89, 0x81, 0x74, 0x70, 0x75, 0x7a, + 0x81, 0x86, 0x86, 0x83, 0x7c, 0x76, 0x74, 0x77, 0x7d, 0x84, 0x89, 0x8a, 0x88, 0x80, 0x7a, 0x78, + 0x79, 0x7b, 0x7b, 0x79, 0x75, 0x76, 0x89, 0x9d, 0xa3, 0x98, 0x7a, 0x57, 0x49, 0x61, 0x8b, 0xb3, + 0xc0, 0xa4, 0x74, 0x50, 0x4b, 0x5c, 0x75, 0x8b, 0x93, 0x90, 0x8b, 0x86, 0x7e, 0x75, 0x6d, 0x68, + 0x6a, 0x78, 0x8e, 0x9d, 0xa0, 0x96, 0x7d, 0x65, 0x5c, 0x66, 0x79, 0x8c, 0x94, 0x8a, 0x7c, 0x7a, + 0x7b, 0x82, 0x87, 0x84, 0x81, 0x7a, 0x74, 0x74, 0x73, 0x76, 0x7d, 0x87, 0x90, 0x91, 0x8f, 0x86, + 0x77, 0x69, 0x61, 0x64, 0x71, 0x83, 0x92, 0x99, 0x95, 0x88, 0x79, 0x6f, 0x71, 0x77, 0x7b, 0x7c, + 0x78, 0x78, 0x80, 0x86, 0x87, 0x83, 0x7d, 0x7c, 0x81, 0x84, 0x80, 0x7c, 0x7b, 0x7b, 0x7d, 0x7e, + 0x7e, 0x83, 0x88, 0x87, 0x82, 0x78, 0x74, 0x75, 0x7b, 0x89, 0x8c, 0x83, 0x7d, 0x7a, 0x7a, 0x80, + 0x83, 0x85, 0x85, 0x80, 0x7a, 0x74, 0x61, 0x3f, 0x2b, 0x51, 0xa5, 0xe5, 0xee, 0xcc, 0x8f, 0x47, + 0x26, 0x48, 0x8d, 0xbb, 0xc4, 0xb2, 0x92, 0x64, 0x43, 0x49, 0x68, 0x89, 0x97, 0x90, 0x82, 0x7a, + 0x71, 0x58, 0x4b, 0x5f, 0x81, 0x9a, 0xb6, 0xcf, 0xbb, 0x7a, 0x45, 0x3d, 0x4c, 0x66, 0x97, 0xcf, + 0xdc, 0xb4, 0x81, 0x5f, 0x4a, 0x41, 0x55, 0x84, 0xa2, 0xa3, 0xa3, 0x9e, 0x81, 0x5b, 0x4f, 0x5a, + 0x64, 0x75, 0x93, 0xab, 0xa5, 0x8d, 0x79, 0x6c, 0x62, 0x6e, 0x8c, 0xa3, 0xa2, 0x93, 0x86, 0x74, + 0x68, 0x6d, 0x82, 0x91, 0x8b, 0x81, 0x78, 0x67, 0x5f, 0x6b, 0x7d, 0x8a, 0x90, 0x95, 0x94, 0x87, + 0x77, 0x6f, 0x6b, 0x6c, 0x7e, 0x94, 0x9f, 0x9d, 0x8d, 0x7b, 0x69, 0x5d, 0x66, 0x7d, 0x8d, 0x90, + 0x8b, 0x84, 0x7e, 0x84, 0x8c, 0x8d, 0x84, 0x72, 0x69, 0x6d, 0x7a, 0x8a, 0x99, 0x9b, 0x8d, 0x7c, + 0x71, 0x6b, 0x6b, 0x76, 0x80, 0x82, 0x81, 0x80, 0x82, 0x83, 0x83, 0x81, 0x7c, 0x76, 0x77, 0x7d, + 0x83, 0x85, 0x84, 0x7a, 0x6b, 0x62, 0x67, 0x78, 0x94, 0xaf, 0xb8, 0xa4, 0x79, 0x4c, 0x38, 0x4a, + 0x79, 0xae, 0xc5, 0xb8, 0x8d, 0x61, 0x51, 0x5b, 0x71, 0x85, 0x87, 0x84, 0x83, 0x86, 0x8c, 0x87, + 0x76, 0x6c, 0x70, 0x7d, 0x92, 0xa0, 0x9c, 0x8c, 0x70, 0x58, 0x54, 0x66, 0x86, 0xa2, 0xb0, 0xa6, + 0x8b, 0x6d, 0x59, 0x59, 0x68, 0x7a, 0x8e, 0x9a, 0x99, 0x8b, 0x7c, 0x75, 0x71, 0x6f, 0x71, 0x77, + 0x79, 0x7c, 0x83, 0x85, 0x83, 0x80, 0x84, 0x89, 0x89, 0x85, 0x7a, 0x6c, 0x63, 0x64, 0x72, 0x87, + 0x98, 0xa3, 0xa2, 0x90, 0x75, 0x5e, 0x56, 0x62, 0x78, 0x92, 0xa0, 0x9e, 0x92, 0x7b, 0x65, 0x5d, + 0x5e, 0x6a, 0x7c, 0x92, 0x9d, 0x97, 0x8a, 0x80, 0x77, 0x78, 0x87, 0x93, 0x8d, 0x78, 0x5f, 0x4e, + 0x52, 0x60, 0x5e, 0x56, 0x73, 0xb5, 0xe4, 0xd9, 0xb9, 0x87, 0x42, 0x22, 0x4d, 0xa4, 0xd3, 0xd5, + 0xc9, 0x9f, 0x52, 0x1a, 0x27, 0x59, 0x85, 0x99, 0x9d, 0x95, 0x82, 0x68, 0x55, 0x5d, 0x71, 0x78, + 0x87, 0xa9, 0xc2, 0xaa, 0x78, 0x62, 0x5f, 0x50, 0x5b, 0x97, 0xc7, 0xc0, 0xa1, 0x8c, 0x6c, 0x45, + 0x40, 0x68, 0x91, 0x98, 0x95, 0x97, 0x82, 0x58, 0x45, 0x57, 0x6a, 0x7b, 0x96, 0xa8, 0xa0, 0x86, + 0x74, 0x6d, 0x6d, 0x76, 0x89, 0x9d, 0xa2, 0x97, 0x89, 0x77, 0x66, 0x61, 0x70, 0x85, 0x95, 0x9b, + 0x94, 0x82, 0x67, 0x58, 0x59, 0x69, 0x7e, 0x93, 0x9c, 0x96, 0x89, 0x7d, 0x78, 0x77, 0x7b, 0x84, + 0x8a, 0x86, 0x7d, 0x74, 0x69, 0x63, 0x6f, 0x89, 0x9e, 0xa7, 0x9d, 0x83, 0x5e, 0x41, 0x41, 0x61, + 0x95, 0xc1, 0xd7, 0xc4, 0x8b, 0x49, 0x22, 0x28, 0x5b, 0x9d, 0xcf, 0xda, 0xba, 0x86, 0x55, 0x3c, + 0x42, 0x5d, 0x85, 0xa9, 0xb9, 0xb3, 0x98, 0x73, 0x57, 0x46, 0x45, 0x53, 0x6b, 0x8e, 0xb5, 0xce, + 0xcd, 0xa9, 0x68, 0x2a, 0x1f, 0x52, 0xa0, 0xde, 0xe5, 0xb4, 0x6d, 0x3a, 0x37, 0x55, 0x75, 0x8f, + 0x9d, 0xa1, 0x97, 0x7e, 0x67, 0x5b, 0x5f, 0x6f, 0x83, 0x91, 0x9e, 0xa7, 0x9d, 0x7d, 0x5a, 0x4c, + 0x5a, 0x7e, 0xa9, 0xbf, 0xb8, 0x9c, 0x75, 0x56, 0x49, 0x51, 0x6f, 0x99, 0xb1, 0xb0, 0x9d, 0x82, + 0x68, 0x5b, 0x5e, 0x6c, 0x7c, 0x8a, 0x92, 0x8f, 0x7c, 0x6c, 0x68, 0x6f, 0x7c, 0x8f, 0x9c, 0x9b, + 0x90, 0x81, 0x72, 0x66, 0x65, 0x74, 0x89, 0x93, 0x8e, 0x86, 0x7c, 0x79, 0x78, 0x79, 0x84, 0x8f, + 0x95, 0x8f, 0x7e, 0x6f, 0x6b, 0x6c, 0x70, 0x7d, 0x8f, 0x9a, 0x99, 0x91, 0x87, 0x7a, 0x74, 0x6f, + 0x68, 0x5c, 0x53, 0x56, 0x55, 0x4e, 0x5f, 0x9b, 0xd7, 0xe9, 0xcf, 0x99, 0x56, 0x2b, 0x3d, 0x85, + 0xc3, 0xd5, 0xcb, 0xae, 0x72, 0x33, 0x23, 0x44, 0x6f, 0x8e, 0x9e, 0xa1, 0x91, 0x75, 0x5c, 0x55, + 0x59, 0x5f, 0x72, 0x96, 0xb9, 0xb9, 0x9a, 0x80, 0x6d, 0x57, 0x4f, 0x73, 0xa3, 0xb2, 0xaa, 0x9e, + 0x89, 0x62, 0x4c, 0x5c, 0x7a, 0x86, 0x89, 0x92, 0x89, 0x6c, 0x5a, 0x61, 0x6b, 0x6f, 0x82, 0x9c, + 0xa4, 0x98, 0x87, 0x7a, 0x6b, 0x60, 0x6d, 0x8c, 0x9d, 0xa1, 0x9f, 0x91, 0x79, 0x65, 0x63, 0x6e, + 0x7a, 0x86, 0x90, 0x8c, 0x7b, 0x6f, 0x6a, 0x68, 0x6c, 0x7b, 0x8d, 0x93, 0x8f, 0x88, 0x7b, 0x6f, + 0x6e, 0x7b, 0x8d, 0x94, 0x92, 0x88, 0x77, 0x6c, 0x6c, 0x76, 0x7d, 0x83, 0x83, 0x82, 0x80, 0x7c, + 0x7c, 0x7d, 0x80, 0x82, 0x86, 0x88, 0x84, 0x81, 0x7d, 0x79, 0x79, 0x7d, 0x88, 0x93, 0x95, 0x8e, + 0x80, 0x72, 0x6b, 0x6b, 0x6f, 0x71, 0x6d, 0x71, 0x84, 0x9f, 0xb4, 0xac, 0x86, 0x56, 0x3d, 0x4b, + 0x7e, 0xac, 0xbe, 0xb4, 0x94, 0x73, 0x5c, 0x54, 0x5b, 0x6e, 0x8b, 0x9f, 0xa2, 0x98, 0x88, 0x76, + 0x6a, 0x5e, 0x5b, 0x66, 0x7d, 0x98, 0xa7, 0xa2, 0x8b, 0x71, 0x60, 0x61, 0x6f, 0x80, 0x8c, 0x93, + 0x8f, 0x7e, 0x72, 0x72, 0x79, 0x82, 0x8c, 0x93, 0x8a, 0x78, 0x71, 0x6f, 0x6b, 0x6b, 0x7a, 0x8d, + 0x93, 0x90, 0x86, 0x78, 0x68, 0x65, 0x71, 0x80, 0x87, 0x8e, 0x91, 0x8a, 0x7e, 0x7c, 0x81, 0x85, + 0x8b, 0x8f, 0x8d, 0x83, 0x7b, 0x76, 0x72, 0x71, 0x76, 0x7c, 0x80, 0x83, 0x84, 0x7e, 0x74, 0x75, + 0x7a, 0x79, 0x75, 0x7e, 0x90, 0x9c, 0x9d, 0x91, 0x7c, 0x67, 0x5d, 0x61, 0x60, 0x51, 0x4b, 0x73, + 0xbb, 0xe5, 0xdc, 0xb0, 0x6a, 0x29, 0x1a, 0x49, 0x98, 0xc8, 0xd1, 0xc2, 0x90, 0x53, 0x2b, 0x34, + 0x5e, 0x83, 0x9a, 0xa1, 0x9e, 0x8f, 0x73, 0x60, 0x5d, 0x66, 0x6d, 0x81, 0xa9, 0xc3, 0xb0, 0x86, + 0x68, 0x54, 0x3f, 0x4c, 0x88, 0xbb, 0xbd, 0xa9, 0x96, 0x72, 0x47, 0x42, 0x6b, 0x8a, 0x8a, 0x92, + 0xa1, 0x8d, 0x66, 0x5b, 0x67, 0x67, 0x67, 0x84, 0xa3, 0xa1, 0x90, 0x89, 0x7c, 0x62, 0x5e, 0x76, + 0x8f, 0x98, 0x9a, 0x99, 0x88, 0x6f, 0x66, 0x6b, 0x6f, 0x75, 0x87, 0x94, 0x8f, 0x87, 0x82, 0x77, + 0x69, 0x68, 0x75, 0x83, 0x8a, 0x8d, 0x8b, 0x82, 0x78, 0x7b, 0x86, 0x8c, 0x89, 0x82, 0x76, 0x6a, + 0x67, 0x74, 0x89, 0x96, 0x95, 0x89, 0x76, 0x67, 0x62, 0x6b, 0x7b, 0x89, 0x8f, 0x90, 0x8f, 0x90, + 0x96, 0x99, 0x8f, 0x80, 0x70, 0x64, 0x60, 0x5e, 0x63, 0x6e, 0x7a, 0x92, 0xac, 0xb7, 0xad, 0x8d, + 0x68, 0x50, 0x4d, 0x61, 0x7c, 0x91, 0x9d, 0x9d, 0x95, 0x88, 0x79, 0x70, 0x71, 0x76, 0x7c, 0x7e, + 0x7c, 0x7d, 0x7d, 0x7b, 0x79, 0x79, 0x7b, 0x81, 0x88, 0x8c, 0x8d, 0x83, 0x74, 0x6d, 0x6b, 0x71, + 0x7d, 0x8b, 0x95, 0x92, 0x88, 0x7c, 0x6e, 0x66, 0x6b, 0x7a, 0x8c, 0x99, 0x9f, 0x99, 0x85, 0x6e, + 0x5d, 0x59, 0x64, 0x79, 0x8d, 0x95, 0x91, 0x87, 0x7b, 0x76, 0x76, 0x7e, 0x87, 0x88, 0x86, 0x7e, + 0x79, 0x74, 0x73, 0x79, 0x87, 0x95, 0x98, 0x92, 0x86, 0x79, 0x6e, 0x66, 0x69, 0x72, 0x84, 0x92, + 0x97, 0x92, 0x84, 0x73, 0x68, 0x68, 0x74, 0x86, 0x94, 0x96, 0x92, 0x85, 0x6a, 0x40, 0x22, 0x3c, + 0x8c, 0xd5, 0xf1, 0xdd, 0x9e, 0x53, 0x24, 0x30, 0x68, 0xa3, 0xc6, 0xc8, 0xa7, 0x74, 0x4a, 0x3b, + 0x45, 0x5e, 0x81, 0x9c, 0xae, 0xaf, 0x9e, 0x7e, 0x5b, 0x45, 0x43, 0x56, 0x81, 0xb7, 0xd4, 0xc1, + 0x9a, 0x72, 0x50, 0x40, 0x51, 0x7d, 0x9d, 0xa4, 0xa2, 0x95, 0x7c, 0x63, 0x62, 0x70, 0x79, 0x83, + 0x93, 0x99, 0x8d, 0x78, 0x6e, 0x68, 0x5d, 0x60, 0x78, 0x96, 0xa1, 0xa3, 0x9f, 0x8b, 0x6f, 0x5f, + 0x66, 0x77, 0x8a, 0x9c, 0xa1, 0x93, 0x7e, 0x6e, 0x6b, 0x6c, 0x75, 0x86, 0x91, 0x92, 0x8a, 0x7b, + 0x6d, 0x63, 0x61, 0x6f, 0x86, 0x99, 0xa4, 0xa4, 0x98, 0x7d, 0x66, 0x5d, 0x5d, 0x6b, 0x81, 0x92, + 0x99, 0x92, 0x85, 0x7a, 0x77, 0x7b, 0x86, 0x8d, 0x8c, 0x86, 0x81, 0x7a, 0x78, 0x7a, 0x81, 0x86, + 0x8b, 0x8d, 0x8a, 0x7c, 0x69, 0x59, 0x59, 0x72, 0x96, 0xb3, 0xb6, 0x9b, 0x73, 0x55, 0x55, 0x6e, + 0x8c, 0x9a, 0x95, 0x86, 0x78, 0x75, 0x77, 0x79, 0x7c, 0x82, 0x85, 0x86, 0x86, 0x87, 0x83, 0x7c, + 0x71, 0x67, 0x69, 0x75, 0x89, 0x9a, 0x9c, 0x8f, 0x7a, 0x69, 0x65, 0x6e, 0x7e, 0x8c, 0x91, 0x8b, + 0x82, 0x7b, 0x7b, 0x7a, 0x7b, 0x7d, 0x7c, 0x78, 0x77, 0x79, 0x84, 0x89, 0x85, 0x7c, 0x6f, 0x68, + 0x6e, 0x80, 0x93, 0x9d, 0x98, 0x89, 0x73, 0x65, 0x66, 0x70, 0x7d, 0x8b, 0x93, 0x91, 0x89, 0x81, + 0x7d, 0x79, 0x77, 0x78, 0x7b, 0x7e, 0x83, 0x88, 0x8b, 0x87, 0x83, 0x80, 0x7b, 0x78, 0x74, 0x73, + 0x73, 0x77, 0x7e, 0x8d, 0x9b, 0xa1, 0x97, 0x77, 0x4a, 0x28, 0x32, 0x6f, 0xc3, 0xf7, 0xee, 0xb2, + 0x63, 0x2f, 0x2b, 0x4e, 0x7e, 0xa6, 0xb8, 0xaf, 0x95, 0x7a, 0x6d, 0x67, 0x5f, 0x5e, 0x6a, 0x7e, + 0x90, 0x99, 0x97, 0x84, 0x67, 0x53, 0x56, 0x74, 0x99, 0xb6, 0xbc, 0xa0, 0x74, 0x50, 0x4a, 0x5a, + 0x77, 0x98, 0xaf, 0xb0, 0x9c, 0x87, 0x73, 0x63, 0x56, 0x57, 0x68, 0x82, 0x99, 0xa9, 0xa9, 0x95, + 0x74, 0x59, 0x4c, 0x52, 0x6b, 0x8e, 0xa6, 0xa8, 0x9b, 0x85, 0x72, 0x66, 0x65, 0x6f, 0x83, 0x95, + 0xa0, 0xa2, 0x96, 0x83, 0x6f, 0x64, 0x66, 0x73, 0x87, 0x92, 0x92, 0x85, 0x74, 0x69, 0x68, 0x74, + 0x88, 0x98, 0x9c, 0x95, 0x86, 0x75, 0x6c, 0x68, 0x69, 0x73, 0x7e, 0x89, 0x8f, 0x92, 0x92, 0x8e, + 0x87, 0x78, 0x70, 0x6b, 0x71, 0x80, 0x93, 0x9e, 0x94, 0x77, 0x58, 0x54, 0x72, 0xa0, 0xc0, 0xb3, + 0x83, 0x4c, 0x35, 0x50, 0x85, 0xb1, 0xbd, 0xa6, 0x7c, 0x60, 0x61, 0x6c, 0x76, 0x79, 0x74, 0x72, + 0x7d, 0x92, 0xa2, 0xa1, 0x8b, 0x68, 0x51, 0x52, 0x6b, 0x91, 0xad, 0xb2, 0x9e, 0x7e, 0x65, 0x5e, + 0x69, 0x7b, 0x88, 0x8a, 0x86, 0x84, 0x86, 0x8a, 0x8a, 0x82, 0x74, 0x6d, 0x70, 0x7d, 0x8e, 0x94, + 0x8d, 0x7c, 0x6c, 0x69, 0x70, 0x7c, 0x8c, 0x90, 0x8b, 0x81, 0x77, 0x72, 0x71, 0x77, 0x80, 0x83, + 0x83, 0x84, 0x87, 0x89, 0x89, 0x86, 0x7b, 0x73, 0x71, 0x74, 0x7d, 0x86, 0x8a, 0x88, 0x84, 0x84, + 0x80, 0x7a, 0x74, 0x73, 0x76, 0x79, 0x80, 0x8a, 0x92, 0x94, 0x8e, 0x81, 0x67, 0x45, 0x2b, 0x35, + 0x6d, 0xb5, 0xe1, 0xdf, 0xb9, 0x77, 0x38, 0x25, 0x4c, 0x8b, 0xb6, 0xc7, 0xbf, 0xa1, 0x74, 0x59, + 0x54, 0x54, 0x57, 0x67, 0x86, 0x9f, 0xa8, 0xa8, 0x9a, 0x77, 0x4f, 0x3e, 0x4d, 0x6b, 0x8c, 0xab, + 0xb8, 0xa2, 0x7d, 0x66, 0x5b, 0x5a, 0x64, 0x7c, 0x8e, 0x91, 0x96, 0x9d, 0x98, 0x88, 0x78, 0x6b, + 0x63, 0x66, 0x76, 0x8e, 0x99, 0x96, 0x8e, 0x82, 0x71, 0x6a, 0x6b, 0x73, 0x7a, 0x82, 0x8b, 0x8d, + 0x89, 0x82, 0x7a, 0x74, 0x72, 0x78, 0x82, 0x8c, 0x90, 0x91, 0x8b, 0x80, 0x73, 0x6b, 0x6a, 0x72, + 0x83, 0x91, 0x9d, 0x9e, 0x91, 0x7b, 0x66, 0x5e, 0x60, 0x6b, 0x80, 0x96, 0xa3, 0x9f, 0x8e, 0x7a, + 0x6b, 0x66, 0x66, 0x6e, 0x7b, 0x8b, 0x98, 0x9c, 0x99, 0x8e, 0x81, 0x6d, 0x55, 0x4b, 0x57, 0x81, + 0xaf, 0xc9, 0xc3, 0x98, 0x61, 0x3d, 0x41, 0x68, 0x94, 0xae, 0xad, 0x97, 0x7d, 0x70, 0x70, 0x74, + 0x77, 0x77, 0x77, 0x7a, 0x82, 0x8e, 0x93, 0x8f, 0x83, 0x72, 0x66, 0x66, 0x73, 0x89, 0x9a, 0x9d, + 0x92, 0x7e, 0x6b, 0x5f, 0x62, 0x72, 0x84, 0x90, 0x91, 0x8b, 0x87, 0x86, 0x87, 0x86, 0x7d, 0x72, + 0x6a, 0x6d, 0x78, 0x89, 0x94, 0x98, 0x94, 0x87, 0x77, 0x6b, 0x67, 0x6e, 0x76, 0x7e, 0x87, 0x8c, + 0x8c, 0x87, 0x82, 0x7d, 0x76, 0x70, 0x6e, 0x75, 0x80, 0x88, 0x8c, 0x8a, 0x85, 0x7e, 0x7a, 0x75, + 0x77, 0x7c, 0x82, 0x83, 0x82, 0x7e, 0x7a, 0x77, 0x78, 0x7c, 0x7e, 0x82, 0x86, 0x8a, 0x88, 0x7e, + 0x71, 0x65, 0x62, 0x67, 0x75, 0x88, 0x94, 0x92, 0x82, 0x72, 0x6d, 0x74, 0x85, 0x97, 0x99, 0x8a, + 0x77, 0x6d, 0x73, 0x7e, 0x8f, 0x97, 0x8b, 0x73, 0x63, 0x65, 0x75, 0x8a, 0x9b, 0x9c, 0x90, 0x7e, + 0x73, 0x72, 0x78, 0x86, 0x8d, 0x86, 0x78, 0x74, 0x74, 0x78, 0x83, 0x89, 0x85, 0x7c, 0x79, 0x7e, + 0x85, 0x89, 0x8e, 0x89, 0x7b, 0x74, 0x71, 0x73, 0x77, 0x82, 0x8a, 0x86, 0x7c, 0x77, 0x75, 0x73, + 0x75, 0x7e, 0x88, 0x88, 0x86, 0x86, 0x83, 0x7e, 0x7c, 0x7a, 0x75, 0x75, 0x7c, 0x86, 0x8b, 0x8a, + 0x8a, 0x87, 0x7c, 0x74, 0x71, 0x77, 0x83, 0x8c, 0x90, 0x8b, 0x81, 0x75, 0x71, 0x72, 0x76, 0x80, + 0x84, 0x84, 0x80, 0x7d, 0x7d, 0x7c, 0x80, 0x83, 0x86, 0x88, 0x82, 0x7a, 0x6e, 0x67, 0x67, 0x6d, + 0x7e, 0x8d, 0x93, 0x8d, 0x82, 0x77, 0x72, 0x78, 0x85, 0x90, 0x8f, 0x82, 0x75, 0x6d, 0x73, 0x83, + 0x91, 0x96, 0x8a, 0x7c, 0x76, 0x76, 0x80, 0x88, 0x88, 0x83, 0x7c, 0x7a, 0x7d, 0x86, 0x90, 0x93, + 0x88, 0x76, 0x67, 0x61, 0x66, 0x74, 0x85, 0x91, 0x96, 0x93, 0x89, 0x82, 0x7d, 0x7c, 0x7a, 0x74, + 0x6f, 0x71, 0x78, 0x86, 0x91, 0x95, 0x91, 0x86, 0x7a, 0x73, 0x73, 0x77, 0x7a, 0x7c, 0x7c, 0x7b, + 0x7d, 0x83, 0x8b, 0x90, 0x8f, 0x8a, 0x81, 0x78, 0x75, 0x78, 0x7c, 0x80, 0x81, 0x80, 0x83, 0x86, + 0x8b, 0x8d, 0x89, 0x82, 0x78, 0x72, 0x6f, 0x71, 0x78, 0x83, 0x8a, 0x8d, 0x8b, 0x82, 0x76, 0x69, + 0x65, 0x6b, 0x76, 0x85, 0x8d, 0x89, 0x81, 0x7b, 0x79, 0x7b, 0x85, 0x8d, 0x8d, 0x84, 0x79, 0x73, + 0x71, 0x74, 0x7e, 0x85, 0x81, 0x7a, 0x7c, 0x85, 0x8e, 0x94, 0x94, 0x8b, 0x77, 0x69, 0x6a, 0x77, + 0x86, 0x8e, 0x8f, 0x86, 0x76, 0x6f, 0x79, 0x85, 0x88, 0x87, 0x81, 0x73, 0x6d, 0x75, 0x83, 0x89, + 0x8b, 0x8c, 0x87, 0x7d, 0x7b, 0x83, 0x84, 0x7c, 0x75, 0x71, 0x6e, 0x71, 0x83, 0x95, 0x95, 0x8d, + 0x84, 0x79, 0x71, 0x6f, 0x77, 0x81, 0x84, 0x84, 0x85, 0x82, 0x81, 0x88, 0x8c, 0x86, 0x7c, 0x77, + 0x77, 0x79, 0x82, 0x8d, 0x92, 0x8b, 0x82, 0x7b, 0x76, 0x76, 0x7c, 0x80, 0x7e, 0x7b, 0x78, 0x7a, + 0x7d, 0x84, 0x89, 0x87, 0x7e, 0x78, 0x78, 0x79, 0x7d, 0x83, 0x83, 0x7c, 0x73, 0x6e, 0x75, 0x82, + 0x8e, 0x91, 0x88, 0x79, 0x6e, 0x6d, 0x77, 0x84, 0x8c, 0x8c, 0x86, 0x7e, 0x7c, 0x82, 0x88, 0x89, + 0x80, 0x74, 0x6b, 0x6d, 0x7a, 0x8d, 0x97, 0x94, 0x8b, 0x7e, 0x73, 0x76, 0x80, 0x8b, 0x8e, 0x88, + 0x7c, 0x73, 0x70, 0x73, 0x7a, 0x82, 0x84, 0x81, 0x7c, 0x7d, 0x84, 0x8a, 0x8a, 0x85, 0x7a, 0x74, + 0x75, 0x79, 0x82, 0x8a, 0x8e, 0x88, 0x7d, 0x77, 0x77, 0x79, 0x7e, 0x82, 0x7e, 0x7b, 0x7d, 0x84, + 0x8b, 0x8e, 0x8d, 0x87, 0x7d, 0x77, 0x78, 0x80, 0x85, 0x87, 0x85, 0x7e, 0x78, 0x76, 0x7d, 0x85, + 0x89, 0x87, 0x81, 0x79, 0x73, 0x76, 0x7d, 0x86, 0x8a, 0x88, 0x80, 0x70, 0x68, 0x6d, 0x77, 0x82, + 0x89, 0x8c, 0x85, 0x79, 0x73, 0x76, 0x7e, 0x89, 0x94, 0x91, 0x81, 0x73, 0x6a, 0x67, 0x6d, 0x7c, + 0x87, 0x88, 0x84, 0x81, 0x82, 0x84, 0x89, 0x8a, 0x83, 0x77, 0x6e, 0x6e, 0x7a, 0x8b, 0x94, 0x95, + 0x8e, 0x7b, 0x6e, 0x6f, 0x7a, 0x83, 0x86, 0x85, 0x7d, 0x75, 0x79, 0x85, 0x89, 0x88, 0x83, 0x77, + 0x6c, 0x68, 0x73, 0x82, 0x89, 0x8c, 0x8c, 0x86, 0x7d, 0x7e, 0x84, 0x81, 0x79, 0x77, 0x76, 0x73, + 0x79, 0x87, 0x8c, 0x85, 0x7c, 0x78, 0x72, 0x70, 0x7c, 0x89, 0x8e, 0x8b, 0x84, 0x7c, 0x77, 0x7a, + 0x85, 0x8a, 0x88, 0x84, 0x7d, 0x77, 0x74, 0x79, 0x7e, 0x80, 0x7e, 0x7d, 0x7d, 0x7e, 0x83, 0x87, + 0x85, 0x80, 0x7a, 0x7a, 0x7d, 0x84, 0x86, 0x82, 0x7b, 0x75, 0x76, 0x7a, 0x7d, 0x81, 0x82, 0x81, + 0x7c, 0x7b, 0x80, 0x85, 0x87, 0x83, 0x7a, 0x71, 0x71, 0x77, 0x80, 0x86, 0x87, 0x85, 0x7e, 0x79, + 0x7a, 0x7e, 0x83, 0x83, 0x80, 0x7a, 0x75, 0x75, 0x7e, 0x8b, 0x90, 0x8d, 0x83, 0x75, 0x70, 0x72, + 0x7c, 0x86, 0x8b, 0x89, 0x83, 0x7d, 0x7b, 0x80, 0x80, 0x7a, 0x73, 0x71, 0x75, 0x7c, 0x86, 0x8d, + 0x8e, 0x88, 0x7e, 0x76, 0x6f, 0x6f, 0x73, 0x79, 0x81, 0x84, 0x85, 0x85, 0x84, 0x84, 0x84, 0x7e, + 0x76, 0x72, 0x73, 0x79, 0x82, 0x8a, 0x8d, 0x8b, 0x85, 0x81, 0x7e, 0x7e, 0x81, 0x81, 0x7b, 0x75, + 0x76, 0x7b, 0x83, 0x8e, 0x93, 0x93, 0x8e, 0x84, 0x7b, 0x73, 0x70, 0x71, 0x73, 0x76, 0x79, 0x7d, + 0x81, 0x81, 0x81, 0x82, 0x81, 0x82, 0x87, 0x86, 0x81, 0x7b, 0x76, 0x74, 0x75, 0x7b, 0x83, 0x84, + 0x83, 0x7d, 0x7a, 0x7c, 0x80, 0x81, 0x80, 0x7e, 0x7b, 0x7b, 0x80, 0x85, 0x89, 0x8b, 0x88, 0x7e, + 0x79, 0x78, 0x7a, 0x7e, 0x81, 0x84, 0x82, 0x7b, 0x7a, 0x7b, 0x80, 0x83, 0x84, 0x82, 0x7c, 0x7b, + 0x7e, 0x84, 0x85, 0x83, 0x7d, 0x76, 0x71, 0x75, 0x7d, 0x83, 0x86, 0x86, 0x84, 0x82, 0x81, 0x81, + 0x7c, 0x76, 0x73, 0x72, 0x73, 0x79, 0x84, 0x8c, 0x8e, 0x8a, 0x81, 0x79, 0x75, 0x78, 0x80, 0x86, + 0x88, 0x85, 0x7c, 0x74, 0x75, 0x7a, 0x81, 0x85, 0x85, 0x81, 0x7e, 0x83, 0x88, 0x87, 0x84, 0x7c, + 0x70, 0x64, 0x64, 0x75, 0x90, 0x9e, 0x9d, 0x94, 0x89, 0x82, 0x74, 0x5f, 0x5b, 0x72, 0x94, 0x96, + 0x7b, 0x6b, 0x78, 0x92, 0x97, 0x89, 0x77, 0x6d, 0x6f, 0x77, 0x8a, 0xa2, 0xad, 0x97, 0x6c, 0x4d, + 0x4e, 0x69, 0x8b, 0xa2, 0xa6, 0x95, 0x7a, 0x68, 0x69, 0x7b, 0x8a, 0x86, 0x79, 0x74, 0x78, 0x84, + 0x8f, 0x94, 0x8c, 0x74, 0x5f, 0x60, 0x74, 0x93, 0xa2, 0x9a, 0x87, 0x71, 0x64, 0x63, 0x70, 0x84, + 0x8e, 0x88, 0x7a, 0x76, 0x7c, 0x86, 0x8c, 0x8a, 0x82, 0x77, 0x70, 0x76, 0x84, 0x8c, 0x85, 0x72, + 0x64, 0x6b, 0x84, 0x97, 0x9b, 0x90, 0x83, 0x81, 0x7c, 0x74, 0x6f, 0x79, 0x88, 0x8a, 0x83, 0x84, + 0x8d, 0x89, 0x67, 0x3c, 0x2f, 0x57, 0x9b, 0xce, 0xdf, 0xc9, 0x92, 0x4a, 0x19, 0x17, 0x48, 0x90, + 0xbf, 0xc5, 0xad, 0x91, 0x7d, 0x70, 0x66, 0x60, 0x5d, 0x67, 0x81, 0x9b, 0xba, 0xc9, 0xb2, 0x75, + 0x3a, 0x2c, 0x4a, 0x7c, 0xb4, 0xce, 0xc3, 0x97, 0x63, 0x46, 0x46, 0x5b, 0x74, 0x82, 0x86, 0x91, + 0x9b, 0x9a, 0x8f, 0x7c, 0x67, 0x56, 0x5b, 0x79, 0x97, 0xa5, 0x9e, 0x84, 0x65, 0x58, 0x63, 0x79, + 0x8f, 0x9c, 0x9c, 0x8f, 0x7c, 0x73, 0x6d, 0x6a, 0x6e, 0x76, 0x80, 0x88, 0x91, 0x94, 0x8c, 0x7e, + 0x71, 0x69, 0x6b, 0x77, 0x88, 0x94, 0x94, 0x8c, 0x80, 0x73, 0x70, 0x77, 0x7a, 0x7b, 0x7b, 0x7d, + 0x83, 0x87, 0x89, 0x85, 0x7a, 0x70, 0x6b, 0x72, 0x82, 0x91, 0x99, 0x96, 0x85, 0x65, 0x40, 0x37, + 0x58, 0x9b, 0xd2, 0xd5, 0xa5, 0x68, 0x42, 0x3f, 0x54, 0x6b, 0x8a, 0xa7, 0xb4, 0xa9, 0x90, 0x7a, + 0x72, 0x69, 0x58, 0x4f, 0x62, 0x94, 0xbd, 0xbf, 0x9c, 0x6f, 0x52, 0x46, 0x4a, 0x66, 0x96, 0xb8, + 0xb3, 0x8e, 0x6a, 0x60, 0x6b, 0x74, 0x70, 0x70, 0x7a, 0x89, 0x93, 0x93, 0x8f, 0x86, 0x73, 0x60, + 0x61, 0x7a, 0x98, 0xa4, 0x9b, 0x85, 0x71, 0x68, 0x6b, 0x78, 0x84, 0x89, 0x85, 0x7c, 0x7b, 0x84, + 0x8b, 0x87, 0x79, 0x6c, 0x65, 0x69, 0x78, 0x8e, 0x98, 0x92, 0x85, 0x75, 0x6f, 0x71, 0x7c, 0x87, + 0x8d, 0x8d, 0x86, 0x81, 0x7d, 0x7e, 0x80, 0x7e, 0x80, 0x85, 0x8c, 0x8e, 0x87, 0x6f, 0x45, 0x27, + 0x38, 0x77, 0xc1, 0xe1, 0xcc, 0x94, 0x58, 0x2f, 0x29, 0x51, 0x8f, 0xb9, 0xbe, 0xab, 0x94, 0x81, + 0x70, 0x65, 0x5d, 0x5f, 0x70, 0x93, 0xba, 0xc4, 0xae, 0x88, 0x58, 0x35, 0x38, 0x64, 0x99, 0xb5, + 0xb2, 0x99, 0x79, 0x5e, 0x54, 0x5f, 0x70, 0x81, 0x8e, 0x92, 0x8d, 0x88, 0x83, 0x78, 0x6c, 0x68, + 0x6d, 0x7c, 0x96, 0xac, 0xa8, 0x8f, 0x71, 0x60, 0x5e, 0x6c, 0x87, 0x9c, 0xa0, 0x97, 0x89, 0x79, + 0x6f, 0x6d, 0x72, 0x79, 0x7d, 0x83, 0x85, 0x84, 0x83, 0x80, 0x7a, 0x75, 0x77, 0x7e, 0x84, 0x87, + 0x86, 0x81, 0x7e, 0x82, 0x83, 0x82, 0x80, 0x7e, 0x7d, 0x7c, 0x7d, 0x82, 0x82, 0x81, 0x7d, 0x80, + 0x89, 0x91, 0x8e, 0x6f, 0x3d, 0x23, 0x47, 0x9b, 0xe2, 0xea, 0xb9, 0x75, 0x43, 0x2e, 0x36, 0x5c, + 0x95, 0xc0, 0xc1, 0xa2, 0x87, 0x82, 0x80, 0x6c, 0x50, 0x49, 0x69, 0x9a, 0xb9, 0xba, 0xa7, 0x85, + 0x5a, 0x3d, 0x46, 0x73, 0xa1, 0xb4, 0xa6, 0x85, 0x69, 0x5e, 0x60, 0x67, 0x74, 0x8a, 0x9b, 0x9d, + 0x93, 0x88, 0x79, 0x66, 0x58, 0x5c, 0x75, 0x9a, 0xb4, 0xb4, 0x9b, 0x7a, 0x60, 0x56, 0x5e, 0x78, + 0x94, 0xa0, 0x9c, 0x8b, 0x79, 0x6c, 0x69, 0x6e, 0x76, 0x80, 0x8c, 0x94, 0x8e, 0x83, 0x75, 0x6b, + 0x6b, 0x76, 0x8a, 0x99, 0x9c, 0x94, 0x81, 0x6c, 0x63, 0x67, 0x76, 0x89, 0x95, 0x96, 0x8d, 0x86, + 0x7c, 0x75, 0x70, 0x71, 0x76, 0x82, 0x93, 0xa1, 0x9a, 0x72, 0x3d, 0x29, 0x51, 0xa2, 0xe2, 0xe7, + 0xa9, 0x4e, 0x1d, 0x2d, 0x64, 0x9d, 0xb4, 0xab, 0x9a, 0x8e, 0x86, 0x7e, 0x72, 0x65, 0x58, 0x57, + 0x6d, 0x95, 0xbc, 0xc6, 0xa5, 0x6a, 0x3a, 0x34, 0x59, 0x8d, 0xae, 0xb0, 0x9c, 0x81, 0x6a, 0x61, + 0x67, 0x77, 0x83, 0x85, 0x84, 0x87, 0x92, 0x95, 0x88, 0x71, 0x60, 0x63, 0x7b, 0x96, 0xa5, 0xa3, + 0x8e, 0x70, 0x5c, 0x5a, 0x6b, 0x86, 0x9a, 0x9e, 0x92, 0x84, 0x77, 0x70, 0x6d, 0x6c, 0x70, 0x77, + 0x83, 0x8e, 0x91, 0x8c, 0x83, 0x76, 0x71, 0x76, 0x83, 0x90, 0x94, 0x8f, 0x84, 0x78, 0x71, 0x72, + 0x78, 0x82, 0x8b, 0x8c, 0x87, 0x7d, 0x73, 0x63, 0x4f, 0x4a, 0x65, 0x94, 0xba, 0xc1, 0xab, 0x85, + 0x58, 0x3f, 0x49, 0x6b, 0x91, 0xae, 0xb7, 0xa8, 0x8c, 0x76, 0x6e, 0x69, 0x65, 0x6f, 0x85, 0x99, + 0xa5, 0xa1, 0x8e, 0x6f, 0x54, 0x4d, 0x5c, 0x7b, 0x9d, 0xae, 0xa8, 0x8e, 0x6f, 0x5a, 0x53, 0x5c, + 0x72, 0x86, 0x94, 0x9b, 0x98, 0x8b, 0x7a, 0x71, 0x6e, 0x6f, 0x79, 0x8a, 0x99, 0x9e, 0x94, 0x82, + 0x70, 0x66, 0x69, 0x75, 0x88, 0x97, 0x9d, 0x94, 0x82, 0x71, 0x6a, 0x68, 0x6d, 0x79, 0x86, 0x8d, + 0x90, 0x8c, 0x83, 0x75, 0x6b, 0x69, 0x6f, 0x7d, 0x90, 0x9a, 0x9a, 0x8d, 0x77, 0x67, 0x64, 0x6f, + 0x81, 0x91, 0x9a, 0x94, 0x85, 0x76, 0x74, 0x7d, 0x84, 0x76, 0x55, 0x3a, 0x4d, 0x8f, 0xcf, 0xdd, + 0xb2, 0x73, 0x45, 0x36, 0x48, 0x70, 0xa5, 0xc4, 0xb8, 0x91, 0x71, 0x6f, 0x78, 0x75, 0x6b, 0x68, + 0x74, 0x8e, 0xa8, 0xae, 0x9b, 0x76, 0x54, 0x47, 0x54, 0x7b, 0xa8, 0xbe, 0xae, 0x84, 0x5f, 0x51, + 0x5a, 0x6a, 0x7a, 0x8b, 0x96, 0x9c, 0x9a, 0x8f, 0x7c, 0x68, 0x5a, 0x5c, 0x70, 0x91, 0xac, 0xb0, + 0x9d, 0x79, 0x5b, 0x53, 0x61, 0x78, 0x8e, 0x9b, 0x98, 0x8a, 0x7a, 0x71, 0x72, 0x76, 0x79, 0x7a, + 0x7e, 0x88, 0x8f, 0x90, 0x88, 0x7a, 0x71, 0x6f, 0x77, 0x85, 0x8c, 0x8b, 0x82, 0x75, 0x6e, 0x73, + 0x80, 0x8b, 0x91, 0x8e, 0x87, 0x82, 0x83, 0x80, 0x69, 0x44, 0x2e, 0x4a, 0x8f, 0xd4, 0xec, 0xc6, + 0x81, 0x45, 0x27, 0x30, 0x5c, 0x9a, 0xc7, 0xc5, 0xa5, 0x83, 0x71, 0x6d, 0x67, 0x61, 0x61, 0x75, + 0x97, 0xb7, 0xc0, 0xa8, 0x76, 0x48, 0x32, 0x40, 0x6f, 0xa7, 0xc6, 0xbf, 0x9d, 0x71, 0x54, 0x4f, + 0x5c, 0x6e, 0x7d, 0x8a, 0x95, 0x9b, 0x98, 0x8b, 0x77, 0x66, 0x60, 0x6a, 0x82, 0x9b, 0xab, 0xa7, + 0x8e, 0x6e, 0x5a, 0x5b, 0x6d, 0x89, 0x9f, 0xa3, 0x96, 0x81, 0x71, 0x6c, 0x6e, 0x76, 0x7d, 0x84, + 0x89, 0x8a, 0x87, 0x7d, 0x74, 0x6d, 0x6a, 0x74, 0x87, 0x97, 0x9d, 0x94, 0x85, 0x74, 0x69, 0x69, + 0x73, 0x82, 0x8b, 0x8d, 0x89, 0x83, 0x7d, 0x7b, 0x81, 0x85, 0x87, 0x81, 0x6e, 0x58, 0x53, 0x6e, + 0x9a, 0xb6, 0xac, 0x87, 0x65, 0x56, 0x59, 0x6f, 0x8a, 0x9e, 0xa3, 0x97, 0x85, 0x7a, 0x76, 0x75, + 0x73, 0x71, 0x71, 0x78, 0x89, 0x9a, 0xa0, 0x97, 0x82, 0x6b, 0x60, 0x65, 0x79, 0x90, 0x99, 0x94, + 0x87, 0x75, 0x6e, 0x72, 0x7b, 0x81, 0x81, 0x81, 0x83, 0x87, 0x88, 0x84, 0x7c, 0x76, 0x72, 0x74, + 0x7b, 0x84, 0x8c, 0x8d, 0x87, 0x7d, 0x77, 0x73, 0x77, 0x7d, 0x80, 0x7e, 0x7d, 0x7e, 0x81, 0x82, + 0x81, 0x80, 0x7d, 0x7c, 0x7c, 0x7e, 0x81, 0x84, 0x83, 0x81, 0x81, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, + 0x7c, 0x7e, 0x84, 0x86, 0x86, 0x83, 0x7d, 0x79, 0x77, 0x79, 0x7c, 0x80, 0x81, 0x81, 0x80, 0x7e, + 0x7e, 0x80, 0x81, 0x81, 0x7d, 0x7b, 0x7c, 0x7e, 0x80, 0x81, 0x81, 0x80, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7e, 0x7e, 0x80, 0x81, 0x83, 0x84, 0x84, 0x83, 0x82, 0x81, 0x7e, 0x7d, 0x7b, 0x7a, 0x7b, 0x7d, + 0x7e, 0x80, 0x82, 0x84, 0x84, 0x84, 0x84, 0x81, 0x7d, 0x7c, 0x7c, 0x7c, 0x7a, 0x7b, 0x80, 0x82, + 0x84, 0x86, 0x85, 0x82, 0x80, 0x80, 0x7e, 0x7c, 0x7b, 0x7b, 0x7b, 0x7c, 0x7e, 0x82, 0x84, 0x84, + 0x83, 0x80, 0x7d, 0x7d, 0x80, 0x81, 0x82, 0x82, 0x81, 0x81, 0x82, 0x81, 0x81, 0x80, 0x80, 0x7e, + 0x7e, 0x80, 0x80, 0x7d, 0x80, 0x80, 0x80, 0x80, 0x7d, 0x7c, 0x7a, 0x78, 0x7a, 0x7d, 0x82, 0x84, + 0x83, 0x7e, 0x7b, 0x7b, 0x7d, 0x80, 0x80, 0x7d, 0x7a, 0x79, 0x7a, 0x7d, 0x83, 0x86, 0x87, 0x86, + 0x81, 0x7c, 0x79, 0x78, 0x77, 0x78, 0x7b, 0x80, 0x84, 0x88, 0x89, 0x87, 0x83, 0x7e, 0x7a, 0x7a, + 0x7a, 0x7c, 0x80, 0x82, 0x83, 0x83, 0x83, 0x84, 0x82, 0x80, 0x7d, 0x7b, 0x7b, 0x7c, 0x7c, 0x7e, + 0x80, 0x83, 0x86, 0x86, 0x83, 0x81, 0x7d, 0x7b, 0x7b, 0x7b, 0x7d, 0x80, 0x81, 0x80, 0x7e, 0x80, + 0x82, 0x82, 0x82, 0x80, 0x7d, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7c, 0x7b, 0x7c, 0x80, 0x82, 0x81, + 0x82, 0x82, 0x83, 0x81, 0x7c, 0x7b, 0x7b, 0x7b, 0x7d, 0x7e, 0x82, 0x84, 0x85, 0x84, 0x83, 0x7e, + 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7e, 0x80, 0x81, 0x81, 0x80, 0x7c, 0x7a, 0x7a, 0x7d, 0x84, 0x88, + 0x8b, 0x88, 0x80, 0x78, 0x73, 0x72, 0x75, 0x78, 0x7c, 0x80, 0x83, 0x84, 0x85, 0x85, 0x85, 0x82, + 0x7d, 0x77, 0x75, 0x76, 0x7a, 0x80, 0x84, 0x86, 0x86, 0x86, 0x85, 0x83, 0x7e, 0x7b, 0x78, 0x76, + 0x78, 0x7b, 0x80, 0x83, 0x85, 0x84, 0x80, 0x7d, 0x7b, 0x7a, 0x7b, 0x7c, 0x7e, 0x82, 0x83, 0x84, + 0x84, 0x82, 0x7e, 0x7c, 0x7c, 0x7d, 0x80, 0x82, 0x83, 0x82, 0x80, 0x7d, 0x7c, 0x7c, 0x7d, 0x80, + 0x81, 0x81, 0x80, 0x7e, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7c, 0x7a, + 0x7b, 0x7e, 0x81, 0x82, 0x84, 0x83, 0x80, 0x7b, 0x78, 0x77, 0x79, 0x7b, 0x81, 0x88, 0x8b, 0x8a, + 0x86, 0x7d, 0x77, 0x75, 0x76, 0x7a, 0x7d, 0x81, 0x81, 0x81, 0x81, 0x82, 0x83, 0x83, 0x80, 0x7c, + 0x7c, 0x7d, 0x7d, 0x7e, 0x7b, 0x78, 0x76, 0x78, 0x7c, 0x82, 0x85, 0x83, 0x81, 0x7d, 0x79, 0x77, + 0x76, 0x76, 0x79, 0x7a, 0x7d, 0x81, 0x83, 0x85, 0x85, 0x83, 0x7e, 0x7b, 0x79, 0x79, 0x7b, 0x81, + 0x82, 0x82, 0x82, 0x80, 0x7d, 0x7b, 0x7b, 0x7e, 0x80, 0x80, 0x81, 0x82, 0x82, 0x81, 0x81, 0x7e, + 0x7b, 0x7c, 0x7e, 0x81, 0x82, 0x83, 0x80, 0x7b, 0x7a, 0x7c, 0x80, 0x83, 0x87, 0x87, 0x82, 0x7e, + 0x7c, 0x7c, 0x7e, 0x82, 0x84, 0x82, 0x81, 0x81, 0x81, 0x81, 0x80, 0x7e, 0x7c, 0x7a, 0x77, 0x76, + 0x77, 0x7a, 0x81, 0x85, 0x87, 0x87, 0x83, 0x7e, 0x7c, 0x7b, 0x7a, 0x7c, 0x7d, 0x7c, 0x7e, 0x83, + 0x87, 0x89, 0x87, 0x82, 0x7c, 0x79, 0x79, 0x7b, 0x84, 0x88, 0x87, 0x82, 0x7e, 0x7c, 0x7b, 0x7d, + 0x7e, 0x7e, 0x81, 0x82, 0x81, 0x82, 0x84, 0x83, 0x81, 0x7d, 0x7b, 0x7b, 0x7d, 0x82, 0x85, 0x85, + 0x83, 0x80, 0x80, 0x81, 0x82, 0x83, 0x80, 0x7a, 0x79, 0x7a, 0x7d, 0x81, 0x82, 0x80, 0x7b, 0x79, + 0x7b, 0x7d, 0x80, 0x82, 0x83, 0x81, 0x7e, 0x80, 0x80, 0x83, 0x83, 0x80, 0x7c, 0x79, 0x78, 0x7a, + 0x7e, 0x80, 0x81, 0x80, 0x80, 0x83, 0x84, 0x84, 0x84, 0x81, 0x7b, 0x76, 0x76, 0x78, 0x7c, 0x82, + 0x86, 0x87, 0x84, 0x81, 0x79, 0x74, 0x75, 0x79, 0x81, 0x86, 0x88, 0x83, 0x7c, 0x7a, 0x7d, 0x83, + 0x87, 0x86, 0x80, 0x79, 0x78, 0x7a, 0x7e, 0x83, 0x81, 0x7a, 0x76, 0x77, 0x7e, 0x89, 0x8f, 0x8d, + 0x85, 0x7c, 0x79, 0x7a, 0x80, 0x84, 0x83, 0x80, 0x7c, 0x7c, 0x80, 0x84, 0x85, 0x7e, 0x78, 0x74, + 0x76, 0x7e, 0x86, 0x8c, 0x8b, 0x82, 0x78, 0x78, 0x7c, 0x80, 0x83, 0x84, 0x7e, 0x79, 0x7a, 0x7d, + 0x81, 0x83, 0x82, 0x7c, 0x7c, 0x82, 0x87, 0x89, 0x86, 0x7e, 0x74, 0x6f, 0x72, 0x79, 0x7e, 0x82, + 0x82, 0x82, 0x84, 0x87, 0x89, 0x89, 0x85, 0x7e, 0x78, 0x77, 0x7a, 0x7e, 0x82, 0x82, 0x80, 0x7e, + 0x7e, 0x80, 0x7e, 0x76, 0x6e, 0x6b, 0x70, 0x7b, 0x85, 0x8d, 0x89, 0x80, 0x7a, 0x7c, 0x82, 0x86, + 0x87, 0x81, 0x77, 0x74, 0x79, 0x83, 0x8a, 0x8a, 0x80, 0x74, 0x70, 0x73, 0x80, 0x8c, 0x8f, 0x8a, + 0x85, 0x82, 0x83, 0x88, 0x89, 0x82, 0x76, 0x70, 0x70, 0x77, 0x86, 0x8f, 0x8d, 0x85, 0x7b, 0x77, + 0x79, 0x81, 0x86, 0x83, 0x7a, 0x76, 0x79, 0x82, 0x89, 0x8a, 0x84, 0x79, 0x72, 0x74, 0x7a, 0x82, + 0x87, 0x84, 0x7b, 0x78, 0x7d, 0x86, 0x8d, 0x8e, 0x87, 0x7d, 0x75, 0x75, 0x77, 0x7b, 0x7d, 0x7c, + 0x7b, 0x7e, 0x86, 0x8c, 0x8f, 0x8b, 0x81, 0x76, 0x72, 0x76, 0x7a, 0x7e, 0x80, 0x7e, 0x81, 0x82, + 0x86, 0x87, 0x82, 0x79, 0x6b, 0x64, 0x65, 0x72, 0x85, 0x8d, 0x8e, 0x87, 0x7b, 0x78, 0x7d, 0x84, + 0x84, 0x80, 0x77, 0x6f, 0x73, 0x7d, 0x89, 0x8e, 0x89, 0x7d, 0x74, 0x77, 0x80, 0x8c, 0x90, 0x8a, + 0x80, 0x79, 0x80, 0x87, 0x8c, 0x8c, 0x84, 0x77, 0x6f, 0x73, 0x7e, 0x88, 0x8a, 0x86, 0x7e, 0x78, + 0x7b, 0x84, 0x87, 0x83, 0x7a, 0x72, 0x70, 0x75, 0x80, 0x86, 0x82, 0x7d, 0x7a, 0x7a, 0x82, 0x88, + 0x89, 0x85, 0x7e, 0x7a, 0x79, 0x7d, 0x82, 0x81, 0x79, 0x75, 0x73, 0x77, 0x80, 0x86, 0x89, 0x87, + 0x84, 0x85, 0x84, 0x85, 0x83, 0x7e, 0x79, 0x75, 0x76, 0x78, 0x7b, 0x7e, 0x80, 0x81, 0x82, 0x83, + 0x82, 0x7a, 0x70, 0x68, 0x68, 0x72, 0x7e, 0x86, 0x86, 0x7e, 0x78, 0x7c, 0x85, 0x8e, 0x8f, 0x84, + 0x72, 0x65, 0x69, 0x76, 0x85, 0x8d, 0x88, 0x7b, 0x75, 0x7a, 0x85, 0x90, 0x91, 0x84, 0x76, 0x73, + 0x79, 0x84, 0x8e, 0x8e, 0x81, 0x74, 0x73, 0x79, 0x83, 0x88, 0x86, 0x7c, 0x75, 0x79, 0x84, 0x8b, + 0x8d, 0x85, 0x79, 0x71, 0x71, 0x79, 0x82, 0x82, 0x7d, 0x77, 0x74, 0x7b, 0x86, 0x87, 0x83, 0x7b, + 0x76, 0x75, 0x7d, 0x88, 0x8b, 0x85, 0x7c, 0x76, 0x75, 0x79, 0x83, 0x84, 0x81, 0x7e, 0x7d, 0x81, + 0x86, 0x8a, 0x88, 0x83, 0x7e, 0x7e, 0x81, 0x82, 0x82, 0x7e, 0x7a, 0x79, 0x7b, 0x84, 0x89, 0x86, + 0x7d, 0x6e, 0x64, 0x67, 0x75, 0x82, 0x88, 0x85, 0x7a, 0x75, 0x7b, 0x89, 0x91, 0x90, 0x87, 0x74, + 0x6a, 0x6e, 0x7a, 0x88, 0x8a, 0x82, 0x78, 0x75, 0x7d, 0x89, 0x92, 0x8f, 0x81, 0x74, 0x72, 0x7b, + 0x87, 0x8d, 0x8b, 0x7d, 0x74, 0x76, 0x80, 0x89, 0x8b, 0x85, 0x7b, 0x76, 0x78, 0x83, 0x89, 0x86, + 0x80, 0x7a, 0x78, 0x80, 0x89, 0x8b, 0x86, 0x7d, 0x76, 0x74, 0x78, 0x80, 0x82, 0x80, 0x80, 0x83, + 0x85, 0x89, 0x8d, 0x89, 0x7e, 0x78, 0x76, 0x78, 0x79, 0x7c, 0x80, 0x7e, 0x81, 0x86, 0x89, 0x89, + 0x88, 0x85, 0x81, 0x80, 0x81, 0x81, 0x7e, 0x7c, 0x7b, 0x7a, 0x7d, 0x83, 0x85, 0x81, 0x76, 0x6c, + 0x65, 0x6a, 0x77, 0x82, 0x87, 0x86, 0x7c, 0x77, 0x80, 0x8b, 0x91, 0x8e, 0x82, 0x73, 0x6b, 0x6f, + 0x7b, 0x85, 0x87, 0x80, 0x77, 0x78, 0x82, 0x8a, 0x90, 0x8a, 0x7b, 0x73, 0x76, 0x81, 0x8a, 0x8f, + 0x8b, 0x7e, 0x77, 0x78, 0x7c, 0x82, 0x82, 0x7c, 0x78, 0x78, 0x7e, 0x89, 0x8b, 0x88, 0x82, 0x7b, + 0x79, 0x7c, 0x81, 0x80, 0x7a, 0x77, 0x76, 0x78, 0x80, 0x86, 0x86, 0x83, 0x82, 0x82, 0x83, 0x85, + 0x84, 0x7c, 0x77, 0x78, 0x7a, 0x7e, 0x82, 0x82, 0x7c, 0x7a, 0x7b, 0x7d, 0x82, 0x84, 0x83, 0x83, + 0x84, 0x86, 0x88, 0x87, 0x82, 0x7d, 0x7b, 0x7b, 0x7e, 0x81, 0x81, 0x7e, 0x78, 0x6f, 0x6d, 0x73, + 0x7c, 0x85, 0x87, 0x82, 0x79, 0x77, 0x80, 0x89, 0x8e, 0x8c, 0x81, 0x73, 0x6e, 0x72, 0x7c, 0x83, + 0x81, 0x7b, 0x77, 0x7a, 0x85, 0x8e, 0x91, 0x89, 0x7c, 0x77, 0x79, 0x81, 0x8a, 0x8b, 0x85, 0x7b, + 0x79, 0x7d, 0x82, 0x84, 0x82, 0x7b, 0x75, 0x78, 0x81, 0x84, 0x86, 0x82, 0x7c, 0x79, 0x7c, 0x83, + 0x84, 0x7e, 0x7a, 0x77, 0x75, 0x7a, 0x81, 0x82, 0x80, 0x80, 0x7e, 0x7e, 0x82, 0x85, 0x84, 0x82, + 0x81, 0x80, 0x7e, 0x7d, 0x7b, 0x79, 0x78, 0x7b, 0x81, 0x85, 0x89, 0x88, 0x86, 0x84, 0x81, 0x81, + 0x81, 0x80, 0x81, 0x80, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7a, 0x74, 0x6e, 0x6d, 0x73, 0x7c, 0x85, + 0x88, 0x87, 0x83, 0x82, 0x84, 0x85, 0x83, 0x7a, 0x73, 0x70, 0x73, 0x7c, 0x83, 0x84, 0x80, 0x7b, + 0x7a, 0x7e, 0x84, 0x87, 0x84, 0x7c, 0x7a, 0x7c, 0x80, 0x85, 0x86, 0x85, 0x83, 0x83, 0x85, 0x84, + 0x80, 0x7b, 0x79, 0x78, 0x7c, 0x83, 0x85, 0x85, 0x83, 0x80, 0x7c, 0x7c, 0x7e, 0x7c, 0x7a, 0x7c, + 0x7e, 0x81, 0x83, 0x82, 0x80, 0x7d, 0x7d, 0x80, 0x7d, 0x7a, 0x7a, 0x7a, 0x7c, 0x81, 0x84, 0x84, + 0x81, 0x7d, 0x7a, 0x78, 0x79, 0x79, 0x7b, 0x80, 0x83, 0x87, 0x88, 0x87, 0x85, 0x82, 0x80, 0x7e, + 0x7d, 0x7c, 0x79, 0x76, 0x76, 0x7a, 0x7d, 0x7e, 0x7c, 0x74, 0x6e, 0x6f, 0x75, 0x7e, 0x85, 0x8a, + 0x8a, 0x86, 0x84, 0x81, 0x79, 0x76, 0x76, 0x76, 0x79, 0x7e, 0x80, 0x7e, 0x7d, 0x80, 0x81, 0x83, + 0x83, 0x7e, 0x7a, 0x76, 0x77, 0x7e, 0x85, 0x8a, 0x8d, 0x8b, 0x86, 0x7e, 0x79, 0x76, 0x76, 0x79, + 0x81, 0x84, 0x84, 0x84, 0x83, 0x83, 0x85, 0x8a, 0x89, 0x83, 0x7c, 0x78, 0x76, 0x77, 0x7b, 0x82, + 0x85, 0x86, 0x87, 0x83, 0x7c, 0x7a, 0x79, 0x79, 0x7b, 0x7e, 0x7d, 0x7d, 0x80, 0x83, 0x86, 0x88, + 0x87, 0x83, 0x7d, 0x7a, 0x79, 0x7a, 0x7d, 0x83, 0x85, 0x87, 0x86, 0x83, 0x81, 0x7e, 0x7c, 0x7c, + 0x7b, 0x78, 0x77, 0x77, 0x77, 0x7a, 0x7e, 0x82, 0x82, 0x80, 0x7b, 0x77, 0x77, 0x7c, 0x84, 0x8b, + 0x8e, 0x8b, 0x83, 0x79, 0x73, 0x70, 0x70, 0x74, 0x79, 0x7c, 0x7e, 0x7d, 0x7c, 0x7e, 0x85, 0x8a, + 0x8d, 0x8b, 0x84, 0x7b, 0x77, 0x79, 0x80, 0x86, 0x89, 0x88, 0x83, 0x7d, 0x7b, 0x7a, 0x7c, 0x7e, + 0x80, 0x80, 0x7e, 0x7c, 0x7c, 0x82, 0x89, 0x8e, 0x8d, 0x88, 0x80, 0x77, 0x76, 0x78, 0x7d, 0x83, + 0x86, 0x86, 0x84, 0x82, 0x81, 0x82, 0x83, 0x83, 0x81, 0x7b, 0x77, 0x76, 0x7b, 0x82, 0x88, 0x89, + 0x86, 0x81, 0x7b, 0x79, 0x79, 0x7c, 0x80, 0x80, 0x7e, 0x7c, 0x7b, 0x7c, 0x7c, 0x7e, 0x80, 0x81, + 0x81, 0x81, 0x82, 0x82, 0x83, 0x83, 0x83, 0x82, 0x82, 0x83, 0x82, 0x81, 0x7b, 0x73, 0x6e, 0x6e, + 0x72, 0x79, 0x83, 0x89, 0x89, 0x86, 0x80, 0x7b, 0x78, 0x78, 0x7c, 0x80, 0x83, 0x83, 0x81, 0x80, + 0x82, 0x85, 0x86, 0x83, 0x7d, 0x77, 0x74, 0x75, 0x79, 0x81, 0x88, 0x8c, 0x8a, 0x86, 0x82, 0x7e, + 0x7e, 0x80, 0x81, 0x7e, 0x7c, 0x7a, 0x7a, 0x7d, 0x83, 0x86, 0x86, 0x85, 0x81, 0x7d, 0x7b, 0x7c, + 0x80, 0x82, 0x84, 0x84, 0x81, 0x7d, 0x7e, 0x7e, 0x80, 0x80, 0x7d, 0x7a, 0x79, 0x7c, 0x81, 0x87, + 0x89, 0x88, 0x85, 0x7e, 0x7c, 0x7c, 0x7d, 0x7e, 0x80, 0x7d, 0x7a, 0x7a, 0x7b, 0x7e, 0x83, 0x84, + 0x84, 0x80, 0x7b, 0x7b, 0x7d, 0x81, 0x83, 0x84, 0x85, 0x86, 0x85, 0x85, 0x85, 0x84, 0x83, 0x81, + 0x7d, 0x79, 0x77, 0x78, 0x7c, 0x81, 0x84, 0x86, 0x85, 0x82, 0x7d, 0x7a, 0x78, 0x7a, 0x80, 0x82, + 0x81, 0x7d, 0x7a, 0x7b, 0x80, 0x84, 0x87, 0x87, 0x83, 0x7d, 0x79, 0x79, 0x7d, 0x82, 0x85, 0x85, + 0x83, 0x82, 0x81, 0x82, 0x82, 0x82, 0x7e, 0x7b, 0x78, 0x76, 0x77, 0x7d, 0x84, 0x88, 0x88, 0x84, + 0x80, 0x7b, 0x79, 0x79, 0x7a, 0x7b, 0x7b, 0x7c, 0x7e, 0x82, 0x84, 0x84, 0x82, 0x80, 0x7c, 0x7a, + 0x79, 0x79, 0x7a, 0x7c, 0x7d, 0x7e, 0x81, 0x80, 0x81, 0x81, 0x81, 0x81, 0x7d, 0x7b, 0x7b, 0x7b, + 0x7d, 0x80, 0x83, 0x85, 0x86, 0x85, 0x83, 0x7e, 0x7c, 0x7a, 0x7a, 0x7b, 0x7c, 0x7e, 0x81, 0x83, + 0x83, 0x82, 0x81, 0x7e, 0x7c, 0x7b, 0x7a, 0x79, 0x78, 0x79, 0x7b, 0x7e, 0x83, 0x85, 0x85, 0x83, + 0x80, 0x7c, 0x78, 0x77, 0x79, 0x7b, 0x7e, 0x81, 0x83, 0x83, 0x84, 0x84, 0x83, 0x81, 0x7d, 0x7a, + 0x78, 0x77, 0x79, 0x7c, 0x80, 0x83, 0x84, 0x84, 0x84, 0x85, 0x84, 0x83, 0x83, 0x7e, 0x7c, 0x7c, + 0x7c, 0x7d, 0x81, 0x83, 0x84, 0x85, 0x84, 0x83, 0x82, 0x80, 0x7e, 0x7c, 0x7c, 0x7b, 0x7d, 0x81, + 0x82, 0x85, 0x87, 0x87, 0x85, 0x82, 0x7e, 0x7b, 0x7a, 0x7b, 0x7c, 0x7e, 0x83, 0x85, 0x85, 0x84, + 0x81, 0x7e, 0x7c, 0x79, 0x78, 0x78, 0x7a, 0x7e, 0x81, 0x83, 0x83, 0x82, 0x7e, 0x7b, 0x78, 0x77, + 0x79, 0x7b, 0x7e, 0x81, 0x83, 0x82, 0x80, 0x7d, 0x7c, 0x7c, 0x7c, 0x7d, 0x80, 0x81, 0x82, 0x82, + 0x7e, 0x7b, 0x7b, 0x7c, 0x7e, 0x80, 0x81, 0x81, 0x80, 0x7d, 0x7c, 0x7c, 0x7b, 0x7a, 0x78, 0x77, + 0x79, 0x7c, 0x82, 0x86, 0x87, 0x87, 0x85, 0x80, 0x7c, 0x79, 0x75, 0x75, 0x77, 0x7a, 0x80, 0x84, + 0x87, 0x89, 0x87, 0x85, 0x81, 0x7a, 0x76, 0x75, 0x76, 0x79, 0x7d, 0x82, 0x85, 0x86, 0x85, 0x83, + 0x81, 0x7c, 0x7a, 0x7a, 0x7b, 0x7d, 0x80, 0x82, 0x85, 0x86, 0x85, 0x84, 0x82, 0x80, 0x7d, 0x7d, + 0x7c, 0x7c, 0x7d, 0x7e, 0x81, 0x82, 0x83, 0x83, 0x84, 0x85, 0x83, 0x81, 0x7e, 0x7d, 0x7a, 0x7a, + 0x7b, 0x7b, 0x7c, 0x80, 0x83, 0x84, 0x84, 0x83, 0x82, 0x7e, 0x7a, 0x78, 0x78, 0x79, 0x7b, 0x7e, + 0x82, 0x84, 0x85, 0x84, 0x80, 0x7c, 0x7a, 0x78, 0x77, 0x75, 0x75, 0x77, 0x7b, 0x7e, 0x82, 0x84, + 0x83, 0x81, 0x7d, 0x7b, 0x77, 0x76, 0x78, 0x79, 0x79, 0x79, 0x7b, 0x7e, 0x82, 0x85, 0x87, 0x86, + 0x82, 0x7c, 0x77, 0x76, 0x76, 0x77, 0x79, 0x7b, 0x80, 0x83, 0x86, 0x88, 0x87, 0x83, 0x7d, 0x77, + 0x74, 0x75, 0x79, 0x7e, 0x85, 0x87, 0x87, 0x84, 0x80, 0x7c, 0x7a, 0x79, 0x7a, 0x7b, 0x7b, 0x7c, + 0x7e, 0x81, 0x82, 0x82, 0x81, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7e, + 0x81, 0x83, 0x84, 0x83, 0x83, 0x81, 0x7e, 0x7d, 0x7b, 0x7a, 0x7b, 0x7b, 0x7d, 0x80, 0x81, 0x84, + 0x85, 0x86, 0x85, 0x82, 0x80, 0x7d, 0x7a, 0x79, 0x7b, 0x7d, 0x81, 0x84, 0x85, 0x85, 0x84, 0x83, + 0x81, 0x7e, 0x7b, 0x79, 0x78, 0x76, 0x78, 0x7a, 0x7e, 0x82, 0x83, 0x82, 0x81, 0x80, 0x7d, 0x7a, + 0x79, 0x7b, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x82, 0x83, 0x83, 0x80, 0x7d, 0x7d, 0x7e, 0x80, 0x81, + 0x81, 0x80, 0x7d, 0x7d, 0x80, 0x84, 0x87, 0x89, 0x88, 0x85, 0x81, 0x7c, 0x79, 0x77, 0x78, 0x7d, + 0x84, 0x88, 0x8a, 0x89, 0x87, 0x85, 0x83, 0x82, 0x7e, 0x7d, 0x7c, 0x7c, 0x7c, 0x7d, 0x7e, 0x7e, + 0x80, 0x81, 0x83, 0x83, 0x83, 0x81, 0x7e, 0x7a, 0x77, 0x77, 0x78, 0x7b, 0x7e, 0x83, 0x86, 0x86, + 0x85, 0x84, 0x82, 0x7e, 0x7b, 0x78, 0x75, 0x76, 0x7b, 0x7e, 0x84, 0x8a, 0x8c, 0x8b, 0x87, 0x80, + 0x7a, 0x76, 0x75, 0x76, 0x79, 0x7d, 0x83, 0x86, 0x87, 0x87, 0x85, 0x82, 0x80, 0x7e, 0x7d, 0x7b, + 0x7a, 0x79, 0x78, 0x79, 0x7d, 0x81, 0x83, 0x85, 0x85, 0x84, 0x82, 0x7e, 0x7d, 0x7c, 0x7a, 0x7a, + 0x7c, 0x7d, 0x81, 0x84, 0x87, 0x88, 0x87, 0x84, 0x7e, 0x7b, 0x7a, 0x78, 0x79, 0x7b, 0x7d, 0x81, + 0x84, 0x87, 0x88, 0x88, 0x86, 0x82, 0x7c, 0x79, 0x78, 0x79, 0x7b, 0x7d, 0x81, 0x83, 0x84, 0x84, + 0x85, 0x84, 0x82, 0x80, 0x7c, 0x7b, 0x79, 0x79, 0x78, 0x7b, 0x88, 0x90, 0x8e, 0x89, 0x82, 0x7a, + 0x76, 0x77, 0x79, 0x7b, 0x81, 0x86, 0x89, 0x89, 0x82, 0x7b, 0x79, 0x7a, 0x7d, 0x80, 0x81, 0x82, + 0x81, 0x7d, 0x7c, 0x7c, 0x7b, 0x7c, 0x78, 0x78, 0x87, 0x94, 0x92, 0x83, 0x7a, 0x78, 0x75, 0x74, + 0x73, 0x7c, 0x8b, 0x90, 0x8f, 0x8e, 0x89, 0x81, 0x7a, 0x77, 0x78, 0x77, 0x6e, 0x63, 0x60, 0x66, + 0x77, 0x8f, 0xa3, 0xa9, 0xa3, 0x95, 0x83, 0x70, 0x64, 0x60, 0x5e, 0x58, 0x53, 0x5c, 0x74, 0x95, + 0xb6, 0xc8, 0xc1, 0xa5, 0x85, 0x66, 0x51, 0x4f, 0x5c, 0x6f, 0x80, 0x8a, 0x97, 0xa9, 0xb6, 0xb8, + 0xaa, 0x85, 0x54, 0x33, 0x30, 0x3e, 0x59, 0x80, 0xa0, 0xaf, 0xae, 0xa9, 0xa2, 0x96, 0x89, 0x74, + 0x56, 0x3b, 0x3b, 0x56, 0x78, 0x9e, 0xbb, 0xbe, 0xaa, 0x93, 0x7c, 0x67, 0x60, 0x63, 0x63, 0x61, + 0x68, 0x83, 0xa8, 0xc1, 0xc5, 0xae, 0x81, 0x52, 0x38, 0x33, 0x43, 0x64, 0x8a, 0xa4, 0xb0, 0xb0, + 0xaa, 0x9c, 0x87, 0x71, 0x5f, 0x57, 0x5d, 0x6c, 0x7d, 0x8c, 0x96, 0x97, 0x90, 0x84, 0x77, 0x72, + 0x70, 0x71, 0x72, 0x73, 0x7b, 0x8e, 0xa3, 0xa9, 0x92, 0x64, 0x33, 0x1e, 0x39, 0x79, 0xb4, 0xd1, + 0xd3, 0xbe, 0xa1, 0x88, 0x71, 0x65, 0x61, 0x5c, 0x53, 0x53, 0x6d, 0xa1, 0xd2, 0xdd, 0xbf, 0x87, + 0x53, 0x35, 0x32, 0x43, 0x5d, 0x79, 0x8d, 0x97, 0x9e, 0xa7, 0xb0, 0xb0, 0x95, 0x67, 0x3f, 0x33, + 0x4b, 0x78, 0xa3, 0xba, 0xbb, 0xb0, 0xa0, 0x8b, 0x77, 0x6d, 0x63, 0x54, 0x4b, 0x53, 0x6f, 0x97, + 0xb8, 0xbc, 0xa2, 0x7c, 0x5c, 0x4d, 0x4d, 0x5b, 0x72, 0x8a, 0x9b, 0xa1, 0xa2, 0xa3, 0x9f, 0x92, + 0x79, 0x5e, 0x52, 0x5e, 0x78, 0x94, 0xa3, 0xa2, 0x92, 0x79, 0x69, 0x65, 0x6c, 0x75, 0x76, 0x73, + 0x76, 0x83, 0x91, 0x9d, 0x9c, 0x8b, 0x75, 0x67, 0x63, 0x6d, 0x81, 0x99, 0xae, 0xb5, 0xa1, 0x66, + 0x1f, 0x8, 0x2d, 0x74, 0xbb, 0xda, 0xce, 0xb5, 0x9f, 0x88, 0x6e, 0x5d, 0x55, 0x51, 0x4d, 0x54, + 0x72, 0xa6, 0xd0, 0xd6, 0xb5, 0x7b, 0x4a, 0x34, 0x35, 0x4b, 0x66, 0x7e, 0x90, 0x9d, 0xa8, 0xb2, + 0xb6, 0xa6, 0x81, 0x53, 0x39, 0x3f, 0x5c, 0x84, 0xaa, 0xc0, 0xb7, 0x9a, 0x84, 0x77, 0x6b, 0x5e, + 0x55, 0x54, 0x58, 0x6c, 0x91, 0xab, 0xb4, 0xad, 0x94, 0x6f, 0x52, 0x50, 0x61, 0x75, 0x86, 0x93, + 0x9c, 0xa1, 0xa4, 0x9f, 0x8d, 0x70, 0x5b, 0x50, 0x55, 0x68, 0x84, 0x9a, 0x9e, 0x93, 0x84, 0x76, + 0x6f, 0x6f, 0x75, 0x79, 0x7c, 0x85, 0x8d, 0x90, 0x8d, 0x88, 0x7e, 0x71, 0x67, 0x68, 0x73, 0x84, + 0x93, 0x9f, 0xa0, 0x93, 0x6c, 0x35, 0x17, 0x26, 0x57, 0x9b, 0xd4, 0xf0, 0xe9, 0xc5, 0x98, 0x6c, + 0x4d, 0x3f, 0x3b, 0x40, 0x56, 0x7c, 0xaf, 0xdb, 0xe1, 0xba, 0x76, 0x3d, 0x1e, 0x1e, 0x39, 0x60, + 0x91, 0xb9, 0xc6, 0xc2, 0xc0, 0xb9, 0x9a, 0x6a, 0x44, 0x38, 0x42, 0x69, 0xa0, 0xc2, 0xc5, 0xb5, + 0x9b, 0x71, 0x4a, 0x3f, 0x46, 0x4a, 0x54, 0x6d, 0x90, 0xaf, 0xc1, 0xc0, 0xa7, 0x7e, 0x5f, 0x55, + 0x56, 0x66, 0x83, 0x9e, 0xa8, 0xa6, 0xa2, 0x9a, 0x88, 0x6c, 0x54, 0x40, 0x3d, 0x4e, 0x6e, 0x8e, + 0xa5, 0xb1, 0xab, 0x9a, 0x86, 0x79, 0x75, 0x72, 0x70, 0x70, 0x71, 0x79, 0x86, 0x90, 0x91, 0x89, + 0x7d, 0x72, 0x67, 0x64, 0x6b, 0x75, 0x7b, 0x82, 0x8a, 0x93, 0x98, 0x99, 0x94, 0x89, 0x79, 0x61, + 0x40, 0x2a, 0x3c, 0x7a, 0xc5, 0xf6, 0xed, 0xb9, 0x7d, 0x56, 0x49, 0x46, 0x41, 0x45, 0x5a, 0x7e, + 0xa8, 0xc4, 0xcd, 0xbe, 0x97, 0x61, 0x33, 0x21, 0x3a, 0x6d, 0x9e, 0xb3, 0xb5, 0xb3, 0xad, 0x9d, + 0x81, 0x5d, 0x41, 0x3b, 0x4b, 0x6e, 0x9a, 0xbf, 0xc9, 0xad, 0x80, 0x54, 0x3f, 0x47, 0x59, 0x6b, + 0x7c, 0x94, 0xac, 0xb7, 0xb0, 0xa0, 0x89, 0x6c, 0x52, 0x49, 0x54, 0x6d, 0x8a, 0x99, 0x99, 0x94, + 0x90, 0x8b, 0x80, 0x71, 0x68, 0x67, 0x6a, 0x74, 0x85, 0x93, 0x9b, 0x99, 0x91, 0x85, 0x7b, 0x78, + 0x76, 0x72, 0x72, 0x77, 0x82, 0x89, 0x8b, 0x89, 0x83, 0x7a, 0x74, 0x6f, 0x6f, 0x76, 0x85, 0x91, + 0x91, 0x89, 0x82, 0x7c, 0x7c, 0x80, 0x8a, 0x94, 0x99, 0x8c, 0x54, 0x20, 0x1c, 0x43, 0x92, 0xda, + 0xef, 0xd6, 0xb0, 0x90, 0x71, 0x53, 0x3f, 0x44, 0x56, 0x61, 0x71, 0x9a, 0xca, 0xd8, 0xb0, 0x66, + 0x2c, 0x25, 0x3f, 0x63, 0x83, 0x9f, 0xb7, 0xc2, 0xb8, 0xa3, 0x8f, 0x7b, 0x61, 0x41, 0x32, 0x4b, + 0x8a, 0xc0, 0xc3, 0xa9, 0x8d, 0x73, 0x57, 0x43, 0x49, 0x5f, 0x74, 0x84, 0x96, 0xa7, 0xb4, 0xbb, + 0xad, 0x85, 0x5c, 0x53, 0x5d, 0x63, 0x6b, 0x81, 0x94, 0x9a, 0x96, 0x92, 0x8c, 0x80, 0x6f, 0x5b, + 0x4d, 0x53, 0x74, 0x95, 0xa1, 0xa0, 0x9d, 0x94, 0x83, 0x73, 0x6d, 0x6f, 0x71, 0x78, 0x83, 0x8a, + 0x91, 0x96, 0x8b, 0x74, 0x63, 0x61, 0x69, 0x72, 0x7d, 0x8b, 0x91, 0x8e, 0x87, 0x7e, 0x7e, 0x84, + 0x87, 0x84, 0x81, 0x81, 0x84, 0x85, 0x86, 0x89, 0x8b, 0x85, 0x6b, 0x47, 0x31, 0x40, 0x77, 0xbc, + 0xe3, 0xda, 0xae, 0x7e, 0x64, 0x5f, 0x62, 0x5a, 0x50, 0x57, 0x73, 0x9b, 0xba, 0xc3, 0xb0, 0x89, + 0x5a, 0x39, 0x34, 0x4f, 0x7a, 0x9a, 0xa3, 0x9f, 0xa0, 0xa4, 0x9e, 0x88, 0x6a, 0x57, 0x51, 0x58, + 0x6d, 0x8b, 0xa0, 0xa4, 0x95, 0x7e, 0x6d, 0x68, 0x6f, 0x72, 0x6d, 0x6b, 0x77, 0x8e, 0x9e, 0xa2, + 0x9e, 0x93, 0x7e, 0x6e, 0x69, 0x6f, 0x78, 0x7e, 0x81, 0x7b, 0x7a, 0x85, 0x8d, 0x8b, 0x83, 0x7a, + 0x75, 0x73, 0x75, 0x7d, 0x87, 0x87, 0x84, 0x81, 0x81, 0x84, 0x88, 0x88, 0x81, 0x7a, 0x7b, 0x80, + 0x82, 0x7e, 0x7a, 0x75, 0x72, 0x74, 0x7a, 0x83, 0x89, 0x8b, 0x86, 0x81, 0x7c, 0x7b, 0x7a, 0x76, + 0x71, 0x74, 0x82, 0x92, 0x9e, 0x9f, 0x92, 0x7b, 0x6b, 0x6a, 0x75, 0x7e, 0x75, 0x56, 0x3f, 0x4b, + 0x81, 0xc9, 0xf2, 0xe0, 0xa2, 0x61, 0x44, 0x51, 0x6a, 0x72, 0x6b, 0x65, 0x72, 0x92, 0xab, 0xaf, + 0x9e, 0x7a, 0x55, 0x3c, 0x41, 0x60, 0x92, 0xb3, 0xb4, 0xa1, 0x8e, 0x8d, 0x8f, 0x84, 0x6a, 0x55, + 0x53, 0x63, 0x7d, 0x99, 0xa8, 0xa5, 0x8d, 0x70, 0x5f, 0x5f, 0x6b, 0x78, 0x80, 0x80, 0x83, 0x92, + 0xa2, 0xa2, 0x91, 0x7c, 0x6d, 0x64, 0x65, 0x72, 0x82, 0x87, 0x83, 0x78, 0x72, 0x74, 0x7d, 0x84, + 0x82, 0x7c, 0x7c, 0x85, 0x8c, 0x8d, 0x8b, 0x86, 0x7a, 0x72, 0x72, 0x78, 0x7e, 0x81, 0x80, 0x7a, + 0x77, 0x7d, 0x87, 0x8a, 0x86, 0x7d, 0x77, 0x73, 0x73, 0x7a, 0x82, 0x86, 0x84, 0x82, 0x80, 0x7b, + 0x79, 0x78, 0x76, 0x76, 0x7d, 0x84, 0x87, 0x86, 0x83, 0x7e, 0x7d, 0x80, 0x84, 0x85, 0x82, 0x7b, + 0x76, 0x75, 0x79, 0x80, 0x87, 0x8a, 0x84, 0x73, 0x61, 0x58, 0x60, 0x7b, 0x9e, 0xb5, 0xb5, 0xa0, + 0x83, 0x6a, 0x60, 0x65, 0x6f, 0x74, 0x73, 0x74, 0x80, 0x91, 0xa0, 0x9f, 0x8a, 0x6c, 0x5a, 0x5b, + 0x6b, 0x83, 0x95, 0x9e, 0x9a, 0x92, 0x8b, 0x85, 0x80, 0x78, 0x6d, 0x66, 0x67, 0x75, 0x8c, 0x9c, + 0x9f, 0x94, 0x81, 0x71, 0x6a, 0x6c, 0x74, 0x7b, 0x82, 0x87, 0x8d, 0x92, 0x95, 0x91, 0x87, 0x76, + 0x6a, 0x68, 0x6f, 0x79, 0x81, 0x83, 0x81, 0x7c, 0x7b, 0x80, 0x85, 0x89, 0x8a, 0x88, 0x85, 0x82, + 0x81, 0x80, 0x7a, 0x75, 0x73, 0x74, 0x7a, 0x83, 0x88, 0x87, 0x82, 0x7d, 0x79, 0x78, 0x7a, 0x7d, + 0x7d, 0x7e, 0x83, 0x85, 0x84, 0x80, 0x7c, 0x7c, 0x7b, 0x78, 0x76, 0x7b, 0x84, 0x89, 0x8b, 0x86, + 0x81, 0x7e, 0x81, 0x83, 0x84, 0x85, 0x8b, 0x91, 0x92, 0x8d, 0x81, 0x5e, 0x30, 0x25, 0x3e, 0x65, + 0xa8, 0xe9, 0xf8, 0xda, 0xac, 0x83, 0x5b, 0x3a, 0x28, 0x30, 0x4a, 0x6a, 0x91, 0xbd, 0xdc, 0xd4, + 0x9a, 0x52, 0x24, 0x1f, 0x3c, 0x69, 0x93, 0xb0, 0xc4, 0xc7, 0xbb, 0xa5, 0x85, 0x5f, 0x40, 0x32, + 0x3a, 0x58, 0x8a, 0xb8, 0xc3, 0xa8, 0x88, 0x77, 0x66, 0x52, 0x4f, 0x61, 0x75, 0x86, 0x9a, 0xb3, + 0xbd, 0xb1, 0x98, 0x77, 0x55, 0x46, 0x52, 0x69, 0x79, 0x87, 0x94, 0x9d, 0x95, 0x85, 0x7b, 0x71, + 0x63, 0x5d, 0x68, 0x7e, 0x96, 0xa8, 0xb2, 0xa5, 0x8d, 0x79, 0x6b, 0x5f, 0x58, 0x61, 0x71, 0x7c, + 0x85, 0x90, 0x96, 0x91, 0x85, 0x78, 0x6f, 0x6e, 0x77, 0x86, 0x8e, 0x8c, 0x89, 0x86, 0x80, 0x78, + 0x76, 0x75, 0x72, 0x71, 0x75, 0x7c, 0x84, 0x88, 0x88, 0x83, 0x7d, 0x7d, 0x86, 0x8c, 0x8e, 0x8c, + 0x89, 0x82, 0x78, 0x72, 0x6f, 0x70, 0x72, 0x76, 0x80, 0x86, 0x8a, 0x8c, 0x89, 0x82, 0x7a, 0x73, + 0x67, 0x5a, 0x57, 0x65, 0x85, 0xb0, 0xcf, 0xcf, 0xaf, 0x7a, 0x4f, 0x3f, 0x47, 0x5f, 0x76, 0x81, + 0x85, 0x8f, 0x9e, 0xa9, 0xa2, 0x86, 0x63, 0x4b, 0x4c, 0x66, 0x8a, 0xa5, 0xb0, 0xaa, 0x97, 0x83, + 0x76, 0x71, 0x6c, 0x63, 0x5e, 0x63, 0x75, 0x8f, 0xa3, 0xa5, 0x96, 0x80, 0x6b, 0x63, 0x69, 0x76, + 0x84, 0x8a, 0x8e, 0x91, 0x93, 0x92, 0x8c, 0x81, 0x6e, 0x60, 0x62, 0x6d, 0x79, 0x82, 0x85, 0x83, + 0x80, 0x80, 0x84, 0x87, 0x84, 0x7c, 0x79, 0x7c, 0x84, 0x8d, 0x91, 0x8c, 0x80, 0x74, 0x6f, 0x6f, + 0x72, 0x78, 0x7d, 0x81, 0x83, 0x85, 0x87, 0x86, 0x83, 0x80, 0x7e, 0x80, 0x84, 0x88, 0x8a, 0x88, + 0x82, 0x77, 0x6f, 0x6c, 0x6f, 0x77, 0x82, 0x8a, 0x8c, 0x8d, 0x8d, 0x88, 0x7c, 0x72, 0x6f, 0x73, + 0x7c, 0x87, 0x8e, 0x91, 0x8e, 0x87, 0x80, 0x7a, 0x76, 0x76, 0x76, 0x76, 0x79, 0x81, 0x88, 0x88, + 0x7c, 0x6a, 0x5c, 0x5b, 0x6f, 0x93, 0xb4, 0xc5, 0xb9, 0x97, 0x6d, 0x55, 0x55, 0x64, 0x73, 0x79, + 0x77, 0x78, 0x84, 0x97, 0xa3, 0x9c, 0x83, 0x61, 0x50, 0x58, 0x71, 0x92, 0xa5, 0xa4, 0x98, 0x8b, + 0x85, 0x83, 0x7b, 0x6f, 0x63, 0x5d, 0x66, 0x7d, 0x96, 0xa4, 0xa2, 0x8e, 0x74, 0x64, 0x65, 0x71, + 0x81, 0x89, 0x8e, 0x8f, 0x90, 0x92, 0x91, 0x8a, 0x7a, 0x6b, 0x66, 0x6b, 0x78, 0x87, 0x92, 0x94, + 0x8b, 0x7d, 0x73, 0x6f, 0x70, 0x73, 0x7a, 0x85, 0x90, 0x95, 0x93, 0x8b, 0x7e, 0x73, 0x6d, 0x6e, + 0x75, 0x80, 0x86, 0x88, 0x85, 0x82, 0x81, 0x80, 0x7d, 0x7a, 0x77, 0x77, 0x78, 0x7e, 0x85, 0x8c, + 0x8e, 0x8b, 0x85, 0x82, 0x83, 0x82, 0x7d, 0x76, 0x73, 0x78, 0x7e, 0x82, 0x82, 0x84, 0x87, 0x86, + 0x82, 0x7b, 0x77, 0x79, 0x7b, 0x79, 0x79, 0x83, 0x92, 0x9b, 0x98, 0x87, 0x65, 0x38, 0x24, 0x38, + 0x66, 0xb3, 0xf1, 0xfe, 0xd9, 0xa3, 0x78, 0x56, 0x37, 0x21, 0x24, 0x41, 0x68, 0x95, 0xc5, 0xe6, + 0xdd, 0xa3, 0x51, 0x1b, 0x17, 0x3b, 0x73, 0xa4, 0xc6, 0xd2, 0xcc, 0xb9, 0x9a, 0x73, 0x4b, 0x30, + 0x2e, 0x41, 0x64, 0x99, 0xc9, 0xcd, 0xa8, 0x7e, 0x67, 0x5c, 0x51, 0x55, 0x71, 0x8d, 0x9d, 0xa9, + 0xb2, 0xab, 0x93, 0x76, 0x5c, 0x49, 0x49, 0x62, 0x82, 0x8f, 0x8f, 0x92, 0x92, 0x88, 0x77, 0x6f, + 0x6f, 0x6d, 0x6c, 0x7a, 0x90, 0x9e, 0xa3, 0xa1, 0x90, 0x75, 0x68, 0x6a, 0x6c, 0x6c, 0x74, 0x82, + 0x8a, 0x8b, 0x8b, 0x8b, 0x87, 0x7d, 0x76, 0x76, 0x7d, 0x86, 0x8f, 0x93, 0x8e, 0x85, 0x80, 0x7d, + 0x78, 0x74, 0x76, 0x78, 0x77, 0x79, 0x7e, 0x82, 0x85, 0x87, 0x89, 0x88, 0x86, 0x83, 0x80, 0x7b, + 0x78, 0x78, 0x7a, 0x7d, 0x82, 0x87, 0x8d, 0x8d, 0x86, 0x7e, 0x74, 0x6c, 0x6c, 0x71, 0x78, 0x81, + 0x89, 0x8c, 0x89, 0x86, 0x85, 0x84, 0x81, 0x7a, 0x78, 0x7a, 0x80, 0x87, 0x8c, 0x8e, 0x88, 0x7e, + 0x75, 0x70, 0x6f, 0x72, 0x71, 0x68, 0x5f, 0x64, 0x7d, 0xa7, 0xcc, 0xd9, 0xc0, 0x8a, 0x51, 0x2d, + 0x2f, 0x53, 0x80, 0x9f, 0xa9, 0xa0, 0x92, 0x88, 0x7e, 0x72, 0x61, 0x52, 0x52, 0x66, 0x8b, 0xae, + 0xbf, 0xb8, 0x9b, 0x77, 0x5f, 0x5a, 0x62, 0x6f, 0x79, 0x81, 0x86, 0x8e, 0x97, 0x98, 0x8e, 0x78, + 0x63, 0x59, 0x60, 0x74, 0x8e, 0x9d, 0xa0, 0x99, 0x8c, 0x81, 0x77, 0x6f, 0x69, 0x65, 0x68, 0x73, + 0x84, 0x92, 0x97, 0x92, 0x83, 0x71, 0x68, 0x68, 0x70, 0x7c, 0x88, 0x8f, 0x91, 0x8e, 0x87, 0x7d, + 0x74, 0x6c, 0x6a, 0x73, 0x83, 0x92, 0x9a, 0x98, 0x8b, 0x79, 0x6b, 0x65, 0x67, 0x6f, 0x7b, 0x87, + 0x8f, 0x92, 0x92, 0x8f, 0x86, 0x79, 0x6c, 0x65, 0x67, 0x72, 0x83, 0x90, 0x97, 0x96, 0x8e, 0x7e, + 0x6e, 0x67, 0x66, 0x6a, 0x73, 0x7e, 0x8c, 0x99, 0xa1, 0x9f, 0x94, 0x82, 0x6e, 0x5f, 0x5a, 0x63, + 0x78, 0x92, 0x9e, 0x9b, 0x8f, 0x82, 0x75, 0x6b, 0x68, 0x6a, 0x72, 0x82, 0x92, 0x9b, 0x97, 0x81, + 0x5c, 0x3d, 0x44, 0x76, 0xbf, 0xef, 0xe6, 0xa9, 0x61, 0x38, 0x3d, 0x5c, 0x74, 0x72, 0x64, 0x65, + 0x82, 0xaf, 0xcb, 0xbb, 0x87, 0x50, 0x37, 0x48, 0x74, 0x9d, 0xb2, 0xb0, 0xa0, 0x8c, 0x7c, 0x78, + 0x77, 0x70, 0x5e, 0x4e, 0x53, 0x71, 0x9a, 0xb0, 0xa9, 0x92, 0x77, 0x66, 0x62, 0x6a, 0x78, 0x80, + 0x81, 0x85, 0x91, 0x9b, 0x9e, 0x94, 0x81, 0x64, 0x4c, 0x50, 0x70, 0x8d, 0x96, 0x99, 0x93, 0x84, + 0x74, 0x72, 0x79, 0x79, 0x78, 0x7b, 0x84, 0x8c, 0x91, 0x94, 0x8c, 0x78, 0x68, 0x68, 0x74, 0x7d, + 0x83, 0x87, 0x83, 0x79, 0x75, 0x7b, 0x82, 0x87, 0x8a, 0x86, 0x7e, 0x78, 0x7b, 0x7e, 0x81, 0x83, + 0x84, 0x84, 0x81, 0x7b, 0x76, 0x74, 0x76, 0x7a, 0x83, 0x8c, 0x91, 0x8f, 0x85, 0x76, 0x68, 0x65, + 0x6c, 0x76, 0x81, 0x8b, 0x92, 0x95, 0x93, 0x8e, 0x85, 0x79, 0x6e, 0x66, 0x65, 0x6e, 0x7e, 0x90, + 0x98, 0x95, 0x8b, 0x7c, 0x70, 0x6c, 0x6d, 0x74, 0x7b, 0x82, 0x88, 0x8a, 0x88, 0x85, 0x82, 0x7c, + 0x78, 0x76, 0x78, 0x7a, 0x7d, 0x81, 0x86, 0x89, 0x8a, 0x86, 0x80, 0x77, 0x6f, 0x6e, 0x73, 0x7e, + 0x8c, 0x94, 0x93, 0x87, 0x75, 0x65, 0x5b, 0x5c, 0x6b, 0x86, 0xa0, 0xad, 0xaa, 0x98, 0x7c, 0x62, + 0x57, 0x59, 0x63, 0x72, 0x81, 0x8d, 0x95, 0x97, 0x93, 0x88, 0x78, 0x6a, 0x64, 0x69, 0x75, 0x87, + 0x95, 0x9b, 0x98, 0x90, 0x85, 0x78, 0x6f, 0x6c, 0x6c, 0x71, 0x7a, 0x85, 0x8d, 0x91, 0x8b, 0x81, + 0x75, 0x6d, 0x6d, 0x74, 0x7d, 0x87, 0x8d, 0x8d, 0x8a, 0x85, 0x7d, 0x77, 0x74, 0x73, 0x74, 0x78, + 0x7e, 0x85, 0x89, 0x89, 0x86, 0x81, 0x7a, 0x76, 0x76, 0x77, 0x7c, 0x83, 0x88, 0x89, 0x88, 0x84, + 0x7d, 0x7a, 0x78, 0x77, 0x7a, 0x7e, 0x82, 0x84, 0x85, 0x83, 0x7e, 0x79, 0x74, 0x72, 0x76, 0x80, + 0x8a, 0x92, 0x95, 0x93, 0x8b, 0x81, 0x79, 0x73, 0x6f, 0x6e, 0x70, 0x76, 0x7d, 0x88, 0x8f, 0x8f, + 0x8a, 0x82, 0x7b, 0x79, 0x79, 0x7d, 0x83, 0x85, 0x86, 0x88, 0x83, 0x7a, 0x78, 0x7e, 0x81, 0x80, + 0x82, 0x86, 0x86, 0x83, 0x7d, 0x76, 0x6f, 0x6d, 0x74, 0x81, 0x8e, 0x99, 0x9e, 0x99, 0x86, 0x73, + 0x69, 0x66, 0x6a, 0x75, 0x88, 0x99, 0x9f, 0x95, 0x72, 0x3e, 0x20, 0x3f, 0x90, 0xdb, 0xf9, 0xe4, + 0xad, 0x78, 0x57, 0x48, 0x3d, 0x3e, 0x50, 0x71, 0x8f, 0x9f, 0xaf, 0xb5, 0xa4, 0x76, 0x47, 0x3c, + 0x55, 0x80, 0xa5, 0xb3, 0xad, 0xa0, 0x90, 0x7a, 0x6a, 0x64, 0x61, 0x5d, 0x61, 0x76, 0x92, 0xa4, + 0xa8, 0x9e, 0x82, 0x5d, 0x4e, 0x5f, 0x79, 0x88, 0x92, 0xa4, 0xaa, 0x9a, 0x87, 0x7d, 0x74, 0x62, + 0x57, 0x62, 0x76, 0x87, 0x97, 0xa0, 0x98, 0x81, 0x71, 0x6c, 0x67, 0x63, 0x6b, 0x83, 0x94, 0x9b, + 0xa0, 0xa2, 0x95, 0x79, 0x64, 0x5c, 0x5e, 0x66, 0x77, 0x88, 0x8e, 0x8d, 0x8e, 0x8c, 0x81, 0x73, + 0x71, 0x73, 0x72, 0x76, 0x85, 0x93, 0x96, 0x91, 0x89, 0x7e, 0x74, 0x72, 0x74, 0x75, 0x75, 0x79, + 0x7c, 0x7e, 0x80, 0x82, 0x86, 0x85, 0x82, 0x7e, 0x7b, 0x78, 0x79, 0x7c, 0x81, 0x85, 0x85, 0x82, + 0x7d, 0x76, 0x72, 0x75, 0x7a, 0x82, 0x89, 0x8b, 0x87, 0x81, 0x7a, 0x76, 0x76, 0x79, 0x7c, 0x7d, + 0x7d, 0x7d, 0x7e, 0x81, 0x83, 0x85, 0x85, 0x85, 0x84, 0x81, 0x7d, 0x79, 0x77, 0x75, 0x74, 0x77, + 0x7c, 0x82, 0x87, 0x88, 0x84, 0x7d, 0x77, 0x73, 0x73, 0x7a, 0x84, 0x8b, 0x90, 0x8f, 0x8b, 0x85, + 0x7d, 0x79, 0x76, 0x74, 0x74, 0x78, 0x7d, 0x84, 0x88, 0x8b, 0x89, 0x84, 0x7e, 0x7b, 0x7a, 0x77, + 0x6e, 0x62, 0x5a, 0x62, 0x7a, 0xa2, 0xc5, 0xcb, 0xae, 0x77, 0x45, 0x31, 0x42, 0x6a, 0x8f, 0x9a, + 0x94, 0x87, 0x84, 0x8c, 0x93, 0x88, 0x6a, 0x50, 0x4f, 0x6a, 0x97, 0xb9, 0xbf, 0xa8, 0x85, 0x65, + 0x57, 0x5c, 0x69, 0x77, 0x80, 0x82, 0x86, 0x92, 0x9e, 0x9e, 0x8b, 0x6d, 0x58, 0x56, 0x67, 0x83, + 0x9a, 0xa6, 0xa3, 0x91, 0x81, 0x77, 0x71, 0x6b, 0x68, 0x6c, 0x76, 0x82, 0x8e, 0x97, 0x97, 0x86, + 0x71, 0x68, 0x6b, 0x73, 0x7d, 0x88, 0x8d, 0x88, 0x84, 0x84, 0x85, 0x81, 0x7a, 0x75, 0x72, 0x74, + 0x7a, 0x84, 0x8b, 0x89, 0x81, 0x7b, 0x79, 0x78, 0x79, 0x81, 0x87, 0x88, 0x87, 0x87, 0x86, 0x81, + 0x7b, 0x78, 0x77, 0x7a, 0x81, 0x87, 0x8a, 0x85, 0x7c, 0x77, 0x74, 0x75, 0x7b, 0x84, 0x88, 0x86, + 0x83, 0x7e, 0x7b, 0x79, 0x77, 0x78, 0x7d, 0x87, 0x8f, 0x91, 0x89, 0x7b, 0x71, 0x6a, 0x69, 0x6f, + 0x7d, 0x8e, 0x96, 0x95, 0x8f, 0x87, 0x7c, 0x72, 0x6d, 0x6c, 0x71, 0x7d, 0x88, 0x8b, 0x88, 0x85, + 0x82, 0x7b, 0x74, 0x73, 0x7c, 0x88, 0x8e, 0x8e, 0x8a, 0x84, 0x7a, 0x74, 0x73, 0x78, 0x83, 0x8c, + 0x8e, 0x7e, 0x60, 0x45, 0x45, 0x6b, 0xac, 0xe2, 0xec, 0xc1, 0x77, 0x3e, 0x34, 0x52, 0x72, 0x7d, + 0x75, 0x70, 0x7e, 0x9d, 0xb2, 0xa9, 0x85, 0x59, 0x44, 0x49, 0x67, 0x91, 0xb2, 0xbc, 0xad, 0x8e, + 0x71, 0x67, 0x69, 0x6c, 0x68, 0x60, 0x67, 0x81, 0x9f, 0xae, 0xa5, 0x8d, 0x6e, 0x57, 0x51, 0x66, + 0x89, 0x9d, 0x9c, 0x91, 0x8a, 0x86, 0x81, 0x81, 0x80, 0x72, 0x63, 0x63, 0x76, 0x88, 0x8c, 0x8e, + 0x8b, 0x7b, 0x6c, 0x6f, 0x7e, 0x89, 0x8a, 0x88, 0x85, 0x80, 0x7d, 0x84, 0x8a, 0x86, 0x7b, 0x76, + 0x7a, 0x7c, 0x7e, 0x87, 0x8b, 0x83, 0x78, 0x78, 0x7d, 0x82, 0x85, 0x87, 0x84, 0x7b, 0x76, 0x78, + 0x7d, 0x7e, 0x80, 0x83, 0x86, 0x86, 0x88, 0x8b, 0x87, 0x79, 0x6b, 0x66, 0x66, 0x6b, 0x76, 0x84, + 0x8f, 0x93, 0x94, 0x93, 0x8d, 0x81, 0x74, 0x6a, 0x63, 0x63, 0x6d, 0x7c, 0x8c, 0x97, 0x9b, 0x96, + 0x87, 0x75, 0x6b, 0x69, 0x6e, 0x77, 0x81, 0x86, 0x86, 0x87, 0x89, 0x8a, 0x88, 0x83, 0x7c, 0x76, + 0x73, 0x75, 0x7b, 0x82, 0x85, 0x84, 0x81, 0x80, 0x80, 0x81, 0x84, 0x84, 0x82, 0x80, 0x7e, 0x7c, + 0x79, 0x77, 0x75, 0x77, 0x7e, 0x87, 0x90, 0x94, 0x90, 0x89, 0x7d, 0x73, 0x6b, 0x68, 0x6a, 0x71, + 0x79, 0x86, 0x90, 0x97, 0x96, 0x8f, 0x82, 0x74, 0x6d, 0x6f, 0x77, 0x82, 0x8b, 0x8f, 0x8c, 0x84, + 0x7b, 0x76, 0x76, 0x76, 0x77, 0x79, 0x7c, 0x81, 0x87, 0x8a, 0x8a, 0x87, 0x81, 0x75, 0x63, 0x53, + 0x51, 0x68, 0x99, 0xcc, 0xe8, 0xd5, 0x98, 0x51, 0x29, 0x2b, 0x4e, 0x7b, 0x93, 0x92, 0x86, 0x84, + 0x90, 0x98, 0x8d, 0x6f, 0x54, 0x4d, 0x64, 0x90, 0xb5, 0xc4, 0xb0, 0x8a, 0x66, 0x4e, 0x50, 0x62, + 0x79, 0x89, 0x8a, 0x89, 0x8e, 0x93, 0x91, 0x82, 0x6b, 0x5a, 0x59, 0x69, 0x86, 0xa3, 0xb2, 0xad, + 0x94, 0x77, 0x67, 0x61, 0x62, 0x69, 0x75, 0x80, 0x85, 0x8c, 0x96, 0x98, 0x89, 0x75, 0x6b, 0x69, + 0x6d, 0x7b, 0x8e, 0x96, 0x91, 0x87, 0x7e, 0x7a, 0x79, 0x7a, 0x7c, 0x7c, 0x7b, 0x7d, 0x84, 0x88, + 0x84, 0x7c, 0x77, 0x75, 0x77, 0x7e, 0x8a, 0x90, 0x8d, 0x86, 0x7d, 0x78, 0x75, 0x76, 0x79, 0x7c, + 0x7e, 0x80, 0x83, 0x86, 0x84, 0x7d, 0x77, 0x72, 0x70, 0x74, 0x7c, 0x84, 0x87, 0x89, 0x8a, 0x8a, + 0x89, 0x87, 0x82, 0x79, 0x70, 0x6a, 0x6b, 0x71, 0x79, 0x80, 0x86, 0x87, 0x85, 0x84, 0x83, 0x81, + 0x7e, 0x7d, 0x80, 0x80, 0x7e, 0x7e, 0x7d, 0x78, 0x73, 0x73, 0x77, 0x7e, 0x85, 0x8c, 0x8f, 0x8d, + 0x86, 0x7c, 0x76, 0x77, 0x7b, 0x83, 0x88, 0x87, 0x82, 0x7b, 0x77, 0x76, 0x79, 0x7e, 0x82, 0x82, + 0x81, 0x82, 0x86, 0x88, 0x86, 0x80, 0x78, 0x74, 0x74, 0x77, 0x7d, 0x85, 0x88, 0x86, 0x80, 0x78, + 0x75, 0x78, 0x7d, 0x83, 0x88, 0x8d, 0x91, 0x94, 0x91, 0x87, 0x73, 0x58, 0x40, 0x3e, 0x5c, 0x94, + 0xcf, 0xe9, 0xd4, 0x99, 0x54, 0x30, 0x34, 0x54, 0x78, 0x90, 0x9a, 0x9a, 0x9d, 0x9e, 0x93, 0x74, + 0x4f, 0x38, 0x3c, 0x5f, 0x92, 0xbe, 0xcc, 0xbc, 0x98, 0x6e, 0x53, 0x4c, 0x58, 0x6c, 0x7b, 0x87, + 0x90, 0x9a, 0x9e, 0x98, 0x83, 0x68, 0x57, 0x55, 0x62, 0x7e, 0x9b, 0xab, 0xa5, 0x90, 0x7c, 0x6f, + 0x6b, 0x6c, 0x73, 0x7b, 0x7d, 0x7e, 0x85, 0x8c, 0x8a, 0x82, 0x79, 0x72, 0x6d, 0x6f, 0x7d, 0x8d, + 0x92, 0x8d, 0x86, 0x7d, 0x77, 0x76, 0x78, 0x7d, 0x7e, 0x7d, 0x80, 0x85, 0x86, 0x82, 0x7d, 0x78, + 0x72, 0x70, 0x78, 0x85, 0x8e, 0x90, 0x8c, 0x84, 0x7c, 0x78, 0x77, 0x7a, 0x7a, 0x79, 0x7b, 0x82, + 0x86, 0x88, 0x88, 0x83, 0x79, 0x72, 0x73, 0x7a, 0x82, 0x87, 0x88, 0x86, 0x82, 0x7c, 0x79, 0x7a, + 0x7a, 0x7c, 0x81, 0x85, 0x87, 0x87, 0x83, 0x7c, 0x78, 0x76, 0x77, 0x7c, 0x82, 0x83, 0x83, 0x83, + 0x84, 0x85, 0x87, 0x89, 0x88, 0x86, 0x82, 0x7b, 0x76, 0x71, 0x6f, 0x73, 0x7b, 0x84, 0x8c, 0x91, + 0x8e, 0x88, 0x82, 0x7c, 0x79, 0x76, 0x71, 0x6d, 0x6a, 0x6f, 0x7b, 0x8b, 0x9a, 0xa0, 0x9a, 0x8c, + 0x77, 0x67, 0x5f, 0x61, 0x6c, 0x7b, 0x8c, 0x99, 0x9d, 0x98, 0x8b, 0x79, 0x6c, 0x66, 0x69, 0x76, + 0x88, 0x95, 0x97, 0x90, 0x84, 0x75, 0x6b, 0x6a, 0x6e, 0x76, 0x81, 0x89, 0x8d, 0x8c, 0x8c, 0x88, + 0x81, 0x7a, 0x78, 0x7a, 0x7e, 0x82, 0x84, 0x80, 0x78, 0x74, 0x76, 0x7c, 0x86, 0x8d, 0x8f, 0x85, + 0x6e, 0x51, 0x44, 0x54, 0x85, 0xbf, 0xdf, 0xda, 0xab, 0x6a, 0x3d, 0x37, 0x4e, 0x69, 0x7c, 0x86, + 0x8a, 0x96, 0xa3, 0xa7, 0x95, 0x72, 0x53, 0x4a, 0x5b, 0x7e, 0xa5, 0xbd, 0xbd, 0xa2, 0x7c, 0x60, + 0x59, 0x64, 0x74, 0x7e, 0x80, 0x7e, 0x84, 0x8a, 0x8a, 0x84, 0x79, 0x70, 0x6d, 0x73, 0x87, 0x9c, + 0xa2, 0x97, 0x83, 0x70, 0x65, 0x65, 0x6c, 0x7b, 0x8a, 0x8e, 0x8a, 0x88, 0x85, 0x7b, 0x73, 0x70, + 0x71, 0x73, 0x79, 0x89, 0x96, 0x97, 0x8d, 0x81, 0x75, 0x71, 0x70, 0x76, 0x81, 0x84, 0x83, 0x83, + 0x86, 0x85, 0x7d, 0x78, 0x76, 0x74, 0x78, 0x81, 0x8c, 0x93, 0x8e, 0x83, 0x7a, 0x75, 0x72, 0x76, + 0x81, 0x87, 0x86, 0x85, 0x85, 0x81, 0x7a, 0x74, 0x70, 0x70, 0x74, 0x7c, 0x89, 0x90, 0x8f, 0x8a, + 0x82, 0x79, 0x75, 0x74, 0x78, 0x7e, 0x81, 0x82, 0x84, 0x83, 0x81, 0x7e, 0x7c, 0x7b, 0x7b, 0x7a, + 0x79, 0x7b, 0x7b, 0x7e, 0x85, 0x89, 0x89, 0x87, 0x81, 0x7d, 0x7e, 0x7c, 0x7d, 0x80, 0x7d, 0x79, + 0x78, 0x7c, 0x80, 0x82, 0x84, 0x86, 0x84, 0x81, 0x81, 0x81, 0x81, 0x80, 0x79, 0x70, 0x65, 0x62, + 0x6a, 0x7b, 0x91, 0xa4, 0xaa, 0xa0, 0x8d, 0x71, 0x5e, 0x59, 0x61, 0x74, 0x89, 0x96, 0x9c, 0x99, + 0x8d, 0x7b, 0x6b, 0x60, 0x5f, 0x69, 0x7c, 0x95, 0xa6, 0xa6, 0x98, 0x81, 0x6d, 0x63, 0x62, 0x6c, + 0x7b, 0x86, 0x8a, 0x8c, 0x8b, 0x84, 0x7b, 0x74, 0x71, 0x75, 0x7e, 0x88, 0x8d, 0x8b, 0x82, 0x75, + 0x6b, 0x6c, 0x77, 0x88, 0x94, 0x94, 0x84, 0x64, 0x45, 0x3b, 0x59, 0x90, 0xc3, 0xdd, 0xca, 0x92, + 0x5a, 0x47, 0x53, 0x6f, 0x82, 0x81, 0x76, 0x71, 0x7c, 0x8e, 0x95, 0x8c, 0x79, 0x68, 0x69, 0x7b, + 0x95, 0xa9, 0xab, 0x97, 0x74, 0x57, 0x53, 0x64, 0x7e, 0x95, 0x9b, 0x93, 0x89, 0x82, 0x78, 0x6b, + 0x61, 0x5f, 0x65, 0x73, 0x8c, 0xa7, 0xb6, 0xad, 0x91, 0x72, 0x60, 0x5e, 0x65, 0x73, 0x85, 0x8b, + 0x8b, 0x89, 0x88, 0x89, 0x83, 0x78, 0x71, 0x6e, 0x6d, 0x77, 0x87, 0x93, 0x94, 0x8b, 0x82, 0x7d, + 0x79, 0x7a, 0x80, 0x85, 0x86, 0x82, 0x7d, 0x7b, 0x79, 0x77, 0x7a, 0x80, 0x84, 0x86, 0x87, 0x87, + 0x83, 0x7b, 0x76, 0x76, 0x78, 0x7b, 0x81, 0x87, 0x8a, 0x8a, 0x87, 0x83, 0x7b, 0x74, 0x71, 0x73, + 0x78, 0x7e, 0x84, 0x87, 0x89, 0x86, 0x81, 0x7d, 0x7b, 0x79, 0x7a, 0x7e, 0x84, 0x86, 0x86, 0x85, + 0x83, 0x7d, 0x7a, 0x7b, 0x7d, 0x80, 0x81, 0x81, 0x81, 0x7c, 0x79, 0x79, 0x7a, 0x78, 0x78, 0x81, + 0x8b, 0x92, 0x93, 0x8d, 0x82, 0x74, 0x68, 0x63, 0x68, 0x75, 0x84, 0x90, 0x98, 0x96, 0x8b, 0x7b, + 0x70, 0x67, 0x63, 0x6c, 0x7b, 0x8a, 0x96, 0x9f, 0x9e, 0x93, 0x7e, 0x66, 0x4e, 0x41, 0x48, 0x60, + 0x88, 0xae, 0xc4, 0xc4, 0xb0, 0x90, 0x6b, 0x54, 0x4e, 0x57, 0x68, 0x7d, 0x95, 0xa3, 0xa4, 0x98, + 0x83, 0x68, 0x57, 0x58, 0x66, 0x7a, 0x8f, 0x9b, 0x99, 0x8d, 0x7d, 0x75, 0x75, 0x7a, 0x83, 0x86, + 0x84, 0x7e, 0x76, 0x6f, 0x6b, 0x6b, 0x70, 0x7d, 0x8c, 0x97, 0x9e, 0x9a, 0x8b, 0x76, 0x63, 0x56, + 0x59, 0x68, 0x7c, 0x92, 0xa1, 0xa7, 0xa1, 0x94, 0x7d, 0x60, 0x44, 0x35, 0x41, 0x6d, 0xa8, 0xd7, + 0xe2, 0xbf, 0x81, 0x45, 0x29, 0x3a, 0x67, 0x93, 0xa7, 0xa6, 0x99, 0x8c, 0x82, 0x78, 0x69, 0x58, + 0x54, 0x64, 0x84, 0xa7, 0xbe, 0xb9, 0x9c, 0x71, 0x4d, 0x43, 0x57, 0x78, 0x97, 0xa2, 0x9b, 0x8f, + 0x84, 0x77, 0x6c, 0x64, 0x64, 0x6a, 0x78, 0x8c, 0x9d, 0xa2, 0x96, 0x7d, 0x65, 0x5e, 0x66, 0x77, + 0x8b, 0x97, 0x94, 0x89, 0x7a, 0x71, 0x6e, 0x70, 0x73, 0x7b, 0x85, 0x8a, 0x8f, 0x91, 0x8d, 0x80, + 0x71, 0x66, 0x67, 0x72, 0x85, 0x95, 0x9d, 0x9a, 0x8e, 0x7d, 0x70, 0x69, 0x65, 0x68, 0x71, 0x7c, + 0x87, 0x90, 0x96, 0x97, 0x8f, 0x82, 0x73, 0x69, 0x66, 0x6b, 0x76, 0x81, 0x87, 0x8a, 0x8c, 0x8a, + 0x88, 0x84, 0x7e, 0x77, 0x72, 0x6e, 0x70, 0x75, 0x7c, 0x84, 0x89, 0x8b, 0x8b, 0x88, 0x82, 0x7b, + 0x74, 0x6f, 0x70, 0x78, 0x83, 0x8c, 0x91, 0x90, 0x88, 0x7b, 0x71, 0x6c, 0x6d, 0x73, 0x7d, 0x89, + 0x8f, 0x91, 0x8d, 0x87, 0x80, 0x78, 0x6f, 0x66, 0x68, 0x7a, 0x91, 0xa1, 0xa9, 0xa3, 0x8b, 0x6a, + 0x56, 0x53, 0x60, 0x78, 0x91, 0xa0, 0x9f, 0x95, 0x86, 0x79, 0x70, 0x68, 0x6a, 0x73, 0x83, 0x93, + 0x9b, 0x9a, 0x8f, 0x7a, 0x6a, 0x63, 0x63, 0x69, 0x70, 0x77, 0x82, 0x8c, 0x95, 0x9a, 0x93, 0x80, + 0x6a, 0x5f, 0x63, 0x76, 0x94, 0xae, 0xb6, 0xaa, 0x8f, 0x6f, 0x55, 0x47, 0x47, 0x52, 0x66, 0x7e, + 0x97, 0xab, 0xb3, 0xac, 0x98, 0x7e, 0x69, 0x5e, 0x5d, 0x68, 0x78, 0x86, 0x8f, 0x95, 0x92, 0x8d, + 0x87, 0x7e, 0x76, 0x72, 0x72, 0x72, 0x75, 0x79, 0x7e, 0x84, 0x89, 0x8c, 0x90, 0x95, 0x96, 0x94, + 0x8b, 0x77, 0x5f, 0x45, 0x34, 0x3b, 0x5f, 0x9b, 0xd2, 0xed, 0xdc, 0xab, 0x6e, 0x3e, 0x30, 0x43, + 0x68, 0x89, 0x9b, 0x9e, 0x99, 0x91, 0x87, 0x7a, 0x68, 0x59, 0x58, 0x67, 0x82, 0x98, 0xa3, 0x9e, + 0x8d, 0x78, 0x6e, 0x71, 0x7e, 0x90, 0x97, 0x8f, 0x7d, 0x69, 0x5d, 0x5b, 0x63, 0x74, 0x89, 0x9d, + 0xab, 0xad, 0xa4, 0x90, 0x71, 0x53, 0x42, 0x47, 0x61, 0x8a, 0xb0, 0xc7, 0xc1, 0xa1, 0x7c, 0x5b, + 0x4a, 0x48, 0x57, 0x70, 0x8a, 0x9f, 0xab, 0xab, 0xa0, 0x89, 0x6a, 0x55, 0x53, 0x65, 0x7e, 0x98, + 0xa6, 0xa4, 0x93, 0x7c, 0x6c, 0x66, 0x67, 0x6e, 0x79, 0x84, 0x89, 0x8d, 0x8c, 0x87, 0x7c, 0x71, + 0x6d, 0x71, 0x7b, 0x8b, 0x96, 0x98, 0x93, 0x83, 0x72, 0x68, 0x66, 0x6c, 0x75, 0x80, 0x8a, 0x90, + 0x94, 0x94, 0x8d, 0x81, 0x74, 0x6c, 0x69, 0x6d, 0x76, 0x80, 0x89, 0x8f, 0x93, 0x92, 0x8c, 0x83, + 0x79, 0x71, 0x6d, 0x6e, 0x73, 0x7b, 0x85, 0x8c, 0x91, 0x92, 0x8d, 0x85, 0x79, 0x72, 0x70, 0x73, + 0x79, 0x80, 0x85, 0x87, 0x85, 0x83, 0x82, 0x80, 0x7d, 0x7c, 0x7c, 0x7a, 0x77, 0x75, 0x6f, 0x66, + 0x6f, 0x8f, 0xaf, 0xbe, 0xb9, 0x9c, 0x72, 0x47, 0x33, 0x3f, 0x5d, 0x83, 0xa7, 0xb9, 0xb9, 0xa9, + 0x8c, 0x70, 0x58, 0x49, 0x4d, 0x65, 0x87, 0xa3, 0xb0, 0xac, 0x94, 0x75, 0x5f, 0x5a, 0x65, 0x7a, + 0x91, 0x99, 0x90, 0x78, 0x64, 0x5d, 0x60, 0x6d, 0x7e, 0x92, 0xa0, 0xa5, 0xa2, 0x96, 0x86, 0x72, + 0x63, 0x61, 0x6a, 0x7a, 0x8a, 0x92, 0x8e, 0x7b, 0x6a, 0x61, 0x62, 0x6d, 0x81, 0x96, 0xa4, 0xa7, + 0x9d, 0x8c, 0x76, 0x66, 0x5d, 0x5b, 0x65, 0x78, 0x8e, 0xa1, 0xa7, 0x9e, 0x8d, 0x7a, 0x6c, 0x66, + 0x68, 0x73, 0x80, 0x86, 0x85, 0x7d, 0x76, 0x73, 0x75, 0x7d, 0x87, 0x8d, 0x8f, 0x8e, 0x89, 0x83, + 0x7b, 0x73, 0x67, 0x59, 0x57, 0x6d, 0x94, 0xb4, 0xbe, 0xac, 0x89, 0x67, 0x58, 0x59, 0x65, 0x77, + 0x8a, 0x99, 0x9d, 0x93, 0x82, 0x70, 0x64, 0x5e, 0x5f, 0x6b, 0x80, 0x98, 0xa9, 0xaa, 0x98, 0x7c, + 0x6a, 0x64, 0x69, 0x74, 0x82, 0x8f, 0x94, 0x8f, 0x82, 0x77, 0x72, 0x71, 0x70, 0x72, 0x7c, 0x8b, + 0x93, 0x93, 0x88, 0x78, 0x6d, 0x66, 0x68, 0x73, 0x86, 0x96, 0x9e, 0x9b, 0x91, 0x7d, 0x6e, 0x68, + 0x69, 0x6c, 0x71, 0x7d, 0x8d, 0x96, 0x95, 0x90, 0x88, 0x7d, 0x73, 0x6f, 0x71, 0x78, 0x82, 0x87, + 0x87, 0x83, 0x7d, 0x7c, 0x80, 0x83, 0x85, 0x85, 0x84, 0x81, 0x7b, 0x76, 0x74, 0x74, 0x76, 0x7b, + 0x84, 0x8b, 0x90, 0x90, 0x8a, 0x81, 0x78, 0x74, 0x73, 0x77, 0x7d, 0x84, 0x89, 0x8c, 0x89, 0x81, + 0x79, 0x75, 0x74, 0x77, 0x7e, 0x84, 0x88, 0x88, 0x84, 0x7e, 0x7b, 0x79, 0x78, 0x7c, 0x81, 0x86, + 0x89, 0x88, 0x85, 0x7e, 0x76, 0x72, 0x73, 0x77, 0x7d, 0x83, 0x87, 0x87, 0x85, 0x82, 0x80, 0x7d, + 0x7b, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7e, 0x81, 0x83, 0x85, 0x84, 0x81, 0x7b, 0x77, 0x76, + 0x78, 0x7c, 0x81, 0x86, 0x88, 0x82, 0x75, 0x6f, 0x74, 0x80, 0x8b, 0x92, 0x92, 0x8a, 0x7b, 0x72, + 0x72, 0x76, 0x79, 0x7b, 0x7e, 0x7e, 0x7e, 0x83, 0x86, 0x83, 0x7a, 0x74, 0x7a, 0x87, 0x90, 0x92, + 0x8e, 0x81, 0x70, 0x67, 0x6c, 0x77, 0x87, 0x92, 0x93, 0x8a, 0x7a, 0x71, 0x70, 0x73, 0x78, 0x7d, + 0x82, 0x85, 0x89, 0x8c, 0x8c, 0x86, 0x79, 0x6e, 0x6a, 0x6f, 0x7b, 0x8a, 0x94, 0x95, 0x8b, 0x7e, + 0x75, 0x70, 0x6b, 0x68, 0x68, 0x6b, 0x71, 0x7d, 0x8f, 0x9e, 0xa4, 0xa0, 0x93, 0x82, 0x73, 0x6c, + 0x6d, 0x76, 0x80, 0x87, 0x8a, 0x88, 0x82, 0x7b, 0x76, 0x73, 0x72, 0x74, 0x7a, 0x84, 0x8c, 0x8f, + 0x8d, 0x88, 0x81, 0x7a, 0x78, 0x7c, 0x84, 0x8b, 0x8d, 0x8a, 0x82, 0x78, 0x71, 0x70, 0x73, 0x77, + 0x7d, 0x86, 0x8a, 0x8a, 0x88, 0x82, 0x7a, 0x76, 0x78, 0x7d, 0x86, 0x8d, 0x8f, 0x8c, 0x85, 0x7e, + 0x7b, 0x7a, 0x79, 0x79, 0x7c, 0x81, 0x84, 0x83, 0x81, 0x7c, 0x77, 0x77, 0x7a, 0x7d, 0x80, 0x7d, + 0x7a, 0x79, 0x80, 0x8b, 0x91, 0x90, 0x88, 0x7c, 0x75, 0x75, 0x77, 0x79, 0x7c, 0x80, 0x82, 0x82, + 0x7e, 0x7b, 0x77, 0x76, 0x76, 0x78, 0x7c, 0x83, 0x89, 0x8b, 0x87, 0x7e, 0x75, 0x6f, 0x70, 0x78, + 0x85, 0x92, 0x9a, 0x97, 0x8b, 0x7b, 0x6d, 0x65, 0x63, 0x69, 0x74, 0x84, 0x93, 0x9e, 0xa1, 0x9a, + 0x8b, 0x78, 0x69, 0x63, 0x68, 0x73, 0x7e, 0x8a, 0x91, 0x93, 0x91, 0x8d, 0x85, 0x7a, 0x70, 0x6c, + 0x6d, 0x74, 0x7e, 0x88, 0x8d, 0x8f, 0x8b, 0x83, 0x7c, 0x77, 0x74, 0x73, 0x75, 0x79, 0x7b, 0x82, + 0x8d, 0x95, 0x94, 0x8b, 0x7c, 0x6d, 0x62, 0x64, 0x74, 0x89, 0x96, 0x9b, 0x97, 0x88, 0x76, 0x6b, + 0x68, 0x69, 0x6f, 0x7a, 0x86, 0x8f, 0x93, 0x91, 0x8c, 0x83, 0x77, 0x6e, 0x6d, 0x73, 0x7c, 0x87, + 0x8d, 0x8c, 0x85, 0x7a, 0x75, 0x72, 0x72, 0x74, 0x79, 0x7d, 0x82, 0x87, 0x8a, 0x89, 0x84, 0x7c, + 0x77, 0x76, 0x7b, 0x80, 0x84, 0x85, 0x82, 0x7d, 0x7c, 0x81, 0x85, 0x86, 0x84, 0x80, 0x79, 0x75, + 0x77, 0x7b, 0x82, 0x87, 0x89, 0x8a, 0x89, 0x86, 0x84, 0x80, 0x7a, 0x74, 0x70, 0x72, 0x76, 0x79, + 0x7d, 0x82, 0x85, 0x86, 0x84, 0x83, 0x84, 0x82, 0x81, 0x78, 0x68, 0x5d, 0x65, 0x85, 0xa9, 0xc3, + 0xca, 0xb2, 0x84, 0x54, 0x37, 0x35, 0x47, 0x68, 0x8a, 0x9e, 0xa2, 0x9d, 0x92, 0x85, 0x74, 0x6b, + 0x6e, 0x7d, 0x92, 0x9f, 0xa1, 0x95, 0x7d, 0x66, 0x5b, 0x5f, 0x6f, 0x83, 0x94, 0x9c, 0x95, 0x87, + 0x78, 0x6e, 0x68, 0x6c, 0x77, 0x87, 0x92, 0x97, 0x95, 0x89, 0x7a, 0x6f, 0x69, 0x71, 0x80, 0x91, + 0x9d, 0x9e, 0x90, 0x76, 0x60, 0x54, 0x58, 0x6a, 0x86, 0x9d, 0xaa, 0xa7, 0x98, 0x81, 0x68, 0x59, + 0x55, 0x5e, 0x72, 0x8b, 0xa1, 0xad, 0xa9, 0x97, 0x80, 0x68, 0x5a, 0x57, 0x5f, 0x6d, 0x7d, 0x8c, + 0x94, 0x96, 0x92, 0x88, 0x7d, 0x76, 0x73, 0x76, 0x7c, 0x83, 0x86, 0x85, 0x81, 0x7a, 0x78, 0x79, + 0x7b, 0x82, 0x85, 0x84, 0x81, 0x7d, 0x7b, 0x7b, 0x7d, 0x7e, 0x7e, 0x80, 0x82, 0x84, 0x87, 0x86, + 0x82, 0x7e, 0x7c, 0x7e, 0x80, 0x7e, 0x7c, 0x78, 0x78, 0x7a, 0x81, 0x86, 0x88, 0x8a, 0x88, 0x85, + 0x80, 0x7b, 0x77, 0x74, 0x75, 0x77, 0x7b, 0x80, 0x85, 0x87, 0x88, 0x89, 0x88, 0x86, 0x84, 0x80, + 0x79, 0x75, 0x72, 0x72, 0x77, 0x7e, 0x86, 0x8a, 0x8d, 0x8d, 0x88, 0x81, 0x7b, 0x74, 0x6f, 0x70, + 0x74, 0x7b, 0x81, 0x87, 0x8a, 0x8a, 0x88, 0x85, 0x82, 0x7e, 0x7c, 0x76, 0x72, 0x72, 0x77, 0x83, + 0x8e, 0x92, 0x8d, 0x81, 0x75, 0x71, 0x74, 0x7b, 0x82, 0x86, 0x86, 0x88, 0x89, 0x8a, 0x87, 0x81, + 0x7a, 0x76, 0x77, 0x7b, 0x80, 0x81, 0x81, 0x81, 0x82, 0x83, 0x81, 0x7e, 0x7d, 0x7e, 0x81, 0x83, + 0x82, 0x7e, 0x7a, 0x78, 0x7b, 0x82, 0x88, 0x8a, 0x89, 0x85, 0x80, 0x7d, 0x7c, 0x7a, 0x74, 0x6e, + 0x6a, 0x6e, 0x7c, 0x8d, 0x9b, 0xa2, 0x9e, 0x93, 0x83, 0x70, 0x64, 0x5e, 0x60, 0x6d, 0x7d, 0x8d, + 0x98, 0x9a, 0x94, 0x87, 0x7a, 0x73, 0x70, 0x71, 0x75, 0x7b, 0x81, 0x85, 0x85, 0x84, 0x81, 0x7b, + 0x78, 0x76, 0x79, 0x80, 0x88, 0x8d, 0x8c, 0x86, 0x7d, 0x76, 0x74, 0x76, 0x7c, 0x85, 0x8b, 0x8d, + 0x8b, 0x84, 0x7a, 0x70, 0x6d, 0x72, 0x7c, 0x89, 0x93, 0x96, 0x91, 0x87, 0x7a, 0x6e, 0x69, 0x6c, + 0x77, 0x86, 0x91, 0x95, 0x90, 0x88, 0x7e, 0x76, 0x73, 0x75, 0x78, 0x7d, 0x83, 0x87, 0x89, 0x87, + 0x82, 0x7b, 0x79, 0x78, 0x78, 0x7a, 0x7e, 0x7d, 0x7b, 0x7c, 0x7e, 0x82, 0x88, 0x8d, 0x8e, 0x8a, + 0x83, 0x7a, 0x71, 0x6d, 0x6e, 0x75, 0x81, 0x8d, 0x95, 0x99, 0x95, 0x89, 0x78, 0x6a, 0x65, 0x69, + 0x76, 0x88, 0x95, 0x9b, 0x97, 0x8c, 0x7d, 0x6f, 0x67, 0x67, 0x6d, 0x77, 0x84, 0x8e, 0x93, 0x93, + 0x8e, 0x85, 0x7b, 0x73, 0x6f, 0x6f, 0x73, 0x7a, 0x81, 0x85, 0x87, 0x88, 0x87, 0x86, 0x82, 0x7e, + 0x7c, 0x7a, 0x7a, 0x79, 0x79, 0x7b, 0x7d, 0x80, 0x81, 0x81, 0x81, 0x80, 0x80, 0x81, 0x82, 0x84, + 0x85, 0x83, 0x80, 0x7b, 0x79, 0x7a, 0x7a, 0x7a, 0x7c, 0x80, 0x85, 0x8a, 0x8c, 0x88, 0x7e, 0x75, + 0x6f, 0x6d, 0x71, 0x7a, 0x84, 0x8b, 0x8f, 0x8e, 0x8a, 0x84, 0x7a, 0x71, 0x6b, 0x69, 0x6e, 0x7b, + 0x8a, 0x95, 0x98, 0x94, 0x8c, 0x80, 0x75, 0x6e, 0x6c, 0x6f, 0x76, 0x7e, 0x86, 0x89, 0x8a, 0x89, + 0x86, 0x80, 0x78, 0x71, 0x6d, 0x6e, 0x78, 0x89, 0x98, 0xa1, 0x9d, 0x8f, 0x7e, 0x6f, 0x67, 0x66, + 0x6b, 0x74, 0x7a, 0x7d, 0x7e, 0x7e, 0x81, 0x86, 0x8c, 0x91, 0x92, 0x90, 0x8c, 0x83, 0x77, 0x69, + 0x5f, 0x5f, 0x69, 0x7d, 0x92, 0xa0, 0xa0, 0x95, 0x83, 0x6f, 0x62, 0x5c, 0x5f, 0x69, 0x78, 0x8b, + 0x9a, 0xa2, 0x9e, 0x90, 0x7b, 0x69, 0x60, 0x64, 0x70, 0x80, 0x8c, 0x90, 0x8d, 0x87, 0x80, 0x79, + 0x76, 0x78, 0x80, 0x89, 0x8f, 0x8f, 0x86, 0x79, 0x6e, 0x6a, 0x6e, 0x77, 0x82, 0x89, 0x8d, 0x8c, + 0x87, 0x7e, 0x75, 0x71, 0x73, 0x7b, 0x86, 0x8b, 0x89, 0x84, 0x80, 0x7e, 0x7d, 0x7b, 0x7a, 0x7b, + 0x7c, 0x7e, 0x7e, 0x7a, 0x78, 0x7a, 0x7e, 0x84, 0x88, 0x89, 0x88, 0x81, 0x74, 0x69, 0x68, 0x70, + 0x80, 0x8e, 0x95, 0x93, 0x8c, 0x83, 0x79, 0x70, 0x6c, 0x6c, 0x73, 0x7c, 0x88, 0x94, 0x99, 0x96, + 0x89, 0x79, 0x6b, 0x65, 0x66, 0x6e, 0x7a, 0x86, 0x90, 0x97, 0x96, 0x8f, 0x83, 0x75, 0x6f, 0x6c, + 0x6f, 0x77, 0x82, 0x8d, 0x94, 0x93, 0x8b, 0x7b, 0x6d, 0x67, 0x6a, 0x74, 0x82, 0x90, 0x97, 0x95, + 0x8c, 0x7e, 0x73, 0x6d, 0x6e, 0x73, 0x7d, 0x88, 0x8f, 0x8f, 0x88, 0x7d, 0x78, 0x79, 0x7b, 0x7b, + 0x79, 0x78, 0x7a, 0x7e, 0x85, 0x89, 0x8c, 0x8c, 0x89, 0x83, 0x79, 0x73, 0x71, 0x70, 0x72, 0x78, + 0x81, 0x8a, 0x8e, 0x8e, 0x88, 0x80, 0x78, 0x74, 0x76, 0x7c, 0x82, 0x84, 0x82, 0x7c, 0x7b, 0x80, + 0x86, 0x87, 0x85, 0x81, 0x78, 0x71, 0x6d, 0x70, 0x7a, 0x88, 0x92, 0x97, 0x94, 0x8a, 0x7c, 0x6d, + 0x61, 0x5e, 0x66, 0x77, 0x8a, 0x98, 0x9d, 0x99, 0x8d, 0x7d, 0x6e, 0x64, 0x64, 0x6c, 0x78, 0x84, + 0x8d, 0x92, 0x91, 0x8b, 0x83, 0x7a, 0x74, 0x73, 0x76, 0x7a, 0x81, 0x89, 0x8d, 0x88, 0x7d, 0x77, + 0x77, 0x7d, 0x85, 0x89, 0x86, 0x80, 0x7a, 0x77, 0x79, 0x7c, 0x81, 0x84, 0x83, 0x81, 0x7c, 0x7a, + 0x76, 0x72, 0x6f, 0x73, 0x7c, 0x8a, 0x93, 0x95, 0x8e, 0x81, 0x72, 0x6a, 0x6b, 0x71, 0x7c, 0x87, + 0x8f, 0x91, 0x8c, 0x84, 0x7a, 0x73, 0x70, 0x74, 0x7b, 0x83, 0x89, 0x8d, 0x8d, 0x88, 0x81, 0x77, + 0x71, 0x71, 0x74, 0x7b, 0x83, 0x87, 0x87, 0x82, 0x7d, 0x7c, 0x7d, 0x80, 0x81, 0x80, 0x81, 0x83, + 0x85, 0x84, 0x80, 0x7a, 0x76, 0x75, 0x78, 0x7c, 0x82, 0x88, 0x8b, 0x8b, 0x8a, 0x85, 0x81, 0x7e, + 0x7c, 0x7b, 0x7a, 0x79, 0x77, 0x77, 0x7c, 0x82, 0x85, 0x88, 0x89, 0x86, 0x83, 0x7e, 0x78, 0x75, + 0x77, 0x7c, 0x85, 0x8c, 0x8e, 0x89, 0x7e, 0x77, 0x73, 0x74, 0x7a, 0x83, 0x88, 0x88, 0x89, 0x88, + 0x87, 0x85, 0x80, 0x79, 0x72, 0x6d, 0x70, 0x7a, 0x85, 0x90, 0x95, 0x94, 0x8d, 0x82, 0x76, 0x69, + 0x5f, 0x5f, 0x68, 0x79, 0x8e, 0x9f, 0xa6, 0xa1, 0x92, 0x7d, 0x6a, 0x5e, 0x5b, 0x60, 0x6d, 0x7c, + 0x8b, 0x95, 0x97, 0x94, 0x8d, 0x84, 0x79, 0x71, 0x6e, 0x6e, 0x71, 0x76, 0x7d, 0x85, 0x8b, 0x8d, + 0x8f, 0x8c, 0x86, 0x7e, 0x77, 0x71, 0x70, 0x73, 0x7a, 0x84, 0x8c, 0x90, 0x91, 0x90, 0x88, 0x7c, + 0x70, 0x67, 0x66, 0x6f, 0x7e, 0x8f, 0x9a, 0x9c, 0x93, 0x84, 0x73, 0x66, 0x62, 0x68, 0x74, 0x87, + 0x96, 0x9c, 0x9b, 0x92, 0x85, 0x78, 0x6f, 0x6c, 0x6e, 0x74, 0x7c, 0x85, 0x8b, 0x8d, 0x89, 0x82, + 0x7c, 0x7a, 0x7c, 0x7d, 0x7e, 0x7d, 0x7a, 0x79, 0x7a, 0x7d, 0x81, 0x84, 0x85, 0x85, 0x83, 0x80, + 0x7e, 0x7d, 0x7c, 0x7b, 0x7a, 0x7a, 0x7a, 0x7b, 0x7d, 0x80, 0x83, 0x84, 0x83, 0x80, 0x7d, 0x7e, + 0x83, 0x86, 0x86, 0x83, 0x80, 0x7a, 0x74, 0x6e, 0x6b, 0x6f, 0x7c, 0x8c, 0x9a, 0xa0, 0x9b, 0x8c, + 0x79, 0x6b, 0x67, 0x69, 0x71, 0x7b, 0x82, 0x87, 0x8a, 0x8b, 0x88, 0x80, 0x77, 0x74, 0x76, 0x7a, + 0x81, 0x84, 0x83, 0x7e, 0x79, 0x78, 0x7a, 0x7d, 0x83, 0x87, 0x8a, 0x88, 0x82, 0x7a, 0x75, 0x73, + 0x76, 0x7a, 0x7e, 0x82, 0x84, 0x85, 0x83, 0x81, 0x80, 0x7d, 0x7b, 0x78, 0x77, 0x77, 0x7a, 0x7c, + 0x80, 0x81, 0x83, 0x86, 0x87, 0x87, 0x85, 0x81, 0x7c, 0x7a, 0x79, 0x7b, 0x7c, 0x7e, 0x81, 0x83, + 0x85, 0x87, 0x84, 0x7e, 0x7a, 0x7a, 0x7d, 0x80, 0x81, 0x7d, 0x78, 0x75, 0x76, 0x7c, 0x86, 0x8b, + 0x8a, 0x85, 0x7e, 0x7b, 0x7b, 0x7d, 0x7d, 0x7d, 0x7d, 0x80, 0x84, 0x88, 0x89, 0x86, 0x81, 0x7b, + 0x78, 0x77, 0x78, 0x7c, 0x80, 0x83, 0x85, 0x85, 0x83, 0x82, 0x7e, 0x7b, 0x7a, 0x7d, 0x82, 0x87, + 0x89, 0x88, 0x86, 0x82, 0x7d, 0x7a, 0x78, 0x78, 0x79, 0x7e, 0x83, 0x86, 0x86, 0x85, 0x84, 0x82, + 0x7d, 0x7a, 0x76, 0x74, 0x76, 0x7a, 0x80, 0x83, 0x83, 0x82, 0x81, 0x80, 0x82, 0x85, 0x85, 0x82, + 0x7d, 0x7a, 0x79, 0x7a, 0x7d, 0x80, 0x82, 0x84, 0x85, 0x83, 0x81, 0x7d, 0x79, 0x77, 0x77, 0x7a, + 0x80, 0x86, 0x89, 0x8a, 0x88, 0x84, 0x7e, 0x7b, 0x7b, 0x7a, 0x7a, 0x7b, 0x7d, 0x82, 0x85, 0x87, + 0x87, 0x83, 0x7d, 0x78, 0x75, 0x75, 0x78, 0x7e, 0x86, 0x8d, 0x90, 0x8d, 0x85, 0x7b, 0x73, 0x6f, + 0x70, 0x76, 0x7e, 0x87, 0x8d, 0x8e, 0x8a, 0x82, 0x79, 0x73, 0x70, 0x70, 0x74, 0x7b, 0x84, 0x8b, + 0x8f, 0x8d, 0x86, 0x7c, 0x75, 0x72, 0x73, 0x78, 0x7d, 0x83, 0x87, 0x8a, 0x8b, 0x88, 0x83, 0x7b, + 0x73, 0x70, 0x70, 0x72, 0x77, 0x7e, 0x85, 0x8c, 0x8f, 0x8f, 0x8a, 0x82, 0x79, 0x71, 0x6e, 0x6f, + 0x75, 0x7c, 0x84, 0x89, 0x8b, 0x8b, 0x88, 0x83, 0x7e, 0x7a, 0x7a, 0x7b, 0x7c, 0x7c, 0x7a, 0x78, + 0x78, 0x78, 0x7b, 0x80, 0x84, 0x87, 0x8a, 0x8a, 0x89, 0x84, 0x7c, 0x75, 0x70, 0x71, 0x76, 0x7c, + 0x84, 0x88, 0x88, 0x86, 0x83, 0x80, 0x7c, 0x7b, 0x7a, 0x7a, 0x7b, 0x7c, 0x7e, 0x82, 0x85, 0x86, + 0x85, 0x81, 0x7c, 0x79, 0x77, 0x77, 0x7a, 0x7e, 0x83, 0x88, 0x8a, 0x89, 0x85, 0x7e, 0x79, 0x77, + 0x77, 0x7a, 0x7d, 0x7e, 0x81, 0x81, 0x80, 0x80, 0x80, 0x84, 0x88, 0x89, 0x88, 0x83, 0x7a, 0x75, + 0x73, 0x73, 0x77, 0x7c, 0x82, 0x87, 0x8a, 0x89, 0x85, 0x7e, 0x79, 0x75, 0x71, 0x72, 0x77, 0x7d, + 0x86, 0x8c, 0x90, 0x8e, 0x89, 0x82, 0x79, 0x74, 0x73, 0x75, 0x7a, 0x81, 0x87, 0x8b, 0x8a, 0x85, + 0x80, 0x79, 0x75, 0x73, 0x76, 0x7c, 0x82, 0x88, 0x8d, 0x8f, 0x8d, 0x86, 0x7c, 0x73, 0x6d, 0x6d, + 0x72, 0x7a, 0x83, 0x8a, 0x90, 0x92, 0x8f, 0x87, 0x7d, 0x75, 0x70, 0x6f, 0x72, 0x77, 0x7d, 0x84, + 0x88, 0x89, 0x88, 0x86, 0x84, 0x81, 0x7d, 0x7a, 0x78, 0x77, 0x78, 0x7b, 0x7e, 0x82, 0x84, 0x84, + 0x82, 0x81, 0x81, 0x82, 0x83, 0x83, 0x80, 0x7b, 0x77, 0x77, 0x78, 0x7b, 0x80, 0x80, 0x7d, 0x7b, + 0x7b, 0x80, 0x86, 0x8c, 0x8d, 0x8b, 0x83, 0x79, 0x72, 0x6e, 0x6f, 0x73, 0x79, 0x7e, 0x86, 0x8d, + 0x92, 0x94, 0x8f, 0x87, 0x7d, 0x74, 0x6e, 0x6c, 0x6d, 0x72, 0x7a, 0x83, 0x8a, 0x90, 0x91, 0x8d, + 0x86, 0x7d, 0x76, 0x72, 0x72, 0x74, 0x78, 0x7b, 0x7d, 0x82, 0x87, 0x8b, 0x8b, 0x86, 0x7e, 0x78, + 0x75, 0x76, 0x79, 0x7b, 0x7e, 0x81, 0x83, 0x83, 0x83, 0x80, 0x7c, 0x7b, 0x7a, 0x7a, 0x7e, 0x83, + 0x85, 0x86, 0x85, 0x81, 0x7c, 0x78, 0x75, 0x77, 0x7b, 0x82, 0x87, 0x89, 0x87, 0x81, 0x79, 0x75, + 0x75, 0x78, 0x7e, 0x84, 0x88, 0x88, 0x85, 0x83, 0x80, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7e, 0x80, + 0x80, 0x80, 0x81, 0x82, 0x82, 0x82, 0x81, 0x81, 0x80, 0x7d, 0x7b, 0x78, 0x78, 0x7a, 0x7e, 0x86, + 0x8c, 0x8d, 0x89, 0x81, 0x79, 0x74, 0x72, 0x75, 0x7a, 0x80, 0x84, 0x88, 0x88, 0x86, 0x83, 0x7b, + 0x74, 0x71, 0x71, 0x76, 0x80, 0x87, 0x8b, 0x8c, 0x8b, 0x87, 0x80, 0x79, 0x74, 0x72, 0x73, 0x77, + 0x7d, 0x83, 0x87, 0x88, 0x85, 0x82, 0x7e, 0x7b, 0x7b, 0x7a, 0x78, 0x79, 0x7d, 0x81, 0x84, 0x85, + 0x84, 0x82, 0x7e, 0x7c, 0x7a, 0x79, 0x78, 0x79, 0x7d, 0x81, 0x83, 0x84, 0x82, 0x7d, 0x7b, 0x7a, + 0x7c, 0x80, 0x83, 0x84, 0x83, 0x80, 0x7d, 0x7b, 0x7a, 0x7b, 0x7e, 0x82, 0x84, 0x87, 0x88, 0x86, + 0x84, 0x7d, 0x78, 0x75, 0x73, 0x75, 0x7a, 0x82, 0x88, 0x8c, 0x8e, 0x8b, 0x85, 0x7d, 0x74, 0x70, + 0x6e, 0x70, 0x79, 0x83, 0x8b, 0x8f, 0x8b, 0x86, 0x83, 0x7e, 0x7d, 0x7a, 0x78, 0x76, 0x74, 0x74, + 0x77, 0x7d, 0x86, 0x8d, 0x8f, 0x8f, 0x8b, 0x86, 0x7e, 0x75, 0x6e, 0x6a, 0x6a, 0x71, 0x7b, 0x88, + 0x92, 0x98, 0x97, 0x8f, 0x83, 0x76, 0x6e, 0x6c, 0x6f, 0x78, 0x82, 0x8a, 0x8f, 0x8e, 0x8a, 0x83, + 0x7c, 0x75, 0x72, 0x72, 0x78, 0x81, 0x8a, 0x91, 0x92, 0x8d, 0x84, 0x78, 0x71, 0x6c, 0x6b, 0x70, + 0x79, 0x85, 0x8c, 0x90, 0x8e, 0x86, 0x7d, 0x77, 0x74, 0x75, 0x76, 0x78, 0x7c, 0x84, 0x8a, 0x8d, + 0x8a, 0x85, 0x7d, 0x76, 0x74, 0x75, 0x77, 0x7a, 0x7e, 0x82, 0x85, 0x85, 0x84, 0x83, 0x82, 0x7d, + 0x7a, 0x78, 0x76, 0x77, 0x79, 0x7c, 0x80, 0x81, 0x84, 0x85, 0x82, 0x80, 0x7c, 0x7b, 0x7b, 0x7b, + 0x7c, 0x7b, 0x7b, 0x7c, 0x7d, 0x7e, 0x80, 0x7e, 0x7d, 0x7e, 0x80, 0x82, 0x81, 0x7d, 0x79, 0x76, + 0x75, 0x78, 0x7b, 0x7d, 0x81, 0x84, 0x86, 0x8a, 0x8c, 0x8c, 0x84, 0x7a, 0x70, 0x6a, 0x6b, 0x70, + 0x78, 0x83, 0x8b, 0x91, 0x94, 0x90, 0x88, 0x7d, 0x71, 0x6a, 0x69, 0x6e, 0x77, 0x81, 0x8a, 0x8e, + 0x8c, 0x88, 0x84, 0x80, 0x7a, 0x76, 0x75, 0x77, 0x7d, 0x83, 0x86, 0x85, 0x81, 0x7c, 0x7b, 0x7d, + 0x82, 0x84, 0x83, 0x81, 0x7c, 0x7a, 0x7a, 0x7c, 0x7c, 0x7d, 0x80, 0x84, 0x88, 0x89, 0x84, 0x7a, + 0x73, 0x70, 0x73, 0x78, 0x7e, 0x84, 0x86, 0x87, 0x87, 0x86, 0x83, 0x7e, 0x7a, 0x7a, 0x7b, 0x7c, + 0x7b, 0x78, 0x78, 0x78, 0x7b, 0x81, 0x85, 0x87, 0x88, 0x87, 0x85, 0x80, 0x79, 0x75, 0x73, 0x74, + 0x77, 0x7b, 0x81, 0x86, 0x88, 0x89, 0x86, 0x81, 0x7b, 0x77, 0x75, 0x77, 0x79, 0x7b, 0x7e, 0x84, + 0x89, 0x8c, 0x8c, 0x88, 0x81, 0x79, 0x74, 0x72, 0x73, 0x78, 0x7d, 0x83, 0x88, 0x8a, 0x88, 0x84, + 0x80, 0x7a, 0x77, 0x76, 0x79, 0x7c, 0x7d, 0x80, 0x83, 0x86, 0x88, 0x87, 0x85, 0x81, 0x7b, 0x78, + 0x75, 0x75, 0x78, 0x7c, 0x82, 0x88, 0x8b, 0x8b, 0x87, 0x7e, 0x76, 0x72, 0x70, 0x72, 0x77, 0x7c, + 0x82, 0x86, 0x88, 0x87, 0x83, 0x7c, 0x78, 0x77, 0x78, 0x79, 0x7a, 0x7c, 0x7e, 0x83, 0x88, 0x8c, + 0x8b, 0x86, 0x7d, 0x74, 0x71, 0x74, 0x77, 0x7b, 0x80, 0x82, 0x82, 0x83, 0x86, 0x87, 0x85, 0x83, + 0x81, 0x80, 0x7e, 0x7c, 0x7b, 0x79, 0x79, 0x7d, 0x82, 0x86, 0x88, 0x87, 0x85, 0x82, 0x7e, 0x7b, + 0x78, 0x78, 0x7a, 0x7d, 0x81, 0x84, 0x85, 0x84, 0x82, 0x83, 0x84, 0x84, 0x82, 0x7b, 0x75, 0x71, + 0x71, 0x77, 0x80, 0x87, 0x8c, 0x8f, 0x90, 0x8b, 0x83, 0x77, 0x6d, 0x67, 0x67, 0x6c, 0x78, 0x86, + 0x91, 0x98, 0x99, 0x94, 0x8a, 0x7b, 0x6e, 0x66, 0x64, 0x6b, 0x76, 0x84, 0x8d, 0x94, 0x96, 0x93, + 0x8d, 0x83, 0x78, 0x70, 0x6d, 0x6e, 0x74, 0x7a, 0x82, 0x88, 0x8d, 0x8e, 0x8a, 0x84, 0x7b, 0x77, + 0x76, 0x77, 0x78, 0x7a, 0x7d, 0x81, 0x83, 0x84, 0x83, 0x81, 0x82, 0x83, 0x82, 0x80, 0x7d, 0x7b, + 0x7b, 0x7b, 0x7c, 0x7e, 0x82, 0x84, 0x85, 0x85, 0x81, 0x7c, 0x79, 0x79, 0x7c, 0x7d, 0x7e, 0x81, + 0x83, 0x83, 0x85, 0x84, 0x82, 0x7c, 0x78, 0x79, 0x7c, 0x80, 0x83, 0x83, 0x82, 0x83, 0x83, 0x82, + 0x7d, 0x78, 0x74, 0x73, 0x76, 0x7b, 0x80, 0x84, 0x87, 0x89, 0x8a, 0x89, 0x83, 0x7b, 0x76, 0x75, + 0x78, 0x7a, 0x7c, 0x7e, 0x81, 0x84, 0x88, 0x8a, 0x8a, 0x85, 0x80, 0x7a, 0x77, 0x76, 0x75, 0x77, + 0x7b, 0x83, 0x8a, 0x8e, 0x8c, 0x87, 0x80, 0x79, 0x76, 0x74, 0x73, 0x74, 0x78, 0x7d, 0x84, 0x89, + 0x8d, 0x8d, 0x8a, 0x87, 0x81, 0x7a, 0x72, 0x6e, 0x70, 0x76, 0x80, 0x88, 0x8f, 0x91, 0x8e, 0x88, + 0x81, 0x77, 0x70, 0x6f, 0x72, 0x78, 0x7e, 0x84, 0x88, 0x8b, 0x8e, 0x8e, 0x8b, 0x81, 0x73, 0x69, + 0x63, 0x67, 0x75, 0x84, 0x92, 0x9a, 0x9a, 0x96, 0x8c, 0x80, 0x72, 0x67, 0x62, 0x64, 0x6c, 0x79, + 0x88, 0x94, 0x99, 0x98, 0x92, 0x87, 0x7b, 0x70, 0x68, 0x67, 0x6d, 0x76, 0x80, 0x89, 0x8d, 0x8e, + 0x8c, 0x8a, 0x86, 0x82, 0x7d, 0x78, 0x75, 0x73, 0x73, 0x74, 0x77, 0x7e, 0x87, 0x8d, 0x8f, 0x8e, + 0x89, 0x83, 0x7b, 0x74, 0x71, 0x70, 0x72, 0x78, 0x80, 0x86, 0x88, 0x86, 0x85, 0x84, 0x82, 0x80, + 0x7d, 0x7c, 0x7c, 0x7d, 0x7e, 0x7d, 0x7b, 0x7b, 0x7c, 0x7e, 0x83, 0x85, 0x84, 0x83, 0x80, 0x7e, + 0x80, 0x80, 0x80, 0x7e, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7d, 0x7e, 0x82, 0x86, 0x88, 0x86, + 0x82, 0x7e, 0x7a, 0x79, 0x7a, 0x7b, 0x7d, 0x81, 0x82, 0x82, 0x81, 0x7c, 0x7a, 0x7b, 0x81, 0x87, + 0x8a, 0x89, 0x85, 0x7d, 0x78, 0x75, 0x76, 0x79, 0x7d, 0x82, 0x85, 0x89, 0x8b, 0x89, 0x84, 0x7d, + 0x78, 0x76, 0x75, 0x77, 0x79, 0x7b, 0x7d, 0x80, 0x85, 0x89, 0x89, 0x88, 0x86, 0x82, 0x7c, 0x78, + 0x74, 0x73, 0x75, 0x7a, 0x82, 0x88, 0x8a, 0x8a, 0x88, 0x83, 0x7d, 0x7a, 0x78, 0x77, 0x77, 0x79, + 0x7d, 0x83, 0x89, 0x8b, 0x89, 0x84, 0x7c, 0x75, 0x71, 0x71, 0x77, 0x82, 0x8a, 0x8f, 0x8d, 0x86, + 0x7d, 0x77, 0x74, 0x75, 0x78, 0x7d, 0x84, 0x87, 0x89, 0x86, 0x82, 0x7d, 0x7b, 0x78, 0x79, 0x7b, + 0x7c, 0x7b, 0x7b, 0x7d, 0x7e, 0x81, 0x83, 0x85, 0x85, 0x83, 0x80, 0x7b, 0x78, 0x77, 0x79, 0x79, + 0x80, 0x86, 0x84, 0x86, 0x87, 0x81, 0x7c, 0x7a, 0x7b, 0x7e, 0x7c, 0x7e, 0x80, 0x7b, 0x7b, 0x7b, + 0x7c, 0x82, 0x82, 0x81, 0x82, 0x82, 0x83, 0x82, 0x7c, 0x7a, 0x78, 0x77, 0x7a, 0x80, 0x83, 0x81, + 0x80, 0x7e, 0x7b, 0x7a, 0x7b, 0x7c, 0x7e, 0x7e, 0x7e, 0x81, 0x80, 0x7d, 0x7d, 0x80, 0x81, 0x80, + 0x7e, 0x7d, 0x7c, 0x7c, 0x7e, 0x81, 0x81, 0x7d, 0x7b, 0x7b, 0x7d, 0x80, 0x82, 0x83, 0x86, 0x86, + 0x85, 0x81, 0x7b, 0x77, 0x72, 0x73, 0x75, 0x7a, 0x80, 0x84, 0x8a, 0x8e, 0x90, 0x8b, 0x81, 0x75, + 0x6d, 0x68, 0x69, 0x71, 0x7b, 0x86, 0x8f, 0x91, 0x90, 0x89, 0x7d, 0x72, 0x6c, 0x6e, 0x73, 0x7a, + 0x82, 0x87, 0x89, 0x87, 0x85, 0x83, 0x80, 0x7d, 0x7b, 0x7b, 0x7b, 0x7d, 0x80, 0x81, 0x83, 0x84, + 0x84, 0x84, 0x84, 0x82, 0x80, 0x80, 0x80, 0x80, 0x81, 0x80, 0x7e, 0x7d, 0x7c, 0x7b, 0x7d, 0x7d, + 0x7e, 0x7d, 0x7d, 0x7c, 0x7d, 0x80, 0x7e, 0x7d, 0x7c, 0x7b, 0x7c, 0x7e, 0x81, 0x82, 0x82, 0x81, + 0x80, 0x7e, 0x7c, 0x7b, 0x7a, 0x7b, 0x7b, 0x7e, 0x84, 0x87, 0x87, 0x85, 0x82, 0x7e, 0x79, 0x76, + 0x75, 0x77, 0x79, 0x7d, 0x83, 0x88, 0x8b, 0x8b, 0x8a, 0x86, 0x7d, 0x75, 0x72, 0x73, 0x76, 0x7c, + 0x84, 0x89, 0x8b, 0x87, 0x84, 0x80, 0x7a, 0x75, 0x74, 0x79, 0x7e, 0x83, 0x86, 0x88, 0x86, 0x81, + 0x7d, 0x7a, 0x76, 0x75, 0x78, 0x7c, 0x82, 0x86, 0x88, 0x86, 0x81, 0x7e, 0x7c, 0x79, 0x78, 0x7b, + 0x7e, 0x7e, 0x80, 0x81, 0x80, 0x7e, 0x81, 0x83, 0x82, 0x81, 0x80, 0x7e, 0x7b, 0x77, 0x75, 0x75, + 0x77, 0x7d, 0x85, 0x8a, 0x8c, 0x8b, 0x88, 0x82, 0x79, 0x72, 0x6f, 0x71, 0x75, 0x7d, 0x86, 0x8a, + 0x8c, 0x8d, 0x8b, 0x86, 0x7e, 0x77, 0x72, 0x70, 0x72, 0x79, 0x81, 0x85, 0x89, 0x8c, 0x8c, 0x89, + 0x86, 0x82, 0x7c, 0x77, 0x73, 0x73, 0x74, 0x78, 0x80, 0x86, 0x88, 0x87, 0x85, 0x82, 0x7d, 0x7a, + 0x79, 0x79, 0x7a, 0x7e, 0x84, 0x86, 0x85, 0x82, 0x80, 0x80, 0x81, 0x82, 0x80, 0x7c, 0x79, 0x7a, + 0x7e, 0x82, 0x84, 0x85, 0x86, 0x85, 0x84, 0x81, 0x7d, 0x78, 0x75, 0x78, 0x7e, 0x84, 0x88, 0x8b, + 0x8c, 0x88, 0x83, 0x7e, 0x77, 0x72, 0x72, 0x74, 0x78, 0x81, 0x88, 0x8b, 0x8c, 0x8b, 0x86, 0x82, + 0x7d, 0x77, 0x73, 0x71, 0x70, 0x72, 0x79, 0x82, 0x8c, 0x93, 0x94, 0x90, 0x89, 0x7d, 0x75, 0x70, + 0x6e, 0x70, 0x74, 0x7a, 0x84, 0x8d, 0x92, 0x93, 0x8f, 0x88, 0x7e, 0x75, 0x6f, 0x6e, 0x72, 0x79, + 0x82, 0x89, 0x8e, 0x8f, 0x8c, 0x84, 0x7b, 0x74, 0x70, 0x6f, 0x74, 0x7a, 0x82, 0x88, 0x8b, 0x89, + 0x85, 0x81, 0x7b, 0x76, 0x73, 0x72, 0x74, 0x79, 0x80, 0x86, 0x8b, 0x8d, 0x8b, 0x89, 0x83, 0x7b, + 0x75, 0x72, 0x71, 0x73, 0x78, 0x80, 0x87, 0x8d, 0x91, 0x90, 0x8c, 0x86, 0x7b, 0x72, 0x6f, 0x6f, + 0x72, 0x76, 0x7c, 0x82, 0x86, 0x88, 0x88, 0x86, 0x84, 0x82, 0x80, 0x7c, 0x78, 0x76, 0x74, 0x75, + 0x79, 0x7d, 0x83, 0x87, 0x8b, 0x8b, 0x88, 0x84, 0x7d, 0x75, 0x70, 0x6f, 0x71, 0x78, 0x80, 0x88, + 0x8d, 0x8d, 0x8b, 0x86, 0x82, 0x7c, 0x7a, 0x7a, 0x79, 0x79, 0x7a, 0x7a, 0x7d, 0x84, 0x89, 0x8b, + 0x8c, 0x89, 0x84, 0x7d, 0x77, 0x73, 0x72, 0x74, 0x78, 0x7c, 0x82, 0x87, 0x8c, 0x90, 0x91, 0x8d, + 0x85, 0x79, 0x6f, 0x69, 0x69, 0x6d, 0x75, 0x80, 0x8a, 0x92, 0x97, 0x95, 0x8d, 0x82, 0x75, 0x6e, + 0x6c, 0x6e, 0x75, 0x7c, 0x84, 0x89, 0x8d, 0x8f, 0x8c, 0x85, 0x7c, 0x73, 0x6d, 0x6d, 0x72, 0x7b, + 0x86, 0x8f, 0x92, 0x91, 0x8c, 0x84, 0x79, 0x71, 0x6f, 0x70, 0x75, 0x7d, 0x86, 0x8b, 0x8c, 0x88, + 0x82, 0x7d, 0x7a, 0x78, 0x77, 0x76, 0x77, 0x7b, 0x80, 0x83, 0x83, 0x82, 0x81, 0x82, 0x83, 0x82, + 0x83, 0x82, 0x7e, 0x7b, 0x7a, 0x79, 0x7a, 0x7b, 0x7e, 0x82, 0x86, 0x89, 0x89, 0x85, 0x80, 0x78, + 0x74, 0x73, 0x75, 0x79, 0x7e, 0x84, 0x88, 0x8b, 0x8b, 0x89, 0x83, 0x7b, 0x76, 0x73, 0x73, 0x76, + 0x7b, 0x81, 0x84, 0x87, 0x88, 0x89, 0x87, 0x83, 0x7e, 0x7a, 0x77, 0x78, 0x7a, 0x7d, 0x80, 0x82, + 0x82, 0x82, 0x81, 0x7f, 0x7e, 0x7d, 0x7c, 0x7c, 0x7d, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, 0x80, 0x80, 0x81, 0x81, 0x81, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x81, 0x81, 0x82, 0x82, 0x82, 0x81, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x80, + 0x7e, 0x7d, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x7e, 0x7d, 0x7e, 0x80, 0x81, 0x81, 0x81, 0x80, 0x7d, + 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7c, 0x7b, 0x7a, 0x79, 0x78, 0x79, 0x7a, 0x7b, 0x7a, 0x79, 0x78, + 0x78, 0x79, 0x7a, 0x7a, 0x78, 0x77, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7e, 0x7c, 0x7b, 0x7b, + 0x7d, 0x81, 0x83, 0x85, 0x85, 0x84, 0x83, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x83, + 0x84, 0x85, 0x85, 0x84, 0x84, 0x84, 0x84, 0x85, 0x87, 0x87, 0x85, 0x80, 0x75, 0x77, 0x80, 0x85, + 0x88, 0x87, 0x85, 0x82, 0x7e, 0x7e, 0x7e, 0x81, 0x84, 0x86, 0x84, 0x83, 0x85, 0x88, 0x89, 0x8a, + 0x8a, 0x87, 0x81, 0x7a, 0x78, 0x77, 0x77, 0x79, 0x79, 0x75, 0x70, 0x6d, 0x6b, 0x6f, 0x73, 0x77, + 0x79, 0x77, 0x75, 0x74, 0x71, 0x70, 0x71, 0x7a, 0x83, 0x7d, 0x76, 0x76, 0x7c, 0x7d, 0x7c, 0x7a, + 0x77, 0x75, 0x72, 0x77, 0x7a, 0x83, 0x8b, 0x8a, 0x8b, 0x87, 0x85, 0x87, 0x8c, 0x94, 0x9e, 0xa8, + 0xac, 0xa8, 0xa3, 0x9d, 0x98, 0x92, 0x89, 0x87, 0x86, 0x7e, 0x79, 0x7e, 0x81, 0x7d, 0x72, 0x6a, + 0x67, 0x61, 0x66, 0x6c, 0x70, 0x74, 0x71, 0x6a, 0x67, 0x69, 0x6a, 0x6c, 0x6e, 0x71, 0x70, 0x6b, + 0x68, 0x69, 0x6b, 0x6e, 0x6f, 0x6f, 0x6a, 0x64, 0x61, 0x5e, 0x6c, 0x7a, 0x82, 0x84, 0x86, 0x89, + 0x8a, 0x8e, 0x97, 0x9f, 0xa6, 0xa4, 0xa5, 0xa7, 0xa3, 0x9d, 0xa0, 0xa2, 0xa3, 0xb1, 0xb1, 0xab, + 0xa8, 0xa4, 0xa0, 0x9a, 0x93, 0x8a, 0x83, 0x7e, 0x76, 0x7b, 0x86, 0x8c, 0x8b, 0x83, 0x7d, 0x7d, + 0x7e, 0x82, 0x86, 0x89, 0x85, 0x7d, 0x7e, 0x7c, 0x79, 0x7c, 0x78, 0x71, 0x6f, 0x69, 0x68, 0x66, + 0x62, 0x63, 0x63, 0x5f, 0x5a, 0x4c, 0x49, 0x5e, 0x64, 0x6c, 0x74, 0x74, 0x6d, 0x6e, 0x76, 0x81, + 0x89, 0x8e, 0x90, 0x8e, 0x88, 0x87, 0x86, 0x86, 0x88, 0x86, 0x7b, 0x7e, 0x84, 0x8a, 0x92, 0x99, + 0xa2, 0xa5, 0x9c, 0x91, 0x88, 0x7c, 0x7e, 0x81, 0x73, 0x70, 0x69, 0x61, 0x5e, 0x5c, 0x58, 0x5e, + 0x5b, 0x5f, 0x67, 0x6a, 0x71, 0x76, 0x83, 0x8a, 0x8d, 0x8a, 0x81, 0x84, 0x89, 0x8c, 0x90, 0x8f, + 0x8d, 0x85, 0x79, 0x75, 0x70, 0x72, 0x7e, 0x70, 0x68, 0x6d, 0x6e, 0x72, 0x7c, 0x87, 0x8b, 0x8a, + 0x87, 0x7d, 0x72, 0x78, 0x82, 0x8a, 0x8d, 0x86, 0x77, 0x69, 0x67, 0x7a, 0x8c, 0x92, 0x98, 0xa3, + 0xa2, 0x97, 0x89, 0x80, 0x7b, 0x88, 0x95, 0x8e, 0x92, 0x96, 0x98, 0x9b, 0x9c, 0x9a, 0x9e, 0x9b, + 0x95, 0x93, 0x94, 0x94, 0x96, 0x93, 0x8c, 0x83, 0x78, 0x6d, 0x6f, 0x72, 0x6d, 0x68, 0x67, 0x66, + 0x63, 0x5f, 0x59, 0x5a, 0x63, 0x6b, 0x67, 0x68, 0x70, 0x7a, 0x7a, 0x7c, 0x7a, 0x79, 0x7b, 0x7a, + 0x76, 0x6c, 0x68, 0x70, 0x6a, 0x67, 0x6e, 0x74, 0x71, 0x78, 0x8e, 0x91, 0x87, 0x86, 0x8d, 0x8c, + 0x84, 0x7b, 0x7e, 0x80, 0x72, 0x5f, 0x63, 0x71, 0x7e, 0x85, 0x88, 0x83, 0x74, 0x72, 0x70, 0x74, + 0x82, 0x8d, 0x8f, 0x89, 0x82, 0x7b, 0x7a, 0x80, 0x88, 0x95, 0x96, 0x90, 0x90, 0x91, 0x8d, 0x8a, + 0x8c, 0x8b, 0x8f, 0x93, 0x90, 0x98, 0xa9, 0xa6, 0x9a, 0x8f, 0x89, 0x83, 0x74, 0x6a, 0x68, 0x6e, + 0x7a, 0x7a, 0x76, 0x6c, 0x67, 0x80, 0x88, 0x80, 0x83, 0x8d, 0x91, 0x91, 0x8d, 0x8b, 0x89, 0x8b, + 0x8b, 0x83, 0x7a, 0x72, 0x6c, 0x76, 0x7c, 0x7b, 0x81, 0x87, 0x86, 0x89, 0x8e, 0x94, 0xa2, 0xb7, + 0xb1, 0x97, 0x86, 0x81, 0x8a, 0x82, 0x7a, 0x80, 0x7d, 0x77, 0x78, 0x6d, 0x66, 0x6e, 0x75, 0x7b, + 0x6a, 0x5c, 0x5d, 0x69, 0x79, 0x80, 0x7b, 0x77, 0x77, 0x76, 0x73, 0x74, 0x72, 0x77, 0x7a, 0x72, + 0x63, 0x60, 0x62, 0x64, 0x6b, 0x6d, 0x69, 0x68, 0x6d, 0x82, 0x80, 0x75, 0x6e, 0x74, 0x7a, 0x67, + 0x66, 0x6d, 0x67, 0x74, 0x8d, 0x8f, 0x8d, 0x8e, 0x89, 0x84, 0x78, 0x73, 0x78, 0x87, 0x85, 0x77, + 0x74, 0x76, 0x76, 0x7c, 0x83, 0x7a, 0x71, 0x70, 0x72, 0x73, 0x78, 0x83, 0x9d, 0xa6, 0x91, 0x86, + 0x86, 0x87, 0x9e, 0xad, 0xa6, 0xa2, 0xa2, 0xa0, 0x95, 0x90, 0x8d, 0x81, 0x7d, 0x94, 0x90, 0x83, + 0x8a, 0x94, 0x9f, 0x9c, 0x88, 0x7d, 0x8c, 0x8f, 0x83, 0x89, 0x93, 0x8a, 0x7d, 0x73, 0x72, 0x78, + 0x70, 0x6b, 0x75, 0x72, 0x6f, 0x71, 0x79, 0x83, 0x8a, 0x82, 0x91, 0x9a, 0x82, 0x6d, 0x63, 0x70, + 0x77, 0x6a, 0x6b, 0x6a, 0x69, 0x71, 0x72, 0x6c, 0x78, 0x89, 0x88, 0x7b, 0x74, 0x6e, 0x6a, 0x6a, + 0x80, 0x95, 0x8a, 0x7a, 0x6e, 0x5f, 0x5b, 0x64, 0x65, 0x65, 0x69, 0x6b, 0x67, 0x68, 0x6f, 0x78, + 0x82, 0x86, 0x7d, 0x85, 0x89, 0x79, 0x76, 0x82, 0x79, 0x70, 0x64, 0x5e, 0x61, 0x6b, 0x73, 0x65, + 0x6e, 0x85, 0x87, 0x87, 0x88, 0x8a, 0x8b, 0x8d, 0x99, 0xac, 0xbc, 0xba, 0xaf, 0xa4, 0x9d, 0xa0, + 0x9a, 0x7e, 0x75, 0x7c, 0x77, 0x81, 0x9b, 0x9d, 0x95, 0x8b, 0x89, 0x85, 0x8f, 0x96, 0x86, 0x80, + 0x7e, 0x77, 0x6b, 0x68, 0x6b, 0x65, 0x61, 0x70, 0x7b, 0x83, 0x8e, 0x90, 0x91, 0x8e, 0x85, 0x7d, + 0x7a, 0x7c, 0x82, 0x8e, 0xa8, 0x9c, 0x91, 0x9b, 0x93, 0x88, 0x7b, 0x78, 0x74, 0x68, 0x74, 0x74, + 0x63, 0x5d, 0x68, 0x69, 0x6a, 0x82, 0x86, 0x78, 0x77, 0x77, 0x77, 0x73, 0x70, 0x7b, 0x85, 0x83, + 0x81, 0x87, 0x98, 0xac, 0xab, 0xad, 0xa0, 0x98, 0x99, 0x96, 0x97, 0x87, 0x71, 0x77, 0x6f, 0x6c, + 0x75, 0x7c, 0x79, 0x71, 0x7e, 0x84, 0x83, 0x82, 0x81, 0x7e, 0x7a, 0x6f, 0x5e, 0x61, 0x68, 0x5f, + 0x5f, 0x73, 0x76, 0x5f, 0x48, 0x4a, 0x53, 0x53, 0x55, 0x56, 0x48, 0x48, 0x62, 0x67, 0x62, 0x61, + 0x64, 0x68, 0x7d, 0x91, 0x87, 0x81, 0x95, 0xa3, 0x9d, 0x83, 0x6d, 0x64, 0x62, 0x65, 0x6e, 0x71, + 0x6e, 0x86, 0x8c, 0x8f, 0x8f, 0x89, 0x91, 0x9a, 0x92, 0x80, 0x73, 0x79, 0x78, 0x73, 0x82, 0x99, + 0xa7, 0xab, 0xa3, 0x95, 0xa6, 0xbc, 0xbe, 0xb9, 0xb3, 0xae, 0xab, 0xa4, 0xa6, 0xa7, 0xae, 0xb4, + 0xc5, 0xc8, 0xb6, 0xb3, 0xb6, 0xb1, 0xae, 0x9b, 0x7a, 0x73, 0x79, 0x83, 0x86, 0x82, 0x78, 0x81, + 0x86, 0x7d, 0x84, 0x8c, 0x88, 0x77, 0x6f, 0x65, 0x59, 0x57, 0x5a, 0x5c, 0x68, 0x83, 0x8a, 0x7a, + 0x68, 0x5f, 0x59, 0x57, 0x60, 0x6b, 0x6c, 0x5c, 0x4c, 0x54, 0x4d, 0x41, 0x3f, 0x40, 0x55, 0x6d, + 0x68, 0x6f, 0x76, 0x78, 0x79, 0x73, 0x6a, 0x74, 0x80, 0x7e, 0x7e, 0x84, 0x85, 0x84, 0x78, 0x78, + 0x81, 0x84, 0x83, 0x7e, 0x71, 0x62, 0x5c, 0x64, 0x6c, 0x7b, 0x8b, 0x90, 0x94, 0xa3, 0x9e, 0x98, + 0x99, 0x93, 0x95, 0x99, 0x93, 0x89, 0x92, 0x99, 0x9b, 0x90, 0x8f, 0xa1, 0xa0, 0xa3, 0xa1, 0xa2, + 0xaf, 0xb5, 0xa8, 0x99, 0x97, 0x8a, 0x7a, 0x73, 0x7a, 0x83, 0x83, 0x88, 0x88, 0x79, 0x70, 0x83, + 0x9e, 0x9a, 0x8a, 0x7d, 0x79, 0x6b, 0x65, 0x78, 0x78, 0x79, 0x73, 0x62, 0x5b, 0x5d, 0x5f, 0x6b, + 0x6e, 0x6b, 0x68, 0x67, 0x64, 0x64, 0x64, 0x66, 0x62, 0x77, 0x94, 0x8b, 0x84, 0x83, 0x87, 0x84, + 0x72, 0x66, 0x73, 0x7e, 0x81, 0x8b, 0x7c, 0x68, 0x70, 0x88, 0x92, 0x8d, 0x8c, 0x8a, 0x8a, 0x80, + 0x73, 0x72, 0x6c, 0x5a, 0x4d, 0x4f, 0x66, 0x6f, 0x72, 0x80, 0x8c, 0x8e, 0x86, 0x86, 0x92, 0x91, + 0x8c, 0x93, 0x98, 0x94, 0x91, 0x88, 0x85, 0x87, 0x6c, 0x5a, 0x69, 0x74, 0x79, 0x7c, 0x6e, 0x67, + 0x61, 0x64, 0x6d, 0x7b, 0x8b, 0x8e, 0x88, 0x9b, 0xa4, 0xa3, 0xa4, 0xac, 0xad, 0xa0, 0x94, 0x9f, + 0xa1, 0x99, 0x9f, 0x9d, 0xa3, 0xad, 0xa5, 0x90, 0x9c, 0xae, 0xb3, 0xb5, 0x9d, 0x97, 0x94, 0x84, + 0x6d, 0x5a, 0x67, 0x79, 0x83, 0x90, 0x9a, 0x91, 0x7b, 0x6c, 0x83, 0x97, 0x93, 0xa0, 0xaf, 0xa6, + 0xa1, 0x9a, 0x90, 0x8d, 0x86, 0x87, 0x6e, 0x5a, 0x60, 0x61, 0x58, 0x59, 0x6b, 0x6a, 0x57, 0x46, + 0x49, 0x56, 0x62, 0x7a, 0x86, 0x79, 0x71, 0x66, 0x5d, 0x54, 0x43, 0x3e, 0x46, 0x46, 0x4b, 0x43, + 0x39, 0x3d, 0x46, 0x62, 0x68, 0x5d, 0x5b, 0x6f, 0x67, 0x4f, 0x48, 0x57, 0x68, 0x6b, 0x72, 0x82, + 0x7a, 0x6d, 0x68, 0x80, 0x97, 0x94, 0x88, 0x81, 0x89, 0x86, 0x89, 0x9a, 0xb7, 0xbb, 0xae, 0xa5, + 0x91, 0x8b, 0x84, 0x78, 0x86, 0x8f, 0x90, 0x89, 0x72, 0x68, 0x65, 0x60, 0x68, 0x7b, 0x90, 0x9c, + 0xa1, 0x9c, 0x92, 0x8d, 0x92, 0x9d, 0x9e, 0x94, 0x8d, 0x81, 0x78, 0x92, 0xaf, 0xc4, 0xc1, 0xaa, + 0x98, 0x9b, 0xa3, 0xa5, 0x99, 0xa7, 0xa2, 0x91, 0x8b, 0x84, 0x7d, 0x70, 0x6b, 0x6d, 0x72, 0x70, + 0x7b, 0x85, 0x7b, 0x6e, 0x64, 0x69, 0x6d, 0x75, 0x77, 0x78, 0x73, 0x74, 0x94, 0xa5, 0xa2, 0x94, + 0x81, 0x76, 0x67, 0x55, 0x5c, 0x70, 0x7a, 0x7a, 0x8a, 0x9d, 0xa2, 0xa2, 0x98, 0x9b, 0x9c, 0x9a, + 0x99, 0x90, 0x8c, 0x83, 0x6e, 0x6a, 0x75, 0x79, 0x75, 0x6a, 0x6d, 0x71, 0x68, 0x55, 0x5c, 0x80, + 0x8d, 0x84, 0x78, 0x64, 0x66, 0x74, 0x81, 0x8d, 0x9a, 0xa3, 0xa8, 0xa1, 0x9f, 0x8c, 0x81, 0x89, + 0x91, 0x99, 0x99, 0x8a, 0x8e, 0x9c, 0xb4, 0xb4, 0xb1, 0xb4, 0x9b, 0x77, 0x5e, 0x5c, 0x60, 0x5b, + 0x53, 0x4c, 0x42, 0x3b, 0x37, 0x33, 0x2f, 0x41, 0x61, 0x78, 0x83, 0x76, 0x6c, 0x75, 0x89, 0x96, + 0x95, 0x88, 0x84, 0x84, 0x85, 0x7e, 0x77, 0x8f, 0xad, 0xb4, 0xab, 0x91, 0x7e, 0x79, 0x84, 0x89, + 0x70, 0x5c, 0x68, 0x6b, 0x6e, 0x6f, 0x6b, 0x66, 0x64, 0x6b, 0x6f, 0x74, 0x76, 0x6f, 0x6b, 0x69, + 0x74, 0x89, 0x9d, 0x97, 0x7e, 0x76, 0x77, 0x80, 0x87, 0x83, 0x76, 0x6f, 0x6f, 0x68, 0x56, 0x4c, + 0x50, 0x67, 0x75, 0x7b, 0x80, 0x8b, 0x97, 0xb7, 0xc5, 0x9b, 0x77, 0x6f, 0x74, 0x6c, 0x4d, 0x37, + 0x3f, 0x5f, 0x6d, 0x78, 0x79, 0x65, 0x50, 0x3b, 0x39, 0x5c, 0x81, 0x84, 0x75, 0x71, 0x6e, 0x6a, + 0x73, 0x79, 0x8e, 0x90, 0x90, 0xa0, 0xa6, 0x9b, 0x8a, 0x80, 0x98, 0xb4, 0xb5, 0xa8, 0xa7, 0xc4, + 0xda, 0xd4, 0xc6, 0xb8, 0xa9, 0xa9, 0x8b, 0x6e, 0x6c, 0x6e, 0x76, 0x78, 0x7e, 0x84, 0x80, 0x79, + 0x7b, 0x8c, 0x9f, 0xa3, 0xa8, 0xa9, 0x99, 0x8f, 0x96, 0xa5, 0xab, 0xad, 0xa2, 0x9f, 0xa4, 0x93, + 0x8a, 0x8c, 0x90, 0x93, 0x91, 0x88, 0x7b, 0x77, 0x86, 0x96, 0x83, 0x6e, 0x65, 0x64, 0x6d, 0x74, + 0x74, 0x70, 0x81, 0x97, 0x90, 0x84, 0x79, 0x78, 0x6e, 0x57, 0x4a, 0x5a, 0x81, 0x92, 0x8d, 0x8a, + 0x83, 0x7b, 0x79, 0x77, 0x71, 0x74, 0x7a, 0x72, 0x5b, 0x59, 0x66, 0x66, 0x67, 0x76, 0x8a, 0x86, + 0x85, 0xa1, 0xbb, 0xa4, 0x7d, 0x68, 0x5d, 0x53, 0x50, 0x4d, 0x5b, 0x75, 0x80, 0x87, 0x8f, 0x93, + 0x94, 0x79, 0x4d, 0x3c, 0x4c, 0x5f, 0x64, 0x59, 0x62, 0x62, 0x5b, 0x67, 0x83, 0x95, 0x80, 0x6a, + 0x6d, 0x77, 0x6d, 0x69, 0x7b, 0x7d, 0x7c, 0x8a, 0x8e, 0xad, 0xd1, 0xcd, 0xaf, 0x9b, 0x86, 0x70, + 0x4f, 0x3b, 0x38, 0x2e, 0x21, 0x16, 0x2a, 0x49, 0x56, 0x57, 0x59, 0x64, 0x63, 0x71, 0x9f, 0xab, + 0xac, 0xa0, 0x95, 0x99, 0x9b, 0xa0, 0xa4, 0xa9, 0xb4, 0xb8, 0xc1, 0xc6, 0xbc, 0xb1, 0xa3, 0x8b, + 0x86, 0x96, 0xb1, 0xc2, 0xb3, 0xa8, 0x9e, 0x94, 0x86, 0x7c, 0x8f, 0x8b, 0x87, 0x89, 0x8d, 0x96, + 0x9b, 0x93, 0x75, 0x5a, 0x4d, 0x5e, 0x82, 0xa0, 0xae, 0xb2, 0xa1, 0x91, 0x95, 0x86, 0x6a, 0x5f, + 0x5a, 0x5e, 0x56, 0x53, 0x6e, 0x80, 0x8d, 0x95, 0x9d, 0x9f, 0x9e, 0xb8, 0xbc, 0xaf, 0xb0, 0xa7, + 0x9b, 0x84, 0x6f, 0x67, 0x6a, 0x68, 0x64, 0x64, 0x67, 0x75, 0x78, 0x63, 0x43, 0x2b, 0x27, 0x27, + 0x37, 0x3b, 0x40, 0x54, 0x5a, 0x5b, 0x5e, 0x65, 0x5c, 0x60, 0x6f, 0x6c, 0x70, 0x75, 0x77, 0x75, + 0x73, 0x6d, 0x71, 0x8a, 0xac, 0xaf, 0xa6, 0xa2, 0x93, 0x83, 0x6b, 0x4f, 0x46, 0x4f, 0x57, 0x5b, + 0x68, 0x86, 0xa3, 0xac, 0xad, 0xa6, 0x9c, 0x99, 0xa3, 0xac, 0xb9, 0xb6, 0xa8, 0x95, 0x82, 0x7c, + 0x77, 0x84, 0x91, 0x91, 0x8e, 0x91, 0x9e, 0xaf, 0xa8, 0x90, 0x79, 0x75, 0x85, 0x96, 0x7e, 0x7c, + 0x88, 0x89, 0x84, 0x82, 0x92, 0x88, 0x7b, 0x74, 0x6a, 0x6a, 0x68, 0x73, 0x74, 0x69, 0x62, 0x65, + 0x6f, 0x6e, 0x71, 0x7b, 0x81, 0x7a, 0x74, 0x6e, 0x59, 0x3e, 0x39, 0x37, 0x2c, 0x2e, 0x4c, 0x68, + 0x83, 0x93, 0x9c, 0x94, 0x98, 0xb7, 0xac, 0x9f, 0x9d, 0x97, 0x91, 0x77, 0x6d, 0x7d, 0x8c, 0x91, + 0x95, 0x9b, 0xa8, 0xb4, 0xb7, 0xa0, 0x81, 0x5e, 0x4c, 0x5a, 0x72, 0x74, 0x84, 0x8f, 0x91, 0x92, + 0x85, 0x82, 0x6f, 0x6d, 0x7d, 0x84, 0x93, 0x9f, 0xa5, 0xa2, 0xa4, 0xa5, 0xac, 0xbd, 0xc7, 0xc4, + 0xbe, 0xb7, 0xc2, 0xb4, 0x88, 0x65, 0x55, 0x4f, 0x3e, 0x34, 0x2a, 0x34, 0x4d, 0x57, 0x5c, 0x6e, + 0x71, 0x6e, 0x89, 0x92, 0x97, 0xa2, 0x9a, 0x96, 0xa4, 0xa3, 0x98, 0xa1, 0xa0, 0x96, 0x91, 0x9b, + 0xae, 0xb0, 0xa2, 0x97, 0x81, 0x7a, 0x8e, 0x8b, 0x79, 0x79, 0x90, 0xa5, 0xa0, 0xa9, 0xb9, 0xb5, + 0xae, 0xa6, 0x8e, 0x7e, 0x84, 0x83, 0x70, 0x60, 0x5c, 0x67, 0x80, 0x80, 0x7a, 0x80, 0x88, 0x8b, + 0x71, 0x54, 0x3c, 0x1b, 0x1b, 0x2e, 0x42, 0x53, 0x57, 0x60, 0x5f, 0x57, 0x56, 0x55, 0x53, 0x65, + 0x62, 0x4c, 0x53, 0x5f, 0x53, 0x3b, 0x36, 0x42, 0x54, 0x4c, 0x3a, 0x36, 0x45, 0x6a, 0x7b, 0x6d, + 0x59, 0x3c, 0x37, 0x4e, 0x51, 0x52, 0x5c, 0x66, 0x72, 0x80, 0x97, 0x95, 0x82, 0x7c, 0x82, 0x82, + 0x82, 0x8c, 0x95, 0x96, 0x98, 0xa7, 0xbb, 0xd5, 0xce, 0xb1, 0x9a, 0x9c, 0xbc, 0xc3, 0xb6, 0xac, + 0x97, 0x90, 0x89, 0x80, 0x7c, 0x7a, 0x87, 0x99, 0xa4, 0x9f, 0x9b, 0xaf, 0xb1, 0xa9, 0xa4, 0xad, + 0xb2, 0x9c, 0x84, 0x81, 0x7c, 0x7d, 0x84, 0x8d, 0x9f, 0xab, 0xbd, 0xcd, 0xbd, 0x9f, 0x86, 0x7a, + 0x8a, 0x87, 0x7e, 0x80, 0x81, 0x8c, 0x94, 0x98, 0x95, 0x8b, 0x88, 0x8a, 0x8e, 0x8e, 0x99, 0x9a, + 0x91, 0x8e, 0x86, 0x85, 0x92, 0x89, 0x7c, 0x79, 0x89, 0xa3, 0x9f, 0x7e, 0x64, 0x4b, 0x3a, 0x35, + 0x34, 0x3e, 0x47, 0x55, 0x69, 0x83, 0x97, 0xa1, 0xab, 0xac, 0x90, 0x75, 0x70, 0x78, 0x7e, 0x7e, + 0x80, 0x86, 0x8e, 0x82, 0x67, 0x53, 0x47, 0x44, 0x57, 0x6b, 0x6f, 0x63, 0x4f, 0x52, 0x59, 0x55, + 0x52, 0x57, 0x59, 0x68, 0x73, 0x7e, 0x84, 0x80, 0x82, 0x77, 0x74, 0x89, 0x95, 0x8f, 0x93, 0x97, + 0xa1, 0xbc, 0xbd, 0xa8, 0x9d, 0x99, 0x9b, 0xab, 0xac, 0xa0, 0x86, 0x75, 0x7a, 0x76, 0x5e, 0x5e, + 0x6a, 0x5f, 0x61, 0x6a, 0x61, 0x55, 0x5d, 0x66, 0x66, 0x69, 0x72, 0x7e, 0x80, 0x76, 0x76, 0x7d, + 0x82, 0x8c, 0x8a, 0x9b, 0xa4, 0xa8, 0xb2, 0xa8, 0x9c, 0x98, 0x9e, 0x93, 0x83, 0x78, 0x7c, 0x76, + 0x80, 0xa2, 0xaa, 0xa0, 0x95, 0x91, 0x7d, 0x6e, 0x73, 0x7e, 0x83, 0x80, 0x78, 0x80, 0x88, 0x7d, + 0x6a, 0x5e, 0x50, 0x4c, 0x62, 0x71, 0x6c, 0x5e, 0x47, 0x42, 0x45, 0x45, 0x45, 0x4e, 0x56, 0x67, + 0x83, 0x98, 0x9c, 0x90, 0x7a, 0x6f, 0x73, 0x7a, 0x74, 0x74, 0x8a, 0x95, 0x92, 0x87, 0x87, 0x79, + 0x71, 0x75, 0x77, 0x78, 0x72, 0x62, 0x54, 0x57, 0x5e, 0x60, 0x5f, 0x66, 0x69, 0x6c, 0x66, 0x68, + 0x69, 0x64, 0x6e, 0x7b, 0x87, 0x8d, 0x99, 0xa8, 0xa9, 0xab, 0xaf, 0xc0, 0xc2, 0xb5, 0xb7, 0xbf, + 0xb3, 0xa8, 0xac, 0xb8, 0xb2, 0x99, 0x83, 0x86, 0x8e, 0x99, 0xa6, 0xaa, 0xae, 0xb4, 0xb7, 0xb5, + 0xb4, 0xaa, 0x9b, 0x94, 0x8f, 0x90, 0x94, 0x91, 0x88, 0x8d, 0x8f, 0x80, 0x6c, 0x68, 0x65, 0x6a, + 0x7c, 0x81, 0x7d, 0x75, 0x76, 0x6f, 0x62, 0x5b, 0x5b, 0x63, 0x6b, 0x7c, 0x9c, 0x99, 0x76, 0x5b, + 0x49, 0x53, 0x6d, 0x71, 0x72, 0x78, 0x7a, 0x84, 0x90, 0x8b, 0x89, 0x84, 0x78, 0x67, 0x61, 0x63, + 0x5a, 0x48, 0x46, 0x47, 0x40, 0x41, 0x48, 0x56, 0x5b, 0x56, 0x55, 0x62, 0x6d, 0x77, 0x74, 0x6d, + 0x75, 0x88, 0x90, 0x8e, 0x8d, 0x90, 0x8c, 0x7d, 0x75, 0x81, 0x8f, 0x8e, 0x86, 0x80, 0x74, 0x7a, + 0x82, 0x82, 0x72, 0x72, 0x77, 0x71, 0x6a, 0x66, 0x73, 0x73, 0x6f, 0x7b, 0x87, 0x85, 0x7e, 0x85, + 0x98, 0xa0, 0xa8, 0xb1, 0xc0, 0xce, 0xc6, 0xab, 0x92, 0x91, 0x97, 0x9b, 0x9d, 0x9a, 0x9b, 0x99, + 0x86, 0x6c, 0x6a, 0x65, 0x6c, 0x7d, 0x8b, 0x9d, 0x8c, 0x73, 0x6c, 0x6b, 0x6a, 0x71, 0x78, 0x74, + 0x77, 0x8a, 0x9a, 0xaa, 0xbf, 0xbc, 0xa5, 0x9f, 0xa3, 0xa3, 0x9e, 0x9f, 0xa0, 0xa5, 0xb3, 0xa9, + 0x9b, 0x97, 0x91, 0x96, 0x93, 0x8e, 0x84, 0x83, 0x88, 0x84, 0x7c, 0x7a, 0x7e, 0x8c, 0x8a, 0x87, + 0x77, 0x6b, 0x73, 0x78, 0x84, 0x90, 0x83, 0x5f, 0x45, 0x40, 0x44, 0x3d, 0x3d, 0x4b, 0x44, 0x39, + 0x3b, 0x4a, 0x5d, 0x60, 0x64, 0x6b, 0x71, 0x81, 0x7e, 0x70, 0x61, 0x68, 0x73, 0x6e, 0x74, 0x78, + 0x7e, 0x7e, 0x6f, 0x5e, 0x53, 0x56, 0x65, 0x6c, 0x71, 0x69, 0x63, 0x6e, 0x6b, 0x64, 0x5c, 0x58, + 0x5c, 0x5f, 0x77, 0x91, 0x77, 0x5e, 0x73, 0x7d, 0x74, 0x6b, 0x80, 0x93, 0x95, 0x9c, 0xa8, 0xc0, + 0xc8, 0xb1, 0xa6, 0xaa, 0xb8, 0xb7, 0xad, 0x9d, 0x8b, 0x9e, 0xa5, 0x93, 0x79, 0x66, 0x65, 0x71, + 0x82, 0x8c, 0x7e, 0x6a, 0x75, 0x83, 0x89, 0x86, 0x84, 0x77, 0x5a, 0x5a, 0x75, 0x8d, 0x99, 0xa4, + 0xac, 0xa0, 0x8c, 0x88, 0x87, 0x84, 0x79, 0x6a, 0x81, 0x96, 0x8d, 0x76, 0x73, 0x8a, 0x8c, 0x89, + 0x95, 0x8c, 0x82, 0x8b, 0x88, 0x75, 0x6e, 0x80, 0x93, 0x91, 0x91, 0x8e, 0x8b, 0x89, 0x83, 0x76, + 0x62, 0x53, 0x47, 0x3e, 0x3c, 0x48, 0x53, 0x4c, 0x52, 0x55, 0x44, 0x50, 0x67, 0x7d, 0x90, 0x8e, + 0x78, 0x7e, 0xa0, 0xa4, 0x8f, 0x76, 0x7d, 0x82, 0x80, 0x8f, 0x9c, 0xad, 0xa9, 0x98, 0x8d, 0x87, + 0x8c, 0x91, 0x8c, 0x77, 0x79, 0x8f, 0x9d, 0x9e, 0x8d, 0x7c, 0x7c, 0x77, 0x81, 0x89, 0x84, 0x74, + 0x6f, 0x8e, 0xa3, 0x9f, 0x9b, 0x93, 0x92, 0x9d, 0xaf, 0xc5, 0xd9, 0xe3, 0xd1, 0xb2, 0x9d, 0x9b, + 0x98, 0x82, 0x6b, 0x62, 0x77, 0x93, 0x93, 0x74, 0x6a, 0x6f, 0x6c, 0x75, 0x77, 0x68, 0x63, 0x6b, + 0x71, 0x6d, 0x72, 0x73, 0x69, 0x5f, 0x60, 0x6b, 0x7c, 0x85, 0x8c, 0x8b, 0x7e, 0x77, 0x7b, 0x87, + 0x7e, 0x7d, 0x80, 0x87, 0x92, 0x82, 0x78, 0x7b, 0x7b, 0x7e, 0x6d, 0x54, 0x45, 0x4d, 0x6d, 0x77, + 0x5e, 0x53, 0x58, 0x65, 0x6f, 0x70, 0x78, 0x8f, 0x8f, 0x81, 0x78, 0x70, 0x62, 0x4f, 0x37, 0x2e, + 0x42, 0x4f, 0x51, 0x54, 0x4a, 0x43, 0x3e, 0x49, 0x61, 0x62, 0x53, 0x54, 0x74, 0x97, 0x96, 0x96, + 0x95, 0x91, 0x88, 0x82, 0x8a, 0x92, 0xa3, 0xae, 0xa4, 0x96, 0x93, 0x94, 0x92, 0x87, 0x74, 0x75, + 0x84, 0x94, 0x86, 0x79, 0x7b, 0x78, 0x74, 0x6e, 0x71, 0x7a, 0x82, 0x86, 0x99, 0xa4, 0xa9, 0xa9, + 0xa8, 0xaa, 0xb2, 0xb1, 0xb3, 0xc4, 0xc3, 0xac, 0x96, 0x93, 0x9b, 0x89, 0x6d, 0x6a, 0x6d, 0x7b, + 0x92, 0x92, 0x94, 0x96, 0x92, 0x8e, 0x87, 0x7b, 0x79, 0x84, 0x95, 0x95, 0x82, 0x6c, 0x62, 0x5c, + 0x5a, 0x64, 0x74, 0x8f, 0x88, 0x82, 0x8f, 0x88, 0x7d, 0x77, 0x79, 0x85, 0x95, 0x93, 0x90, 0x8a, + 0x77, 0x6f, 0x6a, 0x6c, 0x67, 0x56, 0x45, 0x50, 0x7b, 0x9c, 0xa2, 0x95, 0x8f, 0x8d, 0x86, 0x92, + 0xa0, 0xa7, 0xb3, 0xb1, 0xa5, 0x98, 0x89, 0x7e, 0x6a, 0x54, 0x4b, 0x51, 0x52, 0x4b, 0x4d, 0x5f, + 0x68, 0x63, 0x62, 0x6c, 0x72, 0x75, 0x7d, 0x8f, 0x9a, 0x9e, 0x9d, 0x9a, 0x8b, 0x7a, 0x76, 0x71, + 0x73, 0x7d, 0x8c, 0x95, 0x7e, 0x73, 0x7e, 0x7a, 0x79, 0x7c, 0x7d, 0x76, 0x78, 0x82, 0x89, 0x90, + 0x92, 0x7b, 0x61, 0x5d, 0x6c, 0x80, 0x7b, 0x7c, 0x84, 0x81, 0x74, 0x70, 0x80, 0x91, 0x9f, 0xa4, + 0xa6, 0xa8, 0xa3, 0x9b, 0x9b, 0x99, 0x93, 0x92, 0x8f, 0x82, 0x73, 0x75, 0x82, 0x7a, 0x75, 0x6c, + 0x63, 0x6b, 0x6b, 0x70, 0x77, 0x73, 0x6c, 0x5f, 0x57, 0x57, 0x4e, 0x5c, 0x76, 0x98, 0xac, 0x9b, + 0x91, 0x94, 0x94, 0x93, 0x8f, 0x8f, 0x8e, 0x89, 0x75, 0x6f, 0x7d, 0x90, 0x9a, 0x97, 0x85, 0x6d, + 0x69, 0x73, 0x7e, 0x8f, 0xae, 0xc6, 0xb8, 0xac, 0x9e, 0x8e, 0x8d, 0x89, 0x8b, 0x79, 0x76, 0x7a, + 0x69, 0x58, 0x4c, 0x37, 0x2f, 0x37, 0x3f, 0x3d, 0x2c, 0x3b, 0x57, 0x64, 0x68, 0x59, 0x53, 0x60, + 0x6e, 0x85, 0x95, 0x99, 0x95, 0x91, 0x8e, 0x8a, 0x8c, 0x88, 0x8f, 0x93, 0x8c, 0x9d, 0xa6, 0x98, + 0x95, 0x91, 0x93, 0xa5, 0xa5, 0x92, 0x75, 0x62, 0x64, 0x66, 0x67, 0x5d, 0x48, 0x4d, 0x5d, 0x6c, + 0x7c, 0x78, 0x7d, 0x81, 0x83, 0x87, 0x86, 0x94, 0x9e, 0xb6, 0xc3, 0xb6, 0xa3, 0x94, 0x94, 0x9d, + 0x95, 0x86, 0x7a, 0x6f, 0x5f, 0x64, 0x80, 0x99, 0x92, 0x86, 0x7d, 0x6e, 0x82, 0x96, 0x9f, 0xa5, + 0xad, 0xb4, 0xa8, 0x9f, 0x86, 0x5f, 0x49, 0x56, 0x78, 0x72, 0x61, 0x62, 0x55, 0x49, 0x49, 0x4e, + 0x5a, 0x5a, 0x5a, 0x62, 0x69, 0x76, 0x83, 0x86, 0x8f, 0x88, 0x6b, 0x67, 0x76, 0x8d, 0xa3, 0xbb, + 0xbd, 0xa5, 0x98, 0x90, 0x92, 0x9b, 0xae, 0xb4, 0x9d, 0x8a, 0x8a, 0x91, 0x8b, 0x74, 0x61, 0x61, + 0x61, 0x5c, 0x4c, 0x34, 0x36, 0x3e, 0x44, 0x50, 0x5e, 0x65, 0x5e, 0x66, 0x84, 0x94, 0x9c, 0x8f, + 0x8c, 0x98, 0x91, 0x7b, 0x73, 0x8b, 0x9a, 0x9b, 0x9f, 0xa2, 0x9b, 0x94, 0x91, 0x96, 0xa2, 0x9b, + 0x82, 0x6f, 0x72, 0x7e, 0x82, 0x7d, 0x73, 0x5e, 0x63, 0x83, 0xa1, 0xa5, 0x97, 0xa0, 0x9b, 0x9a, + 0x97, 0x8c, 0x82, 0x92, 0xb4, 0xbc, 0xc0, 0xb3, 0x99, 0x8a, 0x8e, 0x90, 0x87, 0x75, 0x6d, 0x7a, + 0x8b, 0x9d, 0xa3, 0x9c, 0xa4, 0x9f, 0x90, 0x92, 0x9d, 0xa0, 0x91, 0x83, 0x7e, 0x78, 0x72, 0x63, + 0x55, 0x55, 0x78, 0x85, 0x7a, 0x6a, 0x75, 0x89, 0x87, 0x84, 0x85, 0x87, 0x7b, 0x74, 0x74, 0x72, + 0x67, 0x60, 0x6a, 0x78, 0x7d, 0x69, 0x4e, 0x53, 0x6b, 0x7a, 0x90, 0x8a, 0x82, 0x8a, 0x88, 0x77, + 0x82, 0x96, 0x93, 0x7b, 0x61, 0x5c, 0x5e, 0x51, 0x3b, 0x24, 0x29, 0x34, 0x33, 0x31, 0x38, 0x46, + 0x4b, 0x45, 0x4a, 0x54, 0x5e, 0x68, 0x81, 0x94, 0x9e, 0x9a, 0x93, 0x99, 0x9a, 0x8a, 0x6b, 0x6e, + 0x8a, 0x94, 0xa2, 0xa8, 0x92, 0x76, 0x75, 0x7a, 0x7a, 0x78, 0x72, 0x6a, 0x5a, 0x57, 0x5c, 0x64, + 0x6c, 0x60, 0x50, 0x5c, 0x77, 0x8a, 0x85, 0x77, 0x77, 0x82, 0x84, 0x87, 0x91, 0x98, 0xa6, 0xa0, + 0xa1, 0xad, 0xa3, 0x9a, 0x9b, 0x9e, 0x8f, 0x89, 0x89, 0x87, 0x8a, 0x8d, 0x9a, 0x95, 0x8a, 0x92, + 0xa2, 0x9f, 0x96, 0x91, 0x95, 0x92, 0x94, 0x93, 0x9c, 0xa0, 0x93, 0x7e, 0x8b, 0xa1, 0x9e, 0x8c, + 0x79, 0x76, 0x77, 0x75, 0x6d, 0x6b, 0x72, 0x76, 0x74, 0x79, 0x89, 0x8e, 0x84, 0x80, 0x8d, 0x8a, + 0x7e, 0x81, 0x93, 0xa1, 0xa2, 0xa2, 0x98, 0x8c, 0x84, 0x86, 0x8a, 0x9d, 0xa2, 0x99, 0x99, 0x8e, + 0x76, 0x66, 0x67, 0x60, 0x60, 0x63, 0x64, 0x61, 0x54, 0x59, 0x69, 0x6e, 0x77, 0x81, 0x82, 0x88, + 0x92, 0x9a, 0x9f, 0x9d, 0x8d, 0x8d, 0x91, 0x95, 0x93, 0x8a, 0x8c, 0x8a, 0x8c, 0x95, 0x9a, 0x90, + 0x89, 0x7e, 0x78, 0x79, 0x76, 0x74, 0x69, 0x69, 0x75, 0x75, 0x71, 0x7a, 0x7e, 0x6d, 0x62, 0x61, + 0x6a, 0x73, 0x75, 0x75, 0x87, 0x8a, 0x85, 0x87, 0x99, 0xa5, 0xa2, 0xa2, 0xa2, 0x92, 0x88, 0x86, + 0x7c, 0x73, 0x66, 0x65, 0x6b, 0x6c, 0x84, 0x9f, 0x93, 0x86, 0x90, 0x96, 0x90, 0xa2, 0xab, 0x95, + 0x80, 0x6c, 0x64, 0x62, 0x59, 0x4d, 0x4c, 0x5c, 0x5f, 0x5f, 0x64, 0x5c, 0x4a, 0x44, 0x4d, 0x56, + 0x63, 0x68, 0x6c, 0x6c, 0x72, 0x84, 0x82, 0x82, 0x8d, 0x89, 0x72, 0x60, 0x6f, 0x74, 0x72, 0x76, + 0x79, 0x7a, 0x76, 0x7a, 0x87, 0x9b, 0xa9, 0x9f, 0x99, 0x96, 0x90, 0x94, 0x8e, 0x76, 0x62, 0x5a, + 0x59, 0x56, 0x51, 0x54, 0x52, 0x48, 0x4e, 0x5c, 0x69, 0x64, 0x65, 0x70, 0x79, 0x96, 0x9f, 0x91, + 0x92, 0x9b, 0xa0, 0x9e, 0xa2, 0xac, 0xaf, 0xa3, 0x99, 0x8e, 0x8a, 0x83, 0x7c, 0x71, 0x68, 0x69, + 0x66, 0x60, 0x6c, 0x77, 0x79, 0x7b, 0x78, 0x73, 0x7a, 0x98, 0xa3, 0x9c, 0x99, 0x90, 0x92, 0x9a, + 0xa6, 0xad, 0xad, 0xaa, 0xa6, 0xa1, 0xac, 0x9e, 0x86, 0x85, 0x93, 0x9f, 0x90, 0x7b, 0x76, 0x73, + 0x6a, 0x6f, 0x7c, 0x88, 0x95, 0x92, 0x88, 0x86, 0x93, 0x97, 0x95, 0x8a, 0x89, 0x8d, 0x8a, 0x86, + 0x91, 0x9f, 0x9e, 0x87, 0x77, 0x64, 0x4d, 0x59, 0x61, 0x55, 0x50, 0x4d, 0x50, 0x51, 0x54, 0x60, + 0x5b, 0x50, 0x5d, 0x68, 0x6f, 0x68, 0x6a, 0x72, 0x7c, 0x84, 0x8e, 0x99, 0x9c, 0x9c, 0xa1, 0xa9, + 0xb4, 0xb8, 0xb1, 0x9e, 0x88, 0x77, 0x7d, 0x8a, 0x83, 0x72, 0x74, 0x74, 0x6e, 0x6d, 0x6b, 0x64, + 0x6e, 0x77, 0x72, 0x6f, 0x7b, 0x87, 0x87, 0x83, 0x87, 0x86, 0x85, 0x8b, 0x96, 0xa2, 0x9d, 0x94, + 0x89, 0x7c, 0x72, 0x67, 0x63, 0x65, 0x6c, 0x74, 0x75, 0x7a, 0x7a, 0x72, 0x6a, 0x6b, 0x75, 0x8b, + 0x94, 0x7d, 0x6a, 0x6a, 0x6f, 0x82, 0x85, 0x73, 0x6e, 0x74, 0x78, 0x7e, 0x96, 0xa5, 0x9d, 0x8a, + 0x7d, 0x84, 0x81, 0x87, 0x96, 0x98, 0x93, 0x90, 0x97, 0x97, 0x8d, 0x83, 0x7c, 0x7d, 0x83, 0x83, + 0x84, 0x84, 0x82, 0x80, 0x89, 0x88, 0x89, 0x8b, 0x87, 0x84, 0x85, 0x92, 0x9e, 0xa4, 0xa9, 0x92, + 0x68, 0x55, 0x65, 0x7d, 0x7d, 0x7b, 0x80, 0x80, 0x74, 0x70, 0x8f, 0x9a, 0xa1, 0xa2, 0x9d, 0x96, + 0x89, 0x86, 0x89, 0x7a, 0x6c, 0x77, 0x82, 0x84, 0x88, 0x95, 0x9b, 0x88, 0x79, 0x6f, 0x5f, 0x53, + 0x52, 0x54, 0x53, 0x4d, 0x50, 0x54, 0x4f, 0x48, 0x42, 0x3b, 0x48, 0x6e, 0x84, 0x72, 0x60, 0x5f, + 0x69, 0x7e, 0x84, 0x95, 0xa1, 0xa2, 0xa0, 0xa1, 0xae, 0xae, 0xa2, 0x90, 0x74, 0x62, 0x63, 0x6b, + 0x6b, 0x5f, 0x64, 0x6e, 0x71, 0x71, 0x66, 0x63, 0x65, 0x6f, 0x79, 0x7b, 0x72, 0x6a, 0x64, 0x68, + 0x76, 0x73, 0x6d, 0x6b, 0x71, 0x71, 0x74, 0x84, 0x8d, 0x92, 0x91, 0x78, 0x76, 0x82, 0x8f, 0x93, + 0x8d, 0x89, 0x81, 0x81, 0x73, 0x63, 0x75, 0x93, 0xa3, 0x9d, 0x98, 0x94, 0x88, 0x8b, 0x98, 0x90, + 0x8d, 0xa0, 0xad, 0xae, 0xab, 0xb3, 0xb8, 0xa5, 0x97, 0x8e, 0x7b, 0x6e, 0x6b, 0x73, 0x75, 0x70, + 0x6e, 0x6a, 0x61, 0x56, 0x5c, 0x72, 0x8b, 0x9e, 0x9e, 0x83, 0x6c, 0x60, 0x71, 0x7c, 0x74, 0x80, + 0x94, 0x96, 0x8d, 0x96, 0xb5, 0xc3, 0xb2, 0x9b, 0x80, 0x72, 0x73, 0x77, 0x77, 0x6f, 0x71, 0x75, + 0x78, 0x70, 0x5e, 0x56, 0x4f, 0x53, 0x64, 0x67, 0x5f, 0x5a, 0x60, 0x6e, 0x7c, 0x90, 0xa4, 0xa7, + 0x9d, 0x97, 0xa6, 0xb7, 0xb5, 0xb3, 0xa0, 0x78, 0x71, 0x72, 0x70, 0x71, 0x76, 0x77, 0x75, 0x76, + 0x6c, 0x62, 0x7e, 0xa1, 0xa9, 0xa2, 0x93, 0x88, 0x7c, 0x85, 0x93, 0x9b, 0x9f, 0x90, 0x91, 0x95, + 0x8e, 0x8e, 0x8e, 0x80, 0x77, 0x76, 0x7e, 0x92, 0x90, 0x89, 0x8f, 0x98, 0x9b, 0x97, 0x90, 0x7c, + 0x7c, 0x97, 0xad, 0xb2, 0xa8, 0x90, 0x75, 0x6b, 0x7d, 0x85, 0x83, 0x85, 0x86, 0x7c, 0x6e, 0x70, + 0x8d, 0x97, 0x85, 0x79, 0x72, 0x64, 0x54, 0x53, 0x5b, 0x64, 0x63, 0x64, 0x67, 0x64, 0x5c, 0x69, + 0x82, 0x87, 0x81, 0x75, 0x6d, 0x5e, 0x60, 0x6b, 0x6a, 0x7b, 0x89, 0x82, 0x72, 0x6b, 0x7b, 0x82, + 0x77, 0x77, 0x69, 0x52, 0x4c, 0x52, 0x51, 0x4e, 0x4d, 0x4c, 0x4e, 0x4d, 0x4b, 0x4e, 0x62, 0x6f, + 0x72, 0x6e, 0x66, 0x57, 0x4b, 0x59, 0x6a, 0x7e, 0xa5, 0xb0, 0x9f, 0x90, 0x8c, 0x90, 0x85, 0x7b, + 0x77, 0x72, 0x7b, 0x8a, 0x8d, 0x7e, 0x84, 0x8f, 0x8b, 0x86, 0x77, 0x62, 0x65, 0x7e, 0x9b, 0xaa, + 0x9e, 0x82, 0x71, 0x6e, 0x7a, 0x8c, 0x99, 0x9a, 0x83, 0x7c, 0x8c, 0x9c, 0xa8, 0xaf, 0xa5, 0x95, + 0x99, 0xa2, 0x9a, 0x84, 0x77, 0x81, 0x8c, 0x8d, 0x8a, 0x78, 0x68, 0x73, 0x87, 0x92, 0x90, 0x92, + 0x93, 0x96, 0x9d, 0x9d, 0x99, 0xaa, 0xb3, 0xaa, 0xa2, 0x9f, 0xa0, 0x9d, 0x96, 0x97, 0x9b, 0x8e, + 0x74, 0x60, 0x5a, 0x62, 0x60, 0x5a, 0x58, 0x57, 0x57, 0x72, 0xa1, 0xb5, 0x9f, 0x82, 0x6b, 0x5f, + 0x56, 0x5e, 0x6a, 0x76, 0x8d, 0x8f, 0x81, 0x7c, 0x86, 0x87, 0x82, 0x7e, 0x7b, 0x7d, 0x86, 0x91, + 0x8e, 0x79, 0x76, 0x73, 0x69, 0x61, 0x57, 0x5b, 0x6c, 0x75, 0x7a, 0x8a, 0x8a, 0x6e, 0x5b, 0x57, + 0x67, 0x7a, 0x88, 0x9a, 0x92, 0x84, 0x8b, 0x9f, 0xad, 0xa7, 0x97, 0x88, 0x82, 0x81, 0x73, 0x63, + 0x6d, 0x89, 0x91, 0x90, 0x8d, 0x81, 0x77, 0x80, 0x96, 0xa2, 0x9d, 0x90, 0x8d, 0x94, 0x93, 0x90, + 0x98, 0xa0, 0x89, 0x6a, 0x6d, 0x81, 0x84, 0x80, 0x7d, 0x90, 0x9e, 0x9f, 0xa6, 0x99, 0x89, 0x88, + 0x7b, 0x77, 0x76, 0x73, 0x6e, 0x80, 0x9d, 0xaa, 0xa2, 0x94, 0x86, 0x7b, 0x72, 0x72, 0x7b, 0x88, + 0x93, 0x8d, 0x81, 0x80, 0x77, 0x66, 0x5e, 0x58, 0x5c, 0x6a, 0x70, 0x66, 0x50, 0x4a, 0x5d, 0x66, + 0x5a, 0x52, 0x4e, 0x58, 0x73, 0x96, 0x9c, 0x9a, 0x87, 0x68, 0x5b, 0x53, 0x59, 0x58, 0x57, 0x5f, + 0x55, 0x52, 0x65, 0x7b, 0x82, 0x7d, 0x75, 0x70, 0x6b, 0x68, 0x62, 0x63, 0x70, 0x7c, 0x7e, 0x78, + 0x6d, 0x5f, 0x61, 0x69, 0x6e, 0x73, 0x75, 0x72, 0x7a, 0x82, 0x80, 0x84, 0x9d, 0xb7, 0xbb, 0x9f, + 0x94, 0x9d, 0xa6, 0xa7, 0x9c, 0xaa, 0xae, 0xa3, 0x9b, 0x87, 0x7d, 0x76, 0x71, 0x72, 0x73, 0x70, + 0x72, 0x84, 0x9f, 0xb1, 0xa8, 0x91, 0x7c, 0x75, 0x76, 0x81, 0x8e, 0xa5, 0xa8, 0x95, 0x84, 0x8c, + 0x92, 0x85, 0x70, 0x67, 0x6f, 0x7a, 0x88, 0x8c, 0x6d, 0x59, 0x5d, 0x67, 0x64, 0x4f, 0x4b, 0x5b, + 0x75, 0x93, 0xa2, 0xa7, 0x94, 0x84, 0x82, 0x83, 0x86, 0x83, 0x83, 0x88, 0x90, 0x91, 0xa1, 0xa8, + 0x9f, 0x8f, 0x83, 0x83, 0x80, 0x73, 0x5d, 0x5d, 0x6b, 0x7a, 0x83, 0x7e, 0x6e, 0x67, 0x70, 0x88, + 0x9f, 0x98, 0x80, 0x76, 0x86, 0x8a, 0x75, 0x6d, 0x81, 0x91, 0x8b, 0x80, 0x7e, 0x87, 0x8b, 0x8c, + 0x8a, 0x96, 0x92, 0x7e, 0x6b, 0x5f, 0x5e, 0x5a, 0x51, 0x56, 0x54, 0x49, 0x54, 0x6f, 0x82, 0x81, + 0x78, 0x6c, 0x6a, 0x72, 0x79, 0x82, 0x91, 0xa8, 0xb6, 0xbf, 0xaa, 0x94, 0x97, 0x99, 0x89, 0x7c, + 0x87, 0x90, 0x97, 0x8f, 0x77, 0x68, 0x6b, 0x76, 0x77, 0x6e, 0x72, 0x7e, 0x95, 0xad, 0xbd, 0xc7, + 0xbb, 0xac, 0x9e, 0x9c, 0x98, 0x94, 0x95, 0x97, 0x91, 0x8b, 0x9e, 0xb2, 0xac, 0x9c, 0x97, 0x94, + 0x8f, 0x93, 0x95, 0x81, 0x78, 0x85, 0x92, 0x80, 0x61, 0x62, 0x6f, 0x85, 0x91, 0x90, 0x7a, 0x6e, + 0x77, 0x7d, 0x75, 0x6d, 0x72, 0x6f, 0x67, 0x61, 0x5f, 0x6b, 0x6a, 0x62, 0x6f, 0x89, 0x87, 0x76, + 0x63, 0x43, 0x34, 0x3b, 0x46, 0x52, 0x49, 0x41, 0x4f, 0x6e, 0x8d, 0x98, 0x7d, 0x62, 0x64, 0x70, + 0x71, 0x69, 0x6c, 0x79, 0x7c, 0x7b, 0x76, 0x69, 0x68, 0x67, 0x6b, 0x76, 0x82, 0x89, 0x85, 0x76, + 0x61, 0x61, 0x6f, 0x72, 0x68, 0x60, 0x65, 0x73, 0x88, 0x92, 0x8f, 0x8c, 0x80, 0x7a, 0x79, 0x7c, + 0x77, 0x75, 0x7d, 0x98, 0xa4, 0x91, 0x9b, 0xaf, 0xa6, 0x8e, 0x88, 0x89, 0x87, 0x89, 0x86, 0x7e, + 0x76, 0x72, 0x72, 0x6b, 0x61, 0x64, 0x6f, 0x7a, 0x87, 0x8c, 0x86, 0x8a, 0x8f, 0x90, 0x8a, 0x84, + 0x8b, 0x90, 0x8e, 0x84, 0x7a, 0x85, 0x8c, 0x8d, 0x9c, 0xa8, 0x9b, 0x89, 0x82, 0x71, 0x58, 0x57, + 0x60, 0x61, 0x4d, 0x48, 0x5e, 0x77, 0x8b, 0x90, 0x8b, 0x78, 0x75, 0x83, 0x98, 0xa2, 0xa1, 0x9d, + 0x97, 0x97, 0x95, 0x98, 0x98, 0x86, 0x81, 0x8b, 0x8f, 0x8d, 0x84, 0x6c, 0x48, 0x47, 0x5d, 0x67, + 0x66, 0x6a, 0x6b, 0x78, 0x8b, 0xa6, 0xbb, 0xac, 0x92, 0x8b, 0x81, 0x71, 0x70, 0x68, 0x73, 0x86, + 0x8b, 0x98, 0xa0, 0x96, 0x8f, 0x91, 0x9b, 0xa8, 0x9f, 0x92, 0x8c, 0x87, 0x90, 0x8f, 0x82, 0x7d, + 0x78, 0x77, 0x81, 0x84, 0x85, 0x7a, 0x75, 0x7c, 0x82, 0x83, 0x82, 0x7e, 0x7d, 0x82, 0x8e, 0x8d, + 0x89, 0x8b, 0x8a, 0x85, 0x88, 0x92, 0x82, 0x6e, 0x5f, 0x50, 0x51, 0x52, 0x55, 0x5e, 0x6a, 0x7b, + 0x91, 0x98, 0x98, 0x98, 0x9f, 0xaa, 0xa4, 0x9c, 0xa4, 0xa4, 0x9b, 0x97, 0x98, 0x8e, 0x7c, 0x80, + 0x7d, 0x76, 0x76, 0x7b, 0x83, 0x7e, 0x74, 0x72, 0x60, 0x5a, 0x68, 0x6d, 0x64, 0x5b, 0x5c, 0x67, + 0x75, 0x90, 0xa7, 0xa3, 0x8b, 0x75, 0x6a, 0x6c, 0x71, 0x6c, 0x66, 0x67, 0x65, 0x7d, 0x97, 0x86, + 0x73, 0x6c, 0x77, 0x82, 0x7b, 0x72, 0x62, 0x52, 0x57, 0x5f, 0x5e, 0x62, 0x60, 0x5d, 0x63, 0x6b, + 0x84, 0x7d, 0x70, 0x74, 0x74, 0x75, 0x6d, 0x6c, 0x6e, 0x75, 0x86, 0x92, 0x9d, 0x95, 0x8b, 0x95, + 0xab, 0xba, 0xaa, 0x8d, 0x72, 0x69, 0x73, 0x79, 0x6f, 0x68, 0x6a, 0x72, 0x7e, 0x83, 0x84, 0x7e, + 0x75, 0x7c, 0x85, 0x87, 0x8f, 0x92, 0x92, 0x90, 0x97, 0xa9, 0xa8, 0xa9, 0x99, 0x8b, 0x86, 0x7c, + 0x72, 0x68, 0x62, 0x60, 0x61, 0x66, 0x61, 0x56, 0x5c, 0x6a, 0x6f, 0x76, 0x7a, 0x84, 0x92, 0x98, + 0x8e, 0x7e, 0x71, 0x74, 0x80, 0x79, 0x70, 0x74, 0x72, 0x87, 0x99, 0x8a, 0x82, 0x7b, 0x84, 0x88, + 0x83, 0x7e, 0x87, 0x86, 0x87, 0x86, 0x83, 0x85, 0x76, 0x6d, 0x6c, 0x79, 0x90, 0x96, 0x90, 0x8e, + 0x8d, 0x94, 0x9e, 0xa9, 0xa3, 0x96, 0x96, 0xa1, 0xb8, 0xaf, 0xa0, 0xa0, 0xa0, 0x9b, 0x85, 0x6e, + 0x55, 0x4b, 0x51, 0x54, 0x4c, 0x4f, 0x59, 0x64, 0x6c, 0x73, 0x83, 0x8e, 0x87, 0x90, 0x97, 0x91, + 0x8f, 0x89, 0x82, 0x72, 0x7a, 0x8a, 0x96, 0x93, 0x76, 0x6f, 0x78, 0x82, 0x84, 0x82, 0x73, 0x67, + 0x71, 0x88, 0x87, 0x75, 0x6e, 0x69, 0x67, 0x69, 0x76, 0x7e, 0x7b, 0x76, 0x6f, 0x69, 0x68, 0x6a, + 0x6c, 0x5d, 0x57, 0x71, 0x8c, 0xa7, 0xb0, 0xa1, 0x9a, 0x92, 0x88, 0x82, 0x7e, 0x80, 0x87, 0x92, + 0x8f, 0x7d, 0x76, 0x7e, 0x82, 0x85, 0x8b, 0x8f, 0x96, 0xa5, 0xb1, 0xb2, 0xad, 0xa6, 0x9f, 0x97, + 0x82, 0x7b, 0x7b, 0x83, 0x98, 0x98, 0x98, 0x9e, 0xa2, 0x95, 0x79, 0x6b, 0x68, 0x70, 0x71, 0x65, + 0x5b, 0x65, 0x6f, 0x76, 0x7a, 0x7a, 0x84, 0x86, 0x83, 0x81, 0x7b, 0x79, 0x83, 0x8f, 0x8c, 0x83, + 0x80, 0x85, 0x9c, 0xa3, 0x92, 0x84, 0x82, 0x7b, 0x6b, 0x64, 0x61, 0x5b, 0x5c, 0x66, 0x60, 0x5d, + 0x62, 0x63, 0x68, 0x72, 0x83, 0x8a, 0x8d, 0x88, 0x7d, 0x79, 0x81, 0x87, 0x77, 0x5a, 0x55, 0x6f, + 0x90, 0xa5, 0x98, 0x88, 0x7b, 0x78, 0x7c, 0x7d, 0x7b, 0x6f, 0x74, 0x8b, 0x90, 0x85, 0x7b, 0x73, + 0x6b, 0x6a, 0x68, 0x6b, 0x6c, 0x63, 0x6a, 0x74, 0x7e, 0x8a, 0x8b, 0x81, 0x76, 0x78, 0x81, 0x96, + 0xa0, 0xa1, 0xa4, 0x9c, 0x91, 0x76, 0x58, 0x51, 0x5e, 0x67, 0x61, 0x48, 0x3f, 0x49, 0x5e, 0x71, + 0x7e, 0x80, 0x75, 0x73, 0x81, 0x90, 0x97, 0x99, 0x99, 0x91, 0x85, 0x78, 0x74, 0x74, 0x7a, 0x80, + 0x7a, 0x7e, 0x86, 0x7c, 0x6f, 0x6c, 0x6f, 0x73, 0x7c, 0x80, 0x7c, 0x7d, 0x7d, 0x78, 0x7d, 0x8c, + 0x9b, 0xa3, 0xa1, 0x9a, 0x8f, 0x89, 0x8b, 0x8c, 0x7e, 0x6e, 0x71, 0x83, 0xa4, 0xb7, 0xb0, 0xa9, + 0x98, 0x82, 0x72, 0x6e, 0x6e, 0x6a, 0x6e, 0x76, 0x7b, 0x77, 0x79, 0x7c, 0x7a, 0x7e, 0x80, 0x7d, + 0x81, 0x86, 0x8f, 0x98, 0xa1, 0x9f, 0x8e, 0x7b, 0x73, 0x80, 0x8a, 0x92, 0x97, 0x99, 0x96, 0x86, + 0x80, 0x70, 0x69, 0x6a, 0x6d, 0x79, 0x78, 0x6c, 0x6c, 0x72, 0x7a, 0x7e, 0x85, 0x81, 0x75, 0x69, + 0x6e, 0x81, 0x8c, 0x93, 0xa0, 0xa0, 0x96, 0x8e, 0x8e, 0x97, 0xa6, 0xa5, 0xa4, 0xa6, 0x9d, 0x86, + 0x73, 0x79, 0x8c, 0x91, 0x86, 0x7e, 0x7d, 0x71, 0x69, 0x72, 0x81, 0x94, 0x94, 0x90, 0x9c, 0xa5, + 0xa0, 0x9b, 0x96, 0x8d, 0x79, 0x66, 0x70, 0x7e, 0x87, 0x8f, 0x8c, 0x8e, 0x8b, 0x79, 0x69, 0x65, + 0x67, 0x66, 0x73, 0x81, 0x7d, 0x77, 0x76, 0x76, 0x6c, 0x65, 0x6f, 0x7b, 0x7e, 0x7a, 0x84, 0x87, + 0x86, 0x83, 0x77, 0x6e, 0x6d, 0x71, 0x6f, 0x7c, 0x8c, 0x8d, 0x89, 0x79, 0x70, 0x5e, 0x4a, 0x48, + 0x49, 0x45, 0x3a, 0x3c, 0x4c, 0x5f, 0x6f, 0x78, 0x7e, 0x7b, 0x6d, 0x70, 0x7d, 0x89, 0x8d, 0x8e, + 0x91, 0x88, 0x75, 0x76, 0x8b, 0x92, 0x91, 0x8e, 0x8a, 0x8a, 0x7e, 0x70, 0x68, 0x6f, 0x76, 0x77, + 0x74, 0x75, 0x7a, 0x76, 0x74, 0x7e, 0x8e, 0x95, 0x8d, 0x84, 0x8d, 0x87, 0x79, 0x78, 0x81, 0x83, + 0x7a, 0x72, 0x78, 0x77, 0x85, 0x97, 0x94, 0x97, 0x8d, 0x6c, 0x4f, 0x4e, 0x60, 0x6f, 0x77, 0x75, + 0x72, 0x69, 0x66, 0x70, 0x70, 0x70, 0x72, 0x70, 0x73, 0x7d, 0x8f, 0x9a, 0x97, 0x8d, 0x82, 0x7a, + 0x77, 0x7a, 0x7b, 0x83, 0x84, 0x88, 0x92, 0x98, 0x9f, 0x91, 0x82, 0x83, 0x83, 0x92, 0x9b, 0x99, + 0x9c, 0x99, 0x92, 0x8c, 0x93, 0xa0, 0x9e, 0x99, 0x9d, 0xa2, 0x99, 0x95, 0x9b, 0x9b, 0x91, 0x8d, + 0x92, 0x98, 0x98, 0x96, 0x9b, 0x98, 0x88, 0x76, 0x74, 0x78, 0x7a, 0x71, 0x5f, 0x50, 0x4c, 0x51, + 0x61, 0x69, 0x6b, 0x68, 0x5e, 0x5e, 0x85, 0x8a, 0x77, 0x6f, 0x6c, 0x68, 0x5c, 0x5b, 0x71, 0x76, + 0x7b, 0x88, 0x95, 0x98, 0x89, 0x79, 0x6d, 0x6c, 0x71, 0x77, 0x80, 0x83, 0x84, 0x84, 0x8a, 0x95, + 0x90, 0x8d, 0x89, 0x87, 0x89, 0x8c, 0x8c, 0x91, 0x97, 0x97, 0x91, 0x88, 0x86, 0x88, 0x88, 0x9c, + 0xa1, 0x9f, 0x9d, 0x95, 0x89, 0x6c, 0x63, 0x6a, 0x6d, 0x75, 0x7c, 0x78, 0x76, 0x7b, 0x83, 0x89, + 0x8d, 0x8c, 0x86, 0x87, 0x8f, 0x95, 0x97, 0x91, 0x95, 0x94, 0x88, 0x84, 0x85, 0x8a, 0x7d, 0x6c, + 0x71, 0x73, 0x6f, 0x63, 0x61, 0x65, 0x69, 0x63, 0x6a, 0x6f, 0x6d, 0x73, 0x74, 0x66, 0x5f, 0x61, + 0x6a, 0x76, 0x8d, 0x93, 0x8a, 0x7d, 0x7b, 0x85, 0x7e, 0x6d, 0x6f, 0x74, 0x7c, 0x82, 0x8b, 0x8f, + 0x82, 0x74, 0x68, 0x67, 0x67, 0x69, 0x6f, 0x6b, 0x6a, 0x77, 0x89, 0x92, 0x88, 0x80, 0x82, 0x85, + 0x8a, 0xa5, 0xb2, 0xad, 0xa2, 0x8f, 0x80, 0x78, 0x7e, 0x8a, 0x8a, 0x8d, 0x8e, 0x8b, 0x82, 0x7d, + 0x7e, 0x69, 0x5c, 0x60, 0x66, 0x69, 0x6a, 0x68, 0x74, 0x7d, 0x80, 0x80, 0x80, 0x79, 0x73, 0x72, + 0x70, 0x6e, 0x72, 0x76, 0x86, 0x8b, 0x88, 0x8e, 0x8f, 0x96, 0xa3, 0x9e, 0x98, 0x8f, 0x7c, 0x69, + 0x66, 0x74, 0x74, 0x60, 0x57, 0x5e, 0x67, 0x6b, 0x69, 0x65, 0x60, 0x5a, 0x63, 0x73, 0x85, 0x87, + 0x89, 0x89, 0x87, 0x90, 0x8d, 0x82, 0x85, 0x87, 0x93, 0x8f, 0x8b, 0x8d, 0x81, 0x75, 0x67, 0x61, + 0x63, 0x65, 0x73, 0x91, 0x9b, 0x9d, 0xa0, 0x97, 0x84, 0x79, 0x84, 0x8e, 0x8d, 0x8d, 0x99, 0xa2, + 0x98, 0x89, 0x8c, 0x8a, 0x8a, 0x8f, 0x92, 0x96, 0x8d, 0x8c, 0x91, 0x8c, 0x8d, 0x7c, 0x71, 0x6d, + 0x69, 0x69, 0x5f, 0x5f, 0x70, 0x79, 0x7d, 0x7a, 0x73, 0x6d, 0x69, 0x6f, 0x85, 0x88, 0x7c, 0x74, + 0x79, 0x7c, 0x79, 0x8a, 0x93, 0x95, 0x8c, 0x87, 0x8c, 0x84, 0x7a, 0x7a, 0x78, 0x79, 0x7b, 0x6f, + 0x6a, 0x6f, 0x7c, 0x8a, 0x88, 0x82, 0x79, 0x75, 0x78, 0x7e, 0x8a, 0x7d, 0x76, 0x7b, 0x83, 0x8c, + 0x81, 0x73, 0x76, 0x7e, 0x9e, 0xb6, 0xb0, 0xa0, 0x84, 0x75, 0x6f, 0x66, 0x6f, 0x78, 0x79, 0x7e, + 0x8e, 0x97, 0x98, 0x90, 0x86, 0x7d, 0x7a, 0x88, 0x92, 0x96, 0x9f, 0xa8, 0xa6, 0x9c, 0x9b, 0x94, + 0x93, 0x92, 0x91, 0x8f, 0x79, 0x76, 0x80, 0x7e, 0x83, 0x75, 0x5f, 0x5a, 0x5e, 0x69, 0x7b, 0x7e, + 0x74, 0x6e, 0x76, 0x7e, 0x78, 0x79, 0x78, 0x73, 0x75, 0x7e, 0x84, 0x8a, 0x96, 0x99, 0x90, 0x93, + 0x9f, 0xa2, 0x97, 0x8f, 0x94, 0x8f, 0x83, 0x83, 0x82, 0x79, 0x6f, 0x61, 0x5f, 0x63, 0x71, 0x7c, + 0x79, 0x70, 0x69, 0x62, 0x67, 0x76, 0x93, 0x9c, 0x8f, 0x82, 0x7c, 0x86, 0x7b, 0x6f, 0x74, 0x81, + 0x8c, 0x88, 0x80, 0x74, 0x64, 0x5a, 0x5d, 0x57, 0x5f, 0x71, 0x73, 0x77, 0x88, 0x94, 0x93, 0x83, + 0x79, 0x72, 0x6a, 0x66, 0x69, 0x6e, 0x6e, 0x76, 0x77, 0x76, 0x7c, 0x78, 0x76, 0x7a, 0x83, 0x8d, + 0x8f, 0x86, 0x79, 0x6e, 0x74, 0x6a, 0x57, 0x5c, 0x5b, 0x52, 0x51, 0x57, 0x62, 0x6e, 0x75, 0x79, + 0x6c, 0x68, 0x6c, 0x6d, 0x7b, 0x92, 0x9d, 0xa0, 0xa6, 0xa6, 0xa6, 0xa5, 0xa1, 0xa6, 0x9d, 0x8a, + 0x87, 0x8a, 0x8a, 0x8d, 0x8a, 0x82, 0x7e, 0x77, 0x85, 0x9c, 0x99, 0x88, 0x74, 0x6e, 0x6b, 0x68, + 0x73, 0x7c, 0x88, 0x86, 0x83, 0x86, 0x8b, 0x91, 0x85, 0x73, 0x7d, 0x9b, 0xa3, 0x9e, 0x96, 0x8f, + 0x80, 0x6e, 0x71, 0x75, 0x72, 0x71, 0x6f, 0x72, 0x77, 0x81, 0x85, 0x7b, 0x77, 0x6e, 0x67, 0x69, + 0x7d, 0x9a, 0xab, 0xa0, 0x8c, 0x87, 0x8d, 0x88, 0x81, 0x80, 0x7e, 0x78, 0x71, 0x71, 0x74, 0x70, + 0x74, 0x71, 0x65, 0x6b, 0x6e, 0x67, 0x69, 0x6f, 0x84, 0x93, 0x90, 0x8e, 0x83, 0x74, 0x6a, 0x73, + 0x83, 0x84, 0x89, 0x96, 0xa3, 0xa0, 0xa0, 0xa1, 0xa5, 0xb3, 0xb8, 0xb5, 0x9f, 0x8b, 0x88, 0x8c, + 0x8c, 0x89, 0x84, 0x73, 0x74, 0x7b, 0x7d, 0x82, 0x78, 0x73, 0x75, 0x72, 0x79, 0x83, 0x94, 0x9a, + 0x9b, 0xa3, 0xa7, 0xa3, 0x94, 0x89, 0x8b, 0x99, 0x9d, 0x8c, 0x77, 0x6c, 0x61, 0x5c, 0x65, 0x6c, + 0x6c, 0x69, 0x6e, 0x84, 0x9b, 0x97, 0x91, 0x88, 0x82, 0x79, 0x74, 0x77, 0x82, 0x8d, 0x8f, 0x8f, + 0x8f, 0x8b, 0x88, 0x7b, 0x70, 0x78, 0x81, 0x7b, 0x7c, 0x80, 0x7c, 0x76, 0x78, 0x72, 0x6c, 0x5f, + 0x4f, 0x4f, 0x54, 0x52, 0x68, 0x77, 0x74, 0x6e, 0x64, 0x5a, 0x59, 0x70, 0x8d, 0x9a, 0x8e, 0x88, + 0x88, 0x86, 0x89, 0x8a, 0x8e, 0x8d, 0x7a, 0x70, 0x6b, 0x61, 0x61, 0x68, 0x6d, 0x6c, 0x65, 0x59, + 0x5b, 0x64, 0x6d, 0x7b, 0x70, 0x64, 0x63, 0x60, 0x5b, 0x6a, 0x89, 0x8c, 0x7b, 0x79, 0x7b, 0x79, + 0x71, 0x6f, 0x7b, 0x92, 0x9c, 0x99, 0x9a, 0x84, 0x6d, 0x6b, 0x74, 0x7e, 0x7c, 0x70, 0x69, 0x73, + 0x82, 0x90, 0x93, 0x87, 0x82, 0x78, 0x70, 0x7b, 0x95, 0xa8, 0xad, 0xac, 0xaf, 0xa3, 0x92, 0x83, + 0x80, 0x8b, 0x92, 0x91, 0x8f, 0x8c, 0x83, 0x84, 0x97, 0x97, 0x8f, 0x76, 0x62, 0x69, 0x77, 0x80, + 0x84, 0x7e, 0x6b, 0x63, 0x5f, 0x5b, 0x64, 0x73, 0x82, 0x8b, 0x8f, 0x96, 0x96, 0x95, 0x93, 0x96, + 0x9f, 0x9f, 0x92, 0x8b, 0x8c, 0x89, 0x85, 0x85, 0x84, 0x80, 0x6c, 0x55, 0x57, 0x5a, 0x58, 0x63, + 0x60, 0x5e, 0x5d, 0x58, 0x59, 0x74, 0x9a, 0xa3, 0xa0, 0x8f, 0x87, 0x7e, 0x77, 0x78, 0x89, 0x99, + 0x8e, 0x7e, 0x84, 0x83, 0x76, 0x7a, 0x86, 0x8b, 0x85, 0x75, 0x78, 0x88, 0x91, 0x9f, 0xa0, 0x8f, + 0x7c, 0x6a, 0x65, 0x77, 0x8a, 0x95, 0x99, 0x95, 0x9b, 0x94, 0x8c, 0x88, 0x8d, 0x98, 0x9f, 0xa0, + 0xa0, 0xa9, 0x98, 0x90, 0xa1, 0xa0, 0x91, 0x76, 0x5f, 0x61, 0x65, 0x6f, 0x82, 0x83, 0x6f, 0x63, + 0x5c, 0x5d, 0x6e, 0x84, 0x8f, 0x94, 0x9c, 0xa6, 0x9d, 0x91, 0x8a, 0x8f, 0x97, 0x8e, 0x7a, 0x6d, + 0x66, 0x64, 0x65, 0x6c, 0x6b, 0x66, 0x53, 0x46, 0x54, 0x65, 0x7c, 0x7d, 0x6d, 0x63, 0x60, 0x60, + 0x61, 0x76, 0x8e, 0x88, 0x7e, 0x7b, 0x79, 0x73, 0x71, 0x74, 0x86, 0x92, 0x84, 0x79, 0x78, 0x77, + 0x71, 0x70, 0x76, 0x79, 0x73, 0x6a, 0x6c, 0x77, 0x81, 0x86, 0x89, 0x83, 0x77, 0x6c, 0x6f, 0x80, + 0x9b, 0xa7, 0xac, 0xb8, 0xa9, 0x90, 0x88, 0x8e, 0x97, 0x9e, 0x98, 0x86, 0x7e, 0x85, 0x82, 0x85, + 0x94, 0x90, 0x82, 0x72, 0x68, 0x74, 0x7c, 0x83, 0x92, 0x8d, 0x78, 0x6a, 0x62, 0x65, 0x6e, 0x79, + 0x7d, 0x7d, 0x7a, 0x82, 0x83, 0x80, 0x84, 0x8e, 0x99, 0x98, 0x8b, 0x8e, 0xa0, 0x94, 0x83, 0x81, + 0x82, 0x7d, 0x63, 0x4a, 0x50, 0x60, 0x72, 0x7b, 0x70, 0x64, 0x5c, 0x5b, 0x62, 0x87, 0xad, 0xa5, + 0x92, 0x8d, 0x89, 0x80, 0x77, 0x76, 0x86, 0x88, 0x78, 0x72, 0x6f, 0x66, 0x60, 0x5e, 0x65, 0x70, + 0x6e, 0x66, 0x68, 0x74, 0x8c, 0x9d, 0x90, 0x79, 0x67, 0x61, 0x65, 0x6d, 0x79, 0x7c, 0x7b, 0x88, + 0x8c, 0x7e, 0x79, 0x80, 0x87, 0x90, 0x97, 0x99, 0x98, 0x91, 0x88, 0x8c, 0x95, 0x8c, 0x81, 0x6f, + 0x5c, 0x5f, 0x69, 0x6e, 0x6d, 0x68, 0x5e, 0x52, 0x53, 0x5a, 0x69, 0x7a, 0x84, 0x9c, 0xa9, 0x9a, + 0x8c, 0x89, 0x90, 0x95, 0x95, 0x8d, 0x80, 0x7e, 0x89, 0x8b, 0x7d, 0x74, 0x75, 0x79, 0x68, 0x5d, + 0x72, 0x82, 0x83, 0x82, 0x7b, 0x75, 0x6f, 0x6e, 0x75, 0x8c, 0x9f, 0x9b, 0x95, 0x8b, 0x8b, 0x94, + 0x98, 0x9b, 0xa7, 0xa9, 0xa0, 0x9e, 0xb0, 0xb0, 0x95, 0x7d, 0x78, 0x8a, 0x83, 0x6b, 0x6b, 0x73, + 0x7d, 0x8d, 0x96, 0x8b, 0x76, 0x6e, 0x76, 0x85, 0x98, 0xa1, 0x9c, 0x9e, 0xa0, 0x96, 0x9a, 0x9a, + 0x94, 0x93, 0x8a, 0x83, 0x84, 0x79, 0x68, 0x72, 0x80, 0x81, 0x80, 0x6e, 0x69, 0x73, 0x81, 0x98, + 0x9e, 0x86, 0x69, 0x5d, 0x63, 0x6a, 0x6f, 0x72, 0x74, 0x83, 0x93, 0x9d, 0x9b, 0x97, 0x92, 0x9a, + 0xa2, 0xa2, 0xa3, 0xa1, 0x98, 0x91, 0x88, 0x7c, 0x7b, 0x78, 0x65, 0x58, 0x63, 0x6e, 0x6d, 0x65, + 0x64, 0x65, 0x66, 0x63, 0x6d, 0x8a, 0x9c, 0x9b, 0xa1, 0x98, 0x7d, 0x73, 0x6f, 0x6d, 0x72, 0x6a, + 0x5d, 0x55, 0x5d, 0x65, 0x66, 0x5d, 0x60, 0x72, 0x6e, 0x66, 0x76, 0x84, 0x87, 0x87, 0x88, 0x7e, + 0x76, 0x70, 0x70, 0x79, 0x79, 0x73, 0x71, 0x74, 0x6d, 0x64, 0x70, 0x71, 0x6b, 0x73, 0x79, 0x7e, + 0x89, 0x91, 0x8c, 0x89, 0x85, 0x7e, 0x81, 0x68, 0x56, 0x55, 0x4f, 0x56, 0x64, 0x62, 0x53, 0x4f, + 0x57, 0x63, 0x6c, 0x7c, 0x92, 0x94, 0x8c, 0x91, 0x95, 0x94, 0x8b, 0x92, 0x9a, 0x8f, 0x86, 0x87, + 0x83, 0x78, 0x73, 0x6d, 0x75, 0x78, 0x6a, 0x68, 0x77, 0x8a, 0x95, 0x8e, 0x76, 0x68, 0x66, 0x6b, + 0x75, 0x89, 0x98, 0x8d, 0x87, 0x8e, 0x93, 0x90, 0x8c, 0x89, 0x95, 0x92, 0x8e, 0x96, 0x94, 0x8a, + 0x8c, 0x8c, 0x8b, 0x91, 0x87, 0x80, 0x7b, 0x74, 0x79, 0x7d, 0x74, 0x6c, 0x6e, 0x70, 0x72, 0x7a, + 0x84, 0x94, 0xa3, 0xae, 0xa7, 0x8f, 0x8d, 0x90, 0x95, 0x99, 0x93, 0x86, 0x75, 0x75, 0x88, 0x9d, + 0x9f, 0x92, 0x8d, 0x7e, 0x76, 0x7b, 0x82, 0x84, 0x80, 0x7b, 0x7c, 0x85, 0x84, 0x86, 0x8a, 0x86, + 0x8e, 0x95, 0x8f, 0x91, 0x93, 0x92, 0x92, 0x98, 0xa0, 0xa0, 0xa2, 0xa8, 0xaf, 0xa2, 0x89, 0x78, + 0x82, 0x89, 0x74, 0x66, 0x65, 0x63, 0x6b, 0x74, 0x72, 0x67, 0x60, 0x6c, 0x86, 0x9b, 0xb0, 0xac, + 0x98, 0x90, 0x98, 0x9a, 0x93, 0x8b, 0x8a, 0x7e, 0x6c, 0x6b, 0x6c, 0x6b, 0x64, 0x5b, 0x5f, 0x68, + 0x5e, 0x63, 0x73, 0x7a, 0x86, 0x97, 0x8c, 0x75, 0x6b, 0x6f, 0x75, 0x72, 0x6d, 0x6b, 0x69, 0x69, + 0x70, 0x72, 0x6e, 0x6f, 0x82, 0x89, 0x82, 0x79, 0x7a, 0x7d, 0x87, 0x98, 0xa3, 0x96, 0x86, 0x76, + 0x69, 0x5f, 0x5b, 0x5c, 0x5d, 0x53, 0x4f, 0x54, 0x52, 0x5a, 0x6b, 0x7a, 0x89, 0x92, 0x98, 0x96, + 0x88, 0x77, 0x80, 0x8f, 0x85, 0x74, 0x6d, 0x6c, 0x70, 0x75, 0x73, 0x6e, 0x74, 0x7a, 0x79, 0x76, + 0x7c, 0x83, 0x7e, 0x79, 0x7a, 0x79, 0x75, 0x7b, 0x8d, 0x93, 0x96, 0x91, 0x8d, 0x8a, 0x80, 0x78, + 0x75, 0x7b, 0x82, 0x84, 0x8a, 0x90, 0x96, 0xa3, 0x9c, 0x8c, 0x89, 0x8a, 0x7d, 0x74, 0x71, 0x6b, + 0x66, 0x6b, 0x71, 0x72, 0x6b, 0x6f, 0x82, 0x8c, 0x8d, 0x98, 0x9e, 0x92, 0x8a, 0x90, 0x97, 0x97, + 0x9c, 0x90, 0x78, 0x65, 0x67, 0x78, 0x83, 0x85, 0x8a, 0x85, 0x78, 0x6d, 0x6e, 0x79, 0x7b, 0x7a, + 0x86, 0x7d, 0x6c, 0x67, 0x6f, 0x7c, 0x7c, 0x7c, 0x81, 0x7e, 0x7e, 0x89, 0x8d, 0x84, 0x92, 0xa5, + 0x9e, 0x92, 0x8b, 0x8e, 0x88, 0x81, 0x89, 0x92, 0x8d, 0x7b, 0x6f, 0x66, 0x67, 0x6b, 0x6a, 0x68, + 0x5c, 0x51, 0x56, 0x6a, 0x80, 0x9a, 0xb0, 0xab, 0xa8, 0xaa, 0x99, 0x8d, 0x87, 0x90, 0x8e, 0x79, + 0x6d, 0x6b, 0x70, 0x79, 0x84, 0x85, 0x83, 0x84, 0x83, 0x87, 0x88, 0x84, 0x7d, 0x76, 0x71, 0x77, + 0x7b, 0x7b, 0x84, 0x83, 0x7c, 0x7d, 0x83, 0x87, 0x8b, 0x89, 0x86, 0x86, 0x8a, 0x7e, 0x7d, 0x7d, + 0x85, 0x98, 0xaa, 0xaa, 0xa9, 0x97, 0x84, 0x74, 0x65, 0x66, 0x64, 0x56, 0x59, 0x5a, 0x54, 0x57, + 0x6d, 0x87, 0x90, 0x8f, 0x8e, 0x8b, 0x81, 0x81, 0x92, 0x96, 0x99, 0x93, 0x7c, 0x6d, 0x65, 0x70, + 0x74, 0x70, 0x6b, 0x68, 0x64, 0x5a, 0x66, 0x77, 0x85, 0x7e, 0x7c, 0x8b, 0x80, 0x71, 0x6f, 0x84, + 0x94, 0x99, 0xa4, 0x9b, 0x8b, 0x84, 0x84, 0x89, 0x8d, 0x9c, 0x9d, 0x90, 0x85, 0x87, 0x91, 0x8f, + 0x97, 0xa3, 0xa3, 0x96, 0x87, 0x83, 0x80, 0x7b, 0x77, 0x76, 0x73, 0x67, 0x63, 0x6c, 0x76, 0x7a, + 0x82, 0x8a, 0x89, 0x92, 0xa6, 0xa1, 0x94, 0x85, 0x84, 0x75, 0x66, 0x61, 0x65, 0x6e, 0x79, 0x89, + 0x92, 0x8b, 0x7e, 0x77, 0x73, 0x75, 0x70, 0x63, 0x5d, 0x59, 0x5e, 0x67, 0x72, 0x79, 0x7a, 0x75, + 0x75, 0x7b, 0x7b, 0x78, 0x79, 0x77, 0x81, 0x7e, 0x76, 0x7b, 0x83, 0x8a, 0x93, 0x9a, 0x8e, 0x84, + 0x74, 0x6e, 0x77, 0x74, 0x73, 0x62, 0x53, 0x57, 0x5a, 0x5a, 0x66, 0x83, 0x95, 0x9c, 0xa6, 0xa0, + 0x90, 0x7b, 0x79, 0x86, 0x89, 0x85, 0x72, 0x5c, 0x56, 0x60, 0x6e, 0x73, 0x76, 0x77, 0x75, 0x70, + 0x69, 0x72, 0x82, 0x87, 0x81, 0x86, 0x8e, 0x81, 0x78, 0x75, 0x7a, 0x77, 0x71, 0x73, 0x70, 0x71, + 0x7b, 0x7e, 0x81, 0x86, 0x8c, 0x84, 0x7a, 0x73, 0x77, 0x80, 0x82, 0x89, 0x9e, 0x9a, 0x82, 0x6d, + 0x69, 0x6f, 0x6c, 0x62, 0x5c, 0x56, 0x55, 0x5c, 0x6c, 0x7b, 0x8a, 0x91, 0x96, 0x9a, 0xa1, 0xaa, + 0xa2, 0xa0, 0x9f, 0x98, 0x88, 0x80, 0x84, 0x81, 0x7d, 0x7b, 0x84, 0x8c, 0x8c, 0x95, 0x9e, 0x99, + 0x91, 0x82, 0x76, 0x72, 0x74, 0x76, 0x86, 0x98, 0x9d, 0xa1, 0xaa, 0xa6, 0x9d, 0x8c, 0x86, 0x8b, + 0x8e, 0x86, 0x7c, 0x7b, 0x81, 0x8d, 0x93, 0xa1, 0xad, 0xa3, 0x95, 0x86, 0x81, 0x7e, 0x80, 0x7d, + 0x6f, 0x67, 0x6e, 0x77, 0x7e, 0x8c, 0x9b, 0x9c, 0x9c, 0x9b, 0x9a, 0x9d, 0x99, 0x90, 0x96, 0xa2, + 0x9d, 0x8f, 0x81, 0x76, 0x7d, 0x86, 0x86, 0x8d, 0x9a, 0x85, 0x6e, 0x67, 0x73, 0x81, 0x7b, 0x6c, + 0x6e, 0x71, 0x62, 0x5e, 0x66, 0x74, 0x78, 0x72, 0x6f, 0x6d, 0x66, 0x66, 0x6d, 0x7e, 0x90, 0x95, + 0x90, 0x8b, 0x89, 0x84, 0x7d, 0x78, 0x80, 0x86, 0x85, 0x84, 0x77, 0x67, 0x5f, 0x59, 0x55, 0x54, + 0x52, 0x4d, 0x50, 0x5c, 0x6e, 0x8e, 0xa4, 0x9e, 0x90, 0x88, 0x8c, 0x87, 0x8a, 0x7e, 0x74, 0x67, + 0x5d, 0x63, 0x69, 0x6f, 0x75, 0x77, 0x73, 0x73, 0x74, 0x73, 0x79, 0x79, 0x71, 0x6b, 0x65, 0x6b, + 0x76, 0x7c, 0x79, 0x72, 0x73, 0x74, 0x81, 0x86, 0x7c, 0x6c, 0x6c, 0x6f, 0x6a, 0x6d, 0x73, 0x75, + 0x7e, 0x82, 0x94, 0xb0, 0xad, 0x93, 0x7e, 0x71, 0x6f, 0x6f, 0x67, 0x5a, 0x54, 0x4f, 0x53, 0x61, + 0x77, 0x89, 0x91, 0x90, 0x92, 0x90, 0x80, 0x74, 0x77, 0x8e, 0x98, 0x88, 0x75, 0x6e, 0x70, 0x76, + 0x77, 0x77, 0x79, 0x77, 0x73, 0x7a, 0x7e, 0x82, 0x81, 0x82, 0x80, 0x84, 0x8b, 0x7b, 0x78, 0x7d, + 0x90, 0xa6, 0xa8, 0x99, 0x88, 0x79, 0x78, 0x85, 0x96, 0x96, 0x94, 0x89, 0x81, 0x88, 0x8d, 0x90, + 0x90, 0x8f, 0x90, 0x93, 0x88, 0x78, 0x7e, 0x81, 0x83, 0x7e, 0x73, 0x77, 0x79, 0x76, 0x80, 0x8f, + 0x9f, 0xa3, 0xa7, 0xa5, 0xa8, 0x9e, 0x91, 0x96, 0x88, 0x82, 0x75, 0x6b, 0x6d, 0x72, 0x86, 0x99, + 0x9d, 0x92, 0x8e, 0x88, 0x8b, 0x8f, 0x87, 0x7a, 0x69, 0x5f, 0x68, 0x7a, 0x8e, 0x93, 0x8f, 0x88, + 0x84, 0x87, 0x80, 0x75, 0x78, 0x86, 0x86, 0x84, 0x89, 0x8d, 0x8f, 0x8f, 0x8e, 0x9d, 0xa6, 0x95, + 0x8e, 0x89, 0x83, 0x79, 0x6d, 0x67, 0x61, 0x5b, 0x5a, 0x5d, 0x6d, 0x83, 0x9e, 0xb3, 0xb3, 0xa0, + 0x8a, 0x77, 0x77, 0x88, 0x9a, 0x95, 0x83, 0x70, 0x66, 0x6b, 0x76, 0x7c, 0x77, 0x6a, 0x60, 0x5f, + 0x5f, 0x62, 0x71, 0x74, 0x73, 0x69, 0x6a, 0x73, 0x6a, 0x69, 0x6b, 0x77, 0x79, 0x75, 0x71, 0x6a, + 0x6c, 0x6b, 0x7a, 0x8e, 0x8b, 0x89, 0x82, 0x7d, 0x83, 0x8a, 0x93, 0x9e, 0x9e, 0x92, 0x89, 0x70, + 0x6c, 0x70, 0x67, 0x62, 0x56, 0x49, 0x48, 0x53, 0x62, 0x75, 0x82, 0x85, 0x89, 0x88, 0x7e, 0x84, + 0x8f, 0x95, 0x93, 0x85, 0x81, 0x7c, 0x7b, 0x7b, 0x7e, 0x86, 0x88, 0x86, 0x8c, 0x8d, 0x8e, 0x92, + 0x90, 0x8a, 0x79, 0x67, 0x65, 0x6b, 0x7d, 0x92, 0x9a, 0xa0, 0xa0, 0x91, 0x80, 0x71, 0x6a, 0x74, + 0x7e, 0x75, 0x72, 0x76, 0x79, 0x82, 0x8f, 0x94, 0x9c, 0x97, 0x88, 0x87, 0x7b, 0x76, 0x79, 0x74, + 0x6d, 0x66, 0x63, 0x69, 0x74, 0x80, 0x89, 0x90, 0x91, 0x95, 0x92, 0x82, 0x78, 0x7b, 0x8b, 0x91, + 0x85, 0x73, 0x63, 0x5d, 0x69, 0x7d, 0x84, 0x87, 0x7e, 0x71, 0x6b, 0x65, 0x75, 0x80, 0x74, 0x6c, + 0x62, 0x69, 0x6d, 0x6e, 0x77, 0x7b, 0x7b, 0x78, 0x7b, 0x75, 0x71, 0x72, 0x82, 0x98, 0x99, 0x90, + 0x8c, 0x8b, 0x8c, 0x8e, 0x89, 0x83, 0x85, 0x81, 0x83, 0x84, 0x81, 0x86, 0x7e, 0x76, 0x73, 0x63, + 0x59, 0x5d, 0x75, 0x8a, 0x96, 0xab, 0xb1, 0xa5, 0x91, 0x83, 0x92, 0x9f, 0x96, 0x86, 0x7d, 0x78, + 0x72, 0x78, 0x85, 0x8c, 0x88, 0x86, 0x88, 0x8c, 0x87, 0x87, 0x90, 0x8c, 0x85, 0x71, 0x68, 0x76, + 0x84, 0x90, 0x95, 0x8e, 0x8b, 0x86, 0x7b, 0x78, 0x7a, 0x7c, 0x82, 0x87, 0x7d, 0x76, 0x76, 0x7a, + 0x8c, 0x94, 0x95, 0xa7, 0x9f, 0x8c, 0x7c, 0x6d, 0x73, 0x72, 0x63, 0x5e, 0x5c, 0x5a, 0x67, 0x79, + 0x8a, 0x90, 0x90, 0x97, 0x9b, 0x90, 0x80, 0x79, 0x8e, 0x9e, 0xa0, 0x96, 0x8f, 0x8e, 0x8e, 0x90, + 0x90, 0x87, 0x77, 0x6a, 0x6f, 0x70, 0x79, 0x8b, 0x84, 0x77, 0x6c, 0x5e, 0x64, 0x6e, 0x80, 0x87, + 0x88, 0x95, 0x97, 0x8a, 0x76, 0x71, 0x7b, 0x90, 0x90, 0x86, 0x82, 0x7d, 0x83, 0x8c, 0x90, 0x87, + 0x7d, 0x82, 0x82, 0x87, 0x80, 0x79, 0x7b, 0x76, 0x73, 0x6b, 0x5e, 0x5f, 0x6a, 0x7b, 0x7d, 0x80, + 0x8b, 0x8d, 0x87, 0x82, 0x8f, 0xa6, 0x9e, 0x8f, 0x7a, 0x6a, 0x64, 0x6d, 0x7e, 0x85, 0x87, 0x93, + 0x95, 0x8a, 0x7e, 0x78, 0x80, 0x84, 0x75, 0x6c, 0x5d, 0x54, 0x62, 0x72, 0x80, 0x82, 0x7d, 0x80, + 0x7e, 0x78, 0x71, 0x65, 0x68, 0x75, 0x7c, 0x6c, 0x6a, 0x77, 0x80, 0x83, 0x83, 0x85, 0x89, 0x77, + 0x6f, 0x6e, 0x75, 0x7b, 0x6c, 0x5d, 0x51, 0x43, 0x47, 0x63, 0x76, 0x7c, 0x82, 0x94, 0x9a, 0x8c, + 0x7c, 0x70, 0x74, 0x7e, 0x7a, 0x77, 0x6e, 0x67, 0x6a, 0x6e, 0x76, 0x75, 0x69, 0x65, 0x6c, 0x77, + 0x6e, 0x6d, 0x7a, 0x81, 0x81, 0x76, 0x7b, 0x8f, 0x90, 0x8d, 0x84, 0x81, 0x7c, 0x73, 0x71, 0x78, + 0x84, 0x93, 0x95, 0x8b, 0x7c, 0x74, 0x82, 0x97, 0x9f, 0x9a, 0x92, 0x9c, 0xa0, 0x9c, 0x95, 0x8d, + 0x8e, 0x8a, 0x7d, 0x7b, 0x74, 0x6a, 0x71, 0x83, 0x90, 0x86, 0x85, 0x91, 0x92, 0x92, 0x8c, 0x93, + 0xa2, 0xa0, 0x94, 0x82, 0x83, 0x8f, 0x91, 0x91, 0x90, 0x8a, 0x86, 0x85, 0x88, 0x8f, 0x9c, 0xa5, + 0x99, 0x85, 0x6f, 0x5c, 0x65, 0x82, 0x93, 0x94, 0x93, 0x9d, 0x98, 0x8a, 0x7e, 0x72, 0x71, 0x76, + 0x79, 0x7b, 0x6a, 0x6d, 0x81, 0x8a, 0x8e, 0x8c, 0x96, 0x97, 0x8c, 0x82, 0x71, 0x6b, 0x6b, 0x6b, + 0x6b, 0x67, 0x67, 0x75, 0x82, 0x84, 0x83, 0x84, 0x86, 0x83, 0x83, 0x84, 0x87, 0x8d, 0x8b, 0x84, + 0x72, 0x66, 0x74, 0x86, 0x8a, 0x88, 0x83, 0x84, 0x7d, 0x7d, 0x73, 0x60, 0x63, 0x67, 0x63, 0x65, + 0x63, 0x71, 0x7e, 0x81, 0x80, 0x7a, 0x7c, 0x7b, 0x74, 0x79, 0x78, 0x78, 0x86, 0x8a, 0x83, 0x7e, + 0x86, 0x99, 0xa1, 0x99, 0x8e, 0x83, 0x79, 0x7e, 0x89, 0x8a, 0x91, 0x8d, 0x7e, 0x72, 0x65, 0x5a, + 0x66, 0x7e, 0x8d, 0x89, 0x84, 0x93, 0x8f, 0x88, 0x82, 0x7c, 0x91, 0x8c, 0x77, 0x6b, 0x60, 0x67, + 0x71, 0x71, 0x75, 0x74, 0x73, 0x74, 0x77, 0x76, 0x73, 0x73, 0x79, 0x7e, 0x77, 0x6d, 0x68, 0x70, + 0x80, 0x80, 0x7b, 0x78, 0x73, 0x6e, 0x6f, 0x75, 0x7b, 0x81, 0x77, 0x6d, 0x5e, 0x53, 0x67, 0x7c, + 0x83, 0x82, 0x8d, 0xa6, 0x98, 0x8d, 0x79, 0x6a, 0x6d, 0x63, 0x5b, 0x5a, 0x57, 0x60, 0x73, 0x80, + 0x85, 0x8a, 0x8f, 0x93, 0x8e, 0x8f, 0x8e, 0x83, 0x81, 0x88, 0x88, 0x84, 0x88, 0x94, 0x95, 0x8d, + 0x88, 0x82, 0x7d, 0x84, 0x8c, 0x88, 0x86, 0x81, 0x79, 0x76, 0x6e, 0x79, 0x99, 0x9f, 0x9d, 0x92, + 0x95, 0xa4, 0x94, 0x86, 0x7d, 0x77, 0x80, 0x81, 0x77, 0x74, 0x78, 0x86, 0x97, 0x9b, 0x9c, 0x9a, + 0x91, 0x89, 0x92, 0x94, 0x8a, 0x81, 0x7c, 0x81, 0x7d, 0x72, 0x78, 0x86, 0x91, 0x8d, 0x7e, 0x71, + 0x6b, 0x6b, 0x72, 0x81, 0x94, 0x9b, 0x80, 0x6b, 0x61, 0x69, 0x7c, 0x81, 0x80, 0x7e, 0x86, 0x95, + 0x94, 0x8f, 0x7c, 0x72, 0x71, 0x6c, 0x68, 0x65, 0x63, 0x68, 0x73, 0x87, 0x90, 0x94, 0x94, 0x8d, + 0x83, 0x7c, 0x7a, 0x7a, 0x83, 0x88, 0x86, 0x80, 0x7b, 0x86, 0x8b, 0x8c, 0x8a, 0x8e, 0x90, 0x87, + 0x85, 0x83, 0x84, 0x79, 0x67, 0x60, 0x5c, 0x68, 0x7d, 0x92, 0x96, 0x92, 0x9d, 0xac, 0xa4, 0x95, + 0x8e, 0x8d, 0x84, 0x76, 0x72, 0x77, 0x7e, 0x86, 0x8c, 0x8c, 0x8c, 0x8c, 0x8f, 0x8e, 0x8e, 0x87, + 0x73, 0x5f, 0x5d, 0x6b, 0x71, 0x6a, 0x7b, 0x8d, 0x8a, 0x81, 0x76, 0x75, 0x6f, 0x65, 0x67, 0x76, + 0x81, 0x7e, 0x72, 0x66, 0x69, 0x76, 0x85, 0x8f, 0x94, 0x95, 0x98, 0x9a, 0x8e, 0x8c, 0x81, 0x79, + 0x73, 0x6a, 0x65, 0x5e, 0x65, 0x7a, 0x8b, 0x97, 0x97, 0x90, 0x87, 0x7f, 0x7d, 0x80, 0x82, 0x8a, + 0x8c, 0x7e, 0x79, 0x78, 0x80, 0x84, 0x7b, 0x77, 0x72, 0x6c, 0x6c, 0x79, 0x81, 0x85, 0x82, 0x78, + 0x6e, 0x6b, 0x6a, 0x6f, 0x75, 0x83, 0x90, 0x8f, 0x99, 0xa0, 0x8b, 0x74, 0x66, 0x6e, 0x73, 0x68, + 0x61, 0x64, 0x68, 0x69, 0x6e, 0x7a, 0x84, 0x81, 0x8b, 0x87, 0x79, 0x71, 0x69, 0x63, 0x61, 0x62, + 0x60, 0x60, 0x6b, 0x79, 0x88, 0x82, 0x7c, 0x78, 0x75, 0x77, 0x7d, 0x8d, 0x8e, 0x7c, 0x6b, 0x71, + 0x7e, 0x86, 0x87, 0x87, 0x86, 0x84, 0x93, 0x9d, 0x90, 0x85, 0x77, 0x6b, 0x5d, 0x56, 0x62, 0x65, + 0x70, 0x8f, 0x99, 0x96, 0x91, 0x8f, 0x8f, 0x81, 0x74, 0x72, 0x74, 0x72, 0x77, 0x82, 0x87, 0x8e, + 0x8f, 0x93, 0x93, 0x93, 0x90, 0x87, 0x7e, 0x8c, 0x9a, 0x9e, 0x95, 0x83, 0x75, 0x73, 0x75, 0x8d, + 0x9c, 0xa4, 0xa4, 0x99, 0x9d, 0x9a, 0x85, 0x83, 0x81, 0x86, 0x8e, 0x79, 0x6c, 0x70, 0x7c, 0x88, + 0x87, 0x86, 0x8a, 0x86, 0x7e, 0x83, 0x89, 0x82, 0x7b, 0x6d, 0x6d, 0x77, 0x79, 0x7a, 0x84, 0x84, + 0x89, 0x8c, 0x8a, 0x88, 0x7e, 0x7c, 0x7d, 0x85, 0x8a, 0x84, 0x79, 0x7e, 0x87, 0x85, 0x80, 0x86, + 0x94, 0x94, 0xa2, 0xab, 0x94, 0x82, 0x76, 0x75, 0x6b, 0x5d, 0x5b, 0x5c, 0x6f, 0x84, 0x94, 0x9e, + 0x9b, 0x98, 0x93, 0x8e, 0x8c, 0x8f, 0x8a, 0x7c, 0x77, 0x81, 0x8f, 0x94, 0x93, 0x8a, 0x80, 0x79, + 0x7b, 0x7b, 0x78, 0x81, 0x82, 0x78, 0x68, 0x56, 0x55, 0x61, 0x6a, 0x86, 0x96, 0x91, 0x8a, 0x83, + 0x91, 0x8c, 0x74, 0x6b, 0x67, 0x66, 0x64, 0x63, 0x66, 0x6f, 0x7d, 0x88, 0x8f, 0x95, 0x99, 0x94, + 0x88, 0x82, 0x84, 0x84, 0x81, 0x74, 0x6e, 0x74, 0x76, 0x88, 0x9a, 0x97, 0x92, 0x8b, 0x7d, 0x74, + 0x6e, 0x72, 0x84, 0x85, 0x87, 0x88, 0x75, 0x6e, 0x74, 0x7b, 0x7b, 0x7a, 0x7b, 0x77, 0x7e, 0x7b, + 0x7a, 0x71, 0x66, 0x67, 0x5c, 0x56, 0x57, 0x5e, 0x74, 0x81, 0x85, 0x8a, 0x88, 0x86, 0x80, 0x74, + 0x70, 0x74, 0x6f, 0x69, 0x6a, 0x70, 0x76, 0x72, 0x6e, 0x68, 0x6a, 0x73, 0x75, 0x7d, 0x80, 0x77, + 0x6d, 0x6d, 0x6b, 0x63, 0x5b, 0x56, 0x62, 0x71, 0x7a, 0x8a, 0x89, 0x83, 0x91, 0x8d, 0x7e, 0x7e, + 0x7d, 0x76, 0x73, 0x6d, 0x6e, 0x78, 0x87, 0x8d, 0x8c, 0x8c, 0x90, 0x93, 0x8d, 0x8b, 0x87, 0x7d, + 0x6f, 0x63, 0x61, 0x70, 0x83, 0x99, 0xaf, 0xaa, 0x9c, 0x93, 0x8e, 0x8f, 0x8b, 0x89, 0x8e, 0x85, + 0x7c, 0x85, 0x89, 0x89, 0x92, 0x9a, 0x9b, 0x9c, 0x99, 0x9c, 0xa6, 0x9c, 0x93, 0x8a, 0x85, 0x82, + 0x74, 0x66, 0x63, 0x78, 0x97, 0xa2, 0xa2, 0xa2, 0x97, 0x83, 0x7c, 0x76, 0x7e, 0x89, 0x80, 0x88, + 0x88, 0x82, 0x82, 0x89, 0x8d, 0x84, 0x7d, 0x78, 0x74, 0x73, 0x79, 0x85, 0x84, 0x82, 0x7c, 0x79, + 0x70, 0x6d, 0x7e, 0x8c, 0x92, 0x94, 0x92, 0x95, 0x9f, 0x94, 0x86, 0x86, 0x84, 0x7c, 0x75, 0x6b, + 0x6d, 0x72, 0x76, 0x7c, 0x7a, 0x82, 0x8a, 0x8f, 0x96, 0x8d, 0x7c, 0x71, 0x6a, 0x64, 0x61, 0x66, + 0x6e, 0x7c, 0x83, 0x85, 0x89, 0x87, 0x83, 0x81, 0x81, 0x86, 0x8e, 0x8a, 0x88, 0x91, 0x89, 0x83, + 0x8a, 0x8f, 0x89, 0x80, 0x7d, 0x85, 0x89, 0x82, 0x7c, 0x77, 0x6a, 0x5d, 0x56, 0x4c, 0x52, 0x6c, + 0x89, 0x9d, 0x91, 0x85, 0x7b, 0x78, 0x77, 0x70, 0x73, 0x6a, 0x5d, 0x5f, 0x67, 0x73, 0x80, 0x88, + 0x88, 0x80, 0x78, 0x7a, 0x80, 0x7e, 0x80, 0x7c, 0x7d, 0x7e, 0x81, 0x82, 0x78, 0x7b, 0x91, 0x9f, + 0xa1, 0x9a, 0x91, 0x82, 0x75, 0x71, 0x76, 0x89, 0x89, 0x8a, 0x89, 0x71, 0x68, 0x6d, 0x81, 0x83, + 0x78, 0x76, 0x71, 0x6e, 0x6d, 0x71, 0x72, 0x6f, 0x68, 0x66, 0x64, 0x61, 0x74, 0x86, 0x8b, 0x86, + 0x78, 0x75, 0x73, 0x6f, 0x69, 0x72, 0x7e, 0x82, 0x8c, 0x8c, 0x85, 0x7c, 0x78, 0x7a, 0x75, 0x73, + 0x7c, 0x82, 0x88, 0x8a, 0x80, 0x7a, 0x73, 0x74, 0x70, 0x61, 0x60, 0x72, 0x83, 0x8d, 0x8f, 0x8d, + 0x8c, 0x88, 0x87, 0x87, 0x8a, 0x89, 0x86, 0x84, 0x82, 0x83, 0x8d, 0x94, 0x8e, 0x7a, 0x74, 0x79, + 0x7e, 0x84, 0x88, 0x85, 0x7d, 0x75, 0x79, 0x7d, 0x72, 0x7c, 0x92, 0xa5, 0xa8, 0x97, 0x8c, 0x85, + 0x87, 0x82, 0x89, 0x8c, 0x80, 0x78, 0x6e, 0x6b, 0x75, 0x84, 0x92, 0x90, 0x85, 0x82, 0x87, 0x88, + 0x88, 0x84, 0x78, 0x75, 0x6f, 0x6c, 0x68, 0x6a, 0x83, 0x94, 0x9d, 0x99, 0x89, 0x7c, 0x74, 0x74, + 0x77, 0x82, 0x87, 0x91, 0xa0, 0x90, 0x7e, 0x7a, 0x82, 0x90, 0x85, 0x80, 0x7b, 0x71, 0x6c, 0x72, + 0x78, 0x7a, 0x78, 0x70, 0x6f, 0x63, 0x65, 0x82, 0x90, 0x98, 0x91, 0x85, 0x87, 0x86, 0x7e, 0x80, + 0x86, 0x86, 0x85, 0x7e, 0x78, 0x7d, 0x81, 0x83, 0x81, 0x73, 0x71, 0x77, 0x80, 0x8e, 0x87, 0x77, + 0x74, 0x7d, 0x8d, 0x85, 0x77, 0x7b, 0x82, 0x8a, 0x94, 0x92, 0x90, 0x8c, 0x87, 0x8d, 0x96, 0x97, + 0x98, 0x95, 0x87, 0x7a, 0x7c, 0x89, 0x90, 0x84, 0x79, 0x7d, 0x81, 0x83, 0x88, 0x81, 0x73, 0x68, + 0x5d, 0x5f, 0x61, 0x6a, 0x80, 0x91, 0x96, 0x81, 0x6e, 0x66, 0x6d, 0x77, 0x71, 0x73, 0x74, 0x78, + 0x7d, 0x75, 0x72, 0x76, 0x7a, 0x82, 0x87, 0x86, 0x85, 0x84, 0x86, 0x8c, 0x8b, 0x87, 0x89, 0x87, + 0x80, 0x7b, 0x85, 0x92, 0x9a, 0x9d, 0x97, 0x8d, 0x86, 0x85, 0x85, 0x85, 0x86, 0x87, 0x8d, 0x8e, + 0x7d, 0x79, 0x79, 0x81, 0x80, 0x6f, 0x6d, 0x6c, 0x6b, 0x6e, 0x6c, 0x69, 0x73, 0x81, 0x8f, 0x90, + 0x84, 0x7b, 0x7a, 0x7c, 0x81, 0x83, 0x7c, 0x75, 0x6f, 0x67, 0x6b, 0x76, 0x7c, 0x7c, 0x78, 0x70, + 0x6c, 0x6a, 0x6d, 0x6f, 0x6f, 0x70, 0x77, 0x86, 0x85, 0x73, 0x67, 0x60, 0x67, 0x6d, 0x67, 0x6c, + 0x6d, 0x6a, 0x68, 0x62, 0x63, 0x68, 0x6f, 0x76, 0x76, 0x78, 0x84, 0x91, 0x97, 0x91, 0x8a, 0x85, + 0x83, 0x7b, 0x79, 0x81, 0x85, 0x82, 0x83, 0x83, 0x7d, 0x79, 0x78, 0x7e, 0x83, 0x81, 0x83, 0x88, + 0x96, 0x95, 0x8c, 0x89, 0x89, 0x91, 0x8b, 0x81, 0x81, 0x7e, 0x7b, 0x79, 0x76, 0x78, 0x7e, 0x83, + 0x82, 0x7c, 0x79, 0x7a, 0x7e, 0x7e, 0x7a, 0x7a, 0x80, 0x89, 0x8b, 0x86, 0x86, 0x86, 0x85, 0x88, + 0x90, 0x90, 0x87, 0x80, 0x81, 0x81, 0x86, 0x8a, 0x93, 0x9b, 0x91, 0x82, 0x7a, 0x7b, 0x86, 0x7e, + 0x7a, 0x81, 0x84, 0x83, 0x7c, 0x73, 0x70, 0x74, 0x7d, 0x8a, 0x8d, 0x8d, 0x8a, 0x8a, 0x87, 0x83, + 0x83, 0x82, 0x83, 0x7b, 0x7c, 0x8d, 0x9d, 0xa7, 0xa9, 0xa3, 0x94, 0x86, 0x84, 0x85, 0x8b, 0x90, + 0x8d, 0x8f, 0x95, 0x8a, 0x7e, 0x79, 0x7b, 0x8a, 0x84, 0x7d, 0x81, 0x81, 0x7e, 0x7b, 0x7b, 0x82, + 0x8b, 0x8e, 0x8c, 0x8a, 0x88, 0x88, 0x89, 0x88, 0x88, 0x86, 0x81, 0x7b, 0x71, 0x6d, 0x70, 0x73, + 0x73, 0x74, 0x76, 0x78, 0x78, 0x7e, 0x87, 0x84, 0x80, 0x78, 0x78, 0x80, 0x81, 0x81, 0x7c, 0x75, + 0x74, 0x71, 0x73, 0x78, 0x78, 0x74, 0x6d, 0x68, 0x68, 0x70, 0x74, 0x76, 0x7c, 0x83, 0x87, 0x86, + 0x80, 0x78, 0x74, 0x76, 0x7d, 0x83, 0x84, 0x85, 0x82, 0x7d, 0x7d, 0x7c, 0x7b, 0x78, 0x77, 0x76, + 0x7a, 0x84, 0x88, 0x8a, 0x8a, 0x85, 0x7a, 0x70, 0x6e, 0x6e, 0x71, 0x70, 0x6e, 0x6a, 0x69, 0x67, + 0x65, 0x6a, 0x73, 0x7b, 0x7d, 0x7c, 0x7c, 0x79, 0x77, 0x75, 0x78, 0x7d, 0x7b, 0x74, 0x6d, 0x6c, + 0x6c, 0x6c, 0x6b, 0x6d, 0x71, 0x6c, 0x65, 0x66, 0x67, 0x6b, 0x71, 0x73, 0x74, 0x74, 0x73, 0x75, + 0x7a, 0x82, 0x8a, 0x89, 0x85, 0x82, 0x7d, 0x7c, 0x7d, 0x7b, 0x7e, 0x7e, 0x81, 0x87, 0x8c, 0x91, + 0x8f, 0x8d, 0x8c, 0x8a, 0x86, 0x87, 0x89, 0x88, 0x8c, 0x8e, 0x8d, 0x87, 0x80, 0x7c, 0x7a, 0x7d, + 0x85, 0x88, 0x8c, 0x91, 0x8d, 0x87, 0x84, 0x80, 0x81, 0x82, 0x82, 0x85, 0x89, 0x8b, 0x8d, 0x90, + 0x92, 0x90, 0x8b, 0x87, 0x89, 0x89, 0x8c, 0x8e, 0x8e, 0x89, 0x87, 0x84, 0x83, 0x84, 0x84, 0x85, + 0x83, 0x82, 0x80, 0x7d, 0x7c, 0x82, 0x8a, 0x8e, 0x8b, 0x88, 0x86, 0x88, 0x8b, 0x8a, 0x87, 0x84, + 0x84, 0x81, 0x7b, 0x79, 0x79, 0x79, 0x79, 0x79, 0x7b, 0x7b, 0x79, 0x7b, 0x84, 0x8d, 0x90, 0x8f, + 0x90, 0x8d, 0x85, 0x82, 0x84, 0x85, 0x81, 0x7d, 0x82, 0x85, 0x89, 0x8b, 0x89, 0x86, 0x85, 0x85, + 0x7c, 0x78, 0x7b, 0x82, 0x8a, 0x8e, 0x8b, 0x80, 0x72, 0x6d, 0x6e, 0x71, 0x71, 0x72, 0x76, 0x79, + 0x76, 0x75, 0x76, 0x74, 0x74, 0x7a, 0x81, 0x85, 0x86, 0x8c, 0x90, 0x90, 0x93, 0x92, 0x8c, 0x81, + 0x7a, 0x79, 0x7a, 0x79, 0x76, 0x72, 0x70, 0x6e, 0x70, 0x70, 0x70, 0x72, 0x73, 0x77, 0x77, 0x76, + 0x75, 0x75, 0x76, 0x76, 0x74, 0x6e, 0x6d, 0x70, 0x71, 0x6f, 0x70, 0x72, 0x73, 0x72, 0x71, 0x75, + 0x78, 0x78, 0x7b, 0x7e, 0x7e, 0x80, 0x81, 0x86, 0x8c, 0x93, 0x97, 0x98, 0x99, 0x94, 0x8e, 0x8a, + 0x8c, 0x8e, 0x8a, 0x88, 0x8b, 0x8c, 0x90, 0x93, 0x8f, 0x8a, 0x85, 0x7d, 0x78, 0x78, 0x79, 0x7e, + 0x80, 0x7b, 0x77, 0x71, 0x6b, 0x6a, 0x6c, 0x73, 0x79, 0x7b, 0x80, 0x83, 0x7e, 0x78, 0x78, 0x74, + 0x73, 0x72, 0x72, 0x73, 0x74, 0x78, 0x7a, 0x7a, 0x7b, 0x7e, 0x7c, 0x74, 0x72, 0x76, 0x7b, 0x7d, + 0x7b, 0x79, 0x76, 0x71, 0x71, 0x75, 0x79, 0x77, 0x79, 0x7d, 0x80, 0x82, 0x83, 0x85, 0x84, 0x82, + 0x83, 0x83, 0x83, 0x83, 0x87, 0x86, 0x84, 0x88, 0x8a, 0x85, 0x7e, 0x82, 0x87, 0x82, 0x7d, 0x7a, + 0x78, 0x74, 0x75, 0x7c, 0x83, 0x8a, 0x8f, 0x94, 0x97, 0x94, 0x8f, 0x8a, 0x88, 0x84, 0x81, 0x7d, + 0x7c, 0x7d, 0x80, 0x82, 0x7e, 0x7d, 0x7c, 0x78, 0x76, 0x7d, 0x86, 0x89, 0x86, 0x84, 0x7e, 0x76, + 0x72, 0x71, 0x73, 0x75, 0x79, 0x7c, 0x7e, 0x7c, 0x78, 0x78, 0x76, 0x74, 0x76, 0x78, 0x7a, 0x80, + 0x87, 0x90, 0x94, 0x91, 0x92, 0x91, 0x8b, 0x85, 0x7e, 0x7e, 0x81, 0x7d, 0x7b, 0x78, 0x75, 0x72, + 0x71, 0x76, 0x7e, 0x82, 0x82, 0x83, 0x84, 0x86, 0x87, 0x89, 0x88, 0x82, 0x7b, 0x78, 0x7b, 0x7e, + 0x80, 0x7c, 0x7b, 0x7e, 0x80, 0x7e, 0x7a, 0x7b, 0x7b, 0x78, 0x7a, 0x7d, 0x7a, 0x76, 0x76, 0x78, + 0x7e, 0x7d, 0x7e, 0x86, 0x8b, 0x8c, 0x8a, 0x8a, 0x8a, 0x86, 0x84, 0x88, 0x8e, 0x8f, 0x90, 0x91, + 0x8c, 0x8a, 0x8b, 0x87, 0x85, 0x86, 0x8a, 0x88, 0x7e, 0x78, 0x74, 0x6c, 0x66, 0x6a, 0x72, 0x74, + 0x76, 0x78, 0x7d, 0x81, 0x7e, 0x7b, 0x78, 0x73, 0x6f, 0x6e, 0x6e, 0x72, 0x78, 0x80, 0x84, 0x84, + 0x8b, 0x90, 0x8d, 0x8f, 0x93, 0x96, 0x91, 0x89, 0x88, 0x85, 0x82, 0x81, 0x83, 0x87, 0x86, 0x89, + 0x8b, 0x8a, 0x8a, 0x8c, 0x8a, 0x86, 0x83, 0x80, 0x7c, 0x7b, 0x80, 0x87, 0x88, 0x84, 0x80, 0x7e, + 0x7b, 0x77, 0x76, 0x72, 0x6e, 0x68, 0x68, 0x6c, 0x68, 0x67, 0x68, 0x6c, 0x77, 0x84, 0x8d, 0x90, + 0x8d, 0x8e, 0x8b, 0x89, 0x86, 0x80, 0x78, 0x76, 0x7e, 0x82, 0x83, 0x82, 0x7c, 0x7a, 0x77, 0x75, + 0x78, 0x7c, 0x7e, 0x80, 0x7e, 0x7d, 0x78, 0x70, 0x6e, 0x71, 0x71, 0x73, 0x71, 0x71, 0x72, 0x77, + 0x7a, 0x78, 0x77, 0x6f, 0x6a, 0x6d, 0x76, 0x82, 0x85, 0x89, 0x8e, 0x8d, 0x8f, 0x8e, 0x8b, 0x86, + 0x82, 0x84, 0x81, 0x7b, 0x77, 0x74, 0x73, 0x70, 0x71, 0x74, 0x75, 0x76, 0x79, 0x7d, 0x82, 0x85, + 0x84, 0x81, 0x7b, 0x76, 0x70, 0x6c, 0x6f, 0x76, 0x7c, 0x7a, 0x76, 0x76, 0x70, 0x70, 0x75, 0x7b, + 0x7d, 0x74, 0x71, 0x72, 0x70, 0x70, 0x75, 0x80, 0x87, 0x8a, 0x91, 0x91, 0x8d, 0x8e, 0x8f, 0x8e, + 0x87, 0x81, 0x7c, 0x7e, 0x8a, 0x94, 0x9a, 0x99, 0x94, 0x91, 0x8e, 0x8e, 0x92, 0x92, 0x8c, 0x87, + 0x83, 0x84, 0x80, 0x7b, 0x7d, 0x80, 0x82, 0x86, 0x8b, 0x8c, 0x86, 0x85, 0x87, 0x86, 0x84, 0x7e, + 0x7d, 0x79, 0x78, 0x80, 0x84, 0x8b, 0x8f, 0x92, 0x94, 0x90, 0x8d, 0x8c, 0x8c, 0x8d, 0x8a, 0x84, + 0x7d, 0x7c, 0x82, 0x82, 0x82, 0x82, 0x7e, 0x7a, 0x77, 0x7b, 0x86, 0x8a, 0x87, 0x85, 0x7c, 0x78, + 0x7b, 0x85, 0x8d, 0x92, 0x93, 0x8e, 0x85, 0x7e, 0x7d, 0x82, 0x7d, 0x7b, 0x7a, 0x6f, 0x69, 0x68, + 0x6a, 0x6d, 0x6e, 0x73, 0x7b, 0x82, 0x88, 0x8b, 0x8a, 0x88, 0x86, 0x84, 0x7d, 0x75, 0x72, 0x72, + 0x77, 0x7b, 0x80, 0x84, 0x80, 0x7c, 0x7c, 0x7c, 0x83, 0x8a, 0x93, 0x92, 0x89, 0x83, 0x81, 0x82, + 0x82, 0x86, 0x89, 0x87, 0x85, 0x85, 0x83, 0x86, 0x87, 0x87, 0x83, 0x78, 0x72, 0x72, 0x75, 0x7e, + 0x8b, 0x93, 0x92, 0x90, 0x8f, 0x8a, 0x86, 0x82, 0x7d, 0x78, 0x6d, 0x66, 0x6a, 0x6d, 0x74, 0x72, + 0x6d, 0x70, 0x75, 0x77, 0x76, 0x75, 0x78, 0x78, 0x74, 0x70, 0x6d, 0x6a, 0x66, 0x67, 0x6d, 0x71, + 0x70, 0x6d, 0x6c, 0x67, 0x64, 0x67, 0x69, 0x69, 0x69, 0x64, 0x63, 0x65, 0x68, 0x6c, 0x6f, 0x72, + 0x79, 0x79, 0x77, 0x75, 0x76, 0x79, 0x7b, 0x7e, 0x7a, 0x74, 0x77, 0x81, 0x8d, 0x91, 0x91, 0x90, + 0x8b, 0x84, 0x82, 0x87, 0x8a, 0x85, 0x82, 0x7e, 0x75, 0x74, 0x79, 0x83, 0x84, 0x7d, 0x7b, 0x7e, + 0x80, 0x80, 0x84, 0x89, 0x8a, 0x8a, 0x87, 0x7e, 0x79, 0x78, 0x79, 0x80, 0x89, 0x8f, 0x91, 0x90, + 0x91, 0x8f, 0x8c, 0x8c, 0x8e, 0x91, 0x88, 0x7e, 0x82, 0x89, 0x8d, 0x89, 0x8a, 0x8e, 0x8d, 0x89, + 0x8a, 0x8a, 0x8d, 0x8f, 0x90, 0x8d, 0x85, 0x7d, 0x7e, 0x86, 0x8f, 0x97, 0x98, 0x93, 0x8d, 0x89, + 0x88, 0x8b, 0x88, 0x83, 0x7b, 0x6f, 0x6e, 0x75, 0x7a, 0x83, 0x84, 0x86, 0x8d, 0x92, 0x91, 0x8c, + 0x88, 0x87, 0x88, 0x87, 0x82, 0x81, 0x81, 0x81, 0x86, 0x88, 0x87, 0x82, 0x7b, 0x7c, 0x80, 0x7e, + 0x80, 0x81, 0x82, 0x80, 0x79, 0x7a, 0x7c, 0x7b, 0x77, 0x72, 0x75, 0x7c, 0x79, 0x74, 0x74, 0x79, + 0x7a, 0x79, 0x76, 0x70, 0x6f, 0x75, 0x80, 0x8c, 0x8f, 0x8f, 0x8c, 0x8a, 0x88, 0x87, 0x87, 0x84, + 0x7c, 0x78, 0x70, 0x6d, 0x72, 0x78, 0x7b, 0x76, 0x70, 0x71, 0x75, 0x78, 0x7d, 0x81, 0x83, 0x82, + 0x7c, 0x76, 0x6f, 0x6d, 0x6d, 0x70, 0x74, 0x79, 0x7d, 0x7d, 0x7a, 0x7a, 0x7d, 0x82, 0x82, 0x83, + 0x7e, 0x75, 0x78, 0x84, 0x8d, 0x91, 0x91, 0x93, 0x96, 0x92, 0x8f, 0x8d, 0x87, 0x85, 0x86, 0x86, + 0x83, 0x7c, 0x7b, 0x82, 0x89, 0x8c, 0x8d, 0x88, 0x82, 0x80, 0x80, 0x7e, 0x7e, 0x7a, 0x74, 0x6e, + 0x69, 0x6c, 0x6f, 0x6e, 0x6c, 0x6c, 0x72, 0x79, 0x79, 0x77, 0x75, 0x77, 0x77, 0x75, 0x6f, 0x6a, + 0x6c, 0x6f, 0x75, 0x7e, 0x83, 0x81, 0x7e, 0x7e, 0x83, 0x83, 0x7a, 0x76, 0x79, 0x7b, 0x7b, 0x7c, + 0x80, 0x7e, 0x79, 0x71, 0x70, 0x75, 0x74, 0x73, 0x75, 0x75, 0x79, 0x7a, 0x79, 0x78, 0x76, 0x78, + 0x7b, 0x82, 0x87, 0x8b, 0x8b, 0x8b, 0x8a, 0x89, 0x88, 0x88, 0x84, 0x7b, 0x72, 0x6e, 0x70, 0x78, + 0x83, 0x8b, 0x88, 0x84, 0x87, 0x8c, 0x90, 0x91, 0x8f, 0x8c, 0x89, 0x85, 0x82, 0x81, 0x81, 0x80, + 0x81, 0x83, 0x83, 0x82, 0x81, 0x83, 0x84, 0x85, 0x86, 0x84, 0x81, 0x7c, 0x7a, 0x79, 0x7c, 0x7e, + 0x7c, 0x80, 0x86, 0x89, 0x87, 0x85, 0x82, 0x82, 0x80, 0x7b, 0x78, 0x74, 0x73, 0x7b, 0x89, 0x94, + 0x96, 0x93, 0x91, 0x8e, 0x8e, 0x8b, 0x86, 0x83, 0x82, 0x80, 0x81, 0x83, 0x84, 0x84, 0x81, 0x7d, + 0x80, 0x83, 0x84, 0x86, 0x85, 0x85, 0x87, 0x84, 0x80, 0x7c, 0x79, 0x76, 0x75, 0x77, 0x7c, 0x7e, + 0x7d, 0x7e, 0x80, 0x82, 0x7c, 0x77, 0x78, 0x78, 0x76, 0x76, 0x78, 0x7b, 0x7a, 0x77, 0x76, 0x79, + 0x7c, 0x7e, 0x82, 0x84, 0x83, 0x81, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x83, 0x87, 0x8a, 0x8a, 0x8a, + 0x8b, 0x8a, 0x88, 0x87, 0x86, 0x81, 0x77, 0x73, 0x72, 0x71, 0x74, 0x78, 0x79, 0x76, 0x79, 0x7e, + 0x83, 0x84, 0x83, 0x82, 0x7c, 0x71, 0x6b, 0x6a, 0x6e, 0x76, 0x7d, 0x86, 0x88, 0x87, 0x89, 0x8b, + 0x8d, 0x8d, 0x89, 0x88, 0x8a, 0x8c, 0x8d, 0x8f, 0x8f, 0x92, 0x93, 0x92, 0x96, 0x99, 0x96, 0x90, + 0x8c, 0x8a, 0x89, 0x84, 0x81, 0x80, 0x79, 0x77, 0x7d, 0x85, 0x8a, 0x8c, 0x8b, 0x89, 0x82, 0x7b, + 0x77, 0x77, 0x73, 0x6c, 0x6a, 0x6e, 0x73, 0x79, 0x7c, 0x7a, 0x76, 0x77, 0x7a, 0x7d, 0x81, 0x80, + 0x7c, 0x79, 0x78, 0x76, 0x75, 0x73, 0x73, 0x73, 0x74, 0x76, 0x77, 0x79, 0x7b, 0x7c, 0x7a, 0x74, + 0x71, 0x71, 0x70, 0x70, 0x6f, 0x6d, 0x69, 0x63, 0x66, 0x6e, 0x74, 0x73, 0x70, 0x6d, 0x6d, 0x70, + 0x6c, 0x65, 0x62, 0x65, 0x6e, 0x7b, 0x84, 0x89, 0x89, 0x86, 0x86, 0x87, 0x89, 0x88, 0x84, 0x81, + 0x81, 0x7a, 0x78, 0x78, 0x76, 0x79, 0x80, 0x81, 0x82, 0x85, 0x86, 0x86, 0x83, 0x82, 0x7e, 0x72, + 0x6a, 0x6a, 0x74, 0x7a, 0x7b, 0x7e, 0x85, 0x88, 0x89, 0x89, 0x87, 0x80, 0x78, 0x7b, 0x7e, 0x7b, + 0x79, 0x7d, 0x84, 0x88, 0x8a, 0x89, 0x8c, 0x91, 0x94, 0x93, 0x8f, 0x8f, 0x8e, 0x8b, 0x8b, 0x8d, + 0x8b, 0x87, 0x89, 0x91, 0x98, 0x9c, 0x9c, 0x99, 0x94, 0x8a, 0x87, 0x81, 0x78, 0x7d, 0x7c, 0x79, + 0x7a, 0x7c, 0x7e, 0x7d, 0x79, 0x7a, 0x83, 0x87, 0x86, 0x84, 0x82, 0x82, 0x78, 0x6d, 0x6c, 0x74, + 0x7c, 0x82, 0x84, 0x84, 0x89, 0x87, 0x85, 0x87, 0x8e, 0x91, 0x8d, 0x88, 0x8f, 0x91, 0x8d, 0x87, + 0x84, 0x86, 0x81, 0x7a, 0x7a, 0x7d, 0x79, 0x81, 0x89, 0x89, 0x84, 0x7b, 0x75, 0x70, 0x70, 0x79, + 0x82, 0x85, 0x89, 0x8c, 0x8e, 0x8e, 0x88, 0x81, 0x7c, 0x79, 0x71, 0x6e, 0x70, 0x79, 0x7c, 0x7b, + 0x7d, 0x7e, 0x78, 0x72, 0x72, 0x76, 0x78, 0x81, 0x86, 0x82, 0x7a, 0x76, 0x74, 0x70, 0x71, 0x76, + 0x77, 0x7d, 0x8d, 0x92, 0x95, 0x98, 0x93, 0x8d, 0x8c, 0x83, 0x7e, 0x86, 0x8c, 0x92, 0x97, 0x98, + 0x96, 0x96, 0x98, 0x95, 0x8c, 0x86, 0x8a, 0x87, 0x7d, 0x79, 0x7b, 0x7c, 0x7a, 0x83, 0x89, 0x8a, + 0x88, 0x83, 0x85, 0x85, 0x86, 0x84, 0x78, 0x76, 0x72, 0x60, 0x5e, 0x5d, 0x67, 0x71, 0x75, 0x76, + 0x76, 0x72, 0x6e, 0x6f, 0x6e, 0x6c, 0x6a, 0x64, 0x60, 0x61, 0x62, 0x62, 0x69, 0x6c, 0x6b, 0x73, + 0x77, 0x7a, 0x81, 0x7d, 0x79, 0x79, 0x73, 0x75, 0x7a, 0x6e, 0x6e, 0x6f, 0x6b, 0x6c, 0x72, 0x70, + 0x6c, 0x68, 0x67, 0x66, 0x6c, 0x67, 0x6e, 0x7b, 0x77, 0x7b, 0x80, 0x7d, 0x84, 0x8a, 0x8c, 0x8b, + 0x8a, 0x8b, 0x8b, 0x89, 0x8b, 0x85, 0x7b, 0x80, 0x75, 0x6f, 0x81, 0x86, 0x88, 0x8b, 0x87, 0x84, + 0x87, 0x8e, 0x91, 0x8a, 0x7b, 0x71, 0x70, 0x73, 0x76, 0x78, 0x75, 0x76, 0x84, 0x89, 0x8a, 0x8b, + 0x9a, 0xa1, 0x9a, 0x93, 0x8e, 0x7e, 0x89, 0x93, 0x8b, 0x94, 0x9a, 0x98, 0x93, 0x8c, 0x88, 0x87, + 0x84, 0x87, 0x86, 0x85, 0x89, 0x8d, 0x8b, 0x8d, 0x94, 0x9c, 0x99, 0x91, 0x8f, 0x8b, 0x86, 0x84, + 0x88, 0x8a, 0x87, 0x7d, 0x78, 0x85, 0x85, 0x74, 0x7e, 0x86, 0x8d, 0x8b, 0x87, 0x88, 0x8a, 0x89, + 0x87, 0x81, 0x74, 0x6a, 0x66, 0x63, 0x75, 0x86, 0x8a, 0x82, 0x7b, 0x7c, 0x7a, 0x75, 0x76, 0x7c, + 0x84, 0x8d, 0x7e, 0x74, 0x76, 0x6f, 0x65, 0x62, 0x6b, 0x6f, 0x6b, 0x67, 0x6b, 0x6e, 0x6a, 0x73, + 0x82, 0x7e, 0x79, 0x79, 0x87, 0x8e, 0x91, 0x8f, 0x86, 0x7d, 0x86, 0x89, 0x84, 0x85, 0x89, 0x89, + 0x83, 0x78, 0x72, 0x77, 0x77, 0x7a, 0x7e, 0x88, 0x85, 0x85, 0x8b, 0x86, 0x80, 0x7b, 0x78, 0x72, + 0x65, 0x68, 0x6d, 0x6f, 0x78, 0x7b, 0x71, 0x7a, 0x86, 0x89, 0x89, 0x81, 0x82, 0x89, 0x93, 0x8f, + 0x8b, 0x8c, 0x88, 0x8e, 0x91, 0x86, 0x8b, 0x8f, 0x8a, 0x87, 0x86, 0x8a, 0x8e, 0x8e, 0x8b, 0x87, + 0x87, 0x80, 0x81, 0x8c, 0x9e, 0x9c, 0x8f, 0x7d, 0x7a, 0x74, 0x6f, 0x7a, 0x7a, 0x71, 0x66, 0x62, + 0x70, 0x7c, 0x80, 0x81, 0x75, 0x6e, 0x6c, 0x70, 0x79, 0x76, 0x7a, 0x7d, 0x78, 0x6d, 0x6a, 0x71, + 0x78, 0x7e, 0x7c, 0x75, 0x6f, 0x72, 0x72, 0x71, 0x74, 0x74, 0x7c, 0x7d, 0x83, 0x80, 0x74, 0x76, + 0x71, 0x70, 0x6c, 0x65, 0x67, 0x6b, 0x64, 0x5a, 0x5e, 0x62, 0x70, 0x7d, 0x7a, 0x75, 0x72, 0x6e, + 0x72, 0x84, 0x8d, 0x8b, 0x8d, 0x8f, 0x80, 0x77, 0x7e, 0x8e, 0x8f, 0x84, 0x7e, 0x92, 0x98, 0x8c, + 0x87, 0x83, 0x7b, 0x73, 0x7b, 0x8a, 0x85, 0x82, 0x87, 0x8a, 0x89, 0x74, 0x66, 0x76, 0x8f, 0x90, + 0x84, 0x71, 0x79, 0x96, 0x9c, 0x8d, 0x83, 0x89, 0x88, 0x7e, 0x89, 0x9d, 0x98, 0x93, 0x8e, 0x89, + 0x83, 0x7b, 0x7c, 0x88, 0x84, 0x83, 0x84, 0x87, 0x92, 0x91, 0x8a, 0x99, 0x97, 0x93, 0x99, 0x85, + 0x7f, 0x85, 0x80, 0x80, 0x76, 0x79, 0x87, 0x89, 0x7d, 0x6a, 0x6b, 0x81, 0x91, 0x93, 0x8a, 0x7e, + 0x6f, 0x6e, 0x74, 0x70, 0x7d, 0x88, 0x82, 0x80, 0x79, 0x6a, 0x6f, 0x72, 0x76, 0x7d, 0x7a, 0x75, + 0x7c, 0x84, 0x83, 0x7d, 0x7a, 0x81, 0x81, 0x89, 0x8c, 0x85, 0x8a, 0x81, 0x73, 0x67, 0x65, 0x66, + 0x5b, 0x5d, 0x6a, 0x72, 0x7e, 0x8d, 0x92, 0x88, 0x82, 0x8b, 0x92, 0x94, 0x8c, 0x86, 0x8a, 0x88, + 0x91, 0x93, 0x85, 0x7c, 0x83, 0x7b, 0x75, 0x7c, 0x80, 0x86, 0x84, 0x86, 0x85, 0x81, 0x7c, 0x77, + 0x83, 0x88, 0x88, 0x85, 0x85, 0x80, 0x6d, 0x77, 0x8d, 0x88, 0x7e, 0x79, 0x74, 0x79, 0x85, 0x8e, + 0x91, 0x8c, 0x8d, 0x97, 0x94, 0x96, 0x8b, 0x93, 0xa9, 0xa3, 0x99, 0x92, 0x83, 0x76, 0x6d, 0x7b, + 0x85, 0x89, 0x88, 0x8e, 0x89, 0x7e, 0x82, 0x81, 0x8d, 0x94, 0x85, 0x80, 0x7c, 0x73, 0x6f, 0x72, + 0x7a, 0x78, 0x79, 0x7b, 0x7a, 0x76, 0x7d, 0x7d, 0x76, 0x6f, 0x6c, 0x6c, 0x67, 0x63, 0x72, 0x71, + 0x72, 0x7e, 0x7b, 0x66, 0x5d, 0x75, 0x86, 0x80, 0x73, 0x72, 0x6c, 0x67, 0x64, 0x69, 0x78, 0x78, + 0x71, 0x7d, 0x7e, 0x6e, 0x59, 0x54, 0x5c, 0x5b, 0x5e, 0x64, 0x5f, 0x54, 0x53, 0x5f, 0x67, 0x7a, + 0x7e, 0x76, 0x70, 0x81, 0x87, 0x80, 0x7e, 0x83, 0x80, 0x77, 0x78, 0x88, 0x84, 0x85, 0x92, 0x97, + 0x8e, 0x81, 0x8d, 0x89, 0x8b, 0x8a, 0x8e, 0x8c, 0x85, 0x83, 0x84, 0x7e, 0x8b, 0x8c, 0x84, 0x7a, + 0x72, 0x6d, 0x6e, 0x73, 0x6e, 0x6e, 0x79, 0x87, 0x94, 0x95, 0x93, 0x90, 0x89, 0x8f, 0x96, 0xa1, + 0xa3, 0xa1, 0x92, 0x84, 0x86, 0x81, 0x81, 0x88, 0x88, 0x82, 0x88, 0x93, 0x93, 0x8a, 0x7c, 0x78, + 0x8b, 0x97, 0xa4, 0xae, 0xa3, 0x98, 0x8c, 0x83, 0x7c, 0x74, 0x7d, 0x89, 0x82, 0x7d, 0x83, 0x83, + 0x7e, 0x87, 0x8b, 0x83, 0x76, 0x78, 0x81, 0x87, 0x81, 0x80, 0x84, 0x76, 0x6a, 0x6f, 0x71, 0x75, + 0x80, 0x82, 0x81, 0x79, 0x7b, 0x80, 0x7c, 0x7c, 0x80, 0x80, 0x83, 0x8e, 0x8e, 0x79, 0x7c, 0x78, + 0x7c, 0x73, 0x68, 0x6d, 0x6c, 0x6e, 0x6e, 0x66, 0x5d, 0x6b, 0x8b, 0x8e, 0x7e, 0x76, 0x80, 0x81, + 0x87, 0x91, 0x8d, 0x84, 0x80, 0x7c, 0x83, 0x95, 0x97, 0x9f, 0x9c, 0x84, 0x85, 0x81, 0x7a, 0x82, + 0x80, 0x85, 0x84, 0x7c, 0x88, 0x99, 0x96, 0x8f, 0x8b, 0x84, 0x76, 0x6b, 0x77, 0x83, 0x86, 0x87, + 0x83, 0x7c, 0x79, 0x8a, 0x91, 0x90, 0x87, 0x84, 0x9a, 0x96, 0x88, 0x85, 0x7a, 0x6f, 0x70, 0x74, + 0x84, 0x8c, 0x80, 0x7e, 0x85, 0x7b, 0x81, 0x85, 0x81, 0x77, 0x80, 0x83, 0x7b, 0x7c, 0x6e, 0x6e, + 0x75, 0x72, 0x70, 0x72, 0x7d, 0x84, 0x8d, 0x8c, 0x69, 0x5c, 0x68, 0x6f, 0x77, 0x76, 0x75, 0x76, + 0x70, 0x6d, 0x7b, 0x7e, 0x6b, 0x5c, 0x5c, 0x66, 0x5c, 0x56, 0x63, 0x69, 0x6a, 0x60, 0x5b, 0x68, + 0x6b, 0x6a, 0x70, 0x77, 0x82, 0x9c, 0x91, 0x74, 0x73, 0x5b, 0x50, 0x59, 0x5b, 0x66, 0x6e, 0x69, + 0x73, 0x7c, 0x79, 0x73, 0x7b, 0x89, 0x84, 0x83, 0x93, 0x9b, 0x9b, 0x9a, 0x94, 0x88, 0x8c, 0x93, + 0x9d, 0x9e, 0x94, 0x97, 0x93, 0x88, 0x83, 0x87, 0x77, 0x7c, 0x8e, 0x90, 0x95, 0x91, 0xa7, 0xb1, + 0xa2, 0x8e, 0x82, 0x87, 0x7a, 0x77, 0x87, 0x86, 0x83, 0x7e, 0x72, 0x74, 0x7b, 0x78, 0x8f, 0xa0, + 0xa4, 0xb2, 0xb4, 0xa1, 0x91, 0x88, 0x8c, 0x82, 0x77, 0x83, 0x88, 0x78, 0x77, 0x90, 0x95, 0x8e, + 0x81, 0x75, 0x72, 0x76, 0x77, 0x73, 0x82, 0x9b, 0x95, 0x85, 0x7c, 0x74, 0x6a, 0x69, 0x6f, 0x81, + 0x89, 0x7d, 0x71, 0x65, 0x6c, 0x6b, 0x63, 0x64, 0x6f, 0x7c, 0x78, 0x7c, 0x8b, 0x93, 0x90, 0x87, + 0x85, 0x85, 0x84, 0x75, 0x6c, 0x72, 0x7b, 0x7b, 0x6d, 0x6f, 0x77, 0x7c, 0x88, 0x95, 0x9a, 0x97, + 0x96, 0x83, 0x74, 0x71, 0x72, 0x72, 0x66, 0x6a, 0x74, 0x6f, 0x74, 0x7b, 0x81, 0x81, 0x77, 0x78, + 0x84, 0x85, 0x7d, 0x88, 0x90, 0x8b, 0x8a, 0x89, 0x83, 0x81, 0x88, 0x92, 0xa1, 0xa1, 0x95, 0x8e, + 0x81, 0x72, 0x73, 0x7a, 0x7d, 0x71, 0x75, 0x82, 0x8a, 0x93, 0x92, 0x8f, 0x7e, 0x70, 0x6f, 0x70, + 0x6d, 0x71, 0x78, 0x76, 0x74, 0x75, 0x75, 0x6e, 0x6e, 0x72, 0x7d, 0x8b, 0x89, 0x85, 0x7e, 0x76, + 0x73, 0x79, 0x7a, 0x75, 0x75, 0x81, 0x8b, 0x90, 0x91, 0x95, 0x9b, 0x96, 0x92, 0x94, 0x8d, 0x85, + 0x86, 0x8b, 0x8f, 0x8c, 0x83, 0x7b, 0x77, 0x7b, 0x7d, 0x82, 0x7d, 0x71, 0x68, 0x65, 0x65, 0x6d, + 0x74, 0x71, 0x6c, 0x6e, 0x73, 0x78, 0x80, 0x81, 0x84, 0x85, 0x7d, 0x76, 0x73, 0x72, 0x75, 0x79, + 0x7a, 0x7a, 0x7a, 0x7b, 0x7c, 0x7e, 0x83, 0x87, 0x88, 0x84, 0x81, 0x82, 0x7c, 0x75, 0x6e, 0x69, + 0x69, 0x68, 0x69, 0x6e, 0x71, 0x70, 0x70, 0x75, 0x75, 0x6d, 0x69, 0x68, 0x6b, 0x72, 0x7a, 0x7e, + 0x82, 0x84, 0x84, 0x84, 0x83, 0x83, 0x84, 0x84, 0x83, 0x79, 0x76, 0x7a, 0x82, 0x88, 0x8a, 0x8c, + 0x8f, 0x90, 0x90, 0x93, 0x96, 0x9e, 0xa0, 0x94, 0x8a, 0x85, 0x7c, 0x7c, 0x7e, 0x7a, 0x75, 0x70, + 0x74, 0x7e, 0x80, 0x7a, 0x78, 0x78, 0x77, 0x76, 0x77, 0x7a, 0x82, 0x84, 0x85, 0x83, 0x84, 0x89, + 0x8d, 0x90, 0x8e, 0x8c, 0x8d, 0x8c, 0x89, 0x85, 0x84, 0x85, 0x89, 0x8a, 0x8d, 0x8f, 0x90, 0x8d, + 0x85, 0x7e, 0x7d, 0x7e, 0x81, 0x7e, 0x7b, 0x76, 0x74, 0x7c, 0x80, 0x7b, 0x76, 0x70, 0x71, 0x78, + 0x7b, 0x7d, 0x81, 0x81, 0x7b, 0x74, 0x70, 0x72, 0x76, 0x7a, 0x7e, 0x80, 0x7d, 0x80, 0x84, 0x87, + 0x89, 0x88, 0x83, 0x81, 0x7d, 0x76, 0x77, 0x7d, 0x80, 0x7a, 0x78, 0x7b, 0x7c, 0x80, 0x81, 0x81, + 0x81, 0x85, 0x8d, 0x91, 0x90, 0x89, 0x84, 0x83, 0x84, 0x89, 0x89, 0x89, 0x8b, 0x8b, 0x8a, 0x87, + 0x85, 0x83, 0x82, 0x7c, 0x77, 0x79, 0x7e, 0x85, 0x86, 0x86, 0x8b, 0x8f, 0x91, 0x93, 0x91, 0x8f, + 0x8c, 0x83, 0x7a, 0x76, 0x75, 0x7a, 0x7d, 0x7d, 0x79, 0x74, 0x77, 0x7d, 0x83, 0x83, 0x80, 0x7c, + 0x7c, 0x80, 0x81, 0x85, 0x89, 0x8b, 0x89, 0x86, 0x83, 0x86, 0x8b, 0x8e, 0x90, 0x8d, 0x89, 0x87, + 0x86, 0x85, 0x85, 0x87, 0x8b, 0x8a, 0x87, 0x87, 0x87, 0x86, 0x80, 0x7c, 0x7d, 0x7b, 0x76, 0x72, + 0x6b, 0x62, 0x64, 0x6b, 0x75, 0x79, 0x75, 0x73, 0x72, 0x71, 0x76, 0x79, 0x7b, 0x82, 0x82, 0x7d, + 0x78, 0x74, 0x74, 0x74, 0x70, 0x6c, 0x67, 0x66, 0x66, 0x69, 0x6d, 0x6d, 0x6a, 0x66, 0x61, 0x5b, + 0x5d, 0x61, 0x62, 0x61, 0x5f, 0x63, 0x69, 0x6c, 0x6c, 0x69, 0x63, 0x61, 0x66, 0x6a, 0x6e, 0x6e, + 0x70, 0x72, 0x75, 0x79, 0x7d, 0x80, 0x85, 0x8a, 0x8b, 0x8c, 0x8b, 0x8f, 0x92, 0x91, 0x90, 0x8f, + 0x8f, 0x90, 0x8e, 0x8c, 0x8d, 0x8f, 0x8f, 0x91, 0x92, 0x8f, 0x8b, 0x86, 0x7e, 0x7d, 0x81, 0x83, + 0x85, 0x87, 0x84, 0x81, 0x81, 0x84, 0x8a, 0x8b, 0x89, 0x83, 0x7c, 0x7a, 0x7c, 0x81, 0x8a, 0x92, + 0x93, 0x91, 0x8d, 0x8f, 0x94, 0x96, 0x9b, 0x9b, 0x98, 0x98, 0x98, 0x99, 0x9b, 0x9b, 0x99, 0x98, + 0x95, 0x91, 0x8a, 0x83, 0x7d, 0x78, 0x7a, 0x7b, 0x78, 0x73, 0x71, 0x6f, 0x6f, 0x72, 0x79, 0x7c, + 0x7c, 0x80, 0x81, 0x80, 0x7d, 0x82, 0x83, 0x83, 0x81, 0x7d, 0x7c, 0x7b, 0x7c, 0x83, 0x86, 0x84, + 0x82, 0x81, 0x82, 0x86, 0x87, 0x89, 0x8a, 0x8b, 0x8b, 0x88, 0x88, 0x89, 0x85, 0x80, 0x77, 0x74, + 0x76, 0x78, 0x78, 0x79, 0x79, 0x75, 0x74, 0x74, 0x79, 0x7c, 0x7a, 0x7b, 0x7c, 0x7e, 0x83, 0x86, + 0x88, 0x87, 0x84, 0x81, 0x80, 0x7a, 0x77, 0x78, 0x78, 0x7b, 0x80, 0x84, 0x86, 0x85, 0x85, 0x85, + 0x88, 0x89, 0x87, 0x86, 0x89, 0x8d, 0x88, 0x83, 0x81, 0x82, 0x81, 0x7c, 0x75, 0x71, 0x6f, 0x6c, + 0x6c, 0x6d, 0x6f, 0x6b, 0x63, 0x60, 0x64, 0x6a, 0x72, 0x78, 0x7c, 0x80, 0x80, 0x7e, 0x7e, 0x83, + 0x87, 0x8b, 0x87, 0x85, 0x82, 0x83, 0x86, 0x87, 0x8a, 0x8a, 0x89, 0x88, 0x85, 0x85, 0x82, 0x7c, + 0x76, 0x77, 0x7a, 0x7a, 0x7a, 0x78, 0x75, 0x72, 0x72, 0x73, 0x72, 0x73, 0x70, 0x69, 0x68, 0x6c, + 0x71, 0x74, 0x75, 0x74, 0x73, 0x70, 0x6e, 0x72, 0x75, 0x76, 0x7a, 0x79, 0x76, 0x75, 0x76, 0x79, + 0x79, 0x74, 0x6f, 0x6d, 0x6b, 0x6f, 0x71, 0x72, 0x72, 0x70, 0x76, 0x7a, 0x79, 0x7c, 0x7a, 0x78, + 0x7d, 0x83, 0x8a, 0x8f, 0x8e, 0x8a, 0x86, 0x80, 0x82, 0x8a, 0x8c, 0x8c, 0x89, 0x88, 0x89, 0x89, + 0x89, 0x8b, 0x8b, 0x88, 0x8b, 0x8f, 0x94, 0x9a, 0x9c, 0x9f, 0x9d, 0x9a, 0x98, 0x94, 0x92, 0x90, + 0x8a, 0x87, 0x84, 0x82, 0x88, 0x8b, 0x88, 0x84, 0x81, 0x80, 0x82, 0x85, 0x85, 0x84, 0x7c, 0x73, + 0x79, 0x81, 0x86, 0x88, 0x86, 0x82, 0x7e, 0x7b, 0x78, 0x76, 0x79, 0x7d, 0x7c, 0x7c, 0x7d, 0x7c, + 0x7d, 0x7e, 0x80, 0x81, 0x81, 0x7e, 0x82, 0x85, 0x87, 0x86, 0x81, 0x7c, 0x7c, 0x7a, 0x78, 0x75, + 0x71, 0x71, 0x73, 0x81, 0x8a, 0x8b, 0x86, 0x81, 0x7e, 0x81, 0x8e, 0x95, 0x93, 0x90, 0x8f, 0x8b, + 0x87, 0x87, 0x86, 0x84, 0x82, 0x80, 0x79, 0x77, 0x78, 0x78, 0x77, 0x75, 0x75, 0x74, 0x70, 0x6c, + 0x6e, 0x6f, 0x6e, 0x6d, 0x6f, 0x73, 0x73, 0x75, 0x79, 0x77, 0x76, 0x75, 0x78, 0x7b, 0x7c, 0x7c, + 0x7e, 0x7b, 0x7a, 0x86, 0x8b, 0x8f, 0x8f, 0x8d, 0x8a, 0x83, 0x82, 0x85, 0x85, 0x83, 0x83, 0x84, + 0x85, 0x86, 0x88, 0x88, 0x80, 0x7d, 0x7e, 0x7d, 0x7c, 0x7e, 0x80, 0x7d, 0x7a, 0x79, 0x7d, 0x81, + 0x80, 0x7d, 0x7d, 0x78, 0x70, 0x72, 0x75, 0x74, 0x71, 0x6d, 0x6d, 0x6d, 0x6c, 0x73, 0x74, 0x78, + 0x82, 0x83, 0x82, 0x8d, 0x91, 0x95, 0x94, 0x92, 0x92, 0x91, 0x95, 0x9a, 0x9e, 0x9d, 0x9b, 0x96, + 0x92, 0x91, 0x8d, 0x83, 0x7d, 0x80, 0x87, 0x87, 0x85, 0x85, 0x76, 0x6d, 0x6f, 0x73, 0x7a, 0x7d, + 0x80, 0x7c, 0x7b, 0x7c, 0x7a, 0x77, 0x6f, 0x6f, 0x6f, 0x73, 0x7e, 0x83, 0x85, 0x89, 0x89, 0x85, + 0x81, 0x74, 0x71, 0x77, 0x81, 0x86, 0x88, 0x85, 0x81, 0x7a, 0x78, 0x77, 0x71, 0x6c, 0x6e, 0x70, + 0x71, 0x73, 0x74, 0x71, 0x69, 0x63, 0x6a, 0x69, 0x65, 0x68, 0x6f, 0x78, 0x82, 0x89, 0x8e, 0x8d, + 0x81, 0x78, 0x70, 0x66, 0x70, 0x75, 0x77, 0x7c, 0x84, 0x83, 0x7e, 0x83, 0x89, 0x87, 0x7d, 0x7b, + 0x7d, 0x76, 0x7e, 0x86, 0x82, 0x7e, 0x7e, 0x81, 0x8c, 0x90, 0x8d, 0x8b, 0x8a, 0x89, 0x85, 0x81, + 0x80, 0x81, 0x74, 0x73, 0x73, 0x6e, 0x68, 0x6b, 0x6e, 0x71, 0x77, 0x7a, 0x7c, 0x7c, 0x86, 0x8e, + 0x8f, 0x91, 0x93, 0x8b, 0x82, 0x84, 0x8c, 0x91, 0x91, 0x8e, 0x91, 0x95, 0x92, 0x90, 0x85, 0x7c, + 0x83, 0x88, 0x85, 0x8c, 0x89, 0x86, 0x84, 0x80, 0x7a, 0x80, 0x83, 0x7d, 0x76, 0x75, 0x7c, 0x7e, + 0x7e, 0x80, 0x81, 0x79, 0x6e, 0x6f, 0x75, 0x76, 0x86, 0x96, 0x9f, 0x9d, 0x95, 0x89, 0x86, 0x8f, + 0x94, 0x88, 0x84, 0x7c, 0x77, 0x76, 0x76, 0x75, 0x75, 0x79, 0x82, 0x85, 0x86, 0x87, 0x83, 0x7b, + 0x85, 0x93, 0x90, 0x81, 0x80, 0x82, 0x79, 0x77, 0x7c, 0x87, 0x8d, 0x8c, 0x85, 0x7d, 0x78, 0x73, + 0x6f, 0x71, 0x78, 0x78, 0x72, 0x74, 0x7b, 0x82, 0x89, 0x8b, 0x89, 0x81, 0x78, 0x7b, 0x82, 0x7b, + 0x75, 0x72, 0x70, 0x6f, 0x76, 0x78, 0x7a, 0x82, 0x8f, 0x9a, 0x90, 0x7a, 0x6e, 0x73, 0x6d, 0x67, + 0x71, 0x7b, 0x7e, 0x80, 0x7d, 0x77, 0x6e, 0x76, 0x8e, 0x8e, 0x84, 0x7e, 0x86, 0x86, 0x83, 0x83, + 0x80, 0x7e, 0x84, 0x8e, 0x91, 0x90, 0x9c, 0xa0, 0x9c, 0x9c, 0x98, 0x92, 0x87, 0x7b, 0x72, 0x6b, + 0x6a, 0x6d, 0x7d, 0x73, 0x71, 0x74, 0x77, 0x73, 0x61, 0x67, 0x7b, 0x78, 0x75, 0x6f, 0x66, 0x70, + 0x83, 0x80, 0x7b, 0x72, 0x66, 0x70, 0x7d, 0x7d, 0x77, 0x75, 0x6f, 0x68, 0x67, 0x5f, 0x50, 0x5a, + 0x69, 0x6a, 0x63, 0x66, 0x74, 0x7e, 0x82, 0x86, 0x7e, 0x73, 0x6d, 0x6f, 0x7b, 0x74, 0x67, 0x6f, + 0x73, 0x71, 0x77, 0x86, 0x8e, 0x80, 0x87, 0x8d, 0x8d, 0xa1, 0x9e, 0x93, 0x88, 0x7e, 0x7d, 0x88, + 0x8e, 0x85, 0x81, 0x87, 0x8d, 0x8e, 0x89, 0x86, 0x89, 0x87, 0x7d, 0x71, 0x6e, 0x75, 0x86, 0x96, + 0x9a, 0x96, 0x8f, 0x8c, 0x8d, 0x93, 0x92, 0x85, 0x85, 0x83, 0x7d, 0x7b, 0x6f, 0x6e, 0x7c, 0x77, + 0x75, 0x72, 0x83, 0x94, 0x97, 0x9a, 0x9a, 0x98, 0x94, 0x99, 0x96, 0x8d, 0x95, 0x9b, 0x94, 0x85, + 0x87, 0x91, 0x99, 0x91, 0x86, 0x83, 0x88, 0x8b, 0x8a, 0x83, 0x7c, 0x6d, 0x64, 0x82, 0x88, 0x7c, + 0x74, 0x75, 0x75, 0x76, 0x81, 0x82, 0x83, 0x87, 0x7e, 0x6b, 0x66, 0x7e, 0x92, 0x94, 0x8f, 0x8a, + 0x88, 0x81, 0x7c, 0x93, 0xa4, 0x98, 0x8e, 0x84, 0x70, 0x63, 0x5d, 0x63, 0x6e, 0x69, 0x6a, 0x72, + 0x80, 0x81, 0x79, 0x6e, 0x68, 0x70, 0x7e, 0x73, 0x5d, 0x64, 0x77, 0x7b, 0x7c, 0x7c, 0x83, 0x89, + 0x82, 0x7c, 0x7c, 0x85, 0x87, 0x85, 0x85, 0x85, 0x76, 0x68, 0x65, 0x6e, 0x81, 0x8d, 0x89, 0x83, + 0x81, 0x87, 0x88, 0x86, 0x83, 0x87, 0x82, 0x71, 0x6e, 0x83, 0x8c, 0x85, 0x7c, 0x7e, 0x8b, 0x88, + 0x76, 0x6c, 0x65, 0x61, 0x60, 0x5c, 0x5c, 0x62, 0x6b, 0x6e, 0x70, 0x75, 0x81, 0x8b, 0x92, 0xa1, + 0x9d, 0x8e, 0x8a, 0x8b, 0x8b, 0x89, 0x8e, 0x92, 0x94, 0x99, 0x9a, 0x93, 0x86, 0x82, 0x88, 0x94, + 0xa9, 0xa8, 0x9e, 0x97, 0x8e, 0x7c, 0x6b, 0x66, 0x74, 0x7a, 0x72, 0x6e, 0x72, 0x75, 0x6a, 0x5f, + 0x5f, 0x63, 0x68, 0x70, 0x68, 0x6b, 0x7e, 0x82, 0x84, 0x85, 0x7d, 0x78, 0x79, 0x81, 0x8e, 0x8f, + 0x88, 0x81, 0x7b, 0x7b, 0x69, 0x5e, 0x60, 0x5c, 0x61, 0x6c, 0x6e, 0x6f, 0x7b, 0x87, 0x87, 0x88, + 0x93, 0x94, 0x7d, 0x6e, 0x6b, 0x6c, 0x6b, 0x78, 0x8d, 0x8d, 0x87, 0x8b, 0x8f, 0x89, 0x7d, 0x7c, + 0x7c, 0x7e, 0x82, 0x85, 0x87, 0x87, 0x81, 0x7a, 0x76, 0x81, 0x89, 0x92, 0x97, 0x95, 0x97, 0x93, + 0x89, 0x86, 0x81, 0x85, 0x8e, 0x8c, 0x8d, 0x93, 0x94, 0x92, 0x95, 0x9d, 0x9d, 0x91, 0x87, 0x7e, + 0x78, 0x76, 0x75, 0x74, 0x6e, 0x6a, 0x7c, 0x8d, 0x8b, 0x89, 0x86, 0x7a, 0x78, 0x80, 0x80, 0x72, + 0x72, 0x7b, 0x87, 0x91, 0x87, 0x80, 0x84, 0x84, 0x87, 0x9a, 0x98, 0x8d, 0x7b, 0x74, 0x77, 0x75, + 0x69, 0x6d, 0x7b, 0x71, 0x6a, 0x6c, 0x6d, 0x63, 0x6a, 0x80, 0x85, 0x87, 0x85, 0x7d, 0x74, 0x79, + 0x8e, 0x91, 0x87, 0x85, 0x8f, 0x8f, 0x8f, 0x86, 0x89, 0x8a, 0x79, 0x6d, 0x72, 0x70, 0x6c, 0x6f, + 0x7a, 0x7d, 0x71, 0x6a, 0x6d, 0x6b, 0x6e, 0x73, 0x78, 0x75, 0x7a, 0x83, 0x7c, 0x73, 0x73, 0x78, + 0x75, 0x75, 0x7d, 0x82, 0x76, 0x6e, 0x82, 0x9a, 0x9c, 0x9c, 0x9a, 0x8f, 0x85, 0x84, 0x88, 0x8a, + 0x82, 0x70, 0x66, 0x6f, 0x6d, 0x6b, 0x75, 0x77, 0x79, 0x83, 0x81, 0x7e, 0x7c, 0x7e, 0x81, 0x85, + 0x84, 0x7c, 0x7a, 0x89, 0x9a, 0x8c, 0x82, 0x81, 0x71, 0x69, 0x67, 0x73, 0x7a, 0x84, 0x8c, 0x8c, + 0x79, 0x72, 0x8a, 0x9b, 0xa5, 0xa6, 0xa2, 0xa5, 0xa1, 0x97, 0x9b, 0x9e, 0x99, 0x91, 0x91, 0x93, + 0x92, 0x9b, 0x9e, 0x8b, 0x7c, 0x86, 0x7b, 0x72, 0x76, 0x74, 0x77, 0x6d, 0x6f, 0x6b, 0x63, 0x57, + 0x51, 0x5e, 0x6a, 0x6e, 0x71, 0x77, 0x6d, 0x68, 0x65, 0x5c, 0x69, 0x7b, 0x83, 0x82, 0x7e, 0x79, + 0x79, 0x83, 0x86, 0x86, 0x84, 0x6e, 0x58, 0x52, 0x67, 0x7c, 0x7c, 0x70, 0x6c, 0x62, 0x51, 0x52, + 0x5e, 0x60, 0x63, 0x6a, 0x79, 0x75, 0x60, 0x5b, 0x63, 0x6e, 0x75, 0x6d, 0x6e, 0x79, 0x87, 0xa8, + 0xb8, 0x9c, 0x92, 0x8c, 0x8f, 0x8a, 0x8c, 0x91, 0x9d, 0xa0, 0xa4, 0xaf, 0xa8, 0x8f, 0x87, 0x8d, + 0x9d, 0xa5, 0xa8, 0x9c, 0x8e, 0x8a, 0x88, 0x89, 0x97, 0x99, 0x93, 0x95, 0x86, 0x8d, 0xa3, 0x92, + 0x82, 0x80, 0x71, 0x62, 0x66, 0x70, 0x79, 0x83, 0x84, 0x88, 0x80, 0x6e, 0x68, 0x86, 0x9a, 0x9c, + 0x94, 0x8b, 0x83, 0x7b, 0x73, 0x6f, 0x71, 0x81, 0x89, 0x8f, 0x95, 0x8f, 0x90, 0x8f, 0x91, 0x94, + 0x8d, 0x70, 0x68, 0x78, 0x7c, 0x7e, 0x7d, 0x81, 0x7e, 0x6c, 0x5a, 0x55, 0x5a, 0x64, 0x6c, 0x6e, + 0x6e, 0x6f, 0x6b, 0x63, 0x68, 0x72, 0x74, 0x7b, 0x8c, 0x92, 0x9f, 0xab, 0xa0, 0x92, 0x89, 0x80, + 0x6e, 0x64, 0x72, 0x7b, 0x79, 0x7c, 0x8a, 0x90, 0x85, 0x71, 0x75, 0x82, 0x8c, 0x8a, 0x7e, 0x7d, + 0x80, 0x7c, 0x7a, 0x85, 0x8a, 0x82, 0x81, 0x84, 0x8c, 0x92, 0x8e, 0x85, 0x7b, 0x75, 0x6d, 0x6b, + 0x6d, 0x75, 0x82, 0x7d, 0x7c, 0x82, 0x87, 0x85, 0x82, 0x89, 0x8c, 0x8e, 0x87, 0x80, 0x80, 0x81, + 0x80, 0x7c, 0x7a, 0x7a, 0x7d, 0x7d, 0x7d, 0x7d, 0x7a, 0x7a, 0x79, 0x7a, 0x79, 0x75, 0x72, 0x72, + 0x76, 0x7a, 0x7b, 0x80, 0x7d, 0x79, 0x75, 0x74, 0x79, 0x7d, 0x82, 0x7e, 0x7a, 0x79, 0x7d, 0x84, + 0x88, 0x86, 0x82, 0x7e, 0x7e, 0x87, 0x95, 0x99, 0x97, 0x93, 0x8e, 0x8b, 0x89, 0x89, 0x85, 0x7b, + 0x74, 0x72, 0x72, 0x73, 0x77, 0x78, 0x77, 0x78, 0x79, 0x7a, 0x76, 0x75, 0x77, 0x77, 0x74, 0x71, + 0x71, 0x72, 0x70, 0x6f, 0x6e, 0x6e, 0x6f, 0x72, 0x73, 0x71, 0x70, 0x6e, 0x6e, 0x6f, 0x72, 0x76, + 0x7d, 0x7e, 0x80, 0x86, 0x87, 0x87, 0x84, 0x85, 0x85, 0x7c, 0x79, 0x79, 0x7b, 0x82, 0x82, 0x80, + 0x82, 0x80, 0x7d, 0x81, 0x85, 0x8b, 0x90, 0x8e, 0x89, 0x8b, 0x90, 0x91, 0x91, 0x8f, 0x8c, 0x8d, + 0x8f, 0x92, 0x92, 0x8c, 0x86, 0x83, 0x83, 0x83, 0x82, 0x81, 0x80, 0x81, 0x83, 0x86, 0x87, 0x87, + 0x87, 0x86, 0x84, 0x7d, 0x7a, 0x83, 0x8c, 0x8f, 0x90, 0x8b, 0x83, 0x7e, 0x7c, 0x7e, 0x83, 0x84, + 0x84, 0x80, 0x7d, 0x80, 0x84, 0x82, 0x7c, 0x79, 0x79, 0x7b, 0x7e, 0x81, 0x7d, 0x79, 0x78, 0x76, + 0x74, 0x78, 0x7c, 0x80, 0x80, 0x7b, 0x79, 0x79, 0x77, 0x77, 0x74, 0x70, 0x70, 0x73, 0x7c, 0x82, + 0x81, 0x7b, 0x77, 0x7a, 0x7a, 0x7a, 0x7e, 0x7c, 0x7b, 0x79, 0x7a, 0x7c, 0x80, 0x82, 0x7e, 0x7d, + 0x82, 0x87, 0x8c, 0x8c, 0x89, 0x86, 0x81, 0x7b, 0x7b, 0x7a, 0x7c, 0x86, 0x8a, 0x89, 0x80, 0x77, + 0x76, 0x76, 0x76, 0x72, 0x6f, 0x6f, 0x6f, 0x6f, 0x75, 0x7a, 0x79, 0x7a, 0x80, 0x81, 0x7b, 0x78, + 0x7d, 0x83, 0x84, 0x83, 0x84, 0x84, 0x81, 0x80, 0x7e, 0x7d, 0x86, 0x8d, 0x8d, 0x89, 0x88, 0x88, + 0x85, 0x83, 0x83, 0x85, 0x87, 0x87, 0x87, 0x85, 0x82, 0x80, 0x7e, 0x7c, 0x77, 0x71, 0x6f, 0x72, + 0x74, 0x75, 0x72, 0x74, 0x75, 0x74, 0x75, 0x78, 0x7e, 0x88, 0x91, 0x8e, 0x89, 0x86, 0x86, 0x8c, + 0x90, 0x91, 0x94, 0x97, 0x9a, 0x9a, 0x9a, 0x98, 0x96, 0x94, 0x93, 0x93, 0x98, 0x97, 0x95, 0x92, + 0x8c, 0x86, 0x84, 0x83, 0x82, 0x7d, 0x77, 0x76, 0x78, 0x76, 0x72, 0x70, 0x71, 0x6f, 0x6b, 0x63, + 0x5f, 0x64, 0x6a, 0x6b, 0x6a, 0x6b, 0x6d, 0x70, 0x73, 0x72, 0x6e, 0x6d, 0x6f, 0x72, 0x75, 0x75, + 0x74, 0x72, 0x75, 0x78, 0x79, 0x7c, 0x84, 0x85, 0x82, 0x7e, 0x7d, 0x7a, 0x7a, 0x7a, 0x73, 0x6c, + 0x6b, 0x70, 0x73, 0x75, 0x7b, 0x80, 0x80, 0x7b, 0x75, 0x74, 0x7a, 0x7d, 0x79, 0x76, 0x7c, 0x81, + 0x82, 0x86, 0x89, 0x8a, 0x90, 0x96, 0x99, 0x95, 0x8d, 0x89, 0x8a, 0x8c, 0x8b, 0x8a, 0x8b, 0x8c, + 0x8c, 0x8d, 0x8a, 0x85, 0x83, 0x82, 0x81, 0x7e, 0x79, 0x74, 0x70, 0x71, 0x78, 0x7a, 0x7b, 0x7b, + 0x7a, 0x77, 0x78, 0x7e, 0x85, 0x81, 0x79, 0x78, 0x78, 0x78, 0x77, 0x76, 0x76, 0x75, 0x7a, 0x80, + 0x82, 0x84, 0x86, 0x89, 0x88, 0x84, 0x86, 0x8d, 0x8f, 0x8d, 0x8a, 0x8a, 0x8c, 0x8b, 0x8c, 0x8a, + 0x87, 0x86, 0x81, 0x7c, 0x7d, 0x82, 0x84, 0x83, 0x82, 0x7e, 0x79, 0x76, 0x79, 0x81, 0x83, 0x81, + 0x84, 0x8a, 0x88, 0x85, 0x82, 0x81, 0x82, 0x82, 0x81, 0x7d, 0x7c, 0x80, 0x82, 0x83, 0x80, 0x85, + 0x8a, 0x8b, 0x86, 0x7e, 0x7b, 0x7d, 0x7e, 0x80, 0x7e, 0x79, 0x74, 0x74, 0x73, 0x74, 0x7b, 0x81, + 0x86, 0x85, 0x84, 0x87, 0x87, 0x86, 0x83, 0x7a, 0x79, 0x7d, 0x82, 0x86, 0x89, 0x8a, 0x8a, 0x8d, + 0x8d, 0x87, 0x83, 0x81, 0x7d, 0x7d, 0x80, 0x81, 0x83, 0x85, 0x85, 0x82, 0x7e, 0x7e, 0x7e, 0x7c, + 0x78, 0x73, 0x6d, 0x6b, 0x6b, 0x67, 0x65, 0x69, 0x70, 0x77, 0x7a, 0x7c, 0x7b, 0x7b, 0x83, 0x87, + 0x85, 0x84, 0x84, 0x82, 0x82, 0x85, 0x86, 0x8a, 0x8d, 0x92, 0x93, 0x93, 0x92, 0x8c, 0x88, 0x86, + 0x86, 0x89, 0x88, 0x84, 0x80, 0x7c, 0x7a, 0x7b, 0x7c, 0x7a, 0x7a, 0x77, 0x73, 0x6f, 0x6b, 0x69, + 0x6c, 0x72, 0x75, 0x71, 0x6a, 0x66, 0x6a, 0x70, 0x71, 0x71, 0x71, 0x6e, 0x6c, 0x6a, 0x6c, 0x6f, + 0x6f, 0x6d, 0x6c, 0x6c, 0x6a, 0x6c, 0x71, 0x73, 0x78, 0x81, 0x83, 0x81, 0x7e, 0x79, 0x75, 0x73, + 0x72, 0x77, 0x78, 0x75, 0x75, 0x76, 0x75, 0x76, 0x7e, 0x89, 0x8c, 0x8b, 0x88, 0x84, 0x85, 0x88, + 0x8c, 0x8c, 0x8a, 0x8b, 0x8c, 0x8f, 0x93, 0x96, 0x95, 0x94, 0x92, 0x94, 0x94, 0x93, 0x91, 0x90, + 0x90, 0x8d, 0x8c, 0x90, 0x90, 0x91, 0x93, 0x93, 0x92, 0x8c, 0x87, 0x83, 0x7b, 0x74, 0x71, 0x72, + 0x73, 0x78, 0x7e, 0x8a, 0x90, 0x8c, 0x8a, 0x8b, 0x8d, 0x8e, 0x8e, 0x8d, 0x90, 0x91, 0x8d, 0x8c, + 0x8c, 0x85, 0x81, 0x81, 0x84, 0x85, 0x82, 0x7d, 0x7a, 0x79, 0x76, 0x75, 0x78, 0x75, 0x72, 0x70, + 0x6e, 0x6d, 0x70, 0x70, 0x69, 0x6b, 0x74, 0x73, 0x6b, 0x68, 0x6c, 0x72, 0x76, 0x78, 0x74, 0x6b, + 0x68, 0x6e, 0x76, 0x7b, 0x79, 0x77, 0x78, 0x7b, 0x81, 0x82, 0x7d, 0x7c, 0x7d, 0x84, 0x87, 0x87, + 0x8a, 0x8f, 0x91, 0x92, 0x97, 0x9a, 0x96, 0x91, 0x8f, 0x8b, 0x87, 0x84, 0x81, 0x79, 0x73, 0x73, + 0x76, 0x74, 0x77, 0x7b, 0x7d, 0x81, 0x82, 0x7d, 0x77, 0x77, 0x79, 0x7d, 0x80, 0x80, 0x80, 0x83, + 0x87, 0x8a, 0x8c, 0x8a, 0x82, 0x7c, 0x86, 0x8b, 0x87, 0x84, 0x83, 0x81, 0x80, 0x82, 0x83, 0x82, + 0x84, 0x80, 0x79, 0x71, 0x6e, 0x6f, 0x6a, 0x64, 0x64, 0x5c, 0x5b, 0x60, 0x68, 0x71, 0x76, 0x77, + 0x78, 0x79, 0x7d, 0x83, 0x86, 0x84, 0x84, 0x84, 0x86, 0x8c, 0x90, 0x91, 0x91, 0x95, 0x9c, 0xa1, + 0xa2, 0x9d, 0x98, 0x98, 0x96, 0x90, 0x8d, 0x8d, 0x92, 0x8f, 0x87, 0x81, 0x84, 0x81, 0x7e, 0x7c, + 0x77, 0x6e, 0x66, 0x62, 0x65, 0x76, 0x82, 0x84, 0x81, 0x79, 0x6e, 0x6d, 0x6f, 0x70, 0x6f, 0x6e, + 0x72, 0x74, 0x76, 0x78, 0x72, 0x6d, 0x6d, 0x6b, 0x6e, 0x70, 0x71, 0x7b, 0x83, 0x87, 0x88, 0x85, + 0x85, 0x86, 0x82, 0x82, 0x80, 0x79, 0x75, 0x77, 0x7b, 0x78, 0x76, 0x7a, 0x79, 0x7b, 0x79, 0x87, + 0x8b, 0x80, 0x7d, 0x84, 0x8b, 0x8e, 0x92, 0x95, 0x90, 0x87, 0x8d, 0x99, 0x9c, 0x97, 0x93, 0x91, + 0x8f, 0x8e, 0x8f, 0x93, 0x96, 0x91, 0x8b, 0x89, 0x8b, 0x8d, 0x8b, 0x84, 0x79, 0x79, 0x77, 0x70, + 0x69, 0x68, 0x6b, 0x6a, 0x6a, 0x70, 0x71, 0x70, 0x61, 0x5c, 0x74, 0x7d, 0x74, 0x7e, 0x85, 0x7d, + 0x7a, 0x79, 0x78, 0x7c, 0x80, 0x79, 0x76, 0x75, 0x76, 0x7a, 0x76, 0x71, 0x75, 0x79, 0x74, 0x70, + 0x75, 0x81, 0x89, 0x88, 0x88, 0x88, 0x82, 0x82, 0x7e, 0x81, 0x84, 0x81, 0x80, 0x7c, 0x7b, 0x78, + 0x74, 0x74, 0x75, 0x7c, 0x85, 0x87, 0x8f, 0x98, 0x9b, 0x94, 0x8a, 0x87, 0x82, 0x84, 0x81, 0x82, + 0x8f, 0x99, 0x9b, 0x9a, 0x9a, 0x8d, 0x89, 0x8e, 0x83, 0x87, 0x8b, 0x82, 0x74, 0x6c, 0x6c, 0x74, + 0x7a, 0x76, 0x71, 0x69, 0x65, 0x68, 0x6a, 0x72, 0x7b, 0x7d, 0x75, 0x76, 0x7a, 0x7c, 0x8c, 0x8f, + 0x91, 0x9a, 0x99, 0x93, 0x8d, 0x8c, 0x9d, 0x95, 0x85, 0x8c, 0x8f, 0x89, 0x89, 0x88, 0x83, 0x86, + 0x83, 0x79, 0x84, 0x8e, 0x8f, 0x8c, 0x8a, 0x8e, 0x88, 0x70, 0x62, 0x63, 0x5f, 0x5b, 0x5a, 0x60, + 0x70, 0x77, 0x75, 0x71, 0x6d, 0x79, 0x80, 0x74, 0x85, 0x89, 0x7b, 0x72, 0x72, 0x79, 0x7e, 0x88, + 0x8e, 0x89, 0x88, 0x91, 0x9c, 0x9c, 0x95, 0x8d, 0x88, 0x82, 0x86, 0x91, 0x93, 0x8f, 0x90, 0x90, + 0x82, 0x75, 0x6e, 0x64, 0x74, 0x7c, 0x6f, 0x70, 0x7b, 0x7a, 0x70, 0x69, 0x60, 0x6e, 0x76, 0x70, + 0x6c, 0x73, 0x78, 0x72, 0x72, 0x71, 0x6d, 0x71, 0x6b, 0x60, 0x68, 0x72, 0x76, 0x7d, 0x88, 0x85, + 0x81, 0x86, 0x8a, 0x92, 0x93, 0x87, 0x83, 0x8b, 0x84, 0x75, 0x71, 0x6b, 0x67, 0x64, 0x64, 0x6d, + 0x71, 0x72, 0x78, 0x73, 0x6c, 0x76, 0x8c, 0x92, 0x88, 0x86, 0x87, 0x89, 0x8a, 0x85, 0x81, 0x83, + 0x8d, 0x92, 0x8f, 0x8c, 0x89, 0x85, 0x86, 0x84, 0x7c, 0x79, 0x88, 0x93, 0x9a, 0x9c, 0x99, 0x94, + 0x8b, 0x8c, 0x88, 0x80, 0x7c, 0x7d, 0x79, 0x6b, 0x6d, 0x73, 0x72, 0x70, 0x6e, 0x69, 0x75, 0x91, + 0x99, 0x95, 0x8d, 0x79, 0x61, 0x6f, 0x7b, 0x75, 0x81, 0x8b, 0x8a, 0x84, 0x7d, 0x77, 0x74, 0x77, + 0x72, 0x6d, 0x72, 0x75, 0x79, 0x84, 0x84, 0x83, 0x83, 0x7e, 0x8c, 0x89, 0x7c, 0x76, 0x75, 0x85, + 0x81, 0x7a, 0x82, 0x8a, 0x8d, 0x8d, 0x81, 0x77, 0x8c, 0x98, 0x96, 0x8e, 0x81, 0x77, 0x81, 0x91, + 0x8e, 0x8c, 0x91, 0x88, 0x8d, 0x9c, 0x99, 0x96, 0x91, 0x92, 0x94, 0x8d, 0x83, 0x85, 0x97, 0x92, + 0x86, 0x78, 0x6d, 0x6e, 0x6c, 0x66, 0x60, 0x65, 0x6a, 0x65, 0x63, 0x64, 0x6c, 0x70, 0x6c, 0x5e, + 0x68, 0x87, 0x94, 0x9c, 0xa9, 0x9a, 0x83, 0x78, 0x87, 0x88, 0x84, 0x81, 0x8b, 0x8b, 0x7c, 0x7a, + 0x7a, 0x6d, 0x60, 0x67, 0x7e, 0x8b, 0x96, 0x95, 0x91, 0x87, 0x72, 0x7c, 0x8a, 0x79, 0x69, 0x5e, + 0x5c, 0x60, 0x65, 0x6e, 0x6f, 0x6d, 0x70, 0x65, 0x61, 0x7e, 0x98, 0x92, 0x88, 0x82, 0x81, 0x7c, + 0x6e, 0x70, 0x87, 0x8c, 0x8c, 0x98, 0xa3, 0x9f, 0x96, 0x86, 0x87, 0x8c, 0x89, 0x84, 0x84, 0x91, + 0x9c, 0x98, 0x92, 0x88, 0x84, 0x96, 0x94, 0x89, 0x8d, 0x92, 0x7a, 0x63, 0x5d, 0x65, 0x63, 0x54, + 0x4c, 0x60, 0x78, 0x82, 0x85, 0x8c, 0x89, 0x7e, 0x6f, 0x68, 0x64, 0x68, 0x72, 0x6f, 0x74, 0x87, + 0x88, 0x80, 0x74, 0x6b, 0x6e, 0x73, 0x88, 0x9f, 0x99, 0x8a, 0x7b, 0x74, 0x6e, 0x70, 0x72, 0x69, + 0x6f, 0x75, 0x71, 0x70, 0x77, 0x79, 0x7a, 0x86, 0x8d, 0x8c, 0x86, 0x89, 0x86, 0x7c, 0x7e, 0x8d, + 0x8c, 0x83, 0x84, 0x90, 0x8f, 0x9a, 0xa8, 0xa0, 0x96, 0x8d, 0x82, 0x7c, 0x7d, 0x77, 0x70, 0x7d, + 0x8d, 0x90, 0x8d, 0x91, 0x8b, 0x7b, 0x8d, 0x96, 0x83, 0x7a, 0x73, 0x71, 0x6f, 0x67, 0x67, 0x69, + 0x68, 0x6b, 0x76, 0x7c, 0x96, 0x97, 0x89, 0x90, 0x8f, 0x85, 0x75, 0x71, 0x6a, 0x57, 0x61, 0x72, + 0x81, 0x80, 0x81, 0x85, 0x85, 0x85, 0x80, 0x70, 0x6b, 0x7b, 0x87, 0x89, 0x82, 0x7a, 0x83, 0x83, + 0x7a, 0x7e, 0x8b, 0x99, 0x8c, 0x78, 0x7d, 0x8c, 0x8a, 0x80, 0x78, 0x71, 0x7b, 0x8e, 0x86, 0x7d, + 0x82, 0x86, 0x89, 0x88, 0x8c, 0x7d, 0x6f, 0x80, 0x9b, 0xa7, 0xa0, 0x9a, 0x96, 0x92, 0x8d, 0x88, + 0x80, 0x8d, 0x9b, 0x92, 0x88, 0x82, 0x79, 0x76, 0x72, 0x61, 0x4f, 0x51, 0x60, 0x5b, 0x56, 0x5a, + 0x63, 0x62, 0x5e, 0x63, 0x64, 0x71, 0x80, 0x8b, 0x9a, 0x9a, 0x8e, 0x85, 0x82, 0x88, 0x8c, 0x86, + 0x7a, 0x8a, 0x86, 0x7a, 0x75, 0x78, 0x77, 0x7c, 0x86, 0x88, 0x8f, 0x98, 0x8e, 0x88, 0x84, 0x80, + 0x81, 0x78, 0x70, 0x7a, 0x7e, 0x7c, 0x78, 0x7c, 0x80, 0x76, 0x6a, 0x5f, 0x61, 0x66, 0x87, 0xa6, + 0xa6, 0x93, 0x8b, 0x8b, 0x87, 0x85, 0x90, 0x92, 0x8f, 0x93, 0x96, 0x99, 0x96, 0x8f, 0x93, 0x90, + 0x7a, 0x75, 0x79, 0x82, 0x8d, 0x8d, 0x83, 0x76, 0x87, 0xa4, 0x9c, 0x89, 0x86, 0x8b, 0x7c, 0x62, + 0x5c, 0x62, 0x62, 0x60, 0x6d, 0x73, 0x6d, 0x79, 0x8b, 0x88, 0x75, 0x74, 0x77, 0x6c, 0x61, 0x60, + 0x61, 0x62, 0x63, 0x66, 0x77, 0x83, 0x82, 0x89, 0x8c, 0x90, 0x87, 0x80, 0x84, 0x86, 0x74, 0x6b, + 0x5f, 0x5f, 0x6e, 0x72, 0x73, 0x74, 0x6f, 0x65, 0x5c, 0x69, 0x7c, 0x89, 0x84, 0x85, 0x78, 0x6e, + 0x82, 0x95, 0x9a, 0x99, 0x90, 0x94, 0xa4, 0xa3, 0xa2, 0x9d, 0x8e, 0x92, 0x83, 0x77, 0x87, 0x8c, + 0x8a, 0x7c, 0x7b, 0x84, 0x92, 0x90, 0x8c, 0x8d, 0x91, 0xa0, 0xa1, 0x89, 0x6b, 0x60, 0x62, 0x64, + 0x5c, 0x5a, 0x6c, 0x7a, 0x8a, 0x96, 0x90, 0x8d, 0x7a, 0x87, 0xa4, 0xa3, 0x99, 0x93, 0x90, 0x8a, + 0x80, 0x74, 0x76, 0x82, 0x7a, 0x71, 0x6d, 0x87, 0x98, 0x88, 0x75, 0x72, 0x74, 0x76, 0x78, 0x80, + 0x86, 0x7c, 0x7e, 0x8b, 0x87, 0x84, 0x82, 0x74, 0x70, 0x74, 0x77, 0x6d, 0x68, 0x6c, 0x73, 0x70, + 0x62, 0x61, 0x77, 0x84, 0x8a, 0x96, 0x96, 0x90, 0x84, 0x7c, 0x85, 0x87, 0x8c, 0x8d, 0x8b, 0x81, + 0x7c, 0x8b, 0x8d, 0x88, 0x92, 0x95, 0x8a, 0x7e, 0x83, 0x87, 0x81, 0x84, 0x8d, 0x82, 0x76, 0x72, + 0x67, 0x5a, 0x54, 0x5f, 0x6c, 0x6f, 0x71, 0x70, 0x6d, 0x72, 0x81, 0x8a, 0x90, 0x8e, 0x91, 0x98, + 0x95, 0x8c, 0x87, 0x87, 0x8b, 0x92, 0x95, 0x93, 0x81, 0x6f, 0x71, 0x7d, 0x85, 0x86, 0x86, 0x81, + 0x7d, 0x7c, 0x81, 0x88, 0x99, 0x98, 0x83, 0x79, 0x71, 0x6b, 0x67, 0x60, 0x63, 0x6b, 0x73, 0x77, + 0x74, 0x6b, 0x6b, 0x6b, 0x76, 0x83, 0x81, 0x7d, 0x7e, 0x80, 0x82, 0x85, 0x87, 0x89, 0x8b, 0x8d, + 0x8f, 0x8e, 0x84, 0x7e, 0x87, 0x8d, 0x8b, 0x86, 0x84, 0x88, 0x8e, 0x8d, 0x8b, 0x8c, 0x89, 0x84, + 0x83, 0x7b, 0x77, 0x77, 0x74, 0x71, 0x70, 0x6c, 0x6d, 0x6f, 0x71, 0x73, 0x72, 0x73, 0x77, 0x81, + 0x87, 0x84, 0x7a, 0x6d, 0x64, 0x65, 0x67, 0x68, 0x6d, 0x73, 0x78, 0x79, 0x75, 0x78, 0x83, 0x86, + 0x82, 0x82, 0x87, 0x8b, 0x8a, 0x8a, 0x89, 0x87, 0x86, 0x88, 0x86, 0x84, 0x84, 0x87, 0x8c, 0x8b, + 0x86, 0x84, 0x82, 0x80, 0x80, 0x7e, 0x81, 0x85, 0x8c, 0x8f, 0x91, 0x8d, 0x89, 0x87, 0x85, 0x81, + 0x80, 0x7c, 0x78, 0x74, 0x72, 0x75, 0x7c, 0x80, 0x80, 0x7d, 0x7c, 0x80, 0x86, 0x8d, 0x8d, 0x84, + 0x7c, 0x78, 0x72, 0x70, 0x70, 0x72, 0x7b, 0x82, 0x7d, 0x7c, 0x7b, 0x80, 0x81, 0x7b, 0x7b, 0x81, + 0x84, 0x84, 0x80, 0x7e, 0x81, 0x81, 0x80, 0x7b, 0x78, 0x7a, 0x7e, 0x81, 0x82, 0x7d, 0x7a, 0x7a, + 0x79, 0x75, 0x73, 0x75, 0x7a, 0x83, 0x8b, 0x8f, 0x8c, 0x85, 0x83, 0x83, 0x81, 0x83, 0x87, 0x8b, + 0x8d, 0x86, 0x81, 0x82, 0x88, 0x90, 0x91, 0x8f, 0x91, 0x8e, 0x8b, 0x8b, 0x88, 0x85, 0x82, 0x7e, + 0x7d, 0x7b, 0x7c, 0x7e, 0x80, 0x7c, 0x7c, 0x7d, 0x7d, 0x80, 0x82, 0x7e, 0x7b, 0x79, 0x79, 0x79, + 0x79, 0x74, 0x6c, 0x68, 0x66, 0x65, 0x6a, 0x76, 0x7a, 0x78, 0x75, 0x71, 0x71, 0x77, 0x7a, 0x7a, + 0x7a, 0x7e, 0x85, 0x87, 0x8c, 0x93, 0x93, 0x90, 0x8f, 0x8b, 0x88, 0x87, 0x87, 0x85, 0x7e, 0x7b, + 0x7d, 0x82, 0x84, 0x85, 0x80, 0x7e, 0x84, 0x88, 0x8c, 0x8b, 0x88, 0x81, 0x78, 0x71, 0x6e, 0x70, + 0x72, 0x70, 0x6c, 0x69, 0x68, 0x6b, 0x76, 0x7e, 0x7a, 0x75, 0x71, 0x6e, 0x6f, 0x76, 0x80, 0x83, + 0x85, 0x89, 0x8a, 0x8a, 0x92, 0x9a, 0x9a, 0x98, 0x92, 0x8d, 0x8d, 0x8c, 0x87, 0x84, 0x84, 0x89, + 0x8d, 0x8e, 0x8b, 0x86, 0x82, 0x80, 0x7d, 0x79, 0x78, 0x76, 0x74, 0x74, 0x73, 0x77, 0x7a, 0x78, + 0x79, 0x77, 0x75, 0x79, 0x81, 0x85, 0x85, 0x87, 0x85, 0x7e, 0x77, 0x6d, 0x69, 0x6b, 0x70, 0x79, + 0x80, 0x7e, 0x7e, 0x82, 0x82, 0x84, 0x87, 0x8a, 0x89, 0x86, 0x88, 0x86, 0x82, 0x7c, 0x77, 0x74, + 0x74, 0x77, 0x7d, 0x7e, 0x79, 0x71, 0x6b, 0x68, 0x6a, 0x69, 0x68, 0x67, 0x6c, 0x70, 0x73, 0x7a, + 0x7d, 0x81, 0x85, 0x83, 0x84, 0x87, 0x85, 0x82, 0x85, 0x87, 0x86, 0x83, 0x83, 0x86, 0x8c, 0x90, + 0x93, 0x95, 0x99, 0x97, 0x92, 0x8b, 0x84, 0x80, 0x79, 0x75, 0x75, 0x79, 0x7d, 0x7d, 0x7a, 0x7b, + 0x81, 0x87, 0x86, 0x80, 0x77, 0x71, 0x70, 0x74, 0x78, 0x79, 0x77, 0x74, 0x73, 0x75, 0x79, 0x7c, + 0x7e, 0x83, 0x82, 0x81, 0x83, 0x83, 0x85, 0x87, 0x8a, 0x8c, 0x8b, 0x8c, 0x8e, 0x8c, 0x89, 0x8c, + 0x90, 0x8d, 0x89, 0x88, 0x88, 0x87, 0x86, 0x85, 0x87, 0x8b, 0x89, 0x85, 0x84, 0x84, 0x82, 0x82, + 0x87, 0x86, 0x80, 0x7c, 0x79, 0x77, 0x7a, 0x7b, 0x7b, 0x7a, 0x78, 0x79, 0x7c, 0x83, 0x8c, 0x91, + 0x8f, 0x8a, 0x87, 0x84, 0x85, 0x86, 0x85, 0x83, 0x7c, 0x74, 0x70, 0x71, 0x73, 0x75, 0x75, 0x76, + 0x78, 0x79, 0x7b, 0x79, 0x74, 0x73, 0x78, 0x7c, 0x7d, 0x84, 0x8b, 0x89, 0x88, 0x88, 0x86, 0x7e, + 0x79, 0x77, 0x76, 0x76, 0x77, 0x76, 0x72, 0x72, 0x77, 0x7e, 0x89, 0x8b, 0x8b, 0x8d, 0x8c, 0x8a, + 0x83, 0x75, 0x6d, 0x6b, 0x72, 0x7c, 0x80, 0x7d, 0x7a, 0x77, 0x75, 0x75, 0x74, 0x70, 0x65, 0x62, + 0x6a, 0x6f, 0x76, 0x7e, 0x82, 0x7e, 0x7a, 0x7b, 0x81, 0x87, 0x8a, 0x8a, 0x87, 0x81, 0x7c, 0x7b, + 0x78, 0x78, 0x7d, 0x83, 0x84, 0x84, 0x86, 0x86, 0x87, 0x87, 0x86, 0x82, 0x7d, 0x7e, 0x83, 0x87, + 0x86, 0x85, 0x85, 0x89, 0x8d, 0x8e, 0x8e, 0x8e, 0x8b, 0x8a, 0x88, 0x86, 0x82, 0x7a, 0x73, 0x6b, + 0x65, 0x66, 0x69, 0x69, 0x6b, 0x6a, 0x68, 0x6e, 0x76, 0x7c, 0x81, 0x83, 0x81, 0x82, 0x81, 0x80, + 0x82, 0x7c, 0x76, 0x71, 0x6e, 0x72, 0x76, 0x79, 0x7a, 0x77, 0x72, 0x6b, 0x67, 0x67, 0x65, 0x66, + 0x6a, 0x6c, 0x70, 0x7a, 0x87, 0x90, 0x9b, 0xa0, 0x9e, 0x9a, 0x97, 0x95, 0x93, 0x8f, 0x8f, 0x91, + 0x92, 0x96, 0x9d, 0xa4, 0xa3, 0x9f, 0x9f, 0x9e, 0x9a, 0x92, 0x8b, 0x84, 0x79, 0x73, 0x71, 0x71, + 0x75, 0x7b, 0x7d, 0x81, 0x8a, 0x94, 0x95, 0x90, 0x8a, 0x84, 0x81, 0x7c, 0x7b, 0x80, 0x88, 0x8a, + 0x84, 0x83, 0x81, 0x7d, 0x7b, 0x7a, 0x73, 0x6d, 0x6c, 0x6c, 0x71, 0x78, 0x7a, 0x79, 0x7a, 0x7c, + 0x80, 0x85, 0x87, 0x88, 0x86, 0x84, 0x85, 0x86, 0x87, 0x88, 0x86, 0x80, 0x7c, 0x7b, 0x78, 0x76, + 0x77, 0x7b, 0x7e, 0x84, 0x89, 0x8a, 0x8a, 0x85, 0x7e, 0x78, 0x72, 0x6d, 0x6b, 0x69, 0x67, 0x69, + 0x6e, 0x70, 0x73, 0x74, 0x7c, 0x84, 0x85, 0x86, 0x81, 0x81, 0x80, 0x7e, 0x7b, 0x73, 0x6e, 0x71, + 0x75, 0x79, 0x80, 0x80, 0x78, 0x74, 0x6f, 0x6d, 0x6f, 0x6c, 0x68, 0x66, 0x68, 0x6c, 0x74, 0x83, + 0x88, 0x88, 0x8b, 0x8e, 0x90, 0x91, 0x8e, 0x88, 0x83, 0x7d, 0x78, 0x7a, 0x7d, 0x7e, 0x87, 0x90, + 0x92, 0x94, 0x91, 0x8a, 0x8a, 0x88, 0x83, 0x80, 0x7b, 0x7a, 0x7a, 0x7a, 0x7c, 0x80, 0x80, 0x7c, + 0x7c, 0x7e, 0x7e, 0x7b, 0x78, 0x77, 0x7b, 0x83, 0x89, 0x88, 0x88, 0x8d, 0x92, 0x91, 0x8c, 0x87, + 0x84, 0x7c, 0x77, 0x7b, 0x81, 0x83, 0x87, 0x84, 0x80, 0x79, 0x77, 0x7d, 0x81, 0x83, 0x81, 0x7c, + 0x79, 0x7b, 0x80, 0x83, 0x85, 0x83, 0x82, 0x80, 0x7b, 0x7c, 0x7d, 0x7e, 0x7c, 0x79, 0x77, 0x79, + 0x7b, 0x7a, 0x7c, 0x7b, 0x79, 0x76, 0x73, 0x6e, 0x69, 0x69, 0x70, 0x78, 0x7e, 0x87, 0x8b, 0x8c, + 0x8a, 0x87, 0x89, 0x8e, 0x91, 0x93, 0x93, 0x8d, 0x84, 0x80, 0x79, 0x7a, 0x7c, 0x77, 0x6e, 0x6d, + 0x72, 0x73, 0x74, 0x72, 0x71, 0x71, 0x71, 0x76, 0x80, 0x8b, 0x90, 0x90, 0x90, 0x90, 0x8d, 0x87, + 0x80, 0x79, 0x75, 0x73, 0x79, 0x80, 0x86, 0x8c, 0x8c, 0x8b, 0x8d, 0x8f, 0x8f, 0x8e, 0x8f, 0x8b, + 0x7e, 0x74, 0x72, 0x79, 0x80, 0x80, 0x80, 0x7c, 0x79, 0x79, 0x77, 0x76, 0x76, 0x75, 0x75, 0x73, + 0x76, 0x7c, 0x86, 0x8c, 0x89, 0x8a, 0x8d, 0x8d, 0x8d, 0x87, 0x7d, 0x76, 0x71, 0x74, 0x7a, 0x7c, + 0x7a, 0x78, 0x78, 0x7a, 0x80, 0x8a, 0x8d, 0x8c, 0x8d, 0x86, 0x7e, 0x7e, 0x84, 0x88, 0x88, 0x80, + 0x77, 0x75, 0x73, 0x76, 0x7c, 0x7d, 0x7d, 0x7b, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x79, 0x79, 0x78, + 0x75, 0x77, 0x7a, 0x7a, 0x7b, 0x7a, 0x7d, 0x84, 0x89, 0x8a, 0x86, 0x83, 0x89, 0x8d, 0x8a, 0x86, + 0x87, 0x84, 0x7a, 0x78, 0x7c, 0x83, 0x85, 0x81, 0x7c, 0x75, 0x70, 0x6d, 0x6f, 0x74, 0x78, 0x77, + 0x76, 0x77, 0x7d, 0x89, 0x90, 0x95, 0x94, 0x90, 0x8f, 0x8c, 0x86, 0x86, 0x80, 0x74, 0x72, 0x74, + 0x77, 0x81, 0x87, 0x87, 0x83, 0x83, 0x85, 0x8a, 0x8c, 0x8b, 0x86, 0x7d, 0x76, 0x76, 0x79, 0x79, + 0x7b, 0x7c, 0x77, 0x75, 0x77, 0x76, 0x73, 0x72, 0x72, 0x6f, 0x6e, 0x75, 0x7d, 0x84, 0x86, 0x85, + 0x87, 0x89, 0x85, 0x80, 0x7b, 0x7a, 0x7a, 0x7b, 0x80, 0x84, 0x85, 0x82, 0x79, 0x75, 0x79, 0x82, + 0x86, 0x88, 0x8c, 0x8d, 0x87, 0x85, 0x84, 0x82, 0x83, 0x83, 0x80, 0x77, 0x75, 0x74, 0x77, 0x81, + 0x86, 0x84, 0x7b, 0x76, 0x7d, 0x85, 0x85, 0x82, 0x80, 0x7d, 0x77, 0x72, 0x71, 0x73, 0x73, 0x73, + 0x71, 0x6d, 0x6d, 0x71, 0x76, 0x7b, 0x7d, 0x83, 0x8d, 0x8d, 0x85, 0x82, 0x80, 0x7c, 0x80, 0x84, + 0x7c, 0x75, 0x77, 0x79, 0x75, 0x72, 0x72, 0x6f, 0x6e, 0x6e, 0x6c, 0x6f, 0x78, 0x84, 0x8f, 0x97, + 0x98, 0x95, 0x93, 0x92, 0x91, 0x8f, 0x8e, 0x91, 0x93, 0x91, 0x8e, 0x8d, 0x92, 0x97, 0x95, 0x8f, + 0x89, 0x87, 0x87, 0x83, 0x83, 0x84, 0x83, 0x86, 0x85, 0x83, 0x84, 0x83, 0x7e, 0x77, 0x74, 0x73, + 0x74, 0x7b, 0x82, 0x80, 0x7b, 0x7d, 0x82, 0x7e, 0x7b, 0x7c, 0x7e, 0x82, 0x86, 0x88, 0x88, 0x88, + 0x85, 0x82, 0x80, 0x7c, 0x79, 0x7e, 0x82, 0x83, 0x84, 0x87, 0x89, 0x87, 0x83, 0x82, 0x7d, 0x79, + 0x7b, 0x7b, 0x74, 0x72, 0x77, 0x76, 0x6f, 0x6d, 0x72, 0x79, 0x7e, 0x7d, 0x7a, 0x74, 0x72, 0x78, + 0x7c, 0x7e, 0x80, 0x7e, 0x7c, 0x7b, 0x7b, 0x81, 0x87, 0x88, 0x87, 0x86, 0x83, 0x82, 0x85, 0x8a, + 0x8b, 0x8a, 0x8a, 0x8b, 0x89, 0x84, 0x7d, 0x7e, 0x7e, 0x80, 0x81, 0x77, 0x6f, 0x6c, 0x69, 0x67, + 0x67, 0x66, 0x66, 0x67, 0x69, 0x6e, 0x71, 0x78, 0x85, 0x89, 0x88, 0x87, 0x83, 0x7d, 0x76, 0x6f, + 0x73, 0x7b, 0x7d, 0x7c, 0x78, 0x75, 0x7a, 0x83, 0x88, 0x8d, 0x8b, 0x89, 0x8c, 0x88, 0x85, 0x85, + 0x84, 0x85, 0x87, 0x87, 0x88, 0x86, 0x81, 0x7a, 0x74, 0x72, 0x70, 0x6c, 0x6c, 0x69, 0x69, 0x6d, + 0x77, 0x7d, 0x7d, 0x7c, 0x7c, 0x80, 0x81, 0x80, 0x80, 0x80, 0x83, 0x86, 0x86, 0x80, 0x77, 0x75, + 0x7a, 0x83, 0x89, 0x8e, 0x92, 0x91, 0x8d, 0x89, 0x89, 0x8d, 0x8e, 0x88, 0x82, 0x7e, 0x7e, 0x80, + 0x7e, 0x7c, 0x80, 0x82, 0x84, 0x89, 0x8a, 0x81, 0x7d, 0x82, 0x8b, 0x8c, 0x86, 0x85, 0x84, 0x84, + 0x85, 0x86, 0x87, 0x87, 0x87, 0x83, 0x7c, 0x7c, 0x83, 0x83, 0x80, 0x83, 0x89, 0x8b, 0x87, 0x82, + 0x7e, 0x81, 0x85, 0x88, 0x8a, 0x81, 0x76, 0x72, 0x6e, 0x69, 0x6a, 0x6b, 0x6b, 0x6b, 0x6c, 0x6f, + 0x77, 0x7a, 0x7c, 0x84, 0x88, 0x8a, 0x8a, 0x87, 0x81, 0x7b, 0x80, 0x86, 0x8a, 0x89, 0x89, 0x87, + 0x86, 0x8a, 0x8e, 0x8e, 0x8b, 0x8a, 0x8a, 0x88, 0x86, 0x82, 0x81, 0x84, 0x85, 0x83, 0x7b, 0x77, + 0x73, 0x6f, 0x6f, 0x74, 0x79, 0x7c, 0x76, 0x6e, 0x70, 0x73, 0x77, 0x7e, 0x81, 0x80, 0x81, 0x84, + 0x88, 0x8a, 0x89, 0x88, 0x8d, 0x94, 0x95, 0x90, 0x85, 0x7e, 0x83, 0x88, 0x89, 0x8e, 0x91, 0x8f, + 0x8a, 0x89, 0x88, 0x83, 0x7c, 0x78, 0x70, 0x6a, 0x69, 0x6b, 0x6c, 0x68, 0x65, 0x6a, 0x6d, 0x66, + 0x60, 0x60, 0x63, 0x67, 0x6d, 0x6e, 0x6a, 0x68, 0x68, 0x6a, 0x70, 0x73, 0x72, 0x72, 0x76, 0x7a, + 0x80, 0x85, 0x89, 0x8d, 0x90, 0x92, 0x98, 0x9c, 0x9c, 0x9b, 0x97, 0x90, 0x92, 0x99, 0x97, 0x8f, + 0x89, 0x83, 0x7c, 0x77, 0x73, 0x6d, 0x68, 0x67, 0x6b, 0x71, 0x78, 0x7d, 0x83, 0x88, 0x87, 0x85, + 0x83, 0x83, 0x84, 0x83, 0x83, 0x84, 0x89, 0x90, 0x94, 0x90, 0x8c, 0x93, 0x9b, 0x97, 0x94, 0x93, + 0x92, 0x92, 0x92, 0x91, 0x8d, 0x8d, 0x8e, 0x8c, 0x87, 0x7d, 0x73, 0x6c, 0x6a, 0x6a, 0x68, 0x64, + 0x5c, 0x56, 0x53, 0x56, 0x5e, 0x62, 0x64, 0x62, 0x62, 0x65, 0x6f, 0x79, 0x77, 0x74, 0x73, 0x71, + 0x71, 0x72, 0x72, 0x72, 0x76, 0x79, 0x7e, 0x81, 0x81, 0x80, 0x81, 0x83, 0x83, 0x82, 0x7c, 0x77, + 0x77, 0x75, 0x75, 0x77, 0x7c, 0x82, 0x83, 0x83, 0x84, 0x84, 0x81, 0x82, 0x88, 0x8a, 0x8d, 0x96, + 0x97, 0x94, 0x93, 0x94, 0x97, 0x98, 0x96, 0x91, 0x90, 0x93, 0x97, 0x99, 0x97, 0x94, 0x8f, 0x8b, + 0x8d, 0x90, 0x95, 0x97, 0x97, 0x95, 0x96, 0x9b, 0x9e, 0x99, 0x8e, 0x84, 0x7c, 0x7b, 0x79, 0x75, + 0x72, 0x6f, 0x6c, 0x6d, 0x72, 0x75, 0x76, 0x7c, 0x84, 0x82, 0x7b, 0x77, 0x7a, 0x7c, 0x7e, 0x82, + 0x85, 0x88, 0x88, 0x88, 0x89, 0x8e, 0x90, 0x8d, 0x87, 0x84, 0x85, 0x84, 0x82, 0x82, 0x7e, 0x79, + 0x76, 0x74, 0x73, 0x6f, 0x6a, 0x66, 0x6a, 0x70, 0x71, 0x6b, 0x64, 0x5e, 0x5c, 0x5d, 0x64, 0x6e, + 0x76, 0x79, 0x7b, 0x79, 0x7c, 0x85, 0x8b, 0x88, 0x80, 0x7c, 0x80, 0x85, 0x8a, 0x8d, 0x8f, 0x8f, + 0x8c, 0x8a, 0x8d, 0x91, 0x90, 0x8f, 0x8a, 0x84, 0x81, 0x7b, 0x76, 0x74, 0x72, 0x6f, 0x71, 0x75, + 0x77, 0x7a, 0x7c, 0x7d, 0x80, 0x80, 0x7a, 0x7b, 0x82, 0x86, 0x87, 0x82, 0x7e, 0x80, 0x84, 0x85, + 0x84, 0x80, 0x7b, 0x7d, 0x85, 0x89, 0x89, 0x86, 0x82, 0x7c, 0x79, 0x7d, 0x84, 0x88, 0x8a, 0x87, + 0x86, 0x8b, 0x8d, 0x8b, 0x85, 0x7c, 0x72, 0x66, 0x62, 0x64, 0x67, 0x69, 0x6a, 0x69, 0x69, 0x6a, + 0x6c, 0x71, 0x78, 0x7b, 0x75, 0x6d, 0x70, 0x78, 0x79, 0x76, 0x72, 0x6e, 0x70, 0x79, 0x7e, 0x7e, + 0x7e, 0x84, 0x85, 0x83, 0x86, 0x8b, 0x8b, 0x8b, 0x8d, 0x90, 0x8f, 0x8c, 0x8d, 0x8d, 0x8a, 0x86, + 0x83, 0x83, 0x81, 0x7a, 0x72, 0x6c, 0x67, 0x62, 0x5e, 0x5f, 0x66, 0x6e, 0x72, 0x70, 0x70, 0x7a, + 0x83, 0x81, 0x79, 0x78, 0x7a, 0x7c, 0x83, 0x8c, 0x92, 0x8e, 0x88, 0x87, 0x8a, 0x8f, 0x96, 0x98, + 0x92, 0x8f, 0x8b, 0x85, 0x87, 0x8d, 0x8f, 0x91, 0x93, 0x94, 0x96, 0x97, 0x98, 0x9c, 0xa0, 0x9f, + 0x9c, 0x9b, 0x9b, 0x9c, 0x9d, 0x98, 0x90, 0x8a, 0x85, 0x82, 0x83, 0x7e, 0x7d, 0x82, 0x82, 0x81, + 0x7e, 0x76, 0x6a, 0x66, 0x6a, 0x72, 0x78, 0x7e, 0x82, 0x80, 0x78, 0x73, 0x74, 0x77, 0x76, 0x76, + 0x73, 0x70, 0x6e, 0x6d, 0x72, 0x75, 0x75, 0x76, 0x76, 0x77, 0x77, 0x78, 0x7c, 0x7c, 0x78, 0x73, + 0x6f, 0x71, 0x78, 0x7c, 0x7c, 0x7c, 0x7b, 0x7c, 0x7d, 0x7e, 0x80, 0x82, 0x81, 0x83, 0x8a, 0x8e, + 0x8a, 0x82, 0x7c, 0x7a, 0x7a, 0x79, 0x7c, 0x81, 0x83, 0x7d, 0x75, 0x6f, 0x6a, 0x66, 0x66, 0x67, + 0x68, 0x6e, 0x74, 0x7c, 0x87, 0x8d, 0x91, 0x90, 0x8e, 0x8f, 0x92, 0x92, 0x90, 0x92, 0x92, 0x93, + 0x93, 0x95, 0x96, 0x90, 0x8a, 0x87, 0x86, 0x86, 0x86, 0x80, 0x76, 0x74, 0x76, 0x78, 0x75, 0x71, + 0x74, 0x74, 0x71, 0x6e, 0x6c, 0x6b, 0x6b, 0x6d, 0x75, 0x76, 0x76, 0x76, 0x74, 0x76, 0x7c, 0x7e, + 0x7c, 0x7a, 0x7b, 0x82, 0x8a, 0x8d, 0x89, 0x85, 0x83, 0x85, 0x86, 0x81, 0x7b, 0x78, 0x79, 0x80, + 0x8a, 0x93, 0x96, 0x91, 0x8d, 0x8f, 0x91, 0x8e, 0x86, 0x85, 0x87, 0x84, 0x7e, 0x79, 0x77, 0x77, + 0x73, 0x70, 0x70, 0x71, 0x70, 0x6e, 0x70, 0x77, 0x80, 0x7e, 0x76, 0x72, 0x71, 0x72, 0x75, 0x7a, + 0x7d, 0x7e, 0x7a, 0x7a, 0x81, 0x85, 0x85, 0x85, 0x8b, 0x91, 0x94, 0x93, 0x90, 0x8d, 0x8b, 0x8a, + 0x8b, 0x8d, 0x8d, 0x8a, 0x82, 0x79, 0x71, 0x6a, 0x66, 0x61, 0x5d, 0x5b, 0x5c, 0x63, 0x69, 0x6e, + 0x70, 0x6e, 0x69, 0x6a, 0x6d, 0x6f, 0x75, 0x7b, 0x85, 0x8c, 0x8a, 0x85, 0x82, 0x84, 0x82, 0x83, + 0x8a, 0x92, 0x97, 0x9a, 0x9d, 0x9c, 0x97, 0x8f, 0x8b, 0x88, 0x85, 0x89, 0x8d, 0x8d, 0x87, 0x82, + 0x7d, 0x81, 0x88, 0x87, 0x86, 0x8c, 0x91, 0x90, 0x8d, 0x8b, 0x89, 0x87, 0x89, 0x8b, 0x89, 0x88, + 0x83, 0x7a, 0x71, 0x6c, 0x69, 0x65, 0x62, 0x62, 0x64, 0x69, 0x71, 0x77, 0x7c, 0x7c, 0x79, 0x76, + 0x76, 0x7a, 0x7e, 0x85, 0x8e, 0x90, 0x87, 0x7b, 0x74, 0x70, 0x73, 0x7c, 0x7e, 0x7e, 0x7c, 0x7a, + 0x77, 0x76, 0x7a, 0x7b, 0x7c, 0x7c, 0x7a, 0x7a, 0x7d, 0x81, 0x83, 0x88, 0x8c, 0x8a, 0x8b, 0x8e, + 0x8e, 0x8d, 0x90, 0x94, 0x95, 0x93, 0x92, 0x91, 0x8e, 0x8f, 0x93, 0x92, 0x92, 0x8e, 0x88, 0x7e, + 0x76, 0x72, 0x72, 0x76, 0x77, 0x77, 0x77, 0x78, 0x79, 0x7c, 0x83, 0x81, 0x7a, 0x7c, 0x80, 0x80, + 0x80, 0x84, 0x88, 0x89, 0x89, 0x8c, 0x8d, 0x8e, 0x93, 0x92, 0x8c, 0x8a, 0x88, 0x85, 0x85, 0x85, + 0x84, 0x7c, 0x71, 0x69, 0x68, 0x6b, 0x6c, 0x6d, 0x6f, 0x6e, 0x6c, 0x6c, 0x6d, 0x6d, 0x72, 0x74, + 0x75, 0x76, 0x79, 0x80, 0x84, 0x83, 0x83, 0x85, 0x85, 0x85, 0x87, 0x83, 0x7d, 0x7a, 0x7c, 0x80, + 0x7e, 0x7c, 0x7c, 0x80, 0x85, 0x8d, 0x93, 0x96, 0x95, 0x91, 0x8c, 0x89, 0x89, 0x8d, 0x8f, 0x8e, + 0x85, 0x77, 0x6b, 0x62, 0x5a, 0x5a, 0x59, 0x57, 0x58, 0x5f, 0x65, 0x6a, 0x6f, 0x71, 0x70, 0x69, + 0x65, 0x69, 0x6f, 0x75, 0x7b, 0x80, 0x80, 0x7b, 0x7a, 0x7c, 0x7d, 0x7c, 0x7e, 0x82, 0x87, 0x8d, + 0x90, 0x90, 0x8c, 0x8c, 0x8e, 0x8d, 0x8c, 0x8f, 0x8c, 0x83, 0x78, 0x73, 0x70, 0x69, 0x63, 0x61, + 0x61, 0x5f, 0x5e, 0x60, 0x62, 0x62, 0x5f, 0x5d, 0x5e, 0x61, 0x69, 0x75, 0x81, 0x84, 0x83, 0x7e, + 0x80, 0x89, 0x93, 0x98, 0x96, 0x94, 0x9b, 0x9e, 0x9e, 0xa2, 0xa6, 0xa2, 0x9a, 0x95, 0x94, 0x9a, + 0x9e, 0x9c, 0x9a, 0x95, 0x91, 0x90, 0x92, 0x91, 0x92, 0x98, 0x9b, 0x9e, 0x9e, 0xa0, 0xa2, 0xa0, + 0xa2, 0xa1, 0x9b, 0x95, 0x92, 0x91, 0x88, 0x7d, 0x7b, 0x7d, 0x7d, 0x7e, 0x7d, 0x76, 0x72, 0x71, + 0x71, 0x76, 0x7e, 0x82, 0x7e, 0x7a, 0x78, 0x7a, 0x7e, 0x80, 0x7c, 0x74, 0x6b, 0x67, 0x6b, 0x72, + 0x71, 0x6f, 0x6d, 0x6c, 0x6e, 0x70, 0x6f, 0x71, 0x74, 0x70, 0x6c, 0x6d, 0x71, 0x75, 0x77, 0x7b, + 0x7e, 0x82, 0x85, 0x87, 0x88, 0x86, 0x82, 0x7e, 0x7d, 0x80, 0x86, 0x8d, 0x91, 0x8a, 0x83, 0x84, + 0x81, 0x7c, 0x7c, 0x7c, 0x76, 0x71, 0x6e, 0x6e, 0x6e, 0x6d, 0x6e, 0x6d, 0x6d, 0x6f, 0x73, 0x7c, + 0x81, 0x82, 0x7d, 0x7c, 0x82, 0x8a, 0x93, 0x94, 0x8e, 0x8b, 0x8c, 0x90, 0x97, 0x9c, 0x99, 0x94, + 0x90, 0x8d, 0x90, 0x91, 0x8a, 0x7d, 0x70, 0x5e, 0x5c, 0x6d, 0x71, 0x71, 0x72, 0x6f, 0x64, 0x60, + 0x61, 0x5f, 0x5e, 0x61, 0x69, 0x70, 0x6f, 0x6d, 0x71, 0x79, 0x7c, 0x79, 0x77, 0x77, 0x79, 0x80, + 0x82, 0x80, 0x80, 0x7e, 0x81, 0x88, 0x8d, 0x8d, 0x8a, 0x8b, 0x91, 0x9a, 0xa1, 0xa4, 0x9d, 0x96, + 0x97, 0x99, 0x93, 0x95, 0x96, 0x8b, 0x7a, 0x6f, 0x6a, 0x67, 0x6b, 0x6f, 0x68, 0x65, 0x67, 0x64, + 0x60, 0x62, 0x61, 0x5e, 0x60, 0x65, 0x6a, 0x71, 0x77, 0x7a, 0x7e, 0x7d, 0x7d, 0x7c, 0x7c, 0x87, + 0x8c, 0x88, 0x85, 0x87, 0x8a, 0x8d, 0x92, 0x97, 0x95, 0x8f, 0x86, 0x84, 0x86, 0x83, 0x8b, 0x89, + 0x7d, 0x77, 0x74, 0x71, 0x70, 0x6b, 0x6a, 0x69, 0x67, 0x6a, 0x73, 0x7b, 0x76, 0x7a, 0x8b, 0x93, + 0x97, 0x97, 0x95, 0x93, 0x97, 0xa1, 0xaa, 0xaf, 0xab, 0x9f, 0x9a, 0x9a, 0x99, 0x99, 0x99, 0x99, + 0x97, 0x98, 0x98, 0x94, 0x90, 0x90, 0x93, 0x8e, 0x93, 0x94, 0x8e, 0x8a, 0x88, 0x8f, 0x91, 0x8f, + 0x8b, 0x84, 0x81, 0x80, 0x80, 0x79, 0x6f, 0x64, 0x5c, 0x5a, 0x5b, 0x57, 0x55, 0x5d, 0x5a, 0x57, + 0x66, 0x6b, 0x66, 0x64, 0x70, 0x7e, 0x89, 0x90, 0x90, 0x8e, 0x8e, 0x8c, 0x84, 0x86, 0x83, 0x75, + 0x6d, 0x67, 0x63, 0x6d, 0x70, 0x71, 0x74, 0x75, 0x73, 0x71, 0x78, 0x7e, 0x7e, 0x74, 0x6e, 0x71, + 0x70, 0x6f, 0x6c, 0x6e, 0x74, 0x77, 0x7a, 0x80, 0x85, 0x86, 0x90, 0x8f, 0x87, 0x8f, 0x90, 0x8b, + 0x89, 0x85, 0x8c, 0x8e, 0x8b, 0x8d, 0x94, 0x94, 0x89, 0x7d, 0x73, 0x6b, 0x66, 0x66, 0x60, 0x65, + 0x71, 0x75, 0x72, 0x76, 0x87, 0x8a, 0x88, 0x8f, 0x92, 0x9a, 0xa0, 0x91, 0x91, 0x95, 0x90, 0x92, + 0x9d, 0xa2, 0x9e, 0x9a, 0x95, 0x94, 0x92, 0x8d, 0x8c, 0x84, 0x77, 0x73, 0x6f, 0x62, 0x61, 0x6d, + 0x70, 0x6b, 0x6f, 0x6d, 0x6c, 0x7a, 0x87, 0x9b, 0xa0, 0xa0, 0x92, 0x81, 0x80, 0x7e, 0x7e, 0x7c, + 0x78, 0x76, 0x76, 0x74, 0x78, 0x7d, 0x7b, 0x7b, 0x7c, 0x7b, 0x7d, 0x86, 0x83, 0x74, 0x7d, 0x8d, + 0x92, 0x95, 0x99, 0x96, 0x92, 0x8c, 0x81, 0x76, 0x7a, 0x73, 0x60, 0x5c, 0x59, 0x4f, 0x4e, 0x50, + 0x51, 0x5a, 0x54, 0x50, 0x54, 0x57, 0x60, 0x6e, 0x6f, 0x72, 0x72, 0x6e, 0x62, 0x66, 0x73, 0x72, + 0x74, 0x84, 0x95, 0x9a, 0x9a, 0x95, 0x92, 0x9a, 0x9a, 0x88, 0x8a, 0x88, 0x87, 0x82, 0x7a, 0x7e, + 0x8d, 0x9c, 0xa4, 0xa0, 0x8e, 0x79, 0x84, 0x8d, 0x87, 0x7a, 0x70, 0x6a, 0x62, 0x5f, 0x5d, 0x5d, + 0x65, 0x6b, 0x73, 0x7c, 0x7b, 0x71, 0x72, 0x75, 0x72, 0x89, 0x9d, 0xa0, 0x94, 0x8e, 0x92, 0x96, + 0xa9, 0xb8, 0xae, 0xa2, 0x98, 0x8e, 0x8c, 0x8a, 0x8a, 0x8d, 0x8d, 0x8b, 0x83, 0x71, 0x85, 0x9e, + 0xa7, 0xaa, 0xa8, 0x9a, 0x93, 0x8c, 0x85, 0x83, 0x80, 0x85, 0x86, 0x7a, 0x70, 0x71, 0x6f, 0x6d, + 0x70, 0x69, 0x6b, 0x70, 0x6f, 0x6c, 0x6a, 0x66, 0x75, 0x81, 0x8f, 0x97, 0x89, 0x85, 0x84, 0x80, + 0x77, 0x77, 0x80, 0x7d, 0x6f, 0x6b, 0x64, 0x60, 0x75, 0x81, 0x7c, 0x71, 0x67, 0x68, 0x7a, 0x80, + 0x79, 0x81, 0x85, 0x80, 0x79, 0x7e, 0x85, 0x7e, 0x80, 0x75, 0x6c, 0x76, 0x86, 0x90, 0x96, 0x98, + 0x91, 0x95, 0x9a, 0x9e, 0x9b, 0x8b, 0x75, 0x8a, 0x99, 0x8c, 0x82, 0x85, 0x91, 0x8d, 0x7c, 0x6a, + 0x61, 0x74, 0x7e, 0x78, 0x6f, 0x68, 0x67, 0x74, 0x83, 0x81, 0x8b, 0x9d, 0xa0, 0x94, 0x90, 0x8f, + 0x93, 0x8f, 0x87, 0x88, 0x8a, 0x83, 0x90, 0x9d, 0x8a, 0x7e, 0x7c, 0x8c, 0x9c, 0x89, 0x73, 0x71, + 0x75, 0x73, 0x64, 0x61, 0x68, 0x63, 0x65, 0x67, 0x5b, 0x72, 0x93, 0x93, 0x82, 0x78, 0x75, 0x5e, + 0x4e, 0x58, 0x69, 0x6c, 0x66, 0x70, 0x71, 0x65, 0x6c, 0x79, 0x82, 0x87, 0x81, 0x77, 0x73, 0x7a, + 0x82, 0x81, 0x80, 0x8b, 0x97, 0x98, 0x8d, 0x86, 0x9b, 0xa4, 0x92, 0x86, 0x8e, 0x83, 0x6b, 0x5b, + 0x4c, 0x51, 0x66, 0x66, 0x63, 0x5e, 0x51, 0x4f, 0x61, 0x6c, 0x75, 0x7e, 0x79, 0x6f, 0x67, 0x66, + 0x64, 0x5d, 0x5c, 0x6b, 0x76, 0x75, 0x75, 0x8b, 0x9d, 0x9e, 0x9e, 0x99, 0x88, 0x84, 0x8c, 0x8f, + 0x93, 0x9e, 0xa2, 0x9c, 0x97, 0x96, 0x95, 0x92, 0x92, 0x92, 0x8c, 0x93, 0x94, 0x90, 0x89, 0x7a, + 0x6f, 0x66, 0x66, 0x66, 0x6d, 0x73, 0x7e, 0x88, 0x86, 0x90, 0x93, 0x88, 0x85, 0x83, 0x83, 0x87, + 0x8a, 0x91, 0x93, 0x94, 0x96, 0x95, 0xa1, 0xae, 0xa9, 0xa1, 0x9f, 0xa1, 0x9e, 0x95, 0x95, 0x92, + 0x87, 0x84, 0x8b, 0x8e, 0x98, 0xa5, 0xaa, 0x9e, 0x94, 0x8b, 0x79, 0x6d, 0x68, 0x6e, 0x83, 0x8c, + 0x78, 0x69, 0x70, 0x6f, 0x6e, 0x6c, 0x64, 0x57, 0x56, 0x6f, 0x8a, 0x8b, 0x81, 0x7c, 0x7a, 0x7c, + 0x6e, 0x62, 0x6c, 0x76, 0x7c, 0x82, 0x8a, 0x8c, 0x75, 0x67, 0x61, 0x63, 0x6d, 0x7c, 0x85, 0x75, + 0x67, 0x6d, 0x70, 0x71, 0x71, 0x72, 0x69, 0x6f, 0x7b, 0x84, 0x7d, 0x75, 0x7c, 0x84, 0x83, 0x79, + 0x70, 0x70, 0x81, 0x8e, 0x93, 0x94, 0x82, 0x6e, 0x6d, 0x83, 0x98, 0xa5, 0xa7, 0x9a, 0x85, 0x84, + 0x85, 0x74, 0x67, 0x60, 0x60, 0x6f, 0x84, 0x8a, 0x85, 0x7a, 0x79, 0x7d, 0x7c, 0x79, 0x78, 0x6f, + 0x73, 0x87, 0x9a, 0x9d, 0x99, 0x92, 0x83, 0x7d, 0x7e, 0x7c, 0x87, 0x92, 0x8c, 0x86, 0x8d, 0x91, + 0x99, 0x9b, 0x88, 0x7b, 0x71, 0x72, 0x6c, 0x5f, 0x65, 0x73, 0x87, 0x8b, 0x81, 0x77, 0x80, 0x8b, + 0x85, 0x7d, 0x81, 0x73, 0x67, 0x6a, 0x7a, 0x81, 0x7a, 0x75, 0x83, 0x81, 0x70, 0x74, 0x7c, 0x75, + 0x6f, 0x70, 0x74, 0x79, 0x7b, 0x77, 0x78, 0x81, 0x89, 0x98, 0x96, 0x92, 0x90, 0x88, 0x81, 0x78, + 0x7d, 0x87, 0x73, 0x5d, 0x55, 0x56, 0x57, 0x5c, 0x68, 0x6a, 0x62, 0x6a, 0x75, 0x79, 0x74, 0x70, + 0x65, 0x52, 0x48, 0x4d, 0x5c, 0x66, 0x6d, 0x88, 0x99, 0x8f, 0x88, 0x96, 0x9c, 0x9e, 0x9f, 0x92, + 0x8d, 0x8b, 0x9b, 0xac, 0xaa, 0xa9, 0x9f, 0x96, 0x89, 0x86, 0x84, 0x94, 0xa1, 0x9a, 0x8d, 0x7d, + 0x87, 0xa2, 0x9e, 0x91, 0x93, 0x97, 0x94, 0x8c, 0x7b, 0x74, 0x71, 0x6c, 0x81, 0x80, 0x80, 0x79, + 0x64, 0x5e, 0x61, 0x6a, 0x78, 0x80, 0x79, 0x78, 0x87, 0x81, 0x88, 0x99, 0x99, 0x93, 0x8d, 0x85, + 0x72, 0x69, 0x6e, 0x7b, 0x8e, 0x98, 0x92, 0x7e, 0x76, 0x81, 0x96, 0xa1, 0x95, 0x88, 0x7d, 0x6f, + 0x68, 0x76, 0x7e, 0x75, 0x6a, 0x62, 0x68, 0x6d, 0x66, 0x5d, 0x50, 0x50, 0x61, 0x6a, 0x6c, 0x62, + 0x5b, 0x5a, 0x64, 0x79, 0x7b, 0x74, 0x7d, 0x7b, 0x74, 0x80, 0x86, 0x85, 0x83, 0x85, 0x8d, 0x86, + 0x86, 0x8c, 0x9d, 0x9f, 0x9b, 0x9f, 0x8e, 0x83, 0x88, 0x89, 0x81, 0x76, 0x80, 0x87, 0x84, 0x82, + 0x8d, 0x9a, 0x9a, 0x8e, 0x8d, 0x9b, 0x9c, 0xa3, 0xa5, 0x93, 0x8b, 0x85, 0x92, 0xa1, 0xaa, 0xa3, + 0x9c, 0x98, 0x8a, 0x8a, 0x8d, 0x89, 0x8c, 0x93, 0x86, 0x69, 0x62, 0x7e, 0x8d, 0x8b, 0x8c, 0x91, + 0x91, 0x8c, 0x89, 0x85, 0x82, 0x84, 0x8e, 0x88, 0x74, 0x73, 0x76, 0x6a, 0x73, 0x8e, 0x95, 0x93, + 0x8f, 0x89, 0x89, 0x83, 0x80, 0x8c, 0x86, 0x7b, 0x71, 0x65, 0x57, 0x4a, 0x4e, 0x5d, 0x72, 0x74, + 0x64, 0x53, 0x4c, 0x4a, 0x56, 0x69, 0x6c, 0x69, 0x68, 0x5f, 0x57, 0x5b, 0x6e, 0x84, 0x86, 0x83, + 0x89, 0x8a, 0x79, 0x6e, 0x6e, 0x6a, 0x6b, 0x6c, 0x70, 0x72, 0x6a, 0x6b, 0x81, 0xac, 0xb8, 0xa4, + 0x9d, 0x93, 0x89, 0x82, 0x72, 0x6f, 0x7c, 0x85, 0x86, 0x82, 0x75, 0x72, 0x6c, 0x6c, 0x86, 0x90, + 0x87, 0x75, 0x65, 0x61, 0x5d, 0x5e, 0x65, 0x69, 0x6b, 0x6a, 0x64, 0x56, 0x54, 0x68, 0x76, 0x75, + 0x7c, 0x8c, 0x90, 0x91, 0x93, 0x8f, 0x9f, 0xa9, 0xa2, 0xa1, 0xa0, 0x9e, 0x94, 0x9f, 0xab, 0xa8, + 0xa1, 0x94, 0x85, 0x78, 0x6f, 0x64, 0x6b, 0x77, 0x7d, 0x7e, 0x7a, 0x73, 0x62, 0x58, 0x5d, 0x65, + 0x6d, 0x70, 0x70, 0x72, 0x66, 0x5d, 0x6b, 0x78, 0x7b, 0x86, 0x91, 0x92, 0x92, 0x95, 0xa1, 0xb0, + 0xa6, 0x9d, 0x98, 0x93, 0x8e, 0x88, 0x8c, 0x93, 0x92, 0x8b, 0x82, 0x7c, 0x82, 0x8d, 0x94, 0x93, + 0x9a, 0x99, 0x93, 0x8f, 0x87, 0x84, 0x86, 0x8c, 0x8d, 0x8c, 0x89, 0x89, 0x84, 0x72, 0x61, 0x59, + 0x61, 0x69, 0x6e, 0x78, 0x7c, 0x7d, 0x86, 0x96, 0x9c, 0x90, 0x86, 0x7d, 0x7e, 0x85, 0x8c, 0x94, + 0x96, 0x92, 0x89, 0x83, 0x7b, 0x82, 0x91, 0x8f, 0x8c, 0x92, 0x8e, 0x8a, 0x7d, 0x74, 0x7a, 0x83, + 0x82, 0x7c, 0x73, 0x6e, 0x6d, 0x6d, 0x6b, 0x60, 0x53, 0x5d, 0x6a, 0x73, 0x7c, 0x88, 0x8d, 0x8f, + 0x98, 0x94, 0x8c, 0x8a, 0x8a, 0x8f, 0x8d, 0x8d, 0x92, 0x94, 0x8e, 0x81, 0x73, 0x6d, 0x73, 0x7b, + 0x78, 0x6f, 0x74, 0x72, 0x6f, 0x6e, 0x6e, 0x6b, 0x6e, 0x73, 0x70, 0x6e, 0x6f, 0x72, 0x77, 0x77, + 0x72, 0x69, 0x68, 0x75, 0x80, 0x87, 0x92, 0x98, 0x9b, 0xa3, 0x93, 0x81, 0x7b, 0x7e, 0x84, 0x76, + 0x6f, 0x6f, 0x70, 0x71, 0x6e, 0x62, 0x5f, 0x67, 0x64, 0x63, 0x66, 0x6c, 0x6a, 0x65, 0x6b, 0x73, + 0x78, 0x80, 0x82, 0x85, 0x86, 0x87, 0x8e, 0x89, 0x78, 0x69, 0x5c, 0x58, 0x68, 0x7a, 0x84, 0x89, + 0x8c, 0x96, 0x9e, 0x8f, 0x82, 0x7c, 0x84, 0x88, 0x85, 0x89, 0x8d, 0x8e, 0x92, 0x95, 0x93, 0x8f, + 0x8b, 0x7c, 0x6c, 0x6d, 0x73, 0x6c, 0x66, 0x62, 0x64, 0x67, 0x67, 0x65, 0x64, 0x62, 0x68, 0x75, + 0x7e, 0x7a, 0x72, 0x6d, 0x70, 0x7a, 0x8d, 0x9b, 0x9f, 0xa0, 0xa5, 0xa5, 0x9f, 0xa2, 0xa6, 0xa7, + 0xa6, 0xa3, 0xa4, 0xa7, 0xa6, 0xa1, 0x9f, 0x9b, 0x99, 0x96, 0x8b, 0x7e, 0x79, 0x79, 0x7d, 0x7b, + 0x74, 0x6d, 0x6a, 0x6a, 0x6a, 0x6a, 0x6e, 0x76, 0x7d, 0x83, 0x83, 0x7e, 0x78, 0x76, 0x79, 0x83, + 0x8c, 0x8f, 0x8a, 0x85, 0x80, 0x7c, 0x7e, 0x85, 0x87, 0x83, 0x80, 0x83, 0x89, 0x8d, 0x8c, 0x8d, + 0x8c, 0x8d, 0x91, 0x8e, 0x8a, 0x87, 0x87, 0x8c, 0x91, 0x91, 0x91, 0x90, 0x8a, 0x85, 0x81, 0x81, + 0x84, 0x82, 0x78, 0x6e, 0x65, 0x61, 0x63, 0x68, 0x6a, 0x6c, 0x6f, 0x72, 0x6b, 0x5f, 0x5c, 0x61, + 0x6a, 0x6d, 0x6a, 0x6a, 0x70, 0x75, 0x7a, 0x7d, 0x7e, 0x7d, 0x7c, 0x78, 0x75, 0x76, 0x7b, 0x81, + 0x7c, 0x77, 0x72, 0x6f, 0x73, 0x72, 0x6e, 0x6a, 0x6e, 0x79, 0x83, 0x81, 0x78, 0x73, 0x72, 0x74, + 0x79, 0x7e, 0x83, 0x83, 0x80, 0x80, 0x84, 0x8a, 0x91, 0x96, 0x98, 0x96, 0x93, 0x93, 0x94, 0x93, + 0x90, 0x8b, 0x84, 0x80, 0x7b, 0x79, 0x78, 0x7e, 0x84, 0x83, 0x7b, 0x77, 0x78, 0x7d, 0x83, 0x84, + 0x80, 0x82, 0x8c, 0x93, 0x9a, 0x9f, 0x9e, 0x9e, 0x9f, 0xa4, 0xab, 0xa9, 0xa3, 0x9a, 0x90, 0x87, + 0x85, 0x83, 0x7d, 0x77, 0x6f, 0x6c, 0x70, 0x72, 0x6f, 0x6b, 0x66, 0x64, 0x65, 0x63, 0x62, 0x66, + 0x70, 0x78, 0x76, 0x73, 0x77, 0x7d, 0x86, 0x8a, 0x85, 0x82, 0x85, 0x88, 0x89, 0x88, 0x84, 0x82, + 0x7c, 0x79, 0x79, 0x7e, 0x88, 0x8f, 0x8f, 0x88, 0x83, 0x84, 0x88, 0x8c, 0x8c, 0x87, 0x84, 0x84, + 0x86, 0x8d, 0x8d, 0x87, 0x7d, 0x76, 0x73, 0x71, 0x71, 0x74, 0x71, 0x6c, 0x65, 0x61, 0x61, 0x60, + 0x60, 0x5e, 0x5c, 0x60, 0x65, 0x67, 0x69, 0x6a, 0x6a, 0x6b, 0x6d, 0x6f, 0x78, 0x86, 0x8f, 0x92, + 0x91, 0x8e, 0x8d, 0x94, 0x9e, 0xa5, 0xa7, 0xa7, 0xa5, 0xa4, 0xa1, 0x9b, 0x92, 0x88, 0x7d, 0x74, + 0x6e, 0x70, 0x75, 0x71, 0x65, 0x5d, 0x5b, 0x5d, 0x5d, 0x5b, 0x57, 0x58, 0x5f, 0x66, 0x6a, 0x6c, + 0x70, 0x73, 0x73, 0x6f, 0x6d, 0x74, 0x7e, 0x82, 0x80, 0x7c, 0x7a, 0x7d, 0x84, 0x8d, 0x93, 0x95, + 0x97, 0x93, 0x8c, 0x8b, 0x8e, 0x94, 0x97, 0x96, 0x98, 0x98, 0x97, 0x97, 0x94, 0x8b, 0x82, 0x7e, + 0x7a, 0x77, 0x75, 0x72, 0x72, 0x6f, 0x70, 0x75, 0x76, 0x72, 0x6d, 0x6e, 0x6c, 0x6b, 0x6f, 0x73, + 0x75, 0x73, 0x6f, 0x6f, 0x71, 0x75, 0x7a, 0x81, 0x88, 0x8a, 0x8a, 0x8a, 0x8c, 0x92, 0x97, 0x95, + 0x93, 0x92, 0x8d, 0x8e, 0x8e, 0x93, 0x99, 0x9a, 0x9a, 0x9a, 0x9b, 0x96, 0x92, 0x94, 0x93, 0x93, + 0x92, 0x90, 0x92, 0x93, 0x93, 0x8f, 0x8f, 0x95, 0x9c, 0x9c, 0x96, 0x92, 0x94, 0x98, 0x90, 0x8a, + 0x8e, 0x92, 0x93, 0x91, 0x92, 0x95, 0x96, 0x93, 0x90, 0x90, 0x8c, 0x86, 0x84, 0x84, 0x86, 0x84, + 0x7c, 0x79, 0x74, 0x6c, 0x67, 0x68, 0x6e, 0x75, 0x78, 0x75, 0x70, 0x6d, 0x69, 0x64, 0x63, 0x66, + 0x68, 0x67, 0x67, 0x66, 0x6b, 0x6f, 0x71, 0x73, 0x74, 0x73, 0x75, 0x75, 0x72, 0x6f, 0x6a, 0x63, + 0x5d, 0x5d, 0x5f, 0x60, 0x62, 0x66, 0x69, 0x6a, 0x6c, 0x6f, 0x71, 0x71, 0x71, 0x73, 0x78, 0x79, + 0x79, 0x7b, 0x76, 0x71, 0x72, 0x73, 0x77, 0x79, 0x79, 0x7c, 0x7e, 0x7c, 0x7c, 0x81, 0x83, 0x83, + 0x80, 0x81, 0x84, 0x8a, 0x8d, 0x8b, 0x86, 0x85, 0x87, 0x81, 0x79, 0x74, 0x73, 0x72, 0x6a, 0x65, + 0x65, 0x63, 0x64, 0x6b, 0x70, 0x71, 0x6d, 0x6d, 0x70, 0x74, 0x79, 0x7d, 0x80, 0x7d, 0x7e, 0x84, + 0x88, 0x89, 0x89, 0x85, 0x81, 0x85, 0x90, 0x99, 0x99, 0x97, 0x96, 0x97, 0x96, 0x93, 0x94, 0x96, + 0x94, 0x92, 0x95, 0x99, 0x98, 0x97, 0x94, 0x8e, 0x88, 0x87, 0x88, 0x84, 0x7a, 0x78, 0x78, 0x72, + 0x70, 0x74, 0x76, 0x73, 0x74, 0x78, 0x77, 0x73, 0x77, 0x7c, 0x7e, 0x7e, 0x80, 0x87, 0x91, 0x9b, + 0xa4, 0xa5, 0xa1, 0x99, 0x94, 0x93, 0x96, 0x98, 0x99, 0x97, 0x90, 0x84, 0x7e, 0x81, 0x84, 0x85, + 0x7d, 0x73, 0x6d, 0x72, 0x7b, 0x82, 0x83, 0x82, 0x81, 0x82, 0x81, 0x85, 0x8a, 0x8e, 0x8e, 0x8b, + 0x88, 0x83, 0x82, 0x81, 0x7c, 0x79, 0x76, 0x78, 0x7b, 0x78, 0x75, 0x74, 0x79, 0x80, 0x86, 0x8b, + 0x8b, 0x88, 0x85, 0x80, 0x7c, 0x82, 0x88, 0x8e, 0x8e, 0x86, 0x7d, 0x7a, 0x79, 0x7a, 0x7e, 0x7d, + 0x77, 0x70, 0x6d, 0x6e, 0x6f, 0x74, 0x78, 0x75, 0x6c, 0x68, 0x6e, 0x77, 0x7e, 0x7d, 0x78, 0x75, + 0x7b, 0x86, 0x88, 0x89, 0x8c, 0x89, 0x83, 0x7e, 0x80, 0x84, 0x84, 0x81, 0x81, 0x80, 0x7d, 0x81, + 0x84, 0x80, 0x7a, 0x73, 0x6c, 0x6b, 0x6d, 0x71, 0x78, 0x7c, 0x7c, 0x78, 0x71, 0x6b, 0x6e, 0x79, + 0x7b, 0x75, 0x74, 0x7b, 0x82, 0x84, 0x83, 0x81, 0x7e, 0x80, 0x87, 0x90, 0x94, 0x8b, 0x7e, 0x75, + 0x75, 0x7d, 0x83, 0x82, 0x7c, 0x72, 0x6a, 0x68, 0x69, 0x6d, 0x6c, 0x64, 0x5d, 0x5f, 0x64, 0x67, + 0x6d, 0x74, 0x78, 0x75, 0x6f, 0x6d, 0x6f, 0x76, 0x81, 0x88, 0x8c, 0x88, 0x82, 0x80, 0x86, 0x8e, + 0x93, 0x94, 0x96, 0x9d, 0xa1, 0x9f, 0x9a, 0x94, 0x8d, 0x8a, 0x8a, 0x8d, 0x94, 0x93, 0x86, 0x79, + 0x7a, 0x7e, 0x7d, 0x7a, 0x73, 0x69, 0x61, 0x63, 0x6e, 0x75, 0x77, 0x75, 0x76, 0x7c, 0x82, 0x85, + 0x8b, 0x92, 0x92, 0x8b, 0x82, 0x7a, 0x7a, 0x7e, 0x84, 0x89, 0x8e, 0x92, 0x91, 0x8c, 0x8d, 0x91, + 0x91, 0x8d, 0x8c, 0x8e, 0x90, 0x94, 0x9d, 0xa4, 0xa1, 0x99, 0x92, 0x90, 0x8f, 0x8a, 0x82, 0x78, + 0x73, 0x72, 0x74, 0x73, 0x6e, 0x67, 0x60, 0x5c, 0x5f, 0x63, 0x65, 0x65, 0x6a, 0x74, 0x7b, 0x7c, + 0x81, 0x87, 0x85, 0x7e, 0x7d, 0x84, 0x8c, 0x8f, 0x8d, 0x89, 0x8a, 0x8f, 0x8e, 0x8c, 0x8c, 0x89, + 0x83, 0x80, 0x7e, 0x7b, 0x78, 0x76, 0x74, 0x6e, 0x6a, 0x68, 0x68, 0x6f, 0x7a, 0x81, 0x7b, 0x71, + 0x66, 0x60, 0x5f, 0x67, 0x72, 0x73, 0x6c, 0x61, 0x5e, 0x64, 0x68, 0x6c, 0x74, 0x7e, 0x83, 0x7d, + 0x7c, 0x82, 0x82, 0x82, 0x87, 0x8c, 0x8e, 0x8f, 0x90, 0x90, 0x92, 0x96, 0x97, 0x93, 0x88, 0x7b, + 0x74, 0x76, 0x86, 0x94, 0x98, 0x96, 0x93, 0x91, 0x8e, 0x88, 0x89, 0x90, 0x96, 0x95, 0x8f, 0x87, + 0x7e, 0x78, 0x7a, 0x84, 0x8a, 0x89, 0x83, 0x81, 0x89, 0x90, 0x90, 0x91, 0x93, 0x93, 0x90, 0x8d, + 0x91, 0x9a, 0x9d, 0x98, 0x90, 0x8a, 0x88, 0x84, 0x7c, 0x7b, 0x80, 0x81, 0x80, 0x79, 0x70, 0x6c, + 0x6c, 0x70, 0x79, 0x7d, 0x7d, 0x7b, 0x7d, 0x83, 0x84, 0x7e, 0x7d, 0x80, 0x80, 0x80, 0x82, 0x85, + 0x84, 0x7e, 0x7a, 0x74, 0x6e, 0x6c, 0x6e, 0x73, 0x7d, 0x86, 0x84, 0x79, 0x74, 0x75, 0x75, 0x75, + 0x74, 0x70, 0x6a, 0x63, 0x65, 0x6c, 0x71, 0x73, 0x75, 0x79, 0x77, 0x70, 0x71, 0x7a, 0x7c, 0x7b, + 0x7a, 0x76, 0x72, 0x75, 0x7a, 0x81, 0x87, 0x8b, 0x89, 0x82, 0x7a, 0x7a, 0x7e, 0x82, 0x83, 0x86, + 0x84, 0x7c, 0x74, 0x72, 0x78, 0x7b, 0x7d, 0x7c, 0x76, 0x6b, 0x62, 0x62, 0x6a, 0x72, 0x78, 0x77, + 0x6f, 0x69, 0x6d, 0x6e, 0x71, 0x78, 0x81, 0x87, 0x83, 0x80, 0x82, 0x84, 0x84, 0x8b, 0x8d, 0x86, + 0x81, 0x80, 0x87, 0x93, 0x99, 0x9a, 0x9b, 0x97, 0x8f, 0x8d, 0x91, 0x99, 0x9e, 0x9f, 0x99, 0x8e, + 0x88, 0x86, 0x81, 0x7c, 0x80, 0x80, 0x7b, 0x73, 0x6c, 0x6b, 0x6c, 0x6e, 0x71, 0x74, 0x72, 0x6f, + 0x6f, 0x73, 0x79, 0x80, 0x85, 0x84, 0x82, 0x80, 0x82, 0x82, 0x81, 0x82, 0x7e, 0x78, 0x72, 0x70, + 0x70, 0x73, 0x78, 0x80, 0x81, 0x7a, 0x75, 0x75, 0x77, 0x75, 0x71, 0x6e, 0x6f, 0x73, 0x74, 0x77, + 0x7d, 0x84, 0x88, 0x87, 0x85, 0x80, 0x7d, 0x7d, 0x7a, 0x78, 0x79, 0x7b, 0x7d, 0x85, 0x8d, 0x92, + 0x95, 0x9b, 0x9d, 0x99, 0x96, 0x96, 0x9a, 0x9f, 0xa1, 0xa0, 0x9b, 0x95, 0x92, 0x95, 0x99, 0x97, + 0x95, 0x97, 0x92, 0x8c, 0x89, 0x8b, 0x8a, 0x88, 0x85, 0x83, 0x81, 0x7e, 0x83, 0x8a, 0x8e, 0x8f, + 0x8b, 0x7a, 0x6a, 0x62, 0x69, 0x77, 0x80, 0x83, 0x81, 0x7a, 0x79, 0x78, 0x80, 0x8e, 0x94, 0x91, + 0x90, 0x8c, 0x89, 0x87, 0x86, 0x87, 0x8b, 0x91, 0x92, 0x8d, 0x87, 0x82, 0x7e, 0x7d, 0x7b, 0x78, + 0x6f, 0x67, 0x68, 0x72, 0x7c, 0x7b, 0x78, 0x75, 0x70, 0x68, 0x5e, 0x5b, 0x60, 0x69, 0x70, 0x72, + 0x71, 0x6e, 0x6c, 0x6a, 0x6b, 0x71, 0x72, 0x6c, 0x61, 0x5d, 0x60, 0x64, 0x68, 0x6d, 0x6f, 0x6a, + 0x63, 0x63, 0x67, 0x66, 0x61, 0x5c, 0x5b, 0x5f, 0x64, 0x6b, 0x6f, 0x6c, 0x69, 0x68, 0x69, 0x6a, + 0x6e, 0x72, 0x75, 0x7b, 0x82, 0x83, 0x84, 0x89, 0x8e, 0x92, 0x95, 0x99, 0x9a, 0x94, 0x93, 0x95, + 0x97, 0x99, 0x95, 0x95, 0x93, 0x93, 0x98, 0x99, 0x99, 0x94, 0x92, 0x96, 0x97, 0x93, 0x8e, 0x8e, + 0x8c, 0x89, 0x88, 0x85, 0x7b, 0x6f, 0x6e, 0x78, 0x83, 0x8a, 0x8b, 0x82, 0x6f, 0x64, 0x61, 0x6a, + 0x70, 0x6f, 0x6f, 0x72, 0x7c, 0x83, 0x85, 0x87, 0x88, 0x85, 0x84, 0x86, 0x86, 0x85, 0x89, 0x8f, + 0x92, 0x8f, 0x87, 0x7d, 0x77, 0x76, 0x77, 0x77, 0x76, 0x6d, 0x62, 0x5d, 0x60, 0x68, 0x6e, 0x70, + 0x70, 0x6f, 0x6c, 0x6a, 0x65, 0x5f, 0x5c, 0x5f, 0x68, 0x74, 0x79, 0x77, 0x76, 0x7a, 0x7d, 0x7e, + 0x7e, 0x80, 0x81, 0x87, 0x93, 0xa0, 0xa7, 0xac, 0xac, 0xa9, 0xa8, 0xa8, 0xaa, 0xa8, 0xa2, 0x9c, + 0x9a, 0x9c, 0x9a, 0x97, 0x97, 0x97, 0x95, 0x94, 0x96, 0x93, 0x90, 0x8e, 0x90, 0x94, 0x94, 0x8e, + 0x88, 0x86, 0x86, 0x88, 0x86, 0x84, 0x88, 0x8b, 0x8d, 0x91, 0x96, 0x9b, 0x9a, 0x97, 0x92, 0x8e, + 0x8e, 0x8c, 0x8b, 0x8c, 0x8c, 0x8a, 0x87, 0x83, 0x7d, 0x7a, 0x79, 0x7c, 0x7e, 0x79, 0x75, 0x74, + 0x73, 0x73, 0x74, 0x77, 0x75, 0x6d, 0x66, 0x63, 0x62, 0x5f, 0x5a, 0x59, 0x59, 0x5c, 0x66, 0x70, + 0x71, 0x6d, 0x68, 0x65, 0x66, 0x6a, 0x6d, 0x6e, 0x74, 0x7c, 0x83, 0x86, 0x85, 0x83, 0x7e, 0x75, + 0x6e, 0x6c, 0x6d, 0x6f, 0x73, 0x76, 0x78, 0x7a, 0x78, 0x76, 0x73, 0x75, 0x7e, 0x86, 0x85, 0x7e, + 0x7a, 0x78, 0x78, 0x7a, 0x78, 0x74, 0x75, 0x7e, 0x87, 0x85, 0x7b, 0x74, 0x77, 0x7d, 0x85, 0x8c, + 0x8d, 0x89, 0x80, 0x7a, 0x7b, 0x7d, 0x80, 0x7b, 0x75, 0x72, 0x74, 0x77, 0x7b, 0x79, 0x73, 0x6d, + 0x6a, 0x6a, 0x6c, 0x6c, 0x6f, 0x76, 0x7d, 0x84, 0x85, 0x83, 0x84, 0x88, 0x8c, 0x8b, 0x88, 0x8a, + 0x8f, 0x92, 0x91, 0x8e, 0x8d, 0x8c, 0x8a, 0x8a, 0x8c, 0x86, 0x7d, 0x78, 0x76, 0x79, 0x7e, 0x82, + 0x80, 0x76, 0x6b, 0x68, 0x6a, 0x6b, 0x67, 0x62, 0x62, 0x6a, 0x73, 0x77, 0x7a, 0x81, 0x85, 0x82, + 0x7c, 0x7a, 0x7a, 0x80, 0x83, 0x82, 0x81, 0x87, 0x92, 0x9e, 0xa3, 0xa1, 0x9c, 0x9b, 0x9b, 0x9a, + 0x9a, 0x99, 0x95, 0x94, 0x95, 0x96, 0x93, 0x93, 0x93, 0x8a, 0x7d, 0x71, 0x71, 0x75, 0x77, 0x7a, + 0x7a, 0x79, 0x77, 0x77, 0x76, 0x78, 0x7d, 0x7e, 0x7d, 0x80, 0x83, 0x85, 0x87, 0x8c, 0x8b, 0x85, + 0x80, 0x83, 0x8a, 0x8d, 0x8c, 0x87, 0x84, 0x88, 0x8c, 0x90, 0x94, 0x93, 0x8f, 0x8e, 0x93, 0x96, + 0x95, 0x8f, 0x85, 0x77, 0x72, 0x74, 0x75, 0x72, 0x6c, 0x64, 0x5b, 0x54, 0x51, 0x52, 0x59, 0x61, + 0x65, 0x6a, 0x6f, 0x73, 0x78, 0x7e, 0x85, 0x85, 0x84, 0x87, 0x8e, 0x95, 0x98, 0x95, 0x93, 0x8f, + 0x8a, 0x89, 0x88, 0x89, 0x8a, 0x84, 0x7c, 0x79, 0x7b, 0x82, 0x86, 0x80, 0x72, 0x6b, 0x6e, 0x70, + 0x73, 0x71, 0x6b, 0x67, 0x67, 0x69, 0x6b, 0x71, 0x74, 0x6e, 0x63, 0x5c, 0x61, 0x6d, 0x75, 0x7a, + 0x7e, 0x80, 0x85, 0x8e, 0x95, 0x97, 0x94, 0x8f, 0x8e, 0x94, 0x9b, 0x9c, 0x99, 0x96, 0x96, 0x96, + 0x94, 0x92, 0x91, 0x90, 0x8b, 0x82, 0x7a, 0x78, 0x78, 0x7a, 0x7d, 0x80, 0x7d, 0x7c, 0x7e, 0x84, + 0x8b, 0x8c, 0x86, 0x7a, 0x74, 0x78, 0x81, 0x85, 0x83, 0x7a, 0x6e, 0x6a, 0x6f, 0x79, 0x86, 0x87, + 0x82, 0x82, 0x86, 0x8a, 0x8c, 0x89, 0x80, 0x7a, 0x78, 0x78, 0x7a, 0x7d, 0x82, 0x82, 0x80, 0x80, + 0x80, 0x7d, 0x79, 0x74, 0x71, 0x6d, 0x6b, 0x69, 0x66, 0x69, 0x6e, 0x70, 0x72, 0x77, 0x7d, 0x87, + 0x91, 0x94, 0x8d, 0x86, 0x84, 0x85, 0x8b, 0x8f, 0x8e, 0x86, 0x79, 0x78, 0x7e, 0x87, 0x8c, 0x88, + 0x84, 0x7e, 0x7c, 0x80, 0x84, 0x88, 0x85, 0x79, 0x74, 0x78, 0x7c, 0x7e, 0x7e, 0x7a, 0x75, 0x76, + 0x77, 0x79, 0x7a, 0x75, 0x70, 0x6c, 0x6c, 0x71, 0x77, 0x7b, 0x80, 0x81, 0x7e, 0x83, 0x89, 0x8d, + 0x8c, 0x87, 0x82, 0x7a, 0x74, 0x70, 0x6b, 0x6b, 0x70, 0x72, 0x6f, 0x6a, 0x67, 0x6f, 0x7e, 0x86, + 0x82, 0x79, 0x77, 0x7d, 0x86, 0x8d, 0x8b, 0x83, 0x7d, 0x7e, 0x89, 0x90, 0x8f, 0x86, 0x7a, 0x74, + 0x74, 0x79, 0x7e, 0x7c, 0x70, 0x68, 0x69, 0x74, 0x7b, 0x7c, 0x7b, 0x78, 0x77, 0x7c, 0x80, 0x80, + 0x7d, 0x7e, 0x83, 0x88, 0x8a, 0x87, 0x86, 0x85, 0x87, 0x85, 0x7d, 0x74, 0x6c, 0x6c, 0x71, 0x73, + 0x74, 0x72, 0x71, 0x74, 0x7b, 0x86, 0x88, 0x83, 0x80, 0x86, 0x91, 0x9d, 0xa4, 0x9e, 0x91, 0x8c, + 0x93, 0x9d, 0xa3, 0xa1, 0x99, 0x94, 0x90, 0x90, 0x93, 0x94, 0x94, 0x93, 0x8f, 0x8e, 0x92, 0x99, + 0x9b, 0x97, 0x8e, 0x8a, 0x88, 0x85, 0x84, 0x82, 0x7d, 0x7c, 0x7b, 0x77, 0x75, 0x77, 0x7c, 0x84, + 0x8c, 0x93, 0x98, 0x9d, 0xa2, 0xa8, 0xa2, 0x98, 0x93, 0x96, 0x9b, 0x9d, 0x99, 0x93, 0x89, 0x7e, + 0x73, 0x71, 0x77, 0x7a, 0x76, 0x71, 0x6e, 0x6e, 0x73, 0x73, 0x6e, 0x65, 0x5e, 0x60, 0x69, 0x74, + 0x78, 0x75, 0x72, 0x70, 0x74, 0x78, 0x78, 0x77, 0x73, 0x71, 0x6e, 0x6c, 0x70, 0x74, 0x72, 0x6e, + 0x6c, 0x6f, 0x75, 0x78, 0x7b, 0x81, 0x82, 0x80, 0x76, 0x6f, 0x70, 0x76, 0x7c, 0x7c, 0x79, 0x77, + 0x77, 0x78, 0x7d, 0x7e, 0x7a, 0x76, 0x75, 0x77, 0x75, 0x6d, 0x67, 0x65, 0x65, 0x67, 0x6c, 0x70, + 0x6f, 0x6c, 0x69, 0x69, 0x6e, 0x78, 0x80, 0x7b, 0x73, 0x72, 0x76, 0x79, 0x7c, 0x80, 0x84, 0x84, + 0x83, 0x81, 0x7e, 0x84, 0x8b, 0x8c, 0x86, 0x79, 0x6f, 0x6d, 0x70, 0x73, 0x72, 0x6c, 0x67, 0x69, + 0x6b, 0x6c, 0x6a, 0x69, 0x6a, 0x6a, 0x6d, 0x6e, 0x6d, 0x6b, 0x69, 0x6f, 0x7a, 0x82, 0x8a, 0x92, + 0x92, 0x8f, 0x94, 0x9a, 0x9a, 0x98, 0x92, 0x8a, 0x83, 0x7d, 0x78, 0x76, 0x76, 0x76, 0x78, 0x74, + 0x71, 0x77, 0x82, 0x88, 0x8d, 0x8e, 0x88, 0x84, 0x86, 0x8c, 0x93, 0x99, 0x9c, 0x98, 0x94, 0x92, + 0x93, 0x93, 0x92, 0x8f, 0x8c, 0x8e, 0x95, 0x98, 0x99, 0x93, 0x8d, 0x92, 0x9c, 0xa1, 0xa0, 0xa1, + 0xa1, 0x9e, 0x9b, 0x9b, 0x9f, 0xa1, 0x9e, 0x98, 0x94, 0x92, 0x95, 0x95, 0x8f, 0x8b, 0x84, 0x79, + 0x76, 0x77, 0x7b, 0x7d, 0x7e, 0x83, 0x84, 0x83, 0x7b, 0x74, 0x73, 0x78, 0x7b, 0x7c, 0x7e, 0x81, + 0x83, 0x83, 0x7d, 0x79, 0x7d, 0x82, 0x89, 0x92, 0x94, 0x8d, 0x80, 0x77, 0x7d, 0x86, 0x8d, 0x8f, + 0x8a, 0x86, 0x88, 0x8b, 0x8c, 0x8d, 0x88, 0x78, 0x6d, 0x69, 0x66, 0x63, 0x5f, 0x59, 0x53, 0x50, + 0x51, 0x51, 0x52, 0x54, 0x5e, 0x6f, 0x7e, 0x81, 0x7b, 0x75, 0x72, 0x77, 0x82, 0x8a, 0x8c, 0x8f, + 0x95, 0x94, 0x8b, 0x82, 0x80, 0x81, 0x83, 0x8a, 0x8c, 0x82, 0x74, 0x6d, 0x6e, 0x74, 0x77, 0x78, + 0x72, 0x6c, 0x6f, 0x76, 0x7d, 0x82, 0x7e, 0x76, 0x72, 0x73, 0x74, 0x78, 0x78, 0x76, 0x75, 0x74, + 0x72, 0x71, 0x73, 0x76, 0x78, 0x7d, 0x86, 0x86, 0x7c, 0x71, 0x6b, 0x67, 0x68, 0x6f, 0x73, 0x77, + 0x79, 0x79, 0x77, 0x73, 0x7b, 0x86, 0x8a, 0x90, 0x94, 0x95, 0x92, 0x8b, 0x87, 0x86, 0x81, 0x7a, + 0x75, 0x74, 0x75, 0x79, 0x7b, 0x80, 0x7e, 0x75, 0x69, 0x62, 0x61, 0x65, 0x68, 0x68, 0x6a, 0x6c, + 0x74, 0x84, 0x8c, 0x8a, 0x86, 0x88, 0x8d, 0x8f, 0x8e, 0x89, 0x81, 0x7a, 0x7a, 0x80, 0x8a, 0x91, + 0x93, 0x94, 0x90, 0x8b, 0x89, 0x87, 0x84, 0x83, 0x82, 0x7e, 0x82, 0x87, 0x8d, 0x97, 0xa0, 0xa2, + 0xa0, 0x9b, 0x95, 0x97, 0x9a, 0x9e, 0x9f, 0x98, 0x94, 0x91, 0x8c, 0x89, 0x81, 0x76, 0x6f, 0x6b, + 0x6a, 0x66, 0x66, 0x69, 0x63, 0x5f, 0x63, 0x62, 0x58, 0x5a, 0x59, 0x59, 0x61, 0x6c, 0x71, 0x75, + 0x7a, 0x78, 0x71, 0x6b, 0x6c, 0x74, 0x7c, 0x82, 0x84, 0x85, 0x86, 0x88, 0x91, 0x9f, 0xa5, 0xa5, + 0xa7, 0xa8, 0xa7, 0xa7, 0xa7, 0xa3, 0x98, 0x8a, 0x82, 0x82, 0x89, 0x8f, 0x8e, 0x8b, 0x89, 0x83, + 0x78, 0x6e, 0x64, 0x68, 0x70, 0x7b, 0x83, 0x84, 0x84, 0x80, 0x79, 0x74, 0x78, 0x7d, 0x81, 0x87, + 0x89, 0x85, 0x7d, 0x74, 0x6c, 0x6c, 0x78, 0x80, 0x7a, 0x78, 0x7b, 0x80, 0x84, 0x89, 0x83, 0x74, + 0x68, 0x65, 0x6a, 0x73, 0x7d, 0x7e, 0x7c, 0x87, 0x8c, 0x8c, 0x86, 0x82, 0x7d, 0x7d, 0x87, 0x83, + 0x7d, 0x7b, 0x6e, 0x5a, 0x4f, 0x58, 0x63, 0x6e, 0x7e, 0x83, 0x87, 0x8b, 0x90, 0x99, 0xa2, 0xad, + 0xb5, 0xb3, 0xac, 0xa5, 0x9a, 0x8d, 0x97, 0xa6, 0xa7, 0x9e, 0x97, 0x96, 0x97, 0x96, 0x8f, 0x89, + 0x83, 0x77, 0x6f, 0x6f, 0x72, 0x76, 0x83, 0x7b, 0x77, 0x82, 0x81, 0x77, 0x6b, 0x62, 0x65, 0x6e, + 0x74, 0x73, 0x68, 0x5f, 0x61, 0x68, 0x7c, 0x8c, 0x92, 0x86, 0x85, 0x89, 0x88, 0x89, 0x8d, 0x8d, + 0x88, 0x81, 0x76, 0x73, 0x7b, 0x83, 0x81, 0x7b, 0x83, 0x87, 0x88, 0x86, 0x85, 0x87, 0x86, 0x7d, + 0x73, 0x6a, 0x6e, 0x80, 0x81, 0x7a, 0x86, 0x86, 0x84, 0x86, 0x85, 0x7d, 0x75, 0x70, 0x6c, 0x69, + 0x69, 0x70, 0x7a, 0x7a, 0x77, 0x78, 0x77, 0x77, 0x7b, 0x71, 0x66, 0x57, 0x55, 0x72, 0x81, 0x7e, + 0x7d, 0x80, 0x89, 0x8b, 0x73, 0x68, 0x6a, 0x67, 0x69, 0x6a, 0x65, 0x5b, 0x5c, 0x5e, 0x55, 0x4f, + 0x53, 0x5a, 0x62, 0x66, 0x69, 0x6a, 0x67, 0x6c, 0x78, 0x83, 0x94, 0x9a, 0x95, 0x8d, 0x86, 0x83, + 0x89, 0x99, 0xa2, 0x90, 0x7d, 0x83, 0x8b, 0x89, 0x7d, 0x71, 0x68, 0x5f, 0x5b, 0x5d, 0x65, 0x7b, + 0x89, 0x93, 0x94, 0x88, 0x80, 0x71, 0x67, 0x6c, 0x76, 0x7e, 0x82, 0x82, 0x80, 0x7a, 0x7e, 0x8a, + 0x99, 0xaa, 0xab, 0xa1, 0xa4, 0xa6, 0xa5, 0x9f, 0x9a, 0x96, 0x94, 0x8c, 0x86, 0x8b, 0x89, 0x8a, + 0x8b, 0x84, 0x77, 0x6e, 0x6d, 0x69, 0x76, 0x90, 0x92, 0x8b, 0x83, 0x8b, 0xa2, 0xa3, 0x9f, 0xa5, + 0xab, 0xa9, 0x91, 0x8b, 0x87, 0x7e, 0x74, 0x6f, 0x72, 0x79, 0x85, 0x94, 0xa1, 0xa6, 0xa6, 0xa9, + 0xa5, 0x9c, 0x99, 0x98, 0x94, 0x9d, 0xb6, 0xb1, 0x9f, 0x97, 0x91, 0x8e, 0x8b, 0x95, 0x9a, 0x92, + 0x83, 0x69, 0x57, 0x61, 0x75, 0x77, 0x6e, 0x65, 0x57, 0x54, 0x5f, 0x5c, 0x5d, 0x69, 0x62, 0x5b, + 0x65, 0x6a, 0x78, 0x8c, 0x92, 0x99, 0x8e, 0x83, 0x85, 0x8a, 0x91, 0x9a, 0xa5, 0xa4, 0x92, 0x86, + 0x82, 0x76, 0x78, 0x78, 0x70, 0x65, 0x64, 0x6c, 0x6d, 0x62, 0x5d, 0x6a, 0x6e, 0x77, 0x7b, 0x6d, + 0x60, 0x58, 0x56, 0x5e, 0x6e, 0x6b, 0x67, 0x6d, 0x6e, 0x72, 0x73, 0x80, 0x88, 0x74, 0x69, 0x7b, + 0x88, 0x92, 0x97, 0x90, 0x90, 0x8a, 0x7c, 0x6b, 0x64, 0x71, 0x77, 0x76, 0x6f, 0x63, 0x61, 0x62, + 0x6d, 0x7e, 0x83, 0x7b, 0x7b, 0x75, 0x82, 0x9a, 0x9e, 0x93, 0x92, 0x90, 0x76, 0x6d, 0x78, 0x70, + 0x66, 0x6b, 0x64, 0x5a, 0x5f, 0x65, 0x6a, 0x73, 0x7b, 0x87, 0x88, 0x78, 0x65, 0x52, 0x60, 0x7b, + 0x8d, 0xa3, 0x9d, 0x8b, 0x83, 0x82, 0x8c, 0x89, 0x83, 0x8a, 0x85, 0x73, 0x6a, 0x6a, 0x61, 0x77, + 0x8d, 0x83, 0x75, 0x6e, 0x69, 0x5d, 0x5c, 0x70, 0x7b, 0x76, 0x6c, 0x63, 0x5d, 0x67, 0x7d, 0x8e, + 0xa3, 0xa7, 0xa3, 0xa4, 0xa6, 0xa6, 0xad, 0xac, 0x9a, 0x8a, 0x7e, 0x6b, 0x53, 0x44, 0x4a, 0x57, + 0x5d, 0x69, 0x75, 0x7e, 0x80, 0x73, 0x65, 0x77, 0x8a, 0x84, 0x76, 0x78, 0x8c, 0x9a, 0xa2, 0xa7, + 0xae, 0xb9, 0xbd, 0xbe, 0xc6, 0xd1, 0xcb, 0xb6, 0xa5, 0xa2, 0xa7, 0xab, 0xaa, 0xaa, 0xa7, 0x98, + 0x8e, 0x92, 0x8f, 0x92, 0x8d, 0x83, 0x7b, 0x6f, 0x5d, 0x4f, 0x56, 0x6c, 0x7e, 0x82, 0x83, 0x82, + 0x8f, 0xaf, 0xba, 0xc4, 0xc8, 0xad, 0x87, 0x61, 0x47, 0x4a, 0x62, 0x66, 0x63, 0x71, 0x7a, 0x70, + 0x6c, 0x71, 0x76, 0x85, 0x95, 0x96, 0x84, 0x74, 0x6e, 0x6d, 0x73, 0x89, 0x9e, 0x9f, 0x8b, 0x7b, + 0x78, 0x83, 0x87, 0x85, 0x76, 0x63, 0x52, 0x4b, 0x3e, 0x40, 0x53, 0x5a, 0x61, 0x60, 0x56, 0x50, + 0x4e, 0x60, 0x74, 0x81, 0x82, 0x6d, 0x65, 0x66, 0x62, 0x65, 0x7d, 0x9f, 0xa6, 0xa8, 0xb4, 0xc0, + 0xc2, 0xc2, 0xaa, 0x8f, 0x8b, 0x86, 0x77, 0x6a, 0x65, 0x62, 0x62, 0x6b, 0x6e, 0x72, 0x76, 0x7a, + 0x75, 0x71, 0x7c, 0x75, 0x63, 0x5a, 0x5a, 0x5e, 0x63, 0x69, 0x7a, 0x78, 0x67, 0x74, 0x8a, 0x99, + 0x93, 0x91, 0x98, 0x9b, 0x99, 0x95, 0x8b, 0x8d, 0x8f, 0x83, 0x7c, 0x6f, 0x77, 0x8c, 0x93, 0x8c, + 0x83, 0x76, 0x61, 0x4c, 0x4e, 0x60, 0x7b, 0x97, 0xa1, 0x98, 0x91, 0x9e, 0xa9, 0xb5, 0xbf, 0xb2, + 0x8f, 0x73, 0x6c, 0x6f, 0x64, 0x5d, 0x69, 0x75, 0x7a, 0x77, 0x70, 0x76, 0x79, 0x81, 0x84, 0x82, + 0x81, 0x77, 0x87, 0x9a, 0xa0, 0xae, 0xc4, 0xc0, 0xa5, 0x90, 0x85, 0x82, 0x80, 0x89, 0x8d, 0x79, + 0x64, 0x52, 0x4f, 0x4e, 0x5b, 0x61, 0x59, 0x55, 0x4b, 0x3e, 0x45, 0x4f, 0x51, 0x52, 0x50, 0x46, + 0x42, 0x48, 0x52, 0x6d, 0x8e, 0xa3, 0xad, 0xa0, 0x95, 0x98, 0x98, 0x9e, 0x9c, 0x8c, 0x7c, 0x6f, + 0x68, 0x67, 0x63, 0x74, 0x7e, 0x7b, 0x78, 0x70, 0x66, 0x61, 0x5a, 0x50, 0x47, 0x41, 0x3b, 0x47, + 0x55, 0x64, 0x76, 0x94, 0xaa, 0xad, 0xa7, 0xa2, 0xa2, 0xaf, 0xc2, 0xc2, 0xb9, 0xb8, 0xb9, 0xbb, + 0xba, 0xb7, 0xb3, 0xb7, 0xaf, 0x96, 0x8a, 0x86, 0x88, 0x88, 0x7a, 0x71, 0x6c, 0x68, 0x75, 0x88, + 0x9b, 0xb0, 0xc0, 0xc4, 0xc1, 0xb0, 0xa8, 0x9f, 0x8f, 0x86, 0x71, 0x59, 0x51, 0x53, 0x56, 0x53, + 0x66, 0x7e, 0x87, 0x7a, 0x77, 0x84, 0x94, 0xa1, 0x9d, 0x90, 0x86, 0x71, 0x6e, 0x79, 0x86, 0x97, + 0xaa, 0xb1, 0xad, 0xa2, 0x9b, 0x9b, 0x8f, 0x90, 0x91, 0x73, 0x67, 0x60, 0x61, 0x66, 0x62, 0x68, + 0x72, 0x71, 0x5b, 0x4e, 0x55, 0x5b, 0x5b, 0x54, 0x4c, 0x3c, 0x2f, 0x32, 0x43, 0x5b, 0x79, 0x98, + 0xac, 0xb1, 0xa9, 0xb0, 0xb6, 0xac, 0xac, 0xaa, 0x98, 0x81, 0x81, 0x8c, 0x95, 0x99, 0x9e, 0xa9, + 0x9f, 0x84, 0x7a, 0x77, 0x7a, 0x7d, 0x7c, 0x70, 0x5d, 0x54, 0x57, 0x65, 0x7a, 0x94, 0xa3, 0xab, + 0xa8, 0xa9, 0xbb, 0xb7, 0xad, 0xa1, 0x8c, 0x7e, 0x75, 0x7c, 0x80, 0x81, 0x82, 0x88, 0x8d, 0x7d, + 0x69, 0x6a, 0x6c, 0x6c, 0x67, 0x61, 0x53, 0x4c, 0x54, 0x57, 0x5f, 0x76, 0x8a, 0x9c, 0xa9, 0xa1, + 0xa1, 0x9e, 0x85, 0x75, 0x61, 0x41, 0x38, 0x45, 0x4c, 0x4e, 0x57, 0x63, 0x69, 0x61, 0x4e, 0x47, + 0x53, 0x5e, 0x67, 0x64, 0x5a, 0x4c, 0x47, 0x4a, 0x4f, 0x5b, 0x6c, 0x78, 0x83, 0x83, 0x82, 0x88, + 0x85, 0x84, 0x87, 0x75, 0x52, 0x5a, 0x73, 0x7e, 0x85, 0x88, 0x90, 0x89, 0x70, 0x5a, 0x5e, 0x6d, + 0x76, 0x72, 0x66, 0x59, 0x50, 0x52, 0x58, 0x6a, 0x84, 0x9a, 0xb3, 0xbf, 0xbc, 0xc0, 0xbb, 0xb6, + 0xb3, 0xaa, 0x9b, 0x82, 0x7e, 0x92, 0x96, 0x92, 0x9c, 0xb0, 0xb2, 0x9b, 0x84, 0x86, 0x8e, 0x94, + 0x8b, 0x82, 0x81, 0x7c, 0x71, 0x71, 0x84, 0x8f, 0x98, 0xa2, 0x9f, 0xa0, 0xa0, 0x9f, 0xa0, 0xa0, + 0x9b, 0x8e, 0x81, 0x78, 0x8e, 0x99, 0x9c, 0xaa, 0xb5, 0xb3, 0xa0, 0x90, 0x8e, 0x8e, 0x88, 0x72, + 0x65, 0x5f, 0x61, 0x6a, 0x71, 0x7e, 0x89, 0x90, 0x96, 0x9e, 0xa0, 0x9b, 0x91, 0x82, 0x71, 0x65, + 0x58, 0x54, 0x56, 0x6a, 0x79, 0x81, 0x92, 0x97, 0x8d, 0x78, 0x6e, 0x6f, 0x76, 0x72, 0x6e, 0x75, + 0x78, 0x7c, 0x83, 0x80, 0x81, 0x89, 0x8d, 0x8d, 0x90, 0x90, 0x94, 0x97, 0x93, 0x89, 0x7d, 0x72, + 0x6d, 0x68, 0x79, 0x8a, 0x94, 0x9a, 0x91, 0x7a, 0x63, 0x60, 0x69, 0x6b, 0x61, 0x5c, 0x5a, 0x59, + 0x5d, 0x65, 0x71, 0x83, 0x97, 0x9e, 0xa3, 0xa7, 0xa3, 0xa2, 0x9a, 0x86, 0x76, 0x6a, 0x63, 0x61, + 0x6a, 0x77, 0x83, 0x88, 0x87, 0x81, 0x74, 0x6b, 0x6c, 0x6f, 0x6e, 0x67, 0x66, 0x63, 0x61, 0x61, + 0x65, 0x6a, 0x76, 0x85, 0x8d, 0x91, 0x91, 0x92, 0x93, 0x8c, 0x84, 0x81, 0x7c, 0x77, 0x71, 0x77, + 0x83, 0x91, 0x97, 0x94, 0x8b, 0x82, 0x7c, 0x82, 0x87, 0x86, 0x7d, 0x71, 0x6c, 0x6f, 0x79, 0x8c, + 0x9a, 0xa0, 0x9b, 0x8e, 0x82, 0x79, 0x76, 0x76, 0x6e, 0x5e, 0x55, 0x52, 0x53, 0x56, 0x60, 0x6c, + 0x75, 0x74, 0x6b, 0x66, 0x69, 0x70, 0x79, 0x7c, 0x79, 0x73, 0x6a, 0x67, 0x67, 0x6f, 0x7b, 0x85, + 0x88, 0x87, 0x85, 0x89, 0x8e, 0x91, 0x95, 0x96, 0x8f, 0x86, 0x81, 0x7e, 0x79, 0x7b, 0x82, 0x86, + 0x85, 0x77, 0x67, 0x5e, 0x5a, 0x5b, 0x5b, 0x5c, 0x59, 0x55, 0x57, 0x5e, 0x6e, 0x80, 0x8d, 0x94, + 0x93, 0x92, 0x97, 0x9f, 0xa7, 0xae, 0xad, 0xa6, 0xa5, 0xab, 0xaf, 0xb5, 0xbb, 0xbf, 0xba, 0xad, + 0xa1, 0x97, 0x8f, 0x8e, 0x8f, 0x8a, 0x81, 0x74, 0x6b, 0x64, 0x61, 0x65, 0x68, 0x61, 0x56, 0x4d, + 0x51, 0x56, 0x5b, 0x5f, 0x5c, 0x5a, 0x5c, 0x68, 0x77, 0x82, 0x93, 0xa3, 0xaa, 0xa7, 0x9b, 0x92, + 0x8a, 0x87, 0x89, 0x8b, 0x8b, 0x86, 0x80, 0x7d, 0x82, 0x8e, 0x9c, 0xa1, 0x9b, 0x8d, 0x7e, 0x7a, + 0x7c, 0x80, 0x7c, 0x70, 0x68, 0x62, 0x64, 0x66, 0x6f, 0x81, 0x89, 0x88, 0x81, 0x73, 0x6a, 0x6b, + 0x73, 0x7b, 0x80, 0x7e, 0x74, 0x6a, 0x69, 0x70, 0x80, 0x91, 0x96, 0x93, 0x8a, 0x85, 0x86, 0x91, + 0x9c, 0x99, 0x93, 0x91, 0x92, 0x96, 0x9c, 0xa5, 0xb0, 0xb5, 0xad, 0x9b, 0x84, 0x72, 0x66, 0x5f, + 0x60, 0x62, 0x5f, 0x57, 0x58, 0x5e, 0x66, 0x75, 0x82, 0x88, 0x84, 0x7d, 0x82, 0x8b, 0x94, 0x96, + 0x93, 0x8f, 0x8c, 0x8b, 0x8a, 0x89, 0x8d, 0x94, 0x9a, 0x97, 0x8d, 0x88, 0x87, 0x83, 0x82, 0x86, + 0x8a, 0x83, 0x79, 0x78, 0x7b, 0x88, 0x95, 0x98, 0x91, 0x87, 0x88, 0x92, 0x99, 0x9c, 0x94, 0x89, + 0x81, 0x7d, 0x81, 0x84, 0x8a, 0x94, 0x97, 0x90, 0x86, 0x7b, 0x79, 0x7a, 0x7b, 0x80, 0x80, 0x77, + 0x6c, 0x66, 0x64, 0x6e, 0x7d, 0x82, 0x78, 0x65, 0x56, 0x56, 0x5e, 0x63, 0x63, 0x5a, 0x4f, 0x48, + 0x49, 0x4f, 0x58, 0x6a, 0x82, 0x8f, 0x88, 0x77, 0x70, 0x6c, 0x6f, 0x77, 0x7e, 0x80, 0x73, 0x67, + 0x5e, 0x5c, 0x67, 0x76, 0x7d, 0x77, 0x69, 0x60, 0x64, 0x6d, 0x75, 0x7b, 0x79, 0x76, 0x75, 0x74, + 0x73, 0x74, 0x7b, 0x83, 0x80, 0x6c, 0x55, 0x4a, 0x45, 0x4c, 0x58, 0x65, 0x6c, 0x6c, 0x69, 0x66, + 0x69, 0x79, 0x89, 0x8f, 0x8d, 0x8d, 0x97, 0xa0, 0xa5, 0xa8, 0xa4, 0x9a, 0x95, 0x9a, 0xa0, 0x9f, + 0xa3, 0xab, 0xb3, 0xb1, 0xa7, 0x9b, 0x93, 0x8a, 0x87, 0x84, 0x7c, 0x70, 0x67, 0x62, 0x61, 0x65, + 0x6b, 0x6c, 0x62, 0x56, 0x54, 0x58, 0x5e, 0x64, 0x68, 0x6f, 0x78, 0x86, 0x97, 0xa0, 0xa9, 0xb6, + 0xbe, 0xbd, 0xad, 0x9c, 0x94, 0x97, 0xa0, 0xad, 0xb0, 0xa7, 0x9c, 0x94, 0x92, 0x99, 0xa5, 0xac, + 0xa4, 0x92, 0x82, 0x81, 0x83, 0x83, 0x82, 0x78, 0x6a, 0x63, 0x67, 0x6a, 0x6a, 0x75, 0x86, 0x8e, + 0x8a, 0x7c, 0x75, 0x76, 0x7a, 0x82, 0x88, 0x87, 0x7e, 0x79, 0x7c, 0x84, 0x90, 0x9e, 0xa4, 0xa0, + 0x99, 0x94, 0x8e, 0x87, 0x89, 0x92, 0x99, 0x97, 0x95, 0x97, 0x91, 0x8e, 0x96, 0x9e, 0x9d, 0x91, + 0x7e, 0x70, 0x64, 0x62, 0x6b, 0x71, 0x6c, 0x63, 0x61, 0x63, 0x67, 0x74, 0x80, 0x83, 0x7b, 0x75, + 0x72, 0x70, 0x70, 0x74, 0x74, 0x6e, 0x66, 0x66, 0x69, 0x69, 0x6f, 0x7e, 0x88, 0x87, 0x83, 0x82, + 0x7e, 0x78, 0x78, 0x79, 0x7a, 0x77, 0x7a, 0x81, 0x7d, 0x7e, 0x88, 0x8c, 0x87, 0x84, 0x88, 0x8e, + 0x92, 0x97, 0x97, 0x90, 0x89, 0x88, 0x8a, 0x83, 0x7c, 0x86, 0x94, 0x96, 0x8b, 0x7e, 0x79, 0x78, + 0x75, 0x75, 0x71, 0x68, 0x5c, 0x57, 0x5c, 0x61, 0x69, 0x70, 0x6d, 0x68, 0x66, 0x67, 0x64, 0x63, + 0x65, 0x5e, 0x4f, 0x45, 0x42, 0x47, 0x4f, 0x5a, 0x65, 0x6b, 0x66, 0x59, 0x54, 0x57, 0x63, 0x72, + 0x7c, 0x7d, 0x7a, 0x78, 0x7c, 0x88, 0x97, 0xa2, 0xa0, 0x9a, 0x98, 0x96, 0x94, 0x95, 0x9a, 0xa2, + 0xa5, 0x9d, 0x96, 0x96, 0x94, 0x96, 0x99, 0x98, 0x8e, 0x79, 0x63, 0x5e, 0x63, 0x6d, 0x76, 0x76, + 0x72, 0x6d, 0x6a, 0x66, 0x65, 0x6f, 0x80, 0x8c, 0x91, 0x92, 0x93, 0x91, 0x8d, 0x8b, 0x8a, 0x8b, + 0x8c, 0x88, 0x87, 0x86, 0x88, 0x90, 0x96, 0x94, 0x86, 0x7b, 0x7e, 0x84, 0x8d, 0x95, 0x98, 0x98, + 0x91, 0x8b, 0x86, 0x88, 0x94, 0x9a, 0x91, 0x7c, 0x6b, 0x64, 0x64, 0x6b, 0x70, 0x70, 0x6e, 0x6d, + 0x76, 0x85, 0x90, 0x98, 0x97, 0x8f, 0x84, 0x7c, 0x82, 0x8c, 0x92, 0x95, 0x94, 0x8f, 0x89, 0x89, + 0x91, 0x94, 0x97, 0x96, 0x8e, 0x87, 0x84, 0x88, 0x83, 0x74, 0x6d, 0x6a, 0x65, 0x60, 0x65, 0x6e, + 0x6f, 0x6d, 0x6e, 0x72, 0x78, 0x71, 0x63, 0x59, 0x5a, 0x62, 0x6b, 0x74, 0x75, 0x70, 0x6c, 0x71, + 0x7d, 0x8e, 0x99, 0x93, 0x80, 0x6e, 0x71, 0x7e, 0x8f, 0x9f, 0xa2, 0x96, 0x8a, 0x91, 0xa1, 0xb5, + 0xc6, 0xca, 0xbb, 0xa3, 0x84, 0x71, 0x73, 0x80, 0x87, 0x7b, 0x70, 0x6f, 0x74, 0x87, 0x96, 0xa0, + 0xa1, 0x9c, 0x95, 0x8e, 0x91, 0x98, 0x99, 0x94, 0x8e, 0x86, 0x7d, 0x7b, 0x83, 0x86, 0x82, 0x85, + 0x88, 0x87, 0x7e, 0x6a, 0x5a, 0x5a, 0x6b, 0x7e, 0x8e, 0x94, 0x8c, 0x81, 0x7c, 0x7e, 0x89, 0x94, + 0x95, 0x88, 0x72, 0x68, 0x69, 0x6f, 0x75, 0x71, 0x61, 0x4b, 0x47, 0x55, 0x6a, 0x83, 0x93, 0x94, + 0x89, 0x79, 0x6f, 0x71, 0x81, 0x90, 0x90, 0x84, 0x70, 0x62, 0x67, 0x71, 0x75, 0x75, 0x71, 0x6c, + 0x62, 0x64, 0x6f, 0x71, 0x6c, 0x62, 0x53, 0x4a, 0x54, 0x66, 0x72, 0x75, 0x7d, 0x89, 0x8b, 0x85, + 0x79, 0x6f, 0x6b, 0x70, 0x77, 0x7d, 0x7a, 0x6d, 0x65, 0x60, 0x60, 0x6b, 0x76, 0x7b, 0x76, 0x69, + 0x65, 0x6d, 0x79, 0x84, 0x88, 0x81, 0x73, 0x73, 0x82, 0x8d, 0x99, 0xa4, 0xa3, 0x8f, 0x73, 0x68, + 0x6b, 0x79, 0x89, 0x8a, 0x7b, 0x66, 0x5a, 0x5c, 0x67, 0x76, 0x85, 0x89, 0x88, 0x86, 0x8a, 0x96, + 0xa1, 0xa4, 0x9d, 0x95, 0x8c, 0x89, 0x93, 0x9c, 0xa0, 0x9f, 0x9d, 0x9b, 0x9a, 0x96, 0x92, 0x90, + 0x96, 0xa1, 0xa6, 0xa1, 0x93, 0x85, 0x79, 0x73, 0x78, 0x7e, 0x80, 0x75, 0x60, 0x54, 0x55, 0x5e, + 0x64, 0x63, 0x5a, 0x4e, 0x4a, 0x57, 0x69, 0x77, 0x7d, 0x80, 0x7c, 0x74, 0x77, 0x83, 0x95, 0xa9, + 0xb4, 0xad, 0x9a, 0x8d, 0x89, 0x8d, 0x97, 0x9c, 0x95, 0x89, 0x80, 0x77, 0x7e, 0x89, 0x87, 0x79, + 0x6b, 0x63, 0x64, 0x6f, 0x7a, 0x7c, 0x76, 0x75, 0x7a, 0x7a, 0x79, 0x7a, 0x76, 0x76, 0x7d, 0x86, + 0x87, 0x82, 0x7d, 0x7a, 0x7e, 0x8d, 0x9d, 0xa9, 0xab, 0xa1, 0x94, 0x91, 0x99, 0x9e, 0x9f, 0x9e, + 0x98, 0x93, 0x97, 0xa2, 0xaa, 0xb3, 0xb9, 0xb5, 0x9f, 0x8e, 0x8c, 0x92, 0x9b, 0x9d, 0x9a, 0x90, + 0x89, 0x87, 0x87, 0x8c, 0x8c, 0x80, 0x70, 0x6d, 0x6a, 0x6b, 0x74, 0x78, 0x6e, 0x63, 0x62, 0x6a, + 0x7a, 0x8d, 0x95, 0x8d, 0x83, 0x85, 0x8c, 0x94, 0x97, 0x94, 0x90, 0x8e, 0x93, 0x92, 0x8d, 0x89, + 0x7c, 0x6b, 0x67, 0x6b, 0x6b, 0x6e, 0x6d, 0x64, 0x5e, 0x5f, 0x5f, 0x5c, 0x5b, 0x5d, 0x5c, 0x5c, + 0x65, 0x6f, 0x74, 0x7a, 0x7d, 0x78, 0x70, 0x71, 0x74, 0x75, 0x71, 0x69, 0x59, 0x49, 0x49, 0x4f, + 0x58, 0x63, 0x64, 0x5b, 0x51, 0x51, 0x5c, 0x6c, 0x73, 0x66, 0x4c, 0x44, 0x52, 0x68, 0x7c, 0x89, + 0x8a, 0x81, 0x7b, 0x79, 0x7c, 0x87, 0x91, 0x8e, 0x85, 0x80, 0x7b, 0x7a, 0x81, 0x85, 0x81, 0x81, + 0x89, 0x8e, 0x92, 0x8f, 0x8b, 0x85, 0x7d, 0x7b, 0x7b, 0x7e, 0x84, 0x86, 0x88, 0x8d, 0x96, 0xa0, + 0xa8, 0xa5, 0x95, 0x7d, 0x75, 0x7a, 0x85, 0x94, 0x98, 0x8e, 0x7e, 0x76, 0x75, 0x7e, 0x8c, 0x92, + 0x86, 0x75, 0x6f, 0x6f, 0x71, 0x77, 0x79, 0x71, 0x6a, 0x6c, 0x73, 0x83, 0x8c, 0x8d, 0x86, 0x87, + 0x92, 0x9e, 0xab, 0xb4, 0xb5, 0xae, 0xa4, 0x99, 0x96, 0x98, 0x8e, 0x73, 0x5d, 0x56, 0x5b, 0x65, + 0x6c, 0x70, 0x6f, 0x65, 0x5e, 0x5d, 0x62, 0x6a, 0x6a, 0x5f, 0x5a, 0x5f, 0x69, 0x7b, 0x91, 0x9f, + 0x9f, 0x9c, 0x9e, 0xa4, 0xa9, 0xa3, 0x96, 0x8d, 0x89, 0x86, 0x84, 0x8d, 0x94, 0x90, 0x84, 0x7b, + 0x7e, 0x83, 0x86, 0x84, 0x74, 0x66, 0x68, 0x70, 0x80, 0x8e, 0x8f, 0x86, 0x7b, 0x79, 0x83, 0x93, + 0xa1, 0x9f, 0x8d, 0x7d, 0x74, 0x74, 0x83, 0x8e, 0x8d, 0x86, 0x83, 0x84, 0x86, 0x8a, 0x8b, 0x8a, + 0x86, 0x89, 0x8d, 0x92, 0x9c, 0xa3, 0xa6, 0xa5, 0xa7, 0xa8, 0xab, 0xae, 0xab, 0x9d, 0x94, 0x97, + 0x9c, 0xa0, 0xa4, 0xa2, 0x9b, 0x90, 0x87, 0x82, 0x83, 0x81, 0x6e, 0x51, 0x3e, 0x37, 0x3a, 0x4d, + 0x5d, 0x5c, 0x51, 0x4a, 0x4d, 0x5b, 0x6b, 0x73, 0x6f, 0x68, 0x6f, 0x7a, 0x87, 0x98, 0xa2, 0x9f, + 0x91, 0x87, 0x82, 0x84, 0x7d, 0x6d, 0x5c, 0x5b, 0x64, 0x69, 0x71, 0x74, 0x6f, 0x5e, 0x52, 0x53, + 0x5b, 0x60, 0x5d, 0x5a, 0x5a, 0x61, 0x69, 0x77, 0x8d, 0x9d, 0x9c, 0x8e, 0x89, 0x88, 0x89, 0x8b, + 0x8b, 0x87, 0x88, 0x8d, 0x90, 0x99, 0xa9, 0xad, 0x9f, 0x8b, 0x80, 0x74, 0x6f, 0x6f, 0x6a, 0x5f, + 0x54, 0x4f, 0x57, 0x6d, 0x79, 0x78, 0x6d, 0x6a, 0x71, 0x7e, 0x87, 0x83, 0x72, 0x61, 0x5c, 0x60, + 0x6f, 0x84, 0x8b, 0x84, 0x7b, 0x81, 0x8a, 0x8e, 0x8a, 0x7b, 0x64, 0x56, 0x54, 0x58, 0x60, 0x66, + 0x6f, 0x74, 0x78, 0x7c, 0x79, 0x7a, 0x7b, 0x73, 0x68, 0x64, 0x64, 0x68, 0x6f, 0x72, 0x6e, 0x64, + 0x62, 0x66, 0x72, 0x82, 0x81, 0x6e, 0x5f, 0x60, 0x69, 0x7c, 0x91, 0x98, 0x92, 0x89, 0x8b, 0x9a, + 0xb2, 0xbe, 0xb7, 0xaa, 0xa9, 0xb4, 0xc0, 0xd0, 0xdd, 0xda, 0xc8, 0xb7, 0xb0, 0xaf, 0xaf, 0xa8, + 0x9b, 0x92, 0x96, 0x9b, 0x9a, 0x9c, 0x97, 0x86, 0x6f, 0x65, 0x64, 0x67, 0x68, 0x5c, 0x50, 0x51, + 0x60, 0x71, 0x84, 0x95, 0x9f, 0x9a, 0x8f, 0x90, 0x9a, 0xa2, 0x9c, 0x8d, 0x80, 0x7c, 0x80, 0x88, + 0x9b, 0xab, 0xa7, 0x96, 0x89, 0x7e, 0x79, 0x76, 0x6f, 0x5f, 0x51, 0x4e, 0x51, 0x62, 0x75, 0x7a, + 0x72, 0x69, 0x6c, 0x76, 0x82, 0x7c, 0x6d, 0x5c, 0x55, 0x5a, 0x64, 0x73, 0x7e, 0x7e, 0x74, 0x71, + 0x78, 0x82, 0x88, 0x82, 0x73, 0x6b, 0x6f, 0x79, 0x8b, 0x9f, 0xab, 0xb2, 0xb5, 0xb8, 0xbc, 0xc1, + 0xc2, 0xbb, 0xaa, 0x9e, 0x9a, 0x9b, 0xa7, 0xb3, 0xaf, 0xa1, 0x93, 0x87, 0x83, 0x89, 0x89, 0x77, + 0x5e, 0x52, 0x54, 0x5f, 0x72, 0x7a, 0x71, 0x60, 0x55, 0x55, 0x62, 0x6e, 0x6a, 0x5c, 0x50, 0x53, + 0x5c, 0x6b, 0x79, 0x7e, 0x75, 0x67, 0x5f, 0x5e, 0x68, 0x71, 0x6a, 0x59, 0x52, 0x57, 0x61, 0x6f, + 0x7c, 0x7d, 0x73, 0x6e, 0x71, 0x79, 0x82, 0x7d, 0x6b, 0x5b, 0x5d, 0x6a, 0x7e, 0x95, 0x9e, 0x9b, + 0x90, 0x89, 0x87, 0x8a, 0x88, 0x7a, 0x6c, 0x63, 0x64, 0x69, 0x75, 0x83, 0x84, 0x77, 0x67, 0x5e, + 0x5d, 0x69, 0x72, 0x6c, 0x5d, 0x54, 0x58, 0x68, 0x83, 0x9b, 0xa6, 0x9d, 0x92, 0x8e, 0x96, 0xa1, + 0x9e, 0x8c, 0x78, 0x74, 0x7d, 0x98, 0xad, 0xb0, 0xa4, 0x97, 0x92, 0x90, 0x91, 0x90, 0x82, 0x6d, + 0x68, 0x6f, 0x75, 0x7e, 0x83, 0x7b, 0x72, 0x70, 0x73, 0x7b, 0x82, 0x7e, 0x76, 0x6c, 0x6c, 0x72, + 0x80, 0x97, 0xa6, 0xa7, 0xa1, 0x98, 0x90, 0x92, 0x99, 0x97, 0x87, 0x6f, 0x64, 0x66, 0x76, 0x8b, + 0x91, 0x84, 0x73, 0x6b, 0x6c, 0x7c, 0x90, 0x99, 0x92, 0x8a, 0x8a, 0x95, 0xa9, 0xb2, 0xa7, 0x93, + 0x87, 0x84, 0x88, 0x88, 0x79, 0x61, 0x4f, 0x4e, 0x5b, 0x6c, 0x77, 0x78, 0x72, 0x70, 0x70, 0x6b, + 0x6d, 0x75, 0x73, 0x65, 0x5f, 0x69, 0x78, 0x89, 0x91, 0x94, 0x95, 0x91, 0x8a, 0x85, 0x89, 0x89, + 0x80, 0x71, 0x69, 0x6d, 0x7a, 0x8c, 0x98, 0x9a, 0x8e, 0x82, 0x77, 0x7d, 0x8c, 0x88, 0x6e, 0x56, + 0x4d, 0x52, 0x67, 0x7d, 0x89, 0x86, 0x80, 0x7b, 0x84, 0x97, 0x9d, 0x8d, 0x72, 0x67, 0x6a, 0x76, + 0x87, 0x93, 0x97, 0x97, 0x95, 0x96, 0x9a, 0x9b, 0x8e, 0x79, 0x71, 0x79, 0x81, 0x87, 0x8f, 0x94, + 0x94, 0x92, 0x9a, 0xa4, 0xac, 0xae, 0xa8, 0x9e, 0x95, 0x8d, 0x8b, 0x95, 0xa0, 0xa3, 0x9a, 0x8d, + 0x80, 0x78, 0x7c, 0x7a, 0x65, 0x47, 0x33, 0x34, 0x48, 0x64, 0x75, 0x74, 0x67, 0x60, 0x65, 0x6f, + 0x76, 0x77, 0x6f, 0x62, 0x63, 0x70, 0x89, 0x98, 0x96, 0x89, 0x83, 0x85, 0x85, 0x89, 0x8b, 0x87, + 0x7e, 0x78, 0x79, 0x83, 0x93, 0x99, 0x98, 0x9a, 0x9d, 0x9a, 0x96, 0x92, 0x8d, 0x84, 0x76, 0x75, + 0x7e, 0x8b, 0x99, 0x9e, 0x99, 0x8d, 0x83, 0x7d, 0x81, 0x82, 0x74, 0x63, 0x58, 0x5a, 0x68, 0x7c, + 0x88, 0x86, 0x7c, 0x76, 0x73, 0x79, 0x8b, 0x8f, 0x80, 0x68, 0x58, 0x57, 0x62, 0x75, 0x82, 0x81, + 0x78, 0x76, 0x77, 0x7e, 0x87, 0x82, 0x72, 0x62, 0x60, 0x6b, 0x7c, 0x8d, 0x93, 0x8e, 0x87, 0x82, + 0x7d, 0x7c, 0x76, 0x68, 0x59, 0x53, 0x52, 0x53, 0x58, 0x5f, 0x65, 0x67, 0x6a, 0x71, 0x78, 0x7d, + 0x7c, 0x6f, 0x60, 0x5e, 0x65, 0x75, 0x8a, 0x94, 0x95, 0x8c, 0x84, 0x84, 0x87, 0x89, 0x82, 0x6f, + 0x61, 0x5d, 0x65, 0x7b, 0x8e, 0x8d, 0x7e, 0x75, 0x74, 0x7d, 0x8b, 0x8f, 0x85, 0x74, 0x72, 0x7a, + 0x84, 0x8c, 0x91, 0x93, 0x91, 0x8f, 0x8f, 0x94, 0x93, 0x8a, 0x7c, 0x6c, 0x6b, 0x70, 0x7a, 0x86, + 0x87, 0x83, 0x79, 0x74, 0x72, 0x75, 0x7c, 0x7d, 0x75, 0x6d, 0x6c, 0x6f, 0x7c, 0x87, 0x88, 0x83, + 0x83, 0x8b, 0x94, 0x9d, 0x9a, 0x90, 0x84, 0x85, 0x90, 0xa0, 0xb0, 0xb9, 0xb8, 0xaf, 0xab, 0xab, + 0xb0, 0xb3, 0xa6, 0x8c, 0x79, 0x79, 0x84, 0x9b, 0xae, 0xb1, 0xa5, 0x9c, 0x9d, 0x9f, 0xa2, 0xa2, + 0x91, 0x75, 0x61, 0x59, 0x63, 0x72, 0x78, 0x78, 0x71, 0x6b, 0x6b, 0x68, 0x63, 0x5b, 0x50, 0x4c, + 0x52, 0x59, 0x65, 0x74, 0x7d, 0x85, 0x8f, 0x9e, 0xa9, 0xad, 0xb0, 0xaf, 0xa2, 0x98, 0x97, 0x9b, + 0xab, 0xb3, 0xae, 0xa2, 0x95, 0x8e, 0x8e, 0x90, 0x8b, 0x78, 0x5c, 0x4d, 0x4d, 0x5e, 0x74, 0x7c, + 0x74, 0x67, 0x62, 0x64, 0x6e, 0x78, 0x76, 0x6a, 0x61, 0x61, 0x68, 0x75, 0x7e, 0x82, 0x7c, 0x7a, + 0x88, 0x97, 0xa2, 0xa5, 0xa1, 0x97, 0x8d, 0x8d, 0x92, 0x95, 0x8f, 0x87, 0x7e, 0x79, 0x7b, 0x80, + 0x83, 0x80, 0x72, 0x64, 0x5f, 0x5f, 0x65, 0x6e, 0x6e, 0x67, 0x60, 0x5c, 0x5d, 0x64, 0x68, 0x66, + 0x5f, 0x53, 0x49, 0x45, 0x4c, 0x5a, 0x65, 0x65, 0x62, 0x67, 0x72, 0x79, 0x71, 0x5f, 0x4b, 0x43, + 0x48, 0x5e, 0x7a, 0x87, 0x85, 0x7b, 0x7e, 0x8b, 0x9b, 0xa2, 0x95, 0x7b, 0x6c, 0x6e, 0x7c, 0x92, + 0x9e, 0x9e, 0x94, 0x88, 0x85, 0x83, 0x7e, 0x77, 0x6a, 0x5a, 0x53, 0x4e, 0x4b, 0x59, 0x6a, 0x74, + 0x7d, 0x87, 0x8d, 0x8b, 0x87, 0x83, 0x7e, 0x7c, 0x80, 0x84, 0x8d, 0x9d, 0xa3, 0x9c, 0x90, 0x8d, + 0x93, 0x9c, 0x9f, 0x94, 0x80, 0x71, 0x74, 0x80, 0x91, 0x9e, 0x9c, 0x92, 0x92, 0x9c, 0xae, 0xbd, + 0xbe, 0xb3, 0xa0, 0x94, 0x92, 0x98, 0xa3, 0xa4, 0x9e, 0x97, 0x98, 0x9e, 0xa3, 0xa4, 0x9b, 0x8a, + 0x7a, 0x78, 0x76, 0x78, 0x7d, 0x7d, 0x74, 0x70, 0x74, 0x7d, 0x8c, 0x8f, 0x84, 0x72, 0x66, 0x66, + 0x6b, 0x75, 0x7e, 0x7d, 0x7a, 0x7b, 0x7e, 0x85, 0x8e, 0x93, 0x8c, 0x7e, 0x75, 0x71, 0x74, 0x80, + 0x80, 0x76, 0x6c, 0x68, 0x69, 0x6b, 0x66, 0x57, 0x43, 0x3a, 0x3d, 0x43, 0x52, 0x5a, 0x5a, 0x57, + 0x57, 0x5e, 0x70, 0x84, 0x85, 0x72, 0x62, 0x68, 0x78, 0x8b, 0x9d, 0xa4, 0x9d, 0x92, 0x8f, 0x8f, + 0x93, 0x9e, 0xa1, 0x91, 0x81, 0x7b, 0x77, 0x7a, 0x89, 0x95, 0x99, 0x9c, 0xa1, 0xa6, 0xb0, 0xb0, + 0xa6, 0x96, 0x8d, 0x8a, 0x8a, 0x93, 0x9f, 0xa1, 0x98, 0x94, 0x94, 0x95, 0x94, 0x84, 0x69, 0x54, + 0x55, 0x58, 0x5a, 0x63, 0x67, 0x5c, 0x50, 0x57, 0x69, 0x80, 0x8f, 0x8b, 0x75, 0x64, 0x5e, 0x5d, + 0x69, 0x7a, 0x81, 0x80, 0x82, 0x8d, 0x9e, 0xad, 0xb0, 0xa6, 0x99, 0x92, 0x8d, 0x8f, 0x9b, 0xa3, + 0x9c, 0x8d, 0x85, 0x81, 0x7e, 0x82, 0x7e, 0x71, 0x60, 0x5b, 0x5e, 0x64, 0x67, 0x66, 0x66, 0x6a, + 0x72, 0x7b, 0x88, 0x8c, 0x88, 0x7b, 0x6c, 0x61, 0x67, 0x7b, 0x86, 0x87, 0x81, 0x7e, 0x84, 0x8d, + 0x96, 0x92, 0x82, 0x73, 0x76, 0x83, 0x8e, 0x98, 0x9f, 0xa1, 0xa0, 0x9d, 0x9e, 0xa8, 0xac, 0xa1, + 0x8c, 0x7d, 0x7c, 0x7d, 0x80, 0x80, 0x7b, 0x77, 0x72, 0x6f, 0x76, 0x82, 0x7b, 0x68, 0x57, 0x50, + 0x4d, 0x4d, 0x5f, 0x70, 0x78, 0x75, 0x72, 0x74, 0x85, 0x92, 0x8f, 0x88, 0x7e, 0x79, 0x78, 0x7e, + 0x86, 0x89, 0x87, 0x80, 0x7d, 0x7c, 0x80, 0x78, 0x6c, 0x62, 0x5e, 0x60, 0x60, 0x68, 0x72, 0x72, + 0x6a, 0x6c, 0x76, 0x86, 0x90, 0x88, 0x78, 0x6b, 0x67, 0x63, 0x6b, 0x78, 0x82, 0x81, 0x7b, 0x84, + 0x94, 0xa0, 0xa8, 0xa4, 0x96, 0x8b, 0x89, 0x8b, 0x8d, 0x88, 0x83, 0x7b, 0x6f, 0x6c, 0x67, 0x63, + 0x60, 0x59, 0x51, 0x4a, 0x47, 0x47, 0x47, 0x44, 0x42, 0x48, 0x55, 0x68, 0x7d, 0x93, 0xa1, 0x9f, + 0x95, 0x93, 0x94, 0x91, 0x8c, 0x83, 0x72, 0x6d, 0x71, 0x77, 0x86, 0x8f, 0x83, 0x6a, 0x61, 0x6b, + 0x76, 0x81, 0x83, 0x81, 0x80, 0x82, 0x85, 0x8d, 0x9d, 0xaa, 0xab, 0xa6, 0xa6, 0xac, 0xac, 0xa6, + 0xae, 0xb0, 0xac, 0xb1, 0xc4, 0xdb, 0xe3, 0xd3, 0xb9, 0xa2, 0x97, 0x92, 0x94, 0x9b, 0x98, 0x92, + 0x8c, 0x94, 0xa6, 0xb5, 0xb1, 0x9b, 0x83, 0x7b, 0x84, 0x92, 0xa3, 0xa9, 0xa4, 0x9e, 0x9c, 0x9d, + 0xa3, 0x9d, 0x89, 0x6e, 0x58, 0x55, 0x55, 0x51, 0x4b, 0x3f, 0x37, 0x3b, 0x4b, 0x5f, 0x6b, 0x6a, + 0x60, 0x48, 0x4c, 0x60, 0x6a, 0x6d, 0x70, 0x75, 0x7a, 0x86, 0x91, 0x95, 0xa2, 0xa4, 0x9a, 0x9a, + 0xa8, 0xa9, 0x9f, 0x98, 0x97, 0x98, 0x9a, 0x9e, 0x96, 0x89, 0x87, 0x84, 0x7d, 0x76, 0x6a, 0x5a, + 0x52, 0x51, 0x51, 0x53, 0x4f, 0x4b, 0x51, 0x63, 0x72, 0x77, 0x7b, 0x75, 0x6d, 0x6c, 0x5f, 0x60, + 0x65, 0x57, 0x4b, 0x45, 0x4f, 0x5e, 0x72, 0x79, 0x69, 0x63, 0x66, 0x6d, 0x7c, 0x87, 0x8a, 0x84, + 0x80, 0x8a, 0x97, 0xa3, 0xa3, 0x8f, 0x7a, 0x78, 0x7a, 0x85, 0x8a, 0x83, 0x81, 0x73, 0x68, 0x78, + 0x84, 0x83, 0x78, 0x63, 0x54, 0x55, 0x5e, 0x6b, 0x6a, 0x5d, 0x58, 0x58, 0x5b, 0x6f, 0x86, 0x80, + 0x6f, 0x73, 0x79, 0x87, 0x9d, 0xa8, 0xa7, 0xac, 0xa7, 0xa3, 0xaf, 0xbc, 0xb8, 0x9a, 0x8a, 0x85, + 0x8f, 0x95, 0x8b, 0x78, 0x6a, 0x5e, 0x59, 0x62, 0x6f, 0x76, 0x70, 0x68, 0x6a, 0x77, 0x7c, 0x68, + 0x4f, 0x51, 0x58, 0x5b, 0x69, 0x77, 0x7d, 0x83, 0x83, 0x72, 0x7c, 0x8c, 0x77, 0x6d, 0x77, 0x7c, + 0x81, 0x83, 0x81, 0x7d, 0x85, 0x90, 0x92, 0x89, 0x82, 0x81, 0x77, 0x80, 0x90, 0x9d, 0x97, 0x8a, + 0x93, 0xa5, 0xb2, 0xbf, 0xce, 0xc3, 0xab, 0x9a, 0x8f, 0x8c, 0x89, 0x80, 0x7c, 0x86, 0x8e, 0x99, + 0x93, 0x87, 0x81, 0x74, 0x77, 0x85, 0x86, 0x86, 0x87, 0x7d, 0x76, 0x7c, 0x85, 0x8e, 0x93, 0x8c, + 0x79, 0x6f, 0x77, 0x81, 0x91, 0x9f, 0x99, 0x86, 0x7e, 0x7d, 0x8b, 0xaf, 0xbb, 0xa8, 0x98, 0x8e, + 0x8d, 0x99, 0x9d, 0x98, 0x99, 0x99, 0x90, 0x8d, 0x8b, 0x93, 0x9b, 0x87, 0x76, 0x77, 0x90, 0x9a, + 0x85, 0x73, 0x70, 0x73, 0x82, 0x97, 0xa4, 0x88, 0x66, 0x52, 0x48, 0x56, 0x60, 0x52, 0x3b, 0x3a, + 0x45, 0x56, 0x69, 0x71, 0x77, 0x6f, 0x5e, 0x6c, 0x82, 0x78, 0x5a, 0x4f, 0x5b, 0x6f, 0x88, 0x95, + 0x8f, 0x91, 0xa5, 0xa7, 0x9d, 0x9f, 0x91, 0x78, 0x7d, 0x78, 0x77, 0x85, 0x74, 0x5e, 0x5e, 0x6b, + 0x6d, 0x65, 0x5c, 0x56, 0x51, 0x4f, 0x61, 0x77, 0x79, 0x6f, 0x67, 0x60, 0x64, 0x6f, 0x7b, 0x85, + 0x83, 0x73, 0x64, 0x54, 0x58, 0x5d, 0x62, 0x72, 0x6e, 0x6b, 0x73, 0x7c, 0x81, 0x7e, 0x8e, 0x9f, + 0xaa, 0xb9, 0xd0, 0xc8, 0xaf, 0xa4, 0x9e, 0xa3, 0xb2, 0xb9, 0xb2, 0x9e, 0x9a, 0x98, 0xa0, 0xa3, + 0x93, 0x78, 0x6b, 0x67, 0x62, 0x61, 0x6b, 0x71, 0x68, 0x6a, 0x66, 0x63, 0x67, 0x65, 0x5d, 0x59, + 0x5e, 0x65, 0x74, 0x7b, 0x7b, 0x86, 0x8c, 0x94, 0xa5, 0xa7, 0x94, 0x81, 0x81, 0x77, 0x75, 0x88, + 0x9f, 0x94, 0x83, 0x80, 0x87, 0x8d, 0x8d, 0x81, 0x76, 0x6b, 0x6d, 0x7b, 0x8c, 0x8e, 0x81, 0x86, + 0x8a, 0x77, 0x6e, 0x69, 0x53, 0x3c, 0x3f, 0x48, 0x5c, 0x75, 0x72, 0x69, 0x6a, 0x88, 0x9e, 0xa1, + 0x8d, 0x73, 0x60, 0x57, 0x56, 0x60, 0x5f, 0x5e, 0x59, 0x6e, 0x80, 0x84, 0x8b, 0x8b, 0x78, 0x6b, + 0x66, 0x71, 0x85, 0x84, 0x7b, 0x82, 0x8d, 0x93, 0x9e, 0xa1, 0x9e, 0x90, 0x85, 0x83, 0x71, 0x6b, + 0x6d, 0x69, 0x6e, 0x78, 0x72, 0x76, 0x87, 0x8c, 0x85, 0x88, 0x87, 0x87, 0x8f, 0x8f, 0x97, 0xa1, + 0xa2, 0xa0, 0xa7, 0xa4, 0x99, 0x90, 0x88, 0x88, 0x88, 0x9e, 0xae, 0xb0, 0xaf, 0xa8, 0xa1, 0x9c, + 0x97, 0x9a, 0x9c, 0x9a, 0x84, 0x7d, 0x95, 0x9d, 0x8e, 0x85, 0x89, 0x91, 0x9d, 0xa7, 0xad, 0xa6, + 0x98, 0x8e, 0x8b, 0x88, 0x85, 0x7d, 0x72, 0x6c, 0x7b, 0x92, 0xa0, 0x92, 0x70, 0x59, 0x50, 0x58, + 0x60, 0x59, 0x51, 0x43, 0x46, 0x5e, 0x72, 0x6c, 0x57, 0x5f, 0x73, 0x86, 0x96, 0x9a, 0x91, 0x89, + 0x84, 0x7a, 0x76, 0x81, 0x94, 0x90, 0x79, 0x7e, 0xa3, 0xbe, 0xb6, 0x9d, 0x89, 0x7e, 0x84, 0x87, + 0x79, 0x65, 0x4f, 0x4f, 0x56, 0x58, 0x5d, 0x6a, 0x72, 0x6f, 0x7d, 0x8e, 0x8c, 0x89, 0x81, 0x71, + 0x68, 0x5e, 0x5c, 0x71, 0x74, 0x6a, 0x6e, 0x7a, 0x85, 0x7a, 0x7a, 0x7a, 0x73, 0x77, 0x80, 0x7b, + 0x76, 0x7a, 0x86, 0x93, 0x95, 0x99, 0xb1, 0xb8, 0xad, 0x9d, 0x90, 0x8e, 0x96, 0x9a, 0x96, 0x92, + 0x93, 0x8b, 0x80, 0x83, 0x7b, 0x7c, 0x82, 0x85, 0x81, 0x84, 0x87, 0x95, 0x92, 0x81, 0x6d, 0x58, + 0x5d, 0x6a, 0x5d, 0x4a, 0x47, 0x50, 0x61, 0x6d, 0x74, 0x7c, 0x79, 0x83, 0x90, 0x96, 0x8d, 0x79, + 0x68, 0x5d, 0x57, 0x52, 0x63, 0x73, 0x60, 0x56, 0x5b, 0x5f, 0x60, 0x5c, 0x48, 0x30, 0x2b, 0x39, + 0x57, 0x56, 0x4a, 0x4d, 0x5a, 0x53, 0x4b, 0x4b, 0x47, 0x3f, 0x34, 0x3d, 0x54, 0x5e, 0x59, 0x54, + 0x50, 0x4d, 0x5e, 0x70, 0x73, 0x69, 0x57, 0x55, 0x64, 0x74, 0x7c, 0x72, 0x6a, 0x6b, 0x83, 0x95, + 0x9f, 0xad, 0xb0, 0xaa, 0xad, 0xbd, 0xca, 0xd4, 0xe3, 0xe5, 0xec, 0xec, 0xea, 0xf4, 0xee, 0xd5, + 0xbc, 0xac, 0xac, 0xb6, 0xb3, 0xb1, 0xae, 0xb6, 0xb9, 0xb5, 0xaf, 0xb5, 0xb4, 0x9f, 0x9f, 0xaa, + 0xb9, 0xbf, 0xaf, 0xa0, 0x98, 0x87, 0x85, 0x8f, 0x98, 0x94, 0x8a, 0x8c, 0xae, 0xbd, 0xc0, 0xb4, + 0xa0, 0xa1, 0x8c, 0x72, 0x81, 0x95, 0xa0, 0x88, 0x71, 0x77, 0x95, 0x92, 0x72, 0x75, 0x84, 0x8e, + 0x95, 0x88, 0x68, 0x4a, 0x4e, 0x51, 0x57, 0x6f, 0x82, 0x81, 0x76, 0x72, 0x76, 0x7b, 0x61, 0x3c, + 0x36, 0x41, 0x46, 0x50, 0x63, 0x66, 0x5b, 0x50, 0x59, 0x64, 0x5f, 0x53, 0x57, 0x62, 0x70, 0x73, + 0x72, 0x72, 0x6d, 0x6b, 0x71, 0x81, 0x95, 0xa7, 0xa9, 0x9d, 0x90, 0x92, 0x97, 0x9a, 0x96, 0x8d, + 0x86, 0x84, 0x82, 0x80, 0x7b, 0x73, 0x5e, 0x50, 0x50, 0x5d, 0x7e, 0x9a, 0x9e, 0x9a, 0x8f, 0x85, + 0x88, 0x8c, 0x7c, 0x64, 0x58, 0x60, 0x71, 0x80, 0x71, 0x5c, 0x54, 0x54, 0x50, 0x5c, 0x76, 0x80, + 0x82, 0x83, 0x82, 0x7e, 0x8b, 0x99, 0xa7, 0xaf, 0xaf, 0xac, 0xa8, 0xa0, 0x97, 0x89, 0x7d, 0x77, + 0x7c, 0x7e, 0x73, 0x67, 0x6c, 0x68, 0x5e, 0x5b, 0x5b, 0x52, 0x3c, 0x2f, 0x35, 0x4c, 0x57, 0x53, + 0x4d, 0x3e, 0x31, 0x30, 0x34, 0x34, 0x38, 0x3b, 0x4b, 0x63, 0x7a, 0x84, 0x7d, 0x7b, 0x97, 0xab, + 0xa4, 0x96, 0x84, 0x72, 0x6a, 0x71, 0x86, 0x9d, 0xa3, 0x98, 0x8f, 0x8c, 0x88, 0x93, 0x9d, 0x95, + 0x86, 0x83, 0x84, 0x84, 0x81, 0x78, 0x76, 0x74, 0x78, 0x7a, 0x78, 0x75, 0x69, 0x62, 0x64, 0x5e, + 0x6c, 0x82, 0x87, 0x82, 0x7a, 0x7a, 0x85, 0x8f, 0x9a, 0xa2, 0xa4, 0xa3, 0x9f, 0xa4, 0xb0, 0xbd, + 0xbd, 0xbb, 0xbb, 0xbc, 0xc1, 0xcb, 0xcb, 0xc4, 0xc1, 0xc1, 0xcc, 0xce, 0xc4, 0xaf, 0xa0, 0xa3, + 0xa9, 0xa9, 0x98, 0x84, 0x6f, 0x67, 0x6b, 0x77, 0x81, 0x80, 0x7c, 0x82, 0x83, 0x86, 0x8f, 0x88, + 0x7a, 0x77, 0x7d, 0x85, 0x8d, 0x8c, 0x85, 0x81, 0x87, 0x94, 0x9b, 0x94, 0x80, 0x69, 0x68, 0x74, + 0x82, 0x8e, 0x8f, 0x84, 0x79, 0x79, 0x83, 0x8f, 0x8c, 0x77, 0x63, 0x55, 0x4d, 0x52, 0x62, 0x6f, + 0x71, 0x70, 0x75, 0x76, 0x74, 0x6a, 0x5b, 0x50, 0x4e, 0x4c, 0x51, 0x5a, 0x5c, 0x5b, 0x62, 0x6b, + 0x74, 0x7d, 0x82, 0x73, 0x5c, 0x56, 0x5e, 0x6e, 0x7b, 0x85, 0x89, 0x8e, 0x96, 0x9d, 0xa7, 0xaa, + 0x9e, 0x8b, 0x7b, 0x70, 0x6d, 0x72, 0x7c, 0x87, 0x90, 0x90, 0x92, 0x96, 0x92, 0x83, 0x77, 0x7c, + 0x84, 0x8e, 0x90, 0x89, 0x80, 0x7d, 0x7a, 0x7d, 0x85, 0x80, 0x71, 0x69, 0x68, 0x73, 0x8a, 0x94, + 0x8c, 0x7e, 0x7e, 0x81, 0x82, 0x7a, 0x69, 0x53, 0x46, 0x4b, 0x57, 0x62, 0x61, 0x55, 0x4c, 0x50, + 0x5c, 0x6d, 0x73, 0x69, 0x58, 0x55, 0x61, 0x7d, 0x9b, 0xb0, 0xbb, 0xc4, 0xce, 0xd4, 0xd8, 0xce, + 0xb8, 0xa1, 0x98, 0x96, 0x98, 0x9b, 0x93, 0x84, 0x7c, 0x7a, 0x7e, 0x88, 0x84, 0x71, 0x5f, 0x59, + 0x5c, 0x66, 0x73, 0x75, 0x69, 0x5f, 0x5a, 0x5c, 0x68, 0x70, 0x70, 0x71, 0x79, 0x7e, 0x84, 0x88, + 0x89, 0x8f, 0x97, 0x96, 0x91, 0x88, 0x7d, 0x71, 0x6e, 0x72, 0x7c, 0x8b, 0x91, 0x90, 0x8a, 0x8c, + 0x89, 0x86, 0x88, 0x81, 0x73, 0x68, 0x5e, 0x5e, 0x67, 0x6d, 0x6d, 0x69, 0x62, 0x57, 0x55, 0x5b, + 0x5a, 0x4f, 0x4d, 0x54, 0x60, 0x6c, 0x6d, 0x66, 0x65, 0x6e, 0x7c, 0x93, 0xa2, 0x9a, 0x84, 0x72, + 0x6a, 0x73, 0x81, 0x84, 0x7e, 0x7a, 0x82, 0x93, 0xa5, 0xaf, 0xaa, 0x98, 0x90, 0x93, 0xa2, 0xaa, + 0xa3, 0x97, 0x95, 0x95, 0x96, 0x95, 0x87, 0x6c, 0x54, 0x4d, 0x56, 0x69, 0x73, 0x6c, 0x62, 0x68, + 0x77, 0x86, 0x96, 0x9f, 0x98, 0x8f, 0x86, 0x82, 0x8c, 0x93, 0x8e, 0x87, 0x8c, 0x93, 0x98, 0x97, + 0x8a, 0x77, 0x6c, 0x6c, 0x76, 0x87, 0x90, 0x90, 0x94, 0x9a, 0x9d, 0xa4, 0xa6, 0x98, 0x82, 0x78, + 0x77, 0x7b, 0x87, 0x8e, 0x8e, 0x8b, 0x8c, 0x8f, 0x92, 0x90, 0x8b, 0x88, 0x8e, 0x95, 0x9e, 0xa2, + 0xa1, 0x9c, 0x9b, 0xa1, 0xa7, 0xac, 0xaa, 0x9b, 0x84, 0x73, 0x70, 0x75, 0x7a, 0x80, 0x84, 0x83, + 0x7c, 0x79, 0x80, 0x7e, 0x74, 0x6a, 0x65, 0x61, 0x63, 0x6b, 0x70, 0x6f, 0x73, 0x78, 0x7a, 0x7b, + 0x79, 0x6d, 0x62, 0x60, 0x6c, 0x87, 0x9a, 0x98, 0x87, 0x7a, 0x74, 0x7b, 0x8b, 0x91, 0x89, 0x7a, + 0x75, 0x7c, 0x8f, 0x9f, 0xa9, 0xa9, 0xa3, 0x99, 0x95, 0x93, 0x85, 0x6c, 0x5d, 0x5c, 0x67, 0x72, + 0x6e, 0x61, 0x57, 0x58, 0x63, 0x74, 0x7c, 0x75, 0x64, 0x5f, 0x6a, 0x83, 0x9c, 0xa8, 0xa5, 0xa0, + 0x9c, 0x99, 0x9d, 0x9f, 0x92, 0x7b, 0x6f, 0x6f, 0x78, 0x81, 0x80, 0x7d, 0x88, 0x8e, 0x8a, 0x85, + 0x7b, 0x6f, 0x63, 0x61, 0x63, 0x68, 0x65, 0x57, 0x47, 0x42, 0x44, 0x45, 0x45, 0x44, 0x40, 0x39, + 0x35, 0x3c, 0x4b, 0x51, 0x4d, 0x4e, 0x5a, 0x66, 0x6e, 0x71, 0x6d, 0x66, 0x60, 0x5e, 0x61, 0x6f, + 0x7d, 0x85, 0x86, 0x86, 0x81, 0x81, 0x7d, 0x72, 0x63, 0x5d, 0x59, 0x5b, 0x69, 0x73, 0x71, 0x6b, + 0x6f, 0x74, 0x73, 0x6f, 0x69, 0x5e, 0x5b, 0x5b, 0x63, 0x75, 0x80, 0x82, 0x81, 0x82, 0x88, 0x96, + 0x9e, 0x95, 0x81, 0x73, 0x6b, 0x74, 0x8a, 0x9c, 0xa6, 0xb0, 0xb9, 0xc8, 0xd6, 0xdc, 0xd9, 0xd0, + 0xc7, 0xc5, 0xce, 0xd5, 0xd4, 0xc9, 0xbf, 0xbb, 0xbd, 0xbe, 0xb7, 0xa2, 0x8f, 0x88, 0x89, 0x93, + 0x99, 0x93, 0x8c, 0x8a, 0x8e, 0x9b, 0xa9, 0xa5, 0x93, 0x8a, 0x89, 0x8d, 0x9a, 0xa8, 0xa9, 0xa3, + 0xa0, 0xa0, 0xa4, 0xa5, 0x9b, 0x8e, 0x8c, 0x93, 0x9a, 0x9d, 0x96, 0x91, 0x91, 0x91, 0x90, 0x8c, + 0x84, 0x76, 0x62, 0x56, 0x51, 0x52, 0x54, 0x53, 0x50, 0x48, 0x42, 0x43, 0x4d, 0x54, 0x4a, 0x3d, + 0x39, 0x3d, 0x46, 0x52, 0x61, 0x6d, 0x7a, 0x80, 0x7d, 0x81, 0x8a, 0x8c, 0x88, 0x8a, 0x8f, 0x97, + 0x99, 0x91, 0x8a, 0x86, 0x82, 0x82, 0x8a, 0x8b, 0x84, 0x7c, 0x7b, 0x7d, 0x82, 0x85, 0x81, 0x76, + 0x71, 0x6d, 0x72, 0x80, 0x84, 0x79, 0x6d, 0x67, 0x68, 0x73, 0x75, 0x6e, 0x67, 0x63, 0x61, 0x5e, + 0x60, 0x5f, 0x51, 0x45, 0x43, 0x4e, 0x61, 0x6a, 0x72, 0x75, 0x77, 0x79, 0x86, 0x90, 0x8c, 0x85, + 0x81, 0x86, 0x94, 0xa2, 0xa8, 0xa2, 0x9d, 0x9e, 0xa4, 0xb4, 0xbe, 0xb5, 0xa1, 0x94, 0x91, 0x9f, + 0xa7, 0x98, 0x8a, 0x86, 0x80, 0x79, 0x7e, 0x81, 0x75, 0x65, 0x5b, 0x5b, 0x64, 0x67, 0x68, 0x69, + 0x77, 0x88, 0x91, 0x93, 0x90, 0x83, 0x71, 0x68, 0x62, 0x5f, 0x57, 0x4e, 0x4c, 0x51, 0x55, 0x53, + 0x4f, 0x4b, 0x42, 0x37, 0x38, 0x46, 0x59, 0x68, 0x72, 0x7b, 0x85, 0x86, 0x82, 0x86, 0x8f, 0x98, + 0x97, 0x91, 0x8e, 0x8d, 0x8c, 0x8d, 0x93, 0x9c, 0x9e, 0x9b, 0x92, 0x8a, 0x83, 0x7c, 0x7b, 0x7b, + 0x7d, 0x7e, 0x7c, 0x80, 0x86, 0x8a, 0x8a, 0x8a, 0x8a, 0x88, 0x7a, 0x6f, 0x75, 0x89, 0x99, 0xa5, + 0xaf, 0xb1, 0xaa, 0x9f, 0x98, 0x99, 0x97, 0x8d, 0x81, 0x7d, 0x83, 0x8a, 0x8a, 0x89, 0x8e, 0x96, + 0x9d, 0xac, 0xbb, 0xba, 0xad, 0xa1, 0xa0, 0xa6, 0xa3, 0x94, 0x84, 0x7a, 0x77, 0x80, 0x89, 0x81, + 0x70, 0x67, 0x63, 0x67, 0x6c, 0x66, 0x5b, 0x57, 0x5d, 0x64, 0x6b, 0x68, 0x5f, 0x58, 0x54, 0x55, + 0x5c, 0x5b, 0x53, 0x55, 0x64, 0x76, 0x8b, 0x93, 0x96, 0xa1, 0xac, 0xb4, 0xba, 0xb3, 0xa2, 0x9b, + 0x9f, 0xa0, 0xa3, 0xa0, 0x8e, 0x7c, 0x72, 0x71, 0x74, 0x6c, 0x5b, 0x4d, 0x46, 0x49, 0x50, 0x52, + 0x4e, 0x53, 0x62, 0x74, 0x84, 0x84, 0x78, 0x75, 0x80, 0x85, 0x88, 0x87, 0x80, 0x78, 0x74, 0x74, + 0x77, 0x79, 0x73, 0x6c, 0x6c, 0x69, 0x71, 0x83, 0x8a, 0x8a, 0x92, 0x9c, 0xa2, 0x9d, 0x91, 0x8a, + 0x94, 0xa2, 0xab, 0xb6, 0xb3, 0xa0, 0x93, 0x91, 0x95, 0x9d, 0x9d, 0x92, 0x88, 0x81, 0x7d, 0x7e, + 0x79, 0x73, 0x71, 0x6e, 0x6a, 0x71, 0x79, 0x78, 0x75, 0x75, 0x79, 0x86, 0x8d, 0x89, 0x84, 0x84, + 0x86, 0x91, 0x94, 0x89, 0x82, 0x7d, 0x78, 0x87, 0x99, 0xa1, 0xa1, 0x9f, 0x98, 0x97, 0x96, 0x8f, + 0x88, 0x87, 0x8c, 0x9a, 0xa3, 0xa0, 0x97, 0x95, 0x9b, 0xa2, 0xa4, 0x94, 0x7e, 0x73, 0x6c, 0x6c, + 0x70, 0x6a, 0x60, 0x60, 0x67, 0x78, 0x8a, 0x8b, 0x83, 0x7e, 0x79, 0x7a, 0x7d, 0x7a, 0x6e, 0x60, + 0x55, 0x56, 0x5b, 0x51, 0x3f, 0x35, 0x36, 0x40, 0x4f, 0x59, 0x5e, 0x68, 0x74, 0x7d, 0x85, 0x85, + 0x7e, 0x7b, 0x7d, 0x85, 0x8f, 0x90, 0x87, 0x80, 0x79, 0x70, 0x6b, 0x62, 0x55, 0x4e, 0x50, 0x55, + 0x5d, 0x5f, 0x57, 0x4e, 0x53, 0x5e, 0x6b, 0x70, 0x67, 0x5a, 0x5d, 0x63, 0x69, 0x6c, 0x63, 0x57, + 0x51, 0x50, 0x5e, 0x72, 0x83, 0x8b, 0x8b, 0x88, 0x8b, 0x93, 0x96, 0x91, 0x87, 0x7e, 0x83, 0x8c, + 0x89, 0x7c, 0x7b, 0x85, 0x96, 0xa5, 0xa6, 0xa2, 0xa8, 0xaa, 0xab, 0xab, 0xa3, 0x99, 0x97, 0x9d, + 0xa6, 0xb2, 0xb7, 0xb4, 0xb0, 0xac, 0xa8, 0xa5, 0x9b, 0x82, 0x71, 0x6c, 0x76, 0x8c, 0x93, 0x83, + 0x72, 0x76, 0x82, 0x8c, 0x8b, 0x7a, 0x6c, 0x6c, 0x7a, 0x92, 0xa5, 0xa3, 0x9a, 0x94, 0x92, 0xa0, + 0xb3, 0xb7, 0xaf, 0xac, 0xb0, 0xb5, 0xb0, 0xa2, 0x9b, 0x9a, 0x91, 0x8d, 0x8c, 0x7e, 0x70, 0x6e, + 0x71, 0x76, 0x75, 0x68, 0x5c, 0x60, 0x68, 0x71, 0x79, 0x71, 0x63, 0x65, 0x70, 0x80, 0x8b, 0x86, + 0x76, 0x71, 0x70, 0x70, 0x6f, 0x61, 0x4f, 0x4b, 0x53, 0x69, 0x85, 0x91, 0x89, 0x7c, 0x7b, 0x83, + 0x8d, 0x8e, 0x81, 0x77, 0x7c, 0x8b, 0x9d, 0xa6, 0x9e, 0x94, 0x8f, 0x8c, 0x89, 0x84, 0x7e, 0x83, + 0x8d, 0x94, 0x97, 0x97, 0x8c, 0x7c, 0x75, 0x73, 0x7b, 0x7e, 0x70, 0x60, 0x63, 0x70, 0x7a, 0x75, + 0x66, 0x5d, 0x65, 0x72, 0x7e, 0x84, 0x79, 0x69, 0x6b, 0x7a, 0x93, 0xa4, 0xa6, 0xa2, 0xa1, 0xa2, + 0xa7, 0xa3, 0x90, 0x78, 0x72, 0x7b, 0x8b, 0x9c, 0xa1, 0x96, 0x8c, 0x8a, 0x8e, 0x8f, 0x88, 0x76, + 0x6c, 0x6b, 0x6e, 0x73, 0x73, 0x6e, 0x6d, 0x70, 0x77, 0x7a, 0x75, 0x6e, 0x70, 0x79, 0x84, 0x82, + 0x6a, 0x4d, 0x3d, 0x3a, 0x3c, 0x40, 0x3f, 0x32, 0x28, 0x2f, 0x43, 0x52, 0x51, 0x4a, 0x44, 0x45, + 0x4f, 0x63, 0x6b, 0x61, 0x61, 0x72, 0x86, 0x8e, 0x84, 0x74, 0x6e, 0x6d, 0x6d, 0x75, 0x79, 0x72, + 0x6c, 0x6c, 0x6f, 0x77, 0x84, 0x83, 0x6f, 0x66, 0x6f, 0x7b, 0x76, 0x65, 0x5c, 0x62, 0x72, 0x82, + 0x85, 0x7b, 0x73, 0x77, 0x80, 0x8c, 0x93, 0x8b, 0x82, 0x8c, 0xa1, 0xba, 0xc0, 0xb1, 0xa0, 0x9a, + 0x9b, 0xa5, 0xb1, 0xb4, 0xaf, 0xaf, 0xb5, 0xc1, 0xc3, 0xb8, 0xac, 0xab, 0xb2, 0xbd, 0xc5, 0xbd, + 0xab, 0xa1, 0xa0, 0xa6, 0xb0, 0xaa, 0x96, 0x8c, 0x87, 0x8c, 0x95, 0x8c, 0x76, 0x71, 0x79, 0x84, + 0x87, 0x80, 0x78, 0x73, 0x6f, 0x72, 0x79, 0x77, 0x6d, 0x6a, 0x6f, 0x74, 0x7e, 0x86, 0x81, 0x78, + 0x7c, 0x8d, 0xa4, 0xa8, 0x97, 0x92, 0x9f, 0xa9, 0xaf, 0xa9, 0x91, 0x7b, 0x71, 0x6e, 0x6c, 0x68, + 0x66, 0x69, 0x69, 0x68, 0x70, 0x73, 0x65, 0x57, 0x55, 0x5d, 0x69, 0x6b, 0x65, 0x60, 0x65, 0x70, + 0x80, 0x84, 0x73, 0x5a, 0x4f, 0x4d, 0x51, 0x58, 0x52, 0x4b, 0x54, 0x5e, 0x69, 0x72, 0x7b, 0x84, + 0x86, 0x85, 0x8a, 0x8d, 0x86, 0x7e, 0x84, 0x8a, 0x8e, 0x89, 0x7c, 0x73, 0x71, 0x77, 0x86, 0x94, + 0x96, 0x8e, 0x8a, 0x89, 0x8f, 0x9a, 0x96, 0x85, 0x75, 0x75, 0x82, 0x85, 0x78, 0x70, 0x79, 0x89, + 0x95, 0x99, 0x96, 0x8b, 0x7e, 0x7a, 0x81, 0x86, 0x82, 0x80, 0x8a, 0x97, 0xa4, 0xb4, 0xc0, 0xbf, + 0xb7, 0xae, 0xa6, 0xa8, 0xa8, 0x9f, 0x97, 0x9a, 0x9d, 0x9b, 0x92, 0x87, 0x89, 0x92, 0x97, 0x98, + 0x8c, 0x73, 0x62, 0x5d, 0x5e, 0x5e, 0x58, 0x50, 0x4b, 0x4b, 0x4a, 0x52, 0x5d, 0x63, 0x67, 0x6d, + 0x6e, 0x6a, 0x65, 0x5b, 0x4b, 0x44, 0x43, 0x46, 0x45, 0x3d, 0x3d, 0x48, 0x4e, 0x51, 0x55, 0x54, + 0x4c, 0x4c, 0x52, 0x5a, 0x5b, 0x56, 0x5a, 0x68, 0x74, 0x77, 0x76, 0x73, 0x6f, 0x6f, 0x6e, 0x6c, + 0x69, 0x63, 0x54, 0x4a, 0x4a, 0x53, 0x5e, 0x66, 0x6a, 0x78, 0x8a, 0x99, 0xa0, 0x9d, 0x96, 0x97, + 0x9d, 0xa4, 0xa3, 0x9a, 0x92, 0x98, 0xa0, 0xa8, 0xb4, 0xba, 0xb9, 0xbb, 0xb9, 0xb6, 0xb7, 0xb6, + 0xb0, 0xaf, 0xb3, 0xba, 0xbd, 0xb7, 0xaf, 0xb2, 0xbd, 0xbd, 0xb3, 0xa5, 0x9b, 0x9a, 0x9f, 0xa4, + 0xa9, 0xa0, 0x8f, 0x89, 0x93, 0xa0, 0xa9, 0xaa, 0xa4, 0x9e, 0x9c, 0x98, 0x8f, 0x82, 0x74, 0x6d, + 0x6e, 0x73, 0x77, 0x6c, 0x58, 0x55, 0x66, 0x74, 0x7b, 0x77, 0x6d, 0x6c, 0x75, 0x79, 0x7a, 0x78, + 0x71, 0x64, 0x61, 0x6e, 0x82, 0x89, 0x7e, 0x73, 0x74, 0x70, 0x63, 0x52, 0x3f, 0x35, 0x3c, 0x4b, + 0x5c, 0x63, 0x57, 0x4c, 0x54, 0x62, 0x6f, 0x71, 0x6b, 0x60, 0x54, 0x50, 0x52, 0x53, 0x51, 0x55, + 0x64, 0x74, 0x84, 0x8d, 0x8e, 0x87, 0x86, 0x86, 0x82, 0x7a, 0x6a, 0x5e, 0x61, 0x6d, 0x83, 0x98, + 0x9f, 0x9f, 0xa6, 0xb3, 0xc0, 0xc4, 0xbc, 0xb5, 0xba, 0xc2, 0xc1, 0xb6, 0xa4, 0x92, 0x8d, 0x94, + 0x9f, 0xaa, 0xaa, 0xa2, 0x9c, 0x9b, 0x99, 0x99, 0x98, 0x90, 0x83, 0x76, 0x74, 0x7d, 0x7d, 0x76, + 0x79, 0x8d, 0xa0, 0xa7, 0xa1, 0x96, 0x8f, 0x90, 0x8e, 0x87, 0x77, 0x65, 0x5e, 0x61, 0x6d, 0x82, + 0x9a, 0xa7, 0xa8, 0xa8, 0xa4, 0xa1, 0x99, 0x88, 0x75, 0x6f, 0x6c, 0x6f, 0x6c, 0x60, 0x55, 0x5c, + 0x6d, 0x83, 0x8a, 0x7c, 0x6d, 0x6b, 0x6b, 0x70, 0x75, 0x71, 0x69, 0x66, 0x63, 0x67, 0x71, 0x79, + 0x7e, 0x88, 0x8e, 0x8e, 0x88, 0x7b, 0x6d, 0x65, 0x5d, 0x59, 0x57, 0x49, 0x39, 0x38, 0x41, 0x51, + 0x61, 0x62, 0x5b, 0x58, 0x59, 0x5e, 0x5e, 0x51, 0x42, 0x3f, 0x44, 0x49, 0x49, 0x4d, 0x55, 0x60, + 0x71, 0x85, 0x90, 0x8f, 0x85, 0x7e, 0x79, 0x7b, 0x8c, 0x99, 0x98, 0x94, 0x93, 0x96, 0xa0, 0xa1, + 0x9a, 0x98, 0x9a, 0x9c, 0x9c, 0x93, 0x85, 0x78, 0x75, 0x79, 0x80, 0x7c, 0x75, 0x77, 0x85, 0x92, + 0x9c, 0x9d, 0x95, 0x87, 0x7e, 0x7a, 0x7e, 0x83, 0x7b, 0x75, 0x80, 0x8e, 0x97, 0x96, 0x8c, 0x82, + 0x87, 0x97, 0xac, 0xb7, 0xac, 0x9e, 0x97, 0x8f, 0x8e, 0x91, 0x93, 0x8c, 0x80, 0x72, 0x6d, 0x66, + 0x5c, 0x5a, 0x64, 0x69, 0x67, 0x61, 0x58, 0x51, 0x51, 0x5a, 0x6b, 0x75, 0x6d, 0x66, 0x6a, 0x74, + 0x84, 0x91, 0x8f, 0x85, 0x7d, 0x78, 0x7b, 0x82, 0x82, 0x85, 0x99, 0xb0, 0xbf, 0xbd, 0xac, 0x99, + 0x8e, 0x8d, 0x92, 0x96, 0x8f, 0x85, 0x83, 0x82, 0x86, 0x93, 0x99, 0x91, 0x83, 0x75, 0x6c, 0x68, + 0x63, 0x5f, 0x64, 0x6f, 0x7a, 0x80, 0x7e, 0x7a, 0x73, 0x74, 0x7b, 0x85, 0x85, 0x77, 0x70, 0x78, + 0x83, 0x94, 0x9f, 0xa4, 0xad, 0xb8, 0xc0, 0xc6, 0xc3, 0xb2, 0xac, 0xb8, 0xc1, 0xc3, 0xb7, 0xa3, + 0x8c, 0x82, 0x85, 0x91, 0x96, 0x92, 0x90, 0x92, 0x98, 0xa3, 0xac, 0xad, 0xa2, 0x96, 0x8e, 0x85, + 0x7e, 0x73, 0x67, 0x6c, 0x79, 0x87, 0x8d, 0x87, 0x75, 0x6c, 0x6c, 0x79, 0x88, 0x88, 0x7b, 0x76, + 0x78, 0x7c, 0x80, 0x7b, 0x78, 0x7b, 0x80, 0x83, 0x7e, 0x6e, 0x5b, 0x58, 0x5f, 0x62, 0x5e, 0x4e, + 0x3a, 0x34, 0x40, 0x58, 0x71, 0x79, 0x74, 0x76, 0x7e, 0x84, 0x8a, 0x8c, 0x85, 0x7a, 0x6e, 0x65, + 0x64, 0x5d, 0x54, 0x5e, 0x74, 0x84, 0x8b, 0x83, 0x70, 0x5c, 0x51, 0x4f, 0x51, 0x4d, 0x40, 0x3a, + 0x44, 0x52, 0x5c, 0x5c, 0x59, 0x59, 0x5f, 0x63, 0x65, 0x66, 0x5f, 0x5b, 0x66, 0x71, 0x75, 0x71, + 0x67, 0x64, 0x69, 0x6d, 0x74, 0x78, 0x73, 0x6b, 0x6a, 0x69, 0x6c, 0x6a, 0x60, 0x54, 0x4f, 0x53, + 0x5e, 0x68, 0x68, 0x65, 0x6f, 0x7b, 0x87, 0x8c, 0x88, 0x7d, 0x75, 0x6e, 0x72, 0x7d, 0x82, 0x84, + 0x93, 0xa0, 0xa3, 0xa0, 0x99, 0x96, 0x9b, 0x9d, 0xa1, 0xa4, 0x9e, 0x92, 0x93, 0xa1, 0xb3, 0xc1, + 0xc1, 0xb7, 0xad, 0xa9, 0xad, 0xb4, 0xb8, 0xb6, 0xb7, 0xbd, 0xc4, 0xc7, 0xb9, 0xa4, 0x98, 0x95, + 0x93, 0x94, 0x8f, 0x83, 0x7a, 0x7c, 0x85, 0x8e, 0x89, 0x78, 0x6a, 0x66, 0x6c, 0x7e, 0x8f, 0x95, + 0x97, 0x9f, 0xa0, 0x9b, 0x92, 0x8b, 0x87, 0x8a, 0x8e, 0x98, 0x9c, 0x94, 0x8f, 0x9f, 0xb3, 0xbb, + 0xb4, 0xa4, 0x93, 0x8a, 0x82, 0x83, 0x80, 0x70, 0x66, 0x6b, 0x76, 0x80, 0x81, 0x78, 0x6c, 0x64, + 0x60, 0x62, 0x62, 0x5b, 0x53, 0x57, 0x61, 0x6e, 0x75, 0x6e, 0x63, 0x62, 0x69, 0x74, 0x7e, 0x80, + 0x7b, 0x80, 0x86, 0x87, 0x80, 0x6e, 0x65, 0x6a, 0x6f, 0x78, 0x82, 0x81, 0x77, 0x77, 0x7b, 0x80, + 0x7e, 0x72, 0x64, 0x62, 0x65, 0x6b, 0x79, 0x81, 0x7d, 0x82, 0x90, 0xa1, 0xaa, 0xa4, 0x96, 0x8e, + 0x8c, 0x90, 0x94, 0x8f, 0x83, 0x7d, 0x83, 0x8c, 0x93, 0x8f, 0x85, 0x80, 0x7c, 0x77, 0x79, 0x7a, + 0x74, 0x76, 0x85, 0x90, 0x99, 0x95, 0x8a, 0x83, 0x84, 0x88, 0x92, 0x91, 0x85, 0x7c, 0x80, 0x86, + 0x89, 0x7a, 0x63, 0x57, 0x57, 0x59, 0x61, 0x68, 0x68, 0x68, 0x6f, 0x78, 0x81, 0x7c, 0x6b, 0x56, + 0x4d, 0x4a, 0x50, 0x57, 0x53, 0x4a, 0x4d, 0x59, 0x69, 0x6f, 0x69, 0x60, 0x5c, 0x5d, 0x65, 0x6a, + 0x61, 0x54, 0x56, 0x61, 0x6b, 0x67, 0x5b, 0x54, 0x57, 0x5b, 0x60, 0x69, 0x6a, 0x64, 0x6a, 0x78, + 0x88, 0x91, 0x8d, 0x82, 0x7e, 0x81, 0x87, 0x93, 0x97, 0x94, 0x94, 0x9c, 0xa9, 0xaf, 0xa1, 0x88, + 0x7a, 0x79, 0x83, 0x91, 0x98, 0x9c, 0xa9, 0xb8, 0xc3, 0xc6, 0xb8, 0xa3, 0x98, 0x94, 0x97, 0x9f, + 0xa0, 0x9a, 0x98, 0x9f, 0xaa, 0xb5, 0xb2, 0xa3, 0x98, 0x92, 0x91, 0x9c, 0xa0, 0x92, 0x89, 0x90, + 0x9b, 0xa5, 0x9e, 0x8d, 0x84, 0x85, 0x87, 0x88, 0x8a, 0x84, 0x7e, 0x84, 0x8a, 0x91, 0x91, 0x85, + 0x74, 0x6d, 0x6b, 0x73, 0x7a, 0x77, 0x72, 0x74, 0x7a, 0x8d, 0x93, 0x88, 0x72, 0x66, 0x64, 0x6c, + 0x74, 0x6f, 0x69, 0x6f, 0x78, 0x7e, 0x7a, 0x67, 0x54, 0x4c, 0x46, 0x47, 0x4d, 0x49, 0x3e, 0x3c, + 0x44, 0x53, 0x5f, 0x5d, 0x50, 0x49, 0x46, 0x4d, 0x5d, 0x65, 0x61, 0x67, 0x74, 0x83, 0x8f, 0x8c, + 0x7e, 0x7a, 0x7d, 0x82, 0x8a, 0x8a, 0x82, 0x81, 0x86, 0x8d, 0x91, 0x86, 0x75, 0x69, 0x63, 0x69, + 0x78, 0x82, 0x86, 0x8a, 0x90, 0x9a, 0xa1, 0x9d, 0x91, 0x86, 0x89, 0x8e, 0x96, 0x9a, 0x92, 0x8d, + 0x97, 0xa5, 0xb2, 0xb3, 0xa6, 0x9a, 0x98, 0x98, 0x9c, 0xa1, 0x9f, 0x9e, 0xa6, 0xab, 0xb4, 0xb4, + 0xa3, 0x94, 0x92, 0x91, 0x94, 0x98, 0x92, 0x88, 0x88, 0x8e, 0x98, 0x97, 0x86, 0x71, 0x69, 0x6c, + 0x78, 0x83, 0x83, 0x81, 0x88, 0x8e, 0x96, 0x98, 0x90, 0x88, 0x83, 0x80, 0x86, 0x8f, 0x8e, 0x85, + 0x85, 0x8b, 0x93, 0x96, 0x8c, 0x79, 0x6d, 0x69, 0x6f, 0x7a, 0x7e, 0x7d, 0x86, 0x90, 0x9a, 0xa2, + 0x96, 0x80, 0x78, 0x7a, 0x7d, 0x80, 0x7b, 0x6f, 0x6c, 0x70, 0x77, 0x84, 0x83, 0x71, 0x63, 0x5c, + 0x5e, 0x6a, 0x70, 0x6e, 0x70, 0x74, 0x76, 0x78, 0x70, 0x5e, 0x4e, 0x47, 0x48, 0x4f, 0x52, 0x4a, + 0x47, 0x51, 0x62, 0x74, 0x76, 0x6c, 0x62, 0x5e, 0x5d, 0x65, 0x70, 0x70, 0x72, 0x7d, 0x81, 0x7d, + 0x74, 0x68, 0x5f, 0x5f, 0x65, 0x6f, 0x77, 0x73, 0x6e, 0x76, 0x86, 0x97, 0xa0, 0x98, 0x8a, 0x83, + 0x80, 0x85, 0x85, 0x7b, 0x73, 0x78, 0x7d, 0x83, 0x86, 0x7d, 0x72, 0x6e, 0x6f, 0x71, 0x72, 0x6d, + 0x6a, 0x6d, 0x71, 0x7a, 0x83, 0x7a, 0x6a, 0x59, 0x4b, 0x4a, 0x50, 0x54, 0x57, 0x69, 0x81, 0x90, + 0x96, 0x91, 0x87, 0x89, 0x92, 0x9a, 0xa4, 0xa4, 0x95, 0x8d, 0x8c, 0x89, 0x88, 0x82, 0x75, 0x6d, + 0x67, 0x6a, 0x79, 0x84, 0x82, 0x80, 0x83, 0x8a, 0x91, 0x8d, 0x82, 0x78, 0x74, 0x76, 0x7b, 0x7d, + 0x76, 0x79, 0x87, 0x97, 0xaa, 0xb3, 0xad, 0xa8, 0xa3, 0xa0, 0xa2, 0xa2, 0x9e, 0xa2, 0xad, 0xb2, + 0xb4, 0xae, 0x9d, 0x89, 0x81, 0x77, 0x83, 0x91, 0x8f, 0x8c, 0x90, 0x94, 0x98, 0x96, 0x8e, 0x7b, + 0x6d, 0x6c, 0x75, 0x80, 0x79, 0x6c, 0x77, 0x86, 0x8e, 0x8f, 0x84, 0x7b, 0x7c, 0x78, 0x7d, 0x8a, + 0x8b, 0x8e, 0x96, 0x9e, 0xa9, 0xb0, 0xa7, 0x90, 0x8a, 0x8a, 0x8c, 0x97, 0x90, 0x84, 0x93, 0x9e, + 0xa5, 0xac, 0xa8, 0x9e, 0x99, 0x9c, 0xa5, 0xa7, 0x9c, 0x88, 0x85, 0x8e, 0x99, 0x98, 0x8a, 0x74, + 0x68, 0x61, 0x65, 0x6c, 0x6e, 0x72, 0x79, 0x86, 0x97, 0xa9, 0xad, 0x9d, 0x92, 0x91, 0x8f, 0x93, + 0x8d, 0x80, 0x7e, 0x83, 0x8f, 0x8f, 0x7c, 0x6b, 0x60, 0x5f, 0x5f, 0x5f, 0x55, 0x49, 0x4d, 0x55, + 0x59, 0x5d, 0x53, 0x46, 0x3e, 0x3d, 0x49, 0x52, 0x4f, 0x42, 0x3c, 0x4a, 0x51, 0x57, 0x5f, 0x59, + 0x54, 0x57, 0x5e, 0x6c, 0x6b, 0x5d, 0x59, 0x66, 0x75, 0x73, 0x64, 0x5b, 0x58, 0x56, 0x4c, 0x3c, + 0x37, 0x39, 0x39, 0x44, 0x4c, 0x4d, 0x4c, 0x41, 0x31, 0x1d, 0xe, 0x14, 0x1f, 0x24, 0x31, 0x4a, + 0x5e, 0x6a, 0x77, 0x82, 0x7e, 0x7b, 0x88, 0x95, 0xa0, 0xae, 0xaa, 0xaa, 0xb9, 0xca, 0xd5, 0xc8, + 0xb0, 0xac, 0xa8, 0xb0, 0xc3, 0xbe, 0xaa, 0x9f, 0xa3, 0xba, 0xd2, 0xda, 0xcf, 0xbb, 0xb1, 0xb5, + 0xbc, 0xaf, 0x8d, 0x81, 0x95, 0xae, 0xc6, 0xc1, 0xa4, 0xa3, 0xa7, 0xa7, 0xb3, 0xa9, 0x9a, 0x9e, + 0xaa, 0xbd, 0xcb, 0xca, 0xb3, 0xaf, 0xbb, 0xb9, 0xac, 0x96, 0x81, 0x81, 0x9b, 0xb3, 0xb7, 0xa0, + 0x7d, 0x6b, 0x69, 0x6c, 0x69, 0x58, 0x46, 0x45, 0x55, 0x65, 0x59, 0x45, 0x3d, 0x46, 0x53, 0x51, + 0x44, 0x3f, 0x3e, 0x42, 0x4f, 0x50, 0x4d, 0x4c, 0x44, 0x45, 0x4e, 0x44, 0x41, 0x50, 0x55, 0x6c, + 0x89, 0x86, 0x86, 0x90, 0x99, 0xb2, 0xbf, 0xb8, 0xb2, 0xb1, 0xab, 0xa5, 0xad, 0xbb, 0xc9, 0xd1, + 0xd3, 0xd4, 0xc9, 0xb5, 0xa6, 0x9d, 0x9f, 0x91, 0x80, 0x81, 0x84, 0x89, 0x92, 0x88, 0x7a, 0x7a, + 0x7e, 0x87, 0x80, 0x66, 0x59, 0x60, 0x7c, 0x8d, 0x7e, 0x6c, 0x66, 0x67, 0x6d, 0x80, 0x8a, 0x7e, + 0x7a, 0x7b, 0x88, 0x8c, 0x7e, 0x73, 0x74, 0x78, 0x73, 0x77, 0x68, 0x57, 0x62, 0x6e, 0x7c, 0x85, + 0x73, 0x60, 0x63, 0x69, 0x83, 0x8f, 0x80, 0x6f, 0x6c, 0x8b, 0xa3, 0xad, 0xa9, 0x99, 0x9b, 0xb0, + 0xa9, 0x93, 0x7b, 0x69, 0x6b, 0x78, 0x7e, 0x72, 0x64, 0x58, 0x49, 0x4c, 0x4c, 0x3b, 0x38, 0x3c, + 0x34, 0x3f, 0x4b, 0x45, 0x48, 0x52, 0x68, 0x85, 0x79, 0x6e, 0x7c, 0x81, 0x94, 0x9d, 0x98, 0xa0, + 0x95, 0x8f, 0x8d, 0x81, 0x70, 0x63, 0x53, 0x54, 0x5f, 0x68, 0x77, 0x86, 0x88, 0x8e, 0x80, 0x70, + 0x68, 0x62, 0x6a, 0x6d, 0x72, 0x67, 0x61, 0x82, 0x96, 0xa6, 0xad, 0x99, 0x87, 0x84, 0x92, 0xa0, + 0x9c, 0x9a, 0xa7, 0xb3, 0xc6, 0xc3, 0xa7, 0xa7, 0xa5, 0x97, 0x9a, 0xa1, 0x8e, 0x7e, 0x87, 0xa1, + 0xb9, 0xba, 0xa8, 0x94, 0x85, 0x7d, 0x83, 0x82, 0x81, 0x84, 0x94, 0xa6, 0x9c, 0x82, 0x61, 0x59, + 0x69, 0x7d, 0x82, 0x72, 0x58, 0x5d, 0x66, 0x76, 0x8b, 0x7b, 0x6a, 0x5a, 0x53, 0x5e, 0x5a, 0x4d, + 0x52, 0x5f, 0x71, 0x83, 0x83, 0x77, 0x6c, 0x72, 0x7a, 0x70, 0x67, 0x66, 0x62, 0x5d, 0x64, 0x6e, + 0x6f, 0x67, 0x58, 0x5c, 0x64, 0x57, 0x49, 0x51, 0x67, 0x82, 0x88, 0x81, 0x7b, 0x6a, 0x6a, 0x6d, + 0x77, 0x74, 0x63, 0x72, 0x80, 0x88, 0x7d, 0x6c, 0x7a, 0x8f, 0x97, 0x9e, 0x93, 0x79, 0x6f, 0x72, + 0x81, 0x79, 0x6c, 0x6f, 0x87, 0x90, 0x8d, 0x8b, 0x84, 0x74, 0x6e, 0x79, 0x68, 0x58, 0x61, 0x68, + 0x7b, 0x97, 0xab, 0xaa, 0x9d, 0xa2, 0xa4, 0x9e, 0xa0, 0x96, 0x8a, 0xa2, 0xb6, 0xbb, 0xad, 0x98, + 0x94, 0x9e, 0xa8, 0xaa, 0x95, 0x8d, 0x82, 0x87, 0x99, 0x97, 0x85, 0x80, 0x9c, 0xb6, 0xb2, 0x9b, + 0x8e, 0x9a, 0xaf, 0xb2, 0xc6, 0xc6, 0xa2, 0x85, 0x8e, 0x9e, 0xa4, 0x9c, 0x7e, 0x7a, 0x88, 0x94, + 0xa2, 0xa4, 0xa5, 0xb3, 0xa4, 0xa2, 0x9d, 0x76, 0x73, 0x75, 0x77, 0x71, 0x6a, 0x62, 0x58, 0x66, + 0x8f, 0x90, 0x94, 0x85, 0x75, 0x81, 0x84, 0x8c, 0x83, 0x8b, 0x98, 0x9a, 0x92, 0x83, 0x73, 0x70, + 0x86, 0x90, 0x8f, 0x7e, 0x77, 0x75, 0x6c, 0x75, 0x73, 0x64, 0x58, 0x59, 0x5f, 0x58, 0x54, 0x53, + 0x5b, 0x61, 0x61, 0x5a, 0x45, 0x37, 0x16, 0x13, 0x3b, 0x4d, 0x49, 0x42, 0x43, 0x59, 0x76, 0x78, + 0x63, 0x57, 0x50, 0x57, 0x61, 0x61, 0x69, 0x86, 0x9f, 0xa5, 0xab, 0xa4, 0x94, 0x7d, 0x7b, 0x97, + 0xa2, 0x81, 0x6d, 0x59, 0x57, 0x5d, 0x5b, 0x54, 0x44, 0x38, 0x5d, 0x76, 0x76, 0x73, 0x7a, 0x87, + 0x93, 0x8b, 0x92, 0x95, 0x7b, 0x69, 0x7e, 0x70, 0x67, 0x66, 0x74, 0x76, 0x76, 0x84, 0x7c, 0x7b, + 0x89, 0x78, 0x7a, 0x86, 0x76, 0x83, 0x9d, 0xb1, 0xb0, 0x98, 0x7b, 0x82, 0x9e, 0xad, 0xa3, 0x83, + 0x66, 0x65, 0x6f, 0x64, 0x62, 0x63, 0x6b, 0x6b, 0x82, 0x88, 0x79, 0x7d, 0x76, 0x81, 0x94, 0x95, + 0x7e, 0x72, 0x69, 0x84, 0xa5, 0x95, 0x6c, 0x65, 0x6f, 0x73, 0x71, 0x7c, 0x7d, 0x7c, 0x80, 0x91, + 0xae, 0x9b, 0x8b, 0x9d, 0xb5, 0xd9, 0xd1, 0xb7, 0xa9, 0x9a, 0x97, 0x99, 0xb1, 0xbd, 0xab, 0x9f, + 0x87, 0x7b, 0x66, 0x4f, 0x45, 0x57, 0x6f, 0x75, 0x89, 0x87, 0x97, 0xb0, 0xb0, 0xa9, 0x9c, 0x92, + 0x9e, 0xa2, 0xa3, 0xa2, 0xac, 0xbb, 0xaa, 0xab, 0xab, 0xa3, 0xad, 0xa2, 0xa8, 0xbe, 0xc1, 0xa6, + 0x9b, 0xad, 0xb0, 0xb0, 0x9b, 0x7e, 0x84, 0x82, 0x91, 0x8c, 0x91, 0x97, 0x86, 0x77, 0x68, 0x5c, + 0x59, 0x46, 0x38, 0x51, 0x5a, 0x64, 0x56, 0x57, 0x69, 0x76, 0x70, 0x60, 0x3f, 0x49, 0x68, 0x7d, + 0xa1, 0x88, 0x7b, 0x7e, 0x73, 0x89, 0x84, 0x69, 0x6f, 0x68, 0x83, 0x8b, 0x6f, 0x66, 0x73, 0x88, + 0x88, 0x87, 0x6c, 0x54, 0x53, 0x59, 0x73, 0x74, 0x69, 0x75, 0x75, 0x6c, 0x75, 0x69, 0x4f, 0x2a, + 0x2a, 0x3f, 0x4f, 0x64, 0x62, 0x4b, 0x6b, 0x9c, 0xa1, 0x6e, 0x59, 0x4e, 0x50, 0x53, 0x6b, 0x85, + 0x80, 0x7a, 0x79, 0x86, 0x8c, 0x87, 0x69, 0x64, 0x85, 0x80, 0x67, 0x4d, 0x4e, 0x63, 0x6d, 0x71, + 0x69, 0x3c, 0x36, 0x4f, 0x71, 0x8f, 0x86, 0x95, 0x92, 0x81, 0x9b, 0xa7, 0x8a, 0x71, 0x82, 0x97, + 0x96, 0xac, 0x93, 0x99, 0xa6, 0xb0, 0xa7, 0x85, 0x82, 0x8a, 0x80, 0x88, 0x95, 0x94, 0x97, 0x99, + 0xa0, 0xa6, 0x96, 0x8e, 0x8f, 0xa2, 0xbf, 0xb6, 0x97, 0x8e, 0x7c, 0x90, 0xaf, 0xbe, 0xba, 0xa5, + 0xa9, 0xbb, 0xab, 0x9c, 0x86, 0x84, 0x9e, 0xa5, 0xa7, 0x95, 0x83, 0x8a, 0x96, 0x90, 0x96, 0x98, + 0x71, 0x69, 0x89, 0x8b, 0x69, 0x44, 0x42, 0x41, 0x3e, 0x54, 0x57, 0x44, 0x3c, 0x52, 0x6a, 0x83, + 0x7a, 0x70, 0x7d, 0x8e, 0xaa, 0xb1, 0x8c, 0x87, 0x97, 0x92, 0xad, 0xa5, 0x88, 0x60, 0x6d, 0x82, + 0x7c, 0x8f, 0x74, 0x6d, 0x82, 0x83, 0x73, 0x62, 0x3d, 0x47, 0x52, 0x5f, 0x76, 0x77, 0x62, 0x56, + 0x60, 0x7d, 0x8b, 0x6f, 0x66, 0x5a, 0x77, 0x8d, 0x6c, 0x65, 0x7b, 0x7a, 0x84, 0x85, 0x78, 0x8d, + 0x98, 0xb1, 0xc4, 0xb8, 0x9d, 0x94, 0x9a, 0xa7, 0xb3, 0x98, 0x78, 0x74, 0x73, 0x6e, 0x68, 0x68, + 0x63, 0x4f, 0x56, 0x5b, 0x5f, 0x63, 0x5d, 0x58, 0x7e, 0x9a, 0x8a, 0x77, 0x6a, 0x6c, 0x6a, 0x72, + 0x6c, 0x6a, 0x6d, 0x74, 0x8d, 0x8e, 0x6e, 0x8f, 0x90, 0x80, 0xa3, 0xa3, 0x8b, 0x89, 0x9d, 0x9f, + 0xa7, 0x9b, 0x92, 0x93, 0x95, 0x9f, 0xa5, 0x9e, 0x71, 0x6d, 0x6c, 0x70, 0x78, 0x8e, 0x8b, 0x8a, + 0x97, 0x7d, 0x6c, 0x68, 0x70, 0x82, 0x93, 0x96, 0x92, 0x88, 0x8f, 0x87, 0x7b, 0x91, 0x8d, 0x92, + 0xa8, 0xaf, 0xc5, 0xb3, 0x94, 0x8d, 0x80, 0x68, 0x5f, 0x54, 0x46, 0x4e, 0x67, 0x86, 0x94, 0xa7, + 0x99, 0x99, 0xba, 0xbb, 0xbc, 0xa8, 0x7b, 0x77, 0x9d, 0x97, 0x94, 0xa0, 0x82, 0x55, 0x5c, 0x61, + 0x51, 0x60, 0x61, 0x65, 0x83, 0x86, 0x75, 0x79, 0x72, 0x6b, 0x99, 0xa1, 0x7a, 0x83, 0x8f, 0x7c, + 0x98, 0xa2, 0x98, 0x9a, 0x95, 0x82, 0x94, 0x7a, 0x5d, 0x60, 0x84, 0x9d, 0xae, 0x9e, 0x83, 0x7c, + 0x91, 0xad, 0xa3, 0x90, 0x81, 0x7b, 0x8f, 0x83, 0x74, 0x84, 0x6b, 0x58, 0x5a, 0x48, 0x2f, 0x2b, + 0x38, 0x3b, 0x46, 0x45, 0x34, 0x22, 0x37, 0x3b, 0x4a, 0x52, 0x4b, 0x62, 0x8a, 0xa0, 0xa0, 0x9a, + 0x7d, 0x76, 0x84, 0x7b, 0x6b, 0x56, 0x46, 0x4d, 0x64, 0x63, 0x70, 0x88, 0x86, 0x82, 0x83, 0x84, + 0x87, 0x76, 0x61, 0x6c, 0x72, 0x62, 0x52, 0x5c, 0x5c, 0x5d, 0x74, 0x6e, 0x50, 0x55, 0x71, 0x83, + 0x86, 0x88, 0x83, 0x70, 0x71, 0x84, 0x86, 0x71, 0x77, 0x8a, 0x9a, 0xb0, 0xaf, 0xa2, 0x8e, 0x98, + 0x96, 0x8c, 0x7e, 0x67, 0x70, 0x8b, 0x9f, 0xb9, 0xaa, 0x98, 0xa1, 0x80, 0x81, 0x93, 0x7e, 0x6d, + 0x76, 0x97, 0xab, 0xa9, 0xa8, 0xad, 0x99, 0x92, 0x9d, 0x9e, 0x75, 0x64, 0x8d, 0xa2, 0x9a, 0xa0, + 0xab, 0x9e, 0x8a, 0x96, 0x9f, 0x96, 0x88, 0x8b, 0xb7, 0xd4, 0xc2, 0xc1, 0xb5, 0xa9, 0xae, 0x9e, + 0x84, 0x7c, 0x74, 0x87, 0xa2, 0x9f, 0x9c, 0x94, 0x95, 0x99, 0xab, 0xb0, 0xac, 0x93, 0x88, 0xa0, + 0x87, 0x85, 0x75, 0x67, 0x62, 0x6a, 0x7c, 0x92, 0x7d, 0x60, 0x6a, 0x76, 0x7b, 0x7a, 0x6c, 0x6a, + 0x6b, 0x6d, 0x5e, 0x4b, 0x57, 0x65, 0x76, 0x90, 0x9e, 0x8d, 0x88, 0x75, 0x84, 0x85, 0x4d, 0x34, + 0x46, 0x7a, 0x8b, 0x85, 0x79, 0x89, 0x8b, 0x77, 0xa7, 0x9a, 0x90, 0x84, 0x81, 0x93, 0x90, 0x8b, + 0x6f, 0x74, 0x72, 0x65, 0x6f, 0x5d, 0x3b, 0x32, 0x2c, 0x44, 0x68, 0x44, 0x29, 0x2f, 0x21, 0x39, + 0x51, 0x3d, 0x41, 0x64, 0x8b, 0xa2, 0x9c, 0x8a, 0x84, 0x7a, 0x8e, 0x94, 0x77, 0x53, 0x6c, 0x97, + 0xa3, 0xa4, 0xae, 0x97, 0x87, 0x90, 0x94, 0x82, 0x61, 0x5e, 0x6c, 0x6e, 0x4c, 0x49, 0x55, 0x4e, + 0x52, 0x6e, 0x81, 0x6e, 0x69, 0x6b, 0x76, 0x8b, 0x8e, 0x7a, 0x76, 0x6b, 0x67, 0x6e, 0x71, 0x6e, + 0x5d, 0x7b, 0xa3, 0xa2, 0x9a, 0x98, 0x9a, 0x86, 0x7a, 0x7a, 0x5a, 0x58, 0x70, 0x7b, 0x94, 0x90, + 0x8d, 0x89, 0x8f, 0x8c, 0x75, 0x57, 0x4a, 0x5e, 0x71, 0x8a, 0x8f, 0x91, 0x96, 0x90, 0x90, 0x8c, + 0x94, 0x72, 0x55, 0x62, 0x68, 0x70, 0x6f, 0x73, 0x86, 0x8e, 0x99, 0xa4, 0xa4, 0xa2, 0xb1, 0xcd, + 0xdf, 0xe2, 0xd6, 0xc4, 0xab, 0xa5, 0xa3, 0x95, 0x77, 0x8c, 0x87, 0x9b, 0xc4, 0xb0, 0xb1, 0xcb, + 0xcd, 0xb5, 0x8e, 0x87, 0x82, 0x7a, 0x7e, 0x81, 0x8c, 0x93, 0x8d, 0x81, 0xac, 0xd6, 0xb7, 0x93, + 0x82, 0x81, 0x87, 0x6c, 0x58, 0x6c, 0x7a, 0x7e, 0x8b, 0x90, 0x7d, 0x71, 0x74, 0x81, 0x8d, 0x8e, + 0x73, 0x74, 0x87, 0x84, 0x82, 0x7e, 0x68, 0x63, 0x78, 0x97, 0x98, 0x6e, 0x5a, 0x81, 0x91, 0x75, + 0x74, 0x7a, 0x65, 0x48, 0x4d, 0x69, 0x7d, 0x7b, 0x6e, 0x5f, 0x6e, 0x75, 0x57, 0x3e, 0x3a, 0x3c, + 0x3b, 0x46, 0x4d, 0x55, 0x58, 0x55, 0x5c, 0x53, 0x4b, 0x55, 0x71, 0x86, 0x8e, 0x98, 0x80, 0x73, + 0x6c, 0x66, 0x55, 0x60, 0x6f, 0x77, 0xa1, 0xc9, 0xbb, 0xb1, 0xad, 0xb2, 0x8f, 0x6c, 0x58, 0x54, + 0x52, 0x54, 0x46, 0x3e, 0x4c, 0x49, 0x5e, 0x74, 0x8f, 0x9e, 0x91, 0x8b, 0x8e, 0x92, 0x9f, 0x9a, + 0x71, 0x5f, 0x68, 0x6c, 0x7b, 0x6a, 0x5f, 0x7d, 0x9f, 0xb2, 0xb6, 0x9e, 0x83, 0x98, 0x9d, 0x97, + 0x8a, 0x7a, 0x6f, 0x6f, 0x8c, 0xb2, 0xa3, 0x8b, 0x8b, 0x8e, 0x91, 0x91, 0x7a, 0x62, 0x56, 0x61, + 0x72, 0x88, 0x82, 0x7a, 0x86, 0x9c, 0xa6, 0x97, 0x74, 0x60, 0x5d, 0x60, 0x6a, 0x79, 0x64, 0x4c, + 0x70, 0xa8, 0xbf, 0xac, 0xaa, 0xba, 0xd1, 0xf2, 0xd3, 0xa7, 0xa3, 0x86, 0x66, 0x6f, 0x79, 0x70, + 0x61, 0x6b, 0x88, 0x9c, 0x88, 0x8a, 0xa2, 0x97, 0x9d, 0x82, 0x60, 0x5f, 0x5c, 0x68, 0x7d, 0x9b, + 0x9e, 0x8d, 0xaf, 0xc8, 0xc1, 0xb8, 0x81, 0x78, 0x81, 0x75, 0x74, 0x6d, 0x66, 0x75, 0x7b, 0x81, + 0x7d, 0x75, 0x5d, 0x7d, 0xaf, 0xb6, 0xa6, 0x95, 0x8c, 0x71, 0x6f, 0x5a, 0x43, 0x41, 0x39, 0x58, + 0x7b, 0x8b, 0xae, 0xb9, 0xba, 0xc6, 0xbc, 0x84, 0x6c, 0x78, 0x87, 0x91, 0x88, 0x8e, 0x7b, 0x61, + 0x69, 0x79, 0x69, 0x3a, 0x1e, 0x2d, 0x31, 0x3d, 0x4d, 0x37, 0x40, 0x49, 0x3a, 0x4d, 0x5f, 0x57, + 0x69, 0x90, 0x8b, 0x83, 0x7c, 0x73, 0x6e, 0x4e, 0x5c, 0x6c, 0x55, 0x6a, 0x92, 0x9a, 0x9e, 0xae, + 0xb9, 0xb2, 0xb2, 0xa0, 0x81, 0x65, 0x5a, 0x59, 0x3e, 0x26, 0x46, 0x5c, 0x52, 0x7b, 0xa4, 0xb4, + 0xba, 0xa7, 0x9e, 0x9b, 0x79, 0x83, 0x8e, 0x7c, 0x76, 0x59, 0x69, 0x73, 0x6e, 0x8f, 0x98, 0x8e, + 0x88, 0x8b, 0x9c, 0x8e, 0x9c, 0xa4, 0x84, 0x7c, 0x66, 0x6d, 0x67, 0x5c, 0x74, 0x7d, 0x9c, 0xbc, + 0xc5, 0xb2, 0x8c, 0x78, 0x77, 0x7a, 0x82, 0x84, 0x84, 0x93, 0x96, 0x99, 0x9d, 0x94, 0x85, 0x71, + 0x59, 0x69, 0x72, 0x5f, 0x73, 0x74, 0x70, 0x6b, 0x78, 0x7a, 0x7c, 0xaf, 0xdc, 0xe4, 0xea, 0xf4, + 0xfe, 0xc0, 0xa9, 0xa7, 0x83, 0x6d, 0x6c, 0x86, 0x96, 0x96, 0xa3, 0xa4, 0xb0, 0xb2, 0xa1, 0x86, + 0x6a, 0x4a, 0x3d, 0x3c, 0x45, 0x4e, 0x5c, 0x74, 0x93, 0x98, 0x99, 0xa9, 0x96, 0x7a, 0x90, 0x9c, + 0x80, 0x6f, 0x67, 0x64, 0x75, 0x77, 0x78, 0x74, 0x70, 0x92, 0xac, 0x97, 0x7e, 0x6f, 0x88, 0x86, + 0x85, 0x78, 0x6e, 0x5a, 0x4d, 0x48, 0x53, 0x6f, 0x7e, 0x95, 0xbe, 0xd1, 0xdb, 0xdb, 0xa4, 0x81, + 0x6f, 0x5e, 0x6a, 0x71, 0x57, 0x60, 0x7b, 0x78, 0x79, 0x7c, 0x48, 0x33, 0x27, 0x25, 0x28, 0x2e, + 0x3b, 0x43, 0x47, 0x3f, 0x48, 0x51, 0x48, 0x49, 0x50, 0x4a, 0x3b, 0x5a, 0x65, 0x60, 0x5f, 0x59, + 0x64, 0x76, 0x7a, 0x77, 0x93, 0x98, 0x9f, 0xb0, 0xd6, 0xdb, 0xb4, 0x8e, 0x66, 0x58, 0x5a, 0x5c, + 0x55, 0x54, 0x52, 0x56, 0x6a, 0x82, 0x8e, 0x87, 0x7a, 0x8f, 0x91, 0x7d, 0x89, 0x9a, 0x9c, 0x8a, + 0x94, 0x91, 0x9a, 0xa2, 0x9e, 0xb3, 0xc8, 0xce, 0x98, 0x72, 0x9a, 0x9f, 0x84, 0x78, 0x72, 0x69, + 0x5c, 0x63, 0x87, 0x96, 0x99, 0xa9, 0xbb, 0xaf, 0xb9, 0xaf, 0x7e, 0x84, 0x7a, 0x6e, 0x87, 0x80, + 0x7d, 0x74, 0x80, 0x76, 0x66, 0x69, 0x4d, 0x49, 0x42, 0x51, 0x7a, 0x92, 0x9c, 0x91, 0x8e, 0x8d, + 0x71, 0x71, 0xaa, 0xbc, 0xb3, 0xbb, 0xbd, 0xd2, 0xdc, 0xbe, 0x9c, 0x9b, 0x93, 0x8c, 0x84, 0x76, + 0x90, 0xa6, 0xaa, 0xc1, 0xc6, 0x9d, 0xa2, 0x8c, 0x64, 0x6c, 0x55, 0x57, 0x6a, 0x67, 0x7a, 0x92, + 0x9c, 0x84, 0x67, 0x66, 0x68, 0x5c, 0x6e, 0x5d, 0x6d, 0x89, 0x76, 0x82, 0x8a, 0x7b, 0x79, 0x8a, + 0x90, 0x95, 0x87, 0x7a, 0x79, 0x7c, 0x81, 0x6b, 0x66, 0x68, 0x63, 0x57, 0x45, 0x48, 0x52, 0x63, + 0x87, 0x9f, 0xc2, 0xd1, 0xc7, 0xc8, 0xb2, 0x9d, 0x8e, 0x80, 0x80, 0x95, 0xa2, 0x91, 0x7c, 0x80, + 0x83, 0x75, 0x47, 0x28, 0x31, 0x3b, 0x4f, 0x4d, 0x45, 0x46, 0x41, 0x3d, 0x42, 0x6c, 0x73, 0x5b, + 0x4f, 0x3b, 0x42, 0x4f, 0x65, 0x76, 0x7b, 0x75, 0x84, 0x78, 0x83, 0x7e, 0x79, 0x9b, 0xbc, 0xcf, + 0xcc, 0xa6, 0x89, 0x7b, 0x5c, 0x5c, 0x4d, 0x3b, 0x3f, 0x3e, 0x3e, 0x3d, 0x4a, 0x6d, 0x67, 0x5c, + 0x58, 0x52, 0x76, 0x7b, 0x70, 0x6e, 0x6d, 0x74, 0x79, 0x79, 0x91, 0xae, 0xb7, 0xa0, 0x8e, 0x81, + 0x71, 0x63, 0x6d, 0x85, 0x94, 0xa2, 0x95, 0x72, 0x85, 0x9a, 0xa6, 0x9f, 0xa2, 0xaf, 0xb6, 0xa0, + 0x6c, 0x8b, 0x89, 0x75, 0x6d, 0x6b, 0x91, 0x96, 0x7d, 0x7c, 0x8f, 0xac, 0xa8, 0x85, 0x81, 0x7e, + 0x8a, 0xa5, 0x9b, 0x9c, 0x8c, 0x51, 0x60, 0x94, 0x8b, 0x99, 0x8f, 0x82, 0x97, 0x9d, 0xcb, 0xd7, + 0xd2, 0xc8, 0xae, 0xb1, 0xb2, 0xba, 0xc6, 0xb3, 0xaa, 0xab, 0xc2, 0xd5, 0xbf, 0x9b, 0x7a, 0x75, + 0x73, 0x61, 0x63, 0x6f, 0x73, 0x82, 0x90, 0x95, 0x8a, 0x82, 0x77, 0x6d, 0x60, 0x61, 0x69, 0x6b, + 0x69, 0x7e, 0x8c, 0x89, 0x86, 0x77, 0x7a, 0x7b, 0x88, 0x7c, 0x78, 0x6b, 0x4c, 0x55, 0x5b, 0x6b, + 0x7d, 0x68, 0x56, 0x51, 0x51, 0x5c, 0x6b, 0x83, 0x98, 0xaf, 0xc0, 0xa7, 0x93, 0x88, 0x7d, 0x8d, + 0x87, 0x79, 0x7d, 0x70, 0x5d, 0x74, 0x85, 0x72, 0x82, 0x65, 0x41, 0x36, 0x44, 0x67, 0x66, 0x62, + 0x59, 0x52, 0x45, 0x4b, 0x5d, 0x52, 0x48, 0x38, 0x32, 0x2a, 0x2a, 0x3c, 0x52, 0x5d, 0x64, 0x7e, + 0x89, 0x7e, 0x83, 0x92, 0xac, 0xbc, 0xda, 0xe1, 0xc4, 0xa0, 0x98, 0x95, 0x91, 0x6e, 0x4c, 0x4b, + 0x40, 0x4c, 0x62, 0x5e, 0x68, 0x56, 0x51, 0x5a, 0x63, 0x77, 0x80, 0x83, 0x8f, 0x93, 0x9f, 0xa2, + 0xa2, 0xb7, 0xbf, 0xc7, 0xc3, 0x9c, 0x97, 0x81, 0x6c, 0x85, 0x8e, 0x94, 0x8e, 0x82, 0x73, 0x56, + 0x68, 0x7a, 0x72, 0x8f, 0x99, 0x96, 0xa8, 0x93, 0x8b, 0x8c, 0x7d, 0x71, 0x7a, 0x7a, 0x78, 0x76, + 0x8c, 0x8b, 0x78, 0x7e, 0x85, 0x9d, 0x94, 0x7b, 0x84, 0x7b, 0x60, 0x6a, 0x75, 0x6f, 0x78, 0x85, + 0x7c, 0x87, 0x8f, 0x90, 0x9b, 0x99, 0x87, 0x8b, 0xa4, 0xa5, 0xa8, 0xc3, 0xc1, 0x98, 0x8c, 0x87, + 0x97, 0xb0, 0xaf, 0xba, 0xae, 0x95, 0x93, 0xb0, 0xb0, 0x9d, 0x92, 0x80, 0x86, 0x8b, 0x76, 0x61, + 0x63, 0x5d, 0x61, 0x75, 0x79, 0x76, 0x6f, 0x76, 0x78, 0x6c, 0x79, 0x82, 0x8b, 0x88, 0x8a, 0x93, + 0xaa, 0xa3, 0x89, 0x78, 0x5a, 0x59, 0x79, 0x75, 0x63, 0x5c, 0x5b, 0x48, 0x4e, 0x7c, 0x9f, 0x95, + 0x8c, 0x8f, 0x7b, 0x69, 0x81, 0x8b, 0x8c, 0x80, 0x86, 0x91, 0x91, 0x99, 0x91, 0x81, 0x6d, 0x5f, + 0x5e, 0x58, 0x5b, 0x4b, 0x50, 0x65, 0x5f, 0x49, 0x31, 0x40, 0x50, 0x5f, 0x58, 0x4f, 0x5e, 0x66, + 0x71, 0x81, 0x6d, 0x6f, 0x90, 0x96, 0x7a, 0x74, 0x79, 0x7d, 0x77, 0x85, 0x9b, 0x98, 0xb0, 0xb4, + 0x97, 0xa1, 0x9e, 0x76, 0x5f, 0x51, 0x53, 0x45, 0x52, 0x68, 0x57, 0x3f, 0x4c, 0x55, 0x65, 0x6e, + 0x6e, 0x5f, 0x68, 0x83, 0x89, 0x9f, 0xa5, 0x9a, 0xa1, 0x94, 0x88, 0x84, 0x85, 0x94, 0x97, 0x71, + 0x66, 0x78, 0x8e, 0x91, 0x88, 0x7b, 0x76, 0x6f, 0x79, 0x8e, 0x91, 0xa0, 0xa9, 0xa4, 0xa7, 0x8d, + 0x76, 0x6c, 0x77, 0x68, 0x56, 0x68, 0x7e, 0x8a, 0x88, 0x8d, 0xa9, 0xa7, 0xa5, 0xb0, 0xb8, 0xa7, + 0x9e, 0x99, 0x93, 0x93, 0x77, 0x70, 0x85, 0x9f, 0xa3, 0x97, 0x99, 0xab, 0x97, 0x80, 0x7b, 0x8d, + 0xa6, 0xb3, 0x9b, 0x8f, 0x9c, 0xa6, 0x9a, 0x98, 0xa4, 0xa9, 0xac, 0xaa, 0xb3, 0xac, 0xa8, 0xa1, + 0x94, 0x79, 0x61, 0x59, 0x5c, 0x4f, 0x52, 0x5f, 0x5a, 0x66, 0x72, 0x6f, 0x7c, 0x86, 0x97, 0xa3, + 0x94, 0x80, 0x8d, 0x93, 0xa6, 0xa2, 0x83, 0x75, 0x76, 0x6b, 0x68, 0x63, 0x55, 0x44, 0x50, 0x65, + 0x6c, 0x6c, 0x6d, 0x71, 0x62, 0x59, 0x71, 0x86, 0x77, 0x72, 0x69, 0x56, 0x5e, 0x52, 0x5a, 0x5f, + 0x56, 0x71, 0x78, 0x6d, 0x6d, 0x44, 0x50, 0x63, 0x68, 0x65, 0x5c, 0x71, 0x6a, 0x57, 0x4f, 0x51, + 0x55, 0x42, 0x48, 0x4f, 0x63, 0x75, 0x89, 0x95, 0x81, 0x72, 0x6c, 0x52, 0x5f, 0x7b, 0x70, 0x73, + 0x88, 0x93, 0xab, 0xc0, 0xc3, 0xcf, 0xdc, 0xdf, 0xc8, 0x88, 0x81, 0x9b, 0x90, 0x8b, 0x84, 0x74, + 0x5b, 0x46, 0x36, 0x34, 0x54, 0x57, 0x42, 0x50, 0x6c, 0x87, 0x9e, 0xa3, 0xa6, 0x97, 0x9f, 0xc1, + 0xce, 0xbb, 0xb5, 0xa8, 0x8f, 0xa1, 0xb1, 0x99, 0x8c, 0x81, 0x90, 0x93, 0x87, 0x91, 0x86, 0x81, + 0x7e, 0x72, 0x78, 0x96, 0x94, 0x8e, 0x93, 0x7a, 0x74, 0x83, 0x87, 0x8b, 0x80, 0x77, 0x92, 0xa1, + 0x91, 0x78, 0x62, 0x77, 0x82, 0x7d, 0x7e, 0x7c, 0x7c, 0x7e, 0x77, 0x5e, 0x79, 0x88, 0x83, 0x85, + 0x8b, 0x8b, 0x81, 0x76, 0x79, 0x90, 0x94, 0x90, 0x95, 0x88, 0x86, 0x78, 0x69, 0x7e, 0x8a, 0x90, + 0x94, 0xa3, 0xb7, 0xb5, 0xac, 0xb3, 0xa8, 0x9a, 0x9d, 0x9c, 0x86, 0x78, 0x65, 0x61, 0x68, 0x5c, + 0x4f, 0x60, 0x76, 0x72, 0x60, 0x54, 0x6e, 0x6e, 0x6b, 0x7d, 0x89, 0x84, 0x83, 0x9c, 0xa3, 0x91, + 0xa2, 0xa3, 0x97, 0x93, 0x95, 0x74, 0x80, 0x97, 0x95, 0x78, 0x66, 0x65, 0x5a, 0x54, 0x6a, 0x73, + 0x72, 0x67, 0x66, 0x76, 0x78, 0x7e, 0x96, 0x7c, 0x6c, 0x75, 0x6f, 0x75, 0x76, 0x6f, 0x6c, 0x6d, + 0x7c, 0x78, 0x67, 0x5c, 0x5a, 0x3d, 0x41, 0x5b, 0x54, 0x54, 0x62, 0x71, 0x6e, 0x6d, 0x65, 0x72, + 0x6d, 0x5b, 0x67, 0x55, 0x63, 0x74, 0x67, 0x70, 0x6c, 0x6e, 0x7b, 0x9c, 0x99, 0x96, 0x82, 0x86, + 0x9b, 0x81, 0x73, 0x7a, 0x7b, 0x65, 0x59, 0x49, 0x4f, 0x5e, 0x57, 0x59, 0x56, 0x6c, 0x75, 0x6c, + 0x7c, 0x89, 0x7b, 0x60, 0x6d, 0x82, 0x86, 0x94, 0x98, 0x93, 0x9f, 0x9d, 0x99, 0xa4, 0xaf, 0xae, + 0xa0, 0x99, 0xa3, 0xa5, 0x9c, 0x9c, 0x9c, 0x8a, 0x79, 0x9b, 0x9c, 0x89, 0x93, 0xa1, 0x7b, 0x76, + 0x8f, 0x9f, 0x9e, 0x9e, 0x94, 0x78, 0x8f, 0xa4, 0xa5, 0x96, 0x9d, 0xb0, 0xae, 0xad, 0xac, 0x8e, + 0x78, 0x8d, 0x8f, 0x94, 0x92, 0x8f, 0x94, 0x8e, 0x8e, 0xa4, 0xa6, 0x86, 0x8d, 0x9d, 0x92, 0x87, + 0x73, 0x70, 0x82, 0x85, 0x89, 0x99, 0x9b, 0xa1, 0x9d, 0x97, 0xaa, 0x9f, 0x84, 0x88, 0x84, 0x84, + 0x8a, 0x7e, 0x6b, 0x69, 0x5c, 0x5f, 0x74, 0x65, 0x5c, 0x5f, 0x66, 0x91, 0x7e, 0x66, 0x6b, 0x73, + 0x74, 0x5c, 0x5c, 0x82, 0x7a, 0x63, 0x6a, 0x65, 0x6b, 0x72, 0x63, 0x6e, 0x7c, 0x70, 0x5e, 0x6a, + 0x76, 0x70, 0x67, 0x76, 0x7a, 0x72, 0x71, 0x6a, 0x5e, 0x5a, 0x69, 0x81, 0x6c, 0x57, 0x67, 0x62, + 0x62, 0x52, 0x64, 0x7a, 0x71, 0x75, 0x71, 0x68, 0x6c, 0x72, 0x56, 0x55, 0x74, 0x7d, 0x72, 0x78, + 0x76, 0x80, 0x72, 0x62, 0x67, 0x5a, 0x56, 0x6a, 0x6b, 0x76, 0x7b, 0x65, 0x6e, 0x84, 0x8d, 0x8c, + 0x8d, 0x9d, 0x9b, 0x8e, 0xbc, 0xce, 0xbc, 0xb1, 0xac, 0x9c, 0x8a, 0x7d, 0x79, 0x7e, 0x75, 0x76, + 0x78, 0x6f, 0x6c, 0x72, 0x77, 0x81, 0x88, 0x80, 0x76, 0x72, 0x68, 0x62, 0x8a, 0x96, 0x98, 0xb1, + 0x9a, 0x8a, 0x8d, 0x95, 0xa2, 0x8e, 0x8d, 0x8e, 0x7d, 0x79, 0x76, 0x91, 0x91, 0x77, 0x8f, 0x98, + 0x7b, 0x64, 0x66, 0x74, 0x79, 0x8b, 0x8b, 0x9d, 0xa2, 0x97, 0x8a, 0x83, 0x7b, 0x6c, 0x70, 0x7a, + 0x7b, 0x85, 0x81, 0x8c, 0x93, 0x88, 0x85, 0x80, 0x83, 0x8a, 0x86, 0x8e, 0x8e, 0xa7, 0xae, 0x7e, + 0x86, 0x88, 0x78, 0x72, 0x6a, 0x6f, 0x72, 0x6d, 0x6e, 0x7c, 0x8f, 0x7b, 0x85, 0x8c, 0x81, 0x8e, + 0x93, 0xa0, 0xb3, 0xa7, 0x98, 0xb6, 0xa6, 0x9a, 0x96, 0x78, 0x6e, 0x6d, 0x70, 0x78, 0x6c, 0x67, + 0x79, 0x89, 0x8a, 0x81, 0x6e, 0x65, 0x75, 0x86, 0x75, 0x73, 0x87, 0x8b, 0x78, 0x6b, 0x7c, 0x8a, + 0x8f, 0x97, 0x7d, 0x83, 0x6b, 0x55, 0x5b, 0x67, 0x74, 0x73, 0x81, 0x77, 0x87, 0x79, 0x7a, 0x8b, + 0x70, 0x75, 0x7c, 0x74, 0x72, 0x78, 0x80, 0x88, 0x69, 0x6f, 0x83, 0x6d, 0x61, 0x60, 0x4b, 0x4f, + 0x6d, 0x6a, 0x73, 0x6a, 0x5f, 0x73, 0x70, 0x72, 0x6a, 0x67, 0x57, 0x59, 0x5a, 0x5f, 0x7c, 0x8d, + 0x71, 0x6e, 0x6b, 0x66, 0x74, 0x76, 0x87, 0x7e, 0x77, 0xa0, 0x96, 0x79, 0x85, 0xa4, 0xa4, 0x92, + 0x9d, 0xa1, 0x84, 0x7e, 0x77, 0x78, 0x64, 0x64, 0x77, 0x7e, 0x80, 0x75, 0x5c, 0x62, 0x7a, 0x6c, + 0x55, 0x62, 0x67, 0x69, 0x6d, 0x84, 0x95, 0x8e, 0x80, 0x70, 0x5d, 0x7d, 0x9a, 0x9d, 0x91, 0x94, + 0xae, 0x8d, 0x80, 0xa0, 0xa4, 0x92, 0x90, 0x8c, 0x81, 0x8e, 0xa1, 0xa5, 0xa5, 0xa6, 0x9f, 0x9b, + 0x95, 0x9a, 0xa1, 0x82, 0x7d, 0x95, 0x95, 0xaf, 0xa6, 0x93, 0x89, 0x9e, 0xaa, 0xa1, 0x99, 0x97, + 0x8b, 0x96, 0xa9, 0xb0, 0xa2, 0x8c, 0x92, 0x87, 0x87, 0x8e, 0x95, 0x7e, 0x6a, 0x5f, 0x62, 0x6c, + 0x7d, 0x90, 0x90, 0x8c, 0x83, 0x75, 0x70, 0x87, 0x8f, 0x97, 0x91, 0x9a, 0xa7, 0x93, 0x8e, 0x9c, + 0x89, 0x7d, 0x6e, 0x63, 0x75, 0x7b, 0x89, 0x71, 0x66, 0x80, 0x62, 0x4e, 0x5f, 0x5b, 0x49, 0x4e, + 0x5c, 0x62, 0x5d, 0x62, 0x6f, 0x73, 0x5e, 0x5c, 0x69, 0x73, 0x6b, 0x51, 0x42, 0x43, 0x4d, 0x66, + 0x7b, 0x71, 0x5b, 0x5b, 0x6b, 0x78, 0x7d, 0x74, 0x64, 0x70, 0x7d, 0x88, 0x85, 0x82, 0x71, 0x68, + 0x6d, 0x5e, 0x6f, 0x77, 0x59, 0x4f, 0x64, 0x73, 0x73, 0x6a, 0x76, 0x88, 0x80, 0x78, 0x7a, 0x90, + 0xa8, 0x9c, 0x8c, 0x7c, 0x85, 0x97, 0xa3, 0x97, 0x92, 0x8d, 0x6c, 0x63, 0x75, 0x8e, 0x96, 0x8c, + 0x81, 0x8e, 0x9d, 0x9c, 0x7a, 0x8b, 0xa9, 0x97, 0x81, 0x8b, 0x83, 0x74, 0x68, 0x7c, 0x86, 0x8a, + 0x8c, 0x88, 0x9c, 0x94, 0x8d, 0x8f, 0x7d, 0x7e, 0x84, 0x89, 0x84, 0x8b, 0x89, 0x8e, 0xa3, 0xa2, + 0x92, 0x85, 0x7b, 0x87, 0x9b, 0x97, 0x7d, 0x6e, 0x72, 0x73, 0x6d, 0x87, 0x87, 0x79, 0x62, 0x67, + 0x6d, 0x74, 0x84, 0x74, 0x72, 0x6a, 0x6f, 0x80, 0x79, 0x88, 0x8c, 0x8b, 0x83, 0x86, 0x84, 0x9f, + 0xaa, 0x95, 0x8e, 0x8c, 0x91, 0x98, 0x94, 0x93, 0x9a, 0x8a, 0x99, 0x9c, 0x8f, 0x95, 0x7a, 0x6a, + 0x7a, 0x7b, 0x73, 0x6d, 0x65, 0x71, 0x7b, 0x76, 0x8a, 0x97, 0x87, 0x9a, 0xa0, 0x90, 0x96, 0x95, + 0x96, 0x92, 0x9a, 0x91, 0x94, 0x87, 0x7b, 0x8a, 0x89, 0x82, 0x6c, 0x6a, 0x7c, 0x7b, 0x77, 0x63, + 0x51, 0x7b, 0x85, 0x77, 0x80, 0x87, 0x87, 0x62, 0x66, 0x76, 0x7a, 0x84, 0x71, 0x68, 0x6f, 0x79, + 0x6c, 0x65, 0x72, 0x7e, 0x6e, 0x5f, 0x75, 0x8e, 0x94, 0x93, 0x91, 0x7d, 0x6e, 0x6b, 0x7d, 0x6e, + 0x6f, 0x69, 0x5f, 0x74, 0x7a, 0x70, 0x68, 0x70, 0x6c, 0x5d, 0x64, 0x68, 0x58, 0x53, 0x58, 0x69, + 0x76, 0x7d, 0x84, 0x86, 0x8b, 0x89, 0x8d, 0x8f, 0x7e, 0x74, 0x72, 0x74, 0x70, 0x6c, 0x5f, 0x65, + 0x71, 0x6e, 0x73, 0x6f, 0x6b, 0x7a, 0x89, 0x8f, 0x86, 0x74, 0x80, 0x85, 0x83, 0x91, 0x87, 0x6e, + 0x6c, 0x6f, 0x67, 0x65, 0x71, 0x66, 0x6c, 0x7c, 0x78, 0x7c, 0x69, 0x6c, 0x76, 0x6d, 0x7b, 0x86, + 0x95, 0xa4, 0xa3, 0x9d, 0x9e, 0x87, 0x93, 0xa0, 0x83, 0x7b, 0x80, 0x7b, 0x83, 0x8b, 0x8d, 0x8a, + 0x88, 0x8e, 0x8a, 0x88, 0x9c, 0x9b, 0x89, 0x8a, 0x92, 0xaa, 0xad, 0xa9, 0xa0, 0xa2, 0xa5, 0xaf, + 0xaa, 0x9a, 0xaa, 0xae, 0x90, 0x8b, 0x90, 0x99, 0x7e, 0x84, 0x95, 0x8f, 0x8d, 0x83, 0x9b, 0x97, + 0x94, 0x8c, 0x82, 0x93, 0x94, 0x8e, 0x84, 0x88, 0x71, 0x6b, 0x6b, 0x61, 0x5d, 0x67, 0x7b, 0x73, + 0x79, 0x82, 0x84, 0x8a, 0x8b, 0x8b, 0x91, 0x91, 0x92, 0xa2, 0x8f, 0x8e, 0x93, 0x86, 0x83, 0x6d, + 0x6f, 0x7c, 0x65, 0x56, 0x58, 0x69, 0x63, 0x4d, 0x5d, 0x68, 0x71, 0x6a, 0x65, 0x6e, 0x71, 0x6b, + 0x67, 0x70, 0x7b, 0x87, 0x76, 0x66, 0x67, 0x67, 0x6e, 0x6a, 0x67, 0x71, 0x87, 0x6f, 0x6c, 0x78, + 0x77, 0x7e, 0x75, 0x71, 0x6b, 0x68, 0x6e, 0x67, 0x61, 0x5f, 0x68, 0x5e, 0x66, 0x69, 0x6f, 0x78, + 0x70, 0x6b, 0x61, 0x5a, 0x60, 0x5b, 0x48, 0x6c, 0x85, 0x81, 0x8a, 0x8b, 0x90, 0x92, 0x8c, 0x8e, + 0x94, 0x8a, 0x95, 0x90, 0x8d, 0x9f, 0x8c, 0x90, 0xa0, 0x97, 0x91, 0x8c, 0x89, 0x88, 0x8b, 0x92, + 0x9d, 0xa4, 0xa4, 0x8c, 0x8a, 0x8f, 0x8e, 0x80, 0x75, 0x82, 0x84, 0x7b, 0x7b, 0x7e, 0x82, 0x7e, + 0x83, 0x78, 0x6e, 0x76, 0x6b, 0x6e, 0x79, 0x92, 0x9e, 0x9c, 0x96, 0x9f, 0xa6, 0x9e, 0x9f, 0x91, + 0x94, 0x92, 0x8d, 0x81, 0x76, 0x82, 0x8d, 0x86, 0x80, 0x83, 0x87, 0x7c, 0x6c, 0x75, 0x84, 0x7a, + 0x71, 0x70, 0x7b, 0x77, 0x75, 0x6e, 0x6c, 0x76, 0x70, 0x71, 0x75, 0x85, 0x8a, 0x77, 0x85, 0x83, + 0x6f, 0x73, 0x81, 0x87, 0x77, 0x82, 0x8e, 0x87, 0x8c, 0x8b, 0x8b, 0x8e, 0x86, 0x83, 0x7e, 0x7a, + 0x76, 0x60, 0x65, 0x80, 0x96, 0x87, 0x7e, 0x84, 0x80, 0x85, 0x8d, 0x8d, 0x95, 0x94, 0x8e, 0x81, + 0x89, 0x8d, 0x8b, 0x8b, 0x94, 0x9c, 0x8b, 0x8a, 0x95, 0x8a, 0x85, 0x92, 0x93, 0x83, 0x7d, 0x87, + 0x7b, 0x75, 0x7c, 0x86, 0x87, 0x74, 0x7b, 0x6f, 0x77, 0x81, 0x70, 0x76, 0x80, 0x78, 0x69, 0x59, + 0x60, 0x67, 0x71, 0x7a, 0x83, 0x86, 0x78, 0x7b, 0x79, 0x70, 0x76, 0x71, 0x6a, 0x5f, 0x5c, 0x58, + 0x54, 0x62, 0x5c, 0x5e, 0x7b, 0x79, 0x7d, 0x6c, 0x69, 0x7b, 0x74, 0x6c, 0x70, 0x7b, 0x76, 0x78, + 0x86, 0x94, 0x95, 0x7e, 0x78, 0x7e, 0x86, 0x78, 0x73, 0x7b, 0x81, 0x75, 0x6c, 0x61, 0x77, 0x7e, + 0x69, 0x7e, 0x86, 0x73, 0x71, 0x72, 0x7e, 0x8f, 0x9c, 0x88, 0x81, 0x84, 0x7b, 0x72, 0x78, 0x83, + 0x77, 0x7b, 0x74, 0x72, 0x7e, 0x78, 0x77, 0x79, 0x77, 0x82, 0x8b, 0x7c, 0x83, 0x92, 0x99, 0x93, + 0x9a, 0x96, 0x96, 0x91, 0x90, 0x8b, 0x85, 0x92, 0x8f, 0x77, 0x71, 0x74, 0x6c, 0x6e, 0x80, 0x8d, + 0x8f, 0x8e, 0x97, 0x91, 0x9a, 0xa1, 0xa4, 0x98, 0x9d, 0x97, 0x88, 0x8d, 0x84, 0x84, 0x8b, 0x8d, + 0xa4, 0xa4, 0x96, 0x94, 0x92, 0x89, 0x86, 0x92, 0x95, 0x92, 0x95, 0x97, 0x98, 0x9a, 0x9d, 0x95, + 0x91, 0x89, 0x8e, 0x8e, 0x87, 0x80, 0x7d, 0x73, 0x79, 0x79, 0x73, 0x70, 0x7d, 0x77, 0x75, 0x84, + 0x84, 0x83, 0x7e, 0x89, 0x9d, 0x94, 0x8b, 0x87, 0x7d, 0x7a, 0x87, 0x83, 0x7e, 0x77, 0x82, 0x70, + 0x6b, 0x6b, 0x67, 0x59, 0x60, 0x5b, 0x6a, 0x73, 0x62, 0x55, 0x5e, 0x6c, 0x6a, 0x5b, 0x5c, 0x6a, + 0x63, 0x5e, 0x5c, 0x5f, 0x5c, 0x59, 0x5a, 0x4e, 0x58, 0x5e, 0x70, 0x6f, 0x7e, 0x81, 0x6d, 0x77, + 0x80, 0x77, 0x77, 0x75, 0x68, 0x6a, 0x6b, 0x6a, 0x73, 0x65, 0x68, 0x70, 0x71, 0x73, 0x77, 0x66, + 0x64, 0x68, 0x70, 0x79, 0x80, 0x83, 0x8b, 0x91, 0x95, 0x9d, 0x99, 0x95, 0x97, 0xa4, 0xa9, 0xa4, + 0xa2, 0xa6, 0xa1, 0xa1, 0xa4, 0x96, 0x9c, 0x8b, 0x87, 0x9a, 0x95, 0x8d, 0x8a, 0x8b, 0x91, 0x91, + 0x94, 0x88, 0x7e, 0x7a, 0x72, 0x78, 0x80, 0x7a, 0x82, 0x8d, 0x88, 0x83, 0x86, 0x77, 0x7d, 0x77, + 0x6e, 0x84, 0x82, 0x8e, 0x8c, 0x83, 0x8e, 0x8a, 0x8c, 0x8a, 0x7b, 0x7c, 0x7e, 0x7d, 0x78, 0x71, + 0x7b, 0x70, 0x79, 0x71, 0x67, 0x68, 0x79, 0x7b, 0x65, 0x6a, 0x84, 0x7c, 0x75, 0x6a, 0x7b, 0x7a, + 0x6e, 0x7d, 0x7d, 0x86, 0x80, 0x8a, 0x8f, 0x96, 0x9d, 0x98, 0x8e, 0x99, 0x9e, 0x82, 0x92, 0x91, + 0x95, 0x8e, 0x8b, 0x8b, 0x83, 0x90, 0x8b, 0x87, 0x82, 0x85, 0x85, 0x7d, 0x78, 0x7b, 0x76, 0x68, + 0x7a, 0x7d, 0x68, 0x6b, 0x6f, 0x68, 0x68, 0x78, 0x78, 0x79, 0x83, 0x83, 0x86, 0x83, 0x81, 0x7e, + 0x83, 0x82, 0x8c, 0x89, 0x8a, 0x88, 0x8f, 0x84, 0x87, 0x89, 0x79, 0x6f, 0x71, 0x88, 0x8a, 0x80, + 0x81, 0x7b, 0x7b, 0x7c, 0x92, 0x8f, 0x7a, 0x8f, 0x95, 0x88, 0x8e, 0x82, 0x84, 0x77, 0x6d, 0x7e, + 0x72, 0x77, 0x80, 0x74, 0x76, 0x81, 0x83, 0x75, 0x6f, 0x76, 0x6b, 0x66, 0x75, 0x79, 0x7c, 0x78, + 0x74, 0x79, 0x79, 0x73, 0x79, 0x7a, 0x77, 0x7b, 0x72, 0x68, 0x73, 0x73, 0x74, 0x74, 0x6e, 0x6e, + 0x6b, 0x78, 0x76, 0x7d, 0x85, 0x7d, 0x7c, 0x7b, 0x79, 0x75, 0x6e, 0x72, 0x6b, 0x60, 0x62, 0x68, + 0x6a, 0x6a, 0x74, 0x78, 0x83, 0x81, 0x7b, 0x7c, 0x76, 0x77, 0x71, 0x71, 0x80, 0x89, 0x84, 0x7b, + 0x83, 0x85, 0x81, 0x89, 0x7a, 0x7c, 0x7d, 0x79, 0x7b, 0x84, 0x8b, 0x8d, 0x8a, 0x87, 0x90, 0x8e, + 0x85, 0x90, 0x9b, 0x99, 0x8d, 0x8e, 0x90, 0x8c, 0x89, 0x8e, 0x8f, 0x93, 0x87, 0x84, 0x82, 0x7a, + 0x85, 0x8b, 0x8f, 0x9a, 0x8f, 0x78, 0x7a, 0x88, 0x8f, 0x82, 0x9a, 0xa2, 0x92, 0x9d, 0x9b, 0x8d, + 0x85, 0x89, 0x90, 0x95, 0x94, 0x8e, 0x84, 0x83, 0x82, 0x80, 0x8e, 0x8b, 0x85, 0x89, 0x7e, 0x93, + 0x91, 0x85, 0x92, 0x80, 0x72, 0x81, 0x75, 0x73, 0x6a, 0x6b, 0x76, 0x6c, 0x7c, 0x7a, 0x75, 0x83, + 0x7e, 0x7b, 0x77, 0x82, 0x80, 0x6f, 0x6c, 0x7d, 0x87, 0x74, 0x70, 0x6f, 0x6b, 0x66, 0x65, 0x5d, + 0x64, 0x67, 0x68, 0x66, 0x73, 0x77, 0x6d, 0x64, 0x6d, 0x78, 0x77, 0x75, 0x71, 0x7e, 0x89, 0x8d, + 0x83, 0x89, 0x7a, 0x79, 0x8c, 0x81, 0x87, 0x81, 0x7a, 0x81, 0x7a, 0x7a, 0x80, 0x83, 0x77, 0x6e, + 0x6c, 0x6b, 0x66, 0x5f, 0x6d, 0x7b, 0x87, 0x82, 0x7e, 0x85, 0x7b, 0x77, 0x80, 0x89, 0x88, 0x87, + 0x7a, 0x77, 0x73, 0x83, 0x75, 0x6f, 0x7e, 0x7d, 0x86, 0x80, 0x8b, 0x90, 0x92, 0x9b, 0x9b, 0xa4, + 0x9b, 0x90, 0x8b, 0x81, 0x7b, 0x79, 0x80, 0x87, 0x81, 0x75, 0x7c, 0x89, 0x79, 0x76, 0x84, 0x77, + 0x6a, 0x78, 0x7d, 0x7c, 0x85, 0x95, 0x8a, 0x83, 0x92, 0x8b, 0x7d, 0x77, 0x86, 0x97, 0x8b, 0x89, + 0x90, 0x89, 0x89, 0x92, 0x86, 0x8b, 0x8f, 0x89, 0x94, 0x94, 0x92, 0x94, 0x93, 0x8b, 0x88, 0x86, + 0x8f, 0x7c, 0x68, 0x68, 0x70, 0x71, 0x66, 0x5c, 0x61, 0x68, 0x60, 0x64, 0x7c, 0x77, 0x69, 0x6c, + 0x6d, 0x6f, 0x72, 0x73, 0x72, 0x75, 0x7b, 0x73, 0x72, 0x82, 0x82, 0x85, 0x8d, 0x8b, 0x81, 0x82, + 0x7e, 0x7d, 0x89, 0x83, 0x94, 0x94, 0x84, 0x84, 0x89, 0x89, 0x83, 0x8a, 0x81, 0x71, 0x82, 0x84, + 0x73, 0x79, 0x7a, 0x77, 0x77, 0x81, 0x8f, 0x8b, 0x8e, 0x88, 0x8d, 0x8d, 0x90, 0x8c, 0x84, 0x8b, + 0x97, 0x84, 0x7a, 0x8a, 0x7d, 0x75, 0x7e, 0x8b, 0x90, 0x91, 0x91, 0x8c, 0x84, 0x86, 0x8d, 0x79, + 0x7a, 0x7a, 0x73, 0x7b, 0x7c, 0x82, 0x80, 0x79, 0x8c, 0x8b, 0x74, 0x76, 0x76, 0x6d, 0x76, 0x74, + 0x77, 0x72, 0x71, 0x7c, 0x73, 0x74, 0x7a, 0x6d, 0x6f, 0x78, 0x7d, 0x79, 0x6e, 0x76, 0x87, 0x80, + 0x79, 0x75, 0x7b, 0x77, 0x6e, 0x75, 0x80, 0x85, 0x81, 0x78, 0x78, 0x71, 0x72, 0x67, 0x70, 0x72, + 0x74, 0x7e, 0x7c, 0x7a, 0x7b, 0x7e, 0x85, 0x7a, 0x7c, 0x80, 0x80, 0x71, 0x6c, 0x6c, 0x66, 0x75, + 0x86, 0x87, 0x7b, 0x76, 0x7c, 0x6d, 0x77, 0x87, 0x83, 0x70, 0x6f, 0x7c, 0x6e, 0x73, 0x7e, 0x6d, + 0x68, 0x82, 0x84, 0x83, 0x89, 0x90, 0x90, 0x89, 0x93, 0x89, 0x82, 0x82, 0x86, 0x83, 0x81, 0x87, + 0x8e, 0x85, 0x8c, 0x9d, 0x93, 0x8b, 0x99, 0x90, 0x8c, 0x8f, 0x80, 0x76, 0x7d, 0x74, 0x7c, 0x7c, + 0x82, 0x8a, 0x75, 0x78, 0x96, 0x9b, 0x92, 0x9d, 0x90, 0x96, 0x9d, 0x9b, 0x9a, 0x95, 0x9a, 0x93, + 0x8e, 0x9e, 0x9e, 0x93, 0x89, 0x87, 0x8f, 0x89, 0x85, 0x8b, 0x98, 0x88, 0x87, 0x89, 0x84, 0x89, + 0x83, 0x7c, 0x7d, 0x7a, 0x79, 0x6c, 0x6d, 0x75, 0x72, 0x77, 0x7d, 0x7d, 0x87, 0x7d, 0x87, 0x8d, + 0x84, 0x8b, 0x81, 0x7e, 0x88, 0x87, 0x77, 0x7a, 0x7a, 0x76, 0x73, 0x67, 0x6f, 0x5f, 0x55, 0x7c, + 0x84, 0x71, 0x71, 0x7a, 0x70, 0x60, 0x5f, 0x67, 0x62, 0x5c, 0x5e, 0x60, 0x5a, 0x68, 0x69, 0x60, + 0x74, 0x76, 0x6a, 0x75, 0x7a, 0x75, 0x71, 0x68, 0x71, 0x77, 0x77, 0x73, 0x6c, 0x63, 0x68, 0x80, + 0x7c, 0x7c, 0x83, 0x7b, 0x78, 0x71, 0x74, 0x7c, 0x86, 0x86, 0x7d, 0x82, 0x82, 0x8e, 0x85, 0x80, + 0x9a, 0x99, 0x8f, 0x8b, 0x8e, 0x98, 0x9b, 0xa5, 0x9f, 0x9a, 0xa1, 0xa0, 0x97, 0x9c, 0xa3, 0xa3, + 0x9a, 0x90, 0x88, 0x8a, 0x80, 0x77, 0x80, 0x7c, 0x84, 0x8e, 0x85, 0x71, 0x7b, 0x80, 0x71, 0x73, + 0x76, 0x72, 0x75, 0x65, 0x5f, 0x6c, 0x73, 0x77, 0x6d, 0x6a, 0x77, 0x7d, 0x86, 0x88, 0x86, 0x80, + 0x80, 0x86, 0x81, 0x7e, 0x82, 0x84, 0x76, 0x7e, 0x8d, 0x86, 0x7d, 0x7e, 0x8a, 0x7d, 0x76, 0x75, + 0x69, 0x67, 0x6b, 0x66, 0x6c, 0x64, 0x69, 0x6e, 0x6a, 0x71, 0x7c, 0x76, 0x79, 0x85, 0x86, 0x8b, + 0x8a, 0x87, 0x83, 0x7a, 0x8c, 0x8d, 0x7c, 0x7e, 0x84, 0x7c, 0x93, 0x80, 0x86, 0x8f, 0x88, 0x8e, + 0x87, 0x93, 0x99, 0x8b, 0x8c, 0x8c, 0x8a, 0x81, 0x83, 0x7a, 0x81, 0x86, 0x7d, 0x76, 0x76, 0x7e, + 0x83, 0x82, 0x84, 0x87, 0x83, 0x8c, 0x87, 0x85, 0x90, 0x8d, 0x95, 0x91, 0x8a, 0x82, 0x84, 0x7b, + 0x7e, 0x81, 0x83, 0x7b, 0x82, 0x89, 0x8c, 0x93, 0x95, 0x9a, 0x91, 0x91, 0x94, 0x89, 0x83, 0x7e, + 0x78, 0x77, 0x85, 0x85, 0x7d, 0x81, 0x8d, 0x85, 0x83, 0x86, 0x81, 0x7a, 0x6e, 0x78, 0x7b, 0x7a, + 0x80, 0x7c, 0x6e, 0x77, 0x76, 0x6e, 0x70, 0x72, 0x77, 0x6c, 0x6d, 0x72, 0x6f, 0x66, 0x6b, 0x6b, + 0x68, 0x6e, 0x77, 0x6b, 0x65, 0x6f, 0x76, 0x7a, 0x77, 0x72, 0x6b, 0x77, 0x84, 0x73, 0x69, 0x7b, + 0x76, 0x71, 0x72, 0x73, 0x7b, 0x85, 0x7c, 0x80, 0x8b, 0x8a, 0x7c, 0x74, 0x7b, 0x86, 0x82, 0x78, + 0x72, 0x7e, 0x78, 0x72, 0x76, 0x6f, 0x73, 0x70, 0x6c, 0x75, 0x76, 0x75, 0x7b, 0x77, 0x78, 0x87, + 0x86, 0x8d, 0x8c, 0x91, 0x94, 0x94, 0x9b, 0x8d, 0x84, 0x8a, 0x8b, 0x7d, 0x83, 0x8d, 0x82, 0x82, + 0x89, 0x8e, 0x95, 0x8f, 0x8f, 0x92, 0x8a, 0x80, 0x78, 0x7c, 0x81, 0x89, 0x80, 0x83, 0x88, 0x81, + 0x75, 0x81, 0x8a, 0x8a, 0x8e, 0x8b, 0x99, 0x8e, 0x89, 0x8e, 0x7d, 0x7e, 0x80, 0x84, 0x83, 0x8a, + 0x89, 0x83, 0x84, 0x87, 0x89, 0x7c, 0x85, 0x87, 0x83, 0x77, 0x83, 0x80, 0x78, 0x7c, 0x7d, 0x80, + 0x80, 0x79, 0x7a, 0x7e, 0x84, 0x73, 0x6d, 0x88, 0x92, 0x89, 0x83, 0x7c, 0x8c, 0x8b, 0x84, 0x90, + 0x90, 0x85, 0x7a, 0x73, 0x73, 0x6b, 0x6d, 0x6b, 0x61, 0x6d, 0x6c, 0x6e, 0x78, 0x78, 0x76, 0x77, + 0x84, 0x89, 0x7e, 0x79, 0x84, 0x7c, 0x77, 0x7d, 0x7a, 0x73, 0x79, 0x7d, 0x7d, 0x87, 0x88, 0x85, + 0x76, 0x7d, 0x86, 0x70, 0x6f, 0x75, 0x80, 0x87, 0x7d, 0x77, 0x83, 0x74, 0x79, 0x79, 0x66, 0x68, + 0x71, 0x6c, 0x5e, 0x64, 0x63, 0x59, 0x56, 0x67, 0x6c, 0x70, 0x79, 0x82, 0x87, 0x90, 0x9a, 0x94, + 0x93, 0x9d, 0x9d, 0x93, 0x8d, 0x97, 0x9c, 0x93, 0x9a, 0xa6, 0x98, 0x98, 0x93, 0x8c, 0x8d, 0x94, + 0x94, 0x85, 0x88, 0x8e, 0x8a, 0x8e, 0x8e, 0x7d, 0x8d, 0x8e, 0x8c, 0x92, 0x7e, 0x7e, 0x7b, 0x78, + 0x7a, 0x7b, 0x72, 0x71, 0x72, 0x70, 0x77, 0x7c, 0x8a, 0x7e, 0x7c, 0x8c, 0x8c, 0x88, 0x89, 0x76, + 0x6e, 0x81, 0x7d, 0x83, 0x84, 0x7d, 0x75, 0x7c, 0x7e, 0x7d, 0x7a, 0x72, 0x67, 0x6a, 0x67, 0x5f, + 0x68, 0x64, 0x69, 0x70, 0x79, 0x6c, 0x6a, 0x72, 0x67, 0x70, 0x77, 0x81, 0x78, 0x72, 0x7d, 0x7d, + 0x69, 0x69, 0x7e, 0x74, 0x73, 0x80, 0x8e, 0x92, 0x8d, 0x8a, 0x8c, 0x91, 0x97, 0x90, 0x7d, 0x8c, + 0x83, 0x87, 0x8e, 0x89, 0x8a, 0x83, 0x7b, 0x83, 0x7e, 0x7e, 0x77, 0x6e, 0x75, 0x74, 0x78, 0x83, + 0x85, 0x8c, 0x8a, 0x84, 0x97, 0xa0, 0x92, 0x8b, 0x95, 0x8f, 0x8a, 0x96, 0x95, 0x8d, 0x85, 0x83, + 0x8c, 0x90, 0x8c, 0x7b, 0x86, 0x8f, 0x88, 0x81, 0x88, 0x90, 0x8a, 0x82, 0x84, 0x86, 0x81, 0x7d, + 0x79, 0x79, 0x82, 0x84, 0x86, 0x79, 0x7e, 0x78, 0x6f, 0x6e, 0x6e, 0x6f, 0x6b, 0x6c, 0x6f, 0x6a, + 0x6d, 0x6f, 0x6f, 0x71, 0x6f, 0x79, 0x7b, 0x6d, 0x72, 0x7b, 0x73, 0x69, 0x62, 0x68, 0x65, 0x62, + 0x6e, 0x74, 0x7b, 0x84, 0x7c, 0x85, 0x86, 0x87, 0x89, 0x83, 0x87, 0x88, 0x77, 0x7d, 0x8f, 0x84, + 0x79, 0x84, 0x8d, 0x86, 0x87, 0x82, 0x84, 0x89, 0x8a, 0x8a, 0x90, 0x84, 0x89, 0x88, 0x73, 0x7b, + 0x7d, 0x78, 0x78, 0x7b, 0x77, 0x7c, 0x7a, 0x73, 0x6b, 0x76, 0x73, 0x67, 0x73, 0x71, 0x6a, 0x80, + 0x89, 0x7e, 0x7e, 0x8c, 0x80, 0x7b, 0x7d, 0x81, 0x7d, 0x79, 0x80, 0x80, 0x8e, 0x8d, 0x88, 0x93, + 0x92, 0x90, 0x90, 0x8a, 0x80, 0x87, 0x80, 0x7c, 0x84, 0x87, 0x8d, 0x83, 0x77, 0x82, 0x89, 0x8e, + 0x86, 0x7e, 0x8f, 0x98, 0x8d, 0x84, 0x8b, 0x8f, 0x82, 0x75, 0x80, 0x8c, 0x88, 0x91, 0x9a, 0x99, + 0x9a, 0x98, 0x8e, 0x94, 0x94, 0x87, 0x86, 0x81, 0x7b, 0x81, 0x85, 0x80, 0x8b, 0x8b, 0x7a, 0x81, + 0x82, 0x79, 0x78, 0x77, 0x79, 0x78, 0x7c, 0x82, 0x7e, 0x83, 0x73, 0x7c, 0x7d, 0x79, 0x7b, 0x6d, + 0x73, 0x73, 0x6a, 0x73, 0x6a, 0x63, 0x67, 0x62, 0x6c, 0x6f, 0x68, 0x6e, 0x81, 0x79, 0x7b, 0x7b, + 0x76, 0x7c, 0x7a, 0x78, 0x77, 0x76, 0x70, 0x75, 0x83, 0x7e, 0x76, 0x87, 0x83, 0x72, 0x77, 0x79, + 0x74, 0x73, 0x71, 0x78, 0x79, 0x86, 0x85, 0x82, 0x7e, 0x70, 0x73, 0x7b, 0x76, 0x77, 0x7d, 0x74, + 0x78, 0x75, 0x6c, 0x70, 0x71, 0x6b, 0x6d, 0x7a, 0x78, 0x8c, 0x98, 0x92, 0x90, 0x9c, 0x9f, 0xa0, + 0x92, 0x9b, 0x98, 0x7b, 0x84, 0x8e, 0x8f, 0x85, 0x86, 0x88, 0x8b, 0x90, 0x82, 0x7a, 0x7d, 0x81, + 0x7d, 0x84, 0x81, 0x8b, 0x8e, 0x82, 0x85, 0x89, 0x87, 0x7c, 0x7c, 0x7a, 0x7a, 0x81, 0x83, 0x7d, + 0x76, 0x7c, 0x78, 0x6e, 0x75, 0x84, 0x81, 0x81, 0x80, 0x8c, 0x81, 0x78, 0x7e, 0x85, 0x86, 0x8a, + 0x7e, 0x6e, 0x7c, 0x7c, 0x71, 0x79, 0x7d, 0x7e, 0x76, 0x68, 0x69, 0x78, 0x6f, 0x67, 0x6e, 0x6c, + 0x6c, 0x77, 0x73, 0x6f, 0x78, 0x7a, 0x81, 0x7d, 0x85, 0x88, 0x79, 0x7b, 0x81, 0x79, 0x81, 0x7d, + 0x7a, 0x7e, 0x7d, 0x90, 0x91, 0x82, 0x80, 0x85, 0x88, 0x84, 0x87, 0x93, 0x9a, 0x92, 0x8c, 0x85, + 0x8f, 0x96, 0x7a, 0x7e, 0x89, 0x81, 0x88, 0x80, 0x7a, 0x84, 0x73, 0x75, 0x88, 0x84, 0x7b, 0x80, + 0x87, 0x8d, 0x8d, 0x88, 0x8c, 0x91, 0x89, 0x8b, 0x8f, 0x8f, 0x8c, 0x7a, 0x76, 0x7a, 0x7a, 0x82, + 0x79, 0x80, 0x86, 0x81, 0x83, 0x82, 0x88, 0x88, 0x84, 0x81, 0x8b, 0x87, 0x81, 0x85, 0x90, 0x96, + 0x8d, 0x99, 0x95, 0x85, 0x86, 0x7e, 0x82, 0x80, 0x73, 0x87, 0x89, 0x80, 0x7d, 0x7d, 0x78, 0x74, + 0x6f, 0x70, 0x7e, 0x7a, 0x74, 0x75, 0x77, 0x71, 0x6c, 0x6c, 0x6d, 0x68, 0x62, 0x69, 0x63, 0x67, + 0x71, 0x6f, 0x74, 0x68, 0x66, 0x6a, 0x66, 0x65, 0x6d, 0x72, 0x70, 0x7e, 0x81, 0x7c, 0x89, 0x8b, + 0x81, 0x84, 0x80, 0x76, 0x7e, 0x75, 0x6a, 0x7d, 0x80, 0x79, 0x78, 0x78, 0x83, 0x86, 0x7e, 0x82, + 0x89, 0x83, 0x82, 0x86, 0x8d, 0x8a, 0x90, 0x94, 0x83, 0x7c, 0x7e, 0x80, 0x81, 0x7d, 0x7d, 0x7e, + 0x85, 0x80, 0x7e, 0x8c, 0x86, 0x87, 0x89, 0x86, 0x81, 0x7e, 0x83, 0x89, 0x8d, 0x8f, 0x8d, 0x8d, + 0x87, 0x7d, 0x83, 0x82, 0x78, 0x78, 0x7c, 0x84, 0x79, 0x79, 0x7e, 0x79, 0x77, 0x76, 0x76, 0x7e, + 0x7e, 0x7a, 0x83, 0x88, 0x7a, 0x79, 0x81, 0x7b, 0x88, 0x87, 0x7c, 0x86, 0x8b, 0x8a, 0x8e, 0x8e, + 0x8a, 0x8d, 0x8e, 0x88, 0x92, 0x96, 0x89, 0x89, 0x94, 0x91, 0x8e, 0x8b, 0x85, 0x88, 0x8a, 0x80, + 0x77, 0x7e, 0x80, 0x75, 0x75, 0x76, 0x7a, 0x75, 0x70, 0x77, 0x85, 0x82, 0x76, 0x81, 0x84, 0x75, + 0x72, 0x73, 0x73, 0x6d, 0x6f, 0x67, 0x6f, 0x81, 0x7d, 0x79, 0x7e, 0x7c, 0x7c, 0x77, 0x70, 0x7d, + 0x77, 0x76, 0x75, 0x81, 0x81, 0x7a, 0x78, 0x78, 0x82, 0x86, 0x79, 0x74, 0x7b, 0x75, 0x73, 0x6d, + 0x7d, 0x77, 0x6b, 0x6a, 0x6f, 0x74, 0x6f, 0x6f, 0x79, 0x6d, 0x6e, 0x85, 0x81, 0x76, 0x7c, 0x7c, + 0x7b, 0x77, 0x78, 0x80, 0x82, 0x7a, 0x80, 0x90, 0x91, 0x8e, 0x87, 0x88, 0x91, 0x8f, 0x8b, 0x8d, + 0x8e, 0x8e, 0x89, 0x90, 0x94, 0x8a, 0x8b, 0x8d, 0x8e, 0x8c, 0x87, 0x82, 0x7d, 0x80, 0x88, 0x87, + 0x88, 0x8c, 0x8b, 0x84, 0x86, 0x92, 0x8f, 0x83, 0x87, 0x8d, 0x8b, 0x88, 0x93, 0x8d, 0x84, 0x7c, + 0x7b, 0x86, 0x86, 0x7e, 0x7d, 0x83, 0x8d, 0x79, 0x7a, 0x88, 0x7c, 0x72, 0x6b, 0x7d, 0x85, 0x73, + 0x6f, 0x72, 0x7a, 0x75, 0x76, 0x7c, 0x82, 0x77, 0x6c, 0x6c, 0x71, 0x73, 0x6c, 0x65, 0x69, 0x74, + 0x75, 0x6b, 0x68, 0x6e, 0x68, 0x6c, 0x6b, 0x75, 0x7a, 0x72, 0x70, 0x72, 0x82, 0x7b, 0x77, 0x7c, + 0x78, 0x79, 0x81, 0x80, 0x7a, 0x78, 0x7e, 0x8d, 0x86, 0x83, 0x85, 0x89, 0x85, 0x7d, 0x8e, 0x8d, + 0x90, 0x87, 0x82, 0x8f, 0x91, 0x81, 0x7c, 0x82, 0x7d, 0x83, 0x86, 0x82, 0x86, 0x88, 0x85, 0x98, + 0x9e, 0x97, 0x99, 0x97, 0x9a, 0x93, 0x96, 0x98, 0x90, 0x8b, 0x88, 0x82, 0x8b, 0x8c, 0x79, 0x7b, + 0x7e, 0x83, 0x81, 0x73, 0x7a, 0x80, 0x73, 0x70, 0x79, 0x7e, 0x7b, 0x6a, 0x71, 0x70, 0x76, 0x7b, + 0x6c, 0x7a, 0x79, 0x71, 0x70, 0x78, 0x7c, 0x71, 0x76, 0x73, 0x7b, 0x79, 0x74, 0x7b, 0x77, 0x77, + 0x77, 0x79, 0x7c, 0x7d, 0x7b, 0x75, 0x86, 0x8c, 0x79, 0x7a, 0x8e, 0x84, 0x76, 0x79, 0x7c, 0x76, + 0x77, 0x75, 0x78, 0x80, 0x78, 0x70, 0x6e, 0x79, 0x7a, 0x71, 0x70, 0x76, 0x7c, 0x7a, 0x79, 0x7a, + 0x79, 0x75, 0x83, 0x7e, 0x76, 0x7c, 0x77, 0x77, 0x7d, 0x7e, 0x85, 0x86, 0x82, 0x7c, 0x7c, 0x7c, + 0x81, 0x81, 0x7d, 0x78, 0x7b, 0x82, 0x7a, 0x7c, 0x85, 0x80, 0x80, 0x7d, 0x80, 0x7e, 0x81, 0x83, + 0x76, 0x7e, 0x88, 0x88, 0x8b, 0x87, 0x93, 0x8e, 0x90, 0x8f, 0x8e, 0x8a, 0x8e, 0x90, 0x8c, 0x89, + 0x8a, 0x89, 0x85, 0x8e, 0x91, 0x88, 0x81, 0x84, 0x7e, 0x7b, 0x83, 0x87, 0x84, 0x7b, 0x83, 0x86, + 0x82, 0x87, 0x7d, 0x79, 0x7d, 0x8f, 0x8c, 0x7d, 0x85, 0x89, 0x84, 0x89, 0x92, 0x8b, 0x87, 0x95, + 0x91, 0x8c, 0x8d, 0x89, 0x87, 0x80, 0x7a, 0x81, 0x81, 0x79, 0x7b, 0x71, 0x73, 0x76, 0x76, 0x70, + 0x72, 0x80, 0x81, 0x83, 0x88, 0x8b, 0x83, 0x7a, 0x80, 0x82, 0x79, 0x77, 0x76, 0x77, 0x6f, 0x73, + 0x7e, 0x76, 0x70, 0x70, 0x71, 0x71, 0x73, 0x70, 0x6e, 0x74, 0x74, 0x77, 0x74, 0x79, 0x75, 0x65, + 0x6e, 0x76, 0x71, 0x74, 0x74, 0x76, 0x7a, 0x7e, 0x7b, 0x78, 0x77, 0x7c, 0x7c, 0x7b, 0x83, 0x82, + 0x7b, 0x75, 0x74, 0x81, 0x7b, 0x6f, 0x79, 0x74, 0x76, 0x81, 0x7a, 0x78, 0x87, 0x82, 0x79, 0x86, + 0x7e, 0x80, 0x85, 0x88, 0x7d, 0x7e, 0x86, 0x83, 0x86, 0x83, 0x85, 0x96, 0x98, 0x93, 0x95, 0x8c, + 0x94, 0x97, 0x85, 0x80, 0x8c, 0x8e, 0x77, 0x80, 0x8d, 0x86, 0x85, 0x7b, 0x76, 0x81, 0x84, 0x82, + 0x84, 0x81, 0x85, 0x8c, 0x89, 0x82, 0x7e, 0x7e, 0x74, 0x7d, 0x88, 0x81, 0x82, 0x84, 0x7e, 0x7e, + 0x87, 0x81, 0x7a, 0x7c, 0x77, 0x80, 0x85, 0x7e, 0x84, 0x81, 0x80, 0x85, 0x77, 0x73, 0x79, 0x76, + 0x6f, 0x6e, 0x79, 0x7e, 0x6e, 0x6e, 0x78, 0x77, 0x74, 0x6f, 0x76, 0x7a, 0x79, 0x77, 0x6e, 0x6c, + 0x71, 0x73, 0x72, 0x77, 0x84, 0x7b, 0x6f, 0x80, 0x7d, 0x80, 0x82, 0x80, 0x80, 0x82, 0x85, 0x7c, + 0x80, 0x7e, 0x80, 0x7e, 0x81, 0x81, 0x7a, 0x7e, 0x80, 0x88, 0x83, 0x87, 0x93, 0x93, 0x83, 0x82, + 0x7d, 0x7a, 0x81, 0x83, 0x7d, 0x82, 0x8a, 0x83, 0x83, 0x85, 0x86, 0x88, 0x92, 0x8d, 0x8d, 0x8f, + 0x93, 0x91, 0x8d, 0x92, 0x91, 0x95, 0x91, 0x88, 0x8c, 0x91, 0x8f, 0x8c, 0x88, 0x84, 0x86, 0x81, + 0x76, 0x7b, 0x81, 0x84, 0x7e, 0x7c, 0x80, 0x83, 0x75, 0x73, 0x7a, 0x85, 0x7b, 0x77, 0x83, 0x83, + 0x84, 0x85, 0x84, 0x82, 0x83, 0x85, 0x85, 0x8a, 0x83, 0x7e, 0x7a, 0x77, 0x79, 0x76, 0x70, 0x6f, + 0x6b, 0x67, 0x69, 0x6e, 0x71, 0x73, 0x71, 0x69, 0x73, 0x71, 0x6b, 0x6b, 0x6e, 0x6f, 0x6b, 0x74, + 0x78, 0x70, 0x6f, 0x76, 0x7d, 0x7a, 0x73, 0x74, 0x7c, 0x7c, 0x75, 0x76, 0x7d, 0x80, 0x79, 0x75, + 0x7c, 0x7d, 0x79, 0x78, 0x7d, 0x82, 0x82, 0x88, 0x86, 0x86, 0x8d, 0x90, 0x80, 0x87, 0x8a, 0x83, + 0x7b, 0x85, 0x90, 0x81, 0x7e, 0x85, 0x8e, 0x8b, 0x81, 0x80, 0x7c, 0x85, 0x7d, 0x7b, 0x8b, 0x8b, + 0x84, 0x81, 0x84, 0x8e, 0x8a, 0x85, 0x82, 0x83, 0x86, 0x85, 0x81, 0x82, 0x87, 0x87, 0x84, 0x88, + 0x88, 0x8c, 0x85, 0x7c, 0x85, 0x83, 0x7d, 0x86, 0x8a, 0x7e, 0x73, 0x78, 0x80, 0x79, 0x76, 0x76, + 0x7c, 0x7c, 0x83, 0x7d, 0x82, 0x82, 0x79, 0x83, 0x7e, 0x80, 0x85, 0x7e, 0x85, 0x88, 0x84, 0x8a, + 0x8e, 0x8b, 0x7e, 0x7c, 0x87, 0x7b, 0x78, 0x79, 0x80, 0x83, 0x7b, 0x80, 0x7d, 0x85, 0x88, 0x83, + 0x83, 0x7e, 0x85, 0x8a, 0x81, 0x86, 0x88, 0x80, 0x7d, 0x89, 0x87, 0x76, 0x81, 0x7c, 0x74, 0x7d, + 0x84, 0x7c, 0x7a, 0x7a, 0x72, 0x75, 0x7e, 0x78, 0x6f, 0x72, 0x7b, 0x7a, 0x73, 0x7a, 0x79, 0x78, + 0x71, 0x73, 0x78, 0x69, 0x6a, 0x75, 0x75, 0x6f, 0x72, 0x77, 0x72, 0x7c, 0x7e, 0x7d, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x85, 0x7c, 0x79, 0x7e, 0x80, 0x89, 0x7e, 0x7e, 0x80, 0x80, 0x7e, 0x7a, 0x82, + 0x85, 0x7c, 0x79, 0x7c, 0x81, 0x81, 0x79, 0x84, 0x8e, 0x88, 0x86, 0x87, 0x95, 0x96, 0x85, 0x82, + 0x8f, 0x83, 0x81, 0x83, 0x7e, 0x85, 0x81, 0x7a, 0x79, 0x80, 0x8e, 0x8a, 0x7e, 0x88, 0x91, 0x91, + 0x8b, 0x87, 0x84, 0x86, 0x8d, 0x85, 0x87, 0x8a, 0x8a, 0x86, 0x82, 0x8b, 0x87, 0x85, 0x88, 0x7d, + 0x7d, 0x82, 0x78, 0x7e, 0x86, 0x84, 0x84, 0x83, 0x7e, 0x80, 0x7c, 0x71, 0x6f, 0x73, 0x6a, 0x6e, + 0x73, 0x75, 0x73, 0x77, 0x6d, 0x74, 0x7b, 0x75, 0x78, 0x76, 0x79, 0x7b, 0x7e, 0x84, 0x81, 0x87, + 0x7d, 0x76, 0x7d, 0x74, 0x70, 0x70, 0x6d, 0x70, 0x75, 0x7a, 0x7b, 0x77, 0x73, 0x6d, 0x74, 0x6f, + 0x72, 0x7a, 0x75, 0x7b, 0x83, 0x83, 0x84, 0x89, 0x88, 0x7d, 0x80, 0x87, 0x83, 0x7b, 0x7d, 0x7b, + 0x82, 0x89, 0x86, 0x8e, 0x8d, 0x83, 0x81, 0x8c, 0x93, 0x8f, 0x8a, 0x8c, 0x99, 0x9e, 0x94, 0x8e, + 0x99, 0x97, 0x94, 0x93, 0x8e, 0x8e, 0x8e, 0x88, 0x87, 0x83, 0x87, 0x85, 0x7b, 0x73, 0x74, 0x80, + 0x7c, 0x75, 0x7a, 0x81, 0x83, 0x84, 0x87, 0x79, 0x83, 0x85, 0x84, 0x7d, 0x7d, 0x89, 0x84, 0x7c, + 0x7c, 0x80, 0x7b, 0x77, 0x7d, 0x82, 0x7b, 0x76, 0x78, 0x73, 0x7e, 0x82, 0x7d, 0x7c, 0x7a, 0x83, + 0x84, 0x7c, 0x73, 0x6a, 0x6f, 0x74, 0x70, 0x69, 0x6d, 0x73, 0x6c, 0x66, 0x73, 0x77, 0x6f, 0x70, + 0x70, 0x76, 0x7e, 0x77, 0x74, 0x72, 0x7a, 0x78, 0x71, 0x77, 0x77, 0x76, 0x79, 0x7d, 0x7a, 0x83, + 0x7e, 0x71, 0x75, 0x7b, 0x82, 0x7a, 0x7a, 0x78, 0x7b, 0x7d, 0x77, 0x7a, 0x7e, 0x78, 0x80, 0x83, + 0x84, 0x85, 0x8b, 0x8b, 0x84, 0x88, 0x8f, 0x8c, 0x86, 0x82, 0x7e, 0x89, 0x91, 0x8d, 0x8b, 0x88, + 0x84, 0x87, 0x83, 0x7c, 0x86, 0x85, 0x81, 0x8b, 0x8b, 0x8a, 0x8c, 0x90, 0x8c, 0x88, 0x84, 0x89, + 0x88, 0x7d, 0x86, 0x8c, 0x83, 0x82, 0x85, 0x83, 0x80, 0x81, 0x82, 0x7d, 0x87, 0x8a, 0x87, 0x88, + 0x8d, 0x86, 0x83, 0x88, 0x82, 0x7e, 0x82, 0x82, 0x81, 0x85, 0x81, 0x87, 0x90, 0x8e, 0x88, 0x84, + 0x84, 0x84, 0x7e, 0x7b, 0x7b, 0x81, 0x6f, 0x77, 0x84, 0x80, 0x81, 0x73, 0x70, 0x7b, 0x7a, 0x79, + 0x7c, 0x78, 0x7a, 0x78, 0x82, 0x84, 0x77, 0x75, 0x73, 0x79, 0x74, 0x79, 0x7b, 0x78, 0x78, 0x7a, + 0x83, 0x7e, 0x74, 0x71, 0x78, 0x73, 0x75, 0x75, 0x78, 0x7c, 0x79, 0x79, 0x78, 0x79, 0x75, 0x70, + 0x6f, 0x74, 0x73, 0x7e, 0x7b, 0x79, 0x86, 0x87, 0x7e, 0x79, 0x84, 0x7e, 0x7b, 0x82, 0x80, 0x78, + 0x81, 0x7b, 0x75, 0x74, 0x76, 0x7b, 0x7d, 0x80, 0x7a, 0x80, 0x85, 0x87, 0x87, 0x8e, 0x8c, 0x81, + 0x86, 0x8a, 0x8a, 0x89, 0x87, 0x8b, 0x8f, 0x8f, 0x8b, 0x8b, 0x88, 0x86, 0x87, 0x85, 0x81, 0x7e, + 0x7c, 0x86, 0x88, 0x85, 0x7c, 0x7e, 0x81, 0x7b, 0x7b, 0x7b, 0x7b, 0x84, 0x86, 0x85, 0x85, 0x85, + 0x81, 0x80, 0x80, 0x81, 0x80, 0x79, 0x78, 0x82, 0x86, 0x82, 0x87, 0x88, 0x7e, 0x81, 0x86, 0x87, + 0x84, 0x7a, 0x7c, 0x8a, 0x88, 0x84, 0x7e, 0x79, 0x78, 0x77, 0x71, 0x72, 0x6c, 0x6f, 0x6c, 0x6c, + 0x70, 0x73, 0x74, 0x73, 0x74, 0x78, 0x79, 0x75, 0x7b, 0x7d, 0x77, 0x81, 0x86, 0x81, 0x7d, 0x80, + 0x7d, 0x76, 0x74, 0x79, 0x78, 0x78, 0x72, 0x6d, 0x79, 0x76, 0x73, 0x78, 0x75, 0x76, 0x78, 0x73, + 0x78, 0x80, 0x83, 0x7b, 0x7b, 0x88, 0x84, 0x86, 0x82, 0x82, 0x7c, 0x82, 0x88, 0x84, 0x8e, 0x8b, + 0x8c, 0x8f, 0x8c, 0x89, 0x8f, 0x8d, 0x8c, 0x95, 0x95, 0x98, 0x93, 0x8e, 0x8f, 0x93, 0x93, 0x94, + 0x8f, 0x8b, 0x92, 0x8d, 0x83, 0x8a, 0x92, 0x8b, 0x84, 0x81, 0x7a, 0x85, 0x83, 0x7e, 0x85, 0x88, + 0x85, 0x82, 0x7e, 0x83, 0x7d, 0x7e, 0x81, 0x7b, 0x81, 0x7b, 0x7e, 0x88, 0x86, 0x80, 0x7e, 0x89, + 0x79, 0x70, 0x77, 0x78, 0x79, 0x78, 0x73, 0x7a, 0x79, 0x74, 0x7a, 0x76, 0x78, 0x7c, 0x77, 0x6f, + 0x70, 0x72, 0x6a, 0x66, 0x66, 0x68, 0x67, 0x64, 0x68, 0x69, 0x6b, 0x6e, 0x69, 0x74, 0x7b, 0x78, + 0x77, 0x79, 0x77, 0x7b, 0x7e, 0x78, 0x7b, 0x80, 0x7b, 0x7e, 0x80, 0x76, 0x79, 0x7d, 0x6b, 0x71, + 0x78, 0x77, 0x79, 0x7a, 0x7d, 0x89, 0x88, 0x82, 0x85, 0x8e, 0x8b, 0x80, 0x84, 0x8a, 0x88, 0x8b, + 0x88, 0x83, 0x8f, 0x8f, 0x81, 0x82, 0x87, 0x83, 0x89, 0x8e, 0x8e, 0x95, 0x8e, 0x8c, 0x8b, 0x82, + 0x85, 0x83, 0x81, 0x89, 0x86, 0x81, 0x86, 0x90, 0x8c, 0x87, 0x8b, 0x8c, 0x82, 0x7e, 0x7d, 0x7d, + 0x7e, 0x86, 0x83, 0x89, 0x84, 0x7c, 0x7e, 0x7d, 0x7d, 0x7c, 0x7e, 0x7c, 0x7c, 0x78, 0x78, 0x7e, + 0x82, 0x76, 0x73, 0x82, 0x83, 0x76, 0x6d, 0x79, 0x7a, 0x7c, 0x7b, 0x7d, 0x85, 0x87, 0x7b, 0x7b, + 0x85, 0x85, 0x84, 0x7c, 0x80, 0x88, 0x85, 0x81, 0x82, 0x7b, 0x7b, 0x7c, 0x7a, 0x82, 0x7d, 0x82, + 0x80, 0x80, 0x7e, 0x83, 0x89, 0x84, 0x7e, 0x83, 0x85, 0x7e, 0x81, 0x7d, 0x81, 0x82, 0x82, 0x81, + 0x7a, 0x7c, 0x7d, 0x74, 0x74, 0x80, 0x79, 0x7d, 0x79, 0x77, 0x7c, 0x76, 0x75, 0x77, 0x7c, 0x78, + 0x7d, 0x75, 0x72, 0x7a, 0x82, 0x82, 0x80, 0x77, 0x72, 0x7b, 0x7b, 0x7b, 0x76, 0x79, 0x7c, 0x77, + 0x79, 0x84, 0x79, 0x76, 0x7b, 0x77, 0x85, 0x83, 0x79, 0x7c, 0x78, 0x7b, 0x80, 0x7e, 0x81, 0x83, + 0x82, 0x7d, 0x7e, 0x86, 0x83, 0x89, 0x87, 0x84, 0x8b, 0x83, 0x87, 0x8f, 0x8b, 0x85, 0x86, 0x8c, + 0x88, 0x8a, 0x82, 0x79, 0x84, 0x88, 0x80, 0x84, 0x84, 0x84, 0x81, 0x80, 0x89, 0x81, 0x86, 0x81, + 0x77, 0x88, 0x89, 0x8a, 0x87, 0x7a, 0x88, 0x8e, 0x88, 0x84, 0x7d, 0x80, 0x81, 0x80, 0x81, 0x84, + 0x85, 0x7a, 0x79, 0x7e, 0x7d, 0x77, 0x75, 0x72, 0x73, 0x79, 0x76, 0x75, 0x6d, 0x76, 0x7a, 0x7a, + 0x77, 0x75, 0x7a, 0x7c, 0x71, 0x71, 0x74, 0x76, 0x7c, 0x73, 0x73, 0x79, 0x79, 0x74, 0x6e, 0x77, + 0x75, 0x6f, 0x75, 0x75, 0x82, 0x85, 0x7c, 0x78, 0x75, 0x7b, 0x83, 0x79, 0x7a, 0x7c, 0x7c, 0x7d, + 0x79, 0x7e, 0x86, 0x79, 0x79, 0x7d, 0x7b, 0x7b, 0x78, 0x7c, 0x7b, 0x85, 0x93, 0x8b, 0x8b, 0x90, + 0x8b, 0x90, 0x90, 0x8a, 0x8d, 0x91, 0x96, 0x95, 0x8f, 0x9a, 0x95, 0x90, 0x95, 0x95, 0x90, 0x8a, + 0x8d, 0x93, 0x90, 0x8e, 0x94, 0x92, 0x8d, 0x91, 0x90, 0x87, 0x80, 0x7d, 0x82, 0x82, 0x84, 0x7e, + 0x7d, 0x7d, 0x7d, 0x7e, 0x77, 0x75, 0x7d, 0x78, 0x74, 0x80, 0x7d, 0x82, 0x81, 0x7b, 0x7d, 0x78, + 0x79, 0x72, 0x6d, 0x74, 0x71, 0x6e, 0x6e, 0x75, 0x74, 0x70, 0x72, 0x77, 0x73, 0x70, 0x74, 0x74, + 0x72, 0x69, 0x72, 0x72, 0x6e, 0x75, 0x72, 0x74, 0x77, 0x71, 0x77, 0x72, 0x72, 0x79, 0x72, 0x7b, + 0x83, 0x7a, 0x77, 0x75, 0x77, 0x7c, 0x7d, 0x80, 0x77, 0x77, 0x78, 0x79, 0x7c, 0x77, 0x7c, 0x7e, + 0x79, 0x7a, 0x80, 0x80, 0x7b, 0x7b, 0x7e, 0x79, 0x80, 0x83, 0x7d, 0x7d, 0x80, 0x82, 0x83, 0x80, + 0x83, 0x81, 0x83, 0x82, 0x82, 0x8d, 0x91, 0x8e, 0x8b, 0x83, 0x88, 0x8a, 0x83, 0x89, 0x84, 0x80, + 0x84, 0x82, 0x82, 0x87, 0x8e, 0x89, 0x87, 0x92, 0x92, 0x8d, 0x8b, 0x83, 0x87, 0x8d, 0x8e, 0x8b, + 0x86, 0x88, 0x87, 0x82, 0x88, 0x83, 0x80, 0x80, 0x83, 0x83, 0x82, 0x8a, 0x8d, 0x83, 0x81, 0x87, + 0x89, 0x85, 0x78, 0x79, 0x84, 0x80, 0x7e, 0x84, 0x84, 0x7a, 0x78, 0x7a, 0x77, 0x76, 0x7b, 0x74, + 0x71, 0x77, 0x7c, 0x7d, 0x77, 0x79, 0x75, 0x73, 0x74, 0x74, 0x71, 0x72, 0x76, 0x7c, 0x7d, 0x7d, + 0x7e, 0x7c, 0x78, 0x7c, 0x75, 0x71, 0x7c, 0x7c, 0x79, 0x7b, 0x7c, 0x88, 0x87, 0x83, 0x83, 0x89, + 0x85, 0x81, 0x80, 0x81, 0x85, 0x84, 0x7d, 0x79, 0x80, 0x80, 0x7a, 0x74, 0x6e, 0x7b, 0x78, 0x78, + 0x7d, 0x80, 0x7e, 0x7e, 0x84, 0x84, 0x7d, 0x88, 0x8b, 0x7c, 0x84, 0x86, 0x86, 0x8a, 0x88, 0x84, + 0x89, 0x85, 0x7e, 0x81, 0x7e, 0x81, 0x80, 0x7c, 0x7e, 0x83, 0x85, 0x80, 0x7d, 0x7b, 0x7b, 0x7d, + 0x79, 0x79, 0x80, 0x77, 0x7d, 0x83, 0x81, 0x86, 0x82, 0x7e, 0x7a, 0x7d, 0x82, 0x7d, 0x78, 0x78, + 0x7b, 0x82, 0x85, 0x7c, 0x75, 0x7b, 0x7c, 0x76, 0x7c, 0x86, 0x88, 0x84, 0x80, 0x88, 0x87, 0x81, + 0x7d, 0x7a, 0x7d, 0x81, 0x76, 0x72, 0x7c, 0x7e, 0x7b, 0x81, 0x82, 0x84, 0x8e, 0x85, 0x81, 0x81, + 0x7d, 0x7b, 0x7d, 0x80, 0x7c, 0x7b, 0x79, 0x7b, 0x7d, 0x7a, 0x76, 0x78, 0x77, 0x75, 0x77, 0x7d, + 0x7d, 0x73, 0x75, 0x83, 0x82, 0x7c, 0x7c, 0x81, 0x84, 0x7a, 0x7c, 0x7d, 0x77, 0x78, 0x7a, 0x80, + 0x7c, 0x7b, 0x7a, 0x74, 0x73, 0x7b, 0x73, 0x71, 0x7d, 0x7d, 0x7e, 0x7a, 0x81, 0x85, 0x82, 0x82, + 0x7e, 0x81, 0x7d, 0x7d, 0x83, 0x7c, 0x81, 0x81, 0x81, 0x86, 0x87, 0x83, 0x7b, 0x7b, 0x82, 0x85, + 0x8a, 0x8e, 0x88, 0x86, 0x8c, 0x95, 0x95, 0x92, 0x8e, 0x8a, 0x84, 0x85, 0x8c, 0x8a, 0x87, 0x86, + 0x8a, 0x8f, 0x8c, 0x88, 0x83, 0x86, 0x8e, 0x8d, 0x8a, 0x89, 0x8c, 0x87, 0x85, 0x88, 0x83, 0x8a, + 0x84, 0x79, 0x7d, 0x81, 0x81, 0x83, 0x87, 0x89, 0x88, 0x89, 0x83, 0x80, 0x7e, 0x82, 0x7c, 0x78, + 0x7c, 0x83, 0x80, 0x7c, 0x79, 0x79, 0x78, 0x79, 0x76, 0x6a, 0x66, 0x6c, 0x6b, 0x6e, 0x6a, 0x6a, + 0x70, 0x6a, 0x65, 0x69, 0x70, 0x69, 0x60, 0x66, 0x6a, 0x77, 0x78, 0x6c, 0x6f, 0x73, 0x75, 0x72, + 0x6f, 0x72, 0x74, 0x76, 0x79, 0x79, 0x78, 0x76, 0x7b, 0x7e, 0x7c, 0x80, 0x81, 0x7b, 0x77, 0x7d, + 0x7b, 0x7d, 0x80, 0x88, 0x8a, 0x85, 0x82, 0x7e, 0x82, 0x81, 0x85, 0x87, 0x86, 0x8b, 0x92, 0x8d, + 0x90, 0x94, 0x91, 0x94, 0x91, 0x8b, 0x8b, 0x90, 0x8c, 0x85, 0x8c, 0x91, 0x8e, 0x87, 0x8b, 0x91, + 0x88, 0x85, 0x88, 0x85, 0x89, 0x8b, 0x84, 0x88, 0x83, 0x82, 0x87, 0x86, 0x7e, 0x83, 0x80, 0x7d, + 0x83, 0x89, 0x8a, 0x88, 0x7e, 0x7b, 0x7d, 0x7e, 0x7e, 0x7d, 0x7a, 0x7a, 0x7a, 0x74, 0x78, 0x7c, + 0x7b, 0x80, 0x7d, 0x80, 0x7e, 0x7b, 0x7c, 0x7a, 0x75, 0x78, 0x6c, 0x70, 0x78, 0x71, 0x6d, 0x78, + 0x7a, 0x79, 0x78, 0x74, 0x79, 0x82, 0x7c, 0x81, 0x81, 0x85, 0x83, 0x85, 0x84, 0x80, 0x85, 0x85, + 0x80, 0x86, 0x80, 0x7c, 0x83, 0x84, 0x81, 0x82, 0x85, 0x80, 0x7e, 0x81, 0x7d, 0x82, 0x8c, 0x86, + 0x80, 0x83, 0x82, 0x7c, 0x74, 0x77, 0x70, 0x6d, 0x76, 0x75, 0x76, 0x7c, 0x83, 0x82, 0x83, 0x86, + 0x81, 0x85, 0x80, 0x7e, 0x80, 0x81, 0x80, 0x80, 0x81, 0x81, 0x81, 0x82, 0x7c, 0x80, 0x82, 0x7d, + 0x76, 0x75, 0x75, 0x76, 0x79, 0x73, 0x75, 0x75, 0x74, 0x79, 0x79, 0x77, 0x7c, 0x7e, 0x80, 0x82, + 0x88, 0x85, 0x8a, 0x88, 0x82, 0x7e, 0x82, 0x80, 0x7b, 0x7d, 0x81, 0x80, 0x83, 0x85, 0x83, 0x84, + 0x80, 0x7b, 0x82, 0x88, 0x85, 0x83, 0x82, 0x82, 0x82, 0x89, 0x8a, 0x8c, 0x89, 0x81, 0x7c, 0x84, + 0x83, 0x82, 0x82, 0x7d, 0x7e, 0x84, 0x85, 0x87, 0x81, 0x7c, 0x86, 0x85, 0x85, 0x81, 0x7a, 0x78, + 0x7e, 0x7c, 0x75, 0x77, 0x78, 0x74, 0x77, 0x77, 0x7b, 0x7c, 0x75, 0x76, 0x75, 0x7a, 0x7e, 0x72, + 0x77, 0x76, 0x75, 0x79, 0x79, 0x77, 0x79, 0x81, 0x84, 0x81, 0x7d, 0x84, 0x82, 0x78, 0x74, 0x79, + 0x7c, 0x79, 0x70, 0x78, 0x82, 0x7a, 0x79, 0x7d, 0x86, 0x85, 0x82, 0x85, 0x88, 0x8b, 0x86, 0x82, + 0x84, 0x7e, 0x7c, 0x86, 0x81, 0x82, 0x87, 0x81, 0x83, 0x8c, 0x87, 0x87, 0x8b, 0x88, 0x8a, 0x91, + 0x93, 0x92, 0x8f, 0x90, 0x92, 0x90, 0x92, 0x8d, 0x8c, 0x8c, 0x87, 0x87, 0x84, 0x88, 0x85, 0x7d, + 0x82, 0x86, 0x85, 0x7a, 0x77, 0x81, 0x84, 0x84, 0x7c, 0x7e, 0x85, 0x7c, 0x76, 0x80, 0x86, 0x80, + 0x80, 0x81, 0x84, 0x85, 0x7e, 0x7d, 0x80, 0x7c, 0x78, 0x77, 0x7c, 0x78, 0x78, 0x78, 0x79, 0x76, + 0x6e, 0x73, 0x76, 0x72, 0x74, 0x7a, 0x79, 0x73, 0x74, 0x76, 0x75, 0x76, 0x75, 0x72, 0x72, 0x74, + 0x73, 0x74, 0x77, 0x79, 0x76, 0x75, 0x75, 0x77, 0x7b, 0x71, 0x71, 0x76, 0x77, 0x79, 0x7a, 0x76, + 0x77, 0x77, 0x75, 0x76, 0x7a, 0x74, 0x6f, 0x79, 0x7e, 0x79, 0x79, 0x7a, 0x76, 0x76, 0x77, 0x78, + 0x7d, 0x78, 0x7a, 0x81, 0x82, 0x84, 0x86, 0x85, 0x88, 0x8e, 0x8c, 0x82, 0x85, 0x8a, 0x87, 0x82, + 0x7d, 0x84, 0x88, 0x89, 0x86, 0x88, 0x90, 0x89, 0x86, 0x87, 0x84, 0x88, 0x8b, 0x87, 0x86, 0x8e, + 0x8f, 0x85, 0x87, 0x88, 0x8a, 0x8b, 0x8b, 0x87, 0x88, 0x8c, 0x8d, 0x89, 0x8a, 0x8d, 0x8a, 0x84, + 0x87, 0x8e, 0x8c, 0x89, 0x87, 0x84, 0x86, 0x89, 0x83, 0x7c, 0x7b, 0x80, 0x7d, 0x79, 0x7b, 0x7c, + 0x7d, 0x81, 0x7b, 0x7d, 0x84, 0x81, 0x79, 0x7b, 0x7b, 0x7b, 0x7a, 0x76, 0x7a, 0x77, 0x70, 0x75, + 0x76, 0x79, 0x7b, 0x7c, 0x78, 0x7b, 0x82, 0x7a, 0x7a, 0x77, 0x75, 0x75, 0x77, 0x78, 0x77, 0x7c, + 0x7c, 0x73, 0x78, 0x7c, 0x7a, 0x7d, 0x79, 0x75, 0x7d, 0x83, 0x80, 0x7c, 0x7a, 0x79, 0x77, 0x7a, + 0x7c, 0x7e, 0x7d, 0x7e, 0x80, 0x7a, 0x81, 0x84, 0x7c, 0x7b, 0x85, 0x86, 0x85, 0x80, 0x82, 0x86, + 0x84, 0x83, 0x85, 0x8e, 0x87, 0x81, 0x83, 0x87, 0x8d, 0x85, 0x81, 0x84, 0x86, 0x86, 0x86, 0x84, + 0x84, 0x80, 0x82, 0x87, 0x83, 0x83, 0x7e, 0x7a, 0x79, 0x7e, 0x86, 0x80, 0x7a, 0x80, 0x82, 0x81, + 0x81, 0x79, 0x7c, 0x78, 0x78, 0x80, 0x80, 0x80, 0x82, 0x7c, 0x7c, 0x77, 0x7c, 0x80, 0x77, 0x76, + 0x7d, 0x83, 0x81, 0x7c, 0x7d, 0x82, 0x7d, 0x79, 0x7c, 0x80, 0x82, 0x7b, 0x80, 0x7e, 0x7a, 0x79, + 0x77, 0x7c, 0x78, 0x77, 0x7d, 0x7d, 0x7d, 0x7c, 0x80, 0x7e, 0x7a, 0x83, 0x80, 0x74, 0x77, 0x7d, + 0x81, 0x7e, 0x7d, 0x7e, 0x7e, 0x80, 0x80, 0x7e, 0x7b, 0x79, 0x7b, 0x7c, 0x84, 0x87, 0x89, 0x83, + 0x83, 0x8e, 0x8b, 0x87, 0x8a, 0x81, 0x85, 0x8a, 0x7e, 0x7c, 0x7b, 0x7a, 0x75, 0x74, 0x7c, 0x7d, + 0x7b, 0x76, 0x77, 0x7b, 0x7c, 0x7d, 0x79, 0x7b, 0x7a, 0x80, 0x85, 0x81, 0x83, 0x88, 0x7e, 0x79, + 0x82, 0x83, 0x83, 0x82, 0x80, 0x80, 0x82, 0x80, 0x84, 0x80, 0x84, 0x86, 0x80, 0x81, 0x85, 0x84, + 0x83, 0x83, 0x87, 0x89, 0x87, 0x87, 0x82, 0x80, 0x84, 0x89, 0x87, 0x85, 0x86, 0x81, 0x81, 0x85, + 0x83, 0x87, 0x86, 0x85, 0x86, 0x8a, 0x88, 0x84, 0x87, 0x84, 0x82, 0x87, 0x84, 0x85, 0x84, 0x81, + 0x88, 0x8b, 0x86, 0x81, 0x83, 0x81, 0x7d, 0x7e, 0x80, 0x7e, 0x7e, 0x83, 0x80, 0x7b, 0x82, 0x7c, + 0x73, 0x75, 0x78, 0x74, 0x74, 0x76, 0x74, 0x71, 0x6f, 0x70, 0x6f, 0x68, 0x6d, 0x71, 0x69, 0x67, + 0x69, 0x6c, 0x6c, 0x69, 0x6d, 0x70, 0x73, 0x74, 0x73, 0x79, 0x78, 0x7a, 0x79, 0x78, 0x77, 0x76, + 0x7a, 0x73, 0x79, 0x7d, 0x76, 0x7c, 0x7c, 0x7a, 0x7e, 0x7b, 0x74, 0x7d, 0x83, 0x82, 0x85, 0x86, + 0x84, 0x85, 0x84, 0x89, 0x8b, 0x88, 0x8a, 0x8b, 0x8a, 0x89, 0x8c, 0x8f, 0x85, 0x88, 0x94, 0x91, + 0x8e, 0x8d, 0x8a, 0x8f, 0x90, 0x8c, 0x90, 0x93, 0x8a, 0x87, 0x86, 0x88, 0x8a, 0x87, 0x87, 0x86, + 0x81, 0x82, 0x82, 0x82, 0x81, 0x85, 0x86, 0x81, 0x82, 0x83, 0x7d, 0x80, 0x85, 0x85, 0x81, 0x80, + 0x86, 0x85, 0x88, 0x81, 0x7d, 0x87, 0x83, 0x7c, 0x7e, 0x7d, 0x7d, 0x7c, 0x77, 0x7a, 0x7c, 0x79, + 0x76, 0x73, 0x77, 0x7c, 0x80, 0x7a, 0x73, 0x78, 0x7c, 0x79, 0x73, 0x73, 0x76, 0x76, 0x72, 0x72, + 0x7b, 0x7e, 0x7b, 0x75, 0x7a, 0x80, 0x7c, 0x7c, 0x78, 0x7c, 0x82, 0x80, 0x80, 0x81, 0x80, 0x85, + 0x8b, 0x7c, 0x7d, 0x86, 0x7e, 0x79, 0x7d, 0x7d, 0x7b, 0x79, 0x79, 0x7b, 0x81, 0x81, 0x7c, 0x7b, + 0x7b, 0x81, 0x83, 0x7c, 0x79, 0x7e, 0x85, 0x7b, 0x79, 0x86, 0x81, 0x7c, 0x7d, 0x7b, 0x84, 0x87, + 0x85, 0x88, 0x87, 0x89, 0x86, 0x7e, 0x7c, 0x81, 0x83, 0x7d, 0x7d, 0x84, 0x83, 0x85, 0x88, 0x7e, + 0x7b, 0x81, 0x7d, 0x76, 0x75, 0x78, 0x74, 0x71, 0x7c, 0x79, 0x75, 0x78, 0x75, 0x76, 0x76, 0x7a, + 0x80, 0x74, 0x78, 0x84, 0x80, 0x7d, 0x80, 0x83, 0x83, 0x80, 0x81, 0x86, 0x7a, 0x83, 0x88, 0x87, + 0x86, 0x81, 0x83, 0x83, 0x82, 0x84, 0x88, 0x87, 0x83, 0x81, 0x80, 0x84, 0x87, 0x82, 0x7c, 0x81, + 0x81, 0x81, 0x7a, 0x7c, 0x7e, 0x80, 0x81, 0x7e, 0x84, 0x85, 0x80, 0x7a, 0x7a, 0x84, 0x81, 0x78, + 0x7a, 0x7c, 0x7a, 0x78, 0x7b, 0x7d, 0x7b, 0x7e, 0x80, 0x7e, 0x80, 0x81, 0x82, 0x7c, 0x7d, 0x7d, + 0x7e, 0x83, 0x79, 0x76, 0x81, 0x86, 0x81, 0x80, 0x83, 0x84, 0x84, 0x7e, 0x80, 0x82, 0x7b, 0x7b, + 0x7b, 0x7b, 0x7d, 0x7d, 0x7a, 0x7a, 0x7b, 0x85, 0x85, 0x7d, 0x82, 0x83, 0x83, 0x88, 0x7e, 0x81, + 0x82, 0x80, 0x7b, 0x7d, 0x83, 0x82, 0x82, 0x82, 0x83, 0x85, 0x89, 0x88, 0x85, 0x85, 0x8a, 0x8b, + 0x86, 0x84, 0x81, 0x86, 0x83, 0x7d, 0x86, 0x86, 0x81, 0x81, 0x7c, 0x80, 0x7c, 0x7b, 0x83, 0x82, + 0x81, 0x83, 0x8a, 0x88, 0x82, 0x83, 0x86, 0x83, 0x82, 0x86, 0x84, 0x80, 0x7d, 0x80, 0x7c, 0x7d, + 0x81, 0x7a, 0x78, 0x7a, 0x79, 0x7e, 0x81, 0x7d, 0x85, 0x84, 0x7d, 0x7b, 0x78, 0x78, 0x70, 0x76, + 0x79, 0x77, 0x7a, 0x7c, 0x7d, 0x7a, 0x7b, 0x7d, 0x78, 0x74, 0x75, 0x74, 0x74, 0x71, 0x77, 0x75, + 0x71, 0x73, 0x76, 0x79, 0x76, 0x72, 0x77, 0x78, 0x7a, 0x79, 0x75, 0x73, 0x73, 0x72, 0x72, 0x75, + 0x71, 0x72, 0x75, 0x76, 0x77, 0x7d, 0x7c, 0x7c, 0x7b, 0x80, 0x80, 0x82, 0x7e, 0x7c, 0x7e, 0x83, + 0x88, 0x86, 0x85, 0x87, 0x8a, 0x89, 0x87, 0x84, 0x84, 0x84, 0x82, 0x7d, 0x86, 0x89, 0x87, 0x85, + 0x89, 0x8d, 0x8c, 0x88, 0x8a, 0x85, 0x85, 0x85, 0x88, 0x87, 0x83, 0x89, 0x8a, 0x86, 0x87, 0x90, + 0x8c, 0x88, 0x8c, 0x8b, 0x8d, 0x8e, 0x8c, 0x8b, 0x8d, 0x8b, 0x87, 0x84, 0x82, 0x84, 0x81, 0x7e, + 0x83, 0x84, 0x83, 0x7d, 0x7d, 0x83, 0x7b, 0x7a, 0x7e, 0x7a, 0x7c, 0x80, 0x80, 0x7d, 0x80, 0x80, + 0x7c, 0x7d, 0x85, 0x84, 0x7a, 0x76, 0x7a, 0x73, 0x6e, 0x73, 0x72, 0x6f, 0x6b, 0x71, 0x77, 0x72, + 0x6f, 0x76, 0x74, 0x75, 0x77, 0x72, 0x76, 0x77, 0x76, 0x7a, 0x7c, 0x7a, 0x78, 0x78, 0x7c, 0x7c, + 0x77, 0x7a, 0x7b, 0x76, 0x77, 0x7d, 0x7d, 0x7b, 0x7a, 0x7d, 0x80, 0x7d, 0x84, 0x82, 0x81, 0x83, + 0x87, 0x87, 0x82, 0x85, 0x88, 0x84, 0x83, 0x88, 0x83, 0x86, 0x89, 0x8a, 0x8c, 0x8a, 0x91, 0x91, + 0x8a, 0x8e, 0x8e, 0x8c, 0x88, 0x8a, 0x89, 0x82, 0x84, 0x86, 0x82, 0x85, 0x86, 0x87, 0x81, 0x80, + 0x81, 0x80, 0x7a, 0x7a, 0x7b, 0x74, 0x77, 0x7b, 0x7b, 0x76, 0x78, 0x7b, 0x7b, 0x7b, 0x7e, 0x7d, + 0x7d, 0x7e, 0x7c, 0x7a, 0x77, 0x79, 0x74, 0x74, 0x79, 0x79, 0x78, 0x79, 0x7c, 0x7e, 0x78, 0x7d, + 0x80, 0x75, 0x72, 0x79, 0x78, 0x78, 0x79, 0x7b, 0x83, 0x80, 0x7e, 0x83, 0x7c, 0x7b, 0x7a, 0x7c, + 0x7d, 0x79, 0x7a, 0x82, 0x84, 0x7e, 0x7e, 0x86, 0x83, 0x80, 0x82, 0x81, 0x85, 0x83, 0x80, 0x82, + 0x84, 0x87, 0x85, 0x7b, 0x81, 0x83, 0x84, 0x83, 0x7e, 0x81, 0x86, 0x86, 0x7c, 0x7c, 0x81, 0x85, + 0x80, 0x7b, 0x80, 0x7e, 0x80, 0x7c, 0x7e, 0x85, 0x82, 0x85, 0x84, 0x81, 0x7e, 0x7d, 0x82, 0x7b, + 0x79, 0x84, 0x82, 0x7b, 0x7a, 0x83, 0x87, 0x80, 0x7c, 0x82, 0x81, 0x7b, 0x7e, 0x7b, 0x75, 0x77, + 0x76, 0x7a, 0x7d, 0x78, 0x80, 0x7b, 0x77, 0x7b, 0x80, 0x80, 0x7c, 0x7e, 0x82, 0x7e, 0x7d, 0x7a, + 0x7b, 0x80, 0x81, 0x86, 0x87, 0x83, 0x84, 0x87, 0x8b, 0x89, 0x81, 0x82, 0x83, 0x81, 0x7d, 0x82, + 0x85, 0x80, 0x80, 0x85, 0x87, 0x85, 0x82, 0x82, 0x86, 0x82, 0x84, 0x86, 0x81, 0x81, 0x84, 0x88, + 0x89, 0x84, 0x87, 0x8a, 0x83, 0x8a, 0x8a, 0x84, 0x85, 0x7c, 0x80, 0x83, 0x7d, 0x7e, 0x82, 0x7d, + 0x7c, 0x80, 0x80, 0x7a, 0x74, 0x78, 0x7a, 0x73, 0x71, 0x70, 0x70, 0x73, 0x6c, 0x6f, 0x71, 0x6f, + 0x6c, 0x6c, 0x72, 0x70, 0x72, 0x77, 0x75, 0x73, 0x77, 0x74, 0x74, 0x74, 0x73, 0x72, 0x74, 0x78, + 0x82, 0x83, 0x7b, 0x7d, 0x7d, 0x7c, 0x7d, 0x80, 0x7e, 0x7c, 0x7b, 0x7c, 0x7e, 0x83, 0x83, 0x83, + 0x87, 0x87, 0x86, 0x84, 0x89, 0x88, 0x80, 0x85, 0x89, 0x8f, 0x8d, 0x8b, 0x92, 0x92, 0x8e, 0x8e, + 0x90, 0x8e, 0x8a, 0x8c, 0x88, 0x87, 0x8f, 0x8b, 0x82, 0x82, 0x85, 0x83, 0x81, 0x81, 0x84, 0x82, + 0x83, 0x87, 0x86, 0x83, 0x85, 0x81, 0x80, 0x7d, 0x82, 0x86, 0x7e, 0x7e, 0x89, 0x88, 0x87, 0x85, + 0x82, 0x81, 0x7e, 0x7e, 0x78, 0x75, 0x77, 0x7a, 0x79, 0x7b, 0x7b, 0x7a, 0x78, 0x75, 0x79, 0x78, + 0x79, 0x78, 0x73, 0x74, 0x77, 0x75, 0x77, 0x79, 0x77, 0x73, 0x72, 0x79, 0x7c, 0x79, 0x79, 0x7a, + 0x7e, 0x7b, 0x7c, 0x83, 0x80, 0x7d, 0x79, 0x7c, 0x82, 0x78, 0x7b, 0x78, 0x7a, 0x85, 0x7e, 0x7c, + 0x7e, 0x7a, 0x7a, 0x7b, 0x79, 0x79, 0x7a, 0x78, 0x78, 0x80, 0x84, 0x82, 0x7d, 0x7d, 0x7d, 0x7b, + 0x82, 0x7e, 0x7c, 0x81, 0x81, 0x85, 0x8b, 0x85, 0x83, 0x86, 0x87, 0x83, 0x83, 0x86, 0x86, 0x83, + 0x7e, 0x87, 0x8b, 0x89, 0x88, 0x8a, 0x8b, 0x84, 0x85, 0x85, 0x86, 0x84, 0x82, 0x81, 0x82, 0x83, + 0x7d, 0x7b, 0x7d, 0x7b, 0x7c, 0x7a, 0x7e, 0x81, 0x7c, 0x7b, 0x7b, 0x81, 0x86, 0x81, 0x7e, 0x7c, + 0x7c, 0x7c, 0x75, 0x73, 0x76, 0x75, 0x79, 0x7c, 0x83, 0x81, 0x7b, 0x7e, 0x81, 0x7e, 0x7a, 0x7c, + 0x7c, 0x7a, 0x80, 0x85, 0x84, 0x7c, 0x7b, 0x81, 0x82, 0x7e, 0x81, 0x7e, 0x7a, 0x7c, 0x82, 0x7e, + 0x7e, 0x82, 0x80, 0x7b, 0x81, 0x7e, 0x7a, 0x7b, 0x79, 0x79, 0x7b, 0x7b, 0x7d, 0x7d, 0x79, 0x79, + 0x7a, 0x7a, 0x7c, 0x7a, 0x7d, 0x80, 0x81, 0x81, 0x85, 0x84, 0x80, 0x84, 0x81, 0x7e, 0x82, 0x80, + 0x82, 0x80, 0x83, 0x84, 0x81, 0x86, 0x88, 0x84, 0x80, 0x81, 0x80, 0x7a, 0x79, 0x7c, 0x7e, 0x7a, + 0x7c, 0x7d, 0x7d, 0x80, 0x85, 0x84, 0x7e, 0x81, 0x83, 0x82, 0x81, 0x85, 0x86, 0x85, 0x84, 0x86, + 0x88, 0x7e, 0x85, 0x87, 0x81, 0x86, 0x86, 0x84, 0x84, 0x81, 0x80, 0x81, 0x80, 0x7e, 0x7e, 0x7b, + 0x7b, 0x82, 0x7d, 0x7c, 0x82, 0x81, 0x82, 0x7c, 0x80, 0x7e, 0x78, 0x7c, 0x80, 0x78, 0x7d, 0x82, + 0x7e, 0x82, 0x86, 0x7e, 0x7d, 0x80, 0x7b, 0x7d, 0x7b, 0x81, 0x7e, 0x7b, 0x7e, 0x85, 0x8a, 0x85, + 0x84, 0x85, 0x81, 0x83, 0x83, 0x7d, 0x7b, 0x7c, 0x7b, 0x7a, 0x7a, 0x80, 0x7d, 0x78, 0x7a, 0x7b, + 0x7c, 0x7c, 0x7a, 0x7b, 0x7b, 0x76, 0x7b, 0x7b, 0x78, 0x77, 0x78, 0x79, 0x82, 0x80, 0x7b, 0x83, + 0x86, 0x82, 0x82, 0x84, 0x81, 0x7d, 0x7c, 0x75, 0x74, 0x78, 0x79, 0x76, 0x75, 0x7a, 0x7b, 0x7a, + 0x7a, 0x7b, 0x7d, 0x7a, 0x76, 0x78, 0x79, 0x77, 0x79, 0x82, 0x81, 0x7c, 0x80, 0x83, 0x82, 0x83, + 0x82, 0x85, 0x83, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x81, 0x80, 0x7e, 0x7d, 0x7e, 0x83, 0x84, 0x82, + 0x83, 0x82, 0x83, 0x84, 0x85, 0x82, 0x80, 0x84, 0x86, 0x85, 0x89, 0x85, 0x84, 0x86, 0x87, 0x8b, + 0x8c, 0x88, 0x84, 0x87, 0x8b, 0x86, 0x84, 0x87, 0x87, 0x86, 0x84, 0x86, 0x87, 0x81, 0x81, 0x88, + 0x83, 0x82, 0x80, 0x82, 0x7e, 0x7b, 0x81, 0x7e, 0x7e, 0x82, 0x82, 0x81, 0x81, 0x82, 0x81, 0x79, + 0x7d, 0x7c, 0x74, 0x77, 0x77, 0x76, 0x77, 0x76, 0x78, 0x76, 0x73, 0x75, 0x75, 0x76, 0x77, 0x74, + 0x70, 0x73, 0x75, 0x70, 0x72, 0x75, 0x76, 0x75, 0x75, 0x79, 0x7b, 0x7a, 0x79, 0x81, 0x82, 0x7d, + 0x80, 0x80, 0x79, 0x79, 0x7b, 0x7a, 0x7d, 0x7b, 0x7e, 0x7c, 0x7d, 0x81, 0x7e, 0x80, 0x80, 0x82, + 0x85, 0x85, 0x86, 0x88, 0x87, 0x88, 0x89, 0x87, 0x88, 0x86, 0x87, 0x8b, 0x8e, 0x8c, 0x89, 0x8e, + 0x8d, 0x89, 0x8b, 0x8b, 0x8d, 0x8a, 0x84, 0x8d, 0x8b, 0x83, 0x86, 0x85, 0x86, 0x84, 0x82, 0x84, + 0x81, 0x7d, 0x7b, 0x7b, 0x81, 0x82, 0x7b, 0x79, 0x7a, 0x7d, 0x7b, 0x7d, 0x7a, 0x76, 0x78, 0x76, + 0x79, 0x78, 0x7c, 0x79, 0x76, 0x7c, 0x7a, 0x78, 0x7a, 0x7b, 0x78, 0x78, 0x77, 0x78, 0x79, 0x78, + 0x77, 0x7b, 0x7b, 0x79, 0x7b, 0x7c, 0x7b, 0x79, 0x7b, 0x7d, 0x80, 0x81, 0x7d, 0x7c, 0x7c, 0x7b, + 0x78, 0x78, 0x78, 0x7a, 0x7a, 0x78, 0x7b, 0x7e, 0x7e, 0x82, 0x81, 0x7e, 0x82, 0x81, 0x83, 0x85, + 0x84, 0x80, 0x81, 0x88, 0x82, 0x85, 0x85, 0x84, 0x86, 0x85, 0x85, 0x86, 0x83, 0x82, 0x82, 0x82, + 0x82, 0x80, 0x81, 0x82, 0x7e, 0x83, 0x83, 0x81, 0x84, 0x85, 0x82, 0x7e, 0x7b, 0x7a, 0x79, 0x7e, + 0x80, 0x7e, 0x7d, 0x7d, 0x82, 0x81, 0x81, 0x7e, 0x7e, 0x81, 0x7c, 0x7d, 0x84, 0x84, 0x7e, 0x79, + 0x7e, 0x83, 0x80, 0x7c, 0x7a, 0x83, 0x82, 0x7b, 0x82, 0x81, 0x7b, 0x7c, 0x7e, 0x81, 0x81, 0x7c, + 0x80, 0x81, 0x7d, 0x7d, 0x7d, 0x83, 0x81, 0x80, 0x81, 0x7e, 0x82, 0x82, 0x80, 0x83, 0x87, 0x82, + 0x7e, 0x83, 0x88, 0x80, 0x7e, 0x81, 0x84, 0x84, 0x80, 0x84, 0x85, 0x81, 0x83, 0x82, 0x83, 0x88, + 0x87, 0x84, 0x89, 0x8c, 0x86, 0x83, 0x88, 0x89, 0x84, 0x81, 0x80, 0x84, 0x82, 0x7e, 0x7b, 0x7b, + 0x7a, 0x78, 0x76, 0x78, 0x77, 0x79, 0x77, 0x75, 0x78, 0x77, 0x76, 0x76, 0x74, 0x79, 0x77, 0x75, + 0x79, 0x78, 0x75, 0x79, 0x78, 0x76, 0x75, 0x77, 0x74, 0x73, 0x76, 0x77, 0x77, 0x75, 0x76, 0x77, + 0x7a, 0x7c, 0x78, 0x7c, 0x82, 0x82, 0x7c, 0x7d, 0x83, 0x85, 0x7e, 0x80, 0x81, 0x81, 0x81, 0x83, + 0x84, 0x87, 0x85, 0x84, 0x85, 0x87, 0x88, 0x89, 0x88, 0x88, 0x8c, 0x8c, 0x88, 0x89, 0x8a, 0x88, + 0x8a, 0x89, 0x85, 0x84, 0x87, 0x86, 0x85, 0x88, 0x84, 0x82, 0x83, 0x82, 0x81, 0x83, 0x84, 0x86, + 0x80, 0x81, 0x88, 0x84, 0x82, 0x81, 0x81, 0x81, 0x80, 0x80, 0x7a, 0x79, 0x7b, 0x7c, 0x7d, 0x7b, + 0x7a, 0x7c, 0x79, 0x77, 0x77, 0x78, 0x75, 0x73, 0x78, 0x79, 0x7b, 0x7c, 0x7a, 0x7e, 0x7c, 0x7e, + 0x84, 0x7d, 0x7c, 0x7d, 0x7c, 0x7d, 0x7b, 0x78, 0x7a, 0x7c, 0x77, 0x78, 0x7d, 0x80, 0x78, 0x77, + 0x7c, 0x81, 0x81, 0x7e, 0x7c, 0x7a, 0x83, 0x7e, 0x7a, 0x7d, 0x7a, 0x7c, 0x7c, 0x7a, 0x82, 0x80, + 0x7c, 0x7e, 0x80, 0x81, 0x81, 0x81, 0x80, 0x82, 0x83, 0x80, 0x7d, 0x82, 0x7d, 0x7e, 0x86, 0x87, + 0x81, 0x81, 0x84, 0x81, 0x83, 0x86, 0x82, 0x84, 0x85, 0x7e, 0x84, 0x88, 0x86, 0x89, 0x84, 0x84, + 0x89, 0x87, 0x87, 0x87, 0x85, 0x83, 0x82, 0x83, 0x85, 0x85, 0x80, 0x83, 0x83, 0x80, 0x83, 0x84, + 0x7e, 0x7b, 0x7a, 0x7e, 0x7c, 0x7d, 0x7d, 0x7b, 0x7b, 0x7e, 0x82, 0x80, 0x80, 0x7e, 0x7d, 0x80, + 0x81, 0x80, 0x7e, 0x7d, 0x7c, 0x7d, 0x7d, 0x7b, 0x7c, 0x7d, 0x7c, 0x7b, 0x79, 0x80, 0x80, 0x79, + 0x7a, 0x7b, 0x7b, 0x79, 0x73, 0x77, 0x7d, 0x79, 0x79, 0x7e, 0x80, 0x7b, 0x7e, 0x7d, 0x7e, 0x7e, + 0x7b, 0x7d, 0x77, 0x78, 0x7e, 0x78, 0x79, 0x79, 0x78, 0x7b, 0x79, 0x7c, 0x7d, 0x7a, 0x7a, 0x7a, + 0x7d, 0x7e, 0x7d, 0x80, 0x80, 0x7e, 0x80, 0x85, 0x81, 0x7c, 0x7e, 0x81, 0x80, 0x80, 0x80, 0x7e, + 0x81, 0x80, 0x80, 0x85, 0x86, 0x85, 0x83, 0x84, 0x8a, 0x85, 0x82, 0x83, 0x83, 0x82, 0x81, 0x80, + 0x81, 0x7e, 0x81, 0x84, 0x81, 0x83, 0x86, 0x84, 0x87, 0x8a, 0x88, 0x84, 0x85, 0x83, 0x86, 0x83, + 0x83, 0x84, 0x82, 0x82, 0x7d, 0x85, 0x88, 0x81, 0x82, 0x81, 0x81, 0x82, 0x7d, 0x7c, 0x7e, 0x7e, + 0x78, 0x78, 0x80, 0x7d, 0x7a, 0x7b, 0x80, 0x7c, 0x79, 0x7d, 0x83, 0x7e, 0x7b, 0x7d, 0x82, 0x81, + 0x7c, 0x7e, 0x7c, 0x7e, 0x80, 0x7e, 0x7e, 0x81, 0x82, 0x79, 0x7b, 0x7d, 0x7d, 0x7d, 0x7a, 0x7b, + 0x7d, 0x7e, 0x80, 0x80, 0x7e, 0x7d, 0x7d, 0x80, 0x83, 0x80, 0x7b, 0x81, 0x81, 0x7e, 0x81, 0x82, + 0x83, 0x81, 0x7e, 0x81, 0x88, 0x83, 0x7d, 0x81, 0x82, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x80, 0x82, + 0x83, 0x81, 0x80, 0x7c, 0x7c, 0x7e, 0x7c, 0x77, 0x78, 0x7c, 0x7a, 0x79, 0x7d, 0x7c, 0x7b, 0x77, + 0x75, 0x7e, 0x7c, 0x7a, 0x7c, 0x7a, 0x7b, 0x7b, 0x78, 0x77, 0x78, 0x79, 0x7a, 0x76, 0x7d, 0x7d, + 0x7b, 0x7d, 0x7d, 0x81, 0x80, 0x7e, 0x82, 0x80, 0x80, 0x82, 0x85, 0x84, 0x85, 0x84, 0x81, 0x82, + 0x83, 0x84, 0x86, 0x85, 0x83, 0x83, 0x85, 0x87, 0x86, 0x83, 0x87, 0x89, 0x84, 0x82, 0x86, 0x87, + 0x82, 0x7c, 0x80, 0x85, 0x84, 0x80, 0x80, 0x82, 0x83, 0x84, 0x86, 0x86, 0x87, 0x8a, 0x87, 0x82, + 0x85, 0x86, 0x7e, 0x7d, 0x83, 0x82, 0x7c, 0x7c, 0x80, 0x7e, 0x7d, 0x7e, 0x81, 0x81, 0x80, 0x7c, + 0x7d, 0x7d, 0x79, 0x77, 0x77, 0x7a, 0x79, 0x75, 0x75, 0x77, 0x75, 0x72, 0x74, 0x77, 0x77, 0x76, + 0x77, 0x79, 0x78, 0x76, 0x78, 0x79, 0x77, 0x76, 0x78, 0x7a, 0x7b, 0x7c, 0x7a, 0x78, 0x7e, 0x7d, + 0x77, 0x79, 0x7c, 0x7a, 0x76, 0x7a, 0x7d, 0x82, 0x82, 0x7d, 0x81, 0x86, 0x88, 0x83, 0x82, 0x83, + 0x85, 0x84, 0x84, 0x87, 0x8a, 0x87, 0x87, 0x8e, 0x8b, 0x8b, 0x8b, 0x8b, 0x8c, 0x8c, 0x8c, 0x8a, + 0x8b, 0x89, 0x88, 0x8a, 0x8a, 0x8a, 0x8c, 0x8d, 0x8b, 0x85, 0x85, 0x86, 0x85, 0x82, 0x81, 0x86, + 0x85, 0x7e, 0x7b, 0x81, 0x84, 0x7c, 0x7d, 0x7c, 0x7a, 0x80, 0x7a, 0x74, 0x77, 0x7b, 0x7d, 0x75, + 0x75, 0x79, 0x76, 0x72, 0x73, 0x76, 0x75, 0x78, 0x76, 0x74, 0x75, 0x78, 0x75, 0x70, 0x6f, 0x71, + 0x73, 0x72, 0x6f, 0x72, 0x76, 0x79, 0x7b, 0x78, 0x79, 0x7c, 0x7e, 0x7b, 0x76, 0x7a, 0x7d, 0x7a, + 0x78, 0x7a, 0x7e, 0x7b, 0x7b, 0x7a, 0x7b, 0x85, 0x83, 0x7d, 0x81, 0x83, 0x85, 0x85, 0x87, 0x8b, + 0x89, 0x89, 0x88, 0x88, 0x89, 0x8a, 0x8b, 0x86, 0x84, 0x86, 0x88, 0x85, 0x83, 0x86, 0x81, 0x81, + 0x86, 0x83, 0x81, 0x85, 0x86, 0x85, 0x80, 0x81, 0x82, 0x7e, 0x7e, 0x7b, 0x7d, 0x7e, 0x7c, 0x7c, + 0x83, 0x84, 0x81, 0x80, 0x80, 0x81, 0x81, 0x7d, 0x7e, 0x80, 0x7e, 0x7c, 0x7e, 0x81, 0x7b, 0x7d, + 0x7e, 0x7c, 0x81, 0x81, 0x80, 0x7a, 0x7d, 0x80, 0x7d, 0x7c, 0x7b, 0x7c, 0x78, 0x78, 0x7a, 0x7b, + 0x79, 0x7c, 0x7c, 0x7a, 0x7c, 0x7e, 0x7d, 0x7c, 0x7e, 0x7e, 0x81, 0x7e, 0x80, 0x81, 0x82, 0x84, + 0x83, 0x81, 0x85, 0x88, 0x85, 0x83, 0x84, 0x82, 0x83, 0x81, 0x82, 0x86, 0x85, 0x82, 0x84, 0x82, + 0x81, 0x82, 0x82, 0x80, 0x7e, 0x83, 0x80, 0x81, 0x82, 0x81, 0x7e, 0x7e, 0x80, 0x80, 0x7d, 0x7d, + 0x7e, 0x7d, 0x7c, 0x7c, 0x80, 0x7e, 0x7c, 0x7c, 0x80, 0x7c, 0x7a, 0x7c, 0x80, 0x81, 0x7d, 0x7d, + 0x81, 0x7c, 0x7b, 0x7c, 0x78, 0x78, 0x79, 0x75, 0x76, 0x76, 0x74, 0x75, 0x77, 0x78, 0x78, 0x7a, + 0x7d, 0x7c, 0x7b, 0x7a, 0x7a, 0x77, 0x76, 0x77, 0x76, 0x7a, 0x7b, 0x7e, 0x81, 0x85, 0x83, 0x86, + 0x83, 0x84, 0x87, 0x85, 0x85, 0x85, 0x86, 0x84, 0x84, 0x82, 0x83, 0x85, 0x83, 0x83, 0x86, 0x86, + 0x83, 0x84, 0x84, 0x84, 0x84, 0x83, 0x81, 0x82, 0x83, 0x81, 0x81, 0x81, 0x83, 0x84, 0x85, 0x85, + 0x88, 0x85, 0x81, 0x82, 0x83, 0x81, 0x7d, 0x83, 0x84, 0x81, 0x80, 0x7e, 0x80, 0x7d, 0x7b, 0x7d, + 0x7b, 0x79, 0x7b, 0x79, 0x7a, 0x79, 0x79, 0x78, 0x7b, 0x80, 0x7d, 0x79, 0x7c, 0x7b, 0x7a, 0x7c, + 0x7b, 0x7d, 0x7b, 0x7a, 0x79, 0x7a, 0x7d, 0x7b, 0x7b, 0x7b, 0x7e, 0x81, 0x7d, 0x7e, 0x7e, 0x7d, + 0x7c, 0x7b, 0x7b, 0x7d, 0x7b, 0x7e, 0x81, 0x7d, 0x7e, 0x84, 0x83, 0x80, 0x7e, 0x82, 0x81, 0x7e, + 0x7d, 0x7e, 0x81, 0x82, 0x7d, 0x7a, 0x82, 0x85, 0x80, 0x7e, 0x83, 0x82, 0x82, 0x7e, 0x80, 0x80, + 0x7e, 0x80, 0x7e, 0x80, 0x7e, 0x80, 0x81, 0x81, 0x83, 0x83, 0x85, 0x86, 0x83, 0x83, 0x84, 0x86, + 0x85, 0x83, 0x82, 0x82, 0x84, 0x82, 0x81, 0x81, 0x84, 0x83, 0x7e, 0x80, 0x80, 0x81, 0x83, 0x7c, + 0x7c, 0x82, 0x80, 0x80, 0x83, 0x81, 0x7e, 0x81, 0x83, 0x81, 0x7d, 0x7d, 0x84, 0x81, 0x7d, 0x82, + 0x82, 0x82, 0x81, 0x83, 0x83, 0x80, 0x80, 0x7c, 0x7a, 0x7d, 0x7b, 0x76, 0x76, 0x7b, 0x7c, 0x76, + 0x77, 0x79, 0x78, 0x7a, 0x79, 0x7a, 0x7b, 0x77, 0x75, 0x75, 0x79, 0x79, 0x75, 0x76, 0x79, 0x79, + 0x79, 0x77, 0x77, 0x7a, 0x7c, 0x7a, 0x7b, 0x7d, 0x7d, 0x7c, 0x7d, 0x7d, 0x7e, 0x7e, 0x7d, 0x7b, + 0x7e, 0x81, 0x7e, 0x7b, 0x7e, 0x82, 0x83, 0x84, 0x7e, 0x7e, 0x81, 0x82, 0x83, 0x82, 0x81, 0x80, + 0x81, 0x82, 0x81, 0x83, 0x83, 0x81, 0x7d, 0x81, 0x84, 0x82, 0x83, 0x86, 0x84, 0x84, 0x84, 0x83, + 0x86, 0x85, 0x84, 0x82, 0x85, 0x88, 0x86, 0x84, 0x87, 0x88, 0x87, 0x87, 0x88, 0x88, 0x88, 0x84, + 0x83, 0x86, 0x86, 0x80, 0x80, 0x81, 0x7e, 0x7c, 0x7b, 0x7e, 0x7a, 0x79, 0x7c, 0x79, 0x7c, 0x7d, + 0x7b, 0x7d, 0x7d, 0x7e, 0x7d, 0x7c, 0x80, 0x80, 0x7e, 0x82, 0x7d, 0x7b, 0x80, 0x7d, 0x80, 0x80, + 0x7c, 0x7d, 0x81, 0x7e, 0x7a, 0x7b, 0x7d, 0x7b, 0x79, 0x7a, 0x7e, 0x7a, 0x76, 0x74, 0x79, 0x7e, + 0x7b, 0x78, 0x79, 0x7e, 0x7e, 0x7a, 0x7a, 0x7c, 0x7d, 0x7c, 0x7c, 0x7e, 0x7d, 0x80, 0x83, 0x84, + 0x80, 0x83, 0x84, 0x84, 0x81, 0x80, 0x82, 0x83, 0x83, 0x82, 0x81, 0x83, 0x82, 0x80, 0x80, 0x82, + 0x83, 0x80, 0x7d, 0x7d, 0x84, 0x88, 0x82, 0x80, 0x82, 0x80, 0x81, 0x82, 0x7e, 0x7e, 0x80, 0x80, + 0x7e, 0x7d, 0x80, 0x7e, 0x77, 0x7a, 0x7e, 0x7d, 0x79, 0x79, 0x7b, 0x7b, 0x7b, 0x81, 0x7c, 0x79, + 0x7b, 0x7c, 0x7a, 0x7c, 0x80, 0x7c, 0x79, 0x79, 0x7b, 0x80, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, + 0x7b, 0x79, 0x7b, 0x7b, 0x7c, 0x81, 0x84, 0x85, 0x80, 0x7e, 0x84, 0x87, 0x88, 0x83, 0x82, 0x83, + 0x83, 0x83, 0x84, 0x84, 0x84, 0x86, 0x83, 0x85, 0x84, 0x84, 0x84, 0x85, 0x86, 0x87, 0x86, 0x84, + 0x83, 0x83, 0x83, 0x82, 0x83, 0x7e, 0x80, 0x81, 0x7c, 0x7c, 0x7c, 0x7b, 0x7d, 0x7c, 0x7b, 0x7b, + 0x7a, 0x7c, 0x79, 0x7b, 0x7e, 0x79, 0x7b, 0x7b, 0x7b, 0x7b, 0x7a, 0x79, 0x77, 0x76, 0x77, 0x78, + 0x76, 0x76, 0x7a, 0x7b, 0x7b, 0x80, 0x7d, 0x7b, 0x79, 0x7a, 0x7b, 0x7c, 0x79, 0x79, 0x7c, 0x7d, + 0x7d, 0x7e, 0x81, 0x80, 0x7c, 0x7e, 0x83, 0x82, 0x81, 0x81, 0x81, 0x84, 0x80, 0x81, 0x85, 0x85, + 0x84, 0x83, 0x85, 0x87, 0x86, 0x87, 0x89, 0x85, 0x8b, 0x8b, 0x85, 0x85, 0x85, 0x83, 0x80, 0x83, + 0x87, 0x84, 0x81, 0x84, 0x86, 0x84, 0x83, 0x85, 0x86, 0x81, 0x82, 0x86, 0x83, 0x83, 0x85, 0x86, + 0x86, 0x84, 0x83, 0x81, 0x7e, 0x7e, 0x80, 0x7b, 0x79, 0x7c, 0x79, 0x79, 0x7c, 0x7b, 0x7a, 0x79, + 0x7c, 0x7c, 0x7a, 0x78, 0x79, 0x78, 0x79, 0x7c, 0x7b, 0x78, 0x76, 0x77, 0x79, 0x77, 0x79, 0x78, + 0x74, 0x79, 0x79, 0x77, 0x77, 0x77, 0x76, 0x74, 0x77, 0x7a, 0x79, 0x76, 0x77, 0x7a, 0x79, 0x7a, + 0x7c, 0x7e, 0x7d, 0x7d, 0x80, 0x7d, 0x7c, 0x80, 0x80, 0x7c, 0x7e, 0x84, 0x86, 0x83, 0x83, 0x84, + 0x83, 0x85, 0x86, 0x84, 0x84, 0x84, 0x83, 0x83, 0x81, 0x84, 0x86, 0x83, 0x81, 0x83, 0x83, 0x80, + 0x7e, 0x81, 0x81, 0x81, 0x82, 0x83, 0x84, 0x82, 0x80, 0x81, 0x82, 0x83, 0x8a, 0x87, 0x80, 0x81, + 0x85, 0x88, 0x82, 0x82, 0x82, 0x7e, 0x81, 0x80, 0x82, 0x83, 0x82, 0x7e, 0x7e, 0x80, 0x81, 0x7d, + 0x7b, 0x7c, 0x7d, 0x7e, 0x7b, 0x78, 0x7a, 0x7d, 0x7e, 0x80, 0x7d, 0x80, 0x7d, 0x7c, 0x7d, 0x7d, + 0x7e, 0x80, 0x7e, 0x80, 0x7e, 0x80, 0x81, 0x80, 0x7e, 0x7e, 0x82, 0x84, 0x7b, 0x79, 0x7e, 0x7d, + 0x7c, 0x7c, 0x7d, 0x82, 0x81, 0x80, 0x80, 0x81, 0x82, 0x7e, 0x80, 0x80, 0x81, 0x83, 0x82, 0x82, + 0x82, 0x81, 0x7d, 0x7e, 0x7c, 0x7d, 0x80, 0x80, 0x80, 0x80, 0x7d, 0x7e, 0x7e, 0x7b, 0x7a, 0x81, + 0x80, 0x7c, 0x7a, 0x7d, 0x80, 0x7e, 0x7d, 0x80, 0x82, 0x81, 0x7e, 0x7c, 0x7c, 0x7d, 0x7d, 0x7c, + 0x7c, 0x80, 0x7d, 0x78, 0x7a, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b, 0x79, 0x78, 0x7d, 0x7c, 0x7b, 0x7c, + 0x7b, 0x7c, 0x7c, 0x7c, 0x80, 0x7e, 0x7d, 0x80, 0x82, 0x81, 0x83, 0x83, 0x80, 0x82, 0x83, 0x82, + 0x80, 0x83, 0x85, 0x83, 0x81, 0x86, 0x85, 0x83, 0x82, 0x7e, 0x7e, 0x80, 0x7e, 0x81, 0x7e, 0x7c, + 0x80, 0x80, 0x83, 0x83, 0x82, 0x81, 0x81, 0x83, 0x84, 0x83, 0x81, 0x83, 0x83, 0x83, 0x85, 0x82, + 0x7e, 0x7e, 0x80, 0x7e, 0x82, 0x81, 0x7c, 0x7e, 0x81, 0x7d, 0x80, 0x82, 0x82, 0x80, 0x81, 0x80, + 0x7d, 0x7c, 0x7b, 0x7e, 0x7e, 0x7e, 0x7e, 0x7b, 0x80, 0x7e, 0x7a, 0x7b, 0x7c, 0x7d, 0x7d, 0x7b, + 0x7c, 0x7c, 0x7a, 0x7e, 0x7d, 0x7c, 0x7d, 0x79, 0x7b, 0x80, 0x7e, 0x7c, 0x7d, 0x7c, 0x80, 0x7d, + 0x7b, 0x7d, 0x80, 0x7c, 0x7e, 0x83, 0x80, 0x81, 0x82, 0x82, 0x84, 0x84, 0x82, 0x82, 0x82, 0x81, + 0x84, 0x82, 0x7e, 0x80, 0x80, 0x82, 0x80, 0x7c, 0x7a, 0x7b, 0x7d, 0x80, 0x7d, 0x7d, 0x82, 0x82, + 0x7d, 0x80, 0x81, 0x81, 0x81, 0x80, 0x84, 0x85, 0x83, 0x84, 0x84, 0x82, 0x87, 0x89, 0x83, 0x82, + 0x86, 0x84, 0x81, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7d, 0x80, 0x80, 0x80, 0x81, 0x7e, 0x80, 0x84, + 0x83, 0x7e, 0x80, 0x81, 0x81, 0x80, 0x7d, 0x81, 0x83, 0x80, 0x7d, 0x81, 0x83, 0x80, 0x80, 0x7d, + 0x80, 0x81, 0x7e, 0x80, 0x81, 0x7d, 0x7b, 0x7e, 0x7d, 0x7c, 0x7a, 0x7a, 0x78, 0x7a, 0x7b, 0x78, + 0x75, 0x72, 0x74, 0x75, 0x77, 0x7a, 0x7a, 0x78, 0x79, 0x7d, 0x7d, 0x7a, 0x7a, 0x7c, 0x7b, 0x7b, + 0x7a, 0x7a, 0x78, 0x77, 0x79, 0x78, 0x7a, 0x7a, 0x77, 0x7b, 0x7b, 0x78, 0x7b, 0x7c, 0x7a, 0x7a, + 0x7b, 0x7d, 0x7d, 0x7b, 0x7c, 0x80, 0x81, 0x82, 0x82, 0x83, 0x83, 0x84, 0x81, 0x83, 0x85, 0x84, + 0x84, 0x82, 0x83, 0x86, 0x87, 0x84, 0x83, 0x87, 0x88, 0x88, 0x89, 0x8a, 0x88, 0x88, 0x89, 0x86, + 0x85, 0x88, 0x84, 0x83, 0x89, 0x89, 0x88, 0x86, 0x84, 0x86, 0x85, 0x83, 0x82, 0x83, 0x80, 0x80, + 0x82, 0x82, 0x82, 0x83, 0x82, 0x7e, 0x82, 0x83, 0x80, 0x7e, 0x7e, 0x7e, 0x7d, 0x7e, 0x7d, 0x7b, + 0x7c, 0x7d, 0x7d, 0x7a, 0x7b, 0x81, 0x80, 0x7a, 0x7b, 0x7c, 0x7a, 0x7b, 0x7a, 0x78, 0x7b, 0x7b, + 0x78, 0x7b, 0x7b, 0x79, 0x7d, 0x7c, 0x7b, 0x7c, 0x7d, 0x7a, 0x7b, 0x7b, 0x7a, 0x7c, 0x7c, 0x78, + 0x79, 0x7b, 0x7c, 0x80, 0x80, 0x7c, 0x7e, 0x80, 0x7e, 0x7c, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, + 0x80, 0x7e, 0x7e, 0x83, 0x83, 0x80, 0x82, 0x82, 0x81, 0x84, 0x85, 0x81, 0x83, 0x81, 0x81, 0x84, + 0x84, 0x82, 0x84, 0x85, 0x84, 0x83, 0x83, 0x83, 0x83, 0x80, 0x7e, 0x80, 0x7e, 0x7e, 0x80, 0x7d, + 0x7d, 0x7e, 0x7c, 0x7a, 0x7c, 0x81, 0x7e, 0x7b, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7d, + 0x7e, 0x7e, 0x7e, 0x7b, 0x7b, 0x7b, 0x7a, 0x7b, 0x78, 0x78, 0x7a, 0x7a, 0x79, 0x79, 0x7c, 0x7e, + 0x7c, 0x7d, 0x7e, 0x7b, 0x7a, 0x7d, 0x82, 0x7d, 0x7e, 0x82, 0x82, 0x80, 0x7e, 0x83, 0x83, 0x84, + 0x87, 0x88, 0x85, 0x82, 0x83, 0x83, 0x83, 0x81, 0x81, 0x82, 0x82, 0x81, 0x83, 0x82, 0x84, 0x84, + 0x82, 0x82, 0x84, 0x83, 0x7d, 0x80, 0x82, 0x81, 0x82, 0x80, 0x7d, 0x81, 0x81, 0x82, 0x82, 0x80, + 0x80, 0x80, 0x80, 0x81, 0x81, 0x7e, 0x7d, 0x7e, 0x7e, 0x7c, 0x7c, 0x7d, 0x7b, 0x7b, 0x7b, 0x79, + 0x7b, 0x7b, 0x79, 0x7a, 0x79, 0x7a, 0x7e, 0x7c, 0x7b, 0x7d, 0x7d, 0x7a, 0x7b, 0x7d, 0x7b, 0x7b, + 0x79, 0x7a, 0x7d, 0x7d, 0x7c, 0x7d, 0x7e, 0x7e, 0x82, 0x85, 0x84, 0x83, 0x82, 0x84, 0x85, 0x85, + 0x84, 0x85, 0x86, 0x85, 0x84, 0x88, 0x86, 0x86, 0x87, 0x87, 0x88, 0x8b, 0x8b, 0x86, 0x85, 0x87, + 0x84, 0x84, 0x86, 0x81, 0x82, 0x81, 0x81, 0x81, 0x7e, 0x80, 0x82, 0x82, 0x7e, 0x83, 0x83, 0x81, + 0x82, 0x81, 0x80, 0x81, 0x83, 0x80, 0x7c, 0x7d, 0x7d, 0x7c, 0x7b, 0x7b, 0x7a, 0x79, 0x78, 0x7b, + 0x7b, 0x79, 0x78, 0x7a, 0x76, 0x78, 0x7a, 0x76, 0x76, 0x76, 0x76, 0x75, 0x77, 0x79, 0x78, 0x77, + 0x7a, 0x7a, 0x79, 0x7a, 0x7c, 0x7b, 0x79, 0x7d, 0x80, 0x7c, 0x79, 0x7e, 0x80, 0x7b, 0x7c, 0x7c, + 0x7d, 0x7d, 0x7b, 0x7d, 0x80, 0x7e, 0x7e, 0x7d, 0x7c, 0x7e, 0x7e, 0x7c, 0x7c, 0x7e, 0x80, 0x80, + 0x80, 0x81, 0x83, 0x82, 0x81, 0x83, 0x84, 0x85, 0x84, 0x82, 0x82, 0x85, 0x86, 0x85, 0x87, 0x84, + 0x83, 0x85, 0x85, 0x7e, 0x7e, 0x83, 0x83, 0x83, 0x82, 0x83, 0x86, 0x85, 0x84, 0x85, 0x85, 0x85, + 0x82, 0x82, 0x84, 0x83, 0x84, 0x82, 0x82, 0x84, 0x84, 0x83, 0x82, 0x80, 0x81, 0x85, 0x82, 0x80, + 0x81, 0x82, 0x82, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x80, 0x7e, 0x7b, 0x7d, 0x82, + 0x7e, 0x7b, 0x7e, 0x81, 0x80, 0x7d, 0x7b, 0x7d, 0x7c, 0x7e, 0x7e, 0x7b, 0x7b, 0x7b, 0x7d, 0x7b, + 0x7d, 0x7d, 0x7b, 0x79, 0x79, 0x7c, 0x7c, 0x7b, 0x7a, 0x7b, 0x7b, 0x7d, 0x7c, 0x7b, 0x7e, 0x7d, + 0x80, 0x81, 0x80, 0x82, 0x81, 0x7b, 0x7e, 0x81, 0x7e, 0x80, 0x7d, 0x7d, 0x7d, 0x7b, 0x7e, 0x7e, + 0x7d, 0x7b, 0x7c, 0x7e, 0x7d, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, 0x7d, 0x7c, 0x7d, 0x7c, + 0x7e, 0x80, 0x7d, 0x7e, 0x7d, 0x7c, 0x7c, 0x7d, 0x81, 0x7e, 0x7d, 0x7e, 0x7e, 0x81, 0x80, 0x7d, + 0x81, 0x80, 0x7e, 0x81, 0x82, 0x80, 0x82, 0x84, 0x82, 0x84, 0x84, 0x82, 0x83, 0x82, 0x80, 0x82, + 0x83, 0x81, 0x7e, 0x7d, 0x7e, 0x82, 0x82, 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x82, 0x81, 0x7d, + 0x7c, 0x7d, 0x80, 0x82, 0x81, 0x7d, 0x7e, 0x82, 0x82, 0x82, 0x81, 0x80, 0x81, 0x82, 0x81, 0x7e, + 0x7e, 0x7e, 0x7d, 0x7c, 0x7d, 0x81, 0x7c, 0x7b, 0x7c, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7c, + 0x7e, 0x7d, 0x7c, 0x7c, 0x7d, 0x7b, 0x7c, 0x80, 0x7e, 0x7e, 0x81, 0x82, 0x81, 0x83, 0x84, 0x82, + 0x80, 0x82, 0x83, 0x83, 0x83, 0x81, 0x80, 0x83, 0x82, 0x82, 0x81, 0x7d, 0x80, 0x81, 0x7e, 0x7e, + 0x7d, 0x7e, 0x7e, 0x81, 0x82, 0x82, 0x85, 0x81, 0x7e, 0x82, 0x83, 0x82, 0x80, 0x82, 0x83, 0x81, + 0x82, 0x81, 0x81, 0x83, 0x80, 0x81, 0x83, 0x80, 0x7d, 0x7e, 0x7e, 0x7e, 0x7d, 0x7c, 0x80, 0x82, + 0x7e, 0x80, 0x82, 0x81, 0x7e, 0x81, 0x83, 0x84, 0x82, 0x82, 0x84, 0x83, 0x7e, 0x7d, 0x81, 0x81, + 0x80, 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7c, 0x7c, 0x7e, 0x7e, 0x7d, 0x7c, 0x7c, + 0x80, 0x7e, 0x7d, 0x7e, 0x7e, 0x7e, 0x80, 0x82, 0x83, 0x80, 0x7e, 0x81, 0x83, 0x81, 0x7d, 0x80, + 0x7d, 0x7c, 0x7c, 0x7b, 0x7d, 0x7c, 0x79, 0x78, 0x78, 0x78, 0x79, 0x78, 0x7a, 0x7a, 0x79, 0x7a, + 0x7a, 0x7b, 0x7b, 0x7b, 0x7c, 0x7d, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x79, 0x7b, 0x7e, 0x7b, 0x79, + 0x7b, 0x7c, 0x7d, 0x7b, 0x78, 0x7b, 0x7c, 0x78, 0x78, 0x7a, 0x78, 0x78, 0x7a, 0x7c, 0x7b, 0x7b, + 0x7c, 0x7d, 0x80, 0x80, 0x80, 0x80, 0x80, 0x82, 0x84, 0x83, 0x85, 0x88, 0x86, 0x86, 0x88, 0x89, + 0x84, 0x84, 0x88, 0x87, 0x85, 0x85, 0x85, 0x84, 0x84, 0x85, 0x85, 0x85, 0x84, 0x83, 0x85, 0x87, + 0x87, 0x84, 0x84, 0x87, 0x88, 0x88, 0x86, 0x87, 0x88, 0x87, 0x85, 0x87, 0x87, 0x85, 0x83, 0x82, + 0x83, 0x86, 0x84, 0x81, 0x81, 0x82, 0x82, 0x81, 0x81, 0x83, 0x81, 0x7d, 0x80, 0x80, 0x7c, 0x7d, + 0x7e, 0x7a, 0x79, 0x7b, 0x7d, 0x7c, 0x7a, 0x78, 0x78, 0x79, 0x7b, 0x78, 0x75, 0x75, 0x77, 0x78, + 0x76, 0x78, 0x79, 0x76, 0x76, 0x77, 0x7a, 0x7b, 0x78, 0x78, 0x7b, 0x7d, 0x7e, 0x80, 0x7d, 0x7b, + 0x7c, 0x7b, 0x7c, 0x7e, 0x7a, 0x7b, 0x80, 0x7e, 0x7d, 0x7e, 0x80, 0x7e, 0x7d, 0x7d, 0x80, 0x7e, + 0x80, 0x81, 0x7d, 0x80, 0x82, 0x7e, 0x80, 0x80, 0x7e, 0x7d, 0x7d, 0x81, 0x81, 0x81, 0x82, 0x84, + 0x85, 0x84, 0x86, 0x88, 0x86, 0x82, 0x83, 0x85, 0x84, 0x82, 0x7d, 0x7d, 0x82, 0x81, 0x7c, 0x7c, + 0x80, 0x82, 0x80, 0x80, 0x80, 0x82, 0x80, 0x7d, 0x81, 0x82, 0x80, 0x80, 0x7d, 0x7c, 0x80, 0x80, + 0x7c, 0x7d, 0x7c, 0x7c, 0x7d, 0x7c, 0x7b, 0x7a, 0x7a, 0x7e, 0x7c, 0x79, 0x7b, 0x7c, 0x7d, 0x7a, + 0x7d, 0x80, 0x7d, 0x7c, 0x7c, 0x7e, 0x7d, 0x7b, 0x7c, 0x7d, 0x81, 0x7e, 0x7b, 0x7d, 0x7e, 0x80, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, 0x81, 0x7e, 0x7d, 0x80, 0x80, 0x80, 0x81, 0x81, + 0x81, 0x82, 0x83, 0x80, 0x80, 0x81, 0x81, 0x81, 0x82, 0x80, 0x81, 0x81, 0x82, 0x80, 0x81, 0x82, + 0x82, 0x82, 0x81, 0x82, 0x84, 0x81, 0x80, 0x81, 0x81, 0x7e, 0x7d, 0x81, 0x80, 0x7e, 0x81, 0x7e, + 0x7e, 0x7e, 0x7d, 0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b, 0x7e, 0x7e, 0x7d, 0x80, 0x7d, 0x7c, 0x7c, + 0x7d, 0x81, 0x81, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x7e, 0x80, 0x83, 0x82, 0x82, 0x84, 0x82, + 0x81, 0x82, 0x83, 0x84, 0x82, 0x82, 0x83, 0x81, 0x81, 0x82, 0x82, 0x82, 0x81, 0x81, 0x84, 0x84, + 0x82, 0x81, 0x81, 0x85, 0x83, 0x80, 0x81, 0x81, 0x80, 0x7e, 0x81, 0x81, 0x82, 0x80, 0x7c, 0x7d, + 0x7e, 0x7b, 0x7b, 0x7c, 0x7a, 0x7b, 0x7a, 0x7c, 0x7b, 0x78, 0x7a, 0x7b, 0x79, 0x7a, 0x79, 0x78, + 0x79, 0x78, 0x79, 0x78, 0x78, 0x77, 0x76, 0x74, 0x77, 0x79, 0x79, 0x79, 0x78, 0x7a, 0x78, 0x7a, + 0x7b, 0x7b, 0x7b, 0x7a, 0x7c, 0x7c, 0x7c, 0x7d, 0x7e, 0x7d, 0x80, 0x7e, 0x81, 0x82, 0x7d, 0x80, + 0x82, 0x7e, 0x80, 0x81, 0x7e, 0x7e, 0x80, 0x80, 0x7e, 0x82, 0x82, 0x7e, 0x81, 0x83, 0x82, 0x82, + 0x82, 0x83, 0x85, 0x81, 0x82, 0x83, 0x85, 0x85, 0x82, 0x84, 0x85, 0x84, 0x86, 0x83, 0x83, 0x87, + 0x83, 0x81, 0x81, 0x82, 0x82, 0x82, 0x82, 0x84, 0x84, 0x85, 0x86, 0x81, 0x81, 0x85, 0x83, 0x7e, + 0x80, 0x82, 0x81, 0x81, 0x82, 0x83, 0x82, 0x83, 0x85, 0x83, 0x82, 0x84, 0x86, 0x82, 0x81, 0x82, + 0x83, 0x83, 0x83, 0x81, 0x80, 0x80, 0x82, 0x81, 0x7c, 0x7e, 0x81, 0x7d, 0x7c, 0x7e, 0x7e, 0x7a, + 0x79, 0x7c, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7a, 0x7d, 0x7d, 0x78, 0x7a, 0x7c, 0x7a, + 0x79, 0x78, 0x7b, 0x7e, 0x7d, 0x7d, 0x7e, 0x7b, 0x7b, 0x7b, 0x7b, 0x7c, 0x7b, 0x79, 0x7a, 0x7b, + 0x7a, 0x79, 0x7b, 0x7c, 0x7d, 0x7c, 0x7d, 0x80, 0x7c, 0x7a, 0x7a, 0x7d, 0x7d, 0x7b, 0x7c, 0x7c, + 0x7c, 0x7d, 0x80, 0x7e, 0x7e, 0x7e, 0x7c, 0x7d, 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x7d, 0x80, + 0x82, 0x7e, 0x7c, 0x81, 0x83, 0x80, 0x7d, 0x81, 0x81, 0x82, 0x84, 0x81, 0x7e, 0x81, 0x80, 0x80, + 0x80, 0x81, 0x83, 0x81, 0x83, 0x83, 0x82, 0x83, 0x81, 0x80, 0x80, 0x82, 0x84, 0x82, 0x81, 0x82, + 0x82, 0x85, 0x83, 0x81, 0x82, 0x82, 0x82, 0x81, 0x81, 0x82, 0x81, 0x7e, 0x7d, 0x80, 0x83, 0x81, + 0x7c, 0x7c, 0x80, 0x80, 0x7d, 0x7b, 0x7e, 0x80, 0x7e, 0x7c, 0x7c, 0x7d, 0x7c, 0x7b, 0x7b, 0x7d, + 0x7e, 0x7e, 0x7a, 0x7b, 0x7e, 0x7d, 0x7a, 0x7b, 0x7d, 0x7c, 0x7a, 0x78, 0x79, 0x7b, 0x7b, 0x7c, + 0x7c, 0x7d, 0x7c, 0x7d, 0x7b, 0x7c, 0x7e, 0x80, 0x80, 0x80, 0x81, 0x83, 0x84, 0x84, 0x83, 0x82, + 0x84, 0x85, 0x82, 0x81, 0x83, 0x85, 0x84, 0x81, 0x83, 0x84, 0x81, 0x7e, 0x82, 0x85, 0x83, 0x82, + 0x83, 0x83, 0x86, 0x86, 0x83, 0x83, 0x84, 0x82, 0x7e, 0x82, 0x82, 0x81, 0x7e, 0x81, 0x83, 0x83, + 0x81, 0x7e, 0x7d, 0x80, 0x7d, 0x7e, 0x80, 0x81, 0x80, 0x7e, 0x80, 0x80, 0x7d, 0x7e, 0x81, 0x80, + 0x7d, 0x80, 0x7d, 0x7d, 0x7d, 0x7b, 0x7d, 0x80, 0x7c, 0x7b, 0x7c, 0x7e, 0x7c, 0x7a, 0x7c, 0x80, + 0x7e, 0x79, 0x7b, 0x80, 0x7d, 0x7c, 0x7c, 0x7d, 0x7e, 0x80, 0x7e, 0x7d, 0x80, 0x7d, 0x7b, 0x7d, + 0x81, 0x80, 0x7d, 0x7e, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7c, 0x7d, 0x80, 0x7b, 0x79, 0x79, + 0x7a, 0x7a, 0x79, 0x79, 0x7b, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7c, 0x7b, 0x7c, 0x7e, 0x7e, 0x7b, + 0x7c, 0x7e, 0x7e, 0x7d, 0x7e, 0x82, 0x82, 0x7e, 0x7d, 0x7d, 0x80, 0x7d, 0x7a, 0x7c, 0x7c, 0x79, + 0x7b, 0x7c, 0x7a, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7c, 0x7d, 0x7c, 0x7c, 0x7e, 0x7e, 0x7e, 0x81, + 0x7e, 0x81, 0x81, 0x82, 0x81, 0x80, 0x84, 0x83, 0x83, 0x84, 0x85, 0x86, 0x85, 0x86, 0x85, 0x85, + 0x87, 0x88, 0x88, 0x8a, 0x8b, 0x88, 0x86, 0x87, 0x89, 0x85, 0x84, 0x86, 0x84, 0x82, 0x83, 0x84, + 0x84, 0x83, 0x84, 0x85, 0x85, 0x85, 0x84, 0x83, 0x85, 0x87, 0x84, 0x84, 0x85, 0x85, 0x85, 0x83, + 0x80, 0x81, 0x81, 0x7e, 0x80, 0x80, 0x80, 0x7d, 0x7c, 0x7e, 0x7e, 0x7e, 0x7c, 0x7b, 0x7b, 0x7a, + 0x7b, 0x7b, 0x79, 0x79, 0x7a, 0x79, 0x79, 0x7b, 0x77, 0x75, 0x77, 0x74, 0x73, 0x76, 0x76, 0x78, + 0x76, 0x75, 0x79, 0x79, 0x77, 0x77, 0x7a, 0x7a, 0x79, 0x7b, 0x7d, 0x7c, 0x7a, 0x7c, 0x7c, 0x7b, + 0x7e, 0x7d, 0x7a, 0x7a, 0x7d, 0x7e, 0x7b, 0x7c, 0x7e, 0x7a, 0x7a, 0x7e, 0x81, 0x7d, 0x7d, 0x81, + 0x82, 0x83, 0x83, 0x83, 0x83, 0x85, 0x84, 0x83, 0x83, 0x84, 0x81, 0x82, 0x86, 0x87, 0x82, 0x83, + 0x83, 0x83, 0x84, 0x83, 0x83, 0x83, 0x81, 0x82, 0x83, 0x82, 0x81, 0x82, 0x83, 0x82, 0x83, 0x86, + 0x83, 0x81, 0x82, 0x81, 0x7e, 0x7e, 0x80, 0x7e, 0x7d, 0x80, 0x7e, 0x7c, 0x7e, 0x80, 0x80, 0x7d, + 0x7d, 0x82, 0x82, 0x7d, 0x7c, 0x7c, 0x7b, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b, 0x7b, 0x79, 0x7a, 0x7c, + 0x7b, 0x7a, 0x7a, 0x7d, 0x80, 0x7b, 0x7a, 0x7d, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, + 0x80, 0x7e, 0x7e, 0x81, 0x7e, 0x7b, 0x7d, 0x7c, 0x7c, 0x7e, 0x82, 0x82, 0x82, 0x83, 0x82, 0x83, + 0x83, 0x83, 0x81, 0x7d, 0x80, 0x82, 0x81, 0x80, 0x82, 0x84, 0x82, 0x80, 0x82, 0x84, 0x84, 0x81, + 0x82, 0x83, 0x83, 0x80, 0x80, 0x82, 0x83, 0x80, 0x81, 0x82, 0x82, 0x81, 0x81, 0x83, 0x85, 0x84, + 0x82, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7d, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x7e, 0x7c, 0x80, + 0x80, 0x7c, 0x7d, 0x80, 0x7d, 0x7d, 0x82, 0x83, 0x7d, 0x7d, 0x81, 0x83, 0x7e, 0x7e, 0x81, 0x7e, + 0x7c, 0x7c, 0x7e, 0x7d, 0x7d, 0x7e, 0x81, 0x81, 0x81, 0x80, 0x81, 0x80, 0x82, 0x83, 0x80, 0x7e, + 0x80, 0x80, 0x7c, 0x7c, 0x82, 0x81, 0x7e, 0x81, 0x81, 0x7e, 0x7e, 0x7d, 0x7b, 0x7b, 0x7c, 0x7b, + 0x79, 0x7a, 0x7a, 0x7b, 0x7c, 0x7b, 0x7b, 0x7c, 0x7c, 0x7d, 0x79, 0x79, 0x7d, 0x7d, 0x7a, 0x78, + 0x79, 0x7a, 0x78, 0x77, 0x79, 0x79, 0x7b, 0x79, 0x7a, 0x7c, 0x7d, 0x7b, 0x7b, 0x7d, 0x7d, 0x7d, + 0x7e, 0x7d, 0x7d, 0x7e, 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x7e, 0x7e, 0x80, + 0x80, 0x80, 0x81, 0x82, 0x81, 0x80, 0x82, 0x82, 0x84, 0x85, 0x83, 0x84, 0x86, 0x85, 0x85, 0x86, + 0x86, 0x84, 0x85, 0x85, 0x85, 0x85, 0x82, 0x84, 0x86, 0x82, 0x84, 0x84, 0x81, 0x82, 0x84, 0x81, + 0x83, 0x85, 0x83, 0x82, 0x83, 0x84, 0x83, 0x81, 0x7e, 0x7e, 0x81, 0x7c, 0x7d, 0x82, 0x7d, 0x7e, + 0x83, 0x83, 0x80, 0x81, 0x82, 0x82, 0x81, 0x84, 0x83, 0x83, 0x84, 0x83, 0x82, 0x81, 0x84, 0x82, + 0x7e, 0x80, 0x81, 0x81, 0x7e, 0x80, 0x80, 0x7d, 0x80, 0x80, 0x7e, 0x80, 0x7e, 0x7c, 0x7c, 0x7c, + 0x7c, 0x7d, 0x7c, 0x78, 0x79, 0x7a, 0x7a, 0x7a, 0x78, 0x79, 0x7a, 0x79, 0x79, 0x79, 0x79, 0x7a, + 0x78, 0x7a, 0x7b, 0x7a, 0x7c, 0x7c, 0x7c, 0x7d, 0x7e, 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7c, 0x7d, + 0x7d, 0x7c, 0x7b, 0x7b, 0x7c, 0x7b, 0x7d, 0x7b, 0x7a, 0x7c, 0x7a, 0x7b, 0x80, 0x7e, 0x7d, 0x7e, + 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7d, 0x7e, 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x81, 0x81, 0x7e, + 0x80, 0x81, 0x82, 0x81, 0x81, 0x82, 0x82, 0x82, 0x83, 0x83, 0x83, 0x82, 0x81, 0x84, 0x85, 0x85, + 0x85, 0x83, 0x83, 0x86, 0x85, 0x83, 0x83, 0x83, 0x83, 0x83, 0x82, 0x83, 0x84, 0x83, 0x83, 0x83, + 0x85, 0x84, 0x83, 0x82, 0x81, 0x82, 0x80, 0x80, 0x82, 0x7e, 0x7d, 0x80, 0x7c, 0x7c, 0x7c, 0x7b, + 0x7b, 0x7c, 0x7d, 0x7d, 0x7d, 0x80, 0x80, 0x7d, 0x7c, 0x7e, 0x7b, 0x7a, 0x7d, 0x7c, 0x7b, 0x7a, + 0x7b, 0x7c, 0x7b, 0x7a, 0x7a, 0x7b, 0x7b, 0x78, 0x7a, 0x7d, 0x7d, 0x7b, 0x7b, 0x7c, 0x7b, 0x7c, + 0x7d, 0x7d, 0x80, 0x7c, 0x7d, 0x81, 0x82, 0x81, 0x80, 0x81, 0x81, 0x81, 0x81, 0x82, 0x80, 0x81, + 0x83, 0x83, 0x83, 0x85, 0x84, 0x81, 0x84, 0x85, 0x84, 0x83, 0x85, 0x86, 0x85, 0x84, 0x86, 0x86, + 0x84, 0x83, 0x84, 0x86, 0x83, 0x82, 0x84, 0x84, 0x80, 0x81, 0x82, 0x82, 0x80, 0x7e, 0x82, 0x83, + 0x80, 0x80, 0x81, 0x82, 0x80, 0x80, 0x81, 0x7e, 0x80, 0x7e, 0x7c, 0x7e, 0x81, 0x80, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7d, 0x7c, 0x7c, 0x7b, 0x7a, 0x7b, 0x7d, 0x7b, 0x7c, 0x7b, 0x7b, 0x7c, 0x7c, 0x7a, + 0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7b, 0x7a, 0x79, 0x79, 0x7a, 0x78, 0x78, 0x7a, 0x7a, 0x7a, 0x7c, + 0x7e, 0x7d, 0x7e, 0x81, 0x80, 0x7e, 0x80, 0x7d, 0x7c, 0x7d, 0x7c, 0x7b, 0x7c, 0x80, 0x80, 0x7d, + 0x7c, 0x7e, 0x80, 0x7c, 0x7c, 0x7d, 0x7e, 0x80, 0x81, 0x7e, 0x7e, 0x80, 0x80, 0x81, 0x81, 0x81, + 0x80, 0x7e, 0x7c, 0x80, 0x82, 0x81, 0x81, 0x80, 0x80, 0x81, 0x81, 0x7e, 0x7e, 0x80, 0x80, 0x7d, + 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x83, 0x84, 0x83, 0x83, 0x83, + 0x83, 0x83, 0x83, 0x81, 0x81, 0x82, 0x82, 0x82, 0x83, 0x83, 0x82, 0x83, 0x83, 0x84, 0x84, 0x83, + 0x83, 0x85, 0x85, 0x83, 0x83, 0x83, 0x82, 0x82, 0x83, 0x84, 0x84, 0x84, 0x82, 0x83, 0x85, 0x85, + 0x83, 0x83, 0x83, 0x84, 0x83, 0x82, 0x84, 0x83, 0x82, 0x82, 0x83, 0x83, 0x80, 0x81, 0x81, 0x7d, + 0x7e, 0x80, 0x80, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7a, 0x7b, 0x7d, 0x7b, 0x7a, 0x7a, 0x7a, 0x7b, + 0x7b, 0x7a, 0x79, 0x7a, 0x7a, 0x77, 0x77, 0x79, 0x7a, 0x78, 0x78, 0x79, 0x78, 0x78, 0x76, 0x77, + 0x77, 0x78, 0x79, 0x79, 0x7a, 0x7c, 0x7b, 0x7d, 0x80, 0x7e, 0x7c, 0x7e, 0x7c, 0x79, 0x7b, 0x7e, + 0x7d, 0x7b, 0x7d, 0x7e, 0x7d, 0x7a, 0x7a, 0x7e, 0x7e, 0x7c, 0x7d, 0x7e, 0x7e, 0x80, 0x81, 0x81, + 0x81, 0x83, 0x83, 0x82, 0x85, 0x85, 0x84, 0x84, 0x84, 0x85, 0x86, 0x84, 0x84, 0x84, 0x82, 0x83, + 0x82, 0x80, 0x82, 0x84, 0x82, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x7e, 0x81, 0x81, 0x81, 0x81, + 0x80, 0x82, 0x82, 0x81, 0x81, 0x82, 0x80, 0x7d, 0x80, 0x81, 0x80, 0x80, 0x82, 0x81, 0x81, 0x81, + 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x7d, 0x7c, 0x7c, 0x7e, 0x7d, 0x7c, 0x7d, 0x7d, 0x7b, 0x7d, + 0x7e, 0x7e, 0x80, 0x7e, 0x80, 0x81, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x81, 0x82, 0x80, 0x80, + 0x7d, 0x7c, 0x7e, 0x7c, 0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7c, 0x7d, 0x7b, 0x7b, 0x7b, 0x7d, 0x7d, + 0x7e, 0x7e, 0x7e, 0x81, 0x81, 0x80, 0x82, 0x82, 0x81, 0x80, 0x81, 0x82, 0x83, 0x82, 0x82, 0x84, + 0x84, 0x83, 0x85, 0x83, 0x82, 0x82, 0x81, 0x83, 0x82, 0x84, 0x82, 0x81, 0x83, 0x82, 0x80, 0x81, + 0x82, 0x80, 0x7e, 0x7e, 0x80, 0x7d, 0x7b, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, 0x81, + 0x81, 0x7e, 0x7e, 0x81, 0x82, 0x81, 0x80, 0x80, 0x7e, 0x81, 0x81, 0x7e, 0x80, 0x81, 0x7e, 0x7e, + 0x81, 0x81, 0x7d, 0x7d, 0x7d, 0x7e, 0x80, 0x80, 0x7e, 0x80, 0x81, 0x7e, 0x7d, 0x7c, 0x7d, 0x7c, + 0x7b, 0x7c, 0x7c, 0x7b, 0x7a, 0x7b, 0x7b, 0x7a, 0x7b, 0x7c, 0x7c, 0x7a, 0x7b, 0x7d, 0x7e, 0x7d, + 0x7c, 0x7e, 0x7e, 0x7c, 0x7c, 0x7a, 0x7a, 0x7c, 0x7b, 0x7b, 0x7e, 0x7e, 0x7b, 0x7a, 0x7a, 0x7b, + 0x7b, 0x7a, 0x78, 0x7a, 0x7c, 0x7b, 0x7c, 0x7c, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7c, + 0x7d, 0x7e, 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x81, 0x82, 0x82, 0x83, 0x83, 0x84, + 0x85, 0x84, 0x84, 0x83, 0x84, 0x87, 0x85, 0x84, 0x86, 0x87, 0x86, 0x85, 0x85, 0x86, 0x84, 0x82, + 0x83, 0x83, 0x83, 0x83, 0x85, 0x85, 0x85, 0x85, 0x83, 0x82, 0x82, 0x83, 0x80, 0x80, 0x82, 0x80, + 0x7d, 0x81, 0x81, 0x80, 0x81, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x7e, 0x80, 0x82, 0x80, + 0x80, 0x80, 0x7e, 0x80, 0x81, 0x82, 0x81, 0x81, 0x81, 0x7d, 0x80, 0x82, 0x7d, 0x7c, 0x7e, 0x7d, + 0x7b, 0x7d, 0x7e, 0x7c, 0x7b, 0x7d, 0x7d, 0x7d, 0x7c, 0x7b, 0x7a, 0x7b, 0x7c, 0x7b, 0x7a, 0x7d, + 0x7e, 0x7b, 0x79, 0x7c, 0x7e, 0x7c, 0x7a, 0x7c, 0x7d, 0x7c, 0x7b, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, + 0x7b, 0x7d, 0x7d, 0x7c, 0x7b, 0x7c, 0x7e, 0x7b, 0x7b, 0x7b, 0x7a, 0x7b, 0x7b, 0x7b, 0x79, 0x7b, + 0x7e, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7c, 0x7d, 0x7b, 0x7b, 0x7e, 0x7e, 0x80, 0x80, + 0x80, 0x82, 0x82, 0x81, 0x80, 0x81, 0x81, 0x80, 0x82, 0x80, 0x7e, 0x81, 0x81, 0x80, 0x80, 0x81, + 0x83, 0x83, 0x82, 0x82, 0x83, 0x83, 0x82, 0x83, 0x84, 0x83, 0x82, 0x83, 0x84, 0x86, 0x86, 0x84, + 0x83, 0x83, 0x83, 0x83, 0x82, 0x81, 0x80, 0x82, 0x81, 0x80, 0x82, 0x82, 0x80, 0x80, 0x81, 0x82, + 0x82, 0x7e, 0x7e, 0x81, 0x80, 0x7e, 0x80, 0x7e, 0x7d, 0x7e, 0x7d, 0x7c, 0x7d, 0x7e, 0x7d, 0x7c, + 0x7e, 0x80, 0x80, 0x7e, 0x7c, 0x7d, 0x7e, 0x7c, 0x7d, 0x7e, 0x7e, 0x80, 0x81, 0x80, 0x7e, 0x7e, + 0x7c, 0x7b, 0x7a, 0x7b, 0x7a, 0x79, 0x78, 0x78, 0x7a, 0x7b, 0x7a, 0x7a, 0x7b, 0x7d, 0x7d, 0x7b, + 0x7b, 0x7e, 0x7e, 0x7c, 0x7e, 0x81, 0x81, 0x81, 0x80, 0x7e, 0x81, 0x83, 0x82, 0x81, 0x83, 0x84, + 0x83, 0x80, 0x80, 0x82, 0x82, 0x80, 0x81, 0x84, 0x83, 0x82, 0x83, 0x83, 0x82, 0x84, 0x84, 0x83, + 0x83, 0x84, 0x84, 0x81, 0x80, 0x81, 0x83, 0x83, 0x81, 0x81, 0x82, 0x82, 0x83, 0x82, 0x80, 0x82, + 0x83, 0x81, 0x7e, 0x81, 0x82, 0x81, 0x7e, 0x80, 0x81, 0x81, 0x81, 0x80, 0x80, 0x81, 0x7c, 0x7b, + 0x7b, 0x7b, 0x7b, 0x7b, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7b, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x79, + 0x79, 0x79, 0x79, 0x7a, 0x7b, 0x7b, 0x7a, 0x7a, 0x7a, 0x7c, 0x7d, 0x7c, 0x7d, 0x7d, 0x7c, 0x7d, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x81, 0x80, 0x7e, 0x80, 0x7e, 0x7d, + 0x7c, 0x7c, 0x7e, 0x7e, 0x7d, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x80, 0x80, 0x7e, 0x7d, 0x7e, + 0x80, 0x80, 0x7e, 0x80, 0x81, 0x7d, 0x7e, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x83, 0x81, 0x81, 0x83, 0x83, 0x83, 0x84, 0x84, 0x85, 0x83, 0x83, 0x83, 0x82, 0x82, + 0x84, 0x84, 0x82, 0x83, 0x84, 0x83, 0x82, 0x83, 0x82, 0x82, 0x82, 0x82, 0x81, 0x81, 0x83, 0x81, + 0x81, 0x82, 0x82, 0x81, 0x81, 0x81, 0x83, 0x82, 0x7e, 0x81, 0x80, 0x80, 0x82, 0x83, 0x83, 0x82, + 0x82, 0x83, 0x84, 0x82, 0x83, 0x82, 0x81, 0x81, 0x81, 0x7d, 0x7e, 0x7e, 0x7d, 0x7c, 0x7d, 0x7e, + 0x7d, 0x7b, 0x7b, 0x7c, 0x7d, 0x7b, 0x7a, 0x7b, 0x7b, 0x7a, 0x7a, 0x7b, 0x7a, 0x7a, 0x7b, 0x7a, + 0x7a, 0x79, 0x78, 0x7a, 0x79, 0x78, 0x7a, 0x7a, 0x78, 0x78, 0x79, 0x7a, 0x7b, 0x7a, 0x7a, 0x7a, + 0x7b, 0x7c, 0x7b, 0x7a, 0x7d, 0x7d, 0x7b, 0x7b, 0x7b, 0x7c, 0x7d, 0x7c, 0x7c, 0x80, 0x80, 0x7e, + 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x80, 0x80, 0x7e, 0x80, 0x81, 0x82, 0x81, 0x82, 0x83, 0x82, 0x81, + 0x82, 0x83, 0x82, 0x82, 0x83, 0x84, 0x84, 0x82, 0x84, 0x85, 0x84, 0x84, 0x86, 0x84, 0x84, 0x86, + 0x84, 0x83, 0x85, 0x83, 0x82, 0x83, 0x81, 0x82, 0x82, 0x81, 0x82, 0x82, 0x81, 0x81, 0x82, 0x82, + 0x81, 0x80, 0x81, 0x80, 0x7e, 0x80, 0x7e, 0x7d, 0x80, 0x7e, 0x7e, 0x80, 0x7e, 0x80, 0x7e, 0x7d, + 0x7d, 0x7d, 0x7b, 0x7c, 0x7d, 0x7b, 0x7c, 0x7d, 0x7d, 0x7d, 0x7c, 0x7d, 0x7e, 0x7d, 0x7e, 0x80, + 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x82, 0x81, 0x7e, 0x80, 0x80, 0x7e, 0x80, 0x7e, 0x7d, 0x7e, + 0x7e, 0x7e, 0x7d, 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7e, 0x7d, 0x7d, 0x80, 0x80, + 0x7d, 0x7e, 0x80, 0x81, 0x80, 0x80, 0x81, 0x82, 0x80, 0x80, 0x82, 0x83, 0x82, 0x81, 0x80, 0x81, + 0x81, 0x7e, 0x7e, 0x7d, 0x7e, 0x80, 0x7e, 0x7d, 0x7e, 0x7e, 0x7c, 0x7d, 0x80, 0x80, 0x7d, 0x7e, + 0x80, 0x7e, 0x7e, 0x80, 0x82, 0x82, 0x81, 0x82, 0x83, 0x81, 0x81, 0x82, 0x83, 0x82, 0x82, 0x81, + 0x81, 0x81, 0x7e, 0x7e, 0x81, 0x82, 0x80, 0x7e, 0x7e, 0x80, 0x81, 0x7e, 0x7e, 0x81, 0x80, 0x7d, + 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7e, 0x7d, 0x7c, 0x7c, 0x7b, 0x7a, 0x7b, + 0x7b, 0x7b, 0x7b, 0x7b, 0x7a, 0x7b, 0x7c, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, + 0x7d, 0x7e, 0x80, 0x80, 0x7d, 0x7e, 0x80, 0x7d, 0x7c, 0x7c, 0x7b, 0x7c, 0x7d, 0x7b, 0x7b, 0x7d, + 0x7c, 0x7a, 0x7b, 0x7e, 0x7e, 0x7c, 0x7c, 0x7d, 0x7d, 0x7e, 0x80, 0x80, 0x7e, 0x80, 0x81, 0x81, + 0x80, 0x81, 0x82, 0x81, 0x82, 0x84, 0x84, 0x84, 0x82, 0x81, 0x82, 0x82, 0x82, 0x83, 0x82, 0x83, + 0x85, 0x85, 0x84, 0x83, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x81, 0x83, 0x85, 0x85, 0x84, + 0x84, 0x85, 0x85, 0x84, 0x82, 0x82, 0x84, 0x83, 0x81, 0x80, 0x83, 0x81, 0x80, 0x81, 0x81, 0x82, + 0x82, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x7e, 0x7c, 0x7e, 0x80, 0x7d, 0x7e, 0x81, 0x80, 0x7c, 0x7c, + 0x7e, 0x7d, 0x7e, 0x7e, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7d, 0x7d, 0x7d, 0x7e, 0x7d, + 0x7c, 0x7d, 0x7c, 0x7c, 0x7c, 0x7b, 0x79, 0x79, 0x7c, 0x7c, 0x7b, 0x7c, 0x7e, 0x7d, 0x7c, 0x7d, + 0x7e, 0x7d, 0x7c, 0x7e, 0x80, 0x7e, 0x7e, 0x80, 0x7d, 0x7c, 0x80, 0x7e, 0x7c, 0x7e, 0x80, 0x7c, + 0x7b, 0x7d, 0x7d, 0x7b, 0x7b, 0x7b, 0x7a, 0x7a, 0x79, 0x7a, 0x7b, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, + 0x7d, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x80, 0x80, 0x80, 0x82, 0x81, 0x80, 0x81, 0x80, 0x80, 0x7e, + 0x7e, 0x80, 0x81, 0x81, 0x7d, 0x7e, 0x81, 0x81, 0x81, 0x80, 0x81, 0x82, 0x82, 0x80, 0x80, 0x83, + 0x83, 0x82, 0x82, 0x84, 0x86, 0x85, 0x83, 0x84, 0x86, 0x85, 0x84, 0x84, 0x84, 0x85, 0x83, 0x82, + 0x83, 0x84, 0x83, 0x82, 0x82, 0x82, 0x81, 0x82, 0x82, 0x80, 0x81, 0x82, 0x80, 0x7e, 0x80, 0x7e, + 0x7d, 0x7d, 0x7e, 0x7c, 0x7d, 0x7d, 0x7c, 0x7e, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, + 0x80, 0x7e, 0x7d, 0x7e, 0x7e, 0x7d, 0x7c, 0x7d, 0x7c, 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7c, + 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7b, 0x7c, 0x7d, + 0x7c, 0x7c, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x81, 0x81, 0x81, 0x80, 0x82, 0x81, 0x81, 0x82, + 0x82, 0x82, 0x83, 0x82, 0x81, 0x81, 0x81, 0x80, 0x81, 0x81, 0x81, 0x82, 0x81, 0x80, 0x82, 0x81, + 0x81, 0x83, 0x83, 0x81, 0x82, 0x83, 0x82, 0x82, 0x82, 0x84, 0x83, 0x82, 0x84, 0x85, 0x83, 0x81, + 0x80, 0x82, 0x80, 0x80, 0x83, 0x81, 0x81, 0x80, 0x7d, 0x80, 0x81, 0x7e, 0x7c, 0x7d, 0x7d, 0x7c, + 0x7b, 0x7b, 0x7c, 0x7c, 0x7b, 0x7c, 0x7c, 0x7c, 0x7a, 0x7a, 0x7b, 0x7c, 0x7c, 0x7b, 0x7b, 0x7c, + 0x7c, 0x7b, 0x7b, 0x7b, 0x7a, 0x7b, 0x7d, 0x7c, 0x7b, 0x7c, 0x7c, 0x7b, 0x7c, 0x7c, 0x7c, 0x7d, + 0x7c, 0x7a, 0x7c, 0x7c, 0x7b, 0x7b, 0x7c, 0x7d, 0x7d, 0x7e, 0x7d, 0x7e, 0x81, 0x80, 0x7e, 0x81, + 0x83, 0x81, 0x81, 0x83, 0x83, 0x83, 0x81, 0x80, 0x82, 0x82, 0x81, 0x80, 0x81, 0x82, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x81, 0x81, 0x82, 0x81, 0x80, 0x80, 0x80, + 0x80, 0x82, 0x82, 0x80, 0x81, 0x84, 0x83, 0x81, 0x82, 0x83, 0x83, 0x80, 0x81, 0x83, 0x82, 0x81, + 0x81, 0x82, 0x83, 0x83, 0x82, 0x82, 0x82, 0x83, 0x82, 0x81, 0x82, 0x80, 0x80, 0x82, 0x82, 0x83, + 0x83, 0x81, 0x80, 0x82, 0x82, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, 0x81, 0x81, 0x80, 0x81, + 0x81, 0x81, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, 0x7d, 0x7c, 0x7b, 0x7b, 0x7b, 0x7a, 0x79, 0x7a, + 0x7b, 0x7a, 0x7a, 0x7b, 0x7c, 0x7a, 0x79, 0x7a, 0x7b, 0x7b, 0x7a, 0x7a, 0x7b, 0x7a, 0x79, 0x79, + 0x7a, 0x7b, 0x7b, 0x79, 0x7b, 0x7d, 0x7b, 0x7a, 0x7c, 0x7c, 0x7b, 0x7d, 0x7d, 0x7c, 0x7b, 0x7b, + 0x7b, 0x7c, 0x7c, 0x7c, 0x7d, 0x7c, 0x7c, 0x81, 0x7e, 0x7d, 0x7e, 0x80, 0x80, 0x80, 0x81, 0x80, + 0x7e, 0x81, 0x82, 0x81, 0x81, 0x82, 0x82, 0x81, 0x81, 0x81, 0x82, 0x82, 0x81, 0x80, 0x82, 0x83, + 0x84, 0x83, 0x82, 0x83, 0x82, 0x82, 0x83, 0x83, 0x82, 0x81, 0x82, 0x82, 0x82, 0x83, 0x83, 0x81, + 0x82, 0x83, 0x84, 0x84, 0x82, 0x82, 0x82, 0x81, 0x83, 0x83, 0x82, 0x82, 0x82, 0x82, 0x81, 0x82, + 0x82, 0x81, 0x81, 0x81, 0x82, 0x81, 0x80, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7c, 0x7b, 0x7c, 0x7c, + 0x7c, 0x7d, 0x7d, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7d, 0x7e, 0x7e, 0x80, 0x80, 0x81, + 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x81, 0x7e, 0x7e, 0x80, 0x7e, 0x80, 0x80, 0x7d, 0x7e, 0x7e, 0x7c, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x81, 0x80, 0x80, + 0x80, 0x81, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x80, + 0x80, 0x7d, 0x7c, 0x7d, 0x7c, 0x7b, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x80, 0x7e, 0x7e, 0x7e, + 0x7e, 0x80, 0x81, 0x81, 0x81, 0x81, 0x82, 0x81, 0x81, 0x82, 0x81, 0x81, 0x81, 0x80, 0x80, 0x81, + 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, + 0x80, 0x80, 0x81, 0x80, 0x7d, 0x7d, 0x7e, 0x7e, 0x7d, 0x7c, 0x7d, 0x7d, 0x7c, 0x7d, 0x7c, 0x7c, + 0x7d, 0x7d, 0x7c, 0x7d, 0x80, 0x7e, 0x7c, 0x7d, 0x7e, 0x7e, 0x7d, 0x7c, 0x7c, 0x7c, 0x7b, 0x7a, + 0x7a, 0x7a, 0x7a, 0x7b, 0x7a, 0x79, 0x7c, 0x7b, 0x7a, 0x7b, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, + 0x80, 0x7d, 0x7d, 0x7d, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x82, 0x81, 0x80, 0x81, 0x83, 0x84, 0x83, 0x81, 0x82, 0x82, 0x82, 0x84, 0x84, 0x83, + 0x83, 0x84, 0x83, 0x84, 0x85, 0x85, 0x84, 0x84, 0x85, 0x84, 0x84, 0x85, 0x84, 0x83, 0x84, 0x85, + 0x85, 0x84, 0x84, 0x85, 0x85, 0x82, 0x80, 0x82, 0x82, 0x80, 0x81, 0x82, 0x81, 0x80, 0x7e, 0x7e, + 0x7e, 0x7d, 0x7c, 0x7d, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7d, 0x7e, 0x7e, 0x7c, 0x7e, 0x7e, 0x7d, + 0x7c, 0x7e, 0x7e, 0x7d, 0x7d, 0x7c, 0x7b, 0x7b, 0x7b, 0x7a, 0x79, 0x79, 0x7c, 0x7c, 0x7c, 0x7b, + 0x7b, 0x7c, 0x7b, 0x7a, 0x7b, 0x7c, 0x7b, 0x7a, 0x7c, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, + 0x7c, 0x7c, 0x7e, 0x7e, 0x7c, 0x7c, 0x7d, 0x7d, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x7d, 0x7b, 0x7c, + 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x80, 0x7e, 0x7e, 0x80, 0x80, + 0x81, 0x81, 0x80, 0x81, 0x80, 0x7e, 0x80, 0x80, 0x81, 0x81, 0x7e, 0x80, 0x81, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x7e, 0x81, 0x83, 0x82, 0x81, 0x81, 0x81, 0x82, 0x82, 0x82, 0x81, 0x81, 0x82, 0x82, + 0x82, 0x82, 0x83, 0x83, 0x82, 0x82, 0x83, 0x84, 0x83, 0x83, 0x84, 0x84, 0x84, 0x84, 0x84, 0x83, + 0x84, 0x83, 0x83, 0x83, 0x81, 0x82, 0x83, 0x81, 0x81, 0x82, 0x81, 0x80, 0x7e, 0x7e, 0x7e, 0x80, + 0x7e, 0x7d, 0x7d, 0x7d, 0x7c, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7c, 0x7c, 0x7d, + 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7c, 0x7b, 0x7c, 0x7c, 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, + 0x7c, 0x7b, 0x7b, 0x7c, 0x7d, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x80, 0x7e, 0x7d, + 0x80, 0x81, 0x7d, 0x7d, 0x81, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x80, 0x81, 0x82, 0x81, 0x81, + 0x80, 0x80, 0x7e, 0x80, 0x81, 0x82, 0x82, 0x81, 0x82, 0x82, 0x82, 0x80, 0x80, 0x81, 0x81, 0x81, + 0x81, 0x82, 0x82, 0x81, 0x81, 0x82, 0x82, 0x83, 0x83, 0x81, 0x80, 0x82, 0x81, 0x80, 0x81, 0x80, + 0x80, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, + 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7d, 0x7e, 0x7e, 0x7d, 0x7d, 0x7c, 0x7d, 0x7d, 0x7c, 0x7d, + 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7d, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7a, 0x7b, 0x7b, 0x7a, + 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x80, 0x7e, + 0x81, 0x82, 0x81, 0x81, 0x83, 0x83, 0x81, 0x80, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x81, 0x80, + 0x80, 0x7e, 0x80, 0x81, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x80, 0x82, 0x81, 0x80, 0x7e, 0x80, + 0x81, 0x81, 0x81, 0x82, 0x82, 0x81, 0x82, 0x81, 0x81, 0x82, 0x82, 0x83, 0x82, 0x82, 0x83, 0x83, + 0x82, 0x82, 0x83, 0x81, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x80, 0x81, 0x81, 0x81, 0x80, 0x82, + 0x83, 0x83, 0x83, 0x83, 0x83, 0x84, 0x82, 0x81, 0x82, 0x82, 0x81, 0x7e, 0x80, 0x81, 0x80, 0x7d, + 0x7d, 0x7d, 0x7c, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7a, 0x7b, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b, 0x7b, + 0x7b, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b, 0x7c, 0x7b, 0x7a, 0x7a, 0x7a, 0x7a, 0x7b, 0x7a, 0x7a, 0x7b, + 0x7a, 0x79, 0x7b, 0x7b, 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7d, 0x7d, + 0x7d, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x80, 0x80, 0x80, 0x80, 0x80, 0x82, 0x83, 0x81, 0x82, 0x83, + 0x83, 0x82, 0x82, 0x83, 0x83, 0x82, 0x82, 0x84, 0x84, 0x82, 0x81, 0x81, 0x82, 0x83, 0x83, 0x82, + 0x83, 0x84, 0x84, 0x83, 0x83, 0x84, 0x82, 0x81, 0x83, 0x84, 0x84, 0x82, 0x81, 0x83, 0x83, 0x82, + 0x82, 0x82, 0x81, 0x81, 0x82, 0x82, 0x82, 0x81, 0x80, 0x81, 0x82, 0x82, 0x83, 0x82, 0x7e, 0x7e, + 0x81, 0x81, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7d, 0x7c, + 0x7b, 0x7c, 0x7d, 0x80, 0x7e, 0x7c, 0x7c, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x80, + 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7d, 0x7c, 0x7d, + 0x7d, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, 0x7d, 0x80, 0x7e, + 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x81, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7d, + 0x7d, 0x7e, 0x80, 0x81, 0x80, 0x7d, 0x7e, 0x80, 0x80, 0x81, 0x82, 0x80, 0x7e, 0x81, 0x80, 0x80, + 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x7e, 0x7d, 0x80, 0x80, 0x7d, 0x7e, + 0x81, 0x80, 0x7e, 0x80, 0x80, 0x7e, 0x81, 0x81, 0x80, 0x7e, 0x7e, 0x80, 0x82, 0x81, 0x81, 0x82, + 0x80, 0x7e, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x81, 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x7e, + 0x7d, 0x7d, 0x7d, 0x7c, 0x7d, 0x7c, 0x7b, 0x7d, 0x7c, 0x7b, 0x7c, 0x7c, 0x7b, 0x7b, 0x7c, 0x7c, + 0x7c, 0x7c, 0x7c, 0x7b, 0x7c, 0x7d, 0x7c, 0x7c, 0x7c, 0x7d, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7e, 0x7e, 0x7d, 0x7e, 0x7e, 0x7d, 0x7e, 0x7d, 0x7e, 0x7e, 0x7e, 0x80, 0x81, 0x81, 0x80, 0x80, + 0x80, 0x7e, 0x81, 0x82, 0x80, 0x81, 0x81, 0x81, 0x82, 0x82, 0x83, 0x82, 0x83, 0x83, 0x82, 0x83, + 0x82, 0x82, 0x84, 0x84, 0x83, 0x84, 0x84, 0x84, 0x84, 0x84, 0x85, 0x84, 0x84, 0x84, 0x84, 0x83, + 0x84, 0x84, 0x82, 0x82, 0x83, 0x81, 0x7e, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x80, + 0x80, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7c, 0x7d, 0x7c, 0x7c, + 0x7c, 0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b, 0x7b, 0x7a, 0x7a, 0x7b, + 0x7a, 0x7a, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7e, 0x7d, 0x7c, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7b, 0x7d, 0x7d, 0x7c, 0x7d, 0x7e, 0x7e, 0x7d, 0x7d, + 0x7d, 0x7c, 0x7d, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x80, 0x81, 0x80, 0x81, 0x81, 0x80, 0x80, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, 0x82, + 0x81, 0x82, 0x82, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, + 0x81, 0x82, 0x82, 0x82, 0x83, 0x83, 0x83, 0x84, 0x83, 0x82, 0x83, 0x83, 0x82, 0x81, 0x83, 0x82, + 0x82, 0x82, 0x82, 0x80, 0x80, 0x82, 0x82, 0x81, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, + 0x7e, 0x7d, 0x7c, 0x7e, 0x7e, 0x7c, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7d, + 0x7c, 0x7c, 0x7c, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7c, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, + 0x7a, 0x7a, 0x7b, 0x7b, 0x7c, 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7e, 0x80, 0x7e, 0x7e, 0x80, 0x80, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x7e, 0x7e, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x81, 0x81, 0x81, 0x81, 0x83, + 0x84, 0x83, 0x82, 0x83, 0x82, 0x81, 0x81, 0x82, 0x82, 0x80, 0x80, 0x81, 0x80, 0x80, 0x80, 0x7e, + 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, + 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, 0x7d, 0x7e, 0x7d, 0x7d, 0x7e, + 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x81, 0x81, + 0x81, 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x81, 0x7e, 0x7e, 0x7e, 0x7e, + 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x81, 0x82, 0x82, 0x81, 0x81, 0x82, 0x83, 0x82, 0x82, + 0x83, 0x83, 0x82, 0x83, 0x82, 0x82, 0x82, 0x83, 0x83, 0x82, 0x82, 0x81, 0x82, 0x82, 0x82, 0x81, + 0x81, 0x81, 0x80, 0x80, 0x81, 0x81, 0x80, 0x7e, 0x80, 0x81, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x80, 0x80, 0x82, 0x82, 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7b, 0x7c, 0x7b, 0x7a, 0x7b, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, + 0x7b, 0x7c, 0x7c, 0x7d, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7b, + 0x7b, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7a, 0x7b, 0x7b, 0x7d, 0x7d, 0x7c, 0x7b, 0x7b, 0x7b, 0x7c, + 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x81, 0x81, 0x80, 0x81, 0x83, 0x82, 0x81, 0x81, + 0x83, 0x83, 0x84, 0x83, 0x82, 0x83, 0x83, 0x82, 0x84, 0x84, 0x84, 0x83, 0x83, 0x83, 0x83, 0x83, + 0x82, 0x83, 0x84, 0x84, 0x83, 0x82, 0x83, 0x82, 0x82, 0x83, 0x83, 0x82, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x80, + 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7e, 0x7e, 0x7d, 0x7d, 0x7c, 0x7d, 0x7e, 0x7d, 0x7d, 0x7e, + 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7e, 0x7e, 0x80, 0x80, 0x7e, 0x7e, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7c, 0x7d, 0x7d, 0x7c, + 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7d, 0x7c, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x81, 0x81, 0x80, 0x7e, 0x80, 0x81, 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x7d, 0x7d, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x83, + 0x82, 0x81, 0x81, 0x81, 0x82, 0x80, 0x80, 0x81, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x81, 0x80, 0x7e, + 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7d, 0x7c, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, + 0x7b, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7c, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x81, 0x81, + 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x82, 0x82, 0x83, 0x83, 0x83, 0x83, 0x83, 0x82, 0x82, 0x83, + 0x84, 0x84, 0x83, 0x83, 0x82, 0x82, 0x84, 0x84, 0x83, 0x83, 0x82, 0x82, 0x82, 0x82, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x82, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x7e, + 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7c, 0x7d, + 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7b, 0x7b, 0x7c, 0x7c, + 0x7c, 0x7b, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7c, 0x7d, 0x7c, 0x7d, 0x7d, 0x7c, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7b, 0x7c, 0x7d, 0x7d, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x82, 0x81, 0x82, 0x82, 0x81, 0x81, + 0x82, 0x82, 0x81, 0x81, 0x81, 0x82, 0x82, 0x81, 0x81, 0x82, 0x82, 0x81, 0x81, 0x80, 0x81, 0x82, + 0x82, 0x82, 0x83, 0x83, 0x82, 0x80, 0x81, 0x82, 0x82, 0x83, 0x83, 0x83, 0x82, 0x83, 0x83, 0x83, + 0x83, 0x83, 0x83, 0x82, 0x82, 0x82, 0x82, 0x82, 0x83, 0x81, 0x81, 0x82, 0x82, 0x81, 0x80, 0x80, + 0x7e, 0x7e, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, + 0x7e, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7b, 0x7c, 0x7c, 0x7b, 0x7c, 0x7b, 0x7c, 0x7d, 0x7c, 0x7c, + 0x7c, 0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7c, 0x7b, 0x7b, 0x7c, 0x7b, 0x7b, 0x7b, 0x7c, 0x7b, 0x7c, + 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7e, 0x7d, 0x7d, 0x80, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, + 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x81, 0x82, 0x82, 0x81, 0x82, 0x82, + 0x82, 0x81, 0x82, 0x83, 0x83, 0x82, 0x82, 0x83, 0x83, 0x83, 0x83, 0x84, 0x83, 0x83, 0x83, 0x82, + 0x82, 0x82, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x7e, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7c, 0x7c, 0x7c, 0x7d, 0x7c, 0x7c, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, + 0x7e, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x81, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x7e, 0x80, 0x81, 0x81, 0x80, 0x7e, + 0x80, 0x81, 0x80, 0x7e, 0x80, 0x81, 0x80, 0x80, 0x81, 0x81, 0x80, 0x81, 0x81, 0x82, 0x82, 0x81, + 0x80, 0x81, 0x81, 0x81, 0x82, 0x82, 0x81, 0x81, 0x81, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x82, + 0x82, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x81, 0x82, 0x82, 0x81, + 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, + 0x7c, 0x7d, 0x7c, 0x7c, 0x7c, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7b, 0x7c, 0x7c, 0x7b, 0x7b, + 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7a, 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7e, 0x7e, + 0x7d, 0x7e, 0x7e, 0x7e, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, 0x81, 0x81, 0x82, 0x83, + 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x84, 0x83, 0x83, 0x83, 0x83, 0x84, 0x83, 0x83, 0x84, + 0x83, 0x83, 0x83, 0x83, 0x82, 0x82, 0x82, 0x82, 0x83, 0x82, 0x82, 0x81, 0x82, 0x82, 0x81, 0x81, + 0x81, 0x80, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7c, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7d, 0x7d, + 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7e, 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x81, 0x80, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x81, + 0x82, 0x82, 0x82, 0x81, 0x82, 0x82, 0x82, 0x82, 0x82, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x82, 0x82, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7d, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x80, 0x80, + 0x80, 0x80, 0x7e, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7d, 0x7c, 0x7d, 0x7c, + 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7c, 0x7c, 0x7b, 0x7b, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x80, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x80, + 0x81, 0x81, 0x81, 0x80, 0x80, 0x81, 0x82, 0x82, 0x82, 0x82, 0x81, 0x81, 0x82, 0x83, 0x83, 0x82, + 0x82, 0x83, 0x83, 0x83, 0x83, 0x83, 0x82, 0x81, 0x82, 0x82, 0x82, 0x83, 0x82, 0x82, 0x82, 0x82, + 0x82, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, 0x81, 0x80, 0x80, 0x81, 0x80, 0x80, 0x80, 0x7e, 0x7d, + 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7d, 0x7e, 0x7d, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, + 0x7c, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7d, 0x7d, + 0x7e, 0x7e, 0x7d, 0x7c, 0x7d, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7d, 0x7d, 0x7c, 0x7c, + 0x7c, 0x7d, 0x7d, 0x7d, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x81, 0x80, + 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x81, 0x81, 0x80, + 0x81, 0x81, 0x81, 0x80, 0x81, 0x82, 0x82, 0x82, 0x81, 0x80, 0x81, 0x81, 0x80, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x82, 0x82, 0x81, 0x82, 0x82, 0x82, 0x82, 0x82, 0x81, 0x81, 0x82, 0x83, 0x82, 0x82, + 0x82, 0x82, 0x82, 0x83, 0x82, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x80, 0x80, + 0x7e, 0x80, 0x80, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, 0x7d, 0x7d, + 0x7e, 0x7e, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7c, + 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7d, 0x7c, 0x7c, 0x7d, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, 0x82, + 0x83, 0x83, 0x82, 0x82, 0x83, 0x83, 0x82, 0x83, 0x83, 0x83, 0x83, 0x82, 0x82, 0x83, 0x83, 0x82, + 0x81, 0x81, 0x81, 0x80, 0x7e, 0x80, 0x81, 0x80, 0x80, 0x81, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7e, 0x80, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7c, 0x7c, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7c, 0x7d, 0x7e, 0x7d, 0x7d, 0x7e, 0x80, 0x7e, 0x7d, 0x7e, 0x80, 0x80, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x81, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x82, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, + 0x80, 0x81, 0x82, 0x81, 0x82, 0x82, 0x80, 0x81, 0x81, 0x81, 0x81, 0x80, 0x7e, 0x7e, 0x80, 0x80, + 0x81, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x81, 0x80, 0x81, 0x80, 0x7e, 0x7e, 0x7e, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, + 0x7d, 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7c, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, + 0x7d, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7c, 0x7b, 0x7b, 0x7b, 0x7c, 0x7b, 0x7b, 0x7b, 0x7b, + 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x80, 0x81, 0x81, + 0x80, 0x81, 0x81, 0x82, 0x82, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x82, 0x81, 0x81, 0x81, 0x81, 0x82, 0x81, 0x81, 0x82, 0x82, 0x82, 0x82, 0x82, 0x83, 0x83, 0x82, + 0x82, 0x83, 0x83, 0x82, 0x82, 0x82, 0x82, 0x82, 0x81, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x81, + 0x82, 0x82, 0x81, 0x81, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, + 0x7c, 0x7d, 0x7d, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7c, 0x7d, 0x7d, 0x7c, 0x7d, 0x7e, 0x7d, 0x7d, + 0x7d, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7c, 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x7e, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x81, 0x80, 0x81, 0x81, 0x81, 0x81, + 0x80, 0x81, 0x82, 0x82, 0x82, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b, 0x7b, 0x7c, + 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x80, 0x80, 0x80, 0x81, 0x81, 0x80, 0x81, 0x81, 0x81, + 0x82, 0x81, 0x82, 0x82, 0x81, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x81, 0x82, 0x82, 0x82, 0x81, + 0x82, 0x82, 0x82, 0x82, 0x82, 0x81, 0x81, 0x82, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7d, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7d, 0x7d, 0x7c, 0x7d, 0x7d, 0x7e, 0x7d, + 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x81, 0x80, 0x80, 0x81, 0x81, + 0x80, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x82, 0x82, 0x82, 0x81, + 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x81, 0x82, 0x82, 0x82, 0x81, + 0x80, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, + 0x7c, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7b, 0x7b, + 0x7b, 0x7b, 0x7b, 0x7c, 0x7d, 0x7d, 0x7d, 0x7c, 0x7d, 0x7d, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, + 0x81, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, 0x82, 0x82, 0x82, 0x83, 0x82, 0x82, 0x82, + 0x82, 0x82, 0x83, 0x83, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x81, 0x80, 0x81, 0x81, 0x81, + 0x80, 0x80, 0x80, 0x81, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x80, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7c, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x80, 0x81, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x80, 0x80, + 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, + 0x7d, 0x7d, 0x7c, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x81, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x80, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x81, 0x82, 0x82, 0x81, 0x82, 0x82, + 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, + 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x80, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x81, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7d, 0x7c, 0x7d, 0x7d, 0x7d, 0x7c, + 0x7c, 0x7c, 0x7b, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, 0x82, 0x81, 0x81, + 0x81, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x81, 0x82, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x81, 0x80, 0x7e, 0x80, + 0x80, 0x7e, 0x80, 0x80, 0x80, 0x7f, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, + 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x7e, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x81, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x81, 0x81, + 0x81, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7d, + 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7e, 0x7e, 0x7e, 0x7d, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x7e, 0x7e, + 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x81, + 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, + 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, + 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7d, 0x7e, + 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x80, 0x80, + 0x81, 0x81, 0x81, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, 0x81, + 0x81, 0x82, 0x82, 0x82, 0x81, 0x81, 0x80, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, + 0x81, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, + 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, + 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7d, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x7e, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, + 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, + 0x81, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x7e, + 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, + 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x80, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, + 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, + 0x80, 0x81, 0x81, 0x81, 0x80, 0x81, 0x81, 0x81, 0x81, 0x80, 0x81, 0x81, 0x80, 0x80, 0x81, 0x81, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7d, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x81, 0x80, 0x80, 0x80, 0x81, 0x81, + 0x80, 0x80, 0x80, 0x81, 0x81, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, + 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7e, + 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x7e, 0x7f, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, + 0x80, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x81, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x81, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x80, 0x80, 0x81, 0x81, 0x81, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, + 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x81, 0x81, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x7e, 0x7f, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7d, + 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x7e, 0x7e, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7f, 0x80, 0x7e, 0x7e, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x81, 0x80, 0x81, 0x80, 0x80, 0x81, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x7e, 0x7f, 0x80, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x80, 0x81, 0x80, 0x80, 0x81, 0x81, 0x81, 0x80, 0x81, 0x81, + 0x81, 0x80, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, + 0x80, 0x81, 0x81, 0x80, 0x81, 0x81, 0x80, 0x80, 0x80, 0x81, 0x80, 0x80, 0x81, 0x80, 0x80, 0x81, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x7e, + 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x7e, 0x80, + 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x80, 0x80, 0x80, 0x81, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, + 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x7e, 0x80, + 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x80, + 0x7e, 0x7e, 0x7f, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x80, 0x80, 0x80, 0x80, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, +}; diff --git a/components/driver/test_apps/i2s_test_apps/legacy_i2s_adc_dac/main/test_i2s_adc.c b/components/driver/test_apps/i2s_test_apps/legacy_i2s_adc_dac/main/test_i2s_adc.c new file mode 100644 index 0000000000..b290bbe395 --- /dev/null +++ b/components/driver/test_apps/i2s_test_apps/legacy_i2s_adc_dac/main/test_i2s_adc.c @@ -0,0 +1,252 @@ +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + Tests for the adc device driver on ESP32 only +*/ +#include "sdkconfig.h" +#if CONFIG_IDF_TARGET_ESP32 + +#include "esp_system.h" +#include "driver/adc.h" +#include "driver/rtc_io.h" +#include "driver/gpio.h" +#include "unity.h" +#include "esp_system.h" +#include "esp_event.h" +#include "esp_wifi.h" +#include "esp_log.h" +#include "nvs_flash.h" +#include "esp_rom_sys.h" +#include "driver/dac.h" +#include "soc/adc_periph.h" + +/* + * ADC DMA testcase + */ +#include "driver/i2s.h" + +//i2s number +#define EXAMPLE_I2S_NUM (0) +//i2s sample rate +#define EXAMPLE_I2S_SAMPLE_RATE (150000) +//i2s data bits +#define EXAMPLE_I2S_SAMPLE_BITS (16) +//enable display buffer for debug +#define EXAMPLE_I2S_BUF_DEBUG (0) +//I2S read buffer length +#define EXAMPLE_I2S_READ_LEN (16 * 1024) +//I2S data format, ADC-I2S only support mono. +#define EXAMPLE_I2S_FORMAT I2S_CHANNEL_FMT_ONLY_RIGHT +//I2S built-in ADC unit +#define I2S_ADC_UNIT ADC_UNIT_1 +//I2S built-in ADC channel +#define I2S_ADC_CHANNEL ADC1_CHANNEL_4 + +#define ADC_GET_IO_NUM(periph, channel) (adc_channel_io_map[periph][channel]) + +static void adc_fake_tie_middle(adc_unit_t adc_unit, adc_channel_t channel) +{ + gpio_num_t gpio_num = 0; + if (adc_unit == ADC_UNIT_1) { + gpio_num = ADC_GET_IO_NUM(0, channel); + TEST_ESP_OK(rtc_gpio_init(gpio_num)); + TEST_ESP_OK(rtc_gpio_pullup_en(gpio_num)); + TEST_ESP_OK(rtc_gpio_pulldown_en(gpio_num)); + TEST_ESP_OK(gpio_set_pull_mode(gpio_num, GPIO_PULLUP_PULLDOWN)); + TEST_ESP_OK(rtc_gpio_set_direction(gpio_num, RTC_GPIO_MODE_DISABLED)); + } + if (adc_unit == ADC_UNIT_2) { + gpio_num = ADC_GET_IO_NUM(1, channel); + TEST_ESP_OK(rtc_gpio_init(gpio_num)); + TEST_ESP_OK(rtc_gpio_pullup_en(gpio_num)); + TEST_ESP_OK(rtc_gpio_pulldown_en(gpio_num)); + TEST_ESP_OK(gpio_set_pull_mode(gpio_num, GPIO_PULLUP_PULLDOWN)); + TEST_ESP_OK(rtc_gpio_set_direction(gpio_num, RTC_GPIO_MODE_DISABLED)); + } + vTaskDelay(10 / portTICK_PERIOD_MS); +} + +static void adc_fake_tie_high(adc_unit_t adc_unit, adc_channel_t channel) +{ + gpio_num_t gpio_num = 0; + if (adc_unit == ADC_UNIT_1) { + gpio_num = ADC_GET_IO_NUM(0, channel); + TEST_ESP_OK(rtc_gpio_init(gpio_num)); + TEST_ESP_OK(rtc_gpio_pullup_en(gpio_num)); + TEST_ESP_OK(rtc_gpio_pulldown_dis(gpio_num)); + TEST_ESP_OK(gpio_set_pull_mode(gpio_num, GPIO_PULLUP_ONLY)); + TEST_ESP_OK(rtc_gpio_set_direction(gpio_num, RTC_GPIO_MODE_OUTPUT_ONLY)); + TEST_ESP_OK(rtc_gpio_set_level(gpio_num, 1)); + } + if (adc_unit == ADC_UNIT_2) { + gpio_num = ADC_GET_IO_NUM(1, channel); + TEST_ESP_OK(rtc_gpio_init(gpio_num)); + TEST_ESP_OK(rtc_gpio_pullup_en(gpio_num)); + TEST_ESP_OK(rtc_gpio_pulldown_dis(gpio_num)); + TEST_ESP_OK(gpio_set_pull_mode(gpio_num, GPIO_PULLUP_ONLY)); + TEST_ESP_OK(rtc_gpio_set_direction(gpio_num, RTC_GPIO_MODE_OUTPUT_ONLY)); + TEST_ESP_OK(rtc_gpio_set_level(gpio_num, 1)); + } + vTaskDelay(10 / portTICK_PERIOD_MS); +} + +static void adc_fake_tie_low(adc_unit_t adc_unit, adc_channel_t channel) +{ + gpio_num_t gpio_num = 0; + if (adc_unit == ADC_UNIT_1) { + gpio_num = ADC_GET_IO_NUM(0, channel); + TEST_ESP_OK(rtc_gpio_init(gpio_num)); + TEST_ESP_OK(rtc_gpio_pullup_dis(gpio_num)); + TEST_ESP_OK(rtc_gpio_pulldown_en(gpio_num)); + TEST_ESP_OK(gpio_set_pull_mode(gpio_num, GPIO_PULLDOWN_ONLY)); + TEST_ESP_OK(rtc_gpio_set_direction(gpio_num, RTC_GPIO_MODE_OUTPUT_ONLY)); + TEST_ESP_OK(rtc_gpio_set_level(gpio_num, 0)); + } + if (adc_unit == ADC_UNIT_2) { + gpio_num = ADC_GET_IO_NUM(1, channel); + TEST_ESP_OK(rtc_gpio_init(gpio_num)); + TEST_ESP_OK(rtc_gpio_pullup_dis(gpio_num)); + TEST_ESP_OK(rtc_gpio_pulldown_en(gpio_num)); + TEST_ESP_OK(gpio_set_pull_mode(gpio_num, GPIO_PULLDOWN_ONLY)); + TEST_ESP_OK(rtc_gpio_set_direction(gpio_num, RTC_GPIO_MODE_OUTPUT_ONLY)); + TEST_ESP_OK(rtc_gpio_set_level(gpio_num, 0)); + } + vTaskDelay(10 / portTICK_PERIOD_MS); +} + +static void adc_io_normal(adc_unit_t adc_unit, adc_channel_t channel) +{ + gpio_num_t gpio_num = 0; + if (adc_unit == ADC_UNIT_1) { + gpio_num = ADC_GET_IO_NUM(0, channel); + TEST_ESP_OK(rtc_gpio_init(gpio_num)); + TEST_ESP_OK(rtc_gpio_pullup_dis(gpio_num)); + TEST_ESP_OK(rtc_gpio_pulldown_dis(gpio_num)); + TEST_ESP_OK(gpio_set_pull_mode(gpio_num, GPIO_FLOATING)); + TEST_ESP_OK(rtc_gpio_set_direction(gpio_num, RTC_GPIO_MODE_DISABLED)); + } + if (adc_unit == ADC_UNIT_2) { + gpio_num = ADC_GET_IO_NUM(1, channel); + TEST_ESP_OK(rtc_gpio_init(gpio_num)); + TEST_ESP_OK(rtc_gpio_pullup_dis(gpio_num)); + TEST_ESP_OK(rtc_gpio_pulldown_dis(gpio_num)); + TEST_ESP_OK(gpio_set_pull_mode(gpio_num, GPIO_FLOATING)); + TEST_ESP_OK(rtc_gpio_set_direction(gpio_num, RTC_GPIO_MODE_DISABLED)); + } + vTaskDelay(10 / portTICK_PERIOD_MS); +} + +/** + * @brief I2S ADC/DAC mode init. + */ +static void example_i2s_init(void) +{ + int i2s_num = EXAMPLE_I2S_NUM; + i2s_config_t i2s_config = { + .mode = I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_ADC_BUILT_IN, + .sample_rate = EXAMPLE_I2S_SAMPLE_RATE, + .bits_per_sample = EXAMPLE_I2S_SAMPLE_BITS, + .channel_format = EXAMPLE_I2S_FORMAT, + .intr_alloc_flags = 0, + .dma_desc_num = 2, + .dma_frame_num = 1024, + .use_apll = 0, + }; + + //install and start i2s driver + TEST_ESP_OK( i2s_driver_install(i2s_num, &i2s_config, 0, NULL) ); + //init ADC pad + TEST_ESP_OK( i2s_set_adc_mode(I2S_ADC_UNIT, I2S_ADC_CHANNEL) ); +} + +static void example_i2s_deinit(void) +{ + TEST_ESP_OK( i2s_driver_uninstall(EXAMPLE_I2S_NUM) ); +} + +/** + * @brief debug buffer data + */ +static void example_disp_buf(uint8_t *buf, int length) +{ + printf("\n======"); + for (int i = 0; i < length; i += 2) { + uint16_t data = ((uint16_t)buf[i+1] << 8) | (uint16_t)buf[i]; + adc_digi_output_data_t *p = (adc_digi_output_data_t *)&data; + if ((i) % 16 == 0) printf("\n"); + printf("[%d_%d] ", p->type1.channel, p->type1.data); + } + printf("\n======\n"); +} + +static esp_err_t adc_dma_data_check(uint8_t *buf, int length, int ideal_level) +{ + for (int i = 0; i < length; i += 2) { + uint16_t data = ((uint16_t)buf[i+1] << 8) | (uint16_t)buf[i]; + adc_digi_output_data_t *p = (adc_digi_output_data_t *)&data; + if (p->type1.channel != I2S_ADC_CHANNEL) { + TEST_FAIL_MESSAGE("I2S-DMA data channel error!"); + } + if (ideal_level == 1) { // high level 3.3v + TEST_ASSERT_EQUAL( 0xFFF, p->type1.data ); + } else if (ideal_level == 0) { // low level 0v + TEST_ASSERT_LESS_THAN( 10, p->type1.data ); + } else if (ideal_level == 2) { // middle level 1.4v + TEST_ASSERT_INT_WITHIN( 128, 1586, p->type1.data ); + } else if (ideal_level == 3) { // normal level + } else { // no check + } + } + return ESP_OK; +} + +static void adc_dma_read(uint8_t *buf, int length) +{ + size_t bytes_read = 0; + int flash_wr_size = 0; + + vTaskDelay(pdTICKS_TO_MS(100)); + while (flash_wr_size < length) { + //read data from I2S bus, in this case, from ADC. + TEST_ESP_OK( i2s_read(EXAMPLE_I2S_NUM, (void *) buf + flash_wr_size, length - flash_wr_size, &bytes_read, portMAX_DELAY) ); + flash_wr_size += bytes_read; + example_disp_buf((uint8_t *) buf, 128); + } +} + +TEST_CASE("ADC_DMA_read", "[adc dma]") +{ + int i2s_read_len = EXAMPLE_I2S_READ_LEN; + char *i2s_read_buff = (char *) calloc(i2s_read_len, sizeof(char)); + + example_i2s_init(); + TEST_ESP_OK( i2s_adc_enable(EXAMPLE_I2S_NUM) ); + + adc_fake_tie_low(I2S_ADC_UNIT, I2S_ADC_CHANNEL); + adc_dma_read((uint8_t *)i2s_read_buff, i2s_read_len); + adc_dma_data_check((uint8_t *)i2s_read_buff, i2s_read_len, 0); + + adc_fake_tie_middle(I2S_ADC_UNIT, I2S_ADC_CHANNEL); + adc_dma_read((uint8_t *)i2s_read_buff, i2s_read_len); + adc_dma_data_check((uint8_t *)i2s_read_buff, i2s_read_len, 2); + + adc_fake_tie_high(I2S_ADC_UNIT, I2S_ADC_CHANNEL); + adc_dma_read((uint8_t *)i2s_read_buff, i2s_read_len); + adc_dma_data_check((uint8_t *)i2s_read_buff, i2s_read_len, 1); + + adc_io_normal(I2S_ADC_UNIT, I2S_ADC_CHANNEL); + + TEST_ESP_OK( i2s_adc_disable(EXAMPLE_I2S_NUM) ); + if (i2s_read_buff) { + free(i2s_read_buff); + i2s_read_buff = NULL; + } + + example_i2s_deinit(); +} + +#endif // CONFIG_IDF_TARGET_ESP32 diff --git a/components/driver/test_apps/i2s_test_apps/legacy_i2s_adc_dac/main/test_i2s_dac.c b/components/driver/test_apps/i2s_test_apps/legacy_i2s_adc_dac/main/test_i2s_dac.c new file mode 100644 index 0000000000..7af9a520f0 --- /dev/null +++ b/components/driver/test_apps/i2s_test_apps/legacy_i2s_adc_dac/main/test_i2s_dac.c @@ -0,0 +1,160 @@ +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + Tests for the dac device driver on ESP32 only + Hardware connection: + - ESP32: GPIO25 <---> GPIO26 +*/ +#include "sdkconfig.h" +#if CONFIG_IDF_TARGET_ESP32 + +#include "esp_system.h" +#include "driver/adc.h" +#include "unity.h" +#include "esp_system.h" +#include "esp_event.h" +#include "esp_wifi.h" +#include "esp_log.h" +#include "nvs_flash.h" +#include "test_dac_audio_file.h" +#include "driver/i2s.h" +#include "driver/dac.h" + +/* + * DAC DMA config. + */ + +//enable record sound and save in flash +#define RECORD_IN_FLASH_EN (1) +//enable replay recorded sound in flash +#define REPLAY_FROM_FLASH_EN (1) + +//i2s number +#define EXAMPLE_I2S_NUM (0) +//i2s sample rate +#define EXAMPLE_I2S_SAMPLE_RATE (16000) +//i2s data bits +#define EXAMPLE_I2S_SAMPLE_BITS (16) +//enable display buffer for debug +#define EXAMPLE_I2S_BUF_DEBUG (0) +//I2S read buffer length +#define EXAMPLE_I2S_READ_LEN (16 * 1024) +//I2S data format +#define EXAMPLE_I2S_FORMAT (I2S_CHANNEL_FMT_RIGHT_LEFT) +//I2S channel number +#define EXAMPLE_I2S_CHANNEL_NUM ((EXAMPLE_I2S_FORMAT < I2S_CHANNEL_FMT_ONLY_RIGHT) ? (2) : (1)) + +/** + * @brief I2S ADC/DAC mode init. + */ +static void example_i2s_init(void) +{ + int i2s_num = EXAMPLE_I2S_NUM; + i2s_config_t i2s_config = { + .mode = I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN, + .sample_rate = EXAMPLE_I2S_SAMPLE_RATE, + .bits_per_sample = EXAMPLE_I2S_SAMPLE_BITS, + .channel_format = EXAMPLE_I2S_FORMAT, + .intr_alloc_flags = 0, + .dma_desc_num = 2, + .dma_frame_num = 1024, + .use_apll = 0, + }; + //install and start i2s driver + TEST_ESP_OK( i2s_driver_install(i2s_num, &i2s_config, 0, NULL) ); + //init DAC pad + TEST_ESP_OK( i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN) ); +} + +static void example_i2s_deinit(void) +{ + TEST_ESP_OK( i2s_set_dac_mode(I2S_DAC_CHANNEL_DISABLE) ); + TEST_ESP_OK( i2s_driver_uninstall(EXAMPLE_I2S_NUM) ); +} + +/** + * @brief Set i2s clock for example audio file + */ +static void example_set_file_play_mode(void) +{ + TEST_ESP_OK( i2s_set_clk(EXAMPLE_I2S_NUM, 16000, EXAMPLE_I2S_SAMPLE_BITS, 1) ); +} + +/** + * @brief Scale data to 16bit/32bit for I2S DMA output. + * DAC can only output 8bit data value. + * I2S DMA will still send 16 bit or 32bit data, the highest 8bit contains DAC data. + */ +static int example_i2s_dac_data_scale(uint8_t *d_buff, uint8_t *s_buff, uint32_t len) +{ + uint32_t j = 0; +#if (EXAMPLE_I2S_SAMPLE_BITS == 16) + for (int i = 0; i < len; i++) { + d_buff[j++] = 0; + d_buff[j++] = s_buff[i]; + } + return (len * 2); +#else + for (int i = 0; i < len; i++) { + d_buff[j++] = 0; + d_buff[j++] = 0; + d_buff[j++] = 0; + d_buff[j++] = s_buff[i]; + } + return (len * 4); +#endif +} +/** + * @brief debug buffer data + */ +static void example_disp_buf(uint8_t *buf, int length) +{ + printf("======\n"); + for (int i = 0; i < length; i++) { + printf("%02x ", buf[i]); + if ((i + 1) % 8 == 0) { + printf("\n"); + } + } + printf("======\n"); +} + +/** + * @brief Reset i2s clock and mode + */ +static void example_reset_play_mode(void) +{ + TEST_ESP_OK( i2s_set_clk(EXAMPLE_I2S_NUM, EXAMPLE_I2S_SAMPLE_RATE, EXAMPLE_I2S_SAMPLE_BITS, EXAMPLE_I2S_CHANNEL_NUM) ); +} + +TEST_CASE("DAC_DMA_output", "[dac]") +{ + size_t bytes_written; + int i2s_read_len = EXAMPLE_I2S_READ_LEN; + uint8_t *i2s_write_buff = (uint8_t *) calloc(i2s_read_len, sizeof(char)); + int offset = 0; + int tot_size = sizeof(audio_table); + printf("Playing file example: \n"); + + example_i2s_init(); + example_set_file_play_mode(); + + while (offset < tot_size) { + int play_len = ((tot_size - offset) > (4 * 1024)) ? (4 * 1024) : (tot_size - offset); + int i2s_wr_len = example_i2s_dac_data_scale(i2s_write_buff, (uint8_t *)(audio_table + offset), play_len); + i2s_write(EXAMPLE_I2S_NUM, i2s_write_buff, i2s_wr_len, &bytes_written, portMAX_DELAY); + offset += play_len; + example_disp_buf((uint8_t *) i2s_write_buff, 32); + } + + example_reset_play_mode(); + free(i2s_write_buff); + + example_i2s_deinit(); +} + +#endif // CONFIG_IDF_TARGET_ESP32 diff --git a/components/driver/test_apps/i2s_test_apps/legacy_i2s_adc_dac/pytest_legacy_i2s_adc_dac.py b/components/driver/test_apps/i2s_test_apps/legacy_i2s_adc_dac/pytest_legacy_i2s_adc_dac.py new file mode 100644 index 0000000000..f3b2df44d9 --- /dev/null +++ b/components/driver/test_apps/i2s_test_apps/legacy_i2s_adc_dac/pytest_legacy_i2s_adc_dac.py @@ -0,0 +1,20 @@ +# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Apache-2.0 + +import pytest +from pytest_embedded import Dut + + +@pytest.mark.esp32 +@pytest.mark.generic +@pytest.mark.parametrize( + 'config', + [ + 'release', + ], + indirect=True, +) +def test_i2s_adc_dac(dut: Dut) -> None: + dut.expect_exact('Press ENTER to see the list of tests') + dut.write('*') + dut.expect_unity_test_output() diff --git a/components/driver/test_apps/i2s_test_apps/legacy_i2s_adc_dac/sdkconfig.ci.release b/components/driver/test_apps/i2s_test_apps/legacy_i2s_adc_dac/sdkconfig.ci.release new file mode 100644 index 0000000000..2b8cfffb06 --- /dev/null +++ b/components/driver/test_apps/i2s_test_apps/legacy_i2s_adc_dac/sdkconfig.ci.release @@ -0,0 +1,9 @@ +CONFIG_PM_ENABLE=y +CONFIG_FREERTOS_USE_TICKLESS_IDLE=y +CONFIG_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y +CONFIG_I2S_ISR_IRAM_SAFE=y +CONFIG_COMPILER_DUMP_RTL_FILES=y +# silent the error check, as the error string are stored in rodata, causing RTL check failure +CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT=y diff --git a/components/driver/test_apps/i2s/sdkconfig.defaults b/components/driver/test_apps/i2s_test_apps/legacy_i2s_adc_dac/sdkconfig.defaults similarity index 60% rename from components/driver/test_apps/i2s/sdkconfig.defaults rename to components/driver/test_apps/i2s_test_apps/legacy_i2s_adc_dac/sdkconfig.defaults index 16e72deaf9..7fb17baea9 100644 --- a/components/driver/test_apps/i2s/sdkconfig.defaults +++ b/components/driver/test_apps/i2s_test_apps/legacy_i2s_adc_dac/sdkconfig.defaults @@ -1,3 +1,3 @@ CONFIG_I2S_SUPPRESS_DEPRECATE_WARN=y -CONFIG_PCNT_SUPPRESS_DEPRECATE_WARN=y +CONFIG_I2S_ENABLE_DEBUG_LOG=y CONFIG_ESP_TASK_WDT=n diff --git a/components/driver/test_apps/i2s/CMakeLists.txt b/components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/CMakeLists.txt similarity index 65% rename from components/driver/test_apps/i2s/CMakeLists.txt rename to components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/CMakeLists.txt index 3d2e9717ee..0acac81f65 100644 --- a/components/driver/test_apps/i2s/CMakeLists.txt +++ b/components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/CMakeLists.txt @@ -1,5 +1,5 @@ # This is the project CMakeLists.txt file for the test subproject -cmake_minimum_required(VERSION 3.5) +cmake_minimum_required(VERSION 3.16) include($ENV{IDF_PATH}/tools/cmake/project.cmake) -project(i2s_test) +project(i2s_legacy_test) diff --git a/components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/README.md b/components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/README.md new file mode 100644 index 0000000000..36802259d0 --- /dev/null +++ b/components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/README.md @@ -0,0 +1,2 @@ +| Supported Targets | ESP32 | ESP32-S2 | ESP32-S3 | ESP32-C3 | +| ----------------- | ----- | -------- | -------- | -------- | \ No newline at end of file diff --git a/components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/main/CMakeLists.txt b/components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/main/CMakeLists.txt new file mode 100644 index 0000000000..5a3a449155 --- /dev/null +++ b/components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/main/CMakeLists.txt @@ -0,0 +1,6 @@ +set(srcs "test_app_main.c" + "test_legacy_i2s.c") + +idf_component_register(SRCS ${srcs} + PRIV_INCLUDE_DIRS "../../" + WHOLE_ARCHIVE) diff --git a/components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/main/test_app_main.c b/components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/main/test_app_main.c new file mode 100644 index 0000000000..e2c05a7a08 --- /dev/null +++ b/components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/main/test_app_main.c @@ -0,0 +1,53 @@ +/* + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "unity.h" +#include "unity_test_runner.h" +#include "esp_heap_caps.h" + +// Some resources are lazy allocated in I2S driver, the threadhold is left for that case +#define TEST_MEMORY_LEAK_THRESHOLD (-400) + +static size_t before_free_8bit; +static size_t before_free_32bit; + +static void check_leak(size_t before_free, size_t after_free, const char *type) +{ + ssize_t delta = after_free - before_free; + printf("MALLOC_CAP_%s: Before %u bytes free, After %u bytes free (delta %d)\n", type, before_free, after_free, delta); + TEST_ASSERT_MESSAGE(delta >= TEST_MEMORY_LEAK_THRESHOLD, "memory leak"); +} + +void setUp(void) +{ + before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); + before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); +} + +void tearDown(void) +{ + size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); + size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); + check_leak(before_free_8bit, after_free_8bit, "8BIT"); + check_leak(before_free_32bit, after_free_32bit, "32BIT"); +} + +void app_main(void) +{ + // ___ ____ ____ _____ _ + // |_ _|___ \/ ___| |_ _|__ ___| |_ + // | | __) \___ \ | |/ _ \/ __| __| + // | | / __/ ___) | | | __/\__ \ |_ + // |___|_____|____/ |_|\___||___/\__| + + printf(" ___ ____ ____ _____ _ \r\n"); + printf(" |_ _|___ \\/ ___| |_ _|__ ___| |_ \r\n"); + printf(" | | __) \\___ \\ | |/ _ \\/ __| __|\r\n"); + printf(" | | / __/ ___) | | | __/\\__ \\ |_ \r\n"); + printf(" |___|_____|____/ |_|\\___||___/\\__| (legacy)\r\n"); + + unity_run_menu(); +} diff --git a/components/driver/test_apps/i2s/main/test_i2s_legacy.c b/components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/main/test_legacy_i2s.c similarity index 63% rename from components/driver/test_apps/i2s/main/test_i2s_legacy.c rename to components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/main/test_legacy_i2s.c index 03cad7ed12..a6ea825982 100644 --- a/components/driver/test_apps/i2s/main/test_i2s_legacy.c +++ b/components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/main/test_legacy_i2s.c @@ -17,70 +17,27 @@ #include "freertos/task.h" #include "freertos/queue.h" #include "driver/i2s.h" +#include "hal/i2s_hal.h" +#include "soc/i2s_periph.h" +#include "soc/soc_caps.h" #include "driver/gpio.h" #include "hal/gpio_hal.h" #include "unity.h" #include "math.h" #include "esp_rom_gpio.h" - -#define SAMPLE_RATE (36000) -#define SAMPLE_BITS (16) - -#if CONFIG_IDF_TARGET_ESP32 -#define MASTER_BCK_IO 15 -#define MASTER_WS_IO 25 -#define SLAVE_BCK_IO 19 -#define SLAVE_WS_IO 26 -#define DATA_IN_IO 21 -#define DATA_OUT_IO 22 -#define ADC1_CHANNEL_4_IO 32 -#define I2S0_DATA_OUT_IDX I2S0O_DATA_OUT23_IDX -#define I2S0_DATA_IN_IDX I2S0I_DATA_IN15_IDX -#define I2S1_DATA_OUT_IDX I2S1O_DATA_OUT23_IDX -#define I2S1_DATA_IN_IDX I2S1I_DATA_IN15_IDX -#elif CONFIG_IDF_TARGET_ESP32S2 -#define MASTER_BCK_IO 15 -#define MASTER_WS_IO 28 -#define SLAVE_BCK_IO 19 -#define SLAVE_WS_IO 26 -#define DATA_IN_IO 21 -#define DATA_OUT_IO 20 -#define I2S0_DATA_OUT_IDX I2S0O_DATA_OUT23_IDX -#define I2S0_DATA_IN_IDX I2S0I_DATA_IN15_IDX -#elif CONFIG_IDF_TARGET_ESP32C3 -// TODO: change pins -#define MASTER_BCK_IO 4 -#define MASTER_WS_IO 5 -#define SLAVE_BCK_IO 14 -#define SLAVE_WS_IO 15 -#define DATA_IN_IO 19 -#define DATA_OUT_IO 18 -#define I2S0_DATA_OUT_IDX I2SO_SD_OUT_IDX -#define I2S0_DATA_IN_IDX I2SI_SD_IN_IDX -#elif CONFIG_IDF_TARGET_ESP32S3 -#define MASTER_BCK_IO 4 -#define MASTER_WS_IO 5 -#define SLAVE_BCK_IO 14 -#define SLAVE_WS_IO 15 -#define DATA_IN_IO 19 -#define DATA_OUT_IO 18 -#define I2S0_DATA_OUT_IDX I2S0O_SD_OUT_IDX -#define I2S0_DATA_IN_IDX I2S0I_SD_IN_IDX -#define I2S1_DATA_OUT_IDX I2S1O_SD_OUT_IDX -#define I2S1_DATA_IN_IDX I2S1I_SD_IN_IDX +#if SOC_PCNT_SUPPORTED +#include "driver/pulse_cnt.h" +#include "soc/pcnt_periph.h" #endif +#include "test_inc/test_i2s.h" + #define PERCENT_DIFF 0.0001 -#define I2S_TEST_MODE_SLAVE_TO_MAXTER 0 +#define I2S_TEST_MODE_SLAVE_TO_MASTER 0 #define I2S_TEST_MODE_MASTER_TO_SLAVE 1 #define I2S_TEST_MODE_LOOPBACK 2 -// This empty function is used to force the compiler link this file -void test_app_include_i2s_legacy(void) -{ -} - // mode: 0, master rx, slave tx. mode: 1, master tx, slave rx. mode: 2, master tx rx loop-back // Since ESP32-S2 has only one I2S, only loop back test can be tested. static void i2s_test_io_config(int mode) @@ -96,33 +53,33 @@ static void i2s_test_io_config(int mode) switch (mode) { #if SOC_I2S_NUM > 1 - case I2S_TEST_MODE_SLAVE_TO_MAXTER: { - esp_rom_gpio_connect_out_signal(MASTER_BCK_IO, I2S0I_BCK_OUT_IDX, 0, 0); - esp_rom_gpio_connect_in_signal(MASTER_BCK_IO, I2S1O_BCK_IN_IDX, 0); + case I2S_TEST_MODE_SLAVE_TO_MASTER: { + esp_rom_gpio_connect_out_signal(MASTER_BCK_IO, i2s_periph_signal[0].m_rx_bck_sig, 0, 0); + esp_rom_gpio_connect_in_signal(MASTER_BCK_IO, i2s_periph_signal[1].s_tx_bck_sig, 0); - esp_rom_gpio_connect_out_signal(MASTER_WS_IO, I2S0I_WS_OUT_IDX, 0, 0); - esp_rom_gpio_connect_in_signal(MASTER_WS_IO, I2S1O_WS_IN_IDX, 0); + esp_rom_gpio_connect_out_signal(MASTER_WS_IO, i2s_periph_signal[0].m_rx_ws_sig, 0, 0); + esp_rom_gpio_connect_in_signal(MASTER_WS_IO, i2s_periph_signal[1].s_tx_ws_sig, 0); - esp_rom_gpio_connect_out_signal(DATA_OUT_IO, I2S1_DATA_OUT_IDX, 0, 0); - esp_rom_gpio_connect_in_signal(DATA_OUT_IO, I2S0_DATA_IN_IDX, 0); + esp_rom_gpio_connect_out_signal(DATA_OUT_IO, i2s_periph_signal[1].data_out_sig, 0, 0); + esp_rom_gpio_connect_in_signal(DATA_OUT_IO, i2s_periph_signal[0].data_in_sig, 0); } break; case I2S_TEST_MODE_MASTER_TO_SLAVE: { - esp_rom_gpio_connect_out_signal(MASTER_BCK_IO, I2S0O_BCK_OUT_IDX, 0, 0); - esp_rom_gpio_connect_in_signal(MASTER_BCK_IO, I2S1I_BCK_IN_IDX, 0); + esp_rom_gpio_connect_out_signal(MASTER_BCK_IO, i2s_periph_signal[0].m_tx_bck_sig, 0, 0); + esp_rom_gpio_connect_in_signal(MASTER_BCK_IO, i2s_periph_signal[1].s_rx_bck_sig, 0); - esp_rom_gpio_connect_out_signal(MASTER_WS_IO, I2S0O_WS_OUT_IDX, 0, 0); - esp_rom_gpio_connect_in_signal(MASTER_WS_IO, I2S1I_WS_IN_IDX, 0); + esp_rom_gpio_connect_out_signal(MASTER_WS_IO, i2s_periph_signal[0].m_tx_ws_sig, 0, 0); + esp_rom_gpio_connect_in_signal(MASTER_WS_IO, i2s_periph_signal[1].s_rx_ws_sig, 0); - esp_rom_gpio_connect_out_signal(DATA_OUT_IO, I2S0_DATA_OUT_IDX, 0, 0); - esp_rom_gpio_connect_in_signal(DATA_OUT_IO, I2S1_DATA_IN_IDX, 0); + esp_rom_gpio_connect_out_signal(DATA_OUT_IO, i2s_periph_signal[0].data_out_sig, 0, 0); + esp_rom_gpio_connect_in_signal(DATA_OUT_IO, i2s_periph_signal[1].data_in_sig, 0); } break; #endif case I2S_TEST_MODE_LOOPBACK: { - esp_rom_gpio_connect_out_signal(DATA_OUT_IO, I2S0_DATA_OUT_IDX, 0, 0); - esp_rom_gpio_connect_in_signal(DATA_OUT_IO, I2S0_DATA_IN_IDX, 0); + esp_rom_gpio_connect_out_signal(DATA_OUT_IO, i2s_periph_signal[0].data_out_sig, 0, 0); + esp_rom_gpio_connect_in_signal(DATA_OUT_IO, i2s_periph_signal[0].data_in_sig, 0); } break; @@ -133,13 +90,81 @@ static void i2s_test_io_config(int mode) } } +#if SOC_I2S_SUPPORTS_ADC +#define ADC1_CHANNEL_4_IO 32 +/* Only ESP32 need I2S adc/dac test */ +TEST_CASE("I2S_adc_test", "[i2s_legacy]") +{ + // init I2S ADC + i2s_config_t i2s_config = { + .mode = I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_ADC_BUILT_IN, + .sample_rate = SAMPLE_RATE, + .bits_per_sample = SAMPLE_BITS, + .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, + .intr_alloc_flags = 0, + .dma_desc_num = 2, + .dma_frame_num = 1024, + .use_apll = 0, + }; + // install and start I2S driver + i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL); + // init ADC pad + i2s_set_adc_mode(ADC_UNIT_1, ADC1_CHANNEL_4); + // enable adc sampling, ADC_WIDTH_BIT_12, ADC_ATTEN_DB_11 hard-coded in adc_i2s_mode_init + i2s_adc_enable(I2S_NUM_0); + // init read buffer + uint16_t *i2sReadBuffer = (uint16_t *)calloc(1024, sizeof(uint16_t)); + size_t bytesRead; + + for (int loop = 0; loop < 10; loop++) { + for (int level = 0; level <= 1; level++) { + if (level == 0) { + gpio_set_pull_mode(ADC1_CHANNEL_4_IO, GPIO_PULLDOWN_ONLY); + } else { + gpio_set_pull_mode(ADC1_CHANNEL_4_IO, GPIO_PULLUP_ONLY); + } + vTaskDelay(pdMS_TO_TICKS(200)); + // read data from adc, will block until buffer is full + i2s_read(I2S_NUM_0, (void *)i2sReadBuffer, 1024 * sizeof(uint16_t), &bytesRead, portMAX_DELAY); + + // calc average + int64_t adcSumValue = 0; + for (size_t i = 0; i < 1024; i++) { + adcSumValue += i2sReadBuffer[i] & 0xfff; + } + int adcAvgValue = adcSumValue / 1024; + printf("adc average val: %d\n", adcAvgValue); + + if (level == 0) { + if (adcAvgValue > 100) { + i2s_adc_disable(I2S_NUM_0); + free(i2sReadBuffer); + i2s_driver_uninstall(I2S_NUM_0); + TEST_ASSERT_LESS_THAN(100, adcAvgValue); + } + } else { + if (adcAvgValue < 4000) { + i2s_adc_disable(I2S_NUM_0); + free(i2sReadBuffer); + i2s_driver_uninstall(I2S_NUM_0); + TEST_ASSERT_GREATER_THAN(4000, adcAvgValue); + } + } + } + } + + i2s_adc_disable(I2S_NUM_0); + free(i2sReadBuffer); + i2s_driver_uninstall(I2S_NUM_0); +} +#endif /** * i2s initialize test * 1. i2s_driver_install * 2. i2s_set_pin */ -TEST_CASE("I2S basic driver install, uninstall, set pin test", "[i2s_legacy]") +TEST_CASE("I2S_basic_driver_installation_uninstallation_and_settings_test", "[i2s_legacy]") { // dac, adc i2s i2s_config_t i2s_config = { @@ -177,7 +202,7 @@ TEST_CASE("I2S basic driver install, uninstall, set pin test", "[i2s_legacy]") TEST_ESP_OK(i2s_driver_uninstall(I2S_NUM_0)); //error param test - TEST_ASSERT(i2s_driver_install(I2S_NUM_MAX, &i2s_config, 0, NULL) == ESP_ERR_INVALID_ARG); + TEST_ASSERT(i2s_driver_install(SOC_I2S_NUM, &i2s_config, 0, NULL) == ESP_ERR_INVALID_ARG); TEST_ASSERT(i2s_driver_install(I2S_NUM_0, NULL, 0, NULL) == ESP_ERR_INVALID_ARG); i2s_config.dma_desc_num = 1; TEST_ASSERT(i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL) == ESP_ERR_INVALID_ARG); @@ -186,15 +211,24 @@ TEST_CASE("I2S basic driver install, uninstall, set pin test", "[i2s_legacy]") TEST_ASSERT_EQUAL(ESP_ERR_INVALID_STATE, i2s_driver_uninstall(I2S_NUM_0)); } -TEST_CASE("I2S Loopback test(master tx and rx)", "[i2s_legacy]") +/** + * @brief Test mono and stereo mode of I2S by loopback + * @note Only rx channel distinguish left mono and right mono, tx channel does not + * @note 1. Check switch mono/stereo by 'i2s_set_clk' + * 2. Check rx right mono and left mono (requiring tx works in stereo mode) + * 3. Check tx mono (requiring rx works in stereo mode) + */ +TEST_CASE("I2S_mono_stereo_loopback_test", "[i2s_legacy]") { +#define WRITE_BUF_LEN 2000 +#define READ_BUF_LEN 4000 // master driver installed and send data i2s_config_t master_i2s_config = { .mode = I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_RX, .sample_rate = SAMPLE_RATE, .bits_per_sample = SAMPLE_BITS, - .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, - .communication_format = I2S_COMM_FORMAT_STAND_I2S, + .channel_format = I2S_CHANNEL_FMT_ONLY_RIGHT, + .communication_format = I2S_COMM_FORMAT_STAND_MSB, .dma_desc_num = 6, .dma_frame_num = 100, .use_apll = 0, @@ -215,51 +249,152 @@ TEST_CASE("I2S Loopback test(master tx and rx)", "[i2s_legacy]") .data_out_num = DATA_OUT_IO, .data_in_num = DATA_IN_IO }; + /* Install I2S in duplex mode */ TEST_ESP_OK(i2s_driver_install(I2S_NUM_0, &master_i2s_config, 0, NULL)); + TEST_ESP_OK(i2s_stop(I2S_NUM_0)); + /* Config TX as stereo channel directly, because legacy driver can't support config tx&rx separately */ +#if SOC_I2S_HW_VERSION_1 + i2s_ll_tx_select_slot(&I2S0, I2S_STD_SLOT_LEFT_RIGHT, true); +#else + i2s_ll_tx_select_slot(&I2S0, I2S_STD_SLOT_LEFT_RIGHT); +#endif + i2s_ll_tx_enable_mono_mode(&I2S0, false); + TEST_ESP_OK(i2s_set_pin(I2S_NUM_0, &master_pin_config)); i2s_test_io_config(I2S_TEST_MODE_LOOPBACK); - printf("\r\nheap size: %d\n", esp_get_free_heap_size()); - uint8_t *data_wr = (uint8_t *)malloc(sizeof(uint8_t) * 400); - size_t i2s_bytes_write = 0; - size_t bytes_read = 0; - int length = 0; - uint8_t *i2s_read_buff = (uint8_t *)malloc(sizeof(uint8_t) * 10000); + TEST_ESP_OK(i2s_start(I2S_NUM_0)); - for (int i = 0; i < 100; i++) { - data_wr[i] = i + 1; + uint16_t *w_buf = calloc(1, WRITE_BUF_LEN); + uint16_t *r_buf = calloc(1, READ_BUF_LEN); + size_t w_bytes = 0; + size_t r_bytes = 0; + for (int n = 0; n < WRITE_BUF_LEN / 2; n++) { + w_buf[n] = n%100; } - int flag = 0; // break loop flag - int end_position = 0; - // write data to slave - i2s_write(I2S_NUM_0, data_wr, sizeof(uint8_t) * 400, &i2s_bytes_write, 1000 / portTICK_PERIOD_MS); - while (!flag) { - if (length >= 10000 - 500) { + /* rx right mono test + * tx format: 0x00[L] 0x01[R] 0x02[L] 0x03[R] ... + * rx receive: 0x01[R] 0x03[R] ... */ + TEST_ESP_OK(i2s_write(I2S_NUM_0, w_buf, WRITE_BUF_LEN, &w_bytes, portMAX_DELAY)); + TEST_ESP_OK(i2s_read(I2S_NUM_0, r_buf, READ_BUF_LEN, &r_bytes, portMAX_DELAY)); +#if CONFIG_IDF_TARGET_ESP32 + /* The data of tx/rx channels are flipped on ESP32 */ + for (int n = 0; n < READ_BUF_LEN / 2; n += 2) { + int16_t temp = r_buf[n]; + r_buf[n] = r_buf[n+1]; + r_buf[n+1] = temp; + } +#endif + int i = 0; + for (i = 0; (i < READ_BUF_LEN / 2); i++) { + if (r_buf[i] == 1) { + printf("%d %d %d %d\n%d %d %d %d\n", + r_buf[i], r_buf[i+1], r_buf[i+2], r_buf[i+3], + r_buf[i+4], r_buf[i+5], r_buf[i+6], r_buf[i+7]); break; } - i2s_read(I2S_NUM_0, i2s_read_buff + length, sizeof(uint8_t) * 500, &bytes_read, 1000 / portMAX_DELAY); - if (bytes_read > 0) { - for (int i = length; i < length + bytes_read; i++) { - if (i2s_read_buff[i] == 100) { - flag = 1; - end_position = i; - break; - } - } + } + printf("Data start index: %d\n", i); + TEST_ASSERT(i < READ_BUF_LEN / 2 - 50); + for (int16_t j = 1; j < 100; j += 2) { + TEST_ASSERT_EQUAL_INT16(r_buf[i++], j); + } + printf("rx right mono test passed\n"); + + /* tx/rx stereo test + * tx format: 0x00[L] 0x01[R] 0x02[L] 0x03[R] ... + * rx receive: 0x00[L] 0x01[R] 0x02[L] 0x03[R] ... */ + TEST_ESP_OK(i2s_set_clk(I2S_NUM_0, SAMPLE_RATE, SAMPLE_BITS, I2S_CHANNEL_STEREO)); + TEST_ESP_OK(i2s_write(I2S_NUM_0, w_buf, WRITE_BUF_LEN, &w_bytes, portMAX_DELAY)); + TEST_ESP_OK(i2s_read(I2S_NUM_0, r_buf, READ_BUF_LEN, &r_bytes, portMAX_DELAY)); + + for (i = 0; (i < READ_BUF_LEN / 2); i++) { + if (r_buf[i] == 1) { + printf("%d %d %d %d\n%d %d %d %d\n", + r_buf[i], r_buf[i+1], r_buf[i+2], r_buf[i+3], + r_buf[i+4], r_buf[i+5], r_buf[i+6], r_buf[i+7]); + break; } - length = length + bytes_read; } - // test the read data right or not - for (int i = end_position - 99; i <= end_position; i++) { - TEST_ASSERT_EQUAL_UINT8((i - end_position + 100), *(i2s_read_buff + i)); + printf("Data start index: %d\n", i); + TEST_ASSERT(i < READ_BUF_LEN / 2 - 100); + TEST_ASSERT(i % 2); + for (int16_t j = 1; j < 100; j ++) { + TEST_ASSERT_EQUAL_INT16(r_buf[i++], j); // receive all number } - free(data_wr); - free(i2s_read_buff); - i2s_driver_uninstall(I2S_NUM_0); + printf("tx/rx stereo test passed\n"); + + /* tx mono rx right mono test + * tx format: 0x01[L] 0x01[R] 0x02[L] 0x02[R] ... + * rx receive: 0x01[R] 0x02[R] ... */ + TEST_ESP_OK(i2s_set_clk(I2S_NUM_0, SAMPLE_RATE, I2S_BITS_PER_SAMPLE_32BIT, I2S_CHANNEL_MONO)); + TEST_ESP_OK(i2s_write(I2S_NUM_0, w_buf, WRITE_BUF_LEN, &w_bytes, portMAX_DELAY)); + TEST_ESP_OK(i2s_read(I2S_NUM_0, r_buf, READ_BUF_LEN, &r_bytes, portMAX_DELAY)); + + for (i = 0; i < READ_BUF_LEN / 2; i++) { + if (r_buf[i] == 1) { + printf("%d %d %d %d\n%d %d %d %d\n", + r_buf[i], r_buf[i+1], r_buf[i+2], r_buf[i+3], + r_buf[i+4], r_buf[i+5], r_buf[i+6], r_buf[i+7]); + break; + } + } + printf("Data start index: %d\n", i); + TEST_ASSERT(i < READ_BUF_LEN / 2 - 100); + for (int16_t j = 1; j < 100; j ++) { + TEST_ASSERT_EQUAL_INT16(r_buf[i++], j); + } + printf("tx/rx mono test passed\n"); + + /* Reinstalling I2S to test rx left mono */ + TEST_ESP_OK(i2s_driver_uninstall(I2S_NUM_0)); + master_i2s_config.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT; + TEST_ESP_OK(i2s_driver_install(I2S_NUM_0, &master_i2s_config, 0, NULL)); + TEST_ESP_OK(i2s_stop(I2S_NUM_0)); +#if SOC_I2S_HW_VERSION_1 + i2s_ll_tx_select_slot(&I2S0, I2S_STD_SLOT_LEFT_RIGHT, true); +#else + i2s_ll_tx_select_slot(&I2S0, I2S_STD_SLOT_LEFT_RIGHT); +#endif + i2s_ll_tx_enable_mono_mode(&I2S0, false); + + TEST_ESP_OK(i2s_start(I2S_NUM_0)); + + /* rx left mono test + * tx format: 0x00[L] 0x01[R] 0x02[L] 0x03[R] ... + * rx receive: 0x00[R] 0x02[R] ... */ + TEST_ESP_OK(i2s_write(I2S_NUM_0, w_buf, WRITE_BUF_LEN, &w_bytes, portMAX_DELAY)); + TEST_ESP_OK(i2s_read(I2S_NUM_0, r_buf, READ_BUF_LEN, &r_bytes, portMAX_DELAY)); +#if CONFIG_IDF_TARGET_ESP32 + /* The data of tx/rx channels are flipped on ESP32 */ + for (int n = 0; n < READ_BUF_LEN / 2; n += 2) { + int16_t temp = r_buf[n]; + r_buf[n] = r_buf[n+1]; + r_buf[n+1] = temp; + } +#endif + for (i = 0; (i < READ_BUF_LEN / 2); i++) { + if (r_buf[i] == 2) { + printf("%d %d %d %d\n%d %d %d %d\n", + r_buf[i], r_buf[i+1], r_buf[i+2], r_buf[i+3], + r_buf[i+4], r_buf[i+5], r_buf[i+6], r_buf[i+7]); + break; + } + } + printf("Data start index: %d\n", i); + TEST_ASSERT(i < READ_BUF_LEN / 2 - 50); + for (int16_t j = 2; j < 100; j += 2) { + TEST_ASSERT_EQUAL_INT16(r_buf[i++], j); + } + printf("rx left mono test passed\n"); + + free(w_buf); + free(r_buf); + TEST_ESP_OK(i2s_driver_uninstall(I2S_NUM_0)); } #if SOC_I2S_SUPPORTS_TDM -TEST_CASE("I2S TDM Loopback test(master tx and rx)", "[i2s_legacy]") +TEST_CASE("I2S_TDM_loopback_test_with_master_tx_and_rx", "[i2s_legacy]") { // master driver installed and send data i2s_config_t master_i2s_config = { @@ -328,7 +463,7 @@ TEST_CASE("I2S TDM Loopback test(master tx and rx)", "[i2s_legacy]") #if SOC_I2S_NUM > 1 /* ESP32S2 and ESP32C3 has only single I2S port and hence following test cases are not applicable */ -TEST_CASE("I2S write and read test(master tx and slave rx)", "[i2s_legacy]") +TEST_CASE("I2S_write_and_read_test_with_master_tx_and_slave_rx", "[i2s_legacy]") { // master driver installed and send data i2s_config_t master_i2s_config = { @@ -432,7 +567,7 @@ TEST_CASE("I2S write and read test(master tx and slave rx)", "[i2s_legacy]") i2s_driver_uninstall(I2S_NUM_1); } -TEST_CASE("I2S write and read test(master rx and slave tx)", "[i2s_legacy]") +TEST_CASE("I2S_write_and_read_test_master_rx_and_slave_tx", "[i2s_legacy]") { // master driver installed and send data i2s_config_t master_i2s_config = { @@ -463,7 +598,7 @@ TEST_CASE("I2S write and read test(master rx and slave tx)", "[i2s_legacy]") }; TEST_ESP_OK(i2s_driver_install(I2S_NUM_0, &master_i2s_config, 0, NULL)); TEST_ESP_OK(i2s_set_pin(I2S_NUM_0, &master_pin_config)); - i2s_test_io_config(I2S_TEST_MODE_SLAVE_TO_MAXTER); + i2s_test_io_config(I2S_TEST_MODE_SLAVE_TO_MASTER); printf("\r\nheap size: %d\n", esp_get_free_heap_size()); i2s_config_t slave_i2s_config = { @@ -495,7 +630,7 @@ TEST_CASE("I2S write and read test(master rx and slave tx)", "[i2s_legacy]") // slave driver installed and receive data TEST_ESP_OK(i2s_driver_install(I2S_NUM_1, &slave_i2s_config, 0, NULL)); TEST_ESP_OK(i2s_set_pin(I2S_NUM_1, &slave_pin_config)); - i2s_test_io_config(I2S_TEST_MODE_SLAVE_TO_MAXTER); + i2s_test_io_config(I2S_TEST_MODE_SLAVE_TO_MASTER); printf("\r\nheap size: %d\n", esp_get_free_heap_size()); uint8_t *data_wr = (uint8_t *)malloc(sizeof(uint8_t) * 400); @@ -538,7 +673,7 @@ TEST_CASE("I2S write and read test(master rx and slave tx)", "[i2s_legacy]") } #endif -TEST_CASE("I2S memory leaking test", "[i2s_legacy]") +TEST_CASE("I2S_memory_leaking_test", "[i2s_legacy]") { i2s_config_t master_i2s_config = { .mode = I2S_MODE_MASTER | I2S_MODE_RX, @@ -588,7 +723,7 @@ TEST_CASE("I2S memory leaking test", "[i2s_legacy]") * and the APLL clock generate for it. The TEST_CASE passes PERCENT_DIFF variation from the provided sample rate in APLL generated clock * The percentage difference calculated as (mod((obtained clock rate - desired clock rate)/(desired clock rate))) * 100. */ -TEST_CASE("I2S APLL clock variation test", "[i2s_legacy]") +TEST_CASE("I2S_APLL_clock_variation_test", "[i2s_legacy]") { i2s_pin_config_t pin_config = { .mck_io_num = -1, @@ -644,76 +779,8 @@ TEST_CASE("I2S APLL clock variation test", "[i2s_legacy]") } #endif -#if SOC_I2S_SUPPORTS_ADC -/* Only ESP32 need I2S adc/dac test */ -TEST_CASE("I2S adc test", "[i2s_legacy]") -{ - // init I2S ADC - i2s_config_t i2s_config = { - .mode = I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_ADC_BUILT_IN, - .sample_rate = SAMPLE_RATE, - .bits_per_sample = SAMPLE_BITS, - .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, - .intr_alloc_flags = 0, - .dma_desc_num = 2, - .dma_frame_num = 1024, - .use_apll = 0, - }; - // install and start I2S driver - i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL); - // init ADC pad - i2s_set_adc_mode(ADC_UNIT_1, ADC1_CHANNEL_4); - // enable adc sampling, ADC_WIDTH_BIT_12, ADC_ATTEN_DB_11 hard-coded in adc_i2s_mode_init - i2s_adc_enable(I2S_NUM_0); - // init read buffer - uint16_t *i2sReadBuffer = (uint16_t *)calloc(1024, sizeof(uint16_t)); - size_t bytesRead; - - for (int loop = 0; loop < 10; loop++) { - for (int level = 0; level <= 1; level++) { - if (level == 0) { - gpio_set_pull_mode(ADC1_CHANNEL_4_IO, GPIO_PULLDOWN_ONLY); - } else { - gpio_set_pull_mode(ADC1_CHANNEL_4_IO, GPIO_PULLUP_ONLY); - } - vTaskDelay(pdMS_TO_TICKS(200)); - // read data from adc, will block until buffer is full - i2s_read(I2S_NUM_0, (void *)i2sReadBuffer, 1024 * sizeof(uint16_t), &bytesRead, portMAX_DELAY); - - // calc average - int64_t adcSumValue = 0; - for (size_t i = 0; i < 1024; i++) { - adcSumValue += i2sReadBuffer[i] & 0xfff; - } - int adcAvgValue = adcSumValue / 1024; - printf("adc average val: %d\n", adcAvgValue); - - if (level == 0) { - if (adcAvgValue > 100) { - i2s_adc_disable(I2S_NUM_0); - free(i2sReadBuffer); - i2s_driver_uninstall(I2S_NUM_0); - TEST_ASSERT_LESS_THAN(100, adcAvgValue); - } - } else { - if (adcAvgValue < 4000) { - i2s_adc_disable(I2S_NUM_0); - free(i2sReadBuffer); - i2s_driver_uninstall(I2S_NUM_0); - TEST_ASSERT_GREATER_THAN(4000, adcAvgValue); - } - } - } - } - - i2s_adc_disable(I2S_NUM_0); - free(i2sReadBuffer); - i2s_driver_uninstall(I2S_NUM_0); -} -#endif - #if SOC_I2S_SUPPORTS_DAC -TEST_CASE("I2S dac test", "[i2s_legacy]") +TEST_CASE("I2S_dac_test", "[i2s_legacy]") { // dac, adc i2s i2s_config_t i2s_config = { @@ -736,3 +803,112 @@ TEST_CASE("I2S dac test", "[i2s_legacy]") TEST_ESP_OK(i2s_driver_uninstall(I2S_NUM_0)); } #endif + +/*------------------------------ Clock Test --------------------------------*/ +#if SOC_PCNT_SUPPORTED + +#define TEST_I2S_PERIOD_MS 100 + +static void i2s_test_common_sample_rate(i2s_port_t id) +{ + /* Prepare configuration for the PCNT unit */ + pcnt_unit_handle_t pcnt_unit = NULL; + pcnt_channel_handle_t pcnt_chan = NULL; + + pcnt_unit_config_t unit_config = { + .high_limit = (int16_t)0x7fff, + .low_limit = (int16_t)0x8000, + }; + pcnt_chan_config_t chan_config = { + .edge_gpio_num = MASTER_WS_IO, + .level_gpio_num = -1, + }; + TEST_ESP_OK(pcnt_new_unit(&unit_config, &pcnt_unit)); + TEST_ESP_OK(pcnt_unit_set_glitch_filter(pcnt_unit, NULL)); + TEST_ESP_OK(pcnt_new_channel(pcnt_unit, &chan_config, &pcnt_chan)); + TEST_ESP_OK(pcnt_channel_set_edge_action(pcnt_chan, PCNT_CHANNEL_EDGE_ACTION_INCREASE, PCNT_CHANNEL_EDGE_ACTION_HOLD)); + TEST_ESP_OK(pcnt_channel_set_level_action(pcnt_chan, PCNT_CHANNEL_LEVEL_ACTION_KEEP, PCNT_CHANNEL_LEVEL_ACTION_KEEP)); + TEST_ESP_OK(pcnt_unit_enable(pcnt_unit)); + + // Reconfig GPIO signal + gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[MASTER_WS_IO], PIN_FUNC_GPIO); + gpio_set_direction(MASTER_WS_IO, GPIO_MODE_INPUT_OUTPUT); + esp_rom_gpio_connect_out_signal(MASTER_WS_IO, i2s_periph_signal[0].m_tx_ws_sig, 0, 0); + esp_rom_gpio_connect_in_signal(MASTER_WS_IO, pcnt_periph_signals.groups[0].units[0].channels[0].pulse_sig, 0); + + // Test common sample rate + uint32_t test_freq[15] = {8000, 11025, 12000, 16000, 22050, 24000, + 32000, 44100, 48000, 64000, 88200, 96000, + 128000, 144000, 196000}; + int real_pulse = 0; + for (int i = 0; i < 15; i++) { + int expt_pulse = (int16_t)((float)test_freq[i] * (TEST_I2S_PERIOD_MS / 1000.0)); + TEST_ESP_OK(i2s_set_clk(id, test_freq[i], SAMPLE_BITS, I2S_CHANNEL_STEREO)); + vTaskDelay(1); // Waiting for hardware totally started + // pcnt will count the pulse number on WS signal in 100ms + TEST_ESP_OK(pcnt_unit_clear_count(pcnt_unit)); + TEST_ESP_OK(pcnt_unit_start(pcnt_unit)); + vTaskDelay(pdMS_TO_TICKS(TEST_I2S_PERIOD_MS)); + TEST_ESP_OK(pcnt_unit_stop(pcnt_unit)); + TEST_ESP_OK(pcnt_unit_get_count(pcnt_unit, &real_pulse)); + printf("[%d Hz] %d pulses, expected %d, err %d\n", test_freq[i], real_pulse, expt_pulse, real_pulse - expt_pulse); + // Check if the error between real pulse number and expected pulse number is within 1% + TEST_ASSERT_INT_WITHIN(expt_pulse * 0.01, expt_pulse, real_pulse); + } + TEST_ESP_OK(pcnt_del_channel(pcnt_chan)); + TEST_ESP_OK(pcnt_unit_stop(pcnt_unit)); + TEST_ESP_OK(pcnt_unit_disable(pcnt_unit)); + TEST_ESP_OK(pcnt_del_unit(pcnt_unit)); +} + +TEST_CASE("I2S clock freqency test", "[i2s_legacy]") +{ + // master driver installed and send data + i2s_config_t master_i2s_config = { + .mode = I2S_MODE_MASTER | I2S_MODE_TX, + .sample_rate = SAMPLE_RATE, + .bits_per_sample = SAMPLE_BITS, + .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, + .communication_format = I2S_COMM_FORMAT_STAND_I2S, + .dma_desc_num = 6, + .dma_frame_num = 100, + .use_apll = 0, + .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, +#if SOC_I2S_SUPPORTS_TDM + .chan_mask = I2S_TDM_ACTIVE_CH0 | I2S_TDM_ACTIVE_CH1, + .total_chan = 2, + .left_align = false, + .big_edin = false, + .bit_order_msb = false, + .skip_msk = false +#endif + }; + i2s_pin_config_t master_pin_config = { + .mck_io_num = -1, + .bck_io_num = MASTER_BCK_IO, + .ws_io_num = MASTER_WS_IO, + .data_out_num = DATA_OUT_IO, + .data_in_num = -1 + }; + /* Non-APLL test */ + TEST_ESP_OK(i2s_driver_install(I2S_NUM_0, &master_i2s_config, 0, NULL)); + TEST_ESP_OK(i2s_set_pin(I2S_NUM_0, &master_pin_config)); + + i2s_test_common_sample_rate(I2S_NUM_0); + + TEST_ESP_OK(i2s_driver_uninstall(I2S_NUM_0)); + + /* APLL test */ +#if SOC_I2S_SUPPORTS_APLL + master_i2s_config.use_apll = true; + master_i2s_config.mclk_multiple = I2S_MCLK_MULTIPLE_256; + + TEST_ESP_OK(i2s_driver_install(I2S_NUM_0, &master_i2s_config, 0, NULL)); + TEST_ESP_OK(i2s_set_pin(I2S_NUM_0, &master_pin_config)); + + i2s_test_common_sample_rate(I2S_NUM_0); + TEST_ESP_OK(i2s_driver_uninstall(I2S_NUM_0)); +#endif +} + +#endif // SOC_PCNT_SUPPORTED diff --git a/components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/pytest_legacy_i2s.py b/components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/pytest_legacy_i2s.py new file mode 100644 index 0000000000..e3777b1045 --- /dev/null +++ b/components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/pytest_legacy_i2s.py @@ -0,0 +1,23 @@ +# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Apache-2.0 + +import pytest +from pytest_embedded import Dut + + +@pytest.mark.esp32 +@pytest.mark.esp32s2 +@pytest.mark.esp32c3 +@pytest.mark.esp32s3 +@pytest.mark.generic +@pytest.mark.parametrize( + 'config', + [ + 'release', + ], + indirect=True, +) +def test_legacy_i2s(dut: Dut) -> None: + dut.expect_exact('Press ENTER to see the list of tests') + dut.write('*') + dut.expect_unity_test_output() diff --git a/components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/sdkconfig.ci.release b/components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/sdkconfig.ci.release new file mode 100644 index 0000000000..74be71a29b --- /dev/null +++ b/components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/sdkconfig.ci.release @@ -0,0 +1,6 @@ +CONFIG_PM_ENABLE=y +CONFIG_FREERTOS_USE_TICKLESS_IDLE=y +CONFIG_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y +CONFIG_I2S_ISR_IRAM_SAFE=y diff --git a/components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/sdkconfig.defaults b/components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/sdkconfig.defaults new file mode 100644 index 0000000000..7fb17baea9 --- /dev/null +++ b/components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/sdkconfig.defaults @@ -0,0 +1,3 @@ +CONFIG_I2S_SUPPRESS_DEPRECATE_WARN=y +CONFIG_I2S_ENABLE_DEBUG_LOG=y +CONFIG_ESP_TASK_WDT=n diff --git a/components/driver/test_apps/i2s_test_apps/test_inc/test_i2s.h b/components/driver/test_apps/i2s_test_apps/test_inc/test_i2s.h new file mode 100644 index 0000000000..90d7ea7060 --- /dev/null +++ b/components/driver/test_apps/i2s_test_apps/test_inc/test_i2s.h @@ -0,0 +1,51 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "sdkconfig.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define SAMPLE_RATE (48000) +#define SAMPLE_BITS (16) + +#if CONFIG_IDF_TARGET_ESP32 +#define MASTER_MCK_IO 0 +#define MASTER_BCK_IO 4 +#define MASTER_WS_IO 5 +#define SLAVE_BCK_IO 21 +#define SLAVE_WS_IO 22 +#define DATA_IN_IO 19 +#define DATA_OUT_IO 18 +#elif CONFIG_IDF_TARGET_ESP32S2 +#define MASTER_MCK_IO 0 +#define MASTER_BCK_IO 4 +#define MASTER_WS_IO 5 +#define SLAVE_BCK_IO 14 +#define SLAVE_WS_IO 15 +#define DATA_IN_IO 19 +#define DATA_OUT_IO 18 +#elif CONFIG_IDF_TARGET_ESP32C3 +#define MASTER_MCK_IO 0 +#define MASTER_BCK_IO 4 +#define MASTER_WS_IO 5 +#define SLAVE_BCK_IO 14 +#define SLAVE_WS_IO 15 +#define DATA_IN_IO 19 +#define DATA_OUT_IO 18 +#elif CONFIG_IDF_TARGET_ESP32S3 +#define MASTER_MCK_IO 0 +#define MASTER_BCK_IO 4 +#define MASTER_WS_IO 5 +#define SLAVE_BCK_IO 14 +#define SLAVE_WS_IO 15 +#define DATA_IN_IO 19 +#define DATA_OUT_IO 18 +#endif + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_lcd/src/esp_lcd_panel_io_i2s.c b/components/esp_lcd/src/esp_lcd_panel_io_i2s.c index dc50ad840e..9cdd282b97 100644 --- a/components/esp_lcd/src/esp_lcd_panel_io_i2s.c +++ b/components/esp_lcd/src/esp_lcd_panel_io_i2s.c @@ -152,7 +152,7 @@ esp_err_t esp_lcd_new_i80_bus(const esp_lcd_i80_bus_config_t *bus_config, esp_lc // LCD mode can't work with other modes at the same time, we need to register the driver object to the I2S platform int bus_id = -1; for (int i = 0; i < SOC_LCD_I80_BUSES; i++) { - if (i2s_platform_acquire_occupation(0, "esp_lcd_panel_io_i2s") == ESP_OK) { + if (i2s_platform_acquire_occupation(i, "esp_lcd_panel_io_i2s") == ESP_OK) { bus_id = i; break; } @@ -185,7 +185,7 @@ esp_err_t esp_lcd_new_i80_bus(const esp_lcd_i80_bus_config_t *bus_config, esp_lc i2s_ll_tx_bypass_pcm(bus->hal.dev, true); i2s_ll_tx_set_slave_mod(bus->hal.dev, false); i2s_ll_tx_set_bits_mod(bus->hal.dev, bus_config->bus_width); - i2s_ll_tx_select_slot(bus->hal.dev, I2S_STD_SLOT_ONLY_LEFT); // mono + i2s_ll_tx_select_slot(bus->hal.dev, I2S_STD_SLOT_ONLY_LEFT, false); // mono bus->bus_width = bus_config->bus_width; i2s_ll_tx_enable_right_first(bus->hal.dev, true); #if SOC_I2S_SUPPORTS_DMA_EQUAL @@ -593,7 +593,7 @@ static esp_err_t i2s_lcd_select_periph_clock(esp_lcd_i80_bus_handle_t bus, lcd_c switch (src) { case LCD_CLK_SRC_PLL160M: bus->resolution_hz = 160000000 / LCD_PERIPH_CLOCK_PRE_SCALE; - i2s_ll_tx_clk_set_src(bus->hal.dev, I2S_CLK_PLL_160M); + i2s_ll_tx_clk_set_src(bus->hal.dev, I2S_CLK_SRC_PLL_160M); #if CONFIG_PM_ENABLE ret = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "i2s_controller_lcd", &bus->pm_lock); ESP_RETURN_ON_ERROR(ret, TAG, "create ESP_PM_APB_FREQ_MAX lock failed"); diff --git a/components/esp_lcd/test_apps/i80_lcd/main/test_i80_lcd_panel.c b/components/esp_lcd/test_apps/i80_lcd/main/test_i80_lcd_panel.c index 8ab5618f63..b06da4e986 100644 --- a/components/esp_lcd/test_apps/i80_lcd/main/test_i80_lcd_panel.c +++ b/components/esp_lcd/test_apps/i80_lcd/main/test_i80_lcd_panel.c @@ -1,7 +1,7 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 + * SPDX-License-Identifier: CC0-1.0 */ #include @@ -453,35 +453,3 @@ TEST_CASE("lcd_panel_with_i80_interface_(st7789, 8bits)", "[lcd]") free(img); #undef TEST_IMG_SIZE } - -#if SOC_I2S_LCD_I80_VARIANT -#include "driver/i2s_std.h" - -TEST_CASE("i80 and i2s driver coexistance", "[lcd][i2s]") -{ - esp_lcd_i80_bus_handle_t i80_bus = NULL; - esp_lcd_i80_bus_config_t bus_config = { - .dc_gpio_num = TEST_LCD_DC_GPIO, - .wr_gpio_num = TEST_LCD_PCLK_GPIO, - .data_gpio_nums = { - TEST_LCD_DATA0_GPIO, - TEST_LCD_DATA1_GPIO, - TEST_LCD_DATA2_GPIO, - TEST_LCD_DATA3_GPIO, - TEST_LCD_DATA4_GPIO, - TEST_LCD_DATA5_GPIO, - TEST_LCD_DATA6_GPIO, - TEST_LCD_DATA7_GPIO, - }, - .bus_width = 8, - .max_transfer_bytes = 20, - }; - TEST_ESP_OK(esp_lcd_new_i80_bus(&bus_config, &i80_bus)); - - i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER); - i2s_chan_handle_t tx_handle; - // I2S driver won't be installed as the same I2S port has been used by LCD - TEST_ASSERT_EQUAL(ESP_ERR_NOT_FOUND, i2s_new_channel(&chan_cfg, &tx_handle, NULL)); - TEST_ESP_OK(esp_lcd_del_i80_bus(i80_bus)); -} -#endif // SOC_I2S_LCD_I80_VARIANT diff --git a/components/hal/adc_hal.c b/components/hal/adc_hal.c index 4e7fc20610..89d02f0a6d 100644 --- a/components/hal/adc_hal.c +++ b/components/hal/adc_hal.c @@ -189,7 +189,7 @@ static void adc_hal_digi_sample_freq_config(adc_hal_dma_ctx_t *hal, uint32_t fre adc_ll_digi_controller_clk_div(ADC_LL_CLKM_DIV_NUM_DEFAULT, ADC_LL_CLKM_DIV_B_DEFAULT, ADC_LL_CLKM_DIV_A_DEFAULT); adc_ll_digi_clk_sel(0); //use APB #else - i2s_ll_rx_clk_set_src(hal->dev, I2S_CLK_PLL_160M); /*!< Clock from PLL_D2_CLK(160M)*/ + i2s_ll_rx_clk_set_src(hal->dev, I2S_CLK_SRC_DEFAULT); /*!< Clock from PLL_D2_CLK(160M)*/ uint32_t bck = I2S_BASE_CLK / (ADC_LL_CLKM_DIV_NUM_DEFAULT + ADC_LL_CLKM_DIV_B_DEFAULT / ADC_LL_CLKM_DIV_A_DEFAULT) / 2 / freq; i2s_ll_set_raw_mclk_div(hal->dev, ADC_LL_CLKM_DIV_NUM_DEFAULT, ADC_LL_CLKM_DIV_A_DEFAULT, ADC_LL_CLKM_DIV_B_DEFAULT); i2s_ll_rx_set_bck_div_num(hal->dev, bck); diff --git a/components/hal/esp32/include/hal/gpio_ll.h b/components/hal/esp32/include/hal/gpio_ll.h index 8e5237ae85..361100c685 100644 --- a/components/hal/esp32/include/hal/gpio_ll.h +++ b/components/hal/esp32/include/hal/gpio_ll.h @@ -570,6 +570,16 @@ static inline __attribute__((always_inline)) void gpio_ll_iomux_func_sel(uint32_ PIN_FUNC_SELECT(pin_name, func); } +/** + * @brief Control the pin in the IOMUX + * + * @param val Control value + */ +static inline __attribute__((always_inline)) void gpio_ll_iomux_pin_ctrl(uint32_t val) +{ + WRITE_PERI_REG(PIN_CTRL, val); +} + /** * @brief Set peripheral output to an GPIO pad through the IOMUX. * diff --git a/components/hal/esp32/include/hal/i2s_ll.h b/components/hal/esp32/include/hal/i2s_ll.h index f8f4aa197c..5a1603eac2 100644 --- a/components/hal/esp32/include/hal/i2s_ll.h +++ b/components/hal/esp32/include/hal/i2s_ll.h @@ -42,6 +42,9 @@ extern "C" { #define I2S_LL_EVENT_TX_DSCR_ERR BIT(14) #define I2S_INTR_MAX (UINT32_MAX) +#define I2S_LL_TX_EVENT_MASK I2S_LL_EVENT_TX_EOF +#define I2S_LL_RX_EVENT_MASK I2S_LL_EVENT_RX_EOF + /* I2S clock configuration structure */ typedef struct { uint16_t mclk_div; // I2S module clock divider, Fmclk = Fsclk /(mclk_div+b/a) @@ -203,6 +206,8 @@ static inline void i2s_ll_tx_reset(i2s_dev_t *hw) { hw->conf.tx_reset = 1; hw->conf.tx_reset = 0; + hw->lc_conf.out_rst = 1; + hw->lc_conf.out_rst = 0; } /** @@ -214,6 +219,8 @@ static inline void i2s_ll_rx_reset(i2s_dev_t *hw) { hw->conf.rx_reset = 1; hw->conf.rx_reset = 0; + hw->lc_conf.in_rst = 1; + hw->lc_conf.in_rst = 0; } /** @@ -248,7 +255,7 @@ static inline void i2s_ll_tx_clk_set_src(i2s_dev_t *hw, i2s_clock_src_t src) { //0: disable APLL clock, I2S module will using PLL_D2_CLK(160M) as source clock //1: Enable APLL clock, I2S module will using APLL as source clock - hw->clkm_conf.clka_en = (src == I2S_CLK_APLL) ? 1 : 0; + hw->clkm_conf.clka_en = (src == I2S_CLK_SRC_APLL) ? 1 : 0; } /** @@ -261,7 +268,7 @@ static inline void i2s_ll_rx_clk_set_src(i2s_dev_t *hw, i2s_clock_src_t src) { //0: disable APLL clock, I2S module will using PLL_D2_CLK(160M) as source clock //1: Enable APLL clock, I2S module will using APLL as source clock - hw->clkm_conf.clka_en = (src == I2S_CLK_APLL) ? 1 : 0; + hw->clkm_conf.clka_en = (src == I2S_CLK_SRC_APLL) ? 1 : 0; } /** @@ -444,6 +451,14 @@ static inline uint32_t i2s_ll_get_intr_status(i2s_dev_t *hw) return hw->int_st.val; } +/** + * @brief Get channel interrupt status register address + */ +static inline volatile void *i2s_ll_get_interrupt_status_reg(i2s_dev_t *hw) +{ + return (volatile void *)(&hw->int_st); +} + /** * @brief Clear I2S interrupt status * @@ -734,17 +749,18 @@ static inline void i2s_ll_rx_enable_msb_shift(i2s_dev_t *hw, bool msb_shift_enab * @brief Set I2S tx chan mode * * @param hw Peripheral I2S hardware instance address. - * @param slot_sel select slot to send data + * @param slot_mask select slot to send data + * @param is_msb_right the slot sequence is affected by msb_right according to TRM */ -static inline void i2s_ll_tx_select_slot(i2s_dev_t *hw, i2s_std_slot_sel_t slot_sel) +static inline void i2s_ll_tx_select_slot(i2s_dev_t *hw, i2s_std_slot_mask_t slot_mask, bool is_msb_right) { - switch (slot_sel) + switch (slot_mask) { - case I2S_STD_SLOT_ONLY_LEFT: - hw->conf_chan.tx_chan_mod = 1; - break; case I2S_STD_SLOT_ONLY_RIGHT: - hw->conf_chan.tx_chan_mod = 2; + hw->conf_chan.tx_chan_mod = is_msb_right ? 1 : 2; + break; + case I2S_STD_SLOT_ONLY_LEFT: + hw->conf_chan.tx_chan_mod = is_msb_right ? 2 : 1; break; case I2S_STD_SLOT_LEFT_RIGHT: hw->conf_chan.tx_chan_mod = 0; @@ -758,17 +774,18 @@ static inline void i2s_ll_tx_select_slot(i2s_dev_t *hw, i2s_std_slot_sel_t slot_ * @brief Set I2S rx chan mode * * @param hw Peripheral I2S hardware instance address. - * @param slot_sel select slot to receive data + * @param slot_mask select slot to receive data + * @param is_msb_right the slot sequence is affected by msb_right according to TRM */ -static inline void i2s_ll_rx_select_slot(i2s_dev_t *hw, i2s_std_slot_sel_t slot_sel) +static inline void i2s_ll_rx_select_slot(i2s_dev_t *hw, i2s_std_slot_mask_t slot_mask, bool is_msb_right) { - switch (slot_sel) + switch (slot_mask) { - case I2S_STD_SLOT_ONLY_LEFT: - hw->conf_chan.rx_chan_mod = 1; - break; case I2S_STD_SLOT_ONLY_RIGHT: - hw->conf_chan.rx_chan_mod = 2; + hw->conf_chan.rx_chan_mod = is_msb_right ? 1 : 2; + break; + case I2S_STD_SLOT_ONLY_LEFT: + hw->conf_chan.rx_chan_mod = is_msb_right ? 2 : 1; break; case I2S_STD_SLOT_LEFT_RIGHT: hw->conf_chan.rx_chan_mod = 0; @@ -788,7 +805,6 @@ static inline void i2s_ll_tx_enable_mono_mode(i2s_dev_t *hw, bool mono_ena) { int data_bit = hw->sample_rate_conf.tx_bits_mod; hw->fifo_conf.tx_fifo_mod = data_bit <= I2S_DATA_BIT_WIDTH_16BIT ? mono_ena : 2 + mono_ena; - hw->conf_chan.tx_chan_mod = mono_ena; } /** @@ -801,7 +817,6 @@ static inline void i2s_ll_rx_enable_mono_mode(i2s_dev_t *hw, bool mono_ena) { int data_bit = hw->sample_rate_conf.rx_bits_mod; hw->fifo_conf.rx_fifo_mod = data_bit <= I2S_DATA_BIT_WIDTH_16BIT ? mono_ena : 2 + mono_ena; - hw->conf_chan.rx_chan_mod = mono_ena; } /** diff --git a/components/hal/esp32c3/include/hal/i2s_ll.h b/components/hal/esp32c3/include/hal/i2s_ll.h index 72083a93e6..db8321746c 100644 --- a/components/hal/esp32c3/include/hal/i2s_ll.h +++ b/components/hal/esp32c3/include/hal/i2s_ll.h @@ -17,7 +17,7 @@ #include "soc/i2s_periph.h" #include "soc/i2s_struct.h" #include "hal/i2s_types.h" -#include "hal/i2s_types_priv.h" + #ifdef __cplusplus extern "C" { @@ -200,7 +200,7 @@ static inline void i2s_ll_tx_clk_set_src(i2s_dev_t *hw, i2s_clock_src_t src) * @brief Set RX source clock * * @param hw Peripheral I2S hardware instance address. - * @param src I2S source clock, ESP32-C3 only support `I2S_CLK_PLL_160M` + * @param src I2S source clock, ESP32-C3 only support `I2S_CLK_SRC_PLL_160M` */ static inline void i2s_ll_rx_clk_set_src(i2s_dev_t *hw, i2s_clock_src_t src) { @@ -555,21 +555,21 @@ static inline void i2s_ll_rx_set_active_chan_mask(i2s_dev_t *hw, uint32_t chan_m * @brief Set I2S tx chan mode * * @param hw Peripheral I2S hardware instance address. - * @param slot_sel select slot to send data + * @param slot_mask select slot to send data */ -static inline void i2s_ll_tx_select_slot(i2s_dev_t *hw, i2s_std_slot_sel_t slot_sel) +static inline void i2s_ll_tx_select_slot(i2s_dev_t *hw, i2s_std_slot_mask_t slot_mask) { /* In mono mode, there only should be one slot enabled, another inactive slot will transmit same data as enabled slot * Otherwise always enable the first two slots */ hw->tx_tdm_ctrl.tx_tdm_tot_chan_num = 1; // tx_tdm_tot_chan_num = 2 slots - 1 = 1 hw->tx_tdm_ctrl.val &= ~I2S_LL_TDM_CH_MASK; - switch (slot_sel) + switch (slot_mask) { case I2S_STD_SLOT_ONLY_LEFT: - hw->tx_tdm_ctrl.val |= 0x02; + hw->tx_tdm_ctrl.val |= 0x01; break; case I2S_STD_SLOT_ONLY_RIGHT: - hw->tx_tdm_ctrl.val |= 0x01; + hw->tx_tdm_ctrl.val |= 0x02; break; case I2S_STD_SLOT_LEFT_RIGHT: hw->tx_tdm_ctrl.val |= 0x03; @@ -583,21 +583,21 @@ static inline void i2s_ll_tx_select_slot(i2s_dev_t *hw, i2s_std_slot_sel_t slot_ * @brief Set I2S rx chan mode * * @param hw Peripheral I2S hardware instance address. - * @param slot_sel select slot to receive data + * @param slot_mask select slot to receive data */ -static inline void i2s_ll_rx_select_slot(i2s_dev_t *hw, i2s_std_slot_sel_t slot_sel) +static inline void i2s_ll_rx_select_slot(i2s_dev_t *hw, i2s_std_slot_mask_t slot_mask) { /* In mono mode, there only should be one slot enabled, another inactive slot will transmit same data as enabled slot * Otherwise always enable the first two slots */ hw->rx_tdm_ctrl.rx_tdm_tot_chan_num = 1; // rx_tdm_tot_chan_num = 2 slots - 1 = 1 hw->rx_tdm_ctrl.val &= ~I2S_LL_TDM_CH_MASK; - switch (slot_sel) + switch (slot_mask) { case I2S_STD_SLOT_ONLY_LEFT: - hw->rx_tdm_ctrl.val |= 0x02; + hw->rx_tdm_ctrl.val |= 0x01; break; case I2S_STD_SLOT_ONLY_RIGHT: - hw->rx_tdm_ctrl.val |= 0x01; + hw->rx_tdm_ctrl.val |= 0x02; break; case I2S_STD_SLOT_LEFT_RIGHT: hw->rx_tdm_ctrl.val |= 0x03; diff --git a/components/hal/esp32h2/include/hal/i2s_ll.h b/components/hal/esp32h2/include/hal/i2s_ll.h index d1e6b62a6f..d87c2b8f73 100644 --- a/components/hal/esp32h2/include/hal/i2s_ll.h +++ b/components/hal/esp32h2/include/hal/i2s_ll.h @@ -18,7 +18,7 @@ #include "soc/i2s_periph.h" #include "soc/i2s_struct.h" #include "hal/i2s_types.h" -#include "hal/i2s_types_priv.h" + #ifdef __cplusplus extern "C" { @@ -28,7 +28,8 @@ extern "C" { #define I2S_LL_TDM_CH_MASK (0xffff) #define I2S_LL_PDM_BCK_FACTOR (64) -#define I2S_LL_BASE_CLK (2*APB_CLK_FREQ) +// [clk_tree] TODO: replace the following switch table by clk_tree API +#define I2S_LL_BASE_CLK (96*1000000) #define I2S_LL_MCLK_DIVIDER_BIT_WIDTH (9) #define I2S_LL_MCLK_DIVIDER_MAX ((1 << I2S_LL_MCLK_DIVIDER_BIT_WIDTH) - 1) @@ -201,7 +202,7 @@ static inline void i2s_ll_tx_clk_set_src(i2s_dev_t *hw, i2s_clock_src_t src) * @brief Set RX source clock * * @param hw Peripheral I2S hardware instance address. - * @param src I2S source clock, ESP32-H2 only support `I2S_CLK_PLL_160M` + * @param src I2S source clock, ESP32-H2 only support `I2S_CLK_SRC_PLL_96M` for now */ static inline void i2s_ll_rx_clk_set_src(i2s_dev_t *hw, i2s_clock_src_t src) { @@ -556,21 +557,21 @@ static inline void i2s_ll_rx_set_active_chan_mask(i2s_dev_t *hw, uint32_t chan_m * @brief Set I2S tx chan mode * * @param hw Peripheral I2S hardware instance address. - * @param slot_sel select slot to send data + * @param slot_mask select slot to send data */ -static inline void i2s_ll_tx_select_slot(i2s_dev_t *hw, i2s_std_slot_sel_t slot_sel) +static inline void i2s_ll_tx_select_slot(i2s_dev_t *hw, i2s_std_slot_mask_t slot_mask) { /* In mono mode, there only should be one slot enabled, another inactive slot will transmit same data as enabled slot * Otherwise always enable the first two slots */ hw->tx_tdm_ctrl.tx_tdm_tot_chan_num = 1; // tx_tdm_tot_chan_num = 2 slots - 1 = 1 hw->tx_tdm_ctrl.val &= ~I2S_LL_TDM_CH_MASK; - switch (slot_sel) + switch (slot_mask) { case I2S_STD_SLOT_ONLY_LEFT: - hw->tx_tdm_ctrl.val |= 0x02; + hw->tx_tdm_ctrl.val |= 0x01; break; case I2S_STD_SLOT_ONLY_RIGHT: - hw->tx_tdm_ctrl.val |= 0x01; + hw->tx_tdm_ctrl.val |= 0x02; break; case I2S_STD_SLOT_LEFT_RIGHT: hw->tx_tdm_ctrl.val |= 0x03; @@ -584,21 +585,21 @@ static inline void i2s_ll_tx_select_slot(i2s_dev_t *hw, i2s_std_slot_sel_t slot_ * @brief Set I2S rx chan mode * * @param hw Peripheral I2S hardware instance address. - * @param slot_sel select slot to receive data + * @param slot_mask select slot to receive data */ -static inline void i2s_ll_rx_select_slot(i2s_dev_t *hw, i2s_std_slot_sel_t slot_sel) +static inline void i2s_ll_rx_select_slot(i2s_dev_t *hw, i2s_std_slot_mask_t slot_mask) { /* In mono mode, there only should be one slot enabled, another inactive slot will transmit same data as enabled slot * Otherwise always enable the first two slots */ hw->rx_tdm_ctrl.rx_tdm_tot_chan_num = 1; // rx_tdm_tot_chan_num = 2 slots - 1 = 1 hw->rx_tdm_ctrl.val &= ~I2S_LL_TDM_CH_MASK; - switch (slot_sel) + switch (slot_mask) { case I2S_STD_SLOT_ONLY_LEFT: - hw->rx_tdm_ctrl.val |= 0x02; + hw->rx_tdm_ctrl.val |= 0x01; break; case I2S_STD_SLOT_ONLY_RIGHT: - hw->rx_tdm_ctrl.val |= 0x01; + hw->rx_tdm_ctrl.val |= 0x02; break; case I2S_STD_SLOT_LEFT_RIGHT: hw->rx_tdm_ctrl.val |= 0x03; diff --git a/components/hal/esp32s2/include/hal/i2s_ll.h b/components/hal/esp32s2/include/hal/i2s_ll.h index f1162ec41e..1263517c15 100644 --- a/components/hal/esp32s2/include/hal/i2s_ll.h +++ b/components/hal/esp32s2/include/hal/i2s_ll.h @@ -19,7 +19,7 @@ #include "soc/i2s_periph.h" #include "soc/i2s_struct.h" #include "hal/i2s_types.h" -#include "hal/i2s_types_priv.h" + #ifdef __cplusplus extern "C" { @@ -41,6 +41,9 @@ extern "C" { #define I2S_LL_EVENT_TX_DSCR_ERR BIT(14) #define I2S_INTR_MAX (UINT32_MAX) +#define I2S_LL_TX_EVENT_MASK I2S_LL_EVENT_TX_EOF +#define I2S_LL_RX_EVENT_MASK I2S_LL_EVENT_RX_EOF + /* I2S clock configuration structure */ typedef struct { uint16_t mclk_div; // I2S module clock divider, Fmclk = Fsclk /(mclk_div+b/a) @@ -247,7 +250,7 @@ static inline void i2s_ll_rx_reset_fifo(i2s_dev_t *hw) */ static inline void i2s_ll_tx_clk_set_src(i2s_dev_t *hw, i2s_clock_src_t src) { - hw->clkm_conf.clk_sel = (src == I2S_CLK_APLL) ? 1 : 2; + hw->clkm_conf.clk_sel = (src == I2S_CLK_SRC_APLL) ? 1 : 2; } /** @@ -258,7 +261,7 @@ static inline void i2s_ll_tx_clk_set_src(i2s_dev_t *hw, i2s_clock_src_t src) */ static inline void i2s_ll_rx_clk_set_src(i2s_dev_t *hw, i2s_clock_src_t src) { - hw->clkm_conf.clk_sel = (src == I2S_CLK_APLL) ? 1 : 2; + hw->clkm_conf.clk_sel = (src == I2S_CLK_SRC_APLL) ? 1 : 2; } /** @@ -441,6 +444,14 @@ static inline uint32_t i2s_ll_get_intr_status(i2s_dev_t *hw) return hw->int_st.val; } +/** + * @brief Get DMA interrupt status register address + */ +static inline volatile void *i2s_ll_get_interrupt_status_reg(i2s_dev_t *hw) +{ + return (volatile void *)(&hw->int_st); +} + /** * @brief Clear I2S interrupt status * @@ -829,17 +840,17 @@ static inline void i2s_ll_rx_enable_msb_shift(i2s_dev_t *hw, bool msb_shift_enab * @brief Set I2S tx chan mode * * @param hw Peripheral I2S hardware instance address. - * @param slot_sel select slot to send data + * @param slot_mask select slot to send data */ -static inline void i2s_ll_tx_select_slot(i2s_dev_t *hw, i2s_std_slot_sel_t slot_sel) +static inline void i2s_ll_tx_select_slot(i2s_dev_t *hw, i2s_std_slot_mask_t slot_mask, bool is_msb_right) { - switch (slot_sel) + switch (slot_mask) { - case I2S_STD_SLOT_ONLY_LEFT: - hw->conf_chan.tx_chan_mod = 1; - break; case I2S_STD_SLOT_ONLY_RIGHT: - hw->conf_chan.tx_chan_mod = 2; + hw->conf_chan.tx_chan_mod = is_msb_right ? 1 : 2; + break; + case I2S_STD_SLOT_ONLY_LEFT: + hw->conf_chan.tx_chan_mod = is_msb_right ? 2 : 1; break; case I2S_STD_SLOT_LEFT_RIGHT: hw->conf_chan.tx_chan_mod = 0; @@ -853,17 +864,17 @@ static inline void i2s_ll_tx_select_slot(i2s_dev_t *hw, i2s_std_slot_sel_t slot_ * @brief Set I2S rx chan mode * * @param hw Peripheral I2S hardware instance address. - * @param slot_sel select slot to receive data + * @param slot_mask select slot to receive data */ -static inline void i2s_ll_rx_select_slot(i2s_dev_t *hw, i2s_std_slot_sel_t slot_sel) +static inline void i2s_ll_rx_select_slot(i2s_dev_t *hw, i2s_std_slot_mask_t slot_mask, bool is_msb_right) { - switch (slot_sel) + switch (slot_mask) { - case I2S_STD_SLOT_ONLY_LEFT: - hw->conf_chan.rx_chan_mod = 1; - break; case I2S_STD_SLOT_ONLY_RIGHT: - hw->conf_chan.rx_chan_mod = 2; + hw->conf_chan.rx_chan_mod = is_msb_right ? 1 : 2; + break; + case I2S_STD_SLOT_ONLY_LEFT: + hw->conf_chan.rx_chan_mod = is_msb_right ? 2 : 1; break; case I2S_STD_SLOT_LEFT_RIGHT: hw->conf_chan.rx_chan_mod = 0; @@ -906,7 +917,6 @@ static inline void i2s_ll_tx_enable_mono_mode(i2s_dev_t *hw, bool mono_ena) int data_bit = hw->sample_rate_conf.tx_bits_mod; hw->fifo_conf.tx_fifo_mod = data_bit <= I2S_DATA_BIT_WIDTH_16BIT ? mono_ena : 2 + mono_ena; hw->conf.tx_dma_equal = mono_ena; - hw->conf_chan.tx_chan_mod = mono_ena; } /** @@ -920,7 +930,6 @@ static inline void i2s_ll_rx_enable_mono_mode(i2s_dev_t *hw, bool mono_ena) int data_bit = hw->sample_rate_conf.rx_bits_mod; hw->fifo_conf.rx_fifo_mod = data_bit <= I2S_DATA_BIT_WIDTH_16BIT ? mono_ena : 2 + mono_ena; hw->conf.rx_dma_equal = mono_ena; - hw->conf_chan.rx_chan_mod = mono_ena; } /** diff --git a/components/hal/esp32s3/include/hal/i2s_ll.h b/components/hal/esp32s3/include/hal/i2s_ll.h index 133b1952cc..e5ebe9eaa8 100644 --- a/components/hal/esp32s3/include/hal/i2s_ll.h +++ b/components/hal/esp32s3/include/hal/i2s_ll.h @@ -17,7 +17,7 @@ #include "soc/i2s_periph.h" #include "soc/i2s_struct.h" #include "hal/i2s_types.h" -#include "hal/i2s_types_priv.h" + #ifdef __cplusplus extern "C" { @@ -190,7 +190,7 @@ static inline void i2s_ll_rx_reset_fifo(i2s_dev_t *hw) * @brief Set TX source clock * * @param hw Peripheral I2S hardware instance address. - * @param src I2S source clock, ESP32-S3 only support `I2S_CLK_PLL_160M` + * @param src I2S source clock, ESP32-S3 only support `I2S_CLK_SRC_PLL_160M` * TX and RX share the same clock setting */ static inline void i2s_ll_tx_clk_set_src(i2s_dev_t *hw, i2s_clock_src_t src) @@ -202,7 +202,7 @@ static inline void i2s_ll_tx_clk_set_src(i2s_dev_t *hw, i2s_clock_src_t src) * @brief Set RX source clock * * @param hw Peripheral I2S hardware instance address. - * @param src I2S source clock, ESP32-S3 only support `I2S_CLK_PLL_160M` + * @param src I2S source clock, ESP32-S3 only support `I2S_CLK_SRC_PLL_160M` * TX and RX share the same clock setting */ static inline void i2s_ll_rx_clk_set_src(i2s_dev_t *hw, i2s_clock_src_t src) @@ -558,21 +558,21 @@ static inline void i2s_ll_rx_set_active_chan_mask(i2s_dev_t *hw, uint32_t chan_m * @brief Set I2S tx chan mode * * @param hw Peripheral I2S hardware instance address. - * @param slot_sel select slot to send data + * @param slot_mask select slot to send data */ -static inline void i2s_ll_tx_select_slot(i2s_dev_t *hw, i2s_std_slot_sel_t slot_sel) +static inline void i2s_ll_tx_select_slot(i2s_dev_t *hw, i2s_std_slot_mask_t slot_mask) { /* In mono mode, there only should be one slot enabled, another inactive slot will transmit same data as enabled slot * Otherwise always enable the first two slots */ hw->tx_tdm_ctrl.tx_tdm_tot_chan_num = 1; // tx_tdm_tot_chan_num = 2 slots - 1 = 1 hw->tx_tdm_ctrl.val &= ~I2S_LL_TDM_CH_MASK; - switch (slot_sel) + switch (slot_mask) { case I2S_STD_SLOT_ONLY_LEFT: - hw->tx_tdm_ctrl.val |= 0x02; + hw->tx_tdm_ctrl.val |= 0x01; break; case I2S_STD_SLOT_ONLY_RIGHT: - hw->tx_tdm_ctrl.val |= 0x01; + hw->tx_tdm_ctrl.val |= 0x02; break; case I2S_STD_SLOT_LEFT_RIGHT: hw->tx_tdm_ctrl.val |= 0x03; @@ -586,21 +586,21 @@ static inline void i2s_ll_tx_select_slot(i2s_dev_t *hw, i2s_std_slot_sel_t slot_ * @brief Set I2S rx chan mode * * @param hw Peripheral I2S hardware instance address. - * @param slot_sel select slot to receive data + * @param slot_mask select slot to receive data */ -static inline void i2s_ll_rx_select_slot(i2s_dev_t *hw, i2s_std_slot_sel_t slot_sel) +static inline void i2s_ll_rx_select_slot(i2s_dev_t *hw, i2s_std_slot_mask_t slot_mask) { /* In mono mode, there only should be one slot enabled, another inactive slot will transmit same data as enabled slot * Otherwise always enable the first two slots */ hw->rx_tdm_ctrl.rx_tdm_tot_chan_num = 1; // rx_tdm_tot_chan_num = 2 slots - 1 = 1 hw->rx_tdm_ctrl.val &= ~I2S_LL_TDM_CH_MASK; - switch (slot_sel) + switch (slot_mask) { case I2S_STD_SLOT_ONLY_LEFT: - hw->rx_tdm_ctrl.val |= 0x02; + hw->rx_tdm_ctrl.val |= 0x01; break; case I2S_STD_SLOT_ONLY_RIGHT: - hw->rx_tdm_ctrl.val |= 0x01; + hw->rx_tdm_ctrl.val |= 0x02; break; case I2S_STD_SLOT_LEFT_RIGHT: hw->rx_tdm_ctrl.val |= 0x03; diff --git a/components/hal/i2s_hal.c b/components/hal/i2s_hal.c index 8db8e27fc6..6cadd8f591 100644 --- a/components/hal/i2s_hal.c +++ b/components/hal/i2s_hal.c @@ -20,7 +20,8 @@ static const float cut_off_coef[21][3] = { {104, 2, 4}, {92, 4, 4}, {91.5, 2, 7}, {81, 4, 5}, {77.2, 3, 7}, {69, 5, 5}, {63, 4, 7}, {58, 5, 6}, {49, 5, 7}, - {46, 6, 6}, {35.5, 6, 7}, {23.3, 7, 7}}; + {46, 6, 6}, {35.5, 6, 7}, {23.3, 7, 7} +}; #endif void i2s_hal_init(i2s_hal_context_t *hal, int port_id) @@ -65,11 +66,14 @@ void i2s_hal_std_set_tx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_ha i2s_ll_tx_enable_msb_shift(hal->dev, slot_cfg->std.bit_shift); i2s_ll_tx_set_ws_width(hal->dev, slot_cfg->std.ws_width); #if SOC_I2S_HW_VERSION_1 + i2s_ll_tx_select_slot(hal->dev, slot_cfg->std.slot_mask, slot_cfg->std.msb_right); + // According to the test, the behavior of tx_msb_right is opposite with TRM, TRM is wrong? i2s_ll_tx_enable_msb_right(hal->dev, slot_cfg->std.msb_right); i2s_ll_tx_enable_right_first(hal->dev, slot_cfg->std.ws_pol); /* Should always enable fifo */ i2s_ll_tx_force_enable_fifo_mod(hal->dev, true); #elif SOC_I2S_HW_VERSION_2 + i2s_ll_tx_select_slot(hal->dev, slot_cfg->std.slot_mask); i2s_ll_tx_set_half_sample_bit(hal->dev, slot_bit_width); i2s_ll_tx_set_ws_idle_pol(hal->dev, slot_cfg->std.ws_pol); i2s_ll_tx_set_bit_order(hal->dev, slot_cfg->std.bit_order_lsb); @@ -88,13 +92,14 @@ void i2s_hal_std_set_rx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_ha i2s_ll_rx_enable_mono_mode(hal->dev, slot_cfg->slot_mode == I2S_SLOT_MODE_MONO); i2s_ll_rx_enable_msb_shift(hal->dev, slot_cfg->std.bit_shift); i2s_ll_rx_set_ws_width(hal->dev, slot_cfg->std.ws_width); - i2s_ll_rx_select_slot(hal->dev, slot_cfg->std.slot_sel); #if SOC_I2S_HW_VERSION_1 + i2s_ll_rx_select_slot(hal->dev, slot_cfg->std.slot_mask, slot_cfg->std.msb_right); i2s_ll_rx_enable_msb_right(hal->dev, slot_cfg->std.msb_right); i2s_ll_rx_enable_right_first(hal->dev, slot_cfg->std.ws_pol); /* Should always enable fifo */ i2s_ll_rx_force_enable_fifo_mod(hal->dev, true); #elif SOC_I2S_HW_VERSION_2 + i2s_ll_rx_select_slot(hal->dev, slot_cfg->std.slot_mask); i2s_ll_rx_set_half_sample_bit(hal->dev, slot_bit_width); i2s_ll_rx_set_ws_idle_pol(hal->dev, slot_cfg->std.ws_pol); i2s_ll_rx_set_bit_order(hal->dev, slot_cfg->std.bit_order_lsb); diff --git a/components/hal/include/hal/i2s_hal.h b/components/hal/include/hal/i2s_hal.h index 650e5d4c26..71e5827fc7 100644 --- a/components/hal/include/hal/i2s_hal.h +++ b/components/hal/include/hal/i2s_hal.h @@ -34,21 +34,23 @@ typedef struct { union { /* STD configurations */ struct { + i2s_std_slot_mask_t slot_mask; /*!< Select the left, right or both slot */ uint32_t ws_width; /*!< WS signal width (i.e. the number of bclk ticks that ws signal is high) */ bool ws_pol; /*!< WS signal polarity, set true to enable high lever first */ bool bit_shift; /*!< Set to enbale bit shift in Philip mode */ - #if SOC_I2S_HW_VERSION_1 // For esp32/esp32-s2 +#if SOC_I2S_HW_VERSION_1 // For esp32/esp32-s2 bool msb_right; /*!< Set to place right channel data at the MSB in the FIFO */ - #else +#else bool left_align; /*!< Set to enable left alignment */ bool big_endian; /*!< Set to enable big endian */ bool bit_order_lsb; /*!< Set to enable lsb first */ - #endif - } std; +#endif + } std; /*!< Specific configurations for standard mode */ - #if SOC_I2S_SUPPORTS_TDM +#if SOC_I2S_SUPPORTS_TDM /* TDM configurations */ struct { + i2s_tdm_slot_mask_t slot_mask; /*!< Slot mask. Activating slots by setting 1 to corresponding bits. When the activated slots is not consecutive, those data in unactivated slots will be ignored */ uint32_t ws_width; /*!< WS signal width ((i.e. the number of bclk ticks that ws signal is high)) */ bool ws_pol; /*!< WS signal polarity, set true to enable high lever first */ bool bit_shift; /*!< Set true to enable bit shift in Philip mode */ @@ -58,12 +60,11 @@ typedef struct { bool bit_order_lsb; /*!< Set true to enable lsb first */ bool skip_mask; /*!< Set true to enable skip mask. If it is enabled, only the data of the enabled channels will be sent, otherwise all data stored in DMA TX buffer will be sent */ - i2s_tdm_slot_mask_t slot_mask; /*!< Slot mask. Activating slots by setting 1 to corresponding bits. When the activated slots is not consecutive, those data in unactivated slots will be ignored */ uint32_t total_slot; /*!< I2S total number of slots. If it is smaller than the biggest activated channel number, it will be set to this number automatically. */ - } tdm; - #endif + } tdm; /*!< Specific configurations for TDM mode */ +#endif - #if SOC_I2S_SUPPORTS_PDM_TX +#if SOC_I2S_SUPPORTS_PDM_TX /* PDM TX configurations */ struct { uint32_t sd_prescale; /*!< Sigma-delta filter prescale */ @@ -71,15 +72,15 @@ typedef struct { i2s_pdm_sig_scale_t hp_scale; /*!< High pass filter scaling value */ i2s_pdm_sig_scale_t lp_scale; /*!< Low pass filter scaling value */ i2s_pdm_sig_scale_t sinc_scale; /*!< Sinc filter scaling value */ - #if SOC_I2S_HW_VERSION_2 +#if SOC_I2S_HW_VERSION_2 bool sd_en; /*!< Sigma-delta filter enable */ bool hp_en; /*!< High pass filter enable */ float hp_cut_off_freq_hz; /*!< High pass filter cut-off frequency, range 23.3Hz ~ 185Hz, see cut-off frequency sheet above */ uint32_t sd_dither; /*!< Sigma-delta filter dither */ uint32_t sd_dither2; /*!< Sigma-delta filter dither2 */ - #endif // SOC_I2S_HW_VERSION_2 - } pdm_tx; - #endif +#endif // SOC_I2S_HW_VERSION_2 + } pdm_tx; /*!< Specific configurations for PDM TX mode */ +#endif }; } i2s_hal_slot_config_t; @@ -106,7 +107,7 @@ typedef struct { * @brief Init I2S hal context * * @param hal Context of the HAL layer - * @param port_id The I2S port number, the max port number is (I2S_NUM_MAX -1) + * @param port_id The I2S port number, the max port number is (SOC_I2S_NUM -1) */ void i2s_hal_init(i2s_hal_context_t *hal, int port_id); @@ -139,7 +140,7 @@ void i2s_hal_set_rx_clock(i2s_hal_context_t *hal, const i2s_hal_clock_info_t *cl * @param is_slave If is slave role * @param slot_config General slot configuration pointer, but will specified to i2s standard mode */ -void i2s_hal_std_set_tx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_hal_slot_config_t *slot_config); +void i2s_hal_std_set_tx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_hal_slot_config_t *slot_cfg); /** * @brief Set rx slot to standard mode @@ -148,7 +149,7 @@ void i2s_hal_std_set_tx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_ha * @param is_slave If is slave role * @param slot_config General slot configuration pointer, but will specified to i2s standard mode */ -void i2s_hal_std_set_rx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_hal_slot_config_t *slot_config); +void i2s_hal_std_set_rx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_hal_slot_config_t *slot_cfg); /** * @brief Enable tx channel as standard mode @@ -177,7 +178,7 @@ void i2s_hal_std_enable_rx_channel(i2s_hal_context_t *hal); * @param is_slave If is slave role * @param slot_config General slot configuration pointer, but will specified to i2s pdm tx mode */ -void i2s_hal_pdm_set_tx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_hal_slot_config_t *slot_config); +void i2s_hal_pdm_set_tx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_hal_slot_config_t *slot_cfg); /** * @brief Enable tx channel as pdm mode @@ -195,7 +196,7 @@ void i2s_hal_pdm_enable_tx_channel(i2s_hal_context_t *hal); * @param is_slave If is slave role * @param slot_config General slot configuration pointer, but will specified to i2s pdm rx mode */ -void i2s_hal_pdm_set_rx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_hal_slot_config_t *slot_config); +void i2s_hal_pdm_set_rx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_hal_slot_config_t *slot_cfg); /** * @brief Enable rx channel as pdm mode @@ -217,7 +218,7 @@ void i2s_hal_pdm_enable_rx_channel(i2s_hal_context_t *hal); * @param is_slave If is slave role * @param slot_config General slot configuration pointer, but will specified to i2s tdm mode */ -void i2s_hal_tdm_set_tx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_hal_slot_config_t *slot_config); +void i2s_hal_tdm_set_tx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_hal_slot_config_t *slot_cfg); /** * @brief Set rx slot to tdm mode @@ -226,7 +227,7 @@ void i2s_hal_tdm_set_tx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_ha * @param is_slave If is slave role * @param slot_config General slot configuration pointer, but will specified to i2s tdm mode */ -void i2s_hal_tdm_set_rx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_hal_slot_config_t *slot_config); +void i2s_hal_tdm_set_rx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_hal_slot_config_t *slot_cfg); /** * @brief Enable tx channel as tdm mode diff --git a/components/hal/include/hal/i2s_types.h b/components/hal/include/hal/i2s_types.h index 3d370511f3..272ae826ec 100644 --- a/components/hal/include/hal/i2s_types.h +++ b/components/hal/include/hal/i2s_types.h @@ -12,37 +12,12 @@ #include #include "esp_bit_defs.h" #include "soc/soc_caps.h" +#include "soc/clk_tree_defs.h" #ifdef __cplusplus extern "C" { #endif -/** - * @brief I2S controller port number, the max port number is (I2S_NUM_MAX -1). - */ -typedef enum { - I2S_NUM_0 = 0, /*!< I2S controller port 0 */ -#if SOC_I2S_NUM > 1 - I2S_NUM_1 = 1, /*!< I2S controller port 1 */ -#endif - I2S_NUM_MAX, /*!< I2S controller port max */ - I2S_NUM_AUTO, /*!< Select whichever port is available */ -} i2s_port_t; - -/** - * @brief I2S controller communication mode - */ -typedef enum { - I2S_COMM_MODE_STD, /*!< I2S controller using standard communication mode, support philip/MSB/PCM format */ -#if SOC_I2S_SUPPORTS_PDM - I2S_COMM_MODE_PDM, /*!< I2S controller using PDM communication mode, support PDM output or input */ -#endif -#if SOC_I2S_SUPPORTS_TDM - I2S_COMM_MODE_TDM, /*!< I2S controller using TDM communication mode, support up to 16 slots per frame */ -#endif - I2S_COMM_MODE_NONE, /*!< Unspecific I2S controller mode */ -} i2s_comm_mode_t; - /** * @brief I2S channel slot mode */ @@ -51,15 +26,6 @@ typedef enum { I2S_SLOT_MODE_STEREO = 2, /*!< I2S channel slot format stereo, transmit different data in different slots for tx mode, receive the data in all slots for rx mode. */ } i2s_slot_mode_t; -/** - * @brief I2S slot select in standard mode - */ -typedef enum { - I2S_STD_SLOT_ONLY_LEFT = 0x01, /*!< I2S only transmits or receives left slot */ - I2S_STD_SLOT_ONLY_RIGHT = 0x02, /*!< I2S only transmits or receives right slot */ - I2S_STD_SLOT_LEFT_RIGHT = 0x03, /*!< I2S only transmits or receives both left and right slot */ -} i2s_std_slot_sel_t; - /** * @brief I2S channel direction */ @@ -98,33 +64,7 @@ typedef enum { I2S_SLOT_BIT_WIDTH_32BIT = (32), /*!< I2S channel slot bit-width: 32 */ } i2s_slot_bit_width_t; -/** - * @brief The multiple of mclk to sample rate - */ -typedef enum { - I2S_MCLK_MULTIPLE_128 = 128, /*!< mclk = sample_rate * 128 */ - I2S_MCLK_MULTIPLE_256 = 256, /*!< mclk = sample_rate * 256 */ - I2S_MCLK_MULTIPLE_384 = 384, /*!< mclk = sample_rate * 384 */ -} i2s_mclk_multiple_t; - -typedef enum { - I2S_CLK_PLL_160M = 0, /*!< I2S controller clock source PLL_D2_CLK(160M)*/ -#if SOC_I2S_SUPPORTS_APLL - I2S_CLK_APLL, /*!< I2S controller clock source APLL*/ -#endif -} i2s_clock_src_t; - -/** - * @brief I2S event queue types - */ -typedef enum { - I2S_EVENT_DMA_ERROR, - I2S_EVENT_TX_DONE, /*!< I2S DMA finish sent 1 buffer*/ - I2S_EVENT_RX_DONE, /*!< I2S DMA finish received 1 buffer*/ - I2S_EVENT_TX_Q_OVF, /*!< I2S DMA sent queue overflow*/ - I2S_EVENT_RX_Q_OVF, /*!< I2S DMA receive queue overflow*/ - I2S_EVENT_MAX, /*!< I2S event max index*/ -} i2s_event_type_t; +typedef soc_periph_i2s_clk_src_t i2s_clock_src_t; /*!< I2S clock source */ #if SOC_I2S_SUPPORTS_PCM /** @@ -163,10 +103,19 @@ typedef enum { } i2s_pdm_sig_scale_t; #endif // SOC_I2S_SUPPORTS_PDM_TX +/** + * @brief I2S slot select in standard mode + */ +typedef enum { + I2S_STD_SLOT_ONLY_LEFT = BIT(0), /*!< I2S only transmits or receives left slot */ + I2S_STD_SLOT_ONLY_RIGHT = BIT(1), /*!< I2S only transmits or receives right slot */ + I2S_STD_SLOT_LEFT_RIGHT = BIT(0) | BIT(1), /*!< I2S transmits or receives both left and right slot */ +} i2s_std_slot_mask_t; + #if SOC_I2S_SUPPORTS_TDM /** * @brief tdm slot number - * @note There are 16 slots in TDM mode. + * @note Multiple slots in TDM mode. * For TX module, only the active slot send the audio data, the inactive slot send a constant or will be skipped if 'skip_msk' is set. * For RX module, only receive the audio data in active slots, the data in inactive slots will be ignored. * the bit map of active slot can not exceed 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 literal 64258 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�lHBCxo&BJ9v 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 Z7Pe2DC&8osgn@y9!PC{xWt~$(695Zt)a(EN diff --git a/docs/_static/diagrams/i2s/i2s_state_machine.png b/docs/_static/diagrams/i2s/i2s_state_machine.png index 493e938723b1197549650c9660ba255adbe9b837..e5223bf878e9b4152c7797824164d574bb3cdf7c 100644 GIT binary patch literal 53689 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 literal 55870 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

r#d# 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 diff --git a/docs/_static/diagrams/i2s/pdm.json b/docs/_static/diagrams/i2s/pdm.json new file mode 100644 index 0000000000..c9fd6ff5c8 --- /dev/null +++ b/docs/_static/diagrams/i2s/pdm.json @@ -0,0 +1,47 @@ +{ + "head": { + "text": "PDM Timing Diagram" + }, + "signal": [ + { + "node": ".A.B.C..D.E.F.G.H." + }, + { + "name": "CLK", + "wave": "10.1.x|.0.1.0.1.x" + }, + { + "name": "DIN / DOUT", + "wave": "x2.2.x|.2.2.2.2.x", + "data": [ + "LMSB", + "RMSB", + "LLSB", + "RLSB", + "LMSB", + "RMSB" + ], + "node": "...L.M..O.P...R.S." + }, + { + "node": ".I..........J" + } + ], + "edge": [ + "A<->B left", + "B<->C right", + "D<->E left", + "E<->F right", + "F<->G left", + "G<->H right", + "I<->J left slot & right slot", + "A-I", + "B-L", + "C-M", + "D-O", + "E-P", + "F-J", + "G-R", + "H-S" + ] +} diff --git a/docs/_static/diagrams/i2s/pdm.png b/docs/_static/diagrams/i2s/pdm.png deleted file mode 100644 index 0228d1838f7e247e5e71b861db703136ccd5c3a4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 81899 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%0A5uV1}d`Tvcx&+OIJpWoP+e15*YI9Kbt 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 aPu{=u1WVndWPSz)1_n=8KbLh*2~7a7;($N^ diff --git a/docs/_static/diagrams/i2s/std_msb.json b/docs/_static/diagrams/i2s/std_msb.json new file mode 100644 index 0000000000..35352067d6 --- /dev/null +++ b/docs/_static/diagrams/i2s/std_msb.json @@ -0,0 +1,52 @@ +{ + "head": { + "text": "Standard MSB Timing Diagram" + }, + "signal": [ + { + "node": "..C.....D", + "phase": 0.65 + }, + { + "node": "..A...B", + "phase": 0.65 + }, + { + "name": "BCLK", + "wave": "p..pd.pd.pd.pd" + }, + { + "name": "WS", + "wave": "xx0.d0.d1.u1u10", + "node": ".H.....I......J", + "phase": 0.65 + }, + { + "name": "DIN / DOUT", + "wave": "xx2x|2x|2x|2x|2", + "data": [ + "MSB", + "LSB", + "MSB", + "LSB", + "MSB" + ], + "node": "......K", + "phase": 0.65 + }, + { + "node": "..E.....F.....G", + "phase": 0.65 + } + ], + "edge": [ + "C<->D slot_bit_width", + "A<->B data_bit_width", + "E<->F Left Slot", + "F<->G Right Slot", + "E-C", + "K-B", + "F-D", + "J-G" + ] +} diff --git a/docs/_static/diagrams/i2s/std_msb.png b/docs/_static/diagrams/i2s/std_msb.png deleted file mode 100644 index d77faab377b9aae61920a41e8cb43d5d1a8c473a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23008 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 slot_bit_width", + "A<->B data_bit_width", + "M<->E bit shift", + "E<->F Left Slot", + "F<->G Right Slot", + "P-M", + "E-C", + "K-B", + "F-D", + "G-L" + ] +} diff --git a/docs/_static/diagrams/i2s/std_pcm.png b/docs/_static/diagrams/i2s/std_pcm.png deleted file mode 100644 index 31e8b523d68979498868b96141001c1d909f1905..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20415 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 slot_bit_width", + "A<->B data_bit_width", + "M<->E bit shift", + "E<->F Left Slot", + "F<->G Right Slot", + "P-M", + "E-C", + "K-B", + "F-D", + "L-G" + ] +} diff --git a/docs/_static/diagrams/i2s/std_philip.png b/docs/_static/diagrams/i2s/std_philip.png deleted file mode 100644 index 7b3fca26205212e5a19d43e42de6d752587af65a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19028 zcmeAS@N?(olHy`uVBq!ia0y~yV6tOiU^vRb#K6FCdsaRN1A_vCr;B4q1>@V;${4?! z|M$NQ-1d#tRcexprknG^9AB3pwW$V2d*&_^$V>}pThFuaScKEJ0FNoBP+VZau|lhF<%u9LuR*|p<4-dKSL_LXs0xRJ0uBqk4@&XO>=tm~P+$>Y(kM}s zhp;#pS)CbL^;okFQuLe{6hWF38lF6V^{VTFBUmX1V@m^%U_oi=Q|ZMaC-{!9UNIr< zf}KvMeW*1fvXctnC`Iy1?d7VPO>6HD!rnpefh^4!0c{TGws6d~L-tu!9{u zLC*1%5(;Go+qXrQCE!Jtb#Cu~YG1p>G&d(_&8k&Fw_YvmQe+Wevf)^8;V3hwl78_yl7oCM#)J>Wd&hS&@U4>apJ^|s;{qh6h592)bZs)6GN22 z64o#k5yb|93BoK~TwH6`tXW|A{{H^(;Na+uNv;VA3+BvdKQn=cQDm3OVcw}u911KV z%#7aNr=8pR5+&FeW|-y9>hC}Q>gsCI!zC%ImP{HY6O)^ZMA#X{y1#yS=zJ$GH1ulS z-(L^=H7-sQ%(%aA@8ZSEE(zDy#mdRa+1c6o`T6Ba3ahTL=8E;Y(2={BYu2n;zP`SC zdU_TDZ*Om3zh=!5`9LN`2El^j;?Li|^YiiTD}O(4+BC5y*Fr&u<0c~8-%fb?zyH9W zpPygv`?GLI>zrnu#vea^e1Cs`ef<7;J&YGcnHWu82X&-5xhb&-Filc0sQmQgU^Bb0 z_p8^hmoHgjQ~PVm;fE_$E!t=;DDCRCnt|cRt<{U1W*wa_F9-@za2|5dWlEXI!E3eR zsHCSeG#lI!bXeG3)-jO@tfE0+ff%F6t`$dx2`LEfTXOX1(UTKRPl)VvPx$lWV^O}c zQNTWd35n{?RXr2l#I)Bawy#liXV|J>X{OQ6&vYX3M?;eblVHMu^b;WqBBvji<~S3a zaTpX8>Nyr%P_55x(g8&bD2f|F0s?YVI>9+lfay~^16S;)>uM$uEDRR)|Ng9t-JLO^ z*F{T($dQqWg;$ z{{FtbwKXz2`v0%j>#ttDdPHYR-e!)FkPsIaml?BXv$L|=*8PciX0hOc>SwhD7aOK( zhtHZlo1LBgbo1(q5&kMsK`is^>-S|`RO06D4qY9VC{gz8jHJ2w_C{v*e?Onk_x1Ii z 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 diff --git a/docs/_static/diagrams/i2s/tdm_msb.json b/docs/_static/diagrams/i2s/tdm_msb.json new file mode 100644 index 0000000000..93ffc2e301 --- /dev/null +++ b/docs/_static/diagrams/i2s/tdm_msb.json @@ -0,0 +1,60 @@ +{ + "head": { + "text": "TDM MSB Timing Diagram" + }, + "signal": [ + { + "node": ".E.........F.........G", + "phase": -0.35 + }, + { + "name": "BCLK", + "wave": "p..d.p.d.pd.pd.p.d.pd.p" + }, + { + "name": "WS", + "wave": "x0dd0.dd0dd1uu1.uu1uu0", + "node": ".H...................R", + "phase": -0.35 + }, + { + "name": "DIN / DOUT", + "wave": "x2x|22x|2x|2x|22x|2x|2", + "data": [ + "MSB", + "LSB", + "MSB", + "LSB", + "MSB", + "LSB", + "MSB", + "LSB", + "MSB" + ], + "node": ".H...K...I.M...N...P.Q", + "phase": -0.35 + }, + { + "node": ".A...B...C.D...J...L.S", + "phase": -0.35 + } + ], + "edge": [ + "E<->F Left Slots", + "F<->G Right Slots", + "A<->B Slot 1", + "B<->C Slot 2", + "C<->D ...", + "D<->J Slot n", + "J<->L Slot n+1", + "L<->S ...", + "A-E", + "K-B", + "C-I", + "D-F", + "J-N", + "L-P", + "Q-G", + "S-R" + ] +} diff --git a/docs/_static/diagrams/i2s/tdm_msb.png b/docs/_static/diagrams/i2s/tdm_msb.png deleted file mode 100644 index dfc30cb77dbd507a92cdebf50036d3a8e0d261c9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73090 zcmeAS@N?(olHy`uVBq!ia0y~yV0C0*VB+OqVqjpHe_S(cUg`;r&2Kb!^SDlIN^%qtaB<`cWpQULgQq3oR_2+k?d+_X^*LYA-Oa%CU)ZAf*_k<(#a){;*0u5T z@VvRa+&{2-lN`F!SbVe-^5bLXp0j=Hv)b1L-O@9v4!rq#k&l$ntVoDr%&NFtCB%zv zUNL9D;o08PcA$kX$BeKBse4=Ixj3UoNet7K56>p4>Y>NTGSLNX=4;h2BF7&{ufcQ% z(>*&=I=hjh4-{9KtScV+zV;mTf&&BNXe=Po-)KTYWTDaQj3~56OC&_~IA{yit0DUs-oIdh0=JxkGq^U|5Z1V5%a#KN4t#uk zJUW}n-#YL2^1BoNp6WR8_V)J2j~fY||)iFDZBu_3sl35_L??{M=3#hIFITox)z~OYXw1H~YDVB{{S65kDTTkD)#e)M>r#{#(zG3s`)q#uK=Fh)hZ$IUdETd`7%c|(O z{L|BPgI9(a%{=p|?N|rc^fhq_$NOZ3I*+`%tN_x>z<63%BYfSRjmgL7%$cK;pYcpq z&~#5_t*-s9?c29M<)0)7uFfM?I<#_$t|@uKBMs7Z;1KJQpq0FGE#fSV#w&FHOg;Gl zY&sJ0!=5p#B903jjz~mAJA>(-(le7I-B(_JeO7Az1F)Q#_JaB^8*YB_lmVN*hG|>m ziGahizq+Qf9$fA-Q%FQ)%Iw+EpEhQh%$j7rOchlBJ46aqT-x67;K73l6DFt&Rb0}W zr(w|xj&q&J2c7qrrg)_W1YB^JuT42AIWsxu&gFA5tFDQBKGG@t@Zm$%pV=2*e|`D# zB|E=d&4&jER|GCzqv?693)E0ZP-^s@ZMO32tGv6re*X9|Tho*o_?zOGG_gC zbyd~3cXx*`4B(Nm*r2le0vpK13wk)$#O%Cu{`~sn<9&H~dHuE1Po6$~dtYsJSy`E+ zb48BTl@I-@iw^#0F_AiZZm#wI|NnkZR`<`lvqMk>oF;FJWZc@4d3#&#>#M89g@iu6 zTD{)N!eYh|$F*VWqqe?UKEJN3yW6_>S&wIu5DUo01Fu-JuC4j`YW4bUxwpT)-G2Yw zy}i5l+CI%vEavc1)L3IA=Hc&eU-00-p32YX=2|ZgTkY)R6tyKI@lHc3i&wCMuI}4I zt=#4B?@jek;c8t}`}^Cwckhm~@#p8~etG+USHt6d=U8m?pKoVpXXpQR!jvgn zN?%_)+ASWxtHe`jVoPi5&1d|qwx$Z!Vp;`%e|>#?yq~*iL4d}tvbV3EJqyd&+@!re zet+GkC!TA=UO#<$b!TzuK-JV`S-iK%XjbC@#fCXU;&o+`1=c;+owJG zee21SCmkIfw$#zqas>gwOuz=l%Zwamz1TT3PYQT3xw)`*uZ0tKRaZOI_XE-rd`4 zt*7U=GGv-|___P{_h(;U*DG!Q?bD}89xC19`uDbEPFCPZOiT<5Km7m4<9_Y%bs{W@ zUtV0i@}YGfLqwz#qqz8V!{lRsJ|36XnyO`EQ}g4)!`xe2B(2MG+WBN-Vq?Ak=>;Ep zw`Pl^>7J>6b56G1UF6CwE{>-nJXD4&(F>M{h*ou$l-JP z`~MVuG~E-oo}Zt8zE$a~mBGt<;&0dg`}urLUQzIBa?y_Evpm zN{`7cDZLpPM^(&YYg>98D8u&)%JO zc9wkI4@D&McrRC2T7Z?8w>+%m@6Jc2P=Elv<>DJcP z;qa<<#@@9S|mRaO037rXo0+uPT7m%k5O?DqB5)zd#F&s)6sF}MDn z3rjqOqlFi@ZQm++e*XJCm7hzj=04=r*VTRd;9zrn?bpzhl$3q5um1k^Yv1p8yMKOv zZppM%bwP+0znsmA>#tLdZt~mzxv)Ooer?$6H*aL*<>Nmo&ao=Zy0E~})6=s_;l|CI zS679uuKD?C=FFMl>tarxIkTtaWl&t4oN3KT+sw?(Ov>(kcXpM&-kN>gg>h|I^_v?T zgO~f&{(igt@v+|5x3{l<_~w^s_B9FZyZh_wUte46JzcN2v-4#5nJX)U(~oor9_x*C zTcE+1p8ovW+UVW8c0GIgG;p4Wr_0zqUhOP=(8MCt}FE1}9CMGH>Dkmo=EG#T=<|a8tX^{=v zx7UBaTYmWPVR@Shg=On6W^Bv5yDR_xJ~7=WpIIg=laKd3S~?{!FE4sq&P1==cgwG> zc$oX){iArzZg!t9ReOV0+7v!Ia;TM?H~rlI)pHd}-rm|8x;pG<*e4N2VJ?lSr=qv# zfn0sCnLRHr@9V3pt0Olrb6PmTLuKa7ndW(SJpBB`SPovic=7!C_XnHV*R5M8DJi*f z<;q7AAzGnMPEC_1Pi}5@KH4S9&8MTQoBQp}%_K(s>8B4LIuuv+QZ+yS{hT>-K0iON zAGarB`Q@j#z1Ls2ulS&#rSCcj-`Dz5_4jZ)zp$|I`q8TJ-dk1gcKEu`)nRpYb;t7kq) zNG^VV-O(=5?)_UM^78VMk{&%hJ^lT?z1mZ~w8PfCc>n(W>({^M*Kaw?el9p$a7Fa? zcisB?Eb9N&JZ4;d_0@?JCkh`QTN|_U)7|p>Z*Of~y?pud3W2!w*OxC__U`89=eP6s z+t&Z9+4sKVsKWX^pS;e_GVNvF)Z-Ay6c-oAEw1d7*Kc`<7OP`HK|w)bq2UovZ|~hTKR+$?p8lk$^71lYTU*sh zRO;;8+uIKxK5T4koPBkbsDOaNzxgv~&YU@8hQ_fgFH6eb-xJMW5W6wS^|5kGQuCZS zb1FYS>tx;2+)YGgZ4W!StM=MiTmSy_^t7R& zp-|_N(A8mASBIPbQJ+6^X65&HccsnqI_}4uNZBN1nssGO(zpPFFbMT)ZELXF>K07Q_1W_CV_`LT2I{kKN_y_r7$Y4pz} z{?;WgF6^!Tu70=sTWXxc`s?#;tIc$D-rU%joOD!MPW}De-PjxgcnY+5PFB0SulD!%`}N}2j~_YGk^ayu=Z1ln)~OxuM5SYP6g)gJQMpOMLuJy0 z2@^o&7en;Qprv_tcgb259Qd(#o&tw;*&7aSZtKcVOLm0MwJNRq^YOS@?k$d{2@@xR zO6RYyufP6UgxLcf4~3z{e8NJ%E^-__f~(mtN*u0fn&0|zg_98DHZOjjsjU%S8XkM8FV<_H!SR0 zm#Fr>zu%${fAn`0&F1}X$NqPxrKO#lYh8Z0jrUQkld90k4-XHE>qI8pHU;nS>V7H@?kdRs49gTg#JQ4;EKA*QYpCVINSJ&9s*v=>W>B9$uC2AZ_IXQ1m zOjI_{xuLKxzM`_S_R~rA$H#hwSsd42UmvkC>DHFapMJ?JgO;9}VVLaX?0j^+qL@yE zLS0(+-Cd=pr|H)Jda3^LfBj6KZ~uP3um5t<{oJ{8ReS3`JvnLr|IcOxj%GIAqJn}O z+j3{0c=7C+S@E+o<@YMx|2%S7ef8bV&FRn1%zS=+zIjbRNm&^mAK$+(m;JkUdA)mh zxP5-jr<1!%Umsb2?kLOLxpUchBsNrieN_`)D7E~2k)*(loyE(4+xyw^zq>XI@?=xoYC^t*N_tIa}J>_y7C#`s2rsQ?){~E-q@_z5Dn5`v0}h z&dhv!d%JzjkAmCVa`p7|M72UZyu2>GED`EFa{Kn}ix)56y&JnU=;x0g5`E{x*F*#= zP5klm=TqxxN z)m%L@v$AVzBBjl8CY*k1HCInp_w4cG%Zr|#TDNZ9&Ye52uaDnf|Nq}i<8(Ej85edG zKK7cbCAsUu%aYaM>$h#+US3-2>+OB{Wr?Py=KQ)}nGOyPQ?){Q&aya0?5Wr|ckbNP zt5*lDyz;Une0>}*FE6N=kH`c?+3D%};VVOOZ*5r_xj8K_@7>48$KT)EYhC=zCqMuF z#l`N@?LyNxZ`yRMS9*K#bHBNM;d`q}KU$<06@9w8Iy^Z!xx1=aN21*{)lR$rZGQ~BxJ+uQtdHUTR`?$>oF`e^r|bz6UT_wKT{vsSNO?X>X3 znKM^jf6czOhLeY<=J(s}v9Yn*p{rE(EjemDTSi7^&fK}Y?WcN~-Q3-~pEK{?v4cm_ z=t#hU?%X+Z=2U%qlX)jjpk;0Jb}I{uii(OQOP8(;S#{;g70cphU*6md{=;vhtbF+9 z&7FC7cg4lUMXmjIZ*O(@`nbKNudf}KufMY7rS{b}N@9r+i@?E*N%|5fP*;iIVcq`2AAooyTS)odwrlgVOzv z9~CP@tZILK*;o7f*6rKJk00-svHbMu>FJ9XFE00+`|9fI>Fd|OKdrxi&cum|(@%@* zL|j?6_x8~=kJ9qB1@k;B(@7q)J^OM!wcgN-H=NKlp zMXmk!`MiBQpKR2JJ3oH>_`xl%_oBqAy88D_aVYsUd(t>^z+ft?(D0pRHu4z+bZQ&ycT?aEGi@Z zXV|uki%FlJoUE&>JKirp-z;~Q+hR{|@7)z2lg`dERTc7FAGi0`w%q8=X}Wn}THGc6RpkIdfvx#q8AI_hV7%>uW(P zzkGRlS=qhM$Is8M=!r*6Ow8Y3Uq3G`czUEkD*H`S{J7In$Qmv=y~`K7^}f2Z^Rw}@t?B3IrJkN9D&?XzwW_L$Pu|YP!eU3++gn*%XG!e~ z&n*_*n1nXS4IKt&h*Ixi(qx^NblYA~&art`Xqjjc|DI zl0`^Z*nhsAt{g-C>$TfIv7S72YFFv&u=De5=hy$M{1~HYZEam&Uw_zNC1hPpd(*H{|{LiQdwE~=xVc{pC70> zQ~vJGw%pt6Vs}rQGUdyMht3}*_JyrJd*+M@pXyYv-{0Ts$1Q#N?Af-&!)>>>=clKq zi|^5@IMN}wx9Y19%fgtQMM=E+av#2b{d#w2@$wu0*6;t9b!ElG!Wu_`clY$2e1;^UiDX3w6j{f{H; zpu)R%@0i(mD!$(>mp0GSnd-&PC-dUTlP|aP_ixRJWc zKlV1yc=Pk~^P{V`U%GUOjZY?H&vXTjnKNf{a&od}SL}?@+b5s7_14jDad&t3>y=+J zuCI&jm$O~*@U!8xy~}y!ZRe@3@9F7bTIkfuwSM2PS2GNgv#zdM8luI{Cv#&< z=H*3F;!+EF);zJOk(_ZP-AmEP$jHVfX7yDsl}WowU)TM7Ivq4zwX5XiG~H++A)%hv zb1pCUe}8N1>Iaf1&R?;$R#xE9)YN?R_Rf-^%*)GsdH285zU8s>(xgA{@;nuIuhw~a zojN<){Pnf9(UbNbG5fS#C%_%H7QmgqaL%Jy?EG?PW|?MRT@~uJG-z#@wg}hGn7kd^ zH+;PBw=eEUH2c%&$PX(EuO)48LBp4bp1(4rN(YR~t3)tl4L z?<;9_qK0Ww;J-D_SY2<6x>++-0$&SRiV!Qe*b`g z2^DYde#pIbak2YR`>d5Aw-&i}i)x4UNSo*V{Pfhi?2U(~r{O>En|mrhcL*x~NX<+R zoz^W>P*lXl!4a_fsznY zVaJXgJ9h3AeRJ{n@$^qmPQKs!9W)yF{{H^|xAXUVstBp8tH;OR|9-!|{?3j7M$D3vNmiL)J!>9%x`pKHj%BYU`>WK_M$c9+?NXrI~GV;LTSS zj=f|eD=Yi=?_W^8{P1x5`nbKnrpMO>YE6Aq|Hx};(aTFq_4oaFGFsy)~5`$2a3BS(%%m}~FI z$pYt5s+_RjwL|I6psW!>DQ`rb%&CaZM*Co-q)C&Cii)nSiKLFkHF{gl%d4xWKg?!&tRU2RqEfjDRXliQ8y0T(p{{4L&9Ua}``d#_9+w<=JdbN7}u9BCZ{(L_F zJo|hw3lEdl)U2PMp0+(!3R-#P>ebRGCng>|c(7O6T<@XwO@XyOdN=O$znpq9(xft| ztgK8oYD>h9f`t|3dWWYTcJGt9xjDW64NtdOOMicJ^Yi0=`*#-?yMKOmw)_9o zxk-zrrcAb|a1>BdQVLrewKQzC>xwsT-tyUWH&U;Lz5c$n1v=iS+sJNw6#!-pSly&h*>_~?lK{y&#CCc7WL zzj$HcLT)}jzPZ-ral6ajZcIMj)ZBb}s?Jb#?Z*ETKzS}yLLqtR)e&3%%t=y}_ z)@s>UEzLeN!!UeZjOGoWn9Dl~lM567FLtl0`n5It`Vr$N-M5y`_}ca=YHe7zy5~!I zTdsFOOTDIo+Npm|C47H(7c{oIyFA~?3Dj49b#?Xb^7nS-@9sFQ*VB~n5@=bmLgQmg zrM~|9r>Cd$OBjGgZ;sAy2*{W-X?@P6C7lxg4>q%ZetzEH(^K$%)smo>8BfMac9=Dd_MYcWiHp78yg=V z=@d?SS65f}e((3Vl$0ma$9h7nDpj^Cj9^R_h+8eogIab&(1dYpJ(&)toeN(Utim* zFB#w8-F{@e}DbiS*EhGvWE{JJ}Rs)ZIY2t^LTI5?@ertO-ws??z~_7 zJ+`W<>gT7Y)!*OQrk$D5#w%@icYFAw^8uitXL0?wm~A;X*TwD*3J%`?``zwkzO$cM z3q=%2tZ{S@SrNbg-yF;0do`cWu359@$B!SH!OLpC-z{&AdwOqu{Qjq>r!QZ&OifLV zPtwTcPwJ1~-{0HMU9xy_@=~v<>*Ds#nmk!~Uf0w)bM}fpuR<^h5tCwAy*HkS_3yT$3Uw!%VrIlM8G%O{q zA9rU*Ve(03n@sQc`1|GeD$|ekNJd6R?*IGk_Q%J^|Ni|eDkC}>3zRmt&ZB7b#-0r?W0FkwY0qUEZOfhRqNlsf2`$+yiAK6yu40rN9q{M>JAl&qW_XlnAK-3`|4ijVD0*Vjgy=ib_KxShXyX?0fCsv8qm zuLg~i^QuQbd%g6*Wku(*^z`)Ur=P0s)Z3V_Wzw3$f`W)m zDV_cO=U-i2U0hU@l$7-E*K7TcK4~Ahjydh0GwozbSy|blSB=c@IuDReM#^`RnWJ>wlb1d{R^iYCCPoD135a;#BSM zyt});HuKw6EV>;kQGR^WTFx6cZ|?o`>2y24eB92WrGCqAZ_U0wJ-*Je{N0@^7dU|?4>o(ur@V@xG?f2K~_n(_(n*I1#Z`RhRJxjc6UKbV?zPz$B_#}U?N$#yL zPp8NK`}_TVadEM_?<|$6UQdg5J~R*GwVhSqs5EiU*K5&ye0=k3K6yq(-RhM#Ul+eW zuR>cheqYVP=a;(o3l={<)?5Akovd}4PmcaXk5^Y#8mFI|BW0R3qoAclE1BtdpX}~} zhlh@I3ddK!1yv%V^`%oMPrkgsu{r0%C7!GwM&CBoKPpK(KQDGt?VC4mX4zNu$lL#W zbhKObW~&*81PdFFM8Fl>>Z8tLeSLk+?ELR;ZwHMfou6-C|Nmd@T)*cpUxHd2-`?Kt zPXD-b$BvekmXvhRbY1t<{Sxtiwr=yCZ5F$uK+)Lv^4YVx3JMEW^d|{*swgNVJU=&g zx_-P}$%_CdCnrC@zU9l)C#(5dmA!fK@}=gyO#7@W8XxzR9Oh@8svmEsqN1X$efsj{ z;5}KOK?YF&err}}Ow63kn~P6R(~aJq_xJVs{rC1%UOsqmVc6QJCIt%%3l>(^pTB>5 zFAX|8_lYQ%YeB(=AFuh7ICZC=X6KjFxp(Sx0gt=dxH4m92}}S(K2l;33QAy1&0VuWPfhuym9g*pY@YBn z5gRK%KYM$7yZ*jSMn3Y~91`4j_SOFW@bK{0*Vpx5tv|D4qXLKh|3Ah1Ok3@?Zr=R* z(o*l|=jJY6yg2{P4oBYj6++seF8#mbFFw9dY`Sst=Gj@Mr_Z1Fw^^|+Y<2#3F z*5azKuhvFxRjU%FYz4H9FOc%7E zh=J)S=aMB$JXC}>|N9nNcy}{z_=7;AT!=@d$%r{-?U*^+Or|N>2`E>U6*;RaaaQUxM zKxCoRjaPa_D4L5%S#W-Y@jt(V0bHLkZ*3AW0FCD|;$G zt9nn1_!Z%6WtUYkxhN`e!;Bd-f|vVcZjI8Gv37O?EgaiW(zrSOyj0%1+?UCzHQ?n` zVX6zlR{PJjN^O2`6tsGl8XLv}=(k(}hi|{TGuaa2bFeNB&?0uufWy((YYd~n?nDr` zMITgE+@4!)_?eNJ%_QqehxMjgzg{=|0j;0BX z+y4Fg*J=hFzJ06b`T6h7{B|eycRh#LHNzv}U=yoamx}~g2g^Uz1pyktI8bcv&vYFiwwt8>j<70cPzt7X{`TEwEH@~(x?UrDBTN@iI>(gh? zW|`?g7nuvNC|X!psHm`TLEP`7w;)8Txv6QH|NOj9C&c6?{Js?ZgJouI#mA2yFJ8PT z({65UA`4njYNlE6@{;P#n7qj=C!2smzoC-VM9R0MWJ`a4f939tdtS)2Z{K5?=mK#Q zNDG7|qUOLGKZENv(i%H(AZ)N<%&Is&TiC4yo-M$6qroAODTY6OMwjkdX~QI!>3Xp; zva-3FnMJOkpwm!oJULn2+QMQ=PkN;Pjtn8027 zT6{s<_J5Wt%xL1b1s1g7QD3u-XI=dMx|f$!=lXrmNxT7GddSe|#FCVpygp`U&;5CB+ z8W86h>~yHAs)DW*M2Wf1&d!e?Kcd9k-(RJuF}Ecux2C4%>Z;JQw|k$uKDXHO^em^c z6F6iL!~z4xtRII$BHFg{l?;r+oIP^3w_GN2fTO$NzS5UaU^)LCnC*7>}N3D z^Yy%#cO|!}p*mSgGLOpPwsMtZ*{hzy(^w z$k3QBd?CXm{oI_+-ribp#C_kgd7q{6+YV=E=kxPyrNzacKYEmO>jX6N6f7(v)F!*S zxj8k0gRvo#_0r|bzrVk~zbd&1zX z$8lrcfxo}MKP}q%_NnhNu$$7vFMyY3`1<;qR{M)xV|;!o`bLX^40?og2`p&SXKK3& z)`Ubv%wRCx)9TA{7!(bV1O?8N4huLK*R|_29ZL&4KgZJ8((>lbn>W*p)B-^UH(nC{ z@ox9~H*bG#2&{VW1(a`Z^fk<$ef!qd?9qd5!uFh1Bt}w}};GVCrnO|R9+k0imtFKj?zq_!5 z!+o3jf)FiJsb175eEITaWMpL8`;&*P9>i2}&lYHdByzBgV8TI=>Bl;`1v_sZ|}(`Q^YLH+CY)0knol%``Vg~n>TO%rXyhwF5FqUcI@1ldw18>)2B}} z9Z$Qa7}+gN2Q?&>z=}$_N?u<(YsG$U1vrE2#2&bKabx)UxM_A?#y$PT zFV8l3c|cMCB;G;cc1FR0H=ixU2`$GeB(O1NRTwW2LaRI(7>zjs4$o%1y2@#uO=Z#b zb+J)vudQ-Bn*g?PjWcLqrJYZ9Q{P4-$Og96LIEp7Km(y29UE2!&Q92H=kht0jxbpz z6O%7bPEO{Rw+qn_37gB&><%jEHaIjsc#yC&rta^rQf?V(XK>QkkOghWEcKplTm3Df zRLS3}qVKT%%81D9^;fe@rF>hlaF7&R(58QQvUe6(F@i|-YIyzd^pz4jS0g<=y}Z0Uq0T3o-%`aPVb>*I zP+UCuWXjR)iP{hY{S_6adfmNyH#R0_UQ+z(d#zIURxLlz(mda~d>yzOWag;j1TOFt zKIAu=W?%DII_Jyxe35zJYG;PifwO0GPfyd8lapJ+c-;^ErNZD$OxE%Ti{OIgPd z9I^reEDL>Sn^{0iN#J8-XK(M5wVtKCsrC4i)rH*i7243Ng#-UN0}g)<0!1=7Y@oye zE0z@x*Cx-C055+B2LzP3@?qOQsT;e?-_J75Hj(OG>pTIH_9R(Ai$r{9o6S@-Pz1Xs zCssjUKmY73Q+7U?4W=Af716Ul{`pz=>7@GMHr~@`&z{}i2yLI)Y(5a3zt=SJP)j;G+={>_ovx8}UTPjFyB{0FLyr-(9U{n%tQ`3abP8iif9v@l2M71U@X<93llb=xcXQI3CPZQC$sLd}8zT-y2A2;c$^jR4Zh{$rRW8 zbZ&@7e@z9*y1=JTzfSob{WkB)hcN3>HK`wWb`~2O8~lAW=Hvlv=D41kkVqt^$ z`ix>ie*XPEmBqy_+dj;wG0l4@e1yc^4#JDkw|F#2-Mbdg{QCO(_$?U|qt*nq>)=VJaCPs+Z&?(BSfdwu=)^FwtYahougNm5d> z_}Q6_=QbK=fr6z`U2H}0@^e$Q!{=3)muYNdFs9sM@!QsF%-`OQrv6^3g9%Pq~ z*;lhu#A*>YNDJd_kq_U#{rmZRey(x(CQu_hC*Z)*qpI54t3`yuwWd0^^Xazs>8$0> zs_>pY@qh2}Ey|i z&$#nWPTaYCuIhQdWJp5~R4hUA&;xnKtRM9{5#T}zA_SH^Fo|`=L*2?U329J>flLRb zUr@^V&k=C=fAT>gbn$6A4!rp%Hy^$M&68kbK*SIC2C0AY+|$s-H>5CTRd~;nJqAh5 z2s;kgGhO-cKVk#8-hf#P>Vc_p2ON(6^v1vp9A-$wKfw+E(=VQyZe(nne{T;cu6LK^ zcDf{G-ptr~EBpGoOp{qzS67`(G4hs{dyLi`*-+DXX~jcjW##MZVsC?bH@4MME}&)m z_5c3NGRU2@6koNvI&5chsL+wylYK|zx?Z!SJN%hbC3UCh?3 z(2u8^e*F01+ARiJ{S&{x?wIUc%i?F-@7Jw{EadxA_4m|NZO{n#dAr{^cXkvWI~xH? zPRL=uK!s^(;9>8jmq0`QJByC)XtS^S^5S}YeeCwUyW(*b3(MZ#dK8g=ch}a8i;K$M z-s)p{u4@awO?y2U{grrlhvNnc-G?d$7nQUI-_d3JWTaoQOU9v&VJ z4ug_|Oz0_ARZyc>>fZhP`<+_3mix~STN#pMs?BleXLyp0Cf*?>7C@ z%+4>S6A`d6=_tS54+p*J(^Yae_U_*OdsXP_J$v?)Sj7efU7DooeQkaG`}glb6YCQD zWN+-L1Z}`#b^P(^wEpew`RfBTK7INmBqUV#_v>|Gb-$SXb$hG6zGAHgEpK{paq-+a zbHwywGBmEs%E~VHnOXGi&Q5!U1T)xLfc5)+WgYDj)zi~sEl=S^_qr?R6gOV|$tQ1Z z$=sZDwClx-7ini_aW+kuJGb`Ro12c!Y`J%K7%C|(@}92Or0}9-*NGDz>gvmv`OfBQ znlNL=j^gL%s=mHDJKz5P`Sa%|IDCF~HopGvSL^b35~toIAMa~zZ}*>RwA8Ivsx3`5 z614v=YU`?smi=LCqpq$By}hUMb0ahRrcIkfxLOrBBqb#$tNVwo40(NR?dwZRyB8jZ ztY`!6un1iprhDV!+1cjD`(&lX#lIhyukTnXdCMg8(vzjr0h9+vhelu694WheJvv^+uYoIbn^?|v-3(0f+nesx_*A4 z`0n>{`Fa%<6&`uJJ;l$@wY@vy8?+KM%gVan)WgqD&aURi)z#skrL>PX-QN)I;nCr@ zJbHWH-N}6Y-@sKaf-uty@G`9dO>Kv)5RjCdIeD@&XbtZgx5b$^HYDyYdz+M;JbBV2 z7RM83&VV-7+}%}rdb++o2WT7G>+9?5L5l|V{{b!NTe)&&WMpL2TC@8tPoF$#X>T{r zyR+kh^P`_q;{Q$T?Cf-P*G6s4TDNZ9quNhON=k3uys7&7D)dF~JC%O9V}_F_O;Yop zCnGHU`DXh3uWxUg$KTZ7wkBYqlY@hUi;Ih!TieHdI?70;GN{}R*yEsi^}~7F@1PZ3 zix)2r4hmv%v?zTwrM=z#?ygd1X6EAJ;>C*=v4B?Xefs$*U`x78Vt^wq!tZZRUR-#0 zclUg|+Nkx{xtj{!-?Qy?OWvVr#8;ocj!Kke+Swb9#8rEHS5F1xddO-kx9RWs(Dd-f&c%xt@7}%p)5XOqjBnq* z71xRQa4kB&wY|N)wN*5D(diVUxqi!oR(c6dGeabO2&;o>X<>ZT#^q+Yw=_h!KE}O! z_wF69w3!HtquOLvHnxACPU~;nxbfr1kD!%y`5f^DRU-XzrrFm(wVaR78PHONPoL(@ zohvIVt15Kz^3}uZ)~zdke(vknuc2B~^Y?r__Ur3w&{SdJBNugbbw>diSy^fGyggZ0 zSJnRhCRw*>--81@*=@YiVlpx|DJLehw6yrnHru&lhfegiGasU>+R~a7o;-c(sUlSU z`_f_acXLyb+8?0mRa;bJ>EjP=MStJ#|NrlCzdeunI$@TD!OQ)=zq@;TYj${0P|)dV zy1cIMo7wr#&9z>B`Q@jRUCS@*-o3l~`^?YZzHQsQS=j&L`RkjW_}{&A=h^xB_g4ll z2i4+VUtN{zb-Po3VS(eL{1fx->*L;B7YJT|J$_%!&wG2TA4zq(JbLp+XR4R1jEtCW z)Ro2V{h_PFKuZAjw9ik}cNEwX_4e-W@>HXlvuDr#STzmY+X1;4>H&?o1z)l%R)*Z# zSNl79d*0g{8yCmzt%{3_dvxN@-@kkJ?ydjx(cMv?r{3uAv0iD=2AnG^gBLGav}yC^ z&!0XO6&GK=bm`gI*`VDyjm+#;*4Erj0eh=T)6>&GuB%`TzWVyB)>N(c_xYVW^X}|( z>y-j+EBf%^$B)PT-{0O=&s!C?_STNV$M5d$HZOW|;&3~EdTMIt;T`4g?=5oej;sIs z)qA?0B)j1BzkmKbJ3IUOionIJ++u5Dcbnb6E}%74OHJ+A;ls-JLz!70ZvgK%1~oZh zSt7adlJ(qZrHNazuAaJi(^6M=ZSwKHw$tZMPt_I|5ZF-t{oSvxugxQ?;_TTIuQOsjH_yIMBE`?QBs&fdI?F!-tg>6dqhy=h<#F%j@f6LHl5@tPF1D66M(~t^ecq@AXkzSNYGko2>5t z?aP-p_xJCAc>U$1Nt62I?f;$9UO(kS+4p0Kk!UTu4XKTnRzGBQ%($^3aeLm~cXxIs z*HrFwTKMAX>gho%-`w21{G;k4)2u5uHY7T`xE$G-eEiX)N0%;N7UeoRLD89wN8-Y+ z((Ll`^21y9e!1kW?l&g(Vi5^lW84sR3QK=J5 z$N-(W!^$nD6TR)t^ZE7j43pd1+uLLGKzn+Ae|x*T^!2sR&(AMkvLs}6*jo2~xx2f| z`8hZQ&Z`v^7iV8y<_p@%P{`uAB7FV5OG~}?|9Z8$^!2r^xwo%fzaB2YGS_c=-QQn( z_UxG+S9NlS;b}-w0qTZ8ST1i{&bThPPL@7vd}Z!ax9-N?+Ylj5;V>e#m2+f7YP zhYlSAt?_6w^nPFUqp5awmhaV7q09Z|Ry{c}5wt;g_0?HgYfe7SFqw7U{y(S@dwIG4 z_6bb)o>&SAAdR_!I-@mAsSDf0Sr+Es-{;)M6S=42{q2q6KDm2O_S$$m^twHM z`0(S`>+#<~TU|H(Pwzar4-%a4fHhMMaLcN26wnG?Wm5FSqkFE+Odl~BnVgM>lM~RC zPSX!?JGXRuO@qB-Ru(@!HTBZV?l^G4r{n0bFd*WPfdn(CVeBwd zgoB@dec)m@%_YwsJ=&CddKzf0wp0Aka!20yJ^nZE-`ZDOEiXSm==A0D=hw&Wty+3b zRu#zar0--ULCaZR7%-V6<6MP zo<83kE?!<c7(0odh(4YWUOHiQ#-%>w9`+Yy={I0j#x9z1wkvny}g~@+{$zO zVeY4|ewV=F2qH|wfj7T(^05iXfx^JZk`vS*bx&>i+$Ct@YXTZxKU`aI$;awR+1p!{ zm6bPdfA%ua)IJD~RXNTtZ*E>bd6JU{6bOtgK6($HJP{EQxw0Zqd9wSq4-FxCVs?&c z^7roSEIxaW9Xju^>cA}1>>Sh5PvFwjU_EHEVVZ9AncMBIZqH+?y61?owL-%i=5Pl_ z#;hMqDr;cX48%GChXYEWL6f2=2@&*|Vr5zJkbA<78(m+%e7SNZWN%!4a^+<3SzQj9 z95yvyGYm&?V)<;2q>Y2SHUycGoGeEIU@$B#!%lR!gC0WAj}9Bf`4y1MMqkxr#;n{O>+y^{6yKqK>P zv)o44=kDG4Dg3u?O>^+_;(Bki&GczXG!tm1iBZTGoIa3<4GfHZhocXu{8{e& z;_~wT{rmSfHy^II;IrC?Hf73tRa0LsC8y7EL zEINMt#J}vuK3VHuKY#wczIZ`Bx99|~rE{&zzkUC{{lZ7XHUFay+`MV2qOv4zZ`J>= z4qm(KvwmC>+rH)Bp+kpsay@#EFJh_t@sPb+iobcINn`2jYmv7mNc6jMg0>AVI(9fg z$G7429Nk_Hs0Qze}8xR`La){m(_(Xy#C6` z$@%^L{rW|FGjgn%tmf(|Dk^Gfo-7LzGhPZkLSc$#a8pxLQBl#S{0Ejy{Vd1&wM>9+NwIBx{A0H>@LB_^KENr||CV6*uEZVl|-Z9oIS)~C17nXQV z&bib0rCZ3u-=Ck0YnEMYRUq%FS5@!4)AGwxOW1GSoZ*m@^CrIj zZ)&pVvUI8KK|YhMhK(;?WbBN|gGjizx_(|><^Tl?#aX0zvHjImoW%?-J?w=Gz(V8ezD=k5RR zdB9*fecuAkY$W%Boxj0_@!ZnwMiqotRPTR(b#-;} zu^!FJYUk6huC8uxZ3T5jHY`)&etfKVchOTX&!}hF#;K>KoSSQX`*!q;`%~N&zr4CS ze4pX;Co7jPPtVB6aBy(&l#;%6X100${e87<%T?nmzFrM)=av5El78>s*X!}1h0-T? z8*Et?e8+rD5>omw{Pd?<;}gnZ|~f>b3ay{jy!kb zgoH`Ph2Wm$H9tQEFZav6vEgCxo6~w6BB}yXQdRHn>|C@>Y;)b48yjnXf2&=@eS}Zm zF6KpGUs9EzxoOsw7mNGtK7II5k>mZC&C$`(zwl@0>ebm985yUi>8c8K7Mh%n+*kMa z*Ncmb=O@{Ot`6hn=3X7R_?R$gA#Tg*>H78;^^zWYPF5>@eeG@My*1_U?)?0EJ>K3m zo{^DJzW&d~?r!gs-><&@s=w!h)5+V?QB@TcEp2UP+1Ji&ICe=4w0->D?)P>_S7cpX zB`PKswzKHz@*C4*1vFMOiACj434LcYIXoxl&A-3D=PS*5>o>!i$<|}?y(i!$~%a$!XXTtpa_}UL!*8JGu5_$UE zxw=0;HoABUI7zgHhKCA>+Ga(VLE6f z1ACZ)wzl@yuU}(hV}HMTqrYt3y1ayK@9ypOUVd3M_kaBUx>|i%N(xxT(< z4|tu}TmAjYl`H%H{mTBBtJuPp=I!XXaLpPWef@qX$%Vx^(b3WD)3(l;GiTnsdG`PR z1S|C@@UXa|2`j|EWLD*Z%`;{GT;z z)_*sT5C8A%EUy3gRGd>tVae*%(IFu!fkI9@cI}EmCNDHp!2l0->-`f4>xBh4h#$g?Uwz)xqH_xA75X2+bWeh zA*V@hi$lZ0gr+}YvHSPqvG;Vn($dmSWt$$O%gcOsSA1OL!e?P=XO-MOli!u2nh*UvT~)S-MZY{+uq*Z{{HIf@JH&3D%aP?>t9qztgQTbWo0n?g~jax zMuvtb&z@EF=@#zj=-5&F+id!2QTGao)U@;SY9Ab6?36JuGOGIVVWEpB$HVmV^9&_; z9)0R<1nsVSad9#8>NTJVjicS-`!BL61_T5=c>g{=EX?glhx~?(8$G?fh2!NEpS*rO zd;Wa=z)6XMaXShg_S^r{*q6!Io}7|m^5DGXN8ZLK(OwP5AKO-bYB`zGw{@n}g|>Qc z?=@HM#BI;J`*(l6k6Lih(yXkkTeogKS{@V@CKeyzG0AVacZ#>h&Lz{MqN0R+pHF)s z?G%*0L_=R+UtiO$Q%#0z=c;w<^d{~+*rRVa)2B11w5*J)Qv2dkmu&)0LTlwGo)CV? z#lN71XTfj(U3Sge1pN~J{rSnmmYiU0YGP`t`YT%6!PV_Ta7f6M6Jgoe+7rVrHO!ea z2dq2PbJ8zm*Pjd5uTiaf(Y$ia)G1R`s!pX%*b|0o;H`r zN?oCIJSJ=pI>?9Wi;CnJ*=5Y71J{&8)Qc;;rChX<&dz zGcYPJKsgBll~Yr- zm6et6Pdi)Wrs7n<1u^26>W0$S*S4o_Ut9N?!5m_Hf{RcC}G%>5tZ&^(Z7En+j{0i}+f-uwK&Ajn3 zF@KKB*QcbUe5kOQnIJvq(xgd~7Q6S~+f|xfkhNs;t}R=>+}m4SV;67r%7GgeszQxT zO-=3m@{^PlIH2L{V8yZ{=H1@v@25_kTC(`v+lxwvZQp8XYuo?(@%Y)Zv^i|8PJw}e z8@FzqYg@f-@?_!GPxg1&w{G1!bLPzJ>ta{0Sn=ZRTT=srg7WhDcD28Le0=<}WS4_N z#rwVAHAGIm-~WHznl(NTbhWjkcbDn*y4~JYx_atVQMv!0o}OOnJ$>5r>GAt&Bo7+L3BmVwceC^I!a_n!3=Ip5i$8z(AYq<2XU`s+g_}2SG*nktx3k-~XV0G9 zyQAad@87(6^ZNDcmo7~@nX>8To5;;+FJHWnv8|fo;l#3Q*DkZXI}w3_8`ICrDJv^0 z{rma(xwKi%iuLRNe>^Uqo0~gz>ePN&>#)GUi8E$ow=o1ARc*s>JH=xw+PhE&3;zLK35d7*lR;uArdcFswZFb>urP>m`@dXK zH&(r>s_N6HPp3|w4*mD<;>$1T=jZ+Xa@l|3!i6_)-fYorbeJ%GI%sO)&tv)j9i5$t zn{U?G{r~m#_3E&-pT2#wD|<7;LBWB;_Q&tzPm4NRK*vVyttyR*y7l}0{`}0$&f}je z_SFCXec#p9_4fAs^0KmH)m$u02O-;g7B5~bZ(rAwc%xff-*1kEps1*6_O&&aE(JNI z2L@hjV&zs+Rz5$^_V&e#jtc`eZQ68gZM1pvu^!v%Zyf*r-Q8QgeZz(c9!`88D)t=j zmw*2J`S&kh1U}B4J2(5V*pz z0%Bu(o#n*X4`@IVT~88|sj2DKty>pcG{b{UkI6=E{jOcR7A{QOAtRx;+eoJU_~s|C zUR6Cj#Az!-9g7r%s(JzgM|@;lhWr^Y{IHv-$js z605ev7`^ZR{{F81{th(1&LFkx?Af!c!`AL9e0;3@e(m;@lR}65)zz1Smcd7EPJ4G} z=leaM`5tOPGZ0f97d_!A`uh50=?@%=JcsYq|NlGJx?Ik( zNJT}Z#cz4{6^4nBf(TYZLp{jBWHiUy|AqqlJp1~4_wK!W^QLF}9B*&$%a<>!`_3}S zzh_g#Ea!hHX``C|Je?~=@7}xt9azvQtiCPh=BAvRMp|G0?^4Xl%32q{|J}ofid#;| z95%3~XQNbEiy6Nle_BaZzazqkqM^HEV2APl+h{ckEVTW@=Qh zvikMm;bHmuKOe>8YZ{+V*IBu2nOXI>H-G-r+<4R8!+Hpd!!O7;{?BIku5NhZ$8`Pp zxIGnuidSymj*f`|odUwj&R+lPPYQ*N1OUmq722il_}Dk@s^Df9BOnX_iSySbTN@yWx7i3te{mM=e^w6SC6 zTaJa(_2Z{apYHDBl98D?@iL#znY7L2Z*P@8IMBFa#fse9+ci;e1LtP{uV>BgU%7t$``c|2d(tkzVgR&w@JNZ}0!C<(bLe83GIeUdob9UR z%hg@y=C^9i-2M=>z5HRj{3D$oHFo{SgM)*;{rvd&_`(7LGV=4^zkGS|>Qz<#<=@%+ z4nLH!srYa`zP_}e;Kl6*caG5T@b6!~e39KX-z4)=pRBc6-kl$p{q5i0ZLd4Z#sIw| zV0UeZ_^Z?0Up(D27Ko&Mw2rLV3uGP9pKb0%zU z)Yn;+pPoH?#>3XUXJuS{<@DGZ508#FQ<~Ehz}}L0%mPY!hJFm2_#xghQgT>+SzIqh zL;0z4)7A#{;lZax z`tkd0%HQ2tv0}xnSyDBPR_{FHcTYNY<;s;mpHAybNlCf7y6*q`O}bLQRx$L}ty?8l zf1jS7?)0$$Yx`w^KI6>(!`T@b6_u5OZGZp%t*xn1^Pl$zv_o&Ear@CE!l-TM3g7@3(}JAC-@=JR&JVPRpRp=(#IdiCZ_NKlZ{?Wra`i8r3luisbk z@lpBx+V2M%nWdzp=GT6cyy@?>u&Ifu)hTiFO&14$1%OVx5XE)T)C2ylQT^(cGZFfA6{HkZkaG|-n^MJZ_c$YU$tsg%cSpL zU6wEiu3Wv^I{%(ca`I!)+^M9btGoO0$H$*FX0v1C;`S9k_p_QSCo0gj1OU%yV4xOV5xoLRGeU5~G4WnuYpw}kibh64u<$Xb`x{QY{pTU_6+_*qYD zE34Cq3l{=hU7z0DTdk<5_{8@4`qe{W|E>*0#2`qM{;QUERpYNcTROjT<-4G|d)^bEvMW z>gw)3*(!S2Kvs6{KH+C~@813X{{H`q?((1meXx_rR*7Z;VyX6u#+$wj^u zXt};N8Z`Y78rnL4qdAM%K^AE9LYC?C^YiHj63HK!v)|YxozMh{C+y(ZvUO`~dwX?d z<-_Q;ywjzf^TVIz{+Kgo&W8^LdwB2Py?gh@jShiZTQV=dxw-k{9VuyPdCQ_Fr}g*y z`1tsEd0o16>5##jtEKpVL)E_Uyiw_mq#;lUK6+qZ8=M@8xAg3i2K?m1cQ z;Upcg*B>4p1`S2m{QUIh=H{(iwmf(p(!m<<-qgLvuDq~efxI%#r8x)-NR-!-AALg z`uv(h zNgL&CDhi&TldW0A=(J+hs#kx0eijrIJbb%N{Z9+HBL{82!1`uA1x!XchqE&?bMNj7 zJ@Y46V~S_}f0t9q65l|xnR|~W7=*2h@$8G=QSh*lnf>42_x09RR$AKH!rNbz>^gqm zUTN8WhPK4V|NnK0Oqf3XKIrhm=!z%q^0imKuiLZd&m!0E6Cdy1y$d?waL$}Nn^I3d zdGh4Mb_J}ZuY*cs;*HCGOXM$gUAcZees5K2Rn@PTmzOVH8Z1^dY4T+MxmI8Q{eEw4 zX?fCV{|_re9_9D43Uy8sU>(N~ZcHLvtr4By+!8_A0_;--JH|bV#%#BZjAYuy=kF6y z)f74P>gwwEcXxmP`F#HDnKLV^tNXXKYYA{{+O#QbO+;c&&Y!#G_rI3U+AA`1Pux|| z>iOBTPj-vM>GPMvdbb_^51yQyY;f17CPo2T4L%YM2n_7(?Y(;8f`I+W7ZYT1b1PZ| znh)OCo*$o@y0owF9LJmA#|_ThxnpBy78V>F92;AEqx<5P%*$sAu}5%kJs<-Z(tBTzT(||`$82*Hb`2BMJJ>} zU~o*>vbJ5_hz(nRn}KO@55ty+?l+lR-$0c^EQ4?ktWagh{So*(H z%$xB^fel(;I@B;_W@eh_-xG=eR=xSDYiGa|Nj1devYMb-KX^P^E&l)RBm3nqy!p= zSslKaI zddie39Uu#D+|bCprlRVnTd(Or^m;7i%UyY z^>**xZER#TYxe9;32kj{YisLAn^vyWG&bJ6d^x+K%i@bSa?A?7=Qy~#w_7ABrB+o} zpOjGdot2WD?Ch~^+qSfnlnLDXCr_TdbEl=^g)3L4Oq}Rg23nWb*4EbIP+ME;=EgSt z^wH!ePoCJ=*p!r(ayHJIHLItG=TVTOW{_c#bRxw*N$d-txT#^2xH&5i9RYieTR z!v_x>I7&)NQqs~U-B--75$NmddwjfK-DE@BHd~Ic+((S|7c9`STdNVg0|F zmJ9Q2t2vw>v1Dau9~BhVoIG!y-o^WwWo6quY#+IVg@;e(-f!XAF-fOy!vvq?Waak5 z2bCpx*mib&`}WPQ{+~=e^8=<^_5V3|=gytm+S(c$8|%`ubgAl3{Yx^;aQ6hhoL+(H|cl%gV}f zR(?uXk;_a@HqN}H;#$a6A%<6 zHN(W0J`1NG6KZorjmK!;sGki|w8hm_vDZ`}DXF}?~ACLKqY}*C6czK_GtY|s2I()s2 zjm-%=j;TLiy~-+T=2hHM_BKjsr-Q^Joc;3lYS|IH%XA|T96Y#i*REMQ9}cq1 zPhhpNv5DJT<;wA)!e(J_F*7ss$@eq2Z8OWy&)?Lxv-r8tNmizVr>E=3#>AXp(hgsz z!fjLgYs#I{CV^XfDvcu-yl=KBc)$<|YB)RbKYDX>a|+`^cE`mRTjX3~Vq)&I8_p1p zc=hVl3BEmsGQz^nd6Op;?lqK=mHq4XH>L5{uV0ay(*jpAOL7|;8!N9CQvY+9-~Pp` zSGR88{=a=v;hlZ8)|L;u#r2(>oIIxX+Ezr7U@4uq=_x85P6*5hoI@LJ+ zoXUUKJ#qFw*UgAF1avrU7P*|~g zwet7h$}KGc)2C18uDzIhXUD`f4<8Jt-%@Jvn{VeUwxjOv zE*E|$UtixBjxzRjbLJf1$Dee4U2F;?H+T1!FC|4iYYumHb!lp9K8ZQ4CnGK0EfBT8 zZm)+h^UCTJU-mE25fM2zH>FNsUY?X>Q}QApHTCH--`Q*doqf{gem>eeX3U-qItnxI z&JM*ut(b@xdzJgzKnF;^y0Y@^+qaK6xK9em&UgCwH+J9md)1klnI})4JQAT)X~Lt} zk~m}EKD(I`JDDZqExvyIsK|Ze_U*}MH%6?vx;p&v;gVOcUOjnevFXO^!%q75uX78R z8}i)VS8H9US=aDGM#T8!mzS5z-`$xxb*kzzo5-F!H+}lv>#td`pkcbery0)mhnzl6 z660^VaHy4grcYXBrRBn`KR-S`$+u=}-dOVT(t`&HP7W*1tX{EVP0Y?oHWr#8(b7^< z>*Dvz$-hf8n#p`Z+-XIA^PCUQO&P7`?n^w(=5*ln>240?mXgxa{XZUYe~NDjh`w^- z#EaMK_p4d^$VobY&YjG?wWagLt>r;0pG;(InJ{&#=*|u!37&;L7FJen?(V{ID_5-G z5cSj7*Wc98*2Y#TA+IPRBH|)9`Qp{9p@D&lB1$dK&dfAUJj9}O?8J$VJI*bMH`wKC z9OS~yjg6JXRit{iReVgcx3_m{zHoiprcI#j0m@2B9E=N%)~{Rl@8$COla?1%R8K@28m4fgpN%X=64DW4Sm5p{mqT+LzBK8ZfkE( zmT)^$R@wV(-}baKGcKBcGBu2fiuz%l!tnUj6HA5lhK~ETmb|>QyZrsLr%weZK6z-= zA~4m<)WAT&ydoqtlrym=!&XD1!{)m43e)V2j34Xk|8j?0KZtT$q1^fAK=z@isHp5~ zYbtvk>bF06`tbvGCkaW(hpH_S|7!QveY(ro^Qrdd z)9GqzYEP`3UihwFxNu|I*;&VqxgEOj<>lp0gMVG1jWs8kzdG%GWoBk}WOc=Xtvvzh zCN~?exA5}vPS=n3jZrg2GRIKX>=`nofbL=X1+X==(T3J1?|KI@rXT zmzUQP7#tj2B)+hz$tfgc%KG*CiV9aQE?ctX%g5vL?d|QtOin8zb*`-nU45do<-&=^ zZQH(y$JboEbjc}0;disZp?JY3k)=-jhpt>HnZSSO-o1HeBImF-*89z#J=@*YRdC*E zJq3Mz{V&g^%w2mu`S_wJ3o(c!|yi;nAD zL_|bR7?-j#Ir{ta|BThu*Y|%nSDb^z=`L?kQPGowCm){D>~%9XH?RNl;$nd%Lz%k~ zquFfV<(KEqoqO{2LbpwaAKVrY&dA8PaP8W+j~_jKePxp_Z!!}X7Z;b4+gJCus%Sr3 zqR6p_oFd642NDbxeASzp?(bvp+W)q6xr{>jj&I9TUOb-Zqc&y2!sGwMB11w#RKCaU zb)DC|+S%D5FmU3XD>71x7oX>9OMK$Fs@Aw8QKB-!e@VlV#n)=5o=|f0^yKvF&^gd2 zH8;S??d;+yu5JcA!9hV)e{cJXm9@vJZ+Y1MSCD5jvvt{@ zmzS2--csf{Md3(qAk(T4+iH%yo**VCZ$0-+J;i8db%iZj)epK9o@S^xEDUJ*_FJZRXNwK*oQ6Gn z{@l<}EU^1?fSY#-tQQI%&jnBWGB7F_Okr8TYd>YnK{4b$7OW%Q*eKj!_UFJ&M=!`I zFiaQJ2xm`*TOXV~t5t4!d3#%zzngQR(pdRo;D^i^95K7g-v0Ud`EZKNnSHD*LPA1G zNlEvZ+z%d2R1y#t7M7Q{_c?a(O|%23@(f=eSIaHKD&F4AF#o)L`MWzWtj%&PBKrJh z=a~Jzv$NPd|DMd;o3HJ|H!P3+pL6WkTwZCj13y0`KMv$Kn4W!oUF+wE>?iVaRH8Q~ zvCiSQHPe#@44j@S4*>`rp@@ z2YOgTa-tK%wZr{W)D2_mHbm&;=H~JoZadAm!TJ#Aiq)%Mzj)D8pnh;~qRN7mD>e1? z?R)qdUJCj-czbsrOn}L(UAuPSLPMxbbaZrVY;B7*=R00;My}RHYuBDl+Sqow@!=-! z+#e5>?1SFCyRmWc;>FE=%lk#z5A+MVJ(wO}_wv;%sYJgVId3TOa;6C-cO`>?(Qr;9&FKy?c`l-cLv^ z}VMeLmw7k53FD@>=I7RbB_ZE%~H*>7!zI*d#&g|LRx^ow# zn+T#5oxVSvIF24Y+S=Z}K7PNQmDR5NYY8&@^o2Vhi$TzW*gy!hxI@KG^aCfhFm{M% zy3qFiG)ofNU=Ad`_qZ@!nfOBFhe->|moHy@e0>dhq@89byvkKdNJzMF^X5;pN}hdu zx{S)o%A%rE7jEUec2A8-O--%D>Tm8Ri5l4`rpL#6jZI8sqGl(&U8~rTIAi6?mHYPn zi+*fqVYP+j$&)8OzP?|-d}+J(=0kL|*`E*g%@4mO9Pg8jjg94DORl)f@LGA=fqQ$a zZ{~dKDCL)tE(0x2fA+EB@H;jOgCx#5HkCrVI^Ew~mgMY<-BS_h=$NQd!DQFt!1U?U zCqqL+AGKnZUu=54EKFKjT84&($pz_o8Hf8@9+}Uvn=yMf|MJQWwvRX?A|iS!%xIwwE=&dHGi-TyG@W%4))|zx$qZW_wokUZ!Gh)a1`vkvo?CWoLx;tL6*YT6{;7mUfo*y`kJu1U(YR>Z<7su z6a>EP-CFne7wB+gJ3BiQlP&LKJ0yKsmif+}Hg)RNd-v?v%1dN?&j*%OZrr-H_Qwas z`RAw4<-G7GOjyD^FXr_9{oAd?AMAO<0cl07TBUV!Cd1i$Q$zv>%lDupaAn~I-`1*K zxNu>?+O=;VKb|~m)~~SiCF?&I78X8y`0(}h_5FQ)@2bU*J^XFdD1o&YP@V`HS$q`C zI3H^o{sJmQ_W3Aa9ke{)q2eIh>DTD*>~Y}Al`UJhPIdbEzq+`>26S3DXx;Ab@9+8V zb+1^l;_B+~erfY{_Mum=Ufuui*XwAoxgvsaeCjL zJvMo#@7$TQC!1~hXY$6s_LjfD_rO#?YRiku{`RJ(rf>bPc8lxt$y#kGe}C^E%aQ*1 z7KM+d=|=C_ySMXH)uSVwZflW9~yS;7gu3fV_WFi{8mOfH#Ihq8v+sn&q zTh7f%Q>Lf{IV|#skH5b*dV5rKbpHgQNfRe-Og!9n=#W!qkz!EA&reUa!`3L+t0``L zet!P@+uPrRZp-SDKd=9*Cg6*-ncPi=1g7(Q58vUmK7nZdV9}i-;!D^ z%Je4FJZk=$9Y3o+K63T^e6HEe_dbb+%Cb>*3{%wZL$E(jLC#x4fKUe$j&(2MoHvPzQ^(wNM^X}cdrQXxu-Pq{7 zguyA}>8Yv9{pKba&2;JBXn*qhac-8TzCJ!~?r!7sb2Dbl*b`U5@y^WDR5xM+Xn?0# zUol2+`|8!&3JMR-+y757kWiX?e}Dad^ZPZ*YlRjqSt24VoSdHCetXrLHBUZPtpE8- z{H2gfpDfe)dA5fQdVcKI*3jta>B-5>mHp$kD#vX1?%ma&pPkLVwnp&e=H<)PwY0P} zH9JqH2+s>nKR!Or%F0qY%bS`~S^4wMPSEHmTfEbU zQ&w79S>NB?{hRvmvcJ7;-Jc&1ygA|`XV0EJ-?myTe<~+SQ&$(4RBu{B!iD*z9rCAH zDs1k3etuq(r)}Q6dm4{F{IY#J!QsmL*X#GYaU4B({SaTU)PQxze`& zU(6CMv)OMSKW-LywVtEX=W6_uZ*Om}40&~KuJzBFx_To4ewJU#2cCZhot&UG6|}PZ zU&@jG`aeGm+Y;x^o0nr2owDlHt1PkZrw<+kgomqxyuEGPwhbE$R8^P0d6V-o_@tka zo?hR{lz*S+|9|uTujam&uU=&t8yoxjo&_!0U0GFCwPx+wNS!cO*H)0fcE-F@pI_s& z_+p=&t(K8!|MA=VYIo0>bLZXN-L707A~UB?Zx`U=&dA)zlWgRhX3yU3V*RI_^vrbi2m6etC+qZ9KW@e98 zzxBU#`m}d^yuGF6&ZSFTm-zVj^z7MFQ&8|hfqkoh)3Ia6oP6y#6nq7(WWh1L^Krwm-P4dFI$!t6ciL5KHY`WQG!FEW!LWA!a_nOCMGqtwe0*y z4jnpl^ytzpTTJZjZ$qenk# z>M}AkD(4_4$U$Zo$F9QBkuzcq1btLqkI^FY{Ga3+@mRRuA&?)3dOc;kO)g z1LBnY?CjlTZ)dGr_wLKf%b*C)%+0k;JvHUfp+k!nDNW>@JZVx?baZo56I*=b>Xj>7 z+uF8m-Kwgl*0sg-$V5X!!w@Y~3yX>gn{RwLb?frw&C8alDJwgt=;htn5f~o+{OQxL zv!)g*34iMi2?*fedPDTK&M2Z~BrpLy{ zc6N3a6%|$3ns_)%w6(UhoH%(By{W+fYN#R`nab>JDpB`bluFMm^oEIUteFWd+MAy zHgCGOTU%SNkK5Z-Zo~Psieb77r>BRbBzYqhiG`lrvC zbLaA9W!)Y?u=JHf{3r@i|gGWyvSY=MNt) zT(@rCq)C@<-O^gQT7jSC7$0aC$K3S4&*t3QQMh>DzI(@yyN8E=KYJ<3!@|-sG9qHh z^5xgBUghlEzGcgjB}-<^nBlRs$&n*7GxO)~-`lrs^GcPrRLoc1RrBTh`Kwp2-nkRA zsO2x`Z14&byQ(i9PdpAiJw1J z`1BJ(N-45>jST{g+TrU;%F5bWT0F83ZkRuRep{OxX!7RRbI=7wcXy}f=i3)Pa#1vA zE6dEtc=7aUXk1*~_jh+2Gbe|Y zd-CK-H#fJ-%Y21*nQri|c@U15&0O3fuqZ&Iv9Zz1%S*}JR7X!w zPe-SuuyEovGpl9GmIW{O)78|Rc*?AZ`Ed7gFHg^d=?gNlv-#clCtkaH_3D)?Cc3(7 zSFY^rIKo`9HY+dh-J?fJCD{qnt*or->gs%begB?)Br_w*gO$Zi5)`eQ*tH7F>i+$F z9=bYgC2~XPP>mv46nc8uh>FM=(Ej>5KGB|46nKNf(WMsIwxa4fB zRF-@`*v#H9XIoTSD*NY-jZ<+&#SRCB9Ys%1Juv^EUg9Msz`>%asi~{0Yn*;=%C&n( zwY0SA>gqsCmBUp-!ot#0Q)kYe?LX7VH7NY|WPVQ0L<0#-)`eZZrsF<>&7&ddk&&@WAp6&(@x`YuC269({Xz`+WO)y(I?P+N(Ehx^(?| zIB0g@T7$l_lG3ePw+^QMb*!wU6t7&mG-<|+6DdZ{PEH*6*(3|f%FGN6 zPo6kY@$pgX1g)9|MGcLPlPO$xrEaM9x^Z)IX6EF`+&h-;@9$qzW7Fz1F)1}SE9=#h zCtp6ipD!@y(4j-_{c<~Z?BJ=3Raq$c-Nw#t-r2O`op(Z4hrPYEwR;CQqk@Clg^L$A zR(;J{DO2bgX8q~#g*N%0=RLN`&9kqsyT7k?@7}#<&z_Z(luS!Y`}XbIC8L!K76^!m z9eeyyNJ!{}uq-Q+qmvWU^wYeYoRWW{><&dsOG|5Oubwk!&c4I{T6)$nR|p5Xx*i3s zHPbcWYHfNyrTFP7Q6smO3tO|V@7leanTd&QzqgH}o4^10yLbP-yuAF!%fjV;a}V9` zDJ?Cvw6qjf^Ogt;L^vaDJ zH*VhCxnqZf{5Q~9aQXZHs_8ymkp4yR$KUVw`{iuA1gbtg@eB-{xOnm72h&4^r-+D( zHa9g@RaXlO33Yh1{M-MxN?1rpL_~xMFkLqRokhNt1#S5)@{i6_fgQTszy<)m1a>nnc^#8HUcjzP$H^t0v6jx2SY>b}lR1 zwsh&zkgzom@*Y&5`Vt;lyffxy*tN29oGm^IJXddYq-}O6=n~i^|{Mv)!W}+Qs~sV_`!BLuu*PD_253@$7ADYsQqrt(LELI)xZ7c+nqgk&dl7rysT{6BHr}$^y1>rZ{EC7 z_n#+_Wo>1Zl$`vsq$(mpLeTOD!@3VwSBIZGc`_w;=gyr=moA+*Z(fj$ggeK>*_^Sv z%hoPj*l6(m)6>&eu7s49er;%AP%8Ss7#tj2lhhI77a}*qzF*#cU-9$4ty@hC&2As~ z!m+fdyxiQ(?A)0%D)}iFZrzd+7hk?+jn2_T|CR}xHWei#B;@A4{m^I1DcEp&qW^&(9?#CEMECrPLgs@aR#J z=BlY4p>=it4!84v^m1I(vR<5zgX6-53m)Fy%K4=iFI*`2`YP1abnAfw2d=A6f3a@f zym`~7U!Sb*pLc(suiuP0bMD-@At5EDwYIS^rZOU8#-c?@IXOAi)z*pY_Uy6I);@ja zj8ByDfx@$WeSKnLVwRScwc%!h%Ti@`6hA-r_;~-_yLUSu|5}n{XkZ|4KX}=`ee(h$ zqN8U|nxypg)U6{&QeItIdGzSf!~61DPiV3<9Pm(P$o(<#n@ihq`I?J5P8vo=L0!&b z9Ez%{OD9a2Fl&}nQE2V^dwaXOxZ>mEOG`^N(<1!*-pwt)=g1MeuV&`)$DVCk|Hj*bq{1lhg6;`(tsC}`jM1+`LjB+CEh2KKkkF*V=DyBzMO4=3fyP5;FSnxslVELs4t0l%!l|TRf{yulkoF&y2*87fx1O^(asij5y zyKv&X$f100M!9}*Y3b7`M$OI5OHJK5&+qQ+?CkFLc64OCcvMq>W76cww{PD*eE9HE zi;3)tD*F2N+1GShE-dw)-u6`X(DTn9ABU%%ouzvB)U1OEEiEk%X7dTPzB<^$h*$u3S-3VwYFY%Kl{Ca{B49W5-slT>10YFR$!Ap?9lVTU+POy$e|${z0NfVBXm@ z@4YP=8X7I_?T?qvtq|p(H{*v?g^gUC(~^Id%U7*>_5OW)WMt?38|}NN%$^+`8!Iaz zp>gzN!;@39Vw{e&GfZ+w&=F`b`x8-dD*s%vudi=d*tB)))@>=9q3rW${_hw)b4$ya zE6!iKbZOVFU4Q=mU3&Y1D+j3Tl90Hww|e`gO_M$(o?v?W_N}I-<`0*umC|3oeG3Z> z_4V{r+!ngO_P1G`#r!R1YZYs@{repr6y&56ynfZHQ)kbb8W>DC)%T@Ev1LM2Q`7$a z_2uQ}g=+-={XP4%h?$vr>F>4u0!8KJ*RNhZ`kUiK9*^&iojWacb$y+kowbguasKR? z?>k}AB&Rp*g|Dya{wdgZP=2;b%IRy@%KrTL2s$tH&yS54ba${YDREAjHcd=KWX9~- z-sNmuP9CA5S8w0my>a72iyxppA*!mae#?LV{MlKOW-u`>E^gMWS>}0nB&Mla>c{Up zqMe=j*1+9OP(-BVy_0{5|B|IkOUufB{ru@!cvU*@;?bi=FI@QW?(Xg*Zfr-79_^R2 zo%F6q_s+Cs%a%=_F5bu2|MJBP4`1KVu&{3*KPn1O@VasPcC@druBmBh#J14&>(-q+ zd-m$}>+`KjSA}eH)|fbbIzI=;f&V)?PCR*%!q+Y=A)#?sPPOI2m6gF?zkK=dUgnSt zXr-kBhlBJy2SYdJYuB#n>FHHgR{GDknU$57@2~$~=jq8QXqnQuyZrsMY11BcUs;kT60apHEZjUlxhwpdj+nNA zLBKBN#~g}My<*_)48@unx#EI3bnT9-(R<4#e`j-%(eEEz79)GeR^i5@zNdaTzMjg4dUbDb93Kvi|cK; znbRUL`|Q4okBio=TNiT9Lgdt}t}d^Pj0{&-S3keL?(S|8^GAY4EYtI?87nI*#l^*6 zp7W^Hp5Y+UPWn*FSs7;VjOv%W2@$6Yxc=+_0Gdn@UOJ${{ zTQ_h1yrb~(l6i()txf#zx!+DyD|J>91&t_~oB#g#)3f%5Flaf{pFe*-G{&@CcznEH z-mWGiH&=IYSMIGXnN?L)=6QE+Y)U=-^z`)gF*}v?_20jLumAO$g42m3M~>XQxpUVp zsrZ74GiOGIhd+PzOzm##_aDlK-Gv04Iy*a+27w#hZ~kHTef|Bd2q0B zUB$h_?fl+eUOBnBsTUWw2+Xpp-PP9S=H+#2o^3T~P1FuXMg;{I&?;)sp>AGYT-`?} z9o=r{bmG#bOV_S#TeD`(f&~nUC6ABwE?c(j<>lqsnVFoH#y`AORhKq2H1zfHEtGX; zTOTRI>*?vq)Tp4K;IJ#3rQk9f8{4~g?@CKcE7U9U^72AMr(O|%{9u~_4>t$Lg3B*E zJ3G_Q&+F~$+gJB@S6^RW$#;E)34U`dE*?9!Y{d$W_mu~=vumzOC@QaQm^EwG{{8jd z-riYRtG1MMtyfo6boBGn16j2CUIBYgZ*Oc&OvlxU+w<f`AH5tBo}>%#ButNk5u`bYHTw)D+6LA#ANrJnZk_I5w(tfi;-@6G1( zbw3`qC!U$OYuBz-tF-oI_Ug3Req@gNnCz64ocvMvO;vUE(uxh!1Z=~@!((Ibt`1-S zNSV{AJhlAf!-5aOn?W^^T}q?CAp;)!Z~At2^A0~uNl)Kj^V3K}!$T~-h(ocs__OC^ zwWm*?mX?)iX=}&ttqKhf4}T^6^5gMF`Nrn=I%gjiBqb*cI&IQc1TSFKHZ+_#qgZcu zkmI#8X`6+Ggfv9FA|h@GOquZI%a>)#mTlNz5Lt6lv1QHLwYs{xn>TOX8ME$6c=3dt zjz4nM7pz@-_W9@hySq&5{!~bQwLEq5lvn|JQ~d8}7jhEH8jk55r$cX*+PN5`H$ zf2L}Of4F!;vDyLD6zS~L($d-#(Q|n_Xt>}>fkk3s;-(k7TsbVQtzW-#x<@1JW^{`QurtnAw5%iZhthlhmZ+}m^W-o3cU$eDi2rKO~P{rXk+ z|L^zj@9!Vq86FyX^X5&#HW5+LvuDnL&Tx2ig!7ZyjU&!kd3panpSM4J=+KreTO@ee z8XFJ(`T03HIr*dKgB=m+>C4xzU*Fm3d7t?VXz43gYtf@4ou57xDJv`AS$Cq|)YNo+ z{QkVu)TOIe?@m2EEx!J5sl@g+FHg^v>(_t({Mp#RKq0`x{K2bNS*fX|pP!xm^XJc$ zDI&(k#*$yRf*0B`GciR)MYZ%vP0H*0m38|3d3`OdqT=GsTeiHZ4%afAHf>t)a=+Ry zF9Pf8{{8&?eCm`bPR`D$UrLuQS|lVX*_mHEf5LffLed3V3& zO)m$BhH2BnVq#+I>gwX+<~27ri|}7ll6K;lIcru`W#!cA(hXlhhcRBrCt z_3PK`Jkxl{XKigA9UYyXlJeyFb9Hs~*)wLGSWzsmxMcBSVG)rlmo61OJvH^ljT?P^ zeUY2fR<2rgib=LDQBhHG)v8tE`f+E@pV!yXIb!dflE|%?l9>4L-MhG$7@wNHQzs@& zxV2=-l4sAJH8e2T+S)FRzO<{PyxiQ}+~3#t?D_Ni3m+eA;S^4}va?^{()H`#zkkoq z$=Or&b=8(X?6wXGR|F>1N$*>{`0-?ayU5LHzPY)%1qB~ArJnx4yZYa+*Xz&Q|DTib zo$KE}-S~ZfKA*Rb-&L}5_3G@{*t^%(M&Gafes|yPy>^wKQog^t8y6RseQk|mlum1F zt9;FegZ}n^k0cm?E-~x3`*i}mRN2bPs_J;3>=9uh4i+~zH|_9sfBt+vFRl}jkeNAi z`tHTielY@%53Lmn~VMqM?y-a+2!0b?eOY?nLaV_}IoP zeWH2Sj?XQeMGWC97A@M8aImTW|L?=sC+*y|>!10f$FALCk`fXL65CQvPTH_xL+tJ{ z-qWY7S_Ik;d;0i@aIh#UDn9A)FkiEJ_3KBEKK=Okc*l+%hYmSaS63$|C%>GfkbRil z^U>qSC+F&?Fh;f*g9lBUo0^vFyEXa4G_R#>tgNPHX2*^mUAi2U`%aa}79}Jo^tyHT z_uE&0TeD}+9v|3gt=kf9W*qE4<>+uZ&hdwv;8wpmVN?+o*u?2Kpn$ji^4HEY(69XsB<$pK{>-s(qX&CSiCA|jI}O|r7GYO!hbR&Wq_ z@#c+>mse0gz=YU-Av;4B`^(yTdh2%Wx^??@^sePm0yhsbFI>1#R#rAMGxNx|d?%)$ z{h-kYFRw?Re;U=czj*Ot$IhKor%pY3^r)za$c>vfXU>@6VXNPA=)r@88s+96KPsep z)h-J))mNmXr5!tZ^y>BNr!zh(%roU`6%rEq^y=#B+2;8|GpCj|oJ~7^{CM!nD-Rwd z+`M_n-lnUo>(Qe}UESSt=gj%?^=oRno{CC~(?S&$6#?glO`BO~H6FO_+Mrcht{=Or zpsKpXCph@>&f@20d3Sb{ybQ9nwOy3l zfA}FN%}BJ>e!Uw0MD{vp5OB|)J-yQA>*DrG*?Wa32$-0d#Oy3`eevMh$H&L>@9mMC z-+uV{=lQnPpzHoXXW(C4pIpQ-Kslma)X=%%5&YT&LU2uI}tbY8ym<_Vx9h zZ(m>c^3u{-v!rr!bIU+m$c<>%*Ef=-=3-Y0wb z`7_V&U&0jwCad{w+P3Z7*|W7jKP}ZU;}|+1a_g{QI0abGo{?w6#~CoUA_i?!A4r)zQ(n54CdV=Hyse zS#8U|@3;8kG@Zz#jEo;oPENjY&o11S3T}$xraQhECx4yoDYWQ=iJ93v>+*Gr7BwAB+PP!Lj@`TC zcN9E4H`n^dO2)pvzQ1o%E%NSIq^Cchw7=fZ&(9@Ik%8p|i^(JpseR?T6IvxOwu{ty{OZ=ljnvaD3%%KVhwbM9+o| z8#bq(e>A_?IQ^W+sx`A`&#wRd)?8F{>WUQ_j~0f9hR(GtUbb+dqqFnj+qbI^wQ#EY z%{g%W*rf~;dwcu*{QQZJ<-dLVCMG5p85zmT%e!fIozppmmc|3o&J6NFV!uFF_PTLA zR1f67TlH6U`su%KHlKg;^r`Ezw{PD*{rq!BTlxK3amA46Xz#ES&q2+dt5>h?-Lq%b ztXUtTTU%Ry{rc4{ru*vMJ2md;sHj)3Uvp;)aIn+i8K28&aI8!4!ZuN?oWlW@#YH`0@T&j z)6<{#_4WPy{5)7=%7O(7*4EZqQ+MUxx7(y;bLZZ@zU`7BAtA3`z52!FVF>C}U0oF_ z(f0Sb{r`!JZe3roYQ>5PlP4D!7r%b>s;c+KgZ$F+^2e|5%B;n{!n%9STCUaVNXT3STp$-{?+nU|IvI&>)Y^t6i^TO^IsZrr?i@#Pm;>#_&+ ztWLLn)cl)gTm3<|$^PdP;Ya7W#5Zr)aKPZrWq3wV zhm=fAN={AD3|{W{^do56yr`&X;lhPxW@aH;UvF$ocG||m0faC@3jea{1-MhYz1Ud-lUE zBSpAk$ASe6`2|stk)>s2-$W-Q`S|<$7Zez@CD#5wwIri;jh3b+=iv>k++rM|*HR=` zw%opb`=ee$YU z>;Fe92;|(^A*g6l`RU23RjYRFuuz+vnV&B&C6$$%`}chPzhDJ{h^QznP0iN!_SrLL ztXQ>b+0vz7x6YV4we`ETg|#)mW9r+74;>c5Yh8Zk?Ahb}^72ALj~+dG^!RabOw60t zuTLj!{PXwk*)wOROquebwxczKlZA<|{qse4`G@lt*S>e+5fI>DS-W=a`@P@qZOgsw zCeK?_zvAob>)mH&O*#HhQ-rJg=%dd+%irJo`thTnRokoH=dBM8_sp9&ud}l=H8u4| z(~UWE=G?k<>%<9&I>Teqyz&&}C)J8j0ynXIg=vesp9K0ZEfbj!l(@L}jfTTRrG(B&J3M6O$=t1j4-+2CR$Q`|HWc$^ZX6w?DEi;>SkS_}Z^mFD>=1 zuCDg>_Wro`&C{n(`Q>aPLPA8u#M-{Ma{pYmWXY4~&&%K4+4=JFa$)8MC!D_5?3zyJTf z6GDfQHZJp@FDEYk{P}bB%bpv4u(Vvb02+O&|9Dh0t0k37A#QO z8yUp2v=%zf9`AxoCiJ|e0To+eUsJwCwVOC>f+jv6zS>t@=z=H z(W6J%`D8M3b46D*dZ^sGaU*6=g`uV8&11*drrz9|ef`{A>x-vPo$|7`w=Z}k+hJ4n zMdQW-K~Nlo=95yKQ$yhf1T@V`*^5psR>lZIJ zs##Wl(eATZ~sn}UFxO~r=P)6*V2 zNZ8W$=kNFX98EIzb$4#v+O>N1>Wv!(HNwNgLEEs7c8h}!;<Jlos% z@5}Gz|8sM5`oW&Rw{Ar-H7ab`=r;MW(1gj8H*eg?$;St}@nq>nKTpqF-||1z`ygv z$&(*He|8q%JLzOfeSN*Kuy9CdRFu>Uj>Z`qH9DfV=h;?$;W!%@9)2C&ZUx{iZ3+je&ooXFPHrv%t^4c+_|tzG_=FJ;b_v*B}=w!*#bJ(XNSfdEw6%ihlM#> zN?%`#-Cy_jP%F2ps_L?3%eck$V)j&Q+_h_0!eiYj6Q@j>vU6u;LBWUF=J^itc9xbi zebjE>y7lSg?;k%v`%)(R+kO1>$;iY6q-owfxnB#O2#f6r2?#JSGxPKIUcGkh)hk!d zoII&G(c{>$V@Z;;5##HoWy{nW9d;Bw^$H4_v~s29jISou-*UKGi++B3dgREFsoLS7v()zZ7g)>z z9cR30Q&4bl@!wxxBWyDy))a&V1`2L8TEOWp5D*%=G(aOXH1z4yrx``@@$n`-3Lfd{ z=|x3GzYcjR2>ghu-3Pitujc&XS+k@H`ow1#S}gP45qR1$@#LvfU6-ViO)~Tp6x7w(pB>^X_4W4dKAIG} zqd?Kx`u2?*JNE6H=b&(Arg6K63TQwxFfb6b_N)9o+kQ>6*?;er-xn1T$;i%5p3P$7 zt~8M&%6eht!lVk;D_5>)hG3awUyPRNt3Fos~wkxXo=n~QRKLE>sD77 z1B;`GsHnBI^+vIu?-K~ zyzqH;Fx{(+_`hdxDw+39k{0& z85t=lDY?RL-&wvHK51@lY%>nhYV3UBj`19Yc z4U2gL_g`pInCQ{;_;JGP^?iMP@Av&)w{c_P#YL_;X0tt1&doN@FDUqMq*J(G-hSJ* zZEo{#-@SVmG|cPe)irP4ybGgtal70Jnu|Nj2ooaY%Fe0iz&bS`dC-qQHN)$Rm3Z9{-Vgv<5CZ_s!H=p_1YZ$QJ| z1~1gq)RwJYef#?L@+T(*ot>Snt*y5RU%GYc*VpUu$B!P>jo#*y(f8=lqXf@o7s}UHK-6ySL9a>=SyRw0)gcJcJ}t4=;?|MyF*CJeIO*WQgXa17mMmYs*y?AW&-?f9&!0JS=KOhg)(y!|IhwwF`?hT9($J8Q1x(Ur zISz+2q#N^c+Z0ax`}=z%ldrFDXJ_Yw)9s)I72HizTOM8%KCqL&U!h~)zJHU|{qjEA z+4<$}?5UjWqZYjK%F%A|_xJYRK7E?odehPA0x^?Lrl_i_s!isc*Cs0~%fjUN!kev0 zfs2dFMQP&uPKA)SCzQ5s-TL(DQ*SS?9Wm=>%#gS-H7jM6o!QjxZf`d?w~UMxGiOT1 zXX`2}KYsP9>glPeqS|3P@%v;-O7Gmg3)-*O&M!Z0%9JI`mbJCEHtKuF=!y3*mY0^^ z-BI}X)6>&6wmxFrtbWCvU0tus#zApdk ztE*3+K7H|8yh-7OyYYhF^$Hv;O!p^zUg+HZ?cLpO1rJBZ#;sdRGcsPxv#n;?AD)~m zojT)eTC?z*O`A8bUcI_?-s*zHqfahGiKb`QF!>!A*b;0?fdr0 zIZo)6HvjhZ>))@}<5g8v6TUB4vqp!-vBDX81t=qSoYiV&g zPS~(vgZFg3-k00eHsrLQOu4tCka^8(#%Uj>u3x$|H8=OIf$5Q(Hzlp#IV%YKSao4# z@bUv16;V;MX3vfW%?O{J-7aN#@RCHK#9GCdFJJQV^45IgSQWb^<05E{(48HDQBhT| zudSUiL*j#K$t;aGMXPfa^#1}pMSsK->~)dP!S4i@KCX<`odwoyURx{nLRSYB&wjm;M-Kb zYH>#aQPHU{USzCc*mX^0#*(#b=T4f`Wc%nzGwZ?c8>^0Xi7wXRP*+!9$a?YaU0HGQ z<;#~J|9;HA{$Gu!=SgYvyfyLr=N(NF6%!NUX!-m5`{sx>9UUAWPR*V$fkDlpz+%p; zS6Nz9qhexezQ4P>*uDRgZO-gjvkrvoY~YyrUN6eNkh8#I&V&gQ_U+sE;6cKd8KMWx z4&A+5`@_9u{d)axf+`WlpdBy;M&It&{|D`znlM4Y+uM7eyP=-kLaz(Qtkl$&Enoh; zd2LT?>(RfzzvtiE6B!uz@%Q`v%a<&)u{o`)YrGJ2%(*hHuk_Jv(CZ zA|fQ(4`=4)vM%RewB5lWK7RlD_3yvEy=`6grsDs3`9=qesxKPthdVnvHFb1)y1P%G zIPv54`uzedi5nxXUcDL=6x7<<$}eXFIsoQ=@ak>bzMY+Ip0M`CzrVka?`mslYy0-? z+p%NEq@<*n%2{rAtc~8Dq^>I1>9SA#eER&_ZPnlNM7kd=e);b1?gYCBpdmsTOVAGT zloXR?rY$E^n&zieRQ!1GK;iymE>lt79XodX`T2Z)`TKioSFG^x_4W1kW}ZBcjg9Tq zt5-{wE;TkXdUt<+|J*BW%UF9&n-tvK+zbs3Gi>Bljg5^rIPi!bu&WbfDJ&^D(sz+t z?8r3T=mVV%4u?6oKu7CvM{BN+EJ-Pn-G zyi1g|(c!>8yM-wQ{9Cqe?Y-L=up_#AvD2U59}@npZESRmjEv09%`Gha`1<;KV z(8&Dr=g<4~|82Lu;#PWGw9`jzvWrsVI;Ix~7EDh2`GlQ~t-?m`m)()?VohAlr>w5T zhWHpbEDcIcNx5LiWHeLf6pNXot#SurZbVQ}P;s&G{SRwr%$TuzcXdI*hdx>B3z|MZ zfBsBMOViWSyL$C%JD;qVzdw6)P_V|7=+9oh z-@Ms-AWCp@LvT}QNJvg@Zo8tV(!{oU>z@gZ0sntG3$V=DHfj3w@UXCB<{vZ{omJ|Z zI(_={XU{HWY`J#r+L0qJU(PbjmdW8XG%#>b5YW=rHZ?KHyT9-5ojY&dzyJT{=H^$g zvRE8bQd8^yd^}$H`Ptgo-DV~xTh_1l-@t$VVZowBiw>|n`|;yPGduq$-lB;oQ>^C7 z$;rKY`}oBaR#{{N*VB^O?PnXVtt z_0IqEudlCf-HMXx4GRsOI(4dPS^8;3j!Sp$%$YJ}$+~rU$;rk(yo!@gE?%Q3^#6|{ zM^awiy0vTnK07;m)haDnS=pS*hthiB)$B_yW;{?yS;#9Lk;0MX5gB>&&d%cZcXnRB zaiikfo15bLaSfFvr%s)kt`|GYG<(|Ixpz0GpI;Zd``CB09)%MJ4mkMuoO$qIK}*XK z1Bs(Yj%>I+k?WWCDgDAJtcw56&ri6P!SgHHE%^u2r2l_Dx+du_{rB_mu@9|3?`i&g zC&bb6(A})lGJl55IH*(6- z(w_Cz|I^aeHqX8F<=fln50>73e(z3BR%c~pl{U+%`1t7PJlpCYS+QAJS;@)Dy>8li zdZ1?Kxrk@ZhQChFnlX@@r;h?A^3&+dR|kFfT8! z;NZ(Q=E}4wc$AfurKYO(x~*Qly87?0t&0~cUrP{pRL8+ z*{oQ%?%%7`>o;xQd~ieSv}xD!_y2WUe36HjmzkNl_1i;hYwO349#z=H)z{aDgk0H{ zd;5o5{?esOV`E~BjE&9n@6~*L6>4BIVdBJ(FPG1McXRXdRjW=NKD>Cr0){hp=bC0; zo2>5N@S$5=zoxeKXI;t3lP43tMb_2TWoEuyCZ z+^@DpI5j(a^{Q2~CQP_+?Hb#%;D=AS=g&KH=FF^FQc}HPv9W)jot1vWTusD=Vw5r3E^>a)0%Az8dE1SFi3Ze9Sh}=i24V)!*LCykKWjan(_v#YKttv$J$< zvhA-XiFUK5^>&N5I40EG>UbFanLp{tX36Q^Z&tAAaV_r>`t$q4f#S@}%*FNp4*W=R zc0QawA9Ty}<`*wA-joMA`q;?vzlrCKir>J>cRxUQ7T1~Qfq{XBrlxl{rE>QlKYjZ2 z=PzGs{`~lOZEf_%(_t4?G8XLLzkkb?5LZ{$l9=abXCHr9aBpvQd+Z9fmP(tr$Vkcd z!;IE*CZ9|Z>SWo*G|cRl!U~O2M3wCxw(yI#)O5X<>vCF4Ja?u;of|K8BhaNvMLc6RnbJ;u1Y(2$Unw6s|>XZGG+_C-ag({DNG%=!m8 z#d~A~uS}jW;lh9tf<1s!gD;evsc)vn#Ue}8&<+C^#OiWM9=VyZL3%gf6vDt1hnGNq-(B`qzjveGhM zUhd2+KY#z}6DBa!R_IOt{o$dr!P;gAg)3LCSXfy#^{>k@`~BqPv?Q&C}=4t*xxMWaUL%41Y;zYHEs$Pv2eseqYts ztT(?t*vRQyS?yZ9IQeiJ?}E09>gvyXg_SviqN86wf3B{ox)i(x4Yb2RT3T9Ca%N9Y zkL&+Gjggn_|9%l}KfH3y8Ww9~PN$6A+}_^asZ*zl{^C>D;7?9dYc$QirlPKX{OHlG zTefh>g}5!htgEZ5DZ+KDeSh6wtB9KilQ!PEb!%JBO(r*q-Mc~aq+yYfpyhTCA09NH z-F!63w)z{7jq|@>uh)y~$Gv#{xEJ%3s>qCs5xrRo^;fD))x2|2g_QCg8mo8mOKHk^a-JPAC{r$@qn~Dzy?%kW` zp#oYvJ7Y$J5Yxa@9*u+2G74fk)DyZ zF(N_H)`D48PcQG`q1NPZ=Sh<$Nl8hyY`eHfovokZ3laeM)m=F*aW>!{PvG16b zfkDC3Q&XFIO9KNhK0MrhGG)`cb$QOt&K@2ey}i8s$F+5JO^uD2FF(%C%G&q)-R{0V zKDEg^)6PmQ)SEtK%9Cf$R;^r_xP7L87N>H$4kK4hg8#_^duBY}1v}m(bAB>FMl@+>~;1Q|jphQptsdh5JIa6+|Vp$^|nVFj( zKYlzrJNx&qU$0)hTDEN2wX0VXHy<{ak(9i7^(yPPqesI(8{C>RcW$Q1tk z^VImIYv4P}ZSl`vznUV~S5{Wuc#@Qqbb7je{N^;@`1ttX;Na}+)iY<_43DpMRhuj= zCABU0_O~xDFIRqk_VV@X=;-M3va+)B^8c^n|L>~(ZFc{-;R0hbvu$hFp1pnh_v`ih z-@SXs_FHS=&B(~ewQ+lAd8lYql-na_pE}TpVZ%Q1rH(moHzweEZh6_ScvH zfA9YnPjxoOWHn>S(^ z4}#k|J5Rp4y1Kfm%7J&|_U-m%ZzL>cTt0qWT|pt?+#E|bHnwNap1pnhHsRvSUTO0S z;u&k68X6kP%F6!!_O|-d6HYU^Hbq9A#&&-Bx=$z7Wo2bAUc8uLGtpzq_U+~-CL#eJ zQneTu6c{{R97BYKgM)$=1!$a}uD^ZDmMPPx+n2qWv3av`^Faw2nLSlswPtwcrKP2% zriMmEc_~fwn{QY9?2P2T{MqmC?LB?=Z0xR*mFw59pET)Gx48Zfv1yAV9}98t^0KlQ za{tYIFo|`(kf*0-c=+{$2OT$P^}g4Oo35*?TUb~a6&1B_-#%_JorFMeE=>`(MzMwT@v(0j?3LZH4`}>!de?QpF{{Q{|fBvztcW>ONczSB8udi>8 z+3(x=`)%w0?Fry^O#XW{JpS#SotxLL<+YBS<+Sj|?c4gXyQa7(HA;cDnj|JF>g(5k zdg7U#{rcOtGPBvWudl7m-~U(4Q9xT;J2?3ArAtAco+pc+pPOq@*p&Z6sAjc+k4anqJfSH#GF`@2{UfXU>|% ziyyy!ZC(B@=0hyw>R>0QLx&C>I&fgY-o1NQu3WhnbVg(P_jh;i-o3lP@#o`y`;d^3 zu(eTJla6+^wXx|8&Q4HS{6wQ-o6PL9>sGE@c==_B z*4I~8SLc{Xd#sDyU3P6vWJIowT>sfLdHcFOTegUtDPo@#qqlwQ)~h#eM7X=N=NK!0 z$=P}E;K3tDTxx4;Sy@|qdUz&$`}_O5n3&k6O`H1V?T^Xbxpe#X@4MyqCweT|Tm5}e zyVKo$wX+=*Km*)2?wme-`s>%PQ>RQ}>E9yxFUL}@KRiBuf5O2gP)D!-9%EbY;r&~; zZoPEr(yw2?Y;A3mr^GrrHMO*~OrIX^?cKe7yZKZvUT$vb#e1r%t9^Zaj~+R4AhIEO zO80_W)24|zJ3CADs#UyLu;9aqq*=3OWthxrY;^SYK5c%###wE$e*C^O-!DtdOgk9D z%*2FttTQi^fB*V*=Iq&{M~--Tdn+p|ce*UvzTN!W)~qj)38tW%Fj9;_cdzN{>S~9r zS#UAq>({Rlj53Eo_3Box9F6A1&mM+`hKEl+nIbGad1LmP#fuiL2zhmFZFF>0lv&;# zkEKDaa*xgT%vHMg_T@`M6O$Z%wwZpq_Uo&ubLY-o zzWn)A?eM1N=EaK^y}Q4EfByY_udlDKuBb@xU+E~IqN}TGXlQ6=W~QL<;LFR))22;J zm?&MQE+i~Gxvh<@#MVqA_2I_~^Za`;TeC!ebV+9>!pFDYUYb*C| zwV4MKK&6nPqN0%z=u~=kJ{iyr;u#sBiy_q*jU_UP#A>kA7{o?rj(=Y@sNii(PchKB$DzOUb&cQ-07 z?%z@Ic#gkIEdM+RaCCIc&VK#r>FMJo(vueET)1*&%cf1M)~-D|FVk?!hZBzu@)eg@ z#d><4JbbwMY#KW|d%w?B_Tbdi)TvXa&YU@u)9==wgj*LmG&D6WEiFO2WzJ?u^!n}F z^6=q9TU*3-;gzmu=D_44Ydq;0d>0G!_G2(M%TpV8+^P|mN)4d;b zw70iUnj|#WFWqS7!i5WWWQc`;mPpQ;CFSky{pMt1Q__y(D^{$qu&^j8Elu=SIBY(B z!-fs_?!|?NhpVcprl+TCYHAwnmbf3&uNOK;xfC@U);{OX=OQTB@EQt+L#Cr)Un zt1n-&B&A2@=kNFXRaI1CVq&IDnR4gOovP~UgWu*SPmB!-32}FC-@EtkkDUCzT?-a2 zOiWD;4G*6_X;PEhBWVs!&P1b`3pU2>F4LWUT6Xs_D{JfBTeg&(on?CK)-5(RHt*?r zXHT3s@UE|Oadtv)!Z1Wi2f&BO@arSBBZz?mch!o5xy?bKhZR&<++?SJw*`wpCv`@*6BQ zH9OrF*Z%+e{YL(k7`^X*ets4c6O)pX+O%m?QBe^W7uTv)tJ>Py%=7NNc=wL2uJQc` z6(LVQKfizT?NwEm?ks+ucW;lSrY7f_On1(Lop-)``SSJk_3X?{%|H9?V`K0B{rx>W zBqU*fS<%irj~*rY`}_O)`YNngv0_KY#YNoWdLJbDr||!mop<`_zu))&gZ8RPPAFI{R%)^iY@ej0S7 z_e`ICB`<~Eow8qHU}zW^6LaVC_AQa&bd@wYndto;1!gh`KDXhp@29Xobx-)?TTGTr3Xk4t6XUCV(h zudG?4BiDcZ=1tDJ^7r@mKc9T$>8EdRZ>tEs{PFQ|4S!I~6lc}TJq)wYvUOLji{Ec2 zw$9YV+I&phu9874KTeu=*)!x0e;o;)%ZW_+?iI0!xY88@^>Dm2>UkkKqTvO!K z{{Mg9Z~Sq0>-O!^l9HeRYIm!y-o0wos%_i8MVMT(k$ZnoEg*K8!CJE?gbtBEG{m;oBzs< zH$M)Aua8rmd@{cNuj#kBGyT(!Oa~RIBIy^bKu0=wdg?}QO6ie$y?)=XE~kYtyUTKq zupMrhaA1m>!JqPqIp4Pk3kw&Qm2KO$ZQY6$E7q=MJ@1v7nK`%q--g+7GFBxgE?*Yr zsSxON@$~cz4ZYgREzY%$Gk#0P#ZyzYo12+Af{q1#ib#rra z-n@Rz{JKb7C!*o*60g9(kL~hx4%06;H_Moqn0)#2g{7QHS%5=3eBGY%_i=@Vg`lfT z4>T-UvSi)5b$xw&_g85#H7;1by!`#Wy@w7Rx^*kcY_{*>i(+~)7U}0?*7Uz9IM*er z{qOt!|B@0C3k+{CG#{+^@!{d6rQYFdA{u+;=Nr7(vOa2S*0nW}`tkc@x`Xd;+O+A_ zt5<8*tU2IT&c(%LW@a{V;>66%OwjQayG}kVP*PHwGG&U6j?RaxI$hgXxy5v%x9O;> zFJHEd&05%H$`<)4D_5>OdGaKv{=Jbo$8E8trRCCP%iP@D+5^&+_{A7k*cby+S;qXeEG6w zjZSrSwd2o=N4|Xhdi2<_RjXI`zufoTIdVtJNg-R?y*)iV2b-nayp*bHA|oRc6CZYo zYH!)PRgh)k#EFFk1sWO}9bH|YK7JI8?bn!OBd4#U;}a8e=ioucoaUzLwE{la_ z8bXhM`}Xbnx>#;*?%z))`xnG3$_NWzzJC4rg9i*{&*mGa^I2^8aCdk44)Zl<&z{Z9 z%;Xl+k+@v@zFq6)RPFGrtgL-CKQ}F3p8kV(QTrtWADfIlIyyQBUf%!o>C?7t+ZHZd zxN_yn8=ud&T~zp`Td-Ig>eZ%An+{x#6RE68J#*$vNJt3iD52-i+t0}z z)$Z=;={a`H&Dz@fLWH)KR#bHK@@31?($ctW_a~VA{Pz93ySw}9l`Ch?nzboHhpEvZ zuiC%oSk8`{eWU^PDV)etv%LzCLSH=8O05?F%2ZOqmi= zQSqbYM%kAaf$8bb&z(D0`udt8$D~=ay4Fi3Ok-?y+FASCY}L<)hua@Ldi4AI`{Q}G z4fkYyAH2Q2oulc-ty_I}XYEQn!+d`h2g@P(`agy}H%{b%4(eoKdU&K$_(e>odH%f% z87A)T?jK%erew7)TLoVKaOJ{<7q4I6-e14JyZiKk0}K{?2KM&x8IuIvH$|-Z`}=!$ zcej1b4}s94-`{dStmXWE{$IjDj=6rv_r6P;0NlOiJ{@04r3eEIU`hQ#J2OHy)jbWTh>{P4%`-`$;^f4^Mz-!YxZ!jV}f zsUK9-$;imW?60$JQb^v&fAr(y<0n%-^-7xu7|*k*bXpn&nnV4~ES$4FGd0!Jz~I5V zcl+}1+o?@nxpe8$b?f?mKYD)doL_i&xK!`7dGq*U9v4{D)z!Hu73!$9-Pv0`-9e$} z;t{tk8EsrVJUkYbmWrS~J&WOYfQ(&@L~i+o=*2t@ zPZ<)X+oh*JcW&qF4N~;6i{&(s;7Lz^F0Ah7W6$3HpRfOO)el3d+QO2OFP}c`s{EW5 z6LUu*)lf03(k8B=;ssY0L4) zy*_I%gxtM**U-@LL4Zt1!r57-uU@@MOiX;R$IYZ}3S&v`^7i)QEj8wBx2qI6ntt>1 zUJ=mL)KphjFNx+gFjO%%7QUaXaDcPS*4FmjyLTa4rgnC6yJvsVIL)Cpzm6p-Ir;J9 z$16it?cQA-A0HnQBC_xNgtoS}FJDS(Yimos2~YGWDJWQQF=K~)*Tr;>xqkB}tZzy& zn(4Q^|EO^bc%}ZTl`Ch?p1pW#!Ou@mi=UsX{rO4NYQErJ(^(At$C*#RxxOyedttz$ zMT;g)p1d+-)$G~Q%?CUB`{jF!4sHnz4YjniJRn{$-9rVmc0*&z#ubW+ii$2u7Y`q1 z&RxUmE45pKt94V^+b9;trlzJ3e;0oJ_RY=J_3S*`>ZhlsuK2rb*)l09DM3NOrgp1^ zM#>xu>`nOj`Gq<~Bqc4&q|JH{*vv=?5|ogU>FMc_*=?(!Hg$7E@-jF1c|L0YL2JRM zOtC3?!g1eFJtBQs%#X9P&DH(qg#-jx6hGtXb(Xa!$LPAl|(S=)H!+5lO(fX}hx9-{V=k#=a zR{v0$xQ8Fgi@_WCczAga@)RiSNjS(6z0>C>D!b9NR#PwMvw4Gc6iH($ScwYR_j@r$kh{{5RVL&9L9 zocq>*t6S6`Jb2)+G-&bS#UE?$vhQDJntd&ye1@@!$sF_ixVSjbzsO$0&ns81 zY*>8B;+44T)YjJ4Nt1$tf`YugyEQ&3o!V3Td)tm3pgESRs;Z1hmc`F>;`i;@v&Y8T zTDn)Jw&7sHkt0V=oIZW~#*Kunjfy8`%#b*ExOroeytJRMZ*E4$hAmr;$l2xRZ-9$T>SG8g9-zuPp_R#lLEK6 zUd``sxp{f-N^Z>+irvt@?(_TuQY*ppV$2GUQ`x4UuKn}Fut{OIS?-~_O$rk|W}D?Y z2|W4u__#&gdOc0elV{GvY)(6SXJ_%pqKC;}12m@aN}Fxjw$07m{jn(vpI!B~ZQJs0 zY+$tB-{7H=cVk1NkD7huCzj)PUrO@0RaEQ%HE*;#wr$%sbLP$2=J`MRWd29EL{##% zGiRN6c6N6ADn$!Fo|C6fYinq1*tl`#f%rKsEiKEJr`OijIyo_k9nCmoBlrI2=jV6t z-fc2X`TXoGN7I97=UKC7CnqP1>qfQ6>Pz(gHF(RTxFP4JQElzt9XockwXyAqN!xt$ zg)z(To0EOi^6%`}xO_RgOmACw*~yb9w{G29VioJ<#ic)2ezkjO=+$%Q)@|4zaJ~~AZ0F9I?*n_j7RrFGP&{(KokoxPx;{!=;>57Vq4<9^WFcUn; z?OI%1TvW7a*)p~Gd;v#+|1XrtT^IEyZ^&&U1+gX>{+sO z>D#w&ckkYvoSeMz<6_S1*RL;MzP#C$v8F0)ZPe10D`(D`bLYyHBjwpgreC~x@$cWi ze0+RDLPE-6MyFa>m<}F1*yy9??&kLB>#@tXZ-b6pQdd{EU}p6((9_VU`2Oy$hOYZ$ zbv3nZ+qOl4yt~nJ1*3t1D`&%7t=qS5704XW($+qG{`~dJmxb>no;!8Q%h8c>3wMQJ zcSnbSuyAof!GS*U2TNmIY(uoJ9z2*>P+*{?<#j|wUL-p+)6>iA(uE5Vd#g<68_a0> z_v>r6%yPb?$Bvbim04L>e8^2+18y_1^*l6AJ~F+vwbj+twfq0i$H7V2+1k3gva+(h z*B9xU&6X7vRaI0}yb+0$X3k%!LT^+V|mTh$z zWK#A1TEY0HSgp5j-?|q>eeN)BB{i!;qtJ`hxuz)u3Wi#_39ZjBpMwyY~Mb8 z(xj??e=OtPMrLMa*46Fn?Bx8mf#E^(rcIk>&Xnw%d;Z|TgBLCYY*3Q@uA6J$Wo;24 zd))GQLhpe&mc>0iJwJ2=g@vPcm*rMhSJ%|o=*|CoGskR~k6_KF4I4HTl$N>*v^Xg2 z*tv6}$CBsg=RY>JVNA=PHFGBCH#Sof6CWR+PoF<~dwc)fBX?8v#w^F6pi2i2CMIQ{ zSQWbZ%GImN%F5N%)$Y%@<5w+Pw(QB1C!ifDa##Hp2E@e1N=r+Bj4C*owDEwNww#>Y zg0>qsZdh1Ye3;3iugEy1p}Dzv?ONR?g@lO)O$v&NiV2&mLeh>jZrQTs*RLvdb@hXd zJ6pNMU%hWir>wF+-j;MARhhHgZ zXT7;O`&vuAd3=0)O}$;9w!GX?Jw3gIQzqNm9vJQHIsUlO(EUxA(F*a?({yKBm*>UA z#6(9+OIglxNKa4q@j3J6=H^0s-iM3VD1n#erx-~dziw$Dl9ZLz6}ypXO;C7v{LUiP z2#cSAWqhhO1_mGg{4Ca*`s&FO7X^V1mqoK@&z?E+X22(dx;Ehj0UCLEc}0d*$xLyngCnsaReev^iTeoakvv#eopWif7Ews!R9wBB{=-W3!j*ZaG=9=&;U=D`FP7ncW(PR zSxa|!_mq?;?mG>peE9tQ{O(=5?%cVvVYO|efrY{Zx5cb%Y>z(O+`nXr3V7!h$KN+U zkIUCLMDB2&$^JOqq7k$taAz^Q!-ebD$Se8r>D8O`5TkW3DcXJ z4&B15l+fb!upAY;01JlHR)3mXDn>Qup;mUGuhurHs_!^ijNtJU;bv!Y^Sa}yI8#qLc$`Q*Wa2cVU9 zY#ct;y__dbonm8W2OR}1^;_eL>5X>ru2eQxp-z`Ka~#6MuQxU}zIgHCB7b9fX{oEb zd$Z;*r^cwr$dji|9XoQwK!Rr>(<1kxop*lx__1!C-W~oq;&<8Bs7NsJb8}1oz2^Ji zH2+K=v0q$G3MVG1dY6=x#Op0yc{iQa)9n6W3q8lA39q0XkJ!Sore&`|qDUYjg8UIB@hR>zNFR zzjLPV+qdt;i4%!g9TO*Bd~PpiJ}v$(o>Q}Q;X=?kw;{7PZ#JIk)7Q}fGOw|*@xp}wp-z@(s+?!@Y?SZb zxf7ui77}vhh4kxp@7}Fgp;1`)abe$&Z5uXBm_EI~w^z0{`7HR%J_#PSZ5xkW6R@q;4 zY+yNHsOUe>=H=_xhx6vQO%*h}bLmo0TwGpa;=%1}qRI27}bpr<`~4WwO65a_yd`7dvapl#(YW1P`8nU*6*T$Cohc=X69n zzO*Uzw3u#`h^%bwlM{kljC(`{Y|kVZ#O<%!n{ zdC}r{@ovh-hzAZy7L{=&839FYLJv59TUUNkX;L^p-(I{-_?T}x6J+l0bim!C{eLI! z*tzrQv15FPwJj}go<99L`6}1c>sPOWhBkix`qg$a?@r#vn{OH#81{%gUlX_2N(^`t=KR`qjBcktnf6?p0M)YO1QdQ^os_ zclY)lty?D;yLrKrL#^EF;{F5x9&$HqN41ozx5n`$dmg2 z_V)bpcXv8Z>oG`4NvZqIdGYR@oR+=>KPQhr=&F+|D}yU?&G#lB@7uFy&%&Z71s0Bu zj?Sgx_OHU*6hJw>{{Qd$2M-=xxJml_kAMIE-LL!2yZ+sx)vL8{%&XN94+;)8&$;no zdh zp{wO=tBxdXY&(@_^LVDuv!mVO8;}3ubM>6^qxAJPRTUMUfkB#=Qa`u=qZuom)W$^NrG#7zg{MS|nFF!Zm{{Nq!#cx8U@&9|Z;6RAV zh0B)@r)^G6O}+TNny-EG+_}A{B_Di#e*U=JFWo8rv9Ym%ffFx8%ZqAiYiFmVw0PTp zTl`7ZZO4KI4AYgTT)BGn>({UCCpjD^Y}>YN&YU?H{lP0jO-zo|Nxpmc?pcAwjeZFo zF>Pz>-J3TTS4?)7RgoP09n*^?(>3A5PPyZm_~P07i*85tdOtuNfX>8T>LvG`h5b#-x3(XU^>+#<7FlrA1P;Na<* zSz()hf8Wtm!&$Rt-3plet=&AK=iR1=H6YKgZ*UNB@%Mk1}YOhF0ThI4X&!Fm}6CX>i+%s4FL)AaT89S>9Q<%;Na+Z zuv=W8#awiDq{4#j&H^{KW{11Fvi7Ar@=oOMnYW6?EdSn}yLWr9FAE5s%Cx0Ag9$tw z^A&VcXcWu6nHO2!ym@0{Vgee~KAXXH;in=846!)LD%Z`}p~m)Zf1682^I_E3EnOTs^_ z(i0joSQ6ypO#A}4gc?{B7(E!!s2Led1-5@&rXO&5{{G1m6VOQ}J9<(U9rU01=kDFR z>Q}?g1hd`gF}!m5^5*T^%a85gmi?Q-1nQ{gIsLo%GO_8UU&8Hex$-tK3A>CN{_%P? zc&JoWSD&A4p6|g~k(?&HAZX>id-uGj>CDWONRY2vHq~PPe$Xn0dXYVCECww5{{O2! zBg*5%^oM2HeZLKVQD7d5U@2?jk2d-S6bKvgo^5r|*FYFBzP?&rYbpAst(~Oc? z!V{)Vn>W*x<=oQw&rGFvv2&t_$^-@#gItaSc7L{LdcELKVZc;yz(k$l_lL`S8WvV# z4YcAcD_5@ExUulb z%fwSJ{T6K8xN+sm%w5%-f2A!O+uGWmJ$p8BdAsIvQ%1Rd&>rk*)23y0z^+@iFh_V>5g-DSSo(-#=;5c=@xlU2nBg>_mBH@$RjIGR*hQBm{p zsQBgMsxLU#vFzHl%f`lL-@jkkFXebm-2AGPxm{RdA@HC)%S3y-DnV2_p7L=`11X`{{~ru-zU8uTv+H_VpY2-iv8`Z3Z~!R z-rnAndiuz1M%@`}ShnTg-Xv+u43x*0Y}VL(a~RPi=n|tzNZCOG~Ti{zLWnlRjeIpv8GzU25H? z7y3@RFW9nW%E1I5yWI<1C$}EhUH)E0RaG4-wPVMOqe;GCsV0X0kBXGi~7S7x!Gjj#iFBWQ8Q6nKtm_ z*I!_36Q{C#)x5vIzwh3?J6L1N%2y0qs(UzP>}qx_U7Ffs-1us_L8JcuKSFt3maV7r z-}u_s{xX^ABlo)|fiHOKft|(ApFDlKeAU+r?+n!(lqT-`|L=F?=Cs~IyMVtTstT&A zU;lo;pPilUAIk2QW&Y-H|CBo=p4*d;_q}|?^(EPd(8$cbtXum+ zzoBBmlM@pSFLF=y6K9IA`}wq_ko8xiJ)@!FM$mCl>&3I?=z+3AdKzzI@yq4jqHT3p zN?Zm`pK_4z?|Mu8!d@iDf{Nr4P0ttXSc~KmaFM*X#r{crW@ctyp5FA+eF5vmX+e!i&T3T8f8Ul_2U1tKASXo(HTU(8^d9SAiBK17X`4aA`=?L4PM8~}RN%imGjxt}!LuWs!uj|1XzJ)pnKVht zv1mrhEn$n27Xgr|_buN=tSpR}s=vQ``{qr{-5(P#&gNXXE&slrqTuQgX8U1TnRl-yrv;w>LIAdU%}JQZ8m?!Ne3B8!IO#mzI{sFK;K~_-W;A zmTwQ2=iPjmTp1i3?CZ=mQ89400vSFT*~vEIJGd57SN_3P6OBzCN9?ph|> zxNDb{r{~Gc=VB!s=1g0+ZvD^@eJ8`u+SNvG{jz0lp`oR>D%oTYwKKFIUb%AR#j973 zy5GHWk?Hv*|GAr*ra7Ut8o*`DnH*4TZ9Xku#gDBBGbjbc))h_d3{9-Dbw-Wh`r-3$ zKDkd=zwg(ol`B1CVrrH(H~iyweDLPx=C^O(I^SuzIDz5QVSala9v%mQ2?qjL>i+#q z7vkKP!_&%sO!@ly_~{cTHYzAEE@bggx%Bq-_Nh~+w%%)>##}5=NmZw>xSg|YkAly(} zQK$4l3VRVSV-8D#d|lDB(?24o&YwSj)~r(x3y$e~&$v8AX~OK;zh7Nlt(j_MQWnFR zlA4;DlG2ks&0w>ptAeufIoNuM( z?0tMHL-*0DudlA&-kyKl^t$H+$v21no1A6@2>Z>ka9n=*_wV1XTNbTey?V=*5SK&^ zGfvJcSFUW?w(V1ejbQF?aC>4`$03d;1BsqZn~W|#UHBwLIUqFj>a}ZXRlGNMm+RlT zmbXdt(UMKaZ{Lpo;(NNnCa$`=IyLp_k|IW_&w(tbPM?XL*7*~j}pOOpRYJ@|S>F(5Q_YwqoB4Gj!}?0FJAZrRzZHU9DP z@f|yQ^zDs}%BrfaB9$7(mY^~r=k_*T4GoVYQkVXnzyIV5Ym})Z$Cj;IJ1gu`>+9=1 zJWg!Oz0JkVt=|0fLfb^a3h*6Gj@t(GNBH zHFl`2J#%`xe)+pQGbc?tl(f;saMRYUUl+Tzx?JQ;UB=6(H~sdlTUx(XT-Z`5^X=hs z-@v|wpp|J07cMNZx_jx;rd6xB(-{5Z+NB6X3U&vTlc4eZCm%`oh8dw=f=jy z`p>i3xM9PGPoJbDBsOf`JbT@|b1eJk%$*w@6*cGI&)>h_@BjVlm)rYNclYDX?EGQt z^3u}16(2#{`mM{}boBJ3Y`(d>?CmVm>}wTIct1-RGqLl@Oqe|R^y$-}g%h)9 z-~RjidvsKk%Y5tJt*bY0{`~Xvb7`}j4X`mWweO&HMwp ziY^0m%c*Vkw~C4i78aJ8D{p?Se5${tjES>h=I4HS`(>A3R)2eQ5`5y)o&ELuckKAV z62-b%PL+|BwRLaxccIQBKYmoi$KU_@`g(gyOHYo8z?nJqA09OB-u+vBe$AxWv$d6# zi$6SYWNI|u1ckVIj%5SyGzG%*<@rvSl1iU%q}_ zx^(H!U%&G1?E$S!Q975!>{e(YV<4M%d71CShYuHgy?X5$o4n_-V+AWp=Wy)Uu|q;q zQjz1*?c1|w%-E59yf63mHdZ#aO*h{ZZemC?X6D#%^UZ<<3*O$|UR_;%{P^+jU%n`C zBqby~c=n8~IwN@3pH7!Y&(6+%es*@df=76GcuLBXXJ=<0blTH@%VGM_Bv4{GJxzDt zzJ1{JQz-shtxZ(kSV=f^j7j!NUTYu8q+ z&=Bi>`tqfwva)et*xkL=(_NGzqodEyv#nl~BVZWs>3Q<;@&4n-k2i-a@wE$!i%*|0 zp#Zdd=6K)EojWzPv=*%bou~QkUEUX=FR$bF)l`0bbo9!VkeuayF)@FBe0(e%!4jdo z@!_#!$8Ow+Fq^#>yv^P7&Duil%@J#=zrXA3?!JBFhR?s5Izd4}$NS~apE!|VG?Sxg z!_7AVM+4to`}fDslr+osI7tJP9fZ4JF~?V6aJ z9OwkjKYwcUrgz_C>b>4#b4*)X`|+bkQ>ILL^XAQuHLho+UpqKEJNx+XO!WBj<;xra z4ht&{ZSCqmKR$w5fhO{M_wIFcbUZ)be*30PRz*)b)~?lkr7+WnkBe(oi~f9zOAV{s zoE^f#%rrDI)Xp(HMIT#?W=eRrXZiBw7t)vR+gF#G`jo}$e2UTI$B+4CEE4kb^Ru&e z*Z=>wV8McY`}SR5AFr*g-QC?ieaaM{1(hsJj&5#hCMF>l+S=OMR)??OwR2}=boBdM zTea=%>Iw=10&;AUt*ov0?%Bg)U*_rMHEY%^yQ(iMcJ7>c`e~ByqoSP&&-TooJ$ucX zH4m7tA33sQ-8#P6DRU0*-Me?=#*M$fz1_Td^X9EvZ7V(`L_|nTKI!A(5fBitAZX?L z`}^h7CtrATz@nq6$;rouN2-&}%F0ShOY6^{KR&*`=jYq^AM;OGuy*a)t5-ueOvyBv zwRGvz%ggExdZ>*-_1jvYMs@We#rj~_oWGcz|fHU6G*wXCi3RZo5C4w zFCwpBzrH?huas_#38=z;^oS|#`e$3`9Wi;{-rf!l2WFXOw|txYvc#(SpupWWK@TH| zp5^}YfBpCo5gl!9Z4Ej`tgx`qM(+K|$?60u+nbp*E=)^4} zv)Ok)oR@Du{BZN~ty{N(?^U{f<;s_Te}C7MAAhlF)v8km4lt~h$Z+rj9p2r1^K0@H z(-3Y>A5JDkMMaLLIaZ}!E4FrAhyYIwNx5&j`DVI){JQx4aZXN5wLPC$^0S?lD(WYjaxoVXDy% z5nPJ=U;n?m&vZk?nvRZ+(%08`r?NOs0Nt~@nft~YHgjt>@%vZ*ApVE633^!9#_ey}hAliVxy>F4GMuKLqF zapA&+;`(uK-oE|%?c2Fir?T?$_;`4>Y~Su)p7i)*#leFIw{6?j)z#J4*LU;gO^&85 z+qc*MdbyliTrUK4++WzX4I6gU{x*wH_;A+z{)G&a;NZ*3?tK|qS?A{2{=Ts>`N6fV z+1HmWT`I00SM%w~$(_Z|SFK(xZ&AQ-w_jaNE$#8K-dC?)ojP?YEiLWf!GkwM*_--Y z+}+(>T|2wG|9`z6|Mcn8605y?_x}C#^t6)P9n}>AjuSq7_z)=0n)~+FR%hSFX9X6V zoSfC)-bC)L`ug~Izp#){PHwKPt!;BtQ=340o@_G@N#zKo2FGc%2!e|dR%!5aOT9S(~xPScP7_jG#vxp}tH&d!fN zJUsj&U){#0=I*Z2tgI|8EiE%Mvxg5K-VkM9VSD4in#j#Py}hQUrW+?N=CrT;l=3AN zbgl2goP^CcFJ8Q8UG~Pn*qED__wRyc=a-EijT;$epXKA`Ha0i^{_R^|SC`bXZ8>*$ zm45m9?cd+u$_q|CEy};QhjX8UoL$Y2ySqWl*Y{U{UpH~0;I^qdD?cyWxN+m6MUS@S z-d?q8l>p1iHEZtdDt-Ou=Vwt7ktFaB6Z)|jqjg578 zfBx#~>H~k3-TN+Nm`F>{_P75lViULT=QHUK6%UJcCTwtab#)C5y?XbqYz@2Iv6aXB zlZIT_n^!& zJ$?7CEKkF?FJE$QZRvDdocr^+zpHEN!6w%FKOfm=pMCf8WnpRQ(u*0p%ik}%{BqT* zRiJ%-e|{LQkc*9t1)cBq>gsAyQPK4C^FUKalO_pWVLQmsfBg5S)B2evvznU^&$F%G zvSmx!*;$~Wjb>Z5fJ(mh%RkP~S4hmw%`GklZE6qs(cD=4{9Nxo9lyC&rXg;B|NcEc z&$hU{yu75u$J_g`-bx8A&YpIbG?7Nd_QUBStux=~G&)R}HZ3eLaN@LS@7}+6j}K#+ zdE)fx&$VpgQ+_6#ao;Ks0oryqckbM%s3>v0n1JwbcY!0PPoF+@s>??Wv@73HK&<=g zY5n~ZJXF*sO9~5rKFn{=!otGC!?UOQd)~V{J6DIV*VESa_V(7+(wb#ozi;c-uMZx8 z>fF4%y!iO}ixwp%CO*{P|L4)8M@jkl=aV*8Rac)reHwJBp1%J7Z*Ol$Z_k@Kb7t=S zeYUEqsrUEQCe+ulH46#|d^o8-zoo5h){GemYmc^l{``5S&$6zruI}#c9Xoa`UYuM| zP!Jm%TU)!gua7S*=!?Nruh8IN;n=tpD&0q!ikVvPsS0oi2?=RwX>oCJ6%`e&TD8hV zDmNh^;fK_r?~*Yqo;_4{4?Aul;};PT;qQO`&dy@}xIG-#p5))#bMxG}KCh)|si}=p zML$2KDoungrwIx9_viEZef#!p+O&z4TTDYsYudDFYO1PxtH1k&hhM*PMdZqaGiT16 zJLkvB+PY}bqWSgzZXP^%@X{rrJ6c*=Nt^xe{ZjlkWlsa zce#0ab)TM`ytlXd|Nd|9Y_wKe)j#;Lxp58uZjNOWn-(=HDc$DhJ#t6s#Ho)amo3Bc zrba|9m&$&1MRS?j?GTadBNx+Vt!b9p;oCJ~hs~O_j*i9#A+3xz-8tt!TOY4JS3K|V zrw;R-Iq#pZZ?Aq|UVZm;?Yrl7`@dIDo;>+@pKSJ$huPQGL~hHuX?)%Ww2xkS_Sd?r zd##*$uDI(>kB*42u(rN^^JZzS#^Udxsizh76{eqVE$(P-ZN2dFR`6ud;;x=AFEvA# zKXr4PTzc!$hx5md9Ruw%Tf25GBO{}sq2Zy<7cGOw7)X4hZ=0@woi?IhL2NUk|rvPf1O^dgTho^6BU8|JR(GV`-dz&d0|m zW@iy-!#ijP+@wj9_Evv?_Vj6LYO3V5ZI{1)`&RbQTw7D~Cb&OG~c}d;R83Ohkl6$*!{5E_&0g zEiGrxm{GEO+jnkWbp|7!s~0a$oG@X*)vUvZ58tnN%=>WS#;2#JpPy~+zdzE`)3c^# zPteLWt5)6GTmAjY%Ha6Qr&E_LTQ+IZq?N(Tqaq`pK6xTzSM%ff{Cd0ke|v&f=457O z=H%E^eR;8?@bQ|pYxQGyeK{tbe`db@{bR?L?cBL@<3>YG&69WU-aT|^(TWu>)^5KC zIyme9zu)#hpG?-@_v6s@>*a56ZIzUiykGO#H#zz7x3{;yUVZV!b@^pZ_bG0RL8W`t zT0ISoA0H0$Gcz$&eV*mEGv?nxcKH)2n>dBlN@o3A7VOwoe{Zt#l8qZb{`&g5?WR)Y-8>Z+-) zUtL}O|J(NcU&F6*b91+9cE5f5_G_uZoa^o@LyjFi+S=9z+7M-CW@c?2tv1=x%8JW; zo41#jmX=o7+NjXb(5cg>i%Usqr3gt#R6ID)`0UxU1q&7|TC`}+9GSl@+lAG9E@YTQ ztu6ca=ciP!n!0-W$45s$e*Cy}>C%G-4_eJV2hNr2cI>cFRb9GVB5w87u+Y%Vtx?j_ z(up0*HgDeSqqe*Bb=doQ&985-*3Y!9E(;8t_|LyEo=?_lOUA`TdB3lQYF+*F^Ye7w zXfZ*-iF4=b+ALUcF#|MEdPnl*wj<{EDjq+b9{;W^G+zHo)>fvD`Sa&LtW`Q}=@+7P z^?H20ZSJit;qkSmc6M<))XGXr?`}@_&(2<5&;mN1^ZWgJeGLtPXK$yUOxc`%{@=gf z?_a-uU0YM5r3JdvmQ|$jkpf%y0kYis=87>hu4+^sj#5nu7J6?8z` zsj1p=adA$oRK2I=+}!l^+1c62$NScKYVuX`yrbw*31Q)y4N17-U|8&IPFZ@!?@!zrfOgpO8c=1T5aBGYAbiKP95}Vx?NA9Wk`1SR5{n%Yg?AgNB$Nhb` z`@NifosE{(svSFatXg&I+_`t3&)Z+m+M0Z&NGvECEe&5{OeER99+1J;} zS{9{jkGxy>aM$hm)_G|)&HVO%HY{IPQC$3a`Mj#EpP!!A)zuyEm(S11dGpfgbcNs= z*-uQlxw(gwC;zHnt$06WVdIexhg00Y-#7zG(8|h-7cDw;|Ni~s$JMQ@tn~Es3=KDK z+O#RS|Mm6wdeAuA-~6C{%Wr477B+`h9F5(ssxkExr?6T?WTfv*BiEH7TnjTn_W|bb z-rcZOr@7>&< zKfklHbM4x-A4;}A6imv@%q;u8IBd1HmKIO{1VLrDh+#+7t{b#PxE5A#%U=6s zr{+{Ie}DglyMulNPB;k~lz)AFy}zfYq+wFa)~%)0)w_dMn#g?5&dtqDN&+?15)&`p zx|LPIXK1rGBrI&()~%u8;oP#o_^n&F z{AQVG>gxJRm<9v|ZAv>kYt9^*;NW0yZ|{Z5M?RRftX;b{Xr+v0(UPdO`|AGgdZ@pC z@7}#JdgUc0A*-*JmX_w`<}O{jl$V!x*|KGGV^rsaY>CEnSrSBTu^^oSU1QyZr5~tEMMU zOjK4@R*tWD$f~ce9~=zY^S@%nikFv{FJHQ}^zIB*jw{!$xw*QwwzWykJd*CAC3u+s zD%Zq=$w?w?duRYB$F?)Uqu#dqG{ z?fdu7pFSDONpt7Uoj6fYL?k6C>C%-eQ)bS*`PDR5YpR$1rt*?uPTUTFR=6fh~$3G5D4UHSS%iphFzi-v~;7$5mt%t5(H`mqGwY9ZX zS5JR+Wu?~CRU0=N+S=}YZOi(QLvYpJ>hJGjcb8RGR2(^Sq(|Pq?&2cXr%#{W4U4Xq zD2ZJizcfUvRc_CR4S$zJNBAwHWpuJb3W+wYA(_ zTt+f)F4X*9e1DQYM~P5IUf#9&lh2+x2LqHWVwvWkIR=XeLBc4f9B*#%ep^5b{0QZ^PROMKtoDO3e?$3JvGHo)WFd2;`WT& z+j4(@d;9t0$DhCN|IbTJ-CFVS(X3gs{BCpCuL{vR{NQYX^k2&(SFVIu#M=CPGCBL& znn10oR&&>F+ZMK?J!8g^6XmseZrdg%T;;d_qwwb*XDVlZNK0$$+SuJ;_3Qx=SMS_e zGhg8t_yUhB*RO+Hh&3NuKSWjhU4Q1}WOe^J7J{OpSH-_>->{+L!$J1br%v_BSQdSJ zbd*zAO+%z>)~s1emMlr1SGg>>^H;lFiPhco`L)yL%=uIQ|9k!WJ)ir+R@c7U`CLm| z+d5Z&@<|b{)_)sbZV8+5H7p_{H&^#gVASriw~PDjv?ib25|!)gd-lXc<<{fxt(U(2 zwLC`8e9w}PpFZ8%TU}mVU0quG_1D+erB-*_c%`poZH>{pem?oSsW9g>(CHJ?^zZ)UE&P=TFIdn=`VqF3BtYdi%4fL1Dq=mu=4lop{dgcSvUh-?8!F zz<~ps(?R`*cQ-dLU$@S$!u`v&wb9qtL?&A_?Ja&}_xtzx`hUevPEL-F2Pdg|D=8_t z^-7g~dvo*5nKO5HmrGX$tXj0lY4z1xw{KThRG65W{+;;nwb9Hocka|2Y+^m$C+qFu zQBYbs*QzutHa6DD>Chxq?`it+_ku4UK79D?+qe1m_DIUgzJ2;s^-d`tC#RvzqMO0D z?4s^nxUeDfvf5w$MP5szb`(4WEe_U;xiP!j{-KtQhK7c=HfWLf`FXZZ^?}jR(K$J9 zHlMegwv{ z<==n(s#>UMn_F}IY1Y=NdwVJ~Gc)hkeD0k)ckcG>+drtSovIzqH9g7p>4J+HT-@BP z3-=s7dUSXB`*}8%Mb}R(T>j*HO=WEC-DSSBTMU&C>3r!H(~a7e6IoGFk>59=I!@k5 zCW$F5EbQUKhy1o*0v#oCNJ3VdMw6n9#-QC=zELVRQY@Ipt=BcUL{4y2+ zVPRsDl9GagiK(eeFJ_!Nefs;Go5@Qqbaipf^?Uy4(W7V2!a_op%)fofLr8h`oVjxk zA3Ahyj-~RRXNNCe-n?gzjiREWn%c70yxGb>zx-YW+68qZ;_m|H;^NQh^J|K(t_p2z zY;1d&>i<>bp8fX^hxz~ic-;T-3eQ(G$-$l)ti3$`kKhe zQ>T_bJk)wzzP{$(p2}y>o~irK^YQn8FLn5}@%tAq1eD6c!><=UK9*@B^>=3Q{Q zkikov+FxHl6?Saw+ZQh)LPDm@nsw{#ffe_jtO;8Uy41@uX6@RwrB-))B#o_NPsmyp zEm^h7Ylqvfr_;^X5l z@;7|hlwszakij8vn7{XL#rtT*lAL2lkGi_M=ilC@YiRiK*xU1!+p8vE^U@$QS{`*Lg)4t`Bm5B>+gC@ z+80;)<3nPvoATt7IXO9L=jQyposCw{PFR z#csW?R%XYlP1cRvq@t>-s;>V0qPu))aq;iw>v3L7jjXJ8En1|csp+}no{^zpVL`!; z$G*L5qqnQ6sBm20eY{`(dWOmRz2BnhkAAS4n|FU-ZTk6nQ%|Opm6atXCSJUF@mIRG z%XC#vORZi_*}TJ^nVGr# z%?;4mmh-I3_4M@o^rl-|Tc4k0divnOgD3tddr#N1t^SsimG$aSD|c*c>{r9i9ab}D z%-HkwTC}OD>B*BPLHo6x78)2D78Vt4+PYPAdgA^iuU@>kv9oyjhZkE7ivG2V$9?$t zap!G8Ppzr1Cc4XU^73BIFqv(h@8|8kdgaQKXU^CZJU9^SZ+lhTceZu;yKirACnqI! zb#-maxv9j{FyFd--Na2HT30_kJzZQ}%r9p%WA5CyuU@U%Z=a_!bz*4I&OfWy@2mR# zcDt$6+1Km$uM1k~;|pp8@GQ?Xm=tqFYi-!?d)4p%{`q{~=`3h`ac}kay02HmYsC+5 z-@ZNn_BP)cwFgd~)HE^zWwW@rxbo_jjtm`70SP0fqQ4xfht>A}d^TIY?#IJMW_G#C zCxVBc*2q^eZB9S$=kLFM%^Hz;f8T9u%+1Yx`SK;`E|Tx>@4tWaXjA?Fx{JcA%4gTV z7r%Dx+OwxmIX55ST%TE3P_Sa%I=k9mCDGBh=U5i6S+hnjeqYVAGm^%}n_0QVUX<+8 z4qx}==~K@0PU7O?*RNi!tgha@d-wCFPyhaUy?(J3UPAP209*%Z!;b@0Q=MefRF2 zvRluM-R0}OmVWyF{rxY4ba!|6!otG9z=;O#7pG_j^RTb}zVGMvl+%5EeeLpf7Rt)X z3JMRdhR4sfEME3eZ@r{(+LPzcrQa{e%gprj_rJd>^>n}ezZcJ*mA$yI@Zw_k`;%|o z%T>F2^=f5h<)PF0?!8i`iHBIMt#{8h&tJBD`S$JGLAQyVIrHYyQtzERcOJ^F*bd#6vI-rnx+=;&Bi zw{P*{#RmKDo}8?%t*x!@H%DVn(~7NIx2{<6;?vX9YuBz76BAqP-d|Q;9 zW&i&Di=A(O=FFKtZ@1s)kzRfNY{5d4`?F`yK79CaadB~Tb8~$4+pP;0C@8D5&-8ir z@?~UjaB@msV&*DeP3Eu%`+mO@p4V<3bokgYw_dl;C)MYJmZP6O{rbhl#mD-slq3Hh z1ReV;t{1an<;p+}5j{P|a zjJ&*e4Ib~vQE^k?MUy))U=)YP{4nNMcs%Nd5r zfByVgvR_nbPj>FXCRSBdRet+F1tldV0Ra;p?s&1z`oy(sVHI-wUTgiG^y}BJ;N^a~ zH#R6LD<8go-CR|5Y5y;w605tQj(FUji0J6mAzHDqv7n1(GBYFN;^s}9n3$a{Eh3VV zm-p|q{{EO+5`X{msnCxR7D;_3KwfMa6I5zDe~yJJu^5yv(PtynOxY)z-DYN`ixfGcr~boZk+) z{J@DHbU@th-Md$>e*J#`|8*BLM7WO5u`IS~-Mw??PFGjg#qRxl92^q zH@AI1pUpNjG>o0?#&iE_N`>ypQ>Rv~UCYbOy*v5%%COaEPoMt%X7l-FzO%2zU+(8$ zUwhent!>qp7t`bGe%>iQe|E0*cJu2FkOT04z5LZ1;t{ONFCVTUVw`?% zPqM6)mDQz7m$v2J23<@$?_OuYai1Ft?z5J?xiN9lq)(T;^?&~S`86%3#LKH|=gyt~ zauwWO-M@El-kdpmYJYzd)ee)`_vx&MP#CX6OE51$tmTAqWJ!NlatzDa&e{Y*XjZcOqQ!H!G@eelq_d|PBkFlJ|ukXn{ zxT{h3!u9L6GK$RA|L^ZCJK|SvmejpZ zdSicmy_Z+lMc)X^8rCgQxk*V$QBk)(s4jTw#u^nJEi5eTKi@95WVPasNzWg)Kk(bT zTJ7)G_4S}>yxQ8@`n@Nfugf}p>=O5$Kc7xlR#rx>4g0l7voL^TO~l4U&%UJxT$$$O zrT^i}W&h}ih$&O2dd8cm@^LkST9to(eEj+IXY-!Y}@K@8g$4xSaGy)y@b|U)JC%_H zLDB{5SvnrRpQ`c`Sv5%F!geMb{`=eaG253*OG~q}v+s@)J_qXeTYuBz_ytpyG zYuN=y#f0?qRUg9yT|_> z{F8!2xmuf>n|piDDy)2OyIRfgkL_ZaC6a$1%l}`oe!aP|vGkI!%Wu`{Zpgg6Y}vA9 z`}A7>u&+Px?d|Q#jYl8ctrfcRXLkO+K&`1lA})f>AqnsA?Tu;Sxm2s}xYgIkXVRoe zGs+{GUO7g!M6LDn@=|J(U$VPDt6TiTw{K$eXG}TlaNzjybcrpK)VjoH*wya(ab$@M z8`Hmk{|+yhY7)4|At7M_Naz(4SF4hRMa7EklfHF|8yFf&&U5ErRyZnevcv_E-oPve zFUF(_&8?c;sA-Xb@gvib50Bn@bbiLM?L one slot pulse", + "U<->E bit shift", + "E<->G Frame", + "A<->B Slot 1", + "B<->C ...", + "C<->D Slot n", + "T-N", + "A-E", + "K-B", + "C-I", + "D-M", + "D-G", + "L-F" + ] +} diff --git a/docs/_static/diagrams/i2s/tdm_pcm_long.png b/docs/_static/diagrams/i2s/tdm_pcm_long.png deleted file mode 100644 index 3e2416f3d848c7364a912728495a928c083da0e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 63728 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 pulse", + "E<->G Frame", + "U<->A bit shift", + "A<->B Slot 1", + "B<->C ...", + "C<->D Slot n", + "T-U", + "A-E", + "K-B", + "C-I", + "D-M", + "D-G" + ] +} diff --git a/docs/_static/diagrams/i2s/tdm_pcm_short.png b/docs/_static/diagrams/i2s/tdm_pcm_short.png deleted file mode 100644 index c1c46ff4a635352a4a7d8b38f5912048f4b6997e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 71424 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 JS?83{1OS#ZWP<F Left Slots", + "F<->G Right Slots", + "U<->A bit shift", + "A<->B Slot 1", + "B<->C Slot 2", + "C<->D ...", + "D<->J Slot n", + "J<->L Slot n+1", + "L<->S ...", + "A-E", + "K-B", + "C-I", + "D-F", + "J-N", + "L-P", + "Q-G", + "S-R", + "T-U" + ] +} diff --git a/docs/_static/diagrams/i2s/tdm_philip.png b/docs/_static/diagrams/i2s/tdm_philip.png deleted file mode 100644 index 4556703f7f395ac3a9254ea90a081a4bc2b35a07..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 80203 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�^LVVkXGl;m?6>V;NY*8nVGpg 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 diff --git a/docs/doxygen/Doxyfile b/docs/doxygen/Doxyfile index 34b7ba0609..e781826428 100644 --- a/docs/doxygen/Doxyfile +++ b/docs/doxygen/Doxyfile @@ -67,7 +67,6 @@ INPUT = \ $(PROJECT_PATH)/components/driver/include/driver/gpio.h \ $(PROJECT_PATH)/components/driver/include/driver/gptimer.h \ $(PROJECT_PATH)/components/driver/include/driver/i2c.h \ - $(PROJECT_PATH)/components/driver/include/driver/i2s.h \ $(PROJECT_PATH)/components/driver/include/driver/ledc.h \ $(PROJECT_PATH)/components/driver/include/driver/rtc_io.h \ $(PROJECT_PATH)/components/driver/include/driver/sdio_slave.h \ @@ -156,14 +155,8 @@ INPUT = \ $(PROJECT_PATH)/components/hal/include/hal/esp_flash_err.h \ $(PROJECT_PATH)/components/hal/include/hal/gpio_types.h \ $(PROJECT_PATH)/components/hal/include/hal/i2c_types.h \ - $(PROJECT_PATH)/components/hal/include/hal/i2s_types.h \ $(PROJECT_PATH)/components/hal/include/hal/lcd_types.h \ - $(PROJECT_PATH)/components/driver/include/driver/i2s_common.h \ - $(PROJECT_PATH)/components/driver/include/driver/i2s_std.h \ - $(PROJECT_PATH)/components/driver/include/driver/i2s_pdm.h \ - $(PROJECT_PATH)/components/driver/include/driver/i2s_tdm.h \ $(PROJECT_PATH)/components/hal/include/hal/ledc_types.h \ - $(PROJECT_PATH)/components/hal/include/hal/rmt_types.h \ $(PROJECT_PATH)/components/hal/include/hal/rtc_io_types.h \ $(PROJECT_PATH)/components/hal/include/hal/sdio_slave_types.h \ $(PROJECT_PATH)/components/hal/include/hal/sigmadelta_types.h \ diff --git a/docs/doxygen/Doxyfile_esp32 b/docs/doxygen/Doxyfile_esp32 index c35a4e2ef9..bdf8686905 100644 --- a/docs/doxygen/Doxyfile_esp32 +++ b/docs/doxygen/Doxyfile_esp32 @@ -1,6 +1,10 @@ INPUT += \ $(PROJECT_PATH)/components/driver/$(IDF_TARGET)/include/driver/dac.h \ $(PROJECT_PATH)/components/driver/$(IDF_TARGET)/include/driver/touch_sensor.h \ + $(PROJECT_PATH)/components/driver/include/driver/i2s_common.h \ + $(PROJECT_PATH)/components/driver/include/driver/i2s_pdm.h \ + $(PROJECT_PATH)/components/driver/include/driver/i2s_std.h \ + $(PROJECT_PATH)/components/driver/include/driver/i2s_types.h \ $(PROJECT_PATH)/components/driver/include/driver/mcpwm.h \ $(PROJECT_PATH)/components/driver/include/driver/pulse_cnt.h \ $(PROJECT_PATH)/components/driver/include/driver/rmt_common.h \ @@ -11,6 +15,7 @@ INPUT += \ $(PROJECT_PATH)/components/esp_hw_support/include/esp_himem.h \ $(PROJECT_PATH)/components/esp_system/include/esp_ipc.h \ $(PROJECT_PATH)/components/esp_system/include/esp_ipc_isr.h \ + $(PROJECT_PATH)/components/hal/include/hal/i2s_types.h \ $(PROJECT_PATH)/components/hal/include/hal/mcpwm_types.h \ $(PROJECT_PATH)/components/hal/include/hal/pcnt_types.h \ $(PROJECT_PATH)/components/hal/include/hal/rmt_types.h \ diff --git a/docs/doxygen/Doxyfile_esp32c3 b/docs/doxygen/Doxyfile_esp32c3 index 80aee38fa0..bc8bb51bcf 100644 --- a/docs/doxygen/Doxyfile_esp32c3 +++ b/docs/doxygen/Doxyfile_esp32c3 @@ -1,4 +1,9 @@ INPUT += \ + $(PROJECT_PATH)/components/driver/include/driver/i2s_common.h \ + $(PROJECT_PATH)/components/driver/include/driver/i2s_pdm.h \ + $(PROJECT_PATH)/components/driver/include/driver/i2s_std.h \ + $(PROJECT_PATH)/components/driver/include/driver/i2s_tdm.h \ + $(PROJECT_PATH)/components/driver/include/driver/i2s_types.h \ $(PROJECT_PATH)/components/driver/include/driver/rmt_common.h \ $(PROJECT_PATH)/components/driver/include/driver/rmt_encoder.h \ $(PROJECT_PATH)/components/driver/include/driver/rmt_rx.h \ @@ -7,4 +12,5 @@ INPUT += \ $(PROJECT_PATH)/components/driver/include/driver/temperature_sensor.h \ $(PROJECT_PATH)/components/esp_hw_support/include/soc/esp32c3/esp_ds.h \ $(PROJECT_PATH)/components/esp_hw_support/include/soc/esp32c3/esp_hmac.h \ + $(PROJECT_PATH)/components/hal/include/hal/i2s_types.h \ $(PROJECT_PATH)/components/hal/include/hal/rmt_types.h \ diff --git a/docs/doxygen/Doxyfile_esp32h2 b/docs/doxygen/Doxyfile_esp32h2 index c26f3191cf..ef8cb8a37c 100644 --- a/docs/doxygen/Doxyfile_esp32h2 +++ b/docs/doxygen/Doxyfile_esp32h2 @@ -1,4 +1,8 @@ INPUT += \ + $(PROJECT_PATH)/components/driver/include/driver/i2s_common.h \ + $(PROJECT_PATH)/components/driver/include/driver/i2s_pdm.h \ + $(PROJECT_PATH)/components/driver/include/driver/i2s_std.h \ + $(PROJECT_PATH)/components/driver/include/driver/i2s_types.h \ $(PROJECT_PATH)/components/driver/include/driver/rmt_common.h \ $(PROJECT_PATH)/components/driver/include/driver/rmt_encoder.h \ $(PROJECT_PATH)/components/driver/include/driver/rmt_rx.h \ @@ -7,4 +11,5 @@ INPUT += \ $(PROJECT_PATH)/components/driver/include/driver/temperature_sensor.h \ $(PROJECT_PATH)/components/esp_hw_support/include/soc/esp32h2/esp_ds.h \ $(PROJECT_PATH)/components/esp_hw_support/include/soc/esp32h2/esp_hmac.h \ + $(PROJECT_PATH)/components/hal/include/hal/i2s_types.h \ $(PROJECT_PATH)/components/hal/include/hal/rmt_types.h \ diff --git a/docs/doxygen/Doxyfile_esp32s2 b/docs/doxygen/Doxyfile_esp32s2 index f58d4c87ce..f74884ca20 100644 --- a/docs/doxygen/Doxyfile_esp32s2 +++ b/docs/doxygen/Doxyfile_esp32s2 @@ -2,6 +2,9 @@ INPUT += \ $(PROJECT_PATH)/components/driver/$(IDF_TARGET)/include/driver/dac.h \ $(PROJECT_PATH)/components/driver/$(IDF_TARGET)/include/driver/touch_sensor.h \ $(PROJECT_PATH)/components/driver/include/driver/pulse_cnt.h \ + $(PROJECT_PATH)/components/driver/include/driver/i2s_common.h \ + $(PROJECT_PATH)/components/driver/include/driver/i2s_std.h \ + $(PROJECT_PATH)/components/driver/include/driver/i2s_types.h \ $(PROJECT_PATH)/components/driver/include/driver/rmt_common.h \ $(PROJECT_PATH)/components/driver/include/driver/rmt_encoder.h \ $(PROJECT_PATH)/components/driver/include/driver/rmt_rx.h \ @@ -10,6 +13,7 @@ INPUT += \ $(PROJECT_PATH)/components/driver/include/driver/temperature_sensor.h \ $(PROJECT_PATH)/components/esp_hw_support/include/soc/esp32s2/esp_ds.h \ $(PROJECT_PATH)/components/esp_hw_support/include/soc/esp32s2/esp_hmac.h \ + $(PROJECT_PATH)/components/hal/include/hal/i2s_types.h \ $(PROJECT_PATH)/components/hal/include/hal/pcnt_types.h \ $(PROJECT_PATH)/components/hal/include/hal/rmt_types.h \ $(PROJECT_PATH)/components/soc/$(IDF_TARGET)/include/soc/dac_channel.h \ diff --git a/docs/doxygen/Doxyfile_esp32s3 b/docs/doxygen/Doxyfile_esp32s3 index 4ee673dcb5..7b9a67d7aa 100644 --- a/docs/doxygen/Doxyfile_esp32s3 +++ b/docs/doxygen/Doxyfile_esp32s3 @@ -1,5 +1,10 @@ INPUT += \ $(PROJECT_PATH)/components/driver/$(IDF_TARGET)/include/driver/touch_sensor.h \ + $(PROJECT_PATH)/components/driver/include/driver/i2s_common.h \ + $(PROJECT_PATH)/components/driver/include/driver/i2s_pdm.h \ + $(PROJECT_PATH)/components/driver/include/driver/i2s_std.h \ + $(PROJECT_PATH)/components/driver/include/driver/i2s_tdm.h \ + $(PROJECT_PATH)/components/driver/include/driver/i2s_types.h \ $(PROJECT_PATH)/components/driver/include/driver/mcpwm.h \ $(PROJECT_PATH)/components/driver/include/driver/pulse_cnt.h \ $(PROJECT_PATH)/components/driver/include/driver/rmt_common.h \ @@ -12,6 +17,7 @@ INPUT += \ $(PROJECT_PATH)/components/esp_hw_support/include/soc/$(IDF_TARGET)/esp_hmac.h \ $(PROJECT_PATH)/components/esp_system/include/esp_ipc.h \ $(PROJECT_PATH)/components/esp_system/include/esp_ipc_isr.h \ + $(PROJECT_PATH)/components/hal/include/hal/i2s_types.h \ $(PROJECT_PATH)/components/hal/include/hal/mcpwm_types.h \ $(PROJECT_PATH)/components/hal/include/hal/pcnt_types.h \ $(PROJECT_PATH)/components/hal/include/hal/rmt_types.h \ diff --git a/docs/en/api-reference/peripherals/i2s.rst b/docs/en/api-reference/peripherals/i2s.rst index d432802ca7..975a7dcf5d 100644 --- a/docs/en/api-reference/peripherals/i2s.rst +++ b/docs/en/api-reference/peripherals/i2s.rst @@ -10,14 +10,21 @@ I2S (Inter-IC Sound) is a serial, synchronous communication protocol that is usu {IDF_TARGET_NAME} contains {IDF_TARGET_I2S_NUM} I2S peripheral(s). These peripherals can be configured to input and output sample data via the I2S driver. -An I2S bus consists of the following lines: +An I2S bus that communicate in Standard or TDM mode consists of the following lines: -- MCLK: Master clock line. It's an optional signal depends on slave side, mainly for offering a reference clock to the I2S slave device. -- BCLK: Bit clock line. The bit clock for data line in common I2S applications. -- WS: Word(Slot) select line. It is usually used to identify the vocal tract except PDM mode. -- DIN/DOUT: Serial data input/output line. +- **MCLK:** Master clock line. It's an optional signal depends on slave side, mainly used for offering a reference clock to the I2S slave device. +- **BCLK:** Bit clock line. The bit clock for data line. +- **WS:** Word(Slot) select line. It is usually used to identify the vocal tract except PDM mode. +- **DIN/DOUT:** Serial data input/output line. (Data will loopback internally if din and dout are set to a same GPIO) -Each I2S controller has the following features that can be configured using the I2S driver: +.. only:: SOC_I2S_SUPPORTS_PDM_TX or SOC_I2S_SUPPORTS_PDM_RX + + And for the I2S bus that communicate in PDM mode, the lines are: + + - **CLK:** PDM clock line. + - **DIN/DOUT:** Serial data input/output line. + +Each I2S controller has the following features that can be configured by the I2S driver: - Operation as system master or slave - Capable of acting as transmitter or receiver @@ -29,7 +36,66 @@ Each I2S controller has the following features that can be configured using the .. only:: SOC_I2S_HW_VERSION_2 - Each controller has separate rx and tx channel. That means they are able to work under different clock and slot configurations with separate GPIO pins. Note that although their internal MCLK are separate, but the output MCLK signal can only be attached to one channel, we can't output two different MCLK at the same time. + Each controller has separate rx and tx channel. That means they are able to work under different clock and slot configurations with separate GPIO pins. Note that although the internal MCLK of tx channel and rx channel are separate on a controller, the output MCLK signal can only be attached to one channel. If two different MCLK ouput is required, they must be allocated on different I2S controller. + +I2S File Structure +------------------ + +.. figure:: ../../../_static/diagrams/i2s/i2s_file_structure.png + :align: center + :alt: I2S file structure + +**Public headers that need to be included in the I2S application** + +- ``i2s.h``: The header file of legacy I2S APIs (for apps using legacy driver). +- ``i2s_std.h``: The header file that provides standard communication mode specific APIs (for apps using new driver with standard mode). +- ``i2s_pdm.h``: The header file that provides PDM communication mode specific APIs (for apps using new driver with PDM mode). +- ``i2s_tdm.h``: The header file that provides TDM communication mode specific APIs (for apps using new driver with TDM mode). + +.. note:: + + The legacy driver can't coexist with the new driver. Including ``i2s.h`` to use the legacy driver or the other three headers to use the new driver. The legacy driver might be removed in future. + +**Public headers that have been included in the headers above** + +- ``i2s_types_legacy.h``: The legacy public types that only used in the legacy driver. +- ``i2s_types.h``: The header file that provides public types. +- ``i2s_common.h``: The header file that provides common APIs for all communication modes. + +I2S Clock +--------- + +Clock Source +^^^^^^^^^^^^ + +- :cpp:enumerator:`i2s_clock_src_t::I2S_CLK_SRC_DEFAULT`: Default PLL clock. + +.. only:: not esp32h2 + + - :cpp:enumerator:`i2s_clock_src_t::I2S_CLK_SRC_PLL_160M`: 160 MHz PLL clock. + +.. only:: esp32h2 + + - :cpp:enumerator:`i2s_clock_src_t::I2S_CLK_SRC_PLL_96M`: 96 MHz PLL clock. + +.. only:: SOC_I2S_SUPPORTS_APLL + + - :cpp:enumerator:`i2s_clock_src_t::I2S_CLK_SRC_APLL`: Audio PLL clock, more precise than ``I2S_CLK_SRC_PLL_160M`` in high sample rate applications. Its frequency is configurable according to the sample rate, but if APLL has been occupied by emac or other channels already, the APLL frequency is not allowed to change, the driver will try to work under this APLL frequency, if this APLL frequency can't meet the requirements of I2S, the clock configuration will fail. + +Clock Terminology +^^^^^^^^^^^^^^^^^ + +- **sample rate**: The number of sampled data in one second per slot. +- **sclk**: Source clock frequency. It is the frequency of the clock source. +- **mclk**: Master clock frequency. ``bclk`` is generate from this clock, ``mclk`` is mostly needed in the case that requires the MCLK signal as a reference clock to synchronize BCLK and WS between I2S master role and slave role. +- **bclk**: Bit clock frequency. Every tick of this clock stands for one data bit on data pin. It means there will be 8/16/24/32 ``bclk`` ticks in one slot, because the number of ``bclk`` ticks in one slot is equal to the :cpp:member:`i2s_std_slot_config_t::slot_bit_width`. +- **lrck** / **ws**: Left/Right clock or word select clock. For non-PDM mode, its frequency is equal to the sample rate. + +.. note:: + + Normally ``mclk`` should be the multiple of ``sample rate`` and ``bclk`` at the same time. This field :cpp:member:`i2s_std_clk_config_t::mclk_multiple` means the multiple of ``mclk`` to the ``sample rate``. If ``slot_bit_width`` is set to ``I2S_SLOT_BIT_WIDTH_24BIT``, to keep ``mclk`` a multiple to the ``bclk``, :cpp:member:`i2s_std_clk_config_t::mclk_multiple` should be set to ``I2S_MCLK_MULTIPLE_384``, otherwise the ``ws`` will be inaccurate. But in the most other cases, ``I2S_MCLK_MULTIPLE_256`` should be enough. + +.. _i2s-communication-mode: I2S Communication Mode ---------------------- @@ -38,36 +104,30 @@ Overview of All Modes ^^^^^^^^^^^^^^^^^^^^^ ========= ======== ======== ======== ======== ======== ========== -Platform Standard PDM TX PDM RX TDM ADC/DAC LCD/Camera + Target Standard PDM TX PDM RX TDM ADC/DAC LCD/Camera ========= ======== ======== ======== ======== ======== ========== -ESP32 port 0/1 port 0 port 0 none port 0 port 0 -ESP32S2 port 0 none none none none port 0 -ESP32C3 port 0 port 0 none port0 none none -ESP32S3 port 0/1 port 0 port 0 port 0/1 none none +ESP32 I2S 0/1 I2S 0 I2S 0 none I2S 0 I2S 0 +ESP32S2 I2S 0 none none none none I2S 0 +ESP32C3 I2S 0 I2S 0 none I2S0 none none +ESP32S3 I2S 0/1 I2S 0 I2S 0 I2S 0/1 none none ========= ======== ======== ======== ======== ======== ========== Standard Mode ^^^^^^^^^^^^^ -Standard mode always has left and right two sound channels which we called 'slots'. These slots can support 8/16/24/32 bits width sample data. And the communication format for the slots mainly includes the following formats: +Standard mode always has left and right two sound channels which are called 'slots'. These slots can support 8/16/24/32 bits width sample data. And the communication format for the slots mainly includes these following formats: - **Philip Format**: Data signal have one bit shift comparing to the WS(word select) signal. And the duty of WS signal is 50%. -.. figure:: ../../../_static/diagrams/i2s/std_philip.png - :align: center - :alt: Standard Philip Format +.. wavedrom:: /../_static/diagrams/i2s/std_philip.json - **MSB Format**: Almost same as philip format, but its data have no shift. -.. figure:: ../../../_static/diagrams/i2s/std_msb.png - :align: center - :alt: Standard MSB Format +.. wavedrom:: /../_static/diagrams/i2s/std_msb.json - **PCM Short Format**: Data have one bit shift and meanwhile WS signal becomes a pulse lasting one BCLK(Bit Clock) cycle. -.. figure:: ../../../_static/diagrams/i2s/std_pcm.png - :align: center - :alt: Standard PCM (Short Sync) Format +.. wavedrom:: /../_static/diagrams/i2s/std_pcm.json .. only:: SOC_I2S_SUPPORTS_PDM_TX @@ -75,26 +135,24 @@ Standard mode always has left and right two sound channels which we called 'slot PDM Mode (TX) ^^^^^^^^^^^^^ - PDM mode for tx channel can transfer PCM data into PDM format which always has left and right slots. PDM TX can only support 16 bits width sample data. PDM TX only need WS pin for clock signal and DOUT pin for data signal. This mode allows user to configure the up-sampling parameters :cpp:member:`i2s_pdm_tx_clk_config_t::up_sample_fp` :cpp:member:`i2s_pdm_tx_clk_config_t::up_sample_fs`. The up-sampling rate can be calculated by``up_sample_rate = fp / fs``, there are up-sampling modes in PDM TX: + PDM mode for tx channel can convert PCM data into PDM format which always has left and right slots. PDM TX can only support 16 bits width sample data. PDM TX only needs CLK pin for clock signal and DOUT pin for data signal (i.e. WS and SD signal in the following figure, the BCK signal is an internal bit sampling clock, not needed between PDM devices). This mode allows user to configure the up-sampling parameters :cpp:member:`i2s_pdm_tx_clk_config_t::up_sample_fp` :cpp:member:`i2s_pdm_tx_clk_config_t::up_sample_fs`. The up-sampling rate can be calculated by ``up_sample_rate = fp / fs``, there are up-sampling modes in PDM TX: + + - **Fixed Clock Frequency**: In this mode the up-sampling rate will change according to the sample rate. Setting ``fp = 960`` and ``fs = sample_rate / 100``, then the clock frequency(Fpdm) on CLK pin will be fixed to 128 * 48 KHz = 6.144 MHz, note that this frequency is not equal to the sample rate(Fpcm). + - **Fixed Up-sampling Rate**: In this mode the up-sampling rate is fixed to 2. Setting ``fp = 960`` and ``fs = 480``, then the clock frequency(Fpdm) on CLK pin will be ``128 * sample_rate`` + + .. wavedrom:: /../_static/diagrams/i2s/pdm.json - - **Fixed Clock Frequency**: In this mode the up-sampling rate will change according to the sample rate. We need to set ``fp = 960`` and ``fs = sample_rate / 100``, then the clock frequency(Fpdm) on WS pin will be fixed to 128 * 48 KHz = 6.144 MHz, note that this frequency is not equal to the sample rate(Fpcm). - - **Fixed Up-sampling Rate**: In this mode the up-sampling rate is fixed to 2. We need to set ``fp = 960`` and ``fs = 480``, then the clock frequency(Fpdm) on WS pin will be ``128 * sample_rate`` .. only:: SOC_I2S_SUPPORTS_PDM_RX PDM Mode (RX) ^^^^^^^^^^^^^ - PDM mode for rx channel can receive PDM format data and transfer the data into PCM format. PDM RX can only support 16 bits width sample data. PDM RX only need WS pin for clock signal and DIN pin for data signal. This mode allows user to configure the down-sampling parameter :cpp:member:`i2s_pdm_rx_slot_config_t::dn_sample_mode`, there are two down-sampling modes in PDM RX: + PDM mode for rx channel can receive PDM format data and convert the data into PCM format. PDM RX can only support 16 bits width sample data. PDM RX only need WS pin for clock signal and DIN pin for data signal. This mode allows user to configure the down-sampling parameter :cpp:member:`i2s_pdm_rx_clk_config_t::dn_sample_mode`, there are two down-sampling modes in PDM RX: - - :cpp:member:`i2s_pdm_dsr_t::I2S_PDM_DSR_8S`: In this mode, the clock frequency(Fpdm) on WS pin will be sample_rate(Fpcm) * 64. - - :cpp:member:`i2s_pdm_dsr_t::I2S_PDM_DSR_16S`: In this mode, the clock frequency(Fpdm) on WS pin will be sample_rate(Fpcm) * 128. + - :cpp:enumerator:`i2s_pdm_dsr_t::I2S_PDM_DSR_8S`: In this mode, the clock frequency(Fpdm) on WS pin will be sample_rate(Fpcm) * 64. + - :cpp:enumerator:`i2s_pdm_dsr_t::I2S_PDM_DSR_16S`: In this mode, the clock frequency(Fpdm) on WS pin will be sample_rate(Fpcm) * 128. -.. only:: SOC_I2S_SUPPORTS_PDM_TX or SOC_I2S_SUPPORTS_PDM_RX - - .. figure:: ../../../_static/diagrams/i2s/pdm.png - :align: center - :alt: PDM Format .. only:: SOC_I2S_SUPPORTS_TDM @@ -105,66 +163,33 @@ Standard mode always has left and right two sound channels which we called 'slot - **Philip Format**: Data signal have one bit shift comparing to the WS(word select) signal. And no matter how many slots are contained in one frame, the duty of WS signal will always keep 50%. - .. figure:: ../../../_static/diagrams/i2s/tdm_philip.png - :align: center - :alt: TDM Philip Format + .. wavedrom:: /../_static/diagrams/i2s/tdm_philip.json - **MSB Format**: Almost same as philip format, but its data have no shift. - .. figure:: ../../../_static/diagrams/i2s/tdm_msb.png - :align: center - :alt: TDM MSB Format + .. wavedrom:: /../_static/diagrams/i2s/tdm_msb.json - **PCM Short Format**: Data have one bit shift and meanwhile WS signal becomes a pulse lasting one BCLK(Bit Clock) cycle for every frame. - .. figure:: ../../../_static/diagrams/i2s/tdm_pcm_short.png - :align: center - :alt: TDM PCM (Short Sync) Format + .. wavedrom:: /../_static/diagrams/i2s/tdm_pcm_short.json - **PCM Long Format**: Data have one bit shift and meanwhile WS signal will lasting one slot bit width for every frame. For example, if there are 4 slots enabled, then the duty of WS will be 25%, and if there are 5 slots, it will be 20%. - .. figure:: ../../../_static/diagrams/i2s/tdm_pcm_long.png - :align: center - :alt: TDM PCM (Long Sync) Format + .. wavedrom:: /../_static/diagrams/i2s/tdm_pcm_long.json .. only:: SOC_I2S_SUPPORTS_LDC_CAMERA LCD/Camera Mode ^^^^^^^^^^^^^^^ - LCD/Camera mode are only supported on I2S0 over a parallel bus. For LCD mode, I2S0 should working at master tx mode. For camera mode, I2S0 should working at slave rx mode. These two modes won't be implemented in I2S driver, please refer to :doc:`/api-reference/peripherals/lcd` for LCD implementation. For more information, see *{IDF_TARGET_NAME} Technical Reference Manual* > *I2S Controller (I2S)* > LCD Mode [`PDF <{IDF_TARGET_TRM_EN_URL}#camlcdctrl>`__]. + LCD/Camera mode are only supported on I2S0 over a parallel bus. For LCD mode, I2S0 should working at master tx mode. For camera mode, I2S0 should working at slave rx mode. These two modes are not implemented by I2S driver, please refer to :doc:`/api-reference/peripherals/lcd` for LCD implementation. For more information, see *{IDF_TARGET_NAME} Technical Reference Manual* > *I2S Controller (I2S)* > LCD Mode [`PDF <{IDF_TARGET_TRM_EN_URL}#camlcdctrl>`__]. .. only:: SOC_I2S_SUPPORTS_ADC_DAC ADC/DAC Mode ^^^^^^^^^^^^ - ADC/DAC mode only exist on ESP32 and are only supported on I2S0. Actually, they are two sub-modes of LCD/Camera mode. I2S0 can be routed directly to the internal analog-to-digital converter(ADC) or digital-to-analog converter(DAC). In other words, ADC/DAC peripherals can read/write continuously via I2S0 DMA. As they are not an actual communication mode, I2S driver will no longer implement them, for the full support of ADC/DAC, please refer to ADC(:doc:`/api-reference/peripherals/adc`) or DAC(:doc:`/api-reference/peripherals/dac`) driver for implementation. - -I2S Clock ---------- - -Clock Source -^^^^^^^^^^^^ - -- :cpp:member:`i2s_clock_src_t::I2S_CLK_PLL_160M`: 160 MHz PLL clock. - -.. only:: SOC_I2S_SUPPORTS_APLL - - - :cpp:member:`i2s_clock_src_t::I2S_CLK_APLL`: Audio PLL clock, more precise than ``I2S_CLK_PLL_160M`` in high sample rate applications. Its frequency is configurable according to the sample rate, but if APLL has been occupied by emac or other channels already, the APLL frequency is not allowed to change, the driver will try to work under this APLL frequency, if this APLL frequency can't meet the requirements of I2S, the clock configuration will fail. - -Clock Concepts -^^^^^^^^^^^^^^ - -- **sample rate**: The number of sampled data in one second per slot. -- **sclk**: Source clock frequency. It is the frequency of the clock source. -- **mclk**: Master clock frequency. ``bclk`` is generate from this clock, in some cases, we need to output MCLK signal as a reference clock to synchronize BCLK and WS between I2S master role and slave role. -- **bclk**: Bit clock frequency. Every tick of this clock stands for one data bit on data pin. It means there will be 8/16/24/32 ``bclk`` ticks in one slot, because the number of ``bclk`` ticks in one slot is equal to the :cpp:member:`slot_bit_width` we set. -- **lrck** / **ws**: Left/Right clock or word select clock. For non-PDM mode, its frequency is equal to the sample rate. - -.. note:: - - Normally ``mclk`` should be the multiple of ``sample rate`` and ``bclk`` at the same time. This field :cpp:member:`i2s_std_clk_config_t::mclk_multiple` means the multiple of ``mclk`` to the ``sample rate``. If ``slot_bit_width`` is set to ``I2S_SLOT_BIT_WIDTH_24BIT``, to keep ``mclk`` a multiple to the ``bclk``, we need to set the :cpp:member:`i2s_std_clk_config_t::mclk_multiple` to ``I2S_MCLK_MULTIPLE_384``, otherwise the ``ws`` will be inaccurate. But in the most cases, ``I2S_MCLK_MULTIPLE_256`` should be enough. + ADC and DAC modes only exist on ESP32 and are only supported on I2S0. Actually, they are two sub-modes of LCD/Camera mode. I2S0 can be routed directly to the internal analog-to-digital converter(ADC) and digital-to-analog converter(DAC). In other words, ADC and DAC peripherals can read or write continuously via I2S0 DMA. As they are not an actual communication mode, the I2S driver does not implement them. Functional Overview ------------------- @@ -180,38 +205,42 @@ There are three levels' resources in I2S driver: - ``controller level``: Resources in one I2S controller. - ``channel level``: Resources of tx or rx channel in one I2S controller. -The public APIs are all channel level APIs, the channel handle :cpp:type:`i2s_chan_handle_t` can help user to manage the resources under a specific channel without considering the other two levels. The other two upper levels' resources are private and will be managed by the driver automatically. Users can call :cpp:func:`i2s_new_channel` to apply a channel handle and call :cpp:func:`i2s_del_channel` to delete it. +The public APIs are all channel level APIs, the channel handle :cpp:type:`i2s_chan_handle_t` can help user to manage the resources under a specific channel without considering the other two levels. The other two upper levels' resources are private and will be managed by the driver automatically. Users can call :cpp:func:`i2s_new_channel` to allocate a channel handle and call :cpp:func:`i2s_del_channel` to delete it. Power Management ^^^^^^^^^^^^^^^^ -When power management is enabled (i.e. :ref:`CONFIG_PM_ENABLE` is on), the system will adjust or stop the source clock of I2S before going into light sleep, thus potentially changing the I2S signals and leading to transmitting or receiving invalid data. +When the power management is enabled (i.e. :ref:`CONFIG_PM_ENABLE` is on), the system will adjust or stop the source clock of I2S before going into light sleep, thus potentially changing the I2S signals and leading to transmitting or receiving invalid data. -I2S driver can prevent the system from changing or stopping the source clock by acquiring a power management lock. When the source clock is generated from APB, the lock type will be set to :c:member:`ESP_PM_APB_FREQ_MAX` and when the source clock is APLL (if target support APLL), it will be set to :c:member:`ESP_PM_NO_LIGHT_SLEEP`. Whenever user is reading or writing via I2S, the driver will guarantee that the power management lock is acquired. Likewise, the driver releases the lock after reading or writing finished. +I2S driver can prevent the system from changing or stopping the source clock by acquiring a power management lock. When the source clock is generated from APB, the lock type will be set to :cpp:enumerator:`esp_pm_lock_type_t::ESP_PM_APB_FREQ_MAX` and when the source clock is APLL (if target support APLL), it will be set to :cpp:enumerator:`esp_pm_lock_type_t::ESP_PM_NO_LIGHT_SLEEP`. Whenever user is reading or writing via I2S (i.e. calling :cpp:func:`i2s_channel_read` or :cpp:func:`i2s_channel_write`), the driver will guarantee that the power management lock is acquired. Likewise, the driver releases the lock after reading or writing finished. Finite-State Machine ^^^^^^^^^^^^^^^^^^^^ -There are six states for a I2S channel, they are ``registered``, ``initializing``, ``ready``, ``idle``, ``writing`` and ``reading``. Their relationship is shown in the following diagram: +There are three states for an I2S channel, they are ``registered``, ``ready`` and ``running``. Their relationship is shown in the following diagram: .. figure:: ../../../_static/diagrams/i2s/i2s_state_machine.png :align: center :alt: I2S Finite-State Machine +The ```` in the diagram can be replaced by corresponding I2S communication mode like ``std`` for standard two-slot mode, for other information of communication mode, please refer to :ref:`i2s-communication-mode` section. + Data Transport ^^^^^^^^^^^^^^ -The data transport of I2S peripheral, including sending and receiving, is realized by DMA. Before transporting data, we need to call :cpp:func:`i2s_start_channel` to start the specific channel. When we sent or received data reached the size of one DMA buffer, ``I2S_OUT_EOF`` or ``I2S_IN_SUC_EOF`` interrupt will be triggered. Note that the DMA buffer size is not equal to :cpp:member:`i2s_std_slot_config_t::dma_frame_num`, one frame here means all the sampled data in one WS circle. Therefore, ``dma_buffer_size = dma_frame_num * slot_num * slot_bit_width / 8``. For the transmit case, users input the data by :cpp:func:`i2s_write_channel`, ``i2s_write_channel`` will help user to copy the data from source buffer to the DMA tx buffer and waiting for transmit finished and then repeat until sent bytes reached the given size. For the receive case, the rx DMA buffer address will be sent from isr to :cpp:func:`i2s_read_channel`, ``i2s_read_channel`` will help user the copy the data from DMA rx buffer to the destination buffer. +The data transport of I2S peripheral, including sending and receiving, is realized by DMA. Before transporting data, please call :cpp:func:`i2s_channel_enable` to enable the specific channel. When the sent or received data reach the size of one DMA buffer, ``I2S_OUT_EOF`` or ``I2S_IN_SUC_EOF`` interrupt will be triggered. Note that the DMA buffer size is not equal to :cpp:member:`i2s_std_slot_config_t::dma_frame_num`, one frame here means all the sampled data in one WS circle. Therefore, ``dma_buffer_size = dma_frame_num * slot_num * slot_bit_width / 8``. For the transmit case, users can input the data by calling :cpp:func:`i2s_channel_write`. This function will help users to copy the data from the source buffer to the DMA tx buffer and wait for the transmition finished. Then it'll repeat until the sent bytes reach the given size. For the receive case, the function :cpp:func:`i2s_channel_read` will wait for receiving the message queue which contains the DMA buffer address, it will help users to copy the data from DMA rx buffer to the destination buffer. + +Both :cpp:func:`i2s_channel_write` and :cpp:func:`i2s_channel_read` are blocking functions, they will keep waiting until the whole source buffer are sent or the whole destination buffer loaded, unless they exceed the max blocking time, then the error code `ESP_ERR_TIMEOUT` will return in this case. To send or receive data asynchronously, callbacks can be registered by :cpp:func:`i2s_channel_register_event_callback`, users are able to access the DMA buffer directly in the callback function instead of transmitting or receiving by the two blocking functions. However, please be aware that it is an interrupt callback, don't do complex logic, floating operation or call non-reentrant functions in the callback. Configuration Setting ^^^^^^^^^^^^^^^^^^^^^^ -Users can initialize a channel by calling :cpp:func:`i2s_init_channel`, it will initialize a channel working at a specific mode by input corresponding clock and slot configurations. If we want to update the configuration after initialization, we need to call :cpp:func:`i2s_stop_channel` first to ensure the channel has stopped, then call :cpp:func:`i2s_set_slot` or :cpp:func:`i2s_set_clock` to update the configuration. +Users can initialize a channel by corresponding function (i.e. :func:`i2s_channel_init_std_mode`, :func:`i2s_channel_init_pdm_rx_mode`, :func:`i2s_channel_init_pdm_tx_mode` or :func:`i2s_channel_init_tdm_mode`), the channel will be initialized to the specific mode. If the configurations need to be updated after initialization, :cpp:func:`i2s_channel_disable` has to be called first to ensure the channel has stopped, and then calling corresponding 'reconfig' functions, like :cpp:func:`i2s_channel_reconfig_std_slot`, :cpp:func:`i2s_channel_reconfig_std_clock`, :cpp:func:`i2s_channel_reconfig_std_gpio`. IRAM Safe ^^^^^^^^^ -By default, the GPTimer interrupt will be deferred when the Cache is disabled for reasons like writing/erasing Flash. Thus the EOF interrupt will not get executed in time, which is not expected in a real-time application. +By default, the I2S interrupt will be deferred when the Cache is disabled for reasons like writing/erasing Flash. Thus the EOF interrupt will not get executed in time, which is not expected in a real-time application. There's a Kconfig option :ref:`CONFIG_I2S_ISR_IRAM_SAFE` that will: @@ -221,6 +250,18 @@ There's a Kconfig option :ref:`CONFIG_I2S_ISR_IRAM_SAFE` that will: This will allow the interrupt to run while the cache is disabled but will come at the cost of increased IRAM consumption. +Thread Safety +^^^^^^^^^^^^^ + +All the public I2S APIs are guaranteed to be thread safe by the driver, which means, user can call them from different RTOS tasks without protection by extra locks. Notice that I2S driver uses mutex lock to ensure the thread safety, thus these APIs are not allowed to be used in ISR. + +Kconfig Options +^^^^^^^^^^^^^^^ + +- :ref:`CONFIG_I2S_ISR_IRAM_SAFE` controls whether the default ISR handler can work when cache is disabled, see `IRAM Safe <#iram-safe>`__ for more information. +- :ref:`CONFIG_I2S_SUPPRESS_DEPRECATE_WARN` controls whether to suppress the compiling warning message while using the legacy I2S driver. +- :ref:`CONFIG_I2S_ENABLE_DEBUG_LOG` is used to enabled the debug log output. Enable this option will increase the firmware binary size. + Application Example ------------------- @@ -230,100 +271,116 @@ Here are some simple usages of each mode: Standard TX/RX usage ^^^^^^^^^^^^^^^^^^^^ -We can choose different helper macros to generate different slot communication format for standard mode. As described above, there are three formats in standard mode, their helper macros are: +Different slot communication formats can be generated by following helper macros for standard mode. As described above, there are three formats in standard mode, their helper macros are: -- ``I2S_STD_PHILIP_SLOT_CONFIG(bits_per_sample, mono_or_stereo)`` -- ``I2S_STD_PCM_SLOT_CONFIG(bits_per_sample, mono_or_stereo)`` -- ``I2S_STD_MSB_SLOT_CONFIG(bits_per_sample, mono_or_stereo)`` +- :c:macro:`I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG` +- :c:macro:`I2S_STD_PCM_SLOT_DEFAULT_CONFIG` +- :c:macro:`I2S_STD_MSB_SLOT_DEFAULT_CONFIG` The clock config helper macro is: -- ``I2S_STD_CLK_CONFIG(rate)`` +- :c:macro:`I2S_STD_CLK_DEFAULT_CONFIG` -You can refer to :ref:`i2s-api-reference-i2s_std` for STD API information. -And for more details, please refer to :component_file:`hal/include/hal/i2s_std.h`. +Please refer to :ref:`i2s-api-reference-i2s_std` for STD API information. +And for more details, please refer to :component_file:`driver/include/driver/i2s_std.h`. .. code-block:: c - #include "driver/i2s_controller.h" + #include "driver/i2s_std.h" #include "driver/gpio.h" i2s_chan_handle_t tx_handle; - i2s_gpio_config_t i2s_pin = { - .mclk = I2S_GPIO_UNUSED, - .bclk = GPIO_NUM_4, - .ws = GPIO_NUM_5, - .dout = GPIO_NUM_18, - .din = I2S_GPIO_UNUSED - }; /* Get the default channel configuration by helper macro. - * This helper macro is defined in 'i2s_controller.h' and shared by all the i2s communication mode. - * It can help to specify the I2S role, mode and gpio pins */ - i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); - /* Apply a new tx channel and get the handle of this channel */ + * This helper macro is defined in 'i2s_common.h' and shared by all the i2s communication mode. + * It can help to specify the I2S role, and port id */ + i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER); + /* Allocate a new tx channel and get the handle of this channel */ i2s_new_channel(&chan_cfg, &tx_handle, NULL); - /* Get the default std philip format slot config and default std clock config + /* Setting the configurations, the slot configuration and clock configuration can be generated by the macros * These two helper macros is defined in 'i2s_std.h' which can only be used in STD mode. * They can help to specify the slot and clock configurations for initialization or updating */ - i2s_std_slot_config_t slot_cfg = I2S_STD_PHILIP_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_STEREO); - i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(48000); + i2s_std_config_t std_cfg = { + .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(48000), + .slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_STEREO), + .gpio_cfg = { + .mclk = I2S_GPIO_UNUSED, + .bclk = GPIO_NUM_4, + .ws = GPIO_NUM_5, + .dout = GPIO_NUM_18, + .din = I2S_GPIO_UNUSED, + .invert_flags = { + .mclk_inv = false, + .bclk_inv = false, + .ws_inv = false, + }, + }, + }; /* Initialize the channel */ - i2s_init_channel(tx_handle, &clk_cfg, &slot_cfg); + i2s_channel_init_std_mode(tx_handle, &std_cfg); - /* If we meed to acquire the I2S events, we can apply an event handle for receiving the events */ - // QueueHandle_t evt_que = i2s_get_event_queue(tx_handle, 15); + /* Before write data, start the tx channel first */ + i2s_channel_enable(tx_handle); + i2s_channel_write(tx_handle, src_buf, bytes_to_write, bytes_written, ticks_to_wait); - /* Before write data, we have to start the tx channel */ - i2s_start_channel(tx_handle); - i2s_write_channel(tx_handle, src_buf, bytes_to_write, bytes_written, ticks_to_wait); + /* If the configurations of slot or clock need to be updated, + * stop the channel first and then update it */ + // i2s_channel_disable(tx_handle); + // std_cfg.slot_cfg.slot_mode = I2S_SLOT_MODE_MONO; // Default is stereo + // i2s_channel_reconfig_std_slot(tx_handle, &std_cfg.slot_cfg); + // std_cfg.clk_cfg.sample_rate_hz = 96000; + // i2s_channel_reconfig_std_clock(tx_handle, &std_cfg.clk_cfg); - /* If we need to update the configurations of slot or clock, - * we need to stop the channel first and then update it */ - // i2s_stop_channel(tx_handle); - // slot_cfg.slot_mode = I2S_SLOT_MODE_MONO; // Default is stereo - // i2s_set_slot(tx_handle, &slot_cfg); - // i2s_std_clk_config_t new_clk_cfg = I2S_STD_CLK_CONFIG(96000); - // i2s_set_clock(tx_handle, &new_clk_cfg); - - /* If the handle is not needed any more, we can delete it to release the channel resources */ + /* Have to stop the channel before deleting it */ + i2s_channel_disable(tx_handle); + /* If the handle is not needed any more, delete it to release the channel resources */ i2s_del_channel(tx_handle); .. code-block:: c - #include "driver/i2s_controller.h" + #include "driver/i2s_std.h" #include "driver/gpio.h" i2s_chan_handle_t rx_handle; - i2s_gpio_config_t i2s_pin = { - .mclk = I2S_GPIO_UNUSED, - .bclk = GPIO_NUM_4, - .ws = GPIO_NUM_5, - .dout = I2S_GPIO_UNUSED, - .din = GPIO_NUM_19 - }; /* Get the default channel configuration by helper macro. - * This helper macro is defined in 'i2s_controller.h' and shared by all the i2s communication mode. - * It can help to specify the I2S role, mode and gpio pins */ - i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); - /* Apply a new rx channel and get the handle of this channel */ + * This helper macro is defined in 'i2s_common.h' and shared by all the i2s communication mode. + * It can help to specify the I2S role, and port id */ + i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER); + /* Allocate a new rx channel and get the handle of this channel */ i2s_new_channel(&chan_cfg, NULL, &rx_handle); - /* Get the default std philip format slot config and default std clock config + /* Setting the configurations, the slot configuration and clock configuration can be generated by the macros * These two helper macros is defined in 'i2s_std.h' which can only be used in STD mode. * They can help to specify the slot and clock configurations for initialization or updating */ - i2s_std_slot_config_t slot_cfg = I2S_STD_MSB_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_STEREO); // get the default MSB format slot config - i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(48000); + i2s_std_config_t std_cfg = { + .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(48000), + .slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_STEREO), + .gpio_cfg = { + .mclk = I2S_GPIO_UNUSED, + .bclk = GPIO_NUM_4, + .ws = GPIO_NUM_5, + .dout = I2S_GPIO_UNUSED, + .din = GPIO_NUM_19, + .invert_flags = { + .mclk_inv = false, + .bclk_inv = false, + .ws_inv = false, + }, + }, + }; /* Initialize the channel */ - i2s_init_channel(rx_handle, &clk_cfg, &slot_cfg); + i2s_channel_init_std_mode(rx_handle, &std_cfg); - /* Before read data, we have to start the rx channel */ - i2s_start_channel(rx_handle); - i2s_read_channel(rx_handle, desc_buf, bytes_to_read, bytes_read, ticks_to_wait); + /* Before read data, start the rx channel first */ + i2s_channel_enable(rx_handle); + i2s_channel_read(rx_handle, desc_buf, bytes_to_read, bytes_read, ticks_to_wait); - /* If the handle is not needed any more, we can delete it to release the channel resources */ + /* Have to stop the channel before deleting it */ + i2s_channel_disable(rx_handle); + /* If the handle is not needed any more, delete it to release the channel resources */ i2s_del_channel(rx_handle); + .. only:: SOC_I2S_SUPPORTS_PDM_TX PDM TX usage @@ -331,37 +388,37 @@ And for more details, please refer to :component_file:`hal/include/hal/i2s_std.h For PDM mode in tx channel, the slot configuration helper macro is: - - ``I2S_PDM_TX_SLOT_CONFIG(bits_per_sample, mono_or_stereo)`` + - :c:macro:`I2S_PDM_TX_SLOT_DEFAULT_CONFIG` The clock configuration helper macro is: - - ``I2S_PDM_TX_CLK_CONFIG(rate)`` + - :c:macro:`I2S_PDM_TX_CLK_DEFAULT_CONFIG` - You can refer to :ref:`i2s-api-reference-i2s_pdm` for PDM TX API information. - And for more details, please refer to :component_file:`hal/include/hal/i2s_pdm.h`. + Please refer to :ref:`i2s-api-reference-i2s_pdm` for PDM TX API information. + And for more details, please refer to :component_file:`driver/include/driver/i2s_pdm.h`. .. code-block:: c - #include "driver/i2s_controller.h" + #include "driver/i2s_pdm.h" #include "driver/gpio.h" - i2s_chan_handle_t tx_handle; - i2s_gpio_config_t i2s_pin = { - .mclk = I2S_GPIO_UNUSED, - .bclk = I2S_GPIO_UNUSED, - .ws = GPIO_NUM_5, - .dout = GPIO_NUM_18, - .din = I2S_GPIO_UNUSED - }; - - /* Set the channel mode to PDM TX */ - i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_PDM, &i2s_pin); + /* Allocate an I2S tx channel */ + i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER); i2s_new_channel(&chan_cfg, &tx_handle, NULL); - /* Get the default pdm tx format slot config and default pdm tx config */ - i2s_pdm_tx_slot_config_t tx_slot_cfg = I2S_PDM_TX_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO); - i2s_pdm_tx_clk_config_t tx_clk_cfg = I2S_PDM_TX_CLK_CONFIG(36000); - i2s_init_channel(tx_handle, &tx_clk_cfg, &tx_slot_cfg); + /* Init the channel into PDM TX mode */ + i2s_pdm_tx_config_t pdm_tx_cfg = { + .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(36000), + .slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO), + .gpio_cfg = { + .clk = GPIO_NUM_5, + .dout = GPIO_NUM_18, + .invert_flags = { + .clk_inv = false, + }, + }, + }; + i2s_channel_init_pdm_tx_mode(tx_handle, &pdm_tx_cfg); ... @@ -373,38 +430,39 @@ And for more details, please refer to :component_file:`hal/include/hal/i2s_std.h For PDM mode in RX channel, the slot configuration helper macro is: - - ``I2S_PDM_RX_SLOT_CONFIG(bits_per_sample, mono_or_stereo)`` + - :c:macro:`I2S_PDM_RX_SLOT_DEFAULT_CONFIG` The clock configuration helper macro is: - - ``I2S_PDM_RX_CLK_CONFIG(rate)`` + - :c:macro:`I2S_PDM_RX_CLK_DEFAULT_CONFIG` - You can refer to :ref:`i2s-api-reference-i2s_pdm` for PDM RX API information. - And for more details, please refer to :component_file:`hal/include/hal/i2s_pdm.h`. + Please refer to :ref:`i2s-api-reference-i2s_pdm` for PDM RX API information. + And for more details, please refer to :component_file:`driver/include/driver/i2s_pdm.h`. .. code-block:: c - #include "driver/i2s_controller.h" + #include "driver/i2s_pdm.h" #include "driver/gpio.h" i2s_chan_handle_t rx_handle; - i2s_gpio_config_t i2s_pin = { - .mclk = I2S_GPIO_UNUSED, - .bclk = I2S_GPIO_UNUSED, - .ws = GPIO_NUM_5, - .dout = I2S_GPIO_UNUSED, - .din = GPIO_NUM_19 - }; - /* Set the channel mode to PDM RX */ - i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_PDM, &i2s_pin); + /* Allocate an I2S rx channel */ + i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER); i2s_new_channel(&chan_cfg, &rx_handle, NULL); - /* Get the default pdm rx format slot config and default pdm rx clock config */ - i2s_pdm_rx_slot_config_t rx_slot_cfg = I2S_PDM_RX_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO); - // rx_slot_cfg.slot_mode = I2S_SLOT_MODE_STEREO; // Default is mono - i2s_pdm_rx_clk_config_t rx_clk_cfg = I2S_PDM_RX_CLK_CONFIG(36000); - i2s_init_channel(rx_handle, &clk_cfg, &slot_cfg); + /* Init the channel into PDM RX mode */ + i2s_pdm_rx_config_t pdm_rx_cfg = { + .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(36000), + .slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO), + .gpio_cfg = { + .clk = GPIO_NUM_5, + .din = GPIO_NUM_19, + .invert_flags = { + .clk_inv = false, + }, + }, + }; + i2s_channel_init_pdm_rx_mode(rx_handle, &pdm_rx_cfg); ... @@ -414,108 +472,125 @@ And for more details, please refer to :component_file:`hal/include/hal/i2s_std.h TDM TX/RX usage ^^^^^^^^^^^^^^^ - We can choose different helper macros to generate different slot communication format for TDM mode. As described above, there are four formats in TDM mode, their helper macros are: + Different slot communication formats can be generated by following helper macros for TDM mode. As described above, there are four formats in TDM mode, their helper macros are: - - ``I2S_TDM_PHILIP_SLOT_CONFIG(bits_per_sample, mono_or_stereo, mask)`` - - ``I2S_TDM_MSB_SLOT_CONFIG(bits_per_sample, mono_or_stereo, mask)`` - - ``I2S_TDM_PCM_SHORT_SLOT_CONFIG(bits_per_sample, mono_or_stereo, mask)`` - - ``I2S_TDM_PCM_LONG_SLOT_CONFIG(bits_per_sample, mono_or_stereo, mask)`` + - :c:macro:`I2S_TDM_PHILIP_SLOT_DEFAULT_CONFIG` + - :c:macro:`I2S_TDM_MSB_SLOT_DEFAULT_CONFIG` + - :c:macro:`I2S_TDM_PCM_SHORT_SLOT_DEFAULT_CONFIG` + - :c:macro:`I2S_TDM_PCM_LONG_SLOT_DEFAULT_CONFIG` The clock config helper macro is: - - ``I2S_TDM_CLK_CONFIG(rate)`` + - :c:macro:`I2S_TDM_CLK_DEFAULT_CONFIG` - You can refer to :ref:`i2s-api-reference-i2s_tdm` for TDM API information. - And for more details, please refer to :component_file:`hal/include/hal/i2s_tdm.h`. + Please refer to :ref:`i2s-api-reference-i2s_tdm` for TDM API information. + And for more details, please refer to :component_file:`driver/include/driver/i2s_tdm.h`. .. code-block:: c - #include "driver/i2s_controller.h" + #include "driver/i2s_tdm.h" #include "driver/gpio.h" - i2s_chan_handle_t tx_handle; - i2s_gpio_config_t i2s_pin = { - .mclk = I2S_GPIO_UNUSED, - .bclk = GPIO_NUM_4, - .ws = GPIO_NUM_5, - .dout = GPIO_NUM_18, - .din = I2S_GPIO_UNUSED - }; - - /* Set the channel mode to TDM */ - i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_TDM, &i2s_pin); + /* Allocate an I2S tx channel */ + i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER); i2s_new_channel(&chan_cfg, &tx_handle, NULL); - /* Get the default tdm format slot config and default tdm clock config */ - i2s_tdm_slot_config_t slot_cfg = I2S_TDM_MSB_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO, I2S_TDM_SLOT0 | I2S_TDM_SLOT1 | I2S_TDM_SLOT2 | I2S_TDM_SLOT3); - // slot_cfg.mono = true; // Default is false, set true will let all the active slots send same data - i2s_tdm_clk_config_t clk_cfg = I2S_TDM_CLK_CONFIG(44100); - i2s_init_channel(tx_handle, &clk_cfg, &slot_cfg); + /* Init the channel into TDM mode */ + i2s_tdm_config_t tdm_cfg = { + .clk_cfg = I2S_TDM_CLK_DEFAULT_CONFIG(44100), + .slot_cfg = I2S_TDM_MSB_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO, + I2S_TDM_SLOT0 | I2S_TDM_SLOT1 | I2S_TDM_SLOT2 | I2S_TDM_SLOT3), + .gpio_cfg = { + .mclk = I2S_GPIO_UNUSED, + .bclk = GPIO_NUM_4, + .ws = GPIO_NUM_5, + .dout = GPIO_NUM_18, + .din = I2S_GPIO_UNUSED, + .invert_flags = { + .mclk_inv = false, + .bclk_inv = false, + .ws_inv = false, + }, + }, + }; + i2s_channel_init_tdm_mode(tx_handle, &tdm_cfg); ... .. code-block:: c - #include "driver/i2s_controller.h" + #include "driver/i2s_tdm.h" #include "driver/gpio.h" - i2s_chan_handle_t rx_handle; - i2s_gpio_config_t i2s_pin = { - .mclk = I2S_GPIO_UNUSED, - .bclk = GPIO_NUM_4, - .ws = GPIO_NUM_5, - .dout = I2S_GPIO_UNUSED, - .din = GPIO_NUM_19 - }; - /* Set the channel mode to TDM */ i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_TDM, &i2s_pin); i2s_new_channel(&chan_cfg, NULL, &rx_handle); - /* Get the default tdm format slot config and default tdm clock config */ - i2s_tdm_slot_config_t slot_cfg = I2S_TDM_MSB_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO, I2S_TDM_SLOT0 | I2S_TDM_SLOT1 | I2S_TDM_SLOT2 | I2S_TDM_SLOT3); - i2s_tdm_clk_config_t clk_cfg = I2S_TDM_CLK_CONFIG(44100); - i2s_init_channel(tx_handle, &clk_cfg, &slot_cfg); + /* Init the channel into TDM mode */ + i2s_tdm_config_t tdm_cfg = { + .clk_cfg = I2S_TDM_CLK_DEFAULT_CONFIG(44100), + .slot_cfg = I2S_TDM_MSB_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO, + I2S_TDM_SLOT0 | I2S_TDM_SLOT1 | I2S_TDM_SLOT2 | I2S_TDM_SLOT3), + .gpio_cfg = { + .mclk = I2S_GPIO_UNUSED, + .bclk = GPIO_NUM_4, + .ws = GPIO_NUM_5, + .dout = I2S_GPIO_UNUSED, + .din = GPIO_NUM_18, + .invert_flags = { + .mclk_inv = false, + .bclk_inv = false, + .ws_inv = false, + }, + }, + }; + i2s_channel_init_tdm_mode(rx_handle, &tdm_cfg); ... Full-duplex ^^^^^^^^^^^ -Full-duplex mode will register tx and rx channel in a I2S port at the same time, and they will share the BCLK and WS signal. Currently STD and TDM communication mode are able to apply full-duplex mode in following way, but PDM full-duplex is not supported in this way. +Full-duplex mode will register tx and rx channel in an I2S port at the same time, and they will share the BCLK and WS signal. Currently STD and TDM communication mode are able to adopt full-duplex mode in following way, but PDM full-duplex is not supported because PDM TX and RX clock are not same. -Note that since the handle is the channel handle, we have to apply same slot and clock configurations for both tx and rx channel one by one. +Note that one handle can only stand for one channel, the slot and clock configurations for both tx and rx channel should be set one by one. -Here is an example of how to apply a pair of full-duplex channels: +Here is an example of how to allocate a pair of full-duplex channels: .. code-block:: c - #include "driver/i2s_controller.h" + #include "driver/i2s_std.h" #include "driver/gpio.h" i2s_chan_handle_t tx_handle; i2s_chan_handle_t rx_handle; - i2s_gpio_config_t i2s_pin = { - .mclk = I2S_GPIO_UNUSED, - .bclk = GPIO_NUM_4, - .ws = GPIO_NUM_5, - .dout = GPIO_NUM_18, - .din = GPIO_NUM_19 - }; - /* Set the channel mode to STD */ - i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); - /* Apply for tx and rx channel at the same time, then they will work in full-duplex mode */ + /* Allocate a pair of I2S channel */ + i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER); + /* Allocate for tx and rx channel at the same time, then they will work in full-duplex mode */ i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle); - /* Get the default configurations */ - i2s_std_slot_config_t slot_cfg = I2S_STD_PHILIP_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO); - i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(32000); /* Set the configurations for BOTH TWO channels, since tx and rx channel have to be same in full-duplex mode */ - i2s_init_channle(tx_handle, &clk_cfg, &slot_cfg); - i2s_init_channle(rx_handle, &clk_cfg, &slot_cfg); + i2s_std_config_t std_cfg = { + .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(32000), + .slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO), + .gpio_cfg = { + .mclk = I2S_GPIO_UNUSED, + .bclk = GPIO_NUM_4, + .ws = GPIO_NUM_5, + .dout = GPIO_NUM_18, + .din = GPIO_NUM_19, + .invert_flags = { + .mclk_inv = false, + .bclk_inv = false, + .ws_inv = false, + }, + }, + }; + i2s_init_channle(tx_handle, &std_cfg); + i2s_init_channle(rx_handle, &std_cfg); - i2s_start_channel(tx_handle); - i2s_start_channel(rx_handle); + i2s_channel_enable(tx_handle); + i2s_channel_enable(rx_handle); ... @@ -524,92 +599,119 @@ Here is an example of how to apply a pair of full-duplex channels: Simplex Mode ^^^^^^^^^^^^ - To apply the simplex mode, :c:func:`i2s_new_channel` should be called for each channel. The clock and gpio pins of TX/RX channel on {IDF_TARGET_NAME} are not separate, therefore TX and RX channel can't coexist on a same I2S port in simplex mode. + To allocate a channel handle in simplex mode, :cpp:func:`i2s_new_channel` should be called for each channel. The clock and gpio pins of TX/RX channel on {IDF_TARGET_NAME} are not separate, therefore TX and RX channel can't coexist on a same I2S port in simplex mode. .. code-block:: c - #include "driver/i2s_controller.h" + #include "driver/i2s_std.h" #include "driver/gpio.h" i2s_chan_handle_t tx_handle; i2s_chan_handle_t rx_handle; - i2s_gpio_config_t tx_pin = { - .mclk = GPIO_NUM_0, - .bclk = GPIO_NUM_4, - .ws = GPIO_NUM_5, - .dout = GPIO_NUM_18, - .din = I2S_GPIO_UNUSED - }; - i2s_chan_config_t tx_chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, tx_pin); - i2s_new_channel(&tx_chan_cfg, &tx_handle, NULL); - i2s_std_slot_config_t tx_slot_cfg = I2S_STD_PHILIP_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO); - tx_slot_cfg.auto_clear = false; - i2s_std_clk_config_t tx_clk_cfg = I2S_STD_CLK_CONFIG(48000); - i2s_init_channel(tx_handle, &tx_clk_cfg, &tx_slot_cfg); - i2s_start_channel(tx_handle); - i2s_gpio_config_t rx_pin = { - .mclk = I2S_GPIO_UNUSED, - .bclk = GPIO_NUM_6, - .ws = GPIO_NUM_7, - .dout = I2S_GPIO_UNUSED, - .din = GPIO_NUM_19 + i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER); + i2s_new_channel(&chan_cfg, &tx_handle, NULL); + i2s_std_config_t std_tx_cfg = { + .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(48000), + .slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO), + .gpio_cfg = { + .mclk = GPIO_NUM_0, + .bclk = GPIO_NUM_4, + .ws = GPIO_NUM_5, + .dout = GPIO_NUM_18, + .din = I2S_GPIO_UNUSED, + .invert_flags = { + .mclk_inv = false, + .bclk_inv = false, + .ws_inv = false, + }, + }, }; - i2s_chan_config_t rx_chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, rx_pin); + /* Initialize the channel */ + i2s_channel_init_std_mode(tx_handle, &std_tx_cfg); + i2s_channel_enable(tx_handle); + /* rx channel will be registered on another I2S, if no other available I2S unit found * it will return ESP_ERR_NOT_FOUND */ - i2s_new_channel(&rx_chan_cfg, NULL, &rx_handle); - i2s_std_slot_config_t rx_slot_cfg = I2S_STD_MSB_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_STEREO); - i2s_std_clk_config_t rx_clk_cfg = I2S_STD_CLK_CONFIG(16000); - i2s_init_channel(rx_handle, &rx_clk_cfg, &rx_slot_cfg); - i2s_start_channel(rx_handle); + i2s_new_channel(&chan_cfg, NULL, &rx_handle); + i2s_std_config_t std_rx_cfg = { + .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(16000), + .slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_STEREO), + .gpio_cfg = { + .mclk = I2S_GPIO_UNUSED, + .bclk = GPIO_NUM_6, + .ws = GPIO_NUM_7, + .dout = I2S_GPIO_UNUSED, + .din = GPIO_NUM_19, + .invert_flags = { + .mclk_inv = false, + .bclk_inv = false, + .ws_inv = false, + }, + }, + }; + i2s_channel_init_std_mode(rx_handle, &std_rx_cfg); + i2s_channel_enable(rx_handle); .. only:: SOC_I2S_HW_VERSION_2 Simplex Mode ^^^^^^^^^^^^ - To apply the simplex mode, :c:func:`i2s_new_channel` should be called for each channel. The clock and gpio pins of TX/RX channel on {IDF_TARGET_NAME} are separate, they can be configured in different modes and clocks, and they are able to coexist on a same I2S port in simplex mode. So PDM duplex can be realized by registering PDM TX simplex and PDM RX simplex on a same I2S port. But in this way, PDM TX/RX might work with different clocks, take care when configuring the gpio pins and clocks. + To allocate a channel in simplex mode, :cpp:func:`i2s_new_channel` should be called for each channel. The clock and gpio pins of TX/RX channel on {IDF_TARGET_NAME} are separate, they can be configured in different modes and clocks, and they are able to coexist on a same I2S port in simplex mode. So PDM duplex can be realized by registering PDM TX simplex and PDM RX simplex on a same I2S port. But in this way, PDM TX/RX might work with different clocks, take care when configuring the gpio pins and clocks. - The following codes offer an example for the simplex mode, but note that, although the internal MCLK signals for tx and rx channel are separate, the output MCLK can only be bound to one of them, if both channel initialized MCLK, it depends on which is initialized later. + The following example offers a use case for the simplex mode, but note that, although the internal MCLK signals for tx and rx channel are separate, the output MCLK can only be bound to one of them if they are from a same controller, if both channel initialized MCLK, it depends on which is initialized later. -1. Determine the interrupt interval. Generally, when data lost happened, the interval should be the bigger the better, it can help to reduce the interrupt times, i.e., ``dma_frame_num`` should be as big as possible while the DMA buffer size won't exceed its maximum value 4092. The relationships are:: + .. code-block:: c - #include "driver/i2s_controller.h" + #include "driver/i2s_std.h" #include "driver/gpio.h" i2s_chan_handle_t tx_handle; i2s_chan_handle_t rx_handle; - i2s_gpio_config_t tx_pin = { - .mclk = GPIO_NUM_0, - .bclk = GPIO_NUM_4, - .ws = GPIO_NUM_5, - .dout = GPIO_NUM_18, - .din = I2S_GPIO_UNUSED + i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER); + i2s_new_channel(&chan_cfg, &tx_handle, NULL); + i2s_std_config_t std_tx_cfg = { + .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(48000), + .slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO), + .gpio_cfg = { + .mclk = GPIO_NUM_0, + .bclk = GPIO_NUM_4, + .ws = GPIO_NUM_5, + .dout = GPIO_NUM_18, + .din = I2S_GPIO_UNUSED, + .invert_flags = { + .mclk_inv = false, + .bclk_inv = false, + .ws_inv = false, + }, + }, }; - i2s_chan_config_t tx_chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, tx_pin); - tx_chan_cfg.id = I2S_NUM_0; // Specify the port id - i2s_new_channel(&tx_chan_cfg, &tx_handle, NULL); - i2s_std_slot_config_t tx_slot_cfg = I2S_STD_PHILIP_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO); - tx_slot_cfg.auto_clear = false; - i2s_std_clk_config_t tx_clk_cfg = I2S_STD_CLK_CONFIG(48000); - i2s_init_channel(tx_handle, &tx_clk_cfg, &tx_slot_cfg); - i2s_start_channel(tx_handle); + /* Initialize the channel */ + i2s_channel_init_std_mode(tx_handle, &std_tx_cfg); + i2s_channel_enable(tx_handle); - i2s_gpio_config_t rx_pin = { - .mclk = I2S_GPIO_UNUSED, - .bclk = GPIO_NUM_6, - .ws = GPIO_NUM_7, - .dout = I2S_GPIO_UNUSED, - .din = GPIO_NUM_19 + /* rx channel will be registered on another I2S, if no other available I2S unit found + * it will return ESP_ERR_NOT_FOUND */ + i2s_new_channel(&chan_cfg, NULL, &rx_handle); // Both rx and tx channel will be registered on I2S0, but they can work with different configurations. + i2s_std_config_t std_rx_cfg = { + .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(16000), + .slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_STEREO), + .gpio_cfg = { + .mclk = I2S_GPIO_UNUSED, + .bclk = GPIO_NUM_6, + .ws = GPIO_NUM_7, + .dout = I2S_GPIO_UNUSED, + .din = GPIO_NUM_19, + .invert_flags = { + .mclk_inv = false, + .bclk_inv = false, + .ws_inv = false, + }, + }, }; - i2s_chan_config_t rx_chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, rx_pin); - tx_chan_cfg.id = I2S_NUM_0; // Specify the port id - i2s_new_channel(&rx_chan_cfg, NULL, &rx_handle); - i2s_std_slot_config_t rx_slot_cfg = I2S_STD_MSB_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_STEREO); - i2s_std_clk_config_t rx_clk_cfg = I2S_STD_CLK_CONFIG(16000); - i2s_init_channel(rx_handle, &rx_clk_cfg, &rx_slot_cfg); - i2s_start_channel(rx_handle); + i2s_channel_init_std_mode(rx_handle, &std_rx_cfg); + i2s_channel_enable(rx_handle); Application Notes @@ -618,18 +720,24 @@ Application Notes How to Prevent Data Lost ^^^^^^^^^^^^^^^^^^^^^^^^ -For the applications that need a high frequency sample rate, sometimes the massive throughput of receiving data may cause data lost. Users can receive data lost event by the event queue: +For the applications that need a high frequency sample rate, sometimes the massive throughput of receiving data may cause data lost. Users can receive data lost event by registering isr callback function to receive event queue: - dma_desc_num > polling_cycle / interrupt_interval + .. code-block:: c - QueueHandle_t evt_que = i2s_get_event_queue(rx_handle, 10); - ... - i2s_event_t evt; - xQueueReceive(evt_que, &evt, portMAX_DELAY); - if (evt.type == I2S_EVENT_RX_Q_OVF) { - printf("RX data dropped\n"); + static IRAM_ATTR bool i2s_rx_queue_overflow_callback(i2s_chan_handle_t handle, i2s_event_data_t *event, void *user_ctx) + { + // handle rx queue overflow event ... + return false; } + i2s_event_callbacks_t cbs = { + .on_recv = NULL, + .on_recv_q_ovf = i2s_rx_queue_overflow_callback, + .on_sent = NULL, + .on_send_q_ovf = NULL, + }; + TEST_ESP_OK(i2s_channel_register_event_callback(rx_handle, &cbs, NULL)); + Please follow these steps to prevent data lost: 1. Determine the interrupt interval. Generally, when data lost happened, the interval should be the bigger the better, it can help to reduce the interrupt times, i.e., ``dma_frame_num`` should be as big as possible while the DMA buffer size won't exceed its maximum value 4092. The relationships are:: @@ -637,22 +745,22 @@ Please follow these steps to prevent data lost: interrupt_interval(unit: sec) = dma_frame_num / sample_rate dma_buffer_size = dma_frame_num * slot_num * data_bit_width / 8 <= 4092 -2. Determine the ``dma_desc_num``. The ``dma_desc_num`` is decided by the max time of ``i2s_read_channel`` polling cycle, we need to guarantee all the data can be stored between two ``i2s_read_channel``. This cycle can be measured by a timer or an outputting gpio signal. The relationship is:: +2. Determine the ``dma_desc_num``. The ``dma_desc_num`` is decided by the max time of ``i2s_channel_read`` polling cycle, all the received data are supposed to be stored between two ``i2s_channel_read``. This cycle can be measured by a timer or an outputting gpio signal. The relationship is:: dma_desc_num > polling_cycle / interrupt_interval -3. Determine the receiving buffer size. The receiving buffer that offered by user in ``i2s_read_channel`` should be able to take all the data in all dma buffers, that means it should be bigger than the total size of all the dma buffers:: +3. Determine the receiving buffer size. The receiving buffer that offered by user in ``i2s_channel_read`` should be able to take all the data in all dma buffers, that means it should be bigger than the total size of all the dma buffers:: recv_buffer_size > dma_desc_num * dma_buffer_size -For example, if there is a I2S application, we have known these values:: +For example, if there is an I2S application, and the known values are:: sample_rate = 144000 Hz data_bit_width = 32 bits slot_num = 2 polling_cycle = 10ms -Then we need to calculate ``dma_frame_num``, ``dma_desc_num`` and ``recv_buf_size`` according to the given known values:: +Then the parameters ``dma_frame_num``, ``dma_desc_num`` and ``recv_buf_size`` can be calculated according to the given known values:: dma_frame_num * slot_num * data_bit_width / 8 = dma_buffer_size <= 4092 dma_frame_num <= 511 @@ -694,11 +802,12 @@ Standard Mode I2S Driver ^^^^^^^^^^ -.. include-build-file:: inc/i2s_controller.inc +.. include-build-file:: inc/i2s_common.inc .. _i2s-api-reference-i2s_types: I2S Types ^^^^^^^^^ -.. include-build-file:: inc/i2s_types.inc +.. include-build-file:: inc/components/driver/include/driver/i2s_types.inc +.. include-build-file:: inc/components/hal/include/hal/i2s_types.inc diff --git a/docs/en/migration-guides/peripherals.rst b/docs/en/migration-guides/peripherals.rst index 479894c145..1d0fa4298c 100644 --- a/docs/en/migration-guides/peripherals.rst +++ b/docs/en/migration-guides/peripherals.rst @@ -256,62 +256,66 @@ LCD - All of the dedicated GPIO related LL functionsn in ``cpu_ll.h`` have been moved to ``dedic_gpio_cpu_ll.h`` and renamed. -I2S driver ----------- +.. only:: SOC_I2S_SUPPORTED -Since the old driver is unable to support all the new features on ESP32-C3 & ESP32-S3, I2S driver is re-designed to make it more compatibile and flexibile to all the communication modes. New APIs are available by including :component_file:`driver/include/driver/i2s_controller.h`. Meanwhile, the old APIs in :component_file:`driver/deprecated/driver/i2s.h` are still supported for backward compatibility. But there will be warnings if you keep using the old APIs in your project, these warnings can be suppressed by the Kconfig option :ref:`CONFIG_I2S_SUPPRESS_DEPRECATE_WARN`. Here is the general overview of the current I2S files: + I2S driver + ---------- -.. figure:: ../../_static/diagrams/i2s/i2s_file_structure.png - :align: center - :alt: I2S File Structure + {I2S_DRIVER_HEADERS:default=":component_file:`driver/include/driver/i2s_std.h`, :component_file:`driver/include/driver/i2s_pdm.h` or :component_file:`driver/include/driver/i2s_tdm.h`", esp32=":component_file:`driver/include/driver/i2s_std.h` or :component_file:`driver/include/driver/i2s_pdm.h`", esp32s2=":component_file:`driver/include/driver/i2s_std.h`"} -Breaking changes in Concepts -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Shortcomings are exposed when supporting all the new features of ESP32-C3 & ESP32-S3 by the old I2S driver, so it is re-designed to make it more compatible and flexible to all the communication modes. New APIs are available by including corresponding mode header files {I2S_DRIVER_HEADERS}. Meanwhile, the old APIs in :component_file:`driver/deprecated/driver/i2s.h` are still supported for backward compatibility. But there will be warnings if you keep using the old APIs in your project, these warnings can be suppressed by the Kconfig option :ref:`CONFIG_I2S_SUPPRESS_DEPRECATE_WARN`. Here is the general overview of the current I2S files: -- The minimum control unit in new I2S driver will be tx/rx channel instead of a whole I2S controller. + .. figure:: ../../_static/diagrams/i2s/i2s_file_structure.png + :align: center + :alt: I2S File Structure - 1. The tx/rx channel in a same I2S controller can be controlled separately, that means they will be initialized, started or stopped separately. Especially for ESP32-C3 and ESP32-S3, tx and rx channels in one controller can be configured to different clocks or modes now, they are able to work in a totally separate way which can help to save the resources of I2S controller. But for ESP32 and ESP32-S2, though their tx/rx can be controlled separately, some hardware resources are still shared by tx and rx, they might affect each other if they are configured to different configurations; - 2. The channels can be registered to an available I2S controller automatically by choosing :cpp:member:`i2s_port_t::I2S_NUM_AUTO` as I2S port id. The driver will help you to search for the available tx/rx channel. Of cause, you can still choose a specific port for it; - 3. :c:type:`i2s_chan_handle_t` is the handle that used for identifying the I2S channels. All the APIs will require the channel handle, users need to maintain the channel handles by themselves; - 4. In order to distinguish tx/rx channel and sound channel, now the word 'channel' is only stand for the tx/rx channel in new driver, meanwhile the sound channel will be called 'slot'. + Breaking changes in Concepts + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- I2S communication modes are extracted into three modes. + - The minimum control unit in new I2S driver will be tx/rx channel instead of a whole I2S controller. - 1. **Standard mode**: Standard mode always has two slots, it can support Philip, MSB and PCM(short sync) format, please refer to :component_file:`hal/include/hal/i2s_std.h` for details; - 2. **PDM mode**: PDM mode only support two slots with 16 bits data width, but the configurations of PDM TX and PDM RX are little bit different. For PDM TX, the sample rate can be set by :cpp:member:`i2s_pdm_tx_clk_config_t::sample_rate`, and its clock frequency is depended on the up-sampling configuration. For PDM RX, the sample rate can be set by :cpp:member:`i2s_pdm_rx_clk_config_t::sample_rate`, and its clock frequency is depended on the down-sampling configuration. Please refer to :component_file:`hal/include/hal/i2s_pdm.h` for details; - 3. **TDM mode**: TDM mode can support upto 16 slots. It can work in Philip, MSB, PCM(short sync) and PCM(long sync) format, please refer to :component_file:`hal/include/hal/i2s_tdm.h` for details; - 4. When we allocate a new channel in a specific mode, we must initialize this channel by corresponding slot configurations and clock configurations. We strongly recommend to use the helper macros to generate the default configurations, in case the default values will be changed one day. - 5. Although there are three modes, they still share some general slot and clock configurations which are defined in :component_file:`hal/include/hal/i2s_hal.h` + 1. The tx/rx channel in a same I2S controller can be controlled separately, that means they will be initialized, started or stopped separately. Especially for ESP32-C3 and ESP32-S3, tx and rx channels in one controller can be configured to different clocks or modes now, they are able to work in a totally separate way which can help to save the resources of I2S controller. But for ESP32 and ESP32-S2, though their tx/rx can be controlled separately, some hardware resources are still shared by tx and rx, they might affect each other if they are configured to different configurations; + 2. The channels can be registered to an available I2S controller automatically by setting :cpp:enumerator:`i2s_port_t::I2S_NUM_AUTO` as I2S port id. The driver will help you to search for the available tx/rx channel. Of cause, driver can still support to be installed by a specific port; + 3. :c:type:`i2s_chan_handle_t` is the handle that used for identifying the I2S channels. All the APIs will require the channel handle, users need to maintain the channel handles by themselves; + 4. In order to distinguish tx/rx channel and sound channel, now the word 'channel' is only stand for the tx/rx channel in new driver, meanwhile the sound channel will be called 'slot'. -- States and state-machine are adopted in the new I2S driver to avoid APIs are called in wrong state. + - I2S communication modes are extracted into three modes. -- The slot configurations and clock configurations can be configured separately. + 1. **Standard mode**: Standard mode always has two slots, it can support Philip, MSB and PCM(short sync) format, please refer to :component_file:`driver/include/driver/i2s_std.h` for details; + 2. **PDM mode**: PDM mode only support two slots with 16 bits data width, but the configurations of PDM TX and PDM RX are little bit different. For PDM TX, the sample rate can be set by :cpp:member:`i2s_pdm_tx_clk_config_t::sample_rate`, and its clock frequency is depended on the up-sampling configuration. For PDM RX, the sample rate can be set by :cpp:member:`i2s_pdm_rx_clk_config_t::sample_rate`, and its clock frequency is depended on the down-sampling configuration. Please refer to :component_file:`driver/include/driver/i2s_pdm.h` for details; + 3. **TDM mode**: TDM mode can support upto 16 slots. It can work in Philip, MSB, PCM(short sync) and PCM(long sync) format, please refer to :component_file:`driver/include/driver/i2s_tdm.h` for details; + 4. When allocating a new channel in a specific mode, must initialize this channel by corresponding function. It is strongly recommended to use the helper macros to generate the default configurations, in case the default values will be changed one day. - 1. Calling :func:`i2s_init_channel` to initialize the slot/clock/gpio_pin configurations; - 2. Calling :c:func:`i2s_set_slot` can change the slot configurations after initialization; - 3. Calling :c:func:`i2s_set_clock` can change the clock configurations after initialization. + - States and state-machine are adopted in the new I2S driver to avoid APIs called in wrong state. -- ADC and DAC modes are removed. They will only be supported in their own driver and legacy I2S driver. + - The slot configurations and clock configurations can be configured separately. -- :c:func:`i2s_write_channel` and :c:func:`i2s_read_channel` can be aborted by :c:func:`i2s_abort_reading_writing` now. + 1. Calling :cpp:func:`i2s_channel_init_std_mode`, :cpp:func:`i2s_channel_init_pdm_rx_mode`, :cpp:func:`i2s_channel_init_pdm_tx_mode` or :cpp:func:`i2s_channel_init_tdm_mode` to initialize the slot/clock/gpio_pin configurations; + 2. Calling :cpp:func:`i2s_channel_reconfig_std_slot`, :cpp:func:`i2s_channel_reconfig_pdm_rx_slot`, :cpp:func:`i2s_channel_reconfig_pdm_tx_slot` or :cpp:func:`i2s_channel_reconfig_tdm_slot` can change the slot configurations after initialization; + 3. Calling :cpp:func:`i2s_channel_reconfig_std_clock`, :cpp:func:`i2s_channel_reconfig_pdm_rx_clock`, :cpp:func:`i2s_channel_reconfig_pdm_tx_clock` or :cpp:func:`i2s_channel_reconfig_tdm_clock` can change the clock configurations after initialization; + 4. Calling :cpp:func:`i2s_channel_reconfig_std_gpio`, :cpp:func:`i2s_channel_reconfig_pdm_rx_gpio`, :cpp:func:`i2s_channel_reconfig_pdm_tx_gpio` or :cpp:func:`i2s_channel_reconfig_tdm_gpio` can change the gpio configurations after initialization. -Breaking Changes in Usage -~~~~~~~~~~~~~~~~~~~~~~~~~ + - ADC and DAC modes are removed. They will only be supported in their own driver and legacy I2S driver. -To use the new I2S driver, please follow these steps: + - :cpp:func:`i2s_channel_write` and :cpp:func:`i2s_channel_read` can be aborted by :cpp:func:`i2s_channel_abort_reading_writing` now. -1. Calling :c:func:`i2s_new_channel` to aquire the channel handles. We should specify the GPIO pins, work mode, work role and I2S port in this step. Besides, we need to input the tx or rx handle to acuire the channel handles that generated by the driver. We don't have to input both two tx and rx handles but at least one handle is needed. While we input both two handles, the driver will work in duplex mode, both tx and rx channel will be avaliable on a same port, and they will share the MCLK, BCLK and WS signal, there will be MCLK(optional), BCLK, WS, DATA_IN and DATA_OUT signals in this case. But if we only input tx or rx handle, this channel will only work in simplex mode. + Breaking Changes in Usage + ~~~~~~~~~~~~~~~~~~~~~~~~~ -2. Calling :c:func:`i2s_init_channel` to initialize the channel that specified by the given channel handle. We are supposed to input corresponding slot and clock configurations according to the mode that we set in the first step. + To use the new I2S driver, please follow these steps: -3. (Optional) We can acquire the event queue handle by :c:func:`i2s_get_event_queue` if we want to monitor the I2S event. + 1. Calling :cpp:func:`i2s_new_channel` to aquire the channel handles. We should specify the work role and I2S port in this step. Besides, the tx or rx channel handles will be generated by the driver. Inputting both two tx and rx handles is not necessary but at least one handle is needed. In the case of inputting both two handles, the driver will work at duplex mode, both tx and rx channel will be avaliable on a same port, and they will share the MCLK, BCLK and WS signal. But if only one of the tx or rx handle is inputted, this channel will only work in simplex mode. -4. Calling :c:func:`i2s_start_channel` to start the I2S channel. In the new driver, I2S won't start automatically after installed anymore, we are supposed to know clearly whether the channel has started or not. + 2. Calling :func:`i2s_channel_init_std_mode`, :func:`i2s_channel_init_pdm_rx_mode`, :func:`i2s_channel_init_pdm_tx_mode` or :func:`i2s_channel_init_tdm_mode` to initialize the channel to the specified mode. Corresponding slot, clock and gpio configurations are needed in this step. -5. Reading or writing data by :c:func:`i2s_read_channel` or :c:func:`i2s_write_channel`. Of cause we can only use rx channel handle in :c:func:`i2s_read_channel` and tx channel handle in :c:func:`i2s_write_channel`. + 3. (Optional) Calling :cpp:func:`i2s_channel_register_event_callback` to register the ISR event callback functions. I2S events now can be received by the callback function synchronously, instead of from event queue asynchronously. -6. (Optional) We can clear the legacy data in DMA buffer by :c:func:`i2s_clear_dma_buffer`. If we need the driver clear the tx dma buffer automatically, we can set :c:member`auto_clear` in slot configurations. + 4. Calling :cpp:func:`i2s_channel_enable` to start the hardware of I2S channel. In the new driver, I2S won't start automatically after installed anymore, users are supposed to know clearly whether the channel has started or not. -7. (Optional) We can change the slot and clock configurations after initialized by :c:func:`i2s_set_slot`, :c:func:`i2s_set_clock`, but we have to call :c:func:`i2s_stop_channel` before we update the configurations. + 5. Reading or writing data by :cpp:func:`i2s_channel_read` or :cpp:func:`i2s_channel_write`. Certainly, only rx channel handle is suppoesd to be inputted in :cpp:func:`i2s_channel_read` and tx channel handle in :cpp:func:`i2s_channel_write`. -8. (Optional) We can delete the i2s channel by calling :c:func:`i2s_del_channel` if we don't need it any more. The related resources will be released if delete function is called. + 6. (Optional) The slot, clock and gpio configurations can be changed by corresponding 'reconfig' functions, but :cpp:func:`i2s_channel_disable` must be called before updating the configurations. + + 7. Calling :cpp:func:`i2s_channel_disable` to stop the hardware of I2S channel. + + 8. Calling :cpp:func:`i2s_del_channel` to delete and release the resources of the channel if it is not needed any more, but the channel must be disabled before deleting it. diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_av.c b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_av.c index 98e5beff75..3238cc3f27 100644 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_av.c +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_av.c @@ -183,9 +183,9 @@ void bt_i2s_driver_install(void) }; /* enable I2S */ - i2s_driver_install(0, &i2s_config, 0, NULL); - i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN); - i2s_set_pin(0, NULL); + ESP_ERROR_CHECK(i2s_driver_install(0, &i2s_config, 0, NULL)); + ESP_ERROR_CHECK(i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN)); + ESP_ERROR_CHECK(i2s_set_pin(0, NULL)); #else i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER); chan_cfg.auto_clear = true; @@ -198,12 +198,17 @@ void bt_i2s_driver_install(void) .ws = CONFIG_EXAMPLE_I2S_LRCK_PIN, .dout = CONFIG_EXAMPLE_I2S_DATA_PIN, .din = I2S_GPIO_UNUSED, + .invert_flags = { + .mclk_inv = false, + .bclk_inv = false, + .ws_inv = false, + }, }, }; /* enable I2S */ - i2s_new_channel(&chan_cfg, &tx_chan, NULL); - i2s_init_std_channel(tx_chan, &std_cfg); - i2s_start_channel(tx_chan); + ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, &tx_chan, NULL)); + ESP_ERROR_CHECK(i2s_channel_init_std_mode(tx_chan, &std_cfg)); + ESP_ERROR_CHECK(i2s_channel_enable(tx_chan)); #endif } @@ -212,7 +217,8 @@ void bt_i2s_driver_uninstall(void) #ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC i2s_driver_uninstall(0); #else - i2s_del_channel(tx_chan); + ESP_ERROR_CHECK(i2s_channel_disable(tx_chan)); + ESP_ERROR_CHECK(i2s_del_channel(tx_chan)); #endif } @@ -308,7 +314,7 @@ static void bt_av_hdl_a2d_evt(uint16_t event, void *p_param) i2s_set_clk(0, sample_rate, 16, 2); #else i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(sample_rate); - i2s_reconfig_std_clock(tx_chan, &clk_cfg); + i2s_channel_reconfig_std_clock(tx_chan, &clk_cfg); #endif ESP_LOGI(BT_AV_TAG, "Configure audio player: %x-%x-%x-%x", a2d->audio_cfg.mcc.cie.sbc[0], diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_core.c b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_core.c index d99e22e68b..a1cfb3b867 100644 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_core.c +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_core.c @@ -110,7 +110,7 @@ static void bt_i2s_task_handler(void *arg) #ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC i2s_write(0, data, item_size, &bytes_written, portMAX_DELAY); #else - i2s_write_channel(tx_chan, data, item_size, &bytes_written, portMAX_DELAY); + i2s_channel_write(tx_chan, data, item_size, &bytes_written, portMAX_DELAY); #endif vRingbufferReturnItem(s_ringbuf_i2s, (void *)data); } diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/tutorial/Example_A2DP_Sink.md b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/tutorial/Example_A2DP_Sink.md index d672a7decf..9604f00a59 100644 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/tutorial/Example_A2DP_Sink.md +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/tutorial/Example_A2DP_Sink.md @@ -102,11 +102,10 @@ The main function installs I2S to play the audio. A loudspeaker, additional ADC }; /* enable I2S */ - i2s_driver_install(0, &i2s_config, 0, NULL); - i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN); - i2s_set_pin(0, NULL); + ESP_ERROR_CHECK(i2s_driver_install(0, &i2s_config, 0, NULL)); + ESP_ERROR_CHECK(i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN)); + ESP_ERROR_CHECK(i2s_set_pin(0, NULL)); #else - i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER); chan_cfg.auto_clear = true; i2s_std_config_t std_cfg = { @@ -118,12 +117,17 @@ The main function installs I2S to play the audio. A loudspeaker, additional ADC .ws = CONFIG_EXAMPLE_I2S_LRCK_PIN, .dout = CONFIG_EXAMPLE_I2S_DATA_PIN, .din = I2S_GPIO_UNUSED, + .invert_flags = { + .mclk_inv = false, + .bclk_inv = false, + .ws_inv = false, + }, }, }; /* enable I2S */ - i2s_new_channel(&chan_cfg, &tx_chan, NULL); - i2s_init_std_channel(tx_chan, &std_cfg); - i2s_start_channel(tx_chan); + ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, &tx_chan, NULL)); + ESP_ERROR_CHECK(i2s_channel_init_std_mode(tx_chan, &std_cfg)); + ESP_ERROR_CHECK(i2s_channel_enable(tx_chan)); #endif ``` diff --git a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_av.c b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_av.c index 86e453115d..f8ee8f811b 100644 --- a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_av.c +++ b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_av.c @@ -174,7 +174,7 @@ static void bt_av_hdl_a2d_evt(uint16_t event, void *p_param) i2s_set_clk(0, sample_rate, 16, 2); #else i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(sample_rate); - i2s_reconfig_clock(tx_chan, &clk_cfg); + i2s_channel_reconfig_std_clock(tx_chan, &clk_cfg); #endif ESP_LOGI(BT_AV_TAG, "Configure audio player %x-%x-%x-%x", diff --git a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_core.c b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_core.c index 88008a5a6e..f69d10b216 100644 --- a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_core.c +++ b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_core.c @@ -134,7 +134,7 @@ static void bt_i2s_task_handler(void *arg) #ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC i2s_write(0, data, item_size, &bytes_written, portMAX_DELAY); #else - i2s_write_channel(tx_chan, data, item_size, &bytes_written, portMAX_DELAY); + i2s_channel_write(tx_chan, data, item_size, &bytes_written, portMAX_DELAY); #endif vRingbufferReturnItem(s_ringbuf_i2s,(void *)data); } diff --git a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/main.c b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/main.c index b1cc5a52cc..81bf399f78 100644 --- a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/main.c +++ b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/main.c @@ -705,9 +705,9 @@ void app_main(void) }; /* enable I2S */ - i2s_driver_install(0, &i2s_config, 0, NULL); - i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN); - i2s_set_pin(0, NULL); + ESP_ERROR_CHECK(i2s_driver_install(0, &i2s_config, 0, NULL)); + ESP_ERROR_CHECK(i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN)); + ESP_ERROR_CHECK(i2s_set_pin(0, NULL)); #else i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER); chan_cfg.auto_clear = true; @@ -720,12 +720,17 @@ void app_main(void) .ws = CONFIG_EXAMPLE_I2S_LRCK_PIN, .dout = CONFIG_EXAMPLE_I2S_DATA_PIN, .din = I2S_GPIO_UNUSED, + .invert_flags = { + .mclk_inv = false, + .bclk_inv = false, + .ws_inv = false, + }, }, }; /* enable I2S */ - i2s_new_channel(&chan_cfg, &tx_chan, NULL); - i2s_init_std_channel(tx_chan, &std_cfg); - i2s_start_channel(tx_chan); + ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, &tx_chan, NULL)); + ESP_ERROR_CHECK(i2s_channel_init_std_mode(tx_chan, &std_cfg)); + ESP_ERROR_CHECK(i2s_channel_enable(tx_chan)); #endif esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); diff --git a/examples/peripherals/i2s/i2s_adc_dac/main/app_main.c b/examples/peripherals/i2s/i2s_adc_dac/main/app_main.c index de467a6e0c..b198aeea24 100644 --- a/examples/peripherals/i2s/i2s_adc_dac/main/app_main.c +++ b/examples/peripherals/i2s/i2s_adc_dac/main/app_main.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ -/* ADC/DAC are supported in the new I2S driver, but still available in the legacy I2S driver for backward compatibility +/* ADC/DAC are not supported in the new I2S driver, but still available in the legacy I2S driver for backward compatibility * Please turn to the dedicated ADC/DAC driver instead */ #pragma message("ADC/DAC on ESP32 will no longer supported via I2S driver") @@ -286,9 +286,9 @@ void adc_read_task(void* arg) esp_adc_cal_characterize(ADC_UNIT_1, ADC_ATTEN_DB_11, ADC_WIDTH_BIT_12, V_REF, &characteristics); while(1) { uint32_t voltage; + vTaskDelay(200 / portTICK_PERIOD_MS); esp_adc_cal_get_voltage(ADC1_TEST_CHANNEL, &characteristics, &voltage); ESP_LOGI(TAG, "%d mV", voltage); - vTaskDelay(200 / portTICK_PERIOD_MS); } } diff --git a/examples/peripherals/i2s/i2s_adc_dac/pytest_i2s_adc_dac.py b/examples/peripherals/i2s/i2s_adc_dac/pytest_i2s_adc_dac.py new file mode 100644 index 0000000000..2a9af29b7b --- /dev/null +++ b/examples/peripherals/i2s/i2s_adc_dac/pytest_i2s_adc_dac.py @@ -0,0 +1,15 @@ +# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 + +import pytest +from pytest_embedded import Dut + + +@pytest.mark.esp32 +@pytest.mark.generic +def test_i2s_adc_dac_example(dut: Dut) -> None: + dut.expect('partiton addr: 0x([0-9a-fA-F]+); size: ([0-9]+); label: storage', timeout=30) + dut.expect_exact('Erasing flash', timeout=30) + dut.expect('partiton addr: 0x([0-9a-fA-F]+); size: ([0-9]+); label: storage', timeout=30) + dut.expect('Erase size: ([0-9]+) Bytes', timeout=30) + dut.expect('I \\(([0-9]+)\\) ad/da: ([0-9]+) mV', timeout=30) diff --git a/examples/peripherals/i2s/i2s_adc_dac/sdkconfig.defaults b/examples/peripherals/i2s/i2s_adc_dac/sdkconfig.defaults index 71e36947d0..9b35e20017 100644 --- a/examples/peripherals/i2s/i2s_adc_dac/sdkconfig.defaults +++ b/examples/peripherals/i2s/i2s_adc_dac/sdkconfig.defaults @@ -2,4 +2,5 @@ CONFIG_PARTITION_TABLE_CUSTOM=y CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_adc_dac_example.csv" CONFIG_PARTITION_TABLE_FILENAME="partitions_adc_dac_example.csv" CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +# ADC/DAC are only supported in the legacy driver, suppress the warnings while using the legacy driver CONFIG_I2S_SUPPRESS_DEPRECATE_WARN=y diff --git a/examples/peripherals/i2s/i2s_audio_recorder_sdcard/main/Kconfig.projbuild b/examples/peripherals/i2s/i2s_audio_recorder_sdcard/main/Kconfig.projbuild index 74d0e40ec1..da76acc070 100644 --- a/examples/peripherals/i2s/i2s_audio_recorder_sdcard/main/Kconfig.projbuild +++ b/examples/peripherals/i2s/i2s_audio_recorder_sdcard/main/Kconfig.projbuild @@ -30,12 +30,6 @@ menu "Example Configuration" menu "I2S MEMS MIC Configuration" - config EXAMPLE_I2S_CH - int "I2S Channel Number" - default 0 - help - Set the I2S channel number. - config EXAMPLE_SAMPLE_RATE int "Audio Sample Rate" default 44100 diff --git a/examples/peripherals/i2s/i2s_audio_recorder_sdcard/main/i2s_recorder_main.c b/examples/peripherals/i2s/i2s_audio_recorder_sdcard/main/i2s_recorder_main.c index de7f702dc2..f0c7c46d4f 100644 --- a/examples/peripherals/i2s/i2s_audio_recorder_sdcard/main/i2s_recorder_main.c +++ b/examples/peripherals/i2s/i2s_audio_recorder_sdcard/main/i2s_recorder_main.c @@ -22,7 +22,7 @@ #include "sdmmc_cmd.h" #include "sdkconfig.h" -static const char* TAG = "pdm_rec_example"; +static const char *TAG = "pdm_rec_example"; #define SPI_DMA_CHAN SPI_DMA_CH_AUTO #define NUM_CHANNELS (1) // For mono recording only! @@ -34,7 +34,7 @@ static const char* TAG = "pdm_rec_example"; // initialized in SPI mode, it can not be reinitialized in SD mode without // toggling power to the card. sdmmc_host_t host = SDSPI_HOST_DEFAULT(); -sdmmc_card_t* card; +sdmmc_card_t *card; i2s_chan_handle_t rx_handle = NULL; static int16_t i2s_readraw_buff[SAMPLE_SIZE]; @@ -81,7 +81,7 @@ void mount_sdcard(void) ESP_LOGE(TAG, "Failed to mount filesystem."); } else { ESP_LOGE(TAG, "Failed to initialize the card (%s). " - "Make sure SD card lines have pull-up resistors in place.", esp_err_to_name(ret)); + "Make sure SD card lines have pull-up resistors in place.", esp_err_to_name(ret)); } return; } @@ -90,17 +90,17 @@ void mount_sdcard(void) sdmmc_card_print_info(stdout, card); } -void generate_wav_header(char* wav_header, uint32_t wav_size, uint32_t sample_rate){ - +void generate_wav_header(char *wav_header, uint32_t wav_size, uint32_t sample_rate) +{ // See this for reference: http://soundfile.sapp.org/doc/WaveFormat/ uint32_t file_size = wav_size + WAVE_HEADER_SIZE - 8; uint32_t byte_rate = BYTE_RATE; const char set_wav_header[] = { - 'R','I','F','F', // ChunkID + 'R', 'I', 'F', 'F', // ChunkID file_size, file_size >> 8, file_size >> 16, file_size >> 24, // ChunkSize - 'W','A','V','E', // Format - 'f','m','t',' ', // Subchunk1ID + 'W', 'A', 'V', 'E', // Format + 'f', 'm', 't', ' ', // Subchunk1ID 0x10, 0x00, 0x00, 0x00, // Subchunk1Size (16 for PCM) 0x01, 0x00, // AudioFormat (1 for PCM) 0x01, 0x00, // NumChannels (1 channel) @@ -108,7 +108,7 @@ void generate_wav_header(char* wav_header, uint32_t wav_size, uint32_t sample_ra byte_rate, byte_rate >> 8, byte_rate >> 16, byte_rate >> 24, // ByteRate 0x02, 0x00, // BlockAlign 0x10, 0x00, // BitsPerSample (16 bits) - 'd','a','t','a', // Subchunk2ID + 'd', 'a', 't', 'a', // Subchunk2ID wav_size, wav_size >> 8, wav_size >> 16, wav_size >> 24, // Subchunk2Size }; @@ -122,12 +122,6 @@ void record_wav(uint32_t rec_time) ESP_LOGI(TAG, "Opening file"); char wav_header_fmt[WAVE_HEADER_SIZE]; - - if (rx_handle == NULL) { - ESP_LOGE(TAG, "I2S channel has not been registered yet"); - return; - } - uint32_t flash_rec_time = BYTE_RATE * rec_time; generate_wav_header(wav_header_fmt, flash_rec_time, CONFIG_EXAMPLE_SAMPLE_RATE); @@ -139,7 +133,7 @@ void record_wav(uint32_t rec_time) } // Create new WAV file - FILE* f = fopen(SD_MOUNT_POINT"/record.wav", "a"); + FILE *f = fopen(SD_MOUNT_POINT"/record.wav", "a"); if (f == NULL) { ESP_LOGE(TAG, "Failed to open file for writing"); return; @@ -151,7 +145,7 @@ void record_wav(uint32_t rec_time) // Start recording while (flash_wr_size < flash_rec_time) { // Read the RAW samples from the microphone - i2s_read_channel(rx_handle, (char *)i2s_readraw_buff, SAMPLE_SIZE, &bytes_read, 100); + i2s_channel_read(rx_handle, (char *)i2s_readraw_buff, SAMPLE_SIZE, &bytes_read, 1000); // Write the samples to the WAV file fwrite(i2s_readraw_buff, 1, bytes_read, f); flash_wr_size += bytes_read; @@ -170,8 +164,8 @@ void record_wav(uint32_t rec_time) void init_microphone(void) { - i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(CONFIG_EXAMPLE_I2S_CH, I2S_ROLE_MASTER); - i2s_new_channel(&chan_cfg, NULL, &rx_handle); + i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER); + ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, NULL, &rx_handle)); i2s_pdm_rx_config_t pdm_rx_cfg = { .clk_cfg = I2S_PDM_RX_CLK_DEFAULT_CONFIG(CONFIG_EXAMPLE_SAMPLE_RATE), @@ -179,15 +173,18 @@ void init_microphone(void) .gpio_cfg = { .clk = CONFIG_EXAMPLE_I2S_CLK_GPIO, .din = CONFIG_EXAMPLE_I2S_DATA_GPIO, + .invert_flags = { + .clk_inv = false, + }, }, }; - i2s_init_pdm_rx_channel(rx_handle, &pdm_rx_cfg); - i2s_start_channel(rx_handle); + ESP_ERROR_CHECK(i2s_channel_init_pdm_rx_mode(rx_handle, &pdm_rx_cfg)); + ESP_ERROR_CHECK(i2s_channel_enable(rx_handle)); } void app_main(void) { - ESP_LOGI(TAG, "PDM microphone recording Example start"); + printf("PDM microphone recording example start\n--------------------------------------\n"); // Mount the SDCard for recording the audio file mount_sdcard(); // Acquire a I2S PDM channel for the PDM digital microphone @@ -196,5 +193,6 @@ void app_main(void) // Start Recording record_wav(CONFIG_EXAMPLE_REC_TIME); // Stop I2S driver and destroy - ESP_ERROR_CHECK( i2s_del_channel(rx_handle) ); + ESP_ERROR_CHECK(i2s_channel_disable(rx_handle)); + ESP_ERROR_CHECK(i2s_del_channel(rx_handle)); } diff --git a/examples/peripherals/i2s/i2s_audio_recorder_sdcard/pytest_i2s_record.py b/examples/peripherals/i2s/i2s_audio_recorder_sdcard/pytest_i2s_record.py new file mode 100644 index 0000000000..7d3e48e51f --- /dev/null +++ b/examples/peripherals/i2s/i2s_audio_recorder_sdcard/pytest_i2s_record.py @@ -0,0 +1,13 @@ +# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 +import pytest +from pytest_embedded import Dut + + +@pytest.mark.esp32 +@pytest.mark.esp32s3 +@pytest.mark.generic +def test_i2s_es8311_example_generic(dut: Dut) -> None: + dut.expect('PDM microphone recording example start', timeout=30) + dut.expect('--------------------------------------', timeout=30) + dut.expect('I \\(([0-9]+)\\) pdm_rec_example: Initializing SD card', timeout=30) diff --git a/examples/peripherals/i2s/i2s_basic/README.md b/examples/peripherals/i2s/i2s_basic/README.md index c9aaa20eff..04955ab9e4 100644 --- a/examples/peripherals/i2s/i2s_basic/README.md +++ b/examples/peripherals/i2s/i2s_basic/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | -| ----------------- | ----- | +| Supported Targets | ESP32 | ESP32-S2 | ESP32-C3 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | # I2S Example @@ -11,7 +11,7 @@ In this example, we generate a 100Hz triangle and sine wave and send it out from ### Hardware Required -* A development board with ESP32 SoC (e.g., ESP32-DevKitC, ESP-WROVER-KIT, etc.) +* A development board with ESP32/ESP32-S2/ESP32-C3/ESP32-S3 SoC (e.g., ESP32-DevKitC, ESP-WROVER-KIT, etc.) * A USB cable for power supply and programming ### Configure the Project @@ -34,20 +34,50 @@ See the Getting Started Guide for full steps to configure and use ESP-IDF to bui ## Example Output -Running this example, you will see the Bits per Sample changes every 5 seconds after you have run this example. You can use `i2s_set_clk` to change the Bits per Sample and the Sample Rate. The output log can be seen below: +Running this example, you will see I2S start to read and write data, and only the first 4 elements in the receive buffer will be displayed. The output log can be seen below: ``` -Test bits=24 free mem=293780, written data=2880 -I2S: DMA Malloc info, datalen=blocksize=480, dma_desc_num=6 -I2S: PLL_D2: Req RATE: 36000, real rate: 37878.000, BITS: 24, CLKM: 11, BCK: 8, MCLK: 13837837.838, SCLK: 1818144.000000, diva: 64, divb: 36 +[i2s write] 1440 bytes are written successfully -Test bits=32 free mem=292336, written data=2880 -I2S: DMA Malloc info, datalen=blocksize=480, dma_desc_num=6 -I2S: PLL_D2: Req RATE: 36000, real rate: 36764.000, BITS: 32, CLKM: 17, BCK: 4, MCLK: 9216921.692, SCLK: 2352896.000000, diva: 64, divb: 23 +[i2s read] 8192 bytes are read successfully +---------------------------------------------- +[0] 0 [1] 0 [2] 0 [3] 0 -Test bits=16 free mem=293772, written data=1440 -I2S: DMA Malloc info, datalen=blocksize=240, dma_desc_num=6 -I2S: PLL_D2: Req RATE: 36000, real rate: 36764.000, BITS: 16, CLKM: 17, BCK: 8, MCLK: 9216921.692, SCLK: 1176448.000000, diva: 64, divb: 23 +[i2s write] 1440 bytes are written successfully +[i2s write] 1440 bytes are written successfully +[i2s write] 1440 bytes are written successfully + +[i2s read] 8192 bytes are read successfully +---------------------------------------------- +[0] a7d468d9 [1] a88a6a1d [2] a9406b58 [3] a9f66c8b + +[i2s write] 1440 bytes are written successfully +[i2s write] 1440 bytes are written successfully + +[i2s read] 8192 bytes are read successfully +---------------------------------------------- +[0] 8b622120 [1] 8c182347 [2] 8cce256c [3] 8d84278d +``` + +There is a abnormal case that printing `Data dropped`, it is caused by a long polling time of `i2s_channel_read`, please refer to the `Application Notes` section in I2S API reference. + +``` +[i2s read] 8192 bytes are read successfully +---------------------------------------------- +[0] a7d468d9 [1] a88a6a1d [2] a9406b58 [3] a9f66c8b + + +[i2s monitor] Data dropped + + +[i2s monitor] Data dropped + + +[i2s monitor] Data dropped + +[i2s write] 1440 bytes are written successfully + +[i2s monitor] Data dropped ``` If you have a logic analyzer, you can use a logic analyzer to grab online data. The following table describes the pins we use by default (Note that you can also use other pins for the same purpose). diff --git a/examples/peripherals/i2s/i2s_basic/main/i2s_example_main.c b/examples/peripherals/i2s/i2s_basic/main/i2s_example_main.c index ecf64d6ca3..414bcbe03e 100644 --- a/examples/peripherals/i2s/i2s_basic/main/i2s_example_main.c +++ b/examples/peripherals/i2s/i2s_basic/main/i2s_example_main.c @@ -9,114 +9,172 @@ */ #include #include "freertos/FreeRTOS.h" +#include "freertos/queue.h" #include "freertos/task.h" -#include "driver/i2s.h" +#include "driver/i2s_std.h" #include "driver/gpio.h" #include "esp_system.h" #include "esp_log.h" +#include "esp_attr.h" #include +#define EXAMPLE_SAMPLE_RATE (36000) +#define EXAMPLE_DATA_BIT_WIDTH (I2S_DATA_BIT_WIDTH_16BIT) -#define SAMPLE_RATE (36000) #define I2S_NUM (0) #define WAVE_FREQ_HZ (100) #define PI (3.14159265) #define I2S_BCK_IO (GPIO_NUM_4) #define I2S_WS_IO (GPIO_NUM_5) #define I2S_DO_IO (GPIO_NUM_18) -#define I2S_DI_IO (-1) +#define I2S_DI_IO (GPIO_NUM_18) /// Loopback internally if data_out and data_in signal are bound to a same GPIO -#define SAMPLE_PER_CYCLE (SAMPLE_RATE/WAVE_FREQ_HZ) +#define SAMPLE_PER_CYCLE (EXAMPLE_SAMPLE_RATE/WAVE_FREQ_HZ) -static const char* TAG = "i2s_example"; +static i2s_chan_handle_t tx_handle = NULL; +static i2s_chan_handle_t rx_handle = NULL; -static void setup_triangle_sine_waves(int bits) +static volatile int is_overflow = 0; + +static uint32_t* example_generate_triangle_sine_waves(int bits, uint32_t *buf_len) { - int *samples_data = malloc(((bits+8)/16)*SAMPLE_PER_CYCLE*4); - unsigned int i, sample_val; - double sin_float, triangle_float, triangle_step = (double) pow(2, bits) / SAMPLE_PER_CYCLE; - size_t i2s_bytes_write = 0; + uint32_t len = ((bits + 8) / 16)*SAMPLE_PER_CYCLE * 4; + uint32_t *samples_data = malloc(len); - printf("\r\nTest bits=%d free mem=%d, written data=%d\n", bits, esp_get_free_heap_size(), ((bits+8)/16)*SAMPLE_PER_CYCLE*4); + double triangle_float = -(pow(2, bits) / 2 - 1); + double triangle_step = (double) pow(2, bits) / SAMPLE_PER_CYCLE; - triangle_float = -(pow(2, bits)/2 - 1); - - for(i = 0; i < SAMPLE_PER_CYCLE; i++) { - sin_float = sin(i * 2 * PI / SAMPLE_PER_CYCLE); - if(sin_float >= 0) + for (int i = 0; i < SAMPLE_PER_CYCLE; i++) { + double sin_float = sin(i * 2 * PI / SAMPLE_PER_CYCLE); + if (sin_float >= 0) { triangle_float += triangle_step; - else - triangle_float -= triangle_step; - - sin_float *= (pow(2, bits)/2 - 1); - - if (bits == 16) { - sample_val = 0; - sample_val += (short)triangle_float; - sample_val = sample_val << 16; - sample_val += (short) sin_float; - samples_data[i] = sample_val; - } else if (bits == 24) { //1-bytes unused - samples_data[i*2] = ((int) triangle_float) << 8; - samples_data[i*2 + 1] = ((int) sin_float) << 8; } else { - samples_data[i*2] = ((int) triangle_float); - samples_data[i*2 + 1] = ((int) sin_float); + triangle_float -= triangle_step; + } + sin_float *= (pow(2, bits) / 2 - 1); + if (bits == 16) { + samples_data[i] = ((short)triangle_float << 16) | (short)sin_float; + } else if (bits == 24) { //1-bytes unused + samples_data[i * 2] = ((int) triangle_float) << 8; + samples_data[i * 2 + 1] = ((int) sin_float) << 8; + } else { + samples_data[i * 2] = ((int) triangle_float); + samples_data[i * 2 + 1] = ((int) sin_float); } } - ESP_LOGI(TAG, "set clock"); - i2s_set_clk(I2S_NUM, SAMPLE_RATE, bits, 2); - //Using push - // for(i = 0; i < SAMPLE_PER_CYCLE; i++) { - // if (bits == 16) - // i2s_push_sample(0, &samples_data[i], 100); - // else - // i2s_push_sample(0, &samples_data[i*2], 100); - // } - // or write - ESP_LOGI(TAG, "write data"); - i2s_write(I2S_NUM, samples_data, ((bits+8)/16)*SAMPLE_PER_CYCLE*4, &i2s_bytes_write, 100); + *buf_len = len; + return samples_data; +} - free(samples_data); +static IRAM_ATTR bool i2s_rx_queue_overflow_callback(i2s_chan_handle_t handle, i2s_event_data_t *event, void *user_ctx) +{ + is_overflow++; + return false; +} + +static void example_i2s_read_task(void * args) +{ + uint32_t *rx_buf = calloc(1, 8192); + size_t bytes_read = 0; + uint32_t cnt = 0; + + while (1) { + if (i2s_channel_read(rx_handle, rx_buf, 8192, &bytes_read, 1000) == ESP_OK) { + if (cnt == 0) { + printf("\n[i2s read] %d bytes are read successfully\n", bytes_read); + printf("----------------------------------------------\n"); + printf("[0] %4x [1] %4x [2] %4x [3] %4x\n\n", rx_buf[0], rx_buf[1], rx_buf[2], rx_buf[3]); + } + cnt++; + cnt %= 10; + /* If the polling time is too long, there will be data dropped event */ + // vTaskDelay(10); + } else { + printf("[i2s read] %d bytes are read, timeout triggered\n\n", bytes_read); + } + } + vTaskDelete(NULL); +} + +static void example_i2s_write_task(void * args) +{ + uint32_t buf_len = 0; + uint32_t *tx_buf = example_generate_triangle_sine_waves(EXAMPLE_DATA_BIT_WIDTH, &buf_len); + size_t bytes_written = 0; + uint32_t cnt = 0; + + while (1) { + if (i2s_channel_write(tx_handle, tx_buf, buf_len, &bytes_written, 1000) == ESP_OK) { + if (cnt == 0) { + printf("[i2s write] %d bytes are written successfully\n", bytes_written); + } + cnt++; + cnt %= 20; + } else { + printf("[i2s write] %d bytes are written, timeout triggered\n", bytes_written); + } + } + vTaskDelete(NULL); +} + +static void example_i2s_init_std_duplex(void) +{ + i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER); + /* Giving both tx and rx handle will make the i2s works in full-duplex mode and can share the bclk and ws signal */ + ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle)); + i2s_std_config_t std_cfg = { + .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(EXAMPLE_SAMPLE_RATE), + .slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(EXAMPLE_DATA_BIT_WIDTH, I2S_SLOT_MODE_STEREO), + .gpio_cfg = { + .mclk = I2S_GPIO_UNUSED, + .bclk = I2S_BCK_IO, + .ws = I2S_WS_IO, + .dout = I2S_DO_IO, + .din = I2S_DI_IO, + .invert_flags = { + .mclk_inv = false, + .bclk_inv = false, + .ws_inv = false, + }, + }, + }; +#if SOC_I2S_SUPPORTS_APLL + // APLL clock is more accurate when sample rate is high + std_cfg.clk_cfg.clk_src = I2S_CLK_SRC_APLL; +#endif + /* Initialize the tx channel handle to standard mode */ + ESP_ERROR_CHECK(i2s_channel_init_std_mode(tx_handle, &std_cfg)); + /* Initialize the rx channel handle to standard mode */ + ESP_ERROR_CHECK(i2s_channel_init_std_mode(rx_handle, &std_cfg)); + + printf("I2S tx and rx channels have been initialized to standard duplex mode\n"); + + i2s_event_callbacks_t cbs = { + .on_recv = NULL, + .on_recv_q_ovf = i2s_rx_queue_overflow_callback, + .on_sent = NULL, + .on_send_q_ovf = NULL, + }; + ESP_ERROR_CHECK(i2s_channel_register_event_callback(rx_handle, &cbs, NULL)); + + ESP_ERROR_CHECK(i2s_channel_enable(tx_handle)); + ESP_ERROR_CHECK(i2s_channel_enable(rx_handle)); + printf("I2S tx and rx channels enabled\n"); } void app_main(void) { //for 36Khz sample rates, we create 100Hz sine wave, every cycle need 36000/100 = 360 samples (4-bytes or 8-bytes each sample) - //depend on bits_per_sample - //using 6 buffers, we need 60-samples per buffer - //if 2-channels, 16-bit each channel, total buffer is 360*4 = 1440 bytes - //if 2-channels, 24/32-bit each channel, total buffer is 360*8 = 2880 bytes - i2s_config_t i2s_config = { - .mode = I2S_MODE_MASTER | I2S_MODE_TX, - .sample_rate = SAMPLE_RATE, - .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, - .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, - .communication_format = I2S_COMM_FORMAT_STAND_MSB, - .dma_desc_num = 6, - .dma_frame_num = 60, - .use_apll = false, - .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1 //Interrupt level 1 - }; - i2s_pin_config_t pin_config = { - .mck_io_num = I2S_PIN_NO_CHANGE, - .bck_io_num = I2S_BCK_IO, - .ws_io_num = I2S_WS_IO, - .data_out_num = I2S_DO_IO, - .data_in_num = I2S_DI_IO //Not used - }; - i2s_driver_install(I2S_NUM, &i2s_config, 0, NULL); - i2s_set_pin(I2S_NUM, &pin_config); + example_i2s_init_std_duplex(); + xTaskCreate(example_i2s_write_task, "i2s write task", 4096, NULL, 5, NULL); + xTaskCreate(example_i2s_read_task, "i2s read task", 8192, NULL, 5, NULL); - int test_bits = 16; while (1) { - setup_triangle_sine_waves(test_bits); - vTaskDelay(5000/portTICK_PERIOD_MS); - test_bits += 8; - if(test_bits > 32) - test_bits = 16; - + if (is_overflow > 0) { + printf("[i2s monitor] RX message Queue overflowed\n"); + is_overflow--; + } + vTaskDelay(1); } - } diff --git a/examples/peripherals/i2s/i2s_basic/pytest_i2s_basic.py b/examples/peripherals/i2s/i2s_basic/pytest_i2s_basic.py new file mode 100644 index 0000000000..691aa7f186 --- /dev/null +++ b/examples/peripherals/i2s/i2s_basic/pytest_i2s_basic.py @@ -0,0 +1,18 @@ +# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 + +import pytest +from pytest_embedded import Dut + + +@pytest.mark.esp32 +@pytest.mark.esp32s2 +@pytest.mark.esp32s3 +@pytest.mark.esp32c3 +@pytest.mark.generic +def test_i2s_basic_example(dut: Dut) -> None: + dut.expect_exact('I2S tx and rx channels have been initialized to standard duplex mode', timeout=30) + dut.expect_exact('I2S tx and rx channels enabled', timeout=30) + dut.expect_exact('[i2s write] 1440 bytes are written successfully', timeout=30) + dut.expect_exact('', timeout=30) + dut.expect_exact('[i2s read] 8192 bytes are read successfully', timeout=30) diff --git a/examples/peripherals/i2s/i2s_basic/sdkconfig.defaults b/examples/peripherals/i2s/i2s_basic/sdkconfig.defaults deleted file mode 100644 index ed0a8a90d9..0000000000 --- a/examples/peripherals/i2s/i2s_basic/sdkconfig.defaults +++ /dev/null @@ -1 +0,0 @@ -CONFIG_I2S_SUPPRESS_DEPRECATE_WARN=y diff --git a/examples/peripherals/i2s/i2s_basic_new/CMakeLists.txt b/examples/peripherals/i2s/i2s_basic_new/CMakeLists.txt deleted file mode 100644 index ffc1310d66..0000000000 --- a/examples/peripherals/i2s/i2s_basic_new/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -# The following lines of boilerplate have to be in your project's CMakeLists -# in this exact order for cmake to work correctly -cmake_minimum_required(VERSION 3.5) - -include($ENV{IDF_PATH}/tools/cmake/project.cmake) -project(esp32_i2s_driver_example) diff --git a/examples/peripherals/i2s/i2s_basic_new/README.md b/examples/peripherals/i2s/i2s_basic_new/README.md deleted file mode 100644 index 0b0a9d3913..0000000000 --- a/examples/peripherals/i2s/i2s_basic_new/README.md +++ /dev/null @@ -1,98 +0,0 @@ -| Supported Targets | ESP32 | ESP32-S2 | ESP32-C3 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | - -# I2S Example - -(See the README.md file in the upper level 'examples' directory for more information about examples.) - -In this example, we generate a 100Hz triangle and sine wave and send it out from left and right channels at a sample rate of 36kHz through the I2S bus. - -## How to Use Example - -### Hardware Required - -* A development board with ESP32/ESP32-S2/ESP32-C3/ESP32-S3 SoC (e.g., ESP32-DevKitC, ESP-WROVER-KIT, etc.) -* A USB cable for power supply and programming - -### Configure the Project - -``` -idf.py menuconfig -``` - -### Build and Flash - -Build the project and flash it to the board, then run monitor tool to view serial output: - -``` -idf.py -p PORT flash monitor -``` - -(To exit the serial monitor, type ``Ctrl-]``.) - -See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects. - -## Example Output - -Running this example, you will see I2S start to read and write data, and only the first 4 elements in the receive buffer will be displayed. The output log can be seen below: - -``` -[i2s write] 1440 bytes are written successfully - -[i2s read] 8192 bytes are read successfully ----------------------------------------------- -[0] 0 [1] 0 [2] 0 [3] 0 - -[i2s write] 1440 bytes are written successfully -[i2s write] 1440 bytes are written successfully -[i2s write] 1440 bytes are written successfully - -[i2s read] 8192 bytes are read successfully ----------------------------------------------- -[0] a7d468d9 [1] a88a6a1d [2] a9406b58 [3] a9f66c8b - -[i2s write] 1440 bytes are written successfully -[i2s write] 1440 bytes are written successfully - -[i2s read] 8192 bytes are read successfully ----------------------------------------------- -[0] 8b622120 [1] 8c182347 [2] 8cce256c [3] 8d84278d -``` - -There is a abnormal case that printing `Data dropped`, it is caused by a long polling time of `i2s_read_channel`, please refer to the `Application Notes` section in I2S API reference. - -``` -[i2s read] 8192 bytes are read successfully ----------------------------------------------- -[0] a7d468d9 [1] a88a6a1d [2] a9406b58 [3] a9f66c8b - - -[i2s monitor] Data dropped - - -[i2s monitor] Data dropped - - -[i2s monitor] Data dropped - -[i2s write] 1440 bytes are written successfully - -[i2s monitor] Data dropped -``` - -If you have a logic analyzer, you can use a logic analyzer to grab online data. The following table describes the pins we use by default (Note that you can also use other pins for the same purpose). - -| pin name| function | gpio_num | -|:---:|:---:|:---:| -| WS |word select| GPIO_NUM_15 | -| SCK |continuous serial clock| GPIO_NUM_13 | -| SD |serial data| GPIO_NUM_21 | - -## Troubleshooting - -* Program upload failure - - * Hardware connection is not correct: run `idf.py -p PORT monitor`, and reboot your board to see if there are any output logs. - * The baud rate for downloading is too high: lower your baud rate in the `menuconfig` menu, and try again. - -For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon. diff --git a/examples/peripherals/i2s/i2s_basic_new/main/CMakeLists.txt b/examples/peripherals/i2s/i2s_basic_new/main/CMakeLists.txt deleted file mode 100644 index 4c583513cd..0000000000 --- a/examples/peripherals/i2s/i2s_basic_new/main/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -idf_component_register(SRCS "i2s_example_main.c" - INCLUDE_DIRS ".") diff --git a/examples/peripherals/i2s/i2s_basic_new/main/i2s_example_main.c b/examples/peripherals/i2s/i2s_basic_new/main/i2s_example_main.c deleted file mode 100644 index a9c8e2c0ee..0000000000 --- a/examples/peripherals/i2s/i2s_basic_new/main/i2s_example_main.c +++ /dev/null @@ -1,166 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Unlicense OR CC0-1.0 - */ -/* I2S Example - * This example code will output 100Hz sine wave and triangle wave to 2-channel of I2S driver - * Every 5 seconds, it will change bits_per_sample [16, 24, 32] for i2s data - */ -#include -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "driver/i2s_std.h" -#include "driver/gpio.h" -#include "esp_system.h" -#include "esp_log.h" -#include - -#define EXAMPLE_SAMPLE_RATE (36000) -#define EXAMPLE_DATA_BIT_WIDTH (I2S_DATA_BIT_WIDTH_16BIT) - -#define I2S_NUM (0) -#define WAVE_FREQ_HZ (100) -#define PI (3.14159265) -#define I2S_BCK_IO (GPIO_NUM_4) -#define I2S_WS_IO (GPIO_NUM_5) -#define I2S_DO_IO (GPIO_NUM_18) -#define I2S_DI_IO (GPIO_NUM_18) /// Loopback internally if data_out and data_in signal are bound to a same GPIO - -#define SAMPLE_PER_CYCLE (EXAMPLE_SAMPLE_RATE/WAVE_FREQ_HZ) - -static i2s_chan_handle_t tx_handle = NULL; -static i2s_chan_handle_t rx_handle = NULL; - -static uint32_t* example_generate_triangle_sine_waves(int bits, uint32_t *buf_len) -{ - uint32_t len = ((bits + 8) / 16)*SAMPLE_PER_CYCLE * 4; - uint32_t *samples_data = malloc(len); - - double triangle_float = -(pow(2, bits) / 2 - 1); - double triangle_step = (double) pow(2, bits) / SAMPLE_PER_CYCLE; - - for (int i = 0; i < SAMPLE_PER_CYCLE; i++) { - double sin_float = sin(i * 2 * PI / SAMPLE_PER_CYCLE); - if (sin_float >= 0) { - triangle_float += triangle_step; - } else { - triangle_float -= triangle_step; - } - sin_float *= (pow(2, bits) / 2 - 1); - if (bits == 16) { - samples_data[i] = ((short)triangle_float << 16) | (short)sin_float; - } else if (bits == 24) { //1-bytes unused - samples_data[i * 2] = ((int) triangle_float) << 8; - samples_data[i * 2 + 1] = ((int) sin_float) << 8; - } else { - samples_data[i * 2] = ((int) triangle_float); - samples_data[i * 2 + 1] = ((int) sin_float); - } - - } - *buf_len = len; - return samples_data; -} - -static void example_i2s_monitor_task(void * args) -{ - QueueHandle_t evt_que = *(QueueHandle_t*)args; - i2s_event_t event; - while (1) { - if (xQueueReceive(evt_que, &event, portMAX_DELAY) == pdTRUE) { - if (event.type == I2S_EVENT_RX_Q_OVF) { - /* When the rx message queue is overflow, the data in oldest DMA buffer will be dropped */ - printf("\n[i2s monitor] Data dropped\n\n"); - } - } - } - vTaskDelete(NULL); -} - -static void example_i2s_read_task(void * args) -{ - uint32_t *rx_buf = calloc(1, 8192); - uint32_t bytes_read = 0; - uint32_t cnt = 0; - - while (1) { - if (i2s_read_channel(rx_handle, rx_buf, 8192, &bytes_read, 100) == ESP_OK) { - if (cnt == 0) { - printf("\n[i2s read] %d bytes are read successfully\n", bytes_read); - printf("----------------------------------------------\n"); - printf("[0] %4x [1] %4x [2] %4x [3] %4x\n\n", rx_buf[0], rx_buf[1], rx_buf[2], rx_buf[3]); - } - cnt++; - cnt %= 10; - /* If the polling time is too long, there will be data dropped event */ - // vTaskDelay(10); - } else { - printf("[i2s read] %d bytes are read, timeout triggered\n\n", bytes_read); - } - } - vTaskDelete(NULL); -} - -static void example_i2s_write_task(void * args) -{ - uint32_t buf_len = 0; - uint32_t *tx_buf = example_generate_triangle_sine_waves(EXAMPLE_DATA_BIT_WIDTH, &buf_len); - uint32_t bytes_written = 0; - uint32_t cnt = 0; - - while (1) { - if (i2s_write_channel(tx_handle, tx_buf, buf_len, &bytes_written, 1000) == ESP_OK) { - if (cnt == 0) { - printf("[i2s write] %d bytes are written successfully\n", bytes_written); - } - cnt++; - cnt %= 20; - } else { - printf("[i2s write] %d bytes are written, timeout triggered\n", bytes_written); - } - } - vTaskDelete(NULL); -} - -static void example_i2s_init_std_duplex(void) -{ - i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER); - /* Giving both tx and rx handle will make the i2s works in full-duplex mode and can share the bclk and ws signal */ - ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle)); - i2s_std_config_t std_cfg = { - .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(EXAMPLE_SAMPLE_RATE), - .slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(EXAMPLE_DATA_BIT_WIDTH, I2S_SLOT_MODE_STEREO), - .gpio_cfg = { - .mclk = I2S_GPIO_UNUSED, - .bclk = I2S_BCK_IO, - .ws = I2S_WS_IO, - .dout = I2S_DO_IO, - .din = I2S_DI_IO, - }, - }; -#if SOC_I2S_SUPPORTS_APLL - // APLL clock is more accurate when sample rate is high - std_cfg.clk_cfg.clk_src = I2S_CLK_APLL; -#endif - /* Initialize the tx channel handle to standard mode */ - ESP_ERROR_CHECK(i2s_init_std_channel(tx_handle, &std_cfg)); - /* Initialize the rx channel handle to standard mode */ - ESP_ERROR_CHECK(i2s_init_std_channel(rx_handle, &std_cfg)); - - ESP_ERROR_CHECK(i2s_start_channel(tx_handle)); - ESP_ERROR_CHECK(i2s_start_channel(rx_handle)); -} - -void app_main(void) -{ - //for 36Khz sample rates, we create 100Hz sine wave, every cycle need 36000/100 = 360 samples (4-bytes or 8-bytes each sample) - example_i2s_init_std_duplex(); - - // Acquire I2S rx channel event queue handle for monitoring whether the received data dropped - QueueHandle_t evt_que = i2s_get_event_queue(rx_handle, 16); - - xTaskCreate(example_i2s_write_task, "i2s write task", 4096, NULL, 5, NULL); - xTaskCreate(example_i2s_read_task, "i2s read task", 8192, NULL, 5, NULL); - xTaskCreate(example_i2s_monitor_task, "i2s monitor task", 4096, &evt_que, 5, NULL); -} diff --git a/examples/peripherals/i2s/i2s_es8311/README.md b/examples/peripherals/i2s/i2s_es8311/README.md index fa3a2363ab..c0dfffed99 100644 --- a/examples/peripherals/i2s/i2s_es8311/README.md +++ b/examples/peripherals/i2s/i2s_es8311/README.md @@ -65,7 +65,7 @@ The component can be installed by esp component manager. Since this example alre idf.py add-dependency espressif/es8311==0.0.2-alpha ``` -If dependency is added, you can check `idf_component.yml` for more detail. When building this example or other project with managed-component in it, the component manager will search the componet online and download it under `managed_componets` folder. +If the dependency is added, you can check `idf_component.yml` for more detail. When building this example or other project with managed component in it, the component manager will search the component online and download it under the `managed_componets` folder. ### Configure the Project @@ -137,7 +137,7 @@ The example have contained a piece of music in canon.pcm, if you want to play yo 5. Transfer the music format into .pcm. ```ffmpeg -i a_cut.mp3 -f s16ls -ar 16000 -ac -1 -acodec pcm_s16le a.pcm``` 6. Move 'a.pcm' under 'main' directory 7. Replace 'canon.pcm' with 'a.pcm' in 'CMakeLists.txt' under 'main' directory -8. Replace '_binary_canon_pcm_start' and '_binary_canon_pcm_end' with '_binary_a_pcm_start' and '_binary_a_pcm_end' in `i2s_es8311_example.c`(line 46/47) +8. Replace '_binary_canon_pcm_start' and '_binary_canon_pcm_end' with '_binary_a_pcm_start' and '_binary_a_pcm_end' in `i2s_es8311_example.c` 9. Download the example and enjoy your own music ## Troubleshooting diff --git a/examples/peripherals/i2s/i2s_es8311/main/i2s_es8311_example.c b/examples/peripherals/i2s/i2s_es8311/main/i2s_es8311_example.c index 4f3716c7d8..984796d9c0 100644 --- a/examples/peripherals/i2s/i2s_es8311/main/i2s_es8311_example.c +++ b/examples/peripherals/i2s/i2s_es8311/main/i2s_es8311_example.c @@ -97,14 +97,19 @@ static esp_err_t i2s_driver_init(void) .bclk = GPIO_NUM_4, .ws = GPIO_NUM_5, .dout = GPIO_NUM_18, - .din = GPIO_NUM_19 + .din = GPIO_NUM_19, + .invert_flags = { + .mclk_inv = false, + .bclk_inv = false, + .ws_inv = false, + }, }, }; - ESP_ERROR_CHECK(i2s_init_std_channel(tx_handle, &std_cfg)); - ESP_ERROR_CHECK(i2s_init_std_channel(rx_handle, &std_cfg)); - ESP_ERROR_CHECK(i2s_start_channel(tx_handle)); - ESP_ERROR_CHECK(i2s_start_channel(rx_handle)); + ESP_ERROR_CHECK(i2s_channel_init_std_mode(tx_handle, &std_cfg)); + ESP_ERROR_CHECK(i2s_channel_init_std_mode(rx_handle, &std_cfg)); + ESP_ERROR_CHECK(i2s_channel_enable(tx_handle)); + ESP_ERROR_CHECK(i2s_channel_enable(rx_handle)); return ESP_OK; } @@ -113,18 +118,14 @@ static void i2s_music(void *args) { esp_err_t ret = ESP_OK; size_t bytes_write = 0; - if (tx_handle == NULL) { - ESP_LOGE(TAG, "[music] i2s tx channel has not been registered yet"); - abort(); - } while (1) { /* Write music to earphone */ - ret = i2s_write_channel(tx_handle, music_pcm_start, music_pcm_end - music_pcm_start, &bytes_write, portMAX_DELAY); + ret = i2s_channel_write(tx_handle, music_pcm_start, music_pcm_end - music_pcm_start, &bytes_write, portMAX_DELAY); if (ret != ESP_OK) { - /* Since we set timeout to 'portMAX_DELAY' in 'i2s_write_channel' + /* Since we set timeout to 'portMAX_DELAY' in 'i2s_channel_write' so you won't reach here unless you set other timeout value, if timeout detected, it means write operation failed. */ - ESP_LOGE(TAG, "[music] i2s read failed, %s", err_reason[ret == ESP_ERR_TIMEOUT]); + ESP_LOGE(TAG, "[music] i2s write failed, %s", err_reason[ret == ESP_ERR_TIMEOUT]); abort(); } if (bytes_write > 0) { @@ -141,10 +142,6 @@ static void i2s_music(void *args) #else static void i2s_echo(void *args) { - if (rx_handle == NULL || tx_handle == NULL) { - ESP_LOGE(TAG, "[echo] i2s rx or tx channel has not been registered yet"); - abort(); - } int *mic_data = malloc(EXAMPLE_RECV_BUF_SIZE); if (!mic_data) { ESP_LOGE(TAG, "[echo] No memory for read data buffer"); @@ -158,13 +155,13 @@ static void i2s_echo(void *args) while (1) { memset(mic_data, 0, EXAMPLE_RECV_BUF_SIZE); /* Read sample data from mic */ - ret = i2s_read_channel(rx_handle, mic_data, EXAMPLE_RECV_BUF_SIZE, &bytes_read, 100); + ret = i2s_channel_read(rx_handle, mic_data, EXAMPLE_RECV_BUF_SIZE, &bytes_read, 1000); if (ret != ESP_OK) { ESP_LOGE(TAG, "[echo] i2s read failed, %s", err_reason[ret == ESP_ERR_TIMEOUT]); abort(); } /* Write sample data to earphone */ - ret = i2s_write_channel(tx_handle, mic_data, EXAMPLE_RECV_BUF_SIZE, &bytes_write, 100); + ret = i2s_channel_write(tx_handle, mic_data, EXAMPLE_RECV_BUF_SIZE, &bytes_write, 1000); if (ret != ESP_OK) { ESP_LOGE(TAG, "[echo] i2s write failed, %s", err_reason[ret == ESP_ERR_TIMEOUT]); abort(); @@ -179,15 +176,20 @@ static void i2s_echo(void *args) void app_main(void) { + printf("i2s es8311 codec example start\n-----------------------------\n"); /* Initialize i2s peripheral */ if (i2s_driver_init() != ESP_OK) { ESP_LOGE(TAG, "i2s driver init failed"); abort(); + } else { + ESP_LOGI(TAG, "i2s driver init success"); } /* Initialize i2c peripheral and config es8311 codec by i2c */ if (es8311_codec_init() != ESP_OK) { ESP_LOGE(TAG, "es8311 codec init failed"); abort(); + } else { + ESP_LOGI(TAG, "es8311 codec init success"); } #if CONFIG_EXAMPLE_MODE_MUSIC /* Play a piece of music in music mode */ diff --git a/examples/peripherals/i2s/i2s_es8311/pytest_i2s_es8311.py b/examples/peripherals/i2s/i2s_es8311/pytest_i2s_es8311.py new file mode 100644 index 0000000000..51fb648239 --- /dev/null +++ b/examples/peripherals/i2s/i2s_es8311/pytest_i2s_es8311.py @@ -0,0 +1,16 @@ +# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 + +import pytest +from pytest_embedded import Dut + + +@pytest.mark.esp32 +@pytest.mark.esp32s2 +@pytest.mark.esp32s3 +@pytest.mark.esp32c3 +@pytest.mark.generic +def test_i2s_es8311_example_generic(dut: Dut) -> None: + dut.expect('i2s es8311 codec example start', timeout=30) + dut.expect('-----------------------------', timeout=30) + dut.expect('I \\(([0-9]+)\\) i2s_es8311: i2s driver init success', timeout=30)

r#d# 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 literal 0 HcmV?d00001 diff --git a/docs/_static/diagrams/i2s/pdm.png b/docs/_static/diagrams/i2s/pdm.png new file mode 100644 index 0000000000000000000000000000000000000000..0228d1838f7e247e5e71b861db703136ccd5c3a4 GIT binary patch literal 81899 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%0A5uV1}d`Tvcx&+OIJpWoP+e15*YI9Kbt zckklj;lZ|-wOt|wsT9adU|-wFidt^?l+f-nHiL#^(W;tK|!0!-rjokDr=^X zn21P9MutW4GoOV4pgYq+3+M9hcO88cx3>z^gywPXTC^?qcG>@bf9wAKl9ZO7JTFyP z%_m_`uHsa$ei_S0uU<(B2`!ot-RUAECpT~6#DzO1#@*Xr|Nryz^Xk5{OcD+-9JNkt z=aUuFi&?R5ot&s>>AO2SKYaKwzy9CNLx&C>IB?*^iH>*D5m8Z94-Pag_n-gj_3OzhQ}_3m?>w8Ceft+IcyMK9@XMDk^YZc*yY-$rc~WufMpaeS|3A;yfBE`#x^8q@ zR+d%H4Fh@k`L(~lwYImfkJ#uG+0Zv(qryawZ8|5B{Nr%##cTbr*b*^>! zyH{6NH?#51vMyiO-tL}kYb15&@BQ6@J01GBm8S~lByz;;EINAj?AqFOhVt_B*;W@x zMrM^w&8zP3>QZXdkJ$m5P!GH^O*i^U(a%>`S6{tyB_}u6y6lZd+%_I=ZqRm-SF6|W zh|!yUcH4#x1w}#o&{}yA90jd~4RMSrT0b zI$|s?PH(DLY;5e+t5^GFES=t8jksOy=XY*_WAl$1(5*S|-n=>U_~V>8bL4C)1Ox;e zqNICzdu?rP|Nr^yZ)|KV)~zbQF=x)4KY#yvzMdbVrP}}C;K73>QD2-23k@sxeEa&9 zmxt%c=byZC+?@W~_x}HOJ3r<0+uPgEo;|DC#l^`v(QB#qG#$mi2`8mHb;Pp&{`#7l znhM%-9iWl2F(NH3&Cky-dRtEAj}HqQ8yjcNoVj=J-d($_x{toPzCPa3k#VkJm806^ zt5>g1tUM}u`>d9>wrA|Vq}kGUzx{i4RePpS*~?3+7k8iEn0)+6(a&|UyEVFA-Q1jB zSXk)j$S66n@%ZD3%lx_)?fdmgduNQ_t$UU-e6g(upB5cHbSNu3yPZeU>CDa2+ikr01|;R?c5b%$`@Q$m@dH|l`AJsoH%%}agS|cdiwWAN4t&F z&rP_rb=Is|lP6!E9$yz38Ts<@>r!J+G9_=a!U~T9>?Vkdw5OIrr-7YR~_<-*)?7Ul+^F z%$$B^hU2mL7Z(;bPo5m?;=xpP6~gzlAV+D=D`DpUq{MbUD33* z{{8OmZdvQHl#LNFde={$JbC=My0&)quP-l`RGz(ZWyglKb|9-uG zadGjI&fDkD_uqN`{oUQuk3ZVj+GaX~W5ZK9tF+Wq(_QfSpFe*<*Rd~JapHu>&X|4G z-}5#`_ykV*akqVu#;1D%wd|nl*rYSxzJ0rS(pWJU0p5t^Z$gaPoAW>-CP!W-S0GWc1A{zr17$+wma>fEVxyF|JScy%<5z|LWDNlP6E6Og}r@d~<{jFK@4Q__`BMKdp=1{p#gQOACt$ zpJp^R9-M1kE+i~$UH0Zg+Gb0czR8m(PoEy{=60-&SK4EH7B@HdrNGpSi(Gq-FWjDg zA9Qe>h^kPhiK*$yYLmXcz9p+;Yiev>dIg7txjo;%aohJ9GbDn8gPolZ*Zut!84M z6VwV151)Se>AJYRx6YpR_4UoYy)C!vy2V`EoiTp1WK2y=;`UT1PCuP$baR$zc7)Ef zY16`-oSI_v>W_OV6G>IXO4??8AZ^Ic3xJVr^_~g@uJZuQO|FYiDO?H#!_h z+PKVr{<=HH*;iHsrerYl^70nd8H+)hr5l@8*aE>Ftb1E)ABMC`Bo`}lbONj)36^XJZ;J9)BGVp5d1 zudi=<`tvz+WUP$O>V<@d*FWIcs=Mcuh0Hne_?p7U$9mH?e|gW@uCH%~?*KGqw)K5pV8M$dKo_RZUqlarF7BGjqT zrKIn_ukv$SfvURt>=`pkUSC_g@y*1yMl*A+uZs;|A17;+a^lX;Vr^~h|DWgoS5Z@o z+g}IT;B$R_yuYXCOsmpYJ(9*Irl#H9-JqH)DM?6J`0(S89-cjC({}IP{r}(Z_a8rg zOp(z!DzbIU7B!z4AKu*DJY$ALqk}=_r6oTsPF}u_g2J#l`OD=USUretM$nJ#CJCy`8NsXl(IG=>J{2 zcAYrk;q2_(=~DFj+gnxdX-AG9PftzNoGy1VVgITAjHgeZ_RHIE+q5ZbLt*B%HIX`E z+M1dx_wD=Ft-tTXhYtxU|E{bIHqXB&!qsYB{_f4SwYT;6|0#NMLeOo7W%09;_xEbQ zzPf6jf6u1=-=9OR+~I2?3@bl9d47I=dt2MC-Mc5ZOLQ%I^Y*Q;udlpK#e}I-uSW12 zx;@d2oNJtZ?#0E$(L$R#4UYH8{(igtz7)@ar$uYmtO1Rk*Vor?jIb$qaDY=-E$7CD zhnJRmFHv)?)ZZAfC-w9+{>-i^9x6|tJ_R)w|M#9cxwWj@Lq*Ck>BvIo_PD)OQ)kc4 zPD$C4c$iIBS9hYvlxfqpReXH({QUg;yURf%!k3r%a`W} zz5B7EwYBy1G+l2GkB-jHj~_oKK55L;S+#cU-s0zc-A7;D-@o5MVZzB2etEk!D_0hl zmxuo=Pjvz9v99@9v@+z^=kxZ~78Xa2AJ>oDW1*#W>i+%z&*#^JCWIgdzPTt(jL`#~ zK~q=vZ;oa0u|8Sv`za+QB{4BEj~+eRw0X1Sc0sXj(}D*M>gvn)|Nl4p3)79g)#Z+k zj`Qtmca^-{RQdVYvUsB>1s2K2z{}an%F62M_D!97_1)dwpsI(j;N_*I{`2i>e|&hj zz_FQ$nYsSgOZ7{2=bjev^78Kg`AquLvCPcOm#?m_PEJl*Zc8Bs!di^Q@eKkx_L&$&reS|h1EnvMDFaXy?x?D#<3nrp69!E?TWAe zyLHW)Gslmo-`tdX_3G7A;``>#jSUD0@bf$O=jZ3*qM~>A_k&Ks2VKhf^wiY5yUXuy zOm5${&CGUL^YZ2CDJdyIK|!UZrI#~$KHomFYU|doA0Ho={(Uhg$^Gd1dwVKBgU&{; z{^nDt9GSK;V%Dr#a&mHvjEr}8m9Ab7YJvy9lUlatv3<68WaP}{%a?a|pMH3_9o$qf zmd>u@=j4>MtNGC`6B`&fapugKK5D@^*144}&TTvwFJIQy(W&|Lq_e&K_^Yd{d3kwn z=6pLnU0+;3?$48xlTT0AKR?@C-@?K|L!;yPN_$V!sr>V!(9NxF@#5s9q@>*3wX0XJ zF4}K)v{tig)%x}PoSd4vy1aaR@2;aPk`ua*#MrO^zg$Eyh zytk)vbIQp{pbOWI9O02LP|(rox$^Pt?d|6;TmX#2y z3kxkREqVX7e0_i4-oylSfR%y4ggfbb_Ut)z`m|@d$tB}Oixw$aTF%^aA~`+X{asG4 zujhn`69WSR5>is0JbHA9q4MXar)Opwzkc=V-Mzi1pB5eOm0tcw?@Xt#dfwe#OV_Ub z`+R=Am4!u1TbrA^yY{ie4-1-_nm`w%%E-)_GUdzl_>}+{PQb zyKL#~kJe>xGLn-&zqz@2(j=j(#Ys85dY^y(;gvRZ zr!MR$e7rgR{FKu-%=7Mmmg5#xu6gR&*3$Cl>-G3{e)+tdBU`7rFO`{e{P9GuuuDJZ zml%T1LF(({n<=(>*REar_T4*iqT}$x4G}t*?)k+g1cF@xGwb9$}?W;YVwDAQqXeX!3 zwab?;U%aSzH_Sfi<=)4;{V((R)<;K0{rY~t-dy6?ojWzJuB;4R=JWE##^lP%pA!_F ztG>MWcwD~z&CSi~c6N43N=imXlRn1#9_#V-^_8`+`%_)M*VD@@YGcw-@%WmLm;LRx zx-M+`^Wpmb-yeSdxpe7LeBDo1z3H28zL_*hsB6)wQ>U(6z3RDN+HU^+h0g3nI=61! znmBQyrl#i7rAwDcrwI4!Y~8vwdRvZV^|v)MXGRtjY;aJR;Gy!w_AT3dZpq~ehK3s# zELgB^o!>@({hdy{JUkIPVlUq~e^c7d7aJRUwBEAOAt5g>E&6)*1YTSH$`)YrG zo1o|{XHzj@@?>F2$;`w=L3#Q6HyVO^-ehKEY>3b?3fkzPuwwP<+Zz&@U)Fm0oH})i zg{g7gJh_uva}8~6_s+F0S5sA;I%Ud)aI;mbR=s-tT5@Umq&s(Z7JvTy`TSgK(83H! zZdtG)(JTc~mB?AhEe zFD@>*w`AYGeTx=3#m3Iv5-%8Zl-*rhTia}QY(zvvboA{K#^#BW)xunrCT`wbEX)}7 z>1rc0`=(8srZ^Yvyrbycc4mfQ@{0=#ZRGOr?ka8PlfAVmwHs6rKB)gPO}_rm$BT>I z!`H{fZb~`%^|rZl@7~*6{q@Tizj-#2 z^78Q^AudwPS@&zDd`@4z`gQYpyT_k@f);gFD!X61etq(sJNs&9|2gvd#S5F79~+$8`A+Rzx_yE;8)(gGRQNCO zFqTDO)0#e6>$1PUzMd*|E`N7t<@)vCLHoi$XO5im*ZlSCm$16umQ9;>mA#D$3JS{1 z)a*a5%zo}^QEzYWOKanoeM{D_|Nr11^CO4nOJ1^?&HnrF{f?*4p55D18EmO2)_rwn z@$<^h&w3>c4;?t5ps1Mm?#@nOb-zCk+vTS)CwDJ$us++fbcV{b|1X&$BO^IEIa5BA zDJw6YX`Bw4|37d4KSa*)%h}oH(&l+f-dDXZe6VumN={DB-n&`%m7R{p#_g$ayrmZt z8=Go$^Tb4D|G8FEXU(!Ic@c0))Ys5pZ%lmr{+yeeEQ_Dr*;l(eet+F!x85Kbw|RWW z9)I*WtfRRiSj2T+>enw{SeO`p?#x=VZyG4ZE=`=eXhr_MpU+kvQrFP%FpRi-`pbK5 zt*=VRaKvUdV2cQ?#XRZN7YN88l-f4s3dK^dDbpb;7MAu=`=6tT>GLY9Fmjf z_Raqz(capss-~tFxvAyLgf;8e`+ImOyx&%6F=t=x@4VaF-oCrLJ9xQY>Xy$QOE0~> zy?uYp&q;k7wsJpx`n3H0JzsC{Y;NsN7a?hB@4zWDXU^QX@#Dk8?a$B7o<3#Dl9ekh z^X^y#oxGZ`>*dRrhue5>?byrptzDbYJZ*WPEixHWBXi`6u*`TtNZcr@WgD%nAq2M?(y;d_xJXCOL+3G{G?d_ z|L^yHIonqk7q|PUS=an1NK8~z=6Tt1I&HJ`9(8TDX9X5ZyhEDVo!V8lXIu)LeDB9e zaV;$^&=GQOulG)yHf{a-_g7bk_siSAd;QvbmA6R!8vDv^_IYe__H}b6OmKMSymiy2 zsEtXkNlA|&ds8KsF8J}IVwchPzn><|m@#9@lqE4!Zyvhw?*9JyvuA4yb$Z0x*Vq4t zY%TSfVX*MvtbHvlESFw`j=2W4FHfHQ`0bn8WCzpV>pgxYT$WV+e~(AtSM*WVp#STZ zF5O!FJ?~dv$@6n_!+Nj!3kB_4mX)1d{_c+EM2}~J zRZV?xpi%eD2{i!@k=M)KzIo&1ydX6DWxchxmCR@~H5bh`LJziIK} z$CK6lm-)~43%t@RZT{}=?&ULzH~Gv9x^ngEY};nt%1H~~uRf*jVfnIuhpW=WHL<&= z86LE5Km79g`ulyd)58BvW-6$#|vSj)4cZ62)Fu1HV)LEewJrI-;ZfWZ)k?AMsq^O5eS33r z{k~sWpPrn2629l)a;~cTj~+ex^5u)Pc^(TJn_d0CI~Oh#Tw3D!^yyQ6c{`C#m(S17 z&o|GPTU^^&qI>StsZ*y#nl$N!h3Dw1;%HfZuA?`~9V ztnZ~qMLVZWo0gcEsO~@S&(G)czkdBXyFyK2eSF@nEt+a-X@^=k+uGW`D0{@k-J54y zE%kc&twWC&C1)r8Sk`>?+O>T(KR=zEte%*d`1||&=LHu3{{4IQ>=|f+^7)CgXLIlD zDD3i0f0CrBp>g8m$&=^L`}_InX=*Ai_C7bmaPdaZLn%f#A0O{O-YYFGC-?5b0|7Cy zw3L)7^XB;-o2i_8@f5%OllwFFt?-O5_w_xyY15_~HzFDx7A##F8W&gh;6Ni=^zWZF z`$DwNo;h>o{CRzSeRYx2($dPx%9K4xY znKM0tGvcOtsNB4H^Zb1K_}yi1r|CvV=uDeGe|~H0(Y@8*v$C>cVq&hXi8QYIlJU#b z`;vX@*|hMmuw_e^ii(JU#zC&G4p%vPb91`+wWP_DCr@JTu4Q15ck^^{3=tL(*pPX7 z+5Z3kem^@q`}Vfn>fhgV`;Qx&n=jY4oyx1(^{8lPSy|b_g$tP)73}QlzP`HJQ|}}! zEUc@$_SLIb$;bO_tG~Uuwl@09Mbo_wb(_7syo`*E@9(K}F1N1w`)g~6*43+5m)2jI z)wf)BpK5XXk|j$fY&miIfSsLPU|?YN_jhk^Z(si^Wvi^o3zZu=+a^xDxX878(c;C^ z_2d1PWh&ec3l07I@woi^*l)`wXIyQH(X0RatF)@>7w8l~{WzV;Cv9wOVq#*1goRI^ zKF!O^dwpFj=r+Hjy8?|QD?&p>XTIIKX3d*>d#h{g>=hIgG&DRakKCO004p>^ShSV9S;*uU^0Am$h;^e`UoCnV<5f&z;lL z&{&{-(c`-D%8*rmls(+`C_j$(QknGN!Gm{qcVEAH^<%{zwOi|+7X4fuzW&msOJ(ow zNJ>d*O+LA2@7~=dFP)@7%kIP1#aPz+~)!NJaHPiGjVo;uXZ zebU3ci~Z81)Jv&{hEKQuOKkPK$r3HXdSZdp^>wkqcRcj>SAI@=eQj-5vZ;Rb zww{06wsQab_fN$2qVe1Z=FGgjx{r@sSB6Bz$NTS}@#Ot`|2qDv zudiI&zAIe4m$Y$5@$++nf`Xtq`pq}h)YKjy?=LSZO4@u=N=oX>6Pc1lm6erytG}zo z-t^>8tgimu)5CLV<-MCXBb}WeAL$e>si^uFcj>|5q>UCb=Q@SeFI~FiVZ3A3tXaLi zygxHR2QI|ul@}H!Zj9Lf|DScIilU;Uj@ag#Ioa9S`uh5xHcj(UQ+8g$#>RFj^CI{6 z_xHDN*r34wC@n3`X<>lBfB*UCn{U3!yu8e??a^ZQwZa@MN)tOo4)E~sfYznSU&*_> zYh%P3IoqlpDbubg!oR-1_rJG5t@O;2zlmRW^G^ru)s;2RyOTb@*6kNt{NAdm=OiLm ztXlQ!VY_@zZm#FYIPi(v|IXY0pK=;>+V9<6rNZ4uzdXq;+8I-L#cF5FyeU&$y5>5! z@o4JmhRSSx_ww@cC37bqemLQ=YVd;#i?3ZYKDIV?_q4+gEv&3gJ^i$4lhG%8O|foS zSy_HL8;?&jCrn7l%F4>gIU|rP<7d4dbPDc2)eRdqL~KlA{W(409GfKL?Zbzie`;U) z{rLU<|Nq|Ye*c2|__=fMPEJpj+$(LqW$V_H4<4Rn%QIt;jBGyqaK-A?lm9Ep z^_yp2QZe!pp4rm5XvMnN-QV8dpT9?QbM5c4oiU&o51O%k^XAVVK2&^oz$m%r!sW}C zj~{Qhxj!M0NAz<*OpH(YnTG`yDM1=?{qE}yHna0{wI146`}@*j!-;{fJr=Xq##&oj zpMLu3e%=Gouz|UtgEf;cK*D;>3v) zTU$X3@m@|yanzc6ZkB2Ho#K+xQqS<3qWcEM#=&y>6MCZDXRYy!RcSvgX;q@Jvq)J< z=|o7)V)y>C;$mg~cc2?cPCo_J6c?kSqN*w??(8l(`GT7Z!*5&Nk~kn$+6b zdQpAKxl7BVG&D6|USBW2bKTCEb?eu^Um3hyYPMkRyE{8YTs8Yt=>o%E{$VulC7W-@19z)MCY|q6DKX+3ur4oi0z35;sPy zTet2>o20n-@|7!3KL6a#D{Yo>LE(~T%NdTTQ>M6tuZxU`u&MsG#(%z@j@apo7Yo0< zxR|o!@VmRajo&@|vZ54pV^oY@{U^|I+oqZ4rk(~3$Ao~F`G(HXpVkw#ydv1h*m!sO z`+NWX{yv$VQB_q{R#qk@B_(TBvZMb0zthw8dwY9ZogO|tJ^kdzw)XbPf)8Y5Wl#Rd zD%!bc&z?KiuTMYxP{yL5;hF)0Cle}GW4`;CCn}wl7hiLAb)9JThm~6_Bs5gBFY5b)gUm%{C-Zq% z=FT@vW|M64D?DalB)?<#?&{p!+_*Tom6oPvX4|%JUtYiRr1lp-Kfja;8!P+Vy$=0# zN7FX%E_=Hx`FP*4wo9PPf-Y0W& zZ}s=Lx3_r;o;W}laI+*79BZvuFvLO{>@EG!`H|4%iD`}y3DmM|Mva+_D!31)&4fq zJTTv;a?`qXen0oBIXfSoF=NKx-`^(}&WMSLIo2cT{E9U~=h}+E#ZJ!7_54{*8ThUuU)G<|NQpt+xxq^tZIG~q@^uey!i1{?Qp&LeLh`EZEbCb+xge8 zU8`z;Y}>YN%ITC;4kVP0bM?A0sKurBCuW-BWzU0q!zrKU5J?tZH9IH6`G zyvv~TnabtvY8_&y2OS_X)mL!5!TQRfoSX6#`(k-rUA>-H1C%b3w z-m~{=|NQwQvfK5~_x=A>b^Vwc8(dT;pX8IXnK6I9J*dU|Y5C-Y%{M_!*b57tK~3a< zfP|bJ(3Xno>T09=i6tdl_U_%A)I7Dfmp9iV>afkdT92tWmv~NQVRFpLSreckV_lZx zJw0d6o_%|F_xAq&^R3+CF)=X`|4XM$ zn`T}1#-je;pVQOzLC0zMfNB6+TU$>9eSQ7d*t^!{@9yjAm!R z=Z{aP^|Q0GPQ=yz`eIq~;=;<{)n8sX=Kc1cZ)aQmZH;zP-BIy)HQW|CtqOT{>c?FI_5nd1)ylBV+XTJlm2N0a;nE+IXe! z+_^KQKFRKvqJ)&xrTvd%^sb*capLURv$t>0wo%-%bEm9*-JCNS78M^7%+0sE_sdP( zcnVYwmA}7txSfCU_wp}azJO*|l$3&kgLjv_G|IcPqnVvQDk{q8*UFC-d-m1-p0qMf zqwCU@D_=f+I(7cMy8hzYZ#UD+%E~~_uln-h$;rtlV~^gvIrE&NWzDCgZ#xPfSABU= z`00sf&<;~WLrIg2famAtYHMlL)YNEcYrj-XQ}dg1;$gwMn4L-!JzjKAx%2(an>Ql6 z^(Otene*+>&(GCgUx^9}e|~jU+tzlk{=OfJ;`i6396NjC#*MtYyEN~q`1<&~koi<$ zqpZC6-{0T-ayB!zl-|B^V-DzU(SyxPmoA<6-tObak1Bz}!jqZV`QF^$Z*OkC-MO7F zEiJA7&qsIAT4TGKjNDw?%1=*Xcb9?I;7B(;TKWF&?(H#p>gMcn{pJ-P9;}PqeQB$` z3aC+GSF@vNyNlWEw+|jHSiJc1Vt0Nkze`i+9)JAv_wW3Bdn)hms|B@ZMY~fj`Eqk} z2QeFEU0Ko7(_>x!?#Xk|`Nn1M@7=wBe}DM;xF^@&o|vfo`}_Oz=g+^tv$HrS=grsG z*G~p_&6_uG|9*R04WrJ@+1JBcR)K2^KcUt(`C{Y1{3lY}G zejmMgBW~r&m2<61AASD0+;6Uu^G#E+PtMz}U%kr8%35e4b2M{;or=@cTjr{&M^Byd zQV}|O?AW$z8+PrgIyFV}e$8j!goFnx0v8`i+Bj|6wVlP!qpBN>X1;lMcej<5)v;s8 z%=7Q%ynUA|Zl|Sn>e#WgtE)oK&$G=ITfS(Kl7d3Q-Cd<;pDkau?Af!kvxU`s3d+jT zwlJCQ*5~~2=xFzW0}e(iaopuUCnWUC*>Z7k1iX3jNpYj;?);1ljsD}GzkO3%yxvs$ z-(MzBOYh#jIA7o1Jl^X46(PmzA3R8q>wo_G^>4Y)`k-~T=g+@ym#_P=|Nn3Mpj+QR zf7aI5&wo2HEEL>eJO0>rj>X5nb$g;_CwU(d7ZdyS>sM7}+i%?e8~sBp>H9HQoB|?(Y3nUtiglI~&34&i2&(t;&9{^7H4<%gcO!zuW!(+4=eJ-@n%v>g3_&)sNkE zK5a9#8g-AljHkItMw z-@fEUfLQm|go90NyT8``c=+V`^U0Dknwy(v>+Y?oD0(aJ?B{o`fsr{v=h~&E-jaLY z%|7c>QnIDBwRP4ksmyP43=*BPva&W;8!}zFdUb95{&|NVmb|~W_hwbrv3i%^IDsS1kb!W`FUAwBz&$GS1 z{@U-CmzU4ADi!K<(OtP9Ka_7aUrcy7XiM1l6)m||x9ZPt_nmSt@>DW^TT9EDsI9NQ zyuAD*Hh$_m%Z4+5omp-rB|Wb{vCw?#*jNgG45 zGPI4#%A>#gA1=N7px!$(Gt*?Fu^R>0LS(zHwt;<`@^ZM1RQ>RXO{G4|BX;xO&wpZI6`lk07Ma0JHig2AYnKS=X z<3zo67Hl4?!~SorN@22;>tDWlwKrRH#?)wUCUFrF4;3L^Uf!dDy3v~+?^ooR=`-bM z(#sbwCTuT?s<>h_bIqPTbLzYVxmu&5qSo$`pVX3-oz2b7ebS=xiSIG7v^{51=$&m){_EI+qqQ9$_J{dDzWdzy#jLyGg&+Q; zG5^2K^r2$U_iB%X%{S$rUUyLtxWKHm&G_H`Z;P_C)6Ym;zjmlYo=KpAfklCVk;8!j z!u+t1Nn>yQiU<1({x4dzsHdlA)~s1&7T^B-`P0+GQ+4mtHa|mk^>!c6OV>CR>o`_S zVVIe$sjt6YwkR|>c=FV#uD|NGI~QHOdUfW^nX0O)ZzqUNYH0A{6cHESe!IWaTD~GL zFK_qXi1hUI{Z(JR)Fy8|Zi3eq5QPsbSyruHZER%J)!l6$%J$Fk<)SbD z_^l#WO}hH__V(XDf7;gl*&%BrA}03i`E&PWmD%l2#B?G+=gj6!Wqn)V;=#nEE2yEb z|NZml=q(w6-c0ogGp0_w=B%-qk__|llAz3@BBPl~JJx;V;$Y0{$?FK*b0M^#o<78MoM z)zwAIi$7{_SjD;JIVcFLqoSgUii&=3X}7Qa72@pdtTlDpc|$dI_5H_Bq`aMMzJ#f9 zoA8PiD?I%C^5)w$~IH^TI~85-i6B_7u@K; zz$EX?u=IQX!VZgDJ`B06%myM&98V@nW2?)$YY&IKF}3vyXM z+^fF*>!1IzcW>XWUA#CsG4UdwyLsK83UP7qjS+YFG6O|SOJ7}qEH(Y+$+yzM!4-7$ z)ij;Rq}0@_d_OmC*zn`!^7*^U-`}%)Uv}%}P2I>%OX~msds~pe;hz{wF`EpHcVT>1U{-l5%xb=yL!0a%MR<)XzvxYD3K|42&FqRH%U9)UGZ(CmcBSs{K5OUtKPtDX=5hbb(-ffO_-He9l1W?2mi zUF5vTz&KUd;brVoKTac16rmcKzyYovwJ=O`c*+t`6}~gLiN_IDM*{;ywz0h}46r3>~(Z=BQe$-12qp<`@HKPd+lC4Jb5~S%cT0DTu?9t+Z zqT(UunAP50g^!O3tNUG89RW#M@J1=9l3L))8n>_JX2hS~Y4?(olcjI7-&O>PLoy>c z3K*CKGW;2*#ptCk`Tpwa>N|I0j=5o}i4`vJF{!DkJ$v@7r$tI*ud!2tD5UL+Y+R$i zc0=H6yS4T~?HF~wiGIVS>d$T*j1V6qIrhgEQ0qCWehD9jR7M=b((liD1(-1G`jE-` aPu{=u1WVndWPSz)1_n=8KbLh*2~7a7;($N^ literal 0 HcmV?d00001 diff --git a/docs/_static/diagrams/i2s/std_msb.png b/docs/_static/diagrams/i2s/std_msb.png new file mode 100644 index 0000000000000000000000000000000000000000..d77faab377b9aae61920a41e8cb43d5d1a8c473a GIT binary patch literal 23008 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 z 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 literal 0 HcmV?d00001 diff --git a/docs/_static/diagrams/i2s/tdm_msb.png b/docs/_static/diagrams/i2s/tdm_msb.png new file mode 100644 index 0000000000000000000000000000000000000000..dfc30cb77dbd507a92cdebf50036d3a8e0d261c9 GIT binary patch literal 73090 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 JS?83{1OS#ZWP< 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