7 changed files with 221 additions and 0 deletions
After Width: | Height: | Size: 740 KiB |
@ -0,0 +1,30 @@
@@ -0,0 +1,30 @@
|
||||
PROG ?= main
|
||||
|
||||
JLINKEXE ?= ~/.platformio/packages/tool-jlink/JLinkExe
|
||||
|
||||
PREFIX ?= riscv32-elf-
|
||||
ARCH ?= rv32imac
|
||||
|
||||
AFLAGS = --warn --fatal-warnings
|
||||
LDFLAGS = -m elf32lriscv -b elf32-littleriscv
|
||||
|
||||
all: $(PROG).hex |
||||
|
||||
$(PROG).o: $(PROG).s |
||||
$(PREFIX)as -march=$(ARCH) $(AFLAGS) $(PROG).s -o $(PROG).o
|
||||
|
||||
$(PROG).hex: memmap $(PROG).o |
||||
$(PREFIX)ld $(LDFLAGS) -o $(PROG).elf -T memmap $(PROG).o
|
||||
$(PREFIX)objdump -Mnumeric -D $(PROG).elf > $(PROG).list
|
||||
$(PREFIX)objcopy $(PROG).elf $(PROG).bin -O binary
|
||||
$(PREFIX)objcopy $(PROG).elf $(PROG).hex -O ihex
|
||||
|
||||
flash: $(PROG).hex |
||||
echo -e "loadfile $(PROG).hex\nr\ng\nexit\n" | $(JLINKEXE) -device FE310 -if JTAG -speed 4000 -si JTAG -jtagconf -1,-1 -autoconnect 1
|
||||
|
||||
clean: |
||||
rm -f *.bin
|
||||
rm -f *.hex
|
||||
rm -f *.o
|
||||
rm -f *.elf
|
||||
rm -f *.list
|
@ -0,0 +1,53 @@
@@ -0,0 +1,53 @@
|
||||
# |
||||
# |
||||
# 2021 flabbergast <flabbergast@drak.xyz>
|
||||
# Unlicense: https://unlicense.org/ |
||||
#
|
||||
|
||||
.option norelax
|
||||
|
||||
# ----------------------------------------------------------------------------- |
||||
# Code begins here |
||||
# ----------------------------------------------------------------------------- |
||||
|
||||
.text |
||||
j Reset # Instead of a true vector table |
||||
|
||||
# ----------------------------------------------------------------------------- |
||||
# Include any supporting code |
||||
# ----------------------------------------------------------------------------- |
||||
|
||||
.include "platform_regs.inc" |
||||
.include "p_clock.s" |
||||
.include "p_delay.s" |
||||
|
||||
# ----------------------------------------------------------------------------- |
||||
Reset: # Execution begins here |
||||
# ----------------------------------------------------------------------------- |
||||
|
||||
# Set base address for interrupt handler |
||||
# la x15, irq_collection |
||||
# csrrs zero, mtvec, x15 |
||||
|
||||
# the board (usually) runs on 13.8MHz HFROSC on boot? |
||||
call clock_extcryst # switch to external crystal, 16MHz |
||||
# call clock_pll_64mhz # switch to 64MHz PLL driven by 16MHz ext crystal |
||||
|
||||
li s1, GPIO_CTRL_BASE |
||||
li s2, 0b111111<<18 # pins 18-23 |
||||
sw s2, GPIO_OUTPUT_EN(s1) # set as outputs |
||||
|
||||
li a0, 200 # delay in ms |
||||
li s2, 0b1<<18 # start with pin 18 |
||||
li s3, 0b1<<23 # end with pin 23 |
||||
1: |
||||
sw s2, GPIO_OUTPUT_VAL(s1) # make the pin high |
||||
# call delay |
||||
call deelay |
||||
slli s2, s2, 1 # move one to the left |
||||
bleu s2, s3, 1b # did we move past last pin? |
||||
li s2, 0b1<<18 # back to the first pin |
||||
j 1b |
||||
|
||||
end: |
||||
j end |
@ -0,0 +1,57 @@
@@ -0,0 +1,57 @@
|
||||
.align 2
|
||||
|
||||
.include "platform_regs.inc" |
||||
|
||||
|
||||
# switch to external crystal (16MHz on red-v thing) |
||||
clock_extcryst: |
||||
li t0, PRCI_BASE |
||||
1: # Wait for crystal to oscillate |
||||
lw t1, PRCI_HFXOSCCFG(t0) # hfxoscen(bit30) is on by default on reset |
||||
bgtz t1, 1b # ... hfxoscrdy(bit31): makes value negative |
||||
|
||||
li t1, 0x00070df1 # 0x00060df1 | (1<<16) | (1<<17) | (1<<18) |
||||
# = Reset value | PLLSEL | PLLREFSEL | PLLBYPASS |
||||
sw t1, PRCI_PLLCFG(t0) # Select crystal as the main clock source |
||||
ret |
||||
|
||||
|
||||
# switch to 64MHz PLL driven by 16MHz external crystal |
||||
clock_pll_64mhz: |
||||
li t0, PRCI_BASE |
||||
1: # Wait for crystal to oscillate |
||||
lw t1, PRCI_HFXOSCCFG(t0) # hfxoscen(bit30) is on by default on reset |
||||
bgtz t1, 1b # ... hfxoscrdy(bit31): makes value negative |
||||
|
||||
# Set PLL to 64 MHz (don't activate); 64 = 16 /(2^1) *(2*(31+1)) /(2^3)
|
||||
li t1, 0x20df1 # pllr=1, pllf=0x1f, pllq=0x3 (reset vals) |
||||
sw t1, PRCI_PLLCFG(t0) # pllsel=0, pllrefsel=1, pllbypass=0(!) |
||||
|
||||
2: # Wait for PLL to lock: plllock(bit31): sign bit |
||||
lw t1, PRCI_PLLCFG(t0) |
||||
bgtz t1, 2b |
||||
|
||||
li t1, 0x30df1 # pllsel=1 (on top of the above) |
||||
sw t1, PRCI_PLLCFG(t0) |
||||
ret |
||||
|
||||
|
||||
# switch to 320MHz PLL driven by 16MHz external crystal |
||||
# (the board gets quite warm!) |
||||
clock_pll_320mhz: |
||||
li t0, PRCI_BASE |
||||
1: # Wait for crystal to oscillate |
||||
lw t1, PRCI_HFXOSCCFG(t0) # hfxoscen(bit30) is on by default on reset |
||||
bgtz t1, 1b # ... hfxoscrdy(bit31): makes value negative |
||||
|
||||
# Set PLL to 320 MHz (don't activate); 320 = 16 /(2^1) *(2*(39+1)) /(2^1)
|
||||
li t1, 0x20671 # pllr=1, pllf=0x27(!), pllq=1(!) |
||||
sw t1, PRCI_PLLCFG(t0) # pllsel=0, pllrefsel=1, pllbypass=0(!) |
||||
|
||||
2: # Wait for PLL to lock: plllock(bit31): sign bit |
||||
lw t1, PRCI_PLLCFG(t0) |
||||
bgtz t1, 2b |
||||
|
||||
li t1, 0x30671 # pllsel=1 (on top of the above) |
||||
sw t1, PRCI_PLLCFG(t0) |
||||
ret |
@ -0,0 +1,35 @@
@@ -0,0 +1,35 @@
|
||||
.align 2
|
||||
|
||||
.include "platform_regs.inc" |
||||
.equ MTIME_FREQUENCY, 33 # 32_768 Hz clock |
||||
|
||||
# a0: delay value in milliseconds |
||||
# (should be less than 0xFFFF_FFFF/33/4) |
||||
delay: |
||||
li t0, CLINT_CTRL_BASE+CLINT_MTIME # Load the timer registers base |
||||
lw t1, 0(t0) # Load the current value of the timer |
||||
|
||||
li t2, MTIME_FREQUENCY # Get our clock frequency |
||||
mul t2, t2, a0 # Multiply milliseconds with frequency |
||||
add t2, t1, t2 # Target mtime is now in t2 |
||||
bltu t2, t1, 2f # Overflown back to zero? |
||||
# if yes, (signed)t1<0 |
||||
|
||||
1: |
||||
lw t1, 0(t0) # Read mtime value again |
||||
bltu t1, t2, 1b # Keep looping until timout |
||||
ret |
||||
|
||||
2: # Overflown branch |
||||
lw t1, 0(t0) # Read mtime; t1 can be "<0" |
||||
blt t1, t2, 2b # Do signed compare |
||||
ret |
||||
|
||||
deelay: |
||||
li a0, 8000000 |
||||
# a0: (delay in cycles)/2 |
||||
busy_delay_cycles: |
||||
1: |
||||
addi a0, a0, -1 |
||||
bnez a0, 1b |
||||
ret |
@ -0,0 +1,45 @@
@@ -0,0 +1,45 @@
|
||||
# SPDX-License-Identifier: Unlicense |
||||
# Copyright (c) 2018 Western Digital Corporation or its affiliates. |
||||
|
||||
.equ GPIO_CTRL_BASE, 0x10012000 |
||||
.equ GPIO_INPUT_VAL, 0x00 |
||||
.equ GPIO_INPUT_EN, 0x04 |
||||
.equ GPIO_OUTPUT_EN, 0x08 |
||||
.equ GPIO_OUTPUT_VAL, 0x0C |
||||
.equ GPIO_PUE, 0x10 |
||||
.equ GPIO_DS, 0x14 |
||||
.equ GPIO_RISE_IE, 0x18 |
||||
.equ GPIO_RISE_IP, 0x1C |
||||
.equ GPIO_FALL_IE, 0x20 |
||||
.equ GPIO_FALL_IP, 0x24 |
||||
.equ GPIO_HIGH_IE, 0x28 |
||||
.equ GPIO_HIGH_IP, 0x2C |
||||
.equ GPIO_LOW_IE, 0x30 |
||||
.equ GPIO_LOW_IP, 0x34 |
||||
.equ GPIO_IOF_EN, 0x38 |
||||
.equ GPIO_IOF_SEL, 0x3C |
||||
.equ GPIO_OUTPUT_XOR, 0x40 |
||||
|
||||
.equ CLINT_CTRL_BASE, 0x02000000 |
||||
.equ CLINT_MSIP, 0x0000 |
||||
.equ CLINT_MTIMECMP, 0x4000 |
||||
.equ CLINT_MTIME, 0xBFF8 |
||||
|
||||
.equ PRCI_BASE, 0x10008000 |
||||
.equ PRCI_HFROSCCFG, 0x00 # Ring osc config |
||||
.equ PRCI_HFXOSCCFG, 0x04 # XTAL osc config |
||||
.equ PRCI_PLLCFG, 0x08 # PLL config |
||||
.equ PRCI_PLLOUTDIV, 0x0C |
||||
.equ PRCI_PROCMONCFG, 0xF0 |
||||
.equ PRCI_PLLCFG_PLLSEL, 1<<16 # PLL selected as clock source |
||||
.equ PRCI_PLLCFG_PLLREFSEL, 1<<17 # PLL to take XTAL as reference |
||||
.equ PRCI_PLLCFG_PLLBYPASS, 1<<18 # PLL bypassed and shut off |
||||
|
||||
.equ UART0_BASE, 0x10013000 |
||||
.equ UART0_TXDATA, 0x00 |
||||
.equ UART0_RXDATA, 0x04 |
||||
.equ UART0_TXCTRL, 0x08 |
||||
.equ UART0_RXCTRL, 0x0C |
||||
.equ UART0_IE, 0x10 |
||||
.equ UART0_IP, 0x14 |
||||
.equ UART0_DIV, 0x18 |
Loading…
Reference in new issue