PoC
This commit is contained in:
commit
45eebb1b18
|
@ -0,0 +1,12 @@
|
||||||
|
[target.thumbv7m-none-eabi]
|
||||||
|
runner = "gdb -q -x openocd.gdb"
|
||||||
|
rustflags = [
|
||||||
|
"-C", "link-arg=-Tlink.x",
|
||||||
|
]
|
||||||
|
|
||||||
|
[build]
|
||||||
|
# Pick ONE of these compilation targets
|
||||||
|
# target = "thumbv6m-none-eabi" # Cortex-M0 and Cortex-M0+
|
||||||
|
target = "thumbv7m-none-eabi" # Cortex-M3
|
||||||
|
# target = "thumbv7em-none-eabi" # Cortex-M4 and Cortex-M7 (no FPU)
|
||||||
|
# target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (with FPU)
|
|
@ -0,0 +1,35 @@
|
||||||
|
[package]
|
||||||
|
categories = ["embedded", "no-std"]
|
||||||
|
name = "pentatube"
|
||||||
|
license = "GPL-3.0-only"
|
||||||
|
authors = ["Astro <astro@spaceboyz.net>"]
|
||||||
|
version = "0.0.0"
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[badges]
|
||||||
|
maintenance = { status = "experimental" }
|
||||||
|
|
||||||
|
[package.metadata.docs.rs]
|
||||||
|
features = []
|
||||||
|
default-target = "thumbv7m-none-eabi"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
panic-abort = "0.3.1"
|
||||||
|
bare-metal = "0.2"
|
||||||
|
cortex-m = "0.5"
|
||||||
|
cortex-m-rt = { version = "0.6", features = ["device"] }
|
||||||
|
cortex-m-log = { version = "0.4", features = ["log-integration"] }
|
||||||
|
stm32f1 = { version = "0.6", features = ["rt", "stm32f103"] }
|
||||||
|
embedded-hal = "0.2.2"
|
||||||
|
stm32f1xx-hal = { git = "https://github.com/stm32-rs/stm32f1xx-hal", features = ["rt", "stm32f103"] }
|
||||||
|
#stm32f1xx-hal = { path = "../stm32f4xx-hal", features = ["rt", "stm32f429"] }
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = []
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
codegen-units = 1
|
||||||
|
incremental = false
|
||||||
|
debug = true
|
||||||
|
opt-level = "s"
|
||||||
|
lto = true
|
|
@ -0,0 +1,18 @@
|
||||||
|
use std::env;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::Write;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// Put the linker script somewhere the linker can find it
|
||||||
|
let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
|
||||||
|
File::create(out.join("memory.x"))
|
||||||
|
.unwrap()
|
||||||
|
.write_all(include_bytes!("memory.x"))
|
||||||
|
.unwrap();
|
||||||
|
println!("cargo:rustc-link-search={}", out.display());
|
||||||
|
|
||||||
|
// Only re-run the build script when memory.x is changed,
|
||||||
|
// instead of when any part of the source code changes.
|
||||||
|
println!("cargo:rerun-if-changed=memory.x");
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
{ # Use master branch of the overlay by default
|
||||||
|
mozillaOverlay ? import (builtins.fetchTarball https://github.com/mozilla/nixpkgs-mozilla/archive/master.tar.gz),
|
||||||
|
rustManifest ? builtins.fetchurl "https://static.rust-lang.org/dist/channel-rust-nightly.toml"
|
||||||
|
}:
|
||||||
|
|
||||||
|
let
|
||||||
|
pkgs = import <nixpkgs> { overlays = [ mozillaOverlay ]; };
|
||||||
|
in
|
||||||
|
with pkgs;
|
||||||
|
let
|
||||||
|
targets = [
|
||||||
|
"x86_64-unknown-linux-gnu"
|
||||||
|
"thumbv6m-none-eabi"
|
||||||
|
"thumbv7m-none-eabi"
|
||||||
|
"thumbv7em-none-eabi"
|
||||||
|
"thumbv7em-none-eabihf"
|
||||||
|
];
|
||||||
|
rust =
|
||||||
|
rustChannelOfTargets "nightly" null targets;
|
||||||
|
rustPlatform = recurseIntoAttrs (makeRustPlatform {
|
||||||
|
rustc = rust;
|
||||||
|
cargo = rust;
|
||||||
|
});
|
||||||
|
|
||||||
|
openocd =
|
||||||
|
stdenv.mkDerivation {
|
||||||
|
name = "openocd-stlink-blackpill";
|
||||||
|
buildInputs = [
|
||||||
|
pkgs.openocd
|
||||||
|
makeWrapper
|
||||||
|
];
|
||||||
|
src = ./src;
|
||||||
|
noBuild = true;
|
||||||
|
installPhase =
|
||||||
|
let
|
||||||
|
openOcdFlags = [
|
||||||
|
"-f" "${pkgs.openocd}/share/openocd/scripts/interface/stlink-v2-1.cfg"
|
||||||
|
"-f" "${pkgs.openocd}/share/openocd/scripts/target/stm32f1x.cfg"
|
||||||
|
"-c" "init"
|
||||||
|
];
|
||||||
|
in ''
|
||||||
|
mkdir -p $out/bin
|
||||||
|
|
||||||
|
makeWrapper ${pkgs.openocd}/bin/openocd $out/bin/openocd-stlink-blackpill \
|
||||||
|
--add-flags "${lib.escapeShellArgs openOcdFlags}"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
inherit pkgs rustPlatform openocd;
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
/* Linker script for the STM32F103C8T6 */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
FLASH : ORIGIN = 0x08000000, LENGTH = 64K
|
||||||
|
RAM : ORIGIN = 0x20000000, LENGTH = 20K
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
target remote :3333
|
||||||
|
|
||||||
|
# print demangled symbols by default
|
||||||
|
set print asm-demangle on
|
||||||
|
|
||||||
|
monitor arm semihosting enable
|
||||||
|
|
||||||
|
load
|
||||||
|
continue
|
||||||
|
#step
|
|
@ -0,0 +1,23 @@
|
||||||
|
let
|
||||||
|
project = import ./default.nix {};
|
||||||
|
in
|
||||||
|
with project.pkgs;
|
||||||
|
stdenv.mkDerivation {
|
||||||
|
name = "project-env";
|
||||||
|
buildInputs = with project.rustPlatform.rust; [
|
||||||
|
rustc cargo gdb project.openocd
|
||||||
|
];
|
||||||
|
|
||||||
|
# Set Environment Variables
|
||||||
|
RUST_BACKTRACE = 1;
|
||||||
|
|
||||||
|
shellHook = ''
|
||||||
|
echo "Starting openocd…"
|
||||||
|
${project.openocd}/bin/openocd-stlink-blackpill -c "reset init" &
|
||||||
|
|
||||||
|
# Let openocd output scroll by
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
echo "Run 'cargo run --release'"
|
||||||
|
'';
|
||||||
|
}
|
|
@ -0,0 +1,131 @@
|
||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
// #![deny(warnings, unused)]
|
||||||
|
|
||||||
|
#[allow(unused_extern_crates)]
|
||||||
|
extern crate panic_abort;
|
||||||
|
|
||||||
|
// use cortex_m::asm::{wfi, nop};
|
||||||
|
use cortex_m_rt::entry;
|
||||||
|
use embedded_hal::{
|
||||||
|
digital::OutputPin,
|
||||||
|
spi::MODE_0,
|
||||||
|
blocking::spi::Write as SpiWrite,
|
||||||
|
// watchdog::{WatchdogEnable, Watchdog},
|
||||||
|
};
|
||||||
|
use stm32f1xx_hal::{
|
||||||
|
flash::FlashExt,
|
||||||
|
rcc::RccExt,
|
||||||
|
gpio::GpioExt,
|
||||||
|
afio::AfioExt,
|
||||||
|
time::U32Ext,
|
||||||
|
spi::Spi,
|
||||||
|
stm32::{CorePeripherals, Peripherals},
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
pub struct PwmGraphics {
|
||||||
|
t: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PwmGraphics {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
PwmGraphics { t: 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn generate_frame(&mut self, rgb: &[[u8; 3]; 8]) -> [u8; 3] {
|
||||||
|
let mut bgr = [0u8; 3];
|
||||||
|
|
||||||
|
for i in 0..bgr.len() {
|
||||||
|
for x in 0..rgb.len() {
|
||||||
|
if self.t < rgb[x][i] {
|
||||||
|
bgr[2 - i] |= 1 << x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.t += 1;
|
||||||
|
bgr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Initialization and main loop
|
||||||
|
#[entry]
|
||||||
|
fn main() -> ! {
|
||||||
|
let mut cp = CorePeripherals::take().unwrap();
|
||||||
|
cp.SCB.enable_icache();
|
||||||
|
cp.SCB.enable_dcache(&mut cp.CPUID);
|
||||||
|
|
||||||
|
let dp = Peripherals::take().unwrap();
|
||||||
|
let mut flash = dp.FLASH.constrain();
|
||||||
|
let mut rcc = dp.RCC.constrain();
|
||||||
|
let clocks = rcc.cfgr
|
||||||
|
.use_hse(8.mhz())
|
||||||
|
.sysclk(72.mhz())
|
||||||
|
.hclk(72.mhz())
|
||||||
|
.pclk1(36.mhz())
|
||||||
|
.pclk2(72.mhz())
|
||||||
|
.freeze(&mut flash.acr);
|
||||||
|
|
||||||
|
// let mut wd = IndependentWatchdog::new(dp.IWDG);
|
||||||
|
// wd.start(1000u32.ms());
|
||||||
|
// wd.feed();
|
||||||
|
|
||||||
|
let mut gpioa = dp.GPIOA.split(&mut rcc.apb2);
|
||||||
|
let mut gpiob = dp.GPIOB.split(&mut rcc.apb2);
|
||||||
|
|
||||||
|
let mut led = gpiob.pb12.into_push_pull_output(&mut gpiob.crh);
|
||||||
|
|
||||||
|
// (srclk) violet, nucleo: D13
|
||||||
|
let sck = gpioa.pa5.into_alternate_push_pull(&mut gpioa.crl);
|
||||||
|
// not connected
|
||||||
|
let miso = gpioa.pa6.into_floating_input(&mut gpioa.crl);
|
||||||
|
// (serin) blue, nucleo: D11
|
||||||
|
let mosi = gpioa.pa7.into_alternate_push_pull(&mut gpioa.crl);
|
||||||
|
let pins = (sck, miso, mosi);
|
||||||
|
let mut parts = dp.AFIO.constrain(&mut rcc.apb2);
|
||||||
|
let mut spi = Spi::spi1(dp.SPI1, pins, &mut parts.mapr, MODE_0, 36u32.mhz(), clocks, &mut rcc.apb2);
|
||||||
|
|
||||||
|
// (rclk) brown, nucleo: D8
|
||||||
|
let mut rclk = gpioa.pa4.into_push_pull_output(&mut gpioa.crl);
|
||||||
|
// (srclr) green, nucleo: D9
|
||||||
|
let mut srclr = gpioa.pa3.into_push_pull_output(&mut gpioa.crl);
|
||||||
|
|
||||||
|
// timer::setup(cp.SYST, clocks);
|
||||||
|
|
||||||
|
srclr.set_high();
|
||||||
|
rclk.set_low();
|
||||||
|
let mut pg = PwmGraphics::new();
|
||||||
|
let mut t = 0usize;
|
||||||
|
loop {
|
||||||
|
let mut frame = [[0u8; 3]; 8];
|
||||||
|
for x in 0..frame.len() {
|
||||||
|
frame[x][0] = (t >> 10) as u8;
|
||||||
|
frame[x][1] = ((t >> 10) + (x << 1)) as u8;
|
||||||
|
frame[x][2] = ((t >> 9) - (x << 2)) as u8;
|
||||||
|
}
|
||||||
|
let data = pg.generate_frame(&frame);
|
||||||
|
spi.write(&data)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
rclk.set_high();
|
||||||
|
// for _ in 0..200 {
|
||||||
|
// nop();
|
||||||
|
// }
|
||||||
|
rclk.set_low();
|
||||||
|
|
||||||
|
t += 1;
|
||||||
|
if (t / 1_000) % 2 == 0 {
|
||||||
|
led.set_high();
|
||||||
|
} else {
|
||||||
|
led.set_low();
|
||||||
|
}
|
||||||
|
// // for _ in 0..100000 {
|
||||||
|
// // nop();
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // Update watchdog
|
||||||
|
// wd.feed();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue