From 28cb5c88b6efffb6f618b069cd1561ff2385ea73 Mon Sep 17 00:00:00 2001 From: Troy <5659019+troyhacks@users.noreply.github.com> Date: Wed, 3 Jul 2024 16:20:44 -0400 Subject: [PATCH 1/4] Skeleton, not working yet. --- usermods/audioreactive/audio_reactive.h | 22 +++ usermods/audioreactive/audio_source.h | 174 ++++++++++++++++++++++++ 2 files changed, 196 insertions(+) diff --git a/usermods/audioreactive/audio_reactive.h b/usermods/audioreactive/audio_reactive.h index b958184cef..ff1c9ed5b8 100644 --- a/usermods/audioreactive/audio_reactive.h +++ b/usermods/audioreactive/audio_reactive.h @@ -1923,6 +1923,23 @@ class AudioReactive : public Usermod { if (i2c_sda >= 0) sdaPin = -1; // -1 = use global if (i2c_scl >= 0) sclPin = -1; + if (audioSource) audioSource->initialize(i2swsPin, i2ssdPin, i2sckPin, mclkPin); + break; + case 8: + #ifdef use_ac101_mic + DEBUGSR_PRINTLN(F("AR: AC101 Source (Mic)")); + #else + DEBUGSR_PRINTLN(F("AR: AC101 Source (Line-In)")); + #endif + audioSource = new AC101Source(SAMPLE_RATE, BLOCK_SIZE, 1.0f); + //useInputFilter = 0; // to disable low-cut software filtering and restore previous behaviour + delay(100); + // WLEDMM align global pins + if ((sdaPin >= 0) && (i2c_sda < 0)) i2c_sda = sdaPin; // copy usermod prefs into globals (if globals not defined) + if ((sclPin >= 0) && (i2c_scl < 0)) i2c_scl = sclPin; + if (i2c_sda >= 0) sdaPin = -1; // -1 = use global + if (i2c_scl >= 0) sclPin = -1; + if (audioSource) audioSource->initialize(i2swsPin, i2ssdPin, i2sckPin, mclkPin); break; @@ -2802,6 +2819,11 @@ class AudioReactive : public Usermod { #else oappend(SET_F("addOption(dd,'WM8978 ☾',7);")); #endif + #if SR_DMTYPE==8 + oappend(SET_F("addOption(dd,'AC101 ☾ (⎌)',8);")); + #else + oappend(SET_F("addOption(dd,'AC101 ☾',8);")); + #endif #ifdef SR_SQUELCH oappend(SET_F("addInfo('AudioReactive:config:squelch',1,'⎌ ")); oappendi(SR_SQUELCH); oappend("');"); // 0 is field type, 1 is actual field #endif diff --git a/usermods/audioreactive/audio_source.h b/usermods/audioreactive/audio_source.h index cf3e3b745a..c83af476ae 100644 --- a/usermods/audioreactive/audio_source.h +++ b/usermods/audioreactive/audio_source.h @@ -736,6 +736,180 @@ class WM8978Source : public I2SSource { }; +class AC101Source : public I2SSource { + private: + // I2C initialization functions for WM8978 + void _ac101I2cBegin() { + Wire.setClock(400000); + } + + void _ac101I2cWrite(uint8_t reg_addr, uint16_t val) { + #ifndef AC101_ADDR + #define AC101_ADDR 0x1A + #endif + char send_buff[3]; + send_buff[0] = reg_addr; + send_buff[1] = (val >> 8) & 0xff; + send_buff[2] = val & 0xff; + Wire.beginTransmission(AC101_ADDR); + Wire.write((const uint8_t*)send_buff, 3); + uint8_t i2cErr = Wire.endTransmission(); // i2cErr == 0 means OK + if (i2cErr != 0) { + DEBUGSR_PRINTF("AR: AC101 I2C write failed with error=%d (addr=0x%X, reg 0x%X, val 0x%X).\n", i2cErr, AC101_ADDR, reg_addr, val); + } + } + + void _ac101InitAdc() { + // https://files.seeedstudio.com/wiki/ReSpeaker_6-Mics_Circular_Array_kit_for_Raspberry_Pi/reg/AC101_User_Manual_v1.1.pdf + // + _ac101I2cBegin(); + + #define CHIP_AUDIO_RS 0x00 + #define PLL_CTRL1 0x01 + #define PLL_CTRL2 0x02 + #define SYSCLK_CTRL 0x03 + #define MOD_CLK_ENA 0x04 + #define MOD_RST_CTRL 0x05 + #define I2S_SR_CTRL 0x06 + #define I2S1LCK_CTRL 0x10 + #define I2S1_SDOUT_CTRL 0x11 + #define I2S1_SDIN_CTRL 0x12 + #define I2S1_MXR_SRC 0x13 + #define I2S1_VOL_CTRL1 0x14 + #define I2S1_VOL_CTRL2 0x15 + #define I2S1_VOL_CTRL3 0x16 + #define I2S1_VOL_CTRL4 0x17 + #define I2S1_MXR_GAIN 0x18 + #define ADC_DIG_CTRL 0x40 + #define ADC_VOL_CTRL 0x41 + #define HMIC_CTRL1 0x44 + #define HMIC_CTRL2 0x45 + #define HMIC_STATUS 0x46 + #define DAC_DIG_CTRL 0x48 + #define DAC_VOL_CTRL 0x49 + #define DAC_MXR_SRC 0x4c + #define DAC_MXR_GAIN 0x4d + #define ADC_APC_CTRL 0x50 + #define ADC_SRC 0x51 + #define ADC_SRCBST_CTRL 0x52 + #define OMIXER_DACA_CTRL 0x53 + #define OMIXER_SR 0x54 + #define OMIXER_BST1_CTRL 0x55 + #define HPOUT_CTRL 0x56 + #define SPKOUT_CTRL 0x58 + #define AC_DAC_DAPCTRL 0xa0 + #define AC_DAC_DAPHHPFC 0xa1 + #define AC_DAC_DAPLHPFC 0xa2 + #define AC_DAC_DAPLHAVC 0xa3 + #define AC_DAC_DAPLLAVC 0xa4 + #define AC_DAC_DAPRHAVC 0xa5 + #define AC_DAC_DAPRLAVC 0xa6 + #define AC_DAC_DAPHGDEC 0xa7 + #define AC_DAC_DAPLGDEC 0xa8 + #define AC_DAC_DAPHGATC 0xa9 + #define AC_DAC_DAPLGATC 0xaa + #define AC_DAC_DAPHETHD 0xab + #define AC_DAC_DAPLETHD 0xac + #define AC_DAC_DAPHGKPA 0xad + #define AC_DAC_DAPLGKPA 0xae + #define AC_DAC_DAPHGOPA 0xaf + #define AC_DAC_DAPLGOPA 0xb0 + #define AC_DAC_DAPOPT 0xb1 + #define DAC_DAP_ENA 0xb5 + + _ac101I2cWrite(CHIP_AUDIO_RS, 0x123); // Reset (any value written does a reset) + vTaskDelay(1000 / portTICK_PERIOD_MS); + _ac101I2cWrite(SPKOUT_CTRL, 0xe880); + + //Enable the PLL from 256*44.1KHz MCLK source + _ac101I2cWrite(PLL_CTRL1, 0x014f); + //res |= ac101_write_reg(PLL_CTRL2, 0x83c0); + _ac101I2cWrite(PLL_CTRL2, 0x8600); + + //Clocking system + _ac101I2cWrite(SYSCLK_CTRL, 0x8b08); + _ac101I2cWrite(MOD_CLK_ENA, 0x800c); + _ac101I2cWrite(MOD_RST_CTRL, 0x800c); + _ac101I2cWrite(I2S_SR_CTRL, 0b0111000000000000); //sample rate 22050 Hz + //AIF config + _ac101I2cWrite(I2S1LCK_CTRL, 0x8850); //BCLK/LRCK + _ac101I2cWrite(I2S1_SDOUT_CTRL, 0xc000); // + _ac101I2cWrite(I2S1_SDIN_CTRL, 0xc000); + _ac101I2cWrite(I2S1_MXR_SRC, 0x2200); // + + _ac101I2cWrite(ADC_SRCBST_CTRL, 0xccc4); + _ac101I2cWrite(ADC_SRC, 0x2020); + _ac101I2cWrite(ADC_DIG_CTRL, 0x8000); + _ac101I2cWrite(ADC_APC_CTRL, 0xbbc3); + + //Path Configuration + _ac101I2cWrite(DAC_MXR_SRC, 0xcc00); + _ac101I2cWrite(DAC_DIG_CTRL, 0x8000); + _ac101I2cWrite(OMIXER_SR, 0x0081); + _ac101I2cWrite(OMIXER_DACA_CTRL, 0xf080); //} + + //* Enable Speaker output + // _ac101I2cWrite(0x58, 0xeabd); + + _ac101I2cWrite(ADC_SRC, 0b0000010000001000); // Line-in to ADC + _ac101I2cWrite(ADC_DIG_CTRL, 0x8000); + _ac101I2cWrite(ADC_APC_CTRL, 0x3bc0); + //I2S1_SDOUT_CTRL + //res |= _ac101I2cWrite(PLL_CTRL2, 0x8120); + _ac101I2cWrite(MOD_CLK_ENA, 0x800c); + _ac101I2cWrite(MOD_RST_CTRL, 0x800c); + //res |= _ac101I2cWrite(0x06, 0x3000); + //* Enable Headphoe output + _ac101I2cWrite(OMIXER_DACA_CTRL, 0xff80); + _ac101I2cWrite(HPOUT_CTRL, 0xc3c1); + _ac101I2cWrite(HPOUT_CTRL, 0xcb00); + vTaskDelay(100 / portTICK_PERIOD_MS); + _ac101I2cWrite(HPOUT_CTRL, 0xfbc0); + + _ac101I2cWrite(OMIXER_SR, 0b0000010000001000); // default all 0 + + //* Enable Speaker output + _ac101I2cWrite(SPKOUT_CTRL, 0xeabd); + + + } + + public: + AC101Source(SRate_t sampleRate, int blockSize, float sampleScale = 1.0f, bool i2sMaster=true) : + I2SSource(sampleRate, blockSize, sampleScale, i2sMaster) { + _config.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT; + }; + + void initialize(int8_t i2swsPin, int8_t i2ssdPin, int8_t i2sckPin, int8_t mclkPin) { + DEBUGSR_PRINTLN("AC101Source:: initialize();"); + + // if ((i2sckPin < 0) || (mclkPin < 0)) { // WLEDMM not sure if this check is needed here, too + // ERRORSR_PRINTF("\nAR: invalid I2S WM8978 pin: SCK=%d, MCLK=%d\n", i2sckPin, mclkPin); + // return; + // } + // BUG: "use global I2C pins" are valid as -1, and -1 is seen as invalid here. + // Workaround: Set I2C pins here, which will also set them globally. + // Bug also exists in ES7243. + if ((i2c_sda < 0) || (i2c_scl < 0)) { // check that global I2C pins are not "undefined" + ERRORSR_PRINTF("\nAR: invalid AC101 global I2C pins: SDA=%d, SCL=%d\n", i2c_sda, i2c_scl); + return; + } + if (!pinManager.joinWire(i2c_sda, i2c_scl)) { // WLEDMM specific: start I2C with globally defined pins + ERRORSR_PRINTF("\nAR: failed to join I2C bus with SDA=%d, SCL=%d\n", i2c_sda, i2c_scl); + return; + } + + // First route mclk, then configure ADC over I2C, then configure I2S + _ac101InitAdc(); + I2SSource::initialize(i2swsPin, i2ssdPin, i2sckPin, mclkPin); + } + + void deinitialize() { + I2SSource::deinitialize(); + } + +}; + #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 2, 0) #if !defined(SOC_I2S_SUPPORTS_ADC) && !defined(SOC_I2S_SUPPORTS_ADC_DAC) #warning this MCU does not support analog sound input From 1fe871c42ce73463fb0177d118419f26e14aa57a Mon Sep 17 00:00:00 2001 From: Troy <5659019+troyhacks@users.noreply.github.com> Date: Wed, 10 Jul 2024 18:54:02 -0400 Subject: [PATCH 2/4] Fully working with analog loopthru --- usermods/audioreactive/audio_source.h | 113 +++++--------------------- 1 file changed, 20 insertions(+), 93 deletions(-) diff --git a/usermods/audioreactive/audio_source.h b/usermods/audioreactive/audio_source.h index c83af476ae..f8156fe7cd 100644 --- a/usermods/audioreactive/audio_source.h +++ b/usermods/audioreactive/audio_source.h @@ -749,8 +749,8 @@ class AC101Source : public I2SSource { #endif char send_buff[3]; send_buff[0] = reg_addr; - send_buff[1] = (val >> 8) & 0xff; - send_buff[2] = val & 0xff; + send_buff[1] = uint8_t((val >> 8) & 0xff); + send_buff[2] = uint8_t(val & 0xff); Wire.beginTransmission(AC101_ADDR); Wire.write((const uint8_t*)send_buff, 3); uint8_t i2cErr = Wire.endTransmission(); // i2cErr == 0 means OK @@ -765,112 +765,39 @@ class AC101Source : public I2SSource { _ac101I2cBegin(); #define CHIP_AUDIO_RS 0x00 - #define PLL_CTRL1 0x01 - #define PLL_CTRL2 0x02 #define SYSCLK_CTRL 0x03 #define MOD_CLK_ENA 0x04 #define MOD_RST_CTRL 0x05 #define I2S_SR_CTRL 0x06 #define I2S1LCK_CTRL 0x10 #define I2S1_SDOUT_CTRL 0x11 - #define I2S1_SDIN_CTRL 0x12 #define I2S1_MXR_SRC 0x13 - #define I2S1_VOL_CTRL1 0x14 - #define I2S1_VOL_CTRL2 0x15 - #define I2S1_VOL_CTRL3 0x16 - #define I2S1_VOL_CTRL4 0x17 - #define I2S1_MXR_GAIN 0x18 #define ADC_DIG_CTRL 0x40 - #define ADC_VOL_CTRL 0x41 - #define HMIC_CTRL1 0x44 - #define HMIC_CTRL2 0x45 - #define HMIC_STATUS 0x46 - #define DAC_DIG_CTRL 0x48 - #define DAC_VOL_CTRL 0x49 - #define DAC_MXR_SRC 0x4c - #define DAC_MXR_GAIN 0x4d #define ADC_APC_CTRL 0x50 #define ADC_SRC 0x51 #define ADC_SRCBST_CTRL 0x52 #define OMIXER_DACA_CTRL 0x53 #define OMIXER_SR 0x54 - #define OMIXER_BST1_CTRL 0x55 #define HPOUT_CTRL 0x56 - #define SPKOUT_CTRL 0x58 - #define AC_DAC_DAPCTRL 0xa0 - #define AC_DAC_DAPHHPFC 0xa1 - #define AC_DAC_DAPLHPFC 0xa2 - #define AC_DAC_DAPLHAVC 0xa3 - #define AC_DAC_DAPLLAVC 0xa4 - #define AC_DAC_DAPRHAVC 0xa5 - #define AC_DAC_DAPRLAVC 0xa6 - #define AC_DAC_DAPHGDEC 0xa7 - #define AC_DAC_DAPLGDEC 0xa8 - #define AC_DAC_DAPHGATC 0xa9 - #define AC_DAC_DAPLGATC 0xaa - #define AC_DAC_DAPHETHD 0xab - #define AC_DAC_DAPLETHD 0xac - #define AC_DAC_DAPHGKPA 0xad - #define AC_DAC_DAPLGKPA 0xae - #define AC_DAC_DAPHGOPA 0xaf - #define AC_DAC_DAPLGOPA 0xb0 - #define AC_DAC_DAPOPT 0xb1 - #define DAC_DAP_ENA 0xb5 - - _ac101I2cWrite(CHIP_AUDIO_RS, 0x123); // Reset (any value written does a reset) - vTaskDelay(1000 / portTICK_PERIOD_MS); - _ac101I2cWrite(SPKOUT_CTRL, 0xe880); - - //Enable the PLL from 256*44.1KHz MCLK source - _ac101I2cWrite(PLL_CTRL1, 0x014f); - //res |= ac101_write_reg(PLL_CTRL2, 0x83c0); - _ac101I2cWrite(PLL_CTRL2, 0x8600); - - //Clocking system - _ac101I2cWrite(SYSCLK_CTRL, 0x8b08); - _ac101I2cWrite(MOD_CLK_ENA, 0x800c); - _ac101I2cWrite(MOD_RST_CTRL, 0x800c); - _ac101I2cWrite(I2S_SR_CTRL, 0b0111000000000000); //sample rate 22050 Hz - //AIF config - _ac101I2cWrite(I2S1LCK_CTRL, 0x8850); //BCLK/LRCK - _ac101I2cWrite(I2S1_SDOUT_CTRL, 0xc000); // - _ac101I2cWrite(I2S1_SDIN_CTRL, 0xc000); - _ac101I2cWrite(I2S1_MXR_SRC, 0x2200); // - - _ac101I2cWrite(ADC_SRCBST_CTRL, 0xccc4); - _ac101I2cWrite(ADC_SRC, 0x2020); - _ac101I2cWrite(ADC_DIG_CTRL, 0x8000); - _ac101I2cWrite(ADC_APC_CTRL, 0xbbc3); - - //Path Configuration - _ac101I2cWrite(DAC_MXR_SRC, 0xcc00); - _ac101I2cWrite(DAC_DIG_CTRL, 0x8000); - _ac101I2cWrite(OMIXER_SR, 0x0081); - _ac101I2cWrite(OMIXER_DACA_CTRL, 0xf080); //} - - //* Enable Speaker output - // _ac101I2cWrite(0x58, 0xeabd); - - _ac101I2cWrite(ADC_SRC, 0b0000010000001000); // Line-in to ADC - _ac101I2cWrite(ADC_DIG_CTRL, 0x8000); - _ac101I2cWrite(ADC_APC_CTRL, 0x3bc0); - //I2S1_SDOUT_CTRL - //res |= _ac101I2cWrite(PLL_CTRL2, 0x8120); - _ac101I2cWrite(MOD_CLK_ENA, 0x800c); - _ac101I2cWrite(MOD_RST_CTRL, 0x800c); - //res |= _ac101I2cWrite(0x06, 0x3000); - //* Enable Headphoe output - _ac101I2cWrite(OMIXER_DACA_CTRL, 0xff80); - _ac101I2cWrite(HPOUT_CTRL, 0xc3c1); - _ac101I2cWrite(HPOUT_CTRL, 0xcb00); - vTaskDelay(100 / portTICK_PERIOD_MS); - _ac101I2cWrite(HPOUT_CTRL, 0xfbc0); - - _ac101I2cWrite(OMIXER_SR, 0b0000010000001000); // default all 0 - - //* Enable Speaker output - _ac101I2cWrite(SPKOUT_CTRL, 0xeabd); + _ac101I2cWrite(CHIP_AUDIO_RS, 0x123); // I think anything written here is a reset as 0x123 is kinda suss. + + delay(100); + + _ac101I2cWrite(SYSCLK_CTRL, 0b0000100000001000); // System Clock is I2S MCLK + _ac101I2cWrite(MOD_CLK_ENA, 0b1000000000001000); // I2S and ADC Clock Enable + _ac101I2cWrite(MOD_RST_CTRL, 0b1000000000001000); // I2S and ADC Clock Enable + _ac101I2cWrite(I2S_SR_CTRL, 0b0100000000000000); // set to 22050hz just in case + _ac101I2cWrite(I2S1LCK_CTRL, 0b1000000000110000); // set I2S slave mode, 24-bit word size + _ac101I2cWrite(I2S1_SDOUT_CTRL, 0b1100000000000000); // I2S enable Left/Right channels + _ac101I2cWrite(I2S1_MXR_SRC, 0b0010001000000000); // I2S digital Mixer, ADC L/R data + _ac101I2cWrite(ADC_SRCBST_CTRL, 0b0000000000000100); // mute all boosts. last 3 bits are reserved/default + _ac101I2cWrite(OMIXER_SR, 0b0000010000001000); // Line L/R to output mixer + _ac101I2cWrite(ADC_SRC, 0b0000010000001000); // Line L/R to ADC + _ac101I2cWrite(ADC_DIG_CTRL, 0b1000000000000000); // Enable ADC + _ac101I2cWrite(ADC_APC_CTRL, 0b1011100100000000); // ADC L/R enabled, 0dB gain + _ac101I2cWrite(OMIXER_DACA_CTRL, 0b0011111110000000); // L/R Analog Output Mixer enabled, headphone DC offset default + _ac101I2cWrite(HPOUT_CTRL, 0b1111101111110001); // Headphone out from Analog Mixer stage, no reduction in volume } From f7e2f14ca4badfcbd8e45bbd88e752926ae3751d Mon Sep 17 00:00:00 2001 From: Troy <5659019+troyhacks@users.noreply.github.com> Date: Wed, 10 Jul 2024 19:03:38 -0400 Subject: [PATCH 3/4] Minor tab and comment clean-up. --- usermods/audioreactive/audio_source.h | 38 ++++++++++++++------------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/usermods/audioreactive/audio_source.h b/usermods/audioreactive/audio_source.h index f8156fe7cd..d7c0478c5d 100644 --- a/usermods/audioreactive/audio_source.h +++ b/usermods/audioreactive/audio_source.h @@ -761,27 +761,29 @@ class AC101Source : public I2SSource { void _ac101InitAdc() { // https://files.seeedstudio.com/wiki/ReSpeaker_6-Mics_Circular_Array_kit_for_Raspberry_Pi/reg/AC101_User_Manual_v1.1.pdf - // - _ac101I2cBegin(); - - #define CHIP_AUDIO_RS 0x00 - #define SYSCLK_CTRL 0x03 - #define MOD_CLK_ENA 0x04 - #define MOD_RST_CTRL 0x05 - #define I2S_SR_CTRL 0x06 - #define I2S1LCK_CTRL 0x10 - #define I2S1_SDOUT_CTRL 0x11 - #define I2S1_MXR_SRC 0x13 - #define ADC_DIG_CTRL 0x40 - #define ADC_APC_CTRL 0x50 - #define ADC_SRC 0x51 - #define ADC_SRCBST_CTRL 0x52 + // This supports mostly the older AI Thinkier AudioKit A1S that has an AC101 chip + // Newer versions use the ES3833 chip - which we also support. + + _ac101I2cBegin(); + + #define CHIP_AUDIO_RS 0x00 + #define SYSCLK_CTRL 0x03 + #define MOD_CLK_ENA 0x04 + #define MOD_RST_CTRL 0x05 + #define I2S_SR_CTRL 0x06 + #define I2S1LCK_CTRL 0x10 + #define I2S1_SDOUT_CTRL 0x11 + #define I2S1_MXR_SRC 0x13 + #define ADC_DIG_CTRL 0x40 + #define ADC_APC_CTRL 0x50 + #define ADC_SRC 0x51 + #define ADC_SRCBST_CTRL 0x52 #define OMIXER_DACA_CTRL 0x53 - #define OMIXER_SR 0x54 - #define HPOUT_CTRL 0x56 + #define OMIXER_SR 0x54 + #define HPOUT_CTRL 0x56 _ac101I2cWrite(CHIP_AUDIO_RS, 0x123); // I think anything written here is a reset as 0x123 is kinda suss. - + delay(100); _ac101I2cWrite(SYSCLK_CTRL, 0b0000100000001000); // System Clock is I2S MCLK From 1c33a4bbea66b2bf6f6e002afe11e8551fe5dcbf Mon Sep 17 00:00:00 2001 From: Troy <5659019+troyhacks@users.noreply.github.com> Date: Wed, 10 Jul 2024 19:08:58 -0400 Subject: [PATCH 4/4] Remove references to AC101 mic mode (not implemented) --- usermods/audioreactive/audio_reactive.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/usermods/audioreactive/audio_reactive.h b/usermods/audioreactive/audio_reactive.h index ea43aa60f0..f7c91594c7 100644 --- a/usermods/audioreactive/audio_reactive.h +++ b/usermods/audioreactive/audio_reactive.h @@ -2013,11 +2013,7 @@ class AudioReactive : public Usermod { if (audioSource) audioSource->initialize(i2swsPin, i2ssdPin, i2sckPin, mclkPin); break; case 8: - #ifdef use_ac101_mic - DEBUGSR_PRINTLN(F("AR: AC101 Source (Mic)")); - #else DEBUGSR_PRINTLN(F("AR: AC101 Source (Line-In)")); - #endif audioSource = new AC101Source(SAMPLE_RATE, BLOCK_SIZE, 1.0f); //useInputFilter = 0; // to disable low-cut software filtering and restore previous behaviour delay(100);