; TCK is bit 0, TMS is bit 1, TDI/O is bit 2 #def tdi_off = b011; ; TMS is bit 1 #def tms_1 = b010; #def tms_0 = b101; ; TCK is bit 0 #def tck_1 = b001; #def tck_0 = b110; ; TDI is bit 2 #def tdi_1 = b100; #def tdi_0 = b011; ; TDO is bit 2 #def tdo_msk = b100; #def tdo_pos = -2; ;#def j2c_timed = 10; #def MaxLoop = 0xFFF ;#def looptest = 1; #def oportd = r15; #def j2c_wrk = r0; #def return1 = r8; #def return2 = r7; #def return3 = r6; #def dat2send = r2; #def bit2send = r3; #def rec_data = r4; tst: #ifdef looptest mov MaxLoop, r12 shl 8, r12, r12 mov 0, r14 ; error counter j2c_loop: mov 0xFF, r13 and r12, r13, r13 ; only to see the LEDs mov 0x80, j2c_wrk or j2c_wrk, r13, r13 shl 4, r13, r13 mov b1001, r11 or r11, r13, r11 ; data to send iext srv_command ; the address in GIO sgio r11, srv_command jmpr cc_busy, 0 ; start, write mvpcr +2, return1 jmp cc_uncond, j2c_cmd mov b0101, r11 iext srv_command ; the address in GIO sgio r11, srv_command jmpr cc_busy, 0 ; start, read mvpcr +2, return1 jmp cc_uncond, j2c_cmd shl -4, r13, r13 cmp r13, rec_data jmpr cc_eq, +2 add r14, c1, r14 ; delay just to see the LEDs mov 0xFFF, j2c_wrk shl 8, j2c_wrk, j2c_wrk sub j2c_wrk, c1, j2c_wrk jmpr cc_nzero, -1 sub r12, c1, r12 jmp cc_nzero, j2c_loop iext srv_outdata ; the address in GIO sgio r14, srv_outdata ; the address in GIO jmpr cc_busy, 0 #else mvpcr +2, return1 jmp cc_uncond, j2c_cmd #endif ; low power mov CMD_LP, j2c_wrk sgio j2c_wrk, SMCMD jmpr cc_uncond, 0 nop j2c_cmd: ; INIT mov tms_1, oportd iext SEBDOU sgio oportd, SEBDOU ; TCK=0, TMS=1, TDI=0 mov 7, j2c_wrk ; all enabled jmpr cc_busy, 0 iext SEBDEN sgio j2c_wrk, SEBDEN jmpr cc_busy, 0 ; copy the command & data iext srv_command lgio 0, srv_command jmpr cc_busy, 0 lpio 0x300, dat2send ; send the command mov 4, bit2send ; 4 bits to send mvpcr +2, return2 ; return address jmp cc_uncond, j2c_sendd ; send 4 bits of dat2send ; set TDI high mvpcr +2, return3 jmp cc_uncond, j2c_set_tdi ; TDI=1 mvpcr +2, return2 ; return address jmp cc_uncond, j2c_tmsp ; tms pulse ; send/receive data mov 8, bit2send ; 8 bits to send mvpcr +2, return2 ; return address jmp cc_uncond, j2c_sendd ; send 8 bits of dat2send ; enable the data output, TDI=0 and make a pulse at TMS ; set TDI low mvpcr +2, return3 jmp cc_uncond, j2c_clr_tdi ; TDI=0 mvpcr +2, return2 ; return address jmp cc_uncond, j2c_tmsp ; tms pulse ; store the result back jmpr cc_busy, 0 iext srv_outdata sgio rec_data, srv_outdata jmpr cc_busy, 0 jmp cc_uncond, return1 nop ; send a bitstream using TCK and TDI and receive the data from TDI ; ; The slave pulls TDI low only when TCK=1 and its output data is 0 ; ; The master pulls TDI low before the rising edge of TCK if its output data is 0 ; ; The master stores the TDI before the falling edge of TCK ; ; data to be sent : dat2send ; bits to be sent : bit2send ; received data : rec_data ; ; Data are sent LSB first, 4 bit command and 8 bit data j2c_sendd: mvpcr +2, return3 jmp cc_uncond, j2c_ena_tdi mvpcr +4, return3 shl -1, dat2send, dat2send jmp cc_carry, j2c_set_tdi jmp cc_uncond, j2c_clr_tdi #ifdef j2c_timed mvpcr +2, return3 jmp cc_uncond, j2c_delay #endif ; rising edge of TCK -- TDI must be active, not open drain! ; TDO in simulation must be weak pull up/down! -- not directly attached to TDI! mvpcr +2, return3 jmp cc_uncond, j2c_set_tck mvpcr +2, return3 jmp cc_uncond, j2c_dis_tdi #ifdef j2c_timed mvpcr +2, return3 jmp cc_uncond, j2c_delay #endif iext SEBDIN ; read the TDI lgio 0, SEBDIN jmpr cc_busy, 0 lpio 0x300, j2c_wrk ; mov tdo_msk, r4 ; and r4, j2c_wrk, j2c_wrk #ifdef tdo_pos shl tdo_pos, j2c_wrk, j2c_wrk #endif and j2c_wrk, c1, j2c_wrk shl 7, j2c_wrk, j2c_wrk ; now the received data is bit 7 shl -1, rec_data, rec_data ; shift right the serial register or j2c_wrk, rec_data, rec_data ; put the new input data as bit 7 ; falling edge of TCK mvpcr +2, return3 jmp cc_uncond, j2c_clr_tck sub bit2send, c1, bit2send ; dec the bit counter jmp cc_nzero, j2c_sendd ; loop mvpcr +2, return3 jmp cc_uncond, j2c_ena_tdi jmp cc_uncond, return2 ; return ; make a negative strobe pulse at TMS ; return address in return2 j2c_tmsp: ; falling edge of TCK mvpcr +2, return3 jmp cc_uncond, j2c_clr_tms #ifdef j2c_timed mvpcr +2, return3 jmp cc_uncond, j2c_delay #endif mvpcr +2, return3 jmp cc_uncond, j2c_set_tms jmp cc_uncond, return2 ; return #ifdef j2c_timed j2c_delay: mov j2c_timed, j2c_wrk sub j2c_wrk, c1, j2c_wrk jmpr cc_nzero, -1 jmp cc_uncond, return3 #endif j2c_set_tck: mov tck_1, j2c_wrk jmp cc_uncond, j2c_set_ttt j2c_clr_tck: mov tck_0, j2c_wrk jmp cc_uncond, j2c_clr_ttt j2c_set_tms: mov tms_1, j2c_wrk jmp cc_uncond, j2c_set_ttt j2c_clr_tms: mov tms_0, j2c_wrk jmp cc_uncond, j2c_clr_ttt j2c_set_tdi: mov tdi_1, j2c_wrk jmp cc_uncond, j2c_set_ttt j2c_clr_tdi: mov tdi_0, j2c_wrk jmp cc_uncond, j2c_clr_ttt j2c_set_ttt: or oportd, j2c_wrk, oportd iext SEBDOU sgio oportd, SEBDOU jmpr cc_busy, 0 jmp cc_uncond, return3 ; return j2c_clr_ttt: and oportd, j2c_wrk, oportd iext SEBDOU sgio oportd, SEBDOU jmpr cc_busy, 0 jmp cc_uncond, return3 ; return j2c_ena_tdi: mov 7, j2c_wrk iext SEBDEN sgio j2c_wrk, SEBDEN jmpr cc_busy, 0 jmp cc_uncond, return3 ; return j2c_dis_tdi: mov tdi_off, j2c_wrk iext SEBDEN sgio j2c_wrk, SEBDEN jmpr cc_busy, 0 jmp cc_uncond, return3 ; return nop