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

CH582M (СH581, CH582, СH583)

pvvx

Активный участник сообщества
Если для примера взять INA228 (2.94-MHz high-speed I2C interface), то минимальный шаг оцифровки и опроса у INA228 равен 50 мкс. Т.е. за 50 мкс по минимуму необходимо по I2C два раза выставить номер адреса, номер регистра и прочитать 3 байта данных. На это требуется около 60 тактов CLK I2C (менее 830 нс на один такт CLK) и не менее 20 записей и опросов регистров типа while(бит-регистра = ok) контроллера I2С.
Т.е. CPU будет занят только этой задачей и ничем более (если ещё сможет выставить частоту шины I2C менее 820 нс).
В итоге большинство любимых в народе MCU/SoC в пролете…

Такие вот дела с I2C и SMBus… :p
По этому ещё в начале этого века были проектированы стандартные ip модели контроллеров I2C... Но всякие STM и т.д. жадятся за каждый транзистор в чипе...
 

dzanis

Member
Куда девать входящий поток в CH582/592 ?
Проверить что последние байты идентичны тем , что были отправлены? Я думал просто тест скорости провести. Можно отправлять один и тот-же пакет,с итерацией последних байт для того чтоб понимать номер пакета.
Но тут у меня другая проблема. Настроил и собрал iSLER.c на MRS2 , залил в CH592 и чип постоянно в ребуте. Этот ch32fun настолько оброс дефайнами,что там чёрт ногу сломит. Я понимаю их , что они хотят чтобы их код работал на любом устройстве от wch.Но даже оракул счёл что проще сделать виртуальную машину с которой байт код будет работать на любом устройстве, это проще чем пихать миллион дефайноф в одном файле.
Я к отладке не подключал CH592,пока не знаю где копать. Заливал через usb программой WCHISPTool_CH57x-59x.exe .Отладка просто printf через uart1. В общем летит мусор в uart и всё.
 

pvvx

Активный участник сообщества
Понятно. А по SPI к INA не подключится?
INA229 - это SPI. Но имеем почти те-же проблемы.
И INAxxx тут не при чем. Давно есть куча датчиков температуры и влажности с CLK I2С более 1 МГц. А для BLE важно время активности SoC, т.к. это рано потреблению.
 

pvvx

Активный участник сообщества
Проверить что последние байты идентичны тем , что были отправлены? Я думал просто тест скорости провести. Можно отправлять один и тот-же пакет,с итерацией последних байт для того чтоб понимать номер пакета.
Это не будет тестом для реальных приложений.
Поток данных нужно форматировать и буферизировать. Это работа CPU с неким шагом, который можно вызывать через событие в TMOS.
Но данные нужно отправлять в какой-то интерфейс - типично это делается по прерываниям.
И тут сразу неизвестность в приоритетах прерываний и вообще схеме прерываний используемых в TMOS.
Т.е. для теста нужно отнимать время работы у CPU, к примеру через прерывание таймера, и смотреть что на это скажет TMOS и стек BLE.

Но тут у меня другая проблема. Настроил и собрал iSLER.c на MRS2 , залил в CH592 и чип постоянно в ребуте. Этот ch32fun настолько оброс дефайнами,что там чёрт ногу сломит. Я понимаю их , что они хотят чтобы их код работал на любом устройстве от wch.Но даже оракул счёл что проще сделать виртуальную машину с которой байт код будет работать на любом устройстве, это проще чем пихать миллион дефайноф в одном файле.
Я и не лезу в это скопление. Так как для каждой задачи требуется своя оптимизация и алгоритмы. Универсального решения для таких тупых чипов не бывает. А там хотят сделать очередное Arduino... и послал разбираться с этой кашей https://github.com/biemster в одиночку :)
И у них задача простая - сделать урезанный Apple FindMy - это передача маяков раз несколько секунд.
 

pvvx

Активный участник сообщества
На сегодня итог с CH582F такой:
Не тянет опрос I2C и передачу более 9 килобайт, а менее – запросто и благополучно.

Для теста был изменен вызов GATT_Notification() на GATT_Indication().
Разница в том, что GATT_Indication() требует обязательного подтверждения передачи приемником.
И при превышении 9 килобайт сообщает об ошибке передачи...
Какую из функций использовать – без разницы – итог одинаков.

Тестовая прога с INA226 на 8000 байт в секунду (опрос INA226 в 250 мкс):
1758778804267.png
Всё без проблем на таком трафике.
Код:
CH58x_BLE_LIB_V2.13
I2C: Set default CFG
Initialized..
Advertising..
Scan req from f4 4e fc bf aa 91 (запрос активного сканирования внешним адаптером - запрашивает имя устрйоства)
Scan req from f4 4e fc bf aa 91 (дубль запроса)
Conn1: 48, 0, 960  (запрос соединение с адаптера, с его хотелками интервалов)
Connected.. (соединение)
MTU exchange: 507 (изменяем размер MTU)
CurMTU = 507:507 (проверка что говорит стек WCH о своем MTU и MTU адаптера)
ExchangeMTU(494): 2 (затесавшийся тест: команда изменения MTU возвращает ошибку  номер 2, т.к. она только для мастера)
PHY Update 0… (посылка запроса изменения PHY для соединения номер 0)
Update conn1 : 7, 0, 50 (переназначение интервалов соединения)
PHY update Rx:2 Tx:2 ..  (согласовал PHY 2MHz на TX и RX)
(далее команды идентификации устройства и конфигурации I2C и INA226)
cmd[2]: 00,00  
cmd[40]: 26,01,00,00,50,c3,e8,03,80,00,ff,07,00,00,00,00,00,00,00,00,00,00,00,00,80,01,80,02,80,01,80,02,80,00,00,00,00,00,00,00
cmd[3]: 01,40,01
cmd[4]: 02,10,80,fe
cmd[13]: 0b,01,74,00,fa,00,dc,05,80,00,4f,00,00 (старт потока с заданными параметрами)
(далее молча гонит поток, т.к. производительности и так не хватает)

Диаграммы приема на СВЧ диод рядом с модулем для контроля кто и когда передает (клетка 5 мс):

Если внешний адаптер умеет играть в BT5.0+:
1758778901528.png

Если внешний адаптер прикидывается в поддержку BT5.0+ (передача идет мелкими блочками по 9 шт, стеку указано до 12):
1758778911009.png

Импульсы малой амплитуды - передачи внешнего адаптера, большой амплитуды - это CH582F.

Аналогичное поведение наблюдается на 7 проверенных USB-BT и PCI-BT адаптерах. Кто кусками, кто целыми блоками по MTU…

По всевозможным issue в Windows Web Bluetooth API нет команды запроса установки MTU. Отнекиваются тем, что якобы windows при соединении сама устанавливает максимальный MTU. Но по реальному поведению видно, что это не совсем так - гарантированно имеющий размер внутреннего буфера приемника-передатчика адаптер с BT5.0+ вдруг начинает работать с блоками 2x байта...
 

pvvx

Активный участник сообщества
В этой-же прошивке работает и USB и там всё нормально до пределов INA226 (опрос в 140 мкс):
1758779275844.png
На вход дана пила с генератора...
То есть получить гальваническую развязку PowerProfiler-у через BLE с CH582 не выйдет...
 

pvvx

Активный участник сообщества
При работе стека у USB не хватает производительности для обслуживания потока с I2С более 20 килобайт в секунду.
При увеличении частоты CPU с 60 на 80 МГц, получаем пропорциональную прибавку ограничения в USB и BLE.

Т.е. тормоз создает сам стек – ему не хватает времени, остающегося от работы прерывания обслуживающего I2C. При этом USB без запущенного стека запросто перелопачивает к сотне килобайт в секунду от I2C или за 600 килобайт в секунду при тусовке через двойные буфера, с формированием заголовков блоков передачи от встроенного ADC...

На этом можно заканчивать с CH58x/592. Будет второй тормозной чип – первый с совершенно идентичным BLE стеком = РНY62xx/ST17H6x. На нем аналогично не удалось обрабатывать прием OTA данных на полную скорость, хотя-бы в половину от TLSR825x…
 

pvvx

Активный участник сообщества
Если обратиться к документации:

6.6 Ограничение обработки приложения во время работы Bluetooth Low Energy

Из-за временной зависимости протокола Bluetooth Low Energy контроллер должен обрабатывать каждое событие соединения или событие трансляции до его поступления. Несвоевременная обработка приведет к повторной передаче или отключению.

TOMS не является многопоточным, поэтому при наличии транзакций Bluetooth Low Energy другие задачи должны быть остановлены для обработки контроллером. Поэтому следите за тем, чтобы не занимать слишком много событий в приложении. Если требуется сложная обработка, обратитесь к разделу 3.3, чтобы разбить её на части.

3.3 События задач и их выполнение

Планирование TMOS осуществляется посредством опроса. Системные часы обычно берутся из RTC, а единица измерения — 625 мкс. Пользователи добавляют настраиваемые события в список задач TMOS, регистрируя задачи, а затем TMOS планирует и запускает их…..


Всё это соблюдено. Кроме прерывания, которое должно отрабатывать постоянно для чтения шины по I2C с мелким интервалом.
Т.е. данное описание работы стека в CH58x/59x гласит, что стек у WCH, скопированный из какой-то общей кормушки (наверно древний nRF) вышел сверх тормознутым и занимать время CPU во время его работы незя.

Для этого WCH прилагает вариант примеров 8K_PollingRateWirelessMouse с libCH59xRF_FAST.a и другими библиотеками стека… Это те примеры с исходниками, которые ищет @selevo:
1758789172870.png
 

dzanis

Member
На этом можно заканчивать с CH58x/592.
pvvx, спасибо за труды и эксперименты! Пока WCH гордо пишет в даташите про 2 Мбит/с, мы имеем честные 9 КБ/с. В мегабитах это выглядит ещё печальнее, стыдно перед dial-up из 90-х . Но благодаря тебе хотя бы знаем реальность, а не маркетинг.
Правда, остаётся вопрос: куда вообще пристроить столь тормознутый BLE? Музыку не послушаешь, самый пережатый кодек не потянет, разве что midi. Файлы логов, максимум передавать сохранения небольшие, на большее терпения не хватит. В общем, ble на ch5xx явно не для скорости, а для медитативного общения байтов в стиле дзен.
 

dzanis

Member
Интересно, а почему товарищ здесь пишет , что добился до 1.1 МБит/с на CH582F . Сам я ещё не дошёл до отправки больших массивов данных. Всего что я понял за два дня, это как создать на openwch ble api собственный сервис. Самый простой пример для этого взял из battservice.c . Изучив этот сервис меня озадачил подход к отправке через Notify.
Но сначала про чтение атрибутов из структуры. Например battLevel так записывается
C:
// Battery Level Value
    {
        {ATT_BT_UUID_SIZE, battLevelUUID},      /* type */
        GATT_PERMIT_READ,                       /* permissions */
        0,                                      /* handle */
        (uint8_t *)&battLevel                   /* pValue */
    },
Тут просто стек сам лезет по этому указателю pValue и читает или записывает байты.
С чтением совсем просто, так как у меня все данные в характеристиках 16-ти битные, то разницы нету какой uuid, все они по два байта и просто написал такой калбак.
C:
static bStatus_t bicycle_ReadAttrCB(uint16_t connHandle, gattAttribute_t *pAttr,
                                    uint8_t *pValue, uint16_t *pLen, uint16_t offset,
                                    uint16_t maxLen, uint8_t method)
{
    *pLen = 2;
    tmos_memcpy(pValue, pAttr->pValue, 2);
    return SUCCESS;
}
Но с notify всё иначе и запутанней.
Оказалось, что стеку ble вообще не важны сами данные из переменной, на которую указывает атрибут на pValue .
Через Notify просто шлёт то, что ты ему передашь вручную хоть число, хоть массив байт.
А та ссылка на данные pValue , которая указывается в структуре атрибутов gattAttribute_t , нужна только когда клиент хочет сделать обычное read write характеристики.
Но notify работает через handle атрибута, а uuid только для того, чтобы при инициализации стек понял, что это за характеристика и где она находится в таблице.
В общем при самой передаче через notify стек пользуется не uuid и не pValue , а handle блин.
Это типа handle как адрес ячейки в таблице атрибутов, по которому клиент потом понимает,
что именно обновилось. И индекс атрибута handle в массиве надо посчитать вручную. Тут он BATT_LEVEL_VALUE_IDX
C:
// кусок из кода notify 
noti.handle = battAttrTbl[BATT_LEVEL_VALUE_IDX].handle;
noti.len = BATT_LEVEL_VALUE_LEN;
noti.pValue[0] = battLevel;
Получается, если мы что-то добавляем к нашему сервису новую характеристику или дескриптор не забываем обновлять этот индекс, иначе будет слать не то, что надо.
Но зачем так делать, я не понимаю. Нанятому программисту, видимо, мало на счёт насыпали.
Или, может, они такие сидят в офисе и думают "Надо добавить боли. Пусть у людей будет свой Dark Souls среди протоколов!”
В итоге, пока я пытаюсь понять, почему при notify улетает не температура, а какая-то батарейка, уже появляются мысли дропнуть все нафиг.
А потом вернувшись в gattAttribute_t, и осознал что структура это портал в иное измерение, где handle важнее uuid.
Пока что продолжаю делать задуманное, пока не выгорел как pecherskih.


.
 

pvvx

Активный участник сообщества
Интересно, а почему товарищ здесь пишет , что добился до 1.1 МБит/с на CH582F . Сам я ещё не дошёл до отправки больших массивов данных.
Это по тому, что в моем описании идет разговор о том, что кроме BLE стека работает и другая задача и у тормозного стека не хватает времени на большие потоки.
Во вторых, в описании значится, что используется Notify() - отправка без подтверждения. И в моем описании указано - эта функция не возвращает ошибки, даже если не успела передать данные.
А если и успела, то после определенной скорости потока передача содержит перепутанные куски передаваемого потока.

В пустом стеке, если нет никаких других задач и исполняется тупая передача в цикле пустых блоков (просто указателей в памяти на обум, даже не заполненных рандомом или ещё чем-то), тогда счетчик передачи байт в секунду на CH592F показывает:
Код:
Phy update Rx:2 Tx:2 ..
MTU exchange: 492
Tx: 29829B/s
Tx: 48411B/s
Tx: 48411B/s
Tx: 51345B/s
Tx: 52812B/s
Tx: 47433B/s
Tx: 50367B/s
Tx: 50367B/s
Tx: 49878B/s
Tx: 53301B/s
Tx: 53301B/s
Tx: 53301B/s
Tx: 51834B/s
Tx: 50856B/s
Tx: 55257B/s
Tx: 57213B/s
Tx: 53301B/s
Tx: 50856B/s
Tx: 52323B/s
Tx: 49878B/s
Tx: 48900B/s
Tx: 52812B/s
Tx: 49878B/s
Tx: 49389B/s
Tx: 53301B/s
Tx: 49389B/s
Tx: 50367B/s
Tx: 49878B/s
Tx: 49389B/s
Tx: 52812B/s
Tx: 51834B/s
Tx: 75306B/s
Tx: 72861B/s
Tx: 67971B/s
Tx: 69927B/s
Tx: 89487B/s
Tx: 90954B/s
Tx: 89487B/s
Tx: 92910B/s
Tx: 90465B/s
Tx: 93888B/s
Tx: 92421B/s
Tx: 93399B/s
Tx: 90954B/s
Tx: 93888B/s
Tx: 93399B/s
Tx: 86553B/s
Tx: 61125B/s
Tx: 59658B/s
Tx: 60636B/s
Tx: 60636B/s
Tx: 58191B/s
Disconnected.. Reason:13
Advertising..
Но реально принятые байты совсем другие и их кол-во во много раз меньше.
А это счет сколько байт сожрала функция Notify().
 

pvvx

Активный участник сообщества
В моем тесте время CPU распределено примерно так:
1759661111192.png
Это при потоке с I2C в ~14 килобайт в секунду. Так шинкуется время CPU прерыванием для обработки чтения 2 байтового регистра по I2C и ещё выполняется функция формирующая заголовки блоков по 250 байт.
Этот поток и передается стеку. И на работу стека остается менее 50% времени.
 

pvvx

Активный участник сообщества
Соответственно подключить акселерометр или какое другое устройство, требующее постоянных коротких прерываний, шинкующее на мелкие кусочки в микросекунды работу данного стека не выйдет. У него сразу тормозит TMOS с событиями, т.к. там сотня килобайтов кода для вызова события стека, хотя RF (BLE) работает по прерываниям и особой точности в микросекунду не требует – малый джиттер не критичен – расстояние связи и тормознутости разных адаптеров оказывает большую разницу в задержке, да и межкадровое пространство = 150 мкс за которые можно много чего сделать и типично выполняется самой RF частью. BLE требует только правильного расчета интервалов соединения, т.е. нормируется уход часов со временем для расчета больших интервалов в режиме сна для минимизации потребления (+-500 ppm)…

В итоге к данным чипам надо лепить 8 ногий CH32V003J4M6, который будет непрерывно обрабатывать I2C или что-то ещё, и гнать поток в UART или SPI на прием в CH58x/59x по DMA.

А в этом стеке, когда он удосужится вызвать событие пользователя – обрабатывать полученный DMA буфер и ……... а тут опять засада с параметрами WCH стека. Он не умеет передавать между интервалами более объявленного MTU в 507 байт, что дает теор.максимум 507(байт в пакете)/0.0075(интервал соединения в секундах) = 67600 байтов в сек, вместо реально возможных более 140 кбайт в сек. И если и передаст, то у него не хватает сил передать всякие ACK и прочие параметры поддержки соединения, для чего ему требуется ещё интервал соединения...

@dzanis - Изучайте как работает BLE и многое станет понятно, а не пишите возгласы, типа: "Пока WCH гордо пишет в даташите про 2 Мбит/с, мы имеем честные 9 КБ/с.".
Так как прием ведется в Windows и на простые адаптеры, с работой которых это тоже частично сказывается. Плюс все тесты производились на CH582F, а стек у CH592F имеет номер меньше, плюс ограничения в самом задании параметров у стека WCH и сверх тормозной TMOS. В итоге на сегодня удается работать только с потоком до 14 килобайт в секунду при приеме из I2C в Web Bluetooth API:
1759663206696.png
 

dzanis

Member
О, вижу накидал скринов. Очень красивый веб интерфейс.
Я пока только разбираюсь с ble, но уже втянулся, с каждой строчкой кода всё интереснее.
Да, с возгласами я, пожалуй, погорячился. Просто когда надежда на скорость в этом чипе, а на деле нифига, эмоции сами выходят через uart без фильтра
Но спасибо за разъяснения особенно про tmos и mtu, стало гораздо понятнее, где стек сам себе ногу откусывает.
tmos там похоже,не реалтайм а реалтормоз, зато всё по стандарту ble.
Спасибо за подробности, теперь ясно, почему без второго микроконтроллера не обойтись.
Про идею с v003 как отдельным контроллером, дельная мысль, возьму на заметку.Только у меня нету маложруших датчиков холла,и который ещё от 1.7 вольта работает. А имеется только A3141 , который ест больше самого ch592, и рабочий режим от 4.5v.
 

pvvx

Активный участник сообщества
WCH написал специальный якобы быстрый стек для WCH (SDK, Sample code) и при этом он проприетарный, точнее не стандарта BLE.
И там всего 8000 транзакций в секунду по 20 байт. Этим они хвалятся... :ROFLMAO:
 

il-2

New member
Привет, ребята!!! Я давно уже здесь присутствую в режиме Read only, и чипами CH57x/CH58x/CH59x занимаюсь тоже давно и плотно, причем пишу проект сразу для всей линейки этих чипов. Если честно, времени нет совсем, чтобы делиться подробно и обстоятельно своими наблюдениями. А поделиться есть чем. Поэтому, пусть коротко и скомкано - напишу.
Для успешной работы с этими МК следует сразу придерживаться правил:
1. Использовать для прерываний HPE и свои наиболее часто вызываемые прерывания настраивать через быстрые каналы (Fast Interrupt channels). Причем можно использовать только первые 2 канала из 4, последние 2 канала библиотека BLE настраивает для своего использования.
2. Обработчики прерывания размещать в ОЗУ, делать их как можно короче, все что можно - выносить в обработку по событиям TMOS (т.е. использовать в прерываниях tmos_set_event()
3. Соответственно - саму функцию tmos_set_event() с помощью скрипта линкера тоже разместить в ОЗУ
4. Использовать для событий из прерываний отдельную задачу. Причем - если используются прерывания с разными уровнями вложенности (поддерживается 2 уровня), то для каждого уровня - своя задача для событий). Это из-за того, что функция tmos_set_event() выполняет установку события в режиме чтение/модификация/запись без запрета прерываний, ну и я не буду подробно объяснять какие здесь при этом происходят эффективные эффекты :)
5. При выходе из прерывания обязательно ставьте команду разрешения доступа к защищенным регистрам. Ибо в самой библиотеке BLE доступ к защищенным регистрам используется, однако никаких попыток защитить эти участки кода от прерываний не делаются. А как известно - после открытия доступа он закрывается по таймауту 112 тактов. Излишне говорить - что при возникновении прерывания между разрешением доступа и самим доступом произойдет сбой, защищяемый регистр не запишется. Поэтому - принудительно разрешаем доступ при выходе из прерывания.
Это пока что вспомнил. По ходу еще буду вспоминать и писать
 

il-2

New member
И сразу напишу насчет скорости. У меня проект классического "моста" BLE-UART для переходя с UART на BLE. Протокол "запрос-ответ", удалось добиться пиковой скорости 310кбод (это для CH58x/CH59x). Ограничения естественно на участке BLE, и 310кбод - это для идеального случая, когда ответный пакет данных по размеру полностью занимает connection interval
Ну и параметры соединения - (ConnInterval = 7.5мс(минимальный), ATT_MTU = 512байт)
Еще такие моменты:
- я для тестирования своих железок пишу код в VisualStudio и использую библиотеку SimpleBLE. При этом у меня цикл запрос-ответ занимает 3 connection interval. Мой коллега-программист пишет основную программу на NET (точе через какую-то библиотеку) - и у него цикл запрос-ответ занимает 2 connection interval, и скорость 310кбод именно для этого случая.
 

il-2

New member
Ну и (я пока не пробовал) можно предположить что при односторонней передаче с помощью нотификаций можно достичь скорости 600кбод
 
Сверху Снизу