-
Notifications
You must be signed in to change notification settings - Fork 55
Expand file tree
/
Copy pathflash_func.c
More file actions
166 lines (139 loc) · 5.91 KB
/
flash_func.c
File metadata and controls
166 lines (139 loc) · 5.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
//=============================================================================
// Copyright (C) 2018, Active-Semi International
//
// THIS SOFTWARE IS SUBJECT TO A SOURCE CODE LICENSE AGREEMENT WHICH PROVIDES,
// AMONG OTHER THINGS: (i) THAT IT CAN BE USED ONLY TO ADAPT THE LICENSEE'S
// APPLICATION TO PAC PROCESSORS SUPPLIED BY ACTIVE-SEMI INTERNATIONAL;
// (ii) THAT IT IS PROVIDED "AS IS" WITHOUT WARRANTY; (iii) THAT
// ACTIVE-SEMICONDUCTOR IS NOT LIABLE FOR ANY INDIRECT DAMAGES OR FOR DIRECT
// DAMAGES EXCEEDING US$1,500; AND (iv) THAT IT CAN BE DISCLOSED TO AND USED
// ONLY BY CERTAIN AUTHORIZED PERSONS.
//
//=============================================================================
#include "flash_func.h"
//==============================================================================
///
/// @brief Erase the specified flash page
///
/// @param page_num: the Flash page to erase
///
/// @retval None
///
//==============================================================================
#if defined(__GNUC__)
__attribute__((optimize("-O0")))
#endif
PAC5XXX_RAMFUNC void flash_erase_page(uint32_t page_num)
{
// Enable Write Access to FLash Controller
PAC55XX_MEMCTL->FLASHLOCK = FLASH_LOCK_ALLOW_WRITE_ERASE_FLASH;
// Set Page to Be Written
PAC55XX_MEMCTL->FLASHPAGE.PAGE = page_num;
// Erase Page
PAC55XX_MEMCTL->FLASHERASE = FLASH_START_PAGE_ERASE;
// Wait for erase to complete
while (PAC55XX_MEMCTL->MEMSTATUS.EBUSY) { }
// Disable Write Access to FLash Controller
PAC55XX_MEMCTL->FLASHLOCK = 0;
}
//==============================================================================
///
/// @brief Perform Flash erase of type specified by key
///
/// @param key Flash erase Key that determines type of Flash erase
///
/// @retval None
///
//==============================================================================
#if defined(__GNUC__)
__attribute__((optimize("-O0")))
#endif
PAC5XXX_RAMFUNC void flash_erase_key(uint32_t key)
{
// Enable Write Access to FLash Controller
PAC55XX_MEMCTL->FLASHLOCK = FLASH_LOCK_ALLOW_WRITE_ERASE_FLASH;
// Start Flash erase of type specified by key
PAC55XX_MEMCTL->FLASHERASE = key;
// Wait for erase to complete
while (PAC55XX_MEMCTL->MEMSTATUS.EBUSY) { }
// Disable Write Access to FLash Controller
PAC55XX_MEMCTL->FLASHLOCK = 0;
}
//==============================================================================
/// @brief Write Flash with a byte data array of any size on any boundary
///
/// @param p_dest pointer to destination FLASH to write, can be any byte address
/// @param p_src pointer to source buffer to write, can be any byte address
/// @param size_bytes size in bytes of the FLASH to write
///
/// @retval None
///
//==============================================================================
#if defined(__GNUC__)
__attribute__((optimize("-O0")))
#endif
PAC5XXX_RAMFUNC void flash_write(uint8_t *p_dest, uint8_t *p_src, uint32_t size_bytes)
{
// The memory controller requires all flash writes to start on a 16-byte boundary and consist of 16 bytes in size
// If the desired amount to be written is less than 16 bytes, this code writes the other bytes as 0xFF to preserve the contents.
// The Memory Controller will automatically hold off the write of the next 16 bytes until the previous write is complete.
// Note that reads or fetches from Flash should not take place until WBUSY=0 and an additional delay of 10 uSec has been added
union {
uint8_t b[16];
uint32_t w[4];
}buff;
uint8_t i;
uint32_t src_index;
uint8_t buff_index;
uint32_t *p_flash_write;
// Clear WRITEWORDCNT in case it's not 0; must set FLASHLOCK to allow write to MEMCTL
PAC55XX_MEMCTL->FLASHLOCK = FLASH_LOCK_ALLOW_WRITE_MEMCTL;
PAC55XX_MEMCTL->MEMCTL.WRITEWORDCNT = 0;
// Set FLASHLOCK to allow Writes to Flash
PAC55XX_MEMCTL->FLASHLOCK = FLASH_LOCK_ALLOW_WRITE_ERASE_FLASH;
// Set pointer for Flash writes to 16 byte boundary; All flash writes must start on a 16-byte boundary and consist of 16 bytes in size
p_flash_write = (uint32_t *)((uint32_t)p_dest & ~0xF);
// buff_index points to the first byte to contain valid data
buff_index = (uint32_t)p_dest & 0xF;
// Fill 16 byte temp buffer with FFs up to buff_index (must write FFs to bytes that shouldn't change)
for(i=0; i < buff_index; i++)
{
buff.b[i] = 0xFF;
}
src_index = 0;
// Fill the temp buffer and write when it's full
while(size_bytes--)
{
// Copy enough bytes from source buffer into temp buffer to reach 16 bytes
buff.b[buff_index++] = p_src[src_index++];
// If we have 16 bytes in temp buff, then write the 16 bytes of data
if(buff_index == 16)
{
// Write 4 words (16 bytes) to Flash
for(i=0; i < 4; i++)
{
*p_flash_write++ = buff.w[i];
}
buff_index = 0; // Reset buff_index for next time through
}
}
// If index is non zero then we need to fill remaining buffer with FFs and write last bytes
if(buff_index)
{
// Fill remainder of buffer with FFs
for(i=buff_index; i < 16; i++)
{
buff.b[i] = 0xFF;
}
// Write final 4 32-bit words (16 bytes) to Flash
for(i=0; i < 4; i++)
{
*p_flash_write++ = buff.w[i];
}
}
// Make sure were not still busy writing and add delay before allowing read/fetch access to flash
while(PAC55XX_MEMCTL->MEMSTATUS.WBUSY) { } // wait for Flash Write WBUSY bit to be 0
pac_delay_asm_ramfunc(320); // delay 20uS after WBUSY=0
// Return FLASHLOCK to locked state
PAC55XX_MEMCTL->FLASHLOCK =0;
}