/*
 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include "hardware/interp.h"
#include "hardware/structs/sio.h"
#include "hardware/claim.h"

check_hw_size(interp_hw_t, SIO_INTERP1_ACCUM0_OFFSET - SIO_INTERP0_ACCUM0_OFFSET);

check_hw_layout(sio_hw_t, interp, SIO_INTERP0_ACCUM0_OFFSET);

static_assert(NUM_DMA_CHANNELS <= 16, "");

static uint8_t _claimed;

void interp_claim_lane(interp_hw_t *interp, uint lane) {
    valid_params_if(INTERP, lane < 2);
    uint bit = (interp_index(interp) << 1u) | lane;
    hw_claim_or_assert((uint8_t *) &_claimed, bit, "Lane is already claimed");
}

void interp_claim_lane_mask(interp_hw_t *interp, uint lane_mask) {
    valid_params_if(INTERP, lane_mask && lane_mask <= 0x3);
    if (lane_mask & 1u) interp_claim_lane(interp, 0);
    if (lane_mask & 2u) interp_claim_lane(interp, 1);
}

void interp_unclaim_lane(interp_hw_t *interp, uint lane) {
    valid_params_if(INTERP, lane < 2);
    uint bit = (interp_index(interp) << 1u) | lane;
    hw_claim_clear((uint8_t *) &_claimed, bit);
}

void interp_save(interp_hw_t *interp, interp_hw_save_t *saver) {
    saver->accum[0] = interp->accum[0];
    saver->accum[1] = interp->accum[1];
    saver->base[0] = interp->base[0];
    saver->base[1] = interp->base[1];
    saver->base[2] = interp->base[2];
    saver->ctrl[0] = interp->ctrl[0];
    saver->ctrl[1] = interp->ctrl[1];
}

void interp_restore(interp_hw_t *interp, interp_hw_save_t *saver) {
    interp->accum[0] = saver->accum[0];
    interp->accum[1] = saver->accum[1];
    interp->base[0] = saver->base[0];
    interp->base[1] = saver->base[1];
    interp->base[2] = saver->base[2];
    interp->ctrl[0] = saver->ctrl[0];
    interp->ctrl[1] = saver->ctrl[1];
}
