lpcware

IAP Using USBVirtualCOM on LPC1788

Discussion created by lpcware Employee on Jun 15, 2016
Latest reply on Jun 15, 2016 by lpcware
Content originally posted in LPCWare by pcproa on Tue Oct 09 06:49:32 MST 2012
Hello,

I am having a problem with IAP on my LPC1788. I have merged two GIT examples by using Virtual COM port to download the entire new firmware to the SDRAM, using all of the Checksum data from the Hex File on the Host computer. Once everything is downloaded into a normal binary sequence on SDRAM, I start the process of CopyRAM2Flash in 1024byte sections into the flash from the starting address in the hex file.

Everything seems to copy successfully, but once the LPC1788 goes into ‘Compare’ it fails on the first or second 1024 byte compare loop.

I have even tried loading one solid value into the entire flash and tried comparing. It will always fail. In Keil, I try running debug. I set my debugger to run the firmware update. Once it fails I restart the debugger and verifiy the contents in the flash address that the Hex file said to write to, and it is always the same.

The CMSIS/GIT example linked below for IAP usage works start to finish on the same board. Compare and everything. The difference is, mine initializes the internal EEPROM, LCD, SDRAM, and the USB. In the future, it may also initialize SPI so I can use the touch screen controller. However, the IAP example just initializes UART0, where I do not in my program.

IAP Demo Used:
http://sw.lpcware.com/?p=lpc177x_8x.git&a=tree&h=c38c91aded3d473f12b1999431c6bc9556866af5&hb=50329337d0f1259ffa6158c331577a053b843f69&f=Examples/IAP/IAP_Demo

USB Virtual COM Demo Used:
http://sw.lpcware.com/?p=lpc177x_8x.git&a=tree&h=3546301845bdc9d998af808a01231228180237bd&hb=50329337d0f1259ffa6158c331577a053b843f69&f=Examples/USBDEV/USB_VirtualCom

I always get the value returned from Compare, 10, as COMPARE ERROR.
Sometimes I comment out the Compare section to test to see if the program will run after the IAP program loads it into flash. My IAP is set to load the downloaded programs to starting address 0x8000.

Once in a while I’ll have the LCD Backlight come on since it is set at the beginning of the main loop of the downloaded program as a test. Sometimes it will do a step or two further and clear the screen as well to a colour I set (Usually Red or Green)

And here is the full code section in cdcuser.c where I download the data to SDRAM, then load from SDRAM into internal Flash using intermediate buffers.

<code>
case 'd': // Start the download
{
    //uint8_t * dest = (uint8_t *)((BulkBufOut[2] << 8) | (BulkBufOut[3]));
    int x;
    Font fnt = {0xFFFFFFFF, 0xFF000000, 8, 13};
    uint8_t good = 1, bad = 0;
    uint32_t checkSum = 0;
    for (x = 0; x < BulkBufOut[1] + 4; x++)
        checkSum += BulkBufOut[x + 1];
    checkSum = (0x100 - checkSum) & 0xFF;
    if (checkSum == BulkBufOut[5 + BulkBufOut[1]])
    {
        if (BulkBufOut[4] == 00) // If the type is data record
        {
            memmove((uint8_t*)dest, (uint8_t*)&BulkBufOut[5], (uint8_t)BulkBufOut[1]);
            //memset(dest, 2, BulkBufOut[1]);
            dest += BulkBufOut[1]; // Increase the Buffer by the amount of bytes recieved

            currentAddress &= 0xFFFF0000;
            currentAddress |= ((BulkBufOut[2] << 8) | (BulkBufOut[3]));

            if (flashstartaddress > currentAddress)
                flashstartaddress = currentAddress;
            if (flashendaddress < currentAddress)
                flashendaddress = currentAddress;
        }
        else if (BulkBufOut[4] == 04)
        {
            currentAddress &= 0xFFFF;
            currentAddress |= (((BulkBufOut[5] << 24) | (BulkBufOut[6])) << 16);
        }
        USB_TX((uint8_t*)&good, 1); // Send good value for next set

        if (BulkBufOut[4] == 01) // End of hex file
        {
            uint32_t flash_prog_area_sec_start;
            uint32_t flash_prog_area_sec_end;
            uint32_t one, two;
            int i;
            uint8_t __attribute__ ((aligned (4))) * ptr;
            uint8_t __attribute__ ((aligned (4))) * emcBuffer;// = (uint8_t *)(0xA0000000 + (LCD_WIDTH * LCD_HEIGHT * sizeof(uint32_t)));
            uint8_t __attribute__ ((aligned (4))) buffer[1024];

            IAP_STATUS_CODE status;
   
            clear(0,0,0);
            print("Starting Load", 0, 0, &fnt);

            NVIC->ICER[0] = 0xFFFFDFFF; // Disable the interrupts
            NVIC->ICER[1] = 0xFF;

            // Load firmware and execute user code
            flash_prog_area_sec_start = GetSecNum(flashstartaddress);
            flash_prog_area_sec_end =  GetSecNum(flashendaddress);

            status = EraseSector(flash_prog_area_sec_start, flash_prog_area_sec_end);
            if (status != CMD_SUCCESS)
            {
                clear(0xFF,0,0);
                print("Erase Error", 0, 0, &fnt);
                ShowInt(status, 13, 0, &fnt);
                while(1);
            }
            print("Erasing Complete", 13, 0, &fnt);
            status = BlankCheckSector(flash_prog_area_sec_start, flash_prog_area_sec_end, &one, &two);
            if (status != CMD_SUCCESS)
            {
                clear(0xFF,0,0);
                print("Blank Check Error", 0, 0, &fnt);
                while(1);
            }
            print("Blank Check Complete", 26, 0, &fnt);
            for (i = 0; i < ((flashendaddress - flashstartaddress) / 1024) + 1; i++)
            {
                ptr = (uint8_t*)(flashstartaddress + (i * 1024));
                emcBuffer = (uint8_t *)((0xA0000000 + (LCD_WIDTH * LCD_HEIGHT * sizeof(uint32_t))) + (i * 1024));
                memset((uint8_t*)buffer, 0xFF, 1024);
                memcpy((uint8_t*)buffer, (uint8_t*)emcBuffer, 1024);
   
                status = CopyRAM2Flash(ptr, buffer, IAP_WRITE_1024);

                if (status != CMD_SUCCESS)
                {
                    clear(0xFF,0,0);
                    ShowInt(((flashendaddress - flashstartaddress) / 1024) + 1, 0, 0, &fnt);
                    ShowInt(i, 13, 0, &fnt);
                    ShowInt(status, 26, 0, &fnt);

                    while(1){}
                }
            }
            print("Copy Complete", 39, 0, &fnt);

            for (i = 0; i < ((flashendaddress - flashstartaddress) / 1024) + 1; i++)
            {
                ptr = (uint8_t*)(flashstartaddress + (i * 1024));
                emcBuffer = (uint8_t *)((0xA0000000 + (LCD_WIDTH * LCD_HEIGHT * sizeof(uint32_t))) + (i * 1024));
                memcpy((uint8_t*)buffer, (uint8_t*)emcBuffer, 1024);

                status = Compare(ptr, buffer, IAP_WRITE_1024);

                if (status != CMD_SUCCESS)
                {
                    clear(0xFF,0,0xFF);
                    ShowInt(((flashendaddress - flashstartaddress) / 1024) + 1, 0, 0, &fnt);
                    ShowInt(i, 13, 0, &fnt);
                    ShowInt((uint32_t)status, 26, 0, &fnt);
                    while(1){}
                }
            }
            print("Compare Check Complete", 52, 0, &fnt);
            LPC_GPIO5->SET |= (1 << 04); // Remove Power on the USB pin pull up
            print("Turned off USB - Restarting", 65, 0, &fnt);
            _DelayMs(1000); // Delay for 1000ms
            NVIC->ICER[0] = 0xFFFFDFFF; // Again, make sure the interrupts are disabled
            NVIC->ICER[1] = 0xFF;
            execute_user_code();
            //NVIC_SystemReset();
        }
    }
    else
    {
        clear(0xFF,0,0);
        print("Send again", 0, 0, &fnt);
        USB_TX((uint8_t*)&bad, 1); // Send bad value for a repeat

        // TODO: Go back to recieve sent section from the Computer and remove the next while loop
        while(1){}
    }
}
break;
</code>

And there are three global variables used that are referred to in the code above
<code>
uint32_t flashstartaddress = 0xFFFFFFFF, flashendaddress = 0;
uint32_t currentAddress = 0;
uint8_t __attribute__ ((aligned (4))) * dest = (uint8_t*)(0xA0000000 + (LCD_WIDTH * LCD_HEIGHT * sizeof(uint32_t)));
</code>

Can anyone see something I’m missing here or there?  Or something I should be doing differently?
Thanks in advance,
Patrick

Outcomes