1 /********************************** (C) COPYRIGHT *******************************
2 * File Name          : CH57x_flash.c
3 * Author             : WCH
4 * Version            : V1.1
5 * Date               : 2020/03/20
6 * Description        :
7 *******************************************************************************/
8 
9 /******************************************************************************/
10 /* 头文件包含 */
11 #include "CH57x_common.h"
12 
13 /* 操作Flash的保护状态标志 */
14 #define CODEFLASH_SAFE_FLAG1          0x57
15 #define CODEFLASH_SAFE_FLAG2          0xA8
16 
17 /* 操作Flash的保护状态变量 */
18 unsigned char codeflash_access_flag1 = 0x0;
19 unsigned char codeflash_access_flag2 = 0x0;
20 
21 /*******************************************************************************
22 * Function Name  : GetUniqueID
23 * Description    : 获取芯片唯一ID,小端模式,6B-ID, 2B-CKS
24 * Input          : buf: 存储8字节,前6字节(小端)ID,后2字节(小端)校验和
25 * Return         : None
26 *******************************************************************************/
GetUniqueID(PUINT8 buf)27 void GetUniqueID(PUINT8 buf)
28 {
29     PUINT8  pID;
30     UINT8   i;
31 
32     pID = (PUINT8)ROM_UUID_ADDR;
33     for(i=0; i<8; i++) *buf++ = *pID++;
34 }
35 
36 /*******************************************************************************
37 * Function Name  : GetMACAddress
38 * Description    : 获取网络MAC,小端模式,6B-MAC
39 * Input          : buf: 存储6字节,6字节(小端)物理 MAC
40 * Return         : None
41 *******************************************************************************/
GetMACAddress(PUINT8 buf)42 void GetMACAddress(PUINT8 buf)
43 {
44     PUINT8  pMAC;
45     UINT8   i;
46 
47     pMAC = (PUINT8)ROM_MAC_ADDR;
48     for(i=0; i<6; i++) *buf++ = *pMAC++;
49 }
50 
51 /*******************************************************************************
52 * Function Name  : FlashBlockErase
53 * Description    : Flash 块擦除,一次擦除512B
54 * Input          : addr: 32位地址,需要512对齐
55 *                       codeflash:  startAddr - 0x00000000    size - 0x3E800
56 *                       dataflash:  startAddr - 0x3E800(DATA_FLASH_ADDR)       size -  0x0800(DATA_FLASH_SIZE)
57 * Return         : 0 - 成功,其他  - 错误
58 *******************************************************************************/
FlashBlockErase(UINT32 addr)59 UINT8 FlashBlockErase(UINT32 addr)
60 {
61     UINT8  status = 0;
62     volatile UINT8  op_step;
63 
64     if( addr & (0x200-1) )          return 1;  //地址不对齐
65 
66     op_step = 0x11;
67     codeflash_access_flag1 = 0;
68     codeflash_access_flag2 = 0;
69     R8_FLASH_PROTECT = RB_ROM_WE_MUST_10;
70 
71     //开启电压监控中断
72     op_step += 0x11;
73     if((R8_BAT_DET_CTRL & 0x0F) != 0x0D)        PowerMonitor( ENABLE );
74 
75     op_step += 0x11;
76     if((R8_BAT_STATUS & 0x03) != 0x00)      return 2;  //电源电压偏低,Flash不允许操作
77 
78     op_step += 0x11;
79     if(((R8_BAT_STATUS & 0x03) == 0x00)
80         &&(op_step == 0x44))
81     {
82         codeflash_access_flag1 = CODEFLASH_SAFE_FLAG1;
83     }
84 
85     op_step += 0x11;
86     if(((R8_BAT_STATUS & 0x03) == 0x00)
87         &&(op_step == 0x55)
88         &&(codeflash_access_flag1 == CODEFLASH_SAFE_FLAG1))
89     {
90         codeflash_access_flag2 = CODEFLASH_SAFE_FLAG2;
91     }
92 
93     op_step += 0x11;
94     if((codeflash_access_flag1 == CODEFLASH_SAFE_FLAG1)
95      &&(codeflash_access_flag2 == CODEFLASH_SAFE_FLAG2)
96      &&(op_step == 0x66))
97     {
98         R32_FLASH_ADDR = addr;
99         if( addr < DATA_FLASH_ADDR  )    R8_FLASH_PROTECT = RB_ROM_WE_MUST_10|RB_ROM_CODE_WE;   // Codefalsh区
100         else       R8_FLASH_PROTECT = RB_ROM_WE_MUST_10|RB_ROM_DATA_WE;         // datafalsh区
101     }
102 
103     op_step += 0x11;
104     /* 判断操作Flash的保护状态标志 */
105     if((codeflash_access_flag1 == CODEFLASH_SAFE_FLAG1)
106      &&(codeflash_access_flag2 == CODEFLASH_SAFE_FLAG2)
107      &&(op_step == 0x77))
108     {
109         R8_FLASH_COMMAND = ROM_CMD_ERASE;
110         status = (unsigned char)(R16_FLASH_STATUS & 0xff);
111     }
112 
113     op_step = 0x00;
114     codeflash_access_flag1 = 0x00;
115     codeflash_access_flag2 = 0x00;
116     R8_FLASH_PROTECT = RB_ROM_WE_MUST_10;       // LOCK
117 
118     if( status != RB_ROM_ADDR_OK )  return 3;   //操作失败
119     return 0;
120 }
121 
122 /*******************************************************************************
123 * Function Name  : FlashWriteDW
124 * Description    : Flash 双字写,地址需4字节对齐
125 * Input          : addr: 32位地址,需要4对齐
126 *                       codeflash:  startAddr - 0x00000000    size - 0x3E800
127 *                       dataflash:  startAddr - 0x3E800(DATA_FLASH_ADDR)       size -  0x0800(DATA_FLASH_SIZE)
128                     dat: 32位写入数据
129 * Return         : FAILED  - 错误
130                    SUCCESS - 成功
131 *******************************************************************************/
FlashWriteDW(UINT32 addr,UINT32 dat)132 UINT8 FlashWriteDW(UINT32 addr, UINT32 dat)
133 {
134     UINT32  add = addr;
135     UINT32  val = dat;
136     UINT8  status = 0;
137     volatile UINT8  op_step;
138 
139     if( addr & (4-1) )              return 1; //地址不对齐
140 
141     op_step = 0x11;
142     codeflash_access_flag1 = 0;
143     codeflash_access_flag2 = 0;
144     R8_FLASH_PROTECT = RB_ROM_WE_MUST_10;
145 
146     //开启电压监控中断
147     op_step += 0x11;
148     if((R8_BAT_DET_CTRL & 0x0F) != 0x0D)        PowerMonitor( ENABLE );
149 
150     op_step += 0x11;
151     if((R8_BAT_STATUS & 0x03) != 0x00)      return 2;  //电源电压偏低,Flash不允许操作
152 
153     op_step += 0x11;
154     if(((R8_BAT_STATUS & 0x01) == 0x00)
155         &&(op_step == 0x44))
156     {
157         codeflash_access_flag1 = CODEFLASH_SAFE_FLAG1;
158     }
159 
160     op_step += 0x11;
161     if(((R8_BAT_STATUS & 0x01) == 0x00)
162         &&(op_step == 0x55)
163         &&(codeflash_access_flag1 == CODEFLASH_SAFE_FLAG1))
164     {
165         codeflash_access_flag2 = CODEFLASH_SAFE_FLAG2;
166     }
167 
168     op_step += 0x11;
169     if((codeflash_access_flag1 == CODEFLASH_SAFE_FLAG1)
170      &&(codeflash_access_flag2 == CODEFLASH_SAFE_FLAG2)
171      &&(op_step == 0x66))
172     {
173         if( addr < DATA_FLASH_ADDR  )    R8_FLASH_PROTECT = RB_ROM_WE_MUST_10|RB_ROM_CODE_WE;   // Codefalsh区
174         else       R8_FLASH_PROTECT = RB_ROM_WE_MUST_10|RB_ROM_DATA_WE;         // datafalsh区
175     }
176 
177     op_step += 0x11;
178     /* 判断OTA操作Flash的保护状态标志 */
179     if((codeflash_access_flag1==CODEFLASH_SAFE_FLAG1)
180      &&(codeflash_access_flag2==CODEFLASH_SAFE_FLAG2)
181      &&(op_step == 0x77))
182     {
183         R32_FLASH_ADDR = add;
184         R32_FLASH_DATA = val;
185         R8_FLASH_COMMAND = ROM_CMD_PROG;
186         status = (unsigned char)(R16_FLASH_STATUS & 0xff);
187     }
188 
189     op_step = 0x00;
190     codeflash_access_flag1 = 0x00;
191     codeflash_access_flag2 = 0x00;
192     R8_FLASH_PROTECT = RB_ROM_WE_MUST_10;
193     if( status != RB_ROM_ADDR_OK )  return 3;  //操作失败
194 
195     return 0;
196 
197 }
198 
199 /*******************************************************************************
200 * Function Name  : FlashWriteBuf
201 * Description    : Flash 连续多个双字写入
202 * Input          : addr: 32位地址,需要4对齐
203 *                       codeflash:  startAddr - 0x00000000    size - 0x3E800
204 *                       dataflash:  startAddr - 0x3E800(DATA_FLASH_ADDR)       size -  0x0800(DATA_FLASH_SIZE)
205 *                  pdat: 待写入数据缓存区首地址
206 *                   len: 待写入数据字节长度
207 * Return         : 0 - 成功,其他  - 错误
208 *******************************************************************************/
FlashWriteBuf(UINT32 addr,PUINT32 pdat,UINT16 len)209 UINT8 FlashWriteBuf(UINT32 addr, PUINT32 pdat, UINT16 len)
210 {
211     UINT32  add = addr;
212     PUINT32 p32 = pdat;
213     UINT8  status = 0;
214     UINT16  i;
215     volatile UINT8  op_step;
216 
217     if( addr & (4-1) )              return 1; //地址不对齐
218 
219     op_step = 0x11;
220     codeflash_access_flag1 = 0;
221     codeflash_access_flag2 = 0;
222     R8_FLASH_PROTECT = RB_ROM_WE_MUST_10;
223 
224     //开启电压监控中断
225     op_step += 0x11;
226     if((R8_BAT_DET_CTRL & 0x0F) != 0x0D)        PowerMonitor( ENABLE );
227 
228     op_step += 0x11;
229     if((R8_BAT_STATUS & 0x03) != 0x00)      return 2;  //电源电压偏低,Flash不允许操作
230 
231     op_step += 0x11;
232     if(((R8_BAT_STATUS & 0x01) == 0x00)
233         &&(op_step == 0x44))
234     {
235         codeflash_access_flag1 = CODEFLASH_SAFE_FLAG1;
236     }
237 
238     op_step += 0x11;
239     if(((R8_BAT_STATUS & 0x01) == 0x00)
240         &&(op_step == 0x55)
241         &&(codeflash_access_flag1 == CODEFLASH_SAFE_FLAG1))
242     {
243         codeflash_access_flag2 = CODEFLASH_SAFE_FLAG2;
244     }
245 
246     op_step += 0x11;
247     if((codeflash_access_flag1 == CODEFLASH_SAFE_FLAG1)
248      &&(codeflash_access_flag2 == CODEFLASH_SAFE_FLAG2)
249      &&(op_step == 0x66))
250     {
251         if( addr < DATA_FLASH_ADDR  )    R8_FLASH_PROTECT = RB_ROM_WE_MUST_10|RB_ROM_CODE_WE;   // Codefalsh区
252         else       R8_FLASH_PROTECT = RB_ROM_WE_MUST_10|RB_ROM_DATA_WE;         // datafalsh区
253     }
254 
255     op_step += 0x11;
256     /* 判断OTA操作Flash的保护状态标志 */
257     if((codeflash_access_flag1==CODEFLASH_SAFE_FLAG1)
258      &&(codeflash_access_flag2==CODEFLASH_SAFE_FLAG2)
259      &&(op_step == 0x77))
260     {
261         for(i=0; i<len; i+=4)
262         {
263             R32_FLASH_ADDR = add;
264             R32_FLASH_DATA = *p32++;
265             R8_FLASH_COMMAND = ROM_CMD_PROG;
266             add += 4;
267             //status = R8_FLASH_STATUS;
268             status = (unsigned char)(R16_FLASH_STATUS & 0xff);
269             if( status != RB_ROM_ADDR_OK )  break;
270         }
271     }
272 
273     op_step = 0x00;
274     codeflash_access_flag1 = 0x00;
275     codeflash_access_flag2 = 0x00;
276     R8_FLASH_PROTECT = RB_ROM_WE_MUST_10;
277     if( status != RB_ROM_ADDR_OK )  return 3;  //操作失败
278 
279     return 0;
280 }
281 
282 
283 
284