cancel
Showing results for 
Search instead for 
Did you mean: 

Moving from STM32L476xx to STM32L4R9xx

machinehum
Associate II

After spending some time looking into the R9 I decided to make the switch. I've been developing on the 76 for a while now. I read the migration document and it doesn't look like there are any differences.

Right now I'm having issues with spi and sd card / fatfs stuff. After several days of reading I really can't figure out what's goin on. I've changed the linker script, startup.s asm, and the define in the Makefile. I know the sdio driver uses an internal DMA, so I just pulled out the DMA stuff and linked up a callback... No dice. For the spi I changed the clock divider because I'm running the hclk faster (120)

I'll post some code tommorow but I have to be missing some major component...​

3 REPLIES 3

Looks like you've got DMA on SDMMC handled differently on L4+

CLOCKDIV math also different, and peripheral clock sourcing. So CLKCR and HSI/PLL sources

Perhaps check command line option/defines, and merge in example code from an L4+ BSP

 RCC_OscInitTypeDef    RCC_OscInitStruct;

 RCC_PeriphCLKInitTypeDef RCC_PeriphClkInit;

 /* Check whether HSI48 is enabled or not */

 HAL_RCC_GetOscConfig(&RCC_OscInitStruct);

 if(RCC_OscInitStruct.HSI48State != RCC_HSI48_ON)

 {

  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48;

  RCC_OscInitStruct.HSI48State   = RCC_HSI48_ON;

  RCC_OscInitStruct.PLL.PLLState  = RCC_PLL_NONE;

  if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

  {

   while(1) {}

  }

 }

 /* Configure the SDMMC1 clock source. The clock is derived from the HSI48 */

 RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SDMMC1;

 RCC_PeriphClkInit.Sdmmc1ClockSelection = RCC_SDMMC1CLKSOURCE_HSI48;

 if(HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit) != HAL_OK)

 {

  while(1) {}

 }

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

I'm not using the HSI48, I routing through some PLLs to generate my clock for SDMMC1. Here is my clock code.

#ifndef __CLOCK_H
#define __CLOCK_H
 
/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
 
  /** Configure the main internal regulator output voltage 
  */
  if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1_BOOST) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
  RCC_OscInitStruct.MSIState = RCC_MSI_ON;
  RCC_OscInitStruct.MSICalibrationValue = 0;
  RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI;
  RCC_OscInitStruct.PLL.PLLM = 1;
  RCC_OscInitStruct.PLL.PLLN = 60;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV5;
  RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
  RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  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_5) != HAL_OK)
  {
    Error_Handler();
  }
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2|RCC_PERIPHCLK_SDMMC1
                              |RCC_PERIPHCLK_OSPI;
  PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
  PeriphClkInit.OspiClockSelection = RCC_OSPICLKSOURCE_SYSCLK;
  PeriphClkInit.Sdmmc1ClockSelection = RCC_SDMMC1CLKSOURCE_PLLP;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  {
    Error_Handler();
  }
}
 
#endif /* __CLOCK_H*/

Here's my sd init

sd::sd(SD_HandleTypeDef &sdi)
:rsd(sdi),SDMounted(false), _error(false)
{
  __HAL_RCC_SDMMC1_CLK_ENABLE();
  __HAL_RCC_DMAMUX1_CLK_ENABLE();
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  
  rsd.Instance = SDMMC1;
  rsd.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
  rsd.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
  rsd.Init.BusWide = SDMMC_BUS_WIDE_1B; 
  rsd.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
  rsd.Init.ClockDiv = 64;
  
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();
  
  GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12; 
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF12_SDMMC1;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
 
  GPIO_InitStruct.Pin = GPIO_PIN_2;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF12_SDMMC1;
  HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
  
  HAL_SD_Init(&rsd);
 
  HAL_SD_RegisterCallback(&rsd, HAL_SD_READ_DMA_DBL_BUF0_CPLT_CB_ID, &rxcb);
  HAL_SD_RegisterCallback(&rsd, HAL_SD_WRITE_DMA_DBL_BUF0_CPLT_CB_ID, &txcb);
  HAL_SD_RegisterCallback(&rsd, HAL_SD_READ_DMA_DBL_BUF1_CPLT_CB_ID, &rxcb);
  HAL_SD_RegisterCallback(&rsd, HAL_SD_WRITE_DMA_DBL_BUF1_CPLT_CB_ID, &txcb);
 
  //rsd.Read_DMADblBuf1CpltCallback(SD_HandleTypeDef*) = &txcb; 
  //rsd.Write_DMADblBuf1CpltCallback(SD_HandleTypeDef*) = &rxcb; 
  
  /* Enable the Global Interrupt*/
  HAL_NVIC_SetPriority(SDMMC1_IRQn, 6, 1);
  HAL_NVIC_EnableIRQ(SDMMC1_IRQn);
 
  mount(); //Mount the SD card.
}

machinehum
Associate II

Alright I've gotten the spi working again by calling

__HAL_RCC_DMAMUX1_CLK_ENABLE();

Hopefully it's something similar to this with the sd card stuff