This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Modified an Exiting Flash Download Algorithm

HI
I Use a S3C2440 And K9F2G08U0B.
I Modified an Exiting Flash Download Algorithm in keil S3C2440 NAND SP.
But It Doesn't Work.When The System Call Function FindBlock(0, 1); then it didn't return From The Function And Went To Address 0x00000000.


#include "..\FlashOS.H"                 // FlashOS Structures
#include "FlashHW.h"                    // Low level NAND flash declarations
#include "NAND_Error.h"                 // Error definitions

#define STACK_SIZE   128                // Stack Size

// Enumerated type names definitions
enum BOOL_TYPE {     FALSE = 0,       TRUE};

// Constants values for Small and Large Page
const unsigned int BLOCK_SIZE      =  131072;  // Block size
const unsigned int BLOCK_SIZE_SHIFT=      17;  // Block size in bit shifts
const unsigned int PAGE_SIZE       =    2112;  // Size of complete page
const unsigned int PAGE_USR_SIZE   =    2048;  // Size of page user data

// Global variables used throughout this module
unsigned long base_adr;                 // Base Address
unsigned long nand_block_offset;        // Offset of valid block
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_size;                // Size of Complete Page
unsigned int  page_usr_size;            // Size of User Page Data
unsigned char data_buf[528];            // Data buffer

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


/************************* Flash Algorithm Functions ***************************/

int Init (unsigned long adr, unsigned long clk, unsigned long fnc) {
  static unsigned char first_run_f = TRUE;

  if (first_run_f) {
    first_run_f = 0;

    base_adr = adr;

    InitFlashController_HW (&bus_width, &adr_cycles, &page_type, clk);

    // Remember block size information
    block_size       = BLOCK_SIZE;

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

    // Remember page size information
    page_size        = PAGE_SIZE;

    // Remember user page size information
    page_usr_size    = PAGE_USR_SIZE;

    // Restart block searching from beginning
    FindBlock(0, 1);
   (*(volatile unsigned long *) (0x56000014))&=0xFFDF;
  }

  return (0);
}

int UnInit (unsigned long fnc) {
  return (0);
}
int BlankCheck (unsigned long adr, unsigned long sz, unsigned char pat) {

  return (1);                           // Always Force Erase
}

int EraseSector (unsigned long adr) {


  if (adr == 0) {                       // Erasing block for 2-nd level bootloader
    if (EraseBlock_HW(0) != NAND_OK) return (1);
  } else {                              // Erasing block for program
    FindBlock(adr, 0);
    if (EraseBlock_HW(nand_block_offset) != NAND_OK) return (1);
  }

  return (0);
}

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

  if (adr < block_size) {               // Programming 2-nd level bootloader data
    adr_dest = adr;
  } else {                              // Programming program data
    FindBlock(adr, 0);
    adr_dest  = nand_block_offset + ((adr-base_adr) & (block_size-1));
  }

  if (ProgramPage_HW(adr_dest, sz, buf) != NAND_OK) return (1);

  return (0);
}

unsigned long Verify (unsigned long adr, unsigned long sz, unsigned char *buf) {
  unsigned long i, adr_dest, in_page_ofs;

  if (adr < block_size) {               // Verifying 2-nd level bootloader data
    adr_dest  = adr;
  } else {                              // Verifying program data
    FindBlock(adr, 0);
    adr_dest  = nand_block_offset + ((adr-base_adr) & (block_size-1));
  }
  in_page_ofs = adr_dest & (page_usr_size-1);

  if (ReadPage_HW(adr_dest, page_usr_size, data_buf) != NAND_OK) return (1);

  // Verify if written bytes are same as what was written, if not mark block bad
  for (i=0; i<sz; i++)
    if (buf[i] != data_buf[i+in_page_ofs]) {
      if (adr_dest >= block_size)       // Do not mark block 0 as bad
        MarkBlockBad_HW (nand_block_offset);
      break;
    }

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

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

  adr      -= base_adr;                 // Address to relative
  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);
}