Перейти к содержанию
    

CC1101: странности работы

Приветствую!

Начал осваивать  СС1101 и столкнулся с некоторыми "особенностями".

 

По порядку:

надо научиться принимать сигнал скоростью 9600бит/с, модуляция FSK, на которого наложен манчестер (длительность сигнала порядка 10мс).

Сигнал был записан на SDR и изучен, после чего сделал сперва имитатор сигнала на СС1101 (передатчик)

Для работы с СС1101 использую библиотеку https://github.com/LSatan/SmartRC-CC1101-Driver-Lib

 

1) Передатчик на СС1101:

код

  ELECHOUSE_cc1101.Init();              // must be set to initialize the cc1101!
  ELECHOUSE_cc1101.setCCMode(1);       // set config for internal transmission mode.
  
  ELECHOUSE_cc1101.setModulation(0);  // set modulation mode. 0 = 2-FSK, 1 = GFSK, 2 = ASK/OOK, 3 = 4-FSK, 4 = MSK.
  ELECHOUSE_cc1101.setMHZ(433.92);   // Here you can set your basic frequency. The lib calculates the frequency automatically (default = 433.92).
  
  ELECHOUSE_cc1101.setDeviation(38.0);   // Set the Frequency deviation in kHz. Value from 1.58 to 380.85. Default is 47.60 kHz.
  ELECHOUSE_cc1101.setManchester(1);      // Enables Manchester encoding/decoding. 0 = Disable. 1 = Enable.
  ELECHOUSE_cc1101.setDRate(19.2);       // Set the Data Rate in kBaud. Value from 0.02 to 1621.83. Default is 99.97 kBaud!
   
  ELECHOUSE_cc1101.setSyncMode(0);        // Combined sync-word qualifier mode. 0 = No preamble/sync. 1 = 16 sync word bits detected. 2 = 16/16 sync word bits detected. 3 = 30/32 sync word bits detected. 4 = No preamble/sync, carrier-sense above threshold. 5 = 15/16 + carrier-sense above threshold. 6 = 16/16 + carrier-sense above threshold. 7 = 30/32 + carrier-sense above threshold.

  ELECHOUSE_cc1101.setWhiteData(0);       // Turn data whitening on / off. 0 = Whitening off. 1 = Whitening on.
  ELECHOUSE_cc1101.setPktFormat(0);       // Format of RX and TX data. 0 = Normal mode, use FIFOs for RX and TX. 1 = Synchronous serial mode, Data in on GDO0 and data out on either of the GDOx pins. 2 = Random TX mode; sends random data using PN9 generator. Used for test. Works as normal mode, setting 0 (00), in RX. 3 = Asynchronous serial mode, Data in on GDO0 and data out on either of the GDOx pins.
  ELECHOUSE_cc1101.setLengthConfig(1);    // 0 = Fixed packet length mode. 1 = Variable packet length mode. 2 = Infinite packet length mode. 3 = Reserved
  ELECHOUSE_cc1101.setPacketLength(0);    // Indicates the packet length when fixed packet length mode is enabled. If variable packet length mode is used, this value indicates the maximum packet length allowed.

  ELECHOUSE_cc1101.setCrc(0);     // 1 = CRC calculation in TX and CRC check in RX enabled. 0 = CRC disabled for TX and RX.
    
  ELECHOUSE_cc1101.setFEC(0);             // Enable Forward Error Correction (FEC) with interleaving for packet payload (Only supported for fixed packet length mode. 0 = Disable. 1 = Enable.
  ELECHOUSE_cc1101.setPRE(0);             // Sets the minimum number of preamble bytes to be transmitted. Values: 0 : 2, 1 : 3, 2 : 4, 3 : 6, 4 : 8, 5 : 12, 6 : 16, 7 : 24
  ELECHOUSE_cc1101.setPQT(0);             // Preamble quality estimator threshold. The preamble quality estimator increases an internal counter by one each time a bit is received that is different from the previous bit, and decreases the counter by 8 each time a bit is received that is the same as the last bit. A threshold of 4∙PQT for this counter is used to gate sync word detection. When PQT=0 a sync word is always accepted.
  ELECHOUSE_cc1101.setAppendStatus(0);    // When enabled, two status bytes will be appended to the payload of the packet. The status bytes contain RSSI and LQI values, as well as CRC OK.
    
  ELECHOUSE_cc1101.setPA(-10);      // set TxPower. The following settings are possible depending on the frequency band.  (-30  -20  -15  -10  -6    0    5    7    10   11   12) Default is max!

Отключены все автоматические вставки длин, адресов и проч.

преамбула 16 бит её кладу в пейлоад пакета (в начало): 0х00, 0х01

 

Тут всё хорошо за исключением одного нюанса: откуда-то всё равно пролезает байт 0х0С, которые передаются _перед_ моим пейлоадом

передаю пакет: byte transmit_byte[PACKET_LEN] = {0x00, 0x01, 0x0f, 0x3c, 0x35, 0xdb, 0x66, 0xbb, 0x42, 0x1b, 0x59, 0xA4};

оригинал:

794238175_Screenshotfrom2022-05-1717-43-53.thumb.png.cbdd806febd29bfc253a5809fa2fb52b.png

имитация на СС1101:

21356689_Screenshotfrom2022-05-1819-51-48.thumb.png.04bdf3eeb6a6fd9fcf22a037af0ec9df.png

 

какой настройкой это задаётся? это вообще отключается?

 

================================================================================

2) приём на СС1101

  ELECHOUSE_cc1101.Init();              // must be set to initialize the cc1101!
  ELECHOUSE_cc1101.setCCMode(1);       // set config for internal transmission mode.
  
  ELECHOUSE_cc1101.setModulation(0);  // set modulation mode. 0 = 2-FSK, 1 = GFSK, 2 = ASK/OOK, 3 = 4-FSK, 4 = MSK.
  ELECHOUSE_cc1101.setMHZ(433.92);   // Here you can set your basic frequency. The lib calculates the frequency automatically (default = 433.92).
  
  ELECHOUSE_cc1101.setDeviation(38.0);   // Set the Frequency deviation in kHz. Value from 1.58 to 380.85. Default is 47.60 kHz.
  ELECHOUSE_cc1101.setManchester(1);      // Enables Manchester encoding/decoding. 0 = Disable. 1 = Enable.
  ELECHOUSE_cc1101.setDRate(19.2);       // Set the Data Rate in kBaud. Value from 0.02 to 1621.83. Default is 99.97 kBaud!

  ELECHOUSE_cc1101.setRxBW(200.0);       // Set the Receive Bandwidth in kHz. Value from 58.03 to 812.50. Default is 812.50 kHz.
      
  ELECHOUSE_cc1101.setSyncMode(2);        // Combined sync-word qualifier mode. 0 = No preamble/sync. 1 = 16 sync word bits detected. 2 = 16/16 sync word bits detected. 3 = 30/32 sync word bits detected. 4 = No preamble/sync, carrier-sense above threshold. 5 = 15/16 + carrier-sense above threshold. 6 = 16/16 + carrier-sense above threshold. 7 = 30/32 + carrier-sense above threshold.
  ELECHOUSE_cc1101.setSyncWord(0, 1); // Set sync word. Must be the same for the transmitter and receiver. (Syncword high, Syncword low)

  ELECHOUSE_cc1101.setAdrChk(0);          // Controls address check configuration of received packages. 0 = No address check. 1 = Address check, no broadcast. 2 = Address check and 0 (0x00) broadcast. 3 = Address check and 0 (0x00) and 255 (0xFF) broadcast.
  ELECHOUSE_cc1101.setAddr(0);            // Address used for packet filtration. Optional broadcast addresses are 0 (0x00) and 255 (0xFF).
  ELECHOUSE_cc1101.setWhiteData(0);       // Turn data whitening on / off. 0 = Whitening off. 1 = Whitening on.
  ELECHOUSE_cc1101.setPktFormat(0);       // Format of RX and TX data. 0 = Normal mode, use FIFOs for RX and TX. 1 = Synchronous serial mode, Data in on GDO0 and data out on either of the GDOx pins. 2 = Random TX mode; sends random data using PN9 generator. Used for test. Works as normal mode, setting 0 (00), in RX. 3 = Asynchronous serial mode, Data in on GDO0 and data out on either of the GDOx pins.
  
  // page 39 of SWRS061I
  ELECHOUSE_cc1101.setLengthConfig(2);    // 0 = Fixed packet length mode. 1 = Variable packet length mode. 2 = Infinite packet length mode. 3 = Reserved
  ELECHOUSE_cc1101.setPacketLength(PACKET_LEN);    // Indicates the packet length when fixed packet length mode is enabled. If variable packet length mode is used, this value indicates the maximum packet length allowed.

  ELECHOUSE_cc1101.setCrc(0);     // 1 = CRC calculation in TX and CRC check in RX enabled. 0 = CRC disabled for TX and RX.

  ELECHOUSE_cc1101.setDcFilterOff(0);     // Disable digital DC blocking filter before demodulator. Only for data rates ≤ 250 kBaud The recommended IF frequency changes when the DC blocking is disabled. 1 = Disable (current optimized). 0 = Enable (better sensitivity).
    
  ELECHOUSE_cc1101.setFEC(0);             // Enable Forward Error Correction (FEC) with interleaving for packet payload (Only supported for fixed packet length mode. 0 = Disable. 1 = Enable.
  ELECHOUSE_cc1101.setPRE(0);             // Sets the minimum number of preamble bytes to be transmitted. Values: 0 : 2, 1 : 3, 2 : 4, 3 : 6, 4 : 8, 5 : 12, 6 : 16, 7 : 24
  ELECHOUSE_cc1101.setPQT(0);             // Preamble quality estimator threshold. The preamble quality estimator increases an internal counter by one each time a bit is received that is different from the previous bit, and decreases the counter by 8 each time a bit is received that is the same as the last bit. A threshold of 4∙PQT for this counter is used to gate sync word detection. When PQT=0 a sync word is always accepted.
  ELECHOUSE_cc1101.setAppendStatus(0);    // When enabled, two status bytes will be appended to the payload of the packet. The status bytes contain RSSI and LQI values, as well as CRC OK.

 

Тут задаю 16битное синхрослово setSyncWord(0, 1) по которому из эфира ловится пакет, и пакеты сгенерированные на СС1101 действительно ловятся (вероятно из-за доп.байта - он помогает отработать схемам АРУ + захват тактовой/несущей?), а оригинальный пакет не принимается.

Тут проблема: на СС1101 нельзя задать синхрослово менее 16 бит (наверное 12..13 бит хватило бы), а после прембулы 0х00 0х01 идёт динамический пейлоад и хвататься за него нельзя (точнее неизвестно за что "хвататься").

Как быть в этой ситуации? Гипотетически есть еще режимы:

  • 0 = No preamble/sync.
  • 4 = No preamble/sync, carrier-sense above threshold.

но опасение, что байты могут быть приняты с произвольной сдвижкой, а 0х0001 не самая надёжная последовательность чтобы на мк пытаться найти правильный офсет байтов.

Или есть еще какая-то возможность настройки, которую я не вижу?

 

================================================================================

3) "таймаут" приёма на СС1101

самая загадочная часть сс1101 с которой столкнулся, делаю прийм пакета опросом в цикле:

 

void loop() {

  //Checks whether something has been received.
  rxfifo_len = ELECHOUSE_cc1101.CheckRXFIFO();

  if (rxfifo_len >= RX_PACKET_LEN){

    delay(50);
    
    int size = ELECHOUSE_cc1101.ReceiveData(buffer, RX_PACKET_LEN);

    //Print received in bytes format
    for (int i = 0; i<size; i++){
      Serial.print(buffer[i], HEX);
      Serial.print(" ");
    }
    Serial.println();
    
  } else if (rxfifo_len) { // rxfifo_len > 0
    delay(DURATION_PACKET/2); // waiting to receive remaining frame
  } else {
    delay(DURATION_PACKET); // no data received. just wait: 10ms == duration of packet
  }

}

сами библиотечные процедуры модифицированы (библиотечные версии подразумевали первым байтом длины пакета):


byte ELECHOUSE_CC1101::CheckRXFIFO(void){
  if(trxstate!=2){
    SetRx();
  }
  return (SpiReadStatus(CC1101_RXBYTES) & BYTES_IN_RXFIFO);
}

byte ELECHOUSE_CC1101::ReceiveData(byte *rxBuffer, byte limit){
  SpiReadBurstReg(CC1101_RXFIFO,rxBuffer,limit);
  SpiStrobe(CC1101_SFRX);
  SpiStrobe(CC1101_SRX);
  return limit;
}

Так вот delay(50); был подобран экспериментально ( и содержится внутри CheckRXFIFO() в оригинальной авторской библиотеке - т.е. он также знал об этой "странности"), 50мс - минимальная задержка при которой проект стабильно принимает пакеты, если ставить менее, то принимается 1й пакет, после чего поллинг SpiReadStatus(CC1101_RXBYTES) всегда возвращает 0 ).

Т.е. по факту эта задержка между SpiReadStatus(CC1101_RXBYTES) и последующим SpiReadBurstReg(CC1101_RXFIFO,rxBuffer,limit) и она должна присутствовать. Зачем?

В errata по этому поводу информации не содержится https://www.ti.com/lit/er/swrz020e/swrz020e.pdf

 

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Скриншоты из SmartRF ? Возможно связано с "Proprietary, Wireless M-Bus (T, S, C mode)" и поддержкой этих требований.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...