m4 qspi works. m0 compiles

This commit is contained in:
Scott Shawcroft 2018-02-17 00:29:03 -08:00
parent f20d5723aa
commit 15f626be58
12 changed files with 121 additions and 62 deletions

View File

@ -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

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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)

View File

@ -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"

View File

@ -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"

View File

@ -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

View File

@ -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;

View File

@ -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;
}

View File

@ -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) {