Atmel Software Framework

Quick start guide for SPI master on UC3 devices

Basic setup for UC3 devices

The SPI module will be set up as master:

  • SPI on module SPI0
  • 1MHz SPI clock speed
  • Slave Chip Select connected on NPCS1
  • 8 bits per transfer
  • SPI mode 0 (data on rising clock edge)

Workflow

Example code

Add to application C-file (e.g. main.c):

#define SPI_EXAMPLE (&AVR32_SPI0)
struct spi_device spi_device_conf = {
.id = 1
};
void spi_init_module(void)
{
//Init SPI module as master
spi_master_init(SPI_EXAMPLE);
//Setup parameters for the slave device
spi_master_setup_device(SPI_EXAMPLE, &spi_device_conf, SPI_MODE_0, 1000000, 0);
//Allow the module to transfer data
spi_enable(SPI_EXAMPLE);
}

Workflow

  1. Ensure that board_init() has configured selected I/Os for SPI function.
  2. Ensure that conf_spi_master.h is present for the driver.
    • Note
      This file is only for the driver and should not be included by the user. In this example, the file can be left empty.
  3. Define an alias for the SPI module you want to use :
    #define SPI_EXAMPLE (&AVR32_SPI0)
  4. Create the structure for the device id (Chip select)
    struct spi_device spi_device_conf = {
    .id = 1
    };
    • Note
      As this struct is the same for both the initializing part and the usage part it could be a good idea to make the struct global, and hence accessible for both the initializing part and usage part.
  5. Write the initialization function to setup the module :
    void spi_init_module(void)
    {
    //Init SPI module as master
    spi_master_init(SPI_EXAMPLE);
    //Setup parameters for the slave device : id, mode, baudrate
    spi_master_setup_device(SPI_EXAMPLE, &spi_device_conf, SPI_MODE_0, 1000000, 0);
    //Allow the module to transfer data
    spi_enable(SPI_EXAMPLE);
    }
    • Note
      The last argument of spi_master_setup_device, which is zero in this case, can be ignored and is only included for compatibility purposes.
  6. Call the initialization routine from your application.
    • spi_init_module();

Usage steps

Example code

Use in application C-file:

//Buffer to send data to SPI slave
uint8_t txdata[1]={0xD7};
//Buffer to receive data from SPI slave
uint8_t rxdata[1];
...
// Select the slave device with chip select
spi_select_device(SPI_EXAMPLE,&spi_device_conf);
// Send the data to slave
spi_write_packet(SPI_EXAMPLE, txdata, 1);
// Read data from slave
spi_read_packet(SPI_EXAMPLE, rxdata,1);
// Deselect the slave
spi_deselect_device(SPI_EXAMPLE,&spi_device_conf);

Workflow

  1. Create two buffers for data to be sent/received on the SPI bus, The buffer can be of arbitrary size as long as there is space left in SRAM:
    • //Buffer to send data to SPI slave
      uint8_t txdata[1]={0xD7};
      //Buffer to receive data from SPI slave
      uint8_t rxdata[1];
    • Note
      In this case, we have set a default value for the txdata which is a status read command to a spi memory chip.
  2. Call the spi_select_device routine to enable the chip select line for the slave you want to communicate with. The chip select enabled is defined by the value of the id field in the spi_device_conf struct
    spi_select_device(SPI_EXAMPLE,&spi_device_conf);
  3. Write data to the SPI slave device, in this case write one byte from the data buffer txdata:
  4. Read data from the SPI slave device, in this case read one byte and put it into the data buffer rxdata:
    • spi_read_packet(SPI_EXAMPLE, rxdata,1);
    • Attention
      As the SPI works as a shift register so that data is shifted in at the same time as data is shifted out a read operation will mean that a dummy byte CONFIG_SPI_MASTER_DUMMY is written to the SPI bus. CONFIG_SPI_MASTER_DUMMY defaults to 0xFF, but can be changed by defining it inside the conf_spi_master.h file.
  5. When read and write operations is done, de-select the slave:
  6. Now you can use the data read from the slave which is in rxdata
    • //Check read content
      if(rxdata[0]<0x3C)
      do_something();