From a06c84a27bd760039c522460f79bfe242d2d22c8 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 6 Nov 2022 18:31:42 -0800 Subject: [PATCH] samd21: Add SPI configurations used by TM v4.0 SPI 0 on PA04 PA05 PA06 SPI 3 on PA22 PA23 PA20 SPI 5 on PB22 PB23 PB03 Signed-off-by: Keith Packard --- src/samd21/ao_arch_funcs.h | 86 +++++++++++++++++++++++--------------- src/samd21/ao_spi_samd21.c | 30 +++++++++++++ 2 files changed, 82 insertions(+), 34 deletions(-) diff --git a/src/samd21/ao_arch_funcs.h b/src/samd21/ao_arch_funcs.h index 47656551..141a9a20 100644 --- a/src/samd21/ao_arch_funcs.h +++ b/src/samd21/ao_arch_funcs.h @@ -153,21 +153,57 @@ ao_enable_cs(struct samd21_port *port, uint8_t pin) #define AO_SPI_CONFIG_2 (2 << AO_SPI_CONFIG_BIT) #define AO_SPI_CONFIG_3 (3 << AO_SPI_CONFIG_BIT) +#define AO_SPI_INDEX(id) ((uint8_t) ((id) & AO_SPI_INDEX_MASK)) +#define AO_SPI_CONFIG(id) ((id) & AO_SPI_CONFIG_MASK) +#define AO_SPI_PIN_CONFIG(id) ((id) & (AO_SPI_INDEX_MASK | AO_SPI_CONFIG_MASK)) +#define AO_SPI_CPOL(id) ((uint32_t) (((id) >> AO_SPI_CPOL_BIT) & 1)) +#define AO_SPI_CPHA(id) ((uint32_t) (((id) >> AO_SPI_CPHA_BIT) & 1)) +#define AO_SPI_DOPO(id) ((uint32_t) (((id) >> AO_SPI_DOPO_BIT) & 3)) +#define AO_SPI_DIPO(id) ((uint32_t) (((id) >> AO_SPI_DIPO_BIT) & 3)) + +#define AO_SPI_MAKE_MODE(pol,pha) (((pol) << AO_SPI_CPOL_BIT) | ((pha) << AO_SPI_CPHA_BIT)) +#define AO_SPI_MODE_0 AO_SPI_MAKE_MODE(0,0) +#define AO_SPI_MODE_1 AO_SPI_MAKE_MODE(0,1) +#define AO_SPI_MODE_2 AO_SPI_MAKE_MODE(1,0) +#define AO_SPI_MODE_3 AO_SPI_MAKE_MODE(1,1) + +#if HAS_SPI_0 /* * PA08 SERCOM0.0 -> MOSI (DOPO 0) * PA09 SERCOM0.1 -> SCLK (DOPO 0) * PA10 SERCOM0.2 -> MISO (DIPO 2) */ -#define AO_SPI_0_CONFIG_PA08_PA09_PA10 (AO_SPI_CONFIG_0 | \ - AO_SPI_DOPO_MOSI_0_SCLK_1 | \ - AO_SPI_DIPO_MISO_2) +#define AO_SPI_0_PA08_PA09_PA10 (0 | AO_SPI_CONFIG_0 | \ + AO_SPI_DOPO_MOSI_0_SCLK_1 | \ + AO_SPI_DIPO_MISO_2) +/* + * PA04 SERCOM0.0 -> MOSI (DOPO 0) + * PA05 SERCOM0.1 -> SCLK (DOPO 0) + * PA06 SERCOM0.2 -> MISO (DIPO 2) + */ +#define AO_SPI_0_PA04_PA05_PA06 (0 | AO_SPI_CONFIG_1 | \ + AO_SPI_DOPO_MOSI_0_SCLK_1 | \ + AO_SPI_DIPO_MISO_2) +#endif /* HAS_SPI_0 */ + +#if HAS_SPI_3 +/* + * PA22 SERCOM3.0 -> MOSI (DOPO 0) + * PA23 SERCOM3.1 -> SCLK (DOPO 0) + * PA20 SERCOM3.3 -> MISO (DIPO 3) + */ +#define AO_SPI_3_PA22_PA23_PA20 (3 | AO_SPI_CONFIG_0 | \ + AO_SPI_DOPO_MOSI_0_SCLK_1 | \ + AO_SPI_DIPO_MISO_3) +#endif /* HAS_SPI_3 */ +#if HAS_SPI_4 /* * PA04 SERCOM0.0 -> MOSI (DOPO 0) * PA05 SERCOM0.1 -> SCLK (DOPO 0) * PA16 SERCOM0.2 -> MISO (DIPO 2) */ -#define AO_SPI_0_CONFIG_PA04_PA05_PA06 (AO_SPI_CONFIG_1 | \ +#define AO_SPI_CONFIG_PA04_PA05_PA06 (0 | AO_SPI_CONFIG_1 | \ AO_SPI_DOPO_MOSI_0_SCLK_1 | \ AO_SPI_DIPO_MISO_2) @@ -176,46 +212,28 @@ ao_enable_cs(struct samd21_port *port, uint8_t pin) * PB11 SERCOM4.3 -> SCLK (DOPO 1) * PA12 SERCOM4.0 -> MISO (DIPO 0) */ -#define AO_SPI_4_CONFIG_PB10_PB11_PA12 (AO_SPI_CONFIG_0 | \ - AO_SPI_DOPO_MOSI_2_SCLK_3 | \ - AO_SPI_DIPO_MISO_0) +#define AO_SPI_4_PB10_PB11_PA12 (4 | AO_SPI_CONFIG_0 | \ + AO_SPI_DOPO_MOSI_2_SCLK_3 | \ + AO_SPI_DIPO_MISO_0) +#endif /* HAS_SPI_4 */ +#if HAS_SPI_5 /* * PB22 SERCOM5.2 -> MOSI (DOPO 1) * PB23 SERCOM5.3 -> SCLK (DOPO 1) * PB03 SERCOM5.1 -> MISO (DIPO 1) */ -#define AO_SPI_5_CONFIG_PB22_PB23_PB03 (AO_SPI_CONFIG_3 | \ - AO_SPI_DOPO_MOSI_2_SCLK_3 | \ - AO_SPI_DIPO_MISO_1) - -#define AO_SPI_INDEX(id) ((uint8_t) ((id) & AO_SPI_INDEX_MASK)) -#define AO_SPI_CONFIG(id) ((id) & AO_SPI_CONFIG_MASK) -#define AO_SPI_PIN_CONFIG(id) ((id) & (AO_SPI_INDEX_MASK | AO_SPI_CONFIG_MASK)) -#define AO_SPI_CPOL(id) ((uint32_t) (((id) >> AO_SPI_CPOL_BIT) & 1)) -#define AO_SPI_CPHA(id) ((uint32_t) (((id) >> AO_SPI_CPHA_BIT) & 1)) -#define AO_SPI_DOPO(id) ((uint32_t) (((id) >> AO_SPI_DOPO_BIT) & 3)) -#define AO_SPI_DIPO(id) ((uint32_t) (((id) >> AO_SPI_DIPO_BIT) & 3)) - -/* - * We're not going to do any fancy SPI pin remapping, just use the first - * three PAD pins, which means: - * - * MOSI: PAD.0 - * SCK: PAD.1 - * MISO: PAD.2 - */ - -#define AO_SPI_0_PA08_PA09_PA10 (0 | AO_SPI_0_CONFIG_PA08_PA09_PA10) -#define AO_SPI_0_PA04_PA05_PA06 (0 | AO_SPI_0_CONFIG_PA04_PA05_PA06) - -#define AO_SPI_4_PB10_PB11_PA12 (4 | AO_SPI_4_CONFIG_PB10_PB11_PA12) - -#define AO_SPI_5_PB22_PB23_PB03 (5 | AO_SPI_5_CONFIG_PB22_PB23_PB03) +#define AO_SPI_5_PB22_PB23_PB03 (5 | AO_SPI_CONFIG_0 | \ + AO_SPI_DOPO_MOSI_2_SCLK_3 | \ + AO_SPI_DIPO_MISO_1) +#endif /* HAS_SPI_5 */ void ao_spi_send(const void *block, uint16_t len, uint16_t spi_index); +void +ao_spi_send_fixed(uint8_t data, uint16_t len, uint16_t spi_index); + void ao_spi_recv(void *block, uint16_t len, uint16_t spi_index); diff --git a/src/samd21/ao_spi_samd21.c b/src/samd21/ao_spi_samd21.c index f6242649..639ba97f 100644 --- a/src/samd21/ao_spi_samd21.c +++ b/src/samd21/ao_spi_samd21.c @@ -241,6 +241,11 @@ ao_spi_send(const void *block, uint16_t len, uint16_t spi_index) spi_run(block, &spi_dev_null, len, spi_index, true, false); } +void +ao_spi_send_fixed(uint8_t data, uint16_t len, uint16_t spi_index) +{ + spi_run(&data, &spi_dev_null, len, spi_index, false, false); +} void ao_spi_recv(void *block, uint16_t len, uint16_t spi_index) @@ -272,6 +277,20 @@ ao_spi_disable_pin_config(uint16_t spi_pin_config) samd21_port_pmux_clr(&samd21_port_a, 6); /* MISO */ break; #endif +#if HAS_SPI_3 + case AO_SPI_PIN_CONFIG(AO_SPI_3_PA22_PA23_PA20): + samd21_port_pmux_clr(&samd21_port_a, 22); /* MOSI */ + samd21_port_pmux_clr(&samd21_port_a, 23); /* SCLK */ + samd21_port_pmux_clr(&samd21_port_a, 20); /* MISO */ + break; +#endif +#if HAS_SPI_4 + case AO_SPI_PIN_CONFIG(AO_SPI_4_PB10_PB11_PA12): + samd21_port_pmux_clr(&samd21_port_b, 10); /* MOSI */ + samd21_port_pmux_clr(&samd21_port_b, 11); /* SCLK */ + samd21_port_pmux_clr(&samd21_port_a, 12); /* MISO */ + break; +#endif #if HAS_SPI_5 case AO_SPI_PIN_CONFIG(AO_SPI_5_PB22_PB23_PB03): samd21_port_pmux_clr(&samd21_port_b, 22); /* MOSI */ @@ -308,6 +327,17 @@ ao_spi_enable_pin_config(uint16_t spi_pin_config) samd21_port_pmux_set(&samd21_port_a, 6, SAMD21_PORT_PMUX_FUNC_C); /* MISO */ break; #endif +#if HAS_SPI_3 + case AO_SPI_PIN_CONFIG(AO_SPI_3_PA22_PA23_PA20): + ao_enable_output(&samd21_port_a, 22, 1); + ao_enable_output(&samd21_port_a, 23, 1); + ao_enable_input(&samd21_port_a, 20, AO_MODE_PULL_NONE); + + samd21_port_pmux_set(&samd21_port_a, 22, SAMD21_PORT_PMUX_FUNC_C); /* MOSI */ + samd21_port_pmux_set(&samd21_port_a, 23, SAMD21_PORT_PMUX_FUNC_C); /* SCLK */ + samd21_port_pmux_set(&samd21_port_a, 20, SAMD21_PORT_PMUX_FUNC_D); /* MISO */ + break; +#endif #if HAS_SPI_4 case AO_SPI_PIN_CONFIG(AO_SPI_4_PB10_PB11_PA12): ao_enable_output(&samd21_port_b, 10, 1); -- 2.30.2