/* * Copyright (c) 2021 Mathema GmbH * SPDX-License-Identifier: BSD-3-Clause * https://opensource.org/licenses/BSD-3-Clause * Created: Günter Woigk */ ; ----------------------------------------------------------------------- ; XY2-100 Interface ; clock for XY2_100_clock must be 8 MHz ; channel x word must be stored before channel y word ; ----------------------------------------------------------------------- ; ----------------------------------------------------------------------- ; generate 2MHz clock and sync pulse on parity bit ; clock+ and clock- pins are OUT pins 0, 1 ; sync+ and sync- pins are OUT pins 2, 3 .program XY2_100_clock .define public sm_clock 8000000 .define CLOCK_HIGH 0b01 ; pin N = 1, pin N+1 = !1 .define CLOCK_LOW 0b10 ; pin N = 0, Pin N+1 = !0 .define SYNC_HIGH 0b0100 .define SYNC_LOW 0b1000 public start: .wrap_target set x, 18 ; => 19 loops bit_loop: set pins, (SYNC_HIGH + CLOCK_HIGH) [1] set pins, (SYNC_HIGH + CLOCK_LOW) jmp x-- bit_loop set pins, (SYNC_LOW + CLOCK_HIGH) [1] ; parity bit set pins, (SYNC_LOW + CLOCK_LOW) .wrap ; ----------------------------------------------------------------------- ; 2 state machines to send X data or send Y data ; the software must store x before y. ; the SM for y data must have a higher number than the SM for x data ; data+ and data- is emitted on the side-set pins ; one out pin is the x/y synchronizing pin ; one in pin is the x/y synchronizing pin ; if Y OSR is empty, then X and Y repeat the last value ; EXECCTRL register must be configured for STATUS to STATUS_TX_LESSTHAN, 1 ; shift must be configured to pull_threshold = 32 .program XY2_100_data .define public sm_clock 8000000 .side_set 2 opt ; the data+ and data- pins .define DATA_HIGH 0b01 ; pin N = 1, pin N+1 = !1 .define DATA_LOW 0b10 ; pin N = 0, Pin N+1 = !0 ; if fifo runs dry then data must be repeated: ; at start both axis must agree on whether to repeat last value or pull the next value. ; we can't simply pull non-blocking from the fifo, because in a race condition only X may be written. ; therefore we detect whether Y, which fifo must be written last, is empty ; X tests fifo too because we use same code for X and Y. ; therefore Y must override pin setting and therefore Y must be SM with higher number. ; during this time the the 3 header bits '001' are sent via side-set public start: nop [1] ; start delay to run in sync with the clock SM next_word: mov pins, status side DATA_LOW ; set pin from TX fifo status in null, 31 [1] ; clear isr in pins, 1 ; read pin back mov y, isr ; move bit to y for testing jmp !y, tx_not_empty ; tx fifos empty: repeat last value from x register: tx_empty: mov osr,x jmp tx_common ; tx fifos not emty: pull next value from fifo: tx_not_empty: pull block mov x, osr ; store value for repeating tx_common: out null,16 side DATA_HIGH [1] ; discard high bits ; ------------------------------- ; send data bits until OSR empty: ; parity is currently 'odd': loop_odd: out y, 1 ; get next data bit OSR -> Y jmp !y, send_0_odd send_1_odd: jmp loop_end_even side DATA_HIGH ; send '1' and toggle to parity even send_0_odd: jmp loop_end_odd side DATA_LOW ; send '0' and keep parity odd ; parity is currently 'even': loop_even: out y, 1 ; get next data bit OSR -> Y jmp !y, send_0_even send_1_even: jmp loop_end_odd side DATA_HIGH ; send '1' and toggle to parity odd send_0_even: jmp loop_end_even side DATA_LOW ; send '0' and keep parity even loop_end_odd: jmp !osre, loop_odd nop [1] jmp next_word side DATA_HIGH [3] ; send '1' to make parity even loop_end_even: jmp !osre, loop_even nop [1] jmp next_word side DATA_LOW [3] ; send '0' to keep parity even