OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [CORTEX_AT91SAM3U256_IAR/] [AT91Lib/] [peripherals/] [eefc/] [eefc.c] - Blame information for rev 580

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 580 jeremybenn
/* ----------------------------------------------------------------------------
2
 *         ATMEL Microcontroller Software Support
3
 * ----------------------------------------------------------------------------
4
 * Copyright (c) 2009, Atmel Corporation
5
 *
6
 * All rights reserved.
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions are met:
10
 *
11
 * - Redistributions of source code must retain the above copyright notice,
12
 * this list of conditions and the disclaimer below.
13
 *
14
 * Atmel's name may not be used to endorse or promote products derived from
15
 * this software without specific prior written permission.
16
 *
17
 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
18
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
20
 * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
23
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
 * ----------------------------------------------------------------------------
28
 */
29
 
30
//------------------------------------------------------------------------------
31
//         Headers
32
//------------------------------------------------------------------------------
33
 
34
#include <board.h>
35
#include "eefc.h"
36
 
37
#if !defined (CHIP_FLASH_EEFC)
38
#error eefc not supported
39
#endif
40
 
41
#include <utility/assert.h>
42
#include <utility/trace.h>
43
 
44
//------------------------------------------------------------------------------
45
//         Global functions
46
//------------------------------------------------------------------------------
47
 
48
//------------------------------------------------------------------------------
49
/// Enables the flash ready interrupt source on the EEFC peripheral.
50
/// \param pEfc  Pointer to an AT91S_EFC structure.
51
//------------------------------------------------------------------------------
52
void EFC_EnableFrdyIt(AT91S_EFC *pEfc)
53
{
54
    pEfc->EFC_FMR |= AT91C_EFC_FRDY;
55
}
56
 
57
//------------------------------------------------------------------------------
58
/// Disables the flash ready interrupt source on the EEFC peripheral.
59
/// \param pEfc  Pointer to an AT91S_EFC structure.
60
//------------------------------------------------------------------------------
61
void EFC_DisableFrdyIt(AT91S_EFC *pEfc)
62
{
63
    pEfc->EFC_FMR &= ~AT91C_EFC_FRDY;
64
}
65
 
66
//------------------------------------------------------------------------------
67
/// Translates the given address page and offset values. The resulting
68
/// values are stored in the provided variables if they are not null.
69
/// \param ppEfc  Pointer to target EFC peripheral.
70
/// \param address  Address to translate.
71
/// \param pPage  First page accessed.
72
/// \param pOffset  Byte offset in first page.
73
//------------------------------------------------------------------------------
74
void EFC_TranslateAddress(
75
    AT91S_EFC **ppEfc,
76
    unsigned int address,
77
    unsigned short *pPage,
78
    unsigned short *pOffset)
79
{
80
    AT91S_EFC *pEfc;
81
    unsigned short page;
82
    unsigned short offset;
83
 
84
#if defined(AT91C_BASE_EFC1)
85
    SANITY_CHECK(address >= AT91C_IFLASH);
86
    if (address >= AT91C_IFLASH1) {
87
        SANITY_CHECK(address <= (AT91C_IFLASH1 + AT91C_IFLASH1_SIZE));
88
    }
89
    else {
90
        SANITY_CHECK(address <= (AT91C_IFLASH + AT91C_IFLASH_SIZE));
91
    }
92
#else
93
    SANITY_CHECK(address >= AT91C_IFLASH);
94
    SANITY_CHECK(address <= (AT91C_IFLASH + AT91C_IFLASH_SIZE));
95
#endif
96
 
97
    pEfc = AT91C_BASE_EFC;
98
    page = (address - AT91C_IFLASH) / AT91C_IFLASH_PAGE_SIZE;
99
    offset = (address - AT91C_IFLASH) % AT91C_IFLASH_PAGE_SIZE;
100
 
101
#if defined(AT91C_BASE_EFC1)
102
    if (address >= AT91C_IFLASH1) {
103
        pEfc = AT91C_BASE_EFC1;
104
        page = (address - AT91C_IFLASH1) / AT91C_IFLASH1_PAGE_SIZE;
105
        offset = (address - AT91C_IFLASH1) % AT91C_IFLASH1_PAGE_SIZE;
106
    }
107
#endif
108
 
109
    TRACE_DEBUG("Translated 0x%08X to page=%d and offset=%d\n\r",
110
              address, page, offset);
111
 
112
    // Store values
113
    if (ppEfc) {
114
        *ppEfc = pEfc;
115
    }
116
    if (pPage) {
117
 
118
        *pPage = page;
119
    }
120
    if (pOffset) {
121
 
122
        *pOffset = offset;
123
    }
124
}
125
 
126
//------------------------------------------------------------------------------
127
/// Computes the address of a flash access given the page and offset.
128
/// \param pEfc  Pointer to an AT91S_EFC structure.
129
/// \param page  Page number.
130
/// \param offset  Byte offset inside page.
131
/// \param pAddress  Computed address (optional).
132
//------------------------------------------------------------------------------
133
void EFC_ComputeAddress(
134
    AT91S_EFC *pEfc,
135
    unsigned short page,
136
    unsigned short offset,
137
    unsigned int *pAddress)
138
{
139
    unsigned int address;
140
    SANITY_CHECK(pEfc);
141
    SANITY_CHECK(page <= AT91C_IFLASH_NB_OF_PAGES);
142
    SANITY_CHECK(offset < AT91C_IFLASH_PAGE_SIZE);
143
 
144
    // Compute address
145
    address = AT91C_IFLASH + page * AT91C_IFLASH_PAGE_SIZE + offset;
146
#if defined(AT91C_BASE_EFC1)
147
    if (pEfc == AT91C_BASE_EFC1) {
148
        address = AT91C_IFLASH1 + page * AT91C_IFLASH1_PAGE_SIZE + offset;
149
    }
150
#endif    
151
 
152
    // Store result
153
    if (pAddress) {
154
 
155
        *pAddress = address;
156
    }
157
}
158
 
159
//------------------------------------------------------------------------------
160
/// Starts the executing the given command on the EEFC. This function returns
161
/// as soon as the command is started. It does NOT set the FMCN field automatically.
162
/// \param pEfc  Pointer to an AT91S_EFC structure.
163
/// \param command  Command to execute.
164
/// \param argument  Command argument (should be 0 if not used).
165
//------------------------------------------------------------------------------
166
#if defined(flash) || defined (USE_FLASH)
167
   #ifdef __ICCARM__
168
__ramfunc
169
   #else
170
__attribute__ ((section (".ramfunc")))
171
   #endif
172
#endif
173
void EFC_StartCommand(AT91S_EFC *pEfc, unsigned char command, unsigned short argument)
174
{
175
    // Check command & argument
176
    switch (command) {
177
 
178
        case AT91C_EFC_FCMD_WP:
179
        case AT91C_EFC_FCMD_WPL:
180
        case AT91C_EFC_FCMD_EWP:
181
        case AT91C_EFC_FCMD_EWPL:
182
        case AT91C_EFC_FCMD_EPL:
183
        case AT91C_EFC_FCMD_EPA:
184
        case AT91C_EFC_FCMD_SLB:
185
        case AT91C_EFC_FCMD_CLB:
186
            ASSERT(argument < AT91C_IFLASH_NB_OF_PAGES,
187
                   "-F- Embedded flash has only %d pages\n\r",
188
                   AT91C_IFLASH_NB_OF_PAGES);
189
            break;
190
 
191
        case AT91C_EFC_FCMD_SFB:
192
        case AT91C_EFC_FCMD_CFB:
193
            ASSERT(argument < CHIP_EFC_NUM_GPNVMS, "-F- Embedded flash has only %d GPNVMs\n\r", CHIP_EFC_NUM_GPNVMS);
194
            break;
195
 
196
        case AT91C_EFC_FCMD_GETD:
197
        case AT91C_EFC_FCMD_EA:
198
        case AT91C_EFC_FCMD_GLB:
199
        case AT91C_EFC_FCMD_GFB:
200
#ifdef AT91C_EFC_FCMD_STUI
201
        case AT91C_EFC_FCMD_STUI:
202
#endif
203
            ASSERT(argument == 0, "-F- Argument is meaningless for the given command.\n\r");
204
            break;
205
 
206
        default: ASSERT(0, "-F- Unknown command %d\n\r", command);
207
    }
208
 
209
    // Start commandEmbedded flash 
210
    ASSERT((pEfc->EFC_FSR & AT91C_EFC_FRDY) == AT91C_EFC_FRDY, "-F- EEFC is not ready\n\r");
211
    pEfc->EFC_FCR = (0x5A << 24) | (argument << 8) | command;
212
}
213
 
214
//------------------------------------------------------------------------------
215
/// Performs the given command and wait until its completion (or an error).
216
/// Returns 0 if successful; otherwise returns an error code.
217
/// \param pEfc  Pointer to an AT91S_EFC structure.
218
/// \param command  Command to perform.
219
/// \param argument  Optional command argument.
220
//------------------------------------------------------------------------------
221
#if defined(flash) || defined (USE_FLASH)
222
   #ifdef __ICCARM__
223
__ramfunc
224
   #else
225
__attribute__ ((section (".ramfunc")))
226
   #endif
227
#endif
228
unsigned char EFC_PerformCommand(AT91S_EFC *pEfc, unsigned char command, unsigned short argument)
229
{
230
    unsigned int status;
231
 
232
#ifdef CHIP_FLASH_IAP_ADDRESS
233
    // Pointer on IAP function in ROM
234
    static void (*IAP_PerformCommand)(unsigned int);
235
    IAP_PerformCommand = (void (*)(unsigned int)) *((unsigned int *) CHIP_FLASH_IAP_ADDRESS);
236
 
237
    // Check if IAP function is implemented (opcode in SWI != 'b' or 'ldr') */
238
    if ((((((unsigned long) IAP_PerformCommand >> 24) & 0xFF) != 0xEA) &&
239
        (((unsigned long) IAP_PerformCommand >> 24) & 0xFF) != 0xE5)) {
240
 
241
        IAP_PerformCommand((0x5A << 24) | (argument << 8) | command);
242
        return (pEfc->EFC_FSR & (AT91C_EFC_LOCKE | AT91C_EFC_FCMDE));
243
    }
244
#endif
245
 
246
    pEfc->EFC_FCR = (0x5A << 24) | (argument << 8) | command;
247
    do {
248
 
249
        status = pEfc->EFC_FSR;
250
    }
251
    while ((status & AT91C_EFC_FRDY) != AT91C_EFC_FRDY);
252
 
253
    return (status & (AT91C_EFC_LOCKE | AT91C_EFC_FCMDE));
254
}
255
 
256
//------------------------------------------------------------------------------
257
/// Returns the current status of the EEFC. Keep in mind that this function clears
258
/// the value of some status bits (LOCKE, PROGE).
259
/// \param pEfc  Pointer to an AT91S_EFC structure.
260
//------------------------------------------------------------------------------
261
unsigned int EFC_GetStatus(AT91S_EFC *pEfc)
262
{
263
    return pEfc->EFC_FSR;
264
}
265
 
266
//------------------------------------------------------------------------------
267
/// Returns the result of the last executed command.
268
/// \param pEfc  Pointer to an AT91S_EFC structure.
269
//------------------------------------------------------------------------------
270
unsigned int EFC_GetResult(AT91S_EFC *pEfc) {
271
 
272
    return pEfc->EFC_FRR;
273
}
274
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.