iLLD_TC27xC  1.0
How to use the SPI Master Interface driver?
Collaboration diagram for How to use the SPI Master Interface driver?:

The SPI Master interface driver provides a default QSPI configuration for a bidirectional serial communication of data words.

Data transactions are buffered by the hardware based FIFOs. Incoming and outgoing data is transfered in background from/to the QSPI peripheral by interrupt service handlers, which are part of this driver as well. This allows a nonblocking communication without stalling the thread(s) from where data is sent and received. Optionally Dma can be used for data transfers. Only the interrupt configuration and Module initialisation are different when dma is used.

In the following sections it will be described, how to integrate the driver into the application framework.

Preparation

Include Files

Include following header file into your C code:

Variables

Declare QSPI module and channel handles:

In addition, declare global transmit and receive buffers for the data transfers:

#define SPI_BUFFER_SIZE 8
uint8 spiTxBuffer[SPI_BUFFER_SIZE];
uint8 spiRxBuffer[SPI_BUFFER_SIZE];

Interrupt Handler Installation (without dma use)

See also IfxLld_Cpu_Interrupt_Usage

Define priorities for the Interrrupt handlers. This is normally done in the Ifx_IntPrioDef.h file:

// priorities are normally defined in Ifx_IntPrioDef.h
#define IFX_INTPRIO_QSPI0_TX 1
#define IFX_INTPRIO_QSPI0_RX 2
#define IFX_INTPRIO_QSPI0_ER 5

Add the interrupt service routines to your C code. They have to call the QSPI interrupt handlers by passing the spi handle:

IFX_INTERRUPT(qspi0TxISR, 0, IFX_INTPRIO_QSPI0_TX)
{
}
IFX_INTERRUPT(qspi0RxISR, 0, IFX_INTPRIO_QSPI0_RX)
{
}
IFX_INTERRUPT(qspi0ErISR, 0, IFX_INTPRIO_QSPI0_ER)
{
}

Finally install the interrupt handlers in your initialisation function:

// install interrupt handlers
IfxCpu_Irq_installInterruptHandler(&qspi0TxISR, IFX_INTPRIO_QSPI0_TX);
IfxCpu_Irq_installInterruptHandler(&qspi0RxISR, IFX_INTPRIO_QSPI0_RX);
IfxCpu_Irq_installInterruptHandler(&qspi0ErISR, IFX_INTPRIO_QSPI0_ER);

Interrupt Handler Installation (with dma use)

See also IfxLld_Cpu_Interrupt_Usage

Define priorities for the Interrrupt handlers. This is normally done in the Ifx_IntPrioDef.h file:

// qspi priorities
#define IFX_INTPRIO_QSPI0_TX 1 // DMA channel 1
#define IFX_INTPRIO_QSPI0_RX 2 // DMA channel 2
#define IFX_INTPRIO_QSPI0_ER 0x30
// dma priorities
#define IFX_INTPRIO_DMA_CH1 10
#define IFX_INTPRIO_DMA_CH2 11

Add the interrupt service routines to your C code. They have to call the QSPI interrupt handlers by passing the spi handle:

IFX_INTERRUPT(qspi0DmaTxISR, 0, IFX_INTPRIO_DMA_CH1 )
{
}
IFX_INTERRUPT(qspi0DmaRxISR, 0, IFX_INTPRIO_DMA_CH2)
{
}
IFX_INTERRUPT(qspi0ErISR, 0, IFX_INTPRIO_QSPI0_ER)
{
}

Finally install the interrupt handlers in your initialisation function:

// install interrupt handlers
IfxCpu_Irq_installInterruptHandler(&qspi0DmaTxISR, IFX_INTPRIO_DMA_CH1);
IfxCpu_Irq_installInterruptHandler(&qspi0DmaRxISR, IFX_INTPRIO_DMA_CH2);
IfxCpu_Irq_installInterruptHandler(&qspi0ErISR, IFX_INTPRIO_QSPI0_ER);

Module Initialisation (without dma use)

The module initialisation can be done in the same function.

Here an example for master mode:

// create module config
IfxQspi_SpiMaster_Config spiMasterConfig;
IfxQspi_SpiMaster_initModuleConfig(&spiMasterConfig, &MODULE_QSPI0);
// set the desired mode and maximum baudrate
spiMasterConfig.base.mode = SpiIf_Mode_master;
spiMasterConfig.base.maximumBaudrate = 10000000;
// ISR priorities and interrupt target
spiMasterConfig.base.txPriority = IFX_INTPRIO_QSPI0_TX;
spiMasterConfig.base.rxPriority = IFX_INTPRIO_QSPI0_RX;
spiMasterConfig.base.erPriority = IFX_INTPRIO_QSPI0_ER;
// pin configuration
const IfxQspi_SpiMaster_Pins pins = {
};
spiMasterConfig.pins = &pins;
// initialize module
//IfxQspi_SpiMaster spi; // defined globally
IfxQspi_SpiMaster_initModule(&spi, &spiMasterConfig);

Module Initialisation (with dma use)

The module initialisation can be done in the same function.

Here an example for master mode:

// create module config
IfxQspi_SpiMaster_Config spiMasterConfig;
IfxQspi_SpiMaster_initModuleConfig(&spiMasterConfig, &MODULE_QSPI0);
// set the desired mode and maximum baudrate
spiMasterConfig.base.mode = SpiIf_Mode_master;
spiMasterConfig.base.maximumBaudrate = 10000000;
// ISR priorities and interrupt target (with Dma usage)
spiMasterConfig.base.txPriority = IFX_INTPRIO_DMA_CH1;
spiMasterConfig.base.rxPriority = IFX_INTPRIO_DMA_CH2;
spiMasterConfig.base.erPriority = IFX_INTPRIO_QSPI0_ER;
// dma configuration.
spiMasterConfig.dma.useDma = 1;
// pin configuration
const IfxQspi_SpiMaster_Pins pins = {
};
spiMasterConfig.pins = &Pins;
// initialize module
//IfxQspi_SpiMaster spi; // defined globally
IfxQspi_SpiMaster_initModule(&spi, &spiMasterConfig);

SPI Channel Initialisation

After the module has been initialized, one or more SPI channels can be configured. Each channel has a dedicated select line.

Here an example for a SPI channel in master mode:

// create channel config
IfxQspi_SpiMaster_ChannelConfig spiMasterChannelConfig;
IfxQspi_SpiMaster_initChannelConfig(&spiMasterChannelConfig, &spi);
// set the baudrate for this channel
spiMasterChannelConfig.base.baudrate = 5000000;
// select pin configuration
const IfxQspi_SpiMaster_Output slsOutput = {
};
spiMasterChannelConfig.sls.output = (IfxQspi_SpiMaster_Output)slsOutput;
// initialize channel
//IfxQspi_SpiMaster_Channel spiChannel; // defined globally
IfxQspi_SpiMaster_initChannel(&spiChannel, &spiMasterChannelConfig);

The QSPI is ready for use now!

Data Transfers

In following examples we assume, that following buffers are declared globally:

// declared somewhere globally
#define SPI_BUFFER_SIZE 8
uint8 spiTxBuffer[SPI_BUFFER_SIZE] = { 1, 2, 3, 4, 5, 6, 7, 8 };
uint8 spiRxBuffer[SPI_BUFFER_SIZE] = { 0, 0, 0, 0, 0, 0, 0, 0 };

Sending and Receiving a data stream:

// wait until transfer of previous data stream is finished
// send/receive new stream
IfxQspi_SpiMaster_exchange(&spiChannel, &spiTxBuffer[i], &spiRxBuffer[i], SPI_BUFFER_SIZE);

Send only, discard received data:

// wait until transfer of previous data stream is finished
// send new stream
IfxQspi_SpiMaster_exchange(&spiChannel, &spiTxBuffer[i], NULL_PTR, SPI_BUFFER_SIZE);

Receive only, send all-1

// wait until transfer of previous data stream is finished
// receive new stream
IfxQspi_SpiMaster_exchange(&spiChannel, NULL_PTR, &spiRxBuffer[i], SPI_BUFFER_SIZE);