⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 flashprg.c

📁 基于AT91SAM7_256的嵌入式系统的Flash编程算法
💻 C
字号:
/***********************************************************************/
/*  This file is part of the ARM Toolchain package                     */
/*  Copyright KEIL ELEKTRONIK GmbH 2003 - 2006                         */
/***********************************************************************/
/*                                                                     */
/*  FlashDev.C:  Flash Programming Functions adapted                   */
/*               for AT91SAM7 256kB Flash                              */
/*                                                                     */
/***********************************************************************/

#include "..\FlashOS.H"        // FlashOS Structures
#include <AT91SAM7S256.H>

#define AT91C_MC_CORRECT_KEY   ((unsigned int) 0x5A << 24)
#define FLASH_PAGE_SIZE_BYTE   256

#define STACK_SIZE   64        // Stack Size


unsigned long base_adr;        // Base Address


/*
 *  Initialize Flash Programming Functions
 *    Parameter:      adr:  Device Base Address
 *                    clk:  Clock Frequency (Hz)
 *                    fnc:  Function Code (1 - Erase, 2 - Program, 3 - Verify)
 *    Return Value:   0 - OK,  1 - Failed
 */

int Init (unsigned long adr, unsigned long clk, unsigned long fnc) {
  AT91PS_PMC    pPMC;
  unsigned long clkus;

  base_adr = adr;

  // Calculate Flash Microsecond Cycle Number - Approximate (no Library Code)
//clkus = (1074*(clk >> 10)) >> 20;            // Master Clock Cycles in 1.0us
  clkus = (1611*(clk >> 10)) >> 20;            // Master Clock Cycles in 1.5us

  // Set Flash Microsecond Cycle Number
  // Set Flash Waite State to max. (Single Cycle Access at Up to 30 MHz)
  AT91C_BASE_MC->MC_FMR = ((AT91C_MC_FMCN) & (clkus << 16)) | AT91C_MC_FWS_3FWS;

  // Disable Watchdog
  AT91C_BASE_WDTC->WDTC_WDMR = AT91C_WDTC_WDDIS;

  // Pointer to PMC
  pPMC = AT91C_BASE_PMC;

  // Enable the Main Oscillator:
  // SCK Period = 1/32768 = 30.51 us
  // Start-up Time = 8 * 6 / SCK = 56 * 30.51 = 1,46484375 ms
  pPMC->PMC_MOR = ((AT91C_CKGR_OSCOUNT & (0x06 << 8) | AT91C_CKGR_MOSCEN));

  // Wait the Start-up Time
  while(!(pPMC->PMC_SR & AT91C_PMC_MOSCS));

  // Select Main Clock
  pPMC->PMC_MCKR = AT91C_PMC_CSS_MAIN_CLK;

  // Wait for Clock ready
  while (!(pPMC->PMC_SR & AT91C_PMC_MCKRDY));

  return (0);
}


/*
 *  De-Initialize Flash Programming Functions
 *    Parameter:      fnc:  Function Code (1 - Erase, 2 - Program, 3 - Verify)
 *    Return Value:   0 - OK,  1 - Failed
 */

int UnInit (unsigned long fnc) {
  if (fnc == 2)
    switch (((AT91C_BASE_SYS->DBGU_CIDR >> 20) & 0xFF)) {
      case 0x71:                        // ARCH: for SAM7XCxxx
      case 0x72:                        // ARCH: for SAM7SExx
      case 0x75:                        // ARCH: for SAM7Xxx
        // Set GPNVM bit 2 for booting from Flash
        AT91C_BASE_MC->MC_FCR = AT91C_MC_CORRECT_KEY | AT91C_MC_FCMD_SET_GP_NVM | (2 << 8);
        break;
    }

  return (0);
}


/*
 *  Erase complete Flash Memory
 *    Return Value:   0 - OK,  1 - Failed
 */

int EraseChip (void) {

  // Erase All Command
  AT91C_BASE_MC->MC_FCR = AT91C_MC_CORRECT_KEY | AT91C_MC_FCMD_ERASE_ALL;

  // Wait until the end of Command
  while ((AT91C_BASE_MC->MC_FSR & AT91C_MC_FRDY) != AT91C_MC_FRDY);

  return (0);
}


/*
 *  Erase Sector in Flash Memory
 *    Parameter:      adr:  Sector Address
 *    Return Value:   0 - OK,  1 - Failed
 */

int EraseSector (unsigned long adr) {
  return (0);                  // Automatic Erase during Program Cycle
}


/*
 *  Program Page in Flash Memory
 *    Parameter:      adr:  Page Start Address
 *                    sz:   Page Size
 *                    buf:  Page Data
 *    Return Value:   0 - OK,  1 - Failed
 */

int ProgramPage (unsigned long adr, unsigned long sz, unsigned char *buf) {
  unsigned long   page;
  unsigned long * Flash;

  Flash = (unsigned long *)adr;
  page  = (adr - base_adr) / FLASH_PAGE_SIZE_BYTE;

  // Unlock Page Command
  AT91C_BASE_MC->MC_FCR = AT91C_MC_CORRECT_KEY | AT91C_MC_FCMD_UNLOCK |
                         (AT91C_MC_PAGEN & (page << 8));

  // Wait until the end of Command
  while ((AT91C_BASE_MC->MC_FSR & AT91C_MC_FRDY) != AT91C_MC_FRDY);

  // Copy to the Write Buffer
  for (sz = (sz + 3) & ~3; sz; sz -= 4, buf += 4) {
	*Flash++ = *((unsigned long *)buf);
  }
  //* Start Programming Command
  AT91C_BASE_MC->MC_FCR = AT91C_MC_CORRECT_KEY | AT91C_MC_FCMD_START_PROG |
                         (AT91C_MC_PAGEN & (page << 8));

  // Wait until the end of Command
  while ((AT91C_BASE_MC->MC_FSR & AT91C_MC_FRDY) != AT91C_MC_FRDY);

  // Check for Errors
  if (AT91C_BASE_MC->MC_FSR & (AT91C_MC_PROGE | AT91C_MC_LOCKE)) return (1);

  return (0);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -