/******************************************************************************
 * @file      drv_adbms1818.h
 * @brief     LT6820-ADBMS1818�ջ���оƬ�ɼ�
 * @version   V1.0
 * @author    Gary 2024-11-13
 * @copyright
 ******************************************************************************/
#ifndef DRV_ADBMS1818_H_
#define DRV_ADBMS1818_H_

#ifdef __cplusplus
extern "C"
{
#endif

#include "stdlib.h"
#include "kit_data.h"
#include "drv_misc.h"
#include "drv_spi.h"
#include "kit_time.h"
#include "gpio_manager.h"

//#define cs_low() drv_gpio_set_pin_status(kGpioType_SP1_Cs_En1, kGpioStatus_Low);           // Set Cs Signal
//#define cs_high() drv_gpio_set_pin_status(kGpioType_SP1_Cs_En1, kGpioStatus_High)          // Set Cs Signal
#define cs_low() drv_gpio_set_pin_status(kGpioType_SP1_Cs_En2, kGpioStatus_Low);           // Set Cs Signal
#define cs_high() drv_gpio_set_pin_status(kGpioType_SP1_Cs_En2, kGpioStatus_High)          // Set Cs Signal
#define cs_low_reverse() drv_gpio_set_pin_status(kGpioType_SP1_Cs_En2, kGpioStatus_Low); // Set Cs Signal
#define cs_high_reverse() drv_gpio_set_pin_status(kGpioType_SP1_Cs_En2, kGpioStatus_High);// Set Cs Signal

#define IC_ADBMS1818

#define MD_422HZ_1KHZ 0
#define MD_27KHZ_14KHZ 1
#define MD_7KHZ_3KHZ 2
#define MD_26HZ_2KHZ 3

#define ADC_OPT_ENABLED 1
#define ADC_OPT_DISABLED 0

#define CELL_CH_ALL 0
#define CELL_CH_1and7 1
#define CELL_CH_2and8 2
#define CELL_CH_3and9 3
#define CELL_CH_4and10 4
#define CELL_CH_5and11 5
#define CELL_CH_6and12 6s

#define SELFTEST_1 1
#define SELFTEST_2 2

#define AUX_CH_ALL 0
#define AUX_CH_GPIO1 1
#define AUX_CH_GPIO2 2
#define AUX_CH_GPIO3 3
#define AUX_CH_GPIO4 4
#define AUX_CH_GPIO5 5
#define AUX_CH_VREF2 6

#define STAT_CH_ALL 0
#define STAT_CH_SOC 1
#define STAT_CH_ITEMP 2
#define STAT_CH_VREGA 3
#define STAT_CH_VREGD 4

#define REG_ALL 0
#define REG_1 1
#define REG_2 2
#define REG_3 3
#define REG_4 4
#define REG_5 5
#define REG_6 6

#define DCP_DISABLED 0
#define DCP_ENABLED 1

#define PULL_UP_CURRENT 1
#define PULL_DOWN_CURRENT 0

#define NUM_RX_BYT 8
#define CELL 1
#define AUX 2
#define STAT 3
#define CFGR 0
#define CFGRB 4
#define CS_PIN 10

  typedef struct
  {
    uint8_t tx_data[6];   //!< Stores data to be transmitted
    uint8_t rx_data[8];   //!< Stores received data
    uint8_t rx_pec_match; //!< If a PEC error was detected during most recent read cmd
  } ic_register;

  typedef struct
  {
    uint16_t c_codes[18]; //!< Cell Voltage Codes
    uint8_t pec_match[6]; //!< If a PEC error was detected during most recent read cmd
  } cv;

  /*! AUX Reg Voltage Data structure */
  typedef struct
  {
    uint16_t a_codes[9];  //!< Aux Voltage Codes
    uint8_t pec_match[4]; //!< If a PEC error was detected during most recent read cmd
  } ax;

  /*! Status Reg data structure. */
  typedef struct
  {
    uint16_t stat_codes[4]; //!< Status codes.
    uint8_t flags[3];       //!< Byte array that contains the uv/ov flag data
    uint8_t mux_fail[1];    //!< Mux self test status flag
    uint8_t thsd[1];        //!< Thermal shutdown status
    uint8_t pec_match[2];   //!< If a PEC error was detected during most recent read cmd
  } st;

  /*! PEC error counter structure. */
  typedef struct
  {
    uint16_t pec_count;   //!< Overall PEC error count
    uint16_t cfgr_pec;    //!< Configuration register data PEC error count
    uint16_t cell_pec[6]; //!< Cell voltage register data PEC error count
    uint16_t aux_pec[4];  //!< Aux register data PEC error count
    uint16_t stat_pec[2]; //!< Status register data PEC error count
  } pec_counter;

  /*! Register configuration structure */
  typedef struct
  {
    uint8_t cell_channels; //!< Number of Cell channels
    uint8_t stat_channels; //!< Number of Stat channels
    uint8_t aux_channels;  //!< Number of Aux channels
    uint8_t num_cv_reg;    //!< Number of Cell voltage register
    uint8_t num_gpio_reg;  //!< Number of Aux register
    uint8_t num_stat_reg;  //!< Number of  Status register
  } register_cfg;

  /*! Cell variable structure */
  typedef struct
  {
    ic_register config;
    ic_register configb;
    cv cells;
    ax aux;
    st stat;
    ic_register com;
    ic_register pwm;
    ic_register pwmb;
    ic_register sctrl;
    ic_register sctrlb;
    uint8_t sid[6];
    bool isospi_reverse;
    pec_counter crc_count;
    register_cfg ic_reg;
    long system_open_wire;
  } cell_asic;

  void wakeup_sleep(uint8_t total_ic);
  void wakeup_idle(uint8_t total_ic);

  void write_68(uint8_t total_ic,  // Number of ICs to be written to
                uint8_t tx_cmd[2], // The command to be transmitted
                uint8_t data[]     // Payload Data
  );
  void spi_write_read(uint8_t tx_Data[], // array of data to be written on SPI port
                      uint8_t tx_len,    // length of the tx data arry
                      uint8_t *rx_data,  // Input: array that will store the data read by the SPI port
                      uint8_t rx_len     // Option: number of bytes to be read from the SPI port
  );

  /* Write the ADBMS181x CFGRA */
  void ADBMS1818_wrcfg(uint8_t total_ic, // The number of ICs being written to
                       cell_asic ic[]    // A two dimensional array of the configuration data that will be written
  );
  /* Write the ADBMS181x CFGRB */
  void ADBMS1818_wrcfgb(uint8_t total_ic, // The number of ICs being written to
                        cell_asic ic[]    // A two dimensional array of the configuration data that will be written
  );
  /* Read the ADBMS181x CFGA */
  int8_t ADBMS1818_rdcfg(uint8_t total_ic, // Number of ICs in the system
                         cell_asic ic[]    // A two dimensional array that the function stores the read configuration data.
  );
  /* Reads the ADBMS181x CFGB */
  int8_t ADBMS1818_rdcfgb(uint8_t total_ic, // Number of ICs in the system
                          cell_asic ic[]    // A two dimensional array that the function stores the read configuration data.
  );

  /* Starts ADC conversion for cell voltage */
  void ADBMS1818_adcv(uint8_t MD,  // ADC Mode
                      uint8_t DCP, // Discharge Permit
                      uint8_t CH   // Cell Channels to be measured
  );

  /* This function will block operation until the ADC has finished it's conversion */
  uint32_t ADBMS1818_pollAdc(void);

  /*
  Reads and parses the ADBMS181x cell voltage registers.
  The function is used to read the parsed Cell voltages codes of the ADBMS181x.
  This function will send the requested read commands parse the data
  and store the cell voltages in c_codes variable.
  */
  uint8_t ADBMS1818_rdcv(uint8_t reg,      // Controls which cell voltage register is read back.
                         uint8_t total_ic, // The number of ICs in the system
                         cell_asic *ic     // Array of the parsed cell codes
  );

  /* Start ADC Conversion for GPIO and Vref2  */
  void ADBMS1818_adax(uint8_t MD, // ADC Mode
                      uint8_t CHG // GPIO Channels to be measured
  );

  int8_t ADBMS1818_rdaux(uint8_t reg,      // Determines which GPIO voltage register is read back.
                         uint8_t total_ic, // The number of ICs in the system
                         cell_asic *ic     // A two dimensional array of the gpio voltage codes.
  );

#ifdef __cplusplusS
  
}
  
#endif
  
#endif
  
