X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fsamd21%2Fao_arch_funcs.h;h=32670b45ca1897bc1f6a3016a4fd9c1cf4902930;hb=e026f1d16eb368d6a27b4c4ffbc4cece3950a07b;hp=8ef93aa4383fd12b9aa0ced14f2e882339c84fec;hpb=5e7e4303f161e38ac2d84110dccafc67b3aa7fc8;p=fw%2Faltos diff --git a/src/samd21/ao_arch_funcs.h b/src/samd21/ao_arch_funcs.h index 8ef93aa4..32670b45 100644 --- a/src/samd21/ao_arch_funcs.h +++ b/src/samd21/ao_arch_funcs.h @@ -123,6 +123,184 @@ ao_enable_cs(struct samd21_port *port, uint8_t pin) ao_enable_output(port, pin, 1); } +/* 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_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_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.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 */ + +#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) + +/* + * 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 +/* + * 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 */ + +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); + +void +ao_spi_duplex(const void *out, void *in, uint16_t len, uint16_t spi_index); + +void +ao_spi_get(uint16_t spi_index, uint32_t speed); + +void +ao_spi_put(uint16_t spi_index); + +void +ao_spi_init(void); + +#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,spi_index) do { \ + ao_spi_clr_cs(reg,mask); \ + ao_spi_put(spi_index); \ + } while (0) + +static inline void +ao_spi_get_bit(struct samd21_port *port, uint8_t bit, uint16_t spi_index, uint32_t 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, uint16_t spi_index) +{ + ao_gpio_set(port, bit, 1); + ao_spi_put(spi_index); +} + +static inline uint8_t +ao_spi_speed(uint32_t hz) +{ + int32_t baud = (int32_t) (AO_SYSCLK / (2 * hz)) - 1; + + if (baud < 1) + baud = 1; + if (baud > 255) + baud = 255; + return (uint8_t) baud; +} + +#define ao_spi_init_cs(port, mask) do { \ + uint8_t __bit__; \ + for (__bit__ = 0; __bit__ < 32; __bit__++) { \ + if (mask & (1 << __bit__)) \ + ao_enable_output(port, __bit__, 1); \ + } \ + } while (0) + #define ARM_PUSH32(stack, val) (*(--(stack)) = (val)) typedef uint32_t ao_arch_irq_t;