All electronics exists to convert electricity into (mostly) heat. It just happens to do something useful along the way. The progression on the design so far has been to consider digital issues first (make the circuit work at all), then mechanical (fit to the case), and now is down to thermal - what to do with the heat.
Now that I've started to run the prototypes in the target case I have some idea of the temp of the board, components, and how the case feels. And it's warmer than I want.
This is somewhat of an issue since the stability of the clock is related to the temperature. If a crystal has a stability of, say, 20ppm, it is always stated with a temperature range at which that holds true. For (most) cheap crystals that's 25 degrees. As it gets colder or warmer it gets worse.
During the design some of this was taken into consideration. Firstly, since we are aligning ourselves to GPS sources, the stability is less critical: we have a stable external reference less influenced by our local temperature. It does mean we're limiting how long we can run without GPS sources (it's currently in the "minutes" range, which is not far off what a $4k device does and this costs nothing like that). This is currently implemented in a coarse-grain way, we just adjust our internal clock being fed by the DS3234 output.
Secondly, the decision to use the DS3234 RTC instead of a watch crystal was driven by the fact it's a Temperature Compensated Crystal Oscillator, that is it has a temp sensor and can tune the crystal inside it to compensate for the local temperature. Over the range 0 to 40 degrees it claims 2ppm out of the box, and 3.5ppm between -40 and +85. So even with a lot of heat it's still significantly more stable than a cheap watch crystal.
There are some things I haven't implemented yet which I'll now need to consider.
The DS3234 exposes it's tuning interface, and the datasheet mentions that with an external trusted reference (oh hai GPS) you can feed it extra offset information to further compensate for both aging and to obtain finer precision (you get about +/- 0.1ppm of control). I'll need to add an extra step after GPS lock to tune the DS3234 against the GPS pulses, and retune it from time to time.
Once the case is closed up properly (it's not fully closed right now), it may need some holes cut in specific places to improve natural convection. Likely places will be right under the (not very efficient, therefore a source of a lot of heat) LDO regulator. It also will likely need holes in both endplates to ensure any air that is around can get into the case.
We're also running the main MCU at full clock rate without any regard for clocking down based on demand. While it's a lot of work to implement, I could look at power management for the MCU by implementing dynamic clocking.
Those things can be done without changing any aspect of the board design. But there's board design changes I'm looking at as well.
The 1.5 board now has space for a 16x16x4mm fan in one endplate, with PWM control so we can run it as slow as possible. Like many things, it's there if I finally decide it needs a fan, but it's something I'm going to try to avoid. The fan is 3.3V so doesn't need it's own LDO (since a lot of fans are 12V, fewer 5V), but should probably have a transistor between the MCU and it to source as little current from the MCU as possible.
The LDO has also been re-arranged to make it easier to attach a small heatsink to. Ideally this will move heat away from going into the board so much, as I suspect that's what is really causing the reported temps to be as high as they are. It might only work best with real airflow over it, but we'll see how that goes.
There's also some evidence the Ethernet section is drawing more power than it should do, as a result of not quite getting the front-end right. There's fixes for that in 1.5 as well.
All in all, it feels like I'm getting into the real tail end of the project now to be considering these sorts of issues. There's less making-it-work-at-all, and more making-it-awesome.