lpcware

LPC4357 IAP bootloader - working only with ULink Pro

Discussion created by lpcware Employee on Jun 15, 2016
Latest reply on Jun 15, 2016 by lpcware
Content originally posted in LPCWare by TP on Thu Aug 14 02:24:21 MST 2014
I'm writing bootloader for LPC4357. Bootloader is located at address 0x1A000000 and application binary image resides in external SPIFI FLASH.

After MCU finishes copying image into internal FLASH at address 0x1A010000, jump command is executed and application starts. This is only true if I use Ulink Pro for code download and testing. If i use Flash Magic, bootloader hangs at first IAP write operation.

I'm using Keil MDK ARM 4.73. LPC4537 is running at 204 MHz. I'm not using RAM reserved for IAP operations. All IAP operations are completed successfully if I use Ulink Pro for download & run.

If I don't use IAP commands, code is working fine, regardless of programming tool used.I don't have any special code inside UlinkPro INI script, just issuing reset. I've tried adding equivalent code inside SystemInit() function but there is no difference in code behavior.

Is there any special requirement before using IAP on LPC43xx platform?
I've build bootloader for LPC1768 platform and everything works as it should. I don't have ULink Pro on that board.



uint32_t write_data (uint32_t cclk, uint32_t flash_address, uint32_t *flash_data_buf, uint32_t count)
{
   uint32_t i, ret, interrupts;

   disable_interrupts(interrupts);

   for (i = USER_START_SECTOR; i <= MAX_USER_SECTOR; i++)
   {
      if (flash_address < sector_end_map)
      {
         if (flash_address == sector_start_map)
         {
            if ((ret = prepare_sector(i,i,cclk)) != 0)
            {
               printf("prepare for erase failed (%d)\n", ret);
               while(1);
            }

            WaitUs(1000 * 250); // not needed

            if ((ret = erase_sector(i,i,cclk)) != 0)
            {
               printf("erase sector failed (%d)\n", ret);
               while(1);
            }
         }

         if ((ret = prepare_sector(i,i,cclk)) != 0)
         {
            printf("prepare for write failed (%d)\n", ret);
            while(1);
         }
         break;
      }
   }

   param_table[0] = COPY_RAM_TO_FLASH;
   param_table[1] = flash_address;
   param_table[2] = (uint32_t) flash_data_buf;
   param_table[3] = count;
   param_table[4] = cclk;

   iap_entry(param_table,result_table);

   enable_interrupts(interrupts);

   return result_table[0];
}

uint32_t erase_sector (uint32_t start_sector,uint32_t end_sector,uint32_t cclk)
{
   param_table[0] = ERASE_SECTOR;
   param_table[1] = start_sector;
   param_table[2] = end_sector;
   param_table[3] = cclk;
   param_table[4] = FLASH_BANK;
   iap_entry(param_table,result_table);

   return result_table[0];
}

uint32_t prepare_sector (uint32_t start_sector,uint32_t end_sector,uint32_t cclk)
{
   disable_interrupts(0);

   param_table[0] = PREPARE_SECTOR_FOR_WRITE;
   param_table[1] = start_sector;
   param_table[2] = end_sector;
   param_table[3] = FLASH_BANK;
   iap_entry(param_table,result_table);

   enable_interrupts(0);

   return result_table[0];
}




// UlinkPro INI script

FUNC void Setup (void)
{
  // Reset peripherals: LCD, USB0, USB1, DMA, SDIO, ETHERNET
  _WDWORD(0x40053100, 0x005F0000);   // Issue reset
  _sleep_(1);
}

Setup();                             // Setup for Running

Outcomes