Sonsivri
 
*
Welcome, Guest. Please login or register.
Did you miss your activation email?
March 29, 2024, 07:00:19 07:00


Login with username, password and session length


Pages: 1 2 [All]
Print
Author Topic: STM32H743ZI Nucleo board UART issue  (Read 10724 times)
0 Members and 1 Guest are viewing this topic.
burgic
Newbie
*
Offline Offline

Posts: 34

Thank You
-Given: 9
-Receive: 24


WWW
« on: May 16, 2020, 11:55:20 11:55 »

Hi,

Recently I started a new project on a STM32H743ZI Nucleo board. One of the first steps was to implement Command Line Interface on USART3 and also to use USART3 as a debug output (route printf() to USART3). After re-using and compiling my common code for CLI and UART (a layer above STM HAL) I was able to get a proper output on the serial terminal.

The issue I have (for the first time) is that receiving in interrupt mode is not working well. I do receive the amount of characters I send but the received value is corrupted. To test what I receive I made a code to print back the character received. I print it as a char and also the decimal value (to be able to compare it with values in ASCII table). From that I was able to see that the decimal value is always between 160 and 255 (decimal) and that the reason why I have strange characters at the output.

I checked several times the following:
- All UART init data (baudrate, no of start/stop bits, parity, etc..)
- If all required peripheral clocks are enabled and if GPIOs are initialized for AF.
- System Clock configuration

All of the above mentioned is generated using CubeMX SW and is configured properly.
The toolchain I am using is gcc-arm-none-eabi.
The baudrate is 115200 (also tested with 9600 and with same result).

I also suspect the HSI (because I am currently using one).
In my previous experience I sometimes had issues with corrupted data in IT mode when the CPU data cache and CPU instruction cache are enabled. On this project, they are both disabled, but even if I enable them the result is the same so I do not expect this can make any difference at the moment.

Does anyone have some experience with this issue and maybe a solution or at least an idea what to try next?

P.S. The same code works with STM32F4 and STM32F1 MCUs. The only difference is the name of same registers of STM32H7, but that is handled properly.

Thx.
« Last Edit: May 21, 2020, 09:34:03 09:34 by burgic » Logged
UKFlyer
Newbie
*
Offline Offline

Posts: 25

Thank You
-Given: 40
-Receive: 17


« Reply #1 on: May 16, 2020, 01:26:09 13:26 »

Not something I've seen but I attach my USART3 initialisation in case it is useful

/* USART3 init function */
static void MX_USART3_UART_Init(void)
{

  huart3.Instance = USART3;
  huart3.Init.BaudRate = 38400;
  huart3.Init.WordLength = UART_WORDLENGTH_8B;
  huart3.Init.StopBits = UART_STOPBITS_1;
  huart3.Init.Parity = UART_PARITY_NONE;
  huart3.Init.Mode = UART_MODE_TX_RX;
  huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart3.Init.OverSampling = UART_OVERSAMPLING_16;
  huart3.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart3.Init.Prescaler = UART_PRESCALER_DIV1;
  huart3.Init.FIFOMode = UART_FIFOMODE_DISABLE;
  huart3.Init.TXFIFOThreshold = UART_TXFIFO_THRESHOLD_1_8;
  huart3.Init.RXFIFOThreshold = UART_RXFIFO_THRESHOLD_1_8;
  huart3.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart3) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

}

From  stm32h7xx_hal_msp.c

  else if(huart->Instance==USART3)
  {
  /* USER CODE BEGIN USART3_MspInit 0 */

  /* USER CODE END USART3_MspInit 0 */
    /* Peripheral clock enable */
    __HAL_RCC_USART3_CLK_ENABLE();
  
    /**USART3 GPIO Configuration    
    PD8     ------> USART3_TX
    PD9     ------> USART3_RX
    */
    GPIO_InitStruct.Pin = CONSOLE_TX_Pin|CONSOLE_RX_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF7_USART3;
    HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

    /* USART3 interrupt Init */
    HAL_NVIC_SetPriority(USART3_IRQn, 2, 0);
    HAL_NVIC_EnableIRQ(USART3_IRQn);
  /* USER CODE BEGIN USART3_MspInit 1 */

  /* USER CODE END USART3_MspInit 1 */
  }

Logged
comlekciler
Junior Member
**
Offline Offline

Posts: 40

Thank You
-Given: 73
-Receive: 44

Ph.D.


« Reply #2 on: May 16, 2020, 01:56:48 13:56 »

@burgic, Did you write all the codes yourself or did you make from CubeMX? Now that you have received the data incorrectly, you have a logic error somewhere. I think, try to do it again from CubeMX.
Logged

...none...
burgic
Newbie
*
Offline Offline

Posts: 34

Thank You
-Given: 9
-Receive: 24


WWW
« Reply #3 on: May 16, 2020, 05:30:09 17:30 »

@UKFlyer: Thx, the code I am using is almost the same as yours:

Code:
status_t uart_init( USART_TypeDef* uart, uint32_t baudrate )
{
    status_t           ret  = STATUS_OK;
    HAL_StatusTypeDef  hret = HAL_ERROR;
    UART_HandleTypeDef uart_hdl = {0};

    uart_hdl.Instance                    = uart;
    uart_hdl.Init.BaudRate               = baudrate;
    uart_hdl.Init.WordLength             = UART_WORDLENGTH_8B;
    uart_hdl.Init.StopBits               = UART_STOPBITS_1;
    uart_hdl.Init.Parity                 = UART_PARITY_NONE;
    uart_hdl.Init.Mode                   = UART_MODE_TX_RX;
    uart_hdl.Init.HwFlowCtl              = UART_HWCONTROL_NONE;
    uart_hdl.Init.OverSampling           = UART_OVERSAMPLING_16;
    uart_hdl.Init.OneBitSampling         = UART_ONE_BIT_SAMPLE_DISABLE;
    uart_hdl.Init.ClockPrescaler         = UART_PRESCALER_DIV1;
    uart_hdl.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;

    hret  = HAL_UART_Init( &uart_hdl );

    if ( HAL_OK != hret )
    {
        ret = STATUS_ERROR;
    }
    else
    {
        hret  = HAL_UARTEx_SetTxFifoThreshold( &uart_hdl
                                             , UART_TXFIFO_THRESHOLD_1_8
                                             );
        hret |= HAL_UARTEx_SetRxFifoThreshold( &uart_hdl
                                             , UART_RXFIFO_THRESHOLD_1_8
                                             );
        hret |= HAL_UARTEx_DisableFifoMode( &uart_hdl );
    }

    if ( HAL_OK != hret )
    {
        ret = STATUS_ERROR;
    }
    else
    {
        /* Enable RX interrupt */
        uart->CR1 |= USART_CR1_RXNEIE;
    }

    return ret;
}
Code:
void HAL_UART_MspInit( UART_HandleTypeDef* huart )
{
    GPIO_InitTypeDef GPIO_InitStruct;

    if ( USART2 == huart->Instance )
    {
        /* PD5 ------> USART2_TX */
        /* PD6 ------> USART2_RX */
        __HAL_RCC_USART2_CLK_ENABLE();
        __HAL_RCC_USART2_FORCE_RESET();
        __HAL_RCC_USART2_RELEASE_RESET();
        __HAL_RCC_GPIOD_CLK_ENABLE();

        GPIO_InitStruct.Pin       = GPIO_PIN_5 | GPIO_PIN_6;
        GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Pull      = GPIO_NOPULL;
        GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_LOW;
        GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
        HAL_GPIO_Init( GPIOD, &GPIO_InitStruct );

        HAL_NVIC_SetPriority( USART2_IRQn, 3, 4 );
        HAL_NVIC_EnableIRQ( USART2_IRQn );
        HAL_NVIC_ClearPendingIRQ( USART2_IRQn );
    }

    if ( USART3 == huart->Instance )
    {
        /* PD8 ------> USART3_TX */
        /* PD9 ------> USART3_RX */
        __HAL_RCC_USART3_CLK_ENABLE();
        __HAL_RCC_USART3_FORCE_RESET();
        __HAL_RCC_USART3_RELEASE_RESET();
        __HAL_RCC_GPIOD_CLK_ENABLE();

        GPIO_InitStruct.Pin       = GPIO_PIN_8 | GPIO_PIN_9;
        GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Pull      = GPIO_NOPULL;
        GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_LOW;
        GPIO_InitStruct.Alternate = GPIO_AF7_USART3;
        HAL_GPIO_Init( GPIOD, &GPIO_InitStruct );

        HAL_NVIC_SetPriority( USART3_IRQn, 2, 3 );
        HAL_NVIC_EnableIRQ( USART3_IRQn );
        HAL_NVIC_ClearPendingIRQ( USART3_IRQn );
    }
}

@comlekciler: I used the code generated by CubeMX (as I always do for configuration of the system and peripherals).
Logged
bobcat1
Senior Member
****
Offline Offline

Posts: 295

Thank You
-Given: 4135
-Receive: 89


« Reply #4 on: May 17, 2020, 12:28:23 12:28 »

Hi

I have a similar problem,as far as I remember the problem was the PC terminal software
I replace the terminal software and everithing was normal again
What terminal software are you using?
please ignore my response if the result ,seeing by watching the buffer content using the debugger software.

All the best

Bobi  
« Last Edit: May 17, 2020, 12:30:36 12:30 by bobcat1 » Logged
dennis78
Active Member
***
Offline Offline

Posts: 121

Thank You
-Given: 266
-Receive: 153


« Reply #5 on: May 17, 2020, 07:51:38 19:51 »

I use usart interrupt on stm32h7xx chips without problems. I prefer low level (LL) functions instead full HAL variant because I don't like HAL libs, but for H7 no exist old config libs. I really don't have time and energy to make it for H7 from zero so I use new HAL(with Cube) but only LL variant when I can. I other cases I most time isolate and modify specific HAL functions because in many cases they are not as I want Huh

Your first post is little confused for me.

You wrote "I was able to get a proper output on the serial terminal." for variant without interrupt? If it true, I don't know why HSE or HSI can be problem if you only enable IT mode?!  In over 90% cases I use HSE. Only when I don't use/have any precision time triggered procedures or components I use HSI.

I think your problem is fw or wrong config. Did you try to generate complete code with cube and only add simple echo function in main(without any other interventions in code) and  send/receive characters from terminal?



« Last Edit: May 17, 2020, 08:01:56 20:01 by dennis78 » Logged
burgic
Newbie
*
Offline Offline

Posts: 34

Thank You
-Given: 9
-Receive: 24


WWW
« Reply #6 on: May 17, 2020, 08:09:05 20:09 »

@bobcat1: I tried that already, but no luck. I did sometimes experience that issue but in that case output is messed up anyway. I usually use MobaXterm and Putty.

@dennis78: As you can see from my code posted above I initialize USART in a particular way - I enable interrupts only for receive but transmission is done in blocking mode. Receive interrupt is always enabled and in the interrupt routine I just take the received char and put into a circular buffer and get out of the interrupt routine. I clear the interrupts flags, of course. Therefore, I don't use HAL functions for sending and receiving, but my own. These functions are working for STM32F1xx series and STM32F4xx series, but I understand now what you are trying to point out. It seems that USART peripheral and the Clock tree is far more complicated on STM32H7 MCUs than on the series I used before.
Currently I am testing with simple echo (with my own send and receive functions) but maybe I should test the examples and Cube code first.
Logged
dennis78
Active Member
***
Offline Offline

Posts: 121

Thank You
-Given: 266
-Receive: 153


« Reply #7 on: May 17, 2020, 08:20:14 20:20 »

Ok. Echo with original cube code is good start point for check.

When I start to use H7 I as I wrote above start to do with Cube and HAL (sometime I little modify it) because I don't have time to play with additional H7 specific things, but always it work without any big problems.

Big ARM mcu's has relative complex peripheral structure and manufacturer libs are simple and fastest way how to setup mcu. It isn't only simple register config, sometime is very important a seemingly insignificant sequence of operations in config procedures.

« Last Edit: May 18, 2020, 08:37:03 08:37 by dennis78 » Logged
burgic
Newbie
*
Offline Offline

Posts: 34

Thank You
-Given: 9
-Receive: 24


WWW
« Reply #8 on: May 18, 2020, 08:51:13 08:51 »

@dennis78: I just tried the source code generated out of Cube and simple echo example in non-blocking mode (the simplest variant) and I have the same result. I am not sure what could I try next. I am beginning to suspect that MCU is damaged.

This is the code:

Code:
int main(void)
{

  uint8_t ch;

  HAL_Init();
  SystemClock_Config();

  MX_USART3_UART_Init();

  while (1)
  {
 if( HAL_UART_Receive (&huart3, &ch, 1, 0x1FFFFFF ) == HAL_OK )
 {
 HAL_UART_Transmit( &huart3, &ch, 1, 0x1FFFFFF );
 }
  }

}

Code:
void MX_USART3_UART_Init(void)
{

  huart3.Instance = USART3;
  huart3.Init.BaudRate = 115200;
  huart3.Init.WordLength = UART_WORDLENGTH_8B;
  huart3.Init.StopBits = UART_STOPBITS_1;
  huart3.Init.Parity = UART_PARITY_NONE;
  huart3.Init.Mode = UART_MODE_TX_RX;
  huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart3.Init.OverSampling = UART_OVERSAMPLING_16;
  huart3.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart3.Init.ClockPrescaler = UART_PRESCALER_DIV1;
  huart3.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_RXOVERRUNDISABLE_INIT|UART_ADVFEATURE_DMADISABLEONERROR_INIT;
  huart3.AdvancedInit.OverrunDisable = UART_ADVFEATURE_OVERRUN_DISABLE;
  huart3.AdvancedInit.DMADisableonRxError = UART_ADVFEATURE_DMA_DISABLEONRXERROR;
  if (HAL_UART_Init(&huart3) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetTxFifoThreshold(&huart3, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetRxFifoThreshold(&huart3, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_DisableFifoMode(&huart3) != HAL_OK)
  {
    Error_Handler();
  }

}
« Last Edit: May 18, 2020, 08:54:22 08:54 by burgic » Logged
burgic
Newbie
*
Offline Offline

Posts: 34

Thank You
-Given: 9
-Receive: 24


WWW
« Reply #9 on: May 19, 2020, 06:49:19 06:49 »

After further investigation there was some progress last night.

There is definitely something wrong in the clock configuration. When setting CPU to work on 400 MHz instead of 80 MHz everything works fine. Of course, not only the speed is different in the configuration, for example CSI is used instead of HSI, etc..

This is working configuration:
Code:
void system_clk_cfg( void )
{
    RCC_ClkInitTypeDef       clkinitstruct    = {0};
    RCC_OscInitTypeDef       oscinitstruct    = {0};
    RCC_PeriphCLKInitTypeDef periphinitstruct = {0};

    HAL_PWREx_ConfigSupply( PWR_LDO_SUPPLY );
    __HAL_PWR_VOLTAGESCALING_CONFIG( PWR_REGULATOR_VOLTAGE_SCALE1 );

    while ( 0 == __HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY )) {}

    oscinitstruct.OscillatorType      = RCC_OSCILLATORTYPE_CSI;
    oscinitstruct.CSIState            = RCC_CSI_ON;
    oscinitstruct.CSICalibrationValue = 16;
    oscinitstruct.PLL.PLLState        = RCC_PLL_ON;
    oscinitstruct.PLL.PLLSource       = RCC_PLLSOURCE_CSI;
    oscinitstruct.PLL.PLLM            = 1;
    oscinitstruct.PLL.PLLN            = 200;
    oscinitstruct.PLL.PLLP            = 2;
    oscinitstruct.PLL.PLLQ            = 4;
    oscinitstruct.PLL.PLLR            = 2;
    oscinitstruct.PLL.PLLRGE          = RCC_PLL1VCIRANGE_2;
    oscinitstruct.PLL.PLLVCOSEL       = RCC_PLL1VCOWIDE;
    oscinitstruct.PLL.PLLFRACN        = 0;

    if ( HAL_OK != HAL_RCC_OscConfig( &oscinitstruct ))
    {
        /* Initialization Error */
        while( 1 );
    }

    clkinitstruct.ClockType      = ( RCC_CLOCKTYPE_HCLK  \
                                   | RCC_CLOCKTYPE_SYSCLK    \
                                   | RCC_CLOCKTYPE_PCLK1   \
                                   | RCC_CLOCKTYPE_PCLK2   \
                                   | RCC_CLOCKTYPE_D3PCLK1 \
                                   | RCC_CLOCKTYPE_D1PCLK1
                                   );
    clkinitstruct.SYSCLKSource   = RCC_SYSCLKSOURCE_PLLCLK;
    clkinitstruct.SYSCLKDivider  = RCC_SYSCLK_DIV1;
    clkinitstruct.AHBCLKDivider  = RCC_HCLK_DIV2;
    clkinitstruct.APB3CLKDivider = RCC_APB3_DIV2;
    clkinitstruct.APB1CLKDivider = RCC_APB1_DIV2;
    clkinitstruct.APB2CLKDivider = RCC_APB2_DIV2;
    clkinitstruct.APB4CLKDivider = RCC_APB4_DIV2;

    if ( HAL_OK != HAL_RCC_ClockConfig( &clkinitstruct, FLASH_LATENCY_2 ))
    {
        /* Initialization Error */
        while( 1 );
    }

    periphinitstruct.PeriphClockSelection      = RCC_PERIPHCLK_USART3
                                               | RCC_PERIPHCLK_USART2;
    periphinitstruct.Usart234578ClockSelection =
                                               RCC_USART234578CLKSOURCE_D2PCLK1;

    if ( HAL_OK != HAL_RCCEx_PeriphCLKConfig( &periphinitstruct ))
    {
        /* Initialization Error */
        while( 1 );
    }
}

Thank you all for your help.
Cheers!
Logged
dennis78
Active Member
***
Offline Offline

Posts: 121

Thank You
-Given: 266
-Receive: 153


« Reply #10 on: May 19, 2020, 08:48:37 08:48 »

Good. Your first post confused me or I wrong understand when you wrote " I was able to get a proper output on the serial terminal." It is why I eliminate clock as source of problem.

Without calibration or sync procedure (autobaud option in your case!?) using internal RC oscillators isn't good practice. RC's are not very precision and not very stable.

I just ask to confirm, you generate clock code in Cube and checked that all clock parameters are in appropriate range (no red boxes)?

You can try simple experiment to check clock timing. Generate for example 1kHz on some timer output and check freq with multimeter or look with scope uart byte frame.  

« Last Edit: May 19, 2020, 08:56:37 08:56 by dennis78 » Logged
burgic
Newbie
*
Offline Offline

Posts: 34

Thank You
-Given: 9
-Receive: 24


WWW
« Reply #11 on: May 19, 2020, 10:32:20 10:32 »

Quote
Your first post confused me or I wrong understand when you wrote " I was able to get a proper output on the serial terminal." It is why I eliminate clock as source of problem.
This is because the output was actually always working. So TX on USART3 is OK. I had some debug print when starting the application, but when I wanted to echo the received char then I had these issues and this is the reason why I stated that RX (only) is not functioning.

Quote
Without calibration or sync procedure (autobaud option in your case!?) using internal RC oscillators isn't good practice. RC's are not very precision and not very stable.
I know, but this was a requirement from customer to use internal XTAL (to implement everything on Nucleo boad as is, w/o any modifications to the board). Autobaud is not used, but fixed 115200 baudrate.

Quote
I just ask to confirm, you generate clock code in Cube and checked that all clock parameters are in appropriate range (no red boxes)?
Yes, that is correct. Both times I did this and this is why it confuses me more, especially when their own example was not working.

Quote
You can try simple experiment to check clock timing. Generate for example 1kHz on some timer output and check freq with multimeter or look with scope uart byte frame.
Already did with expected result, it was working fine.

I will compare two clock configurations which I used and try to find what is really the difference and how to make this work.
The most important thing is that I have now something to start with.

Thx for your support!
Logged
h0nk
Senior Member
****
Offline Offline

Posts: 256

Thank You
-Given: 208
-Receive: 230



« Reply #12 on: May 19, 2020, 05:05:30 17:05 »


Hello burgic,

> Nucleo boad
use the MCO-pin of the integrated ST-Link (STM32F103)
to produce a 8 MHz clock for the main controller.
The main controller should be configured for:
- Extern clock
- Quartz osc bypass


Best Regards

Logged
burgic
Newbie
*
Offline Offline

Posts: 34

Thank You
-Given: 9
-Receive: 24


WWW
« Reply #13 on: May 19, 2020, 11:53:50 23:53 »

@h0nk: Thx for the proposal. I'll try this solution as well.
Logged
dennis78
Active Member
***
Offline Offline

Posts: 121

Thank You
-Given: 266
-Receive: 153


« Reply #14 on: May 20, 2020, 08:25:01 08:25 »

I'm not sure, but if you have correctly send procedure clock should not be a problem but who know. What serial interface you use? External adapter or built-in USB/serial interface?
Logged
burgic
Newbie
*
Offline Offline

Posts: 34

Thank You
-Given: 9
-Receive: 24


WWW
« Reply #15 on: May 20, 2020, 08:51:04 08:51 »

@dennis78: I am using built-in USB/Serial IF.
Logged
dennis78
Active Member
***
Offline Offline

Posts: 121

Thank You
-Given: 266
-Receive: 153


« Reply #16 on: May 20, 2020, 09:00:11 09:00 »

Did you try LL code for uart instead HAL?
Logged
burgic
Newbie
*
Offline Offline

Posts: 34

Thank You
-Given: 9
-Receive: 24


WWW
« Reply #17 on: May 20, 2020, 11:14:55 11:14 »

@dennis78: Not yet. I'll try that sometimes in the future. I'm off the schedule now on this project so I need to focus on the next tasks since I lost too much time while debugging the issue above.
Logged
dennis78
Active Member
***
Offline Offline

Posts: 121

Thank You
-Given: 266
-Receive: 153


« Reply #18 on: May 20, 2020, 12:20:35 12:20 »

Ok. Today, if I have time I will make simple echo app with H7 mcu on uart3 and internal RC and I will write here results.

Yes, this is much time for relative simple problem (I think this can be solved quickly), but under this conditions we can't do much more and faster because it need to do many simple tests.
Logged
burgic
Newbie
*
Offline Offline

Posts: 34

Thank You
-Given: 9
-Receive: 24


WWW
« Reply #19 on: May 20, 2020, 12:44:45 12:44 »

@dennis78: Thx, I am looking forward to see result.
Logged
dennis78
Active Member
***
Offline Offline

Posts: 121

Thank You
-Given: 266
-Receive: 153


« Reply #20 on: May 20, 2020, 10:13:10 22:13 »

I made simple app with CSI clock source, 80MHz as you wrote, RX int and all work ok. MCU is STM32H743II
Logged
burgic
Newbie
*
Offline Offline

Posts: 34

Thank You
-Given: 9
-Receive: 24


WWW
« Reply #21 on: May 20, 2020, 10:22:29 22:22 »

@dennis78: With CSI clock source it is working for me as well. It doesn't work with LSI.
Logged
dennis78
Active Member
***
Offline Offline

Posts: 121

Thank You
-Given: 266
-Receive: 153


« Reply #22 on: May 20, 2020, 10:42:22 22:42 »

HSI doesn't work. I can't chose LSI as source.

Problem is clock accuracy. With CSI is about 1-2%. For HSI > 10%  It is what I suspect in previous post. RX internal osc is not good choice without autobaud or similar option.
« Last Edit: May 21, 2020, 09:20:06 09:20 by dennis78 » Logged
burgic
Newbie
*
Offline Offline

Posts: 34

Thank You
-Given: 9
-Receive: 24


WWW
« Reply #23 on: May 21, 2020, 09:03:43 09:03 »

@dennis78: Sorry, I meant HSI, but I wrote LSI (I was too tired when I wrote this message Smiley)

Just to make it more straight, this is the code which was NOT working:
Code:
void system_clk_cfg( void )
{
    RCC_ClkInitTypeDef       clkinitstruct    = {0};
    RCC_OscInitTypeDef       oscinitstruct    = {0};
    RCC_PeriphCLKInitTypeDef periphinitstruct = {0};

    HAL_PWREx_ConfigSupply( PWR_LDO_SUPPLY );
    __HAL_PWR_VOLTAGESCALING_CONFIG( PWR_REGULATOR_VOLTAGE_SCALE1 );

    while ( 0 == __HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY )) {}

    oscinitstruct.OscillatorType      = RCC_OSCILLATORTYPE_HSI;
    oscinitstruct.HSIState            = RCC_HSI_DIV1;
    oscinitstruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
    oscinitstruct.PLL.PLLState        = RCC_PLL_ON;
    oscinitstruct.PLL.PLLSource       = RCC_PLLSOURCE_HSI;
    oscinitstruct.PLL.PLLM            = 4;
    oscinitstruct.PLL.PLLN            = 10;
    oscinitstruct.PLL.PLLP            = 2;
    oscinitstruct.PLL.PLLQ            = 4;
    oscinitstruct.PLL.PLLR            = 2;
    oscinitstruct.PLL.PLLRGE          = RCC_PLL1VCIRANGE_3;
    oscinitstruct.PLL.PLLVCOSEL       = RCC_PLL1VCOMEDIUM;
    oscinitstruct.PLL.PLLFRACN        = 0;

    if ( HAL_OK != HAL_RCC_OscConfig( &oscinitstruct ))
    {
        /* Initialization Error */
        while( 1 );
    }

    clkinitstruct.ClockType      = ( RCC_CLOCKTYPE_HCLK  \
                                   | RCC_CLOCKTYPE_SYSCLK    \
                                   | RCC_CLOCKTYPE_PCLK1   \
                                   | RCC_CLOCKTYPE_PCLK2   \
                                   | RCC_CLOCKTYPE_D3PCLK1 \
                                   | RCC_CLOCKTYPE_D1PCLK1
                                   );
    clkinitstruct.SYSCLKSource   = RCC_SYSCLKSOURCE_PLLCLK;
    clkinitstruct.SYSCLKDivider  = RCC_SYSCLK_DIV1;
    clkinitstruct.AHBCLKDivider  = RCC_HCLK_DIV1;
    clkinitstruct.APB3CLKDivider = RCC_APB3_DIV1;
    clkinitstruct.APB1CLKDivider = RCC_APB1_DIV1;
    clkinitstruct.APB2CLKDivider = RCC_APB2_DIV1;
    clkinitstruct.APB4CLKDivider = RCC_APB4_DIV1;

    if ( HAL_OK != HAL_RCC_ClockConfig( &clkinitstruct, FLASH_LATENCY_1 ))
    {
        /* Initialization Error */
        while( 1 );
    }

    periphinitstruct.PeriphClockSelection      = RCC_PERIPHCLK_USART3
                                               | RCC_PERIPHCLK_USART2;
    periphinitstruct.Usart234578ClockSelection =
                                               RCC_USART234578CLKSOURCE_D2PCLK1;

    if ( HAL_OK != HAL_RCCEx_PeriphCLKConfig( &periphinitstruct ))
    {
        /* Initialization Error */
        while( 1 );
    }
}

And this is the code which is working:
Code:
void system_clk_cfg( void )
{
    RCC_ClkInitTypeDef       clkinitstruct    = {0};
    RCC_OscInitTypeDef       oscinitstruct    = {0};
    RCC_PeriphCLKInitTypeDef periphinitstruct = {0};

    HAL_PWREx_ConfigSupply( PWR_LDO_SUPPLY );
    __HAL_PWR_VOLTAGESCALING_CONFIG( PWR_REGULATOR_VOLTAGE_SCALE1 );

    while ( 0 == __HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY )) {}

    oscinitstruct.OscillatorType      = RCC_OSCILLATORTYPE_CSI;
    oscinitstruct.CSIState            = RCC_CSI_ON;
    oscinitstruct.CSICalibrationValue = 16;
    oscinitstruct.PLL.PLLState        = RCC_PLL_ON;
    oscinitstruct.PLL.PLLSource       = RCC_PLLSOURCE_CSI;
    oscinitstruct.PLL.PLLM            = 1;
    oscinitstruct.PLL.PLLN            = 200;
    oscinitstruct.PLL.PLLP            = 2;
    oscinitstruct.PLL.PLLQ            = 4;
    oscinitstruct.PLL.PLLR            = 2;
    oscinitstruct.PLL.PLLRGE          = RCC_PLL1VCIRANGE_2;
    oscinitstruct.PLL.PLLVCOSEL       = RCC_PLL1VCOWIDE;
    oscinitstruct.PLL.PLLFRACN        = 0;

    if ( HAL_OK != HAL_RCC_OscConfig( &oscinitstruct ))
    {
        /* Initialization Error */
        while( 1 );
    }

    clkinitstruct.ClockType      = ( RCC_CLOCKTYPE_HCLK  \
                                   | RCC_CLOCKTYPE_SYSCLK    \
                                   | RCC_CLOCKTYPE_PCLK1   \
                                   | RCC_CLOCKTYPE_PCLK2   \
                                   | RCC_CLOCKTYPE_D3PCLK1 \
                                   | RCC_CLOCKTYPE_D1PCLK1
                                   );
    clkinitstruct.SYSCLKSource   = RCC_SYSCLKSOURCE_PLLCLK;
    clkinitstruct.SYSCLKDivider  = RCC_SYSCLK_DIV1;
    clkinitstruct.AHBCLKDivider  = RCC_HCLK_DIV2;
    clkinitstruct.APB3CLKDivider = RCC_APB3_DIV2;
    clkinitstruct.APB1CLKDivider = RCC_APB1_DIV2;
    clkinitstruct.APB2CLKDivider = RCC_APB2_DIV2;
    clkinitstruct.APB4CLKDivider = RCC_APB4_DIV2;

    if ( HAL_OK != HAL_RCC_ClockConfig( &clkinitstruct, FLASH_LATENCY_2 ))
    {
        /* Initialization Error */
        while( 1 );
    }

    periphinitstruct.PeriphClockSelection      = RCC_PERIPHCLK_USART3
                                               | RCC_PERIPHCLK_USART2;
    periphinitstruct.Usart234578ClockSelection =
                                               RCC_USART234578CLKSOURCE_D2PCLK1;

    if ( HAL_OK != HAL_RCCEx_PeriphCLKConfig( &periphinitstruct ))
    {
        /* Initialization Error */
        while( 1 );
    }
}

From your latest post I understand that you were also able to recreate the same behavior and we can now come to a common conclusion regarding HSI.
Logged
dennis78
Active Member
***
Offline Offline

Posts: 121

Thank You
-Given: 266
-Receive: 153


« Reply #24 on: May 21, 2020, 09:26:36 09:26 »

Yes. Inacuracy internal RC osc's is source of problem. In start topic you wrote little confusing description. Now it is clear.  CSI is better, but in wide temperature range it can be problem. If you want use internal RC and avoid autobaud or calibration during normal using, you can make some tuning option during fabrication phase and use temperature compensation with internal temperature sensor. I can't confirm that it is enough for properly functioning.
« Last Edit: May 21, 2020, 09:29:41 09:29 by dennis78 » Logged
burgic
Newbie
*
Offline Offline

Posts: 34

Thank You
-Given: 9
-Receive: 24


WWW
« Reply #25 on: May 21, 2020, 09:35:18 09:35 »

Ok, thx. I'll stick to the CSI right now but I'll definitely need to have a deeper look into this in future.
Logged
millegps
Newbie
*
Offline Offline

Posts: 34

Thank You
-Given: 38
-Receive: 3


« Reply #26 on: May 21, 2020, 06:09:25 18:09 »

Check attached link, it's an app note from ST about accuracy of RC oscillators. Note that you can also trim internal oscillators to meet your specs

Logged
burgic
Newbie
*
Offline Offline

Posts: 34

Thank You
-Given: 9
-Receive: 24


WWW
« Reply #27 on: May 21, 2020, 09:25:25 21:25 »

@millegps: Thx, I'll have a look.
Logged
Pages: 1 2 [All]
Print
Jump to:  


DISCLAIMER
WE DONT HOST ANY ILLEGAL FILES ON THE SERVER
USE CONTACT US TO REPORT ILLEGAL FILES
ADMINISTRATORS CANNOT BE HELD RESPONSIBLE FOR USERS POSTS AND LINKS

... Copyright © 2003-2999 Sonsivri.to ...
Powered by SMF 1.1.18 | SMF © 2006-2009, Simple Machines LLC | HarzeM Dilber MC