Skip to content

Instantly share code, notes, and snippets.

@piedoom
Created June 21, 2020 09:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save piedoom/11737876b245d4ee5e495b1f1358968d to your computer and use it in GitHub Desktop.
Save piedoom/11737876b245d4ee5e495b1f1358968d to your computer and use it in GitHub Desktop.
#![no_main]
#![no_std]
extern crate panic_semihosting;
extern crate stm32f1xx_hal as hal;
use cortex_m::singleton;
use rtic::app;
use rtic::cyccnt::U32Ext;
use stm32f1xx_hal::prelude::*;
#[macro_use]
use cortex_m_semihosting::hprintln;
use hal::{
dma::{dma1::C3, TxDma},
gpio::{gpioa, gpioa::*},
spi::{Mode, Phase, Polarity, Spi, SpiPayload},
time::MegaHertz,
};
use smart_leds::RGB8;
use ws2812::spi_bit_container;
use ws2812_spi_dma as ws2812;
const LED_COUNT: usize = 50;
const SYS_CLK: MegaHertz = MegaHertz(16);
spi_bit_container!(LedBitContainer, LED_COUNT);
#[app(device = stm32f1xx_hal::pac, peripherals = true, monotonic = rtic::cyccnt::CYCCNT)]
const APP: () = {
struct Resources {
led_count: usize,
spi_dma: TxDma<
SpiPayload<
hal::pac::SPI1,
hal::spi::Spi1NoRemap,
(
gpioa::PA5<hal::gpio::Alternate<hal::gpio::PushPull>>,
gpioa::PA6<hal::gpio::Input<hal::gpio::Floating>>,
PA7<hal::gpio::Alternate<hal::gpio::PushPull>>,
),
>,
C3,
>,
}
#[init(schedule = [exe])]
fn init(mut cx: init::Context) -> init::LateResources {
let mut core = cx.core;
// Initialize (enable) the monotonic timer (CYCCNT)
core.DWT.enable_cycle_counter();
hprintln!("init @ {:?}", cx.start).unwrap();
// Cortex-M peripherals
let mut rcc = cx.device.RCC.constrain();
let mut afio = cx.device.AFIO.constrain(&mut rcc.apb2);
let mut flash = cx.device.FLASH.constrain();
let mut mapr = cx.device.AFIO.constrain(&mut rcc.apb2).mapr;
let clocks = rcc
.cfgr
.sysclk(SYS_CLK)
.pclk1(24.mhz())
.freeze(&mut flash.acr);
hprintln!("Initialising Ws2812 LEDs").unwrap();
// Set up pins for SPI and create SPI interface
let mut gpioa = cx.device.GPIOA.split(&mut rcc.apb2);
let pins = (
gpioa.pa5.into_alternate_push_pull(&mut gpioa.crl),
gpioa.pa6.into_floating_input(&mut gpioa.crl),
gpioa.pa7.into_alternate_push_pull(&mut gpioa.crl),
);
let spi_mode = Mode {
polarity: Polarity::IdleLow,
phase: Phase::CaptureOnFirstTransition,
};
let mut spi = Spi::spi1(
cx.device.SPI1,
pins,
&mut mapr,
spi_mode,
3.mhz(),
clocks,
&mut rcc.apb2,
);
let dma = cx.device.DMA1.split(&mut rcc.ahb);
let spi_dma = spi.with_tx_dma(dma.3);
let bits: &'static mut LedBitContainer =
singleton!(: LedBitContainer = LedBitContainer::new()).unwrap();
let color = [RGB8::new(255, 0, 0); 50];
led_spi_bit_pattern(&color, &mut bits.data);
let transfer = spi_dma.write(bits.into());
transfer.wait();
cx.schedule.exe(cx.start).unwrap();
init::LateResources {
spi_dma: spi_dma,
led_count: LED_COUNT,
}
}
#[task(schedule = [exe], resources = [spi_dma, led_count])]
fn exe(mut cx: exe::Context) {
let data: [RGB8; 3] = [RGB8::default(); 3];
let empty: [RGB8; LED_COUNT] = [RGB8::default(); LED_COUNT];
cx.schedule.exe(cx.scheduled + 48_000_000.cycles()).unwrap();
}
extern "C" {
fn EXTI0();
}
};
fn led_spi_bit_pattern(leds: &[RGB8; LED_COUNT], mut output: &mut [u8]) {
// Set all LEDS to 0
for i in 0..output.len() {
output[i] = 0;
}
for led in leds.iter() {
set_from_byte(led.g, output);
output = &mut output[8..];
set_from_byte(led.r, output);
output = &mut output[8..];
set_from_byte(led.b, output);
output = &mut output[8..];
}
}
fn set_from_byte(byte: u8, mut target: &mut [u8]) {
for i in 0..8 {
set_spi_byte(byte << i & 0x70 == 0x70, target);
target = &mut target[1..]
}
}
fn set_spi_byte(value: bool, target: &mut [u8]) {
target[0] = match value {
false => 0b10000000,
true => 0b11110000,
};
}
@piedoom
Copy link
Author

piedoom commented Jun 21, 2020

error[E0282]: type annotations needed                               
   |
96 |         transfer.wait();
   |                  ^^^^ cannot infer type

error[E0599]: no method named `wait` found for struct `hal::dma::Tra:SPI1, hal::spi::Spi1NoRemap, (hal::gpio::gpioa::PA5<hal::gpio::Alternate<hal::gpio::PushPull>>, hal::gpio::gpioa::PA6<hal::gpio::Input<hal::gpio::Floating>>, hal::gpio::gpioa::PA7<hal::gpio::Alternate<hal::gpio::PushPull>>)>, hal::dma::dma1::C3>>` in the current scope   
  --> src\main.rs:96:18
   |
96 |         transfer.wait();
   |                  ^^^^ method not found in `hal::dma::Transfer<hal::dma::R, _, hal::dma::TxDma<hal::spi::SpiPayload<hal::pac::SPI1, 
hal::spi::Spi1NoRemap, (hal::gpio::gpioa::PA5<hal::gpio::Alternate<hal::gpio::PushPull>>, hal::gpio::gpioa::PA6<hal::gpio::Input<hal::gpio::Floating>>, hal::gpio::gpioa::PA7<hal::gpio::Alternate<hal::gpio::PushPull>>)>, hal::dma::dma1::C3>>`
   |
   = note: `transfer` is a function, perhaps you wish to call it    

error: aborting due to 2 previous errors

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment