Topic : Ride7 GCC STM32, Uart wrong speed problem ??

Forum : ARM

Original Post
Post Information Post
January 7, 2008 - 9:42pm
Guest

when configuring the UART baud rate, I guess the compiler or ride7 needs to know the clock speed of my CPU or so ?
else it can not calculate the BRR value right ?
HOW do I input this ?
I get 9600 Baud, with the examples from ST, they are ment to give 115200 baud,
and the funny thing is that exactly same example run perfect with the KEIL suite microvision, BRR = 525 (115200 baud)
but the Ride7 with GCC gives BRR = 7500 (9600 baud)
so I think I have forgotten a configure clock speed or a define or something ??
any ideas about this ? sorry I have only played with ride7 for a few days :-)

Replies
Post Information Post
+1
0
-1
January 8, 2008 - 9:52am
Guest

I have found out:
the uart init stm32f10x_usart.c
calls another function:
RCC_GetClocksFreq(&RCC_ClocksStatus); located in stm32f10x_rcc.c
this returns the selected clock speed wrong !! so that is why the GCC compiler setup wrong clock speed..
how to fix this ?

+1
0
-1
January 8, 2008 - 9:56am
Guest

Hi Thomas,

the file stm32f10x_conf.h defines a HSE_Value Preprocessor definition that you can adjust if needed.

Lionel

+1
0
-1
January 8, 2008 - 10:41am
Guest

aha, how is that done smartest ?
in my main.c ? have you 5 sec to give me an example ?

+1
0
-1
January 8, 2008 - 10:48am
Guest

I tried to put:
#define HSE_Value ((u32)8000000) /* Value of the External oscillator in Hz*/
in the top of my mail.c but still same problem

I even tried to // comment this line out in the conf.h you said
and I also tried to change the value to 16000000 but still exactly same wrong value 7500 gets stored in my BRR
and I still gets 9600 baud..

+1
0
-1
January 8, 2008 - 10:58am
Guest

The file stm32f10x_conf.h should be part of your application. It is most often found with your own source files, and is a part of the library where modifications can be done (and recommended!)

In this file, you define which peripherals you want to use, so that the library declares the associated API or not. You should have a look at it. The value of HSE_Value is given in Hertz.

The STM32 lib has been tested so I doubt there is an error in the clock config (although it may happen), but your clock may have been reconfigured elsewhere... Did you include the "UART0 printf" library (in the linker options) ?

you can send me (support@raisonance.com) your project if you want me to have a look here.

regards
Lionel

+1
0
-1
January 8, 2008 - 11:09am
Guest

more news :
i have simply copied the BRR value and send it to serial port, just after init of uart
and it is truly 625 !! the correct value !!
so something else is overwriting it later,
if I put
USART1->BRR = 625;
in my main loop the baud rate STAY 115200 as I want.
and exactly same project make with keil dont have this problem !!
now I zip it all and email to you :-)

+1
0
-1
January 9, 2008 - 11:13am
Guest

ok just to help others !! here we go I got this PERFECT answer from Lionel, it really solved the problem:
------------------------------
Hi Thomas,

here are the modifications to do, and below are the explanations:

- in Blinky.c :

- remove #define HSE_Value ((u32)8000000)
(useless)

- replace #include by #include

- in Serial.c :

- before SendChar and GetKey definitions, add the following :
#ifdef __GNUC__
#define SendChar __io_putchar
#define GetKey __io_getchar
#endif

- in the project options :

- set the linker option Libraries -> UART0 Putchar to "No"

- in the project tree :

- add C:\Program Files\Raisonance\Ride\Lib\ARM\io_putchar\syscalls.c
as a node of your project

Try to compile and see if everything works fine.

Here are the explanations:

the Keil libraries probably provide printf/scanf routines that call
SendChar() and GetKey(). So you redefine these functions to change the behaviour of printf. Our own printf version (that is used when "Small printf" option is set to "Yes") uses different function names.
GNU GCC uses #defines to provide the needed putchar() and getchar() functions. In the UART0_stdio.h file, we manage to redefine everything properly by redirecting putchar() to __io_putchar() and getchar() to __io_getchar(). The block ito add in Serial.c helps you defining these functions while keeping the names GetKey and SendChar.

Then, the printf does many things handled by the GNU standard library functions provided with GCC. Many routines must be provided, that are a part of an OS, and we don't need or want them. So it's not an easy task to make an application with a printf link correctly.

The first solution consists in using our own "UART0 printf" that takes care of redefining all these system routines (most of them end as empty functions because they have no sense in the embedded world). We do these redefinitions in syscalls.c, see the project in "C:\Program Files\Raisonance\Ride\Lib\ARM\io_putchar". The io_putchar library also redefines __io_putchar() and __io_getchar(), but uses its own initialization routines. This is where your problem comes from. By default the "UART0 printf" library is used, so when you call a printf() for the first time, the UART is reconfigured (and indeed we configure it to 9600 bauds). What should be done in such a case is call the
__io_init() function explicitly after your UART is configured, so that subsequent calls to pritnf don't reconfigure the UART. You can also send your oscillator frequency to the library so that it is taken into account when calculating baudrate, by using the function __io_SetMainOscFreq(). It's a clean way to use printf (you don't even have to define putchar or getchar, everything is included) but you may want to use your own functions.

The other solution consists in using your own putchar and getchar functions (what we do using the modifications above) and setting the "UART0 printf" library option to "No", but the system calls are still made by the printf. So if you manually add the syscalls.c file to the project, these system calls are redefined, and everything works fine.

As you can see we used here the second solution. It is the most flexible (and in that case the easiest solution as well), but needs the additional syscalls.c file.

I hope my explanations were clear. You can also have a look at the map file produced by the GNU Linker to get more information: right-click on your application node and select "Open Listing". You will see which libraries have been loaded, and a bit later in the file, what functions are discarded because not used.

Best regards,
Lionel