atmel-samd: Use DMA for user SPI.

Also replace use of PINMUX_DEFAULT with PINMUX_UNUSED to prevent any
accidental pin changes. This caused user SPI to break internal SPI
flash on the Feather M0 Express.

Fixes #100
This commit is contained in:
Scott Shawcroft 2017-05-03 10:50:29 -07:00
parent 24a5752f94
commit 6512ccf32e
4 changed files with 22 additions and 13 deletions

View File

@ -12,13 +12,13 @@
// Rev B:
// #define SPI_FLASH_PAD0_PINMUX PINMUX_PA12D_SERCOM4_PAD0 // MISO
// #define SPI_FLASH_PAD1_PINMUX PINMUX_DEFAULT // CS
// #define SPI_FLASH_PAD1_PINMUX PINMUX_UNUSED // CS
// #define SPI_FLASH_PAD2_PINMUX PINMUX_PB10D_SERCOM4_PAD2 // MOSI
// #define SPI_FLASH_PAD3_PINMUX PINMUX_PB11D_SERCOM4_PAD3 // SCK
// Rev C:
#define SPI_FLASH_PAD0_PINMUX PINMUX_PA16D_SERCOM3_PAD0 // MISO
#define SPI_FLASH_PAD1_PINMUX PINMUX_DEFAULT // CS
#define SPI_FLASH_PAD1_PINMUX PINMUX_UNUSED // CS
#define SPI_FLASH_PAD2_PINMUX PINMUX_PA20D_SERCOM3_PAD2 // MOSI
#define SPI_FLASH_PAD3_PINMUX PINMUX_PA21D_SERCOM3_PAD3 // SCK

View File

@ -13,7 +13,7 @@
// Use default pinmux for the chip select since we manage it ourselves.
#define SPI_FLASH_PAD1_PINMUX PINMUX_PA09D_SERCOM2_PAD1 // SCK
#define SPI_FLASH_PAD2_PINMUX PINMUX_PA14C_SERCOM2_PAD2 // MISO
#define SPI_FLASH_PAD3_PINMUX PINMUX_DEFAULT // SCK
#define SPI_FLASH_PAD3_PINMUX PINMUX_UNUSED // SCK
#define SPI_FLASH_SERCOM SERCOM2
#define SPI_FLASH_CS PIN_PA13

View File

@ -12,7 +12,7 @@
#define SPI_FLASH_BAUDRATE (8000000)
#define SPI_FLASH_MUX_SETTING SPI_SIGNAL_MUX_SETTING_F
#define SPI_FLASH_PAD0_PINMUX PINMUX_DEFAULT // CS
#define SPI_FLASH_PAD0_PINMUX PINMUX_UNUSED // CS
// Use default pinmux for the chip select since we manage it ourselves.
#define SPI_FLASH_PAD1_PINMUX PINMUX_PB03D_SERCOM5_PAD1 // MISO
#define SPI_FLASH_PAD2_PINMUX PINMUX_PB22D_SERCOM5_PAD2 // MOSI

View File

@ -29,6 +29,7 @@
#include "py/runtime.h"
#include "rgb_led_status.h"
#include "samd21_pins.h"
#include "shared_dma.h"
// We use ENABLE registers below we don't want to treat as a macro.
#undef ENABLE
@ -127,6 +128,11 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self,
&config_spi_master.pinmux_pad1,
&config_spi_master.pinmux_pad2,
&config_spi_master.pinmux_pad3};
// Set other pinmuxes to unused so we don't accidentally change other pin
// state.
for (uint8_t i = 0; i < 4; i++) {
*pinmuxes[i] = PINMUX_UNUSED;
}
*pinmuxes[clock_pad] = clock_pinmux;
self->clock_pin = clock->pin;
claim_pin(clock);
@ -220,10 +226,12 @@ bool common_hal_busio_spi_write(busio_spi_obj_t *self,
if (len == 0) {
return true;
}
enum status_code status = spi_write_buffer_wait(
&self->spi_master_instance,
data,
len);
enum status_code status;
if (len >= 16) {
status = shared_dma_write(self->spi_master_instance.hw, data, len);
} else {
status = spi_write_buffer_wait(&self->spi_master_instance, data, len);
}
return status == STATUS_OK;
}
@ -232,10 +240,11 @@ bool common_hal_busio_spi_read(busio_spi_obj_t *self,
if (len == 0) {
return true;
}
enum status_code status = spi_read_buffer_wait(
&self->spi_master_instance,
data,
len,
write_value);
enum status_code status;
if (len >= 16) {
status = shared_dma_read(self->spi_master_instance.hw, data, len, write_value);
} else {
status = spi_read_buffer_wait(&self->spi_master_instance, data, len, write_value);
}
return status == STATUS_OK;
}