@.CharSet=CP1251
@GNU AS

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


.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

@ +-----------------------------------------------------------------------------------------------------+
@ |   логика работы:                                                                                    |
@ |    создаем 5 х-таймеров с различными частотами (периодами) и различными callback'ами                |
@ |    запускаем xtim1                                                                                  |
@ |      в колбэке callback1 переключаем LED и проверяем сколько раз сработал таймер по флагу-счетчику  |
@ |                и если он сработал нужное число раз, тогда останавливаем xtim1 и запускем xtim2      |
@ |      и так далее...                                                                                 |
@ |                                                                                                     |
@ |   пример показывает последовательную работу нескольких х-таймеров и работу tick-модуля              |
@ |                                                                                                     |
@ +-----------------------------------------------------------------------------------------------------+


.section .bss
xtim1: .word 0    @ переменые для хранения идентификаторов х-таймеров
xtim2: .word 0
xtim3: .word 0
xtim4: .word 0
xtim5: .word 0

.section .asmcode

@ основная программа
.global Start
Start:              @ поместите код своей программы ниже
                    BL         SYSCLK84_START     @ системная частота 84 МГц

.INCLUDE   "/src/inc/rcc_ahb1enr_gpio_set.inc"    @ Включим GPIO

.include   "/src/inc/gpio_c_conf.inc"             @ конфигурируем PC13 как выход push-pull

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

                @ добавление (создание) х-таймеров:
                    ldr        r0, = XTIMER_MODE_CYCLE_FLAG
                    ldr        r1, = xtim1_period
                    ldr        r2, = callback1
                    bl         xtimer_Add    @ добавили новый х-таймер
                    ldr        r3, = xtim1
                    str        r7, [ r3 ]    @ сохранили его идентификатор
                         @ Следующий х-таймер
                    ldr        r0, = XTIMER_MODE_CYCLE_FLAG
                    ldr        r1, = xtim2_period
                    ldr        r2, = callback2
                    bl         xtimer_Add    @ добавили новый х-таймер
                    ldr        r3, = xtim2
                    str        r7, [ r3 ]    @ сохранили его идентификатор
                         @ Следующий х-таймер
                    ldr        r0, = XTIMER_MODE_CYCLE_FLAG
                    ldr        r1, = xtim3_period
                    ldr        r2, = callback3
                    bl         xtimer_Add    @ добавили новый х-таймер
                    ldr        r3, = xtim3
                    str        r7, [ r3 ]    @ сохранили его идентификатор
                         @ Следующий х-таймер
                    ldr        r0, = XTIMER_MODE_CYCLE_FLAG
                    ldr        r1, = xtim4_period
                    ldr        r2, = callback4
                    bl         xtimer_Add    @ добавили новый х-таймер
                    ldr        r3, = xtim4
                    str        r7, [ r3 ]    @ сохранили его идентификатор
                         @ Следующий х-таймер
                    ldr        r0, = XTIMER_MODE_CYCLE_FLAG
                    ldr        r1, = xtim5_period
                    ldr        r2, = callback5
                    bl         xtimer_Add    @ добавили новый х-таймер
                    ldr        r3, = xtim5
                    str        r7, [ r3 ]    @ сохранили его идентификатор в xtim5

          @ это мы только создали новые х-таймеры, но ни один не запустили

          @ запустить xtim1
                    ldr        r3, = xtim1
                    ldr        r7, [ r3 ]      @ r7 = xtim1;
                    bl         xtimer_Start    @ запск xtim1


                    mov    r12, 0   @ индекс засечки для теста tick-функций

MAIN_LOOP:          @ а здесь потестируем tick-функции:
                    bl tick_set_notch      @ поставили засечку
                    nop                    @ измеряемый код
                    bl tick_get_notch      @ получили время в R1_R0. Должно быть 1 такт



                  @ *_non_stop_irq - для блоков, где нельзя включать прерывания:
                    cpsid  i    @ общие прерывания выкл.
                    cpsid  f    @ fault IRQ выкл.

                    bl tick_set_notch_non_stop_irq  @ поставили засечку
                    nop                             @ измеряемый код
                    bl tick_get_notch_non_stop_irq  @ получили время в R1_R0. Должно быть 1 такт

                    cpsie  f    @ fault IRq вкл.
                    cpsie  i    @ общие прерывания вкл.
                       @ !!! прерывания надо включать, иначе х-таймеры перестанут работать.

                    b      MAIN_LOOP


.EQU  pc13_out_bb   , PERIPH_BB_BASE + ( GPIOC_BASE + GPIO_ODR ) * 32 + 13 * 4
.global toggle_LED  @ переключает состояние PC13 на противоположное
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

callback1:    push   { lr }  @ на входе r1 = compare, r3 = FlagCnt, r0 = r7 = tID индекс таймера
              bl     toggle_LED    @ переключим LED
              ldr    r1, = xtim1_fl_cnt
              cmp    r3, r1
              it     ls    @ если не досчитали, то выходим
              popls  { pc }
         @ если досчитали, то останавливаем xtim1 и запускаем xtim2
              bl     xtimer_Stop          @ остановили xtim1
              ldr    r1, = xtim2
              ldr    r7, [ r1 ]           @ r7 = xtim2
              mov    r3, 0
              bl     xtimer_SetFlagCnt    @ сбросили флаг-счетчик в xtim2
              bl     xtimer_Restart       @ запустили таймер xtim2
              pop    { pc }

callback2:    push   { lr }  @ на входе r1 = compare, r3 = FlagCnt, r0 = r7 = tID индекс таймера
              bl     toggle_LED    @ переключим LED
              ldr    r1, = xtim2_fl_cnt
              cmp    r3, r1
              it     ls    @ если не досчитали, то выходим
              popls  { pc }
         @ если досчитали, то останавливаем xtim2 и запускаем xtim3
              bl     xtimer_Stop          @ остановили xtim2
              ldr    r1, = xtim3
              ldr    r7, [ r1 ]           @ r7 = xtim3
              mov    r3, 0
              bl     xtimer_SetFlagCnt    @ сбросили флаг-счетчик в xtim3
              bl     xtimer_Restart       @ запустили таймер xtim3
              pop    { pc }


callback3:    push   { lr }  @ на входе r1 = compare, r3 = FlagCnt, r0 = r7 = tID индекс таймера
              bl     toggle_LED    @ переключим LED
              ldr    r1, = xtim3_fl_cnt
              cmp    r3, r1
              it     ls    @ если не досчитали, то выходим
              popls  { pc }
         @ если досчитали, то останавливаем xtim3 и запускаем xtim4
              bl     xtimer_Stop          @ остановили xtim3
              ldr    r1, = xtim4
              ldr    r7, [ r1 ]           @ r7 = xtim4
              mov    r3, 0
              bl     xtimer_SetFlagCnt    @ сбросили флаг-счетчик в xtim4
              bl     xtimer_Restart       @ запустили таймер xtim4
              pop    { pc }


callback4:    push   { lr }  @ на входе r1 = compare, r3 = FlagCnt, r0 = r7 = tID индекс таймера
              bl     toggle_LED    @ переключим LED
              ldr    r1, = xtim4_fl_cnt
              cmp    r3, r1
              it     ls    @ если не досчитали, то выходим
              popls  { pc }
         @ если досчитали, то останавливаем xtim4 и запускаем xtim5
              bl     xtimer_Stop          @ остановили xtim4
              ldr    r1, = xtim5
              ldr    r7, [ r1 ]           @ r7 = xtim5
              mov    r3, 0
              bl     xtimer_SetFlagCnt    @ сбросили флаг-счетчик в xtim5
              bl     xtimer_Restart       @ запустили таймер xtim5
              pop    { pc }


callback5:    push   { lr }  @ на входе r1 = compare, r3 = FlagCnt, r0 = r7 = tID индекс таймера
              bl     toggle_LED    @ переключим LED
              ldr    r1, = xtim5_fl_cnt
              cmp    r3, r1
              it     ls    @ если не досчитали, то выходим
              popls  { pc }
         @ если досчитали, то останавливаем xtim5 и запускаем xtim1
              bl     xtimer_Stop          @ остановили xtim5
              ldr    r1, = xtim1
              ldr    r7, [ r1 ]           @ r7 = xtim1
              mov    r3, 0
              bl     xtimer_SetFlagCnt    @ сбросили флаг-счетчик в xtim1
              bl     xtimer_Restart       @ запустили таймер xtim1
              pop    { pc }




