-
Notifications
You must be signed in to change notification settings - Fork 2
Description
Hi,
Thanks again for working on this super-cool project ;)
While the Minimal UART Computer 3 still maintains the retro feeling to it, it seems to be shifting its focus to educational purposes. With that in mind, I propose some changes to it which will make builder's and user's life easier but otherwise DON'T require ANY architecture changes. The number and kind of chips used also remains exactly the same. The only changes are in wiring (plus some pull-up, pull-down and current-limiting resistors) and in the ATmega328P clock module firmware.
- Clock booting [change in ATmega328P firmware only]
I propose to introduce an optional timeout before CPU_OSC and UART_OSC start being output. This would be signalled to the user with rapid flashing of one LED and during this time the user has an option to press a button to enter clock selection mode before the clock actually starts. Then each press of the other button cycles to the next clock mode, signalled with another LED blinking a corresponding number of times (e.g. 1 blink for 8MHz, 2 blinks for 1MHz, ..., 8 blinks for 1Hz and one long blink for manual single step). When the user is satisfied with the choice they press the first button to leave the clock booting mode. The purpose of this change is to be able to run with a selected clock speed from the very first clock cycle. With the educational focus in mind being able to e.g. single step from the very first instruction executed by the Minimal is valuable. When the operating system is running, it might not be the most exciting experience (the OS loading itself in a loop repeated hundreds of times), but again, with education in mind there could be a dedicated bare metal program flashed into the SSD instead of the OS image. If the user does not press the first button to start with, after the configured timeout (later I will expand on such configuration) the Minimal boots as usual.
- In-circuit programming of the ATmega328P [wiring changes required]
I propose adding a 6-pin header known from Arduino to allow in-circuit programming of the ATmega328P. This requires wiring PB3, PB4, PB5, PC6 and GND to the header. While the ATmega is being programmed, all its pins except MOSI, MISO, SCK and RESET are in a high impedance state, so they are effectively disconnected from the rest of the circuit. A side effect would be UART_OSC pulsing while the ATmega is being programmed, but when it is programmed the CPU_OSC is not output at all, so I think it is not a big deal (and later I will expand on ensuring inactive state of Minimal's control signals). The purpose of this change is to make it easier to build the Minimal. Without the change a programmer with a socket for the ATmega328P is needed, but in fact on Minimal's board we have all we need to program the MCU. On top of that, the users might have lots of ideas about playing with the Minimal's clock and so they will need to keep re-programming the ATmega to suit their needs. Example clock ideas: configurable clock speed persisted across reboots (using ATmega's EEPROM) or programming contests where the participants are supposed to solve a programming task with the Minimal using a predefined number of clock cycles (after reaching which the clock stops).
- In-circuit programming of the flash chips [wiring changes required]
I propose adding a capability to program the SST flash chips in-circuit. This would serve three purposes: a) to eliminate the need for a dedicated programmer while building the Minimal, b) to be able to update the flash drive without pulling the chip out of the machine and c) to extract the currently programmed contents from the flash drive (if the number of spare GPIOs on the MCU allow for the latter). While the updating of MinOS is already possible without chip's removal, with the educational purposes in mind the user might want to run a bare metal program, and then revert to MinOS. With the current setup this does require pulling the chip out and using an external programmer. But in fact most of the programmer's circuitry is already on the PCB. The idea is to keep receiving the image via ATmega's UART, and then use the spare GPIO lines on the MCU to trick MAR into accepting whatever the ATmega puts on the Minimal's bus (use current-limiting resistors in a way similar to how VREG connects to VRAM in Minimal64x4), then put the actual data byte on the bus and toggle SSD's ~WE. It should be possible to program the LSB, MSB and HSB while the Minimal is not fully assembled (by placing them in U15 socket), but will also be possible in the assembled system. The only socket used for this would be the U15 SSD. There are a couple of details to be addressed, but it seems to me this can be done.
a) PB4 and PB5 to be used (via current-limiting resistors) to control ~MIH an ~MIL. The side effect is that while the ATmega itself is being programmed In-circuit, the MAR will be tricked into occasionally storing whatever happens to be on the bus, but that doesn't seem to hurt anything.
b) inhibit Minimal's control signals while the flash is being programmed, so tie U7, U9 and U11 ~OE together, pull-up with a resistor and let it be controlled by the ATmega. The Minimal's control signals should be pulled-down (active-high signals) or pulled-up (active-low signals) so that they are in a well-defined state even when the U7, U9 and U11 have their outputs inhibited.
c) ATmega328P UART RX cannot be used to drive the Minimal's bus, because it might generate a conflict with another component driving the bus, so use e.g. PC5 and PD1..PD7 to drive the bus. This makes receiving the data from the host possible all the time, but imposes some limitations on what the ATmega can transmit. If we assume 115200 kbps for the MCU UART, we have quite a lot of time during a single bit time, this might be enough to write to the U15, so: if we need to put a one on the Minimal's bus at a position corresponding to PD1, then the UART at the host side will only notice that it's own RX is being idle, and if we need to put a zero, then the zero will be treated as a start bit (and so needs to last 1/115200 seconds), this seems enough time to do the U15 programming (and if not, a slower UART clock might be chosen instead). Then the MCU waits 8 bits time plus a stop bit time holding PD1 high, which the host will interpret as receiving a 0xff, which can be filtered by its own software. This requires some attention while extracting the U15 contents, but that's not a thing that cannot be solved with software (ATmega and host).
- SSD banking [wiring changes required]
The obvious idea behind Minimal UART Computer 3 is to simplify its design for educational purposes, and that includes eliminating the SSD banking. That said, the SST39SF010 contains 4 times the storage capacity the Minimal normally handles. Adding a couple of jumpers for the U15's high address bits (which are now tied to GND) would make it possible to have several images without having to re-flash the chip. The jumpers can even handle all high address bits, so that the 020 or 040 variants can be used as well.
- EEPROM configuration [change in ATmega328P firmware only]
Now that there is an MCU on board, it has 1kB of EEPROM conveniently accessible with single-byte erases and reads. This could be used to persist e.g. clock settings and Minimal's UART speed across reboots and maybe store other parameters, such as the clock booting timeout. This EEPROM would be accessible via ATmega's UART and manipulated with host software.
I imagine that the host-side software would be also capable of triggering the clock booting mode while the relevant timeout has not passed and then it would allow changing the EEPROM settings while in this mode. Also, in that mode downloading/uploading U15's contents would be possible. The communication from the ATmega to the host would have to be filtered for 0xff (the side effect of using PD1 to drive the Minimal's bus while programming the U15 flash). When the Minimal's clock has booted, the host software could maybe still be able to e.g. influence the clock and Minimal's UART speed in a way similar to what the buttons do.
Proposed MCU GPIO usage:
PB0 SW2
PB1 CPU_OSC
PB2 SW3
PB3 UART_OSC/ICSP MOSI
PB4 ~MIH override/ICSP MISO
PB5 ~MIL override/ICSP SCK
PB6 XTAL1
PB7 XTAL2
PC0, PC1, PC2 - LEDs
PC3 ~WE override (U15)
PC4 ~OE override (U7, U9, U11)
PC5 BUS0
PD0 RX
PD1 TX/BUS1
PD2 BUS2
PD3 BUS3
PD4 BUS4
PD5 BUS5
PD6 BUS6
PD7 BUS7
I guess with the above allocation extracting the U15 contents is not possible because there's no spare pin to override ~RO. On the other hand, the extraction should be doable with Minimal's own software and via its own UART.
Another idea is to maybe free up one GPIO by charlieplexing two of the LEDs https://en.wikipedia.org/wiki/Charlieplexing#/media/File:2-pin_Charlieplexing_with_common_resistor.svg and then use the freed GPIO for BUS1. And maybe charlieplex the fourth LED for some purpose.
I think I could help with some of the above, the software rather than the hardware, but I would need a working, modified hardware, so I'd appreciate if you commented on the above ideas and their prospects of becoming the next PCB release.
EDIT: by replacing the ATmega328p with e.g. ATmega32 one more MCU port becomes available. But then it deviates from a typical Arduino.