johngarchie / xmas-icetube

Alternative Ice Tube Clock firmware and hardware revision
43 stars 15 forks source link

Using 14 character IV-27 tube and two MAX6921's #6

Closed Barbouri closed 3 years ago

Barbouri commented 4 years ago

I have designed the hardware using two MAX6921 VFD drivers using the DOUT and DIN connections, and would like to clock 40 bits vs the usual 20 to utilize a second MAX6921 chip. Most of the code is very well documented except clocking of the 20 bits of data. IV-27-IceTubeClock10

johngarchie commented 4 years ago

It's bee a while since I looked at this code...

If I understand correctly, you'll need to expand the size of the intermediate bits array that gets sent to the maxim display chip in display.c. Since 5x8 = 40, you'll need 5 bytes and the line declaring bits should be: uint8_t bits[5] = {0, 0, 0, 0, 0}; Also the "for" loop that sends the data needs to be for(int8_t bitidx=4; bitidx >= 0; --bitidx) { to count back from the maximum index of 4 instead of a maximum index of 2. And bitflag will need to initially start at the very first bit: uint8_t bitflag = 0x80;

Below are the excerpts from display.c that actually do the work of sending the data to the maxim chip:

// bits to send MAX6921 (vfd driver chip)
uint8_t bits[3] = {0, 0, 0};

// <...bits[3] gets populated for transmission to driver chip...>

// send bits to the MAX6921 (vfd driver chip)

// Note that one system clock cycle is 1 / 8 MHz seconds or 125 ns.
// According to the MAX6921 datasheet, the minimum pulse-width on the
// MAX6921 CLK and LOAD pins need only be 90 ns and 55 ns,
// respectively.  The minimum period for CLK must be at least 200 ns.
// Therefore, no delays should be necessary in the code below.

// Also, the bits could be sent by SPI (they are in the origional
// Adafruit firmware), but I have found that doing so sometimes
// results in display flicker.
uint8_t bitflag = 0x08;
for(int8_t bitidx=2; bitidx >= 0; --bitidx) {
    uint8_t bitbyte = bits[bitidx];

    for(; bitflag; bitflag >>= 1) {
        if(bitbyte & bitflag) {
            // output high on MAX6921 DIN pin
            PORTB |= _BV(PB3);
        } else {
            // output low on MAX6921 DIN pin
            PORTB &= ~_BV(PB3);
        }

        // pulse MAX6921 CLK pin:  shifts DIN input into
        // the 20-bit shift register on rising edge
        PORTB |=  _BV(PB5);
        PORTB &= ~_BV(PB5);
    }

    bitflag = 0x80;
}

// pulse MAX6921 LOAD pin:  transfers shift
// register to latch when high; latches when low
PORTC |=  _BV(PC0);
PORTC &= ~_BV(PC0);
Barbouri commented 4 years ago

That worked. I modified one of the existing display formats to include the day of the week. IV-27-IceTubeClockDisp10

johngarchie commented 4 years ago

Wow! The other software changes you had to make to the code were non-trivial. I recall the display code as being the most difficult part of the design....

Your hardware is also beautifully done. Congratulations!