5
5
6
6
#include <sam.h>
7
7
8
+ #include "platform/samx7x/atomic.h"
8
9
#include "platform/samx7x/eefc.h"
9
10
10
- void eefc_config_waitstates (u32 frequency )
11
+ #define ROM_BASE_ADDR 0x00400000ul
12
+
13
+ #define EEFC_ERROR_FLAGS \
14
+ (EEFC_FSR_FLOCKE_Msk | EEFC_FSR_FCMDE_Msk | EEFC_FSR_FLERR_Msk | EEFC_FSR_UECCELSB_Msk | EEFC_FSR_MECCELSB_Msk | \
15
+ EEFC_FSR_UECCEMSB_Msk | EEFC_FSR_MECCEMSB_Msk)
16
+
17
+ static struct flash_info_t flash_info ;
18
+
19
+ /*
20
+ * Local function declaration.
21
+ * Because they are RAM functions, they need 'extern' declaration.
22
+ */
23
+ extern void eefc_write_fmr (u32 fmr );
24
+ extern u32 eefc_perform_fcr (u32 fcr );
25
+
26
+ static u32 eefc_get_result ();
27
+ static u32 eefc_get_status ();
28
+ static void eefc_perform_command (u32 command , u32 argument );
29
+
30
+ void eefc_init ()
31
+ {
32
+ /* enable code loop optimization and sequential code optimization */
33
+ eefc_write_fmr (EFC -> EEFC_FMR & ~(EEFC_FMR_FWS_Msk | EEFC_FMR_SCOD_Msk ) | EEFC_FMR_CLOE_Msk | EEFC_FMR_FWS (6 ));
34
+
35
+ eefc_perform_command (EEFC_FCR_FCMD_GETD , 0 );
36
+ while (!(eefc_get_status () & EEFC_FSR_FRDY_Msk )) continue ;
37
+ eefc_get_result (); /* dummy read: id */
38
+ flash_info .size = eefc_get_result ();
39
+ flash_info .page_size = eefc_get_result ();
40
+ flash_info .base_addr = ROM_BASE_ADDR ;
41
+ }
42
+
43
+ void eefc_set_waitstates (u32 frequency )
11
44
{
12
45
if (frequency <= 23000000UL )
13
- EFC -> EEFC_FMR = (EFC -> EEFC_FMR & ~EEFC_FMR_FWS_Msk ) | ( 0 << EEFC_FMR_FWS_Pos );
46
+ EFC -> EEFC_FMR = (EFC -> EEFC_FMR & ~EEFC_FMR_FWS_Msk ) | EEFC_FMR_FWS ( 0 );
14
47
else if (frequency <= 46000000UL )
15
- EFC -> EEFC_FMR = (EFC -> EEFC_FMR & ~EEFC_FMR_FWS_Msk ) | ( 1 << EEFC_FMR_FWS_Pos );
48
+ EFC -> EEFC_FMR = (EFC -> EEFC_FMR & ~EEFC_FMR_FWS_Msk ) | EEFC_FMR_FWS ( 1 );
16
49
else if (frequency <= 69000000UL )
17
- EFC -> EEFC_FMR = (EFC -> EEFC_FMR & ~EEFC_FMR_FWS_Msk ) | ( 2 << EEFC_FMR_FWS_Pos );
50
+ EFC -> EEFC_FMR = (EFC -> EEFC_FMR & ~EEFC_FMR_FWS_Msk ) | EEFC_FMR_FWS ( 2 );
18
51
else if (frequency <= 92000000UL )
19
- EFC -> EEFC_FMR = (EFC -> EEFC_FMR & ~EEFC_FMR_FWS_Msk ) | ( 3 << EEFC_FMR_FWS_Pos );
52
+ EFC -> EEFC_FMR = (EFC -> EEFC_FMR & ~EEFC_FMR_FWS_Msk ) | EEFC_FMR_FWS ( 3 );
20
53
else if (frequency <= 115000000UL )
21
- EFC -> EEFC_FMR = (EFC -> EEFC_FMR & ~EEFC_FMR_FWS_Msk ) | ( 4 << EEFC_FMR_FWS_Pos );
54
+ EFC -> EEFC_FMR = (EFC -> EEFC_FMR & ~EEFC_FMR_FWS_Msk ) | EEFC_FMR_FWS ( 4 );
22
55
else if (frequency <= 138000000UL )
23
- EFC -> EEFC_FMR = (EFC -> EEFC_FMR & ~EEFC_FMR_FWS_Msk ) | ( 5 << EEFC_FMR_FWS_Pos );
56
+ EFC -> EEFC_FMR = (EFC -> EEFC_FMR & ~EEFC_FMR_FWS_Msk ) | EEFC_FMR_FWS ( 5 );
24
57
else
25
- EFC -> EEFC_FMR = (EFC -> EEFC_FMR & ~EEFC_FMR_FWS_Msk ) | ( 6 << EEFC_FMR_FWS_Pos );
58
+ EFC -> EEFC_FMR = (EFC -> EEFC_FMR & ~EEFC_FMR_FWS_Msk ) | EEFC_FMR_FWS ( 6 );
26
59
}
27
60
28
61
void eefc_tcm_disable ()
@@ -33,8 +66,110 @@ void eefc_tcm_disable()
33
66
34
67
__DSB ();
35
68
__ISB ();
36
- SCB -> ITCMCR &= ~(uint32_t ) (1UL );
37
- SCB -> DTCMCR &= ~(uint32_t ) SCB_DTCMCR_EN_Msk ;
69
+ SCB -> ITCMCR &= ~(u32 ) (1UL );
70
+ SCB -> DTCMCR &= ~(u32 ) SCB_DTCMCR_EN_Msk ;
38
71
__DSB ();
39
72
__ISB ();
40
73
}
74
+
75
+ const struct flash_info_t * eefc_get_info ()
76
+ {
77
+ return (const struct flash_info_t * ) & flash_info ;
78
+ }
79
+
80
+ s32 eefc_addr_to_page (u32 addr )
81
+ {
82
+ if (addr < flash_info .base_addr )
83
+ return -1 ;
84
+
85
+ /* align to pages */
86
+ addr -= (flash_info .base_addr );
87
+ addr -= (addr % flash_info .page_size );
88
+
89
+ return (addr / flash_info .page_size );
90
+ }
91
+
92
+ u32 eefc_page_to_addr (u32 page )
93
+ {
94
+ return ((page * flash_info .page_size ) + flash_info .base_addr );
95
+ }
96
+
97
+ u32 eefc_erase_16 (u32 addr )
98
+ {
99
+ u32 page = eefc_addr_to_page (addr );
100
+
101
+ /* give erase and write page command */
102
+ eefc_perform_command (EEFC_FCR_FCMD_EPA , (page & ~0xF ) | 2 ); /* 16 pages (minimum for large sectors) */
103
+ while (!(eefc_get_status () & EEFC_FSR_FRDY_Msk )) continue ;
104
+ }
105
+
106
+ void eefc_read (void * buffer , u32 addr , u32 size )
107
+ {
108
+ u8 * src = (u8 * ) addr ;
109
+ u8 * dst = (u8 * ) buffer ;
110
+ while (size -- ) {
111
+ * dst ++ = * src ++ ;
112
+ }
113
+ }
114
+
115
+ void eefc_write (u32 addr , void * buffer , u32 size )
116
+ {
117
+ /* require 128 bit alignment, and single page writes */
118
+ if ((addr % 16 ) || (size % 16 ) || ((size + (addr % 16 )) > flash_info .page_size )) {
119
+ return ;
120
+ }
121
+
122
+ size /= 4 ;
123
+ u32 * dst = (u32 * ) addr ;
124
+ u32 * src = (u32 * ) buffer ;
125
+ while (size -- ) {
126
+ * dst ++ = * src ++ ;
127
+ }
128
+
129
+ u32 page = eefc_addr_to_page (addr );
130
+
131
+ /* give erase and write page command */
132
+ eefc_perform_command (EEFC_FCR_FCMD_WP , page );
133
+ while (!(eefc_get_status () & EEFC_FSR_FRDY_Msk )) continue ;
134
+ }
135
+
136
+ static u32 eefc_get_status ()
137
+ {
138
+ return EFC -> EEFC_FSR ;
139
+ }
140
+
141
+ static u32 eefc_get_result ()
142
+ {
143
+ return EFC -> EEFC_FRR ;
144
+ }
145
+
146
+ static void eefc_perform_command (u32 command , u32 argument )
147
+ {
148
+ /* Unique ID commands are not supported. */
149
+ if (command == EEFC_FCR_FCMD_STUI || command == EEFC_FCR_FCMD_SPUI ) {
150
+ return ;
151
+ }
152
+
153
+ ATOMIC_BLOCK (ATOMIC_RESTORESTATE )
154
+ {
155
+ /* Use RAM Function. */
156
+ eefc_perform_fcr (EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FARG (argument ) | EEFC_FCR_FCMD (command ));
157
+ }
158
+ }
159
+
160
+ __attribute__((noinline , section (".ramfunc" ))) void eefc_write_fmr (u32 fmr )
161
+ {
162
+ EFC -> EEFC_FMR = fmr ;
163
+ }
164
+
165
+ __attribute__((noinline , section (".ramfunc" ))) u32 eefc_perform_fcr (u32 fcr )
166
+ {
167
+ volatile u32 status ;
168
+
169
+ EFC -> EEFC_FCR = fcr ;
170
+ do {
171
+ status = EFC -> EEFC_FSR ;
172
+ } while (!(status & EEFC_FSR_FRDY_Msk ));
173
+
174
+ return (status & EEFC_ERROR_FLAGS );
175
+ }
0 commit comments