summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Shawcroft <scott.shawcroft@gmail.com>2018-02-17 00:29:03 -0800
committerScott Shawcroft <scott.shawcroft@gmail.com>2018-02-19 14:02:04 -0800
commit15f626be5869a2dc5d8bc53ad44cc678bb5462d2 (patch)
tree3048ba889da33fd19e517fc716666cbdbb7e9299
parentf20d5723aab3e6b5eea316235767c5e28a2dac2d (diff)
m4 qspi works. m0 compiles
-rw-r--r--ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h6
-rw-r--r--ports/atmel-samd/boards/feather_m0_express/mpconfigboard.h6
-rw-r--r--ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.h4
-rw-r--r--ports/atmel-samd/boards/itsybitsy_m0/mpconfigboard.h8
-rw-r--r--ports/atmel-samd/boards/metro_m0_express/mpconfigboard.h6
-rw-r--r--ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h4
-rw-r--r--ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.h4
-rw-r--r--ports/atmel-samd/boards/ugame10/mpconfigboard.h6
-rw-r--r--ports/atmel-samd/external_flash/common_commands.h1
-rw-r--r--ports/atmel-samd/external_flash/external_flash.c15
-rw-r--r--ports/atmel-samd/external_flash/qspi_flash.c65
-rw-r--r--ports/atmel-samd/external_flash/spi_flash.c58
12 files changed, 121 insertions, 62 deletions
diff --git a/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h b/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h
index 2b8fed6b8..cc09d7f79 100644
--- a/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h
+++ b/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h
@@ -38,7 +38,7 @@
#define SPEAKER_ENABLE_PIN (&pin_PA30)
-#include "external_flash.h"
+#include "external_flash/external_flash.h"
// If you change this, then make sure to update the linker scripts as well to
// make sure you don't overwrite code.
@@ -47,8 +47,8 @@
#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE)
-#include "flash_S25FL216K.h"
-#include "flash_GD25Q16C.h"
+#include "external_flash/devices/S25FL216K.h"
+#include "external_flash/devices/GD25Q16C.h"
#define CALIBRATE_CRYSTALLESS 1
diff --git a/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.h b/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.h
index d0e70d954..378b0891a 100644
--- a/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.h
+++ b/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.h
@@ -31,7 +31,7 @@
#define MICROPY_PORT_B ( 0 )
#define MICROPY_PORT_C ( 0 )
-#include "external_flash.h"
+#include "external_flash/external_flash.h"
// If you change this, then make sure to update the linker scripts as well to
// make sure you don't overwrite code.
@@ -40,5 +40,5 @@
#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE)
-#include "flash_S25FL216K.h"
-#include "flash_GD25Q16C.h"
+#include "external_flash/devices/S25FL216K.h"
+#include "external_flash/devices/GD25Q16C.h"
diff --git a/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.h b/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.h
index 4f9b177be..b5ed68296 100644
--- a/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.h
+++ b/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.h
@@ -33,7 +33,7 @@
#define MICROPY_PORT_B ( 0 )
#define MICROPY_PORT_C ( 0 )
-#include "external_flash.h"
+#include "external_flash/external_flash.h"
// If you change this, then make sure to update the linker scripts as well to
// make sure you don't overwrite code.
@@ -42,4 +42,4 @@
#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE)
-#include "flash_S25FL064L.h"
+#include "external_flash/devices/S25FL064L.h"
diff --git a/ports/atmel-samd/boards/itsybitsy_m0/mpconfigboard.h b/ports/atmel-samd/boards/itsybitsy_m0/mpconfigboard.h
index 116775886..15a992221 100644
--- a/ports/atmel-samd/boards/itsybitsy_m0/mpconfigboard.h
+++ b/ports/atmel-samd/boards/itsybitsy_m0/mpconfigboard.h
@@ -33,7 +33,7 @@
#define MICROPY_PORT_B (PORT_PB22 | PORT_PB23 | PORT_PB03 )
#define MICROPY_PORT_C (0)
-#include "external_flash.h"
+#include "external_flash/external_flash.h"
// If you change this, then make sure to update the linker scripts as well to
// make sure you don't overwrite code.
@@ -41,6 +41,6 @@
#define CIRCUITPY_INTERNAL_NVM_SIZE 0
#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE)
-//#include "flash_S25FL216K.h"
-#include "flash_W25Q80DV.h"
-//#include "flash_GD25Q16C.h"
+//#include "external_flash/devices/S25FL216K.h"
+#include "external_flash/devices/W25Q80DV.h"
+//#include "external_flash/devices/GD25Q16C.h"
diff --git a/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.h b/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.h
index be1a1a57e..70e830620 100644
--- a/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.h
+++ b/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.h
@@ -34,7 +34,7 @@
#define MICROPY_PORT_B (PORT_PB03 | PORT_PB22 | PORT_PB23)
#define MICROPY_PORT_C (0)
-#include "external_flash.h"
+#include "external_flash/external_flash.h"
// If you change this, then make sure to update the linker scripts as well to
// make sure you don't overwrite code.
@@ -43,5 +43,5 @@
#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE)
-#include "flash_S25FL216K.h"
-#include "flash_GD25Q16C.h"
+#include "external_flash/devices/S25FL216K.h"
+#include "external_flash/devices/GD25Q16C.h"
diff --git a/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h
index 6ced2ca70..b8f14e625 100644
--- a/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h
+++ b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h
@@ -33,8 +33,8 @@
#define SPI_FLASH_DIPO 3 // same as MISO pad
// These are pins not to reset.
-#define MICROPY_PORT_A (PORT_PA27)
-#define MICROPY_PORT_B (PORT_PB06 | PORT_PB08 | PORT_PB09 | PORT_PB10 | PORT_PB11 | PORT_PB17)
+#define MICROPY_PORT_A (PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11 | PORT_PA27)
+#define MICROPY_PORT_B (PORT_PB10 | PORT_PB11 | PORT_PB17)
#define MICROPY_PORT_C (0)
#define MICROPY_PORT_D (0)
diff --git a/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.h b/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.h
index 5dcea945a..62bca9a41 100644
--- a/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.h
+++ b/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.h
@@ -40,7 +40,7 @@
#define CALIBRATE_CRYSTALLESS 1
-#include "external_flash.h"
+#include "external_flash/external_flash.h"
// If you change this, then make sure to update the linker scripts as well to
// make sure you don't overwrite code.
@@ -48,4 +48,4 @@
#define CIRCUITPY_INTERNAL_NVM_SIZE 0
#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE)
-#include "flash_W25Q32BV.h"
+#include "external_flash/devices/W25Q32BV.h"
diff --git a/ports/atmel-samd/boards/ugame10/mpconfigboard.h b/ports/atmel-samd/boards/ugame10/mpconfigboard.h
index 3bec61ff9..d0d9296a4 100644
--- a/ports/atmel-samd/boards/ugame10/mpconfigboard.h
+++ b/ports/atmel-samd/boards/ugame10/mpconfigboard.h
@@ -33,7 +33,7 @@
#define CALIBRATE_CRYSTALLESS 1
-#include "external_flash.h"
+#include "external_flash/external_flash.h"
// If you change this, then make sure to update the linker scripts as well to
// make sure you don't overwrite code.
@@ -41,5 +41,5 @@
#define CIRCUITPY_INTERNAL_NVM_SIZE 0
#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE)
-//#include "flash_W25Q32BV.h"
-#include "flash_S25FL216K.h"
+//#include "external_flash/devices/W25Q32BV.h"
+#include "external_flash/devices/S25FL216K.h"
diff --git a/ports/atmel-samd/external_flash/common_commands.h b/ports/atmel-samd/external_flash/common_commands.h
index ca1e87782..fc05e70de 100644
--- a/ports/atmel-samd/external_flash/common_commands.h
+++ b/ports/atmel-samd/external_flash/common_commands.h
@@ -36,5 +36,6 @@
// #define CMD_PAGE_PROGRAM CMD_READ_JEDEC_ID
#define CMD_READ_STATUS 0x05
#define CMD_WRITE_STATUS_BYTE1 0x01
+#define CMD_QUAD_READ 0x6b
#endif // MICROPY_INCLUDED_ATMEL_SAMD_EXTERNAL_FLASH_COMMON_COMMANDS_H
diff --git a/ports/atmel-samd/external_flash/external_flash.c b/ports/atmel-samd/external_flash/external_flash.c
index c046047e4..48872adda 100644
--- a/ports/atmel-samd/external_flash/external_flash.c
+++ b/ports/atmel-samd/external_flash/external_flash.c
@@ -195,19 +195,20 @@ void external_flash_init(void) {
gpio_set_pin_level(MICROPY_HW_LED_MSC, false);
#endif
- uint8_t jedec_id_response[4] = {0x00, 0x00, 0x00, 0x00};
- spi_flash_read_command(CMD_READ_JEDEC_ID, jedec_id_response, 4);
+ uint8_t jedec_id_response[3] = {0x00, 0x00, 0x00};
+ spi_flash_read_command(CMD_READ_JEDEC_ID, jedec_id_response, 3);
- uint8_t manufacturer = jedec_id_response[1];
- if ((jedec_id_response[1] == SPI_FLASH_JEDEC_MANUFACTURER
+ uint8_t manufacturer = jedec_id_response[0];
+ if ((jedec_id_response[0] == SPI_FLASH_JEDEC_MANUFACTURER
#ifdef SPI_FLASH_JEDEC_MANUFACTURER_2
- || jedec_id_response[1] == SPI_FLASH_JEDEC_MANUFACTURER_2
+ || jedec_id_response[0] == SPI_FLASH_JEDEC_MANUFACTURER_2
#endif
) &&
- jedec_id_response[2] == SPI_FLASH_JEDEC_MEMORY_TYPE &&
- jedec_id_response[3] == SPI_FLASH_JEDEC_CAPACITY) {
+ jedec_id_response[1] == SPI_FLASH_JEDEC_MEMORY_TYPE &&
+ jedec_id_response[2] == SPI_FLASH_JEDEC_CAPACITY) {
spi_flash_is_initialised = true;
} else {
+ asm("bkpt");
// Unknown flash chip!
spi_flash_is_initialised = false;
return;
diff --git a/ports/atmel-samd/external_flash/qspi_flash.c b/ports/atmel-samd/external_flash/qspi_flash.c
index 42d4e5a42..d9dc3bf01 100644
--- a/ports/atmel-samd/external_flash/qspi_flash.c
+++ b/ports/atmel-samd/external_flash/qspi_flash.c
@@ -95,23 +95,66 @@ bool spi_flash_write_command(uint8_t command, uint8_t* data, uint32_t length) {
}
bool spi_flash_sector_command(uint8_t command, uint32_t address) {
-// QSPI->INSTRCTRL.bit.INSTR = command;
-// QSPI->INSTRADDR.reg = addr;
-// uint32_t iframe = QSPI->INSTRFRAME.reg;
-//
-// iframe = QSPI_INSTRFRAME_WIDTH(instr->ioFormat) | instr->options |
-// QSPI_INSTRFRAME_OPTCODELEN(instr->opcodeLen) | (instr->addrLen << QSPI_INSTRFRAME_ADDRLEN_Pos) |
-// ( instr->continuousRead << QSPI_INSTRFRAME_CRMODE_Pos) | QSPI_INSTRFRAME_TFRTYPE(instr->type) | QSPI_INSTRFRAME_DUMMYLEN(instr->dummylen);
-//
-// QSPI->INSTRFRAME.reg = iframe;
+ QSPI->INSTRCTRL.bit.INSTR = command;
+ QSPI->INSTRADDR.bit.ADDR = address;
+
+ QSPI->INSTRFRAME.reg = QSPI_INSTRFRAME_WIDTH_SINGLE_BIT_SPI |
+ QSPI_INSTRFRAME_ADDRLEN_24BITS |
+ QSPI_INSTRFRAME_TFRTYPE_WRITE |
+ QSPI_INSTRFRAME_INSTREN |
+ QSPI_INSTRFRAME_ADDREN;
+
+ QSPI->CTRLA.reg = QSPI_CTRLA_ENABLE | QSPI_CTRLA_LASTXFER;
+
+ while( !QSPI->INTFLAG.bit.INSTREND );
+
+ QSPI->INTFLAG.reg = QSPI_INTFLAG_INSTREND;
+
return true;
}
-bool spi_flash_write_data(uint32_t address, uint8_t* data, uint32_t data_length) {
+bool spi_flash_write_data(uint32_t address, uint8_t* data, uint32_t length) {
+ QSPI->INSTRCTRL.bit.INSTR = CMD_PAGE_PROGRAM;
+ uint32_t mode = QSPI_INSTRFRAME_WIDTH_SINGLE_BIT_SPI;
+
+ QSPI->INSTRFRAME.reg = mode |
+ QSPI_INSTRFRAME_ADDRLEN_24BITS |
+ QSPI_INSTRFRAME_TFRTYPE_WRITEMEMORY |
+ QSPI_INSTRFRAME_INSTREN |
+ QSPI_INSTRFRAME_ADDREN |
+ QSPI_INSTRFRAME_DATAEN;
+
+ memcpy(((uint8_t *) QSPI_AHB) + address, data, length);
+
+ QSPI->CTRLA.reg = QSPI_CTRLA_ENABLE | QSPI_CTRLA_LASTXFER;
+
+ while( !QSPI->INTFLAG.bit.INSTREND );
+
+ QSPI->INTFLAG.reg = QSPI_INTFLAG_INSTREND;
+
return true;
}
-bool spi_flash_read_data(uint32_t address, uint8_t* data, uint32_t data_length) {
+bool spi_flash_read_data(uint32_t address, uint8_t* data, uint32_t length) {
+ QSPI->INSTRCTRL.bit.INSTR = CMD_QUAD_READ;
+ uint32_t mode = QSPI_INSTRFRAME_WIDTH_QUAD_OUTPUT;
+
+ QSPI->INSTRFRAME.reg = mode |
+ QSPI_INSTRFRAME_ADDRLEN_24BITS |
+ QSPI_INSTRFRAME_TFRTYPE_READMEMORY |
+ QSPI_INSTRFRAME_INSTREN |
+ QSPI_INSTRFRAME_ADDREN |
+ QSPI_INSTRFRAME_DATAEN |
+ QSPI_INSTRFRAME_DUMMYLEN(8);
+
+ memcpy(data, ((uint8_t *) QSPI_AHB) + address, length);
+
+ QSPI->CTRLA.reg = QSPI_CTRLA_ENABLE | QSPI_CTRLA_LASTXFER;
+
+ while( !QSPI->INTFLAG.bit.INSTREND );
+
+ QSPI->INTFLAG.reg = QSPI_INTFLAG_INSTREND;
+
return true;
}
diff --git a/ports/atmel-samd/external_flash/spi_flash.c b/ports/atmel-samd/external_flash/spi_flash.c
index 9695067f1..4b63132ee 100644
--- a/ports/atmel-samd/external_flash/spi_flash.c
+++ b/ports/atmel-samd/external_flash/spi_flash.c
@@ -23,11 +23,12 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-#include "spi_flash.h"
+#include "spi_flash_api.h"
#include <stdint.h>
#include <string.h>
+#include "external_flash/common_commands.h"
#include "peripherals.h"
#include "hal_gpio.h"
@@ -45,11 +46,32 @@ static void flash_disable(void) {
gpio_set_pin_level(SPI_FLASH_CS_PIN, true);
}
-void spi_flash_command(uint8_t* request, uint8_t* response, uint32_t length) {
- struct spi_xfer xfer = { request, response, length };
+static bool transfer(uint8_t* command, uint32_t command_length, uint8_t* data_in, uint8_t* data_out, uint32_t data_length) {
+ struct spi_xfer xfer = { command, NULL, command_length };
flash_enable();
- spi_m_sync_transfer(&spi_flash_desc, &xfer);
+ int32_t status = spi_m_sync_transfer(&spi_flash_desc, &xfer);
+ if (status >= 0 && !(data_in == NULL && data_out == NULL)) {
+ struct spi_xfer data_xfer = {data_in, data_out, data_length};
+ status = spi_m_sync_transfer(&spi_flash_desc, &data_xfer);
+ }
flash_disable();
+ return status >= 0;
+}
+
+static bool transfer_command(uint8_t command, uint8_t* data_in, uint8_t* data_out, uint32_t data_length) {
+ return transfer(&command, 1, data_in, data_out, data_length);
+}
+
+bool spi_flash_command(uint8_t command) {
+ return transfer_command(command, NULL, NULL, 0);
+}
+
+bool spi_flash_read_command(uint8_t command, uint8_t* data, uint32_t data_length) {
+ return transfer_command(command, NULL, data, data_length);
+}
+
+bool spi_flash_write_command(uint8_t command, uint8_t* data, uint32_t data_length) {
+ return transfer_command(command, data, NULL, data_length);
}
// Pack the low 24 bits of the address into a uint8_t array.
@@ -59,32 +81,24 @@ static void address_to_bytes(uint32_t address, uint8_t* bytes) {
bytes[2] = address & 0xff;
}
-void spi_flash_sector_command(uint8_t command, uint32_t address) {
+bool spi_flash_sector_command(uint8_t command, uint32_t address) {
uint8_t request[4] = {command, 0x00, 0x00, 0x00};
- address_to_bytes(address, page_program_request + 1);
- struct spi_xfer xfer = { request, NULL, 4 };
- flash_enable();
- spi_m_sync_transfer(&spi_flash_desc, &xfer);
- flash_disable();
+ address_to_bytes(address, request + 1);
+ return transfer(request, 4, NULL, NULL, 0);
}
bool spi_flash_write_data(uint32_t address, uint8_t* data, uint32_t data_length) {
- flash_enable();
- uint8_t page_program_request[4] = {CMD_PAGE_PROGRAM, 0x00, 0x00, 0x00};
+ uint8_t request[4] = {CMD_PAGE_PROGRAM, 0x00, 0x00, 0x00};
// Write the SPI flash write address into the bytes following the command byte.
- address_to_bytes(address, page_program_request + 1);
- struct spi_xfer page_program_xfer = {request, 0, request_length};
- int32_t status = spi_m_sync_transfer(&spi_flash_desc, &page_program_xfer);
- if (status >= 0) {
- struct spi_xfer write_data_buffer_xfer = {data, 0, data_length};
- status = spi_m_sync_transfer(&spi_flash_desc, &write_data_buffer_xfer);
- }
- flash_disable();
- return status >= 0;
+ address_to_bytes(address, request + 1);
+ return transfer(request, 4, data, NULL, data_length);
}
bool spi_flash_read_data(uint32_t address, uint8_t* data, uint32_t data_length) {
-
+ uint8_t request[4] = {CMD_READ_DATA, 0x00, 0x00, 0x00};
+ // Write the SPI flash write address into the bytes following the command byte.
+ address_to_bytes(address, request + 1);
+ return transfer(request, 4, NULL, data, data_length);
}
void spi_flash_init(void) {