Making i2c more generic over any i2c pins
This commit is contained in:
7
.vscode/settings.json
vendored
Normal file
7
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"editor.formatOnSave": true,
|
||||||
|
"editor.defaultFormatter": "rust-lang.rust-analyzer",
|
||||||
|
"workbench.editor.customLabels.patterns": {
|
||||||
|
"**/mod.rs": "mod | ${dirname}"
|
||||||
|
},
|
||||||
|
}
|
||||||
80
src/main.rs
80
src/main.rs
@@ -1,23 +1,13 @@
|
|||||||
// Intended to be used with a 1.3" OLED
|
// Intended to be used with a 1.3" OLED
|
||||||
// resolution is 128*64
|
// resolution is 128*64
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
use embedded_hal::{
|
use embedded_hal::{digital::OutputPin, i2c::I2c};
|
||||||
digital::OutputPin,
|
use hal::{fugit::RateExtU32, pac};
|
||||||
i2c::I2c
|
|
||||||
};
|
|
||||||
use hal::gpio::bank0::{Gpio8, Gpio9};
|
|
||||||
use rp2040_hal::gpio::PullUp;
|
|
||||||
use rp2040_hal as hal;
|
use rp2040_hal as hal;
|
||||||
use hal::{
|
use rp2040_hal::i2c::Error;
|
||||||
pac as pac,
|
|
||||||
gpio::{FunctionI2C, Pin},
|
|
||||||
fugit::RateExtU32,
|
|
||||||
};
|
|
||||||
|
|
||||||
use defmt as _;
|
use defmt as _;
|
||||||
use panic_probe as _;
|
use panic_probe as _;
|
||||||
@@ -76,10 +66,9 @@ fn main() -> ! {
|
|||||||
pac.IO_BANK0,
|
pac.IO_BANK0,
|
||||||
pac.PADS_BANK0,
|
pac.PADS_BANK0,
|
||||||
sio.gpio_bank0,
|
sio.gpio_bank0,
|
||||||
&mut pac.RESETS
|
&mut pac.RESETS,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// Create the I²C drive, using the two pre-configured pins.
|
// Create the I²C drive, using the two pre-configured pins.
|
||||||
let mut i2c = hal::I2C::i2c0(
|
let mut i2c = hal::I2C::i2c0(
|
||||||
pac.I2C0,
|
pac.I2C0,
|
||||||
@@ -116,18 +105,30 @@ fn main() -> ! {
|
|||||||
sprites[0].visible = true;
|
sprites[0].visible = true;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
|
||||||
gfx_buf.iter_mut().for_each(|x| *x = 0);
|
gfx_buf.iter_mut().for_each(|x| *x = 0);
|
||||||
|
|
||||||
sprites.iter_mut().for_each(|s| {
|
sprites.iter_mut().for_each(|s| {
|
||||||
if s.visible {
|
if s.visible {
|
||||||
sprite_atlas.draw_sprite(s.sprite_index, s.x as u8, s.y as u8, s.flip, &mut gfx_buf);
|
sprite_atlas.draw_sprite(
|
||||||
|
s.sprite_index,
|
||||||
|
s.x as u8,
|
||||||
|
s.y as u8,
|
||||||
|
s.flip,
|
||||||
|
&mut gfx_buf,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
sprite_atlas.draw_string(10, 10, "Hello World!", &mut gfx_buf);
|
sprite_atlas.draw_string(10, 10, "Hello World!", &mut gfx_buf);
|
||||||
|
|
||||||
sprite_atlas.draw_textfield(10, 20, 110, 10, "I think this font has a *lot* of 'character'! ;)", &mut gfx_buf);
|
sprite_atlas.draw_textfield(
|
||||||
|
10,
|
||||||
|
20,
|
||||||
|
110,
|
||||||
|
10,
|
||||||
|
"I think this font has a *lot* of 'character'! ;)",
|
||||||
|
&mut gfx_buf,
|
||||||
|
);
|
||||||
|
|
||||||
draw_bresenham_line(0, 0, 127, 0, &mut gfx_buf);
|
draw_bresenham_line(0, 0, 127, 0, &mut gfx_buf);
|
||||||
draw_bresenham_line(0, 63, 128, 63, &mut gfx_buf);
|
draw_bresenham_line(0, 63, 128, 63, &mut gfx_buf);
|
||||||
@@ -139,11 +140,7 @@ fn main() -> ! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_bresenham_line(
|
fn draw_bresenham_line(x0: u8, y0: u8, x1: u8, y1: u8, gfx_buf: &mut [u8; 8192]) {
|
||||||
x0: u8, y0: u8,
|
|
||||||
x1: u8, y1: u8,
|
|
||||||
gfx_buf: &mut [u8; 8192],
|
|
||||||
) {
|
|
||||||
let x0 = (x0 as i32).clamp(0, 127);
|
let x0 = (x0 as i32).clamp(0, 127);
|
||||||
let x1 = (x1 as i32).clamp(0, 127);
|
let x1 = (x1 as i32).clamp(0, 127);
|
||||||
let y0 = (y0 as i32).clamp(0, 63);
|
let y0 = (y0 as i32).clamp(0, 63);
|
||||||
@@ -195,15 +192,9 @@ fn draw_bresenham_line(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn blit_framebuffer(i2c: &mut dyn I2c<Error = Error>, graphic: &[u8; 8192]) {
|
||||||
|
|
||||||
fn blit_framebuffer(
|
|
||||||
i2c: &mut hal::I2C<pac::I2C0, (Pin<Gpio8, FunctionI2C, PullUp>, Pin<Gpio9, FunctionI2C, PullUp>)>,
|
|
||||||
graphic: &[u8; 8192]) {
|
|
||||||
|
|
||||||
// for each row of 8x8 pixels
|
// for each row of 8x8 pixels
|
||||||
for r in 0..8 {
|
for r in 0..8 {
|
||||||
set_page(i2c, r);
|
set_page(i2c, r);
|
||||||
@@ -230,13 +221,10 @@ fn blit_framebuffer(
|
|||||||
|
|
||||||
write_cel_pixels(i2c, &cel);
|
write_cel_pixels(i2c, &cel);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
fn set_col(i2c: &mut dyn I2c<Error = Error>, col: u8) {
|
||||||
|
|
||||||
fn set_col(i2c: &mut hal::I2C<pac::I2C0, (Pin<Gpio8, FunctionI2C, PullUp>, Pin<Gpio9, FunctionI2C, PullUp>)>,
|
|
||||||
col: u8) {
|
|
||||||
let col_lo = col & 0b0000_1111;
|
let col_lo = col & 0b0000_1111;
|
||||||
let col_hi = (col & 0b1111_0000) >> 4;
|
let col_hi = (col & 0b1111_0000) >> 4;
|
||||||
|
|
||||||
@@ -244,51 +232,43 @@ fn set_col(i2c: &mut hal::I2C<pac::I2C0, (Pin<Gpio8, FunctionI2C, PullUp>, Pin<G
|
|||||||
send_command(i2c, &SH1106Cmd::SetColumnHi, col_hi);
|
send_command(i2c, &SH1106Cmd::SetColumnHi, col_hi);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_page(i2c: &mut hal::I2C<pac::I2C0, (Pin<Gpio8, FunctionI2C, PullUp>, Pin<Gpio9, FunctionI2C, PullUp>)>,
|
fn set_page(i2c: &mut dyn I2c<Error = Error>, page: u8) {
|
||||||
page: u8) {
|
|
||||||
send_command(i2c, &SH1106Cmd::SetPage, page & 0b0000_0111);
|
send_command(i2c, &SH1106Cmd::SetPage, page & 0b0000_0111);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clr_screen(i2c: &mut hal::I2C<pac::I2C0, (Pin<Gpio8, FunctionI2C, PullUp>, Pin<Gpio9, FunctionI2C, PullUp>)>) {
|
fn clr_screen(i2c: &mut dyn I2c<Error = Error>) {
|
||||||
let mut writebuf = [0u8; 132 * 8 + 1];
|
let mut writebuf = [0u8; 132 * 8 + 1];
|
||||||
|
|
||||||
writebuf[0] = 0b0100_0000;
|
writebuf[0] = 0b0100_0000;
|
||||||
|
|
||||||
for i in 0..8 {
|
for i in 0..8 {
|
||||||
match i2c.write(SH1106_I2C_ADDR, &writebuf) {
|
match i2c.write(SH1106_I2C_ADDR, &writebuf) {
|
||||||
_ => ()
|
_ => (),
|
||||||
};
|
};
|
||||||
|
|
||||||
set_page(i2c, i);
|
set_page(i2c, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn write_cel_pixels(i2c: &mut dyn I2c<Error = Error>, data: &[u8]) {
|
||||||
fn write_cel_pixels(
|
|
||||||
i2c: &mut hal::I2C<pac::I2C0, (Pin<Gpio8, FunctionI2C, PullUp>, Pin<Gpio9, FunctionI2C, PullUp>)>,
|
|
||||||
data: &[u8]) {
|
|
||||||
|
|
||||||
let mut writebuf = [0b0100_0000u8; 9];
|
let mut writebuf = [0b0100_0000u8; 9];
|
||||||
|
|
||||||
writebuf[0] = 0b0100_0000;
|
writebuf[0] = 0b0100_0000;
|
||||||
writebuf[1..].copy_from_slice(&data[0..8]);
|
writebuf[1..].copy_from_slice(&data[0..8]);
|
||||||
|
|
||||||
match i2c.write(SH1106_I2C_ADDR, &writebuf) {
|
match i2c.write(SH1106_I2C_ADDR, &writebuf) {
|
||||||
_ => ()
|
_ => (),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn send_command(i2c: &mut dyn I2c<Error = Error>, command: &SH1106Cmd, data: u8) {
|
||||||
fn send_command(i2c: &mut hal::I2C<pac::I2C0, (Pin<Gpio8, FunctionI2C, PullUp>, Pin<Gpio9, FunctionI2C, PullUp>)>,
|
|
||||||
command: &SH1106Cmd,
|
|
||||||
data:u8) {
|
|
||||||
let mut writebuf: [u8; 2] = [0; 2];
|
let mut writebuf: [u8; 2] = [0; 2];
|
||||||
|
|
||||||
writebuf[0] = 0b1000_0000;
|
writebuf[0] = 0b1000_0000;
|
||||||
writebuf[1] = (command.clone() as u8) | data;
|
writebuf[1] = (command.clone() as u8) | data;
|
||||||
|
|
||||||
match i2c.write(SH1106_I2C_ADDR, &writebuf) {
|
match i2c.write(SH1106_I2C_ADDR, &writebuf) {
|
||||||
_ => ()
|
_ => (),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user