Introduction Despite plummeting costs, programmable logic devices remain outside my budget comfort-zone. While individual chips can be had for reasonable prices, the programming environments for them often require expensive software or hardware to program them or exhibit a dependency on closed, or at least opaque, operating systems. In an effort to try and control construction costs, I have elected to design the Kestrel K/1 around microcontrollers instead of dedicated programmable logic devices. Microcontrollers offer numerous I/O functions at substantially reduced costs compared to programmable logic, provided data throughput isn't a strong require. Unfortunately, modern microcontrollers generally respond to their I/O pins too slowly to hang the microcontroller directly off the processor's bus. Even earlier generations of microcontrollers, equipped with parallel slave ports, seem to lack flow control facilities. On-going I/O tasks may require sufficient microcontroller power that it violates the bus interface's timing constraints. For example, a display controller might take up to 64 microseconds before it can respond to its bus interface stimulus, as most 60Hz frame rates take 64 microseconds to refresh a single horizontal line. Ideally, the microcontrollers would hang off of a bus with asynchronous handshaking. The asynchronous handshake protocol would let the slave respond to the master at its own pace. Many microprocessors, such as the 65816 and 6809, only expose a fully synchronous bus. While these support a wait-state mechanism through their RDY signals, using RDY requires external logic to properly time back-to-back transfers to a slow resource. The K/1 implements a slave-only bus bridge implementing the required state machine providing RDY signal generation as well as managing the asynchronous bus interface. The bridge permits effortless expansion of the K/1's I/O capacity without general concern to strict timing parameters. As I write this, the least-cost microcontrollers on the market seem to be 28-pin ATmega and PIC units. For some applications, these parts expose too few I/O pins to adequately express both data and address pins. The K/1 bridge multiplexes address and data bytes over the same set of eight interconnects. While this slows throughput over the bus considerably, it permits a greater address space. Bus signal descriptions: CD(7:0) Channel Data bits 0-7. MRD High if data transfer is slave-to-master (e.g., reading). ACK# Acknowledge the current bus cycle. ASEL# Address Select; master drives CD(7:0) with either A(15:8) or A(7:0). DSEL# Data Select; master or slave drives CD(7:0) with D(7:0). CD(7:0) These signals contain either data or address information, depending on the bus phase. The master _always_ drives CD(7:0) when presenting address information on the bus, regardless of the state of MRD. The slave drives CD(7:0) during a data phase if, and only if, the master asserts MRD; otherwise, the master drives CD(7:0) with data. If a slave isn't participating in a bus transaction, it should leave CD(7:0) in high-impedance or input state. MRD The master always drives this signal. If the master intends data to flow from the slave to the master, it asserts MRD. If data flows from the master to the slave, it negates MRD. ACK# The addressed slave drives ACK to acknowledge the completion of the current bus phase. The K/1 bridge utilizes a four-cycle handshake protocol to ensure proper data transfer and bus hand-off in all cases. When not driving ACK, the slave must keep ACK in a high-impedance state (e.g., as with an open-collector or open-drain driver). DO NOT actively negate ACK, or a short-circuit may result with a slower-responding peripheral. The backplane implementation must pull ACK# high on behalf of the master and all the slaves. ASEL# The master drives ASEL# when it presents either A(15:8) or A(7:0) on the bus. The master actively negates ASEL# when not in use. The bridge expects the addressed slave to respond with ACK# after properly processing the address byte. Note that the master always presents addresses most-significant byte first to facilitate software address decoding in each microcontroller peripheral. Configure each slave to respond to a unique upper address byte to eliminate overlapping ACK# signals, which can result in timing problems under some conditions. DSEL# The master drives DSEL# when it presents D(7:0) on the bus, or when it expects the slave to do the same. The bridge expects the addressed slave to respond with ACK# after properly processing or presenting the data. Handshake Protocol The K/1 bridge utilizes a four-cycle handshake process to ensure proper bus timing and hand-off. As with most CPU buses, the MPB requires slightly different timing for reads and writes. The diagram below illustrates the four distinct events in the handshake: ________ _________________________________ ASEL#/ \_________________________/ DSEL# | | ____________________ | __________________ ACK# \____________________________/ | | | | | | | | A B C D ============================================================================================================= ADDRESS DATA PHASE STEP PHASE MRD=1 MRD=0 ============================================================================================================= A Master drives address bits on CD(7:0). Master is ready for data. Master puts data on CD. B Slave has latched address. Slave places data on CD(7:0) Slave has latched data. C Master takes address off bus. Master has latched data. Master takes data off bus. D Slave is ready for next byte. Slave removed data. Slave is ready for next byte. ============================================================================================================= Theoretically, the minimum time delay between any two events may approach zero. Gate delays, bus loading, and of course software delays in the addressed microcontroller will lead to response times much slower than instantaneous response. The host CPU experiences wait-states until ASEL#, DSEL#, and ACK# return to their negated state. Bus Timing Examples Read Byte From $FFFC (with sluggish handshakes) _____ ________________ ________________ _________ ________ CD(7:0) _____X___ $FF ________X____ $FC _______>----<_________>---<________ ___________________________________________________________________ MRD _______/ \_________ ___________ __________ ____________________________ ASEL# \_____/ \_____/ \___ _____________________________________ _________________ DSEL# ___/ \_______/ _________ ___________ _______ ______________ ACK# _____/ \____/ \____/ \______/ Write Byte $AA to $405F (with faster handshakes) _____ ________________ ________________ ______________ _____ ______ CD(7:0) _____X___ $40 ________X____ $5F _______X____ $AA _____X_____X______ _______ _________ MRD _______\_________________________________________________/_________ _____ ____ ____________________________ ASEL# \___________/ \___________/ \___ ___________________________________ ____________ DSEL# ___/ \______________/ _________ _________ _________ ______ ACK# _____/ \______/ \______/ \__________/ Read Byte and Write Byte From/To $FFFC (with fastest-possible handshakes): _____ _____ _____ _____ _____ _____ _____ __________________________ CD(7:0) _____X_$FF_X_$FC_X_____X_$FF_X_$FC_X_____X__________________________ _______________________ __________________________ MRD _____/ \_________________/__________________________ _____ __ ________ __ ___________________________________ ASEL# \__/ \__/ \__/ \__/ _________________ ______________ _____________________________ DSEL# \__/ \__/ _______ __ __ __ __ __ ___________________________ ACK# \__/ \__/ \__/ \__/ \__/ \__/