2015-09-17 02:20 PM
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!'');}
2015-09-18 07:10 AM
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 thehttp://www.st.com/web/en/resource/technical/document/application_note/DM00164538.pdf
Application note about Migration of microcontroller applications from STM32F42xxx/STM32F43xxx to STM32F74xxx/STM32F75xxxAlso 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 –2015-09-18 09:24 AM
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: 0HAL STATUS: 0WHO AM I: 0//should be 104
Well it seems i get like spi is working but maybe it is wrongly implemented?2015-09-18 09:24 AM
null
2015-09-18 12:17 PM
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!
2015-09-18 01:52 PM
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