cAVR64 protocol, pre-draft ---------------------------------------------------- cAVR is a communication protocol between the HummerDTV v3 (and possibly a std C=64) and an AVR microcontroller. It has been tested with an ATmega8L, but should work with virtually no changes on other ATmega chips. The ATmega8L is a 28 pin PDIP package (or a 32 pin TQFP or MFL package) with six 10-bit ADCs, as well as various other comm interfaces and digital IO. The ATmega8 actually has eight ADCs, but only six are available on the 28 pin package. If more IO lines and ADCs are required in a PDIP, then the ATmega16 is available in a 40 pin PDIP. The ATmega8L is also a low-power 3.3V device, and should make tapping the DTV power supply possible (low current draw.) The AVR is currently operating at 4 mHz, using the internal oscillator. 8mHz is possible--but I've had trouble with a DAPA ISP cable @ 8mHz. The internal clock source should be fine, as there is no absolute timing reference for the protocol. ATmega AVRs can be easily programmed using a cheap ISP (in-system programming) cable. Free programming software is available for all major platforms (Linux, Windows, Mac.) A description of the DAPA cable can be found here: http://www.linuxfocus.org/English/November2004/article352.shtml Guido Socher's article is also a great introduction to programming the device. Although many commercial development environments exist for AVRs, they can be programmed with opensource tools also. Most prominently is AVR-GCC, a 'C' cross-compiler port of the GNU C compiler. I am currently using AVR-GCC for code, and programming the device (transferring code) with UISP. An alternative to UISP is AVRDUDE, which is commonly used on the Mac and Windows. ----------------------------------------------------- Using 5 userport lines, it transfers data in 3-bit chunks, so it is (or should be) much faster than a single-bit serial transfer. The DTV acts as master, the AVR as slave. All transfers are initiated by the master. Bits: PB7 | PB6 | PB5 | PB4 | PB3 DTV userport ---------------------------------------- Data2 Data1 Data0 CLK ATTN Signals ---------------------------------------- PD4 | PD3 | PD2 | PD1 | PD0 AVR micro ------------------------------------- Sending data to, and receiving data from the AVR has been demonstrated in the following ways: 1) Requesting and receiving a STATUS byte (currently this is a rolling count to demonstrate that full and unique bytes are being transfered.) 2) Requesting and receiving BUTTON press status. 3) Requesting and initiating output lines (LED, relays, etc.) 4) Requesting and receiving ADC data. ------------------------------------- General Info about the Protocol 1) All communication is initiated by dropping the ATTN Line (master only), then pulling high once again. 2) The master begins the CLK signal by pulling it low. The clock is cycled once for each data transfer. 3) The master places a 3-bit data chunk on in data2-data0, containing a command. Currently limited to 8 commands, one command will be an extended command (cmd continued in second chunk.) 4) The slave AVR responds to each request in kind, performing a function or sending data back to the master. 5) The slave AVR returns to a wait state. -------------------------------------- ABOUT ADC READS ATmega AVRs generally have eight 10-bit ADC inputs (ATmega8 is limited to six [DIP only].) Since the data bus is 3-bits wide, a normal byte transfer takes three clock cycles. But 3-bits x 3 cycles equals 9 bits, not 8. Consequently, I have truncated the 10-bit ADC to a 9-bit value (512 units) by dropping the LSBit. The 9th bit does not lengthen the transfer time. The routine stores the data as a standard two-byte integer--8 bits LSData, 1 bit MSData. A fast routine ("gimme8") converts that to a byte, if only 8 bits are needed. Eventually a separate routine will be written for the full ADC resolution, but this will require 4 rather than 3 clock cycles. (and 9 bits is pretty decent.) 9 bits of data also work well with c64 sprites, which use a 9th bit for full horiz resolution. Several modes of ADC reads will be explored: a) reading individual lines separately. b) each read will advance the current ADC channel to the next. c) reading two or three channels at once. d) read all the channels at once. e) assign a custom order to channel reads. -------------------------------------- BUGS and DIFFICULTIES The protocol on the AVR is bit-banged without IRQs, so it is possible for the master/slave to loose sync. And a true soft RESET doesn't exist, just a kludgy one (send the AVR a few empty clock cycles.) I will hopefully improve on this, and and plan to implement the ATTN signal as an input IRQ. Although the AVR is running much quicker than the DTV, an ADC read on the AVR takes several clock (AVR clock) cycles. This is the most common cause of sync problems. A possible cure would be to init the ADC in free-running mode, but this causes other difficulties when using more than one ADC. Still, this remains a possible hopeful alternative. -------------------------------------- Q & A Q) Why not also use the CASSSENCE line, allowing a full nibble (4 bit) transfer per cycle rather than just 3 bits? (DTVLOAD uses this approach) A) Because the same protocol could be used on the DTV v2, substituting a joystick port for the userport. Q) Why not run the ADC in free-running mode? A) Indeed, this is possible. Setting the current channel is the only difficulty, but since the current channel/channel rotation will be set prior to a read, the channel could be reset at the start of an exchange (immediately following ATTN trigger.) Another possibility would be to initiate a normal read at the same point, regardless if the cmd is an ADC read or not. The read is IRQ handled, which would add some overhead (not much.) That way, when the routine is actually ready to fetch the ADC result, the IRQ should nearly be finished. -------------------------------------- TO DO: Make protocol more robust (So far it works OK, but very little testing has been done.) Test, test and test. Add a true RESET function.