Clock and other Registers

ChibiOS public support forum for all topics not covered by a specific support forum.

Moderators: RoccoMarco, lbednarz, tfAteba

Post Reply
eribla
Posts: 20
Joined: Fri Nov 29, 2013 1:10 am

Clock and other Registers

Post by eribla »

Hi

Trying to figure out how to change the ADC conversion speed. (Eventually).

I understand that it is derived from the system clock and some pre-scalers.

I am trying to wind through the Chibi initialisations to see how it is set initially. (Using the STM32F4x example).

When I start with the system clock initialisation I find that

Code: Select all

SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |  SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk;

Somewhere else I then can find that i.e.

SysTick_CTRL_CLKSOURCE_Msk    is      (1UL << SysTick_CTRL_CLKSOURCE_Pos)         
and  SysTick_CTRL_CLKSOURCE_Pos    is       2       


after a lot of shifting and or-ing I finally can get the value of SysTick->CTRL.....


Is there an easier way to find the values of all these STM32F4x registers? (They are not in my Keil default register list).
Are there any tools that help with the shifting, or-ing and and-ing?
I can't believe that you guys all do it in your head or on a piece of paper.

( I have seen the STSW-STM32091 Clock configuration tool but that does not help me with the ADC, also I am talking about how to configure any configuration register easier).

Thanks

Eriks
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: Clock and other Registers

Post by Giovanni »

Hi,

The system tick is entirely *unrelated* to the ADC.

You can use two methods:
1) Change the sample time for each channel, the settings are in the ADCConversionGroup structure.
2) You can use hardware triggering and trigger the ADC using a timer.

Read carefully the ADC section in the STM32F4xx Reference Manual.

Giovanni
eribla
Posts: 20
Joined: Fri Nov 29, 2013 1:10 am

Re: Clock and other Registers

Post by eribla »

Thank you Giovanni

but you have not answered my questions about an easier way to see what is in the configuration registers, my KEIL IDE
cannot evaluade SysTick->CTRL and there is no SysTickControl register in the register view either.

Another related issue:
Please educate me or point me to another source or book:
Coming from pure desktop programming I do not get the purpose for these register definitions
Example:

Code: Select all

#define SysTick_CTRL_TICKINT_Pos            1                                             /*!< SysTick CTRL: TICKINT Position */
#define SysTick_CTRL_TICKINT_Msk           (1UL << SysTick_CTRL_TICKINT_Pos)              /*!< SysTick CTRL: TICKINT Mask */
 

Why not #define SysTick_CTRL_TICKINT_Msk = 2; That should be the same, or not?


Even more insane is to set the shift number to 0:

Code: Select all

#define SysTick_CTRL_ENABLE_Pos             0                                             /*!< SysTick CTRL: ENABLE Position */
#define SysTick_CTRL_ENABLE_Msk            (1UL << SysTick_CTRL_ENABLE_Pos)


Is this not the same as #define SysTick_CTRL_ENABLE_Msk =1; ?

I know there must be a logical reason for doing it this way.
It's definitely not speed.
It seems to me that even the memory usage is more, so what is it then?


Thanks a lot as always, I very much appreciate all your work with CHiBi-OS, it's pretty amazing what you did there.

Eriks
efuentes
Posts: 35
Joined: Wed Jul 25, 2012 6:16 am

Re: Clock and other Registers

Post by efuentes »

Hi Eriks,

You've asked a few questions, and I'll try to answer each as best as I can.

1. I can't really help you with your KEIL issue, as I don't use it but it sounds like you're able to view the register values for other peripherals? Maybe there is another register definition file somewhere?

2. I imagine that stm32f4xx.h and it's brethren are all autogenerated from some register definition file similar to the one used by your register viewer. In that file, they probably define a start bit and length for each field and from those the defines are created.

3. You understand what the #defines simplify to, but remember that all that simplification happens during the compilation process, in particular preprocessing. If you look at your c code after preproccessing (use the -E option when compiling), anywhere you use a #define, it gets replaced with a hard coded value it if can. So in the end there
is no increase in speed or memory usage.

Code: Select all

SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |  SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk;
//after preprocessing becomes
((SysTick_Type *) 0xE000E010UL)->CTRL = 7

4. From a code readability standpoint, having:

Code: Select all

SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |  SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk;

is much more useful than simply having:

Code: Select all

SysTick->CTRL = 0x07;

As for going from 0x07 back to a real meaning, you get better at it the more you do it ;) .

Erick
eribla
Posts: 20
Joined: Fri Nov 29, 2013 1:10 am

Re: Clock and other Registers

Post by eribla »

Hi Erick

I fully get that

Code: Select all

SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |  SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk;

is better than

((SysTick_Type *) 0xE000E010UL)->CTRL = 7


What I don't understand are the multiple indirections and shifting or mathematical operations involved to define a certain value.
Why not say SysTick_CTRL_CLKSOURCE_Msk = 0; (or 1..2..4...) instead of
#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) with pos some other number?


For instance to figure out the setting of the DMA channel bits, I have to go through

Code: Select all


#define ADC1_DMA_CHANNEL   STM32_DMA_GETCHANNEL(STM32_ADC_ADC1_DMA_STREAM, STM32_ADC1_DMA_CHN)
STM32_DMA_GETCHANNEL(STM32_ADC_ADC1_DMA_STREAM, STM32_ADC1_DMA_CHN)
with 
#define STM32_ADC_ADC1_DMA_STREAM           STM32_DMA_STREAM_ID(2, 4)     
and
#define STM32_DMA_STREAM_ID(dma, stream) ((((dma) - 1) * 8) + (stream))  */


instead of
#define ADC1_DMA_CHANNEL1 = 0x02000000;

or #define CHSEL =3;


With the last info I just could go the the register definition and see what these bits are doing.

Anyway, I need to figure out how I can see the ADC or DMA registers directly in Keil.

Again, if you know of some literature that explains these basics....

Thanks

Eriks
efuentes
Posts: 35
Joined: Wed Jul 25, 2012 6:16 am

Re: Clock and other Registers

Post by efuentes »

If you want to know why the defines are written in that way, you're going to have to ask ARM, as they are the ones that generated that file. If you look at the GPIO ODR register defines in stm32f4xx.h, you'll see that those fields are defined in the way that you mention (Pin 0 = 1, Pin 1 = 2, Pin 3 = 4, etc).

You are totally right in saying that all of these drivers can be written without all of the indirection that is present. In fact, the drivers may end up being more efficient if all of those abstractions were removed. The ST peripheral libraries take this route to a certain degree.

What you end up losing is code portability and maintainability. Indirection to create common interfaces is the price you have to pay if you want to reuse code across product lines, vendors, or processor cores.

I haven't looked at the code for the linux kernel, but I would be willing to bet that similar abstractions are used to hide the differences between processors, ram, sound cards etc.

Erick
eribla
Posts: 20
Joined: Fri Nov 29, 2013 1:10 am

Re: Clock and other Registers

Post by eribla »

Thanks!
Post Reply