int spi_init_slave(spi_t dev, spi_conf_t conf, char(*cb)(char data)) { SPI_TypeDef *spi_port; switch (dev) { #if SPI_0_EN case SPI_0: spi_port = SPI_0_DEV; /* enable clocks */ SPI_0_CLKEN(); SPI_0_SCK_PORT_CLKEN(); SPI_0_MISO_PORT_CLKEN(); SPI_0_MOSI_PORT_CLKEN(); /* configure interrupt channel */ NVIC_SetPriority(SPI_0_IRQ, SPI_IRQ_PRIO); /* set SPI interrupt priority */ NVIC_EnableIRQ(SPI_0_IRQ); /* set SPI interrupt priority */ break; #endif /* SPI_0_EN */ #if SPI_1_EN case SPI_1: spi_port = SPI_1_DEV; /* enable clocks */ SPI_1_CLKEN(); SPI_1_SCK_PORT_CLKEN(); SPI_1_MISO_PORT_CLKEN(); SPI_1_MOSI_PORT_CLKEN(); /* configure interrupt channel */ NVIC_SetPriority(SPI_1_IRQ, SPI_IRQ_PRIO); NVIC_EnableIRQ(SPI_1_IRQ); 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; spi_port->CR2 = 0; /* enable RXNEIE flag to enable rx buffer not empty interrupt */ spi_port->CR2 |= (SPI_CR2_RXNEIE); /*1:not masked */ spi_port->CR1 |= (conf); /* the NSS (chip select) is managed by software and NSS is low (slave enabled) */ spi_port->CR1 |= SPI_CR1_SSM; /* set callback */ spi_config[dev].cb = cb; /* enable SPI device */ spi_port->CR1 |= SPI_CR1_SPE; return 0; }
int spi_init_master(spi_t dev, spi_conf_t conf, spi_speed_t speed) { uint8_t speed_devider; SPI_TypeDef *spi_port; switch (speed) { case SPI_SPEED_100KHZ: return -2; /* not possible for stm32f4, APB2 minimum is 328 kHz */ break; case SPI_SPEED_400KHZ: speed_devider = 0x05 + spi_bus_div_map[dev]; /* makes 656 kHz */ break; case SPI_SPEED_1MHZ: speed_devider = 0x04 + spi_bus_div_map[dev]; /* makes 1.3 MHz */ break; case SPI_SPEED_5MHZ: speed_devider = 0x02 + spi_bus_div_map[dev]; /* makes 5.3 MHz */ break; case SPI_SPEED_10MHZ: speed_devider = 0x01 + spi_bus_div_map[dev]; /* makes 10.5 MHz */ break; default: return -1; } switch (dev) { #if SPI_0_EN case SPI_0: spi_port = SPI_0_DEV; /* enable clocks */ SPI_0_CLKEN(); SPI_0_SCK_PORT_CLKEN(); SPI_0_MISO_PORT_CLKEN(); SPI_0_MOSI_PORT_CLKEN(); break; #endif /* SPI_0_EN */ #if SPI_1_EN case SPI_1: spi_port = SPI_1_DEV; /* enable clocks */ SPI_1_CLKEN(); SPI_1_SCK_PORT_CLKEN(); SPI_1_MISO_PORT_CLKEN(); SPI_1_MOSI_PORT_CLKEN(); 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 -2; } /* 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; spi_port->CR2 = 0; /* the NSS (chip select) is managed purely by software */ spi_port->CR1 |= SPI_CR1_SSM | SPI_CR1_SSI; spi_port->CR1 |= (speed_devider << 3); /* Define serial clock baud rate. 001 leads to f_PCLK/4 */ spi_port->CR1 |= (SPI_CR1_MSTR); /* 1: master configuration */ spi_port->CR1 |= (conf); /* enable SPI */ spi_port->CR1 |= (SPI_CR1_SPE); return 0; }
int spi_init_master(spi_t dev, spi_conf_t conf, spi_speed_t speed) { uint8_t speed_divider; switch (speed) { case SPI_SPEED_100KHZ: return -2; /* not possible for stm32f3 */ break; case SPI_SPEED_400KHZ: speed_divider = 7; /* makes 656 kHz */ break; case SPI_SPEED_1MHZ: speed_divider = 6; /* makes 1.3 MHz */ break; case SPI_SPEED_5MHZ: speed_divider = 4; /* makes 5.3 MHz */ break; case SPI_SPEED_10MHZ: speed_divider = 3; /* makes 10.5 MHz */ break; default: return -1; } switch (dev) { #if SPI_0_EN case SPI_0: /* enable clocks */ SPI_0_CLKEN(); SPI_0_SCK_PORT_CLKEN(); SPI_0_MISO_PORT_CLKEN(); SPI_0_MOSI_PORT_CLKEN(); break; #endif /* SPI_0_EN */ #if SPI_1_EN case SPI_1: /* enable clocks */ SPI_1_CLKEN(); SPI_1_SCK_PORT_CLKEN(); SPI_1_MISO_PORT_CLKEN(); SPI_1_MOSI_PORT_CLKEN(); break; #endif /* SPI_1_EN */ #if SPI_2_EN case SPI_2: /* 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 -2; } /* configure SCK, MISO and MOSI pin */ spi_conf_pins(dev); /**************** SPI-Init *****************/ #ifdef CPU_MODEL_STM32F303VC spi[dev]->I2SCFGR &= ~(SPI_I2SCFGR_I2SMOD);/* Activate the SPI mode (Reset I2SMOD bit in I2SCFGR register) */ #endif spi[dev]->CR1 = 0; spi[dev]->CR2 = 0; /* the NSS (chip select) is managed purely by software */ spi[dev]->CR1 |= SPI_CR1_SSM | SPI_CR1_SSI; spi[dev]->CR1 |= (speed_divider << 3); /* Define serial clock baud rate. 001 leads to f_PCLK/4 */ spi[dev]->CR1 |= (SPI_CR1_MSTR); /* 1: master configuration */ spi[dev]->CR1 |= (conf); spi[dev]->CR2 |= SPI_CR2_FRXTH; /* set FIFO reception threshold to 8bit (default: 16bit) */ /* enable SPI */ spi[dev]->CR1 |= (SPI_CR1_SPE); return 0; }