/*
 * kl_phy.h
 * Physical layer: UART driver, state-based echo suppression, RX FIFO.
 */

#ifndef KL_PHY_H
#define KL_PHY_H

#include "kl_protocol.h"

/* ================================================================
 * TX state
 * ================================================================ */
typedef enum {
    KL_PHY_TX_IDLE,         /* No TX in progress                    */
    KL_PHY_TX_SENDING,      /* HAL_UART_Transmit_IT issued          */
    KL_PHY_TX_ECHO_WAIT     /* TxCplt fired, awaiting self-echo     */
} KL_PhyTxState;

/* ================================================================
 * Physical layer context
 * ================================================================ */
typedef struct {
    volatile KL_PhyTxState tx_state;
    uint8_t       tx_byte;              /* Byte buffer for Transmit_IT  */
    uint8_t       last_tx_byte;         /* For echo matching            */
    volatile uint32_t tx_done_tick;     /* Tick when TxCplt fired       */
    volatile uint8_t  echo_pending;     /* Expecting self-echo on RX    */

    uint8_t       rx_fifo[KL_RX_FIFO_SIZE];
    volatile uint16_t rx_head;          /* Written by ISR               */
    volatile uint16_t rx_tail;          /* Read by main loop            */

    uint8_t       rx_it_buf[1];         /* HAL_UART_Receive_IT buffer   */
} KL_Phy;

/* ================================================================
 * API
 * ================================================================ */
void    KL_Phy_Init(void);
void    KL_Phy_Service(void);           /* Echo-timeout recovery        */
void    KL_Phy_EnableUart9600(void);
void    KL_Phy_DisableUart(void);

int     KL_Phy_TxByte(uint8_t byte);   /* Returns 1 accepted, 0 busy  */
int     KL_Phy_TxBusy(void);           /* Includes echo wait           */

int     KL_Phy_RxPop(uint8_t *out);    /* Returns 1 if byte available  */
int     KL_Phy_RxAvailable(void);
void    KL_Phy_RxFlush(void);

/* ISR callbacks -- call from HAL callbacks */
void    KL_Phy_TxCpltCB(void);
void    KL_Phy_RxCpltCB(void);

#endif /* KL_PHY_H */
