hathach / tinyusb

An open source cross-platform USB stack for embedded system
https://www.tinyusb.org
MIT License
5.01k stars 1.05k forks source link

Port STM32 G4 #1014

Closed philippgurtner closed 2 years ago

philippgurtner commented 3 years ago

Port to the "new" STM32G4 Family

like NUCLEO-G431KB (...but it has no USB-Conn)

synopsys or fsdev ?

duempel commented 3 years ago

G4 family should use fsdev drivers. I'm not sure if it helps to add a board which does not support USB as it is. But if you try to implement G4 into fsdev dcd, I could test it with a custom hardware.

hathach commented 2 years ago

I have an G474 nucleo and add bsp support for it (blinky and button work fine)

However, the board does not has usb connector and need to use usb breakout cable similar to the nucleo070 board. I tried a bit but couldn't get usb clock/pin set up probably. At the moment, I don't have time to go through its datasheet. If anyone could get the hardware side correct, I could get the rest running.

atdicapf commented 2 years ago

I have an g474 eval with a similar clock setup. Here are the rcc settings that should work:


  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48|RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSI48State = RCC_HSI48_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV4;
  RCC_OscInitStruct.PLL.PLLN = 50;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
  RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;

later on near the bottom:


  */
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB;
  PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_HSI48;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  {
    Error_Handler();
  }```
hathach commented 2 years ago

@atdicapf thank you for your input, I give it a quick try, but it still doesn't seem to work. There is probably something more as well https://github.com/hathach/tinyusb/commit/cd76193f3c82a4d1cd870f91e5538bebd147e710

philippgurtner commented 2 years ago

Hi all @atdicapf Thanks a lot :) Your version works for me to.

@hathach on cd76193 you forget to take something:

family.c: __HAL_RCC_USB_CLK_ENABLE(); is the important

Thanks all you for the great solutions :)

Something i wondering about: with HSE it works but same settings with HSI not...Idk why, both generated with cubemx => on their example it works but on Tinyusb not:

#define HSI_USAGE 0
static inline void board_clock_init(void)
{
// ... other stuff
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48;
  RCC_OscInitStruct.HSI48State = RCC_HSI48_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;

  //identical pll settings for HSI & HSE (no code twice :)
  RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV4;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
  RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;

  #if !HSI_USAGE // HSE... wokring
    RCC_OscInitStruct.OscillatorType |= RCC_OSCILLATORTYPE_HSE;
    RCC_OscInitStruct.HSEState = RCC_HSE_ON;
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
    RCC_OscInitStruct.PLL.PLLN = 50;
  #else
    // Same Config for HSI but seems not working....
    RCC_OscInitStruct.OscillatorType |= RCC_OSCILLATORTYPE_HSI;
    RCC_OscInitStruct.HSIState = RCC_HSI_ON;
    RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
    RCC_OscInitStruct.PLL.PLLN = 75;
  #endif
  HAL_RCC_OscConfig(&RCC_OscInitStruct);
// ... other stuff
}

Here if someone want to test to... => i can give my mx config if you want. Very intresting => the basic CDC from CubeMX works with both of this settings (probably i forgot a single flag to set :/ what i saw, cubemx only changes this)

Thanks again :)

hathach commented 2 years ago

@philippgurtner I am glad it works for you, I have updated the BSP though It stills does not work for me. https://github.com/hathach/tinyusb/commit/51acc3e1b90f42ebb80881a143fe36a4ce45821c . Would you mind telling Which board you are using. It could be hardware setup on my side since g4 nucleo don't have usb and I have to use break out cable https://www.adafruit.com/product/4448 Green is D+, white is D-

image

philippgurtner commented 2 years ago

Hi I Think you mixed up D+ & D- PA12 (CN10 p 12) is D+ (green) PA11 (CN10 p 14) is D- (white) Schematic

I found my "flag" :D In _boardinit() we need to call HAL_InitTick(TICK_INT_PRIORITY); or at least set uwTickPrio = TICK_INT_PRIORITY; Inside HAL_RCC_OscConfig(&RCC_OscInitStruct); in _board_clockinit(): HAL_InitTick(uwTickPrio); get called and it needs uwTickPrio, otherwise systick is not initialised completely... I know you do call SysTick_config() afterwards, but the it seems, that the interrupt is needed. Without it, it hangs up inside the _dcd_stm32fsdev.c l 226 by writing to the USB registers. (I think... with only a little debuging)

finaly: add uwTickPrio = TICK_INT_PRIORITY; to the begining of _boardinit() and HSI works to. (at least on my machine :D)

then you can use the clock setting as it is now (for HSE) or as I provided in the last post (for HSI).

afaik: The problem with the HSI48 is, he is not that accurate to use with usb. We need to sync him with the CRS to the usb SOF. Append to _board_clockinit():

  // Configures CRS
  RCC_CRSInitTypeDef pInit = {0};
  pInit.Prescaler = RCC_CRS_SYNC_DIV1;
  pInit.Source = RCC_CRS_SYNC_SOURCE_USB;
  pInit.Polarity = RCC_CRS_SYNC_POLARITY_RISING;
  pInit.ReloadValue = __HAL_RCC_CRS_RELOADVALUE_CALCULATE(48000000,1000);
  pInit.ErrorLimitValue = 34;
  pInit.HSI48CalibrationValue = 32;

  HAL_RCCEx_CRSConfig(&pInit);

It works, but I don't understand enough to say that it does what it is supposed to do. It's the generated CubeMX code ... Best wishes

hathach commented 2 years ago

@philippgurtner ah right, silly me, I did mixed up D+ and D-. IT works now with HSE, g4nucleo has 24 mhz one, HSE is always more accurate than HSI.