#****************************************************************************************# # Project: task2 - ASM: Interrupts # File: task2.s # Hardware: STefi Light v1.1 # Processor: STM32G431KBT6U #****************************************************************************************# .include "G431_addr.s" // Zusätzliche und benötigte Adressen .equ RCC_AHB2ENR, 0x4002104C .equ RCC_APB2ENR, 0x40021060 .equ GPIOA_MODER, 0x48000000 .equ GPIOA_ODR, 0x48000014 .equ GPIOC_MODER, 0x48000800 .equ GPIOC_PUPDR, 0x4800080C .equ GPIOC_IDR, 0x48000810 .equ SYSCFG_BASE, 0x40010000 .equ SYSCFG_EXTICR4, (SYSCFG_BASE + 0x14) .equ EXTI_BASE, 0x40010400 .equ EXTI_IMR1, (EXTI_BASE + 0x00) .equ EXTI_FTSR1, (EXTI_BASE + 0x0C) .equ EXTI_PR1, (EXTI_BASE + 0x14) .equ NVIC_ISER1, 0xE000E104 #----------------------------------------------------------------------------------------# .section .vectortable,"a" // vector table at begin of ROM #----------------------------------------------------------------------------------------# .align 2 .word 0x20004000 // initial Stack Pointer .word 0x08000401 // initial Program Counter .word _ISR_NMI // non-masking interrupt .word _ISR_HARDF // hard fault interrupt .space 0xD0 // padding 208 Bytes bis Offset 0xE0 (EXTI15_10 IRQ 40) .word _ISR_S0_S1 // gemeinsamer Interrupt für PC13 (S0) und PC14 (S1) #----------------------------------------------------------------------------------------# .text // section .text (default section for program code) #----------------------------------------------------------------------------------------# .align 2 .syntax unified .thumb .thumb_func .global init .type init, %function init: CPSID i // disable interrupts globally MOVS r0, #0 // safely initialize the GPRs MOVS r1, #0 MOVS r2, #0 MOVS r3, #0 MOVS r4, #0 MOVS r5, #0 MOVS r6, #0 MOVS r7, #0 MOV r8, r0 MOV r9, r0 MOV r10, r0 MOV r11, r0 MOV r12, r0 #--- enable port clocking LDR r1, =RCC_AHB2ENR MOVS r2, #0x05 // Bit 0 (GPIOA) und Bit 2 (GPIOC) LDR r0, [r1, #0] ORRS r0, r2 STR r0, [r1, #0] #--- port init #- LEDs (PA0-PA3) LDR r1, =GPIOA_MODER LDR r2, =0x000000FF // Maske PA0-PA3 LDR r0, [r1, #0] BICS r0, r2 LDR r2, =0x00000055 // Maske Output 0101 0101 ORRS r0, r2 STR r0, [r1, #0] #- switch LED off LDR r1, =GPIOA_ODR MOVS r2, #0x0F // Maske LED0-3 LDR r0, [r1, #0] ORRS r0, r2 STR r0, [r1, #0] #- buttons (PC13, PC14 als Input) LDR r1, =GPIOC_MODER LDR r2, =0x3C000000 // Maske Bits 26-29 LDR r0, [r1, #0] BICS r0, r2 STR r0, [r1, #0] #- Pull-Up für PC13, PC14 LDR r1, =GPIOC_PUPDR LDR r2, =0x3C000000 LDR r0, [r1, #0] BICS r0, r2 LDR r2, =0x14000000 // 01 = Pull-Up für PC13 (Bits 27:26) und PC14 (Bits 29:28) ORRS r0, r2 STR r0, [r1, #0] #--- button interrupt config #- enable clock for SYSCFG module LDR r1, =RCC_APB2ENR MOVS r2, #0x01 LDR r0, [r1, #0] ORRS r0, r2 STR r0, [r1, #0] #- connect GPIO pins of the buttons to EXTended Interrupt controller lines (EXTI) LDR r1, =SYSCFG_EXTICR4 LDR r2, =0x00000FF0 // Maske für EXTI13 (Bits 7:4) und EXTI14 (Bits 11:8) LDR r0, [r1, #0] BICS r0, r2 LDR r2, =0x00000220 // Port C (0010) für EXTI13 und EXTI14 ORRS r0, r2 STR r0, [r1, #0] #- configure lines in EXTI module (EXTI_* registers) LDR r1, =EXTI_FTSR1 // Fallende Flanke LDR r2, =0x00006000 // Bits 13 und 14 LDR r0, [r1, #0] ORRS r0, r2 STR r0, [r1, #0] LDR r1, =EXTI_IMR1 // Maskierung aufheben LDR r2, =0x00006000 LDR r0, [r1, #0] ORRS r0, r2 STR r0, [r1, #0] #- NVIC: set interrupt priority, clear pending bits LDR r1, =NVIC_ISER1 LDR r2, =0x00000100 // Bit 8 für IRQ 40 (EXTI15_10) LDR r0, [r1, #0] ORRS r0, r2 STR r0, [r1, #0] CPSIE i // enable interrupts globally #----------------------------------------------------------------------------------------# .align 2 .syntax unified .thumb .thumb_func .global main .type main, %function main: WFI B main #----------------------------------------------------------------------------------------# .align 2 .syntax unified .thumb .thumb_func .global delay .type delay, %function delay: LDR r0, =106000 // Entprell-Zeit ~20ms .L1: SUBS r0, r0, #1 BNE .L1 BX lr #----------------------------------------------------------------------------------------# .align 2 .global stop stop: NOP B stop #----------------------------------------------------------------------------------------# .lp1: .ltorg #----------------------------------------------------------------------------------------# #----------------------------------------------------------------------------------------# .section .exhand,"ax" // section for exception handlers #----------------------------------------------------------------------------------------# .align 2 .syntax unified .thumb .type _ISR_NMI, %function _ISR_NMI: LDR r1, =RCC_AHB2ENR MOV r2, #0x01 LDR r0, [r1, #0] ORRS r0, r2 STR r0, [r1, #0] LDR r1, =GPIOA_MODER MOVS r2, #0xFF LDR r0, [r1, #0] BICS r0, r2 MOVS r2, #0x44 ORRS r0, r2 STR r0, [r1, #0] LDR r1, =GPIOA_ODR MOVS r2, #0x0A LDR r0, [r1, #0] BICS r0, r2 STR r0, [r1, #0] B _ISR_NMI #----------------------------------------------------------------------------------------# .align 2 .syntax unified .thumb .type _ISR_HARDF, %function _ISR_HARDF: LDR r1, =RCC_AHB2ENR MOV r2, #0x01 LDR r0, [r1, #0] ORRS r0, r2 STR r0, [r1, #0] LDR r1, =GPIOA_MODER MOVS r2, #0xFF LDR r0, [r1, #0] BICS r0, r2 MOVS r2, #0x11 ORRS r0, r2 STR r0, [r1, #0] LDR r1, =GPIOA_ODR MOVS r2, #0x05 LDR r0, [r1, #0] BICS r0, r2 STR r0, [r1, #0] B _ISR_HARDF #----------------------------------------------------------------------------------------# .align 2 .syntax unified .thumb .type _ISR_S0_S1, %function _ISR_S0_S1: PUSH {r4, r5, lr} // Wichtig: Register sichern gemäß AAPCS _check_S0: LDR r4, =EXTI_PR1 LDR r5, [r4, #0] LDR r2, =0x2000 // Maske für S0 (PC13 / Bit 13) TST r5, r2 BEQ _check_S1 // Wenn Bit 13 nicht gesetzt, überspringen #--- do the work S0 BL delay // Entprellen LDR r0, =GPIOC_IDR LDR r1, [r0, #0] LDR r2, =0x2000 TST r1, r2 BNE _clear_S0 // Abbruch, wenn High (Taster prellt / schon losgelassen) LDR r0, =GPIOA_ODR LDR r1, [r0, #0] MOVS r2, #0x09 // LED0 & LED3 toggeln (1001) EORS r1, r2 STR r1, [r0, #0] _clear_S0: #--- clear interrupt flag S0 LDR r4, =EXTI_PR1 LDR r5, =0x2000 STR r5, [r4, #0] _check_S1: LDR r4, =EXTI_PR1 LDR r5, [r4, #0] LDR r2, =0x4000 // Maske für S1 (PC14 / Bit 14) TST r5, r2 BEQ _leave_ISR // Wenn Bit 14 nicht gesetzt, Ende #--- do the work S1 BL delay LDR r0, =GPIOC_IDR LDR r1, [r0, #0] LDR r2, =0x4000 TST r1, r2 BNE _clear_S1 // Abbruch, wenn High LDR r0, =GPIOA_ODR LDR r1, [r0, #0] MOVS r2, #0x06 // LED1 & LED2 toggeln (0110) EORS r1, r2 STR r1, [r0, #0] _clear_S1: #--- clear interrupt flag S1 LDR r4, =EXTI_PR1 LDR r5, =0x4000 STR r5, [r4, #0] _leave_ISR: #--- leave ISR POP {r4, r5, pc} // Register wiederherstellen und zurückkehren #----------------------------------------------------------------------------------------# .lp2: .ltorg #----------------------------------------------------------------------------------------# .end #************************************** E O F *******************************************#