Merge pull request #2654 from Antiklesys/master
[RRG-proxmark3.git] / common_arm / flashmem.c
blob5aa88b0ebce5a9cfe53ea56fded0d569bda8a165
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
47 spi_flash_t spi_flash_data = {0};
48 uint8_t spi_flash_pages64k = 4;
50 void FlashmemSetSpiBaudrate(uint32_t baudrate) {
51 FLASHMEM_SPIBAUDRATE = baudrate;
52 Dbprintf("Spi Baudrate : %dMHz", FLASHMEM_SPIBAUDRATE / 1000000);
55 // read ID out
56 bool Flash_ReadID(flash_device_type_t *result, bool read_jedec) {
58 if (Flash_CheckBusy(BUSY_TIMEOUT)) return false;
61 if (read_jedec) {
62 // 0x9F JEDEC
63 FlashSendByte(JEDECID);
65 result->manufacturer_id = (FlashSendByte(0xFF) & 0xFF);
66 result->device_id = (FlashSendByte(0xFF) & 0xFF);
67 result->device_id2 = (FlashSendLastByte(0xFF) & 0xFF);
68 } else {
69 // 0x90 Manufacture ID / device ID
70 FlashSendByte(ID);
71 FlashSendByte(0x00);
72 FlashSendByte(0x00);
73 FlashSendByte(0x00);
75 result->manufacturer_id = (FlashSendByte(0xFF) & 0xFF);
76 result->device_id = (FlashSendLastByte(0xFF) & 0xFF);
79 return true;
82 uint16_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len) {
84 if (!FlashInit()) return 0;
86 // length should never be zero
87 if (!len || Flash_CheckBusy(BUSY_TIMEOUT)) return 0;
89 uint8_t cmd = (FASTFLASH) ? FASTREAD : READDATA;
91 FlashSendByte(cmd);
92 Flash_TransferAdresse(address);
94 if (FASTFLASH) {
95 FlashSendByte(DUMMYBYTE);
98 uint16_t i = 0;
99 for (; i < (len - 1); i++) {
100 out[i] = (FlashSendByte(0xFF) & 0xFF);
102 out[i] = (FlashSendLastByte(0xFF) & 0xFF);
103 FlashStop();
104 return len;
107 void Flash_TransferAdresse(uint32_t address) {
108 FlashSendByte((address >> 16) & 0xFF);
109 FlashSendByte((address >> 8) & 0xFF);
110 FlashSendByte((address >> 0) & 0xFF);
113 /* This ensures we can ReadData without having to cycle through initialization every time */
114 uint16_t Flash_ReadDataCont(uint32_t address, uint8_t *out, uint16_t len) {
116 // length should never be zero
117 if (!len) return 0;
119 uint8_t cmd = (FASTFLASH) ? FASTREAD : READDATA;
121 FlashSendByte(cmd);
122 Flash_TransferAdresse(address);
124 if (FASTFLASH) {
125 FlashSendByte(DUMMYBYTE);
128 uint16_t i = 0;
129 for (; i < (len - 1); i++) {
130 out[i] = (FlashSendByte(0xFF) & 0xFF);
132 out[i] = (FlashSendLastByte(0xFF) & 0xFF);
133 return len;
136 ////////////////////////////////////////
137 // Write data can only program one page. A page has 256 bytes.
138 // if len > 256, it might wrap around and overwrite pos 0.
139 uint16_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len) {
141 // length should never be zero
142 if (!len)
143 return 0;
145 // Max 256 bytes write
146 if (((address & 0xFF) + len) > 256) {
147 Dbprintf("Flash_WriteData 256 fail [ 0x%02x ] [ %u ]", (address & 0xFF) + len, len);
148 return 0;
151 if (!FlashInit()) {
152 if (g_dbglevel > 3) Dbprintf("Flash_WriteData init fail");
153 return 0;
156 // out-of-range
157 if (((address >> 16) & 0xFF) > spi_flash_pages64k) {
158 Dbprintf("Flash_WriteData, block out-of-range %02x > %02x", (address >> 16) & 0xFF, spi_flash_pages64k);
159 FlashStop();
160 return 0;
163 Flash_CheckBusy(BUSY_TIMEOUT);
165 Flash_WriteEnable();
167 FlashSendByte(PAGEPROG);
168 FlashSendByte((address >> 16) & 0xFF);
169 FlashSendByte((address >> 8) & 0xFF);
170 FlashSendByte((address >> 0) & 0xFF);
172 uint16_t i = 0;
173 for (; i < (len - 1); i++)
174 FlashSendByte(in[i]);
176 FlashSendLastByte(in[i]);
178 FlashStop();
179 return len;
182 // length should never be zero
183 // Max 256 bytes write
184 // out-of-range
185 uint16_t Flash_WriteDataCont(uint32_t address, uint8_t *in, uint16_t len) {
187 if (!len)
188 return 0;
190 if (((address & 0xFF) + len) > 256) {
191 Dbprintf("Flash_WriteDataCont 256 fail [ 0x%02x ] [ %u ]", (address & 0xFF) + len, len);
192 return 0;
195 if (((address >> 16) & 0xFF) > spi_flash_pages64k) {
196 Dbprintf("Flash_WriteDataCont, block out-of-range %02x > %02x", (address >> 16) & 0xFF, spi_flash_pages64k);
197 return 0;
200 FlashSendByte(PAGEPROG);
201 FlashSendByte((address >> 16) & 0xFF);
202 FlashSendByte((address >> 8) & 0xFF);
203 FlashSendByte((address >> 0) & 0xFF);
205 uint16_t i = 0;
206 for (; i < (len - 1); i++)
207 FlashSendByte(in[i]);
209 FlashSendLastByte(in[i]);
210 return len;
213 // assumes valid start 256 based 00 address
215 uint16_t Flash_Write(uint32_t address, uint8_t *in, uint16_t len) {
217 bool isok;
218 uint16_t res, bytes_sent = 0, bytes_remaining = len;
219 uint8_t buf[FLASH_MEM_BLOCK_SIZE];
220 while (bytes_remaining > 0) {
222 Flash_CheckBusy(BUSY_TIMEOUT);
223 Flash_WriteEnable();
225 uint32_t bytes_in_packet = MIN(FLASH_MEM_BLOCK_SIZE, bytes_remaining);
227 memcpy(buf, in + bytes_sent, bytes_in_packet);
229 res = Flash_WriteDataCont(address + bytes_sent, buf, bytes_in_packet);
231 bytes_remaining -= bytes_in_packet;
232 bytes_sent += bytes_in_packet;
234 isok = (res == bytes_in_packet);
236 if (!isok)
237 goto out;
240 out:
241 FlashStop();
242 return len;
245 // WARNING -- if callers are using a file system (such as SPIFFS),
246 // they should inform the file system of this change
247 // e.g., rdv40_spiffs_check()
248 bool Flash_WipeMemoryPage(uint8_t page) {
249 if (!FlashInit()) {
250 if (g_dbglevel > 3) Dbprintf("Flash_WriteData init fail");
251 return false;
253 Flash_ReadStat1();
255 // Each block is 64Kb. One block erase takes 1s ( 1000ms )
256 Flash_WriteEnable();
257 Flash_Erase64k(page);
258 Flash_CheckBusy(BUSY_TIMEOUT);
260 FlashStop();
262 return true;
264 // Wipes flash memory completely, fills with 0xFF
265 bool Flash_WipeMemory(void) {
266 if (!FlashInit()) {
267 if (g_dbglevel > 3) Dbprintf("Flash_WriteData init fail");
268 return false;
270 Flash_ReadStat1();
272 // Each block is 64Kb. Four blocks
273 // one block erase takes 1s ( 1000ms )
274 for (uint8_t i = 0; i < spi_flash_pages64k; i++) {
275 Flash_WriteEnable();
276 Flash_Erase64k(i);
277 Flash_CheckBusy(BUSY_TIMEOUT);
280 FlashStop();
281 return true;
284 // enable the flash write
285 void Flash_WriteEnable(void) {
286 FlashSendLastByte(WRITEENABLE);
287 if (g_dbglevel > 3) Dbprintf("Flash Write enabled");
290 // erase 4K at one time
291 // execution time: 0.8ms / 800us
292 bool Flash_Erase4k(uint8_t block, uint8_t sector) {
294 if (block > spi_flash_pages64k || sector > MAX_SECTORS) return false;
296 FlashSendByte(SECTORERASE);
297 FlashSendByte(block);
298 FlashSendByte(sector << 4);
299 FlashSendLastByte(00);
300 return true;
304 // erase 32K at one time
305 // execution time: 0,3s / 300ms
306 bool Flash_Erase32k(uint32_t address) {
307 if (address & (32*1024 - 1)) {
308 if ( g_dbglevel > 1 ) Dbprintf("Flash_Erase32k : Address is not align at 4096");
309 return false;
311 FlashSendByte(BLOCK32ERASE);
312 FlashSendByte((address >> 16) & 0xFF);
313 FlashSendByte((address >> 8) & 0xFF);
314 FlashSendLastByte((address >> 0) & 0xFF);
315 return true;
319 // erase 64k at one time
320 // since a block is 64kb, and there is four blocks.
321 // we only need block number, as MSB
322 // execution time: 1s / 1000ms
323 // 0x00 00 00 -- 0x 00 FF FF == block 0
324 // 0x01 00 00 -- 0x 01 FF FF == block 1
325 // 0x02 00 00 -- 0x 02 FF FF == block 2
326 // 0x03 00 00 -- 0x 03 FF FF == block 3
327 bool Flash_Erase64k(uint8_t block) {
329 if (block > spi_flash_pages64k) return false;
331 FlashSendByte(BLOCK64ERASE);
332 FlashSendByte(block);
333 FlashSendByte(0x00);
334 FlashSendLastByte(0x00);
335 return true;
339 // Erase chip
340 void Flash_EraseChip(void) {
341 FlashSendLastByte(CHIPERASE);
345 void Flashmem_print_status(void) {
346 DbpString(_CYAN_("Flash memory"));
347 Dbprintf(" Baudrate................ " _GREEN_("%d MHz"), FLASHMEM_SPIBAUDRATE / 1000000);
349 if (!FlashInit()) {
350 DbpString(" Init.................... " _RED_("failed"));
351 return;
353 DbpString(" Init.................... " _GREEN_("ok"));
355 if (spi_flash_data.device_id > 0) {
356 Dbprintf(" Mfr ID / Dev ID......... " _YELLOW_("%02X / %02X"),
357 spi_flash_data.manufacturer_id,
358 spi_flash_data.device_id
362 if (spi_flash_data.jedec_id > 0) {
363 Dbprintf(" JEDEC Mfr ID / Dev ID... " _YELLOW_("%02X / %04X"),
364 spi_flash_data.manufacturer_id,
365 spi_flash_data.jedec_id
369 Dbprintf(" Device.................. " _YELLOW_("%s"), spi_flash_data.device);
370 Dbprintf(" Memory size............. " _YELLOW_("%d kB (%d pages * 64k)"), spi_flash_pages64k * 64, spi_flash_pages64k);
372 uint8_t uid[8] = {0, 0, 0, 0, 0, 0, 0, 0};
373 Flash_UniqueID(uid);
374 Dbprintf(" Unique ID (be).......... " _YELLOW_("0x%02X%02X%02X%02X%02X%02X%02X%02X"),
375 uid[0], uid[1], uid[2], uid[3],
376 uid[4], uid[5], uid[6], uid[7]
378 if (g_dbglevel > 3) {
379 Dbprintf(" Unique ID (le).......... " _YELLOW_("0x%02X%02X%02X%02X%02X%02X%02X%02X"),
380 uid[7], uid[6], uid[5], uid[4],
381 uid[3], uid[2], uid[1], uid[0]
384 FlashStop();
387 void Flashmem_print_info(void) {
389 if (!FlashInit()) return;
391 DbpString(_CYAN_("Flash memory dictionary loaded"));
393 // load dictionary offsets.
394 uint8_t keysum[2];
395 uint16_t num;
397 Flash_CheckBusy(BUSY_TIMEOUT);
398 uint16_t isok = Flash_ReadDataCont(DEFAULT_MF_KEYS_OFFSET_P(spi_flash_pages64k), keysum, 2);
399 if (isok == 2) {
400 num = ((keysum[1] << 8) | keysum[0]);
401 if (num != 0xFFFF && num != 0x0)
402 Dbprintf(" Mifare.................. "_YELLOW_("%u")" / "_GREEN_("%u")" keys", num, DEFAULT_MF_KEYS_MAX);
405 Flash_CheckBusy(BUSY_TIMEOUT);
406 isok = Flash_ReadDataCont(DEFAULT_T55XX_KEYS_OFFSET_P(spi_flash_pages64k), keysum, 2);
407 if (isok == 2) {
408 num = ((keysum[1] << 8) | keysum[0]);
409 if (num != 0xFFFF && num != 0x0)
410 Dbprintf(" T55x7................... "_YELLOW_("%u")" / "_GREEN_("%u")" keys", num, DEFAULT_T55XX_KEYS_MAX);
413 Flash_CheckBusy(BUSY_TIMEOUT);
414 isok = Flash_ReadDataCont(DEFAULT_ICLASS_KEYS_OFFSET_P(spi_flash_pages64k), keysum, 2);
415 if (isok == 2) {
416 num = ((keysum[1] << 8) | keysum[0]);
417 if (num != 0xFFFF && num != 0x0)
418 Dbprintf(" iClass.................. "_YELLOW_("%u")" / "_GREEN_("%u")" keys", num, DEFAULT_ICLASS_KEYS_MAX);
421 FlashStop();
424 bool FlashDetect(void) {
425 flash_device_type_t flash_data = {0};
426 bool ret = false;
427 // read using 0x9F (JEDEC)
428 if (Flash_ReadID(&flash_data, true)) {
429 spi_flash_data.manufacturer_id = flash_data.manufacturer_id;
430 spi_flash_data.jedec_id = (flash_data.device_id << 8) + flash_data.device_id2;
431 ret = true;
432 } else {
433 if (g_dbglevel > 3) Dbprintf("Flash_ReadID failed reading JEDEC (0x9F)");
435 // read using 0x90 (Manufacturer / Device ID)
436 if (Flash_ReadID(&flash_data, false)) {
437 if (spi_flash_data.manufacturer_id == 0) {
438 spi_flash_data.manufacturer_id = flash_data.manufacturer_id;
440 spi_flash_data.device_id = flash_data.device_id;
441 ret = true;
442 } else {
443 if (g_dbglevel > 3) Dbprintf("Flash_ReadID failed reading Mfr/Dev (0x90)");
445 // default device is 'unknown'
446 spi_flash_data.device = SpiFlashTable[0].device;
448 if (ret) {
449 for (int i = 0; i < ARRAYLEN(SpiFlashTable); i++) {
450 if (SpiFlashTable[i].manufacturer_id == spi_flash_data.manufacturer_id) {
451 if (SpiFlashTable[i].jedec_id == spi_flash_data.jedec_id) {
452 spi_flash_pages64k = SpiFlashTable[i].pages64k;
453 spi_flash_data.device = SpiFlashTable[i].device;
454 break;
456 if (SpiFlashTable[i].device_id == spi_flash_data.device_id) {
457 spi_flash_data.device = SpiFlashTable[i].device;
458 break;
464 return ret;
467 #endif // #ifndef AS_BOOTROM
470 // initialize
471 bool FlashInit(void) {
472 FlashSetup(FLASHMEM_SPIBAUDRATE);
474 StartTicks();
476 if (Flash_CheckBusy(BUSY_TIMEOUT)) {
477 StopTicks();
478 return false;
481 #ifndef AS_BOOTROM
482 if (spi_flash_data.manufacturer_id == 0) {
483 if (!FlashDetect()) {
484 return false;
487 #endif // #ifndef AS_BOOTROM
489 return true;
492 // read unique id for chip.
493 void Flash_UniqueID(uint8_t *uid) {
495 if (Flash_CheckBusy(BUSY_TIMEOUT)) return;
497 // reading unique serial number
498 FlashSendByte(UNIQUE_ID);
499 FlashSendByte(0xFF);
500 FlashSendByte(0xFF);
501 FlashSendByte(0xFF);
502 FlashSendByte(0xFF);
504 uid[7] = (FlashSendByte(0xFF) & 0xFF);
505 uid[6] = (FlashSendByte(0xFF) & 0xFF);
506 uid[5] = (FlashSendByte(0xFF) & 0xFF);
507 uid[4] = (FlashSendByte(0xFF) & 0xFF);
508 uid[3] = (FlashSendByte(0xFF) & 0xFF);
509 uid[2] = (FlashSendByte(0xFF) & 0xFF);
510 uid[1] = (FlashSendByte(0xFF) & 0xFF);
511 uid[0] = (FlashSendLastByte(0xFF) & 0xFF);
514 void FlashStop(void) {
515 //Bof
516 //* Reset all the Chip Select register
517 AT91C_BASE_SPI->SPI_CSR[0] = 0;
518 AT91C_BASE_SPI->SPI_CSR[1] = 0;
519 AT91C_BASE_SPI->SPI_CSR[2] = 0;
520 AT91C_BASE_SPI->SPI_CSR[3] = 0;
522 // Reset the SPI mode
523 AT91C_BASE_SPI->SPI_MR = 0;
525 // Disable all interrupts
526 AT91C_BASE_SPI->SPI_IDR = 0xFFFFFFFF;
528 // SPI disable
529 AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIDIS;
531 #ifndef AS_BOOTROM
532 if (g_dbglevel > 3) Dbprintf("FlashStop");
533 #endif // AS_BOOTROM
535 StopTicks();
538 void FlashSetup(uint32_t baudrate) {
539 //WDT_DISABLE
540 AT91C_BASE_WDTC->WDTC_WDMR = AT91C_WDTC_WDDIS;
542 // PA10 -> SPI_NCS2 chip select (FLASHMEM)
543 // PA11 -> SPI_NCS0 chip select (FPGA)
544 // PA12 -> SPI_MISO Master-In Slave-Out
545 // PA13 -> SPI_MOSI Master-Out Slave-In
546 // PA14 -> SPI_SPCK Serial Clock
548 // Disable PIO control of the following pins, allows use by the SPI peripheral
549 AT91C_BASE_PIOA->PIO_PDR |= (GPIO_NCS0 | GPIO_MISO | GPIO_MOSI | GPIO_SPCK | GPIO_NCS2);
551 // Pull-up Enable
552 AT91C_BASE_PIOA->PIO_PPUER |= (GPIO_NCS0 | GPIO_MISO | GPIO_MOSI | GPIO_SPCK | GPIO_NCS2);
554 // Peripheral A
555 AT91C_BASE_PIOA->PIO_ASR |= (GPIO_NCS0 | GPIO_MISO | GPIO_MOSI | GPIO_SPCK);
557 // Peripheral B
558 AT91C_BASE_PIOA->PIO_BSR |= GPIO_NCS2;
560 //enable the SPI Peripheral clock
561 AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_SPI);
564 //reset spi needs double SWRST, see atmel's errata on this case
565 AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST;
566 AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST;
568 // Enable SPI
569 AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIEN;
571 // NPCS2 Mode 0
572 AT91C_BASE_SPI->SPI_MR =
573 (0 << 24) | // Delay between chip selects = DYLBCS/MCK BUT:
574 // If DLYBCS is less than or equal to six, six MCK periods
575 // will be inserted by default.
576 SPI_PCS(SPI_CSR_NUM) | // Peripheral Chip Select (selects SPI_NCS2 or PA10)
577 (0 << 7) | // Disable LLB (1=MOSI2MISO test mode)
578 (1 << 4) | // Disable ModeFault Protection
579 (0 << 3) | // makes spi operate at MCK (1 is MCK/2)
580 (0 << 2) | // Chip selects connected directly to peripheral
581 AT91C_SPI_PS_FIXED | // Fixed Peripheral Select
582 AT91C_SPI_MSTR; // Master Mode
584 uint8_t csaat = 1;
585 uint32_t dlybct = 0;
586 uint8_t ncpha = 1;
587 uint8_t cpol = 0;
588 if (baudrate > FLASH_MINFAST) {
589 baudrate = FLASH_FASTBAUD;
590 //csaat = 0;
591 dlybct = 1500;
592 ncpha = 0;
593 cpol = 0;
596 AT91C_BASE_SPI->SPI_CSR[2] =
597 SPI_DLYBCT(dlybct, MCK) | // Delay between Consecutive Transfers (32 MCK periods)
598 SPI_DLYBS(0, MCK) | // Delay Beforce SPCK CLock
599 SPI_SCBR(baudrate, MCK) | // SPI Baudrate Selection
600 AT91C_SPI_BITS_8 | // Bits per Transfer (8 bits)
601 //AT91C_SPI_CSAAT | // Chip Select inactive after transfer
602 // 40.4.6.2 SPI: Bad tx_ready Behavior when CSAAT = 1 and SCBR = 1
603 // If the SPI is programmed with CSAAT = 1, SCBR(baudrate) = 1 and two transfers are performed consecutively on
604 // the same slave with an IDLE state between them, the tx_ready signal does not rise after the second data has been
605 // transferred in the shifter. This can imply for example, that the second data is sent twice.
606 // COLIN :: For now we STILL use CSAAT=1 to avoid having to (de)assert NPCS manually via PIO lines and we deal with delay
607 (csaat << 3) |
608 /* Spi modes:
609 Mode CPOL CPHA NCPHA
610 0 0 0 1 clock normally low read on rising edge
611 1 0 1 0 clock normally low read on falling edge
612 2 1 0 1 clock normally high read on falling edge
613 3 1 1 0 clock normally high read on rising edge
614 However, page 512 of the AT91SAM7Sx datasheet say "Note that in SPI
615 master mode the ATSAM7S512/256/128/64/321/32 does not sample the data
616 (MISO) on the opposite edge where data clocks out (MOSI) but the same
617 edge is used as shown in Figure 36-3 and Figure 36-4." Figure 36-3
618 shows that CPOL=NCPHA=0 or CPOL=NCPHA=1 samples on the rising edge and
619 that the data changes sometime after the rising edge (about 2 ns). To
620 be consistent with normal SPI operation, it is probably safe to say
621 that the data changes on the falling edge and should be sampled on the
622 rising edge. Therefore, it appears that NCPHA should be treated the
623 same as CPHA. Thus:
624 Mode CPOL CPHA NCPHA
625 0 0 0 0 clock normally low read on rising edge
626 1 0 1 1 clock normally low read on falling edge
627 2 1 0 0 clock normally high read on falling edge
628 3 1 1 1 clock normally high read on rising edge
629 Update: for 24MHz, writing is more stable with ncpha=1, else bitflips occur.
631 (ncpha << 1) | // Clock Phase data captured on leading edge, changes on following edge
632 (cpol << 0); // Clock Polarity inactive state is logic 0
634 // read first, empty buffer
635 if (AT91C_BASE_SPI->SPI_RDR == 0) {};
638 bool Flash_CheckBusy(uint32_t timeout) {
639 WaitUS(WINBOND_WRITE_DELAY);
640 StartCountUS();
641 uint32_t _time = GetCountUS();
643 do {
644 if (!(Flash_ReadStat1() & BUSY)) {
645 return false;
647 } while ((GetCountUS() - _time) < timeout);
649 if (timeout <= (GetCountUS() - _time)) {
650 return true;
653 return false;
656 // read state register 1
657 uint8_t Flash_ReadStat1(void) {
658 FlashSendByte(READSTAT1);
659 return FlashSendLastByte(0xFF);
662 // send one byte over SPI
663 uint16_t FlashSendByte(uint32_t data) {
665 // wait until SPI is ready for transfer
666 //if you are checking for incoming data returned then the TXEMPTY flag is redundant
667 //while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0) {};
669 // send the data
670 AT91C_BASE_SPI->SPI_TDR = data;
672 //while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TDRE) == 0){};
674 // wait receive transfer is complete
675 while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_RDRF) == 0) {};
677 // reading incoming data
678 return ((AT91C_BASE_SPI->SPI_RDR) & 0xFFFF);
681 // send last byte over SPI
682 uint16_t FlashSendLastByte(uint32_t data) {
683 return FlashSendByte(data | AT91C_SPI_LASTXFER);