samd21: Add SPI configurations used by TM v4.0
authorKeith Packard <keithp@keithp.com>
Mon, 7 Nov 2022 02:31:42 +0000 (18:31 -0800)
committerKeith Packard <keithp@keithp.com>
Mon, 7 Nov 2022 02:31:42 +0000 (18:31 -0800)
SPI 0 on PA04 PA05 PA06
SPI 3 on PA22 PA23 PA20
SPI 5 on PB22 PB23 PB03

Signed-off-by: Keith Packard <keithp@keithp.com>
src/samd21/ao_arch_funcs.h
src/samd21/ao_spi_samd21.c

index 47656551c00305a17d4fe15a30325452d67329e0..141a9a205b7b32a144902d3912e76b6af9a85ed0 100644 (file)
@@ -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);
 
index f62426497f96cab921d91b59ed57c21a2ac360c2..639ba97fc7fb3416c99a6671a27800ce47e05cfa 100644 (file)
@@ -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);