#ifndef __TPAFE5160_H
#define __TPAFE5160_H

/*
 * 模块名称：TPAFE5160 16位8通道同步采样ADC驱动
 * 模块功能：提供 TPAFE5160 并行接口模式下的初始化、过采样设置、转换启动、数据读取接口
 * 适用平台：STM32F407ZGT6，并行16位数据总线接 GPIOG[15:0]
 * 作者：王建锋
 * 创建日期：2026-07-17
 * 修改记录：
 *     2026-07-17  王建锋  创建初始版本，参考 AD7606 并行驱动及 TPAFE5160 手册
 *     2026-07-17  王建锋  增加 EXTI 中断读取模式
 */

#ifdef __cplusplus
extern "C" {
#endif

#include "main.h"

/* ======================== 宏定义 ======================== */

/* 通道数量 */
#define TPAFE5160_CH_NUM            8

/* 控制引脚操作宏 —— RD (PD3) */
#define TPAFE5160_RD_LOW()          HAL_GPIO_WritePin(TP_RD_GPIO_Port, TP_RD_Pin, GPIO_PIN_RESET)
#define TPAFE5160_RD_HIGH()         HAL_GPIO_WritePin(TP_RD_GPIO_Port, TP_RD_Pin, GPIO_PIN_SET)

/* 控制引脚操作宏 —— CONVST (PD4) */
#define TPAFE5160_CONVST_LOW()      HAL_GPIO_WritePin(TP_CONVST_GPIO_Port, TP_CONVST_Pin, GPIO_PIN_RESET)
#define TPAFE5160_CONVST_HIGH()     HAL_GPIO_WritePin(TP_CONVST_GPIO_Port, TP_CONVST_Pin, GPIO_PIN_SET)

/* 状态引脚读取宏 */
#define TPAFE5160_BUSY_READ()       HAL_GPIO_ReadPin(TP_BUSY_GPIO_Port, TP_BUSY_Pin)
#define TPAFE5160_FRSTDATA_READ()   HAL_GPIO_ReadPin(TP_FRSTDATA_GPIO_Port, TP_FRSTDATA_Pin)

/* 过采样引脚操作宏 —— OS0 (PF13), OS1 (PF14), OS2 (PF15) */
#define TPAFE5160_OS0(val)          HAL_GPIO_WritePin(TP_OS0_GPIO_Port, TP_OS0_Pin, \
                                        (val) ? GPIO_PIN_SET : GPIO_PIN_RESET)
#define TPAFE5160_OS1(val)          HAL_GPIO_WritePin(TP_OS1_GPIO_Port, TP_OS1_Pin, \
                                        (val) ? GPIO_PIN_SET : GPIO_PIN_RESET)
#define TPAFE5160_OS2(val)          HAL_GPIO_WritePin(TP_OS2_GPIO_Port, TP_OS2_Pin, \
                                        (val) ? GPIO_PIN_SET : GPIO_PIN_RESET)

/* 并行数据总线读取 —— DB[15:0] 接 GPIOG[15:0]，单次读取16位 */
#define TPAFE5160_READ_BUS()        ((uint16_t)GPIOG->IDR)

/* 过采样率枚举 (OS[2:0] 编码，OS2为MSB, OS0为LSB) */
typedef enum {
    TPAFE5160_OS_NONE  = 0,    /* 000 — 无过采样，350 kSPS */
    TPAFE5160_OS_X2    = 1,    /* 001 — 2倍过采样，175 kSPS */
    TPAFE5160_OS_X4    = 2,    /* 010 — 4倍过采样，87.5 kSPS */
    TPAFE5160_OS_X8    = 3,    /* 011 — 8倍过采样，43.75 kSPS */
    TPAFE5160_OS_X16   = 4,    /* 100 — 16倍过采样，21.875 kSPS */
    TPAFE5160_OS_X32   = 5,    /* 101 — 32倍过采样，10.94 kSPS */
    TPAFE5160_OS_X64   = 6,    /* 110 — 64倍过采样，5.47 kSPS */
    TPAFE5160_OS_HBW   = 7     /* 111 — 高带宽模式 (~30kHz)，350 kSPS */
} tpafe5160_os_t;

/* 输入量程枚举 */
typedef enum {
    TPAFE5160_RANGE_5V  = 0,   /* ±5V  (RANGE = LOW) */
    TPAFE5160_RANGE_10V = 1    /* ±10V (RANGE = HIGH) */
} tpafe5160_range_t;

/* 返回值定义 */
#define TPAFE5160_OK                0
#define TPAFE5160_ERROR           -1
#define TPAFE5160_BUSY_TIMEOUT    -2

/* 默认超时时间 (ms) */
#define TPAFE5160_CONV_TIMEOUT_MS  10

/* ======================== 函数声明 ======================== */

/*
 * 函数功能：初始化 TPAFE5160（设置过采样、等待就绪）
 * 入口参数：无
 * 返回值：0 - 成功，-2 - BUSY 超时
 * 限定条件：CubeMX 已完成 GPIO 初始化
 * 函数说明：1. 设置过采样为无过采样 (000)
 *           2. 确保 RD 为高、CONVST 为低
 *           3. 等待 BUSY 释放（转换空闲）
 */
int tpafe5160_init(void);

/*
 * 函数功能：设置过采样率
 * 入口参数：os - 过采样率枚举值  tpafe5160_os_t
 * 返回值：无
 * 限定条件：GPIO 已初始化
 * 函数说明：通过 OS[2:0] 引脚设置过采样率，在下一次转换时生效
 */
void tpafe5160_set_os(tpafe5160_os_t os);

/*
 * 函数功能：启动一次转换（CONVST 上升沿触发）
 * 入口参数：无
 * 返回值：无
 * 限定条件：GPIO 已初始化
 * 函数说明：产生 CONVST 脉冲上升沿，启动全部8通道同步采样与转换
 */
void tpafe5160_start_conv(void);

/*
 * 函数功能：等待转换完成
 * 入口参数：timeout_ms - 超时时间  uint32_t  > 0
 * 返回值：0 - 转换完成，-2 - 超时
 * 限定条件：已调用 tpafe5160_start_conv()
 * 函数说明：轮询 BUSY 引脚等待下降沿
 */
int tpafe5160_wait_busy(uint32_t timeout_ms);

/*
 * 函数功能：查询当前是否正在转换
 * 入口参数：无
 * 返回值：1 - 正在转换，0 - 空闲
 * 限定条件：GPIO 已初始化
 * 函数说明：读取 BUSY 引脚电平
 */
uint8_t tpafe5160_is_busy(void);

/*
 * 函数功能：读取全部8通道转换结果
 * 入口参数：buf - 8个int16_t的输出缓冲区  int16_t*  不为 NULL
 * 返回值：0 - 成功，-2 - BUSY 超时
 * 限定条件：GPIO 已初始化
 * 函数说明：1. 启动转换并等待 BUSY 释放
 *           2. 连续8次拉低RD读取各通道数据
 *           3. 通过 FRSTDATA 验证第一通道
 */
int tpafe5160_read_all(int16_t *buf);

/*
 * 函数功能：读取指定通道的转换结果
 * 入口参数：channel - 通道号  uint8_t  0 - 7
 *           value   - 输出指针 int16_t*  不为 NULL
 * 返回值：0 - 成功，-1 - 通道号无效，-2 - BUSY 超时
 * 限定条件：GPIO 已初始化
 * 函数说明：启动转换并等待完成后，连续读取至指定通道
 */
int tpafe5160_read_channel(uint8_t channel, int16_t *value);

/*
 * 函数功能：原始ADC值转电压值
 * 入口参数：raw - ADC原始值  int16_t  有符号补码
 * 返回值：电压值  float  单位 V
 * 限定条件：无
 * 函数说明：±5V量程时 LSB=152.59μV，±10V量程时 LSB=305.18μV
 *           默认使用 ±5V 量程 (RANGE 接 GND)
 */
float tpafe5160_to_voltage(int16_t raw);

/*
 * 函数功能：直接读取并行数据总线（不启动转换）
 * 入口参数：无
 * 返回值：16位原始数据  uint16_t
 * 限定条件：RD 为低或CS与RD已拉低
 * 函数说明：用于读取当前总线上的数据，需自行控制RD时序
 */
uint16_t tpafe5160_read_bus(void);

/* ======================== 中断模式 API ======================== */

/*
 * 函数功能：使能 BUSY EXTI 中断（运行时重使能用）
 * 入口参数：无
 * 返回值：无
 * 限定条件：CubeMX 已完成 GPIO 和 NVIC 配置
 * 函数说明：正常启动流程无需调用，仅在 irq_disable() 后需要重新使能时使用
 */
void tpafe5160_irq_enable(void);

/*
 * 函数功能：关闭 BUSY EXTI 中断
 * 入口参数：无
 * 返回值：无
 * 限定条件：已调用 tpafe5160_irq_enable()
 * 函数说明：仅禁用 NVIC 中断，GPIO 配置保持 CubeMX 设定
 */
void tpafe5160_irq_disable(void);

/*
 * 函数功能：启动转换（中断模式）
 * 入口参数：无
 * 返回值：无
 * 限定条件：已调用 tpafe5160_irq_enable()
 * 函数说明：产生 CONVST 脉冲，转换完成后由 EXTI 中断自动读取 8 通道数据
 */
void tpafe5160_start_conv_irq(void);

/*
 * 函数功能：检查是否有新的转换数据
 * 入口参数：无
 * 返回值：1 - 数据就绪，0 - 无新数据
 * 限定条件：中断模式已启用
 * 函数说明：在 EXTI 回调中置位，主循环读取后需调用 tpafe5160_clear_ready() 清除
 */
uint8_t tpafe5160_data_ready(void);

/*
 * 函数功能：清除数据就绪标志
 * 入口参数：无
 * 返回值：无
 * 限定条件：中断模式已启用
 * 函数说明：主循环处理完数据后调用
 */
void tpafe5160_clear_ready(void);

/*
 * 函数功能：获取数据缓冲区指针
 * 入口参数：无
 * 返回值：int16_t[8] 数据缓冲区的 const 指针
 * 限定条件：tpafe5160_data_ready() 返回 1 时调用
 * 函数说明：缓冲区由 EXTI 回调写入，主循环只读
 */
const int16_t* tpafe5160_get_buf(void);

/*
 * 函数功能：EXTI 中断处理（由 HAL_GPIO_EXTI_Callback 调用）
 * 入口参数：GPIO_Pin - 触发的引脚号
 * 返回值：无
 * 限定条件：BUSY EXTI 已使能
 * 函数说明：BUSY 下降沿时自动读取 8 通道数据到缓冲区
 */
void tpafe5160_exti_handler(uint16_t GPIO_Pin);

#ifdef __cplusplus
}
#endif

#endif /* __TPAFE5160_H */
