diff options
Diffstat (limited to 'firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/DRIVERS/FLASHC')
| -rw-r--r-- | firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/DRIVERS/FLASHC/flashc.c | 1117 | ||||
| -rw-r--r-- | firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/DRIVERS/FLASHC/flashc.h | 1002 | 
2 files changed, 2119 insertions, 0 deletions
| diff --git a/firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/DRIVERS/FLASHC/flashc.c b/firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/DRIVERS/FLASHC/flashc.c new file mode 100644 index 0000000..2eee15c --- /dev/null +++ b/firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/DRIVERS/FLASHC/flashc.c @@ -0,0 +1,1117 @@ +/* This source file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */ + +/*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) 2009 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. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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) +{ +#if (defined AVR32_FLASHC_300_H_INCLUDED) +  static const unsigned int FLASH_SIZE[1 << AVR32_FLASHC_PR_FSZ_SIZE] = +  { +      32 << 10, +      64 << 10, +     128 << 10, +     256 << 10, +     384 << 10, +     512 << 10, +     768 << 10, +    1024 << 10 +  }; +  return FLASH_SIZE[(AVR32_FLASHC.pr & AVR32_FLASHC_PR_FSZ_MASK) >> AVR32_FLASHC_PR_FSZ_OFFSET]; +#else  +  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]; +#endif   +} + + +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_FGPFRLO_BOOTPROT_SIZE) - 1 - +                          flashc_read_gp_fuse_bitfield(AVR32_FLASHC_FGPFRLO_BOOTPROT_OFFSET, +                                                       AVR32_FLASHC_FGPFRLO_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_FGPFRLO_BOOTPROT_OFFSET, +                              AVR32_FLASHC_FGPFRLO_BOOTPROT_SIZE, +                              (1 << AVR32_FLASHC_FGPFRLO_BOOTPROT_SIZE) - 1 - +                              ((bootprot_size) ? +                               32 - clz((((min(max(bootprot_size, AVR32_FLASHC_PAGE_SIZE << 1), +                                               AVR32_FLASHC_PAGE_SIZE << +                                               ((1 << AVR32_FLASHC_FGPFRLO_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_FGPFRLO_EPFL_OFFSET)); +} + + +void flashc_lock_external_privileged_fetch(Bool lock) +{ +  flashc_set_gp_fuse_bit(AVR32_FLASHC_FGPFRLO_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); +} + + +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 ((flashc_read_all_gp_fuses() & 1ULL << (gp_fuse_bit & 0x3F)) != 0); +} + + +U64 flashc_read_gp_fuse_bitfield(unsigned int pos, unsigned int width) +{ +  return flashc_read_all_gp_fuses() >> (pos & 0x3F) & ((1ULL << min(width, 64)) - 1); +} + + +U8 flashc_read_gp_fuse_byte(unsigned int gp_fuse_byte) +{ +  return flashc_read_all_gp_fuses() >> ((gp_fuse_byte & 0x07) << 3); +} + + +U64 flashc_read_all_gp_fuses(void) +{ +  return AVR32_FLASHC.fgpfrlo | (U64)AVR32_FLASHC.fgpfrhi << 32; +} + + +Bool flashc_erase_gp_fuse_bit(unsigned int gp_fuse_bit, Bool check) +{ +  flashc_issue_command(AVR32_FLASHC_FCMD_CMD_EGPB, gp_fuse_bit & 0x3F); +  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 &= 0x3F; +  width = min(width, 64); +  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) == (1ULL << 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; +  U64 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 < 8; 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() == 0xFFFFFFFFFFFFFFFFULL) : 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 & 0x3F); +} + + +void flashc_write_gp_fuse_bitfield(unsigned int pos, unsigned int width, U64 value) +{ +  unsigned int error_status = 0; +  unsigned int gp_fuse_bit; +  pos &= 0x3F; +  width = min(width, 64); +  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 & 0x07) | value << 3); +} + + +void flashc_write_all_gp_fuses(U64 value) +{ +  unsigned int error_status = 0; +  unsigned int gp_fuse_byte; +  for (gp_fuse_byte = 0; gp_fuse_byte < 8; 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, U64 value) +{ +  unsigned int error_status = 0; +  unsigned int gp_fuse_bit; +  pos &= 0x3F; +  width = min(width, 64); +  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(U64 value) +{ +  unsigned int error_status; +  switch (value) +  { +  case 0xFFFFFFFFFFFFFFFFULL: +    flashc_erase_all_gp_fuses(FALSE); +    break; +  case 0x0000000000000000ULL: +    flashc_write_all_gp_fuses(0x0000000000000000ULL); +    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_quick_user_page_read(void) +{ +  flashc_issue_command(AVR32_FLASHC_FCMD_CMD_QPRUP, -1); +  return flashc_is_page_erased(); +} + + +Bool flashc_erase_user_page(Bool check) +{ +  flashc_issue_command(AVR32_FLASHC_FCMD_CMD_EUP, -1); +  return (check) ? flashc_quick_user_page_read() : 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) +  { +    // Clear the page buffer in order to prepare data for a flash page write. +    flashc_clear_page_buffer(); +    error_status |= flashc_error_status; + +    // Determine where the source data will end in the current flash page. +    flash_page_source_end.u64ptr = +      (U64 *)min((U32)dest_end.u64ptr, +                 Align_down((U32)dest.u8ptr, AVR32_FLASHC_PAGE_SIZE) + AVR32_FLASHC_PAGE_SIZE); + +    // Determine if the current destination page has an incomplete end. +    incomplete_flash_page_end = (Align_down((U32)dest.u8ptr, AVR32_FLASHC_PAGE_SIZE) >= +                                 Align_down((U32)dest_end.u8ptr, AVR32_FLASHC_PAGE_SIZE)); + +    // Use a flash double-word buffer to manage unaligned accesses. +    flash_dword.u64 = source.u64; + +    // If destination does not point to the beginning of the current flash page... +    if (!Test_align((U32)dest.u8ptr, AVR32_FLASHC_PAGE_SIZE)) +    { +      // Fill the beginning of the page buffer with the current flash page data. +      // This is required by the hardware, even if page erase is not requested, +      // in order to be able to write successfully to erased parts of flash +      // pages that have already been written to. +      for (tmp.u8ptr = (U8 *)Align_down((U32)dest.u8ptr, AVR32_FLASHC_PAGE_SIZE); +           tmp.u64ptr < (U64 *)Align_down((U32)dest.u8ptr, sizeof(U64)); +           tmp.u64ptr++) +        *tmp.u64ptr = *tmp.u64ptr; + +      // If destination is not 64-bit aligned... +      if (!Test_align((U32)dest.u8ptr, sizeof(U64))) +      { +        // Fill the beginning of the flash double-word buffer with the current +        // flash page data. +        // This is required by the hardware, even if page erase is not +        // requested, in order to be able to write successfully to erased parts +        // of flash pages that have already been written to. +        for (i = 0; i < Get_align((U32)dest.u8ptr, sizeof(U64)); i++) +          flash_dword.u8[i] = *tmp.u8ptr++; + +        // Align the destination pointer with its 64-bit boundary. +        dest.u64ptr = (U64 *)Align_down((U32)dest.u8ptr, sizeof(U64)); + +        // If the current destination double-word is not the last one... +        if (dest.u64ptr < dest_end.u64ptr) +        { +          // Write the flash double-word buffer to the page buffer and reinitialize it. +          *dest.u64ptr++ = flash_dword.u64; +          flash_dword.u64 = source.u64; +        } +      } +    } + +    // Write the source data to the page buffer with 64-bit alignment. +    for (i = flash_page_source_end.u64ptr - dest.u64ptr; i; i--) +      *dest.u64ptr++ = source.u64; + +    // If the current destination page has an incomplete end... +    if (incomplete_flash_page_end) +    { +      // This is required by the hardware, even if page erase is not requested, +      // in order to be able to write successfully to erased parts of flash +      // pages that have already been written to. +      { +        tmp.u8ptr = (volatile U8 *)dest_end.u8ptr; + +        // If end of destination is not 64-bit aligned... +        if (!Test_align((U32)dest_end.u8ptr, sizeof(U64))) +        { +          // Fill the end of the flash double-word buffer with the current flash page data. +          for (i = Get_align((U32)dest_end.u8ptr, sizeof(U64)); i < sizeof(U64); i++) +            flash_dword.u8[i] = *tmp.u8ptr++; + +          // Write the flash double-word buffer to the page buffer. +          *dest.u64ptr++ = flash_dword.u64; +        } + +        // Fill the end of the page buffer with the current flash page data. +        for (; !Test_align((U32)tmp.u64ptr, AVR32_FLASHC_PAGE_SIZE); tmp.u64ptr++) +          *tmp.u64ptr = *tmp.u64ptr; +      } +    } + +    // If the current flash page is in the flash array... +    if (dest.u8ptr <= AVR32_FLASHC_USER_PAGE) +    { +      // Erase the current page if requested and write it from the page buffer. +      if (erase) +      { +        flashc_erase_page(-1, FALSE); +        error_status |= flashc_error_status; +      } +      flashc_write_page(-1); +      error_status |= flashc_error_status; + +      // If the end of the flash array is reached, go to the User page. +      if (dest.u8ptr >= flash_array_end.u8ptr) +        dest.u8ptr = AVR32_FLASHC_USER_PAGE; +    } +    // If the current flash page is the User page... +    else +    { +      // Erase the User page if requested and write it from the page buffer. +      if (erase) +      { +        flashc_erase_user_page(FALSE); +        error_status |= flashc_error_status; +      } +      flashc_write_user_page(); +      error_status |= flashc_error_status; +    } +  } + +  // Update the FLASHC error status. +  flashc_error_status = error_status; + +  // Return the initial destination pointer as the standard memset function does. +  return dst; +} + + +volatile void *flashc_memcpy(volatile void *dst, const void *src, size_t nbytes, Bool erase) +{ +  // Use aggregated pointers to have several alignments available for a same address. +  UnionCVPtr flash_array_end; +  UnionVPtr dest; +  UnionCPtr source; +  StructCVPtr dest_end; +  UnionCVPtr flash_page_source_end; +  Bool incomplete_flash_page_end; +  Union64 flash_dword; +  Bool flash_dword_pending = FALSE; +  UnionVPtr tmp; +  unsigned int error_status = 0; +  unsigned int i, j; + +  // Reformat arguments. +  flash_array_end.u8ptr = AVR32_FLASH + flashc_get_flash_size(); +  dest.u8ptr = dst; +  source.u8ptr = src; +  dest_end.u8ptr = dest.u8ptr + nbytes; + +  // If destination is outside flash, go to next flash page if any. +  if (dest.u8ptr < AVR32_FLASH) +  { +    source.u8ptr += AVR32_FLASH - dest.u8ptr; +    dest.u8ptr = AVR32_FLASH; +  } +  else if (flash_array_end.u8ptr <= dest.u8ptr && dest.u8ptr < AVR32_FLASHC_USER_PAGE) +  { +    source.u8ptr += AVR32_FLASHC_USER_PAGE - dest.u8ptr; +    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) +  { +    // Clear the page buffer in order to prepare data for a flash page write. +    flashc_clear_page_buffer(); +    error_status |= flashc_error_status; + +    // Determine where the source data will end in the current flash page. +    flash_page_source_end.u64ptr = +      (U64 *)min((U32)dest_end.u64ptr, +                 Align_down((U32)dest.u8ptr, AVR32_FLASHC_PAGE_SIZE) + AVR32_FLASHC_PAGE_SIZE); + +    // Determine if the current destination page has an incomplete end. +    incomplete_flash_page_end = (Align_down((U32)dest.u8ptr, AVR32_FLASHC_PAGE_SIZE) >= +                                 Align_down((U32)dest_end.u8ptr, AVR32_FLASHC_PAGE_SIZE)); + +    // If destination does not point to the beginning of the current flash page... +    if (!Test_align((U32)dest.u8ptr, AVR32_FLASHC_PAGE_SIZE)) +    { +      // Fill the beginning of the page buffer with the current flash page data. +      // This is required by the hardware, even if page erase is not requested, +      // in order to be able to write successfully to erased parts of flash +      // pages that have already been written to. +      for (tmp.u8ptr = (U8 *)Align_down((U32)dest.u8ptr, AVR32_FLASHC_PAGE_SIZE); +           tmp.u64ptr < (U64 *)Align_down((U32)dest.u8ptr, sizeof(U64)); +           tmp.u64ptr++) +        *tmp.u64ptr = *tmp.u64ptr; + +      // If destination is not 64-bit aligned... +      if (!Test_align((U32)dest.u8ptr, sizeof(U64))) +      { +        // Fill the beginning of the flash double-word buffer with the current +        // flash page data. +        // This is required by the hardware, even if page erase is not +        // requested, in order to be able to write successfully to erased parts +        // of flash pages that have already been written to. +        for (i = 0; i < Get_align((U32)dest.u8ptr, sizeof(U64)); i++) +          flash_dword.u8[i] = *tmp.u8ptr++; + +        // Fill the end of the flash double-word buffer with the source data. +        for (; i < sizeof(U64); i++) +          flash_dword.u8[i] = *source.u8ptr++; + +        // Align the destination pointer with its 64-bit boundary. +        dest.u64ptr = (U64 *)Align_down((U32)dest.u8ptr, sizeof(U64)); + +        // If the current destination double-word is not the last one... +        if (dest.u64ptr < dest_end.u64ptr) +        { +          // Write the flash double-word buffer to the page buffer. +          *dest.u64ptr++ = flash_dword.u64; +        } +        // If the current destination double-word is the last one, the flash +        // double-word buffer must be kept for later. +        else flash_dword_pending = TRUE; +      } +    } + +    // Read the source data with the maximal possible alignment and write it to +    // the page buffer with 64-bit alignment. +    switch (Get_align((U32)source.u8ptr, sizeof(U32))) +    { +    case 0: +      for (i = flash_page_source_end.u64ptr - dest.u64ptr; i; i--) +        *dest.u64ptr++ = *source.u64ptr++; +      break; + +    case sizeof(U16): +      for (i = flash_page_source_end.u64ptr - dest.u64ptr; i; i--) +      { +        for (j = 0; j < sizeof(U64) / sizeof(U16); j++) flash_dword.u16[j] = *source.u16ptr++; +        *dest.u64ptr++ = flash_dword.u64; +      } +      break; + +    default: +      for (i = flash_page_source_end.u64ptr - dest.u64ptr; i; i--) +      { +        for (j = 0; j < sizeof(U64); j++) flash_dword.u8[j] = *source.u8ptr++; +        *dest.u64ptr++ = flash_dword.u64; +      } +    } + +    // If the current destination page has an incomplete end... +    if (incomplete_flash_page_end) +    { +      // If the flash double-word buffer is in use, do not initialize it. +      if (flash_dword_pending) i = Get_align((U32)dest_end.u8ptr, sizeof(U64)); +      // If the flash double-word buffer is free... +      else +      { +        // Fill the beginning of the flash double-word buffer with the source data. +        for (i = 0; i < Get_align((U32)dest_end.u8ptr, sizeof(U64)); i++) +          flash_dword.u8[i] = *source.u8ptr++; +      } + +      // This is required by the hardware, even if page erase is not requested, +      // in order to be able to write successfully to erased parts of flash +      // pages that have already been written to. +      { +        tmp.u8ptr = (volatile U8 *)dest_end.u8ptr; + +        // If end of destination is not 64-bit aligned... +        if (!Test_align((U32)dest_end.u8ptr, sizeof(U64))) +        { +          // Fill the end of the flash double-word buffer with the current flash page data. +          for (; i < sizeof(U64); i++) +            flash_dword.u8[i] = *tmp.u8ptr++; + +          // Write the flash double-word buffer to the page buffer. +          *dest.u64ptr++ = flash_dword.u64; +        } + +        // Fill the end of the page buffer with the current flash page data. +        for (; !Test_align((U32)tmp.u64ptr, AVR32_FLASHC_PAGE_SIZE); tmp.u64ptr++) +          *tmp.u64ptr = *tmp.u64ptr; +      } +    } + +    // If the current flash page is in the flash array... +    if (dest.u8ptr <= AVR32_FLASHC_USER_PAGE) +    { +      // Erase the current page if requested and write it from the page buffer. +      if (erase) +      { +        flashc_erase_page(-1, FALSE); +        error_status |= flashc_error_status; +      } +      flashc_write_page(-1); +      error_status |= flashc_error_status; + +      // If the end of the flash array is reached, go to the User page. +      if (dest.u8ptr >= flash_array_end.u8ptr) +      { +        source.u8ptr += AVR32_FLASHC_USER_PAGE - dest.u8ptr; +        dest.u8ptr = AVR32_FLASHC_USER_PAGE; +      } +    } +    // If the current flash page is the User page... +    else +    { +      // Erase the User page if requested and write it from the page buffer. +      if (erase) +      { +        flashc_erase_user_page(FALSE); +        error_status |= flashc_error_status; +      } +      flashc_write_user_page(); +      error_status |= flashc_error_status; +    } +  } + +  // Update the FLASHC error status. +  flashc_error_status = error_status; + +  // Return the initial destination pointer as the standard memcpy function does. +  return dst; +} + + +#if UC3C +void flashc_set_flash_waitstate_and_readmode(unsigned long cpu_f_hz) +{ +  //! Device-specific data +  #undef AVR32_FLASHC_FWS_0_MAX_FREQ +  #undef AVR32_FLASHC_FWS_1_MAX_FREQ +  #undef AVR32_FLASHC_HSEN_FWS_0_MAX_FREQ +  #undef AVR32_FLASHC_HSEN_FWS_1_MAX_FREQ +  #define AVR32_FLASHC_FWS_0_MAX_FREQ           33000000 +  #define AVR32_FLASHC_FWS_1_MAX_FREQ           66000000 +  #define AVR32_FLASHC_HSEN_FWS_0_MAX_FREQ      33000000 +  #define AVR32_FLASHC_HSEN_FWS_1_MAX_FREQ      72000000 +  // These defines are missing from or wrong in the toolchain header files uc3cxxx.h +  // Put a Bugzilla  + +  if(cpu_f_hz > AVR32_FLASHC_HSEN_FWS_0_MAX_FREQ)    // > 33MHz +  { +    // Set a wait-state +    flashc_set_wait_state(1); +    if(cpu_f_hz <= AVR32_FLASHC_FWS_1_MAX_FREQ) // <= 66MHz and >33Mhz +    { +      // Disable the high-speed read mode.       +      flashc_issue_command(AVR32_FLASHC_FCMD_CMD_HSDIS, -1); +    } +    else // > 66Mhz +    { +      // Enable the high-speed read mode. +      flashc_issue_command(AVR32_FLASHC_FCMD_CMD_HSEN, -1);                      +    } +  } +  else  // <= 33 MHz     +  { +    // Disable wait-state +    flashc_set_wait_state(0); + +    // Disable the high-speed read mode. +    flashc_issue_command(AVR32_FLASHC_FCMD_CMD_HSDIS, -1); +     +  } +} +#endif // UC3C device-specific implementation + +//! @} diff --git a/firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/DRIVERS/FLASHC/flashc.h b/firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/DRIVERS/FLASHC/flashc.h new file mode 100644 index 0000000..9f2547a --- /dev/null +++ b/firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/DRIVERS/FLASHC/flashc.h @@ -0,0 +1,1002 @@ +/* This header file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */ + +/*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) 2009 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. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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 + * + */ + +#ifndef _FLASHC_H_ +#define _FLASHC_H_ + +#include <avr32/io.h> +#include <stddef.h> +#include "compiler.h" + +//! Number of flash regions defined by the FLASHC. +#define AVR32_FLASHC_REGIONS  (AVR32_FLASHC_FLASH_SIZE /\ +                               (AVR32_FLASHC_PAGES_PR_REGION * AVR32_FLASHC_PAGE_SIZE)) + + +/*! \name Flash Properties + */ +//! @{ + +/*! \brief Gets the size of the whole flash array. + * + * \return The size of the whole flash array in bytes. + */ +extern unsigned int flashc_get_flash_size(void); + +/*! \brief Gets the total number of pages in the flash array. + * + * \return The total number of pages in the flash array. + */ +extern unsigned int flashc_get_page_count(void); + +/*! \brief Gets the number of pages in each flash region. + * + * \return The number of pages in each flash region. + */ +extern unsigned int flashc_get_page_count_per_region(void); + +/*! \brief Gets the region number of a page. + * + * \param page_number The page number: + *   \arg \c 0 to <tt>(flashc_get_page_count() - 1)</tt>: a page number within + *        the flash array; + *   \arg <tt>< 0</tt>: the current page number. + * + * \return The region number of the specified page. + */ +extern unsigned int flashc_get_page_region(int page_number); + +/*! \brief Gets the number of the first page of a region. + * + * \param region The region number: \c 0 to <tt>(AVR32_FLASHC_REGIONS - 1)</tt>. + * + * \return The number of the first page of the specified region. + */ +extern unsigned int flashc_get_region_first_page_number(unsigned int region); + +//! @} + + +/*! \name FLASHC Control + */ +//! @{ + +/*! \brief Gets the number of wait states of flash read accesses. + * + * \return The number of wait states of flash read accesses. + */ +extern unsigned int flashc_get_wait_state(void); + +/*! \brief Sets the number of wait states of flash read accesses. + * + * \param wait_state The number of wait states of flash read accesses: \c 0 to + *                   \c 1. + */ +extern void flashc_set_wait_state(unsigned int wait_state); + +/*! \brief Tells whether the Flash Ready interrupt is enabled. + * + * \return Whether the Flash Ready interrupt is enabled. + */ +extern Bool flashc_is_ready_int_enabled(void); + +/*! \brief Enables or disables the Flash Ready interrupt. + * + * \param enable Whether to enable the Flash Ready interrupt: \c TRUE or + *               \c FALSE. + */ +extern void flashc_enable_ready_int(Bool enable); + +/*! \brief Tells whether the Lock Error interrupt is enabled. + * + * \return Whether the Lock Error interrupt is enabled. + */ +extern Bool flashc_is_lock_error_int_enabled(void); + +/*! \brief Enables or disables the Lock Error interrupt. + * + * \param enable Whether to enable the Lock Error interrupt: \c TRUE or + *               \c FALSE. + */ +extern void flashc_enable_lock_error_int(Bool enable); + +/*! \brief Tells whether the Programming Error interrupt is enabled. + * + * \return Whether the Programming Error interrupt is enabled. + */ +extern Bool flashc_is_prog_error_int_enabled(void); + +/*! \brief Enables or disables the Programming Error interrupt. + * + * \param enable Whether to enable the Programming Error interrupt: \c TRUE or + *               \c FALSE. + */ +extern void flashc_enable_prog_error_int(Bool enable); + +//! @} + + +/*! \name FLASHC Status + */ +//! @{ + +/*! \brief Tells whether the FLASHC is ready to run a new command. + * + * \return Whether the FLASHC is ready to run a new command. + */ +extern Bool flashc_is_ready(void); + +/*! \brief Waits actively until the FLASHC is ready to run a new command. + * + * This is the default function assigned to \ref flashc_wait_until_ready. + */ +extern void flashc_default_wait_until_ready(void); + +//! Pointer to the function used by the driver when it needs to wait until the +//! FLASHC is ready to run a new command. +//! The default function is \ref flashc_default_wait_until_ready. +//! The user may change this pointer to use another implementation. +extern void (*volatile flashc_wait_until_ready)(void); + +/*! \brief Tells whether a Lock Error has occurred during the last function + *         called that issued one or more FLASHC commands. + * + * \return Whether a Lock Error has occurred during the last function called + *         that issued one or more FLASHC commands. + */ +extern Bool flashc_is_lock_error(void); + +/*! \brief Tells whether a Programming Error has occurred during the last + *         function called that issued one or more FLASHC commands. + * + * \return Whether a Programming Error has occurred during the last function + *         called that issued one or more FLASHC commands. + */ +extern Bool flashc_is_programming_error(void); + +//! @} + + +/*! \name FLASHC Command Control + */ +//! @{ + +/*! \brief Gets the last issued FLASHC command. + * + * \return The last issued FLASHC command. + */ +extern unsigned int flashc_get_command(void); + +/*! \brief Gets the current FLASHC page number. + * + * \return The current FLASHC page number. + */ +extern unsigned int flashc_get_page_number(void); + +/*! \brief Issues a FLASHC command. + * + * \param command The command: \c AVR32_FLASHC_FCMD_CMD_x. + * \param page_number The page number to apply the command to: + *   \arg \c 0 to <tt>(flashc_get_page_count() - 1)</tt>: a page number within + *        the flash array; + *   \arg <tt>< 0</tt>: use this to apply the command to the current page number + *        or if the command does not apply to any page number; + *   \arg this argument may have other meanings according to the command. See + *        the FLASHC chapter of the MCU datasheet. + * + * \warning A Lock Error is issued if the command violates the protection + *          mechanism. + * + * \warning A Programming Error is issued if the command is invalid. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + *       \ref flashc_is_programming_error is updated. + */ +extern void flashc_issue_command(unsigned int command, int page_number); + +//! @} + + +/*! \name FLASHC Global Commands + */ +//! @{ + +/*! \brief Issues a No Operation command to the FLASHC. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + *       \ref flashc_is_programming_error is updated. + */ +extern void flashc_no_operation(void); + +/*! \brief Issues an Erase All command to the FLASHC. + * + * This command erases all bits in the flash array, the general-purpose fuse + * bits and the Security bit. The User page is not erased. + * + * This command also ensures that all volatile memories, such as register file + * and RAMs, are erased before the Security bit is erased, i.e. deactivated. + * + * \warning A Lock Error is issued if at least one region is locked or the + *          bootloader protection is active. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + *       \ref flashc_is_programming_error is updated. + * + * \note An erase operation can only set bits. + */ +extern void flashc_erase_all(void); + +//! @} + + +/*! \name FLASHC Protection Mechanisms + */ +//! @{ + +/*! \brief Tells whether the Security bit is active. + * + * \return Whether the Security bit is active. + */ +extern Bool flashc_is_security_bit_active(void); + +/*! \brief Activates the Security bit. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + *       \ref flashc_is_programming_error is updated. + */ +extern void flashc_activate_security_bit(void); + +/*! \brief Gets the bootloader protected size. + * + * \return The bootloader protected size in bytes. + */ +extern unsigned int flashc_get_bootloader_protected_size(void); + +/*! \brief Sets the bootloader protected size. + * + * \param bootprot_size The wanted bootloader protected size in bytes. If this + *                      size is not supported, the actual size will be the + *                      nearest greater available size or the maximal possible + *                      size if the requested size is too large. + * + * \return The actual bootloader protected size in bytes. + * + * \warning A Lock Error is issued if the Security bit is active. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + *       \ref flashc_is_programming_error is updated. + */ +extern unsigned int flashc_set_bootloader_protected_size(unsigned int bootprot_size); + +/*! \brief Tells whether external privileged fetch is locked. + * + * \return Whether external privileged fetch is locked. + */ +extern Bool flashc_is_external_privileged_fetch_locked(void); + +/*! \brief Locks or unlocks external privileged fetch. + * + * \param lock Whether to lock external privileged fetch: \c TRUE or \c FALSE. + * + * \warning A Lock Error is issued if the Security bit is active. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + *       \ref flashc_is_programming_error is updated. + */ +extern void flashc_lock_external_privileged_fetch(Bool lock); + +/*! \brief Tells whether the region of a page is locked. + * + * \param page_number The page number: + *   \arg \c 0 to <tt>(flashc_get_page_count() - 1)</tt>: a page number within + *        the flash array; + *   \arg <tt>< 0</tt>: the current page number. + * + * \return Whether the region of the specified page is locked. + */ +extern Bool flashc_is_page_region_locked(int page_number); + +/*! \brief Tells whether a region is locked. + * + * \param region The region number: \c 0 to <tt>(AVR32_FLASHC_REGIONS - 1)</tt>. + * + * \return Whether the specified region is locked. + */ +extern Bool flashc_is_region_locked(unsigned int region); + +/*! \brief Locks or unlocks the region of a page. + * + * \param page_number The page number: + *   \arg \c 0 to <tt>(flashc_get_page_count() - 1)</tt>: a page number within + *        the flash array; + *   \arg <tt>< 0</tt>: the current page number. + * \param lock Whether to lock the region of the specified page: \c TRUE or + *             \c FALSE. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + *       \ref flashc_is_programming_error is updated. + */ +extern void flashc_lock_page_region(int page_number, Bool lock); + +/*! \brief Locks or unlocks a region. + * + * \param region The region number: \c 0 to <tt>(AVR32_FLASHC_REGIONS - 1)</tt>. + * \param lock Whether to lock the specified region: \c TRUE or \c FALSE. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + *       \ref flashc_is_programming_error is updated. + */ +extern void flashc_lock_region(unsigned int region, Bool lock); + +/*! \brief Locks or unlocks all regions. + * + * \param lock Whether to lock the regions: \c TRUE or \c FALSE. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + *       \ref flashc_is_programming_error is updated. + */ +extern void flashc_lock_all_regions(Bool lock); + +//! @} + + +/*! \name Access to General-Purpose Fuses + */ +//! @{ + +/*! \brief Reads a general-purpose fuse bit. + * + * \param gp_fuse_bit The general-purpose fuse bit: \c 0 to \c 63. + * + * \return The value of the specified general-purpose fuse bit. + * + * \note The actual number of general-purpose fuse bits implemented by hardware + *       is given by \c AVR32_FLASHC_GPF_NUM. The other bits among the 64 are + *       fixed at 1 by hardware. + */ +extern Bool flashc_read_gp_fuse_bit(unsigned int gp_fuse_bit); + +/*! \brief Reads a general-purpose fuse bit-field. + * + * \param pos The bit-position of the general-purpose fuse bit-field: \c 0 to + *            \c 63. + * \param width The bit-width of the general-purpose fuse bit-field: \c 0 to + *              \c 64. + * + * \return The value of the specified general-purpose fuse bit-field. + * + * \note The actual number of general-purpose fuse bits implemented by hardware + *       is given by \c AVR32_FLASHC_GPF_NUM. The other bits among the 64 are + *       fixed at 1 by hardware. + */ +extern U64 flashc_read_gp_fuse_bitfield(unsigned int pos, unsigned int width); + +/*! \brief Reads a general-purpose fuse byte. + * + * \param gp_fuse_byte The general-purpose fuse byte: \c 0 to \c 7. + * + * \return The value of the specified general-purpose fuse byte. + * + * \note The actual number of general-purpose fuse bits implemented by hardware + *       is given by \c AVR32_FLASHC_GPF_NUM. The other bits among the 64 are + *       fixed at 1 by hardware. + */ +extern U8 flashc_read_gp_fuse_byte(unsigned int gp_fuse_byte); + +/*! \brief Reads all general-purpose fuses. + * + * \return The value of all general-purpose fuses as a word. + * + * \note The actual number of general-purpose fuse bits implemented by hardware + *       is given by \c AVR32_FLASHC_GPF_NUM. The other bits among the 64 are + *       fixed at 1 by hardware. + */ +extern U64 flashc_read_all_gp_fuses(void); + +/*! \brief Erases a general-purpose fuse bit. + * + * \param gp_fuse_bit The general-purpose fuse bit: \c 0 to \c 63. + * \param check Whether to check erase: \c TRUE or \c FALSE. + * + * \return Whether the erase succeeded or always \c TRUE if erase check was not + *         requested. + * + * \warning A Lock Error is issued if the Security bit is active and the command + *          is applied to BOOTPROT or EPFL fuses. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + *       \ref flashc_is_programming_error is updated. + * + * \note An erase operation can only set bits. + * + * \note The actual number of general-purpose fuse bits implemented by hardware + *       is given by \c AVR32_FLASHC_GPF_NUM. The other bits among the 64 are + *       fixed at 1 by hardware. + */ +extern Bool flashc_erase_gp_fuse_bit(unsigned int gp_fuse_bit, Bool check); + +/*! \brief Erases a general-purpose fuse bit-field. + * + * \param pos The bit-position of the general-purpose fuse bit-field: \c 0 to + *            \c 63. + * \param width The bit-width of the general-purpose fuse bit-field: \c 0 to + *              \c 64. + * \param check Whether to check erase: \c TRUE or \c FALSE. + * + * \return Whether the erase succeeded or always \c TRUE if erase check was not + *         requested. + * + * \warning A Lock Error is issued if the Security bit is active and the command + *          is applied to BOOTPROT or EPFL fuses. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + *       \ref flashc_is_programming_error is updated. + * + * \note An erase operation can only set bits. + * + * \note The actual number of general-purpose fuse bits implemented by hardware + *       is given by \c AVR32_FLASHC_GPF_NUM. The other bits among the 64 are + *       fixed at 1 by hardware. + */ +extern Bool flashc_erase_gp_fuse_bitfield(unsigned int pos, unsigned int width, Bool check); + +/*! \brief Erases a general-purpose fuse byte. + * + * \param gp_fuse_byte The general-purpose fuse byte: \c 0 to \c 7. + * \param check Whether to check erase: \c TRUE or \c FALSE. + * + * \return Whether the erase succeeded or always \c TRUE if erase check was not + *         requested. + * + * \warning A Lock Error is issued if the Security bit is active. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + *       \ref flashc_is_programming_error is updated. + * + * \note An erase operation can only set bits. + * + * \note The actual number of general-purpose fuse bits implemented by hardware + *       is given by \c AVR32_FLASHC_GPF_NUM. The other bits among the 64 are + *       fixed at 1 by hardware. + */ +extern Bool flashc_erase_gp_fuse_byte(unsigned int gp_fuse_byte, Bool check); + +/*! \brief Erases all general-purpose fuses. + * + * \param check Whether to check erase: \c TRUE or \c FALSE. + * + * \return Whether the erase succeeded or always \c TRUE if erase check was not + *         requested. + * + * \warning A Lock Error is issued if the Security bit is active. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + *       \ref flashc_is_programming_error is updated. + * + * \note An erase operation can only set bits. + * + * \note The actual number of general-purpose fuse bits implemented by hardware + *       is given by \c AVR32_FLASHC_GPF_NUM. The other bits among the 64 are + *       fixed at 1 by hardware. + */ +extern Bool flashc_erase_all_gp_fuses(Bool check); + +/*! \brief Writes a general-purpose fuse bit. + * + * \param gp_fuse_bit The general-purpose fuse bit: \c 0 to \c 63. + * \param value The value of the specified general-purpose fuse bit. + * + * \warning A Lock Error is issued if the Security bit is active and the command + *          is applied to BOOTPROT or EPFL fuses. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + *       \ref flashc_is_programming_error is updated. + * + * \note A write operation can only clear bits. + * + * \note The actual number of general-purpose fuse bits implemented by hardware + *       is given by \c AVR32_FLASHC_GPF_NUM. The other bits among the 64 are + *       fixed at 1 by hardware. + */ +extern void flashc_write_gp_fuse_bit(unsigned int gp_fuse_bit, Bool value); + +/*! \brief Writes a general-purpose fuse bit-field. + * + * \param pos The bit-position of the general-purpose fuse bit-field: \c 0 to + *            \c 63. + * \param width The bit-width of the general-purpose fuse bit-field: \c 0 to + *              \c 64. + * \param value The value of the specified general-purpose fuse bit-field. + * + * \warning A Lock Error is issued if the Security bit is active and the command + *          is applied to BOOTPROT or EPFL fuses. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + *       \ref flashc_is_programming_error is updated. + * + * \note A write operation can only clear bits. + * + * \note The actual number of general-purpose fuse bits implemented by hardware + *       is given by \c AVR32_FLASHC_GPF_NUM. The other bits among the 64 are + *       fixed at 1 by hardware. + */ +extern void flashc_write_gp_fuse_bitfield(unsigned int pos, unsigned int width, U64 value); + +/*! \brief Writes a general-purpose fuse byte. + * + * \param gp_fuse_byte The general-purpose fuse byte: \c 0 to \c 7. + * \param value The value of the specified general-purpose fuse byte. + * + * \warning A Lock Error is issued if the Security bit is active. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + *       \ref flashc_is_programming_error is updated. + * + * \note A write operation can only clear bits. + * + * \note The actual number of general-purpose fuse bits implemented by hardware + *       is given by \c AVR32_FLASHC_GPF_NUM. The other bits among the 64 are + *       fixed at 1 by hardware. + */ +extern void flashc_write_gp_fuse_byte(unsigned int gp_fuse_byte, U8 value); + +/*! \brief Writes all general-purpose fuses. + * + * \param value The value of all general-purpose fuses as a word. + * + * \warning A Lock Error is issued if the Security bit is active. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + *       \ref flashc_is_programming_error is updated. + * + * \note A write operation can only clear bits. + * + * \note The actual number of general-purpose fuse bits implemented by hardware + *       is given by \c AVR32_FLASHC_GPF_NUM. The other bits among the 64 are + *       fixed at 1 by hardware. + */ +extern void flashc_write_all_gp_fuses(U64 value); + +/*! \brief Sets a general-purpose fuse bit with the appropriate erase and write + *         operations. + * + * \param gp_fuse_bit The general-purpose fuse bit: \c 0 to \c 63. + * \param value The value of the specified general-purpose fuse bit. + * + * \warning A Lock Error is issued if the Security bit is active and the command + *          is applied to BOOTPROT or EPFL fuses. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + *       \ref flashc_is_programming_error is updated. + * + * \note The actual number of general-purpose fuse bits implemented by hardware + *       is given by \c AVR32_FLASHC_GPF_NUM. The other bits among the 64 are + *       fixed at 1 by hardware. + */ +extern void flashc_set_gp_fuse_bit(unsigned int gp_fuse_bit, Bool value); + +/*! \brief Sets a general-purpose fuse bit-field with the appropriate erase and + *         write operations. + * + * \param pos The bit-position of the general-purpose fuse bit-field: \c 0 to + *            \c 63. + * \param width The bit-width of the general-purpose fuse bit-field: \c 0 to + *              \c 64. + * \param value The value of the specified general-purpose fuse bit-field. + * + * \warning A Lock Error is issued if the Security bit is active and the command + *          is applied to BOOTPROT or EPFL fuses. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + *       \ref flashc_is_programming_error is updated. + * + * \note The actual number of general-purpose fuse bits implemented by hardware + *       is given by \c AVR32_FLASHC_GPF_NUM. The other bits among the 64 are + *       fixed at 1 by hardware. + */ +extern void flashc_set_gp_fuse_bitfield(unsigned int pos, unsigned int width, U64 value); + +/*! \brief Sets a general-purpose fuse byte with the appropriate erase and write + *         operations. + * + * \param gp_fuse_byte The general-purpose fuse byte: \c 0 to \c 7. + * \param value The value of the specified general-purpose fuse byte. + * + * \warning A Lock Error is issued if the Security bit is active. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + *       \ref flashc_is_programming_error is updated. + * + * \note The actual number of general-purpose fuse bits implemented by hardware + *       is given by \c AVR32_FLASHC_GPF_NUM. The other bits among the 64 are + *       fixed at 1 by hardware. + */ +extern void flashc_set_gp_fuse_byte(unsigned int gp_fuse_byte, U8 value); + +/*! \brief Sets all general-purpose fuses with the appropriate erase and write + *         operations. + * + * \param value The value of all general-purpose fuses as a word. + * + * \warning A Lock Error is issued if the Security bit is active. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + *       \ref flashc_is_programming_error is updated. + * + * \note The actual number of general-purpose fuse bits implemented by hardware + *       is given by \c AVR32_FLASHC_GPF_NUM. The other bits among the 64 are + *       fixed at 1 by hardware. + */ +extern void flashc_set_all_gp_fuses(U64 value); + +//! @} + + +/*! \name Access to Flash Pages + */ +//! @{ + +/*! \brief Clears the page buffer. + * + * This command resets all bits in the page buffer to one. Write accesses to the + * page buffer can only change page buffer bits from one to zero. + * + * \warning The page buffer is not automatically reset after a page write. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + *       \ref flashc_is_programming_error is updated. + */ +extern void flashc_clear_page_buffer(void); + +/*! \brief Tells whether the page to which the last Quick Page Read or Quick + *         Page Read User Page command was applied was erased. + * + * \return Whether the page to which the last Quick Page Read or Quick Page Read + *         User Page command was applied was erased. + */ +extern Bool flashc_is_page_erased(void); + +/*! \brief Applies the Quick Page Read command to a page. + * + * \param page_number The page number: + *   \arg \c 0 to <tt>(flashc_get_page_count() - 1)</tt>: a page number within + *        the flash array; + *   \arg <tt>< 0</tt>: the current page number. + * + * \return Whether the specified page is erased. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + *       \ref flashc_is_programming_error is updated. + */ +extern Bool flashc_quick_page_read(int page_number); + +/*! \brief Erases a page. + * + * \param page_number The page number: + *   \arg \c 0 to <tt>(flashc_get_page_count() - 1)</tt>: a page number within + *        the flash array; + *   \arg <tt>< 0</tt>: the current page number. + * \param check Whether to check erase: \c TRUE or \c FALSE. + * + * \return Whether the erase succeeded or always \c TRUE if erase check was not + *         requested. + * + * \warning A Lock Error is issued if the command is applied to a page belonging + *          to a locked region or to the bootloader protected area. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + *       \ref flashc_is_programming_error is updated. + * + * \note An erase operation can only set bits. + */ +extern Bool flashc_erase_page(int page_number, Bool check); + +/*! \brief Erases all pages within the flash array. + * + * \param check Whether to check erase: \c TRUE or \c FALSE. + * + * \return Whether the erase succeeded or always \c TRUE if erase check was not + *         requested. + * + * \warning A Lock Error is issued if at least one region is locked or the + *          bootloader protection is active. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + *       \ref flashc_is_programming_error is updated. + * + * \note An erase operation can only set bits. + */ +extern Bool flashc_erase_all_pages(Bool check); + +/*! \brief Writes a page from the page buffer. + * + * \param page_number The page number: + *   \arg \c 0 to <tt>(flashc_get_page_count() - 1)</tt>: a page number within + *        the flash array; + *   \arg <tt>< 0</tt>: the current page number. + * + * \warning A Lock Error is issued if the command is applied to a page belonging + *          to a locked region or to the bootloader protected area. + * + * \warning The page buffer is not automatically reset after a page write. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + *       \ref flashc_is_programming_error is updated. + * + * \note A write operation can only clear bits. + */ +extern void flashc_write_page(int page_number); + +/*! \brief Issues a Quick Page Read User Page command to the FLASHC. + * + * \return Whether the User page is erased. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + *       \ref flashc_is_programming_error is updated. + */ +extern Bool flashc_quick_user_page_read(void); + +/*! \brief Erases the User page. + * + * \param check Whether to check erase: \c TRUE or \c FALSE. + * + * \return Whether the erase succeeded or always \c TRUE if erase check was not + *         requested. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + *       \ref flashc_is_programming_error is updated. + * + * \note An erase operation can only set bits. + */ +extern Bool flashc_erase_user_page(Bool check); + +/*! \brief Writes the User page from the page buffer. + * + * \warning The page buffer is not automatically reset after a page write. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + *       \ref flashc_is_programming_error is updated. + * + * \note A write operation can only clear bits. + */ +extern void flashc_write_user_page(void); + +/*! \brief Copies \a nbytes bytes to the flash destination pointed to by \a dst + *         from the repeated \a src source byte. + * + * The destination areas that are not within the flash array or the User page + * are ignored. + * + * All pointer and size alignments are supported. + * + * \param dst Pointer to flash destination. + * \param src Source byte. + * \param nbytes Number of bytes to set. + * \param erase Whether to erase before writing: \c TRUE or \c FALSE. + * + * \return The value of \a dst. + * + * \warning This function may be called with \a erase set to \c FALSE only if + *          the destination consists only of erased words, i.e. this function + *          can not be used to write only one bit of a previously written word. + *          E.g., if \c 0x00000001 then \c 0xFFFFFFFE are written to a word, the + *          resulting value in flash may be different from \c 0x00000000. + * + * \warning A Lock Error is issued if the command is applied to pages belonging + *          to a locked region or to the bootloader protected area. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + *       \ref flashc_is_programming_error is updated. + */ +extern volatile void *flashc_memset8(volatile void *dst, U8 src, size_t nbytes, Bool erase); + +/*! \brief Copies \a nbytes bytes to the flash destination pointed to by \a dst + *         from the repeated \a src big-endian source half-word. + * + * The destination areas that are not within the flash array or the User page + * are ignored. + * + * All pointer and size alignments are supported. + * + * \param dst Pointer to flash destination. + * \param src Source half-word. + * \param nbytes Number of bytes to set. + * \param erase Whether to erase before writing: \c TRUE or \c FALSE. + * + * \return The value of \a dst. + * + * \warning This function may be called with \a erase set to \c FALSE only if + *          the destination consists only of erased words, i.e. this function + *          can not be used to write only one bit of a previously written word. + *          E.g., if \c 0x00000001 then \c 0xFFFFFFFE are written to a word, the + *          resulting value in flash may be different from \c 0x00000000. + * + * \warning A Lock Error is issued if the command is applied to pages belonging + *          to a locked region or to the bootloader protected area. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + *       \ref flashc_is_programming_error is updated. + */ +extern volatile void *flashc_memset16(volatile void *dst, U16 src, size_t nbytes, Bool erase); + +/*! \brief Copies \a nbytes bytes to the flash destination pointed to by \a dst + *         from the repeated \a src big-endian source word. + * + * The destination areas that are not within the flash array or the User page + * are ignored. + * + * All pointer and size alignments are supported. + * + * \param dst Pointer to flash destination. + * \param src Source word. + * \param nbytes Number of bytes to set. + * \param erase Whether to erase before writing: \c TRUE or \c FALSE. + * + * \return The value of \a dst. + * + * \warning This function may be called with \a erase set to \c FALSE only if + *          the destination consists only of erased words, i.e. this function + *          can not be used to write only one bit of a previously written word. + *          E.g., if \c 0x00000001 then \c 0xFFFFFFFE are written to a word, the + *          resulting value in flash may be different from \c 0x00000000. + * + * \warning A Lock Error is issued if the command is applied to pages belonging + *          to a locked region or to the bootloader protected area. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + *       \ref flashc_is_programming_error is updated. + */ +extern volatile void *flashc_memset32(volatile void *dst, U32 src, size_t nbytes, Bool erase); + +/*! \brief Copies \a nbytes bytes to the flash destination pointed to by \a dst + *         from the repeated \a src big-endian source double-word. + * + * The destination areas that are not within the flash array or the User page + * are ignored. + * + * All pointer and size alignments are supported. + * + * \param dst Pointer to flash destination. + * \param src Source double-word. + * \param nbytes Number of bytes to set. + * \param erase Whether to erase before writing: \c TRUE or \c FALSE. + * + * \return The value of \a dst. + * + * \warning This function may be called with \a erase set to \c FALSE only if + *          the destination consists only of erased words, i.e. this function + *          can not be used to write only one bit of a previously written word. + *          E.g., if \c 0x00000001 then \c 0xFFFFFFFE are written to a word, the + *          resulting value in flash may be different from \c 0x00000000. + * + * \warning A Lock Error is issued if the command is applied to pages belonging + *          to a locked region or to the bootloader protected area. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + *       \ref flashc_is_programming_error is updated. + */ +extern volatile void *flashc_memset64(volatile void *dst, U64 src, size_t nbytes, Bool erase); + +/*! \brief Copies \a nbytes bytes to the flash destination pointed to by \a dst + *         from the repeated \a src big-endian source pattern. + * + * The destination areas that are not within the flash array or the User page + * are ignored. + * + * All pointer and size alignments are supported. + * + * \param dst Pointer to flash destination. + * \param src Source double-word. + * \param src_width \a src width in bits: 8, 16, 32 or 64. + * \param nbytes Number of bytes to set. + * \param erase Whether to erase before writing: \c TRUE or \c FALSE. + * + * \return The value of \a dst. + * + * \warning This function may be called with \a erase set to \c FALSE only if + *          the destination consists only of erased words, i.e. this function + *          can not be used to write only one bit of a previously written word. + *          E.g., if \c 0x00000001 then \c 0xFFFFFFFE are written to a word, the + *          resulting value in flash may be different from \c 0x00000000. + * + * \warning A Lock Error is issued if the command is applied to pages belonging + *          to a locked region or to the bootloader protected area. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + *       \ref flashc_is_programming_error is updated. + */ +#define flashc_memset(dst, src, src_width, nbytes, erase) \ +          TPASTE2(flashc_memset, src_width)((dst), (src), (nbytes), (erase)) + +/*! \brief Copies \a nbytes bytes to the flash destination pointed to by \a dst + *         from the source pointed to by \a src. + * + * The destination areas that are not within the flash array or the User page + * are ignored. + * + * All pointer and size alignments are supported. + * + * \param dst Pointer to flash destination. + * \param src Pointer to source data. + * \param nbytes Number of bytes to copy. + * \param erase Whether to erase before writing: \c TRUE or \c FALSE. + * + * \return The value of \a dst. + * + * \warning If copying takes place between areas that overlap, the behavior is + *          undefined. + * + * \warning This function may be called with \a erase set to \c FALSE only if + *          the destination consists only of erased words, i.e. this function + *          can not be used to write only one bit of a previously written word. + *          E.g., if \c 0x00000001 then \c 0xFFFFFFFE are written to a word, the + *          resulting value in flash may be different from \c 0x00000000. + * + * \warning A Lock Error is issued if the command is applied to pages belonging + *          to a locked region or to the bootloader protected area. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + *       \ref flashc_is_programming_error is updated. + */ +extern volatile void *flashc_memcpy(volatile void *dst, const void *src, size_t nbytes, Bool erase); + +#if UC3C + +/*! \brief Depednding to the CPU frequency, set the wait states of flash read + *         accesses and enable or disable the High speed read mode. + * + * \param cpu_f_hz The CPU frequency + */ +void flashc_set_flash_waitstate_and_readmode(unsigned long cpu_f_hz); +#endif // UC3C device-specific implementation + +//! @} + + +#endif  // _FLASHC_H_ | 
