Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LTC681x - idea to improve rdstat, rdaux, and rdcv #63

Open
gudnimg opened this issue Dec 26, 2020 · 0 comments
Open

LTC681x - idea to improve rdstat, rdaux, and rdcv #63

gudnimg opened this issue Dec 26, 2020 · 0 comments

Comments

@gudnimg
Copy link

gudnimg commented Dec 26, 2020

Below are improvements to ltc681x_rdstat, ltc681x_rdaux, ltc681x_rdcv. I carefully tested this with DC2259 (LTC6811). This will resolve issue #45

I have used #47 and #58 in the code below.

This change will:

  • Reduce code size by 280 bytes
  • Reduce code lines from 171 lines to 108 lines (This improves readability a lot)

rdcv

uint8_t LTC681x_rdcv(uint8_t reg, uint8_t total_ic, cell_asic *ic) {
    int8_t pec_error = 0;
    uint8_t cell_data[NUM_RX_BYT * total_ic];
    uint8_t c_ic = 0;

    // Executes once for each of the LTC6811 cell voltage registers 
    for (uint8_t cell_reg = reg; cell_reg < ic[0].ic_reg.num_cv_reg + 1; cell_reg++) {
        if (cell_reg == REG_ALL) cell_reg++; // Start with REG_1 = 1

        LTC681x_rdcv_reg(cell_reg, total_ic, cell_data);

        for (uint8_t current_ic = 0; current_ic < total_ic; current_ic++) {
            c_ic = isospi_reverse_check(total_ic, current_ic, ic->isospi_reverse);
            pec_error = pec_error + parse_cells(c_ic, cell_reg, cell_data,
                                                &ic[c_ic].cells.c_codes[0],
                                                &ic[c_ic].cells.pec_match[0]);
        }
        if (reg == REG_1) break;
        if (reg == REG_2) break;
        if (reg == REG_3) break;
        if (reg == REG_4) break;
        if (reg == REG_5) break;
        if (reg == REG_6) break;
    }
    LTC681x_check_pec(total_ic, CELL, ic);

  return(pec_error);
}

rdaux

int8_t LTC681x_rdaux(uint8_t reg, uint8_t total_ic, cell_asic *ic) {   
    uint8_t data[NUM_RX_BYT * total_ic];
    int8_t pec_error = 0;
    uint8_t c_ic = 0;

    // Executes once for each of the LTC681x aux voltage registers 
    for (uint8_t gpio_reg = reg; gpio_reg < ic[0].ic_reg.num_gpio_reg + 1; gpio_reg++) {
        if (gpio_reg == REG_ALL) gpio_reg++; // Start with REG_1 = 1

        LTC681x_rdaux_reg(gpio_reg, total_ic, data);

        for (uint8_t current_ic = 0; current_ic < total_ic; current_ic++) {
            c_ic = isospi_reverse_check(total_ic, current_ic, ic->isospi_reverse);
            pec_error = parse_cells(c_ic, gpio_reg, data,
                                    &ic[c_ic].aux.a_codes[0],
                                    &ic[c_ic].aux.pec_match[0]);
        }

        if (reg == REG_1) break; // skip Register B if only Register A was selected.
    }
    LTC681x_check_pec(total_ic, AUX, ic);

    return (pec_error);
}

rdstat

int8_t LTC681x_rdstat(uint8_t reg, uint8_t total_ic, cell_asic *ic) {
    const uint8_t STAT_IN_REG = 3;
    uint8_t data[NUM_RX_BYT * total_ic];
    uint8_t data_counter = 0;
    int8_t pec_error = 0;
    uint16_t parsed_stat;
    uint16_t received_pec;
    uint16_t data_pec;
    uint8_t c_ic = 0;

    for (uint8_t stat_reg = reg; stat_reg < 3; stat_reg++) {
        if (stat_reg == REG_ALL) stat_reg++; // Start with REG_1 = 1
        data_counter = 0;

        LTC681x_rdstat_reg(stat_reg, total_ic, data);
        
        // Executes for every LTC681x in the daisy chain
        for (uint8_t current_ic = 0; current_ic < total_ic; current_ic++) {
            c_ic = isospi_reverse_check(total_ic, current_ic, ic->isospi_reverse);
            if (stat_reg == REG_1) {
                for (uint8_t current_stat = 0; current_stat< STAT_IN_REG; current_stat++) // This loop parses the read back data into Status registers, 
                {																		 // it loops once for each of the 3 stat codes in the register
                    parsed_stat = data[data_counter] + (data[data_counter + 1] << 8);       //Each stat codes is received as two bytes and is combined to create the parsed status code
                    ic[c_ic].stat.stat_codes[current_stat] = parsed_stat;
                    data_counter += 2;
                    // data[0:1]   -> STBR0 og STBR1
                    // data[2:3]   -> STBR2 og STBR3
                    // data[4:5]   -> STBR4 og STBR5
                }
            } else if (stat_reg == REG_2) {
                parsed_stat = data[data_counter] + (data[data_counter + 1] << 8);          //Each stat is received as two bytes and is combined to create the parsed status code
                ic[c_ic].stat.stat_codes[3] = parsed_stat; // STBR0 og STBR1 16-bit value for Digital power supply
                data_counter += 2;

                //ic[x].stat.flags[0] = STBR2: [C4OV, C4UV, C3OV, C3UV, C2OV, C2UV, C1OV, C1UV]
                //ic[x].stat.flags[1] = STBR3: [C8OV, C8UV, C7OV, C7UV, C6OV, C6UV, C5V, C5UV]
                //ic[x].stat.flags[2] = STBR4: [C12OV, C12UV, C11OV, C11UV, C10OV, C10UV, C9OV, C9UV]
                ic[c_ic].stat.flags[0] = data[data_counter++];
                ic[c_ic].stat.flags[1] = data[data_counter++];
                ic[c_ic].stat.flags[2] = data[data_counter++]; 
                ic[c_ic].stat.mux_fail[0] = (data[data_counter] & 0x02) >> 1; // Multiplexer self test status, 1 means failure.
                ic[c_ic].stat.thsd[0] = data[data_counter++] & 0x01; // Thermal shutdown status
            }

            // Check for PEC mismatch
            received_pec = (data[data_counter] << 8) + data[data_counter + 1];
            data_pec = pec15_calc(6, &data[current_ic*NUM_RX_BYT]);
            data_counter += 2;
        
            if (received_pec != data_pec) {
                pec_error = -1;                         //The pec_error variable is simply set negative if any PEC errors
                ic[c_ic].stat.pec_match[stat_reg - 1] = 1;  //are detected in the received serial data 
            } else {
                ic[c_ic].stat.pec_match[stat_reg - 1] = 0;
            }
        }

        if (reg == REG_1) {
            break; // skip Register B if only Register A was selected.
        }
    }

    LTC681x_check_pec(total_ic, STAT, ic);
    return (pec_error);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant