I add a code snippet to this subject to demonstrate, how an ATMega can do IO with devices requiring a phi2 clock.
The macros use timer 2 in ctc mode with OC2 pin set to toggle. Overflow compare is set to 7 and results in 1/16 of the ATMega clock being present on the OC2 pin, 1Mhz at 16MHz AVR clock.
Code:
;phase 2 synchronisation macro
; next instruction after macro is at tcnt=7, OC2=1
;
; you are here | at end of macro
; _ _ _ _ _ _ _V_ _ _
; Phi2 _ _| |_ _ _ _ _ _ _ _|
;
; tcnt 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1
;
; 500ns/phase, 62.5ns/count
.macro phi2_sync
phi2_syncloop:
in zl,tcnt2
sbic pind,7 ;wait for phi2 low
rjmp phi2_syncloop
clr zh
subi zl,low(-phi2_synctable) ;calculate offset cycles
sbci zh,high(-phi2_synctable)
ijmp
phi2_synctable: ;delay -1 cycle for each count in tcnt
nop ;0/1 - tcnt=0/OC2=1
nop ;1/1
nop ;2/1
nop ;3/1
nop ;4/1
nop ;5/1
nop ;6/1
; next 7/1 - output to next cycle, input from previous cycle
.endmacro
.macro nop2 ;2 cycle nop
rjmp pc+1
.endmacro
;macro phase 2 synchronized read
;
;
; data latched 1/2 clock ahead of IN +
; address valid + |
; after sync + | |
; | | _ _ _ _ _ _ _ _ _ _ _ _ | _ _
; chip select _ _|_ _|_ _| | |_ _
; _ _ _ _V_ | _ _ _ _ _ _ _ V
; Phi2 |_V_ _ _ _ _ _ _| |_ _ _ _
;
; tcnt 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3
;
.macro phi2_rd
phi2_sync
sbi abuslo,7 ;7/1 generate R/-W - tcnt=7/OC2=1
sbi cbus,io_select ;1/0 CS strobe high >300ns before phi2
nop2 ;3/0
nop2 ;5/0
nop2 ;7/0
nop2 ;1/1
nop2 ;3/1
nop2 ;5/1
nop ;7/1
in operand,dbusin ;0/0 input latched at 7/1 +30ns
out cbus,clear ;1/0 end strobe 125ns after phi2 te
.endmacro
;macro phase 2 synchronized write
;
; output data valid +
; address valid + |
; after sync + | |
; | | _ _ _ _ _ _ _|_ _ _ _ _ _ _
; chip select _ _|_ _|_ _| | |_ _ _
; _ _ _ _V_ | _ _V_ _ _ _ _ _
; Phi2 |_V_ _ _ _ _ _ _| |_ _ _ _
;
; tcnt 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3
;
.macro phi2_wrt
phi2_sync
cbi abuslo,7 ;7/1 generate R/-W - tcnt=7/OC2=1
sbi cbus,io_select ;1/0 CS strobe high >300ns before phi2
nop2 ;3/0
nop2 ;5/0
nop ;7/0
out dbusout,operand ;0/1 precharge data to be written
out dbusddr,allon ;1/1 write data valid 125 ns after phi2 le
nop2 ;2/1
nop2 ;4/1
nop2 ;6/1
out cbus,clear ;0/0 end strobe 60ns after phi2 te
out dbusddr,zero ;data hold ends
.endmacro
note: register address is present on abuslo before macros are called. Global interrupts must be disabled.
edit1: replaced with improved code saving 2 cycles to sync
edit2: avoided the use of register a and the page alignment
edit4: fixed broken offset calculation - forward reference & wrong carry