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

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

pvvx

Активный участник сообщества
Доп. MCU ещё жрет батарейку, а при передаче на скорости 9600 жрут оба чипа. Почему не сделали 1Мбит - непонятно.
 

pvvx

Активный участник сообщества
ZTH01
Что-то, что смотрел по передаче в UART:
 

Вложения

pvvx

Активный участник сообщества
Есть ли где протоколы (обычно UART) для работы с потрохами к последним дешевым китайским инверторным кондиционерам?
Пульты у всех часто одинаковые по кодам, заводов вроде 3 или 4 всего... Названия кондеев разные, т.к. на заказ партии в тусчу штук рисуют любое и пульт тоже.
Наверно и протокол один для подключения всяких блоков WiFi...
 

Slacky

Member
А вот есть еще вопрос :))

Есть такой чайник - XIAOMI Mi Smart Kettle Pro. Он BLE. Но чипы, примененные в них могут быть разные. Вот пока точно знаю, что есть версия на TLSR8269, а есть на TLSR8250. Вопрос - можно как-то не разбирая чайник проверить, на каком чипе он собран?photo_2024-06-25_17-38-55.jpg
1000051014.jpg
 

pvvx

Активный участник сообщества
Там наверно Tuya прошивка, а по ней не определить. Если только по номеру версии?
 

Slacky

Member
TLSR8258. SDK Zigbee. ADC.

Вдруг кому пригодится.

Понадобилось мне тут измерять 9 вольтовую батарейку с шагом 0.1 вольт. Собрал резистивный делитель 1 к 3. Прогнал по напряжением от 5 до 9 вольт. Записал значения, подобрал поправочный коэффициент. Все вроде нормально. Но попался чип, который показывал на 0.1 вольт меньше, чем все остальные. Полез посмотреть, что есть полезного и нашел такой файлик в драайверах drv_calibration.c. Там есть интересный момент, где что-то считывается из определенных ячеек флешки. Для 512к версии это 0x770c0.

C:
static void drv_calib_adc_verf(void)
{
    u8 adc_vref_calib_value[7] = {0};
    u16 gpio_calib_vref = 0;
    s8 gpio_calib_vref_offset = 0;

    flash_read(CFG_ADC_CALIBRATION, 7, adc_vref_calib_value);

#if defined(MCU_CORE_8258) || defined(MCU_CORE_8278)
    //Check the two-point gpio calibration value whether is exist
    if((adc_vref_calib_value[4] != 0xff) &&
       (adc_vref_calib_value[4] <= 0x7f) &&
       (adc_vref_calib_value[5] != 0xff) &&
       (adc_vref_calib_value[6] != 0xff)){
        /****** Method of calculating two-point gpio calibration Flash_gain and Flash_offset value: ********/
        /****** Vref = [(Seven_Byte << 8) + Six_Byte + 1000]mv ********/
        /****** offset = [Five_Byte - 20] mv. ********/
        gpio_calib_vref = (adc_vref_calib_value[6] << 8) + adc_vref_calib_value[5] + 1000;
        gpio_calib_vref_offset = adc_vref_calib_value[4] - 20;
Видно, что читается 7 байт, но используется только 5, 6 и 7. А первые 4 вообще не проверяются. Ну и к тому же вообще нигде этот код не вызывается.

В общем заиспользовал я эти 4 байта под свои нужны. И теперь проверяем экземпляр и если он немного занижает или завышает показания, записываем по адресу 0x770c0 свои 4 байта информации, типа

C:
typedef struct __attribute__((packed)) _adc_calibration_t {
    uint16_t    id;                             /* 0x1965                             */
    uint8_t     voltage_factor;                 /* 1-255; default - 0x78 (120)        */
    uint8_t     reserve;
} adc_calibration_t;
И при старте проверяем, что там. Если там есть наш идентификатор, то поправку берем из флеш, если нет, то стандартно, по умолчанию.

C:
        flash_read(CFG_ADC_CALIBRATION, 4, (uint8_t*)&adc_calibration);

        if (adc_calibration.id == ADC_CALIBRATION_ID) {
#if UART_PRINTF_MODE && DEBUG_BATTERY
            printf("voltage_factor from flash\r\n");
#endif
            voltage_factor = adc_calibration.voltage_factor;
            /* voltage_factor should not be 0 */
            if (voltage_factor == 0) voltage_factor++;
        } else {
#if UART_PRINTF_MODE && DEBUG_BATTERY
            printf("voltage_factor from #define\r\n");
#endif
            voltage_factor = VOLTAGE_FACTOR;
        }
 

pvvx

Активный участник сообщества
Я не пользую калибровки и вообще процедуры ADC из SDK, т.к. они кошмарные.
Да и указанные корректировочные значения используются только в одной версии оф. SDK.

> Но попался чип, который показывал на 0.1 вольт меньше, чем все остальные.
Вот этим и грозит - попался чип с записью каких-то байт в левом секторе, который для данного SDK есть калибровка :p

Из более 80 устройств с TLSR825x пока ADC у всех одинаково.
 

pvvx

Активный участник сообщества
> Собрал резистивный делитель 1 к 3.

В делителе, т.к. резисторы высокоомные, требуется емкость в диапазоне от 3..10 нФ.
И может "попавшийся" чип имеет подожжённый GPIO....
 

pvvx

Активный участник сообщества
> Ну и к тому же вообще нигде этот код не вызывается.

Вызывается в drv_platform_init() в SDK Zigbee. А drv_platform_init() вызывается в main().
 

pvvx

Активный участник сообщества
И в оф. Zigbee SDK ADC трогать незя - он постоянно опрашивается при любом обращении к функциям Flash. При этом ADC инициализируется один раз при старте voltage_detect_init(), а далее просто считывают значения voltage_detect() и если менее BATTERY_SAFETY_THRESHOLD, то reset или PM_SLEEP... :) :)
Я замучалcя это всё патчить... - батарейка не садится за миллисекунды, как там она опрашивается. Да и при нормальном подходе к записи во Flash - пофигу, что сорвет последнюю запись.
 

pvvx

Активный участник сообщества
Конденсаторов в питании, которые стоят в устройствах, всё равно не хватит на завершение стирания сектора или записи конфигов Zigbee. Обычно кондеры вообще отсутствуют - китайцы экономят на всём. А SDK наверно писано для макетных плат от Telink с кондерами по расчету (от нескольких десятков мкФ - к сотне)...
 

pvvx

Активный участник сообщества
@Slacky - вот у вас в коде каждую итерацию while(1) опрашивается ADC
При этом никакой переинициализации ADC после старта не делается. Т.е. ADC трогать незя.
 

Slacky

Member
> Ну и к тому же вообще нигде этот код не вызывается.

Вызывается в drv_platform_init() в SDK Zigbee. А drv_platform_init() вызывается в main().
Действительно. Сейчас посмотрел, есть такое. Странно, что я, когда проверял, этого не обнаружил.
 

Slacky

Member
@Slacky - вот у вас в коде каждую итерацию while(1) опрашивается ADC
При этом никакой переинициализации ADC после старта не делается. Т.е. ADC трогать незя.
Этот кусок не мой. Это стандартный, из SDK. Я его даже не трогал.

Но! Все равно, первые 4 байта 0x770c0 не используются (наверно :))

А вот еще, что происходит с калибровкой, если флеш очистить? Если там были какие-то значения, они затрутся ...
 

Slacky

Member
Не, используются первый два байта.

C:
}else{
        /****** If flash do not exist the two-point gpio calibration value,use the one-point gpio calibration value ********/
        /****** Method of calculating one-point gpio calibration Flash_gpio_Vref value: ********/
        /****** Vref = [1175 +First_Byte-255+Second_Byte] mV = [920 + First_Byte + Second_Byte] mV ********/
        gpio_calib_vref = 920 + adc_vref_calib_value[0] + adc_vref_calib_value[1];
        /****** Check the one-point calibration value whether is correct ********/
        if((gpio_calib_vref >= 1047) && (gpio_calib_vref <= 1302)){
            adc_set_gpio_calib_vref(gpio_calib_vref);
        }
    }
Бум думать ...
 

Slacky

Member
Вот есть еще область
Скриншот 31-08-2024 105125.jpg
U_Cfg_Info. Там используется только первый 16 байт. Больше я нигде в коде не нашел, что там еще что-то пишется/читается.

C:
/**************************************************************************************
 * The following is the detailed user configure information (U_CFG_Info).
 */
/* 16 bytes for pre-install code. */
#if(FLASH_CAP_SIZE_1M || FLASH_CAP_SIZE_2M || FLASH_CAP_SIZE_4M)
#define CFG_PRE_INSTALL_CODE            (0xFD000)
#else
#define CFG_PRE_INSTALL_CODE            (0x78000)
#endif
И только в одном месте встречается чтение этого адреса.

C:
CODE_BDB_ u8 bdb_preInstallCodeLoad(u8 *keyType, u8 derivedKey[])
{
    u8 invalidInstallCode[SEC_KEY_LEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
                                           0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
    u8 installCode[SEC_KEY_LEN];

    flash_read(CFG_PRE_INSTALL_CODE, SEC_KEY_LEN, (u8 *)installCode);

    if(!memcmp((u8 *)installCode, (u8 *)invalidInstallCode, SEC_KEY_LEN)){
        return RET_NOT_FOUND;
    }

    tl_bdbUseInstallCode(installCode, derivedKey);
    *keyType = SS_UNIQUE_LINK_KEY;

    return RET_OK;
}
Потому, наверно :), можно что-то безболезненно для системы записать например по адресу CFG_PRE_INSTALL_CODE+0x100

Как-то так.
 
Сверху Снизу