mirror of
https://github.com/im-tomu/fomu-workshop.git
synced 2024-09-19 19:00:18 +00:00
Rust-USB support using riscv-blink c-code
This commit is contained in:
parent
8e3ba84d78
commit
66939a4fbf
@ -1,6 +1,6 @@
|
||||
[target.riscv32i-unknown-none-elf]
|
||||
rustflags = [
|
||||
"-C", "link-arg=-Tlink.x",
|
||||
"-C", "link-arg=-Tld/linker.ld",
|
||||
]
|
||||
|
||||
|
||||
|
9
riscv-rust-blink/Cargo.lock
generated
9
riscv-rust-blink/Cargo.lock
generated
@ -1,5 +1,7 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.13"
|
||||
@ -24,6 +26,12 @@ version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a165d606cf084741d4ac3a28fb6e9b1eb0bd31f6cd999098cfddb0b2ab381dc0"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.71"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79c2681d6594606957bbb8631c4b90a7fcaaa72cdb714743a437b156d6a7eedd"
|
||||
|
||||
[[package]]
|
||||
name = "fomu-pac"
|
||||
version = "0.0.4"
|
||||
@ -157,6 +165,7 @@ dependencies = [
|
||||
name = "riscv-rust-blink"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"fomu-pac",
|
||||
"fomu-rt",
|
||||
"panic-halt",
|
||||
|
@ -12,6 +12,9 @@ fomu-rt = "0.0.6"
|
||||
|
||||
panic-halt = "0.2"
|
||||
|
||||
[build-dependencies]
|
||||
cc = "1.0.71"
|
||||
|
||||
[profile.release]
|
||||
# Keep debug information for release builds, for easier debugging.
|
||||
# It will be removed during the conversion to the .dfu file.
|
||||
|
16
riscv-rust-blink/build.rs
Normal file
16
riscv-rust-blink/build.rs
Normal file
@ -0,0 +1,16 @@
|
||||
use cc;
|
||||
|
||||
// Build the USB-Support from the riscv-blink c-code
|
||||
fn main() {
|
||||
cc::Build::new()
|
||||
.file("../riscv-blink/src/usb-dev.c")
|
||||
.file("../riscv-blink/src/usb-epfifo.c")
|
||||
.file("../riscv-blink/src/usb-eptri.c")
|
||||
.file("../riscv-blink/src/usb.c")
|
||||
.file("../riscv-blink/src/rgb.c")
|
||||
.file("src/c/irq.c")
|
||||
.include("../riscv-blink/include")
|
||||
|
||||
.define("__vexriscv__", None)
|
||||
.compile("fomu-usb");
|
||||
}
|
162
riscv-rust-blink/ld/linker.ld
Normal file
162
riscv-rust-blink/ld/linker.ld
Normal file
@ -0,0 +1,162 @@
|
||||
MEMORY
|
||||
{
|
||||
RAM : ORIGIN = 0x10000000, LENGTH = 128K
|
||||
FLASH : ORIGIN = 0x20040000, LENGTH = 2M - 0x40000
|
||||
}
|
||||
|
||||
REGION_ALIAS("REGION_TEXT", FLASH);
|
||||
REGION_ALIAS("REGION_RODATA", FLASH);
|
||||
REGION_ALIAS("REGION_DATA", RAM);
|
||||
REGION_ALIAS("REGION_BSS", RAM);
|
||||
REGION_ALIAS("REGION_HEAP", RAM);
|
||||
REGION_ALIAS("REGION_STACK", RAM);
|
||||
|
||||
PROVIDE(_stext = ORIGIN(REGION_TEXT));
|
||||
PROVIDE(_stack_start = ORIGIN(REGION_STACK) + LENGTH(REGION_STACK));
|
||||
PROVIDE(_max_hart_id = 0);
|
||||
PROVIDE(_hart_stack_size = 2K);
|
||||
PROVIDE(_heap_size = 0);
|
||||
|
||||
PROVIDE(trap_handler = default_trap_handler);
|
||||
|
||||
/* # Pre-initialization function */
|
||||
/* If the user overrides this using the `#[pre_init]` attribute or by creating a `__pre_init` function,
|
||||
then the function this points to will be called before the RAM is initialized. */
|
||||
PROVIDE(__pre_init = default_pre_init);
|
||||
|
||||
/* # Multi-processing hook function
|
||||
fn _mp_hook() -> bool;
|
||||
|
||||
This function is called from all the harts and must return true only for one hart,
|
||||
which will perform memory initialization. For other harts it must return false
|
||||
and implement wake-up in platform-dependent way (e.g. after waiting for a user interrupt).
|
||||
*/
|
||||
PROVIDE(_mp_hook = default_mp_hook);
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text.dummy (NOLOAD) :
|
||||
{
|
||||
/* This section is intended to make _stext address work */
|
||||
. = _stext;
|
||||
} > REGION_TEXT
|
||||
|
||||
.text _stext :
|
||||
{
|
||||
/* Put reset handler first in .text section so it ends up as the entry */
|
||||
/* point of the program. */
|
||||
KEEP(*(.init));
|
||||
KEEP(*(.init.rust));
|
||||
. = ALIGN(4);
|
||||
KEEP(*(.trap));
|
||||
KEEP(*(.trap.rust));
|
||||
|
||||
*(.text .text.*);
|
||||
} > REGION_TEXT
|
||||
|
||||
.rodata : ALIGN(4)
|
||||
{
|
||||
*(.rodata .rodata.*);
|
||||
|
||||
/* 4-byte align the end (VMA) of this section.
|
||||
This is required by LLD to ensure the LMA of the following .data
|
||||
section will have the correct alignment. */
|
||||
. = ALIGN(4);
|
||||
} > REGION_RODATA
|
||||
|
||||
.data : ALIGN(4)
|
||||
{
|
||||
_sidata = LOADADDR(.data);
|
||||
_sdata = .;
|
||||
*(.ramtext .ramtext.*)
|
||||
|
||||
/* Must be called __global_pointer$ for linker relaxations to work. */
|
||||
PROVIDE(__global_pointer$ = . + 0x800);
|
||||
*(.sdata .sdata.* .sdata2 .sdata2.*);
|
||||
*(.data .data.*);
|
||||
. = ALIGN(4);
|
||||
_edata = .;
|
||||
} > REGION_DATA AT > REGION_RODATA
|
||||
|
||||
.bss (NOLOAD) :
|
||||
{
|
||||
_sbss = .;
|
||||
*(.sbss .sbss.* .bss .bss.*);
|
||||
. = ALIGN(4);
|
||||
_ebss = .;
|
||||
} > REGION_BSS
|
||||
|
||||
/* fictitious region that represents the memory available for the heap */
|
||||
.heap (NOLOAD) :
|
||||
{
|
||||
_sheap = .;
|
||||
. += _heap_size;
|
||||
. = ALIGN(4);
|
||||
_eheap = .;
|
||||
} > REGION_HEAP
|
||||
|
||||
/* fake output .got section */
|
||||
/* Dynamic relocations are unsupported. This section is only used to detect
|
||||
relocatable code in the input files and raise an error if relocatable code
|
||||
is found */
|
||||
.got (INFO) :
|
||||
{
|
||||
KEEP(*(.got .got.*));
|
||||
}
|
||||
|
||||
/* Discard .eh_frame, we are not doing unwind on panic so it is not needed */
|
||||
/DISCARD/ :
|
||||
{
|
||||
*(.eh_frame);
|
||||
*(.eh_frame_hdr);
|
||||
}
|
||||
}
|
||||
|
||||
_estack = ORIGIN(RAM) + LENGTH(RAM);
|
||||
|
||||
/* Do not exceed this mark in the error messages above | */
|
||||
ASSERT(ORIGIN(REGION_TEXT) % 4 == 0, "
|
||||
ERROR(riscv-rt): the start of the REGION_TEXT must be 4-byte aligned");
|
||||
|
||||
ASSERT(ORIGIN(REGION_RODATA) % 4 == 0, "
|
||||
ERROR(riscv-rt): the start of the REGION_RODATA must be 4-byte aligned");
|
||||
|
||||
ASSERT(ORIGIN(REGION_DATA) % 4 == 0, "
|
||||
ERROR(riscv-rt): the start of the REGION_DATA must be 4-byte aligned");
|
||||
|
||||
ASSERT(ORIGIN(REGION_HEAP) % 4 == 0, "
|
||||
ERROR(riscv-rt): the start of the REGION_HEAP must be 4-byte aligned");
|
||||
|
||||
ASSERT(ORIGIN(REGION_TEXT) % 4 == 0, "
|
||||
ERROR(riscv-rt): the start of the REGION_TEXT must be 4-byte aligned");
|
||||
|
||||
ASSERT(ORIGIN(REGION_STACK) % 4 == 0, "
|
||||
ERROR(riscv-rt): the start of the REGION_STACK must be 4-byte aligned");
|
||||
|
||||
ASSERT(_stext % 4 == 0, "
|
||||
ERROR(riscv-rt): `_stext` must be 4-byte aligned");
|
||||
|
||||
ASSERT(_sdata % 4 == 0 && _edata % 4 == 0, "
|
||||
BUG(riscv-rt): .data is not 4-byte aligned");
|
||||
|
||||
ASSERT(_sidata % 4 == 0, "
|
||||
BUG(riscv-rt): the LMA of .data is not 4-byte aligned");
|
||||
|
||||
ASSERT(_sbss % 4 == 0 && _ebss % 4 == 0, "
|
||||
BUG(riscv-rt): .bss is not 4-byte aligned");
|
||||
|
||||
ASSERT(_sheap % 4 == 0, "
|
||||
BUG(riscv-rt): start of .heap is not 4-byte aligned");
|
||||
|
||||
ASSERT(_stext + SIZEOF(.text) < ORIGIN(REGION_TEXT) + LENGTH(REGION_TEXT), "
|
||||
ERROR(riscv-rt): The .text section must be placed inside the REGION_TEXT region.
|
||||
Set _stext to an address smaller than 'ORIGIN(REGION_TEXT) + LENGTH(REGION_TEXT)'");
|
||||
|
||||
ASSERT(SIZEOF(.got) == 0, "
|
||||
.got section detected in the input files. Dynamic relocations are not
|
||||
supported. If you are linking to C code compiled using the `gcc` crate
|
||||
then modify your build script to compile the C code _without_ the
|
||||
-fPIC flag. See the documentation of the `gcc::Config.fpic` method for
|
||||
details.");
|
||||
|
||||
/* Do not exceed this mark in the error messages above | */
|
22
riscv-rust-blink/src/c/irq.c
Normal file
22
riscv-rust-blink/src/c/irq.c
Normal file
@ -0,0 +1,22 @@
|
||||
#include <generated/csr.h>
|
||||
#include <irq.h>
|
||||
#include <usb.h>
|
||||
#include <system.h>
|
||||
|
||||
|
||||
void isr(void) {
|
||||
unsigned int irqs;
|
||||
|
||||
irqs = irq_pending() & irq_getmask();
|
||||
|
||||
if (irqs & (1 << USB_INTERRUPT)) {
|
||||
usb_isr();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void irq_init() {
|
||||
irq_setmask(0);
|
||||
irq_setie(1);
|
||||
csrw(mie, 0x880);
|
||||
}
|
@ -14,10 +14,37 @@ use timer::Timer;
|
||||
|
||||
const SYSTEM_CLOCK_FREQUENCY: u32 = 12_000_000;
|
||||
|
||||
|
||||
// USB-support using the c-code from riscv-blink
|
||||
#[link(name = "fomu-usb", kind = "static")]
|
||||
extern "C" {
|
||||
fn usb_init();
|
||||
fn usb_connect();
|
||||
fn irq_init();
|
||||
fn isr();
|
||||
fn _start_trap_rust();
|
||||
}
|
||||
|
||||
// set irq handler and call c-implementation
|
||||
#[doc(hidden)]
|
||||
#[link_section = ".trap.rust"]
|
||||
#[no_mangle]
|
||||
fn trap_handler() {
|
||||
unsafe {isr();}
|
||||
}
|
||||
|
||||
// This is the entry point for the application.
|
||||
// It is not allowed to return.
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
|
||||
// Call riscv-blink c-usb-initialization code
|
||||
unsafe {
|
||||
irq_init();
|
||||
usb_init();
|
||||
usb_connect();
|
||||
}
|
||||
|
||||
let peripherals = fomu_pac::Peripherals::take().unwrap();
|
||||
|
||||
let mut rgb_control = rgb::RgbControl::new(peripherals.RGB);
|
||||
|
Loading…
Reference in New Issue
Block a user