@.CHARSET CP1251

@ GNU AS
.syntax unified
.cpu cortex-m4
.thumb
.fpu fpv4-sp-d16

.INCLUDE   "/src/inc/rcc.inc"
.INCLUDE   "/src/inc/adc.inc"
.INCLUDE   "/src/inc/dma.inc"

.section .bss

@ переменные в озу в которые происходит оцифровка каналов 1-3 adc
.global ADC_INPUT_1
.global ADC_INPUT_2
.global ADC_INPUT_3
ADC_INPUT_1:   .space 2   @ напряжение зарядки
ADC_INPUT_2:   .space 2   @ напряжение батареи
ADC_INPUT_3:        .SPACE     2    @ петля (в базе не используется)

.section .asmcode

@.desc name=ADC_INIT type=proc
@ +---------------------------------------------------------------------+
@ |      Запуск автоматического аналого-цифрового преобразования        |
@ +---------------------------------------------------------------------+
@ | Преобразование осуществляется в автоматическом режиме,  результат   |
@ | преобразования помещается в ОЗУ: ADC_INPUT_1 - ADC_INPUT_3          |
@ +---------------------------------------------------------------------+
@.enddesc

.global ADC_INIT
ADC_INIT:
                    PUSH       { LR }

                    @ сбросим состояние переменных
                    LDR        R0, = ADC_INPUT_1
                    MOV        R1, 0
                    STRH       R1, [ R0 ], 2
                    STRH       R1, [ R0 ], 2
                    STRH       R1, [ R0 ], 2

                @ тактирование ADC1
                    mov        R1, 1
                    LDR        R0, =PERIPH_BB_BASE + ( RCC_BASE + RCC_APB2ENR ) * 32 + RCC_APB2ENR_ADC1EN_N * 4
                    STR        R1, [ R0 ]
                @ тактирование ADC1 происходит по шине APB2 с ее тактом в 42 мгц
                @ ADCPRE=0 в регистре ADC_CCR - делит частоту еще на 2 => 42\2=21 мгц
                @ согласно Table 66. ADC characteristics (continued) Datasheet DS9716
                @ максимально допустимая частота 36 мгц (норма - 30 мгц)

               @ тактирование DMA2
                    LDR        R0, =PERIPH_BB_BASE + ( RCC_BASE + RCC_AHB1ENR ) * 32 + RCC_AHB1ENR_DMA2EN_N * 4
                    STR        R1, [ R0 ]

              @ инициализация ADC -----------------------------------------------------------------------------
                    LDR        R0, = ADC1

              @ используемые входы ацп в ADC_SQRx (преобразование нескольких регулярных каналов)
                    MOV        R1, ADC_CR1_SCAN
                    STR        R1, [ R0, ADC_CR1 ]

              @ непрерывное преобразование с запросами DMA
                    LDR        R1, = ADC_CR2_CONT + ADC_CR2_EOCS + ADC_CR2_DMA + ADC_CR2_DDS
                    STR        R1, [ R0, ADC_CR2 ]

              @ количество каналов преобразования = 3 (0 => 1, 1 => 2, 2 => 3)
                    MOV        R1, 2 << ADC_SQR1_L
                    STR        R1, [ R0, ADC_SQR1 ]

              @ последовательность опроса каналов
                    LDR        R1, = 1 << ADC_SQR3_SQ1_N + 2 << ADC_SQR3_SQ2_N + 3 << ADC_SQR3_SQ3_N
                    STR        R1, [ R0, ADC_SQR3 ]

              @ количество циклов преобразования для каждого из 3х каналов (c 1-го по 3-ий)

.EQU  smp1          , ADC_SMPR2_SMPx_480C << ADC_SMPR2_SMP1_N    @ время преобразования IN1
.EQU  smp2          , ADC_SMPR2_SMPx_480C << ADC_SMPR2_SMP2_N    @ время преобразования IN2
.EQU  smp3          , ADC_SMPR2_SMPx_480C << ADC_SMPR2_SMP3_N    @ время преобразования IN3

                    LDR        R1, =smp1 + smp2 + smp3
                    STR        R1, [ R0, ADC_SMPR2 ]

               @ включение ADC ---------------------------------------------------------------------------------
                    LDR        R0, = PERIPH_BB_BASE + ( ADC1_BASE + ADC_CR2 ) * 32
                    MOV        R1, 1
                    STR        R1, [ R0, ADC_CR2_ADON_N * 4 ]

               @ ожидание 10 мс
                    MOV        R0, 10
                    BL         SYSTICK_DELAY

               @ Инициализация DMA2 ----------------------------------------------------------------------------
                    LDR        R0, = DMA2

.EQU  size          , DMA_SxCR_PSIZE_16B + DMA_SxCR_MSIZE_16B  @ размер операций пересылки 16 бит
                                        @  высший приеоритет   циркул. режим  увеличить адрес в памяти  прерывания по завершению
                    LDR        R1, = size + DMA_SxCR_PL_VHIGH + DMA_SxCR_CIRC  + DMA_SxCR_MINC  @ + DMA_SxCR_TCIE
                    STR        R1, [ R0, DMA_S0CR ]

               @ старт DMA2 Stream 0
               @ сброс флагов, если есть установленные то без этого dma работать не будет
@                    MOV        R1, DMA_LIFCR_CFEIF0+DMA_LIFCR_CDMEIF0+DMA_LIFCR_CTEIF0+DMA_LIFCR_CHTIF0+DMA_LIFCR_СTCIF0
@                    STR        R1, [ R0, DMA_LIFCR ]

                    MOV        R1, 3   @ количество передач = 3, по одному для каждого канала оцифровки
                    STR        R1, [ R0, DMA_S0NDTR ]

                    LDR        R1, = ADC1 + ADC_DR    @ адрес регистра данных ADC
                    STR        R1, [ R0, DMA_S0PAR ]

                    LDR        R1, = ADC_INPUT_1
                    STR        R1, [ R0, DMA_S0M0AR ]

                    LDR        R0, = PERIPH_BB_BASE + ( DMA2_BASE + DMA_S0CR ) * 32
                    MOV        R1, 1
                    STR        R1, [ R0, DMA_SxCR_EN_N * 4 ]

               @ старт ADC -------------------------------------------------------------------------------------

               @ сбросим флаги исполнения
@                    LDR        R0, = ADC1
@                    MOV        R1, 0
@                    STR        R1, [ R0, ADC_SR ]

              @ запускаем преобразование
                    LDR        R0, = PERIPH_BB_BASE + ( ADC1_BASE + ADC_CR2 ) * 32
                    MOV        R1, 1
                    STR        R1, [ R0, ADC_CR2_SWSTART_N * 4 ]

                    POP        { PC }
