3232#include "mpconfigboard.h" // for EXTERNAL_FLASH_QSPI_DUAL
3333
3434#include "external_flash/common_commands.h"
35+ #include "peripherals.h"
3536#include "shared_dma.h"
3637
3738#include "atmel_start_pins.h"
@@ -55,6 +56,8 @@ bool spi_flash_command(uint8_t command) {
5556}
5657
5758bool spi_flash_read_command (uint8_t command , uint8_t * response , uint32_t length ) {
59+ samd_peripherals_disable_and_clear_cache ();
60+
5861 QSPI -> INSTRCTRL .bit .INSTR = command ;
5962
6063 QSPI -> INSTRFRAME .reg = QSPI_INSTRFRAME_WIDTH_SINGLE_BIT_SPI |
@@ -63,6 +66,11 @@ bool spi_flash_read_command(uint8_t command, uint8_t* response, uint32_t length)
6366 QSPI_INSTRFRAME_INSTREN |
6467 QSPI_INSTRFRAME_DATAEN ;
6568
69+ // Dummy read of INSTRFRAME needed to synchronize.
70+ // See Instruction Transmission Flow Diagram, figure 37.9, page 995
71+ // and Example 4, page 998, section 37.6.8.5.
72+ (volatile uint32_t ) QSPI -> INSTRFRAME .reg ;
73+
6674 memcpy (response , (uint8_t * ) QSPI_AHB , length );
6775
6876 QSPI -> CTRLA .reg = QSPI_CTRLA_ENABLE | QSPI_CTRLA_LASTXFER ;
@@ -71,20 +79,28 @@ bool spi_flash_read_command(uint8_t command, uint8_t* response, uint32_t length)
7179
7280 QSPI -> INTFLAG .reg = QSPI_INTFLAG_INSTREND ;
7381
82+ samd_peripherals_enable_cache ();
83+
7484 return true;
7585}
7686
7787bool spi_flash_write_command (uint8_t command , uint8_t * data , uint32_t length ) {
88+ samd_peripherals_disable_and_clear_cache ();
89+
7890 QSPI -> INSTRCTRL .bit .INSTR = command ;
7991
8092 QSPI -> INSTRFRAME .reg = QSPI_INSTRFRAME_WIDTH_SINGLE_BIT_SPI |
8193 QSPI_INSTRFRAME_ADDRLEN_24BITS |
8294 QSPI_INSTRFRAME_TFRTYPE_WRITE |
83- QSPI_INSTRFRAME_INSTREN ;
95+ QSPI_INSTRFRAME_INSTREN |
96+ (data != NULL ? QSPI_INSTRFRAME_DATAEN : 0 );
8497
85- if (data != NULL ) {
86- QSPI -> INSTRFRAME .bit .DATAEN = true;
98+ // Dummy read of INSTRFRAME needed to synchronize.
99+ // See Instruction Transmission Flow Diagram, figure 37.9, page 995
100+ // and Example 4, page 998, section 37.6.8.5.
101+ (volatile uint32_t ) QSPI -> INSTRFRAME .reg ;
87102
103+ if (data != NULL ) {
88104 memcpy ((uint8_t * ) QSPI_AHB , data , length );
89105 }
90106
@@ -94,6 +110,8 @@ bool spi_flash_write_command(uint8_t command, uint8_t* data, uint32_t length) {
94110
95111 QSPI -> INTFLAG .reg = QSPI_INTFLAG_INSTREND ;
96112
113+ samd_peripherals_enable_cache ();
114+
97115 return true;
98116}
99117
@@ -117,6 +135,8 @@ bool spi_flash_sector_command(uint8_t command, uint32_t address) {
117135}
118136
119137bool spi_flash_write_data (uint32_t address , uint8_t * data , uint32_t length ) {
138+ samd_peripherals_disable_and_clear_cache ();
139+
120140 QSPI -> INSTRCTRL .bit .INSTR = CMD_PAGE_PROGRAM ;
121141 uint32_t mode = QSPI_INSTRFRAME_WIDTH_SINGLE_BIT_SPI ;
122142
@@ -137,10 +157,14 @@ bool spi_flash_write_data(uint32_t address, uint8_t* data, uint32_t length) {
137157
138158 QSPI -> INTFLAG .reg = QSPI_INTFLAG_INSTREND ;
139159
160+ samd_peripherals_enable_cache ();
161+
140162 return true;
141163}
142164
143165bool spi_flash_read_data (uint32_t address , uint8_t * data , uint32_t length ) {
166+ samd_peripherals_disable_and_clear_cache ();
167+
144168 #ifdef EXTERNAL_FLASH_QSPI_DUAL
145169 QSPI -> INSTRCTRL .bit .INSTR = CMD_DUAL_READ ;
146170 uint32_t mode = QSPI_INSTRFRAME_WIDTH_DUAL_OUTPUT ;
@@ -167,6 +191,8 @@ bool spi_flash_read_data(uint32_t address, uint8_t* data, uint32_t length) {
167191
168192 QSPI -> INTFLAG .reg = QSPI_INTFLAG_INSTREND ;
169193
194+ samd_peripherals_enable_cache ();
195+
170196 return true;
171197}
172198
@@ -183,7 +209,7 @@ void spi_flash_init(void) {
183209 // QSPI->BAUD.bit.BAUD = 32;
184210 // Super fast, may be unreliable when Saleae is connected to high speed lines.
185211 QSPI -> BAUD .bit .BAUD = 2 ;
186- QSPI -> CTRLB .reg = QSPI_CTRLB_MODE_MEMORY |
212+ QSPI -> CTRLB .reg = QSPI_CTRLB_MODE_MEMORY | // Serial memory mode (map to QSPI_AHB)
187213 QSPI_CTRLB_DATALEN_8BITS |
188214 QSPI_CTRLB_CSMODE_LASTXFER ;
189215
0 commit comments