Правильный способ деактивации SPI в полудуплексном/симплексном режиме STM32F4

Я пытаюсь изменить STM32F4 с ведомого на ведущее через определенное время, отправить сообщение в качестве ведущего и вернуться к ведомому. Я обнаружил, что настройка SPI как slave_rxonly и включение SPI приведет к тому, что часы неожиданно отправят часы, как только я снова настрою устройство в качестве ведущего. Без отправки каких-либо данных. Я предполагаю, что это потому, что я либо неправильно инициализирую периферийное устройство, либо неправильно его деинициализирую.

Это мой основной цикл.

  while (1)
  {
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
      MX_SPI1_Init(); /* This configures master */
      HAL_Delay(10);
 
      sendHelloWorld();
      configSlave(); /* Configures slave mode */
      __HAL_SPI_ENABLE(&hspi1); /* Enabling the device in this mode generates a continous clock during master init */
 
      HAL_Delay(100);
 
      HAL_SPI_DeInit(&hspi1);   /* Disables SPI and de-initializes the peripheral */
  }

Моя основная конфигурация:

  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_256;
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi1.Init.CRCPolynomial = 10;
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
  {
    Error_Handler();
  }

Моя конфигурация ведомого:

if(HAL_SPI_DeInit(&hspi1) != HAL_ERROR)
{
       /* SPI1 parameter configuration*/
    hspi1.Instance = SPI1;
    hspi1.Init.Mode = SPI_MODE_SLAVE;
    hspi1.Init.Direction = SPI_DIRECTION_2LINES_RXONLY;
    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.FirstBit = SPI_FIRSTBIT_MSB;
    hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
    hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
    hspi1.Init.CRCPolynomial = 10;
 
    if (HAL_SPI_Init(&hspi1) != HAL_OK)
    {
        Error_Handler();
    }
 
}

а это осциллограмма моего логического анализатора. Как только я запускаю функцию MX_SPI1_Init() после включения SPI в качестве ведомого, генерируются часы. Оранжевые часы — это часы, и, как вы можете видеть — из-за задержки в 10 мс — они включаются сразу после инициализации в качестве мастера. введите здесь описание изображения

Какие-нибудь мысли? Я боролся с этой проблемой больше недели и перепробовал много вещей.


person Farynx    schedule 23.04.2021    source источник


Ответы (1)


Возможно, мусорная функция HAL случайно временно меняется на master rx-only. Различные функции HAL наивны в том порядке, в котором они пишут в регистры, и создают подобные глюки. Попробуйте позвонить HAL_SPI_DeInit перед повторной настройкой. В качестве альтернативы просто полностью откажитесь от HAL.

Master RX-only всегда должен слепо выводить часы. Если вы хотите контролировать, когда часы отправляются, используйте режим master tx и rx, а затем запишите тот же объем фиктивных данных, который вы хотите прочитать. Если вы хотите, чтобы MOSI оставался в трех состояниях и не отправлял фиктивные данные, вы можете изменить вывод на режим GPIO, пока вы это делаете.

person Tom V    schedule 23.04.2021
comment
Да. HAL был мучением, и мне, скорее всего, придется создать свою собственную реализацию, однако я думал, что будет проще поэкспериментировать с HAL заранее. Кто-то в сообществе ST посоветовал мне никогда не отключать SPI (рег. SPE) и просто менять конфигурацию master/slave. Это решило проблему, но я не думаю, что это должно быть правильным способом. - person Farynx; 23.04.2021
comment
Если это решило вашу проблему, не могли бы вы принять ответ с зеленой галочкой слева? Спасибо. - person Tom V; 29.04.2021