Wednesday, October 7, 2015

Assigning I/O to peripheral with IOPORT

Previously I mentioned that I couldn't assign the I/O PINs to SPI (which is the 'A' peripherial) with IOPORT. That was frustrating, because I had to use GPIO for that purpose which is a deprecated service.

Today I managed to solve this issue, here is the solution:


#define SPI_MISO_IOPIN  IOPORT_CREATE_PIN(PIOA, PIO_PA12_IDX)
#define SPI_MOSI_IOPIN  IOPORT_CREATE_PIN(PIOA, PIO_PA13_IDX)
#define SPI_SPCK_IOPIN  IOPORT_CREATE_PIN(PIOA, PIO_PA14_IDX)
#define SPI_NPCS1_IOPIN  IOPORT_CREATE_PIN(PIOA, PIO_PA31_IDX)


 ioport_set_pin_mode(SPI_MISO_IOPIN, PIO_PERIPH_A);
 ioport_disable_pin(SPI_MISO_IOPIN);
 ioport_set_pin_mode(SPI_MOSI_IOPIN, PIO_PERIPH_A);
 ioport_disable_pin(SPI_MOSI_IOPIN);
 ioport_set_pin_mode(SPI_SPCK_IOPIN, PIO_PERIPH_A);
 ioport_disable_pin(SPI_SPCK_IOPIN);
 ioport_set_pin_mode(SPI_NPCS1_IOPIN, PIO_PERIPH_A);
 ioport_disable_pin(SPI_NPCS1_IOPIN);

The trick is that you have to disable the pin after assigning it to one of the peripherals.

If you implemented your SPI communication based on my previous post and you want to get rid of GPIO, add the defines to your header file and overwrite the spi_init function with the followings:


void spi_init(void)
{
 
 ioport_set_pin_mode(SPI_MISO_IOPIN, PIO_PERIPH_A);
 ioport_disable_pin(SPI_MISO_IOPIN);
 ioport_set_pin_mode(SPI_MOSI_IOPIN, PIO_PERIPH_A);
 ioport_disable_pin(SPI_MOSI_IOPIN);
 ioport_set_pin_mode(SPI_SPCK_IOPIN, PIO_PERIPH_A);
 ioport_disable_pin(SPI_SPCK_IOPIN);
 ioport_set_pin_mode(SPI_NPCS1_IOPIN, PIO_PERIPH_A);
 ioport_disable_pin(SPI_NPCS1_IOPIN);
 
 
 spi_enable_clock(SPI_MASTER_BASE);
 spi_disable(SPI_MASTER_BASE);
 spi_reset(SPI_MASTER_BASE);
 spi_set_lastxfer(SPI_MASTER_BASE);
 spi_set_master_mode(SPI_MASTER_BASE);
 spi_disable_mode_fault_detect(SPI_MASTER_BASE);
 spi_set_peripheral_chip_select_value(SPI_MASTER_BASE, SPI_CHIP_PCS);

 spi_configure_cs_behavior(SPI, 1, SPI_CS_RISE_NO_TX);//SPI_CS_KEEP_LOW
 spi_set_clock_polarity(SPI_MASTER_BASE, SPI_CHIP_SEL, SPI_CLK_POLARITY);
 spi_set_clock_phase(SPI_MASTER_BASE, SPI_CHIP_SEL, SPI_CLK_PHASE);
 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,(sysclk_get_cpu_hz() / gs_ul_spi_clock));
 spi_set_transfer_delay(SPI_MASTER_BASE, SPI_CHIP_SEL, SPI_DLYBS,
 SPI_DLYBCT);
 spi_enable(SPI_MASTER_BASE);
}

If you like my post and/or it was useful, please, leave some comment. If you don't, let me know that too. :-)

1 comment:

  1. I spent days trying to make the SPI module work. Thanks!

    ReplyDelete