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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [CORTEX_LM3S811_IAR/] [LuminaryCode/] [flash.c] - Blame information for rev 724

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 581 jeremybenn
//*****************************************************************************
2
//
3
// flash.c - Driver for programming the on-chip flash.
4
//
5
// Copyright (c) 2005,2006 Luminary Micro, Inc.  All rights reserved.
6
//
7
// Software License Agreement
8
//
9
// Luminary Micro, Inc. (LMI) is supplying this software for use solely and
10
// exclusively on LMI's Stellaris Family of microcontroller products.
11
//
12
// The software is owned by LMI and/or its suppliers, and is protected under
13
// applicable copyright laws.  All rights are reserved.  Any use in violation
14
// of the foregoing restrictions may subject the user to criminal sanctions
15
// under applicable laws, as well as to civil liability for the breach of the
16
// terms and conditions of this license.
17
//
18
// THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
19
// OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
20
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
21
// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
22
// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
23
//
24
// This is part of revision 991 of the Stellaris Driver Library.
25
//
26
//*****************************************************************************
27
 
28
//*****************************************************************************
29
//
30
//! \addtogroup flash_api
31
//! @{
32
//
33
//*****************************************************************************
34
 
35
#include "../hw_flash.h"
36
#include "../hw_ints.h"
37
#include "../hw_memmap.h"
38
#include "../hw_sysctl.h"
39
#include "../hw_types.h"
40
#include "debug.h"
41
#include "flash.h"
42
#include "interrupt.h"
43
 
44
//*****************************************************************************
45
//
46
//! Gets the number of processor clocks per micro-second.
47
//!
48
//! This function returns the number of clocks per micro-second, as presently
49
//! known by the flash controller.
50
//!
51
//! \return Returns the number of processor clocks per micro-second.
52
//
53
//*****************************************************************************
54
#if defined(GROUP_usecget) || defined(BUILD_ALL) || defined(DOXYGEN)
55
unsigned long
56
FlashUsecGet(void)
57
{
58
    //
59
    // Return the number of clocks per micro-second.
60
    //
61
    return(HWREG(FLASH_USECRL) + 1);
62
}
63
#endif
64
 
65
//*****************************************************************************
66
//
67
//! Sets the number of processor clocks per micro-second.
68
//!
69
//! \param ulClocks is the number of processor clocks per micro-second.
70
//!
71
//! This function is used to tell the flash controller the number of processor
72
//! clocks per micro-second.  This value must be programmed correctly or the
73
//! flash most likely will not program correctly; it has no affect on reading
74
//! flash.
75
//!
76
//! \return None.
77
//
78
//*****************************************************************************
79
#if defined(GROUP_usecset) || defined(BUILD_ALL) || defined(DOXYGEN)
80
void
81
FlashUsecSet(unsigned long ulClocks)
82
{
83
    //
84
    // Set the number of clocks per micro-second.
85
    //
86
    HWREG(FLASH_USECRL) = ulClocks - 1;
87
}
88
#endif
89
 
90
//*****************************************************************************
91
//
92
//! Erases a block of flash.
93
//!
94
//! \param ulAddress is the start address of the flash block to be erased.
95
//!
96
//! This function will erase a 1 kB block of the on-chip flash.  After erasing,
97
//! the block will be filled with 0xFF bytes.  Read-only and execute-only
98
//! blocks cannot be erased.
99
//!
100
//! This function will not return until the block has been erased.
101
//!
102
//! \return Returns 0 on success, or -1 if an invalid block address was
103
//! specified or the block is write-protected.
104
//
105
//*****************************************************************************
106
#if defined(GROUP_erase) || defined(BUILD_ALL) || defined(DOXYGEN)
107
long
108
FlashErase(unsigned long ulAddress)
109
{
110
    //
111
    // Check the arguments.
112
    //
113
    ASSERT(!(ulAddress & (FLASH_ERASE_SIZE - 1)));
114
 
115
    //
116
    // Clear the flash access interrupt.
117
    //
118
    HWREG(FLASH_FCMISC) = FLASH_FCMISC_ACCESS;
119
 
120
    //
121
    // Erase the block.
122
    //
123
    HWREG(FLASH_FMA) = ulAddress;
124
    HWREG(FLASH_FMC) = FLASH_FMC_WRKEY | FLASH_FMC_ERASE;
125
 
126
    //
127
    // Wait until the word has been programmed.
128
    //
129
    while(HWREG(FLASH_FMC) & FLASH_FMC_ERASE)
130
    {
131
    }
132
 
133
    //
134
    // Return an error if an access violation occurred.
135
    //
136
    if(HWREG(FLASH_FCRIS) & FLASH_FCRIS_ACCESS)
137
    {
138
        return(-1);
139
    }
140
 
141
    //
142
    // Success.
143
    //
144
    return(0);
145
}
146
#endif
147
 
148
//*****************************************************************************
149
//
150
//! Programs flash.
151
//!
152
//! \param pulData is a pointer to the data to be programmed.
153
//! \param ulAddress is the starting address in flash to be programmed.  Must
154
//! be a multiple of four.
155
//! \param ulCount is the number of bytes to be programmed.  Must be a multiple
156
//! of four.
157
//!
158
//! This function will program a sequence of words into the on-chip flash.
159
//! Programming each location consists of the result of an AND operation
160
//! of the new data and the existing data; in other words bits that contain
161
//! 1 can remain 1 or be changed to 0, but bits that are 0 cannot be changed
162
//! to 1.  Therefore, a word can be programmed multiple times as long as these
163
//! rules are followed; if a program operation attempts to change a 0 bit to
164
//! a 1 bit, that bit will not have its value changed.
165
//!
166
//! Since the flash is programmed one word at a time, the starting address and
167
//! byte count must both be multiples of four.  It is up to the caller to
168
//! verify the programmed contents, if such verification is required.
169
//!
170
//! This function will not return until the data has been programmed.
171
//!
172
//! \return Returns 0 on success, or -1 if a programming error is encountered.
173
//
174
//*****************************************************************************
175
#if defined(GROUP_program) || defined(BUILD_ALL) || defined(DOXYGEN)
176
long
177
FlashProgram(unsigned long *pulData, unsigned long ulAddress,
178
             unsigned long ulCount)
179
{
180
    //
181
    // Check the arguments.
182
    //
183
    ASSERT(!(ulAddress & 3));
184
    ASSERT(!(ulCount & 3));
185
 
186
    //
187
    // Clear the flash access interrupt.
188
    //
189
    HWREG(FLASH_FCMISC) = FLASH_FCMISC_ACCESS;
190
 
191
    //
192
    // Loop over the words to be programmed.
193
    //
194
    while(ulCount)
195
    {
196
        //
197
        // Program the next word.
198
        //
199
        HWREG(FLASH_FMA) = ulAddress;
200
        HWREG(FLASH_FMD) = *pulData;
201
        HWREG(FLASH_FMC) = FLASH_FMC_WRKEY | FLASH_FMC_WRITE;
202
 
203
        //
204
        // Wait until the word has been programmed.
205
        //
206
        while(HWREG(FLASH_FMC) & FLASH_FMC_WRITE)
207
        {
208
        }
209
 
210
        //
211
        // Increment to the next word.
212
        //
213
        pulData++;
214
        ulAddress += 4;
215
        ulCount -= 4;
216
    }
217
 
218
    //
219
    // Return an error if an access violation occurred.
220
    //
221
    if(HWREG(FLASH_FCRIS) & FLASH_FCRIS_ACCESS)
222
    {
223
        return(-1);
224
    }
225
 
226
    //
227
    // Success.
228
    //
229
    return(0);
230
}
231
#endif
232
 
233
//*****************************************************************************
234
//
235
//! Gets the protection setting for a block of flash.
236
//!
237
//! \param ulAddress is the start address of the flash block to be queried.
238
//!
239
//! This function will get the current protection for the specified 2 kB block
240
//! of flash.  Each block can be read/write, read-only, or execute-only.
241
//! Read/write blocks can be read, executed, erased, and programmed.  Read-only
242
//! blocks can be read and executed.  Execute-only blocks can only be executed;
243
//! processor and debugger data reads are not allowed.
244
//!
245
//! \return Returns the protection setting for this block.  See
246
//! FlashProtectSet() for possible values.
247
//
248
//*****************************************************************************
249
#if defined(GROUP_protectget) || defined(BUILD_ALL) || defined(DOXYGEN)
250
tFlashProtection
251
FlashProtectGet(unsigned long ulAddress)
252
{
253
    unsigned long ulFMPRE, ulFMPPE;
254
 
255
    //
256
    // Check the argument.
257
    //
258
    ASSERT(!(ulAddress & (FLASH_PROTECT_SIZE - 1)));
259
 
260
    //
261
    // Read the flash protection register and get the bits that apply to the
262
    // specified block.
263
    //
264
    ulFMPRE = HWREG(FLASH_FMPRE);
265
    ulFMPPE = HWREG(FLASH_FMPPE);
266
    switch((((ulFMPRE >> (ulAddress / FLASH_PROTECT_SIZE)) &
267
             FLASH_FMP_BLOCK_0) << 1) |
268
           ((ulFMPPE >> (ulAddress / FLASH_PROTECT_SIZE)) & FLASH_FMP_BLOCK_0))
269
    {
270
        //
271
        // This block is marked as execute only (i.e. it can not be erased or
272
        // programmed, and the only reads allowed are via the instruction fecth
273
        // interface).
274
        //
275
        case 0:
276
        case 1:
277
        {
278
            return(FlashExecuteOnly);
279
        }
280
 
281
        //
282
        // This block is marked as read only (i.e. it can not be erased or
283
        // programmed).
284
        //
285
        case 2:
286
        {
287
            return(FlashReadOnly);
288
        }
289
 
290
        //
291
        // This block is read/write; it can be read, erased, and programmed.
292
        //
293
        case 3:
294
        default:
295
        {
296
            return(FlashReadWrite);
297
        }
298
    }
299
}
300
#endif
301
 
302
//*****************************************************************************
303
//
304
//! Sets the protection setting for a block of flash.
305
//!
306
//! \param ulAddress is the start address of the flash block to be protected.
307
//! \param eProtect is the protection to be applied to the block.  Can be one
308
//! of \b FlashReadWrite, \b FlashReadOnly, or \b FlashExecuteOnly.
309
//!
310
//! This function will set the protection for the specified 2 kB block of
311
//! flash.  Blocks which are read/write can be made read-only or execute-only.
312
//! Blocks which are read-only can be made execute-only.  Blocks which are
313
//! execute-only cannot have their protection modified.  Attempts to make the
314
//! block protection less stringent (i.e. read-only to read/write) will result
315
//! in a failure (and be prevented by the hardware).
316
//!
317
//! Changes to the flash protection are maintained only until the next reset.
318
//! This allows the application to be executed in the desired flash protection
319
//! environment to check for inappropriate flash access (via the flash
320
//! interrupt).  To make the flash protection permanent, use the
321
//! FlashProtectSave() function.
322
//!
323
//! \return Returns 0 on success, or -1 if an invalid address or an invalid
324
//! protection was specified.
325
//
326
//*****************************************************************************
327
#if defined(GROUP_protectset) || defined(BUILD_ALL) || defined(DOXYGEN)
328
long
329
FlashProtectSet(unsigned long ulAddress, tFlashProtection eProtect)
330
{
331
    unsigned long ulProtectRE, ulProtectPE;
332
 
333
    //
334
    // Check the argument.
335
    //
336
    ASSERT(!(ulAddress & (FLASH_PROTECT_SIZE - 1)));
337
    ASSERT((eProtect == FlashReadWrite) || (eProtect == FlashReadOnly) ||
338
           (eProtect == FlashExecuteOnly));
339
 
340
    //
341
    // Convert the address into a block number.
342
    //
343
    ulAddress /= FLASH_PROTECT_SIZE;
344
 
345
    //
346
    // Get the current protection.
347
    //
348
    ulProtectRE = HWREG(FLASH_FMPRE);
349
    ulProtectPE = HWREG(FLASH_FMPPE);
350
 
351
    //
352
    // Set the protection based on the requested proection.
353
    //
354
    switch(eProtect)
355
    {
356
        //
357
        // Make this block execute only.
358
        //
359
        case FlashExecuteOnly:
360
        {
361
            //
362
            // Turn off the read and program bits for this block.
363
            //
364
            ulProtectRE &= ~(FLASH_FMP_BLOCK_0 << ulAddress);
365
            ulProtectPE &= ~(FLASH_FMP_BLOCK_0 << ulAddress);
366
 
367
            //
368
            // We're done handling this protection.
369
            //
370
            break;
371
        }
372
 
373
        //
374
        // Make this block read only.
375
        //
376
        case FlashReadOnly:
377
        {
378
            //
379
            // The block can not be made read only if it is execute only.
380
            //
381
            if(((ulProtectRE >> ulAddress) & FLASH_FMP_BLOCK_0) !=
382
               FLASH_FMP_BLOCK_0)
383
            {
384
                return(-1);
385
            }
386
 
387
            //
388
            // Make this block read only.
389
            //
390
            ulProtectPE &= ~(FLASH_FMP_BLOCK_0 << ulAddress);
391
 
392
            //
393
            // We're done handling this protection.
394
            //
395
            break;
396
        }
397
 
398
        //
399
        // Make this block read/write.
400
        //
401
        case FlashReadWrite:
402
        default:
403
        {
404
            //
405
            // The block can not be made read/write if it is not already
406
            // read/write.
407
            //
408
            if((((ulProtectRE >> ulAddress) & FLASH_FMP_BLOCK_0) !=
409
                FLASH_FMP_BLOCK_0) ||
410
               (((ulProtectPE >> ulAddress) & FLASH_FMP_BLOCK_0) !=
411
                FLASH_FMP_BLOCK_0))
412
            {
413
                return(-1);
414
            }
415
 
416
            //
417
            // The block is already read/write, so there is nothing to do.
418
            //
419
            return(0);
420
        }
421
    }
422
 
423
    //
424
    // Set the new protection.
425
    //
426
    HWREG(FLASH_FMPRE) = ulProtectRE;
427
    HWREG(FLASH_FMPPE) = ulProtectPE;
428
 
429
    //
430
    // Success.
431
    //
432
    return(0);
433
}
434
#endif
435
 
436
//*****************************************************************************
437
//
438
//! Saves the flash protection settings.
439
//!
440
//! This function will make the currently programmed flash protection settings
441
//! permanent.  This is a non-reversible operation; a chip reset or power cycle
442
//! will not change the flash protection.
443
//!
444
//! This function will not return until the protection has been saved.
445
//!
446
//! \return Returns 0 on success, or -1 if a hardware error is encountered.
447
//
448
//*****************************************************************************
449
#if defined(GROUP_protectsave) || defined(BUILD_ALL) || defined(DOXYGEN)
450
long
451
FlashProtectSave(void)
452
{
453
    //
454
    // Tell the flash controller to write the flash read protection register.
455
    //
456
    HWREG(FLASH_FMA) = 0;
457
    HWREG(FLASH_FMC) = FLASH_FMC_WRKEY | FLASH_FMC_COMT;
458
 
459
    //
460
    // Wait until the write has completed.
461
    //
462
    while(HWREG(FLASH_FMC) & FLASH_FMC_COMT)
463
    {
464
    }
465
 
466
    //
467
    // Tell the flash controller to write the flash program protection
468
    // register.
469
    //
470
    HWREG(FLASH_FMA) = 1;
471
    HWREG(FLASH_FMC) = FLASH_FMC_WRKEY | FLASH_FMC_COMT;
472
 
473
    //
474
    // Wait until the write has completed.
475
    //
476
    while(HWREG(FLASH_FMC) & FLASH_FMC_COMT)
477
    {
478
    }
479
 
480
    //
481
    // Success.
482
    //
483
    return(0);
484
}
485
#endif
486
 
487
//*****************************************************************************
488
//
489
//! Registers an interrupt handler for the flash interrupt.
490
//!
491
//! \param pfnHandler is a pointer to the function to be called when the flash
492
//! interrupt occurs.
493
//!
494
//! This sets the handler to be called when the flash interrupt occurs.  The
495
//! flash controller can generate an interrupt when an invalid flash access
496
//! occurs, such as trying to program or erase a read-only block, or trying to
497
//! read from an execute-only block.  It can also generate an interrupt when a
498
//! program or erase operation has completed.  The interrupt will be
499
//! automatically enabled when the handler is registered.
500
//!
501
//! \sa IntRegister() for important information about registering interrupt
502
//! handlers.
503
//!
504
//! \return None.
505
//
506
//*****************************************************************************
507
#if defined(GROUP_intregister) || defined(BUILD_ALL) || defined(DOXYGEN)
508
void
509
FlashIntRegister(void (*pfnHandler)(void))
510
{
511
    //
512
    // Register the interrupt handler, returning an error if an error occurs.
513
    //
514
    IntRegister(INT_FLASH, pfnHandler);
515
 
516
    //
517
    // Enable the flash interrupt.
518
    //
519
    IntEnable(INT_FLASH);
520
}
521
#endif
522
 
523
//*****************************************************************************
524
//
525
//! Unregisters the interrupt handler for the flash interrupt.
526
//!
527
//! This function will clear the handler to be called when the flash interrupt
528
//! occurs.  This will also mask off the interrupt in the interrupt controller
529
//! so that the interrupt handler is no longer called.
530
//!
531
//! \sa IntRegister() for important information about registering interrupt
532
//! handlers.
533
//!
534
//! \return None.
535
//
536
//*****************************************************************************
537
#if defined(GROUP_intunregister) || defined(BUILD_ALL) || defined(DOXYGEN)
538
void
539
FlashIntUnregister(void)
540
{
541
    //
542
    // Disable the interrupt.
543
    //
544
    IntDisable(INT_FLASH);
545
 
546
    //
547
    // Unregister the interrupt handler.
548
    //
549
    IntUnregister(INT_FLASH);
550
}
551
#endif
552
 
553
//*****************************************************************************
554
//
555
//! Enables individual flash controller interrupt sources.
556
//!
557
//! \param ulIntFlags is a bit mask of the interrupt sources to be enabled.
558
//! Can be any of the \b FLASH_FCIM_PROGRAM or \b FLASH_FCIM_ACCESS values.
559
//!
560
//! Enables the indicated flash controller interrupt sources.  Only the sources
561
//! that are enabled can be reflected to the processor interrupt; disabled
562
//! sources have no effect on the processor.
563
//!
564
//! \return None.
565
//
566
//*****************************************************************************
567
#if defined(GROUP_intenable) || defined(BUILD_ALL) || defined(DOXYGEN)
568
void
569
FlashIntEnable(unsigned long ulIntFlags)
570
{
571
    //
572
    // Enable the specified interrupts.
573
    //
574
    HWREG(FLASH_FCIM) |= ulIntFlags;
575
}
576
#endif
577
 
578
//*****************************************************************************
579
//
580
//! Disables individual flash controller interrupt sources.
581
//!
582
//! \param ulIntFlags is a bit mask of the interrupt sources to be disabled.
583
//! Can be any of the \b FLASH_FCIM_PROGRAM or \b FLASH_FCIM_ACCESS values.
584
//!
585
//! Disables the indicated flash controller interrupt sources.  Only the
586
//! sources that are enabled can be reflected to the processor interrupt;
587
//! disabled sources have no effect on the processor.
588
//!
589
//! \return None.
590
//
591
//*****************************************************************************
592
#if defined(GROUP_intdisable) || defined(BUILD_ALL) || defined(DOXYGEN)
593
void
594
FlashIntDisable(unsigned long ulIntFlags)
595
{
596
    //
597
    // Disable the specified interrupts.
598
    //
599
    HWREG(FLASH_FCIM) &= ~(ulIntFlags);
600
}
601
#endif
602
 
603
//*****************************************************************************
604
//
605
//! Gets the current interrupt status.
606
//!
607
//! \param bMasked is false if the raw interrupt status is required and true if
608
//! the masked interrupt status is required.
609
//!
610
//! This returns the interrupt status for the flash controller.  Either the raw
611
//! interrupt status or the status of interrupts that are allowed to reflect to
612
//! the processor can be returned.
613
//!
614
//! \return The current interrupt status, enumerated as a bit field of
615
//! \b FLASH_FCMISC_PROGRAM and \b FLASH_FCMISC_ACCESS.
616
//
617
//*****************************************************************************
618
#if defined(GROUP_intgetstatus) || defined(BUILD_ALL) || defined(DOXYGEN)
619
unsigned long
620
FlashIntGetStatus(tBoolean bMasked)
621
{
622
    //
623
    // Return either the interrupt status or the raw interrupt status as
624
    // requested.
625
    //
626
    if(bMasked)
627
    {
628
        return(HWREG(FLASH_FCMISC));
629
    }
630
    else
631
    {
632
        return(HWREG(FLASH_FCRIS));
633
    }
634
}
635
#endif
636
 
637
//*****************************************************************************
638
//
639
//! Clears flash controller interrupt sources.
640
//!
641
//! \param ulIntFlags is the bit mask of the interrupt sources to be cleared.
642
//! Can be any of the \b FLASH_FCMISC_PROGRAM or \b FLASH_FCMISC_ACCESS
643
//! values.
644
//!
645
//! The specified flash controller interrupt sources are cleared, so that they
646
//! no longer assert.  This must be done in the interrupt handler to keep it
647
//! from being called again immediately upon exit.
648
//!
649
//! \return None.
650
//
651
//*****************************************************************************
652
#if defined(GROUP_intclear) || defined(BUILD_ALL) || defined(DOXYGEN)
653
void
654
FlashIntClear(unsigned long ulIntFlags)
655
{
656
    //
657
    // Clear the flash interrupt.
658
    //
659
    HWREG(FLASH_FCMISC) = ulIntFlags;
660
}
661
#endif
662
 
663
//*****************************************************************************
664
//
665
// Close the Doxygen group.
666
//! @}
667
//
668
//*****************************************************************************

powered by: WebSVN 2.1.0

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