Skip to content

SPI transfer in master mode

SPI tutorial will guide you through initializing and working with the SPI module of your MCU using mikroSDK 2.0.
In order to follow this tutorial, you will need to have familiarized yourself with context and configuration structures, their purpose and their proper initialization.
The following example will show the correct way of using the SPI driver in mikroSDK V2.

To start, we need to include the SPI driver. In this case, we need the drv_spi_master.h as our MCU will act as master:

#include "drv_spi_master.h"

Immediately after, we declare our context structures and a configuration structure, as the SPI driver also requires one.
We will as well declare two buffers tx_buffer and rx_buffer that will be used to store the data sent/received via SPI.

spi_master_t spi;                    // SPI master driver context structure.
spi_master_config_t spi_master_cfg;  // SPI master driver configuration structure.

uint8_t tx_buffer[3];
uint8_t rx_buffer[3];

Let us move onto initializing the configuration structure and the SPI driver context:

spi_master_configure_default( &spi_master_cfg );  /* Initialize SPI master
configuration structure to default values  */

spi_master_cfg.sck = PA9;
spi_master_cfg.miso = PA10;
spi_master_cfg.mosi = PA11;

spi_master_open( &spi, &spi_master_cfg );  // Initializes SPI master driver object.
spi_master_set_speed( &spi, 100000 );      // Set SPI clock frequency 

We use the spi_master_configure_default() function to initialize the configuration structure to its default values.
However, we would like to change on which pins we want to initialize SPI.
We do that by accessing each field via spi_master_cfg and stating the desired pin.
spi_master_open() function initializes the SPI driver object and spi_master_set_speed() sets the desired SPI clock frequency.

We put some random values in the tx_buffer to send over SPI and specify how many bytes we wish to send or receive. In this case we are sending and receiving same amount of bytes:

#define byte_count 3

tx_buffer[0] = 0xAA;
tx_buffer[1] = 0xBB;
tx_buffer[2] = 0xCC;

spi_master_select_device( PC0 );    // Chip select
spi_master_write_then_read( &spi, &tx_buffer, byte_count, &rx_buffer, byte_count );    // Perform SPI transfer.
spi_master_deselect_device( PC0 );  // Chip select

spi_master_select_device() and spi_master_deselect_device() are equivalent to setting the chip select pin low and high.
spi_master_write_then_read() function does the actual transfer in which we send our three bytes from tx_buffer then read out three bytes and store them into rx_buffer.

The entire code can be found below:

#include "drv_spi_master.h"

#define byte_count 3

spi_master_t spi;
spi_master_config_t spi_master_cfg;

uint8_t tx_buffer[3];
uint8_t rx_buffer[3];

tx_buffer[0] = 0xAA;
tx_buffer[1] = 0xBB;
tx_buffer[2] = 0xCC;

void application_init ( void )
{
    spi_master_configure_default( &spi_master_cfg );

    spi_master_cfg.sck = PA9;
    spi_master_cfg.miso = PA10;
    spi_master_cfg.mosi = PA11;

    spi_master_open( &spi, &spi_master_cfg );
    spi_master_set_speed( &spi, 100000 );

    spi_master_select_device( PC0 );
    spi_master_write_then_read( &spi, &tx_buffer, byte_count, &rx_buffer, byte_count );
    spi_master_deselect_device( PC0 );
}

void application_task ( void )
{
    asm nop;
}

void main ( void )
{
    application_init( );

    for ( ; ; )
    {
        application_task( );
    }
}