This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC1101: Signal not being received consistently nor demodulated correctly

Part Number: CC1101
Other Parts Discussed in Thread: TEST2, CC110L

So, this question is a follow-up to my last thread that helped me understand how the sync word can still be used with a signal that doesn't use "101010" as a preamble, but instead has something like "110110110".

* I am able to receive this OOK-modulated signal

* It doesn't work immediately, instead only after trying (transmitting) for a while.

* Unfortunately, the actually returned values are mostly zero / the demodulation of the signal didn't completely work out fine.

* For whatever reason, at least when sending, I need to invert all bits, as well as when setting the sync word. So maybe the output also has to be inverted, in that case my actually received signal is mostly high.

* The value in RSSI after reception is around 240, which I think is quite high (?). While transmitting and being close to the CC1101 (20cm) the RSSI drops to around 50-ish and when the system is idle the reading is around 210.

* The signal to be detected (logical): 1111111111111111000010110111001100

* The signal to be detected (physical): 110110110110110110110110110110110110110110110110 100100100100 110100110110100110110110100100110110100100

* The preamble: 11011011011011011011011011011011011011011011

* The sync word to be looked for: 0110100100100100 = 0x6924

* The payload data: 110100110110100110110110100100110110100100

 

 

 


These are my initial register settings:

IOCFG2, 0x69
IOCFG1, 0x6E
IOCFG0, 0x46
FIFOTHR, 0x47
PKTLEN, 0x23
PKTCTRL1, 0x04
PKTCTRL0, 0x04

SYNC1, 0x69 (actually, inverted: 0x96)
SYNC0, 0x24 (actually, inverted: 0xDB)
CHANNR, 0x00

FSCTRL1, 0x06
FSCTRL0, 0x00

FREQ2, 0x10
FREQ1, 0xB0
FREQ0, 0x71

MDMCFG4, 0xE6
MDMCFG3, 0xA7
MDMCFG2, 0x32
MDMCFG1, 0x22
MDMCFG0, 0xF8

DEVIATN, 0x15
MCSM2, 0x07
MCSM1, 0x20
MCSM0, 0x18
FOCCFG, 0x14
BSCFG, 0x6C
AGCCTRL2, 0x03
AGCCTRL1, 0x00
AGCCTRL0, 0x92
WOREVT1, 0x87
WOREVT0, 0x6B
WORCTRL, 0xFB
FREND1, 0x56
FREND0, 0x11
FSCAL3, 0xE9
FSCAL2, 0x2A
FSCAL1, 0x00
FSCAL0, 0x1F
RCCTRL1, 0x41
RCCTRL0, 0x00
FSTEST, 0x59
PTEST, 0x7F
AGCTEST, 0x3F
TEST2, 0x81
TEST1, 0x35
TEST0, 0x0B
0x3E, 0xC0

After that, I just do a strobe command to set the CC1101 in RX state.

 

 

 

Thank you in advance!
PS: I've also read this already and that's why my AGCCTRL settings are like pasted above.

  • I'm going to mention and @TER (not working :( ) as they helped me significantly to get to the point that I'm at now. Thanks again!
    Hopefully we can figure out together how to fix the demodulation and get the CC1101 to receive all the sent data packets.
  • In the linked / original post, I was told that the CC1101 can detect the 110110110... preamble. It actually does, but not consistently.
  • CC1101 works with preamble that is different from 0x55 (or 0xAA). The comments Torstein and I made in the other post are correct. You need to enter your "custom" preamble in the TX FIFO along with the sync word (i.e. TX needs to be set up with no preamble/sync). As long as the "custom" preamble has transitions CC1101 will perform bit synchronization. On the RX side you cannot enable PQT (i.e. gating sync word search with preamble quality), but this is not something you have done in your settings so you will be ok. The 16 bit sync word can be entered into SYNC1, SYNC0 registers and 16/16 sync + carrier sense enabled.

    Tested this on my bench this morning and provided register settings in the original thread. e2e.ti.com/.../2787012
  • Thank you Sverre! I don't need PQT so that's not an issue :-) Thank you very much for actually testing it with your hardware.
    I think that it's something with the demodulation that doesn't work :/
  • Could you maybe try to receive this signal?

    1010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010

    0110011001101010

    10010101101010010110101010101010101001010110010110101010100101101001011001101001101010011001011010010101010101100101010101101001011001011010101010010101101001100110101001010110100

    http://pasted.co/f1c4e1d5

    It has a regular preamble, but I still can't receive it.

    I only do:

    1.) reset()

    2.) your register settings for RX

    3.) set carrier frequency to 434.4MHz (as that's what this transmitter sends at)

    4.) set sync mode to 2

    5.) set sync word to 0x666A (marked in bold)

    6.) set into RX state, wait until RXBYTES has something and print it out.

    The device never prints anything :(

  • Please refer to the attached Word document. This shows both the

    A) original "preamble + sync"

    Preamble: 1101 1011 0110 1101 1011 0110 1101 1011 0110 1101 1011 = 0xDB 69 B6 DB 6D B (=first 44 chips)

    Sync: 0110 1001 0010 0100 = 0x6924 (=16 chips before payload)

    B) new "preamble + sync"

    AA AA AA AA AA AA AA 66 6A

    As you can see from the SmartRF Studio figures the data is received correctly

    E2E_OOK.docx

  • Hi Sverre,

    Here is my code. https://gist.github.com/unixb0y/e00be8849ca5a576efdda22b9f16e2a3 I removed all methods and functions etc, and simplified it as far as possible. It works like this:

    I reset the chip and afterwards set the registers to the exact same values that you chose in the DOCX file, except the ones where you can see comments on the right of them. (the comments are your original values)

    That's because my transmitter uses 434.4 MHz and a baud rate of around 3300 kBaud.

    I don't know if you code in Python but you should easily be able to understand it and hopefully you can tell me whether I missed something or maybe I didn't put it into RX mode correctly or anything like that? The actual "logic" part is under 20 lines of code (from line 217 to line 235). That would be so awesome!
    Thank you in advance :-)


    Dave

  • I am an RF / HW guy and would not be the right person to look at your code. I will ask one of my colleagues to have a look.
  • Okay, thank you very much!
    Is it maybe possible that my bandwidth is too small or something like that? (Even though I have the exact same settings like you do and it works in your case, so.... ¯\_(ツ)_/¯)

    By the way: How do you interface with the module directly from your PC (using RFStudio)?

  • Hi

    I have been asked by Sverre to take a look at your code. Please see my comment below:

    writeBurst(PATABLE, PA_TABLE) // You cannot write to PATABLE first and then reset the device. Then your PA TABLE will be deleted
    strobe(SRES) // Please make sure that the Power on Reset req. Stated in the data sheet is fulfilled. If not, you need to perform a manual reset as described in Figure 27 (an sres is not enough)
    
    writeSingleByte(IOCFG2, 0x29)    
    writeSingleByte(IOCFG1, 0x2E)    
    writeSingleByte(IOCFG0, 0x06)    
    writeSingleByte(FIFOTHR, 0x47)   
    writeSingleByte(SYNC1, 0x66)
    writeSingleByte(SYNC0, 0x6A)
    writeSingleByte(PKTLEN, 0x0A)    
    writeSingleByte(PKTCTRL1, 0x04)  
    writeSingleByte(PKTCTRL0, 0x04)  
    writeSingleByte(ADDR, 0x00)
    writeSingleByte(CHANNR, 0x00)
    writeSingleByte(FSCTRL1, 0x06)   
    writeSingleByte(FSCTRL0, 0x00)   
    writeSingleByte(FREQ2, 0x10)	  #. 0x10 .#
    writeSingleByte(FREQ1, 0xB5)	  #. 0xB0 .#
    writeSingleByte(FREQ0, 0x2B)	  #. 0x71 .#
    writeSingleByte(MDMCFG4, 0xE7)    #. 0xE6 .# 
    writeSingleByte(MDMCFG3, 0x10)    #. 0xA7 .#
    writeSingleByte(MDMCFG2, 0x32)   
    writeSingleByte(MDMCFG1, 0x22)   
    writeSingleByte(MDMCFG0, 0xF8)
    writeSingleByte(DEVIATN, 0x00)   
    writeSingleByte(MCSM2, 0x07)
    writeSingleByte(MCSM1, 0x30)     
    writeSingleByte(MCSM0, 0x18)
    writeSingleByte(FOCCFG, 0x16)
    writeSingleByte(BSCFG, 0x6C)
    writeSingleByte(AGCCTRL2, 0x04)  
    writeSingleByte(AGCCTRL1, 0x00)  
    writeSingleByte(AGCCTRL0, 0x91)
    writeSingleByte(WOREVT1, 0x87)
    writeSingleByte(WOREVT0, 0x6B)
    writeSingleByte(WORCTRL, 0xFB)
    writeSingleByte(FREND1, 0x56)    
    writeSingleByte(FREND0, 0x11)    
    writeSingleByte(FSCAL3, 0xE9)
    writeSingleByte(FSCAL2, 0x2A)
    writeSingleByte(FSCAL1, 0x00)
    writeSingleByte(FSCAL0, 0x1F)
    writeSingleByte(RCCTRL1, 0x41)
    writeSingleByte(RCCTRL0, 0x00)
    writeSingleByte(FSTEST, 0x59)
    writeSingleByte(PTEST, 0x7F)
    writeSingleByte(AGCTEST, 0x3F)
    writeSingleByte(TEST2, 0x81)     
    writeSingleByte(TEST1, 0x35)     
    writeSingleByte(TEST0, 0x09)     
    writeSingleByte(PARTNUM, 0x00)
    writeSingleByte(VERSION, 0x04)
    writeSingleByte(FREQEST, 0x00)
    writeSingleByte(LQI, 0x7F)
    writeSingleByte(RSSI, 0x80)
    writeSingleByte(MARCSTATE, 0x01)
    writeSingleByte(WORTIME1, 0x00)
    writeSingleByte(WORTIME0, 0x00)
    writeSingleByte(PKTSTATUS, 0x00)
    writeSingleByte(VCO_VC_DAC, 0x94)
    writeSingleByte(TXBYTES, 0x00)
    writeSingleByte(RXBYTES, 0x00)
    writeSingleByte(RCCTRL1_STATUS, 0x00)
    writeSingleByte(RCCTRL0_STATUS, 0x00)
    
    strobe(SRX)
    
    rx_bytes_val = readSingleByte(RXBYTES) // It does not make sense to read this register here. The radio will most likely not have reached RX state yet
    
    print("waiting for data")
    
    while gdo0.value == False: 
    	pass // At this point you only know that a sync word is received. There is still not any data in the RX FIFO
    
    #if rx_bytes_val has something and Underflow bit is not 1
    while not (rx_bytes_val & 0x7F and not (rx_bytes_val & 0x80)): 
        rx_bytes_val = readSingleByte(RXBYTES)
        print(rx_bytes_val)
        pass // At this point you might have only 1 byte in the RX FIFO
    
    data_len = readSingleByte(PKTLEN)
    
    data = readBurst(RXFIFO, data_len) // Still, you try to read several byte
    print("Data: ", ''.join(list(map(lambda x: zfill(x[2:],8), list(map(bin, data))))))

    Below is some pseudo code showing what your code should do:

    1) Perform manual reset in case POR Requirements is not fulfilled (see table 18 in the data sheet)
    2) Configure all registers (including PATABLE)
    3) Strobe SRX
    4) Wait for falling edge interrupt on GDO0 (there will first be a rising edge interrupt when sync is received)
    5) When you get the falling edge interrupt, you can simply read 12 bytes from the RXFIFO. 
       // PKTLEN = 10 (and you have APPEND_STATUS = 1). You will not have any overflow if you always starts RX with an empty FIFO

    BR

    Siri

  • Hello Siri,

    Thank you very much for your reply and your new information, that definitely helps!

    This is how my code looks like right now:

    mySPI = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
    cs = DigitalInOut(board.D9)
    gdo0 = DigitalInOut(board.D10)
    device = SPIDevice(mySPI, cs, baudrate=50000, polarity=0, phase=0) 
    strobe(SRES)
    
    writeBurst(PATABLE, PA_TABLE)
    
    writeSingleByte(IOCFG2, 0x29)    
    writeSingleByte(IOCFG1, 0x2E)    
    writeSingleByte(IOCFG0, 0x06)    
    writeSingleByte(FIFOTHR, 0x47)   
    writeSingleByte(SYNC1, 0x66)
    writeSingleByte(SYNC0, 0x6A)
    writeSingleByte(PKTLEN, 0x0A)    
    writeSingleByte(PKTCTRL1, 0x04)  
    writeSingleByte(PKTCTRL0, 0x04)  
    writeSingleByte(ADDR, 0x00)
    writeSingleByte(CHANNR, 0x00)
    writeSingleByte(FSCTRL1, 0x06)   
    writeSingleByte(FSCTRL0, 0x00)   
    writeSingleByte(FREQ2, 0x10)	  #. 0x10 .#
    writeSingleByte(FREQ1, 0xB5)	  #. 0xB0 .#
    writeSingleByte(FREQ0, 0x2B)	  #. 0x71 .#
    writeSingleByte(MDMCFG4, 0xE7)    #. 0xE6 .# 
    writeSingleByte(MDMCFG3, 0x10)    #. 0xA7 .#
    writeSingleByte(MDMCFG2, 0x32)   
    writeSingleByte(MDMCFG1, 0x22)   
    writeSingleByte(MDMCFG0, 0xF8)
    writeSingleByte(DEVIATN, 0x00)   
    writeSingleByte(MCSM2, 0x07)
    writeSingleByte(MCSM1, 0x30)     
    writeSingleByte(MCSM0, 0x18)
    writeSingleByte(FOCCFG, 0x16)
    writeSingleByte(BSCFG, 0x6C)
    writeSingleByte(AGCCTRL2, 0x04)  
    writeSingleByte(AGCCTRL1, 0x00)  
    writeSingleByte(AGCCTRL0, 0x91)
    writeSingleByte(WOREVT1, 0x87)
    writeSingleByte(WOREVT0, 0x6B)
    writeSingleByte(WORCTRL, 0xFB)
    writeSingleByte(FREND1, 0x56)    
    writeSingleByte(FREND0, 0x11)    
    writeSingleByte(FSCAL3, 0xE9)
    writeSingleByte(FSCAL2, 0x2A)
    writeSingleByte(FSCAL1, 0x00)
    writeSingleByte(FSCAL0, 0x1F)
    writeSingleByte(RCCTRL1, 0x41)
    writeSingleByte(RCCTRL0, 0x00)
    writeSingleByte(FSTEST, 0x59)
    writeSingleByte(PTEST, 0x7F)
    writeSingleByte(AGCTEST, 0x3F)
    writeSingleByte(TEST2, 0x81)     
    writeSingleByte(TEST1, 0x35)     
    writeSingleByte(TEST0, 0x09)     
    writeSingleByte(PARTNUM, 0x00)
    writeSingleByte(VERSION, 0x04)
    writeSingleByte(FREQEST, 0x00)
    writeSingleByte(LQI, 0x7F)
    writeSingleByte(RSSI, 0x80)
    writeSingleByte(MARCSTATE, 0x01)
    writeSingleByte(WORTIME1, 0x00)
    writeSingleByte(WORTIME0, 0x00)
    writeSingleByte(PKTSTATUS, 0x00)
    writeSingleByte(VCO_VC_DAC, 0x94)
    writeSingleByte(TXBYTES, 0x00)
    writeSingleByte(RXBYTES, 0x00)
    writeSingleByte(RCCTRL1_STATUS, 0x00)
    writeSingleByte(RCCTRL0_STATUS, 0x00)
    
    strobe(SRX)
    
    print("waiting for data")
    
    while gdo0.value == False:
    	pass 
    #detected rising edge
    
    while gdo0.value == True:
        pass
    #detected falling edge
    
    data_len = readSingleByte(PKTLEN)
    
    data = readBurst(RXFIFO, data_len)
    print("Data: ", ''.join(list(map(lambda x: zfill(x[2:],8), list(map(bin, data))))))

    I'm not sure whether I need to do the manual reset, but I do have working code for TX where I also use the normal strobe-reset and it definitely works. I power the chip directly from the 3.3V of my micro controller.

  • Still have some comments to your code. You should not write to the status registers (non of the registers from PARTNUM and below).
    You do not need to read PKTLEN register to figure out what is is. It will always be the value you programmed it to (in your case, 0x0A) :-)
    You need to read PKTLEN + 2 bytes since you have APPEND_STATUS = 1 in the PKTCTRL1 register

    I assume that since you posted this, you still are having problems?

    If you do, I need to know what the problems are, if I shall be able to help your further. Are you not getting any interrupts on the GDO0 line? Are you getting data, but they are wrong?

    Siri
  • Hi Siri,
    You're right, I'll fix it asap, now I'm not @ home anymore, but I will implement that later.
    The issue is that I don't get the GDO0 signal, so I'm hanging in the
    "while gdo0.value == False:
    pass "
    loop.
    Dave
  • Is it possible that I’m too slow at reading GDO0?
    I don’t have a logic analyzer but I’ll try to program an FPGA to turn on a flag (LED) as soon as GDO0 goes to high and never turns it back off. The FPGA has no clock or timing - it’s a hardware circuit with flip flops to save data so that should do the job. But I’m pretty sure already that GDO0 is simply not set by the CC1101.
  • Hi Siri, I updated the code, still no interrupt on GDO0.

    mySPI = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
    cs = DigitalInOut(board.D9)
    gdo0 = DigitalInOut(board.D10)
    device = SPIDevice(mySPI, cs, baudrate=50000, polarity=0, phase=0) 
    strobe(SRES)
    
    writeSingleByte(IOCFG2, 0x29)    
    writeSingleByte(IOCFG1, 0x2E)    
    writeSingleByte(IOCFG0, 0x06)    
    writeSingleByte(FIFOTHR, 0x47)   
    writeSingleByte(SYNC1, 0x66)
    writeSingleByte(SYNC0, 0x6A)
    writeSingleByte(PKTLEN, 0x0A)    
    writeSingleByte(PKTCTRL1, 0x04)  
    writeSingleByte(PKTCTRL0, 0x04)  
    writeSingleByte(ADDR, 0x00)
    writeSingleByte(CHANNR, 0x00)
    writeSingleByte(FSCTRL1, 0x06)   
    writeSingleByte(FSCTRL0, 0x00)   
    writeSingleByte(FREQ2, 0x10)	  #. 0x10 .#
    writeSingleByte(FREQ1, 0xB5)	  #. 0xB0 .#
    writeSingleByte(FREQ0, 0x2B)	  #. 0x71 .#
    writeSingleByte(MDMCFG4, 0xE7)    #. 0xE6 .# 
    writeSingleByte(MDMCFG3, 0x10)    #. 0xA7 .#
    writeSingleByte(MDMCFG2, 0x32)   
    writeSingleByte(MDMCFG1, 0x22)   
    writeSingleByte(MDMCFG0, 0xF8)
    writeSingleByte(DEVIATN, 0x00)   
    writeSingleByte(MCSM2, 0x07)
    writeSingleByte(MCSM1, 0x30)     
    writeSingleByte(MCSM0, 0x18)
    writeSingleByte(FOCCFG, 0x16)
    writeSingleByte(BSCFG, 0x6C)
    writeSingleByte(AGCCTRL2, 0x04)  
    writeSingleByte(AGCCTRL1, 0x00)  
    writeSingleByte(AGCCTRL0, 0x91)
    writeSingleByte(WOREVT1, 0x87)
    writeSingleByte(WOREVT0, 0x6B)
    writeSingleByte(WORCTRL, 0xFB)
    writeSingleByte(FREND1, 0x56)    
    writeSingleByte(FREND0, 0x11)    
    writeSingleByte(FSCAL3, 0xE9)
    writeSingleByte(FSCAL2, 0x2A)
    writeSingleByte(FSCAL1, 0x00)
    writeSingleByte(FSCAL0, 0x1F)
    writeSingleByte(RCCTRL1, 0x41)
    writeSingleByte(RCCTRL0, 0x00)
    writeSingleByte(FSTEST, 0x59)
    writeSingleByte(PTEST, 0x7F)   
    writeSingleByte(AGCTEST, 0x3F)
    writeSingleByte(TEST2, 0x81)     
    writeSingleByte(TEST1, 0x35)     
    writeSingleByte(TEST0, 0x09)
    
    writeBurst(PATABLE, PA_TABLE)
    
    strobe(SRX)
    
    print("waiting for data")
    
    while gdo0.value == False:
    	pass 
    #detected rising edge
    
    while gdo0.value == True:
        pass
    #detected falling edge
    
    data_len = 0x0C # PKTLEN is programmed to 0x0A, add 2 status bytes
    
    data = readBurst(RXFIFO, data_len)
    print("Data: ", ''.join(list(map(lambda x: zfill(x[2:],8), list(map(bin, data))))))

  • If GDO0 does not toggle the sync word is not found.

    If you are able to, it could be useful to take one step back. Meaning if you can control the TX side with SmartRF Studio so we know exactly what has being sent using one of the predefined settings. Then export these settings and use them in your code and see if you are able to get sync found. After you have succeeded with that you can go back to the packet format you are working with now.
  • Unfortunately I don’t have the device to connect to SmartRF.

    But I can tell you which register settings I have used in the past to achieve a successful transmission which looked virtually the same as the original signal when receiving it with an RTL-SDR.

    Would that be helpful?

  • I just stripped down the TX code and verified that it still works. Here it is:

    mySPI = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
    cs = DigitalInOut(board.D9)
    gdo0 = DigitalInOut(board.D10)
    device = SPIDevice(mySPI, cs, baudrate=50000, polarity=0, phase=0) 
    strobe(SRES)
    
    writeSingleByte(IOCFG2, 0x69)    
    writeSingleByte(IOCFG1, 0x6E)    
    writeSingleByte(IOCFG0, 0x46)    
    writeSingleByte(FIFOTHR, 0x47)   
    writeSingleByte(SYNC1, 0x66)
    writeSingleByte(SYNC0, 0x6A)
    writeSingleByte(PKTLEN, 0x0A)    
    writeSingleByte(PKTCTRL1, 0x04)  
    writeSingleByte(PKTCTRL0, 0x04)  
    writeSingleByte(ADDR, 0x00)
    writeSingleByte(CHANNR, 0x00)
    writeSingleByte(FSCTRL1, 0x06)   
    writeSingleByte(FSCTRL0, 0x00)   
    writeSingleByte(FREQ2, 0x10)	  #. 0x10 .#
    writeSingleByte(FREQ1, 0xB5)	  #. 0xB0 .#
    writeSingleByte(FREQ0, 0x2B)	  #. 0x71 .#
    writeSingleByte(MDMCFG4, 0xE7)    #. 0xE6 .# 
    writeSingleByte(MDMCFG3, 0x10)    #. 0xA7 .#
    writeSingleByte(MDMCFG2, 0x30)    #. 0x32 .# 32 means 16/16 sync word bits
    writeSingleByte(MDMCFG1, 0x22)   
    writeSingleByte(MDMCFG0, 0xF8)
    writeSingleByte(DEVIATN, 0x15)   
    writeSingleByte(MCSM2, 0x07)
    writeSingleByte(MCSM1, 0x20)     
    writeSingleByte(MCSM0, 0x18)
    writeSingleByte(FOCCFG, 0x14)
    writeSingleByte(BSCFG, 0x6C)
    writeSingleByte(AGCCTRL2, 0x03)  
    writeSingleByte(AGCCTRL1, 0x00)  
    writeSingleByte(AGCCTRL0, 0x92)
    writeSingleByte(WOREVT1, 0x87)
    writeSingleByte(WOREVT0, 0x6B)
    writeSingleByte(WORCTRL, 0xFB)
    writeSingleByte(FREND1, 0x56)    
    writeSingleByte(FREND0, 0x11)    
    writeSingleByte(FSCAL3, 0xE9)
    writeSingleByte(FSCAL2, 0x2A)
    writeSingleByte(FSCAL1, 0x00)
    writeSingleByte(FSCAL0, 0x1F)
    writeSingleByte(RCCTRL1, 0x41)
    writeSingleByte(RCCTRL0, 0x00)
    writeSingleByte(FSTEST, 0x59)
    writeSingleByte(PTEST, 0x7F)   
    writeSingleByte(AGCTEST, 0x3F)
    writeSingleByte(TEST2, 0x81)     
    writeSingleByte(TEST1, 0x35)     
    writeSingleByte(TEST0, 0x0B)
    
    writeBurst(PATABLE, PA_TABLE)
    
    bitstring = "10101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100110011001101010100101011010100101101010101010101001101010010101010110101001011010011010011010101010101001010110011001011001101010011010100110100101100110101010010110011001011010101010010101101000"
    data = []
    for i in range(0,len(bitstring)/8):
        data.append(int(bitstring[i*8:i*8+8], 2))
    
    writeSingleByte(PKTLEN, len(data))
    strobe(SRX)
    
    marcstate = readSingleByte(MARCSTATE) & 0x1F
    dataToSend = []
    
    while (marcstate != 0x0D):
        marcstate = readSingleByte(MARCSTATE) & 0x1F
    
    print("Sending packet of", len(data), "bytes")
    
    writeBurst(TXFIFO, data)
    time.sleep(0.002)
    strobe(STX)
    
    remaining_bytes = readSingleByte(TXBYTES) & 0x7F
    while remaining_bytes != 0:
        time.sleep(0.001)
        remaining_bytes = readSingleByte(TXBYTES) & 0x7F
    
    if (readSingleByte(TXBYTES) & 0x7F) == 0:
        print("Packet sent!")
    
    else:
        print(readSingleByte(TXBYTES) & 0x7F)

  • Sorry for the late response. If I understand correctly you are using the above code for TX and you are able to receive anything using CC1101 as a receiver.

    As Torstein wrote, since GDO0 is not asserted the sync word is not detected (assuming IOCFG0 = 0x6)

    Use a spectrum analyzer to demodulate the transmitted data (in fact, since this is OOK you can also use a scope). Are you transmitting preamble followed by the sync word? Is the sync word configured in the RX unit the same as you are transmitting? Have you set PATABLE(0) and PATBLE[1] correctly (PATABLE(0) is used for logic '0' and PATBLE[1] is used for logic '1').
  • Hello Sverre,

    Thank you for the reply! Yes, that's my TX code and the "real" receiver does receive it fine. The PATABLE is set to: [0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00] both in the RX and in the TX code.

    I don't have a spectrum analyser / scope but I will attach a "recording" (with GnuRadio) of the signal that the "real" sender (remote) sends. In TX, as you can see from my register settings, I just send a few bytes of preamble and then the sync word and the data. I don't use the pre-built preamble / sync word settings for TX, but just put it all into the payload because it was easier and it worked :D

    I am pretty sure that the sync word is configured correctly, but I'm "less sure" about my PATABLE setup.

    We can clearly see that after the last 1010 of the preamble, the sync word is 0110 0110 0110 1010 = 0x666A and I set SYNC1 to 0x66 and SYNC0 to 0x6A.

  • Doing debugging with no measuring equipment is hard. You should try to get hold of a scope so that you can look at the transmitted signal.

    My understanding is that the recording is with the "real sender". How do you then know that CC1101 in TX is correctly set up?

    As far as I understand CC1101 cannot receive regardless what the TX unit is. Please confirm.
    "Real sender" in TX and CC1101 in RX: Not OK
    CC1101 in TX and CC1101 in RX: Not OK

    In RX GDO0 is not asserted, and reason being that the sync word is not detected (assuming IOCFG0 = 0x6). One possible explanation is that the RX and TX sync words are not the same. In RX the sync word in SYNC1 and SYNC0 needs to match the transmitted sync word. As a test you can set the RX sync word as 0xAA AA. The sync word will be found somewhere inside the preamble so the bit and byte sync will be off, but it would be interesting to see if you receive anything in this case. In addition, if there is a significant offset between the RX and TX units the signal will fall outside the RX filter BW and the reception will be poor (if you get anything through at all).

    Your PATABLE setup is correct.

    I will be back on January 2nd. Support will be limited until then.
  • Okay, well I can also just receive the signal with my HackRF (SDR) and GnuRadio and look at it that way. It's basically the same thing :-) If you want, I can send a recording of the received signal of the CC1101 in TX mode, but it looks exactly the same. I used this method to calibrate the baud rate to be exactly the same as the original one.
    This way I know that the CC1101 TX mode is correct: The signals look the same and (because of this) the original receiver accepts the signal.
    Yes, I confirm that the CC1101 can't receive no matter what the TX unit is.

    IOCFG0 is 0x06.

    That's a good idea! I'll try to set SYNC to 0xAAAA and see if I get *anything*.
    Hmm, true. Is there a good method to find the correct frequency offset setting? In theory my register settings should put it right at 433.4 MHz which is where the peak of the (original) signal was when I measured it with the SDR. Also, the original receiver accepts the TX signal from the CC1101 with my listed TX register settings, so if this isn't something internal to the CC1101, the frequency setting should match.

    Thanks for confirming the PATABLE!

    Okay, if you still read this in December, maybe you can give me a quick reply!
    And Merry Christmas & a happy new year :-)
  • Hello I was able to get the setup working!
    With your idea of trying different sync words, I first tried 0xAAAA. I only got results sometimes and then they looked like this: 111111100000010101111111000000 so it was just a case that it actually found anything that looked like AAAA and the whole code was garbage. So I went through my registers one by one and noticed that for whatever reason, my bandwidth was set to around 60 or 70 KHz only. Also I compared the peak of the signal in GQRX with the peak of the "real" one and the frequency was a tiny bit off. So I corrected the frequency and increased the RX bandwidth to the default of 200 KHz and voilà - it works!
    Thanks again for all the help!
    Dave
  • Good to hear you resolved this case.

    When you change the RX BW you should look at a few registers: AGCCTRL2 , FSCTRL1 (the IF frequency) and FREND1. If you refer to the attached Excel spreadsheet I have made a summary of settings used for other OOK cases. At 200 kHz RX BW AGCCTRL2 = 0x6, FSCTRL1 = 0x8, and FREND1 = 0xB6 are the better choices. See also 

    0268.OOK summary E2E.xls

  • Hello Sverre, thank you very much for the additional info, I will have a look!
    On another note: Is there such a thing as „TX bandwidth“? Like to prevent transmissions on different frequencies (channels) interfering with each other?
  • TX bandwidth (aka signal bandwidth) is often defined as the 99% occupied bandwidth (i.e bandwidth containing 99% of the total integrated power of the transmitted spectrum). An alternative is to use the 95% occupied bandwidth.

    On the RX side the RX filter needs to be wide enough to fit the TX (signal) bandwidth and also take the frequency error due to crystal errors into account. Assuming +/-X ppm frequency offset and the the errors can be at opposite extremes the following equation can be used: RX filter BW > TX bandwidth + 4*X ppm*RF frequency .

    The channel spacing should be at least as wide as the RX filter BW. You have used 200 kHz RX filter BW so a channel spacing of 200 kHz (or more) is good design choice.
  • Okay, and if I want to send data with the CC1101, can I somehow set how wide this TX / signal bandwidth is allowed to be?
  • The CC110L TX bandwidth depends on the modulation format (OOK in your case), data rate, and phase noise. The latter is fixed. The 99% bandwidth can easily be measured using a spectrum analyzer. I will be back in the lab on January 3rd and can measure if you don't have access to a spectrum analyzer.
  • I see, so that's essentially fixed in my case because if I change the data rate or modulation format, my existing off-the-shelf system that I am communicating with won't recognise the signal, right?

    But it's good to know that if I'll do a project where CC1101's communicate among each other I can choose specific settings to get a narrower channel spacing or something like that!

    It would definitely be great if you could analyse and measure the signal for me, thank you in advance! I can only try to guesstimate it by receiving transmitted signals with my SDR and looking at the image on my screen, that's something like this:

    The "left" signal is what the CC1101 sends, so I would say the bandwidth is around <100KHz?

  • Measured the 99% OBW as 40 kHz.
  • Thank you very much Sverre!
    I have a different issue now, which occurred when transitioning from a breadboard to a point-to-point hand soldered PCB. After transmitting a few times, the CC1101 behaves like always (TXBYTES go down etc.) but my SDR doesn't receive anything, so essentially nothing is sent.
    With the exact same code, if I pop the microcontroller and antennas out of the PCB's female headers and back into the breadboard, everything works fine.
    A few things that make it transmit reliably:
    1) Only insert one antenna into the PCB instead of both
    2) Connect both antennas, but put jumper wires between one of the two and the PCB
    I measured the resistances of all connections and they're pretty much equal at around 2.3 Ohms across the board.
    Should I open a new thread for this issue?
    Dave