Erasing a flash on TIVA TM4C123 Microcontroller

1

I have been trying to understand the following code which is writing to micro controller flash. The Microcontroller is TIVA ARM Cortex M4. I have read the Internal Memory Chapter 8 of Tiva™ TM4C123GH6PM Microcontroller Data sheet. At high level I understand Flash Memory Address (FMA), Flash Memory Data (FMD), and Flash Memory Control (FMC) and Boot Configuration (BOOTCFG).

Below are definitions for some of the variable used in the function.

#define FLASH_FMA_R             (*((volatile uint32_t *)0x400FD000))
#define FLASH_FMA_OFFSET_MAX    0x0003FFFF  // Address Offset max
#define FLASH_FMD_R             (*((volatile uint32_t *)0x400FD004))
#define FLASH_FMC_R             (*((volatile uint32_t *)0x400FD008))
#define FLASH_FMC_WRKEY         0xA4420000  // FLASH write key (KEY bit of FLASH_BOOTCFG_R set)
#define FLASH_FMC_WRKEY2        0x71D50000  // FLASH write key (KEY bit of FLASH_BOOTCFG_R cleared)
#define FLASH_FMC_MERASE        0x00000004  // Mass Erase Flash Memory
#define FLASH_FMC_ERASE         0x00000002  // Erase a Page of Flash Memory
#define FLASH_FMC_WRITE         0x00000001  // Write a Word into Flash Memory
#define FLASH_FMC2_R            (*((volatile uint32_t *)0x400FD020))
#define FLASH_FMC2_WRBUF        0x00000001  // Buffered Flash Memory Write
#define FLASH_FWBN_R            (*((volatile uint32_t *)0x400FD100))
#define FLASH_BOOTCFG_R         (*((volatile uint32_t *)0x400FE1D0))
#define FLASH_BOOTCFG_KEY       0x00000010  // KEY Select

This function is used to erase a section of the flash. The function is called from a start address to and end address. I have not fully comprehended how this code works.

//------------Flash_Erase------------
// Erase 1 KB block of flash.
// Input: addr 1-KB aligned flash memory address to erase
// Output: 'NOERROR' if successful, 'ERROR' if fail (defined in FlashProgram.h)
// Note: disables interrupts while erasing
int Flash_Erase(uint32_t addr){
  uint32_t flashkey;
  if(EraseAddrValid(addr)){
    DisableInterrupts();                            // may be optional step
                                                    // wait for hardware idle
    while(FLASH_FMC_R&(FLASH_FMC_WRITE|FLASH_FMC_ERASE|FLASH_FMC_MERASE)){
                 // to do later: return ERROR if this takes too long
                 // remember to re-enable interrupts
    };
    FLASH_FMA_R = addr;
    if(FLASH_BOOTCFG_R&FLASH_BOOTCFG_KEY){          // by default, the key is 0xA442
      flashkey = FLASH_FMC_WRKEY;
    } else{                                         // otherwise, the key is 0x71D5
      flashkey = FLASH_FMC_WRKEY2;
    }
    FLASH_FMC_R = (flashkey|FLASH_FMC_ERASE);       // start erasing 1 KB block
    while(FLASH_FMC_R&FLASH_FMC_ERASE){
                 // to do later: return ERROR if this takes too long
                 // remember to re-enable interrupts
    };           // wait for completion (~3 to 4 usec)
    EnableInterrupts();
    return NOERROR;
  }
  return ERROR;
}

Questions: How does the function exit out of the two while loops? How are variables FLASH_FMC_WRITE, FLASH_FMC_ERASE, and FLASH_FMC_MERASE changed? Can '0' be written as part of the erase process?

embedded
asked on Stack Overflow Jun 11, 2018 by user7083

1 Answer

0

FLASH_FMC_WRITE, FLASH_FMC_ERASE, and FLASH_FMC_MERASE are individual bits in the FLASH_FMC_R register value (a bitfield). Look in the part's reference manual (or maybe datasheet) at the description of the FLASH_FMC_R register and you will find the description of these bits and more.

The while loops repeatedly read the FLASH_FMC_R register value and exit when the specified bits are set. The flash memory controller sets these bits when it's appropriate (read the reference manual).

Erasing flash means setting all bits to 1 (all bytes to 0xFF). Writing flash means setting select bits to 0. You cannot change a bit from 0 to 1 with a write. You need to erase to do that. This is just the way flash works.

answered on Stack Overflow Jun 12, 2018 by kkrambo

User contributions licensed under CC BY-SA 3.0