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().
functions.s@0:5446675502f2, 2020-04-22 (annotated)
- Committer:
- ghsalazar
- Date:
- Wed Apr 22 15:14:54 2020 +0000
- Revision:
- 0:5446675502f2
Initial commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
ghsalazar | 0:5446675502f2 | 1 | ; @file main.S |
ghsalazar | 0:5446675502f2 | 2 | ; @author Gastón SALAZAR <gaston_salazar@yahoo.com> |
ghsalazar | 0:5446675502f2 | 3 | ; |
ghsalazar | 0:5446675502f2 | 4 | ; @brief A blink program for the STM32F446re in assembly. |
ghsalazar | 0:5446675502f2 | 5 | ; It implements a state machine. It requires a basic |
ghsalazar | 0:5446675502f2 | 6 | ; C++ main function. |
ghsalazar | 0:5446675502f2 | 7 | ; |
ghsalazar | 0:5446675502f2 | 8 | ; This example is used as a didactical resource. |
ghsalazar | 0:5446675502f2 | 9 | |
ghsalazar | 0:5446675502f2 | 10 | AREA functions_asm, CODE, READONLY |
ghsalazar | 0:5446675502f2 | 11 | |
ghsalazar | 0:5446675502f2 | 12 | ; Interface |
ghsalazar | 0:5446675502f2 | 13 | |
ghsalazar | 0:5446675502f2 | 14 | ; @def LED |
ghsalazar | 0:5446675502f2 | 15 | ; @brief The bit address of pin 5 on port A. |
ghsalazar | 0:5446675502f2 | 16 | LED EQU (1 << 5) |
ghsalazar | 0:5446675502f2 | 17 | |
ghsalazar | 0:5446675502f2 | 18 | ; @def DELAY |
ghsalazar | 0:5446675502f2 | 19 | ; @brief The number of loops to execute before changing th state of LED. |
ghsalazar | 0:5446675502f2 | 20 | DELAY EQU 5000000 |
ghsalazar | 0:5446675502f2 | 21 | |
ghsalazar | 0:5446675502f2 | 22 | RCC_AHB1ENR EQU 0x40023830 ; Register for enabling the AHB1 clock for GPIOA |
ghsalazar | 0:5446675502f2 | 23 | GPIOAEN EQU (1 << 0) |
ghsalazar | 0:5446675502f2 | 24 | |
ghsalazar | 0:5446675502f2 | 25 | GPIOA EQU 0x40020000 ; Base address of port-A registers |
ghsalazar | 0:5446675502f2 | 26 | |
ghsalazar | 0:5446675502f2 | 27 | |
ghsalazar | 0:5446675502f2 | 28 | GPIO_MODER EQU 0x00 ; Offsets of the registers for port X, |
ghsalazar | 0:5446675502f2 | 29 | GPIO_PUPDR EQU 0x0c ; using as base the port address |
ghsalazar | 0:5446675502f2 | 30 | GPIO_ODR EQU 0x14 |
ghsalazar | 0:5446675502f2 | 31 | |
ghsalazar | 0:5446675502f2 | 32 | RESET_MODER5 EQU (3 << 10) ; Bit addresses in the port registers, in order to configure the behaviour of the output pin |
ghsalazar | 0:5446675502f2 | 33 | SET_MODER5 EQU (1 << 10) |
ghsalazar | 0:5446675502f2 | 34 | RESET_PUPDR5 EQU (3 << 10) |
ghsalazar | 0:5446675502f2 | 35 | |
ghsalazar | 0:5446675502f2 | 36 | EXPORT setup |
ghsalazar | 0:5446675502f2 | 37 | |
ghsalazar | 0:5446675502f2 | 38 | setup ; Machine setup |
ghsalazar | 0:5446675502f2 | 39 | |
ghsalazar | 0:5446675502f2 | 40 | ; Enable port A |
ghsalazar | 0:5446675502f2 | 41 | LDR R0, =RCC_AHB1ENR ; R0 = RCC_AHB1ENR |
ghsalazar | 0:5446675502f2 | 42 | LDR R1, [R0] ; R1 = *R0 |
ghsalazar | 0:5446675502f2 | 43 | ORR R1, R1, #GPIOAEN ; R1 = R1 | GPIOAEN |
ghsalazar | 0:5446675502f2 | 44 | STR R1, [R0] ; *R0 = R1 |
ghsalazar | 0:5446675502f2 | 45 | |
ghsalazar | 0:5446675502f2 | 46 | ; A minimal initialization for PA5 as output (LED) on the STM32F446re |
ghsalazar | 0:5446675502f2 | 47 | LDR R3, =GPIOA |
ghsalazar | 0:5446675502f2 | 48 | |
ghsalazar | 0:5446675502f2 | 49 | LDR R1, [R3, #GPIO_MODER] ; R1 = R3[GPIO_MODER] |
ghsalazar | 0:5446675502f2 | 50 | BIC R1, R1, #RESET_MODER5 ; R1 = R1 & ~RESET_MODER5 |
ghsalazar | 0:5446675502f2 | 51 | ORR R1, R1, #SET_MODER5 |
ghsalazar | 0:5446675502f2 | 52 | STR R1, [R3, #GPIO_MODER] ; R3[GPIO_MODER] = R1 |
ghsalazar | 0:5446675502f2 | 53 | |
ghsalazar | 0:5446675502f2 | 54 | LDR R1, [R3, #GPIO_PUPDR] |
ghsalazar | 0:5446675502f2 | 55 | BIC R1, R1, #RESET_PUPDR5 |
ghsalazar | 0:5446675502f2 | 56 | STR R1, [R3, #GPIO_PUPDR] |
ghsalazar | 0:5446675502f2 | 57 | |
ghsalazar | 0:5446675502f2 | 58 | ; State initilization |
ghsalazar | 0:5446675502f2 | 59 | ; LED = 0 |
ghsalazar | 0:5446675502f2 | 60 | LDR R1, [R3, #GPIO_ODR] |
ghsalazar | 0:5446675502f2 | 61 | BIC R1, R1,#LED |
ghsalazar | 0:5446675502f2 | 62 | STR R1, [R3, #GPIO_ODR] |
ghsalazar | 0:5446675502f2 | 63 | |
ghsalazar | 0:5446675502f2 | 64 | BX LR |
ghsalazar | 0:5446675502f2 | 65 | |
ghsalazar | 0:5446675502f2 | 66 | ALIGN |
ghsalazar | 0:5446675502f2 | 67 | EXPORT loop |
ghsalazar | 0:5446675502f2 | 68 | loop |
ghsalazar | 0:5446675502f2 | 69 | ; State update |
ghsalazar | 0:5446675502f2 | 70 | LDR R3, =GPIOA |
ghsalazar | 0:5446675502f2 | 71 | LDR R0, =DELAY |
ghsalazar | 0:5446675502f2 | 72 | loop1 |
ghsalazar | 0:5446675502f2 | 73 | CBNZ R0, wait ; if (R0!=0) goto wait |
ghsalazar | 0:5446675502f2 | 74 | LDR R1, [R3, #GPIO_ODR] |
ghsalazar | 0:5446675502f2 | 75 | EOR R1, R1, #LED ; R1 = R1 ^ LED |
ghsalazar | 0:5446675502f2 | 76 | STR R1, [R3, #GPIO_ODR] |
ghsalazar | 0:5446675502f2 | 77 | LDR R0, =DELAY |
ghsalazar | 0:5446675502f2 | 78 | wait |
ghsalazar | 0:5446675502f2 | 79 | SUB R0, R0, #1 ; R0 = R0 - 1 |
ghsalazar | 0:5446675502f2 | 80 | B loop1 ; goto loop |
ghsalazar | 0:5446675502f2 | 81 | |
ghsalazar | 0:5446675502f2 | 82 | BX LR ; end of function main, to never be reached |
ghsalazar | 0:5446675502f2 | 83 | END |