Rewrote display pinout to match patched PCB

This commit is contained in:
Gregor Riepl 2021-04-21 23:23:07 +02:00
parent c5b29bdee2
commit fe7106cfa1
2 changed files with 141 additions and 17 deletions

View file

@ -2,63 +2,116 @@
#include <util/delay.h>
#include "display.h"
// maximum wait time until busy should be deasserted
// bail out if it takes longer than that
// unit: 10us (roughly)
// range: 0..255
#define DISPLAY_WAIT_MAX_10US 100
void display_init() {
// PC5, PC6, PC7: output (VFD RS, RW, E), RS=0, RW=1, E=1
// PD: output (VFD DB) - can be switched to input (pullup not needed)
// PB0, PB1, PB7, PD0, PD1, PD5, PD6, PD7: output (VFD DB) - can be switched to input (pullup not needed)
PORTB &= ~(_BV(PB0) | _BV(PB1) | _BV(PB7));
DDRB |= _BV(PB0) | _BV(PB1) | _BV(PB7);
PORTC |= _BV(PC6) | _BV(PC7);
DDRC |= _BV(PC5) | _BV(PC6) | _BV(PC7);
PORTD = 0x00;
DDRD = 0xff;
PORTD &= ~(_BV(PD0) | _BV(PD1) | _BV(PD5) | _BV(PD6) | _BV(PD7));
DDRD |= _BV(PD0) | _BV(PD1) | _BV(PD5) | _BV(PD6) | _BV(PD7);
display_wait_ready();
// initialize display: 8 bit, 2 lines, 50% brightness
display_write_ir(0x3c);
display_wait_ready();
}
uint8_t display_read_ir() {
// switch PD to input
DDRD = 0x00;
DDRB &= ~(_BV(PB0) | _BV(PB1) | _BV(PB7));
DDRD &= ~(_BV(PD0) | _BV(PD1) | _BV(PD5) | _BV(PD6) | _BV(PD7));
// E=0 (enable/clock) RS=0 (IR) RW=1 (read)
PORTC = (PORTC & ~(_BV(PC5) | _BV(PC7))) | _BV(PC6);
_delay_us(0.23);
// E=1 (enable/clock)
PORTC |= _BV(PC7);
_delay_us(0.16);
uint8_t data = PIND;
// read inputs
uint8_t datab = PINB;
uint8_t datad = PIND;
_delay_us(0.23 - 0.16);
// E=0 (enable/clock)
PORTC &= ~_BV(PC7);
_delay_us(0.01);
// reset to idle
// reset to idle / output
PORTC = _BV(PC6) | _BV(PC7);
DDRD = 0xff;
DDRB |= _BV(PB0) | _BV(PB1) | _BV(PB7);
DDRD |= _BV(PD0) | _BV(PD1) | _BV(PD5) | _BV(PD6) | _BV(PD7);
// reassemble data
uint8_t data = 0;
data |= (datad & _BV(PD0)) ? _BV(0) : 0;
data |= (datad & _BV(PD1)) ? _BV(1) : 0;
data |= (datad & _BV(PD5)) ? _BV(5) : 0;
data |= (datad & _BV(PD6)) ? _BV(6) : 0;
data |= (datad & _BV(PD7)) ? _BV(7) : 0;
data |= (datab & _BV(PB0)) ? _BV(2) : 0;
data |= (datab & _BV(PB1)) ? _BV(3) : 0;
data |= (datab & _BV(PB7)) ? _BV(4) : 0;
return data;
}
uint8_t display_read_dr() {
// switch PD to input
DDRD = 0x00;
DDRB &= ~(_BV(PB0) | _BV(PB1) | _BV(PB7));
DDRD &= ~(_BV(PD0) | _BV(PD1) | _BV(PD5) | _BV(PD6) | _BV(PD7));
// E=0 (enable/clock) RS=1 (IR) RW=1 (read)
PORTC = (PORTC & ~_BV(PC7)) | (_BV(PC5) | _BV(PC6));
_delay_us(0.23);
// E=1 (enable/clock)
PORTC |= _BV(PC7);
_delay_us(0.16);
uint8_t data = PIND;
// read inputs
uint8_t datab = PINB;
uint8_t datad = PIND;
_delay_us(0.23 - 0.16);
// E=0 (enable/clock)
PORTC &= ~_BV(PC7);
_delay_us(0.01);
// reset to idle
// reset to idle / output
PORTC = _BV(PC6) | _BV(PC7);
DDRD = 0xff;
DDRB |= _BV(PB0) | _BV(PB1) | _BV(PB7);
DDRD |= _BV(PD0) | _BV(PD1) | _BV(PD5) | _BV(PD6) | _BV(PD7);
// reassemble data
uint8_t data = 0;
data |= (datad & _BV(PD0)) ? _BV(0) : 0;
data |= (datad & _BV(PD1)) ? _BV(1) : 0;
data |= (datad & _BV(PD5)) ? _BV(5) : 0;
data |= (datad & _BV(PD6)) ? _BV(6) : 0;
data |= (datad & _BV(PD7)) ? _BV(7) : 0;
data |= (datab & _BV(PB0)) ? _BV(2) : 0;
data |= (datab & _BV(PB1)) ? _BV(3) : 0;
data |= (datab & _BV(PB7)) ? _BV(4) : 0;
return data;
}
void display_write_ir(uint8_t data) {
// reassemble data
uint8_t datab = 0;
uint8_t datad = 0;
datad |= (data & _BV(0)) ? _BV(PD0) : 0;
datad |= (data & _BV(1)) ? _BV(PD1) : 0;
datad |= (data & _BV(5)) ? _BV(PD5) : 0;
datad |= (data & _BV(6)) ? _BV(PD6) : 0;
datad |= (data & _BV(7)) ? _BV(PD7) : 0;
datab |= (data & _BV(2)) ? _BV(PB0) : 0;
datab |= (data & _BV(3)) ? _BV(PB1) : 0;
datab |= (data & _BV(4)) ? _BV(PB7) : 0;
// E=0 (enable/clock) RS=0 (IR) RW=0 (write)
PORTC &= ~(_BV(PC5) | _BV(PC6) | _BV(PC7));
_delay_us(0.23);
// E=1 (enable/clock)
PORTC |= _BV(PC7);
// data
PORTD = data;
// send data
PORTB = datab;
PORTD = datad;
_delay_us(0.23);
// E=0 (enable/clock)
PORTC &= ~_BV(PC7);
@ -69,13 +122,25 @@ void display_write_ir(uint8_t data) {
}
void display_write_dr(uint8_t data) {
// reassemble data
uint8_t datab = 0;
uint8_t datad = 0;
datad |= (data & _BV(0)) ? _BV(PD0) : 0;
datad |= (data & _BV(1)) ? _BV(PD1) : 0;
datad |= (data & _BV(5)) ? _BV(PD5) : 0;
datad |= (data & _BV(6)) ? _BV(PD6) : 0;
datad |= (data & _BV(7)) ? _BV(PD7) : 0;
datab |= (data & _BV(2)) ? _BV(PB0) : 0;
datab |= (data & _BV(3)) ? _BV(PB1) : 0;
datab |= (data & _BV(4)) ? _BV(PB7) : 0;
// E=0 (enable/clock) RS=1 (IR) RW=0 (write)
PORTC = (PORTC & ~(_BV(PC6) | _BV(PC7))) | _BV(PC5);
_delay_us(0.23);
// E=1 (enable/clock)
PORTC |= _BV(PC7);
// data
PORTD = data;
// send data
PORTB = datab;
PORTD = datad;
_delay_us(0.23);
// E=0 (enable/clock)
PORTC &= ~_BV(PC7);
@ -87,9 +152,14 @@ void display_write_dr(uint8_t data) {
bool display_wait_ready() {
// FIXME hack to avoid read mode
_delay_ms(1);
return true;
// FIXME
// if the busy flag never goes high, we'll run into a deadlock here.
// let's put a deadline on the wait loop.
for (uint8_t i = 0; i < 100; i++) {
for (uint8_t i = 0; i < DISPLAY_WAIT_MAX_10US; i++) {
// read_ir() takes about 500ns
if (display_read_ir() & _BV(7)) return true;
// wait 10us until the next status read

View file

@ -14,7 +14,7 @@ static void init();
static void send_status();
static void loop();
/* I/O map:
/* I/O map version 1 (non-working):
PB2 BUTTON0
PB3 BUTTON1
PB4 BUTTON2
@ -38,6 +38,60 @@ static void loop();
PD7 VFDDB7
*/
/* I/O map version 1 (patched):
PB0 VFDDB2
PB1 VFDDB3
PB2 BUTTON0
PB3 BUTTON1
PB4 BUTTON2
PB5 BUTTON3
PB6 BUTTON4
PB7 VFDDB4
PC0 BUTTON5
PC1 BUTTON6
PC2 CANTX
PC3 CANRX
PC4 BUTTON7
PC5 VFDRS
PC6 VFDRW
PC7 VFDE
PD0 VFDDB0
PD1 VFDDB1
PD2 -
PD3 -
PD4 -
PD5 VFDDB5
PD6 VFDDB6
PD7 VFDDB7
*/
/* I/O map version 2:
PB0 VFDDB0
PB1 VFDDB1
PB2 VFDDB2
PB3 VFDDB3
PB4 VFDDB4
PB5 VFDDB5
PB6 VFDDB6
PB7 VFDDB7
PC0 BUTTON5
PC1 BUTTON7
PC2 CANTX
PC3 CANRX
PC4 BUTTON6
PC5 VFDRS
PC6 VFDRW
PC7 VFDE
PD0 BUTTON0
PD1 BUTTON1
PD2 -
PD3 -
PD4 -
PD5 BUTTON2
PD6 BUTTON3
PD7 BUTTON4
*/
static void init() {
// initialize buttons
button_init();