A lot has happened since the last project log, specifically I got the firmware into a usable state, wrote some simple scripts for setting the clock, and printed the top cover. This is what it looks like right now:
In addition to getting the firmware and software in a working state, I also had to hunt down two hardware bugs in order to get the hardware to a point where I'm comfortable calling it done.
As such I'll split up this discussion over a couple of project logs. This log will discuss the firmware and software, and the next log will discuss the hardware bugs I had to fix. I'll also try to write a log discussing the case design since that's changed a little as well.
on to the firmware!
Firmware for this project lives here: https://github.com/ZakSN/z_1_rtc/tree/master/firmware/avr
The clock's firmware has a couple of important functions:
- allow a user (via a host computer) to put a new epoch into the fpga's epoch register
- retrieve the current fpga epoch
- calculate the current time from the fpga epoch
- format and display the current time on the device display
additionally the firmware retains a simple mode call 'cal mode' where the fpga epoch register is not reset, and the clock simply broadcasts the current fpga epoch (starting from 0x0 at reset) over uart and to the display.
Ultimately full detail will only come from reading the code in the repo above, but here's a flow chart that explains what the clock's firmware does:
Basically, 'cal mode' allows me to produce calibration graphs as seen in this project log, and !'cal mode' lets the clock act like a clock.
In !'cal mode' the clock needs some setup information, specifically:
- we need to know the current unix epoch (e.g. what time is it?)
- we need to know the current timezone (e.g. how many hours offset from the unix epoch)
- and we need to know how to format the time for the display
all of this information is provided to the clock via a simple python script that basically just checks the computer's clock for NTP time information and then blasts bits at the clock over UART.
Internally the clock uses the avr gcc `time.h` lib to do time calculation. This works pretty well, but has a couple of quirks due to running in an embedded environment:
- avr gcc uses a different (smaller) epoch, so I have to convert the FPGA (64 bit unix) epoch to an avr epoch
- daylight savings time/timezones don't work (the timezone database is too huge for embedded apps and so the avr gcc implementation of `time.h` just doesn't deal with timezones)
to get around the timezone thing I just embed the current timezone in the display format. This at least lets the clock display the current timezone as e.g. 'EDT (UTC -4)', but it means that the clock needs to be reset when ever daylight savings time changes occur, which while not ideal is acceptable.
I think that's everything I want to say about the firmware/software for the clock. As usual its probably more informative to just go and read the code in the repo if you really care about how this thing works for some reason...