This commit is contained in:
Astro 2019-04-22 00:14:32 +02:00
commit 45eebb1b18
8 changed files with 285 additions and 0 deletions

12
.cargo/config Normal file
View File

@ -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)

35
Cargo.toml Normal file
View File

@ -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

18
build.rs Normal file
View File

@ -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");
}

50
default.nix Normal file
View File

@ -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;
}

6
memory.x Normal file
View File

@ -0,0 +1,6 @@
/* Linker script for the STM32F103C8T6 */
MEMORY
{
FLASH : ORIGIN = 0x08000000, LENGTH = 64K
RAM : ORIGIN = 0x20000000, LENGTH = 20K
}

10
openocd.gdb Normal file
View File

@ -0,0 +1,10 @@
target remote :3333
# print demangled symbols by default
set print asm-demangle on
monitor arm semihosting enable
load
continue
#step

23
shell.nix Normal file
View File

@ -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'"
'';
}

131
src/main.rs Normal file
View File

@ -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();
}
}