|
|
@@ -7,17 +7,22 @@
|
|
|
#define FMC_FLAG_END FMC_FLAG_BANK0_END
|
|
|
#endif
|
|
|
|
|
|
-#define one_page_size 2048
|
|
|
+#define one_page_size 1024
|
|
|
+#define image_page_index 62
|
|
|
#define sn_page_index 3
|
|
|
#define data_page_index 2
|
|
|
#define magic_page_index 1 //must is the last page in 256K eara
|
|
|
static void _fmc_write_data(uint32_t addr, uint8_t *data, int len);
|
|
|
static void _fmc_read_data(uint32_t addr, uint8_t *data, int len);
|
|
|
+static void _fmc_erase_addr(uint32_t addr, int len);
|
|
|
static uint32_t _sn_addr(void);
|
|
|
static uint32_t _data_addr(void);
|
|
|
static uint32_t _maigc_addr(void);
|
|
|
-
|
|
|
+static uint32_t _image_addr(void);
|
|
|
+static uint32_t _image_write_addr = 0;
|
|
|
+static uint32_t _image_read_addr = 0;
|
|
|
void fmc_write_sn(uint8_t *sn, int len){
|
|
|
+ _fmc_erase_addr(_sn_addr(), len);
|
|
|
_fmc_write_data(_sn_addr(), sn, len);
|
|
|
}
|
|
|
|
|
|
@@ -26,6 +31,7 @@ void fmc_read_sn(uint8_t *sn, int len){
|
|
|
}
|
|
|
|
|
|
void fmc_write_data(uint8_t *data, int len){
|
|
|
+ _fmc_erase_addr(_data_addr(), len);
|
|
|
_fmc_write_data(_data_addr(), data, len);
|
|
|
}
|
|
|
|
|
|
@@ -33,6 +39,23 @@ void fmc_read_data(uint8_t *data, int len){
|
|
|
_fmc_read_data(_data_addr(), data, len);
|
|
|
}
|
|
|
|
|
|
+void fmc_erase_image(int len){
|
|
|
+ _fmc_erase_addr(_image_addr(), len);
|
|
|
+ _image_write_addr = 0;
|
|
|
+}
|
|
|
+void fmc_write_image(uint8_t *data, int len){
|
|
|
+ _fmc_write_data(_image_addr() + _image_write_addr, data, len);
|
|
|
+ _image_write_addr += len;
|
|
|
+}
|
|
|
+
|
|
|
+void fmc_start_read_image(void){
|
|
|
+ _image_read_addr = 0;
|
|
|
+}
|
|
|
+void fmc_read_image(uint8_t *data, int len){
|
|
|
+ _fmc_read_data(_image_addr() + _image_read_addr, data, len);
|
|
|
+ _image_read_addr += len;
|
|
|
+}
|
|
|
+
|
|
|
static __inline__ void _fmc_flag_clear(void) {
|
|
|
fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_WPERR | FMC_FLAG_END);
|
|
|
}
|
|
|
@@ -98,6 +121,10 @@ static uint32_t _maigc_addr(void){
|
|
|
return 0x08000000 + (_flash_capatity() - one_page_size * magic_page_index);
|
|
|
}
|
|
|
|
|
|
+static uint32_t _image_addr(void){
|
|
|
+ return 0x08000000 + (one_page_size * image_page_index);
|
|
|
+}
|
|
|
+
|
|
|
static void _fmc_read_data(uint32_t addr, uint8_t *data, int len){
|
|
|
int i = 0;
|
|
|
for (i = 0; i < len; i++){
|
|
|
@@ -105,34 +132,36 @@ static void _fmc_read_data(uint32_t addr, uint8_t *data, int len){
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+static void _fmc_erase_addr(uint32_t addr, int len){
|
|
|
+ fmc_unlock();
|
|
|
+ uint32_t pages = len/one_page_size + ((len % one_page_size) > 0)?1:0;
|
|
|
+ for (int i = 0; i < pages; i++){
|
|
|
+ fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_WPERR | FMC_FLAG_END);
|
|
|
+ fmc_page_erase(addr + i * one_page_size);
|
|
|
+ }
|
|
|
+ fmc_lock();
|
|
|
+}
|
|
|
+
|
|
|
static void _fmc_write_data(uint32_t addr, uint8_t *data, int len){
|
|
|
fmc_unlock();
|
|
|
- fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_WPERR | FMC_FLAG_END);
|
|
|
- fmc_page_erase(addr);
|
|
|
- int total_words = len>>2;
|
|
|
+ int total_words = len / 4;
|
|
|
uint32_t *p_u32_data = (uint32_t *)data;
|
|
|
int i;
|
|
|
for (i = 0; i < total_words; i++){
|
|
|
fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_WPERR | FMC_FLAG_END);
|
|
|
- fmc_word_program(addr + i * 4, p_u32_data[i]);
|
|
|
+ fmc_word_program(addr, p_u32_data[i]);
|
|
|
+ data += 4;
|
|
|
+ addr += 4;
|
|
|
}
|
|
|
- data += i * 4;
|
|
|
- addr += i * 4;
|
|
|
- total_words = len - total_words * 4;
|
|
|
- if (total_words > 0){
|
|
|
- if (total_words == 1){
|
|
|
- uint16_t half = *data;
|
|
|
- fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_WPERR | FMC_FLAG_END);
|
|
|
- fmc_halfword_program(addr, half);
|
|
|
- }else if (total_words == 2){
|
|
|
- uint16_t half = *((uint16_t *)data);
|
|
|
- fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_WPERR | FMC_FLAG_END);
|
|
|
- fmc_halfword_program(addr, half);
|
|
|
- }else {
|
|
|
- uint32_t words = *((uint32_t *)data);
|
|
|
- fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_WPERR | FMC_FLAG_END);
|
|
|
- fmc_word_program(addr, words);
|
|
|
+
|
|
|
+ int remain_len = len - total_words * 4;
|
|
|
+ if (remain_len > 0){
|
|
|
+ uint32_t words = 0;
|
|
|
+ for (int i = 0; i < remain_len; i++){
|
|
|
+ words |= data[i] << (8*i);
|
|
|
}
|
|
|
+ fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_WPERR | FMC_FLAG_END);
|
|
|
+ fmc_word_program(addr, words);
|
|
|
}
|
|
|
fmc_lock();
|
|
|
}
|