Fun with rust

This commit is contained in:
Wladimir J. van der Laan 2019-05-11 10:18:44 +00:00
parent b641ee4054
commit d9453e8a52
28 changed files with 2668 additions and 0 deletions

View File

@ -47,6 +47,17 @@ serial output in Intel HEX format.
[README](src/dump_otp/README.md)
rust/k210-console
-----------------
Console emulator written in Rust for the Maix Go.
Barely functional at the moment. This is really a test for some functionality
like SPI and driving the display from Rust, and for playing with Rust RISC-V 64
in general.
[README](rust/k210-console/README.md)
ROM re'ing
===========

View File

@ -0,0 +1,9 @@
[target.riscv64gc-unknown-none-elf]
runner = "riscv64-unknown-elf-gdb -x gdb_init"
rustflags = [
"-C", "link-arg=-Tmemory.x",
"-C", "link-arg=-Tlink.x",
]
[build]
target = "riscv64gc-unknown-none-elf"

2
rust/k210-console/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/target
**/*.rs.bk

View File

@ -0,0 +1,37 @@
# The Rust Code of Conduct
## Conduct
**Contact**: [RISC-V team](https://github.com/rust-embedded/wg#the-riscv-team)
* We are committed to providing a friendly, safe and welcoming environment for all, regardless of level of experience, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, nationality, or other similar characteristic.
* On IRC, please avoid using overtly sexual nicknames or other nicknames that might detract from a friendly, safe and welcoming environment for all.
* Please be kind and courteous. There's no need to be mean or rude.
* Respect that people have differences of opinion and that every design or implementation choice carries a trade-off and numerous costs. There is seldom a right answer.
* Please keep unstructured critique to a minimum. If you have solid ideas you want to experiment with, make a fork and see how it works.
* We will exclude you from interaction if you insult, demean or harass anyone. That is not welcome behavior. We interpret the term "harassment" as including the definition in the [Citizen Code of Conduct](http://citizencodeofconduct.org/); if you have any lack of clarity about what might be included in that concept, please read their definition. In particular, we don't tolerate behavior that excludes people in socially marginalized groups.
* Private harassment is also unacceptable. No matter who you are, if you feel you have been or are being harassed or made uncomfortable by a community member, please contact one of the channel ops or any of the [RISC-V team][team] immediately. Whether you're a regular contributor or a newcomer, we care about making this community a safe place for you and we've got your back.
* Likewise any spamming, trolling, flaming, baiting or other attention-stealing behavior is not welcome.
## Moderation
These are the policies for upholding our community's standards of conduct.
1. Remarks that violate the Rust standards of conduct, including hateful, hurtful, oppressive, or exclusionary remarks, are not allowed. (Cursing is allowed, but never targeting another user, and never in a hateful manner.)
2. Remarks that moderators find inappropriate, whether listed in the code of conduct or not, are also not allowed.
3. Moderators will first respond to such remarks with a warning.
4. If the warning is unheeded, the user will be "kicked," i.e., kicked out of the communication channel to cool off.
5. If the user comes back and continues to make trouble, they will be banned, i.e., indefinitely excluded.
6. Moderators may choose at their discretion to un-ban the user if it was a first offense and they offer the offended party a genuine apology.
7. If a moderator bans someone and you think it was unjustified, please take it up with that moderator, or with a different moderator, **in private**. Complaints about bans in-channel are not allowed.
8. Moderators are held to a higher standard than other community members. If a moderator creates an inappropriate situation, they should expect less leeway than others.
In the Rust community we strive to go the extra step to look out for each other. Don't just aim to be technically unimpeachable, try to be your best self. In particular, avoid flirting with offensive or sensitive issues, particularly if they're off-topic; this all too often leads to unnecessary fights, hurt feelings, and damaged trust; worse, it can drive people away from the community entirely.
And if someone takes issue with something you said or did, resist the urge to be defensive. Just stop doing what it was they complained about and apologize. Even if you feel you were misinterpreted or unfairly accused, chances are good there was something you could've communicated better — remember that it's your responsibility to make your fellow Rustaceans comfortable. Everyone wants to get along and we are all here first and foremost because we want to talk about cool technology. You will find that people will be eager to assume good intent and forgive as long as you earn their trust.
The enforcement policies listed above apply to all official embedded WG venues; including official IRC channels (#rust-embedded); GitHub repositories under rust-embedded; and all forums under rust-embedded.org (forum.rust-embedded.org).
*Adapted from the [Node.js Policy on Trolling](http://blog.izs.me/post/30036893703/policy-on-trolling) as well as the [Contributor Covenant v1.3.0](https://www.contributor-covenant.org/version/1/3/0/).*
[team]: https://github.com/rust-embedded/wg#the-riscv-team

208
rust/k210-console/Cargo.lock generated Normal file
View File

@ -0,0 +1,208 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "bare-metal"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "bit_field"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "embedded-hal"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"nb 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "k210-console"
version = "0.1.0"
dependencies = [
"k210-hal 0.1.0 (git+https://github.com/riscv-rust/k210-hal.git?rev=725418b922d9bb6d8593ba4087b5d90f49e1b8e7)",
"panic-halt 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"riscv 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"riscv-rt 0.5.0 (git+https://github.com/rust-embedded/riscv-rt.git?rev=ecc1344ffc9af1c88b3dd76b83ad56284672f888)",
]
[[package]]
name = "k210-hal"
version = "0.1.0"
source = "git+https://github.com/riscv-rust/k210-hal.git?rev=725418b922d9bb6d8593ba4087b5d90f49e1b8e7#725418b922d9bb6d8593ba4087b5d90f49e1b8e7"
dependencies = [
"embedded-hal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"k210-pac 0.1.0 (git+https://github.com/riscv-rust/k210-pac.git?rev=eea80433bf6c0f91e1eeb89cd9f0b892b970149a)",
"nb 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "k210-pac"
version = "0.1.0"
source = "git+https://github.com/riscv-rust/k210-pac.git?rev=eea80433bf6c0f91e1eeb89cd9f0b892b970149a#eea80433bf6c0f91e1eeb89cd9f0b892b970149a"
dependencies = [
"bare-metal 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"riscv 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"riscv-rt 0.5.0 (git+https://github.com/rust-embedded/riscv-rt.git?rev=ecc1344ffc9af1c88b3dd76b83ad56284672f888)",
"vcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "nb"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "panic-halt"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "proc-macro2"
version = "0.4.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "quote"
version = "0.6.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "r0"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "rand"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand_core"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand_core"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "riscv"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bare-metal 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "riscv-rt"
version = "0.5.0"
source = "git+https://github.com/rust-embedded/riscv-rt.git?rev=ecc1344ffc9af1c88b3dd76b83ad56284672f888#ecc1344ffc9af1c88b3dd76b83ad56284672f888"
dependencies = [
"r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"riscv 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"riscv-rt-macros 0.1.5 (git+https://github.com/rust-embedded/riscv-rt.git?rev=ecc1344ffc9af1c88b3dd76b83ad56284672f888)",
]
[[package]]
name = "riscv-rt-macros"
version = "0.1.5"
source = "git+https://github.com/rust-embedded/riscv-rt.git?rev=ecc1344ffc9af1c88b3dd76b83ad56284672f888#ecc1344ffc9af1c88b3dd76b83ad56284672f888"
dependencies = [
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rustc_version"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "semver"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "semver-parser"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "syn"
version = "0.15.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "unicode-xid"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "vcell"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "void"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum bare-metal 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a3caf393d93b2d453e80638d0674597020cef3382ada454faacd43d1a55a735a"
"checksum bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed8765909f9009617974ab6b7d332625b320b33c326b1e9321382ef1999b5d56"
"checksum embedded-hal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ee4908a155094da7723c2d60d617b820061e3b4efcc3d9e293d206a5a76c170b"
"checksum k210-hal 0.1.0 (git+https://github.com/riscv-rust/k210-hal.git?rev=725418b922d9bb6d8593ba4087b5d90f49e1b8e7)" = "<none>"
"checksum k210-pac 0.1.0 (git+https://github.com/riscv-rust/k210-pac.git?rev=eea80433bf6c0f91e1eeb89cd9f0b892b970149a)" = "<none>"
"checksum nb 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b1411551beb3c11dedfb0a90a0fa256b47d28b9ec2cdff34c25a2fa59e45dbdc"
"checksum panic-halt 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de96540e0ebde571dc55c73d60ef407c653844e6f9a1e2fdbd40c07b9252d812"
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
"checksum quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "faf4799c5d274f3868a4aae320a0a182cbd2baee377b378f080e16a23e9d80db"
"checksum r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2a38df5b15c8d5c7e8654189744d8e396bddc18ad48041a500ce52d6948941f"
"checksum rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9"
"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
"checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0"
"checksum riscv 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "00f3ec73803f144a6474819070dfcf0b0d1662e1bd8845956850ee8f8cfbc69b"
"checksum riscv-rt 0.5.0 (git+https://github.com/rust-embedded/riscv-rt.git?rev=ecc1344ffc9af1c88b3dd76b83ad56284672f888)" = "<none>"
"checksum riscv-rt-macros 0.1.5 (git+https://github.com/rust-embedded/riscv-rt.git?rev=ecc1344ffc9af1c88b3dd76b83ad56284672f888)" = "<none>"
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
"checksum syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)" = "a1393e4a97a19c01e900df2aec855a29f71cf02c402e2f443b8d2747c25c5dbe"
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
"checksum vcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "45c297f0afb6928cd08ab1ff9d95e99392595ea25ae1b5ecf822ff8764e57a0d"
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"

View File

@ -0,0 +1,16 @@
[package]
name = "k210-console"
version = "0.1.0"
authors = ["W.J. van der Laan <laanwj@protonmail.com>"]
edition = "2018"
[dependencies]
panic-halt = "0.2.0"
riscv-rt = "0.5.0"
k210-hal = "0.1.0"
riscv = "0.5"
[patch.crates-io]
riscv-rt = { git = "https://github.com/rust-embedded/riscv-rt.git", rev = "ecc1344ffc9af1c88b3dd76b83ad56284672f888"}
k210-pac = { git = "https://github.com/riscv-rust/k210-pac.git", rev = "eea80433bf6c0f91e1eeb89cd9f0b892b970149a"}
k210-hal = { git = "https://github.com/riscv-rust/k210-hal.git", rev = "725418b922d9bb6d8593ba4087b5d90f49e1b8e7" }

View File

@ -0,0 +1,41 @@
# `k210-console`
Console emulator written in rust for the Maix Go.
Barely functional at the moment. This is really a test for some functionality
like SPI and driving the display from Rust.
## Getting started
Start openocd:
openocd -f dp_busblaster.cfg -f openocd.cfg
Run the example:
cargo run --release
## License
Copyright 2019 W. J. van der Laan
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
## Code of Conduct
Contribution to this crate is organized under the terms of the [Rust Code of
Conduct][CoC], the maintainer of this crate, the [RISC-V team][team], promises
to intervene to uphold that code of conduct.
[CoC]: CODE_OF_CONDUCT.md
[team]: https://github.com/rust-embedded/wg#the-riscv-team

View File

@ -0,0 +1,13 @@
use std::{env, fs};
use std::path::PathBuf;
use std::io::Write;
fn main() {
// Put the linker script somewhere the linker can find it
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
println!("cargo:rustc-link-search={}", out_dir.display());
fs::File::create(out_dir.join("memory.x")).unwrap()
.write_all(include_bytes!("memory.x")).unwrap();
println!("cargo:rerun-if-changed=memory.x");
}

View File

@ -0,0 +1,3 @@
target remote :3333
load
c

View File

@ -0,0 +1,8 @@
INCLUDE memory-k210.x
REGION_ALIAS("REGION_TEXT", SRAM_NOCACHE);
REGION_ALIAS("REGION_RODATA", SRAM_NOCACHE);
REGION_ALIAS("REGION_DATA", SRAM_NOCACHE);
REGION_ALIAS("REGION_BSS", SRAM_NOCACHE);
REGION_ALIAS("REGION_HEAP", SRAM_NOCACHE);
REGION_ALIAS("REGION_STACK", SRAM_NOCACHE);

View File

@ -0,0 +1,11 @@
transport select jtag
adapter_khz 1000
set _CHIPNAME riscv
jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x04e4796b
set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME riscv -chain-position $_TARGETNAME
init
halt

View File

@ -0,0 +1,2 @@
pub mod lcd;
pub mod lcd_colors;

View File

@ -0,0 +1,308 @@
/** ST7789V LCD driver */
use k210_hal::pac;
use pac::spi0::ctrlr0;
use pac::spi0::spi_ctrlr0;
use crate::soc::gpio;
use crate::soc::gpiohs;
use crate::soc::sleep::usleep;
use crate::soc::spi;
pub const SPI_SLAVE_SELECT: u32 = 3;
pub const DCX_GPIONUM: u8 = 2;
pub const RST_GPIONUM: u8 = 3;
pub const LCD_X_MAX: u16 = 320;
pub const LCD_Y_MAX: u16 = 240;
#[repr(u8)]
#[derive(Copy, Clone)]
pub enum command {
NO_OPERATION = 0x00,
SOFTWARE_RESET = 0x01,
READ_ID = 0x04,
READ_STATUS = 0x09,
READ_POWER_MODE = 0x0A,
READ_MADCTL = 0x0B,
READ_PIXEL_FORMAT = 0x0C,
READ_IMAGE_FORMAT = 0x0D,
READ_SIGNAL_MODE = 0x0E,
READ_SELT_DIAG_RESULT = 0x0F,
SLEEP_ON = 0x10,
SLEEP_OFF = 0x11,
PARTIAL_DISPLAY_ON = 0x12,
NORMAL_DISPLAY_ON = 0x13,
INVERSION_DISPLAY_OFF = 0x20,
INVERSION_DISPLAY_ON = 0x21,
GAMMA_SET = 0x26,
DISPLAY_OFF = 0x28,
DISPLAY_ON = 0x29,
HORIZONTAL_ADDRESS_SET = 0x2A,
VERTICAL_ADDRESS_SET = 0x2B,
MEMORY_WRITE = 0x2C,
COLOR_SET = 0x2D,
MEMORY_READ = 0x2E,
PARTIAL_AREA = 0x30,
VERTICAL_SCROLL_DEFINE = 0x33,
TEAR_EFFECT_LINE_OFF = 0x34,
TEAR_EFFECT_LINE_ON = 0x35,
MEMORY_ACCESS_CTL = 0x36,
VERTICAL_SCROLL_S_ADD = 0x37,
IDLE_MODE_OFF = 0x38,
IDLE_MODE_ON = 0x39,
PIXEL_FORMAT_SET = 0x3A,
WRITE_MEMORY_CONTINUE = 0x3C,
READ_MEMORY_CONTINUE = 0x3E,
SET_TEAR_SCANLINE = 0x44,
GET_SCANLINE = 0x45,
WRITE_BRIGHTNESS = 0x51,
READ_BRIGHTNESS = 0x52,
WRITE_CTRL_DISPLAY = 0x53,
READ_CTRL_DISPLAY = 0x54,
WRITE_BRIGHTNESS_CTL = 0x55,
READ_BRIGHTNESS_CTL = 0x56,
WRITE_MIN_BRIGHTNESS = 0x5E,
READ_MIN_BRIGHTNESS = 0x5F,
READ_ID1 = 0xDA,
READ_ID2 = 0xDB,
READ_ID3 = 0xDC,
RGB_IF_SIGNAL_CTL = 0xB0,
NORMAL_FRAME_CTL = 0xB1,
IDLE_FRAME_CTL = 0xB2,
PARTIAL_FRAME_CTL = 0xB3,
INVERSION_CTL = 0xB4,
BLANK_PORCH_CTL = 0xB5,
DISPLAY_FUNCTION_CTL = 0xB6,
ENTRY_MODE_SET = 0xB7,
BACKLIGHT_CTL1 = 0xB8,
BACKLIGHT_CTL2 = 0xB9,
BACKLIGHT_CTL3 = 0xBA,
BACKLIGHT_CTL4 = 0xBB,
BACKLIGHT_CTL5 = 0xBC,
BACKLIGHT_CTL7 = 0xBE,
BACKLIGHT_CTL8 = 0xBF,
POWER_CTL1 = 0xC0,
POWER_CTL2 = 0xC1,
VCOM_CTL1 = 0xC5,
VCOM_CTL2 = 0xC7,
NV_MEMORY_WRITE = 0xD0,
NV_MEMORY_PROTECT_KEY = 0xD1,
NV_MEMORY_STATUS_READ = 0xD2,
READ_ID4 = 0xD3,
POSITIVE_GAMMA_CORRECT = 0xE0,
NEGATIVE_GAMMA_CORRECT = 0xE1,
DIGITAL_GAMMA_CTL1 = 0xE2,
DIGITAL_GAMMA_CTL2 = 0xE3,
INTERFACE_CTL = 0xF6,
}
#[repr(u8)]
#[derive(Copy, Clone)]
pub enum direction {
XY_RLUD = 0x00,
YX_RLUD = 0x20,
XY_LRUD = 0x40,
YX_LRUD = 0x60,
XY_RLDU = 0x80,
YX_RLDU = 0xA0,
XY_LRDU = 0xC0,
YX_LRDU = 0xE0,
}
pub const DIR_XY_MASK: u8 = 0x20;
pub const DIR_MASK: u8 = 0xE0;
/* Low-level functions */
fn init_dcx() {
gpiohs::set_direction(DCX_GPIONUM, gpio::direction::OUTPUT);
gpiohs::set_pin(DCX_GPIONUM, true);
}
fn set_dcx_control() {
gpiohs::set_pin(DCX_GPIONUM, false);
}
fn set_dcx_data() {
gpiohs::set_pin(DCX_GPIONUM, true);
}
fn init_rst() {
gpiohs::set_direction(RST_GPIONUM, gpio::direction::OUTPUT);
gpiohs::set_pin(RST_GPIONUM, true);
}
fn set_rst(val: bool) {
gpiohs::set_pin(RST_GPIONUM, val);
}
pub fn hard_init() {
init_dcx();
init_rst();
set_rst(false);
spi::clk_init();
spi::init(
ctrlr0::WORK_MODEW::MODE0,
ctrlr0::FRAME_FORMATW::OCTAL,
8,
0,
8, /*instruction length*/
0, /*address length*/
0, /*wait cycles*/
spi_ctrlr0::AITMW::AS_FRAME_FORMAT,
ctrlr0::TMODW::TRANS,
);
spi::set_clk_rate(10000000);
set_rst(true);
}
pub fn write_command(cmd: command) {
set_dcx_control();
spi::init(
ctrlr0::WORK_MODEW::MODE0,
ctrlr0::FRAME_FORMATW::OCTAL,
8,
0,
8, /*instruction length*/
0, /*address length*/
0, /*wait cycles*/
spi_ctrlr0::AITMW::AS_FRAME_FORMAT,
ctrlr0::TMODW::TRANS,
);
spi::send_data(SPI_SLAVE_SELECT, &[cmd as u8]);
}
pub fn write_byte(data_buf: &[u8]) {
set_dcx_data();
spi::init(
ctrlr0::WORK_MODEW::MODE0,
ctrlr0::FRAME_FORMATW::OCTAL,
8,
0,
0, /*instruction length*/
8, /*address length*/
0, /*wait cycles*/
spi_ctrlr0::AITMW::AS_FRAME_FORMAT,
ctrlr0::TMODW::TRANS,
);
spi::send_data(SPI_SLAVE_SELECT, data_buf);
}
pub fn write_half(data_buf: &[u16]) {
set_dcx_data();
spi::init(
ctrlr0::WORK_MODEW::MODE0,
ctrlr0::FRAME_FORMATW::OCTAL,
16,
0,
0, /*instruction length*/
16, /*address length*/
0, /*wait cycles*/
spi_ctrlr0::AITMW::AS_FRAME_FORMAT,
ctrlr0::TMODW::TRANS,
);
spi::send_data(SPI_SLAVE_SELECT, data_buf);
}
pub fn write_word(data_buf: &[u32]) {
set_dcx_data();
spi::init(
ctrlr0::WORK_MODEW::MODE0,
ctrlr0::FRAME_FORMATW::OCTAL,
32,
0,
0, /*instruction length*/
32, /*address length*/
0, /*wait cycles*/
spi_ctrlr0::AITMW::AS_FRAME_FORMAT,
ctrlr0::TMODW::TRANS,
);
spi::send_data(SPI_SLAVE_SELECT, data_buf);
}
pub fn fill_data(data: u32, length: usize) {
set_dcx_data();
spi::init(
ctrlr0::WORK_MODEW::MODE0,
ctrlr0::FRAME_FORMATW::OCTAL,
32,
0,
0, /*instruction length*/
32, /*address length*/
0, /*wait cycles*/
spi_ctrlr0::AITMW::AS_FRAME_FORMAT,
ctrlr0::TMODW::TRANS,
);
spi::fill_data(SPI_SLAVE_SELECT, data, length);
}
/* High-level functions */
pub fn init() {
hard_init();
/*soft reset*/
write_command(command::SOFTWARE_RESET);
usleep(100000);
/*exit sleep*/
write_command(command::SLEEP_OFF);
usleep(100000);
/*pixel format*/
write_command(command::PIXEL_FORMAT_SET);
write_byte(&[0x55]);
set_direction(direction::XY_LRUD);
/*display on*/
write_command(command::DISPLAY_ON);
}
pub fn set_direction(dir: direction) {
/* No support for YX orientations right now --
lcd_ctl.dir = dir;
if (dir & DIR_XY_MASK)
{
lcd_ctl.width = LCD_Y_MAX - 1;
lcd_ctl.height = LCD_X_MAX - 1;
}
else
{
lcd_ctl.width = LCD_X_MAX - 1;
lcd_ctl.height = LCD_Y_MAX - 1;
}
*/
write_command(command::MEMORY_ACCESS_CTL);
write_byte(&[dir as u8]);
}
pub fn set_area(x1: u16, y1: u16, x2: u16, y2: u16) {
write_command(command::HORIZONTAL_ADDRESS_SET);
write_byte(&[
(x1 >> 8) as u8,
(x1 & 0xff) as u8,
(x2 >> 8) as u8,
(x2 & 0xff) as u8,
]);
write_command(command::VERTICAL_ADDRESS_SET);
write_byte(&[
(y1 >> 8) as u8,
(y1 & 0xff) as u8,
(y2 >> 8) as u8,
(y2 & 0xff) as u8,
]);
write_command(command::MEMORY_WRITE);
}
pub fn clear(color: u16) {
let data = ((color as u32) << 16) | (color as u32);
//set_area(0, 0, lcd_ctl.width, lcd_ctl.height);
set_area(0, 0, LCD_X_MAX - 1, LCD_Y_MAX - 1);
fill_data(data, (LCD_X_MAX as usize) * (LCD_Y_MAX as usize) / 2);
}
pub fn draw_picture(x1: u16, y1: u16, width: u16, height: u16, data: &[u32]) {
set_area(x1, y1, x1 + width - 1, y1 + height - 1);
assert!(data.len() == (width as usize) * (height as usize) / 2);
write_word(data);
}

View File

@ -0,0 +1,25 @@
/** Some convenient RGB565 colors */
pub const BLACK: u16 = 0x0000;
pub const NAVY: u16 = 0x000F;
pub const DARKGREEN: u16 = 0x03E0;
pub const DARKCYAN: u16 = 0x03EF;
pub const MAROON: u16 = 0x7800;
pub const PURPLE: u16 = 0x780F;
pub const OLIVE: u16 = 0x7BE0;
pub const LIGHTGREY: u16 = 0xC618;
pub const DARKGREY: u16 = 0x7BEF;
pub const BLUE: u16 = 0x001F;
pub const GREEN: u16 = 0x07E0;
pub const CYAN: u16 = 0x07FF;
pub const RED: u16 = 0xF800;
pub const MAGENTA: u16 = 0xF81F;
pub const YELLOW: u16 = 0xFFE0;
pub const WHITE: u16 = 0xFFFF;
pub const ORANGE: u16 = 0xFD20;
pub const GREENYELLOW: u16 = 0xAFE5;
pub const PINK: u16 = 0xF81F;
/** Truncate 8 bit RGB to RBG565 */
pub const fn rgb565(r: u8, g: u8, b: u8) -> u16 {
return (((r as u16) >> 3) << 11) | (((g as u16) >> 2) << 5) | ((b as u16) >> 3);
}

View File

@ -0,0 +1,150 @@
use crate::board::lcd_colors::rgb565;
use crate::cp437;
use crate::cp437_8x8;
pub const DISP_WIDTH: usize = 320;
pub const DISP_HEIGHT: usize = 240;
const GRID_WIDTH: usize = DISP_WIDTH / 8;
const GRID_HEIGHT: usize = DISP_HEIGHT / 8;
pub type ScreenImage = [u32; DISP_WIDTH * DISP_HEIGHT / 2];
#[derive(Copy, Clone)]
pub struct Color {
r: u8,
g: u8,
b: u8,
a: u8,
}
impl Color {
pub fn new(r: u8, g: u8, b: u8) -> Color {
Color { r, g, b, a: 255 }
}
pub fn new_rgba(r: u8, g: u8, b: u8, a: u8) -> Color {
Color { r, g, b, a: a }
}
pub fn from_rgba32(val: u32) -> Color {
Color {
r: ((val >> 24) & 0xff) as u8,
g: ((val >> 16) & 0xff) as u8,
b: ((val >> 8) & 0xff) as u8,
a: ((val >> 0) & 0xff) as u8,
}
}
}
#[derive(Copy, Clone)]
pub struct Coord {
x: u16,
y: u16,
}
impl Coord {
fn new(x: u16, y: u16) -> Self {
Self { x, y }
}
}
/** Axis aligned 2D rectangle */
#[derive(Copy, Clone)]
pub struct Rect {
x0: u16,
y0: u16,
x1: u16,
y1: u16,
}
impl Rect {
fn new(x0: u16, y0: u16, x1: u16, y1: u16) -> Self {
Self { x0, y0, x1, y1 }
}
}
/** One character cell */
#[derive(Copy, Clone)]
pub struct Cell {
fg: u16,
bg: u16,
ch: char,
}
/** Visual attributes of console */
pub struct Console {
/** Array of character cells representing console */
cells: [Cell; GRID_WIDTH * GRID_HEIGHT],
/** Cursor position */
cursor_pos: Coord,
/** Cursor visible flag */
cursor_visible: bool,
}
impl Console {
/** Create new, empty console */
pub fn new() -> Console {
Console {
cells: [Cell {
fg: 0,
bg: 0,
ch: '\x00',
}; GRID_WIDTH * GRID_HEIGHT],
cursor_pos: Coord::new(0, 0),
cursor_visible: true,
}
}
/** Render console to u32 image for ST7789V LCD */
pub fn render(&self, image: &mut ScreenImage) {
let mut image_base = 0;
let mut cell_idx = 0;
for y in 0..(GRID_HEIGHT as u16) {
for x in 0..(GRID_WIDTH as u16) {
let cell = &self.cells[cell_idx];
let glyph = &cp437_8x8::FONT[cp437::to(cell.ch) as usize];
let mut image_ofs = image_base;
let is_cursor =
self.cursor_visible && (y == self.cursor_pos.y) && (x == self.cursor_pos.x);
let fg = if is_cursor { cell.bg } else { cell.fg };
let bg = if is_cursor { cell.fg } else { cell.bg };
for yi in 0..8 {
let val = glyph[yi];
for xih in 0..4 {
image[image_ofs + xih] = ((if val & (1 << (xih * 2 + 0)) != 0 {
fg
} else {
bg
} as u32)
<< 16)
| ((if val & (1 << (xih * 2 + 1)) != 0 {
fg
} else {
bg
} as u32)
<< 0);
}
image_ofs += DISP_WIDTH / 2;
}
cell_idx += 1;
image_base += 8 / 2;
}
image_base += 7 * DISP_WIDTH / 2;
}
}
pub fn width(&self) -> u16 {
GRID_WIDTH as u16
}
pub fn height(&self) -> u16 {
GRID_HEIGHT as u16
}
pub fn put(&mut self, x: u16, y: u16, fg: Color, bg: Color, ch: char) {
self.cells[(y as usize) * GRID_WIDTH + (x as usize)] = Cell {
fg: rgb565(fg.r, fg.g, fg.b),
bg: rgb565(bg.r, bg.g, bg.b),
ch,
};
}
}

View File

@ -0,0 +1,9 @@
pub fn from(ch: u8) -> char {
// TODO: correct mapping
ch as char
}
pub fn to(ch: char) -> u8 {
// TODO: correct mapping
ch as u8
}

View File

@ -0,0 +1,277 @@
pub static FONT: [[u8; 8]; 256] = [
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
[0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e],
[0x7e, 0xff, 0xdb, 0xff, 0xc3, 0xe7, 0xff, 0x7e],
[0x36, 0x7f, 0x7f, 0x7f, 0x3e, 0x1c, 0x08, 0x00],
[0x08, 0x1c, 0x3e, 0x7f, 0x3e, 0x1c, 0x08, 0x00],
[0x1c, 0x3e, 0x1c, 0x7f, 0x7f, 0x6b, 0x08, 0x1c],
[0x08, 0x1c, 0x3e, 0x7f, 0x7f, 0x2a, 0x08, 0x1c],
[0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00],
[0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff],
[0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00],
[0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff],
[0xf0, 0xe0, 0xf0, 0xbe, 0x33, 0x33, 0x33, 0x1e],
[0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18],
[0x7c, 0x6c, 0x7c, 0x0c, 0x0c, 0x0e, 0x0f, 0x07],
[0x7e, 0x66, 0x7e, 0x66, 0x66, 0x76, 0x37, 0x03],
[0x18, 0xdb, 0xff, 0x3c, 0xff, 0xdb, 0x18, 0x00],
[0x00, 0x06, 0x1e, 0x7e, 0x7e, 0x1e, 0x06, 0x00],
[0x00, 0x60, 0x78, 0x7e, 0x7e, 0x78, 0x60, 0x00],
[0x18, 0x3c, 0x7e, 0x18, 0x18, 0x7e, 0x3c, 0x18],
[0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x36, 0x00],
[0xfe, 0xdb, 0xdb, 0xde, 0xd8, 0xd8, 0xd8, 0x00],
[0x7c, 0x86, 0x3c, 0x66, 0x66, 0x3c, 0x61, 0x3e],
[0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x00],
[0x18, 0x3c, 0x7e, 0x18, 0x7e, 0x3c, 0x18, 0xff],
[0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x00],
[0x00, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00],
[0x00, 0x10, 0x30, 0x7e, 0x7e, 0x30, 0x10, 0x00],
[0x00, 0x08, 0x0c, 0x7e, 0x7e, 0x0c, 0x08, 0x00],
[0x00, 0x00, 0x00, 0x06, 0x06, 0x7e, 0x00, 0x00],
[0x00, 0x24, 0x66, 0xff, 0xff, 0x66, 0x24, 0x00],
[0x00, 0x18, 0x18, 0x3c, 0x3c, 0x7e, 0x7e, 0x00],
[0x00, 0x7e, 0x7e, 0x3c, 0x3c, 0x18, 0x18, 0x00],
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
[0x18, 0x3c, 0x3c, 0x18, 0x18, 0x00, 0x18, 0x00],
[0x36, 0x36, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00],
[0x36, 0x36, 0x7f, 0x36, 0x7f, 0x36, 0x36, 0x00],
[0x18, 0x7c, 0x06, 0x3c, 0x60, 0x3e, 0x18, 0x00],
[0x00, 0x63, 0x33, 0x18, 0x0c, 0x66, 0x63, 0x00],
[0x1c, 0x36, 0x1c, 0x6e, 0x3b, 0x33, 0x6e, 0x00],
[0x18, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00],
[0x18, 0x0c, 0x06, 0x06, 0x06, 0x0c, 0x18, 0x00],
[0x06, 0x0c, 0x18, 0x18, 0x18, 0x0c, 0x06, 0x00],
[0x00, 0x36, 0x1c, 0x7f, 0x1c, 0x36, 0x00, 0x00],
[0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00],
[0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x0c],
[0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00],
[0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00],
[0x60, 0x70, 0x38, 0x1c, 0x0e, 0x07, 0x03, 0x00],
[0x3c, 0x66, 0x76, 0x7e, 0x6e, 0x66, 0x3c, 0x00],
[0x18, 0x1e, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00],
[0x3c, 0x66, 0x60, 0x38, 0x0c, 0x66, 0x7e, 0x00],
[0x3c, 0x66, 0x60, 0x38, 0x60, 0x66, 0x3c, 0x00],
[0x38, 0x3c, 0x36, 0x33, 0x7f, 0x30, 0x30, 0x00],
[0x7e, 0x06, 0x3e, 0x60, 0x60, 0x66, 0x3c, 0x00],
[0x38, 0x0c, 0x06, 0x3e, 0x66, 0x66, 0x3c, 0x00],
[0x7e, 0x66, 0x60, 0x30, 0x18, 0x0c, 0x0c, 0x00],
[0x3c, 0x66, 0x66, 0x3c, 0x66, 0x66, 0x3c, 0x00],
[0x3c, 0x66, 0x66, 0x7c, 0x60, 0x30, 0x1c, 0x00],
[0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00],
[0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x0c],
[0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00],
[0x00, 0x00, 0x7e, 0x00, 0x7e, 0x00, 0x00, 0x00],
[0x06, 0x0c, 0x18, 0x30, 0x18, 0x0c, 0x06, 0x00],
[0x3c, 0x66, 0x60, 0x30, 0x18, 0x00, 0x18, 0x00],
[0x3c, 0x66, 0x76, 0x76, 0x76, 0x06, 0x3c, 0x00],
[0x18, 0x3c, 0x66, 0x66, 0x7e, 0x66, 0x66, 0x00],
[0x3f, 0x66, 0x66, 0x3e, 0x66, 0x66, 0x3f, 0x00],
[0x3c, 0x66, 0x03, 0x03, 0x03, 0x66, 0x3c, 0x00],
[0x3f, 0x36, 0x66, 0x66, 0x66, 0x36, 0x3f, 0x00],
[0x7f, 0x46, 0x16, 0x1e, 0x16, 0x46, 0x7f, 0x00],
[0x7f, 0x46, 0x16, 0x1e, 0x16, 0x06, 0x0f, 0x00],
[0x3c, 0x66, 0x03, 0x03, 0x73, 0x66, 0x7c, 0x00],
[0x66, 0x66, 0x66, 0x7e, 0x66, 0x66, 0x66, 0x00],
[0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00],
[0x78, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1e, 0x00],
[0x67, 0x66, 0x36, 0x1e, 0x36, 0x66, 0x67, 0x00],
[0x0f, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7f, 0x00],
[0x63, 0x77, 0x7f, 0x6b, 0x63, 0x63, 0x63, 0x00],
[0x63, 0x67, 0x6f, 0x7b, 0x73, 0x63, 0x63, 0x00],
[0x1c, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1c, 0x00],
[0x3f, 0x66, 0x66, 0x3e, 0x06, 0x06, 0x0f, 0x00],
[0x3c, 0x66, 0x66, 0x66, 0x76, 0x3c, 0x70, 0x00],
[0x3f, 0x66, 0x66, 0x3e, 0x1e, 0x36, 0x67, 0x00],
[0x3c, 0x66, 0x0e, 0x38, 0x70, 0x66, 0x3c, 0x00],
[0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00],
[0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7e, 0x00],
[0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00],
[0x63, 0x63, 0x63, 0x6b, 0x7f, 0x77, 0x63, 0x00],
[0x63, 0x63, 0x36, 0x1c, 0x36, 0x63, 0x63, 0x00],
[0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x3c, 0x00],
[0x7f, 0x33, 0x19, 0x0c, 0x46, 0x63, 0x7f, 0x00],
[0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00],
[0x03, 0x07, 0x0e, 0x1c, 0x38, 0x70, 0x60, 0x00],
[0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00],
[0x08, 0x1c, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00],
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e],
[0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00],
[0x00, 0x00, 0x1e, 0x30, 0x3e, 0x33, 0x6e, 0x00],
[0x07, 0x06, 0x3e, 0x66, 0x66, 0x66, 0x3d, 0x00],
[0x00, 0x00, 0x3c, 0x66, 0x06, 0x66, 0x3c, 0x00],
[0x38, 0x30, 0x30, 0x3e, 0x33, 0x33, 0x6e, 0x00],
[0x00, 0x00, 0x3c, 0x66, 0x7e, 0x06, 0x3c, 0x00],
[0x38, 0x6c, 0x0c, 0x1e, 0x0c, 0x0c, 0x1e, 0x00],
[0x00, 0x00, 0x6e, 0x33, 0x33, 0x3e, 0x30, 0x1f],
[0x07, 0x06, 0x36, 0x6e, 0x66, 0x66, 0x67, 0x00],
[0x18, 0x00, 0x1c, 0x18, 0x18, 0x18, 0x3c, 0x00],
[0x30, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x36, 0x1c],
[0x07, 0x06, 0x66, 0x36, 0x1e, 0x36, 0x67, 0x00],
[0x1c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00],
[0x00, 0x00, 0x37, 0x7f, 0x6b, 0x63, 0x63, 0x00],
[0x00, 0x00, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x00],
[0x00, 0x00, 0x1e, 0x33, 0x33, 0x33, 0x1e, 0x00],
[0x00, 0x00, 0x3b, 0x66, 0x66, 0x3e, 0x06, 0x0f],
[0x00, 0x00, 0x6e, 0x33, 0x33, 0x3e, 0x30, 0x78],
[0x00, 0x00, 0x36, 0x6c, 0x6c, 0x0c, 0x1e, 0x00],
[0x00, 0x00, 0x7c, 0x06, 0x3c, 0x60, 0x3e, 0x00],
[0x08, 0x0c, 0x3e, 0x0c, 0x0c, 0x2c, 0x18, 0x00],
[0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x6e, 0x00],
[0x00, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00],
[0x00, 0x00, 0x63, 0x63, 0x6b, 0x7f, 0x36, 0x00],
[0x00, 0x00, 0x63, 0x36, 0x1c, 0x36, 0x63, 0x00],
[0x00, 0x00, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x3e],
[0x00, 0x00, 0x7e, 0x32, 0x18, 0x4c, 0x7e, 0x00],
[0x38, 0x0c, 0x0c, 0x06, 0x0c, 0x0c, 0x38, 0x00],
[0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00],
[0x0e, 0x18, 0x18, 0x30, 0x18, 0x18, 0x0e, 0x00],
[0x6e, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
[0x00, 0x00, 0x18, 0x3c, 0x66, 0x66, 0x7e, 0x00],
[0x1e, 0x33, 0x03, 0x03, 0x33, 0x1e, 0x0c, 0x06],
[0x00, 0x33, 0x00, 0x33, 0x33, 0x33, 0x7e, 0x00],
[0x30, 0x18, 0x3c, 0x66, 0x7e, 0x06, 0x3c, 0x00],
[0x7e, 0xc3, 0x3c, 0x60, 0x7c, 0x66, 0xfc, 0x00],
[0x33, 0x00, 0x1e, 0x30, 0x3e, 0x33, 0x7e, 0x00],
[0x06, 0x0c, 0x1e, 0x30, 0x3e, 0x33, 0x7e, 0x00],
[0x3c, 0x66, 0x3c, 0x60, 0x7c, 0x66, 0xfc, 0x00],
[0x00, 0x3c, 0x66, 0x06, 0x66, 0x3c, 0x18, 0x0c],
[0x7e, 0xc3, 0x3c, 0x66, 0x7e, 0x06, 0x3c, 0x00],
[0x66, 0x00, 0x3c, 0x66, 0x7e, 0x06, 0x3c, 0x00],
[0x0c, 0x18, 0x3c, 0x66, 0x7e, 0x06, 0x3c, 0x00],
[0x66, 0x00, 0x1c, 0x18, 0x18, 0x18, 0x3c, 0x00],
[0x3e, 0x63, 0x1c, 0x18, 0x18, 0x18, 0x3c, 0x00],
[0x0c, 0x18, 0x1c, 0x18, 0x18, 0x18, 0x3c, 0x00],
[0x66, 0x18, 0x3c, 0x66, 0x66, 0x7e, 0x66, 0x00],
[0x18, 0x24, 0x18, 0x3c, 0x66, 0x7e, 0x66, 0x00],
[0x18, 0x0c, 0x3f, 0x06, 0x1e, 0x06, 0x3f, 0x00],
[0x00, 0x00, 0x7e, 0x30, 0x7e, 0x33, 0x7e, 0x00],
[0x7c, 0x36, 0x33, 0x7f, 0x33, 0x33, 0x73, 0x00],
[0x3c, 0x66, 0x00, 0x3c, 0x66, 0x66, 0x3c, 0x00],
[0x00, 0x66, 0x00, 0x3c, 0x66, 0x66, 0x3c, 0x00],
[0x0c, 0x18, 0x00, 0x3c, 0x66, 0x66, 0x3c, 0x00],
[0x1e, 0x33, 0x00, 0x33, 0x33, 0x33, 0x7e, 0x00],
[0x06, 0x0c, 0x00, 0x33, 0x33, 0x33, 0x7e, 0x00],
[0x00, 0x66, 0x00, 0x66, 0x66, 0x7e, 0x60, 0x3e],
[0x63, 0x00, 0x3e, 0x63, 0x63, 0x63, 0x3e, 0x00],
[0x66, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00],
[0x18, 0x18, 0x7e, 0x03, 0x03, 0x7e, 0x18, 0x18],
[0x1c, 0x36, 0x26, 0x0f, 0x06, 0x67, 0x3f, 0x00],
[0x66, 0x66, 0x3c, 0x7e, 0x18, 0x7e, 0x18, 0x18],
[0x1e, 0x22, 0x22, 0x1e, 0x32, 0x1a, 0x72, 0x00],
[0x70, 0xd8, 0x18, 0x7e, 0x18, 0x1b, 0x0e, 0x00],
[0x18, 0x0c, 0x1e, 0x30, 0x3e, 0x33, 0x7e, 0x00],
[0x30, 0x18, 0x1c, 0x18, 0x18, 0x18, 0x3c, 0x00],
[0x60, 0x30, 0x00, 0x3c, 0x66, 0x66, 0x3c, 0x00],
[0x30, 0x18, 0x00, 0x33, 0x33, 0x33, 0x7e, 0x00],
[0x6e, 0x3b, 0x00, 0x1f, 0x33, 0x33, 0x33, 0x00],
[0x6e, 0x3b, 0x00, 0x37, 0x3f, 0x3b, 0x33, 0x00],
[0x3c, 0x36, 0x36, 0x7c, 0x00, 0x7e, 0x00, 0x00],
[0x3c, 0x66, 0x66, 0x3c, 0x00, 0x7e, 0x00, 0x00],
[0x18, 0x00, 0x18, 0x0c, 0x06, 0x66, 0x3c, 0x00],
[0x00, 0x00, 0x00, 0x7e, 0x06, 0x06, 0x00, 0x00],
[0x00, 0x00, 0x00, 0x7e, 0x60, 0x60, 0x00, 0x00],
[0xc3, 0x63, 0x33, 0x7b, 0xcc, 0x66, 0x33, 0xf0],
[0xc3, 0x63, 0x33, 0xdb, 0xec, 0xf6, 0xf3, 0xc0],
[0x00, 0x18, 0x00, 0x18, 0x18, 0x3c, 0x3c, 0x18],
[0x00, 0xcc, 0x66, 0x33, 0x66, 0xcc, 0x00, 0x00],
[0x00, 0x33, 0x66, 0xcc, 0x66, 0x33, 0x00, 0x00],
[0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88],
[0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55],
[0xbb, 0xee, 0xbb, 0xee, 0xbb, 0xee, 0xbb, 0xee],
[0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18],
[0x18, 0x18, 0x18, 0x1f, 0x1f, 0x18, 0x18, 0x18],
[0x18, 0x1f, 0x1f, 0x18, 0x18, 0x1f, 0x1f, 0x18],
[0x66, 0x66, 0x66, 0x67, 0x67, 0x66, 0x66, 0x66],
[0x00, 0x00, 0x00, 0x7f, 0x7f, 0x66, 0x66, 0x66],
[0x00, 0x1f, 0x1f, 0x18, 0x18, 0x1f, 0x1f, 0x18],
[0x66, 0x67, 0x67, 0x60, 0x60, 0x67, 0x67, 0x66],
[0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66],
[0x00, 0x7f, 0x7f, 0x60, 0x60, 0x67, 0x67, 0x66],
[0x66, 0x67, 0x67, 0x60, 0x60, 0x7f, 0x7f, 0x00],
[0x66, 0x66, 0x66, 0x7f, 0x7f, 0x00, 0x00, 0x00],
[0x18, 0x1f, 0x1f, 0x18, 0x18, 0x1f, 0x1f, 0x00],
[0x00, 0x00, 0x00, 0x1f, 0x1f, 0x18, 0x18, 0x18],
[0x18, 0x18, 0x18, 0xf8, 0xf8, 0x00, 0x00, 0x00],
[0x18, 0x18, 0x18, 0xff, 0xff, 0x00, 0x00, 0x00],
[0x00, 0x00, 0x00, 0xff, 0xff, 0x18, 0x18, 0x18],
[0x18, 0x18, 0x18, 0xf8, 0xf8, 0x18, 0x18, 0x18],
[0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00],
[0x18, 0x18, 0x18, 0xff, 0xff, 0x18, 0x18, 0x18],
[0x18, 0xf8, 0xf8, 0x18, 0x18, 0xf8, 0xf8, 0x18],
[0x66, 0x66, 0x66, 0xe6, 0xe6, 0x66, 0x66, 0x66],
[0x66, 0xe6, 0xe6, 0x06, 0x06, 0xfe, 0xfe, 0x00],
[0x00, 0xfe, 0xfe, 0x06, 0x06, 0xe6, 0xe6, 0x66],
[0x66, 0xe7, 0xe7, 0x00, 0x00, 0xff, 0xff, 0x00],
[0x00, 0xff, 0xff, 0x00, 0x00, 0xe7, 0xe7, 0x66],
[0x66, 0xe6, 0xe6, 0x06, 0x06, 0xe6, 0xe6, 0x66],
[0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00],
[0x66, 0xe7, 0xe7, 0x00, 0x00, 0xe7, 0xe7, 0x66],
[0x18, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00],
[0x66, 0x66, 0x66, 0xff, 0xff, 0x00, 0x00, 0x00],
[0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x18],
[0x00, 0x00, 0x00, 0xff, 0xff, 0x66, 0x66, 0x66],
[0x66, 0x66, 0x66, 0xfe, 0xfe, 0x00, 0x00, 0x00],
[0x18, 0xf8, 0xf8, 0x18, 0x18, 0xf8, 0xf8, 0x00],
[0x00, 0xf8, 0xf8, 0x18, 0x18, 0xf8, 0xf8, 0x18],
[0x00, 0x00, 0x00, 0xfe, 0xfe, 0x66, 0x66, 0x66],
[0x66, 0x66, 0x66, 0xff, 0xff, 0x66, 0x66, 0x66],
[0x18, 0xff, 0xff, 0x18, 0x18, 0xff, 0xff, 0x18],
[0x18, 0x18, 0x18, 0x1f, 0x1f, 0x00, 0x00, 0x00],
[0x00, 0x00, 0x00, 0xf8, 0xf8, 0x18, 0x18, 0x18],
[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff],
[0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff],
[0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f],
[0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0],
[0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00],
[0x00, 0x00, 0x6e, 0x3b, 0x3b, 0x6e, 0x00, 0x00],
[0x00, 0x3c, 0x66, 0x3e, 0x66, 0x3e, 0x0c, 0x00],
[0x00, 0x7e, 0x66, 0x06, 0x06, 0x06, 0x00, 0x00],
[0x00, 0x7f, 0x36, 0x36, 0x36, 0x36, 0x66, 0x00],
[0x00, 0x7e, 0x46, 0x0c, 0x0c, 0x46, 0x7e, 0x00],
[0x00, 0x00, 0x7c, 0x36, 0x36, 0x36, 0x1c, 0x00],
[0x00, 0x00, 0x66, 0x66, 0x66, 0x3e, 0x06, 0x03],
[0x00, 0x00, 0x6e, 0x3b, 0x18, 0x18, 0x18, 0x00],
[0x7e, 0x18, 0x3c, 0x66, 0x3c, 0x18, 0x7e, 0x00],
[0x1c, 0x36, 0x36, 0x3e, 0x36, 0x36, 0x1c, 0x00],
[0x1c, 0x36, 0x63, 0x63, 0x36, 0x36, 0x77, 0x00],
[0x38, 0x0c, 0x18, 0x3c, 0x66, 0x66, 0x3c, 0x00],
[0x00, 0x00, 0x3e, 0x6b, 0x6b, 0x3e, 0x00, 0x00],
[0x30, 0x18, 0x3e, 0x6b, 0x6b, 0x3e, 0x06, 0x03],
[0x38, 0x0c, 0x06, 0x3e, 0x06, 0x0c, 0x38, 0x00],
[0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00],
[0x00, 0x7e, 0x00, 0x7e, 0x00, 0x7e, 0x00, 0x00],
[0x0c, 0x0c, 0x3f, 0x0c, 0x0c, 0x00, 0x3f, 0x00],
[0x06, 0x0c, 0x18, 0x0c, 0x06, 0x00, 0x3f, 0x00],
[0x18, 0x0c, 0x06, 0x0c, 0x18, 0x00, 0x3f, 0x00],
[0x00, 0x1c, 0x36, 0x36, 0x06, 0x06, 0x06, 0x06],
[0x30, 0x30, 0x30, 0x30, 0x36, 0x36, 0x1c, 0x00],
[0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00],
[0x00, 0x6e, 0x3b, 0x00, 0x6e, 0x3b, 0x00, 0x00],
[0x1c, 0x36, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00],
[0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00],
[0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00],
[0x70, 0x10, 0x10, 0x12, 0x16, 0x1c, 0x18, 0x00],
[0x1e, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00],
[0x1c, 0x30, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00],
[0x00, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x00],
[0x00, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x7e, 0x00],
];
pub static GLYPH_BY_FILL: [u8; 256] = [
0x00, 0x20, 0xfa, 0x2e, 0xf9, 0x27, 0x2c, 0x2d, 0x5f, 0x60, 0x3a, 0x1c, 0x22, 0x3b, 0x7e, 0xa9,
0xaa, 0xfd, 0x07, 0x16, 0x3d, 0x5e, 0x7c, 0x28, 0x29, 0x2b, 0x3c, 0x3e, 0xf6, 0xf8, 0x69, 0xfb,
0x21, 0x3f, 0x7b, 0x7d, 0xa8, 0xad, 0xb0, 0xb3, 0xbf, 0xc0, 0xc4, 0xd9, 0xda, 0xe2, 0xe7, 0xf2,
0xf3, 0xfc, 0x6c, 0x74, 0x8b, 0x8d, 0xa1, 0x18, 0x19, 0x1a, 0x1b, 0x49, 0x5b, 0x5d, 0x63, 0x72,
0x73, 0x76, 0xf0, 0x2f, 0x5c, 0x6a, 0x78, 0xee, 0xf4, 0xf5, 0x09, 0x25, 0x31, 0x37, 0x61, 0x65,
0x6f, 0x7a, 0x7f, 0x94, 0x95, 0xa2, 0xae, 0xaf, 0xe0, 0xe5, 0xec, 0xf1, 0xf7, 0xff, 0x2a, 0x66,
0x6e, 0x75, 0xe6, 0x24, 0x43, 0x4a, 0x54, 0x81, 0x87, 0x8c, 0x97, 0x9e, 0xa3, 0xa7, 0xb4, 0xc1,
0xc2, 0xc3, 0xe4, 0x33, 0xa6, 0xeb, 0x10, 0x11, 0x13, 0x1e, 0x1f, 0x36, 0x39, 0x4c, 0x59, 0x70,
0x71, 0x77, 0x79, 0x80, 0x82, 0x89, 0x8a, 0x8f, 0x90, 0x91, 0x93, 0x9a, 0x9b, 0x9f, 0xe1, 0xef,
0x04, 0x32, 0x35, 0x53, 0x64, 0x67, 0x6d, 0x84, 0x85, 0x98, 0xa0, 0x34, 0x46, 0x47, 0x4f, 0x56,
0x6b, 0x96, 0x99, 0xb7, 0xb8, 0xbd, 0xbe, 0xd3, 0xd4, 0xd5, 0xd6, 0x50, 0x58, 0x62, 0x68, 0x9c,
0xa4, 0xe3, 0xe9, 0x0d, 0x12, 0x1d, 0x38, 0x41, 0x51, 0x8e, 0xb5, 0xc5, 0xc6, 0xd0, 0xd2, 0xe8,
0xed, 0x26, 0x40, 0x86, 0xea, 0x06, 0x0c, 0x45, 0x48, 0x4b, 0x55, 0x5a, 0x88, 0x9d, 0xa5, 0x83,
0x01, 0x15, 0x30, 0x44, 0x52, 0xb1, 0xb9, 0xba, 0xbb, 0xbc, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd,
0xce, 0xdc, 0xdd, 0xde, 0xdf, 0x0b, 0x42, 0x92, 0x03, 0x05, 0x17, 0x23, 0x4d, 0x4e, 0x57, 0xab,
0xb6, 0xc7, 0xcf, 0xd1, 0x0e, 0x0f, 0xfe, 0x14, 0xac, 0xd7, 0xd8, 0x0a, 0xb2, 0x02, 0x08, 0xdb,
];

View File

@ -0,0 +1,24 @@
/** 32-bit LFSR for "random" output */
pub struct LFSR {
state: u32,
feedback: u32,
}
impl LFSR {
pub fn new() -> LFSR {
LFSR {
state: 0x12345678,
feedback: 0xf00f00f0, // LFSR period 0xf7ffffe0
}
}
pub fn next(&mut self) -> u32 {
let rv = self.state;
let lsb = (self.state & 1) != 0;
self.state >>= 1;
if lsb {
self.state ^= self.feedback;
}
rv
}
}

View File

@ -0,0 +1,186 @@
#![allow(dead_code)]
#![allow(non_snake_case)]
#![allow(non_camel_case_types)]
#![no_std]
#![no_main]
extern crate panic_halt;
mod board;
mod console;
mod cp437;
mod cp437_8x8;
mod lfsr;
mod palette_xterm256;
mod soc;
use k210_hal::pac;
use k210_hal::prelude::*;
use k210_hal::stdout::Stdout;
use riscv_rt::entry;
use crate::board::lcd;
use crate::board::lcd_colors;
use crate::console::{Color, Console, ScreenImage, DISP_HEIGHT, DISP_WIDTH};
use crate::palette_xterm256::PALETTE;
use crate::soc::fpioa;
use crate::soc::sleep::usleep;
use crate::soc::sysctl;
/** Connect pins to internal functions */
fn io_mux_init() {
/* Init SPI IO map and function settings */
fpioa::set_function(37, fpioa::function::gpiohs(lcd::RST_GPIONUM));
fpioa::set_io_pull(37, fpioa::pull::DOWN); // outputs must be pull-down
fpioa::set_function(38, fpioa::function::gpiohs(lcd::DCX_GPIONUM));
fpioa::set_io_pull(38, fpioa::pull::DOWN);
fpioa::set_function(36, fpioa::function::SPI0_SS3);
fpioa::set_function(39, fpioa::function::SPI0_SCLK);
sysctl::set_spi0_dvp_data(true);
}
/** Set correct voltage for pins */
fn io_set_power() {
/* Set dvp and spi pin to 1.8V */
sysctl::set_power_mode(sysctl::power_bank::BANK6, sysctl::io_power_mode::V18);
sysctl::set_power_mode(sysctl::power_bank::BANK7, sysctl::io_power_mode::V18);
}
#[entry]
fn main() -> ! {
let p = pac::Peripherals::take().unwrap();
// Configure clocks (TODO)
let clocks = k210_hal::clock::Clocks::new();
// sleep a bit to let clients connect
usleep(200000);
// Configure UART
let serial = p.UARTHS.constrain(115_200.bps(), &clocks);
let (mut tx, _) = serial.split();
let mut stdout = Stdout(&mut tx);
io_mux_init();
io_set_power();
writeln!(stdout, "Clocks:").unwrap();
writeln!(
stdout,
" CPU {}",
sysctl::clock_get_freq(sysctl::clock::CPU)
)
.unwrap();
writeln!(
stdout,
" SPI0 {}",
sysctl::clock_get_freq(sysctl::clock::SPI0)
)
.unwrap();
writeln!(
stdout,
" PLL0 {}",
sysctl::clock_get_freq(sysctl::clock::PLL0)
)
.unwrap();
writeln!(
stdout,
" PLL1 {}",
sysctl::clock_get_freq(sysctl::clock::PLL1)
)
.unwrap();
writeln!(
stdout,
" PLL2 {}",
sysctl::clock_get_freq(sysctl::clock::PLL2)
)
.unwrap();
/* LCD init */
lcd::init();
lcd::set_direction(lcd::direction::YX_RLDU);
lcd::clear(lcd_colors::PURPLE);
let mut image: ScreenImage = [0; DISP_WIDTH * DISP_HEIGHT / 2];
let mut console: Console = Console::new();
/* Make a border */
let fg = Color::new(0x40, 0x40, 0x40);
let bg = Color::new(0x00, 0x00, 0x00);
// Sides
for x in 1..console.width() - 1 {
console.put(x, 0, fg, bg, cp437::from(196));
console.put(x, console.height() - 1, fg, bg, cp437::from(196));
}
for y in 1..console.height() - 1 {
console.put(0, y, fg, bg, cp437::from(179));
console.put(console.width() - 1, y, fg, bg, cp437::from(179));
}
// Corners
console.put(0, 0, fg, bg, cp437::from(218));
console.put(console.width() - 1, 0, fg, bg, cp437::from(191));
console.put(0, console.height() - 1, fg, bg, cp437::from(192));
console.put(
console.width() - 1,
console.height() - 1,
fg,
bg,
cp437::from(217),
);
let mut frame = 0;
let mut s = lfsr::LFSR::new();
loop {
console.put(
2,
0,
Color::new(0xc0, 0x00, 0xff),
bg,
((0x30 + ((frame / 1000) % 10)) as u8) as char,
);
console.put(
3,
0,
Color::new(0xd0, 0x00, 0xff),
bg,
((0x30 + ((frame / 100) % 10)) as u8) as char,
);
console.put(
4,
0,
Color::new(0xe0, 0x00, 0xff),
bg,
((0x30 + ((frame / 10) % 10)) as u8) as char,
);
console.put(
5,
0,
Color::new(0xf0, 0x00, 0xff),
bg,
((0x30 + ((frame / 1) % 10)) as u8) as char,
);
/* just put some random stuff */
for y in 2..console.height() - 2 {
for x in 2..console.width() - 2 {
let rv = s.next();
console.put(
x,
y,
Color::from_rgba32(PALETTE[((rv >> 24) & 0xf) as usize]),
Color::from_rgba32(PALETTE[((rv >> 20) & 0x7) as usize]),
cp437::from((rv & 0xff) as u8),
);
}
}
console.render(&mut image);
lcd::draw_picture(0, 0, DISP_WIDTH as u16, DISP_HEIGHT as u16, &image);
writeln!(stdout, "test {}", frame).unwrap();
usleep(1_000_000);
frame += 1;
}
}

View File

@ -0,0 +1,262 @@
/// Xterm-256 palette, 0xRRGGBBxx format
/// First 16 colors are the VGA colors
#[cfg_attr(rustfmt, rustfmt_skip)]
pub const PALETTE: [u32; 256] = [
0x000000ff,
0xaa0000ff,
0x00aa00ff,
0xaa5500ff,
0x0000aaff,
0xaa00aaff,
0x00aaaaff,
0xaaaaaaff,
0x555555ff,
0xff5555ff,
0x55ff55ff,
0xffff55ff,
0x5555ffff,
0xff55ffff,
0x55ffffff,
0xffffffff,
0x000000ff,
0x00005fff,
0x000087ff,
0x0000afff,
0x0000d7ff,
0x0000ffff,
0x005f00ff,
0x005f5fff,
0x005f87ff,
0x005fafff,
0x005fd7ff,
0x005fffff,
0x008700ff,
0x00875fff,
0x008787ff,
0x0087afff,
0x0087d7ff,
0x0087ffff,
0x00af00ff,
0x00af5fff,
0x00af87ff,
0x00afafff,
0x00afd7ff,
0x00afffff,
0x00d700ff,
0x00d75fff,
0x00d787ff,
0x00d7afff,
0x00d7d7ff,
0x00d7ffff,
0x00ff00ff,
0x00ff5fff,
0x00ff87ff,
0x00ffafff,
0x00ffd7ff,
0x00ffffff,
0x5f0000ff,
0x5f005fff,
0x5f0087ff,
0x5f00afff,
0x5f00d7ff,
0x5f00ffff,
0x5f5f00ff,
0x5f5f5fff,
0x5f5f87ff,
0x5f5fafff,
0x5f5fd7ff,
0x5f5fffff,
0x5f8700ff,
0x5f875fff,
0x5f8787ff,
0x5f87afff,
0x5f87d7ff,
0x5f87ffff,
0x5faf00ff,
0x5faf5fff,
0x5faf87ff,
0x5fafafff,
0x5fafd7ff,
0x5fafffff,
0x5fd700ff,
0x5fd75fff,
0x5fd787ff,
0x5fd7afff,
0x5fd7d7ff,
0x5fd7ffff,
0x5fff00ff,
0x5fff5fff,
0x5fff87ff,
0x5fffafff,
0x5fffd7ff,
0x5fffffff,
0x870000ff,
0x87005fff,
0x870087ff,
0x8700afff,
0x8700d7ff,
0x8700ffff,
0x875f00ff,
0x875f5fff,
0x875f87ff,
0x875fafff,
0x875fd7ff,
0x875fffff,
0x878700ff,
0x87875fff,
0x878787ff,
0x8787afff,
0x8787d7ff,
0x8787ffff,
0x87af00ff,
0x87af5fff,
0x87af87ff,
0x87afafff,
0x87afd7ff,
0x87afffff,
0x87d700ff,
0x87d75fff,
0x87d787ff,
0x87d7afff,
0x87d7d7ff,
0x87d7ffff,
0x87ff00ff,
0x87ff5fff,
0x87ff87ff,
0x87ffafff,
0x87ffd7ff,
0x87ffffff,
0xaf0000ff,
0xaf005fff,
0xaf0087ff,
0xaf00afff,
0xaf00d7ff,
0xaf00ffff,
0xaf5f00ff,
0xaf5f5fff,
0xaf5f87ff,
0xaf5fafff,
0xaf5fd7ff,
0xaf5fffff,
0xaf8700ff,
0xaf875fff,
0xaf8787ff,
0xaf87afff,
0xaf87d7ff,
0xaf87ffff,
0xafaf00ff,
0xafaf5fff,
0xafaf87ff,
0xafafafff,
0xafafd7ff,
0xafafffff,
0xafd700ff,
0xafd75fff,
0xafd787ff,
0xafd7afff,
0xafd7d7ff,
0xafd7ffff,
0xafff00ff,
0xafff5fff,
0xafff87ff,
0xafffafff,
0xafffd7ff,
0xafffffff,
0xd70000ff,
0xd7005fff,
0xd70087ff,
0xd700afff,
0xd700d7ff,
0xd700ffff,
0xd75f00ff,
0xd75f5fff,
0xd75f87ff,
0xd75fafff,
0xd75fd7ff,
0xd75fffff,
0xd78700ff,
0xd7875fff,
0xd78787ff,
0xd787afff,
0xd787d7ff,
0xd787ffff,
0xd7af00ff,
0xd7af5fff,
0xd7af87ff,
0xd7afafff,
0xd7afd7ff,
0xd7afffff,
0xd7d700ff,
0xd7d75fff,
0xd7d787ff,
0xd7d7afff,
0xd7d7d7ff,
0xd7d7ffff,
0xd7ff00ff,
0xd7ff5fff,
0xd7ff87ff,
0xd7ffafff,
0xd7ffd7ff,
0xd7ffffff,
0xff0000ff,
0xff005fff,
0xff0087ff,
0xff00afff,
0xff00d7ff,
0xff00ffff,
0xff5f00ff,
0xff5f5fff,
0xff5f87ff,
0xff5fafff,
0xff5fd7ff,
0xff5fffff,
0xff8700ff,
0xff875fff,
0xff8787ff,
0xff87afff,
0xff87d7ff,
0xff87ffff,
0xffaf00ff,
0xffaf5fff,
0xffaf87ff,
0xffafafff,
0xffafd7ff,
0xffafffff,
0xffd700ff,
0xffd75fff,
0xffd787ff,
0xffd7afff,
0xffd7d7ff,
0xffd7ffff,
0xffff00ff,
0xffff5fff,
0xffff87ff,
0xffffafff,
0xffffd7ff,
0xffffffff,
0x080808ff,
0x121212ff,
0x1c1c1cff,
0x262626ff,
0x303030ff,
0x3a3a3aff,
0x444444ff,
0x4e4e4eff,
0x585858ff,
0x626262ff,
0x6c6c6cff,
0x767676ff,
0x808080ff,
0x8a8a8aff,
0x949494ff,
0x9e9e9eff,
0xa8a8a8ff,
0xb2b2b2ff,
0xbcbcbcff,
0xc6c6c6ff,
0xd0d0d0ff,
0xdadadaff,
0xe4e4e4ff,
0xeeeeeeff,
];

View File

@ -0,0 +1,7 @@
pub mod fpioa;
pub mod gpio;
pub mod gpiohs;
pub mod sleep;
pub mod spi;
pub mod sysctl;
pub mod utils;

View File

@ -0,0 +1,368 @@
use k210_hal::pac;
#[derive(Copy, Clone)]
pub enum function {
JTAG_TCLK = 0, /* JTAG Test Clock */
JTAG_TDI = 1, /* JTAG Test Data In */
JTAG_TMS = 2, /* JTAG Test Mode Select */
JTAG_TDO = 3, /* JTAG Test Data Out */
SPI0_D0 = 4, /* SPI0 Data 0 */
SPI0_D1 = 5, /* SPI0 Data 1 */
SPI0_D2 = 6, /* SPI0 Data 2 */
SPI0_D3 = 7, /* SPI0 Data 3 */
SPI0_D4 = 8, /* SPI0 Data 4 */
SPI0_D5 = 9, /* SPI0 Data 5 */
SPI0_D6 = 10, /* SPI0 Data 6 */
SPI0_D7 = 11, /* SPI0 Data 7 */
SPI0_SS0 = 12, /* SPI0 Chip Select 0 */
SPI0_SS1 = 13, /* SPI0 Chip Select 1 */
SPI0_SS2 = 14, /* SPI0 Chip Select 2 */
SPI0_SS3 = 15, /* SPI0 Chip Select 3 */
SPI0_ARB = 16, /* SPI0 Arbitration */
SPI0_SCLK = 17, /* SPI0 Serial Clock */
UARTHS_RX = 18, /* UART High speed Receiver */
UARTHS_TX = 19, /* UART High speed Transmitter */
RESV6 = 20, /* Reserved function */
RESV7 = 21, /* Reserved function */
CLK_SPI1 = 22, /* Clock SPI1 */
CLK_I2C1 = 23, /* Clock I2C1 */
GPIOHS0 = 24, /* GPIO High speed 0 */
GPIOHS1 = 25, /* GPIO High speed 1 */
GPIOHS2 = 26, /* GPIO High speed 2 */
GPIOHS3 = 27, /* GPIO High speed 3 */
GPIOHS4 = 28, /* GPIO High speed 4 */
GPIOHS5 = 29, /* GPIO High speed 5 */
GPIOHS6 = 30, /* GPIO High speed 6 */
GPIOHS7 = 31, /* GPIO High speed 7 */
GPIOHS8 = 32, /* GPIO High speed 8 */
GPIOHS9 = 33, /* GPIO High speed 9 */
GPIOHS10 = 34, /* GPIO High speed 10 */
GPIOHS11 = 35, /* GPIO High speed 11 */
GPIOHS12 = 36, /* GPIO High speed 12 */
GPIOHS13 = 37, /* GPIO High speed 13 */
GPIOHS14 = 38, /* GPIO High speed 14 */
GPIOHS15 = 39, /* GPIO High speed 15 */
GPIOHS16 = 40, /* GPIO High speed 16 */
GPIOHS17 = 41, /* GPIO High speed 17 */
GPIOHS18 = 42, /* GPIO High speed 18 */
GPIOHS19 = 43, /* GPIO High speed 19 */
GPIOHS20 = 44, /* GPIO High speed 20 */
GPIOHS21 = 45, /* GPIO High speed 21 */
GPIOHS22 = 46, /* GPIO High speed 22 */
GPIOHS23 = 47, /* GPIO High speed 23 */
GPIOHS24 = 48, /* GPIO High speed 24 */
GPIOHS25 = 49, /* GPIO High speed 25 */
GPIOHS26 = 50, /* GPIO High speed 26 */
GPIOHS27 = 51, /* GPIO High speed 27 */
GPIOHS28 = 52, /* GPIO High speed 28 */
GPIOHS29 = 53, /* GPIO High speed 29 */
GPIOHS30 = 54, /* GPIO High speed 30 */
GPIOHS31 = 55, /* GPIO High speed 31 */
GPIO0 = 56, /* GPIO pin 0 */
GPIO1 = 57, /* GPIO pin 1 */
GPIO2 = 58, /* GPIO pin 2 */
GPIO3 = 59, /* GPIO pin 3 */
GPIO4 = 60, /* GPIO pin 4 */
GPIO5 = 61, /* GPIO pin 5 */
GPIO6 = 62, /* GPIO pin 6 */
GPIO7 = 63, /* GPIO pin 7 */
UART1_RX = 64, /* UART1 Receiver */
UART1_TX = 65, /* UART1 Transmitter */
UART2_RX = 66, /* UART2 Receiver */
UART2_TX = 67, /* UART2 Transmitter */
UART3_RX = 68, /* UART3 Receiver */
UART3_TX = 69, /* UART3 Transmitter */
SPI1_D0 = 70, /* SPI1 Data 0 */
SPI1_D1 = 71, /* SPI1 Data 1 */
SPI1_D2 = 72, /* SPI1 Data 2 */
SPI1_D3 = 73, /* SPI1 Data 3 */
SPI1_D4 = 74, /* SPI1 Data 4 */
SPI1_D5 = 75, /* SPI1 Data 5 */
SPI1_D6 = 76, /* SPI1 Data 6 */
SPI1_D7 = 77, /* SPI1 Data 7 */
SPI1_SS0 = 78, /* SPI1 Chip Select 0 */
SPI1_SS1 = 79, /* SPI1 Chip Select 1 */
SPI1_SS2 = 80, /* SPI1 Chip Select 2 */
SPI1_SS3 = 81, /* SPI1 Chip Select 3 */
SPI1_ARB = 82, /* SPI1 Arbitration */
SPI1_SCLK = 83, /* SPI1 Serial Clock */
SPI_SLAVE_D0 = 84, /* SPI Slave Data 0 */
SPI_SLAVE_SS = 85, /* SPI Slave Select */
SPI_SLAVE_SCLK = 86, /* SPI Slave Serial Clock */
I2S0_MCLK = 87, /* I2S0 Master Clock */
I2S0_SCLK = 88, /* I2S0 Serial Clock(BCLK) */
I2S0_WS = 89, /* I2S0 Word Select(LRCLK) */
I2S0_IN_D0 = 90, /* I2S0 Serial Data Input 0 */
I2S0_IN_D1 = 91, /* I2S0 Serial Data Input 1 */
I2S0_IN_D2 = 92, /* I2S0 Serial Data Input 2 */
I2S0_IN_D3 = 93, /* I2S0 Serial Data Input 3 */
I2S0_OUT_D0 = 94, /* I2S0 Serial Data Output 0 */
I2S0_OUT_D1 = 95, /* I2S0 Serial Data Output 1 */
I2S0_OUT_D2 = 96, /* I2S0 Serial Data Output 2 */
I2S0_OUT_D3 = 97, /* I2S0 Serial Data Output 3 */
I2S1_MCLK = 98, /* I2S1 Master Clock */
I2S1_SCLK = 99, /* I2S1 Serial Clock(BCLK) */
I2S1_WS = 100, /* I2S1 Word Select(LRCLK) */
I2S1_IN_D0 = 101, /* I2S1 Serial Data Input 0 */
I2S1_IN_D1 = 102, /* I2S1 Serial Data Input 1 */
I2S1_IN_D2 = 103, /* I2S1 Serial Data Input 2 */
I2S1_IN_D3 = 104, /* I2S1 Serial Data Input 3 */
I2S1_OUT_D0 = 105, /* I2S1 Serial Data Output 0 */
I2S1_OUT_D1 = 106, /* I2S1 Serial Data Output 1 */
I2S1_OUT_D2 = 107, /* I2S1 Serial Data Output 2 */
I2S1_OUT_D3 = 108, /* I2S1 Serial Data Output 3 */
I2S2_MCLK = 109, /* I2S2 Master Clock */
I2S2_SCLK = 110, /* I2S2 Serial Clock(BCLK) */
I2S2_WS = 111, /* I2S2 Word Select(LRCLK) */
I2S2_IN_D0 = 112, /* I2S2 Serial Data Input 0 */
I2S2_IN_D1 = 113, /* I2S2 Serial Data Input 1 */
I2S2_IN_D2 = 114, /* I2S2 Serial Data Input 2 */
I2S2_IN_D3 = 115, /* I2S2 Serial Data Input 3 */
I2S2_OUT_D0 = 116, /* I2S2 Serial Data Output 0 */
I2S2_OUT_D1 = 117, /* I2S2 Serial Data Output 1 */
I2S2_OUT_D2 = 118, /* I2S2 Serial Data Output 2 */
I2S2_OUT_D3 = 119, /* I2S2 Serial Data Output 3 */
RESV0 = 120, /* Reserved function */
RESV1 = 121, /* Reserved function */
RESV2 = 122, /* Reserved function */
RESV3 = 123, /* Reserved function */
RESV4 = 124, /* Reserved function */
RESV5 = 125, /* Reserved function */
I2C0_SCLK = 126, /* I2C0 Serial Clock */
I2C0_SDA = 127, /* I2C0 Serial Data */
I2C1_SCLK = 128, /* I2C1 Serial Clock */
I2C1_SDA = 129, /* I2C1 Serial Data */
I2C2_SCLK = 130, /* I2C2 Serial Clock */
I2C2_SDA = 131, /* I2C2 Serial Data */
CMOS_XCLK = 132, /* DVP System Clock */
CMOS_RST = 133, /* DVP System Reset */
CMOS_PWDN = 134, /* DVP Power Down Mode */
CMOS_VSYNC = 135, /* DVP Vertical Sync */
CMOS_HREF = 136, /* DVP Horizontal Reference output */
CMOS_PCLK = 137, /* Pixel Clock */
CMOS_D0 = 138, /* Data Bit 0 */
CMOS_D1 = 139, /* Data Bit 1 */
CMOS_D2 = 140, /* Data Bit 2 */
CMOS_D3 = 141, /* Data Bit 3 */
CMOS_D4 = 142, /* Data Bit 4 */
CMOS_D5 = 143, /* Data Bit 5 */
CMOS_D6 = 144, /* Data Bit 6 */
CMOS_D7 = 145, /* Data Bit 7 */
SCCB_SCLK = 146, /* SCCB Serial Clock */
SCCB_SDA = 147, /* SCCB Serial Data */
UART1_CTS = 148, /* UART1 Clear To Send */
UART1_DSR = 149, /* UART1 Data Set Ready */
UART1_DCD = 150, /* UART1 Data Carrier Detect */
UART1_RI = 151, /* UART1 Ring Indicator */
UART1_SIR_IN = 152, /* UART1 Serial Infrared Input */
UART1_DTR = 153, /* UART1 Data Terminal Ready */
UART1_RTS = 154, /* UART1 Request To Send */
UART1_OUT2 = 155, /* UART1 User-designated Output 2 */
UART1_OUT1 = 156, /* UART1 User-designated Output 1 */
UART1_SIR_OUT = 157, /* UART1 Serial Infrared Output */
UART1_BAUD = 158, /* UART1 Transmit Clock Output */
UART1_RE = 159, /* UART1 Receiver Output Enable */
UART1_DE = 160, /* UART1 Driver Output Enable */
UART1_RS485_EN = 161, /* UART1 RS485 Enable */
UART2_CTS = 162, /* UART2 Clear To Send */
UART2_DSR = 163, /* UART2 Data Set Ready */
UART2_DCD = 164, /* UART2 Data Carrier Detect */
UART2_RI = 165, /* UART2 Ring Indicator */
UART2_SIR_IN = 166, /* UART2 Serial Infrared Input */
UART2_DTR = 167, /* UART2 Data Terminal Ready */
UART2_RTS = 168, /* UART2 Request To Send */
UART2_OUT2 = 169, /* UART2 User-designated Output 2 */
UART2_OUT1 = 170, /* UART2 User-designated Output 1 */
UART2_SIR_OUT = 171, /* UART2 Serial Infrared Output */
UART2_BAUD = 172, /* UART2 Transmit Clock Output */
UART2_RE = 173, /* UART2 Receiver Output Enable */
UART2_DE = 174, /* UART2 Driver Output Enable */
UART2_RS485_EN = 175, /* UART2 RS485 Enable */
UART3_CTS = 176, /* UART3 Clear To Send */
UART3_DSR = 177, /* UART3 Data Set Ready */
UART3_DCD = 178, /* UART3 Data Carrier Detect */
UART3_RI = 179, /* UART3 Ring Indicator */
UART3_SIR_IN = 180, /* UART3 Serial Infrared Input */
UART3_DTR = 181, /* UART3 Data Terminal Ready */
UART3_RTS = 182, /* UART3 Request To Send */
UART3_OUT2 = 183, /* UART3 User-designated Output 2 */
UART3_OUT1 = 184, /* UART3 User-designated Output 1 */
UART3_SIR_OUT = 185, /* UART3 Serial Infrared Output */
UART3_BAUD = 186, /* UART3 Transmit Clock Output */
UART3_RE = 187, /* UART3 Receiver Output Enable */
UART3_DE = 188, /* UART3 Driver Output Enable */
UART3_RS485_EN = 189, /* UART3 RS485 Enable */
TIMER0_TOGGLE1 = 190, /* TIMER0 Toggle Output 1 */
TIMER0_TOGGLE2 = 191, /* TIMER0 Toggle Output 2 */
TIMER0_TOGGLE3 = 192, /* TIMER0 Toggle Output 3 */
TIMER0_TOGGLE4 = 193, /* TIMER0 Toggle Output 4 */
TIMER1_TOGGLE1 = 194, /* TIMER1 Toggle Output 1 */
TIMER1_TOGGLE2 = 195, /* TIMER1 Toggle Output 2 */
TIMER1_TOGGLE3 = 196, /* TIMER1 Toggle Output 3 */
TIMER1_TOGGLE4 = 197, /* TIMER1 Toggle Output 4 */
TIMER2_TOGGLE1 = 198, /* TIMER2 Toggle Output 1 */
TIMER2_TOGGLE2 = 199, /* TIMER2 Toggle Output 2 */
TIMER2_TOGGLE3 = 200, /* TIMER2 Toggle Output 3 */
TIMER2_TOGGLE4 = 201, /* TIMER2 Toggle Output 4 */
CLK_SPI2 = 202, /* Clock SPI2 */
CLK_I2C2 = 203, /* Clock I2C2 */
INTERNAL0 = 204, /* Internal function signal 0 */
INTERNAL1 = 205, /* Internal function signal 1 */
INTERNAL2 = 206, /* Internal function signal 2 */
INTERNAL3 = 207, /* Internal function signal 3 */
INTERNAL4 = 208, /* Internal function signal 4 */
INTERNAL5 = 209, /* Internal function signal 5 */
INTERNAL6 = 210, /* Internal function signal 6 */
INTERNAL7 = 211, /* Internal function signal 7 */
INTERNAL8 = 212, /* Internal function signal 8 */
INTERNAL9 = 213, /* Internal function signal 9 */
INTERNAL10 = 214, /* Internal function signal 10 */
INTERNAL11 = 215, /* Internal function signal 11 */
INTERNAL12 = 216, /* Internal function signal 12 */
INTERNAL13 = 217, /* Internal function signal 13 */
INTERNAL14 = 218, /* Internal function signal 14 */
INTERNAL15 = 219, /* Internal function signal 15 */
INTERNAL16 = 220, /* Internal function signal 16 */
INTERNAL17 = 221, /* Internal function signal 17 */
CONSTANT = 222, /* Constant function */
INTERNAL18 = 223, /* Internal function signal 18 */
DEBUG0 = 224, /* Debug function 0 */
DEBUG1 = 225, /* Debug function 1 */
DEBUG2 = 226, /* Debug function 2 */
DEBUG3 = 227, /* Debug function 3 */
DEBUG4 = 228, /* Debug function 4 */
DEBUG5 = 229, /* Debug function 5 */
DEBUG6 = 230, /* Debug function 6 */
DEBUG7 = 231, /* Debug function 7 */
DEBUG8 = 232, /* Debug function 8 */
DEBUG9 = 233, /* Debug function 9 */
DEBUG10 = 234, /* Debug function 10 */
DEBUG11 = 235, /* Debug function 11 */
DEBUG12 = 236, /* Debug function 12 */
DEBUG13 = 237, /* Debug function 13 */
DEBUG14 = 238, /* Debug function 14 */
DEBUG15 = 239, /* Debug function 15 */
DEBUG16 = 240, /* Debug function 16 */
DEBUG17 = 241, /* Debug function 17 */
DEBUG18 = 242, /* Debug function 18 */
DEBUG19 = 243, /* Debug function 19 */
DEBUG20 = 244, /* Debug function 20 */
DEBUG21 = 245, /* Debug function 21 */
DEBUG22 = 246, /* Debug function 22 */
DEBUG23 = 247, /* Debug function 23 */
DEBUG24 = 248, /* Debug function 24 */
DEBUG25 = 249, /* Debug function 25 */
DEBUG26 = 250, /* Debug function 26 */
DEBUG27 = 251, /* Debug function 27 */
DEBUG28 = 252, /* Debug function 28 */
DEBUG29 = 253, /* Debug function 29 */
DEBUG30 = 254, /* Debug function 30 */
DEBUG31 = 255, /* Debug function 31 */
}
impl function {
/** GPIOHS pin to function */
pub fn gpiohs(num: u8) -> function {
use function::*;
match num {
0 => GPIOHS0,
1 => GPIOHS1,
2 => GPIOHS2,
3 => GPIOHS3,
4 => GPIOHS4,
5 => GPIOHS5,
6 => GPIOHS6,
7 => GPIOHS7,
8 => GPIOHS8,
9 => GPIOHS9,
10 => GPIOHS10,
11 => GPIOHS11,
12 => GPIOHS12,
13 => GPIOHS13,
14 => GPIOHS14,
15 => GPIOHS15,
16 => GPIOHS16,
17 => GPIOHS17,
18 => GPIOHS18,
19 => GPIOHS19,
20 => GPIOHS20,
21 => GPIOHS21,
22 => GPIOHS22,
23 => GPIOHS23,
24 => GPIOHS24,
25 => GPIOHS25,
26 => GPIOHS26,
27 => GPIOHS27,
28 => GPIOHS28,
29 => GPIOHS29,
30 => GPIOHS30,
31 => GPIOHS31,
_ => panic!("no such GPIO pin"),
}
}
}
#[derive(Copy, Clone)]
pub enum pull {
/** No Pull */
NONE,
/** Pull Down */
DOWN,
/** Pull Up */
UP,
}
/** Defaults per function (from Kendryte fpioa.c) */
#[cfg_attr(rustfmt, rustfmt_skip)]
static FUNCTION_DEFAULTS: &[u32] = &[
0x00900000, 0x00900001, 0x00900002, 0x00001f03, 0x00b03f04, 0x00b03f05, 0x00b03f06, 0x00b03f07,
0x00b03f08, 0x00b03f09, 0x00b03f0a, 0x00b03f0b, 0x00001f0c, 0x00001f0d, 0x00001f0e, 0x00001f0f,
0x03900010, 0x00001f11, 0x00900012, 0x00001f13, 0x00900014, 0x00900015, 0x00001f16, 0x00001f17,
0x00901f18, 0x00901f19, 0x00901f1a, 0x00901f1b, 0x00901f1c, 0x00901f1d, 0x00901f1e, 0x00901f1f,
0x00901f20, 0x00901f21, 0x00901f22, 0x00901f23, 0x00901f24, 0x00901f25, 0x00901f26, 0x00901f27,
0x00901f28, 0x00901f29, 0x00901f2a, 0x00901f2b, 0x00901f2c, 0x00901f2d, 0x00901f2e, 0x00901f2f,
0x00901f30, 0x00901f31, 0x00901f32, 0x00901f33, 0x00901f34, 0x00901f35, 0x00901f36, 0x00901f37,
0x00901f38, 0x00901f39, 0x00901f3a, 0x00901f3b, 0x00901f3c, 0x00901f3d, 0x00901f3e, 0x00901f3f,
0x00900040, 0x00001f41, 0x00900042, 0x00001f43, 0x00900044, 0x00001f45, 0x00b03f46, 0x00b03f47,
0x00b03f48, 0x00b03f49, 0x00b03f4a, 0x00b03f4b, 0x00b03f4c, 0x00b03f4d, 0x00001f4e, 0x00001f4f,
0x00001f50, 0x00001f51, 0x03900052, 0x00001f53, 0x00b03f54, 0x00900055, 0x00900056, 0x00001f57,
0x00001f58, 0x00001f59, 0x0090005a, 0x0090005b, 0x0090005c, 0x0090005d, 0x00001f5e, 0x00001f5f,
0x00001f60, 0x00001f61, 0x00001f62, 0x00001f63, 0x00001f64, 0x00900065, 0x00900066, 0x00900067,
0x00900068, 0x00001f69, 0x00001f6a, 0x00001f6b, 0x00001f6c, 0x00001f6d, 0x00001f6e, 0x00001f6f,
0x00900070, 0x00900071, 0x00900072, 0x00900073, 0x00001f74, 0x00001f75, 0x00001f76, 0x00001f77,
0x00000078, 0x00000079, 0x0000007a, 0x0000007b, 0x0000007c, 0x0000007d, 0x0099107e, 0x0099107f,
0x00991080, 0x00991081, 0x00991082, 0x00991083, 0x00001f84, 0x00001f85, 0x00001f86, 0x00900087,
0x00900088, 0x00900089, 0x0090008a, 0x0090008b, 0x0090008c, 0x0090008d, 0x0090008e, 0x0090008f,
0x00900090, 0x00900091, 0x00993092, 0x00993093, 0x00900094, 0x00900095, 0x00900096, 0x00900097,
0x00900098, 0x00001f99, 0x00001f9a, 0x00001f9b, 0x00001f9c, 0x00001f9d, 0x00001f9e, 0x00001f9f,
0x00001fa0, 0x00001fa1, 0x009000a2, 0x009000a3, 0x009000a4, 0x009000a5, 0x009000a6, 0x00001fa7,
0x00001fa8, 0x00001fa9, 0x00001faa, 0x00001fab, 0x00001fac, 0x00001fad, 0x00001fae, 0x00001faf,
0x009000b0, 0x009000b1, 0x009000b2, 0x009000b3, 0x009000b4, 0x00001fb5, 0x00001fb6, 0x00001fb7,
0x00001fb8, 0x00001fb9, 0x00001fba, 0x00001fbb, 0x00001fbc, 0x00001fbd, 0x00001fbe, 0x00001fbf,
0x00001fc0, 0x00001fc1, 0x00001fc2, 0x00001fc3, 0x00001fc4, 0x00001fc5, 0x00001fc6, 0x00001fc7,
0x00001fc8, 0x00001fc9, 0x00001fca, 0x00001fcb, 0x00001fcc, 0x00001fcd, 0x00001fce, 0x00001fcf,
0x00001fd0, 0x00001fd1, 0x00001fd2, 0x00001fd3, 0x00001fd4, 0x009000d5, 0x009000d6, 0x009000d7,
0x009000d8, 0x009100d9, 0x00991fda, 0x009000db, 0x009000dc, 0x009000dd, 0x000000de, 0x009000df,
0x00001fe0, 0x00001fe1, 0x00001fe2, 0x00001fe3, 0x00001fe4, 0x00001fe5, 0x00001fe6, 0x00001fe7,
0x00001fe8, 0x00001fe9, 0x00001fea, 0x00001feb, 0x00001fec, 0x00001fed, 0x00001fee, 0x00001fef,
0x00001ff0, 0x00001ff1, 0x00001ff2, 0x00001ff3, 0x00001ff4, 0x00001ff5, 0x00001ff6, 0x00001ff7,
0x00001ff8, 0x00001ff9, 0x00001ffa, 0x00001ffb, 0x00001ffc, 0x00001ffd, 0x00001ffe, 0x00001fff,
];
pub fn set_function(number: u32, function: function) {
// TODO: check for overlapping assignments and assign to RESV0 as the Kendryte SDK does?
unsafe {
let ptr = pac::FPIOA::ptr();
(*ptr).io[number as usize].write(|w| w.bits(FUNCTION_DEFAULTS[function as usize]));
}
}
pub fn set_io_pull(number: u32, pull: pull) {
unsafe {
(*pac::FPIOA::ptr()).io[number as usize].modify(|_, w| match pull {
pull::NONE => w.pu().bit(false).pd().bit(false),
pull::DOWN => w.pu().bit(false).pd().bit(true),
pull::UP => w.pu().bit(true).pd().bit(false),
});
}
}

View File

@ -0,0 +1,5 @@
#[derive(Copy, Clone, PartialEq, Eq)]
pub enum direction {
INPUT,
OUTPUT,
}

View File

@ -0,0 +1,25 @@
use k210_hal::pac;
use crate::soc::gpio;
use crate::soc::utils::set_bit;
pub fn set_direction(pin: u8, direction: gpio::direction) {
unsafe {
let ptr = pac::GPIOHS::ptr();
(*ptr)
.output_en
.modify(|r, w| w.bits(set_bit(r.bits(), pin, direction == gpio::direction::OUTPUT)));
(*ptr)
.input_en
.modify(|r, w| w.bits(set_bit(r.bits(), pin, direction == gpio::direction::INPUT)));
}
}
pub fn set_pin(pin: u8, value: bool) {
unsafe {
let ptr = pac::GPIOHS::ptr();
(*ptr)
.output_val
.modify(|r, w| w.bits(set_bit(r.bits(), pin, value)));
}
}

View File

@ -0,0 +1,14 @@
use crate::soc::sysctl;
use riscv::register::mcycle;
pub fn cycle_sleep(n: usize) {
let start = mcycle::read();
while (mcycle::read().wrapping_sub(start)) < n {
// IDLE
}
}
pub fn usleep(n: usize) {
let freq = sysctl::clock_get_freq(sysctl::clock::CPU) as usize;
cycle_sleep(freq * n / 1000000);
}

View File

@ -0,0 +1,135 @@
use k210_hal::pac;
use pac::spi0::ctrlr0;
use pac::spi0::spi_ctrlr0;
use crate::soc::sysctl;
pub fn clk_init() {
sysctl::clock_enable(sysctl::clock::SPI0);
sysctl::clock_set_threshold(sysctl::threshold::SPI0, 0);
unsafe {
(*pac::SPI0::ptr()).baudr.write(|w| w.bits(0x14)); // Set baudrate to some default
}
}
pub fn init(
work_mode: ctrlr0::WORK_MODEW,
frame_format: ctrlr0::FRAME_FORMATW,
data_bit_length: u8,
endian: u32,
instruction_length: u8,
address_length: u8,
wait_cycles: u8,
instruction_address_trans_mode: spi_ctrlr0::AITMW,
tmod: ctrlr0::TMODW,
) {
assert!(data_bit_length >= 4 && data_bit_length <= 32);
assert!(wait_cycles < (1 << 5));
let inst_l: u8 = match instruction_length {
0 => 0,
4 => 1,
8 => 2,
16 => 3,
_ => panic!("unhandled intruction length"),
};
assert!(address_length % 4 == 0 && address_length <= 60);
let addr_l: u8 = address_length / 4;
unsafe {
let ptr = pac::SPI0::ptr();
(*ptr).imr.write(|w| w.bits(0x00));
(*ptr).dmacr.write(|w| w.bits(0x00));
(*ptr).dmatdlr.write(|w| w.bits(0x10));
(*ptr).dmardlr.write(|w| w.bits(0x00));
(*ptr).ser.write(|w| w.bits(0x00));
(*ptr).ssienr.write(|w| w.bits(0x00));
(*ptr).ctrlr0.write(|w| {
w.work_mode()
.variant(work_mode)
.tmod()
.variant(tmod)
.frame_format()
.variant(frame_format)
.data_length()
.bits(data_bit_length - 1)
});
(*ptr).spi_ctrlr0.write(|w| {
w.aitm()
.variant(instruction_address_trans_mode)
.addr_length()
.bits(addr_l)
.inst_length()
.bits(inst_l)
.wait_cycles()
.bits(wait_cycles)
});
(*ptr).endian.write(|w| w.bits(endian));
}
}
pub fn set_clk_rate(spi_clk: u32) -> u32 {
let clock_freq: u32 = sysctl::clock_get_freq(sysctl::clock::SPI0);
let mut spi_baudr = clock_freq / spi_clk;
if spi_baudr < 2 {
spi_baudr = 2;
} else if spi_baudr > 65534 {
spi_baudr = 65534;
}
unsafe {
(*pac::SPI0::ptr()).baudr.write(|w| w.bits(spi_baudr));
}
clock_freq / spi_baudr
}
pub fn send_data<X: Into<u32> + Copy>(chip_select: u32, tx: &[X]) {
unsafe {
let ptr = pac::SPI0::ptr();
(*ptr).ser.write(|w| w.bits(1 << chip_select));
(*ptr).ssienr.write(|w| w.bits(0x01));
// TODO: write this using iterators / slices
let mut i = 0;
let mut tx_len = tx.len();
while tx_len != 0 {
let mut fifo_len = (32 - (*ptr).txflr.read().bits()) as usize;
fifo_len = if fifo_len < tx_len { fifo_len } else { tx_len };
for _ in 0..fifo_len {
(*ptr).dr[0].write(|f| f.bits(tx[i].into()));
i += 1;
}
tx_len -= fifo_len;
}
while ((*ptr).sr.read().bits() & 0x05) != 0x04 {
// IDLE
}
(*ptr).ser.write(|w| w.bits(0x00));
(*ptr).ssienr.write(|w| w.bits(0x00));
}
}
pub fn fill_data(chip_select: u32, value: u32, mut tx_len: usize) {
unsafe {
let ptr = pac::SPI0::ptr();
(*ptr).ser.write(|w| w.bits(1 << chip_select));
(*ptr).ssienr.write(|w| w.bits(0x01));
while tx_len != 0 {
let mut fifo_len = (32 - (*ptr).txflr.read().bits()) as usize;
fifo_len = if fifo_len < tx_len { fifo_len } else { tx_len };
for _ in 0..fifo_len {
(*ptr).dr[0].write(|f| f.bits(value));
}
tx_len -= fifo_len;
}
while ((*ptr).sr.read().bits() & 0x05) != 0x04 {
// IDLE
}
(*ptr).ser.write(|w| w.bits(0x00));
(*ptr).ssienr.write(|w| w.bits(0x00));
}
}

View File

@ -0,0 +1,505 @@
use k210_hal::pac;
use crate::soc::utils::set_bit;
const SYSCTRL_CLOCK_FREQ_IN0: u32 = 26000000;
#[derive(Copy, Clone)]
pub enum pll {
PLL0,
PLL1,
PLL2,
}
#[derive(Copy, Clone)]
pub enum clock_source {
IN0,
PLL0,
PLL1,
PLL2,
ACLK,
}
#[derive(Copy, Clone)]
pub enum clock {
PLL0,
PLL1,
PLL2,
CPU,
SRAM0,
SRAM1,
APB0,
APB1,
APB2,
ROM,
DMA,
AI,
DVP,
FFT,
GPIO,
SPI0,
SPI1,
SPI2,
SPI3,
I2S0,
I2S1,
I2S2,
I2C0,
I2C1,
I2C2,
UART1,
UART2,
UART3,
AES,
FPIOA,
TIMER0,
TIMER1,
TIMER2,
WDT0,
WDT1,
SHA,
OTP,
RTC,
ACLK,
HCLK,
IN0,
}
#[derive(Copy, Clone)]
pub enum threshold {
ACLK,
APB0,
APB1,
APB2,
SRAM0,
SRAM1,
AI,
DVP,
ROM,
SPI0,
SPI1,
SPI2,
SPI3,
TIMER0,
TIMER1,
TIMER2,
I2S0,
I2S1,
I2S2,
I2S0_M,
I2S1_M,
I2S2_M,
I2C0,
I2C1,
I2C2,
WDT0,
WDT1,
}
#[derive(Copy, Clone)]
pub enum clock_select {
PLL0_BYPASS,
PLL1_BYPASS,
PLL2_BYPASS,
PLL2,
ACLK,
SPI3,
TIMER0,
TIMER1,
TIMER2,
SPI3_SAMPLE,
}
#[derive(Copy, Clone)]
pub enum io_power_mode {
V33,
V18,
}
#[derive(Copy, Clone)]
pub enum power_bank {
BANK0 = 0,
BANK1,
BANK2,
BANK3,
BANK4,
BANK5,
BANK6,
BANK7,
}
fn clock_bus_en(clock: clock, en: bool) {
/*
* The timer is under APB0, to prevent apb0_clk_en1 and apb0_clk_en0
* on same register, we split it to peripheral and central two
* registers, to protect CPU close apb0 clock accidentally.
*
* The apb0_clk_en0 and apb0_clk_en1 have same function,
* one of them set, the APB0 clock enable.
*/
/* The APB clock should carefully disable */
if en {
match clock {
/*
* These peripheral devices are under APB0
* GPIO, UART1, UART2, UART3, SPI_SLAVE, I2S0, I2S1,
* I2S2, I2C0, I2C1, I2C2, FPIOA, SHA256, TIMER0,
* TIMER1, TIMER2
*/
clock::GPIO
| clock::SPI2
| clock::I2S0
| clock::I2S1
| clock::I2S2
| clock::I2C0
| clock::I2C1
| clock::I2C2
| clock::UART1
| clock::UART2
| clock::UART3
| clock::FPIOA
| clock::TIMER0
| clock::TIMER1
| clock::TIMER2
| clock::SHA => unsafe {
(*pac::SYSCTL::ptr())
.clk_en_cent
.modify(|_, w| w.apb0_clk_en().bit(en));
},
/*
* These peripheral devices are under APB1
* WDT, AES, OTP, DVP, SYSCTL
*/
clock::AES | clock::WDT0 | clock::WDT1 | clock::OTP | clock::RTC => unsafe {
(*pac::SYSCTL::ptr())
.clk_en_cent
.modify(|_, w| w.apb1_clk_en().bit(en));
},
/*
* These peripheral devices are under APB2
* SPI0, SPI1
*/
clock::SPI0 | clock::SPI1 => unsafe {
(*pac::SYSCTL::ptr())
.clk_en_cent
.modify(|_, w| w.apb2_clk_en().bit(en));
},
_ => {}
}
}
}
fn clock_device_en(clock: clock, en: bool) {
unsafe {
let ptr = pac::SYSCTL::ptr();
match clock {
/*
/*
* These devices are PLL
*/
clock::PLL0 => sysctl->pll0.pll_out_en0 = en;
clock::PLL1 => sysctl->pll1.pll_out_en1 = en;
clock::PLL2 => sysctl->pll2.pll_out_en2 = en;
/*
* These devices are CPU, SRAM, APB bus, ROM, DMA, AI
*/
clock::CPU => sysctl->clk_en_cent.cpu_clk_en = en;
clock::SRAM0 => sysctl->clk_en_cent.sram0_clk_en = en;
clock::SRAM1 => sysctl->clk_en_cent.sram1_clk_en = en;
clock::APB0 => sysctl->clk_en_cent.apb0_clk_en = en;
clock::APB1 => sysctl->clk_en_cent.apb1_clk_en = en;
clock::APB2 => sysctl->clk_en_cent.apb2_clk_en = en;
clock::ROM => sysctl->clk_en_peri.rom_clk_en = en;
clock::DMA => sysctl->clk_en_peri.dma_clk_en = en;
clock::AI => sysctl->clk_en_peri.ai_clk_en = en;
clock::DVP => sysctl->clk_en_peri.dvp_clk_en = en;
clock::FFT => sysctl->clk_en_peri.fft_clk_en = en;
clock::SPI3 => sysctl->clk_en_peri.spi3_clk_en = en;
/*
* These peripheral devices are under APB0
* GPIO, UART1, UART2, UART3, SPI_SLAVE, I2S0, I2S1,
* I2S2, I2C0, I2C1, I2C2, FPIOA, SHA256, TIMER0,
* TIMER1, TIMER2
*/
clock::GPIO => sysctl->clk_en_peri.gpio_clk_en = en;
clock::SPI2 => sysctl->clk_en_peri.spi2_clk_en = en;
clock::I2S0 => sysctl->clk_en_peri.i2s0_clk_en = en;
clock::I2S1 => sysctl->clk_en_peri.i2s1_clk_en = en;
clock::I2S2 => sysctl->clk_en_peri.i2s2_clk_en = en;
clock::I2C0 => sysctl->clk_en_peri.i2c0_clk_en = en;
clock::I2C1 => sysctl->clk_en_peri.i2c1_clk_en = en;
clock::I2C2 => sysctl->clk_en_peri.i2c2_clk_en = en;
clock::UART1 => sysctl->clk_en_peri.uart1_clk_en = en;
clock::UART2 => sysctl->clk_en_peri.uart2_clk_en = en;
clock::UART3 => sysctl->clk_en_peri.uart3_clk_en = en;
clock::FPIOA => sysctl->clk_en_peri.fpioa_clk_en = en;
clock::TIMER0 => sysctl->clk_en_peri.timer0_clk_en = en;
clock::TIMER1 => sysctl->clk_en_peri.timer1_clk_en = en;
clock::TIMER2 => sysctl->clk_en_peri.timer2_clk_en = en;
clock::SHA => sysctl->clk_en_peri.sha_clk_en = en;
/*
* These peripheral devices are under APB1
* WDT, AES, OTP, DVP, SYSCTL
*/
clock::AES => sysctl->clk_en_peri.aes_clk_en = en;
clock::WDT0 => sysctl->clk_en_peri.wdt0_clk_en = en;
clock::WDT1 => sysctl->clk_en_peri.wdt1_clk_en = en;
clock::OTP => sysctl->clk_en_peri.otp_clk_en = en;
clock::RTC => sysctl->clk_en_peri.rtc_clk_en = en;
*/
/*
* These peripheral devices are under APB2
* SPI0, SPI1
*/
clock::SPI0 => (*ptr).clk_en_peri.modify(|_, w| w.spi0_clk_en().bit(en)),
clock::SPI1 => (*ptr).clk_en_peri.modify(|_, w| w.spi1_clk_en().bit(en)),
_ => {}
}
}
}
pub fn clock_enable(clock: clock) {
clock_bus_en(clock, true);
clock_device_en(clock, true);
}
pub fn sysctl_clock_disable(clock: clock) {
clock_bus_en(clock, false);
clock_device_en(clock, false);
}
pub fn clock_set_threshold(which: threshold, threshold: u32) {
unsafe {
let ptr = pac::SYSCTL::ptr();
match which {
/*
/*
* These threshold is 2 bit width
*/
threshold::ACLK =>
sysctl->clk_sel0.aclk_divider_sel = (uint8_t)threshold & 0x03;
/*
* These threshold is 3 bit width
*/
threshold::APB0 =>
sysctl->clk_sel0.apb0_clk_sel = (uint8_t)threshold & 0x07;
threshold::APB1 =>
sysctl->clk_sel0.apb1_clk_sel = (uint8_t)threshold & 0x07;
threshold::APB2 =>
sysctl->clk_sel0.apb2_clk_sel = (uint8_t)threshold & 0x07;
/*
* These threshold is 4 bit width
*/
threshold::SRAM0 =>
sysctl->clk_th0.sram0_gclk_threshold = (uint8_t)threshold & 0x0F;
threshold::SRAM1 =>
sysctl->clk_th0.sram1_gclk_threshold = (uint8_t)threshold & 0x0F;
threshold::AI =>
sysctl->clk_th0.ai_gclk_threshold = (uint8_t)threshold & 0x0F;
threshold::DVP =>
sysctl->clk_th0.dvp_gclk_threshold = (uint8_t)threshold & 0x0F;
threshold::ROM =>
sysctl->clk_th0.rom_gclk_threshold = (uint8_t)threshold & 0x0F;
/*
* These threshold is 8 bit width
*/
*/
threshold::SPI0 => (*ptr)
.clk_th1
.modify(|_, w| w.spi0_clk().bits(threshold as u8)),
/*
threshold::SPI1 =>
sysctl->clk_th1.spi1_clk_threshold = (uint8_t)threshold;
threshold::SPI2 =>
sysctl->clk_th1.spi2_clk_threshold = (uint8_t)threshold;
threshold::SPI3 =>
sysctl->clk_th1.spi3_clk_threshold = (uint8_t)threshold;
threshold::TIMER0 =>
sysctl->clk_th2.timer0_clk_threshold = (uint8_t)threshold;
threshold::TIMER1 =>
sysctl->clk_th2.timer1_clk_threshold = (uint8_t)threshold;
threshold::TIMER2 =>
sysctl->clk_th2.timer2_clk_threshold = (uint8_t)threshold;
threshold::I2S0_M =>
sysctl->clk_th4.i2s0_mclk_threshold = (uint8_t)threshold;
threshold::I2S1_M =>
sysctl->clk_th4.i2s1_mclk_threshold = (uint8_t)threshold;
threshold::I2S2_M =>
sysctl->clk_th5.i2s2_mclk_threshold = (uint8_t)threshold;
threshold::I2C0 =>
sysctl->clk_th5.i2c0_clk_threshold = (uint8_t)threshold;
threshold::I2C1 =>
sysctl->clk_th5.i2c1_clk_threshold = (uint8_t)threshold;
threshold::I2C2 =>
sysctl->clk_th5.i2c2_clk_threshold = (uint8_t)threshold;
threshold::WDT0 =>
sysctl->clk_th6.wdt0_clk_threshold = (uint8_t)threshold;
threshold::WDT1 =>
sysctl->clk_th6.wdt1_clk_threshold = (uint8_t)threshold;
/*
* These threshold is 16 bit width
*/
threshold::I2S0 =>
sysctl->clk_th3.i2s0_clk_threshold = (uint16_t)threshold;
threshold::I2S1 =>
sysctl->clk_th3.i2s1_clk_threshold = (uint16_t)threshold;
threshold::I2S2 =>
sysctl->clk_th4.i2s2_clk_threshold = (uint16_t)threshold;
*/
_ => {}
}
}
}
pub fn clock_get_threshold(which: threshold) -> u32 {
unsafe {
let ptr = pac::SYSCTL::ptr();
match which {
threshold::ACLK => (*ptr).clk_sel0.read().aclk_divider_sel().bits().into(),
threshold::SPI0 => (*ptr).clk_th1.read().spi0_clk().bits().into(),
_ => {
panic!("no such threshold");
}
}
}
}
pub fn set_power_mode(power_bank: power_bank, mode: io_power_mode) {
let power_bank = power_bank as u32;
unsafe {
(*pac::SYSCTL::ptr()).power_sel.modify(|r, w| {
w.bits(set_bit(
r.bits(),
power_bank as u8,
match mode {
io_power_mode::V33 => false,
io_power_mode::V18 => true,
},
))
});
}
}
pub fn set_spi0_dvp_data(status: bool) {
unsafe {
(*pac::SYSCTL::ptr())
.misc
.modify(|_, w| w.spi_dvp_data_enable().bit(status));
}
}
pub fn pll_get_freq(pll: pll) -> u32 {
let freq_in;
let nr;
let nf;
let od;
match pll {
pll::PLL0 => {
freq_in = clock_source_get_freq(clock_source::IN0);
unsafe {
let val = (*pac::SYSCTL::ptr()).pll0.read();
nr = val.clkr().bits() + 1;
nf = val.clkf().bits() + 1;
od = val.clkod().bits() + 1;
}
}
pll::PLL1 => {
freq_in = clock_source_get_freq(clock_source::IN0);
unsafe {
let val = (*pac::SYSCTL::ptr()).pll1.read();
nr = val.clkr().bits() + 1;
nf = val.clkf().bits() + 1;
od = val.clkod().bits() + 1;
}
}
pll::PLL2 => {
/* Get input freq accrording to select register. */
freq_in = clock_source_get_freq(match clock_get_clock_select(clock_select::PLL2) {
0 => clock_source::IN0,
1 => clock_source::PLL0,
2 => clock_source::PLL1,
_ => panic!("unknown PLL2 source"),
});
unsafe {
let val = (*pac::SYSCTL::ptr()).pll2.read();
nr = val.clkr().bits() + 1;
nf = val.clkf().bits() + 1;
od = val.clkod().bits() + 1;
}
}
}
/*
* Get final PLL output freq
* FOUT = FIN / NR * NF / OD
* (rewritten as integer expression)
*/
(((freq_in as u64) * (nf as u64)) / ((nr as u64) * (od as u64))) as u32
}
pub fn clock_source_get_freq(source: clock_source) -> u32 {
match source {
clock_source::IN0 => SYSCTRL_CLOCK_FREQ_IN0,
clock_source::PLL0 => pll_get_freq(pll::PLL0),
clock_source::PLL1 => pll_get_freq(pll::PLL1),
clock_source::PLL2 => pll_get_freq(pll::PLL2),
clock_source::ACLK => clock_get_freq(clock::ACLK),
}
}
pub fn clock_get_clock_select(which: clock_select) -> u8 {
unsafe {
let ptr = pac::SYSCTL::ptr();
match which {
/*
* Select and get clock select value
*/
clock_select::PLL0_BYPASS => (*ptr).pll0.read().bypass().bit().into(),
clock_select::PLL1_BYPASS => (*ptr).pll1.read().bypass().bit().into(),
clock_select::PLL2_BYPASS => (*ptr).pll2.read().bypass().bit().into(),
clock_select::PLL2 => (*ptr).pll2.read().ckin_sel().bits().into(),
clock_select::ACLK => (*ptr).clk_sel0.read().aclk_sel().bit().into(),
clock_select::SPI3 => (*ptr).clk_sel0.read().spi3_clk_sel().bit().into(),
clock_select::TIMER0 => (*ptr).clk_sel0.read().timer0_clk_sel().bit().into(),
clock_select::TIMER1 => (*ptr).clk_sel0.read().timer1_clk_sel().bit().into(),
clock_select::TIMER2 => (*ptr).clk_sel0.read().timer2_clk_sel().bit().into(),
clock_select::SPI3_SAMPLE => (*ptr).clk_sel1.read().spi3_sample_clk_sel().bit().into(),
}
}
}
pub fn clock_get_freq(clock: clock) -> u32 {
match clock {
clock::PLL0 => clock_source_get_freq(clock_source::PLL0),
clock::PLL1 => clock_source_get_freq(clock_source::PLL1),
clock::PLL2 => clock_source_get_freq(clock_source::PLL2),
clock::CPU => match clock_get_clock_select(clock_select::ACLK) {
0 => clock_source_get_freq(clock_source::IN0),
1 => {
clock_source_get_freq(clock_source::PLL0)
/ (2 << clock_get_threshold(threshold::ACLK))
}
_ => panic!("invalid cpu clock select"),
},
clock::SPI0 => {
let source = clock_source_get_freq(clock_source::PLL0);
source / ((clock_get_threshold(threshold::SPI0) + 1) * 2)
}
_ => panic!("not implemented"),
}
}

View File

@ -0,0 +1,7 @@
pub fn set_bit(inval: u32, bit: u8, state: bool) -> u32 {
if state {
inval | (1 << (bit as u32))
} else {
inval & !(1 << (bit as u32))
}
}