Page 1 of 1
Clock and other Registers
Posted: Fri Jan 03, 2014 12:46 am
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
Re: Clock and other Registers
Posted: Fri Jan 03, 2014 8:36 am
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
Re: Clock and other Registers
Posted: Sat Jan 04, 2014 12:53 am
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
Re: Clock and other Registers
Posted: Sat Jan 04, 2014 8:23 am
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:
As for going from 0x07 back to a real meaning, you get better at it the more you do it

.
Erick
Re: Clock and other Registers
Posted: Sat Jan 04, 2014 9:00 pm
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
Re: Clock and other Registers
Posted: Sat Jan 04, 2014 9:46 pm
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
Re: Clock and other Registers
Posted: Sun Jan 05, 2014 12:56 am
by eribla
Thanks!