Merge pull request #2639 from ANTodorov/fix_unknown_flash
[RRG-proxmark3.git] / common_arm / flashmem.c
blobd316fa94516292b8c1d9c0a85513555172f1c139
1 //-----------------------------------------------------------------------------
2 // Borrowed initially from Arduino SPIFlash Library v.2.5.0
3 // Copyright (C) 2015 by Prajwal Bhattaram.
4 // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
5 //
6 // This program is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation, either version 3 of the License, or
9 // (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // See LICENSE.txt for the text of the license.
17 //-----------------------------------------------------------------------------
18 #include "flashmem.h"
19 #include "pmflash.h"
21 #include "proxmark3_arm.h"
22 #include "ticks.h"
24 #ifndef AS_BOOTROM
25 #include "dbprint.h"
26 #endif // AS_BOOTROM
28 #include "string.h"
29 #include "usb_cdc.h"
31 /* here: use NCPS2 @ PA10: */
32 #define SPI_CSR_NUM 2
33 #define SPI_PCS(npcs) ((~(1 << (npcs)) & 0xF) << 16)
34 /// Calculates the value of the CSR SCBR field given the baudrate and MCK.
35 #define SPI_SCBR(baudrate, masterClock) ((uint32_t) ((masterClock) / (baudrate)) << 8)
36 /// Calculates the value of the CSR DLYBS field given the desired delay (in ns)
37 #define SPI_DLYBS(delay, masterClock) ((uint32_t) ((((masterClock) / 1000000) * (delay)) / 1000) << 16)
38 /// Calculates the value of the CSR DLYBCT field given the desired delay (in ns)
39 #define SPI_DLYBCT(delay, masterClock) ((uint32_t) ((((masterClock) / 1000000) * (delay)) / 32000) << 24)
41 static uint32_t FLASHMEM_SPIBAUDRATE = FLASH_BAUD;
42 #define FASTFLASH (FLASHMEM_SPIBAUDRATE > FLASH_MINFAST)
44 #ifndef AS_BOOTROM
46 uint8_t spi_flash_p64k = 0;
48 void FlashmemSetSpiBaudrate(uint32_t baudrate) {
49 FLASHMEM_SPIBAUDRATE = baudrate;
50 Dbprintf("Spi Baudrate : %dMHz", FLASHMEM_SPIBAUDRATE / 1000000);
53 // read ID out
54 bool Flash_ReadID(flash_device_type_t *result, bool read_jedec) {
56 if (Flash_CheckBusy(BUSY_TIMEOUT)) return false;
59 if (read_jedec) {
60 // 0x9F JEDEC
61 FlashSendByte(JEDECID);
63 result->manufacturer_id = (FlashSendByte(0xFF) & 0xFF);
64 result->device_id = (FlashSendByte(0xFF) & 0xFF);
65 result->device_id2 = (FlashSendLastByte(0xFF) & 0xFF);
66 } else {
67 // 0x90 Manufacture ID / device ID
68 FlashSendByte(ID);
69 FlashSendByte(0x00);
70 FlashSendByte(0x00);
71 FlashSendByte(0x00);
73 result->manufacturer_id = (FlashSendByte(0xFF) & 0xFF);
74 result->device_id = (FlashSendLastByte(0xFF) & 0xFF);
77 return true;
80 uint16_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len) {
82 if (!FlashInit()) return 0;
84 // length should never be zero
85 if (!len || Flash_CheckBusy(BUSY_TIMEOUT)) return 0;
87 uint8_t cmd = (FASTFLASH) ? FASTREAD : READDATA;
89 FlashSendByte(cmd);
90 Flash_TransferAdresse(address);
92 if (FASTFLASH) {
93 FlashSendByte(DUMMYBYTE);
96 uint16_t i = 0;
97 for (; i < (len - 1); i++) {
98 out[i] = (FlashSendByte(0xFF) & 0xFF);
100 out[i] = (FlashSendLastByte(0xFF) & 0xFF);
101 FlashStop();
102 return len;
105 void Flash_TransferAdresse(uint32_t address) {
106 FlashSendByte((address >> 16) & 0xFF);
107 FlashSendByte((address >> 8) & 0xFF);
108 FlashSendByte((address >> 0) & 0xFF);
111 /* This ensures we can ReadData without having to cycle through initialization every time */
112 uint16_t Flash_ReadDataCont(uint32_t address, uint8_t *out, uint16_t len) {
114 // length should never be zero
115 if (!len) return 0;
117 uint8_t cmd = (FASTFLASH) ? FASTREAD : READDATA;
119 FlashSendByte(cmd);
120 Flash_TransferAdresse(address);
122 if (FASTFLASH) {
123 FlashSendByte(DUMMYBYTE);
126 uint16_t i = 0;
127 for (; i < (len - 1); i++) {
128 out[i] = ( FlashSendByte(0xFF) & 0xFF);
130 out[i] = (FlashSendLastByte(0xFF) & 0xFF);
131 return len;
134 ////////////////////////////////////////
135 // Write data can only program one page. A page has 256 bytes.
136 // if len > 256, it might wrap around and overwrite pos 0.
137 uint16_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len) {
139 // length should never be zero
140 if (!len)
141 return 0;
143 // Max 256 bytes write
144 if (((address & 0xFF) + len) > 256) {
145 Dbprintf("Flash_WriteData 256 fail [ 0x%02x ] [ %u ]", (address & 0xFF) + len, len);
146 return 0;
149 if (!FlashInit()) {
150 if (g_dbglevel > 3) Dbprintf("Flash_WriteData init fail");
151 return 0;
154 // out-of-range
155 if (((address >> 16) & 0xFF) > spi_flash_p64k) {
156 Dbprintf("Flash_WriteData, block out-of-range %02x > %02x", (address >> 16) & 0xFF, spi_flash_p64k);
157 FlashStop();
158 return 0;
161 Flash_CheckBusy(BUSY_TIMEOUT);
163 Flash_WriteEnable();
165 FlashSendByte(PAGEPROG);
166 FlashSendByte((address >> 16) & 0xFF);
167 FlashSendByte((address >> 8) & 0xFF);
168 FlashSendByte((address >> 0) & 0xFF);
170 uint16_t i = 0;
171 for (; i < (len - 1); i++)
172 FlashSendByte(in[i]);
174 FlashSendLastByte(in[i]);
176 FlashStop();
177 return len;
180 // length should never be zero
181 // Max 256 bytes write
182 // out-of-range
183 uint16_t Flash_WriteDataCont(uint32_t address, uint8_t *in, uint16_t len) {
185 if (!len)
186 return 0;
188 if (((address & 0xFF) + len) > 256) {
189 Dbprintf("Flash_WriteDataCont 256 fail [ 0x%02x ] [ %u ]", (address & 0xFF) + len, len);
190 return 0;
193 if (((address >> 16) & 0xFF) > spi_flash_p64k) {
194 Dbprintf("Flash_WriteDataCont, block out-of-range %02x > %02x", (address >> 16) & 0xFF, spi_flash_p64k);
195 return 0;
198 FlashSendByte(PAGEPROG);
199 FlashSendByte((address >> 16) & 0xFF);
200 FlashSendByte((address >> 8) & 0xFF);
201 FlashSendByte((address >> 0) & 0xFF);
203 uint16_t i = 0;
204 for (; i < (len - 1); i++)
205 FlashSendByte(in[i]);
207 FlashSendLastByte(in[i]);
208 return len;
211 // assumes valid start 256 based 00 address
213 uint16_t Flash_Write(uint32_t address, uint8_t *in, uint16_t len) {
215 bool isok;
216 uint16_t res, bytes_sent = 0, bytes_remaining = len;
217 uint8_t buf[FLASH_MEM_BLOCK_SIZE];
218 while (bytes_remaining > 0) {
220 Flash_CheckBusy(BUSY_TIMEOUT);
221 Flash_WriteEnable();
223 uint32_t bytes_in_packet = MIN(FLASH_MEM_BLOCK_SIZE, bytes_remaining);
225 memcpy(buf, in + bytes_sent, bytes_in_packet);
227 res = Flash_WriteDataCont(address + bytes_sent, buf, bytes_in_packet);
229 bytes_remaining -= bytes_in_packet;
230 bytes_sent += bytes_in_packet;
232 isok = (res == bytes_in_packet);
234 if (!isok)
235 goto out;
238 out:
239 FlashStop();
240 return len;
243 // WARNING -- if callers are using a file system (such as SPIFFS),
244 // they should inform the file system of this change
245 // e.g., rdv40_spiffs_check()
246 bool Flash_WipeMemoryPage(uint8_t page) {
247 if (!FlashInit()) {
248 if (g_dbglevel > 3) Dbprintf("Flash_WriteData init fail");
249 return false;
251 Flash_ReadStat1();
253 // Each block is 64Kb. One block erase takes 1s ( 1000ms )
254 Flash_WriteEnable();
255 Flash_Erase64k(page);
256 Flash_CheckBusy(BUSY_TIMEOUT);
258 FlashStop();
260 return true;
262 // Wipes flash memory completely, fills with 0xFF
263 bool Flash_WipeMemory(void) {
264 if (!FlashInit()) {
265 if (g_dbglevel > 3) Dbprintf("Flash_WriteData init fail");
266 return false;
268 Flash_ReadStat1();
270 // Each block is 64Kb. Four blocks
271 // one block erase takes 1s ( 1000ms )
272 for (uint8_t i=0; i < spi_flash_p64k; i++) {
273 Flash_WriteEnable();
274 Flash_Erase64k(i);
275 Flash_CheckBusy(BUSY_TIMEOUT);
278 FlashStop();
279 return true;
282 // enable the flash write
283 void Flash_WriteEnable(void) {
284 FlashSendLastByte(WRITEENABLE);
285 if (g_dbglevel > 3) Dbprintf("Flash Write enabled");
288 // erase 4K at one time
289 // execution time: 0.8ms / 800us
290 bool Flash_Erase4k(uint8_t block, uint8_t sector) {
292 if (block > spi_flash_p64k || sector > MAX_SECTORS) return false;
294 FlashSendByte(SECTORERASE);
295 FlashSendByte(block);
296 FlashSendByte(sector << 4);
297 FlashSendLastByte(00);
298 return true;
302 // erase 32K at one time
303 // execution time: 0,3s / 300ms
304 bool Flash_Erase32k(uint32_t address) {
305 if (address & (32*1024 - 1)) {
306 if ( g_dbglevel > 1 ) Dbprintf("Flash_Erase32k : Address is not align at 4096");
307 return false;
309 FlashSendByte(BLOCK32ERASE);
310 FlashSendByte((address >> 16) & 0xFF);
311 FlashSendByte((address >> 8) & 0xFF);
312 FlashSendLastByte((address >> 0) & 0xFF);
313 return true;
317 // erase 64k at one time
318 // since a block is 64kb, and there is four blocks.
319 // we only need block number, as MSB
320 // execution time: 1s / 1000ms
321 // 0x00 00 00 -- 0x 00 FF FF == block 0
322 // 0x01 00 00 -- 0x 01 FF FF == block 1
323 // 0x02 00 00 -- 0x 02 FF FF == block 2
324 // 0x03 00 00 -- 0x 03 FF FF == block 3
325 bool Flash_Erase64k(uint8_t block) {
327 if (block > spi_flash_p64k) return false;
329 FlashSendByte(BLOCK64ERASE);
330 FlashSendByte(block);
331 FlashSendByte(0x00);
332 FlashSendLastByte(0x00);
333 return true;
337 // Erase chip
338 void Flash_EraseChip(void) {
339 FlashSendLastByte(CHIPERASE);
343 void Flashmem_print_status(void) {
344 DbpString(_CYAN_("Flash memory"));
345 Dbprintf(" Baudrate................ " _GREEN_("%d MHz"), FLASHMEM_SPIBAUDRATE / 1000000);
347 if (!FlashInit()) {
348 DbpString(" Init.................... " _RED_("failed"));
349 return;
351 DbpString(" Init.................... " _GREEN_("ok"));
353 // NOTE: It would likely be more useful to use JDEC ID command 9F,
354 // as it provides a third byte indicative of capacity.
355 flash_device_type_t device_type = {0};
356 if (!Flash_ReadID(&device_type, false)) {
357 DbpString(" Device ID............... " _RED_(" --> Not Found <--"));
358 } else {
359 if (device_type.manufacturer_id == WINBOND_MANID) {
360 switch (device_type.device_id) {
361 case WINBOND_32MB_DEVID:
362 DbpString(" Memory size............. " _YELLOW_("32 mbits / 4 MB"));
363 break;
364 case WINBOND_16MB_DEVID:
365 DbpString(" Memory size............. " _YELLOW_("16 mbits / 2 MB"));
366 break;
367 case WINBOND_8MB_DEVID:
368 DbpString(" Memory size............. " _YELLOW_("8 mbits / 1 MB"));
369 break;
370 case WINBOND_4MB_DEVID:
371 DbpString(" Memory size............. " _YELLOW_("4 mbits / 512 kb"));
372 break;
373 case WINBOND_2MB_DEVID:
374 DbpString(" Memory size............. " _YELLOW_("2 mbits / 256 kb"));
375 break;
376 case WINBOND_1MB_DEVID:
377 DbpString(" Memory size..... ....... " _YELLOW_("1 mbits / 128 kb"));
378 break;
379 case WINBOND_512KB_DEVID:
380 DbpString(" Memory size............. " _YELLOW_("512 kbits / 64 kb"));
381 break;
382 default:
383 Dbprintf(" Device ID............... " _YELLOW_("%02X / %02X (Winbond)"),
384 device_type.manufacturer_id,
385 device_type.device_id
387 break;
389 } else {
390 Dbprintf(" Device ID............... " _YELLOW_("%02X / %02X (unknown)"),
391 device_type.manufacturer_id,
392 device_type.device_id
395 if (Flash_ReadID(&device_type, true)) {
396 Dbprintf(" JEDEC Mfr ID / Dev ID... " _YELLOW_("%02X / %02X%02X"),
397 device_type.manufacturer_id,
398 device_type.device_id,
399 device_type.device_id2
403 Dbprintf(" Flash pages (64k)....... " _YELLOW_("0x%02x (%u)"), spi_flash_p64k, spi_flash_p64k);
405 uint8_t uid[8] = {0, 0, 0, 0, 0, 0, 0, 0};
406 Flash_UniqueID(uid);
407 Dbprintf(" Unique ID (be).......... " _YELLOW_("0x%02X%02X%02X%02X%02X%02X%02X%02X"),
408 uid[0], uid[1], uid[2], uid[3],
409 uid[4], uid[5], uid[6], uid[7]
411 if (g_dbglevel > 3) {
412 Dbprintf(" Unique ID (le).......... " _YELLOW_("0x%02X%02X%02X%02X%02X%02X%02X%02X"),
413 uid[7], uid[6], uid[5], uid[4],
414 uid[3], uid[2], uid[1], uid[0]
417 FlashStop();
420 void Flashmem_print_info(void) {
422 if (!FlashInit()) return;
424 DbpString(_CYAN_("Flash memory dictionary loaded"));
426 // load dictionary offsets.
427 uint8_t keysum[2];
428 uint16_t num;
430 Flash_CheckBusy(BUSY_TIMEOUT);
431 uint16_t isok = Flash_ReadDataCont(DEFAULT_MF_KEYS_OFFSET_P(spi_flash_p64k), keysum, 2);
432 if (isok == 2) {
433 num = ((keysum[1] << 8) | keysum[0]);
434 if (num != 0xFFFF && num != 0x0)
435 Dbprintf(" Mifare.................. "_YELLOW_("%u")" / "_GREEN_("%u")" keys", num, DEFAULT_MF_KEYS_MAX);
438 Flash_CheckBusy(BUSY_TIMEOUT);
439 isok = Flash_ReadDataCont(DEFAULT_T55XX_KEYS_OFFSET_P(spi_flash_p64k), keysum, 2);
440 if (isok == 2) {
441 num = ((keysum[1] << 8) | keysum[0]);
442 if (num != 0xFFFF && num != 0x0)
443 Dbprintf(" T55x7................... "_YELLOW_("%u")" / "_GREEN_("%u")" keys", num, DEFAULT_T55XX_KEYS_MAX);
446 Flash_CheckBusy(BUSY_TIMEOUT);
447 isok = Flash_ReadDataCont(DEFAULT_ICLASS_KEYS_OFFSET_P(spi_flash_p64k), keysum, 2);
448 if (isok == 2) {
449 num = ((keysum[1] << 8) | keysum[0]);
450 if (num != 0xFFFF && num != 0x0)
451 Dbprintf(" iClass.................. "_YELLOW_("%u")" / "_GREEN_("%u")" keys", num, DEFAULT_ICLASS_KEYS_MAX);
454 FlashStop();
457 //read spi flash JEDEC ID and fill the global variable spi_flash_p64k
458 bool FlashDetect(void) {
459 flash_device_type_t flash_device = {0};
461 if (!Flash_ReadID(&flash_device, true)) {
462 if (g_dbglevel > 3) Dbprintf("Flash_ReadID failed");
463 return false;
466 uint32_t identifier = (flash_device.manufacturer_id << 16) + (flash_device.device_id <<8 ) + flash_device.device_id2;
467 int i = 0;
468 for (; i < ARRAYLEN(SpiFlashTable)-1; i++) {
469 if (SpiFlashTable[i].identifier == identifier) {
470 break;
474 spi_flash_p64k = SpiFlashTable[i].pages64;
476 return true;
479 #endif // #ifndef AS_BOOTROM
482 // initialize
483 bool FlashInit(void) {
484 FlashSetup(FLASHMEM_SPIBAUDRATE);
486 StartTicks();
488 if (Flash_CheckBusy(BUSY_TIMEOUT)) {
489 StopTicks();
490 return false;
493 #ifndef AS_BOOTROM
494 if (spi_flash_p64k == 0) {
495 if (!FlashDetect()) {
496 return false;
499 #endif // #ifndef AS_BOOTROM
501 return true;
504 // read unique id for chip.
505 void Flash_UniqueID(uint8_t *uid) {
507 if (Flash_CheckBusy(BUSY_TIMEOUT)) return;
509 // reading unique serial number
510 FlashSendByte(UNIQUE_ID);
511 FlashSendByte(0xFF);
512 FlashSendByte(0xFF);
513 FlashSendByte(0xFF);
514 FlashSendByte(0xFF);
516 uid[7] = (FlashSendByte(0xFF) & 0xFF);
517 uid[6] = (FlashSendByte(0xFF) & 0xFF);
518 uid[5] = (FlashSendByte(0xFF) & 0xFF);
519 uid[4] = (FlashSendByte(0xFF) & 0xFF);
520 uid[3] = (FlashSendByte(0xFF) & 0xFF);
521 uid[2] = (FlashSendByte(0xFF) & 0xFF);
522 uid[1] = (FlashSendByte(0xFF) & 0xFF);
523 uid[0] = (FlashSendLastByte(0xFF) & 0xFF);
526 void FlashStop(void) {
527 //Bof
528 //* Reset all the Chip Select register
529 AT91C_BASE_SPI->SPI_CSR[0] = 0;
530 AT91C_BASE_SPI->SPI_CSR[1] = 0;
531 AT91C_BASE_SPI->SPI_CSR[2] = 0;
532 AT91C_BASE_SPI->SPI_CSR[3] = 0;
534 // Reset the SPI mode
535 AT91C_BASE_SPI->SPI_MR = 0;
537 // Disable all interrupts
538 AT91C_BASE_SPI->SPI_IDR = 0xFFFFFFFF;
540 // SPI disable
541 AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIDIS;
543 #ifndef AS_BOOTROM
544 if (g_dbglevel > 3) Dbprintf("FlashStop");
545 #endif // AS_BOOTROM
547 StopTicks();
550 void FlashSetup(uint32_t baudrate) {
551 //WDT_DISABLE
552 AT91C_BASE_WDTC->WDTC_WDMR = AT91C_WDTC_WDDIS;
554 // PA10 -> SPI_NCS2 chip select (FLASHMEM)
555 // PA11 -> SPI_NCS0 chip select (FPGA)
556 // PA12 -> SPI_MISO Master-In Slave-Out
557 // PA13 -> SPI_MOSI Master-Out Slave-In
558 // PA14 -> SPI_SPCK Serial Clock
560 // Disable PIO control of the following pins, allows use by the SPI peripheral
561 AT91C_BASE_PIOA->PIO_PDR |= (GPIO_NCS0 | GPIO_MISO | GPIO_MOSI | GPIO_SPCK | GPIO_NCS2);
563 // Pull-up Enable
564 AT91C_BASE_PIOA->PIO_PPUER |= (GPIO_NCS0 | GPIO_MISO | GPIO_MOSI | GPIO_SPCK | GPIO_NCS2);
566 // Peripheral A
567 AT91C_BASE_PIOA->PIO_ASR |= (GPIO_NCS0 | GPIO_MISO | GPIO_MOSI | GPIO_SPCK);
569 // Peripheral B
570 AT91C_BASE_PIOA->PIO_BSR |= GPIO_NCS2;
572 //enable the SPI Peripheral clock
573 AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_SPI);
576 //reset spi needs double SWRST, see atmel's errata on this case
577 AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST;
578 AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST;
580 // Enable SPI
581 AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIEN;
583 // NPCS2 Mode 0
584 AT91C_BASE_SPI->SPI_MR =
585 (0 << 24) | // Delay between chip selects = DYLBCS/MCK BUT:
586 // If DLYBCS is less than or equal to six, six MCK periods
587 // will be inserted by default.
588 SPI_PCS(SPI_CSR_NUM) | // Peripheral Chip Select (selects SPI_NCS2 or PA10)
589 (0 << 7) | // Disable LLB (1=MOSI2MISO test mode)
590 (1 << 4) | // Disable ModeFault Protection
591 (0 << 3) | // makes spi operate at MCK (1 is MCK/2)
592 (0 << 2) | // Chip selects connected directly to peripheral
593 AT91C_SPI_PS_FIXED | // Fixed Peripheral Select
594 AT91C_SPI_MSTR; // Master Mode
596 uint8_t csaat = 1;
597 uint32_t dlybct = 0;
598 uint8_t ncpha = 1;
599 uint8_t cpol = 0;
600 if (baudrate > FLASH_MINFAST) {
601 baudrate = FLASH_FASTBAUD;
602 //csaat = 0;
603 dlybct = 1500;
604 ncpha = 0;
605 cpol = 0;
608 AT91C_BASE_SPI->SPI_CSR[2] =
609 SPI_DLYBCT(dlybct, MCK) | // Delay between Consecutive Transfers (32 MCK periods)
610 SPI_DLYBS(0, MCK) | // Delay Beforce SPCK CLock
611 SPI_SCBR(baudrate, MCK) | // SPI Baudrate Selection
612 AT91C_SPI_BITS_8 | // Bits per Transfer (8 bits)
613 //AT91C_SPI_CSAAT | // Chip Select inactive after transfer
614 // 40.4.6.2 SPI: Bad tx_ready Behavior when CSAAT = 1 and SCBR = 1
615 // If the SPI is programmed with CSAAT = 1, SCBR(baudrate) = 1 and two transfers are performed consecutively on
616 // the same slave with an IDLE state between them, the tx_ready signal does not rise after the second data has been
617 // transferred in the shifter. This can imply for example, that the second data is sent twice.
618 // COLIN :: For now we STILL use CSAAT=1 to avoid having to (de)assert NPCS manually via PIO lines and we deal with delay
619 (csaat << 3) |
620 /* Spi modes:
621 Mode CPOL CPHA NCPHA
622 0 0 0 1 clock normally low read on rising edge
623 1 0 1 0 clock normally low read on falling edge
624 2 1 0 1 clock normally high read on falling edge
625 3 1 1 0 clock normally high read on rising edge
626 However, page 512 of the AT91SAM7Sx datasheet say "Note that in SPI
627 master mode the ATSAM7S512/256/128/64/321/32 does not sample the data
628 (MISO) on the opposite edge where data clocks out (MOSI) but the same
629 edge is used as shown in Figure 36-3 and Figure 36-4." Figure 36-3
630 shows that CPOL=NCPHA=0 or CPOL=NCPHA=1 samples on the rising edge and
631 that the data changes sometime after the rising edge (about 2 ns). To
632 be consistent with normal SPI operation, it is probably safe to say
633 that the data changes on the falling edge and should be sampled on the
634 rising edge. Therefore, it appears that NCPHA should be treated the
635 same as CPHA. Thus:
636 Mode CPOL CPHA NCPHA
637 0 0 0 0 clock normally low read on rising edge
638 1 0 1 1 clock normally low read on falling edge
639 2 1 0 0 clock normally high read on falling edge
640 3 1 1 1 clock normally high read on rising edge
641 Update: for 24MHz, writing is more stable with ncpha=1, else bitflips occur.
643 (ncpha << 1) | // Clock Phase data captured on leading edge, changes on following edge
644 (cpol << 0); // Clock Polarity inactive state is logic 0
646 // read first, empty buffer
647 if (AT91C_BASE_SPI->SPI_RDR == 0) {};
650 bool Flash_CheckBusy(uint32_t timeout) {
651 WaitUS(WINBOND_WRITE_DELAY);
652 StartCountUS();
653 uint32_t _time = GetCountUS();
655 do {
656 if (!(Flash_ReadStat1() & BUSY)) {
657 return false;
659 } while ((GetCountUS() - _time) < timeout);
661 if (timeout <= (GetCountUS() - _time)) {
662 return true;
665 return false;
668 // read state register 1
669 uint8_t Flash_ReadStat1(void) {
670 FlashSendByte(READSTAT1);
671 return FlashSendLastByte(0xFF);
674 // send one byte over SPI
675 uint16_t FlashSendByte(uint32_t data) {
677 // wait until SPI is ready for transfer
678 //if you are checking for incoming data returned then the TXEMPTY flag is redundant
679 //while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0) {};
681 // send the data
682 AT91C_BASE_SPI->SPI_TDR = data;
684 //while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TDRE) == 0){};
686 // wait receive transfer is complete
687 while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_RDRF) == 0) {};
689 // reading incoming data
690 return ((AT91C_BASE_SPI->SPI_RDR) & 0xFFFF);
693 // send last byte over SPI
694 uint16_t FlashSendLastByte(uint32_t data) {
695 return FlashSendByte(data | AT91C_SPI_LASTXFER);