From fe7106cfa12821dd06b36490b2525f44cf27179c Mon Sep 17 00:00:00 2001 From: Gregor Riepl Date: Wed, 21 Apr 2021 23:23:07 +0200 Subject: [PATCH] Rewrote display pinout to match patched PCB --- display/firmware/display.c | 102 +++++++++++++++++++++++++++++++------ display/firmware/main.c | 56 +++++++++++++++++++- 2 files changed, 141 insertions(+), 17 deletions(-) diff --git a/display/firmware/display.c b/display/firmware/display.c index 2b5f529..bbcd942 100644 --- a/display/firmware/display.c +++ b/display/firmware/display.c @@ -2,63 +2,116 @@ #include #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 diff --git a/display/firmware/main.c b/display/firmware/main.c index f622ed5..9b7ef12 100644 --- a/display/firmware/main.c +++ b/display/firmware/main.c @@ -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();