/* * Initialize IO pins and SPI low level device */ static int lattice_ice40_io_init(unsigned int freq) { struct stm32f_spi * spi = STM32F_SPI3; unsigned int div; int br; /* Enable peripheral clock */ stm32_clk_enable(STM32_RCC, STM32_CLK_GPIOB); stm32_clk_enable(STM32_RCC, STM32_CLK_GPIOC); stm32_clk_enable(STM32_RCC, STM32_CLK_GPIOE); stm32_clk_enable(STM32_RCC, STM32_CLK_SPI3); /* Configure IO pins */ stm32_gpio_mode(ICE40_CDONE, INPUT, PULL_UP); stm32_gpio_set(ICE40_CRESET); stm32_gpio_mode(ICE40_CRESET, OUTPUT, SPEED_MED); stm32_gpio_set(ICE40_SPI_SS); stm32_gpio_mode(ICE40_SPI_SS, OUTPUT, SPEED_MED); stm32_gpio_mode(ICE40_SPI_SCK, ALT_FUNC, PUSH_PULL | SPEED_LOW); stm32_gpio_af(ICE40_SPI_SCK, GPIO_AF6); stm32_gpio_mode(ICE40_SPI_SDO, ALT_FUNC, PULL_UP); stm32_gpio_af(ICE40_SPI_SDO, GPIO_AF6); stm32_gpio_mode(ICE40_SPI_SDI, ALT_FUNC, PUSH_PULL | SPEED_LOW); stm32_gpio_af(ICE40_SPI_SDI, GPIO_AF6); /* Configure SPI */ div = stm32_clk_hz(STM32_CLK_SPI3) / freq / 2; br = 31 - __clz(div); if (div > (1 << br)) br++; DCC_LOG3(LOG_TRACE, "SPI freq=%d div=%d br=%d", freq, div, br); spi->cr1 = 0; spi->cr2 = 0; spi->i2scfgr = 0; spi->i2spr = 0; /* Master mode, MSB first */ spi->cr1 = SPI_SPE | SPI_BR_SET(br) | SPI_MSTR | SPI_SSM | SPI_SSI; return 0; }
int stm32f_spi_init(struct stm32f_spi * spi, const struct stm32f_spi_io * spi_io, unsigned int freq, unsigned int opt) { struct stm32_rcc * rcc = STM32_RCC; gpio_io_t io; uint32_t div; int br; int id; if ((id = stm32f_spi_lookup(spi)) < 0) { /* invalid SPI ??? */ return id; } /* Configure IO pins */ io = spi_io->miso; stm32_gpio_clock_en(STM32_GPIO(io.port)); stm32_gpio_mode(STM32_GPIO(io.port), io.pin, ALT_FUNC, PULL_UP | SPEED_MED); stm32_gpio_af(STM32_GPIO(io.port), io.pin, spi_cfg[id].af); io = spi_io->mosi; stm32_gpio_clock_en(STM32_GPIO(io.port)); stm32_gpio_mode(STM32_GPIO(io.port), io.pin, ALT_FUNC, PUSH_PULL | SPEED_MED); stm32_gpio_af(STM32_GPIO(io.port), io.pin, spi_cfg[id].af); io = spi_io->sck; stm32_gpio_clock_en(STM32_GPIO(io.port)); stm32_gpio_mode(STM32_GPIO(io.port), io.pin, ALT_FUNC, PUSH_PULL | SPEED_MED); stm32_gpio_af(STM32_GPIO(io.port), io.pin, spi_cfg[id].af); /* Enable peripheral clock */ if (spi_cfg[id].apb2) { rcc->apb2enr |= (1 << spi_cfg[id].ckbit); div = stm32f_apb2_hz / freq / 2; } else { rcc->apb1enr |= (1 << spi_cfg[id].ckbit); div = stm32f_apb1_hz / freq / 2; } br = 31 - __clz(div); if (div > (1 << br)) { br++; } DCC_LOG3(LOG_TRACE, "SPI id=%d div=%d br=%d", id, div, br); spi->cr1 = 0; spi->cr2 = 0; spi->i2scfgr = 0; spi->i2spr = 0; spi->cr1 = SPI_SPE | SPI_BR_SET(br) | opt | SPI_SSM | SPI_SSI; #if 0 spi->cr1 = SPI_SPE | SPI_MSTR | SPI_SSM | SPI_SSI | \ SPI_BR_SET(br) | SPI_LSBFIRST; #endif return id; }