Hi TI support.
For some time now I've tried to make it work but somehow I'm not getting any interrupt on when ADC conversion is ready.
So I'm triggering ADC conversion manually (ADCCTRL0.ADC_CONV_START = 1) during the active battery mode. Also I've set the MASK2 (MASK2.ADC_READY_MASK = 1) and ADC_READ_EN for VBAT (ADC_READ_EN.EN_VBAT_READ = 1). Then, if I haven't missed something in the datasheet, the interrupt pin should be triggered when the ADC conversion is ready. But it doesn't for some reason. Then if I manually read the FLAG2 register 1 second after the ADC conversion was started, I see, that FLAG2.ADC_READY_FLAG bit is set. Also the VBAT value can be normally read and it is also the correct value (as expected)...
I can normally write and read registers and I'm sure that I2C communication is working as is should. I can read all the default register values, I can set the LDO voltage, etc. I'm sure that interrupts are working in other cases, let's say if the VIN was attached or when MR is pressed, etc.
Here are some basic register settings which I think should be sufficient for my needs...
Basic code example (some party of the code are not included for better readability):
/*
Goal is to start ADC conversion manually in battery active mode (only battery is connected) and receive
interrupt (rising edge) when ADC conversion has finished.
Needed register description:
• FLAG2 - ADC Flags -> Flag ADC_READY_FLAG identicates the status of ADC conversion (Cleared-on-read).
• MASK2 - Interrupt Masks 2 -> Mask of events which triggers the interrupt line. ADC_READY_MASK for the ADC ready.
• ADCCTRL0 - ADC Control 0 -> Start ADC conversion manually. Set ADC_CONV_START bit to "1".
• ADC_READ_EN - Channel Enable -> Enable certain ADC conversions. In this case EN_VBAT_READ.
*/
#define BQ2515X_ADC_READ_EN 0x58
#define BQ2515X_MASK2 0x09
#define BQ2515X_ADCCTRL0 0x40
#define BQ2515X_FLAG2 0x05
struct FLAG2{
bool TS_OPEN_FLAG :1;
uint8_t reserved :3;
bool COMP3_ALARM_FLAG :1;
bool COMP2_ALARM_FLAG :1;
bool COMP1_ALARM_FLAG :1;
bool ADC_READY_FLAG :1;
}FLAG2;
struct MASK2{
bool TS_OPEN_MASK :1;
uint8_t reserved :3;
bool COMP3_ALARM_MASK :1;
bool COMP2_ALARM_MASK :1;
bool COMP1_ALARM_MASK :1;
bool ADC_READY_MASK :1;
}MASK2;
struct ICCTRL0{
bool SW_RESET :1;
bool HW_RESET :1;
bool GLOBAL_INT_MASK :1;
bool reserved :1;
uint8_t AUTOWAKE :2;
bool reserved_1 :1;
bool EN_SHIP_MODE :1;
}ICCTRL0;
struct ADC_READ_EN{
bool reserved :1;
bool EN_ADCIN_READ :1;
bool EN_TS_READ :1;
bool EN_VBAT_READ :1;
bool EN_VIN_READ :1;
bool EN_ICHG_READ :1;
bool EN_PMID_READ :1;
bool EN_IIN_READ :1;
}ADC_READ_EN;
// Init BQ25155.
void bq25155_init(){
// All registers set to the default values.
ADC_READ_EN.EN_VBAT_READ = 1; // Enable VBAT ADC conversion.
bq25155_write_reg(BQ2515X_ADC_READ_EN, &ADC_READ_EN); // Write ADC_READ_EN register.
MASK2.ADC_READY_MASK = 1; // Enable ADC ready interrupt triggering mask.
bq25155_write_reg(BQ2515X_MASK2, &MASK2); // Write MASK2 register.
}
// Called every 2 seconds.
void start_adc_conv(){
ADCCTRL0.ADC_CONV_START = 1; // Set this bit to start the ADC conversion.
bq25155_write_reg(BQ2515X_ADCCTRL0, &ADCCTRL0);
}
// ISR called on rising and/or falling edge.
void bq25515_on_int_change(){
// Read FLAG2 register and clear its values, so that interrupt is going to be triggered next time.
bq25155_read_reg(BQ2515X_FLAG2, &FLAG2); // Read FLAG2 register.
printf("F2: 0x%.2X\n", FLAG2);
if(FLAG2.ADC_READY_FLAG){
// ADC Conversion completed.
// Read ADC VBAT MSB and LSB registers -> Reading the right value (battery voltage).
}
}
I'd kindly as you to help me figure it out what is the thing that I'm missing in the datasheet and what am I doing wrong...
Looking forward in solving the issue.
Regards, Ales Zupanc.
Firmware developer, Polabs d.o.o.