0
\$\begingroup\$

I'm trying to execute the SPI example from STM32Cube using a STM32F429 board and a STM32F4 board. The first has 180MHz of clock and the second one has 168MHz, both with similar Arm cortex-M3 microcontrollers.

I am using the HAL library to access the peripherals and I am configuring it with this:

main.c ==>

  SpiHandle.Instance               = SPI4;
  SpiHandle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;
  SpiHandle.Init.Direction         = SPI_DIRECTION_2LINES;
  SpiHandle.Init.CLKPhase          = SPI_PHASE_1EDGE;
  SpiHandle.Init.CLKPolarity       = SPI_POLARITY_HIGH;
  SpiHandle.Init.CRCCalculation    = SPI_CRCCALCULATION_DISABLE;
  SpiHandle.Init.CRCPolynomial     = 7;
  SpiHandle.Init.DataSize          = SPI_DATASIZE_8BIT;
  SpiHandle.Init.FirstBit          = SPI_FIRSTBIT_MSB;
  SpiHandle.Init.NSS               = SPI_NSS_SOFT;
  SpiHandle.Init.TIMode            = SPI_TIMODE_DISABLE;
  if(HAL_SPI_Init(&SpiHandle) != HAL_OK)
  {
    /* Initialization Error */
    Error_Handler();
  }

stm32f4xx_hal_msp.c ==>

void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)
{
  GPIO_InitTypeDef  GPIO_InitStruct;

  /*##-1- Enable peripherals and GPIO Clocks #################################*/
  /* Enable GPIO TX/RX clock */
  SPIx_SCK_GPIO_CLK_ENABLE();
  SPIx_MISO_GPIO_CLK_ENABLE();
  SPIx_MOSI_GPIO_CLK_ENABLE();
  /* Enable SPI clock */
  SPIx_CLK_ENABLE(); 

  /*##-2- Configure peripheral GPIO ##########################################*/  
  /* SPI SCK GPIO pin configuration  */
  GPIO_InitStruct.Pin       = SPIx_SCK_PIN;
  GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull      = GPIO_PULLUP;
  GPIO_InitStruct.Speed     = GPIO_SPEED_LOW;
  GPIO_InitStruct.Alternate = SPIx_SCK_AF;

  HAL_GPIO_Init(SPIx_SCK_GPIO_PORT, &GPIO_InitStruct);

  /* SPI MISO GPIO pin configuration  */
  GPIO_InitStruct.Pin = SPIx_MISO_PIN;
  GPIO_InitStruct.Alternate = SPIx_MISO_AF;

  HAL_GPIO_Init(SPIx_MISO_GPIO_PORT, &GPIO_InitStruct);

  /* SPI MOSI GPIO pin configuration  */
  GPIO_InitStruct.Pin = SPIx_MOSI_PIN;
  GPIO_InitStruct.Alternate = SPIx_MOSI_AF;

  HAL_GPIO_Init(SPIx_MOSI_GPIO_PORT, &GPIO_InitStruct);

  /*##-3- Configure the NVIC for SPI #########################################*/
  /* NVIC for SPI */
  HAL_NVIC_SetPriority(SPIx_IRQn, 0, 1);
  HAL_NVIC_EnableIRQ(SPIx_IRQn);
}

Both, master and slave have the same configuration. The problem is that the slave receives the data correctly but the master has some time of operation in the last bit of each byte. For example, I sent {0x01, 0x00, 0x00} and master received {0x00, 0x01, 0x00}. It seams to me that it is doing a OR operation with the last bit or simple substituting it by the last bit from the last byte received.

Thanks!

\$\endgroup\$
1
\$\begingroup\$

Apparently, the problem was that the ground was not connected. My shame, sorry!

\$\endgroup\$
  • \$\begingroup\$ Ha! That has happened to me so many times :) Thanks for letting us know. I'll leave my answer in case it helps someone else... \$\endgroup\$ – bitsmack Oct 6 '15 at 17:50
1
\$\begingroup\$

It's possible that the problem is in the application code instead of the initialization routines.

Generally the master device will send a command to the slave requesting information. Then the master provides enough clock pulses for the slave to reply with the requested data.

The issue is that the master is sending and receiving at the same time. While the command message is being clocked out of the TX register, the RX register is also being populated. But the slave isn't sending anything yet because it is still receiving the command. The end result is that the master now has a byte in its RX buffer which needs to be discarded. This value is generally {0x00} or {0xFF} depending on the the idle state of the MISO line.

To discard the byte in the STM32 you need to read the Data Register. I expect you'll use SPI_I2S_ReceiveData() or something similar.

After the command is sent (and the RX register is cleared), the master sends "dummy bytes" so that it creates clock pulses for the slave. This can generally be any value, but this depends on the slave.

Try sending {0x01, 0x02, 0x03}. If the master receives {0x00, 0x01, 0x02} then you need to alter your driver code to discard the first byte.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.