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.

[参考译文] CC1200:接收的数据包大小超过128字节

Guru**** 2524550 points
Other Parts Discussed in Thread: CC1200, CC1120

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/1120602/cc1200-reception-of-packet-size-more-than-128-bytes

器件型号:CC1200
主题中讨论的其他器件: CC1120

您好!

我在监听模式下使用 cc1200、所以我使用可变长度数据包模式。

我们有一项要求、即我们必须接收 大约240字节的大尺寸数据包。

我在中断 RXFIFO_THR_PKT 上接收数据包、其中 FIFO 阈值配置为127字节。

我没有接收整个数据包、而是连续接收前几个字节

请帮我解决此问题。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    首先、我建议您在不使用监听模式的情况下进行此操作、以验证您是否能够正确地发送和接收大于128字节的数据包。

    首先使用 SmartRF Studio 中的一些典型设置、并在开始更改任何内容之前让软件使用这些设置。

    如果不详细了解您正在做什么、我就不可能告诉您导致您所看到问题的原因。

    我建议您设置较低的阈值、因为在开始读取 RX FIFO 之前、它几乎无需溢出。

    请记住、即使您所期望的数据包长度为240字节、对讲机也可能会接收长度远低于(低于您设置的 FIFO 阈值)的虚假数据包。 必须确保您的软件也处理这些情况。  

    在这些情况下 、RXFIFO_THR 信号永远不会置位、 您还需要使用 PKT_SYNC_RxTx 信号来确定是否接收到数据包

    Siri

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    我已经在 数据包模式(无监听模式)下进行了测试、在这种情况下、我也无法接收任何数据包、并且我收到 RX FIFO 错误。 它仅在同步串行模式下工作正常。

    我还尝试将 FIFO 阈值 设置为64字节的一半大小,即 0x3F。 在这种情况下、我也会观察到同样的问题。  

    我的接收机制如下:

    将 GPIO0的 RX 中断配置为0x01 (即  RXFIFO_THR_PKT)。 接收到中断时、我的接收功能被触发。

    //读取 RX FIFO 中的字节数
    cc120xSpiReadReg (CC1200_NUM_RXBYTES、&rxBytes、1);
    操作

     if (rxBytes!= 0)
     {

      cc120xSpiReadRxFifo (&RFBuffer[RX_DATA_index]、rxBytes);
      RX_DATA_INDEX += rxBytes;
     }
     cc120xSpiReadReg (CC1200_NUM_RXBYTES、&rxBytes、1);

    while (rxBytes!= 0);

    如果我的数据包是 F01000-032-0705.... F0。

    当 FIFO 中有128个字节并且没有 FIFO 错误时、我接收到第一个中断。 我正在读取前128个字节、并且它已正确读取。但是、正如您在函数中观察到的、我会继续读取 FIFO、直到它为空。 在下一次迭代中、我在 FIFO 中得到30个字节、然后、数据包从 F0 01 02 03开始...最多30个字节、 我在 RX FIFO 中一直得到大约1、2个字节、直到它为0、并且每次它从数据包起始而不是下一个字节开始。

    读取 FIFO 时是否缺少任何内容? 或者、我是否需要在该特定场景中阅读其他一些机制?  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我查看了 CC1120的无限数据包长度模式、并进行了一些更改、以便能够发送和接收长度介于1到255之间的数据包。 我的修改代码如下:

    请将其用作参考:

    发送:

    #define FIFO_SIZE                   128
    #define CRC_OK                      0x80
    #define AVAILABLE_BYTES_IN_TX_FIFO  122     // # of bytes one can write to the
                                                // TX_FIFO when a falling edge occur
                                                // on IOCFGx = 0x02 and
                                                // FIFO_THR = 120
    #define BYTES_IN_TX_FIFO            (FIFO_SIZE - AVAILABLE_BYTES_IN_TX_FIFO)
    #define INFINITE                    0
    #define FIXED                       1
    #define MAX_VARIABLE_LENGTH         255
    #define INFINITE_PACKET_LENGTH_MODE 0x40
    #define FIXED_PACKET_LENGTH_MODE    0x00
    
    #define GPIO3                       0x04
    #define GPIO2                       0x08
    #define GPIO0                       0x80
    
    
    /*******************************************************************************
    * LOCAL VARIABLES
    */
    static uint8 txBuffer[MAX_VARIABLE_LENGTH + 1];   // Buffer used to hold the packet
                                                      // to be sent
    static uint8 packetSent = FALSE;            // Flag set when packet is sent
    static uint16 packetCounter = 0;            // Counter keeping track of
                                                // packets sent
    static uint16 packetLength = 1;             // Length byte inserted in the first
                                                // byte of the TX FIFO
    static uint32 bytesLeft;                    // Keeping track of bytes left to
                                                // write to the TX FIFO
    static uint8 *pBufferIndex;                 // Pointer to current position in
                                                // the txBuffer
    static int8 iterations;                     // For packets greater than 128
                                                // bytes, this variable is used to
                                                // keep track of how many time the
                                                // TX FIFO should be re-filled to
                                                // its limit
    static uint8 writeRemainingDataFlag;        // When this flag is set, the
                                                // TX FIFO should not be filled
                                                // entirely
    
    
    /*******************************************************************************
    * STATIC FUNCTIONS
    */
    static void initMCU(void);
    static void registerConfig(void);
    static void updateLcd(void);
    static void packetSentISR(void);
    static void txFifoBelowThresholdISR(void);
    static void printWelcomeMessage(void);
    static void waitMs(uint16 msec);
    static void waitUs(uint16 msec);
    
    
    /*******************************************************************************
    *   @fn         main
    *
    *   @brief      Runs the main routine
    *
    *   @param      none
    *
    *   @return     none
    */
    void main(void)
    {
        uint8 writeByte;
    
        // Initialize MCU and peripherals
        initMCU();
    
        // Write radio registers (typical settings from SmartRF Studio)
        registerConfig();
    
        // Application specific registers
        // FIFO_THR = 120
        // GPIO0 = TXFIFO_THR
        // GPIO2 = PKT_SYNC_RXTX
        writeByte = 0x78; cc120xSpiWriteReg(CC120X_FIFO_CFG, &writeByte, 1);
        writeByte = 0x02; cc120xSpiWriteReg(CC120X_IOCFG0,   &writeByte, 1);
        writeByte = 0x06; cc120xSpiWriteReg(CC120X_IOCFG2,   &writeByte, 1);
    
        // Connect ISR function to GPIO0
        ioPinIntRegister(IO_PIN_PORT_1, GPIO0, &txFifoBelowThresholdISR);
    
        // Interrupt on falling edge
        ioPinIntTypeSet(IO_PIN_PORT_1, GPIO0, IO_PIN_FALLING_EDGE);
    
        // Clear interrupt
        ioPinIntClear(IO_PIN_PORT_1, GPIO0);
    
        // Connect ISR function to GPIO2
        ioPinIntRegister(IO_PIN_PORT_1, GPIO2, &packetSentISR);
    
        // Interrupt on falling edge
        ioPinIntTypeSet(IO_PIN_PORT_1, GPIO2, IO_PIN_FALLING_EDGE);
    
        // Clear interrupt
        ioPinIntClear(IO_PIN_PORT_1, GPIO2);
    
        // Enable interrupt
        ioPinIntEnable(IO_PIN_PORT_1, GPIO2);
    
        printWelcomeMessage();
    
        // Infinite loop
        while(TRUE)
        {
            // Wait for button push
            while(!bspKeyPushed(BSP_KEY_ALL));
    
            // Transmit 1000 packets
            for (uint16 i = 0; i < MAX_VARIABLE_LENGTH; i++)
            {
                // Create data packet
                txBuffer[0] = packetLength;
                for (uint16 i = 1; i < packetLength + 1; i++)
                {
                    txBuffer[i] = (uint8)i;
                }
        
                writeRemainingDataFlag = FALSE;
                
                ioPinIntClear(IO_PIN_PORT_1, GPIO0);
                ioPinIntEnable(IO_PIN_PORT_1, GPIO0);
                       
                if (packetLength < FIFO_SIZE)
                {
                    cc120xSpiWriteTxFifo(txBuffer, packetLength + 1);
                    ioPinIntDisable(IO_PIN_PORT_1, GPIO0);
                }
                else
                {
                    cc120xSpiWriteTxFifo(txBuffer, FIFO_SIZE);
                    pBufferIndex = txBuffer + FIFO_SIZE;
                    bytesLeft = packetLength + 1 - FIFO_SIZE;
                    iterations = (bytesLeft / AVAILABLE_BYTES_IN_TX_FIFO);
                
                    if(iterations < 1)
                    {
                        writeRemainingDataFlag = TRUE;
                    }
                }
                
                // Enter TX mode
                trxSpiCmdStrobe(CC120X_STX);
    
                // Wait for packet to be sent
                while (!packetSent);
                packetSent = FALSE;
    
                // Update LCD
                updateLcd();
    
                waitMs(300);
                
                packetLength++;
            }
        }
    }
    
    /*******************************************************************************
    * @fn          packetSentISR
    *
    * @brief       Function running every time a packet has been sent
    *
    * @param       none
    *
    * @return      none
    */
    static void packetSentISR(void) {
    
        packetSent = TRUE;
    
        // Clear ISR flag
        ioPinIntClear(IO_PIN_PORT_1, GPIO2);
        ioPinIntClear(IO_PIN_PORT_1, GPIO0);
    }
    
    
    /*******************************************************************************
    *   @fn         txFifoBelowThresholdISR
    *
    *   @brief      Function running every time the TX FIFO is drained below
    *               127 - FIFO_THR = 127 - 120 = 7
    *
    *   @param      none
    *
    *   @return     none
    */
    static void txFifoBelowThresholdISR(void) {
    
        uint8 writeByte;
    
        if (writeRemainingDataFlag)
        { 
            cc120xSpiWriteTxFifo(pBufferIndex, bytesLeft);  // Write remaining bytes
                                                            // to the TX FIFO
            // Disable interrupt on GPIO0
            ioPinIntDisable(IO_PIN_PORT_1, GPIO0);
    
        }
        else 
        { // Fill up the TX FIFO
            cc120xSpiWriteTxFifo(pBufferIndex, AVAILABLE_BYTES_IN_TX_FIFO);
    
            pBufferIndex += AVAILABLE_BYTES_IN_TX_FIFO;
            bytesLeft -= AVAILABLE_BYTES_IN_TX_FIFO;
    
            if (!(--iterations))
            {
                writeRemainingDataFlag = TRUE;
            }
        }
    
        // Clear ISR flag
        ioPinIntClear(IO_PIN_PORT_1, GPIO0);
    }
    

    RX:

    #define PACKET_LENGTH               255     // Max packet length excepted
    #define CRC_OK                      0x80
    #define BYTES_IN_RX_FIFO            121     // # of bytes one can read from the
                                                // RX_FIFO when a rising edge occur
                                                // on IOCFGx = 0x00 and
                                                // FIFO_THR = 120
    
    #define MAX_VARIABLE_LENGTH         255
    #define RX_START                    0
    #define RX_WAIT                     1
    
    #define GPIO3                       0x04
    #define GPIO2                       0x08
    #define GPIO0                       0x80
    
    
    /*******************************************************************************
    * LOCAL VARIABLES
    */
    static uint8 rxBuffer[PACKET_LENGTH + 3];   // Buffer used to hold the received
                                                // packet (1 length byte + 2 status bytes)
    static uint8 packetReceived = FALSE;        // Flag set when packet is received
    static uint16 packetCounter = 0;            // Counter keeping track of packets
                                                // with CRC OK
    static uint16 packetLength;                 // Two first bytes received after
                                                // the sync word
    static uint32 bytesLeft;                    // Keeping track of bytes left to
                                                // read from the RX FIFO
    static uint8 fixedPacketLength;
    static uint8 *pBufferIndex;                 // Pointer to current position in
                                                // the rxBuffer
    static uint8 state = RX_START;
    
    
    /*******************************************************************************
    * STATIC FUNCTIONS
    */
    static void initMCU(void);
    static void registerConfig(void);
    static void updateLcd(void);
    static void syncReceivedISR(void);
    static void packetReceivedISR(void);
    static void rxFifoAboveThresholdISR(void);
    static void printWelcomeMessage(void);
    
    
    /*******************************************************************************
    *   @fn         main
    *
    *   @brief      Runs the main routine
    *
    *   @param      none
    *
    *   @return     none
    */
    void main(void) {
    
        uint8 writeByte;
    
        // Initialize MCU and peripherals
        initMCU();
    
        // Write radio registers (preferred settings from SmartRF Studio)
        registerConfig();
    
        // Application specific registers
        // FIFO_THR = 120
        // GPIO0 = RXFIFO_THR
        // GPIO2 = PKT_SYNC_RXTX
        // GPIO3 = PKT_SYNC_RXTX
        writeByte = 0x78; cc120xSpiWriteReg(CC120X_FIFO_CFG, &writeByte, 1);
        writeByte = 0x00; cc120xSpiWriteReg(CC120X_IOCFG0,   &writeByte, 1);
        writeByte = 0x06; cc120xSpiWriteReg(CC120X_IOCFG2,   &writeByte, 1);
        writeByte = 0x06; cc120xSpiWriteReg(CC120X_IOCFG3,   &writeByte, 1);
    
        // Connect ISR function to GPIO0
        ioPinIntRegister(IO_PIN_PORT_1, GPIO0, &rxFifoAboveThresholdISR);
    
        // Interrupt on falling edge
        ioPinIntTypeSet(IO_PIN_PORT_1, GPIO0, IO_PIN_RISING_EDGE);
    
        // Clear interrupt
        ioPinIntClear(IO_PIN_PORT_1, GPIO0);
    
        // Enable interrupt
        ioPinIntEnable(IO_PIN_PORT_1, GPIO0);
    
        // Connect ISR function to GPIO2
        ioPinIntRegister(IO_PIN_PORT_1, GPIO2, &syncReceivedISR);
    
        // Interrupt on rising edge
        ioPinIntTypeSet(IO_PIN_PORT_1, GPIO2, IO_PIN_RISING_EDGE);
    
        // Clear interrupt
        ioPinIntClear(IO_PIN_PORT_1, GPIO2);
    
        // Enable interrupt
        ioPinIntEnable(IO_PIN_PORT_1, GPIO2);
    
        // Set up interrupt on GPIO3 (PKT_SYNC_RXTX)
        ioPinIntRegister(IO_PIN_PORT_1, GPIO3, &packetReceivedISR);
    
        // Interrupt on falling edge
        ioPinIntTypeSet(IO_PIN_PORT_1, GPIO3, IO_PIN_FALLING_EDGE);
    
        printWelcomeMessage();
    
        while (TRUE) {
            switch (state) {
    
                //------------------------------------------------------------------
                case RX_START:
                //------------------------------------------------------------------
                trxSpiCmdStrobe(CC120X_SRX);
                pBufferIndex = rxBuffer;
    
                // Disable interrupt on GPIO3
                ioPinIntDisable(IO_PIN_PORT_1, GPIO3);
                
                ioPinIntClear(IO_PIN_PORT_1, GPIO0);
                ioPinIntClear(IO_PIN_PORT_1, GPIO2);
    
                state = RX_WAIT;
    
                //------------------------------------------------------------------
                case RX_WAIT:
                //------------------------------------------------------------------
                if (packetReceived) {
                    packetReceived = FALSE;
    
                    // Check CRC and update LCD if CRC OK
                    if ((rxBuffer[packetLength + 2]) & CRC_OK)
                        updateLcd();
    
                    state = RX_START;
                }
                break;
    
                //------------------------------------------------------------------
                default:
                //------------------------------------------------------------------
    
                break;
            }
        }
    }
    
    /*******************************************************************************
    *   @fn         syncReceivedISR
    *
    *   @brief      Function running every time a sync word has been received
    *
    *   @param      none
    *
    *   @return     none
    */
    static void syncReceivedISR(void) {
    
        uint8 numRxBytes;
        uint8 writeByte;
    
        // After the sync word is received one needs to wait for the 
        // length byte to be put in the RX FIFO
        do {
            cc120xSpiReadReg(CC120X_NUM_RXBYTES, &numRxBytes, 1);
        } while (numRxBytes < 1);
    
        // Read the length byte and store it in the packetLength variable
        cc120xSpiReadRxFifo(rxBuffer, 1);
        pBufferIndex += 1;
        packetLength =  rxBuffer[0];
    
        bytesLeft = packetLength + 2;
    
        // Clear interrupt flag and enable GPIO3
        ioPinIntClear(IO_PIN_PORT_1, GPIO3);
        ioPinIntEnable(IO_PIN_PORT_1, GPIO3);
    
        // Clear ISR flag
        ioPinIntClear(IO_PIN_PORT_1, GPIO2);
    }
    
    
    /*******************************************************************************
    *   @fn         packetReceivedISR
    *
    *   @brief      Function running every time a packet has been received
    *
    *   @param      none
    *
    *   @return     none
    */
    static void packetReceivedISR(void) {
        cc120xSpiReadRxFifo(pBufferIndex, bytesLeft);
        bytesLeft = 0;
        packetReceived = TRUE;
    
        // Clear ISR flag
        ioPinIntClear(IO_PIN_PORT_1, GPIO3);
    }
    
    
    /*******************************************************************************
    *   @fn         rxFifoAboveThresholdISR
    *
    *   @brief      Function running every time the RX FIFO is filled above
    *               threshold (FIFO_THR = 120)
    *
    *   @param      none
    *
    *   @return     none
    */
    static void rxFifoAboveThresholdISR(void) {
    
        uint8 writeByte;
    
        if(!packetReceived)
        {
            cc120xSpiReadRxFifo(pBufferIndex, BYTES_IN_RX_FIFO);
            bytesLeft -= BYTES_IN_RX_FIFO;
            pBufferIndex += BYTES_IN_RX_FIFO;
    
            // Clear ISR flag
            ioPinIntClear(IO_PIN_PORT_1, GPIO0);
        }
    }
    

    Siri

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Siri、

    感谢您的快速响应。

    但我需要在射频监听模式(使用 PQT 的 eWOR)下实现此功能。 如果您能为我建议相同的方法、那将非常有帮助。

    同时、如果与监听模式兼容、我将在我的末尾尝试无限数据包模式

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    恐怕我们没有带宽来为您提供完整的代码示例。 我已经向您展示了如何接收长度大于 FIFO 大小的数据包、并且提供了示例代码来说明如何对长度不超过 FIFO 大小的数据包使用监听模式。

    您需要努力将这两个示例组合在一起。

    Siri

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    是的、当然、我理解。

    只需一个查询:Infinite 数据包模式是否与射频监听模式兼容?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    如果数据包长度小于255字节、则不应使用无限数据包模式。 在提供的示例中、我使用了可变数据包长度模式(我刚刚使用了无限数据包长度模式示例作为起点并对其进行了修改)。

    Siri

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我可以在监听模式下为 cc1200评估板实现类似的逻辑。相同的逻辑当我为定制 cc1200评估板进行移植时、我会看到不同的行为。  

    中断被配置为-> GPIO0 0x01和 GPIO2 0x29

    假设数据包大小为240、FIFO 阈值为120、我将在 FIFO 中获得121个字节的中断、但不会在数据包结束时获得中断。

    您能帮我解决可能的原因吗?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    遗憾的是、我本周不在办公室、因此我没有 CC1200硬件可供测试、无法为您提供任何图解。

    我发送给您的代码在 CC1200 EM (+ TRXEB)上经过测试、可与所有数据包长度配合使用。

    我的理解是、代码在 EMS 上运行、而不是在硬件上运行。 是这样吗?

    我建议您这样做、以获取我们知道可以正常工作的代码、并将其修改为仅发送长度为240的数据包。

    使用逻辑分析仪监控 SPI 线路和 GPIO、以查看在这种情况下 GPIO 的行为。

    然后在您的硬件上尝试相同的操作、并比较 GPIO 切换。

    在您自己的硬件上、您应该做的第一件事是验证您的中断配置是否正确、以及您是否能够在所有 GPIO 的正确边缘上获得中断。 如何在 MCU 上启用/禁用/清除中断可能与我使用的 MSP430不同、因此我的演示代码必须根据您的 MCU 工作方式进行更改。

    BR

    Siri