cancel
Showing results for 
Search instead for 
Did you mean: 

Issues with SPI using HAL

EDaws.1
Associate II

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

8 REPLIES 8
LMI2
Lead

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.

S.Ma
Principal

use transmitreceive function

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

LMI2
Lead

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.

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

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);
   }

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

LMI2
Lead

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.