• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

BLE модули TB-04/TB-03F (TLSR8253F512)

pvvx

Активный участник сообщества
Суть построения ПО для простого чипа BLE – полная привязка всех действий к арбитражу таймингов BLE. И если вы досконально не изучили арбитраж BLE во всех режимах, то делать на этих чипах нечего. Вставлять свои даже редко срабатывающие таймеры на просыпание - это не хило увеличить общее потребление… Текущие чипы BLE тратят на пробуждение из глубокого сна 1..1.5 мс, а прием-передача фрейма занимает менее 1 мс в любом режиме BLE. И нет смысла будить чип на каждый чих. Вот тот-же nRF и другие, использующие RTOS, постоянно пробуждаются для отсчета тиков никчемной для них системы и как итог – жруны.

Использование простого sleep (не deep-sleep), когда спит только CPU не может обеспечить минимальное потребление, т.к. пашут генераторы и всякие PLL и другие у течки на включенную периферию, шины, контролеры прерываний и т.д.

Берите монстр типа ESP32 и прикручивайте к нему автомобильные АКБ и будут вам постоянно работающие UART и JTAG.
 

pvvx

Активный участник сообщества
Урезанная диаграмма последовательности работы для типового мелкого чипа BLE:
  1. Чип пробуждается из deep-sleep по спец. таймеру арбитража BLE. Запускаются и стабилизируются всякие кварцы и PLL. На это уходит примерно 1 мс
  2. Инициализируется память переменных для СИ. Энергонезависимая часть RAM не инициализируется. Инициализируются основные регистры SoC - включаются CLK на необходимые для минимальной работы блоки и GPIO. Восстанавливается прошлое состояние арбитра BLE, вычисляется время сна с учетом времени восстановления, причина просыпания и т.д. На это уходит от 0.5 до 1 мс. Там отдельно считается время исполнения стартового кода и вы должны указать его арбитру. Измеряется осциллографом и спец. вставкой дергания GPIO – популярно описано в доке к SDK.
  3. Запускается стек BLE и обычно происходит прием-передача. Тут зависимость от текущего режима работы – соединение или реклама (примерно 1..2 или 2..3 мс).
  4. Выполняется расчет следующего события для арбитража BLE.
  5. Запускается ваш код. Он должен быть шустрым – в нем вы меняете счетчик вашего счета событий и выполняете требуемое действие. Время выполнения должно быть менее чем до следующего события BLE. Это можно узнать у арбитра - самый малый период – это при соединении – минимальный интервал соединения 7 мс (такой CR2032 много не выдержит и Apple девайсы не сожрут, да и засыпать при таком интервале уже некогда и используйте интервал больше – хотя-бы от 15 мс). Минимальный интервал для засыпания указывается арбитру. Вычисляется самостоятельно по минимальному потреблению с учетом пробуждения и использования прочих режимов sleep. Если он меньше чем указанный - PMU не переведет чип в deep-sleep.
  6. Передаете управление арбитру, с указанием - можно спать в deep-sleep. Если всё криво и чего-то ждете – указываете что ещё рано спать и произойдет переход к п.п.3 или 4 (типа всё по кругу, без сна, но с отработкой BLE). Или требуете простой sleep (иногда выгоднее при коротком интервале).
  7. Чип переводится в deep-sleep или простой sleep. Тоже надо какое-то время для инициализации спец.таймера, отключения всего, включая Flash…
 

Slacky

Member
Нахимичили - нет соответствия кода загрузчика и разметки файла линковщика.
ATC_MiThermometer использует свои, специально заточенные коды загрузчика и линковщика. К ним и привязана программа показа информации по разметке.
Оф. линк и код loader-a создают большой бинарный код с дырами заполненными нулями. Это увеличивает время загрузки OTA и, следовательно, потребление при OTA. А OTA обходится жирно для CR2032 и т.д.
Спасибо за разъяснение. В общем еще раз все перепроверил, немного подкорректировал makefile. Собрал, загрузил. Как MCU уже работает. Буду дальше изучать предмет.
 

Slacky

Member
А вот подскажите хороший BLE монитор по Windows? А то то, что я нарыл в поисковике, или не работает или платное ...
 

pvvx

Активный участник сообщества
А вот подскажите хороший BLE монитор по Windows? А то то, что я нарыл в поисковике, или не работает или платное ...
Обычный адаптер BT в Windows очень плохо работает с рекламными пакетами. Лучше использовать какой sniffer.
Так-же в Windows плохи дела с привязкой. Дрова ограничивают кол-во привязанных BLE устройств.
А вот BLE cоединение в Windows работает нормально, но хотя-бы более менее мониторов нет. Они все вылетают, сбоят и т.д.
В качестве монитора используйте Android c "nRF connect".
От nRF есть монитор для Windows, но он работает с модулем на nRF58xx со специально записанной программой...
На Windows есть возможность использовать Wireshark с разными снифферами или старенький BT4.2 от TI c CC2540 или его эмуляция на TLSR8266 на JDY-10...
Есть и такой вариант для обычного BT адаптера:

Windows 10
There is a Windows hardware developer package that includes a tool that supports capturing Bluetooth traffic directly in Wireshark.
Install
1 Download and install Wireshark.
2 Download and install the BTP software package.
Capture
To capture Bluetooth traffic:
1 Open a terminal as Administrator.
Search start menu for cmd. (Powershell and Windows Terminal are fine too.)
Right-click Command Prompt and select Run as Administrator.
2 Run C:\BTP\v1.9.0\x86\btvs.exe. This should automatically start Wireshark in capture mode.
The version needs to match the installed version. v1.9.0 was the current version at the time this was written. Additionally, C: may not be the root drive on some systems.
3 Run your Python script in a different terminal (not as Administrator) to reproduce the problem.
4 Click the stop button in Wireshark to stop the capture.
 

Slacky

Member
Обычный адаптер BT в Windows очень плохо работает с рекламными пакетами.
Под Debian 9 он вообще не работает. Проблема с драйверами realtek. Может вот такой попробовать, у меня одноплатник, там раньше WiFi модуль стоял, но я его убрал за ненадобностью - https://aliexpress.ru/item/10050014..._id=1005001465285549&sku_id=12000016223340443

или вот такой подешевле, но 4.0 - https://aliexpress.ru/item/10050019...erPdpSubstituteRcmd&tpp_rcmd_bucket_id=285258
 

pvvx

Активный участник сообщества
В Debian и Ubuntu всё работает. Только надо патчить ядро и добавить проприетарные бинарные драйвера загружаемые в сами адаптеры от Realtek в /usr/lib/firmware/rtl[wifi/bt/_bt].. Ссылку забыл, но она просто ищется...
Без патчей на текущий момент работает только Armbian (для всяких плат типа NanoPi и т.д.). Проверено на пяток типов BT(и + объединенных с WiFI) USB адаптерах и их клонах с али.
 

Slacky

Member
В Debian и Ubuntu всё работает. Только надо патчить ядро и добавить проприетарные бинарные драйвера загружаемые в сами адаптеры от Realtek в /usr/lib/firmware/rtl[wifi/bt/_bt].. Ссылку забыл, но она просто ищется...
Без патчей на текущий момент работает только Armbian (для всяких плат типа NanoPi и т.д.). Проверено на пяток типов BT(и + объединенных с WiFI) USB адаптерах и их клонах с али.
Ядро не патчил. Просто накатил драйвера из non-free репозитория - apt install firmware-realtek

Но не работает.

Код:
Jun 14 16:48:26 slacky-debian kernel: [531169.971578] usb 1-4: new full-speed USB device number 5 using xhci_hcd
Jun 14 16:48:26 slacky-debian kernel: [531170.112471] usb 1-4: New USB device found, idVendor=0bda, idProduct=8771
Jun 14 16:48:26 slacky-debian kernel: [531170.112477] usb 1-4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
Jun 14 16:48:26 slacky-debian kernel: [531170.112481] usb 1-4: Product: Bluetooth Radio
Jun 14 16:48:26 slacky-debian kernel: [531170.112484] usb 1-4: Manufacturer: Realtek
Jun 14 16:48:26 slacky-debian kernel: [531170.112488] usb 1-4: SerialNumber: 00E04C239987
Jun 14 16:48:26 slacky-debian kernel: [531170.116370] Bluetooth: hci0: rtl: examining hci_ver=0a hci_rev=000b lmp_ver=0a lmp_subver=8761
Jun 14 16:48:26 slacky-debian kernel: [531170.116377] Bluetooth: hci0: rtl: loading rtl_bt/rtl8761a_config.bin
Jun 14 16:48:26 slacky-debian kernel: [531170.116542] bluetooth hci0: Direct firmware load for rtl_bt/rtl8761a_config.bin failed with error -2
Jun 14 16:48:26 slacky-debian kernel: [531170.116646] Bluetooth: hci0: rtl: loading rtl_bt/rtl8761a_fw.bin
Jun 14 16:48:26 slacky-debian kernel: [531170.116774] bluetooth hci0: firmware: direct-loading firmware rtl_bt/rtl8761a_fw.bin
Jun 14 16:48:26 slacky-debian kernel: [531170.117357] Bluetooth: hci0: rom_version status=0 version=1
Jun 14 16:48:26 slacky-debian kernel: [531170.117385] Bluetooth: cfg_sz 0, total size 20204
Jun 14 16:49:59 slacky-debian kernel: [531263.747591] usb 1-4: USB disconnect, device number 5

Нашел обсуждение проблемы. Вышел вот сюда - https://github.com/mkopa/Linux-Driver-USB-Bluetooth-5.0-ORICO-BTA-508

Сделал, как у него в реадми написано. Вроде все поставилось. Но все равно не работает.

Код:
[13735.656349] usb 1-4: new full-speed USB device number 4 using xhci_hcd
[13735.797203] usb 1-4: New USB device found, idVendor=0bda, idProduct=8771
[13735.797209] usb 1-4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[13735.797212] usb 1-4: Product: Bluetooth Radio
[13735.797216] usb 1-4: Manufacturer: Realtek
[13735.797219] usb 1-4: SerialNumber: 00E04C239987
[13735.800471] Bluetooth: hci0: rtl: examining hci_ver=0a hci_rev=000b lmp_ver=0a lmp_subver=8761
[13735.800476] Bluetooth: hci0: rtl: loading rtl_bt/rtl8761a_config.bin
[13735.800535] bluetooth hci0: firmware: direct-loading firmware rtl_bt/rtl8761a_config.bin
[13735.800547] Bluetooth: hci0: rtl: loading rtl_bt/rtl8761a_fw.bin
[13735.800660] bluetooth hci0: firmware: direct-loading firmware rtl_bt/rtl8761a_fw.bin
[13735.801444] Bluetooth: hci0: rom_version status=0 version=1
[13735.801468] Bluetooth: cfg_sz 44, total size 14808
[13737.865157] Bluetooth: hci0 command 0xfc20 tx timeout
[13745.964116] Bluetooth: hci0: download fw command failed (-110)
 

pvvx

Активный участник сообщества
Ядро не патчил. Просто накатил драйвера из non-free репозитория - apt install firmware-realtek

Но не работает.
Там и есть вечная путаница rtl8761a и rtl8761b и несоответствие ответов команд от ядра... Разгребсти это сложно. Из того, что смотрел и ставил разные USB-BT, правильные исправления имеются только в Armbian - там пришлось только закинуть пару бинарных firmware для rtl и все какие скопились у меня адаптеры заработали. На последней Ubuntu (в принципе это одно ядро с Debian) половина не пашет, т.к. не предусмотрены варианты клонов от китайцев - затыкаются на первых ответах после загрузки firmware. В Ubuntu беды не с Realtek клонами, а с Mediatek Bluetooth клонами. С Realtek надо подбирать правильные firmware, с вариантом HCI который жрет ядро. Т.е. в большом линух всем пофигу - просто меняют адаптеры методом тыка - пашет или нет, и если не пашет - в помойку :)
 

pvvx

Активный участник сообщества
 

pvvx

Активный участник сообщества
Гарантированно и на всех системах всегда работает только CSR8510 A10. Но не клоны. У клонов часто другой код ответа при инициализации и в линухах ядро отбрыкивает их.
Определить можно только по внутренностям, сняв пластиковый корпус - там обычно бескорпусной чип (тупо на плату припаян кристалл) с маркировкой:

Это и один из самых быстрых адаптеров - принимает рекламных пакетов больше всех известных мне USB-BT. Имеет интерфейс связи HCI по USB2.0 HiSpeed. Но это древнее чудовище BT4... Т.е. наилучший вариант для интеграций с пассивным приемом реклам во всяких Home Assistant и типа.
 

pvvx

Активный участник сообщества
И т.к. в каждой сборке линухов всегда свои проблемы с адаптерами BT - я вам помочь ничем не могу. Это разгребается только на месте, имея конкретный линух с адаптером...
Вот, что ещё валяется "на столе" без дела:
1655411937917.png
Первый - это китайский клон CSR8510 A10 - не работает в линухах и windows. Имеет USB1.1. Работает только в Armbian (до этого уже хотел их выкинуть). Тормозит и нормально не принимает BLE рекламы. BT4.
Второй - realtek, не работает нв половине линух. Запускается там только с танцами с бубном и имеет BT5. Работает в Windows. Но так-же тормоз для приема BLE рекламы, хотя при соединении показывает скорости BT5 более менее.
Третий - очередной realtek с WiFi. Всё тоже-самое, что и предыдущий, но немного хуже из-за совмещения с WiFi...
 

Slacky

Member
А вот еще глупый вопрос :))

Если я разведу свою плату и оставлю вот эту схему впаянной намертво



Это отразится на работе модуля в штатном режиме? Или лучше сделать перемычку и сопротивление подключаемые на время?
 

pvvx

Активный участник сообщества
Это отразится на работе модуля в штатном режиме? Или лучше сделать перемычку и сопротивление подключаемые на время?
Непонятно: что у вас такое "в штатном режиме"?
У меня штатно, для программирования и отладки подключается SWS и иногда RST от нормального аппаратного программатора с SWM, да плюс контроль-измеритель питания на PowerProfiller...
Зачем на плате что-то замыкать - вдруг пригодится...
Вывод SWS = обычный GPIO, а выводы с RX-TX - это UART или другие функции...
 

Slacky

Member
А вот еще про ADC. Если мне нужно считывать показание с, например, двух разных GPIO, то правильно ли я понимаю, что каждый раз, прежде чем сосчитать показания, нужно сбрасывать и по-новой инитить adc под конкретный GPIO? Пример из SDK убогий, заточен только на один GPIO ...
 

pvvx

Активный участник сообщества
Желательно каждый раз включать и выключать ADC, т.к. он жрет +0.4 мА.
Можно не переинициализировать всё, а просто изменить регистры управления входами после каждого считывания замера.
У меня в термометрах используется полная инициализация с измерением на любой пин ADC. Используется номер канала ADC, а не GPIO.
 

aloika

Active member
В телинковской инструкции написано, что можно использовать только один канал ADC за раз, одновременно включать несколько каналов нельзя. Например, вот здесь:

Refer to the “8258 Datasheet” that the ADC state machine includes several channels such as Left, Right,
and Misc. Due to some special reasons, these state channels cannot work at the same time. Telink stipulates
that the channels in the ADC state machine must operate independently.
The Misc channel is used for low battery detect as the most basic ADC sampling. Users need to use the Misc
channel if they need other ADC tasks besides low battery detect. Amic Audio uses Left channel. The low
battery detect cannot run simultaneously with other ADC tasks and must be implemented by switching.
Но на самом деле это не так. Можно, можно. (Вопрос потребления мне не важен, т.к. девайс питается от розетки.)

Вот так я одновременно инициализирую Left channel и Misc channel:

C:
void my_app_adc_init_test(bool shorted)
{
    ///Step 1: power off sar adc/////////////////////////////////////////////////////////
        /******power off sar adc********/
        adc_power_on_sar_adc(0);
    //////////////////////////////////////////////////////////////////////////////////////


    ////Step 2: Config some common adc settings(user can not change these)/////////////////
        /******enable signal of 24M clock to sar adc********/
        adc_enable_clk_24m_to_sar_adc(1);

        /******set adc sample clk as 4MHz******/
        adc_set_sample_clk(5); //adc sample clk= 24M/(1+5)=4M

        /******set adc L R channel Gain Stage bias current trimming******/
        adc_set_left_gain_bias(GAIN_STAGE_BIAS_PER100);
        adc_set_right_gain_bias(GAIN_STAGE_BIAS_PER100);


        adc_set_chn_enable_and_max_state_cnt(ADC_MISC_CHN|ADC_LEFT_CHN, 4);      //set total length for sampling state machine and channel
        adc_set_state_length(240, 240, 10);      //set R_max_mc,R_max_c,R_max_s // 500 100

        gpio_set_func(GPIO_PB7, AS_GPIO);
        gpio_set_input_en(GPIO_PB7, 0);
        gpio_set_output_en(GPIO_PB7, 0);
        gpio_write(GPIO_PB7, 0);


        gpio_set_func(GPIO_PB6, AS_GPIO);
        gpio_set_input_en(GPIO_PB6, 0);
        gpio_set_output_en(GPIO_PB6, 0);
        gpio_write(GPIO_PB6, 0);

        if (shorted) //закороченные входы
        {
        adc_set_ain_channel_differential_mode(ADC_MISC_CHN, B7P, B7N);
        }
        else
        {
        adc_set_ain_channel_differential_mode(ADC_MISC_CHN, B7P, B6N /*B7P, B6N*/);
        }

        //set misc channel resolution 14 bit
        //notice that: in differential_mode MSB is sign bit, rest are data,  here BIT(13) is sign bit
        adc_set_resolution(ADC_MISC_CHN, RES14);  //set resolution


        //set misc channel vref 1.2V
        adc_set_ref_voltage(ADC_MISC_CHN, ADC_VREF_1P2V );                      //set channel Vref


        //set misc t_sample 6 cycle of adc clock:  6 * 1/4M
        adc_set_tsample_cycle(ADC_MISC_CHN, SAMPLING_CYCLES_6);      //Number of ADC clock cycles in sampling phase

        //set Analog input pre-scaling 1/8
        adc_set_ain_pre_scaler(ADC_PRESCALER_1F8);

        adc_config_misc_channel_buf((unsigned short *)adc_data_buf, ADC_SAMPLE_NUM<<2);  //size: ADC_SAMPLE_NUM*4
        dfifo_enable_dfifo2();

// left channel:

        AudioRate_Typedef Audio_Rate=AUDIO_16K;

        audio_config_mic_buf ( buffer_mic, TL_MIC_BUFFER_SIZE);

        gpio_set_output_en(GPIO_AMIC_SP, 0);
        gpio_set_output_en(GPIO_AMIC_SN, 0);

        adc_set_input_mode(ADC_LEFT_CHN, DIFFERENTIAL_MODE); //left channel differential mode
        adc_set_ain_channel_differential_mode(ADC_LEFT_CHN, PGA0P, PGA0N); //left channel positive and negative data in


        //adc_set_ref_voltage(ADC_LEFT_CHN, ADC_VREF_0P6V); // одинаковые должны быть

        adc_set_resolution(ADC_LEFT_CHN, RES14);                            //left channel resolution
        adc_set_tsample_cycle(ADC_LEFT_CHN, SAMPLING_CYCLES_6);                //left channel tsample

        //    adc_set_vref_vbat_divider(ADC_VBAT_DIVIDER_OFF);                    //vbat vref divider
//        adc_set_ain_pre_scaler(ADC_PRESCALER_1);  //ain pre scaler none

//        adc_set_itrim_preamp(ADC_CUR_TRIM_PER75);
//        adc_set_itrim_vrefbuf(ADC_CUR_TRIM_PER100);
//        adc_set_itrim_vcmbuf(ADC_CUR_TRIM_PER100);


        //PGA0 left  C0/C1 ON,
        //PGA1 right C2/C3 OFF

        SET_PGA_LEFT_P_AIN(PGA_AIN_C1);
        SET_PGA_LEFT_N_AIN(PGA_AIN_C1);
        SET_PGA_RIGHT_P_AIN(PGA_AIN_C0);
        SET_PGA_RIGHT_N_AIN(PGA_AIN_C0);


        //
        adc_set_left_boost_bias(GAIN_STAGE_BIAS_PER75);

        analog_write (areg_adc_pga_ctrl, MASK_VAL( FLD_PGA_ITRIM_GAIN_L, GAIN_STAGE_BIAS_PER150, \
                                                              FLD_PGA_ITRIM_GAIN_R,GAIN_STAGE_BIAS_PER150, \
                                                              FLD_ADC_MODE, 0, \
                                                              FLD_SAR_ADC_POWER_DOWN, 1, \
                                                              FLD_POWER_DOWN_PGA_CHN_L, 0, \
                                                              FLD_POWER_DOWN_PGA_CHN_R, 1) );


        WriteAnalogReg(0xfe,0x05);        //0x80+126  = 0x05,0xfe default value is 0xe5,for output audio, must clear 0xfe<7:5>

        ///////////////////////////////  PGA gain setting ///////////////////////////////////////
        //0xb63[7] 1b'1 enable gain mode to manual mode  manual mode 1

        reg_pga_fix_value = MASK_VAL(    FLD_PGA_POST_AMPLIFIER_GAIN,PGA_POST_GAIN_12DB,\
                                        FLD_PGA_PRE_AMPLIFIER_GAIN,PGA_PRE_GAIN_38DB,\
                                        FLD_PGA_GAIN_FIX_EN, 1);


            ////////////////////////////// ALC HPF LPF setting /////////////////////////////////
        //enable hpf, enable lpf, anable alc, disable double_down_sampling


        reg_aud_alc_hpf_lpf_ctrl =   MASK_VAL( FLD_AUD_IN_HPF_SFT,  0x07,   //different pcb may set different value. 5
                                                   FLD_AUD_IN_HPF_BYPASS, 0, \
                                                   FLD_AUD_IN_ALC_BYPASS, 1, \
                                                   FLD_AUD_IN_LPF_BYPASS, 1, \
                                                   FLD_DOUBLE_DOWN_SAMPLING_ON,\
                                                   (Audio_Rate==AUDIO_32K)?0:1);


            if(Audio_Rate==AUDIO_32K)
            {
                reg_dfifo_dec_ratio = AMIC_CIC_Rate[AUDIO_32K];
            }
            else
            {
                if(Audio_Rate==AUDIO_16K)
                {
                    reg_dfifo_dec_ratio = AMIC_CIC_Rate[AUDIO_32K];//32k
                }
                else if(Audio_Rate==AUDIO_8K)
                {
                    reg_dfifo_dec_ratio = AMIC_CIC_Rate[AUDIO_16K];//16k
                }
            }

            //alc mode select digital mode
            reg_aud_alc_cfg &= ~FLD_AUD_ALC_ANALOG_MODE_EN;

            //alc left channel select manual regulate, and set volume //0x28
            reg_aud_alc_vol_l_chn = MASK_VAL( FLD_AUD_ALC_MIN_VOLUME_IN_DIGITAL_MODE,  0x8, \
                                              FLD_AUD_ALC_DIGITAL_MODE_AUTO_REGULATE_EN, 0);

            //2. Dfifo setting
            reg_clk_en2 |= FLD_CLK2_DFIFO_EN; //enable dfifo clock, this will be initialed in cpu_wakeup_int()
        #if AUDIO_DBL_BUF_ENABLE
            reg_dfifo_mode = FLD_AUD_DFIFO1_IN;
        #else
            reg_dfifo_mode |= FLD_AUD_DFIFO0_IN;

        #endif

            //amic input, mono mode, enable decimation filter
            reg_dfifo_ain =  MASK_VAL( FLD_AUD_DMIC0_DATA_IN_RISING_EDGE,AUDIO_DMIC_DATA_IN_FALLING_EDGE,\
                                            FLD_AUD_INPUT_SELECT, AUDIO_INPUT_AMIC, \
                                            FLD_AUD_INPUT_MONO_MODE, 1, \
                                            FLD_AUD_DECIMATION_FILTER_BYPASS, 1);


            reg_audio_dec_mode  |= FLD_AUD_LNR_VALID_SEL | FLD_AUD_CIC_MODE;

            adc_power_on_sar_adc(1);



}
/////////////////////////////////////////////////// end test //////////////////////////////////////////////////////////////////
 

aloika

Active member
А вот так получаю значение с misc:

C:
signed int my_adc_sample_and_get_result(void)
{
    signed short temp;


    int i,j;

    signed short adc_sample[ADC_SAMPLE_NUM] = {0};
    signed short  adc_result=0;


//////////////// get adc sample data and sort these data ////////////////

    for(i=0;i<ADC_SAMPLE_NUM;i++){
    

        adc_sample[i] = (short)adc_data_buf[i];


        //insert sort
        if(i){
            if(adc_sample[i] < adc_sample[i-1]){
                temp = adc_sample[i];
                adc_sample[i] = adc_sample[i-1];
                for(j=i-1;j>=0 && adc_sample[j] > temp;j--){
                    adc_sample[j+1] = adc_sample[j];
                }
                adc_sample[j+1] = temp;
            }
        }
    }

int sum = 0;

for(i=ADC_SAMPLE_NUM/4;i<ADC_SAMPLE_NUM-ADC_SAMPLE_NUM/4;i++)
{
sum=sum+adc_sample[i];
}

    int adc_average=sum/(ADC_SAMPLE_NUM/2);

    adc_result = adc_average;

    return adc_result;
}

А вот так - с left:

C:
signed short my_amic_sample_and_get_result(void)
{
        signed short  adc_result=0, temp;
        int i,j, sum=0;
        signed short mic_samples[TL_MIC_BUFFER_SIZE>>1] = {0};

// Значений всего 32, а не 64, т.е. всего TL_MIC_BUFFER_SIZE>>1 = TL_MIC_BUFFER_SIZE/2  !!!!
/*
        printf("ns: {");
        //array_printf((u8*)buffer_mic,64);
        for(int i=0; i<TL_MIC_BUFFER_SIZE>>1;i++)
        {
            printf("%d, ", (s16)buffer_mic[i] );
        }
        printf("} \n\r");
*/
        for(i=0;i<TL_MIC_BUFFER_SIZE>>1;i++){
                mic_samples[i] = (s16)buffer_mic[i];
                //insert sort
                if(i){
                    if(mic_samples[i] < mic_samples[i-1]){
                        temp = mic_samples[i];
                        mic_samples[i] = mic_samples[i-1];
                        for(j=i-1;j>=0 && mic_samples[j] > temp;j--){
                            mic_samples[j+1] = mic_samples[j];
                        }
                        mic_samples[j+1] = temp;
                    }
                }
            }
/*
        printf("s: {");
        //array_printf((u8*)buffer_mic,64);
        for(int i=0; i<TL_MIC_BUFFER_SIZE>>1;i++)
        {
            printf("%d, ", mic_samples[i] );
        }
        printf("} \n\r");

*/
//                    8                            32               -        8
        for(i=TL_MIC_BUFFER_SIZE>>3; i<(TL_MIC_BUFFER_SIZE>>1) - (TL_MIC_BUFFER_SIZE>>3);i++)
            {
                sum=sum+abs(mic_samples[i]);
            }

        adc_result=sum/(TL_MIC_BUFFER_SIZE>>2);

//        printf("res: %d, \n\r", adc_result);

/*        if (adc_result>0xF) BLUE_LED_ON; else BLUE_LED_OFF;
        extern int putchar();
        putchar((adc_result)); */

        return adc_result;
}
 

pvvx

Активный участник сообщества
В телинковской инструкции написано, что можно использовать только один канал ADC за раз, одновременно включать несколько каналов нельзя. Например, вот здесь:
В инструкции числится, что сразу 3 канала (одновременно):
1656296391376.png
Но left и Right фиксированы по GPIO и подключены к PGA. Требуют настройки других audio частей...

PS: Всё это было проверено ещё в TLSR8269. У TLSR825x ADC практически аналогичен TLSR8266/8269. Но у TLSR8266 толи баг, толи что-то подрезано в кристалле и не всё соответствует полной доке (дока по 8269, а для 8266 описание ADC скомкано - наверно баги в кристалле).
 
Сверху Снизу