Author Topic: Help to start with STM3L412 and libopenCM3  (Read 7384 times)

0 Members and 1 Guest are viewing this topic.

Offline psysc0rpi0nTopic starter

  • Frequent Contributor
  • **
  • Posts: 325
  • Country: ar
Help to start with STM3L412 and libopenCM3
« on: August 03, 2021, 11:53:50 am »
Hello,

So, I've been trying to grasp the basics of libopenCM3 libraries to use with my STM32L412CBT chip.
Datasheet
Reference Manual

For now, I'm just trying to use a timer to blink a led. The initial stuff as usual.
I was reading someone's post somewhere on the web about this and tried to replicate some of the steps.

I can confirm with my scope that the following code is bringing the PIN I selected up.

Code: [Select]
   rcc_periph_clock_enable(RCC_GPIOB);
   gpio_mode_setup(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO0);
   gpio_set_output_options(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_LOW, GPIO0);
   gpio_toggle(GPIOB, GPIO0);
   while(1){
   }

Now, I started reading about timers and specific clock configuration within the source code of libopenCM3 itself, but it's quite a daunting task for someone with no experience with STM32 chips or libopenCM3, so I need some help to be able to understand how the clock blocks all work together and in isolated conditions and also to be able to use the correct libopenCM3 functions for each task.

I want to use a basic timer (TIM6) which, according to the clock tree from the datasheet below, is affected by the following blocks in the way:


And looking into the code of libopenCM3, I find this function to set the RCC PLL clock register:
rcc_set_main_pll()

Code: [Select]
void rcc_set_main_pll (uint32_t source,
       uint32_t pllm,
                       uint32_t plln,
       uint32_t pllp,
       uint32_t pllq,
       uint32_t pllr
)

But when I look in STM32CubeMX to help me with the dividers and multipliers, it tells me that pllq is not available unless RNG or some IP mode is selected, so, I'm not sure what to send as parameter for this function.
Similar question is for pllp. Reference manual says this is Main PLL division factor for PLLSAICLK (SAI1 clock). But a bit down in the reference manual, it's said that this PLLSAICLK is Not available on STM3L41xxx and STM32L42xxx devices. So, I'm a bit confused here.

Even so, this is what I have for now, but I have no idea this is supposed to be like this and if it will work.
Code: [Select]
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/timer.h>

int main(void){
   rcc_set_msi_range(0xb0);
   rcc_set_main_pll(RCC_PLLCFGR_PLLSRC_MSI, // [url]https://libopencm3.org/docs/latest/stm32l4/html/l4_2rcc_8h_source.html#l00272[/url]
                    RCC_PLLCFGR_PLLM(1),    // PLLM divider 1, RM0394, page 201
                    40,                     // PLLN divider 40, RM0394, page 201, see also libopencm3 l4/rcc.h file, lines 252 to 255
                                            // STM32CubeMX says it's 40
                    RCC_PLLCFGR_PLLP_DIV7,  // verify this one, RM0394 page 200 and libopencm l4/rcc.h file, lines 246 to 250
                    RCC_PLLCFGR_PLLQ_DIV2,  // verify this one too. It's says in STM32CubeMX that it's not available, ony if IP or
                                            //RNG mode is selected. RM0394 page 200
                    RCC_PLLCFGR_PLLR_DIV2); // PLLR divider 2, RM0394 page 200. STM32CubeMX says it's 2
   rcc_periph_clock_enable(RCC_GPIOB);
   gpio_mode_setup(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO0);
   gpio_set_output_options(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_LOW, GPIO0);
   gpio_toggle(GPIOB, GPIO0);
   while(1){
   }
   return 0;
}


So, if anyone is willing to dive a bit into this with me I would appreciate!
« Last Edit: August 03, 2021, 03:24:55 pm by psysc0rpi0n »
 

Offline thm_w

  • Super Contributor
  • ***
  • Posts: 6349
  • Country: ca
  • Non-expert
Re: Help to start with STM3L412 and libopenCM3
« Reply #1 on: August 03, 2021, 09:55:20 pm »
If its not available, should be fine to set it to 0.
You can find some example code here: https://github.com/libopencm3/libopencm3-examples/blob/master/examples/stm32/l4/stm32l476g-disco/basics/basics.c
pllcfg options: http://libopencm3.org/docs/latest/stm32g4/html/group__rcc__pllcfgr__values.html

To me it seems like you've got the right idea.
Profile -> Modify profile -> Look and Layout ->  Don't show users' signatures
 
The following users thanked this post: psysc0rpi0n

Offline psysc0rpi0nTopic starter

  • Frequent Contributor
  • **
  • Posts: 325
  • Country: ar
Re: Help to start with STM3L412 and libopenCM3
« Reply #2 on: August 04, 2021, 09:08:48 am »
If its not available, should be fine to set it to 0.
You can find some example code here: https://github.com/libopencm3/libopencm3-examples/blob/master/examples/stm32/l4/stm32l476g-disco/basics/basics.c
pllcfg options: http://libopencm3.org/docs/latest/stm32g4/html/group__rcc__pllcfgr__values.html

To me it seems like you've got the right idea.

I'm not sure I started in the right place. I want to use one of the internal clocks that allow me to have the 80Mhz for the timers clock. The image I posted above is from STM32CubeMX, but the one from the datasheet is slightly different.
This is the one I should be sticking to:


The difference is that in the image from my post above (STM32CubeMX), I assumed that the MSI input at the PLL Source Mux, was the block above it called MSI RC. Truth is that I'm not sure this is correct because in the datasheet, block diagram is a bit different.
In STM32CubeMX, the block diagram shows a PLL Source Mux before the PLL block and in the dataseet, I can't see any mux before the PLL block.



So, my question is if the MSI RC block in STM32CubeMX, marked in brown is the same from the one also marked in brown in the datasheet and if this is the input clock source that is feeding the PLL block and that later multiplies and divides to get the 80Mhz out, in the end! (don't mind the frequency and divider/multiplier values shown in the pictures).
« Last Edit: August 04, 2021, 09:10:52 am by psysc0rpi0n »
 

Offline Silenos

  • Regular Contributor
  • *
  • Posts: 54
  • Country: pl
  • Fumbling in ignorance
Re: Help to start with STM3L412 and libopenCM3
« Reply #3 on: August 04, 2021, 09:38:23 am »
I do not understand the red lines in your first pic from rm schematic. If my eyesight is correct, both cube and rm clock tree schematics are the same, and your color clouds in second pic are correct. And MSI connection point commented in red should be "connected before /M...", not "connected after /M...". You sure you haven't mistaken reading a direction of pre-pll mux?
« Last Edit: August 04, 2021, 09:42:06 am by Silenos »
 

Offline psysc0rpi0nTopic starter

  • Frequent Contributor
  • **
  • Posts: 325
  • Country: ar
Re: Help to start with STM3L412 and libopenCM3
« Reply #4 on: August 04, 2021, 09:53:31 am »
I do not understand the red lines in your first pic from rm schematic. If my eyesight is correct, both cube and rm clock tree schematics are the same, and your color clouds in second pic are correct. And MSI connection point commented in red should be "connected before /M...", not "connected after /M...". You sure you haven't mistaken reading a direction of pre-pll mux?

The red lines were just to show the path of the blocks that will be influenced by my final goal, which is to get 80Mhz at the end, using TIM6 and PLL.
About the direction of pre-pll mux... I assume pre-pll mux is this:


If so, I didn't notice the arrow pointing in (into) the PLL block. Does this means it is before the PLL block?
Even so, in STM3CubeMX, this PLLM parameter is exiting (after) the PLL block.


Edited;

Ignore, I see now that my mind was kinda blocked/stuck making me see that PLLM parameter was exiting PLL block when it is in fact exiting the PLL source mux (which I think you called pre-pll mux)
« Last Edit: August 04, 2021, 10:22:27 am by psysc0rpi0n »
 
The following users thanked this post: Silenos

Offline Silenos

  • Regular Contributor
  • *
  • Posts: 54
  • Country: pl
  • Fumbling in ignorance
Re: Help to start with STM3L412 and libopenCM3
« Reply #5 on: August 04, 2021, 10:23:23 am »
The "/M" and "PLLM" labels are the same thing.
 

Offline psysc0rpi0nTopic starter

  • Frequent Contributor
  • **
  • Posts: 325
  • Country: ar
Re: Help to start with STM3L412 and libopenCM3
« Reply #6 on: August 04, 2021, 11:29:25 am »
The "/M" and "PLLM" labels are the same thing.

Yes, that one is obvious.

What I was making confusion with was with PLL Source Mux (STM32CubeMX) and the PLL block itself.

Ok, I think I got this part.
Now I'm searching libopencm3 source code where we set the AHB and APB1 prescaler values. I mean, what are the functions we should use to set these values.
 

Offline Kjelt

  • Super Contributor
  • ***
  • Posts: 6460
  • Country: nl
Re: Help to start with STM3L412 and libopenCM3
« Reply #7 on: August 04, 2021, 11:40:09 am »
I would really advise this book, it will help you get up and running quickly with low frustration levels.

 
The following users thanked this post: psysc0rpi0n, Doctorandus_P

Offline psysc0rpi0nTopic starter

  • Frequent Contributor
  • **
  • Posts: 325
  • Country: ar
Re: Help to start with STM3L412 and libopenCM3
« Reply #8 on: August 04, 2021, 01:27:10 pm »
I still couldn't find where we set AHB and APB1 prescaler values in libopencm3 library source code.

I can see all these functions:

I can see all these subject in reference manual but none is to set prescalers, as far as I know



Any hint?
 

Offline psysc0rpi0nTopic starter

  • Frequent Contributor
  • **
  • Posts: 325
  • Country: ar
Re: Help to start with STM3L412 and libopenCM3
« Reply #9 on: August 04, 2021, 01:34:49 pm »
I would really advise this book, it will help you get up and running quickly with low frustration levels.

I also searched in that book, but the functions used there are deprecated or no longer available:
In page 280 an 281 is described a list of SYSCLK dividers


and ana example:


but this function is no longer used, it's deprecated:



Then, I search for the suggested replacement function but I can't find one for "l4" series:


So, I'm sitll not sure how to set AHB and APB1 presclers.
« Last Edit: August 04, 2021, 01:39:15 pm by psysc0rpi0n »
 

Offline Kjelt

  • Super Contributor
  • ***
  • Posts: 6460
  • Country: nl
Re: Help to start with STM3L412 and libopenCM3
« Reply #10 on: August 04, 2021, 02:44:42 pm »
They changed it then. Has been a while ago since I last used libopen and that was with a F4 not an L4.
Strange. Can not find much on their wiki or site.

Check rcc.h and compare it to an older version see what interface functions changed.
« Last Edit: August 04, 2021, 02:50:12 pm by Kjelt »
 

Offline Kjelt

  • Super Contributor
  • ***
  • Posts: 6460
  • Country: nl
Re: Help to start with STM3L412 and libopenCM3
« Reply #11 on: August 04, 2021, 03:18:32 pm »
Ah ok found that this function is still there but only in the STM32F1 directory in the rcc.c file.
For the newer uCs they have deprecated it. You have to call the functions your self, but you can still see the example in the F1 directory, looks like the same rcc_ functions are available for L4.

So you have to find a simple blinky example for F4 or L4 then, probably just as easy but a couple of more function calls.
« Last Edit: August 04, 2021, 03:21:04 pm by Kjelt »
 

Offline psysc0rpi0nTopic starter

  • Frequent Contributor
  • **
  • Posts: 325
  • Country: ar
Re: Help to start with STM3L412 and libopenCM3
« Reply #12 on: August 04, 2021, 05:30:17 pm »
Ah ok found that this function is still there but only in the STM32F1 directory in the rcc.c file.
For the newer uCs they have deprecated it. You have to call the functions your self, but you can still see the example in the F1 directory, looks like the same rcc_ functions are available for L4.

So you have to find a simple blinky example for F4 or L4 then, probably just as easy but a couple of more function calls.

I found an example at some site and I'm making a few changes. I have to select another timer, because TIM6 doesn't have an Output Comparator pin and I need a timer that has this feature to be able to follow the example. This example also uses functions from libopenCM3, so, at least it gives me hints on the functions to use.

For reference:
https://bdebyl.net/post/stm32-part1/
 

Offline psysc0rpi0nTopic starter

  • Frequent Contributor
  • **
  • Posts: 325
  • Country: ar
Re: Help to start with STM3L412 and libopenCM3
« Reply #13 on: August 04, 2021, 06:52:37 pm »
Ok, this is what I have for now:

Code: [Select]
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/timer.h>

int main(void){
   rcc_set_main_pll(RCC_PLLCFGR_PLLSRC_MSI, // Clock source MSI RC
                    // libopencm3 l4/rcc.h, line 272
                    // RM0394, page 201
                    RCC_PLLCFGR_PLLM(1), // PLLM divider 1
                    // libopencm3 l4/rcc.h, line 266
                    // RM0394, page 201
                    // STM32CubeMX says it's 1                       
                    // RM says PLLSAI1 is not available for STM32L412
                    80, // PLLN divider 80
                    // libopencm3 l4/rcc.h file, lines 252 to 255
                    // RM0394, page 201
                    // STM32CubeMX says it's 80 for the default MSI RC clock of 4Mhz
                    RCC_PLLCFGR_PLLP_DIV7,
                    // libopencm3 l4/rcc.h file, lines 246 to 250
                    // RM0394 page 200
                    // Doesen't matter for STM32L412. PLLSAI1 is not available
                    RCC_PLLCFGR_PLLQ_DIV2,
                    // libopencm3 l4/rcc.h file, line 240,
                    // RM0394 page 200
                    // Disabled for this case.
                    RCC_PLLCFGR_PLLR_DIV4); // PLLR divider 4
                    // libopencm3 l4/rcc.h
                    // RM0394 page 200
                    // STM32CubeMX says it's 4 for the default MSI RC clock of 4Mhz
   rcc_set_ppre1(RCC_CFGR_PPRE1_NODIV); // APB1 prescaler to 1 (no div)
   rcc_set_hpre(RCC_CFGR_HPRE_NODIV);   // AHB prescaler to 1 (no div)
   rcc_periph_clock_enable(RCC_GPIOA);
   timer_set_mode(TIM2, TIM_CR1_CKD_CK_INT,
                        TIM_CR1_CMS_EDGE,
                        TIM_CR1_DIR_UP);
   gpio_mode_setup(GPIOA, GPIO_MODE_AF,
                   GPIO_PUPD_NONE, GPIO10);
   gpio_set_output_options(GPIOA, GPIO_OTYPE_PP,
                           GPIO_OSPEED_HIGH, GPIO10);
   gpio_set_af(GPIOA, GPIO_AF1, GPIO10);
   timer_set_prescaler(TIM2, (rcc_apb1_frequency/80000)/2*1); < -------- NOT SURE HOW THIS WORKS HERE
   timer_set_period(TIM2, 80000);
   timer_disable_preload(TIM2);
   timer_continuous_mode(TIM2);
   rcc_periph_clock_enable(RCC_GPIOA);
   gpio_mode_setup(GPIOA, GPIO_MODE_AF,
                   GPIO_PUPD_NONE, GPIO10);
   timer_set_mode(TIM2, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE,
                  TIM_CR1_DIR_UP);
   gpio_toggle(GPIOA, GPIO10);
   while(1){
   }
   return 0;
}

I'm not sure how the prescaler value works. Apparently this is where you put the upper limit of our counter. So, in the example I'm following, is said that:
Quote
In addition to the timer clock, set by the peripheral clock (internal), each timer has a perscaler value. This determines the counter clock frequency and is equal to Frequency/(Prescaler + 1). This is the value the timer will count to prior resetting (default behavior). We can get the exact value of this frequency, provided we didn’t change the clock divisions via rcc_apb1_frequency (unsigned integer value).

For the sake of simplicity in dividing the clock into easy decimal values, we will utilize setting up the High Speed Internal clock to 48MHz and dividing by 48,000:

And they use the following code:
Code: [Select]
rcc_clock_setup_in_hsi_out_48mhz(); // Place at the beginning of your int 'main(void)'
...

// SECONDS: integer value of period (seconds) of LED blink
timer_set_prescaler(TIM3, (rcc_apb1_frequency/48000)/2*SECONDS));

In my case, I set AHB and APB1 frequencies to 80Mhz. So, How am I going to compute, let's say, 300 miliseconds for a led to blink?
 

Offline thm_w

  • Super Contributor
  • ***
  • Posts: 6349
  • Country: ca
  • Non-expert
Re: Help to start with STM3L412 and libopenCM3
« Reply #14 on: August 04, 2021, 08:51:11 pm »
I'm not sure how the prescaler value works. Apparently this is where you put the upper limit of our counter. So, in the example I'm following, is said that:

Probably an english language thing. Prescaler = scale the clock, so divide it down. Its not an upper limit, that would be related to the preload or max register value.

So if the timer is 80MHz, then prescale is set to 10, now the timer will run at 8MHz.
Assuming 16-bit timer, max prescale is probably 65536. So prescale by whatever makes sense to you, since you need low timer resolution, maybe 10000 or 40000.
Profile -> Modify profile -> Look and Layout ->  Don't show users' signatures
 

Offline psysc0rpi0nTopic starter

  • Frequent Contributor
  • **
  • Posts: 325
  • Country: ar
Re: Help to start with STM3L412 and libopenCM3
« Reply #15 on: August 05, 2021, 08:47:39 am »
I'm not sure how the prescaler value works. Apparently this is where you put the upper limit of our counter. So, in the example I'm following, is said that:

Probably an english language thing. Prescaler = scale the clock, so divide it down. Its not an upper limit, that would be related to the preload or max register value.

So if the timer is 80MHz, then prescale is set to 10, now the timer will run at 8MHz.
Assuming 16-bit timer, max prescale is probably 65536. So prescale by whatever makes sense to you, since you need low timer resolution, maybe 10000 or 40000.

I know what the prescaler is meant to do. What I'm not sure about is how it relates to the value I want/need the led to blink.

You say the if the timer is 80Mhz, thhen prescale is set to 10. How do you know this?
 

Offline Kjelt

  • Super Contributor
  • ***
  • Posts: 6460
  • Country: nl
Re: Help to start with STM3L412 and libopenCM3
« Reply #16 on: August 05, 2021, 09:25:00 am »
In my case, I set AHB and APB1 frequencies to 80Mhz. So, How am I going to compute, let's say, 300 miliseconds for a led to blink?
This depends what you exactly want since there are many solutions for this.
Lets start with how I look at it, but as said many things are possible.

Look at the reference manual of your uC and esp. on the timer chapter and look at the time base unit and upcounting mode.
So to do this you need to have the clock activated to your timer, you need to know the frequency.
Then you calculate how much to divide the clock signal to get the wanted frequency.
That division you split between the prescaler and the upcounting register ARR.

So for instance you have a 80MHz clock to the timer and you want the ARR to overflow after 300ms (3.3Hz)
Then you need to divide the 80MHz clock by 24242424. The max value of the prescaler is 65535 you are left with 1220 Hz.
To divide the 1220Hz to 3.3Hz again a factor of 360 is needed. So that is the value of the ARR register.

Now you still have to do some things. First enable the timer (start timer) and enable the interrupts of that timer register and map the overflow interrupt to your interrupt handler.
In that interrupt handler you toggle the led. Measure with an oscilloscope the exact frequency and correct with the ARR value. If you can not get it perfect you need a multi step plan.

So personally I find it a waste to set a hardware timer peripheral to those low speeds.
What I usually do is use one generic HW timer to generate for instance a 1ms interrupt, and in that 1ms interrupt handler I update the software timer module (a piece of software with different user configurable timers 8bit, 16 bit etc) that are increased or decreased by the 1ms interrupt handler.
In your code you have a superloop or RTOS and there you check if the software counter has expired (with downcounting software timers) if so you toggle the led.

But I don't want to make it more difficult than it is.
If you do not succeed with the above, then you can do some fast checks:  in your code readout the ARR register and display or store it and view it, it should increase to 360 then start over at 0.
If you do not see the ARR increasing, check if you have started the timer (enabled it) , still does not work, set the frequency lower. Change the 80MHz to 16MHz or so and try again.
 
 

Offline thm_w

  • Super Contributor
  • ***
  • Posts: 6349
  • Country: ca
  • Non-expert
Re: Help to start with STM3L412 and libopenCM3
« Reply #17 on: August 05, 2021, 09:00:42 pm »
You say the if the timer is 80Mhz, thhen prescale is set to 10. How do you know this?

Its just an example, you set prescaler to any number between 1 and 65535 in your code.
Thats why I said you could set it to 10,000 or 40,000 as well.
Profile -> Modify profile -> Look and Layout ->  Don't show users' signatures
 

Offline psysc0rpi0nTopic starter

  • Frequent Contributor
  • **
  • Posts: 325
  • Country: ar
Re: Help to start with STM3L412 and libopenCM3
« Reply #18 on: August 05, 2021, 11:36:23 pm »
In my case, I set AHB and APB1 frequencies to 80Mhz. So, How am I going to compute, let's say, 300 miliseconds for a led to blink?
This depends what you exactly want since there are many solutions for this.
Lets start with how I look at it, but as said many things are possible.

Look at the reference manual of your uC and esp. on the timer chapter and look at the time base unit and upcounting mode.

Ok, I think I did that here:

Code: [Select]
timer_set_mode(TIM2, TIM_CR1_CKD_CK_INT,
                        TIM_CR1_CMS_EDGE,
                        TIM_CR1_DIR_UP);

TIM_CR1_DIR_UP is for upcounting.

About base unit, the reference manual says:

Quote
The time-base unit includes:
• Counter Register (TIMx_CNT)
• Prescaler Register (TIMx_PSC):
• Auto-Reload Register (TIMx_ARR)

I'm not sure how to interpret this and what to retain for what I need.

So to do this you need to have the clock activated to your timer, you need to know the frequency.

If I did things correctly, the Timer frequency is 80Mhz.
I activate the clock here:

rcc_periph_clock_enable(RCC_TIM2);


Then you calculate how much to divide the clock signal to get the wanted frequency.
That division you split between the prescaler and the upcounting register ARR.

So for instance you have a 80MHz clock to the timer and you want the ARR to overflow after 300ms (3.3Hz)
Then you need to divide the 80MHz clock by 24242424. The max value of the prescaler is 65535 you are left with 1220 Hz.
To divide the 1220Hz to 3.3Hz again a factor of 360 is needed. So that is the value of the ARR register.

Ok, just to confirm I got it, the procedure is to divide the timer clock frequency by the time we want our led on. As we can't mix up frequency with time, we convert the time to frequency. That's 1/300ms = 3.3Hz.
So, 80Mhz / 3.3Hz is that 24242424 value that would be the one to set in ARR but it can only take up to 65536, so we need to go back and divide  again the 80Mhz by 65536 and we get 1220Hz, approximately.

In practice, correct me if I'm wrong, it will take 300ms for the timer to overflow at a frequency of 1220Hz, yes?

And in terms of code, as I was following the other example I found, I probably did this wrong.
The other example used the rcc_apb1_frequency constant (which is 4Mhz) to calculate the value for the prescaler, and to be honest, I'm a bit lost here.

timer_set_prescaler(TIM2, (rcc_apb1_frequency/80000)/2*1);

Instead of that value, I want there the 1220, right?

Now you still have to do some things. First enable the timer (start timer) and enable the interrupts of that timer register and map the overflow interrupt to your interrupt handler.
In that interrupt handler you toggle the led. Measure with an oscilloscope the exact frequency and correct with the ARR value. If you can not get it perfect you need a multi step plan.

I enabled the timer here:
timer_enable_counter(TIM2);

but I didn't do the interrupt thing. I thought that wouldn't be needed because, at least I thought, I was using the Output Compare Mode. Quoting the reference manual:

Quote
When a match is found between the capture/compare register and the counter, the output
compare function:
• Assigns the corresponding output pin to a programmable value defined by the output
compare mode (OCxM bits in the TIMx_CCMRx register) and the output polarity (CCxP
bit in the TIMx_CCER register). The output pin can keep its level (OCXM=000), be set
active (OCxM=001), be set inactive (OCxM=010) or can toggle (OCxM=011) on match.
• Sets a flag in the interrupt status register (CCxIF bit in the TIMx_SR register).
• Generates an interrupt if the corresponding interrupt mask is set (CCXIE bit in the
TIMx_DIER register).
• Sends a DMA request if the corresponding enable bit is set (CCxDE bit in the
TIMx_DIER register, CCDS bit in the TIMx_CR2 register for the DMA request
selection).

I think I setup the timer accordingly here:
timer_set_oc_mode(TIM2, TIM_OC1, TIM_OCM_PWM1);

But I also got a bit confused here when I was reading the example, because the Output Compare Mode was selected but then there is that  TIM_OCM_PWM1 constant/macro that made me think if we are on Output Compare Mode or in some PMW mode.

So personally I find it a waste to set a hardware timer peripheral to those low speeds.
What I usually do is use one generic HW timer to generate for instance a 1ms interrupt, and in that 1ms interrupt handler I update the software timer module (a piece of software with different user configurable timers 8bit, 16 bit etc) that are increased or decreased by the 1ms interrupt handler.
In your code you have a superloop or RTOS and there you check if the software counter has expired (with downcounting software timers) if so you toggle the led.

Well, I don't want and I can't discuss other solutions because I'm just learning. I'm sure that in a production environment, that would probably be faster, more efficient and less time consuming. As of my situation, I started this as a learning process, so I want to get familiar with the most common libopencm3 functions that setup these most common peripherals, clocks, etc and maybe later I can think about alternatives, when I'm more comfortable.

But I don't want to make it more difficult than it is.
If you do not succeed with the above, then you can do some fast checks:  in your code readout the ARR register and display or store it and view it, it should increase to 360 then start over at 0.
If you do not see the ARR increasing, check if you have started the timer (enabled it) , still does not work, set the frequency lower. Change the 80MHz to 16MHz or so and try again.

Yes, as of now, I want to make it as simple and straight forward as possible, taking into account that I want to learn more about libopencm3 and the stm32 chips themselves.
 

Offline abyrvalg

  • Frequent Contributor
  • **
  • Posts: 824
  • Country: es
Re: Help to start with STM3L412 and libopenCM3
« Reply #19 on: August 06, 2021, 06:07:06 am »
Note that PA10 pin you are configuring is timer channel 3, so you need to configure TIM_OC3, not 1.
 

Offline psysc0rpi0nTopic starter

  • Frequent Contributor
  • **
  • Posts: 325
  • Country: ar
Re: Help to start with STM3L412 and libopenCM3
« Reply #20 on: August 06, 2021, 07:36:39 am »
Note that PA10 pin you are configuring is timer channel 3, so you need to configure TIM_OC3, not 1.

My datasheet says otherwise:

TIM2_CH1


Am I right, right?
 

Offline Kjelt

  • Super Contributor
  • ***
  • Posts: 6460
  • Country: nl
Re: Help to start with STM3L412 and libopenCM3
« Reply #21 on: August 06, 2021, 08:26:13 am »
Note that PA10 pin you are configuring is timer channel 3, so you need to configure TIM_OC3, not 1.
My datasheet says otherwise:
Am I right, right? 

No you are looking at the physical ic device pin, you should be looking at the logical pin function name, see picture. So abyrvalg is right, PA10 is tim3 and PA0 is tim2.
 
 

Offline Kjelt

  • Super Contributor
  • ***
  • Posts: 6460
  • Country: nl
Re: Help to start with STM3L412 and libopenCM3
« Reply #22 on: August 06, 2021, 08:34:28 am »
So on your previous post, yes if you use the timer as capture/compare and toggle the output that should work.
Unfortunately I am full time at work again and do not have the libopen environment and other hw to "play along" as Dave always eloquently puts it, so hopefully some student or retired forum member might help you further.

To correct a mistake I made in a previous post, the counter register is the register you can read out if you want to check if the timer is running, it should increase each time you read it out till it overflows.
But if you set the capture compare mode to a value than it will overflow sooner. You do have some debug (usb or serial) output so you can see what you are doing ? Good luck.
 

Offline psysc0rpi0nTopic starter

  • Frequent Contributor
  • **
  • Posts: 325
  • Country: ar
Re: Help to start with STM3L412 and libopenCM3
« Reply #23 on: August 06, 2021, 08:46:58 am »
@kjelt

Oh I see. Ok, my goal is to use TIM2_CH1, so I already changed the code to reflect this (fixed) mistake. GPIO10 to GPIO0
So, now I have:

Code: [Select]
   gpio_mode_setup(GPIOA, GPIO_MODE_AF,
                   GPIO_PUPD_NONE, GPIO0);

   gpio_set_output_options(GPIOA, GPIO_OTYPE_PP,
                           GPIO_OSPEED_HIGH, GPIO0);

   gpio_set_af(GPIOA, GPIO_AF1, GPIO0);

I am using OpenOCD, GDB and a J-Link clone. I'm not even going to detail now some other weird things that have been happening to me with this J-Link. Maybe later.  |O |O



Edited:
And I can see now that my physical pin 10 goes high at this line of code:

Code: [Select]
timer_enable_oc_output(TIM2, TIM_OC1);

But then, stays high for ever, so I think I have the period and prescaler and comparator value wrong.
« Last Edit: August 06, 2021, 08:56:29 am by psysc0rpi0n »
 

Offline Kjelt

  • Super Contributor
  • ***
  • Posts: 6460
  • Country: nl
Re: Help to start with STM3L412 and libopenCM3
« Reply #24 on: August 06, 2021, 09:14:16 am »
I can advise you to use an oscilloscope on the pin to see what's going on since >200Hz you won't be able to see it.
If you don't have an oscilloscope, start using a lower system clock, 80MHz is pretty high for the first experiments, first set it to say 16MHz or 24MHz and increase the timer prescaler till you have a lower frequency.
Also double check if you set the timer to toggle the output (or can toggle (OCxM=011) on match.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf