2025-08-29 1:27 PM
I have a SPIRIT1 DK_2.2.1 dev kit, with two motherboards and two STEVAL-IKR002V3D transciever boards with EEPROM.
When I run two of the SPIRIT1 DK - Application v2.2.1 (one per motherboard) and set one for TX and the other for RX with default settings in BASIC packet format the Rx sees the Tx as expected.
When I take the STEVAL-IKR002V3D and attach it to a test setup using a Nucleo-F429ZI board, running FreeRTOS, using STM32CubeIDE HAL, and a port of (SPIRIT1 DK_2.2.1/Projects/Drivers/BSP/Components/Spirit1/SPIRIT1_Library and SPIRIT1 DK_2.2.1/Projects/Projects_Cube/Spirit1Library_Examples/Src/BasicGeneric/SDK_BasicGeneric_B.c, the SPIRIT1 sees the EEPROM, completes initialization and sits in the while(1) loop with a state: MC_STATE: 0 0x07, 1 0x02 (READY, XO_ON, RX_FIFO_EMPTY)
Only a single interrupt is received, with xIrqStatus 000D0500.
If I use the SPIRIT1 DK - Application's TX to send messages, the Nucleo SPIRIT1 does not appear to see the messages, remaining in the above mentioned state. SpiritLinearFifoReadNumElementsRxFifo() returns 0.
Below are the initialization code as well as the DK Application's TX, RX and Nucleo RX register dumps:
Nucleo-F429ZI code:
static void MX_SPI1_Init(void)
{
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 7;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
Error_Handler();
}
}
static void SPIRIT_Task(void *pvParameters)
{
osDelay(3000); //XXX
HAL_GPIO_WritePin(SPIRIT1_RST_GPIO_Port, SPIRIT1_RST_Pin, GPIO_PIN_RESET); // release SPIRIT1 from reset
osDelay(10); // sleep 10 milliseconds (to allow Spirit1 a proper boot-up sequence)
SpiritManagementWaExtraCurrent();
SpiritManagementIdentificationRFBoard();
SRadioInit xRadioInit = {
XTAL_OFFSET_PPM,
BASE_FREQUENCY,
CHANNEL_SPACE,
CHANNEL_NUMBER,
MODULATION_SELECT,
DATARATE,
FREQ_DEVIATION,
BANDWIDTH
};
/* if the board has eeprom, we can compensate the offset calling SpiritManagementGetOffset
(if eeprom is not present this fcn will return 0) */
xRadioInit.lFrequencyBase = xRadioInit.lFrequencyBase + SpiritManagementGetOffset();
/* Initialize the signals to drive the range extender application board */
SpiritManagementRangeExtInit();
SGpioInit xGpioIRQ={
SPIRIT_GPIO_3,
SPIRIT_GPIO_MODE_DIGITAL_OUTPUT_LP,
SPIRIT_GPIO_DIG_OUT_IRQ
};
/* Spirit IRQ config */
SpiritGpioInit(&xGpioIRQ);
/* Spirit Radio config */
SpiritRadioInit(&xRadioInit);
PktBasicInit xBasicInit={
PREAMBLE_LENGTH,
SYNC_LENGTH,
SYNC_WORD,
LENGTH_TYPE,
LENGTH_WIDTH,
CRC_MODE,
CONTROL_LENGTH,
EN_ADDRESS,
EN_FEC,
EN_WHITENING
};
/* Spirit Packet config */
SpiritPktBasicInit(&xBasicInit);
PktBasicAddressesInit xAddressInit={
EN_FILT_MY_ADDRESS,
MY_ADDRESS,
EN_FILT_MULTICAST_ADDRESS,
MULTICAST_ADDRESS,
EN_FILT_BROADCAST_ADDRESS,
BROADCAST_ADDRESS
};
SpiritPktBasicAddressesInit(&xAddressInit);
/* Spirit IRQs enable */
SpiritIrqDeInit(NULL);
SpiritIrq(RX_DATA_DISC,S_ENABLE);
SpiritIrq(RX_DATA_READY,S_ENABLE);
/* payload length config */
SpiritPktBasicSetPayloadLength(20);
/* enable SQI check */
SpiritQiSetSqiThreshold(SQI_TH_0);
SpiritQiSqiCheck(S_ENABLE);
/* RX timeout config */
SpiritTimerSetRxTimeoutMs(1000.0);
SpiritTimerSetRxTimeoutStopCondition(SQI_ABOVE_THRESHOLD);
/* IRQ registers blanking */
SpiritIrqClearStatus();
/* RX command */
SpiritCmdStrobeRx();
printf("%s: entering GENERIC_B while loop\n", __func__); //XXX
while (1)
{
osDelay(1000);
}
}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if (GPIO_Pin == SPIRIT1_IRQ_Pin)
{
gunSPIRITinterrupts++;
gbTxDoneFlag = true;
/* Get the IRQ status */
SpiritIrqGetStatus(&xIrqStatus);
printf("%s: xIrqStatus %08lX\n", __func__, xIrqStatus); //XXX //XXX
/* Check the SPIRIT RX_DATA_DISC IRQ flag */
if(xIrqStatus.IRQ_RX_DATA_DISC)
{
/* toggle LED1 */
printf("%s: SdkEvalLedToggle(LED1)\n", __func__); //XXX
/* RX command - to ensure the device will be ready for the next reception */
SpiritCmdStrobeRx();
}
/* Check the SPIRIT RX_DATA_READY IRQ flag */
if(xIrqStatus.IRQ_RX_DATA_READY)
{
/* Get the RX FIFO size */
gucRxData = SpiritLinearFifoReadNumElementsRxFifo();
/* Read the RX FIFO */
SpiritSpiReadLinearFifo(gucRxData, gzucVectcRxBuff);
/* Flush the RX FIFO */
SpiritCmdStrobeFlushRxFifo();
/* A simple way to check if the received data sequence is correct (in this case LED5 will toggle) */
{
SpiritBool xCorrect = S_TRUE;
for (uint8_t i = 0; i < gucRxData ; i++)
{
if (gzucVectcRxBuff[i] != i+1)
{
xCorrect = S_FALSE;
}
}
if (xCorrect)
{
/* toggle LED2 */
printf("%s: SdkEvalLedToggle(LED2)\n", __func__); //XXX
#ifdef USE_VCOM
printf("DATA CORRECT\r\n");
#endif
}
}
/* RX command - to ensure the device will be ready for the next reception */
SpiritCmdStrobeRx();
#ifdef USE_VCOM
/* print the received data */
printf("%s: data received: [", __func__);
for (uint8_t i = 0 ; i < gucRxData ; i++)
{
printf("%d ", gzucVectcRxBuff[i]);
}
printf("]\n");
#endif
}
printf("%s: xIrqStatus %08lX\n", __func__, xIrqStatus); //XXX
}
}
Address AppTx AppRx NucleoRx Reg Label
0x00 0x0C 0x0C 0x0C ANA_FUNC_CONF1
0x01 0xC0 0xC0 0xC0 ANA_FUNC_CONF0
0x02 0xA3 0xA3 0x02 GPIO3_CONF
0x03 0xA2 0xA2 0xA2 GPIO2_CONF
0x04 0xA2 0xA2 0xA2 GPIO1_CONF
0x05 0x0A 0x0A 0x0A GPIO0_CONF
0x06 0x00 0x00 0x00 MCU_CK_CONF
0x07 0x36 0x36 0x36 IF_OFFSET_ANA
0x08 0x06 0x06 0x06 SYNT3
0x09 0x7E 0x7E 0x82 SYNT2
0x0A 0xA8 0xA8 0x89 SYNT1
0x0B 0xA3 0xA3 0xE1 SYNT0
0x0C 0x01 0x01 0x0E CHSPACE
0x0D 0xAC 0xAC 0xAC IF_OFFSET_DIG
0x0E 0x00 0x00 0x00 FC_OFFSET1
0x0F 0x00 0x00 0x00 FC_OFFSET2
0x10 0x1B 0x1B 0x03 PA_POWER8
0x11 0x0E 0x0E 0x0E PA_POWER7
0x12 0x1A 0x1A 0x1A PA_POWER6
0x13 0x25 0x25 0x25 PA_POWER5
0x14 0x35 0x35 0x35 PA_POWER4
0x15 0x40 0x40 0x40 PA_POWER3
0x16 0x4E 0x4E 0x4E PA_POWER2
0x17 0x00 0x00 0x00 PA_POWER1
0x18 0xC7 0x07 0x07 PA_POWER0
0x1A 0x93 0x93 0x93 MOD1
0x1B 0x1A 0x1A 0x0A MOD0
0x1C 0x45 0x45 0x45 FDEV0
0x1D 0x13 0x13 0x13 CHFLT
0x1E 0xC8 0xC8 0xC8 AFC2
0x1F 0x18 0x18 0x18 AFC1
0x20 0x25 0x25 0x25 AFC0
0x21 0xE3 0xE3 0xE3 RSSI_FLT
0x22 0x24 0x00 0x24 RSSI_TH
0x23 0x58 0x58 0x58 CLOCKREC
0x24 0x22 0x22 0x22 AGCCTRL2
0x25 0x62 0x62 0x62 AGCCTRL1
0x26 0x8A 0x8A 0x8A AGCCTRL0
0x27 0x15 0x15 0x05 ANT_SELECT_CONF
0x30 0x00 0x00 0x00 PCKTCTRL4
0x31 0x07 0x07 0x07 PCKTCTRL3
0x32 0x3F 0x3F 0x1F PCKTCTRL2
0x33 0x30 0x30 0x30 PCKTCTRL1
0x34 0x00 0x00 0x00 PCKTLEN1
0x35 0x12 0x12 0x14 PCKTLEN0
0x36 0x88 0x88 0x88 SYNC4
0x37 0x88 0x88 0x88 SYNC3
0x38 0x88 0x88 0x88 SYNC2
0x39 0x88 0x88 0x88 SYNC1
0x3A 0x02 0x02 0x02 QI
0x3B 0x20 0x20 0x20 MBUS_PRMBL
0x3C 0x20 0x20 0x20 MBUS_PSTMBL
0x3D 0x00 0x00 0x00 MBUS_CTRL
0x3E 0x30 0x30 0x30 FIFO_CONFIG3_RXAFTHR
0x3F 0x30 0x30 0x30 FIFO_CONFIG2_RXAETHR
0x40 0x30 0x30 0x30 FIFO_CONFIG1_TXAFTHR
0x41 0x30 0x30 0x30 FIFO_CONFIG0_TXAETHR
0x42 0x00 0x00 0x00 PCKT_FLT_GOALS_CONTROL0_MASK
0x43 0x00 0x00 0x00 PCKT_FLT_GOALS_CONTROL1_MASK
0x44 0x00 0x00 0x00 PCKT_FLT_GOALS_CONTROL2_MASK
0x45 0x00 0x00 0x00 PCKT_FLT_GOALS_CONTROL3_MASK
0x46 0x00 0x00 0x00 PCKT_FLT_GOALS_CONTROL0_FIEL
0x47 0x00 0x00 0x00 PCKT_FLT_GOALS_CONTROL1_FIEL
0x48 0x00 0x00 0x00 PCKT_FLT_GOALS_CONTROL2_FIEL
0x49 0x00 0x00 0x00 PCKT_FLT_GOALS_CONTROL3_FIEL
0x4A 0x00 0x00 0x00 PCKT_FLT_GOALS_SOURCE_MASK
0x4B 0x00 0x00 0x00 PCKT_FLT_GOALS_SOURCE_ADDR
0x4C 0x00 0x00 0xFF PCKT_FLT_GOALS_BROADCAST
0x4D 0x00 0x00 0xEE PCKT_FLT_GOALS_MULTICAST
0x4E 0x00 0x00 0x34 PCKT_FLT_GOALS_TX_ADDR
0x4F 0x41 0x41 0x01 PCKT_FLT_OPTIONS
0x50 0x40 0x40 0x40 PROTOCOL2
0x51 0x01 0x01 0x01 PROTOCOL1
0x52 0x08 0x08 0x08 PROTOCOL0
0x53 0x01 0x09 0x52 TIMERS5_RX_TIMEOUT_PRESCALER
0x54 0x00 0xCE 0xF8 TIMERS4_RX_TIMEOUT_COUNTER
0x55 0x01 0x01 0x01 TIMERS3_LDC_PRESCALER
0x56 0x00 0x00 0x00 TIMERS2_LDC_COUNTER
0x57 0x01 0x01 0x01 TIMERS1_LDC_RELOAD_PRESCALER
0x58 0x00 0x00 0x00 TIMERS0_LDC_RELOAD_COUNTER
0x64 0xFF 0xFF 0xFF CSMA_CONFIG3
0x65 0x00 0x00 0x00 CSMA_CONFIG2
0x66 0x04 0x04 0x04 CSMA_CONFIG1
0x67 0x00 0x00 0x00 CSMA_CONFIG0
0x68 0x00 0x00 0x00 TX_CTRL_FIELD3
0x69 0x00 0x00 0x00 TX_CTRL_FIELD2
0x6A 0x00 0x00 0x00 TX_CTRL_FIELD1
0x6B 0x00 0x00 0x00 TX_CTRL_FIELD0
0x6C 0x00 0x00 0x00 CHNUM
0x6D 0x70 0x70 0x70 RCO_VCO_CALIBR_IN2
0x6E 0x3F 0x3F 0x3D RCO_VCO_CALIBR_IN1
0x6F 0x41 0x41 0x3E RCO_VCO_CALIBR_IN0
0x90 0x00 0x00 0x00 IRQ_MASK3
0x91 0x00 0x00 0x00 IRQ_MASK2
0x92 0x00 0x02 0x00 IRQ_MASK1
0x93 0x00 0x00 0x03 IRQ_MASK0
0x9E 0x5B 0x5B 0x5B SYNTH_CONFIG1
0x9F 0xA0 0xA0 0xA0 SYNTH_CONFIG0
0xA1 0x11 0x11 0x25 VCO_CONFIG
0xA3 0x35 0x35 0x35 DEM_CONFIG
0xA4 0x0C 0x0C 0x0C PM_CONFIG2
0xA5 0x20 0x98 0x98 PM_CONFIG1
0xA6 0x00 0x00 0x00 PM_CONFIG0
0xA7 0xE1 0xE1 0xE1 XO_CONFIG
0xB4 0x21 0x21 0x61 XO_RCO_TEST
0xC0 0x02 0x02 0x02 MC_STATE1
0xC1 0x07 0x07 0x07 MC_STATE0
0xC2 0x00 0x00 0x00 TX_PCKT_INFO
0xC3 0x00 0x00 0x00 RX_PCKT_INFO
0xC4 0x00 0x00 0xFE AFC_CORR
0xC5 0x00 0x0E 0x0F LINK_QUALIF2
0xC6 0x00 0x14 0x18 LINK_QUALIF1
0xC7 0x00 0x28 0x28 LINK_QUALIF0
0xC8 0x00 0x4B 0x0E RSSI_LEVEL
0xC9 0x00 0x00 0x00 RX_PCKT_LEN1
0xCA 0x00 0x00 0x00 RX_PCKT_LEN0
0xCB 0x00 0x00 0x00 CRC_FIELD2
0xCC 0x00 0x00 0x00 CRC_FIELD1
0xCD 0x00 0x00 0x00 CRC_FIELD0
0xCE 0x00 0x00 0x00 RX_CTRL_FIELD0
0xCF 0x00 0x00 0x00 RX_CTRL_FIELD1
0xD0 0x00 0x00 0x00 RX_CTRL_FIELD2
0xD1 0x00 0x00 0x00 RX_CTRL_FIELD3
0xD2 0x00 0x00 0x00 RX_ADDR_FIELD1
0xD3 0x00 0x00 0x00 RX_ADDR_FIELD0
0xE4 0x70 0x70 0x70 RCO_VCO_CALIBR_OUT1
0xE5 0x00 0x00 0x00 RCO_VCO_CALIBR_OUT0
0xE6 0x00 0x00 0x00 LINEAR_FIFO_STATUS1
0xE7 0x00 0x00 0x00 LINEAR_FIFO_STATUS0
0xF0 0x01 0x01 0x01 DEVICE_INFO1
0xF1 0x30 0x30 0x30 DEVICE_INFO0
0xFA 0x30 IRQ_STATUS3
0xFB 0x60 IRQ_STATUS2
0xFC 0x40 IRQ_STATUS1
0xFD 0x02 IRQ_STATUS0