Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- @ STDNUM001 STDNUM002
- .syntax unified
- .global _start
- vectors:
- .word 0x20002000
- .word _start + 1
- _start:
- @ enable clock for GPIOA and GPIOB
- LDR R0, RCC_BASE
- LDR R1, [R0, #0x14] @ RCC_AHBENR
- LDR R2, AHBENR_IOPABEN @ pattern to set PA and PB bits
- ORRS R1, R1, R2
- STR R1, [R0, #0x14] @ write back
- @ enable clock for ADC
- LDR R1, [R0, #0x18] @ RCC_APB2ENR
- LDR R2, APB2ENR_ADCEN @ pattern to set ADCEN bit
- ORRS R1, R1, R2
- STR R1, [R0, #0x18] @ RCC_APB2ENR write back
- @ set LEDs to outputs
- LDR R0, GPIOB_BASE
- LDR R1, LEDS_OUTPUTS
- STR R1, [R0, #0]
- @ set pullup for PA3
- LDR R0, GPIOA_BASE
- LDR R1, [R0, #0x0C] @ GPIOA_PUPDR
- MOVS R2, #0b01010101
- ORRS R1, R1, R2
- STR R1, [R0, #0x0C] @ GPIOA_PUPDR write back
- @ set PA5 and PA6 to analogue
- LDR R1, [R0, #0] @ GPIOA_MODER
- LDR R2, MODER_5_6_ANALOGUE
- ORRS R1, R1, R2
- STR R1, [R0, #0] @ GPIOA_MODER write back
- @ ADC resolution to 8-bit
- LDR R0, ADC_BASE
- LDR R1, [R0, #0x0C]
- MOVS R2, #0b10000
- ORRS R1, R1, R2
- STR R1, [R0, #0x0C]
- @ enable ADC
- LDR R0, ADC_BASE
- MOVS R1, #1 @ ADEN = bit0
- STR R1, [R0, #0x08] @ ADC_CR
- adrdy_loop:
- LDR R1, [R0, #0] @ ADC_ISR
- MOVS R2, #1
- ANDS R1, R1, R2
- BEQ adrdy_loop
- LDR R0, DATA_ADDR @ soure pointer
- LDR R1, DATA_END_ADDR @ out-of-bounds pointer
- LDR R2, RAM_START @ destination pointer
- MOVS R3, #0 @ counter for number of bytes copied
- to_RAM_loop:
- CMP R0, R1 @ is the source pointer out of bounds?
- BEQ copy_to_RAM_done @ if so, don't copy any more
- LDR R4, [R0] @ copy from source...
- STR R4, [R2] @ ...to destination
- ADDS R0, #4 @ interment source and destination pointers by a word
- ADDS R2, #4
- ADDS R3, #4 @ increment counter by number of bytes copied
- B to_RAM_loop
- @ CRITICAL! When the program hits this label, the automarker will
- @ stop execution and verify the contents of RAM.
- copy_to_RAM_done:
- MOVS R1, #0x80 @ Iterate for all numbers, see if we get any matches in our data set(for i=-128; i<128; i++)
- SXTB R1, R1
- LDR R0, RAM_START @ pointer to load from RAMSTART
- outer_for_loop:
- MOVS R2, #0 @ R2 will be used to OFFSET as we iterate through data set
- MOVS R5, R3 @ number of bytes to process @ R3 is the counter of number of bytes to process.
- inner_for_loop:
- LDRSB R4, [R0, R2] @ load from RAM
- CMP R4, R1 @ Compare byte in RAM with each value
- BNE no_hit @ If not the same was not match
- PUSH {R4} @ if the same, add to stack
- no_hit:
- ADDS R2, #1 @ Increment RAM address offset
- SUBS R5, #1 @ subtract bytes processed this inner run
- BNE inner_for_loop
- ADDS R1, #1 @ increment checking value (i++)
- CMP R1, #0x80 @ if value wrapped around, exit
- BNE outer_for_loop
- @ CRITICAL! The marker will verify contents of stack
- @ the stack when the program hits this label.
- order_to_stack_done:
- LDR R0, GPIOB_BASE
- MOV R4, SP
- MOVS R5, #4
- MULS R3, R3, R5
- SUBS R3, #4
- LDR R1, [R4, #0] @ larger element (B) on top
- LDR R2, [R4, R3] @ smaller (A) is located bottom of the stack
- main_loop:
- STR R2, [R0, #0x14] @ display smaller of pair (A)
- BL delay @ call delay subroutine
- STR R1, [R0, #0x14] @ display larger of pair (B)
- BL delay @ call delay subroutine
- B main_loop @ loopidy loop loop loop
- delay:
- PUSH {R0, R1, R2, R3, R4, R5} @ backup registers to the stack
- LDR R0, DEFAULT_DELAY @ assume full 1.2 second delay. Will be overridden if SW0 held.
- LDR R1, GPIOA_BASE @ get contents of GPIOA_IDR
- LDR R2, [R1, #0x10]
- MOVS R3, #0b100 @ mask out all bits except bit2 == SW2
- ANDS R2, R2, R3
- BNE delay_loop @ if the button is held, skip the ADC fetching logic and begin delay
- LDR R0, DELAY_OFFSET @ the minimum delay. Will be added to by ADC value.
- LDR R1, ADC_BASE
- @ select channel 5 (POT0)
- MOVS R2, #0b100000
- STR R2, [R1, #0x28]
- @ run a conversion by setting ADSTART and waiting for it to go low
- MOVS R2, #0b100 @ ADSTART
- STR R2, [R1, #0x08] @ ADC_CR
- eoc_loop_0:
- LDR R3, [R1, #0]
- ANDS R3, R3, R2
- BEQ eoc_loop_0
- LDR R4, [R1, #0x40] @ R4 will hold the value of POT0
- @ select channel 6 (POT1)
- MOVS R2, #0b1000000
- STR R2, [R1, #0x28]
- @ run a conversion by setting ADSTART and waiting for it to go low
- MOVS R2, #0b100 @ ADSTART
- STR R2, [R1, #0x08] @ ADC_CR
- eoc_loop_1:
- LDR R3, [R1, #0]
- ANDS R3, R3, R2
- BEQ eoc_loop_1
- LDR R5, [R1, #0x40] @ R5 will hold the value of POT1
- LDR R1, DELAY_MULTIPLIER
- CMP R5, R4
- BHI pot0_larger
- MULS R1, R1, R5
- ADDS R0, R0, R1
- B delay_loop
- pot0_larger:
- MULS R1, R1, R4
- ADDS R0, R0, R1
- delay_loop:
- SUBS R0, #1
- BNE delay_loop
- POP {R0, R1, R2, R3, R4, R5} @ restore backed up registers
- BX LR
- .align
- @ you can define more literals here.
- RCC_BASE: .word 0x40021000
- AHBENR_IOPABEN: .word 0b11 << 17
- APB2ENR_ADCEN: .word 0b1 << 9
- GPIOB_BASE: .word 0x48000400
- LEDS_INPUTS: .word 0xFFFF0000
- LEDS_OUTPUTS: .word 0x00005555
- GPIOA_BASE: .word 0x48000000
- MODER_5_6_ANALOGUE: .word 0b1111 << 10
- ADC_BASE: .word 0x40012400
- INIT: .word 0x80
- RAM_START: .word 0x20000000
- DATA_ADDR: .word DATA
- DATA_END_ADDR: .word DATA_END
- DEFAULT_DELAY: .word 2400000
- DELAY_OFFSET: .word 1200000
- DELAY_MULTIPLIER: .word 6274
- @ Before compiling your code, the automarker will modify this block.
- @ Be sure to avoid out-by-one errors: make sure you access ALL elements.
- DATA:
- .word 0x62967109
- .word 0x0674a70b
- .word 0x902bff4f
- .word 0xe7fa8a65
- .word 0xb610c2af
- .word 0x237e8814
- .word 0xfe0573a4
- .word 0xefd6e381
- .word 0x33c8bf70
- .word 0xfbe4bc46
- DATA_END:
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement