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

📄 bootloader.c

📁 lpc3250 example program
💻 C
字号:
/***********************************************************************/
/*  This file is part of the ARM Toolchain package                     */
/*  Copyright KEIL ELEKTRONIK GmbH 2003 - 2008                         */
/***********************************************************************/
/*                                                                     */
/*  Bootloader.C: 2-nd level NAND Flash bootloader for                 */
/*                NXP LPC3000 Device Series                            */
/*                                                                     */
/***********************************************************************/

#include "FlashHW.h"
#include "NAND_Error.h"                 // Error definitions

#define STACK_SIZE       64             // Stack Size
#define MAX_USER_PROG_SZ (0x1FFC000)    // Maximal size of user program
#define EXT_SDRAM        (0x80000000)   // Start address of external SDRAM

// Enumerated type names definitions
enum PAGE_TYPE {SMALL_PAGE = 0, LARGE_PAGE};

// Constants values for Small and Large Page
const unsigned int BLOCK_SIZE[2]      = {16384, 131072};  // Block size
const unsigned int BLOCK_SIZE_SHIFT[2]= {   14,     17};  // Block size in bit shifts
const unsigned int PAGE_USR_SIZE[2]   = {  512,   2048};  // Size of page user data

// Global variables used throughout this module
unsigned long nand_block_offset;        // Offset of valid block
unsigned char ICR;                      // Interface Configuration Data
unsigned char bus_width;                // Bus width
unsigned char adr_cycles;               // Address word count
unsigned char page_type;                // Page type (small or large)
unsigned int  block_size;               // Block size
unsigned int  block_size_shift;         // Block size in bit shifts
unsigned int  page_usr_size;            // Size of User Page Data
unsigned char data_buf[32];             // Data buffer

// Module's local functions prototypes
static int FindBlock     (unsigned long adr, unsigned int restart);

// Pointer to start of the External SDRAM where Application is copied
typedef void (*fnc)(void);
const fnc AppEntry = (fnc) EXT_SDRAM;

/*************************** 2-nd Level Bootloader *****************************/

/*- main () --------------------------------------------------------------------
 *
 *  C routine for NAND Flash Initialization and copying code from NAND Flash
 *  to External SDRAM
 *    Parameter:
 *    Return Value:   0 - OK,  1 - Failed
 */
           
int main (void) {

  unsigned long i,j;
  unsigned char byte;

  // Read Interface Configuration Data (ICR) and setup interface according to it
  InitFlashController_HW(8, 3, SMALL_PAGE, 0);
  ReadPage_HW(0, 16, data_buf);

  // Check if Interface Configuration Data (ICR) are valid and setup interface accordingly
  for (i=0; i<16; i=i+4) {
    byte = data_buf[i];

    // Check if ICR valid
    if (((byte & 0x0F) ^ (byte >> 4)) == 0x0F) {

      ICR = byte;
      if (ICR & 0x01) bus_width = 16;
      else            bus_width =  8;

      if (ICR & 0x04) {
        page_type = LARGE_PAGE;
        if (ICR & 0x02) adr_cycles = 5;
        else            adr_cycles = 4;
      } else {
        page_type = SMALL_PAGE;
        if (ICR & 0x02) adr_cycles = 4;
        else            adr_cycles = 3;
      }
      InitFlashController_HW(bus_width, adr_cycles, page_type, 0);
      break;
    }
  }

  // Remember block size information
  block_size    = BLOCK_SIZE[page_type];

  // Remember block size information in bit shifts
  block_size_shift = BLOCK_SIZE_SHIFT[page_type];

  // Remember user page size information
  page_usr_size = PAGE_USR_SIZE[page_type];

  // Restart block searching from beginning
  FindBlock(0, 1);

  // Read size of application in bytes to be copied (position 0x14 in first correct block after BLOCK 0)
  FindBlock(0, 0);
  ReadPage_HW(nand_block_offset, 32, data_buf);

  // Copy code from NAND Flash to External SDRAM
  i = *(unsigned long *)(&data_buf[0x14]);  // Number of bytes to copy
  if (i == 0xFFFFFFFF) while (1);       // If no user program size information
  if (i == 0xE1A00000)                  // Unknown size (NOP instruction)
    i = MAX_USER_PROG_SZ;

  j = 0;
  while (i) {
    FindBlock(j, 0);
    if (i > page_usr_size) {            // Copy whole page
      ReadPage_HW(nand_block_offset+(j & (block_size-1)), page_usr_size, (unsigned char *)(EXT_SDRAM+j));
      j += page_usr_size;
      i -= page_usr_size;
    } else {                            // Copy less then whole page
      ReadPage_HW(nand_block_offset+(j & (block_size-1)),             i, (unsigned char *)(EXT_SDRAM+j));
      j += i;
      i  = 0;
    }
  }

  AppEntry();                           // Start the copied Application

  return (0);
}


/**************************** Auxiliary Functions ******************************/

/*- FindBlock (...) ------------------------------------------------------------
 *
 *  Find appropriate good block for requested address
 *    Parameter:     adr:       Address Requested for Setting
 *                   restart:   0 - find operation, 1 - restart search from beginning
 *    Return Value:  0 - OK,  1 - Failed
 */

static int FindBlock (unsigned long adr, unsigned int restart) {
  static int last_src_index  = -1;
         int src_index;

  if (restart == 1) {                   // Just restart for block finding starting from beginning
    last_src_index = -1;
    nand_block_offset = 0;
    return (0);
  }

  src_index = adr >> block_size_shift;  // Get requested block index for source

  if (src_index == last_src_index)      // Same block as previously requested
    return (0);

  while (last_src_index < src_index) {  // Find appropriate valid block
    nand_block_offset += block_size;
    if (CheckBlock_HW(nand_block_offset) == NAND_OK) 
      last_src_index++;
  }

  return (0);
}


/*******************************************************************************/

⌨️ 快捷键说明

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