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

BLE SoC PHY6202

pvvx

Активный участник сообщества
Есть ещё https://aliexpress.ru/item/1005005184112062.html

В документации про Coded PHY мало что:
1712515947876.png
Очень похоже на программу сканера от TI ....


В итоге самое дешевое решение - это nRF сканер с Wireshark
И Wireshark - это жирный плюс.
 

cool2000

Member
Сканер заработал и с Coded PHY.
С Wireshark тоже есть интерфейс и можно сохранить данные в формате pcap.
Осталось разобраться, как отследить соединение в режиме расширенной рекламы.

Очень похоже на программу сканера от TI ....
Почему-то китайцы любят продукты TI.
Можно было бы попробовать и TI сканер. Он точно работает с launchpad на СС2652P. Но мне показалось проще взять другой проект. К тому же и автор быстро отвечает на вопросы. А от TI ничего не дождёшься.
 
Последнее редактирование:

cool2000

Member
В общем, после разборок при помощи RF сканера нашёл причину, почему не работает соединение в режиме Coded PHY: hardware не отдаёт вовремя прерывание по концу пакета, причём именно в режиме Coded PHY, т.е. прерыание задерживается где-то в недрах аппаратного блока примерно на 120мкс. Плюс есть ещё задержка порядка 70-80мкс самого передатчика.
По стандарту же, нужно ответить на запрос на соединение через 150±2мкс после приёма пакета. Т. е. даже если пакет готов заранее, то всё равно ответ безнадёжно запаздывает.
Скорее всего ошибка в обработчике пакетов в аппаратном блоке. Попробую написать китайцам, но шансов скорее всего нет.
Примерный расчёт времени:
17040(длина пакета рекламы) + 150 (T_IFS) + 2896(длина запроса на соединение) = 20087мкс.
А прерывание по концу пакета запроса на соединение выходит через ~20207мкс.
 

pvvx

Активный участник сообщества
Непонятно, что за интервалы показывает Wireshark.
1712689207258.png
17: 1712689242254.png,18:1712689337817.png, 19:1712689308681.png
 

pvvx

Активный участник сообщества
Я не разбирался в этих данных сниффера, но другое измеренное соединение имеет такие как и эти цифры - т.е. различий нет.
И мне кажется, что отличий быть не должно, т.к. это задается аппаратно в параметрах процедуры названной примерно rx2tx() или tx2rx().
 

pvvx

Активный участник сообщества
Т.е. прерывание возможно ненужно - все блоки автоматом в RF по заданным параметрам (?)
 

pvvx

Активный участник сообщества
По стандарту же, нужно ответить на запрос на соединение через 150±2мкс после приёма пакета.
Если 2 мкс, тогда ограничение на дальность выходит 299792458 * 0.000002 = 599.584916 метров
На 2 мкс задержка приема на устройстве и отсылка - поступление на приемник запросившего через 2 мкс. Итого 4 мкс на 600 метров?
 

pvvx

Активный участник сообщества
Как тогда происходит связь LE LR на 1.6 км с внешней антенной? Там задержка будет 10.7 мкс
 

cool2000

Member
Я не пробовал загонять в Wireshark, а вот таким образом выглядит
Код:
Timestamp: 12.500241    Length: 9       RSSI: -61       Channel: 37     PHY: Coded (S=8)
Ad Type: ADV_EXT_IND
ChSel: 0 TxAdd: 0 RxAdd: 0 Ad Length: 7
AuxPtr Chan: 3 PHY: Coded Delay: 6480 us
AdvMode: Connectable
AdvDataInfo: 01 00
00000000  07 07 46 18 01 00 03 d8  40                       |..F.....@       |
00000009

Timestamp: 12.506750    Length: 257     RSSI: -61       Channel: 3      PHY: Coded (S=8)
Ad Type: AUX_ADV_IND
ChSel: 0 TxAdd: 0 RxAdd: 0 Ad Length: 255
AdvMode: Connectable
AdvA: 66:55:44:33:22:11 (Public) AdvDataInfo: 01 00
00000000  07 ff 49 09 11 22 33 44  55 66 01 00 02 01 06 1a  |..I.."3DUf......|
00000010  ff 4c 00 02 15 fd a5 06  93 a4 e2 4f b1 af cf c6  |.L.........O....|
00000020  eb 07 64 78 25 27 74 6b  ed c5 00 00 00 00 00 00  |..dx%'tk........|
00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000100  00                                                |.               |
00000101

Timestamp: 12.523941    Length: 36      RSSI: -61       Channel: 3      PHY: Coded (S=8)
Ad Type: AUX_CONNECT_REQ
ChSel: 0 TxAdd: 1 RxAdd: 0 Ad Length: 34
InitA: 79:12:20:DA:A3:5C (RPA) AdvA: 66:55:44:33:22:11 (Public) AA: 0x66D796F2 CRCInit: 0xA54BD0
WinSize: 1 WinOffset: 12 Interval: 36 Latency: 0 Timeout: 500 Hop: 6 SCA: 5
Channel Map: FF FF FF FF 1F (all channels)
00000000  45 22 5c a3 da 20 12 79  11 22 33 44 55 66 f2 96  |E"\.. .y."3DUf..|
00000010  d7 66 d0 4b a5 01 0c 00  24 00 00 00 f4 01 ff ff  |.f.K....$.......|
00000020  ff ff 1f a6                                       |....            |
00000024

Timestamp: 12.527042    Length: 16      RSSI: -73       Channel: 3      PHY: Coded (S=8)
Ad Type: AUX_CONNECT_RSP
ChSel: 0 TxAdd: 0 RxAdd: 1 Ad Length: 14
AdvMode: Non-connectable, non-scannable
AdvA: 66:55:44:33:22:11 (Public) TargetA: 79:12:20:DA:A3:5C (RPA)
00000000  88 0e 0d 03 11 22 33 44  55 66 5c a3 da 20 12 79  |....."3DUf\.. .y|
00000010
принимаемая сканером.

Время ответа AUX_CONNECT_RSP должно быть порядка 12.526987 = 12.523941 + 0.002896(длительность AUX_CONNECT_REQ) + 0.000150(T_IFS). phy хотя и отвечает сразу (я убрал все задержки), но всё равно слишком поздно 12.527042 из-за того, что прерывание по приёму Coded PHY AUX_CONNECT_REQ застревает где-то в недрах аппаратного блока на ~120мкс. Используется режим TRX (tx2rx) Tx(AUX_ADV_IND)->Rx(AUX_CONNECT_REQ). Причём в режиме STX прерывание срабатывает чётко по концу передываемого пакета.

Как тогда происходит связь LE LR на 1.6 км с внешней антенной? Там задержка будет 10.7 мкс
В этом случае предлагается слушать возможный ответ дольше:

Range delay.png
 

cool2000

Member
Судить по Timestamp передачи в комп от чипа сниффера не лучшая затея
С этим всё нормально, Timestamp измеряется CC2652P от счётчика с тактированием 4МГц и передаётся наверх.
Значит параметры TRX заданы неверно.
Не, параметры на 99.99% заданы корректно. Проблема точно в аппаратном модуле и именно при приёме Coded PHY. Переделал TRX->STX на STX->SRX->STX. Тайминги вообще не изменились. Первый STX выдаёт прерывание без задержки, а SRX застревает на те же ~120мкс.
 

pvvx

Активный участник сообщества
А какие там есть параметры для RX? Окно приема, размер блока, .. ?
И декодирование и расчет CRC там программный или апп. ?
Некоторые чипы принимают на 1M PHY и программно декодируют... Тогда и на 1M будут задержки...
 

cool2000

Member
А какие там есть параметры для RX? Окно приема, размер блока, .. ?
Задаётся окно приёма ll_hw_set_rx_timeout() Китайцы зачем-то влепили 3000. Уменьшил до 300. Влияет только на задержку Rx Timeout, когда пакет не принимается, размер блока set_max_length() стоит макс размер PDU 50 байт. Ещё задаются всякие интервалы, tx->rx rf_phy_change_cfg(). Ни на что особо не влияют.
И декодирование и расчет CRC там программный или апп. ?
Декодирование и проверка CRC, скорее всего аппаратные, возможно внутри hardware стоит MCU на котором исполняется программный декодер, у TI вроде так сделано, тогда это объясняет такую большую задержку.
Кстати на удивление мне ответил китаец, некто Duanyang Chen. Пока что ушёл в несознанку, предожил посмотреть проект extBleCentral. Зачем смотреть Central, если нужен Pheripheral? Буду дальше долбить, посмотрим, может выведет на разрабочиков.
 

pvvx

Активный участник сообщества
размер блока set_max_length() стоит макс размер PDU 50 байт. Ещё задаются всякие интервалы, tx->rx rf_phy_change_cfg(). Ни на что особо не влияют.
Пакет вроде 43 байта? + Преамбула ?? мкс.
1712765692117.png
Если лишние 7 байт - это 7*4*8 = 224 мкс.
RF принимает всё подряд с преамбулы до конца буфера. Во всяком случае это если пользовать demo процедуры в Telink, которым указывается только канал, код преамбулы, модуляция.
Там всегда в конце какой-то разный шум.
 

pvvx

Активный участник сообщества
C:
        if(rf_is_rx_finish())
        {
#if (RF_MODE==RF_ANT)
            if(rf_is_rx_finish() && if(rf_is_rx_right()))
#elif ((RF_MODE==RF_BLE_2M)||(RF_MODE==RF_BLE_1M)||(RF_MODE==RF_BLE_1M_NO_PN)||(RF_MODE==RF_LR_S8_125K)||(RF_MODE==RF_LR_S2_500K))
            if(RF_BLE_PACKET_CRC_OK(rx_packet)&&RF_BLE_PACKET_LENGTH_OK(rx_packet))
#elif (RF_MODE==RF_ZIGBEE_250K)
            if(RF_ZIGBEE_PACKET_CRC_OK(rx_packet)&&RF_ZIGBEE_PACKET_LENGTH_OK(rx_packet))
#elif ((RF_MODE==RF_PRIVATE_2M)||(RF_MODE==RF_PRIVATE_1M)||(RF_MODE==RF_PRIVATE_500K)||(RF_MODE==RF_PRIVATE_250K))
#if(PRI_MODE == ESB_MODE)
            if(RF_NRF_ESB_PACKET_CRC_OK(rx_packet)&&RF_NRF_ESB_PACKET_LENGTH_OK(rx_packet))
#elif(PRI_MODE == SB_MODE)
            if(RF_NRF_SB_PACKET_CRC_OK(rx_packet))
#endif
#endif
В нем все define типа RF_BLE_PACKET_LENGTH_OK - это смещение в буфере где лежит размер и как считать/сравнить/где лежит CRC.
 

cool2000

Member
Пакет вроде 43 байта? + Преамбула ?? мкс.
Запрос на соединение длиной 36 байт. Пробовал ставить 36, не влияет. Если бы он ждал все 50 байт, то задержка бы была ~ 896мкс = 14*64
Полная длительность AUX_CONNECT_REQ для LE Coded_S8 получается 2896 мкс = 80 + 256 + 16 + 24 + 36*64 + 24*8 + 3*8. Фактически прерывание вызывается на 120мкс позже.

1712766823080.png

RF принимает всё подряд с преамбулы до конца буфера
А как тогда CRC аппаратно проверяется, или у Telink её надо в программе вычислять?

Другой китаец из phyplus зачем-то прислал мне DTM firmware, новейшее аж от сентября 2022. Просто hex без исходников. Издеваются они что ли?
 

pvvx

Активный участник сообщества
#define RF_BLE_PACKET_LENGTH_OK(p) ( *((unsigned int*)p) == p[5]+13) //dma_len must 4 byte aligned
#define RF_BLE_PACKET_CRC_OK(p) ((p[*((unsigned int*)p) + 3] & 0x01) == 0x0)

C:
#define    RF_ZIGBEE_PACKET_LENGTH_OK(p)                (p[0]  == p[4]+9)
#define    RF_ZIGBEE_PACKET_CRC_OK(p)                   ((p[p[0]+3] & 0x51) == 0x10)
#define    RF_ZIGBEE_PACKET_RSSI_GET(p)                 (p[p[0]+2])
#define    RF_ZIGBEE_PACKET_TIMESTAMP_GET(p)               (p[p[0]-4] | (p[p[0]-3]<<8) | (p[p[0]-2]<<16) | (p[p[0]-1]<<24))
#define    RF_ZIGBEE_PACKET_PAYLOAD_LENGTH_GET(p)          (p[4])
#define    RF_NRF_ESB_PACKET_LENGTH_OK(p)                  (p[0] == (p[4] & 0x3f) + 11)
#define    RF_NRF_ESB_PACKET_CRC_OK(p)                     ((p[p[0]+3] & 0x01) == 0x00)
#define    RF_NRF_ESB_PACKET_RSSI_GET(p)                   (p[p[0]+2])
#define    RF_NRF_SB_PACKET_PAYLOAD_LENGTH_GET(p)          (p[0] - 10)
#define    RF_NRF_SB_PACKET_CRC_OK(p)                      ((p[p[0]+3] & 0x01) == 0x00)
#define    RF_NRF_SB_PACKET_CRC_GET(p)                     ((p[p[0]-8]<<8) + p[p[0]-7]) //Note: here assume that the MSByte of CRC is received first
#define    RF_NRF_SB_PACKET_RSSI_GET(p)                    (p[p[0]+2])
#define    RF_NRF_ESB_PACKET_TIMESTAMP_GET(p)          (p[p[0]-4] | (p[p[0]-3]<<8) | (p[p[0]-2]<<16) | (p[p[0]-1]<<24))
#define    RF_NRF_SB_PACKET_TIMESTAMP_GET(p)           (p[p[0]-4] | (p[p[0]-3]<<8) | (p[p[0]-2]<<16) | (p[p[0]-1]<<24))
 

pvvx

Активный участник сообщества
p[0] - это dma_len (uint32). Данный буфер получает проц от RF по DMA. А что там в RF - фиг знает.
 
Сверху Снизу