/*
 * kl_protocol.h
 * Shared constants, enums, and types for the K-Line protocol stack.
 */

#ifndef KL_PROTOCOL_H
#define KL_PROTOCOL_H

#include <stdint.h>
#include <stddef.h>

/* ================================================================
 * Hardware pin mapping (USART1 on PA9/PA10)
 * ================================================================ */
#define KL_RX_PIN           GPIO_PIN_10
#define KL_TX_PIN           GPIO_PIN_9
#define KL_GPIO_PORT        GPIOA

/* ================================================================
 * Protocol constants
 * ================================================================ */
#define KL_SLAVE_ADDR       0xF1
#define KL_SYNC_BYTE        0x55
#define KL_KEYWORD_LSB      0x8C
#define KL_KEYWORD_MSB      0x51
#define KL_PACKET_END       0x03

/* ================================================================
 * Timing (milliseconds)
 * ================================================================ */
#define KL_5BAUD_BIT_MS     200U    /* 5-baud bit period              */
#define KL_5BAUD_FIRST_MS   300U    /* 1.5 bit times for first sample */
#define KL_W1_MS            200U    /* Post-5baud delay before sync   */
#define KL_W2_MS            11U     /* Sync to keyword LSB            */
#define KL_W3_MS            11U     /* Keyword LSB to MSB             */
#define KL_HS_RETRY_MS      43U     /* Between handshake retries      */
#define KL_P1_GAP_MS        5U      /* ECU inter-byte gap             */
#define KL_SESSION_TMO_MS   5250U   /* Session keepalive timeout      */
#define KL_BYTE_TMO_MS      50U     /* Per-byte RX timeout            */
#define KL_PKT_TMO_MS       800U    /* Overall packet RX timeout      */
#define KL_COMPL_TMO_MS     25U     /* Complement wait timeout        */
#define KL_ECHO_TMO_MS      3U      /* Max time to wait for echo      */

/* ================================================================
 * Buffer sizing
 * ================================================================ */
#define KL_MAX_PACKET_PAYLOAD  16   /* KWP1281 max block data         */
#define KL_MAX_PACKET_RAW      20   /* LEN+CNT+CMD+16+0x03+margin    */
#define KL_RX_FIFO_SIZE        64
#define KL_IDENT_BUF_SIZE      64
#define KL_STREAM_BUF_SIZE     64

/* ================================================================
 * Handshake
 * ================================================================ */
#define KL_HANDSHAKE_MAX_RETRIES  5

/* ================================================================
 * ASCII / DTC chunk sizes
 * ================================================================ */
#define KL_ASCII_CHUNK_SIZE    13   /* Data bytes per ASCII packet     */
#define KL_DTC_CHUNK_SIZE      15   /* Data bytes per DTC packet       */
#define KL_DTC_RECORD_SIZE     8
#define KL_DTC_TOTAL_RECORDS   8

/* ================================================================
 * Packet command enum
 * ================================================================ */
typedef enum {
    KL_CMD_ReadIdent            = 0x00,
    KL_CMD_ReadRam              = 0x01,
    KL_CMD_WriteRam             = 0x02,
    KL_CMD_ReadRomEeprom        = 0x03,
    KL_CMD_ActuatorTest         = 0x04,
    KL_CMD_FaultCodesDelete     = 0x05,
    KL_CMD_End                  = 0x06,
    KL_CMD_FaultCodesRead       = 0x07,
    KL_CMD_SingleRead           = 0x08,
    KL_CMD_ACK                  = 0x09,
    KL_CMD_NAK                  = 0x0A,
    KL_CMD_SoftwareCoding       = 0x10,
    KL_CMD_LoginEeprom          = 0x18,
    KL_CMD_ReadEeprom           = 0x19,
    KL_CMD_WriteEeprom          = 0x1A,
    KL_CMD_Custom               = 0x1B,
    KL_CMD_GroupReading         = 0x29,
    KL_CMD_Login                = 0x2B,
    KL_CMD_GroupReadingResponse = 0xE7,
    KL_CMD_ReadEepromResponse   = 0xEF,
    KL_CMD_EepromLoginResponse  = 0xF0,
    KL_CMD_ActuatorTestResponse = 0xF5,
    KL_CMD_AsciiData            = 0xF6,
    KL_CMD_WriteEepromResponse  = 0xF9,
    KL_CMD_SingleReadResponse   = 0xFB,
    KL_CMD_FaultCodesResponse   = 0xFC,
    KL_CMD_ReadRomResponse      = 0xFD
} KL_PacketCmd;

/* ================================================================
 * Packet structure (parsed)
 * ================================================================ */
typedef struct {
    uint8_t  length;                    /* LENGTH field from wire      */
    uint8_t  counter;                   /* COUNTER field               */
    uint8_t  command;                   /* COMMAND field                */
    uint8_t  data[KL_MAX_PACKET_PAYLOAD]; /* Data bytes after COMMAND  */
    uint8_t  data_len;                  /* Number of data bytes        */
} KL_Packet;

/* ================================================================
 * Inline helper
 * ================================================================ */
static inline int32_t kl_tick_diff(uint32_t now, uint32_t ref)
{
    return (int32_t)(now - ref);
}

#endif /* KL_PROTOCOL_H */
