Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions ports/atmel-samd/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -217,9 +217,6 @@ endif

SRC_ASF := $(addprefix asf4/$(CHIP_FAMILY)/, $(SRC_ASF))

# Skip this source for now.
# shared_dma.c \

SRC_C = \
background.c \
fatfs_port.c \
Expand All @@ -229,6 +226,7 @@ SRC_C = \
$(CHIP_FAMILY)_peripherals.c \
peripherals.c \
$(CHIP_FAMILY)_pins.c \
shared_dma.c \
tick.c \
timers.c \
usb.c \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#define MICROPY_HW_APA102_MOSI (&pin_PA01)
#define MICROPY_HW_APA102_SCK (&pin_PA00)

// Salae reads 12mhz which is the limit even though we set it to the safer 8mhz.
// Saleae reads 12mhz which is the limit even though we set it to the safer 8mhz.
#define SPI_FLASH_BAUDRATE (8000000)

#define SPI_FLASH_MOSI_PIN PIN_PB22
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

#define MICROPY_HW_NEOPIXEL (&pin_PB17)

#define SPI_FLASH_BAUDRATE (8000000)
#define SPI_FLASH_BAUDRATE (60000000)

// Rev B: single channel SPI
// Rev C will be QSPI
Expand Down
40 changes: 20 additions & 20 deletions ports/atmel-samd/common-hal/busio/SPI.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@

#include "peripherals.h"
#include "pins.h"
//#include "shared_dma.h"
#include "shared_dma.h"

void common_hal_busio_spi_construct(busio_spi_obj_t *self,
const mcu_pin_obj_t * clock, const mcu_pin_obj_t * mosi,
Expand Down Expand Up @@ -113,15 +113,15 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self,

// Set up SPI clocks on SERCOM.
samd_peripherals_sercom_clock_init(sercom, sercom_index);

#if defined(MICROPY_HW_APA102_SCK) && defined(MICROPY_HW_APA102_MOSI) && !defined(CIRCUITPY_BITBANG_APA102)
// if we're re-using the dotstar sercom, make sure it is disabled or the init will fail out
hri_sercomspi_clear_CTRLA_ENABLE_bit(sercom);
#endif
if (spi_m_sync_init(&self->spi_desc, sercom) != ERR_NONE) {
mp_raise_OSError(MP_EIO);
}

// Pads must be set after spi_m_sync_init(), which uses default values from
// the prototypical SERCOM.
hri_sercomspi_write_CTRLA_DOPO_bf(sercom, dopo);
Expand All @@ -135,7 +135,7 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self,
// busy or not
mp_raise_OSError(MP_EIO);
}

gpio_set_pin_direction(clock->pin, GPIO_DIRECTION_OUT);
gpio_set_pin_pull_mode(clock->pin, GPIO_PULL_OFF);
gpio_set_pin_function(clock->pin, clock_pinmux);
Expand Down Expand Up @@ -194,7 +194,7 @@ bool common_hal_busio_spi_configure(busio_spi_obj_t *self,
return true;
}

// Disable, set values (most or all are enable-protected), and re-enable.
// Disable, set values (most or all are enable-protected), and re-enable.
spi_m_sync_disable(&self->spi_desc);
hri_sercomspi_wait_for_sync(hw, SERCOM_SPI_SYNCBUSY_MASK);

Expand Down Expand Up @@ -235,14 +235,14 @@ bool common_hal_busio_spi_write(busio_spi_obj_t *self,
return true;
}
int32_t status;
// if (len >= 16) {
// status = shared_dma_write(self->spi_desc.dev.prvt, data, len);
// } else {
if (len >= 16) {
status = sercom_dma_write(self->spi_desc.dev.prvt, data, len);
} else {
struct io_descriptor *spi_io;
spi_m_sync_get_io_descriptor(&self->spi_desc, &spi_io);
status = spi_io->write(spi_io, data, len);
// }
return status >= 0; // Status is number of chars read or an error code < 0.
}
return status >= 0; // Status is number of chars read or an error code < 0.
}

bool common_hal_busio_spi_read(busio_spi_obj_t *self,
Expand All @@ -251,34 +251,34 @@ bool common_hal_busio_spi_read(busio_spi_obj_t *self,
return true;
}
int32_t status;
// if (len >= 16) {
// status = shared_dma_read(self->spi_desc.dev.prvt, data, len, write_value);
// } else {
if (len >= 16) {
status = sercom_dma_read(self->spi_desc.dev.prvt, data, len, write_value);
} else {
self->spi_desc.dev.dummy_byte = write_value;

struct io_descriptor *spi_io;
spi_m_sync_get_io_descriptor(&self->spi_desc, &spi_io);

status = spi_io->read(spi_io, data, len);
// }
return status >= 0; // Status is number of chars read or an error code < 0.
}
return status >= 0; // Status is number of chars read or an error code < 0.
}

bool common_hal_busio_spi_transfer(busio_spi_obj_t *self, uint8_t *data_out, uint8_t *data_in, size_t len) {
if (len == 0) {
return true;
}
int32_t status;
// if (len >= 16) {
// status = shared_dma_transfer(self->spi_master_instance.hw, data_out, data_in, len, 0 /*ignored*/);
// } else {
if (len >= 16) {
status = sercom_dma_transfer(self->spi_desc.dev.prvt, data_out, data_in, len);
} else {
struct spi_xfer xfer;
xfer.txbuf = data_out;
xfer.rxbuf = data_in;
xfer.size = len;
status = spi_m_sync_transfer(&self->spi_desc, &xfer);
// }
return status >= 0; // Status is number of chars read or an error code < 0.
}
return status >= 0; // Status is number of chars read or an error code < 0.
}

uint32_t common_hal_busio_spi_get_frequency(busio_spi_obj_t* self) {
Expand Down
2 changes: 0 additions & 2 deletions ports/atmel-samd/external_flash/external_flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,6 @@ void external_flash_init(void) {

spi_flash_init();


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};
Expand All @@ -213,7 +212,6 @@ void external_flash_init(void) {
}

if (flash_device == NULL) {
asm("bkpt");
return;
}

Expand Down
12 changes: 10 additions & 2 deletions ports/atmel-samd/external_flash/qspi_flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <string.h>

#include "external_flash/common_commands.h"
#include "shared_dma.h"

#include "atmel_start_pins.h"
#include "hal_gpio.h"
Expand Down Expand Up @@ -125,6 +126,8 @@ bool spi_flash_write_data(uint32_t address, uint8_t* data, uint32_t length) {
QSPI_INSTRFRAME_DATAEN;

memcpy(((uint8_t *) QSPI_AHB) + address, data, length);
// TODO(tannewt): Fix DMA and enable it.
// qspi_dma_write(address, data, length);

QSPI->CTRLA.reg = QSPI_CTRLA_ENABLE | QSPI_CTRLA_LASTXFER;

Expand All @@ -148,6 +151,8 @@ bool spi_flash_read_data(uint32_t address, uint8_t* data, uint32_t length) {
QSPI_INSTRFRAME_DUMMYLEN(8);

memcpy(data, ((uint8_t *) QSPI_AHB) + address, length);
// TODO(tannewt): Fix DMA and enable it.
// qspi_dma_read(address, data, length);

QSPI->CTRLA.reg = QSPI_CTRLA_ENABLE | QSPI_CTRLA_LASTXFER;

Expand All @@ -167,12 +172,15 @@ void spi_flash_init(void) {
QSPI->CTRLA.reg = QSPI_CTRLA_SWRST;
// We don't need to wait because we're running as fast as the CPU.

QSPI->BAUD.bit.BAUD = 1;
// Slow, good for debugging with Saleae
// QSPI->BAUD.bit.BAUD = 32;
// Super fast
QSPI->BAUD.bit.BAUD = 2;
QSPI->CTRLB.reg = QSPI_CTRLB_MODE_MEMORY |
QSPI_CTRLB_DATALEN_8BITS |
QSPI_CTRLB_CSMODE_LASTXFER;

QSPI->CTRLA.bit.ENABLE = 1;
QSPI->CTRLA.reg = QSPI_CTRLA_ENABLE;

// The QSPI is only connected to one set of pins in the SAMD51 so we can hard code it.
uint32_t pins[6] = {PIN_PA08, PIN_PA09, PIN_PA10, PIN_PA11, PIN_PB10, PIN_PB11};
Expand Down
19 changes: 17 additions & 2 deletions ports/atmel-samd/external_flash/spi_flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

#include "external_flash/common_commands.h"
#include "peripherals.h"
#include "shared_dma.h"

#include "hal_gpio.h"
#include "hal_spi_m_sync.h"
Expand Down Expand Up @@ -91,14 +92,28 @@ bool spi_flash_write_data(uint32_t address, uint8_t* data, uint32_t data_length)
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, request + 1);
return transfer(request, 4, data, NULL, data_length);
struct spi_xfer xfer = { request, NULL, 4 };
flash_enable();
int32_t status = spi_m_sync_transfer(&spi_flash_desc, &xfer);
if (status >= 0) {
status = sercom_dma_write(spi_flash_desc.dev.prvt, data, data_length);
}
flash_disable();
return status >= 0;
}

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);
struct spi_xfer xfer = { request, NULL, 4 };
flash_enable();
int32_t status = spi_m_sync_transfer(&spi_flash_desc, &xfer);
if (status >= 0) {
status = sercom_dma_read(spi_flash_desc.dev.prvt, data, data_length, 0xff);
}
flash_disable();
return status >= 0;
}

void spi_flash_init(void) {
Expand Down
Loading