/** * \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 Initialize the SPI in master mode. * * \param p_spi Base address of the SPI instance. * */ void spi_master_init(Spi *p_spi) { spi_enable_clock(p_spi); spi_reset(p_spi); spi_set_master_mode(p_spi); spi_disable_mode_fault_detect(p_spi); spi_disable_loopback(p_spi); spi_set_peripheral_chip_select_value(p_spi, DEFAULT_CHIP_ID); spi_set_fixed_peripheral_select(p_spi); spi_disable_peripheral_select_decode(p_spi); spi_set_delay_between_chip_select(p_spi, CONFIG_SPI_MASTER_DELAY_BCS); }
spi_p spi_new_instance(Spi * spi_base, uint8_t spi_chip_sel, uint32_t spi_freq, uint8_t spi_mode, uint8_t buffer_size, void(*handler_call_back )(spi_p, uint8_t)) { _spi_base = spi_base; if (!spi_is_enabled(_spi_base)) { _spi_init_base(spi_base); } spi_p _spi = malloc(sizeof *_spi); _spi->_call_back = handler_call_back; _spi->_cs_pin = spi_chip_sel; _spi->_spi_rx_fifo_desc = (fifo_desc_t *)malloc(sizeof(fifo_desc_t)); _spi->_spi_tx_fifo_desc = (fifo_desc_t *)malloc(sizeof(fifo_desc_t)); union spi_buffer_element *spi_tx_fifo_buffer = (union spi_buffer_element *)(malloc(sizeof(union spi_buffer_element) * buffer_size)); union spi_buffer_element *spi_rx_fifo_buffer = (union spi_buffer_element *)(malloc(sizeof(union spi_buffer_element) * buffer_size)); fifo_init(_spi->_spi_rx_fifo_desc, spi_rx_fifo_buffer, buffer_size); fifo_init(_spi->_spi_tx_fifo_desc, spi_tx_fifo_buffer, buffer_size); spi_set_peripheral_chip_select_value(spi_base, spi_get_pcs(spi_chip_sel)); switch (spi_mode) { case 0: spi_set_clock_polarity(spi_base, spi_chip_sel,0); spi_set_clock_phase(spi_base, spi_chip_sel, 1); break; case 1: spi_set_clock_polarity(spi_base, spi_chip_sel, 0); spi_set_clock_phase(spi_base, spi_chip_sel, 0); break; case 2: spi_set_clock_polarity(spi_base, spi_chip_sel, 1); spi_set_clock_phase(spi_base, spi_chip_sel, 1); break; case 3: spi_set_clock_polarity(spi_base, spi_chip_sel, 1); spi_set_clock_phase(spi_base, spi_chip_sel, 0); break; } spi_set_bits_per_transfer(spi_base, spi_chip_sel, SPI_CSR_BITS_8_BIT); spi_configure_cs_behavior(spi_base, spi_chip_sel, SPI_CS_KEEP_LOW); spi_set_baudrate_div(spi_base, spi_chip_sel, (sysclk_get_peripheral_hz() / spi_freq)); spi_set_delay_between_chip_select(spi_base, 0x10); spi_set_transfer_delay(spi_base, spi_chip_sel, 0x01, 0x10); spi_enable(spi_base); return _spi; }
/** \brief Initialize the SPI in master mode. * * \param p_spi Base address of the SPI instance. * */ void spi_master_init(Spi *p_spi) { #if SAMG55 flexcom_enable(BOARD_FLEXCOM_SPI); flexcom_set_opmode(BOARD_FLEXCOM_SPI, FLEXCOM_SPI); #else spi_enable_clock(p_spi); #endif spi_reset(p_spi); spi_set_master_mode(p_spi); spi_disable_mode_fault_detect(p_spi); spi_disable_loopback(p_spi); spi_set_peripheral_chip_select_value(p_spi, DEFAULT_CHIP_ID); spi_set_fixed_peripheral_select(p_spi); spi_disable_peripheral_select_decode(p_spi); spi_set_delay_between_chip_select(p_spi, CONFIG_SPI_MASTER_DELAY_BCS); }