Browse Source

fix fmc flash bug

Signed-off-by: huhui <huhui@sharkgulf.com>
huhui 5 years ago
parent
commit
d931e38c28
3 changed files with 87 additions and 22 deletions
  1. 32 0
      Application/bsp/bsp.c
  2. 51 22
      Application/bsp/fmc_flash.c
  3. 4 0
      Application/bsp/fmc_flash.h

+ 32 - 0
Application/bsp/bsp.c

@@ -4,6 +4,11 @@
 #include "bsp/AT24CXX.h"
 #include "bsp/shark_rtc.h"
 #include "bsp/clock.h"
+#include "bsp/fmc_flash.h"
+#include "libs/logger.h"
+
+#include <string.h>
+
 #if defined CONFIG_BOARD_SP700
 const char iap_board_name[] __attribute__((at(0x08002800))) = "SP700";
 #elif defined CONFIG_BOARD_SP600
@@ -17,6 +22,33 @@ const char iap_fw_name[] __attribute__((at(0x08002C00))) = "App";
 extern void system_clock_config(void);
 extern void SystemCoreClockUpdate(void);
 #define ALARM_TEST 1
+
+#if 0
+void test_fmc_flash(void){
+	uint8_t data[128];
+	fmc_erase_image(50 * 1024);
+	fmc_start_read_image();
+	for(int i = 0; i < sizeof(data); i++){
+		data[i] = i;
+	}
+	int count = 50;
+	while(count-- >= 0) {
+		for(int i = 0; i < sizeof(data); i++){
+			data[i] = i;
+		}		
+		fmc_write_image(data, sizeof(data));
+
+		memset(data, 0, sizeof(data));
+		fmc_read_image(data, sizeof(data));
+		for(int i = 0; i < sizeof(data); i++){
+			if (data[i] != (uint8_t)i){
+				sys_debug("");
+			}
+		}
+	}
+}
+#endif
+
 //all board's low level init is here
 void bsp_init(void){
 	wdog_start(4);

+ 51 - 22
Application/bsp/fmc_flash.c

@@ -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();
 }

+ 4 - 0
Application/bsp/fmc_flash.h

@@ -9,6 +9,10 @@ void fmc_write_data(uint8_t *data, int len);
 void fmc_read_data(uint8_t *data, int len);
 void fmc_write_magic(uint32_t magic);
 uint32_t fmc_read_magic(void);
+void fmc_erase_image(int len);
+void fmc_write_image(uint8_t *data, int len);
+void fmc_read_image(uint8_t *data, int len);
+void fmc_start_read_image(void);
 
 #endif /* _FMC_FLASH_H__ */