• Система автоматизации с открытым исходным кодом на базе 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 - фиг знает.
 
Сверху Снизу