📄 eeprom.lst
字号:
C51 COMPILER V7.00 EEPROM 02/10/2003 10:48:05 PAGE 1
C51 COMPILER V7.00, COMPILATION OF MODULE EEPROM
OBJECT MODULE PLACED IN eeprom.OBJ
COMPILER INVOKED BY: C:\KEIL\C51\BIN\C51.EXE eeprom.c BROWSE DEBUG OBJECTEXTEND
stmt level source
1 /*--------------------------------------------------------------------------
2 eeprom.c
3
4 Header file for eeprom emulation using boot (secondary) flash
5 11/2002 Ver 0.1 - Initial Version
6
7 Copyright (c) 2002 ST Microelectronics
8 This example demo code is provided as is and has no warranty,
9 implied or otherwise. You are free to use/modify any of the provided
10 code at your own risk in your applications with the expressed limitation
11 of liability (see below) so long as your product using the code contains
12 at least one uPSD products (device).
13
14 LIMITATION OF LIABILITY: NEITHER STMicroelectronics NOR ITS VENDORS OR
15 AGENTS SHALL BE LIABLE FOR ANY LOSS OF PROFITS, LOSS OF USE, LOSS OF DATA,
16 INTERRUPTION OF BUSINESS, NOR FOR INDIRECT, SPECIAL, INCIDENTAL OR
17 CONSEQUENTIAL DAMAGES OF ANY KIND WHETHER UNDER THIS AGREEMENT OR
18 OTHERWISE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
19 --------------------------------------------------------------------------*/
20
21
22 #include "eeprom.h"
23 #include "upsd3200.h" // special function register declarations for UPSD
24
25
26 /***** EEPROM_Format *****/
27 // Formats sectors 0 and 1 to accept record data
28 // Accepts maximum number of records allowed.
29 // Returns 0 on success. If error, returns 1.
30 // ********** WARNING ********** //
31 // This function erases any existing data in both sectors
32 // ********** WARNING ********** //
33 BYTE EEPROM_Format(WORD max_records)
34 {
35 1 xdata struct record_entry xdata record;
36 1
37 1 // Verify data will fit into half of sector
38 1 if ( (sizeof(record) * max_records) > (SECTOR_SIZE/2) )
39 1 return ILLEGAL_RECORD_NUMBER;
40 1
41 1 // Format sector 0
42 1 if ( E_andF_Sector(SECTOR_0, max_records) ) return FORMAT_FAILED;
43 1 // Erase sector 1
44 1 if ( Eeprom_Sector_Erase(SECTOR_1) ) return SECTOR_ERASE_ERROR;
45 1
46 1 return 0;
47 1 }
48
49 /***** Eeprom_Init *****/
50 // Verifies database integrity after power loss.
51 // Attempts to recover data corruption after power loss.
52 // Re-formats database if corrupted.
53 BYTE Eeprom_Init(void)
54 {
55 1 xdata struct sector_header xdata sector_header_0;
C51 COMPILER V7.00 EEPROM 02/10/2003 10:48:05 PAGE 2
56 1 xdata struct sector_header xdata sector_header_1;
57 1 xdata struct record_entry xdata record;
58 1 WORD i, j;
59 1 BYTE *ptr;
60 1 WORD xdata max_rec;
61 1 WORD xdata last_address;
62 1 WORD xdata base_address;
63 1 WORD xdata new_address;
64 1 BYTE xdata valid_sector;
65 1
66 1 // Get both sector headers
67 1 ptr = (BYTE*) (§or_header_0);
68 1 base_address = SECTOR_0_BASE_ADDRESS;
69 1 for ( i=0; i < sizeof(sector_header_0); i++ )
70 1 {
71 2 ptr[i] = Boot_Flash_Read( base_address++ );
72 2 }
73 1 ptr = (BYTE*) (§or_header_1);
74 1 base_address = SECTOR_1_BASE_ADDRESS;
75 1 for ( i=0; i < sizeof(sector_header_1); i++ )
76 1 {
77 2 ptr[i] = Boot_Flash_Read( base_address++ );
78 2 }
79 1
80 1 // Check for corrupted sectors
81 1 // This would occur if a sector erase was interrupted by a power loss
82 1 // In this case, the sector must be re-erased
83 1 if ( ~(sector_header_0.sector ^ sector_header_0.sector_checksum) )
84 1 {
85 2 if ( Eeprom_Sector_Erase(SECTOR_0) ) return SECTOR_ERASE_ERROR;
86 2 sector_header_0.sector_status = ERASED;
87 2 }
88 1 if ( ~(sector_header_1.sector ^ sector_header_1.sector_checksum) )
89 1 {
90 2 if ( Eeprom_Sector_Erase(SECTOR_1) ) return SECTOR_ERASE_ERROR;
91 2 sector_header_1.sector_status = ERASED;
92 2 }
93 1
94 1 // Get maximum number of records from header
95 1 // If unable, return error
96 1 if ( sector_header_0.max_records != 0xFFFF )
97 1 max_rec = sector_header_0.max_records;
98 1 else if ( sector_header_1.max_records != 0xFFFF )
99 1 max_rec = sector_header_1.max_records;
100 1 else
101 1 return ILLEGAL_RECORD_NUMBER;
102 1
103 1 // Check for invalid header states and repair
104 1 switch(sector_header_0.sector_status)
105 1 {
106 2 case ERASED:
107 2 if( sector_header_1.sector_status == VALID__SECTOR ) // sector 1 is valid
108 2 {
109 3 if ( Eeprom_Sector_Erase(SECTOR_0) ) return SECTOR_ERASE_ERROR;
110 3 }
111 2 else // invalid state re-format database
112 2 {
113 3 if ( Eeprom_Sector_Erase(SECTOR_1) ) return SECTOR_ERASE_ERROR;
114 3 if ( E_andF_Sector(SECTOR_0, max_rec) ) return FORMAT_FAILED;
115 3 return INVALID_SECTOR_STATE;
116 3 }
117 2 break;
C51 COMPILER V7.00 EEPROM 02/10/2003 10:48:05 PAGE 3
118 2 case RECEIVE_DATA:
119 2 if ( sector_header_1.sector_status == VALID__SECTOR ) // use sector 1
120 2 {
121 3 if ( Eeprom_Sector_Erase(SECTOR_0) ) return SECTOR_ERASE_ERROR;
122 3 }
123 2 else if(sector_header_1.sector_status == TRANSFER_COMPLETE) //use sector 0
124 2 {
125 3 if ( Eeprom_Sector_Erase(SECTOR_1) ) return SECTOR_ERASE_ERROR;
126 3 // update sector 0 header to valid data
127 3 sector_header_0.sector_status = VALID__SECTOR;
128 3 ptr = (BYTE*) (§or_header_0);
129 3 base_address = SECTOR_0_BASE_ADDRESS;
130 3 for ( i=0; i < sizeof(sector_header_0); i++ )
131 3 {
132 4 if ( Boot_Flash_Write( base_address++, ptr[i] ) ) return FLASH_WRITE_ERROR;
133 4 }
134 3 }
135 2 else // invalid state erase both sectors
136 2 {
137 3 if ( Eeprom_Sector_Erase(SECTOR_1) ) return SECTOR_ERASE_ERROR;
138 3 if ( E_andF_Sector(SECTOR_0, max_rec) ) return FORMAT_FAILED;
139 3 return INVALID_SECTOR_STATE;
140 3 }
141 2 break;
142 2 case VALID__SECTOR:
143 2 if ( sector_header_1.sector_status == VALID__SECTOR ) // invalid state erase both sectors
144 2 {
145 3 if ( Eeprom_Sector_Erase(SECTOR_1) ) return SECTOR_ERASE_ERROR;
146 3 if ( E_andF_Sector(SECTOR_0, max_rec) ) return FORMAT_FAILED;
147 3 return INVALID_SECTOR_STATE;
148 3 }
149 2 else // sector 0 is valid sector, erase sector 1
150 2 {
151 3 if ( Eeprom_Sector_Erase(SECTOR_1) ) return SECTOR_ERASE_ERROR;
152 3 }
153 2 break;
154 2 case TRANSFER_COMPLETE:
155 2 if ( sector_header_1.sector_status == VALID__SECTOR ) // erase sector 0
156 2 {
157 3 if ( Eeprom_Sector_Erase(SECTOR_0) ) return SECTOR_ERASE_ERROR;
158 3 }
159 2 else if (sector_header_1.sector_status == RECEIVE_DATA) // erase sector 0, use sector 1
160 2 {
161 3 if ( Eeprom_Sector_Erase(SECTOR_0) ) return SECTOR_ERASE_ERROR;
162 3 // mark sector 1 as valid sector
163 3 sector_header_1.sector_status = VALID__SECTOR;
164 3 ptr = (BYTE*) (§or_header_1);
165 3 base_address = SECTOR_1_BASE_ADDRESS;
166 3 for ( i=0; i < sizeof(sector_header_1); i++ )
167 3 {
168 4 if ( Boot_Flash_Write( base_address++, ptr[i] ) ) return FLASH_WRITE_ERROR;
169 4 }
170 3 }
171 2 else // invalid state, format both sectors
172 2 {
173 3 if ( Eeprom_Sector_Erase(SECTOR_1) ) return SECTOR_ERASE_ERROR;
174 3 if ( E_andF_Sector(SECTOR_0, max_rec) ) return FORMAT_FAILED;
175 3 return INVALID_SECTOR_STATE;
176 3 }
177 2 break;
178 2 default: // any other state, erase both sectors
179 2
C51 COMPILER V7.00 EEPROM 02/10/2003 10:48:05 PAGE 4
180 2 if ( Eeprom_Sector_Erase(SECTOR_1) ) return SECTOR_ERASE_ERROR;
181 2 if ( E_andF_Sector(SECTOR_0, max_rec) ) return FORMAT_FAILED;
182 2 return INVALID_SECTOR_STATE;
183 2 break;
184 2 }
185 1
186 1 // Check for corrupted data
187 1 // This would happen if a data write/update was interrupted by a power loss
188 1 for ( i=0; i<max_rec; i++ )
189 1 {
190 2 // get address of last entry of each record
191 2 last_address = Read_Record_Data_Structure( i, (BYTE*) (&record) );
192 2 // repair record entry if necessary
193 2 if ( record.status == UPDATE_DATA )
194 2 {
195 3 // get sector
196 3 valid_sector = Find_Active_Sector(F_WRITE);
197 3 if ( valid_sector == SECTOR_ID_ERROR ) return SECTOR_ID_ERROR;
198 3 // get base address of sector
199 3 base_address = SECTOR_0_BASE_ADDRESS + ((WORD)valid_sector * SECTOR_SIZE);
200 3 // get address for repaired entry
201 3 new_address = Find_Next_Address();
202 3 if( new_address == SECTOR_FULL ) return SECTOR_FULL; // abort if sector is full
203 3 // set status and pointer to next data
204 3 record.status = VALID_DATA;
205 3 record.last_record_update = 0xFFFF;
206 3 // write new record with old data
207 3 ptr = (BYTE*) (&record);
208 3 for ( j=0; j<sizeof(record); j++ )
209 3 {
210 4 if ( Boot_Flash_Write(new_address++, ptr[j]) ) return FLASH_WRITE_ERROR;
211 4 }
212 3 // fix status and pointer of old record
213 3 record.status = SUPERSEDED;
214 3 record.last_record_update = new_address - sizeof(record);
215 3 for ( j=0; j < sizeof(record); j++ )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -