1 /*************************************************************************
2 *
3 * File name : FlashPrg.c
4 * Description :
5 *
6 * History :
7 * 1. Date : 9, 2018
8 * Author :
9 * Description :
10 *
11 * $Revision: 0 $
12 **************************************************************************/
13
14 /*
15 * ICP WRITER MODE COMMAND
16 * 1'b0, 1'b0,FOEN,FCEN,FCTRL[3:0]
17 */
18 #define ICPCMD_EntryMode 0x55AA03
19 #define ICPCMD_Standby 0x30
20 #define ICPCMD_ReadCompanyID 0x0B
21 #define ICPCMD_ReadDeviceID 0x0C
22 #define ICPCMD_FlashProgram 0x21
23 #define ICPCMD_FlashEraseVerify 0x09
24 #define ICPCMD_FlashProgramVerify 0x0A
25 #define ICPCMD_WholechipErase 0x26
26 #define ICPCMD_FlashRead 0x00
27
28 typedef struct{
29 INT32U Sectorsz; // Sector Size in Bytes
30 INT32U SectorAddr; // Address of Sector
31 } SPC_SECTORS_Type;
32
33 typedef struct{
34 INT16U RstLevel;
35 INT16U dlyEntryMode;
36 INT8U dlyTz;
37 INT8U dlyTrd;
38 INT8U dlyTprog;
39 INT8U dlyTme;
40 INT8U dlyTeph;
41 }DLY_Type;
42
43 // special sectors
44 static SPC_SECTORS_Type tSpcSectors[] = {
45 [Bidx_NUC126_128K_4K_2K_8B] = { .Sectorsz = 0x8, .SectorAddr = 0x300000,},
46 [Bidx_NUC126_256K_4K_2K_8B] = { .Sectorsz = 0x8, .SectorAddr = 0x300000,},
47 [Bidx_NUC400_256k_16K_16B] = { .Sectorsz = 0x10, .SectorAddr = 0x300000,},
48 [Bidx_NUC400_512k_16K_16B] = { .Sectorsz = 0x10, .SectorAddr = 0x300000,},
49
50 [Bidx_M451_040k_4K_8B] = { .Sectorsz = 0x8, .SectorAddr = 0x300000,},
51 [Bidx_M451_072k_4K_8B] = { .Sectorsz = 0x8, .SectorAddr = 0x300000,},
52 [Bidx_M451_128k_4K_8B] = { .Sectorsz = 0x8, .SectorAddr = 0x300000,},
53 [Bidx_M451_256k_4K_8B] = { .Sectorsz = 0x8, .SectorAddr = 0x300000,},
54 };
55
56 #define SpcSectorAddr tSpcSectors[M_BlkIndex].SectorAddr
57 #define SpcSectorSize tSpcSectors[M_BlkIndex].Sectorsz
58
59 // ICP Timing Parameters Table
60 static DLY_Type tDlys[] = {
61 [Bidx_NUC126_128K_4K_2K_8B] = {.RstLevel = 0xffff, .dlyEntryMode = 500, .dlyTz = 1, .dlyTrd = 1, .dlyTprog = 100, .dlyTme = 80, .dlyTeph = 5,},
62 [Bidx_NUC126_256K_4K_2K_8B] = {.RstLevel = 0xffff, .dlyEntryMode = 500, .dlyTz = 1, .dlyTrd = 1, .dlyTprog = 100, .dlyTme = 80, .dlyTeph = 5,},
63
64 [Bidx_NUC400_256k_16K_16B] = {.RstLevel = 0x0000, .dlyEntryMode = 100, .dlyTz = 1, .dlyTrd = 1, .dlyTprog = 40, .dlyTme = 60, .dlyTeph = 5,},
65 [Bidx_NUC400_512k_16K_16B] = { .RstLevel = 0x0000, .dlyEntryMode = 100,.dlyTz = 1, .dlyTrd = 1, .dlyTprog = 40, .dlyTme = 60, .dlyTeph = 5,},
66
67 [Bidx_M451_040k_4K_8B] = {.RstLevel = 0xffff, .dlyEntryMode = 500, .dlyTz = 1, .dlyTrd = 1, .dlyTprog = 60, .dlyTme = 90, .dlyTeph = 5,},
68 [Bidx_M451_072k_4K_8B] = {.RstLevel = 0xffff, .dlyEntryMode = 500, .dlyTz = 1, .dlyTrd = 1, .dlyTprog = 60, .dlyTme = 90, .dlyTeph = 5,},
69 [Bidx_M451_128k_4K_8B] = {.RstLevel = 0xffff, .dlyEntryMode = 500, .dlyTz = 1, .dlyTrd = 1, .dlyTprog = 60, .dlyTme = 90, .dlyTeph = 5,},
70 [Bidx_M451_256k_4K_8B] = {.RstLevel = 0xffff, .dlyEntryMode = 500, .dlyTz = 1, .dlyTrd = 1, .dlyTprog = 60, .dlyTme = 90, .dlyTeph = 5,},
71 };
72
73 #define RL tDlys[M_BlkIndex].RstLevel
74 #define EM tDlys[M_BlkIndex].dlyEntryMode
75 #define Tz tDlys[M_BlkIndex].dlyTz
76 #define Trd tDlys[M_BlkIndex].dlyTrd
77 #define Tprog tDlys[M_BlkIndex].dlyTprog
78 #define Tme tDlys[M_BlkIndex].dlyTme
79 #define Teph tDlys[M_BlkIndex].dlyTeph
80
81
82 void EntryMode(void)
83 {
84 INT32U code = ICPCMD_EntryMode;
85 INT8U i;
86
87 make_lock();
88
89 ICETDA_DPORT(IODecVaddr) = 0xFFFF;
90
91 RESET_DPORT(IODecVaddr) = RL;
92 delay_x1us(EM);
93
94 /* 50 clocks */
95 for(i=0; i<50; i++)
96 {
97 ICETCK_DPORT(IODecVaddr) = 0xFFFF;
98 delay_x1us(1);
99
100 ICETCK_DPORT(IODecVaddr) = 0x0000;
101 delay_x1us(1);
102 }
103
104 /* ICP Mode Entry Code */
105 for(i=0; i<24; i++)
106 {
107 ICETDA_DPORT(IODecVaddr)=(code&0x800000)? 0xFFFF:0x0000;
108 delay_x1us(1);
109
110 ICETCK_DPORT(IODecVaddr) = 0xFFFF;
111 delay_x1us(1);
112
113 ICETCK_DPORT(IODecVaddr) = 0x0000;
114 delay_x1us(1);
115
116 code=code<<1;
117 }
118
119 /* ICP Mode clean reset,icpda,icpck statues */
120 ICETDA_DPORT(IODecVaddr) = 0x0000;
121 ICETCK_DPORT(IODecVaddr) = 0x0000;
122 delay_x1us(50);
123
124 make_unlock();
125 }
126
127 void SendHead(INT32U dev_addr, INT8U cmd)
128 {
129 INT32U i, head = 0;
130
131 head|=((dev_addr<<8)|cmd);
132
133 for(i=0; i<32; i++)
134 {
135 ICETDA_DPORT(IODecVaddr)=(head&0x80000000)? 0xFFFF:0x0000;
136
137 ICETCK_DPORT(IODecVaddr) = 0xFFFF;
138 ICETCK_DPORT(IODecVaddr) = 0x0000;
139
140 head=head<<1;
141 }
142 ICETDA_DPORT(IODecVaddr) = 0x0000;
143 }
144
145 void ICPRead(INT32U dev_addr,INT32U dev_size, INT8U cmd, INT32U *buf)
146 {
147 INT32U i,j;
148 INT8U tmp;
149
150 SendHead(dev_addr,cmd);
151
152 for(i=0; i<dev_size; i++)
153 {
154 ICETDA_ZPORT(IODecVaddr) = 0xFFFF;
155
156 ICETCK_DPORT(IODecVaddr) = 0xFFFF;//Tri-State
157 ICETCK_DPORT(IODecVaddr) = 0x0000;
158 delay_x1us(Tz);
159
160 for(j=0; j<32; j++) //(Read 32 bits from ICE_DAT pin)
161 {
162 ICETCK_DPORT(IODecVaddr) = 0xFFFF;
163
164 tmp = ICETDA_ZPORT(IODecVaddr);
165
166 ICETCK_DPORT(IODecVaddr) = 0x0000;
167
168 buf[i] = (tmp&0x01)|(buf[i]<<1);
169 }
170
171 ICETCK_DPORT(IODecVaddr) = 0xFFFF;//Tri-State
172 ICETCK_DPORT(IODecVaddr) = 0x0000;
173 delay_x1us(Tz);
174
175 ICETDA_DPORT(IODecVaddr) = (i == dev_size-1)?0xFFFF:0x0000; //NCONT
176 delay_x1us(Trd);
177
178 ICETCK_DPORT(IODecVaddr) = 0xFFFF;
179 ICETCK_DPORT(IODecVaddr) = 0x0000;
180 delay_x1us(1);
181
182 }
183 ICETDA_DPORT(IODecVaddr) = 0x0000;
184 }
185
186 void ICPWrite(INT32U dev_addr,INT32U dev_size, INT8U cmd, INT32U *buf)
187 {
188 INT32U i,j;
189
190 SendHead(dev_addr,cmd);
191
192 for(i=0; i<dev_size; i++)
193 {
194 ICETCK_DPORT(IODecVaddr) = 0xFFFF;//Tri-State
195 ICETCK_DPORT(IODecVaddr) = 0x0000;
196 delay_x1us(Tz);
197
198 for(j=0; j<32; j++) //(Write 32 bits to ICE_DAT pin)
199 {
200 ICETDA_DPORT(IODecVaddr) = (buf[i] & (0x80000000>>j))?0xFFFF:0x0000;
201
202 ICETCK_DPORT(IODecVaddr) = 0xFFFF;
203 ICETCK_DPORT(IODecVaddr) = 0x0000;
204 }
205 ICETCK_DPORT(IODecVaddr) = 0xFFFF;//Tri-State
206 ICETCK_DPORT(IODecVaddr) = 0x0000;
207 delay_x1us(Tz);
208
209 ICETDA_DPORT(IODecVaddr) = (i == dev_size-1)?0xFFFF:0x0000; //NCONT
210 delay_x1us(Tprog);
211
212 ICETCK_DPORT(IODecVaddr) = 0xFFFF;
213 ICETCK_DPORT(IODecVaddr) = 0x0000;
214 delay_x1us(Teph);
215
216 }
217 ICETDA_DPORT(IODecVaddr) = 0x0000;
218 }
219
220 void ICPErase(INT32U dev_addr,INT32U dev_size, INT8U cmd, INT32U *buf)
221 {
222 INT32U i,j;
223
224 SendHead(dev_addr,cmd);
225
226 for(i=0; i<dev_size; i++)
227 {
228 ICETCK_DPORT(IODecVaddr) = 0xFFFF;//Tri-State
229 ICETCK_DPORT(IODecVaddr) = 0x0000;
230 delay_x1us(Tz);
231
232 for(j=0; j<32; j++) //(Write 32 bits to ICE_DAT pin)
233 {
234 ICETDA_DPORT(IODecVaddr) = (buf[i] & (0x80000000>>j))?0xFFFF:0x0000;
235
236 ICETCK_DPORT(IODecVaddr) = 0xFFFF;
237 ICETCK_DPORT(IODecVaddr) = 0x0000;
238 }
239 ICETCK_DPORT(IODecVaddr) = 0xFFFF;//Tri-State
240 ICETCK_DPORT(IODecVaddr) = 0x0000;
241 delay_x1us(Tz);
242
243 ICETDA_DPORT(IODecVaddr) = (i == dev_size-1)?0xFFFF:0x0000; //NCONT
244 delay_x1ms(Tme);
245
246 ICETCK_DPORT(IODecVaddr) = 0xFFFF;
247 ICETCK_DPORT(IODecVaddr) = 0x0000;
248 delay_x1us(Teph);
249
250 }
251
252 ICETDA_DPORT(IODecVaddr) = 0x0000;
253 }