void spi_setup(void) { rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_SPI1EN); /* For spi signal pins */ rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_IOPAEN); /* For spi mode select on the l3gd20 */ rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_IOPEEN); /* Setup GPIOE3 pin for spi mode l3gd20 select. */ gpio_mode_setup(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO3); /* Start with spi communication disabled */ gpio_set(GPIOE, GPIO3); /* Setup GPIO pins for AF5 for SPI1 signals. */ gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO5 | GPIO6 | GPIO7); gpio_set_af(GPIOA, GPIO_AF5, GPIO5 | GPIO6 | GPIO7); //spi initialization; spi_set_master_mode(SPI1); spi_set_baudrate_prescaler(SPI1, SPI_CR1_BR_FPCLK_DIV_64); spi_set_clock_polarity_0(SPI1); spi_set_clock_phase_0(SPI1); spi_set_full_duplex_mode(SPI1); spi_set_unidirectional_mode(SPI1); /* bidirectional but in 3-wire */ spi_set_data_size(SPI1, SPI_CR2_DS_8BIT); spi_enable_software_slave_management(SPI1); spi_send_msb_first(SPI1); spi_set_nss_high(SPI1); //spi_enable_ss_output(SPI1); spi_fifo_reception_threshold_8bit(SPI1); SPI_I2SCFGR(SPI1) &= ~SPI_I2SCFGR_I2SMOD; spi_enable(SPI1); }
/* Setup the SPI bus. This function may cause spurious signals on the SPI bus, * so it should be called before the transaction starts (i.e. while SS is high). * -CPOL is the clock polarity (0 or 1) * -CPHA is the clock phase (0 or 1) * -baudrate is one of libopencm3's SPI_CR1_BAUDRATE_FPCLK_DIV_X values. * Baudrates are derived from the low-speed peripheral clock APB1. * -firstbit is either SPI_CR1_MSBFIRST or SPI_CR1_LSBFIRST. */ void setup_spi(uint8_t cpol, uint8_t cpha, uint8_t baudrate, uint8_t firstbit){ disable_and_reset_spi_properly(); SPI_CR1(SPI3) &= 0xFFC7; /* Mask off baudrate bits. */ SPI_CR1(SPI3) |= baudrate; if(0 == cpol){ spi_set_clock_polarity_0(SPI3); } else { spi_set_clock_polarity_1(SPI3); } if(0 == cpha){ spi_set_clock_phase_0(SPI3); } else { spi_set_clock_polarity_1(SPI3); } spi_set_unidirectional_mode(SPI3); /* bidirectional but in 3-wire */ spi_set_full_duplex_mode(SPI3); SPI_CR1(SPI3) &= ~SPI_CR1_LSBFIRST; SPI_CR1(SPI3) |= firstbit; spi_enable_software_slave_management(SPI3); spi_set_nss_high(SPI3); spi_set_master_mode(SPI3); spi_set_data_size(SPI3, SPI_CR2_DS_8BIT); spi_fifo_reception_threshold_8bit(SPI3); SPI_I2SCFGR(SPI3) &= ~SPI_I2SCFGR_I2SMOD; /* All DMA configuration is handled by tx_spi(), rx_spi(), and rxtx_spi(). */ }
void mew_spi_flash_init(void) { gpio_mode_setup(MEW_FLASH_GPIO_PORT_WP, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, MEW_FLASH_GPIO_PIN_WP); gpio_set_output_options(MEW_FLASH_GPIO_PORT_WP, GPIO_OTYPE_PP, GPIO_OSPEED_100MHZ, MEW_FLASH_GPIO_PIN_WP); gpio_set(MEW_FLASH_GPIO_PORT_WP, MEW_FLASH_GPIO_PIN_WP); gpio_mode_setup(MEW_FLASH_GPIO_PORT_HOLD, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, MEW_FLASH_GPIO_PIN_HOLD); gpio_set_output_options(MEW_FLASH_GPIO_PORT_HOLD, GPIO_OTYPE_PP, GPIO_OSPEED_100MHZ, MEW_FLASH_GPIO_PIN_HOLD); gpio_set(MEW_FLASH_GPIO_PORT_HOLD, MEW_FLASH_GPIO_PIN_HOLD); gpio_mode_setup(MEW_FLASH_GPIO_PORT_CS, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, MEW_FLASH_GPIO_PIN_CS); gpio_set_output_options(MEW_FLASH_GPIO_PORT_CS, GPIO_OTYPE_PP, GPIO_OSPEED_100MHZ, MEW_FLASH_GPIO_PIN_CS); gpio_set(MEW_FLASH_GPIO_PORT_CS, MEW_FLASH_GPIO_PIN_CS); gpio_mode_setup(MEW_FLASH_SPI_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLDOWN, MEW_FLASH_SPI_GPIO_PINS); gpio_set_output_options(MEW_FLASH_SPI_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_100MHZ, MEW_FLASH_SPI_GPIO_PINS); gpio_set_af(MEW_FLASH_SPI_GPIO_PORT, MEW_FLASH_SPI_GPIO_AF_NUMBER, MEW_FLASH_SPI_GPIO_PINS); spi_disable(MEW_FLASH_SPI); spi_set_master_mode(MEW_FLASH_SPI); spi_set_baudrate_prescaler(MEW_FLASH_SPI, SPI_CR1_BR_FPCLK_DIV_2); spi_set_clock_polarity_0(MEW_FLASH_SPI); spi_set_clock_phase_0(MEW_FLASH_SPI); spi_set_unidirectional_mode(MEW_FLASH_SPI); spi_enable_software_slave_management(MEW_FLASH_SPI); spi_send_msb_first(MEW_FLASH_SPI); spi_set_nss_high(MEW_FLASH_SPI); SPI_I2SCFGR(MEW_FLASH_SPI) &= ~SPI_I2SCFGR_I2SMOD; spi_disable_tx_buffer_empty_interrupt(MEW_FLASH_SPI); spi_disable_rx_buffer_not_empty_interrupt(MEW_FLASH_SPI); spi_disable_error_interrupt(MEW_FLASH_SPI); spi_disable_tx_dma(MEW_FLASH_SPI); spi_disable_rx_dma(MEW_FLASH_SPI); spi_set_dff_8bit(MEW_FLASH_SPI); spi_send_msb_first(MEW_FLASH_SPI); spi_enable(MEW_FLASH_SPI); }
void spi_i2s_mode_spi_mode(uint32_t spi) { SPI_I2SCFGR(spi) &= ~SPI_I2SCFGR_I2SMOD; }
extern void init_i2s(const i2s_config *cfg, const i2s_instance *inst, i2s_sample_callback *callback) { uint32_t base = inst->i2si_base_address; // Just handle one case for now. assert(cfg->i2sc_sample_frequency == 44100); assert(cfg->i2sc_mode == I2SM_MASTER_TX); assert(cfg->i2sc_standard == I2SS_LSB); assert(cfg->i2sc_data_format == I2SF_16); assert(cfg->i2sc_mclk_output == I2SM_ENABLED); assert(cfg->i2sc_cpol == I2SC_CPOL_HIGH); assert(cfg->i2sc_clock_source == I2SC_PLL); assert(cfg->i2sc_full_duplex == false); switch (base) { case SPI2_BASE: spi2_callback = callback; spi2_left_right = I2SC_LEFT; break; case SPI3_BASE: spi3_callback = callback; spi3_left_right = I2SC_LEFT; break; default: assert(false && "i2s: unknown bad address"); } // Enable clock. rcc_periph_clock_enable(RCC_SPI2); // Enable GPIO pins. size_t pin_count = 3 + !!cfg->i2sc_mclk_output + !!cfg->i2sc_full_duplex; gpio_init_pins(cfg->i2sc_gpio_pins, pin_count); // Enable interrupt. nvic_enable_irq(NVIC_SPI2_IRQ); SPI_I2SCFGR(base) = 0; RCC_PLLI2SCFGR = PLLI2S_N_VALUE << RCC_PLLI2SCFGR_PLLI2SN_SHIFT | PLLI2S_R_VALUE << RCC_PLLI2SCFGR_PLLI2SR_SHIFT; SPI_I2SPR(base) = SPI_I2SPR_MCKOE | I2SPR_ODD_VALUE | I2SPR_I2SDIV_VALUE; SPI_I2SCFGR(base) = SPI_I2SCFGR_I2SMOD | SPI_I2SCFGR_I2SCFG_MASTER_TRANSMIT << SPI_I2SCFGR_I2SCFG_LSB | SPI_I2SCFGR_I2SSTD_I2S_PHILIPS << SPI_I2SCFGR_I2SSTD_LSB | SPI_I2SCFGR_CKPOL | SPI_I2SCFGR_DATLEN_16BIT << SPI_I2SCFGR_DATLEN_LSB; SPI_CR2(base) |= SPI_CR2_TXEIE; // Start the I2S PLL. RCC_CR |= RCC_CR_PLLI2SON; // Enable I2S. SPI_I2SCFGR(base) |= SPI_I2SCFGR_I2SE; }
void codecInit(void) { memset(adcBuffer, 0xaa, sizeof(adcBuffer)); // I2S2 alternate function mapping gpio_mode_setup(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO12 | GPIO13 | GPIO14 | GPIO15); gpio_set_af(GPIOB, GPIO_AF5, GPIO12 | GPIO13 | GPIO15); gpio_set_af(GPIOB, GPIO_AF6, GPIO14); // I2S2ext_SD (I2S receive) gpio_mode_setup(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO6); gpio_set_af(GPIOC, GPIO_AF5, GPIO6); // MCLK gpio_set_output_options(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_25MHZ, GPIO12 | GPIO13 | GPIO15); gpio_set_output_options(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_100MHZ, GPIO6); // Set up SPI1 spi_reset(SPI1); spi_init_master(SPI1, SPI_CR1_BAUDRATE_FPCLK_DIV_256, SPI_CR1_CPOL_CLK_TO_1_WHEN_IDLE, SPI_CR1_CPHA_CLK_TRANSITION_2, SPI_CR1_DFF_16BIT, SPI_CR1_MSBFIRST); spi_set_nss_high(SPI1); spi_enable_software_slave_management(SPI1); spi_enable(SPI1); // SPI1 alternate function mapping, set CSB signal high output gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO5 | GPIO7); gpio_set_af(GPIOA, GPIO_AF5, GPIO5 | GPIO7); gpio_set(GPIOA, GPIO4); gpio_mode_setup(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO4); codecConfig(); // Set up I2S for 48kHz 16-bit stereo. // The input to the PLLI2S is 1MHz. Division factors are from // table 126 in the data sheet. // // This gives us 1.536MHz SCLK = 16 bits * 2 channels * 48000 Hz // and 12.288 MHz MCLK = 256 * 48000 Hz. // With this PLL configuration the actual sampling frequency // is nominally 47991 Hz. spi_reset(SPI2); RCC_PLLI2SCFGR = (3 << 28) | (258 << 6); RCC_CR |= RCC_CR_PLLI2SON; while (!(RCC_CR & RCC_CR_PLLI2SRDY)); const unsigned i2sdiv = 3; SPI_I2SPR(SPI2) = SPI_I2SPR_MCKOE | SPI_I2SPR_ODD | i2sdiv; SPI_I2SCFGR(SPI2) |= SPI_I2SCFGR_I2SMOD | SPI_I2SCFGR_I2SE | (SPI_I2SCFGR_I2SCFG_MASTER_TRANSMIT << SPI_I2SCFGR_I2SCFG_LSB); SPI_I2SCFGR(I2S2_EXT_BASE) = SPI_I2SCFGR_I2SMOD | SPI_I2SCFGR_I2SE | (SPI_I2SCFGR_I2SCFG_SLAVE_RECEIVE << SPI_I2SCFGR_I2SCFG_LSB); // Configure the DMA engine to stream data to the DAC. dma_stream_reset(DMA1, DAC_DMA_STREAM); dma_set_peripheral_address(DMA1, DAC_DMA_STREAM, (intptr_t)&SPI_DR(SPI2)); dma_set_memory_address(DMA1, DAC_DMA_STREAM, (intptr_t)dacBuffer[0]); dma_set_memory_address_1(DMA1, DAC_DMA_STREAM, (intptr_t)dacBuffer[1]); dma_set_number_of_data(DMA1, DAC_DMA_STREAM, BUFFER_SAMPLES); dma_channel_select(DMA1, DAC_DMA_STREAM, DAC_DMA_CHANNEL); dma_set_transfer_mode(DMA1, DAC_DMA_STREAM, DMA_SxCR_DIR_MEM_TO_PERIPHERAL); dma_set_memory_size(DMA1, DAC_DMA_STREAM, DMA_SxCR_MSIZE_16BIT); dma_set_peripheral_size(DMA1, DAC_DMA_STREAM, DMA_SxCR_PSIZE_16BIT); dma_enable_memory_increment_mode(DMA1, DAC_DMA_STREAM); dma_enable_double_buffer_mode(DMA1, DAC_DMA_STREAM); dma_enable_stream(DMA1, DAC_DMA_STREAM); // Configure the DMA engine to stream data from the ADC. dma_stream_reset(DMA1, ADC_DMA_STREAM); dma_set_peripheral_address(DMA1, ADC_DMA_STREAM, (intptr_t)&SPI_DR(I2S2_EXT_BASE)); dma_set_memory_address(DMA1, ADC_DMA_STREAM, (intptr_t)adcBuffer[0]); dma_set_memory_address_1(DMA1, ADC_DMA_STREAM, (intptr_t)adcBuffer[1]); dma_set_number_of_data(DMA1, ADC_DMA_STREAM, BUFFER_SAMPLES); dma_channel_select(DMA1, ADC_DMA_STREAM, ADC_DMA_CHANNEL); dma_set_transfer_mode(DMA1, ADC_DMA_STREAM, DMA_SxCR_DIR_PERIPHERAL_TO_MEM); dma_set_memory_size(DMA1, ADC_DMA_STREAM, DMA_SxCR_MSIZE_16BIT); dma_set_peripheral_size(DMA1, ADC_DMA_STREAM, DMA_SxCR_PSIZE_16BIT); dma_enable_memory_increment_mode(DMA1, ADC_DMA_STREAM); dma_enable_double_buffer_mode(DMA1, ADC_DMA_STREAM); dma_enable_stream(DMA1, ADC_DMA_STREAM); dma_enable_transfer_complete_interrupt(DMA1, ADC_DMA_STREAM); nvic_enable_irq(NVIC_DMA1_STREAM3_IRQ); nvic_set_priority(NVIC_DMA1_STREAM3_IRQ, 0x80); // 0 is most urgent // Start transmitting data spi_enable_rx_dma(I2S2_EXT_BASE); spi_enable_tx_dma(SPI2); }