My Digidash project

Non-EMS Electronics related discussions and projects in here please.
User avatar
KW1252
LQFP112 - Up with the play
Posts: 166
Joined: Tue Jan 15, 2008 5:31 pm

My Digidash project

Post by KW1252 »

Hello!

One of the things I've been working on sporadically over last few years is a LED display digidash, built in the golden eighties style, but with a bit of modern technology thrown in. Here's how I wanted the thing to look:

Image

That's 518 LED's (and that's not counting the 16-segment display I forgot in that picture) plus one 8-character parallel-input ASCII display to control... no small task! The larger gauges have 96 LED's while the smaller have 32 and ten (or sixteen if the space permits). All bar graph displays are backed by 3x7 segment displays.

The basis for the unit is simple. A PIC18F458 has the required features, and an Allegro A6832, a 32-bit latching shift register, able to source 125mA, will be used as a display driver; it's actually a thermal printer head driver. I'll introduce the CPU now, and other bits later.

First, the input conditioning:

Image
(click for a bigger picture)

Active low inputs
First, there's grounding inputs for various warning lights on the dash, such as low oil or low fuel. The odd number-letter combination derives from Mazda connector code; I've made this to fit my own car(s) so using those codes help keeping things in order. The inputs are protected with diodes to prevent possible battery voltage from entering the circuit. The output signals are the moved forward in semi-intelligible lines, like Fuel for "No Fuel". 10k pull-up resistors limit the current on these.

Active high inputs
The signals for indicators and high-beam (yep, even these are driven through the system) are active high inputs instead. On these, the 14v battery voltage is brought down to logic levels with a voltage divider. While there's no voltage, the MOSFET remains non-conductive. As soon as the input line gets voltage, the MOSFET goes conductive, and the output signal drops to zero.

Charge light
Now, this one's a bit different. In the car it's actually used to charge the field coils for the alternator, with a diode pointing into the alternator. When the battery charged the alternator, current passes through the diode and the charge light is lit. Once the alternator start producing current, the voltage bias on the diode is reversed, there's no more current and the light goes out. Now here, the current limiting is arranged by high-power 2 ohm resistor, and the bias detection is arranged with a 741 Op-amp. While the current runs through the ballast resistor, the inverting input at the battery side sees a higher voltage, and the output swings toward VSS (or just ground here). Once the alternator gets into action, the non-inverting input sees higher voltage, and the output is swung to VCC. The current running through this circuit is rather substantial, so wide traces are needed on the board.

pulse inputs
These are for vehicle speed and RPM. On the vehicle speed, a pulse sender is used; these might be available commercially or DIY'ed somewhat trivially. There is a highh-pass filter, I don't expect further problems On the engine speed side, the circuit is filtered with high-pass filter set to about 670Hz. An optocoupler is used to isolate the coil signal from the rest of the circuit.

analog inputs
A simple voltage divider is used to source a voltage signal with these. (in older cars the analog sensors were used as rheostats to limit current, and the needle actuation was by a bending a bi-metal strip that was heated with the current!). I've included inputs past the OEM specification, as I know I'll be using these. The resistor values (in my case) are 30 ohms for fuel quantity and 15 for engine temp; these give a swing of roughly 1.7 - 4 volts, which is good enough. There is no input conditioner for a lambda sensor; for that I'm running a wire straight from the connector to the analog input. Anything I would come up with would be nowhere near enough JAW or LC-1 (that I have) to warrant the effort. The RControl is for remote control which would use an external resistor network with resistors staged in 2^n values for a simple one-wire communication.

EGT
I originally planned for using a 741 and software correction, but the better solution was simpler. A MAX6675 circuit is used to interface to the CPU.

With that done, here's the actual CPU:

Image

Power sources
The first regulator is an LM340 that's connected to continuous voltage (this might be changed into lower power unit.) This keeps the MCU and RS232 interface alive when the car is shut down. The second LM340 is used to drive logic circuits and analog voltage; it's connected to ignition voltage line, so the dash is only active when the ignition's on. Finally, the third regulator is a 5-amp LM 1084 regulator, and that's for driving LEDs. (32*125mA!) The filtering is done by regular polymer capacitors and a few big cans to compensate for voltage drops during crank. Running the input lines through a ferrite ring a few times and the Zeners should take care of spikes.

There's an interesting possibility here; using a gear-on-neutral switch input and the handbrake signal, it would be possible to make an MCU driven turbo timer function by connecting the switched and continuous power lines with a MOSFET. Just saying...

The microcontroller
The microcontroller of choice is PIC18F458. It's pretty well featured; in fact, everything except the parallel port is in use! (and even that is... in some manner) The I/O from top down is like this:
AN0, the ADC input port in use (actually I might turn these two around). Analog input is multiplexed for sixteen inputs. The latency is not an issue here really, it's more than acute enough for human input.
AN1, unused pin, routed to header
VREF- Ground reference for ADC. Probably an overkill but why not.
VREF+ VCC reference for ADC. Same as above.
T0CKL Timer 0 clock input. Used for vehicle speed clock input.
RA5 not used at this time.
OSC2 second input for external XTAL.
INT0 Speed measuring cycle completed
INT1 RPM measuring cycle completed
CANTX signal to CAN transceiver
CANRX signal from CAN transceiver
RB4 Odometer mode change and trip, also message acknowledge button if there's need for one.
PGM/PGC/PGD: ICSP pins. Routed to ICSP header.
T1CKL Timer1 clock, for RPM clock signal
RC1 routed to pin header
CCP PWM capture to detect dashboard light dimmer setting. Needed for ASCII display dimming (software driven)
SCK SPI serial clock
SDI Serial Data In (SPI bus)
SDO Serial data out (SPI bus)
DX Data sent to RS232 interface
RX Data received from RS232 interface
RD0-RD3 4-bit parallel signal sent to SPI address demuxer and analog multiplexer.
RD4 Speed clock circuit reset
RD5 RPM clock circuit reset
RE0 blanking signal for display driver
RE1 Address signal for display panels
RE2 Clear signal for display panel address memory.

VDD, VSS: as it says on the tin.

MCLR startup reset. Set to float, the MCU should power up fast enough for Power-on reset.
OSC1 external oscillator pin 1

The oscillator is 10MHz unit, the CPU is brought to 40MHz with high-speed PLL mode. This is to minimize any RFI.

Analog multiplexer
Chip used is DG406, which both TTL and CMOS compatible. For a larger number of possible analog inputs, the analog signals are all multiplexed with a 16-channel miutiplexer. The channel selection is by the same A0-A3 address signals that are used to assign the SPI devices. Because the enable pin does not require strobing, it is tied to VCC permanently.

SPI address controller
74154, a 4-bit demultiplexer is used for this task. The output is inversed, which follows the active low chip select method of SPI devices. Only three are in use for now, the rest are routed to header pins. This unit won't require strobing either, so here the both !enable -pins are tied to GND.

Parallel to serial shift registers
The caution light signals are converted into a 16-bit serial word with two 74165 8-bit shift registers. The procedure is as follows: as the SPI line "MUX1" goes low, the SPI clock signals start shifting the bits toward the output. Using inverting output, the active lows are converted into active highs; when later the registers are written into display driver, the bits are already in the right logic. After reading the information, the registers are filled with zeros because the input for MUX2 is tied to GND. If for some reason the signal input circuitry fails, it would light up the malfunctioning system. The DDRIVER SPI signal is tied to !LOAD pin; thus at every display write the data on the parallel inputs are loaded into the registers and no extra steps are needed.

canbus transceiver
MCP2551 minimum component CAN tranceiver. According to the example circuit in the datasheet, the CAN module can be used to connect the unit into a CAN bus if present. The system can have suthority on the bus, or be a listening node.

RS232 interface
The only module besides the MCU to receive uninterrupted power, the RS232 is intended for configuring the system with a PC. Circuit according to Maxim MAX232 datasheet.

Display driver
The display driver is used by SPI interface, and it has the same maximum data clock as the PIC, 10MHz. To get the number of LEDS lit up with 32 bits, the system first writes the address of the required cathode on the line, and as the flip-flops on the display end have registered the correct address, the double word for required leds are thrown in the bus. The A6832 is capable of sourcing 125mA per line, this is about the same as the forward current on non-restricted LED. There's online resistors in the bus just in case, though.

Speed and RPM clock circuitry
This circuit handles the timing of RPM and vehicle speed sensors. Instead of guessing the elapsed time with a program loop counter, this circuit will tell exactly (more or less) the period of RPM and speed signals. The crystal frequency is 32768kHz; this is the frequency used for real time clock circuits. The beauty of it is one second is exactly 2^15 cycles. The circuit for creating clock pulses from a crystal was nicked from Discover Circuits, they had a good one. The clock pulses are delivered into PIC pulse counter by an NPN transistor, which is tied to !Q output pin of a 74112 D-type Flip Flop. While the chip is in reset mode, the pin !Q is high, and the NPN is conductive. There's a 4.7M resistor to limit the base current. The pulses from the speed pickup and coil are put onto the B input pins on the 74360 decade counter. The output pin QA will create a square wave based on the pulse count; the pin is held high from 5 to 9. When the counter rolls over to zero, the output falls low. The flip-flop will detect this and trip; the pin !Q will go low, and the transistor will go non-conductive. Also the output Q will go high, and cause an interrupt on the PIC. Now the PIC will move the counter data into memory, reset the internal counter and send a reset pulse to the JK flip flop for a new batch of pulses. Since the speed difference is vast (40 MHz vs 32 kHz) the PIC should finish the task before the RTC has completed one cycle.

PIC pulse counter rollover happens after two seconds, so it's worth it to run a sanity check here. Let's say lowest reasonable engine RPM you'd expect of a car engine is 600 RPM. That's already 10Hz, and since the coil will fire twice per revolution, the decade counter will roll over every half second. For the vehicle speed, a good estimate is one revolution of the speedometer gauge per half a metre. Since the gauge can display speeds down to 1 unit per hour, it would be reasonable to expect it to do so. 1 km/h is 0.28 m/s, or a full rotation in just a bit under two seconds. For acceptable pulse rate there must be at least ten pulses per rotation.


Finally, the connectors:

Image

The connectors between the car and the CPU are Molex Microclasp connectors, very professional and affordable too (http://www.mouser.com/catalog/629/1185.pdf), unfortunately they're rated only for 3A per pin so they're bit too weak for ECU use (I need to multiply certain pins too).

The connection to gauge panels is via 40-pole ribbon cable, essentially similar to IDE cables. The current capacity is a big issue (With all 32 LEDs powered up, the load is four amps for four lines!). If it gets into a problem, a thicker external wire will be used for LED cathode wire. At first, metallic binder clips are used for heatsinks and the gauge pod will have a chassis fan. The ribbon cable will be quite hot in any case.

The connector for CANbus is standard DE9, and the RS232 is just a header on the circuit board. The idea is the actual connector will be placed somewhere you don't need to take the car apart to access it.

All expansion pin pads are left empty, and will thusmake a sort of veroboard zone on the PCB. There are zones for free CPU pins, SPI channels (with SDI and SDO pins conveniently near by too), analog channels, parallel to serial converter pins, and case connector pins. The number of vacant addresses on the display bus at the moment is eight, so with a led bar and 3x7 display forming an unit there's room for four extra gauges.

It's 5.05AM, I'm tired as hell, but I hope that covered the basics on the CPU in an understandable way. Comments are welcome. Next update will be about the gauge panels. It's a "bit" ambitious project, but I'm hopeful I'm able to build one in the future.
Last edited by KW1252 on Wed Nov 25, 2009 4:48 am, edited 1 time in total.
Reason: circuit design updated
User avatar
sry_not4sale
LQFP144 - On Top Of The Game
Posts: 568
Joined: Mon Mar 31, 2008 12:47 am
Location: New Zealand, land of the long white burnout
Contact:

Re: My Digidash project

Post by sry_not4sale »

WOW, this is awesome :D Will definately be watching this thread.
Owner / Builder: 1983 Mazda Cosmo 12at (1200cc 2-rotor turbo) coupe [SPASTK]
165hp @ 6psi standard - fastest production car in japan Oct 82
User avatar
jharvey
1N4001 - Signed up
Posts: 1607
Joined: Tue Jun 10, 2008 5:17 pm

Re: My Digidash project

Post by jharvey »

I'm in the same boat, certainly interesting stuff.

Some quick thoughts, have you see clear plexy when the back is painted black. Typicaly that comes out quite nice, and works for a nice finish on a budget.

I'm also curious if you plan to do this up in modules, such taht if someone wanted to make just one or two of the guages, they could.

Also also, is tha KICAD? Perhaps it's Eagle, that red boarder looks familure.
User avatar
KW1252
LQFP112 - Up with the play
Posts: 166
Joined: Tue Jan 15, 2008 5:31 pm

Re: My Digidash project

Post by KW1252 »

jharvey wrote:I'm in the same boat, certainly interesting stuff.

Some quick thoughts, have you see clear plexy when the back is painted black. Typicaly that comes out quite nice, and works for a nice finish on a budget.

I'm also curious if you plan to do this up in modules, such taht if someone wanted to make just one or two of the guages, they could.

Also also, is tha KICAD? Perhaps it's Eagle, that red boarder looks familure.
Good eye! I'm working here with eagle on this, I started with it and never got to transfer the design into Kicad. I will when I've finished the design though.

I was thinking about using smoked acrylic glass with a printed backlight film and an indiglo sheet, so the panel would be evenly black without power and the texts would light up with power on.

I need a bit more time with the gauge schematics, but I designed the gauges with certain flexibility. The addressing bus I've planned has 29 addresses and three multiplying lines, so the 3x7 and three segment LED bars only need one unique line on the bus. The gauge panels would be sandwiched design; on the bottom panel you have the transistors for the element common grounds and jumpers for addresses. I figured using an 8-bit flip-flop latch, and for the best compromise on flexibility vs. board price I decided to use two three-element displays and three single element displays. They would connect to the passive top board with LEDs through a polarized array of pin and socket headers.

Also, I just realized a much better way to feed speed signals into the CPU. Instead of feeding the sensor pulses directly into the processor, I'll use them to input clock crystal cycles. By sacrificing some PCB estate I'll get much more accurate results with a lot less programming.
User avatar
KW1252
LQFP112 - Up with the play
Posts: 166
Joined: Tue Jan 15, 2008 5:31 pm

Re: My Digidash project

Post by KW1252 »

Right. Got the decoder/base board for the displays figured out.

Image

First, the configuration pins. The display boards have five addressable display elements; to make use of them, they need to be tied with data pins on the bus. Referring to connection pin list, the INT_ADDx pins are air-wired to the corresponding pins using the pin header pads. Signals DATA30,DATA31 and DATA32 are always sub-address pins, and should never change. Thus they are connected permanently to the bus, without rewiring possibility.

The 74273 logic chip, "octal type D FlipFlop with reset" or 8-bit register in non-BigWord, is connected to the MOSFET gates to keep the right segment grounded while displaying data. It's a pretty straightforward process. Prior to writing the address, the !CLR pin cycles. This is will reset the output and turn off the display. It's more of a refinement, and used to keep unwanted LEDs from lighting up when feeding the new address. The address signal is then written on the display driver, EG in my setup 01000000 00000000 00000000 00000010 to address the second LED segment of the first LED bar gauge. Once this is written and send on the bus, the CLK pin cycles to latch the data on the register. At this moment the display driver output enable pin goes down to turn off the bus signals and prevent ghosting. The display data is now written on the display driver. Once the data is strobed in and latched on the bus, the output is enabled again, and now the register chip will keep the correct MOSFET conductive and the LEDs on the correct segment will light up.

Stuff happening with "ASCII !reset / !CE/!WR timer" is a bit more interesting. The ASCII chip needs a reset after power on. To enable this without running extra code or wires from the processor, an RC network is arranged so there should be at least 50ns of delay between the power signal and the reset going high. There's an inverting schmitt trigger to ensure a crisp switch-on the power line, and then another to bring to logic into right order. The !CE/!WR is a bit more complicated. When the data arrives, the inputs need to be in for a while before !CE (chip enable) goes low. To achieve that, there's an RC integrator circuit in the ST pin input that delays the !CE pin going low. After !CE goes low, !WE (write enable) needs to go low, and needs to stay there for at least for at least 100ns and go to high before !CE. When the !CE signal does go low, a second ST node tied to the CE signal outputs a high. This intermediary signal is taken into an RC differentiator circuit; the signal going into the final ST node will start to decay immediately after peaking to maximum value, and will make the ST cycle the !WE pin low for a set time. Exact values for the resistors and capacitors need to be SPICEd, but the circuit should work. The third RD circuit will ground the input line to the !CE ST node after at least 150ns, bringing the !CE pin back to high and completing the write cycle to ASCII chip. You'd think the engineers who designed this 50 buck component would've taken care of such trifle things on-chip, but ohhhhhh nnnnnnoooo... To prevent the wrong data from being written into ASCII display the FET on the data input is driven with the ASCII address signal.

Finally, the connection to the top panel is arranged with the 2x8 pin headers. The data signals are split into two different headers to make the top panel wiring even a bit easier, and the third header will handle the common cathode connections and signals for the ASCII chip. The headers will be arranged in polarized pattern so it wouldn't be possible to connect the top panels wrong way. Depending on components installed and left out this circuit would can handle these combination:

Two large gauges and two small gauges
One large gauges, two smaller gauges and a 3x7 segment displays
Two smaller gauges and two 3x7 segment displays

plus

Indicator light elements
16-segment display or an ASCII display.

I would like to consider there two a sort of non-altering options, but they too could be replaced with LED bars.
User avatar
KW1252
LQFP112 - Up with the play
Posts: 166
Joined: Tue Jan 15, 2008 5:31 pm

Re: My Digidash project

Post by KW1252 »

(I updated the first post concerningn the engine speed input, check it out if you missed it!)

And now for the visible results of the hard work, the actual gauge panel! I planned so there would be two panels with large displays, two panels with small displays, and a readout panel for the rest of the numeric data.

Image

First, the connector pins to the back plane decoder. The addresses are defined on the bottom plane, so the the connections between addresses and elements are set on the display board. The data pins however are doubled by 1x8 pin headers, to allow wiring the configurable elements (mostly the caution light LEDs)

There are five caution lights per panel in this design. It's more on an aesthetic decision, but also the keep traces manageable on the PCB. Of course one could redesign the board with 32 caution light LEDs though it might seem a bit crowded. (in fact, if the 32 signal lights turn out too little, it's possible to multiply the caution light address too). The lights have no preset options, and an be freely chosen by using jumper wires from the pin header hole to the right data bus header.

The ASCII display signals were already handled in the back plane, so it needs no special attention here. I did use the same line for the ASCII and the 16-segment display, so those two cannot be placed on the same board. This is based on the idea that the ASCII is more of an instrument for a speed gauge (as odometer), while the 16-segment is intended as a gear indicator (automatic or sequential or what ever the reason) and thus better suited for RPM panel.

16-segment display is wired up to segment G2 as a 7-segment display; the top and bottom horizontal bars are connected as to create a 14-segment display. The split top and bottom segments aren't necessary here, and pairing them will save some coding and wiring effort. This is one item I don't have present or predicted need for, but left it in anyway after pruning a lot of stuff from the design I saw as dead weight gor my use.

The 96-segment led bar display had a major change in the last few days. Initially it was just three 32-led segments thrown in back to back. The idea was to simplify the coding. However, after realizing a drive on the motorway would probably cause the thing to catch fire (at 120 km/h on gear the first third of both RPM and Speedo gauges would be always lit, meaning 4 amps of current going through the wire), I decided to mix the addresses and signals so that every third LED would be run by the same address. This also had a few other benefits; the wiring got MUCH simpler, and there's no change in LED light intensity going from one segment to another (one MOSFET sinking 4 amps will most definitely not have the same resistance as one draining a few hundred milliamps!). The only real drawback is the programming, but that shouldn't be TOO tough either. I'm not much of a programmer, but I hope I'll manage.

I figured the 96 segment LEDs would work pretty well in regular driving. For 240 km/h panel, each LED would mean exactly 2.5 km/h. For imperial units a good scale would be 0-120 mph with 1.25 increments. For traffic use, you'll want numbers divisible by five. as for the RPM, there's no good way to divide eg. 0-8000 RPM gauge with 96; the resolution would be 83.333333 and that's not really elegant at all. However, if I limited the top end to the redline of my engine, 7200, and kept the lowere end at 800, which is the idle speed of my engine given by the manual, the value per LED would be 75 RPM. For a screamer engine the resolution could be for example 100 RPM per led, so the scale could be for example 400-10000 RPM. I'll post a non-routed version of the actual layout I planned for the large gauge:

Image

It's in 150 DPI resolution so if use that if you want to print it out and test to see how it would size up in real life. BTW this is the reason why I didn't go for Kicad just yet, I don't know how to make a macro to place the LED's in perfect arcs in it.

There are still few display panels to design, but with hardware pretty much set, I think it would be worth it to start figuring out the programming next.
User avatar
jbelanger
LQFP144 - On Top Of The Game
Posts: 387
Joined: Sat Feb 23, 2008 8:58 pm
Contact:

Re: My Digidash project

Post by jbelanger »

I must say that while this looks like a very nice project, the way you go about getting the speed input seems way over the top. Simply use a CPU with timers and use an input capture channel. That's what it's used for. Choosing a CPU and then having to go through hoops to get it to do what you need to do is completely backwards to me.

You have some requirements so choose the CPU that meets those. It might be cool to be able to make it do what you want it to do despite of what it lacks but besides the nerd factor, I don't see the point.

Jean
User avatar
KW1252
LQFP112 - Up with the play
Posts: 166
Joined: Tue Jan 15, 2008 5:31 pm

Re: My Digidash project

Post by KW1252 »

Hmm... yeah, the system is excessive. Still a good workaround if you need more frequency counters than the system has capture modules :D It takes so much PCB estate I think I'll scrap that idea and go with the capture modules indeed. Fortunately, PIC18f458 has two CCP modules, normal and enhanced; had I needed a PWM output though, I would've been one short. The 32kHz clock is still a keeper, the capture module needs it for reliable operation, and it's the substitute for 10MHz resonator in low power mode. It can also provide exact display refresh interrupts.

Now the CPU needs another way to detect the dimmer setting though (the ASCII display brightness is controlled by software, not by PWM dimmer) so using an AD input with an RC comparator (basically the same circuit used as conditioner for other analog inputs) should do.
User avatar
KW1252
LQFP112 - Up with the play
Posts: 166
Joined: Tue Jan 15, 2008 5:31 pm

Re: My Digidash project

Post by KW1252 »

Image

Here's the logic updated; the RTC clock signal is supplied to T1OSI pin for accurate time base and alternative clock for low-power operations. RPM and speed signal are fed into the capture/compare pins.

Image

The dimmer signal is now measured with an ADC input, the signal is DIM and is fed to the analog multiplexer.
User avatar
KW1252
LQFP112 - Up with the play
Posts: 166
Joined: Tue Jan 15, 2008 5:31 pm

Re: My Digidash project

Post by KW1252 »

I realized there's a secondary Xtal driver built in the PIC µC, so I don't need external circuitry, just the 32.768kHz crystal and some capacitors. Anyway, the idea was to use the timer rollover interrupt to time the display write sequence, but the 32k oscillator is so slow I need to preset the timer value to 0xFF for fast enough timing... It doesn't seem reasonable, I need to find out if there's a better way. Anyway, LED timing is the most timing-critical task of the system (Well, the SPI bus is even more so, but that's handled by the hardware all the way)

While I was looking into programming (something I truly, genuinely SUCK at), I realized it was better to reserve the 4th address byte exclusively as sub-address byte (that is, digit/bar segment number) to keep programming more simple and efficient. Also, as there's now eight bits to use for addressing the element, the arbitrary LED bar / digit distinction can be eliminated, leaving a single address for each quantity. This vastly increases the number of available gauge addresses and flexibility, even if five bits are "sacrificed". I think it's now the way it should have been in the first place.

Also, I now think the idea to use three digit FETs connected to a common FET was plain stupid. A better idea is to use a number of logic AND gates (74HC08 for quad 2-input AND gate in CMOS technology) to drive the transistors. This saves a bunch of relatively expensive transistors and makes a more elegant solution altogether.

Now, about the programming. SPI and ADC modules are must have from the get-go. USART should be added when the basic stuff is working. CAN is pretty much an eventuality at this point. The interrupts should be prioritized, with display refresh at the very top spot. The display interrupt vector should be as short and simple as possible. To get the display information, the measuring subroutine in order has to have written the data on common registers the display routine will then read. The display interrupt handler should go roughly as follows in pseudocode:

Code: Select all

Display interrup handler

Set SPI_ADDRESS bits to display driver; The four GPIO pins connected to the 4-to-16 demuxer for SPI addressing
 
Read  ADDRESS_WIDTH; always four bytes, but let's make it a variable nonetheless)

Clear OUTPUT_ENABLE bit; GPIO pin connected to the A6832 enable output pin; shuts down the display pins)
Set DISPLAY_MEMORY_CLEAR bit;(this is a GPIO pin connected to the clear pin on the display flip-flop registers)
Wait until flip-flops are cleared; this takes some nanoseconds so a few NOP instructions probably work better than a full-blown wait loop
Clear DISPLAY_MEMORY_CLEAR bit; LED cathode registers are now reset and LEDs can display no data

ADDRESS LOOP
  ADDRESS_POINTER_OFFSET = ADDRESS_WIDTH-1
  Add ADDRESS POINTER_OFFSET to ADRESS_POINTER
  Read address data at ADDRESS_POINTER into WREG
  Write WREG into SPI; WREG: Work register.
  Decrease ADDRESS_WIDTH by one, skip next instruction if result is zero
Goto ADDRESS LOOP; a DO ... WHILE -loop, inputs all four bytes into the register.
Set latch bit (writes the serial stream into parallel output buffer in the A6832)
Wait until A6832 is finished writing the data into output
Set OUTPUT_ENABLE bit (turns on the A6832 output)
Wait until A6832 is finished
Set FLIPFLOP_CLOCK bit; this will make the chip register the data on it's input lines
Wait until Flipflop is finished
Clear FLIPFLOP_CLOCK bit
Wait until flip-flop is done
Clear OUTPUT_ENABLE bit sets A6832 output to 0's.
Clear LATCH bit; Enables A6832 to receive new data.

Read DATA_ITERATION_COUNT (1 except for the ASCII display which has 8.)
DATA ITERATION LOOP
  Read DATA_WIDTH (1-4 bytes) (Data can be under 32 bits, because garbage bits are ignored in the hardware)
  DATA WIDTH LOOP
    DATA_POINTER_OFFSET is DATA_WIDTH-1
    DATA_POINTER_OFFSET is DATA_POINTER_OFFSET * DATA_ITERATION_NUMBER (To access the correct register for each byte)
    Add DATA_POINTER_OFFSET into DATA_POINTER 
    Load data at DATA_POINTER into WREG (again, data is needed to load into work register)
    Write WREG onto SPI
   Decrease data_width by one, skip next instruction if result is zero
   Goto DATA WIDTH LOOP
Decrease DATA_ITERATION_COUNT by one, skip next instruction if result is zero; The only nonzero result should be when data is written into the ASCII display.
Goto DATA ITERATION LOOP
Set LATCH bit; latches data into parallel outputs
Wait
Set OUTPUT_ENABLE bit; LEDs light up; we're done for now, next is housekeeping duties before returning to main code

Reset watchdog; good thing to do every once and awhile to keep the unit from resetting itself
Decrease DISPLAY_SEQUENCE register by one: this is to let the main program know what's it's supposed to do next
Write 0xFF to timer register; this is to set another interrupt at the next RTC clock cycle.
Reset INTERRUPT bit (interrupts won't reset by themselves after exiting the interrupt routine)

Return from interrupt
The code might need a bit more work with WREG use, but I think I got the logic right.
Post Reply