/** * \brief Initialize SPI as master. */ static void spi_master_initialize(void) { /* Configure an SPI peripheral. */ uint32_t spi_chip_sel, spi_clk_freq, spi_clk_pol, spi_clk_pha; spi_enable_clock(SPI_MASTER_BASE); spi_reset(SPI_MASTER_BASE); spi_set_master_mode(SPI_MASTER_BASE); spi_disable_mode_fault_detect(SPI_MASTER_BASE); spi_disable_loopback(SPI_MASTER_BASE); spi_set_peripheral_chip_select_value(SPI_MASTER_BASE, spi_get_pcs(2)); // This sets the value of PCS within the Mode Register. spi_set_variable_peripheral_select(SPI_MASTER_BASE); // PCS needs to be set within each transfer (PCS within SPI_TDR). spi_disable_peripheral_select_decode(SPI_MASTER_BASE); // Each CS is to be connected to a single device. spi_set_delay_between_chip_select(SPI_MASTER_BASE, SPI_DLYBCS); /* Set communication parameters for CS0 */ spi_chip_sel = 0; spi_clk_freq = 100000; // SPI CLK for RTC = 100kHz. spi_clk_pol = 1; spi_clk_pha = 0; spi_set_transfer_delay(SPI_MASTER_BASE, spi_chip_sel, SPI_DLYBS, SPI_DLYBCT); spi_set_bits_per_transfer(SPI_MASTER_BASE, spi_chip_sel, SPI_CSR_BITS_16_BIT); spi_set_baudrate_div(SPI_MASTER_BASE, spi_chip_sel, spi_calc_baudrate_div(spi_clk_freq, sysclk_get_cpu_hz())); spi_configure_cs_behavior(SPI_MASTER_BASE, spi_chip_sel, SPI_CS_RISE_FORCED); // CS rises after SPI transfers have completed. spi_set_clock_polarity(SPI_MASTER_BASE, spi_chip_sel, spi_clk_pol); spi_set_clock_phase(SPI_MASTER_BASE, spi_chip_sel, spi_clk_pha); /* Set communication parameters for CS1 */ spi_chip_sel = 1; spi_clk_freq = 2000000; // SPI CLK for RTC = 4MHz. spi_clk_pol = 0; spi_clk_pha = 0; spi_set_transfer_delay(SPI_MASTER_BASE, spi_chip_sel, SPI_DLYBS, SPI_DLYBCT); spi_set_bits_per_transfer(SPI_MASTER_BASE, spi_chip_sel, SPI_CSR_BITS_8_BIT); spi_set_baudrate_div(SPI_MASTER_BASE, spi_chip_sel, spi_calc_baudrate_div(spi_clk_freq, sysclk_get_cpu_hz())); spi_configure_cs_behavior(SPI_MASTER_BASE, spi_chip_sel, SPI_CS_RISE_FORCED); spi_set_clock_polarity(SPI_MASTER_BASE, spi_chip_sel, spi_clk_pol); spi_set_clock_phase(SPI_MASTER_BASE, spi_chip_sel, spi_clk_pha); /* Set communication parameters for CS2 */ spi_chip_sel = 2; spi_clk_freq = 44000000; // SPI CLK for MEM2 = 44MHz. spi_clk_pol = 1; spi_clk_pha = 0; spi_set_transfer_delay(SPI_MASTER_BASE, spi_chip_sel, SPI_DLYBS, SPI_DLYBCT); spi_set_bits_per_transfer(SPI_MASTER_BASE, spi_chip_sel, SPI_CSR_BITS_8_BIT); spi_set_baudrate_div(SPI_MASTER_BASE, spi_chip_sel, spi_calc_baudrate_div(spi_clk_freq, sysclk_get_cpu_hz())); spi_configure_cs_behavior(SPI_MASTER_BASE, spi_chip_sel, SPI_CS_KEEP_LOW); spi_set_clock_polarity(SPI_MASTER_BASE, spi_chip_sel, spi_clk_pol); spi_set_clock_phase(SPI_MASTER_BASE, spi_chip_sel, spi_clk_pha); /* Enable SPI Communication */ spi_enable(SPI_MASTER_BASE); }
/** * \brief Set up an SPI device. * * The returned device descriptor structure must be passed to the driver * whenever that device should be used as current slave device. * * \param p_spi Base address of the SPI instance. * \param device Pointer to SPI device struct that should be initialized. * \param flags SPI configuration flags. Common flags for all * implementations are the SPI modes SPI_MODE_0 ... * SPI_MODE_3. * \param baud_rate Baud rate for communication with slave device in Hz. * \param sel_id Board specific select id. */ void spi_master_setup_device(Spi *p_spi, struct spi_device *device, spi_flags_t flags, uint32_t baud_rate, board_spi_select_id_t sel_id) { sel_id = sel_id; spi_set_transfer_delay(p_spi, device->id, CONFIG_SPI_MASTER_DELAY_BS, CONFIG_SPI_MASTER_DELAY_BCT); spi_set_bits_per_transfer(p_spi, device->id, CONFIG_SPI_MASTER_BITS_PER_TRANSFER); spi_set_baudrate_div(p_spi, device->id, spi_calc_baudrate_div(baud_rate, sysclk_get_cpu_hz())); spi_configure_cs_behavior(p_spi, device->id, SPI_CS_KEEP_LOW); spi_set_clock_polarity(p_spi, device->id, flags >> 1); spi_set_clock_phase(p_spi, device->id, ((flags & 0x1) ^ 0x1)); }
/** * \brief Set up an SPI device. * * The returned device descriptor structure must be passed to the driver * whenever that device should be used as current slave device. * * \param p_spi Base address of the SPI instance. * \param device Pointer to SPI device struct that should be initialized. * \param flags SPI configuration flags. Common flags for all * implementations are the SPI modes SPI_MODE_0 ... * SPI_MODE_3. * \param baud_rate Baud rate for communication with slave device in Hz. * \param sel_id Board specific select id. */ void spi_master_setup_device(Spi *p_spi, struct spi_device *device, spi_flags_t flags, uint32_t baud_rate, board_spi_select_id_t sel_id) { int16_t baud_div = spi_calc_baudrate_div(baud_rate, sysclk_get_cpu_hz()); /* avoid Cppcheck Warning */ UNUSED(sel_id); if (-1 == baud_div) { Assert(0 == "Failed to find baudrate divider"); } spi_set_transfer_delay(p_spi, device->id, CONFIG_SPI_MASTER_DELAY_BS, CONFIG_SPI_MASTER_DELAY_BCT); spi_set_bits_per_transfer(p_spi, device->id, CONFIG_SPI_MASTER_BITS_PER_TRANSFER); spi_set_baudrate_div(p_spi, device->id, baud_div); spi_configure_cs_behavior(p_spi, device->id, SPI_CS_KEEP_LOW); spi_set_clock_polarity(p_spi, device->id, flags >> 1); spi_set_clock_phase(p_spi, device->id, ((flags & 0x1) ^ 0x1)); }
/** * \brief Set up an SPI device. * * The returned device descriptor structure must be passed to the driver * whenever that device should be used as current slave device. * * \param p_spi Base address of the SPI instance. * \param device Pointer to SPI device struct that should be initialized. * \param flags SPI configuration flags. Common flags for all * implementations are the SPI modes SPI_MODE_0 ... * SPI_MODE_3. * \param baud_rate Baud rate for communication with slave device in Hz. * \param sel_id Board specific select id. */ void spi_master_setup_device(Spi *p_spi, const struct spi_device *device, spi_flags_t flags, uint32_t baud_rate, board_spi_select_id_t sel_id) { /* avoid Cppcheck Warning */ UNUSED(sel_id); UNUSED(flags); spi_reset(p_spi); spi_set_transfer_delay(p_spi, device->id, CONFIG_SPI_MASTER_DELAY_BS, CONFIG_SPI_MASTER_DELAY_BCT); spi_set_bits_per_transfer(p_spi, device->id, CONFIG_SPI_MASTER_BITS_PER_TRANSFER); int16_t baud_div = spi_calc_baudrate_div(baud_rate, SystemCoreClock); spi_set_baudrate_div(p_spi, device->id, baud_div); spi_configure_cs_behavior(p_spi, device->id, SPI_CS_KEEP_LOW); spi_set_clock_polarity(p_spi, device->id, flags >> 1); spi_set_clock_phase(p_spi, device->id, ((flags & 0x1) ^ 0x1)); }
/** Set the SPI baud rate * * Actual frequency may differ from the desired frequency due to available dividers and bus clock * Configures the SPI peripheral's baud rate * @param[in,out] obj The SPI object to configure * @param[in] hz The baud rate in Hz */ void spi_frequency(spi_t *obj, int hz){ spi_disable(obj->spi.spi_base); int16_t baudrate_div=spi_calc_baudrate_div(hz, sysclk_get_cpu_hz()); spi_set_baudrate_div(obj->spi.spi_base,obj->spi.cs,(uint8_t)baudrate_div); spi_enable(obj->spi.spi_base); }