diff --git a/Cargo.toml b/Cargo.toml index 158fc8f..c972d51 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,14 +10,19 @@ license = "ISC" edition = "2018" [dependencies] -gd32vf103-pac = "0.4.0" -riscv = "0.6.0" +riscv = "0.10.1" nb = "0.1.2" void = { version = "1.0.2", default-features = false } cast = { version = "0.2.3", default-features = false } vcell = "0.1.2" embedded-dma = "0.1.2" +[dependencies.gd32vf103-pac] +# remove if/when upstream is updated +git = "https://github.com/rmsyn/gd32vf103-pac" +branch = "fixup/update" +features = ["critical-section"] + [dependencies.embedded-hal] version = "0.2.3" features = ["unproven"] diff --git a/assemble.sh b/assemble.sh deleted file mode 100755 index f0598ad..0000000 --- a/assemble.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash - -set -euxo pipefail - -# remove existing blobs because otherwise this will append object files to the old blobs -rm -f bin/*.a - -riscv64-unknown-elf-gcc -c -mabi=ilp32 -march=rv32imac eclic-mode-hack.S -o bin/eclic-mode-hack.o -ar crs bin/gd32vf103xx-hal.a bin/eclic-mode-hack.o - -rm bin/eclic-mode-hack.o diff --git a/bin/gd32vf103xx-hal.a b/bin/gd32vf103xx-hal.a deleted file mode 100644 index 092b6bf..0000000 Binary files a/bin/gd32vf103xx-hal.a and /dev/null differ diff --git a/build.rs b/build.rs deleted file mode 100644 index ed9e200..0000000 --- a/build.rs +++ /dev/null @@ -1,21 +0,0 @@ -use std::env; -use std::fs; -use std::path::PathBuf; - -fn main() { - let target = env::var("TARGET").unwrap(); - let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); - let name = env::var("CARGO_PKG_NAME").unwrap(); - - if target.starts_with("riscv") { - fs::copy( - format!("bin/{}.a", name), - out_dir.join(format!("lib{}.a", name)), - ).unwrap(); - - println!("cargo:rustc-link-lib=static={}", name); - println!("cargo:rustc-link-search={}", out_dir.display()); - } - - println!("cargo:rerun-if-changed=bin/{}.a", name); -} diff --git a/eclic-mode-hack.S b/eclic-mode-hack.S deleted file mode 100644 index 3ab85d4..0000000 --- a/eclic-mode-hack.S +++ /dev/null @@ -1,343 +0,0 @@ -/* - The code is based on vendor provided HAL libraries. - Most code come from Firmware\RISCV\env_Eclipse\start.S -*/ - -#define STORE sw -#define LOAD lw -#define LOG_REGBYTES 2 -#define REGBYTES (1 << LOG_REGBYTES) - -#define CSR_MSTATUS 0x300 -#define CSR_MTVT 0x307 -#define CSR_MEPC 0x341 -#define CSR_MCAUSE 0x342 -#define CSR_MTVT2 0x7EC -#define CSR_JALMNXTI 0x7ED -#define CSR_PUSHMCAUSE 0x7EE -#define CSR_PUSHMEPC 0x7EF -#define CSR_PUSHMSUBM 0x7EB -#define CSR_MMISC_CTL 0x7d0 -#define CSR_MSUBM 0x7c4 - -#define MSTATUS_MIE 0x00000008 - -.macro DISABLE_MIE - csrc CSR_MSTATUS, MSTATUS_MIE -.endm - -.macro SAVE_CONTEXT - addi sp, sp, -20*REGBYTES - - STORE x1, 0*REGBYTES(sp) - STORE x4, 1*REGBYTES(sp) - STORE x5, 2*REGBYTES(sp) - STORE x6, 3*REGBYTES(sp) - STORE x7, 4*REGBYTES(sp) - STORE x10, 5*REGBYTES(sp) - STORE x11, 6*REGBYTES(sp) - STORE x12, 7*REGBYTES(sp) - STORE x13, 8*REGBYTES(sp) - STORE x14, 9*REGBYTES(sp) - STORE x15, 10*REGBYTES(sp) - STORE x16, 11*REGBYTES(sp) - STORE x17, 12*REGBYTES(sp) - STORE x28, 13*REGBYTES(sp) - STORE x29, 14*REGBYTES(sp) - STORE x30, 15*REGBYTES(sp) - STORE x31, 16*REGBYTES(sp) -.endm - -.macro RESTORE_CONTEXT - LOAD x1, 0*REGBYTES(sp) - LOAD x4, 1*REGBYTES(sp) - LOAD x5, 2*REGBYTES(sp) - LOAD x6, 3*REGBYTES(sp) - LOAD x7, 4*REGBYTES(sp) - LOAD x10, 5*REGBYTES(sp) - LOAD x11, 6*REGBYTES(sp) - LOAD x12, 7*REGBYTES(sp) - LOAD x13, 8*REGBYTES(sp) - LOAD x14, 9*REGBYTES(sp) - LOAD x15, 10*REGBYTES(sp) - LOAD x16, 11*REGBYTES(sp) - LOAD x17, 12*REGBYTES(sp) - LOAD x28, 13*REGBYTES(sp) - LOAD x29, 14*REGBYTES(sp) - LOAD x30, 15*REGBYTES(sp) - LOAD x31, 16*REGBYTES(sp) - // De-allocate the stack space - addi sp, sp, 20*REGBYTES -.endm - -// IRQ entry point -.section .text.irq -.option push -.option norelax -.align 2 -.option pop -.global _irq_handler -_irq_handler: - SAVE_CONTEXT - - // The special CSR read operation, which is actually use mcause as operand to - // directly store it to memory - csrrwi x0, CSR_PUSHMCAUSE, 17 - // The special CSR read operation, which is actually use mepc as operand to - // directly store it to memory - csrrwi x0, CSR_PUSHMEPC, 18 - // The special CSR read operation, which is actually use Msubm as operand to - // directly store it to memory - csrrwi x0, CSR_PUSHMSUBM, 19 - - // The special CSR read/write operation, which is actually Claim the CLIC to - // find its pending highest ID, if the ID is not 0, then automatically enable - // the mstatus.MIE, and jump to its vector-entry-label, and update the link register. - csrrw ra, CSR_JALMNXTI, ra - - DISABLE_MIE - - LOAD x5, 19*REGBYTES(sp) - csrw CSR_MSUBM, x5 - LOAD x5, 18*REGBYTES(sp) - csrw CSR_MEPC, x5 - LOAD x5, 17*REGBYTES(sp) - csrw CSR_MCAUSE, x5 - - RESTORE_CONTEXT - - mret - -.section .text.vectors, "ax" -.option push -.option norelax -.align 9 -.option pop - -vectors: - .word 0 - .word 0 - .word 0 - .word INT_SFT - .word 0 - .word 0 - .word 0 - .word INT_TMR - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word INT_BWEI - .word INT_PMOVI - .word WWDGT - .word EXTI_LVD - .word TAMPER - .word RTC - .word FMC - .word RCU - .word EXTI_LINE0 - .word EXTI_LINE1 - .word EXTI_LINE2 - .word EXTI_LINE3 - .word EXTI_LINE4 - .word DMA0_CHANNEL0 - .word DMA0_CHANNEL1 - .word DMA0_CHANNEL2 - .word DMA0_CHANNEL3 - .word DMA0_CHANNEL4 - .word DMA0_CHANNEL5 - .word DMA0_CHANNEL6 - .word ADC0_1 - .word CAN0_TX - .word CAN0_RX0 - .word CAN0_RX1 - .word CAN0_EWMC - .word EXTI_LINE9_5 - .word TIMER0_BRK - .word TIMER0_UP - .word TIMER0_TRG_CMT - .word TIMER0_CHANNEL - .word TIMER1 - .word TIMER2 - .word TIMER3 - .word I2C0_EV - .word I2C0_ER - .word I2C1_EV - .word I2C1_ER - .word SPI0 - .word SPI1 - .word USART0 - .word USART1 - .word USART2 - .word EXTI_LINE15_10 - .word RTC_ALARM - .word USBFS_WKUP - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word EXMC // not present in Reference Manual but present in vendor HAL - .word 0 - .word TIMER4 - .word SPI2 - .word UART3 - .word UART4 - .word TIMER5 - .word TIMER6 - .word DMA1_CHANNEL0 - .word DMA1_CHANNEL1 - .word DMA1_CHANNEL2 - .word DMA1_CHANNEL3 - .word DMA1_CHANNEL4 - .word 0 - .word 0 - .word CAN1_TX - .word CAN1_RX0 - .word CAN1_RX1 - .word CAN1_EWMC - .word USBFS -/* - Trap entry point (_start_trap) -*/ -.section .trap, "ax" -.option push -.option norelax -.align 6 -.option pop -.global _start_trap -_start_trap: - addi sp, sp, -16*REGBYTES - - STORE ra, 0*REGBYTES(sp) - STORE t0, 1*REGBYTES(sp) - STORE t1, 2*REGBYTES(sp) - STORE t2, 3*REGBYTES(sp) - STORE t3, 4*REGBYTES(sp) - STORE t4, 5*REGBYTES(sp) - STORE t5, 6*REGBYTES(sp) - STORE t6, 7*REGBYTES(sp) - STORE a0, 8*REGBYTES(sp) - STORE a1, 9*REGBYTES(sp) - STORE a2, 10*REGBYTES(sp) - STORE a3, 11*REGBYTES(sp) - STORE a4, 12*REGBYTES(sp) - STORE a5, 13*REGBYTES(sp) - STORE a6, 14*REGBYTES(sp) - STORE a7, 15*REGBYTES(sp) - - add a0, sp, zero - jal ra, _start_trap_rust - - LOAD ra, 0*REGBYTES(sp) - LOAD t0, 1*REGBYTES(sp) - LOAD t1, 2*REGBYTES(sp) - LOAD t2, 3*REGBYTES(sp) - LOAD t3, 4*REGBYTES(sp) - LOAD t4, 5*REGBYTES(sp) - LOAD t5, 6*REGBYTES(sp) - LOAD t6, 7*REGBYTES(sp) - LOAD a0, 8*REGBYTES(sp) - LOAD a1, 9*REGBYTES(sp) - LOAD a2, 10*REGBYTES(sp) - LOAD a3, 11*REGBYTES(sp) - LOAD a4, 12*REGBYTES(sp) - LOAD a5, 13*REGBYTES(sp) - LOAD a6, 14*REGBYTES(sp) - LOAD a7, 15*REGBYTES(sp) - - addi sp, sp, 16*REGBYTES - mret -.section .text -.global _setup_interrupts -_setup_interrupts: - // Set the the NMI base to share with mtvec by setting CSR_MMISC_CTL - li t0, 0x200 - csrs CSR_MMISC_CTL, t0 - - // Set the mtvt - la t0, vectors - csrw CSR_MTVT, t0 - - // Set the mtvt2 and enable it - la t0, _irq_handler - csrw CSR_MTVT2, t0 - csrs CSR_MTVT2, 0x1 - - // Enable ECLIC and set trap handler - la t0, _start_trap - andi t0, t0, -64 - ori t0, t0, 3 - csrw mtvec, t0 - - ret - -.weak INT_SFT -.weak INT_TMR -.weak INT_BWEI -.weak INT_PMOVI -.weak WWDGT -.weak EXTI_LVD -.weak TAMPER -.weak RTC -.weak FMC -.weak RCU -.weak EXTI_LINE0 -.weak EXTI_LINE1 -.weak EXTI_LINE2 -.weak EXTI_LINE3 -.weak EXTI_LINE4 -.weak DMA0_CHANNEL0 -.weak DMA0_CHANNEL1 -.weak DMA0_CHANNEL2 -.weak DMA0_CHANNEL3 -.weak DMA0_CHANNEL4 -.weak DMA0_CHANNEL5 -.weak DMA0_CHANNEL6 -.weak ADC0_1 -.weak CAN0_TX -.weak CAN0_RX0 -.weak CAN0_RX1 -.weak CAN0_EWMC -.weak EXTI_LINE9_5 -.weak TIMER0_BRK -.weak TIMER0_UP -.weak TIMER0_TRG_CMT -.weak TIMER0_CHANNEL -.weak TIMER1 -.weak TIMER2 -.weak TIMER3 -.weak I2C0_EV -.weak I2C0_ER -.weak I2C1_EV -.weak I2C1_ER -.weak SPI0 -.weak SPI1 -.weak USART0 -.weak USART1 -.weak USART2 -.weak EXTI_LINE15_10 -.weak RTC_ALARM -.weak USBFS_WKUP -.weak EXMC -.weak TIMER4 -.weak SPI2 -.weak UART3 -.weak UART4 -.weak TIMER5 -.weak TIMER6 -.weak DMA1_CHANNEL0 -.weak DMA1_CHANNEL1 -.weak DMA1_CHANNEL2 -.weak DMA1_CHANNEL3 -.weak DMA1_CHANNEL4 -.weak CAN1_TX -.weak CAN1_RX0 -.weak CAN1_RX1 -.weak CAN1_EWMC -.weak USBFS diff --git a/src/eclic.rs b/src/eclic.rs index 071892c..853a6f1 100644 --- a/src/eclic.rs +++ b/src/eclic.rs @@ -1,5 +1,8 @@ -use crate::pac::ECLIC; -use riscv::interrupt::Nr; +use crate::pac::{ECLIC, Interrupt}; + +/// The code is based on vendor provided HAL libraries. +/// Most code come from Firmware\RISCV\env_Eclipse\start.S +pub mod mode; const EFFECTIVE_LEVEL_PRIORITY_BITS: u8 = 4; @@ -84,43 +87,43 @@ pub trait EclicExt { fn get_priority_bits() -> u8; /// Setup `interrupt` - fn setup(interrupt: I, tt: TriggerType, level: Level, priority: Priority); + fn setup(interrupt: Interrupt, tt: TriggerType, level: Level, priority: Priority); /// Enables `interrupt` - unsafe fn unmask(interrupt: I); + unsafe fn unmask(interrupt: Interrupt); /// Disables `interrupt` - fn mask(interrupt: I); + fn mask(interrupt: Interrupt); /// Checks if `interrupt` is enabled - fn is_enabled(interrupt: I) -> bool; + fn is_enabled(interrupt: Interrupt) -> bool; /// Forces `interrupt` into pending state - fn pend(interrupt: I); + fn pend(interrupt: Interrupt); /// Clears `interrupt`'s pending state - fn unpend(interrupt: I); + fn unpend(interrupt: Interrupt); /// Checks if `interrupt` is pending - fn is_pending(interrupt: I) -> bool; + fn is_pending(interrupt: Interrupt) -> bool; /// Set `interrupt` trigger type - fn set_trigger_type(interrupt: I, tt: TriggerType); + fn set_trigger_type(interrupt: Interrupt, tt: TriggerType); /// Get `interrupt` trigger type - fn get_trigger_type(interrupt: I) -> Option; + fn get_trigger_type(interrupt: Interrupt) -> Option; // Set `interrupt` level - fn set_level(interrupt: I, level: Level); + fn set_level(interrupt: Interrupt, level: Level); // Get `interrupt` level - fn get_level(interrupt: I) -> Level; + fn get_level(interrupt: Interrupt) -> Level; // Set `interrupt` priority - fn set_priority(interrupt: I, priority: Priority); + fn set_priority(interrupt: Interrupt, priority: Priority); // Get `interrupt` interrupt - fn get_priority(interrupt: I) -> Priority; + fn get_priority(interrupt: Interrupt) -> Priority; } impl EclicExt for ECLIC { @@ -181,7 +184,7 @@ impl EclicExt for ECLIC { EFFECTIVE_LEVEL_PRIORITY_BITS - Self::get_level_bits() } - fn setup(interrupt: I, tt: TriggerType, level: Level, priority: Priority) { + fn setup(interrupt: Interrupt, tt: TriggerType, level: Level, priority: Priority) { Self::mask(interrupt); Self::set_trigger_type(interrupt, tt); Self::set_level(interrupt, level); @@ -190,8 +193,8 @@ impl EclicExt for ECLIC { } #[inline] - unsafe fn unmask(interrupt: I) { - let nr = usize::from(interrupt.nr()); + unsafe fn unmask(interrupt: Interrupt) { + let nr = interrupt as usize; (*Self::ptr()).clicints[nr] .clicintie @@ -199,8 +202,8 @@ impl EclicExt for ECLIC { } #[inline] - fn mask(interrupt: I) { - let nr = usize::from(interrupt.nr()); + fn mask(interrupt: Interrupt) { + let nr = interrupt as usize; unsafe { (*Self::ptr()).clicints[nr] @@ -210,8 +213,8 @@ impl EclicExt for ECLIC { } #[inline] - fn is_enabled(interrupt: I) -> bool { - let nr = usize::from(interrupt.nr()); + fn is_enabled(interrupt: Interrupt) -> bool { + let nr = interrupt as usize; unsafe { (*Self::ptr()).clicints[nr] @@ -223,8 +226,8 @@ impl EclicExt for ECLIC { } #[inline] - fn pend(interrupt: I) { - let nr = usize::from(interrupt.nr()); + fn pend(interrupt: Interrupt) { + let nr = interrupt as usize; unsafe { (*Self::ptr()).clicints[nr] @@ -234,8 +237,8 @@ impl EclicExt for ECLIC { } #[inline] - fn unpend(interrupt: I) { - let nr = usize::from(interrupt.nr()); + fn unpend(interrupt: Interrupt) { + let nr = interrupt as usize; unsafe { (*Self::ptr()).clicints[nr] @@ -245,8 +248,8 @@ impl EclicExt for ECLIC { } #[inline] - fn is_pending(interrupt: I) -> bool { - let nr = usize::from(interrupt.nr()); + fn is_pending(interrupt: Interrupt) -> bool { + let nr = interrupt as usize; unsafe { (*Self::ptr()).clicints[nr] @@ -258,8 +261,8 @@ impl EclicExt for ECLIC { } #[inline] - fn set_trigger_type(interrupt: I, tt: TriggerType) { - let nr = usize::from(interrupt.nr()); + fn set_trigger_type(interrupt: Interrupt, tt: TriggerType) { + let nr = interrupt as usize; unsafe { (*Self::ptr()).clicints[nr] @@ -269,8 +272,8 @@ impl EclicExt for ECLIC { } #[inline] - fn get_trigger_type(interrupt: I) -> Option { - let nr = usize::from(interrupt.nr()); + fn get_trigger_type(interrupt: Interrupt) -> Option { + let nr = interrupt as usize; match unsafe { (*Self::ptr()).clicints[nr].clicintattr.read().trig().bits() } { 0 => Some(TriggerType::Level), @@ -281,8 +284,8 @@ impl EclicExt for ECLIC { } #[inline] - fn set_level(interrupt: I, level: Level) { - let nr = usize::from(interrupt.nr()); + fn set_level(interrupt: Interrupt, level: Level) { + let nr = interrupt as usize; let mut intctl = unsafe { (*Self::ptr()).clicints[nr] @@ -307,8 +310,8 @@ impl EclicExt for ECLIC { } #[inline] - fn get_level(interrupt: I) -> Level { - let nr = usize::from(interrupt.nr()); + fn get_level(interrupt: Interrupt) -> Level { + let nr = interrupt as usize; let intctl = unsafe { (*Self::ptr()).clicints[nr] @@ -325,8 +328,8 @@ impl EclicExt for ECLIC { } #[inline] - fn set_priority(interrupt: I, priority: Priority) { - let nr = usize::from(interrupt.nr()); + fn set_priority(interrupt: Interrupt, priority: Priority) { + let nr = interrupt as usize; let mut intctl = unsafe { (*Self::ptr()).clicints[nr] @@ -354,8 +357,8 @@ impl EclicExt for ECLIC { } #[inline] - fn get_priority(interrupt: I) -> Priority { - let nr = usize::from(interrupt.nr()); + fn get_priority(interrupt: Interrupt) -> Priority { + let nr = interrupt as usize; let intctl = unsafe { (*Self::ptr()).clicints[nr] diff --git a/src/eclic/mode.rs b/src/eclic/mode.rs new file mode 100644 index 0000000..9ca1a42 --- /dev/null +++ b/src/eclic/mode.rs @@ -0,0 +1,264 @@ +#![allow(named_asm_labels)] + +use core::arch::global_asm; + +global_asm!( + ".equ LOG_REGBYTES, 2", + ".equ REGBYTES, 1 << LOG_REGBYTES", + ".equ MSTATUS_MIE, 0x00000008", + // + ".macro DISABLE_MIE", + "csrc mstatus, MSTATUS_MIE", + ".endm", + // + ".macro SAVE_CONTEXT", + // + "addi sp, sp, -20*REGBYTES", + // + "sw x1, 0*REGBYTES(sp)", + "sw x4, 1*REGBYTES(sp)", + "sw x5, 2*REGBYTES(sp)", + "sw x6, 3*REGBYTES(sp)", + "sw x7, 4*REGBYTES(sp)", + "sw x10, 5*REGBYTES(sp)", + "sw x11, 6*REGBYTES(sp)", + "sw x12, 7*REGBYTES(sp)", + "sw x13, 8*REGBYTES(sp)", + "sw x14, 9*REGBYTES(sp)", + "sw x15, 10*REGBYTES(sp)", + "sw x16, 11*REGBYTES(sp)", + "sw x17, 12*REGBYTES(sp)", + "sw x28, 13*REGBYTES(sp)", + "sw x29, 14*REGBYTES(sp)", + "sw x30, 15*REGBYTES(sp)", + "sw x31, 16*REGBYTES(sp)", + ".endm", + // + ".macro RESTORE_CONTEXT", + "lw x1, 0*REGBYTES(sp)", + "lw x4, 1*REGBYTES(sp)", + "lw x5, 2*REGBYTES(sp)", + "lw x6, 3*REGBYTES(sp)", + "lw x7, 4*REGBYTES(sp)", + "lw x10, 5*REGBYTES(sp)", + "lw x11, 6*REGBYTES(sp)", + "lw x12, 7*REGBYTES(sp)", + "lw x13, 8*REGBYTES(sp)", + "lw x14, 9*REGBYTES(sp)", + "lw x15, 10*REGBYTES(sp)", + "lw x16, 11*REGBYTES(sp)", + "lw x17, 12*REGBYTES(sp)", + "lw x28, 13*REGBYTES(sp)", + "lw x29, 14*REGBYTES(sp)", + "lw x30, 15*REGBYTES(sp)", + "lw x31, 16*REGBYTES(sp)", + // De-allocate the stack space + "addi sp, sp, 20*REGBYTES", + ".endm", + // + ".section .text.irq", + ".option push", + ".option norelax", + ".align 2", + ".option pop", + ".global _irq_handler", + "_irq_handler:", + "SAVE_CONTEXT", + // + // The special CSR read operation, which actually uses mcause as operand + // to directly store it to memory + "csrrwi x0, 0x7ee, 17", + // The special CSR read operation, which actually uses mepc as operand + // to directly store it to memory + "csrrwi x0, 0x7ef, 18", + // The special CSR read operation, which actually uses msubm as operand + // to directly store it to memory + "csrrwi x0, 0x7eb, 19", + // + // The special CSR read/write operation, which is actually Claim the CLIC to + // find its pending highest ID, if the ID is not 0, then automatically enable + // the mstatus.MIE, and jump to its vector-entry-label, and update the link register. + "csrrw ra, 0x7ed, ra", + // + "DISABLE_MIE", + // + "lw x5, 19*REGBYTES(sp)", + // Load x5 value into PUSHMSUBM system status register + "csrw 0x7eb, x5", + "lw x5, 18*REGBYTES(sp)", + "csrw mepc, x5", + "lw x5, 17*REGBYTES(sp)", + "csrw mcause, x5", + // + "RESTORE_CONTEXT", + // + "mret", + // + ".section .text.vectors, \"ax\"", + ".option push", + ".option norelax", + ".align 9", + ".option pop", + "vectors:", + ".word 0", + ".word 0", + ".word 0", + ".word INT_SFT", + ".word 0", + ".word 0", + ".word 0", + ".word INT_TMR", + ".word 0", + ".word 0", + ".word 0", + ".word 0", + ".word 0", + ".word 0", + ".word 0", + ".word 0", + ".word 0", + ".word INT_BWEI", + ".word INT_PMOVI", + ".word WWDGT", + ".word EXTI_LVD", + ".word TAMPER", + ".word RTC", + ".word FMC", + ".word RCU", + ".word EXTI_LINE0", + ".word EXTI_LINE1", + ".word EXTI_LINE2", + ".word EXTI_LINE3", + ".word EXTI_LINE4", + ".word DMA0_CHANNEL0", + ".word DMA0_CHANNEL1", + ".word DMA0_CHANNEL2", + ".word DMA0_CHANNEL3", + ".word DMA0_CHANNEL4", + ".word DMA0_CHANNEL5", + ".word DMA0_CHANNEL6", + ".word ADC0_1", + ".word CAN0_TX", + ".word CAN0_RX0", + ".word CAN0_RX1", + ".word CAN0_EWMC", + ".word EXTI_LINE9_5", + ".word TIMER0_BRK", + ".word TIMER0_UP", + ".word TIMER0_TRG_CMT", + ".word TIMER0_CHANNEL", + ".word TIMER1", + ".word TIMER2", + ".word TIMER3", + ".word I2C0_EV", + ".word I2C0_ER", + ".word I2C1_EV", + ".word I2C1_ER", + ".word SPI0", + ".word SPI1", + ".word USART0", + ".word USART1", + ".word USART2", + ".word EXTI_LINE15_10", + ".word RTC_ALARM", + ".word USBFS_WKUP", + ".word 0", + ".word 0", + ".word 0", + ".word 0", + ".word 0", + ".word EXMC", // not present in Reference Manual but present in vendor HAL + ".word 0", + ".word TIMER4", + ".word SPI2", + ".word UART3", + ".word UART4", + ".word TIMER5", + ".word TIMER6", + ".word DMA1_CHANNEL0", + ".word DMA1_CHANNEL1", + ".word DMA1_CHANNEL2", + ".word DMA1_CHANNEL3", + ".word DMA1_CHANNEL4", + ".word 0", + ".word 0", + ".word CAN1_TX", + ".word CAN1_RX0", + ".word CAN1_RX1", + ".word CAN1_EWMC", + ".word USBFS", + // + ".section .trap, \"ax\"", + ".option push", + ".option norelax", + ".align 6", + ".option pop", + ".global _start_trap", + "_start_trap:", + "addi sp, sp, -16*REGBYTES", + // + "sw ra, 0*REGBYTES(sp)", + "sw t0, 1*REGBYTES(sp)", + "sw t1, 2*REGBYTES(sp)", + "sw t2, 3*REGBYTES(sp)", + "sw t3, 4*REGBYTES(sp)", + "sw t4, 5*REGBYTES(sp)", + "sw t5, 6*REGBYTES(sp)", + "sw t6, 7*REGBYTES(sp)", + "sw a0, 8*REGBYTES(sp)", + "sw a1, 9*REGBYTES(sp)", + "sw a2, 10*REGBYTES(sp)", + "sw a3, 11*REGBYTES(sp)", + "sw a4, 12*REGBYTES(sp)", + "sw a5, 13*REGBYTES(sp)", + "sw a6, 14*REGBYTES(sp)", + "sw a7, 15*REGBYTES(sp)", + // + "add a0, sp, zero", + "jal ra, _start_trap_rust", + // + "lw ra, 0*REGBYTES(sp)", + "lw t0, 1*REGBYTES(sp)", + "lw t1, 2*REGBYTES(sp)", + "lw t2, 3*REGBYTES(sp)", + "lw t3, 4*REGBYTES(sp)", + "lw t4, 5*REGBYTES(sp)", + "lw t5, 6*REGBYTES(sp)", + "lw t6, 7*REGBYTES(sp)", + "lw a0, 8*REGBYTES(sp)", + "lw a1, 9*REGBYTES(sp)", + "lw a2, 10*REGBYTES(sp)", + "lw a3, 11*REGBYTES(sp)", + "lw a4, 12*REGBYTES(sp)", + "lw a5, 13*REGBYTES(sp)", + "lw a6, 14*REGBYTES(sp)", + "lw a7, 15*REGBYTES(sp)", + // + "addi sp, sp, 16*REGBYTES", + "mret", + // + ".section .text", + ".global _setup_interrupts", + "_setup_interrupts:", + // Set the the NMI base to share with mtvec by setting CSR_MMISC_CTL + "li t0, 0x200", + "csrs 0x7d0, t0", + // + // Set the mtvt + "la t0, vectors", + "csrw 0x307, t0", + // + // Set the mtvt2 and enable it + "la t0, _irq_handler", + "csrw 0x7ec, t0", + "csrs 0x7ec, 0x1", + // + // Enable ECLIC and set trap handler + "la t0, _start_trap", + "andi t0, t0, -64", + "ori t0, t0, 3", + "csrw mtvec, t0", + // + "ret", + options(raw), +); diff --git a/src/gpio.rs b/src/gpio.rs index 8cced3c..7984d72 100644 --- a/src/gpio.rs +++ b/src/gpio.rs @@ -117,7 +117,7 @@ trait PeripheralAccess { let value = (bits as u32) << offset; let regs = Self::peripheral(); - interrupt::free(|_| { + interrupt::free(|| { if index < 8 { regs.ctl0.modify(|r, w| unsafe { w.bits((r.bits() & mask) | value) diff --git a/src/rcu.rs b/src/rcu.rs index 5aa694e..2203285 100644 --- a/src/rcu.rs +++ b/src/rcu.rs @@ -327,14 +327,14 @@ macro_rules! bus_enable { impl Enable for crate::pac::$PER { #[inline(always)] fn enable(rcu: &mut Rcu) { - interrupt::free(|_| { + interrupt::free(|| { rcu.regs.$apben.modify(|_, w| w.$peren().set_bit()); }); } #[inline(always)] fn disable(rcu: &mut Rcu) { - interrupt::free(|_| { + interrupt::free(|| { rcu.regs.$apben.modify(|_, w| w.$peren().clear_bit()); }); } @@ -350,7 +350,7 @@ macro_rules! bus { impl Reset for crate::pac::$PER { #[inline(always)] fn reset(rcu: &mut Rcu) { - interrupt::free(|_| { + interrupt::free(|| { rcu.regs.$apbrst.modify(|_, w| w.$perrst().set_bit()); rcu.regs.$apbrst.modify(|_, w| w.$perrst().clear_bit()); });