This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430FR2155: Error:[E0300] The following symbols are undefined:

Part Number: MSP430FR2155
Other Parts Discussed in Thread: BQ34Z100-R2, , BQ34Z100, MSPMATHLIB

Hello TI Experts!

I'm working with MSP430FR2155 and BQ34Z100-R2 to retrieve data. I have a code to read and write data.

But when i try to build it I'm getting this error : [E0300] The following symbols are undefined:

Could you help me resolve the issue

Thanks in advance !

  • It means you are not linking correctly. What symbols are listed as undefined?

  • Hey thank you for the response. However I have made a few changes and i fixed this part

    Now i have another set of errors. I will attach the codes and the screenshots of the errors below

    main.c

    #include <stdio.h>
    #include <inttypes.h>
    #include <msp430.h>
    #include <driverlib.h>
    #include <gpio.h>
    #include "drivers.h"
    #include "BQ34Z100.h"
    
    void i2c_init();
    void GPIO_Init();
    void GPIO_configPins();
    
    
    int main(void)
    {
    	WDTCTL = WDTPW | WDTHOLD;   // stop watchdog timer
    
    	i2c_init();
    	GPIO_Init();
    	    BQ34Z100 bq;
    
    	    uint16_t status = BQ34Z100_1_getStatus(&bq);
    	    printf("Status: %d\n", status);
    
    
    	return 0;
    }
    
    
    void i2c_init()
    {
        UCB1CTLW0 |=  UCSWRST;       // SWRST SET
    
        UCB1CTLW0 |= UCSSEL_3;       //CHOOSE SMCLK
        UCB1BRW = 400;                //CHOOSE PRESCALER VALUEwhere SMCLK =16MHz, 16000000/400 = 40000
    
        UCB1CTLW0 |= UCMODE_3;      // CHOOSE I2C MODE
        UCB1CTLW0 |= UCMST;         //CHOOSE MASTER MODE
        UCB1CTLW0 |= UCTR;          //CHOOSE TRANSMITTER MODE
        UCB1I2CSA |= 0xAA;          //set slave address
    
        UCB1CTLW0 |= UCSYNC;        //enable synchronous mode
    
        P4SEL1 &= ~BIT7;
        P4SEL0 |= BIT7;             //SET P4.7 AS SCL
    
        P4SEL1 &= ~BIT6;
        P4SEL0 |= BIT6;             //SET P4.6 AS SDA
    
        PM5CTL0 &= ~LOCKLPM5;
    
        UCB0CTLW0 &= ~UCSWRST;      //CLEAR SWRST
    
    
    
        UCB0IE |= UCTXIE0;
        __enable_interrupt();
    }
    
    
    void GPIO_Init()
    {
        P1OUT = 0x00; P2OUT = 0x00;
        P3OUT = 0x00; P4OUT = 0x00;
        P5OUT = 0x00;
    
        P1DIR |= 0xFF; P2DIR |= 0xFF;
        P3DIR |= 0xFF; P4DIR |= 0xFF;
        P5DIR |= 0xFF;
    
        GPIO_configPins();
    }
    
    
    void GPIO_configPins()
    {
        P1DIR &= ~BIT6;
        P1REN |= BIT6;
    
    
        P2DIR &= ~BIT0 & ~BIT2;
        P2REN |= BIT0 | BIT2;
    
    
        P5DIR &= ~BIT0;
        P5REN |= ~BIT0;
    
    }

    source code:

    #include <stdio.h>
    #include <stdlib.h>
    #include <stdint.h>
    #include <inttypes.h>
    #include <stdbool.h>
    #include <math.h>
    #include "driverlib.h"
    #include "BQ34Z100.h"
    #include "drv_i2c.h"
    
    uint8_t currFlashPage;
    uint8_t currFlashBlockIndex;
    uint8_t flashbytes[32];
    
    void delay(int DELAY)
    
    {
       short i;
       for (i = 0; i < DELAY; i++) {}
    }
    
    float BQ34Z100_1_xemicsToFloat(uint32_t xemics);
    
    typedef struct {
        int hz;
        uint8_t addr = 0xAA;
    } I2C;
    
    typedef struct {
        I2C i2c;
    } BQ34Z100_1;
    
    BQ34Z100* BQ34Z100_create() {
        BQ34Z100* bq34z100 = (BQ34Z100*)malloc(sizeof(BQ34Z100));
    
        // Check if memory allocation was successful
        if (bq34z100 == NULL) {
            // Handle memory allocation failure
            return NULL; // Return NULL to indicate failure
        }
    
        // Initialize the structure members if necessary
        // You can add initialization code here if needed
    
        return bq34z100; // Return a pointer to the newly allocated structure
    }
    
    // Function to destroy an instance of BQ34Z100
    void BQ34Z100_destroy(BQ34Z100* bq34z100) {
        // Check if the pointer is not NULL
        if (bq34z100 != NULL) {
            // Free the memory allocated for the BQ34Z100 structure
            free(bq34z100);
        }
        // Note: If there are other cleanup tasks, such as releasing resources held by
        // members of the structure, you can perform them here before freeing the memory.
    }
    
    
    void BQ34Z100_1_write(BQ34Z100_1* bq, Command command, const uint8_t cmd)
    {
        unsigned int sentbyte = 0;
        uint8_t cmd8 = (uint8_t)command;
        int writeResult = I2CSendBytes(bq->i2c.addr, &cmd8, 2, &sentbyte);
        if(writeResult != 0) {
            printf("A write error has occurred when transmitting address.\r\n");
        }
    }
    
    uint32_t BQ34Z100_1_read(BQ34Z100_1* bq, Command command, const uint8_t length) {
        uint32_t val = 0;
        int i;
        for (i = 0; i < length; i++)
        {
            uint8_t cmdByte = (uint8_t)command + i;
            int writeResult = I2CSendByte(bq->i2c.addr, cmdByte);
            if(writeResult != 0) {
                printf("A write error has occurred when transmitting address.\r\n");
            }
            unsigned char readByte;
            unsigned int count = 0;
            int readResult = I2CReadBytes(bq->i2c.addr, &readByte, 1, &count);
            if(readResult != 0) {
                printf("A read error has occurred when reading data.\r\n");
            }
            val |= ((uint32_t)readByte << (8 * i));
        }
        return val;
    }
    
    void BQ34Z100_1_sendControlCommand(BQ34Z100_1* bq, Control_2 control) {
        uint16_t controlBytes = (uint16_t)control;
        BQ34Z100_1_write(bq, Control, controlBytes & 0xFF);
       // BQ34Z100_1_write(bq, Command2 (controlBytes >> 8) & 0xFF);
    }
    
    uint16_t BQ34Z100_1_readControlCommand(BQ34Z100_1* bq, Control_2 control) {
        BQ34Z100_1_sendControlCommand(bq, control);
        return BQ34Z100_1_read(bq, Control , 2);
    }
    
    void BQ34Z100_1_write2(BQ34Z100_1* bq, Command command, const uint8_t cmd1, const uint8_t cmd2) {
        uint8_t command8 = (uint8_t)command;
        unsigned int sentbyte = 0;
        int writeResult = I2CSendBytes(bq->i2c.addr, &command8, 3, &sentbyte);
        if(writeResult != 0) {
            printf("A write error has occurred when transmitting address.\r\n");
        }
    }
    
    void BQ34Z100_1_enableCal(BQ34Z100_1* bq) {
        BQ34Z100_1_sendControlCommand(bq, CAL_ENABLE);
    }
    
    void BQ34Z100_1_enterCal(BQ34Z100_1* bq) {
        BQ34Z100_1_sendControlCommand(bq, ENTER_CAL);
    }
    
    void BQ34Z100_1_exitCal(BQ34Z100_1* bq) {
        BQ34Z100_1_sendControlCommand(bq, EXIT_CAL);
    }
    
    void BQ34Z100_1_ITEnable(BQ34Z100_1* bq) {
        BQ34Z100_1_sendControlCommand(bq, IT_ENABLE);
    
    }
    
    uint16_t getATTE(BQ34Z100_1* bq)
    {
        return(BQ34Z100_1_read(bq, AverageTimeToEmpty , 2));
    }
    
    uint16_t getATTF(BQ34Z100_1* bq)
    {
        return(BQ34Z100_1_read(bq, AverageTimeToFull , 2));
    }
    
    uint8_t getVoltScale(BQ34Z100_1* bq)
    {
        return(BQ34Z100_1_read(bq, VoltScale , 1));
    }
    
    uint8_t getCurrScale(BQ34Z100_1* bq)
    {
        return(BQ34Z100_1_read(bq, CurrScale , 1));
    }
    
    uint8_t getEnergyScale(BQ34Z100_1* bq)
    {
        return(BQ34Z100_1_read(bq, EnergyScale , 1));
    }
    
    uint16_t getAvailableEnergy(BQ34Z100_1* bq)
    {
        return(BQ34Z100_1_read(bq, AvailableEnergy , 2));
    }
    
    uint16_t getAvgPower(BQ34Z100_1* bq)
    {
        return(BQ34Z100_1_read(bq, AveragePower , 2));
    }
    
    uint16_t getChargeVoltage(BQ34Z100_1* bq)
    {
        return(BQ34Z100_1_read(bq, ChargeVoltage , 2));
    }
    
    uint16_t getChargeCurrent(BQ34Z100_1* bq)
    {
        return(BQ34Z100_1_read(bq, ChargeCurrent , 2));
    }
    
    uint16_t getGridNumber(BQ34Z100_1* bq)
    {
        return(BQ34Z100_1_read(bq, GridNumber , 2));
    }
    
    uint8_t BQ34Z100_1_getFull(BQ34Z100_1* bq)
    {
        return(BQ34Z100_1_read(bq, FullChargeCapacity, 1));
    }
    
    uint8_t getLearnedStatus(BQ34Z100_1* bq)
    {
        return(BQ34Z100_1_read(bq, LearnedStatus , 1));
    }
    
    uint8_t getDoDatEOC(BQ34Z100_1* bq)
    {
        return(BQ34Z100_1_read(bq, DoDatEOC , 1));
    }
    
    uint8_t getQstart(BQ34Z100_1* bq)
    {
        return(BQ34Z100_1_read(bq, QStart , 1));
    }
    
    uint16_t getTrueRC(BQ34Z100_1* bq)
    {
        return(BQ34Z100_1_read(bq, TrueRC , 2));
    }
    
    uint16_t getTrueFCC(BQ34Z100_1* bq)
    {
        return(BQ34Z100_1_read(bq, TrueFCC , 2));
    }
    
    uint16_t getStateTime(BQ34Z100_1* bq)
    {
        return(BQ34Z100_1_read(bq, StateTime , 2));
    }
    
    uint16_t getDOD0(BQ34Z100_1* bq)
    {
        return(BQ34Z100_1_read(bq, DOD0 , 2));
    }
    
    uint16_t getQmaxPassedQ(BQ34Z100_1* bq)
    {
        return(BQ34Z100_1_read(bq, QMaxPassedQ , 2));
    }
    
    uint16_t getQmaxDOD0(BQ34Z100_1* bq)
    {
        return(BQ34Z100_1_read(bq, QmaxDOD0 , 2));
    }
    
    uint16_t getQmaxTime(BQ34Z100_1* bq)
    {
        return(BQ34Z100_1_read(bq, QmaxTime , 2));
    }
    
    uint16_t getAvgCurrent(BQ34Z100_1* bq)
    {
        return(BQ34Z100_1_read(bq, AverageCurrent, 2));
    }
    
    uint16_t getCC(BQ34Z100_1* bq)
    {
        return(BQ34Z100_1_read(bq, CycleCount, 2));
    }
    
    uint16_t BQ34Z100_1_getStatus(BQ34Z100_1* bq) {
        return BQ34Z100_1_readControlCommand(bq, CONTROL_STATUS);
    }
    
    uint16_t BQ34Z100_1_getChemID(BQ34Z100_1* bq) {
        return BQ34Z100_1_readControlCommand(bq, CHEM_ID);
    }
    
    uint16_t BQ34Z100_1_getStateOfHealth(BQ34Z100_1* bq) {
        return BQ34Z100_1_read(bq, StateOfHealth, 2);
    }
    
    uint8_t BQ34Z100_1_getSOC(BQ34Z100_1* bq) {
        return BQ34Z100_1_read(bq, StateOfCharge, 1);
    }
    
    uint16_t BQ34Z100_1_getError(BQ34Z100_1* bq) {
        return BQ34Z100_1_read(bq, MaxError, 1);
    }
    
    uint16_t BQ34Z100_1_getRemaining(BQ34Z100_1* bq) {
        return BQ34Z100_1_read(bq, RemainingCapacity, 2);
    }
    
    uint16_t BQ34Z100_1_getVoltage(BQ34Z100_1* bq) {
        return BQ34Z100_1_read(bq, Voltage, 2);
    }
    
    int16_t BQ34Z100_1_getCurrent(BQ34Z100_1* bq) {
        int16_t result = BQ34Z100_1_read(bq, Current, 2);
        if (result < 0) result = -result;
        return result;
    }
    
    double BQ34Z100_1_getTemperature(BQ34Z100_1* bq) {
        return (BQ34Z100_1_read(bq, Temperature, 2) / 10.0) - 273.15;
    }
    
    //
    
    double BQ34Z100_1_getIntTemperature(BQ34Z100_1* bq) {
        return (BQ34Z100_1_read(bq, InternalTemperature, 2) / 10.0) - 273.15;
    }
    
    
    int BQ34Z100_1_getSerial(BQ34Z100_1* bq) {
        return BQ34Z100_1_read(bq,SerialNumber, 2);
    }
    
    void BQ34Z100_1_reset(BQ34Z100_1* bq) {
        BQ34Z100_1_sendControlCommand(bq, RESET);
        delay(175);
    }
    
    void BQ34Z100_1_unseal(BQ34Z100_1* bq) {
        BQ34Z100_1_sendControlCommand(bq, UNSEAL_KEY1);
        BQ34Z100_1_sendControlCommand(bq, UNSEAL_KEY2);
    }
    
    void BQ34Z100_1_seal(BQ34Z100_1* bq) {
        BQ34Z100_1_sendControlCommand(bq, SEALED);
    }
    
    void BQ34Z100_1_changePage(BQ34Z100_1* bq, char subclass, uint16_t offset) {
        delay(10);
        BQ34Z100_1_write(bq, BlockDataControl, 0x00);
        delay(10);
        BQ34Z100_1_write(bq, DataFlashClass, subclass);
        delay(10);
        currFlashPage = subclass;
        delay(10);
        currFlashBlockIndex = (uint8_t)(offset / 32);
        BQ34Z100_1_write(bq, DataFlashBlock, currFlashBlockIndex);
        delay(20);
    }
    
    uint8_t BQ34Z100_1_calcChecksum()
    {
        uint8_t chkSum = 0;
        int i;
        for (i = 0; i < 32; i++)
        {
            chkSum += flashbytes[i];
        }
        chkSum = 255 - chkSum;
        return chkSum;
    }
    
    void BQ34Z100_1_updateChecksum(BQ34Z100_1* bq)
    {
        uint8_t newChecksum = BQ34Z100_1_calcChecksum();
        BQ34Z100_1_write(bq, BlockDataCheckSum, newChecksum);
        printf("Writing new checksum for page %d" PRIu8 " block %d" PRIu8 ": 0x%d" PRIx8 "\r\n" , currFlashPage, currFlashBlockIndex, newChecksum);
        delay(50);
    }
    
    void BQ34Z100_1_readFlash(BQ34Z100_1* bq) {
        unsigned char command = (char)BlockData;
    //    int writeResult = write(bq->i2c.hz, &command, 1);
        int writeResult = I2CSendByte(bq->i2c.addr, command);
        if(writeResult != 0) {
            printf("A write error has occurred when transmitting address.\r\n");
        }
        uint16_t count = 0;
        uint8_t flash32;
        int readResult = I2CReadBytes(bq->i2c.addr, &flash32, 32, &count);
        flash32 = flashbytes[31];
        if(readResult != 0) {
            printf("A read error has occurred when reading data.\r\n");
        }
        uint8_t expectedChecksum = BQ34Z100_1_read(bq, BlockDataCheckSum, 1);
        if(expectedChecksum != BQ34Z100_1_calcChecksum()) {
            printf("ERROR: Checksum of flash memory block does not match.  I2C read was likely corrupted.");
        }
        printf("Page %d" PRIu8 " block %d" PRIu8 " contents:", currFlashPage, currFlashBlockIndex);
        size_t byteIndex;
        for(byteIndex = 0 ; byteIndex < 32 ; ++byteIndex)
        {
            printf(" %d" PRIx8, flashbytes[byteIndex]);
        }
        printf("\r\n");
        printf("Checksum: 0x%d" PRIx8 "\r\n", expectedChecksum);
        delay(10);
    }
    
    void BQ34Z100_1_writeFlash(BQ34Z100_1* bq, uint8_t index, uint32_t value, int len) {
        if (index > 31) index = index % 32;
        if (len == 1) {
            flashbytes[index] = value;
            BQ34Z100_1_write(bq, (Command)(BlockData + index), (unsigned char)value);
            printf("Flash[%d] <- 0x%d" PRIx8 "\n", index, flashbytes[index]);
        } else if (len > 1)
        {
            int i;
            for (i = 0; i < len - 1; i++)
            {
                flashbytes[index + i] = value >> 8 * ((len - 1) - i);
                printf("Flash[%d] <- 0x%d" PRIx8 "\n", index + i, flashbytes[index + i]);
                BQ34Z100_1_write(bq, (Command)(BlockData + index + i), flashbytes[index + i]);
            }
            flashbytes[index + len - 1] = value & 0xFF;
            printf("Flash[%d] <- 0x%d" PRIx8 "\n", index + (len - 1), flashbytes[index + len - 1]);
            BQ34Z100_1_write(bq, (Command)(BlockData + index + len - 1), value & 0xFF);
        }
    }
    
    uint8_t* BQ34Z100_1_getFlashBytes(BQ34Z100_1* bq) {
        return flashbytes;
    }
    
    void BQ34Z100_1_changePage48(BQ34Z100_1* bq) {
        BQ34Z100_1_changePage(bq, 48, 0);
        BQ34Z100_1_readFlash(bq);
        BQ34Z100_1_writeFlash(bq, 11, DESIGNCAP, 2);
        BQ34Z100_1_writeFlash(bq, 13, DESIGNENERGY, 2);
        BQ34Z100_1_updateChecksum(bq);
        delay(300);
    }
    
    void BQ34Z100_1_changePage64(BQ34Z100_1* bq) {
        BQ34Z100_1_changePage(bq, 64, 0);
        BQ34Z100_1_readFlash(bq);
        uint8_t packConfig_high = flashbytes[0];
        uint8_t packConfig_low = flashbytes[1];
        if (VOLTSEL) {
            packConfig_high |= 0x08;
        }
        packConfig_high |= 0x40;
        packConfig_low &= ~(1);
        packConfig_low |= USE_EXTERNAL_THERMISTOR;
        BQ34Z100_1_writeFlash(bq, 0, packConfig_high, 1);
        BQ34Z100_1_writeFlash(bq, 1, packConfig_low, 1);
        uint8_t packConfigB = flashbytes[2];
        packConfigB &= ~1;
        BQ34Z100_1_writeFlash(bq, 2, packConfigB, 1);
        BQ34Z100_1_writeFlash(bq, 4, LEDCONFIG, 1);
        BQ34Z100_1_writeFlash(bq, 7, 0x04, 1);
        BQ34Z100_1_updateChecksum(bq);
        delay(300);
    }
    
    void BQ34Z100_1_changePage80(BQ34Z100_1* bq) {
        BQ34Z100_1_changePage(bq, 80, 0);
        BQ34Z100_1_readFlash(bq);
        BQ34Z100_1_writeFlash(bq, 0, LOADSELECT, 1);
        BQ34Z100_1_writeFlash(bq, 1, LOADMODE, 1);
        BQ34Z100_1_writeFlash(bq, 10, 10, 2);
        BQ34Z100_1_updateChecksum(bq);
        delay(300);
        BQ34Z100_1_changePage(bq, 80, 53);
        BQ34Z100_1_readFlash(bq);
        BQ34Z100_1_writeFlash(bq, 53, ZEROCHARGEVOLT, 2);
        BQ34Z100_1_updateChecksum(bq);
        delay(300);
    }
    
    void BQ34Z100_1_changePage82(BQ34Z100_1* bq) {
        BQ34Z100_1_changePage(bq, 82, 0);
        BQ34Z100_1_readFlash(bq);
        BQ34Z100_1_writeFlash(bq, 0, QMAX0, 2);
        BQ34Z100_1_updateChecksum(bq);
        delay(300);
    }
    
    uint16_t BQ34Z100_1_calibrateVoltage(BQ34Z100_1* bq, uint16_t currentVoltage) {
        BQ34Z100_1_changePage(bq, 104, 0);
        BQ34Z100_1_readFlash(bq);
        uint16_t flashVoltage = (uint16_t)(flashbytes[14] << 8);
        flashVoltage |= (uint16_t)(flashbytes[15]);
        float readVoltage = (float)BQ34Z100_1_getVoltage(bq);
        float newSetting = ((float)(currentVoltage) / readVoltage) * (float)(flashVoltage);
        uint16_t writeSetting;
        if (newSetting > 65535.0f) writeSetting = 65535;
        else if (newSetting < 0.0f) writeSetting = 0;
        else writeSetting = (uint16_t)(newSetting);
        BQ34Z100_1_writeFlash(bq, 14, writeSetting, 2);
        BQ34Z100_1_updateChecksum(bq);
        delay(10);
        BQ34Z100_1_changePage(bq, 68, 0);
        BQ34Z100_1_readFlash(bq);
        int16_t oldUpdateOK = 0;
        oldUpdateOK |= (uint16_t)(flashbytes[0] << 8);
        oldUpdateOK |= flashbytes[1];
        int16_t newUpdateOK = (int16_t)(round(FLASH_UPDATE_OK_VOLT * CELLCOUNT * (5000.0f / writeSetting)));
        printf("Changing Flash Update OK Voltage from %d" PRIi16 " to %d" PRIi16 "\r\n", oldUpdateOK, newUpdateOK);
        BQ34Z100_1_writeFlash(bq, 0, newUpdateOK, 2);
        BQ34Z100_1_updateChecksum(bq);
        printf("Register (voltage divider): %d\r\n", flashVoltage);
        printf("New Ratio: %f\r\n", ((float)(currentVoltage) / readVoltage));
        printf("READ VOLTAGE (mv): %f\r\n", readVoltage);
        return (uint16_t)newSetting;
    }
    
    void BQ34Z100_1_resetVoltageDivider(BQ34Z100_1* bq) {
        BQ34Z100_1_changePage(bq, 104, 0);
        BQ34Z100_1_readFlash(bq);
        BQ34Z100_1_writeFlash(bq, 14, RESETVOLTAGE, 2);
        BQ34Z100_1_updateChecksum(bq);
        delay(300);
    }
    
    uint32_t BQ34Z100_1_floatToXemics(float value) {
        int iByte1, iByte2, iByte3, iByte4, iExp;
        bool bNegative = false;
        float fMantissa;
    
        if (value == 0) value = 0.00001F;
        if (value < 0) {
            bNegative = true;
            value = -value;
        }
    
        iExp = (int)((log(value) / log(2)) + 1);
    
        iByte1 = iExp + 128;
    
        fMantissa = value / (pow(2, iExp));
    
        fMantissa = fMantissa / (pow(2, -24));
    
        iByte2 = (int)(fMantissa / (pow(2, 16)));
        iByte3 = (int)((fMantissa - (iByte2 * (pow(2, 16)))) / (pow(2, 8)));
        iByte4 = (int)(fMantissa - (iByte2 * (pow(2, 16))) - (iByte3 * (pow(2, 8))));
    
        if (bNegative == false) {
            iByte2 = iByte2 & 0x7F;
        }
        return (uint32_t)((uint32_t)iByte1 << 24 | (uint32_t)iByte2 << 16 | (uint32_t)iByte3 << 8 | (uint32_t)iByte4);
    }
    
    void BQ34Z100_1_calibrateShunt(BQ34Z100_1* bq, int16_t calCurrent) {
        if (calCurrent < 0) calCurrent = -calCurrent;
        int16_t currentReading = BQ34Z100_1_getCurrent(bq);
        if (currentReading < 0) currentReading = -currentReading;
        BQ34Z100_1_changePage(bq, 104, 0);
        BQ34Z100_1_readFlash(bq);
        delay(30);
        uint32_t currentGainDF = ((uint32_t)flashbytes[0]) << 24 | ((uint32_t)flashbytes[1]) << 16 | ((uint32_t)flashbytes[2]) << 8 | (uint32_t)flashbytes[3];
        float currentGainResistance = (4.768f / BQ34Z100_1_xemicsToFloat(currentGainDF));
        uint32_t currentDeltaDF = ((uint32_t)flashbytes[4]) << 24 | ((uint32_t)flashbytes[5]) << 16 | ((uint32_t)flashbytes[6]) << 8 | (uint32_t)flashbytes[7];
        float currentDeltaResistance = (5677445 / BQ34Z100_1_xemicsToFloat(currentGainDF));
        float newGain = (((float)currentReading) / ((float)calCurrent)) * currentGainResistance;
        uint32_t newGainDF = BQ34Z100_1_floatToXemics(4.768 / newGain);
        float DeltaDF = BQ34Z100_1_floatToXemics(5677445 / newGain);
        printf("currentGainDF = 0x%" PRIx32 ", currentGainResistance = %f, currentDeltaDF = %" PRIx32 ", currentDeltaResistance = %f, newGain = %f, newGainDF = 0x%" PRIx32 "\n",
               currentGainDF, currentGainResistance, currentDeltaDF, currentDeltaResistance, newGain, newGainDF);
        BQ34Z100_1_writeFlash(bq, 0, newGainDF, 4);
        BQ34Z100_1_writeFlash(bq, 4, DeltaDF, 4);
        BQ34Z100_1_updateChecksum(bq);
        delay(300);
    }
    
    void BQ34Z100_1_setSenseResistor(BQ34Z100_1* bq) {
        BQ34Z100_1_changePage(bq, 104, 0);
        BQ34Z100_1_readFlash(bq);
        delay(30);
        uint32_t GainDF = BQ34Z100_1_floatToXemics(4.768 / SENSE_RES);
        uint32_t DeltaDF = BQ34Z100_1_floatToXemics(5677445 / SENSE_RES);
        BQ34Z100_1_writeFlash(bq, 0, GainDF, 4);
        BQ34Z100_1_writeFlash(bq, 4, DeltaDF, 4);
        printf("newGain = %f, GainDF = 0x%" PRIx32 "\n",
               SENSE_RES, GainDF);
        BQ34Z100_1_updateChecksum(bq);
        delay(300);
    }
    
    uint16_t BQ34Z100_1_readDeviceType(BQ34Z100_1* bq) {
        return BQ34Z100_1_readControlCommand(bq, DEVICE_TYPE);
    }
    
    uint16_t BQ34Z100_1_readFWVersion(BQ34Z100_1* bq) {
        return BQ34Z100_1_readControlCommand(bq, FW_VERSION);
    }
    
    uint16_t BQ34Z100_1_readHWVersion(BQ34Z100_1* bq) {
        return BQ34Z100_1_readControlCommand(bq, HW_VERSION);
    }
    
    
    float BQ34Z100_1_xemicsToFloat(uint32_t xemics) {
        bool bIsPositive = false;
        float fExponent, fResult;
        uint8_t vMSByte = (uint8_t)(xemics >> 24);
        uint8_t vMidHiByte = (uint8_t)(xemics >> 16);
        uint8_t vMidLoByte = (uint8_t)(xemics >> 8);
        uint8_t vLSByte = (uint8_t)xemics;
    
        if ((vMidHiByte & 128) == 0) {
            bIsPositive = true;
        }
    
        fExponent = pow(2, (vMSByte - 128));
    
        vMidHiByte = (uint8_t)(vMidHiByte | 128);
    
        fResult = (vMidHiByte) * 65536;
    
        fResult = fResult + (vMidLoByte * 256);
    
        fResult = fResult + vLSByte;
    
        fResult = fResult * pow(2, -24);
    
        fResult = fResult * fExponent;
    
        if (bIsPositive)
            return fResult;
        else
            return -fResult;
    }
    uint8_t BQ34Z100_1_getUpdateStatus(BQ34Z100_1* bq)
    {
        BQ34Z100_1_changePage(bq, 82, 0);
        BQ34Z100_1_readFlash(bq);
        return flashbytes[4];
    }
    
    uint16_t BQ34Z100_1_getFlags(BQ34Z100_1* bq)
    {
        uint16_t flags = BQ34Z100_1_read(bq, Flags, 2);
        //Flags_1 result = {flags, flagsB};
        return (flags);
    }
    
    uint16_t BQ34Z100_1_getFlagsB(BQ34Z100_1* bq)
    {
        uint16_t flagsB = BQ34Z100_1_read(bq, FlagsB, 2);
        return(flagsB);
    }
    
    
    

    header file:

    #ifndef BQ34Z100_H
    #define BQ34Z100_H
    
    #include <stdint.h>
    #include <stdlib.h>
    
    typedef enum {
        Control = 0x0,
        StateOfCharge = 0x2,
        MaxError = 0x3,
        RemainingCapacity = 0x4,
        FullChargeCapacity = 0x6,
        Voltage = 0x8,
        AverageCurrent = 0xA,
        Temperature = 0xC,
        Flags = 0xE,
        Current = 0x10,
        FlagsB = 0x12,
        AverageTimeToEmpty = 0x18,
        AverageTimeToFull = 0x1A,
        PassedCharge = 0x1C,
        DoD0Time = 0x1E,
        VoltScale = 0x20,
        CurrScale = 0x21,
        EnergyScale = 0x22,
        AvailableEnergy = 0x24,
        AveragePower = 0x26,
        SerialNumber = 0x28,
        InternalTemperature = 0x2A,
        CycleCount = 0x2C,
        StateOfHealth = 0x2E,
        ChargeVoltage = 0x30,
        ChargeCurrent = 0x32,
        DataFlashClass = 0x3E,
        DataFlashBlock = 0x3F,
        BlockData = 0x40,
        BlockDataCheckSum = 0x60,
        BlockDataControl = 0x61,
        GridNumber = 0x62,
        LearnedStatus = 0x63,
        DoDatEOC = 0x64,
        QStart = 0x66,
        TrueRC = 0x68,
        TrueFCC = 0x6A,
        StateTime = 0x6C,
        QMaxPassedQ = 0x6E,
        QmaxDOD0 = 0x72,
        QmaxTime = 0x74,
        DOD0 = 0x70,
    
    } Command;
    
    typedef enum {
        CONTROL_STATUS = 0x0,
        DEVICE_TYPE = 0x1,
        FW_VERSION = 0x02,
        HW_VERSION = 0x03,
        RESET_DATA = 0x5,
        PREV_MACWRITE = 0x7,
        CHEM_ID = 0x8,
        BOARD_OFFSET = 0x9,
        CC_OFFSET = 0xA,
        CC_OFFSET_SAVE = 0xB,
        DF_VERSION = 0xC,
        SET_FULLSLEEP = 0x10,
        STATIC_CHEM_CHECKSUM = 0x17,
        SEALED = 0x20,
        IT_ENABLE = 0x21,
        CAL_ENABLE = 0x2D,
        RESET = 0x41,
        EXIT_CAL = 0x80,
        ENTER_CAL = 0x81,
        OFFSET_CAL = 0x82,
        UNSEAL_KEY1 = 0x0414,
        UNSEAL_KEY2 = 0x3672
    } Control_2;
    
    
    // Define BQ34Z100 structure
    typedef struct {
    #define GAUGE_ADDRESS 0xAA
    
    #define DESIGNCAP 1400
    #define DESIGNENERGY 5180
    #define CELLCOUNT 0x04
    #define LEDCONFIG 0x4b
    #define VOLTSEL 1
    #define ZEROCHARGEVOLT 3375
    #define FLASH_UPDATE_OK_VOLT 2800
    #define QMAX0 1400
    
    
    #define VOLTAGEGAIN 17818
    #define LOADSELECT 0x01
    #define LOADMODE 0x00
    
    #define RESETVOLTAGE 22200 
    
    #define SENSE_RES 15.0f 
    
    #define USE_EXTERNAL_THERMISTOR 0 
                                        // Other member variables...
    } BQ34Z100;
    
    // Function to create a new instance of BQ34Z100
    // Function prototypes
    
    //BQ34Z100* BQ34Z100_create();
    //void BQ34Z100_destroy(BQ34Z100* bq34z100);
    
    
    uint32_t BQ34Z100_1_read(BQ34Z100* bq, Command command, const uint8_t length);
    void BQ34Z100_1_write(BQ34Z100* bq, Command command, const uint8_t cmd);
    void BQ34Z100_1_sendControlCommand(BQ34Z100* bq, Control_2 control);
    uint16_t BQ34Z100_1_readControlCommand(BQ34Z100* bq, Control_2 control);
    void BQ34Z100_write2(BQ34Z100* bq, Command command, const uint8_t cmd1, const uint8_t cmd2);
    
    void BQ34Z100_1_enableCal(BQ34Z100* bq);
    void BQ34Z100_1_enterCal(BQ34Z100* bq);
    void BQ34Z100_1_exitCal(BQ34Z100* bq);
    void BQ34Z100_1_ITEnable(BQ34Z100* bq);
    
    
    uint16_t getATTE(BQ34Z100* bq);
    uint16_t getATTF(BQ34Z100* bq);
    uint8_t getVoltScale(BQ34Z100* bq);
    uint8_t getCurrScale(BQ34Z100* bq);
    uint8_t getEnergyScale(BQ34Z100* bq);
    uint16_t getAvailableEnergy(BQ34Z100* bq);
    uint16_t getAvgPower(BQ34Z100* bq);
    uint16_t getChargeVoltage(BQ34Z100* bq);
    uint16_t getChargeCurrent(BQ34Z100* bq);
    uint16_t getGridNumber(BQ34Z100* bq);
    uint8_t BQ34Z100_1_getFull(BQ34Z100* bq);
    uint8_t getLearnedStatus(BQ34Z100* bq);
    uint8_t getDoDatEOC(BQ34Z100* bq);
    uint8_t getQstart(BQ34Z100* bq);
    uint16_t getTrueRC(BQ34Z100* bq);
    uint16_t getTrueFCC(BQ34Z100* bq);
    uint16_t getStateTime(BQ34Z100* bq);
    uint16_t getDOD0(BQ34Z100* bq);
    uint16_t getQmaxPassedQ(BQ34Z100* bq);
    uint16_t getQmaxDOD0(BQ34Z100* bq);
    uint16_t getQmaxTime(BQ34Z100* bq);
    uint16_t getAvgCurrent(BQ34Z100* bq);
    uint16_t getCC(BQ34Z100* bq);
    uint16_t BQ34Z100_1_getStatus(BQ34Z100* bq);
    uint16_t BQ34Z100_1_getChemID(BQ34Z100* bq);
    uint16_t BQ34Z100_1_getStateOfHealth(BQ34Z100* bq);
    uint8_t BQ34Z100_1_getSOC(BQ34Z100* bq);
    uint16_t BQ34Z100_1_getError(BQ34Z100* bq);
    uint16_t BQ34Z100_1_getRemaining(BQ34Z100* bq);
    uint16_t BQ34Z100_1_getVoltage(BQ34Z100* bq);
    int16_t BQ34Z100_1_getCurrent(BQ34Z100* bq);
    double BQ34Z100_1_getTemperature(BQ34Z100* bq);
    double BQ34Z100_1_getIntTemperature(BQ34Z100*bq);
    int BQ34Z100_1_getSerial(BQ34Z100* bq);
    void BQ34Z100_1_reset(BQ34Z100* bq);
    void BQ34Z100_1_unseal(BQ34Z100* bq);
    void BQ34Z100_1_seal(BQ34Z100* bq);
    void BQ34Z100_1_changePage(BQ34Z100* bq, char subclass, uint16_t offset);
    uint8_t BQ34Z100_1_calcChecksum();
    void BQ34Z100_1_updateChecksum(BQ34Z100* bq);
    void BQ34Z100_1_readFlash(BQ34Z100* bq);
    void BQ34Z100_1_writeFlash(BQ34Z100* bq, uint8_t index, uint32_t value, int len);
    uint8_t* BQ34Z100_1_getFlashBytes(BQ34Z100* bq);
    void BQ34Z100_1_changePage48(BQ34Z100* bq);
    void BQ34Z100_1_changePage64(BQ34Z100* bq);
    void BQ34Z100_1_changePage80(BQ34Z100* bq);
    void BQ34Z100_1_changePage82(BQ34Z100* bq);
    uint16_t BQ34Z100_1_calibrateVoltage(BQ34Z100* bq, uint16_t currentVoltage);
    void BQ34Z100_1_resetVoltageDivider(BQ34Z100* bq);
    uint32_t BQ34Z100_1_floatToXemics(float value);
    void BQ34Z100_1_calibrateShunt(BQ34Z100* bq, int16_t calCurrent);
    void BQ34Z100_1_setSenseResistor(BQ34Z100* bq);
    uint16_t BQ34Z100_1_readDeviceType(BQ34Z100* bq);
    uint16_t BQ34Z100_1_readFWVersion(BQ34Z100* bq);
    uint16_t BQ34Z100_1_readHWVersion(BQ34Z100* bq);
    float BQ34Z100_1_xemicsToFloat(uint32_t xemics);
    uint8_t BQ34Z100_1_getUpdateStatus(BQ34Z100* bq);
    uint16_t BQ34Z100_1_getFlags(BQ34Z100* bq);
    uint16_t BQ34Z100_1_getFlagsB(BQ34Z100* bq);
    
    
    
    #endif
    

    ERRORS:

     

    Console:


    **** Build of configuration Debug for project bq34z100r2 ****

    "C:\\ti\\ccs1220\\ccs\\utils\\bin\\gmake" -k -j 8 all -O

    Building target: "bq34z100r2.out"
    Invoking: MSP430 Linker
    "C:/ti/ccs1220/ccs/tools/compiler/ti-cgt-msp430_21.6.1.LTS/bin/cl430" -vmspx --data_model=restricted --near_data=none --use_hw_mpy=F5 --advice:power="all" --advice:hw_config="all" --define=__MSP430FR2155__ --define=_FRWP_ENABLE --define=_INFO_FRWP_ENABLE -g --rtti --cpp_default --plain_char=unsigned --printf_support=full --diag_warning=225 --diag_wrap=off --display_error_number --silicon_errata=CPU21 --silicon_errata=CPU22 --silicon_errata=CPU40 -z -m"bq34z100r2.map" --heap_size=160 --stack_size=160 --cinit_hold_wdt=on -i"C:/ti/ccs1220/ccs/ccs_base/msp430/include" -i"C:/ti/ccs1220/ccs/ccs_base/msp430/lib/FR2xx" -i"C:/ti/ccs1220/ccs/tools/compiler/ti-cgt-msp430_21.6.1.LTS/lib" -i"C:/ti/ccs1220/ccs/tools/compiler/ti-cgt-msp430_21.6.1.LTS/include" --priority --reread_libs --define=_FRWP_ENABLE --define=_INFO_FRWP_ENABLE --diag_wrap=off --display_error_number --warn_sections --xml_link_info="bq34z100r2_linkInfo.xml" --use_hw_mpy=F5 --rom_model -o "bq34z100r2.out" "./BQ34Z100.obj" "./main.obj" "../lnk_msp430fr2155.cmd" -lfrwp_init.a -llibc.a
    <Linking>
    warning #10229-D: output section ".data" refers to load symbol "_nop" and hence cannot be compressed; compression "lzss" is ignored

    undefined first referenced
    symbol in file
    --------- ----------------
    remark #10371-D: (ULP 1.1) Detected no uses of low power mode state changing instructions
    BQ34Z100_1_getStatus(BQ34Z100 *) ./main.obj
    remark #10372-D: (ULP 4.1) Detected uninitialized Port 6 in this project. Recommend initializing all unused ports to eliminate wasted current consumption on unused pins.
    remark #10372-D: (ULP 4.1) Detected uninitialized Port A in this project. Recommend initializing all unused ports to eliminate wasted current consumption on unused pins.
    remark #10372-D: (ULP 4.1) Detected uninitialized Port B in this project. Recommend initializing all unused ports to eliminate wasted current consumption on unused pins.
    remark #10372-D: (ULP 4.1) Detected uninitialized Port C in this project. Recommend initializing all unused ports to eliminate wasted current consumption on unused pins.
    remark #10422-D: (ULP 6.2) Detected use of a device with available 32-bit hardware multiplier and not also using MSPMATHLIB library (libmath.a). Recommend using MSPMATHLIB library (libmath.a) for improved performance.

    >> Compilation failure
    makefile:137: recipe for target 'bq34z100r2.out' failed

    error #10234-D: unresolved symbols remain
    error #10010: errors encountered during linking; "bq34z100r2.out" not built
    gmake[1]: *** [bq34z100r2.out] Error 1
    makefile:133: recipe for target 'all' failed
    gmake: *** [all] Error 2

    **** Build Finished ****

    Please help me sort these issues out. 

    Thanks in advance!

  • The header file says BQ34Z100_1_getStatus() expects a "BQ34Z100 *" but the definition says it expects a "BQ34Z100_1 *", where the latter is private to the source file.

    I wonder if there's a source code mis-match somewhere.

    Did you get any messages from the compiler when you compiled BQ34Z100.c?

  • Did you get any messages from the compiler when you compiled BQ34Z100.c?

    These were the messages I got when I compiled BQ34Z100.c

  • I'm guessing the source file was named BQ34Z100.cpp, which allowed you to compile a (second) set of functions with the same names as in the header, but with different signatures. But since they expect BQ34Z100_1 structures, you can't call them since the BQ34Z100_1 structure isn't visible outside the .cpp file.

    I'm still not sure I see how this was supposed to fit together,. Were there any suggestions how to use this code? I've only been able to find Arduino-based libraries.

  • So the original file i had was a .cpp file which I later converted to a .c file. Would creating another structure with the same parameters as those in the .cpp file work?

    Or if any other suggestion on how could I solve this problem? 

  • One way would be to move the BQ34Z100_1 structure declaration (as well as the I2C structure) to the header file -- so it's visible -- and have main use that.

    You would have to also change all the function prototypes [you could start with just BQ34Z100_1_getStatus() as an experiment] to match those in the .cpp file. 

    Or you could go the other way, and change everything to use the BQ34Z100 structure, but that's probably more typing.

  • Oh thank you for your suggestion. It is working now.

    I will be testing it in a few days, will get back to you if any issues are there. 

    Once again thank you!

**Attention** This is a public forum