/* * AD7280A Lithium Ion Battery Monitoring System * * Copyright 2011 Analog Devices Inc. * * Licensed under the GPL-2. */ #ifndef _AD7280A_H_ #define _AD7280A_H_ #include /* * TODO: struct ad7280_platform_data needs to go into include/linux/iio */ #define DUMMY_BYTE 0x00 #define EIO 1 #define EFAULT 2 #define AD7280A_ACQ_TIME_400ns 0 #define AD7280A_ACQ_TIME_800ns 1 #define AD7280A_ACQ_TIME_1200ns 2 #define AD7280A_ACQ_TIME_1600ns 3 #define AD7280A_CONV_AVG_DIS 0 #define AD7280A_CONV_AVG_2 1 #define AD7280A_CONV_AVG_4 2 #define AD7280A_CONV_AVG_8 3 #define AD7280A_ALERT_REMOVE_VIN5 (1 << 2) #define AD7280A_ALERT_REMOVE_VIN4_VIN5 (2 << 2) #define AD7280A_ALERT_REMOVE_AUX5 (1 << 0) #define AD7280A_ALERT_REMOVE_AUX4_AUX5 (2 << 0) /* Registers */ #define AD7280A_CELL_VOLTAGE_1 0x0 /* D11 to D0, Read only */ #define AD7280A_CELL_VOLTAGE_2 0x1 /* D11 to D0, Read only */ #define AD7280A_CELL_VOLTAGE_3 0x2 /* D11 to D0, Read only */ #define AD7280A_CELL_VOLTAGE_4 0x3 /* D11 to D0, Read only */ #define AD7280A_CELL_VOLTAGE_5 0x4 /* D11 to D0, Read only */ #define AD7280A_CELL_VOLTAGE_6 0x5 /* D11 to D0, Read only */ #define AD7280A_AUX_ADC_1 0x6 /* D11 to D0, Read only */ #define AD7280A_AUX_ADC_2 0x7 /* D11 to D0, Read only */ #define AD7280A_AUX_ADC_3 0x8 /* D11 to D0, Read only */ #define AD7280A_AUX_ADC_4 0x9 /* D11 to D0, Read only */ #define AD7280A_AUX_ADC_5 0xA /* D11 to D0, Read only */ #define AD7280A_AUX_ADC_6 0xB /* D11 to D0, Read only */ #define AD7280A_SELF_TEST 0xC /* D11 to D0, Read only */ #define AD7280A_CONTROL_HB 0xD /* D15 to D8, Read/write */ #define AD7280A_CONTROL_LB 0xE /* D7 to D0, Read/write */ #define AD7280A_CELL_OVERVOLTAGE 0xF /* D7 to D0, Read/write */ #define AD7280A_CELL_UNDERVOLTAGE 0x10 /* D7 to D0, Read/write */ #define AD7280A_AUX_ADC_OVERVOLTAGE 0x11 /* D7 to D0, Read/write */ #define AD7280A_AUX_ADC_UNDERVOLTAGE 0x12 /* D7 to D0, Read/write */ #define AD7280A_ALERT 0x13 /* D7 to D0, Read/write */ #define AD7280A_CELL_BALANCE 0x14 /* D7 to D0, Read/write */ #define AD7280A_CB1_TIMER 0x15 /* D7 to D0, Read/write */ #define AD7280A_CB2_TIMER 0x16 /* D7 to D0, Read/write */ #define AD7280A_CB3_TIMER 0x17 /* D7 to D0, Read/write */ #define AD7280A_CB4_TIMER 0x18 /* D7 to D0, Read/write */ #define AD7280A_CB5_TIMER 0x19 /* D7 to D0, Read/write */ #define AD7280A_CB6_TIMER 0x1A /* D7 to D0, Read/write */ #define AD7280A_PD_TIMER 0x1B /* D7 to D0, Read/write */ #define AD7280A_READ 0x1C /* D7 to D0, Read/write */ #define AD7280A_CNVST_CONTROL 0x1D /* D7 to D0, Read/write */ /* Bits and Masks */ #define AD7280A_CTRL_HB_CONV_INPUT_ALL (0 << 6) #define AD7280A_CTRL_HB_CONV_INPUT_6CELL_AUX1_3_4 (1 << 6) #define AD7280A_CTRL_HB_CONV_INPUT_6CELL (2 << 6) #define AD7280A_CTRL_HB_CONV_INPUT_SELF_TEST (3 << 6) #define AD7280A_CTRL_HB_CONV_RES_READ_ALL (0 << 4) #define AD7280A_CTRL_HB_CONV_RES_READ_6CELL_AUX1_3_4 (1 << 4) #define AD7280A_CTRL_HB_CONV_RES_READ_6CELL (2 << 4) #define AD7280A_CTRL_HB_CONV_RES_READ_NO (3 << 4) #define AD7280A_CTRL_HB_CONV_START_CNVST (0 << 3) #define AD7280A_CTRL_HB_CONV_START_CS (1 << 3) #define AD7280A_CTRL_HB_CONV_AVG_DIS (0 << 1) #define AD7280A_CTRL_HB_CONV_AVG_2 (1 << 1) #define AD7280A_CTRL_HB_CONV_AVG_4 (2 << 1) #define AD7280A_CTRL_HB_CONV_AVG_8 (3 << 1) #define AD7280A_CTRL_HB_CONV_AVG(x) ((x) << 1) #define AD7280A_CTRL_HB_PWRDN_SW (1 << 0) #define AD7280A_CTRL_LB_SWRST (1 << 7) #define AD7280A_CTRL_LB_ACQ_TIME_400ns (0 << 5) #define AD7280A_CTRL_LB_ACQ_TIME_800ns (1 << 5) #define AD7280A_CTRL_LB_ACQ_TIME_1200ns (2 << 5) #define AD7280A_CTRL_LB_ACQ_TIME_1600ns (3 << 5) #define AD7280A_CTRL_LB_ACQ_TIME(x) ((x) << 5) #define AD7280A_CTRL_LB_MUST_SET (1 << 4) #define AD7280A_CTRL_LB_THERMISTOR_EN (1 << 3) #define AD7280A_CTRL_LB_LOCK_DEV_ADDR (1 << 2) #define AD7280A_CTRL_LB_INC_DEV_ADDR (1 << 1) #define AD7280A_CTRL_LB_DAISY_CHAIN_RB_EN (1 << 0) #define AD7280A_ALERT_GEN_STATIC_HIGH (1 << 6) #define AD7280A_ALERT_RELAY_SIG_CHAIN_DOWN (3 << 6) #define AD7280A_ALL_CELLS (0xAD << 16) #define AD7280A_MAX_SPI_CLK_Hz 700000 /* < 1MHz */ #define AD7280A_MAX_CHAIN 8 #define AD7280A_CELLS_PER_DEV 6 #define AD7280A_BITS 12 #define AD7280A_NUM_CH (AD7280A_AUX_ADC_6 - AD7280A_CELL_VOLTAGE_1 + 1) #define AD7280A_DEVADDR_MASTER 0 #define AD7280A_DEVADDR_ALL 0x1F #define AD7280A_CONV_BUF_SIZE (12 * 3) #define AD7280A_CELL_MAX (5 * 3) /* During a read a valid write is mandatory. * So writing to the highest available address (Address 0x1F) * and setting the address all parts bit to 0 is recommended * So the TXVAL is AD7280A_DEVADDR_ALL + CRC */ #define AD7280A_READ_TXVAL 0xF800030A /* AD7280A IO Configuration */ #define AD_CHIP_IO_GPIO GPIOD #define AD_CHIP_IO_GPIO_CLK RCC_AHB1Periph_GPIOD #define AD_CHIP_PD GPIO_Pin_10 #define AD_CHIP_ALERT GPIO_Pin_9 #define AD_CHIP_CONV GPIO_Pin_8 #define AD_CHIP_CS GPIO_Pin_12 #define AD_ALERT_IN GPIO_ReadInputDataBit(GPIOD, AD_CHIP_ALERT) #define DI_AD_ALERT 0 #define AD7280A_PD_HIGH GPIO_SetBits (GPIOD, AD_CHIP_PD); #define AD7280A_PD_LOW GPIO_ResetBits(GPIOD, AD_CHIP_PD); #define AD7280A_CS_HIGH GPIO_SetBits (GPIOB, AD_CHIP_CS); #define AD7280A_CS_LOW GPIO_ResetBits(GPIOB, AD_CHIP_CS); #define AD7280A_CONV GPIO_ResetBits(GPIOD, AD_CHIP_CONV);\ ad7280_delay(1);\ GPIO_SetBits (GPIOD, AD_CHIP_CONV);\ ad7280_delay(2);\ /* * AD7280 CRC * * P(x) = x^8 + x^5 + x^3 + x^2 + x^1 + x^0 = 0b100101111 => 0x2F */ #define POLYNOM 0x2F #define POLYNOM_ORDER 8 #define HIGHBIT (1 << (POLYNOM_ORDER - 1)); #pragma pack(1) typedef struct _ad7280_state { u8 init; u8 pd_status; u16 slave_num; u16 scan_cnt; u16 readback_delay_us; u8 crc_tab[256]; u8 ctrl_hb; u8 ctrl_lb; u8 cell_threshhigh; u8 cell_threshlow; u8 aux_threshhigh; u8 aux_threshlow; u8 cb_mask[AD7280A_MAX_CHAIN]; } ad7280_state; struct ad7280_platform_data { unsigned acquisition_time; unsigned conversion_averaging; unsigned chain_last_alert_ignore; u8 thermistor_term_en; }; typedef struct _T32BitWriteCycle { u32 BitPattern : 3; u32 Bit8CRC : 8; u32 Reserved : 1; u32 AddrAllParts : 1; u32 RegisterData : 8; u32 RegisterAddr : 6; u32 DeviceAddr : 5; } T32BitWriteCycle, *P32BitWriteCycle; typedef struct _T32BitReadConversionResultCycle { u32 BitPattern : 2; u32 Bit8CRC : 8; u32 WriteAck : 1; u32 ConversionData : 12; u32 ChannelAddr : 4; u32 DeviceAddr : 5; } T32BitReadConversionResultCycle, *P32BitReadConversionResultCycle; typedef struct _T32BitReadRegisterDataCycle { u32 BitPattern : 2; u32 Bit8CRC : 8; u32 WriteAck : 1; u32 Reserved : 2; u32 RegisterData : 8; u32 RegisterAddr : 6; u32 DeviceAddr : 5; } T32BitReadRegisterDataCycle, *P32BitReadRegisterDataCycle; typedef struct _TCellBalanceData { u16 cell_00 : 1; u16 cell_01 : 1; u16 cell_02 : 1; u16 cell_03 : 1; u16 cell_04 : 1; u16 cell_05 : 1; u16 cell_06 : 1; u16 cell_07 : 1; u16 cell_08 : 1; u16 cell_09 : 1; u16 cell_10 : 1; u16 cell_11 : 1; u16 cell_12 : 1; u16 cell_13 : 1; u16 cell_14 : 1; u16 cell_flag : 1; } TCellBalanceData, *PCellBalanceData; void AD7280A_READ_TEST(void); void AD7280A_READ_TEST2(void); void AD7280A_READ_TEST3(void); void AD7280A_READ_TEST4(void); void AD7280A_READ_TEST5(void); void Print_CRC_TABLE(void); void ad7280_init(void); s32 ad7280_chain_setup(void); s32 ad7280_self_test(unsigned devaddr); s32 ad7280_sw_reset(void); s8 ad7280_write_register(u8 devaddr, u8 all, u8 addr, u8 data); s8 ad7280_read_register(u8 devaddr, u8 addr); s32 ad7280_read_all_channels(u16 cnt, u32 *array); void SetCellbalanceBuff(u8 dev_addr, u8 value); u8 GetCellbalanceBuff(u8 dev_addr); void set_pd_status(u8 status); u8 get_pd_status(void); void App_TaskAdSpiComm(void *pdata); #endif /* _AD7280A_H_ */