diff options
Diffstat (limited to 'misc')
-rw-r--r-- | misc/blink.s | 103 | ||||
-rw-r--r-- | misc/pll.s | 78 |
2 files changed, 181 insertions, 0 deletions
diff --git a/misc/blink.s b/misc/blink.s new file mode 100644 index 0000000..46e6eff --- /dev/null +++ b/misc/blink.s @@ -0,0 +1,103 @@ +.syntax unified +.cpu cortex-m0plus +.thumb + +.equ IO_BANK0_BASE, 0x40014000 +.equ GPIO25_STATUS, (IO_BANK0_BASE + 0x0c8) +.equ GPIO25_CTRL, (IO_BANK0_BASE + 0x0cc) + +.equ SIO_BASE, 0xd0000000 +.equ GPIO_OUT_SET_OFST, 0x014 +.equ GPIO_OUT_XOR_OFST, 0x01c +.equ GPIO_OE_SET_OFST, 0x024 + +.equ ATOMIC_CLEAR, 0x3000 + +.type setup_led, %function +.global setup_led + +setup_led: + ldr r1, =GPIO25_CTRL + movs r0, 5 // SIO function = 5 + str r0, [r1, 0] + ldr r1, =SIO_BASE + movs r0, 1 + lsls r0, 25 // GPIO 25 (LED) output enable + str r0, [r1, GPIO_OE_SET_OFST] + bx lr + +.type led_on, %function +.global led_on + +led_on: + ldr r1, =SIO_BASE + movs r0, 1 + lsls r0, 25 + str r0, [r1, GPIO_OUT_SET_OFST] +1: + b 1b + +.type blink, %function +.global blink + +blink: + ldr r1, =SIO_BASE + movs r0, 1 + lsls r0, 25 +1: + str r0, [r1, GPIO_OUT_XOR_OFST] + bl delay_1s + b 1b + +.type long_blink, %function +.global long_blink + +long_blink: + push {lr} + ldr r1, =SIO_BASE + movs r0, 1 + lsls r0, 25 + bl delay_1s + str r0, [r1, GPIO_OUT_XOR_OFST] + bl delay_1s + str r0, [r1, GPIO_OUT_XOR_OFST] + bl delay_1s + pop {pc} + +.type blinkN, %function +.global blinkN + +blinkN: + push {lr} + ldr r1, =SIO_BASE + movs r2, 1 + lsls r2, 25 + tst r0, r0 + beq done +on_then_off: + str r2, [r1, GPIO_OUT_XOR_OFST] + bl delay_quick + str r2, [r1, GPIO_OUT_XOR_OFST] + bl delay_quick + subs r0, 1 + bne on_then_off +done: + pop {pc} + +.type blink_hex, %function +.global blink_hex + +blink_hex: + push {lr} + movs r4, r0 + movs r5, 0xf +1: + ands r0, r5 + bl blinkN + lsrs r4, 4 + beq 2f + bl long_blink + movs r0, r4 + b 1b +2: + pop {pc} diff --git a/misc/pll.s b/misc/pll.s new file mode 100644 index 0000000..faeacb1 --- /dev/null +++ b/misc/pll.s @@ -0,0 +1,78 @@ +.syntax unified +.cpu cortex-m0plus +.thumb + +.equ RESETS_BASE, 0x4000c000 +.equ RESET_OFST, 0x0 +.equ RESET_DONE_OFST, 0x8 + +.equ PLL_SYS_BASE, 0x40028000 +.equ CS_OFST, 0x0 +.equ PWR_OFST, 0x4 +.equ FBDIV_INT_OFST, 0x8 +.equ PRIM_OFST, 0xc + +.equ ATOMIC_CLEAR, 0x3000 + +.type start_pll, %function +.global start_pll + +// configure pll_sys for 100MHz +start_pll: + // clear reset + ldr r1, =(RESETS_BASE + ATOMIC_CLEAR) + movs r0, 1 + lsls r0, 12 // pll_sys is bit 12 + str r0, [r1, RESET_OFST] + ldr r1, =RESETS_BASE +1: + ldr r2, [r1, RESET_DONE_OFST] + tst r0, r2 // pll_sys is still bit 12 + // wait for reset done + beq 1b + // set pls_sys feedback divider to 100 + ldr r1, =PLL_SYS_BASE + movs r0, 100 // FBDIV = 100 + str r0, [r1, FBDIV_INT_OFST] + // set pl_sys post dividers to 12 (6 * 2) + ldr r1, =PLL_SYS_BASE + movs r0, 6 // POSTDIV1 = 6 + lsls r0, 4 + adds r0, 2 // POSTDIV2 = 2 + lsls r0, 12 + str r0, [r1, PRIM_OFST] + // turn on main power and VCO + ldr r1, =(PLL_SYS_BASE + ATOMIC_CLEAR) + movs r0, 0x21 // power and VCO (bits 0 and 5) + str r0, [r1, PWR_OFST] + // wait for VCO to lock + ldr r1, =PLL_SYS_BASE +vco_lock: + ldr r2, [r1, CS_OFST] + lsrs r2, 31 + beq vco_lock + // turn on post divider power + ldr r1, =(PLL_SYS_BASE + ATOMIC_CLEAR) + movs r0, 0x8 // postdiv (bit 3) + str r0, [r1, PWR_OFST] + bx lr + +.type delay_1s, %function +.global delay_1s + +delay_1s: + ldr r3, =0x1fca055 // 33.3 * 10^6 (one-third of a second at 100MHz) +1: // 3 clock cycle loop + subs r3, 1 // 1 clock cycle + bne 1b // 2 clock cycles when taken + bx lr + +.type delay_quick, %function +.global delay_quick + +delay_quick: + ldr r3, =0x65b9ab +1: + subs r3, 1 + bne 1b + bx lr |