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.

How to send data in async serial mode?

Part Number: CC1101

Hey, I'm gonna send data with CC1101 in asynchronous serial mode. In TI SmartRF Studio I generated register's values for the 433.92MHz and ASK/OOK modulation

    radio.writeSingleByte(defs.IOCFG2,0x0B)  #GDO2 Output Pin Configuration
    radio.writeSingleByte(defs.IOCFG0,0x0C)  #GDO0 Output Pin Configuration
    radio.writeSingleByte(defs.FIFOTHR,0x47) #RX FIFO and TX FIFO Thresholds
    radio.writeSingleByte(defs.PKTCTRL0,0x32)#Packet Automation Control
    radio.writeSingleByte(defs.FSCTRL1,0x06) #Frequency Synthesizer Control
    radio.writeSingleByte(defs.FREQ2,0x10)   #Frequency Control Word, High Byte
    radio.writeSingleByte(defs.FREQ1,0xB0)   #Frequency Control Word, Middle Byte
    radio.writeSingleByte(defs.FREQ0,0x71)   #Frequency Control Word, Low Byte
    radio.writeSingleByte(defs.MDMCFG4,0xF5) #Modem Configuration
    radio.writeSingleByte(defs.MDMCFG3,0x83) #Modem Configuration
    radio.writeSingleByte(defs.MDMCFG2,0x30) #Modem Configuration
    radio.writeSingleByte(defs.DEVIATN,0x15) #Modem Deviation Setting
    radio.writeSingleByte(defs.MCSM0,0x18)   #Main Radio Control State Machine Configuration
    radio.writeSingleByte(defs.FOCCFG,0x16)  #Frequency Offset Compensation Configuration
    radio.writeSingleByte(defs.AGCCTRL0,0x92)#AGC Control
    radio.writeSingleByte(defs.WORCTRL,0xFB) #Wake On Radio Control
    radio.writeSingleByte(defs.FREND0,0x11)  #Front End TX Configuration
    radio.writeSingleByte(defs.FSCAL3,0xE9)  #Frequency Synthesizer Calibration
    radio.writeSingleByte(defs.FSCAL2,0x2A)  #Frequency Synthesizer Calibration
    radio.writeSingleByte(defs.FSCAL1,0x00)  #Frequency Synthesizer Calibration
    radio.writeSingleByte(defs.FSCAL0,0x1F)  #Frequency Synthesizer Calibration
    radio.writeSingleByte(defs.TEST2,0x81)   #Various Test Settings
    radio.writeSingleByte(defs.TEST1,0x35)   #Various Test Settings
    radio.writeSingleByte(defs.TEST0,0x09)   #Various Test Settings

As I Understood from AN, to send in TX transparent mode, I need to toggle pin, connected to GD0 (GD0 is set as INPUT)

So, I write my init and strobed to TX

PA_TABLE = [0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00]
spi = SPI(1, baudrate=1125000, polarity=0, phase=0, bits=8, firstbit=SPI.MSB, sck=Pin(22), mosi=Pin(23), miso=Pin(21))

radio = cc1101.CC1101(spi=spi)
radio.reset()
setDefaultValues()
radio.writeBurst(defs.PATABLE, PA_TABLE)
radio.sidle()
radio.selfTest()
print("CC1101 radio initialized\r\n")
radio.setTXState()
radio.selfTest()

OUTPUT:
init CC1101 configuration...
PARTNUM 0x00
VERSION 0x14
MARCSTATE 0x01 (IDLE)
CC1101 radio initialized

PARTNUM 0x00
VERSION 0x14
MARCSTATE 0x13 (TX)

Next, I'm trying to send data, changing the state of pin is connected to GD0

def sendRawData(self, code1, code2, Pe):
        code1 = (code1 << 16) + 257 * urandom.getrandbits(8)
        print("0x%08X 0x%08X" % (code1, code2))
        self.__sendANMotors(code1, code2, Pe)
        #ToDo: если не установлен callback
        #self.tx_cb(code1, code2) if self.tx_cb is not None else None
        utime.sleep_ms(1000)
        return True

    def __sendANMotors(self, c1, c2, Pe):
        for j in range(0, 4):
            # sending preamble with 12 bit
            for i in range(0, 12):
                utime.sleep_us(Pe)
                self.gd0.on()
                utime.sleep_us(Pe)
                self.gd0.off()
            utime.sleep_us(Pe * 10)
            
            #send code1
            for i in range(4 * 8, 0, -1):
                self.__sendBit(c1 >> (i - 1) & 1, Pe)
            
            #send code2
            for i in range(4 * 8, 0, -1):
                self.__sendBit(c2 >> (i - 1) & 1, Pe)

            #send a few bits
            self.__sendBit(1, Pe)
            self.__sendBit(1, Pe)
            utime.sleep_us(Pe * 39)

    def __sendBit(self, b, Pe):
        if b == 0:
            self.gd0.on() # 0
            utime.sleep_us(Pe * 2)
            self.gd0.off()
            utime.sleep_us(Pe)
        else:
            self.gd0.on() # 1
            utime.sleep_us(Pe)
            self.gd0.off()
            utime.sleep_us(Pe * 2)

sendRawData(0x2020, 0x456AAA32, 420)

My RTL-SDR doesnt show any activities from cc1101, where am I not right?

  • You can test async mode using smartrf studio. I just tested cont. RX and cont TX with async mode selected. On the TX side I input a square wave into GDO0 (Data in) and I monitored the GDO0 on the receiver (data out) with a logic analyzer.

    I was able to see the square wave on my receiver.

    BR

    Siri

  • Are my configurations ok? And am I right toggling GD0 pin to transmit the data?

    And doest my order correct when I set up cc1101?

    PA_TABLE = [0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00]
    
    radio = cc1101.CC1101(spi=spi)
    radio.reset()
    setDefaultValues()
    radio.writeBurst(defs.PATABLE, PA_TABLE)
    radio.sidle()
    radio.setTXState()
    radio.selfTest()
    sendRawData(0x2020, 0x456AAA32, 420) # toggling the pin to transmit ASK/OOK code
    radio.sidle()
    radio.setTXState()

    As I understood PA_TABLE responses for transmit power, right?

    Unfortunately, I can't test cont. TX in SmartRF studio, cause I use my own custom board, but I can test GD0 with logic analyzer (on my board as initialized as OUTPUT)

    UPD

     


    I checked with my logic analyzer the GD0 Pin, the pulse is correct

  • Hi

    Your settings is according to SmartRF STudio except the FOCCFG register (Studio set this to 0x14 and you use 0x16, why?)

    I did not understand what we see on the plot you sent. Is this GDO0 on your transmitter or your receiver?

    Have you tested your boards in normal mode to make sure that your HW is OK.

    Try to make a simple example where you do the following (OOK settings from SmartRF Studio with normal packet format/FIFO mode)

    TX

    • Init MCU
    • Reset Radio
    • Configure radio (write register and PATABLE)
    • Write packet to FIFO: 5, 1, 2, 3, 4, 5
    • Strobe STX

    RX

    • Init MCU
    • Reset Radio
    • Configure radio (write register and PATABLE)
    • Strobe RTX
    • Wait for GDO0 to go high (Sync received), then low (packet received)
    • Read the RXFIFO

    If nothing happens on the GDO0 signal on the receiver (IOCFG0 = 0x06), than you need to review your HW design.

    BR

    Siri

  • Thanks for your reply!

    I tried to send data in Normal mode

    PA_TABLE = [0x00,0x12,0x0e,0x34,0x60,0xc5,0xc1,0xc0]
    spi = SPI(1, baudrate=4000000, polarity=0, phase=0, bits=8, firstbit=SPI.MSB, sck=Pin(22), mosi=Pin(23), miso=Pin(21))
    
    utime.sleep(2)
    
    radio = cc1101.CC1101(spi=spi, gd0=18)
    radio.reset()
    setPacketValues()
    radio.writeBurst(defs.PATABLE, PA_TABLE)
    radio.sidle()
    radio.selfTest()
    print("CC1101 radio initialized\r\n")
    radio.setTXState()
    radio.selfTest()
    radio.sendPacketData([5,1,2,3,5])
    utime.sleep(1)
    radio.sidle()
    radio.setTXState()

    But got nothing in my receiver side.

    My config is

        radio.writeSingleByte(defs.IOCFG0,0x06)  #GDO0 Output Pin Configuration
        radio.writeSingleByte(defs.FIFOTHR,0x47) #RX FIFO and TX FIFO Thresholds
        radio.writeSingleByte(defs.PKTCTRL0,0x05)#Packet Automation Control
        radio.writeSingleByte(defs.FSCTRL1,0x06) #Frequency Synthesizer Control
        radio.writeSingleByte(defs.FREQ2,0x10)   #Frequency Control Word, High Byte
        radio.writeSingleByte(defs.FREQ1,0xB0)   #Frequency Control Word, Middle Byte
        radio.writeSingleByte(defs.FREQ0,0x71)   #Frequency Control Word, Low Byte
        radio.writeSingleByte(defs.MDMCFG4,0xF5) #Modem Configuration
        radio.writeSingleByte(defs.MDMCFG3,0x83) #Modem Configuration
        radio.writeSingleByte(defs.MDMCFG2,0x33) #Modem Configuration
        radio.writeSingleByte(defs.DEVIATN,0x15) #Modem Deviation Setting
        radio.writeSingleByte(defs.MCSM0,0x18)   #Main Radio Control State Machine Configuration
        radio.writeSingleByte(defs.FOCCFG,0x14)  #Frequency Offset Compensation Configuration
        radio.writeSingleByte(defs.AGCCTRL0,0x92)#AGC Control
        radio.writeSingleByte(defs.WORCTRL,0xFB) #Wake On Radio Control
        radio.writeSingleByte(defs.FREND0,0x11)  #Front End TX Configuration
        radio.writeSingleByte(defs.FSCAL3,0xE9)  #Frequency Synthesizer Calibration
        radio.writeSingleByte(defs.FSCAL2,0x2A)  #Frequency Synthesizer Calibration
        radio.writeSingleByte(defs.FSCAL1,0x00)  #Frequency Synthesizer Calibration
        radio.writeSingleByte(defs.FSCAL0,0x1F)  #Frequency Synthesizer Calibration
        radio.writeSingleByte(defs.TEST2,0x81)   #Various Test Settings
        radio.writeSingleByte(defs.TEST1,0x35)   #Various Test Settings
        radio.writeSingleByte(defs.TEST0,0x09)   #Various Test Settings

    So, it seems the HW issue, if I can read PART number and Version of CC1101, does it mean that the chip is working correctly?

    And I haven't soldered the antenna, because my previous pcb was working fine without it whithin 30-40 cm. Does it affect on transmittion?

  • Normally you should be able to communicate over 30 cm without antenna but  the received signal will have low RSSI. 

    If you are working with HW you haven't fully verified yet I would use an antenna and/ or do conducted measurements. 

    Ideally you should test if your HW works with known good SW (SmartRF Studio) and after this start testing SW to give lower number of unknown. 

  • Thank you!

    A soldered an antenna, but still got nothing in the air. I tested all connections and there are no unrouted traces. I use all passive components from AN, so, maybe the problem with crystal? I use NDK-NX3225GA-26MHZ-EXS00A, and according to its DS, the loading capacitors CL = 10pF, so then I need to use 15pF of loading capacitors, my pcb uses 27pF. Do i need to change them?

  • Do you have access to a CCDebugger? 

  • just some comment to your code.

    Why are you writing more than 2 values to the PA TABLE?

    Do you have a logic analyzer so that you can confirm that your SPI accesses are according to spec?

    Siri

  • No, but I found that I incorrect placed the crystal NDK-NX3225GA-26MHZ and my crystal's pins were connected to GND. I fixed it and probably send something, need to check

  • In the software you should wait until SO goes low before doing anything else (see datasheet). Does that mean you don't have any checks on this? 

  • I wait a few seconds before doing something, I think it's enough that MISO goes low. Changing the direction of crystal doesn't give any effect. I'll try to set this one as receiver to be sure that HW is ok or not ok

  • Please verify that SO is actually low. Also monitor  the SPI interface traffic and verify that the traffic is as defined in the datasheet.

  • Ok, but if I transmit data using async, I do not need SPI, only for configure registers and patable. I can read back my registers and they have those values I set, it means SPI' working fine

  • And to send command strobes, STX? 

  • yes, I send strobe STX and wait 2 seconds, thinking for this period MISO became low, but i'll check SPI with logic analyzer, how to tell cc1101 thats my async tx is ending? Does it enough to send strobe IDLE, and after that do I need to flush TX FIFO?

  • - Change the code to wait for SO low. Waiting for 2 s does not make sense. The most important to check with a logic analyzer is that SO actually go low. 

    - You are using async mode, in other words all packet related features are disabled. Hence the TX FIFO is not in use.

    - Yes, SIDLE exits the TX state and go to IDLE.