Skip to content

Commit

Permalink
LCD Communication fix (#48)
Browse files Browse the repository at this point in the history
* update microzig, include lcd

* wip

* wip

* SPI communication with LCD is fixed

* increase cart ram allocation

* add framebuffer to cart fixed memory
  • Loading branch information
mattnite authored May 15, 2024
1 parent 83983b7 commit 8b134df
Show file tree
Hide file tree
Showing 13 changed files with 507 additions and 57 deletions.
5 changes: 3 additions & 2 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ pub fn build(b: *Build) void {

const zeroman_cart = add_cart(&dep, b, .{
.name = "zeroman",
.optimize = .ReleaseSmall,
.optimize = optimize,
.root_source_file = .{ .path = "samples/zeroman/main.zig" },
});
add_zeroman_assets_step(b, zeroman_cart);
Expand Down Expand Up @@ -91,7 +91,8 @@ pub fn build(b: *Build) void {
//"usb_cdc",
//"usb_storage",
"buttons",
//"lcd",
"lcd",
"spi",
"audio",
"light_sensor",
//"qspi",
Expand Down
30 changes: 29 additions & 1 deletion src/badge.zig
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const chip = microzig.chip;
const hal = microzig.hal;
const clocks = hal.clocks;
const timer = hal.timer;
const sercom = hal.sercom;

// direct peripheral access
const SystemControl = chip.peripherals.SystemControl;
Expand Down Expand Up @@ -78,7 +79,6 @@ pub fn main() !void {
clocks.gclk.reset_blocking();
microzig.cpu.dmb();

// lcd init
// audio init
//
// MPU.RBAR
Expand Down Expand Up @@ -134,6 +134,7 @@ pub fn main() !void {

clocks.gclk.enable_generator(.GCLK3, .DPLL1, .{});
clocks.gclk.set_peripheral_clk_gen(.GCLK_TC4_TC5, .GCLK3);
clocks.gclk.set_peripheral_clk_gen(.GCLK_SERCOM4_CORE, .GCLK0);

timer.init();
init_frame_sync();
Expand All @@ -145,12 +146,37 @@ pub fn main() !void {
.TC0 = .enabled,
.TC1 = .enabled,
.TC4 = .enabled,
.SERCOM4 = .enabled,
});

const state = clocks.get_state();
const freqs = clocks.Frequencies.get(state);
_ = freqs;

const lcd = Lcd.init(.{
.spi = sercom.spi.Master.init(.SERCOM4, .{
.cpha = .LEADING_EDGE,
.cpol = .IDLE_LOW,
.dord = .MSB,
.dopo = .PAD2,
.ref_freq_hz = 120_000_000,
.baud_freq_hz = 4_000_000,
}),
.pins = .{
.rst = board.TFT_RST,
.lite = board.TFT_LITE,
.dc = board.TFT_DC,
.cs = board.TFT_CS,
.sck = board.TFT_SCK,
.mosi = board.TFT_MOSI,
},
.fb = .{
.bpp16 = @ptrCast(cart.api.framebuffer),
},
});

lcd.clear_screen(.{ .r = 0, .g = 0, .b = 0 });

const neopixels = board.Neopixels.init(board.D8_NEOPIX);
adc.init();
const poller = ButtonPoller.init();
Expand Down Expand Up @@ -188,6 +214,8 @@ pub fn main() !void {

neopixels.write(&pixels);
led_pin.write(if (cart.api.red_led.*) .high else .low);
lcd.set_window(0, 0, 160, 128);
lcd.send_colors(@ptrCast(cart.api.framebuffer));
}
}

Expand Down
7 changes: 7 additions & 0 deletions src/badge/cart.zig
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,13 @@ pub const HSRAM = struct {

pub fn start() void {
@memset(@as(*[0x19A0]u8, @ptrFromInt(0x20000000)), 0);
api.neopixels.* = .{
.{ .r = 0, .g = 0, .b = 0 },
.{ .r = 0, .g = 0, .b = 0 },
.{ .r = 0, .g = 0, .b = 0 },
.{ .r = 0, .g = 0, .b = 0 },
.{ .r = 0, .g = 0, .b = 0 },
};

// fill .bss with zeroes
{
Expand Down
15 changes: 10 additions & 5 deletions src/badge/demos/lcd.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ const std = @import("std");
const microzig = @import("microzig");

const hal = microzig.hal;
const mclk = hal.mclk;
const gclk = hal.gclk;
const mclk = hal.clocks.mclk;
const gclk = hal.clocks.gclk;
const sercom = hal.sercom;
const port = hal.port;
const timer = hal.timer;
Expand Down Expand Up @@ -35,7 +35,8 @@ pub fn main() !void {
.div = 48,
});

gclk.set_peripheral_clk_gen(.GCLK_SERCOM4_CORE, .GCLK0);
gclk.set_peripheral_clk_gen(.GCLK_SERCOM4_CORE, .GCLK1);
gclk.set_peripheral_clk_gen(.GCLK_TC0_TC1, .GCLK1);

// TODO: pin and clock configuration
mclk.set_apb_mask(.{
Expand All @@ -45,7 +46,7 @@ pub fn main() !void {
});

timer.init();
const lcd = Lcd.init(.{
var lcd = Lcd.init(.{
.spi = sercom.spi.Master.init(.SERCOM4, .{
.cpha = .LEADING_EDGE,
.cpol = .IDLE_LOW,
Expand All @@ -67,7 +68,11 @@ pub fn main() !void {
},
});

lcd.clear_screen(red16);
lcd.clear_screen(.{
.r = 31,
.g = 0,
.b = 0,
});
lcd.set_window(0, 0, 10, 10);

//Lcd.fill16(red16);
Expand Down
6 changes: 3 additions & 3 deletions src/badge/demos/neopixels.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
const cart = @import("cart-api");

pub export fn start() void {
pub export fn start() void {}

pub export fn update() void {
cart.neopixels.* = if (cart.controls.a) .{
.{ .r = 31, .g = 0, .b = 0 },
.{ .r = 31, .g = 0, .b = 0 },
Expand All @@ -15,5 +17,3 @@ pub export fn start() void {
.{ .r = 0, .g = 31, .b = 31 },
};
}

pub export fn update() void {}
33 changes: 33 additions & 0 deletions src/badge/demos/spi.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
const microzig = @import("microzig");
const board = microzig.board;
const hal = microzig.hal;
const clocks = hal.clocks;
const sercom = hal.sercom;

pub fn main() void {
clocks.mclk.set_apb_mask(.{ .SERCOM4 = .enabled });
clocks.gclk.enable_generator(.GCLK1, .DFLL, .{});

clocks.gclk.set_peripheral_clk_gen(.GCLK_SERCOM4_CORE, .GCLK1);

board.TFT_RST.set_dir(.out);
board.TFT_LITE.set_dir(.out);
board.TFT_DC.set_dir(.out);
board.TFT_CS.set_dir(.out);

board.TFT_SCK.set_mux(.C);
board.TFT_MOSI.set_mux(.C);

const spi = sercom.spi.Master.init(.SERCOM4, .{
.cpha = .LEADING_EDGE,
.cpol = .IDLE_LOW,
.dord = .MSB,
.dopo = .PAD2,
.ref_freq_hz = 48_000_000,
.baud_freq_hz = 4_000_000,
});

while (true) {
spi.write_blocking(0xAA);
}
}
1 change: 1 addition & 0 deletions src/board.zig
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const port = hal.port;

pub const NeopixelColor = @import("board/neopixel.zig").Color;
pub const Neopixels = @import("board/neopixel.zig").Group(5);
pub const Lcd = @import("board/lcd.zig").Lcd;

pub const TFT_RST = port.pin(.a, 0);
pub const TFT_LITE = port.pin(.a, 1);
Expand Down
65 changes: 29 additions & 36 deletions src/board/lcd.zig
Original file line number Diff line number Diff line change
Expand Up @@ -7,42 +7,31 @@ const port = hal.port;
const timer = hal.timer;
const clocks = hal.clocks;

pub const FrameBuffer = union(enum) {
bpp12: *[width][@divExact(height, 2)]Color12,
bpp16: *[width][height]Color16,
bpp24: *[width][height]Color24,
};
pub const Color12 = extern struct {
b0_g0: packed struct(u8) { b0: u4, g0: u4 },
r0_b1: packed struct(u8) { r0: u4, b1: u4 },
g1_r1: packed struct(u8) { g1: u4, r1: u4 },
};

pub const Color16 = packed struct(u16) { b: u5, g: u6, r: u5 };
pub const Color24 = extern struct { b: u8, g: u8, r: u8 };
pub const Rect = struct { x: u8, y: u8, width: u8, height: u8 };

pub const width = 160;
pub const height = 128;

pub const black16: Color16 = .{ .r = 0x00, .g = 0x00, .b = 0x00 };
pub const red16: Color16 = .{ .r = 0x1f, .g = 0x00, .b = 0x00 };
pub const green16: Color16 = .{ .r = 0x00, .g = 0x3f, .b = 0x00 };
pub const blue16: Color16 = .{ .r = 0x00, .g = 0x00, .b = 0x1f };
pub const white16: Color16 = .{ .r = 0x1f, .g = 0x3f, .b = 0x1f };

pub const black24: Color24 = .{ .r = 0x00, .g = 0x00, .b = 0x00 };
pub const red24: Color24 = .{ .r = 0xff, .g = 0x00, .b = 0x00 };
pub const green24: Color24 = .{ .r = 0x00, .g = 0xff, .b = 0x00 };
pub const blue24: Color24 = .{ .r = 0x00, .g = 0x00, .b = 0xff };
pub const white24: Color24 = .{ .r = 0xff, .g = 0xff, .b = 0xff };

pub const Lcd = struct {
spi: sercom.spi.Master,
pins: Pins,
inverted: bool = false,
fb: FrameBuffer,

pub const FrameBuffer = union(enum) {
bpp12: *[width][@divExact(height, 2)]Color12,
bpp16: *[width][height]Color16,
bpp24: *[width][height]Color24,
};

pub const Color12 = extern struct {
b0_g0: packed struct(u8) { b0: u4, g0: u4 },
r0_b1: packed struct(u8) { r0: u4, b1: u4 },
g1_r1: packed struct(u8) { g1: u4, r1: u4 },
};

pub const Color16 = packed struct(u16) { b: u5, g: u6, r: u5 };
pub const Color24 = extern struct { b: u8, g: u8, r: u8 };
pub const Rect = struct { x: u8, y: u8, width: u8, height: u8 };

pub const width = 160;
pub const height = 128;

pub const Pins = struct {
rst: port.Pin,
lite: port.Pin,
Expand Down Expand Up @@ -74,6 +63,10 @@ pub const Lcd = struct {
lcd.pins.sck.set_dir(.out);
lcd.pins.mosi.set_dir(.out);

// TODO: signal multiplexing
lcd.pins.mosi.set_mux(.C);
lcd.pins.sck.set_mux(.C);

lcd.pins.cs.write(.high);
lcd.pins.dc.write(.high);

Expand Down Expand Up @@ -150,9 +143,6 @@ pub const Lcd = struct {
lcd.send_cmd(ST7735.DISPON, &.{});
timer.delay_us(100 * std.time.us_per_ms);

// TODO: more
@memset(lcd.fb, 0);

return lcd;
}

Expand All @@ -178,7 +168,8 @@ pub const Lcd = struct {
lcd.send_cmd(switch (lcd.inverted) {
false => ST7735.INVOFF,
true => ST7735.INVON,
}, &.{}, 1);
}, &.{});
timer.delay_us(1);
}

pub fn send_color(lcd: Lcd, color: Color16, count: u32) void {
Expand Down Expand Up @@ -225,8 +216,10 @@ pub const Lcd = struct {
}

pub fn set_window(lcd: Lcd, x0: u8, y0: u8, x1: u8, y1: u8) void {
lcd.send_cmd(ST7735.CASET, &.{ 0x00, x0, 0x00, x1 }, 1);
lcd.send_cmd(ST7735.RASET, &.{ 0x00, y0, 0x00, y1 }, 1);
lcd.send_cmd(ST7735.CASET, &.{ 0x00, x0, 0x00, x1 });
timer.delay_us(1);
lcd.send_cmd(ST7735.RASET, &.{ 0x00, y0, 0x00, y1 });
timer.delay_us(1);
}

pub fn fill16(lcd: Lcd, color: Color16) void {
Expand Down
6 changes: 3 additions & 3 deletions src/cart.ld
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ MEMORY
bootloader (rx!w) : ORIGIN = 0x00000000, LENGTH = 0x00004000
runtime_flash (rx!w) : ORIGIN = 0x00004000, LENGTH = 0x0002C000
cart_flash (rx!w) : ORIGIN = 0x00030000, LENGTH = 0x00080000
cart_fixed (rw!x) : ORIGIN = 0x20000000, LENGTH = 0x000019A0
cart_ram (rw!x) : ORIGIN = 0x200019A0, LENGTH = 0x0000E660
runtime_ram (rw!x) : ORIGIN = 0x20010000, LENGTH = 0x00018000
cart_fixed (rw!x) : ORIGIN = 0x20000000, LENGTH = 0x0000A01E
cart_ram (rw!x) : ORIGIN = 0x2000A01E, LENGTH = 0x00015FE2
runtime_ram (rw!x) : ORIGIN = 0x20020000, LENGTH = 0x00008000
cart_stack (rw!x) : ORIGIN = 0x20028000, LENGTH = 0x00004000
runtime_stack (rw!x) : ORIGIN = 0x2002C000, LENGTH = 0x00004000
backup_ram (rw!x) : ORIGIN = 0x47000000, LENGTH = 0x00002000
Expand Down
Loading

0 comments on commit 8b134df

Please sign in to comment.