SPI on stm32 (bare metal) question

Thread Starter

irmanao

Joined Apr 29, 2017
87
I am trying to code the stm32h743 for spi communication and i can't seem to transmit. I am using PA5 as SCK and PD7 as MOSI. I read the procedure required that is in the reference manual (49.4.9 https://www.st.com/resource/en/reference_manual/dm00314099.pdf ) and wrote the code below but it doesn't transmit 0x3 (checked with oscilloscope).
Code:
  RCC->AHB4ENR  |= (1 << 0) | (1 << 1) | (1 << 3);  // enable gpio clocks

  GPIOA->MODER  &= ~(0x3 << 10) & ~(0x3 << 12);  // enable alternate functions for gpioa and d
  GPIOA->MODER  |= (0x2 << 10) | (0x2 << 12);     
  GPIOD->MODER  &= ~(0x3 << 14);
  GPIOD->MODER  |= (0x2 << 14);

  GPIOA->AFR[0] &= ~(0xF << 20) & ~(0xF << 24);   // choose alternate function SPI (AF5)
  GPIOA->AFR[0] |= (0x5 << 20)  | (0x5 << 24);
  GPIOD->AFR[0] &= ~(0xF << 28);
  GPIOD->AFR[0] |= (0x5 << 28);

  RCC->APB2ENR = 0x1000;  // enable spi clock
  SPI1->CFG2    |= (1 << 22);  // master mode
  SPI1->CFG1    &= ~(0x1F << 0);  // 8bit mode
  SPI1->CFG1    |= (0x7 << 0);  

  SPI1->CR1     |= (1<<9) | (1<<0);  // spi enable and master transfer start
  *(volatile uint8_t *)&SPI1->TXDR = 0x3;  // send 0x3
I checked with the debugger and all the settings are configured correctly to all the registers up until the last two lines where i don't see any change and can't transmit anything. Any ideas? Also, am i missing any other settings for SPI configuration?
thanks
 

MrChips

Joined Oct 2, 2009
34,726
It is not a good idea to use literal constants when configuring hardware. Use the definitions in the library supplied.
For me to check your code I have to go and see exactly which bit you are enabling, which is a pain.
You can also use CubeMX which will create the initialization code for you.
 

Thread Starter

irmanao

Joined Apr 29, 2017
87
Oh got it. I checked the library and understood what you mean. I'll make the adjustments and come back.
I am trying to learn more about what's actually going on with these microcontrollers so i'll stay away from cube for now.
thanks
 

Thread Starter

irmanao

Joined Apr 29, 2017
87
Ok, i did some changes and i hope it's more readable now.
Code:
RCC->AHB4ENR |= RCC_AHB4ENR_GPIOAEN;   // clock enable for gpio A,B,D
RCC->AHB4ENR |= RCC_AHB4ENR_GPIODEN;          
RCC->AHB4ENR |= RCC_AHB4ENR_GPIOBEN;
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;   // enable SPI clock

GPIOA->MODER &= ~GPIO_MODER_MODER5;   // enable alternate functions for gpioa and d
GPIOA->MODER |= GPIO_MODER_MODER5_1;  // 0b10 for alternate function, (PIN5)
GPIOA->AFR[0] |= (0x05 << 5 * 4);      //  AF5 for SPI which is 0101 (it's a 4bit variation)

GPIOA->MODER &= ~GPIO_MODER_MODER6;  // PIN6
GPIOA->MODER |= GPIO_MODER_MODER6_1;
GPIOA->AFR[0] |= (0x05 << 6 * 4);

GPIOD->MODER &= ~GPIO_MODER_MODER7;  // PIN7
GPIOD->MODER |= GPIO_MODER_MODER7_1;
GPIOD->AFR[0] |= (0x05 << 7 * 4);

SPI1->CFG1=(7u << SPI_CFG1_DSIZE_Pos);  // 8bit data size
SPI1->CFG2|=SPI_CFG2_MASTER ;  // master mode
SPI1->CR1|=SPI_CR1_SPE;           // spi enable
SPI1->CR1|=SPI_CR1_CSTART;        // transfer start
*(volatile uint8_t *)&SPI1->TXDR = 0x3;
I still get the same results as before.
 
Last edited:

MrChips

Joined Oct 2, 2009
34,726
I only write to hw registers when I have to do so. I usually use the libraries supplied by ST.

Here are some of my code snippets:
Code:
void InitSPI2(void)
{
  SPI_HandleTypeDef SpiHandle;
  GPIO_InitTypeDef  GPIO_InitStruct;

     __HAL_RCC_GPIOB_CLK_ENABLE(); // enable GPIOB clock
     __HAL_RCC_GPIOI_CLK_ENABLE(); // enable GPIOI clock
     __HAL_RCC_SPI2_CLK_ENABLE();  // enable SPI2 clock

   //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_HIGH;
    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);

  SpiHandle.Init.Mode = SPI_MODE_MASTER;
  SpiHandle.Instance               = SPIx;
  SpiHandle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
  SpiHandle.Init.Direction         = SPI_DIRECTION_2LINES;
  SpiHandle.Init.CLKPhase          = SPI_PHASE_1EDGE;
  SpiHandle.Init.CLKPolarity       = SPI_POLARITY_LOW;
  SpiHandle.Init.DataSize          = SPI_DATASIZE_16BIT;
  SpiHandle.Init.FirstBit          = SPI_FIRSTBIT_LSB;
  SpiHandle.Init.TIMode            = SPI_TIMODE_DISABLE;
  SpiHandle.Init.CRCCalculation    = SPI_CRCCALCULATION_DISABLE;
  SpiHandle.Init.CRCPolynomial     = 7;
  SpiHandle.Init.NSS               = SPI_NSS_SOFT;
  HAL_SPI_Init(&SpiHandle);

    __HAL_SPI_ENABLE(&SpiHandle);
}
You can compare and see if there is something you are missing.
 
Top