Compare commits
3 Commits
e7a50040b2
...
27b07dc4a8
Author | SHA1 | Date |
---|---|---|
Savanni D'Gerinel | 27b07dc4a8 | |
Savanni D'Gerinel | 75e0a03ff0 | |
Savanni D'Gerinel | 5df343cdeb |
|
@ -1,39 +1,55 @@
|
||||||
#![no_main]
|
#![no_main]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
use embedded_hal::{delay::DelayNs, digital::OutputPin};
|
/// This application demonstrates using a Raspberry Pi Pico to control an individual SK9822 module.
|
||||||
use embedded_hal::spi::SpiBus;
|
/// Keep in mind that the Pico, though it accepts 5V for power, it runs on 3.3V logic. The GPIO
|
||||||
|
/// pins will emit only 3.3 volts, and the SK9822 needs 5V logic. So, make sure that the GPIO pins
|
||||||
|
/// run through a transistor or a logic level lhifter to go from 3.3V logic to 5V logic.
|
||||||
|
use embedded_hal::{delay::DelayNs, spi::SpiBus};
|
||||||
use panic_halt as _;
|
use panic_halt as _;
|
||||||
use rp_pico::hal::gpio::bank0::Gpio0;
|
|
||||||
use rp_pico::{
|
use rp_pico::{
|
||||||
entry,
|
entry,
|
||||||
hal::{
|
hal::{
|
||||||
clocks::init_clocks_and_plls,
|
clocks::init_clocks_and_plls,
|
||||||
fugit::RateExtU32,
|
fugit::RateExtU32,
|
||||||
gpio::{
|
gpio::{
|
||||||
bank0::{Gpio2, Gpio4},
|
bank0::{Gpio10, Gpio11},
|
||||||
FunctionSio, Pin, PullDown, SioOutput,
|
FunctionSpi, Pin, PullDown,
|
||||||
},
|
},
|
||||||
spi::{Enabled, Spi, SpiDevice, ValidSpiPinout},
|
spi::Spi,
|
||||||
uart::{DataBits, StopBits, UartConfig, UartPeripheral},
|
|
||||||
Clock, Sio, Timer, Watchdog,
|
Clock, Sio, Timer, Watchdog,
|
||||||
},
|
},
|
||||||
pac, Pins,
|
pac, Pins,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const FPS: u32 = 60;
|
||||||
|
const MS_PER_FRAME: u32 = 1000 / FPS;
|
||||||
const XOSC_CRYSTAL_FREQ: u32 = 12_000_000; // MHz, https://forums.raspberrypi.com/viewtopic.php?t=356764
|
const XOSC_CRYSTAL_FREQ: u32 = 12_000_000; // MHz, https://forums.raspberrypi.com/viewtopic.php?t=356764
|
||||||
|
|
||||||
#[entry]
|
#[entry]
|
||||||
unsafe fn main() -> ! {
|
unsafe fn main() -> ! {
|
||||||
|
// rp_pico::pac::Peripherals is a reference to physical hardware defined on the Pico.
|
||||||
let mut peripherals = pac::Peripherals::take().unwrap();
|
let mut peripherals = pac::Peripherals::take().unwrap();
|
||||||
|
|
||||||
|
// SIO inidcates "Single Cycle IO". I don't know what this means, but it could mean that this
|
||||||
|
// is a class of IO operations that can be run in a single clock cycle, such as switching a
|
||||||
|
// GPIO pin on or off.
|
||||||
let sio = Sio::new(peripherals.SIO);
|
let sio = Sio::new(peripherals.SIO);
|
||||||
|
|
||||||
|
// Many of the following systems require a watchdog. I do not know what this does, either, but
|
||||||
|
// it may be some failsafe software that will reset operations if the watchdog detects a lack
|
||||||
|
// of activity.
|
||||||
let mut watchdog = Watchdog::new(peripherals.WATCHDOG);
|
let mut watchdog = Watchdog::new(peripherals.WATCHDOG);
|
||||||
|
|
||||||
|
// Here we grab the GPIO pins in bank 0.
|
||||||
let pins = Pins::new(
|
let pins = Pins::new(
|
||||||
peripherals.IO_BANK0,
|
peripherals.IO_BANK0,
|
||||||
peripherals.PADS_BANK0,
|
peripherals.PADS_BANK0,
|
||||||
sio.gpio_bank0,
|
sio.gpio_bank0,
|
||||||
&mut peripherals.RESETS,
|
&mut peripherals.RESETS,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Initialize an abstraction of the clock system with a batch of standard hardware clocks.
|
||||||
let clocks = init_clocks_and_plls(
|
let clocks = init_clocks_and_plls(
|
||||||
XOSC_CRYSTAL_FREQ,
|
XOSC_CRYSTAL_FREQ,
|
||||||
peripherals.XOSC,
|
peripherals.XOSC,
|
||||||
|
@ -46,58 +62,64 @@ unsafe fn main() -> ! {
|
||||||
.ok()
|
.ok()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// let mut power_light: Pin<Gpio0, FunctionSio<SioOutput>, PullDown> = pins.gpio0.into_function();
|
// An abstraction for a timer which we can use to delay the code.
|
||||||
// power_light.set_high();
|
|
||||||
let mut timer = Timer::new(peripherals.TIMER, &mut peripherals.RESETS, &clocks);
|
let mut timer = Timer::new(peripherals.TIMER, &mut peripherals.RESETS, &clocks);
|
||||||
|
|
||||||
let spi_clk = pins.gpio10.into_function();
|
// Grab the clock and data pins for SPI1. For Clock pins and for Data pins, there are only two
|
||||||
let spi_sdo = pins.gpio11.into_function();
|
// pins each on the Pico which can function for SPI1.
|
||||||
let spi = Spi::<_, _, _, 8>::new(peripherals.SPI1, (spi_sdo, spi_clk));
|
let spi_clk: Pin<Gpio10, FunctionSpi, PullDown> = pins.gpio10.into_function();
|
||||||
let mut spi = spi.init(
|
let spi_sdo: Pin<Gpio11, FunctionSpi, PullDown> = pins.gpio11.into_function();
|
||||||
|
|
||||||
|
// Now, create the SPI function abstraction for SPI1 with spi_clk and spi_sdo.
|
||||||
|
let mut spi = Spi::<_, _, _, 8>::new(peripherals.SPI1, (spi_sdo, spi_clk)).init(
|
||||||
&mut peripherals.RESETS,
|
&mut peripherals.RESETS,
|
||||||
|
// The SPI system uses the peripheral clock
|
||||||
clocks.peripheral_clock.freq(),
|
clocks.peripheral_clock.freq(),
|
||||||
|
// Transmit data at a rate of 1Mbit.
|
||||||
1_u32.MHz(),
|
1_u32.MHz(),
|
||||||
|
// Run with SPI Mode 1. This means that the clock line should start high and that data will
|
||||||
|
// be sampled starting at the first falling edge.
|
||||||
embedded_hal::spi::MODE_1,
|
embedded_hal::spi::MODE_1,
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut lights: [u8; 126] = [0; 126];
|
// byte count: 4 for the start frame
|
||||||
lights[124] = 0xff;
|
// 1 * 4 for three lights with 4 bytes per light
|
||||||
lights[125] = 0xff;
|
// 4 for the end frame
|
||||||
for i in 0..30 {
|
// = 20 bytes
|
||||||
lights[(i + 1) * 4 + 0] = 0xe0 + 1;
|
let mut lights: [u8; 12] = [0; 12];
|
||||||
lights[(i + 1) * 4 + 1] = 255;
|
// We just skip the first four bytes, because the start frame is four bytes of 0.
|
||||||
}
|
|
||||||
|
|
||||||
|
// Set the first byte of the one and only lamp. The first byte follows the pattern of three 1
|
||||||
|
// bits followed by five additional bits that indicate an overall brightness level of the
|
||||||
|
// pixel. The datasheet for the SK9822 doesn't specify the exact effect, but it does mean that
|
||||||
|
// the higher this number is, the brighter 255 means for an given LED in the array. 1 is the
|
||||||
|
// lowest brightness that emits light, and 31 is the highest supported brightness.
|
||||||
|
lights[4] = 0xe0 + 1;
|
||||||
|
// Set the Blue light of the dotstar to 255, assuming the dotstar frame format is RBG. Note
|
||||||
|
// that the standard SK9822 datasheed indicates that the format is BGR. Your mileage may vary.
|
||||||
|
lights[6] = 255;
|
||||||
|
|
||||||
|
// The end frame is four bytes of 255.
|
||||||
|
lights[8] = 0xff;
|
||||||
|
lights[9] = 0xff;
|
||||||
|
lights[10] = 0xff;
|
||||||
|
lights[11] = 0xff;
|
||||||
|
|
||||||
|
|
||||||
|
// The rest of this is just a stock pulsating animation which is slightly brightening and
|
||||||
|
// dimming the *blue* LED (on my set of dotstars).
|
||||||
let mut brightness = 1;
|
let mut brightness = 1;
|
||||||
let mut step = 1;
|
let mut step = 1;
|
||||||
loop {
|
loop {
|
||||||
if brightness == 255 && step == 1 {
|
if brightness == 64 && step == 1 {
|
||||||
step = -1;
|
step = -1;
|
||||||
} else if brightness == 1 && step == -1 {
|
} else if brightness == 1 && step == -1 {
|
||||||
step = 1;
|
step = 1;
|
||||||
};
|
};
|
||||||
for i in 0..30 {
|
lights[5] = brightness as u8;
|
||||||
lights[(i + 1) * 4 + 3] = brightness as u8;
|
|
||||||
}
|
|
||||||
brightness = brightness + step;
|
brightness = brightness + step;
|
||||||
|
|
||||||
spi.write(lights.as_slice());
|
let _ = spi.write(lights.as_slice());
|
||||||
timer.delay_ms(10);
|
timer.delay_ms(MS_PER_FRAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
let pins = (pins.gpio0.into_function(), pins.gpio1.into_function());
|
|
||||||
|
|
||||||
let uart = UartPeripheral::new(peripherals.UART0, pins, &mut peripherals.RESETS)
|
|
||||||
.enable(
|
|
||||||
UartConfig::new(9600_u32.Hz(), DataBits::Eight, None, StopBits::One),
|
|
||||||
clocks.peripheral_clock.freq(),
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
loop {
|
|
||||||
uart.write_full_blocking(b"Hello World!\r\n");
|
|
||||||
timer.delay_ms(1000);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue