#include <kernel/dpl/SystemP.h>

#include "ti_drivers_config.h"
#include "ti_drivers_open_close.h"
#include "ti_board_open_close.h"

#include <drivers/mcspi/v0/lld/mcspi_lld.h>

#define SLAVE_MSG_SIZE     (1U)
#define SLAVE_DUMMY_TX    (0x00)

/* =========================================================
 * Globals
 * ========================================================= */
static uint8_t gSlaveTx;
static uint8_t gSlaveRx;

static MCSPILLD_Handle hMcspi;
static MCSPI_ExtendedParams gExtParams;

/* RX 상태 저장용 (Task에서 필요 시 사용) */
static volatile uint8_t gLastRx;
static volatile uint32_t gLastStatus;

/* =========================================================
 * SPI Slave Arm
 * ========================================================= */
static inline void spi_slave_arm(void)
{
    MCSPI_lld_readWriteIntr(
        hMcspi,
        &gSlaveTx,
        &gSlaveRx,
        SLAVE_MSG_SIZE,
        SystemP_WAIT_FOREVER,
        &gExtParams
    );
}

/* =========================================================
 * LLD Callbacks (❗ ISR 컨텍스트)
 * ========================================================= */
void MCSPI_lld_transferCallback(void *args, uint32_t status)
{
    /* RX 보관 */
    gLastRx = gSlaveRx;
    gLastStatus = status;

    if (status == MCSPI_TRANSFER_COMPLETED)
    {
        /* 다음 TX 준비 (가벼운 연산만) */
        gSlaveTx = gSlaveRx + 0x10;
    }
    else
    {
        /* 에러 시 더미 응답 */
        gSlaveTx = SLAVE_DUMMY_TX;
    }

    /* 즉시 다음 프레임 대비 */
    spi_slave_arm();
}

void MCSPI_lld_errorCallback(void *args, uint32_t status)
{
    gLastStatus = status;

    /* 에러 시에도 항상 arm */
    gSlaveTx = SLAVE_DUMMY_TX;
    spi_slave_arm();
}

/* =========================================================
 * Slave Init
 * ========================================================= */
void spi_slave_init(void *args)
{
    Drivers_open();
    Board_driversOpen();

    /* SysConfig가 생성한 LLD Handle */
    hMcspi = gMcspiHandle[CONFIG_MCSPI0];

    /* Extended Params */
    gExtParams.channel   = gConfigMcspi0ChCfg[0].chNum;
    gExtParams.dataSize  = 8;
    gExtParams.csDisable = TRUE;

    /* 초기 상태 */
    gSlaveTx = SLAVE_DUMMY_TX;
    gSlaveRx = 0x00;
    gLastRx  = 0x00;

    /* ★ 최초 1회 arm (필수) */
    spi_slave_arm();
}
