回复
Highlighted
发帖数: 7
注册日期: ‎09-21-2017

SI4463使用802.15.4工程发送数据包时产生CRC错误中断

(1).使用官方提供的WDS配置的radio_config.h文件,在频率为433MHz,2GFSK模式下,Data rate为50Kbps,Deviation为25KHz,使用alt crc(IEEE 16bit)做校验情况下,发送3字节数据,数据是对的,也能读取回来,但是总提示ALT_CRC_ERROR;

(2).在同样频率设置的情况,如果使用primary crc(IEEE 32bit)做校验的情况下,发送3字节数据,则不会产生接收完成中断,也看不到具体数据,而且提示CRC_ERROR;

(3).如果将上面的频率改为433MHz,2GFSK模式下,Data rate为4.8Kbps,Deviation为2.4KHz,使用alt crc(IEEE 16bit)做校验情况下,发送3字节数据,则数据可以正常接收发送,不会产生任何错误;

(4).如果在433MHz,2GFSK模式下,Data rate为4.8Kbps,Deviation为2.4KHz,使用primary crc(IEEE 32bit)做校验情况下,发送3字节数据,则又会提示CRC_ERROR,不会出发接收完成中断。

 

各位常用si446x系列芯片的大神们,有谁遇到过这种CRC出错的情况吗?这是什么情况?

发帖数: 101
注册日期: ‎12-02-2016

回复: SI4463使用802.15.4工程发送数据包时产生CRC错误中断

Hi,

1. 请问你们使用的si4463是哪个版本的?

2. 是否有对硬件性能做过测试? 比如 发射功率、接收灵敏度、频率误差等。

3. 是否有测试其他包长时的CRC情况?

4. 测试环境中是否存在较多同频干扰?

 

如果方便,请发一下测试代码以及相应的XML配置文件,以便在我们EVB板上对其做一下测试。

 

Regards,

Yongsheng

发帖数: 7
注册日期: ‎09-21-2017

回复: SI4463使用802.15.4工程发送数据包时产生CRC错误中断

你好,

(1)我们使用的SI4463的芯片版本为C2版,配置软件版本为3.2.11.0

(2)对于硬件测试,我们没有专门的设备,本想调试好程序在修改硬件的发射功率等设置,所以还没做;

(3)对于其他包长都会产生CRC或ALT_CRC错误;

(4)测试环境中不存在其他干扰源;

(5)关于具体设置:以下是相应的设置截图,具体设置请看附件中的xml文件:

 

捕获.JPG

捕获1.JPG

捕获3.JPG

捕获2.JPG

捕获4.JPG

 

 

 

 

发帖数: 7
注册日期: ‎09-21-2017

回复: SI4463使用802.15.4工程发送数据包时产生CRC错误中断

对于代码:这是我们发送和接收部分函数的代码:

/*!
* File:
* radio_hal.c
*
* Description:
* This file contains RADIO HAL.
*
* Silicon Laboratories Confidential
* Copyright 2011 Silicon Laboratories, Inc.
* SI446x revC2A Command/Property API Documentation: http://dvit.as.kz/manuals/EZRadioPRO_REVC2/Si4463/revC2A/index_all.html
*/

/* ======================================= *
* I N C L U D E *
* ======================================= */
#define LOG_TAG "si4463_radio"

#include <elog.h>
#include "radio_hal.h"
#include <stdbool.h>
#include <rtthread.h>
#include <spi.h>

#define RADIO_SPI_DEV_NAME "spi30"
#define RADIO_DEFAULT_SPI_CFG \
{ \
.mode = RT_SPI_MODE_0 | RT_SPI_MSB, \
.data_width = 8, \
.max_hz = 50 * 1000 * 1000, \
}
#define RSSI_UNKNOWN -128

/* ======================================= *
* D E F I N I T I O N S *
* ======================================= */

/* ======================================= *
* G L O B A L V A R I A B L E S *
* ======================================= */

SEGMENT_VARIABLE(Radio_Configuration_Data_Array[], U8, SEG_CODE) = RADIO_CONFIGURATION_DATA_ARRAY;
const SEGMENT_VARIABLE(RadioConfiguration, tRadioConfiguration, SEG_CODE) = RADIO_CONFIGURATION_DATA;
const SEGMENT_VARIABLE_SEGMENT_POINTER(pRadioConfiguration, tRadioConfiguration, SEG_CODE, SEG_CODE) = &RadioConfiguration;

/* ======================================= *
* L O C A L F U N C T I O N S *
* ======================================= */

/* ======================================= *
* P U B L I C F U N C T I O N S *
* ======================================= */
/* 初始化SPI设备对象 */
static struct rt_spi_device *radio_spi_device;

static void radio_power_up(void) {
// SEGMENT_VARIABLE(wDelay, U16, SEG_XDATA) = 0u;

/* Hardware reset the chip */
si446x_reset();

/* Wait until reset timeout or Reset IT signal */
rt_thread_delay(rt_tick_from_millisecond(1000));
// for (; wDelay < pRadioConfiguration->Radio_Delay_Cnt_After_Reset; wDelay++);
}
uint8_t pkt_config1_for_rx = 0;

//TODO 待完善,如何降低每次错误中断后启动接收的代码量
void radio_start_rx(uint8_t channel, uint8_t packet_lenght) {
// Read ITs, clear pending ones
si446x_get_int_status(0u, 0u, 0u);

// Reset the Rx Fifo
si446x_fifo_info(SI446X_CMD_FIFO_INFO_ARG_FIFO_RX_BIT);

/* Start Receiving packet, channel 0, START immediately, Packet length used or not according to packetLength */
si446x_start_rx(channel, 0u, packet_lenght, SI446X_CMD_START_RX_ARG_NEXT_STATE1_RXTIMEOUT_STATE_ENUM_NOCHANGE,
SI446X_CMD_START_RX_ARG_NEXT_STATE2_RXVALID_STATE_ENUM_READY,
SI446X_CMD_START_RX_ARG_NEXT_STATE3_RXINVALID_STATE_ENUM_RX);
}

/*!
* Set Radio to TX mode, variable packet length.
* Use it when multiple fields are in use (START_TX is called with 0 length).
*
* @param channel Freq. Channel, Packet to be sent length of of the packet sent to TXFIFO
*
* @note
*
*/
void radio_start_tx_variable_packet_multifield(uint8_t channel, uint8_t *radio_packet, uint8_t length) {
/* Read ITs, clear pending ones */
si446x_get_int_status_fast_clear();

/* Reset the Tx Fifo */
si446x_fifo_info_fast_reset(SI446X_CMD_FIFO_INFO_ARG_FIFO_TX_BIT);

/* Fill the TX fifo with datas */
si446x_write_tx_fifo(length, radio_packet);

/* Start sending packet, channel 0, START immediately, stay TX status when send finish */
si446x_start_tx(channel, 0x70, 0);
}

/*!
* Set Radio to TX mode, variable packet length.
*
* @param channel Freq. Channel, Packet to be sent length of of the packet sent to TXFIFO
*
* @note
*
*/
void radio_start_tx_variable_packet(uint8_t channel, uint8_t *radio_packet, uint8_t length) {
/* Leave RX state */
si446x_change_state(SI446X_CMD_CHANGE_STATE_ARG_NEXT_STATE1_NEW_STATE_ENUM_READY);

/* Read ITs, clear pending ones */
si446x_get_int_status(0u, 0u, 0u);

/* Reset the Tx Fifo */
si446x_fifo_info(SI446X_CMD_FIFO_INFO_ARG_FIFO_TX_BIT);

/* Fill the TX fifo with datas */
si446x_write_tx_fifo(length, radio_packet);

/* Start sending packet, channel 0, START immediately */
si446x_start_tx(channel, 0x80, length);

}

void radio_hal_init(void) {
radio_spi_device = (struct rt_spi_device *) rt_device_find(RADIO_SPI_DEV_NAME);
if (radio_spi_device == RT_NULL || radio_spi_device->parent.type != RT_Device_Class_SPIDevice) {
log_e("ERROR: SPI device %s not found!\n", RADIO_SPI_DEV_NAME);
assert(0);
}
struct rt_spi_configuration cfg = RADIO_DEFAULT_SPI_CFG;
rt_spi_configure(radio_spi_device, &cfg);
/* Power Up the radio chip */
radio_power_up();

/* Load radio configuration */
if (SI446X_SUCCESS != si446x_configuration_init(pRadioConfiguration->Radio_ConfigurationArray)) {
// /* Power Up the radio chip */
// radio_power_up();
log_e("SI4463_radio init failed ");
} else {
log_d("SI4463_radio init success ");
}
si446x_part_info();
log_d("si446x chip revision: %d, part id: %x, rom id: %d", Si446xCmd.PART_INFO.CHIPREV, Si446xCmd.PART_INFO.PART, Si446xCmd.PART_INFO.ROMID);

// Configure PH field split, CRC endian, bit order for RX
pkt_config1_for_rx = SI446X_PROP_PKT_CONFIG1_PH_FIELD_SPLIT_BIT /*| SI446X_PROP_PKT_CONFIG1_CRC_INVERT_BIT*/
| SI446X_PROP_PKT_CONFIG1_CRC_ENDIAN_BIT /*| SI446X_PROP_PKT_CONFIG1_BIT_ORDER_BIT*/;
// Configure PKT_CONFIG1 for RX
si446x_set_property(SI446X_PROP_GRP_ID_PKT, 1, SI446X_PROP_GRP_INDEX_PKT_CONFIG1, pkt_config1_for_rx);
// Start RX with Packet handler settings
radio_start_rx(pRadioConfiguration->Radio_ChannelNumber,0u);

// Read ITs, clear pending ones
si446x_get_int_status(0u, 0u, 0u);

}

void radio_software_init(void) {
radio_transmit_software_init();
}

extern void si446x_sdn_enabled(bool enabled);

void radio_hal_AssertShutdown(void)
{
si446x_sdn_enabled(false);
}

void radio_hal_DeassertShutdown(void)
{
si446x_sdn_enabled(true);
}

void radio_hal_ClearNsel(void)
{
// RF_NSEL = 0;
}

void radio_hal_SetNsel(void)
{
// RF_NSEL = 1;
}

bool si446x_irq_pin_state(void);
BIT radio_hal_NirqLevel(void)
{
return si446x_irq_pin_state();
}

void radio_hal_SpiWriteThenRead(U8 byteSend, U8* pSendData, U8 byteRecv, U8* pRecvData)
{
rt_spi_send_then_recv(radio_spi_device, pSendData, byteSend, pRecvData, byteRecv);
}

void radio_hal_SpiWriteThenWrite(U8 sendByte1, U8* pSendData1, U8 sendByte2, U8* pSendData2)
{
rt_spi_send_then_send(radio_spi_device, pSendData1, sendByte1, pSendData2, sendByte2);
}

void radio_hal_SpiWriteData(U8 byteCount, U8* pData)
{
rt_spi_send(radio_spi_device, pData, byteCount);
}

void radio_hal_SpiReadData(U8 byteCount, U8* pData)
{
rt_spi_recv(radio_spi_device, pData, byteCount);
}

U8 radio_find_property(U8* pbArray, U8 bGroup, U8 bAddress, U8* pbValue) {
U16 wInd = 0;
U8 bPropertyValue = 0x00;
BIT gPropertyFound = FALSE;

// Input validation
if (pbArray == NULL) {
return FALSE;
}

// Search until reaching the terminating 0
while (pbArray[wInd] != 0) {
// Looking for SET_PROPERTY = 0x11 command
if (pbArray[wInd + 1] != 0x11) {
wInd += pbArray[wInd] + 1;
continue;
}

// It is a SET_PROPERTY command, check if the corresponding row makes sense (i.e. the array is not broken)
if (pbArray[wInd] < 0x05 || pbArray[wInd] > 0x10
|| pbArray[wInd] != (pbArray[wInd + 3] + 4)) // Command length in line with API length
{
return FALSE;
}

// Look for property value
if (pbArray[wInd + 2] == bGroup) {
if ((pbArray[wInd + 4] <= bAddress)
&& (bAddress < pbArray[wInd + 3] + pbArray[wInd + 4])) {
bPropertyValue = pbArray[wInd + 5 + (bAddress - pbArray[wInd + 4])];
gPropertyFound = TRUE;
// Don't break the loop here, check the rest of the array
}
}
wInd += pbArray[wInd] + 1;
}

if (gPropertyFound) {
*pbValue = bPropertyValue;
}
return gPropertyFound;
}

void radio_comm_err_cb(void) {
static bool has_err = false;
if (!has_err) {
log_e("si446x radio commicate error");
has_err = true;
}
rt_thread_delay(rt_tick_from_millisecond(100));
}

static int calc_rssi_from_modem_status(uint8_t status) {
return status / 2 - 0x40 - 70;
}

/**
* 获取当前的信号强度,单位:dBm
*/
int radio_get_cur_rssi(void) {
si446x_get_modem_status(SI446X_CMD_GET_MODEM_STATUS_ARG_MODEM_CLR_PEND_RSSI_PEND_CLR_BIT);

// log_d("cur rssi: %d, latch rssi %d, ant1: %d, ant2: %d", Si446xCmd.GET_MODEM_STATUS.CURR_RSSI,
// Si446xCmd.GET_MODEM_STATUS.LATCH_RSSI, Si446xCmd.GET_MODEM_STATUS.ANT1_RSSI,
// Si446xCmd.GET_MODEM_STATUS.ANT1_RSSI);

if (Si446xCmd.GET_MODEM_STATUS.CURR_RSSI != 0) {
return calc_rssi_from_modem_status(Si446xCmd.GET_MODEM_STATUS.CURR_RSSI);
} else {
return RSSI_UNKNOWN;
}
}

/**
* 获取上次接收数据时的信号强度,单位:dBm
*/
int radio_get_latch_rssi(void) {
static int rssi = 0;

si446x_get_modem_status(SI446X_CMD_GET_MODEM_STATUS_ARG_MODEM_CLR_PEND_RSSI_PEND_CLR_BIT);
if (Si446xCmd.GET_MODEM_STATUS.LATCH_RSSI != 0) {
rssi = calc_rssi_from_modem_status(Si446xCmd.GET_MODEM_STATUS.LATCH_RSSI);
}
return rssi;
}

发帖数: 7
注册日期: ‎09-21-2017

回复: SI4463使用802.15.4工程发送数据包时产生CRC错误中断

抱歉,贴上去的代码是在不好查看,您可以看我附件中的c文件