AlcapDAQ  1
p30.c
Go to the documentation of this file.
1 #include "p30.h"
2 #include "a3818.h"
3 #include "CAENVMElib.h"
4 
5 /*******************************************************************/
6 /* Funzioni per l'accesso alla FLASH BPI */
7 /*******************************************************************/
8 
9 /*-------------------------------------------------------------*/
10 /* offset deve essere allineato a 16 bit (BIT0 non significativo) */
11 int bpi_flash_read(int32_t dev, uint32_t offset, uint32_t* bpi_data) {
12  uint32_t app_data;
13 
14  //Imposto indirizzo
15  app_data = offset << 1;
16  CAENVME_WriteRegister(dev, A3818_BPI_FLASH_AD | 0x1000, app_data);
17 
18  //Abbasso il CE
19  CAENVME_WriteRegister(dev, A3818_BPI_FLASH_CMD | 0x1000, 0x6);
20 
21  //Abbasso OE
22  CAENVME_WriteRegister(dev, A3818_BPI_FLASH_CMD | 0x1000, 0x2);
23 
24  //Rialzo OE
25  CAENVME_WriteRegister(dev, A3818_BPI_FLASH_CMD | 0x1000, 0x6);
26 
27  //Alzo CE
28  CAENVME_WriteRegister(dev, A3818_BPI_FLASH_CMD | 0x1000, 0x7);
29 
30  //Sono significativi, per la lettura, solo i 16 bit bassi
31  CAENVME_ReadRegister(dev, A3818_BPI_FLASH_DT | 0x1000, &app_data);
32  *bpi_data = app_data & 0x0000FFFF;
33 
34  return 0;
35 }
36 
37 /*-------------------------------------------------------------*/
38 int bpi_flash_write(int32_t dev, uint32_t offset, uint32_t bpi_data) {
39  uint32_t data;
40 
41  //Imposto indirizzo
42  data = offset << 1;
43 
44  CAENVME_WriteRegister(dev, A3818_BPI_FLASH_AD | 0x1000, data);
45 
46  //Imposto il dato
47  //Per la scrittura i 16 bit da scrivere vanno messi nella parte alta del registro.
48  data = bpi_data << 16;
49  CAENVME_WriteRegister(dev, A3818_BPI_FLASH_DT | 0x1000, data);
50 
51  //Abbasso il CE
52  CAENVME_WriteRegister(dev, A3818_BPI_FLASH_CMD | 0x1000, 0x6);
53 
54  //Abbasso WE
55  CAENVME_WriteRegister(dev, A3818_BPI_FLASH_CMD | 0x1000, 0x4);
56 
57  //Rialzo WE
58  CAENVME_WriteRegister(dev, A3818_BPI_FLASH_CMD | 0x1000, 0x6);
59 
60  //Alzo CE
61  CAENVME_WriteRegister(dev, A3818_BPI_FLASH_CMD | 0x1000, 0x7);
62 
63  return 0;
64 }
65 
66 // abilito la BPI flash
68  uint32_t data;
69  CAENVME_ReadRegister(handle, A3818_DMISCCS | 0x1000, &data);
70  data = data | A3818_DMISCCS_SPI_BPI_FLASH_SEL;
71  CAENVME_WriteRegister(handle, A3818_DMISCCS | 0x1000, data);
72 }
73 
74 // Disabilita l'accesso alla BPI flash.
75 // L'a3818 può accedere alla sola flash SPI.
77  uint32_t data;
78  CAENVME_ReadRegister(handle, A3818_DMISCCS | 0x1000, &data);
79  data = data & (~A3818_DMISCCS_SPI_BPI_FLASH_SEL);
80  CAENVME_WriteRegister(handle, A3818_DMISCCS | 0x1000, data);
81 }
82 
83 /****************************************************************************/
84 
85 // Lettura registro di stato e controllo che la flash sia ready
86 static uint32_t readFlashStatus(int32_t dev) {
87 
88  uint32_t stat;
90  bpi_flash_read(dev, 0x0, &stat);
91 
92  return stat;
93 
94 }
95 
96 /****************************************************************************
97  *
98  * waitUntilReady
99  *
100  * Description:
101  *
102  * This procedure is called to wait until the flash device status
103  * indicates a ready state or times out. See the flash device datasheet
104  * for specific details on reading status data.
105  *
106  * Parameters:
107  *
108  * IN timeout - timeout value specified as number of times
109  * to read the status register before giving up.
110  *
111  * Returns:
112  *
113  * uint8_t - boolean flag indicating whether the ready state was
114  * reached before the timeout number of reads
115  * occured.
116  *
117  * Assumptions:
118  *
119  * NONE.
120  *
121  ***************************************************************************/
122 static uint8_t waitUntilReady(int32_t dev, uint32_t timeout) {
123 
124  while (timeout) {
125 
126  if (mIsStatusReady( readFlashStatus(dev) )) {
127  return (TRUE);
128  }
129  timeout--;
130  }
131 
132  return (FALSE);
133 
134 }
135 
136 static int eraseBlock(int32_t dev, uint32_t blockAddress) {
137 
138  uint32_t status;
139 
140  waitUntilReady(dev, 0xFFFFFFFF);
141 
142  // Unlock Command
143  bpi_flash_write(dev, blockAddress, P30_BLOCK_LOCK_SETUP);
144  bpi_flash_write(dev, blockAddress, P30_BLOCK_UNLOCK);
145 
146  //Erase
147  bpi_flash_write(dev, blockAddress, P30_BLOCK_ERASE_SETUP);
148  bpi_flash_write(dev, blockAddress, P30_BLOCK_ERASE_CONFIRM);
149 
150  // Attesa ready della flash
151  waitUntilReady(dev, 0xFFFFFFFF);
152 
153  status = readFlashStatus(dev);
155 
156  // Imposto Read Array Mode
157  bpi_flash_write(dev, 0x0, P30_READ_ARRAY);
158 
159  return status;
160 }
161 
162 /****************************************************************************
163  *
164  * writeFlashPage
165  *
166  * Description:
167  *
168  * Funzioni per la scrittura/lettura di pagine della flash StrataFlash Numonix P30
169  * montata sulla A3818.
170  * Riferimento: Buffer Program Flowchart (fig. 36) da datasheet
171  * Numonyx Strataflash Embedded memory P30 (306666-12 - Agosto 2008).
172  *
173  * Parameters:
174  *
175  * IN dev - A3818 driver handle
176  *
177  * IN data - the buffer containing data to be programmed.
178  *
179  * IN wordAddress - the flash address to be programmed.
180  *
181  * IN numwords - the number of words (ie two bytes) of data contained in the buffer.
182  * This is a X16 write buffer routine and the part expects a count in # of words
183  *
184  * Returns:
185  *
186  * int TBD
187  *
188  * Assumptions:
189  *
190  * NONE
191  *
192  ***************************************************************************/
193 static int writeFlashPage(int32_t dev, uint32_t *data, int wordAddress,
194  int numWords) {
195  int i;
196 
197  // La modalit� di scrittura con buffer ha un massimo di 32 word a 16 bit
198  // che possono essere scritte.
199  if (numWords > 32)
200  return -1;
201 
202  // Imposto Read Array Mode
203  bpi_flash_write(dev, 0x0, P30_READ_ARRAY);
204 
205  // Status check
206  waitUntilReady(dev, 0xFFFFFFFF);
207 
208  bpi_flash_write(dev, wordAddress, P30_BUFFERED_PROGRAM);
209  bpi_flash_write(dev, wordAddress, numWords - 1); // N=16 words da scrivere (bisogna scrivere N-1)
210 
211  for (i = wordAddress; i < (wordAddress + numWords); ++i) {
212  bpi_flash_write(dev, i, data[i - wordAddress]);
213  }
214 
216 
217  // Status check
218  waitUntilReady(dev, 0xFFFFFFFF);
219 
220  // Imposto Read Array Mode
221  bpi_flash_write(dev, 0x0, P30_READ_ARRAY);
222 
223  return 0;
224 }
225 
226 int readFlash(int32_t dev, uint32_t *data, int address, int length) {
227  int flash_addr;
228  int i;
229 
230  // Imposto Read Array Mode
231  bpi_flash_write(dev, 0x0, P30_READ_ARRAY);
232 
233  flash_addr = address;
234  for (i = 0; i < length; i++) {
235  bpi_flash_read(dev, flash_addr + i, &data[i]);
236  }
237 
238  return 0;
239 }
240 
241 unsigned int verifyFlash(uint32_t handle, uint32_t *buffer,
242  uint32_t bufferLength, uint32_t startWordAddress) {
243  int finish, i;
244  unsigned int verify_err;
245  int bp, wc, pp;
246  uint32_t bpi_rd[32]; // 16-bit word read from flash
247 
248  wc = 0; // byte counter
249 
250 
251  bp = 0; // byte pointer in the page
252  finish = 0; // it goes high when eof is found
253  verify_err = 0; // number of errors during verify
254 
255  pp = 0;
256 
257  while (wc < bufferLength) {
258 
259 #ifdef PRINT_POINTS
260  if (((wc % (32 * 1024)) == 0) || finish) {
261  printf(".");
262  fflush(stdout);
263  }
264 #endif
265  readFlash(handle, bpi_rd, (pp * 32) + startWordAddress, 32); // read page
266 
267  for (i = 0; i < 32; i++) { // verify page
268  if (bpi_rd[i] != buffer[wc + i]) {
269  printf("page = %d; bpi_rd[%d]=%04X, buffer[%d]=%04X \n", pp,
270  i, bpi_rd[i], wc + i, buffer[wc + i]);
271  printf("\n\n Writing or Verify error at page %d - %d\n", pp, i);
272  ++verify_err;
273  }
274  }
275  bp = 0;
276  pp++;
277  wc += 32;
278  } // end of while loop
279 
280 
281  return verify_err;
282 
283 }
284 
285 // L'immagine del firmware dell'A3818 � di circa 1716 KB
286 int eraseFirmware(uint32_t handle, uint32_t baseAddress, uint32_t fwcopy) {
287  int i;
288 
289  if (fwcopy == 0) {
290  // Cancella i primi 4 blocchi da 32KB = 128KB
291  for (i = 0; i < 4; i++) {
292  eraseBlock(handle, baseAddress + (i * (16 * 1024)));
293 #ifdef PRINT_POINTS
294 
295  printf(".");
296  fflush(stdout);
297 #endif
298  }
299  // Cancella 13 blocchi da 128KB
300  for (i = 4; i < 18; i++) {
301  eraseBlock(handle, baseAddress + ((i - 3) * (64 * 1024)));
302 #ifdef PRINT_POINTS
303  printf(".");
304  fflush(stdout);
305 #endif
306  }
307  } else {
308  // Cancella 15 blocchi da 128KB = cancella 15*128K = 1920KB
309  for (i = 0; i < 14; i++) {
310  eraseBlock(handle, baseAddress + (i * (64 * 1024)));
311 #ifdef PRINT_POINTS
312  printf(".");
313  fflush(stdout);
314 #endif
315  }
316  }
317 
318  // Ritorna in modalit� Read Array Mode
319  bpi_flash_write(handle, 0x0, P30_READ_ARRAY);
320  return 0;
321 }
322 
323 void writeFlash(uint32_t handle, uint32_t *buffer, uint32_t bufferLength,
324  uint32_t startWordAddress) {
325 
326  int wc, pp;
327 
328  wc = 0;
329  pp = 0;
330 
331 #ifdef PRINT_POINTS
332  printf(".");
333  fflush(stdout);
334 #endif
335  while (wc < bufferLength) {
336 #ifdef PRINT_POINTS
337  if (((wc % (32 * 1024)) == 0)) {
338  printf(".");
339  fflush(stdout);
340  }
341 #endif
342  writeFlashPage(handle, buffer + (pp * 32),
343  startWordAddress + (pp * 32), 32);
344 
345  pp++;
346  wc += 32;
347  } // end of while loop
348 
349 }