// -------------------------------------------------- //
// This file is autogenerated by pioasm; do not edit! //
// -------------------------------------------------- //

#pragma once

#if !PICO_NO_HARDWARE
#include "hardware/pio.h"
#endif

// ----------- //
// dshot_bidir //
// ----------- //

#define dshot_bidir_wrap_target 7
#define dshot_bidir_wrap 7
#define dshot_bidir_pio_version 0

#define dshot_bidir_T1 15
#define dshot_bidir_T2 15
#define dshot_bidir_T3 10
#define dshot_bidir_TRX 6

static const uint16_t dshot_bidir_program_instructions[] = {
    0x6028, //  0: out    x, 8                       
    0xae03, //  1: mov    pins, null             [14]
    0xae01, //  2: mov    pins, x                [14]
    0xa70b, //  3: mov    pins, !null            [7] 
    0x00e0, //  4: jmp    !osre, 0                   
    0xbfe3, //  5: mov    osr, null              [31]
    0x7f80, //  6: out    pindirs, 32            [31]
            //     .wrap_target
    0x4508, //  7: in     pins, 8                [5] 
            //     .wrap
};

#if !PICO_NO_HARDWARE
static const struct pio_program dshot_bidir_program = {
    .instructions = dshot_bidir_program_instructions,
    .length = 8,
    .origin = -1,
    .pio_version = 0,
#if PICO_PIO_VERSION > 0
    .used_gpio_ranges = 0x0
#endif
};

static inline pio_sm_config dshot_bidir_program_get_default_config(uint offset) {
    pio_sm_config c = pio_get_default_sm_config();
    sm_config_set_wrap(&c, offset + dshot_bidir_wrap_target, offset + dshot_bidir_wrap);
    return c;
}

#include "hardware/clocks.h"
// init the sm in disabled state, ready for loading tx fifo.
static inline void dshot_bidir_program_init(PIO pio, uint sm, uint offset, uint pin_base, uint pin_count, float freq) {
    pio_sm_set_enabled(pio, sm, false); //disable sm
    for(uint i=pin_base; i<pin_base+pin_count; i++) {
        pio_gpio_init(pio, i);
    }
    pio_sm_set_consecutive_pindirs(pio, sm, pin_base, pin_count, true); //set output
    pio_sm_config c = dshot_bidir_program_get_default_config(offset);
    sm_config_set_out_shift(&c, true, true, 32); //autopull
    sm_config_set_out_pins(&c, pin_base, pin_count);
    sm_config_set_in_shift(&c, true, true, 32); //autopush
    sm_config_set_in_pins(&c, pin_base);
    int cycles_per_bit = dshot_bidir_T1 + dshot_bidir_T2 + dshot_bidir_T3;
    float div = clock_get_hz(clk_sys) / (freq * cycles_per_bit);
    sm_config_set_clkdiv(&c, div);
    pio_sm_init(pio, sm, offset, &c);
    pio_sm_clear_fifos(pio, sm); //just to be sure
}

#endif

// ------------ //
// dshot_bidir8 //
// ------------ //

#define dshot_bidir8_wrap_target 7
#define dshot_bidir8_wrap 7
#define dshot_bidir8_pio_version 0

#define dshot_bidir8_T1 15
#define dshot_bidir8_T2 15
#define dshot_bidir8_T3 10
#define dshot_bidir8_TRX 6

static const uint16_t dshot_bidir8_program_instructions[] = {
    0x6028, //  0: out    x, 8                       
    0xae03, //  1: mov    pins, null             [14]
    0xae01, //  2: mov    pins, x                [14]
    0xa70b, //  3: mov    pins, !null            [7] 
    0x00e0, //  4: jmp    !osre, 0                   
    0xbfe3, //  5: mov    osr, null              [31]
    0x7f80, //  6: out    pindirs, 32            [31]
            //     .wrap_target
    0x4508, //  7: in     pins, 8                [5] 
            //     .wrap
};

#if !PICO_NO_HARDWARE
static const struct pio_program dshot_bidir8_program = {
    .instructions = dshot_bidir8_program_instructions,
    .length = 8,
    .origin = -1,
    .pio_version = 0,
#if PICO_PIO_VERSION > 0
    .used_gpio_ranges = 0x0
#endif
};

static inline pio_sm_config dshot_bidir8_program_get_default_config(uint offset) {
    pio_sm_config c = pio_get_default_sm_config();
    sm_config_set_wrap(&c, offset + dshot_bidir8_wrap_target, offset + dshot_bidir8_wrap);
    return c;
}

#include "hardware/clocks.h"
// init the sm in disabled state, ready for loading tx fifo.
static inline void dshot_bidir8_program_init(PIO pio, uint sm, uint offset, uint pin_base, uint pin_count, float freq) {
    pio_sm_set_enabled(pio, sm, false); //disable sm
    for(uint i=pin_base; i<pin_base+pin_count; i++) {
        pio_gpio_init(pio, i);
    }
    pio_sm_set_consecutive_pindirs(pio, sm, pin_base, pin_count, true); //set output
    pio_sm_config c = dshot_bidir8_program_get_default_config(offset);
    sm_config_set_out_shift(&c, true, true, 32); //autopull
    sm_config_set_out_pins(&c, pin_base, pin_count);
    sm_config_set_in_shift(&c, true, true, 32); //autopush
    sm_config_set_in_pins(&c, pin_base);
    int cycles_per_bit = dshot_bidir8_T1 + dshot_bidir8_T2 + dshot_bidir8_T3;
    float div = clock_get_hz(clk_sys) / (freq * cycles_per_bit);
    sm_config_set_clkdiv(&c, div);
    pio_sm_init(pio, sm, offset, &c);
    pio_sm_clear_fifos(pio, sm); //just to be sure
}

#endif

