MoistureSoftware/.pack/Keil/STM32F1xx_DFP.2.3.0/RTE_Driver/SPI_STM32F10x.c

1420 lines
44 KiB
C

/* -----------------------------------------------------------------------------
* Copyright (c) 2013-2015 ARM Ltd.
*
* This software is provided 'as-is', without any express or implied warranty.
* In no event will the authors be held liable for any damages arising from
* the use of this software. Permission is granted to anyone to use this
* software for any purpose, including commercial applications, and to alter
* it and redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software in
* a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source distribution.
*
*
* $Date: 26. October 2015
* $Revision: V2.2
*
* Driver: Driver_SPI1, Driver_SPI2, Driver_SPI3
* Configured: via RTE_Device.h configuration file
* Project: SPI Driver for STMicroelectronics STM32F10x
* --------------------------------------------------------------------------
* Use the following configuration settings in the middleware component
* to connect to this driver.
*
* Configuration Setting Value SPI Interface
* --------------------- ----- -------------
* Connect to hardware via Driver_SPI# = 1 use SPI1
* Connect to hardware via Driver_SPI# = 2 use SPI2
* Connect to hardware via Driver_SPI# = 3 use SPI3
* -------------------------------------------------------------------------- */
/* History:
* Version 2.2
* Corrected SPI Peripheral Reset and Clock enable/disable
* - Added checking if peripheral is available on selected device
* Version 2.1
* Corrected Bus Speed configuration
* Corrected 8bit/16bit Data register access, regarding the Data frame size
* Version 2.0
* Updated to CMSIS Driver API V2.01
* Version 1.3
* Event send_data_event added to capabilities
* SPI IRQ handling corrected
* Version 1.2
* Based on API V1.10 (namespace prefix ARM_ added)
* Version 1.1
* Corrections for configuration without DMA
* Version 1.0
* Initial release
*/
#include "SPI_STM32F10x.h"
#define ARM_SPI_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(2,2)
// Driver Version
static const ARM_DRIVER_VERSION DriverVersion = { ARM_SPI_API_VERSION, ARM_SPI_DRV_VERSION };
// Driver Capabilities
static const ARM_SPI_CAPABILITIES DriverCapabilities = {
0, /* Simplex Mode (Master and Slave) */
0, /* TI Synchronous Serial Interface */
0, /* Microwire Interface */
1 /* Signal Mode Fault event: \ref ARM_SPI_EVENT_MODE_FAULT */
};
#ifdef MX_SPI1
// SPI1 Run-Time Information
static SPI_INFO SPI1_Info = { 0U };
static SPI_TRANSFER_INFO SPI1_TransferInfo = { 0U };
#ifdef MX_SPI1_MOSI_Pin
static SPI_PIN SPI1_mosi = {MX_SPI1_MOSI_GPIOx, MX_SPI1_MOSI_GPIO_Pin};
#endif
#ifdef MX_SPI1_MISO_Pin
static SPI_PIN SPI1_miso = {MX_SPI1_MISO_GPIOx, MX_SPI1_MISO_GPIO_Pin};
#endif
#ifdef MX_SPI1_NSS_Pin
static SPI_PIN SPI1_nss = {MX_SPI1_NSS_GPIOx, MX_SPI1_NSS_GPIO_Pin};
#endif
static SPI_PIN SPI1_sck = {MX_SPI1_SCK_GPIOx, MX_SPI1_SCK_GPIO_Pin};
#ifdef MX_SPI1_RX_DMA_Instance
static SPI_DMA SPI1_DMA_Rx = {
MX_SPI1_RX_DMA_Instance,
MX_SPI1_RX_DMA_Number,
MX_SPI1_RX_DMA_Channel,
MX_SPI1_RX_DMA_Priority
};
#endif
#ifdef MX_SPI1_TX_DMA_Instance
static SPI_DMA SPI1_DMA_Tx = {
MX_SPI1_TX_DMA_Instance,
MX_SPI1_TX_DMA_Number,
MX_SPI1_TX_DMA_Channel,
MX_SPI1_TX_DMA_Priority
};
#endif
// SPI1 Resources
static const SPI_RESOURCES SPI1_Resources = {
SPI1,
RTE_PCLK2,
// PINS
{
#ifdef MX_SPI1_MOSI_Pin
&SPI1_mosi,
#else
NULL,
#endif
#ifdef MX_SPI1_MISO_Pin
&SPI1_miso,
#else
NULL,
#endif
#ifdef MX_SPI1_NSS_Pin
&SPI1_nss,
#else
NULL,
#endif
&SPI1_sck,
MX_SPI1_REMAP_DEF,
MX_SPI1_REMAP
},
SPI1_IRQn,
#ifdef MX_SPI1_RX_DMA_Instance
&SPI1_DMA_Rx,
#else
NULL,
#endif
#ifdef MX_SPI1_TX_DMA_Instance
&SPI1_DMA_Tx,
#else
NULL,
#endif
&SPI1_Info,
&SPI1_TransferInfo
};
#endif /* MX_SPI1 */
#ifdef MX_SPI2
// SPI2 Run-Time Information
static SPI_INFO SPI2_Info = { 0U };
static SPI_TRANSFER_INFO SPI2_TransferInfo = { 0U };
#ifdef MX_SPI2_MOSI_Pin
static SPI_PIN SPI2_mosi = {MX_SPI2_MOSI_GPIOx, MX_SPI2_MOSI_GPIO_Pin};
#endif
#ifdef MX_SPI2_MISO_Pin
static SPI_PIN SPI2_miso = {MX_SPI2_MISO_GPIOx, MX_SPI2_MISO_GPIO_Pin};
#endif
#ifdef MX_SPI2_NSS_Pin
static SPI_PIN SPI2_nss = {MX_SPI2_NSS_GPIOx, MX_SPI2_NSS_GPIO_Pin};
#endif
static SPI_PIN SPI2_sck = {MX_SPI2_SCK_GPIOx, MX_SPI2_SCK_GPIO_Pin};
#ifdef MX_SPI2_RX_DMA_Instance
static SPI_DMA SPI2_DMA_Rx = {
MX_SPI2_RX_DMA_Instance,
MX_SPI2_RX_DMA_Number,
MX_SPI2_RX_DMA_Channel,
MX_SPI2_RX_DMA_Priority
};
#endif
#ifdef MX_SPI2_TX_DMA_Instance
static SPI_DMA SPI2_DMA_Tx = {
MX_SPI2_TX_DMA_Instance,
MX_SPI2_TX_DMA_Number,
MX_SPI2_TX_DMA_Channel,
MX_SPI2_TX_DMA_Priority
};
#endif
// SPI2 Resources
static const SPI_RESOURCES SPI2_Resources = {
SPI2,
RTE_PCLK1,
// PINS
{
#ifdef MX_SPI2_MOSI_Pin
&SPI2_mosi,
#else
NULL,
#endif
#ifdef MX_SPI2_MISO_Pin
&SPI2_miso,
#else
NULL,
#endif
#ifdef MX_SPI2_NSS_Pin
&SPI2_nss,
#else
NULL,
#endif
&SPI2_sck,
MX_SPI2_REMAP_DEF,
MX_SPI2_REMAP
},
SPI2_IRQn,
#ifdef MX_SPI2_RX_DMA_Instance
&SPI2_DMA_Rx,
#else
NULL,
#endif
#ifdef MX_SPI2_TX_DMA_Instance
&SPI2_DMA_Tx,
#else
NULL,
#endif
&SPI2_Info,
&SPI2_TransferInfo
};
#endif /* MX_SPI2 */
#ifdef MX_SPI3
// SPI3 Run-Time Information
static SPI_INFO SPI3_Info = { 0U };
static SPI_TRANSFER_INFO SPI3_TransferInfo = { 0U };
#ifdef MX_SPI3_MOSI_Pin
static SPI_PIN SPI3_mosi = {MX_SPI3_MOSI_GPIOx, MX_SPI3_MOSI_GPIO_Pin};
#endif
#ifdef MX_SPI3_MISO_Pin
static SPI_PIN SPI3_miso = {MX_SPI3_MISO_GPIOx, MX_SPI3_MISO_GPIO_Pin};
#endif
#ifdef MX_SPI3_NSS_Pin
static SPI_PIN SPI3_nss = {MX_SPI3_NSS_GPIOx, MX_SPI3_NSS_GPIO_Pin};
#endif
static SPI_PIN SPI3_sck = {MX_SPI3_SCK_GPIOx, MX_SPI3_SCK_GPIO_Pin};
#ifdef MX_SPI3_RX_DMA_Instance
static SPI_DMA SPI3_DMA_Rx = {
MX_SPI3_RX_DMA_Instance,
MX_SPI3_RX_DMA_Number,
MX_SPI3_RX_DMA_Channel,
MX_SPI3_RX_DMA_Priority
};
#endif
#ifdef MX_SPI3_TX_DMA_Instance
static SPI_DMA SPI3_DMA_Tx = {
MX_SPI3_TX_DMA_Instance,
MX_SPI3_TX_DMA_Number,
MX_SPI3_TX_DMA_Channel,
MX_SPI3_TX_DMA_Priority
};
#endif
// SPI3 Resources
static const SPI_RESOURCES SPI3_Resources = {
SPI3,
RTE_PCLK1,
// PINS
{
#ifdef MX_SPI3_MOSI_Pin
&SPI3_mosi,
#else
NULL,
#endif
#ifdef MX_SPI3_MISO_Pin
&SPI3_miso,
#else
NULL,
#endif
#ifdef MX_SPI3_NSS_Pin
&SPI3_nss,
#else
NULL,
#endif
&SPI3_sck,
MX_SPI3_REMAP_DEF,
MX_SPI3_REMAP
},
SPI3_IRQn,
#ifdef MX_SPI3_RX_DMA_Instance
&SPI3_DMA_Rx,
#else
NULL,
#endif
#ifdef MX_SPI3_TX_DMA_Instance
&SPI3_DMA_Tx,
#else
NULL,
#endif
&SPI3_Info,
&SPI3_TransferInfo
};
#endif /* MX_SPI3 */
/**
\fn void SPI_PeripheralReset (const SPI_TypeDef *spi)
\brief SPI Reset
*/
static void SPI_PeripheralReset (const SPI_TypeDef *spi) {
if (spi == SPI1) { RCC->APB2RSTR |= RCC_APB2RSTR_SPI1RST; }
#if !defined(STM32F10X_LD) && !defined(STM32F10X_LD_VL)
if (spi == SPI2) { RCC->APB1RSTR |= RCC_APB1RSTR_SPI2RST; }
#endif
#if defined(STM32F10X_HD) || defined(STM32F10X_CL) || defined(STM32F10X_XL) || defined(STM32F10X_HD_VL)
if (spi == SPI3) { RCC->APB1RSTR |= RCC_APB1RSTR_SPI3RST; }
#endif
__NOP(); __NOP(); __NOP(); __NOP();
if (spi == SPI1) { RCC->APB2RSTR &= ~RCC_APB2RSTR_SPI1RST; }
#if !defined(STM32F10X_LD) && !defined(STM32F10X_LD_VL)
if (spi == SPI2) { RCC->APB1RSTR &= ~RCC_APB1RSTR_SPI2RST; }
#endif
#if defined(STM32F10X_HD) || defined(STM32F10X_CL) || defined(STM32F10X_XL) || defined(STM32F10X_HD_VL)
if (spi == SPI3) { RCC->APB1RSTR &= ~RCC_APB1RSTR_SPI3RST; }
#endif
}
/**
\fn ARM_DRIVER_VERSION SPIX_GetVersion (void)
\brief Get SPI driver version.
\return \ref ARM_DRV_VERSION
*/
static ARM_DRIVER_VERSION SPIX_GetVersion (void) {
return DriverVersion;
}
/**
\fn ARM_SPI_CAPABILITIES SPI_GetCapabilities (void)
\brief Get driver capabilities.
\return \ref ARM_SPI_CAPABILITIES
*/
static ARM_SPI_CAPABILITIES SPIX_GetCapabilities (void) {
return DriverCapabilities;
}
/**
\fn int32_t SPI_Initialize (ARM_SPI_SignalEvent_t cb_event, const SPI_RESOURCES *spi)
\brief Initialize SPI Interface.
\param[in] cb_event Pointer to \ref ARM_SPI_SignalEvent
\param[in] spi Pointer to SPI resources
\return \ref execution_status
*/
static int32_t SPI_Initialize (ARM_SPI_SignalEvent_t cb_event, const SPI_RESOURCES *spi) {
bool ok = true;
if (spi->info->state & SPI_INITIALIZED) { return ARM_DRIVER_OK; }
// Initialize SPI Run-Time Resources
spi->info->cb_event = cb_event;
spi->info->status.busy = 0U;
spi->info->status.data_lost = 0U;
spi->info->status.mode_fault = 0U;
// Clear transfer information
memset(spi->xfer, 0, sizeof(SPI_TRANSFER_INFO));
// Setup pin remap
GPIO_AFConfigure(spi->io.afio);
// Configure SPI SCK pin
GPIO_PortClock (spi->io.sck->port, true);
ok = GPIO_PinConfigure(spi->io.sck->port, spi->io.sck->pin, GPIO_AF_PUSHPULL,
GPIO_MODE_OUT50MHZ);
if (ok && (spi->io.mosi != NULL)) {
// Configure SPI MOSI pin
GPIO_PortClock (spi->io.mosi->port, true);
ok = GPIO_PinConfigure(spi->io.mosi->port, spi->io.mosi->pin, GPIO_AF_PUSHPULL,
GPIO_MODE_OUT50MHZ);
}
if (ok && (spi->io.miso != NULL)) {
// Configure SPI MISO pin
GPIO_PortClock (spi->io.miso->port, true);
ok = GPIO_PinConfigure(spi->io.miso->port, spi->io.miso->pin, GPIO_AF_PUSHPULL,
GPIO_MODE_INPUT);
}
#ifdef __SPI_DMA
if ((spi->rx_dma != NULL) || (spi->tx_dma != NULL)) {
if (spi->rx_dma != NULL) {
DMA_ChannelInitialize (spi->rx_dma->dma_num, spi->rx_dma->ch_num);
}
if (spi->tx_dma != NULL) {
DMA_ChannelInitialize (spi->tx_dma->dma_num, spi->tx_dma->ch_num);
}
}
#endif
spi->info->state = SPI_INITIALIZED;
return (ok) ? (ARM_DRIVER_OK) : (ARM_DRIVER_ERROR);
}
/**
\fn int32_t SPI_Uninitialize (const SPI_RESOURCES *spi)
\brief De-initialize SPI Interface.
\param[in] spi Pointer to SPI resources
\return \ref execution_status
*/
static int32_t SPI_Uninitialize (const SPI_RESOURCES *spi) {
// Uninitialize SPI pins
GPIO_PinConfigure (spi->io.sck->port, spi->io.sck->pin, GPIO_IN_ANALOG, GPIO_MODE_INPUT);
if (spi->io.miso != NULL) {
GPIO_PinConfigure (spi->io.miso->port, spi->io.miso->pin, GPIO_IN_ANALOG, GPIO_MODE_INPUT);
}
if (spi->io.mosi != NULL) {
GPIO_PinConfigure (spi->io.mosi->port, spi->io.mosi->pin, GPIO_IN_ANALOG, GPIO_MODE_INPUT);
}
if (spi->io.nss != NULL) {
GPIO_PinConfigure (spi->io.nss->port, spi->io.nss->pin, GPIO_IN_ANALOG, GPIO_MODE_INPUT);
}
// Uncofigure pin remapping
GPIO_AFConfigure(spi->io.afio_def);
#ifdef __SPI_DMA
if ((spi->rx_dma != NULL) || (spi->tx_dma != NULL)) {
if (spi->rx_dma != NULL) {
DMA_ChannelUninitialize (spi->rx_dma->dma_num, spi->rx_dma->ch_num);
}
if (spi->tx_dma != NULL) {
DMA_ChannelUninitialize (spi->tx_dma->dma_num, spi->tx_dma->ch_num);
}
}
#endif
// Clear SPI state
spi->info->state = 0U;
return ARM_DRIVER_OK;
}
/**
\fn int32_t SPI_PowerControl (ARM_POWER_STATE state, const SPI_RESOURCES *spi)
\brief Control SPI Interface Power.
\param[in] state Power state
\param[in] spi Pointer to SPI resources
\return \ref execution_status
*/
static int32_t SPI_PowerControl (ARM_POWER_STATE state, const SPI_RESOURCES *spi) {
switch (state) {
case ARM_POWER_OFF:
// SPI peripheral reset
SPI_PeripheralReset (spi->reg);
NVIC_DisableIRQ (spi->irq_num);
// Disable SPI clock
if (spi->reg == SPI1) { RCC->APB2ENR &= ~RCC_APB2ENR_SPI1EN; }
#if !defined(STM32F10X_LD) && !defined(STM32F10X_LD_VL)
if (spi->reg == SPI2) { RCC->APB1ENR &= ~RCC_APB1ENR_SPI2EN; }
#endif
#if defined(STM32F10X_HD) || defined(STM32F10X_CL) || defined(STM32F10X_XL) || defined(STM32F10X_HD_VL)
if (spi->reg == SPI3) { RCC->APB1ENR &= ~RCC_APB1ENR_SPI3EN; }
#endif
// Clear status flags
spi->info->status.busy = 0U;
spi->info->status.data_lost = 0U;
spi->info->status.mode_fault = 0U;
// Clear powered flag
spi->info->state &= ~SPI_POWERED;
break;
case ARM_POWER_FULL:
if ((spi->info->state & SPI_INITIALIZED) == 0U) {
return ARM_DRIVER_ERROR;
}
if ((spi->info->state & SPI_POWERED) != 0U) {
return ARM_DRIVER_OK;
}
// Clear status flags
spi->info->status.busy = 0U;
spi->info->status.data_lost = 0U;
spi->info->status.mode_fault = 0U;
spi->xfer->def_val = 0U;
// Ready for operation - set powered flag
spi->info->state |= SPI_POWERED;
// Enable SPI clock
if (spi->reg == SPI1) { RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; }
#if !defined(STM32F10X_LD) && !defined(STM32F10X_LD_VL)
if (spi->reg == SPI2) { RCC->APB1ENR |= RCC_APB1ENR_SPI2EN; }
#endif
#if defined(STM32F10X_HD) || defined(STM32F10X_CL) || defined(STM32F10X_XL) || defined(STM32F10X_HD_VL)
if (spi->reg == SPI3) { RCC->APB1ENR |= RCC_APB1ENR_SPI3EN; }
#endif
// SPI peripheral reset
SPI_PeripheralReset (spi->reg);
// Clear and Enable SPI IRQ
NVIC_ClearPendingIRQ(spi->irq_num);
NVIC_EnableIRQ(spi->irq_num);
break;
case ARM_POWER_LOW:
default: return ARM_DRIVER_ERROR_UNSUPPORTED;
}
return ARM_DRIVER_OK;
}
/**
\fn int32_t SPI_Send (const void *data, uint32_t num, const SPI_RESOURCES *spi)
\brief Start sending data to SPI transmitter.
\param[in] data Pointer to buffer with data to send to SPI transmitter
\param[in] num Number of data items to send
\param[in] spi Pointer to SPI resources
\return \ref execution_status
*/
static int32_t SPI_Send (const void *data, uint32_t num, const SPI_RESOURCES *spi) {
#ifdef __SPI_DMA
uint32_t cfg;
#endif
if ((data == NULL) || (num == 0U)) { return ARM_DRIVER_ERROR_PARAMETER; }
if ((spi->info->state & SPI_CONFIGURED) == 0U) { return ARM_DRIVER_ERROR; }
if ( spi->info->status.busy) { return ARM_DRIVER_ERROR_BUSY; }
// Check if transmit pin available
if ((((spi->io.mosi != NULL) && ((spi->info->mode & ARM_SPI_CONTROL_Msk) == ARM_SPI_MODE_MASTER)) ||
((spi->io.miso != NULL) && ((spi->info->mode & ARM_SPI_CONTROL_Msk) == ARM_SPI_MODE_SLAVE ))) == 0U) {
return ARM_DRIVER_ERROR;
}
// Update SPI statuses
spi->info->status.busy = 1U;
spi->info->status.data_lost = 0U;
spi->info->status.mode_fault = 0U;
// Save transfer info
spi->xfer->rx_buf = NULL;
spi->xfer->tx_buf = (uint8_t *)data;
spi->xfer->num = num;
spi->xfer->rx_cnt = 0U;
spi->xfer->tx_cnt = 0U;
#ifdef __SPI_DMA_RX
if (spi->rx_dma != NULL) {
// Configure and enable rx DMA channel
cfg = ((spi->rx_dma->priority << DMA_PRIORITY_POS) & DMA_PRIORITY_MASK) |
DMA_PERIPHERAL_TO_MEMORY |
DMA_TRANSFER_COMPLETE_INTERRUPT;
if (spi->reg->CR1 & SPI_CR1_DFF) {
// 16 - bit data frame
cfg |= DMA_PERIPHERAL_DATA_16BIT | DMA_MEMORY_DATA_16BIT;
} else {
// 8 - bit data frame
cfg |= DMA_PERIPHERAL_DATA_8BIT | DMA_MEMORY_DATA_8BIT;
}
DMA_ChannelConfigure(spi->rx_dma->instance,
cfg,
(uint32_t)(&spi->reg->DR),
(uint32_t)(&spi->xfer->dump_val),
num);
DMA_ChannelEnable(spi->rx_dma->instance);
// RX Buffer DMA enable
spi->reg->CR2 |= SPI_CR2_RXDMAEN;
} else
#endif
{
// Interrupt mode
// RX Buffer not empty interrupt enable
spi->reg->CR2 |= SPI_CR2_RXNEIE;
}
#ifdef __SPI_DMA_TX
if (spi->tx_dma != NULL) {
cfg = ((spi->tx_dma->priority << DMA_PRIORITY_POS) & DMA_PRIORITY_MASK) |
DMA_READ_MEMORY |
DMA_MEMORY_INCREMENT |
DMA_TRANSFER_COMPLETE_INTERRUPT ;
if (spi->reg->CR1 & SPI_CR1_DFF) {
// 16 - bit data frame
cfg |= DMA_PERIPHERAL_DATA_16BIT | DMA_MEMORY_DATA_16BIT;
} else {
// 8 - bit data frame
cfg |= DMA_PERIPHERAL_DATA_8BIT | DMA_MEMORY_DATA_8BIT;
}
DMA_ChannelConfigure(spi->tx_dma->instance,
cfg,
(uint32_t)&spi->reg->DR,
(uint32_t)data,
num);
DMA_ChannelEnable(spi->tx_dma->instance);
// TX Buffer DMA enable
spi->reg->CR2 |= SPI_CR2_TXDMAEN;
} else
#endif
{
// Interrupt mode
// TX Buffer empty interrupt enable
spi->reg->CR2 |= SPI_CR2_TXEIE;
}
return ARM_DRIVER_OK;
}
/**
\fn int32_t SPI_Receive (void *data, uint32_t num, const SPI_RESOURCES *spi)
\brief Start receiving data from SPI receiver.
\param[out] data Pointer to buffer for data to receive from SPI receiver
\param[in] num Number of data items to receive
\param[in] spi Pointer to SPI resources
\return \ref execution_status
*/
static int32_t SPI_Receive (void *data, uint32_t num, const SPI_RESOURCES *spi) {
#ifdef __SPI_DMA
uint32_t cfg;
#endif
if ((data == NULL) || (num == 0U)) { return ARM_DRIVER_ERROR_PARAMETER; }
if ((spi->info->state & SPI_CONFIGURED) == 0U) { return ARM_DRIVER_ERROR; }
if ( spi->info->status.busy) { return ARM_DRIVER_ERROR_BUSY; }
// Check if receive pin available
if ((((spi->io.miso != NULL) && ((spi->info->mode & ARM_SPI_CONTROL_Msk) == ARM_SPI_MODE_MASTER)) ||
((spi->io.mosi != NULL) && ((spi->info->mode & ARM_SPI_CONTROL_Msk) == ARM_SPI_MODE_SLAVE ))) == 0U) {
return ARM_DRIVER_ERROR;
}
// Update SPI statuses
spi->info->status.busy = 1U;
spi->info->status.data_lost = 0U;
spi->info->status.mode_fault = 0U;
// Save transfer info
spi->xfer->rx_buf = (uint8_t *)data;
spi->xfer->tx_buf = NULL;
spi->xfer->num = num;
spi->xfer->rx_cnt = 0U;
spi->xfer->tx_cnt = 0U;
#ifdef __SPI_DMA_RX
// DMA mode
if (spi->rx_dma != NULL) {
cfg = ((spi->rx_dma->priority << DMA_PRIORITY_POS) & DMA_PRIORITY_MASK) |
DMA_PERIPHERAL_TO_MEMORY |
DMA_MEMORY_INCREMENT |
DMA_TRANSFER_COMPLETE_INTERRUPT ;
if (spi->reg->CR1 & SPI_CR1_DFF) {
// 16 - bit data frame
cfg |= DMA_PERIPHERAL_DATA_16BIT | DMA_MEMORY_DATA_16BIT;
} else {
// 8 - bit data frame
cfg |= DMA_PERIPHERAL_DATA_8BIT | DMA_MEMORY_DATA_8BIT;
}
DMA_ChannelConfigure(spi->rx_dma->instance,
cfg,
(uint32_t)(&spi->reg->DR),
(uint32_t)data,
num);
DMA_ChannelEnable(spi->rx_dma->instance);
// RX Buffer DMA enable
spi->reg->CR2 |= SPI_CR2_RXDMAEN;
} else
#endif
{
// Interrupt mode
// RX Buffer not empty interrupt enable
spi->reg->CR2 |= SPI_CR2_RXNEIE;
}
#ifdef __SPI_DMA_TX
// DMA mode
if (spi->tx_dma != NULL) {
cfg = ((spi->tx_dma->priority << DMA_PRIORITY_POS) & DMA_PRIORITY_MASK) |
DMA_READ_MEMORY |
DMA_TRANSFER_COMPLETE_INTERRUPT;
if (spi->reg->CR1 & SPI_CR1_DFF) {
// 16 - bit data frame
cfg |= DMA_PERIPHERAL_DATA_16BIT | DMA_MEMORY_DATA_16BIT;
} else {
// 8 - bit data frame
cfg |= DMA_PERIPHERAL_DATA_8BIT | DMA_MEMORY_DATA_8BIT;
}
DMA_ChannelConfigure(spi->tx_dma->instance,
cfg,
(uint32_t)(&spi->reg->DR),
(uint32_t)(&spi->xfer->def_val),
num);
DMA_ChannelEnable(spi->tx_dma->instance);
// TX Buffer DMA enable
spi->reg->CR2 |= SPI_CR2_TXDMAEN;
} else
#endif
{
// Interrupt mode
// TX buffer empty interrupt enable
spi->reg->CR2 |= SPI_CR2_TXEIE;
}
return ARM_DRIVER_OK;
}
/**
\fn int32_t SPI_Transfer (const void *data_out, void *data_in, uint32_t num, const SPI_RESOURCES *spi)
\brief Start sending/receiving data to/from SPI transmitter/receiver.
\param[in] data_out Pointer to buffer with data to send to SPI transmitter
\param[out] data_in Pointer to buffer for data to receive from SPI receiver
\param[in] num Number of data items to transfer
\param[in] spi Pointer to SPI resources
\return \ref execution_status
*/
static int32_t SPI_Transfer (const void *data_out, void *data_in, uint32_t num, const SPI_RESOURCES *spi) {
#ifdef __SPI_DMA
uint32_t cfg;
#endif
if ((data_out == NULL) || (data_in == NULL) || (num == 0U)) { return ARM_DRIVER_ERROR_PARAMETER; }
if ((spi->info->state & SPI_CONFIGURED) == 0U) { return ARM_DRIVER_ERROR; }
if ( spi->info->status.busy) { return ARM_DRIVER_ERROR_BUSY; }
// Check if receive and transmit pins available
if ((spi->io.miso == NULL) || (spi->io.mosi == NULL)) {
return ARM_DRIVER_ERROR;
}
// Update SPI statuses
spi->info->status.busy = 1U;
spi->info->status.data_lost = 0U;
spi->info->status.mode_fault = 0U;
// Save transfer info
spi->xfer->rx_buf = (uint8_t *)data_in;
spi->xfer->tx_buf = (uint8_t *)data_out;
spi->xfer->num = num;
spi->xfer->rx_cnt = 0U;
spi->xfer->tx_cnt = 0U;
#ifdef __SPI_DMA
if ((spi->rx_dma != NULL) || (spi->tx_dma != NULL)) {
// DMA mode
if (spi->rx_dma != NULL) {
cfg = ((spi->rx_dma->priority << DMA_PRIORITY_POS) & DMA_PRIORITY_MASK) |
DMA_PERIPHERAL_TO_MEMORY |
DMA_MEMORY_INCREMENT |
DMA_TRANSFER_COMPLETE_INTERRUPT;
if (spi->reg->CR1 & SPI_CR1_DFF) {
// 16 - bit data frame
cfg |= DMA_PERIPHERAL_DATA_16BIT | DMA_MEMORY_DATA_16BIT;
} else {
// 8 - bit data frame
cfg |= DMA_PERIPHERAL_DATA_8BIT | DMA_MEMORY_DATA_8BIT;
}
DMA_ChannelConfigure(spi->rx_dma->instance,
cfg,
(uint32_t)(&spi->reg->DR),
(uint32_t)data_in,
num);
DMA_ChannelEnable(spi->rx_dma->instance);
// RX Buffer DMA enable
spi->reg->CR2 |= SPI_CR2_RXDMAEN;
}
if (spi->tx_dma != NULL) {
cfg = ((spi->tx_dma->priority << DMA_PRIORITY_POS) & DMA_PRIORITY_MASK) |
DMA_READ_MEMORY |
DMA_MEMORY_INCREMENT |
DMA_TRANSFER_COMPLETE_INTERRUPT;
DMA_ChannelConfigure(spi->tx_dma->instance,
cfg,
(uint32_t)(&spi->reg->DR),
(uint32_t)data_out,
num);
DMA_ChannelEnable(spi->tx_dma->instance);
// TX Buffer DMA enable
spi->reg->CR2 |= SPI_CR2_TXDMAEN;
}
} else
#endif
{
// Interrupt mode
// TX Buffer empty and RX Buffer not empty interrupt enable
spi->reg->CR2 |= SPI_CR2_RXNEIE | SPI_CR2_TXEIE;
}
return ARM_DRIVER_OK;
}
/**
\fn uint32_t SPI_GetDataCount (const SPI_RESOURCES *spi)
\brief Get transferred data count.
\param[in] spi Pointer to SPI resources
\return number of data items transferred
*/
static uint32_t SPI_GetDataCount (const SPI_RESOURCES *spi) {
return (spi->xfer->rx_cnt);
}
/**
\fn int32_t SPI_Control (uint32_t control, uint32_t arg, const SPI_RESOURCES *spi)
\brief Control SPI Interface.
\param[in] control operation
\param[in] arg argument of operation (optional)
\param[in] spi Pointer to SPI resources
\return \ref execution_status
*/
static int32_t SPI_Control (uint32_t control, uint32_t arg, const SPI_RESOURCES *spi) {
uint32_t mode, val, pclk;
uint32_t cr1, cr2;
mode = 0U;
val = 0U;
cr1 = 0U;
cr2 = 0U;
if ((spi->info->state & SPI_POWERED) == 0U) { return ARM_DRIVER_ERROR; }
if ((control & ARM_SPI_CONTROL_Msk) == ARM_SPI_ABORT_TRANSFER) {
// Send abort
if (spi->tx_dma != NULL) {
// DMA mode
// TX buffer DMA disable
spi->reg->CR2 &= ~SPI_CR2_TXDMAEN;
// Disable TX DMA transfer
DMA_ChannelDisable (spi->tx_dma->instance);
} else {
// Interrupt mode
// Disable TX buffer empty interrupt
spi->reg->CR2 &= ~SPI_CR2_TXEIE;
}
// Receive abort
if (spi->rx_dma != NULL) {
// DMA mode
// RX buffer DMA disable
spi->reg->CR2 &= ~SPI_CR2_RXDMAEN;
// Disable RX DMA transfer
DMA_ChannelDisable (spi->rx_dma->instance);
} else {
// Interrupt mode
// Disable RX buffer not empty interrupt
spi->reg->CR2 &= ~SPI_CR2_RXNEIE;
}
memset(spi->xfer, 0, sizeof(SPI_TRANSFER_INFO));
spi->info->status.busy = 0U;
return ARM_DRIVER_OK;
}
// Check for busy flag
if (spi->info->status.busy) { return ARM_DRIVER_ERROR_BUSY; }
switch (control & ARM_SPI_CONTROL_Msk) {
case ARM_SPI_MODE_INACTIVE:
mode |= ARM_SPI_MODE_INACTIVE;
break;
case ARM_SPI_MODE_MASTER:
mode |= ARM_SPI_MODE_MASTER;
// Master enabled
cr1 |= SPI_CR1_MSTR;
break;
case ARM_SPI_MODE_SLAVE:
mode |= ARM_SPI_MODE_SLAVE;
break;
case ARM_SPI_MODE_MASTER_SIMPLEX:
return ARM_SPI_ERROR_MODE;
case ARM_SPI_MODE_SLAVE_SIMPLEX:
return ARM_SPI_ERROR_MODE;
case ARM_SPI_SET_BUS_SPEED:
// Set SPI Bus Speed
pclk = spi->pclk;
for (val = 0U; val < 8U; val++) {
if (arg >= (pclk >> (val + 1U))) { break; }
}
if ((val == 8U) || (arg < (pclk >> (val + 1U)))) {
// Requested Bus Speed can not be configured
return ARM_DRIVER_ERROR;
}
// Disable SPI, update prescaler and enable SPI
spi->reg->CR1 &= ~SPI_CR1_SPE;
spi->reg->CR1 = (spi->reg->CR1 & ~SPI_CR1_BR) | (val << 3U);
spi->reg->CR1 |= SPI_CR1_SPE;
return ARM_DRIVER_OK;
case ARM_SPI_GET_BUS_SPEED:
// Return current bus speed
return (spi->pclk >> (((spi->reg->CR1 & SPI_CR1_BR) >> 3U) + 1U));
case ARM_SPI_SET_DEFAULT_TX_VALUE:
spi->xfer->def_val = (uint16_t)(arg & 0xFFFFU);
return ARM_DRIVER_OK;
case ARM_SPI_CONTROL_SS:
val = (spi->info->mode & ARM_SPI_CONTROL_Msk);
// Master modes
if (val == ARM_SPI_MODE_MASTER) {
val = spi->info->mode & ARM_SPI_SS_MASTER_MODE_Msk;
// Check if NSS pin is available and
// software slave select master is selected
if ((spi->io.nss != NULL) && (val == ARM_SPI_SS_MASTER_SW)) {
// Set/Clear NSS pin
if (arg == ARM_SPI_SS_INACTIVE)
GPIO_PinWrite (spi->io.nss->port, spi->io.nss->pin, 1);
else
GPIO_PinWrite (spi->io.nss->port, spi->io.nss->pin, 0);
} else return ARM_DRIVER_ERROR;
return ARM_DRIVER_OK;
}
// Slave modes
else if (val == ARM_SPI_MODE_SLAVE) {
val = spi->info->mode & ARM_SPI_SS_SLAVE_MODE_Msk;
// Check if slave select slave mode is selected
if (val == ARM_SPI_SS_MASTER_SW) {
if (arg == ARM_SPI_SS_ACTIVE) {
spi->reg->CR1 |= SPI_CR1_SSI;
}
else {
spi->reg->CR1 &= ~SPI_CR1_SSI;
}
return ARM_DRIVER_OK;
} else { return ARM_DRIVER_ERROR; }
} else { return ARM_DRIVER_ERROR; }
default:
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
// Frame format:
switch (control & ARM_SPI_FRAME_FORMAT_Msk) {
case ARM_SPI_CPOL0_CPHA0:
break;
case ARM_SPI_CPOL0_CPHA1:
cr1 |= SPI_CR1_CPHA;
break;
case ARM_SPI_CPOL1_CPHA0:
cr1 |= SPI_CR1_CPOL;
break;
case ARM_SPI_CPOL1_CPHA1:
cr1 |= SPI_CR1_CPHA | SPI_CR1_CPOL;
break;
case ARM_SPI_TI_SSI:
case ARM_SPI_MICROWIRE:
default:
return ARM_SPI_ERROR_FRAME_FORMAT;
}
// Data Bits
switch (control & ARM_SPI_DATA_BITS_Msk) {
case ARM_SPI_DATA_BITS(8U):
break;
case ARM_SPI_DATA_BITS(16U):
cr1 |= SPI_CR1_DFF;
break;
default: return ARM_SPI_ERROR_DATA_BITS;
}
// Bit order
if ((control & ARM_SPI_BIT_ORDER_Msk) == ARM_SPI_LSB_MSB) {
cr1 |= SPI_CR1_LSBFIRST;
}
// Slave select master modes
if (mode == ARM_SPI_MODE_MASTER) {
switch (control & ARM_SPI_SS_MASTER_MODE_Msk) {
case ARM_SPI_SS_MASTER_UNUSED:
if (spi->io.nss != NULL) {
// Unconfigure NSS pin
GPIO_PinConfigure (spi->io.nss->port, spi->io.nss->pin, GPIO_IN_ANALOG,
GPIO_MODE_INPUT);
}
// Software slave management
// Internal NSS always active, IO value is ignored
cr1 |= SPI_CR1_SSM | SPI_CR1_SSI;
mode |= ARM_SPI_SS_MASTER_UNUSED;
break;
case ARM_SPI_SS_MASTER_HW_INPUT:
if (spi->io.nss) {
// Configure NSS pin
GPIO_PortClock (spi->io.nss->port, true);
GPIO_PinConfigure (spi->io.nss->port, spi->io.nss->pin, GPIO_AF_PUSHPULL,
GPIO_MODE_OUT50MHZ);
} else {
// NSS pin is not available
return ARM_SPI_ERROR_SS_MODE;
}
mode |= ARM_SPI_SS_MASTER_HW_INPUT;
break;
case ARM_SPI_SS_MASTER_SW:
if (spi->io.nss) {
// Configure NSS pin as GPIO output
GPIO_PortClock (spi->io.nss->port, true);
GPIO_PinConfigure (spi->io.nss->port, spi->io.nss->pin, GPIO_OUT_PUSH_PULL,
GPIO_MODE_OUT50MHZ);
// Software slave management
cr1 |= SPI_CR1_SSM | SPI_CR1_SSI;
mode |= ARM_SPI_SS_MASTER_SW;
} else {
// NSS pin is not available
return ARM_SPI_ERROR_SS_MODE;
}
break;
case ARM_SPI_SS_MASTER_HW_OUTPUT:
if (spi->io.nss) {
// Configure NSS pin - SPI NSS alternative function
GPIO_PortClock (spi->io.nss->port, true);
GPIO_PinConfigure (spi->io.nss->port, spi->io.nss->pin, GPIO_AF_PUSHPULL,
GPIO_MODE_OUT50MHZ);
// Slave select output enable
cr2 |= SPI_CR2_SSOE;
mode |= ARM_SPI_SS_MASTER_HW_OUTPUT;
} else {
// NSS pin is not available
return ARM_SPI_ERROR_SS_MODE;
}
break;
default: return ARM_SPI_ERROR_SS_MODE;
}
}
// Slave select slave modes
if (mode == ARM_SPI_MODE_SLAVE) {
switch (control & ARM_SPI_SS_SLAVE_MODE_Msk) {
case ARM_SPI_SS_SLAVE_HW:
if (spi->io.nss) {
// Configure NSS pin - SPI NSS alternative function
GPIO_PortClock (spi->io.nss->port, true);
GPIO_PinConfigure (spi->io.nss->port, spi->io.nss->pin, GPIO_AF_PUSHPULL,
GPIO_MODE_OUT50MHZ);
mode |= ARM_SPI_SS_SLAVE_HW;
} else {
// NSS pin is not available
return ARM_SPI_ERROR_SS_MODE;
}
break;
case ARM_SPI_SS_SLAVE_SW:
if (spi->io.nss) {
// Unconfigure NSS pin
GPIO_PinConfigure (spi->io.nss->port, spi->io.nss->pin, GPIO_IN_ANALOG,
GPIO_MODE_INPUT);
}
// Enable software slave management
cr1 |= SPI_CR1_SSM;
mode |= ARM_SPI_SS_SLAVE_SW;
break;
default: return ARM_SPI_ERROR_SS_MODE;
}
}
// Set SPI Bus Speed
pclk = spi->pclk;
for (val = 0U; val < 8U; val++) {
if (arg >= (pclk >> (val + 1U))) break;
}
if ((val == 8U) || (arg < (pclk >> (val + 1U)))) {
// Requested Bus Speed can not be configured
return ARM_DRIVER_ERROR;
}
// Save prescaler value
cr1 |= (val << 3U);
spi->info->mode = mode;
// Configure registers
spi->reg->CR1 &= ~SPI_CR1_SPE;
spi->reg->CR2 = cr2 | SPI_CR2_ERRIE;
spi->reg->CR1 = cr1;
if ((mode & ARM_SPI_CONTROL_Msk) == ARM_SPI_MODE_INACTIVE) {
spi->info->state &= ~SPI_CONFIGURED;
} else {
spi->info->state |= SPI_CONFIGURED;
}
// Enable SPI
spi->reg->CR1 |= SPI_CR1_SPE;
return ARM_DRIVER_OK;
}
/**
\fn ARM_SPI_STATUS SPI_GetStatus (const SPI_RESOURCES *spi)
\brief Get SPI status.
\param[in] spi Pointer to SPI resources
\return SPI status \ref ARM_SPI_STATUS
*/
static ARM_SPI_STATUS SPI_GetStatus (const SPI_RESOURCES *spi) {
ARM_SPI_STATUS status;
status.busy = spi->info->status.busy;
status.data_lost = spi->info->status.data_lost;
status.mode_fault = spi->info->status.mode_fault;
return status;
}
/*SPI IRQ Handler */
void SPI_IRQHandler (const SPI_RESOURCES *spi) {
uint8_t data_8bit;
uint16_t data_16bit, sr;
uint32_t event;
// Save status register
sr = spi->reg->SR;
event = 0U;
if ((sr & SPI_SR_OVR) != 0U) {
// Clear Overrun flag by reading data and status register
if ((spi->reg->CR1 & SPI_CR1_DFF) == 0U) {
// 8-bit data frame
data_8bit = *(volatile uint8_t *)(&spi->reg->DR);
if (spi->xfer->rx_cnt < spi->xfer->num) {
if (spi->xfer->rx_buf != NULL) {
*(spi->xfer->rx_buf++) = data_8bit;
}
}
} else {
// 16-bit data frame
data_16bit = *(volatile uint16_t *)(&spi->reg->DR);
if (spi->xfer->rx_cnt < spi->xfer->num) {
if (spi->xfer->rx_buf != NULL) {
*(spi->xfer->rx_buf++) = (uint8_t) data_16bit;
*(spi->xfer->rx_buf++) = (uint8_t)(data_16bit >> 8U);
}
}
}
spi->xfer->rx_cnt++;
sr = spi->reg->SR;
spi->info->status.data_lost = 1U;
event |=ARM_SPI_EVENT_DATA_LOST;
}
if ((sr & SPI_SR_UDR) != 0U) {
// Underrun flag is set
spi->info->status.data_lost = 1U;
event |= ARM_SPI_EVENT_DATA_LOST;
}
if ((sr & SPI_SR_MODF) != 0U) {
// Mode fault flag is set
spi->info->status.mode_fault = 1U;
// Write CR1 register to clear MODF flag
spi->reg->CR1 = spi->reg->CR1;
event |= ARM_SPI_EVENT_MODE_FAULT;
}
if (((sr & SPI_SR_RXNE) != 0U) && ((spi->reg->CR2 & SPI_CR2_RXNEIE) != 0U)) {
// Receive Buffer Not Empty
if (spi->xfer->rx_cnt < spi->xfer->num) {
if ((spi->reg->CR1 & SPI_CR1_DFF) == 0U) {
// 8-bit data frame
data_8bit = *(volatile uint8_t *)(&spi->reg->DR);
if (spi->xfer->rx_buf != NULL) {
*(spi->xfer->rx_buf++) = data_8bit;
}
} else {
// 16-bit data frame
data_16bit = *(volatile uint16_t *)(&spi->reg->DR);
if (spi->xfer->rx_buf != NULL) {
*(spi->xfer->rx_buf++) = (uint8_t) data_16bit;
*(spi->xfer->rx_buf++) = (uint8_t)(data_16bit >> 8U);
}
}
spi->xfer->rx_cnt++;
if (spi->xfer->rx_cnt == spi->xfer->num) {
// Disable RX Buffer Not Empty Interrupt
spi->reg->CR2 &= ~SPI_CR2_RXNEIE;
// Clear busy flag
spi->info->status.busy = 0U;
// Transfer completed
event |= ARM_SPI_EVENT_TRANSFER_COMPLETE;
}
}
else {
// Unexpected transfer, data lost
event |= ARM_SPI_EVENT_DATA_LOST;
}
}
if (((sr & SPI_SR_TXE) != 0U) && ((spi->reg->CR2 & SPI_CR2_TXEIE) != 0U)) {
if (spi->xfer->tx_cnt < spi->xfer->num) {
if ((spi->reg->CR1 & SPI_CR1_DFF) == 0U) {
if (spi->xfer->tx_buf != NULL) {
data_8bit = *(spi->xfer->tx_buf++);
} else {
data_8bit = (uint8_t)spi->xfer->def_val;
}
// Write data to data register
*(volatile uint8_t *)(&spi->reg->DR) = data_8bit;
} else {
if (spi->xfer->tx_buf != NULL) {
data_16bit = *(spi->xfer->tx_buf++);
data_16bit |= *(spi->xfer->tx_buf++) << 8U;
} else {
data_16bit = (uint16_t)spi->xfer->def_val;
}
// Write data to data register
*(volatile uint16_t *)(&spi->reg->DR) = data_16bit;
}
spi->xfer->tx_cnt++;
if (spi->xfer->tx_cnt == spi->xfer->num) {
// All data sent, disable TX Buffer Empty Interrupt
spi->reg->CR2 &= ~SPI_CR2_TXEIE;
}
} else {
// Unexpected transfer, data lost
event |= ARM_SPI_EVENT_DATA_LOST;
}
}
// Send event
if ((event != 0U) && ((spi->info->cb_event != NULL))) {
spi->info->cb_event(event);
}
}
#ifdef __SPI_DMA_TX
void SPI_TX_DMA_Complete(uint32_t events, const SPI_RESOURCES *spi) {
DMA_ChannelDisable(spi->tx_dma->instance);
if ((DMA_ChannelTransferItemCount(spi->tx_dma->instance) != 0) && (spi->xfer->num != 0)) {
// TX DMA Complete caused by transfer abort
return;
}
spi->xfer->tx_cnt = spi->xfer->num;
}
#endif
#ifdef __SPI_DMA_RX
void SPI_RX_DMA_Complete(uint32_t events, const SPI_RESOURCES *spi) {
DMA_ChannelDisable(spi->rx_dma->instance);
if ((DMA_ChannelTransferItemCount(spi->rx_dma->instance) != 0) && (spi->xfer->num != 0)) {
// RX DMA Complete caused by transfer abort
return;
}
spi->xfer->rx_cnt = spi->xfer->num;
spi->info->status.busy = 0U;
if (spi->info->cb_event != NULL) {
spi->info->cb_event(ARM_SPI_EVENT_TRANSFER_COMPLETE);
}
}
#endif
// SPI1
#ifdef MX_SPI1
static int32_t SPI1_Initialize (ARM_SPI_SignalEvent_t pSignalEvent) { return SPI_Initialize (pSignalEvent, &SPI1_Resources); }
static int32_t SPI1_Uninitialize (void) { return SPI_Uninitialize (&SPI1_Resources); }
static int32_t SPI1_PowerControl (ARM_POWER_STATE state) { return SPI_PowerControl (state, &SPI1_Resources); }
static int32_t SPI1_Send (const void *data, uint32_t num) { return SPI_Send (data, num, &SPI1_Resources); }
static int32_t SPI1_Receive (void *data, uint32_t num) { return SPI_Receive (data, num, &SPI1_Resources); }
static int32_t SPI1_Transfer (const void *data_out, void *data_in, uint32_t num) { return SPI_Transfer (data_out, data_in, num, &SPI1_Resources); }
static uint32_t SPI1_GetDataCount (void) { return SPI_GetDataCount (&SPI1_Resources); }
static int32_t SPI1_Control (uint32_t control, uint32_t arg) { return SPI_Control (control, arg, &SPI1_Resources); }
static ARM_SPI_STATUS SPI1_GetStatus (void) { return SPI_GetStatus (&SPI1_Resources); }
void SPI1_IRQHandler (void) { SPI_IRQHandler (&SPI1_Resources); }
#ifdef MX_SPI1_TX_DMA_Instance
void SPI1_TX_DMA_Handler (uint32_t events) { SPI_TX_DMA_Complete (events, &SPI1_Resources); }
#endif
#ifdef MX_SPI1_RX_DMA_Instance
void SPI1_RX_DMA_Handler (uint32_t events) { SPI_RX_DMA_Complete (events, &SPI1_Resources); }
#endif
ARM_DRIVER_SPI Driver_SPI1 = {
SPIX_GetVersion,
SPIX_GetCapabilities,
SPI1_Initialize,
SPI1_Uninitialize,
SPI1_PowerControl,
SPI1_Send,
SPI1_Receive,
SPI1_Transfer,
SPI1_GetDataCount,
SPI1_Control,
SPI1_GetStatus
};
#endif
// SPI2
#ifdef MX_SPI2
static int32_t SPI2_Initialize (ARM_SPI_SignalEvent_t pSignalEvent) { return SPI_Initialize (pSignalEvent, &SPI2_Resources); }
static int32_t SPI2_Uninitialize (void) { return SPI_Uninitialize (&SPI2_Resources); }
static int32_t SPI2_PowerControl (ARM_POWER_STATE state) { return SPI_PowerControl (state, &SPI2_Resources); }
static int32_t SPI2_Send (const void *data, uint32_t num) { return SPI_Send (data, num, &SPI2_Resources); }
static int32_t SPI2_Receive (void *data, uint32_t num) { return SPI_Receive (data, num, &SPI2_Resources); }
static int32_t SPI2_Transfer (const void *data_out, void *data_in, uint32_t num) { return SPI_Transfer (data_out, data_in, num, &SPI2_Resources); }
static uint32_t SPI2_GetDataCount (void) { return SPI_GetDataCount (&SPI2_Resources); }
static int32_t SPI2_Control (uint32_t control, uint32_t arg) { return SPI_Control (control, arg, &SPI2_Resources); }
static ARM_SPI_STATUS SPI2_GetStatus (void) { return SPI_GetStatus (&SPI2_Resources); }
void SPI2_IRQHandler (void) { SPI_IRQHandler (&SPI2_Resources); }
#ifdef MX_SPI2_TX_DMA_Instance
void SPI2_TX_DMA_Handler (uint32_t events) { SPI_TX_DMA_Complete (events, &SPI2_Resources); }
#endif
#ifdef MX_SPI2_RX_DMA_Instance
void SPI2_RX_DMA_Handler (uint32_t events) { SPI_RX_DMA_Complete (events, &SPI2_Resources); }
#endif
ARM_DRIVER_SPI Driver_SPI2 = {
SPIX_GetVersion,
SPIX_GetCapabilities,
SPI2_Initialize,
SPI2_Uninitialize,
SPI2_PowerControl,
SPI2_Send,
SPI2_Receive,
SPI2_Transfer,
SPI2_GetDataCount,
SPI2_Control,
SPI2_GetStatus
};
#endif
// SPI3
#ifdef MX_SPI3
static int32_t SPI3_Initialize (ARM_SPI_SignalEvent_t pSignalEvent) { return SPI_Initialize (pSignalEvent, &SPI3_Resources); }
static int32_t SPI3_Uninitialize (void) { return SPI_Uninitialize (&SPI3_Resources); }
static int32_t SPI3_PowerControl (ARM_POWER_STATE state) { return SPI_PowerControl (state, &SPI3_Resources); }
static int32_t SPI3_Send (const void *data, uint32_t num) { return SPI_Send (data, num, &SPI3_Resources); }
static int32_t SPI3_Receive (void *data, uint32_t num) { return SPI_Receive (data, num, &SPI3_Resources); }
static int32_t SPI3_Transfer (const void *data_out, void *data_in, uint32_t num) { return SPI_Transfer (data_out, data_in, num, &SPI3_Resources); }
static uint32_t SPI3_GetDataCount (void) { return SPI_GetDataCount (&SPI3_Resources); }
static int32_t SPI3_Control (uint32_t control, uint32_t arg) { return SPI_Control (control, arg, &SPI3_Resources); }
static ARM_SPI_STATUS SPI3_GetStatus (void) { return SPI_GetStatus (&SPI3_Resources); }
void SPI3_IRQHandler (void) { SPI_IRQHandler (&SPI3_Resources); }
#ifdef MX_SPI3_TX_DMA_Instance
void SPI3_TX_DMA_Handler (uint32_t events) { SPI_TX_DMA_Complete (events, &SPI3_Resources); }
#endif
#ifdef MX_SPI3_RX_DMA_Instance
void SPI3_RX_DMA_Handler (uint32_t events) { SPI_RX_DMA_Complete (events, &SPI3_Resources); }
#endif
ARM_DRIVER_SPI Driver_SPI3 = {
SPIX_GetVersion,
SPIX_GetCapabilities,
SPI3_Initialize,
SPI3_Uninitialize,
SPI3_PowerControl,
SPI3_Send,
SPI3_Receive,
SPI3_Transfer,
SPI3_GetDataCount,
SPI3_Control,
SPI3_GetStatus
};
#endif