cancel
Showing results for 
Search instead for 
Did you mean: 

S2LP StatusByte 0x52 0xE9 error

Macias
Associate II

Hi, I try to transmit data by S2LP(RC-S2LP-433) and have a problem. When I try to debug the unit (true studio) everything work great, when the TX end then get an ISR to reset flag and in main loop start new transmitt. When I try to start the unit without debugging mode, only give 3V to the my board then don't transmitting and give an status byte[0]=0x52,[1]=0xE9. The S2LP chip is version 0x91. Can anyone help me?

#include "main.h"
#include "cmsis_os.h"
 
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "../S2LP/RF_SPI.h"
xSemaphoreHandle radio_spi_mutex;
/* USER CODE END Includes */
 
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
uint8_t chk_bat = 1;
volatile uint8_t start_flag =0;
SPI_HandleTypeDef hspi1;
/* USER CODE END PTD */
 
 
 
 
UART_HandleTypeDef huart1;
 
osThreadId defaultTaskHandle;
/* USER CODE BEGIN PV */
 
/* USER CODE END PV */
 
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_SPI1_Init(void);
 
static void MX_USART1_UART_Init(void);
void StartDefaultTask(void const * argument);
 
/* USER CODE BEGIN PFP */
volatile FlagStatus xTxDoneFlag = RESET;
S2LPIrqs xIrqStatus;
uint8_t radio_frame[20];
volatile uint16_t counter;
volatile uint8_t start_flag;
volatile uint8_t first = 0;
/* USER CODE END PFP */
 
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
 
 
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){
 
	if(GPIO_Pin==IRQ_SENT_Pin)
	  {
		S2LPGpioIrqGetStatus(&xIrqStatus);
 
				  if(xIrqStatus.IRQ_TX_DATA_SENT == S_SET || xIrqStatus.IRQ_MAX_RE_TX_REACH == S_SET)
				  {
					  xTxDoneFlag = RESET;
					  //counter = 0;
					  HAL_GPIO_WritePin(LEDR_GPIO_Port,LEDR_Pin,RESET);
 
				  }
				  else
				  {
					  S2LPCmdStrobeReady();
					  xTxDoneFlag = RESET;
				  }
 
 
 
	  }
 
	// HAL_GPIO_WritePin(LEDR_GPIO_Port, LEDR_Pin, RESET);
 
}
 
int main(void)
{
  /* USER CODE BEGIN 1 */
 
  /* USER CODE END 1 */
  
 
  /* MCU Configuration--------------------------------------------------------*/
 
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
 
  /* USER CODE BEGIN Init */
 
  /* USER CODE END Init */
 
  /* Configure the system clock */
  SystemClock_Config();
 
  /* USER CODE BEGIN SysInit */
 
  /* USER CODE END SysInit */
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_SPI1_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
 
  /* USER CODE END 2 */
 
  /* USER CODE BEGIN RTOS_MUTEX */
  radio_spi_mutex = xSemaphoreCreateBinary();
  /* USER CODE END RTOS_MUTEX */
 
  /* USER CODE BEGIN RTOS_SEMAPHORES */
  /* add semaphores, ... */
  /* USER CODE END RTOS_SEMAPHORES */
 
  /* USER CODE BEGIN RTOS_TIMERS */
  /* start timers, add new ones, ... */
  /* USER CODE END RTOS_TIMERS */
 
  /* USER CODE BEGIN RTOS_QUEUES */
  /* add queues, ... */
  /* USER CODE END RTOS_QUEUES */
 
  /* Create the thread(s) */
  /* definition and creation of defaultTask */
  osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 256);
  defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);
 
  /* USER CODE BEGIN RTOS_THREADS */
  /* add threads, ... */
  /* USER CODE END RTOS_THREADS */
 
  /* Start scheduler */
  osKernelStart();
  
  /* We should never get here as control is now taken by the scheduler */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}
 
 
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
 
  /** Configure the main internal regulator output voltage 
  */
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
  /** Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL3;
  RCC_OscInitStruct.PLL.PLLDIV = RCC_PLL_DIV2;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
 
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
  {
    Error_Handler();
  }
}
 
 
static void MX_SPI1_Init(void)
{
 
  /* SPI1 parameter configuration*/
  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_64;
  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();
  }
 
}
 
/**
  * @brief USART1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_USART1_UART_Init(void)
{
 
 
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 115200;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
 
 
}
 
 
static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
 
  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
 
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(LEDR_GPIO_Port, LEDR_Pin, GPIO_PIN_RESET);
 
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOB, CSN_Pin, GPIO_PIN_SET);
 
  HAL_GPIO_WritePin(GPIOB, RESET_RF_Pin, GPIO_PIN_SET);
 
 
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(CSN2_GPIO_Port, CSN2_Pin, GPIO_PIN_RESET);
 
  /*Configure GPIO pin : LEDR_Pin */
  GPIO_InitStruct.Pin = LEDR_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(LEDR_GPIO_Port, &GPIO_InitStruct);
 
  /*Configure GPIO pin : IRQ_SENT_Pin */
  GPIO_InitStruct.Pin = IRQ_SENT_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(IRQ_SENT_GPIO_Port, &GPIO_InitStruct);
 
 
  /*Configure GPIO pin : IRQ_SENT_Pin */
  GPIO_InitStruct.Pin = P2_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  HAL_GPIO_Init(P2_Port, &GPIO_InitStruct);
 
 
  /*Configure GPIO pin : RESET_RF_Pin */
  GPIO_InitStruct.Pin = RESET_RF_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
  HAL_GPIO_Init(RESET_RF_GPIO_Port, &GPIO_InitStruct);
 
  /*Configure GPIO pins : CSN_Pin CSN2_Pin */
  GPIO_InitStruct.Pin = CSN_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
 
  /*Configure GPIO pins : CSN_Pin CSN2_Pin */
  GPIO_InitStruct.Pin = CSN2_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
 
  /* EXTI interrupt init*/
  HAL_NVIC_SetPriority(EXTI1_IRQn, 5, 0);
  HAL_NVIC_EnableIRQ(EXTI1_IRQn);
 
 
 
}
 
 
void StartDefaultTask(void const * argument)
{
 
	HAL_GPIO_WritePin(LEDR_GPIO_Port,LEDR_Pin,RESET);
 
	Init_S2LP_TX();
	start_flag = 1;
 
uint8_t statusr[2];
 
S2LPSpiReadRegisters(DEVICE_INFO1_ADDR, 2, statusr);
 
 
  /* Infinite loop */
  for(;;)
  {
if(xTxDoneFlag == RESET)
{
	  HAL_GPIO_WritePin(LEDR_GPIO_Port,LEDR_Pin,SET);
	  S2LPCmdStrobeFlushTxFifo();
	  S2LPSpiWriteFifo(20, radio_frame);
	  S2LPCmdStrobeTx();
	  xTxDoneFlag = SET;
}
	//  state_print();
 
S2LPSpiReadRegisters(MC_STATE1_ADDR, 2, statusr);
 
 
  	vTaskDelay(100/portTICK_RATE_MS);
 
 
 
 
  	//S2LPGpioIrqGetStatus(&xIrqStatus);
 
 
  }
  /* USER CODE END 5 */
}
 
 
 
 
 
 
 
 
 

5 REPLIES 5
Winfred LU
ST Employee

Hi Macias,

Sorry that i couldn't find an issue for the posted code.

MC_STATE0 0xe9 means that S2-LP is setting up synthesizer, it's ready now, and XO is operating.

It seems that there is something wrong trying to lock for TX.

Could you review the circuit, especially for the capacitor on VRSYNTH ?

Possibly if you could try to add some delay before S2LPCmdStrobeTx() ?

Best Regards,

Winfred

Macias
Associate II

Hi Winfred,

I create switch based board to select commands on nucleo board. I'v got 5 switches:

1 - init S2LP registers,

2 - check MC_State's,

3 - send frame (send fifo bytes and tx strobe),

4 - set SDN pin,

5 - reset SDN pin.

Now the first sequence: 4,5,1,3,2 and the board stuck with MC_State0 = 0xE9 (atachment 1-BAD.jpg is the voltage on VrSynth). Then I do the same sequence (board have still a power supply) and then the board work good and the MC_State0 = 0x01 (in the TX_Sent isr arrived), the voltage in Vrsynth look's rising faster(2-good.jpg).

The init sequence:

SRadioInit xRadioInit = {
  BASE_FREQUENCY,
  MODULATION_SELECT,
  DATARATE,
  FREQ_DEVIATION,
  BANDWIDTH
};
 
PktBasicInit xBasicInit={
  PREAMBLE_LENGTH,
  SYNC_LENGTH,
  SYNC_WORD,
  VARIABLE_LENGTH,
  EXTENDED_LENGTH_FIELD,
  CRC_MODE,
  EN_ADDRESS,
  EN_FEC,
  EN_WHITENING
};
 
SGpioInit xGpioIRQ={
		  S2LP_GPIO_1,
		  S2LP_GPIO_MODE_DIGITAL_OUTPUT_HP,
		  S2LP_GPIO_DIG_OUT_IRQ
};
uint8_t status_arr[4];
 
void Init_S2LP_TX(void)
{
	S2LPPktBasicSetPayloadLength(20);
	S2LPGpioIrqDeInit(NULL);
	S2LPPktBasicInit(&xBasicInit);
	S2LPRadioInit(&xRadioInit);
	S2LPGpioInit(&xGpioIRQ);
	S2LPGpioIrqConfig(MAX_RE_TX_REACH,S_ENABLE);
	S2LPGpioIrqConfig(TX_DATA_SENT,S_ENABLE);
	S2LPPktBasicSetPayloadLength(20);
}

ISR:

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){
	if(GPIO_Pin==IRQ_SENT_Pin)
	  {
	S2LPGpioIrqGetStatus(&xIrqStatus);
	 if(xIrqStatus.IRQ_TX_DATA_SENT == S_SET || xIrqStatus.IRQ_MAX_RE_TX_REACH == S_SET)
				  {
					  xTxDoneFlag = RESET;
					  HAL_GPIO_WritePin(LEDR_GPIO_Port,LEDR_Pin,RESET);
				  }
				  else
				  {}
	  }
}

task:

if(cmd[0] == '1')
{Init_S2LP_TX();
	S2LPSpiReadRegisters(0x8e, 1, statusr);
	cmd[0]=0;}
 
if(cmd[0] == '2')
{S2LPSpiReadRegisters(0x8e, 1, statusr);
	cmd[0]=0;}
 
if(cmd[0] == '3'){
flag = 1;
	xTxDoneFlag = RESET;
	cmd[0]=0;}
 
if(cmd[0] == '4'){
	HAL_GPIO_WritePin(RESET_RF_GPIO_Port, RESET_RF_Pin, GPIO_PIN_SET);
	cmd[0]=0;}
 
if(cmd[0] == '5'){
	HAL_GPIO_WritePin(RESET_RF_GPIO_Port, RESET_RF_Pin, GPIO_PIN_RESET);
	cmd[0]=0;}
	 
 if(xTxDoneFlag == RESET)    // If an ISR read TX_Sent == SET
	  {
		  S2LPCmdStrobeFlushTxFifo();
		  vTaskDelay(10/portTICK_RATE_MS);
		  S2LPSpiWriteFifo(20, radio_frame);
		  HAL_GPIO_WritePin(LD2_GPIO_Port,LD2_Pin,SET);
		  S2LPCmdStrobeTx();
                  vTaskDelay(10/portTICK_RATE_MS);
		  xTxDoneFlag = SET;
		  vTaskDelay(10/portTICK_RATE_MS);
	  }

As you see here is a difference with load cap time and the shape for a first run.

0690X00000ApPcMQAV.jpg

Here is a second start:0690X00000ApPcRQAV.jpg

Thank for a replay.

Winfred LU
ST Employee

Please note that SDN hold pulse width (Thold) has to be larger than 1 ms (switch 4 ~ 5)

and the Rest pulse width (Trest) has to be larger than 2 ms (switch 5 ~ 1)

Refer to datasheet Figure 8.

https://www.st.com/resource/en/datasheet/s2-lp.pdf

Possibly also add a delay before calling S2LPCmdStrobeTx() :

if(xTxDoneFlag == RESET)    // If an ISR read TX_Sent == SET
	  {
		  S2LPCmdStrobeFlushTxFifo();
		  vTaskDelay(10/portTICK_RATE_MS);
		  S2LPSpiWriteFifo(20, radio_frame);
		  HAL_GPIO_WritePin(LD2_GPIO_Port,LD2_Pin,SET);
		  vTaskDelay(10/portTICK_RATE_MS);
		  S2LPCmdStrobeTx();
                  vTaskDelay(10/portTICK_RATE_MS);
		  xTxDoneFlag = SET;
		  vTaskDelay(10/portTICK_RATE_MS);
	  }

Please request for schematic review from your supporting FAE.

Thank you.

Hi, the SDN pin is connected without any diode's like it's in a STEVAL-FKI433_V2. I add a delay to initial SDN and SRES strobe:

	SdkEvalSpiInit();
 
	SdkEvalEnterShutdown();
	vTaskDelay(10/portTICK_RATE_MS);
	SdkEvalExitShutdown();
	vTaskDelay(10/portTICK_RATE_MS);
	S2LPCmdStrobeSres();
	vTaskDelay(100/portTICK_RATE_MS);
 
	S2LPGpioIrqDeInit(NULL);
	S2LPRadioInit(&xRadioInit);
	S2LPPktBasicInit(&xBasicInit);
	S2LPGpioInit(&xGpioIRQ);
	S2LPGpioIrqConfig(MAX_RE_TX_REACH,S_ENABLE);
	S2LPGpioIrqConfig(TX_DATA_SENT,S_ENABLE);
	S2LPPktBasicSetPayloadLength(20);
 
	  /*Configure GPIO pin : S2_GPIO1_Pin */
	  GPIO_InitStruct.Pin = S2_GPIO1_Pin;
	  GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
	  GPIO_InitStruct.Pull = GPIO_PULLUP;
	  HAL_GPIO_Init(S2_GPIO1_GPIO_Port, &GPIO_InitStruct);
 
	  GPIO_InitStruct.Pin = S2_GPIO0_Pin;
	  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
	  GPIO_InitStruct.Pull = GPIO_PULLDOWN;
	  HAL_GPIO_Init(S2_GPIO0_GPIO_Port, &GPIO_InitStruct);
 
	  SdkEvalSPICSHigh();
 
	  HAL_NVIC_SetPriority(EXTI0_1_IRQn, 2, 0);
	  HAL_NVIC_EnableIRQ(EXTI0_1_IRQn);
	  HAL_NVIC_SetPriority(EXTI4_15_IRQn, 2, 0);
	  HAL_NVIC_EnableIRQ(EXTI4_15_IRQn);
 
	  S2LPGpioIrqClearStatus();

It's work only one time and when MC_STATE_0 is 0xe9 I go to stanby and to he ready state:

if(status_arr[0] == 0xE9)
{
	S2LPCmdStrobeStandby();
	vTaskDelay(10/portTICK_RATE_MS);
 
	if(status_arr[0] != 0xE9)
	{
	xTxDoneFlag = RESET;
	S2LPCmdStrobeReady();
	}
}

And then it work's. But i still don't know where is the problem.

Anders Dam Kofoed
Associate II

Hi

I found out that I needed this in my mode-switch in order to re-calibrate the RCO:

    S2LPRefreshStatus(); // g_sStatus_MC_STATE
    // Recovery
    if (g_xStatus.MC_STATE != MC_STATE_READY && g_xStatus.MC_STATE != MC_STATE_TX && g_xStatus.MC_STATE != MC_STATE_RX && g_xStatus.MC_STATE != MC_STATE_STANDBY && g_xStatus.MC_STATE != MC_STATE_SLEEP)
    {
        printf("S2LP Recovery...\r\n");
        S2LPCmdStrobeSabort();
        HAL_Delay(1);
        S2LPCmdStrobeStandby();
        HAL_Delay(1);
        S2LPCmdStrobeReady();
        HAL_Delay(1);
    }