Color Oled(SSD1331) connect to STMicroelectronics Nucleo-F466

Dependencies:   ssd1331

Committer:
kadonotakashi
Date:
Wed Oct 10 00:33:53 2018 +0000
Revision:
0:8fdf9a60065b
how to make mbed librry

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kadonotakashi 0:8fdf9a60065b 1 /**
kadonotakashi 0:8fdf9a60065b 2 * \file
kadonotakashi 0:8fdf9a60065b 3 *
kadonotakashi 0:8fdf9a60065b 4 * \brief Enhanced Embedded Flash Controller (EEFC) driver for SAM.
kadonotakashi 0:8fdf9a60065b 5 *
kadonotakashi 0:8fdf9a60065b 6 * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved.
kadonotakashi 0:8fdf9a60065b 7 *
kadonotakashi 0:8fdf9a60065b 8 * \asf_license_start
kadonotakashi 0:8fdf9a60065b 9 *
kadonotakashi 0:8fdf9a60065b 10 * \page License
kadonotakashi 0:8fdf9a60065b 11 *
kadonotakashi 0:8fdf9a60065b 12 * Redistribution and use in source and binary forms, with or without
kadonotakashi 0:8fdf9a60065b 13 * modification, are permitted provided that the following conditions are met:
kadonotakashi 0:8fdf9a60065b 14 *
kadonotakashi 0:8fdf9a60065b 15 * 1. Redistributions of source code must retain the above copyright notice,
kadonotakashi 0:8fdf9a60065b 16 * this list of conditions and the following disclaimer.
kadonotakashi 0:8fdf9a60065b 17 *
kadonotakashi 0:8fdf9a60065b 18 * 2. Redistributions in binary form must reproduce the above copyright notice,
kadonotakashi 0:8fdf9a60065b 19 * this list of conditions and the following disclaimer in the documentation
kadonotakashi 0:8fdf9a60065b 20 * and/or other materials provided with the distribution.
kadonotakashi 0:8fdf9a60065b 21 *
kadonotakashi 0:8fdf9a60065b 22 * 3. The name of Atmel may not be used to endorse or promote products derived
kadonotakashi 0:8fdf9a60065b 23 * from this software without specific prior written permission.
kadonotakashi 0:8fdf9a60065b 24 *
kadonotakashi 0:8fdf9a60065b 25 * 4. This software may only be redistributed and used in connection with an
kadonotakashi 0:8fdf9a60065b 26 * Atmel microcontroller product.
kadonotakashi 0:8fdf9a60065b 27 *
kadonotakashi 0:8fdf9a60065b 28 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
kadonotakashi 0:8fdf9a60065b 29 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
kadonotakashi 0:8fdf9a60065b 30 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
kadonotakashi 0:8fdf9a60065b 31 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
kadonotakashi 0:8fdf9a60065b 32 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
kadonotakashi 0:8fdf9a60065b 33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
kadonotakashi 0:8fdf9a60065b 34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
kadonotakashi 0:8fdf9a60065b 35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
kadonotakashi 0:8fdf9a60065b 36 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
kadonotakashi 0:8fdf9a60065b 37 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
kadonotakashi 0:8fdf9a60065b 38 * POSSIBILITY OF SUCH DAMAGE.
kadonotakashi 0:8fdf9a60065b 39 *
kadonotakashi 0:8fdf9a60065b 40 * \asf_license_stop
kadonotakashi 0:8fdf9a60065b 41 *
kadonotakashi 0:8fdf9a60065b 42 */
kadonotakashi 0:8fdf9a60065b 43 /*
kadonotakashi 0:8fdf9a60065b 44 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
kadonotakashi 0:8fdf9a60065b 45 */
kadonotakashi 0:8fdf9a60065b 46
kadonotakashi 0:8fdf9a60065b 47 #include "efc.h"
kadonotakashi 0:8fdf9a60065b 48
kadonotakashi 0:8fdf9a60065b 49 /// @cond 0
kadonotakashi 0:8fdf9a60065b 50 /**INDENT-OFF**/
kadonotakashi 0:8fdf9a60065b 51 #ifdef __cplusplus
kadonotakashi 0:8fdf9a60065b 52 extern "C" {
kadonotakashi 0:8fdf9a60065b 53 #endif
kadonotakashi 0:8fdf9a60065b 54 /**INDENT-ON**/
kadonotakashi 0:8fdf9a60065b 55 /// @endcond
kadonotakashi 0:8fdf9a60065b 56
kadonotakashi 0:8fdf9a60065b 57 /**
kadonotakashi 0:8fdf9a60065b 58 * \defgroup sam_drivers_efc_group Enhanced Embedded Flash Controller (EEFC)
kadonotakashi 0:8fdf9a60065b 59 *
kadonotakashi 0:8fdf9a60065b 60 * The Enhanced Embedded Flash Controller ensures the interface of the Flash
kadonotakashi 0:8fdf9a60065b 61 * block with the 32-bit internal bus.
kadonotakashi 0:8fdf9a60065b 62 *
kadonotakashi 0:8fdf9a60065b 63 * @{
kadonotakashi 0:8fdf9a60065b 64 */
kadonotakashi 0:8fdf9a60065b 65
kadonotakashi 0:8fdf9a60065b 66 /* Address definition for read operation */
kadonotakashi 0:8fdf9a60065b 67 #if (SAM3XA || SAM3U4 || SAM4SD16 || SAM4SD32)
kadonotakashi 0:8fdf9a60065b 68 # define READ_BUFF_ADDR0 IFLASH0_ADDR
kadonotakashi 0:8fdf9a60065b 69 # define READ_BUFF_ADDR1 IFLASH1_ADDR
kadonotakashi 0:8fdf9a60065b 70 #elif (SAM3S || SAM3N || SAM4E || SAM4N || SAMG || SAMV71 || SAMV70 || SAMS70 || SAME70)
kadonotakashi 0:8fdf9a60065b 71 # define READ_BUFF_ADDR IFLASH_ADDR
kadonotakashi 0:8fdf9a60065b 72 #elif (SAM4C || SAM4CP || SAM4CM)
kadonotakashi 0:8fdf9a60065b 73 #if SAM4C32
kadonotakashi 0:8fdf9a60065b 74 # define READ_BUFF_ADDR0 IFLASH0_CNC_ADDR
kadonotakashi 0:8fdf9a60065b 75 # define READ_BUFF_ADDR1 IFLASH1_CNC_ADDR
kadonotakashi 0:8fdf9a60065b 76 #else
kadonotakashi 0:8fdf9a60065b 77 # define READ_BUFF_ADDR IFLASH_CNC_ADDR
kadonotakashi 0:8fdf9a60065b 78 #endif
kadonotakashi 0:8fdf9a60065b 79 #elif (SAM3U || SAM4S)
kadonotakashi 0:8fdf9a60065b 80 # define READ_BUFF_ADDR IFLASH0_ADDR
kadonotakashi 0:8fdf9a60065b 81 #else
kadonotakashi 0:8fdf9a60065b 82 # warning Only reading unique ID for sam3/4 is implemented.
kadonotakashi 0:8fdf9a60065b 83 #endif
kadonotakashi 0:8fdf9a60065b 84
kadonotakashi 0:8fdf9a60065b 85 /* Flash Writing Protection Key */
kadonotakashi 0:8fdf9a60065b 86 #define FWP_KEY 0x5Au
kadonotakashi 0:8fdf9a60065b 87
kadonotakashi 0:8fdf9a60065b 88 #if (SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM)
kadonotakashi 0:8fdf9a60065b 89 #define EEFC_FCR_FCMD(value) \
kadonotakashi 0:8fdf9a60065b 90 ((EEFC_FCR_FCMD_Msk & ((value) << EEFC_FCR_FCMD_Pos)))
kadonotakashi 0:8fdf9a60065b 91 #define EEFC_ERROR_FLAGS (EEFC_FSR_FLOCKE | EEFC_FSR_FCMDE | EEFC_FSR_FLERR)
kadonotakashi 0:8fdf9a60065b 92 #elif (SAMV71 || SAMV70 || SAMS70 || SAME70)
kadonotakashi 0:8fdf9a60065b 93 #define EEFC_ERROR_FLAGS (EEFC_FSR_FLOCKE | EEFC_FSR_FCMDE | EEFC_FSR_FLERR \
kadonotakashi 0:8fdf9a60065b 94 | EEFC_FSR_UECCELSB | EEFC_FSR_MECCELSB | EEFC_FSR_UECCEMSB | EEFC_FSR_MECCEMSB)
kadonotakashi 0:8fdf9a60065b 95 #else
kadonotakashi 0:8fdf9a60065b 96 #define EEFC_ERROR_FLAGS (EEFC_FSR_FLOCKE | EEFC_FSR_FCMDE)
kadonotakashi 0:8fdf9a60065b 97 #endif
kadonotakashi 0:8fdf9a60065b 98
kadonotakashi 0:8fdf9a60065b 99 #ifndef EEFC_FCR_FKEY_PASSWD
kadonotakashi 0:8fdf9a60065b 100 #define EEFC_FCR_FKEY_PASSWD EEFC_FCR_FKEY(FWP_KEY)
kadonotakashi 0:8fdf9a60065b 101 #endif
kadonotakashi 0:8fdf9a60065b 102
kadonotakashi 0:8fdf9a60065b 103
kadonotakashi 0:8fdf9a60065b 104 /*
kadonotakashi 0:8fdf9a60065b 105 * Local function declaration.
kadonotakashi 0:8fdf9a60065b 106 * Because they are RAM functions, they need 'extern' declaration.
kadonotakashi 0:8fdf9a60065b 107 */
kadonotakashi 0:8fdf9a60065b 108 extern void efc_write_fmr(Efc *p_efc, uint32_t ul_fmr);
kadonotakashi 0:8fdf9a60065b 109 extern uint32_t efc_perform_fcr(Efc *p_efc, uint32_t ul_fcr);
kadonotakashi 0:8fdf9a60065b 110
kadonotakashi 0:8fdf9a60065b 111 /**
kadonotakashi 0:8fdf9a60065b 112 * \brief Initialize the EFC controller.
kadonotakashi 0:8fdf9a60065b 113 *
kadonotakashi 0:8fdf9a60065b 114 * \param ul_access_mode 0 for 128-bit, EEFC_FMR_FAM for 64-bit.
kadonotakashi 0:8fdf9a60065b 115 * \param ul_fws The number of wait states in cycle (no shift).
kadonotakashi 0:8fdf9a60065b 116 *
kadonotakashi 0:8fdf9a60065b 117 * \return 0 if successful.
kadonotakashi 0:8fdf9a60065b 118 */
kadonotakashi 0:8fdf9a60065b 119 uint32_t efc_init(Efc *p_efc, uint32_t ul_access_mode, uint32_t ul_fws)
kadonotakashi 0:8fdf9a60065b 120 {
kadonotakashi 0:8fdf9a60065b 121 #if (SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM || \
kadonotakashi 0:8fdf9a60065b 122 SAMV71 || SAMV70 || SAMS70 || SAME70)
kadonotakashi 0:8fdf9a60065b 123 efc_write_fmr(p_efc, ul_access_mode | EEFC_FMR_FWS(ul_fws) | EEFC_FMR_CLOE);
kadonotakashi 0:8fdf9a60065b 124 #else
kadonotakashi 0:8fdf9a60065b 125 efc_write_fmr(p_efc, ul_access_mode | EEFC_FMR_FWS(ul_fws));
kadonotakashi 0:8fdf9a60065b 126 #endif
kadonotakashi 0:8fdf9a60065b 127 return EFC_RC_OK;
kadonotakashi 0:8fdf9a60065b 128 }
kadonotakashi 0:8fdf9a60065b 129
kadonotakashi 0:8fdf9a60065b 130 #if (SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM || \
kadonotakashi 0:8fdf9a60065b 131 SAMV71 || SAMV70 || SAMS70 || SAME70)
kadonotakashi 0:8fdf9a60065b 132 /**
kadonotakashi 0:8fdf9a60065b 133 * \brief Enable code loop optimization.
kadonotakashi 0:8fdf9a60065b 134 *
kadonotakashi 0:8fdf9a60065b 135 * \param p_efc Pointer to an EFC instance.
kadonotakashi 0:8fdf9a60065b 136 */
kadonotakashi 0:8fdf9a60065b 137 void efc_enable_cloe(Efc *p_efc)
kadonotakashi 0:8fdf9a60065b 138 {
kadonotakashi 0:8fdf9a60065b 139 uint32_t ul_fmr = p_efc->EEFC_FMR;
kadonotakashi 0:8fdf9a60065b 140 efc_write_fmr(p_efc, ul_fmr | EEFC_FMR_CLOE);
kadonotakashi 0:8fdf9a60065b 141 }
kadonotakashi 0:8fdf9a60065b 142
kadonotakashi 0:8fdf9a60065b 143 /**
kadonotakashi 0:8fdf9a60065b 144 * \brief Disable code loop optimization.
kadonotakashi 0:8fdf9a60065b 145 *
kadonotakashi 0:8fdf9a60065b 146 * \param p_efc Pointer to an EFC instance.
kadonotakashi 0:8fdf9a60065b 147 */
kadonotakashi 0:8fdf9a60065b 148 void efc_disable_cloe(Efc *p_efc)
kadonotakashi 0:8fdf9a60065b 149 {
kadonotakashi 0:8fdf9a60065b 150 uint32_t ul_fmr = p_efc->EEFC_FMR;
kadonotakashi 0:8fdf9a60065b 151 efc_write_fmr(p_efc, ul_fmr & (~EEFC_FMR_CLOE));
kadonotakashi 0:8fdf9a60065b 152 }
kadonotakashi 0:8fdf9a60065b 153 #endif
kadonotakashi 0:8fdf9a60065b 154
kadonotakashi 0:8fdf9a60065b 155
kadonotakashi 0:8fdf9a60065b 156
kadonotakashi 0:8fdf9a60065b 157 /**
kadonotakashi 0:8fdf9a60065b 158 * \brief Enable the flash ready interrupt.
kadonotakashi 0:8fdf9a60065b 159 *
kadonotakashi 0:8fdf9a60065b 160 * \param p_efc Pointer to an EFC instance.
kadonotakashi 0:8fdf9a60065b 161 */
kadonotakashi 0:8fdf9a60065b 162 void efc_enable_frdy_interrupt(Efc *p_efc)
kadonotakashi 0:8fdf9a60065b 163 {
kadonotakashi 0:8fdf9a60065b 164 uint32_t ul_fmr = p_efc->EEFC_FMR;
kadonotakashi 0:8fdf9a60065b 165
kadonotakashi 0:8fdf9a60065b 166 efc_write_fmr(p_efc, ul_fmr | EEFC_FMR_FRDY);
kadonotakashi 0:8fdf9a60065b 167 }
kadonotakashi 0:8fdf9a60065b 168
kadonotakashi 0:8fdf9a60065b 169 /**
kadonotakashi 0:8fdf9a60065b 170 * \brief Disable the flash ready interrupt.
kadonotakashi 0:8fdf9a60065b 171 *
kadonotakashi 0:8fdf9a60065b 172 * \param p_efc Pointer to an EFC instance.
kadonotakashi 0:8fdf9a60065b 173 */
kadonotakashi 0:8fdf9a60065b 174 void efc_disable_frdy_interrupt(Efc *p_efc)
kadonotakashi 0:8fdf9a60065b 175 {
kadonotakashi 0:8fdf9a60065b 176 uint32_t ul_fmr = p_efc->EEFC_FMR;
kadonotakashi 0:8fdf9a60065b 177
kadonotakashi 0:8fdf9a60065b 178 efc_write_fmr(p_efc, ul_fmr & (~EEFC_FMR_FRDY));
kadonotakashi 0:8fdf9a60065b 179 }
kadonotakashi 0:8fdf9a60065b 180
kadonotakashi 0:8fdf9a60065b 181 #if (SAMV71 || SAMV70 || SAMS70 || SAME70)
kadonotakashi 0:8fdf9a60065b 182 /**
kadonotakashi 0:8fdf9a60065b 183 * \brief Enable the write protection.
kadonotakashi 0:8fdf9a60065b 184 *
kadonotakashi 0:8fdf9a60065b 185 * \param p_efc Pointer to an EFC instance.
kadonotakashi 0:8fdf9a60065b 186 */
kadonotakashi 0:8fdf9a60065b 187 void efc_enable_write_protection(Efc *p_efc)
kadonotakashi 0:8fdf9a60065b 188 {
kadonotakashi 0:8fdf9a60065b 189 p_efc->EEFC_WPMR = EEFC_WPMR_WPKEY_PASSWD | EEFC_WPMR_WPEN;
kadonotakashi 0:8fdf9a60065b 190 }
kadonotakashi 0:8fdf9a60065b 191
kadonotakashi 0:8fdf9a60065b 192 /**
kadonotakashi 0:8fdf9a60065b 193 * \brief Disable the write protection.
kadonotakashi 0:8fdf9a60065b 194 *
kadonotakashi 0:8fdf9a60065b 195 * \param p_efc Pointer to an EFC instance.
kadonotakashi 0:8fdf9a60065b 196 */
kadonotakashi 0:8fdf9a60065b 197 void efc_disable_write_protection(Efc *p_efc)
kadonotakashi 0:8fdf9a60065b 198 {
kadonotakashi 0:8fdf9a60065b 199 p_efc->EEFC_WPMR = EEFC_WPMR_WPKEY_PASSWD;
kadonotakashi 0:8fdf9a60065b 200 }
kadonotakashi 0:8fdf9a60065b 201 #else
kadonotakashi 0:8fdf9a60065b 202 /**
kadonotakashi 0:8fdf9a60065b 203 * \brief Set flash access mode.
kadonotakashi 0:8fdf9a60065b 204 *
kadonotakashi 0:8fdf9a60065b 205 * \param p_efc Pointer to an EFC instance.
kadonotakashi 0:8fdf9a60065b 206 * \param ul_mode 0 for 128-bit, EEFC_FMR_FAM for 64-bit.
kadonotakashi 0:8fdf9a60065b 207 */
kadonotakashi 0:8fdf9a60065b 208 void efc_set_flash_access_mode(Efc *p_efc, uint32_t ul_mode)
kadonotakashi 0:8fdf9a60065b 209 {
kadonotakashi 0:8fdf9a60065b 210 uint32_t ul_fmr = p_efc->EEFC_FMR & (~EEFC_FMR_FAM);
kadonotakashi 0:8fdf9a60065b 211
kadonotakashi 0:8fdf9a60065b 212 efc_write_fmr(p_efc, ul_fmr | ul_mode);
kadonotakashi 0:8fdf9a60065b 213 }
kadonotakashi 0:8fdf9a60065b 214
kadonotakashi 0:8fdf9a60065b 215 /**
kadonotakashi 0:8fdf9a60065b 216 * \brief Get flash access mode.
kadonotakashi 0:8fdf9a60065b 217 *
kadonotakashi 0:8fdf9a60065b 218 * \param p_efc Pointer to an EFC instance.
kadonotakashi 0:8fdf9a60065b 219 *
kadonotakashi 0:8fdf9a60065b 220 * \return 0 for 128-bit or EEFC_FMR_FAM for 64-bit.
kadonotakashi 0:8fdf9a60065b 221 */
kadonotakashi 0:8fdf9a60065b 222 uint32_t efc_get_flash_access_mode(Efc *p_efc)
kadonotakashi 0:8fdf9a60065b 223 {
kadonotakashi 0:8fdf9a60065b 224 return (p_efc->EEFC_FMR & EEFC_FMR_FAM);
kadonotakashi 0:8fdf9a60065b 225 }
kadonotakashi 0:8fdf9a60065b 226 #endif
kadonotakashi 0:8fdf9a60065b 227
kadonotakashi 0:8fdf9a60065b 228 /**
kadonotakashi 0:8fdf9a60065b 229 * \brief Set flash wait state.
kadonotakashi 0:8fdf9a60065b 230 *
kadonotakashi 0:8fdf9a60065b 231 * \param p_efc Pointer to an EFC instance.
kadonotakashi 0:8fdf9a60065b 232 * \param ul_fws The number of wait states in cycle (no shift).
kadonotakashi 0:8fdf9a60065b 233 */
kadonotakashi 0:8fdf9a60065b 234 void efc_set_wait_state(Efc *p_efc, uint32_t ul_fws)
kadonotakashi 0:8fdf9a60065b 235 {
kadonotakashi 0:8fdf9a60065b 236 uint32_t ul_fmr = p_efc->EEFC_FMR & (~EEFC_FMR_FWS_Msk);
kadonotakashi 0:8fdf9a60065b 237
kadonotakashi 0:8fdf9a60065b 238 efc_write_fmr(p_efc, ul_fmr | EEFC_FMR_FWS(ul_fws));
kadonotakashi 0:8fdf9a60065b 239 }
kadonotakashi 0:8fdf9a60065b 240
kadonotakashi 0:8fdf9a60065b 241 /**
kadonotakashi 0:8fdf9a60065b 242 * \brief Get flash wait state.
kadonotakashi 0:8fdf9a60065b 243 *
kadonotakashi 0:8fdf9a60065b 244 * \param p_efc Pointer to an EFC instance.
kadonotakashi 0:8fdf9a60065b 245 *
kadonotakashi 0:8fdf9a60065b 246 * \return The number of wait states in cycle (no shift).
kadonotakashi 0:8fdf9a60065b 247 */
kadonotakashi 0:8fdf9a60065b 248 uint32_t efc_get_wait_state(Efc *p_efc)
kadonotakashi 0:8fdf9a60065b 249 {
kadonotakashi 0:8fdf9a60065b 250 return ((p_efc->EEFC_FMR & EEFC_FMR_FWS_Msk) >> EEFC_FMR_FWS_Pos);
kadonotakashi 0:8fdf9a60065b 251 }
kadonotakashi 0:8fdf9a60065b 252
kadonotakashi 0:8fdf9a60065b 253 /**
kadonotakashi 0:8fdf9a60065b 254 * \brief Perform the given command and wait until its completion (or an error).
kadonotakashi 0:8fdf9a60065b 255 *
kadonotakashi 0:8fdf9a60065b 256 * \note Unique ID commands are not supported, use efc_perform_read_sequence.
kadonotakashi 0:8fdf9a60065b 257 *
kadonotakashi 0:8fdf9a60065b 258 * \param p_efc Pointer to an EFC instance.
kadonotakashi 0:8fdf9a60065b 259 * \param ul_command Command to perform.
kadonotakashi 0:8fdf9a60065b 260 * \param ul_argument Optional command argument.
kadonotakashi 0:8fdf9a60065b 261 *
kadonotakashi 0:8fdf9a60065b 262 * \note This function will automatically choose to use IAP function.
kadonotakashi 0:8fdf9a60065b 263 *
kadonotakashi 0:8fdf9a60065b 264 * \return 0 if successful, otherwise returns an error code.
kadonotakashi 0:8fdf9a60065b 265 */
kadonotakashi 0:8fdf9a60065b 266 uint32_t efc_perform_command(Efc *p_efc, uint32_t ul_command,
kadonotakashi 0:8fdf9a60065b 267 uint32_t ul_argument)
kadonotakashi 0:8fdf9a60065b 268 {
kadonotakashi 0:8fdf9a60065b 269 uint32_t result;
kadonotakashi 0:8fdf9a60065b 270 irqflags_t flags;
kadonotakashi 0:8fdf9a60065b 271
kadonotakashi 0:8fdf9a60065b 272 /* Unique ID commands are not supported. */
kadonotakashi 0:8fdf9a60065b 273 if (ul_command == EFC_FCMD_STUI || ul_command == EFC_FCMD_SPUI) {
kadonotakashi 0:8fdf9a60065b 274 return EFC_RC_NOT_SUPPORT;
kadonotakashi 0:8fdf9a60065b 275 }
kadonotakashi 0:8fdf9a60065b 276
kadonotakashi 0:8fdf9a60065b 277 flags = cpu_irq_save();
kadonotakashi 0:8fdf9a60065b 278 /* Use RAM Function. */
kadonotakashi 0:8fdf9a60065b 279 result = efc_perform_fcr(p_efc,
kadonotakashi 0:8fdf9a60065b 280 EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FARG(ul_argument) |
kadonotakashi 0:8fdf9a60065b 281 EEFC_FCR_FCMD(ul_command));
kadonotakashi 0:8fdf9a60065b 282 cpu_irq_restore(flags);
kadonotakashi 0:8fdf9a60065b 283 return result;
kadonotakashi 0:8fdf9a60065b 284 }
kadonotakashi 0:8fdf9a60065b 285
kadonotakashi 0:8fdf9a60065b 286 /**
kadonotakashi 0:8fdf9a60065b 287 * \brief Get the current status of the EEFC.
kadonotakashi 0:8fdf9a60065b 288 *
kadonotakashi 0:8fdf9a60065b 289 * \note This function clears the value of some status bits (FLOCKE, FCMDE).
kadonotakashi 0:8fdf9a60065b 290 *
kadonotakashi 0:8fdf9a60065b 291 * \param p_efc Pointer to an EFC instance.
kadonotakashi 0:8fdf9a60065b 292 *
kadonotakashi 0:8fdf9a60065b 293 * \return The current status.
kadonotakashi 0:8fdf9a60065b 294 */
kadonotakashi 0:8fdf9a60065b 295 uint32_t efc_get_status(Efc *p_efc)
kadonotakashi 0:8fdf9a60065b 296 {
kadonotakashi 0:8fdf9a60065b 297 return p_efc->EEFC_FSR;
kadonotakashi 0:8fdf9a60065b 298 }
kadonotakashi 0:8fdf9a60065b 299
kadonotakashi 0:8fdf9a60065b 300 /**
kadonotakashi 0:8fdf9a60065b 301 * \brief Get the result of the last executed command.
kadonotakashi 0:8fdf9a60065b 302 *
kadonotakashi 0:8fdf9a60065b 303 * \param p_efc Pointer to an EFC instance.
kadonotakashi 0:8fdf9a60065b 304 *
kadonotakashi 0:8fdf9a60065b 305 * \return The result of the last executed command.
kadonotakashi 0:8fdf9a60065b 306 */
kadonotakashi 0:8fdf9a60065b 307 uint32_t efc_get_result(Efc *p_efc)
kadonotakashi 0:8fdf9a60065b 308 {
kadonotakashi 0:8fdf9a60065b 309 return p_efc->EEFC_FRR;
kadonotakashi 0:8fdf9a60065b 310 }
kadonotakashi 0:8fdf9a60065b 311
kadonotakashi 0:8fdf9a60065b 312 /**
kadonotakashi 0:8fdf9a60065b 313 * \brief Perform read sequence. Supported sequences are read Unique ID and
kadonotakashi 0:8fdf9a60065b 314 * read User Signature
kadonotakashi 0:8fdf9a60065b 315 *
kadonotakashi 0:8fdf9a60065b 316 * \param p_efc Pointer to an EFC instance.
kadonotakashi 0:8fdf9a60065b 317 * \param ul_cmd_st Start command to perform.
kadonotakashi 0:8fdf9a60065b 318 * \param ul_cmd_sp Stop command to perform.
kadonotakashi 0:8fdf9a60065b 319 * \param p_ul_buf Pointer to an data buffer.
kadonotakashi 0:8fdf9a60065b 320 * \param ul_size Buffer size.
kadonotakashi 0:8fdf9a60065b 321 *
kadonotakashi 0:8fdf9a60065b 322 * \return 0 if successful, otherwise returns an error code.
kadonotakashi 0:8fdf9a60065b 323 */
kadonotakashi 0:8fdf9a60065b 324 __no_inline
kadonotakashi 0:8fdf9a60065b 325 RAMFUNC
kadonotakashi 0:8fdf9a60065b 326 uint32_t efc_perform_read_sequence(Efc *p_efc,
kadonotakashi 0:8fdf9a60065b 327 uint32_t ul_cmd_st, uint32_t ul_cmd_sp,
kadonotakashi 0:8fdf9a60065b 328 uint32_t *p_ul_buf, uint32_t ul_size)
kadonotakashi 0:8fdf9a60065b 329 {
kadonotakashi 0:8fdf9a60065b 330 volatile uint32_t ul_status;
kadonotakashi 0:8fdf9a60065b 331 uint32_t ul_cnt;
kadonotakashi 0:8fdf9a60065b 332
kadonotakashi 0:8fdf9a60065b 333 #if (SAM3U4 || SAM3XA || SAM4SD16 || SAM4SD32 || SAM4C32)
kadonotakashi 0:8fdf9a60065b 334 uint32_t *p_ul_data =
kadonotakashi 0:8fdf9a60065b 335 (uint32_t *) ((p_efc == EFC0) ?
kadonotakashi 0:8fdf9a60065b 336 READ_BUFF_ADDR0 : READ_BUFF_ADDR1);
kadonotakashi 0:8fdf9a60065b 337 #elif (SAM3S || SAM4S || SAM3N || SAM3U || SAM4E || SAM4N || SAM4C || SAMG || \
kadonotakashi 0:8fdf9a60065b 338 SAM4CP || SAM4CM || SAMV71 || SAMV70 || SAMS70 || SAME70)
kadonotakashi 0:8fdf9a60065b 339 uint32_t *p_ul_data = (uint32_t *) READ_BUFF_ADDR;
kadonotakashi 0:8fdf9a60065b 340 #else
kadonotakashi 0:8fdf9a60065b 341 return EFC_RC_NOT_SUPPORT;
kadonotakashi 0:8fdf9a60065b 342 #endif
kadonotakashi 0:8fdf9a60065b 343
kadonotakashi 0:8fdf9a60065b 344 if (p_ul_buf == NULL) {
kadonotakashi 0:8fdf9a60065b 345 return EFC_RC_INVALID;
kadonotakashi 0:8fdf9a60065b 346 }
kadonotakashi 0:8fdf9a60065b 347
kadonotakashi 0:8fdf9a60065b 348 p_efc->EEFC_FMR |= (0x1u << 16);
kadonotakashi 0:8fdf9a60065b 349
kadonotakashi 0:8fdf9a60065b 350 /* Send the Start Read command */
kadonotakashi 0:8fdf9a60065b 351 #if (SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM || \
kadonotakashi 0:8fdf9a60065b 352 SAMV71 || SAMV70 || SAMS70 || SAME70)
kadonotakashi 0:8fdf9a60065b 353 p_efc->EEFC_FCR = EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FARG(0)
kadonotakashi 0:8fdf9a60065b 354 | EEFC_FCR_FCMD(ul_cmd_st);
kadonotakashi 0:8fdf9a60065b 355 #else
kadonotakashi 0:8fdf9a60065b 356 p_efc->EEFC_FCR = EEFC_FCR_FKEY(FWP_KEY) | EEFC_FCR_FARG(0)
kadonotakashi 0:8fdf9a60065b 357 | EEFC_FCR_FCMD(ul_cmd_st);
kadonotakashi 0:8fdf9a60065b 358 #endif
kadonotakashi 0:8fdf9a60065b 359 /* Wait for the FRDY bit in the Flash Programming Status Register
kadonotakashi 0:8fdf9a60065b 360 * (EEFC_FSR) falls.
kadonotakashi 0:8fdf9a60065b 361 */
kadonotakashi 0:8fdf9a60065b 362 do {
kadonotakashi 0:8fdf9a60065b 363 ul_status = p_efc->EEFC_FSR;
kadonotakashi 0:8fdf9a60065b 364 } while ((ul_status & EEFC_FSR_FRDY) == EEFC_FSR_FRDY);
kadonotakashi 0:8fdf9a60065b 365
kadonotakashi 0:8fdf9a60065b 366 /* The data is located in the first address of the Flash
kadonotakashi 0:8fdf9a60065b 367 * memory mapping.
kadonotakashi 0:8fdf9a60065b 368 */
kadonotakashi 0:8fdf9a60065b 369 for (ul_cnt = 0; ul_cnt < ul_size; ul_cnt++) {
kadonotakashi 0:8fdf9a60065b 370 p_ul_buf[ul_cnt] = p_ul_data[ul_cnt];
kadonotakashi 0:8fdf9a60065b 371 }
kadonotakashi 0:8fdf9a60065b 372
kadonotakashi 0:8fdf9a60065b 373 /* To stop the read mode */
kadonotakashi 0:8fdf9a60065b 374 p_efc->EEFC_FCR =
kadonotakashi 0:8fdf9a60065b 375 #if (SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM || \
kadonotakashi 0:8fdf9a60065b 376 SAMV71 || SAMV70 || SAMS70 || SAME70)
kadonotakashi 0:8fdf9a60065b 377 EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FARG(0) |
kadonotakashi 0:8fdf9a60065b 378 EEFC_FCR_FCMD(ul_cmd_sp);
kadonotakashi 0:8fdf9a60065b 379 #else
kadonotakashi 0:8fdf9a60065b 380 EEFC_FCR_FKEY(FWP_KEY) | EEFC_FCR_FARG(0) |
kadonotakashi 0:8fdf9a60065b 381 EEFC_FCR_FCMD(ul_cmd_sp);
kadonotakashi 0:8fdf9a60065b 382 #endif
kadonotakashi 0:8fdf9a60065b 383 /* Wait for the FRDY bit in the Flash Programming Status Register (EEFC_FSR)
kadonotakashi 0:8fdf9a60065b 384 * rises.
kadonotakashi 0:8fdf9a60065b 385 */
kadonotakashi 0:8fdf9a60065b 386 do {
kadonotakashi 0:8fdf9a60065b 387 ul_status = p_efc->EEFC_FSR;
kadonotakashi 0:8fdf9a60065b 388 } while ((ul_status & EEFC_FSR_FRDY) != EEFC_FSR_FRDY);
kadonotakashi 0:8fdf9a60065b 389
kadonotakashi 0:8fdf9a60065b 390 p_efc->EEFC_FMR &= ~(0x1u << 16);
kadonotakashi 0:8fdf9a60065b 391
kadonotakashi 0:8fdf9a60065b 392 return EFC_RC_OK;
kadonotakashi 0:8fdf9a60065b 393 }
kadonotakashi 0:8fdf9a60065b 394
kadonotakashi 0:8fdf9a60065b 395 /**
kadonotakashi 0:8fdf9a60065b 396 * \brief Set mode register.
kadonotakashi 0:8fdf9a60065b 397 *
kadonotakashi 0:8fdf9a60065b 398 * \param p_efc Pointer to an EFC instance.
kadonotakashi 0:8fdf9a60065b 399 * \param ul_fmr Value of mode register
kadonotakashi 0:8fdf9a60065b 400 */
kadonotakashi 0:8fdf9a60065b 401 __no_inline
kadonotakashi 0:8fdf9a60065b 402 RAMFUNC
kadonotakashi 0:8fdf9a60065b 403 void efc_write_fmr(Efc *p_efc, uint32_t ul_fmr)
kadonotakashi 0:8fdf9a60065b 404 {
kadonotakashi 0:8fdf9a60065b 405 p_efc->EEFC_FMR = ul_fmr;
kadonotakashi 0:8fdf9a60065b 406 }
kadonotakashi 0:8fdf9a60065b 407
kadonotakashi 0:8fdf9a60065b 408 /**
kadonotakashi 0:8fdf9a60065b 409 * \brief Perform command.
kadonotakashi 0:8fdf9a60065b 410 *
kadonotakashi 0:8fdf9a60065b 411 * \param p_efc Pointer to an EFC instance.
kadonotakashi 0:8fdf9a60065b 412 * \param ul_fcr Flash command.
kadonotakashi 0:8fdf9a60065b 413 *
kadonotakashi 0:8fdf9a60065b 414 * \return The current status.
kadonotakashi 0:8fdf9a60065b 415 */
kadonotakashi 0:8fdf9a60065b 416 __no_inline
kadonotakashi 0:8fdf9a60065b 417 RAMFUNC
kadonotakashi 0:8fdf9a60065b 418 uint32_t efc_perform_fcr(Efc *p_efc, uint32_t ul_fcr)
kadonotakashi 0:8fdf9a60065b 419 {
kadonotakashi 0:8fdf9a60065b 420 volatile uint32_t ul_status;
kadonotakashi 0:8fdf9a60065b 421
kadonotakashi 0:8fdf9a60065b 422 p_efc->EEFC_FCR = ul_fcr;
kadonotakashi 0:8fdf9a60065b 423 do {
kadonotakashi 0:8fdf9a60065b 424 ul_status = p_efc->EEFC_FSR;
kadonotakashi 0:8fdf9a60065b 425 } while ((ul_status & EEFC_FSR_FRDY) != EEFC_FSR_FRDY);
kadonotakashi 0:8fdf9a60065b 426
kadonotakashi 0:8fdf9a60065b 427 return (ul_status & EEFC_ERROR_FLAGS);
kadonotakashi 0:8fdf9a60065b 428 }
kadonotakashi 0:8fdf9a60065b 429
kadonotakashi 0:8fdf9a60065b 430 //@}
kadonotakashi 0:8fdf9a60065b 431
kadonotakashi 0:8fdf9a60065b 432 /// @cond 0
kadonotakashi 0:8fdf9a60065b 433 /**INDENT-OFF**/
kadonotakashi 0:8fdf9a60065b 434 #ifdef __cplusplus
kadonotakashi 0:8fdf9a60065b 435 }
kadonotakashi 0:8fdf9a60065b 436 #endif
kadonotakashi 0:8fdf9a60065b 437 /**INDENT-ON**/
kadonotakashi 0:8fdf9a60065b 438 /// @endcond