aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.cargo/config.toml13
-rw-r--r--.gitignore1
-rw-r--r--Cargo.lock313
-rw-r--r--Cargo.toml21
-rw-r--r--README.org6
-rw-r--r--gdbinit8
-rw-r--r--memory.x15
l---------src-riscv/.#main.rs1
-rw-r--r--src-riscv/blink.rs (renamed from src/blink.rs)13
-rw-r--r--src-riscv/boot.S (renamed from src/boot.S)0
-rw-r--r--src-riscv/led.rs42
-rw-r--r--src-riscv/log.rs36
-rwxr-xr-xsrc-riscv/main.rs215
-rwxr-xr-xsrc-riscv/usb.rs (renamed from src/usb.rs)0
-rw-r--r--src/led.rs24
-rw-r--r--src/log.rs20
-rwxr-xr-xsrc/main.rs285
17 files changed, 654 insertions, 359 deletions
diff --git a/.cargo/config.toml b/.cargo/config.toml
index d0fb511..033305c 100644
--- a/.cargo/config.toml
+++ b/.cargo/config.toml
@@ -1,15 +1,8 @@
-[alias]
-t = "test --target x86_64-unknown-linux-gnu"
-xtask = "run --package xtask --"
-
[build]
-target = "riscv32imac-unknown-none-elf"
+target = "thumbv7em-none-eabihf"
-[target.riscv32imac-unknown-none-elf]
-runner = "riscv32-elf-gdb -x gdbinit"
-#rustflags = ["-C", "link-arg=-Tdevice.lds", "-C", "link-arg=-nostdlib"]
+[target.thumbv7em-none-eabihf]
+runner = "arm-none-eabi-gdb -x gdbinit"
rustflags = [
- "-C", "link-arg=-Tmemory.x",
"-C", "link-arg=-Tlink.x",
]
-#linker = "riscv32-elf-ld"
diff --git a/.gitignore b/.gitignore
index ea8c4bf..3f92f04 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
/target
+/.gdb_history
diff --git a/Cargo.lock b/Cargo.lock
index 53b2efa..b17d189 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3,21 +3,12 @@
version = 3
[[package]]
-name = "aho-corasick"
-version = "0.7.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
-dependencies = [
- "memchr",
-]
-
-[[package]]
name = "bare-metal"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3"
dependencies = [
- "rustc_version 0.2.3",
+ "rustc_version",
]
[[package]]
@@ -27,202 +18,178 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8fe8f5a8a398345e52358e18ff07cc17a568fbca5c6f73873d3a62056309603"
[[package]]
-name = "bit_field"
-version = "0.10.1"
+name = "bitfield"
+version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dcb6dd1c2376d2e096796e234a70e17e94cc2d5d54ff8ce42b28cef1d0d359a4"
+checksum = "46afbd2983a5d5a7bd740ccb198caf5b82f45c40c09c0eed36052d91cb92e719"
[[package]]
-name = "cast"
-version = "0.2.7"
+name = "bitflags"
+version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c24dab4283a142afa2fdca129b80ad2c6284e073930f964c3a1293c225ee39a"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+
+[[package]]
+name = "bxcan"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4b13b4b2ea9ab2ba924063ebb86ad895cb79f4a79bf90f27949eb20c335b30f9"
dependencies = [
- "rustc_version 0.4.0",
+ "bitflags",
+ "nb 1.0.0",
+ "vcell",
]
[[package]]
-name = "embedded-dma"
-version = "0.1.2"
+name = "cortex-m"
+version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "46c8c02e4347a0267ca60813c952017f4c5948c232474c6010a381a337f1bda4"
+checksum = "70858629a458fdfd39f9675c4dc309411f2a3f83bede76988d81bf1a0ecee9e0"
dependencies = [
- "stable_deref_trait",
+ "bare-metal 0.2.5",
+ "bitfield",
+ "embedded-hal",
+ "volatile-register",
]
[[package]]
-name = "embedded-hal"
-version = "0.2.7"
+name = "cortex-m-rt"
+version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff"
+checksum = "3c433da385b720d5bb9f52362fa2782420798e68d40d67bfe4b0d992aba5dfe7"
dependencies = [
- "nb 0.1.3",
- "void",
+ "cortex-m-rt-macros",
]
[[package]]
-name = "gd32vf103-pac"
-version = "0.4.0"
+name = "cortex-m-rt-macros"
+version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5ffd430737a49edbd1c0241b58cabe79a7ac7ebe208f67dc838c1c981eb60e83"
+checksum = "f0f6f3e36f203cfedbc78b357fb28730aa2c6dc1ab060ee5c2405e843988d3c7"
dependencies = [
- "bare-metal 0.2.5",
- "riscv 0.6.0",
- "vcell",
+ "proc-macro2",
+ "quote",
+ "syn",
]
[[package]]
-name = "gd32vf103xx-hal"
+name = "cortex-m-semihosting"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1bdffb2f55a16c7916b5df9c02b1dab0dc1c8545237491821a7fd98c61378e4a"
+checksum = "c23234600452033cc77e4b761e740e02d2c4168e11dbf36ab14a0f58973592b0"
dependencies = [
- "cast",
- "embedded-dma",
- "embedded-hal",
- "gd32vf103-pac",
- "nb 0.1.3",
- "riscv 0.6.0",
- "vcell",
- "void",
+ "cortex-m",
]
[[package]]
-name = "lazy_static"
-version = "1.4.0"
+name = "embedded-dma"
+version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+checksum = "994f7e5b5cb23521c22304927195f236813053eb9c065dd2226a32ba64695446"
+dependencies = [
+ "stable_deref_trait",
+]
[[package]]
-name = "luchie"
-version = "0.1.0"
+name = "embedded-hal"
+version = "0.2.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff"
dependencies = [
- "embedded-hal",
- "gd32vf103-pac",
- "gd32vf103xx-hal",
- "nb 1.0.0",
- "riscv 0.8.0",
- "riscv-rt",
- "synopsys-usb-otg",
- "usb-device",
- "usbd-serial",
+ "nb 0.1.3",
+ "void",
]
[[package]]
-name = "memchr"
-version = "2.5.0"
+name = "fugit"
+version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
+checksum = "7ab17bb279def6720d058cb6c052249938e7f99260ab534879281a95367a87e5"
+dependencies = [
+ "gcd",
+]
[[package]]
-name = "nb"
+name = "fugit-timer"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f"
+checksum = "d9607bfc4c388f9d629704f56ede4a007546cad417b3bcd6fc7c87dc7edce04a"
dependencies = [
+ "fugit",
"nb 1.0.0",
]
[[package]]
-name = "nb"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "546c37ac5d9e56f55e73b677106873d9d9f5190605e41a856503623648488cae"
-
-[[package]]
-name = "proc-macro2"
-version = "1.0.43"
+name = "gcd"
+version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab"
+checksum = "f37978dab2ca789938a83b2f8bc1ef32db6633af9051a6cd409eff72cbaaa79a"
dependencies = [
- "unicode-ident",
+ "paste",
]
[[package]]
-name = "quote"
-version = "1.0.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
+name = "luchie"
+version = "0.1.0"
dependencies = [
- "proc-macro2",
+ "cortex-m",
+ "cortex-m-rt",
+ "embedded-hal",
+ "nb 1.0.0",
+ "panic-semihosting",
+ "stm32f1xx-hal",
+ "usb-device",
+ "usbd-serial",
+ "usbd-webusb",
]
[[package]]
-name = "r0"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bd7a31eed1591dcbc95d92ad7161908e72f4677f8fabf2a32ca49b4237cbf211"
-
-[[package]]
-name = "regex"
-version = "1.6.0"
+name = "nb"
+version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"
+checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f"
dependencies = [
- "aho-corasick",
- "memchr",
- "regex-syntax",
+ "nb 1.0.0",
]
[[package]]
-name = "regex-syntax"
-version = "0.6.27"
+name = "nb"
+version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
+checksum = "546c37ac5d9e56f55e73b677106873d9d9f5190605e41a856503623648488cae"
[[package]]
-name = "riscv"
+name = "panic-semihosting"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a2f0b705d428e9d0f78e2bb73093887ee58a83c9688de3faedbb4c0631c4618e"
+checksum = "ee8a3e1233d9073d76a870223512ce4eeea43c067a94a445c13bd6d792d7b1ab"
dependencies = [
- "bare-metal 0.2.5",
- "bit_field",
- "riscv-target",
+ "cortex-m",
+ "cortex-m-semihosting",
]
[[package]]
-name = "riscv"
-version = "0.8.0"
+name = "paste"
+version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5e2856a701069e2d262b264750d382407d272d5527f7a51d3777d1805b4e2d3c"
-dependencies = [
- "bare-metal 1.0.0",
- "bit_field",
- "embedded-hal",
-]
+checksum = "b1de2e551fb905ac83f73f7aedf2f0cb4a0da7e35efa24a202a936269f1f18e1"
[[package]]
-name = "riscv-rt"
-version = "0.9.0"
+name = "proc-macro2"
+version = "1.0.46"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "527ddfacbbfeed89256163c2655b0392c4aa76dd95c0189dc05044bf2c47c3f8"
+checksum = "94e2ef8dbfc347b10c094890f778ee2e36ca9bb4262e86dc99cd217e35f3470b"
dependencies = [
- "r0",
- "riscv 0.8.0",
- "riscv-rt-macros",
- "riscv-target",
+ "unicode-ident",
]
[[package]]
-name = "riscv-rt-macros"
-version = "0.2.0"
+name = "quote"
+version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f38509d7b17c2f604ceab3e5ff8ac97bb8cd2f544688c512be75c715edaf4daf"
+checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
dependencies = [
"proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "riscv-target"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "88aa938cda42a0cf62a20cfe8d139ff1af20c2e681212b5b34adb5a58333f222"
-dependencies = [
- "lazy_static",
- "regex",
]
[[package]]
@@ -231,16 +198,7 @@ version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
dependencies = [
- "semver 0.9.0",
-]
-
-[[package]]
-name = "rustc_version"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
-dependencies = [
- "semver 1.0.13",
+ "semver",
]
[[package]]
@@ -253,12 +211,6 @@ dependencies = [
]
[[package]]
-name = "semver"
-version = "1.0.13"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "93f6841e709003d68bb2deee8c343572bf446003ec20a583e76f7b15cebf3711"
-
-[[package]]
name = "semver-parser"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -271,33 +223,64 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]]
-name = "syn"
-version = "1.0.99"
+name = "stm32-usbd"
+version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13"
+checksum = "c6c94998f166d66b210a164648a0b7866428d8f1e0740bf8a4c5edd89d4750c1"
dependencies = [
- "proc-macro2",
- "quote",
- "unicode-ident",
+ "cortex-m",
+ "usb-device",
+ "vcell",
]
[[package]]
-name = "synopsys-usb-otg"
-version = "0.3.0"
+name = "stm32f1"
+version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5999b93d4d7e294fc26de39181dbe1428d61dd3b4046642ee0b3927ea2037c9b"
+checksum = "78d0d11d776bc6f165c68c67468826b33b3eabd04c3c319df5e8476dd580002d"
dependencies = [
- "embedded-hal",
- "riscv 0.6.0",
- "usb-device",
+ "bare-metal 1.0.0",
+ "cortex-m",
+ "cortex-m-rt",
"vcell",
]
[[package]]
+name = "stm32f1xx-hal"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1232c561785bdbc59a5ab2b28c5c9429cb9ee9b04687133e59d1a34a39426943"
+dependencies = [
+ "bitflags",
+ "bxcan",
+ "cortex-m",
+ "cortex-m-rt",
+ "embedded-dma",
+ "embedded-hal",
+ "fugit",
+ "fugit-timer",
+ "nb 1.0.0",
+ "stm32-usbd",
+ "stm32f1",
+ "void",
+]
+
+[[package]]
+name = "syn"
+version = "1.0.102"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3fcd952facd492f9be3ef0d0b7032a6e442ee9b361d4acc2b1d0c4aaa5f613a1"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
name = "unicode-ident"
-version = "1.0.3"
+version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf"
+checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
[[package]]
name = "usb-device"
@@ -317,6 +300,15 @@ dependencies = [
]
[[package]]
+name = "usbd-webusb"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed33ecaa7a26365f13059e753bfa23f0a4a557565499f46d255c51e737464bd8"
+dependencies = [
+ "usb-device",
+]
+
+[[package]]
name = "vcell"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -327,3 +319,12 @@ name = "void"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
+
+[[package]]
+name = "volatile-register"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ee8f19f9d74293faf70901bc20ad067dc1ad390d2cbf1e3f75f721ffee908b6"
+dependencies = [
+ "vcell",
+]
diff --git a/Cargo.toml b/Cargo.toml
index ce3f550..e9238a4 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -17,20 +17,23 @@ lto = true
codegen-units = 1
[dependencies]
-gd32vf103-pac = "0.4.0"
-gd32vf103xx-hal = "0.5.0"
-riscv = "0.8.0"
-riscv-rt = "0.9.0"
+cortex-m = "0.7.6"
+cortex-m-rt = "0.7.1"
nb = "1.0.0"
-embedded-hal = "0.2.7"
+panic-semihosting = "0.6.0"
usb-device = "0.2.9"
usbd-serial = "0.1.1"
+usbd-webusb = "1.0.2"
+embedded-hal = "0.2.7"
-[dependencies.synopsys-usb-otg]
-version = "0.3.0"
-features = ["riscv", "fs"]
+[dependencies.stm32f1xx-hal]
+version = "0.9"
+features = ["stm32f103", "stm32-usbd", "rt"]
[[bin]]
name = "luchie"
test = false
-bench = false \ No newline at end of file
+bench = false
+
+[patch.crates-io]
+#usb-device = { path = "../usb-device" }
diff --git a/README.org b/README.org
index b9da1b8..537960b 100644
--- a/README.org
+++ b/README.org
@@ -1,3 +1,9 @@
+* start rust container
+#+begin_src shell
+ doas podman run --rm -v /home/bjc/src:/home/bjc/src -it --name luchie -h luchie luchie
+#+end_src
+
+
looks like the start board is a gd32vf103cbt from the tiny print silk-screened on the chip. [[https://www.tme.com/us/en-us/details/gd32vf103c-start/development-kits-others/gigadevice/][TME]] says it's a gd32vf103d6t6 — but [[https://www.gigadevice.com/products/microcontrollers/gd32-development-tools/gd32-mcu-starter-kits/][gigadevice]] says gd32vf103cbt6
which means it has 128k flash and 32k sram and 37(!) gpio pins
diff --git a/gdbinit b/gdbinit
index 695822f..fe53799 100644
--- a/gdbinit
+++ b/gdbinit
@@ -2,10 +2,12 @@ define hook-quit
set confirm off
end
-# print demangled symbols by default
+set history save on
+set confirm off
set print asm-demangle on
-# OpenOCD
set remote hardware-breakpoint-limit 4
set remote hardware-watchpoint-limit 2
-target extended-remote psyduck:3333
+target extended-remote psyduck:3334
+
+monitor arm semihosting enable
diff --git a/memory.x b/memory.x
index 6d8ae75..56c58de 100644
--- a/memory.x
+++ b/memory.x
@@ -1,13 +1,10 @@
+/* Linker script for the STM32F303VCT6 */
MEMORY
{
- /* 0x0000_0000 is an alias for 0x08000_0000 */
- FLASH(rwx) : ORIGIN = 0x00000000, LENGTH = 128K
- RAM(rw) : ORIGIN = 0x20000000, LENGTH = 32K
+ CCRAM : ORIGIN = 0x10000000, LENGTH = 8K
+ FLASH : ORIGIN = 0x08000000, LENGTH = 256K
+ RAM : ORIGIN = 0x20000000, LENGTH = 40K
}
-REGION_ALIAS("REGION_TEXT", FLASH);
-REGION_ALIAS("REGION_RODATA", FLASH);
-REGION_ALIAS("REGION_DATA", RAM);
-REGION_ALIAS("REGION_BSS", RAM);
-REGION_ALIAS("REGION_HEAP", RAM);
-REGION_ALIAS("REGION_STACK", RAM);
+/* _stack_start = ORIGIN(CCRAM) + LENGTH(CCRAM); */
+_stack_start = ORIGIN(RAM) + LENGTH(RAM);
diff --git a/src-riscv/.#main.rs b/src-riscv/.#main.rs
new file mode 120000
index 0000000..988fc15
--- /dev/null
+++ b/src-riscv/.#main.rs
@@ -0,0 +1 @@
+bjc@ditto.691749627316654132 \ No newline at end of file
diff --git a/src/blink.rs b/src-riscv/blink.rs
index ba3d6ca..967cde6 100644
--- a/src/blink.rs
+++ b/src-riscv/blink.rs
@@ -1,7 +1,10 @@
use core::convert::Infallible;
-use gd32vf103xx_hal::{
- eclic::{self, EclicExt},
+// use gd32vf103xx_hal as hal;
+use stm32f30x_hal as hal;
+
+use hal::{
+ //eclic::{self, EclicExt},
pac::{self, Interrupt},
prelude::*,
time::Hertz,
@@ -22,9 +25,9 @@ static mut TIMER_FIRED: bool = false;
impl Task {
pub fn new(mut timer: Timer<pac::TIMER6>, frequency: Hertz, led: LED) -> Self {
- pac::ECLIC::setup(Interrupt::TIMER6, eclic::TriggerType::RisingEdge, eclic::Level::L0, eclic::Priority::P3);
- unsafe { pac::ECLIC::unmask(Interrupt::TIMER6); }
- assert!(pac::ECLIC::is_enabled(Interrupt::TIMER6));
+ // pac::ECLIC::setup(Interrupt::TIMER6, eclic::TriggerType::RisingEdge, eclic::Level::L0, eclic::Priority::P3);
+ // unsafe { pac::ECLIC::unmask(Interrupt::TIMER6); }
+ // assert!(pac::ECLIC::is_enabled(Interrupt::TIMER6));
timer.listen(Event::Update);
Self { timer, frequency, led }
diff --git a/src/boot.S b/src-riscv/boot.S
index d31e5fe..d31e5fe 100644
--- a/src/boot.S
+++ b/src-riscv/boot.S
diff --git a/src-riscv/led.rs b/src-riscv/led.rs
new file mode 100644
index 0000000..536121b
--- /dev/null
+++ b/src-riscv/led.rs
@@ -0,0 +1,42 @@
+use gd32vf103xx_hal::{
+ gpio::{Floating, Input, Output, PushPull, Pxx, State, gpioa::PA7},
+};
+use embedded_hal::digital::v2::OutputPin;
+
+pub struct LED {
+ pin: Pxx<Output<PushPull>>,
+ state: State,
+}
+
+impl LED {
+ pub fn new(pin: PA7<Input<Floating>>) -> Self {
+ let mut p = pin.into_push_pull_output().downgrade();
+ p.set_low().ok();
+ Self { pin: p, state: State::Low }
+ }
+
+ pub fn is_on(&self) -> bool {
+ match self.state {
+ State::High => true,
+ State::Low => false,
+ }
+ }
+
+ pub fn on(&mut self) {
+ self.state = State::High;
+ self.pin.set_high().ok();
+ }
+
+ pub fn off(&mut self) {
+ self.state = State::Low;
+ self.pin.set_low().ok();
+ }
+
+ pub fn toggle(&mut self) {
+ if self.is_on() {
+ self.off();
+ } else {
+ self.on();
+ }
+ }
+}
diff --git a/src-riscv/log.rs b/src-riscv/log.rs
new file mode 100644
index 0000000..ddb6792
--- /dev/null
+++ b/src-riscv/log.rs
@@ -0,0 +1,36 @@
+use core::fmt::{write, Arguments};
+
+use gd32vf103xx_hal::{
+ serial::Tx,
+ pac::USART1,
+};
+use riscv::interrupt::{self, Mutex};
+
+#[macro_export]
+macro_rules! log {
+ ($($args:tt)+) => {
+ $crate::log::log_args(core::format_args!($($args)+))
+ }
+}
+
+#[macro_export]
+macro_rules! logln {
+ () => ({ kprint!("\r\n") });
+ ($fmt: literal $(, $($arg: tt)+)?) => {
+ log!(concat!($fmt, "\n") $(, $($arg)+)?)
+ }
+}
+
+static mut TX: Mutex<Option<Tx<USART1>>> = Mutex::new(None);
+
+pub fn init(tx: Tx<USART1>) {
+ interrupt::free(|_cs| {
+ unsafe { TX.get_mut().insert(tx) };
+ });
+}
+
+pub fn log_args(args: Arguments) {
+ interrupt::free(|_cs| {
+ unsafe { TX.get_mut().as_mut().map(|tx| write(tx, args)) };
+ });
+}
diff --git a/src-riscv/main.rs b/src-riscv/main.rs
new file mode 100755
index 0000000..68fa8da
--- /dev/null
+++ b/src-riscv/main.rs
@@ -0,0 +1,215 @@
+#![no_std]
+#![no_main]
+
+mod blink;
+mod led;
+mod log;
+mod usb;
+
+// use gd32vf103xx_hal as hal;
+use stm32f30x_hal as hal;
+
+use hal::{
+ afio::AfioExt,
+ eclic::{self, EclicExt},
+ gpio::GpioExt,
+ pac::{self, Peripherals},
+ rcu::RcuExt,
+ serial::Serial,
+ time::{Hertz, MegaHertz},
+ timer::Timer,
+};
+use riscv::{
+ asm::wfi,
+ interrupt,
+};
+use riscv_rt::entry;
+use usb_device::prelude::*;
+
+use led::LED;
+use usb::{USB, UsbBus};
+
+static mut EP_MEMORY: [u32; 1024] = [0; 1024];
+
+#[entry]
+fn main(_hartid: usize) -> ! {
+ let p = Peripherals::take().expect("couldn't take peripherals");
+
+ pac::ECLIC::reset();
+ pac::ECLIC::set_threshold_level(eclic::Level::L0);
+ pac::ECLIC::set_level_priority_bits(eclic::LevelPriorityBits::L3P1);
+
+ let mut rcu = p.RCU
+ .configure()
+ .ext_hf_clock(MegaHertz(8))
+ .sysclk(MegaHertz(96))
+ .freeze();
+ let mut afio = p.AFIO.constrain(&mut rcu);
+ let gpioa = p.GPIOA.split(&mut rcu);
+
+ // TODO: figure out how to use the usb serial on the start board.
+ //
+ // this version has to be wired up physically.
+ let serial = Serial::new(
+ p.USART1,
+ (gpioa.pa2, gpioa.pa3),
+ Default::default(),
+ &mut afio,
+ &mut rcu,
+ );
+ let (tx, _rx) = serial.split();
+ log::init(tx);
+ logln!("luchie starting");
+
+ let timer = Timer::<pac::TIMER6>::timer6(p.TIMER6, Hertz(5), &mut rcu);
+ let led = LED::new(gpioa.pa7);
+ let mut blink = blink::Task::new(timer, Hertz(5), led);
+
+ let usb = USB {
+ usb_global: p.USBFS_GLOBAL,
+ usb_device: p.USBFS_DEVICE,
+ usb_pwrclk: p.USBFS_PWRCLK,
+ pin_dm: gpioa.pa11,
+ pin_dp: gpioa.pa12,
+ hclk: rcu.clocks.hclk()
+ };
+ logln!("hclk: {:?}", rcu.clocks.hclk().0);
+
+ let usb_bus = UsbBus::new(usb, unsafe { &mut EP_MEMORY });
+
+ let mut usb_dev = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(0x16c0, 0x27dd))
+ .manufacturer("Fake company")
+ .product("Enumeration test")
+ .serial_number("TEST")
+ .device_class(0)
+ .build();
+
+ //let mut serial = SerialPort::new(&bus_alloc);
+
+ unsafe { interrupt::enable() };
+
+ loop {
+ let mut can_sleep = true;
+
+ if let Ok(_) = blink.poll() {
+ can_sleep = false;
+ }
+ if usb_dev.poll(&mut []) {
+ logln!("usb");
+ can_sleep = false;
+ }
+
+ if can_sleep && false {
+ log!("!");
+ unsafe { wfi() };
+ }
+ }
+}
+#[export_name="ExceptionHandler"]
+fn exception_handler(_frame: &riscv_rt::TrapFrame) -> ! {
+ spin();
+}
+
+#[export_name="DefaultHandler"]
+fn default_handler() -> ! {
+ spin();
+}
+
+#[export_name="MachineTimer"]
+fn machine_timer() {
+ spin();
+}
+
+#[panic_handler]
+fn panic(info: &core::panic::PanicInfo) -> ! {
+ interrupt::free(|_cs| {
+ log!("!!! panic ");
+ if let Some(loc) = info.location() {
+ log!("in {}:{} ", loc.file(), loc.line());
+ }
+ if let Some(msg) = info.payload().downcast_ref::<&str>() {
+ log!("⇒ {} ", msg);
+ }
+ logln!("!!!");
+ });
+ spin();
+}
+
+fn spin() -> ! {
+ loop { unsafe { wfi() } };
+}
+
+/*
+#![no_std]
+#![no_main]
+
+mod usb;
+
+use riscv::asm::wfi;
+use riscv_rt::entry;
+use gd32vf103xx_hal::prelude::*;
+use gd32vf103xx_hal::pac;
+
+use usb::{USB, UsbBus};
+use usb_device::prelude::*;
+use usbd_serial::SerialPort;
+
+static mut EP_MEMORY: [u32; 1024] = [0; 1024];
+
+#[entry]
+fn main() -> ! {
+ let dp = pac::Peripherals::take().unwrap();
+
+ // Configure clocks
+ let mut rcu = dp.RCU.configure()
+ .ext_hf_clock(8.mhz())
+ .sysclk(96.mhz())
+ .freeze();
+
+ assert!(rcu.clocks.usbclk_valid());
+
+ let gpioa = dp.GPIOA.split(&mut rcu);
+ let usb = USB {
+ usb_global: dp.USBFS_GLOBAL,
+ usb_device: dp.USBFS_DEVICE,
+ usb_pwrclk: dp.USBFS_PWRCLK,
+ pin_dm: gpioa.pa11,
+ pin_dp: gpioa.pa12,
+ hclk: rcu.clocks.hclk()
+ };
+
+ let usb_bus = UsbBus::new(usb, unsafe { &mut EP_MEMORY });
+
+ let mut serial = SerialPort::new(&usb_bus);
+ let mut usb_dev = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(0x16c0, 0x27dd))
+ .manufacturer("Fake company")
+ .product("Enumeration test")
+ .serial_number("TEST")
+ .device_class(0)
+ .build();
+
+ loop {
+ if usb_dev.poll(&mut [&mut serial]) {
+ }
+ }
+}
+
+#[panic_handler]
+fn panic(info: &core::panic::PanicInfo) -> ! {
+// interrupt::free(|_cs| {
+// log!("!!! panic ");
+ if let Some(loc) = info.location() {
+// log!("in {}:{} ", loc.file(), loc.line());
+ }
+ if let Some(msg) = info.payload().downcast_ref::<&str>() {
+// log!("⇒ {} ", msg);
+ }
+// logln!("!!!");
+// });
+ spin();
+}
+
+fn spin() -> ! {
+ loop { unsafe { wfi() } };
+}
+*/
diff --git a/src/usb.rs b/src-riscv/usb.rs
index 1ec36af..1ec36af 100755
--- a/src/usb.rs
+++ b/src-riscv/usb.rs
diff --git a/src/led.rs b/src/led.rs
index 536121b..788ec81 100644
--- a/src/led.rs
+++ b/src/led.rs
@@ -1,17 +1,23 @@
-use gd32vf103xx_hal::{
- gpio::{Floating, Input, Output, PushPull, Pxx, State, gpioa::PA7},
+use stm32f1xx_hal::{
+ gpio::{Cr, CRL, Floating, Input, Output, PushPull, gpiob::PB2},
};
-use embedded_hal::digital::v2::OutputPin;
+
+enum State {
+ Low,
+ High,
+}
+
+type LEDPin<MODE> = PB2<MODE>;
pub struct LED {
- pin: Pxx<Output<PushPull>>,
+ pin: LEDPin<Output<PushPull>>,
state: State,
}
impl LED {
- pub fn new(pin: PA7<Input<Floating>>) -> Self {
- let mut p = pin.into_push_pull_output().downgrade();
- p.set_low().ok();
+ pub fn new(pin: LEDPin<Input<Floating>>, cr: &mut Cr<CRL, 'B'>) -> Self {
+ let mut p = pin.into_push_pull_output(cr);
+ p.set_low();
Self { pin: p, state: State::Low }
}
@@ -24,12 +30,12 @@ impl LED {
pub fn on(&mut self) {
self.state = State::High;
- self.pin.set_high().ok();
+ self.pin.set_high();
}
pub fn off(&mut self) {
self.state = State::Low;
- self.pin.set_low().ok();
+ self.pin.set_low();
}
pub fn toggle(&mut self) {
diff --git a/src/log.rs b/src/log.rs
index ddb6792..7eb15e4 100644
--- a/src/log.rs
+++ b/src/log.rs
@@ -1,10 +1,14 @@
-use core::fmt::{write, Arguments};
+use core::{
+ cell::RefCell,
+ fmt::{write, Arguments},
+};
-use gd32vf103xx_hal::{
+use stm32f1xx_hal::{
serial::Tx,
pac::USART1,
};
-use riscv::interrupt::{self, Mutex};
+
+use cortex_m::interrupt::{self, Mutex};
#[macro_export]
macro_rules! log {
@@ -21,16 +25,16 @@ macro_rules! logln {
}
}
-static mut TX: Mutex<Option<Tx<USART1>>> = Mutex::new(None);
+static TX: Mutex<RefCell<Option<Tx<USART1>>>> = Mutex::new(RefCell::new(None));
pub fn init(tx: Tx<USART1>) {
- interrupt::free(|_cs| {
- unsafe { TX.get_mut().insert(tx) };
+ interrupt::free(|cs| {
+ TX.borrow(cs).replace(Some(tx));
});
}
pub fn log_args(args: Arguments) {
- interrupt::free(|_cs| {
- unsafe { TX.get_mut().as_mut().map(|tx| write(tx, args)) };
+ interrupt::free(|cs| {
+ TX.borrow(cs).borrow_mut().as_mut().map(|tx| write(tx, args));
});
}
diff --git a/src/main.rs b/src/main.rs
index dce005a..d0dfe1a 100755
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,191 +1,176 @@
-/*
#![no_std]
#![no_main]
-mod blink;
+//extern crate panic_semihosting;
+
mod led;
mod log;
-mod usb;
-
-use gd32vf103xx_hal::{
- afio::AfioExt,
- eclic::{self, EclicExt},
- gpio::GpioExt,
- pac::{self, Peripherals},
- rcu::RcuExt,
- serial::Serial,
- time::{Hertz, MegaHertz},
- timer::Timer,
-};
-use riscv::{
- asm::wfi,
- interrupt,
-};
-use riscv_rt::entry;
-use usb_device::prelude::*;
use led::LED;
-use usb::{USB, UsbBus};
-static mut EP_MEMORY: [u32; 1024] = [0; 1024];
+use cortex_m::{
+ asm::{bkpt, wfi},
+ interrupt,
+};
+use cortex_m_rt::entry;
+use embedded_hal::spi::{Mode, Phase, Polarity};
+use stm32f1xx_hal::{
+ pac,
+ prelude::*,
+ serial::{Config, Serial, StopBits, WordLength},
+ spi::Spi,
+ usb::{self, UsbBus},
+};
+use usb_device::prelude::*;
+use usbd_serial::{SerialPort, USB_CLASS_CDC};
#[entry]
-fn main(_hartid: usize) -> ! {
- let p = Peripherals::take().expect("couldn't take peripherals");
-
- pac::ECLIC::reset();
- pac::ECLIC::set_threshold_level(eclic::Level::L0);
- pac::ECLIC::set_level_priority_bits(eclic::LevelPriorityBits::L3P1);
-
- let mut rcu = p.RCU
- .configure()
- .ext_hf_clock(MegaHertz(8))
- .sysclk(MegaHertz(96))
- .freeze();
- let mut afio = p.AFIO.constrain(&mut rcu);
- let gpioa = p.GPIOA.split(&mut rcu);
-
- // TODO: figure out how to use the usb serial on the start board.
- //
- // this version has to be wired up physically.
- let serial = Serial::new(
- p.USART1,
- (gpioa.pa2, gpioa.pa3),
- Default::default(),
- &mut afio,
- &mut rcu,
+fn main() -> ! {
+ let dp = pac::Peripherals::take().unwrap();
+
+ let mut flash = dp.FLASH.constrain();
+ let rcc = dp.RCC.constrain();
+
+ let clocks = rcc
+ .cfgr
+ .use_hse(8.MHz())
+ .sysclk(72.MHz()) // TODO: gd32 can get up to 120MHz
+ // .pclk1(24.MHz()) // TODO: causes issues with gd32 usb (dropped packets) and garbled usart1 output
+ .freeze(&mut flash.acr);
+
+ assert!(clocks.usbclk_valid());
+
+ let mut gpiob = dp.GPIOB.split();
+ let mut led = LED::new(gpiob.pb2, &mut gpiob.crl);
+
+ let mut afio = dp.AFIO.constrain();
+ let mut gpioa = dp.GPIOA.split();
+
+ let tx_pin = gpioa.pa9.into_alternate_push_pull(&mut gpioa.crh);
+ let rx_pin = gpioa.pa10;
+ let serial = Serial::usart1(
+ dp.USART1,
+ (tx_pin, rx_pin),
+ &mut afio.mapr,
+ Config::default()
+ .baudrate(115200.bps())
+ .wordlength(WordLength::Bits8)
+ .parity_none()
+ .stopbits(StopBits::STOP1),
+ clocks,
);
- let (tx, _rx) = serial.split();
+ let (tx, _) = serial.split();
+
log::init(tx);
- let timer = Timer::<pac::TIMER6>::timer6(p.TIMER6, Hertz(5), &mut rcu);
- let led = LED::new(gpioa.pa7);
- let mut blink = blink::Task::new(timer, Hertz(5), led);
+ logln!("luchie started!");
+
+ // cirque spi connections to spi1:
+ //
+ // pb0 - dr
+ // pa4 - ss1
+ // pa5 - clk1
+ // pa6 - miso1
+ // pa7 - mosi1
+
+ let dr_pin = gpiob.pb0;
+ let sck_pin = gpioa.pa5.into_alternate_push_pull(&mut gpioa.crl);
+ let miso_pin = gpioa.pa6;
+ let mosi_pin = gpioa.pa7.into_alternate_push_pull(&mut gpioa.crl);
+ let cs_pin = gpioa.pa4.into_push_pull_output(&mut gpioa.crl);
+ let spi_mode = Mode {
+ phase: Phase::CaptureOnSecondTransition,
+ polarity: Polarity::IdleHigh,
+ };
+ let spi = Spi::spi1(
+ dp.SPI1,
+ (sck_pin, miso_pin, mosi_pin),
+ &mut afio.mapr,
+ spi_mode,
+ 1.MHz(),
+ clocks,
+ );
- let usb = USB {
- usb_global: p.USBFS_GLOBAL,
- usb_device: p.USBFS_DEVICE,
- usb_pwrclk: p.USBFS_PWRCLK,
+ // BluePill board has a pull-up resistor on the D+ line.
+ // Pull the D+ pin down to send a RESET condition to the USB bus.
+ // This forced reset is needed only for development, without it host
+ // will not reset your device when you upload new firmware.
+ let mut usb_dp = gpioa.pa12.into_push_pull_output(&mut gpioa.crh);
+ usb_dp.set_low();
+ // let mut delay = dp.TIM2.delay_us(&clocks);
+ // delay.delay_ms(10u8);
+ cortex_m::asm::delay(clocks.sysclk().raw() / 100);
+
+ let usb = usb::Peripheral {
+ usb: dp.USB,
pin_dm: gpioa.pa11,
- pin_dp: gpioa.pa12,
- hclk: rcu.clocks.hclk()
+ pin_dp: usb_dp.into_floating_input(&mut gpioa.crh),
};
+ let usb_bus = UsbBus::new(usb);
- let usb_bus = UsbBus::new(usb, unsafe { &mut EP_MEMORY });
+ let mut serial = SerialPort::new(&usb_bus);
- let mut usb_dev = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(0x16c0, 0x27dd))
+ let mut usb_dev = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(0xdead, 0xbeef))
.manufacturer("Fake company")
- .product("Enumeration test")
+ .product("Serial port")
.serial_number("TEST")
- .device_class(0)
+ .device_class(USB_CLASS_CDC)
.build();
- //let mut serial = SerialPort::new(&bus_alloc);
-
- unsafe { interrupt::enable() };
-
loop {
- let mut can_sleep = true;
-
- if let Ok(_) = blink.poll() {
- can_sleep = false;
- }
- if usb_dev.poll(&mut []) {
- logln!("usb");
- can_sleep = false;
+ logln!(".");
+ if !usb_dev.poll(&mut [&mut serial]) {
+ continue;
}
- if can_sleep && false {
- log!("!");
- unsafe { wfi() };
+ let mut buf = [0u8; 64];
+
+ match serial.read(&mut buf) {
+ Ok(count) if count > 0 => {
+ led.on();
+
+ // Echo back in upper case
+ for c in buf[0..count].iter_mut() {
+ if 0x61 <= *c && *c <= 0x7a {
+ *c &= !0x20;
+ }
+ }
+
+ let mut write_offset = 0;
+ while write_offset < count {
+ match serial.write(&buf[write_offset..count]) {
+ Ok(len) if len > 0 => {
+ write_offset += len;
+ }
+ _ => {}
+ }
+ }
+ }
+ _ => {}
}
- }
-}
-#[export_name="ExceptionHandler"]
-fn exception_handler(_frame: &riscv_rt::TrapFrame) -> ! {
- spin();
-}
-
-#[export_name="DefaultHandler"]
-fn default_handler() -> ! {
- spin();
-}
-#[export_name="MachineTimer"]
-fn machine_timer() {
- spin();
-}
-*/
-
-#![no_std]
-#![no_main]
-
-mod usb;
-
-use riscv::asm::wfi;
-use riscv_rt::entry;
-use gd32vf103xx_hal::prelude::*;
-use gd32vf103xx_hal::pac;
-
-use usb::{USB, UsbBus};
-use usb_device::prelude::*;
-use usbd_serial::SerialPort;
-
-static mut EP_MEMORY: [u32; 1024] = [0; 1024];
-
-#[entry]
-fn main() -> ! {
- let dp = pac::Peripherals::take().unwrap();
-
- // Configure clocks
- let mut rcu = dp.RCU.configure()
- .ext_hf_clock(8.mhz())
- .sysclk(96.mhz())
- .freeze();
-
- assert!(rcu.clocks.usbclk_valid());
-
- let gpioa = dp.GPIOA.split(&mut rcu);
- let usb = USB {
- usb_global: dp.USBFS_GLOBAL,
- usb_device: dp.USBFS_DEVICE,
- usb_pwrclk: dp.USBFS_PWRCLK,
- pin_dm: gpioa.pa11,
- pin_dp: gpioa.pa12,
- hclk: rcu.clocks.hclk()
- };
-
- let usb_bus = UsbBus::new(usb, unsafe { &mut EP_MEMORY });
-
- let mut serial = SerialPort::new(&usb_bus);
- let mut usb_dev = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(0x16c0, 0x27dd))
- .manufacturer("Fake company")
- .product("Enumeration test")
- .serial_number("TEST")
- .device_class(0)
- .build();
-
- loop {
- if usb_dev.poll(&mut [&mut serial]) {
- }
+ led.off();
}
}
#[panic_handler]
fn panic(info: &core::panic::PanicInfo) -> ! {
-// interrupt::free(|_cs| {
-// log!("!!! panic ");
+ interrupt::free(|_cs| {
+ log!("!!! panic ");
if let Some(loc) = info.location() {
-// log!("in {}:{} ", loc.file(), loc.line());
+ log!("in {}:{} ", loc.file(), loc.line());
}
if let Some(msg) = info.payload().downcast_ref::<&str>() {
-// log!("⇒ {} ", msg);
+ log!("⇒ {} ", msg);
}
-// logln!("!!!");
-// });
+ logln!("!!!");
+ });
spin();
}
fn spin() -> ! {
- loop { unsafe { wfi() } };
+ bkpt();
+ loop {
+ wfi();
+ }
}