Hugely refactor the display

i2c
Savanni D'Gerinel 2022-06-26 12:40:04 -04:00
parent 5ad6fb8412
commit 65caaa0a50
6 changed files with 217 additions and 75 deletions

155
display/display.c Normal file
View File

@ -0,0 +1,155 @@
#include <stdlib.h>
#include <display.h>
#include <util/delay.h>
#include <base.h>
/*
struct CHAR {
char c;
uint8_t bits;
};
struct CHAR CHARSET[96] = {
{ .c = ' ', .bits = 0x20 },
{ .c = '!', .bits = 0x21 },
{ .c = '"', .bits = 0x22 },
{ .c = '#', .bits = 0x23 },
{ .c = '$', .bits = 0x24 },
{ .c = '%', .bits = 0x25 },
{ .c = '&', .bits = 0x26 },
{ .c = ''', .bits = 0x27 },
{ .c = '(', .bits = 0x28 },
{ .c = ')', .bits = 0x29 },
{ .c = '*', .bits = 0x2a },
{ .c = '+', .bits = 0x2b },
{ .c = ',', .bits = 0x2c },
{ .c = '-', .bits = 0x2d },
{ .c = '.', .bits = 0x2e },
{ .c = '/', .bits = 0x2f },
{ .c = '0', .bits = 0x30 },
{ .c = '1', .bits = 0x31 },
{ .c = '2', .bits = 0x32 },
{ .c = '3', .bits = 0x33 },
{ .c = '4', .bits = 0x34 },
{ .c = '5', .bits = 0x35 },
{ .c = '6', .bits = 0x36 },
{ .c = '7', .bits = 0x37 },
{ .c = '8', .bits = 0x38 },
{ .c = '9', .bits = 0x39 },
{ .c = ':', .bits = 0x3a },
{ .c = ';', .bits = 0x3b },
{ .c = '<', .bits = 0x3c },
{ .c = '=', .bits = 0x3d },
{ .c = '>', .bits = 0x3e },
{ .c = '?', .bits = 0x3f },
{ .c = '@', .bits = 0x40 },
{ .c = 'A', .bits = 0x41 },
{ .c = 'B', .bits = 0x42 },
{ .c = 'C', .bits = 0x43 },
{ .c = 'D', .bits = 0x44 },
{ .c = 'E', .bits = 0x45 },
{ .c = 'F', .bits = 0x46 },
{ .c = 'G', .bits = 0x47 },
{ .c = 'H', .bits = 0x48 },
{ .c = 'I', .bits = 0x49 },
{ .c = 'J', .bits = 0x4a },
{ .c = 'K', .bits = 0x4b },
{ .c = 'L', .bits = 0x4c },
{ .c = 'M', .bits = 0x4d },
{ .c = 'N', .bits = 0x4e },
{ .c = 'O', .bits = 0x4f },
{ .c = 'P', .bits = 0x50 },
{ .c = 'Q', .bits = 0x51 },
{ .c = 'R', .bits = 0x52 },
{ .c = 'S', .bits = 0x53 },
{ .c = 'T', .bits = 0x54 },
{ .c = 'U', .bits = 0x55 },
{ .c = 'V', .bits = 0x56 },
{ .c = 'W', .bits = 0x57 },
{ .c = 'X', .bits = 0x58 },
{ .c = 'Y', .bits = 0x59 },
{ .c = 'Z', .bits = 0x5a },
{ .c = '[', .bits = 0x5b },
{ .c = ' ', .bits = 0x5c },
{ .c = ']', .bits = 0x5d },
{ .c = '^', .bits = 0x5e },
{ .c = '_', .bits = 0x5f },
{ .c = '`', .bits = 0x60 },
{ .c = 'a', .bits = 0x61 },
{ .c = 'b', .bits = 0x62 },
{ .c = 'c', .bits = 0x63 },
{ .c = 'd', .bits = 0x64 },
{ .c = 'e', .bits = 0x65 },
{ .c = 'f', .bits = 0x66 },
{ .c = 'g', .bits = 0x67 },
{ .c = 'h', .bits = 0x68 },
{ .c = 'i', .bits = 0x69 },
{ .c = 'j', .bits = 0x6a },
{ .c = 'k', .bits = 0x6b },
{ .c = 'l', .bits = 0x6c },
{ .c = 'm', .bits = 0x6d },
{ .c = 'n', .bits = 0x6e },
{ .c = 'o', .bits = 0x6f },
{ .c = 'p', .bits = 0 },
{ .c = 'q', .bits = 0 },
{ .c = 'r', .bits = 0 },
{ .c = 's', .bits = 0 },
{ .c = 't', .bits = 0 },
{ .c = 'u', .bits = 0 },
{ .c = 'v', .bits = 0 },
{ .c = 'w', .bits = 0 },
{ .c = 'x', .bits = 0 },
{ .c = 'y', .bits = 0 },
{ .c = 'z', .bits = 0 },
{ .c = ' ', .bits = 0 },
{ .c = ' ', .bits = 0 },
{ .c = ' ', .bits = 0 },
{ .c = ' ', .bits = 0 },
{ .c = ' ', .bits = 0 },
};
*/
void display_strobe_line(gpio_t *line) {
set_line(line);
_delay_us(100);
clear_line(line);
_delay_us(100);
}
void write_instruction(display_t *disp, uint8_t bitcode) {
clear_line(&disp->register_select);
sr_send_msb(&disp->reg, bitcode);
_delay_ms(1);
display_strobe_line(&disp->enable);
}
void write_char(display_t *disp, uint8_t bitcode) {
set_line(&disp->register_select);
sr_send_msb(&disp->reg, bitcode);
_delay_ms(1);
display_strobe_line(&disp->enable);
}
void display_init(display_t *disp) {
sr_initialize(&disp->reg);
set_line_direction(&disp->register_select, LINE_OUT);
set_line_direction(&disp->enable, LINE_OUT);
write_instruction(disp, 0b00111100);
}
void display_clear(display_t *disp) {
write_instruction(disp, 0x01);
write_instruction(disp, 0x02);
}
void display_enable(display_t *disp) {
write_instruction(disp, 0x0e);
}
void display_write_message(display_t *disp, const char *msg) {
for (size_t i = 0; msg[i] != 0; i++) {
write_char(disp, msg[i]);
}
}

50
display/display.h Normal file
View File

@ -0,0 +1,50 @@
/* This library covers a five-wire diagnostic display board.
*
* Hardware:
* 74HC595 shift register
* Adafruit HD44780 LCD
*
* Input pins:
* SDI -- Serial data in. This leads to the 74HC595, pin 14 (A).
* CLK -- Clock pulse. One bit will be shifted into the device on each rising
* edge. This leads to the 74HC595, pin 11 (Shift Clock).
* LS -- Latch pulse. All data in the shift register will be sent to the
* output on a rising edge. This leads to the 74HC595, pin 12 (Latch Clock);
* RS -- Register select. 0 to write an instruction to the display, 1 to write
* data to the display.
* E -- Enable. This tells the display to read the data. The display will get
* the data on the shift register outputs, so be sure to send LS before
* sending E.
*
* 74HC595 -> HD44780
* Qa -> D0
* Qb -> D1
* Qc -> D2
* Qd -> D3
* Qe -> D4
* Qf -> D5
* Qg -> D6
* Qh -> D7
*/
#ifndef __DISPLAY_H__
#define __DISPLAY_H__
#include <shift_register.h>
typedef struct DISPLAY {
shift_register_t reg;
gpio_t register_select;
gpio_t enable;
} display_t;
void display_init(display_t *);
void display_clear(display_t *);
void display_enable(display_t *);
void display_write_message(display_t *, const char *);
#endif

View File

@ -106,7 +106,7 @@
name = "lcd";
src = ./.;
includes = [ "base" "shift_register" "spi" ];
includes = [ "base" "display" "shift_register" "spi" ];
MCU = "atmega32u4";
CHIP_SELECT = "AVR_ATmega32u4";
@ -117,9 +117,10 @@
buildPhase = ''
${avr.gcc}/bin/avr-gcc ${CFLAGS} ${INCLUDE_DIRS} -o base.o -c ${src}/base/base.c
${avr.gcc}/bin/avr-gcc ${CFLAGS} ${INCLUDE_DIRS} -o spi.o -c ${src}/spi/spi.c
${avr.gcc}/bin/avr-gcc ${CFLAGS} ${INCLUDE_DIRS} -o reg.o -c ${src}/shift_register/reg.c
${avr.gcc}/bin/avr-gcc ${CFLAGS} ${INCLUDE_DIRS} -o reg.o -c ${src}/shift_register/shift_register.c
${avr.gcc}/bin/avr-gcc ${CFLAGS} ${INCLUDE_DIRS} -o display.o -c ${src}/display/display.c
${avr.gcc}/bin/avr-gcc ${CFLAGS} ${INCLUDE_DIRS} -o main.o -c ${src}/lcd/main.c
${avr.gcc}/bin/avr-gcc ${CFLAGS} -o main.elf main.o reg.o spi.o base.o
${avr.gcc}/bin/avr-gcc ${CFLAGS} -o main.elf main.o display.o reg.o spi.o base.o
$OBJCOPY -O ihex main.elf main.hex
'';
installPhase = ''

View File

@ -2,76 +2,11 @@
#include <util/delay.h>
#include <base.h>
#include <spi.h>
#include <reg.h>
typedef struct HD44780 {
shift_register_t reg;
gpio_t register_select;
gpio_t enable;
} hd44780_t;
void strobe_line(gpio_t *line) {
set_line(line);
_delay_ms(1);
clear_line(line);
_delay_ms(1);
}
void hd44780_init(hd44780_t *disp) {
spi_initialize(disp);
set_line_direction(&disp->register_select, LINE_OUT);
set_line_direction(&disp->enable, LINE_OUT);
send_msb(&disp->reg, 0b00111100);
}
void hd44780_clear(hd44780_t *disp) {
clear_line(&disp->register_select);
send_msb(&disp->reg, 0b00000001);
_delay_ms(1);
strobe_line(&disp->enable);
send_msb(&disp->reg, 0b00000010);
_delay_ms(1);
strobe_line(&disp->enable);
}
void hd44780_display(hd44780_t *disp) {
clear_line(&disp->register_select);
send_msb(&disp->reg, 0b00001110);
_delay_ms(1);
strobe_line(&disp->enable);
}
void hd44780_write_char(hd44780_t *disp, uint8_t bitcode) {
set_line(&disp->register_select);
send_msb(&disp->reg, bitcode);
strobe_line(&disp->enable);
}
void hd44780_write(hd44780_t *disp) {
set_line(&disp->register_select);
hd44780_write_char(disp, 0b01001000);
hd44780_write_char(disp, 0b01000101);
hd44780_write_char(disp, 0b01001100);
hd44780_write_char(disp, 0b01001100);
hd44780_write_char(disp, 0b01001111);
hd44780_write_char(disp, 0b00101100);
hd44780_write_char(disp, 0b00100000);
hd44780_write_char(disp, 0b01001101);
hd44780_write_char(disp, 0b01011001);
hd44780_write_char(disp, 0b00100000);
hd44780_write_char(disp, 0b01000010);
hd44780_write_char(disp, 0b01000001);
hd44780_write_char(disp, 0b01010100);
}
#include <shift_register.h>
#include <display.h>
int main(void) {
hd44780_t display = {
display_t display = {
.reg = {
.output = { .ddr = &DDRB, .port = &PORTB, .pin = &PINB, .addr = 5 },
.latch_clock = { .ddr = &DDRB, .port = &PORTB, .pin = &PINB, .addr = 6 },
@ -85,13 +20,14 @@ int main(void) {
set_line_direction(&light, LINE_OUT);
clear_line(&light);
hd44780_init(&display);
display_init(&display);
hd44780_clear(&display);
display_clear(&display);
_delay_ms(500);
hd44780_write(&display);
hd44780_display(&display);
const char msg[] = "Hello, my bat";
display_write_message(&display, msg);
display_enable(&display);
set_line(&light);