• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Power Profiler

pvvx

Активный участник сообщества
откуда такие умозаключения? что опять ... Л - логика?
Вот по этому:
чем теорией по древу растекаться , да тактики подчитывать не проще ли взять и на практике это всё подтвердить...
Или по тому, что уже опробовано много раз.
лично я ИМ больше доверяю, ибо производители чипов не такие дураки %username%
Доверяйте, но проверяйте.
А пока только пишите и высосанные из пальца заключения выводите, другие давно проверили и показывают вам работающие варианты :p
 

pvvx

Активный участник сообщества
ибо производители чипов не такие дураки %username%
вот именно %name% производителя о многом и говорит. Одни ничего не смыслят в разработки SoC и бабла нема на спецов (Espressif и типа), другие тупо повторяют и играют на глупости уже %username% с помощью рекламы (Nordic, Ti часто, AVR (уже в небытье) и подобные), третьи серьезно занимаются, включая освоенную военную приемку и содержание специалистов, и ставят в чип всё более менее нормальное (Zilog, Microchip иногда, для возможности по случаю сбыть за дорого воякам), у четверых вал и им бир-бар сколько стоят лицензии, т.к. всё на конвейере (Realtek, Samsung, ...) ...
 

pvvx

Активный участник сообщества
А народ как всегда выбирает худшее. Это от естественного отбора - он более не нужен на шарике. Закон природы.
 

pvvx

Активный участник сообщества
В итоге так и выходит, что если взять аппаратуру которая работает круглосуточно и не имеет никаких проблем с совтом и прочим, то в нашей сфере WiFi с малыми SoC это почти на 90% стоит чип Realtek (как SoC, так и отдельные чипы). Для BLE рынок ещё поделен на регионы и устоявшихся нет. Из малых чипов BLE, по программе партии Китая на конкурсной основе разработан PHY62x2 как замена евпопейским… В России хоть что двигается, кроме выращивая отщепенцев типа @cheblin?
 

pvvx

Активный участник сообщества
браво!
ща посмотрим...
минуточку...а где исходники на JDY-10 ????
бинарник вижу... исходники билли где?
Не позволяет лицензия в заголовках распространяемых файлов SDK Telink. Много раз уже говорил.
Купите мне лицензию у Telink для перевода их в MIT или GNU, я повешу над ними, как это делают Adafruit и прочие.
Или вы видели на github Telink SDK? Тогда тоже можно сослаться на то что оно кем-то публиковано... Но это кривой метод.
По тому могу only передать вам через личку, а не через github.
 

cheblin

Member
Telink по барабану... кто ищет тот найдёт

интересен кастомный код
 

pvvx

Активный участник сообщества
Вам всё равно не нужно SDK, а нужна Рыба, основные процедуры, которые я туды вписал:
Код:
/* Рыба, основные процедуры, без SDK Telink */

#define MIN_TSPS_US  400 // 400 us

#define SMPS_BLK_CNT    116 // ((20+27*7-2)/2)&0xFFFE = 102 or ((20+27*8-2)/2)&0xFFFE = 116
#define DLE_DATA_SIZE (SMPS_BLK_CNT*2+2)
#define MTU_DATA_SIZE (DLE_DATA_SIZE+7) // -(3 байта заголовка ATT и 4 байта заголовка L2CAP)

typedef struct  __attribute__((packed)) _reg_rd_t{
    uint8_t dev_addr; // адрес на шине i2c
    uint8_t reg_addr; // номер регистра чтения
} reg_rd_t;

typedef struct __attribute__((packed)) _reg_wr_t{
    uint8_t dev_addr; // адрес на шине i2c
    uint8_t reg_addr; // номер регистра чтения
    uint16_t data; // значение для записи в регистр
} reg_wr_t;

#define MAX_INIT_REGS 4
#define MAX_READ_REGS 4

// Структура конфигурации опроса и инициализации устройства
// Выходной пакет непрерывного опроса формируется по данному описанию
typedef struct __attribute__((packed)) _dev_cfg_t {
    uint8_t rd_count;     // кол-во регистров для разового чтения
    uint8_t init_count; // кол-во регистров для инициализации
    uint8_t multiplier; // множитель периода опроса, time << multiplier
    uint8_t pktcnt;      // кол-во передаваемых значений из регистров в одном пакете передачи
    uint16_t time;         // период опроса регистров чтения в us
    uint16_t clk_khz;     // частота i2c шины в kHz
    reg_wr_t init[MAX_INIT_REGS];
    reg_rd_t rd[MAX_READ_REGS];
} dev_cfg_t; // 8 + 4*4 + 2*4

// DEV_I2C cmd:
#define CMD_DI2C_VER  0x00 // Get Ver
#define CMD_DI2C_CFG  0x01 // Get/Set CFG/ini & Start measure
#define CMD_DI2C_SCF  0x02 // Store CFG/ini in Flash
#define CMD_DI2C_STA  0x03 // Status
#define CMD_DI2C_CPU  0x04 // Connect parameters Update (BLE)
#define CMD_DI2C_BLK  0x07 // blk out regs data
#define CMD_DI2C_ERR  0x0f // Runtime Error
#define CMD_DI2C_GRG  0x10 // Get reg
#define CMD_DI2C_SRG  0x11 // Set reg
//
#define CMD_ERR_FLG   0x80 // send error cmd mask
//
typedef struct __attribute__((packed)) {
    uint8_t size; // размер пакета
    uint8_t cmd;  // номер команды / тип пакета
} blk_head_t;

typedef struct __attribute__((packed)) _blk_tx_pkt_t{
    blk_head_t head;
    union __attribute__((packed)) {
        uint8_t uc[MTU_DATA_SIZE-sizeof(blk_head_t)];
        int8_t sc[MTU_DATA_SIZE-sizeof(blk_head_t)];
        uint16_t ui[(MTU_DATA_SIZE-sizeof(blk_head_t))/sizeof(uint16_t)];
        int16_t si[(MTU_DATA_SIZE-sizeof(blk_head_t))/sizeof(int16_t)];
        uint32_t ud[(MTU_DATA_SIZE-sizeof(blk_head_t))/sizeof(uint32_t)];
        int32_t sd[(MTU_DATA_SIZE-sizeof(blk_head_t))/sizeof(uint32_t)];
        reg_wr_t reg;
    } data;
} blk_tx_pkt_t;

#define MTU_RX_DATA_SIZE (sizeof(blk_head_t) + sizeof(dev_cfg_t))

typedef struct __attribute__((packed)) _blk_rx_pkt_t{
    blk_head_t head;
    union __attribute__((packed)) {
        uint8_t uc[MTU_RX_DATA_SIZE-sizeof(blk_head_t)];
        int8_t sc[MTU_RX_DATA_SIZE-sizeof(blk_head_t)];
        uint16_t ui[(MTU_RX_DATA_SIZE-sizeof(blk_head_t))/sizeof(uint16_t)];
        int16_t si[(MTU_RX_DATA_SIZE-sizeof(blk_head_t))/sizeof(int16_t)];
        uint32_t ud[(MTU_RX_DATA_SIZE-sizeof(blk_head_t))/sizeof(uint32_t)];
        int32_t sd[(MTU_RX_DATA_SIZE-sizeof(blk_head_t))/sizeof(uint32_t)];
        dev_cfg_t cfg;
        reg_wr_t reg;
    } data;
} blk_rx_pkt_t;

extern blk_rx_pkt_t read_pkt;
extern blk_tx_pkt_t send_pkt;

u32 tick_wakeup;

u8 ui_ota_is_working = 0;
u8 device_in_connection_state = 0;
u8 ui_mtu_size_exchange_req = 0;

u8 wrk_enable = 0;
u8 wrk_tick = 0;

u8 rx_len = 0;
u8 tx_len = 0;

blk_rx_pkt_t read_pkt;
blk_tx_pkt_t send_pkt;

volatile uint8_t timer_flg = 0;
u32 all_rd_count = 0;
u32 not_send_count = 0;
u16 buf[256];
u32 buf_wr = 0;
u32 buf_rd = 0;
u8 rd_next_cnt;

// I2C device GetNewRegData
// Called from Irq (!) Timer
_attribute_ram_code_ void GetNewRegData(void) {
    if (rd_next_cnt >= cfg_ini.rd_count) rd_next_cnt = 0;
    reg_rd_t * raddr = &cfg_ini.rd[rd_next_cnt++];
    I2CBusReadWord(raddr->dev_addr, raddr->reg_addr, &buf[buf_wr]);
    all_rd_count++;
    buf_wr++;
    buf_wr &= 255;
}

// Define USB rx/tx buffer
#define RX_BUF_LEN    USB_CDC_MAX_RX_BLK_SIZE // in bytes
#define TX_BUF_LEN    MTU_DATA_SIZE // in bytes (MTU BLE)
#define RX_BUF_NUM    2
static unsigned char rx_buf[RX_BUF_NUM][RX_BUF_LEN];
static unsigned char tx_buf[TX_BUF_LEN];
static unsigned char rx_ptr = 0;

volatile u8 usb_actived;

void Timer_Stop(void) {
    timer_flg = 0;
    reg_tmr1_tick = 0;
    reg_tmr_sta = FLD_TMR_STA_TMR1;
    reg_irq_mask1 &= ~FLD_IRQ_TMR1_EN;
    reg_tmr_ctrl8 &= ~FLD_TMR1_EN;
}
void Timer_Init(uint32_t period_us) {
    reg_tmr1_tick = 0;
    reg_tmr1_capt = period_us * CLOCK_SYS_CLOCK_1US;
    reg_tmr_ctrl8 |= FLD_TMR1_EN; //     FLD_TMR1_MODE = 0
    reg_irq_mask1 |= FLD_IRQ_TMR1_EN;
    reg_tmr_sta = FLD_TMR_STA_TMR1; // clear irq status
}
int InitExtI2CDevice(void) {
    u32 i;
    timer_flg = 0;
    pkt_smp_max = 2;
    if(cfg_ini.clk_khz < 100 || cfg_ini.clk_khz > 2500)
        cfg_ini.clk_khz = 1000;
    I2CBusInit(cfg_ini.clk_khz * 1000);
    if(cfg_ini.rd_count > MAX_READ_REGS) cfg_ini.rd_count = 0;
    u32 t_us = cfg_ini.time << cfg_ini.multiplier;
    // ~ 30 us on 1 MHz I2C CLK (5 us + 25 us)
    if(usb_actived) i = 30;
    else i = MIN_TSPS_US;
    if(i < t_us && t_us > 0xffffffff/CLOCK_SYS_CLOCK_1US) {
        cfg_ini.rd_count = 0;
        Timer_Stop();
        return 0;
    }
    if (cfg_ini.rd_count) {
        Timer_Init(t_us);
        if(cfg_ini.pktcnt != 0 && cfg_ini.pktcnt <= SMPS_BLK_CNT)
            pkt_smp_max = cfg_ini.pktcnt;
    } else {
        Timer_Stop();
    }
    all_rd_count = 0;
    not_send_count = 0;

    if (cfg_ini.init_count > MAX_INIT_REGS) cfg_ini.init_count = 0;
    else for(i = 0; i < cfg_ini.init_count ; i++) {
        if (!I2CBusWriteWord(cfg_ini.init[i].dev_addr, cfg_ini.init[i].reg_addr, cfg_ini.init[i].data)) {
            Timer_Stop();
            return 0;
        }
    }
    rd_next_cnt = 0;
    buf_wr = 0;
    buf_rd = 0;
    return 1;
}

/*******************************************************************************
* Function Name : usb_ble_cmd_loop.
* Description     : Main loop routine.
* Input         : blk_tx_pkt_t * pbufo, blk_tx_pkt_t * pbufi, int rxlen
* Return         : txlen.
*******************************************************************************/
unsigned int cmd_loop(blk_tx_pkt_t * pbufo, blk_rx_pkt_t * pbufi, unsigned int rxlen) {
    unsigned int txlen = 0;
        pbufo->head.cmd = pbufi->head.cmd;
        switch (pbufi->head.cmd) {
        case CMD_DI2C_VER: // Get Ver
            pbufo->data.ui[0] = 0x1016; // DevID = 0x1016
            pbufo->data.ui[1] = 0x0007; // Ver 0.0.0.7 = 0x0007
            txlen = sizeof(u16) + sizeof(u16) + sizeof(blk_head_t);
            break;
        case CMD_DI2C_CFG: // Get/Set CFG/ini & Start measure
            if (pbufi->head.size) {
                timer_flg = 0;
                memcpy(&cfg_ini, &pbufi->data,
                    (pbufi->head.size > sizeof(cfg_ini))? sizeof(cfg_ini) : pbufi->head.size);
                if (!InitExtI2CDevice()) {
                    pbufo->head.cmd |= CMD_ERR_FLG; // Error cmd
                    txlen = 0 + sizeof(blk_head_t);
                    break;
                }
                timer_flg = 1;
            }
            memcpy(&pbufo->data, &cfg_ini, sizeof(cfg_ini));
            txlen = sizeof(cfg_ini) + sizeof(blk_head_t);
            break;
        case CMD_DI2C_SCF: // Store CFG/ini in Flash
            flash_write_cfg(&cfg_ini, EEP_I2C_CFG_ID, sizeof(cfg_ini));
            txlen = sizeof(blk_head_t);
            break;
        case CMD_DI2C_STA: // Status
            pbufo->data.ud[0] = all_rd_count;
            pbufo->data.ud[1] = not_send_count;
            txlen = 8 + sizeof(blk_head_t);
            break;
        //-------
        case CMD_DI2C_CPU: // Connect parameters Update
            if(!usb_actived) {
                if (pbufi->head.size)
                    bls_l2cap_requestConnParamUpdate(pbufi->data.ui[0],pbufi->data.ui[1],pbufi->data.ui[2],pbufi->data.ui[3]);
                extern void blt_get_conn_para(u8 * x);
                blt_get_conn_para((u8 *)&pbufi->data);
                txlen = 8 + sizeof(blk_head_t);
            } else {
                pbufo->head.cmd |= CMD_ERR_FLG; // Error cmd
                txlen = 0 + sizeof(blk_head_t);
            }
            break;
        //-------
        case CMD_DI2C_GRG: // Get reg
            timer_flg = 0;
            if (I2CBusReadWord(pbufi->data.reg.dev_addr, pbufi->data.reg.reg_addr,
                (uint16_t *)&pbufo->data.reg.data)) {
                pbufo->data.ui[0] = pbufi->data.ui[0];
                timer_flg = 1;
                txlen = sizeof(reg_wr_t) + sizeof(blk_head_t);
            } else {
                timer_flg = 1;
                pbufo->head.cmd |= CMD_ERR_FLG; // Error cmd
                txlen = 0 + sizeof(blk_head_t);
            };
            break;
        case CMD_DI2C_SRG: // Set reg
            timer_flg = 0;
            if (I2CBusWriteWord(pbufi->data.reg.dev_addr, pbufi->data.reg.reg_addr,
                    pbufi->data.reg.data)) {
                pbufo->data.reg = pbufi->data.reg;
                timer_flg = 1;
                txlen = sizeof(reg_wr_t) + sizeof(blk_head_t);
            } else {
                timer_flg = 1;
                pbufo->head.cmd |= CMD_ERR_FLG; // Error cmd
                txlen = 0 + sizeof(blk_head_t);
            };
            break;
        default:
            pbufo->head.cmd |= CMD_ERR_FLG; // Error cmd
            txlen = 0 + sizeof(blk_head_t);
            break;
        };
        pbufo->head.size = txlen - sizeof(blk_head_t);
    return txlen;
}
Код дров (процедуры) с I2C описан ранее и не менялся.
См. вторую часть, т.к. в сообщение форума портянка не лезет.
 

pvvx

Активный участник сообщества
Код:
/////////////////////////////////////////////////////////////////////
// main usb loop flow
/////////////////////////////////////////////////////////////////////
void main_usb_loop() {
    u32 i;
    if(tx_len) {
        if(USBCDC_IsAvailable()) {
            memcpy(&tx_buf, &send_pkt, tx_len);
            USBCDC_DataSend((unsigned char *)&tx_buf, tx_len);
            tx_len = 0;
        }
    } else
    if(cfg_ini.rd_count
        && timer_flg
        && ((buf_wr - buf_rd) & 255) > pkt_smp_max) {
        send_pkt.head.size = pkt_smp_max*2;
        send_pkt.head.cmd = CMD_DI2C_BLK;
        for(i = 0; i < pkt_smp_max ; i ++) {
            send_pkt.data.si[i] = buf[buf_rd];
            buf_rd++;
            buf_rd &= 255;
        }
        tx_len = pkt_smp_max*2+2;
    } else
    if(rx_len) {
        tx_len = cmd_loop(&send_pkt, &read_pkt, rx_len);
        rx_len = 0;
    }
}

//----------
void send_ble_err(u16 err_id, u16 err) {
    send_pkt.head.size = 4;
    send_pkt.head.cmd = CMD_DI2C_ERR;
    send_pkt.data.ui[0] = err_id;
    send_pkt.data.ui[1] = err;
    bls_att_pushIndicateData(SPP_Server2Client_INPUT_DP_H, (u8 *) &send_pkt, 2+2+2);
}
//----------
void send_usb_err(u16 err_id, u16 err) {
    send_pkt.head.size = 4;
    send_pkt.head.cmd = CMD_DI2C_ERR;
    send_pkt.data.ui[0] = err_id;
    send_pkt.data.ui[1] = err;
    if(USBCDC_IsAvailable()) {
        USBCDC_DataSend((u8 *) &send_pkt, 2+2+2);
    }
}

//---- IRQ
_attribute_ram_code_ void irq_handler(void)
{
    if((reg_irq_mask1 & FLD_IRQ_TMR1_EN) != 0 && (reg_irq_src & FLD_IRQ_TMR1_EN) != 0) {
        reg_tmr_sta = FLD_TMR_STA_TMR1; // clear irq status
        if(timer_flg)
            GetNewRegData();
        reg_irq_src =  FLD_IRQ_TMR1_EN;
    }
    if(usb_actived)
        USB_IrqHandle(reg_irq_src);
    else
        irq_blt_sdk_handler();
}
//-----------------
int main (void) {
    // init .....

    irq_enable();

    if(usb_actived) {
        while (1) {
#if (MODULE_WATCHDOG_ENABLE)
            wd_clear(); //clear watch dog
#endif
            main_usb_loop();
        }
    } else {
        while (1) {
#if (MODULE_WATCHDOG_ENABLE)
            wd_clear(); //clear watch dog
#endif
            main_ble_loop();
        }
    }
}
Процедуру main_ble_loop не привожу - там много лишнего и связанного со спецификой работы BLE. Но основа та-же, что и у main_usb_loop()
 

pvvx

Активный участник сообщества
Нашли отличие от исходников для STM32? :D
Нема. Но проц тут включил на 16 MHz и он значительно тупее самого первого ARM и памяти менее чем у STM32F103 (да ещё BLE стек и OTA, но свободной RAM осталось больше - более половины!). А скорость на USB дает от 400 кб/сек :p
 

pvvx

Активный участник сообщества
И если так выразиться, MTU USB (FIFO RX end_points) у TLSR826x до 256 байт, а не 64. Но я это не использовал для полной совместимости с USB1.1...
Драйвер USB-COM полностью мой. Но пользует Telink объявы регистров и прочего...
 

pvvx

Активный участник сообщества
Telink по барабану... кто ищет тот найдёт
Пачка SDK от Telink в их wiki ... и на других страницах...
Для всех SDK у них есть описание на уровне для детсада, включая кухонный язык.
Никакие сторонние писаки, со своими платными книжками, как это произошло с ESP не нужны.
 

pvvx

Активный участник сообщества
Android починился - если в Chrome запускать .html, то Android не тянет за собой остальные файлы, пришлось всё (*.css, *.js) вставить в один файл html.
 

pvvx

Активный участник сообщества
Да, и у многих актуальных смартов этого и того года не хватает быстродействия с BLE. Пришлось изменить коррекцию размера пакета в javascript для Android-ой версии...
 

pvvx

Активный участник сообщества
Полной оптимизации LowPower на BLE версии пока не производилось. Текущие при TX +8 дБ (вместе с INA2xx):
  • В режиме ожидания соединения: до 0.200 мА (3.3В)
  • В режиме соединения и передачи данных по BLE: от 9 до 11 мА (3.3В) (зависит от скорости опроса INA2xx)
USB версия (вместе с INA2xx):
  • В режиме ожидания USB подключения (USB шина отключена): 14.3 мА (3.3В)
  • В режиме ожидания открытия COM порта (USB шина подключена и активна): 14.4 мА (3.3В)
  • В режиме соединения и передачи данных в USB: от 14 до 15.6 мА (3.3В) (зависит от скорости опроса INA2xx)
 

pvvx

Активный участник сообщества
Полной оптимизации LowPower на BLE версии пока не производилось. Текущие при TX +8 дБ (вместе с INA2xx):
  • В режиме ожидания соединения: до 0.200 мА (3.3В)
  • В режиме соединения и передачи данных по BLE: от 9 до 11 мА (3.3В) (зависит от скорости опроса INA2xx)
USB версия (вместе с INA2xx)*:
  • В режиме ожидания USB подключения (USB шина отключена): 14.3 мА (3.3В)
  • В режиме ожидания открытия COM порта (USB шина подключена и активна): 14.4 мА (3.3В)
  • В режиме соединения и передачи данных в USB: от 14 до 15.6 мА (3.3В) (зависит от скорости опроса INA2xx)
* Ток при работе с USB имеет зависимость от нагрузки - кабеля и ответного USB.

ЗЫЖ Эти опции сайта в ограничение времени дополнения последнего сообщения задолбали - не попить чаю и дописывая сообщение...
Начинаю писать по о
 
Сверху Снизу