@@ -112,42 +112,64 @@ int32_t flash_program_page(flash_t *obj, uint32_t address,
112
112
const uint8_t * data , uint32_t size )
113
113
{
114
114
unsigned long n ;
115
- // always malloc outside critical section
116
- uint8_t * alignedData = malloc (size );
115
+ const uint32_t copySize = 1024 ; // should be 256|512|1024|4096
116
+ uint8_t * alignedData , * source ;
117
+
118
+ alignedData = 0 ;
119
+ source = (uint8_t * )data ;
120
+
121
+ // check word boundary
122
+ if (((uint32_t )data % 4 ) != 0 ) {
123
+ // always malloc outside critical section
124
+ alignedData = malloc (copySize );
125
+ if (alignedData == 0 ) {
126
+ return (1 );
127
+ }
128
+ }
117
129
118
130
n = GetSecNum (address ); // Get Sector Number
119
131
120
132
core_util_critical_section_enter ();
121
- IAP .cmd = 50 ;// Prepare Sector for Write
122
- IAP .par [0 ] = n ;// Start Sector
123
- IAP .par [1 ] = n ;// End Sector
124
- IAP_Call (& IAP .cmd , & IAP .stat );// Call IAP Command
125
- if (IAP .stat ) {
126
- return (1 ); // Command Failed
127
- }
128
133
129
- IAP .cmd = 51 ; // Copy RAM to Flash
130
- IAP .par [0 ] = address ;// Destination Flash Address
131
-
132
- if ((unsigned long )data %4 == 0 ) { // Word boundary
133
- IAP .par [1 ] = (unsigned long )data ;// Source RAM Address
134
- } else {
135
- memcpy (alignedData ,data ,size );
136
- IAP .par [1 ] = (unsigned long )alignedData ; // Source RAM Address
134
+ while (size ) {
135
+ if (((uint32_t )data % 4 ) != 0 ) {
136
+ memcpy (alignedData , source , copySize );
137
+ source = alignedData ;
138
+ }
139
+
140
+ /*
141
+ Prepare_Sector_for_Write command must be exected before
142
+ Copy_RAM_to_Flash command.
143
+ */
144
+ IAP .cmd = 50 ; // Prepare Sector for Write
145
+ IAP .par [0 ] = n ; // Start Sector
146
+ IAP .par [1 ] = n ; // End Sector
147
+ IAP_Call (& IAP .cmd , & IAP .stat ); // Call IAP Command
148
+ if (IAP .stat ) {
149
+ return (1 ); // Command Failed
150
+ }
151
+
152
+ IAP .cmd = 51 ; // Copy RAM to Flash
153
+ IAP .par [0 ] = address ; // Destination Flash Address
154
+ IAP .par [1 ] = (unsigned long )source ; // Source RAM Address
155
+ IAP .par [2 ] = copySize ; // number of bytes to be written
156
+ IAP .par [3 ] = CCLK ; // CCLK in kHz
157
+ IAP_Call (& IAP .cmd , & IAP .stat ); // Call IAP Command
158
+ if (IAP .stat ) {
159
+ return (1 ); // Command Failed
160
+ }
161
+
162
+ source += copySize ;
163
+ size -= copySize ;
164
+ address += copySize ;
137
165
}
138
166
139
- IAP .par [2 ] = 1024 ; // Fixed Page Size
140
- IAP .par [3 ] = CCLK ;// CCLK in kHz
141
- IAP_Call (& IAP .cmd , & IAP .stat );// Call IAP Command
142
167
core_util_critical_section_exit ();
143
168
144
- if (alignedData != 0 ) { // We allocated our own memory
169
+ if (alignedData != 0 ) { // We allocated our own memory
145
170
free (alignedData );
146
171
}
147
172
148
- if (IAP .stat ) {
149
- return (1 ); // Command Failed
150
- }
151
173
return (0 ); // Finished without Errors
152
174
}
153
175
0 commit comments