Explorar el Código

update soc&nv storage

Signed-off-by: huhui <huhui@sharkgulf.com>
huhui hace 5 años
padre
commit
36c9f5b6c5

+ 2 - 1
Application/app/bms_message.c

@@ -11,6 +11,7 @@
 
 static uint8_t bms_insert = 0;
 static uint8_t bms_insert_ack = 0;
+//主要用来告知PSxxx是否刚插入,PSxxx答复后需要清除
 void bms_message_update_insert(int is_hall_detect){
 	if (!is_hall_detect){
 		bms_insert = 0;
@@ -32,7 +33,7 @@ void process_bms_message(can_frame_t *frame, int len){
 				result = 1;
 			}else {
 				pwr_cmd_t *cmd = (pwr_cmd_t *)frame->data;
-				int user_request = (int)USER_REQUEST_PENDING;
+				uint32_t user_request = USER_REQUEST_PENDING;
 				if (cmd->charger_fet){
 					user_request |= USER_REQUEST_CHARGER;
 				}

+ 34 - 0
Application/app/nv_storage.c

@@ -0,0 +1,34 @@
+#include "nv_storage.h"
+#include "bsp/AT24CXX.h"
+#include "app/sox/soc.h"
+#include "libs/logger.h"
+#include "libs/shark_utils.h"
+
+
+#define SOC_ADDR 0
+
+void nv_save_soc(void){
+	soc_t *soc = get_soc();
+	
+	uint16_t crc16 = shark_crc16_update(0, (const u8 *)soc, sizeof(soc_t));
+	u64 start_time = shark_get_mseconds();
+	AT24CXX_Write(SOC_ADDR ,(uint8_t *)soc, sizeof(soc_t));
+	AT24CXX_Write(SOC_ADDR + sizeof(soc_t),(uint8_t *)&crc16, sizeof(crc16));
+	printf("write e2rom time %lld\n", (shark_get_mseconds() - start_time));
+}
+
+int nv_restore_soc(void){
+	soc_t soc;
+	AT24CXX_Read(SOC_ADDR , (uint8_t *)&soc, sizeof(soc_t));
+	uint16_t crc16 = shark_crc16_update(0, (const u8 *)&soc, sizeof(soc_t));
+	uint16_t crc_nv;
+	AT24CXX_Read(SOC_ADDR + sizeof(soc_t), (uint8_t *)&crc_nv, sizeof(crc_nv));
+	if (crc_nv != crc16) {
+		return -1;
+	}
+
+	*get_soc() = soc;
+
+	return 0;
+}
+

+ 4 - 0
Application/app/nv_storage.h

@@ -0,0 +1,4 @@
+#pragma once
+
+extern void nv_save_soc(void);
+extern int nv_restore_soc(void);

+ 1 - 0
Application/app/sox/health.c

@@ -123,6 +123,7 @@ void check_current_state(void){
 			shark_timer_post(&_charger_detect_timer._timer, _charger_detect_timer.interval);
 		}
 	}
+	
 	debug_health();
 }
 

+ 49 - 2
Application/app/sox/soc.c

@@ -1,6 +1,8 @@
 #include "soc.h"
 #include "app/sox/measure.h"
 #include "app/sox/measure_task.h"
+#include "app/nv_storage.h"
+#include "libs/logger.h"
 #include "health.h"
 #include "state.h"
 
@@ -9,10 +11,45 @@ static uint8_t charing = 0;
 static u64     time_ms = 0;
 static float _charger_coefficient = 1.0f;
 static float _discharger_coefficient = 1.0f;
+
+static void calibrate_soc_by_ocv(void);
+
+
 void soc_init(void){
+	set_log_level(MOD_SOC, L_debug);
 	time_ms = shark_get_mseconds();
-	_soc.coulomb_min = 0;
-	_soc.coulomb_max = 30.0f * 3600.0f; //30HA,这个值最总需要health模块给
+	if (nv_restore_soc() != 0){
+		soc_warning("SOC: nv storage is not inited, use default value!!\n");
+		_soc.coulomb_min = 0;
+		_soc.coulomb_max = 30.0f * 3600.0f; //30HA,这个值最总需要soh模块给
+		calibrate_soc_by_ocv();
+		nv_save_soc();
+	}
+}
+
+//初始上电或者nv出问题后,通过开路电压对soc做一次初略校准
+static void calibrate_soc_by_ocv(void){
+	uint16_t pack_vol = 0;
+	for (int i = 0; i < CELLS_NUM; i++){
+		pack_vol += measure_value()->cell_vol[i];
+	}
+	if (pack_vol < (2200 * CELLS_NUM)){
+		_soc.capacity = 0;
+	}else if (pack_vol < (2700 * CELLS_NUM)){
+		_soc.capacity = 5;
+	}else if (pack_vol < (3200 * CELLS_NUM)){
+		_soc.capacity = 15;
+	}else if (pack_vol < (3400 * CELLS_NUM)){
+		_soc.capacity = 50;
+	}else if (pack_vol < (3500 * CELLS_NUM)){
+		_soc.capacity = 75;
+	}else if (pack_vol < (3600 * CELLS_NUM)){
+		_soc.capacity = 95;
+	}else {
+		_soc.capacity = 100;
+	}
+	_soc.coulomb_now = _soc.coulomb_max * _soc.capacity / 100.0f;
+	soc_warning("SOC: calibrate_soc_by_ocv -> capacity = %d, pack_voltage = %d\n", _soc.capacity, pack_vol);
 }
 
 static __inline__ float _delta_time(void){
@@ -39,7 +76,17 @@ void soc_update(void){
 		_soc.dischrger_coulomb += abs(delta_q); //转为正数
 	}
 	_soc.coulomb_now += delta_q; //充电加, 放电减
+
+	if (_soc.coulomb_now > _soc.coulomb_max){
+		_soc.coulomb_now = _soc.coulomb_max;
+	}else if (_soc.coulomb_now < _soc.coulomb_min){
+		_soc.coulomb_now = _soc.coulomb_min;
+	}
+	uint8_t old_cap = _soc.capacity;
 	_soc.capacity = (_soc.coulomb_now - _soc.coulomb_min)/(_soc.coulomb_max - _soc.coulomb_min) * 100;
+	if (old_cap != _soc.capacity) {
+		nv_save_soc();
+	}
 }
 
 soc_t *get_soc(void){

+ 48 - 8
Application/app/sox/state.c

@@ -1,17 +1,19 @@
 #include "bsp/gpio.h"
 #include "bsp/ml5238.h"
+#include "bsp/uart.h"
 #include "bsp/mcu_power_sleep.h"
 #include "app/sox/measure.h"
 #include "app/sox/measure_task.h"
 #include "libs/shark_task.h"
 #include "libs/logger.h"
+#include "app/nv_storage.h"
 #include "health.h"
 #include "soc.h"
 #include "state.h"
 #include "iostate.h"
 
 #define ALLOW_DEEP_SLEEP 0
-#define ALLOW_POWER_DOWN 1
+#define ALLOW_POWER_DOWN 0 //disable power down for debug
 #define ALLOW_5238_BALANCE 1
 
 static void _current_notify(void);
@@ -44,7 +46,7 @@ bms_state_t *bms_state_get(void){
  放电mos和充电mos的开关要小心:
  1. 大部分的情况下,尽量能做到同时开关,主要是用来保护被关闭那路mos的体二极管(不能过大电流)
  2. 充电过压的情况下,必须要关闭充电mos,但是这个时候放电mos可能是打开的,这样的情况下,
-    需要检测放电电流,超过4A必须强制打开充电mos,防止烧充电mos的体二极管
+    需要检测放电电流,超过10A必须强制打开充电mos,防止烧充电mos的体二极管
  3. 收到打开大电的指令后,必须两个mos都要打开,然后再经过2的判断
     。。。。。
 */
@@ -117,8 +119,12 @@ static void _process_power_down(void){
 #if (ALLOW_POWER_DOWN==1)	
 	if (bms_health()->powerdown_lower_voltage){
 		state_debug("BMS System PowerDown!!\n");
+
+		nv_save_soc();
+		
 		ml5238_enable_charger_detect(AUX_VOL_IS_OPEN(), 1);
 		delay_us(2* 1000);
+		shark_uart_flush();
 		if (!ml5238_charger_is_disconnect(AUX_VOL_IS_OPEN())){//have charger, do'nt power down
 			bms_health()->powerdown_lower_voltage = 0;
 			ml5238_enable_charger_detect(AUX_VOL_IS_OPEN(), 0);
@@ -135,6 +141,7 @@ static void _process_power_down(void){
 		delay_us(2* 1000);
 		u64 wait_start = shark_get_mseconds();
 		while(!ml5238_charger_is_disconnect(AUX_VOL_IS_OPEN())){
+			shark_uart_flush();
 			if (shark_get_mseconds() - wait_start >= 2000){
 				bms_health()->powerdown_lower_voltage = 0;
 				ml5238_enable_charger_detect(AUX_VOL_IS_OPEN(), 0);
@@ -165,15 +172,15 @@ static void _process_deepsleep(s32 health){
 	/*if (红外或者485通信没有超时){
 		return;
 	}*/
-
-	AUX_VOL_OPEN(1); 
-
-	delay_us(5000);//delay 5ms, to detect if short current
+	if (!AUX_VOL_IS_OPEN()) {
+		AUX_VOL_OPEN(1);		
+		delay_us(5000);//delay 5ms, to detect if short current
+	}
 
 	if (io_state()->aux_lock_detect){
 		return;
 	}
-	
+	nv_save_soc();
 	mcu_enter_deepsleep();
 #endif	
 }
@@ -214,15 +221,48 @@ static void check_charging(){
 	}else if ((measure_value()->load_current < MIN_START_CHARGER_CURRENT) && _bms_state.charging){
 		debounce_dec(_charging_detect);
 		if (debounce_reach_zero(_charging_detect)){
-			_bms_state.charging = 1;
+			_bms_state.charging = 0;
 			debounce_reset(_charging_detect);
 		}		
 	}	
 }
 
+/* if discharger mos and charger mos, one is open but other is closed.
+   we must judage the current: if current is large than 10A(-10A), 
+   we must open the closed mos to avoid the closed mos to be destroyed
+*/
+#define MIN_CURRENT_FOR_BOTH_MOS_OPEN (10 * 1000)
+static int _min_current_for_both_mos_count = 0;
+static void _check_mos_stat(void){
+	if (abs(measure_value()->load_current) >= MIN_CURRENT_FOR_BOTH_MOS_OPEN){
+		_min_current_for_both_mos_count ++;
+		if (_min_current_for_both_mos_count == 2){
+			int dmos = ml5238_is_discharging();
+			int cmos = ml5238_is_charging();
+			if (dmos + cmos == 0){
+				state_error("current = %d, but all mos is closed\n", measure_value()->load_current);
+				return;
+			}
+			if (dmos == 1 && cmos == 1){
+				return;
+			}
+			uint32_t request = USER_REQUEST_PENDING;
+			if (!dmos) {
+				request |= USER_REQUEST_DISCHARGER;
+			}else {
+				request |= USER_REQUEST_CHARGER;
+			}
+			_bms_state.user_request = request;
+		}
+	}else {
+		_min_current_for_both_mos_count = 0;
+	}
+}
+
 static void _current_notify(void){
 	check_current_state(); //check health of current
 	check_charging();
+	_check_mos_stat();
 	soc_update(); //计算soc
 }
 

+ 1 - 1
Application/app/sox/state.h

@@ -30,7 +30,7 @@ typedef struct{
 	uint16_t cell_min_vol;
 	uint8_t  cell_index_of_max_vol;
 	int      used_by;//where this battery is used for: on motor, on charger docker, on charger box, NONE
-	int      user_request;
+	uint32_t user_request;
 }bms_state_t;
 
 #define USER_REQUEST_PENDING BIT(31) //ÊÇ·ñÓÐÓû§ÇëÇó

+ 1 - 2
Application/bsp/AT24CXX.h

@@ -1,8 +1,7 @@
-
-
 #ifndef __24CXX_H
 #define __24CXX_H
 
+#include <stdint.h>
 
 #define AT24C01		127
 #define AT24C02		255

+ 5 - 0
Application/bsp/irqs.c

@@ -1,4 +1,5 @@
 #include "gd32f3x0.h"
+#include "nv_storage.h"
 /*!
     \brief      this function handles NMI exception
     \param[in]  none
@@ -17,6 +18,7 @@ void NMI_Handler(void)
 */
 void HardFault_Handler(void){
     /* if Hard Fault exception occurs, go to infinite loop */
+	nv_save_soc();
     while (1){
     }
 }
@@ -30,6 +32,7 @@ void HardFault_Handler(void){
 void MemManage_Handler(void)
 {
     /* if Memory Manage exception occurs, go to infinite loop */
+	nv_save_soc();
     while (1){
     }
 }
@@ -43,6 +46,7 @@ void MemManage_Handler(void)
 void BusFault_Handler(void)
 {
     /* if Bus Fault exception occurs, go to infinite loop */
+	nv_save_soc();
     while (1){
     }
 }
@@ -56,6 +60,7 @@ void BusFault_Handler(void)
 void UsageFault_Handler(void)
 {
     /* if Usage Fault exception occurs, go to infinite loop */
+	nv_save_soc();
     while (1){
     }
 }

+ 39 - 0
Application/bsp/uart.c

@@ -157,6 +157,7 @@ static void shark_uart_write(shark_uart_t *uart, const u8 *buff, u16 size)
 		u16 length = byte_queue_write(&uart->tx_queue, buff, size);
 
 		if (length == size) {
+			shark_uart_dma_tx(uart);
 			break;
 		}
 
@@ -187,6 +188,14 @@ static void shark_uart_tx_dma_init(shark_uart_t *uart){
 	dma_circulation_disable(uart->tx_dma_ch);
 	dma_memory_to_memory_disable(uart->tx_dma_ch);
 	usart_dma_transmit_config(uart->uart_com, USART_DENT_ENABLE);
+#if 0
+	if (uart->tx_dma_ch == DMA_CH1) {
+		nvic_irq_enable(DMA_Channel1_2_IRQn ,4, 0);
+	}else {
+		nvic_irq_enable(DMA_Channel3_4_IRQn ,4, 0);
+	}
+	dma_interrupt_enable(uart->tx_dma_ch, DMA_INT_FTF);
+#endif
 }
 
 
@@ -264,6 +273,36 @@ static u32 shark_uart_handler(void)
 	return 0;
 }
 
+void shark_uart_flush(void){
+	shark_uart_t *uart = _shark_uart + SHARK_UART0;
+	if (uart->uart_com != 0) {
+		shark_uart_dma_tx(uart);
+	}
+	uart = _shark_uart + SHARK_UART1;
+	if (uart->uart_com != 0) {
+		shark_uart_dma_tx(uart);
+	}
+}
+
+
+#if 0
+void DMA_Channel1_2_IRQHandler(void){
+	shark_uart_t *uart = _shark_uart + SHARK_UART0;
+	if (dma_interrupt_flag_get(uart->tx_dma_ch, DMA_INT_FLAG_FTF) != RESET){
+		shark_uart_dma_tx(uart);
+		dma_interrupt_flag_clear(uart->tx_dma_ch, DMA_INT_FLAG_FTF);
+	}
+}
+
+void DMA_Channel3_4_IRQHandler(void){
+	shark_uart_t *uart = _shark_uart + SHARK_UART1;
+	if (dma_interrupt_flag_get(uart->tx_dma_ch, DMA_INT_FLAG_FTF) != RESET){
+		shark_uart_dma_tx(uart);
+		dma_interrupt_flag_clear(uart->tx_dma_ch, DMA_INT_FLAG_FTF);
+	}
+}
+#endif
+
 static u8 *tx_cache_addr(uart_enum_t uart_no){
 	return (uart_no == SHARK_UART0)?shark_uart0_tx_cache:shark_uart1_tx_cache;
 }

+ 1 - 0
Application/bsp/uart.h

@@ -44,6 +44,7 @@ void shark_uart_frame_start(uart_enum_t uart_no, uint8_t *bytes, int len);
 void shark_uart_frame_continue(uart_enum_t uart_no, uint8_t *bytes, int len);
 void shark_uart_frame_end(uart_enum_t uart_no);
 void shark_uart_write_bytes(uart_enum_t uart_no, u8 *buff, u16 size);
+void shark_uart_flush(void);
 
 
 

+ 9 - 4
Application/libs/logger.h

@@ -20,7 +20,7 @@
 #define MOD_MEASURE 2
 #define MOD_STATE   3
 #define MOD_SYSTEM    4
-
+#define MOD_SOC       5
 extern void set_log_level(int mod, int l);
 extern void log_debug(int mod, char *fmt, ...);
 extern void log_warning(int mod, char *fmt, ...);
@@ -41,10 +41,15 @@ extern void log_error(int mod, char *fmt, ...);
 
 #define state_debug(fmt, args...) log_debug(MOD_STATE, "D"fmt, ##args)
 #define state_warning(fmt, args...) log_warning(MOD_STATE, "W"fmt, ##args)
-#define state_error(fmt, args...) log_error(MOD_STATE, fmt, "E"##args)
+#define state_error(fmt, args...) log_error(MOD_STATE, "E"fmt, ##args)
 
-#define sys_debug(fmt, args...) log_debug(MOD_SYSTEM, fmt, "D"##args)
+#define sys_debug(fmt, args...) log_debug(MOD_SYSTEM, "D"fmt, ##args)
 #define sys_warning(fmt, args...) log_warning(MOD_SYSTEM, "W"fmt, ##args)
-#define sys_error(fmt, args...) log_error(MOD_SYSTEM, fmt, "E"##args)
+#define sys_error(fmt, args...) log_error(MOD_SYSTEM, "E"fmt, ##args)
+
+#define soc_debug(fmt, args...) log_debug(MOD_SOC, "D"fmt, ##args)
+#define soc_warning(fmt, args...) log_warning(MOD_SOC, "W"fmt, ##args)
+#define soc_error(fmt, args...) log_error(MOD_SOC, "E"fmt, ##args)
+
 #endif /* _Shark_Logger_h__ */
 

+ 60 - 48
Project/SP700.uvoptx

@@ -306,6 +306,18 @@
       <RteFlg>0</RteFlg>
       <bShared>0</bShared>
     </File>
+    <File>
+      <GroupNumber>1</GroupNumber>
+      <FileNumber>5</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\Application\app\nv_storage.c</PathWithFileName>
+      <FilenameWithoutPath>nv_storage.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
   </Group>
 
   <Group>
@@ -316,7 +328,7 @@
     <RteFlg>0</RteFlg>
     <File>
       <GroupNumber>2</GroupNumber>
-      <FileNumber>5</FileNumber>
+      <FileNumber>6</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -328,7 +340,7 @@
     </File>
     <File>
       <GroupNumber>2</GroupNumber>
-      <FileNumber>6</FileNumber>
+      <FileNumber>7</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -340,7 +352,7 @@
     </File>
     <File>
       <GroupNumber>2</GroupNumber>
-      <FileNumber>7</FileNumber>
+      <FileNumber>8</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -352,7 +364,7 @@
     </File>
     <File>
       <GroupNumber>2</GroupNumber>
-      <FileNumber>8</FileNumber>
+      <FileNumber>9</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -364,7 +376,7 @@
     </File>
     <File>
       <GroupNumber>2</GroupNumber>
-      <FileNumber>9</FileNumber>
+      <FileNumber>10</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -376,7 +388,7 @@
     </File>
     <File>
       <GroupNumber>2</GroupNumber>
-      <FileNumber>10</FileNumber>
+      <FileNumber>11</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -396,7 +408,7 @@
     <RteFlg>0</RteFlg>
     <File>
       <GroupNumber>3</GroupNumber>
-      <FileNumber>11</FileNumber>
+      <FileNumber>12</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -408,7 +420,7 @@
     </File>
     <File>
       <GroupNumber>3</GroupNumber>
-      <FileNumber>12</FileNumber>
+      <FileNumber>13</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -420,7 +432,7 @@
     </File>
     <File>
       <GroupNumber>3</GroupNumber>
-      <FileNumber>13</FileNumber>
+      <FileNumber>14</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -432,7 +444,7 @@
     </File>
     <File>
       <GroupNumber>3</GroupNumber>
-      <FileNumber>14</FileNumber>
+      <FileNumber>15</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -444,7 +456,7 @@
     </File>
     <File>
       <GroupNumber>3</GroupNumber>
-      <FileNumber>15</FileNumber>
+      <FileNumber>16</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -456,7 +468,7 @@
     </File>
     <File>
       <GroupNumber>3</GroupNumber>
-      <FileNumber>16</FileNumber>
+      <FileNumber>17</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -468,7 +480,7 @@
     </File>
     <File>
       <GroupNumber>3</GroupNumber>
-      <FileNumber>17</FileNumber>
+      <FileNumber>18</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -480,7 +492,7 @@
     </File>
     <File>
       <GroupNumber>3</GroupNumber>
-      <FileNumber>18</FileNumber>
+      <FileNumber>19</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -492,7 +504,7 @@
     </File>
     <File>
       <GroupNumber>3</GroupNumber>
-      <FileNumber>19</FileNumber>
+      <FileNumber>20</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -504,7 +516,7 @@
     </File>
     <File>
       <GroupNumber>3</GroupNumber>
-      <FileNumber>20</FileNumber>
+      <FileNumber>21</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -516,7 +528,7 @@
     </File>
     <File>
       <GroupNumber>3</GroupNumber>
-      <FileNumber>21</FileNumber>
+      <FileNumber>22</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -528,7 +540,7 @@
     </File>
     <File>
       <GroupNumber>3</GroupNumber>
-      <FileNumber>22</FileNumber>
+      <FileNumber>23</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -548,7 +560,7 @@
     <RteFlg>0</RteFlg>
     <File>
       <GroupNumber>4</GroupNumber>
-      <FileNumber>23</FileNumber>
+      <FileNumber>24</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -560,7 +572,7 @@
     </File>
     <File>
       <GroupNumber>4</GroupNumber>
-      <FileNumber>24</FileNumber>
+      <FileNumber>25</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -572,7 +584,7 @@
     </File>
     <File>
       <GroupNumber>4</GroupNumber>
-      <FileNumber>25</FileNumber>
+      <FileNumber>26</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -584,7 +596,7 @@
     </File>
     <File>
       <GroupNumber>4</GroupNumber>
-      <FileNumber>26</FileNumber>
+      <FileNumber>27</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -596,7 +608,7 @@
     </File>
     <File>
       <GroupNumber>4</GroupNumber>
-      <FileNumber>27</FileNumber>
+      <FileNumber>28</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -616,7 +628,7 @@
     <RteFlg>0</RteFlg>
     <File>
       <GroupNumber>5</GroupNumber>
-      <FileNumber>28</FileNumber>
+      <FileNumber>29</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -628,7 +640,7 @@
     </File>
     <File>
       <GroupNumber>5</GroupNumber>
-      <FileNumber>29</FileNumber>
+      <FileNumber>30</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -640,7 +652,7 @@
     </File>
     <File>
       <GroupNumber>5</GroupNumber>
-      <FileNumber>30</FileNumber>
+      <FileNumber>31</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -652,7 +664,7 @@
     </File>
     <File>
       <GroupNumber>5</GroupNumber>
-      <FileNumber>31</FileNumber>
+      <FileNumber>32</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -664,7 +676,7 @@
     </File>
     <File>
       <GroupNumber>5</GroupNumber>
-      <FileNumber>32</FileNumber>
+      <FileNumber>33</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -676,7 +688,7 @@
     </File>
     <File>
       <GroupNumber>5</GroupNumber>
-      <FileNumber>33</FileNumber>
+      <FileNumber>34</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -688,7 +700,7 @@
     </File>
     <File>
       <GroupNumber>5</GroupNumber>
-      <FileNumber>34</FileNumber>
+      <FileNumber>35</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -700,7 +712,7 @@
     </File>
     <File>
       <GroupNumber>5</GroupNumber>
-      <FileNumber>35</FileNumber>
+      <FileNumber>36</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -712,7 +724,7 @@
     </File>
     <File>
       <GroupNumber>5</GroupNumber>
-      <FileNumber>36</FileNumber>
+      <FileNumber>37</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -724,7 +736,7 @@
     </File>
     <File>
       <GroupNumber>5</GroupNumber>
-      <FileNumber>37</FileNumber>
+      <FileNumber>38</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -736,7 +748,7 @@
     </File>
     <File>
       <GroupNumber>5</GroupNumber>
-      <FileNumber>38</FileNumber>
+      <FileNumber>39</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -748,7 +760,7 @@
     </File>
     <File>
       <GroupNumber>5</GroupNumber>
-      <FileNumber>39</FileNumber>
+      <FileNumber>40</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -760,7 +772,7 @@
     </File>
     <File>
       <GroupNumber>5</GroupNumber>
-      <FileNumber>40</FileNumber>
+      <FileNumber>41</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -772,7 +784,7 @@
     </File>
     <File>
       <GroupNumber>5</GroupNumber>
-      <FileNumber>41</FileNumber>
+      <FileNumber>42</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -784,7 +796,7 @@
     </File>
     <File>
       <GroupNumber>5</GroupNumber>
-      <FileNumber>42</FileNumber>
+      <FileNumber>43</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -796,7 +808,7 @@
     </File>
     <File>
       <GroupNumber>5</GroupNumber>
-      <FileNumber>43</FileNumber>
+      <FileNumber>44</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -808,7 +820,7 @@
     </File>
     <File>
       <GroupNumber>5</GroupNumber>
-      <FileNumber>44</FileNumber>
+      <FileNumber>45</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -820,7 +832,7 @@
     </File>
     <File>
       <GroupNumber>5</GroupNumber>
-      <FileNumber>45</FileNumber>
+      <FileNumber>46</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -832,7 +844,7 @@
     </File>
     <File>
       <GroupNumber>5</GroupNumber>
-      <FileNumber>46</FileNumber>
+      <FileNumber>47</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -844,7 +856,7 @@
     </File>
     <File>
       <GroupNumber>5</GroupNumber>
-      <FileNumber>47</FileNumber>
+      <FileNumber>48</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -856,7 +868,7 @@
     </File>
     <File>
       <GroupNumber>5</GroupNumber>
-      <FileNumber>48</FileNumber>
+      <FileNumber>49</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -868,7 +880,7 @@
     </File>
     <File>
       <GroupNumber>5</GroupNumber>
-      <FileNumber>49</FileNumber>
+      <FileNumber>50</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -880,7 +892,7 @@
     </File>
     <File>
       <GroupNumber>5</GroupNumber>
-      <FileNumber>50</FileNumber>
+      <FileNumber>51</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -900,7 +912,7 @@
     <RteFlg>0</RteFlg>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>51</FileNumber>
+      <FileNumber>52</FileNumber>
       <FileType>2</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -912,7 +924,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>52</FileNumber>
+      <FileNumber>53</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>

+ 5 - 0
Project/SP700.uvprojx

@@ -403,6 +403,11 @@
               <FileType>1</FileType>
               <FilePath>..\Application\app\pc_message.c</FilePath>
             </File>
+            <File>
+              <FileName>nv_storage.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Application\app\nv_storage.c</FilePath>
+            </File>
           </Files>
         </Group>
         <Group>