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

📄 flashc.c

📁 FreeRTOS is a portable, open source, mini Real Time Kernel - a free to download and royalty free RTO
💻 C
📖 第 1 页 / 共 3 页
字号:
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
 *
 * \brief FLASHC driver for AVR32 UC3.
 *
 * AVR32 Flash Controller driver module.
 *
 * - Compiler:           IAR EWAVR32 and GNU GCC for AVR32
 * - Supported devices:  All AVR32 devices with a FLASHC module can be used.
 * - AppNote:
 *
 * \author               Atmel Corporation: http://www.atmel.com \n
 *                       Support and FAQ: http://support.atmel.no/
 *
 ******************************************************************************/

/* Copyright (c) 2007, Atmel Corporation All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * 3. The name of ATMEL may not be used to endorse or promote products derived
 * from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
 * SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */


#include <avr32/io.h>
#include <stddef.h>
#include "compiler.h"
#include "flashc.h"


/*! \name FLASHC Writable Bit-Field Registers
 */
//! @{

typedef union
{
  unsigned long                 fcr;
  avr32_flashc_fcr_t            FCR;
} u_avr32_flashc_fcr_t;

typedef union
{
  unsigned long                 fcmd;
  avr32_flashc_fcmd_t           FCMD;
} u_avr32_flashc_fcmd_t;

//! @}


/*! \name Flash Properties
 */
//! @{


unsigned int flashc_get_flash_size(void)
{
  static const unsigned int FLASH_SIZE[1 << AVR32_FLASHC_FSR_FSZ_SIZE] =
  {
      32 << 10,
      64 << 10,
     128 << 10,
     256 << 10,
     384 << 10,
     512 << 10,
     768 << 10,
    1024 << 10
  };
  return FLASH_SIZE[(AVR32_FLASHC.fsr & AVR32_FLASHC_FSR_FSZ_MASK) >> AVR32_FLASHC_FSR_FSZ_OFFSET];
}


unsigned int flashc_get_page_count(void)
{
  return flashc_get_flash_size() / AVR32_FLASHC_PAGE_SIZE;
}


unsigned int flashc_get_page_count_per_region(void)
{
  return flashc_get_page_count() / AVR32_FLASHC_REGIONS;
}


unsigned int flashc_get_page_region(int page_number)
{
  return ((page_number >= 0) ? page_number : flashc_get_page_number()) / flashc_get_page_count_per_region();
}


unsigned int flashc_get_region_first_page_number(unsigned int region)
{
  return region * flashc_get_page_count_per_region();
}


//! @}


/*! \name FLASHC Control
 */
//! @{


unsigned int flashc_get_wait_state(void)
{
  return (AVR32_FLASHC.fcr & AVR32_FLASHC_FCR_FWS_MASK) >> AVR32_FLASHC_FCR_FWS_OFFSET;
}


void flashc_set_wait_state(unsigned int wait_state)
{
  u_avr32_flashc_fcr_t u_avr32_flashc_fcr = {AVR32_FLASHC.fcr};
  u_avr32_flashc_fcr.FCR.fws = wait_state;
  AVR32_FLASHC.fcr = u_avr32_flashc_fcr.fcr;
}


Bool flashc_is_ready_int_enabled(void)
{
  return ((AVR32_FLASHC.fcr & AVR32_FLASHC_FCR_FRDY_MASK) != 0);
}


void flashc_enable_ready_int(Bool enable)
{
  u_avr32_flashc_fcr_t u_avr32_flashc_fcr = {AVR32_FLASHC.fcr};
  u_avr32_flashc_fcr.FCR.frdy = (enable != FALSE);
  AVR32_FLASHC.fcr = u_avr32_flashc_fcr.fcr;
}


Bool flashc_is_lock_error_int_enabled(void)
{
  return ((AVR32_FLASHC.fcr & AVR32_FLASHC_FCR_LOCKE_MASK) != 0);
}


void flashc_enable_lock_error_int(Bool enable)
{
  u_avr32_flashc_fcr_t u_avr32_flashc_fcr = {AVR32_FLASHC.fcr};
  u_avr32_flashc_fcr.FCR.locke = (enable != FALSE);
  AVR32_FLASHC.fcr = u_avr32_flashc_fcr.fcr;
}


Bool flashc_is_prog_error_int_enabled(void)
{
  return ((AVR32_FLASHC.fcr & AVR32_FLASHC_FCR_PROGE_MASK) != 0);
}


void flashc_enable_prog_error_int(Bool enable)
{
  u_avr32_flashc_fcr_t u_avr32_flashc_fcr = {AVR32_FLASHC.fcr};
  u_avr32_flashc_fcr.FCR.proge = (enable != FALSE);
  AVR32_FLASHC.fcr = u_avr32_flashc_fcr.fcr;
}


//! @}


/*! \name FLASHC Status
 */
//! @{


Bool flashc_is_ready(void)
{
  return ((AVR32_FLASHC.fsr & AVR32_FLASHC_FSR_FRDY_MASK) != 0);
}


void flashc_default_wait_until_ready(void)
{
  while (!flashc_is_ready());
}


void (*volatile flashc_wait_until_ready)(void) = flashc_default_wait_until_ready;


/*! \brief Gets the error status of the FLASHC.
 *
 * \return The error status of the FLASHC built up from
 *         \c AVR32_FLASHC_FSR_LOCKE_MASK and \c AVR32_FLASHC_FSR_PROGE_MASK.
 *
 * \warning This hardware error status is cleared by all functions reading the
 *          Flash Status Register (FSR). This function is therefore not part of
 *          the driver's API which instead presents \ref flashc_is_lock_error
 *          and \ref flashc_is_programming_error.
 */
static unsigned int flashc_get_error_status(void)
{
  return AVR32_FLASHC.fsr & (AVR32_FLASHC_FSR_LOCKE_MASK |
                             AVR32_FLASHC_FSR_PROGE_MASK);
}


//! Sticky error status of the FLASHC.
//! This variable is updated by functions that issue FLASHC commands. It
//! contains the cumulated FLASHC error status of all the FLASHC commands issued
//! by a function.
static unsigned int flashc_error_status = 0;


Bool flashc_is_lock_error(void)
{
  return ((flashc_error_status & AVR32_FLASHC_FSR_LOCKE_MASK) != 0);
}


Bool flashc_is_programming_error(void)
{
  return ((flashc_error_status & AVR32_FLASHC_FSR_PROGE_MASK) != 0);
}


//! @}


/*! \name FLASHC Command Control
 */
//! @{


unsigned int flashc_get_command(void)
{
  return (AVR32_FLASHC.fcmd & AVR32_FLASHC_FCMD_CMD_MASK) >> AVR32_FLASHC_FCMD_CMD_OFFSET;
}


unsigned int flashc_get_page_number(void)
{
  return (AVR32_FLASHC.fcmd & AVR32_FLASHC_FCMD_PAGEN_MASK) >> AVR32_FLASHC_FCMD_PAGEN_OFFSET;
}


void flashc_issue_command(unsigned int command, int page_number)
{
  u_avr32_flashc_fcmd_t u_avr32_flashc_fcmd;
  flashc_wait_until_ready();
  u_avr32_flashc_fcmd.fcmd = AVR32_FLASHC.fcmd;
  u_avr32_flashc_fcmd.FCMD.cmd = command;
  if (page_number >= 0) u_avr32_flashc_fcmd.FCMD.pagen = page_number;
  u_avr32_flashc_fcmd.FCMD.key = AVR32_FLASHC_FCMD_KEY_KEY;
  AVR32_FLASHC.fcmd = u_avr32_flashc_fcmd.fcmd;
  flashc_error_status = flashc_get_error_status();
  flashc_wait_until_ready();
}


//! @}


/*! \name FLASHC Global Commands
 */
//! @{


void flashc_no_operation(void)
{
  flashc_issue_command(AVR32_FLASHC_FCMD_CMD_NOP, -1);
}


void flashc_erase_all(void)
{
  flashc_issue_command(AVR32_FLASHC_FCMD_CMD_EA, -1);
}


//! @}


/*! \name FLASHC Protection Mechanisms
 */
//! @{


Bool flashc_is_security_bit_active(void)
{
  return ((AVR32_FLASHC.fsr & AVR32_FLASHC_FSR_SECURITY_MASK) != 0);
}


void flashc_activate_security_bit(void)
{
  flashc_issue_command(AVR32_FLASHC_FCMD_CMD_SSB, -1);
}


unsigned int flashc_get_bootloader_protected_size(void)
{
  unsigned int bootprot = (1 << AVR32_FLASHC_FGPFR_BOOTPROT_SIZE) - 1 -
                          flashc_read_gp_fuse_bitfield(AVR32_FLASHC_FGPFR_BOOTPROT_OFFSET,
                                                       AVR32_FLASHC_FGPFR_BOOTPROT_SIZE);
  return (bootprot) ? AVR32_FLASHC_PAGE_SIZE << bootprot : 0;
}


unsigned int flashc_set_bootloader_protected_size(unsigned int bootprot_size)
{
  flashc_set_gp_fuse_bitfield(AVR32_FLASHC_FGPFR_BOOTPROT_OFFSET,
                              AVR32_FLASHC_FGPFR_BOOTPROT_SIZE,
                              (1 << AVR32_FLASHC_FGPFR_BOOTPROT_SIZE) - 1 -
                              ((bootprot_size) ?
                               32 - clz((((min(max(bootprot_size, AVR32_FLASHC_PAGE_SIZE << 1),
                                               AVR32_FLASHC_PAGE_SIZE <<
                                               ((1 << AVR32_FLASHC_FGPFR_BOOTPROT_SIZE) - 1)) +
                                           AVR32_FLASHC_PAGE_SIZE - 1) /
                                          AVR32_FLASHC_PAGE_SIZE) << 1) - 1) - 1 :
                               0));
  return flashc_get_bootloader_protected_size();
}


Bool flashc_is_external_privileged_fetch_locked(void)
{
  return (!flashc_read_gp_fuse_bit(AVR32_FLASHC_FGPFR_EPFL_OFFSET));
}


void flashc_lock_external_privileged_fetch(Bool lock)
{
  flashc_set_gp_fuse_bit(AVR32_FLASHC_FGPFR_EPFL_OFFSET, !lock);
}


Bool flashc_is_page_region_locked(int page_number)
{
  return flashc_is_region_locked(flashc_get_page_region(page_number));
}


Bool flashc_is_region_locked(unsigned int region)
{
  return ((AVR32_FLASHC.fsr & AVR32_FLASHC_FSR_LOCK0_MASK << (region & (AVR32_FLASHC_REGIONS - 1))) != 0);
}


void flashc_lock_page_region(int page_number, Bool lock)
{
  flashc_issue_command((lock) ? AVR32_FLASHC_FCMD_CMD_LP : AVR32_FLASHC_FCMD_CMD_UP, page_number);
}

⌨️ 快捷键说明

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