X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fsamd21%2Fao_arch_funcs.h;h=754ca3b51c3c84ecc4c8a6e2079ea64c8c8f54ba;hb=f9e319f5a97df8c0950ec7531d0889cf60e53783;hp=e9fd3216855bc2500eeb4f768f208fbb54eb3f0e;hpb=a54f4fae343b7524db508dc1a29d36847a2decde;p=fw%2Faltos diff --git a/src/samd21/ao_arch_funcs.h b/src/samd21/ao_arch_funcs.h index e9fd3216..754ca3b5 100644 --- a/src/samd21/ao_arch_funcs.h +++ b/src/samd21/ao_arch_funcs.h @@ -125,97 +125,170 @@ ao_enable_cs(struct samd21_port *port, uint8_t pin) /* ao_spi_samd21.c */ +#define AO_SPI_INDEX_BIT 0 +#define AO_SPI_INDEX_MASK 0x07 + +#define AO_SPI_CONFIG_BIT 4 +#define AO_SPI_CONFIG_MASK (3 << AO_SPI_CONFIG_BIT) + #define AO_SPI_CPOL_BIT 6 #define AO_SPI_CPHA_BIT 7 -#define AO_SPI_CONFIG_1 0x00 +#define AO_SPI_DOPO_BIT 8 +#define AO_SPI_DOPO_MOSI_0_SCLK_1 (0 << AO_SPI_DOPO_BIT) +#define AO_SPI_DOPO_MOSI_2_SCLK_3 (1 << AO_SPI_DOPO_BIT) +#define AO_SPI_DOPO_MOSI_3_SCLK_1 (2 << AO_SPI_DOPO_BIT) +#define AO_SPI_DOPO_MOSI_0_SCLK_3 (3 << AO_SPI_DOPO_BIT) +#define AO_SPI_DOPO_MASK (3 << AO_SPI_DOPO_BIT) + +#define AO_SPI_DIPO_BIT 10 +#define AO_SPI_DIPO_MISO_0 (0 << AO_SPI_DIPO_BIT) +#define AO_SPI_DIPO_MISO_1 (1 << AO_SPI_DIPO_BIT) +#define AO_SPI_DIPO_MISO_2 (2 << AO_SPI_DIPO_BIT) +#define AO_SPI_DIPO_MISO_3 (3 << AO_SPI_DIPO_BIT) +#define AO_SPI_DIPO_MASK (3 << AO_SPI_DIPO_MASK) + +#define AO_SPI_CONFIG_0 (0 << AO_SPI_CONFIG_BIT) +#define AO_SPI_CONFIG_1 (1 << AO_SPI_CONFIG_BIT) +#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_1 - -#define AO_SPI_CONFIG_2 0x08 +#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) - * PA16 SERCOM0.2 -> MISO (DIPO 2) + * PA06 SERCOM0.2 -> MISO (DIPO 2) */ -#define AO_SPI_0_CONFIG_PA04_PA05_PA06 AO_SPI_CONFIG_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 */ -#define AO_SPI_CONFIG_NONE 0x0c +#if HAS_SPI_3 +/* + * PA22 SERCOM3.0 -> MOSI (DOPO 0) + * PA23 SERCOM3.1 -> SCLK (DOPO 0) + * PA20 SERCOM3.2 -> MISO (DIPO 2) + */ +#define AO_SPI_3_PA22_PA23_PA20 (3 | AO_SPI_CONFIG_0 | \ + AO_SPI_DOPO_MOSI_0_SCLK_1 | \ + AO_SPI_DIPO_MISO_2) +#endif /* HAS_SPI_3 */ -#define AO_SPI_INDEX_MASK 0x07 -#define AO_SPI_CONFIG_MASK 0x18 +#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_CONFIG_PA04_PA05_PA06 (0 | AO_SPI_CONFIG_1 | \ + AO_SPI_DOPO_MOSI_0_SCLK_1 | \ + AO_SPI_DIPO_MISO_2) -#define AO_SPI_INDEX(id) ((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)) +/* + * PB10 SERCOM4.2 -> MOSI (DOPO 1) + * PB11 SERCOM4.3 -> SCLK (DOPO 1) + * PA12 SERCOM4.0 -> MISO (DIPO 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 /* - * 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 + * PB22 SERCOM5.2 -> MOSI (DOPO 1) + * PB23 SERCOM5.3 -> SCLK (DOPO 1) + * PB03 SERCOM5.1 -> MISO (DIPO 1) */ +#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 */ -#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) +void +ao_spi_send(const void *block, uint16_t len, uint16_t spi_index); void -ao_spi_send(const void *block, uint16_t len, uint8_t spi_index); +ao_spi_send_fixed(uint8_t data, uint16_t len, uint16_t spi_index); void -ao_spi_recv(void *block, uint16_t len, uint8_t spi_index); +ao_spi_recv(void *block, uint16_t len, uint16_t spi_index); void -ao_spi_duplex(const void *out, void *in, uint16_t len, uint8_t spi_index); +ao_spi_duplex(const void *out, void *in, uint16_t len, uint16_t spi_index); void -ao_spi_get(uint8_t spi_index, uint32_t speed); +ao_spi_get(uint16_t spi_index, uint32_t speed); void -ao_spi_put(uint8_t spi_index); +ao_spi_put(uint16_t spi_index); void ao_spi_init(void); -#define ao_spi_get_mask(reg,mask,bus, speed) do { \ - ao_spi_get(bus, speed); \ +#define ao_spi_set_cs(reg,mask) do { \ + reg->outclr = mask; \ + } while(0) + +#define ao_spi_clr_cs(reg,mask) do { \ + reg->outset = mask; \ + } while(0) + +#define ao_spi_get_mask(reg,mask,spi_index, speed) do { \ + ao_spi_get(spi_index, speed); \ ao_spi_set_cs(reg,mask); \ } while (0) -#define ao_spi_put_mask(reg,mask,bus) do { \ +#define ao_spi_put_mask(reg,mask,spi_index) do { \ ao_spi_clr_cs(reg,mask); \ - ao_spi_put(bus); \ + ao_spi_put(spi_index); \ } while (0) static inline void -ao_spi_get_bit(struct samd21_port *port, uint8_t bit, uint8_t bus, uint32_t speed) +ao_spi_get_bit(struct samd21_port *port, uint8_t bit, uint16_t spi_index, uint32_t speed) { - ao_spi_get(bus, speed); + ao_spi_get(spi_index, speed); ao_gpio_set(port, bit, 0); } static inline void -ao_spi_put_bit(struct samd21_port *port, uint8_t bit, uint8_t bus) +ao_spi_put_bit(struct samd21_port *port, uint8_t bit, uint16_t spi_index) { ao_gpio_set(port, bit, 1); - ao_spi_put(bus); + ao_spi_put(spi_index); } static inline uint8_t -ao_spi_speed(uint32_t hz) +ao_spi_speed(int index, uint32_t hz) { int32_t baud = (int32_t) (AO_SYSCLK / (2 * hz)) - 1; - if (baud < 0) - baud = 0; + (void) index; + if (baud < 1) + baud = 1; if (baud > 255) baud = 255; return (uint8_t) baud;