MSPM0G3519: Flash error during debugging or running the application

Part Number: MSPM0G3519

Hello,

I am compiling a code, where I am receiving request and sending the response over uart. When I am changing the code, for some of the values of ACTIVE_CELLS the code is running fine, where as some other values, it is giving flash error.

File Loader: Memory write failed: Flash loader exited with flash error.
GEL: File: C:\Users\dibyarekha\workspace_ccstheia\Test_Packet_Transfer_mobileApp\Debug\Test_Packet_Transfer_mobileApp.out: Load failed. 

 

The above error I am getting, when I am changing the ACTIVE_CELLS below 12. 

If I am calling both the functions then only its happening, but both the functions are not simultaneously called, its called on request basis,

the 2 functions are 

Send_Dashboard_Pkt() and 
Send_CellDetails_Packet(). is there any problem to use uart?
 
here with I am attaching the code. please tell me where is the problem?
#include <ti/driverlib/m0p/dl_interrupt.h>
#include "ti_msp_dl_config.h"
#include <string.h>


#pragma pack(1)
typedef struct
{
    uint8_t startByte;
    uint8_t length;
    uint8_t dataID;
    uint8_t crc;
    uint8_t stopByte;
}HANDSHAKE_PACKET_t;
#pragma pack()

#pragma pack(1)
typedef struct
{
    uint8_t startByte;
    uint8_t length;
    uint8_t dataID;
    uint8_t crc;
    uint8_t stopByte;
}ACK_PACKET_t;
#pragma pack()

void Send_VtgSOC_Packet(void);
uint8_t Calculate_CRC8(uint8_t *data, uint16_t length);
void UART1_SendBytes(uint8_t *data, uint16_t length);
void Send_CellVoltagePackets(uint16_t *cellVoltages, uint8_t numberOfCells);
void Send_Dashboard_Pkt(void);
void Send_BLEName_Packet();
void Send_CellDetails_Packet(void);


uint8_t Calculate_CRC8(uint8_t *data, uint16_t length)
{
    uint8_t crc = 0x00;
    for(uint16_t i = 0; i < length; i++)
    {
        crc ^= data[i];
        for(uint8_t j = 0; j < 8; j++)
        {
            if(crc & 0x80)
            {
                crc = (crc << 1) ^ 0x07;
            }
            else
            {
                crc <<= 1;
            }
        }
    }
    return crc;
}

void UART0_SendBytes(uint8_t *data, uint16_t length)
{
    for(uint16_t i = 0; i < length; i++)
    {
        DL_UART_Main_transmitDataBlocking(UART_0_INST, data[i]);
    }
}

void UART0_PrintHex(uint8_t *data, uint16_t length)
{
    char hexString[5];

    for(uint16_t i = 0; i < length; i++)
    {
        sprintf(hexString, "%02X ", data[i]);

        UART0_SendBytes((uint8_t*)hexString, strlen(hexString));
    }

    UART0_SendBytes((uint8_t*)"\r\n", 2);
    delay_cycles(8000000);
}


void UART1_SendBytes(uint8_t *data, uint16_t length)
{
    for(uint16_t i = 0; i < length; i++)
    {
        DL_UART_Main_transmitDataBlocking(UART_1_INST, data[i]);
    }
}

void UART1_PrintHex(uint8_t *data,  uint16_t length)
{
    char hexString[5];

    for(uint16_t i = 0; i < length; i++)
    {
        sprintf(hexString, "%02X ", data[i]);

        UART1_SendBytes((uint8_t*)hexString, strlen(hexString));
    }

    UART1_SendBytes((uint8_t*)"\r\n", 2);
}

#if 1
#define MAX_PACKET_SIZE     20
#define MAX_PACKET_QUEUE    10

volatile uint8_t packetQueue [MAX_PACKET_QUEUE] [MAX_PACKET_SIZE];
volatile uint8_t packetLengths [MAX_PACKET_QUEUE];
volatile uint8_t queueWriteIndex = 0;
volatile uint8_t queueReadIndex = 0;
volatile uint8_t packetCount = 0;

volatile uint8_t tempBuffer [MAX_PACKET_SIZE];
volatile uint8_t rxIndex = 0;
volatile uint8_t expectedLength = 0;
volatile bool packetStarted = false;
void Update_Battery_Data(void);

void UART_1_INST_IRQHandler(void)
{
    uint8_t rxData;
    switch(DL_UART_Main_getPendingInterrupt(UART_1_INST))
    {
        case DL_UART_MAIN_IIDX_RX:

            rxData =  DL_UART_Main_receiveData(UART_1_INST);
            /* WAIT FOR START */
            if(packetStarted == false)
            {
                if(rxData == 0xCC)
                {
                    packetStarted = true;
                    rxIndex = 0;
                    expectedLength = 0;
                    tempBuffer[rxIndex++] = rxData;
                }
            }

            /* RECEIVE PACKET */
            else
            {
                tempBuffer[rxIndex++] = rxData;
                /* LENGTH BYTE */
                if(rxIndex == 2)
                {
                    expectedLength = rxData;
                    /* SAFETY */
                    if(expectedLength < 5 || expectedLength > MAX_PACKET_SIZE)
                    {
                        packetStarted = false;
                        rxIndex = 0;
                    }
                }
                /* FULL PACKET */
                if(rxIndex >= expectedLength)
                {
                    /* VERIFY STOP BYTE */
                    if(tempBuffer[expectedLength - 1] == 0xDD)
                    {
                        /* STORE INTO QUEUE */
                        if(packetCount <  MAX_PACKET_QUEUE)
                        {
                            memcpy((void*)packetQueue[queueWriteIndex],(void*)tempBuffer,expectedLength);

                            packetLengths[queueWriteIndex] = expectedLength;
                            queueWriteIndex++;
                            if(queueWriteIndex >=  MAX_PACKET_QUEUE)
                            {
                                queueWriteIndex = 0;
                            }
                            packetCount++;
                        }
                    }
                    packetStarted = false;
                    rxIndex = 0;
                }
            }
            break;
    }
}
void Send_ACK_Packet(void)
{
    ACK_PACKET_t ackPacket;
    ackPacket.startByte = 0xAA;
    ackPacket.length = 0x05;
    ackPacket.dataID = 0x50;
    ackPacket.stopByte = 0xBB;
    ackPacket.crc = Calculate_CRC8((uint8_t*) &ackPacket.length, 2);

    UART1_SendBytes((uint8_t*) &ackPacket, sizeof(ACK_PACKET_t));
    UART0_PrintHex((uint8_t*) &ackPacket, sizeof(ACK_PACKET_t));
}



uint16_t Calculate_CRC16(uint8_t *data, uint16_t length)
{
    uint16_t crc = 0xFFFF;
    for(uint16_t i = 0; i < length; i++)
    {
        crc ^= ((uint16_t)data[i] << 8);
        for(uint8_t j = 0; j < 8; j++)
        {
            if(crc & 0x8000)
            {
                crc = (crc << 1) ^ 0x1021;
            }
            else
            {
                crc <<= 1;
            }
        }
    }
    return crc;
}

#define ACTIVE_CELLS     10 // Change to 6, 8, 12, 16, 20, 24 etc.


uint16_t cellVoltages[24] = {0};
uint8_t balancingStatus[24] = {0};


#pragma pack(1)
typedef struct
{
    uint8_t  startByte;                 // Byte 0
    uint8_t  length;                    // Byte 1
    uint8_t  dataID;                    // Byte 2
   
    char Bat_Type[17];                    // Byte 45-58
    char batterySerialNo[16];           // Byte 3-16
    uint8_t  soc;                       // Byte 59
    uint8_t  batteryStatus;             // Byte 60
    uint16_t remainingCapacity;         // Byte 61-62
    uint16_t chargeDischargeCycles;     // Byte 73-74
    uint8_t  health;                    // Byte 63
    uint16_t totalVoltage;              // Byte 64-65
    uint16_t  totalCurrent;              // Byte 66-67
    int16_t  temperature;              // Byte 68-69
    uint16_t  powerKW;                   // Byte 70-71
    uint8_t  totalCells;                // Byte 72
    uint16_t cellVoltage[24];
    uint16_t avgVoltage;                // Byte 75-76
    uint16_t voltageDifference;         // Byte 77-78
    uint16_t maxVoltage;                // Byte 79-80
    uint16_t minVoltage;                // Byte 81-82
      
    char warning_alerts;
    char fault_alerts;
    char cleared_alerts;
    char total_alert_notf;
    uint16_t crc;                       // Byte 83-84
    uint8_t  stopByte;                  // Byte 85

}BMS_DASHBOARD_PKT_t;
#pragma pack()

#pragma pack(1)
typedef struct
{
    uint8_t  startByte;                 // Byte 0
    uint8_t  length;                    // Byte 1
    uint8_t  dataID;                    // Byte 2
    char BLE_Name[16];                  // Byte 3 - 18
    uint8_t crc;                       // Byte 19
    uint8_t  stopByte;                  // Byte 20

}BLE_NAME_PKT_t;
#pragma pack()



void Send_BLEName_Packet()
{
    BLE_NAME_PKT_t Ble_name_pkt;
    Ble_name_pkt.startByte = 0xAA;
    Ble_name_pkt.length = sizeof(BLE_NAME_PKT_t);
    Ble_name_pkt.dataID = 0x51;
    char ble_name[16]= "MCH_BAT_1AF00002";
    memcpy(Ble_name_pkt.BLE_Name, ble_name, sizeof(Ble_name_pkt.BLE_Name));
    Ble_name_pkt.stopByte = 0xBB;
    Ble_name_pkt.crc = Calculate_CRC8((uint8_t*)&Ble_name_pkt.length, sizeof(BLE_NAME_PKT_t) - 3);
    UART1_SendBytes((uint8_t*)&Ble_name_pkt, sizeof(BLE_NAME_PKT_t));
    UART0_PrintHex((uint8_t*)&Ble_name_pkt, sizeof(BLE_NAME_PKT_t));

}

// code to test the dashboard page by sending continuous data


void Dashboard_Test_Update(BMS_DASHBOARD_PKT_t *pkt);

static uint8_t dashboardSOC = 0;
static uint8_t dashboardCharging = 1;
static uint16_t dashboardCycleCount = 0;

void Dashboard_Test_Update(BMS_DASHBOARD_PKT_t *pkt)
{
    uint8_t i;
    uint32_t sum = 0;
    uint16_t minV = 6000;
    uint16_t maxV = 0;
    uint16_t cellV;

    /* SOC */

    if(dashboardCharging)
    {
        pkt->batteryStatus = 0x01;

        if(dashboardSOC < 100)
        {
            dashboardSOC += 5;
        }
        else
        {
            dashboardCharging = 0;
        }
    }
    else
    {
        pkt->batteryStatus = 0x03;

        if(dashboardSOC > 0)
        {
            dashboardSOC -= 5;
        }
        else
        {
            dashboardCharging = 1;
            dashboardCycleCount++;
        }
    }

    pkt->soc = dashboardSOC;
    pkt->remainingCapacity = dashboardSOC;

    for(i = 0; i < ACTIVE_CELLS; i++)
    {
        cellV = 2000 + ((3000UL * dashboardSOC) / 100);
        cellV += (i % 5) * 50;

        pkt->cellVoltage[i] = cellV;

        sum += cellV;

        if(cellV < minV)
            minV = cellV;

        if(cellV > maxV)
            maxV = cellV;
    }
    for (i = ACTIVE_CELLS; i < 24; i++)
    {

    pkt->cellVoltage[i] = 0;

    }
    pkt->avgVoltage = sum / ACTIVE_CELLS;
    pkt->minVoltage = minV;
    pkt->maxVoltage = maxV;
    pkt->voltageDifference = maxV - minV;

    if((minV < 3200) || ((maxV - minV) > 300))
        pkt->health = 0x02;
    else
        pkt->health = 0x01;

    pkt->totalVoltage =
        ((uint32_t)pkt->avgVoltage * ACTIVE_CELLS) / 100;

    pkt->totalCurrent =
        (pkt->batteryStatus == 0x01) ?
        (dashboardSOC * 10) :
        (dashboardSOC * 8);

    pkt->powerKW =
        ((uint32_t)pkt->totalVoltage *
         pkt->totalCurrent) / 1000;

    pkt->temperature = 250;

    pkt->totalCells = ACTIVE_CELLS;
    pkt->chargeDischargeCycles = dashboardCycleCount;

    pkt->warning_alerts = (pkt->health == 0x02) ? 0x02 : 0x00;
    pkt->fault_alerts = 0;
    pkt->cleared_alerts = 0;
    pkt->total_alert_notf = pkt->warning_alerts;

    pkt->stopByte = 0xBB;
}
static BMS_DASHBOARD_PKT_t dashboard_pkt;

void Send_Dashboard_Pkt(void)
{
   // BMS_DASHBOARD_PKT_t dashboard_pkt;
    memset(&dashboard_pkt, 0, sizeof(dashboard_pkt));
    dashboard_pkt.startByte = 0xAA;
    dashboard_pkt.length = sizeof(BMS_DASHBOARD_PKT_t);
    dashboard_pkt.dataID = 0x52;

    char bat_type[17] = "14S30Ah_LiHV_3.8V";
    memcpy(dashboard_pkt.Bat_Type, bat_type, sizeof(dashboard_pkt.Bat_Type));

    char batterySN[16] = "CHP5810262400001";
    memcpy(dashboard_pkt.batterySerialNo, batterySN, sizeof(dashboard_pkt.batterySerialNo));
   
    Dashboard_Test_Update(&dashboard_pkt);
    dashboard_pkt.crc               = Calculate_CRC16((uint8_t *)&dashboard_pkt.length, sizeof(BMS_DASHBOARD_PKT_t) - 5);   // Byte 83-84
    UART1_SendBytes((uint8_t *)&dashboard_pkt, sizeof(BMS_DASHBOARD_PKT_t));
    UART0_PrintHex((uint8_t *)&dashboard_pkt, sizeof(BMS_DASHBOARD_PKT_t));
    delay_cycles(8000000);

}

#pragma pack(1)

typedef struct
{
    uint16_t voltage;      // 2 bytes
    uint8_t  balancing;    // 1 byte
} CELL_INFO_t;

typedef struct
{
    uint8_t  startByte;             // Byte 0
    uint8_t  length;                // Byte 1
    uint8_t  dataID;                // Byte 2
    uint16_t maxVoltage;            // Byte 3-4
    uint8_t  maxVoltageCellNo;      // Byte 5
    uint16_t minVoltage;            // Byte 6-7
    uint8_t  minVoltageCellNo;      // Byte 8
    uint16_t avgVoltage;            // Byte 9-10
    uint8_t  balancingStatus;       // Byte 11
    uint8_t  totalCells;            // Byte 12
    CELL_INFO_t cell[24];           // Byte 13 onwards
    uint16_t crc;
    uint8_t  stopByte;

} CELL_DETAILS_PACKET_t;

#pragma pack()


static CELL_DETAILS_PACKET_t packet;

void Send_CellDetails_Packet(void)
{
    uint8_t i;
    uint32_t sumVoltage = 0;

    uint16_t maxVoltage = 0;
    uint16_t minVoltage = 5000;

    uint8_t maxCellNo = 1;
    uint8_t minCellNo = 1;

    static uint16_t baseVoltage = 2000;

    memset(&packet, 0, sizeof(packet));

    packet.startByte = 0xAA;
    packet.length    = sizeof(CELL_DETAILS_PACKET_t);
    packet.dataID    = 0x53;

    packet.balancingStatus = 0x02;

    /* Change voltages every call */

    baseVoltage += 100;

    if(baseVoltage > 5000)
    {
        baseVoltage = 2000;
    }

    /* Active Cells */

    for(i = 0; i < ACTIVE_CELLS; i++)
    {
        packet.cell[i].voltage =
            baseVoltage + ((i % 5) * 50);

        if(packet.cell[i].voltage > 5000)
        {
            packet.cell[i].voltage = 5000;
        }

        packet.cell[i].balancing =
            ((i % 4) == 0) ? 0x01 : 0x02;

        if(packet.cell[i].balancing == 0x01)
        {
            packet.balancingStatus = 0x01;
        }

        sumVoltage += packet.cell[i].voltage;

        if(packet.cell[i].voltage > maxVoltage)
        {
            maxVoltage = packet.cell[i].voltage;
            maxCellNo = i + 1;
        }

        if(packet.cell[i].voltage < minVoltage)
        {
            minVoltage = packet.cell[i].voltage;
            minCellNo = i + 1;
        }
    }

    /* Remaining Cells = 0 */
    for(i = ACTIVE_CELLS; i < 24; i++)
    {
        packet.cell[i].voltage = 0;
        packet.cell[i].balancing = 0;
    }

    packet.maxVoltage = maxVoltage;
    packet.maxVoltageCellNo = maxCellNo;

    packet.minVoltage = minVoltage;
    packet.minVoltageCellNo = minCellNo;
   
    packet.avgVoltage = (uint16_t)(sumVoltage / ACTIVE_CELLS);
    packet.totalCells = ACTIVE_CELLS;
    packet.stopByte = 0xBB;

    packet.crc = Calculate_CRC16((uint8_t *)&packet.length, sizeof(CELL_DETAILS_PACKET_t) - 5);
    UART1_SendBytes((uint8_t *)&packet, sizeof(CELL_DETAILS_PACKET_t));
    UART0_PrintHex((uint8_t *)&packet,  sizeof(CELL_DETAILS_PACKET_t));
   delay_cycles(8000000);
}

void ProcessPacket(uint8_t *packet, uint8_t length)
{
    uint8_t calculatedCRC;
    uint8_t receivedCRC =  packet[length - 2];
    /* CRC VALIDATION */
    calculatedCRC = Calculate_CRC8( &packet[1],length - 3);
    if(calculatedCRC != receivedCRC)
    {
        return;
    }

    /* PACKET ID */
    uint8_t packetID = packet[2];
    switch(packetID)
    {
        case 0x90:
            /* HANDSHAKE PACKET */
            Send_ACK_Packet();    
            delay_cycles(8000000);
            if(DL_GPIO_readPins(GPIOB, DL_GPIO_PIN_31))
                DL_GPIO_setPins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
            delay_cycles(32000000);
           // Send_VtgSOC_Packet();      
            break;

        case 0x91:
            /* Disconnect Packet */
           // Process_OTA_Start();          
           UART0_PrintHex(packet, length);          
           break;
           
        case 0x92:
            Send_BLEName_Packet();
            break;
           
        case 0x93:          
            Send_Dashboard_Pkt();
            delay_cycles(8000000);
            break;

        case 0x94:
            Send_CellDetails_Packet();
            delay_cycles(8000000);
            break;

        default:
            /* UNKNOWN PACKET */
            break;
    }
}

int main(void)
{
    SYSCFG_DL_init();
    NVIC_EnableIRQ(UART_1_INST_INT_IRQN);   
   delay_cycles(32000000);
    while(1)
    {
        if(packetCount > 0)
        {
            ProcessPacket((uint8_t*)packetQueue[queueReadIndex],packetLengths[queueReadIndex]);
            /* REMOVE PACKET */
            queueReadIndex++;
            if(queueReadIndex >= MAX_PACKET_QUEUE)
            {
                queueReadIndex = 0;
            }
            packetCount--;
        }
        if(DL_GPIO_readPins(GPIOB, DL_GPIO_PIN_31))
                DL_GPIO_setPins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
        //if(DL_GPIO_readPins(GPIOB, DL_GPIO_PIN_31) == 0) // here pin checking is not working , but in main while loop its working    
        else
            DL_GPIO_clearPins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
       
     
        delay_cycles(64000000);  
       
    }
}
#endif
  • Hello Dibyarekha,

    Your whole code is too much, we can't help you to review your code byte by byte. Please narrow down the error to min function module through entering debug mode to debug. 

    By the way, the error "Memory write failed" seems like it occurs when you download code into Flash? 

    BR,

    Janz Bai

  • Hi Janz,

    Yes I am receiving the error, while flashing the code. But this is not happening everytime. Basically my code is to communicate through uart to GUI. When I receive request I am sending packets over uart. I have 2 requests, for 2 requests there will be 2 functions, in both the functions I have used a macro ACTIVE_CELLS. The code is running fine with the ACTIVE_CELLS value from 12 to 24. My range is 1 to 24. When I am using any number between 1 to 11 , it's giving flashing error. Instead of taking macro, I tried to use char variable, for that the code is not at all flashing. where is the problem I am not understanding. Where as If I am using separately 1 by 1 function then for all values its running fine. I will getting 1 request at a time. Its not like more requests are coming. Please help

  • Hello Dibyarekha,

    I have said, the code you attached here is too much, I can't review it for you. I think you need to narrow down the code to most concise module which can reproduce your issue stably. Then it will be easier for us to analysis the root cause. 

    For example, a few important points:

    • why the "code programming" is related to how you use the UART or use the function you defined, because in theory, these won't affect you download code into Flash. 
    • What is the "ACTIVE_CELLS", what is its function?
    • what is IDE you use, what is debugger you use, the error occurs when you want to download code through SWD interface?
    • Before you download code, have you already built (compile) your code?

    Best Regards,

    Janz Bai

    • why the "code programming" is related to how you use the UART or use the function you defined, because in theory, these won't affect you download code into Flash.  This is what my concern. Even I don't understand
    • Based on number of active cells, I am calculating average voltage, maximum, and minimum voltage 
    • I am using MSPM0G3519 evaluation board. CCS 20.5.1 IDE
    • yes, I have built the code and the code built without any error.
  • Hello Dibyarekha,

    Get it. Thanks for your confirming. But to be honest, as I said, I need your help to generate a very very very simply code module which can reproduce your issue. Because the code you attached here is really too much that I really can't help to review it. Please forgive.

    BR,

    Janz Bai