📄 flashc.c
字号:
/*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 + -