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

1446 lines
42 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: 21. October 2015
* $Revision: V2.1
*
* Driver: Driver_I2C1, Driver_I2C2
* Configured: via RTE_Device.h configuration file
* Project: I2C Driver for STMicroelectronics STM32F10x
* --------------------------------------------------------------------------
* Use the following configuration settings in the middleware component
* to connect to this driver.
*
* Configuration Setting Value I2C Interface
* --------------------- ----- -------------
* Connect to hardware via Driver_I2C# = 1 use I2C1
* Connect to hardware via Driver_I2C# = 2 use I2C2
* -------------------------------------------------------------------------- */
/* History:
* Version 2.1
* Corrected invalid __I2C_DMA field in I2C_DMA_TxEvent and I2C_DMA_RxEvent functions (corrected from instance into reg)
* Version 2.0
* Updated to the CMSIS Driver API V2.02
* Version 1.2
* Bugfix (corrected I2C register access)
* Version 1.1
* Based on API V1.10 (namespace prefix ARM_ added)
* Version 1.0
* Initial release
*/
#include "I2C_STM32F10x.h"
#define ARM_I2C_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(2,1) /* driver version */
/* Driver Version */
static const ARM_DRIVER_VERSION DriverVersion = {
ARM_I2C_API_VERSION,
ARM_I2C_DRV_VERSION
};
/* Driver Capabilities */
static const ARM_I2C_CAPABILITIES DriverCapabilities = { 0U };
#if defined(USE_I2C1)
/* Function prototypes */
void I2C1_EV_IRQHandler (void);
void I2C1_ER_IRQHandler (void);
/* I2C1 DMA */
#if defined(I2C1_RX_DMA_Instance) && defined(I2C1_TX_DMA_Instance)
static const I2C_DMA I2C1_RX_DMA = {
I2C1_RX_DMA_Instance,
I2C1_RX_DMA_Number,
I2C1_RX_DMA_Channel,
I2C1_RX_DMA_Priority
};
static const I2C_DMA I2C1_TX_DMA = {
I2C1_TX_DMA_Instance,
I2C1_TX_DMA_Number,
I2C1_TX_DMA_Channel,
I2C1_TX_DMA_Priority
};
#endif
/* I2C1 Information (Run-Time) */
static I2C_INFO I2C1_Info;
/* I2C1 Resources */
static I2C_RESOURCES I2C1_Resources = {
I2C1,
#if defined(I2C1_RX_DMA_Instance) && defined(I2C1_TX_DMA_Instance)
&I2C1_RX_DMA,
&I2C1_TX_DMA,
#else
NULL,
NULL,
#endif
{
I2C1_SCL_GPIOx,
I2C1_SDA_GPIOx,
I2C1_SCL_GPIO_Pin,
I2C1_SDA_GPIO_Pin,
I2C1_AF_REMAP,
},
I2C1_EV_IRQn,
I2C1_ER_IRQn,
RCC_APB_I2C1_MASK,
&I2C1_Info
};
#endif /* USE_I2C1 */
#if defined(USE_I2C2)
/* Function prototypes */
void I2C2_EV_IRQHandler (void);
void I2C2_ER_IRQHandler (void);
/* I2C2 DMA */
#if defined(I2C2_RX_DMA_Instance) && defined(I2C2_TX_DMA_Instance)
static const I2C_DMA I2C2_RX_DMA = {
I2C2_RX_DMA_Instance,
I2C2_RX_DMA_Number,
I2C2_RX_DMA_Channel,
I2C2_RX_DMA_Priority
};
static const I2C_DMA I2C2_TX_DMA = {
I2C2_TX_DMA_Instance,
I2C2_TX_DMA_Number,
I2C2_TX_DMA_Channel,
I2C2_TX_DMA_Priority
};
#endif
/* I2C2 Information (Run-Time) */
static I2C_INFO I2C2_Info;
/* I2C2 Resources */
static I2C_RESOURCES I2C2_Resources = {
I2C2,
#if defined(I2C2_RX_DMA_Instance) && defined(I2C2_TX_DMA_Instance)
&I2C2_RX_DMA,
&I2C2_TX_DMA,
#else
NULL,
NULL,
#endif
{
I2C2_SCL_GPIOx,
I2C2_SDA_GPIOx,
I2C2_SCL_GPIO_Pin,
I2C2_SDA_GPIO_Pin,
I2C2_AF_REMAP,
},
I2C2_EV_IRQn,
I2C2_ER_IRQn,
RCC_APB_I2C2_MASK,
&I2C2_Info
};
#endif /* USE_I2C2 */
/**
\fn ARM_DRV_VERSION I2C_GetVersion (void)
\brief Get driver version.
\return \ref ARM_DRV_VERSION
*/
static ARM_DRIVER_VERSION I2CX_GetVersion (void) {
return DriverVersion;
}
/**
\fn ARM_I2C_CAPABILITIES I2C_GetCapabilities (void)
\brief Get driver capabilities.
\return \ref ARM_I2C_CAPABILITIES
*/
static ARM_I2C_CAPABILITIES I2CX_GetCapabilities (void) {
return DriverCapabilities;
}
/**
\fn int32_t I2C_Initialize (ARM_I2C_SignalEvent_t cb_event, I2C_RESOURCES *i2c)
\brief Initialize I2C Interface.
\param[in] cb_event Pointer to \ref ARM_I2C_SignalEvent
\param[in] i2c Pointer to I2C resources
\return \ref ARM_I2C_STATUS
*/
static int32_t I2C_Initialize (ARM_I2C_SignalEvent_t cb_event, I2C_RESOURCES *i2c) {
if (i2c->info->flags & I2C_INIT) { return ARM_DRIVER_OK; }
GPIO_AFConfigure(i2c->io.remap);
/* Configure SCL Pin */
GPIO_PortClock (i2c->io.scl_port, true);
GPIO_PinConfigure(i2c->io.scl_port, i2c->io.scl_pin, GPIO_AF_OPENDRAIN,
GPIO_MODE_OUT50MHZ);
/* Configure SDA Pin */
GPIO_PortClock (i2c->io.sda_port, true);
GPIO_PinConfigure(i2c->io.sda_port, i2c->io.sda_pin, GPIO_AF_OPENDRAIN,
GPIO_MODE_OUT50MHZ);
/* Initialize DMA Channels */
#if defined(USE_I2C1_DMA) || defined(USE_I2C2_DMA)
if ((i2c->dma_rx != NULL) && (i2c->dma_tx != NULL)) {
DMA_ChannelInitialize(i2c->dma_rx->dma_num, i2c->dma_rx->channel);
DMA_ChannelInitialize(i2c->dma_tx->dma_num, i2c->dma_tx->channel);
}
#endif
/* Reset Run-Time information structure */
memset (i2c->info, 0x00, sizeof (I2C_INFO));
i2c->info->cb_event = cb_event;
i2c->info->flags = I2C_INIT;
return ARM_DRIVER_OK;
}
/**
\fn int32_t I2C_Uninitialize (I2C_RESOURCES *i2c)
\brief De-initialize I2C Interface.
\param[in] i2c Pointer to I2C resources
\return \ref execution_status
*/
static int32_t I2C_Uninitialize (I2C_RESOURCES *i2c) {
/* Unconfigure SCL Pin */
GPIO_PinConfigure(i2c->io.scl_port, i2c->io.scl_pin, GPIO_IN_ANALOG,
GPIO_MODE_OUT2MHZ);
/* Unconfigure SDA Pin */
GPIO_PinConfigure(i2c->io.sda_port, i2c->io.sda_pin, GPIO_IN_ANALOG,
GPIO_MODE_OUT2MHZ);
GPIO_AFConfigure(AFIO_I2C1_NO_REMAP);
/* Uninitialize DMA Channels */
#if defined(USE_I2C1_DMA) || defined(USE_I2C2_DMA)
if ((i2c->dma_rx != NULL) && (i2c->dma_tx != NULL)) {
DMA_ChannelUninitialize(i2c->dma_rx->dma_num, i2c->dma_rx->channel);
DMA_ChannelUninitialize(i2c->dma_tx->dma_num, i2c->dma_tx->channel);
}
#endif
i2c->info->flags = 0U;
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_I2C_PowerControl (ARM_POWER_STATE state, I2C_RESOURCES *i2c)
\brief Control I2C Interface Power.
\param[in] state Power state
\param[in] i2c Pointer to I2C resources
\return \ref execution_status
*/
static int32_t I2C_PowerControl (ARM_POWER_STATE state, I2C_RESOURCES *i2c) {
switch (state) {
case ARM_POWER_OFF:
/* Enable I2C clock */
RCC->APB1ENR |= i2c->apb_mask;
/* Disable I2C peripheral */
i2c->reg->CR1 = 0;
#if defined(USE_I2C1_DMA) || defined(USE_I2C2_DMA)
if ((i2c->dma_rx != NULL) && (i2c->dma_tx != NULL)) {
/* Abort DMA channels */
DMA_ChannelDisable (i2c->dma_rx->reg);
DMA_ChannelDisable (i2c->dma_tx->reg);
}
#endif
/* Disable I2C IRQ */
NVIC_DisableIRQ(i2c->ev_irq_num);
NVIC_DisableIRQ(i2c->er_irq_num);
/* Disable peripheral clock */
RCC->APB1ENR &= ~i2c->apb_mask;
i2c->info->status.busy = 0U;
i2c->info->status.mode = 0U;
i2c->info->status.direction = 0U;
i2c->info->status.general_call = 0U;
i2c->info->status.arbitration_lost = 0U;
i2c->info->status.bus_error = 0U;
i2c->info->flags &= ~I2C_POWER;
break;
case ARM_POWER_LOW:
return ARM_DRIVER_ERROR_UNSUPPORTED;
case ARM_POWER_FULL:
if ((i2c->info->flags & I2C_INIT) == 0U) {
return ARM_DRIVER_ERROR;
}
if ((i2c->info->flags & I2C_POWER) != 0U) {
return ARM_DRIVER_OK;
}
/* Enable I2C clock */
RCC->APB1ENR |= i2c->apb_mask;
/* Clear and Enable I2C IRQ */
NVIC_ClearPendingIRQ(i2c->ev_irq_num);
NVIC_ClearPendingIRQ(i2c->er_irq_num);
NVIC_EnableIRQ(i2c->ev_irq_num);
NVIC_EnableIRQ(i2c->er_irq_num);
/* Reset the peripheral */
RCC->APB1RSTR |= i2c->apb_mask;
__NOP(); __NOP(); __NOP(); __NOP();
RCC->APB1RSTR &= ~i2c->apb_mask;
/* Enable event and error interrupts */
i2c->reg->CR2 |= I2C_CR2_ITEVTEN | I2C_CR2_ITERREN;
/* Disable buffer interrupts */
i2c->reg->CR2 &= ~I2C_CR2_ITBUFEN;
/* Enable clock stretching */
i2c->reg->CR1 &= ~I2C_CR1_NOSTRETCH;
/* Enable I2C peripheral */
i2c->reg->CR1 |= I2C_CR1_PE;
/* Enable acknowledge */
i2c->reg->CR1 |= I2C_CR1_ACK;
/* Ready for operation */
i2c->info->flags |= I2C_POWER;
break;
}
return ARM_DRIVER_OK;
}
/**
\fn int32_t I2C_MasterTransmit (uint32_t addr,
const uint8_t *data,
uint32_t num,
bool xfer_pending,
I2C_RESOURCES *i2c)
\brief Start transmitting data as I2C Master.
\param[in] addr Slave address (7-bit or 10-bit)
\param[in] data Pointer to buffer with data to send to I2C Slave
\param[in] num Number of data bytes to send
\param[in] xfer_pending Transfer operation is pending - Stop condition will not be generated
\param[in] i2c Pointer to I2C resources
\return \ref execution_status
*/
static int32_t I2C_MasterTransmit (uint32_t addr,
const uint8_t *data,
uint32_t num,
bool xfer_pending,
I2C_RESOURCES *i2c) {
if ((data == NULL) || (num == 0U)) {
return ARM_DRIVER_ERROR_PARAMETER;
}
if ((addr & ~(ARM_I2C_ADDRESS_10BIT | ARM_I2C_ADDRESS_GC)) > 0x3FFU) {
return ARM_DRIVER_ERROR_PARAMETER;
}
if (i2c->info->status.busy) {
return (ARM_DRIVER_ERROR_BUSY);
}
if ((i2c->info->xfer.ctrl & XFER_CTRL_XPENDING) == 0U) {
/* New transfer */
while (i2c->reg->SR2 & I2C_SR2_BUSY) {
; /* Wait until bus released */
}
}
i2c->info->status.busy = 1U;
i2c->info->status.mode = 1U;
i2c->info->status.direction = 0U;
i2c->info->status.bus_error = 0U;
i2c->info->status.arbitration_lost = 0U;
i2c->info->xfer.num = num;
i2c->info->xfer.cnt = 0U;
i2c->info->xfer.data = (uint8_t *)data;
i2c->info->xfer.addr = (uint16_t)(addr);
i2c->info->xfer.ctrl = 0U;
if (xfer_pending) {
i2c->info->xfer.ctrl |= XFER_CTRL_XPENDING;
}
#if defined(USE_I2C1_DMA) || defined(USE_I2C2_DMA)
if (i2c->dma_tx) {
/* Configure and enable DMA channel */
DMA_ChannelConfigure (i2c->dma_tx->reg,
(i2c->dma_rx->priority << DMA_PRIORITY_POS)|
DMA_MEMORY_DATA_8BIT |
DMA_PERIPHERAL_DATA_8BIT |
DMA_MEMORY_INCREMENT |
DMA_READ_MEMORY |
DMA_TRANSFER_COMPLETE_INTERRUPT,
(uint32_t)&(i2c->reg->DR),
(uint32_t)data,
num);
DMA_ChannelEnable (i2c->dma_tx->reg);
}
#endif
/* Generate start and enable event interrupts */
i2c->reg->CR2 &= ~I2C_CR2_ITEVTEN;
i2c->reg->CR1 |= I2C_CR1_START;
i2c->reg->CR2 |= I2C_CR2_ITEVTEN;
return ARM_DRIVER_OK;
}
/**
\fn int32_t I2C_MasterReceive (uint32_t addr,
uint8_t *data,
uint32_t num,
bool xfer_pending,
I2C_RESOURCES *i2c)
\brief Start receiving data as I2C Master.
\param[in] addr Slave address (7-bit or 10-bit)
\param[out] data Pointer to buffer for data to receive from I2C Slave
\param[in] num Number of data bytes to receive
\param[in] xfer_pending Transfer operation is pending - Stop condition will not be generated
\param[in] i2c Pointer to I2C resources
\return \ref execution_status
*/
static int32_t I2C_MasterReceive (uint32_t addr,
uint8_t *data,
uint32_t num,
bool xfer_pending,
I2C_RESOURCES *i2c) {
if ((data == NULL) || (num == 0U)) {
return ARM_DRIVER_ERROR_PARAMETER;
}
if ((addr & ~(ARM_I2C_ADDRESS_10BIT | ARM_I2C_ADDRESS_GC)) > 0x3FFU) {
return ARM_DRIVER_ERROR_PARAMETER;
}
if (i2c->info->status.busy) {
return (ARM_DRIVER_ERROR_BUSY);
}
if ((i2c->info->xfer.ctrl & XFER_CTRL_XPENDING) == 0U) {
/* New transfer */
while (i2c->reg->SR2 & I2C_SR2_BUSY) {
; /* Wait until bus released */
}
}
i2c->info->status.busy = 1U;
i2c->info->status.mode = 1U;
i2c->info->status.direction = 1U;
i2c->info->status.bus_error = 0U;
i2c->info->status.arbitration_lost = 0U;
i2c->info->xfer.num = num;
i2c->info->xfer.cnt = 0U;
i2c->info->xfer.data = data;
i2c->info->xfer.addr = (uint16_t)(addr);
i2c->info->xfer.ctrl = 0U;
if (xfer_pending) {
i2c->info->xfer.ctrl |= XFER_CTRL_XPENDING;
}
/* Enable acknowledge generation */
i2c->reg->CR1 |= I2C_CR1_ACK;
#if defined(USE_I2C1_DMA) || defined(USE_I2C2_DMA)
if (i2c->dma_rx) {
/* Configure and enable DMA channel */
DMA_ChannelConfigure (i2c->dma_rx->reg,
(i2c->dma_rx->priority << DMA_PRIORITY_POS)|
DMA_MEMORY_DATA_8BIT |
DMA_PERIPHERAL_DATA_8BIT |
DMA_MEMORY_INCREMENT |
DMA_PERIPHERAL_TO_MEMORY |
DMA_TRANSFER_COMPLETE_INTERRUPT,
(uint32_t)&(i2c->reg->DR),
(uint32_t)data,
num);
DMA_ChannelEnable (i2c->dma_rx->reg);
/* Permit generation of a NACK on the last received data */
i2c->reg->CR2 |= I2C_CR2_LAST;
}
#endif
/* Generate start and enable event interrupts */
i2c->reg->CR2 &= ~I2C_CR2_ITEVTEN;
i2c->reg->CR1 |= I2C_CR1_START;
i2c->reg->CR2 |= I2C_CR2_ITEVTEN;
return ARM_DRIVER_OK;
}
/**
\fn int32_t I2C_SlaveTransmit (const uint8_t *data, uint32_t num, I2C_RESOURCES *i2c)
\brief Start transmitting data as I2C Slave.
\param[in] data Pointer to buffer with data to send to I2C Master
\param[in] num Number of data bytes to send
\param[in] i2c Pointer to I2C resources
\return \ref execution_status
*/
static int32_t I2C_SlaveTransmit (const uint8_t *data, uint32_t num, I2C_RESOURCES *i2c) {
if ((data == NULL) || (num == 0U)) {
return ARM_DRIVER_ERROR_PARAMETER;
}
if (i2c->info->status.busy) {
return (ARM_DRIVER_ERROR_BUSY);
}
i2c->info->status.bus_error = 0U;
i2c->info->status.general_call = 0U;
i2c->info->xfer.num = num;
i2c->info->xfer.cnt = 0U;
i2c->info->xfer.data = (uint8_t *)data;
i2c->info->xfer.ctrl = 0U;
#if defined(USE_I2C1_DMA) || defined(USE_I2C2_DMA)
if (i2c->dma_tx) {
/* Configure and enable DMA channel */
DMA_ChannelConfigure (i2c->dma_tx->reg,
(i2c->dma_tx->priority << DMA_PRIORITY_POS)|
DMA_MEMORY_DATA_8BIT |
DMA_PERIPHERAL_DATA_8BIT |
DMA_MEMORY_INCREMENT |
DMA_READ_MEMORY |
DMA_TRANSFER_COMPLETE_INTERRUPT,
(uint32_t)&(i2c->reg->DR),
(uint32_t)data,
num);
DMA_ChannelEnable (i2c->dma_tx->reg);
}
#endif
/* Enable acknowledge */
i2c->reg->CR1 |= I2C_CR1_ACK;
/* Enable event interrupts */
i2c->reg->CR2 |= I2C_CR2_ITEVTEN;
return ARM_DRIVER_OK;
}
/**
\fn int32_t I2C_SlaveReceive (uint8_t *data, uint32_t num, I2C_RESOURCES *i2c)
\brief Start receiving data as I2C Slave.
\param[out] data Pointer to buffer for data to receive from I2C Master
\param[in] num Number of data bytes to receive
\param[in] i2c Pointer to I2C resources
\return \ref execution_status
*/
static int32_t I2C_SlaveReceive (uint8_t *data, uint32_t num, I2C_RESOURCES *i2c) {
if ((data == NULL) || (num == 0U)) {
return ARM_DRIVER_ERROR_PARAMETER;
}
if (i2c->info->status.busy) {
return (ARM_DRIVER_ERROR_BUSY);
}
i2c->info->status.bus_error = 0U;
i2c->info->status.general_call = 0U;
i2c->info->xfer.num = num;
i2c->info->xfer.cnt = 0U;
i2c->info->xfer.data = data;
i2c->info->xfer.ctrl = 0U;
/* Enable acknowledge generation */
i2c->reg->CR2 |= I2C_CR2_LAST;
#if defined(USE_I2C1_DMA) || defined(USE_I2C2_DMA)
if (i2c->dma_rx) {
/* Configure and enable DMA channel */
DMA_ChannelConfigure (i2c->dma_rx->reg,
(i2c->dma_rx->priority << DMA_PRIORITY_POS)|
DMA_MEMORY_DATA_8BIT |
DMA_PERIPHERAL_DATA_8BIT |
DMA_MEMORY_INCREMENT |
DMA_PERIPHERAL_TO_MEMORY |
DMA_TRANSFER_COMPLETE_INTERRUPT,
(uint32_t)&(i2c->reg->DR),
(uint32_t)data,
num);
DMA_ChannelEnable (i2c->dma_rx->reg);
}
#endif
/* Enable acknowledge */
i2c->reg->CR1 |= I2C_CR1_ACK;
/* Enable event interrupts */
i2c->reg->CR2 |= I2C_CR2_ITEVTEN;
return ARM_DRIVER_OK;
}
/**
\fn int32_t I2C_GetDataCount (void)
\brief Get transferred data count.
\return number of data bytes transferred; -1 when Slave is not addressed by Master
*/
static int32_t I2C_GetDataCount (I2C_RESOURCES *i2c) {
return ((int32_t)i2c->info->xfer.cnt);
}
/**
\fn int32_t I2C_Control (uint32_t control, uint32_t arg, I2C_RESOURCES *i2c)
\brief Control I2C Interface.
\param[in] control operation
\param[in] arg argument of operation (optional)
\param[in] i2c pointer to I2C resources
\return \ref execution_status
*/
static int32_t I2C_Control (uint32_t control, uint32_t arg, I2C_RESOURCES *i2c) {
uint32_t state;
uint32_t i, j, pclk;
uint32_t ccr;
uint32_t trise;
if ((i2c->info->flags & I2C_POWER) == 0U) {
/* I2C not powered */
return ARM_DRIVER_ERROR;
}
switch (control) {
case ARM_I2C_OWN_ADDRESS:
/* Enable/Disable General call */
if (arg & ARM_I2C_ADDRESS_GC) {
i2c->reg->CR1 |= I2C_CR1_ENGC;
} else {
i2c->reg->CR1 &= ~I2C_CR1_ENGC;
}
/* Set own address and its length */
i2c->reg->OAR1 = ((arg << 1) & 0x03FFU) |
(1U << 14) |
((arg & ARM_I2C_ADDRESS_10BIT) ? (1U << 15) : (0U));
break;
case ARM_I2C_BUS_SPEED:
pclk = RTE_PCLK1;
switch (arg) {
case ARM_I2C_BUS_SPEED_STANDARD:
/* Clock = 100kHz, Rise Time = 1000ns */
if (pclk > 42000000U) { return ARM_DRIVER_ERROR_UNSUPPORTED; }
if (pclk < 2000000U) { return ARM_DRIVER_ERROR_UNSUPPORTED; }
ccr = (pclk / 100000U) / 2U;
trise = (pclk / 1000000U) + 1U;
break;
case ARM_I2C_BUS_SPEED_FAST:
/* Clock = 400kHz, Rise Time = 300ns */
if (pclk > 42000000U) { return ARM_DRIVER_ERROR_UNSUPPORTED; }
if (pclk < 4000000U) { return ARM_DRIVER_ERROR_UNSUPPORTED; }
if ((pclk >= 10000000U) && ((pclk % 10000000U) == 0U)) {
ccr = I2C_CCR_FS | I2C_CCR_DUTY | ((pclk / 400000U) / 25U);
} else {
ccr = I2C_CCR_FS | ((pclk / 400000U) / 3U);
}
trise = (pclk / 333333U) + 1U;
break;
default:
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
i2c->reg->CR1 &= ~I2C_CR1_PE; /* Disable I2C peripheral */
i2c->reg->CR2 &= ~I2C_CR2_FREQ;
i2c->reg->CR2 |= pclk / 1000000U;
i2c->reg->CCR = ccr;
i2c->reg->TRISE = trise;
i2c->reg->CR1 |= I2C_CR1_PE; /* Enable I2C peripheral */
i2c->reg->CR1 |= I2C_CR1_ACK; /* Enable acknowledge */
break;
case ARM_I2C_BUS_CLEAR:
i2c->reg->CR1 &= ~I2C_CR1_PE;
SystemCoreClockUpdate();
/* Frequency is set to approx. standard speed (100kHz) */
pclk = SystemCoreClock / 100000 / 4;
GPIO_PinWrite (i2c->io.scl_port, i2c->io.scl_pin, 1);
GPIO_PinWrite (i2c->io.sda_port, i2c->io.sda_pin, 1);
/* Configure SCL Pin as GPIO */
GPIO_PinConfigure(i2c->io.scl_port, i2c->io.scl_pin, GPIO_OUT_OPENDRAIN,
GPIO_MODE_OUT50MHZ);
/* Configure SDA Pin as GPIO */
GPIO_PinConfigure(i2c->io.sda_port, i2c->io.sda_pin, GPIO_OUT_OPENDRAIN,
GPIO_MODE_OUT50MHZ);
for (i = 0U; i < 9U; i++) {
if (GPIO_PinRead (i2c->io.sda_port, i2c->io.sda_pin)) {
/* Break if slave released SDA line */
break;
}
/* Clock high */
GPIO_PinWrite (i2c->io.scl_port, i2c->io.scl_pin, 1);
for (j = 0; j < pclk; j++);
/* Clock low */
GPIO_PinWrite (i2c->io.scl_port, i2c->io.scl_pin, 0);
for (j = 0; j < pclk; j++);
}
/* Check SDA state */
state = GPIO_PinRead (i2c->io.sda_port, i2c->io.sda_pin);
/* Generate STOP condition - SDA goes high while SCL is high */
GPIO_PinWrite (i2c->io.sda_port, i2c->io.sda_pin, 0);
for (j = 0; j < pclk; j++);
GPIO_PinWrite (i2c->io.scl_port, i2c->io.scl_pin, 1);
for (j = 0; j < pclk; j++);
GPIO_PinWrite (i2c->io.sda_port, i2c->io.sda_pin, 1);
/* Configure SCL Pin as I2C peripheral pin */
GPIO_PinConfigure(i2c->io.scl_port, i2c->io.scl_pin, GPIO_AF_OPENDRAIN,
GPIO_MODE_OUT50MHZ);
/* Configure SDA Pin as I2C peripheral pin */
GPIO_PinConfigure(i2c->io.sda_port, i2c->io.sda_pin, GPIO_AF_OPENDRAIN,
GPIO_MODE_OUT50MHZ);
i2c->reg->CR1 |= I2C_CR1_PE;
/* Send event */
if (i2c->info->cb_event) {
i2c->info->cb_event (ARM_I2C_EVENT_BUS_CLEAR);
}
return (state) ? ARM_DRIVER_OK : ARM_DRIVER_ERROR;
case ARM_I2C_ABORT_TRANSFER:
/* Disable DMA requests and I2C interrupts */
i2c->reg->CR2 &= ~(I2C_CR2_DMAEN | I2C_CR2_ITBUFEN | I2C_CR2_ITEVTEN);
#if defined(USE_I2C1_DMA) || defined(USE_I2C2_DMA)
if ((i2c->dma_rx != NULL) && (i2c->dma_tx != NULL)) {
DMA_ChannelDisable(i2c->dma_rx->reg);
DMA_ChannelDisable(i2c->dma_tx->reg);
}
#endif
/* Generate stop */
/* Master generates stop after the current byte transfer */
/* Slave releases SCL and SDA after the current byte transfer */
i2c->reg->CR1 |= I2C_CR1_STOP;
i2c->info->xfer.num = 0U;
i2c->info->xfer.cnt = 0U;
i2c->info->xfer.data = NULL;
i2c->info->xfer.addr = 0U;
i2c->info->xfer.ctrl = 0U;
i2c->info->status.busy = 0U;
i2c->info->status.mode = 0U;
i2c->info->status.direction = 0U;
i2c->info->status.general_call = 0U;
i2c->info->status.arbitration_lost = 0U;
i2c->info->status.bus_error = 0U;
/* Disable and reenable peripheral to clear some flags */
i2c->reg->CR1 &= ~I2C_CR1_PE;
i2c->reg->CR1 |= I2C_CR1_PE;
/* Enable acknowledge */
i2c->reg->CR1 |= I2C_CR1_ACK;
break;
default: return ARM_DRIVER_ERROR;
}
return ARM_DRIVER_OK;
}
/**
\fn ARM_I2C_STATUS I2C_GetStatus (I2C_RESOURCES *i2c)
\brief Get I2C status.
\param[in] i2c pointer to I2C resources
\return I2C status \ref ARM_I2C_STATUS
*/
static ARM_I2C_STATUS I2C_GetStatus (I2C_RESOURCES *i2c) {
return (i2c->info->status);
}
/**
\fn void I2C_EV_IRQHandler (I2C_RESOURCES *i2c)
\brief I2C Event Interrupt handler.
\param[in] i2c Pointer to I2C resources
*/
static void I2C_EV_IRQHandler (I2C_RESOURCES *i2c) {
I2C_TRANSFER_INFO *tr = &i2c->info->xfer;
uint8_t data;
uint16_t sr1, sr2;
uint32_t event;
sr1 = (uint16_t)i2c->reg->SR1;
if (sr1 & I2C_SR1_SB) {
/* (EV5): start bit generated, send address */
if (tr->addr & ARM_I2C_ADDRESS_10BIT) {
/* 10-bit addressing mode */
data = (uint8_t)(0xF0U | ((tr->addr >> 7) & 0x06U));
}
else {
/* 7-bit addressing mode */
data = (uint8_t)tr->addr << 1;
data |= (uint8_t)i2c->info->status.direction;
}
i2c->reg->DR = data;
}
else if (sr1 & I2C_SR1_ADD10) {
/* (EV9): 10-bit address header sent, send device address LSB */
i2c->reg->DR = (uint8_t)tr->addr;
if (i2c->info->status.direction) {
/* Master receiver generates repeated start in 10-bit addressing mode */
tr->ctrl |= XFER_CTRL_RSTART;
}
}
else if (sr1 & I2C_SR1_ADDR) {
/* (EV6): addressing complete */
if (tr->ctrl & XFER_CTRL_ADDR_DONE) {
/* Restart condition, end previous transfer */
i2c->info->status.busy = 0U;
event = ARM_I2C_EVENT_TRANSFER_DONE;
if (tr->cnt < tr->num) {
event |= ARM_I2C_EVENT_TRANSFER_INCOMPLETE;
}
if (i2c->info->status.general_call) {
event |= ARM_I2C_EVENT_GENERAL_CALL;
}
if (i2c->info->cb_event != NULL) {
i2c->info->cb_event (event);
}
}
if ((i2c->info->status.mode != 0U) && (i2c->info->status.direction != 0U)) {
/* Master mode, receiver */
if (tr->num == 1U) {
i2c->reg->CR1 &= ~I2C_CR1_ACK;
}
/* Clear ADDR flag */
i2c->reg->SR1;
i2c->reg->SR2;
if (tr->ctrl & XFER_CTRL_RSTART) {
tr->ctrl &= ~XFER_CTRL_RSTART;
/* Generate repeated start */
i2c->reg->CR1 |= I2C_CR1_START;
}
else {
if (tr->num == 1U) {
if ((tr->ctrl & XFER_CTRL_XPENDING) == 0U) {
i2c->reg->CR1 |= I2C_CR1_STOP;
}
}
else if (tr->num == 2U) {
i2c->reg->CR1 &= ~I2C_CR1_ACK;
i2c->reg->CR1 |= I2C_CR1_POS;
/* Wait until BTF == 1 */
tr->ctrl |= XFER_CTRL_WAIT_BTF;
}
else {
if (tr->num == 3U) {
/* Wait until BTF == 1 */
tr->ctrl |= XFER_CTRL_WAIT_BTF;
}
}
}
}
else {
/* Master transmitter or slave mode */
sr2 = (uint16_t)i2c->reg->SR2;
if (i2c->info->status.mode == 0U) {
/* Slave mode */
if (sr2 & I2C_SR2_GENCALL) {
i2c->info->status.general_call = 1U;
} else {
i2c->info->status.general_call = 0U;
}
if (sr2 & I2C_SR2_TRA) {
i2c->info->status.direction = 0U;
} else {
i2c->info->status.direction = 1U;
}
event = 0U;
if (tr->data == NULL) {
if (i2c->info->status.direction) {
event |= ARM_I2C_EVENT_SLAVE_RECEIVE;
}
else {
event |= ARM_I2C_EVENT_SLAVE_TRANSMIT;
}
}
if (i2c->info->status.general_call) {
event |= ARM_I2C_EVENT_GENERAL_CALL;
}
if ((event != 0U) && (i2c->info->cb_event != NULL)) {
i2c->info->cb_event (event);
}
i2c->info->status.busy = 1U;
}
}
tr->ctrl |= XFER_CTRL_ADDR_DONE | XFER_CTRL_XACTIVE;
if ((i2c->dma_rx != NULL) && (i2c->dma_tx != NULL)) {
/* Enable DMA data transfer */
i2c->reg->CR2 |= I2C_CR2_DMAEN;
}
else {
/* Enable IRQ data transfer */
i2c->reg->CR2 |= I2C_CR2_ITBUFEN;
}
}
else if (sr1 & I2C_SR1_STOPF) {
/* STOP condition detected */
tr->data = NULL;
tr->ctrl = 0U;
/* Reenable ACK */
i2c->reg->CR1 |= I2C_CR1_ACK;
i2c->info->status.busy = 0U;
event = ARM_I2C_EVENT_TRANSFER_DONE;
if (tr->cnt < tr->num) {
event |= ARM_I2C_EVENT_TRANSFER_INCOMPLETE;
}
if (i2c->info->status.general_call) {
event |= ARM_I2C_EVENT_GENERAL_CALL;
}
if (i2c->info->cb_event) {
i2c->info->cb_event (event);
}
}
else if (tr->ctrl & XFER_CTRL_XACTIVE) {
/* BTF, RxNE or TxE interrupt */
if (tr->ctrl & XFER_CTRL_DMA_DONE) {
/* BTF triggered this event */
if (i2c->info->status.mode) {
if (i2c->info->xfer.ctrl & XFER_CTRL_XPENDING) {
/* Disable event interrupt */
i2c->reg->CR2 &= ~I2C_CR2_ITEVTEN;
}
else {
/* Generate stop condition */
i2c->reg->CR1 |= I2C_CR1_STOP;
}
tr->data = NULL;
tr->ctrl &= ~XFER_CTRL_XACTIVE;
i2c->info->status.busy = 0U;
i2c->info->status.mode = 0U;
if (i2c->info->cb_event) {
i2c->info->cb_event (ARM_I2C_EVENT_TRANSFER_DONE);
}
}
}
else if (sr1 & I2C_SR1_TXE) {
if (i2c->info->status.mode) {
/* Master transmitter */
if (tr->ctrl & XFER_CTRL_WAIT_BTF) {
if (sr1 & I2C_SR1_BTF) {
/* End master transmit operation */
i2c->reg->CR2 &= ~I2C_CR2_ITBUFEN;
if (tr->ctrl & XFER_CTRL_XPENDING) {
i2c->reg->CR2 &= ~I2C_CR2_ITEVTEN;
}
else {
i2c->reg->CR1 |= I2C_CR1_STOP;
}
tr->data = NULL;
tr->ctrl &= ~XFER_CTRL_XACTIVE;
i2c->info->status.busy = 0U;
i2c->info->status.mode = 0U;
if (i2c->info->cb_event) {
i2c->info->cb_event (ARM_I2C_EVENT_TRANSFER_DONE);
}
}
}
else {
i2c->reg->DR = tr->data[tr->cnt];
tr->cnt++;
if (tr->cnt == tr->num) {
tr->ctrl |= XFER_CTRL_WAIT_BTF;
}
}
}
else {
/* Slave transmitter */
if (tr->data == NULL) {
if (i2c->info->cb_event) {
i2c->info->cb_event (ARM_I2C_EVENT_SLAVE_TRANSMIT);
}
}
if (tr->data) {
i2c->reg->DR = tr->data[tr->cnt];
tr->cnt++;
if (tr->cnt == tr->num) {
tr->data = NULL;
}
}
else {
/* Master requests more data as we have */
i2c->reg->DR = (uint8_t)0xFF;
}
}
}
else if (sr1 & I2C_SR1_RXNE) {
if (i2c->info->status.mode) {
/* Master receiver */
if (tr->ctrl & XFER_CTRL_WAIT_BTF) {
if (sr1 & I2C_SR1_BTF) {
if ((tr->num == 2U) || (tr->cnt == (tr->num - 2U))) {
/* Two bytes remaining */
i2c->reg->CR2 &= ~I2C_CR2_ITBUFEN;
if (tr->ctrl & XFER_CTRL_XPENDING) {
i2c->reg->CR2 &= ~I2C_CR2_ITEVTEN;
}
else {
i2c->reg->CR1 |= I2C_CR1_STOP;
}
/* Read data N-1 and N */
tr->data[tr->cnt++] = (uint8_t)i2c->reg->DR;
tr->data[tr->cnt++] = (uint8_t)i2c->reg->DR;
tr->data = NULL;
tr->ctrl &= ~XFER_CTRL_XACTIVE;
i2c->info->status.busy = 0U;
i2c->info->status.mode = 0U;
i2c->reg->CR1 &= ~I2C_CR1_POS;
if (i2c->info->cb_event) {
i2c->info->cb_event (ARM_I2C_EVENT_TRANSFER_DONE);
}
}
else {
/* Three bytes remaining */
i2c->reg->CR1 &= ~I2C_CR1_ACK;
/* Read data N-2 */
tr->data[tr->cnt++] = (uint8_t)i2c->reg->DR;
}
}
}
else {
tr->data[tr->cnt++] = (uint8_t)i2c->reg->DR;
if (tr->num == 1U) {
/* Single byte transfer completed */
i2c->reg->CR2 &= ~I2C_CR2_ITBUFEN;
if (tr->ctrl & XFER_CTRL_XPENDING) {
i2c->reg->CR2 &= ~I2C_CR2_ITEVTEN;
}
/* (STOP was already sent during ADDR phase) */
tr->data = NULL;
tr->ctrl &= ~XFER_CTRL_XACTIVE;
i2c->info->status.busy = 0U;
i2c->info->status.mode = 0U;
if (i2c->info->cb_event) {
i2c->info->cb_event (ARM_I2C_EVENT_TRANSFER_DONE);
}
}
else {
if (tr->cnt == (tr->num - 3U)) {
/* N > 2 byte reception, begin N-2 data reception */
i2c->reg->CR2 &= ~I2C_CR2_ITBUFEN;
/* Wait until BTF == 1 */
tr->ctrl |= XFER_CTRL_WAIT_BTF;
}
}
}
}
else {
/* Slave receiver */
data = (uint8_t)i2c->reg->DR;
if (tr->data == NULL) {
/* Receive buffer full: Disable ACK */
i2c->reg->CR1 &= ~I2C_CR1_ACK;
}
else {
if (tr->cnt < tr->num) {
tr->data[tr->cnt] = data;
tr->cnt++;
if (tr->cnt == tr->num) {
tr->data = NULL;
}
}
}
}
}
}
}
/**
\fn void I2C_ER_IRQHandler (I2C_RESOURCES *i2c)
\brief I2C Error Interrupt handler.
\param[in] i2c Pointer to I2C resources
*/
static void I2C_ER_IRQHandler (I2C_RESOURCES *i2c) {
uint32_t sr1 = i2c->reg->SR1;
uint32_t evt = 0U;
uint32_t err = 0U;
if (sr1 & I2C_SR1_SMBALERT) {
/* SMBus alert */
err |= I2C_SR1_SMBALERT;
}
if (sr1 & I2C_SR1_TIMEOUT) {
/* Timeout - SCL remained LOW for 25ms */
err |= I2C_SR1_TIMEOUT;
}
if (sr1 & I2C_SR1_PECERR) {
/* PEC Error in reception */
err |= I2C_SR1_PECERR;
}
if (sr1 & I2C_SR1_OVR) {
/* Overrun/Underrun */
err |= I2C_SR1_OVR;
}
if (sr1 & I2C_SR1_AF) {
/* Acknowledge failure */
err |= I2C_SR1_AF;
/* Reset the communication */
i2c->reg->CR1 |= I2C_CR1_STOP;
i2c->info->status.busy = 0U;
i2c->info->status.mode = 0U;
i2c->info->xfer.data = NULL;
i2c->info->xfer.ctrl = 0U;
evt = ARM_I2C_EVENT_TRANSFER_DONE;
if ((i2c->info->xfer.ctrl & XFER_CTRL_ADDR_DONE) == 0U) {
/* Addressing not done */
evt |= ARM_I2C_EVENT_ADDRESS_NACK;
}
}
if (sr1 & I2C_SR1_ARLO) {
/* Arbitration lost */
err |= I2C_SR1_ARLO;
/* Switch to slave mode */
i2c->info->status.busy = 0U;
i2c->info->status.mode = 0U;
i2c->info->status.arbitration_lost = 1U;
i2c->info->xfer.data = NULL;
i2c->info->xfer.ctrl = 0U;
evt = ARM_I2C_EVENT_TRANSFER_DONE | ARM_I2C_EVENT_ARBITRATION_LOST;
}
if (sr1 & I2C_SR1_BERR) {
/* Bus error - misplaced start/stop */
err |= I2C_SR1_BERR;
i2c->info->status.bus_error = 1U;
if (i2c->info->status.mode == 0U) {
/* Lines are released in slave mode */
i2c->info->status.busy = 0U;
i2c->info->xfer.data = NULL;
i2c->info->xfer.ctrl = 0U;
}
evt = ARM_I2C_EVENT_TRANSFER_DONE | ARM_I2C_EVENT_BUS_ERROR;
}
/* Abort DMA channels */
#if defined(USE_I2C1_DMA) || defined(USE_I2C2_DMA)
if ((i2c->dma_rx != NULL) && (i2c->dma_tx != NULL)) {
DMA_ChannelDisable(i2c->dma_tx->reg);
DMA_ChannelDisable(i2c->dma_rx->reg);
}
#endif
/* Clear error flags */
i2c->reg->SR1 &= ~err;
if ((evt != 0) && (i2c->info->cb_event != NULL)) {
if (i2c->info->xfer.cnt < i2c->info->xfer.num) {
evt |= ARM_I2C_EVENT_TRANSFER_INCOMPLETE;
}
i2c->info->cb_event (evt);
}
}
#if defined(USE_I2C1_DMA) || defined(USE_I2C2_DMA)
/**
\fn void I2C_DMA_TxEvent (uint32_t event, I2C_RESOURCES *i2c)
\brief I2C DMA Transmit Event handler
\param[in] i2c Pointer to I2C resources
*/
static void I2C_DMA_TxEvent (uint32_t event, I2C_RESOURCES *i2c) {
i2c->reg->CR2 &= ~I2C_CR2_DMAEN;
DMA_ChannelDisable(i2c->dma_tx->reg);
i2c->info->xfer.cnt = i2c->info->xfer.num - DMA_ChannelTransferItemCount(i2c->dma_tx->reg);
i2c->info->xfer.data = NULL;
if (i2c->info->status.mode) {
/* Master transmitter: Wait for BTF in I2C EV IRQ handler */
i2c->info->xfer.ctrl |= XFER_CTRL_DMA_DONE;
}
}
/**
\fn void I2C_DMA_RxEvent (uint32_t event, I2C_RESOURCES *i2c)
\brief I2C DMA Receive Event handler
\param[in] i2c Pointer to I2C resources
*/
static void I2C_DMA_RxEvent (uint32_t event, I2C_RESOURCES *i2c) {
i2c->reg->CR2 &= ~I2C_CR2_DMAEN;
DMA_ChannelDisable(i2c->dma_rx->reg);
i2c->info->xfer.cnt = i2c->info->xfer.num - DMA_ChannelTransferItemCount(i2c->dma_rx->reg);
i2c->info->xfer.data = NULL;
if (i2c->info->status.mode) {
/* Master mode */
if (i2c->info->xfer.ctrl & XFER_CTRL_XPENDING) {
/* Transfer pending */
i2c->reg->CR2 &= ~I2C_CR2_ITEVTEN;
}
else {
if (i2c->info->xfer.num != 1U) {
i2c->reg->CR1 |= I2C_CR1_STOP;
}
}
i2c->info->status.busy = 0U;
i2c->info->status.mode = 0U;
if (i2c->info->cb_event) {
i2c->info->cb_event (ARM_I2C_EVENT_TRANSFER_DONE);
}
}
}
#endif
#if defined(USE_I2C1)
/* I2C1 Driver wrapper functions */
static int32_t I2C1_Initialize (ARM_I2C_SignalEvent_t cb_event) {
return I2C_Initialize(cb_event, &I2C1_Resources);
}
static int32_t I2C1_Uninitialize (void) {
return I2C_Uninitialize(&I2C1_Resources);
}
static int32_t I2C1_PowerControl (ARM_POWER_STATE state) {
return I2C_PowerControl(state, &I2C1_Resources);
}
static int32_t I2C1_MasterTransmit (uint32_t addr, const uint8_t *data, uint32_t num, bool xfer_pending) {
return I2C_MasterTransmit(addr, data, num, xfer_pending, &I2C1_Resources);
}
static int32_t I2C1_MasterReceive (uint32_t addr, uint8_t *data, uint32_t num, bool xfer_pending) {
return I2C_MasterReceive(addr, data, num, xfer_pending, &I2C1_Resources);
}
static int32_t I2C1_SlaveTransmit (const uint8_t *data, uint32_t num) {
return I2C_SlaveTransmit(data, num, &I2C1_Resources);
}
static int32_t I2C1_SlaveReceive (uint8_t *data, uint32_t num) {
return I2C_SlaveReceive(data, num, &I2C1_Resources);
}
static int32_t I2C1_GetDataCount (void) {
return I2C_GetDataCount(&I2C1_Resources);
}
static int32_t I2C1_Control (uint32_t control, uint32_t arg) {
return I2C_Control(control, arg, &I2C1_Resources);
}
static ARM_I2C_STATUS I2C1_GetStatus (void) {
return I2C_GetStatus(&I2C1_Resources);
}
void I2C1_EV_IRQHandler (void) {
I2C_EV_IRQHandler(&I2C1_Resources);
}
void I2C1_ER_IRQHandler (void) {
I2C_ER_IRQHandler(&I2C1_Resources);
}
#if defined(USE_I2C1_DMA)
void I2C1_RX_DMA_Handler (uint32_t event) {
I2C_DMA_RxEvent (event, &I2C1_Resources);
}
void I2C1_TX_DMA_Handler (uint32_t event) {
I2C_DMA_TxEvent (event, &I2C1_Resources);
}
#endif
/* I2C1 Driver Control Block */
ARM_DRIVER_I2C Driver_I2C1 = {
I2CX_GetVersion,
I2CX_GetCapabilities,
I2C1_Initialize,
I2C1_Uninitialize,
I2C1_PowerControl,
I2C1_MasterTransmit,
I2C1_MasterReceive,
I2C1_SlaveTransmit,
I2C1_SlaveReceive,
I2C1_GetDataCount,
I2C1_Control,
I2C1_GetStatus
};
#endif
#if defined(USE_I2C2)
/* I2C2 Driver wrapper functions */
static int32_t I2C2_Initialize (ARM_I2C_SignalEvent_t cb_event) {
return I2C_Initialize(cb_event, &I2C2_Resources);
}
static int32_t I2C2_Uninitialize (void) {
return I2C_Uninitialize(&I2C2_Resources);
}
static int32_t I2C2_PowerControl (ARM_POWER_STATE state) {
return I2C_PowerControl(state, &I2C2_Resources);
}
static int32_t I2C2_MasterTransmit (uint32_t addr, const uint8_t *data, uint32_t num, bool xfer_pending) {
return I2C_MasterTransmit(addr, data, num, xfer_pending, &I2C2_Resources);
}
static int32_t I2C2_MasterReceive (uint32_t addr, uint8_t *data, uint32_t num, bool xfer_pending) {
return I2C_MasterReceive(addr, data, num, xfer_pending, &I2C2_Resources);
}
static int32_t I2C2_SlaveTransmit (const uint8_t *data, uint32_t num) {
return I2C_SlaveTransmit(data, num, &I2C2_Resources);
}
static int32_t I2C2_SlaveReceive (uint8_t *data, uint32_t num) {
return I2C_SlaveReceive(data, num, &I2C2_Resources);
}
static int32_t I2C2_GetDataCount (void) {
return I2C_GetDataCount(&I2C2_Resources);
}
static int32_t I2C2_Control (uint32_t control, uint32_t arg) {
return I2C_Control(control, arg, &I2C2_Resources);
}
static ARM_I2C_STATUS I2C2_GetStatus (void) {
return I2C_GetStatus(&I2C2_Resources);
}
void I2C2_EV_IRQHandler (void) {
I2C_EV_IRQHandler(&I2C2_Resources);
}
void I2C2_ER_IRQHandler (void) {
I2C_ER_IRQHandler(&I2C2_Resources);
}
#if defined(USE_I2C2_DMA)
void I2C2_RX_DMA_Handler (uint32_t event) {
I2C_DMA_RxEvent (event, &I2C2_Resources);
}
void I2C2_TX_DMA_Handler (uint32_t event) {
I2C_DMA_TxEvent (event, &I2C2_Resources);
}
#endif
/* I2C2 Driver Control Block */
ARM_DRIVER_I2C Driver_I2C2 = {
I2CX_GetVersion,
I2CX_GetCapabilities,
I2C2_Initialize,
I2C2_Uninitialize,
I2C2_PowerControl,
I2C2_MasterTransmit,
I2C2_MasterReceive,
I2C2_SlaveTransmit,
I2C2_SlaveReceive,
I2C2_GetDataCount,
I2C2_Control,
I2C2_GetStatus
};
#endif