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

📄 flashutil.c

📁 采用ST20 CPU的机顶盒的烧写程序
💻 C
📖 第 1 页 / 共 5 页
字号:

  /*
   * Write flash-unlock sequence to device
   */
  *dataPtr = CMD_CLEAR_STATUS_REG;
  *dataPtr = CMD_PROGRAM_SETUP;

  /*
   * Write data to device
   */
  *dataPtr = value;

  /*
   * Poll the flash to wait for the value to stabilise
   */
  endTime = time_plus(time_now(), time_ticks_per_sec() * WRITE_TIMEOUT);

  while (((*dataPtr & PECS_STATUS_BIT) != PECS_STATUS_BIT) && !time_after(time_now(), endTime))
  {
  }

  if ((*dataPtr & STATUS_MASK) != PECS_STATUS_BIT)
  {
    fprintf(stderr, "\nError writing to %s @ 0x%08x\n", device->deviceName, address);
    fprintf(stderr, "status: 0x%08x\n", *dataPtr);
    exit(1);
  }
}

static void writeCFI16(flashDevice_t* device, unsigned int address, unsigned short value)
{
  volatile unsigned short* dataPtr;
  osclock_t endTime;

  dataPtr = (volatile unsigned short*)physToUncachedFlashAddr(address);

  /*
   * Write flash-unlock sequence to device
   */
  *dataPtr = CMD_CLEAR_STATUS_REG16;
  *dataPtr = CMD_PROGRAM_SETUP16;

  /*
   * Write data to device
   */
  *dataPtr = value;

  /*
   * Poll the flash to wait for the value to stabilise
   */
  endTime = time_plus(time_now(), time_ticks_per_sec() * WRITE_TIMEOUT);

  while (((*dataPtr & PECS_STATUS_BIT16) != PECS_STATUS_BIT16) && !time_after(time_now(), endTime))
  {
  }

  if ((*dataPtr & STATUS_MASK16) != PECS_STATUS_BIT16)
  {
    fprintf(stderr, "\nError writing to %s @ 0x%08x\n", device->deviceName, address);
    fprintf(stderr, "status: 0x%04x\n", *dataPtr);
    exit(1);
  }
}

/*
 * Routine to write a 32-bit word of data to a CFI device using
 * a 16 bit bus.
 */
static void writeWordCFI16(flashDevice_t* device, unsigned int address, unsigned int value)
{
  /* Don't bother writing words which are the default erased value */
  if (value == 0xFFFFFFFF)
    return;

  writeCFI16(device, address, (unsigned short) (value & 0xFFFF));
  writeCFI16(device, address + 2, (unsigned short) ((value >> 16)));
}

/*
 * CFI block unprotect method
 * Using 16 bit accesses
 */
static void blockUnprotectCFI16(flashDevice_t* device, unsigned int blockAddress)
{
  volatile unsigned short* blockPtr;
  osclock_t endTime;

  blockPtr = (volatile unsigned short*)physToUncachedFlashAddr(blockAddress + 4);

  *blockPtr = CMD_READ_ESIG16;
  if ((*blockPtr & PROTECT_STATUS_BIT16) == 0)
  {
    /*
     * Block is not protected
     */
    return;
  }

  *blockPtr = CMD_CLEAR_STATUS_REG16;
  *blockPtr = CMD_PROTECTION_SETUP16;
  *blockPtr = CMD_CONFIRM16;
  *blockPtr = CMD_READ_STATUS_REG16;

  endTime = time_plus(time_now(), time_ticks_per_sec() * UNPROTECT_TIMEOUT);

  while (((*blockPtr & PECS_STATUS_BIT16) != PECS_STATUS_BIT16) && !time_after(time_now(), endTime))
  {
  }

  if ((*blockPtr & STATUS_MASK16) != PECS_STATUS_BIT16)
  {
    fprintf(stderr, "\nFailed to unprotect block @ 0x%08x\n", (unsigned int)blockAddress);
    fprintf(stderr, "status = 0x%x\n", *blockPtr);
    *blockPtr = CMD_READ_ARRAY16;
    exit(1);
  }

  *blockPtr = CMD_READ_ARRAY16;
}

/*
 * CFI block unprotect method
 */
static void blockUnprotectCFI(flashDevice_t* device, unsigned int blockAddress)
{
  volatile unsigned int* blockPtr;
  osclock_t endTime;

  blockPtr = (volatile unsigned int*)physToUncachedFlashAddr(blockAddress+8);

  *blockPtr = CMD_READ_ESIG;
  if ((*blockPtr & PROTECT_STATUS_BIT) == 0)
  {
    /*
     * Block is not protected
     */
    return;
  }

  *blockPtr = CMD_CLEAR_STATUS_REG;
  *blockPtr = CMD_PROTECTION_SETUP;
  *blockPtr = CMD_CONFIRM;
  *blockPtr = CMD_READ_STATUS_REG;

  endTime = time_plus(time_now(), time_ticks_per_sec() * UNPROTECT_TIMEOUT);

  while (((*blockPtr & PECS_STATUS_BIT) != PECS_STATUS_BIT) && !time_after(time_now(), endTime))
  {
  }

  if ((*blockPtr & STATUS_MASK) != PECS_STATUS_BIT)
  {
    fprintf(stderr, "\nFailed to unprotect block @ 0x%08x\n", (unsigned int)blockAddress);
    fprintf(stderr, "status = 0x%x\n", *blockPtr);
    *blockPtr = CMD_READ_ARRAY;
    exit(1);
  }

  *blockPtr = CMD_READ_ARRAY;
}

/*
 * Routine to verify that a block erase worked
 */
static void checkErase(flashDevice_t* device, unsigned int blockAddress)
{
  unsigned int* blockPtr;
  unsigned int blkSize;
  unsigned int i;

  blockPtr = (unsigned int*)physToUncachedFlashAddr(blockAddress);
  blkSize = flashBlockSize(device, blockAddress);

  for (i = 0; i < blkSize / sizeof(int); i++, blockPtr++)
  {
    if (*blockPtr != 0xFFFFFFFF)
    {
      fprintf(stderr, "\nErase of block 0x%x failed at 0x%08x (0x%x != 0xFFFFFFFF)\n",
                (unsigned int)blockAddress, blockAddress + (i * sizeof(int)), *blockPtr);
      exit(1);
    }
  }
}

/*
 * Routine to erase a block on an M29W type of device.
 */
static void blockEraseM29W(flashDevice_t* device, unsigned int blockAddress)
{
  /*
   * chipErase(device);
   */
  volatile unsigned int* command1Ptr;
  volatile unsigned int* command2Ptr;
  volatile unsigned int* blockPtr;
  osclock_t endTime;

  blockUnprotect(device, blockAddress);

  blockPtr = (volatile unsigned int*)physToUncachedFlashAddr(blockAddress);
  command1Ptr = (volatile unsigned int*)physToUncachedFlashAddr(device->baseAddress + 0x1554);
  command2Ptr = (volatile unsigned int*)physToUncachedFlashAddr(device->baseAddress + 0x2AA8);

  /*
   * Write flash-unlock sequence to device
   */
  *command1Ptr = 0x00AA00AA;
  *command2Ptr = 0x00550055;
  *command1Ptr = 0x00800080;
  *command1Ptr = 0x00AA00AA;
  *command2Ptr = 0x00550055;
  *blockPtr = 0x00300030;

  /*
   * Wait for a short while for the erase to start
   */
  endTime = time_plus(time_now(), time_ticks_per_sec() * BLOCK_ERASE_TIMEOUT);

  while ((((*blockPtr) & 0x00080008) != 0x00080008) && !time_after(time_now(), endTime))
  {
  }

  if ((((*blockPtr) & 0x00080008) != 0x00080008))
  {
    fprintf(stderr, "\nError for block erase start for 0x%08x\n", (unsigned int)blockAddress);
  }

  /*
   * Poll the FLASH to wait for the erase to complete
   */
  endTime = time_plus(time_now(), time_ticks_per_sec() * BLOCK_ERASE_TIMEOUT);

  while ((*blockPtr != 0xFFFFFFFF) && !time_after(time_now(), endTime))
  {
  }

  if (*blockPtr != 0xFFFFFFFF)
  {
    fprintf(stderr, "\nError erasing block @ 0x%08x\n", (unsigned int)blockAddress);
    exit(1);
  }

  checkErase(device, blockAddress);
}

/*
 * Routine to erase a block on an M29W type of device.
 */
static void blockEraseM29W16(flashDevice_t* device, unsigned int blockAddress)
{
  /*
   * chipErase(device);
   */
  volatile unsigned short* command1Ptr;
  volatile unsigned short* command2Ptr;
  volatile unsigned short* blockPtr;
  osclock_t endTime;

/*  blockUnprotect(device, blockAddress);*/

  blockPtr = (volatile unsigned short*)physToUncachedFlashAddr(blockAddress);
  command1Ptr = (volatile unsigned short*)physToUncachedFlashAddr(device->baseAddress + 0xAAA);
  command2Ptr = (volatile unsigned short*)physToUncachedFlashAddr(device->baseAddress + 0x554);

  /*
   * Write flash-unlock sequence to device
   */
  *command1Ptr = 0x00AA;
  *command2Ptr = 0x0055;
  *command1Ptr = 0x0080;
  *command1Ptr = 0x00AA;
  *command2Ptr = 0x0055;
  *blockPtr = 0x0030;

  /*
   * Wait for a short while for the erase to start
   */
  endTime = time_plus(time_now(), time_ticks_per_sec() * BLOCK_ERASE_TIMEOUT);

  while ((((*blockPtr) & PECS_STATUS_BIT16) != PECS_STATUS_BIT16) && !time_after(time_now(), endTime))
  {
  }

  if ((((*blockPtr) & PECS_STATUS_BIT16) != PECS_STATUS_BIT16))
  {
    fprintf(stderr, "\nError for block erase start for 0x%08x\n", (unsigned int)blockAddress);
  }

  /*
   * Poll the FLASH to wait for the erase to complete
   */
  endTime = time_plus(time_now(), time_ticks_per_sec() * BLOCK_ERASE_TIMEOUT);

  while ((*blockPtr != 0xFFFF) && !time_after(time_now(), endTime))
  {
  }

  if (*blockPtr != 0xFFFF)
  {
    fprintf(stderr, "\nError erasing block @ 0x%08x\n", (unsigned int)blockAddress);
    exit(1);
  }

  checkErase(device, blockAddress);
}

/*
 * Routine to erase a block used by many types of FLASH
 * Uses 16 bit accesses
 */
static void blockEraseCFI16(flashDevice_t* device, unsigned int blockAddress)
{
  volatile unsigned short* blockPtr;
  osclock_t endTime;

  blockUnprotectCFI16(device, blockAddress);

  blockPtr = (volatile unsigned short*)physToUncachedFlashAddr(blockAddress);

  *blockPtr = CMD_CLEAR_STATUS_REG16;
  *blockPtr = CMD_ERASE_SETUP16;
  *blockPtr = CMD_CONFIRM16;

  endTime = time_plus(time_now(), time_ticks_per_sec() * BLOCK_ERASE_TIMEOUT);

  while (((*blockPtr & PECS_STATUS_BIT16) != PECS_STATUS_BIT16) && !time_after(time_now(), endTime))
  {
  }

  if ((*blockPtr & STATUS_MASK16) != PECS_STATUS_BIT16)
  {
    fprintf(stderr, "\nError during erase of block 0x%08x on %s\n",
                (unsigned int)blockAddress, device->deviceName);
    fprintf(stderr, "status is 0x%08x\n", *blockPtr);
    exit(1);
  }

  *blockPtr = CMD_READ_ARRAY16;

  checkErase(device, blockAddress);
}

/*
 * Routine to erase a block used by many types of FLASH
 */
static void blockEraseCFI(flashDevice_t* device, unsigned int blockAddress)
{
  volatile unsigned int* blockPtr;
  osclock_t endTime;

  blockUnprotect(device, blockAddress);

  blockPtr = (volatile unsigned int*)physToUncachedFlashAddr(blockAddress);

  *blockPtr = CMD_CLEAR_STATUS_REG;
  *blockPtr = CMD_ERASE_SETUP;
  *blockPtr = CMD_CONFIRM;
  *blockPtr = CMD_READ_STATUS_REG;

  endTime = time_plus(time_now(), time_ticks_per_sec() * BLOCK_ERASE_TIMEOUT);

  while (((*blockPtr & PECS_STATUS_BIT) != PECS_STATUS_BIT) && !time_after(time_now(), endTime))
  {
  }

  if ((*blockPtr & STATUS_MASK) != PECS_STATUS_BIT)
  {
    fprintf(stderr, "\nError during erase of block 0x%08x on %s\n",
            blockAddress, device->deviceName);
    fprintf(stderr, "status is 0x%08x\n", *blockPtr);
    *blockPtr = CMD_READ_ARRAY;
    exit(1);
  }

  *blockPtr = CMD_READ_ARRAY;

  checkErase(device, blockAddress);
}

/*
 * Routine to erase most FLASHes - just erase all its blocks
 */
static void chipEraseSimple(flashTarget_t* target, flashDevice_t* device, flashProgress_t progressFn)
{
  unsigned int offset = 0;

  while (offset < device->bankSize)
  {
    showProgress(progressFn, offset, device->bankSize);
    flashBlockErase(target, device, device->baseAddress + offset);

    offset += flashBlockSize(device, device->baseAddress + offset);
  }

  showProgress(progressFn, offset, device->bankSize);
}

/*
 * Routine to erase an M29W
 */
static void chipEraseM29W(flashTarget_t* target, flashDevice_t* device, flashProgress_t progressFn)
{
  volatile unsigned int* command1Ptr;
  volatile unsigned int* command2Ptr;
  volatile unsigned int* statusPtr;
  osclock_t endTime;

  showProgress(progressFn, 0, device->bankSize);

  command1Ptr = (volatile unsigned int*)physToUncachedFlashAddr(device->baseAddress + 0x1554);
  command2Ptr = (volatile unsigned int*)physToUncachedFlashAddr(device->baseAddress + 0x2AA8);
  statusPtr = (volatile unsigned int*)physToUncachedFlashAddr(device->baseAddress);

  *command1Ptr = 0x00AA00AA; /* Auto select command */
  *command2Ptr = 0x00550055;
  *command1Ptr = 0x00800080;
  *command1Ptr = 0x00AA00AA;
  *command2Ptr = 0x00550055;
  *command1Ptr = 0x00100010;

  endTime = time_plus(time_now(), time_ticks_per_sec() * CHIP_ERASE_TIMEOUT);

  while ((*statusPtr != 0xFFFFFFFF) && !time_after(time_now(), endTime))
  {
  }

  if (*statusPtr != 0xFFFFFFFF)
  {
    fprintf(stderr, "\nError erasing device\n");
    exit(1);
  }

  showProgress(progressFn, device->bankSize, device->bankSize);
}

/*
 * Routines to switch on / off VDD (programming voltage)
 */
static void switchOnVDD(flashTarget_t* target)
{
  if (target->switchOnVDD)
  {
    target->switchOnVDD();
  }
}

static void switchOffVDD(flashTarget_t* target)
{
  if (target->switchOffVDD)
  {
    target->switchOffVDD();
  }
}

#if defined(__st200__)

#else

#if defined(__st40gx1__)

static void switchOnVDD_mb317(void)
{
  volatile unsigned int* vpp_reg = (volatile unsigned int*)
    vmem_create((void*)0x07300000, vmem_min_page_size(), NULL, VMEM_CREATE_UNCACHED);

⌨️ 快捷键说明

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