Skip to content

Commit 10243d5

Browse files
Merge pull request #9 from FrameworkComputer/workspaces-b1display
2 parents 9db273a + 0d9dc8f commit 10243d5

File tree

8 files changed

+167
-100
lines changed

8 files changed

+167
-100
lines changed

Cargo.lock

Lines changed: 12 additions & 40 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

b1display/Cargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@ usbd-serial = "0.1.1"
2626
usbd-hid = "0.5.1"
2727
fugit = "0.3.6"
2828

29-
display-interface-spi = "0.4.1"
30-
mipidsi = "0.6.0"
29+
st7306-lcd = { git = "ssh://[email protected]/FrameworkComputer/st7306.git" }
3130
embedded-graphics = "0.7"
3231
tinybmp = "0.4.0"
3332

b1display/src/main.rs

Lines changed: 63 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,16 @@ use cortex_m::delay::Delay;
99
use defmt_rtt as _;
1010
use embedded_hal::digital::v2::{InputPin, OutputPin};
1111

12-
use mipidsi::Orientation;
13-
use rp2040_hal::gpio::bank0::Gpio18;
1412
use rp2040_hal::gpio::{Output, Pin, PushPull};
1513
//#[cfg(debug_assertions)]
1614
//use panic_probe as _;
1715
use rp2040_panic_usb_boot as _;
1816

1917
use embedded_graphics::pixelcolor::Rgb565;
2018
use embedded_graphics::prelude::*;
19+
use embedded_graphics::primitives::*;
20+
use embedded_hal::blocking::spi;
21+
use st7306_lcd::ST7306;
2122

2223
// Provide an alias for our BSP so we can switch targets quickly.
2324
// Uncomment the BSP you included in Cargo.toml, the rest of the code does not need to change.
@@ -27,7 +28,7 @@ use lotus_inputmodules::lotus_lcd_hal as bsp;
2728

2829
use bsp::hal::{
2930
clocks::{init_clocks_and_plls, Clock},
30-
pac,
31+
gpio, pac,
3132
sio::Sio,
3233
usb,
3334
watchdog::Watchdog,
@@ -42,7 +43,7 @@ use usb_device::{class_prelude::*, prelude::*};
4243
use usbd_serial::{SerialPort, USB_CLASS_CDC};
4344

4445
// Used to demonstrate writing formatted strings
45-
use core::fmt::Write;
46+
use core::fmt::{Debug, Write};
4647
use heapless::String;
4748

4849
use lotus_inputmodules::control::*;
@@ -126,10 +127,12 @@ fn main() -> ! {
126127
let _spi_sclk = pins.scl.into_mode::<bsp::hal::gpio::FunctionSpi>();
127128
let _spi_mosi = pins.sda.into_mode::<bsp::hal::gpio::FunctionSpi>();
128129
let _spi_miso = pins.miso.into_mode::<bsp::hal::gpio::FunctionSpi>();
129-
let spi = bsp::hal::Spi::<_, _, 8>::new(pac.SPI1);
130+
let spi = bsp::hal::Spi::<_, _, 8>::new(pac.SPI0);
130131
// Display control pins
131132
let dc = pins.dc.into_push_pull_output();
132-
let mut lcd_led = pins.backlight.into_push_pull_output();
133+
//let mut lcd_led = pins.backlight.into_push_pull_output();
134+
let mut cs = pins.cs.into_push_pull_output();
135+
cs.set_low().unwrap();
133136
let rst = pins.rstb.into_push_pull_output();
134137

135138
let spi = spi.init(
@@ -139,27 +142,51 @@ fn main() -> ! {
139142
&embedded_hal::spi::MODE_0,
140143
);
141144

142-
// Create a DisplayInterface from SPI and DC pin, with no manual CS control
143-
let di = display_interface_spi::SPIInterfaceNoCS::new(spi, dc);
144-
let mut disp = mipidsi::Builder::st7735s(di)
145-
.with_invert_colors(true) // Looks cooler. TODO: Should invert image not entire screen
146-
.with_orientation(Orientation::PortraitInverted(false))
147-
.init(&mut delay, Some(rst))
145+
let mut disp: ST7306<
146+
rp2040_hal::Spi<rp2040_hal::spi::Enabled, pac::SPI0, 8>,
147+
Pin<gpio::bank0::Gpio20, Output<PushPull>>,
148+
Pin<gpio::bank0::Gpio17, Output<PushPull>>,
149+
Pin<gpio::bank0::Gpio21, Output<PushPull>>,
150+
25,
151+
200,
152+
> = ST7306::new(spi, dc, cs, rst, false, 300, 400);
153+
disp.init(&mut delay).unwrap();
154+
155+
// TODO: Seems broken
156+
//disp.clear(Rgb565::WHITE).unwrap();
157+
Rectangle::new(Point::new(0, 0), Size::new(300, 400))
158+
.into_styled(PrimitiveStyle::with_fill(Rgb565::WHITE))
159+
.draw(&mut disp)
148160
.unwrap();
149-
disp.clear(Rgb565::WHITE).unwrap();
150161

151162
let logo_rect = draw_logo(&mut disp).unwrap();
163+
Rectangle::new(Point::new(10, 10), Size::new(10, 10))
164+
.into_styled(PrimitiveStyle::with_fill(Rgb565::BLACK))
165+
.draw(&mut disp)
166+
.unwrap();
167+
Rectangle::new(Point::new(20, 20), Size::new(10, 10))
168+
.into_styled(PrimitiveStyle::with_fill(Rgb565::BLACK))
169+
.draw(&mut disp)
170+
.unwrap();
171+
Rectangle::new(Point::new(30, 30), Size::new(10, 10))
172+
.into_styled(PrimitiveStyle::with_fill(Rgb565::BLACK))
173+
.draw(&mut disp)
174+
.unwrap();
175+
Rectangle::new(Point::new(40, 40), Size::new(10, 10))
176+
.into_styled(PrimitiveStyle::with_fill(Rgb565::BLACK))
177+
.draw(&mut disp)
178+
.unwrap();
179+
Rectangle::new(Point::new(50, 50), Size::new(10, 10))
180+
.into_styled(PrimitiveStyle::with_fill(Rgb565::BLACK))
181+
.draw(&mut disp)
182+
.unwrap();
152183
draw_text(
153184
&mut disp,
154185
"Framework",
155-
Point::new(0, LOGO_OFFSET + logo_rect.size.height as i32),
186+
Point::new(LOGO_OFFSET_X, LOGO_OFFSET_Y + logo_rect.size.height as i32),
156187
)
157188
.unwrap();
158189

159-
// Wait until the background and image have been rendered otherwise
160-
// the screen will show random pixels for a brief moment
161-
lcd_led.set_high().unwrap();
162-
163190
let sleep = pins.sleep.into_pull_down_input();
164191

165192
let mut state = State {
@@ -172,10 +199,9 @@ fn main() -> ! {
172199
let mut prev_timer = timer.get_counter().ticks();
173200

174201
loop {
175-
// TODO: Current hardware revision does not have the sleep pin wired up :(
176202
// Go to sleep if the host is sleeping
177-
let _host_sleeping = sleep.is_low().unwrap();
178-
//handle_sleep(host_sleeping, &mut state, &mut matrix, &mut delay);
203+
let host_sleeping = sleep.is_low().unwrap();
204+
handle_sleep(host_sleeping, &mut state, &mut delay, &mut disp);
179205

180206
// Handle period display updates. Don't do it too often
181207
if timer.get_counter().ticks() > prev_timer + 20_000 {
@@ -212,11 +238,11 @@ fn main() -> ! {
212238
Ok(count) => {
213239
if let Some(command) = parse_command(count, &buf) {
214240
if let Command::Sleep(go_sleeping) = command {
215-
handle_sleep(go_sleeping, &mut state, &mut delay, &mut lcd_led);
241+
handle_sleep(go_sleeping, &mut state, &mut delay, &mut disp);
216242
} else if let SleepState::Awake = state.sleeping {
217243
// While sleeping no command is handled, except waking up
218244
//handle_command(&command, &mut disp, logo_rect);
219-
if let Some(response) = handle_command(&command, &mut disp, logo_rect) {
245+
if let Some(response) = handle_command(&command, logo_rect, &mut disp) {
220246
let _ = serial.write(&response);
221247
};
222248
}
@@ -227,20 +253,25 @@ fn main() -> ! {
227253
}
228254
}
229255

230-
fn handle_sleep(
256+
fn handle_sleep<SPI, DC, CS, RST, const COLS: usize, const ROWS: usize>(
231257
go_sleeping: bool,
232258
state: &mut State,
233259
_delay: &mut Delay,
234-
lcd_led: &mut Pin<Gpio18, Output<PushPull>>,
235-
) {
260+
disp: &mut ST7306<SPI, DC, CS, RST, COLS, ROWS>,
261+
) where
262+
SPI: spi::Write<u8>,
263+
DC: OutputPin,
264+
CS: OutputPin,
265+
RST: OutputPin,
266+
<SPI as spi::Write<u8>>::Error: Debug,
267+
{
236268
match (state.sleeping.clone(), go_sleeping) {
237269
(SleepState::Awake, false) => (),
238270
(SleepState::Awake, true) => {
239271
state.sleeping = SleepState::Sleeping;
240-
//state.grid = display_sleep();
241272

242-
// Turn off backlight
243-
lcd_led.set_low().unwrap();
273+
// Turn off display
274+
disp.on_off(false).unwrap();
244275

245276
// TODO: Power Display controller down
246277

@@ -252,10 +283,10 @@ fn handle_sleep(
252283
// Restore back grid before sleeping
253284
state.sleeping = SleepState::Awake;
254285

255-
// TODO: Power display controller back on
286+
// Turn display back on
287+
disp.on_off(true).unwrap();
256288

257-
// Turn backlight back on
258-
lcd_led.set_high().unwrap();
289+
// TODO: Power display controller back on
259290
}
260291
}
261292
}

control.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,14 @@ def main():
105105
help="Get device version", action="store_true")
106106
parser.add_argument("--serial-dev", help="Change the serial dev. Probably /dev/ttyACM0 on Linux, COM0 on Windows",
107107
default='/dev/ttyACM0')
108+
109+
parser.add_argument(
110+
"--disp-str", help="Display a string on the LCD Display", type=str)
111+
parser.add_argument("--display-on", help="Control display power",
112+
action=argparse.BooleanOptionalAction)
113+
parser.add_argument("--invert-screen", help="Invert display",
114+
action=argparse.BooleanOptionalAction)
115+
108116
args = parser.parse_args()
109117

110118
if args.serial_dev is not None:
@@ -179,6 +187,12 @@ def main():
179187
show_string(args.string)
180188
elif args.symbols is not None:
181189
show_symbols(args.symbols)
190+
elif args.disp_str is not None:
191+
display_string(args.disp_str)
192+
elif args.display_on is not None:
193+
display_on_cmd(args.display_on)
194+
elif args.invert_screen is not None:
195+
invert_screen_cmd(args.invert_screen)
182196
elif args.version:
183197
version = get_version()
184198
print(f"Device version: {version}")
@@ -922,6 +936,23 @@ def gui():
922936

923937
window.close()
924938

939+
940+
def display_string(disp_str):
941+
b = [ord(x) for x in disp_str]
942+
command = FWK_MAGIC + [0x09, len(disp_str)] + b
943+
send_command(command)
944+
945+
946+
def display_on_cmd(on):
947+
command = FWK_MAGIC + [0x014, int(on)]
948+
send_command(command)
949+
950+
951+
def invert_screen_cmd(invert):
952+
command = FWK_MAGIC + [0x015, int(invert)]
953+
send_command(command)
954+
955+
925956
# 5x6 symbol font. Leaves 2 pixels on each side empty
926957
# We can leave one row empty below and then the display fits 5 of these digits.
927958

lotus-inputmodules/Cargo.toml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,7 @@ fugit = "0.3.6"
3030
is31fl3741 = { git = "https://github.com/JohnAZoidberg/is31fl3741", branch = "all-at-once", optional = true }
3131

3232
# B1 Display
33-
display-interface-spi = { version = "0.4.1", optional = true }
34-
mipidsi = { version = "0.6.0", optional = true }
33+
st7306-lcd = { git = "ssh://[email protected]/FrameworkComputer/st7306.git", optional = true }
3534
embedded-graphics = { version = "0.7", optional = true }
3635
tinybmp = { version = "0.4.0", optional = true }
3736

@@ -42,5 +41,5 @@ ws2812-pio = { version = "0.5.0", optional = true }
4241
[features]
4342
default = []
4443
ledmatrix = [ "is31fl3741" ]
45-
b1display = [ "display-interface-spi", "mipidsi", "embedded-graphics", "tinybmp" ]
44+
b1display = [ "st7306-lcd", "embedded-graphics", "tinybmp" ]
4645
c1minimal = ["smart-leds", "ws2812-pio" ]

0 commit comments

Comments
 (0)