KM3NeT CLB  2.0
KM3NeT CLB v2 Embedded Software
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
sflash.c
1 /*
2  * KM3NeT CLB v2 Firmware
3  * ----------------------
4  *
5  * Copyright 2013 KM3NeT Collaboration
6  *
7  * All Rights Reserved.
8  *
9  *
10  * File : sflash.c
11  * Created : 29 jan. 2014
12  * Author : Vincent van Beveren
13  */
14 
15 #include "drv/spi/sflash.h"
16 
17 #include "cfg_board.h"
18 
19 #include <stdio.h>
20 #include <assert.h>
21 
22 #include "util/macro.h"
23 #include "util/func.h"
24 
25 #include "lm32soc/dev_soc.h"
26 #include "drv/wb/spi.h"
27 
28 #include "kernel/tm.h"
29 #include "kernel/err.h"
30 #include "errorcode.h"
31 
32 
33 // #define SIM_REG_WRITE
34 // #define DEBUG_REGS
35 // #define SHOW_WRITES_READS
36 
37 #ifdef SHOW_WRITES_READS
38 #include "dbg/show.h"
39 #endif
40 //
41 // This command set seems to be common among flash provider, but i don't seem to be able to
42 // find some central specification. JEDEC only provides the CFI, which does not specify commands.
43 //
44 
45 #define _SF_PP 0x02 // 3 byte page program
46 #define _SF_READ 0x03 // 3 byte address read
47 #define _SF_SE 0xD8 // 3 byte sector erase
48 
49 #define _SF_4READ 0x13 // 4 byte address read
50 #define _SF_4PP 0x12 // 4 byte address page program
51 #define _SF_4SE 0xDC // 4 byte sector erase
52 #define _SF_RDID 0x9F // Read identification
53 #define _SF_WRDI 0x04 // Write disable
54 #define _SF_WREN 0x06 // Write enable
55 #define _SF_RDSR 0x05 // Read status register
56 #define _SF_RDSR_BUSY 0x01 // Busy flag
57 #define _SF_RDSR_WEL 0x02 // Write enable latch.
58 
59 
60 // vendor specific commands
61 // Spanson
62 #define _SF_SP_CLSR 0x30 // Clear status register (clear error)
63 
64 #define _SF_SP_RDSR_E_PROG BIT(6)
65 #define _SF_SP_RDSR_E_ERASE BIT(5)
66 #define _SF_SP_RDSR_ERROR ( _SF_SP_RDSR_E_PROG | _SF_SP_RDSR_E_ERASE )
67 
68 #define _SF_SP_RDCR 0x35
69 #define _SF_SP_RDCR_QUAD 0x02
70 
71 #define _SF_SP_ASPRD 0x2B
72 #define _SF_SP_ASPP 0x2F
73 
74 #define _SF_SP_ASP_DEFAULT 0xFFFF
75 
76 #define _SF_SP_ASP_PWDMLB_ BIT(2)
77 #define _SF_SP_ASP_PSTMLB_ BIT(1)
78 
79 #define _SF_SP_PLBRD 0xA7
80 #define _SF_SP_PLBWR 0xA6
81 
82 #define _SF_SP_RESET 0xF0
83 
84 #define _SF_SP_PPBRD 0xE2
85 #define _SF_SP_PPBP 0xE3
86 #define _SF_SP_PPBE 0xE4
87 
88 #define _SF_SP_PASSRD 0xE7
89 #define _SF_SP_PASSP 0xE8
90 #define _SF_SP_PASSU 0xE9
91 
92 
93 #define _SF_SP_ABRD 0x14
94 
95 #define _SF_SP_WRR 0x01
96 
97 
98 // Micron
99 #define _SF_MI_RFLGR 0x70 // Read flags register
100 #define _SF_MI_CFLGR 0x50 // Clear status register (clear error)
101 #define _SF_MI_ENTER4 0xB7 // Enter 4 byte address mode
102 #define _SF_MI_RESET 0x66
103 
104 
105 #define _SF_RFLGR_E_PROT BIT(1)
106 #define _SF_RFLGR_E_VPP BIT(3)
107 #define _SF_RFLGR_E_PROGRAM BIT(4)
108 #define _SF_RFLGR_E_ERASE BIT(5)
109 #define _SF_RFLGS_ERROR ( _SF_RFLGR_E_PROT | _SF_RFLGR_E_VPP | _SF_RFLGR_E_PROGRAM | _SF_RFLGR_E_ERASE )
110 #define _SF_RFLGR_BUSY BIT(7)
111 
112 typedef struct
113 {
114  uint8_t mfId;
115  uint8_t devId;
116  uint8_t capacity;
117  uint8_t addrBytes;
118  uint8_t capability;
119 
120  uint8_t progCmd;
121  uint8_t readCmd;
122  uint8_t eraseCmd;
123  uint8_t resetCmd;
124 
125  uint8_t stsReg;
126  uint8_t stsRegErr;
127  uint8_t stsRegClr;
128 
129 
130  uint16_t pageSize;
131  uint16_t sectorSize; // in pages
132  uint16_t flashSize; // in sectors
133 
134 } SfDevDesc;
135 
136 // List of supported flash devices.
137 static const SfDevDesc devList[] = {
138  { SF_MF_SPANSION, SF_DEV_SPANSION_S25FL, 0x20,
140  _SF_4PP, _SF_4READ, _SF_4SE, _SF_SP_RESET,
141  _SF_RDSR, _SF_SP_RDSR_ERROR, _SF_SP_CLSR,
142  512, 512, 256
143  },
144  { SF_MF_MICRON, SF_DEV_MICRON_N25QA, 0x18,
145  3, 0,
146  _SF_PP, _SF_READ, _SF_SE, _SF_MI_RESET,
147  _SF_MI_RFLGR, _SF_RFLGS_ERROR, _SF_MI_CFLGR,
148  256, 256, 256
149  },
150  { SF_MF_MICRON, SF_DEV_MICRON_N25QA, 0x21,
151  3, 0,
152  _SF_PP, _SF_READ, _SF_SE, _SF_MI_RESET,
153  _SF_MI_RFLGR, _SF_RFLGS_ERROR, _SF_MI_CFLGR,
154  256, 256, 2048,
155  },
156 };
157 
158 #define _SF_DEV_COUNT ( sizeof(devList) / sizeof(SfDevDesc) )
159 
160 
162 
163 static const SfDevDesc * dev;
164 
165 static bool sfReadReg(uint8_t reg, uint8_t * result, int len) {
166  assert(len <= 8);
167  int i;
168  uint8_t dta[9];
169  dta[0] = reg;
170  spiSelect(FLASH_SPI_DEV, FLASH_SPI_CS);
171  if (!spiTxRx(FLASH_SPI_DEV, dta, dta, 1 + len)) goto fail;
172  spiDeselect(FLASH_SPI_DEV);
173  for (i = 0; i < len; ++i) {
174  result[i] = dta[1 + i];
175  }
176 
177 #ifdef DEBUG_REGS
178  if (reg != 05) {
179  printf("Reading reg %02x:", reg);
180  for (i = 0; i < len; ++i) {
181  printf(" %02x", result[i]);
182  }
183  puts("");
184  }
185 #endif
186 
187  return true;
188 fail:
189  spiDeselect(FLASH_SPI_DEV);
190 
191  return false;
192 }
193 
194 #ifdef SIM_REG_WRITE
195 static inline bool sfWriteReg(uint8_t reg, uint8_t * sequence, int len) {
196  assert(len <= 8);
197  int i;
198  printf("Writing reg %02x:", reg);
199  for (i = 0; i < len; ++i) {
200  printf(" %02x", sequence[i]);
201  }
202  puts("");
203  return true;
204 }
205 #else
206 static bool sfWriteReg(uint8_t reg, uint8_t * sequence, int len)
207 {
208  assert(len <= 8);
209  int i;
210 #ifdef DEBUG_REGS
211 
212 
213  printf("Writing reg %02x:", reg);
214  for (i = 0; i < len; ++i) {
215  printf(" %02x", sequence[i]);
216  }
217  puts("");
218 #endif
219  bool r;
220  uint8_t dta[9];
221  dta[0] = reg;
222  for (i = 0; i < len; ++i) dta[i + 1] = sequence[i];
223 
224  spiSelect(FLASH_SPI_DEV, FLASH_SPI_CS);
225  r = spiTxRx(FLASH_SPI_DEV, dta, NULL, 1 + len);
226  spiDeselect(FLASH_SPI_DEV);
227 
228  return r;
229 }
230 #endif
231 
232 
233 
234 static bool sfAllOk()
235 {
236  uint8_t result;
237  if (!sfReadReg(dev->stsReg, &result, 1)) return false;
238 
239  sfInfo._status = result;
240  // printf("Result : %02x\n", result);
241  if (result & dev->stsRegErr) {
242 
243  sfReset();
244  errClear();
245 
246  return errSet(ERROR(E_SF_WRITEERASE));
247  }
248 
249  return true;
250 }
251 
252 
253 static bool sfBusy()
254 {
255  uint8_t result;
256  if (!sfReadReg(_SF_RDSR, &result, 1)) return false;
257  return result & _SF_RDSR_BUSY;
258 }
259 
260 
261 
262 static inline bool sfPrepare()
263 {
264  uint32_t to = timeOutInit(3000);
265  while(sfBusy()) {
266  if (timeOut(to)) {
267  sfReset();
268  return errSet(ERROR(E_TIMEOUT));
269  }
270  }
271  return sfAllOk();
272 }
273 
274 
275 static void sfCmdAddr(uint8_t cmd, uint32_t address, uint8_t * cmdOut)
276 {
277  cmdOut[0] = cmd;
278  switch (dev->addrBytes) {
279  case 3:
280  cmdOut[1] = 0xff & ( address >> 16 );
281  cmdOut[2] = 0xff & ( address >> 8 );
282  cmdOut[3] = 0xff & ( address );
283  break;
284  case 4:
285  cmdOut[1] = 0xff & ( address >> 24 );
286  cmdOut[2] = 0xff & ( address >> 16 );
287  cmdOut[3] = 0xff & ( address >> 8 );
288  cmdOut[4] = 0xff & ( address );
289  break;
290  }
291 
292 }
293 
294 
295 
296 static bool sfSimpleCommand(uint8_t cmd) {
297  spiSelect(FLASH_SPI_DEV, FLASH_SPI_CS);
298  if (!spiTxRx(FLASH_SPI_DEV, &cmd, 0, 1)) goto fail;
299  spiDeselect(FLASH_SPI_DEV);
300  return true;
301 fail:
302  spiDeselect(FLASH_SPI_DEV);
303  return false;
304 }
305 
306 /*
307 static bool clrStatus() {
308  return sfSimpleCommand(dev->stsRegClr);
309 }
310 */
311 
312 
313 static inline bool sfWriteEnable()
314 {
315  return sfSimpleCommand(_SF_WREN);
316 }
317 
318 
319 
320 bool sfReset()
321 {
322  if (!sfSimpleCommand(dev->resetCmd)) return false;
323  timeDelay(1);
324  return true;
325 }
326 
327 
328 static bool sfReadInfo()
329 {
330  int i;
331 
332 
333  // spiTxRx(FLASH_SPI_DEV, 0, 0, 512); // send 512 clocks
334 
335  // sfSimpleCommand(0x66); // Micron reset
336  // generic reset procedure
337  sfSimpleCommand(_SF_SP_RESET); // Spansion reset
338  timeDelay(1);
339 
340 /* sfSimpleCommand(0x66); // Micron reset
341  timeDelay(1);
342  sfSimpleCommand(0x99);
343  timeDelay(1);*/
344 
345  // for now we're just interested in the first 4 bytes
346  uint8_t rpl[4];
347  uint8_t cmd[4] = { _SF_RDID, 0, 0, 0 };
348 
349  spiSelect(FLASH_SPI_DEV, FLASH_SPI_CS);
350  if (!spiTxRx(FLASH_SPI_DEV, cmd, rpl, sizeof(cmd))) goto fail;
351  spiDeselect(FLASH_SPI_DEV);
352 
353  sfInfo.mfId = rpl[1];
354  sfInfo.devId = rpl[2];
355  sfInfo.devCap = rpl[3];
356 
357 
358  dev = NULL;
359  for (i = 0; i < _SF_DEV_COUNT; ++i) {
360 
361  if (sfInfo.mfId == devList[i].mfId && sfInfo.devId == devList[i].devId && \
362  devList[i].capacity == sfInfo.devCap) {
363  dev = &devList[i];
364  break;
365  }
366  }
367 
368 
369  if (dev == NULL) {
370  sfInfo.pageSize = 0;
371  sfInfo.flashSize = 0;
372  sfInfo.sectorSize = 0;
373  return errSet(ERROR(E_SF_DEVNOTFOUND));
374  }
375 
376 
377  sfInfo.pageSize = dev->pageSize;
378  sfInfo.sectorSize = dev->pageSize * dev->sectorSize;
379  sfInfo.flashSize = dev->pageSize * dev->sectorSize * dev->flashSize;
380 
381  sfInfo.cap = dev->capability;
382 
383  if (sfInfo.mfId == SF_MF_MICRON && dev->addrBytes == 4) {
384  // exception 1: Micron flash >128Mb devices need to be brought into 4 byte address mode
385  uint8_t data[2];
386 
387  puts("Entering 4 byte mode");
388 
389  if (!sfReadReg(0xB5, data, 2)) goto fail;
390 
391  printf("Before: %02x %02x\n", data[0], data[1]);
392 
393  if (!sfSimpleCommand(_SF_WREN)) goto fail;
394  if (!sfSimpleCommand(_SF_MI_ENTER4)) goto fail;
395 
396 
397 
398  if (!sfReadReg(0xB5, data, 2)) goto fail;
399 
400  printf("After: %02x %02x\n", data[0], data[1]);
401  }
402 
403 
404  if (sfInfo.cap & SF_INFO_CAP_PASSWORD) {
405  b16_t v;
406  if (!sfReadReg(_SF_SP_ASPRD, v.bytes, 2)) return false;
407  v.uint = LE2NS(v.uint);
408  if ((v.uint & _SF_SP_ASP_PWDMLB_) == 0) {
409  // for now we assume its also locked
411  }
412 
413  uint8_t tmp = 0xFF;
414  if (!sfReadReg(0xA7, &tmp, 1)) return false;
415  if (tmp == 0) {
416  sfInfo.sts |= SF_INFO_STS_LOCKED;
417  }
418 
419 
420  // printf("lock bit: %02x\n", tmp);
421 
422  }
423 
424  return true;
425 
426 fail:
427 
428  spiDeselect(FLASH_SPI_DEV);
429 
430  // reset flash?
431  return false;
432 
433 }
434 
435 bool sfInit()
436 {
437  return sfReadInfo();
438 }
439 
440 
441 
442 bool sfQuadEnable(bool enable)
443 {
444  // currently only spansion devices are supported.
445  if (sfInfo.mfId != SF_MF_SPANSION) return errSet(ERROR(E_NOTSUPPORTED));
446 
447 
448  if (!sfPrepare()) return false;
449 
450  uint8_t cr;
451  if (!sfReadReg(_SF_SP_RDCR, &cr, 1)) goto fail;
452 
453  // check if it is not already enabled.
454  if ((cr & _SF_SP_RDCR_QUAD) == ( enable ? _SF_SP_RDCR_QUAD : 0 ) ) return true;
455 
456  uint8_t cmd[3];
457  // write enable
458  cmd[0] = _SF_WREN;
459  spiSelect(FLASH_SPI_DEV, FLASH_SPI_CS);
460  if (!spiTxRx(FLASH_SPI_DEV, cmd, 0, 1)) goto fail;
461  spiDeselect(FLASH_SPI_DEV);
462 
463  spiSelect(FLASH_SPI_DEV, FLASH_SPI_CS);
464  cmd[0] = _SF_SP_WRR;
465  cmd[1] = 0x00;
466  cmd[2] = enable? _SF_SP_RDCR_QUAD : 0;
467  if (!spiTxRx(FLASH_SPI_DEV, cmd, 0, 3)) goto fail;
468  spiDeselect(FLASH_SPI_DEV);
469 
470  return true;
471 
472 fail:
473 
474  spiDeselect(FLASH_SPI_DEV);
475 
476  return false;
477 
478 }
479 
480 #ifdef SHOW_WRITES_READS
481 void sfDbgShow(const char * op, uint32_t address, uint8_t * data, uint32_t len)
482 {
483  char title[20];
484  memset(title, 0, sizeof(title));
485  sprintf(title, "sf%s @ %08x", op, address);
486  showHex8(title, data, len);
487 }
488 #endif
489 
490 
491 bool sfRead(uint32_t address, uint8_t * data, uint32_t count)
492 {
493  if (!sfPrepare()) return false;
494 
495  uint8_t cmd[5];
496  sfCmdAddr(dev->readCmd, address, cmd);
497 
498  spiSelect(FLASH_SPI_DEV, FLASH_SPI_CS);
499  if (!spiTxRx(FLASH_SPI_DEV, cmd, 0, dev->addrBytes + 1)) goto fail;
500  if (!spiTxRx(FLASH_SPI_DEV, 0, data, count)) goto fail;
501  spiDeselect(FLASH_SPI_DEV);
502 
503 #ifdef SHOW_WRITES_READS
504  sfDbgShow("Read", address, data, count);
505 #endif
506  return true;
507 
508 fail:
509 
510  spiDeselect(FLASH_SPI_DEV);
511 
512  // reset flash?
513  return false;
514 }
515 
516 
517 
518 
519 bool sfProg(uint32_t address, uint8_t * data, uint32_t count)
520 {
521  if (!sfPrepare()) return false;
522  if (!sfWriteEnable()) return false;
523 
524 #ifdef SHOW_WRITES_READS
525  sfDbgShow("Prog", address, data, count);
526 #endif
527 
528 
529  uint8_t cmd[5];
530 
531  sfCmdAddr(dev->progCmd, address, cmd);
532 
533  spiSelect(FLASH_SPI_DEV, FLASH_SPI_CS);
534  if (!spiTxRx(FLASH_SPI_DEV, cmd, 0, dev->addrBytes + 1)) goto fail;
535  if (!spiTxRx(FLASH_SPI_DEV, data, 0, count)) goto fail;
536  spiDeselect(FLASH_SPI_DEV);
537  return sfAllOk();
538 
539 fail:
540 
541  spiDeselect(FLASH_SPI_DEV);
542 
543  // reset flash?
544  return false;
545 }
546 
547 bool sfProgXPage(uint32_t address, uint8_t * data, uint32_t count)
548 {
549  uint32_t free = sfInfo.pageSize - ( address % sfInfo.pageSize );
550 
551  while (count > 0) {
552  int bytes = count > free ? free : count;
553  if (!sfProg(address, data, bytes)) {
554  return false;
555  }
556  data += bytes;
557  address += bytes;
558  count -= bytes;
559  free = sfInfo.pageSize; // next page we have the full page
560  }
561  return true;
562 }
563 
564 bool sfErase(uint32_t address)
565 {
566  if (!sfPrepare()) return false;
567 
568  if (!sfWriteEnable()) return false;
569 
570  uint8_t cmd[6];
571  sfCmdAddr(dev->eraseCmd, address, cmd);
572  spiSelect(FLASH_SPI_DEV, FLASH_SPI_CS);
573  if (!spiTxRx(FLASH_SPI_DEV, cmd, 0, dev->addrBytes + 1)) goto fail;
574  spiDeselect(FLASH_SPI_DEV);
575 
576 
577 
578  return sfAllOk();
579 
580 fail:
581  spiDeselect(FLASH_SPI_DEV);
582  // reset flash?
583  return false;
584 }
585 
586 
587 
588 
589 bool sfSetPasswordOTP(SfPassword * password)
590 {
591  SfPassword verify;
592 
593  if (!(sfInfo.cap & SF_INFO_CAP_PASSWORD)) return errSet(ERROR(E_NOTSUPPORTED));
594 
595  if (sfInfo.sts & SF_INFO_STS_PASSWORD_PROTECT) return errSet(ERROR(E_INVSTATE));
596 
597  // 1. program the password
598  if (!sfPrepare()) return false;
599  if (!sfWriteEnable()) return false;
600 
601  if (!sfWriteReg(_SF_SP_PASSP, &((*password)[0]), sizeof(SfPassword))) {
602  puts("Could not write password");
603  errPrint(true);
604  }
605 
606  if (!sfPrepare()) return false;
607  if (!sfReadReg(_SF_SP_PASSRD, &( verify[0]), sizeof(SfPassword))) return false;
608 
609  if (memcmp(&(verify[0]), &((*password)[0]), sizeof(SfPassword)) != 0)
610  return errSet(ERROR(E_UNKNOWN));
611 
612 
613  // 2. Activate the locking
614  if (!sfPrepare()) return false;
615  if (!sfWriteEnable()) return false;
616 
617  b16_t asp = { .uint = 0xFFFF }; // init all 1's
618  asp.uint ^= _SF_SP_ASP_PWDMLB_; // flip password protect bit
619  asp.uint = N2LES(asp.uint); // convert to little endian
620  if (!sfWriteReg(_SF_SP_ASPP, asp.bytes, sizeof(asp))) return false;
621 
622  // mark flags with locking.*/
624  return sfAllOk();
625 }
626 
627 void sfSpDiag() {
628 
629  b16_t b16;
630  uint8_t u8;
631 
632  sfReadReg(_SF_RDSR, &u8, sizeof(u8));
633  printf("SR1 : %02x\n", u8);
634  sfReadReg(_SF_SP_RDCR, &u8, sizeof(u8));
635  printf("CR1 : %02x\n", u8);
636  sfReadReg(_SF_SP_ASPRD, b16.bytes, sizeof(b16));
637  b16.uint = LE2NS(b16.uint);
638  printf("ASP : %04x\n", b16.uint);
639  sfReadReg(_SF_SP_PLBRD, &u8, sizeof(u8));
640  printf("PPBL: %02x\n", u8);
641 
642 }
643 
644 
645 bool sfLockUnlock(SfPassword * password)
646 {
647  if (!(sfInfo.cap & SF_INFO_CAP_PASSWORD)) return errSet(ERROR(E_NOTSUPPORTED));
648 
649 
650  if (password == NULL) {
651  if (!sfWriteEnable()) return false;
652  if (!sfSimpleCommand(_SF_SP_PLBWR)) return false;
653  sfInfo.sts |= SF_INFO_STS_LOCKED;
654  return true;
655  }
656 
657  // write password register
658  if (!sfWriteReg(_SF_SP_PASSU, &((*password)[0]), sizeof(SfPassword))) return false;
659 
660  // check if password was OK, simply by checking the time-out
661  if (!sfPrepare())
662  {
663  errClear(); // clear error
664  // else its an error!
665  return errSet(ERROR(E_SF_PASSWORD)); // else, return false
666  }
667  sfInfo.sts &= ~SF_INFO_STS_LOCKED;
668  return true;
669 }
670 
671 
672 bool sfProtect(uint32_t address)
673 {
674  if (!(sfInfo.cap & SF_INFO_CAP_SECTOR_PROTECT)) return errSet(ERROR(E_NOTSUPPORTED));
675 
676  if (!sfPrepare()) return false;
677 
678  if (!sfWriteEnable()) return false;
679 
680  uint8_t cmd[5];
681  bool r;
682  sfCmdAddr(_SF_SP_PPBP, address, cmd);
683  spiSelect(FLASH_SPI_DEV, FLASH_SPI_CS);
684  r = spiTxRx(FLASH_SPI_DEV, cmd, 0, dev->addrBytes + 1);
685  spiDeselect(FLASH_SPI_DEV);
686 
687  return r;
688 }
689 
690 bool sfUnProtect() {
691  if (!(sfInfo.cap & SF_INFO_CAP_SECTOR_PROTECT)) return errSet(ERROR(E_NOTSUPPORTED));
692 
693  if (!sfPrepare()) return false;
694 
695  if (!sfWriteEnable()) return false;
696 
697  return sfSimpleCommand(_SF_SP_PPBE);
698 }
bool sfQuadEnable(bool enable)
Quad enable,.
Definition: sflash.c:442
bool sfLockUnlock(SfPassword *password)
Unlocks or locks the flash with the specified password.
Definition: sflash.c:645
uint8_t SfPassword[8]
Serial Flash password.
Definition: sflash.h:57
bool sfInit()
Initializes the Serial Flash.
Definition: sflash.c:435
Definition: sflash.h:61
void spiSelect(SPI_Device *dev, uint32_t slaveNo)
Selects a specific slave.
Definition: spi.c:204
uint32_t flashSize
flash size in bytes
Definition: sflash.h:63
uint8_t mfId
Manufacturer ID.
Definition: sflash.h:65
#define SF_INFO_CAP_SECTOR_PROTECT
Device support per sector protection.
Definition: sflash.h:50
uint8_t _status
Hardware status register value.
Definition: sflash.h:70
#define SF_INFO_STS_PASSWORD_PROTECT
Whether (part of) the flash is password.
Definition: sflash.h:52
This driver wraps the functions of the OpenCores SPI master.
uint8_t cap
Device capabilities, see SF_INF_CAP_*.
Definition: sflash.h:68
SfInfo sfInfo
Flash info, only valid after successful initialization.
Definition: sflash.c:161
uint16_t pageSize
Page size in bytes.
Definition: sflash.h:64
void timeDelay(uint32_t msec)
Simple busy-wait delay.
Definition: tm.c:18
uint32_t sectorSize
Sector size in bytes.
Definition: sflash.h:62
#define E_INVSTATE
Generic error: Module is in a state in which.
Definition: errorcode.h:103
static uint32_t timeOutInit(uint32_t msec)
Initializes a timeout with the specified no of msecs.
Definition: tm.h:53
static bool timeOut(uint32_t to)
Checks whether or not the timeout has expired.
Definition: tm.h:77
bool sfReset()
Resets the flash.
Definition: sflash.c:320
Manages the global system error.
bool sfErase(uint32_t address)
Erase a sector in flash.
Definition: sflash.c:564
#define SF_INFO_STS_LOCKED
Whether part of the flash is locked.
Definition: sflash.h:54
void errPrint(bool clear)
Prints the last error.
Definition: err.c:79
uint8_t sts
Device status, see SF_INFO_STS_*.
Definition: sflash.h:69
bool sfSetPasswordOTP(SfPassword *password)
Password protects specific sectors from being modified.
Definition: sflash.c:589
uint8_t devId
Device ID.
Definition: sflash.h:66
#define SF_MF_SPANSION
Manufacturer Spansion.
Definition: sflash.h:33
#define SF_MF_MICRON
Manufacturer Micron.
Definition: sflash.h:34
Simple timer functions.
bool sfProtect(uint32_t address)
Protects a specific sector from being erased or programmed.
Definition: sflash.c:672
void errClear()
Clears the current error.
Definition: err.c:46
bool sfProgXPage(uint32_t address, uint8_t *data, uint32_t count)
Program cross pages.
Definition: sflash.c:547
void spiDeselect(SPI_Device *dev)
Deselects all slaves.
Definition: spi.c:212
This module is responsible for distributing error codes.
Various useful functions.
#define E_TIMEOUT
Generic error: Timeout error.
Definition: errorcode.h:100
uint8_t devCap
Device capacity ID.
Definition: sflash.h:67
bool sfRead(uint32_t address, uint8_t *data, uint32_t count)
Read from a specific address in flash.
Definition: sflash.c:491
#define SF_INFO_CAP_PASSWORD
Device supports password protection.
Definition: sflash.h:49
This file assigns all device structures to memory mapped structures.
bool spiTxRx(SPI_Device *dev, uint8_t *dataIn, uint8_t *dataOut, int len)
Transfers a specific number of bytes in a synchronous way.
Definition: spi.c:192
bool errSet(uint32_t code, const char *error, const char *name)
Sets an error.
#define ERROR(CODE,...)
Expands an error code to an error code with a description (if ERROR_W_DESCR is declared).
This driver implements access to the Serial Flash.
Definition: func.h:70
Provides common macros.
#define E_UNKNOWN
Generic error: Unknown error.
Definition: errorcode.h:97
bool sfProg(uint32_t address, uint8_t *data, uint32_t count)
Program an page in flash.
Definition: sflash.c:519
void sfSpDiag()
Shows diagnostic state of Spansion Flash.
Definition: sflash.c:627
#define E_NOTSUPPORTED
Generic error: not supported.
Definition: errorcode.h:115
Configures the board-specific peripherals, like I2C, SPI etc...
bool sfUnProtect()
Unprotects the entire flash array.
Definition: sflash.c:690