@.CharSet=CP1251
@GNU AS

.syntax unified     @ синтаксис исходного кода
.thumb              @ тип используемых инструкций Thumb
.cpu cortex-m3      @ процессор

.INCLUDE   "/src/inc/rcc.inc"    @ определения RCC
.INCLUDE   "/src/inc/gpio.inc"

.equ xtim1_fl_cnt, 20   @ число срабатываний до переключения на следующий х-таймер
.equ xtim1_period, 100  @ период срабатывания в миллисекундах

.equ xtim2_fl_cnt, 6
.equ xtim2_period, 1000

.equ xtim3_fl_cnt, 10
.equ xtim3_period, 500

.equ xtim4_fl_cnt, 4
.equ xtim4_period, 2000

.equ xtim5_fl_cnt, 50
.equ xtim5_period, 40

@ /*
@      логика работы:
@      создаём 1 х-таймер с колбэком и запускаем его
@        в колбэке переключаем LED и по флагу-счетчику проверяем сколько раз сработал таймер
@                  и если он сработал нужное число раз, тогда загружаем новые параметры в х-таймер
@      создаём 2й х-таймер для теста xtimer_Delay
@        xtimer_Delay в главном цикле. Тестируем в режиме отладки с установкой BreakPoint'ов на "nop"
@
@     пример показывает последовательную работу 5 режимов с помощью одного х-таймера.
@        По-хорошему так и должно быть: на каждый выход не более 1 х-таймера.
@     так же пример показывает параллельную работу 2х х-таймеров - один на PC13, другой на xtimer_Delay
@
@ */


.section .bss

my_index:     .word  0    @ текущий индекс массива
my_struct:    .space  ( 5 * 8 )    @  массив структур с пределами флаг-счётчиков и периодами
.equ  my_struct_fl_cnt, 0   @ смещения полей в структуре
.equ  my_struct_period, 4

.section .asmcode

@ основная программа
.global Start
Start:              @ поместите код своей программы ниже

@ системная частота на 72 MHz
                    BL         SYSCLK72

@ инициализация PC13
                    bl        PortC13_init

@ инициализация модуля х-таймеров
                    bl         xtimer_Init

@ добавление (создание) х-таймера:
                    ldr        r0, = XTIMER_MODE_CYCLE_FLAG
                    ldr        r1, = xtim1_period
                    ldr        r2, = x_callback
                    bl         xtimer_Add    @ добавили новый х-таймер
                   @ идентификатор не сохранили - не потребуется
                    bl         xtimer_Add    @ добавили ещё один для теста xtimer_Delay
                   @ здесь идентификатор будет = 1 ( в порядке добавления )

          @ готовим массив my_struct
              ldr    r1, = my_struct
              ldr    r0, = xtim1_fl_cnt
              str    r0, [ r1 ], 4    @ Post-indexed адресация
              ldr    r0, = xtim1_period
              str    r0, [ r1 ], 4

              ldr    r0, = xtim2_fl_cnt
              str    r0, [ r1 ], 4
              ldr    r0, = xtim2_period
              str    r0, [ r1 ], 4

              ldr    r0, = xtim3_fl_cnt
              str    r0, [ r1 ], 4
              ldr    r0, = xtim3_period
              str    r0, [ r1 ], 4

              ldr    r0, = xtim4_fl_cnt
              str    r0, [ r1 ], 4
              ldr    r0, = xtim4_period
              str    r0, [ r1 ], 4

              ldr    r0, = xtim5_fl_cnt
              str    r0, [ r1 ], 4
              ldr    r0, = xtim5_period
              str    r0, [ r1 ], 4

            @ указываем текущий индекс
              mov    r0, 0
              ldr    r1, = my_index
              str    r0, [ r1 ]

            @ запустить наш х-таймер
                    mov    r7, 0
                    bl     xtimer_Start    @ запск xtim1


                    mov    r7, 1  @ tID для xtimer_Delay
MAIN_LOOP:

              ldr    r1, = 1500
              bl     xtimer_Delay @ задержка 1,5 секунды
              nop                 @ команда для точки останова в режиме отладки

              ldr    r1, = 5000
              bl     xtimer_Delay @ задержка 5 секунд
              nop                 @ команда для точки останова в режиме отладки

              B      MAIN_LOOP



PortC13_init: push   { r0 - r2 }
              mov    r1, 1
              ldr    r0, = PERIPH_BASE + PERIPH_BB_BASE + ( RCC_BASE + RCC_APB2ENR ) * 32
              str    r1, [ r0, RCC_APB2ENR_IOPCEN_N * 4 ]
              ldr    r0, = GPIOC
              ldr    r1, [ r0, GPIO_CRH ]
              mov    r2, GPIO_MODE_OUT2
              bfi    r1, r2, GPIO_CRH_MODE13_N, 4
              str    r1, [ r0, GPIO_CRH ]
              pop    { r0 - r2 }
              bx     lr


.EQU  pc13_out_bb   , PERIPH_BASE + PERIPH_BB_BASE + ( GPIOC_BASE + GPIO_ODR ) * 32 + 13 * 4
.global toggle_LED
toggle_LED:         push       { r1 - r3 }
                    mov        r1, 1
                    ldr        r2, = pc13_out_bb
                    ldr        r3, [ r2 ]
                    sub        r3, r1, r3    @ R3 = 1 - R3
                    str        r3, [ r2 ]
                    pop        { r1 - r3 }
                    bx         lr


x_callback:   push   { lr }  @ на входе r1 = compare, r3 = FlagCnt, r0 = r7 = tID индекс таймера
              bl     toggle_LED    @ переключим LED

              ldr    r0, = my_index
              ldr    r0, [ r0 ]  @ r0 = индекс в массиве

              ldr    r12, = my_struct    @ базовый адрес my_struct
              mov    r2, 8        @ множитель
              mla    r1, r0, r2, r12  @  r1 = индекс * 8 + addr(my_struct)   адрес структуры по индексу R0
              ldr    r1, [ r1, my_struct_fl_cnt ]    @  r1 = предел флаг-счетчика для текущего индекса.

              cmp    r3, r1
              it     ls    @ если не досчитали, то выходим
              popls  { pc }
         @ если досчитали, то генерируем следующий индекс для массива структур
              add    r0, 1
              cmp    r0, 4
              it     hi
              movhi  r0, 0    @ если индекс больше 4, тогда обнуляем
              ldr    r1, = my_index
              str    r0, [ r1 ] @ сохранили новый индекс

              mla    r1, r0, r2, r12  @  r1 = индекс * 8 + addr(my_struct)

              ldr    r1, [ r1, my_struct_period ]
              bl     xtimer_SetCompare  @ задали новый период работы х-таймера

              mov    r3, 0
              bl     xtimer_SetFlagCnt   @ сбросили флаг-счетчик х-таймера
              pop    { pc }



