From 95f776bcdcf31a7cfd864195a6f01e7c6fdede28 Mon Sep 17 00:00:00 2001 From: Stephan Date: Fri, 9 Jun 2023 20:47:50 +0200 Subject: [PATCH] use the critical-section crate and update examples accordingly --- examples/blinky/.cargo/config | 2 +- examples/blinky/32MX150F128B_procdefs.ld | 57 ----- examples/blinky/32MX270F256B_procdefs.ld | 40 +++ examples/blinky/Cargo.lock | 96 ++++---- examples/blinky/Cargo.toml | 9 +- examples/blinky/build.sh | 1 + examples/blinky/pic32_common.ld | 27 ++- examples/i2c_oled_display/.cargo/config | 3 +- .../i2c_oled_display/32MX150F128B_procdefs.ld | 57 ----- .../i2c_oled_display/32MX274F256B_procdefs.ld | 57 ----- examples/i2c_oled_display/Cargo.lock | 228 +++++++++++------- examples/i2c_oled_display/Cargo.toml | 15 +- examples/i2c_oled_display/build.sh | 1 + examples/i2c_oled_display/pic32_common.ld | 31 +-- examples/i2c_oled_display/src/main.rs | 136 +++++++---- examples/usb_serial/.cargo/config | 1 - examples/usb_serial/32MX270F256B_procdefs.ld | 61 ++--- examples/usb_serial/32MX274F256B_procdefs.ld | 57 ----- examples/usb_serial/Cargo.lock | 89 ++++--- examples/usb_serial/Cargo.toml | 7 +- examples/usb_serial/build.sh | 1 + examples/usb_serial/pic32_common.ld | 31 +-- mips-mcu-alloc/Cargo.toml | 5 +- mips-mcu-alloc/src/lib.rs | 31 ++- mips-mcu/Cargo.toml | 9 +- mips-mcu/src/critical_section.rs | 19 ++ mips-mcu/src/interrupt.rs | 39 +-- mips-mcu/src/lib.rs | 3 + mips-rt/Cargo.toml | 5 +- mips-rt/src/fmt.rs | 21 -- mips-rt/src/interrupt.rs | 65 ----- pic32-hal/Cargo.toml | 11 +- pic32-hal/src/coretimer.rs | 11 +- pic32-hal/src/gpio.rs | 5 +- pic32-hal/src/int.rs | 2 +- pic32-hal/src/lib.rs | 16 +- pic32-hal/src/uart.rs | 2 +- 37 files changed, 543 insertions(+), 708 deletions(-) delete mode 100644 examples/blinky/32MX150F128B_procdefs.ld create mode 100644 examples/blinky/32MX270F256B_procdefs.ld delete mode 100644 examples/i2c_oled_display/32MX150F128B_procdefs.ld delete mode 100644 examples/i2c_oled_display/32MX274F256B_procdefs.ld delete mode 100644 examples/usb_serial/32MX274F256B_procdefs.ld create mode 100644 mips-mcu/src/critical_section.rs delete mode 100644 mips-rt/src/fmt.rs delete mode 100644 mips-rt/src/interrupt.rs diff --git a/examples/blinky/.cargo/config b/examples/blinky/.cargo/config index e7106c9..263ebc9 100644 --- a/examples/blinky/.cargo/config +++ b/examples/blinky/.cargo/config @@ -1,6 +1,6 @@ [target.mipsel-unknown-none] -rustflags = ["-C", "link-arg=-T32MX150F128B_procdefs.ld"] +rustflags = ["-C", "link-arg=-T32MX270F256B_procdefs.ld"] [build] target = "mipsel-unknown-none" diff --git a/examples/blinky/32MX150F128B_procdefs.ld b/examples/blinky/32MX150F128B_procdefs.ld deleted file mode 100644 index dd6c67e..0000000 --- a/examples/blinky/32MX150F128B_procdefs.ld +++ /dev/null @@ -1,57 +0,0 @@ -/************************************************************************* - * Processor-specific object file. - *************************************************************************/ - -/************************************************************************* - * Symbols used for interrupt-vector table generation - *************************************************************************/ -PROVIDE(_vector_spacing = 0x0001); -PROVIDE(_ebase_address = 0x9D01F000); /* last 4 KiB of program flash */ - -/************************************************************************* - * Memory Address Equates - * _RESET_ADDR -- Reset Vector or entry point - * _BEV_EXCPT_ADDR -- Boot exception Vector - * _DBG_EXCPT_ADDR -- In-circuit Debugging Exception Vector - * _DBG_CODE_ADDR -- In-circuit Debug Executive address - * _DBG_CODE_SIZE -- In-circuit Debug Executive size - * _GEN_EXCPT_ADDR -- General Exception Vector - *************************************************************************/ -_RESET_ADDR = 0xBFC00000; -_BEV_EXCPT_ADDR = 0xBFC00380; -_DBG_EXCPT_ADDR = 0xBFC00480; -_DBG_CODE_ADDR = 0x9FC00490; -_DBG_CODE_SIZE = 0x760; -_GEN_EXCPT_ADDR = _ebase_address + 0x180; - -/************************************************************************* - * Memory Regions - * - * Memory regions without attributes cannot be used for orphaned sections. - * Only sections specifically assigned to these regions can be allocated - * into these regions. - * - * The Debug exception vector is located at 0x9FC00480. - * - * The config_
sections are used to locate the config words at - * their absolute addresses. - *************************************************************************/ - - -MEMORY -{ - kseg0_program_mem (rx) : ORIGIN = 0x9D000000, LENGTH = 0x1F000 -/* kseg0_boot_mem : ORIGIN = 0x9FC00490, LENGTH = 0x970 */ - exception_mem : ORIGIN = 0x9D01F000, LENGTH = 0x1000 - kseg1_boot_mem : ORIGIN = 0xBFC00000, LENGTH = 0x490 - debug_exec_mem : ORIGIN = 0x0FC00490, LENGTH = 0x760 - kseg1_data_mem (w!x) : ORIGIN = 0xA0000000, LENGTH = 0x8000 - sfrs : ORIGIN = 0xBF800000, LENGTH = 0x100000 - configsfrs : ORIGIN = 0xBFC00BF0, LENGTH = 0x10 -} - -/************************************************************************* - * common part for all PIC32 devices - *************************************************************************/ -INPUT("device.x") /* interrupt vector symbols from Peripheral Access Crate */ -INPUT("pic32_common.ld") diff --git a/examples/blinky/32MX270F256B_procdefs.ld b/examples/blinky/32MX270F256B_procdefs.ld new file mode 100644 index 0000000..fb46aa7 --- /dev/null +++ b/examples/blinky/32MX270F256B_procdefs.ld @@ -0,0 +1,40 @@ +/************************************************************************* + * Processor-specific object file for PIC32MX170 and PIC32MX270 + *************************************************************************/ + +/************************************************************************* + * Symbols used for interrupt-vector table generation + *************************************************************************/ +PROVIDE(_vector_spacing = 0x0001); +PROVIDE(_ebase_address = 0x9D000000); /* first 4 KiB of program flash */ + + +MEMORY +{ + boot_flash (rx) : ORIGIN = 0xBFC00000, LENGTH = 0xc00 + program_flash (rx) : ORIGIN = 0x9D000000, LENGTH = 256k + sram (w!x) : ORIGIN = 0x80000000, LENGTH = 64k + configsfrs : ORIGIN = 0xBFC00BF0, LENGTH = 0x10 +} + +REGION_ALIAS("exception_mem", program_flash) +REGION_ALIAS("program_mem", program_flash) +REGION_ALIAS("data_mem", sram) + +/* aliases for direct start without bootloader + * put the reset handler into the boot flash. + */ +REGION_ALIAS(reset_mem, boot_flash) + +/* aliases for bootloader support + * put the bootloader into the boot flash section and the reset handler at the + * beginning of the normal program flash memory. + */ +/* REGION_ALIAS(reset_mem, program_flash) +REGION_ALIAS(bootloader_mem, boot_flash) */ + +/************************************************************************* + * common part for all PIC32 devices + *************************************************************************/ +INPUT("device.x") /* interrupt vector symbols from Peripheral Access Crate */ +INPUT("pic32_common.ld") diff --git a/examples/blinky/Cargo.lock b/examples/blinky/Cargo.lock index 1cff741..22a92f1 100644 --- a/examples/blinky/Cargo.lock +++ b/examples/blinky/Cargo.lock @@ -2,27 +2,28 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "bare-metal" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8fe8f5a8a398345e52358e18ff07cc17a568fbca5c6f73873d3a62056309603" - [[package]] name = "blinky" version = "0.2.0" dependencies = [ "embedded-hal", + "mips-mcu", "mips-rt", "pic32-config-sector", "pic32-hal", ] +[[package]] +name = "critical-section" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6548a0ad5d2549e111e1f6a11a6c2e2d00ce6a3dafe22948d67c2b443f775e52" + [[package]] name = "embedded-hal" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e36cfb62ff156596c892272f3015ef952fe1525e85261fa3a7f327bd6b384ab9" +checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff" dependencies = [ "nb 0.1.3", "void", @@ -30,40 +31,39 @@ dependencies = [ [[package]] name = "enumflags2" -version = "0.6.4" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83c8d82922337cd23a15f88b70d8e4ef5f11da38dd7cdb55e84dd5de99695da0" +checksum = "c041f5090df68b32bcd905365fd51769c8b9d553fe87fde0b683534f10c01bd2" dependencies = [ "enumflags2_derive", ] [[package]] name = "enumflags2_derive" -version = "0.6.4" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "946ee94e3dbf58fdd324f9ce245c7b238d46a66f00e86a020b71996349e46cce" +checksum = "5e9a1f9f7d83e59740248a6e14ecf93929ade55027844dfcea78beafccc15745" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.18", ] [[package]] name = "mips-mcu" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cb9dfcb19ab4530dec67e8f47b696a1480346382983a42db41248b8dc81e945" +checksum = "f03a97ce7dfe942a6601816d623c8bf7d84263fb1a85e4aefbd94be5a24ff5dd" dependencies = [ - "bare-metal", + "critical-section", ] [[package]] name = "mips-rt" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e37979f5efb0e8ba8fa5f926d402264d0925ce2bee8e793d5975ef7b417d1858" +checksum = "3d5524ac83440e7e7d18012dc92c48ccb0447e4f2d0adbe0a8be72cc58e33a49" dependencies = [ - "bare-metal", "mips-rt-macros", ] @@ -75,7 +75,7 @@ checksum = "42ff6b0bb34b0abbc0eef02f9a6dde26c3a3367b9efd5a87c75b2df1e3b6e083" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -84,80 +84,92 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f" dependencies = [ - "nb 1.0.0", + "nb 1.1.0", ] [[package]] name = "nb" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "546c37ac5d9e56f55e73b677106873d9d9f5190605e41a856503623648488cae" +checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d" [[package]] name = "pic32-config-sector" -version = "0.1.2" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef66fccf1a7354d6379530051fc3dc92902c62cf99429578cd680e059baf4b55" +checksum = "ad21a2aff96011e7f7e917a013a9eb246e73d5dae1fe0d94ea1d7e452fa88498" [[package]] name = "pic32-hal" -version = "0.6.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1266b54cee988e517810744f03a6fbd7bd7e14c61fa68c149157d83979e275bb" +checksum = "9f6393dd973e257ad9652c2aa8402de1ad71ce4fadd52579ea83e229db94748b" dependencies = [ + "critical-section", "embedded-hal", "enumflags2", "mips-mcu", "mips-rt", - "nb 1.0.0", + "nb 1.1.0", "pic32mx2xx", ] [[package]] name = "pic32mx2xx" -version = "0.4.2" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40caa69670525379b6ee5107f7b79791a2503d371d4bf199c26bcfc6b5640f7f" +checksum = "799c0d6a647a779daa1808604268ec564384d5f2e94a32df9c5bf04204acf821" dependencies = [ - "mips-mcu", + "critical-section", "mips-rt", "vcell", ] [[package]] name = "proc-macro2" -version = "1.0.36" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" +checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406" dependencies = [ - "unicode-xid", + "unicode-ident", ] [[package]] name = "quote" -version = "1.0.15" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "syn" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2", + "quote", + "unicode-ident", ] [[package]] name = "syn" -version = "1.0.86" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b" +checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" dependencies = [ "proc-macro2", "quote", - "unicode-xid", + "unicode-ident", ] [[package]] -name = "unicode-xid" -version = "0.2.2" +name = "unicode-ident" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" +checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" [[package]] name = "vcell" diff --git a/examples/blinky/Cargo.toml b/examples/blinky/Cargo.toml index a4bd2ea..40e512b 100644 --- a/examples/blinky/Cargo.toml +++ b/examples/blinky/Cargo.toml @@ -9,13 +9,14 @@ edition = "2018" pic32mx1xxfxxxb = ["pic32-hal/pic32mx1xxfxxxb"] pic32mx2xxfxxxb = ["pic32-hal/pic32mx2xxfxxxb"] rx = [] -default = ["pic32mx1xxfxxxb"] +default = ["pic32mx2xxfxxxb"] [dependencies] +mips-mcu = { version = "0.3.0", features = ["critical-section-single-core"] } mips-rt = "0.3.0" -embedded-hal = "0.2.3" -pic32-hal = "0.6.1" -pic32-config-sector = "0.1.2" +embedded-hal = "0.2.7" +pic32-hal = "0.9.0" +pic32-config-sector = "0.2.0" [profile.release] opt-level = 2 lto = true diff --git a/examples/blinky/build.sh b/examples/blinky/build.sh index 1378b0f..54f0853 100755 --- a/examples/blinky/build.sh +++ b/examples/blinky/build.sh @@ -2,4 +2,5 @@ BIN=blinky +cargo build --release || exit cargo objcopy --release $* -- -O ihex $BIN.hex diff --git a/examples/blinky/pic32_common.ld b/examples/blinky/pic32_common.ld index 7a1689f..214af92 100644 --- a/examples/blinky/pic32_common.ld +++ b/examples/blinky/pic32_common.ld @@ -11,10 +11,9 @@ ENTRY(_reset); EXTERN(_gen_exception) /* stack */ -PROVIDE(_stack = ORIGIN(kseg1_data_mem) + LENGTH(kseg1_data_mem)); +PROVIDE(_stack = ORIGIN(data_mem) + LENGTH(data_mem)); - -/* # Pre-initialization function */ +/* Pre-initialization function */ /* If the user overrides this using the `pre_init!` macro or by creating a `__pre_init` function, then the function this points to will be called before the RAM is initialized. */ PROVIDE(__pre_init = DefaultPreInit); @@ -22,17 +21,22 @@ PROVIDE(__pre_init = DefaultPreInit); /* # Sections */ SECTIONS { + /* boot loader */ + .bootloader : { + KEEP(*(.bootloader)) + } > bootloader_mem + /* ## PIC32MX configuration registers */ .configsfrs : { KEEP(*(.configsfrs)); } > configsfrs - /* Boot Sections */ + /* Reset Sections */ .reset : { KEEP(*(.reset)) KEEP(*(.reset.startup)) - } > kseg1_boot_mem + } > reset_mem /* .bev_excpt _BEV_EXCPT_ADDR : { KEEP(*(.bev_handler)) @@ -45,11 +49,10 @@ SECTIONS } > debug_exec_mem */ /* Exception handlers */ - .app_excpt : + .app_excpt _ebase_address + 0x180: { - . = _GEN_EXCPT_ADDR; KEEP(*(.gen_handler)) - } > exception_mem = 0xffffffff + } > exception_mem .vector_0 _ebase_address + 0x200 + ((_vector_spacing << 5) * 0) : { @@ -376,7 +379,7 @@ SECTIONS .text : { *(.text .text.*); - } > kseg0_program_mem + } > program_mem /* ### .rodata */ .rodata : ALIGN(4) @@ -387,7 +390,7 @@ SECTIONS This is required by LLD to ensure the LMA of the following .data section will have the correct alignment. */ . = ALIGN(4); - } > kseg0_program_mem + } > program_mem /* ## Sections in RAM */ /* ### .data */ @@ -396,7 +399,7 @@ SECTIONS *(.data .data.*); . = ALIGN(4); /* 4-byte align the end (VMA) of this section */ - } > kseg1_data_mem AT > kseg0_program_mem + } > data_mem AT > program_mem /* VMA of .data */ __sdata = ADDR(.data); @@ -411,7 +414,7 @@ SECTIONS *(.bss .bss.*); . = ALIGN(4); /* 4-byte align the end (VMA) of this section */ - } > kseg1_data_mem + } > data_mem __sbss = ADDR(.bss); __ebss = ADDR(.bss) + SIZEOF(.bss); diff --git a/examples/i2c_oled_display/.cargo/config b/examples/i2c_oled_display/.cargo/config index 1e1bfb9..263ebc9 100644 --- a/examples/i2c_oled_display/.cargo/config +++ b/examples/i2c_oled_display/.cargo/config @@ -1,7 +1,6 @@ [target.mipsel-unknown-none] -rustflags = ["-C", "link-arg=-T32MX150F128B_procdefs.ld"] -#rustflags = ["-C", "link-arg=-T32MX274F256B_procdefs.ld"] +rustflags = ["-C", "link-arg=-T32MX270F256B_procdefs.ld"] [build] target = "mipsel-unknown-none" diff --git a/examples/i2c_oled_display/32MX150F128B_procdefs.ld b/examples/i2c_oled_display/32MX150F128B_procdefs.ld deleted file mode 100644 index dd6c67e..0000000 --- a/examples/i2c_oled_display/32MX150F128B_procdefs.ld +++ /dev/null @@ -1,57 +0,0 @@ -/************************************************************************* - * Processor-specific object file. - *************************************************************************/ - -/************************************************************************* - * Symbols used for interrupt-vector table generation - *************************************************************************/ -PROVIDE(_vector_spacing = 0x0001); -PROVIDE(_ebase_address = 0x9D01F000); /* last 4 KiB of program flash */ - -/************************************************************************* - * Memory Address Equates - * _RESET_ADDR -- Reset Vector or entry point - * _BEV_EXCPT_ADDR -- Boot exception Vector - * _DBG_EXCPT_ADDR -- In-circuit Debugging Exception Vector - * _DBG_CODE_ADDR -- In-circuit Debug Executive address - * _DBG_CODE_SIZE -- In-circuit Debug Executive size - * _GEN_EXCPT_ADDR -- General Exception Vector - *************************************************************************/ -_RESET_ADDR = 0xBFC00000; -_BEV_EXCPT_ADDR = 0xBFC00380; -_DBG_EXCPT_ADDR = 0xBFC00480; -_DBG_CODE_ADDR = 0x9FC00490; -_DBG_CODE_SIZE = 0x760; -_GEN_EXCPT_ADDR = _ebase_address + 0x180; - -/************************************************************************* - * Memory Regions - * - * Memory regions without attributes cannot be used for orphaned sections. - * Only sections specifically assigned to these regions can be allocated - * into these regions. - * - * The Debug exception vector is located at 0x9FC00480. - * - * The config_
sections are used to locate the config words at - * their absolute addresses. - *************************************************************************/ - - -MEMORY -{ - kseg0_program_mem (rx) : ORIGIN = 0x9D000000, LENGTH = 0x1F000 -/* kseg0_boot_mem : ORIGIN = 0x9FC00490, LENGTH = 0x970 */ - exception_mem : ORIGIN = 0x9D01F000, LENGTH = 0x1000 - kseg1_boot_mem : ORIGIN = 0xBFC00000, LENGTH = 0x490 - debug_exec_mem : ORIGIN = 0x0FC00490, LENGTH = 0x760 - kseg1_data_mem (w!x) : ORIGIN = 0xA0000000, LENGTH = 0x8000 - sfrs : ORIGIN = 0xBF800000, LENGTH = 0x100000 - configsfrs : ORIGIN = 0xBFC00BF0, LENGTH = 0x10 -} - -/************************************************************************* - * common part for all PIC32 devices - *************************************************************************/ -INPUT("device.x") /* interrupt vector symbols from Peripheral Access Crate */ -INPUT("pic32_common.ld") diff --git a/examples/i2c_oled_display/32MX274F256B_procdefs.ld b/examples/i2c_oled_display/32MX274F256B_procdefs.ld deleted file mode 100644 index 8521ed1..0000000 --- a/examples/i2c_oled_display/32MX274F256B_procdefs.ld +++ /dev/null @@ -1,57 +0,0 @@ -/************************************************************************* - * Processor-specific object file. - *************************************************************************/ - -/************************************************************************* - * Symbols used for interrupt-vector table generation - *************************************************************************/ -PROVIDE(_vector_spacing = 0x0001); -PROVIDE(_ebase_address = 0x9FC01000); - -/************************************************************************* - * Memory Address Equates - * _RESET_ADDR -- Reset Vector or entry point - * _BEV_EXCPT_ADDR -- Boot exception Vector - * _DBG_EXCPT_ADDR -- In-circuit Debugging Exception Vector - * _DBG_CODE_ADDR -- In-circuit Debug Executive address - * _DBG_CODE_SIZE -- In-circuit Debug Executive size - * _GEN_EXCPT_ADDR -- General Exception Vector - *************************************************************************/ -_RESET_ADDR = 0xBFC00000; -_BEV_EXCPT_ADDR = 0xBFC00380; -_DBG_EXCPT_ADDR = 0xBFC00480; -_DBG_CODE_ADDR = 0xBFC02000; -_DBG_CODE_SIZE = 0xFF0; -_GEN_EXCPT_ADDR = _ebase_address + 0x180; - -/************************************************************************* - * Memory Regions - * - * Memory regions without attributes cannot be used for orphaned sections. - * Only sections specifically assigned to these regions can be allocated - * into these regions. - * - * The Debug exception vector is located at 0x9FC00480. - * - * The config_
sections are used to locate the config words at - * their absolute addresses. - *************************************************************************/ - - -MEMORY -{ - kseg0_program_mem (rx) : ORIGIN = 0x9D000000, LENGTH = 0x40000 - kseg0_boot_mem : ORIGIN = 0x9FC00490, LENGTH = 0x970 - exception_mem : ORIGIN = 0x9FC01000, LENGTH = 0x1000 - kseg1_boot_mem : ORIGIN = 0xBFC00000, LENGTH = 0x490 - debug_exec_mem : ORIGIN = 0xBFC02000, LENGTH = 0xFF0 - kseg1_data_mem (w!x) : ORIGIN = 0xA0000000, LENGTH = 0x10000 - sfrs : ORIGIN = 0xBF800000, LENGTH = 0x100000 - configsfrs : ORIGIN = 0xBFC02FF0, LENGTH = 0x10 -} - -/************************************************************************* - * common part for all PIC32 devices - *************************************************************************/ -INPUT("device.x") /* interrupt vector symbols from Peripheral Access Crate */ -INPUT("pic32_common.ld") diff --git a/examples/i2c_oled_display/Cargo.lock b/examples/i2c_oled_display/Cargo.lock index 759a190..1009b40 100644 --- a/examples/i2c_oled_display/Cargo.lock +++ b/examples/i2c_oled_display/Cargo.lock @@ -3,26 +3,90 @@ version = 3 [[package]] -name = "bare-metal" -version = "1.0.0" +name = "autocfg" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8fe8f5a8a398345e52358e18ff07cc17a568fbca5c6f73873d3a62056309603" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "az" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b7e4c2464d97fe331d41de9d5db0def0a96f4d823b8b32a2efd503578988973" + +[[package]] +name = "byte-slice-cast" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0a5e3906bcbf133e33c1d4d95afc664ad37fbdb9f6568d8043e7ea8c27d93d3" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "critical-section" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6548a0ad5d2549e111e1f6a11a6c2e2d00ce6a3dafe22948d67c2b443f775e52" + +[[package]] +name = "display-interface" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7517c040926d7b02b111884aa089177db80878533127f7c1b480d852c5fb4112" + +[[package]] +name = "display-interface-i2c" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4895cd4e54e5536ef370d7f1eec787aad8275dd8ad15815aebfa71dd847b4ebf" +dependencies = [ + "display-interface", + "embedded-hal", +] + +[[package]] +name = "display-interface-spi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "489378ad054862146fbd1f09f51d585ccbe4bd1e2feadcda2a13ac33f840e1a5" +dependencies = [ + "byte-slice-cast", + "display-interface", + "embedded-hal", +] [[package]] name = "embedded-graphics" -version = "0.4.9" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd2a8e0250a7e1212828166b01eed0219e488ebb2599f44624a29c9bd249f397" +dependencies = [ + "az", + "byteorder", + "embedded-graphics-core", + "float-cmp", + "micromath", +] + +[[package]] +name = "embedded-graphics-core" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2e7ee289ac88cbeea6f749cd72c6eb4cdeb801f4ea26795aace97b9776a2db2" +checksum = "ba9ecd261f991856250d2207f6d8376946cd9f412a2165d3b75bc87a0bc7a044" dependencies = [ - "tinybmp", - "tinytga", + "az", + "byteorder", ] [[package]] name = "embedded-hal" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e36cfb62ff156596c892272f3015ef952fe1525e85261fa3a7f327bd6b384ab9" +checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff" dependencies = [ "nb 0.1.3", "void", @@ -30,30 +94,41 @@ dependencies = [ [[package]] name = "enumflags2" -version = "0.6.4" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83c8d82922337cd23a15f88b70d8e4ef5f11da38dd7cdb55e84dd5de99695da0" +checksum = "c041f5090df68b32bcd905365fd51769c8b9d553fe87fde0b683534f10c01bd2" dependencies = [ "enumflags2_derive", ] [[package]] name = "enumflags2_derive" -version = "0.6.4" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "946ee94e3dbf58fdd324f9ce245c7b238d46a66f00e86a020b71996349e46cce" +checksum = "5e9a1f9f7d83e59740248a6e14ecf93929ade55027844dfcea78beafccc15745" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.18", +] + +[[package]] +name = "float-cmp" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" +dependencies = [ + "num-traits", ] [[package]] name = "i2c_oled_display" version = "0.3.0" dependencies = [ + "critical-section", "embedded-graphics", "embedded-hal", + "mips-mcu", "mips-rt", "pic32-config-sector", "pic32-hal", @@ -62,27 +137,26 @@ dependencies = [ ] [[package]] -name = "memchr" -version = "2.4.1" +name = "micromath" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" +checksum = "39617bc909d64b068dcffd0e3e31679195b5576d0c83fadc52690268cc2b2b55" [[package]] name = "mips-mcu" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cb9dfcb19ab4530dec67e8f47b696a1480346382983a42db41248b8dc81e945" +checksum = "f03a97ce7dfe942a6601816d623c8bf7d84263fb1a85e4aefbd94be5a24ff5dd" dependencies = [ - "bare-metal", + "critical-section", ] [[package]] name = "mips-rt" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e37979f5efb0e8ba8fa5f926d402264d0925ce2bee8e793d5975ef7b417d1858" +checksum = "3d5524ac83440e7e7d18012dc92c48ccb0447e4f2d0adbe0a8be72cc58e33a49" dependencies = [ - "bare-metal", "mips-rt-macros", ] @@ -94,7 +168,7 @@ checksum = "42ff6b0bb34b0abbc0eef02f9a6dde26c3a3367b9efd5a87c75b2df1e3b6e083" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -103,133 +177,119 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f" dependencies = [ - "nb 1.0.0", + "nb 1.1.0", ] [[package]] name = "nb" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "546c37ac5d9e56f55e73b677106873d9d9f5190605e41a856503623648488cae" - -[[package]] -name = "nom" -version = "4.2.3" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6" -dependencies = [ - "memchr", - "version_check 0.1.5", -] +checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d" [[package]] -name = "nom" -version = "5.1.2" +name = "num-traits" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" dependencies = [ - "memchr", - "version_check 0.9.4", + "autocfg", ] [[package]] name = "pic32-config-sector" -version = "0.1.2" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef66fccf1a7354d6379530051fc3dc92902c62cf99429578cd680e059baf4b55" +checksum = "ad21a2aff96011e7f7e917a013a9eb246e73d5dae1fe0d94ea1d7e452fa88498" [[package]] name = "pic32-hal" -version = "0.6.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1266b54cee988e517810744f03a6fbd7bd7e14c61fa68c149157d83979e275bb" +checksum = "9f6393dd973e257ad9652c2aa8402de1ad71ce4fadd52579ea83e229db94748b" dependencies = [ + "critical-section", "embedded-hal", "enumflags2", "mips-mcu", "mips-rt", - "nb 1.0.0", + "nb 1.1.0", "pic32mx2xx", ] [[package]] name = "pic32mx2xx" -version = "0.4.2" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40caa69670525379b6ee5107f7b79791a2503d371d4bf199c26bcfc6b5640f7f" +checksum = "799c0d6a647a779daa1808604268ec564384d5f2e94a32df9c5bf04204acf821" dependencies = [ - "mips-mcu", + "critical-section", "mips-rt", "vcell", ] [[package]] name = "proc-macro2" -version = "1.0.36" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" +checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406" dependencies = [ - "unicode-xid", + "unicode-ident", ] [[package]] name = "quote" -version = "1.0.15" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145" +checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" dependencies = [ "proc-macro2", ] [[package]] name = "ssd1306" -version = "0.2.6" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57d818022001ebca8cec28b230700660a3f6a027123c8193c5e76e9764d087f3" +checksum = "e1eaea5daefc39bfa675e4e75e484af7e54628ffe4fc5300e52bde5905f6b677" dependencies = [ - "embedded-graphics", + "display-interface", + "display-interface-i2c", + "display-interface-spi", + "embedded-graphics-core", "embedded-hal", ] [[package]] name = "syn" -version = "1.0.86" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2", "quote", - "unicode-xid", + "unicode-ident", ] [[package]] -name = "tinybmp" -version = "0.1.1" +name = "syn" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30d12b7f8b271567d6d072c49dee16b22271aabfc473e2066e3353e5af0f5230" +checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" dependencies = [ - "nom 5.1.2", + "proc-macro2", + "quote", + "unicode-ident", ] [[package]] name = "tinylog" version = "0.1.0" -source = "git+https://github.com/kiffie/pic32-rs.git#850281ec48b3d80837b1ae7f74bef2335f6bfe19" - -[[package]] -name = "tinytga" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc9485052c1f4b541d888f1d564dd9957671e0c21da9bca0c9824c1123e03f07" -dependencies = [ - "nom 4.2.3", -] +source = "git+https://github.com/kiffie/pic32-rs.git#cd9c04013297983948cb472d575d559a2a88d2ac" [[package]] -name = "unicode-xid" -version = "0.2.2" +name = "unicode-ident" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" +checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" [[package]] name = "vcell" @@ -237,18 +297,6 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002" -[[package]] -name = "version_check" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - [[package]] name = "void" version = "1.0.2" diff --git a/examples/i2c_oled_display/Cargo.toml b/examples/i2c_oled_display/Cargo.toml index 80d91ff..42b940d 100644 --- a/examples/i2c_oled_display/Cargo.toml +++ b/examples/i2c_oled_display/Cargo.toml @@ -7,17 +7,20 @@ edition = "2018" [features] pic32mx1xxfxxxb = ["pic32-hal/pic32mx1xxfxxxb"] +pic32mx2xxfxxxb = ["pic32-hal/pic32mx2xxfxxxb"] pic32mx2x4fxxxb = ["pic32-hal/pic32mx2x4fxxxb"] -default = ["pic32mx1xxfxxxb"] +default = ["pic32mx2xxfxxxb"] [dependencies] +mips-mcu = { version = "0.3.0", features = ["critical-section-single-core"] } mips-rt = "0.3.0" -embedded-hal = "0.2.3" +embedded-hal = "0.2.7" +critical-section = "1.0.0" tinylog = { git = "https://github.com/kiffie/pic32-rs.git" } -pic32-hal = "0.6.1" -ssd1306 = "0.2.6" -embedded-graphics = "0.4.9" -pic32-config-sector = "0.1.0" +pic32-hal = "0.9.0" +ssd1306 = "0.8.0" +embedded-graphics = "0.8.0" +pic32-config-sector = "0.2.0" [profile.release] opt-level = 2 diff --git a/examples/i2c_oled_display/build.sh b/examples/i2c_oled_display/build.sh index 8d68d96..bf84317 100755 --- a/examples/i2c_oled_display/build.sh +++ b/examples/i2c_oled_display/build.sh @@ -2,4 +2,5 @@ BIN=i2c_oled_display +cargo build --release || exit cargo objcopy --release -- -O ihex $BIN.hex diff --git a/examples/i2c_oled_display/pic32_common.ld b/examples/i2c_oled_display/pic32_common.ld index ce030b8..214af92 100644 --- a/examples/i2c_oled_display/pic32_common.ld +++ b/examples/i2c_oled_display/pic32_common.ld @@ -11,10 +11,9 @@ ENTRY(_reset); EXTERN(_gen_exception) /* stack */ -PROVIDE(_stack = ORIGIN(kseg1_data_mem) + LENGTH(kseg1_data_mem)); +PROVIDE(_stack = ORIGIN(data_mem) + LENGTH(data_mem)); - -/* # Pre-initialization function */ +/* Pre-initialization function */ /* If the user overrides this using the `pre_init!` macro or by creating a `__pre_init` function, then the function this points to will be called before the RAM is initialized. */ PROVIDE(__pre_init = DefaultPreInit); @@ -22,21 +21,26 @@ PROVIDE(__pre_init = DefaultPreInit); /* # Sections */ SECTIONS { + /* boot loader */ + .bootloader : { + KEEP(*(.bootloader)) + } > bootloader_mem + /* ## PIC32MX configuration registers */ .configsfrs : { KEEP(*(.configsfrs)); } > configsfrs - /* Boot Sections */ + /* Reset Sections */ .reset : { KEEP(*(.reset)) KEEP(*(.reset.startup)) - } > kseg1_boot_mem - .bev_excpt _BEV_EXCPT_ADDR : + } > reset_mem + /* .bev_excpt _BEV_EXCPT_ADDR : { KEEP(*(.bev_handler)) - } > kseg1_boot_mem + } > kseg1_boot_mem */ /* Debug exception vector */ /* Space reserved for the debug executive */ /* .dbg_code _DBG_CODE_ADDR (NOLOAD) : @@ -45,11 +49,10 @@ SECTIONS } > debug_exec_mem */ /* Exception handlers */ - .app_excpt : + .app_excpt _ebase_address + 0x180: { - . = _GEN_EXCPT_ADDR; KEEP(*(.gen_handler)) - } > exception_mem = 0xffffffff + } > exception_mem .vector_0 _ebase_address + 0x200 + ((_vector_spacing << 5) * 0) : { @@ -376,7 +379,7 @@ SECTIONS .text : { *(.text .text.*); - } > kseg0_program_mem + } > program_mem /* ### .rodata */ .rodata : ALIGN(4) @@ -387,7 +390,7 @@ SECTIONS This is required by LLD to ensure the LMA of the following .data section will have the correct alignment. */ . = ALIGN(4); - } > kseg0_program_mem + } > program_mem /* ## Sections in RAM */ /* ### .data */ @@ -396,7 +399,7 @@ SECTIONS *(.data .data.*); . = ALIGN(4); /* 4-byte align the end (VMA) of this section */ - } > kseg1_data_mem AT > kseg0_program_mem + } > data_mem AT > program_mem /* VMA of .data */ __sdata = ADDR(.data); @@ -411,7 +414,7 @@ SECTIONS *(.bss .bss.*); . = ALIGN(4); /* 4-byte align the end (VMA) of this section */ - } > kseg1_data_mem + } > data_mem __sbss = ADDR(.bss); __ebss = ADDR(.bss) + SIZEOF(.bss); diff --git a/examples/i2c_oled_display/src/main.rs b/examples/i2c_oled_display/src/main.rs index 860e0af..a8ea8d5 100644 --- a/examples/i2c_oled_display/src/main.rs +++ b/examples/i2c_oled_display/src/main.rs @@ -4,13 +4,18 @@ #![no_std] #![feature(panic_info_message)] +use core::cell::RefCell; use core::panic::PanicInfo; - +use critical_section::{self, Mutex}; use embedded_graphics::{ - fonts::{Font12x16, Font6x12, Font6x8, Font8x16}, - image::Image1BPP, + image::{Image, ImageRaw}, + mono_font::{ + ascii::{FONT_10X20, FONT_6X9, FONT_8X13}, + MonoTextStyle, + }, + pixelcolor::BinaryColor, prelude::*, - Drawing, + text::Text, }; use embedded_hal::{ blocking::delay::DelayMs, @@ -24,19 +29,21 @@ use pic32_hal::{ gpio::GpioExt, i2c::{Fscl, I2c}, pac, - pac::UART1, + pac::UART2, pps::{MapPin, NoPin, PpsExt}, pps_no_pin, time::U32Ext, uart::{Tx, Uart}, }; -use ssd1306::{mode::GraphicsMode, Builder}; +use ssd1306::{prelude::*, I2CDisplayInterface, Ssd1306}; use tinylog::{self, debug, error, info}; #[cfg(feature = "pic32mx1xxfxxxb")] use pic32_config_sector::pic32mx1xx::*; #[cfg(feature = "pic32mx2x4fxxxb")] use pic32_config_sector::pic32mx2x4::*; +#[cfg(feature = "pic32mx2xxfxxxb")] +use pic32_config_sector::pic32mx2xx::*; const TL_LOGLEVEL: tinylog::Level = tinylog::Level::Debug; @@ -62,6 +69,26 @@ pub static CONFIGSFRS: ConfigSector = ConfigSector::default() .ICESEL(ICESEL::ICS_PGx1) .build(); +// PIC32 configuration registers for PIC32MX1xx and PIC32MX2xx +#[cfg(any(feature = "pic32mx1xxfxxxb", feature = "pic32mx2xxfxxxb"))] +#[link_section = ".configsfrs"] +#[used] +pub static CONFIGSFRS: ConfigSector = ConfigSector::default() + .FVBUSONIO(FVBUSONIO::OFF) + .FUSBIDIO(FUSBIDIO::OFF) + .IOL1WAY(IOL1WAY::OFF) + .PMDL1WAY(PMDL1WAY::OFF) + .FPLLIDIV(FPLLIDIV::DIV_2) + .FPLLMUL(FPLLMUL::MUL_20) + .FPLLODIV(FPLLODIV::DIV_2) + .FNOSC(FNOSC::FRCPLL) + .FSOSCEN(FSOSCEN::OFF) + .FPBDIV(FPBDIV::DIV_1) + .FWDTEN(FWDTEN::OFF) + .JTAGEN(JTAGEN::OFF) + .ICESEL(ICESEL::ICS_PGx1) + .build(); + // PIC32 configuration registers for PIC32MX274 #[cfg(feature = "pic32mx2x4fxxxb")] #[link_section = ".configsfrs"] @@ -91,16 +118,19 @@ pub static CONFIGSFRS: ConfigSector = ConfigSector::default() .DEBUG(DEBUG::OFF) .build(); -static mut LOG_TX: Option> = None; +static LOG_TX2: Mutex>>> = Mutex::new(RefCell::new(None)); fn log_bwrite_all(buffer: &[u8]) { - unsafe { - if let Some(ref mut tx) = LOG_TX { - for b in buffer { - while match tx.write(*b) { - Ok(()) => false, - Err(_) => true, - } {} + let is_none = critical_section::with(|cs| LOG_TX2.borrow(cs).borrow_mut().is_none()); + if is_none { + return; + } + for b in buffer { + loop { + if critical_section::with(|cs| LOG_TX2.borrow_ref_mut(cs).as_mut().unwrap().write(*b)) + .is_ok() + { + break; } } } @@ -110,13 +140,12 @@ fn log_bwrite_all(buffer: &[u8]) { fn main() -> ! { //configure IO ports for UART let p = pac::Peripherals::take().unwrap(); - let porta = p.PORTA.split(); let portb = p.PORTB.split(); let vpins = p.PPS.split(); // setup clock control object let sysclock = 40_000_000_u32.hz(); - #[cfg(feature = "pic32mx1xxfxxxb")] + #[cfg(any(feature = "pic32mx1xxfxxxb", feature = "pic32mx2xxfxxxb"))] let clock = Osc::new(p.OSC, sysclock); #[cfg(feature = "pic32mx2x4fxxxb")] let clock = Osc::new(p.CRU, sysclock); @@ -124,20 +153,22 @@ fn main() -> ! { let mut timer = Delay::new(sysclock); /* initialize clock control and uart */ - let txd = porta - .ra0 + let txd = portb + .rb0 .into_push_pull_output() - .map_pin(vpins.outputs.u1tx); - let uart = Uart::uart1(p.UART1, &clock, 115200, pps_no_pin!(vpins.inputs.u1rx), txd); + .map_pin(vpins.outputs.u2tx); + let uart = Uart::uart2(p.UART2, &clock, 115200, pps_no_pin!(vpins.inputs.u2rx), txd); timer.delay_ms(10u32); let (tx, _) = uart.split(); - unsafe { LOG_TX = Some(tx) }; + critical_section::with(|cs| { + *LOG_TX2.borrow_ref_mut(cs) = Some(tx); + }); tinylog::set_bwrite_all(log_bwrite_all); info!("I2C oled display example"); debug!("sysclock = {} Hz", sysclock.0); /* LED */ - let mut led = portb.rb0.into_push_pull_output(); + let mut led = portb.rb5.into_push_pull_output(); let mut state = false; @@ -149,48 +180,49 @@ fn main() -> ! { info!("initializing display"); let i2c = I2c::i2c1(p.I2C1, clock.pb_clock(), Fscl::F400KHZ); - let mut disp: GraphicsMode<_> = Builder::new().connect_i2c(i2c).into(); + let interface = I2CDisplayInterface::new(i2c); + let mut disp = Ssd1306::new(interface, DisplaySize128x64, DisplayRotation::Rotate0) + .into_buffered_graphics_mode(); disp.init().unwrap(); - disp.flush().unwrap(); - disp.draw( - Font6x8::render_str("Hello World 6x8") - .translate(Coord::new(0, 0)) - .into_iter(), - ); - - disp.draw( - Font6x12::render_str("Hello World 6x12") - .translate(Coord::new(0, 8)) - .into_iter(), - ); - - disp.draw( - Font8x16::render_str("Hello World 8x16") - .translate(Coord::new(0, 20)) - .into_iter(), - ); - - disp.draw( - Font12x16::render_str("Hello 12x16") - .translate(Coord::new(0, 36)) - .into_iter(), - ); + Text::new( + "Hello 10x20", + Point::new(0, 20), + MonoTextStyle::new(&FONT_10X20, BinaryColor::On), + ) + .draw(&mut disp) + .unwrap(); + + Text::new( + "Hello World 8x13", + Point::new(0, 33), + MonoTextStyle::new(&FONT_8X13, BinaryColor::On), + ) + .draw(&mut disp) + .unwrap(); + + Text::new( + "Hello World 6x9", + Point::new(0, 42), + MonoTextStyle::new(&FONT_6X9, BinaryColor::On), + ) + .draw(&mut disp) + .unwrap(); disp.flush().unwrap(); timer.delay_ms(10000u32); - let bitmap = include_bytes!("./rust.raw"); + let raw: ImageRaw = ImageRaw::new(include_bytes!("./rust.raw"), 64); info!("starting loop"); let mut x = 0; let mut move_right = true; loop { - let im = Image1BPP::new(bitmap, 64, 64).translate(Coord::new(x, 0)); - disp.clear(); - disp.draw(im.into_iter()); + let im = Image::new(&raw, Point::new(x, 0)); + disp.clear(BinaryColor::Off).unwrap(); + im.draw(&mut disp).unwrap(); disp.flush().unwrap(); state = !state; if move_right { @@ -198,12 +230,14 @@ fn main() -> ! { x += 1; } else { debug!("left"); + led.set_high().unwrap(); move_right = false; } } else if x > 0 { x -= 1; } else { debug!("right"); + led.set_low().unwrap(); move_right = true; } } diff --git a/examples/usb_serial/.cargo/config b/examples/usb_serial/.cargo/config index 0d089da..263ebc9 100644 --- a/examples/usb_serial/.cargo/config +++ b/examples/usb_serial/.cargo/config @@ -1,7 +1,6 @@ [target.mipsel-unknown-none] rustflags = ["-C", "link-arg=-T32MX270F256B_procdefs.ld"] -#rustflags = ["-C", "link-arg=-T32MX274F256B_procdefs.ld"] [build] target = "mipsel-unknown-none" diff --git a/examples/usb_serial/32MX270F256B_procdefs.ld b/examples/usb_serial/32MX270F256B_procdefs.ld index 766e77f..fb46aa7 100644 --- a/examples/usb_serial/32MX270F256B_procdefs.ld +++ b/examples/usb_serial/32MX270F256B_procdefs.ld @@ -1,55 +1,38 @@ /************************************************************************* - * Processor-specific object file. + * Processor-specific object file for PIC32MX170 and PIC32MX270 *************************************************************************/ /************************************************************************* * Symbols used for interrupt-vector table generation *************************************************************************/ PROVIDE(_vector_spacing = 0x0001); -PROVIDE(_ebase_address = 0x9D03F000); /* last 4 KiB of program flash */ - -/************************************************************************* - * Memory Address Equates - * _RESET_ADDR -- Reset Vector or entry point - * _BEV_EXCPT_ADDR -- Boot exception Vector - * _DBG_EXCPT_ADDR -- In-circuit Debugging Exception Vector - * _DBG_CODE_ADDR -- In-circuit Debug Executive address - * _DBG_CODE_SIZE -- In-circuit Debug Executive size - * _GEN_EXCPT_ADDR -- General Exception Vector - *************************************************************************/ -_RESET_ADDR = 0xBFC00000; -_BEV_EXCPT_ADDR = 0xBFC00380; -_DBG_EXCPT_ADDR = 0xBFC00480; -_DBG_CODE_ADDR = 0x9FC00490; -_DBG_CODE_SIZE = 0x760; -_GEN_EXCPT_ADDR = _ebase_address + 0x180; - -/************************************************************************* - * Memory Regions - * - * Memory regions without attributes cannot be used for orphaned sections. - * Only sections specifically assigned to these regions can be allocated - * into these regions. - * - * The Debug exception vector is located at 0x9FC00480. - * - * The config_
sections are used to locate the config words at - * their absolute addresses. - *************************************************************************/ +PROVIDE(_ebase_address = 0x9D000000); /* first 4 KiB of program flash */ MEMORY { - kseg0_program_mem (rx) : ORIGIN = 0x9D000000, LENGTH = 0x3F000 -/* kseg0_boot_mem : ORIGIN = 0x9FC00490, LENGTH = 0x970 */ - exception_mem : ORIGIN = 0x9D03F000, LENGTH = 0x1000 - kseg1_boot_mem : ORIGIN = 0xBFC00000, LENGTH = 0x490 - debug_exec_mem : ORIGIN = 0x0FC00490, LENGTH = 0x760 - kseg1_data_mem (w!x) : ORIGIN = 0xA0000000, LENGTH = 0x10000 - sfrs : ORIGIN = 0xBF800000, LENGTH = 0x100000 - configsfrs : ORIGIN = 0xBFC00BF0, LENGTH = 0x10 + boot_flash (rx) : ORIGIN = 0xBFC00000, LENGTH = 0xc00 + program_flash (rx) : ORIGIN = 0x9D000000, LENGTH = 256k + sram (w!x) : ORIGIN = 0x80000000, LENGTH = 64k + configsfrs : ORIGIN = 0xBFC00BF0, LENGTH = 0x10 } +REGION_ALIAS("exception_mem", program_flash) +REGION_ALIAS("program_mem", program_flash) +REGION_ALIAS("data_mem", sram) + +/* aliases for direct start without bootloader + * put the reset handler into the boot flash. + */ +REGION_ALIAS(reset_mem, boot_flash) + +/* aliases for bootloader support + * put the bootloader into the boot flash section and the reset handler at the + * beginning of the normal program flash memory. + */ +/* REGION_ALIAS(reset_mem, program_flash) +REGION_ALIAS(bootloader_mem, boot_flash) */ + /************************************************************************* * common part for all PIC32 devices *************************************************************************/ diff --git a/examples/usb_serial/32MX274F256B_procdefs.ld b/examples/usb_serial/32MX274F256B_procdefs.ld deleted file mode 100644 index 8521ed1..0000000 --- a/examples/usb_serial/32MX274F256B_procdefs.ld +++ /dev/null @@ -1,57 +0,0 @@ -/************************************************************************* - * Processor-specific object file. - *************************************************************************/ - -/************************************************************************* - * Symbols used for interrupt-vector table generation - *************************************************************************/ -PROVIDE(_vector_spacing = 0x0001); -PROVIDE(_ebase_address = 0x9FC01000); - -/************************************************************************* - * Memory Address Equates - * _RESET_ADDR -- Reset Vector or entry point - * _BEV_EXCPT_ADDR -- Boot exception Vector - * _DBG_EXCPT_ADDR -- In-circuit Debugging Exception Vector - * _DBG_CODE_ADDR -- In-circuit Debug Executive address - * _DBG_CODE_SIZE -- In-circuit Debug Executive size - * _GEN_EXCPT_ADDR -- General Exception Vector - *************************************************************************/ -_RESET_ADDR = 0xBFC00000; -_BEV_EXCPT_ADDR = 0xBFC00380; -_DBG_EXCPT_ADDR = 0xBFC00480; -_DBG_CODE_ADDR = 0xBFC02000; -_DBG_CODE_SIZE = 0xFF0; -_GEN_EXCPT_ADDR = _ebase_address + 0x180; - -/************************************************************************* - * Memory Regions - * - * Memory regions without attributes cannot be used for orphaned sections. - * Only sections specifically assigned to these regions can be allocated - * into these regions. - * - * The Debug exception vector is located at 0x9FC00480. - * - * The config_
sections are used to locate the config words at - * their absolute addresses. - *************************************************************************/ - - -MEMORY -{ - kseg0_program_mem (rx) : ORIGIN = 0x9D000000, LENGTH = 0x40000 - kseg0_boot_mem : ORIGIN = 0x9FC00490, LENGTH = 0x970 - exception_mem : ORIGIN = 0x9FC01000, LENGTH = 0x1000 - kseg1_boot_mem : ORIGIN = 0xBFC00000, LENGTH = 0x490 - debug_exec_mem : ORIGIN = 0xBFC02000, LENGTH = 0xFF0 - kseg1_data_mem (w!x) : ORIGIN = 0xA0000000, LENGTH = 0x10000 - sfrs : ORIGIN = 0xBF800000, LENGTH = 0x100000 - configsfrs : ORIGIN = 0xBFC02FF0, LENGTH = 0x10 -} - -/************************************************************************* - * common part for all PIC32 devices - *************************************************************************/ -INPUT("device.x") /* interrupt vector symbols from Peripheral Access Crate */ -INPUT("pic32_common.ld") diff --git a/examples/usb_serial/Cargo.lock b/examples/usb_serial/Cargo.lock index 5b43110..f9d0952 100644 --- a/examples/usb_serial/Cargo.lock +++ b/examples/usb_serial/Cargo.lock @@ -3,10 +3,10 @@ version = 3 [[package]] -name = "bare-metal" -version = "1.0.0" +name = "critical-section" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8fe8f5a8a398345e52358e18ff07cc17a568fbca5c6f73873d3a62056309603" +checksum = "6548a0ad5d2549e111e1f6a11a6c2e2d00ce6a3dafe22948d67c2b443f775e52" [[package]] name = "embedded-hal" @@ -20,45 +20,46 @@ dependencies = [ [[package]] name = "enumflags2" -version = "0.6.4" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83c8d82922337cd23a15f88b70d8e4ef5f11da38dd7cdb55e84dd5de99695da0" +checksum = "c041f5090df68b32bcd905365fd51769c8b9d553fe87fde0b683534f10c01bd2" dependencies = [ "enumflags2_derive", ] [[package]] name = "enumflags2_derive" -version = "0.6.4" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "946ee94e3dbf58fdd324f9ce245c7b238d46a66f00e86a020b71996349e46cce" +checksum = "5e9a1f9f7d83e59740248a6e14ecf93929ade55027844dfcea78beafccc15745" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.18", ] [[package]] name = "linked_list_allocator" -version = "0.10.3" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e8da0e6283aace40e4e0395fe5ad7a147fac6ff47bda1f038b5044fb11683c2" +checksum = "9afa463f5405ee81cdb9cc2baf37e08ec7e4c8209442b5d72c04cfb2cd6e6286" [[package]] name = "mips-mcu" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cb9dfcb19ab4530dec67e8f47b696a1480346382983a42db41248b8dc81e945" +checksum = "f03a97ce7dfe942a6601816d623c8bf7d84263fb1a85e4aefbd94be5a24ff5dd" dependencies = [ - "bare-metal", + "critical-section", ] [[package]] name = "mips-mcu-alloc" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1eed3d885d57cd90acfc7b4c8c4a0be9b066ec5dcdaabb4fa12d19fabc581b9" +checksum = "70b64f77b28ceae4862a132ef77411bda6ef3c8f9e0e19a15338219681ee08ed" dependencies = [ + "critical-section", "linked_list_allocator", "mips-mcu", "mips-rt", @@ -66,11 +67,10 @@ dependencies = [ [[package]] name = "mips-rt" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e37979f5efb0e8ba8fa5f926d402264d0925ce2bee8e793d5975ef7b417d1858" +checksum = "3d5524ac83440e7e7d18012dc92c48ccb0447e4f2d0adbe0a8be72cc58e33a49" dependencies = [ - "bare-metal", "mips-rt-macros", ] @@ -82,7 +82,7 @@ checksum = "42ff6b0bb34b0abbc0eef02f9a6dde26c3a3367b9efd5a87c75b2df1e3b6e083" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -91,14 +91,14 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f" dependencies = [ - "nb 1.0.0", + "nb 1.1.0", ] [[package]] name = "nb" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "546c37ac5d9e56f55e73b677106873d9d9f5190605e41a856503623648488cae" +checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d" [[package]] name = "panic-halt" @@ -108,59 +108,71 @@ checksum = "de96540e0ebde571dc55c73d60ef407c653844e6f9a1e2fdbd40c07b9252d812" [[package]] name = "pic32-config-sector" -version = "0.1.2" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef66fccf1a7354d6379530051fc3dc92902c62cf99429578cd680e059baf4b55" +checksum = "ad21a2aff96011e7f7e917a013a9eb246e73d5dae1fe0d94ea1d7e452fa88498" [[package]] name = "pic32-hal" -version = "0.7.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d925e7b84808d5d7958f3ca8f0b3ce07da3c9f14bffe5f10ba35c1eeb73e784b" +checksum = "9f6393dd973e257ad9652c2aa8402de1ad71ce4fadd52579ea83e229db94748b" dependencies = [ + "critical-section", "embedded-hal", "enumflags2", "mips-mcu", "mips-rt", - "nb 1.0.0", + "nb 1.1.0", "pic32mx2xx", "usb-device", ] [[package]] name = "pic32mx2xx" -version = "0.5.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dc71544e56fa5b7396065b610726d6729ec1b991ed0de140f2a41869ed7534c" +checksum = "799c0d6a647a779daa1808604268ec564384d5f2e94a32df9c5bf04204acf821" dependencies = [ - "mips-mcu", + "critical-section", "mips-rt", "vcell", ] [[package]] name = "proc-macro2" -version = "1.0.44" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bd7356a8122b6c4a24a82b278680c73357984ca2fc79a0f9fa6dea7dced7c58" +checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.21" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" dependencies = [ "proc-macro2", ] [[package]] name = "syn" -version = "1.0.100" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52205623b1b0f064a4e71182c3b18ae902267282930c6d5462c91b859668426e" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" dependencies = [ "proc-macro2", "quote", @@ -169,9 +181,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.4" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd" +checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" [[package]] name = "usb-device" @@ -184,6 +196,7 @@ name = "usb_serial" version = "0.3.0" dependencies = [ "embedded-hal", + "mips-mcu", "mips-mcu-alloc", "mips-rt", "panic-halt", diff --git a/examples/usb_serial/Cargo.toml b/examples/usb_serial/Cargo.toml index 41704b7..4d363af 100644 --- a/examples/usb_serial/Cargo.toml +++ b/examples/usb_serial/Cargo.toml @@ -11,14 +11,15 @@ pic32mx2x4fxxxb = ["pic32-hal/pic32mx2x4fxxxb"] default = ["pic32mx2xxfxxxb"] [dependencies] +mips-mcu = { version = "0.3.0", features = ["critical-section-single-core"] } mips-rt = "0.3.0" -mips-mcu-alloc = "0.5.0" +mips-mcu-alloc = "0.6.0" embedded-hal = "0.2.3" -pic32-hal = { version = "0.7.0", features = ["usb-device"] } +pic32-hal = { version = "0.9.0", features = ["usb-device"] } panic-halt = "0.2.0" usb-device = "0.2.5" usbd-serial = "0.1.0" -pic32-config-sector = "0.1.2" +pic32-config-sector = "0.2.0" [profile.release] opt-level = 2 diff --git a/examples/usb_serial/build.sh b/examples/usb_serial/build.sh index 17c4f96..46103cd 100755 --- a/examples/usb_serial/build.sh +++ b/examples/usb_serial/build.sh @@ -2,4 +2,5 @@ BIN=usb_serial +cargo build --release || exit cargo objcopy --release -- -O ihex $BIN.hex diff --git a/examples/usb_serial/pic32_common.ld b/examples/usb_serial/pic32_common.ld index ce030b8..214af92 100644 --- a/examples/usb_serial/pic32_common.ld +++ b/examples/usb_serial/pic32_common.ld @@ -11,10 +11,9 @@ ENTRY(_reset); EXTERN(_gen_exception) /* stack */ -PROVIDE(_stack = ORIGIN(kseg1_data_mem) + LENGTH(kseg1_data_mem)); +PROVIDE(_stack = ORIGIN(data_mem) + LENGTH(data_mem)); - -/* # Pre-initialization function */ +/* Pre-initialization function */ /* If the user overrides this using the `pre_init!` macro or by creating a `__pre_init` function, then the function this points to will be called before the RAM is initialized. */ PROVIDE(__pre_init = DefaultPreInit); @@ -22,21 +21,26 @@ PROVIDE(__pre_init = DefaultPreInit); /* # Sections */ SECTIONS { + /* boot loader */ + .bootloader : { + KEEP(*(.bootloader)) + } > bootloader_mem + /* ## PIC32MX configuration registers */ .configsfrs : { KEEP(*(.configsfrs)); } > configsfrs - /* Boot Sections */ + /* Reset Sections */ .reset : { KEEP(*(.reset)) KEEP(*(.reset.startup)) - } > kseg1_boot_mem - .bev_excpt _BEV_EXCPT_ADDR : + } > reset_mem + /* .bev_excpt _BEV_EXCPT_ADDR : { KEEP(*(.bev_handler)) - } > kseg1_boot_mem + } > kseg1_boot_mem */ /* Debug exception vector */ /* Space reserved for the debug executive */ /* .dbg_code _DBG_CODE_ADDR (NOLOAD) : @@ -45,11 +49,10 @@ SECTIONS } > debug_exec_mem */ /* Exception handlers */ - .app_excpt : + .app_excpt _ebase_address + 0x180: { - . = _GEN_EXCPT_ADDR; KEEP(*(.gen_handler)) - } > exception_mem = 0xffffffff + } > exception_mem .vector_0 _ebase_address + 0x200 + ((_vector_spacing << 5) * 0) : { @@ -376,7 +379,7 @@ SECTIONS .text : { *(.text .text.*); - } > kseg0_program_mem + } > program_mem /* ### .rodata */ .rodata : ALIGN(4) @@ -387,7 +390,7 @@ SECTIONS This is required by LLD to ensure the LMA of the following .data section will have the correct alignment. */ . = ALIGN(4); - } > kseg0_program_mem + } > program_mem /* ## Sections in RAM */ /* ### .data */ @@ -396,7 +399,7 @@ SECTIONS *(.data .data.*); . = ALIGN(4); /* 4-byte align the end (VMA) of this section */ - } > kseg1_data_mem AT > kseg0_program_mem + } > data_mem AT > program_mem /* VMA of .data */ __sdata = ADDR(.data); @@ -411,7 +414,7 @@ SECTIONS *(.bss .bss.*); . = ALIGN(4); /* 4-byte align the end (VMA) of this section */ - } > kseg1_data_mem + } > data_mem __sbss = ADDR(.bss); __ebss = ADDR(.bss) + SIZEOF(.bss); diff --git a/mips-mcu-alloc/Cargo.toml b/mips-mcu-alloc/Cargo.toml index d805751..5c04a29 100644 --- a/mips-mcu-alloc/Cargo.toml +++ b/mips-mcu-alloc/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "mips-mcu-alloc" description = "A heap allocator for MIPS based microcontrollers" -version = "0.5.0" +version = "0.6.0" authors = ["Stephan "] repository = "https://github.com/kiffie/pic32-rs/tree/master/mips-mcu-alloc" license = "MIT OR Apache-2.0" @@ -12,8 +12,9 @@ readme = "README.md" include = ["README.md", "/src", "LICENSE"] [dependencies] -mips-mcu = "0.2.0" +mips-mcu = "0.3.0" mips-rt = "0.3.0" +critical-section = "1.0.0" [dependencies.linked_list_allocator] default-features = false diff --git a/mips-mcu-alloc/src/lib.rs b/mips-mcu-alloc/src/lib.rs index 2988872..a1c9327 100644 --- a/mips-mcu-alloc/src/lib.rs +++ b/mips-mcu-alloc/src/lib.rs @@ -46,8 +46,8 @@ use core::arch::asm; use core::cell::RefCell; use core::ptr::{self, NonNull}; +use critical_section::{self, Mutex}; use linked_list_allocator::Heap; -use mips_mcu::interrupt::Mutex; use mips_rt::heap_start; /// Heap extension is performed stepwise. This constant defines the size of one extension step. @@ -71,10 +71,10 @@ impl MipsMcuHeap { /// Initialize heap with heap start location from linker and a defined initial size pub fn init(&self) { let bottom = heap_start() as *mut u8; - mips_mcu::interrupt::free(|cs| { + critical_section::with(|cs| { unsafe { self.heap - .borrow(*cs) + .borrow(cs) .borrow_mut() .init(bottom, EXTEND_INCREMENT) }; @@ -83,22 +83,22 @@ impl MipsMcuHeap { /// Returns an estimate of the amount of bytes in use. pub fn used(&self) -> usize { - mips_mcu::interrupt::free(|cs| self.heap.borrow(*cs).borrow_mut().used()) + critical_section::with(|cs| self.heap.borrow(cs).borrow_mut().used()) } /// Returns an estimate of the amount of bytes available. pub fn free(&self) -> usize { - mips_mcu::interrupt::free(|cs| self.heap.borrow(*cs).borrow_mut().free()) + critical_section::with(|cs| self.heap.borrow(cs).borrow_mut().free()) } /// Returns the start (bottom) of the heap pub fn bottom(&self) -> *mut u8 { - mips_mcu::interrupt::free(|cs| self.heap.borrow(*cs).borrow_mut().bottom()) + critical_section::with(|cs| self.heap.borrow(cs).borrow_mut().bottom()) } /// Returns the end (top) of the heap pub fn top(&self) -> *mut u8 { - mips_mcu::interrupt::free(|cs| self.heap.borrow(*cs).borrow_mut().top()) + critical_section::with(|cs| self.heap.borrow(cs).borrow_mut().top()) } } @@ -106,22 +106,19 @@ unsafe impl GlobalAlloc for MipsMcuHeap { unsafe fn alloc(&self, layout: Layout) -> *mut u8 { // try to allocate and successively extend by EXTEND_INCREMENT until memory is exhausted loop { - if let Ok(p) = mips_mcu::interrupt::free(|cs| { - self.heap - .borrow(*cs) - .borrow_mut() - .allocate_first_fit(layout) + if let Ok(p) = critical_section::with(|cs| { + self.heap.borrow(cs).borrow_mut().allocate_first_fit(layout) }) { break p.as_ptr(); } else { // this must be a u8 pointer let new_top: *mut u8 = - mips_mcu::interrupt::free(|cs| self.heap.borrow(*cs).borrow_mut().top()) + critical_section::with(|cs| self.heap.borrow(cs).borrow_mut().top()) .add(EXTEND_INCREMENT); // avoid collision with stack if new_top < stack_pointer() { - mips_mcu::interrupt::free(|cs| { - self.heap.borrow(*cs).borrow_mut().extend(EXTEND_INCREMENT) + critical_section::with(|cs| { + self.heap.borrow(cs).borrow_mut().extend(EXTEND_INCREMENT) }); } else { break ptr::null_mut(); @@ -131,9 +128,9 @@ unsafe impl GlobalAlloc for MipsMcuHeap { } unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { - mips_mcu::interrupt::free(|cs| { + critical_section::with(|cs| { self.heap - .borrow(*cs) + .borrow(cs) .borrow_mut() .deallocate(NonNull::new_unchecked(ptr), layout) }); diff --git a/mips-mcu/Cargo.toml b/mips-mcu/Cargo.toml index 2aeb4be..fd3eebb 100644 --- a/mips-mcu/Cargo.toml +++ b/mips-mcu/Cargo.toml @@ -3,11 +3,14 @@ name = "mips-mcu" description = "Low level access to MIPS MCU cores" categories = ["embedded", "hardware-support", "no-std"] keywords = ["mips", "register", "peripheral"] -version = "0.2.0" +version = "0.3.0" authors = ["Stephan "] repository = "https://github.com/kiffie/pic32-rs" license = "MIT OR Apache-2.0" -edition = "2018" +edition = "2021" [dependencies] -bare-metal = "1.0.0" +critical-section = { version = "1.0.0", optional = true } + +[features] +critical-section-single-core = ["critical-section/restore-state-u32"] diff --git a/mips-mcu/src/critical_section.rs b/mips-mcu/src/critical_section.rs new file mode 100644 index 0000000..68895d3 --- /dev/null +++ b/mips-mcu/src/critical_section.rs @@ -0,0 +1,19 @@ +//! Simple critical section implementation based on globally disabling +//! the interrupts + +use critical_section::{set_impl, Impl, RawRestoreState}; + +use crate::interrupt; + +struct SingleCoreCriticalSection; +set_impl!(SingleCoreCriticalSection); + +unsafe impl Impl for SingleCoreCriticalSection { + unsafe fn acquire() -> RawRestoreState { + interrupt::disable() + } + + unsafe fn release(previous_status: RawRestoreState) { + interrupt::restore(previous_status) + } +} diff --git a/mips-mcu/src/interrupt.rs b/mips-mcu/src/interrupt.rs index f98fbd1..5974233 100644 --- a/mips-mcu/src/interrupt.rs +++ b/mips-mcu/src/interrupt.rs @@ -2,35 +2,33 @@ // This is based on Work (c) by Jorge Aparicio, see // https://github.com/rust-embedded/cortex-m -// use core::sync::atomic::{self, Ordering}; - -pub use bare_metal::{CriticalSection, Mutex}; - type IrqSave = u32; /// Enable multi-vectored interrupts #[inline] -pub unsafe fn enable_mv_irq() { +pub fn enable_mv_irq() { extern "C" { fn mips_enable_mv_irq(); } - mips_enable_mv_irq(); + unsafe { + mips_enable_mv_irq(); + } } /// Disables all interrupts and return previous status #[inline] -pub unsafe fn disable() -> IrqSave { +pub fn disable() -> IrqSave { extern "C" { fn mips_di() -> u32; } - mips_di() + unsafe { mips_di() } } /// Enables all the interrupts and return previous status /// /// # Safety /// -/// - Do not call this function inside an `interrupt::free` critical section +/// Do not call this function inside a critical section #[inline] pub unsafe fn enable() -> IrqSave { extern "C" { @@ -39,27 +37,14 @@ pub unsafe fn enable() -> IrqSave { mips_ei() } +/// Restore previously saved IRQ enablement state +/// +/// # Safety +/// +/// Do not call this function inside a critical section pub unsafe fn restore(previous_status: IrqSave) { extern "C" { fn mips_restore_irq(previous_status: u32); } mips_restore_irq(previous_status) } - -/// Execute closure `f` in an interrupt-free context. -/// -/// This as also known as a "critical section". -pub fn free(f: F) -> R -where - F: FnOnce(&CriticalSection) -> R, -{ - let irq_save = unsafe { disable() }; - - let r = f(unsafe { &CriticalSection::new() }); - - // If the interrupts were active before our `disable` call, then re-enable - // them. Otherwise, keep them disabled - unsafe { restore(irq_save) }; - - r -} diff --git a/mips-mcu/src/lib.rs b/mips-mcu/src/lib.rs index 2bb723a..e8f1aef 100644 --- a/mips-mcu/src/lib.rs +++ b/mips-mcu/src/lib.rs @@ -11,6 +11,9 @@ pub mod core_timer; pub mod fmt; pub mod interrupt; +#[cfg(feature = "critical-section-single-core")] +pub mod critical_section; + /// Physical address #[derive(Clone, Copy, Debug, Default)] pub struct PhysicalAddress { diff --git a/mips-rt/Cargo.toml b/mips-rt/Cargo.toml index fbd5a4a..766044f 100644 --- a/mips-rt/Cargo.toml +++ b/mips-rt/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "mips-rt" -version = "0.3.0" +version = "0.3.1" authors = ["Stephan usize { - if virt >= 0x80000000usize { - virt & 0x1fff_ffff - } else { - virt + 0x4000_0000 - } -} - -/// Calculate a physical address for a raw pointer -pub fn virt_to_phys(ptr: *mut T) -> PhysicalAddress { - let virt: usize = ptr as usize; - PhysicalAddress { - addr: virt_to_phys_usize(virt), - } -} diff --git a/mips-rt/src/interrupt.rs b/mips-rt/src/interrupt.rs deleted file mode 100644 index 55f2b29..0000000 --- a/mips-rt/src/interrupt.rs +++ /dev/null @@ -1,65 +0,0 @@ -//! Interrupts -// This is based on Work (c) by Jorge Aparicio, see -// https://github.com/rust-embedded/cortex-m - -// use core::sync::atomic::{self, Ordering}; - -pub use bare_metal::{CriticalSection, Mutex, Nr}; - -type IrqSave = u32; - -/// Enable multi-vectored interrupts -#[inline] -pub unsafe fn enable_mv_irq() { - extern "C" { - fn mips_enable_mv_irq(); - } - mips_enable_mv_irq(); -} - -/// Disables all interrupts and return previous status -#[inline] -pub unsafe fn disable() -> IrqSave { - extern "C" { - fn mips_di() -> u32; - } - mips_di() -} - -/// Enables all the interrupts and return previous status -/// -/// # Safety -/// -/// - Do not call this function inside an `interrupt::free` critical section -#[inline] -pub unsafe fn enable() -> IrqSave { - extern "C" { - fn mips_ei() -> u32; - } - mips_ei() -} - -pub unsafe fn restore(previous_status: IrqSave) { - extern "C" { - fn mips_restore_irq(previous_status: u32); - } - mips_restore_irq(previous_status) -} - -/// Execute closure `f` in an interrupt-free context. -/// -/// This as also known as a "critical section". -pub fn free(f: F) -> R -where - F: FnOnce(&CriticalSection) -> R, -{ - let irq_save = unsafe { disable() }; - - let r = f(unsafe { &CriticalSection::new() }); - - // If the interrupts were active before our `disable` call, then re-enable - // them. Otherwise, keep them disabled - unsafe { restore(irq_save) }; - - r -} diff --git a/pic32-hal/Cargo.toml b/pic32-hal/Cargo.toml index ec4bf53..9482ac8 100644 --- a/pic32-hal/Cargo.toml +++ b/pic32-hal/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "pic32-hal" -version = "0.8.0" +version = "0.9.0" authors = ["Stephan "] -edition = "2018" +edition = "2021" description = "Hardware Abstraction Layer (HAL) for PIC32 microcontrollers" documentation = "https://docs.rs/pic32-hal" repository = "https://github.com/kiffie/pic32-rs/tree/master/pic32-hal" @@ -19,14 +19,15 @@ device-selected = [] [dependencies] nb = "1.0.0" embedded-hal = { version = "0.2.7", features = ["unproven"] } -mips-mcu = "0.2.0" +mips-mcu = "0.3.0" mips-rt = "0.3.0" +critical-section = "1.0.0" usb-device = { version = "0.2.9", optional = true } enumflags2 = "0.7.5" [dependencies.pic32mx2xx] -version = "0.6.0" -features = ["rt"] +version = "0.7.0" +features = ["rt", "critical-section"] [package.metadata.docs.rs] features = ["pic32mx2xxfxxxb", "usb-device"] diff --git a/pic32-hal/src/coretimer.rs b/pic32-hal/src/coretimer.rs index dcc34bf..6dfa112 100644 --- a/pic32-hal/src/coretimer.rs +++ b/pic32-hal/src/coretimer.rs @@ -7,10 +7,9 @@ use crate::hal::blocking::delay::{DelayMs, DelayUs}; use crate::pac::INT; // interrupt controller use crate::time::Hertz; +use critical_section::Mutex; pub use mips_mcu::core_timer::read_count; use mips_mcu::core_timer::{read_compare, write_compare}; -use mips_mcu::interrupt; -use mips_mcu::interrupt::Mutex; use core::cell::Cell; @@ -101,8 +100,8 @@ static TIMER: Mutex>> = Mutex::new(Cell::new(Some(Timer {}))) impl Timer { /// Get the `Timer` singleton. Panics if the singleton is not available. pub fn take() -> Self { - let timeropt = interrupt::free(|cs| { - let cell = TIMER.borrow(*cs); + let timeropt = critical_section::with(|cs| { + let cell = TIMER.borrow(cs); cell.take() }); timeropt.unwrap() @@ -110,8 +109,8 @@ impl Timer { /// Return the `Timer` singleton. pub fn free(self) { - interrupt::free(|cs| { - let cell = TIMER.borrow(*cs); + critical_section::with(|cs| { + let cell = TIMER.borrow(cs); cell.replace(Some(self)); }); } diff --git a/pic32-hal/src/gpio.rs b/pic32-hal/src/gpio.rs index 665d1f6..8e36ea8 100644 --- a/pic32-hal/src/gpio.rs +++ b/pic32-hal/src/gpio.rs @@ -259,10 +259,7 @@ macro_rules! port { } // configuration for general purpose (non-USB) devices -#[cfg(any( - feature = "pic32mx1xxfxxxb", - feature = "pic32mx2xxfxxxb" -))] +#[cfg(any(feature = "pic32mx1xxfxxxb", feature = "pic32mx2xxfxxxb"))] port!(PORTA, porta, [ RA0: (ra0, 0, Input, true), RA1: (ra1, 1, Input, true), diff --git a/pic32-hal/src/int.rs b/pic32-hal/src/int.rs index 054e88e..7afc086 100644 --- a/pic32-hal/src/int.rs +++ b/pic32-hal/src/int.rs @@ -3,7 +3,7 @@ //! Enable/disable and set priorities of interrupts in Multi-vectored mode use crate::pac::INT; -use crate::pac_crate::{RegisterSpec, Reg}; +use crate::pac_crate::{Reg, RegisterSpec}; use core::convert::TryFrom; use core::marker::PhantomData; use core::ptr::{read_volatile, write_volatile}; diff --git a/pic32-hal/src/lib.rs b/pic32-hal/src/lib.rs index 86ca995..1f3cf68 100644 --- a/pic32-hal/src/lib.rs +++ b/pic32-hal/src/lib.rs @@ -32,17 +32,17 @@ pub use pic32mx4xxfxxxh as pac; use embedded_hal as hal; -pub mod time; -pub mod int; +pub mod adc; +pub mod clock; +pub mod coretimer; +pub mod dma; pub mod gpio; +pub mod i2c; +pub mod int; pub mod pps; -pub mod uart; pub mod spi; -pub mod i2c; -pub mod coretimer; -pub mod clock; -pub mod dma; -pub mod adc; +pub mod time; +pub mod uart; #[cfg(any( feature = "pic32mx2xxfxxxb", diff --git a/pic32-hal/src/uart.rs b/pic32-hal/src/uart.rs index 488ec58..e8449d8 100644 --- a/pic32-hal/src/uart.rs +++ b/pic32-hal/src/uart.rs @@ -4,8 +4,8 @@ use core::fmt; use core::marker::PhantomData; use crate::clock::Osc; -use crate::pps::{input, output, MappedPin, IsConnected}; use crate::pac::{UART1, UART2}; +use crate::pps::{input, output, IsConnected, MappedPin}; use embedded_hal::prelude::*; use nb::block;