[ell-i-developers] PWM working for TIM2

  • From: Ivan Raul <supra.material@xxxxxxxxx>
  • To: ell-i-developers@xxxxxxxxxxxxx
  • Date: Mon, 27 Jan 2014 20:56:37 +0200

Dear all.

First of all, good eveneing!!

Finally the PWM ouptput for the TIM2 is working. The main problem was that
TIM2 is a timer with some 32bit registers. Then, the routine

SystemInitData16NoAddress @ system_init.c

Generates this particular assembly:

 80002a2:    8022          strh    r2, [r4, #0]

The problem of that instruction is that when it loads to the register, it
only loads the low half word. Then, the registers of 32 bits failed to
initialize correctly (well, that is what I tested).

To solve the problem, the function was modified:

SystemInitData16NoAddress @ system_init.c

void SystemInitData16NoAddress(const SystemInitRecordArray *ra) {
    register volatile uint32_t *a = (uint32_t *)ra->init_record_address16;
    for (int i = 0; i < ra->init_record_number; i++) {
        *a = (uint32_t)r->init_data16;   // Write 16 bits (zero extended to
        r += 2;
        a ++;                 // Advance dst by 32 bits

That slightly changes the assembly, the most important part is this:

80002a2:    6022          str    r2, [r4, #0]

Now, this function writes the zeros necessary to initialize the peripheral.
(strh vs str)

I am not sure if the c code is the correct one, as I know that typecast is
not advisable.

The problem is that if it is not used like that, the homogeneity of timer
peripheral would be lost, as TIM2 would require 32bit routines and more
space to store that table.

If this code is approved, I will commit the changes, although still two
things would be missing for correct functionality:

Force the linker to save the timer initialization structure in
<TIM2_RCC_INIT> then <TIM2_INIT1> then <TIM2_INIT> in the ld file
Write the alternate function initialization part for the GPIOs

Maybe try a more compact implementation for sparse tables, as now this
particular table consists of:

14 16b elements
in a sparse 18 16b elements separated by 17 (reserved) 16b elements
that translates to 35 16b elements

If stored in a simple 32b container: | 16b element | 16b offset |
That would translate to 28 16b elements = 20% save

If stored in the format Pekka suggested (one table for 16b elements and
another for 8b offsets), would translate to
14 x 16b + 14 x 8b = 21 16b elements = 40% save.

It is important to cite that this table is not that sparse, but it would
improve other peripherals.

BWT, now I understand a little why the STM library takes so much space,
seeing the assembly opened my eyes :)

What would be the next step??

With Warm Regards, Ivan Raul

Other related posts: