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

The SPI Slave 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 handle:

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

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

IFX_INTERRUPT(qspi2TxISR, 0, IFX_INTPRIO_QSPI2_TX)
{
}
IFX_INTERRUPT(qspi2RxISR, 0, IFX_INTPRIO_QSPI2_RX)
{
}
IFX_INTERRUPT(qspi2ErISR, 0, IFX_INTPRIO_QSPI2_ER)
{
}

Finally install the interrupt handlers in your initialisation function:

// install interrupt handlers
IfxCpu_Irq_installInterruptHandler(&qspi2TxISR, IFX_INTPRIO_QSPI2_TX);
IfxCpu_Irq_installInterruptHandler(&qspi2RxISR, IFX_INTPRIO_QSPI2_RX);
IfxCpu_Irq_installInterruptHandler(&qspi2ErISR, IFX_INTPRIO_QSPI2_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:

// priorities are normally defined in Ifx_IntPrioDef.h
// qspi priorities
#define IFX_INTPRIO_QSPI2_TX 3 // DMA channel 3
#define IFX_INTPRIO_QSPI2_RX 4 // DMA channel 4
#define IFX_INTPRIO_QSPI2_ER 0x31
// dma priorities
#define IFX_INTPRIO_DMA_CH3 12
#define IFX_INTPRIO_DMA_CH4 13

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

IFX_INTERRUPT(qspi2DmaTxISR, 0, IFX_INTPRIO_DMA_CH3)
{
}
IFX_INTERRUPT(qspi2DmaRxISR, 0, IFX_INTPRIO_DMA_CH4)
{
}
IFX_INTERRUPT(qspi2ErISR, 0, IFX_INTPRIO_QSPI2_ER)
{
}

Finally install the interrupt handlers in your initialisation function:

// install interrupt handlers
IfxCpu_Irq_installInterruptHandler(&qspi2DmaTxISR, IFX_INTPRIO_DMA_CH3);
IfxCpu_Irq_installInterruptHandler(&qspi2DmaRxISR, IFX_INTPRIO_DMA_CH4);
IfxCpu_Irq_installInterruptHandler(&qspi2ErISR, IFX_INTPRIO_QSPI2_ER);

Module Initialisation (without dma use)

The module initialisation can be done in the same function.

Here an example for slave mode:

// create module config
IfxQspi_SpiSlave_Config spiSlaveConfig;
IfxQspi_SpiSlave_initModuleConfig(&spiSlaveConfig, &MODULE_QSPI2);
// set the maximum baudrate
spiSlaveConfig.base.maximumBaudrate = 10000000;
// ISR priorities and interrupt target
spiSlaveConfig.base.txPriority = IFX_INTPRIO_QSPI2_TX;
spiSlaveConfig.base.rxPriority = IFX_INTPRIO_QSPI2_RX;
spiSlaveConfig.base.erPriority = IFX_INTPRIO_QSPI2_ER;
// pin configuration
const IfxQspi_SpiSlave_Pins slavePins = {
};
spiSlaveConfig.pins = &slavePins;
// initialize module
//IfxQspi_Spi spi; // defined globally
IfxQspi_SpiSlave_initModule(&spi, &spiSlaveConfig);

Module Initialisation (with dma use)

The module initialisation can be done in the same function.

Here an example for slave mode:

// create module config
IfxQspi_SpiSlave_Config spiSlaveConfig;
IfxQspi_SpiSlave_initModuleConfig(&spiSlaveConfig, &MODULE_QSPI2);
// set the maximum baudrate
spiSlaveConfig.base.maximumBaudrate = 10000000;
// ISR priorities and interrupt target (with dma usage)
spiSlaveConfig.base.txPriority = IFX_INTPRIO_DMA_CH3;
spiSlaveConfig.base.rxPriority = IFX_INTPRIO_DMA_CH4;
spiSlaveConfig.base.erPriority = IFX_INTPRIO_QSPI2_ER;
spiSlaveConfig.dma.useDma = 1;
// pin configuration
const IfxQspi_SpiSlave_Pins slavePins = {
};
spiSlaveConfig.pins = &slavePins;
// initialize module
//IfxQspi_Spi spi; // defined globally
IfxQspi_SpiSlave_initModule(&spi, &spiSlaveConfig);

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_SpiSlave_exchange(&spi, &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_SpiSlave_exchange(&spi, &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_SpiSlave_exchange(&spi, NULL_PTR, &spiRxBuffer[i], SPI_BUFFER_SIZE);