diff --git a/cpu/sam3x8e/periph/spi.c b/cpu/sam3x8e/periph/spi.c index d30008fa66be..99a34547751a 100644 --- a/cpu/sam3x8e/periph/spi.c +++ b/cpu/sam3x8e/periph/spi.c @@ -91,57 +91,21 @@ int spi_init_master(spi_t dev, spi_conf_t conf, spi_speed_t speed) default: return -1; - break; } switch (dev) { #if SPI_0_EN case SPI_0: spi_port = SPI_0_DEV; - /***************** PIO-Init *****************/ - /* Push-pull configuration */ - SPI_0_MISO_PORT->PIO_MDER &= ~SPI_0_MISO_PIN; - SPI_0_MISO_PORT->PIO_MDDR |= SPI_0_MISO_PIN; - SPI_0_MOSI_PORT->PIO_MDER &= ~SPI_0_MOSI_PIN; - SPI_0_MOSI_PORT->PIO_MDDR |= SPI_0_MOSI_PIN; - SPI_0_SCK_PORT->PIO_MDER &= ~SPI_0_SCK_PIN; - SPI_0_SCK_PORT->PIO_MDDR |= SPI_0_SCK_PIN; - - /* With pull-up resistors */ - SPI_0_MISO_PORT->PIO_PUDR &= ~SPI_0_MISO_PIN; - SPI_0_MISO_PORT->PIO_PUER |= SPI_0_MISO_PIN; - SPI_0_MOSI_PORT->PIO_PUDR &= ~SPI_0_MOSI_PIN; - SPI_0_MOSI_PORT->PIO_PUER |= SPI_0_MOSI_PIN; - SPI_0_SCK_PORT->PIO_PUDR &= ~SPI_0_SCK_PIN; - SPI_0_SCK_PORT->PIO_PUER |= SPI_0_SCK_PIN; - - /* Clear output */ - SPI_0_MISO_PORT->PIO_SODR &= ~SPI_0_MISO_PIN; - SPI_0_MISO_PORT->PIO_CODR |= SPI_0_MISO_PIN; - SPI_0_MOSI_PORT->PIO_SODR &= ~SPI_0_MOSI_PIN; - SPI_0_MOSI_PORT->PIO_CODR |= SPI_0_MOSI_PIN; - SPI_0_SCK_PORT->PIO_SODR &= ~SPI_0_SCK_PIN; - SPI_0_SCK_PORT->PIO_CODR |= SPI_0_SCK_PIN; - - /* Peripheral Function Selection */ - SPI_0_MISO_PORT->PIO_PER &= ~SPI_0_MISO_PIN; - SPI_0_MISO_PORT->PIO_PDR |= SPI_0_MISO_PIN; - SPI_0_MOSI_PORT->PIO_PER &= ~SPI_0_MOSI_PIN; - SPI_0_MOSI_PORT->PIO_PDR |= SPI_0_MOSI_PIN; - SPI_0_SCK_PORT->PIO_PER &= ~SPI_0_SCK_PIN; - SPI_0_SCK_PORT->PIO_PDR |= SPI_0_SCK_PIN; - - /* Peripheral A */ - SPI_0_MISO_PORT->PIO_ABSR &= ~SPI_0_MISO_PIN; - SPI_0_MOSI_PORT->PIO_ABSR &= ~SPI_0_MOSI_PIN; - SPI_0_SCK_PORT->PIO_ABSR &= ~SPI_0_SCK_PIN; - break; #endif /* SPI_0_EN */ default: return -2; } + /* Configure SCK, MISO and MOSI pin */ + spi_conf_pins(dev); + /***************** SPI-Init *****************/ /* Chip Select Register */ @@ -199,56 +163,18 @@ int spi_init_slave(spi_t dev, spi_conf_t conf, char(*cb)(char data)) spi_port = SPI_0_DEV; NVIC_SetPriority(SPI_0_IRQ, SPI_0_IRQ_PRIO); NVIC_EnableIRQ(SPI_0_IRQ); - - /***************** PIO-Init *****************/ - /* Initialize predefined NSS pin as output so it is "disabled" */ PIOA->PIO_PER |= PIO_PA28A_SPI0_NPCS0; PIOA->PIO_OER |= PIO_PA28A_SPI0_NPCS0; - - /* Push-pull configuration */ - SPI_0_MISO_PORT->PIO_MDER &= ~SPI_0_MISO_PIN; - SPI_0_MISO_PORT->PIO_MDDR |= SPI_0_MISO_PIN; - SPI_0_MOSI_PORT->PIO_MDER &= ~SPI_0_MOSI_PIN; - SPI_0_MOSI_PORT->PIO_MDDR |= SPI_0_MOSI_PIN; - SPI_0_SCK_PORT->PIO_MDER &= ~SPI_0_SCK_PIN; - SPI_0_SCK_PORT->PIO_MDDR |= SPI_0_SCK_PIN; - - /* With pull-up resistors */ - SPI_0_MISO_PORT->PIO_PUDR &= ~SPI_0_MISO_PIN; - SPI_0_MISO_PORT->PIO_PUER |= SPI_0_MISO_PIN; - SPI_0_MOSI_PORT->PIO_PUDR &= ~SPI_0_MOSI_PIN; - SPI_0_MOSI_PORT->PIO_PUER |= SPI_0_MOSI_PIN; - SPI_0_SCK_PORT->PIO_PUDR &= ~SPI_0_SCK_PIN; - SPI_0_SCK_PORT->PIO_PUER |= SPI_0_SCK_PIN; - - /* Clear output */ - SPI_0_MISO_PORT->PIO_SODR &= ~SPI_0_MISO_PIN; - SPI_0_MISO_PORT->PIO_CODR |= SPI_0_MISO_PIN; - SPI_0_MOSI_PORT->PIO_SODR &= ~SPI_0_MOSI_PIN; - SPI_0_MOSI_PORT->PIO_CODR |= SPI_0_MOSI_PIN; - SPI_0_SCK_PORT->PIO_SODR &= ~SPI_0_SCK_PIN; - SPI_0_SCK_PORT->PIO_CODR |= SPI_0_SCK_PIN; - - /* Peripheral Function Selection */ - SPI_0_MISO_PORT->PIO_PER &= ~SPI_0_MISO_PIN; - SPI_0_MISO_PORT->PIO_PDR |= SPI_0_MISO_PIN; - SPI_0_MOSI_PORT->PIO_PER &= ~SPI_0_MOSI_PIN; - SPI_0_MOSI_PORT->PIO_PDR |= SPI_0_MOSI_PIN; - SPI_0_SCK_PORT->PIO_PER &= ~SPI_0_SCK_PIN; - SPI_0_SCK_PORT->PIO_PDR |= SPI_0_SCK_PIN; - - /* Peripheral A */ - SPI_0_MISO_PORT->PIO_ABSR &= ~SPI_0_MISO_PIN; - SPI_0_MOSI_PORT->PIO_ABSR &= ~SPI_0_MOSI_PIN; - SPI_0_SCK_PORT->PIO_ABSR &= ~SPI_0_SCK_PIN; - break; #endif /* SPI_0_EN */ default: return -1; } + /* Configure SCK, MISO and MOSI pin */ + spi_conf_pins(dev); + /***************** SPI-Init *****************/ /* Chip Select Register */ @@ -296,6 +222,58 @@ int spi_init_slave(spi_t dev, spi_conf_t conf, char(*cb)(char data)) return 0; } +int spi_conf_pins(spi_t dev) +{ + switch (dev) { +#if SPI_0_EN + case SPI_0: + /***************** PIO-Init *****************/ + /* Push-pull configuration */ + SPI_0_MISO_PORT->PIO_MDER &= ~SPI_0_MISO_PIN; + SPI_0_MISO_PORT->PIO_MDDR |= SPI_0_MISO_PIN; + SPI_0_MOSI_PORT->PIO_MDER &= ~SPI_0_MOSI_PIN; + SPI_0_MOSI_PORT->PIO_MDDR |= SPI_0_MOSI_PIN; + SPI_0_SCK_PORT->PIO_MDER &= ~SPI_0_SCK_PIN; + SPI_0_SCK_PORT->PIO_MDDR |= SPI_0_SCK_PIN; + + /* With pull-up resistors */ + SPI_0_MISO_PORT->PIO_PUDR &= ~SPI_0_MISO_PIN; + SPI_0_MISO_PORT->PIO_PUER |= SPI_0_MISO_PIN; + SPI_0_MOSI_PORT->PIO_PUDR &= ~SPI_0_MOSI_PIN; + SPI_0_MOSI_PORT->PIO_PUER |= SPI_0_MOSI_PIN; + SPI_0_SCK_PORT->PIO_PUDR &= ~SPI_0_SCK_PIN; + SPI_0_SCK_PORT->PIO_PUER |= SPI_0_SCK_PIN; + + /* Clear output */ + SPI_0_MISO_PORT->PIO_SODR &= ~SPI_0_MISO_PIN; + SPI_0_MISO_PORT->PIO_CODR |= SPI_0_MISO_PIN; + SPI_0_MOSI_PORT->PIO_SODR &= ~SPI_0_MOSI_PIN; + SPI_0_MOSI_PORT->PIO_CODR |= SPI_0_MOSI_PIN; + SPI_0_SCK_PORT->PIO_SODR &= ~SPI_0_SCK_PIN; + SPI_0_SCK_PORT->PIO_CODR |= SPI_0_SCK_PIN; + + /* Peripheral Function Selection */ + SPI_0_MISO_PORT->PIO_PER &= ~SPI_0_MISO_PIN; + SPI_0_MISO_PORT->PIO_PDR |= SPI_0_MISO_PIN; + SPI_0_MOSI_PORT->PIO_PER &= ~SPI_0_MOSI_PIN; + SPI_0_MOSI_PORT->PIO_PDR |= SPI_0_MOSI_PIN; + SPI_0_SCK_PORT->PIO_PER &= ~SPI_0_SCK_PIN; + SPI_0_SCK_PORT->PIO_PDR |= SPI_0_SCK_PIN; + + /* Peripheral A */ + SPI_0_MISO_PORT->PIO_ABSR &= ~SPI_0_MISO_PIN; + SPI_0_MOSI_PORT->PIO_ABSR &= ~SPI_0_MOSI_PIN; + SPI_0_SCK_PORT->PIO_ABSR &= ~SPI_0_SCK_PIN; + + break; +#endif /* SPI_0_EN */ + default: + return -1; + } + + return 0; +} + int spi_transfer_byte(spi_t dev, char out, char *in) { Spi *spi_port; diff --git a/cpu/stm32f0/periph/spi.c b/cpu/stm32f0/periph/spi.c index d4239699f694..6b9bc1c3f8b6 100644 --- a/cpu/stm32f0/periph/spi.c +++ b/cpu/stm32f0/periph/spi.c @@ -15,6 +15,7 @@ * * @author Peter Kietzmann * @author Hauke Petersen + * @author Fabian Nack * * @} */ @@ -32,9 +33,6 @@ int spi_init_master(spi_t dev, spi_conf_t conf, spi_speed_t speed) { SPI_TypeDef *spi; - GPIO_TypeDef *port; - int pin[3]; /* 3 pins: sck, miso, mosi */ - int af = 0; /* power on the SPI device */ spi_poweron(dev); @@ -43,37 +41,21 @@ int spi_init_master(spi_t dev, spi_conf_t conf, spi_speed_t speed) #if SPI_0_EN case SPI_0: spi = SPI_0_DEV; - port = SPI_0_PORT; - pin[0] = SPI_0_PIN_SCK; - pin[1] = SPI_0_PIN_MISO; - pin[2] = SPI_0_PIN_MOSI; - af = SPI_0_PIN_AF; SPI_0_PORT_CLKEN(); break; #endif #if SPI_1_EN case SPI_1: spi = SPI_1_DEV; - port = SPI_1_PORT; - pin[0] = SPI_1_PIN_SCK; - pin[1] = SPI_1_PIN_MISO; - pin[2] = SPI_1_PIN_MOSI; - af = SPI_1_PIN_AF; - SPI_0_PORT_CLKEN(); + SPI_1_PORT_CLKEN(); break; #endif default: return -1; } - /* configure pins for their correct alternate function */ - for (int i = 0; i < 3; i++) { - port->MODER &= ~(3 << (pin[i] * 2)); - port->MODER |= (2 << (pin[i] * 2)); - int hl = (pin[i] < 8) ? 0 : 1; - port->AFR[hl] &= (0xf << ((pin[i] - (hl * 8)) * 4)); - port->AFR[hl] |= (af << ((pin[i] - (hl * 8)) * 4)); - } + /* configure SCK, MISO and MOSI pin */ + spi_conf_pins(dev); /* reset SPI configuration registers */ spi->CR1 = 0; @@ -119,6 +101,47 @@ int spi_init_slave(spi_t dev, spi_conf_t conf, char (*cb)(char data)) return -1; } +int spi_conf_pins(spi_t dev) +{ + GPIO_TypeDef *port; + int pin[3]; /* 3 pins: sck, miso, mosi */ + int af = 0; + + switch (dev) { +#if SPI_0_EN + case SPI_0: + port = SPI_0_PORT; + pin[0] = SPI_0_PIN_SCK; + pin[1] = SPI_0_PIN_MISO; + pin[2] = SPI_0_PIN_MOSI; + af = SPI_0_PIN_AF; + break; +#endif +#if SPI_1_EN + case SPI_1: + port = SPI_1_PORT; + pin[0] = SPI_1_PIN_SCK; + pin[1] = SPI_1_PIN_MISO; + pin[2] = SPI_1_PIN_MOSI; + af = SPI_1_PIN_AF; + break; +#endif + default: + return -1; + } + + /* configure pins for their correct alternate function */ + for (int i = 0; i < 3; i++) { + port->MODER &= ~(3 << (pin[i] * 2)); + port->MODER |= (2 << (pin[i] * 2)); + int hl = (pin[i] < 8) ? 0 : 1; + port->AFR[hl] &= ~(0xf << ((pin[i] - (hl * 8)) * 4)); + port->AFR[hl] |= (af << ((pin[i] - (hl * 8)) * 4)); + } + + return 0; +} + int spi_transfer_byte(spi_t dev, char out, char *in) { char tmp; diff --git a/cpu/stm32f1/periph/spi.c b/cpu/stm32f1/periph/spi.c index 76fad9dc0981..0c92e3278725 100644 --- a/cpu/stm32f1/periph/spi.c +++ b/cpu/stm32f1/periph/spi.c @@ -14,6 +14,7 @@ * @brief Low-level SPI driver implementation * * @author Thomas Eichinger + * @author Fabian Nack * * @} */ @@ -27,11 +28,12 @@ #define ENABLE_DEBUG (0) #include "debug.h" +/* guard file in case no SPI device is defined */ +#if SPI_NUMOF + int spi_init_master(spi_t dev, spi_conf_t conf, spi_speed_t speed) { SPI_TypeDef *spi; - GPIO_TypeDef *clk_port, *mosi_port, *miso_port; - int clk_pin, mosi_pin, miso_pin; uint16_t br_div; uint8_t bus_div; @@ -39,12 +41,6 @@ int spi_init_master(spi_t dev, spi_conf_t conf, spi_speed_t speed) #ifdef SPI_0_EN case SPI_0: spi = SPI_0_DEV; - clk_port = SPI_0_CLK_PORT; - clk_pin = SPI_0_CLK_PIN; - mosi_port = SPI_0_MOSI_PORT; - mosi_pin = SPI_0_MOSI_PIN; - miso_port = SPI_0_MISO_PORT; - miso_pin = SPI_0_MISO_PIN; bus_div = SPI_0_BUS_DIV; SPI_0_CLKEN(); break; @@ -53,33 +49,8 @@ int spi_init_master(spi_t dev, spi_conf_t conf, spi_speed_t speed) return -1; } - /* configure CLK pin */ - if (clk_pin < 8) { - clk_port->CRL &= ~(0xf << (clk_pin * 4)); - clk_port->CRL |= (0xb << (clk_pin * 4)); - } - else { - clk_port->CRH &= ~(0xf << ((clk_pin - 8) * 4)); - clk_port->CRH &= (0xb << ((clk_pin - 8) * 4)); - } - /* configure the MOSI pin */ - if (mosi_pin < 8) { - mosi_port->CRL &= ~(0xf << (mosi_pin * 4)); - mosi_port->CRL |= (0xb << (mosi_pin * 4)); - } - else { - mosi_port->CRH &= ~(0xf << ((mosi_pin - 8) * 4)); - mosi_port->CRH &= (0xb << ((mosi_pin - 8) * 4)); - } - /* configure MISO pin */ - if (miso_pin < 8) { - miso_port->CRL &= ~(0xf << (miso_pin * 4)); - miso_port->CRL |= (0x4 << (miso_pin * 4)); - } - else { - miso_port->CRH &= ~(0xf << ((miso_pin - 8) * 4)); - miso_port->CRH &= (0x4 << ((miso_pin - 8) * 4)); - } + /* configure SCK, MISO and MOSI pin */ + spi_conf_pins(dev); /* configure SPI bus speed */ switch(speed) { @@ -97,6 +68,7 @@ int spi_init_master(spi_t dev, spi_conf_t conf, spi_speed_t speed) break; case SPI_SPEED_100KHZ: br_div = 0x07; /* actual speed: 280kHz on APB2, 140KHz on APB1 */ + break; default: return -2; } @@ -117,6 +89,42 @@ int spi_init_slave(spi_t dev, spi_conf_t conf, char (*cb)(char)) return -1; } +int spi_conf_pins(spi_t dev) +{ + GPIO_TypeDef *port[3]; + int pin[3]; + + switch(dev) { +#ifdef SPI_0_EN + case SPI_0: + port[0] = SPI_0_CLK_PORT; + pin[0] = SPI_0_CLK_PIN; + port[1] = SPI_0_MOSI_PORT; + pin[1] = SPI_0_MOSI_PIN; + port[2] = SPI_0_MISO_PORT; + pin[2] = SPI_0_MISO_PIN; + break; +#endif + default: + return -1; + } + + /* configure pins for alternate function input (MISO) or output (MOSI, CLK) */ + for (int i = 0; i < 3; i++) { + int crbitval = (i < 2) ? 0xb : 0x4; + if (pin[i] < 8) { + port[i]->CRL &= ~(0xf << (pin[i] * 4)); + port[i]->CRL |= (crbitval << (pin[i] * 4)); + } + else { + port[i]->CRH &= ~(0xf << ((pin[i] - 8) * 4)); + port[i]->CRH &= (crbitval << ((pin[i] - 8) * 4)); + } + } + + return 0; +} + int spi_transfer_byte(spi_t dev, char out, char *in) { SPI_TypeDef *spi; @@ -222,3 +230,5 @@ void spi_poweroff(spi_t dev) #endif } } + +#endif /* SPI_NUMOF */ diff --git a/cpu/stm32f4/periph/spi.c b/cpu/stm32f4/periph/spi.c index 48008af83202..b391b7fdbb9d 100644 --- a/cpu/stm32f4/periph/spi.c +++ b/cpu/stm32f4/periph/spi.c @@ -14,6 +14,7 @@ * @brief Low-level SPI driver implementation * * @author Peter Kietzmann + * @author Fabian Nack * * @} */ @@ -43,7 +44,6 @@ static spi_state_t spi_config[SPI_NUMOF]; int spi_init_master(spi_t dev, spi_conf_t conf, spi_speed_t speed) { - uint8_t speed_devider; SPI_TypeDef *spi_port; @@ -76,58 +76,6 @@ int spi_init_master(spi_t dev, spi_conf_t conf, spi_speed_t speed) SPI_0_SCK_PORT_CLKEN(); SPI_0_MISO_PORT_CLKEN(); SPI_0_MOSI_PORT_CLKEN(); - - /***************** GPIO-Init *****************/ - /* Set GPIOs to AF mode */ - SPI_0_SCK_PORT->MODER &= ~(3 << (2 * SPI_0_SCK_PIN)); - SPI_0_SCK_PORT->MODER |= (2 << (2 * SPI_0_SCK_PIN)); - SPI_0_MISO_PORT->MODER &= ~(3 << (2 * SPI_0_MISO_PIN)); - SPI_0_MISO_PORT->MODER |= (2 << (2 * SPI_0_MISO_PIN)); - SPI_0_MOSI_PORT->MODER &= ~(3 << (2 * SPI_0_MOSI_PIN)); - SPI_0_MOSI_PORT->MODER |= (2 << (2 * SPI_0_MOSI_PIN)); - /* Set speed */ - SPI_0_SCK_PORT->OSPEEDR &= ~(3 << (2 * SPI_0_SCK_PIN)); - SPI_0_SCK_PORT->OSPEEDR |= (3 << (2 * SPI_0_SCK_PIN)); - SPI_0_MISO_PORT->OSPEEDR &= ~(3 << (2 * SPI_0_MISO_PIN)); - SPI_0_MISO_PORT->OSPEEDR |= (3 << (2 * SPI_0_MISO_PIN)); - SPI_0_MOSI_PORT->OSPEEDR &= ~(3 << (2 * SPI_0_MOSI_PIN)); - SPI_0_MOSI_PORT->OSPEEDR |= (3 << (2 * SPI_0_MOSI_PIN)); - /* Set to push-pull configuration */ - SPI_0_SCK_PORT->OTYPER &= ~(1 << SPI_0_SCK_PIN); - SPI_0_MISO_PORT->OTYPER &= ~(1 << SPI_0_MISO_PIN); - SPI_0_MOSI_PORT->OTYPER &= ~(1 << SPI_0_MOSI_PIN); - /* Configure push-pull resistors */ - SPI_0_SCK_PORT->PUPDR &= ~(3 << (2 * SPI_0_SCK_PIN)); - SPI_0_SCK_PORT->PUPDR |= (2 << (2 * SPI_0_SCK_PIN)); - SPI_0_MISO_PORT->PUPDR &= ~(3 << (2 * SPI_0_MISO_PIN)); - SPI_0_MISO_PORT->PUPDR |= (2 << (2 * SPI_0_MISO_PIN)); - SPI_0_MOSI_PORT->PUPDR &= ~(3 << (2 * SPI_0_MOSI_PIN)); - SPI_0_MOSI_PORT->PUPDR |= (2 << (2 * SPI_0_MOSI_PIN)); - /* Configure GPIOs to for the SPI0 alternate function */ -#if (SPI_0_SCK_PIN < 8) - SPI_0_SCK_PORT->AFR[0] &= ~(0xf << (4 * SPI_0_SCK_PIN)); - SPI_0_SCK_PORT->AFR[0] |= (SPI_0_SCK_AF << (4 * SPI_0_SCK_PIN)); - -#else - SPI_0_SCK_PORT->AFR[1] &= ~(0xf << (4 * (SPI_0_SCK_PIN - 8))); - SPI_0_SCK_PORT->AFR[1] |= (SPI_0_SCK_AF << (4 * (SPI_0_SCK_PIN - 8))); -#endif - -#if (SPI_0_MISO_PIN < 8) - SPI_0_MISO_PORT->AFR[0] &= ~(0xf << (4 * SPI_0_MISO_PIN)); - SPI_0_MISO_PORT->AFR[0] |= (SPI_0_MISO_AF << (4 * SPI_0_MISO_PIN)); -#else - SPI_0_MISO_PORT->AFR[1] &= ~(0xf << (4 * (SPI_0_MISO_PIN - 8))); - SPI_0_MISO_PORT->AFR[1] |= (SPI_0_MISO_AF << (4 * (SPI_0_MISO_PIN - 8))); -#endif - -#if (SPI_0_MOSI_PIN < 8) - SPI_0_MOSI_PORT->AFR[0] &= ~(0xf << (4 * SPI_0_MOSI_PIN)); - SPI_0_MOSI_PORT->AFR[0] |= (SPI_0_MOSI_AF << (4 * SPI_0_MOSI_PIN)); -#else - SPI_0_MOSI_PORT->AFR[1] &= ~(0xf << (4 * (SPI_0_MOSI_PIN - 8))); - SPI_0_MOSI_PORT->AFR[1] |= (SPI_0_MOSI_AF << (4 * (SPI_0_MOSI_PIN - 8))); -#endif break; #endif /* SPI_0_EN */ #if SPI_1_EN @@ -138,63 +86,25 @@ int spi_init_master(spi_t dev, spi_conf_t conf, spi_speed_t speed) SPI_1_SCK_PORT_CLKEN(); SPI_1_MISO_PORT_CLKEN(); SPI_1_MOSI_PORT_CLKEN(); - - /************************* GPIO-Init *************************/ - /* Set GPIOs to AF mode */ - SPI_1_SCK_PORT->MODER &= ~(3 << (2 * SPI_1_SCK_PIN)); - SPI_1_SCK_PORT->MODER |= (2 << (2 * SPI_1_SCK_PIN)); - SPI_1_MISO_PORT->MODER &= ~(3 << (2 * SPI_1_MISO_PIN)); - SPI_1_MISO_PORT->MODER |= (2 << (2 * SPI_1_MISO_PIN)); - SPI_1_MOSI_PORT->MODER &= ~(3 << (2 * SPI_1_MOSI_PIN)); - SPI_1_MOSI_PORT->MODER |= (2 << (2 * SPI_1_MOSI_PIN)); - /* Set speed */ - SPI_1_SCK_PORT->OSPEEDR &= ~(3 << (2 * SPI_1_SCK_PIN)); - SPI_1_SCK_PORT->OSPEEDR |= (3 << (2 * SPI_1_SCK_PIN)); - SPI_1_MISO_PORT->OSPEEDR &= ~(3 << (2 * SPI_1_MISO_PIN)); - SPI_1_MISO_PORT->OSPEEDR |= (3 << (2 * SPI_1_MISO_PIN)); - SPI_1_MOSI_PORT->OSPEEDR &= ~(3 << (2 * SPI_1_MOSI_PIN)); - SPI_1_MOSI_PORT->OSPEEDR |= (3 << (2 * SPI_1_MOSI_PIN)); - /* Set to push-pull configuration */ - SPI_1_SCK_PORT->OTYPER &= ~(1 << SPI_1_SCK_PIN); - SPI_1_MISO_PORT->OTYPER &= ~(1 << SPI_1_MISO_PIN); - SPI_1_MOSI_PORT->OTYPER &= ~(1 << SPI_1_MOSI_PIN); - /* Configure push-pull resistors */ - SPI_1_SCK_PORT->PUPDR &= ~(3 << (2 * SPI_1_SCK_PIN)); - SPI_1_SCK_PORT->PUPDR |= (2 << (2 * SPI_1_SCK_PIN)); - SPI_1_MISO_PORT->PUPDR &= ~(3 << (2 * SPI_1_MISO_PIN)); - SPI_1_MISO_PORT->PUPDR |= (2 << (2 * SPI_1_MISO_PIN)); - SPI_1_MOSI_PORT->PUPDR &= ~(3 << (2 * SPI_1_MOSI_PIN)); - SPI_1_MOSI_PORT->PUPDR |= (2 << (2 * SPI_1_MOSI_PIN)); - /* Configure the pins alternate function */ -#if (SPI_1_SCK_PIN < 8) - SPI_1_SCK_PORT->AFR[0] &= ~(0xf << (4 * SPI_1_SCK_PIN)); - SPI_1_SCK_PORT->AFR[0] |= (SPI_1_SCK_AF << (4 * SPI_1_SCK_PIN)); -#else - SPI_1_SCK_PORT->AFR[1] &= ~(0xf << (4 * (SPI_1_SCK_PIN - 8))); - SPI_1_SCK_PORT->AFR[1] |= (SPI_1_SCK_AF << (4 * (SPI_1_SCK_PIN - 8))); -#endif - -#if (SPI_1_MISO_PIN < 8) - SPI_1_MISO_PORT->AFR[0] &= ~(0xf << (4 * SPI_1_MISO_PIN)); - SPI_1_MISO_PORT->AFR[0] |= (SPI_1_MISO_AF << (4 * SPI_1_MISO_PIN)); -#else - SPI_1_MISO_PORT->AFR[1] &= ~(0xf << (4 * (SPI_1_MISO_PIN - 8))); - SPI_1_MISO_PORT->AFR[1] |= (SPI_1_MISO_AF << (4 * (SPI_1_MISO_PIN - 8))); -#endif - -#if (SPI_1_MOSI_PIN < 8) - SPI_1_MOSI_PORT->AFR[0] &= ~(0xf << (4 * SPI_1_MOSI_PIN)); - SPI_1_MOSI_PORT->AFR[0] |= (SPI_1_MOSI_AF << (4 * SPI_1_MOSI_PIN)); -#else - SPI_1_MOSI_PORT->AFR[1] &= ~(0xf << (4 * (SPI_1_MOSI_PIN - 8))); - SPI_1_MOSI_PORT->AFR[1] |= (SPI_1_MOSI_AF << (4 * (SPI_1_MOSI_PIN - 8))); -#endif break; #endif /* SPI_1_EN */ +#if SPI_2_EN + case SPI_2: + spi_port = SPI_2_DEV; + /* enable clocks */ + SPI_2_CLKEN(); + SPI_2_SCK_PORT_CLKEN(); + SPI_2_MISO_PORT_CLKEN(); + SPI_2_MOSI_PORT_CLKEN(); + break; +#endif /* SPI_2_EN */ default: return -1; } + /* configure SCK, MISO and MOSI pin */ + spi_conf_pins(dev); + /**************** SPI-Init *****************/ spi_port->I2SCFGR &= ~(SPI_I2SCFGR_I2SMOD);/* Activate the SPI mode (Reset I2SMOD bit in I2SCFGR register) */ spi_port->CR1 = 0; @@ -225,55 +135,6 @@ int spi_init_slave(spi_t dev, spi_conf_t conf, char(*cb)(char data)) /* configure interrupt channel */ NVIC_SetPriority(SPI_0_IRQ, SPI_IRQ_PRIO); /* set SPI interrupt priority */ NVIC_EnableIRQ(SPI_0_IRQ); /* set SPI interrupt priority */ - - /***************** GPIO-Init *****************/ - /* Set GPIOs to AF mode (not especially input or output) */ - SPI_0_SCK_PORT->MODER &= ~(3 << (2 * SPI_0_SCK_PIN)); - SPI_0_SCK_PORT->MODER |= (2 << (2 * SPI_0_SCK_PIN)); - SPI_0_MISO_PORT->MODER &= ~(3 << (2 * SPI_0_MISO_PIN)); - SPI_0_MISO_PORT->MODER |= (2 << (2 * SPI_0_MISO_PIN)); - SPI_0_MOSI_PORT->MODER &= ~(3 << (2 * SPI_0_MOSI_PIN)); - SPI_0_MOSI_PORT->MODER |= (2 << (2 * SPI_0_MOSI_PIN)); - /* Set speed */ - SPI_0_SCK_PORT->OSPEEDR &= ~(3 << (2 * SPI_0_SCK_PIN)); - SPI_0_SCK_PORT->OSPEEDR |= (3 << (2 * SPI_0_SCK_PIN)); - SPI_0_MISO_PORT->OSPEEDR &= ~(3 << (2 * SPI_0_MISO_PIN)); - SPI_0_MISO_PORT->OSPEEDR |= (3 << (2 * SPI_0_MISO_PIN)); - SPI_0_MOSI_PORT->OSPEEDR &= ~(3 << (2 * SPI_0_MOSI_PIN)); - SPI_0_MOSI_PORT->OSPEEDR |= (3 << (2 * SPI_0_MOSI_PIN)); - /* Set to push-pull configuration (not open drain) */ - SPI_0_SCK_PORT->OTYPER &= ~(1 << SPI_0_SCK_PIN); - SPI_0_MISO_PORT->OTYPER &= ~(1 << SPI_0_MISO_PIN); - SPI_0_MOSI_PORT->OTYPER &= ~(1 << SPI_0_MOSI_PIN); - /* Configure push-pull resistors */ - SPI_0_SCK_PORT->PUPDR &= ~(3 << (2 * SPI_0_SCK_PIN)); - SPI_0_SCK_PORT->PUPDR |= (2 << (2 * SPI_0_SCK_PIN)); - SPI_0_MISO_PORT->PUPDR &= ~(3 << (2 * SPI_0_MISO_PIN)); - SPI_0_MISO_PORT->PUPDR |= (2 << (2 * SPI_0_MISO_PIN)); - SPI_0_MOSI_PORT->PUPDR &= ~(3 << (2 * SPI_0_MOSI_PIN)); - SPI_0_MOSI_PORT->PUPDR |= (2 << (2 * SPI_0_MOSI_PIN)); - /* configure the pins alternate function */ -#if (SPI_0_SCK_PIN < 8) - SPI_0_SCK_PORT->AFR[0] &= ~(0xf << (4 * SPI_0_SCK_PIN)); - SPI_0_SCK_PORT->AFR[0] |= (SPI_0_SCK_AF << (4 * SPI_0_SCK_PIN)); -#else - SPI_0_SCK_PORT->AFR[1] &= ~(0xf << (4 * (SPI_0_SCK_PIN - 8))); - SPI_0_SCK_PORT->AFR[1] |= (SPI_0_SCK_AF << (4 * (SPI_0_SCK_PIN - 8))); -#endif -#if (SPI_0_MISO_PIN < 8) - SPI_0_MISO_PORT->AFR[0] &= ~(0xf << (4 * SPI_0_MISO_PIN)); - SPI_0_MISO_PORT->AFR[0] |= (SPI_0_MISO_AF << (4 * SPI_0_MISO_PIN)); -#else - SPI_0_MISO_PORT->AFR[1] &= ~(0xf << (4 * (SPI_0_MISO_PIN - 8))); - SPI_0_MISO_PORT->AFR[1] |= (SPI_0_MISO_AF << (4 * (SPI_0_MISO_PIN - 8))); -#endif -#if (SPI_0_MOSI_PIN < 8) - SPI_0_MOSI_PORT->AFR[0] &= ~(0xf << (4 * SPI_0_MOSI_PIN)); - SPI_0_MOSI_PORT->AFR[0] |= (SPI_0_MOSI_AF << (4 * SPI_0_MOSI_PIN)); -#else - SPI_0_MOSI_PORT->AFR[1] &= ~(0xf << (4 * (SPI_0_MOSI_PIN - 8))); - SPI_0_MOSI_PORT->AFR[1] |= (SPI_0_MOSI_AF << (4 * (SPI_0_MOSI_PIN - 8))); -#endif break; #endif /* SPI_0_EN */ #if SPI_1_EN @@ -287,61 +148,28 @@ int spi_init_slave(spi_t dev, spi_conf_t conf, char(*cb)(char data)) /* configure interrupt channel */ NVIC_SetPriority(SPI_1_IRQ, SPI_IRQ_PRIO); NVIC_EnableIRQ(SPI_1_IRQ); - - /***************** GPIO-Init *****************/ - /* Set GPIOs to AF mode (not especially input or output) */ - SPI_1_SCK_PORT->MODER &= ~(3 << (2 * SPI_1_SCK_PIN)); - SPI_1_SCK_PORT->MODER |= (2 << (2 * SPI_1_SCK_PIN)); - SPI_1_MISO_PORT->MODER &= ~(3 << (2 * SPI_1_MISO_PIN)); - SPI_1_MISO_PORT->MODER |= (2 << (2 * SPI_1_MISO_PIN)); - SPI_1_MOSI_PORT->MODER &= ~(3 << (2 * SPI_1_MOSI_PIN)); - SPI_1_MOSI_PORT->MODER |= (2 << (2 * SPI_1_MOSI_PIN)); - /* Set speed */ - SPI_1_SCK_PORT->OSPEEDR &= ~(3 << (2 * SPI_1_SCK_PIN)); - SPI_1_SCK_PORT->OSPEEDR |= (3 << (2 * SPI_1_SCK_PIN)); - SPI_1_MISO_PORT->OSPEEDR &= ~(3 << (2 * SPI_1_MISO_PIN)); - SPI_1_MISO_PORT->OSPEEDR |= (3 << (2 * SPI_1_MISO_PIN)); - SPI_1_MOSI_PORT->OSPEEDR &= ~(3 << (2 * SPI_1_MOSI_PIN)); - SPI_1_MOSI_PORT->OSPEEDR |= (3 << (2 * SPI_1_MOSI_PIN)); - /* Set to push-pull configuration (not open drain) */ - SPI_1_SCK_PORT->OTYPER &= ~(1 << SPI_1_SCK_PIN); - SPI_1_MISO_PORT->OTYPER &= ~(1 << SPI_1_MISO_PIN); - SPI_1_MOSI_PORT->OTYPER &= ~(1 << SPI_1_MOSI_PIN); - /* Configure push-pull resistors */ - SPI_1_SCK_PORT->PUPDR &= ~(3 << (2 * SPI_1_SCK_PIN)); - SPI_1_SCK_PORT->PUPDR |= (2 << (2 * SPI_1_SCK_PIN)); - SPI_1_MISO_PORT->PUPDR &= ~(3 << (2 * SPI_1_MISO_PIN)); - SPI_1_MISO_PORT->PUPDR |= (2 << (2 * SPI_1_MISO_PIN)); - SPI_1_MOSI_PORT->PUPDR &= ~(3 << (2 * SPI_1_MOSI_PIN)); - SPI_1_MOSI_PORT->PUPDR |= (2 << (2 * SPI_1_MOSI_PIN)); - -#if (SPI_1_SCK_PIN < 8) - SPI_1_SCK_PORT->AFR[0] &= ~(0xf << (4 * SPI_1_SCK_PIN)); - SPI_1_SCK_PORT->AFR[0] |= (SPI_1_SCK_AF << (4 * SPI_1_SCK_PIN)); -#else - SPI_1_SCK_PORT->AFR[1] &= ~(0xf << (4 * (SPI_1_SCK_PIN - 8))); - SPI_1_SCK_PORT->AFR[1] |= (SPI_1_SCK_AF << (4 * (SPI_1_SCK_PIN - 8))); -#endif -#if (SPI_1_MISO_PIN < 8) - SPI_1_MISO_PORT->AFR[0] &= ~(0xf << (4 * SPI_1_MISO_PIN)); - SPI_1_MISO_PORT->AFR[0] |= (SPI_1_MISO_AF << (4 * SPI_1_MISO_PIN)); -#else - SPI_1_MISO_PORT->AFR[1] &= ~(0xf << (4 * (SPI_1_MISO_PIN - 8))); - SPI_1_MISO_PORT->AFR[1] |= (SPI_1_MISO_AF << (4 * (SPI_1_MISO_PIN - 8))); -#endif -#if (SPI_1_MOSI_PIN < 8) - SPI_1_MOSI_PORT->AFR[0] &= ~(0xf << (4 * SPI_1_MOSI_PIN)); - SPI_1_MOSI_PORT->AFR[0] |= (SPI_1_MOSI_AF << (4 * SPI_1_MOSI_PIN)); -#else - SPI_1_MOSI_PORT->AFR[1] &= ~(0xf << (4 * (SPI_1_MOSI_PIN - 8))); - SPI_1_MOSI_PORT->AFR[1] |= (SPI_1_MOSI_AF << (4 * (SPI_1_MOSI_PIN - 8))); -#endif break; #endif /* SPI_1_EN */ +#if SPI_2_EN + case SPI_2: + spi_port = SPI_2_DEV; + /* enable clocks */ + SPI_2_CLKEN(); + SPI_2_SCK_PORT_CLKEN(); + SPI_2_MISO_PORT_CLKEN(); + SPI_2_MOSI_PORT_CLKEN(); + /* configure interrupt channel */ + NVIC_SetPriority(SPI_2_IRQ, SPI_IRQ_PRIO); + NVIC_EnableIRQ(SPI_2_IRQ); + break; +#endif /* SPI_2_EN */ default: return -1; } + /* configure sck, miso and mosi pin */ + spi_conf_pins(dev); + /***************** SPI-Init *****************/ spi_port->I2SCFGR &= ~(SPI_I2SCFGR_I2SMOD); spi_port->CR1 = 0; @@ -358,6 +186,77 @@ int spi_init_slave(spi_t dev, spi_conf_t conf, char(*cb)(char data)) return 0; } +int spi_conf_pins(spi_t dev) +{ + GPIO_TypeDef *port[3]; + int pin[3], af[3]; + + switch (dev) { +#if SPI_0_EN + case SPI_0: + port[0] = SPI_0_SCK_PORT; + pin[0] = SPI_0_SCK_PIN; + af[0] = SPI_0_SCK_AF; + port[1] = SPI_0_MOSI_PORT; + pin[1] = SPI_0_MOSI_PIN; + af[1] = SPI_0_MOSI_AF; + port[2] = SPI_0_MISO_PORT; + pin[2] = SPI_0_MISO_PIN; + af[2] = SPI_0_MISO_AF; + break; +#endif /* SPI_0_EN */ +#if SPI_1_EN + case SPI_1: + port[0] = SPI_1_SCK_PORT; + pin[0] = SPI_1_SCK_PIN; + af[0] = SPI_1_SCK_AF; + port[1] = SPI_1_MOSI_PORT; + pin[1] = SPI_1_MOSI_PIN; + af[1] = SPI_1_MOSI_AF; + port[2] = SPI_1_MISO_PORT; + pin[2] = SPI_1_MISO_PIN; + af[2] = SPI_1_MISO_AF; + break; +#endif /* SPI_1_EN */ +#if SPI_2_EN + case SPI_2: + port[0] = SPI_2_SCK_PORT; + pin[0] = SPI_2_SCK_PIN; + af[0] = SPI_2_SCK_AF; + port[1] = SPI_2_MOSI_PORT; + pin[1] = SPI_2_MOSI_PIN; + af[1] = SPI_2_MOSI_AF; + port[2] = SPI_2_MISO_PORT; + pin[2] = SPI_2_MISO_PIN; + af[2] = SPI_2_MISO_AF; + break; +#endif /* SPI_2_EN */ + default: + return -1; + } + + /***************** GPIO-Init *****************/ + for (int i = 0; i < 3; i++) { + /* Set GPIOs to AF mode */ + port[i]->MODER &= ~(3 << (2 * pin[i])); + port[i]->MODER |= (2 << (2 * pin[i])); + /* Set speed */ + port[i]->OSPEEDR &= ~(3 << (2 * pin[i])); + port[i]->OSPEEDR |= (3 << (2 * pin[i])); + /* Set to push-pull configuration */ + port[i]->OTYPER &= ~(1 << pin[i]); + /* Configure push-pull resistors */ + port[i]->PUPDR &= ~(3 << (2 * pin[i])); + port[i]->PUPDR |= (2 << (2 * pin[i])); + /* Configure GPIOs for the SPI alternate function */ + int hl = (pin[i] < 8) ? 0 : 1; + port[i]->AFR[hl] &= ~(0xf << ((pin[i] - (hl * 8)) * 4)); + port[i]->AFR[hl] |= (af[i] << ((pin[i] - (hl * 8)) * 4)); + } + + return 0; +} + int spi_transfer_byte(spi_t dev, char out, char *in) { SPI_TypeDef *spi_port; @@ -372,6 +271,11 @@ int spi_transfer_byte(spi_t dev, char out, char *in) case SPI_1: spi_port = SPI_1_DEV; break; +#endif +#if SPI_2_EN + case SPI_2: + spi_port = SPI_2_DEV; + break; #endif default: return -1; @@ -462,6 +366,11 @@ void spi_transmission_begin(spi_t dev, char reset_val) case SPI_1: SPI_1_DEV->DR = reset_val; break; +#endif +#if SPI_2_EN + case SPI_2: + SPI_2_DEV->DR = reset_val; + break; #endif } } @@ -478,6 +387,11 @@ void spi_poweron(spi_t dev) case SPI_1: SPI_1_CLKEN(); break; +#endif +#if SPI_2_EN + case SPI_2: + SPI_2_CLKEN(); + break; #endif } } @@ -496,6 +410,12 @@ void spi_poweroff(spi_t dev) while (SPI_1_DEV->SR & SPI_SR_BSY); SPI_1_CLKDIS(); break; +#endif +#if SPI_2_EN + case SPI_2: + while (SPI_2_DEV->SR & SPI_SR_BSY); + SPI_2_CLKDIS(); + break; #endif } } @@ -533,4 +453,13 @@ __attribute__((naked)) void SPI_1_IRQ_HANDLER(void) } #endif +#if SPI_2_EN +__attribute__((naked)) void SPI_2_IRQ_HANDLER(void) +{ + ISR_ENTER(); + irq_handler_transfer(SPI_2_DEV, SPI_2); + ISR_EXIT(); +} +#endif + #endif /* SPI_NUMOF */ diff --git a/drivers/include/periph/spi.h b/drivers/include/periph/spi.h index 6b82899b532f..9d00a7daef2d 100644 --- a/drivers/include/periph/spi.h +++ b/drivers/include/periph/spi.h @@ -107,6 +107,16 @@ int spi_init_master(spi_t dev, spi_conf_t conf, spi_speed_t speed); */ int spi_init_slave(spi_t dev, spi_conf_t conf, char (*cb)(char data)); +/** + * @brief Configure SCK, MISO and MOSI pins for the given SPI device + * + * @param[in] dev SPI device to use + * + * @return 0 on success + * @return -1 on error + */ +int spi_conf_pins(spi_t dev); + /** * @brief Transfer one byte on the given SPI bus *