#ifndef __ADS1256_H__
#define __ADS1256_H__

#include "stm32l4xx_hal.h"
#include <stdint.h>
#include <stdbool.h>

// ========== 用户配置宏 ==========
#define ADS1256_SPI_HANDLE         hspi2
extern SPI_HandleTypeDef ADS1256_SPI_HANDLE;

#define SPI_TIMEOUT                200     // ms

// 引脚配置
#define ADS1256_CS_GPIO_PORT      GPIOB
#define ADS1256_CS_PIN            GPIO_PIN_12

#define ADS1256_DRDY_GPIO_PORT    GPIOA
#define ADS1256_DRDY_PIN          GPIO_PIN_11

#define ADS1256_RST_GPIO_PORT     GPIOA
#define ADS1256_RST_PIN           GPIO_PIN_8

// ========== 控制宏 ==========
#define ADS1256_CS_LOW()      HAL_GPIO_WritePin(ADS1256_CS_GPIO_PORT, ADS1256_CS_PIN, GPIO_PIN_RESET)
#define ADS1256_CS_HIGH()     HAL_GPIO_WritePin(ADS1256_CS_GPIO_PORT, ADS1256_CS_PIN, GPIO_PIN_SET)

#define ADS1256_RST_LOW()     HAL_GPIO_WritePin(ADS1256_RST_GPIO_PORT, ADS1256_RST_PIN, GPIO_PIN_RESET)
#define ADS1256_RST_HIGH()    HAL_GPIO_WritePin(ADS1256_RST_GPIO_PORT, ADS1256_RST_PIN, GPIO_PIN_SET)
#define ADS1256_DRDY_READ() 	HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_11)
#define ADS1256_READ_DRDY     ADS1256_DRDY_READ()
// ========== 命令定义 ==========
#define ADS1256_CMD_WAKEUP            0x00  // 从休眠模式唤醒（必须在 SYNC 后使用）退出待机模式
#define ADS1256_CMD_RDATA             0x01  // 读取数据（一次性读取当前结果）
#define ADS1256_CMD_RDATAC            0x03  // 启动连续数据读取模式
#define ADS1256_CMD_SDATAC            0x0F  // 停止连续数据读取模式
#define ADS1256_CMD_RREG              0x10  // 读取寄存器命令（后跟寄存器地址和数量）
#define ADS1256_CMD_WREG              0x50  // 写寄存器命令（后跟寄存器地址和数量）
#define ADS1256_CMD_SELFCAL           0xF0  // 启动偏移和增益自动校准
#define ADS1256_CMD_SELFOCAL          0xF1  // 偏移自校准（接 GND）
#define ADS1256_CMD_SELFGCAL          0xF2  // 增益自校准（接参考电压）
#define ADS1256_CMD_SYSOCAL           0xF3  // 系统偏移校准
#define ADS1256_CMD_SYSGCAL           0xF4  // 系统增益校准
#define ADS1256_CMD_SYNC              0xFC  // 同步命令（等待转换）
#define ADS1256_CMD_STANDBY           0xFD  // 进入低功耗待机模式
#define ADS1256_CMD_RESET             0xFE  // 复位芯片


// ========== 寄存器定义 ==========
#define ADS1256_REG_STATUS    0x00  // 状态寄存器：时钟选择、自动校准、缓冲使能等
#define ADS1256_REG_MUX       0x01  // 多路复用器设置：选择输入通道 AINp 和 AINn
#define ADS1256_REG_ADCON     0x02  // A/D 控制寄存器：增益选择、时钟配置
#define ADS1256_REG_DRATE     0x03  // 数据速率设置寄存器
#define ADS1256_REG_IO        0x04  // 数字 I/O 控制寄存器
#define ADS1256_REG_OFC0      0x05  // 偏移校准寄存器 OFC0（低字节）
#define ADS1256_REG_OFC1      0x06  // 偏移校准寄存器 OFC1
#define ADS1256_REG_OFC2      0x07  // 偏移校准寄存器 OFC2（高字节）
#define ADS1256_REG_FSC0      0x08  // 全量程校准寄存器 FSC0（低字节）
#define ADS1256_REG_FSC1      0x09  // 全量程校准寄存器 FSC1
#define ADS1256_REG_FSC2      0x0A  // 全量程校准寄存器 FSC2（高字节）

// ========== 单端输入通道配置 (AINx - AINCOM) ==========
#define ADS1256_MUX_AIN0_AINCOM    0x08  // AIN0 - AINCOM
#define ADS1256_MUX_AIN1_AINCOM    0x18  // AIN1 - AINCOM
#define ADS1256_MUX_AIN2_AINCOM    0x28  // AIN2 - AINCOM
#define ADS1256_MUX_AIN3_AINCOM    0x38  // AIN3 - AINCOM
#define ADS1256_MUX_AIN4_AINCOM    0x48  // AIN4 - AINCOM
#define ADS1256_MUX_AIN5_AINCOM    0x58  // AIN5 - AINCOM
#define ADS1256_MUX_AIN6_AINCOM    0x68  // AIN6 - AINCOM
#define ADS1256_MUX_AIN7_AINCOM    0x78  // AIN7 - AINCOM

// ========== 差分输入通道配置 (AINp - AINn) ==========
#define ADS1256_MUX_AIN0_AIN1      0x01  // AIN0 - AIN1
#define ADS1256_MUX_AIN2_AIN3      0x23  // AIN2 - AIN3
#define ADS1256_MUX_AIN4_AIN5      0x45  // AIN4 - AIN5
#define ADS1256_MUX_AIN6_AIN7      0x67  // AIN6 - AIN7

// ========== 增益配置 ==========
typedef enum {
    ADS1256_GAIN_1 = 0,   // 增益 x1（默认）
    ADS1256_GAIN_2 = 1,       // 增益 x2
    ADS1256_GAIN_4 = 2,       // 增益 x4
    ADS1256_GAIN_8 = 3,       // 增益 x8
    ADS1256_GAIN_16 = 4,      // 增益 x16
    ADS1256_GAIN_32 = 5,      // 增益 x32
    ADS1256_GAIN_64 = 6       // 增益 x64（最大）
} ADS1256_Gain_t;

/*
ADCON 寄存器值
位    名称      描述
7     0         保留位，必须写 0
6-5   CLKOUT    时钟输出频率
            00: 禁用
            01: fCLKIN / 2
            10: fCLKIN / 4
            11: fCLKIN
4-3   SDCS      Sensor Detect Current Source
            建议默认写 0
2-0   PGA       增益设置：
            000: 1x
            001: 2x
            010: 4x
            011: 8x
            100: 16x
            101: 32x
            110: 64x
            111: 64x


*/

// ========== 数据速率 ==========
typedef enum {
    ADS1256_DR_30000SPS = 0xF0, // 30000 采样/秒
    ADS1256_DR_15000SPS = 0xE0, // 15000
    ADS1256_DR_7500SPS  = 0xD0, // 7500
    ADS1256_DR_3750SPS  = 0xC0, // 3750
    ADS1256_DR_2000SPS  = 0xB0, // 2000
    ADS1256_DR_1000SPS  = 0xA1, // 1000（推荐默认）
    ADS1256_DR_500SPS   = 0x92, // 500
    ADS1256_DR_100SPS   = 0x82, // 100
    ADS1256_DR_60SPS    = 0x72, // 60
    ADS1256_DR_50SPS    = 0x63, // 50
    ADS1256_DR_30SPS    = 0x53, // 30
    ADS1256_DR_25SPS    = 0x43, // 25
    ADS1256_DR_15SPS    = 0x33, // 15
    ADS1256_DR_10SPS    = 0x23, // 10
    ADS1256_DR_5SPS     = 0x13, // 5
    ADS1256_DR_2_5SPS   = 0x03  // 2.5（最低速）
} ADS1256_DataRate_t;


// ========== 函数声明 ==========
// 初始化 ADS1256
void ADS1256_Init(void);

// 复位
void ADS1256_Reset(void);

// 读取芯片 ID（高 4 位）
uint8_t ADS1256_ReadID(void);

// 设置输入通道（MUX 寄存器值）
void ADS1256_SetChannel(uint8_t mux);

// 设置增益
void ADS1256_SetGain(ADS1256_Gain_t gain);

// 设置采样率
void ADS1256_SetDataRate(ADS1256_DataRate_t dr);

// 启动一次转换
void ADS1256_StartConversion(void);

// 读取数据（需判断 DRDY 是否为低）
bool ADS1256_ReadData(int32_t* out);

// 寄存器读取出来的整数转为浮点数电压值
float ADS1256_ConvertToVoltage(int32_t raw, float vref, int gain);
// 寄存器操作
uint8_t ADS1256_ReadRegister(uint8_t reg);
void ADS1256_WriteRegister(uint8_t reg, uint8_t value);
void ADS1256_SendCommand(uint8_t cmd);
void ADS1256_SetClockSource(uint8_t useInternal);
bool ADS1256_IsUsingExternalClock(void);

#endif // __ADS1256_H__
