This is a simple example of assembly-language programming inside of an MBED program. It is just a blink program with two functions: setup() and loop().

Dependencies:   mbed

functions.s

Committer:
ghsalazar
Date:
2020-04-22
Revision:
0:5446675502f2

File content as of revision 0:5446675502f2:

;   @file   main.S
;   @author Gastón SALAZAR  <gaston_salazar@yahoo.com>
;
;   @brief  A blink program for the STM32F446re in assembly.
;           It implements a state machine. It requires a basic
;           C++ main function.
;
;   This example is used as a didactical resource.

    AREA    functions_asm, CODE, READONLY

;   Interface

;   @def    LED
;   @brief  The bit address of pin 5 on port A.
LED     EQU (1 << 5)

;    @def    DELAY
;    @brief  The number of loops to execute before changing th state of LED.
DELAY   EQU 5000000

RCC_AHB1ENR EQU 0x40023830  ; Register for enabling the AHB1 clock for GPIOA
GPIOAEN     EQU (1 << 0)

GPIOA       EQU 0x40020000  ; Base address of port-A registers


GPIO_MODER  EQU 0x00    ; Offsets of the registers for port X,
GPIO_PUPDR  EQU 0x0c    ; using as base the port address
GPIO_ODR    EQU 0x14

RESET_MODER5    EQU (3 << 10)   ; Bit addresses in the port registers, in order to configure the behaviour of the output pin
SET_MODER5      EQU (1 << 10)
RESET_PUPDR5    EQU (3 << 10)

    EXPORT setup

setup   ; Machine setup

    ; Enable port A
    LDR R0, =RCC_AHB1ENR    ; R0 = RCC_AHB1ENR
    LDR R1, [R0]            ; R1 = *R0
    ORR R1, R1, #GPIOAEN     ; R1 = R1 | GPIOAEN
    STR R1, [R0]            ; *R0 = R1

    ; A minimal initialization for PA5 as output (LED) on the STM32F446re
    LDR R3, =GPIOA

    LDR R1, [R3, #GPIO_MODER]    ; R1 = R3[GPIO_MODER]
    BIC R1, R1, #RESET_MODER5    ; R1 = R1 & ~RESET_MODER5
    ORR R1, R1, #SET_MODER5
    STR R1, [R3, #GPIO_MODER]    ; R3[GPIO_MODER] = R1

    LDR R1, [R3, #GPIO_PUPDR]
    BIC R1, R1, #RESET_PUPDR5
    STR R1, [R3, #GPIO_PUPDR]

;    State initilization
    ; LED = 0
    LDR R1, [R3, #GPIO_ODR]
    BIC R1, R1,#LED
    STR R1, [R3, #GPIO_ODR]

    BX      LR
    
    ALIGN
    EXPORT loop
loop
;    State update
    LDR R3, =GPIOA
    LDR R0, =DELAY
loop1
    CBNZ    R0, wait           ; if (R0!=0) goto wait
    LDR     R1, [R3, #GPIO_ODR]
    EOR     R1, R1, #LED        ; R1 = R1 ^ LED
    STR     R1, [R3, #GPIO_ODR]
    LDR     R0, =DELAY
wait
    SUB     R0, R0, #1           ; R0 = R0 - 1
    B       loop1                ; goto loop

    BX      LR  ; end of function main, to never be reached
    END