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.

TM4C1290NCPDT: Access Error when writing to Flash

Part Number: TM4C1290NCPDT
Other Parts Discussed in Thread: EK-TM4C1294XL

Tool/software:

I am writing a bootloader and writing the program data into flash starting at address 0x0001 0000 this works fine until I hit address 0x0002 0000 and then the program detects an Access Error in the raw interrupt status register. I have examined the FMPREn and FMPPEn registers and found all the bits set.  I have also examined the flash address where the write was supposed to happen and found it to be all 0, which is not the data to be written. Here is the code used to write to Flash. 

BOOL amd_WriteWord(volatile ULONG* pulDest, ULONG* pulSource)
{
   BOOL bOK = TRUE;
   union
   {
      UBYTE ubByte[4];
      ULONG ulWord;
   } atTemp;
   MAP_IntMasterDisable();
   patFlash->FCMISC = (FLASH_FCMISC_AMISC | FLASH_FCMISC_VOLTMISC |
                           FLASH_FCMISC_ERMISC);
   patFlash->FMA = pulDest;
   atTemp.ubByte[0] = *((UBYTE*)pulSource);
   atTemp.ubByte[1] = *((UBYTE*)pulSource+1);
   atTemp.ubByte[2] = *((UBYTE*)pulSource+2);
   atTemp.ubByte[3] = *((UBYTE*)pulSource+3);
   patFlash->FMD = atTemp.ulWord;

   patFlash->FMC = FLASH_FMC_WRKEY | FLASH_FMC_WRITE; 
   while (patFlash->FMC & FLASH_FMC_WRITE) {} //wait for the write to complete
   if (patFlash->FCRIS & (FLASH_FCRIS_ARIS | FLASH_FCRIS_VOLTRIS |
                             FLASH_FCRIS_INVDRIS | FLASH_FCRIS_PROGRIS))
   {
      bOK = FALSE; 
   }
   MAP_IntMasterEnable(); 
   return(bOK);
}

This error happens when pulDest = 0x0002 0000. The data passed to the function is also valid. 

Any Help debugging is appreciated. 

  • Hi,

      I have a few comments and I hope it will help. 

    - There are several bootloader examples in TivaWare SDK. Not sure why you want to write your own bootloader. I think at least you want to reference the example bootloader and you are free to add/modify/adapt to your own requirements. You can find the bootloader source code in C:\ti\TivaWare_C_Series-2.2.0.295\boot_loader folder and a serial bootloader example at C:\ti\TivaWare_C_Series-2.2.0.295\examples\boards\ek-tm4c1294xl\boot_serial as well as other bootloader examples via other comms port in the examples folder. 

    - On TM4C129 MCU, each logical flash sector is 16kB. Refer to the datasheet for details. The first sector (16kB) is where your bootloader will reside. If you are trying to program something at 0x2000 then you will have a problem. The reason is that you may need to erase the sector before you can program. Erasing the first sector will wipe out your bootloader itself if you allow it to do so. 
    Because the memory is two-way interleaved and each bank individually is an 8-KB sector, when
    the user erases a sector, using the ERASE bits in the Flash Memory Control (FMC) register, it is
    a 16 KB erase. Erasing a block causes the entire contents of the block to be reset to all 1s.

    - If you reference the stock TivaWare bootloader example, the bootloader code is copied to the SRAM and run from SRAM. You can't run code out of flash and also program flash at the same time. 

    - There are APIs to program and erase flash. You can use FlashProgram() and FlashErase() by providing the address and the data plus data size to be programmed. Refer to the peripheral driver user's guide for details. 

  • Hi, 

    Thanks for your response! I took into account the flash banks when setting up the linker script. Here's my memory map of flash. 

    /* partitioning of flash in new applicatoin
    0x0000 0000  Flash start
    0x0000 0000  Vector table (512B) and Boot loader start
    0x0000 8000  PARAMBLOCK1 16K
    0x0000 C000  PARAMBLOCK2 16K
    0x0001 0000  FPGA Code 134K actual size
    0x0003 1A00  Application code 825K Allocated 
    0x000F FFFF  Flash End 1MB
    */

    I switched to the API functions for writing to flash just to be sure, but the behavior is the same. I could try running out of SRAM instead of flash, but given that the part of flash I'm writing to is different from the one I'm executing out of I don't think it'll make a difference. Again I'm seemingly successfully writing to flash for addresses 0x0001 0000 to 0x0001 FFFC (the first 64KB of the application), it only fails on address 0x0002 0000. 

  • Hi Sam,

      Here is a very simple program I try. I can write to 0x20000. Please see below. 

  • I was supplying a pointer to the FlashErase and FlashProgram instead of an int for the address. Although I would expect it to be the same behavior casting it to an int seems to fix the problem. Thank you for your help.