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

📄 flashc.c

📁 FreeRTOS is a portable, open source, mini Real Time Kernel - a free to download and royalty free RTO
💻 C
📖 第 1 页 / 共 3 页
字号:

void flashc_lock_region(unsigned int region, Bool lock)
{
  flashc_lock_page_region(flashc_get_region_first_page_number(region), lock);
}


void flashc_lock_all_regions(Bool lock)
{
  unsigned int error_status = 0;
  unsigned int region = AVR32_FLASHC_REGIONS;
  while (region)
  {
    flashc_lock_region(--region, lock);
    error_status |= flashc_error_status;
  }
  flashc_error_status = error_status;
}


//! @}


/*! \name Access to General-Purpose Fuses
 */
//! @{


Bool flashc_read_gp_fuse_bit(unsigned int gp_fuse_bit)
{
  return ((AVR32_FLASHC.fgpfr & AVR32_FLASHC_FGPFR_GPF00_MASK << (gp_fuse_bit & 0x1F)) != 0);
}


U32 flashc_read_gp_fuse_bitfield(unsigned int pos, unsigned int width)
{
  return AVR32_FLASHC.fgpfr >> (AVR32_FLASHC_FGPFR_GPF00_OFFSET + (pos & 0x1F)) &
         ((1 << min(width, 32)) - 1);
}


U8 flashc_read_gp_fuse_byte(unsigned int gp_fuse_byte)
{
  return AVR32_FLASHC.fgpfr >> (AVR32_FLASHC_FGPFR_GPF00_OFFSET + ((gp_fuse_byte & 0x03) << 3));
}


U32 flashc_read_all_gp_fuses(void)
{
  return AVR32_FLASHC.fgpfr;
}


Bool flashc_erase_gp_fuse_bit(unsigned int gp_fuse_bit, Bool check)
{
  flashc_issue_command(AVR32_FLASHC_FCMD_CMD_EGPB, gp_fuse_bit & 0x1F);
  return (check) ? flashc_read_gp_fuse_bit(gp_fuse_bit) : TRUE;
}


Bool flashc_erase_gp_fuse_bitfield(unsigned int pos, unsigned int width, Bool check)
{
  unsigned int error_status = 0;
  unsigned int gp_fuse_bit;
  pos &= 0x1F;
  width = min(width, 32);
  for (gp_fuse_bit = pos; gp_fuse_bit < pos + width; gp_fuse_bit++)
  {
    flashc_erase_gp_fuse_bit(gp_fuse_bit, FALSE);
    error_status |= flashc_error_status;
  }
  flashc_error_status = error_status;
  return (check) ? (flashc_read_gp_fuse_bitfield(pos, width) == (1 << width) - 1) : TRUE;
}


Bool flashc_erase_gp_fuse_byte(unsigned int gp_fuse_byte, Bool check)
{
  unsigned int error_status;
  unsigned int current_gp_fuse_byte;
  U32 value = flashc_read_all_gp_fuses();
  flashc_erase_all_gp_fuses(FALSE);
  error_status = flashc_error_status;
  for (current_gp_fuse_byte = 0; current_gp_fuse_byte < 4; current_gp_fuse_byte++, value >>= 8)
  {
    if (current_gp_fuse_byte != gp_fuse_byte)
    {
      flashc_write_gp_fuse_byte(current_gp_fuse_byte, value);
      error_status |= flashc_error_status;
    }
  }
  flashc_error_status = error_status;
  return (check) ? (flashc_read_gp_fuse_byte(gp_fuse_byte) == 0xFF) : TRUE;
}


Bool flashc_erase_all_gp_fuses(Bool check)
{
  flashc_issue_command(AVR32_FLASHC_FCMD_CMD_EAGPF, -1);
  return (check) ? (flashc_read_all_gp_fuses() == 0xFFFFFFFF) : TRUE;
}


void flashc_write_gp_fuse_bit(unsigned int gp_fuse_bit, Bool value)
{
  if (!value)
    flashc_issue_command(AVR32_FLASHC_FCMD_CMD_WGPB, gp_fuse_bit & 0x1F);
}


void flashc_write_gp_fuse_bitfield(unsigned int pos, unsigned int width, U32 value)
{
  unsigned int error_status = 0;
  unsigned int gp_fuse_bit;
  pos &= 0x1F;
  width = min(width, 32);
  for (gp_fuse_bit = pos; gp_fuse_bit < pos + width; gp_fuse_bit++, value >>= 1)
  {
    flashc_write_gp_fuse_bit(gp_fuse_bit, value & 0x01);
    error_status |= flashc_error_status;
  }
  flashc_error_status = error_status;
}


void flashc_write_gp_fuse_byte(unsigned int gp_fuse_byte, U8 value)
{
  flashc_issue_command(AVR32_FLASHC_FCMD_CMD_PGPFB, (gp_fuse_byte & 0x03) | value << 2);
}


void flashc_write_all_gp_fuses(U32 value)
{
  unsigned int error_status = 0;
  unsigned int gp_fuse_byte;
  for (gp_fuse_byte = 0; gp_fuse_byte < 4; gp_fuse_byte++, value >>= 8)
  {
    flashc_write_gp_fuse_byte(gp_fuse_byte, value);
    error_status |= flashc_error_status;
  }
  flashc_error_status = error_status;
}


void flashc_set_gp_fuse_bit(unsigned int gp_fuse_bit, Bool value)
{
  if (value)
    flashc_erase_gp_fuse_bit(gp_fuse_bit, FALSE);
  else
    flashc_write_gp_fuse_bit(gp_fuse_bit, FALSE);
}


void flashc_set_gp_fuse_bitfield(unsigned int pos, unsigned int width, U32 value)
{
  unsigned int error_status = 0;
  unsigned int gp_fuse_bit;
  pos &= 0x1F;
  width = min(width, 32);
  for (gp_fuse_bit = pos; gp_fuse_bit < pos + width; gp_fuse_bit++, value >>= 1)
  {
    flashc_set_gp_fuse_bit(gp_fuse_bit, value & 0x01);
    error_status |= flashc_error_status;
  }
  flashc_error_status = error_status;
}


void flashc_set_gp_fuse_byte(unsigned int gp_fuse_byte, U8 value)
{
  unsigned int error_status;
  switch (value)
  {
  case 0xFF:
    flashc_erase_gp_fuse_byte(gp_fuse_byte, FALSE);
    break;
  case 0x00:
    flashc_write_gp_fuse_byte(gp_fuse_byte, 0x00);
    break;
  default:
    flashc_erase_gp_fuse_byte(gp_fuse_byte, FALSE);
    error_status = flashc_error_status;
    flashc_write_gp_fuse_byte(gp_fuse_byte, value);
    flashc_error_status |= error_status;
  }
}


void flashc_set_all_gp_fuses(U32 value)
{
  unsigned int error_status;
  switch (value)
  {
  case 0xFFFFFFFF:
    flashc_erase_all_gp_fuses(FALSE);
    break;
  case 0x00000000:
    flashc_write_all_gp_fuses(0x00000000);
    break;
  default:
    flashc_erase_all_gp_fuses(FALSE);
    error_status = flashc_error_status;
    flashc_write_all_gp_fuses(value);
    flashc_error_status |= error_status;
  }
}


//! @}


/*! \name Access to Flash Pages
 */
//! @{


void flashc_clear_page_buffer(void)
{
  flashc_issue_command(AVR32_FLASHC_FCMD_CMD_CPB, -1);
}


Bool flashc_is_page_erased(void)
{
  return ((AVR32_FLASHC.fsr & AVR32_FLASHC_FSR_QPRR_MASK) != 0);
}


Bool flashc_quick_page_read(int page_number)
{
  flashc_issue_command(AVR32_FLASHC_FCMD_CMD_QPR, page_number);
  return flashc_is_page_erased();
}


Bool flashc_erase_page(int page_number, Bool check)
{
  Bool page_erased = TRUE;
  flashc_issue_command(AVR32_FLASHC_FCMD_CMD_EP, page_number);
  if (check)
  {
    unsigned int error_status = flashc_error_status;
    page_erased = flashc_quick_page_read(-1);
    flashc_error_status |= error_status;
  }
  return page_erased;
}


Bool flashc_erase_all_pages(Bool check)
{
  Bool all_pages_erased = TRUE;
  unsigned int error_status = 0;
  unsigned int page_number = flashc_get_page_count();
  while (page_number)
  {
    all_pages_erased &= flashc_erase_page(--page_number, check);
    error_status |= flashc_error_status;
  }
  flashc_error_status = error_status;
  return all_pages_erased;
}


void flashc_write_page(int page_number)
{
  flashc_issue_command(AVR32_FLASHC_FCMD_CMD_WP, page_number);
}


Bool flashc_check_user_page_erase(void)
{
  volatile U64 *user_page_ptr = (U64 *)AVR32_FLASHC_USER_PAGE;
  while (user_page_ptr < (U64 *)(AVR32_FLASHC_USER_PAGE + AVR32_FLASHC_USER_PAGE_SIZE))
  {
    if (*user_page_ptr++ != 0xFFFFFFFFFFFFFFFFULL)
      return FALSE;
  }
  return TRUE;
}


Bool flashc_erase_user_page(Bool check)
{
  flashc_issue_command(AVR32_FLASHC_FCMD_CMD_EUP, -1);
  return (check) ? flashc_check_user_page_erase() : TRUE;
}


void flashc_write_user_page(void)
{
  flashc_issue_command(AVR32_FLASHC_FCMD_CMD_WUP, -1);
}


volatile void *flashc_memset8(volatile void *dst, U8 src, size_t nbytes, Bool erase)
{
  return flashc_memset16(dst, src | (U16)src << 8, nbytes, erase);
}


volatile void *flashc_memset16(volatile void *dst, U16 src, size_t nbytes, Bool erase)
{
  return flashc_memset32(dst, src | (U32)src << 16, nbytes, erase);
}


volatile void *flashc_memset32(volatile void *dst, U32 src, size_t nbytes, Bool erase)
{
  return flashc_memset64(dst, src | (U64)src << 32, nbytes, erase);
}


volatile void *flashc_memset64(volatile void *dst, U64 src, size_t nbytes, Bool erase)
{
  // Use aggregated pointers to have several alignments available for a same address.
  UnionCVPtr flash_array_end;
  UnionVPtr dest;
  Union64 source = {0};
  StructCVPtr dest_end;
  UnionCVPtr flash_page_source_end;
  Bool incomplete_flash_page_end;
  Union64 flash_dword;
  UnionVPtr tmp;
  unsigned int error_status = 0;
  unsigned int i;

  // Reformat arguments.
  flash_array_end.u8ptr = AVR32_FLASH + flashc_get_flash_size();
  dest.u8ptr = dst;
  for (i = (Get_align((U32)dest.u8ptr, sizeof(U64)) - 1) & (sizeof(U64) - 1);
       src; i = (i - 1) & (sizeof(U64) - 1))
  {
    source.u8[i] = src;
    src >>= 8;
  }
  dest_end.u8ptr = dest.u8ptr + nbytes;

  // If destination is outside flash, go to next flash page if any.
  if (dest.u8ptr < AVR32_FLASH)
  {
    dest.u8ptr = AVR32_FLASH;
  }
  else if (flash_array_end.u8ptr <= dest.u8ptr && dest.u8ptr < AVR32_FLASHC_USER_PAGE)
  {
    dest.u8ptr = AVR32_FLASHC_USER_PAGE;
  }

  // If end of destination is outside flash, move it to the end of the previous flash page if any.
  if (dest_end.u8ptr > AVR32_FLASHC_USER_PAGE + AVR32_FLASHC_USER_PAGE_SIZE)
  {
    dest_end.u8ptr = AVR32_FLASHC_USER_PAGE + AVR32_FLASHC_USER_PAGE_SIZE;
  }
  else if (AVR32_FLASHC_USER_PAGE >= dest_end.u8ptr && dest_end.u8ptr > flash_array_end.u8ptr)
  {
    dest_end.u8ptr = flash_array_end.u8ptr;
  }

  // Align each end of destination pointer with its natural boundary.
  dest_end.u16ptr = (U16 *)Align_down((U32)dest_end.u8ptr, sizeof(U16));
  dest_end.u32ptr = (U32 *)Align_down((U32)dest_end.u16ptr, sizeof(U32));
  dest_end.u64ptr = (U64 *)Align_down((U32)dest_end.u32ptr, sizeof(U64));

  // While end of destination is not reached...
  while (dest.u8ptr < dest_end.u8ptr)
  {

⌨️ 快捷键说明

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