@.CHARSET  CP1251

@ GNU AS
.SYNTAX   unified
.CPU      cortex-m4
.THUMB

.INCLUDE   "/src/inc/rcc.inc"
.INCLUDE   "/src/inc/spi.inc"

@.DESC     name=SPI_TX_INIT type=proc
@ +----------------------------------------------------------------------+
@ |              Процедура инициализации аппаратного SPI                 |
@ +----------------------------------------------------------------------+
@ | Модуль реализует программный SPI для отправки данных для любого GPIO |
@ | указанного в следующих настройках:                                   |
@ |                                                                      |
.EQU  spi_interface , SPI1         @ имя используемого SPI               |
@ |                                                                      |
@ | Настройка GPIO для выходных пинов SPI должна осуществляется во внеш- |
@ | нем модуле                                                           |
@ +----------------------------------------------------------------------+
@ | вызов SPI_TX_INIT параметров не требует, изменяет регистры R0-R4     |
@ +----------------------------------------------------------------------+

@.ENDDESC

@.ITEM SPI_LIST
.EQU  SPI1               , PERIPH_BASE + SPI1_BASE  @ SPI 1
.EQU  SPI2               , PERIPH_BASE + SPI2_BASE  @ SPI 2
.EQU  SPI3               , PERIPH_BASE + SPI3_BASE  @ SPI 3
.EQU  SPI4               , PERIPH_BASE + SPI4_BASE  @ SPI 4
@.end

@.CONFIG spi_interface=SPI_LIST

.SECTION .asmcode

.GLOBAL   SPI_TX_INIT
SPI_TX_INIT:        @ первоначальная настройка
                    @ включим SPI1
                    LDR        R2, = PERIPH_BB_BASE + ( RCC_BASE + RCC_APB2ENR ) * 32
                    MOV        R1, 1
                    STR        R1, [ R2, RCC_APB2ENR_SPI1EN_N * 4 ]

                    @ настройка SPI
                    LDR        R2, = spi_interface

     @ настройки интерфейса SPI
.EQU  spi_dir        , SPI_CR1_BIDIOE                       @ Output enabled (transmit-only mode)
.EQU  spi_mode_master, SPI_CR1_MSTR | SPI_CR1_SSI           @ SPI_Mode_Master &  SSI: Internal slave select
.EQU  spi_nss        , SPI_CR1_SSM  | SPI_CR1_SPE           @ SPI_NSS_Soft    & SPI_Enable
.EQU  spi_br_presc   , SPI_CR1_BR_DIV_2                     @ делитель частоты для SPI

                    LDR        R3, = spi_dir | spi_mode_master | spi_nss | spi_br_presc
                    STR        R3, [ R2, SPI_CR1 ]

                    BX         LR

@.DESC     name=SPI_TX_SEND type=proc
@ +-----------------------------------------------------------------------+
@ |                      Процедура отправки байта по SPI                  |
@ +-----------------------------------------------------------------------+
@ | Передаваемые данные должны быть переданы в R4                         |
@ | при отправке происходит ожидание конца передачи (флаги TXE, BSY)      |
@ | Процедура не изменяет значения регистров                              |
@ +-----------------------------------------------------------------------+
@.ENDDESC

.GLOBAL   SPI_TX_SEND
SPI_TX_SEND:      @ Отправка байта по spi
                    PUSH       {  R1 }

                    LDR        R1, = spi_interface

                    STR        R4, [ R1, SPI_DR ]   @ отправим байт на SPI

                    POP        {  R1 }

@.DESC     name=SPI_TXE_BSY_WAIT type=proc
@ +-----------------------------------------------------------------------+
@ |             Процедура ожидания завершения передачи по SPI             |
@ +-----------------------------------------------------------------------+
@ | Параметров нет                                                        |
@ | Процедура не изменяет значения регистров                              |
@ +-----------------------------------------------------------------------+
@.ENDDESC

.GLOBAL   SPI_TXE_BSY_WAIT
SPI_TXE_BSY_WAIT:   PUSH       { R0, R1 }

                    LDR        R1, = spi_interface

SPI_TXE_WAIT:       @ проверим флаг занятости TXE
                    LDR        R0, [ R1, SPI_SR ]
                    TST        R0, SPI_SR_TXE
                    BEQ        SPI_TXE_WAIT

SPI_BSY_WAIT:       @ проверим флаг занятости BSY
                    LDR        R0, [ R1, SPI_SR ]
                    TST        R0, SPI_SR_BSY
                    BNE        SPI_BSY_WAIT

                    POP        { R0, R1 }

                    BX         LR




