├── rust ├── sdlcd │ ├── .gitignore │ ├── Cargo.toml │ ├── README.md │ └── src │ │ └── main.rs ├── sdtest │ ├── README.md │ ├── .gitignore │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── voxel │ ├── .gitignore │ ├── data │ │ ├── map1.dat │ │ └── map15.dat │ ├── src │ │ ├── map_data.rs │ │ └── aligned_as.rs │ ├── README.md │ ├── Cargo.toml │ └── scripts │ │ └── convert.py ├── cryptest │ ├── .gitignore │ ├── Cargo.toml │ └── README.md ├── dvp-ov │ ├── .gitignore │ ├── Cargo.toml │ └── README.md ├── embgfx │ ├── .gitignore │ ├── README.md │ ├── src │ │ └── rust-pride.bmp │ └── Cargo.toml ├── interrupt │ ├── .gitignore │ ├── src │ │ ├── testpage.dat │ │ └── aligned_as.rs │ ├── README.md │ └── Cargo.toml ├── mandelbrot │ ├── .gitignore │ ├── README.md │ ├── Cargo.toml │ └── src │ │ ├── palette.rs │ │ └── main.rs ├── rgbcontrol │ ├── .gitignore │ ├── Cargo.toml │ └── README.md ├── accelerometer │ ├── .gitignore │ ├── README.md │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── buffered-uart │ ├── .gitignore │ ├── README.md │ └── Cargo.toml ├── game-of-life │ ├── .gitignore │ ├── README.md │ ├── Cargo.toml │ └── gen-block-sprite.py ├── gdb_init ├── glyph-mapping │ ├── .gitignore │ ├── README.md │ └── Cargo.toml ├── k210-console │ ├── .gitignore │ ├── scripts │ │ ├── honeybadger160_24.png │ │ ├── create_tables.py │ │ └── gencolorfont.py │ ├── src │ │ ├── lib.rs │ │ ├── coord.rs │ │ ├── lfsr.rs │ │ ├── color.rs │ │ └── palette_xterm256.rs │ ├── data │ │ └── README.md │ ├── README.md │ └── Cargo.toml ├── k210-shared │ ├── .gitignore │ ├── src │ │ ├── util.rs │ │ ├── soc │ │ │ ├── gpio.rs │ │ │ ├── utils.rs │ │ │ ├── sleep.rs │ │ │ ├── gpiohs.rs │ │ │ ├── pwm.rs │ │ │ └── sha256.rs │ │ ├── board.rs │ │ ├── lib.rs │ │ ├── soc.rs │ │ ├── panic.rs │ │ ├── debug.rs │ │ ├── timing.rs │ │ └── board │ │ │ ├── lcd_colors.rs │ │ │ ├── lcd_render.rs │ │ │ └── def.rs │ ├── README.md │ ├── Cargo.toml │ ├── build.rs │ └── memory.x ├── secp256k1-test │ ├── .gitignore │ ├── README.md │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── uart-passthrough │ ├── demo │ │ ├── .gitignore │ │ └── weather.py │ ├── .gitignore │ ├── Cargo.toml │ ├── README.md │ └── src │ │ └── main.rs ├── .gitignore ├── term-server │ ├── .gitignore │ ├── src │ │ └── config.rs.example │ ├── README.md │ └── Cargo.toml ├── weather │ ├── .gitignore │ ├── src │ │ └── config.rs.example │ ├── Cargo.toml │ └── README.md ├── .cargo │ └── config ├── openocd.cfg └── Cargo.toml ├── linux ├── .gitignore ├── Makefile ├── README.md └── term.c ├── util └── esp8266at │ ├── .gitignore │ ├── README.md │ ├── src │ ├── lib.rs │ ├── traits.rs │ ├── util.rs │ └── mainloop.rs │ ├── Cargo.toml │ ├── data │ └── parses.txt │ └── examples │ ├── parsetest.rs │ └── serial.rs ├── src ├── glyph_mapping │ ├── dvp_ov.bin │ ├── README.md │ ├── board_config.h │ ├── ov2640.h │ ├── ov5640.h │ ├── ov5640.c │ ├── lcd.h │ ├── nt35310.c │ ├── lcd.c │ └── nt35310.h ├── dump_otp │ ├── README.md │ └── main.c ├── secp256k1_tests │ ├── scalar_low.h │ ├── num_impl.h │ ├── ecmult_const.h │ ├── scalar_4x64.h │ ├── COPYING │ ├── ecdsa.h │ ├── eckey.h │ ├── testrand.h │ ├── hash.h │ ├── scratch.h │ ├── field_5x52.h │ ├── ecmult_gen.h │ ├── ecmult.h │ ├── num.h │ ├── README.md │ ├── scratch_impl.h │ ├── util.h │ ├── eckey_impl.h │ ├── contrib │ │ ├── lax_der_privatekey_parsing.h │ │ ├── lax_der_parsing.h │ │ └── lax_der_parsing.c.h │ └── scalar_low_impl.h └── secp256k1_bench │ ├── bench.h │ └── util.h ├── COPYING ├── r2 ├── k210_otp │ └── rop.d │ │ ├── arithm │ │ ├── const │ │ ├── mov │ │ ├── nop │ │ └── arithm_ct ├── k210_rom │ └── rop.d │ │ ├── arithm │ │ ├── const │ │ ├── mov │ │ ├── nop │ │ └── arithm_ct └── README.md └── doc ├── onboard.md ├── mmu_notes.md └── otp_layout.md /rust/sdlcd/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk -------------------------------------------------------------------------------- /rust/sdtest/README.md: -------------------------------------------------------------------------------- 1 | # `sdtest` 2 | 3 | -------------------------------------------------------------------------------- /rust/voxel/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk -------------------------------------------------------------------------------- /linux/.gitignore: -------------------------------------------------------------------------------- 1 | esptun 2 | term 3 | *.gdb 4 | -------------------------------------------------------------------------------- /rust/cryptest/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk -------------------------------------------------------------------------------- /rust/dvp-ov/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk -------------------------------------------------------------------------------- /rust/embgfx/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk -------------------------------------------------------------------------------- /rust/interrupt/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk -------------------------------------------------------------------------------- /rust/interrupt/src/testpage.dat: -------------------------------------------------------------------------------- 1 | 12345678 2 | -------------------------------------------------------------------------------- /rust/mandelbrot/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk -------------------------------------------------------------------------------- /rust/rgbcontrol/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk -------------------------------------------------------------------------------- /rust/sdtest/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk -------------------------------------------------------------------------------- /rust/accelerometer/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk -------------------------------------------------------------------------------- /rust/buffered-uart/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk -------------------------------------------------------------------------------- /rust/game-of-life/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk -------------------------------------------------------------------------------- /rust/gdb_init: -------------------------------------------------------------------------------- 1 | target remote :3333 2 | load 3 | c 4 | -------------------------------------------------------------------------------- /rust/glyph-mapping/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk -------------------------------------------------------------------------------- /rust/k210-console/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk -------------------------------------------------------------------------------- /rust/k210-shared/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk -------------------------------------------------------------------------------- /rust/secp256k1-test/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk -------------------------------------------------------------------------------- /rust/uart-passthrough/demo/.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ 2 | -------------------------------------------------------------------------------- /rust/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | Cargo.lock 4 | -------------------------------------------------------------------------------- /rust/buffered-uart/README.md: -------------------------------------------------------------------------------- 1 | # `buffered-uart` 2 | 3 | -------------------------------------------------------------------------------- /rust/uart-passthrough/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk -------------------------------------------------------------------------------- /util/esp8266at/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | Cargo.lock 4 | -------------------------------------------------------------------------------- /rust/k210-shared/src/util.rs: -------------------------------------------------------------------------------- 1 | /** Internal utilities. */ 2 | pub mod filters; 3 | -------------------------------------------------------------------------------- /rust/embgfx/README.md: -------------------------------------------------------------------------------- 1 | # `embgfx` 2 | 3 | Experiments with `embedded-graphics` crate. 4 | -------------------------------------------------------------------------------- /rust/mandelbrot/README.md: -------------------------------------------------------------------------------- 1 | # `mandelbrot` 2 | 3 | Obligatory Mandelbrot fractal zoom. 4 | -------------------------------------------------------------------------------- /rust/interrupt/README.md: -------------------------------------------------------------------------------- 1 | # `interrupt` 2 | 3 | Test for interrupts, exceptions and the K210 MMU. 4 | -------------------------------------------------------------------------------- /rust/term-server/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | # Do not check in secrets file 4 | config.rs 5 | -------------------------------------------------------------------------------- /rust/weather/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | # Do not check in secrets file 4 | config.rs 5 | -------------------------------------------------------------------------------- /rust/voxel/data/map1.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laanwj/k210-sdk-stuff/HEAD/rust/voxel/data/map1.dat -------------------------------------------------------------------------------- /rust/voxel/data/map15.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laanwj/k210-sdk-stuff/HEAD/rust/voxel/data/map15.dat -------------------------------------------------------------------------------- /src/glyph_mapping/dvp_ov.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laanwj/k210-sdk-stuff/HEAD/src/glyph_mapping/dvp_ov.bin -------------------------------------------------------------------------------- /rust/embgfx/src/rust-pride.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laanwj/k210-sdk-stuff/HEAD/rust/embgfx/src/rust-pride.bmp -------------------------------------------------------------------------------- /util/esp8266at/README.md: -------------------------------------------------------------------------------- 1 | # `esp8266at` 2 | 3 | A crate for communicating with WiFi using the ESP8266 using AT commands. 4 | 5 | -------------------------------------------------------------------------------- /rust/k210-console/scripts/honeybadger160_24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laanwj/k210-sdk-stuff/HEAD/rust/k210-console/scripts/honeybadger160_24.png -------------------------------------------------------------------------------- /rust/secp256k1-test/README.md: -------------------------------------------------------------------------------- 1 | # `secp256k1-test` 2 | 3 | Test for using the elliptic curve cryptography library `secp256k1` from rust on a RISC-V device. 4 | -------------------------------------------------------------------------------- /src/glyph_mapping/README.md: -------------------------------------------------------------------------------- 1 | glyph_mapping 2 | ============== 3 | 4 | Display the real-time image from ov5640 passed through a glyph-mapping algorithm. 5 | -------------------------------------------------------------------------------- /rust/k210-shared/src/soc/gpio.rs: -------------------------------------------------------------------------------- 1 | //! GPIO peripheral 2 | #[derive(Copy, Clone, PartialEq, Eq)] 3 | pub enum direction { 4 | INPUT, 5 | OUTPUT, 6 | } 7 | 8 | // TODO 9 | -------------------------------------------------------------------------------- /rust/k210-console/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![no_std] 2 | 3 | pub mod color; 4 | pub mod console; 5 | pub mod coord; 6 | pub mod cp437; 7 | pub mod cp437_8x8; 8 | pub mod palette_xterm256; 9 | -------------------------------------------------------------------------------- /rust/accelerometer/README.md: -------------------------------------------------------------------------------- 1 | # `accelerometer` 2 | 3 | Read measurements from MSA300 accelerometer. Display a dot on the screen to visualize the current orientation 4 | and magnitude. 5 | -------------------------------------------------------------------------------- /rust/voxel/src/map_data.rs: -------------------------------------------------------------------------------- 1 | pub static WIDTH: u32 = 256; 2 | pub static HEIGHT: u32 = 256; 3 | pub static VOXEL_MAP: &'static [u8] = include_bytes_align_as!(u16, "../data/map15.dat"); 4 | -------------------------------------------------------------------------------- /rust/k210-shared/src/board.rs: -------------------------------------------------------------------------------- 1 | pub mod def; 2 | pub mod lcd; 3 | pub mod lcd_colors; 4 | pub mod lcd_render; 5 | pub mod msa300; 6 | pub mod ns2009; 7 | pub mod ov2640; 8 | pub mod sdcard; 9 | -------------------------------------------------------------------------------- /rust/glyph-mapping/README.md: -------------------------------------------------------------------------------- 1 | # `glyph-mapping` 2 | 3 | Display the real-time image from ov5640 passed through a glyph-mapping algorithm. 4 | 5 | This samples the camera in planar R8G8B8 format. 6 | -------------------------------------------------------------------------------- /rust/k210-console/data/README.md: -------------------------------------------------------------------------------- 1 | Based on https://github.com/nabijaczleweli/codepage-437/blob/master/dialect-specs/cp437_wingdings/values.tsv by nabijaczleweli. 2 | 3 | - Changed 0xFF to WHITE SQUARE 4 | -------------------------------------------------------------------------------- /rust/weather/src/config.rs.example: -------------------------------------------------------------------------------- 1 | /** Secrets */ 2 | 3 | /** Access point name */ 4 | pub const APNAME: &str = ""; 5 | 6 | /** Access point password */ 7 | pub const APPASS: &str = ""; 8 | 9 | -------------------------------------------------------------------------------- /rust/term-server/src/config.rs.example: -------------------------------------------------------------------------------- 1 | /** Secrets */ 2 | 3 | /** Access point name */ 4 | pub const APNAME: &str = ""; 5 | 6 | /** Access point password */ 7 | pub const APPASS: &str = ""; 8 | 9 | -------------------------------------------------------------------------------- /rust/game-of-life/README.md: -------------------------------------------------------------------------------- 1 | # `game-of-life` 2 | 3 | "Game of life" cellular automata simulation. The state can be manipulated through the touch screen. 4 | The amount of pressure applied determines the radius of the state change. 5 | -------------------------------------------------------------------------------- /rust/term-server/README.md: -------------------------------------------------------------------------------- 1 | # `term-server` 2 | 3 | Uses the ESP8285 WiFi chip of the Maix Go to listen for incoming connections, 4 | displaying the data on the terminal. 5 | 6 | See the `weather` demo for configuration instructions. 7 | -------------------------------------------------------------------------------- /rust/k210-console/README.md: -------------------------------------------------------------------------------- 1 | # `k210-console` 2 | 3 | Console emulator written in rust for the Maix Go. 4 | 5 | Barely functional at the moment. This is really a test for some functionality 6 | like SPI and driving the display from Rust. 7 | -------------------------------------------------------------------------------- /rust/k210-shared/README.md: -------------------------------------------------------------------------------- 1 | # `k210-console` 2 | 3 | Console emulator written in rust for the Maix Go. 4 | 5 | Barely functional at the moment. This is really a test for some functionality 6 | like SPI and driving the display from Rust. 7 | -------------------------------------------------------------------------------- /util/esp8266at/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![cfg_attr(not(feature = "std"), no_std)] 2 | #[macro_use] 3 | extern crate nom; 4 | 5 | pub mod handler; 6 | #[cfg(feature = "std")] 7 | pub mod mainloop; 8 | pub mod response; 9 | pub mod traits; 10 | mod util; 11 | -------------------------------------------------------------------------------- /rust/voxel/README.md: -------------------------------------------------------------------------------- 1 | # `voxel` 2 | 3 | Voxel-based landscape rendering. 4 | 5 | Inspired by thie tweet: https://twitter.com/pimoroni/status/1215944540147851264 6 | Based on Sebastian Macke's excellent examples in https://github.com/s-macke/VoxelSpace 7 | 8 | -------------------------------------------------------------------------------- /rust/.cargo/config: -------------------------------------------------------------------------------- 1 | [target.riscv64gc-unknown-none-elf] 2 | runner = "riscv64-unknown-elf-gdb -x gdb_init" 3 | rustflags = [ 4 | "-C", "link-arg=-Tmemory.x", 5 | "-C", "link-arg=-Tlink.x", 6 | ] 7 | 8 | [build] 9 | target = "riscv64gc-unknown-none-elf" 10 | -------------------------------------------------------------------------------- /rust/k210-shared/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![allow(dead_code)] 2 | #![allow(non_snake_case)] 3 | #![allow(non_camel_case_types)] 4 | #![no_std] 5 | 6 | pub mod board; 7 | #[cfg(not(test))] 8 | pub mod debug; 9 | pub mod panic; 10 | pub mod soc; 11 | pub mod timing; 12 | mod util; 13 | -------------------------------------------------------------------------------- /rust/k210-shared/src/soc.rs: -------------------------------------------------------------------------------- 1 | pub mod aes; 2 | pub mod dmac; 3 | pub mod dvp; 4 | pub mod fpioa; 5 | pub mod gpio; 6 | pub mod gpiohs; 7 | pub mod i2c; 8 | pub mod pwm; 9 | pub mod sha256; 10 | pub mod sleep; 11 | pub mod spi; 12 | pub mod sysctl; 13 | pub mod utils; 14 | -------------------------------------------------------------------------------- /rust/k210-console/src/coord.rs: -------------------------------------------------------------------------------- 1 | /** Integer screen coordinate. */ 2 | #[derive(Copy, Clone)] 3 | pub struct Coord { 4 | pub x: u16, 5 | pub y: u16, 6 | } 7 | 8 | impl Coord { 9 | pub fn new(x: u16, y: u16) -> Self { 10 | Self { x, y } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /rust/k210-shared/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "k210-shared" 3 | version = "0.1.0" 4 | authors = ["W.J. van der Laan "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | k210-hal = "0.2.0" 9 | libm = "0.1" 10 | riscv = "0.5" 11 | riscv-rt = "0.7" 12 | -------------------------------------------------------------------------------- /rust/openocd.cfg: -------------------------------------------------------------------------------- 1 | transport select jtag 2 | adapter_khz 1000 3 | 4 | set _CHIPNAME riscv 5 | jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x04e4796b 6 | 7 | set _TARGETNAME $_CHIPNAME.cpu 8 | target create $_TARGETNAME riscv -chain-position $_TARGETNAME 9 | 10 | init 11 | halt 12 | -------------------------------------------------------------------------------- /rust/dvp-ov/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "dvp-ov" 3 | version = "0.1.0" 4 | authors = ["W.J. van der Laan "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | riscv-rt = "0.7" 9 | k210-hal = "0.2.0" 10 | riscv = "0.5" 11 | k210-shared = { path = "../k210-shared" } 12 | -------------------------------------------------------------------------------- /rust/mandelbrot/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "mandelbrot" 3 | version = "0.1.0" 4 | authors = ["W.J. van der Laan "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | riscv-rt = "0.7" 9 | k210-hal = "0.2.0" 10 | riscv = "0.5" 11 | k210-shared = { path = "../k210-shared" } 12 | -------------------------------------------------------------------------------- /rust/rgbcontrol/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rgbcontrol" 3 | version = "0.1.0" 4 | authors = ["W.J. van der Laan "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | k210-hal = "0.2.0" 9 | k210-shared = { path = "../k210-shared" } 10 | riscv = "0.5" 11 | riscv-rt = "0.7" 12 | -------------------------------------------------------------------------------- /rust/game-of-life/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "game-of-life" 3 | version = "0.1.0" 4 | authors = ["W.J. van der Laan "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | riscv-rt = "0.7" 9 | k210-hal = "0.2.0" 10 | riscv = "0.5" 11 | k210-shared = { path = "../k210-shared" } 12 | -------------------------------------------------------------------------------- /rust/k210-console/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "k210-console" 3 | version = "0.1.0" 4 | authors = ["W.J. van der Laan "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | riscv-rt = "0.7" 9 | k210-hal = "0.2.0" 10 | riscv = "0.5" 11 | k210-shared = { path = "../k210-shared" } 12 | -------------------------------------------------------------------------------- /rust/sdlcd/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "sdlcd" 3 | version = "0.1.0" 4 | authors = ["W.J. van der Laan "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | nb = "0.1.1" 9 | riscv-rt = "0.7" 10 | k210-hal = "0.2.0" 11 | riscv = "0.5" 12 | k210-shared = { path = "../k210-shared" } 13 | -------------------------------------------------------------------------------- /rust/sdtest/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "sdtest" 3 | version = "0.1.0" 4 | authors = ["W.J. van der Laan "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | nb = "0.1.1" 9 | riscv-rt = "0.7" 10 | k210-hal = "0.2.0" 11 | riscv = "0.5" 12 | k210-shared = { path = "../k210-shared" } 13 | -------------------------------------------------------------------------------- /rust/voxel/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "voxel" 3 | version = "0.1.0" 4 | authors = ["W.J. van der Laan "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | riscv-rt = "0.7" 9 | k210-hal = "0.2.0" 10 | riscv = "0.5" 11 | k210-shared = { path = "../k210-shared" } 12 | libm = "0.1" 13 | -------------------------------------------------------------------------------- /rust/accelerometer/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "accelerometer" 3 | version = "0.1.0" 4 | authors = ["W.J. van der Laan "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | riscv-rt = "0.7" 9 | k210-hal = "0.2.0" 10 | riscv = "0.5" 11 | libm = "0.1" 12 | k210-shared = { path = "../k210-shared" } 13 | -------------------------------------------------------------------------------- /rust/uart-passthrough/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "uart-passthrough" 3 | version = "0.1.0" 4 | authors = ["W.J. van der Laan "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | nb = "0.1.1" 9 | riscv-rt = "0.7" 10 | k210-hal = "0.2.0" 11 | riscv = "0.5" 12 | k210-shared = { path = "../k210-shared" } 13 | -------------------------------------------------------------------------------- /rust/dvp-ov/README.md: -------------------------------------------------------------------------------- 1 | # `dvp-ov` 2 | 3 | A straightforward passthrough test for video handling, based on `dvp_ov` in the 4 | SDK: read frames from the OV2640 image sensor and display them on the LCD. 5 | 6 | The performance is likely worse (don't know by how much) than the C 7 | implementation because currently, no interrupts and DMA are used. 8 | -------------------------------------------------------------------------------- /rust/interrupt/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "interrupt" 3 | version = "0.1.0" 4 | authors = ["W.J. van der Laan "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | riscv-rt = "0.7" 9 | k210-hal = "0.2.0" 10 | riscv = { version = "0.5", features = ["inline-asm"] } 11 | k210-shared = { path = "../k210-shared" } 12 | -------------------------------------------------------------------------------- /linux/Makefile: -------------------------------------------------------------------------------- 1 | CROSS ?= /opt/riscv64-uclibc/bin/riscv64-buildroot-linux-uclibc- 2 | CFLAGS = -fPIC -Wl,-elf2flt=-r -Wall -Os -g 3 | BINARIES = term esptun 4 | 5 | all: $(BINARIES) 6 | 7 | clean: 8 | rm -f $(BINARIES) 9 | 10 | term: term.c 11 | ${CROSS}gcc $< -o $@ $(CFLAGS) 12 | 13 | esptun: esptun.c 14 | ${CROSS}gcc $< -o $@ $(CFLAGS) 15 | 16 | -------------------------------------------------------------------------------- /rust/glyph-mapping/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "glyph-mapping" 3 | version = "0.1.0" 4 | authors = ["W.J. van der Laan "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | riscv-rt = "0.7" 9 | k210-hal = "0.2.0" 10 | riscv = "0.5" 11 | k210-shared = { path = "../k210-shared" } 12 | k210-console = { path = "../k210-console" } 13 | -------------------------------------------------------------------------------- /rust/buffered-uart/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "buffered-uart" 3 | version = "0.1.0" 4 | authors = ["W.J. van der Laan "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | bare-metal = "0.2.0" 9 | riscv-rt = "0.7" 10 | k210-hal = "0.2.0" 11 | riscv = { version = "0.5", features = ["inline-asm"] } 12 | k210-shared = { path = "../k210-shared" } 13 | -------------------------------------------------------------------------------- /rust/embgfx/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "embgfx" 3 | version = "0.1.0" 4 | authors = ["W.J. van der Laan "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | riscv-rt = "0.7" 9 | k210-hal = "0.2.0" 10 | riscv = "0.5" 11 | libm = "0.1" 12 | k210-shared = { path = "../k210-shared" } 13 | embedded-graphics = { version = "=0.6.0-alpha.2", features = ['bmp'] } 14 | -------------------------------------------------------------------------------- /rust/rgbcontrol/README.md: -------------------------------------------------------------------------------- 1 | # `rgbcontrol` 2 | 3 | Control the color of the RGB LED from the touch screen. 4 | 5 | Displays a HSV color picker and sets sets the color of the LED based on the 6 | position that is touched, with the intensity derived from the touch pressure. 7 | 8 | Exercises the PWM functionality. Channel 1-3 of TIMER0 are assigned to the 9 | R, G and B pins. 10 | 11 | -------------------------------------------------------------------------------- /rust/secp256k1-test/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "secp256k1-test" 3 | version = "0.1.0" 4 | authors = ["W.J. van der Laan "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | riscv-rt = "0.7" 9 | k210-hal = "0.2.0" 10 | riscv = "0.5" 11 | k210-shared = { path = "../k210-shared" } 12 | secp256k1 = { version = "0.17", default-features = false, features = ['lowmemory'] } 13 | -------------------------------------------------------------------------------- /rust/k210-shared/src/soc/utils.rs: -------------------------------------------------------------------------------- 1 | //! Miscelleneous utilities for SoC functions (private) 2 | 3 | pub fn set_bit(inval: u32, bit: u8, state: bool) -> u32 { 4 | if state { 5 | inval | (1 << u32::from(bit)) 6 | } else { 7 | inval & !(1 << u32::from(bit)) 8 | } 9 | } 10 | 11 | pub fn get_bit(inval: u32, bit: u8) -> bool { 12 | (inval & (1 << u32::from(bit))) != 0 13 | } 14 | -------------------------------------------------------------------------------- /rust/cryptest/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cryptest" 3 | version = "0.1.0" 4 | authors = ["W.J. van der Laan "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | k210-hal = "0.2.0" 9 | k210-shared = { path = "../k210-shared" } 10 | riscv = "0.5" 11 | riscv-rt = "0.7" 12 | hex-literal = "0.2" 13 | sha2 = { version = "0.8", default-features = false } 14 | aes-soft = { version = "0.3" } 15 | -------------------------------------------------------------------------------- /rust/sdlcd/README.md: -------------------------------------------------------------------------------- 1 | # `sdlcd` 2 | 3 | This example streams raw data from the SD card to the LCD, frame by frame. 4 | 5 | The following commands can be used to scale and transcode a video to 6 | `320x240xRGB565`, and write it to a SD card: 7 | 8 | ```sh 9 | ffmpeg -i input.mp4 -vf scale=320:240 -vcodec rawvideo -f rawvideo -pix_fmt rgb565le test.vid 10 | dd if=test.vid of=/dev/mmcblk… bs=153600 11 | ``` 12 | -------------------------------------------------------------------------------- /rust/cryptest/README.md: -------------------------------------------------------------------------------- 1 | # `cryptest` 2 | 3 | Test and benchmark the cryptographic acceleration engines of the K210 compared 4 | to rust CPU implementations. 5 | 6 | Example benchmark output: 7 | 8 | ``` 9 | SHA256 hw (4194240 bytes): MATCH (12542 kB/s) 10 | SHA256 hw, 32bit (4194240 bytes): MATCH (18965 kB/s) 11 | SHA256 sw (4194240 bytes): MATCH (5087 kB/s) 12 | AES128 hw, 32bit (262144 bytes): (6247 kB/s) 13 | AES128 sw (262144 bytes): (394 kB/s) 14 | ``` 15 | -------------------------------------------------------------------------------- /rust/k210-shared/src/soc/sleep.rs: -------------------------------------------------------------------------------- 1 | //! Utilities for sleeping short timespans 2 | use crate::soc::sysctl; 3 | use riscv::register::mcycle; 4 | 5 | pub fn cycle_sleep(n: usize) { 6 | let start = mcycle::read(); 7 | while (mcycle::read().wrapping_sub(start)) < n { 8 | // IDLE 9 | } 10 | } 11 | 12 | pub fn usleep(n: usize) { 13 | let freq = sysctl::clock_get_freq(sysctl::clock::CPU) as usize; 14 | cycle_sleep(freq * n / 1000000); 15 | } 16 | -------------------------------------------------------------------------------- /rust/k210-shared/build.rs: -------------------------------------------------------------------------------- 1 | use std::{env, fs}; 2 | use std::path::PathBuf; 3 | use std::io::Write; 4 | 5 | fn main() { 6 | // Put the linker script somewhere the linker can find it 7 | let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); 8 | println!("cargo:rustc-link-search={}", out_dir.display()); 9 | 10 | fs::File::create(out_dir.join("memory.x")).unwrap() 11 | .write_all(include_bytes!("memory.x")).unwrap(); 12 | println!("cargo:rerun-if-changed=memory.x"); 13 | } 14 | -------------------------------------------------------------------------------- /rust/weather/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "weather" 3 | version = "0.1.0" 4 | authors = ["W.J. van der Laan "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | embedded-hal = { version = "0.2.1", features = ["unproven"] } 9 | nb = "0.1.1" 10 | riscv-rt = "0.7" 11 | k210-hal = "0.2.0" 12 | riscv = "0.5" 13 | k210-shared = { path = "../k210-shared" } 14 | k210-console = { path = "../k210-console" } 15 | esp8266at = { path = "../../util/esp8266at", default-features = false } 16 | buffered-uart = { path = "../buffered-uart" } 17 | -------------------------------------------------------------------------------- /rust/term-server/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "term-server" 3 | version = "0.1.0" 4 | authors = ["W.J. van der Laan "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | embedded-hal = { version = "0.2.1", features = ["unproven"] } 9 | nb = "0.1.1" 10 | riscv-rt = "0.7" 11 | k210-hal = "0.2.0" 12 | riscv = "0.5" 13 | k210-shared = { path = "../k210-shared" } 14 | k210-console = { path = "../k210-console" } 15 | esp8266at = { path = "../../util/esp8266at", default-features = false } 16 | buffered-uart = { path = "../buffered-uart" } 17 | -------------------------------------------------------------------------------- /rust/weather/README.md: -------------------------------------------------------------------------------- 1 | # `weather` 2 | 3 | Uses the ESP8285 WiFi chip of the Maix Go to fetch weather data from 4 | [wttr.in](https://wttr.in) and print it to the display using `k210-console`. 5 | 6 | As it needs to connect to an access point first, this needs configuration of one 7 | to connect to in `src/config.rs`: 8 | 9 | ```bash 10 | cp src/config.rs.example src/config.rs 11 | vim src/config.rs # ... 12 | ``` 13 | 14 | Set `` and `` accordingly. Do not check in `src/config.rs` ! 15 | (gitignore settings should prevent this) 16 | -------------------------------------------------------------------------------- /rust/k210-shared/memory.x: -------------------------------------------------------------------------------- 1 | INCLUDE memory-k210.x 2 | 3 | REGION_ALIAS("REGION_TEXT", SRAM); 4 | REGION_ALIAS("REGION_RODATA", SRAM); 5 | REGION_ALIAS("REGION_DATA", SRAM); 6 | REGION_ALIAS("REGION_BSS", SRAM); 7 | REGION_ALIAS("REGION_HEAP", SRAM); 8 | REGION_ALIAS("REGION_STACK", SRAM); 9 | 10 | /* memory-k210.x already sets _max_hart_id = 1 for us. */ 11 | 12 | /* Reserve 4MiB of memory for a heap. This is not used in most of the 13 | programs. 14 | */ 15 | _heap_size = 4M; 16 | 17 | /* 128Kib of stack ought to be enough for anyone. */ 18 | _hart_stack_size = 128K; 19 | -------------------------------------------------------------------------------- /src/dump_otp/README.md: -------------------------------------------------------------------------------- 1 | otp-dump 2 | ======== 3 | 4 | Dump the contents of OTP (One-Time Programmable memory) in hexadecimal format 5 | to serial. 6 | 7 | Output is in Intel HEX format. Make sure your parser ignores non-':' prefixed lines 8 | as there can be warnings, or do 9 | 10 | grep "^:" /tmp/otp1.txt > /tmp/otp1.ihx 11 | objcopy -I ihex -O binary /tmp/otp1.ihx kendryte_otp1.dat 12 | 13 | Note that the OTP contains a serial number (at least 0x3d9c..0x3d9f seem to 14 | differ between boards) so it'd be wise to treat the output as 15 | privacy-sensitive. 16 | -------------------------------------------------------------------------------- /util/esp8266at/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "esp8266at" 3 | version = "0.1.0" 4 | authors = ["Wladimir J. van der Laan "] 5 | edition = "2018" 6 | 7 | [features] 8 | std = [] 9 | default = ["std"] 10 | 11 | [dependencies] 12 | nom = { version = "5", default-features = false } 13 | 14 | [dev-dependencies] 15 | clap = "2" 16 | serialport = { version = "3", default-features = false } 17 | arrayvec = "0.4" 18 | 19 | [[example]] 20 | name = "parsetest" 21 | required-features = ["std"] 22 | 23 | [[example]] 24 | name = "serial" 25 | required-features = ["std"] 26 | -------------------------------------------------------------------------------- /rust/k210-console/src/lfsr.rs: -------------------------------------------------------------------------------- 1 | /** 32-bit LFSR for "random" output */ 2 | pub struct LFSR { 3 | state: u32, 4 | feedback: u32, 5 | } 6 | 7 | impl LFSR { 8 | pub fn new() -> LFSR { 9 | LFSR { 10 | state: 0x12345678, 11 | feedback: 0xf00f00f0, // LFSR period 0xf7ffffe0 12 | } 13 | } 14 | 15 | pub fn next(&mut self) -> u32 { 16 | let rv = self.state; 17 | let lsb = (self.state & 1) != 0; 18 | self.state >>= 1; 19 | if lsb { 20 | self.state ^= self.feedback; 21 | } 22 | rv 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/glyph_mapping/board_config.h: -------------------------------------------------------------------------------- 1 | #ifndef _BOARD_CONFIG_ 2 | #define _BOARD_CONFIG_ 3 | 4 | #define OV5640 0 5 | #define OV2640 1 6 | 7 | #define BOARD_KD233 0 8 | #define BOARD_LICHEEDAN 1 9 | #define BOARD_K61 0 10 | 11 | #if (OV5640 && OV2640) || (!OV5640 && !OV2640) 12 | #error ov sensor only choose one 13 | #endif 14 | 15 | #if (BOARD_LICHEEDAN && BOARD_KD233) || (BOARD_LICHEEDAN && BOARD_K61) || (BOARD_K61 && BOARD_KD233) || (!BOARD_LICHEEDAN && !BOARD_KD233 && !BOARD_K61) 16 | #error board only choose one 17 | #endif 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /src/secp256k1_tests/scalar_low.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2015 Andrew Poelstra * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_SCALAR_REPR_H 8 | #define SECP256K1_SCALAR_REPR_H 9 | 10 | #include 11 | 12 | /** A scalar modulo the group order of the secp256k1 curve. */ 13 | typedef uint32_t secp256k1_scalar; 14 | 15 | #endif /* SECP256K1_SCALAR_REPR_H */ 16 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | Copyright 2019 W. J. van der Laan 2 | 3 | Permission to use, copy, modify, and/or distribute this software for any 4 | purpose with or without fee is hereby granted, provided that the above 5 | copyright notice and this permission notice appear in all copies. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 | -------------------------------------------------------------------------------- /src/secp256k1_tests/num_impl.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2013, 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_NUM_IMPL_H 8 | #define SECP256K1_NUM_IMPL_H 9 | 10 | #if defined HAVE_CONFIG_H 11 | #include "libsecp256k1-config.h" 12 | #endif 13 | 14 | #include "num.h" 15 | 16 | #if defined(USE_NUM_GMP) 17 | #include "num_gmp_impl.h" 18 | #elif defined(USE_NUM_NONE) 19 | /* Nothing. */ 20 | #else 21 | #error "Please select num implementation" 22 | #endif 23 | 24 | #endif /* SECP256K1_NUM_IMPL_H */ 25 | -------------------------------------------------------------------------------- /util/esp8266at/src/traits.rs: -------------------------------------------------------------------------------- 1 | use core::fmt; 2 | #[cfg(feature = "std")] 3 | use std::io; 4 | 5 | /** The trait that's required of anything acting as serial port writer. 6 | * It is much simpler than io::Write. The reason for implementing our own trait here 7 | * is that this is compatible with no_std. 8 | */ 9 | pub trait Write { 10 | type Error: fmt::Debug; 11 | 12 | /** Write all bytes from the buffer, or fail */ 13 | fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error>; 14 | } 15 | 16 | /** Implement our write trait for everything that implements io::Write */ 17 | #[cfg(feature = "std")] 18 | impl Write for X 19 | where 20 | X: io::Write, 21 | { 22 | type Error = io::Error; 23 | 24 | fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error> { 25 | (self as &mut dyn io::Write).write_all(buf) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/secp256k1_tests/ecmult_const.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2015 Andrew Poelstra * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_ECMULT_CONST_H 8 | #define SECP256K1_ECMULT_CONST_H 9 | 10 | #include "scalar.h" 11 | #include "group.h" 12 | 13 | /* Here `bits` should be set to the maximum bitlength of the _absolute value_ of `q`, plus 14 | * one because we internally sometimes add 2 to the number during the WNAF conversion. */ 15 | static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, const secp256k1_scalar *q, int bits); 16 | 17 | #endif /* SECP256K1_ECMULT_CONST_H */ 18 | -------------------------------------------------------------------------------- /src/secp256k1_tests/scalar_4x64.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_SCALAR_REPR_H 8 | #define SECP256K1_SCALAR_REPR_H 9 | 10 | #include 11 | 12 | /** A scalar modulo the group order of the secp256k1 curve. */ 13 | typedef struct { 14 | uint64_t d[4]; 15 | } secp256k1_scalar; 16 | 17 | #define SECP256K1_SCALAR_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{((uint64_t)(d1)) << 32 | (d0), ((uint64_t)(d3)) << 32 | (d2), ((uint64_t)(d5)) << 32 | (d4), ((uint64_t)(d7)) << 32 | (d6)}} 18 | 19 | #endif /* SECP256K1_SCALAR_REPR_H */ 20 | -------------------------------------------------------------------------------- /src/glyph_mapping/ov2640.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2018 Canaan Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | #ifndef _OV2640_H 16 | #define _OV2640_H 17 | 18 | #include 19 | 20 | #define OV2640_ADDR 0x60 21 | 22 | int ov2640_init(void); 23 | int ov2640_read_id(uint16_t *manuf_id, uint16_t *device_id); 24 | 25 | #endif /* _OV2640_H */ 26 | 27 | -------------------------------------------------------------------------------- /util/esp8266at/data/parses.txt: -------------------------------------------------------------------------------- 1 | > AT 2 | < OK 3 | > AT+CWJAP_CUR? 4 | < No AP 5 | < OK 6 | > AT+CWQAP 7 | < OK 8 | > AT+CWMODE? 9 | < +CWMODE:1 10 | < OK 11 | > AT+CWJAP_CUR="x","x" 12 | < WIFI DISCONNECT 13 | > AT+CWJAP_CUR="x","x" 14 | < busy p... 15 | > AT+CWJAP_CUR="x","x" 16 | < busy p... 17 | < +CWJAP:3 18 | < FAIL 19 | > AT 20 | < OK 21 | > AT+CWJAP_CUR? 22 | < No AP 23 | < OK 24 | > AT+CWQAP 25 | < OK 26 | > AT+CWMODE? 27 | < +CWMODE:1 28 | < OK 29 | > AT+CWJAP_CUR="x","x" 30 | < WIFI CONNECTED 31 | < WIFI GOT IP 32 | < OK 33 | > AT+CIFSR 34 | < +CIFSR:STAIP,"192.168.1.1" 35 | < +CIFSR:STAMAC,"12:34:56:78:9a:bc" 36 | < OK 37 | > AT+CIPSTATUS 38 | < STATUS:2 39 | < OK 40 | > AT+CIPMUX=0 41 | < OK 42 | > AT+CIPSTART="TCP","wttr.in",80 43 | < CONNECT 44 | < OK 45 | > AT+CIPSEND=81 46 | < OK 47 | < > 48 | < Recv 81 bytes 49 | < SEND OK 50 | > AT+CWJAP_CUR? 51 | < +CWJAP_CUR:"xxxxxxxx","12:34:56:78:9a:bc",10,-58 52 | < +IPD:8:012345 53 | < 54 | -------------------------------------------------------------------------------- /rust/uart-passthrough/README.md: -------------------------------------------------------------------------------- 1 | # `uart-passthrough` 2 | 3 | Pass through UART from host to the ESP8285 WIFI chip. 4 | 5 | Any input from the host is forwarded to the ESP8285, and any input from the ESP8285 6 | is forwarded to the host. 7 | 8 | Allows setting the baudrate through an out-of-band protocol. Pulling DTR low will 9 | reset the baudrate to the safe default of 115200, accepting two commands: 10 | 11 | ``` 12 | 0x23 13 | Set baudrate (both to host and ESP) 14 | 15 | 0x42 16 | Reset ESP8285 MCU (toggle WIFI_EN pin) 17 | 18 | others: no op 19 | ``` 20 | 21 | The connection from the K210 to the ESP can handle up to `115200*40=4608000` baud, 22 | however the connection to the host seems to get stuck at a lower number. Use 23 | `AT+UART_CUR=` (not `UART_DEF` !) to set the baudrate at the ESP side so that 24 | it is always possible to reset the MCU to get back to 115200 baud. 25 | 26 | There's a demo in `demo/weather.py`. 27 | -------------------------------------------------------------------------------- /rust/voxel/src/aligned_as.rs: -------------------------------------------------------------------------------- 1 | /*! Align an array of bytes to a specified alignment. This struct is generic in Bytes to admit unsizing coercions. 2 | * See: https://users.rust-lang.org/t/can-i-conveniently-compile-bytes-into-a-rust-program-with-a-specific-alignment/24049 3 | */ 4 | #[repr(C)] // guarantee 'bytes' comes after '_align' 5 | pub struct AlignedAs { 6 | pub _align: [Align; 0], 7 | pub bytes: Bytes, 8 | } 9 | 10 | macro_rules! include_bytes_align_as { 11 | ($align_ty:ty, $path:literal) => { 12 | { // const block expression to encapsulate the static 13 | use $crate::aligned_as::AlignedAs; 14 | 15 | // this assignment is made possible by CoerceUnsized 16 | static ALIGNED: &AlignedAs::<$align_ty, [u8]> = &AlignedAs { 17 | _align: [], 18 | bytes: *include_bytes!($path), 19 | }; 20 | 21 | &ALIGNED.bytes 22 | } 23 | }; 24 | } 25 | -------------------------------------------------------------------------------- /rust/game-of-life/gen-block-sprite.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | '''Script to generate BLOCK_SPRITE constant''' 3 | BLK_SIZE = 8 4 | 5 | def rgb565(r, g, b): 6 | return ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3); 7 | 8 | image = [[(0, 0, 0)] * BLK_SIZE for _ in range(BLK_SIZE)] 9 | 10 | mm = BLK_SIZE//2-1 11 | for y in range(BLK_SIZE//2): 12 | for x in range(BLK_SIZE//2): 13 | l = min(min(x,y),mm) 14 | col = (0xa8*(l+1)//mm,0x48*(l+1)//mm,0xa8*(l+1)//mm) 15 | image[y][x] = col 16 | image[BLK_SIZE-y-1][x] = col 17 | image[y][BLK_SIZE-x-1] = col 18 | image[BLK_SIZE-y-1][BLK_SIZE-x-1] = col 19 | 20 | outb = [] 21 | for y in range(BLK_SIZE): 22 | outb.append([((rgb565(*image[y][x*2+0]) << 0) | (rgb565(*image[y][x*2+1]) << 16)) for x in range(BLK_SIZE//2)]) 23 | 24 | print('pub static BLOCK_SPRITE: [[u32; 4];8] = [') 25 | for y in outb: 26 | print(' [%s],' % (', '.join(('0x%08x' % i) for i in y))) 27 | print('];') 28 | -------------------------------------------------------------------------------- /rust/interrupt/src/aligned_as.rs: -------------------------------------------------------------------------------- 1 | /*! Align an array of bytes to a specified alignment. This struct is generic in Bytes to admit unsizing coercions. 2 | * See: https://users.rust-lang.org/t/can-i-conveniently-compile-bytes-into-a-rust-program-with-a-specific-alignment/24049 3 | */ 4 | #[repr(C)] // guarantee 'bytes' comes after '_align' 5 | pub struct AlignedAs { 6 | pub _align: [Align; 0], 7 | pub bytes: Bytes, 8 | } 9 | 10 | macro_rules! include_bytes_align_as { 11 | ($align_ty:ty, $path:literal) => { 12 | { // const block expression to encapsulate the static 13 | use $crate::aligned_as::AlignedAs; 14 | 15 | // this assignment is made possible by CoerceUnsized 16 | static ALIGNED: &AlignedAs::<$align_ty, [u8]> = &AlignedAs { 17 | _align: [], 18 | bytes: *include_bytes!($path), 19 | }; 20 | 21 | &ALIGNED.bytes 22 | } 23 | }; 24 | } 25 | -------------------------------------------------------------------------------- /r2/k210_otp/rop.d/arithm: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /r2/k210_otp/rop.d/const: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /r2/k210_otp/rop.d/mov: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /r2/k210_otp/rop.d/nop: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /r2/k210_rom/rop.d/arithm: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /r2/k210_rom/rop.d/const: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /r2/k210_rom/rop.d/mov: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /r2/k210_rom/rop.d/nop: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /r2/k210_otp/rop.d/arithm_ct: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /r2/k210_rom/rop.d/arithm_ct: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /rust/k210-shared/src/panic.rs: -------------------------------------------------------------------------------- 1 | /** Panic handler: based on ARM panic-itm */ 2 | use k210_hal::pac::Peripherals; 3 | use k210_hal::prelude::*; 4 | use k210_hal::stdout::Stdout; 5 | use core::panic::PanicInfo; 6 | use core::sync::atomic::{self, Ordering}; 7 | 8 | /** Send panic messages to UARTHS at 115200 baud */ 9 | #[panic_handler] 10 | fn panic(info: &PanicInfo) -> ! { 11 | // Stealing all peripherals, re-initializing the clocks and serial seems overkill here, but 12 | // also, can we really know the state? 13 | let p = unsafe { Peripherals::steal() }; 14 | let clocks = k210_hal::clock::Clocks::new(); 15 | let serial = p.UARTHS.configure(115_200.bps(), &clocks); 16 | let (mut tx, _) = serial.split(); 17 | let mut stdout = Stdout(&mut tx); 18 | writeln!(stdout, "{}", info).unwrap(); 19 | 20 | loop { 21 | // add some side effect to prevent this from turning into a UDF instruction 22 | // see rust-lang/rust#28728 for details 23 | atomic::compiler_fence(Ordering::SeqCst) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /r2/README.md: -------------------------------------------------------------------------------- 1 | K210 Boot ROM re'ing 2 | ==================== 3 | 4 | This directory contains annotations (comments, function names, some 5 | cross-referencing) for the K210 boot process. The [radare2](https://rada.re/r/) 6 | reverse-engineering tool was used. 7 | 8 | Where there were clear matches I've tried to use function names from the SDK. When not, 9 | I've tried to think of an appropriate name. Some functions are unknown and still named 10 | after the broad category `fcnXXXXXXXX._flash`, `fcnXXXXXXXX._otp`. 11 | 12 | You need a dump of the K210 ROM (address 0x88000000..0x8801ffff) as `kendryte_rom.dat` 13 | in the current directory. 14 | 15 | To use the radare2 projects the straightforward way is to link them to the user projects 16 | directory. I had no luck overriding `R2_RDATAHOME`. 17 | 18 | ```bash 19 | ln -sf $PWD/k210_* $HOME/.local/share/radare2/projects 20 | ``` 21 | 22 | ```bash 23 | stat kendryte_rom.dat # must be 131072 bytes 24 | r2 -p k210_rom 25 | ``` 26 | 27 | ```bash 28 | stat kendryte_otp.dat # must be 16384 bytes 29 | r2 -p k210_otp 30 | ``` 31 | -------------------------------------------------------------------------------- /src/secp256k1_tests/COPYING: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Pieter Wuille 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = [ 3 | "k210-console", 4 | "mandelbrot", 5 | "game-of-life", 6 | "accelerometer", 7 | "uart-passthrough", 8 | "rgbcontrol", 9 | "weather", 10 | "dvp-ov", 11 | "glyph-mapping", 12 | "term-server", 13 | "secp256k1-test", 14 | "sdtest", 15 | "sdlcd", 16 | "interrupt", 17 | "embgfx", 18 | "voxel", 19 | "cryptest", 20 | ] 21 | 22 | [patch.crates-io] 23 | 24 | k210-hal = { git = "https://github.com/riscv-rust/k210-hal.git", rev = "fdf1ad61af8f756765a65133bb2d08cda686be6f" } 25 | riscv = { git = "https://github.com/rust-embedded/riscv.git", rev = "422a1625cfd666f927eae485629fa7f96be5ebd0" } 26 | 27 | # Remove this after https://github.com/ilya-epifanov/riscv-target/pull/1 or similar merged 28 | riscv-target = { git = "https://github.com/laanwj/riscv-target.git", rev = "189b5261ecdd40f18eb1b82614d6876aa88bd744" } 29 | 30 | # This patch was merged upstream, unfortunately, rust-secp256k1 puts a restriction on 31 | # cc_rs <= 1.0.41 so we can't actually use the newer version yet. 32 | cc = { git = "https://github.com/laanwj/cc-rs.git", rev = "83e66a79a25b55d0aa84db42257a8edbb0095cf8" } 33 | -------------------------------------------------------------------------------- /rust/k210-shared/src/soc/gpiohs.rs: -------------------------------------------------------------------------------- 1 | //! GPIOHS peripheral 2 | use k210_hal::pac; 3 | 4 | use crate::soc::gpio; 5 | use crate::soc::utils::{set_bit,get_bit}; 6 | 7 | // TODO embedded-hal::digital::v2::{InputPin, OutputPin} 8 | 9 | /** Set input/output direction for a GPIOHS pin */ 10 | pub fn set_direction(pin: u8, direction: gpio::direction) { 11 | unsafe { 12 | let ptr = pac::GPIOHS::ptr(); 13 | (*ptr) 14 | .output_en 15 | .modify(|r, w| w.bits(set_bit(r.bits(), pin, direction == gpio::direction::OUTPUT))); 16 | (*ptr) 17 | .input_en 18 | .modify(|r, w| w.bits(set_bit(r.bits(), pin, direction == gpio::direction::INPUT))); 19 | } 20 | } 21 | 22 | /** Set output value for a GPIOHS pin */ 23 | pub fn set_pin(pin: u8, value: bool) { 24 | unsafe { 25 | let ptr = pac::GPIOHS::ptr(); 26 | (*ptr) 27 | .output_val 28 | .modify(|r, w| w.bits(set_bit(r.bits(), pin, value))); 29 | } 30 | } 31 | 32 | /** Get input value for a GPIOHS pin */ 33 | pub fn get_pin(pin: u8) -> bool { 34 | unsafe { 35 | let ptr = pac::GPIOHS::ptr(); 36 | get_bit((*ptr).input_val.read().bits(), pin) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /util/esp8266at/examples/parsetest.rs: -------------------------------------------------------------------------------- 1 | use std::fs::File; 2 | use std::io::BufRead; 3 | use std::io::BufReader; 4 | 5 | use esp8266at::response::{parse,ParseResult}; 6 | 7 | fn main() { 8 | let f = File::open("data/parses.txt").unwrap(); 9 | let file = BufReader::new(&f); 10 | for line in file.lines() { 11 | let l = line.unwrap(); 12 | if l.len() >= 2 { 13 | let mut lb = l[2..].as_bytes().to_vec(); 14 | lb.push(13); 15 | lb.push(10); 16 | let res = parse(&lb); 17 | match res { 18 | ParseResult::Err => { 19 | println!("failed command was: {}", l); 20 | } 21 | ParseResult::Incomplete => { 22 | println!("incomplete command was: {}", l); 23 | } 24 | ParseResult::Ok(res, x) => { 25 | if res == lb.len() { 26 | println!("{:?}", x); 27 | } else { 28 | println!("non-empty residue command was: {}", l); 29 | println!("{:?} {:?}", res, x); 30 | } 31 | } 32 | } 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/secp256k1_tests/ecdsa.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2013, 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_ECDSA_H 8 | #define SECP256K1_ECDSA_H 9 | 10 | #include 11 | 12 | #include "scalar.h" 13 | #include "group.h" 14 | #include "ecmult.h" 15 | 16 | static int secp256k1_ecdsa_sig_parse(secp256k1_scalar *r, secp256k1_scalar *s, const unsigned char *sig, size_t size); 17 | static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, size_t *size, const secp256k1_scalar *r, const secp256k1_scalar *s); 18 | static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context *ctx, const secp256k1_scalar* r, const secp256k1_scalar* s, const secp256k1_ge *pubkey, const secp256k1_scalar *message); 19 | static int secp256k1_ecdsa_sig_sign(const secp256k1_ecmult_gen_context *ctx, secp256k1_scalar* r, secp256k1_scalar* s, const secp256k1_scalar *seckey, const secp256k1_scalar *message, const secp256k1_scalar *nonce, int *recid); 20 | 21 | #endif /* SECP256K1_ECDSA_H */ 22 | -------------------------------------------------------------------------------- /rust/k210-console/scripts/create_tables.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import unicodedata 3 | 4 | mapping = [] 5 | with open('../data/values.tsv', 'r') as f: 6 | lines = iter(f) 7 | next(lines) 8 | for line in lines: 9 | (byte, unich, name) = line.rstrip().split('\t') 10 | byte = int(byte, 0) 11 | unich = int(unich, 0) 12 | mapping.append((byte, unich, name)) 13 | 14 | # add in ASCII 15 | mapping.append((0x00, 0x0000, 'NUL')) 16 | for ch in range(0x20, 0x7f): 17 | mapping.append((ch, ch, unicodedata.name(chr(ch)))) 18 | mapping.sort() 19 | 20 | fw_mapping = [None] * 256 21 | for byte, unich, name in mapping: 22 | #print('%02x %05x %s' % (byte, unich, name)) 23 | fw_mapping[byte] = unich 24 | 25 | def qchar(ch): 26 | return "'\\u{%04x}'" % ch 27 | 28 | print('static FROM: [char; 256] = [') 29 | for i in range(0x100): 30 | if (i % 8)==0: 31 | print(" ", end='') 32 | print("%s," % qchar(fw_mapping[i]), end='') 33 | if ((i+1) % 8)==0: 34 | print() 35 | else: 36 | print(" ", end='') 37 | print(']') 38 | 39 | print('pub fn to(ch: char) -> u8 {') 40 | print(' match ch {') 41 | for byte, unich, name in mapping: 42 | print(' %s => 0x%02x, // %s' % (qchar(unich), byte, name)) 43 | print(' }') 44 | print('}') 45 | 46 | -------------------------------------------------------------------------------- /rust/k210-console/src/color.rs: -------------------------------------------------------------------------------- 1 | use k210_shared::board::lcd_colors::rgb565; 2 | 3 | /** Basic color math. */ 4 | #[derive(Copy, Clone)] 5 | pub struct Color { 6 | pub r: u8, 7 | pub g: u8, 8 | pub b: u8, 9 | #[allow(dead_code)] 10 | pub a: u8, 11 | } 12 | 13 | impl Color { 14 | pub const fn new(r: u8, g: u8, b: u8) -> Color { 15 | Color { r, g, b, a: 255 } 16 | } 17 | 18 | pub const fn new_rgba(r: u8, g: u8, b: u8, a: u8) -> Color { 19 | Color { r, g, b, a: a } 20 | } 21 | 22 | pub const fn from_rgb565(val: u16) -> Color { 23 | let rs = ((val >> 11) & 0x1f) as u8; 24 | let gs = ((val >> 5) & 0x3f) as u8; 25 | let bs = ((val >> 0) & 0x1f) as u8; 26 | Color { 27 | r: (rs << 3) | (rs >> 2), 28 | g: (gs << 2) | (gs >> 4), 29 | b: (bs << 3) | (bs >> 2), 30 | a: 255, 31 | } 32 | } 33 | 34 | pub const fn from_rgba32(val: u32) -> Color { 35 | Color { 36 | r: ((val >> 24) & 0xff) as u8, 37 | g: ((val >> 16) & 0xff) as u8, 38 | b: ((val >> 8) & 0xff) as u8, 39 | a: ((val >> 0) & 0xff) as u8, 40 | } 41 | } 42 | 43 | pub const fn to_rgb565(&self) -> u16 { 44 | rgb565(self.r, self.g, self.b) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /rust/k210-shared/src/debug.rs: -------------------------------------------------------------------------------- 1 | /** Simple logging functionality that prints to UARTHS at the current settings. 2 | * The advantage of this is that it can be used from anywhere without having to pass 3 | * stdout around. The disadvantage is that this prevents rust's safety rules from preventing 4 | * concurrent access. It also assumes someone else set up the UART already. 5 | */ 6 | use k210_hal::pac; 7 | pub use core::fmt::Write; 8 | 9 | pub struct DebugLogger; 10 | 11 | impl Write for DebugLogger { 12 | fn write_str(&mut self, s: &str) -> core::fmt::Result { 13 | let uart = unsafe {&*pac::UARTHS::ptr() }; 14 | for &byte in s.as_bytes() { 15 | while uart.txdata.read().full().bit_is_set() { 16 | continue; 17 | } 18 | unsafe { 19 | uart.txdata.write(|w| w.data().bits(byte)); 20 | } 21 | } 22 | Ok(()) 23 | } 24 | } 25 | 26 | #[macro_export] 27 | macro_rules! debugln { 28 | ($($arg:tt)+) => ({ 29 | let mut stdout = $crate::debug::DebugLogger {}; 30 | writeln!(stdout, $($arg)+).unwrap(); 31 | }) 32 | } 33 | 34 | #[macro_export] 35 | macro_rules! debug { 36 | ($($arg:tt)+) => ({ 37 | let mut stdout = $crate::debug::DebugLogger {}; 38 | write!(stdout, $($arg)+).unwrap(); 39 | }) 40 | } 41 | -------------------------------------------------------------------------------- /src/glyph_mapping/ov5640.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2018 Canaan Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | #ifndef _OV5640_H 16 | #define _OV5640_H 17 | 18 | #include 19 | 20 | #define OV5640_ID 0X5640 21 | #define OV5640_ADDR 0X78 22 | #define OV5640_CHIPIDH 0X300A 23 | #define OV5640_CHIPIDL 0X300B 24 | 25 | #define XSIZE 320 26 | #define YSIZE 240 27 | #define LCD_GRAM_ADDRESS 0x60020000 28 | 29 | #define QQVGA_160_120 0 30 | #define QCIF_176_144 1 31 | #define QVGA_320_240 2 32 | #define WQVGA_400_240 3 33 | #define CIF_352_288 4 34 | 35 | #define jpeg_buf_size (30*1024) 36 | 37 | uint8_t ov5640_init(void); 38 | void ov5640_flash_lamp(uint8_t sw); 39 | 40 | #endif 41 | 42 | -------------------------------------------------------------------------------- /src/secp256k1_tests/eckey.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2013, 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_ECKEY_H 8 | #define SECP256K1_ECKEY_H 9 | 10 | #include 11 | 12 | #include "group.h" 13 | #include "scalar.h" 14 | #include "ecmult.h" 15 | #include "ecmult_gen.h" 16 | 17 | static int secp256k1_eckey_pubkey_parse(secp256k1_ge *elem, const unsigned char *pub, size_t size); 18 | static int secp256k1_eckey_pubkey_serialize(secp256k1_ge *elem, unsigned char *pub, size_t *size, int compressed); 19 | 20 | static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar *key, const secp256k1_scalar *tweak); 21 | static int secp256k1_eckey_pubkey_tweak_add(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak); 22 | static int secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar *key, const secp256k1_scalar *tweak); 23 | static int secp256k1_eckey_pubkey_tweak_mul(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak); 24 | 25 | #endif /* SECP256K1_ECKEY_H */ 26 | -------------------------------------------------------------------------------- /rust/voxel/scripts/convert.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | ''' 3 | Convert map from set of PNG files to native format 4 | for inclusion. 5 | 6 | Example maps can be found here: 7 | https://github.com/s-macke/VoxelSpace/tree/master/maps 8 | ''' 9 | import sys 10 | from PIL import Image 11 | import struct 12 | 13 | def rgb565(r, g, b): 14 | '''Truncate RGB888 color to RGB565''' 15 | return (((r) >> 3) << 11) | (((g) >> 2) << 5) | ((b) >> 3) 16 | 17 | def convert_palette(pal): 18 | '''Convert 8-bit indexed image palette to RGB565''' 19 | return [rgb565(pal[i*3+0], pal[i*3+1], pal[i*3+2]) for i in range(256)] 20 | 21 | color_fname = sys.argv[1] 22 | depth_fname = sys.argv[2] 23 | out_fname = sys.argv[3] 24 | 25 | color_img = Image.open(color_fname) 26 | depth_img = Image.open(depth_fname) 27 | assert(color_img.size == (1024,1024)) 28 | assert(depth_img.size == (1024,1024)) 29 | assert(color_img.getbands() == ('P',)) 30 | assert(len(color_img.getpalette()) == 768) 31 | assert(depth_img.getbands() == ('L',)) 32 | 33 | # downsample 34 | delta = 4 35 | size_out = (color_img.size[0] // delta, color_img.size[1] // delta) 36 | 37 | out = [] 38 | out += convert_palette(color_img.getpalette()) 39 | for y in range(0, size_out[1]): 40 | for x in range(0, size_out[0]): 41 | pos = (x * delta, y * delta) 42 | val = color_img.getpixel(pos) | (depth_img.getpixel(pos) << 8) 43 | out.append(val) 44 | 45 | with open(out_fname, 'wb') as f: 46 | for val in out: 47 | f.write(struct.pack(' 11 | #include 12 | 13 | typedef struct { 14 | uint32_t s[8]; 15 | uint32_t buf[16]; /* In big endian */ 16 | size_t bytes; 17 | } secp256k1_sha256; 18 | 19 | static void secp256k1_sha256_initialize(secp256k1_sha256 *hash); 20 | static void secp256k1_sha256_write(secp256k1_sha256 *hash, const unsigned char *data, size_t size); 21 | static void secp256k1_sha256_finalize(secp256k1_sha256 *hash, unsigned char *out32); 22 | 23 | typedef struct { 24 | secp256k1_sha256 inner, outer; 25 | } secp256k1_hmac_sha256; 26 | 27 | static void secp256k1_hmac_sha256_initialize(secp256k1_hmac_sha256 *hash, const unsigned char *key, size_t size); 28 | static void secp256k1_hmac_sha256_write(secp256k1_hmac_sha256 *hash, const unsigned char *data, size_t size); 29 | static void secp256k1_hmac_sha256_finalize(secp256k1_hmac_sha256 *hash, unsigned char *out32); 30 | 31 | typedef struct { 32 | unsigned char v[32]; 33 | unsigned char k[32]; 34 | int retry; 35 | } secp256k1_rfc6979_hmac_sha256; 36 | 37 | static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha256 *rng, const unsigned char *key, size_t keylen); 38 | static void secp256k1_rfc6979_hmac_sha256_generate(secp256k1_rfc6979_hmac_sha256 *rng, unsigned char *out, size_t outlen); 39 | static void secp256k1_rfc6979_hmac_sha256_finalize(secp256k1_rfc6979_hmac_sha256 *rng); 40 | 41 | #endif /* SECP256K1_HASH_H */ 42 | -------------------------------------------------------------------------------- /doc/mmu_notes.md: -------------------------------------------------------------------------------- 1 | Notes on K210 MMU 2 | ================= 3 | 4 | The K210 has a MMU based on the RISC-V privileged spec 1.9.1. 5 | 6 | This means that: 7 | 8 | - The `sfence.vm` (bit pattern `0x10400073`) instruction should be used to 9 | synchronize updates to the page tables with current execution, not 10 | `sfence.vma` (bit pattern `0x12000073`). See spec section 4.2.1. 11 | 12 | - The `sptbr` CSR (`0x180`, Supervisor Page-Table Base Register) specifies the 13 | current root page table. In the newer spec this register is called `satp` 14 | and is completely different. 15 | 16 | - In spec v1.9.1, `sstatus.SUM` is still `PUM` which has opposite meaning. 17 | 18 | - To switch on paging, set the `VM` bitfield (offset 24:28) of `mstatus` to `Sv39` (9). 19 | 20 | Also, [reportedly](https://www.reddit.com/r/RISCV/comments/fguddz/linux011_with_mmu_for_k210_riscv/fk9otke/) interrupts do not work as expected in S mode, making that 21 | mode more or less useless. Only M and U mode can be used in practice. 22 | 23 | To access paged memory from M mode, the `MPRV` bit in `mstatus` can be set, with `MPP` set to 24 | `0` (U mode). From the spec (section 3.1.9): 25 | 26 | > The MPRV bit modifies the privilege level at which loads and stores execute. When MPRV=0, 27 | > translation and protection behave as normal. When MPRV=1, data memory addresses are trans- 28 | > lated and protected as though the current privilege mode were set to MPP. Instruction address- 29 | > translation and protection are unaffected 30 | 31 | Examples 32 | --------- 33 | 34 | There is a little bit of example code for using the MMU on the K210: 35 | 36 | - [https://github.com/lizhirui/K210-Linux0.11.git](Linux0.11 with MMU) 37 | - [https://github.com/44670/libk9/blob/develop/k9/CacheEngine.c](CacheEngine.c) 38 | - [https://github.com/oscourse-tsinghua/rcore_plus/issues/34#issuecomment-485145060](Some notes on porting a rust-based OS to K210) 39 | -------------------------------------------------------------------------------- /src/secp256k1_tests/scratch.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2017 Andrew Poelstra * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef _SECP256K1_SCRATCH_ 8 | #define _SECP256K1_SCRATCH_ 9 | 10 | #define SECP256K1_SCRATCH_MAX_FRAMES 5 11 | 12 | /* The typedef is used internally; the struct name is used in the public API 13 | * (where it is exposed as a different typedef) */ 14 | typedef struct secp256k1_scratch_space_struct { 15 | void *data[SECP256K1_SCRATCH_MAX_FRAMES]; 16 | size_t offset[SECP256K1_SCRATCH_MAX_FRAMES]; 17 | size_t frame_size[SECP256K1_SCRATCH_MAX_FRAMES]; 18 | size_t frame; 19 | size_t max_size; 20 | const secp256k1_callback* error_callback; 21 | } secp256k1_scratch; 22 | 23 | static secp256k1_scratch* secp256k1_scratch_create(const secp256k1_callback* error_callback, size_t max_size); 24 | 25 | static void secp256k1_scratch_destroy(secp256k1_scratch* scratch); 26 | 27 | /** Attempts to allocate a new stack frame with `n` available bytes. Returns 1 on success, 0 on failure */ 28 | static int secp256k1_scratch_allocate_frame(secp256k1_scratch* scratch, size_t n, size_t objects); 29 | 30 | /** Deallocates a stack frame */ 31 | static void secp256k1_scratch_deallocate_frame(secp256k1_scratch* scratch); 32 | 33 | /** Returns the maximum allocation the scratch space will allow */ 34 | static size_t secp256k1_scratch_max_allocation(const secp256k1_scratch* scratch, size_t n_objects); 35 | 36 | /** Returns a pointer into the most recently allocated frame, or NULL if there is insufficient available space */ 37 | static void *secp256k1_scratch_alloc(secp256k1_scratch* scratch, size_t n); 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /src/secp256k1_tests/field_5x52.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2013, 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_FIELD_REPR_H 8 | #define SECP256K1_FIELD_REPR_H 9 | 10 | #include 11 | 12 | typedef struct { 13 | /* X = sum(i=0..4, n[i]*2^(i*52)) mod p 14 | * where p = 2^256 - 0x1000003D1 15 | */ 16 | uint64_t n[5]; 17 | #ifdef VERIFY 18 | int magnitude; 19 | int normalized; 20 | #endif 21 | } secp256k1_fe; 22 | 23 | /* Unpacks a constant into a overlapping multi-limbed FE element. */ 24 | #define SECP256K1_FE_CONST_INNER(d7, d6, d5, d4, d3, d2, d1, d0) { \ 25 | (d0) | (((uint64_t)(d1) & 0xFFFFFUL) << 32), \ 26 | ((uint64_t)(d1) >> 20) | (((uint64_t)(d2)) << 12) | (((uint64_t)(d3) & 0xFFUL) << 44), \ 27 | ((uint64_t)(d3) >> 8) | (((uint64_t)(d4) & 0xFFFFFFFUL) << 24), \ 28 | ((uint64_t)(d4) >> 28) | (((uint64_t)(d5)) << 4) | (((uint64_t)(d6) & 0xFFFFUL) << 36), \ 29 | ((uint64_t)(d6) >> 16) | (((uint64_t)(d7)) << 16) \ 30 | } 31 | 32 | #ifdef VERIFY 33 | #define SECP256K1_FE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {SECP256K1_FE_CONST_INNER((d7), (d6), (d5), (d4), (d3), (d2), (d1), (d0)), 1, 1} 34 | #else 35 | #define SECP256K1_FE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {SECP256K1_FE_CONST_INNER((d7), (d6), (d5), (d4), (d3), (d2), (d1), (d0))} 36 | #endif 37 | 38 | typedef struct { 39 | uint64_t n[4]; 40 | } secp256k1_fe_storage; 41 | 42 | #define SECP256K1_FE_STORAGE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{ \ 43 | (d0) | (((uint64_t)(d1)) << 32), \ 44 | (d2) | (((uint64_t)(d3)) << 32), \ 45 | (d4) | (((uint64_t)(d5)) << 32), \ 46 | (d6) | (((uint64_t)(d7)) << 32) \ 47 | }} 48 | 49 | #endif /* SECP256K1_FIELD_REPR_H */ 50 | -------------------------------------------------------------------------------- /rust/k210-shared/src/timing.rs: -------------------------------------------------------------------------------- 1 | /** Utilities for measuring time and framerates. */ 2 | use core::cmp; 3 | use crate::soc::sysctl; 4 | use riscv::register::mcycle; 5 | 6 | /** Number of frame times to store. */ 7 | const N_FRAMES: usize = 100; 8 | /** Use last N seconds for statistics. */ 9 | const N_SEC: u64 = 2; 10 | 11 | /** Counter for FPS statistics. 12 | */ 13 | pub struct FPSTimer { 14 | /** An array of the times of the last N frames. */ 15 | frame_times: [u64; N_FRAMES], 16 | /** Current offset in ring buffer. */ 17 | ofs: usize, 18 | } 19 | 20 | impl FPSTimer { 21 | pub fn new() -> Self { 22 | Self { 23 | frame_times: [0; N_FRAMES], 24 | ofs: 0, 25 | } 26 | } 27 | 28 | pub fn frame(&mut self) { 29 | self.frame_times[self.ofs] = mcycle::read64(); 30 | self.ofs += 1; 31 | if self.ofs == N_FRAMES { 32 | self.ofs = 0; 33 | } 34 | } 35 | 36 | pub fn fps(&self) -> u32 { 37 | let freq = sysctl::clock_get_freq(sysctl::clock::CPU) as u64; 38 | let now = mcycle::read64(); 39 | let oldest = now.saturating_sub(freq * N_SEC); 40 | let mut count: u32 = 0; 41 | let mut min: u64 = u64::max_value(); 42 | for &t in self.frame_times.iter() { 43 | if t > oldest { 44 | count += 1; 45 | } 46 | if t != 0 { 47 | min = cmp::min(min, t); 48 | } 49 | } 50 | if count == 0 { 51 | 0 52 | } else if min <= oldest { 53 | // Collected full N seconds 54 | count / (N_SEC as u32) 55 | } else { 56 | // Collected less than N seconds, make an estimate based on what we have 57 | (u64::from(count) * freq / (now - min)) as u32 58 | } 59 | } 60 | } 61 | 62 | /** Return time in microseconds. The starting point is undefined, only differences make sense. */ 63 | pub fn clock() -> u64 { 64 | let freq = sysctl::clock_get_freq(sysctl::clock::CPU) as u64; 65 | let cycles = mcycle::read64(); 66 | return cycles * 1_000_000 / freq; 67 | } 68 | -------------------------------------------------------------------------------- /src/glyph_mapping/ov5640.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2018 Canaan Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | #include 16 | #include 17 | #include "ov5640.h" 18 | #include "ov5640cfg.h" 19 | #include "dvp.h" 20 | 21 | static void hal_delay(uint32_t delay) 22 | { 23 | usleep(delay * 1000); 24 | } 25 | 26 | static void ov5640_wr_reg(uint16_t reg,uint8_t data) 27 | { 28 | dvp_sccb_send_data(OV5640_ADDR, reg, data); 29 | } 30 | 31 | static uint8_t ov5640_rd_reg(uint16_t reg) 32 | { 33 | return dvp_sccb_receive_data(OV5640_ADDR, reg); 34 | } 35 | 36 | uint8_t ov5640_init(void) 37 | { 38 | uint16_t i = 0; 39 | uint16_t reg = 0; 40 | 41 | reg = ov5640_rd_reg(OV5640_CHIPIDH); 42 | reg <<= 8; 43 | reg |= ov5640_rd_reg(OV5640_CHIPIDL); 44 | printf("ID: %X \r\n", reg); 45 | if(reg != OV5640_ID) 46 | { 47 | printf("ID: %d \r\n", reg); 48 | return 1; 49 | } 50 | 51 | ov5640_wr_reg(0x3103,0X11); /*system clock from pad, bit[1]*/ 52 | ov5640_wr_reg(0X3008,0X82); 53 | hal_delay(10); 54 | 55 | for(i = 0; i u16 { 27 | (((r as u16) >> 3) << 11) | (((g as u16) >> 2) << 5) | ((b as u16) >> 3) 28 | } 29 | 30 | /** 32.0 minus 1ulp */ 31 | const ALMOST_32: f32 = 31.999998f32; 32 | /** 64.0 minus 1ulp */ 33 | const ALMOST_64: f32 = 63.999996f32; 34 | 35 | /** Truncate 32 bit RGB to RBG565 */ 36 | pub fn rgbf565(r: f32, g: f32, b: f32) -> u16 { 37 | (((r * ALMOST_32) as u16) << 11) | 38 | (((g * ALMOST_64) as u16) << 5) | 39 | ((b * ALMOST_32) as u16) 40 | } 41 | 42 | /** HSV to RGB. `h` is 0.0..360.0, `s` and `v` are 0.0..1.0 output RGB will be 0.0..1.0 (all ranges 43 | * inclusive) 44 | */ 45 | pub fn hsv2rgb(h: f32, s: f32, v: f32) -> (f32, f32, f32) { 46 | let h = h / 60.0; 47 | let i = h.trunc(); 48 | let f = h - i; 49 | 50 | let c = v * (1.0 - s * f); 51 | let b = v * (1.0 - s + s * f); 52 | let o = v * (1.0 - s); 53 | match i as u32 { 54 | // yellow to green 55 | 1 => (c, v, o), 56 | // green to cyan 57 | 2 => (o, v, b), 58 | // cyan to blue 59 | 3 => (o, c, v), 60 | // blue to magenta 61 | 4 => (b, o, v), 62 | // magenta to red 63 | 5 => (v, o, c), 64 | // red to yellow 65 | _ => (v, b, o), 66 | } 67 | } 68 | 69 | /** Clamp a float between 0 and 1 */ 70 | pub fn clampf(v: f32) -> f32 { 71 | if v < 0.0 { 72 | 0.0 73 | } else if v > 1.0 { 74 | 1.0 75 | } else { 76 | v 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/secp256k1_bench/bench.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_BENCH_H 8 | #define SECP256K1_BENCH_H 9 | 10 | #include 11 | #include 12 | #include 13 | #include "sys/time.h" 14 | 15 | static double gettimedouble(void) { 16 | struct timeval tv; 17 | gettimeofday(&tv, NULL); 18 | return tv.tv_usec * 0.000001 + tv.tv_sec; 19 | } 20 | 21 | void print_number(double x) { 22 | double y = x; 23 | int c = 0; 24 | if (y < 0.0) { 25 | y = -y; 26 | } 27 | while (y > 0 && y < 100.0) { 28 | y *= 10.0; 29 | c++; 30 | } 31 | printf("%.*f", c, x); 32 | } 33 | 34 | void run_benchmark(char *name, void (*benchmark)(void*), void (*setup)(void*), void (*teardown)(void*), void* data, int count, int iter) { 35 | int i; 36 | double min = HUGE_VAL; 37 | double sum = 0.0; 38 | double max = 0.0; 39 | for (i = 0; i < count; i++) { 40 | double begin, total; 41 | if (setup != NULL) { 42 | setup(data); 43 | } 44 | begin = gettimedouble(); 45 | benchmark(data); 46 | total = gettimedouble() - begin; 47 | if (teardown != NULL) { 48 | teardown(data); 49 | } 50 | if (total < min) { 51 | min = total; 52 | } 53 | if (total > max) { 54 | max = total; 55 | } 56 | sum += total; 57 | } 58 | printf("%s: min ", name); 59 | print_number(min * 1000000.0 / iter); 60 | printf("us / avg "); 61 | print_number((sum / count) * 1000000.0 / iter); 62 | printf("us / max "); 63 | print_number(max * 1000000.0 / iter); 64 | printf("us\n"); 65 | } 66 | 67 | int have_flag(int argc, char** argv, char *flag) { 68 | char** argm = argv + argc; 69 | argv++; 70 | if (argv == argm) { 71 | return 1; 72 | } 73 | while (argv != NULL && argv != argm) { 74 | if (strcmp(*argv, flag) == 0) { 75 | return 1; 76 | } 77 | argv++; 78 | } 79 | return 0; 80 | } 81 | 82 | #endif /* SECP256K1_BENCH_H */ 83 | -------------------------------------------------------------------------------- /util/esp8266at/src/util.rs: -------------------------------------------------------------------------------- 1 | use core::slice; 2 | 3 | use crate::traits::Write; 4 | 5 | /** Write quoted string. `\` and `"` are escaped, and the string 6 | * is automatically surrounded with double-quotes. 7 | */ 8 | pub fn write_qstr(w: &mut W, s: &[u8]) -> Result<(), W::Error> 9 | where 10 | W: Write, 11 | { 12 | w.write_all(b"\"")?; 13 | for ch in s { 14 | w.write_all(match ch { 15 | b'\"' => &[b'\\', b'"'], 16 | b'\\' => &[b'\\', b'\\'], 17 | _ => slice::from_ref(ch), 18 | })?; 19 | } 20 | w.write_all(b"\"")?; 21 | Ok(()) 22 | } 23 | 24 | /** Write decimal unsigned number */ 25 | pub fn write_num_u32(w: &mut W, mut val: u32) -> Result<(), W::Error> 26 | where 27 | W: Write, 28 | { 29 | let mut buf = [0u8; 10]; 30 | let mut curr = buf.len(); 31 | for byte in buf.iter_mut().rev() { 32 | *byte = b'0' + (val % 10) as u8; 33 | val = val / 10; 34 | curr -= 1; 35 | if val == 0 { 36 | break; 37 | } 38 | } 39 | w.write_all(&buf[curr..]) 40 | } 41 | 42 | #[cfg(test)] 43 | mod tests { 44 | use super::*; 45 | use arrayvec::ArrayVec; 46 | 47 | #[cfg(not(feature = "std"))] 48 | use arrayvec::Array; 49 | #[cfg(not(feature = "std"))] 50 | impl> Write for ArrayVec { 51 | type Error = (); 52 | fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error> { 53 | for byte in buf { 54 | self.push(*byte); // Panics if the vector is already full. 55 | } 56 | Ok(()) 57 | } 58 | } 59 | 60 | #[test] 61 | fn test_qstr() { 62 | let mut o = ArrayVec::<[_; 16]>::new(); 63 | write_qstr(&mut o, b"123").unwrap(); 64 | assert_eq!(o.as_slice(), b"\"123\""); 65 | 66 | o.clear(); 67 | write_qstr(&mut o, b"\"\\").unwrap(); 68 | assert_eq!(o.as_slice(), b"\"\\\"\\\\\""); 69 | } 70 | 71 | #[test] 72 | fn test_num() { 73 | let mut o = ArrayVec::<[_; 16]>::new(); 74 | write_num_u32(&mut o, 123).unwrap(); 75 | assert_eq!(o.as_slice(), b"123"); 76 | 77 | o.clear(); 78 | write_num_u32(&mut o, 0).unwrap(); 79 | assert_eq!(o.as_slice(), b"0"); 80 | 81 | o.clear(); 82 | write_num_u32(&mut o, 4294967295).unwrap(); 83 | assert_eq!(o.as_slice(), b"4294967295"); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/secp256k1_tests/ecmult_gen.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2013, 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_ECMULT_GEN_H 8 | #define SECP256K1_ECMULT_GEN_H 9 | 10 | #include "scalar.h" 11 | #include "group.h" 12 | 13 | typedef struct { 14 | /* For accelerating the computation of a*G: 15 | * To harden against timing attacks, use the following mechanism: 16 | * * Break up the multiplicand into groups of 4 bits, called n_0, n_1, n_2, ..., n_63. 17 | * * Compute sum(n_i * 16^i * G + U_i, i=0..63), where: 18 | * * U_i = U * 2^i (for i=0..62) 19 | * * U_i = U * (1-2^63) (for i=63) 20 | * where U is a point with no known corresponding scalar. Note that sum(U_i, i=0..63) = 0. 21 | * For each i, and each of the 16 possible values of n_i, (n_i * 16^i * G + U_i) is 22 | * precomputed (call it prec(i, n_i)). The formula now becomes sum(prec(i, n_i), i=0..63). 23 | * None of the resulting prec group elements have a known scalar, and neither do any of 24 | * the intermediate sums while computing a*G. 25 | */ 26 | secp256k1_ge_storage (*prec)[64][16]; /* prec[j][i] = 16^j * i * G + U_i */ 27 | secp256k1_scalar blind; 28 | secp256k1_gej initial; 29 | } secp256k1_ecmult_gen_context; 30 | 31 | static void secp256k1_ecmult_gen_context_init(secp256k1_ecmult_gen_context* ctx); 32 | static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context* ctx, const secp256k1_callback* cb); 33 | static void secp256k1_ecmult_gen_context_clone(secp256k1_ecmult_gen_context *dst, 34 | const secp256k1_ecmult_gen_context* src, const secp256k1_callback* cb); 35 | static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context* ctx); 36 | static int secp256k1_ecmult_gen_context_is_built(const secp256k1_ecmult_gen_context* ctx); 37 | 38 | /** Multiply with the generator: R = a*G */ 39 | static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context* ctx, secp256k1_gej *r, const secp256k1_scalar *a); 40 | 41 | static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context *ctx, const unsigned char *seed32); 42 | 43 | #endif /* SECP256K1_ECMULT_GEN_H */ 44 | -------------------------------------------------------------------------------- /rust/k210-shared/src/board/lcd_render.rs: -------------------------------------------------------------------------------- 1 | //! Efficient(?) full-image rendering. 2 | // TODO: switch this over to embedded-graphics probably 3 | use crate::board::def::{DISP_HEIGHT, DISP_WIDTH, DISP_PIXELS}; 4 | use crate::board::lcd::LCDHL; 5 | 6 | /** Array for representing an image of the entire screen. 7 | * This is an array of DISP_WIDTH / 2 × DISP_HEIGHT, each two horizontally consecutive 8 | * pixels are encoded in a u32 with `(b << 16)|a`. 9 | */ 10 | pub type ScreenImage = [u32; DISP_PIXELS / 2]; 11 | 12 | pub trait AsU8 { 13 | fn as_u8_slice(&self) -> &[u8]; 14 | fn as_u8_slice_mut(&mut self) -> &mut [u8]; 15 | } 16 | 17 | pub trait AsU16 { 18 | fn as_u16_slice(&self) -> &[u16]; 19 | fn as_u16_slice_mut(&mut self) -> &mut [u16]; 20 | } 21 | 22 | impl AsU8 for ScreenImage { 23 | fn as_u8_slice(&self) -> &[u8] { 24 | unsafe { core::slice::from_raw_parts(self.as_ptr() as *mut u8, DISP_PIXELS * 2) } 25 | } 26 | fn as_u8_slice_mut(&mut self) -> &mut [u8] { 27 | unsafe { core::slice::from_raw_parts_mut(self.as_mut_ptr() as *mut u8, DISP_PIXELS * 2) } 28 | } 29 | } 30 | 31 | impl AsU16 for ScreenImage { 32 | fn as_u16_slice(&self) -> &[u16] { 33 | unsafe { core::slice::from_raw_parts(self.as_ptr() as *mut u16, DISP_PIXELS) } 34 | } 35 | fn as_u16_slice_mut(&mut self) -> &mut [u16] { 36 | unsafe { core::slice::from_raw_parts_mut(self.as_mut_ptr() as *mut u16, DISP_PIXELS) } 37 | } 38 | } 39 | 40 | pub fn render_image(lcd: &mut L, mut image: I) 41 | where 42 | L: LCDHL, 43 | I: FnMut(u16, u16) -> u16, 44 | { 45 | // Theoretically this initialization could be avoided by directly initializing from an 46 | // iterator, however, rust doesn't have built-in functionality for this. There's a crate 47 | // (array_init) but it doesn't work for large arrays. 48 | let mut idata: ScreenImage = [0; DISP_PIXELS / 2]; 49 | let yx = (0..DISP_HEIGHT) 50 | .flat_map(|y| core::iter::repeat(y).zip(0..DISP_WIDTH / 2)); 51 | idata.iter_mut().zip(yx).for_each(|(v, (y, x))| { 52 | *v = (u32::from(image(x * 2 + 0, y)) << 0) | (u32::from(image(x * 2 + 1, y)) << 16); 53 | }); 54 | 55 | // It would be possible to make draw_picture take an iterator directly 56 | // instead of rendering to an array first, however, this means that the 57 | // computation has to keep up with the SPI clock speed or there will be 58 | // glitches -- also it means that DMA cannot be used -- whereas a sufficiently 59 | // advanced DMA engine is indistinguishable from a GPU, the one in K210 60 | // isn't that. 61 | lcd.draw_picture(0, 0, DISP_WIDTH, DISP_HEIGHT, &idata); 62 | } 63 | -------------------------------------------------------------------------------- /src/glyph_mapping/lcd.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2018 Canaan Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | #ifndef _LCD_H_ 16 | #define _LCD_H_ 17 | 18 | #include 19 | 20 | /* clang-format off */ 21 | #define LCD_X_MAX (240) 22 | #define LCD_Y_MAX (320) 23 | 24 | #define BLACK 0x0000 25 | #define NAVY 0x000F 26 | #define DARKGREEN 0x03E0 27 | #define DARKCYAN 0x03EF 28 | #define MAROON 0x7800 29 | #define PURPLE 0x780F 30 | #define OLIVE 0x7BE0 31 | #define LIGHTGREY 0xC618 32 | #define DARKGREY 0x7BEF 33 | #define BLUE 0x001F 34 | #define GREEN 0x07E0 35 | #define CYAN 0x07FF 36 | #define RED 0xF800 37 | #define MAGENTA 0xF81F 38 | #define YELLOW 0xFFE0 39 | #define WHITE 0xFFFF 40 | #define ORANGE 0xFD20 41 | #define GREENYELLOW 0xAFE5 42 | #define PINK 0xF81F 43 | #define USER_COLOR 0xAA55 44 | /* clang-format on */ 45 | 46 | typedef enum _lcd_dir 47 | { 48 | DIR_XY_RLUD = 0x00, 49 | DIR_YX_RLUD = 0x20, 50 | DIR_XY_LRUD = 0x40, 51 | DIR_YX_LRUD = 0x60, 52 | DIR_XY_RLDU = 0x80, 53 | DIR_YX_RLDU = 0xA0, 54 | DIR_XY_LRDU = 0xC0, 55 | DIR_YX_LRDU = 0xE0, 56 | DIR_XY_MASK = 0x20, 57 | DIR_MASK = 0xE0, 58 | } lcd_dir_t; 59 | 60 | typedef struct _lcd_ctl 61 | { 62 | uint8_t mode; 63 | uint8_t dir; 64 | uint16_t width; 65 | uint16_t height; 66 | } lcd_ctl_t; 67 | 68 | void lcd_polling_enable(void); 69 | void lcd_interrupt_enable(void); 70 | void lcd_init(void); 71 | void lcd_clear(uint16_t color); 72 | void lcd_set_direction(lcd_dir_t dir); 73 | void lcd_set_area(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2); 74 | void lcd_draw_point(uint16_t x, uint16_t y, uint16_t color); 75 | void lcd_draw_string(uint16_t x, uint16_t y, char *str, uint16_t color); 76 | void lcd_draw_picture(uint16_t x1, uint16_t y1, uint16_t width, uint16_t height, uint32_t *ptr); 77 | void lcd_draw_rectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t width, uint16_t color); 78 | void lcd_ram_draw_string(char *str, uint32_t *ptr, uint16_t font_color, uint16_t bg_color); 79 | 80 | #endif 81 | 82 | -------------------------------------------------------------------------------- /src/secp256k1_tests/ecmult.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2013, 2014, 2017 Pieter Wuille, Andrew Poelstra * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_ECMULT_H 8 | #define SECP256K1_ECMULT_H 9 | 10 | #include "num.h" 11 | #include "group.h" 12 | #include "scalar.h" 13 | #include "scratch.h" 14 | 15 | typedef struct { 16 | /* For accelerating the computation of a*P + b*G: */ 17 | secp256k1_ge_storage (*pre_g)[]; /* odd multiples of the generator */ 18 | #ifdef USE_ENDOMORPHISM 19 | secp256k1_ge_storage (*pre_g_128)[]; /* odd multiples of 2^128*generator */ 20 | #endif 21 | } secp256k1_ecmult_context; 22 | 23 | static void secp256k1_ecmult_context_init(secp256k1_ecmult_context *ctx); 24 | static void secp256k1_ecmult_context_build(secp256k1_ecmult_context *ctx, const secp256k1_callback *cb); 25 | static void secp256k1_ecmult_context_clone(secp256k1_ecmult_context *dst, 26 | const secp256k1_ecmult_context *src, const secp256k1_callback *cb); 27 | static void secp256k1_ecmult_context_clear(secp256k1_ecmult_context *ctx); 28 | static int secp256k1_ecmult_context_is_built(const secp256k1_ecmult_context *ctx); 29 | 30 | /** Double multiply: R = na*A + ng*G */ 31 | static void secp256k1_ecmult(const secp256k1_ecmult_context *ctx, secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_scalar *na, const secp256k1_scalar *ng); 32 | 33 | typedef int (secp256k1_ecmult_multi_callback)(secp256k1_scalar *sc, secp256k1_ge *pt, size_t idx, void *data); 34 | 35 | /** 36 | * Multi-multiply: R = inp_g_sc * G + sum_i ni * Ai. 37 | * Chooses the right algorithm for a given number of points and scratch space 38 | * size. Resets and overwrites the given scratch space. If the points do not 39 | * fit in the scratch space the algorithm is repeatedly run with batches of 40 | * points. If no scratch space is given then a simple algorithm is used that 41 | * simply multiplies the points with the corresponding scalars and adds them up. 42 | * Returns: 1 on success (including when inp_g_sc is NULL and n is 0) 43 | * 0 if there is not enough scratch space for a single point or 44 | * callback returns 0 45 | */ 46 | static int secp256k1_ecmult_multi_var(const secp256k1_ecmult_context *ctx, secp256k1_scratch *scratch, secp256k1_gej *r, const secp256k1_scalar *inp_g_sc, secp256k1_ecmult_multi_callback cb, void *cbdata, size_t n); 47 | 48 | #endif /* SECP256K1_ECMULT_H */ 49 | -------------------------------------------------------------------------------- /rust/secp256k1-test/src/main.rs: -------------------------------------------------------------------------------- 1 | // secp256k1 in rust: testing 2 | // https://github.com/rust-bitcoin/rust-secp256k1/blob/master/src/lib.rs 3 | #![allow(dead_code)] 4 | #![allow(non_snake_case)] 5 | #![allow(non_camel_case_types)] 6 | #![no_std] 7 | #![no_main] 8 | 9 | use k210_hal::pac::Peripherals; 10 | use k210_hal::prelude::*; 11 | use k210_hal::stdout::Stdout; 12 | use riscv_rt::entry; 13 | use k210_shared::soc::sleep::usleep; 14 | use k210_shared::soc::sysctl; 15 | use secp256k1::{Secp256k1, Message, SecretKey, PublicKey}; 16 | use core::slice; 17 | 18 | /** Static buffer for secp256k1: make sure that this is 8-aligned 19 | * by reserving it as an array of u64. 20 | */ 21 | static mut SECP256K1_BUF: [u64; 70000/8] = [0u64; 70000/8]; 22 | 23 | #[entry] 24 | fn main() -> ! { 25 | let p = Peripherals::take().unwrap(); 26 | sysctl::pll_set_freq(sysctl::pll::PLL0, 800_000_000).unwrap(); 27 | sysctl::pll_set_freq(sysctl::pll::PLL1, 300_000_000).unwrap(); 28 | sysctl::pll_set_freq(sysctl::pll::PLL2, 45_158_400).unwrap(); 29 | let clocks = k210_hal::clock::Clocks::new(); 30 | 31 | usleep(200000); 32 | 33 | let serial = p.UARTHS.configure(115_200.bps(), &clocks); 34 | let (mut tx, _) = serial.split(); 35 | 36 | let mut stdout = Stdout(&mut tx); 37 | 38 | let bufsize = unsafe { core::mem::size_of_val(&SECP256K1_BUF) }; 39 | writeln!(stdout, "testing {}(sign {} + verify {}) / {}", 40 | Secp256k1::preallocate_size(), 41 | Secp256k1::preallocate_signing_size(), 42 | Secp256k1::preallocate_verification_size(), 43 | bufsize).unwrap(); 44 | assert!(Secp256k1::preallocate_size() < bufsize); 45 | 46 | let buf = unsafe { slice::from_raw_parts_mut(SECP256K1_BUF.as_mut_ptr() as *mut u8, bufsize) }; 47 | writeln!(stdout, "secp initializing").unwrap(); 48 | let secp = Secp256k1::preallocated_new(buf).unwrap(); 49 | writeln!(stdout, "secp initialized {:?}", secp).unwrap(); 50 | let secret_key = SecretKey::from_slice(&[0xcd; 32]).expect("32 bytes, within curve order"); 51 | writeln!(stdout, "created secret key {:?}", secret_key).unwrap(); 52 | let public_key = PublicKey::from_secret_key(&secp, &secret_key); 53 | writeln!(stdout, "created public key {:?}", public_key).unwrap(); 54 | let message = Message::from_slice(&[0xab; 32]).expect("32 bytes"); 55 | writeln!(stdout, "created message {:?}", message).unwrap(); 56 | 57 | let sig = secp.sign(&message, &secret_key); 58 | writeln!(stdout, "created signature {:?}", sig).unwrap(); 59 | let result = secp.verify(&message, &sig, &public_key); 60 | writeln!(stdout, "verified signature {:?}", result).unwrap(); 61 | 62 | loop { 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/dump_otp/main.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2019 W.J. van der Laan 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | #include 16 | #include 17 | #include "sysctl.h" 18 | #include "sleep.h" 19 | #include "uarths.h" 20 | 21 | typedef int otp_read_func(uint32_t offset, uint8_t *dest, uint32_t size); 22 | static otp_read_func *otp_read_inner = (otp_read_func*)0x8800453c; /* fixed address in ROM */ 23 | 24 | static uint8_t ih_chksum; 25 | 26 | void ih_start(void) 27 | { 28 | printf(":"); 29 | ih_chksum = 0; 30 | } 31 | 32 | void ih_emit(uint8_t val) 33 | { 34 | printf("%02X", val); 35 | ih_chksum += val; 36 | } 37 | 38 | void ih_end() 39 | { 40 | printf("%02X\n", (-ih_chksum) & 0xff); 41 | } 42 | 43 | int main(void) 44 | { 45 | uint64_t core_id = current_coreid(); 46 | 47 | if (core_id == 0) 48 | { 49 | int rv; 50 | 51 | sysctl_pll_set_freq(SYSCTL_PLL0, 800000000UL); 52 | sysctl_pll_set_freq(SYSCTL_PLL1, 300000000UL); 53 | sysctl_pll_set_freq(SYSCTL_PLL2, 45158400UL); 54 | 55 | uarths_init(); 56 | 57 | /* system start, sleep a bit to allow UART clients to connect */ 58 | usleep(100000); 59 | 60 | /* output in Intel HEX */ 61 | uint8_t buf[32]; 62 | for(uint32_t base=0; base<16384; base+=sizeof(buf)) { 63 | memset(buf, 0, sizeof(buf)); 64 | rv = otp_read_inner(base, buf, sizeof(buf)); 65 | if (rv != 0) { 66 | printf("warning: non-zero status %d while reading %08x..%08x\n", rv, base, (uint32_t)(base + sizeof(buf) - 1)); 67 | } 68 | ih_start(); 69 | ih_emit(sizeof(buf)); 70 | ih_emit(base >> 8); 71 | ih_emit(base); 72 | ih_emit(0); /* Data */ 73 | for (uint32_t x=0; x 11 | 12 | This will create tun interface `ifname`. Then, with the with the ESP WIFI 13 | device on `uart` it connects to the AP `ssid` with password `passwd`. 14 | It creates a UDP over IP tunnel with the other endpoint `host:port`. 15 | 16 | The new tun device will not be configured, use the `ip` utility to assign an 17 | IP address and switch the interface on. 18 | 19 | For example: 20 | 21 | /root/esptun tun0 /dev/ttyS1 "accesspointname" "secretpassword" 192.168.122.21 23232 22 | /sbin/ip link set dev tun0 mtu 1472 23 | /sbin/ip addr add 10.0.1.2/24 dev tun0 24 | /sbin/ip link set tun0 up 25 | /sbin/ip route add default via 10.0.1.1 dev tun0 26 | 27 | (setting the MTU to `1500-20-8` the typical network MTU minus IP and UDP header overhead, because 28 | otherwise the ESP's network stack will drop the oversized packets) 29 | 30 | ### Baudrate note 31 | 32 | If the tunnel hangs intermittently, the problem may be the `BAUDRATE` setting. The ESP8285 can handle 33 | baudrates up to `115200*40 = 4608000` baud and `esptun` will try switching to a higher baudrate. 34 | 35 | However, these higher baudrates are unstable as it seems that the UART cannot 36 | keep up reading in some cases and loses data. This may be a misconfiguration or something that could 37 | be improved in the `8250_dw` Linux driver for this peripheral (DMA support?). 38 | 39 | Which values work may vary, if you want to be completely safe use `115200`. The value can be changed 40 | at the top of `esptun.c`. 41 | 42 | Host side 43 | --------- 44 | 45 | On the other endpoint the tunnel is expected to be a host running `socat` or similar to unwrap 46 | the tunnel. For example: 47 | 48 | sudo socat UDP:192.168.2.127:23232,bind=192.168.122.21:23232 \ 49 | TUN:10.0.1.1/24,tun-name=tundudp,iff-no-pi,tun-type=tun,su=$USER,iff-up & 50 | sudo ip link set dev tundudp mtu 1472 51 | 52 | Optionally, enable forwarding and masquerading: 53 | 54 | sudo iptables -t nat -F 55 | sudo iptables -t nat -A POSTROUTING -o ens3 -j MASQUERADE 56 | echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward 57 | 58 | Linux kernel 59 | ------------ 60 | 61 | Until there is a proper solution, you can use the following kernel branch 62 | to get the UART working on Kendryte K210 under Linux: 63 | 64 | https://github.com/laanwj/linux/tree/kendryte-5.6-rc1-wifi 65 | 66 | This is a hack that configures the FPIOA and GPIOHS manually, and configures UART1 67 | from the device tree. 68 | 69 | To enable TUN/TAP, enable the following kernel settings: 70 | ``` 71 | CONFIG_NET=y 72 | CONFIG_INET=y 73 | CONFIG_TUN=y 74 | ``` 75 | 76 | While building the root filesystem, make sure you enable at least `ip` and `ping` 77 | (and possibly other network tools) for busybox. 78 | 79 | Author 80 | ------ 81 | 82 | Copyright (c) 2020 W.J. van der Laan 83 | Distributed under the MIT software license, 84 | -------------------------------------------------------------------------------- /src/secp256k1_tests/num.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2013, 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_NUM_H 8 | #define SECP256K1_NUM_H 9 | 10 | #ifndef USE_NUM_NONE 11 | 12 | #if defined HAVE_CONFIG_H 13 | #include "libsecp256k1-config.h" 14 | #endif 15 | 16 | #if defined(USE_NUM_GMP) 17 | #include "num_gmp.h" 18 | #else 19 | #error "Please select num implementation" 20 | #endif 21 | 22 | /** Copy a number. */ 23 | static void secp256k1_num_copy(secp256k1_num *r, const secp256k1_num *a); 24 | 25 | /** Convert a number's absolute value to a binary big-endian string. 26 | * There must be enough place. */ 27 | static void secp256k1_num_get_bin(unsigned char *r, unsigned int rlen, const secp256k1_num *a); 28 | 29 | /** Set a number to the value of a binary big-endian string. */ 30 | static void secp256k1_num_set_bin(secp256k1_num *r, const unsigned char *a, unsigned int alen); 31 | 32 | /** Compute a modular inverse. The input must be less than the modulus. */ 33 | static void secp256k1_num_mod_inverse(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *m); 34 | 35 | /** Compute the jacobi symbol (a|b). b must be positive and odd. */ 36 | static int secp256k1_num_jacobi(const secp256k1_num *a, const secp256k1_num *b); 37 | 38 | /** Compare the absolute value of two numbers. */ 39 | static int secp256k1_num_cmp(const secp256k1_num *a, const secp256k1_num *b); 40 | 41 | /** Test whether two number are equal (including sign). */ 42 | static int secp256k1_num_eq(const secp256k1_num *a, const secp256k1_num *b); 43 | 44 | /** Add two (signed) numbers. */ 45 | static void secp256k1_num_add(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b); 46 | 47 | /** Subtract two (signed) numbers. */ 48 | static void secp256k1_num_sub(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b); 49 | 50 | /** Multiply two (signed) numbers. */ 51 | static void secp256k1_num_mul(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b); 52 | 53 | /** Replace a number by its remainder modulo m. M's sign is ignored. The result is a number between 0 and m-1, 54 | even if r was negative. */ 55 | static void secp256k1_num_mod(secp256k1_num *r, const secp256k1_num *m); 56 | 57 | /** Right-shift the passed number by bits bits. */ 58 | static void secp256k1_num_shift(secp256k1_num *r, int bits); 59 | 60 | /** Check whether a number is zero. */ 61 | static int secp256k1_num_is_zero(const secp256k1_num *a); 62 | 63 | /** Check whether a number is one. */ 64 | static int secp256k1_num_is_one(const secp256k1_num *a); 65 | 66 | /** Check whether a number is strictly negative. */ 67 | static int secp256k1_num_is_neg(const secp256k1_num *a); 68 | 69 | /** Change a number's sign. */ 70 | static void secp256k1_num_negate(secp256k1_num *r); 71 | 72 | #endif 73 | 74 | #endif /* SECP256K1_NUM_H */ 75 | -------------------------------------------------------------------------------- /src/secp256k1_tests/README.md: -------------------------------------------------------------------------------- 1 | libsecp256k1 2 | ============ 3 | 4 | Run tests and benchmarks for the secp256k1 elliptic curve cryptographic library on this RISC-V CPU. 5 | 6 | Description 7 | ----------- 8 | 9 | Optimized C library for EC operations on curve secp256k1. 10 | 11 | This library is a work in progress and is being used to research best practices. Use at your own risk. 12 | 13 | Features: 14 | * secp256k1 ECDSA signing/verification and key generation. 15 | * Adding/multiplying private/public keys. 16 | * Serialization/parsing of private keys, public keys, signatures. 17 | * Constant time, constant memory access signing and pubkey generation. 18 | * Derandomized DSA (via RFC6979 or with a caller provided function.) 19 | * Very efficient implementation. 20 | 21 | Implementation details 22 | ---------------------- 23 | 24 | * General 25 | * No runtime heap allocation. 26 | * Extensive testing infrastructure. 27 | * Structured to facilitate review and analysis. 28 | * Intended to be portable to any system with a C89 compiler and uint64_t support. 29 | * Expose only higher level interfaces to minimize the API surface and improve application security. ("Be difficult to use insecurely.") 30 | * Field operations 31 | * Optimized implementation of arithmetic modulo the curve's field size (2^256 - 0x1000003D1). 32 | * Using 5 52-bit limbs (including hand-optimized assembly for x86_64, by Diederik Huys). 33 | * Using 10 26-bit limbs. 34 | * Field inverses and square roots using a sliding window over blocks of 1s (by Peter Dettman). 35 | * Scalar operations 36 | * Optimized implementation without data-dependent branches of arithmetic modulo the curve's order. 37 | * Using 4 64-bit limbs (relying on __int128 support in the compiler). 38 | * Using 8 32-bit limbs. 39 | * Group operations 40 | * Point addition formula specifically simplified for the curve equation (y^2 = x^3 + 7). 41 | * Use addition between points in Jacobian and affine coordinates where possible. 42 | * Use a unified addition/doubling formula where necessary to avoid data-dependent branches. 43 | * Point/x comparison without a field inversion by comparison in the Jacobian coordinate space. 44 | * Point multiplication for verification (a*P + b*G). 45 | * Use wNAF notation for point multiplicands. 46 | * Use a much larger window for multiples of G, using precomputed multiples. 47 | * Use Shamir's trick to do the multiplication with the public key and the generator simultaneously. 48 | * Optionally (off by default) use secp256k1's efficiently-computable endomorphism to split the P multiplicand into 2 half-sized ones. 49 | * Point multiplication for signing 50 | * Use a precomputed table of multiples of powers of 16 multiplied with the generator, so general multiplication becomes a series of additions. 51 | * Access the table with branch-free conditional moves so memory access is uniform. 52 | * No data-dependent branches 53 | * The precomputed tables add and eventually subtract points for which no known scalar (private key) is known, preventing even an attacker with control over the private key used to control the data internally. 54 | 55 | -------------------------------------------------------------------------------- /util/esp8266at/src/mainloop.rs: -------------------------------------------------------------------------------- 1 | /** Example synchronous serial receive event loop (for std) */ 2 | use std::fmt; 3 | use std::io; 4 | 5 | use crate::handler::{NetworkEvent, SerialNetworkHandler}; 6 | use crate::response::{parse, ParseResult}; 7 | 8 | /** Mainloop handling serial input and dispatching network events */ 9 | pub fn mainloop( 10 | h: &mut SerialNetworkHandler, 11 | port: &mut P, 12 | mut f: F, 13 | debug: &mut dyn fmt::Write, 14 | ) -> io::Result<()> 15 | where 16 | P: io::Read, 17 | F: FnMut(&mut SerialNetworkHandler, NetworkEvent, &mut dyn fmt::Write) -> bool, 18 | X: io::Write, 19 | { 20 | let mut serial_buf: Vec = vec![0; 2560]; // 2048 + some 21 | let mut ofs: usize = 0; 22 | let mut running: bool = true; 23 | while running { 24 | // Receive bytes into buffer 25 | match port.read(&mut serial_buf[ofs..]) { 26 | Ok(t) => { 27 | // io::stdout().write_all(&serial_buf[ofs..ofs+t]).unwrap(); 28 | ofs += t; 29 | 30 | // Loop as long as there's something in the buffer to parse, starting at the 31 | // beginning 32 | let mut start = 0; 33 | while start < ofs { 34 | // try parsing 35 | let tail = &serial_buf[start..ofs]; 36 | let erase = match parse(tail) { 37 | ParseResult::Ok(offset, resp) => { 38 | h.message( 39 | &resp, 40 | |a, b, debug| { 41 | running = f(a, b, debug); 42 | }, 43 | debug, 44 | )?; 45 | 46 | offset 47 | } 48 | ParseResult::Incomplete => { 49 | // Incomplete, ignored, just retry after a new receive 50 | 0 51 | } 52 | ParseResult::Err => { 53 | writeln!(debug, "err: {:?}", tail).unwrap(); 54 | // Erase unparseable data to next line, if line is complete 55 | if let Some(ofs) = tail.iter().position(|&x| x == b'\n') { 56 | ofs + 1 57 | } else { 58 | // If not, retry next time 59 | 0 60 | } 61 | } 62 | }; 63 | if erase == 0 { 64 | // End of input or remainder unparseable 65 | break; 66 | } 67 | start += erase; 68 | } 69 | // Erase everything before new starting offset 70 | for i in start..ofs { 71 | serial_buf[i - start] = serial_buf[i]; 72 | } 73 | ofs -= start; 74 | } 75 | Err(ref e) if e.kind() == io::ErrorKind::TimedOut => (), 76 | Err(e) => return Err(e), 77 | } 78 | } 79 | Ok(()) 80 | } 81 | -------------------------------------------------------------------------------- /src/secp256k1_tests/scratch_impl.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2017 Andrew Poelstra * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef _SECP256K1_SCRATCH_IMPL_H_ 8 | #define _SECP256K1_SCRATCH_IMPL_H_ 9 | 10 | #include "scratch.h" 11 | 12 | /* Using 16 bytes alignment because common architectures never have alignment 13 | * requirements above 8 for any of the types we care about. In addition we 14 | * leave some room because currently we don't care about a few bytes. 15 | * TODO: Determine this at configure time. */ 16 | #define ALIGNMENT 16 17 | 18 | static secp256k1_scratch* secp256k1_scratch_create(const secp256k1_callback* error_callback, size_t max_size) { 19 | secp256k1_scratch* ret = (secp256k1_scratch*)checked_malloc(error_callback, sizeof(*ret)); 20 | if (ret != NULL) { 21 | memset(ret, 0, sizeof(*ret)); 22 | ret->max_size = max_size; 23 | ret->error_callback = error_callback; 24 | } 25 | return ret; 26 | } 27 | 28 | static void secp256k1_scratch_destroy(secp256k1_scratch* scratch) { 29 | if (scratch != NULL) { 30 | VERIFY_CHECK(scratch->frame == 0); 31 | free(scratch); 32 | } 33 | } 34 | 35 | static size_t secp256k1_scratch_max_allocation(const secp256k1_scratch* scratch, size_t objects) { 36 | size_t i = 0; 37 | size_t allocated = 0; 38 | for (i = 0; i < scratch->frame; i++) { 39 | allocated += scratch->frame_size[i]; 40 | } 41 | if (scratch->max_size - allocated <= objects * ALIGNMENT) { 42 | return 0; 43 | } 44 | return scratch->max_size - allocated - objects * ALIGNMENT; 45 | } 46 | 47 | static int secp256k1_scratch_allocate_frame(secp256k1_scratch* scratch, size_t n, size_t objects) { 48 | VERIFY_CHECK(scratch->frame < SECP256K1_SCRATCH_MAX_FRAMES); 49 | 50 | if (n <= secp256k1_scratch_max_allocation(scratch, objects)) { 51 | n += objects * ALIGNMENT; 52 | scratch->data[scratch->frame] = checked_malloc(scratch->error_callback, n); 53 | if (scratch->data[scratch->frame] == NULL) { 54 | return 0; 55 | } 56 | scratch->frame_size[scratch->frame] = n; 57 | scratch->offset[scratch->frame] = 0; 58 | scratch->frame++; 59 | return 1; 60 | } else { 61 | return 0; 62 | } 63 | } 64 | 65 | static void secp256k1_scratch_deallocate_frame(secp256k1_scratch* scratch) { 66 | VERIFY_CHECK(scratch->frame > 0); 67 | scratch->frame -= 1; 68 | free(scratch->data[scratch->frame]); 69 | } 70 | 71 | static void *secp256k1_scratch_alloc(secp256k1_scratch* scratch, size_t size) { 72 | void *ret; 73 | size_t frame = scratch->frame - 1; 74 | size = ((size + ALIGNMENT - 1) / ALIGNMENT) * ALIGNMENT; 75 | 76 | if (scratch->frame == 0 || size + scratch->offset[frame] > scratch->frame_size[frame]) { 77 | return NULL; 78 | } 79 | ret = (void *) ((unsigned char *) scratch->data[frame] + scratch->offset[frame]); 80 | memset(ret, 0, size); 81 | scratch->offset[frame] += size; 82 | 83 | return ret; 84 | } 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /rust/k210-shared/src/soc/pwm.rs: -------------------------------------------------------------------------------- 1 | //! TIMER peripherals (PWM handling) 2 | use k210_hal::pac; 3 | use core::ops::Deref; 4 | use pac::{timer0,TIMER0,TIMER1,TIMER2}; 5 | 6 | use crate::soc::sysctl; 7 | 8 | #[derive(Copy, Clone, PartialEq, Eq)] 9 | pub enum Channel { 10 | CH1 = 0, 11 | CH2, 12 | CH3, 13 | CH4, 14 | } 15 | impl Channel { 16 | pub fn idx(self) -> usize { self as usize } 17 | } 18 | 19 | pub trait TimerExt: Deref + Sized { 20 | #[doc(hidden)] 21 | const CLK: sysctl::clock; 22 | #[doc(hidden)] 23 | const DIV: sysctl::threshold; 24 | 25 | /// Constrains TIMER peripheral for PWM use 26 | /// A timer channel can either be used for PWM or as a normal timer (say, for interrupt 27 | /// generation). Currently this has a larger granularity than needed and 28 | /// constrains the entire peripheral for PWM use. 29 | fn constrain_pwm(self) -> PWMImpl; 30 | } 31 | 32 | impl TimerExt for TIMER0 { 33 | const CLK: sysctl::clock = sysctl::clock::TIMER0; 34 | const DIV: sysctl::threshold = sysctl::threshold::TIMER0; 35 | 36 | fn constrain_pwm(self) -> PWMImpl { PWMImpl:: { timer: self } } 37 | } 38 | impl TimerExt for TIMER1 { 39 | const CLK: sysctl::clock = sysctl::clock::TIMER1; 40 | const DIV: sysctl::threshold = sysctl::threshold::TIMER1; 41 | 42 | fn constrain_pwm(self) -> PWMImpl { PWMImpl:: { timer: self } } 43 | } 44 | impl TimerExt for TIMER2 { 45 | const CLK: sysctl::clock = sysctl::clock::TIMER2; 46 | const DIV: sysctl::threshold = sysctl::threshold::TIMER2; 47 | 48 | fn constrain_pwm(self) -> PWMImpl { PWMImpl:: { timer: self } } 49 | } 50 | 51 | /** Trait for PWM control */ 52 | pub trait PWM { 53 | // TODO: make this per channel, and use the PWM trait from Rust embedded 54 | fn start(&self, ch: Channel); 55 | fn stop(&self, ch: Channel); 56 | fn set(&self, ch: Channel, freq: u32, value: f32) -> u32; 57 | } 58 | 59 | pub struct PWMImpl { 60 | timer: TIMER, 61 | } 62 | 63 | impl PWM for PWMImpl { 64 | /** Start a PWM channel */ 65 | fn start(&self, ch: Channel) { 66 | unsafe { 67 | use pac::timer0::channel::control::MODE_A; 68 | 69 | // set a deterministic value for load counts 70 | self.timer.channel[ch.idx()].load_count.write(|w| w.bits(1)); 71 | self.timer.load_count2[ch.idx()].write(|w| w.bits(1)); 72 | // start channel 73 | self.timer.channel[ch.idx()].control.write( 74 | |w| w.interrupt().set_bit() 75 | .pwm_enable().set_bit() 76 | .mode().variant(MODE_A::USER) 77 | .enable().set_bit()); 78 | } 79 | } 80 | 81 | /** Stop a PWM channel */ 82 | fn stop(&self, ch: Channel) { 83 | self.timer.channel[ch.idx()].control.write( 84 | |w| w.interrupt().set_bit()); 85 | } 86 | 87 | /** Set frequency and value for a PWM channel */ 88 | fn set(&self, ch: Channel, freq: u32, value: f32) -> u32 { 89 | let clk_freq = sysctl::clock_get_freq(TIMER::CLK); 90 | let periods = clk_freq / freq; 91 | let percent = (value * (periods as f32)) as u32; 92 | unsafe { 93 | self.timer.channel[ch.idx()].load_count.write(|w| w.bits(periods - percent)); 94 | self.timer.load_count2[ch.idx()].write(|w| w.bits(percent)); 95 | } 96 | clk_freq / periods 97 | } 98 | } 99 | 100 | -------------------------------------------------------------------------------- /rust/uart-passthrough/src/main.rs: -------------------------------------------------------------------------------- 1 | #![allow(dead_code)] 2 | #![allow(non_snake_case)] 3 | #![allow(non_camel_case_types)] 4 | #![no_std] 5 | #![no_main] 6 | 7 | use k210_hal::pac::Peripherals; 8 | use k210_hal::prelude::*; 9 | use k210_hal::serial::Serial; 10 | use k210_shared::board::def::io; 11 | use k210_shared::soc::fpioa; 12 | use k210_shared::soc::gpio; 13 | use k210_shared::soc::gpiohs; 14 | use k210_shared::soc::sleep::usleep; 15 | use k210_shared::soc::sysctl; 16 | use nb::block; 17 | use riscv_rt::entry; 18 | 19 | const DEFAULT_BAUD: u32 = 115_200; 20 | 21 | #[entry] 22 | fn main() -> ! { 23 | let p = Peripherals::take().unwrap(); 24 | sysctl::pll_set_freq(sysctl::pll::PLL0, 800_000_000).unwrap(); 25 | sysctl::pll_set_freq(sysctl::pll::PLL1, 300_000_000).unwrap(); 26 | sysctl::pll_set_freq(sysctl::pll::PLL2, 45_158_400).unwrap(); 27 | let clocks = k210_hal::clock::Clocks::new(); 28 | 29 | // Configure UARTHS (→host) 30 | let mut serial = p.UARTHS.configure( DEFAULT_BAUD.bps(), &clocks); 31 | let (mut tx, mut rx) = serial.split(); 32 | 33 | // Configure UART1 (→WIFI) 34 | sysctl::clock_enable(sysctl::clock::UART1); 35 | sysctl::reset(sysctl::reset::UART1); 36 | fpioa::set_function(io::WIFI_RX, fpioa::function::UART1_TX); 37 | fpioa::set_function(io::WIFI_TX, fpioa::function::UART1_RX); 38 | fpioa::set_function(io::WIFI_EN, fpioa::function::GPIOHS8); 39 | fpioa::set_io_pull(io::WIFI_EN, fpioa::pull::DOWN); 40 | gpiohs::set_pin(8, true); 41 | gpiohs::set_direction(8, gpio::direction::OUTPUT); 42 | let mut wifi_serial = p.UART1.configure(DEFAULT_BAUD.bps(), &clocks); 43 | let (mut wtx, mut wrx) = wifi_serial.split(); 44 | 45 | // Relay characters between UARTs 46 | loop { 47 | if !gpiohs::get_pin(0) { // IO16 == DTR pulled low for Out-of-Band command 48 | // OOB restores safe baudrate for UARTHS, to be sure we're able to recover from 49 | // sync failures 50 | let mut rate = DEFAULT_BAUD; 51 | let userial = Serial::join(tx, rx).free(); 52 | serial = userial.configure(rate.bps(), &clocks); 53 | let s = serial.split(); 54 | tx = s.0; 55 | rx = s.1; 56 | 57 | match block!(rx.read()).unwrap() { 58 | 0x23 => { // Set baudrate 59 | let mut d = [0u8; 4]; 60 | d.iter_mut().for_each(|x| { *x = block!(rx.read()).unwrap() }); 61 | rate = u32::from(d[0]) | (u32::from(d[1]) << 8) | (u32::from(d[2]) << 16) | (u32::from(d[3]) << 24); 62 | 63 | // re-configure UARTHS at new rate 64 | let userial = Serial::join(tx, rx).free(); 65 | serial = userial.configure(rate.bps(), &clocks); 66 | let s = serial.split(); 67 | tx = s.0; 68 | rx = s.1; 69 | } 70 | 0x42 => { // WIFI reset 71 | gpiohs::set_pin(8, false); 72 | usleep(100000); 73 | gpiohs::set_pin(8, true); 74 | } 75 | _ => {} 76 | } 77 | // re-configure UART1 78 | let wifi_userial = Serial::join(wtx, wrx).free(); 79 | wifi_serial = wifi_userial.configure(rate.bps(), &clocks); 80 | let s = wifi_serial.split(); 81 | wtx = s.0; 82 | wrx = s.1; 83 | } 84 | if let Ok(ch) = wrx.read() { 85 | let _res = block!(tx.write(ch)); 86 | } 87 | if let Ok(ch) = rx.read() { 88 | let _res = block!(wtx.write(ch)); 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /rust/k210-console/scripts/gencolorfont.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | ''' 3 | Slice an image (or multiple images) into 8x8 chunks (tiles) and deduplicate 4 | them to create a color font and a sequence of characters that represents the 5 | original image(s). 6 | ''' 7 | import sys 8 | from PIL import Image 9 | import struct 10 | 11 | BW=8 # tile width 12 | BH=8 # tile height 13 | BG=(0,0,0) # RGB color for background (hardcoded, could be configurable) 14 | 15 | def rgb565(color): 16 | '''Truncate RGB888[8] color to RGB565''' 17 | return ((color[0] >> 3) << 11) | ((color[1] >> 2) << 5) | (color[2] >> 3) 18 | 19 | def extract_block(img, coord): 20 | '''Extract a RGB block from an image.''' 21 | data = [] 22 | for yi in range(0, BH): 23 | row = [] 24 | for xi in range(0, BW): 25 | try: 26 | row.append(img.getpixel((coord[0] + xi, coord[1] + yi))) 27 | except IndexError: 28 | row.append(BG) 29 | data.append(row) 30 | return data 31 | 32 | def encode_block(block): 33 | '''Encode RGB block to 32-bit column-swizzled RGB565''' 34 | out = [] 35 | for yi in range(0, BH): 36 | for xi in range(0, BW//2): 37 | out.append( 38 | (rgb565(block[yi][xi*2 + 0]) << 0) | 39 | rgb565(block[yi][xi*2 + 1]) << 16) 40 | return tuple(out) 41 | 42 | assert(len(sys.argv) >= 3) 43 | infiles = sys.argv[1:-1] 44 | outfile = sys.argv[-1] 45 | 46 | images = [(infile, Image.open(infile)) for infile in infiles] 47 | 48 | # character set, addressed by content 49 | charset = {} 50 | 51 | # add empty block as character 0 52 | empty_block = encode_block([[BG]*BW]*BH) 53 | charset[empty_block] = 0 54 | 55 | # sequence of characters to represent every image 56 | seq = [] 57 | for (infile, img) in images: 58 | blocks_x = (img.size[0] + (BW-1))//BW 59 | blocks_y = (img.size[1] + (BH-1))//BH 60 | 61 | print(f'{infile}: {blocks_x}×{blocks_y}') 62 | 63 | out = [] 64 | for by in range(0, blocks_y): 65 | row = [] 66 | for bx in range(0, blocks_x): 67 | bd = encode_block(extract_block(img, (bx * BW, by * BH))) 68 | try: 69 | # re-use existing matching character 70 | ch = charset[bd] 71 | except KeyError: 72 | # add character to character set 73 | ch = len(charset) 74 | charset[bd] = ch 75 | row.append(ch) 76 | out.append(row) 77 | seq.append((out, blocks_x, blocks_y)) 78 | 79 | m = len(empty_block) 80 | n = len(charset) 81 | print(f'used {n} characters') 82 | 83 | charset_by_ch = [None] * n 84 | for (bd, ch) in charset.items(): 85 | charset_by_ch[ch] = bd 86 | 87 | with open(outfile, 'w') as f: 88 | f.write(f'/* Auto-generated from {infile} by gencolorfont.py */\n') 89 | f.write('#[rustfmt::skip]\n') 90 | f.write(f'pub static FONT: [[u32; {m}]; {n}] = [\n') 91 | for bd in charset_by_ch: 92 | f.write(' [') 93 | for val in bd: 94 | f.write(f'0x{val:08x}, ') 95 | f.write('],\n') 96 | 97 | f.write('];\n') 98 | f.write('\n') 99 | 100 | # TODO: output sequence; RLE encoding of some kind? 101 | for (i,(out,blocks_x,blocks_y)) in enumerate(seq): 102 | f.write('#[rustfmt::skip]\n') 103 | f.write(f'pub static SEQ{i}: [[u16; {blocks_x}]; {blocks_y}] = [\n') 104 | for subseq in out: 105 | f.write(' [') 106 | for val in subseq: 107 | f.write(f'0x{val:04x}, ') 108 | f.write('],\n') 109 | f.write('];\n') 110 | -------------------------------------------------------------------------------- /src/secp256k1_bench/util.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2013, 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_UTIL_H 8 | #define SECP256K1_UTIL_H 9 | 10 | #if defined HAVE_CONFIG_H 11 | #include "libsecp256k1-config.h" 12 | #endif 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | typedef struct { 19 | void (*fn)(const char *text, void* data); 20 | const void* data; 21 | } secp256k1_callback; 22 | 23 | static SECP256K1_INLINE void secp256k1_callback_call(const secp256k1_callback * const cb, const char * const text) { 24 | cb->fn(text, (void*)cb->data); 25 | } 26 | 27 | #ifdef DETERMINISTIC 28 | #define TEST_FAILURE(msg) do { \ 29 | fprintf(stderr, "%s\n", msg); \ 30 | abort(); \ 31 | } while(0); 32 | #else 33 | #define TEST_FAILURE(msg) do { \ 34 | fprintf(stderr, "%s:%d: %s\n", __FILE__, __LINE__, msg); \ 35 | abort(); \ 36 | } while(0) 37 | #endif 38 | 39 | #if SECP256K1_GNUC_PREREQ(3, 0) 40 | #define EXPECT(x,c) __builtin_expect((x),(c)) 41 | #else 42 | #define EXPECT(x,c) (x) 43 | #endif 44 | 45 | #ifdef DETERMINISTIC 46 | #define CHECK(cond) do { \ 47 | if (EXPECT(!(cond), 0)) { \ 48 | TEST_FAILURE("test condition failed"); \ 49 | } \ 50 | } while(0) 51 | #else 52 | #define CHECK(cond) do { \ 53 | if (EXPECT(!(cond), 0)) { \ 54 | TEST_FAILURE("test condition failed: " #cond); \ 55 | } \ 56 | } while(0) 57 | #endif 58 | 59 | /* Like assert(), but when VERIFY is defined, and side-effect safe. */ 60 | #if defined(COVERAGE) 61 | #define VERIFY_CHECK(check) 62 | #define VERIFY_SETUP(stmt) 63 | #elif defined(VERIFY) 64 | #define VERIFY_CHECK CHECK 65 | #define VERIFY_SETUP(stmt) do { stmt; } while(0) 66 | #else 67 | #define VERIFY_CHECK(cond) do { (void)(cond); } while(0) 68 | #define VERIFY_SETUP(stmt) 69 | #endif 70 | 71 | static SECP256K1_INLINE void *checked_malloc(const secp256k1_callback* cb, size_t size) { 72 | void *ret = malloc(size); 73 | if (ret == NULL) { 74 | secp256k1_callback_call(cb, "Out of memory"); 75 | } 76 | return ret; 77 | } 78 | 79 | static SECP256K1_INLINE void *checked_realloc(const secp256k1_callback* cb, void *ptr, size_t size) { 80 | void *ret = realloc(ptr, size); 81 | if (ret == NULL) { 82 | secp256k1_callback_call(cb, "Out of memory"); 83 | } 84 | return ret; 85 | } 86 | 87 | /* Macro for restrict, when available and not in a VERIFY build. */ 88 | #if defined(SECP256K1_BUILD) && defined(VERIFY) 89 | # define SECP256K1_RESTRICT 90 | #else 91 | # if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) ) 92 | # if SECP256K1_GNUC_PREREQ(3,0) 93 | # define SECP256K1_RESTRICT __restrict__ 94 | # elif (defined(_MSC_VER) && _MSC_VER >= 1400) 95 | # define SECP256K1_RESTRICT __restrict 96 | # else 97 | # define SECP256K1_RESTRICT 98 | # endif 99 | # else 100 | # define SECP256K1_RESTRICT restrict 101 | # endif 102 | #endif 103 | 104 | #if defined(_WIN32) 105 | # define I64FORMAT "I64d" 106 | # define I64uFORMAT "I64u" 107 | #else 108 | # define I64FORMAT "lld" 109 | # define I64uFORMAT "llu" 110 | #endif 111 | 112 | #if defined(HAVE___INT128) 113 | # if defined(__GNUC__) 114 | # define SECP256K1_GNUC_EXT __extension__ 115 | # else 116 | # define SECP256K1_GNUC_EXT 117 | # endif 118 | SECP256K1_GNUC_EXT typedef unsigned __int128 uint128_t; 119 | #endif 120 | 121 | #endif /* SECP256K1_UTIL_H */ 122 | -------------------------------------------------------------------------------- /src/secp256k1_tests/util.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2013, 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_UTIL_H 8 | #define SECP256K1_UTIL_H 9 | 10 | #if defined HAVE_CONFIG_H 11 | #include "libsecp256k1-config.h" 12 | #endif 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | typedef struct { 19 | void (*fn)(const char *text, void* data); 20 | const void* data; 21 | } secp256k1_callback; 22 | 23 | static SECP256K1_INLINE void secp256k1_callback_call(const secp256k1_callback * const cb, const char * const text) { 24 | cb->fn(text, (void*)cb->data); 25 | } 26 | 27 | #ifdef DETERMINISTIC 28 | #define TEST_FAILURE(msg) do { \ 29 | fprintf(stderr, "%s\n", msg); \ 30 | abort(); \ 31 | } while(0); 32 | #else 33 | #define TEST_FAILURE(msg) do { \ 34 | fprintf(stderr, "%s:%d: %s\n", __FILE__, __LINE__, msg); \ 35 | abort(); \ 36 | } while(0) 37 | #endif 38 | 39 | #if SECP256K1_GNUC_PREREQ(3, 0) 40 | #define EXPECT(x,c) __builtin_expect((x),(c)) 41 | #else 42 | #define EXPECT(x,c) (x) 43 | #endif 44 | 45 | #ifdef DETERMINISTIC 46 | #define CHECK(cond) do { \ 47 | if (EXPECT(!(cond), 0)) { \ 48 | TEST_FAILURE("test condition failed"); \ 49 | } \ 50 | } while(0) 51 | #else 52 | #define CHECK(cond) do { \ 53 | if (EXPECT(!(cond), 0)) { \ 54 | TEST_FAILURE("test condition failed: " #cond); \ 55 | } \ 56 | } while(0) 57 | #endif 58 | 59 | /* Like assert(), but when VERIFY is defined, and side-effect safe. */ 60 | #if defined(COVERAGE) 61 | #define VERIFY_CHECK(check) 62 | #define VERIFY_SETUP(stmt) 63 | #elif defined(VERIFY) 64 | #define VERIFY_CHECK CHECK 65 | #define VERIFY_SETUP(stmt) do { stmt; } while(0) 66 | #else 67 | #define VERIFY_CHECK(cond) do { (void)(cond); } while(0) 68 | #define VERIFY_SETUP(stmt) 69 | #endif 70 | 71 | static SECP256K1_INLINE void *checked_malloc(const secp256k1_callback* cb, size_t size) { 72 | void *ret = malloc(size); 73 | if (ret == NULL) { 74 | secp256k1_callback_call(cb, "Out of memory"); 75 | } 76 | return ret; 77 | } 78 | 79 | static SECP256K1_INLINE void *checked_realloc(const secp256k1_callback* cb, void *ptr, size_t size) { 80 | void *ret = realloc(ptr, size); 81 | if (ret == NULL) { 82 | secp256k1_callback_call(cb, "Out of memory"); 83 | } 84 | return ret; 85 | } 86 | 87 | /* Macro for restrict, when available and not in a VERIFY build. */ 88 | #if defined(SECP256K1_BUILD) && defined(VERIFY) 89 | # define SECP256K1_RESTRICT 90 | #else 91 | # if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) ) 92 | # if SECP256K1_GNUC_PREREQ(3,0) 93 | # define SECP256K1_RESTRICT __restrict__ 94 | # elif (defined(_MSC_VER) && _MSC_VER >= 1400) 95 | # define SECP256K1_RESTRICT __restrict 96 | # else 97 | # define SECP256K1_RESTRICT 98 | # endif 99 | # else 100 | # define SECP256K1_RESTRICT restrict 101 | # endif 102 | #endif 103 | 104 | #if defined(_WIN32) 105 | # define I64FORMAT "I64d" 106 | # define I64uFORMAT "I64u" 107 | #else 108 | # define I64FORMAT "lld" 109 | # define I64uFORMAT "llu" 110 | #endif 111 | 112 | #if defined(HAVE___INT128) 113 | # if defined(__GNUC__) 114 | # define SECP256K1_GNUC_EXT __extension__ 115 | # else 116 | # define SECP256K1_GNUC_EXT 117 | # endif 118 | SECP256K1_GNUC_EXT typedef unsigned __int128 uint128_t; 119 | #endif 120 | 121 | #endif /* SECP256K1_UTIL_H */ 122 | -------------------------------------------------------------------------------- /rust/mandelbrot/src/main.rs: -------------------------------------------------------------------------------- 1 | #![allow(dead_code)] 2 | #![allow(non_snake_case)] 3 | #![allow(non_camel_case_types)] 4 | #![no_std] 5 | #![no_main] 6 | 7 | mod palette; 8 | 9 | use k210_hal::pac::Peripherals; 10 | use k210_hal::prelude::*; 11 | use k210_hal::stdout::Stdout; 12 | use k210_shared::board::def::{io,DISP_WIDTH,DISP_HEIGHT}; 13 | use k210_shared::board::lcd::{LCD,LCDHL,self}; 14 | use k210_shared::board::lcd_colors; 15 | use k210_shared::board::lcd_render::render_image; 16 | use k210_shared::soc::fpioa; 17 | use k210_shared::soc::sleep::usleep; 18 | use k210_shared::soc::spi::SPIExt; 19 | use k210_shared::soc::sysctl; 20 | use k210_shared::soc::dmac::{DMACExt, dma_channel}; 21 | use riscv_rt::entry; 22 | 23 | use crate::palette::PALETTE; 24 | 25 | /** Connect pins to internal functions */ 26 | fn io_mux_init() { 27 | /* Init SPI IO map and function settings */ 28 | fpioa::set_function(io::LCD_RST, fpioa::function::gpiohs(lcd::RST_GPIONUM)); 29 | fpioa::set_io_pull(io::LCD_RST, fpioa::pull::DOWN); // outputs must be pull-down 30 | fpioa::set_function(io::LCD_DC, fpioa::function::gpiohs(lcd::DCX_GPIONUM)); 31 | fpioa::set_io_pull(io::LCD_DC, fpioa::pull::DOWN); 32 | fpioa::set_function(io::LCD_CS, fpioa::function::SPI0_SS3); 33 | fpioa::set_function(io::LCD_WR, fpioa::function::SPI0_SCLK); 34 | 35 | sysctl::set_spi0_dvp_data(true); 36 | } 37 | 38 | /** Set correct voltage for pins */ 39 | fn io_set_power() { 40 | /* Set dvp and spi pin to 1.8V */ 41 | sysctl::set_power_mode(sysctl::power_bank::BANK6, sysctl::io_power_mode::V18); 42 | sysctl::set_power_mode(sysctl::power_bank::BANK7, sysctl::io_power_mode::V18); 43 | } 44 | 45 | fn mandelbrot(cx: f32, cy: f32, iterations: u32) -> u32 { 46 | let mut z: (f32, f32) = (0.0, 0.0); 47 | let mut i: u32 = 0; 48 | while (z.0*z.0 + z.1*z.1) < 2.0*2.0 && i < iterations { 49 | z = (z.0 * z.0 - z.1 * z.1 + cx, 2.0 * z.0 * z.1 + cy); 50 | i += 1; 51 | } 52 | i 53 | } 54 | 55 | #[entry] 56 | fn main() -> ! { 57 | let p = Peripherals::take().unwrap(); 58 | 59 | // Configure clocks (TODO) 60 | sysctl::pll_set_freq(sysctl::pll::PLL0, 800_000_000).unwrap(); 61 | sysctl::pll_set_freq(sysctl::pll::PLL1, 300_000_000).unwrap(); 62 | sysctl::pll_set_freq(sysctl::pll::PLL2, 45_158_400).unwrap(); 63 | let clocks = k210_hal::clock::Clocks::new(); 64 | 65 | usleep(200000); 66 | 67 | // Configure UART 68 | let serial = p.UARTHS.configure(115_200.bps(), &clocks); 69 | let (mut tx, _) = serial.split(); 70 | 71 | let mut stdout = Stdout(&mut tx); 72 | 73 | io_mux_init(); 74 | io_set_power(); 75 | 76 | writeln!(stdout, "Init DMAC").unwrap(); 77 | let dmac = p.DMAC.configure(); 78 | let chan = dma_channel::CHANNEL0; 79 | writeln!(stdout, "DMAC: id 0x{:x} version 0x{:x} AXI ID 0x{:x}", 80 | dmac.read_id(), dmac.read_version(), dmac.read_channel_id(chan)).unwrap(); 81 | 82 | let spi = p.SPI0.constrain(); 83 | let mut lcd = LCD::new(spi, &dmac, chan); 84 | lcd.init(); 85 | lcd.set_direction(lcd::direction::YX_RLDU); 86 | lcd.clear(lcd_colors::PURPLE); 87 | 88 | writeln!(stdout, "First frame").unwrap(); 89 | let mut zoom = 5.0f32; 90 | let ofsx = 0.02997f32; 91 | let ofsy = 0.80386f32; 92 | loop { 93 | render_image(&mut lcd, |x,y| { 94 | let xx = 2.0 * (x as f32) / ((DISP_WIDTH-1) as f32) - 1.0; 95 | let yy = 2.0 * (y as f32) / ((DISP_HEIGHT-1) as f32) - 1.0; 96 | let i = mandelbrot(xx * zoom + ofsx, yy * zoom + ofsy, 20); 97 | 98 | PALETTE[i as usize] 99 | }); 100 | 101 | zoom *= 0.98f32; 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /src/secp256k1_tests/eckey_impl.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2013, 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_ECKEY_IMPL_H 8 | #define SECP256K1_ECKEY_IMPL_H 9 | 10 | #include "eckey.h" 11 | 12 | #include "scalar.h" 13 | #include "field.h" 14 | #include "group.h" 15 | #include "ecmult_gen.h" 16 | 17 | static int secp256k1_eckey_pubkey_parse(secp256k1_ge *elem, const unsigned char *pub, size_t size) { 18 | if (size == 33 && (pub[0] == SECP256K1_TAG_PUBKEY_EVEN || pub[0] == SECP256K1_TAG_PUBKEY_ODD)) { 19 | secp256k1_fe x; 20 | return secp256k1_fe_set_b32(&x, pub+1) && secp256k1_ge_set_xo_var(elem, &x, pub[0] == SECP256K1_TAG_PUBKEY_ODD); 21 | } else if (size == 65 && (pub[0] == SECP256K1_TAG_PUBKEY_UNCOMPRESSED || pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_EVEN || pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_ODD)) { 22 | secp256k1_fe x, y; 23 | if (!secp256k1_fe_set_b32(&x, pub+1) || !secp256k1_fe_set_b32(&y, pub+33)) { 24 | return 0; 25 | } 26 | secp256k1_ge_set_xy(elem, &x, &y); 27 | if ((pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_EVEN || pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_ODD) && 28 | secp256k1_fe_is_odd(&y) != (pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_ODD)) { 29 | return 0; 30 | } 31 | return secp256k1_ge_is_valid_var(elem); 32 | } else { 33 | return 0; 34 | } 35 | } 36 | 37 | static int secp256k1_eckey_pubkey_serialize(secp256k1_ge *elem, unsigned char *pub, size_t *size, int compressed) { 38 | if (secp256k1_ge_is_infinity(elem)) { 39 | return 0; 40 | } 41 | secp256k1_fe_normalize_var(&elem->x); 42 | secp256k1_fe_normalize_var(&elem->y); 43 | secp256k1_fe_get_b32(&pub[1], &elem->x); 44 | if (compressed) { 45 | *size = 33; 46 | pub[0] = secp256k1_fe_is_odd(&elem->y) ? SECP256K1_TAG_PUBKEY_ODD : SECP256K1_TAG_PUBKEY_EVEN; 47 | } else { 48 | *size = 65; 49 | pub[0] = SECP256K1_TAG_PUBKEY_UNCOMPRESSED; 50 | secp256k1_fe_get_b32(&pub[33], &elem->y); 51 | } 52 | return 1; 53 | } 54 | 55 | static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar *key, const secp256k1_scalar *tweak) { 56 | secp256k1_scalar_add(key, key, tweak); 57 | if (secp256k1_scalar_is_zero(key)) { 58 | return 0; 59 | } 60 | return 1; 61 | } 62 | 63 | static int secp256k1_eckey_pubkey_tweak_add(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak) { 64 | secp256k1_gej pt; 65 | secp256k1_scalar one; 66 | secp256k1_gej_set_ge(&pt, key); 67 | secp256k1_scalar_set_int(&one, 1); 68 | secp256k1_ecmult(ctx, &pt, &pt, &one, tweak); 69 | 70 | if (secp256k1_gej_is_infinity(&pt)) { 71 | return 0; 72 | } 73 | secp256k1_ge_set_gej(key, &pt); 74 | return 1; 75 | } 76 | 77 | static int secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar *key, const secp256k1_scalar *tweak) { 78 | if (secp256k1_scalar_is_zero(tweak)) { 79 | return 0; 80 | } 81 | 82 | secp256k1_scalar_mul(key, key, tweak); 83 | return 1; 84 | } 85 | 86 | static int secp256k1_eckey_pubkey_tweak_mul(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak) { 87 | secp256k1_scalar zero; 88 | secp256k1_gej pt; 89 | if (secp256k1_scalar_is_zero(tweak)) { 90 | return 0; 91 | } 92 | 93 | secp256k1_scalar_set_int(&zero, 0); 94 | secp256k1_gej_set_ge(&pt, key); 95 | secp256k1_ecmult(ctx, &pt, &pt, tweak, &zero); 96 | secp256k1_ge_set_gej(key, &pt); 97 | return 1; 98 | } 99 | 100 | #endif /* SECP256K1_ECKEY_IMPL_H */ 101 | -------------------------------------------------------------------------------- /rust/accelerometer/src/main.rs: -------------------------------------------------------------------------------- 1 | #![allow(dead_code)] 2 | #![allow(non_snake_case)] 3 | #![allow(non_camel_case_types)] 4 | #![no_std] 5 | #![no_main] 6 | 7 | use k210_hal::pac::Peripherals; 8 | use k210_hal::prelude::*; 9 | use k210_hal::stdout::Stdout; 10 | use k210_shared::board::def::{io,DISP_WIDTH,DISP_HEIGHT,MSA300_SLV_ADDR,MSA300_ADDR_BITS,MSA300_CLK}; 11 | use k210_shared::board::lcd::{LCD,LCDHL,self}; 12 | use k210_shared::board::lcd_colors; 13 | use k210_shared::board::lcd_render::render_image; 14 | use k210_shared::board::msa300::Accelerometer; 15 | use k210_shared::soc::dmac::{DMACExt, dma_channel}; 16 | use k210_shared::soc::fpioa; 17 | use k210_shared::soc::i2c::{I2C,I2CExt}; 18 | use k210_shared::soc::sleep::usleep; 19 | use k210_shared::soc::spi::SPIExt; 20 | use k210_shared::soc::sysctl; 21 | use libm::F32Ext; 22 | use riscv_rt::entry; 23 | 24 | /** Connect pins to internal functions */ 25 | fn io_mux_init() { 26 | /* Init SPI IO map and function settings */ 27 | fpioa::set_function(io::LCD_RST, fpioa::function::gpiohs(lcd::RST_GPIONUM)); 28 | fpioa::set_io_pull(io::LCD_RST, fpioa::pull::DOWN); // outputs must be pull-down 29 | fpioa::set_function(io::LCD_DC, fpioa::function::gpiohs(lcd::DCX_GPIONUM)); 30 | fpioa::set_io_pull(io::LCD_DC, fpioa::pull::DOWN); 31 | fpioa::set_function(io::LCD_CS, fpioa::function::SPI0_SS3); 32 | fpioa::set_function(io::LCD_WR, fpioa::function::SPI0_SCLK); 33 | 34 | /* I2C0 for touch-screen */ 35 | fpioa::set_function(io::I2C1_SCL, fpioa::function::I2C0_SCLK); 36 | fpioa::set_function(io::I2C1_SDA, fpioa::function::I2C0_SDA); 37 | 38 | sysctl::set_spi0_dvp_data(true); 39 | } 40 | 41 | /** Set correct voltage for pins */ 42 | fn io_set_power() { 43 | /* Set dvp and spi pin to 1.8V */ 44 | sysctl::set_power_mode(sysctl::power_bank::BANK6, sysctl::io_power_mode::V18); 45 | sysctl::set_power_mode(sysctl::power_bank::BANK7, sysctl::io_power_mode::V18); 46 | } 47 | 48 | fn sample_cirle(x: i32, y: i32, cx: i32, cy: i32, r: i32, rr: i32) -> bool { 49 | // Early-out based on bounding box 50 | (x - cx).abs() <= r && (y - cy).abs() <= r && 51 | ((x - cx) * (x - cx) + (y - cy) * (y - cy)) <= rr 52 | } 53 | 54 | #[entry] 55 | fn main() -> ! { 56 | let p = Peripherals::take().unwrap(); 57 | 58 | sysctl::pll_set_freq(sysctl::pll::PLL0, 800_000_000).unwrap(); 59 | sysctl::pll_set_freq(sysctl::pll::PLL1, 300_000_000).unwrap(); 60 | sysctl::pll_set_freq(sysctl::pll::PLL2, 45_158_400).unwrap(); 61 | let clocks = k210_hal::clock::Clocks::new(); 62 | 63 | usleep(200000); 64 | 65 | // Configure UART 66 | let serial = p.UARTHS.configure(115_200.bps(), &clocks); 67 | let (mut tx, _) = serial.split(); 68 | 69 | let mut stdout = Stdout(&mut tx); 70 | 71 | io_mux_init(); 72 | io_set_power(); 73 | 74 | let dmac = p.DMAC.configure(); 75 | let spi = p.SPI0.constrain(); 76 | let mut lcd = LCD::new(spi, &dmac, dma_channel::CHANNEL0); 77 | lcd.init(); 78 | lcd.set_direction(lcd::direction::YX_LRUD); 79 | lcd.clear(lcd_colors::PURPLE); 80 | 81 | writeln!(stdout, "MSA300 init").unwrap(); 82 | let i2c = p.I2C0.constrain(); 83 | i2c.init(MSA300_SLV_ADDR, MSA300_ADDR_BITS, MSA300_CLK); 84 | let acc = Accelerometer::init(i2c).unwrap(); 85 | 86 | loop { 87 | let (x, y, z) = acc.measure().unwrap(); 88 | let mag = (x*x+y*y+z*z).sqrt(); 89 | // writeln!(stdout, "m/s^2 x={} y={} z={} (size={})", x, y, z, mag).unwrap(); 90 | 91 | // draw bubble 92 | let cx = ((y/8.5 + 1.0) * ((DISP_WIDTH / 2) as f32)) as i32; 93 | let cy = ((x/8.5 + 1.0) * ((DISP_HEIGHT / 2) as f32)) as i32; 94 | let r = (1.5*mag) as i32; 95 | let rr = r * r; 96 | render_image(&mut lcd, |x,y| { 97 | if sample_cirle(i32::from(x), i32::from(y), cx, cy, r, rr) { 98 | 0xffff 99 | } else { 100 | 0 101 | } 102 | }); 103 | // usleep(10000); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/secp256k1_tests/contrib/lax_der_privatekey_parsing.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2014, 2015 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | /**** 8 | * Please do not link this file directly. It is not part of the libsecp256k1 9 | * project and does not promise any stability in its API, functionality or 10 | * presence. Projects which use this code should instead copy this header 11 | * and its accompanying .c file directly into their codebase. 12 | ****/ 13 | 14 | /* This file contains code snippets that parse DER private keys with 15 | * various errors and violations. This is not a part of the library 16 | * itself, because the allowed violations are chosen arbitrarily and 17 | * do not follow or establish any standard. 18 | * 19 | * It also contains code to serialize private keys in a compatible 20 | * manner. 21 | * 22 | * These functions are meant for compatibility with applications 23 | * that require BER encoded keys. When working with secp256k1-specific 24 | * code, the simple 32-byte private keys normally used by the 25 | * library are sufficient. 26 | */ 27 | 28 | #ifndef SECP256K1_CONTRIB_BER_PRIVATEKEY_H 29 | #define SECP256K1_CONTRIB_BER_PRIVATEKEY_H 30 | 31 | #include 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | /** Export a private key in DER format. 38 | * 39 | * Returns: 1 if the private key was valid. 40 | * Args: ctx: pointer to a context object, initialized for signing (cannot 41 | * be NULL) 42 | * Out: privkey: pointer to an array for storing the private key in BER. 43 | * Should have space for 279 bytes, and cannot be NULL. 44 | * privkeylen: Pointer to an int where the length of the private key in 45 | * privkey will be stored. 46 | * In: seckey: pointer to a 32-byte secret key to export. 47 | * compressed: 1 if the key should be exported in 48 | * compressed format, 0 otherwise 49 | * 50 | * This function is purely meant for compatibility with applications that 51 | * require BER encoded keys. When working with secp256k1-specific code, the 52 | * simple 32-byte private keys are sufficient. 53 | * 54 | * Note that this function does not guarantee correct DER output. It is 55 | * guaranteed to be parsable by secp256k1_ec_privkey_import_der 56 | */ 57 | SECP256K1_WARN_UNUSED_RESULT int ec_privkey_export_der( 58 | const secp256k1_context* ctx, 59 | unsigned char *privkey, 60 | size_t *privkeylen, 61 | const unsigned char *seckey, 62 | int compressed 63 | ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); 64 | 65 | /** Import a private key in DER format. 66 | * Returns: 1 if a private key was extracted. 67 | * Args: ctx: pointer to a context object (cannot be NULL). 68 | * Out: seckey: pointer to a 32-byte array for storing the private key. 69 | * (cannot be NULL). 70 | * In: privkey: pointer to a private key in DER format (cannot be NULL). 71 | * privkeylen: length of the DER private key pointed to be privkey. 72 | * 73 | * This function will accept more than just strict DER, and even allow some BER 74 | * violations. The public key stored inside the DER-encoded private key is not 75 | * verified for correctness, nor are the curve parameters. Use this function 76 | * only if you know in advance it is supposed to contain a secp256k1 private 77 | * key. 78 | */ 79 | SECP256K1_WARN_UNUSED_RESULT int ec_privkey_import_der( 80 | const secp256k1_context* ctx, 81 | unsigned char *seckey, 82 | const unsigned char *privkey, 83 | size_t privkeylen 84 | ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); 85 | 86 | #ifdef __cplusplus 87 | } 88 | #endif 89 | 90 | #endif /* SECP256K1_CONTRIB_BER_PRIVATEKEY_H */ 91 | -------------------------------------------------------------------------------- /rust/k210-shared/src/board/def.rs: -------------------------------------------------------------------------------- 1 | //! Global board definitions for Sipeed Maix Go 2 | 3 | /** Display width in pixels */ 4 | pub const DISP_WIDTH: u16 = 320; 5 | /** Display height in pixels */ 6 | pub const DISP_HEIGHT: u16 = 240; 7 | /** Number of pixels in display */ 8 | pub const DISP_PIXELS: usize = (DISP_WIDTH as usize) * (DISP_HEIGHT as usize); 9 | 10 | /** I2C address of NS2009 (touch screen sensor) */ 11 | pub const NS2009_SLV_ADDR: u16 = 0x48; 12 | 13 | /** I2C address bits for NS2009 */ 14 | pub const NS2009_ADDR_BITS: u32 = 7; 15 | 16 | /** I2C clock speed for NS2009 */ 17 | pub const NS2009_CLK: u32 = 100000; 18 | 19 | /** Calibration matrix for touch screen */ 20 | pub const NS2009_CAL: [i32; 7] = [65, 5853, -1083592, -4292, -15, 16450115, 65536]; 21 | 22 | /** I2C address of MSA300 (accelerometer) */ 23 | pub const MSA300_SLV_ADDR: u16 = 0x26; 24 | 25 | /** I2C address bits for NS2009 */ 26 | pub const MSA300_ADDR_BITS: u32 = 7; 27 | 28 | /** I2C clock speed for MSA300 */ 29 | pub const MSA300_CLK: u32 = 500000; 30 | 31 | /** DVP SCCB address for OV2640 */ 32 | pub const OV2640_ADDR: u8 = 0x60; 33 | 34 | /** I/O pins for FPIOA */ 35 | #[derive(Copy, Clone)] 36 | pub enum io { 37 | /** JTAG TCK */ 38 | JTAG_TCK = 0, 39 | /** JTAG TDI */ 40 | JTAG_TDI = 1, 41 | /** JTAG TMS */ 42 | JTAG_TMS = 2, 43 | /** JTAG TDO */ 44 | JTAG_TDO = 3, 45 | /** Host RX (from STM32F103C8) */ 46 | ISP_RX = 4, 47 | /** Host TX (to STM32F103C8) */ 48 | ISP_TX = 5, 49 | /** WIFI serial TX (from perspective of ESP8285, so our RX) */ 50 | WIFI_TX = 6, 51 | /** WIFI serial RX (from perspective of ESP8285, so our TX) */ 52 | WIFI_RX = 7, 53 | /** WIFI enable (to ESP8285) */ 54 | WIFI_EN = 8, 55 | /** Unused */ 56 | BPSK_P = 9, 57 | /** Unused */ 58 | BPSK_N = 10, 59 | /** General purpose I/O pin */ 60 | IO11 = 11, 61 | /** Blue led (output) */ 62 | LED_B = 12, 63 | /** Green led (output) */ 64 | LED_G = 13, 65 | /** Red led (output) */ 66 | LED_R = 14, 67 | /** Key direction 1 press (input) */ 68 | KEY1 = 15, 69 | /** Key center press (input) */ 70 | BOOT_KEY0 = 16, 71 | /** Key direction 2 press (input) */ 72 | KEY2 = 17, 73 | /** Microphone I2S BCK */ 74 | MIC_BCK = 18, 75 | /** Microphone I2S WS */ 76 | MIC_WS = 19, 77 | /** Microphone I2S DAT3 */ 78 | MIC_DAT3 = 20, 79 | /** Microphone I2S DAT2 */ 80 | MIC_DAT2 = 21, 81 | /** Microphone I2S DAT1 */ 82 | MIC_DAT1 = 22, 83 | /** Microphone I2S DAT0 */ 84 | MIC_DAT0 = 23, 85 | /** Microphone LED DAT */ 86 | MIC_LED_DAT = 24, 87 | /** Microphone LED CLK */ 88 | MIC_LED_CLK = 25, 89 | /** SDCARD SPI MISO */ 90 | SPI0_MISO = 26, 91 | /** SDCARD SPI SCLK */ 92 | SPI0_SCLK = 27, 93 | /** SDCARD SPI MOSI */ 94 | SPI0_MOSI = 28, 95 | /** SDCARD SPI CS */ 96 | SPI0_CS0 = 29, 97 | /** I2C bus 1 SCLK (NS2009, MSA300) */ 98 | I2C1_SCL = 30, 99 | /** I2C bus 2 SDA (NS2009, MSA300) */ 100 | I2C1_SDA = 31, 101 | /** General purpose I/O pin */ 102 | IO32 = 32, 103 | /** DAC I2S WS */ 104 | I2S_WS = 33, 105 | /** DAC I2S DA */ 106 | I2S_DA = 34, 107 | /** DAC I2S BCK */ 108 | I2S_BCK = 35, 109 | /** LCD chip select (output) */ 110 | LCD_CS = 36, 111 | /** LCD reset (output) */ 112 | LCD_RST = 37, 113 | /** LCD Data/Command */ 114 | LCD_DC = 38, 115 | /** LCD SPI SCLK */ 116 | LCD_WR = 39, 117 | /** Camera DVP SDA */ 118 | DVP_SDA = 40, 119 | /** Camera DVP SCL */ 120 | DVP_SCL = 41, 121 | /** Camera DVP RST */ 122 | DVP_RST = 42, 123 | /** Camera DVP VSYNC */ 124 | DVP_VSYNC = 43, 125 | /** Camera DVP PWDN */ 126 | DVP_PWDN = 44, 127 | /** Camera DVP HSYNC */ 128 | DVP_HSYNC = 45, 129 | /** Camera DVP XCLK */ 130 | DVP_XCLK = 46, 131 | /** Camera DVP PCLK */ 132 | DVP_PCLK = 47, 133 | } 134 | 135 | impl From for usize { 136 | fn from(io: io) -> Self { 137 | io as usize 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /src/glyph_mapping/nt35310.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2018 Canaan Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | #include "nt35310.h" 16 | #include "gpiohs.h" 17 | #include "spi.h" 18 | #include "board_config.h" 19 | 20 | static void init_dcx(void) 21 | { 22 | gpiohs_set_drive_mode(DCX_GPIONUM, GPIO_DM_OUTPUT); 23 | gpiohs_set_pin(DCX_GPIONUM, GPIO_PV_HIGH); 24 | } 25 | 26 | static void set_dcx_control(void) 27 | { 28 | gpiohs_set_pin(DCX_GPIONUM, GPIO_PV_LOW); 29 | } 30 | 31 | static void set_dcx_data(void) 32 | { 33 | gpiohs_set_pin(DCX_GPIONUM, GPIO_PV_HIGH); 34 | } 35 | 36 | static void init_rst(void) 37 | { 38 | gpiohs_set_drive_mode(RST_GPIONUM, GPIO_DM_OUTPUT); 39 | gpiohs_set_pin(RST_GPIONUM, GPIO_PV_HIGH); 40 | } 41 | 42 | static void set_rst(uint8_t val) 43 | { 44 | gpiohs_set_pin(RST_GPIONUM, val); 45 | } 46 | 47 | void tft_hard_init(void) 48 | { 49 | init_dcx(); 50 | init_rst(); 51 | set_rst(0); 52 | spi_init(SPI_CHANNEL, SPI_WORK_MODE_0, SPI_FF_OCTAL, 8, 0); 53 | #if BOARD_LICHEEDAN 54 | spi_set_clk_rate(SPI_CHANNEL, 20000000); 55 | #else 56 | spi_set_clk_rate(SPI_CHANNEL, 25000000); 57 | #endif 58 | set_rst(1); 59 | } 60 | 61 | void tft_write_command(uint8_t cmd) 62 | { 63 | set_dcx_control(); 64 | spi_init(SPI_CHANNEL, SPI_WORK_MODE_0, SPI_FF_OCTAL, 8, 0); 65 | spi_init_non_standard(SPI_CHANNEL, 8 /*instrction length*/, 0 /*address length*/, 0 /*wait cycles*/, 66 | SPI_AITM_AS_FRAME_FORMAT /*spi address trans mode*/); 67 | spi_send_data_normal_dma(DMAC_CHANNEL0, SPI_CHANNEL, SPI_SLAVE_SELECT, (uint8_t *)(&cmd), 1, SPI_TRANS_CHAR); 68 | } 69 | 70 | void tft_write_byte(uint8_t *data_buf, uint32_t length) 71 | { 72 | set_dcx_data(); 73 | spi_init(SPI_CHANNEL, SPI_WORK_MODE_0, SPI_FF_OCTAL, 8, 0); 74 | spi_init_non_standard(SPI_CHANNEL, 0 /*instrction length*/, 8 /*address length*/, 0 /*wait cycles*/, 75 | SPI_AITM_AS_FRAME_FORMAT /*spi address trans mode*/); 76 | spi_send_data_normal_dma(DMAC_CHANNEL0, SPI_CHANNEL, SPI_SLAVE_SELECT, data_buf, length, SPI_TRANS_CHAR); 77 | } 78 | 79 | void tft_write_half(uint16_t *data_buf, uint32_t length) 80 | { 81 | set_dcx_data(); 82 | spi_init(SPI_CHANNEL, SPI_WORK_MODE_0, SPI_FF_OCTAL, 16, 0); 83 | spi_init_non_standard(SPI_CHANNEL, 0 /*instrction length*/, 16 /*address length*/, 0 /*wait cycles*/, 84 | SPI_AITM_AS_FRAME_FORMAT /*spi address trans mode*/); 85 | spi_send_data_normal_dma(DMAC_CHANNEL0, SPI_CHANNEL, SPI_SLAVE_SELECT, data_buf, length, SPI_TRANS_SHORT); 86 | } 87 | 88 | void tft_write_word(uint32_t *data_buf, uint32_t length, uint32_t flag) 89 | { 90 | set_dcx_data(); 91 | spi_init(SPI_CHANNEL, SPI_WORK_MODE_0, SPI_FF_OCTAL, 32, 0); 92 | 93 | spi_init_non_standard(SPI_CHANNEL, 0 /*instrction length*/, 32 /*address length*/, 0 /*wait cycles*/, 94 | SPI_AITM_AS_FRAME_FORMAT /*spi address trans mode*/); 95 | spi_send_data_normal_dma(DMAC_CHANNEL0, SPI_CHANNEL, SPI_SLAVE_SELECT, data_buf, length, SPI_TRANS_INT); 96 | } 97 | 98 | void tft_fill_data(uint32_t *data_buf, uint32_t length) 99 | { 100 | set_dcx_data(); 101 | spi_init(SPI_CHANNEL, SPI_WORK_MODE_0, SPI_FF_OCTAL, 32, 0); 102 | spi_init_non_standard(SPI_CHANNEL, 0 /*instrction length*/, 32 /*address length*/, 0 /*wait cycles*/, 103 | SPI_AITM_AS_FRAME_FORMAT /*spi address trans mode*/); 104 | spi_fill_data_dma(DMAC_CHANNEL0, SPI_CHANNEL, SPI_SLAVE_SELECT, data_buf, length); 105 | } 106 | -------------------------------------------------------------------------------- /rust/k210-shared/src/soc/sha256.rs: -------------------------------------------------------------------------------- 1 | //! SHA256 peripheral 2 | use core::iter; 3 | use core::sync::atomic::{self, Ordering}; 4 | use k210_hal::pac; 5 | use pac::sha256::function_reg_0::ENDIAN_A; 6 | 7 | /** SHA256 context for hardware-based computation on K210 SHA256 engine. */ 8 | pub struct SHA256Ctx<'a> { 9 | sha: &'a mut pac::SHA256, 10 | block: u32, 11 | ptr: usize, 12 | } 13 | 14 | impl <'a> SHA256Ctx<'a> { 15 | /** Create new SHA256 hardware context. As the peripheral has internal 16 | * state and supports only one context, this prevents creating multiple concurrent 17 | * contexts by requiring a mutable reference. 18 | * Unlike software SHA256, the peripheral needs to know the total number of blocks 19 | * in advance.`input_len` must match the number of bytes that will be fed using update 20 | * before calling finish, or the result will likely be incorrect or the engine will hang. 21 | */ 22 | pub fn new(sha: &'a mut pac::SHA256, input_len: usize) -> SHA256Ctx { 23 | let num_blocks = (input_len + 64 + 8) / 64; 24 | // Can hash up to 65536 blocks, this is the largest value that fits into data_cnt 25 | // (0 = 65536). 26 | assert!(num_blocks <= 0x10000); 27 | unsafe { 28 | sha.num_reg.write(|w| 29 | w.data_cnt().bits(((input_len + 64 + 8) / 64) as u16)); 30 | sha.function_reg_0.write(|w| 31 | w.endian().variant(ENDIAN_A::BE) 32 | .en().bit(true)); 33 | sha.function_reg_1.write(|w| 34 | w.dma_en().bit(false)); 35 | } 36 | SHA256Ctx { sha, block: 0, ptr: 0 } 37 | } 38 | 39 | /** Update SHA256 computation with new data. */ 40 | pub fn update<'b, X>(&mut self, data: X) 41 | where X: IntoIterator { 42 | let mut block = self.block; 43 | let mut ptr = self.ptr; 44 | for &v in data { 45 | let copy_ofs = ptr % 4; 46 | block |= (v as u32) << (copy_ofs * 8); 47 | ptr += 1; 48 | 49 | if copy_ofs == 3 { 50 | unsafe { 51 | while self.sha.function_reg_1.read().fifo_in_full().bit() { 52 | atomic::compiler_fence(Ordering::SeqCst) 53 | } 54 | self.sha.data_in.write(|w| w.bits(block)); 55 | } 56 | block = 0; 57 | } 58 | } 59 | self.block = block; 60 | self.ptr = ptr; 61 | } 62 | 63 | /** Update SHA256 computation with new data (32 bit little-endian, must be four-aligned in 64 | * the data stream). This is roughly two times faster than byte by byte using `update`. 65 | */ 66 | pub fn update32<'b, X>(&mut self, data: X) 67 | where X: IntoIterator { 68 | assert!((self.ptr & 3) == 0); 69 | let mut ptr = self.ptr; 70 | for &v in data { 71 | unsafe { 72 | while self.sha.function_reg_1.read().fifo_in_full().bit() { 73 | atomic::compiler_fence(Ordering::SeqCst) 74 | } 75 | self.sha.data_in.write(|w| w.bits(v)); 76 | } 77 | ptr += 4; 78 | } 79 | self.ptr = ptr; 80 | } 81 | 82 | /** Finish up SHA256 computation. */ 83 | pub fn finish(&mut self) -> [u8; 32] { 84 | let length_pad = ((self.ptr as u64) * 8).to_be_bytes(); 85 | let mut bytes_to_pad = 120 - (self.ptr % 64); 86 | if bytes_to_pad > 64 { 87 | bytes_to_pad -= 64; 88 | } 89 | self.update(&[0x80]); 90 | self.update(iter::repeat(&0).take(bytes_to_pad - 1)); 91 | self.update(&length_pad); 92 | 93 | while !self.sha.function_reg_0.read().en().bit() { 94 | atomic::compiler_fence(Ordering::SeqCst) 95 | } 96 | let mut sha_out = [0u8; 32]; 97 | for i in 0..8 { 98 | let val = self.sha.result[7 - i].read().bits().to_le_bytes(); 99 | sha_out[i*4..i*4+4].copy_from_slice(&val); 100 | } 101 | sha_out 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /linux/term.c: -------------------------------------------------------------------------------- 1 | /** term: Minimal interactive serial console. 2 | * Usage: term /dev/ttyS1 3 | * 4 | * Copyright (c) 2020 W.J. van der Laan 5 | * Distributed under the MIT software license, 6 | */ 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | int set_raw(int fd) 17 | { 18 | struct termios tty; 19 | 20 | if (tcgetattr(fd, &tty) < 0) { 21 | printf("Error from tcgetattr: %s\n", strerror(errno)); 22 | return -1; 23 | } 24 | 25 | tty.c_iflag &= ~(ICRNL | IXON); 26 | tty.c_lflag &= ~(ECHO | ICANON); 27 | 28 | if (tcsetattr(fd, TCSANOW, &tty) != 0) { 29 | printf("Error from tcsetattr: %s\n", strerror(errno)); 30 | return -1; 31 | } 32 | return 0; 33 | } 34 | 35 | int set_interface_attribs(int fd, int speed) 36 | { 37 | struct termios tty; 38 | 39 | if (tcgetattr(fd, &tty) < 0) { 40 | printf("Error from tcgetattr: %s\n", strerror(errno)); 41 | return -1; 42 | } 43 | 44 | cfsetospeed(&tty, (speed_t)speed); 45 | cfsetispeed(&tty, (speed_t)speed); 46 | 47 | tty.c_cflag |= (CLOCAL | CREAD); /* ignore modem controls */ 48 | tty.c_cflag &= ~CSIZE; 49 | tty.c_cflag |= CS8; /* 8-bit characters */ 50 | tty.c_cflag &= ~PARENB; /* no parity bit */ 51 | tty.c_cflag &= ~CSTOPB; /* only need 1 stop bit */ 52 | tty.c_cflag &= ~CRTSCTS; /* no hardware flowcontrol */ 53 | 54 | /* setup for non-canonical mode */ 55 | tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); 56 | tty.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); 57 | tty.c_oflag &= ~OPOST; 58 | 59 | /* fetch bytes as they become available */ 60 | tty.c_cc[VMIN] = 1; 61 | tty.c_cc[VTIME] = 1; 62 | 63 | if (tcsetattr(fd, TCSANOW, &tty) != 0) { 64 | printf("Error from tcsetattr: %s\n", strerror(errno)); 65 | return -1; 66 | } 67 | return 0; 68 | } 69 | 70 | int main(int argc, char **argv) { 71 | if (argc < 2) { 72 | fprintf(stderr, "Pass serial device on command line\n"); 73 | exit(1); 74 | } 75 | const char *portname = argv[1]; 76 | int fd = open(portname, O_RDWR | O_NOCTTY | O_SYNC); 77 | if (fd < 0) { 78 | fprintf(stderr, "Error opening %s: %s\n", portname, strerror(errno)); 79 | exit(1); 80 | } 81 | 82 | set_raw(STDIN_FILENO); 83 | /*baudrate 115200, 8 bits, no parity, 1 stop bit */ 84 | set_interface_attribs(fd, B115200); 85 | 86 | struct pollfd fds[2] = { 87 | {STDIN_FILENO, POLLIN, 0}, 88 | {fd, POLLIN, 0}, 89 | }; 90 | do { 91 | for (int i=0; i<2; ++i) { 92 | fds[i].revents = 0; 93 | } 94 | 95 | if (poll(fds, 2, -1) < 0) { 96 | fprintf(stderr, "Poll error: %s\n", strerror(errno)); 97 | exit(1); 98 | } 99 | 100 | for (int i=0; i<2; ++i) { 101 | if (fds[i].revents & POLLIN) { 102 | char ch; 103 | int rdlen = read(fds[i].fd, &ch, 1); 104 | if (rdlen < 0) { 105 | fprintf(stderr, "Error from read: %d: %s\n", rdlen, strerror(errno)); 106 | exit(1); 107 | } else if (rdlen == 0) { 108 | /* EOF */ 109 | exit(0); 110 | } 111 | 112 | if (i == 1 && ch == '\r') { 113 | /* Don't print \r */ 114 | continue; 115 | } 116 | if (i == 0 && ch == '\n') { 117 | /* Add extra \r before newline */ 118 | char cr = '\r'; 119 | write(fds[1-i].fd, &cr, 1); 120 | } 121 | 122 | int wlen = write(fds[1-i].fd, &ch, 1); 123 | if (wlen <= 0) { 124 | fprintf(stderr, "Error from write: %d: %s\n", wlen, strerror(errno)); 125 | exit(1); 126 | } 127 | } 128 | } 129 | } while (1); 130 | } 131 | -------------------------------------------------------------------------------- /src/glyph_mapping/lcd.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2018 Canaan Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | #include 16 | #include 17 | #include "lcd.h" 18 | #include "nt35310.h" 19 | #include "board_config.h" 20 | 21 | static lcd_ctl_t lcd_ctl; 22 | 23 | void lcd_polling_enable(void) 24 | { 25 | lcd_ctl.mode = 0; 26 | } 27 | 28 | void lcd_interrupt_enable(void) 29 | { 30 | lcd_ctl.mode = 1; 31 | } 32 | 33 | void lcd_init(void) 34 | { 35 | uint8_t data = 0; 36 | 37 | tft_hard_init(); 38 | /*soft reset*/ 39 | tft_write_command(SOFTWARE_RESET); 40 | usleep(100000); 41 | /*exit sleep*/ 42 | tft_write_command(SLEEP_OFF); 43 | usleep(100000); 44 | /*pixel format*/ 45 | tft_write_command(PIXEL_FORMAT_SET); 46 | data = 0x55; 47 | tft_write_byte(&data, 1); 48 | lcd_set_direction(DIR_XY_LRUD); 49 | 50 | /*display on*/ 51 | tft_write_command(DISPLAY_ON); 52 | lcd_polling_enable(); 53 | } 54 | 55 | void lcd_set_direction(lcd_dir_t dir) 56 | { 57 | #if BOARD_LICHEEDAN 58 | #else 59 | dir |= 0x08; 60 | #endif 61 | lcd_ctl.dir = dir; 62 | if (dir & DIR_XY_MASK) 63 | { 64 | lcd_ctl.width = LCD_Y_MAX - 1; 65 | lcd_ctl.height = LCD_X_MAX - 1; 66 | } 67 | else 68 | { 69 | lcd_ctl.width = LCD_X_MAX - 1; 70 | lcd_ctl.height = LCD_Y_MAX - 1; 71 | } 72 | 73 | tft_write_command(MEMORY_ACCESS_CTL); 74 | tft_write_byte((uint8_t *)&dir, 1); 75 | } 76 | 77 | void lcd_set_area(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) 78 | { 79 | uint8_t data[4] = {0}; 80 | 81 | data[0] = (uint8_t)(x1 >> 8); 82 | data[1] = (uint8_t)(x1); 83 | data[2] = (uint8_t)(x2 >> 8); 84 | data[3] = (uint8_t)(x2); 85 | tft_write_command(HORIZONTAL_ADDRESS_SET); 86 | tft_write_byte(data, 4); 87 | 88 | data[0] = (uint8_t)(y1 >> 8); 89 | data[1] = (uint8_t)(y1); 90 | data[2] = (uint8_t)(y2 >> 8); 91 | data[3] = (uint8_t)(y2); 92 | tft_write_command(VERTICAL_ADDRESS_SET); 93 | tft_write_byte(data, 4); 94 | 95 | tft_write_command(MEMORY_WRITE); 96 | } 97 | 98 | void lcd_draw_point(uint16_t x, uint16_t y, uint16_t color) 99 | { 100 | lcd_set_area(x, y, x, y); 101 | tft_write_half(&color, 1); 102 | } 103 | 104 | void lcd_clear(uint16_t color) 105 | { 106 | uint32_t data = ((uint32_t)color << 16) | (uint32_t)color; 107 | 108 | lcd_set_area(0, 0, lcd_ctl.width, lcd_ctl.height); 109 | tft_fill_data(&data, LCD_X_MAX * LCD_Y_MAX / 2); 110 | } 111 | 112 | void lcd_draw_rectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t width, uint16_t color) 113 | { 114 | uint32_t data_buf[640] = {0}; 115 | uint32_t *p = data_buf; 116 | uint32_t data = color; 117 | uint32_t index = 0; 118 | 119 | data = (data << 16) | data; 120 | for (index = 0; index < 160 * width; index++) 121 | *p++ = data; 122 | 123 | lcd_set_area(x1, y1, x2, y1 + width - 1); 124 | tft_write_word(data_buf, ((x2 - x1 + 1) * width + 1) / 2, 0); 125 | lcd_set_area(x1, y2 - width + 1, x2, y2); 126 | tft_write_word(data_buf, ((x2 - x1 + 1) * width + 1) / 2, 0); 127 | lcd_set_area(x1, y1, x1 + width - 1, y2); 128 | tft_write_word(data_buf, ((y2 - y1 + 1) * width + 1) / 2, 0); 129 | lcd_set_area(x2 - width + 1, y1, x2, y2); 130 | tft_write_word(data_buf, ((y2 - y1 + 1) * width + 1) / 2, 0); 131 | } 132 | 133 | void lcd_draw_picture(uint16_t x1, uint16_t y1, uint16_t width, uint16_t height, uint32_t *ptr) 134 | { 135 | lcd_set_area(x1, y1, x1 + width - 1, y1 + height - 1); 136 | tft_write_word(ptr, width * height / 2, lcd_ctl.mode ? 2 : 0); 137 | } 138 | 139 | -------------------------------------------------------------------------------- /src/secp256k1_tests/contrib/lax_der_parsing.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2015 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | /**** 8 | * Please do not link this file directly. It is not part of the libsecp256k1 9 | * project and does not promise any stability in its API, functionality or 10 | * presence. Projects which use this code should instead copy this header 11 | * and its accompanying .c file directly into their codebase. 12 | ****/ 13 | 14 | /* This file defines a function that parses DER with various errors and 15 | * violations. This is not a part of the library itself, because the allowed 16 | * violations are chosen arbitrarily and do not follow or establish any 17 | * standard. 18 | * 19 | * In many places it matters that different implementations do not only accept 20 | * the same set of valid signatures, but also reject the same set of signatures. 21 | * The only means to accomplish that is by strictly obeying a standard, and not 22 | * accepting anything else. 23 | * 24 | * Nonetheless, sometimes there is a need for compatibility with systems that 25 | * use signatures which do not strictly obey DER. The snippet below shows how 26 | * certain violations are easily supported. You may need to adapt it. 27 | * 28 | * Do not use this for new systems. Use well-defined DER or compact signatures 29 | * instead if you have the choice (see secp256k1_ecdsa_signature_parse_der and 30 | * secp256k1_ecdsa_signature_parse_compact). 31 | * 32 | * The supported violations are: 33 | * - All numbers are parsed as nonnegative integers, even though X.609-0207 34 | * section 8.3.3 specifies that integers are always encoded as two's 35 | * complement. 36 | * - Integers can have length 0, even though section 8.3.1 says they can't. 37 | * - Integers with overly long padding are accepted, violation section 38 | * 8.3.2. 39 | * - 127-byte long length descriptors are accepted, even though section 40 | * 8.1.3.5.c says that they are not. 41 | * - Trailing garbage data inside or after the signature is ignored. 42 | * - The length descriptor of the sequence is ignored. 43 | * 44 | * Compared to for example OpenSSL, many violations are NOT supported: 45 | * - Using overly long tag descriptors for the sequence or integers inside, 46 | * violating section 8.1.2.2. 47 | * - Encoding primitive integers as constructed values, violating section 48 | * 8.3.1. 49 | */ 50 | 51 | #ifndef SECP256K1_CONTRIB_LAX_DER_PARSING_H 52 | #define SECP256K1_CONTRIB_LAX_DER_PARSING_H 53 | 54 | #include 55 | 56 | #ifdef __cplusplus 57 | extern "C" { 58 | #endif 59 | 60 | /** Parse a signature in "lax DER" format 61 | * 62 | * Returns: 1 when the signature could be parsed, 0 otherwise. 63 | * Args: ctx: a secp256k1 context object 64 | * Out: sig: a pointer to a signature object 65 | * In: input: a pointer to the signature to be parsed 66 | * inputlen: the length of the array pointed to be input 67 | * 68 | * This function will accept any valid DER encoded signature, even if the 69 | * encoded numbers are out of range. In addition, it will accept signatures 70 | * which violate the DER spec in various ways. Its purpose is to allow 71 | * validation of the Bitcoin blockchain, which includes non-DER signatures 72 | * from before the network rules were updated to enforce DER. Note that 73 | * the set of supported violations is a strict subset of what OpenSSL will 74 | * accept. 75 | * 76 | * After the call, sig will always be initialized. If parsing failed or the 77 | * encoded numbers are out of range, signature validation with it is 78 | * guaranteed to fail for every message and public key. 79 | */ 80 | int ecdsa_signature_parse_der_lax( 81 | const secp256k1_context* ctx, 82 | secp256k1_ecdsa_signature* sig, 83 | const unsigned char *input, 84 | size_t inputlen 85 | ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); 86 | 87 | #ifdef __cplusplus 88 | } 89 | #endif 90 | 91 | #endif /* SECP256K1_CONTRIB_LAX_DER_PARSING_H */ 92 | -------------------------------------------------------------------------------- /src/secp256k1_tests/scalar_low_impl.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2015 Andrew Poelstra * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_SCALAR_REPR_IMPL_H 8 | #define SECP256K1_SCALAR_REPR_IMPL_H 9 | 10 | #include "scalar.h" 11 | 12 | #include 13 | 14 | SECP256K1_INLINE static int secp256k1_scalar_is_even(const secp256k1_scalar *a) { 15 | return !(*a & 1); 16 | } 17 | 18 | SECP256K1_INLINE static void secp256k1_scalar_clear(secp256k1_scalar *r) { *r = 0; } 19 | SECP256K1_INLINE static void secp256k1_scalar_set_int(secp256k1_scalar *r, unsigned int v) { *r = v; } 20 | 21 | SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { 22 | if (offset < 32) 23 | return ((*a >> offset) & ((((uint32_t)1) << count) - 1)); 24 | else 25 | return 0; 26 | } 27 | 28 | SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { 29 | return secp256k1_scalar_get_bits(a, offset, count); 30 | } 31 | 32 | SECP256K1_INLINE static int secp256k1_scalar_check_overflow(const secp256k1_scalar *a) { return *a >= EXHAUSTIVE_TEST_ORDER; } 33 | 34 | static int secp256k1_scalar_add(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b) { 35 | *r = (*a + *b) % EXHAUSTIVE_TEST_ORDER; 36 | return *r < *b; 37 | } 38 | 39 | static void secp256k1_scalar_cadd_bit(secp256k1_scalar *r, unsigned int bit, int flag) { 40 | if (flag && bit < 32) 41 | *r += (1 << bit); 42 | #ifdef VERIFY 43 | VERIFY_CHECK(secp256k1_scalar_check_overflow(r) == 0); 44 | #endif 45 | } 46 | 47 | static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *b32, int *overflow) { 48 | const int base = 0x100 % EXHAUSTIVE_TEST_ORDER; 49 | int i; 50 | *r = 0; 51 | for (i = 0; i < 32; i++) { 52 | *r = ((*r * base) + b32[i]) % EXHAUSTIVE_TEST_ORDER; 53 | } 54 | /* just deny overflow, it basically always happens */ 55 | if (overflow) *overflow = 0; 56 | } 57 | 58 | static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar* a) { 59 | memset(bin, 0, 32); 60 | bin[28] = *a >> 24; bin[29] = *a >> 16; bin[30] = *a >> 8; bin[31] = *a; 61 | } 62 | 63 | SECP256K1_INLINE static int secp256k1_scalar_is_zero(const secp256k1_scalar *a) { 64 | return *a == 0; 65 | } 66 | 67 | static void secp256k1_scalar_negate(secp256k1_scalar *r, const secp256k1_scalar *a) { 68 | if (*a == 0) { 69 | *r = 0; 70 | } else { 71 | *r = EXHAUSTIVE_TEST_ORDER - *a; 72 | } 73 | } 74 | 75 | SECP256K1_INLINE static int secp256k1_scalar_is_one(const secp256k1_scalar *a) { 76 | return *a == 1; 77 | } 78 | 79 | static int secp256k1_scalar_is_high(const secp256k1_scalar *a) { 80 | return *a > EXHAUSTIVE_TEST_ORDER / 2; 81 | } 82 | 83 | static int secp256k1_scalar_cond_negate(secp256k1_scalar *r, int flag) { 84 | if (flag) secp256k1_scalar_negate(r, r); 85 | return flag ? -1 : 1; 86 | } 87 | 88 | static void secp256k1_scalar_mul(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b) { 89 | *r = (*a * *b) % EXHAUSTIVE_TEST_ORDER; 90 | } 91 | 92 | static int secp256k1_scalar_shr_int(secp256k1_scalar *r, int n) { 93 | int ret; 94 | VERIFY_CHECK(n > 0); 95 | VERIFY_CHECK(n < 16); 96 | ret = *r & ((1 << n) - 1); 97 | *r >>= n; 98 | return ret; 99 | } 100 | 101 | static void secp256k1_scalar_sqr(secp256k1_scalar *r, const secp256k1_scalar *a) { 102 | *r = (*a * *a) % EXHAUSTIVE_TEST_ORDER; 103 | } 104 | 105 | static void secp256k1_scalar_split_128(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a) { 106 | *r1 = *a; 107 | *r2 = 0; 108 | } 109 | 110 | SECP256K1_INLINE static int secp256k1_scalar_eq(const secp256k1_scalar *a, const secp256k1_scalar *b) { 111 | return *a == *b; 112 | } 113 | 114 | #endif /* SECP256K1_SCALAR_REPR_IMPL_H */ 115 | -------------------------------------------------------------------------------- /util/esp8266at/examples/serial.rs: -------------------------------------------------------------------------------- 1 | use std::fmt; 2 | use std::str; 3 | use std::time::Duration; 4 | 5 | use clap::{App, AppSettings, Arg}; 6 | use serialport::prelude::*; 7 | 8 | use esp8266at::handler::{NetworkEvent, SerialNetworkHandler}; 9 | use esp8266at::mainloop::mainloop; 10 | use esp8266at::response::ConnectionType; 11 | use esp8266at::traits::Write; 12 | 13 | struct StdoutDebug {} 14 | impl fmt::Write for StdoutDebug { 15 | fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> { 16 | print!("{}", s); 17 | Ok(()) 18 | } 19 | } 20 | 21 | fn main() { 22 | let matches = App::new("Serialport Example - Receive Data") 23 | .about("Reads data from a serial port and echoes it to stdout") 24 | .setting(AppSettings::DisableVersion) 25 | .arg( 26 | Arg::with_name("port") 27 | .help("The device path to a serial port") 28 | .use_delimiter(false) 29 | .required(true), 30 | ) 31 | .arg( 32 | Arg::with_name("baud") 33 | .help("The baud rate to connect at") 34 | .use_delimiter(false) 35 | .required(true), 36 | ) 37 | .arg( 38 | Arg::with_name("apname") 39 | .help("Access point name") 40 | .use_delimiter(false) 41 | .required(true), 42 | ) 43 | .arg( 44 | Arg::with_name("appass") 45 | .help("Access point password") 46 | .use_delimiter(false) 47 | .required(true), 48 | ) 49 | .get_matches(); 50 | let port_name = matches.value_of("port").unwrap(); 51 | let baud_rate = matches.value_of("baud").unwrap(); 52 | let apname = matches.value_of("apname").unwrap(); 53 | let appass = matches.value_of("appass").unwrap(); 54 | 55 | let mut settings: SerialPortSettings = Default::default(); 56 | settings.timeout = Duration::from_millis(10); 57 | if let Ok(rate) = baud_rate.parse::() { 58 | settings.baud_rate = rate.into(); 59 | } else { 60 | eprintln!("Error: Invalid baud rate '{}' specified", baud_rate); 61 | ::std::process::exit(1); 62 | } 63 | 64 | match serialport::open_with_settings(&port_name, &settings) { 65 | Ok(mut tx) => { 66 | // Split into TX and RX halves 67 | let mut rx = tx.try_clone().unwrap(); 68 | println!("Receiving data on {} at {} baud:", &port_name, &baud_rate); 69 | let mut sh = SerialNetworkHandler::new(&mut tx, apname.as_bytes(), appass.as_bytes()); 70 | 71 | sh.start(true).unwrap(); 72 | 73 | mainloop(&mut sh, &mut rx, |port, ev, debug| { 74 | match ev { 75 | NetworkEvent::Ready => { 76 | writeln!(debug, "--Ready--").unwrap(); 77 | port.connect(ConnectionType::TCP, b"wttr.in", 80).unwrap(); 78 | //port.connect(0, ConnectionType::SSL, b"wttr.in", 443); 79 | true 80 | } 81 | NetworkEvent::Error => { 82 | writeln!(debug, "--Could not connect to AP--").unwrap(); 83 | false 84 | } 85 | NetworkEvent::ConnectionEstablished(_) => { 86 | port.write_all(b"GET /?0qA HTTP/1.1\r\nHost: wttr.in\r\nConnection: close\r\nUser-Agent: Weather-Spy\r\n\r\n").unwrap(); 87 | port.send(0).unwrap(); 88 | true 89 | } 90 | NetworkEvent::Data(_, data) => { 91 | write!(debug, "{}", str::from_utf8(data).unwrap()).unwrap(); 92 | true 93 | } 94 | NetworkEvent::ConnectionClosed(_) => { 95 | false 96 | } 97 | _ => { true } 98 | } 99 | }, &mut StdoutDebug {}).unwrap(); 100 | } 101 | Err(e) => { 102 | eprintln!("Failed to open \"{}\". Error: {}", port_name, e); 103 | ::std::process::exit(1); 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /rust/sdtest/src/main.rs: -------------------------------------------------------------------------------- 1 | #![allow(dead_code)] 2 | #![allow(non_snake_case)] 3 | #![allow(non_camel_case_types)] 4 | #![no_std] 5 | #![no_main] 6 | 7 | use core::convert::TryInto; 8 | use k210_hal::prelude::*; 9 | use k210_hal::stdout::Stdout; 10 | use k210_hal::pac::Peripherals; 11 | use k210_shared::board::def::io; 12 | use k210_shared::board::sdcard; 13 | use k210_shared::soc::dmac::{dma_channel, DMACExt}; 14 | use k210_shared::soc::fpioa; 15 | use k210_shared::soc::sysctl; 16 | use k210_shared::soc::sleep::usleep; 17 | use k210_shared::soc::spi::SPIExt; 18 | use riscv_rt::entry; 19 | 20 | /** GPIOHS GPIO number to use for controlling the SD card CS pin */ 21 | const SD_CS_GPIONUM: u8 = 7; 22 | /** CS value passed to SPI controller, this is a dummy value as SPI0_CS3 is not mapping to anything 23 | * in the FPIOA */ 24 | const SD_CS: u32 = 3; 25 | 26 | /** Connect pins to internal functions */ 27 | fn io_init() { 28 | fpioa::set_function(io::SPI0_SCLK, fpioa::function::SPI0_SCLK); 29 | fpioa::set_function(io::SPI0_MOSI, fpioa::function::SPI0_D0); 30 | fpioa::set_function(io::SPI0_MISO, fpioa::function::SPI0_D1); 31 | fpioa::set_function(io::SPI0_CS0, fpioa::function::gpiohs(SD_CS_GPIONUM)); 32 | fpioa::set_io_pull(io::SPI0_CS0, fpioa::pull::DOWN); // GPIO output=pull down 33 | } 34 | 35 | fn ch(i: u8) -> char { 36 | if i >= 0x20 && i < 0x80 { 37 | i.into() 38 | } else { 39 | '.' 40 | } 41 | } 42 | 43 | fn hexdump(stdout: &mut T, buffer: &[u8], base: usize) { 44 | for (i, chunk) in buffer.chunks_exact(16).enumerate() { 45 | writeln!(stdout, "{:08x}: {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", 46 | base + i * 16, 47 | chunk[0], chunk[1], chunk[2], chunk[3], 48 | chunk[4], chunk[5], chunk[6], chunk[7], 49 | chunk[8], chunk[9], chunk[10], chunk[11], 50 | chunk[12], chunk[13], chunk[14], chunk[15], 51 | ch(chunk[0]), ch(chunk[1]), ch(chunk[2]), ch(chunk[3]), 52 | ch(chunk[4]), ch(chunk[5]), ch(chunk[6]), ch(chunk[7]), 53 | ch(chunk[8]), ch(chunk[9]), ch(chunk[10]), ch(chunk[11]), 54 | ch(chunk[12]), ch(chunk[13]), ch(chunk[14]), ch(chunk[15]), 55 | ).unwrap(); 56 | } 57 | } 58 | 59 | #[entry] 60 | fn main() -> ! { 61 | let p = Peripherals::take().unwrap(); 62 | sysctl::pll_set_freq(sysctl::pll::PLL0, 800_000_000).unwrap(); 63 | sysctl::pll_set_freq(sysctl::pll::PLL1, 300_000_000).unwrap(); 64 | sysctl::pll_set_freq(sysctl::pll::PLL2, 45_158_400).unwrap(); 65 | let clocks = k210_hal::clock::Clocks::new(); 66 | 67 | usleep(200000); 68 | 69 | // Configure UART 70 | let serial = p 71 | .UARTHS 72 | .configure(115_200.bps(), &clocks); 73 | let (mut tx, _) = serial.split(); 74 | 75 | let mut stdout = Stdout(&mut tx); 76 | 77 | io_init(); 78 | 79 | let dmac = p.DMAC.configure(); 80 | let spi = p.SPI0.constrain(); 81 | 82 | writeln!(stdout, "sdcard: pre-init").unwrap(); 83 | let sd = sdcard::SDCard::new(spi, SD_CS, SD_CS_GPIONUM, &dmac, dma_channel::CHANNEL0); 84 | let info = sd.init().unwrap(); 85 | writeln!(stdout, "card info: {:?}", info).unwrap(); 86 | let num_sectors = info.CardCapacity / 512; 87 | writeln!(stdout, "number of sectors on card: {}", num_sectors).unwrap(); 88 | 89 | assert!(num_sectors > 0); 90 | let sector: u32 = (num_sectors - 10).try_into().unwrap(); 91 | let mut buffer = [0u8; 512]; 92 | sd.read_sector(&mut buffer, sector).unwrap(); 93 | writeln!(stdout, "sector {} succesfully read", sector).unwrap(); 94 | 95 | hexdump(&mut stdout, &buffer, 0); 96 | 97 | // Warning: uncommenting this will write to the SD card 98 | /* 99 | let msg = b"Well! I've often seen a cat without a grin', thought Alice, 'but a grin without a cat! It's the most curious thing I ever saw in my life!'"; 100 | let mut buffer = [0u8; 512]; 101 | (&mut buffer[0..msg.len()]).copy_from_slice(msg); 102 | sd.write_sector(&mut buffer, sector).unwrap(); 103 | writeln!(stdout, "sector {} succesfully written", sector).unwrap(); 104 | */ 105 | 106 | loop {} 107 | } 108 | -------------------------------------------------------------------------------- /rust/sdlcd/src/main.rs: -------------------------------------------------------------------------------- 1 | /*! Stream raw data from SD card to LCD, bascially a test for using both SPI0 and SPI1 2 | * at the same time 3 | */ 4 | #![allow(dead_code)] 5 | #![allow(non_snake_case)] 6 | #![allow(non_camel_case_types)] 7 | #![no_std] 8 | #![no_main] 9 | 10 | use core::convert::TryInto; 11 | use k210_hal::prelude::*; 12 | use k210_hal::stdout::Stdout; 13 | use k210_hal::pac::Peripherals; 14 | use k210_shared::board::def::{io, DISP_HEIGHT, DISP_PIXELS, DISP_WIDTH}; 15 | use k210_shared::board::lcd::{self, LCD, LCDHL}; 16 | use k210_shared::board::lcd_colors; 17 | use k210_shared::board::lcd_render::{AsU8, ScreenImage}; 18 | use k210_shared::board::sdcard; 19 | use k210_shared::soc::dmac::{dma_channel, DMACExt}; 20 | use k210_shared::soc::fpioa; 21 | use k210_shared::soc::sleep::usleep; 22 | use k210_shared::soc::spi::SPIExt; 23 | use k210_shared::soc::sysctl; 24 | use riscv_rt::entry; 25 | 26 | /** GPIOHS GPIO number to use for controlling the SD card CS pin */ 27 | const SD_CS_GPIONUM: u8 = 7; 28 | /** CS value passed to SPI controller, this is a dummy value as SPI0_CS3 is not mapped to anything 29 | * in the FPIOA */ 30 | const SD_CS: u32 = 3; 31 | 32 | /** Connect pins to internal functions */ 33 | fn io_init() { 34 | /* Init SD card function settings */ 35 | fpioa::set_function(io::SPI0_SCLK, fpioa::function::SPI1_SCLK); 36 | fpioa::set_function(io::SPI0_MOSI, fpioa::function::SPI1_D0); 37 | fpioa::set_function(io::SPI0_MISO, fpioa::function::SPI1_D1); 38 | fpioa::set_function(io::SPI0_CS0, fpioa::function::gpiohs(SD_CS_GPIONUM)); 39 | fpioa::set_io_pull(io::SPI0_CS0, fpioa::pull::DOWN); // GPIO output=pull down 40 | 41 | /* Init LCD function settings */ 42 | fpioa::set_function(io::LCD_RST, fpioa::function::gpiohs(lcd::RST_GPIONUM)); 43 | fpioa::set_io_pull(io::LCD_RST, fpioa::pull::DOWN); // outputs must be pull-down 44 | fpioa::set_function(io::LCD_DC, fpioa::function::gpiohs(lcd::DCX_GPIONUM)); 45 | fpioa::set_io_pull(io::LCD_DC, fpioa::pull::DOWN); 46 | fpioa::set_function(io::LCD_CS, fpioa::function::SPI0_SS3); 47 | fpioa::set_function(io::LCD_WR, fpioa::function::SPI0_SCLK); 48 | 49 | sysctl::set_spi0_dvp_data(true); 50 | 51 | /* Set dvp and spi pin to 1.8V */ 52 | sysctl::set_power_mode(sysctl::power_bank::BANK6, sysctl::io_power_mode::V18); 53 | sysctl::set_power_mode(sysctl::power_bank::BANK7, sysctl::io_power_mode::V18); 54 | } 55 | 56 | #[entry] 57 | fn main() -> ! { 58 | let p = Peripherals::take().unwrap(); 59 | sysctl::pll_set_freq(sysctl::pll::PLL0, 800_000_000).unwrap(); 60 | sysctl::pll_set_freq(sysctl::pll::PLL1, 300_000_000).unwrap(); 61 | sysctl::pll_set_freq(sysctl::pll::PLL2, 45_158_400).unwrap(); 62 | let clocks = k210_hal::clock::Clocks::new(); 63 | 64 | usleep(200000); 65 | 66 | // Configure UART 67 | let serial = p 68 | .UARTHS 69 | .configure(115_200.bps(), &clocks); 70 | let (mut tx, _) = serial.split(); 71 | 72 | let mut stdout = Stdout(&mut tx); 73 | 74 | io_init(); 75 | 76 | let dmac = p.DMAC.configure(); 77 | 78 | let lspi = p.SPI0.constrain(); 79 | let mut lcd = LCD::new(lspi, &dmac, dma_channel::CHANNEL0); 80 | lcd.init(); 81 | lcd.set_direction(lcd::direction::YX_LRUD); 82 | lcd.clear(lcd_colors::PURPLE); 83 | 84 | let sspi = p.SPI1.constrain(); 85 | writeln!(stdout, "sdcard: pre-init").unwrap(); 86 | let sd = sdcard::SDCard::new(sspi, SD_CS, SD_CS_GPIONUM, &dmac, dma_channel::CHANNEL1); 87 | let info = sd.init().unwrap(); 88 | writeln!(stdout, "card info: {:?}", info).unwrap(); 89 | let num_sectors = info.CardCapacity / 512; 90 | writeln!(stdout, "number of sectors on card: {}", num_sectors).unwrap(); 91 | 92 | assert!(num_sectors > 0); 93 | let mut sector: u64 = 0; 94 | let mut image: ScreenImage = [0; DISP_PIXELS / 2]; 95 | while sector < num_sectors { 96 | /* Read raw image */ 97 | sd.read_sector(image.as_u8_slice_mut(), sector.try_into().unwrap()) 98 | .unwrap(); 99 | 100 | writeln!(stdout, "sector {} succesfully read", sector).unwrap(); 101 | lcd.draw_picture(0, 0, DISP_WIDTH, DISP_HEIGHT, &image); 102 | 103 | sector += (image.len() * 4 / 512) as u64; 104 | } 105 | loop {} 106 | } 107 | -------------------------------------------------------------------------------- /src/secp256k1_tests/contrib/lax_der_parsing.c.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2015 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #include 8 | #include 9 | 10 | #include "lax_der_parsing.h" 11 | 12 | int ecdsa_signature_parse_der_lax(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char *input, size_t inputlen) { 13 | size_t rpos, rlen, spos, slen; 14 | size_t pos = 0; 15 | size_t lenbyte; 16 | unsigned char tmpsig[64] = {0}; 17 | int overflow = 0; 18 | 19 | /* Hack to initialize sig with a correctly-parsed but invalid signature. */ 20 | secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig); 21 | 22 | /* Sequence tag byte */ 23 | if (pos == inputlen || input[pos] != 0x30) { 24 | return 0; 25 | } 26 | pos++; 27 | 28 | /* Sequence length bytes */ 29 | if (pos == inputlen) { 30 | return 0; 31 | } 32 | lenbyte = input[pos++]; 33 | if (lenbyte & 0x80) { 34 | lenbyte -= 0x80; 35 | if (pos + lenbyte > inputlen) { 36 | return 0; 37 | } 38 | pos += lenbyte; 39 | } 40 | 41 | /* Integer tag byte for R */ 42 | if (pos == inputlen || input[pos] != 0x02) { 43 | return 0; 44 | } 45 | pos++; 46 | 47 | /* Integer length for R */ 48 | if (pos == inputlen) { 49 | return 0; 50 | } 51 | lenbyte = input[pos++]; 52 | if (lenbyte & 0x80) { 53 | lenbyte -= 0x80; 54 | if (pos + lenbyte > inputlen) { 55 | return 0; 56 | } 57 | while (lenbyte > 0 && input[pos] == 0) { 58 | pos++; 59 | lenbyte--; 60 | } 61 | if (lenbyte >= sizeof(size_t)) { 62 | return 0; 63 | } 64 | rlen = 0; 65 | while (lenbyte > 0) { 66 | rlen = (rlen << 8) + input[pos]; 67 | pos++; 68 | lenbyte--; 69 | } 70 | } else { 71 | rlen = lenbyte; 72 | } 73 | if (rlen > inputlen - pos) { 74 | return 0; 75 | } 76 | rpos = pos; 77 | pos += rlen; 78 | 79 | /* Integer tag byte for S */ 80 | if (pos == inputlen || input[pos] != 0x02) { 81 | return 0; 82 | } 83 | pos++; 84 | 85 | /* Integer length for S */ 86 | if (pos == inputlen) { 87 | return 0; 88 | } 89 | lenbyte = input[pos++]; 90 | if (lenbyte & 0x80) { 91 | lenbyte -= 0x80; 92 | if (pos + lenbyte > inputlen) { 93 | return 0; 94 | } 95 | while (lenbyte > 0 && input[pos] == 0) { 96 | pos++; 97 | lenbyte--; 98 | } 99 | if (lenbyte >= sizeof(size_t)) { 100 | return 0; 101 | } 102 | slen = 0; 103 | while (lenbyte > 0) { 104 | slen = (slen << 8) + input[pos]; 105 | pos++; 106 | lenbyte--; 107 | } 108 | } else { 109 | slen = lenbyte; 110 | } 111 | if (slen > inputlen - pos) { 112 | return 0; 113 | } 114 | spos = pos; 115 | pos += slen; 116 | 117 | /* Ignore leading zeroes in R */ 118 | while (rlen > 0 && input[rpos] == 0) { 119 | rlen--; 120 | rpos++; 121 | } 122 | /* Copy R value */ 123 | if (rlen > 32) { 124 | overflow = 1; 125 | } else { 126 | memcpy(tmpsig + 32 - rlen, input + rpos, rlen); 127 | } 128 | 129 | /* Ignore leading zeroes in S */ 130 | while (slen > 0 && input[spos] == 0) { 131 | slen--; 132 | spos++; 133 | } 134 | /* Copy S value */ 135 | if (slen > 32) { 136 | overflow = 1; 137 | } else { 138 | memcpy(tmpsig + 64 - slen, input + spos, slen); 139 | } 140 | 141 | if (!overflow) { 142 | overflow = !secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig); 143 | } 144 | if (overflow) { 145 | memset(tmpsig, 0, 64); 146 | secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig); 147 | } 148 | return 1; 149 | } 150 | 151 | -------------------------------------------------------------------------------- /rust/uart-passthrough/demo/weather.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import argparse 3 | import os 4 | import serial 5 | import struct 6 | import sys 7 | import time 8 | 9 | from esp8266 import ESP8266, CLOSED 10 | 11 | def expect(a, b): 12 | if a == b: 13 | return 14 | print(f'Mismatch: {a} versus {b}', file=sys.stderr) 15 | assert(0) 16 | 17 | def sanity_check(ser): 18 | '''Check sanity of current rate''' 19 | retries = 0 20 | ser.write(b'AT\r\n') 21 | while retries < 5: 22 | line1 = ser.readline() 23 | if line1 == b'AT\r\n': 24 | expect(ser.readline(), b'\r\n') 25 | expect(ser.readline(), b'OK\r\n') 26 | return 27 | retries += 1 28 | raise IOError('Basic connection check failed') 29 | 30 | def send_oob(ser, buf): 31 | ser.baudrate = 115200 32 | # Toggle DTR for OoB command 33 | ser.dtr = False 34 | time.sleep(0.01) 35 | ser.dtr = True 36 | ser.write(buf) 37 | time.sleep(0.01) 38 | 39 | def reset_esp8266(ser): 40 | send_oob(ser, b'\x42') # reset 41 | 42 | retries = 0 43 | while retries < 5: 44 | line = ser.readline() 45 | # print('Reset: ', line) 46 | if line == b'ready\r\n': 47 | return 48 | retries += 1 49 | raise IOError('Reset failed') 50 | 51 | def set_rate(ser, newbaud): 52 | '''Set baudrate''' 53 | # Need to do three things here: 54 | # - Set WIFI module baudrate 55 | # - Set K210<->WIFI baudrate 56 | # - Set Host<->K210 baudrate 57 | 58 | sanity_check(ser) 59 | # Set WIFI module to new rate 60 | cmd = b'AT+UART_CUR=%d,8,1,0,0\r\n' % newbaud 61 | ser.write(cmd) 62 | try: 63 | expect(ser.readline(), cmd) 64 | expect(ser.readline(), b'\r\n') 65 | expect(ser.readline(), b'OK\r\n') 66 | except IOError as e: 67 | reset_esp8266(ser) 68 | raise 69 | 70 | send_oob(ser, b'\x23' + struct.pack(' 19 | 20 | /* clang-format off */ 21 | #define NO_OPERATION 0x00 22 | #define SOFTWARE_RESET 0x01 23 | #define READ_ID 0x04 24 | #define READ_STATUS 0x09 25 | #define READ_POWER_MODE 0x0A 26 | #define READ_MADCTL 0x0B 27 | #define READ_PIXEL_FORMAT 0x0C 28 | #define READ_IMAGE_FORMAT 0x0D 29 | #define READ_SIGNAL_MODE 0x0E 30 | #define READ_SELT_DIAG_RESULT 0x0F 31 | #define SLEEP_ON 0x10 32 | #define SLEEP_OFF 0x11 33 | #define PARTIAL_DISPLAY_ON 0x12 34 | #define NORMAL_DISPLAY_ON 0x13 35 | #define INVERSION_DISPLAY_OFF 0x20 36 | #define INVERSION_DISPLAY_ON 0x21 37 | #define GAMMA_SET 0x26 38 | #define DISPLAY_OFF 0x28 39 | #define DISPLAY_ON 0x29 40 | #define HORIZONTAL_ADDRESS_SET 0x2A 41 | #define VERTICAL_ADDRESS_SET 0x2B 42 | #define MEMORY_WRITE 0x2C 43 | #define COLOR_SET 0x2D 44 | #define MEMORY_READ 0x2E 45 | #define PARTIAL_AREA 0x30 46 | #define VERTICAL_SCROLL_DEFINE 0x33 47 | #define TEAR_EFFECT_LINE_OFF 0x34 48 | #define TEAR_EFFECT_LINE_ON 0x35 49 | #define MEMORY_ACCESS_CTL 0x36 50 | #define VERTICAL_SCROLL_S_ADD 0x37 51 | #define IDLE_MODE_OFF 0x38 52 | #define IDLE_MODE_ON 0x39 53 | #define PIXEL_FORMAT_SET 0x3A 54 | #define WRITE_MEMORY_CONTINUE 0x3C 55 | #define READ_MEMORY_CONTINUE 0x3E 56 | #define SET_TEAR_SCANLINE 0x44 57 | #define GET_SCANLINE 0x45 58 | #define WRITE_BRIGHTNESS 0x51 59 | #define READ_BRIGHTNESS 0x52 60 | #define WRITE_CTRL_DISPLAY 0x53 61 | #define READ_CTRL_DISPLAY 0x54 62 | #define WRITE_BRIGHTNESS_CTL 0x55 63 | #define READ_BRIGHTNESS_CTL 0x56 64 | #define WRITE_MIN_BRIGHTNESS 0x5E 65 | #define READ_MIN_BRIGHTNESS 0x5F 66 | #define READ_ID1 0xDA 67 | #define READ_ID2 0xDB 68 | #define READ_ID3 0xDC 69 | #define RGB_IF_SIGNAL_CTL 0xB0 70 | #define NORMAL_FRAME_CTL 0xB1 71 | #define IDLE_FRAME_CTL 0xB2 72 | #define PARTIAL_FRAME_CTL 0xB3 73 | #define INVERSION_CTL 0xB4 74 | #define BLANK_PORCH_CTL 0xB5 75 | #define DISPLAY_FUNCTION_CTL 0xB6 76 | #define ENTRY_MODE_SET 0xB7 77 | #define BACKLIGHT_CTL1 0xB8 78 | #define BACKLIGHT_CTL2 0xB9 79 | #define BACKLIGHT_CTL3 0xBA 80 | #define BACKLIGHT_CTL4 0xBB 81 | #define BACKLIGHT_CTL5 0xBC 82 | #define BACKLIGHT_CTL7 0xBE 83 | #define BACKLIGHT_CTL8 0xBF 84 | #define POWER_CTL1 0xC0 85 | #define POWER_CTL2 0xC1 86 | #define VCOM_CTL1 0xC5 87 | #define VCOM_CTL2 0xC7 88 | #define NV_MEMORY_WRITE 0xD0 89 | #define NV_MEMORY_PROTECT_KEY 0xD1 90 | #define NV_MEMORY_STATUS_READ 0xD2 91 | #define READ_ID4 0xD3 92 | #define POSITIVE_GAMMA_CORRECT 0xE0 93 | #define NEGATIVE_GAMMA_CORRECT 0xE1 94 | #define DIGITAL_GAMMA_CTL1 0xE2 95 | #define DIGITAL_GAMMA_CTL2 0xE3 96 | #define INTERFACE_CTL 0xF6 97 | 98 | #define DCX_GPIONUM (2) 99 | #define RST_GPIONUM (3) 100 | 101 | 102 | #define SPI_CHANNEL 0 103 | #define SPI_SLAVE_SELECT 3 104 | /* clang-format on */ 105 | 106 | void tft_hard_init(void); 107 | void tft_write_command(uint8_t cmd); 108 | void tft_write_byte(uint8_t *data_buf, uint32_t length); 109 | void tft_write_half(uint16_t *data_buf, uint32_t length); 110 | void tft_write_word(uint32_t *data_buf, uint32_t length, uint32_t flag); 111 | void tft_fill_data(uint32_t *data_buf, uint32_t length); 112 | 113 | #endif 114 | --------------------------------------------------------------------------------