@.CHARSET  CP1251

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

.INCLUDE   "/src/inc/gpio.inc"
.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               |
@ |   SPI1  : PA5  - sck,  PA7  - mosi                |
@ |   SPI2  : PB13 - sck,  PB15 - mosi                |
@ |                                                                      |
.equ SPI1_relocation,    @   SPI1  GPIO B:       |
@ |                               (PB3 - SCK,  PB5 - MOSI)               |
@ |  !    SPI1  GPIOB  JTAG  |
@ |                                                                      |
@ +----------------------------------------------------------------------+
@ |  SPI_TX_INIT   ,   R0-R4     |
@ +----------------------------------------------------------------------+
@ |     https://youtu.be/x8-N30mxf5Q                 |
@ | ArmAsmEditor: STM32  :   SPI      |
@ |  .  16                                            |
@ +----------------------------------------------------------------------+

@.ENDDESC

@.ITEM SPI_LIST
.EQU  SPI1               , PERIPH_BASE + SPI1_BASE  @ SPI 1 (PA5  - SCK,  PA7  - MOSI)
.EQU  SPI2               , PERIPH_BASE + SPI2_BASE  @ SPI 2 (PB13 - SCK,  PB15 - MOSI)
@.end

@.CONFIG spi_interface=SPI_LIST

@.item spi1_reloc_q
.EQU              , 1     @ SPI 1 (PB3 - SCK,  PB5 - MOSI)
.EQU             , 0     @ SPI 1 (PA5 - SCK,  PA7 - MOSI)
@.end

@.CONFIG SPI1_relocation=spi1_reloc_q

.if SPI1_relocation==
   .EQU  crx_sck_pin   , 5
   .EQU  crx_mosi_pin  , 7
   .EQU  gpiox         , GPIOA
   .EQU  gpio_crx      , GPIO_CRL
.ELSE
   .EQU  crx_sck_pin   , 3
   .EQU  crx_mosi_pin  , 5
   .EQU  gpiox         , GPIOB
   .EQU  gpio_crx      , GPIO_CRL
.ENDIF

.if spi_interface==SPI2
   .EQU  crx_sck_pin   , 13 - 8
   .EQU  crx_mosi_pin  , 15 - 8
   .EQU  gpiox         , GPIOB
   .EQU  gpio_crx      , GPIO_CRH
.ENDIF



.SECTION .asmcode

.GLOBAL   SPI_TX_INIT
SPI_TX_INIT:        @  
                    MOV        R1, 1

                    LDR        R2, = PERIPH_BASE + PERIPH_BB_BASE + ( RCC_BASE + RCC_APB2ENR ) * 32

.if spi_interface==SPI1
        .if SPI1_relocation==    @ SPI 1   
                    STR        R1, [ R2, RCC_APB2ENR_IOPAEN_N * 4 ]      @  gpio A
        .else
                   @ SPI 1    ( GPIO B)
                    STR        R1, [ R2, RCC_APB2ENR_IOPBEN_N * 4 ]      @  gpio B
                    STR        R1, [ R2, RCC_APB2ENR_AFIOEN_N * 4 ]      @  AFIO   SPI1
        .endif
                    STR        R1, [ R2, RCC_APB2ENR_SPI1EN_N * 4 ]      @  SPI1
.else
                    @   SPI 2
                    STR        R1, [ R2, RCC_APB2ENR_IOPBEN_N * 4 ]      @  gpio B
                    LDR             R2, = PERIPH_BASE + PERIPH_BB_BASE + ( RCC_BASE + RCC_APB1ENR ) * 32
                    STR        R1, [ R2, RCC_APB1ENR_SPI2EN_N * 4 ]      @  SPI2
.endif

                    @     GPIO  SPI
                    LDR        R2, = gpiox
                    LDR        R4, [ R2, gpio_crx  ]    @    GPIO_CRx
                    MOV        R3, GPIO_CNF_OUT_AFPP << 2 + GPIO_MODE_OUT50
                    BFI        R4, R3, crx_sck_pin * 4, 4
                    BFI        R4, R3, crx_mosi_pin * 4, 4
                    STR        R4, [ R2, gpio_crx  ]    @    GPIO_CRx

.if (SPI1_relocation==) & (spi_interface==SPI1)   @    SPI 1
                    LDR        R2, = AFIO
                    LDR        R3, [ R2, AFIO_MAPR ]

                    MOV        R4, AFIO_MAPR_SWJ_SWD_EN        @  JTAG  SWD
                    BFI        R3, R4, AFIO_MAPR_SWJ_CFG_N, 3

                    ORR        R3, R3, AFIO_MAPR_SPI1_REMAP    @    SPI1
                    STR        R3, [ R2, AFIO_MAPR ]
.endif
                    @  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_DIV2                      @    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




