cancel
Showing results for 
Search instead for 
Did you mean: 

STM32WL55 Nucleo board receive not working after transmit using SubGHz_Phy_PingPong - FSK

ola
Associate III

Hi All,

Happy New Year.

I am trying to get two STM32WL55 Nucleo boards communicating with each other on the 868MHz ISM band. The structure is  that one boards sends a message and the other board responds with a reply to the message received from the first board and using a third party sniffer I can monitor the data exchange between the two boards over air.
The project is based of the SubGHz_Phy_PingPong project. 

So my problem is as follows. When Board1 sends a message to Board2. Board2 gets the message correctly and I can also see the data transmitted on Board1 on the packet sniffer. Both boards are running the same code as shown below.

The problem is that when Board2 responds to the message sent by Board1. Board1 does not see the message even though I can confirm by looking at the sniffer that the message was sent by Board2.

uint8_t rxbuffer[MAX_APP_BUFFER_SIZE];
uint8_t debug[MAX_APP_BUFFER_SIZE*3];

static void OnRxDone(uint8_t *payload, uint16_t size, int16_t rssi, int8_t LoraSnr_FskCfo)
{
  int j = 0;
  /* USER CODE BEGIN OnRxDone */
  APP_LOG(TS_ON, VLEVEL_L, "OnRxDone\n\r");
  APP_LOG(TS_ON, VLEVEL_L, "RssiValue=%d dBm\n\r", rssi);

  /* Record Received Signal Strength and payload size */
  memset(rxbuffer, 0, MAX_APP_BUFFER_SIZE); /* Clear rx buffer */
  if (size <= MAX_APP_BUFFER_SIZE)
  {
    memcpy(rxbuffer, payload, size);
  }
  for ( int i = 0; i < size; i++)
  {
      j += sprintf(&debug[j],"%02x ", payload[i]);
  }
  APP_LOG(TS_ON, VLEVEL_L, "Rx: %s\n\r", debug);
  /* USER CODE END OnRxDone */
}

So for example 

Board1: Sends <01,FC,11,22,33,44,55,66,77,88>

Sniffer:  <01,FC,11,22,33,44,55,66,77,88>

Board2 OnRxDone <01,FC,11,22,33,44,55,66,77,88>

Where <11,22,33,44,55,66,77> is meant to be the MAC address of the Board1 read from flash. On receipt of the above message. Board2 is add its own MAC address and sends a reply back to Board1. So Board2 constructs the following packet.

Board2: Sends <01,FD,DE,AF,DE,AD,BE,EF,CA,FE,11,22,33,44,55,66,77,88>

Sniffer:  <<01,FD,DE,AF,DE,AD,BE,EF,CA,FE,11,22,33,44,55,66,77,88>

Board1: OnRxDone <01,FC,11,22,33,44,55,66,77,88,AA,BB,CC,DD,EE,FF,GG,HH> 

Where  DE,AF,DE,AD,BE,EF,CA,FE is the MAC address for Board2 and AA,BB,CC,DD,EE,FF,GG,HH seems to be random data. From what I can see the OnRxDone is being fed data from the internal transmit buffer.

I understand that both Rx and Tx share a 255 Ram buffer which can wholly used by either Tx or RX. So it is possible that Tx can be used to transmit 255 bytes or the Rx can be used to receive 255 bytes but if both needed to be shared then only half the buffer would be available to both Tx and Rx. 

From reading the datasheet both TxBaseAddr and RxBaseAddr can be set using the command SetBufferBaseAddresses(...)

From my debug session it seemed like TxBaseAddr is using TxBaseAddr of 0x00 which happens to also be the same as RxBaseAddr 0x00.

I tried using the SetBufferBaseAddresses(128, 0) to move TxBaseAddr to half way of Ram buffer but did not work as I was expecting. I would appreciate if anyone has any idea on how to solve this issue.

Many thanks in advance.

 

1 ACCEPTED SOLUTION

Accepted Solutions
ola
Associate III

Hi All,

I found a work around to the problem described above just in case someone else find themselves experiencing the same issue. The work around I employed was to change TxConfig and RxConfig from being local to the SubghzApp_Init() function to being private global to the module.

I then create another function named Reconfigure() which I call when I get an OnTxDone() event. The Reconfigure() simply reconfigures the previous initialized data structure TxConfig and RxConfig. See code snippet for more information.

 

// Make private to module
static TxConfigGeneric_t TxConfig = {0};
static RxConfigGeneric_t RxConfig = {0};

/* Exported functions ---------------------------------------------------------*/
void SubghzApp_Init(void)
{
  /* USER CODE BEGIN SubghzApp_Init_1 */

  // Other code removed for brevity

  /* Radio initialization */
  RadioEvents.TxDone = OnTxDone;
  RadioEvents.RxDone = OnRxDone;
  RadioEvents.TxTimeout = OnTxTimeout;
  RadioEvents.RxTimeout = OnRxTimeout;
  RadioEvents.RxError = OnRxError;
  Radio.Init(&RadioEvents);

  /*calculate random delay for synchronisation*/
  random_delay = (Radio.Random()) >> 22; /*10bits random e.g. from 0 to 1023 ms*/

  /* Radio Set frequency */
  Radio.SetChannel(RF_FREQUENCY);

  /* Radio configuration */
  APP_LOG(TS_OFF, VLEVEL_M, "---------------\n\r");
  APP_LOG(TS_OFF, VLEVEL_M, "FSK_MODULATION\n\r");
  APP_LOG(TS_OFF, VLEVEL_M, "FSK_BW=%d Hz\n\r",     FSK_BANDWIDTH);
  APP_LOG(TS_OFF, VLEVEL_M, "FSK_DR=%d bits/s\n\r", FSK_DATARATE);

  /*fsk modulation*/
  TxConfig.fsk.ModulationShaping = RADIO_FSK_MOD_SHAPING_G_BT_05;
  TxConfig.fsk.FrequencyDeviation = FSK_FDEV;
  TxConfig.fsk.BitRate = FSK_DATARATE; /*BitRate*/
  TxConfig.fsk.PreambleLen = FSK_PREAMBLE_LENGTH;   /*in Byte        */
  TxConfig.fsk.SyncWordLength = sizeof(syncword); /*in Byte        */
  TxConfig.fsk.SyncWord = syncword; /*SyncWord Buffer*/
  TxConfig.fsk.whiteSeed =  0x01FF; /*WhiteningSeed  */
  TxConfig.fsk.HeaderType  = RADIO_FSK_PACKET_VARIABLE_LENGTH; /*legacy: payload length field is 1 byte long*/
  TxConfig.fsk.CrcLength = RADIO_FSK_CRC_2_BYTES_IBM;       /* Size of the CRC block in the GFSK packet*/
  TxConfig.fsk.CrcPolynomial = 0x8005;
  TxConfig.fsk.CrcSeed = 0xFFFF;
  TxConfig.fsk.Whitening = RADIO_FSK_DC_FREEWHITENING;
  if (0UL != Radio.RadioSetTxGenericConfig(GENERIC_FSK, &TxConfig, TX_OUTPUT_POWER, TX_TIMEOUT_VALUE))
  {
    while (1);
  }

  /* RX Continuous */
  RxConfig.fsk.ModulationShaping = RADIO_FSK_MOD_SHAPING_G_BT_05;
  RxConfig.fsk.Bandwidth = FSK_BANDWIDTH;
  RxConfig.fsk.BitRate = FSK_DATARATE; /*BitRate*/
  RxConfig.fsk.PreambleLen = FSK_PREAMBLE_LENGTH; /*in Byte*/
  RxConfig.fsk.PreambleMinDetect = RADIO_FSK_PREAMBLE_DETECTOR_08_BITS;
  RxConfig.fsk.SyncWordLength = sizeof(syncword); /*in Byte*/
  RxConfig.fsk.SyncWord = syncword; /*SyncWord Buffer*/
  RxConfig.fsk.whiteSeed = 0x01FF; /*WhiteningSeed*/
  RxConfig.fsk.LengthMode  = RADIO_FSK_PACKET_VARIABLE_LENGTH; /* legacy: payload length field is 1 byte long*/
  RxConfig.fsk.CrcLength = RADIO_FSK_CRC_2_BYTES_IBM;       /* Size of the CRC block in the GFSK packet*/
  RxConfig.fsk.CrcPolynomial = 0x8005;
  RxConfig.fsk.CrcSeed = 0xFFFF;
  RxConfig.fsk.Whitening = RADIO_FSK_DC_FREEWHITENING;
  RxConfig.fsk.MaxPayloadLength = MAX_APP_BUFFER_SIZE;
  RxConfig.fsk.StopTimerOnPreambleDetect = 0;
  RxConfig.fsk.AddrComp = RADIO_FSK_ADDRESSCOMP_FILT_OFF;
  if (0UL != Radio.RadioSetRxGenericConfig(GENERIC_FSK, &RxConfig, RX_CONTINUOUS_ON, 0))
  {
    while (1);
  }
  APP_LOG(TS_ON, VLEVEL_L, "rand=%d\n\r", random_delay);
  
  Radio.Rx(RX_TIMEOUT_VALUE);

  /* USER CODE END SubghzApp_Init_2 */
}

//
// Simply configure previoulsy initialised data structure TxConfig and RxConfig
//
void Reconfigure(void)
{
	if (0UL != Radio.RadioSetTxGenericConfig(GENERIC_FSK, &TxConfig, TX_OUTPUT_POWER, TX_TIMEOUT_VALUE))
	{
		while (1);
	}

	if (0UL != Radio.RadioSetRxGenericConfig(GENERIC_FSK, &RxConfig, RX_CONTINUOUS_ON, 0))
	{
		while (1);
	}
	Radio.Rx(RX_TIMEOUT_VALUE);
}

//
// Data now transmitted so reconfigure
//
static void OnTxDone(void)
{
	APP_LOG(TS_ON, VLEVEL_L, "OnTxDone\n\r");

	Reconfigure();    // Work around to get receive to work after transmit
}

 

View solution in original post

2 REPLIES 2
ola
Associate III

Hi All,

I found a work around to the problem described above just in case someone else find themselves experiencing the same issue. The work around I employed was to change TxConfig and RxConfig from being local to the SubghzApp_Init() function to being private global to the module.

I then create another function named Reconfigure() which I call when I get an OnTxDone() event. The Reconfigure() simply reconfigures the previous initialized data structure TxConfig and RxConfig. See code snippet for more information.

 

// Make private to module
static TxConfigGeneric_t TxConfig = {0};
static RxConfigGeneric_t RxConfig = {0};

/* Exported functions ---------------------------------------------------------*/
void SubghzApp_Init(void)
{
  /* USER CODE BEGIN SubghzApp_Init_1 */

  // Other code removed for brevity

  /* Radio initialization */
  RadioEvents.TxDone = OnTxDone;
  RadioEvents.RxDone = OnRxDone;
  RadioEvents.TxTimeout = OnTxTimeout;
  RadioEvents.RxTimeout = OnRxTimeout;
  RadioEvents.RxError = OnRxError;
  Radio.Init(&RadioEvents);

  /*calculate random delay for synchronisation*/
  random_delay = (Radio.Random()) >> 22; /*10bits random e.g. from 0 to 1023 ms*/

  /* Radio Set frequency */
  Radio.SetChannel(RF_FREQUENCY);

  /* Radio configuration */
  APP_LOG(TS_OFF, VLEVEL_M, "---------------\n\r");
  APP_LOG(TS_OFF, VLEVEL_M, "FSK_MODULATION\n\r");
  APP_LOG(TS_OFF, VLEVEL_M, "FSK_BW=%d Hz\n\r",     FSK_BANDWIDTH);
  APP_LOG(TS_OFF, VLEVEL_M, "FSK_DR=%d bits/s\n\r", FSK_DATARATE);

  /*fsk modulation*/
  TxConfig.fsk.ModulationShaping = RADIO_FSK_MOD_SHAPING_G_BT_05;
  TxConfig.fsk.FrequencyDeviation = FSK_FDEV;
  TxConfig.fsk.BitRate = FSK_DATARATE; /*BitRate*/
  TxConfig.fsk.PreambleLen = FSK_PREAMBLE_LENGTH;   /*in Byte        */
  TxConfig.fsk.SyncWordLength = sizeof(syncword); /*in Byte        */
  TxConfig.fsk.SyncWord = syncword; /*SyncWord Buffer*/
  TxConfig.fsk.whiteSeed =  0x01FF; /*WhiteningSeed  */
  TxConfig.fsk.HeaderType  = RADIO_FSK_PACKET_VARIABLE_LENGTH; /*legacy: payload length field is 1 byte long*/
  TxConfig.fsk.CrcLength = RADIO_FSK_CRC_2_BYTES_IBM;       /* Size of the CRC block in the GFSK packet*/
  TxConfig.fsk.CrcPolynomial = 0x8005;
  TxConfig.fsk.CrcSeed = 0xFFFF;
  TxConfig.fsk.Whitening = RADIO_FSK_DC_FREEWHITENING;
  if (0UL != Radio.RadioSetTxGenericConfig(GENERIC_FSK, &TxConfig, TX_OUTPUT_POWER, TX_TIMEOUT_VALUE))
  {
    while (1);
  }

  /* RX Continuous */
  RxConfig.fsk.ModulationShaping = RADIO_FSK_MOD_SHAPING_G_BT_05;
  RxConfig.fsk.Bandwidth = FSK_BANDWIDTH;
  RxConfig.fsk.BitRate = FSK_DATARATE; /*BitRate*/
  RxConfig.fsk.PreambleLen = FSK_PREAMBLE_LENGTH; /*in Byte*/
  RxConfig.fsk.PreambleMinDetect = RADIO_FSK_PREAMBLE_DETECTOR_08_BITS;
  RxConfig.fsk.SyncWordLength = sizeof(syncword); /*in Byte*/
  RxConfig.fsk.SyncWord = syncword; /*SyncWord Buffer*/
  RxConfig.fsk.whiteSeed = 0x01FF; /*WhiteningSeed*/
  RxConfig.fsk.LengthMode  = RADIO_FSK_PACKET_VARIABLE_LENGTH; /* legacy: payload length field is 1 byte long*/
  RxConfig.fsk.CrcLength = RADIO_FSK_CRC_2_BYTES_IBM;       /* Size of the CRC block in the GFSK packet*/
  RxConfig.fsk.CrcPolynomial = 0x8005;
  RxConfig.fsk.CrcSeed = 0xFFFF;
  RxConfig.fsk.Whitening = RADIO_FSK_DC_FREEWHITENING;
  RxConfig.fsk.MaxPayloadLength = MAX_APP_BUFFER_SIZE;
  RxConfig.fsk.StopTimerOnPreambleDetect = 0;
  RxConfig.fsk.AddrComp = RADIO_FSK_ADDRESSCOMP_FILT_OFF;
  if (0UL != Radio.RadioSetRxGenericConfig(GENERIC_FSK, &RxConfig, RX_CONTINUOUS_ON, 0))
  {
    while (1);
  }
  APP_LOG(TS_ON, VLEVEL_L, "rand=%d\n\r", random_delay);
  
  Radio.Rx(RX_TIMEOUT_VALUE);

  /* USER CODE END SubghzApp_Init_2 */
}

//
// Simply configure previoulsy initialised data structure TxConfig and RxConfig
//
void Reconfigure(void)
{
	if (0UL != Radio.RadioSetTxGenericConfig(GENERIC_FSK, &TxConfig, TX_OUTPUT_POWER, TX_TIMEOUT_VALUE))
	{
		while (1);
	}

	if (0UL != Radio.RadioSetRxGenericConfig(GENERIC_FSK, &RxConfig, RX_CONTINUOUS_ON, 0))
	{
		while (1);
	}
	Radio.Rx(RX_TIMEOUT_VALUE);
}

//
// Data now transmitted so reconfigure
//
static void OnTxDone(void)
{
	APP_LOG(TS_ON, VLEVEL_L, "OnTxDone\n\r");

	Reconfigure();    // Work around to get receive to work after transmit
}

 

Hello. I would not say that it is an optimal solution. The problem lies in how to transmit and receive data with a variable length of data packets. During transmission, the "PayloadLength" value in the "SubgRf.PacketParams.Params.Gfsk" structure is modified. When we send a packet smaller than the packet we expected to receive, the received packet is received corrupted and the CRC sum is in error. So to solve the problem, we add to the radio.c file line 1487 the correction of the structure and send it to the receiver.

/* Set DBG pin */
DBG_GPIO_RADIO_RX( SET );
SubgRf.PacketParams.Params.Gfsk.PayloadLength = 0xFF; // ADDED
SUBGRF_SetPacketParams(&SubgRf.PacketParams); // ADDED
/* RF switch configuration */