主题中讨论的其他器件: CC1120
您好!
我在监听模式下使用 cc1200、所以我使用可变长度数据包模式。
我们有一项要求、即我们必须接收 大约240字节的大尺寸数据包。
我在中断 RXFIFO_THR_PKT 上接收数据包、其中 FIFO 阈值配置为127字节。
我没有接收整个数据包、而是连续接收前几个字节
请帮我解决此问题。
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.
首先、我建议您在不使用监听模式的情况下进行此操作、以验证您是否能够正确地发送和接收大于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
遗憾的是、我本周不在办公室、因此我没有 CC1200硬件可供测试、无法为您提供任何图解。
我发送给您的代码在 CC1200 EM (+ TRXEB)上经过测试、可与所有数据包长度配合使用。
我的理解是、代码在 EMS 上运行、而不是在硬件上运行。 是这样吗?
我建议您这样做、以获取我们知道可以正常工作的代码、并将其修改为仅发送长度为240的数据包。
使用逻辑分析仪监控 SPI 线路和 GPIO、以查看在这种情况下 GPIO 的行为。
然后在您的硬件上尝试相同的操作、并比较 GPIO 切换。
在您自己的硬件上、您应该做的第一件事是验证您的中断配置是否正确、以及您是否能够在所有 GPIO 的正确边缘上获得中断。 如何在 MCU 上启用/禁用/清除中断可能与我使用的 MSP430不同、因此我的演示代码必须根据您的 MCU 工作方式进行更改。
BR
Siri