異なるSPImodeのデバイスを同一バスに接続する

加速度センサMPU6500と磁気エンコーダAS5047Dを一つのSPIで接続したのですが、後々データシート確認するとSPImode(クロック極性)が異なることに気づきました。

SPIペリフェラルを一旦無効化してからCPOLとCPHAレジスタを変更すればokです

SPIを無効化しないとクロック数が増えたり減ったりおかしなことになります(なりました)。ペリフェラルの状態が残って悪さしてるんですかね。

  __HAL_SPI_DISABLE(&hspi1);
  LL_SPI_SetClockPolarity(hspi1.Instance, device->CLKPolarity);
  LL_SPI_SetClockPhase(hspi1.Instance, device->CLKPhase);
  __HAL_SPI_ENABLE(&hspi1);
  
  /* CSアサート */
  HAL_GPIO_WritePin(device->GPIOx, device->GPIOPin, RESET);
  HAL_SPI_TransmitReceive_DMA(&hspi1, device->TxData, device->RxData, device->TxRxBytes);

↓ST提供のLLライブラリから取ってきました。(STM32CubeMXの自動生成でHALとLL両方使えないバグがあるらしくHALを選択するとLLファイル群が消え、LLを選択するとHALファイル群が消えてしまいます…………仕方なく適当なヘッダファイルに以下のコードを張り付けて使用してます。)

/** @defgroup SPI_LL_EC_PHASE Clock Phase
  * @{
  */
#define LL_SPI_PHASE_1EDGE                 0x00000000U               /*!< First clock transition is the first data capture edge  */
#define LL_SPI_PHASE_2EDGE                 (SPI_CR1_CPHA)            /*!< Second clock transition is the first data capture edge */
/**
  * @}
  */

/** @defgroup SPI_LL_EC_POLARITY Clock Polarity
  * @{
  */
#define LL_SPI_POLARITY_LOW                0x00000000U               /*!< Clock to 0 when idle */
#define LL_SPI_POLARITY_HIGH               (SPI_CR1_CPOL)            /*!< Clock to 1 when idle */
/**
  * @}
  */

/**
  * @brief  Set clock phase
  * @note   This bit should not be changed when communication is ongoing.
  *         This bit is not used in SPI TI mode.
  * @rmtoll CR1          CPHA          LL_SPI_SetClockPhase
  * @param  SPIx SPI Instance
  * @param  ClockPhase This parameter can be one of the following values:
  *         @arg @ref LL_SPI_PHASE_1EDGE
  *         @arg @ref LL_SPI_PHASE_2EDGE
  * @retval None
  */
__STATIC_INLINE void LL_SPI_SetClockPhase(SPI_TypeDef *SPIx, uint32_t ClockPhase)
{
  MODIFY_REG(SPIx->CR1, SPI_CR1_CPHA, ClockPhase);
}

/**
  * @brief  Set clock polarity
  * @note   This bit should not be changed when communication is ongoing.
  *         This bit is not used in SPI TI mode.
  * @rmtoll CR1          CPOL          LL_SPI_SetClockPolarity
  * @param  SPIx SPI Instance
  * @param  ClockPolarity This parameter can be one of the following values:
  *         @arg @ref LL_SPI_POLARITY_LOW
  *         @arg @ref LL_SPI_POLARITY_HIGH
  * @retval None
  */
__STATIC_INLINE void LL_SPI_SetClockPolarity(SPI_TypeDef *SPIx, uint32_t ClockPolarity)
{
  MODIFY_REG(SPIx->CR1, SPI_CR1_CPOL, ClockPolarity);
}

ちゃんとクロック極性が変わってます。OK!

コメント