cancel
Showing results for 
Search instead for 
Did you mean: 

RS485 sometimes fails when using STOP2 mode

npatil15
Associate III

Hello,

Using RS485 for modbus communication.

It is observed that, if we disable STOP2 mode then RS485 communication works fine (no frame loss). but asa we keep STOP2 mode then at the time of wakeup I found some frame loss.

#define RS485_TX_ENABLE()   HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET)
#define RS485_RX_ENABLE()   HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET)
static void MX_LPUART1_UART_Init(void)
{
  hlpuart1.Instance = LPUART1;
  hlpuart1.Init.BaudRate = 115200;
  hlpuart1.Init.WordLength = UART_WORDLENGTH_8B;
  hlpuart1.Init.StopBits = UART_STOPBITS_1;
  hlpuart1.Init.Parity = UART_PARITY_NONE;
  hlpuart1.Init.Mode = UART_MODE_TX_RX;
  hlpuart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  hlpuart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  hlpuart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_RS485Ex_Init(&hlpuart1, UART_DE_POLARITY_HIGH, 0, 0) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetTxFifoThreshold(&hlpuart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetRxFifoThreshold(&hlpuart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_DisableFifoMode(&hlpuart1) != HAL_OK)
  {
    Error_Handler();
  }
}

void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE2);
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_LSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.LSIState = RCC_LSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
  {
    Error_Handler();
  }
}

void EnterLowPowerMode()
{
  HAL_UARTEx_EnableStopMode(&hlpuart1);
  HAL_SuspendTick();
  HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);
  HAL_ResumeTick();
  SystemClock_Config();
  RS485_RX_ENABLE();
}

Please guide me what need to re-init to make it run smoothly.

2 REPLIES 2
npatil15
Associate III

After debugging for more, I found that it was failing at CRC (return calculateCRC(data, length - MODBUS_REGISTER_SIZE_BYTES) == received;).

so, for sure, the data received is corrupted during reception, due to not wakeup correctly.

uint16_t calculateCRC(const uint8_t* data, size_t length) const
{
  uint16_t crc = 0xFFFF;
  for (size_t i = 0; i < length; ++i)
  {
    crc ^= data[i];
    for (int j = 0; j < 8; ++j)
    {
      crc = (crc & 1) ? ((crc >> 1) ^ 0xA001) : (crc >> 1);
    }
  }
  return crc;
}

bool validateCRC(const uint8_t* data, size_t length) const
{
  if (length < 2)
  {
    return false;
  }
  uint16_t received = data[length - 2] | (data[length - 1] << 8);
  return calculateCRC(data, length - 2) == received;
}

 

npatil15
Associate III

For further debugging, I have added delay before and after stop2 mode and it works fine, but not sure is it the correct way of doing this.

HAL_Delay(1);
LowPowerMode();
HAL_Delay(1);

Here I need solution where I can m

Can you give me any solution where I can automate the delay. I mean if we can monitor the system wakeup is complete or not then only go ahead, or else wait for some time, like a sample code below?

while(isSystemWakeup())
{
//continue to wait
}