diff --git a/libraries/STM32F0xx_CPAL_Driver/inc/stm32f0xx_i2c_cpal.h b/libraries/STM32F0xx_CPAL_Driver/inc/stm32f0xx_i2c_cpal.h new file mode 100644 --- /dev/null +++ b/libraries/STM32F0xx_CPAL_Driver/inc/stm32f0xx_i2c_cpal.h @@ -0,0 +1,552 @@ +/** + ****************************************************************************** + * @file stm32f0xx_i2c_cpal.h + * @author MCD Application Team + * @version V1.2.0 + * @date 24-July-2014 + * @brief This file contains all the functions prototypes for the I2C firmware + * layer. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2014 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +/*========= CPAL library files includes =========*/ +#include "stm32f0xx_i2c_cpal_hal.h" +#include "stm32f0xx_i2c_cpal_conf.h" + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0XX_I2C_CPAL_H +#define __STM32F0XX_I2C_CPAL_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/*========= CPAL_Dev_TypeDef =========*/ +/* CPAL devices enumeration contains the device instances */ + +typedef enum +{ + CPAL_I2C1 = 0x00, /*!< Use I2C1 device */ + + CPAL_I2C2 = 0x01 /*!< Use I2C2 device */ + +}CPAL_DevTypeDef; + + +/*========= CPAL_Direction_TypeDef =========*/ +/* CPAL transfer directions enumeration is used to configure DMA channels + (TX and RX) if CPAL_PROGMODEL_DMA is selected or TX/RX interrupts + if CPAL_PROGMODEL_INTERRUPT is selected: + - If CPAL_DIRECTION_TX is selected only TX DMA Channel or TX Interrupt is configured + - If CPAL_DIRECTION_RX is selected only RX DMA Channel or RX Interrupt is configured + - If CPAL_DIRECTION_TXRX is selected both TX and Rx DMA Channels or Interrupts are configured.*/ + +typedef enum +{ + CPAL_DIRECTION_TX = 0x01, /*!pI2C_Struct->I2C_Speed = 100000; + CPAL_I2C_Init(&I2C1_DevStructure); */ +}CPAL_InitTypeDef; + + +/*========= Table containing all I2C device structures =========*/ +extern CPAL_InitTypeDef* I2C_DevStructures[]; + + +/*========= CPAL_Global_Device_Structures =========*/ +/* CPAL Global Device Structures are the Global default structures which + are used to handle devices configuration and status.*/ + +#ifdef CPAL_USE_I2C1 +extern CPAL_InitTypeDef I2C1_DevStructure; +#endif /* CPAL_USE_I2C1 */ + +#ifdef CPAL_USE_I2C2 +extern CPAL_InitTypeDef I2C2_DevStructure; +#endif /* CPAL_USE_I2C2 */ + +/* Exported constants --------------------------------------------------------*/ + +/*========= CPAL_Options_TypeDef =========*/ +/* CPAL Options defines contains configuration options which can be affected + to wCPAL_Options which is a bit-field argument so any combination of these + parameters can be selected. If one option is not selected then the relative + feature is disabled. + There are common options and device specific options.*/ + +#define CPAL_OPT_I2C_DUALADDR ((uint32_t)0x00000001) /*!
© COPYRIGHT 2014 STMicroelectronics
+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0XX_I2C_CPAL_CONF_H +#define __STM32F0XX_I2C_CPAL_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/*======================================================================================================================================= + User NOTES +========================================================================================================================================= + +------------------------------- +1. How To use the CPAL Library: +------------------------------- + +------- Refer to the user manual of the library and (eventually) the example to check if + this firmware is appropriate for your hardware (device and (eventually) evaluation board) + + - Section 1 : Select the Device instances to be used and the total number of devices + + - Section 2 : Configure Transfer Options + + - Section 3 : Select and configure transfer and error user Callbacks + + - Section 4 : Configure Timeout mechanism and TimeoutCallback + + - Section 5 : Configure Interrupt Priority Offset + + - Section 6 : Configure CPAL_LOG Macro + +------ After configuring CPAL firmware functionality , You should proceed by configuring hardware used with CPAL + (please refer to stm32f0xx_i2c_cpal_hal.h file). + +------ After configuring CPAL Firmware Library, you should follow these steps to use the Firmware correctly : + + -1- STRUCTURE INITIALIZATION + Start by initializing the Device. To perform this action, the global variable PPPx_DevStructure declared + in CPAL Firmware as CPAL_InitTypeDef (I2C1_DevStructure for I2C1, I2C2_DevStructure for I2C2 ...) must be used. + There are two ways to proceed : + + ** Call the function CPAL_PPP_StructInit() using as parameter PPPx_DevStructure (where PPP = device type (ie. I2C...) + and where x could be 1 for PPP1, 2 for PPP2 ...). This function sets the default values for all fields of this structure. + + Default values for I2C devices are : + I2Cx_DevStructure.CPAL_Direction = CPAL_DIRECTION_TXRX + I2Cx_DevStructure.CPAL_Mode = CPAL_MODE_MASTER + I2Cx_DevStructure.CPAL_ProgModel = CPAL_PROGMODEL_DMA + I2Cx_DevStructure.pCPAL_TransferTx = pNULL + I2Cx_DevStructure.pCPAL_TransferRx = pNULL + I2Cx_DevStructure.CPAL_State = CPAL_STATE_DISABLED + I2Cx_DevStructure.wCPAL_DevError = CPAL_I2C_ERR_NONE + I2Cx_DevStructure.wCPAL_Options = 0 (all options disabled) + I2Cx_DevStructure.wCPAL_Timeout = CPAL_TIMEOUT_DEFAULT + I2Cx_DevStructure.pCPAL_I2C_Struct->I2C_Mode = I2C_Mode_I2C + I2Cx_DevStructure.pCPAL_I2C_Struct->I2C_AnalogFilter = I2C_AnalogFilter_Enable + I2Cx_DevStructure.pCPAL_I2C_Struct->I2C_DigitalFilter = 0x00 + I2Cx_DevStructure.pCPAL_I2C_Struct->I2C_OwnAddress1 = 0 + I2Cx_DevStructure.pCPAL_I2C_Struct->I2C_Ack = I2C_Ack_Enable + I2Cx_DevStructure.pCPAL_I2C_Struct->I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit + + + pCPAL_TransferTx and pCPAL_TransferRx fields have to be updated in order to point to valid structures + (these structures should be local/global variables in the user application). + + ** Another way of configuration is without calling CPAL_PPP_StructInit() function. + Declare the following structures: + - A PPP_InitTypeDef structure for the device configuration (ie. I2C_InitTypeDef structure) + - One or two CPAL_TransferTypeDef variables (one for Tx and one for Rx). + - Use the extern structure provided by the CPAL library: PPPx_InitStructure (ie. I2C1_DevStructure). + Fill in all the fields for these structures (one by one). + Use the pointers to these structures to fill in the fields pCPAL_PPP_Struct and pCPAL_TransferTx and/or + pCPAL_TransferRx of the PPPx_DevStructure. + After that CPAL_State must be set to CPAL_STATE_DISABLED. + Finally, call the CPAL_PPP_Init() with pointer to the PPPx_DevStructure as argument. + + Example: + // Declare local structures + I2C_InitTypeDef I2C1_InitStructure; + CPAL_TransferTypeDef TX_Transfer, RX_Transfer; + // Fill in all the fields of to these structures + I2Cx_InitStructure.I2C_Timing = 0X50321312; + I2Cx_InitStructure.I2C_Mode = I2C_Mode_I2C; + I2Cx_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Disable; + ..... + TX_Transfer.pbBuffer = 0; + TX_Transfer.wNumData = 0; + ..... + RX_Transfer.pbBuffer = 0; + RX_Transfer.wNumData = 0; + ..... + // Use these structures and fill all fields of I2C1_DevStructure. + I2C1_DevStructure.CPAL_Dev = CPAL_I2C1; + I2C1_DevStructure.CPAL_Direction = CPAL_DIRECTION_TXRX; + I2C1_DevStructure.CPAL_Mode = CPAL_MODE_SLAVE; + I2C1_DevStructure.wCPAL_Options = CPAL_OPT_DMATX_TCIT | CPAL_OPT_DMATX_HTIT ; + ..... + I2C1_DevStructure.pCPAL_TransferTx = &TX_Transfer; + I2C1_DevStructure.pCPAL_TransferRx = &RX_Transfer; + I2C1_DevStructure.pCPAL_I2C_Struct = &I2C1_InitStructure; + ... + I2C1_DevStructure.wCPAL_State = CPAL_STATE_DISABLED; + .... + CPAL_I2C_Init(&I2C1_DevStructure); + + -2- DEVICE CONFIGURATION + Call the function CPAL_PPP_Init() to configure the selected device with the selected configuration by calling + CPAL_PPP_Init(). This function also enables device clock and initialize all related peripherals ( GPIO, DMA , IT and NVIC ). + This function tests on CPAL_State, if it is equal to CPAL_STATE_BUSY it exit, otherwise device initialization is + performed and CPAL_State is set to CPAL_STATE_READY. + This function returns CPAL_PASS state when the operation is correctly performed, or CPAL_FAIL when the current state of the + device doesn't allow configuration (ie. state different from READY, DISABLED or ERROR). + After calling this function, you may check on the new state of device, when it is equal to CPAL_STATE_READY, Transfer operations + can be started, otherwise you can call CPAL_PPP_DeInit() to deinitialize device and call CPAL_PPP_Init() once again. + + -3- READ / WRITE OPERATIONS + Call the function CPAL_PPP_Write() or CPAL_PPP_Read() to perform transfer operations. + These functions handle communication events using device event interrupts (independently of programming model used: DMA, + Interrupt). These functions start preparing communication (send start condition, send salve address in case of + master mode ...) if connection is established between devices CPAL_State is set CPAL_STATE_BUSY_XX and data transfer starts. + By default, Error interrupts are enabled to manage device errors (Error interrupts can be disabled by affecting + CPAL_OPT_I2C_ERRIT_DISABLE to wCPAL_Options). When transfer is completed successfully, CPAL_State is set to CPAL_STATE_READY + and another operation can be started. + These functions return CPAL_PASS if the current state of the device allows starting a new operation and the operation is correctly + started (but not finished). It returns CPAL_FAIL when the state of the device doesn't allow starting a new communication (ie. + BUSY, DISABLED, ERROR) or when an error occurs during operation start. + Once operation is started, user application may perform other tasks while CPAL is sending/receiving data on device through interrupt + or DMA. + + -4- DEVICE DEINITIALIZATION + When transfer operations are finished, you may call CPAL_PPP_DeInit() to disable PPPx device and related resources + ( GPIO, DMA , IT and NVIC). CPAL_State is then set to CPAL_STATE_DISABLED by this function. + + + +------ Callbacks are routines that let you insert your own code in different stages of communication and for handling + device errors. Their prototypes are declared by the CPAL library (if the relative define in this stm32f0xx_i2c_cpal_conf.h is enabled) + but their body is not implemented by CPAL library. It may be done by user when needed. + There are three types of Callbacks: Transfer User Callbacks, Error User Callbacks and Timeout User Callbacks: + + -a- Transfer User Callbacks : + + ** CPAL_I2C_TX_UserCallback(CPAL_InitTypeDef* pDevInitStruct) + This function is called before sending data when Interrupt Programming Model is selected. + + ** CPAL_I2C_RX_UserCallback(CPAL_InitTypeDef* pDevInitStruct) + This function is called after receiving data when Interrupt Programming Model is selected. + + ** CPAL_I2C_TXTC_UserCallback(CPAL_InitTypeDef* pDevInitStruct) + ** CPAL_I2C_RXTC_UserCallback(CPAL_InitTypeDef* pDevInitStruct) + These functions are called when a transfer is complete when using Interrupt programming model or DMA + programming model. + + ** CPAL_I2C_DMATXTC_UserCallback(CPAL_InitTypeDef* pDevInitStruct) + ** CPAL_I2C_DMATXTC_UserCallback(CPAL_InitTypeDef* pDevInitStruct) + These functions are called when Transfer complete Interrupt occurred in transmission/reception operation + if DMA Programming Model is selected + + ** CPAL_I2C_DMATXHT_UserCallback(CPAL_InitTypeDef* pDevInitStruct) + ** CPAL_I2C_DMARXHT_UserCallback(CPAL_InitTypeDef* pDevInitStruct) + These functions are called when Half transfer Interrupt occurred in transmission/reception operation + if DMA Programming Model is selected. + + ** CPAL_I2C_DMATXTE_UserCallback(CPAL_InitTypeDef* pDevInitStruct) + ** CPAL_I2C_DMARXTE_UserCallback(CPAL_InitTypeDef* pDevInitStruct) + These functions are called when a transfer error Interrupt occurred in transmission/reception operation + if DMA Programming Model is selected. + + ** CPAL_I2C_GENCALL_UserCallback(CPAL_InitTypeDef* pDevInitStruct) + This function is called when an Address Event interrupt occurred and General Call Address Flag is set + (available in Slave mode only and when the option CPAL_OPT_I2C_GENCALL is enabled). + + ** CPAL_I2C_DUALF_UserCallback(CPAL_InitTypeDef* pDevInitStruct) + This function is called when an Address Event interrupt occurred and Dual Address Flag is set + (available in Slave mode only and when the option CPAL_OPT_I2C_DUALADDR is enabled). + + + -b- Error User Callbacks : + + ** CPAL_I2C_ERR_UserCallback(CPAL_DevTypeDef pDevInstance, uint32_t Device_Error) + This function is called either when an Error Interrupt occurred (If Error Interrupts enabled) or after + a read or write operations to handle device errors (If Error Interrupts disabled). This callback + can be used to handle all device errors. It is available only when the define USE_SINGLE_ERROR_CALLBACK + is enabled (Section 5). + + ** CPAL_I2C_BERR_UserCallback(CPAL_DevTypeDef pDevInstance) + This function is called either when a Bus Error Interrupt occurred (If Error Interrupts enabled) or + after a read or write operations to handle this error (If Error Interrupts disabled). This callback is + available only when USE_MULTIPLE_ERROR_CALLBACK is enabled (Section 5). + + ** CPAL_I2C_ARLO_UserCallback(CPAL_DevTypeDef pDevInstance) + This function is called either when an Arbitration Lost Interrupt occurred (If Error Interrupts + enabled) or after a read or write operations to handle this error (If Error Interrupts disabled). + + ** CPAL_I2C_OVR_UserCallback(CPAL_DevTypeDef pDevInstance) + This function is called either when an Overrun Interrupt occurred (If Error Interrupts enabled) or + after a read or write operations to handle this error (If Error Interrupts disabled). This callback is + available only when USE_MULTIPLE_ERROR_CALLBACK is enabled (Section 5). + + ** CPAL_I2C_AF_UserCallback(CPAL_DevTypeDef pDevInstance) + This function is called either when an Acknowledge Failure Interrupt occurred (If Error Interrupts + enabled) or after a read or write operations to handle this error (If Error Interrupts disabled). + This callback is available only when USE_MULTIPLE_ERROR_CALLBACK is enabled (Section 5). + + + -c- Timeout User Callbacks : + ** CPAL_TIMEOUT_UserCallback(void) + This function is called when a Timeout occurred in communication. + + ** CPAL_TIMEOUT_INIT() + This function allows to configure and enable the counting peripheral/function (ie. SysTick Timer) + It is called into all CPAL_PPP_Init() functions. + + ** CPAL_TIMEOUT_DEINIT() + This function allow to free the resources of counting peripheral/function and stop the count. + (ie. disable the SysTick timer and its interrupt). + + ** CPAL_PPP_TIMEOUT_Manager() + WARNING: DO NOT IMPLEMENT THIS FUNCTION (already implemented in CPAL drivers) + This function is already implemented in the CPAL drivers (stm32f0xx_i2c_cpal.c file). It should be called periodically + (using the count mechanism interrupt for example). This function checks all PPP devices and + manages timeout conditions. In case of timeout occurring, this function calls the + CPAL_TIMEOUT_UserCallback() function that may be implemented by user to manage the cases of + timeout errors (ie. reset the device/microcontroller...). + In order to facilitate implementation, this function (instead to be called periodically by user + application), may be mapped directly to a periodic event/interrupt: + Example: + #define CPAL_I2C_TIMEOUT_Manager SysTick_Handler + + ** Note ** : when mapping CPAL_I2C_TIMEOUT_Manager to a periodic event/interrupt, the prototype + of this event/interrupt should be added. Here below an example when SysTick_Handler + is used to handle timeout mechanism : + #ifndef CPAL_I2C_TIMEOUT_Manager + void CPAL_I2C_TIMEOUT_Manager(void); + #else + void SysTick_Handler(void); + #endif + + To implement Transfer and Error Callbacks, you should comment relative defines in Section 4 and implement Callback function (body) into + your application (their prototypes are declared in stm32f0xx_i2c_cpal.h file). + + Example: How to implement CPAL_I2C_TX_UserCallback() callback: + + -1- Comment the relative define in this file : + //#define CPAL_I2C_TX_UserCallback (void) + + -2- Add CPAL_I2C_TX_UserCallback code source in application file ( example : main.c ) + void CPAL_I2C_TX_UserCallback (CPAL_InitTypeDef* pDevInitStruct) + { + // + // user code + // + } + + There are two types of Error Callbacks : + -1- Single Error Callback : Only one Callback is used to manage all device errors. + -2- Multiple Error Callback : Each device error is managed by its own separate Callback. + + Example of using CPAL_I2C_BERR_UserCallback : + + -1- Select Multiple Error Callback type : + //#define USE_SINGLE_ERROR_CALLBACK + #define USE_MULTIPLE_ERROR_CALLBACK + + -2- Comment define relative to CPAL_I2C_BERR_UserCallback in stm32f0xx_i2c_cpal_conf.h.h file: + //#define CPAL_I2C_BERR_UserCallback (void) + + -3- Add CPAL_I2C_BERR_UserCallback code source in application file ( example: main.c ) + void CPAL_I2C_BERR_UserCallback (CPAL_DevTypeDef pDevInstance) + { + // + // user code + // + } + +------ The driver API functions Prototypes are in stm32f0xx_i2c_cpal.h file. + +*********END OF User Notes***************************************************************************************************************/ + + + + +/*======================================================================================================================================= + CPAL Firmware Functionality Configuration +=========================================================================================================================================*/ + +/*-----------------------------------------------------------------------------------------------------------------------*/ +/*-----------------------------------------------------------------------------------------------------------------------*/ + +/* -- Section 1 : **** I2Cx Device Selection **** + + Description: This section provide an easy way to select I2Cx devices in user application. + Choosing device allows to save memory resources. + If you need I2C1 device, uncomment relative define: #define CPAL_USE_I2C1. + All available I2Cx device can be used at the same time. + At least one I2C device should be selected.*/ + +#define CPAL_USE_I2C1 /*CTRL = 0 /*Libraries->Small printf + // set to 'Yes') calls __io_putchar() + #define PUTCHAR_PROTOTYPE int __io_putchar(int ch) + #else + #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) + #endif + + WARNING Be aware that enabling this feature may slow down the communication process, increase the code size + significantly, and may in some cases cause communication errors (when print/display mechanism is too slow)*/ + + +/* To Enable CPAL_DEBUG Option Uncomment the define below */ +//#define CPAL_DEBUG + +#ifdef CPAL_DEBUG +#define CPAL_LOG(Str) printf(Str) +#include /* This header file must be included when using CPAL_DEBUG option */ +#else +#define CPAL_LOG(Str) ((void)0) +#endif /* CPAL_DEBUG */ + + +/*-----------------------------------------------------------------------------------------------------------------------*/ +/*-----------------------------------------------------------------------------------------------------------------------*/ + +/*********END OF CPAL Firmware Functionality Configuration****************************************************************/ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F0XX_I2C_CPAL_CONF_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/STM32F0xx_CPAL_Driver/inc/stm32f0xx_i2c_cpal_hal.h b/libraries/STM32F0xx_CPAL_Driver/inc/stm32f0xx_i2c_cpal_hal.h new file mode 100644 --- /dev/null +++ b/libraries/STM32F0xx_CPAL_Driver/inc/stm32f0xx_i2c_cpal_hal.h @@ -0,0 +1,631 @@ +/** + ****************************************************************************** + * @file stm32f0xx_i2c_cpal_hal.h + * @author MCD Application Team + * @version V1.2.0 + * @date 24-July-2014 + * @brief This file contains all the functions prototypes for the CPAL_I2C_HAL + * firmware layer. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2014 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef ___STM32F0XX_I2C_CPAL_HAL_H +#define ___STM32F0XX_I2C_CPAL_HAL_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +/*========= STM32 Standard library files includes =========*/ +#include "stm32f0xx.h" +#include "stm32f0xx_i2c.h" +#include "stm32f0xx_dma.h" +#include "stm32f0xx_gpio.h" +#include "stm32f0xx_rcc.h" +#include "stm32f0xx_misc.h" + +/*========= CPAL library files includes =========*/ +#include "stm32f0xx_i2c_cpal.h" + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/*====================================================================================================================================== + CPAL Hardware Configuration +========================================================================================================================================*/ + +/* ------ Configure the communication device and all related peripherals ( GPIO Pin, DMA Channels, + NVIC Priority) with this file, by referring to configuration Sections: + + - Section 1 : Select the pins to be used for each device instance. + + - Section 2 : Select TX and RX DMA Channels (if DMA mode will be used). + + - Section 3 : Set device's Events, Errors and DMA Interrupts Priorities. */ + + +/*-----------------------------------------------------------------------------------------------------------------------*/ +/*-----------------------------------------------------------------------------------------------------------------------*/ + +/* -- Section 1 : **** Device IO Pins Selection **** + + Description: This section allows user to choose IO Pins for each device if possible (in accordance with + used product: some products have only one possibility for the IO pins). + Each device instance (I2C1, I2C2 ..) has its specific defines: one for each Pin. + For each device instance, you will change existing defines with adequate IO Pins and Port + ( Refer to Product Pin mapping in related datasheet).*/ + +/* To configure SCL and SDA Pin change these defines with adequate value : + +#define CPAL_I2C1_SCL_GPIO_PORT GPIOX (X : Name of the GPIO PORT (A,B,C,....)) +#define CPAL_I2C1_SCL_GPIO_CLK RCC_APB2Periph_GPIOX (X : Name of the GPIO PORT (A,B,C,....)) +#define CPAL_I2C1_SCL_GPIO_PIN GPIO_Pin_X (X : Pin number (1,2,3,....)) +#define CPAL_I2C1_SCL_GPIO_PINSOURCE GPIO_PinSourceX (X : Pin number (1,2,3,....)) + +#define CPAL_I2C1_SDA_GPIO_PORT GPIOX (X : Name of the GPIO PORT (A,B,C,....)) +#define CPAL_I2C1_SDA_GPIO_CLK RCC_APB2Periph_GPIOX (X : Name of the GPIO PORT (A,B,C,....)) +#define CPAL_I2C1_SDA_GPIO_PIN GPIO_Pin_X (X : Pin number (1,2,3,....)) +#define CPAL_I2C1_SDA_GPIO_PINSOURCE GPIO_PinSourceX (X : Pin number (1,2,3,....)) */ + +/* IO Pins selection possibilities + +|--------|---------|--------------|-----------|------------------|-------------------------| +| Device | I2C PIN | GPIO_PIN | GPIO_PORT | GPIO_PinSource | GPIO_CLK | +|--------|---------|--------------|-----------|------------------|-------------------------| +| | | GPIO_Pin_6 | GPIOB | GPIO_PinSource6 | RCC_AHBPeriph_GPIOB | +| | SCL |--------------|-----------|------------------|-------------------------| +| | | GPIO_Pin_8 | GPIOB | GPIO_PinSource8 | RCC_AHBPeriph_GPIOB | +| I2C1 |---------|--------------|-----------|------------------|-------------------------| +| | | GPIO_Pin_7 | GPIOB | GPIO_PinSource7 | RCC_AHBPeriph_GPIOB | +| | SDA |--------------|-----------|------------------|-------------------------| +| | | GPIO_Pin_9 | GPIOB | GPIO_PinSource9 | RCC_AHBPeriph_GPIOB | +|--------|---------|--------------|-----------|------------------|-------------------------| +| | | GPIO_Pin_10 | GPIOB | GPIO_PinSource10 | RCC_AHBPeriph_GPIOB | +| | SCL |--------------|-----------|------------------|-------------------------| +| | | GPIO_Pin_6 | GPIOF | GPIO_PinSource6 | RCC_AHBPeriph_GPIOF | +| I2C2 |---------|--------------|-----------|------------------|-------------------------| +| | | GPIO_Pin_11 | GPIOB | GPIO_PinSource11 | RCC_AHBPeriph_GPIOB | +| | SDA |--------------|-----------|------------------|-------------------------| +| | | GPIO_Pin_7 | GPIOF | GPIO_PinSource9 | RCC_AHBPeriph_GPIOF | +|--------|---------|--------------|-----------|------------------|-------------------------| + + */ + + +/*----------- I2C1 Device -----------*/ + +#define CPAL_I2C1_SCL_GPIO_PORT GPIOB +#define CPAL_I2C1_SCL_GPIO_CLK RCC_AHBPeriph_GPIOB +#define CPAL_I2C1_SCL_GPIO_PIN GPIO_Pin_6 +#define CPAL_I2C1_SCL_GPIO_PINSOURCE GPIO_PinSource6 + +#define CPAL_I2C1_SDA_GPIO_PORT GPIOB +#define CPAL_I2C1_SDA_GPIO_CLK RCC_AHBPeriph_GPIOB +#define CPAL_I2C1_SDA_GPIO_PIN GPIO_Pin_7 +#define CPAL_I2C1_SDA_GPIO_PINSOURCE GPIO_PinSource7 + +/*-----------I2C2 Device -----------*/ + +#define CPAL_I2C2_SCL_GPIO_PORT GPIOB +#define CPAL_I2C2_SCL_GPIO_CLK RCC_AHBPeriph_GPIOB +#define CPAL_I2C2_SCL_GPIO_PIN GPIO_Pin_10 +#define CPAL_I2C2_SCL_GPIO_PINSOURCE GPIO_PinSource10 + +#define CPAL_I2C2_SDA_GPIO_PORT GPIOB +#define CPAL_I2C2_SDA_GPIO_CLK RCC_AHBPeriph_GPIOB +#define CPAL_I2C2_SDA_GPIO_PIN GPIO_Pin_11 +#define CPAL_I2C2_SDA_GPIO_PINSOURCE GPIO_PinSource11 + +/*-----------------------------------------------------------------------------------------------------------------------*/ +/*-----------------------------------------------------------------------------------------------------------------------*/ + +/* -- Section 2 : **** Device TX and RX DMA Channels Selection **** + + Description: This section allows user to choose TX and RX DMA Channels if possible (in accordance with + used product) for each device. + Each device instance (I2C1, I2C2 ..) has its specific defines: one for DMA TX Channel and + another one for DMA RX Channel. + For each device instance, you find all TX an RX DMA Channel possibilities ( Refer to Product + Reference Manual).*/ + +/* DMA Channel selection possibilities + +|--------|---------|----------------| +| Device | Channel | DMA Channel | +|--------|---------|----------------| +| | TX | DMA1_Channel2 | +| I2C1 |---------|----------------| +| | RX | DMA1_Channel3 | +|--------|---------|----------------| +| | TX | DMA1_Channel4 | +| I2C2 |---------|----------------| +| | RX | DMA1_Channel5 | +|--------|---------|----------------|*/ + +/* I2Cx TX and RX DMA channels for STM32F0XX family are fixed */ + +/*----------- I2C1 Device -----------*/ +#define CPAL_I2C1_DMA_TX_Channel DMA1_Channel2 +#define CPAL_I2C1_DMA_RX_Channel DMA1_Channel3 + +/*----------- I2C2 Device -----------*/ +#define CPAL_I2C2_DMA_TX_Channel DMA1_Channel4 +#define CPAL_I2C2_DMA_RX_Channel DMA1_Channel5 + +/*-----------------------------------------------------------------------------------------------------------------------*/ +/*-----------------------------------------------------------------------------------------------------------------------*/ + +/* -- Section 3 : **** I2C and DMA Interrupts Priority Selection **** + + Description: This section allows user to select Interrupt Priority of I2C Event Interrupts and DMA Interrupts. + + Make sure that the following rules are always respected: + - I2C event and error interrupts should be interruptible (mainly, the timeout interrupt should + be able to interrupt all device ISR) + - I2C Error interrupt priority should be higher than Event interrupt + - The timeout mechanism interrupt priority should be the highest one and it should be able to + interrupt any other ISR. + - It is advised that DMA interrupts have higher priority than the device event interrupts.*/ + + +/*----------- I2Cx Interrupt Priority -------------*/ + +/*----------- I2C1 Device -----------*/ +#define I2C1_IT_PRIO I2C1_IT_OFFSET_PREPRIO + 2 /* I2C1 IT PRIORITY */ +#define I2C1_IT_DMA_PRIO I2C1_IT_OFFSET_PREPRIO + 0 /* I2C1 DMA PRIORITY */ + +/*----------- I2C2 Device -----------*/ +#define I2C2_IT_PRIO I2C2_IT_OFFSET_PREPRIO + 2 /* I2C2 IT PRIORITY */ +#define I2C2_IT_DMA_PRIO I2C2_IT_OFFSET_PREPRIO + 0 /* I2C2 DMA PRIORITY */ + + +/*-----------------------------------------------------------------------------------------------------------------------*/ +/*-----------------------------------------------------------------------------------------------------------------------*/ + +/*****END OF CPAL Hardware Configuration***************************************************************************************************/ + + /* !WARNING!: + --------- + The following code should not be modified by user. + Any modification may cause Library dysfunction. + */ + +/*========= Common Defines =========*/ + +/* This define set the number of I2C devices that can be used with this product family */ +#define CPAL_I2C_DEV_NUM 2 + +/* This define is used to enable DMA Channel */ +#define CPAL_DMA_CCR_EN DMA_CCR_EN + +/* This define is used to check if DMA interrupt option are enabled */ +#define CPAL_OPT_DMA_IT_MASK ((uint32_t)0x00003F00) + +/* This define is used to check I2C errors (BERR, ARLO and OVR) */ +#define CPAL_I2C_STATUS_ERR_MASK ((uint32_t)0x00000700) /*!< I2C errors Mask */ + +/* This define is used to check I2C events (TXIS, RXNE, ADDR, NACKF, STOPF, TC and TCR) */ +#define CPAL_I2C_STATUS_EVT_MASK ((uint16_t)0x0000000FE) /*!< I2C event Mask for Status Register 1 */ + +/* This define is used to check if DMA TX interrupt are selected */ +#define CPAL_OPT_I2C_DMA_TX_IT_MASK ((uint32_t)0x00000700) + +/* This define is used to check if DMA RX interrupt are selected */ +#define CPAL_OPT_I2C_DMA_RX_IT_MASK ((uint32_t)0x00003800) + + /* I2C Event Defines */ +#define CPAL_I2C_EVT_ADDR I2C_ISR_ADDR /*!
CCR |= CPAL_DMA_CCR_EN + +#define __CPAL_I2C_HAL_DISABLE_DMATX(device) CPAL_I2C_DMA_TX_Channel[(device)]->CCR &= ~CPAL_DMA_CCR_EN + +#define __CPAL_I2C_HAL_ENABLE_DMARX(device) CPAL_I2C_DMA_RX_Channel[(device)]->CCR |= CPAL_DMA_CCR_EN + +#define __CPAL_I2C_HAL_DISABLE_DMARX(device) CPAL_I2C_DMA_RX_Channel[(device)]->CCR &= ~CPAL_DMA_CCR_EN + +/* DMA interrupts enable/disable */ + +#define __I2C_HAL_ENABLE_DMATX_TCIT(device) CPAL_I2C_DMA_TX_Channel[(device)]->CCR |= DMA_IT_TC + +#define __I2C_HAL_ENABLE_DMATX_HTIT(device) CPAL_I2C_DMA_TX_Channel[(device)]->CCR |= DMA_IT_HT + +#define __I2C_HAL_ENABLE_DMATX_TEIT(device) CPAL_I2C_DMA_TX_Channel[(device)]->CCR |= DMA_IT_TE + +#define __I2C_HAL_ENABLE_DMARX_TCIT(device) CPAL_I2C_DMA_RX_Channel[(device)]->CCR |= DMA_IT_TC + +#define __I2C_HAL_ENABLE_DMARX_HTIT(device) CPAL_I2C_DMA_RX_Channel[(device)]->CCR |= DMA_IT_HT + +#define __I2C_HAL_ENABLE_DMARX_TEIT(device) CPAL_I2C_DMA_RX_Channel[(device)]->CCR |= DMA_IT_TE + +/* DMA interrupts flag management */ + +#define __CPAL_I2C_HAL_GET_DMATX_IT(device) (uint32_t)(CPAL_I2C_DMA[(device)]->ISR & (CPAL_I2C_DMA_TX_TC_FLAG[(device)] \ + | CPAL_I2C_DMA_TX_HT_FLAG[(device)] | CPAL_I2C_DMA_TX_TE_FLAG[(device)])) + +#define __CPAL_I2C_HAL_GET_DMATX_TCIT(device) (uint32_t)(CPAL_I2C_DMA[(device)]->ISR & CPAL_I2C_DMA_TX_TC_FLAG [(device)]) + +#define __CPAL_I2C_HAL_GET_DMATX_HTIT(device) (uint32_t)(CPAL_I2C_DMA[(device)]->ISR & CPAL_I2C_DMA_TX_HT_FLAG [(device)]) + +#define __CPAL_I2C_HAL_GET_DMATX_TEIT(device) (uint32_t)(CPAL_I2C_DMA[(device)]->ISR & CPAL_I2C_DMA_TX_TE_FLAG [(device)]) + +#define __CPAL_I2C_HAL_GET_DMARX_IT(device) (uint32_t)(CPAL_I2C_DMA[(device)]->ISR & (CPAL_I2C_DMA_RX_TC_FLAG[(device)] \ + | CPAL_I2C_DMA_RX_HT_FLAG[(device)] | CPAL_I2C_DMA_RX_TE_FLAG[(device)])) + +#define __CPAL_I2C_HAL_GET_DMARX_TCIT(device) (uint32_t)(CPAL_I2C_DMA[(device)]->ISR & CPAL_I2C_DMA_RX_TC_FLAG [(device)]) + +#define __CPAL_I2C_HAL_GET_DMARX_HTIT(device) (uint32_t)(CPAL_I2C_DMA[(device)]->ISR & CPAL_I2C_DMA_RX_HT_FLAG [(device)]) + +#define __CPAL_I2C_HAL_GET_DMARX_TEIT(device) (uint32_t)(CPAL_I2C_DMA[(device)]->ISR & CPAL_I2C_DMA_RX_TE_FLAG [(device)]) + +#define __CPAL_I2C_HAL_CLEAR_DMATX_IT(device) CPAL_I2C_DMA[(device)]->IFCR = (CPAL_I2C_DMA_TX_TC_FLAG[(device)] \ + | CPAL_I2C_DMA_TX_HT_FLAG[(device)] | CPAL_I2C_DMA_TX_TE_FLAG[(device)]) + +#define __CPAL_I2C_HAL_CLEAR_DMARX_IT(device) CPAL_I2C_DMA[(device)]->IFCR = (CPAL_I2C_DMA_RX_TC_FLAG[(device)] \ + | CPAL_I2C_DMA_RX_HT_FLAG[(device)] | CPAL_I2C_DMA_RX_TE_FLAG[(device)]) + +/* Get DMA data counter */ + +#define __CPAL_I2C_HAL_DMATX_GET_CNDT(device) (uint32_t)(CPAL_I2C_DMA_TX_Channel[(device)]->CNDTR) + +#define __CPAL_I2C_HAL_DMARX_GET_CNDT(device) (uint32_t)(CPAL_I2C_DMA_RX_Channel[(device)]->CNDTR) + + +/*========= I2C =========*/ + +/* I2C enable/disable */ + +#define __CPAL_I2C_HAL_ENABLE_DEV(device) CPAL_I2C_DEVICE[(device)]->CR1 |= I2C_CR1_PE + +#define __CPAL_I2C_HAL_DISABLE_DEV(device) CPAL_I2C_DEVICE[(device)]->CR1 &= ~I2C_CR1_PE + +/* I2C software reset */ + +#define __CPAL_I2C_HAL_SWRST(device) CPAL_I2C_DEVICE[(device)]->CR1 |= I2C_CR1_SWRST; \ + CPAL_I2C_DEVICE[(device)]->CR1 &= ~I2C_CR1_SWRST + +/* I2C Wakeup option */ + +#define __CPAL_I2C_HAL_ENABLE_WAKEUP(device) CPAL_I2C_DEVICE[(device)]->CR1 |= I2C_CR1_WUPEN + +#define __CPAL_I2C_HAL_DISABLE_WAKEUP(device) CPAL_I2C_DEVICE[(device)]->CR1 &= ~I2C_CR1_WUPEN + +/* I2C interrupts enable/disable */ + +#define __CPAL_I2C_HAL_DISABLE_ALLIT(device) CPAL_I2C_DEVICE[(device)]->CR1 &= ~(I2C_CR1_TXIE | I2C_CR1_RXIE | I2C_CR1_ADDRIE | \ + I2C_CR1_STOPIE | I2C_CR1_TCIE | I2C_CR1_ERRIE | I2C_CR1_NACKIE) + +#define __CPAL_I2C_HAL_ENABLE_ERRIT(device) CPAL_I2C_DEVICE[(device)]->CR1 |= (I2C_CR1_ERRIE | I2C_CR1_NACKIE) + +#define __CPAL_I2C_HAL_DISABLE_ERRIT(device) CPAL_I2C_DEVICE[(device)]->CR1 &= ~(I2C_CR1_ERRIE | I2C_CR1_NACKIE) + + +#define __CPAL_I2C_HAL_ENABLE_MASTER_IT(device) CPAL_I2C_DEVICE[(device)]->CR1 |= (I2C_CR1_TCIE | I2C_CR1_STOPIE) + +#define __CPAL_I2C_HAL_DISABLE_MASTER_IT(device) CPAL_I2C_DEVICE[(device)]->CR1 &= ~(I2C_CR1_TCIE | I2C_CR1_STOPIE) + +#define __CPAL_I2C_HAL_ENABLE_MASTER_TXIT(device) CPAL_I2C_DEVICE[(device)]->CR1 |= (I2C_CR1_TCIE | I2C_CR1_STOPIE | I2C_CR1_TXIE) + +#define __CPAL_I2C_HAL_ENABLE_MASTER_RXIT(device) CPAL_I2C_DEVICE[(device)]->CR1 |= (I2C_CR1_TCIE | I2C_CR1_STOPIE | I2C_CR1_RXIE) + + +#define __CPAL_I2C_HAL_ENABLE_SLAVE_IT(device) CPAL_I2C_DEVICE[(device)]->CR1 |= (I2C_CR1_ADDRIE | I2C_CR1_STOPIE) + +#define __CPAL_I2C_HAL_DISABLE_SLAVE_IT(device) CPAL_I2C_DEVICE[(device)]->CR1 &= ~(I2C_CR1_ADDRIE | I2C_CR1_STOPIE) + +#define __CPAL_I2C_HAL_ENABLE_SLAVE_TXIT(device) CPAL_I2C_DEVICE[(device)]->CR1 |= (I2C_CR1_ADDRIE | I2C_CR1_STOPIE | I2C_CR1_TXIE) + +#define __CPAL_I2C_HAL_ENABLE_SLAVE_RXIT(device) CPAL_I2C_DEVICE[(device)]->CR1 |= (I2C_CR1_ADDRIE | I2C_CR1_STOPIE | I2C_CR1_RXIE) + + +#define __CPAL_I2C_HAL_ENABLE_STOPIE_IT(device) CPAL_I2C_DEVICE[(device)]->CR1 |= I2C_CR1_STOPIE + +#define __CPAL_I2C_HAL_DISABLE_STOPIE_IT(device) CPAL_I2C_DEVICE[(device)]->CR1 &= ~I2C_CR1_STOPIE + +#define __CPAL_I2C_HAL_ENABLE_ADDRIE_IT(device) CPAL_I2C_DEVICE[(device)]->CR1 |= I2C_CR1_ADDRIE + +#define __CPAL_I2C_HAL_DISABLE_ADDRIE_IT(device) CPAL_I2C_DEVICE[(device)]->CR1 &= ~I2C_CR1_ADDRIE + +#define __CPAL_I2C_HAL_ENABLE_TCIE_IT(device) CPAL_I2C_DEVICE[(device)]->CR1 |= I2C_CR1_TCIE + +#define __CPAL_I2C_HAL_DISABLE_TCIE_IT(device) CPAL_I2C_DEVICE[(device)]->CR1 &= ~I2C_CR1_TCIE + +#define __CPAL_I2C_HAL_ENABLE_TXIE_IT(device) CPAL_I2C_DEVICE[(device)]->CR1 |= I2C_CR1_TXIE + +#define __CPAL_I2C_HAL_DISABLE_TXIE_IT(device) CPAL_I2C_DEVICE[(device)]->CR1 &= ~I2C_CR1_TXIE + +#define __CPAL_I2C_HAL_ENABLE_RXIE_IT(device) CPAL_I2C_DEVICE[(device)]->CR1 |= I2C_CR1_RXIE + +#define __CPAL_I2C_HAL_DISABLE_RXIE_IT(device) CPAL_I2C_DEVICE[(device)]->CR1 &= ~I2C_CR1_RXIE + + +/* I2C Addressing configuration */ + +#define __CPAL_I2C_HAL_SADD_CONF(device,value) CPAL_I2C_DEVICE[(device)]->CR2 &= ~I2C_CR2_SADD; \ + CPAL_I2C_DEVICE[(device)]->CR2 |= (uint32_t)((value) & 0x000003FF) + +#define __CPAL_I2C_HAL_OA2_CONF(device,value) CPAL_I2C_DEVICE[(device)]->OAR2 &= ~I2C_OAR2_OA2; \ + CPAL_I2C_DEVICE[(device)]->OAR2 |= (uint32_t)((value) & 0x000000FE) + +#define __CPAL_I2C_HAL_OA2_MASK_CONF(device,value) CPAL_I2C_DEVICE[(device)]->OAR2 &= ~I2C_OAR2_OA2MSK; \ + CPAL_I2C_DEVICE[(device)]->OAR2 |= (uint32_t)((value) << 8) + +#define __CPAL_I2C_HAL_ENABLE_OA2(device) CPAL_I2C_DEVICE[(device)]->OAR2 |= I2C_OAR2_OA2EN + +#define __CPAL_I2C_HAL_ENABLE_ADD10(device) CPAL_I2C_DEVICE[(device)]->CR2 |= I2C_CR2_ADD10 + +#define __CPAL_I2C_HAL_DISABLE_ADD10(device) CPAL_I2C_DEVICE[(device)]->CR2 &= ~I2C_CR2_ADD10 + +#define __CPAL_I2C_HAL_ENABLE_COMPLETE_HEAD10R(device) CPAL_I2C_DEVICE[(device)]->CR2 &= ~I2C_CR2_HEAD10R + +#define __CPAL_I2C_HAL_DISABLE_COMPLETE_HEAD10R(device) CPAL_I2C_DEVICE[(device)]->CR2 |= I2C_CR2_HEAD10R + +#define __CPAL_I2C_HAL_ENABLE_GENCALL(device) CPAL_I2C_DEVICE[(device)]->CR1 |= I2C_CR1_GCEN + +#define __CPAL_I2C_HAL_REQ_WRITE_TRANSFER(device) CPAL_I2C_DEVICE[(device)]->CR2 &= ~I2C_CR2_RD_WRN + +#define __CPAL_I2C_HAL_REQ_READ_TRANSFER(device) CPAL_I2C_DEVICE[(device)]->CR2 |= I2C_CR2_RD_WRN + +#define __CPAL_I2C_HAL_GET_OA1(device) (uint32_t)(CPAL_I2C_DEVICE[(device)]->ISR & I2C_OAR1_OA1) + +#define __CPAL_I2C_HAL_GET_OA2(device) (uint32_t)(CPAL_I2C_DEVICE[(device)]->ISR & I2C_OAR2_OA2) + +#define __CPAL_I2C_HAL_GET_OA2_MASK(device) (uint32_t)((CPAL_I2C_DEVICE[(device)]->ISR & I2C_OAR2_OA2MSK) >> 8) + +#define __CPAL_I2C_HAL_GET_ADDCODE(device) (uint32_t)((CPAL_I2C_DEVICE[(device)]->ISR & I2C_ISR_ADDCODE) >> 17) + +#define __CPAL_I2C_HAL_GET_DIR(device) (uint32_t)(CPAL_I2C_DEVICE[(device)]->ISR & I2C_ISR_DIR) + +/* I2C misc configuration */ + +#define __CPAL_I2C_HAL_CR2_UPDATE(device,value) CPAL_I2C_DEVICE[(device)]->CR2 = value + +#define __CPAL_I2C_HAL_ENABLE_TXDMAREQ(device) CPAL_I2C_DEVICE[(device)]->CR1 |= I2C_CR1_TXDMAEN + +#define __CPAL_I2C_HAL_DISABLE_TXDMAREQ(device) CPAL_I2C_DEVICE[(device)]->CR1 &= ~I2C_CR1_TXDMAEN + +#define __CPAL_I2C_HAL_ENABLE_RXDMAREQ(device) CPAL_I2C_DEVICE[(device)]->CR1 |= I2C_CR1_RXDMAEN + +#define __CPAL_I2C_HAL_DISABLE_RXDMAREQ(device) CPAL_I2C_DEVICE[(device)]->CR1 &= ~I2C_CR1_RXDMAEN + +#define __CPAL_I2C_HAL_ENABLE_NACK(device) CPAL_I2C_DEVICE[(device)]->CR2 |= I2C_CR2_NACK + +#define __CPAL_I2C_HAL_DISABLE_NACK(device) CPAL_I2C_DEVICE[(device)]->CR2 &= ~I2C_CR2_NACK + +#define __CPAL_I2C_HAL_ENABLE_AUTOEND(device) CPAL_I2C_DEVICE[(device)]->CR2 |= I2C_CR2_AUTOEND + +#define __CPAL_I2C_HAL_DISABLE_AUTOEND(device) CPAL_I2C_DEVICE[(device)]->CR2 &= ~I2C_CR2_AUTOEND + +#define __CPAL_I2C_HAL_ENABLE_RELOAD(device) CPAL_I2C_DEVICE[(device)]->CR2 |= I2C_CR2_RELOAD + +#define __CPAL_I2C_HAL_DISABLE_RELOAD(device) CPAL_I2C_DEVICE[(device)]->CR2 &= ~I2C_CR2_RELOAD + +#define __CPAL_I2C_HAL_ENABLE_NOSTRETCH(device) CPAL_I2C_DEVICE[(device)]->CR1 |= I2C_CR1_NOSTRETCH + +#define __CPAL_I2C_HAL_DISABLE_NOSTRETCH(device) CPAL_I2C_DEVICE[(device)]->CR1 &= ~I2C_CR1_NOSTRETCH + +#define __CPAL_I2C_HAL_START(device) CPAL_I2C_DEVICE[(device)]->CR2 |= I2C_CR2_START + +#define __CPAL_I2C_HAL_STOP(device) CPAL_I2C_DEVICE[(device)]->CR2 |= I2C_CR2_STOP + +/* I2C data management */ + +#define __CPAL_I2C_HAL_RECEIVE(device) (uint8_t)(CPAL_I2C_DEVICE[(device)]->RXDR) + +#define __CPAL_I2C_HAL_SEND(device,value) CPAL_I2C_DEVICE[(device)]->TXDR = (uint8_t)((value)) + +#define __CPAL_I2C_HAL_SET_NBYTES(device,value) CPAL_I2C_DEVICE[(device)]->CR2 &= ~I2C_CR2_NBYTES; \ + CPAL_I2C_DEVICE[(device)]->CR2 |= (uint32_t)((uint32_t)(value) << 16) + +#define __CPAL_I2C_HAL_GET_NBYTES(device,value) (uint32_t)((CPAL_I2C_DEVICE[(device)]->CR2 & I2C_CR2_NBYTES) >> 16) + +#define __CPAL_I2C_HAL_CLEAR_NBYTES(device) CPAL_I2C_DEVICE[(device)]->CR2 &= ~I2C_CR2_NBYTES + +/* I2C flags management */ + +#define __CPAL_I2C_HAL_GET_EVENT(device) (uint32_t)(CPAL_I2C_DEVICE[(device)]->ISR & CPAL_I2C_STATUS_EVT_MASK) + +#define __CPAL_I2C_HAL_GET_ERROR(device) (uint32_t)(CPAL_I2C_DEVICE[(device)]->ISR & CPAL_I2C_STATUS_ERR_MASK) + +#define __CPAL_I2C_HAL_GET_TXE(device) (uint32_t)(CPAL_I2C_DEVICE[(device)]->ISR & I2C_ISR_TXE) + +#define __CPAL_I2C_HAL_GET_TXIS(device) (uint32_t)(CPAL_I2C_DEVICE[(device)]->ISR & I2C_ISR_TXIS) + +#define __CPAL_I2C_HAL_GET_RXNE(device) (uint32_t)(CPAL_I2C_DEVICE[(device)]->ISR & I2C_ISR_RXNE) + +#define __CPAL_I2C_HAL_GET_ADDR(device) (uint32_t)(CPAL_I2C_DEVICE[(device)]->ISR & I2C_ISR_ADDR) + +#define __CPAL_I2C_HAL_GET_NACK(device) (uint32_t)(CPAL_I2C_DEVICE[(device)]->ISR & I2C_ISR_NACKF) + +#define __CPAL_I2C_HAL_GET_STOP(device) (uint32_t)(CPAL_I2C_DEVICE[(device)]->ISR & I2C_ISR_STOPF) + +#define __CPAL_I2C_HAL_GET_TC(device) (uint32_t)(CPAL_I2C_DEVICE[(device)]->ISR & I2C_ISR_TC) + +#define __CPAL_I2C_HAL_GET_TCR(device) (uint32_t)(CPAL_I2C_DEVICE[(device)]->ISR & I2C_ISR_TCR) + +#define __CPAL_I2C_HAL_GET_BERR(device) (uint32_t)(CPAL_I2C_DEVICE[(device)]->ISR & I2C_ISR_BERR) + +#define __CPAL_I2C_HAL_GET_ARLO(device) (uint32_t)(CPAL_I2C_DEVICE[(device)]->ISR & I2C_ISR_ARLO) + +#define __CPAL_I2C_HAL_GET_OVR(device) (uint32_t)(CPAL_I2C_DEVICE[(device)]->ISR & I2C_ISR_OVR) + +#define __CPAL_I2C_HAL_GET_BUSY(device) (uint32_t)(CPAL_I2C_DEVICE[(device)]->ISR & I2C_ISR_BUSY) + +#define __CPAL_I2C_HAL_CLEAR_ADDR(device) CPAL_I2C_DEVICE[(device)]->ICR = I2C_ICR_ADDRCF + +#define __CPAL_I2C_HAL_CLEAR_NACK(device) CPAL_I2C_DEVICE[(device)]->ICR = I2C_ICR_NACKCF + +#define __CPAL_I2C_HAL_CLEAR_STOP(device) CPAL_I2C_DEVICE[(device)]->ICR = I2C_ICR_STOPCF + +#define __CPAL_I2C_HAL_CLEAR_BERR(device) CPAL_I2C_DEVICE[(device)]->ICR = I2C_ICR_BERRCF + +#define __CPAL_I2C_HAL_CLEAR_ARLO(device) CPAL_I2C_DEVICE[(device)]->ICR = I2C_ICR_ARLOCF + +#define __CPAL_I2C_HAL_CLEAR_OVR(device) CPAL_I2C_DEVICE[(device)]->ICR = I2C_ICR_OVRCF + +/* Exported functions --------------------------------------------------------*/ + +/*========= I2CX IRQHandler =========*/ + +#ifdef CPAL_USE_I2C1 + uint32_t I2C1_IRQHandler(void); /*
© COPYRIGHT 2014 STMicroelectronics
+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_i2c_cpal.h" + +/* Private typedef -----------------------------------------------------------*/ +/* Private defines -----------------------------------------------------------*/ + +/* Private macro -------------------------------------------------------------*/ + + +/* This macro allows to test on a flag status and to start Timeout procedure if the + waiting time exceeds the allowed timeout period. + @note This macro has not been implemented as a function because the entered parameter + 'cmd' itself can be a macro (if it was implemented as a function, the check on the + flag would be done only once, while the required behavior is to check the flag + continuously).*/ + +#define __CPAL_I2C_TIMEOUT_DETECT ((pDevInitStruct->wCPAL_Timeout == CPAL_I2C_TIMEOUT_MIN) ||\ + (pDevInitStruct->wCPAL_Timeout == CPAL_I2C_TIMEOUT_DEFAULT)) + +#define __CPAL_I2C_TIMEOUT(cmd, timeout) pDevInitStruct->wCPAL_Timeout = CPAL_I2C_TIMEOUT_MIN + (timeout);\ + while (((cmd) == 0) && (!__CPAL_I2C_TIMEOUT_DETECT));\ + if (__CPAL_I2C_TIMEOUT_DETECT)\ + {\ + return CPAL_I2C_Timeout (pDevInitStruct); \ + }\ + pDevInitStruct->wCPAL_Timeout = CPAL_I2C_TIMEOUT_DEFAULT + + +/* Private variables ---------------------------------------------------------*/ + +/*========= Table Exported from HAL =========*/ + +extern I2C_TypeDef* CPAL_I2C_DEVICE[]; + +#ifdef CPAL_I2C_DMA_PROGMODEL +extern DMA_TypeDef* CPAL_I2C_DMA[]; + +extern DMA_Channel_TypeDef* CPAL_I2C_DMA_TX_Channel[]; +extern DMA_Channel_TypeDef* CPAL_I2C_DMA_RX_Channel[]; + +extern const uint32_t CPAL_I2C_DMA_TX_TC_FLAG[]; +extern const uint32_t CPAL_I2C_DMA_RX_TC_FLAG[]; + +extern const uint32_t CPAL_I2C_DMA_TX_HT_FLAG[]; +extern const uint32_t CPAL_I2C_DMA_RX_HT_FLAG[]; + +extern const uint32_t CPAL_I2C_DMA_TX_TE_FLAG[]; +extern const uint32_t CPAL_I2C_DMA_RX_TE_FLAG[]; +#endif /* CPAL_I2C_DMA_PROGMODEL */ + +/*========= Local structures used in CPAL_I2C_StructInit() function ==========*/ + +I2C_InitTypeDef I2C_InitStructure; + +__IO uint32_t Num_Data = 0; +uint32_t CR2_tmp = 0; + +/* Private function prototypes -----------------------------------------------*/ + +/*========= Local Master events handlers =========*/ + +#ifdef CPAL_I2C_MASTER_MODE + static uint32_t I2C_MASTER_TCR_Handle(CPAL_InitTypeDef* pDevInitStruct); /* Handle Master TCR Interrupt event */ + static uint32_t I2C_MASTER_TC_Handle(CPAL_InitTypeDef* pDevInitStruct); /* Handle Master TC Interrupt event */ + static uint32_t I2C_MASTER_STOP_Handle(CPAL_InitTypeDef* pDevInitStruct); /* Handle Master STOP Interrupt event */ + static uint32_t I2C_MASTER_NACK_Handle(CPAL_InitTypeDef* pDevInitStruct); /* Handle Master NACK Interrupt event */ + #ifdef CPAL_I2C_IT_PROGMODEL + static uint32_t I2C_MASTER_TXIS_Handle(CPAL_InitTypeDef* pDevInitStruct); /* Handle Master TXIS Interrupt event */ + static uint32_t I2C_MASTER_RXNE_Handle(CPAL_InitTypeDef* pDevInitStruct); /* Handle Master RXNE Interrupt event */ + #endif /* CPAL_I2C_IT_PROGMODEL */ +#endif /* CPAL_I2C_MASTER_MODE */ + +/*========= Local Slave events handlers =========*/ + +#ifdef CPAL_I2C_SLAVE_MODE + static uint32_t I2C_SLAVE_ADDR_Handle(CPAL_InitTypeDef* pDevInitStruct); /* Handle Slave ADDR Interrupt event */ + static uint32_t I2C_SLAVE_STOP_Handle(CPAL_InitTypeDef* pDevInitStruct); /* Handle Slave STOPF Interrupt event */ + static uint32_t I2C_SLAVE_NACK_Handle(CPAL_InitTypeDef* pDevInitStruct); /* Handle Slave NACK Interrupt event */ + #ifdef CPAL_I2C_IT_PROGMODEL + static uint32_t I2C_SLAVE_TXIS_Handle(CPAL_InitTypeDef* pDevInitStruct); /* Handle Slave TXIS Interrupt event */ + static uint32_t I2C_SLAVE_RXNE_Handle(CPAL_InitTypeDef* pDevInitStruct); /* Handle Slave RXNE Interrupt event */ + #endif /* CPAL_I2C_IT_PROGMODEL */ +#endif /* CPAL_I2C_SLAVE_MODE */ + + +#ifdef CPAL_I2C_DMA_PROGMODEL +/*========= Local DMA Manager =========*/ +static uint32_t I2C_Enable_DMA (CPAL_InitTypeDef* pDevInitStruct, CPAL_DirectionTypeDef Direction); +#endif /* CPAL_I2C_DMA_PROGMODEL */ + +/*========= CPAL Timeout handler =========*/ +static uint32_t CPAL_I2C_Timeout (CPAL_InitTypeDef* pDevInitStruct); + + +/* Private functions ---------------------------------------------------------*/ + +/*================== USER CPAL Functions ==================*/ + + +/** + * @brief Initialize the peripheral and all related clocks, GPIOs, DMA and + * Interrupts according to the specified parameters in the + * CPAL_InitTypeDef structure. + * @param pDevInitStruct : Pointer to the peripheral configuration structure. + * @retval CPAL_PASS or CPAL_FAIL + */ +uint32_t CPAL_I2C_Init(CPAL_InitTypeDef* pDevInitStruct) +{ + CPAL_LOG("\n\r\n\rLOG : I2C Device Init"); + + /* If CPAL_State is not BUSY */ + if ((pDevInitStruct->CPAL_State == CPAL_STATE_READY) + || (pDevInitStruct->CPAL_State == CPAL_STATE_ERROR) + || (pDevInitStruct->CPAL_State == CPAL_STATE_DISABLED)) + { + /* + - If CPAL_State is CPAL_STATE_ERROR (an Error occurred in transaction): + Perform the initialization routines (device will be deinitialized during initialization). + - If CPAL_State is CPAL_STATE_READY: + Perform the initialization routines + - If CPAL_State is CPAL_STATE_DISABLED: + Perform the Initialization routines */ + +#ifndef CPAL_I2C_DMA_PROGMODEL + if (pDevInitStruct->CPAL_ProgModel == CPAL_PROGMODEL_DMA) + { + /* Update CPAL_State to CPAL_STATE_ERROR */ + pDevInitStruct->CPAL_State = CPAL_STATE_ERROR; + + /* Exit Init function */ + return CPAL_FAIL; + } +#endif /* CPAL_I2C_DMA_PROGMODEL */ + +#ifndef CPAL_I2C_IT_PROGMODEL + if (pDevInitStruct->CPAL_ProgModel == CPAL_PROGMODEL_INTERRUPT) + { + /* Update CPAL_State to CPAL_STATE_ERROR */ + pDevInitStruct->CPAL_State = CPAL_STATE_ERROR; + + /* Exit Init function */ + return CPAL_FAIL; + } +#endif /* CPAL_I2C_IT_PROGMODEL */ + + /* Disable I2Cx device */ + __CPAL_I2C_HAL_DISABLE_DEV(pDevInitStruct->CPAL_Dev); + + CPAL_LOG("\n\rLOG : I2C Device Disabled"); + + /* Deinitialize I2Cx GPIO */ + CPAL_I2C_HAL_GPIODeInit(pDevInitStruct->CPAL_Dev); + + CPAL_LOG("\n\rLOG : I2C Device IOs Deinit"); + + /* Deinitialize I2Cx clock */ + CPAL_I2C_HAL_CLKDeInit(pDevInitStruct->CPAL_Dev); + + CPAL_LOG("\n\rLOG : I2C Device Clock Deinit"); + +#ifdef CPAL_I2C_DMA_PROGMODEL + /* Deinitialize DMA Channels */ + if (pDevInitStruct->CPAL_ProgModel == CPAL_PROGMODEL_DMA) + { + CPAL_I2C_HAL_DMADeInit(pDevInitStruct->CPAL_Dev, pDevInitStruct->CPAL_Direction); + + CPAL_LOG("\n\rLOG : I2C Device DMA Deinit"); + } +#endif /* CPAL_I2C_DMA_PROGMODEL */ + + /*-------------------------------------------------------------------------- + GPIO pins configuration + ---------------------------------------------------------------------------*/ + /* Initialize I2Cx GPIO */ + CPAL_I2C_HAL_GPIOInit(pDevInitStruct->CPAL_Dev); + + CPAL_LOG("\n\rLOG : I2C Device IOs Init"); + + /*-------------------------------------------------------------------------- + Peripheral Clock Initialization + ---------------------------------------------------------------------------*/ + /* Initialize I2Cx clock */ + CPAL_I2C_HAL_CLKInit(pDevInitStruct->CPAL_Dev); + + CPAL_LOG("\n\rLOG : I2C Device Clock Init"); + + /*-------------------------------------------------------------------------- + Peripheral Initialization + ---------------------------------------------------------------------------*/ + + /* Initialize I2Cx device with parameters stored in pCPAL_I2C_Struct */ + I2C_Init(CPAL_I2C_DEVICE[pDevInitStruct->CPAL_Dev], pDevInitStruct->pCPAL_I2C_Struct); + + CPAL_LOG("\n\rLOG : I2C Device Config"); + + /* If General Call mode option bit selected */ + if ((pDevInitStruct->wCPAL_Options & CPAL_OPT_I2C_GENCALL) != 0) + { + /* Enable GENERAL CALL address mode */ + __CPAL_I2C_HAL_ENABLE_GENCALL(pDevInitStruct->CPAL_Dev); + + CPAL_LOG("\n\rLOG : I2C Device GENCALL Mode Enabled"); + } + + /* If OA2 Address mode option bit selected */ + if ((pDevInitStruct->wCPAL_Options & CPAL_OPT_I2C_DUALADDR) != 0) + { + /* Configure OA2 */ + __CPAL_I2C_HAL_OA2_CONF(pDevInitStruct->CPAL_Dev, (uint32_t)(pDevInitStruct->wCPAL_Options & 0x000000FE)); + + /* Configure OA2 masks */ + __CPAL_I2C_HAL_OA2_MASK_CONF(pDevInitStruct->CPAL_Dev, (uint32_t)((pDevInitStruct->wCPAL_Options & CPAL_OPT_I2C_OA2_MASK) >> 25)); + + /* Enable OA2 address mode */ + __CPAL_I2C_HAL_ENABLE_OA2(pDevInitStruct->CPAL_Dev); + + CPAL_LOG("\n\rLOG : I2C Device OA2 ADDR Mode Enabled"); + } + + /* If WakeUp from STOP option bit selected */ + if ((pDevInitStruct->wCPAL_Options & CPAL_OPT_I2C_WAKEUP_STOP) != 0) + { + /* Enable WakeUp from STOP mode */ + __CPAL_I2C_HAL_ENABLE_WAKEUP(pDevInitStruct->CPAL_Dev); + + CPAL_LOG("\n\rLOG : I2C Device WakeUp from Stop Mode Enabled"); + } + else + { + /* Disable WakeUp from STOP mode */ + __CPAL_I2C_HAL_DISABLE_WAKEUP(pDevInitStruct->CPAL_Dev); + } + + /* If NACK Slave Own Address option bit selected */ + if ((pDevInitStruct->wCPAL_Options & CPAL_OPT_I2C_NACK_ADD) != 0) + { + /* Disable Acknowledgement of own Address */ + __CPAL_I2C_HAL_DISABLE_DEV(pDevInitStruct->CPAL_Dev); + + CPAL_LOG("\n\rLOG : I2C Device NACK Own Address Mode Enabled"); + } + +#ifdef CPAL_I2C_DMA_PROGMODEL + /*---------------------------------------------------------------------------- + DMA Initialization : + ---------------------------------------------------------------------------*/ + /* If DMA Programming model is selected*/ + if (pDevInitStruct->CPAL_ProgModel == CPAL_PROGMODEL_DMA) + { + /* Initialize I2Cx DMA channels */ + CPAL_I2C_HAL_DMAInit(pDevInitStruct->CPAL_Dev, pDevInitStruct->CPAL_Direction, pDevInitStruct->wCPAL_Options); + + CPAL_LOG("\n\rLOG : I2C Device DMA Init"); + } +#endif /* CPAL_I2C_DMA_PROGMODEL */ + + /*---------------------------------------------------------------------------- + Peripheral and DMA interrupts Initialization + ---------------------------------------------------------------------------*/ + /* Initialize I2Cx interrupts */ + CPAL_I2C_HAL_ITInit(pDevInitStruct->CPAL_Dev, pDevInitStruct->wCPAL_Options); + + CPAL_LOG("\n\rLOG : I2C Device IT Init"); + + /* Update CPAL_State to CPAL_STATE_READY */ + pDevInitStruct->CPAL_State = CPAL_STATE_READY; + + CPAL_LOG("\n\rLOG : I2C Device Ready"); + + /* Initialize Timeout procedure */ + _CPAL_TIMEOUT_INIT(); + + return CPAL_PASS; + } + /* If CPAL_State is BUSY (a transaction is still on going) exit Init function */ + else + { + CPAL_LOG("\n\rERROR : I2C Device Busy"); + + return CPAL_FAIL; + } +} + + +/** + * @brief Deinitialize the peripheral and all related clocks, GPIOs, DMA and NVIC + * to their reset values. + * @param pDevInitStruct: Pointer to the peripheral configuration structure. + * @retval CPAL_PASS or CPAL_FAIL + * @note The Peripheral clock is disabled but the GPIO Ports clocks remains + * enabled after this deinitialization. + */ +uint32_t CPAL_I2C_DeInit(CPAL_InitTypeDef* pDevInitStruct) +{ + CPAL_LOG("\n\r\n\rLOG : I2C Device Deinit"); + + /* If CPAL_State is not BUSY */ + if ((pDevInitStruct->CPAL_State == CPAL_STATE_READY) + || (pDevInitStruct->CPAL_State == CPAL_STATE_ERROR) + || (pDevInitStruct->CPAL_State == CPAL_STATE_DISABLED)) + { + /* + - If CPAL_State is CPAL_STATE_ERROR (an Error occurred in transaction): + Perform the deinitialization routines + - If CPAL_State is CPAL_STATE_READY: + Perform the deinitialization routines + - If CPAL_State is CPAL_STATE_DISABLED: + Perform the deinitialization routines */ + + /*-------------------------------------------------------------------------- + GPIO pins Deinitialization + Note: The GPIO clock remains enabled after this deinitialization + ---------------------------------------------------------------------------*/ + /* Deinitialize I2Cx GPIO */ + CPAL_I2C_HAL_GPIODeInit(pDevInitStruct->CPAL_Dev); + + CPAL_LOG("\n\rLOG : I2C Device IOs Deinit"); + + /*-------------------------------------------------------------------------- + Peripheral Deinitialization + ---------------------------------------------------------------------------*/ + /* Disable I2Cx device */ + __CPAL_I2C_HAL_DISABLE_DEV(pDevInitStruct->CPAL_Dev); + + CPAL_LOG("\n\rLOG : I2C Device Disabled"); + + /*-------------------------------------------------------------------------- + Peripheral Clock Deinitialization + ---------------------------------------------------------------------------*/ + /* Deinitialize I2Cx clock */ + CPAL_I2C_HAL_CLKDeInit(pDevInitStruct->CPAL_Dev); + + CPAL_LOG("\n\rLOG : I2C Device Clock Deinit"); + +#ifdef CPAL_I2C_DMA_PROGMODEL + /*-------------------------------------------------------------------------- + DMA Deinitialization : if DMA Programming model is selected + ---------------------------------------------------------------------------*/ + if (pDevInitStruct->CPAL_ProgModel == CPAL_PROGMODEL_DMA) + { + CPAL_I2C_HAL_DMADeInit(pDevInitStruct->CPAL_Dev, pDevInitStruct->CPAL_Direction); + + CPAL_LOG("\n\rLOG : I2C Device DMA Deinit"); + } +#endif /* CPAL_I2C_DMA_PROGMODEL */ + + /*-------------------------------------------------------------------------- + Interrupts Deinitialization + ---------------------------------------------------------------------------*/ + CPAL_I2C_HAL_ITDeInit(pDevInitStruct->CPAL_Dev, pDevInitStruct->wCPAL_Options); + + CPAL_LOG("\n\rLOG : I2C Device IT Deinit"); + + /*-------------------------------------------------------------------------- + Structure fields initialization + ----------------------------------------------------------------------------*/ + /* Initialize pDevInitStruct state parameters to their default values */ + pDevInitStruct-> CPAL_State = CPAL_STATE_DISABLED; /* Device Disabled */ + pDevInitStruct-> wCPAL_DevError = CPAL_I2C_ERR_NONE; /* No Device Error */ + pDevInitStruct-> wCPAL_Timeout = ((uint32_t)CPAL_I2C_TIMEOUT_DEFAULT); /* Set timeout value to CPAL_I2C_TIMEOUT_DEFAULT */ + + CPAL_LOG("\n\rLOG :Set State fields to default"); + + /*---------------------------------------------------------------------------- + Deinitialize Timeout Procedure + -----------------------------------------------------------------------------*/ + _CPAL_TIMEOUT_DEINIT(); + + return CPAL_PASS; + } + /* If CPAL_State is BUSY (a transaction is still on going) Exit Init function */ + else + { + CPAL_LOG("\n\rERROR : I2C Device Busy"); + + return CPAL_FAIL; + } +} + + +/** + * @brief Initialize the peripheral structure with default values according + * to the specified parameters in the CPAL_I2CDevTypeDef structure. + * @param pDevInitStruct: Pointer to the peripheral configuration structure. + * @retval CPAL_PASS or CPAL_FAIL. + */ +uint32_t CPAL_I2C_StructInit(CPAL_InitTypeDef* pDevInitStruct) +{ + /* Initialize I2C_InitStructure to their default values */ + I2C_InitStructure.I2C_Timing = 0; /* Initialize the I2C_Timing member */ + I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; /* Initialize the I2C_Mode member */ + I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable; /* Initialize the I2C_AnalogFilter member */ + I2C_InitStructure.I2C_DigitalFilter = 0x00; /* Initialize the I2C_DigitalFilter member */ + I2C_InitStructure.I2C_OwnAddress1 = 0; /* Initialize the I2C_OwnAddress1 member */ + I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; /* Initialize the I2C_Ack member */ + I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; /* Initialize the I2C_AcknowledgedAddress member */ + + /* Initialize pDevInitStruct parameter to their default values */ + pDevInitStruct->CPAL_Direction = CPAL_DIRECTION_TXRX; /* Transmitter and Receiver direction selected */ + pDevInitStruct->CPAL_Mode = CPAL_MODE_MASTER; /* Mode Master selected */ + pDevInitStruct->CPAL_ProgModel = CPAL_PROGMODEL_DMA; /* DMA Programming Model selected */ + pDevInitStruct->pCPAL_TransferTx = pNULL; /* Point pCPAL_TransferTx to a Null pointer */ + pDevInitStruct->pCPAL_TransferRx = pNULL; /* Point pCPAL_TransferRx to a Null pointer */ + pDevInitStruct->CPAL_State = CPAL_STATE_DISABLED; /* Device Disabled */ + pDevInitStruct->wCPAL_DevError = CPAL_I2C_ERR_NONE; /* No Device Error */ + pDevInitStruct->wCPAL_Options = ((uint32_t)0x00000000); /* No Options selected */ + pDevInitStruct->wCPAL_Timeout = ((uint32_t)CPAL_I2C_TIMEOUT_DEFAULT); /* Set timeout value to CPAL_I2C_TIMEOUT_DEFAULT */ + pDevInitStruct->pCPAL_I2C_Struct = &I2C_InitStructure; /* Point to I2C_InitStructure (with default values) */ + + CPAL_LOG("\n\r\n\rLOG : I2C Device Structure set to Default Value"); + + return CPAL_PASS; +} + +#if defined (CPAL_I2C_MASTER_MODE) || ! defined (CPAL_I2C_LISTEN_MODE) + +/** + * @brief Allows to send a data or a buffer of data through the peripheral to + * a selected device in a selected location address. + * @param pDevInitStruct: Pointer to the peripheral configuration structure. + * @retval CPAL_PASS or CPAL_FAIL. + */ +uint32_t CPAL_I2C_Write(CPAL_InitTypeDef* pDevInitStruct) +{ + CR2_tmp = 0; + + /* Check I2C State: + - If busy --> exit Write operation + - If disabled --> exit Write operation + - If error --> exit Write operation + - If ready --> + *- Update CPAL_State to CPAL_STATE_BUSY + *- If CPAL_OPT_I2C_NOSTOP_MODE is not selected : + - Check if device is busy. + *- Update CPAL_State to CPAL_STATE_READY_TX + *- If DMA Prog Model : + - Configure and enable DMA + *- If Master mode : + - If 10Bit Mode : Enable ADD10 + - Configure Slave address + *- If Memory Address mode (master) + - Send target and memory address + *- Update CPAL_State to CPAL_STATE_BUSY_TX + *- If Master mode : + - Configure AUTOEND, RELOAD and NBYTES + - If Interrupt Prog Model : + - Generate start and enable interrupts + - If DMA Prog Model : + - Enable TX DMA request + - Generate start and enable interrupts + *- If Slave mode : + - If Interrupt Prog Model : + - Enable interrupts + - If DMA Prog Model : + - Enable TX DMA request + - Enable interrupts */ + + CPAL_LOG("\n\r\n\rLOG : I2C Device Write OP"); + + /* If Device is Busy (a transaction is still on going) Exit Write function */ + if (((pDevInitStruct->CPAL_State & CPAL_STATE_BUSY) != 0) + || (pDevInitStruct->CPAL_State == CPAL_STATE_READY_TX) + || (pDevInitStruct->CPAL_State == CPAL_STATE_READY_RX)) + { + CPAL_LOG("\n\rERROR : I2C Device Busy"); + + return CPAL_FAIL; + } + /* If CPAL_State is CPAL_STATE_DISABLED (device is not initialized) Exit Write function */ + else if (pDevInitStruct->CPAL_State == CPAL_STATE_DISABLED) + { + CPAL_LOG("\n\rERROR : I2C Device Not Initialized"); + + return CPAL_FAIL; + } + /* If CPAL_State is CPAL_STATE_ERROR (Error occurred ) */ + else if (pDevInitStruct->CPAL_State == CPAL_STATE_ERROR) + { + CPAL_LOG("\n\rERROR : I2C Device Error"); + + return CPAL_FAIL; + } + /* If CPAL_State is CPAL_STATE_READY ( Start Communication )*/ + else + { + /* Update CPAL_State to CPAL_STATE_BUSY */ + pDevInitStruct->CPAL_State = CPAL_STATE_BUSY; + + /* IF CPAL_OPT_I2C_NOSTOP_MODE is not selected */ + if ((pDevInitStruct->wCPAL_Options & CPAL_OPT_I2C_NOSTOP_MODE) == 0) + { + /* Wait until BUSY flag is reset */ + __CPAL_I2C_TIMEOUT(!(__CPAL_I2C_HAL_GET_BUSY(pDevInitStruct->CPAL_Dev)), CPAL_I2C_TIMEOUT_BUSY); + } + + /* Update CPAL_State to CPAL_STATE_READY_TX */ + pDevInitStruct->CPAL_State = CPAL_STATE_READY_TX; + CPAL_LOG("\n\rLOG : I2C Device Ready TX"); + +#ifdef CPAL_I2C_DMA_PROGMODEL + /* If DMA programming model */ + if (pDevInitStruct->CPAL_ProgModel == CPAL_PROGMODEL_DMA) + { + /* Configure and enable TX DMA channel */ + I2C_Enable_DMA(pDevInitStruct, CPAL_DIRECTION_TX); + } +#endif /* CPAL_I2C_DMA_PROGMODEL */ + +#ifdef CPAL_I2C_MASTER_MODE + /* If master mode selected */ + if (pDevInitStruct->CPAL_Mode == CPAL_MODE_MASTER) + { + #ifdef CPAL_I2C_10BIT_ADDR_MODE + /* If 10 Bit addressing mode */ + if (pDevInitStruct->pCPAL_I2C_Struct->I2C_AcknowledgedAddress == I2C_AcknowledgedAddress_10bit) + { + /* Enable 10Bit addressing mode */ + CR2_tmp |= I2C_CR2_ADD10; + } + #endif /* CPAL_I2C_10BIT_ADDR_MODE */ + + /* Configure slave address */ + CR2_tmp |= (uint32_t)((pDevInitStruct->pCPAL_TransferTx->wAddr1) & 0x000003FF); + } + + #ifdef CPAL_I2C_MEM_ADDR + /* If CPAL_OPT_NO_MEM_ADDR is not selected and master mode selected */ + if (((pDevInitStruct->wCPAL_Options & CPAL_OPT_NO_MEM_ADDR) == 0) + && (pDevInitStruct->CPAL_Mode == CPAL_MODE_MASTER )) + { + CPAL_LOG("\n\rLOG : I2C Device Master Mem Addr Mode"); + + /* Enable reload */ + CR2_tmp |= I2C_CR2_RELOAD; + + /* Disable error interrupt to manage error without interrupt */ + __CPAL_I2C_HAL_DISABLE_ERRIT(pDevInitStruct->CPAL_Dev); + + /* If 8 Bit register mode */ + if ((pDevInitStruct->wCPAL_Options & CPAL_OPT_16BIT_REG) == 0) + { + /* Configure Nbytes */ + CR2_tmp |= (uint32_t)((uint32_t)(1) << 16); + + /* Update CR2 Register */ + __CPAL_I2C_HAL_CR2_UPDATE(pDevInitStruct->CPAL_Dev, CR2_tmp); + + /* Generate start */ + __CPAL_I2C_HAL_START(pDevInitStruct->CPAL_Dev); + + /* Wait until TXIS flag is set or NACK is set */ + __CPAL_I2C_TIMEOUT((__CPAL_I2C_HAL_GET_TXIS(pDevInitStruct->CPAL_Dev) || __CPAL_I2C_HAL_GET_NACK(pDevInitStruct->CPAL_Dev)), CPAL_I2C_TIMEOUT_TXIS); + + /* If acknowledge failure detected generate stop and abort communication */ + if (__CPAL_I2C_HAL_GET_NACK(pDevInitStruct->CPAL_Dev)) + { + /* Generate stop if autoend option is disabled */ + if((CPAL_I2C_DEVICE[(pDevInitStruct->CPAL_Dev)]->CR2 & I2C_CR2_AUTOEND) != I2C_CR2_AUTOEND) + { + /* Generate stop */ + __CPAL_I2C_HAL_STOP(pDevInitStruct->CPAL_Dev); + } + + /* Clear NACK flag */ + __CPAL_I2C_HAL_CLEAR_NACK(pDevInitStruct->CPAL_Dev); + + /* Wait until STOP flag is set */ + __CPAL_I2C_TIMEOUT(__CPAL_I2C_HAL_GET_STOP(pDevInitStruct->CPAL_Dev), CPAL_I2C_TIMEOUT_BUSY); + + /* Clear STOP flag */ + __CPAL_I2C_HAL_CLEAR_STOP(pDevInitStruct->CPAL_Dev); + + /* Update wCPAL_DevError */ + pDevInitStruct->wCPAL_DevError = CPAL_I2C_ERR_AF; + + /* Set CPAL_State to CPAL_STATE_ERROR */ + pDevInitStruct->CPAL_State = CPAL_STATE_ERROR; + + return CPAL_FAIL; + } + + /* Send register address */ + __CPAL_I2C_HAL_SEND(pDevInitStruct->CPAL_Dev, (uint8_t)(pDevInitStruct->pCPAL_TransferTx->wAddr2)); + } + #ifdef CPAL_16BIT_REG_OPTION + /* If 16 Bit register mode */ + else + { + /* Configure Nbytes */ + CR2_tmp |= (uint32_t)((uint32_t)(2) << 16); + + /* Update CR2 Register */ + __CPAL_I2C_HAL_CR2_UPDATE(pDevInitStruct->CPAL_Dev, CR2_tmp); + + /* Generate start */ + __CPAL_I2C_HAL_START(pDevInitStruct->CPAL_Dev); + + /* Wait until TXIS flag is set or NACK is set */ + __CPAL_I2C_TIMEOUT((__CPAL_I2C_HAL_GET_TXIS(pDevInitStruct->CPAL_Dev) || __CPAL_I2C_HAL_GET_NACK(pDevInitStruct->CPAL_Dev)), CPAL_I2C_TIMEOUT_TXIS); + + /* If acknowledge failure detected generate stop and abort communication */ + if (__CPAL_I2C_HAL_GET_NACK(pDevInitStruct->CPAL_Dev)) + { + /* Generate stop if autoend option is disabled */ + if((CPAL_I2C_DEVICE[(pDevInitStruct->CPAL_Dev)]->CR2 & I2C_CR2_AUTOEND) != I2C_CR2_AUTOEND) + { + /* Generate stop */ + __CPAL_I2C_HAL_STOP(pDevInitStruct->CPAL_Dev); + } + + /* Clear NACK flag */ + __CPAL_I2C_HAL_CLEAR_NACK(pDevInitStruct->CPAL_Dev); + + /* Wait until STOP flag is set */ + __CPAL_I2C_TIMEOUT(__CPAL_I2C_HAL_GET_STOP(pDevInitStruct->CPAL_Dev), CPAL_I2C_TIMEOUT_BUSY); + + /* Clear STOP flag */ + __CPAL_I2C_HAL_CLEAR_STOP(pDevInitStruct->CPAL_Dev); + + /* Update wCPAL_DevError */ + pDevInitStruct->wCPAL_DevError = CPAL_I2C_ERR_AF; + + /* Set CPAL_State to CPAL_STATE_ERROR */ + pDevInitStruct->CPAL_State = CPAL_STATE_ERROR; + + return CPAL_FAIL; + } + + /* Send register address (MSB) */ + __CPAL_I2C_HAL_SEND(pDevInitStruct->CPAL_Dev, (uint8_t)(((pDevInitStruct->pCPAL_TransferTx->wAddr2)& 0xFF00) >> 8)); + + /* Wait until TXIS flag is set or NACK is set */ + __CPAL_I2C_TIMEOUT((__CPAL_I2C_HAL_GET_TXIS(pDevInitStruct->CPAL_Dev) || __CPAL_I2C_HAL_GET_NACK(pDevInitStruct->CPAL_Dev)), CPAL_I2C_TIMEOUT_TXIS); + + /* If acknowledge failure detected generate stop and abort communication */ + if (__CPAL_I2C_HAL_GET_NACK(pDevInitStruct->CPAL_Dev)) + { + /* Generate stop if autoend option is disabled */ + if((CPAL_I2C_DEVICE[(pDevInitStruct->CPAL_Dev)]->CR2 & I2C_CR2_AUTOEND) != I2C_CR2_AUTOEND) + { + /* Generate stop */ + __CPAL_I2C_HAL_STOP(pDevInitStruct->CPAL_Dev); + } + + /* Clear NACK flag */ + __CPAL_I2C_HAL_CLEAR_NACK(pDevInitStruct->CPAL_Dev); + + /* Wait until STOP flag is set */ + __CPAL_I2C_TIMEOUT(__CPAL_I2C_HAL_GET_STOP(pDevInitStruct->CPAL_Dev), CPAL_I2C_TIMEOUT_BUSY); + + /* Clear STOP flag */ + __CPAL_I2C_HAL_CLEAR_STOP(pDevInitStruct->CPAL_Dev); + + /* Update wCPAL_DevError */ + pDevInitStruct->wCPAL_DevError = CPAL_I2C_ERR_AF; + + /* Set CPAL_State to CPAL_STATE_ERROR */ + pDevInitStruct->CPAL_State = CPAL_STATE_ERROR; + + return CPAL_FAIL; + } + + /* Send register address (LSB) */ + __CPAL_I2C_HAL_SEND(pDevInitStruct->CPAL_Dev, (uint8_t)((pDevInitStruct->pCPAL_TransferTx->wAddr2)& 0x00FF)); + } + #endif /* CPAL_16BIT_REG_OPTION */ + + /* If I2C ERR Interrupt Option Bit not selected */ + if ((pDevInitStruct->wCPAL_Options & CPAL_OPT_I2C_ERRIT_DISABLE) == 0) + { + /* Enable I2C Error Interrupts */ + __CPAL_I2C_HAL_ENABLE_ERRIT(pDevInitStruct->CPAL_Dev); + } + + /* Wait until TCR flag is set */ + __CPAL_I2C_TIMEOUT(__CPAL_I2C_HAL_GET_TCR(pDevInitStruct->CPAL_Dev), CPAL_I2C_TIMEOUT_TCR); + + /* Set Nbytes to zero */ + CR2_tmp &= ~I2C_CR2_NBYTES; + } + #endif /* CPAL_I2C_MEM_ADDR */ +#endif /* CPAL_I2C_MASTER_MODE */ + + /* Update CPAL_State to CPAL_STATE_BUSY_TX */ + pDevInitStruct->CPAL_State = CPAL_STATE_BUSY_TX; + CPAL_LOG("\n\rLOG : I2C Device Busy TX"); + +#ifdef CPAL_I2C_MASTER_MODE + /* If master mode selected */ + if (pDevInitStruct->CPAL_Mode == CPAL_MODE_MASTER) + { + CPAL_LOG("\n\rLOG : I2C Device Master"); + + /* If automatic end mode is selected */ + if ((pDevInitStruct->wCPAL_Options & CPAL_OPT_I2C_AUTOMATIC_END) != 0) + { + /* Enable automatic end mode */ + CR2_tmp |= I2C_CR2_AUTOEND; + } + + /* If number of data is equal or lower than 255 bytes */ + if (pDevInitStruct->pCPAL_TransferTx->wNumData <= 0xFF ) + { + /* Update Num_Data */ + Num_Data = pDevInitStruct->pCPAL_TransferTx->wNumData; + + /* Set Nbytes to wNumData */ + CR2_tmp |= (uint32_t)((uint32_t)(Num_Data) << 16); + + /* Disable reload */ + CR2_tmp &= ~I2C_CR2_RELOAD; + } + /* If number of data is greater than 255 bytes */ + else + { + /* Set Nbytes to 255 */ + CR2_tmp |= (uint32_t)((uint32_t)(255) << 16); + + /* Enable reload */ + CR2_tmp |= I2C_CR2_RELOAD; + } + + /* If CPAL_OPT_NO_MEM_ADDR is selected */ + if ((pDevInitStruct->wCPAL_Options & CPAL_OPT_NO_MEM_ADDR) != 0) + { + /* Generate start */ + CR2_tmp |= I2C_CR2_START; + } + + /* Update CR2 Register */ + __CPAL_I2C_HAL_CR2_UPDATE(pDevInitStruct->CPAL_Dev, CR2_tmp); + + /* If interrupt programming model */ + if (pDevInitStruct->CPAL_ProgModel == CPAL_PROGMODEL_INTERRUPT) + { + CPAL_LOG("\n\rLOG : I2C Device IT Enabled"); + + /* Enable master interrupts */ + __CPAL_I2C_HAL_ENABLE_MASTER_TXIT(pDevInitStruct->CPAL_Dev); + } + /* If DMA programming model */ + else + { + CPAL_LOG("\n\rLOG : I2C Device DMA TX Enabled"); + + /* Enable TX DMA request */ + __CPAL_I2C_HAL_ENABLE_TXDMAREQ(pDevInitStruct->CPAL_Dev); + + /* Enable master interrupts */ + __CPAL_I2C_HAL_ENABLE_MASTER_IT(pDevInitStruct->CPAL_Dev); + } + } + /* If slave mode selected */ + else +#endif /* CPAL_I2C_MASTER_MODE */ + { +#ifdef CPAL_I2C_SLAVE_MODE + CPAL_LOG("\n\rLOG : I2C Device Slave"); + + /* If NACK Slave Own Address option bit selected */ + if ((pDevInitStruct->wCPAL_Options & CPAL_OPT_I2C_NACK_ADD) != 0) + { + /* Enable Acknowledgement of Own address */ + __CPAL_I2C_HAL_ENABLE_DEV(pDevInitStruct->CPAL_Dev); + } + + /* If interrupt programming model */ + if (pDevInitStruct->CPAL_ProgModel == CPAL_PROGMODEL_INTERRUPT) + { + CPAL_LOG("\n\rLOG : I2C Device IT Enabled"); + + /* Enable slave interrupts */ + __CPAL_I2C_HAL_ENABLE_SLAVE_TXIT(pDevInitStruct->CPAL_Dev); + } + /* If DMA programming model */ + else + { + CPAL_LOG("\n\rLOG : I2C Device DMA TX Enabled"); + + /* Enable TX DMA request */ + __CPAL_I2C_HAL_ENABLE_TXDMAREQ(pDevInitStruct->CPAL_Dev); + + /* Enable slave interrupts */ + __CPAL_I2C_HAL_ENABLE_SLAVE_IT(pDevInitStruct->CPAL_Dev); + } +#endif /* CPAL_I2C_SLAVE_MODE */ + } + } + return CPAL_PASS; +} + + + +/** + * @brief Allows to receive a data or a buffer of data through the peripheral + * from a selected device in a selected location address. + * @param pDevInitStruct: Pointer to the peripheral configuration structure. + * @retval CPAL_PASS or CPAL_FAIL. + */ +uint32_t CPAL_I2C_Read(CPAL_InitTypeDef* pDevInitStruct) +{ + CR2_tmp = 0; + + /* Check I2C State: + - If busy --> exit Read operation + - If disabled --> exit Read operation + - If error --> exit Read operation + - If ready --> + *- Update CPAL_State to CPAL_STATE_BUSY + *- If CPAL_OPT_I2C_NOSTOP_MODE is not selected : + - Check if device is busy + *- Update CPAL_State to CPAL_STATE_READY_RX + *- If DMA Prog Model : + - Configure and enable DMA + *- If Master mode : + - If 10Bit Mode : Enable ADD10 + - Configure Slave address + *- If Memory Address mode (master) + - Send target and memory address + *- Update CPAL_State to CPAL_STATE_BUSY_RX + *- If Master mode : + - Configure HEADR10, AUTOEND, RELOAD and NBYTES + - If Interrupt Prog Model : + - Generate start and enable interrupts + - If DMA Prog Model : + - Enable RX DMA request + - Generate start and enable interrupts + *- If Slave mode : + - If Interrupt Prog Model : + - Enable interrupts + - If DMA Prog Model : + - Enable RX DMA request + - Enable interrupts */ + + CPAL_LOG("\n\r\n\rLOG : I2C Device Perform Read OP"); + + /* If Device is Busy (a transaction is still on going) Exit Read function */ + if (((pDevInitStruct->CPAL_State & CPAL_STATE_BUSY) != 0) + || (pDevInitStruct->CPAL_State == CPAL_STATE_READY_TX) + || (pDevInitStruct->CPAL_State == CPAL_STATE_READY_RX)) + { + CPAL_LOG("\n\rERROR : I2C Device Busy"); + + return CPAL_FAIL; + } + /* If CPAL_State is CPAL_STATE_DISABLED (device is not initialized) Exit Read function */ + else if (pDevInitStruct->CPAL_State == CPAL_STATE_DISABLED) + { + CPAL_LOG("\n\rERROR : I2C Device Not Initialized"); + + return CPAL_FAIL; + } + /* If CPAL_State is CPAL_STATE_ERROR (Error occurred ) */ + else if (pDevInitStruct->CPAL_State == CPAL_STATE_ERROR) + { + CPAL_LOG("\n\rERROR : I2C Device Error"); + + return CPAL_FAIL; + } + /* If CPAL_State is CPAL_STATE_READY */ + else + { + /* Update CPAL_State to CPAL_STATE_BUSY */ + pDevInitStruct->CPAL_State = CPAL_STATE_BUSY; + + /* If CPAL_OPT_I2C_NOSTOP_MODE is not selected */ + if ((pDevInitStruct->wCPAL_Options & CPAL_OPT_I2C_NOSTOP_MODE) == 0) + { + /* Wait until BUSY flag is reset */ + __CPAL_I2C_TIMEOUT(!(__CPAL_I2C_HAL_GET_BUSY(pDevInitStruct->CPAL_Dev)), CPAL_I2C_TIMEOUT_BUSY); + } + + /* Update CPAL_State to CPAL_STATE_READY_RX */ + pDevInitStruct->CPAL_State = CPAL_STATE_READY_RX; + CPAL_LOG("\n\rLOG : I2C Device Ready RX"); + +#ifdef CPAL_I2C_DMA_PROGMODEL + /* If DMA programming model */ + if (pDevInitStruct->CPAL_ProgModel == CPAL_PROGMODEL_DMA) + { + /* Configure and enable RX DMA channel */ + I2C_Enable_DMA(pDevInitStruct, CPAL_DIRECTION_RX); + } +#endif /* CPAL_I2C_DMA_PROGMODEL */ + +#ifdef CPAL_I2C_MASTER_MODE + /* If master mode selected */ + if (pDevInitStruct->CPAL_Mode == CPAL_MODE_MASTER) + { + #ifdef CPAL_I2C_10BIT_ADDR_MODE + /* If 10 Bit addressing mode */ + if (pDevInitStruct->pCPAL_I2C_Struct->I2C_AcknowledgedAddress == I2C_AcknowledgedAddress_10bit) + { + /* Enable 10Bit addressing mode */ + CR2_tmp |= I2C_CR2_ADD10; + } + #endif /* CPAL_I2C_10BIT_ADDR_MODE */ + + /* Configure slave address */ + CR2_tmp |= (uint32_t)((pDevInitStruct->pCPAL_TransferRx->wAddr1) & 0x000003FF); + } + + #ifdef CPAL_I2C_MEM_ADDR + /* If No Memory Address option bit is not selected and master mode selected */ + if (((pDevInitStruct->wCPAL_Options & CPAL_OPT_NO_MEM_ADDR) == 0) + && (pDevInitStruct->CPAL_Mode == CPAL_MODE_MASTER )) + { + CPAL_LOG("\n\rLOG : I2C Device Master Mem Addr Mode"); + + /* Disable error interrupt to manage error without interrupt */ + __CPAL_I2C_HAL_DISABLE_ERRIT(pDevInitStruct->CPAL_Dev); + + /* If 8 Bit register mode */ + if ((pDevInitStruct->wCPAL_Options & CPAL_OPT_16BIT_REG) == 0) + { + /* Configure Nbytes */ + CR2_tmp |= (uint32_t)((uint32_t)(1) << 16); + + /* Update CR2 Register */ + __CPAL_I2C_HAL_CR2_UPDATE(pDevInitStruct->CPAL_Dev, CR2_tmp); + + /* Generate start */ + __CPAL_I2C_HAL_START(pDevInitStruct->CPAL_Dev); + + /* Wait until TXIS flag is set or NACK is set */ + __CPAL_I2C_TIMEOUT((__CPAL_I2C_HAL_GET_TXIS(pDevInitStruct->CPAL_Dev) || __CPAL_I2C_HAL_GET_NACK(pDevInitStruct->CPAL_Dev)), CPAL_I2C_TIMEOUT_TXIS); + + /* If acknowledge failure detected generate stop and abort communication */ + if (__CPAL_I2C_HAL_GET_NACK(pDevInitStruct->CPAL_Dev)) + { + /* Generate stop if autoend option is disabled */ + if((CPAL_I2C_DEVICE[(pDevInitStruct->CPAL_Dev)]->CR2 & I2C_CR2_AUTOEND) != I2C_CR2_AUTOEND) + { + /* Generate stop */ + __CPAL_I2C_HAL_STOP(pDevInitStruct->CPAL_Dev); + } + + /* Clear NACK flag */ + __CPAL_I2C_HAL_CLEAR_NACK(pDevInitStruct->CPAL_Dev); + + /* Wait until STOP flag is set */ + __CPAL_I2C_TIMEOUT(__CPAL_I2C_HAL_GET_STOP(pDevInitStruct->CPAL_Dev), CPAL_I2C_TIMEOUT_BUSY); + + /* Clear STOP flag */ + __CPAL_I2C_HAL_CLEAR_STOP(pDevInitStruct->CPAL_Dev); + + /* Update wCPAL_DevError */ + pDevInitStruct->wCPAL_DevError = CPAL_I2C_ERR_AF; + + /* Set CPAL_State to CPAL_STATE_ERROR */ + pDevInitStruct->CPAL_State = CPAL_STATE_ERROR; + + return CPAL_FAIL; + } + + /* Send register address */ + __CPAL_I2C_HAL_SEND(pDevInitStruct->CPAL_Dev, (uint8_t)(pDevInitStruct->pCPAL_TransferRx->wAddr2)); + } + #ifdef CPAL_16BIT_REG_OPTION + /* If 16 Bit register mode */ + else + { + /* Configure Nbytes */ + CR2_tmp |= (uint32_t)((uint32_t)(2) << 16); + + /* Update CR2 Register */ + __CPAL_I2C_HAL_CR2_UPDATE(pDevInitStruct->CPAL_Dev, CR2_tmp); + + /* Generate start */ + __CPAL_I2C_HAL_START(pDevInitStruct->CPAL_Dev); + + /* Wait until TXIS flag is set or NACK is set */ + __CPAL_I2C_TIMEOUT((__CPAL_I2C_HAL_GET_TXIS(pDevInitStruct->CPAL_Dev) || __CPAL_I2C_HAL_GET_NACK(pDevInitStruct->CPAL_Dev)), CPAL_I2C_TIMEOUT_TXIS); + + /* If acknowledge failure detected generate stop and abort communication */ + if (__CPAL_I2C_HAL_GET_NACK(pDevInitStruct->CPAL_Dev)) + { + /* Generate stop if autoend option is disabled */ + if((CPAL_I2C_DEVICE[(pDevInitStruct->CPAL_Dev)]->CR2 & I2C_CR2_AUTOEND) != I2C_CR2_AUTOEND) + { + /* Generate stop */ + __CPAL_I2C_HAL_STOP(pDevInitStruct->CPAL_Dev); + } + + /* Clear NACK flag */ + __CPAL_I2C_HAL_CLEAR_NACK(pDevInitStruct->CPAL_Dev); + + /* Wait until STOP flag is set */ + __CPAL_I2C_TIMEOUT(__CPAL_I2C_HAL_GET_STOP(pDevInitStruct->CPAL_Dev), CPAL_I2C_TIMEOUT_BUSY); + + /* Clear STOP flag */ + __CPAL_I2C_HAL_CLEAR_STOP(pDevInitStruct->CPAL_Dev); + + /* Update wCPAL_DevError */ + pDevInitStruct->wCPAL_DevError = CPAL_I2C_ERR_AF; + + /* Set CPAL_State to CPAL_STATE_ERROR */ + pDevInitStruct->CPAL_State = CPAL_STATE_ERROR; + + return CPAL_FAIL; + } + + /* Send register address (MSB) */ + __CPAL_I2C_HAL_SEND(pDevInitStruct->CPAL_Dev, (uint8_t)(((pDevInitStruct->pCPAL_TransferRx->wAddr2)& 0xFF00) >> 8)); + + /* Wait until TXIS flag is set or NACK is set */ + __CPAL_I2C_TIMEOUT((__CPAL_I2C_HAL_GET_TXIS(pDevInitStruct->CPAL_Dev) || __CPAL_I2C_HAL_GET_NACK(pDevInitStruct->CPAL_Dev)), CPAL_I2C_TIMEOUT_TXIS); + + /* If acknowledge failure detected generate stop and abort communication */ + if (__CPAL_I2C_HAL_GET_NACK(pDevInitStruct->CPAL_Dev)) + { + /* Generate stop if autoend option is disabled */ + if((CPAL_I2C_DEVICE[(pDevInitStruct->CPAL_Dev)]->CR2 & I2C_CR2_AUTOEND) != I2C_CR2_AUTOEND) + { + /* Generate stop */ + __CPAL_I2C_HAL_STOP(pDevInitStruct->CPAL_Dev); + } + + /* Clear NACK flag */ + __CPAL_I2C_HAL_CLEAR_NACK(pDevInitStruct->CPAL_Dev); + + /* Wait until STOP flag is set */ + __CPAL_I2C_TIMEOUT(__CPAL_I2C_HAL_GET_STOP(pDevInitStruct->CPAL_Dev), CPAL_I2C_TIMEOUT_BUSY); + + /* Clear STOP flag */ + __CPAL_I2C_HAL_CLEAR_STOP(pDevInitStruct->CPAL_Dev); + + /* Update wCPAL_DevError */ + pDevInitStruct->wCPAL_DevError = CPAL_I2C_ERR_AF; + + /* Set CPAL_State to CPAL_STATE_ERROR */ + pDevInitStruct->CPAL_State = CPAL_STATE_ERROR; + + return CPAL_FAIL; + } + + /* Send register address (LSB) */ + __CPAL_I2C_HAL_SEND(pDevInitStruct->CPAL_Dev, (uint8_t)((pDevInitStruct->pCPAL_TransferRx->wAddr2)& 0x00FF)); + } + #endif /* CPAL_16BIT_REG_OPTION */ + + /* If I2C ERR Interrupt Option Bit not selected */ + if ((pDevInitStruct->wCPAL_Options & CPAL_OPT_I2C_ERRIT_DISABLE) == 0) + { + /* Enable I2C Error Interrupts */ + __CPAL_I2C_HAL_ENABLE_ERRIT(pDevInitStruct->CPAL_Dev); + } + + /* Wait until TC flag is set */ + __CPAL_I2C_TIMEOUT(__CPAL_I2C_HAL_GET_TC(pDevInitStruct->CPAL_Dev), CPAL_I2C_TIMEOUT_TC); + + /* Set Nbytes to zero */ + CR2_tmp &= ~I2C_CR2_NBYTES; + + } + #endif /* CPAL_I2C_MEM_ADDR */ +#endif /* CPAL_I2C_MASTER_MODE */ + + /* Update CPAL_State to CPAL_STATE_BUSY_RX */ + pDevInitStruct->CPAL_State = CPAL_STATE_BUSY_RX; + CPAL_LOG("\n\rLOG : I2C Device Busy RX"); + +#ifdef CPAL_I2C_MASTER_MODE + /* If master mode selected */ + if (pDevInitStruct->CPAL_Mode == CPAL_MODE_MASTER) + { + CPAL_LOG("\n\rLOG : I2C Device Master"); + + /* Enable transfer request */ + CR2_tmp |= I2C_CR2_RD_WRN; + + #ifdef CPAL_I2C_10BIT_ADDR_MODE + /* If 10 Bit addressing mode */ + if (pDevInitStruct->pCPAL_I2C_Struct->I2C_AcknowledgedAddress == I2C_AcknowledgedAddress_10bit) + { + /* If CPAL_OPT_NO_MEM_ADDR is not selected and CPAL_OPT_I2C_10BIT_HEADR option enabled */ + if (((pDevInitStruct->wCPAL_Options & CPAL_OPT_I2C_10BIT_HEADR) != 0) || ((pDevInitStruct->wCPAL_Options & CPAL_OPT_NO_MEM_ADDR) == 0)) + { + /* Disable 10Bit addressing complete sequence for Read */ + CR2_tmp |= I2C_CR2_HEAD10R; + } + } + #endif /* CPAL_I2C_10BIT_ADDR_MODE */ + + /* If automatic end mode is selected */ + if ((pDevInitStruct->wCPAL_Options & CPAL_OPT_I2C_AUTOMATIC_END) != 0) + { + /* Enable automatic end mode */ + CR2_tmp |= I2C_CR2_AUTOEND; + } + + /* If number of data is equal or lower than 255 bytes */ + if (pDevInitStruct->pCPAL_TransferRx->wNumData <= 0xFF ) + { + /* Update Num_Data */ + Num_Data = pDevInitStruct->pCPAL_TransferRx->wNumData; + + /* Set Nbytes to wNumData */ + CR2_tmp |= (uint32_t)((uint32_t)(Num_Data) << 16); + + /* Disable reload */ + CR2_tmp &= ~I2C_CR2_RELOAD; + } + /* If number of data is greater than 255 bytes */ + else + { + /* Set Nbytes to wNumData */ + CR2_tmp |= (uint32_t)((uint32_t)(255) << 16); + + /* Enaable reload */ + CR2_tmp |= I2C_CR2_RELOAD; + } + + /* Generate start */ + CR2_tmp |= I2C_CR2_START; + + /* If interrupt programming model */ + if (pDevInitStruct->CPAL_ProgModel == CPAL_PROGMODEL_INTERRUPT) + { + CPAL_LOG("\n\rLOG : I2C Device IT Enabled"); + + /* Update CR2 Register */ + __CPAL_I2C_HAL_CR2_UPDATE(pDevInitStruct->CPAL_Dev, CR2_tmp); + + /* Enable master interrupts */ + __CPAL_I2C_HAL_ENABLE_MASTER_RXIT(pDevInitStruct->CPAL_Dev); + } + /* If DMA programming model */ + else + { + CPAL_LOG("\n\rLOG : I2C Device DMA RX Enabled"); + + /* Enable RX DMA request */ + __CPAL_I2C_HAL_ENABLE_RXDMAREQ(pDevInitStruct->CPAL_Dev); + + /* Update CR2 Register */ + __CPAL_I2C_HAL_CR2_UPDATE(pDevInitStruct->CPAL_Dev, CR2_tmp); + + /* Enable master interrupt */ + __CPAL_I2C_HAL_ENABLE_MASTER_IT(pDevInitStruct->CPAL_Dev); + } + } + /* If slave mode selected */ + else +#endif /* CPAL_I2C_MASTER_MODE */ + { +#ifdef CPAL_I2C_SLAVE_MODE + CPAL_LOG("\n\rLOG : I2C Device Slave"); + + /* If NACK Slave Own Address option bit selected */ + if ((pDevInitStruct->wCPAL_Options & CPAL_OPT_I2C_NACK_ADD) != 0) + { + /* Enable Acknowledgement of Own address */ + __CPAL_I2C_HAL_ENABLE_DEV(pDevInitStruct->CPAL_Dev); + } + + /* If interrupt programming model */ + if (pDevInitStruct->CPAL_ProgModel == CPAL_PROGMODEL_INTERRUPT) + { + CPAL_LOG("\n\rLOG : I2C Device IT Enabled"); + + /* Enable slave interrupts */ + __CPAL_I2C_HAL_ENABLE_SLAVE_RXIT(pDevInitStruct->CPAL_Dev); + } + /* If DMA programming model */ + else + { + CPAL_LOG("\n\rLOG : I2C Device DMA RX Enabled"); + + /* Enable RX DMA request */ + __CPAL_I2C_HAL_ENABLE_RXDMAREQ(pDevInitStruct->CPAL_Dev); + + /* Enable slave interrupt */ + __CPAL_I2C_HAL_ENABLE_SLAVE_IT(pDevInitStruct->CPAL_Dev); + } +#endif /* CPAL_I2C_SLAVE_MODE */ + } + } + return CPAL_PASS; +} +#endif /* CPAL_I2C_MASTER_MODE || ! CPAL_I2C_LISTEN_MODE */ + +#if defined (CPAL_I2C_LISTEN_MODE) && defined (CPAL_I2C_SLAVE_MODE) +/** + * @brief Allows slave device to start a communication without knowing in advance + * the nature of the operation (read or write). Slave waits until it receive + * its own address.CPAL_I2C_SLAVE_READ_UserCallback is called for a read request + * and CPAL_I2C_SLAVE_WRITE_UserCallback for a write request in I2C_SLAVE_ADDR_Handle. + * User must implement inorder to configure DMA, interrupts and transfer parameters. + * @param pDevInitStruct: Pointer to the peripheral configuration structure. + * @retval CPAL_PASS or CPAL_FAIL. + */ +uint32_t CPAL_I2C_Listen(CPAL_InitTypeDef* pDevInitStruct) +{ + /* Check I2C State: + - If busy --> exit operation + - If disabled --> exit operation + - If error --> exit operation + - If ready --> + - Enable Event Interrupt */ + + CPAL_LOG("\n\r\n\rLOG : I2C Device in listen mode"); + + /* If Device is Busy (a transaction is still on going) Exit function */ + if (((pDevInitStruct->CPAL_State & CPAL_STATE_BUSY) != 0) + || (pDevInitStruct->CPAL_State == CPAL_STATE_READY_TX) + || (pDevInitStruct->CPAL_State == CPAL_STATE_READY_RX)) + { + CPAL_LOG("\n\rERROR : I2C Device Busy"); + + return CPAL_FAIL; + } + /* If CPAL_State is CPAL_STATE_DISABLED (device is not initialized) Exit function */ + else if (pDevInitStruct->CPAL_State == CPAL_STATE_DISABLED) + { + CPAL_LOG("\n\rERROR : I2C Device Not Initialized"); + + return CPAL_FAIL; + } + /* If CPAL_State is CPAL_STATE_ERROR (Error occurred ) */ + else if (pDevInitStruct->CPAL_State == CPAL_STATE_ERROR) + { + CPAL_LOG("\n\rERROR : I2C Device Error"); + + return CPAL_FAIL; + } + /* If CPAL_State is CPAL_STATE_READY */ + else + { + + /* If NACK Slave Own Address option bit selected */ + if ((pDevInitStruct->wCPAL_Options & CPAL_OPT_I2C_NACK_ADD) != 0) + { + /* Enable Acknowledgement of Own address */ + __CPAL_I2C_HAL_ENABLE_DEV(pDevInitStruct->CPAL_Dev); + } + + /* Set device to slave mode */ + pDevInitStruct->CPAL_Mode = CPAL_MODE_SLAVE; + + /* Update CPAL_State to CPAL_STATE_BUSY */ + pDevInitStruct->CPAL_State = CPAL_STATE_BUSY; + + CPAL_LOG("\n\rLOG : I2C Device EVT IT Enabled"); + + /* Enable Slave Interrupts*/ + __CPAL_I2C_HAL_ENABLE_SLAVE_IT(pDevInitStruct->CPAL_Dev); + } + + return CPAL_PASS; +} +#endif /* CPAL_I2C_LISTEN_MODE && CPAL_I2C_SLAVE_MODE */ + +/** + * @brief Wait until target device is ready for communication (This function is + * used with Memory devices). + * @param pDevInitStruct: Pointer to the peripheral configuration structure. + * @retval CPAL_PASS or CPAL_FAIL. + */ +uint32_t CPAL_I2C_IsDeviceReady(CPAL_InitTypeDef* pDevInitStruct) +{ + CR2_tmp = 0; + + CPAL_LOG("\n\r\n\rLOG : Wait until I2C Device is Ready"); + + /* Set CPAL_State to CPAL_STATE_BUSY */ + pDevInitStruct->CPAL_State = CPAL_STATE_BUSY; + + /* Disable I2Cx device */ + __CPAL_I2C_HAL_DISABLE_DEV(pDevInitStruct->CPAL_Dev); + + /* Enable I2Cx device */ + __CPAL_I2C_HAL_ENABLE_DEV(pDevInitStruct->CPAL_Dev); + + /* Disable interrupts */ + __CPAL_I2C_HAL_DISABLE_ALLIT(pDevInitStruct->CPAL_Dev); + + /* Configure slave address */ + CR2_tmp |= (uint32_t)((pDevInitStruct->pCPAL_TransferTx->wAddr1) & 0x000003FF) | I2C_CR2_AUTOEND; + + /* Update CR2 Register */ + __CPAL_I2C_HAL_CR2_UPDATE(pDevInitStruct->CPAL_Dev, CR2_tmp); + + /* Generate Start */ + __CPAL_I2C_HAL_START(pDevInitStruct->CPAL_Dev); + + /* Set 35ms timeout */ + pDevInitStruct->wCPAL_Timeout = CPAL_I2C_TIMEOUT_MIN + 35; + + /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ + /* Wait until STOPF flag is set or a NACK flag is set*/ + while((__CPAL_I2C_HAL_GET_STOP(pDevInitStruct->CPAL_Dev) == RESET) && (__CPAL_I2C_HAL_GET_NACK(pDevInitStruct->CPAL_Dev) == RESET)); + + /* Reinitialize Timeout Value to default */ + pDevInitStruct->wCPAL_Timeout = CPAL_I2C_TIMEOUT_DEFAULT; + + /* Check if the NACKF flag has not been set */ + if (__CPAL_I2C_HAL_GET_NACK(pDevInitStruct->CPAL_Dev) != RESET) + { + /* Clear NACK flag */ + __CPAL_I2C_HAL_CLEAR_NACK(pDevInitStruct->CPAL_Dev); + + /* Clear Stop flag */ + __CPAL_I2C_HAL_CLEAR_STOP(pDevInitStruct->CPAL_Dev); + + /* Enable error interrupt */ + __CPAL_I2C_HAL_ENABLE_ERRIT(pDevInitStruct->CPAL_Dev); + + /* Set CPAL_State to CPAL_STATE_READY */ + pDevInitStruct->CPAL_State = CPAL_STATE_READY; + + return CPAL_FAIL; + } + else + { + /* Clear Stop flag */ + __CPAL_I2C_HAL_CLEAR_STOP(pDevInitStruct->CPAL_Dev); + + /* Enable error interrupt */ + __CPAL_I2C_HAL_ENABLE_ERRIT(pDevInitStruct->CPAL_Dev); + + /* Set CPAL_State to CPAL_STATE_READY */ + pDevInitStruct->CPAL_State = CPAL_STATE_READY; + + CPAL_LOG("\n\rLOG : I2C Target device Ready"); + + return CPAL_PASS; + } +} + + +/*================== CPAL_I2C_Interrupt_Handler ==================*/ + +/** + * @brief This function handles I2C interrupt request for preparing communication + * and for transfer phase in case of using Interrupt Programming Model. + * @param pDevInitStruct: Pointer to the peripheral configuration structure. + * @retval CPAL_PASS. + */ +uint32_t CPAL_I2C_EV_IRQHandler( CPAL_InitTypeDef* pDevInitStruct) +{ + __IO uint32_t I2CFlagStatus = 0x00000000; + + /* Read I2C status registers (ISR) */ + I2CFlagStatus = __CPAL_I2C_HAL_GET_EVENT(pDevInitStruct->CPAL_Dev); + +#ifdef CPAL_I2C_MASTER_MODE + /*----------------------------------------------------------------------------------------------*/ + /*---------------------------------- If Master Mode selected ----------------------------------*/ + if (pDevInitStruct->CPAL_Mode == CPAL_MODE_MASTER) + { + #ifdef CPAL_I2C_IT_PROGMODEL + /*----------------------------------------*/ + /*------------- If TXIS event ------------*/ + if (((I2CFlagStatus & CPAL_I2C_EVT_TXIS) != 0) && (pDevInitStruct->CPAL_State == CPAL_STATE_BUSY_TX)) + { + I2C_MASTER_TXIS_Handle(pDevInitStruct); + } + + /*----------------------------------------*/ + /*------------- If RXNE event ------------*/ + if (((I2CFlagStatus & CPAL_I2C_EVT_RXNE) != 0) && (pDevInitStruct->CPAL_State == CPAL_STATE_BUSY_RX)) + { + I2C_MASTER_RXNE_Handle(pDevInitStruct); + } + #endif /* CPAL_I2C_IT_PROGMODEL */ + + /*----------------------------------------*/ + /*-------------- If TCR event ------------*/ + if ((I2CFlagStatus & CPAL_I2C_EVT_TCR) != 0) + { + I2C_MASTER_TCR_Handle(pDevInitStruct); + } + + /*----------------------------------------*/ + /*------------- If TC event --------------*/ + if ((I2CFlagStatus & CPAL_I2C_EVT_TC ) != 0) + { + I2C_MASTER_TC_Handle(pDevInitStruct); + } + + /*----------------------------------------*/ + /*------------- If STOP event ------------*/ + if ((I2CFlagStatus & CPAL_I2C_EVT_STOP) != 0) + { + I2C_MASTER_STOP_Handle(pDevInitStruct); + } + + /*----------------------------------------*/ + /*------------- If NACK event ------------*/ + if((I2CFlagStatus & CPAL_I2C_EVT_NACK ) != 0) + { + I2C_MASTER_NACK_Handle(pDevInitStruct); + } + } +#endif /* CPAL_I2C_MASTER_MODE */ + +#ifdef CPAL_I2C_SLAVE_MODE + /*----------------------------------------------------------------------------------------------*/ + /*---------------------------------- If Slave Mode selected ------------------------------------*/ + if (pDevInitStruct->CPAL_Mode == CPAL_MODE_SLAVE) + { + /*----------------------------------------*/ + /*------------- If ADDR event ------------*/ + if ((I2CFlagStatus & CPAL_I2C_EVT_ADDR ) != 0) + { + I2C_SLAVE_ADDR_Handle(pDevInitStruct); + } + + #ifdef CPAL_I2C_IT_PROGMODEL + /*----------------------------------------*/ + /*------------- If TXIS event ------------*/ + if ((I2CFlagStatus & CPAL_I2C_EVT_TXIS) != 0) + { + I2C_SLAVE_TXIS_Handle(pDevInitStruct); + } + + /*----------------------------------------*/ + /*------------- If RXNE event ------------*/ + if ((I2CFlagStatus & CPAL_I2C_EVT_RXNE) != 0) + { + I2C_SLAVE_RXNE_Handle(pDevInitStruct); + } + #endif /* CPAL_I2C_IT_PROGMODEL */ + + /*----------------------------------------*/ + /*------------- If NACK event ------------*/ + if ((I2CFlagStatus & CPAL_I2C_EVT_NACK) != 0) + { + I2C_SLAVE_NACK_Handle(pDevInitStruct); + } + + /*----------------------------------------*/ + /*------------- If STOP event ------------*/ + if ((I2CFlagStatus & CPAL_I2C_EVT_STOP) != 0) + { + I2C_SLAVE_STOP_Handle(pDevInitStruct); + } + } +#endif /* CPAL_I2C_SLAVE_MODE */ + + return CPAL_PASS; +} + + +/** + * @brief Allows to handle errors occurred during initialization or communication + * in order to recover the correct communication status or call specific + * user functions. + * @param pDevInitStruct: Pointer to the peripheral configuration structure. + * @retval CPAL_PASS. + */ +uint32_t CPAL_I2C_ER_IRQHandler(CPAL_InitTypeDef* pDevInitStruct) +{ + /* Read error register and affect to wCPAL_DevError */ + pDevInitStruct->wCPAL_DevError = __CPAL_I2C_HAL_GET_ERROR(pDevInitStruct->CPAL_Dev); + + /* Set CPAL_State to CPAL_STATE_ERROR */ + pDevInitStruct->CPAL_State = CPAL_STATE_ERROR; + + CPAL_LOG("\n\r\n\rERROR : I2C Device Error"); + + /* If Bus error occurred ---------------------------------------------------*/ + if ((pDevInitStruct->wCPAL_DevError & CPAL_I2C_ERR_BERR) != 0) + { + CPAL_LOG("\n\rERROR : I2C Device BERR"); + + /* Clear error flag */ + __CPAL_I2C_HAL_CLEAR_BERR(pDevInitStruct->CPAL_Dev); + +#ifdef USE_MULTIPLE_ERROR_CALLBACK + /* Call Bus Error UserCallback */ + CPAL_I2C_BERR_UserCallback(pDevInitStruct->CPAL_Dev); +#endif /* USE_MULTIPLE_ERROR_CALLBACK */ + } + + /* If Arbitration Loss error occurred --------------------------------------*/ + if ((pDevInitStruct->wCPAL_DevError & CPAL_I2C_ERR_ARLO) != 0) + { + CPAL_LOG("\n\rERROR : I2C Device ARLO"); + + /* Clear error flag */ + __CPAL_I2C_HAL_CLEAR_ARLO(pDevInitStruct->CPAL_Dev); + +#ifdef USE_MULTIPLE_ERROR_CALLBACK + /* Call Arbitration Lost UserCallback */ + CPAL_I2C_ARLO_UserCallback(pDevInitStruct->CPAL_Dev); +#endif /* USE_MULTIPLE_ERROR_CALLBACK */ + } + + /* If Overrun error occurred -----------------------------------------------*/ + if ((pDevInitStruct->wCPAL_DevError & CPAL_I2C_ERR_OVR) != 0) + { + CPAL_LOG("\n\rERROR : I2C Device OVR"); + + /* No I2C software reset is performed here in order to allow user to get back + the last data received correctly */ + + /* Clear error flag */ + __CPAL_I2C_HAL_CLEAR_OVR(pDevInitStruct->CPAL_Dev); + +#ifdef USE_MULTIPLE_ERROR_CALLBACK + /* Call Overrun error UserCallback */ + CPAL_I2C_OVR_UserCallback(pDevInitStruct->CPAL_Dev); +#endif /* USE_MULTIPLE_ERROR_CALLBACK */ + } + + /* USE_SINGLE_ERROR_CALLBACK is defined in stm32f0xx_i2c_cpal_conf.h file */ +#ifdef USE_SINGLE_ERROR_CALLBACK + /* Call Error UserCallback */ + CPAL_I2C_ERR_UserCallback(pDevInitStruct->CPAL_Dev, pDevInitStruct->wCPAL_DevError); +#endif /* USE_SINGLE_ERROR_CALLBACK */ + + return CPAL_PASS; +} + + +#ifdef CPAL_I2C_DMA_PROGMODEL +/** + * @brief Handle I2C DMA TX interrupt request when DMA programming Model is + * used for data transmission. + * @param pDevInitStruct: Pointer to the peripheral configuration structure. + * @retval CPAL_PASS. + */ +uint32_t CPAL_I2C_DMA_TX_IRQHandler(CPAL_InitTypeDef* pDevInitStruct) +{ + /* Reinitialize timeout value to default (no timeout initiated) */ + pDevInitStruct->wCPAL_Timeout = CPAL_I2C_TIMEOUT_DEFAULT; + + CPAL_LOG("\n\r\n\rLOG : I2C Device TX DMA "); + + /*------------- If TC interrupt ------------*/ + if((__CPAL_I2C_HAL_GET_DMATX_TCIT(pDevInitStruct->CPAL_Dev)) != 0) + { + CPAL_LOG("\n\rLOG : I2C Device TX Complete"); + + /* If DMA normal mode */ + if ((pDevInitStruct->wCPAL_Options & CPAL_OPT_DMATX_CIRCULAR) == 0) + { + /* Update remaining number of data */ + pDevInitStruct->pCPAL_TransferTx->wNumData = 0; + + /* Call DMA TX TC UserCallback */ + CPAL_I2C_DMATXTC_UserCallback(pDevInitStruct); + + /* Disable DMA request and channel */ + __CPAL_I2C_HAL_DISABLE_TXDMAREQ(pDevInitStruct->CPAL_Dev); + __CPAL_I2C_HAL_DISABLE_DMATX(pDevInitStruct->CPAL_Dev); + + CPAL_LOG("\n\rLOG : I2C Device TX DMA Disabled"); + } + /* If DMA circular mode */ + else + { + /* Call DMA TX TC UserCallback */ + CPAL_I2C_DMATXTC_UserCallback(pDevInitStruct); + } + + } + /*------------- If HT interrupt ------------*/ + else if ((__CPAL_I2C_HAL_GET_DMATX_HTIT(pDevInitStruct->CPAL_Dev)) != 0) + { + CPAL_LOG("\n\rLOG : I2C Device TX DMA Half Transfer "); + + /* Call DMA TX HT UserCallback */ + CPAL_I2C_DMATXHT_UserCallback(pDevInitStruct); + } + /*------------- If TE interrupt ------------*/ + else if ((__CPAL_I2C_HAL_GET_DMATX_TEIT(pDevInitStruct->CPAL_Dev)) != 0) + { + CPAL_LOG("\n\rERROR : I2C Device TX DMA Transfer Error "); + + /* Update CPAL_State to CPAL_STATE_ERROR */ + pDevInitStruct->CPAL_State = CPAL_STATE_ERROR; + + /* Update remaining number of data */ + pDevInitStruct->pCPAL_TransferTx->wNumData = __CPAL_I2C_HAL_DMATX_GET_CNDT(pDevInitStruct->CPAL_Dev); + + /* Call TX transfer complete UserCallback */ + CPAL_I2C_RXTC_UserCallback(pDevInitStruct); + } + + /* Clear DMA interrupt Flag */ + __CPAL_I2C_HAL_CLEAR_DMATX_IT(pDevInitStruct->CPAL_Dev); + + return CPAL_PASS; +} + + +/** + * @brief Handle I2C DMA RX interrupt request when DMA programming Model is + * used for data reception. + * @param pDevInitStruct: Pointer to the peripheral configuration structure. + * @retval CPAL_PASS. + */ +uint32_t CPAL_I2C_DMA_RX_IRQHandler(CPAL_InitTypeDef* pDevInitStruct) +{ + /* Reinitialize Timeout Value to default (no timeout initiated) */ + pDevInitStruct->wCPAL_Timeout = CPAL_I2C_TIMEOUT_DEFAULT; + + CPAL_LOG("\n\r\n\rLOG : I2C Device RX DMA "); + + /*------------- If TC interrupt ------------*/ + if ((__CPAL_I2C_HAL_GET_DMARX_TCIT(pDevInitStruct->CPAL_Dev)) != 0) + { + CPAL_LOG("\n\rLOG : I2C Device RX Complete"); + + /* If DMA normal mode */ + if ((pDevInitStruct->wCPAL_Options & CPAL_OPT_DMARX_CIRCULAR) == 0) + { + /* Update remaining number of data */ + pDevInitStruct->pCPAL_TransferRx->wNumData = 0; + + /* Disable DMA Request and Channel */ + __CPAL_I2C_HAL_DISABLE_RXDMAREQ(pDevInitStruct->CPAL_Dev); + __CPAL_I2C_HAL_DISABLE_DMARX(pDevInitStruct->CPAL_Dev); + + CPAL_LOG("\n\rLOG : I2C Device RX DMA Disabled"); + + /* Call DMA RX TC UserCallback */ + CPAL_I2C_DMARXTC_UserCallback(pDevInitStruct); + + /* If No Stop Condition Generation option bit selected */ + if (((pDevInitStruct->wCPAL_Options & CPAL_OPT_I2C_NOSTOP) != 0) && (pDevInitStruct->CPAL_Mode == CPAL_MODE_SLAVE)) + { + /* Disable slave interrupt */ + __CPAL_I2C_HAL_DISABLE_SLAVE_IT(pDevInitStruct->CPAL_Dev); + + /* Update CPAL_State to CPAL_STATE_READY */ + pDevInitStruct->CPAL_State = CPAL_STATE_READY; + + /* Call TX transfer complete UserCallback */ + CPAL_I2C_TXTC_UserCallback(pDevInitStruct); + } + } + /* If DMA circular mode */ + else + { + /* Call DMA RX TC UserCallback */ + CPAL_I2C_DMARXTC_UserCallback(pDevInitStruct); + } + } + /*------------- If HT interrupt ------------*/ + else if ((__CPAL_I2C_HAL_GET_DMARX_HTIT(pDevInitStruct->CPAL_Dev)) != 0) + { + CPAL_LOG("\n\rLOG : I2C Device RX DMA Half Transfer"); + + /* Call DMA RX HT UserCallback */ + CPAL_I2C_DMARXHT_UserCallback(pDevInitStruct); + } + /*------------- If TE interrupt ------------*/ + else if ((__CPAL_I2C_HAL_GET_DMARX_TEIT(pDevInitStruct->CPAL_Dev)) != 0) + { + CPAL_LOG("\n\rERROR : I2C Device RX DMA Transfer Error "); + + /* Update CPAL_State to CPAL_STATE_ERROR */ + pDevInitStruct->CPAL_State = CPAL_STATE_ERROR; + + /* Update remaining number of data */ + pDevInitStruct->pCPAL_TransferRx->wNumData = __CPAL_I2C_HAL_DMARX_GET_CNDT(pDevInitStruct->CPAL_Dev); + + /* Call DMA RX TE UserCallback */ + CPAL_I2C_DMARXTE_UserCallback(pDevInitStruct); + } + + /* Clear DMA interrupt Flag */ + __CPAL_I2C_HAL_CLEAR_DMARX_IT(pDevInitStruct->CPAL_Dev); + + return CPAL_PASS; +} +#endif /* CPAL_I2C_DMA_PROGMODEL */ + + +/*================== CPAL_I2C_Timeout_Function ==================*/ + +/** + * @brief This function Manages I2C Timeouts when waiting for specific events. + * @param None + * @retval CPAL_PASS or CPAL_FAIL. + */ +void CPAL_I2C_TIMEOUT_Manager(void) +{ + uint32_t index = 0; + + /* Manage I2C timeouts conditions */ + for (index = 0; index < CPAL_I2C_DEV_NUM; index ++) + { + if (I2C_DevStructures[index] != pNULL) + { + /* If Timeout occurred */ + if (I2C_DevStructures[index]->wCPAL_Timeout == CPAL_I2C_TIMEOUT_DETECTED) + { + /* Reinitialize timeout value */ + I2C_DevStructures[index]->wCPAL_Timeout = CPAL_I2C_TIMEOUT_DEFAULT; + + /* Update CPAL_State to CPAL_STATE_ERROR */ + I2C_DevStructures[index]->CPAL_State = CPAL_STATE_ERROR; + + /* In case of Device Error Timeout_Callback should not be called */ + if (I2C_DevStructures[index]->wCPAL_DevError == CPAL_I2C_ERR_NONE) + { + /* Update wCPAL_DevError to CPAL_I2C_ERR_TIMEOUT */ + I2C_DevStructures[index]->wCPAL_DevError = CPAL_I2C_ERR_TIMEOUT; + + CPAL_LOG("\n\r\n\rLOG : I2C Device Timeout Error"); + + /* Call CPAL_TIMEOUT_UserCallback */ + CPAL_TIMEOUT_UserCallback(I2C_DevStructures[index]); + } + } + /* If Timeout is triggered (wCPAL_Timeout != CPAL_I2C_TIMEOUT_DEFAULT)*/ + else if (I2C_DevStructures[index]->wCPAL_Timeout != CPAL_I2C_TIMEOUT_DEFAULT) + { + /* Decrement the timeout value */ + I2C_DevStructures[index]->wCPAL_Timeout--; + } + } + } +} + + +/** + * @brief This function Manages I2C Timeouts when Timeout occurred. + * @param pDevInitStruct: Pointer to the peripheral configuration structure. + * @retval CPAL_PASS or CPAL_FAIL. + */ +uint32_t CPAL_I2C_Timeout (CPAL_InitTypeDef* pDevInitStruct) +{ + /* Reinitialize timeout value */ + pDevInitStruct->wCPAL_Timeout = CPAL_I2C_TIMEOUT_DEFAULT; + + /* update CPAL_State to CPAL_STATE_ERROR */ + pDevInitStruct->CPAL_State = CPAL_STATE_ERROR; + + /* update wCPAL_DevError to CPAL_I2C_ERR_TIMEOUT */ + pDevInitStruct->wCPAL_DevError = CPAL_I2C_ERR_TIMEOUT; + + /* Call Timeout Callback and quit current function */ + return (CPAL_TIMEOUT_UserCallback(pDevInitStruct)); +} + +/*================== CPAL_I2C_Event_Handler ==================*/ + +#ifdef CPAL_I2C_MASTER_MODE +/** + * @brief Handles Master TCR interrupt event. + * @param pDevInitStruct: Pointer to the peripheral configuration structure. + * @retval CPAL_PASS or CPAL_FAIL. + */ +static uint32_t I2C_MASTER_TCR_Handle(CPAL_InitTypeDef* pDevInitStruct) +{ + CR2_tmp = 0; + + /* If DMA programming model */ + if (pDevInitStruct->CPAL_ProgModel == CPAL_PROGMODEL_DMA) + { + /* If master transmitter */ + if (pDevInitStruct->CPAL_State == CPAL_STATE_BUSY_TX) + { + /* Update wNumData */ + pDevInitStruct->pCPAL_TransferTx->wNumData = pDevInitStruct->pCPAL_TransferTx->wNumData - 0xff; + } + /* If master receiver */ + else + { + /* Update wNumData */ + pDevInitStruct->pCPAL_TransferRx->wNumData = pDevInitStruct->pCPAL_TransferRx->wNumData - 0xff; + } + } + + /* If master transmitter */ + if (pDevInitStruct->CPAL_State == CPAL_STATE_BUSY_TX) + { + /* If remaining number of data is equal or lower than 255 */ + if (pDevInitStruct->pCPAL_TransferTx->wNumData <= 0xff) + { + /* Update Num_Data */ + Num_Data = pDevInitStruct->pCPAL_TransferTx->wNumData; + + /* Set Nbytes to wNumData */ + CR2_tmp |= (uint32_t)((uint32_t)(Num_Data) << 16); + + /* Disable reload */ + CR2_tmp &= ~I2C_CR2_RELOAD; + } + /* If remaining number of data is greater than 255 */ + else + { + /* Set Nbytes to wNumData */ + CR2_tmp |= (uint32_t)((uint32_t)(255) << 16); + + /* Enaable reload */ + CR2_tmp |= I2C_CR2_RELOAD; + } + } + /* If master receiver */ + else + { + /* If remaining number of data is equal or lower than 255 */ + if (pDevInitStruct->pCPAL_TransferRx->wNumData <= 0xff) + { + /* Update num data */ + Num_Data = pDevInitStruct->pCPAL_TransferRx->wNumData; + + /* Set Nbytes to wNumData */ + CR2_tmp |= (uint32_t)((uint32_t)(Num_Data) << 16); + + /* Disable reload */ + CR2_tmp &= ~I2C_CR2_RELOAD; + + } + /* If remaining number of data is greater than 255 */ + else + { + /* Set Nbytes to wNumData */ + CR2_tmp |= (uint32_t)((uint32_t)(255) << 16); + + /* Enaable reload */ + CR2_tmp |= I2C_CR2_RELOAD; + } + } + + /* Update CR2 Register */ + __CPAL_I2C_HAL_CR2_UPDATE(pDevInitStruct->CPAL_Dev, CR2_tmp); + + return CPAL_PASS; +} + +/** + * @brief Handles Master TC interrupt event. + * @param pDevInitStruct: Pointer to the peripheral configuration structure. + * @retval CPAL_PASS or CPAL_FAIL. + */ +static uint32_t I2C_MASTER_TC_Handle(CPAL_InitTypeDef* pDevInitStruct) +{ + /* No Stop Condition Generation option bit is not selected */ + if ((pDevInitStruct->wCPAL_Options & CPAL_OPT_I2C_NOSTOP) == 0) + { + /* Generate stop condition */ + __CPAL_I2C_HAL_STOP(pDevInitStruct->CPAL_Dev); + } + /* No Stop Condition Generation option bit is selected */ + else + { + /* Disable master interrupts */ + __CPAL_I2C_HAL_DISABLE_MASTER_IT(pDevInitStruct->CPAL_Dev); + + /* If master transmitter */ + if (pDevInitStruct->CPAL_State == CPAL_STATE_BUSY_TX) + { + #ifdef CPAL_I2C_IT_PROGMODEL + /* If Interrupt Programming Model */ + if (pDevInitStruct->CPAL_ProgModel == CPAL_PROGMODEL_INTERRUPT) + { + /* Disable TX interrupt */ + __CPAL_I2C_HAL_DISABLE_TXIE_IT(pDevInitStruct->CPAL_Dev); + } + #endif /* CPAL_I2C_IT_PROGMODEL */ + + /* Update CPAL_State to CPAL_STATE_READY */ + pDevInitStruct->CPAL_State = CPAL_STATE_READY; + + /* Call TX Transfer complete Callback */ + CPAL_I2C_TXTC_UserCallback(pDevInitStruct); + } + /* If master receiver */ + else + { + #ifdef CPAL_I2C_IT_PROGMODEL + /* If Interrupt Programming Model */ + if (pDevInitStruct->CPAL_ProgModel == CPAL_PROGMODEL_INTERRUPT) + { + /* Disable RX interrupt */ + __CPAL_I2C_HAL_DISABLE_RXIE_IT(pDevInitStruct->CPAL_Dev); + } + #endif /* CPAL_I2C_IT_PROGMODEL */ + + /* Update CPAL_State to CPAL_STATE_READY */ + pDevInitStruct->CPAL_State = CPAL_STATE_READY; + + /* Call RX Transfer complete Callback */ + CPAL_I2C_RXTC_UserCallback(pDevInitStruct); + } + } + return CPAL_PASS; +} + +/** + * @brief Handles Master STOP interrupt event. + * @param pDevInitStruct: Pointer to the peripheral configuration structure. + * @retval CPAL_PASS or CPAL_FAIL. + */ +static uint32_t I2C_MASTER_STOP_Handle(CPAL_InitTypeDef* pDevInitStruct) +{ + /* If NACK received by master */ + if (pDevInitStruct->wCPAL_DevError == CPAL_I2C_ERR_AF) + { + /* Set CPAL_State to CPAL_STATE_ERROR */ + pDevInitStruct->CPAL_State = CPAL_STATE_ERROR; + + /* Clear STOP flag */ + __CPAL_I2C_HAL_CLEAR_STOP(pDevInitStruct->CPAL_Dev); + } + else + { + /* Clear STOP flag */ + __CPAL_I2C_HAL_CLEAR_STOP(pDevInitStruct->CPAL_Dev); + + CPAL_LOG("\n\r\n\rLOG : I2C Device Master IT"); + + CPAL_LOG("\n\rLOG : I2C Device Stop Generated"); + + /* Disable master interrupt */ + __CPAL_I2C_HAL_DISABLE_MASTER_IT(pDevInitStruct->CPAL_Dev); + + /* Wait until BUSY flag is reset */ + __CPAL_I2C_TIMEOUT(!(__CPAL_I2C_HAL_GET_BUSY(pDevInitStruct->CPAL_Dev)), CPAL_I2C_TIMEOUT_BUSY); + + /* If master transmitter */ + if (pDevInitStruct->CPAL_State == CPAL_STATE_BUSY_TX) + { + #ifdef CPAL_I2C_IT_PROGMODEL + /* If Interrupt Programming Model */ + if (pDevInitStruct->CPAL_ProgModel == CPAL_PROGMODEL_INTERRUPT) + { + /* Disable TX interrupt */ + __CPAL_I2C_HAL_DISABLE_TXIE_IT(pDevInitStruct->CPAL_Dev); + } + #endif /* CPAL_I2C_IT_PROGMODEL */ + + /* Update CPAL_State to CPAL_STATE_READY */ + pDevInitStruct->CPAL_State = CPAL_STATE_READY; + + /* Call TX Transfer complete Callback */ + CPAL_I2C_TXTC_UserCallback(pDevInitStruct); + } + /* If master receiver */ + else + { + #ifdef CPAL_I2C_IT_PROGMODEL + /* If Interrupt Programming Model */ + if (pDevInitStruct->CPAL_ProgModel == CPAL_PROGMODEL_INTERRUPT) + { + /* Disable RX interrupt */ + __CPAL_I2C_HAL_DISABLE_RXIE_IT(pDevInitStruct->CPAL_Dev); + } + #endif /* CPAL_I2C_IT_PROGMODEL */ + + /* Update CPAL_State to CPAL_STATE_READY */ + pDevInitStruct->CPAL_State = CPAL_STATE_READY; + + /* Call RX Transfer complete Callback */ + CPAL_I2C_RXTC_UserCallback(pDevInitStruct); + } + } + return CPAL_PASS; +} + +/** + * @brief Handles Master NACK interrupt event. + * @param pDevInitStruct: Pointer to the peripheral configuration structure. + * @retval CPAL_PASS or CPAL_FAIL. + */ +static uint32_t I2C_MASTER_NACK_Handle(CPAL_InitTypeDef* pDevInitStruct) +{ + /* Update wCPAL_DevError */ + pDevInitStruct->wCPAL_DevError = CPAL_I2C_ERR_AF; + + /* Clear NACK flag */ + __CPAL_I2C_HAL_CLEAR_NACK(pDevInitStruct->CPAL_Dev); + + /* USE_SINGLE_ERROR_CALLBACK is defined in stm32f0xx_i2c_cpal_conf.h file */ +#ifdef USE_SINGLE_ERROR_CALLBACK + /* Call Error UserCallback */ + CPAL_I2C_ERR_UserCallback(pDevInitStruct->CPAL_Dev, pDevInitStruct->wCPAL_DevError); +#elif defined(USE_MULTIPLE_ERROR_CALLBACK) + /* Call AF UserCallback */ + CPAL_I2C_AF_UserCallback(pDevInitStruct->CPAL_Dev); +#endif /* USE_SINGLE_ERROR_CALLBACK */ + + return CPAL_PASS; +} + + #ifdef CPAL_I2C_IT_PROGMODEL +/** + * @brief Handles Master transmission TXIS interrupt event. + * @param pDevInitStruct: Pointer to the peripheral configuration structure. + * @retval CPAL_PASS or CPAL_FAIL. + */ +static uint32_t I2C_MASTER_TXIS_Handle(CPAL_InitTypeDef* pDevInitStruct) +{ + /* Call TX UserCallback */ + CPAL_I2C_TX_UserCallback(pDevInitStruct); + + /* Write Byte */ + __CPAL_I2C_HAL_SEND((pDevInitStruct->CPAL_Dev), (*(pDevInitStruct->pCPAL_TransferTx->pbBuffer))); + + /* Decrement remaining number of data */ + pDevInitStruct->pCPAL_TransferTx->wNumData--; + + if (pDevInitStruct->pCPAL_TransferTx->wNumData != 0) + { + /* Point to next data */ + pDevInitStruct->pCPAL_TransferTx->pbBuffer++; + } + return CPAL_PASS; +} + +/** + * @brief Handles Master reception RXNE interrupt event. + * @param pDevInitStruct: Pointer to the peripheral configuration structure. + * @retval CPAL_PASS or CPAL_FAIL. + */ +static uint32_t I2C_MASTER_RXNE_Handle(CPAL_InitTypeDef* pDevInitStruct) +{ + /* Read Byte */ + *(pDevInitStruct->pCPAL_TransferRx->pbBuffer) = __CPAL_I2C_HAL_RECEIVE(pDevInitStruct->CPAL_Dev); + + /* Call RX UserCallback */ + CPAL_I2C_RX_UserCallback(pDevInitStruct); + + /* Decrement remaining number of data */ + pDevInitStruct->pCPAL_TransferRx->wNumData--; + + /* If data remaining for reception */ + if (pDevInitStruct->pCPAL_TransferRx->wNumData != 0) + { + /* Point to next data */ + pDevInitStruct->pCPAL_TransferRx->pbBuffer++; + } + return CPAL_PASS; +} + #endif /* CPAL_I2C_IT_PROGMODEL */ +#endif /* CPAL_I2C_MASTER_MODE */ + + +#ifdef CPAL_I2C_SLAVE_MODE +/** + * @brief Handles Slave ADDR interrupt event. + * @param pDevInitStruct: Pointer to the peripheral configuration structure. + * @retval CPAL_PASS or CPAL_FAIL. + */ +static uint32_t I2C_SLAVE_ADDR_Handle(CPAL_InitTypeDef* pDevInitStruct) +{ +#ifdef CPAL_I2C_LISTEN_MODE + /* If slave receive request for write */ + if (__CPAL_I2C_HAL_GET_DIR(pDevInitStruct->CPAL_Dev) == 0) + { + pDevInitStruct->CPAL_State = CPAL_STATE_BUSY_RX; + + /* Call Slave receive UserCallback */ + CPAL_I2C_SLAVE_READ_UserCallback(pDevInitStruct); + } + /* If slave receive request for read */ + else + { + pDevInitStruct->CPAL_State = CPAL_STATE_BUSY_TX; + + /* Call Slave Transmit UserCallback */ + CPAL_I2C_SLAVE_WRITE_UserCallback(pDevInitStruct); + } +#else + uint32_t slaveaddr = 0; + + /* If 7 Bit Addressing Mode */ + if (pDevInitStruct->pCPAL_I2C_Struct->I2C_AcknowledgedAddress == I2C_AcknowledgedAddress_7bit) + { + /* Get slave matched address */ + slaveaddr = __CPAL_I2C_HAL_GET_ADDCODE(pDevInitStruct->CPAL_Dev); + + /* if matched address is not equal to OA1 */ + if (slaveaddr !=__CPAL_I2C_HAL_GET_OA1(pDevInitStruct->CPAL_Dev)) + { + /* If General Call addressing mode selected */ + if ( slaveaddr == 0x00000000) + { + CPAL_LOG("\n\rLOG : I2C Device GENCALL Mode"); + + /* Call GENCALL UserCallback */ + CPAL_I2C_GENCALL_UserCallback(pDevInitStruct); + } + /* If DUAL addressing mode selected */ + else + { + CPAL_LOG("\n\rLOG : I2C Device DUAL ADDR Mode Selected"); + + /* Call DUALF UserCallback */ + CPAL_I2C_DUALF_UserCallback(pDevInitStruct); + } + } + } +#endif /* CPAL_I2C_LISTEN_MODE */ + + /* Clear ADDR flag */ + __CPAL_I2C_HAL_CLEAR_ADDR(pDevInitStruct->CPAL_Dev); + + return CPAL_PASS; +} + +/** + * @brief Handles Slave STOP interrupt event. + * @param pDevInitStruct: Pointer to the peripheral configuration structure. + * @retval CPAL_PASS or CPAL_FAIL. + */ +static uint32_t I2C_SLAVE_STOP_Handle(CPAL_InitTypeDef* pDevInitStruct) +{ + /* Clear STOP flag */ + __CPAL_I2C_HAL_CLEAR_STOP(pDevInitStruct->CPAL_Dev); + + CPAL_LOG("\n\r\n\rLOG : I2C Device Slave IT"); + + CPAL_LOG("\n\rLOG : I2C Device Stop Detected"); + + /* Disable slave interrupt */ + __CPAL_I2C_HAL_DISABLE_SLAVE_IT(pDevInitStruct->CPAL_Dev); + + /* Wait until BUSY flag is reset */ + __CPAL_I2C_TIMEOUT(!(__CPAL_I2C_HAL_GET_BUSY(pDevInitStruct->CPAL_Dev)), CPAL_I2C_TIMEOUT_BUSY); + + /* If NACK Slave Own Address option bit selected */ + if ((pDevInitStruct->wCPAL_Options & CPAL_OPT_I2C_NACK_ADD) != 0) + { + /* Disable Acknowledgement of own Address */ + __CPAL_I2C_HAL_DISABLE_DEV(pDevInitStruct->CPAL_Dev); + } + + /* If slave transmitter */ + if (pDevInitStruct->CPAL_State == CPAL_STATE_BUSY_TX) + { + #ifdef CPAL_I2C_IT_PROGMODEL + /* If Interrupt Programming Model */ + if (pDevInitStruct->CPAL_ProgModel == CPAL_PROGMODEL_INTERRUPT) + { + /* Disable TX interrupt */ + __CPAL_I2C_HAL_DISABLE_TXIE_IT(pDevInitStruct->CPAL_Dev); + } + #endif /* CPAL_I2C_IT_PROGMODEL */ + + /* Update CPAL_State to CPAL_STATE_READY */ + pDevInitStruct->CPAL_State = CPAL_STATE_READY; + + /* Call TX Transfer complete Callback */ + CPAL_I2C_TXTC_UserCallback(pDevInitStruct); + } + /* If slave receiver */ + else + { + #ifdef CPAL_I2C_IT_PROGMODEL + /* If Interrupt Programming Model */ + if (pDevInitStruct->CPAL_ProgModel == CPAL_PROGMODEL_INTERRUPT) + { + /* Disable RX interrupt */ + __CPAL_I2C_HAL_DISABLE_RXIE_IT(pDevInitStruct->CPAL_Dev); + } + #endif /* CPAL_I2C_IT_PROGMODEL */ + + /* Update CPAL_State to CPAL_STATE_READY */ + pDevInitStruct->CPAL_State = CPAL_STATE_READY; + + /* Call RX Transfer complete Callback */ + CPAL_I2C_RXTC_UserCallback(pDevInitStruct); + } + return CPAL_PASS; +} + +/** + * @brief Handles Slave NACK interrupt event. + * @param pDevInitStruct: Pointer to the peripheral configuration structure. + * @retval CPAL_PASS or CPAL_FAIL. + */ +static uint32_t I2C_SLAVE_NACK_Handle(CPAL_InitTypeDef* pDevInitStruct) +{ + /* Clear NACK flag */ + __CPAL_I2C_HAL_CLEAR_NACK(pDevInitStruct->CPAL_Dev); + + /* No Stop Condition Generation option bit selected and slave transmitter */ + if (((pDevInitStruct->wCPAL_Options & CPAL_OPT_I2C_NOSTOP) != 0) && (pDevInitStruct->CPAL_State == CPAL_STATE_BUSY_TX)) + { + /* Disable slave interrupt */ + __CPAL_I2C_HAL_DISABLE_SLAVE_IT(pDevInitStruct->CPAL_Dev); + + #ifdef CPAL_I2C_IT_PROGMODEL + /* If Interrupt Programming Model */ + if (pDevInitStruct->CPAL_ProgModel == CPAL_PROGMODEL_INTERRUPT) + { + /* Disable TX interrupt */ + __CPAL_I2C_HAL_DISABLE_TXIE_IT(pDevInitStruct->CPAL_Dev); + } + #endif /* CPAL_I2C_IT_PROGMODEL */ + + /* Update CPAL_State to CPAL_STATE_READY */ + pDevInitStruct->CPAL_State = CPAL_STATE_READY; + + /* Call TX Transfer complete Callback */ + CPAL_I2C_TXTC_UserCallback(pDevInitStruct); + } + return CPAL_PASS; +} + + #ifdef CPAL_I2C_IT_PROGMODEL +/** + * @brief Handles Slave transmission TXIS interrupt event. + * @param pDevInitStruct: Pointer to the peripheral configuration structure. + * @retval CPAL_PASS or CPAL_FAIL. + */ +static uint32_t I2C_SLAVE_TXIS_Handle(CPAL_InitTypeDef* pDevInitStruct) +{ + /* If data remaining for transmission */ + if (pDevInitStruct->pCPAL_TransferTx->wNumData != 0) + { + /* Call TX UserCallback */ + CPAL_I2C_TX_UserCallback(pDevInitStruct); + + /* Write Byte */ + __CPAL_I2C_HAL_SEND((pDevInitStruct->CPAL_Dev), (*(pDevInitStruct->pCPAL_TransferTx->pbBuffer))); + + /* Decrement remaining number of data */ + pDevInitStruct->pCPAL_TransferTx->wNumData--; + + if (pDevInitStruct->pCPAL_TransferTx->wNumData != 0) + { + /* Point to next data */ + pDevInitStruct->pCPAL_TransferTx->pbBuffer++; + } + } + return CPAL_PASS; +} + +/** + * @brief Handles Slave reception RXNE interrupt event. + * @param pDevInitStruct: Pointer to the peripheral configuration structure. + * @retval CPAL_PASS or CPAL_FAIL. + */ +static uint32_t I2C_SLAVE_RXNE_Handle(CPAL_InitTypeDef* pDevInitStruct) +{ + /* If data remaining for reception */ + if (pDevInitStruct->pCPAL_TransferRx->wNumData != 0) + { + /* Read Byte */ + *(pDevInitStruct->pCPAL_TransferRx->pbBuffer) = __CPAL_I2C_HAL_RECEIVE(pDevInitStruct->CPAL_Dev); + + /* Call RX UserCallback */ + CPAL_I2C_RX_UserCallback(pDevInitStruct); + + /* Decrement remaining number of data */ + pDevInitStruct->pCPAL_TransferRx->wNumData--; + + /* If data remaining for reception */ + if (pDevInitStruct->pCPAL_TransferRx->wNumData != 0) + { + /* Point to next data */ + pDevInitStruct->pCPAL_TransferRx->pbBuffer++; + } + /* If all data received and No Stop Condition Generation option bit selected */ + else if ((pDevInitStruct->wCPAL_Options & CPAL_OPT_I2C_NOSTOP) != 0) + { + /* Disable slave interrupt */ + __CPAL_I2C_HAL_DISABLE_SLAVE_IT(pDevInitStruct->CPAL_Dev); + + /* Disable RX interrupt */ + __CPAL_I2C_HAL_DISABLE_RXIE_IT(pDevInitStruct->CPAL_Dev); + + /* Update CPAL_State to CPAL_STATE_READY */ + pDevInitStruct->CPAL_State = CPAL_STATE_READY; + + /* Call RX Transfer complete Callback */ + CPAL_I2C_RXTC_UserCallback(pDevInitStruct); + } + } + return CPAL_PASS; +} + #endif /* CPAL_I2C_IT_PROGMODEL */ +#endif /* CPAL_I2C_SLAVE_MODE */ + + + +/*================== Local DMA and IT Manager ==================*/ + +#ifdef CPAL_I2C_DMA_PROGMODEL +/** + * @brief This function Configures and enables I2C DMA before starting transfer phase. + * @param pDevInitStruct: Pointer to the peripheral configuration structure. + * @param Direction : Transfer direction. + * @retval CPAL_PASS or CPAL_FAIL. + */ +static uint32_t I2C_Enable_DMA (CPAL_InitTypeDef* pDevInitStruct, CPAL_DirectionTypeDef Direction) +{ + /* If data transmission will be performed */ + if ((pDevInitStruct->CPAL_State == CPAL_STATE_BUSY_TX) || (Direction == CPAL_DIRECTION_TX)) + { + /* Configure TX DMA channels */ + CPAL_I2C_HAL_DMATXConfig(pDevInitStruct->CPAL_Dev, pDevInitStruct->pCPAL_TransferTx, pDevInitStruct->wCPAL_Options); + + /* Enable TX DMA channels */ + __CPAL_I2C_HAL_ENABLE_DMATX(pDevInitStruct->CPAL_Dev); + + CPAL_LOG("\n\rLOG : I2C Device DMA TX Configured and Enabled"); + } + /* If data reception will be performed */ + else if ((pDevInitStruct->CPAL_State == CPAL_STATE_BUSY_RX) || (Direction == CPAL_DIRECTION_RX)) + { + /* Configure RX DMA channels */ + CPAL_I2C_HAL_DMARXConfig(pDevInitStruct->CPAL_Dev, pDevInitStruct->pCPAL_TransferRx, pDevInitStruct->wCPAL_Options); + + /* Enable RX DMA channels */ + __CPAL_I2C_HAL_ENABLE_DMARX(pDevInitStruct->CPAL_Dev); + + CPAL_LOG("\n\rLOG : I2C Device DMA RX Configured and Enabled"); + } + return CPAL_PASS; +} +#endif /* CPAL_I2C_DMA_PROGMODEL */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/STM32F0xx_CPAL_Driver/src/stm32f0xx_i2c_cpal_hal.c b/libraries/STM32F0xx_CPAL_Driver/src/stm32f0xx_i2c_cpal_hal.c new file mode 100644 --- /dev/null +++ b/libraries/STM32F0xx_CPAL_Driver/src/stm32f0xx_i2c_cpal_hal.c @@ -0,0 +1,615 @@ +/** + ****************************************************************************** + * @file stm32f0xx_i2c_cpal_hal.c + * @author MCD Application Team + * @version V1.2.0 + * @date 24-July-2014 + * @brief This file provides all the CPAL_I2C_HAL (hardware Abstraction Layer) + * firmware functions. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2014 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_i2c_cpal_hal.h" + +/* Private typedef -----------------------------------------------------------*/ +/* Private defines -----------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ + + +/* Private variables ---------------------------------------------------------*/ + +/*========= Local Structures declaration =========*/ + +CPAL_InitTypeDef* I2C_DevStructures[CPAL_I2C_DEV_NUM] = +{ +#ifdef CPAL_USE_I2C1 + &I2C1_DevStructure, +#else + pNULL, +#endif + +#ifdef CPAL_USE_I2C2 + &I2C2_DevStructure, +#else + pNULL, +#endif +}; + + +#ifdef CPAL_USE_I2C1 +CPAL_InitTypeDef I2C1_DevStructure = { CPAL_I2C1, /* I2C1 device number */ + CPAL_DIRECTION_TXRX, /* Transmitter and Receiver direction selected */ + CPAL_MODE_MASTER, /* Mode Master selected */ + #ifdef CPAL_I2C_DMA_PROGMODEL + CPAL_PROGMODEL_DMA, /* DMA Programming Model selected */ + #else + CPAL_PROGMODEL_INTERRUPT, /* IT Programming Model selected */ + #endif /* CPAL_I2C_DMA_PROGMODEL */ + (CPAL_TransferTypeDef*) pNULL, /* Point pCPAL_TransferTx to a Null pointer */ + (CPAL_TransferTypeDef*) pNULL, /* Point pCPAL_TransferRx to a Null pointer */ + CPAL_STATE_DISABLED, /* Device Disabled */ + CPAL_I2C_ERR_NONE, /* No Device Error */ + ((uint32_t)0x00000000), /* No Options selected */ + ((uint32_t)CPAL_I2C_TIMEOUT_DEFAULT),/* Set timeout value to CPAL_I2C_TIMEOUT_DEFAULT */ + (I2C_InitTypeDef*) pNULL}; /* Point pCPAL_I2C_Struct to a Null pointer */ + +#endif /* CPAL_USE_I2C1 */ + +#ifdef CPAL_USE_I2C2 +CPAL_InitTypeDef I2C2_DevStructure = { CPAL_I2C2, /* I2C2 device number */ + CPAL_DIRECTION_TXRX, /* Transmitter and Receiver direction selected */ + CPAL_MODE_MASTER, /* Mode Master selected */ + #ifdef CPAL_I2C_DMA_PROGMODEL + CPAL_PROGMODEL_DMA, /* DMA Programming Model selected */ + #else + CPAL_PROGMODEL_INTERRUPT, /* IT Programming Model selected */ + #endif /* CPAL_I2C_DMA_PROGMODEL */ + (CPAL_TransferTypeDef*) pNULL, /* Point pCPAL_TransferTx to a Null pointer */ + (CPAL_TransferTypeDef*) pNULL, /* Point pCPAL_TransferRx to a Null pointer */ + CPAL_STATE_DISABLED, /* Device Disabled */ + CPAL_I2C_ERR_NONE, /* No Device Error */ + ((uint32_t)0x00000000), /* No Options selected */ + ((uint32_t)CPAL_I2C_TIMEOUT_DEFAULT),/* Set timeout value to CPAL_I2C_TIMEOUT_DEFAULT */ + (I2C_InitTypeDef*) pNULL}; /* Point pCPAL_I2C_Struct to a Null pointer */ +#endif /* CPAL_USE_I2C2 */ + + +DMA_InitTypeDef CPAL_DMA_InitStructure; + +I2C_TypeDef* CPAL_I2C_DEVICE[2] = {I2C1,I2C2}; + +const uint32_t CPAL_I2C_CLK[2] = {CPAL_I2C1_CLK,CPAL_I2C2_CLK}; +const uint32_t CPAL_I2C_TXDR[2] = {CPAL_I2C1_TXDR,CPAL_I2C2_TXDR}; +const uint32_t CPAL_I2C_RXDR[2] = {CPAL_I2C1_RXDR,CPAL_I2C2_RXDR}; +const uint32_t CPAL_I2C_AF[2] = {CPAL_I2C1_AF,CPAL_I2C2_AF}; + +const GPIO_TypeDef* CPAL_I2C_SCL_GPIO_PORT[2] = {CPAL_I2C1_SCL_GPIO_PORT,CPAL_I2C2_SCL_GPIO_PORT}; +const uint16_t CPAL_I2C_SCL_GPIO_PIN[2] = {CPAL_I2C1_SCL_GPIO_PIN,CPAL_I2C2_SCL_GPIO_PIN}; +const uint32_t CPAL_I2C_SCL_GPIO_CLK[2] = {CPAL_I2C1_SCL_GPIO_CLK,CPAL_I2C2_SCL_GPIO_CLK}; +const uint16_t CPAL_I2C_SCL_GPIO_PINSOURCE[2] = {CPAL_I2C1_SCL_GPIO_PINSOURCE,CPAL_I2C2_SCL_GPIO_PINSOURCE}; + +const GPIO_TypeDef* CPAL_I2C_SDA_GPIO_PORT[2] = {CPAL_I2C1_SDA_GPIO_PORT,CPAL_I2C2_SDA_GPIO_PORT}; +const uint16_t CPAL_I2C_SDA_GPIO_PIN[2] = {CPAL_I2C1_SDA_GPIO_PIN,CPAL_I2C2_SDA_GPIO_PIN}; +const uint32_t CPAL_I2C_SDA_GPIO_CLK[2] = {CPAL_I2C1_SDA_GPIO_CLK,CPAL_I2C2_SDA_GPIO_CLK}; +const uint16_t CPAL_I2C_SDA_GPIO_PINSOURCE[2] = {CPAL_I2C1_SDA_GPIO_PINSOURCE,CPAL_I2C2_SDA_GPIO_PINSOURCE}; + +const uint32_t CPAL_I2C_DMA_CLK[2] = {CPAL_I2C1_DMA_CLK,CPAL_I2C2_DMA_CLK}; + +DMA_Channel_TypeDef* CPAL_I2C_DMA_TX_Channel[2] = {CPAL_I2C1_DMA_TX_Channel, CPAL_I2C2_DMA_TX_Channel}; +DMA_Channel_TypeDef* CPAL_I2C_DMA_RX_Channel[2] = {CPAL_I2C1_DMA_RX_Channel, CPAL_I2C2_DMA_RX_Channel}; + +const IRQn_Type CPAL_I2C_DMA_IRQn[2] = {CPAL_I2C1_DMA_IRQn, CPAL_I2C2_DMA_IRQn}; + +const IRQn_Type CPAL_I2C_IT_IRQn[2] = {CPAL_I2C1_IT_IRQn, CPAL_I2C2_IT_IRQn}; + +const uint8_t I2C_IT_PRIO[2] = {I2C1_IT_PRIO, I2C2_IT_PRIO}; + +const uint8_t I2C_IT_DMA_PRIO[2] = {I2C1_IT_DMA_PRIO, I2C2_IT_DMA_PRIO}; + +DMA_TypeDef* CPAL_I2C_DMA[2] = {CPAL_I2C1_DMA,CPAL_I2C2_DMA}; + +const uint32_t CPAL_I2C_DMA_TX_TC_FLAG[2] = {CPAL_I2C1_DMA_TX_TC_FLAG, CPAL_I2C2_DMA_TX_TC_FLAG}; +const uint32_t CPAL_I2C_DMA_TX_HT_FLAG[2] = {CPAL_I2C1_DMA_TX_HT_FLAG, CPAL_I2C2_DMA_TX_HT_FLAG}; +const uint32_t CPAL_I2C_DMA_TX_TE_FLAG[2] = {CPAL_I2C1_DMA_TX_TE_FLAG, CPAL_I2C2_DMA_TX_TE_FLAG}; + +const uint32_t CPAL_I2C_DMA_RX_TC_FLAG[2] = {CPAL_I2C1_DMA_RX_TC_FLAG, CPAL_I2C2_DMA_RX_TC_FLAG}; +const uint32_t CPAL_I2C_DMA_RX_HT_FLAG[2] = {CPAL_I2C1_DMA_RX_HT_FLAG, CPAL_I2C2_DMA_RX_HT_FLAG}; +const uint32_t CPAL_I2C_DMA_RX_TE_FLAG[2] = {CPAL_I2C1_DMA_RX_TE_FLAG, CPAL_I2C2_DMA_RX_TE_FLAG}; + + + +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/*================== CPAL_I2C_HAL_Config ==================*/ + +/** + * @brief Reset then enable the I2C device clock. + * @param Device : I2C Device instance. + * @retval None + */ +void CPAL_I2C_HAL_CLKInit(CPAL_DevTypeDef Device) +{ + /* Reset I2Cx device clock in order to avoid non-cleared error flags */ + __I2C_RCC_RESET(CPAL_I2C_CLK [Device]); + + /* Enable I2Cx device clock */ + __I2C_CLK_CMD(CPAL_I2C_CLK [Device], ENABLE); +} + + +/** + * @brief Reset then disable the I2C device clock. + * @param Device : I2C Device instance + * @retval None. + */ +void CPAL_I2C_HAL_CLKDeInit(CPAL_DevTypeDef Device) +{ + /* Reset I2Cx device clock in order to avoid non-cleared error flags */ + __I2C_RCC_RESET(CPAL_I2C_CLK[Device]); + + /* Disable I2Cx device clock */ + __I2C_CLK_CMD(CPAL_I2C_CLK[Device], DISABLE); +} + + +/** + * @brief Configure the IO pins used by the I2C device. + * @param Device : I2C Device instance. + * @retval None. + */ +void CPAL_I2C_HAL_GPIOInit(CPAL_DevTypeDef Device) +{ + GPIO_InitTypeDef GPIO_InitStructure; + + /* Enable I2Cx SCL and SDA Pin Clock */ + __I2C_GPIO_CLK_CMD((CPAL_I2C_SCL_GPIO_CLK[Device] | CPAL_I2C_SDA_GPIO_CLK[Device]), ENABLE); + + /* Connect PXx to I2C_SCL */ + GPIO_PinAFConfig((GPIO_TypeDef*)CPAL_I2C_SCL_GPIO_PORT[Device],CPAL_I2C_SCL_GPIO_PINSOURCE[Device],CPAL_I2C_AF[Device]); + + /* Connect PXx to I2C_SDA */ + GPIO_PinAFConfig((GPIO_TypeDef*)CPAL_I2C_SDA_GPIO_PORT[Device],CPAL_I2C_SDA_GPIO_PINSOURCE[Device],CPAL_I2C_AF[Device]); + + /* Set GPIO frequency to 50MHz */ + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + + /* Select Alternate function mode */ + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + + /* Select output Open Drain type */ + GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; + + /* Disable internal Pull-up */ + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; + + /* Initialize I2Cx SCL Pin */ + GPIO_InitStructure.GPIO_Pin = CPAL_I2C_SCL_GPIO_PIN[Device]; + GPIO_Init((GPIO_TypeDef*)CPAL_I2C_SCL_GPIO_PORT[Device], &GPIO_InitStructure); + + /* Initialize I2Cx SDA Pin */ + GPIO_InitStructure.GPIO_Pin = CPAL_I2C_SDA_GPIO_PIN[Device]; + GPIO_Init((GPIO_TypeDef*)CPAL_I2C_SDA_GPIO_PORT[Device], &GPIO_InitStructure); +} + + +/** + * @brief Deinitialize the IO pins used by the I2C device + * (configured to their default state). + * @param Device : I2C Device instance. + * @retval None. + */ +void CPAL_I2C_HAL_GPIODeInit(CPAL_DevTypeDef Device) +{ + GPIO_InitTypeDef GPIO_InitStructure; + + /* Set GPIO frequency to 50MHz */ + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + + /* Select Input floating mode */ + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; + + /* Select output Open Drain type */ + GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; + + /* Disable internal Pull-up */ + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; + + /* Deinitialize I2Cx SCL Pin */ + GPIO_InitStructure.GPIO_Pin = CPAL_I2C_SCL_GPIO_PIN[Device]; + GPIO_Init((GPIO_TypeDef*)CPAL_I2C_SCL_GPIO_PORT[Device], &GPIO_InitStructure); + + /* Deinitialize I2Cx SDA Pin */ + GPIO_InitStructure.GPIO_Pin = CPAL_I2C_SDA_GPIO_PIN[Device]; + GPIO_Init((GPIO_TypeDef*)CPAL_I2C_SDA_GPIO_PORT[Device], &GPIO_InitStructure); +} + + + +#ifdef CPAL_I2C_DMA_PROGMODEL +/** + * @brief Enable the DMA clock and initialize needed DMA Channels + * used by the I2C device. + * @param Device : I2C Device instance. + * @param Direction : Transfer direction. + * @param Options : Transfer Options. + * @retval None. + */ +void CPAL_I2C_HAL_DMAInit(CPAL_DevTypeDef Device, CPAL_DirectionTypeDef Direction, uint32_t Options) +{ + /* Enable I2Cx DMA */ + __DMA_CLK_CMD(CPAL_I2C_DMA_CLK[Device], ENABLE); + + /* I2Cx Common Channel Configuration */ + CPAL_DMA_InitStructure.DMA_BufferSize = 0xFFFF; + CPAL_DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; + CPAL_DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; + CPAL_DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte ; + CPAL_DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; + CPAL_DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; + CPAL_DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; + CPAL_DMA_InitStructure.DMA_MemoryBaseAddr = 0; + CPAL_DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; + + /* If TX Direction (Transmission) selected */ + if ((Direction & CPAL_DIRECTION_TX) != 0) + { + /* Select I2Cx TXDR Address register as DMA PeripheralBaseAddress */ + CPAL_DMA_InitStructure.DMA_PeripheralBaseAddr = CPAL_I2C_TXDR [Device]; + + /* Select Memory to Peripheral transfer direction */ + CPAL_DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; + + /* Initialize I2Cx DMA Tx Channel */ + DMA_Init((DMA_Channel_TypeDef*)CPAL_I2C_DMA_TX_Channel[Device], &CPAL_DMA_InitStructure); + } + + /* If RX Direction (Reception) selected */ + if ((Direction & CPAL_DIRECTION_RX ) != 0) + { + /* Select I2Cx RXDR Address register as DMA PeripheralBaseAddress */ + CPAL_DMA_InitStructure.DMA_PeripheralBaseAddr = CPAL_I2C_RXDR [Device]; + + /* Select Peripheral to Memory transfer direction */ + CPAL_DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; + + /* Initialize I2Cx DMA Rx Channel */ + DMA_Init((DMA_Channel_TypeDef*)CPAL_I2C_DMA_RX_Channel[Device], &CPAL_DMA_InitStructure); + } +} + + +/** + * @brief Configure the DMA channel specific for TX transfer. + * @param Device : I2C Device instance. + * @param TXferStruct : DMA TX Transfer Parameters. + * @param Options : Transfer Options. + * @retval None. + */ +void CPAL_I2C_HAL_DMATXConfig(CPAL_DevTypeDef Device, CPAL_TransferTypeDef* TxXferStruct, uint32_t Options ) +{ + /* Set Memory Base Address */ + CPAL_DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)(TxXferStruct->pbBuffer); + + /* Set number of data */ + CPAL_DMA_InitStructure.DMA_BufferSize = TxXferStruct->wNumData; + + /* Select I2Cx TXDR Address register as DMA PeripheralBaseAddress */ + CPAL_DMA_InitStructure.DMA_PeripheralBaseAddr = CPAL_I2C_TXDR [Device]; + + /* If TX DMA Circular Mode Option Bit Selected */ + if ((Options & CPAL_OPT_DMATX_CIRCULAR) != 0) + { + /* Select DMA Circular Mode */ + CPAL_DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; + } + /* If TX DMA Circular Mode Option Bit not selected */ + else + { + /* Select DMA Normal Mode */ + CPAL_DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; + } + + /* Select Peripheral to Memory transfer direction */ + CPAL_DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; + + /* Initialize I2Cx DMA Tx Channel */ + DMA_Init((DMA_Channel_TypeDef*)CPAL_I2C_DMA_TX_Channel[Device], &CPAL_DMA_InitStructure); +} + + +/** + * @brief Configure the DMA channel specific for RX transfer. + * @param Device : I2C Device instance. + * @param RXferStruct : DMA RX Transfer Parameters. + * @param Options : Transfer Options. + * @retval None. + */ +void CPAL_I2C_HAL_DMARXConfig(CPAL_DevTypeDef Device, CPAL_TransferTypeDef* RxXferStruct, uint32_t Options ) +{ + /* Set Memory Base Address */ + CPAL_DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)(RxXferStruct->pbBuffer); + + /* Set number of data */ + CPAL_DMA_InitStructure.DMA_BufferSize = RxXferStruct->wNumData; + + /* Select I2Cx RXDR Address register as DMA PeripheralBaseAddress */ + CPAL_DMA_InitStructure.DMA_PeripheralBaseAddr = CPAL_I2C_RXDR [Device]; + + /* If RX DMA Circular Mode Option Bit Selected */ + if ((Options & CPAL_OPT_DMARX_CIRCULAR) != 0) + { + /* Select DMA Circular Mode */ + CPAL_DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; + } + /* If RX DMA Circular Mode Option Bit not selected */ + else + { + /* Select DMA Normal Mode */ + CPAL_DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; + } + + /* Select Peripheral to Memory transfer direction */ + CPAL_DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; + + /* Initialize I2Cx DMA Rx Channel */ + DMA_Init((DMA_Channel_TypeDef*)CPAL_I2C_DMA_RX_Channel[Device], &CPAL_DMA_InitStructure); +} + +/** + * @brief Deinitialize the DMA channel used by I2C Device(configured to their default state). + * DMA clock is not disabled. + * @param Device : I2C Device instance. + * @param Direction : Transfer direction. + * @retval None. + */ +void CPAL_I2C_HAL_DMADeInit(CPAL_DevTypeDef Device, CPAL_DirectionTypeDef Direction) +{ + /* If TX Direction (Transmission) selected */ + if ((Direction & CPAL_DIRECTION_TX) != 0) + { + /* Deinitialize I2Cx DMA Tx Channel */ + DMA_DeInit((DMA_Channel_TypeDef*)CPAL_I2C_DMA_TX_Channel[Device]); + } + + /* If RX Direction (Reception) selected */ + if ((Direction & CPAL_DIRECTION_RX) != 0) + { + /* Deinitialize I2Cx DMA Rx Channel */ + DMA_DeInit((DMA_Channel_TypeDef*)CPAL_I2C_DMA_RX_Channel[Device]); + } +} +#endif /* CPAL_I2C_DMA_PROGMODEL */ + + +/** + * @brief Configure NVIC and interrupts used by I2C Device according to + * enabled options + * @param Device : I2C Device instance. + * @param Options : I2C Transfer Options. + * @retval None. + */ +void CPAL_I2C_HAL_ITInit(CPAL_DevTypeDef Device, uint32_t Options) +{ + NVIC_InitTypeDef NVIC_InitStructure; + + /* Enable the IRQ channel */ + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + + /* Configure NVIC for I2Cx Interrupt */ + NVIC_InitStructure.NVIC_IRQChannel = CPAL_I2C_IT_IRQn [Device] ; + NVIC_InitStructure.NVIC_IRQChannelPriority = I2C_IT_PRIO[Device]; + NVIC_Init(&NVIC_InitStructure); + + /* If I2C ERR Interrupt Option Bit not selected */ + if ((Options & CPAL_OPT_I2C_ERRIT_DISABLE) == 0) + { + /* Enable I2C Error Interrupts */ + __CPAL_I2C_HAL_ENABLE_ERRIT(Device); + } + +#ifdef CPAL_I2C_DMA_PROGMODEL + /* If one or more DMA Interrupt option Bits selected */ + if (((Options & CPAL_OPT_I2C_DMA_TX_IT_MASK) != 0) || ((Options & CPAL_OPT_I2C_DMA_RX_IT_MASK) != 0)) + { + /* Configure NVIC for DMA TX channel interrupt */ + NVIC_InitStructure.NVIC_IRQChannel = CPAL_I2C_DMA_IRQn [Device]; + NVIC_InitStructure.NVIC_IRQChannelPriority = I2C_IT_DMA_PRIO[Device]; + NVIC_Init(&NVIC_InitStructure); + + /* If DMA TX TC interrupt Option Bits Selected */ + if ((Options & CPAL_OPT_DMATX_TCIT) != 0) + { + /* Enable DMA TX Channel TCIT */ + __I2C_HAL_ENABLE_DMATX_TCIT(Device); + } + + /* If DMA TX HT interrupt Option Bits Selected */ + if ((Options & CPAL_OPT_DMATX_HTIT) != 0) + { + /* Enable DMA TX Channel HTIT */ + __I2C_HAL_ENABLE_DMATX_HTIT(Device); + } + + /* If DMA TX TE interrupt Option Bits Selected */ + if ((Options & CPAL_OPT_DMATX_TEIT) != 0) + { + /* Enable DMA TX Channel TEIT */ + __I2C_HAL_ENABLE_DMATX_TEIT(Device); + } + + /* If DMA RX TC interrupt Option Bits Selected */ + if ((Options & CPAL_OPT_DMARX_TCIT) != 0) + { + /* Enable DMA RX Channel TCIT */ + __I2C_HAL_ENABLE_DMARX_TCIT(Device); + } + + /* If DMA RX HT interrupt Option Bits Selected */ + if ((Options & CPAL_OPT_DMARX_HTIT) != 0) + { + /* Enable DMA RX Channel HTIT */ + __I2C_HAL_ENABLE_DMARX_HTIT(Device); + } + + /* If DMA RX TE interrupt Option Bits Selected */ + if ((Options & CPAL_OPT_DMARX_TEIT) != 0) + { + /* Enable DMA RX Channel TEIT */ + __I2C_HAL_ENABLE_DMARX_TEIT(Device); + } + } +#endif /* CPAL_I2C_DMA_PROGMODEL */ +} + + +/** + * @brief Deinitialize NVIC and interrupts used by I2C Device in + * the current Configuration. + * @param Device : I2C Device instance. + * @param Options : I2C Transfer Options. + * @retval None. + */ +void CPAL_I2C_HAL_ITDeInit(CPAL_DevTypeDef Device, uint32_t Options ) +{ + NVIC_InitTypeDef NVIC_InitStructure; + + NVIC_InitStructure.NVIC_IRQChannelPriority = 0; + + /* Disable the IRQ channel */ + NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE; + + /* Disable I2Cx EVT IRQn */ + NVIC_InitStructure.NVIC_IRQChannel = CPAL_I2C_IT_IRQn [Device]; + NVIC_Init(&NVIC_InitStructure); + +#ifdef CPAL_I2C_DMA_PROGMODEL + /* If one or more DMA It option Bits selected */ + if (((Options & CPAL_OPT_I2C_DMA_TX_IT_MASK) != 0) || ((Options & CPAL_OPT_I2C_DMA_RX_IT_MASK) != 0)) + { + /* Disable I2Cx DMA TX IRQn */ + NVIC_InitStructure.NVIC_IRQChannel = CPAL_I2C_DMA_IRQn [Device]; + NVIC_Init(&NVIC_InitStructure); + } +#endif /* CPAL_I2C_DMA_PROGMODEL */ +} + + +/*================== CPAL_I2C1_IRQhandler ==================*/ + +#ifdef CPAL_USE_I2C1 + +/** + * @brief This function handles I2C1 interrupt request. + * @param None. + * @retval CPAL_PASS. + */ +uint32_t I2C1_IRQHandler(void) +{ + /* If interrupt sources is I2C event */ + if ((__CPAL_I2C_HAL_GET_ERROR(0) != 0) && ((I2C1_DevStructure.wCPAL_Options & CPAL_OPT_I2C_ERRIT_DISABLE) == 0)) + { + CPAL_LOG("\n\r\n\rLOG : I2C1 Device Error IT "); + + /* Call the Common Error handler function */ + return CPAL_I2C_ER_IRQHandler(&I2C1_DevStructure); + } + else + { + /* Call the Common Event handler function */ + return CPAL_I2C_EV_IRQHandler(&I2C1_DevStructure); + } +} + + #ifdef CPAL_I2C_DMA_PROGMODEL +/** + * @brief This function handles I2C1 DMA interrupt request. + * @param None. + * @retval CPAL_PASS. + */ +uint32_t CPAL_I2C1_DMA_IRQHandler(void) +{ + /* If interrupt source is DMA RX */ + if (__CPAL_I2C_HAL_GET_DMARX_IT(0) != 0) + { + /* Call the Common DMA RX handler function */ + return CPAL_I2C_DMA_RX_IRQHandler(&I2C1_DevStructure); + } + else + { + /* Call the Common DMA TX handler function */ + return CPAL_I2C_DMA_TX_IRQHandler(&I2C1_DevStructure); + } +} + #endif /* CPAL_I2C_DMA_PROGMODEL */ +#endif /* CPAL_USE_I2C1 */ + + +/*================== CPAL_I2C2_IRQhandler ==================*/ + +#ifdef CPAL_USE_I2C2 + +/** + * @brief This function handles I2C2 interrupt request. + * @param None. + * @retval CPAL_PASS. + */ +uint32_t I2C2_IRQHandler(void) +{ + /* If interrupt sources is I2C event */ + if ((__CPAL_I2C_HAL_GET_ERROR(1) != 0) && ((I2C2_DevStructure.wCPAL_Options & CPAL_OPT_I2C_ERRIT_DISABLE) == 0)) + { + CPAL_LOG("\n\r\n\rLOG : I2C2 Device Error IT "); + + /* Call the Common Error handler function */ + return CPAL_I2C_ER_IRQHandler(&I2C2_DevStructure); + } + else + { + /* Call the Common Event handler function */ + return CPAL_I2C_EV_IRQHandler(&I2C2_DevStructure); + } +} + + #ifdef CPAL_I2C_DMA_PROGMODEL +/** + * @brief This function handles I2C2 DMA interrupt request. + * @param None. + * @retval CPAL_PASS. + */ +uint32_t CPAL_I2C2_DMA_IRQHandler(void) +{ + /* If interrupt source is DMA RX */ + if (__CPAL_I2C_HAL_GET_DMARX_IT(1) != 0) + { + /* Call the Common DMA RX handler function */ + return CPAL_I2C_DMA_RX_IRQHandler(&I2C2_DevStructure); + } + else + { + /* Call the Common DMA TX handler function */ + return CPAL_I2C_DMA_TX_IRQHandler(&I2C2_DevStructure); + } +} + #endif /* CPAL_I2C_DMA_PROGMODEL */ +#endif /* CPAL_USE_I2C2 */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/STM32F0xx_CPAL_Driver/src/stm32f0xx_i2c_cpal_usercallback_template.c b/libraries/STM32F0xx_CPAL_Driver/src/stm32f0xx_i2c_cpal_usercallback_template.c new file mode 100644 --- /dev/null +++ b/libraries/STM32F0xx_CPAL_Driver/src/stm32f0xx_i2c_cpal_usercallback_template.c @@ -0,0 +1,265 @@ +/** + ****************************************************************************** + * @file stm32f0xx_i2c_cpal_usercallback.c + * @author MCD Application Team + * @version V1.2.0 + * @date 24-July-2014 + * @brief This file provides all the CPAL UserCallback functions. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2014 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_i2c_cpal.h" + +/* Private typedef -----------------------------------------------------------*/ +/* Private defines -----------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/*------------------------------------------------------------------------------ + CPAL User Callbacks implementations +------------------------------------------------------------------------------*/ + + +/*=========== Timeout UserCallback ===========*/ + + +/** + * @brief User callback that manages the Timeout error + * @param pDevInitStruct + * @retval None. + */ +uint32_t CPAL_TIMEOUT_UserCallback(CPAL_InitTypeDef* pDevInitStruct) +{ + + return CPAL_PASS; +} + + +/*=========== Transfer UserCallback ===========*/ + + +/** + * @brief Manages the End of Tx transfer event + * @param pDevInitStruct + * @retval None + */ +/*void CPAL_I2C_TXTC_UserCallback(CPAL_InitTypeDef* pDevInitStruct) +{ + +}*/ + + +/** + * @brief Manages the End of Rx transfer event + * @param pDevInitStruct + * @retval None + */ +/*void CPAL_I2C_RXTC_UserCallback(CPAL_InitTypeDef* pDevInitStruct) +{ + +}*/ + + +/** + * @brief Manages Tx transfer event + * @param pDevInitStruct + * @retval None + */ +/*void CPAL_I2C_TX_UserCallback(CPAL_InitTypeDef* pDevInitStruct) +{ + +}*/ + + +/** + * @brief Manages Rx transfer event + * @param pDevInitStruct + * @retval None + */ +/*void CPAL_I2C_RX_UserCallback(CPAL_InitTypeDef* pDevInitStruct) +{ + +}*/ + + +/** + * @brief Manages the End of DMA Tx transfer event + * @param pDevInitStruct + * @retval None + */ +/*void CPAL_I2C_DMATXTC_UserCallback(CPAL_InitTypeDef* pDevInitStruct) +{ + +}*/ + + +/** + * @brief Manages the Half of DMA Tx transfer event + * @param pDevInitStruct + * @retval None + */ +/*void CPAL_I2C_DMATXHT_UserCallback(CPAL_InitTypeDef* pDevInitStruct) +{ + +}*/ + + +/** + * @brief Manages Error of DMA Tx transfer event + * @param pDevInitStruct + * @retval None + */ +/*void CPAL_I2C_DMATXTE_UserCallback(CPAL_InitTypeDef* pDevInitStruct) +{ + +}*/ + + +/** + * @brief Manages the End of DMA Rx transfer event + * @param pDevInitStruct + * @retval None + */ +/*void CPAL_I2C_DMARXTC_UserCallback(CPAL_InitTypeDef* pDevInitStruct) +{ + +}*/ + + +/** + * @brief Manages the Half of DMA Rx transfer event + * @param pDevInitStruct + * @retval None + */ +/*void CPAL_I2C_DMARXHT_UserCallback(CPAL_InitTypeDef* pDevInitStruct) +{ + +}*/ + + +/** + * @brief Manages Error of DMA Rx transfer event + * @param pDevInitStruct + * @retval None + */ +/*void CPAL_I2C_DMARXTE_UserCallback(CPAL_InitTypeDef* pDevInitStruct) +{ + +}*/ + + +/*=========== Error UserCallback ===========*/ + + +/** + * @brief User callback that manages the I2C device errors + * @note Make sure that the define USE_SINGLE_ERROR_CALLBACK is uncommented in + * the cpal_conf.h file, otherwise this callback will not be functional + * @param pDevInitStruct + * @param DeviceError + * @retval None + */ +/*void CPAL_I2C_ERR_UserCallback(CPAL_DevTypeDef pDevInstance, uint32_t DeviceError) +{ + +}*/ + + +/** + * @brief User callback that manages BERR I2C device errors + * @note Make sure that the define USE_MULTIPLE_ERROR_CALLBACK is uncommented in + * the cpal_conf.h file, otherwise this callback will not be functional + * @param pDevInstance + * @retval None + */ +/*void CPAL_I2C_BERR_UserCallback(CPAL_DevTypeDef pDevInstance) +{ + +}*/ + + +/** + * @brief User callback that manages ARLO I2C device errors + * @note Make sure that the define USE_MULTIPLE_ERROR_CALLBACK is uncommented in + * the cpal_conf.h file, otherwise this callback will not be functional + * @param pDevInstance + * @retval None + */ +/*void CPAL_I2C_ARLO_UserCallback(CPAL_DevTypeDef pDevInstance) +{ + +}*/ + + +/** + * @brief User callback that manages OVR I2C device errors + * @note Make sure that the define USE_MULTIPLE_ERROR_CALLBACK is uncommented in + * the cpal_conf.h file, otherwise this callback will not be functional + * @param pDevInstance + * @retval None + */ +/*void CPAL_I2C_OVR_UserCallback(CPAL_DevTypeDef pDevInstance) +{ + +}*/ + + +/** + * @brief User callback that manages AF I2C device errors. + * @note Make sure that the define USE_MULTIPLE_ERROR_CALLBACK is uncommented in + * the cpal_conf.h file, otherwise this callback will not be functional + * @param pDevInstance + * @retval None + */ +/*void CPAL_I2C_AF_UserCallback(CPAL_DevTypeDef pDevInstance) +{ + +}*/ + + +/*=========== Addressing Mode UserCallback ===========*/ + + +/** + * @brief User callback that manage General Call Addressing mode + * @param pDevInitStruct + * @retval None + */ +/*void CPAL_I2C_GENCALL_UserCallback(CPAL_InitTypeDef* pDevInitStruct) +{ + +}*/ + + +/** + * @brief User callback that manage Dual Address Addressing mode + * @param pDevInitStruct + * @retval None + */ +/*void CPAL_I2C_DUALF_UserCallback(CPAL_InitTypeDef* pDevInitStruct) +{ + +}*/ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/