TI中文支持网
TI专业的中文技术问题搜集分享网站

CC1352P: DN507 FEC Decoding 解码结果与编码(DN504 FEC Implementation)不一致

Part Number:CC1352POther Parts Discussed in Thread:CC1312R, CC1101,

1. 参考DN504 FEC Implementation 我们将源数据(0x01 0x02 0x03 0x04 0x05)进行FEC编码,得到:4C F0 30 10 C8 7C C3 23 40 34 7C E3;

2. 参考DN507 FEC Decoding 对上述编码数据进行解码,得到结果是:0x01 0x02 0x73 0x04 0x05, 与源数据不一致!

 

// NUMBER_OF_BYTES_AFTER_DECODING should be given the length of the payload + CRC (CRC is optional)
#define NUMBER_OF_BYTES_AFTER_DECODING  5
#define NUMBER_OF_BYTES_BEFORE_DECODING (4 * ((NUMBER_OF_BYTES_AFTER_DECODING / 2) + 1))

/*******************************************************************************
 * @fn:
 * @brief:
 * @para:
 * @return:
 ******************************************************************************/
void ReadRxFifo(uint8_t* rxBuf, uint16_t startAddr, uint16_t readLen)
{// 01 02 03 04 05const uint8_t rxRawData[] = {//0x4C, 0xF0, 0x30, 0x10, //0xC8, 0x7C, 0xC3, 0x23, //0x40, 0x34, 0x7C, 0xE3, //};uint8_t iX;for (iX = 0; iX < readLen; iX++){if (startAddr + iX >= sizeof(rxRawData)){break;}rxBuf[iX] = rxRawData[startAddr + iX];}
}

/*******************************************************************************
 * @fn:
 * @brief:* @para:
 * @return:
 ******************************************************************************/
void main(void)
{unsigned short checksum;unsigned short nBytes;unsigned char *pDecData = rxPacket; // Destination for decoded datauint16_t total = 0;// Init MCU and Radiowhile (1){
//while (!packetReceived)
//; // Wait for packet to be received (64 bytes in the RXFIFO)
//packetReceived = 0;memset(rxPacket, 0, sizeof(rxPacket));pDecData = rxPacket;// Perform de-interleaving and decoding (both done in the same function)fecDecode(NULL, NULL, 0); // The function needs to be called with a NULL pointer for// initialization before every packet to decodenBytes = NUMBER_OF_BYTES_AFTER_DECODING;total = 0;while (nBytes > 0){unsigned short nBytesOut;
//readRxFifo(RF_RXFIFO, rxBuffer, 4); // Read 4 bytes from the RXFIFO and store them in rxBufferReadRxFifo(rxBuffer, total, 4);nBytesOut = fecDecode(pDecData, rxBuffer, nBytes);total += 4;nBytes -= nBytesOut;pDecData += nBytesOut;}
		
		// 运行到此处,rxPacket的内容是:01 02 73 04 05 (十六进制)// Perform CRC check (Optional){unsigned short i;nBytes = NUMBER_OF_BYTES_AFTER_DECODING;checksum = 0xFFFF; // Init value for CRC calculationfor (i = 0; i < nBytes; i++)checksum = calcCRC(rxPacket[i], checksum);if (!checksum){// Do something to indicate that the CRC is OK}}}
}

Cherry Zhou:

您好我们已收到您的问题并升级到英文论坛寻求帮助,如有答复将尽快回复您。谢谢!

,

Cherry Zhou:

您好,

工程师这边做了如下测试:使用 CC1312编码并发送了数据0x01、0x02、0x03、0x04、0x05,并使用 CC1312R 接收它们。

可以成功实现应用手册中描述的代码,但重新编写了代码所指的读取 FIFO 的部分,因为 CC1312没有 FIFO。

数据包已正确编码和解码,此外,还通过与 CC1101和 SmartRF Studio 通信(使能 FEC)验证了这一点:

工程师使用 CC1312R rfPacketRX 示例作为起点。请注意,缓冲区大小经过优化,仅适合此特定数据包(5字节有效载荷、无 CRC),从而产生12字节交错数据。

修改后的代码如下所示:

/***** Includes *****/
/* Standard C Libraries */
#include <stdlib.h>/* TI Drivers */
#include <ti/drivers/rf/RF.h>
#include <ti/drivers/GPIO.h>/* Driverlib Header files */
#include DeviceFamily_constructPath(driverlib/rf_prop_mailbox.h)/* Board Header files */
#include "ti_drivers_config.h"/* Application Header files */
#include "RFQueue.h"
#include <ti_radio_config.h>/***** Defines *****//* Packet RX Configuration */
#define MAX_LENGTH12 //(Number of bytes received when transmitting payload of 5 bytes)
#define DATA_ENTRY_HEADER_SIZE 8/* Constant header size of a Generic Data Entry */
#define NUM_DATA_ENTRIES2/* NOTE: Only two data entries supported at the moment */
#define NUM_APPENDED_BYTES0/***** Prototypes *****/
static void callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e);
static uint16_t culCalcCRC(uint8_t crcData, uint16_t crcReg);/***** Variable declarations *****/
static RF_Object rfObject;
static RF_Handle rfHandle;/* Buffer which contains all Data Entries for receiving data.* Pragmas are needed to make sure this buffer is 4 byte aligned (requirement from the RF Core) */
#if defined(__TI_COMPILER_VERSION__)
#pragma DATA_ALIGN (rxDataEntryBuffer, 4);
static uint8_t
rxDataEntryBuffer[RF_QUEUE_DATA_ENTRY_BUFFER_SIZE(NUM_DATA_ENTRIES,MAX_LENGTH,NUM_APPENDED_BYTES)];
#elif defined(__IAR_SYSTEMS_ICC__)
#pragma data_alignment = 4
static uint8_t
rxDataEntryBuffer[RF_QUEUE_DATA_ENTRY_BUFFER_SIZE(NUM_DATA_ENTRIES,MAX_LENGTH,NUM_APPENDED_BYTES)];
#elif defined(__GNUC__)
static uint8_t
rxDataEntryBuffer[RF_QUEUE_DATA_ENTRY_BUFFER_SIZE(NUM_DATA_ENTRIES,MAX_LENGTH,NUM_APPENDED_BYTES)]__attribute__((aligned(4)));
#else
#error This compiler is not supported.
#endif/* Receive dataQueue for RF Core to fill in data */
static dataQueue_t dataQueue;
static rfc_dataEntryGeneral_t* currentDataEntry;
static uint8_t* packetDataPointer;uint16_t fecDecode(uint8_t *pDecData, uint8_t* pInData, uint16_t RemBytes);
static uint8_t hammWeight(uint8_t a);
static uint8_t min(uint8_t a, uint8_t b);
static uint16_t calcCRC(uint8_t crcData, uint16_t crcReg);
uint8_t hammWeight(uint8_t a);
uint8_t min(uint8_t a, uint8_t b);static uint8_t packet[MAX_LENGTH];// The payload + CRC are 31 bytes. This way the complete packet to be received will fit in the RXFIFO
uint8_t rxBuffer[4]; // Buffer used to hold data read from the RXFIFO (4 bytes are read at a time)
uint8_t rxPacket[5]; // Data + CRC after being interleaved and decodeduint8_t aTrellisSourceStateLut[8][2] =
{{0, 4}, // State {0,4} -> State 0{0, 4}, // State {0,4} -> State 1{1, 5}, // State {1,5} -> State 2{1, 5}, // State {1,5} -> State 3{2, 6}, // State {2,6} -> State 4{2, 6}, // State {2,6} -> State 5{3, 7}, // State {3,7} -> State 6{3, 7}, // State {3,7} -> State 7
};uint8_t aTrellisTransitionOutput[8][2] =
{{0, 3}, // State {0,4} -> State 0 produces {"00", "11"}{3, 0}, // State {0,4} -> State 1 produces {"11", "00"}{1, 2}, // State {1,5} -> State 2 produces {"01", "10"}{2, 1}, // State {1,5} -> State 3 produces {"10", "01"}{3, 0}, // State {2,6} -> State 4 produces {"11", "00"}{0, 3}, // State {2,6} -> State 5 produces {"00", "11"}{2, 1}, // State {3,7} -> State 6 produces {"10", "01"}{1, 2}, // State {3,7} -> State 7 produces {"01", "10"}
};
// Look-up input bit at encoder when:
// Destination state
uint8_t aTrellisTransitionInput[8] =
{0,1,0,1,0,1,0,1,
};// NUMBER_OF_BYTES_AFTER_DECODING should be given the length of the payload + CRC (CRC is optional)
#define NUMBER_OF_BYTES_AFTER_DECODING 5
#define NUMBER_OF_BYTES_BEFORE_DECODING (4 * ((NUMBER_OF_BYTES_AFTER_DECODING / 2) + 1))/***** Function definitions *****/void *mainThread(void *arg0)
{RF_Params rfParams;RF_Params_init(&rfParams);GPIO_setConfig(CONFIG_GPIO_RLED, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);GPIO_write(CONFIG_GPIO_RLED, CONFIG_GPIO_LED_OFF);if( RFQueue_defineQueue(&dataQueue,rxDataEntryBuffer,sizeof(rxDataEntryBuffer),NUM_DATA_ENTRIES,MAX_LENGTH + NUM_APPENDED_BYTES)){/* Failed to allocate space for all data entries */while(1);}/* Modify CMD_PROP_RX command for application needs *//* Set the Data Entity queue for received data */RF_cmdPropRx.pQueue = &dataQueue;/* Discard ignored packets from Rx queue */RF_cmdPropRx.rxConf.bAutoFlushIgnored = 0;/* Discard packets with CRC error from Rx queue */RF_cmdPropRx.rxConf.bAutoFlushCrcErr = 0;RF_cmdPropRx.rxConf.bIncludeHdr = 0;RF_cmdPropRx.rxConf.bAppendStatus = 0;RF_cmdPropRx.maxPktLen = MAX_LENGTH;RF_cmdPropRx.pktConf.bUseCrc = 0;// Turn off CRCRF_cmdPropRx.pktConf.bVarLen = 0;// Use fixed packet length mode (length is manually FEC encodedRF_cmdPropRx.syncWord = 0xD391D391; // CC1101 compatible Sync word/* Request access to the radio */rfHandle = RF_open(&rfObject, &RF_prop, (RF_RadioSetup*)&RF_cmdPropRadioDivSetup, &rfParams);/* Set the frequency */RF_postCmd(rfHandle, (RF_Op*)&RF_cmdFs, RF_PriorityNormal, NULL, 0);while(1){RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropRx, RF_PriorityNormal, &callback, RF_EventRxEntryDone);{uint16_t nBytes;uint8_t *pDecData = rxPacket; // Destination for decoded datapDecData = rxPacket;// Perform de-interleaving and decoding (both done in the same function)fecDecode(NULL, NULL, 0); // The function needs to be called with a NULL pointer for// initialization before every packet to decodenBytes = NUMBER_OF_BYTES_AFTER_DECODING;uint8_t packetIndex = 0;while (nBytes > 0){uint16_t nBytesOut;memcpy(rxBuffer, &packet[packetIndex], 4);packetIndex += 4;nBytesOut = fecDecode(pDecData, rxBuffer, nBytes);nBytes -= nBytesOut;pDecData += nBytesOut;}}}
}void callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e)
{if (e & RF_EventRxEntryDone){GPIO_toggle(CONFIG_GPIO_RLED);/* Get current unhandled data entry */currentDataEntry = RFQueue_getDataEntry();packetDataPointer = (uint8_t*)(&currentDataEntry->data);/* Copy the payload + the status byte to the packet variable */memcpy(packet, packetDataPointer, MAX_LENGTH);RFQueue_nextEntry();}
}uint16_t culCalcCRC(uint8_t crcData, uint16_t crcReg) {uint8_t i;for (i = 0; i < 8; i++){if (((crcReg & 0x8000) >> 8) ^ (crcData & 0x80)){crcReg = (crcReg << 1) ^ 0x8005;}else{crcReg = (crcReg << 1);}crcData <<= 1;}return crcReg;
}uint8_t hammWeight(uint8_t a)
{a = ((a & 0xAA) >> 1) + (a & 0x55);a = ((a & 0xCC) >> 2) + (a & 0x33);a = ((a & 0xF0) >> 4) + (a & 0x0F);return a;
}uint8_t min(uint8_t a, uint8_t b)
{return (a <= b ? a : b);
}uint16_t fecDecode(uint8_t *pDecData, uint8_t* pInData, uint16_t nRemBytes)
{// Two sets of buffers (last, current) for each destination state for holding:static uint8_t nCost[2][8]; // Accumulated path coststatic uint32_t aPath[2][8]; // Encoder input data (32b window)// Indices of (last, current) buffer for each iterationstatic uint8_t iLastBuf;static uint8_t iCurrBuf;// Number of bits in each path bufferstatic uint8_t nPathBits;// Variables used to hold # Viterbi iterations to run, # bytes output,// minimum cost for any destination state, bit index of input symboluint8_t nIterations;uint16_t nOutputBytes = 0;uint8_t nMinCost;int8_t iBit = 8 - 2;// Initialize variables at start of packet (and return without doing any more)if (pDecData == NULL){uint8_t n ;memset(nCost, 0, sizeof(nCost));for (n = 1; n < 8; n++){nCost[0][n] = 100;}iLastBuf = 0;iCurrBuf = 1;nPathBits = 0;return 0;}{uint8_t aDeintData[4];int8_t iOut;int8_t iIn;// De-interleave received data (and change pInData to point to de-interleaved data)for (iOut = 0; iOut < 4; iOut++){uint8_t dataByte = 0;for (iIn = 3; iIn >= 0; iIn--){dataByte = (dataByte << 2) | ((pInData[iIn] >>( 2 * iOut)) & 0x03);}aDeintData[iOut] = dataByte;}pInData = aDeintData;}// Process up to 4 bytes of de-interleaved input data, processing one encoder symbol (2b) at a timefor (nIterations = 16; nIterations > 0; nIterations--){uint8_t iDestState;uint8_t symbol = ((*pInData) >> iBit) & 0x03;// Find minimum cost so that we can normalize costs (only last iteration used)nMinCost = 0xFF;// Get 2b input symbol (MSB first) and do one iteration of Viterbi decodingif ((iBit -= 2) < 0){iBit = 6;pInData++; // Update pointer to the next byte of received data}// For each destination state in the trellis, calculate hamming costs for both possible paths into state and// select the one with lowest cost.for (iDestState = 0; iDestState < 8; iDestState++){uint8_t nCost0;uint8_t nCost1;uint8_t iSrcState0;uint8_t iSrcState1;uint8_t nInputBit;nInputBit = aTrellisTransitionInput[iDestState];// Calculate cost of transition from each of the two source states (cost is Hamming difference between// received 2b symbol and expected symbol for transition)iSrcState0 = aTrellisSourceStateLut[iDestState][0];nCost0 = nCost[iLastBuf][iSrcState0];nCost0 += hammWeight(symbol ^ aTrellisTransitionOutput[iDestState][0]);iSrcState1 = aTrellisSourceStateLut[iDestState][1];nCost1 = nCost[iLastBuf][iSrcState1];nCost1 += hammWeight(symbol ^ aTrellisTransitionOutput[iDestState][1]);// Select transition that gives lowest cost in destination state, copy that source state's path and add// new decoded bitif (nCost0 <= nCost1){nCost[iCurrBuf][iDestState] = nCost0;nMinCost = min(nMinCost, nCost0);aPath[iCurrBuf][iDestState] = (aPath[iLastBuf][iSrcState0] << 1) | nInputBit;}else{nCost[iCurrBuf][iDestState] = nCost1;nMinCost = min(nMinCost, nCost1);aPath[iCurrBuf][iDestState] = (aPath[iLastBuf][iSrcState1] << 1) | nInputBit;}}nPathBits++;// If trellis history is sufficiently long, output a byte of decoded dataif (nPathBits == 32){*pDecData++ = (aPath[iCurrBuf][0] >> 24) & 0xFF;nOutputBytes++;nPathBits -= 8;nRemBytes--;}// After having processed 3-symbol trellis terminator, flush out remaining dataif ((nRemBytes <= 3) && (nPathBits == ((8 * nRemBytes) + 3))){while (nPathBits >= 8){*pDecData++ = (aPath[iCurrBuf][0] >> (nPathBits - 8)) & 0xFF;nOutputBytes++;nPathBits -= 8;}return nOutputBytes;}// Swap current and last buffers for next iterationiLastBuf = (iLastBuf + 1) % 2;iCurrBuf = (iCurrBuf + 1) % 2;}// Normalize costs so that minimum cost becomes 0{unsigned char iState;for (iState = 0; iState < 8; iState++){nCost[iLastBuf][iState] -= nMinCost;}}return nOutputBytes;}

,

Gilbert DQ:

您好,

      我按照您提供的代码在CC1352P上运行了一下fecDecode,得到的结果依然是:0x01 0x02 0x73 0x04 0x05,与期望值不符。

      在程序中,我修改了两个地方:

      1. 屏蔽了RF_runCmd();

      2. 将数组packet的初始值强制设为:0x4C, 0xF0, 0x30, 0x10, 0xC8, 0x7C, 0xC3, 0x23, 0x40, 0x34, 0x7C, 0xE3;

      我的调试结果如下图:

     

     我的源代码如下:

      

/***** Includes *****/
/* Standard C Libraries */
#include <stdlib.h>/* TI Drivers */
#include <ti/drivers/rf/RF.h>
#include <ti/drivers/GPIO.h>/* Driverlib Header files */
#include DeviceFamily_constructPath(driverlib/rf_prop_mailbox.h)/* Application Header files */
#include "RFQueue.h"
#include "smartrf_settings/smartrf_settings.h"/***** Defines *****//* Packet RX Configuration */
#define MAX_LENGTH12 //(Number of bytes received when transmitting payload of 5 bytes)
#define DATA_ENTRY_HEADER_SIZE 8/* Constant header size of a Generic Data Entry */
#define NUM_DATA_ENTRIES2/* NOTE: Only two data entries supported at the moment */
#define NUM_APPENDED_BYTES0/***** Prototypes *****/
static void callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e);
static uint16_t culCalcCRC(uint8_t crcData, uint16_t crcReg);/***** Variable declarations *****/
static RF_Object rfObject;
static RF_Handle rfHandle;/* Buffer which contains all Data Entries for receiving data.* Pragmas are needed to make sure this buffer is 4 byte aligned (requirement from the RF Core) */
#if defined(__TI_COMPILER_VERSION__)
#pragma DATA_ALIGN (rxDataEntryBuffer, 4);
static uint8_t rxDataEntryBuffer[RF_QUEUE_DATA_ENTRY_BUFFER_SIZE(NUM_DATA_ENTRIES, MAX_LENGTH, NUM_APPENDED_BYTES)];
#elif defined(__IAR_SYSTEMS_ICC__)
#pragma data_alignment = 4
static uint8_t
rxDataEntryBuffer[RF_QUEUE_DATA_ENTRY_BUFFER_SIZE(NUM_DATA_ENTRIES,MAX_LENGTH,NUM_APPENDED_BYTES)];
#elif defined(__GNUC__)
static uint8_t
rxDataEntryBuffer[RF_QUEUE_DATA_ENTRY_BUFFER_SIZE(NUM_DATA_ENTRIES,MAX_LENGTH,NUM_APPENDED_BYTES)]
__attribute__((aligned(4)));
#else
#error This compiler is not supported.
#endif/* Receive dataQueue for RF Core to fill in data */
static dataQueue_t dataQueue;
static rfc_dataEntryGeneral_t* currentDataEntry;
static uint8_t* packetDataPointer;uint16_t fecDecode(uint8_t *pDecData, uint8_t* pInData, uint16_t RemBytes);
static uint8_t hammWeight(uint8_t a);
static uint8_t min(uint8_t a, uint8_t b);
static uint16_t calcCRC(uint8_t crcData, uint16_t crcReg);
uint8_t hammWeight(uint8_t a);
uint8_t min(uint8_t a, uint8_t b);static uint8_t packet[MAX_LENGTH] = { 0x4C, 0xF0, 0x30, 0x10, //0xC8, 0x7C, 0xC3, 0x23, //0x40, 0x34, 0x7C, 0xE3, //};// The payload + CRC are 31 bytes. This way the complete packet to be received will fit in the RXFIFO
uint8_t rxBuffer[4]; // Buffer used to hold data read from the RXFIFO (4 bytes are read at a time)
uint8_t rxPacket[5]; // Data + CRC after being interleaved and decodeduint8_t aTrellisSourceStateLut[8][2] = { { 0, 4 }, // State {0,4} -> State 0{ 0, 4 }, // State {0,4} -> State 1{ 1, 5 }, // State {1,5} -> State 2{ 1, 5 }, // State {1,5} -> State 3{ 2, 6 }, // State {2,6} -> State 4{ 2, 6 }, // State {2,6} -> State 5{ 3, 7 }, // State {3,7} -> State 6{ 3, 7 }, // State {3,7} -> State 7};uint8_t aTrellisTransitionOutput[8][2] = { { 0, 3 }, // State {0,4} -> State 0 produces {"00", "11"}{ 3, 0 }, // State {0,4} -> State 1 produces {"11", "00"}{ 1, 2 }, // State {1,5} -> State 2 produces {"01", "10"}{ 2, 1 }, // State {1,5} -> State 3 produces {"10", "01"}{ 3, 0 }, // State {2,6} -> State 4 produces {"11", "00"}{ 0, 3 }, // State {2,6} -> State 5 produces {"00", "11"}{ 2, 1 }, // State {3,7} -> State 6 produces {"10", "01"}{ 1, 2 }, // State {3,7} -> State 7 produces {"01", "10"}};
// Look-up input bit at encoder when:
// Destination state
uint8_t aTrellisTransitionInput[8] = { 0, 1, 0, 1, 0, 1, 0, 1, };// NUMBER_OF_BYTES_AFTER_DECODING should be given the length of the payload + CRC (CRC is optional)
#define NUMBER_OF_BYTES_AFTER_DECODING 5
#define NUMBER_OF_BYTES_BEFORE_DECODING (4 * ((NUMBER_OF_BYTES_AFTER_DECODING / 2) + 1))/***** Function definitions *****/void *mainThread(void *arg0)
{RF_Params rfParams;RF_Params_init(&rfParams);if (RFQueue_defineQueue(&dataQueue, rxDataEntryBuffer,sizeof(rxDataEntryBuffer),NUM_DATA_ENTRIES,MAX_LENGTH + NUM_APPENDED_BYTES)){/* Failed to allocate space for all data entries */while (1);}/* Modify CMD_PROP_RX command for application needs *//* Set the Data Entity queue for received data */RF_cmdPropRx.pQueue = &dataQueue;/* Discard ignored packets from Rx queue */RF_cmdPropRx.rxConf.bAutoFlushIgnored = 0;/* Discard packets with CRC error from Rx queue */RF_cmdPropRx.rxConf.bAutoFlushCrcErr = 0;RF_cmdPropRx.rxConf.bIncludeHdr = 0;RF_cmdPropRx.rxConf.bAppendStatus = 0;RF_cmdPropRx.maxPktLen = MAX_LENGTH;RF_cmdPropRx.pktConf.bUseCrc = 0;// Turn off CRCRF_cmdPropRx.pktConf.bVarLen = 0; // Use fixed packet length mode (length is manually FEC encodedRF_cmdPropRx.syncWord = 0xD391D391; // CC1101 compatible Sync word/* Request access to the radio */rfHandle = RF_open(&rfObject, &RF_prop,(RF_RadioSetup*) &RF_cmdPropRadioDivSetup, &rfParams);/* Set the frequency */RF_postCmd(rfHandle, (RF_Op*) &RF_cmdFs, RF_PriorityNormal, NULL, 0);while (1){
//RF_runCmd(rfHandle, (RF_Op*) &RF_cmdPropRx, RF_PriorityNormal,
//&callback, RF_EventRxEntryDone);{uint16_t nBytes;uint8_t *pDecData = rxPacket; // Destination for decoded datapDecData = rxPacket;// Perform de-interleaving and decoding (both done in the same function)fecDecode(NULL, NULL, 0); // The function needs to be called with a NULL pointer for// initialization before every packet to decodenBytes = NUMBER_OF_BYTES_AFTER_DECODING;uint8_t packetIndex = 0;while (nBytes > 0){uint16_t nBytesOut;memcpy(rxBuffer, &packet[packetIndex], 4);packetIndex += 4;nBytesOut = fecDecode(pDecData, rxBuffer, nBytes);nBytes -= nBytesOut;pDecData += nBytesOut;}}}
}void callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e)
{if (e & RF_EventRxEntryDone){/* Get current unhandled data entry */currentDataEntry = RFQueue_getDataEntry();packetDataPointer = (uint8_t*) (&currentDataEntry->data);/* Copy the payload + the status byte to the packet variable */memcpy(packet, packetDataPointer, MAX_LENGTH);RFQueue_nextEntry();}
}uint16_t culCalcCRC(uint8_t crcData, uint16_t crcReg)
{uint8_t i;for (i = 0; i < 8; i++){if (((crcReg & 0x8000) >> 8) ^ (crcData & 0x80)){crcReg = (crcReg << 1) ^ 0x8005;}else{crcReg = (crcReg << 1);}crcData <<= 1;}return crcReg;
}uint8_t hammWeight(uint8_t a)
{a = ((a & 0xAA) >> 1) + (a & 0x55);a = ((a & 0xCC) >> 2) + (a & 0x33);a = ((a & 0xF0) >> 4) + (a & 0x0F);return a;
}uint8_t min(uint8_t a, uint8_t b)
{return (a <= b ? a : b);
}uint16_t fecDecode(uint8_t *pDecData, uint8_t* pInData, uint16_t nRemBytes)
{// Two sets of buffers (last, current) for each destination state for holding:static uint8_t nCost[2][8]; // Accumulated path coststatic uint32_t aPath[2][8]; // Encoder input data (32b window)// Indices of (last, current) buffer for each iterationstatic uint8_t iLastBuf;static uint8_t iCurrBuf;// Number of bits in each path bufferstatic uint8_t nPathBits;// Variables used to hold # Viterbi iterations to run, # bytes output,// minimum cost for any destination state, bit index of input symboluint8_t nIterations;uint16_t nOutputBytes = 0;uint8_t nMinCost;int8_t iBit = 8 - 2;// Initialize variables at start of packet (and return without doing any more)if (pDecData == NULL){uint8_t n;memset(nCost, 0, sizeof(nCost));for (n = 1; n < 8; n++){nCost[0][n] = 100;}iLastBuf = 0;iCurrBuf = 1;nPathBits = 0;return 0;}{uint8_t aDeintData[4];int8_t iOut;int8_t iIn;// De-interleave received data (and change pInData to point to de-interleaved data)for (iOut = 0; iOut < 4; iOut++){uint8_t dataByte = 0;for (iIn = 3; iIn >= 0; iIn--){dataByte = (dataByte << 2)| ((pInData[iIn] >> (2 * iOut)) & 0x03);}aDeintData[iOut] = dataByte;}pInData = aDeintData;}// Process up to 4 bytes of de-interleaved input data, processing one encoder symbol (2b) at a timefor (nIterations = 16; nIterations > 0; nIterations--){uint8_t iDestState;uint8_t symbol = ((*pInData) >> iBit) & 0x03;// Find minimum cost so that we can normalize costs (only last iteration used)nMinCost = 0xFF;// Get 2b input symbol (MSB first) and do one iteration of Viterbi decodingif ((iBit -= 2) < 0){iBit = 6;pInData++; // Update pointer to the next byte of received data}// For each destination state in the trellis, calculate hamming costs for both possible paths into state and// select the one with lowest cost.for (iDestState = 0; iDestState < 8; iDestState++){uint8_t nCost0;uint8_t nCost1;uint8_t iSrcState0;uint8_t iSrcState1;uint8_t nInputBit;nInputBit = aTrellisTransitionInput[iDestState];// Calculate cost of transition from each of the two source states (cost is Hamming difference between// received 2b symbol and expected symbol for transition)iSrcState0 = aTrellisSourceStateLut[iDestState][0];nCost0 = nCost[iLastBuf][iSrcState0];nCost0 += hammWeight(symbol ^ aTrellisTransitionOutput[iDestState][0]);iSrcState1 = aTrellisSourceStateLut[iDestState][1];nCost1 = nCost[iLastBuf][iSrcState1];nCost1 += hammWeight(symbol ^ aTrellisTransitionOutput[iDestState][1]);// Select transition that gives lowest cost in destination state, copy that source state's path and add// new decoded bitif (nCost0 <= nCost1){nCost[iCurrBuf][iDestState] = nCost0;nMinCost = min(nMinCost, nCost0);aPath[iCurrBuf][iDestState] = (aPath[iLastBuf][iSrcState0] << 1)| nInputBit;}else{nCost[iCurrBuf][iDestState] = nCost1;nMinCost = min(nMinCost, nCost1);aPath[iCurrBuf][iDestState] = (aPath[iLastBuf][iSrcState1] << 1)| nInputBit;}}nPathBits++;// If trellis history is sufficiently long, output a byte of decoded dataif (nPathBits == 32){*pDecData++ = (aPath[iCurrBuf][0] >> 24) & 0xFF;nOutputBytes++;nPathBits -= 8;nRemBytes--;}// After having processed 3-symbol trellis terminator, flush out remaining dataif ((nRemBytes <= 3) && (nPathBits == ((8 * nRemBytes) + 3))){while (nPathBits >= 8){*pDecData++ = (aPath[iCurrBuf][0] >> (nPathBits - 8)) & 0xFF;nOutputBytes++;nPathBits -= 8;}return nOutputBytes;}// Swap current and last buffers for next iterationiLastBuf = (iLastBuf + 1) % 2;iCurrBuf = (iCurrBuf + 1) % 2;}// Normalize costs so that minimum cost becomes 0{unsigned char iState;for (iState = 0; iState < 8; iState++){nCost[iLastBuf][iState] -= nMinCost;}}return nOutputBytes;
}

,

Gilbert DQ:

我的开发环境:

​    1. Code Composer Studio Version: 9.2.0.00013     2. SimpleLink CC13x2 26×2 SDK 3.20.0.68    3. Compiler version: TI v18.12.3.LTS

,

Gilbert DQ:

同样的代码,将其移植到MSP432P411R上运行,得到的结果就是:0x01 0x02 0x03 0x04 0x05。

这是什么原因造成的?project properties的配置问题吗?

,

Cherry Zhou:

我们跟进给英文论坛的工程师看下哈。

,

Cherry Zhou:

您好,

应该是与您使用什么工具相关。

工程师给出的working example中使用的是 TI Clang v2.0.STS (CCS 11.20和 SDK 版本6.20)

工程师也试了使用 CCS 9.3和 TI v18.12.8.LTS 进行测试,得到的结果与您相同。

我们会再请求下CCS 团队的帮助,有新的进展尽快给到您。

,

Gilbert DQ:

您好,这个问题有新的进展吗?另外,麻烦分享一下该问题的英文论坛帖子的链接。

,

Cherry Zhou:

您好,

您的问题并没有解决吗?因为看到您点击了“认为已解决”?

您可以在英文论坛看下:

e2e.ti.com/…/cc1352p-dn507-fec-decoding-results-are-inconsistent-with-the-code-dn504-fec-implementation

,

Gilbert DQ:

您好,

这个问题还没解决,在SimpleLink CC13x2 26×2 SDK 和 Compiler version: TI v18.12.3.LTS 上依然是存在这个问题的。

我的诉求有两个:1. 在当前开发环境(CCS、 SDK、 Compiler )下,能否解决这个问题?如果能,该怎么做?2. 如果在当前开发环境(CCS、 SDK、 Compiler )下,无法解决这个问题,请高祖我什么版本的开发环境,不会出现这个问题。MCU必须是CC1352P。

谢谢!

,

Cherry Zhou:

我们跟进给工程师了,您可以多关注英文论坛的答复。

,

Cherry Zhou:

抱歉我们的工程师这边也并不太清楚此问题的根本原因,但正如之前给您的答复,工程师这边使用最新的SDK (6.20) 和 TI Clang v2.0.0.STS (CCS 11.20) 进行了测试,是没有任何问题的。

赞(0)
未经允许不得转载:TI中文支持网 » CC1352P: DN507 FEC Decoding 解码结果与编码(DN504 FEC Implementation)不一致
分享到: 更多 (0)

© 2024 TI中文支持网   网站地图 鲁ICP备2022002796号-1