cancel
Showing results for 
Search instead for 
Did you mean: 

Porting STM32F4 SPI -> STM32F7 SPI

hitsumen
Associate II
Posted on September 17, 2015 at 23:20

Good day,

 

 

I tried to port STM32F4discovery SPI to STM32F7discovery SPI, without any luck.

 

 

Can you please help me with that.

 

 

Here is my code.

 

 

I want to port this function:

uint8_t SPI_SEND_DATA(uint8_t data){

 

  /* Wait if TXE cleared, Tx FIFO is full. */

  while ((SPI2->SR & TXE) == 0);

  SPI2->DR = data;

 

  /* Wait if RNE cleared, Rx FIFO is empty. */

while ((SPI2->SR & RXNE) == 0);

  return SPI2->DR;

}

to f7 without any luck:

SPI_HandleTypeDef spi2_;

uint8_t SPI_SEND_DATA(uint8_t data){

 

  while((spi2_.Instance->SR & SPI_FLAG_TXE) == 0);

 

spi2_.Instance->DR = data;

   

 

while((spi2_.Instance->SR & SPI_FLAG_RXNE) == 0);

 

return spi2_.Instance->DR;

}

or:

uint8_t SPI_SEND_DATA(uint8_t data){

  uint8_t data_return;  

 

HAL_SPI_TransmitReceive(&spi2_, &data, &data_return, 1, 5000);

 

return data_return;

}

Here is my init function:

void spi2_init(void){

   

  GPIO_InitTypeDef  GPIO_InitStruct;

    

 __HAL_RCC_GPIOI_CLK_ENABLE();

//CS CLOCK

  __HAL_RCC_GPIOI_CLK_ENABLE();

//SCK CLOCK

  __HAL_RCC_GPIOB_CLK_ENABLE();

//MISO CLOCK

  __HAL_RCC_GPIOB_CLK_ENABLE();

//MOSI CLOCK

  

  __HAL_RCC_SPI2_CLK_ENABLE();

//SPI CLOCK

     

  GPIO_InitStruct.Mode  = GPIO_MODE_OUTPUT_PP;

  GPIO_InitStruct.Pull  = GPIO_PULLUP;

  GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;

  GPIO_InitStruct.Pin = GPIO_PIN_0;       

  HAL_GPIO_Init(GPIOI, &GPIO_InitStruct); 

//PI0 CS

      

  GPIO_InitStruct.Pin       = GPIO_PIN_1;

  GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;

  GPIO_InitStruct.Pull      = GPIO_PULLDOWN;

  GPIO_InitStruct.Speed     = GPIO_SPEED_HIGH;

  GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;

  HAL_GPIO_Init(GPIOI, &GPIO_InitStruct);

//PI1 SCK

  GPIO_InitStruct.Pin = GPIO_PIN_14;

  GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;

  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

//PB14 MISO

  GPIO_InitStruct.Pin = GPIO_PIN_15;

  GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;

  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

//PB15 MOSI

  spi2_.Instance               = SPI2;

  spi2_.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;

  spi2_.Init.Direction         = SPI_DIRECTION_2LINES;

  spi2_.Init.CLKPhase          = SPI_PHASE_1EDGE;

  spi2_.Init.CLKPolarity       = SPI_POLARITY_LOW;

  spi2_.Init.DataSize          = SPI_DATASIZE_8BIT;

  spi2_.Init.FirstBit          = SPI_FIRSTBIT_MSB;

  spi2_.Init.TIMode            = SPI_TIMODE_DISABLE;

  spi2_.Init.CRCCalculation    = SPI_CRCCALCULATION_DISABLE;

  spi2_.Init.CRCPolynomial     = 7;

  spi2_.Init.NSS               = SPI_NSS_SOFT;

  spi2_.Init.Mode = SPI_MODE_MASTER;

  if(HAL_SPI_Init(&spi2_) != HAL_OK)

  {

  printf(''\nSPI INIT ERROR!'');

  }

 

printf(''\nSPI INIT OK!'');

}

5 REPLIES 5
Nesrine M_O
Lead II
Posted on September 18, 2015 at 16:10

Hi kovaliov.nikolaj,

1- how it does not work exactly?

2- Where it get stuck?

3- When debugging, are there any error flags or missed configuration bits?

4- The STM32F42xxx/F43xxx and STM32F74xxx/F75xxx implement different features on the SPI, I suggest you to have a look to the SPI paragraph in the

http://www.st.com/web/en/resource/technical/document/application_note/DM00164538.pdf

 Application note about Migration of microcontroller applications from STM32F42xxx/STM32F43xxx to STM32F74xxx/STM32F75xxx

Also try to start from SPI examples under STM32Cube F7 package, it may be very helpful:

STM32Cube_FW_F7_V1.1.0\Projects\STM32746G-Discovery\Examples\SPI

-Syrine –
hitsumen
Associate II
Posted on September 18, 2015 at 18:24

uint8_t read_spi2_reg(uint8_t ReadAddr)

{   

  uint8_t data;

  ReadAddr |= (uint8_t)READWRITE_CMD; //READWRITE_CMD == 0x80

  

 

/* Set chip select Low at the start of the transmission */

  MPU6000_CS_LOW();

  

 

/* Send the Address of the indexed register */

  spi2_put(ReadAddr); 

  

 

/* Receive the data that will be read from the device (MSB First) */

  data = spi2_put(DUMMY_BYTE); //DUMMY_BYTE == 0

 

  

/* Set chip select High at the end of the transmission */

 

  MPU6000_CS_HIGH();

  return data;

}

uint8_t spi2_put(uint8_t data){

 

uint8_t data_return;  

printf(''\nHAL STATUS: %d'', HAL_SPI_TransmitReceive(&spi2_, &data, &data_return, 1, 5000));

return data_return;

}

//main:

spi2_init();

printf(''\nWHO AM I: %d'', read_spi2_reg(0x75));

//debug:

SPI INIT OK!

HAL STATUS: 0

HAL STATUS: 0

WHO AM I: 0

//should be 104

Well it seems i get like spi is working but maybe it is wrongly implemented?

hitsumen
Associate II
Posted on September 18, 2015 at 18:24

null

leogarberoglio
Associate III
Posted on September 18, 2015 at 21:17

what is inside of

spi2_init()

? I have this code for mpu6000 and stm32f411:

SPI_HandleTypeDef hspi2;
/* SPI2 init function */
void MX_SPI2_Init(void)
{
//SPI2 is on APB1. APB1 max freq is 42 or 50 MHz (CCLK/2)
//So 1MHz is max mpu6000 config freq. We need a division by 42/
//We choose 64 and obtain 42MHz/64 = 656Khz.
hspi2.Instance = SPI2;
hspi2.Init.Mode = SPI_MODE_MASTER;
hspi2.Init.Direction = SPI_DIRECTION_2LINES;
//TODO: I can't figure out how to work on 16bit mode....
hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi2.Init.NSS = SPI_NSS_HARD_OUTPUT;
hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;
hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi2.Init.TIMode = SPI_TIMODE_DISABLED;
hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED;
HAL_SPI_Init(&hspi2);
}
void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(hspi->Instance==SPI2)
{
/* Peripheral clock enable */
__SPI2_CLK_ENABLE();
/**SPI2 GPIO Configuration 
PC2 ------> SPI2_MISO
PC3 ------> SPI2_MOSI
PB10 ------> SPI2_SCK
PB12 ------> SPI2_NSS 
*/
GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_10; //|GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* Peripheral interrupt init*/
HAL_NVIC_SetPriority(SPI2_IRQn, 0, 5);
HAL_NVIC_EnableIRQ(SPI2_IRQn);
}
}
void MPU6000_init16(void)
{
// MPU-6000 maximum SPI clock is specified as 1 MHz for all registers
// however the datasheet states that the sensor and interrupt registers
// may be read using an SPI clock of 20 Mhz
// As these register accesses are one time only during initial setup lets be
// conservative and only run the SPI bus at half the maximum specified speed
HAL_StatusTypeDef err;
// need at least 60 msec delay here
HAL_Delay(60);
err = writeMPUSPIreg16(MPUREG_PWR_MGMT_1, BIT_H_RESET);
// 10msec delay seems to be needed for AUAV3 (MW's prototype)
HAL_Delay(10);
// Wake up device and select GyroZ clock (better performance)
err = writeMPUSPIreg16(MPUREG_PWR_MGMT_1, MPU_CLK_SEL_PLLGYROZ);
// Disable I2C bus (recommended on datasheet)
err = writeMPUSPIreg16(MPUREG_USER_CTRL, BIT_I2C_IF_DIS);
// SAMPLE RATE
err = writeMPUSPIreg16(MPUREG_SMPLRT_DIV, 4); // Sample rate = 200Hz Fsample= 1Khz/(N+1) = 200Hz
// scaling & DLPF
err = writeMPUSPIreg16(MPUREG_CONFIG, BITS_DLPF_CFG_42HZ);
// writeMPUSPIreg16(MPUREG_GYRO_CONFIG, BITS_FS_2000DPS); // Gyro scale 2000º/s
err = writeMPUSPIreg16(MPUREG_GYRO_CONFIG, BITS_FS_500DPS); // Gyro scale 500º/s
err = writeMPUSPIreg16(MPUREG_ACCEL_CONFIG, BITS_FS_2G); // Accel scele 2g, g = 8192
// INT CFG => Interrupt on Data Ready, totem-pole (push-pull) output INT: Clear on any read
err = writeMPUSPIreg16(MPUREG_INT_PIN_CFG, BIT_INT_LEVEL | BIT_INT_RD_CLEAR);
// INT: Raw data ready
err = writeMPUSPIreg16(MPUREG_INT_ENABLE, BIT_DATA_RDY_EN);
}
// Blocking 16 bit write to SPI
HAL_StatusTypeDef writeMPUSPIreg16(uint8_t addr, uint8_t cmd)
{
HAL_StatusTypeDef err;
//HAL_SPI_Transmit expect 8 bit pointer on pData parameter, so
//I have to do this:
uint8_t dato[2] = {0,0};
dato[0] = addr;
dato[1] = cmd;
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET);
err = HAL_SPI_Transmit(&hspi2, dato, 2, 10);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET);
// this delay is necessary; it appears that SS must be deasserted for one or
// more SPI clock cycles between writes.
// TODO: It's 1 mseg delay, it would be 2useg. Check on MPU6000 data sheet this issue
HAL_Delay(1);
return err;
}

as you can see there is a few thing that must be take care of. Regards!
hitsumen
Associate II
Posted on September 18, 2015 at 22:52

Hi,

I hate all that cube HAL libraries, but found the problem.

Changed PI0 CS pin to PB4, worked for me.

I use that MPU6000 only for test spi, do not need library.

I want to connect VS1063 audio encoder.

//Nikolaj