/**
 * @file AM2302.pio.h
 * @author Frank Häfele (mail@frankhaefele.de)
 * @brief PIO code for AM2302 Sensor
 * @version 1.0
 * @date 2026-03-02
 * 
 * @copyright Copyright (c) 2026 Frank Häfele
 * 
 */

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

#pragma once

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

// ------ //
// AM2302 //
// ------ //

#define AM2302_wrap_target 0
#define AM2302_wrap 21
#define AM2302_pio_version 0

static const uint16_t AM2302_program_instructions[] = {
            //     .wrap_target
    0x80a0, //  0: pull   block
    0xe081, //  1: set    pindirs, 1
    0xe000, //  2: set    pins, 0
    0xa027, //  3: mov    x, osr
    0xb942, //  4: nop                           [25]
    0x0044, //  5: jmp    x--, 4
    0xe001, //  6: set    pins, 1
    0xe080, //  7: set    pindirs, 0
    0x2020, //  8: wait   0 pin, 0
    0x20a0, //  9: wait   1 pin, 0
    0x2020, // 10: wait   0 pin, 0
    0x20a0, // 11: wait   1 pin, 0
    0xe034, // 12: set    x, 20
    0x00d1, // 13: jmp    pin, 17
    0xe040, // 14: set    y, 0
    0x4041, // 15: in     y, 1
    0x000b, // 16: jmp    11
    0x004d, // 17: jmp    x--, 13
    0xe041, // 18: set    y, 1
    0x4041, // 19: in     y, 1
    0x2020, // 20: wait   0 pin, 0
    0x000b, // 21: jmp    11
            //     .wrap
};

#if !PICO_NO_HARDWARE
static const struct pio_program AM2302_program = {
    .instructions = AM2302_program_instructions,
    .length = 22,
    .origin = -1,
    .pio_version = AM2302_pio_version,
#if PICO_PIO_VERSION > 0
    .used_gpio_ranges = 0x0
#endif
};

static inline pio_sm_config AM2302_program_get_default_config(uint offset) {
    pio_sm_config c = pio_get_default_sm_config();
    sm_config_set_wrap(&c, offset + AM2302_wrap_target, offset + AM2302_wrap);
    return c;
}

// Helper function to set a state machine to run our PIO program
static inline void AM2302_program_init(PIO pio, uint sm, uint offset, uint dataPin) {
    // Get an initialized config structure
    pio_sm_config sm_configuration = AM2302_program_get_default_config(offset);
    // Map the state machine's pin groups
    sm_config_set_set_pins(&sm_configuration, dataPin, 1);
    sm_config_set_in_pins(&sm_configuration, dataPin);
    sm_config_set_jmp_pin(&sm_configuration, dataPin);
    // Set the pin direction at the PIO
    pio_sm_set_consecutive_pindirs(pio, sm, dataPin, 1, true);
    // Turn on pull up on data pin
    gpio_pull_up(dataPin);
    // Make sure data is high at start
    pio_sm_set_pins_with_mask(pio, sm, 1 << dataPin, 1);
    // Set the pin GPIO function (connect PIO to the pad), 
    pio_gpio_init(pio, dataPin);
    // Configure the FIFOs
    // (configuration, false => left shift, true => automated shifting, 8 bits)
    sm_config_set_in_shift (&sm_configuration, false, true, 8);
    // (configuration, true => right shift, false => no automated shifting, 1 bit)
    sm_config_set_out_shift (&sm_configuration, true, false, 1);
    // Configure the clock for 1.4 MHz
    float div = clock_get_hz(clk_sys) / 1400000;
    sm_config_set_clkdiv(&sm_configuration, div);
    // Load our configuration, and jump to the start of the program
    pio_sm_init(pio, sm, offset, &sm_configuration);
    // Set the state machine running
    pio_sm_set_enabled(pio, sm, true);
}

#endif

