Skip to content
Permalink
master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
/******************************************************************************
* File Name: spi_master.h
*
* Description: This is the source code for the XMC MCU: SPI QSPI Flash
* example for ModusToolbox. This file contains all the
* function declarations for the SPI wrapper required to
* interface with the on-board external memory chip.
*
* Related Document: See README.md
*
******************************************************************************
*
* Copyright (c) 2015-2022, Infineon Technologies AG
* All rights reserved.
*
* Boost Software License - Version 1.0 - August 17th, 2003
*
* Permission is hereby granted, free of charge, to any person or organization
* obtaining a copy of the software and accompanying documentation covered by
* this license (the "Software") to use, reproduce, display, distribute,
* execute, and transmit the Software, and to prepare derivative works of the
* Software, and to permit third-parties to whom the Software is furnished to
* do so, all subject to the following:
*
* The copyright notices in the Software and this entire statement, including
* the above license grant, this restriction and the following disclaimer,
* must be included in all copies of the Software, in whole or in part, and
* all derivative works of the Software, unless such copies or derivative
* works are solely in the form of machine-executable object code generated by
* a source language processor.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef SPI_MASTER_H
#define SPI_MASTER_H
/*******************************************************************************
* Include header files
*******************************************************************************/
#include <xmc_gpio.h>
#include <xmc_scu.h>
#include <xmc_spi.h>
#include "spi_master_conf.h"
/*******************************************************************************
* Enums
*******************************************************************************/
/* Return status of the SPI_MASTER APP */
typedef enum SPI_MASTER_STATUS
{
SPI_MASTER_STATUS_SUCCESS = 0U, /* Status success */
SPI_MASTER_STATUS_FAILURE, /* Status failure */
SPI_MASTER_STATUS_BUSY, /* Busy state */
SPI_MASTER_STATUS_BUFFER_INVALID, /* If input buffer and length is invalid */
SPI_MASTER_STATUS_MODE_MISMATCH /* API invoked by a handle configured with
* different mode
*/
} SPI_MASTER_STATUS_t;
/* Service ID for Transmit, Receive and Parity events */
typedef enum SPI_MASTER_SR_ID
{
SPI_MASTER_SR_ID_0 = 0U, /* SR-0 */
SPI_MASTER_SR_ID_1, /* SR-1 */
SPI_MASTER_SR_ID_2, /* SR-2 */
SPI_MASTER_SR_ID_3, /* SR-3 */
SPI_MASTER_SR_ID_4, /* SR-4 */
SPI_MASTER_SR_ID_5 /* SR-5 */
} SPI_MASTER_SR_ID_t;
/* Slave select signals */
typedef enum SPI_MASTER_SS_SIGNAL
{
SPI_MASTER_SS_SIGNAL_0 = 0U, /* Slave select 0 */
SPI_MASTER_SS_SIGNAL_1, /* Slave select 1 */
SPI_MASTER_SS_SIGNAL_2, /* Slave select 2 */
SPI_MASTER_SS_SIGNAL_3, /* Slave select 3 */
SPI_MASTER_SS_SIGNAL_4, /* Slave select 4 */
SPI_MASTER_SS_SIGNAL_5, /* Slave select 5 */
SPI_MASTER_SS_SIGNAL_6, /* Slave select 6 */
SPI_MASTER_SS_SIGNAL_7 /* Slave select 7 */
} SPI_MASTER_SS_SIGNAL_t;
/* Enum type which defines Receive input list */
typedef enum SPI_MASTER_INPUT
{
SPI_MASTER_INPUT_A = 0U, /* Input-A */
SPI_MASTER_INPUT_B, /* Input-B */
SPI_MASTER_INPUT_C, /* Input-C */
SPI_MASTER_INPUT_D, /* Input-D */
SPI_MASTER_INPUT_E, /* Input-E */
SPI_MASTER_INPUT_F, /* Input-F */
SPI_MASTER_INPUT_G, /* Input-G */
SPI_MASTER_INPUT_INVALID /* This is to check during mode switch */
} SPI_MASTER_INPUT_t;
/* Enum used to identify the transfer type used for either transmit or
* receive function.
*/
typedef enum SPI_MASTER_TRANSFER_MODE
{
SPI_MASTER_TRANSFER_MODE_INTERRUPT, /* Implement data transmit or receive using interrupts */
SPI_MASTER_TRANSFER_MODE_DMA, /* Implement data transmit or receive using DMA */
SPI_MASTER_TRANSFER_MODE_DIRECT /* This configuration exposes signals for external APP connection */
} SPI_MASTER_TRANSFER_MODE_t;
typedef void (*SPI_MASTER_functionhandler)(void);
typedef SPI_MASTER_STATUS_t (*SPI_MASTER_lInit_functionhandler)(void);
/*******************************************************************************
* Data Structures
*******************************************************************************/
/* Port pin selection for communication */
typedef struct SPI_MASTER_GPIO
{
XMC_GPIO_PORT_t* port; /* Reference to the port configuration */
uint8_t pin; /* Selected pin */
} SPI_MASTER_GPIO_t;
/* Pin configuration for the selected pins */
typedef struct SPI_MASTER_GPIO_CONFIG
{
const XMC_GPIO_CONFIG_t* port_config; /* Properties of the port pin */
XMC_GPIO_HWCTRL_t hw_control; /* hardware control
* characteristics of the pin
*/
XMC_SPI_CH_SLAVE_SELECT_t slave_select_ch; /* Indicates the mapped slave
* select line
*/
} SPI_MASTER_GPIO_CONFIG_t;
/*
* Configuration parameters of SPI_MASTER APP
*/
typedef struct SPI_MASTER_CONFIG
{
XMC_SPI_CH_CONFIG_t* const channel_config; /**< Reference to SPI configuration structure */
SPI_MASTER_lInit_functionhandler fptr_spi_master_config; /**< Function pointer to configure the MUX values*/
/* Port configuration */
const SPI_MASTER_GPIO_t* const mosi_0_pin; /**< Reference to mosi 0 pin */
const SPI_MASTER_GPIO_CONFIG_t* const mosi_0_pin_config; /**< Reference to mosi 0 pin configuration */
const SPI_MASTER_GPIO_t* const mosi_1_pin; /**< Reference to mosi 1 pin */
const SPI_MASTER_GPIO_CONFIG_t* const mosi_1_pin_config; /**< Reference to mosi 1 pin configuration */
const SPI_MASTER_GPIO_t* const mosi_2_pin; /**< Reference to mosi 2 pin */
const SPI_MASTER_GPIO_CONFIG_t* const mosi_2_pin_config; /**< Reference to mosi 2 pin configuration */
const SPI_MASTER_GPIO_t* const mosi_3_pin; /**< Reference to mosi 3 pin */
const SPI_MASTER_GPIO_CONFIG_t* const mosi_3_pin_config; /**< Reference to mosi 3 pin configuration */
const SPI_MASTER_GPIO_t* const sclk_out_pin; /**< Reference to sclk out pin */
const SPI_MASTER_GPIO_CONFIG_t* const sclk_out_pin_config;/**< Reference to shift clock pin configuration */
const SPI_MASTER_GPIO_t* const slave_select_pin[8]; /**< Reference to slave select pin */
const SPI_MASTER_GPIO_CONFIG_t* const slave_select_pin_config[8]; /**< Reference to slave select pin configuration */
SPI_MASTER_functionhandler tx_cbhandler; /**< callback handler for end of transmission */
SPI_MASTER_functionhandler rx_cbhandler; /**< callback handler for end of reception */
SPI_MASTER_functionhandler parity_cbhandler; /**< callback handler for end of parity error */
/* FIFO configuration */
XMC_USIC_CH_FIFO_SIZE_t tx_fifo_size; /**< Number of FIFO entries assigned to the transmit FIFO buffer*/
XMC_USIC_CH_FIFO_SIZE_t rx_fifo_size; /**< Number of FIFO entries assigned to the receive FIFO buffer */
/* Clock Settings */
XMC_SPI_CH_BRG_SHIFT_CLOCK_PASSIVE_LEVEL_t shift_clk_passive_level; /**< Baudrate Generator shift clock passive level*/
SPI_MASTER_TRANSFER_MODE_t transmit_mode; /**< Indicates how the transmit mode is being handled */
SPI_MASTER_TRANSFER_MODE_t receive_mode; /**< Indicates how the receive mode is being handled */
XMC_SPI_CH_MODE_t spi_master_config_mode; /**< Defines the SPI transmit mode being used */
uint8_t slave_select_lines; /**< Number of slave select lines being used */
uint8_t leading_trailing_delay; /**< Delay before and after each frame in terms of SCLK cycles */
SPI_MASTER_SR_ID_t tx_sr; /**< Service request number assigned to transmit interrupt */
SPI_MASTER_SR_ID_t rx_sr; /**< Service request number assigned to receive interrupts */
SPI_MASTER_SR_ID_t parity_sr; /**< Service request number assigned to receive interrupts */
} SPI_MASTER_CONFIG_t;
/**
* Structure to hold the dynamic variables for the SPI_MASTER communication.
*/
typedef struct SPI_MASTER_RUNTIME
{
uint32_t word_length; /**< Indicates the length of the data word */
uint32_t tx_data_count; /**< Number of bytes of data to be transmitted*/
volatile uint32_t tx_data_index; /**< Index to the byte to be transmitted next in the tx_data
buffer */
uint32_t rx_data_count; /**< Number of bytes of data to be received*/
volatile uint32_t rx_data_index; /**< Indicates the number of bytes currently available in the
rx_data buffer */
uint8_t* rx_data; /**< Pointer to the receive data buffer*/
uint8_t* tx_data; /**< Pointer to the transmit data buffer*/
volatile XMC_SPI_CH_MODE_t spi_master_mode; /**< Defines the SPI transmit mode being used */
SPI_MASTER_INPUT_t dx0_input; /**< DX0 input channel used for Rx input, This is utilized when
mode is changed to full duplex mode */
SPI_MASTER_INPUT_t dx0_input_half_duplex; /**< DX0 input channel used for Rx input, This is utilized when
mode is changed to half duplex mode */
volatile bool rx_busy; /**< Status flag to indicate busy when a reception is assigned */
volatile bool tx_busy; /**< Status flag to indicate busy when a transmission is assigned*/
volatile bool tx_data_dummy; /**< Status flag to indicate, dummy data is being transmitted */
volatile bool rx_data_dummy; /**< Status flag to indicate, receive data has to be neglected or
not */
} SPI_MASTER_RUNTIME_t;
/**
* Initialization parameters of SPI_MASTER APP
*/
typedef struct SPI_MASTER
{
XMC_USIC_CH_t* const channel; /**< Reference to SPI channel */
const SPI_MASTER_CONFIG_t * const config; /**< Reference to the SPI_MASTER configuration structure */
SPI_MASTER_RUNTIME_t * const runtime; /**< Reference to SPI_MASTER dynamic configuration structure */
} SPI_MASTER_t;
/**
* @}
*/
/*******************************************************************************
* Function Prototypes
*******************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
SPI_MASTER_STATUS_t SPI_MASTER_SetMode(SPI_MASTER_t* const handle, const XMC_SPI_CH_MODE_t mode);
SPI_MASTER_STATUS_t SPI_MASTER_SetBaudRate(SPI_MASTER_t* const handle, const uint32_t baud_rate);
SPI_MASTER_STATUS_t SPI_MASTER_Transmit(const SPI_MASTER_t *const handle, uint8_t* dataptr, uint32_t count);
SPI_MASTER_STATUS_t SPI_MASTER_Receive(const SPI_MASTER_t *const handle, uint8_t* dataptr, uint32_t count);
SPI_MASTER_STATUS_t SPI_MASTER_Transfer(const SPI_MASTER_t *const handle,
uint8_t* tx_dataptr,
uint8_t* rx_dataptr,
uint32_t count);
SPI_MASTER_STATUS_t SPI_MASTER_StartReceiveIRQ(const SPI_MASTER_t *const handle, uint8_t* dataptr, uint32_t count);
SPI_MASTER_STATUS_t SPI_MASTER_StartTransmitIRQ(const SPI_MASTER_t *const handle, uint8_t *addr, uint32_t count);
/* Returns the state of the specified interrupt flag */
__STATIC_INLINE uint32_t SPI_MASTER_GetFlagStatus(const SPI_MASTER_t* handle, const uint32_t flag)
{
XMC_ASSERT("SPI_MASTER_GetFlagStatus:handle NULL" , (handle != NULL));
return (XMC_SPI_CH_GetStatusFlag(handle->channel) & flag);
}
/* Clears the status of the specified interrupt flags */
__STATIC_INLINE void SPI_MASTER_ClearFlag(const SPI_MASTER_t* handle, const uint32_t flag_mask)
{
XMC_ASSERT("SPI_MASTER_ClearFlag:handle NULL" , (handle != NULL));
XMC_SPI_CH_ClearStatusFlag(handle->channel, flag_mask);
}
/* Returns the txbusy flag state */
__STATIC_INLINE bool SPI_MASTER_IsTxBusy(const SPI_MASTER_t* const handle)
{
XMC_ASSERT("SPI_MASTER_IsTxBusy:handle NULL", (handle != NULL));
return (handle->runtime->tx_busy);
}
/* Return the rxbusy flag state */
__STATIC_INLINE bool SPI_MASTER_IsRxBusy(const SPI_MASTER_t* const handle)
{
XMC_ASSERT("SPI_MASTER_IsTxBusy:handle NULL", (handle != NULL));
return (handle->runtime->rx_busy);
}
/* Enables the specified slave select line */
__STATIC_INLINE void SPI_MASTER_EnableSlaveSelectSignal(const SPI_MASTER_t* handle, const SPI_MASTER_SS_SIGNAL_t slave)
{
XMC_ASSERT("SPI_MASTER_EnableSlaveSelectSignal:handle NULL" , (handle != NULL));
XMC_ASSERT("SPI_MASTER_EnableSlaveSelectSignal:Invalid Slave selection" , ((slave == SPI_MASTER_SS_SIGNAL_0) ||
(slave == SPI_MASTER_SS_SIGNAL_1) ||
(slave == SPI_MASTER_SS_SIGNAL_2) ||
(slave == SPI_MASTER_SS_SIGNAL_3) ||
(slave == SPI_MASTER_SS_SIGNAL_4) ||
(slave == SPI_MASTER_SS_SIGNAL_5) ||
(slave == SPI_MASTER_SS_SIGNAL_6) ||
(slave == SPI_MASTER_SS_SIGNAL_7))
);
XMC_SPI_CH_EnableSlaveSelect(handle->channel, handle->config->slave_select_pin_config[slave]->slave_select_ch);
}
/* Disables the all the slave select lines */
__STATIC_INLINE void SPI_MASTER_DisableSlaveSelectSignal(const SPI_MASTER_t* handle)
{
XMC_ASSERT("SPI_MASTER_Transmit:handle NULL" , (handle != NULL));
XMC_SPI_CH_DisableSlaveSelect(handle->channel);
}
/* Provides data received in the receive buffer */
__STATIC_INLINE uint16_t SPI_MASTER_GetReceivedWord(const SPI_MASTER_t *const handle)
{
XMC_ASSERT("SPI_MASTER_GetReceivedWord:handle NULL" , (handle != NULL));
return XMC_SPI_CH_GetReceivedData(handle->channel);
}
/* Transmits a word of data */
__STATIC_INLINE void SPI_MASTER_TransmitWord(const SPI_MASTER_t *const handle, const uint16_t data)
{
XMC_ASSERT("SPI_MASTER_TransmitWord:handle NULL" , (handle != NULL));
XMC_SPI_CH_Transmit(handle->channel, data, handle->runtime->spi_master_mode);
}
/* Enables the selected protocol events for interrupt generation */
__STATIC_INLINE void SPI_MASTER_EnableEvent(const SPI_MASTER_t *const handle, const uint32_t event_mask)
{
XMC_ASSERT("SPI_MASTER_EnableEvent:handle NULL" , (handle != NULL));
XMC_SPI_CH_EnableEvent(handle->channel, event_mask);
}
/* Disables selected events from generating interrupt */
__STATIC_INLINE void SPI_MASTER_DisableEvent(const SPI_MASTER_t *const handle, const uint32_t event_mask)
{
XMC_ASSERT("SPI_MASTER_DisableEvent:handle NULL" , (handle != NULL));
XMC_SPI_CH_DisableEvent(handle->channel, event_mask);
}
/* Configures trigger limit for the transmit FIFO */
__STATIC_INLINE void SPI_MASTER_SetTXFIFOTriggerLimit(const SPI_MASTER_t *const handle, const uint32_t limit)
{
XMC_ASSERT("SPI_MASTER_SetTXFIFOTriggerLimit:handle NULL" , (handle != NULL));
XMC_USIC_CH_TXFIFO_SetSizeTriggerLimit(handle->channel, handle->config->tx_fifo_size, limit);
}
/* Configures trigger limit for the receive FIFO */
__STATIC_INLINE void SPI_MASTER_SetRXFIFOTriggerLimit(const SPI_MASTER_t *const handle, const uint32_t limit)
{
XMC_ASSERT("SPI_MASTER_SetRXFIFOTriggerLimit:handle NULL" , (handle != NULL));
XMC_USIC_CH_RXFIFO_SetSizeTriggerLimit(handle->channel, handle->config->rx_fifo_size, limit);
}
/* Enables the interrupt events related to transmit FIFO */
__STATIC_INLINE void SPI_MASTER_TXFIFO_EnableEvent(const SPI_MASTER_t *const handle, const uint32_t event)
{
XMC_ASSERT("SPI_MASTER_TXFIFO_EnableEvent:handle NULL" , (handle != NULL));
XMC_USIC_CH_TXFIFO_EnableEvent(handle->channel, event);
}
/* Disables the interrupt events related to transmit FIFO */
__STATIC_INLINE void SPI_MASTER_TXFIFO_DisableEvent(const SPI_MASTER_t *const handle, const uint32_t event)
{
XMC_ASSERT("SPI_MASTER_TXFIFO_DisableEvent:handle NULL" , (handle != NULL));
XMC_USIC_CH_TXFIFO_DisableEvent(handle->channel, event);
}
/* Gets the transmit FIFO event status */
__STATIC_INLINE uint32_t SPI_MASTER_TXFIFO_GetEvent(const SPI_MASTER_t *const handle)
{
XMC_ASSERT("SPI_MASTER_TXFIFO_GetEvent:handle NULL" , (handle != NULL));
return XMC_USIC_CH_TXFIFO_GetEvent(handle->channel);
}
/* Clears the transmit FIFO event flags in the status register */
__STATIC_INLINE void SPI_MASTER_TXFIFO_ClearEvent(const SPI_MASTER_t *const handle, const uint32_t event)
{
XMC_ASSERT("SPI_MASTER_TXFIFO_ClearEvent:handle NULL" , (handle != NULL));
XMC_USIC_CH_TXFIFO_ClearEvent(handle->channel, event);
}
/* Checks if the transmit FIFO is full */
__STATIC_INLINE bool SPI_MASTER_IsTxFIFOFull(const SPI_MASTER_t* const handle)
{
XMC_ASSERT("SPI_MASTER_IsTxFIFOFull:handle NULL", (handle != NULL));
return XMC_USIC_CH_TXFIFO_IsFull(handle->channel);
}
/* Enables the interrupt events related to transmit FIFO */
__STATIC_INLINE void SPI_MASTER_RXFIFO_EnableEvent(const SPI_MASTER_t *const handle, const uint32_t event)
{
XMC_ASSERT("SPI_MASTER_RXFIFO_EnableEvent:handle NULL" , (handle != NULL));
XMC_USIC_CH_RXFIFO_EnableEvent(handle->channel, event);
}
/* Disables the selected interrupt events related to receive FIFO */
__STATIC_INLINE void SPI_MASTER_RXFIFO_DisableEvent(const SPI_MASTER_t *const handle, const uint32_t event)
{
XMC_ASSERT("SPI_MASTER_RXFIFO_DisableEvent:handle NULL" , (handle != NULL));
XMC_USIC_CH_RXFIFO_DisableEvent(handle->channel, event);
}
/* Get the receive FIFO events status */
__STATIC_INLINE uint32_t SPI_MASTER_RXFIFO_GetEvent(const SPI_MASTER_t *const handle)
{
XMC_ASSERT("SPI_MASTER_RXFIFO_GetEvent:handle NULL" , (handle != NULL));
return XMC_USIC_CH_RXFIFO_GetEvent(handle->channel);
}
/* Clears the receive FIFO event flags in the status register */
__STATIC_INLINE void SPI_MASTER_RXFIFO_ClearEvent(const SPI_MASTER_t *const handle, const uint32_t event)
{
XMC_ASSERT("SPI_MASTER_RXFIFO_ClearEvent:handle NULL" , (handle != NULL));
XMC_USIC_CH_RXFIFO_ClearEvent(handle->channel, event);
}
/* Checks if receive FIFO is empty */
__STATIC_INLINE bool SPI_MASTER_IsRxFIFOEmpty(const SPI_MASTER_t* const handle)
{
XMC_ASSERT("SPI_MASTER_IsRxFIFOEmpty:handle NULL", (handle != NULL));
return XMC_USIC_CH_RXFIFO_IsEmpty(handle->channel);
}
/* Aborts the ongoing data transmission */
SPI_MASTER_STATUS_t SPI_MASTER_AbortTransmit(const SPI_MASTER_t *const handle);
/* Stops the active data reception request */
SPI_MASTER_STATUS_t SPI_MASTER_AbortReceive(const SPI_MASTER_t *const handle);
#include "spi_master_extern.h"
#ifdef __cplusplus
}
#endif
#endif /* SPI_MASTER_H */
/* [] END OF FILE */