Skip to content

Commit 6512ccf

Browse files
committed
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 adafruit#100
1 parent 24a5752 commit 6512ccf

4 files changed

Lines changed: 22 additions & 13 deletions

File tree

atmel-samd/boards/circuitplayground_express/mpconfigboard.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@
1212

1313
// Rev B:
1414
// #define SPI_FLASH_PAD0_PINMUX PINMUX_PA12D_SERCOM4_PAD0 // MISO
15-
// #define SPI_FLASH_PAD1_PINMUX PINMUX_DEFAULT // CS
15+
// #define SPI_FLASH_PAD1_PINMUX PINMUX_UNUSED // CS
1616
// #define SPI_FLASH_PAD2_PINMUX PINMUX_PB10D_SERCOM4_PAD2 // MOSI
1717
// #define SPI_FLASH_PAD3_PINMUX PINMUX_PB11D_SERCOM4_PAD3 // SCK
1818

1919
// Rev C:
2020
#define SPI_FLASH_PAD0_PINMUX PINMUX_PA16D_SERCOM3_PAD0 // MISO
21-
#define SPI_FLASH_PAD1_PINMUX PINMUX_DEFAULT // CS
21+
#define SPI_FLASH_PAD1_PINMUX PINMUX_UNUSED // CS
2222
#define SPI_FLASH_PAD2_PINMUX PINMUX_PA20D_SERCOM3_PAD2 // MOSI
2323
#define SPI_FLASH_PAD3_PINMUX PINMUX_PA21D_SERCOM3_PAD3 // SCK
2424

atmel-samd/boards/feather_m0_express/mpconfigboard.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
// Use default pinmux for the chip select since we manage it ourselves.
1414
#define SPI_FLASH_PAD1_PINMUX PINMUX_PA09D_SERCOM2_PAD1 // SCK
1515
#define SPI_FLASH_PAD2_PINMUX PINMUX_PA14C_SERCOM2_PAD2 // MISO
16-
#define SPI_FLASH_PAD3_PINMUX PINMUX_DEFAULT // SCK
16+
#define SPI_FLASH_PAD3_PINMUX PINMUX_UNUSED // SCK
1717
#define SPI_FLASH_SERCOM SERCOM2
1818

1919
#define SPI_FLASH_CS PIN_PA13

atmel-samd/boards/metro_m0_express/mpconfigboard.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
#define SPI_FLASH_BAUDRATE (8000000)
1313

1414
#define SPI_FLASH_MUX_SETTING SPI_SIGNAL_MUX_SETTING_F
15-
#define SPI_FLASH_PAD0_PINMUX PINMUX_DEFAULT // CS
15+
#define SPI_FLASH_PAD0_PINMUX PINMUX_UNUSED // CS
1616
// Use default pinmux for the chip select since we manage it ourselves.
1717
#define SPI_FLASH_PAD1_PINMUX PINMUX_PB03D_SERCOM5_PAD1 // MISO
1818
#define SPI_FLASH_PAD2_PINMUX PINMUX_PB22D_SERCOM5_PAD2 // MOSI

atmel-samd/common-hal/busio/SPI.c

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "py/runtime.h"
3030
#include "rgb_led_status.h"
3131
#include "samd21_pins.h"
32+
#include "shared_dma.h"
3233

3334
// We use ENABLE registers below we don't want to treat as a macro.
3435
#undef ENABLE
@@ -127,6 +128,11 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self,
127128
&config_spi_master.pinmux_pad1,
128129
&config_spi_master.pinmux_pad2,
129130
&config_spi_master.pinmux_pad3};
131+
// Set other pinmuxes to unused so we don't accidentally change other pin
132+
// state.
133+
for (uint8_t i = 0; i < 4; i++) {
134+
*pinmuxes[i] = PINMUX_UNUSED;
135+
}
130136
*pinmuxes[clock_pad] = clock_pinmux;
131137
self->clock_pin = clock->pin;
132138
claim_pin(clock);
@@ -220,10 +226,12 @@ bool common_hal_busio_spi_write(busio_spi_obj_t *self,
220226
if (len == 0) {
221227
return true;
222228
}
223-
enum status_code status = spi_write_buffer_wait(
224-
&self->spi_master_instance,
225-
data,
226-
len);
229+
enum status_code status;
230+
if (len >= 16) {
231+
status = shared_dma_write(self->spi_master_instance.hw, data, len);
232+
} else {
233+
status = spi_write_buffer_wait(&self->spi_master_instance, data, len);
234+
}
227235
return status == STATUS_OK;
228236
}
229237

@@ -232,10 +240,11 @@ bool common_hal_busio_spi_read(busio_spi_obj_t *self,
232240
if (len == 0) {
233241
return true;
234242
}
235-
enum status_code status = spi_read_buffer_wait(
236-
&self->spi_master_instance,
237-
data,
238-
len,
239-
write_value);
243+
enum status_code status;
244+
if (len >= 16) {
245+
status = shared_dma_read(self->spi_master_instance.hw, data, len, write_value);
246+
} else {
247+
status = spi_read_buffer_wait(&self->spi_master_instance, data, len, write_value);
248+
}
240249
return status == STATUS_OK;
241250
}

0 commit comments

Comments
 (0)