diff --git a/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h index b541af80c9..e2b7f9982e 100644 --- a/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h @@ -3,18 +3,18 @@ #define CIRCUITPY_MCU_FAMILY samd51 -// This is for Rev D which is light blue +// This is for Rev F which is green #define MICROPY_HW_LED_TX PIN_PA27 #define MICROPY_HW_LED_RX PIN_PB06 -#define MICROPY_HW_NEOPIXEL (&pin_PB17) +#define MICROPY_HW_NEOPIXEL (&pin_PB22) // These are pins not to reset. // QSPI Data pins and TX LED #define MICROPY_PORT_A (PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11 | PORT_PA27) // RX LED, QSPI CS, QSPI SCK and NeoPixel pin -#define MICROPY_PORT_B ( PORT_PB06 | PORT_PB10 | PORT_PB11 | PORT_PB17) +#define MICROPY_PORT_B ( PORT_PB06 | PORT_PB10 | PORT_PB11 | PORT_PB22) #define MICROPY_PORT_C (0) #define MICROPY_PORT_D (0) diff --git a/ports/atmel-samd/boards/metro_m4_express/pins.c b/ports/atmel-samd/boards/metro_m4_express/pins.c index 33b69b32b3..32ecdf4923 100644 --- a/ports/atmel-samd/boards/metro_m4_express/pins.c +++ b/ports/atmel-samd/boards/metro_m4_express/pins.c @@ -7,36 +7,37 @@ STATIC const mp_map_elem_t board_global_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_A0), (mp_obj_t)&pin_PA02 }, { MP_OBJ_NEW_QSTR(MP_QSTR_A1), (mp_obj_t)&pin_PA05 }, { MP_OBJ_NEW_QSTR(MP_QSTR_A2), (mp_obj_t)&pin_PA06 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_A3), (mp_obj_t)&pin_PB09 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A3), (mp_obj_t)&pin_PA04 }, { MP_OBJ_NEW_QSTR(MP_QSTR_A4), (mp_obj_t)&pin_PB08 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_A5), (mp_obj_t)&pin_PA07 }, - + { MP_OBJ_NEW_QSTR(MP_QSTR_A5), (mp_obj_t)&pin_PB09 }, { MP_OBJ_NEW_QSTR(MP_QSTR_D0), (mp_obj_t)&pin_PA23 }, { MP_OBJ_NEW_QSTR(MP_QSTR_RX), (mp_obj_t)&pin_PA23 }, { MP_OBJ_NEW_QSTR(MP_QSTR_D1), (mp_obj_t)&pin_PA22 }, { MP_OBJ_NEW_QSTR(MP_QSTR_TX), (mp_obj_t)&pin_PA22 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D2), (mp_obj_t)&pin_PA04 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D2), (mp_obj_t)&pin_PB17 }, { MP_OBJ_NEW_QSTR(MP_QSTR_D3), (mp_obj_t)&pin_PB16 }, { MP_OBJ_NEW_QSTR(MP_QSTR_D4), (mp_obj_t)&pin_PB13 }, { MP_OBJ_NEW_QSTR(MP_QSTR_D5), (mp_obj_t)&pin_PB14 }, { MP_OBJ_NEW_QSTR(MP_QSTR_D6), (mp_obj_t)&pin_PB15 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D7), (mp_obj_t)&pin_PA14 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D8), (mp_obj_t)&pin_PA16 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D9), (mp_obj_t)&pin_PA17 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D7), (mp_obj_t)&pin_PB12 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D8), (mp_obj_t)&pin_PA21 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D9), (mp_obj_t)&pin_PA20 }, { MP_OBJ_NEW_QSTR(MP_QSTR_D10), (mp_obj_t)&pin_PA18 }, { MP_OBJ_NEW_QSTR(MP_QSTR_D11), (mp_obj_t)&pin_PA19 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D12), (mp_obj_t)&pin_PA20 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D13), (mp_obj_t)&pin_PA21 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D12), (mp_obj_t)&pin_PA17 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D13), (mp_obj_t)&pin_PA16 }, { MP_OBJ_NEW_QSTR(MP_QSTR_SDA), (mp_obj_t)&pin_PB02 }, { MP_OBJ_NEW_QSTR(MP_QSTR_SCL), (mp_obj_t)&pin_PB03 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), (mp_obj_t)&pin_PB17 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_AREF), (mp_obj_t)&pin_PA03 }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), (mp_obj_t)&pin_PB22 }, { MP_OBJ_NEW_QSTR(MP_QSTR_SCK), (mp_obj_t)&pin_PA13 }, { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI), (mp_obj_t)&pin_PA12 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MISO), (mp_obj_t)&pin_PA15 }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MISO), (mp_obj_t)&pin_PA14 }, { MP_OBJ_NEW_QSTR(MP_QSTR_LED_RX), (mp_obj_t)&pin_PB06 }, { MP_OBJ_NEW_QSTR(MP_QSTR_LED_TX), (mp_obj_t)&pin_PA27 }, diff --git a/ports/atmel-samd/external_flash/common_commands.h b/ports/atmel-samd/external_flash/common_commands.h index fc05e70de7..79178af9cb 100644 --- a/ports/atmel-samd/external_flash/common_commands.h +++ b/ports/atmel-samd/external_flash/common_commands.h @@ -35,7 +35,10 @@ #define CMD_PAGE_PROGRAM 0x02 // #define CMD_PAGE_PROGRAM CMD_READ_JEDEC_ID #define CMD_READ_STATUS 0x05 +#define CMD_READ_STATUS2 0x35 #define CMD_WRITE_STATUS_BYTE1 0x01 #define CMD_QUAD_READ 0x6b +#define CMD_ENABLE_RESET 0x66 +#define CMD_RESET 0x99 #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 304bf6462b..315eb7506f 100644 --- a/ports/atmel-samd/external_flash/external_flash.c +++ b/ports/atmel-samd/external_flash/external_flash.c @@ -199,10 +199,15 @@ void external_flash_init(void) { spi_flash_init(); + // The response will be 0xff if the flash needs more time to start up. + uint8_t jedec_id_response[3] = {0xff, 0xff, 0xff}; + while (jedec_id_response[0] == 0xff) { + spi_flash_read_command(CMD_READ_JEDEC_ID, jedec_id_response, 3); + } + for (uint8_t i = 0; i < num_possible_devices; i++) { const external_flash_device* possible_device = &possible_devices[i]; - uint8_t jedec_id_response[3] = {0x00, 0x00, 0x00}; - spi_flash_read_command(CMD_READ_JEDEC_ID, jedec_id_response, 3); + if (jedec_id_response[0] == possible_device->manufacturer_id && jedec_id_response[1] == possible_device->memory_type && jedec_id_response[2] == possible_device->capacity) { @@ -215,6 +220,26 @@ void external_flash_init(void) { return; } + // We don't know what state the flash is in so wait for any remaining writes and then reset. + uint8_t read_status_response[1] = {0x00}; + // The write in progress bit should be low. + do { + spi_flash_read_command(CMD_READ_STATUS, read_status_response, 1); + } while ((read_status_response[0] & 0x1) != 0); + // The suspended write/erase bit should be low. + do { + spi_flash_read_command(CMD_READ_STATUS2, read_status_response, 1); + } while ((read_status_response[0] & 0x80) != 0); + + + spi_flash_command(CMD_ENABLE_RESET); + spi_flash_command(CMD_RESET); + + // Wait 30us for the reset + common_hal_mcu_delay_us(30); + + spi_flash_init_device(flash_device); + // Activity LED for flash writes. #ifdef MICROPY_HW_LED_MSC gpio_set_pin_function(SPI_FLASH_CS_PIN, GPIO_PIN_FUNCTION_OFF); diff --git a/ports/atmel-samd/external_flash/qspi_flash.c b/ports/atmel-samd/external_flash/qspi_flash.c index 46e3cb92a3..4ebe30a909 100644 --- a/ports/atmel-samd/external_flash/qspi_flash.c +++ b/ports/atmel-samd/external_flash/qspi_flash.c @@ -189,14 +189,17 @@ void spi_flash_init(void) { gpio_set_pin_pull_mode(pins[i], GPIO_PULL_OFF); gpio_set_pin_function(pins[i], GPIO_PIN_FUNCTION_H); } +} +void spi_flash_init_device(const external_flash_device* device) { // Verify that QSPI mode is enabled. uint8_t status; - spi_flash_read_command(0x35, &status, 1); + spi_flash_read_command(CMD_READ_STATUS2, &status, 1); + // Bit 1 is Quad Enable if ((status & 0x2) == 0) { - uint8_t full_status[3] = { 0, status | 0x2, 0x70}; + uint8_t full_status[2] = { 0x0, 0x2}; spi_flash_command(CMD_ENABLE_WRITE); - spi_flash_write_command(0x01, full_status, 3); + spi_flash_write_command(CMD_WRITE_STATUS_BYTE1, full_status, 2); } } diff --git a/ports/atmel-samd/external_flash/spi_flash.c b/ports/atmel-samd/external_flash/spi_flash.c index fcaedcaaca..8a8cbaef81 100644 --- a/ports/atmel-samd/external_flash/spi_flash.c +++ b/ports/atmel-samd/external_flash/spi_flash.c @@ -152,3 +152,7 @@ void spi_flash_init(void) { spi_m_sync_enable(&spi_flash_desc); } + +void spi_flash_init_device(const external_flash_device* device) { + +} diff --git a/ports/atmel-samd/external_flash/spi_flash_api.h b/ports/atmel-samd/external_flash/spi_flash_api.h index b858ff0ea0..a6df0c4595 100644 --- a/ports/atmel-samd/external_flash/spi_flash_api.h +++ b/ports/atmel-samd/external_flash/spi_flash_api.h @@ -29,6 +29,8 @@ #include #include +#include "external_flash/devices.h" + // This API is implemented for both normal SPI peripherals and QSPI peripherals. bool spi_flash_command(uint8_t command); @@ -38,5 +40,6 @@ bool spi_flash_sector_command(uint8_t command, uint32_t address); bool spi_flash_write_data(uint32_t address, uint8_t* data, uint32_t data_length); bool spi_flash_read_data(uint32_t address, uint8_t* data, uint32_t data_length); void spi_flash_init(void); +void spi_flash_init_device(const external_flash_device* device); #endif // MICROPY_INCLUDED_ATMEL_SAMD_SPI_FLASH_H