/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2021-2023 Raspberry Pi (Trading) Ltd.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 */

// Every TX FIFO entry is either a command, or up to 32 bits of data.
// Command format:
//
// | 13:9 |  8  |  7:0  |
// | Cmd  | Dir | Count |
//
// Count is the number of bits to be transferred by this command, minus 1.
// Dir is the output enable for the SWDIO pin.
// Cmd is the address of the write_cmd, read_cmd or get_next_cmd label.
//
// write_cmd expects a FIFO data entry, but read_cmd does not.
//
// read_cmd pushes data to the FIFO, but write_cmd does not. (The lack of RX
// garbage on writes allows the interface code to return early after pushing a
// write command, as there is no need in general to poll for a command's
// completion as long as all commands are executed in order.)
//
// The SWCLK period is 4 PIO SM execution cycles.

.program probe
.side_set 1 opt

public write_cmd:
public turnaround_cmd:                      ; Alias of write, used for probe_oen.pio
    pull
write_bitloop:
    out pins, 1             [1]  side 0x0   ; Data is output by host on negedge
    jmp x-- write_bitloop   [1]  side 0x1   ; ...and captured by target on posedge
                                            ; Fall through to next command
.wrap_target
public get_next_cmd:
    pull                         side 0x0   ; SWCLK is initially low
    out x, 8                                ; Get bit count
    out pindirs, 1                          ; Set SWDIO direction
    out pc, 5                               ; Go to command routine

read_bitloop:
    nop                                     ; Additional delay on taken loop branch
public read_cmd:
    in pins, 1              [1]  side 0x1   ; Data is captured by host on posedge
    jmp x-- read_bitloop         side 0x0
    push
.wrap                                       ; Wrap to next command


; Implement probe_gpio_init() and probe_sm_init() methods here - set pins, offsets, sidesets etc
% c-sdk {

static inline void probe_gpio_init()
{
#if defined(PROBE_PIN_RESET)
    // Target reset pin: pull up, input to emulate open drain pin
    gpio_pull_up(PROBE_PIN_RESET);
    // gpio_init will leave the pin cleared and set as input
    gpio_init(PROBE_PIN_RESET);
#endif
    // Funcsel pins
    pio_gpio_init(pio0, PROBE_PIN_SWCLK);
    pio_gpio_init(pio0, PROBE_PIN_SWDIO);
    // Make sure SWDIO has a pullup on it. Idle state is high
    gpio_pull_up(PROBE_PIN_SWDIO);
}

static inline void probe_sm_init(pio_sm_config* sm_config) {

    // Set SWCLK as a sideset pin
    sm_config_set_sideset_pins(sm_config, PROBE_PIN_SWCLK);

    // Set SWDIO offset
    sm_config_set_out_pins(sm_config, PROBE_PIN_SWDIO, 1);
    sm_config_set_set_pins(sm_config, PROBE_PIN_SWDIO, 1);
#ifdef PROBE_IO_SWDI
    sm_config_set_in_pins(sm_config, PROBE_PIN_SWDI);
#else
    sm_config_set_in_pins(sm_config, PROBE_PIN_SWDIO);
#endif


    // Set SWD and SWDIO pins as output to start. This will be set in the sm
    pio_sm_set_consecutive_pindirs(pio0, PROBE_SM, PROBE_PIN_OFFSET, 2, true);

    // shift output right, autopull off, autopull threshold
    sm_config_set_out_shift(sm_config, true, false, 0);
    // shift input right as swd data is lsb first, autopush off
    sm_config_set_in_shift(sm_config, true, false, 0);
}

%}
