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.

BQ76PL455A-Q1: CCS/BQ76PL455EVM: Sample code for TMS57004 and Tiva C Series TM4C123G

Part Number: BQ76PL455A-Q1
Other Parts Discussed in Thread: BQ76PL455EVM

Hello,

I have designed on the same PCB 2x16 cells BMS module using two BQ76PL455 ICs with Tiva C Series TM4C123G MCU. in the design part everything was done by your guiding documents. I know that you have already made a sample code with TMS570004 but I am trying to convert your shared code for Tiva.
right now I am trying to complete the code part for Bq76pl455 however I have some questions and hopefully through this forum I can get regarding answers by your help as quickly as possible.

questions:

1-) I have read some people comment on the sample code TMS570004 and BQ76PL455EVM problem that they had faced during coding. if I am not mistaken in the one of forum you were saying that the code which we shared is just skeleton and you have to rearrange it have not you? do I understand correctly? if that it is can you share with me what steps I should follow? I mean I have already checked bq76PL455A-Q1 Software Design Reference and other datasheets out yet I need a flowchart of code which I can sticky with that.

2) for beginning just to see communication, respond and debug, I would not connect batteries to the System, so I am planning to power up separately both of ICs in the stack by supplying Vp,VDIG and VIO pins regarding voltage values (if there are other pins to supply power please let me know).  however I am very attentive to not cause any error that by connections. that's why when considering this setup can you please help me to illustrate the system I want to build?

please let me know you what you think of?

I do need to complete this project as soon as possible

Thank you for your understanding 
Best Regards
Mahmut Demiryent

  • Hi Mahmut,

    I will try to resolve your questions:

    1. Yes the code is a skeleton code that you can use to build your system on top of. In fact this is just mainly a driver for the BQ76PL455 device. As you can notice from the project, the pl455.c is a sample code for device communication between the BQ device and the MCU. However if you look into the sys_main.c file there we actually setup an example system and perform some basic communication with the BQ device in order to configure it and read data from it. You can use this file (please look at the comments) as a flowchart of the code execution.

    2. In order for me to answer this question, I need to know what hardware are you using? Are you connecting to the BQ76PL455EVM (https://www.ti.com/tool/BQ76PL455EVM) ?

    You can find more information about the hardware setup in the EVM user's guide (https://www.ti.com/lit/pdf/sluuba7)

    Regards,

    Viktor.

  • Hi Viktor 

    Thank you for reply, 

    to first answer:

    to be honest I have already cheked many comments which refer to this device, but if you know some related comments that discussed before can you share with those forum links? I totally undersatnd what you have done in the code yet I still need to get a flowchart for following exactly steps and not to make any errors. 


    for the second question:

    I do not use BQ76PL455EVM rather I have already designed my own PCB card with integrated two Bq76pl455 ICs on single pcb card. if you need I can provide you a picture of it in a private message or in a email. so in my card everything is assembled according to your reference design documents such as gerber file etc.

    hope this works 

    best regards
    Mahmut

  • Hi Mahmut,

    Please send a "Request Friendship" message and I will add you, that way we can privately exchange messages.

    Regards,

    Viktor.

  • Hi 

    unfortunately, I still can not connect to BQ76PL455 with Tiva C series launchpad. I have some questions mostly on software please let me know to solve them.

    1-) I do not understand how and where to implement TXHOLDOFF 18  // UART TRANSMITTER HOLDOFF register on? I suppose that maybe I have problem on communication because of that can you please tell me how important is that to using this register and how to integrate with code?


    2-) I follow your sample code to wakeup BQ device but is there any sign that I will get from BQ to understand that it wakeup and ready for next section?

    3-) another point which I suspect for unable to communicate is I do not power my system with battery stack rather I just give an external power (giving power to VP pin with 5.3V and feeding VDIG pin with the same manner also VIO is driven with 3.3V)  that share its ground with board. I am less suspicious with this point however can you please help me on connecting with first BQ on the board.

    my code so far for UART communication:

    void UART_Init( uint32_t baud ){

    // Peripheral driver dokumanda verilen Uart'a ait kod ornegi neden seninki gibi degil?

    //BT
    SysCtlPeripheralEnable( PERIPH_GPIO_UART_BT );//PERIPH_GPIO_UART_BT SYSCTL_PERIPH_GPIOC
    GPIOPinConfigure( CONF_GPIO_UART_BT_TX );//CONF_GPIO_UART_BT_TX GPIO_PC5_U1TX
    GPIOPinConfigure( CONF_GPIO_UART_BT_RX );//CONF_GPIO_UART_BT_RX GPIO_PC4_U1RX
    GPIOPinTypeUART( BASE_GPIO_UART_BT, PIN_GPIO_UART_BT_TX | PIN_GPIO_UART_BT_RX );//PIN_GPIO_UART_BT_RX GPIO_PIN_4
    //PIN_GPIO_UART_BT_TX GPIO_PIN_5
    SysCtlPeripheralEnable( PERIPH_UART_BT );//PERIPH_UART_BT SYSCTL_PERIPH_UART1
    UARTDisable( BASE_UART_BT );//BASE_UART_BT UART1_BASE
    UARTClockSourceSet( BASE_UART_BT, UART_CLOCK_PIOSC );
    UARTConfigSetExpClk( BASE_UART_BT, 16000000, baud, UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE );
    UARTIntRegister( BASE_UART_BT, IntUartBluetooth );
    UARTIntEnable( BASE_UART_BT, UART_INT_RX | UART_INT_RT );
    UARTEnable( BASE_UART_BT);
    IntEnable( INT_UART_BT );//INT_UART_BT INT_UART1
    }

    void sendUartString(uint32_t base, const char * data)
    {
    while (*data != '\0')
    {
    if (UARTSpaceAvail(base))
    {
    while (!UARTCharPutNonBlocking(base, *data));

    data++;
    }
    }
    }

    int WriteReg(BYTE bID, uint16_t wAddr, uint64_t dwData, BYTE bLen, BYTE bWriteType)
    {
    int bRes = 0;
    BYTE bBuf[8] = {0, 0, 0, 0, 0, 0, 0};
    switch(bLen)
    {
    case 1:
    bBuf[0] = dwData & 0x00000000000000FF;
    bRes = WriteFrame(bID, wAddr, bBuf, 1, bWriteType);
    break;
    case 2:
    bBuf[0] = (dwData & 0x000000000000FF00) >> 8;
    bBuf[1] = dwData & 0x00000000000000FF;
    bRes = WriteFrame(bID, wAddr, bBuf, 2, bWriteType);
    break;
    case 3:
    bBuf[0] = (dwData & 0x0000000000FF0000) >> 16;
    bBuf[1] = (dwData & 0x000000000000FF00) >> 8;
    bBuf[2] = dwData & 0x00000000000000FF;
    bRes = WriteFrame(bID, wAddr, bBuf, 3, bWriteType);
    break;
    case 4:
    bBuf[0] = (dwData & 0x00000000FF000000) >> 24;
    bBuf[1] = (dwData & 0x0000000000FF0000) >> 16;
    bBuf[2] = (dwData & 0x000000000000FF00) >> 8;
    bBuf[3] = dwData & 0x00000000000000FF;
    bRes = WriteFrame(bID, wAddr, bBuf, 4, bWriteType);
    break;
    case 5:
    bBuf[0] = (dwData & 0x000000FF00000000) >> 32;
    bBuf[1] = (dwData & 0x00000000FF000000) >> 24;
    bBuf[2] = (dwData & 0x0000000000FF0000) >> 16;
    bBuf[3] = (dwData & 0x000000000000FF00) >> 8;
    bBuf[4] = dwData & 0x00000000000000FF;
    bRes = WriteFrame(bID, wAddr, bBuf, 5, bWriteType);
    break;
    case 6:
    bBuf[0] = (dwData & 0x0000FF0000000000) >> 40;
    bBuf[1] = (dwData & 0x000000FF00000000) >> 32;
    bBuf[2] = (dwData & 0x00000000FF000000) >> 24;
    bBuf[3] = (dwData & 0x0000000000FF0000) >> 16;
    bBuf[4] = (dwData & 0x000000000000FF00) >> 8;
    bBuf[5] = dwData & 0x00000000000000FF;
    bRes = WriteFrame(bID, wAddr, bBuf, 6, bWriteType);
    break;
    case 7:
    bBuf[0] = (dwData & 0x00FF000000000000) >> 48;
    bBuf[1] = (dwData & 0x0000FF0000000000) >> 40;
    bBuf[2] = (dwData & 0x000000FF00000000) >> 32;
    bBuf[3] = (dwData & 0x00000000FF000000) >> 24;
    bBuf[4] = (dwData & 0x0000000000FF0000) >> 16;
    bBuf[5] = (dwData & 0x000000000000FF00) >> 8;
    bBuf[6] = dwData & 0x00000000000000FF;;
    bRes = WriteFrame(bID, wAddr, bBuf, 7, bWriteType);
    break;
    case 8:
    bBuf[0] = (dwData & 0xFF00000000000000) >> 56;
    bBuf[1] = (dwData & 0x00FF000000000000) >> 48;
    bBuf[2] = (dwData & 0x0000FF0000000000) >> 40;
    bBuf[3] = (dwData & 0x000000FF00000000) >> 32;
    bBuf[4] = (dwData & 0x00000000FF000000) >> 24;
    bBuf[5] = (dwData & 0x0000000000FF0000) >> 16;
    bBuf[6] = (dwData & 0x000000000000FF00) >> 8;
    bBuf[7] = dwData & 0x00000000000000FF;
    bRes = WriteFrame(bID, wAddr, bBuf, 8, bWriteType);
    break;
    default:
    break;
    }
    return bRes;
    }

    int main(void)
    {
    SysCtlClockSet( SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ );

    initHandle();
    UART_Init(BAUDRATE);

    WakePL455();

    CommClear();

    CommReset();

    int nSent, nRead, nTopFound = 0;
    int nDev_ID, nGrp_ID;
    BYTE bFrame[132];//our data will be stored in this array, which you can view in the Variables window.
    //uint32_t wTemp = 0;

    /* first things to do:
    * preconfigured with device addresses, communication timeout, and power-down settings

    */

    // Wake all devices
    // The wake tone will awaken any device that is already in shutdown and the pwrdown will shutdown any device
    // that is already awake. The least number of times to sequence wake and pwrdown will be half the number of
    //boards to cover the worst case combination of boards already awake or shutdown.
    for(nDev_ID = 0; nDev_ID < TOTALBOARDS>>1 ; nDev_ID++) { //
    WriteReg(nDev_ID, 12, 0x40, 1, FRMWRT_ALL_NR); // send out broadcast pwrdown command
    SysCtlClockSet(SysCtlClockGet()/200);
    WakePL455();
    SysCtlClockSet(SysCtlClockGet()/200);
    }

    // Mask Customer Checksum Fault bit
    nSent = WriteReg(0, 107, 0x8000, 2, FRMWRT_ALL_NR); // clear all fault summary flags

    // Clear all faults
    nSent = WriteReg(0, 82, 0xFFC0, 2, FRMWRT_ALL_NR); // clear all fault summary flags
    nSent = WriteReg(0, 81, 0x38, 1, FRMWRT_ALL_NR); // clear fault flags in the system status register

    // nDev_ID = 0;
    // nSent = WriteReg(nDev_ID,16, 0x10E0, 2, FRMWRT_ALL_NR); // set communications baud rate as 250KBaud

    // int bitPos = 7;
    // int tse;
    //
    // tse &= ~(1<<7);
    //
    //
    // nSent = WriteReg(nDev_ID, 96, tse, 1, FRMWRT_SGL_NR);

    nSent = WriteReg(nDev_ID,14, 0x19, 1, FRMWRT_ALL_NR);

    nSent = WriteReg(nDev_ID, 12, 0x08, 1, FRMWRT_ALL_NR); // Auto Address enable

    uint8_t wTemp, wTemp1;
    // Set addresses for all boards in daisy-chain (section 1.2.3)
    for (nDev_ID = 0; nDev_ID < TOTALBOARDS; nDev_ID++)
    {
    nSent = WriteReg(nDev_ID, 10, nDev_ID, 1, FRMWRT_ALL_NR); // send address to each board
    }

    nDev_ID = 0;
    nSent = WriteReg(nDev_ID,16, 0x10E0, 2, FRMWRT_ALL_NR); // set communications baud rate as 250KBaud

    // read device ID to see if there is a response
    nDev_ID = 0;
    nRead = ReadReg(nDev_ID, 10, &wTemp, 1, 0); // 0ms timeout
    printf("Device id 0 : %d\r\n", wTemp);

    nDev_ID = 1;
    nRead = ReadReg(nDev_ID, 10, &wTemp1, 1, 0); // 0ms timeout
    printf("Device id 1 : %d\r\n", wTemp1);

    // Clear all faults (section 1.2.7)
    nSent = WriteReg(0, 82, 0xFFC0, 2, FRMWRT_ALL_NR); // clear all fault summary flags
    nSent = WriteReg(0, 81, 0x38, 1, FRMWRT_ALL_NR); // clear fault flags in the system status register

    int WriteFrame(BYTE bID, uint16_t wAddr, BYTE * pData, BYTE bLen, BYTE bWriteType)
    {
    int bPktLen = 0;
    BYTE pFrame[32];
    BYTE * pBuf = pFrame;
    uint16_t wCRC;

    if (bLen == 7 || bLen > 8)
    return 0;

    memset(pFrame, 0x7F, sizeof(pFrame));

    if (wAddr > 255) {
    *pBuf++ = 0x88 | bWriteType | bLen; // use 16-bit address
    if (bWriteType == FRMWRT_SGL_R || bWriteType == FRMWRT_SGL_NR || bWriteType == FRMWRT_GRP_R || bWriteType == FRMWRT_GRP_NR)//(bWriteType != FRMWRT_ALL_NR)// || (bWriteType != FRMWRT_ALL_R))
    {
    *pBuf++ = (bID & 0x00FF);
    }
    *pBuf++ = (wAddr & 0xFF00) >> 8;
    *pBuf++ = wAddr & 0x00FF;
    }
    else {
    *pBuf++ = 0x80 | bWriteType | bLen; // use 8-bit address FRMWRT_ALL_NR
    if (bWriteType == FRMWRT_SGL_R || bWriteType == FRMWRT_SGL_NR || bWriteType == FRMWRT_GRP_R || bWriteType == FRMWRT_GRP_NR)
    {
    *pBuf++ = (bID & 0x00FF);
    }
    *pBuf++ = wAddr & 0x00FF;
    }

    while(bLen--)
    *pBuf++ = *pData++;

    bPktLen = pBuf - pFrame;

    wCRC = CRC16(pFrame, bPktLen);
    *pBuf++ = wCRC & 0x00FF;
    *pBuf++ = (wCRC & 0xFF00) >> 8;
    bPktLen += 2;

    sendUartString(BASE_UART_BT, (char *)&pFrame);
    //sciSend(scilinREG, bPktLen, pFrame);

    return bPktLen;
    }