Hardware Abstraction Layer (HAL)
All Data Structures Functions Variables Typedefs Enumerations Enumerator Modules Pages
SPI (Serial Peripheral Interface)

General Description

High level interface for interacting with the Serial Peripheral Interface (SPI).

The SPI protocol is a synchronous serial interface protocol. Devices operate in either controller or target mode. The controller initiates the data transfer.

Features

Quick Start

Initialise a SPI controller or target interface using the PDL. The data rate can be set using mtb_hal_spi_set_frequency().
See Code snippets for code snippets to send or receive the data.

Code snippets

Snippet 1: SPI controller or target initialization

The following code snippet initializes an SPI Controller or Target interface using the PDL.

cy_rslt_t rslt;
mtb_hal_spi_t spi_inst;
cy_stc_scb_spi_context_t spi_context;
// Configuring the SPI interface: Specify the SPI interface pins, frame size, SPI Motorola
// mode and slave/master mode
rslt = Cy_SCB_SPI_Init(SPI_HW, &SPI_config, &spi_context);
Cy_SCB_SPI_Enable(SPI_HW);
rslt = mtb_hal_spi_setup(&spi_inst, &SPI_hal_cfg, &spi_context, NULL);
// Activate SSEL pin you selected
Cy_SCB_SPI_SetActiveSlaveSelect(SPI_HW, CY_SCB_SPI_SLAVE_SELECT0);
uint32_t cy_rslt_t
Provides the result of an operation as a structured bitfield.
Definition: cy_result.h:457
SPI object.
Definition: mtb_hal_hw_types_spi_scb.h:58

Snippet 2: SPI controller - Single byte transfer operation (Read and Write)

The following code snippet initializes an SPI Controller interface using the PDL. The data rate of transfer is set using mtb_hal_spi_set_frequency(). The code snippet shows how to transfer a single byte of data using mtb_hal_spi_put() and mtb_hal_spi_get().

cy_rslt_t rslt;
mtb_hal_spi_t spi_controller;
uint32_t spi_controller_frequency = 1000000;
uint32_t transmit_data = 0x01;
uint32_t receive_data;
cy_stc_scb_spi_context_t spi_context;
// Configuring the SPI controller: Specify the SPI interface pins, frame size, SPI Motorola mode
// and controller mode
rslt = Cy_SCB_SPI_Init(SPI_HW, &SPI_config, &spi_context);
Cy_SCB_SPI_Enable(SPI_HW);
rslt = mtb_hal_spi_setup(&spi_controller, &SPI_hal_cfg, &spi_context, NULL);
Cy_SCB_SPI_SetActiveSlaveSelect(SPI_HW, CY_SCB_SPI_SLAVE_SELECT0);
// Set the data rate to 1 Mbps
rslt = mtb_hal_spi_set_frequency(&spi_controller, spi_controller_frequency);
// Transfer one byte of data to the target.
if (CY_RSLT_SUCCESS == mtb_hal_spi_put(&spi_controller, transmit_data))
{
// Receives one byte of data from the target by transmiting a dummy byte 0xFF.
if (CY_RSLT_SUCCESS == mtb_hal_spi_get(&spi_controller, &receive_data))
{
// Transfer Complete and successful
}
}
cy_rslt_t mtb_hal_spi_set_frequency(mtb_hal_spi_t *obj, uint32_t hz)
Set the SPI baud rate.
Definition: mtb_hal_spi.c:276
cy_rslt_t mtb_hal_spi_put(mtb_hal_spi_t *obj, uint32_t value)
Synchronously send a byte out.
Definition: mtb_hal_spi.c:368
cy_rslt_t mtb_hal_spi_get(mtb_hal_spi_t *obj, uint32_t *value)
Synchronously get a received value out of the SPI receive buffer.
Definition: mtb_hal_spi.c:348
#define CY_RSLT_SUCCESS
cy_rslt_t return value indicating success
Definition: cy_result.h:484

Snippet 3: SPI Target - Single byte transfer operation (Read and Write)

The following code snippet initializes an SPI Target interface using the PDL. The data rate of transfer is set using mtb_hal_spi_set_frequency. The code snippet shows how to transfer a single byte of data using mtb_hal_spi_put() and mtb_hal_spi_get.

cy_rslt_t rslt;
mtb_hal_spi_t spi_target;
uint32_t spi_target_frequency = 1000000;
uint32_t transmit_data = 1;
uint32_t receive_data;
cy_stc_scb_spi_context_t spi_context;
// Configuring the SPI target: Specify the SPI interface pins, frame size, SPI Motorola mode
// and target mode
rslt = Cy_SCB_SPI_Init(SPI_HW, &SPI_config, &spi_context);
Cy_SCB_SPI_Enable(SPI_HW);
rslt = mtb_hal_spi_setup(&spi_target, &SPI_hal_cfg, &spi_context, NULL);
Cy_SCB_SPI_SetActiveSlaveSelect(SPI_HW, CY_SCB_SPI_SLAVE_SELECT0);
// Set the data rate to 1 Mbps
rslt = mtb_hal_spi_set_frequency(&spi_target, spi_target_frequency);
// Place a byte in the TX FIFO to be read by the controller
if (CY_RSLT_SUCCESS == mtb_hal_spi_put(&spi_target, transmit_data))
{
// Get a received value out of the SPI receive buffer. This API Blocks until a value is
// available
if (CY_RSLT_SUCCESS == mtb_hal_spi_get(&spi_target, &receive_data))
{
// Transfer successful
}
}

Snippet 4: SPI Block Data transfer

The following snippet sends and receives an array of data in a single SPI transaction using mtb_hal_spi_transfer(). The example uses SPI controller to transmit 5 bytes of data and receive 5 bytes of data in a single transaction.

mtb_hal_spi_t spi__obj;
void spi_m_interrupt_callback(void)
{
}
void snippet_mtb_hal_spi_block_data_transfer(void)
{
cy_rslt_t rslt;
uint32_t spi_frequency = 1000000;
uint8_t transmit_data[5] = { 0x1, 0x2, 0x3, 0x4, 0x5 };
uint8_t receive_data[5];
cy_stc_scb_spi_context_t spi_context;
// Configuring the SPI interface: Specify the SPI interface pins, frame size, SPI Motorola
// mode and target/controller mode
rslt = Cy_SCB_SPI_Init(SPI_HW, &SPI_config, &spi_context);
Cy_SCB_SPI_Enable(SPI_HW);
rslt = mtb_hal_spi_setup(&spi__obj, &SPI_hal_cfg, &spi_context, NULL);
Cy_SCB_SPI_SetActiveSlaveSelect(SPI_HW, CY_SCB_SPI_SLAVE_SELECT0);
cy_stc_sysint_t intr_cfg = { .intrSrc = SPI_IRQ, .intrPriority = INT_PRIORITY };
Cy_SysInt_Init(&intr_cfg, spi_m_interrupt_callback);
NVIC_EnableIRQ(SPI_IRQ);
// Set the data rate to 1 Mbps
rslt = mtb_hal_spi_set_frequency(&spi__obj, spi_frequency);
// Controller: Starts a data transfer. Target: Prepares the target for data transfer. It is a
// blocking
// function
if (CY_RSLT_SUCCESS == mtb_hal_spi_transfer(&spi__obj, transmit_data, 5u, receive_data, 5u,
0xFF))
{
// Transfer Complete
}
(void)rslt;
}
cy_rslt_t mtb_hal_spi_transfer(mtb_hal_spi_t *obj, const uint8_t *tx, size_t tx_length, uint8_t *rx, size_t rx_length, uint8_t write_fill)
Synchronously Write a block out and receive a value.
Definition: mtb_hal_spi.c:462
cy_rslt_t mtb_hal_spi_process_interrupt(mtb_hal_spi_t *obj)
Process interrupts related to a SPI instance.
Definition: mtb_hal_spi.c:561

Snippet 5: SPI Target - Write Block Data

The following snippet sends an array of data in a single SPI transaction using mtb_hal_spi_target_write(). The example uses SPI target to transmit 5 bytes of data in a single transaction with 50 ms timeout values.

mtb_hal_spi_t spi_s_obj;
void spi_s_interrupt_callback(void)
{
}
void snippet_mtb_hal_spi_target_write_block_data(void)
{
cy_rslt_t rslt;
uint8_t transmit_data[5] = { 0x1, 0x2, 0x3, 0x4, 0x5 };
uint16_t buff_size = 5;
uint32_t timeout = 50;
cy_stc_scb_spi_context_t spi_context;
// Configuring the SPI Target: Specify the SPI interface pins, frame size, SPI Motorola
// mode and target mode
rslt = Cy_SCB_SPI_Init(SPI_HW, &SPI_config, &spi_context);
Cy_SCB_SPI_Enable(SPI_HW);
rslt = mtb_hal_spi_setup(&spi_s_obj, &SPI_hal_cfg, &spi_context, NULL);
Cy_SCB_SPI_SetActiveSlaveSelect(SPI_HW, CY_SCB_SPI_SLAVE_SELECT0);
cy_stc_sysint_t intr_cfg = { .intrSrc = SPI_IRQ, .intrPriority = INT_PRIORITY };
Cy_SysInt_Init(&intr_cfg, spi_s_interrupt_callback);
NVIC_EnableIRQ(SPI_IRQ);
// Target: Prepares the Tx data and wait Controller to start SPI transaction. It is a blocking
// function within timout value.
rslt = mtb_hal_spi_target_write(&spi_s_obj, transmit_data, &buff_size, timeout);
if (CY_RSLT_SUCCESS == rslt)
{
// Transfer Complete
}
else
{
// Timeout or Bad Argument
}
(void)rslt;
}
cy_rslt_t mtb_hal_spi_target_write(mtb_hal_spi_t *obj, const uint8_t *src_buff, uint16_t *size, uint32_t timeout)
Write data from the user-defined buffer to TX buffer and wait until either all data has been read fro...
Definition: mtb_hal_spi.c:432

Snippet 6: Interrupts on SPI events

SPI interrupt events (mtb_hal_spi_event_t) can be mapped to an interrupt and assigned to a callback function. The callback function needs to be first registered and then the event needs to be enabled. A callback function is registered using mtb_hal_spi_register_callback to notify whenever the SPI transfer is complete.

mtb_hal_spi_t spi_obj;
void spi_interrupt_callback(void)
{
}
// SPI event handler
void spi_event_handler(void* handler_arg, mtb_hal_spi_event_t event)
{
(void)handler_arg;
(void)event;
}
cy_rslt_t snippet_mtb_hal_spi_interrupt_callback_events(void)
{
cy_rslt_t rslt;
uint32_t spi_frequency = 1000000;
uint32_t rx_transfer_count = 5, tx_transfer_count = 5;
uint8_t receive_data[5];
uint8_t transmit_data[5] = { 0x1, 0x2, 0x3, 0x4, 0x5 };
cy_stc_scb_spi_context_t spi_context;
// Configuring the SPI interface: Specify the SPI interface pins, frame size, SPI Motorola
// mode and controller/target mode
rslt = Cy_SCB_SPI_Init(SPI_HW, &SPI_config, &spi_context);
Cy_SCB_SPI_Enable(SPI_HW);
rslt = mtb_hal_spi_setup(&spi_obj, &SPI_hal_cfg, &spi_context, NULL);
Cy_SCB_SPI_SetActiveSlaveSelect(SPI_HW, CY_SCB_SPI_SLAVE_SELECT0);
cy_stc_sysint_t intr_cfg = { .intrSrc = SPI_IRQ, .intrPriority = INT_PRIORITY };
Cy_SysInt_Init(&intr_cfg, spi_interrupt_callback);
NVIC_EnableIRQ(SPI_IRQ);
// Set the data rate to 1 Mbps
if (CY_RSLT_SUCCESS == rslt)
{
rslt = mtb_hal_spi_set_frequency(&spi_obj, spi_frequency);
}
if (CY_RSLT_SUCCESS == rslt)
{
// Register a callback function to be called when the interrupt fires
NULL);
// Enable the events that will trigger the call back function
// Controller: Initiates a data transfer. Target: Prepares the target for data transfer. It
// is a
// non-blocking function
mtb_hal_spi_transfer(&spi_obj, transmit_data, rx_transfer_count, receive_data,
tx_transfer_count, 0))
{
// SPI Controller: Transfer started. SPI Target: Prepares for data transfer
}
}
return rslt;
}
void(* mtb_hal_spi_event_callback_t)(void *callback_arg, mtb_hal_spi_event_t event)
Handler for SPI interrupts.
Definition: mtb_hal_spi.h:148
void mtb_hal_spi_register_callback(mtb_hal_spi_t *obj, mtb_hal_spi_event_callback_t callback, void *callback_arg)
Register a SPI callback handler.
Definition: mtb_hal_spi.c:547
mtb_hal_spi_event_t
SPI interrupt triggers.
Definition: mtb_hal_spi.h:137
void mtb_hal_spi_enable_event(mtb_hal_spi_t *obj, mtb_hal_spi_event_t event, bool enable)
Configure SPI interrupt.
Definition: mtb_hal_spi.c:504
@ MTB_HAL_SPI_IRQ_DONE
Transfer complete.
Definition: mtb_hal_spi.h:142

More Information

mtb-example-psoc6-spi-controller: This example project demonstrates use of SPI (HAL) resource in PSoC® 6 MCU in Controller mode to write data to an SPI target.

API Reference

 SPI HAL Results
 SPI specific return codes.
 

Typedefs

typedef void(* mtb_hal_spi_event_callback_t) (void *callback_arg, mtb_hal_spi_event_t event)
 Handler for SPI interrupts.
 

Enumerations

enum  mtb_hal_spi_event_t {
  MTB_HAL_SPI_EVENT_NONE = 0 ,
  MTB_HAL_SPI_IRQ_DATA_IN_FIFO = (MTB_HAL_MAP_SPI_IRQ_DATA_IN_FIFO) ,
  MTB_HAL_SPI_IRQ_DONE = (MTB_HAL_MAP_SPI_IRQ_DONE) ,
  MTB_HAL_SPI_IRQ_ERROR = (MTB_HAL_MAP_SPI_IRQ_ERROR)
}
 SPI interrupt triggers. More...
 
enum  mtb_hal_spi_fifo_type_t {
  MTB_HAL_SPI_FIFO_RX ,
  MTB_HAL_SPI_FIFO_TX
}
 SPI FIFO type. More...
 

Functions

cy_rslt_t mtb_hal_spi_set_frequency (mtb_hal_spi_t *obj, uint32_t hz)
 Set the SPI baud rate. More...
 
cy_rslt_t mtb_hal_spi_set_fifo_level (mtb_hal_spi_t *obj, mtb_hal_spi_fifo_type_t type, uint16_t level)
 Sets a threshold level for a FIFO that will generate an interrupt and a trigger output. More...
 
cy_rslt_t mtb_hal_spi_get (mtb_hal_spi_t *obj, uint32_t *value)
 Synchronously get a received value out of the SPI receive buffer. More...
 
cy_rslt_t mtb_hal_spi_put (mtb_hal_spi_t *obj, uint32_t value)
 Synchronously send a byte out. More...
 
cy_rslt_t mtb_hal_spi_controller_write (mtb_hal_spi_t *obj, const uint8_t *src_buff, uint16_t *size)
 Write data from the user-defined buffer to the controller TX FIFO. More...
 
cy_rslt_t mtb_hal_spi_target_read (mtb_hal_spi_t *obj, uint8_t *dst_buff, uint16_t *size, uint32_t timeout)
 Wait for controller send data to RX buffer and store them to the user-defined buffer. More...
 
cy_rslt_t mtb_hal_spi_target_write (mtb_hal_spi_t *obj, const uint8_t *src_buff, uint16_t *size, uint32_t timeout)
 Write data from the user-defined buffer to TX buffer and wait until either all data has been read from TX buffer and shift register, or timeout is hit. More...
 
cy_rslt_t mtb_hal_spi_transfer (mtb_hal_spi_t *obj, const uint8_t *tx, size_t tx_length, uint8_t *rx, size_t rx_length, uint8_t write_fill)
 Synchronously Write a block out and receive a value. More...
 
cy_rslt_t mtb_hal_spi_clear (mtb_hal_spi_t *obj)
 Clear the SPI buffers. More...
 
void mtb_hal_spi_register_callback (mtb_hal_spi_t *obj, mtb_hal_spi_event_callback_t callback, void *callback_arg)
 Register a SPI callback handler. More...
 
void mtb_hal_spi_enable_event (mtb_hal_spi_t *obj, mtb_hal_spi_event_t event, bool enable)
 Configure SPI interrupt. More...
 
cy_rslt_t mtb_hal_spi_process_interrupt (mtb_hal_spi_t *obj)
 Process interrupts related to a SPI instance. More...
 

Enumeration Type Documentation

◆ mtb_hal_spi_event_t

SPI interrupt triggers.

Enumerator
MTB_HAL_SPI_EVENT_NONE 

No event.

MTB_HAL_SPI_IRQ_DATA_IN_FIFO 

All transfer data has been moved into data FIFO.

MTB_HAL_SPI_IRQ_DONE 

Transfer complete.

MTB_HAL_SPI_IRQ_ERROR 

An error occurred while transferring data.

◆ mtb_hal_spi_fifo_type_t

SPI FIFO type.

Enumerator
MTB_HAL_SPI_FIFO_RX 

RX FIFO for incoming data.

MTB_HAL_SPI_FIFO_TX 

TX FIFO for outgoing datas.

Function Documentation

◆ mtb_hal_spi_set_frequency()

cy_rslt_t mtb_hal_spi_set_frequency ( mtb_hal_spi_t obj,
uint32_t  hz 
)

Set the SPI baud rate.

Actual frequency may differ from the desired frequency due to available dividers and bus clock Configures the SPI peripheral's baud rate

Parameters
[in,out]objThe SPI object to configure
[in]hzThe baud rate in Hz
Returns
The status of the set_frequency request

◆ mtb_hal_spi_set_fifo_level()

cy_rslt_t mtb_hal_spi_set_fifo_level ( mtb_hal_spi_t obj,
mtb_hal_spi_fifo_type_t  type,
uint16_t  level 
)

Sets a threshold level for a FIFO that will generate an interrupt and a trigger output.

The RX FIFO interrupt and trigger will be activated when the receive FIFO has more entries than the threshold. The TX FIFO interrupt and trigger will be activated when the transmit FIFO has less entries than the threshold.

Parameters
[in]objThe SPI object
[in]typeFIFO type to set level for
[in]levelLevel threshold to set. See the device datasheet for valid range.
Returns
The status of the level set

◆ mtb_hal_spi_get()

cy_rslt_t mtb_hal_spi_get ( mtb_hal_spi_t obj,
uint32_t *  value 
)

Synchronously get a received value out of the SPI receive buffer.

In Controller mode - transmits fill-in value and read the data from RxFifo In Target mode - Blocks until a value is available

Parameters
[in]objThe SPI peripheral to read
[in]valueThe value received
Returns
The status of the read request
Note
  • In Controller mode, CITO pin required to be non-NC for this API to operate
  • In Target mode, COTI pin required to be non-NC for this API to operate

◆ mtb_hal_spi_put()

cy_rslt_t mtb_hal_spi_put ( mtb_hal_spi_t obj,
uint32_t  value 
)

Synchronously send a byte out.

In Controller mode transmits value to target and read/drop a value from the RxFifo. In Target mode writes a value to TxFifo

Parameters
[in]objThe SPI peripheral to use for sending
[in]valueThe value to send
Returns
The status of the write request
Note
  • In Controller mode, COTI pin required to be non-NC for this API to operate
  • In Target mode, CITO pin required to be non-NC for this API to operate

◆ mtb_hal_spi_controller_write()

cy_rslt_t mtb_hal_spi_controller_write ( mtb_hal_spi_t obj,
const uint8_t *  src_buff,
uint16_t *  size 
)

Write data from the user-defined buffer to the controller TX FIFO.

Performs non-blocking controller-mode transfer of an array of data. NOTE: If the size of the actual data is less than the expected, the function will copy only the available data and return.

Parameters
[in]objThe SPI object
[in]src_buffPointer on memory to copy the data to the controller TX buffer.
[in,out]size[in] The number of bytes to send, [out] number actually sent.
Returns
The status of the write request

◆ mtb_hal_spi_target_read()

cy_rslt_t mtb_hal_spi_target_read ( mtb_hal_spi_t obj,
uint8_t *  dst_buff,
uint16_t *  size,
uint32_t  timeout 
)

Wait for controller send data to RX buffer and store them to the user-defined buffer.

NOTE: If size of actual data is less then expected the function copy only available data.

Parameters
[in]objThe SPI object
[in]dst_buffPointer on memory to store the data from the target RX buffer.
[in,out]size[in] The number of bytes to read, [out] number actually read.
[in]timeoutTimeout in millisecond, set this value to 0 if you don't want to wait at all.
Returns
The status of the read request

◆ mtb_hal_spi_target_write()

cy_rslt_t mtb_hal_spi_target_write ( mtb_hal_spi_t obj,
const uint8_t *  src_buff,
uint16_t *  size,
uint32_t  timeout 
)

Write data from the user-defined buffer to TX buffer and wait until either all data has been read from TX buffer and shift register, or timeout is hit.

The user needs to provide the interrupt handler and call mtb_hal_spi_process_interrupt to process the interrupt.

NOTE: If size of actual data is less then expected the function copy only available data.

Parameters
[in]objThe SPI object
[in]src_buffPointer on memory to copy the data to the target TX buffer.
[in,out]size[in] The number of bytes to send, [out] number actually sent.
[in]timeoutTimeout in millisecond, set this value to 0 if you don't want to wait at all.
Returns
The status of the write request

◆ mtb_hal_spi_transfer()

cy_rslt_t mtb_hal_spi_transfer ( mtb_hal_spi_t obj,
const uint8_t *  tx,
size_t  tx_length,
uint8_t *  rx,
size_t  rx_length,
uint8_t  write_fill 
)

Synchronously Write a block out and receive a value.

The total number of bytes sent and received will be the maximum of tx_length and rx_length. The bytes written will be padded (at the end) with the value given by write_fill. Using this function will block for the duration of the transfer. The user needs to provide the interrupt handler and call mtb_hal_spi_process_interrupt to process the interrupt.

Parameters
[in]objThe SPI peripheral to use for sending
[in]txPointer to the byte-array of data to write to the device
[in,out]tx_lengthNumber of bytes to write, updated with the number actually written
[out]rxPointer to the byte-array of data to read from the device
[in,out]rx_lengthNumber of bytes to read, updated with the number actually read
[in]write_fillDefault data transmitted while performing a read
Returns
The status of the transfer request
Note
Both COTI and CITO pins required to be non-NC for this API to operate

◆ mtb_hal_spi_clear()

cy_rslt_t mtb_hal_spi_clear ( mtb_hal_spi_t obj)

Clear the SPI buffers.

Parameters
[in]objThe SPI object
Returns
The status of the clear request

◆ mtb_hal_spi_register_callback()

void mtb_hal_spi_register_callback ( mtb_hal_spi_t obj,
mtb_hal_spi_event_callback_t  callback,
void *  callback_arg 
)

Register a SPI callback handler.

This function will be called when one of the events enabled by mtb_hal_spi_enable_event occurs.

Parameters
[in]objThe SPI object
[in]callbackThe callback handler which will be invoked when the interrupt fires
[in]callback_argGeneric argument that will be provided to the callback when called

◆ mtb_hal_spi_enable_event()

void mtb_hal_spi_enable_event ( mtb_hal_spi_t obj,
mtb_hal_spi_event_t  event,
bool  enable 
)

Configure SPI interrupt.

This function is used for word-approach

When an enabled event occurs, the function specified by mtb_hal_spi_register_callback will be called.

Parameters
[in]objThe SPI object
[in]eventThe SPI event type
[in]enableTrue to turn on interrupts, False to turn off

◆ mtb_hal_spi_process_interrupt()

cy_rslt_t mtb_hal_spi_process_interrupt ( mtb_hal_spi_t obj)

Process interrupts related to a SPI instance.

Parameters
objHAL object for which the interrupt should be processed
Returns
CY_RSLT_SUCCESS if the interrupt was processed successfully; otherwise an error