Загрузка данных


Startup.s
-------------------------------------------------------------------------------------------------------------------------------------------------------

	PRESERVE8
	THUMB

Stack_Size	EQU	0x400

	AREA	STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem	SPACE	Stack_Size
Stack_Top

	AREA	RESET, DATA, READONLY
	EXPORT	__Vectors

__Vectors
	DCD	Stack_Top
	DCD	Reset_Handler
	DCD	NMI_Handler
	DCD	HardFault_Handler

; Skip system exceptions (12 slots), reach IRQ0
	SPACE	12 * 4

; IRQ0..IRQ4 - EXTI lines 0..4, unused
	DCD	EXTI0_IRQHandler
	DCD	EXTI1_IRQHandler
	DCD	EXTI2_IRQHandler
	DCD	EXTI3_IRQHandler
	DCD	EXTI4_IRQHandler

; Skip IRQ5..IRQ22 (18 slots), next is IRQ23
	SPACE	18 * 4

; IRQ23 - shared vector for EXTI 5..9 (PB5 and PA8)
	DCD	EXTI9_5_IRQHandler

; Skip IRQ24..IRQ39 (16 slots), next is IRQ40
	SPACE	16 * 4

; IRQ40 - shared vector for EXTI 10..15 (PB15)
	DCD	EXTI15_10_IRQHandler

	SPACE	2 * 4

	AREA	LAB2, CODE, READONLY
	IMPORT	main
	ENTRY
	EXPORT	Reset_Handler

Reset_Handler
	LDR	R0, =main
	BX	R0

	EXPORT	HardFault_Handler [WEAK]
HardFault_Handler
	B	.

Default_Handler
	EXPORT	NMI_Handler [WEAK]
	EXPORT	EXTI0_IRQHandler [WEAK]
	EXPORT	EXTI1_IRQHandler [WEAK]
	EXPORT	EXTI2_IRQHandler [WEAK]
	EXPORT	EXTI3_IRQHandler [WEAK]
	EXPORT	EXTI4_IRQHandler [WEAK]
	EXPORT	EXTI9_5_IRQHandler [WEAK]
	EXPORT	EXTI15_10_IRQHandler [WEAK]
NMI_Handler
EXTI0_IRQHandler
EXTI1_IRQHandler
EXTI2_IRQHandler
EXTI3_IRQHandler
EXTI4_IRQHandler
EXTI9_5_IRQHandler
EXTI15_10_IRQHandler
	B	.

	EXPORT	__main
__main
	B	.

	ALIGN
	END

---------------------------------------------------------------------------------------------------------------------
main.s
----------------------------------------------------------------------------------------------------------------------------

	THUMB

RCC_APB2ENR	EQU	0x40021018

AFIO_EXTICR2	EQU	0x4001000C
AFIO_EXTICR3	EQU	0x40010010
AFIO_EXTICR4	EQU	0x40010014

EXTI_IMR	EQU	0x40010400
EXTI_RTSR	EQU	0x40010408
EXTI_FTSR	EQU	0x4001040C
EXTI_PR		EQU	0x40010414

GPIOA_CRL	EQU	0x40010800
GPIOA_CRH	EQU	0x40010804
GPIOA_IDR	EQU	0x40010808
GPIOA_ODR	EQU	0x4001080C
GPIOA_BSRR	EQU	0x40010810

GPIOB_CRL	EQU	0x40010C00
GPIOB_CRH	EQU	0x40010C04
GPIOB_IDR	EQU	0x40010C08
GPIOB_ODR	EQU	0x40010C0C
GPIOB_BSRR	EQU	0x40010C10

NVIC_ISER0	EQU	0xE000E100
NVIC_ISER1	EQU	0xE000E104

; Bit-band alias addresses
PER_BB_BASE	EQU	0x42000000
PER_BASE	EQU	0x40000000

GPIOA_ODR_OFF	EQU	0x0001080C
GPIOB_ODR_OFF	EQU	0x00010C0C
GPIOA_IDR_OFF	EQU	0x00010808
GPIOB_IDR_OFF	EQU	0x00010C08

PA5_ODR_BB	EQU	PER_BB_BASE + GPIOA_ODR_OFF * 32 + 5  * 4
PB0_ODR_BB	EQU	PER_BB_BASE + GPIOB_ODR_OFF * 32 + 0  * 4
PB13_ODR_BB	EQU	PER_BB_BASE + GPIOB_ODR_OFF * 32 + 13 * 4

PA8_IDR_BB	EQU	PER_BB_BASE + GPIOA_IDR_OFF * 32 + 8  * 4
PB5_IDR_BB	EQU	PER_BB_BASE + GPIOB_IDR_OFF * 32 + 5  * 4
PB15_IDR_BB	EQU	PER_BB_BASE + GPIOB_IDR_OFF * 32 + 15 * 4

	AREA	LAB2MAIN, CODE, READONLY
	EXPORT	main
	EXPORT	EXTI9_5_IRQHandler
	EXPORT	EXTI15_10_IRQHandler

main
	LDR	R0, =RCC_APB2ENR
	LDR	R1, [R0]
	ORR	R1, R1, #0x0D
	STR	R1, [R0]

	LDR	R0, =GPIOA_BSRR
	LDR	R1, =(1 << 5) :OR: (1 << 8)
	STR	R1, [R0]

	LDR	R0, =GPIOB_BSRR
	LDR	R1, =(1 << 0) :OR: (1 << 13)
	STR	R1, [R0]

	; PA5 - output push-pull
	LDR	R0, =GPIOA_CRL
	LDR	R1, [R0]
	LDR	R2, =0xFF0FFFFF
	AND	R1, R1, R2
	LDR	R2, =0x00200000
	ORR	R1, R1, R2
	STR	R1, [R0]

	; PA8 - input with pull-up
	LDR	R0, =GPIOA_CRH
	LDR	R1, [R0]
	LDR	R2, =0xFFFFFFF0
	AND	R1, R1, R2
	ORR	R1, R1, #0x8
	STR	R1, [R0]

	; PB0 - output, PB5 - input with pull-down
	LDR	R0, =GPIOB_CRL
	LDR	R1, [R0]
	LDR	R2, =0xFF0FFFF0
	AND	R1, R1, R2
	LDR	R2, =0x00800002
	ORR	R1, R1, R2
	STR	R1, [R0]

	; PB13 - output, PB15 - input with pull-down
	LDR	R0, =GPIOB_CRH
	LDR	R1, [R0]
	LDR	R2, =0x0F0FFFFF
	AND	R1, R1, R2
	LDR	R2, =0x80200000
	ORR	R1, R1, R2
	STR	R1, [R0]

	; AFIO: EXTI5 -> PB5
	LDR	R0, =AFIO_EXTICR2
	LDR	R1, [R0]
	BIC	R1, R1, #0xF0
	ORR	R1, R1, #0x10
	STR	R1, [R0]

	; AFIO: EXTI8 -> PA8
	LDR	R0, =AFIO_EXTICR3
	LDR	R1, [R0]
	BIC	R1, R1, #0x0F
	STR	R1, [R0]

	; AFIO: EXTI15 -> PB15
	LDR	R0, =AFIO_EXTICR4
	LDR	R1, [R0]
	BIC	R1, R1, #0xF000
	ORR	R1, R1, #0x1000
	STR	R1, [R0]

	LDR	R0, =EXTI_RTSR
	LDR	R1, [R0]
	LDR	R2, =(1 << 5) :OR: (1 << 8) :OR: (1 << 15)
	ORR	R1, R1, R2
	STR	R1, [R0]

	LDR	R0, =EXTI_FTSR
	LDR	R1, [R0]
	LDR	R2, =(1 << 5) :OR: (1 << 8) :OR: (1 << 15)
	ORR	R1, R1, R2
	STR	R1, [R0]

	; Unmask lines 5, 8, 15
	LDR	R0, =EXTI_IMR
	LDR	R1, [R0]
	LDR	R2, =(1 << 5) :OR: (1 << 8) :OR: (1 << 15)
	ORR	R1, R1, R2
	STR	R1, [R0]

	; NVIC: enable IRQ23
	LDR	R0, =NVIC_ISER0
	MOV	R1, #(1 << 23)
	STR	R1, [R0]

	; NVIC: enable IRQ40
	LDR	R0, =NVIC_ISER1
	MOV	R1, #(1 << 8)
	STR	R1, [R0]

	CPSIE	I

loop
	LDR	R0, =Events
	LDR	R1, [R0]
	CMP	R1, #0
	BNE	process
	WFI
	B	loop

process
	; Clear event flags
	MOV	R2, #0
	STR	R2, [R0]

	; Debounce
	LDR	R3, =200000
	BL	Delay

	; Build Current_State in R4:
	;   bit 0 = PB5(H)
	;   bit 1 = PA8(L)
	;   bit 2 = PB15(H)
	MOV	R4, #0

	LDR	R0, =PB5_IDR_BB
	LDR	R1, [R0]
	CMP	R1, #0
	BEQ	rd_pa8
	ORR	R4, R4, #0x1

rd_pa8
	LDR	R0, =PA8_IDR_BB
	LDR	R1, [R0]
	CMP	R1, #0
	BNE	rd_pb15
	ORR	R4, R4, #0x2

rd_pb15
	LDR	R0, =PB15_IDR_BB
	LDR	R1, [R0]
	CMP	R1, #0
	BEQ	rising
	ORR	R4, R4, #0x4

rising
	; Rising = Current & ~Prev  (buttons pressed since last pass)
	LDR	R5, =Prev_State
	LDR	R6, [R5]
	BIC	R7, R4, R6
	STR	R4, [R5]

	; Toggle green (bit 0)
	TST	R7, #0x1
	BEQ	tog_red
	LDR	R0, =PB0_ODR_BB
	LDR	R1, [R0]
	EOR	R1, R1, #1
	STR	R1, [R0]

tog_red
	; Toggle red (bit 1)
	TST	R7, #0x2
	BEQ	tog_blue
	LDR	R0, =PA5_ODR_BB
	LDR	R1, [R0]
	EOR	R1, R1, #1
	STR	R1, [R0]

tog_blue
	; Toggle blue (bit 2)
	TST	R7, #0x4
	BEQ	done
	LDR	R0, =PB13_ODR_BB
	LDR	R1, [R0]
	EOR	R1, R1, #1
	STR	R1, [R0]

done
	B	loop

Delay
	SUBS	R3, R3, #1
	BNE	Delay
	BX	LR

; ISR for EXTI 5..9 (PB5 and PA8)
EXTI9_5_IRQHandler
	LDR	R0, =EXTI_PR
	LDR	R1, [R0]
	LDR	R2, =Events
	LDR	R3, [R2]
	ORR	R3, R3, R1
	STR	R3, [R2]
	STR	R1, [R0]
	DSB
	BX	LR

; ISR for EXTI 10..15 (PB15)
EXTI15_10_IRQHandler
	LDR	R0, =EXTI_PR
	LDR	R1, [R0]
	LDR	R2, =Events
	LDR	R3, [R2]
	ORR	R3, R3, R1
	STR	R3, [R2]
	STR	R1, [R0]
	DSB
	BX	LR

	AREA	LAB2DATA, DATA, READWRITE
Events		DCD	0
Prev_State	DCD	0

	ALIGN
	END