2020-07-06 05:59 AM
Hi,
I'm new to using HAL, and I'm having several issues with setting up the SPI.
I'm using SPI 1 on an STM32F429ZGT6, and using KEIL as my IDE.
I've just tried initializing SPI 1 by configuring GPIOA Pins 5, 6 and 7 for their SPI Alternate functions.
I set up GPIOE Pins 0, 1, 2 and 3 for a manual chip select, and I'm writing to them for an idle high (initializing them as pullup doesn't seem to work).
My project builds and loads onto the board, but the MOSI pin is silent, and putting the scope on the clock pin, the clock line is pulled up once for a few milliseconds, comes back down, and remains that way.
I will also note that the clock idles low, even though I've set the clock polarity to high on my SPI initiailization.
Is there something I'm missing? I don't understand why the SPI lines are acting this way.
SPI_HandleTypeDef SPI_1;
void SPI_INIT(void)
{
__HAL_RCC_SPI1_CLK_ENABLE();
SPI_1.Instance = SPI1;
SPI_1.Init.Mode = SPI_MODE_MASTER;
SPI_1.Init.Direction = SPI_DIRECTION_2LINES;
SPI_1.Init.DataSize = SPI_DATASIZE_8BIT;
SPI_1.Init.CLKPolarity = SPI_POLARITY_HIGH;
SPI_1.Init.CLKPhase = SPI_PHASE_2EDGE;
SPI_1.Init.NSS = SPI_NSS_SOFT;
SPI_1.Init.FirstBit = SPI_FIRSTBIT_MSB;
SPI_1.Init.TIMode = SPI_TIMODE_DISABLE;
SPI_1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
SPI_1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
HAL_SPI_Init(&SPI_1);
}
static void ConfigGPIOA(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
static void ConfigGPIOE(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
__HAL_RCC_GPIOE_CLK_ENABLE();
GPIO_InitStruct.Pin = SPI_CS02_Pin|SPI_CS03_Pin|SPI_CS00_Pin|SPI_CS01_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
//Manually raise all SPI Chip select pins
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_0, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_1, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_2, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_SET);
}
int main(void)
{
HAL_Init();
SystemClock_Config();
// GPIO Init does the initialization for both GPIOA and GPIOE using the functions above
GPIOInit();
SPI_INIT();
for(spibyte=0; spibyte < 4; spibyte++)
{
// Macro for activating Chip Select Line
CS_LOW();
if(spibyte == 0)
{
HAL_SPI_Transmit(&SPI_1, (uint8_t *)0x51, 2, 10);
}
if(spibyte >= 1)
{
HAL_SPI_Transmit(&SPI_1, (uint8_t *)0xFF, 2, 10);
}
_DELAY(TDISCS);
//Macro for deactivating Chip Select Line
CS_HIGH();
}
Update:
Changed the main loop
for(spibyte=0; spibyte < 4; spibyte++)
{
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_1, GPIO_PIN_RESET);
if(spibyte == 0)
{
txBuffer[0] = 0x51;
HAL_SPI_Transmit(&SPI_1, (uint8_t *)txBuffer, 1, 1000);
}
if(spibyte >= 1)
{
txBuffer[0] = 0xFF;
HAL_SPI_Transmit(&SPI_1, (uint8_t *)txBuffer, 1, 1000);
}
_DELAY(TDISCS);
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_1, GPIO_PIN_SET);
}
And here's the RCC Config
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Configure the main internal regulator output voltage
*/
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);
/** Initializes the CPU, AHB and APB busses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
return;
}
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSE;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
return;
}
}
Using 8MHz external oscillator
2020-07-06 08:25 AM
CubeMx settings can be tricky. Perhaps there is something wrong with your settings. NSS is a problem, I had to enable it and then left it be and use my own CS like you. Have you correct clock phase and polarity.
I used code like you and it works now.
HAL_SPI_Transmit(&hspi1,(uint8_t*)txBuffer,2,1000); for initilaizing
and
HAL_SPI_TransmitReceive(&hspi1,(uint8_t*)txBuffer, (uint8_t*)rxBuffer, 8,1000);
for getting some data out of it
I had to do the SPI bus first with bit banging or driving io pins directly with GPIO commands. After that worked I could be certain where the problem was.)
There is my test main.c attached.
2020-07-06 09:39 AM
use transmitreceive function
2020-07-06 01:33 PM
What board is this? Isn't there any conflict with some inboard peripheral? How is it behaving without anything connected? Try wiggling the pins set as GPIO Out. Read out and check content of SPI and GPIO registers.
JW
2020-07-06 02:19 PM
I wonder what this means (uint8_t *)0x51, 2. I am not a programmer but to me it looks like are giving SPI one byte 0x51, but telling it to send two bytes.
2020-07-06 02:34 PM
Hi,
Thanks for the reply, I've set NSS to soft but I can try setting it to hard, but as I understand it NSS has to do with multimaster systems and I'm only working on one master.
Clock and Polarity seem to be initialized correctly based on my SPI_INIT function but it's strange the clock idles low instead of high..
I may need to try sending sample data like you do to initialize. Thanks for the advice
2020-07-06 02:35 PM
Yes that was a mistake, I've changed the code since then
for(spibyte=0; spibyte < 4; spibyte++)
{
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_1, GPIO_PIN_RESET);
if(spibyte == 0)
{
txBuffer[0] = 0x51;
HAL_SPI_Transmit(&SPI_1, (uint8_t *)txBuffer, 1, 1000);
}
if(spibyte >= 1)
{
txBuffer[0] = 0xFF;
HAL_SPI_Transmit(&SPI_1, (uint8_t *)txBuffer, 1, 1000);
}
_DELAY(TDISCS);
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_1, GPIO_PIN_SET);
}
2020-07-06 02:37 PM
Hi, thank you for the reply:
I'm using the processor on a custom board so that's not a problem.
GPIO lines like CS are triggering, but clock and MOSI lines are dead, even after CS lines activate
2020-07-07 12:33 PM
I needed an external pull-up (resistor) on the SPI pins, Then I turned the HW NSS on and newer used it. NSS is nice in theory and a problem in practise. Let it be HW NSS and forget it. When I saw CLK and MOSI signals, I changed Clock phase and edge until MAX31865 started to work. Do you have newest version of CubeMx CPUlibrary.
MAX31865 has low minimum clock rate, so I could first try "manual" SPI that is, driving SPI pins as GPIO pins.