Mercurial > public > ostc4
comparison Common/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_fmpi2c.c @ 160:e3ca52b8e7fa
Merge with FlipDisplay
author | heinrichsweikamp |
---|---|
date | Thu, 07 Mar 2019 15:06:43 +0100 |
parents | c78bcbd5deda |
children |
comparison
equal
deleted
inserted
replaced
80:cc2bb7bb8456 | 160:e3ca52b8e7fa |
---|---|
1 /** | |
2 ****************************************************************************** | |
3 * @file stm32f4xx_hal_fmpi2c.c | |
4 * @author MCD Application Team | |
5 * @brief FMPI2C HAL module driver. | |
6 * This file provides firmware functions to manage the following | |
7 * functionalities of the Inter Integrated Circuit (FMPI2C) peripheral: | |
8 * + Initialization and de-initialization functions | |
9 * + IO operation functions | |
10 * + Peripheral State and Errors functions | |
11 * | |
12 @verbatim | |
13 ============================================================================== | |
14 ##### How to use this driver ##### | |
15 ============================================================================== | |
16 [..] | |
17 The FMPI2C HAL driver can be used as follows: | |
18 | |
19 (#) Declare a FMPI2C_HandleTypeDef handle structure, for example: | |
20 FMPI2C_HandleTypeDef hfmpi2c; | |
21 | |
22 (#)Initialize the FMPI2C low level resources by implementing the HAL_FMPI2C_MspInit() API: | |
23 (##) Enable the FMPI2Cx interface clock | |
24 (##) FMPI2C pins configuration | |
25 (+++) Enable the clock for the FMPI2C GPIOs | |
26 (+++) Configure FMPI2C pins as alternate function open-drain | |
27 (##) NVIC configuration if you need to use interrupt process | |
28 (+++) Configure the FMPI2Cx interrupt priority | |
29 (+++) Enable the NVIC FMPI2C IRQ Channel | |
30 (##) DMA Configuration if you need to use DMA process | |
31 (+++) Declare a DMA_HandleTypeDef handle structure for the transmit or receive stream | |
32 (+++) Enable the DMAx interface clock using | |
33 (+++) Configure the DMA handle parameters | |
34 (+++) Configure the DMA Tx or Rx stream | |
35 (+++) Associate the initialized DMA handle to the hfmpi2c DMA Tx or Rx handle | |
36 (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on | |
37 the DMA Tx or Rx stream | |
38 | |
39 (#) Configure the Communication Clock Timing, Own Address1, Master Addressing mode, Dual Addressing mode, | |
40 Own Address2, Own Address2 Mask, General call and Nostretch mode in the hfmpi2c Init structure. | |
41 | |
42 (#) Initialize the FMPI2C registers by calling the HAL_FMPI2C_Init(), configures also the low level Hardware | |
43 (GPIO, CLOCK, NVIC...etc) by calling the customized HAL_FMPI2C_MspInit(&hfmpi2c) API. | |
44 | |
45 (#) To check if target device is ready for communication, use the function HAL_FMPI2C_IsDeviceReady() | |
46 | |
47 (#) For FMPI2C IO and IO MEM operations, three operation modes are available within this driver : | |
48 | |
49 *** Polling mode IO operation *** | |
50 ================================= | |
51 [..] | |
52 (+) Transmit in master mode an amount of data in blocking mode using HAL_FMPI2C_Master_Transmit() | |
53 (+) Receive in master mode an amount of data in blocking mode using HAL_FMPI2C_Master_Receive() | |
54 (+) Transmit in slave mode an amount of data in blocking mode using HAL_FMPI2C_Slave_Transmit() | |
55 (+) Receive in slave mode an amount of data in blocking mode using HAL_FMPI2C_Slave_Receive() | |
56 | |
57 *** Polling mode IO MEM operation *** | |
58 ===================================== | |
59 [..] | |
60 (+) Write an amount of data in blocking mode to a specific memory address using HAL_FMPI2C_Mem_Write() | |
61 (+) Read an amount of data in blocking mode from a specific memory address using HAL_FMPI2C_Mem_Read() | |
62 | |
63 | |
64 *** Interrupt mode IO operation *** | |
65 =================================== | |
66 [..] | |
67 (+) Transmit in master mode an amount of data in non-blocking mode using HAL_FMPI2C_Master_Transmit_IT() | |
68 (+) At transmission end of transfer, HAL_FMPI2C_MasterTxCpltCallback() is executed and user can | |
69 add his own code by customization of function pointer HAL_FMPI2C_MasterTxCpltCallback() | |
70 (+) Receive in master mode an amount of data in non-blocking mode using HAL_FMPI2C_Master_Receive_IT() | |
71 (+) At reception end of transfer, HAL_FMPI2C_MasterRxCpltCallback() is executed and user can | |
72 add his own code by customization of function pointer HAL_FMPI2C_MasterRxCpltCallback() | |
73 (+) Transmit in slave mode an amount of data in non-blocking mode using HAL_FMPI2C_Slave_Transmit_IT() | |
74 (+) At transmission end of transfer, HAL_FMPI2C_SlaveTxCpltCallback() is executed and user can | |
75 add his own code by customization of function pointer HAL_FMPI2C_SlaveTxCpltCallback() | |
76 (+) Receive in slave mode an amount of data in non-blocking mode using HAL_FMPI2C_Slave_Receive_IT() | |
77 (+) At reception end of transfer, HAL_FMPI2C_SlaveRxCpltCallback() is executed and user can | |
78 add his own code by customization of function pointer HAL_FMPI2C_SlaveRxCpltCallback() | |
79 (+) In case of transfer Error, HAL_FMPI2C_ErrorCallback() function is executed and user can | |
80 add his own code by customization of function pointer HAL_FMPI2C_ErrorCallback() | |
81 (+) Abort a master FMPI2C process communication with Interrupt using HAL_FMPI2C_Master_Abort_IT() | |
82 (+) End of abort process, HAL_FMPI2C_AbortCpltCallback() is executed and user can | |
83 add his own code by customization of function pointer HAL_FMPI2C_AbortCpltCallback() | |
84 (+) Discard a slave FMPI2C process communication using __HAL_FMPI2C_GENERATE_NACK() macro. | |
85 This action will inform Master to generate a Stop condition to discard the communication. | |
86 | |
87 | |
88 *** Interrupt mode IO sequential operation *** | |
89 ============================================== | |
90 [..] | |
91 (@) These interfaces allow to manage a sequential transfer with a repeated start condition | |
92 when a direction change during transfer | |
93 [..] | |
94 (+) A specific option field manage the different steps of a sequential transfer | |
95 (+) Option field values are defined through @ref FMPI2C_XFEROPTIONS and are listed below: | |
96 (++) FMPI2C_FIRST_AND_LAST_FRAME: No sequential usage, functionnal is same as associated interfaces in no sequential mode | |
97 (++) FMPI2C_FIRST_FRAME: Sequential usage, this option allow to manage a sequence with start condition, address | |
98 and data to transfer without a final stop condition | |
99 (++) FMPI2C_FIRST_AND_NEXT_FRAME: Sequential usage (Master only), this option allow to manage a sequence with start condition, address | |
100 and data to transfer without a final stop condition, an then permit a call the same master sequential interface | |
101 several times (like HAL_FMPI2C_Master_Sequential_Transmit_IT() then HAL_FMPI2C_Master_Sequential_Transmit_IT()) | |
102 (++) FMPI2C_NEXT_FRAME: Sequential usage, this option allow to manage a sequence with a restart condition, address | |
103 and with new data to transfer if the direction change or manage only the new data to transfer | |
104 if no direction change and without a final stop condition in both cases | |
105 (++) FMPI2C_LAST_FRAME: Sequential usage, this option allow to manage a sequance with a restart condition, address | |
106 and with new data to transfer if the direction change or manage only the new data to transfer | |
107 if no direction change and with a final stop condition in both cases | |
108 (++) FMPI2C_LAST_FRAME_NO_STOP: Sequential usage (Master only), this option allow to manage a restart condition after several call of the same master sequential | |
109 interface several times (link with option FMPI2C_FIRST_AND_NEXT_FRAME). | |
110 Usage can, transfer several bytes one by one using HAL_FMPI2C_Master_Sequential_Transmit_IT(option FMPI2C_FIRST_AND_NEXT_FRAME then FMPI2C_NEXT_FRAME) | |
111 or HAL_FMPI2C_Master_Sequential_Receive_IT(option FMPI2C_FIRST_AND_NEXT_FRAME then FMPI2C_NEXT_FRAME). | |
112 Then usage of this option FMPI2C_LAST_FRAME_NO_STOP at the last Transmit or Receive sequence permit to call the oposite interface Receive or Transmit | |
113 without stopping the communication and so generate a restart condition. | |
114 | |
115 (+) Differents sequential FMPI2C interfaces are listed below: | |
116 (++) Sequential transmit in master FMPI2C mode an amount of data in non-blocking mode using HAL_FMPI2C_Master_Sequential_Transmit_IT() | |
117 (+++) At transmission end of current frame transfer, HAL_FMPI2C_MasterTxCpltCallback() is executed and user can | |
118 add his own code by customization of function pointer HAL_FMPI2C_MasterTxCpltCallback() | |
119 (++) Sequential receive in master FMPI2C mode an amount of data in non-blocking mode using HAL_FMPI2C_Master_Sequential_Receive_IT() | |
120 (+++) At reception end of current frame transfer, HAL_FMPI2C_MasterRxCpltCallback() is executed and user can | |
121 add his own code by customization of function pointer HAL_FMPI2C_MasterRxCpltCallback() | |
122 (++) Abort a master FMPI2C process communication with Interrupt using HAL_FMPI2C_Master_Abort_IT() | |
123 (+++) End of abort process, HAL_FMPI2C_AbortCpltCallback() is executed and user can | |
124 add his own code by customization of function pointer HAL_FMPI2C_AbortCpltCallback() | |
125 (++) Enable/disable the Address listen mode in slave FMPI2C mode using HAL_FMPI2C_EnableListen_IT() HAL_FMPI2C_DisableListen_IT() | |
126 (+++) When address slave FMPI2C match, HAL_FMPI2C_AddrCallback() is executed and user can | |
127 add his own code to check the Address Match Code and the transmission direction request by master (Write/Read). | |
128 (+++) At Listen mode end HAL_FMPI2C_ListenCpltCallback() is executed and user can | |
129 add his own code by customization of function pointer HAL_FMPI2C_ListenCpltCallback() | |
130 (++) Sequential transmit in slave FMPI2C mode an amount of data in non-blocking mode using HAL_FMPI2C_Slave_Sequential_Transmit_IT() | |
131 (+++) At transmission end of current frame transfer, HAL_FMPI2C_SlaveTxCpltCallback() is executed and user can | |
132 add his own code by customization of function pointer HAL_FMPI2C_SlaveTxCpltCallback() | |
133 (++) Sequential receive in slave FMPI2C mode an amount of data in non-blocking mode using HAL_FMPI2C_Slave_Sequential_Receive_IT() | |
134 (+++) At reception end of current frame transfer, HAL_FMPI2C_SlaveRxCpltCallback() is executed and user can | |
135 add his own code by customization of function pointer HAL_FMPI2C_SlaveRxCpltCallback() | |
136 (++) In case of transfer Error, HAL_FMPI2C_ErrorCallback() function is executed and user can | |
137 add his own code by customization of function pointer HAL_FMPI2C_ErrorCallback() | |
138 (++) Abort a master FMPI2C process communication with Interrupt using HAL_FMPI2C_Master_Abort_IT() | |
139 (++) End of abort process, HAL_FMPI2C_AbortCpltCallback() is executed and user can | |
140 add his own code by customization of function pointer HAL_FMPI2C_AbortCpltCallback() | |
141 (++) Discard a slave FMPI2C process communication using __HAL_FMPI2C_GENERATE_NACK() macro. | |
142 This action will inform Master to generate a Stop condition to discard the communication. | |
143 | |
144 *** Interrupt mode IO MEM operation *** | |
145 ======================================= | |
146 [..] | |
147 (+) Write an amount of data in non-blocking mode with Interrupt to a specific memory address using | |
148 HAL_FMPI2C_Mem_Write_IT() | |
149 (+) At Memory end of write transfer, HAL_FMPI2C_MemTxCpltCallback() is executed and user can | |
150 add his own code by customization of function pointer HAL_FMPI2C_MemTxCpltCallback() | |
151 (+) Read an amount of data in non-blocking mode with Interrupt from a specific memory address using | |
152 HAL_FMPI2C_Mem_Read_IT() | |
153 (+) At Memory end of read transfer, HAL_FMPI2C_MemRxCpltCallback() is executed and user can | |
154 add his own code by customization of function pointer HAL_FMPI2C_MemRxCpltCallback() | |
155 (+) In case of transfer Error, HAL_FMPI2C_ErrorCallback() function is executed and user can | |
156 add his own code by customization of function pointer HAL_FMPI2C_ErrorCallback() | |
157 | |
158 *** DMA mode IO operation *** | |
159 ============================== | |
160 [..] | |
161 (+) Transmit in master mode an amount of data in non-blocking mode (DMA) using | |
162 HAL_FMPI2C_Master_Transmit_DMA() | |
163 (+) At transmission end of transfer, HAL_FMPI2C_MasterTxCpltCallback() is executed and user can | |
164 add his own code by customization of function pointer HAL_FMPI2C_MasterTxCpltCallback() | |
165 (+) Receive in master mode an amount of data in non-blocking mode (DMA) using | |
166 HAL_FMPI2C_Master_Receive_DMA() | |
167 (+) At reception end of transfer, HAL_FMPI2C_MasterRxCpltCallback() is executed and user can | |
168 add his own code by customization of function pointer HAL_FMPI2C_MasterRxCpltCallback() | |
169 (+) Transmit in slave mode an amount of data in non-blocking mode (DMA) using | |
170 HAL_FMPI2C_Slave_Transmit_DMA() | |
171 (+) At transmission end of transfer, HAL_FMPI2C_SlaveTxCpltCallback() is executed and user can | |
172 add his own code by customization of function pointer HAL_FMPI2C_SlaveTxCpltCallback() | |
173 (+) Receive in slave mode an amount of data in non-blocking mode (DMA) using | |
174 HAL_FMPI2C_Slave_Receive_DMA() | |
175 (+) At reception end of transfer, HAL_FMPI2C_SlaveRxCpltCallback() is executed and user can | |
176 add his own code by customization of function pointer HAL_FMPI2C_SlaveRxCpltCallback() | |
177 (+) In case of transfer Error, HAL_FMPI2C_ErrorCallback() function is executed and user can | |
178 add his own code by customization of function pointer HAL_FMPI2C_ErrorCallback() | |
179 (+) Abort a master FMPI2C process communication with Interrupt using HAL_FMPI2C_Master_Abort_IT() | |
180 (+) End of abort process, HAL_FMPI2C_AbortCpltCallback() is executed and user can | |
181 add his own code by customization of function pointer HAL_FMPI2C_AbortCpltCallback() | |
182 (+) Discard a slave FMPI2C process communication using __HAL_FMPI2C_GENERATE_NACK() macro. | |
183 This action will inform Master to generate a Stop condition to discard the communication. | |
184 | |
185 *** DMA mode IO MEM operation *** | |
186 ================================= | |
187 [..] | |
188 (+) Write an amount of data in non-blocking mode with DMA to a specific memory address using | |
189 HAL_FMPI2C_Mem_Write_DMA() | |
190 (+) At Memory end of write transfer, HAL_FMPI2C_MemTxCpltCallback() is executed and user can | |
191 add his own code by customization of function pointer HAL_FMPI2C_MemTxCpltCallback() | |
192 (+) Read an amount of data in non-blocking mode with DMA from a specific memory address using | |
193 HAL_FMPI2C_Mem_Read_DMA() | |
194 (+) At Memory end of read transfer, HAL_FMPI2C_MemRxCpltCallback() is executed and user can | |
195 add his own code by customization of function pointer HAL_FMPI2C_MemRxCpltCallback() | |
196 (+) In case of transfer Error, HAL_FMPI2C_ErrorCallback() function is executed and user can | |
197 add his own code by customization of function pointer HAL_FMPI2C_ErrorCallback() | |
198 | |
199 | |
200 *** FMPI2C HAL driver macros list *** | |
201 ================================== | |
202 [..] | |
203 Below the list of most used macros in FMPI2C HAL driver. | |
204 | |
205 (+) __HAL_FMPI2C_ENABLE: Enable the FMPI2C peripheral | |
206 (+) __HAL_FMPI2C_DISABLE: Disable the FMPI2C peripheral | |
207 (+) __HAL_FMPI2C_GENERATE_NACK: Generate a Non-Acknowledge FMPI2C peripheral in Slave mode | |
208 (+) __HAL_FMPI2C_GET_FLAG: Check whether the specified FMPI2C flag is set or not | |
209 (+) __HAL_FMPI2C_CLEAR_FLAG: Clear the specified FMPI2C pending flag | |
210 (+) __HAL_FMPI2C_ENABLE_IT: Enable the specified FMPI2C interrupt | |
211 (+) __HAL_FMPI2C_DISABLE_IT: Disable the specified FMPI2C interrupt | |
212 | |
213 [..] | |
214 (@) You can refer to the FMPI2C HAL driver header file for more useful macros | |
215 | |
216 @endverbatim | |
217 ****************************************************************************** | |
218 * @attention | |
219 * | |
220 * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2> | |
221 * | |
222 * Redistribution and use in source and binary forms, with or without modification, | |
223 * are permitted provided that the following conditions are met: | |
224 * 1. Redistributions of source code must retain the above copyright notice, | |
225 * this list of conditions and the following disclaimer. | |
226 * 2. Redistributions in binary form must reproduce the above copyright notice, | |
227 * this list of conditions and the following disclaimer in the documentation | |
228 * and/or other materials provided with the distribution. | |
229 * 3. Neither the name of STMicroelectronics nor the names of its contributors | |
230 * may be used to endorse or promote products derived from this software | |
231 * without specific prior written permission. | |
232 * | |
233 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
234 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
235 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
236 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | |
237 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
238 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
239 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |
240 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |
241 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
242 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
243 * | |
244 ****************************************************************************** | |
245 */ | |
246 | |
247 /* Includes ------------------------------------------------------------------*/ | |
248 #include "stm32f4xx_hal.h" | |
249 | |
250 /** @addtogroup STM32F4xx_HAL_Driver | |
251 * @{ | |
252 */ | |
253 | |
254 /** @defgroup FMPI2C FMPI2C | |
255 * @brief FMPI2C HAL module driver | |
256 * @{ | |
257 */ | |
258 | |
259 #ifdef HAL_FMPI2C_MODULE_ENABLED | |
260 | |
261 #if defined(STM32F410Tx) || defined(STM32F410Cx) || defined(STM32F410Rx) || defined(STM32F446xx) || defined(STM32F412Zx) ||\ | |
262 defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx) | |
263 | |
264 /* Private typedef -----------------------------------------------------------*/ | |
265 /* Private define ------------------------------------------------------------*/ | |
266 | |
267 /** @defgroup FMPI2C_Private_Define FMPI2C Private Define | |
268 * @{ | |
269 */ | |
270 #define TIMING_CLEAR_MASK (0xF0FFFFFFU) /*!< FMPI2C TIMING clear register Mask */ | |
271 #define FMPI2C_TIMEOUT_ADDR (10000U) /*!< 10 s */ | |
272 #define FMPI2C_TIMEOUT_BUSY (25U) /*!< 25 ms */ | |
273 #define FMPI2C_TIMEOUT_DIR (25U) /*!< 25 ms */ | |
274 #define FMPI2C_TIMEOUT_RXNE (25U) /*!< 25 ms */ | |
275 #define FMPI2C_TIMEOUT_STOPF (25U) /*!< 25 ms */ | |
276 #define FMPI2C_TIMEOUT_TC (25U) /*!< 25 ms */ | |
277 #define FMPI2C_TIMEOUT_TCR (25U) /*!< 25 ms */ | |
278 #define FMPI2C_TIMEOUT_TXIS (25U) /*!< 25 ms */ | |
279 #define FMPI2C_TIMEOUT_FLAG (25U) /*!< 25 ms */ | |
280 | |
281 #define MAX_NBYTE_SIZE 255U | |
282 #define SlaveAddr_SHIFT 7U | |
283 #define SlaveAddr_MSK 0x06U | |
284 | |
285 /* Private define for @ref PreviousState usage */ | |
286 #define FMPI2C_STATE_MSK ((uint32_t)((HAL_FMPI2C_STATE_BUSY_TX | HAL_FMPI2C_STATE_BUSY_RX) & (~((uint32_t)HAL_FMPI2C_STATE_READY)))) /*!< Mask State define, keep only RX and TX bits */ | |
287 #define FMPI2C_STATE_NONE ((uint32_t)(HAL_FMPI2C_MODE_NONE)) /*!< Default Value */ | |
288 #define FMPI2C_STATE_MASTER_BUSY_TX ((uint32_t)((HAL_FMPI2C_STATE_BUSY_TX & FMPI2C_STATE_MSK) | HAL_FMPI2C_MODE_MASTER)) /*!< Master Busy TX, combinaison of State LSB and Mode enum */ | |
289 #define FMPI2C_STATE_MASTER_BUSY_RX ((uint32_t)((HAL_FMPI2C_STATE_BUSY_RX & FMPI2C_STATE_MSK) | HAL_FMPI2C_MODE_MASTER)) /*!< Master Busy RX, combinaison of State LSB and Mode enum */ | |
290 #define FMPI2C_STATE_SLAVE_BUSY_TX ((uint32_t)((HAL_FMPI2C_STATE_BUSY_TX & FMPI2C_STATE_MSK) | HAL_FMPI2C_MODE_SLAVE)) /*!< Slave Busy TX, combinaison of State LSB and Mode enum */ | |
291 #define FMPI2C_STATE_SLAVE_BUSY_RX ((uint32_t)((HAL_FMPI2C_STATE_BUSY_RX & FMPI2C_STATE_MSK) | HAL_FMPI2C_MODE_SLAVE)) /*!< Slave Busy RX, combinaison of State LSB and Mode enum */ | |
292 #define FMPI2C_STATE_MEM_BUSY_TX ((uint32_t)((HAL_FMPI2C_STATE_BUSY_TX & FMPI2C_STATE_MSK) | HAL_FMPI2C_MODE_MEM)) /*!< Memory Busy TX, combinaison of State LSB and Mode enum */ | |
293 #define FMPI2C_STATE_MEM_BUSY_RX ((uint32_t)((HAL_FMPI2C_STATE_BUSY_RX & FMPI2C_STATE_MSK) | HAL_FMPI2C_MODE_MEM)) /*!< Memory Busy RX, combinaison of State LSB and Mode enum */ | |
294 | |
295 | |
296 /* Private define to centralize the enable/disable of Interrupts */ | |
297 #define FMPI2C_XFER_TX_IT (0x00000001U) | |
298 #define FMPI2C_XFER_RX_IT (0x00000002U) | |
299 #define FMPI2C_XFER_LISTEN_IT (0x00000004U) | |
300 | |
301 #define FMPI2C_XFER_ERROR_IT (0x00000011U) | |
302 #define FMPI2C_XFER_CPLT_IT (0x00000012U) | |
303 #define FMPI2C_XFER_RELOAD_IT (0x00000012U) | |
304 | |
305 /* Private define Sequential Transfer Options default/reset value */ | |
306 #define FMPI2C_NO_OPTION_FRAME (0xFFFF0000U) | |
307 /** | |
308 * @} | |
309 */ | |
310 | |
311 /* Private macro -------------------------------------------------------------*/ | |
312 #define FMPI2C_GET_DMA_REMAIN_DATA(__HANDLE__) ((((__HANDLE__)->State) == HAL_FMPI2C_STATE_BUSY_TX) ? \ | |
313 ((uint32_t)(((DMA_Stream_TypeDef *)(__HANDLE__)->hdmatx->Instance)->NDTR)) : \ | |
314 ((uint32_t)(((DMA_Stream_TypeDef *)(__HANDLE__)->hdmarx->Instance)->NDTR))) | |
315 | |
316 /* Private variables ---------------------------------------------------------*/ | |
317 /* Private function prototypes -----------------------------------------------*/ | |
318 | |
319 /** @defgroup FMPI2C_Private_Functions FMPI2C Private Functions | |
320 * @{ | |
321 */ | |
322 /* Private functions to handle DMA transfer */ | |
323 static void FMPI2C_DMAMasterTransmitCplt(DMA_HandleTypeDef *hdma); | |
324 static void FMPI2C_DMAMasterReceiveCplt(DMA_HandleTypeDef *hdma); | |
325 static void FMPI2C_DMASlaveTransmitCplt(DMA_HandleTypeDef *hdma); | |
326 static void FMPI2C_DMASlaveReceiveCplt(DMA_HandleTypeDef *hdma); | |
327 static void FMPI2C_DMAError(DMA_HandleTypeDef *hdma); | |
328 static void FMPI2C_DMAAbort(DMA_HandleTypeDef *hdma); | |
329 | |
330 /* Private functions to handle IT transfer */ | |
331 static void FMPI2C_ITAddrCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags); | |
332 static void FMPI2C_ITMasterSequentialCplt(FMPI2C_HandleTypeDef *hfmpi2c); | |
333 static void FMPI2C_ITSlaveSequentialCplt(FMPI2C_HandleTypeDef *hfmpi2c); | |
334 static void FMPI2C_ITMasterCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags); | |
335 static void FMPI2C_ITSlaveCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags); | |
336 static void FMPI2C_ITListenCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags); | |
337 static void FMPI2C_ITError(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ErrorCode); | |
338 | |
339 /* Private functions to handle IT transfer */ | |
340 static HAL_StatusTypeDef FMPI2C_RequestMemoryWrite(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart); | |
341 static HAL_StatusTypeDef FMPI2C_RequestMemoryRead(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart); | |
342 | |
343 /* Private functions for FMPI2C transfer IRQ handler */ | |
344 static HAL_StatusTypeDef FMPI2C_Master_ISR_IT(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags, uint32_t ITSources); | |
345 static HAL_StatusTypeDef FMPI2C_Slave_ISR_IT(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags, uint32_t ITSources); | |
346 static HAL_StatusTypeDef FMPI2C_Master_ISR_DMA(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags, uint32_t ITSources); | |
347 static HAL_StatusTypeDef FMPI2C_Slave_ISR_DMA(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags, uint32_t ITSources); | |
348 | |
349 /* Private functions to handle flags during polling transfer */ | |
350 static HAL_StatusTypeDef FMPI2C_WaitOnFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t Tickstart); | |
351 static HAL_StatusTypeDef FMPI2C_WaitOnTXISFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout, uint32_t Tickstart); | |
352 static HAL_StatusTypeDef FMPI2C_WaitOnRXNEFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout, uint32_t Tickstart); | |
353 static HAL_StatusTypeDef FMPI2C_WaitOnSTOPFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout, uint32_t Tickstart); | |
354 static HAL_StatusTypeDef FMPI2C_IsAcknowledgeFailed(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout, uint32_t Tickstart); | |
355 | |
356 /* Private functions to centralize the enable/disable of Interrupts */ | |
357 static HAL_StatusTypeDef FMPI2C_Enable_IRQ(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t InterruptRequest); | |
358 static HAL_StatusTypeDef FMPI2C_Disable_IRQ(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t InterruptRequest); | |
359 | |
360 /* Private functions to flush TXDR register */ | |
361 static void FMPI2C_Flush_TXDR(FMPI2C_HandleTypeDef *hfmpi2c); | |
362 | |
363 /* Private functions to handle start, restart or stop a transfer */ | |
364 static void FMPI2C_TransferConfig(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t Size, uint32_t Mode, uint32_t Request); | |
365 /** | |
366 * @} | |
367 */ | |
368 | |
369 /* Exported functions --------------------------------------------------------*/ | |
370 | |
371 /** @defgroup FMPI2C_Exported_Functions FMPI2C Exported Functions | |
372 * @{ | |
373 */ | |
374 | |
375 /** @defgroup FMPI2C_Exported_Functions_Group1 Initialization and de-initialization functions | |
376 * @brief Initialization and Configuration functions | |
377 * | |
378 @verbatim | |
379 =============================================================================== | |
380 ##### Initialization and de-initialization functions ##### | |
381 =============================================================================== | |
382 [..] This subsection provides a set of functions allowing to initialize and | |
383 deinitialize the FMPI2Cx peripheral: | |
384 | |
385 (+) User must Implement HAL_FMPI2C_MspInit() function in which he configures | |
386 all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ). | |
387 | |
388 (+) Call the function HAL_FMPI2C_Init() to configure the selected device with | |
389 the selected configuration: | |
390 (++) Clock Timing | |
391 (++) Own Address 1 | |
392 (++) Addressing mode (Master, Slave) | |
393 (++) Dual Addressing mode | |
394 (++) Own Address 2 | |
395 (++) Own Address 2 Mask | |
396 (++) General call mode | |
397 (++) Nostretch mode | |
398 | |
399 (+) Call the function HAL_FMPI2C_DeInit() to restore the default configuration | |
400 of the selected FMPI2Cx peripheral. | |
401 | |
402 @endverbatim | |
403 * @{ | |
404 */ | |
405 | |
406 /** | |
407 * @brief Initializes the FMPI2C according to the specified parameters | |
408 * in the FMPI2C_InitTypeDef and initialize the associated handle. | |
409 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
410 * the configuration information for the specified FMPI2C. | |
411 * @retval HAL status | |
412 */ | |
413 HAL_StatusTypeDef HAL_FMPI2C_Init(FMPI2C_HandleTypeDef *hfmpi2c) | |
414 { | |
415 /* Check the FMPI2C handle allocation */ | |
416 if (hfmpi2c == NULL) | |
417 { | |
418 return HAL_ERROR; | |
419 } | |
420 | |
421 /* Check the parameters */ | |
422 assert_param(IS_FMPI2C_ALL_INSTANCE(hfmpi2c->Instance)); | |
423 assert_param(IS_FMPI2C_OWN_ADDRESS1(hfmpi2c->Init.OwnAddress1)); | |
424 assert_param(IS_FMPI2C_ADDRESSING_MODE(hfmpi2c->Init.AddressingMode)); | |
425 assert_param(IS_FMPI2C_DUAL_ADDRESS(hfmpi2c->Init.DualAddressMode)); | |
426 assert_param(IS_FMPI2C_OWN_ADDRESS2(hfmpi2c->Init.OwnAddress2)); | |
427 assert_param(IS_FMPI2C_OWN_ADDRESS2_MASK(hfmpi2c->Init.OwnAddress2Masks)); | |
428 assert_param(IS_FMPI2C_GENERAL_CALL(hfmpi2c->Init.GeneralCallMode)); | |
429 assert_param(IS_FMPI2C_NO_STRETCH(hfmpi2c->Init.NoStretchMode)); | |
430 | |
431 if (hfmpi2c->State == HAL_FMPI2C_STATE_RESET) | |
432 { | |
433 /* Allocate lock resource and initialize it */ | |
434 hfmpi2c->Lock = HAL_UNLOCKED; | |
435 | |
436 /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */ | |
437 HAL_FMPI2C_MspInit(hfmpi2c); | |
438 } | |
439 | |
440 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY; | |
441 | |
442 /* Disable the selected FMPI2C peripheral */ | |
443 __HAL_FMPI2C_DISABLE(hfmpi2c); | |
444 | |
445 /*---------------------------- FMPI2Cx TIMINGR Configuration ------------------*/ | |
446 /* Configure FMPI2Cx: Frequency range */ | |
447 hfmpi2c->Instance->TIMINGR = hfmpi2c->Init.Timing & TIMING_CLEAR_MASK; | |
448 | |
449 /*---------------------------- FMPI2Cx OAR1 Configuration ---------------------*/ | |
450 /* Disable Own Address1 before set the Own Address1 configuration */ | |
451 hfmpi2c->Instance->OAR1 &= ~FMPI2C_OAR1_OA1EN; | |
452 | |
453 /* Configure FMPI2Cx: Own Address1 and ack own address1 mode */ | |
454 if (hfmpi2c->Init.AddressingMode == FMPI2C_ADDRESSINGMODE_7BIT) | |
455 { | |
456 hfmpi2c->Instance->OAR1 = (FMPI2C_OAR1_OA1EN | hfmpi2c->Init.OwnAddress1); | |
457 } | |
458 else /* FMPI2C_ADDRESSINGMODE_10BIT */ | |
459 { | |
460 hfmpi2c->Instance->OAR1 = (FMPI2C_OAR1_OA1EN | FMPI2C_OAR1_OA1MODE | hfmpi2c->Init.OwnAddress1); | |
461 } | |
462 | |
463 /*---------------------------- FMPI2Cx CR2 Configuration ----------------------*/ | |
464 /* Configure FMPI2Cx: Addressing Master mode */ | |
465 if (hfmpi2c->Init.AddressingMode == FMPI2C_ADDRESSINGMODE_10BIT) | |
466 { | |
467 hfmpi2c->Instance->CR2 = (FMPI2C_CR2_ADD10); | |
468 } | |
469 /* Enable the AUTOEND by default, and enable NACK (should be disable only during Slave process */ | |
470 hfmpi2c->Instance->CR2 |= (FMPI2C_CR2_AUTOEND | FMPI2C_CR2_NACK); | |
471 | |
472 /*---------------------------- FMPI2Cx OAR2 Configuration ---------------------*/ | |
473 /* Disable Own Address2 before set the Own Address2 configuration */ | |
474 hfmpi2c->Instance->OAR2 &= ~FMPI2C_DUALADDRESS_ENABLE; | |
475 | |
476 /* Configure FMPI2Cx: Dual mode and Own Address2 */ | |
477 hfmpi2c->Instance->OAR2 = (hfmpi2c->Init.DualAddressMode | hfmpi2c->Init.OwnAddress2 | (hfmpi2c->Init.OwnAddress2Masks << 8)); | |
478 | |
479 /*---------------------------- FMPI2Cx CR1 Configuration ----------------------*/ | |
480 /* Configure FMPI2Cx: Generalcall and NoStretch mode */ | |
481 hfmpi2c->Instance->CR1 = (hfmpi2c->Init.GeneralCallMode | hfmpi2c->Init.NoStretchMode); | |
482 | |
483 /* Enable the selected FMPI2C peripheral */ | |
484 __HAL_FMPI2C_ENABLE(hfmpi2c); | |
485 | |
486 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; | |
487 hfmpi2c->State = HAL_FMPI2C_STATE_READY; | |
488 hfmpi2c->PreviousState = FMPI2C_STATE_NONE; | |
489 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; | |
490 | |
491 return HAL_OK; | |
492 } | |
493 | |
494 /** | |
495 * @brief DeInitialize the FMPI2C peripheral. | |
496 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
497 * the configuration information for the specified FMPI2C. | |
498 * @retval HAL status | |
499 */ | |
500 HAL_StatusTypeDef HAL_FMPI2C_DeInit(FMPI2C_HandleTypeDef *hfmpi2c) | |
501 { | |
502 /* Check the FMPI2C handle allocation */ | |
503 if (hfmpi2c == NULL) | |
504 { | |
505 return HAL_ERROR; | |
506 } | |
507 | |
508 /* Check the parameters */ | |
509 assert_param(IS_FMPI2C_ALL_INSTANCE(hfmpi2c->Instance)); | |
510 | |
511 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY; | |
512 | |
513 /* Disable the FMPI2C Peripheral Clock */ | |
514 __HAL_FMPI2C_DISABLE(hfmpi2c); | |
515 | |
516 /* DeInit the low level hardware: GPIO, CLOCK, NVIC */ | |
517 HAL_FMPI2C_MspDeInit(hfmpi2c); | |
518 | |
519 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; | |
520 hfmpi2c->State = HAL_FMPI2C_STATE_RESET; | |
521 hfmpi2c->PreviousState = FMPI2C_STATE_NONE; | |
522 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; | |
523 | |
524 /* Release Lock */ | |
525 __HAL_UNLOCK(hfmpi2c); | |
526 | |
527 return HAL_OK; | |
528 } | |
529 | |
530 /** | |
531 * @brief Initialize the FMPI2C MSP. | |
532 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
533 * the configuration information for the specified FMPI2C. | |
534 * @retval None | |
535 */ | |
536 __weak void HAL_FMPI2C_MspInit(FMPI2C_HandleTypeDef *hfmpi2c) | |
537 { | |
538 /* Prevent unused argument(s) compilation warning */ | |
539 UNUSED(hfmpi2c); | |
540 | |
541 /* NOTE : This function should not be modified, when the callback is needed, | |
542 the HAL_FMPI2C_MspInit could be implemented in the user file | |
543 */ | |
544 } | |
545 | |
546 /** | |
547 * @brief DeInitialize the FMPI2C MSP. | |
548 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
549 * the configuration information for the specified FMPI2C. | |
550 * @retval None | |
551 */ | |
552 __weak void HAL_FMPI2C_MspDeInit(FMPI2C_HandleTypeDef *hfmpi2c) | |
553 { | |
554 /* Prevent unused argument(s) compilation warning */ | |
555 UNUSED(hfmpi2c); | |
556 | |
557 /* NOTE : This function should not be modified, when the callback is needed, | |
558 the HAL_FMPI2C_MspDeInit could be implemented in the user file | |
559 */ | |
560 } | |
561 | |
562 /** | |
563 * @} | |
564 */ | |
565 | |
566 /** @defgroup FMPI2C_Exported_Functions_Group2 Input and Output operation functions | |
567 * @brief Data transfers functions | |
568 * | |
569 @verbatim | |
570 =============================================================================== | |
571 ##### IO operation functions ##### | |
572 =============================================================================== | |
573 [..] | |
574 This subsection provides a set of functions allowing to manage the FMPI2C data | |
575 transfers. | |
576 | |
577 (#) There are two modes of transfer: | |
578 (++) Blocking mode : The communication is performed in the polling mode. | |
579 The status of all data processing is returned by the same function | |
580 after finishing transfer. | |
581 (++) No-Blocking mode : The communication is performed using Interrupts | |
582 or DMA. These functions return the status of the transfer startup. | |
583 The end of the data processing will be indicated through the | |
584 dedicated FMPI2C IRQ when using Interrupt mode or the DMA IRQ when | |
585 using DMA mode. | |
586 | |
587 (#) Blocking mode functions are : | |
588 (++) HAL_FMPI2C_Master_Transmit() | |
589 (++) HAL_FMPI2C_Master_Receive() | |
590 (++) HAL_FMPI2C_Slave_Transmit() | |
591 (++) HAL_FMPI2C_Slave_Receive() | |
592 (++) HAL_FMPI2C_Mem_Write() | |
593 (++) HAL_FMPI2C_Mem_Read() | |
594 (++) HAL_FMPI2C_IsDeviceReady() | |
595 | |
596 (#) No-Blocking mode functions with Interrupt are : | |
597 (++) HAL_FMPI2C_Master_Transmit_IT() | |
598 (++) HAL_FMPI2C_Master_Receive_IT() | |
599 (++) HAL_FMPI2C_Slave_Transmit_IT() | |
600 (++) HAL_FMPI2C_Slave_Receive_IT() | |
601 (++) HAL_FMPI2C_Master_Sequential_Transmit_IT() | |
602 (++) HAL_FMPI2C_Master_Sequential_Receive_IT() | |
603 (++) HAL_FMPI2C_Slave_Sequential_Transmit_IT() | |
604 (++) HAL_FMPI2C_Slave_Sequential_Receive_IT() | |
605 (++) HAL_FMPI2C_Mem_Write_IT() | |
606 (++) HAL_FMPI2C_Mem_Read_IT() | |
607 | |
608 (#) No-Blocking mode functions with DMA are : | |
609 (++) HAL_FMPI2C_Master_Transmit_DMA() | |
610 (++) HAL_FMPI2C_Master_Receive_DMA() | |
611 (++) HAL_FMPI2C_Slave_Transmit_DMA() | |
612 (++) HAL_FMPI2C_Slave_Receive_DMA() | |
613 (++) HAL_FMPI2C_Mem_Write_DMA() | |
614 (++) HAL_FMPI2C_Mem_Read_DMA() | |
615 | |
616 (#) A set of Transfer Complete Callbacks are provided in non Blocking mode: | |
617 (++) HAL_FMPI2C_MemTxCpltCallback() | |
618 (++) HAL_FMPI2C_MemRxCpltCallback() | |
619 (++) HAL_FMPI2C_MasterTxCpltCallback() | |
620 (++) HAL_FMPI2C_MasterRxCpltCallback() | |
621 (++) HAL_FMPI2C_SlaveTxCpltCallback() | |
622 (++) HAL_FMPI2C_SlaveRxCpltCallback() | |
623 (++) HAL_FMPI2C_ErrorCallback() | |
624 | |
625 @endverbatim | |
626 * @{ | |
627 */ | |
628 | |
629 /** | |
630 * @brief Transmits in master mode an amount of data in blocking mode. | |
631 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
632 * the configuration information for the specified FMPI2C. | |
633 * @param DevAddress Target device address The device 7 bits address value | |
634 * in datasheet must be shifted to the left before calling the interface | |
635 * @param pData Pointer to data buffer | |
636 * @param Size Amount of data to be sent | |
637 * @param Timeout Timeout duration | |
638 * @retval HAL status | |
639 */ | |
640 HAL_StatusTypeDef HAL_FMPI2C_Master_Transmit(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout) | |
641 { | |
642 uint32_t tickstart = 0U; | |
643 | |
644 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) | |
645 { | |
646 /* Process Locked */ | |
647 __HAL_LOCK(hfmpi2c); | |
648 | |
649 /* Init tickstart for timeout management*/ | |
650 tickstart = HAL_GetTick(); | |
651 | |
652 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, FMPI2C_TIMEOUT_BUSY, tickstart) != HAL_OK) | |
653 { | |
654 return HAL_TIMEOUT; | |
655 } | |
656 | |
657 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX; | |
658 hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER; | |
659 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; | |
660 | |
661 /* Prepare transfer parameters */ | |
662 hfmpi2c->pBuffPtr = pData; | |
663 hfmpi2c->XferCount = Size; | |
664 hfmpi2c->XferISR = NULL; | |
665 | |
666 /* Send Slave Address */ | |
667 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ | |
668 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) | |
669 { | |
670 hfmpi2c->XferSize = MAX_NBYTE_SIZE; | |
671 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_GENERATE_START_WRITE); | |
672 } | |
673 else | |
674 { | |
675 hfmpi2c->XferSize = hfmpi2c->XferCount; | |
676 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_GENERATE_START_WRITE); | |
677 } | |
678 | |
679 while (hfmpi2c->XferCount > 0U) | |
680 { | |
681 /* Wait until TXIS flag is set */ | |
682 if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK) | |
683 { | |
684 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) | |
685 { | |
686 return HAL_ERROR; | |
687 } | |
688 else | |
689 { | |
690 return HAL_TIMEOUT; | |
691 } | |
692 } | |
693 /* Write data to TXDR */ | |
694 hfmpi2c->Instance->TXDR = (*hfmpi2c->pBuffPtr++); | |
695 hfmpi2c->XferCount--; | |
696 hfmpi2c->XferSize--; | |
697 | |
698 if ((hfmpi2c->XferSize == 0U) && (hfmpi2c->XferCount != 0U)) | |
699 { | |
700 /* Wait until TCR flag is set */ | |
701 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK) | |
702 { | |
703 return HAL_TIMEOUT; | |
704 } | |
705 | |
706 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) | |
707 { | |
708 hfmpi2c->XferSize = MAX_NBYTE_SIZE; | |
709 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP); | |
710 } | |
711 else | |
712 { | |
713 hfmpi2c->XferSize = hfmpi2c->XferCount; | |
714 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP); | |
715 } | |
716 } | |
717 } | |
718 | |
719 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ | |
720 /* Wait until STOPF flag is set */ | |
721 if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK) | |
722 { | |
723 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) | |
724 { | |
725 return HAL_ERROR; | |
726 } | |
727 else | |
728 { | |
729 return HAL_TIMEOUT; | |
730 } | |
731 } | |
732 | |
733 /* Clear STOP Flag */ | |
734 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); | |
735 | |
736 /* Clear Configuration Register 2 */ | |
737 FMPI2C_RESET_CR2(hfmpi2c); | |
738 | |
739 hfmpi2c->State = HAL_FMPI2C_STATE_READY; | |
740 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; | |
741 | |
742 /* Process Unlocked */ | |
743 __HAL_UNLOCK(hfmpi2c); | |
744 | |
745 return HAL_OK; | |
746 } | |
747 else | |
748 { | |
749 return HAL_BUSY; | |
750 } | |
751 } | |
752 | |
753 /** | |
754 * @brief Receives in master mode an amount of data in blocking mode. | |
755 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
756 * the configuration information for the specified FMPI2C. | |
757 * @param DevAddress Target device address The device 7 bits address value | |
758 * in datasheet must be shifted to the left before calling the interface | |
759 * @param pData Pointer to data buffer | |
760 * @param Size Amount of data to be sent | |
761 * @param Timeout Timeout duration | |
762 * @retval HAL status | |
763 */ | |
764 HAL_StatusTypeDef HAL_FMPI2C_Master_Receive(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout) | |
765 { | |
766 uint32_t tickstart = 0U; | |
767 | |
768 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) | |
769 { | |
770 /* Process Locked */ | |
771 __HAL_LOCK(hfmpi2c); | |
772 | |
773 /* Init tickstart for timeout management*/ | |
774 tickstart = HAL_GetTick(); | |
775 | |
776 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, FMPI2C_TIMEOUT_BUSY, tickstart) != HAL_OK) | |
777 { | |
778 return HAL_TIMEOUT; | |
779 } | |
780 | |
781 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX; | |
782 hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER; | |
783 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; | |
784 | |
785 /* Prepare transfer parameters */ | |
786 hfmpi2c->pBuffPtr = pData; | |
787 hfmpi2c->XferCount = Size; | |
788 hfmpi2c->XferISR = NULL; | |
789 | |
790 /* Send Slave Address */ | |
791 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ | |
792 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) | |
793 { | |
794 hfmpi2c->XferSize = MAX_NBYTE_SIZE; | |
795 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_GENERATE_START_READ); | |
796 } | |
797 else | |
798 { | |
799 hfmpi2c->XferSize = hfmpi2c->XferCount; | |
800 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_GENERATE_START_READ); | |
801 } | |
802 | |
803 while (hfmpi2c->XferCount > 0U) | |
804 { | |
805 /* Wait until RXNE flag is set */ | |
806 if (FMPI2C_WaitOnRXNEFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK) | |
807 { | |
808 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) | |
809 { | |
810 return HAL_ERROR; | |
811 } | |
812 else | |
813 { | |
814 return HAL_TIMEOUT; | |
815 } | |
816 } | |
817 | |
818 /* Read data from RXDR */ | |
819 (*hfmpi2c->pBuffPtr++) = hfmpi2c->Instance->RXDR; | |
820 hfmpi2c->XferSize--; | |
821 hfmpi2c->XferCount--; | |
822 | |
823 if ((hfmpi2c->XferSize == 0U) && (hfmpi2c->XferCount != 0U)) | |
824 { | |
825 /* Wait until TCR flag is set */ | |
826 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK) | |
827 { | |
828 return HAL_TIMEOUT; | |
829 } | |
830 | |
831 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) | |
832 { | |
833 hfmpi2c->XferSize = MAX_NBYTE_SIZE; | |
834 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP); | |
835 } | |
836 else | |
837 { | |
838 hfmpi2c->XferSize = hfmpi2c->XferCount; | |
839 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP); | |
840 } | |
841 } | |
842 } | |
843 | |
844 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ | |
845 /* Wait until STOPF flag is set */ | |
846 if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK) | |
847 { | |
848 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) | |
849 { | |
850 return HAL_ERROR; | |
851 } | |
852 else | |
853 { | |
854 return HAL_TIMEOUT; | |
855 } | |
856 } | |
857 | |
858 /* Clear STOP Flag */ | |
859 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); | |
860 | |
861 /* Clear Configuration Register 2 */ | |
862 FMPI2C_RESET_CR2(hfmpi2c); | |
863 | |
864 hfmpi2c->State = HAL_FMPI2C_STATE_READY; | |
865 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; | |
866 | |
867 /* Process Unlocked */ | |
868 __HAL_UNLOCK(hfmpi2c); | |
869 | |
870 return HAL_OK; | |
871 } | |
872 else | |
873 { | |
874 return HAL_BUSY; | |
875 } | |
876 } | |
877 | |
878 /** | |
879 * @brief Transmits in slave mode an amount of data in blocking mode. | |
880 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
881 * the configuration information for the specified FMPI2C. | |
882 * @param pData Pointer to data buffer | |
883 * @param Size Amount of data to be sent | |
884 * @param Timeout Timeout duration | |
885 * @retval HAL status | |
886 */ | |
887 HAL_StatusTypeDef HAL_FMPI2C_Slave_Transmit(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout) | |
888 { | |
889 uint32_t tickstart = 0U; | |
890 | |
891 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) | |
892 { | |
893 if ((pData == NULL) || (Size == 0U)) | |
894 { | |
895 return HAL_ERROR; | |
896 } | |
897 /* Process Locked */ | |
898 __HAL_LOCK(hfmpi2c); | |
899 | |
900 /* Init tickstart for timeout management*/ | |
901 tickstart = HAL_GetTick(); | |
902 | |
903 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX; | |
904 hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE; | |
905 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; | |
906 | |
907 /* Prepare transfer parameters */ | |
908 hfmpi2c->pBuffPtr = pData; | |
909 hfmpi2c->XferCount = Size; | |
910 hfmpi2c->XferISR = NULL; | |
911 | |
912 /* Enable Address Acknowledge */ | |
913 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK; | |
914 | |
915 /* Wait until ADDR flag is set */ | |
916 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK) | |
917 { | |
918 /* Disable Address Acknowledge */ | |
919 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; | |
920 return HAL_TIMEOUT; | |
921 } | |
922 | |
923 /* Clear ADDR flag */ | |
924 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR); | |
925 | |
926 /* If 10bit addressing mode is selected */ | |
927 if (hfmpi2c->Init.AddressingMode == FMPI2C_ADDRESSINGMODE_10BIT) | |
928 { | |
929 /* Wait until ADDR flag is set */ | |
930 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK) | |
931 { | |
932 /* Disable Address Acknowledge */ | |
933 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; | |
934 return HAL_TIMEOUT; | |
935 } | |
936 | |
937 /* Clear ADDR flag */ | |
938 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR); | |
939 } | |
940 | |
941 /* Wait until DIR flag is set Transmitter mode */ | |
942 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_DIR, RESET, Timeout, tickstart) != HAL_OK) | |
943 { | |
944 /* Disable Address Acknowledge */ | |
945 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; | |
946 return HAL_TIMEOUT; | |
947 } | |
948 | |
949 while (hfmpi2c->XferCount > 0U) | |
950 { | |
951 /* Wait until TXIS flag is set */ | |
952 if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK) | |
953 { | |
954 /* Disable Address Acknowledge */ | |
955 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; | |
956 | |
957 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) | |
958 { | |
959 return HAL_ERROR; | |
960 } | |
961 else | |
962 { | |
963 return HAL_TIMEOUT; | |
964 } | |
965 } | |
966 | |
967 /* Write data to TXDR */ | |
968 hfmpi2c->Instance->TXDR = (*hfmpi2c->pBuffPtr++); | |
969 hfmpi2c->XferCount--; | |
970 } | |
971 | |
972 /* Wait until STOP flag is set */ | |
973 if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK) | |
974 { | |
975 /* Disable Address Acknowledge */ | |
976 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; | |
977 | |
978 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) | |
979 { | |
980 /* Normal use case for Transmitter mode */ | |
981 /* A NACK is generated to confirm the end of transfer */ | |
982 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; | |
983 } | |
984 else | |
985 { | |
986 return HAL_TIMEOUT; | |
987 } | |
988 } | |
989 | |
990 /* Clear STOP flag */ | |
991 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); | |
992 | |
993 /* Wait until BUSY flag is reset */ | |
994 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, Timeout, tickstart) != HAL_OK) | |
995 { | |
996 /* Disable Address Acknowledge */ | |
997 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; | |
998 return HAL_TIMEOUT; | |
999 } | |
1000 | |
1001 /* Disable Address Acknowledge */ | |
1002 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; | |
1003 | |
1004 hfmpi2c->State = HAL_FMPI2C_STATE_READY; | |
1005 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; | |
1006 | |
1007 /* Process Unlocked */ | |
1008 __HAL_UNLOCK(hfmpi2c); | |
1009 | |
1010 return HAL_OK; | |
1011 } | |
1012 else | |
1013 { | |
1014 return HAL_BUSY; | |
1015 } | |
1016 } | |
1017 | |
1018 /** | |
1019 * @brief Receive in slave mode an amount of data in blocking mode | |
1020 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
1021 * the configuration information for the specified FMPI2C. | |
1022 * @param pData Pointer to data buffer | |
1023 * @param Size Amount of data to be sent | |
1024 * @param Timeout Timeout duration | |
1025 * @retval HAL status | |
1026 */ | |
1027 HAL_StatusTypeDef HAL_FMPI2C_Slave_Receive(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout) | |
1028 { | |
1029 uint32_t tickstart = 0U; | |
1030 | |
1031 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) | |
1032 { | |
1033 if ((pData == NULL) || (Size == 0U)) | |
1034 { | |
1035 return HAL_ERROR; | |
1036 } | |
1037 /* Process Locked */ | |
1038 __HAL_LOCK(hfmpi2c); | |
1039 | |
1040 /* Init tickstart for timeout management*/ | |
1041 tickstart = HAL_GetTick(); | |
1042 | |
1043 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX; | |
1044 hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE; | |
1045 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; | |
1046 | |
1047 /* Prepare transfer parameters */ | |
1048 hfmpi2c->pBuffPtr = pData; | |
1049 hfmpi2c->XferCount = Size; | |
1050 hfmpi2c->XferISR = NULL; | |
1051 | |
1052 /* Enable Address Acknowledge */ | |
1053 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK; | |
1054 | |
1055 /* Wait until ADDR flag is set */ | |
1056 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK) | |
1057 { | |
1058 /* Disable Address Acknowledge */ | |
1059 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; | |
1060 return HAL_TIMEOUT; | |
1061 } | |
1062 | |
1063 /* Clear ADDR flag */ | |
1064 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR); | |
1065 | |
1066 /* Wait until DIR flag is reset Receiver mode */ | |
1067 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_DIR, SET, Timeout, tickstart) != HAL_OK) | |
1068 { | |
1069 /* Disable Address Acknowledge */ | |
1070 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; | |
1071 return HAL_TIMEOUT; | |
1072 } | |
1073 | |
1074 while (hfmpi2c->XferCount > 0U) | |
1075 { | |
1076 /* Wait until RXNE flag is set */ | |
1077 if (FMPI2C_WaitOnRXNEFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK) | |
1078 { | |
1079 /* Disable Address Acknowledge */ | |
1080 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; | |
1081 | |
1082 /* Store Last receive data if any */ | |
1083 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_RXNE) == SET) | |
1084 { | |
1085 /* Read data from RXDR */ | |
1086 (*hfmpi2c->pBuffPtr++) = hfmpi2c->Instance->RXDR; | |
1087 hfmpi2c->XferCount--; | |
1088 } | |
1089 | |
1090 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_TIMEOUT) | |
1091 { | |
1092 return HAL_TIMEOUT; | |
1093 } | |
1094 else | |
1095 { | |
1096 return HAL_ERROR; | |
1097 } | |
1098 } | |
1099 | |
1100 /* Read data from RXDR */ | |
1101 (*hfmpi2c->pBuffPtr++) = hfmpi2c->Instance->RXDR; | |
1102 hfmpi2c->XferCount--; | |
1103 } | |
1104 | |
1105 /* Wait until STOP flag is set */ | |
1106 if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK) | |
1107 { | |
1108 /* Disable Address Acknowledge */ | |
1109 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; | |
1110 | |
1111 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) | |
1112 { | |
1113 return HAL_ERROR; | |
1114 } | |
1115 else | |
1116 { | |
1117 return HAL_TIMEOUT; | |
1118 } | |
1119 } | |
1120 | |
1121 /* Clear STOP flag */ | |
1122 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); | |
1123 | |
1124 /* Wait until BUSY flag is reset */ | |
1125 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, Timeout, tickstart) != HAL_OK) | |
1126 { | |
1127 /* Disable Address Acknowledge */ | |
1128 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; | |
1129 return HAL_TIMEOUT; | |
1130 } | |
1131 | |
1132 /* Disable Address Acknowledge */ | |
1133 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; | |
1134 | |
1135 hfmpi2c->State = HAL_FMPI2C_STATE_READY; | |
1136 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; | |
1137 | |
1138 /* Process Unlocked */ | |
1139 __HAL_UNLOCK(hfmpi2c); | |
1140 | |
1141 return HAL_OK; | |
1142 } | |
1143 else | |
1144 { | |
1145 return HAL_BUSY; | |
1146 } | |
1147 } | |
1148 | |
1149 /** | |
1150 * @brief Transmit in master mode an amount of data in non-blocking mode with Interrupt | |
1151 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
1152 * the configuration information for the specified FMPI2C. | |
1153 * @param DevAddress Target device address The device 7 bits address value | |
1154 * in datasheet must be shifted to the left before calling the interface | |
1155 * @param pData Pointer to data buffer | |
1156 * @param Size Amount of data to be sent | |
1157 * @retval HAL status | |
1158 */ | |
1159 HAL_StatusTypeDef HAL_FMPI2C_Master_Transmit_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size) | |
1160 { | |
1161 uint32_t xfermode = 0U; | |
1162 | |
1163 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) | |
1164 { | |
1165 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET) | |
1166 { | |
1167 return HAL_BUSY; | |
1168 } | |
1169 | |
1170 /* Process Locked */ | |
1171 __HAL_LOCK(hfmpi2c); | |
1172 | |
1173 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX; | |
1174 hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER; | |
1175 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; | |
1176 | |
1177 /* Prepare transfer parameters */ | |
1178 hfmpi2c->pBuffPtr = pData; | |
1179 hfmpi2c->XferCount = Size; | |
1180 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; | |
1181 hfmpi2c->XferISR = FMPI2C_Master_ISR_IT; | |
1182 | |
1183 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) | |
1184 { | |
1185 hfmpi2c->XferSize = MAX_NBYTE_SIZE; | |
1186 xfermode = FMPI2C_RELOAD_MODE; | |
1187 } | |
1188 else | |
1189 { | |
1190 hfmpi2c->XferSize = hfmpi2c->XferCount; | |
1191 xfermode = FMPI2C_AUTOEND_MODE; | |
1192 } | |
1193 | |
1194 /* Send Slave Address */ | |
1195 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE */ | |
1196 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, xfermode, FMPI2C_GENERATE_START_WRITE); | |
1197 | |
1198 /* Process Unlocked */ | |
1199 __HAL_UNLOCK(hfmpi2c); | |
1200 | |
1201 /* Note : The FMPI2C interrupts must be enabled after unlocking current process | |
1202 to avoid the risk of FMPI2C interrupt handle execution before current | |
1203 process unlock */ | |
1204 | |
1205 /* Enable ERR, TC, STOP, NACK, TXI interrupt */ | |
1206 /* possible to enable all of these */ | |
1207 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */ | |
1208 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT); | |
1209 | |
1210 return HAL_OK; | |
1211 } | |
1212 else | |
1213 { | |
1214 return HAL_BUSY; | |
1215 } | |
1216 } | |
1217 | |
1218 /** | |
1219 * @brief Receive in master mode an amount of data in non-blocking mode with Interrupt | |
1220 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
1221 * the configuration information for the specified FMPI2C. | |
1222 * @param DevAddress Target device address The device 7 bits address value | |
1223 * in datasheet must be shifted to the left before calling the interface | |
1224 * @param pData Pointer to data buffer | |
1225 * @param Size Amount of data to be sent | |
1226 * @retval HAL status | |
1227 */ | |
1228 HAL_StatusTypeDef HAL_FMPI2C_Master_Receive_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size) | |
1229 { | |
1230 uint32_t xfermode = 0U; | |
1231 | |
1232 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) | |
1233 { | |
1234 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET) | |
1235 { | |
1236 return HAL_BUSY; | |
1237 } | |
1238 | |
1239 /* Process Locked */ | |
1240 __HAL_LOCK(hfmpi2c); | |
1241 | |
1242 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX; | |
1243 hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER; | |
1244 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; | |
1245 | |
1246 /* Prepare transfer parameters */ | |
1247 hfmpi2c->pBuffPtr = pData; | |
1248 hfmpi2c->XferCount = Size; | |
1249 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; | |
1250 hfmpi2c->XferISR = FMPI2C_Master_ISR_IT; | |
1251 | |
1252 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) | |
1253 { | |
1254 hfmpi2c->XferSize = MAX_NBYTE_SIZE; | |
1255 xfermode = FMPI2C_RELOAD_MODE; | |
1256 } | |
1257 else | |
1258 { | |
1259 hfmpi2c->XferSize = hfmpi2c->XferCount; | |
1260 xfermode = FMPI2C_AUTOEND_MODE; | |
1261 } | |
1262 | |
1263 /* Send Slave Address */ | |
1264 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE */ | |
1265 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, xfermode, FMPI2C_GENERATE_START_READ); | |
1266 | |
1267 /* Process Unlocked */ | |
1268 __HAL_UNLOCK(hfmpi2c); | |
1269 | |
1270 /* Note : The FMPI2C interrupts must be enabled after unlocking current process | |
1271 to avoid the risk of FMPI2C interrupt handle execution before current | |
1272 process unlock */ | |
1273 | |
1274 /* Enable ERR, TC, STOP, NACK, RXI interrupt */ | |
1275 /* possible to enable all of these */ | |
1276 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */ | |
1277 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT); | |
1278 | |
1279 return HAL_OK; | |
1280 } | |
1281 else | |
1282 { | |
1283 return HAL_BUSY; | |
1284 } | |
1285 } | |
1286 | |
1287 /** | |
1288 * @brief Transmit in slave mode an amount of data in non-blocking mode with Interrupt | |
1289 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
1290 * the configuration information for the specified FMPI2C. | |
1291 * @param pData Pointer to data buffer | |
1292 * @param Size Amount of data to be sent | |
1293 * @retval HAL status | |
1294 */ | |
1295 HAL_StatusTypeDef HAL_FMPI2C_Slave_Transmit_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size) | |
1296 { | |
1297 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) | |
1298 { | |
1299 /* Process Locked */ | |
1300 __HAL_LOCK(hfmpi2c); | |
1301 | |
1302 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX; | |
1303 hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE; | |
1304 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; | |
1305 | |
1306 /* Enable Address Acknowledge */ | |
1307 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK; | |
1308 | |
1309 /* Prepare transfer parameters */ | |
1310 hfmpi2c->pBuffPtr = pData; | |
1311 hfmpi2c->XferCount = Size; | |
1312 hfmpi2c->XferSize = hfmpi2c->XferCount; | |
1313 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; | |
1314 hfmpi2c->XferISR = FMPI2C_Slave_ISR_IT; | |
1315 | |
1316 /* Process Unlocked */ | |
1317 __HAL_UNLOCK(hfmpi2c); | |
1318 | |
1319 /* Note : The FMPI2C interrupts must be enabled after unlocking current process | |
1320 to avoid the risk of FMPI2C interrupt handle execution before current | |
1321 process unlock */ | |
1322 | |
1323 /* Enable ERR, TC, STOP, NACK, TXI interrupt */ | |
1324 /* possible to enable all of these */ | |
1325 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */ | |
1326 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT | FMPI2C_XFER_LISTEN_IT); | |
1327 | |
1328 return HAL_OK; | |
1329 } | |
1330 else | |
1331 { | |
1332 return HAL_BUSY; | |
1333 } | |
1334 } | |
1335 | |
1336 /** | |
1337 * @brief Receive in slave mode an amount of data in non-blocking mode with Interrupt | |
1338 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
1339 * the configuration information for the specified FMPI2C. | |
1340 * @param pData Pointer to data buffer | |
1341 * @param Size Amount of data to be sent | |
1342 * @retval HAL status | |
1343 */ | |
1344 HAL_StatusTypeDef HAL_FMPI2C_Slave_Receive_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size) | |
1345 { | |
1346 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) | |
1347 { | |
1348 /* Process Locked */ | |
1349 __HAL_LOCK(hfmpi2c); | |
1350 | |
1351 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX; | |
1352 hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE; | |
1353 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; | |
1354 | |
1355 /* Enable Address Acknowledge */ | |
1356 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK; | |
1357 | |
1358 /* Prepare transfer parameters */ | |
1359 hfmpi2c->pBuffPtr = pData; | |
1360 hfmpi2c->XferCount = Size; | |
1361 hfmpi2c->XferSize = hfmpi2c->XferCount; | |
1362 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; | |
1363 hfmpi2c->XferISR = FMPI2C_Slave_ISR_IT; | |
1364 | |
1365 /* Process Unlocked */ | |
1366 __HAL_UNLOCK(hfmpi2c); | |
1367 | |
1368 /* Note : The FMPI2C interrupts must be enabled after unlocking current process | |
1369 to avoid the risk of FMPI2C interrupt handle execution before current | |
1370 process unlock */ | |
1371 | |
1372 /* Enable ERR, TC, STOP, NACK, RXI interrupt */ | |
1373 /* possible to enable all of these */ | |
1374 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */ | |
1375 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT | FMPI2C_XFER_LISTEN_IT); | |
1376 | |
1377 return HAL_OK; | |
1378 } | |
1379 else | |
1380 { | |
1381 return HAL_BUSY; | |
1382 } | |
1383 } | |
1384 | |
1385 /** | |
1386 * @brief Transmit in master mode an amount of data in non-blocking mode with DMA | |
1387 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
1388 * the configuration information for the specified FMPI2C. | |
1389 * @param DevAddress Target device address The device 7 bits address value | |
1390 * in datasheet must be shifted to the left before calling the interface | |
1391 * @param pData Pointer to data buffer | |
1392 * @param Size Amount of data to be sent | |
1393 * @retval HAL status | |
1394 */ | |
1395 HAL_StatusTypeDef HAL_FMPI2C_Master_Transmit_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size) | |
1396 { | |
1397 uint32_t xfermode = 0U; | |
1398 | |
1399 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) | |
1400 { | |
1401 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET) | |
1402 { | |
1403 return HAL_BUSY; | |
1404 } | |
1405 | |
1406 /* Process Locked */ | |
1407 __HAL_LOCK(hfmpi2c); | |
1408 | |
1409 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX; | |
1410 hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER; | |
1411 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; | |
1412 | |
1413 /* Prepare transfer parameters */ | |
1414 hfmpi2c->pBuffPtr = pData; | |
1415 hfmpi2c->XferCount = Size; | |
1416 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; | |
1417 hfmpi2c->XferISR = FMPI2C_Master_ISR_DMA; | |
1418 | |
1419 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) | |
1420 { | |
1421 hfmpi2c->XferSize = MAX_NBYTE_SIZE; | |
1422 xfermode = FMPI2C_RELOAD_MODE; | |
1423 } | |
1424 else | |
1425 { | |
1426 hfmpi2c->XferSize = hfmpi2c->XferCount; | |
1427 xfermode = FMPI2C_AUTOEND_MODE; | |
1428 } | |
1429 | |
1430 if (hfmpi2c->XferSize > 0U) | |
1431 { | |
1432 /* Set the FMPI2C DMA transfer complete callback */ | |
1433 hfmpi2c->hdmatx->XferCpltCallback = FMPI2C_DMAMasterTransmitCplt; | |
1434 | |
1435 /* Set the DMA error callback */ | |
1436 hfmpi2c->hdmatx->XferErrorCallback = FMPI2C_DMAError; | |
1437 | |
1438 /* Set the unused DMA callbacks to NULL */ | |
1439 hfmpi2c->hdmatx->XferHalfCpltCallback = NULL; | |
1440 hfmpi2c->hdmatx->XferAbortCallback = NULL; | |
1441 | |
1442 /* Enable the DMA stream */ | |
1443 HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)pData, (uint32_t)&hfmpi2c->Instance->TXDR, hfmpi2c->XferSize); | |
1444 | |
1445 /* Send Slave Address */ | |
1446 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ | |
1447 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, xfermode, FMPI2C_GENERATE_START_WRITE); | |
1448 | |
1449 /* Update XferCount value */ | |
1450 hfmpi2c->XferCount -= hfmpi2c->XferSize; | |
1451 | |
1452 /* Process Unlocked */ | |
1453 __HAL_UNLOCK(hfmpi2c); | |
1454 | |
1455 /* Note : The FMPI2C interrupts must be enabled after unlocking current process | |
1456 to avoid the risk of FMPI2C interrupt handle execution before current | |
1457 process unlock */ | |
1458 /* Enable ERR and NACK interrupts */ | |
1459 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_ERROR_IT); | |
1460 | |
1461 /* Enable DMA Request */ | |
1462 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN; | |
1463 } | |
1464 else | |
1465 { | |
1466 /* Update Transfer ISR function pointer */ | |
1467 hfmpi2c->XferISR = FMPI2C_Master_ISR_IT; | |
1468 | |
1469 /* Send Slave Address */ | |
1470 /* Set NBYTES to write and generate START condition */ | |
1471 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_GENERATE_START_WRITE); | |
1472 | |
1473 /* Process Unlocked */ | |
1474 __HAL_UNLOCK(hfmpi2c); | |
1475 | |
1476 /* Note : The FMPI2C interrupts must be enabled after unlocking current process | |
1477 to avoid the risk of FMPI2C interrupt handle execution before current | |
1478 process unlock */ | |
1479 /* Enable ERR, TC, STOP, NACK, TXI interrupt */ | |
1480 /* possible to enable all of these */ | |
1481 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */ | |
1482 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT); | |
1483 } | |
1484 | |
1485 return HAL_OK; | |
1486 } | |
1487 else | |
1488 { | |
1489 return HAL_BUSY; | |
1490 } | |
1491 } | |
1492 | |
1493 /** | |
1494 * @brief Receive in master mode an amount of data in non-blocking mode with DMA | |
1495 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
1496 * the configuration information for the specified FMPI2C. | |
1497 * @param DevAddress Target device address The device 7 bits address value | |
1498 * in datasheet must be shifted to the left before calling the interface | |
1499 * @param pData Pointer to data buffer | |
1500 * @param Size Amount of data to be sent | |
1501 * @retval HAL status | |
1502 */ | |
1503 HAL_StatusTypeDef HAL_FMPI2C_Master_Receive_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size) | |
1504 { | |
1505 uint32_t xfermode = 0U; | |
1506 | |
1507 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) | |
1508 { | |
1509 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET) | |
1510 { | |
1511 return HAL_BUSY; | |
1512 } | |
1513 | |
1514 /* Process Locked */ | |
1515 __HAL_LOCK(hfmpi2c); | |
1516 | |
1517 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX; | |
1518 hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER; | |
1519 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; | |
1520 | |
1521 /* Prepare transfer parameters */ | |
1522 hfmpi2c->pBuffPtr = pData; | |
1523 hfmpi2c->XferCount = Size; | |
1524 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; | |
1525 hfmpi2c->XferISR = FMPI2C_Master_ISR_DMA; | |
1526 | |
1527 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) | |
1528 { | |
1529 hfmpi2c->XferSize = MAX_NBYTE_SIZE; | |
1530 xfermode = FMPI2C_RELOAD_MODE; | |
1531 } | |
1532 else | |
1533 { | |
1534 hfmpi2c->XferSize = hfmpi2c->XferCount; | |
1535 xfermode = FMPI2C_AUTOEND_MODE; | |
1536 } | |
1537 | |
1538 if (hfmpi2c->XferSize > 0U) | |
1539 { | |
1540 /* Set the FMPI2C DMA transfer complete callback */ | |
1541 hfmpi2c->hdmarx->XferCpltCallback = FMPI2C_DMAMasterReceiveCplt; | |
1542 | |
1543 /* Set the DMA error callback */ | |
1544 hfmpi2c->hdmarx->XferErrorCallback = FMPI2C_DMAError; | |
1545 | |
1546 /* Set the unused DMA callbacks to NULL */ | |
1547 hfmpi2c->hdmarx->XferHalfCpltCallback = NULL; | |
1548 hfmpi2c->hdmarx->XferAbortCallback = NULL; | |
1549 | |
1550 /* Enable the DMA stream */ | |
1551 HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR, (uint32_t)pData, hfmpi2c->XferSize); | |
1552 | |
1553 /* Send Slave Address */ | |
1554 /* Set NBYTES to read and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ | |
1555 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, xfermode, FMPI2C_GENERATE_START_READ); | |
1556 | |
1557 /* Update XferCount value */ | |
1558 hfmpi2c->XferCount -= hfmpi2c->XferSize; | |
1559 | |
1560 /* Process Unlocked */ | |
1561 __HAL_UNLOCK(hfmpi2c); | |
1562 | |
1563 /* Note : The FMPI2C interrupts must be enabled after unlocking current process | |
1564 to avoid the risk of FMPI2C interrupt handle execution before current | |
1565 process unlock */ | |
1566 /* Enable ERR and NACK interrupts */ | |
1567 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_ERROR_IT); | |
1568 | |
1569 /* Enable DMA Request */ | |
1570 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN; | |
1571 } | |
1572 else | |
1573 { | |
1574 /* Update Transfer ISR function pointer */ | |
1575 hfmpi2c->XferISR = FMPI2C_Master_ISR_IT; | |
1576 | |
1577 /* Send Slave Address */ | |
1578 /* Set NBYTES to read and generate START condition */ | |
1579 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_GENERATE_START_READ); | |
1580 | |
1581 /* Process Unlocked */ | |
1582 __HAL_UNLOCK(hfmpi2c); | |
1583 | |
1584 /* Note : The FMPI2C interrupts must be enabled after unlocking current process | |
1585 to avoid the risk of FMPI2C interrupt handle execution before current | |
1586 process unlock */ | |
1587 /* Enable ERR, TC, STOP, NACK, TXI interrupt */ | |
1588 /* possible to enable all of these */ | |
1589 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */ | |
1590 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT); | |
1591 } | |
1592 return HAL_OK; | |
1593 } | |
1594 else | |
1595 { | |
1596 return HAL_BUSY; | |
1597 } | |
1598 } | |
1599 | |
1600 /** | |
1601 * @brief Transmit in slave mode an amount of data in non-blocking mode with DMA | |
1602 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
1603 * the configuration information for the specified FMPI2C. | |
1604 * @param pData Pointer to data buffer | |
1605 * @param Size Amount of data to be sent | |
1606 * @retval HAL status | |
1607 */ | |
1608 HAL_StatusTypeDef HAL_FMPI2C_Slave_Transmit_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size) | |
1609 { | |
1610 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) | |
1611 { | |
1612 if ((pData == NULL) || (Size == 0U)) | |
1613 { | |
1614 return HAL_ERROR; | |
1615 } | |
1616 /* Process Locked */ | |
1617 __HAL_LOCK(hfmpi2c); | |
1618 | |
1619 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX; | |
1620 hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE; | |
1621 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; | |
1622 | |
1623 /* Prepare transfer parameters */ | |
1624 hfmpi2c->pBuffPtr = pData; | |
1625 hfmpi2c->XferCount = Size; | |
1626 hfmpi2c->XferSize = hfmpi2c->XferCount; | |
1627 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; | |
1628 hfmpi2c->XferISR = FMPI2C_Slave_ISR_DMA; | |
1629 | |
1630 /* Set the FMPI2C DMA transfer complete callback */ | |
1631 hfmpi2c->hdmatx->XferCpltCallback = FMPI2C_DMASlaveTransmitCplt; | |
1632 | |
1633 /* Set the DMA error callback */ | |
1634 hfmpi2c->hdmatx->XferErrorCallback = FMPI2C_DMAError; | |
1635 | |
1636 /* Set the unused DMA callbacks to NULL */ | |
1637 hfmpi2c->hdmatx->XferHalfCpltCallback = NULL; | |
1638 hfmpi2c->hdmatx->XferAbortCallback = NULL; | |
1639 | |
1640 /* Enable the DMA stream */ | |
1641 HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)pData, (uint32_t)&hfmpi2c->Instance->TXDR, hfmpi2c->XferSize); | |
1642 | |
1643 /* Enable Address Acknowledge */ | |
1644 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK; | |
1645 | |
1646 /* Process Unlocked */ | |
1647 __HAL_UNLOCK(hfmpi2c); | |
1648 | |
1649 /* Note : The FMPI2C interrupts must be enabled after unlocking current process | |
1650 to avoid the risk of FMPI2C interrupt handle execution before current | |
1651 process unlock */ | |
1652 /* Enable ERR, STOP, NACK, ADDR interrupts */ | |
1653 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT); | |
1654 | |
1655 /* Enable DMA Request */ | |
1656 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN; | |
1657 | |
1658 return HAL_OK; | |
1659 } | |
1660 else | |
1661 { | |
1662 return HAL_BUSY; | |
1663 } | |
1664 } | |
1665 | |
1666 /** | |
1667 * @brief Receive in slave mode an amount of data in non-blocking mode with DMA | |
1668 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
1669 * the configuration information for the specified FMPI2C. | |
1670 * @param pData Pointer to data buffer | |
1671 * @param Size Amount of data to be sent | |
1672 * @retval HAL status | |
1673 */ | |
1674 HAL_StatusTypeDef HAL_FMPI2C_Slave_Receive_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size) | |
1675 { | |
1676 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) | |
1677 { | |
1678 if ((pData == NULL) || (Size == 0U)) | |
1679 { | |
1680 return HAL_ERROR; | |
1681 } | |
1682 /* Process Locked */ | |
1683 __HAL_LOCK(hfmpi2c); | |
1684 | |
1685 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX; | |
1686 hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE; | |
1687 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; | |
1688 | |
1689 /* Prepare transfer parameters */ | |
1690 hfmpi2c->pBuffPtr = pData; | |
1691 hfmpi2c->XferCount = Size; | |
1692 hfmpi2c->XferSize = hfmpi2c->XferCount; | |
1693 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; | |
1694 hfmpi2c->XferISR = FMPI2C_Slave_ISR_DMA; | |
1695 | |
1696 /* Set the FMPI2C DMA transfer complete callback */ | |
1697 hfmpi2c->hdmarx->XferCpltCallback = FMPI2C_DMASlaveReceiveCplt; | |
1698 | |
1699 /* Set the DMA error callback */ | |
1700 hfmpi2c->hdmarx->XferErrorCallback = FMPI2C_DMAError; | |
1701 | |
1702 /* Set the unused DMA callbacks to NULL */ | |
1703 hfmpi2c->hdmarx->XferHalfCpltCallback = NULL; | |
1704 hfmpi2c->hdmarx->XferAbortCallback = NULL; | |
1705 | |
1706 /* Enable the DMA stream */ | |
1707 HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR, (uint32_t)pData, hfmpi2c->XferSize); | |
1708 | |
1709 /* Enable Address Acknowledge */ | |
1710 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK; | |
1711 | |
1712 /* Process Unlocked */ | |
1713 __HAL_UNLOCK(hfmpi2c); | |
1714 | |
1715 /* Note : The FMPI2C interrupts must be enabled after unlocking current process | |
1716 to avoid the risk of FMPI2C interrupt handle execution before current | |
1717 process unlock */ | |
1718 /* Enable ERR, STOP, NACK, ADDR interrupts */ | |
1719 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT); | |
1720 | |
1721 /* Enable DMA Request */ | |
1722 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN; | |
1723 | |
1724 return HAL_OK; | |
1725 } | |
1726 else | |
1727 { | |
1728 return HAL_BUSY; | |
1729 } | |
1730 } | |
1731 /** | |
1732 * @brief Write an amount of data in blocking mode to a specific memory address | |
1733 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
1734 * the configuration information for the specified FMPI2C. | |
1735 * @param DevAddress Target device address The device 7 bits address value | |
1736 * in datasheet must be shifted to the left before calling the interface | |
1737 * @param MemAddress Internal memory address | |
1738 * @param MemAddSize Size of internal memory address | |
1739 * @param pData Pointer to data buffer | |
1740 * @param Size Amount of data to be sent | |
1741 * @param Timeout Timeout duration | |
1742 * @retval HAL status | |
1743 */ | |
1744 HAL_StatusTypeDef HAL_FMPI2C_Mem_Write(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout) | |
1745 { | |
1746 uint32_t tickstart = 0U; | |
1747 | |
1748 /* Check the parameters */ | |
1749 assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize)); | |
1750 | |
1751 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) | |
1752 { | |
1753 if ((pData == NULL) || (Size == 0U)) | |
1754 { | |
1755 return HAL_ERROR; | |
1756 } | |
1757 | |
1758 /* Process Locked */ | |
1759 __HAL_LOCK(hfmpi2c); | |
1760 | |
1761 /* Init tickstart for timeout management*/ | |
1762 tickstart = HAL_GetTick(); | |
1763 | |
1764 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, FMPI2C_TIMEOUT_BUSY, tickstart) != HAL_OK) | |
1765 { | |
1766 return HAL_TIMEOUT; | |
1767 } | |
1768 | |
1769 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX; | |
1770 hfmpi2c->Mode = HAL_FMPI2C_MODE_MEM; | |
1771 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; | |
1772 | |
1773 /* Prepare transfer parameters */ | |
1774 hfmpi2c->pBuffPtr = pData; | |
1775 hfmpi2c->XferCount = Size; | |
1776 hfmpi2c->XferISR = NULL; | |
1777 | |
1778 /* Send Slave Address and Memory Address */ | |
1779 if (FMPI2C_RequestMemoryWrite(hfmpi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK) | |
1780 { | |
1781 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) | |
1782 { | |
1783 /* Process Unlocked */ | |
1784 __HAL_UNLOCK(hfmpi2c); | |
1785 return HAL_ERROR; | |
1786 } | |
1787 else | |
1788 { | |
1789 /* Process Unlocked */ | |
1790 __HAL_UNLOCK(hfmpi2c); | |
1791 return HAL_TIMEOUT; | |
1792 } | |
1793 } | |
1794 | |
1795 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE */ | |
1796 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) | |
1797 { | |
1798 hfmpi2c->XferSize = MAX_NBYTE_SIZE; | |
1799 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP); | |
1800 } | |
1801 else | |
1802 { | |
1803 hfmpi2c->XferSize = hfmpi2c->XferCount; | |
1804 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP); | |
1805 } | |
1806 | |
1807 do | |
1808 { | |
1809 /* Wait until TXIS flag is set */ | |
1810 if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK) | |
1811 { | |
1812 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) | |
1813 { | |
1814 return HAL_ERROR; | |
1815 } | |
1816 else | |
1817 { | |
1818 return HAL_TIMEOUT; | |
1819 } | |
1820 } | |
1821 | |
1822 /* Write data to TXDR */ | |
1823 hfmpi2c->Instance->TXDR = (*hfmpi2c->pBuffPtr++); | |
1824 hfmpi2c->XferCount--; | |
1825 hfmpi2c->XferSize--; | |
1826 | |
1827 if ((hfmpi2c->XferSize == 0U) && (hfmpi2c->XferCount != 0U)) | |
1828 { | |
1829 /* Wait until TCR flag is set */ | |
1830 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK) | |
1831 { | |
1832 return HAL_TIMEOUT; | |
1833 } | |
1834 | |
1835 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) | |
1836 { | |
1837 hfmpi2c->XferSize = MAX_NBYTE_SIZE; | |
1838 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP); | |
1839 } | |
1840 else | |
1841 { | |
1842 hfmpi2c->XferSize = hfmpi2c->XferCount; | |
1843 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP); | |
1844 } | |
1845 } | |
1846 | |
1847 } | |
1848 while (hfmpi2c->XferCount > 0U); | |
1849 | |
1850 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ | |
1851 /* Wait until STOPF flag is reset */ | |
1852 if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK) | |
1853 { | |
1854 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) | |
1855 { | |
1856 return HAL_ERROR; | |
1857 } | |
1858 else | |
1859 { | |
1860 return HAL_TIMEOUT; | |
1861 } | |
1862 } | |
1863 | |
1864 /* Clear STOP Flag */ | |
1865 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); | |
1866 | |
1867 /* Clear Configuration Register 2 */ | |
1868 FMPI2C_RESET_CR2(hfmpi2c); | |
1869 | |
1870 hfmpi2c->State = HAL_FMPI2C_STATE_READY; | |
1871 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; | |
1872 | |
1873 /* Process Unlocked */ | |
1874 __HAL_UNLOCK(hfmpi2c); | |
1875 | |
1876 return HAL_OK; | |
1877 } | |
1878 else | |
1879 { | |
1880 return HAL_BUSY; | |
1881 } | |
1882 } | |
1883 | |
1884 /** | |
1885 * @brief Read an amount of data in blocking mode from a specific memory address | |
1886 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
1887 * the configuration information for the specified FMPI2C. | |
1888 * @param DevAddress Target device address The device 7 bits address value | |
1889 * in datasheet must be shifted to the left before calling the interface | |
1890 * @param MemAddress Internal memory address | |
1891 * @param MemAddSize Size of internal memory address | |
1892 * @param pData Pointer to data buffer | |
1893 * @param Size Amount of data to be sent | |
1894 * @param Timeout Timeout duration | |
1895 * @retval HAL status | |
1896 */ | |
1897 HAL_StatusTypeDef HAL_FMPI2C_Mem_Read(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout) | |
1898 { | |
1899 uint32_t tickstart = 0U; | |
1900 | |
1901 /* Check the parameters */ | |
1902 assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize)); | |
1903 | |
1904 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) | |
1905 { | |
1906 if ((pData == NULL) || (Size == 0U)) | |
1907 { | |
1908 return HAL_ERROR; | |
1909 } | |
1910 | |
1911 /* Process Locked */ | |
1912 __HAL_LOCK(hfmpi2c); | |
1913 | |
1914 /* Init tickstart for timeout management*/ | |
1915 tickstart = HAL_GetTick(); | |
1916 | |
1917 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, FMPI2C_TIMEOUT_BUSY, tickstart) != HAL_OK) | |
1918 { | |
1919 return HAL_TIMEOUT; | |
1920 } | |
1921 | |
1922 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX; | |
1923 hfmpi2c->Mode = HAL_FMPI2C_MODE_MEM; | |
1924 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; | |
1925 | |
1926 /* Prepare transfer parameters */ | |
1927 hfmpi2c->pBuffPtr = pData; | |
1928 hfmpi2c->XferCount = Size; | |
1929 hfmpi2c->XferISR = NULL; | |
1930 | |
1931 /* Send Slave Address and Memory Address */ | |
1932 if (FMPI2C_RequestMemoryRead(hfmpi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK) | |
1933 { | |
1934 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) | |
1935 { | |
1936 /* Process Unlocked */ | |
1937 __HAL_UNLOCK(hfmpi2c); | |
1938 return HAL_ERROR; | |
1939 } | |
1940 else | |
1941 { | |
1942 /* Process Unlocked */ | |
1943 __HAL_UNLOCK(hfmpi2c); | |
1944 return HAL_TIMEOUT; | |
1945 } | |
1946 } | |
1947 | |
1948 /* Send Slave Address */ | |
1949 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ | |
1950 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) | |
1951 { | |
1952 hfmpi2c->XferSize = MAX_NBYTE_SIZE; | |
1953 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_GENERATE_START_READ); | |
1954 } | |
1955 else | |
1956 { | |
1957 hfmpi2c->XferSize = hfmpi2c->XferCount; | |
1958 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_GENERATE_START_READ); | |
1959 } | |
1960 | |
1961 do | |
1962 { | |
1963 /* Wait until RXNE flag is set */ | |
1964 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_RXNE, RESET, Timeout, tickstart) != HAL_OK) | |
1965 { | |
1966 return HAL_TIMEOUT; | |
1967 } | |
1968 | |
1969 /* Read data from RXDR */ | |
1970 (*hfmpi2c->pBuffPtr++) = hfmpi2c->Instance->RXDR; | |
1971 hfmpi2c->XferSize--; | |
1972 hfmpi2c->XferCount--; | |
1973 | |
1974 if ((hfmpi2c->XferSize == 0U) && (hfmpi2c->XferCount != 0U)) | |
1975 { | |
1976 /* Wait until TCR flag is set */ | |
1977 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK) | |
1978 { | |
1979 return HAL_TIMEOUT; | |
1980 } | |
1981 | |
1982 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) | |
1983 { | |
1984 hfmpi2c->XferSize = MAX_NBYTE_SIZE; | |
1985 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP); | |
1986 } | |
1987 else | |
1988 { | |
1989 hfmpi2c->XferSize = hfmpi2c->XferCount; | |
1990 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP); | |
1991 } | |
1992 } | |
1993 } | |
1994 while (hfmpi2c->XferCount > 0U); | |
1995 | |
1996 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ | |
1997 /* Wait until STOPF flag is reset */ | |
1998 if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK) | |
1999 { | |
2000 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) | |
2001 { | |
2002 return HAL_ERROR; | |
2003 } | |
2004 else | |
2005 { | |
2006 return HAL_TIMEOUT; | |
2007 } | |
2008 } | |
2009 | |
2010 /* Clear STOP Flag */ | |
2011 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); | |
2012 | |
2013 /* Clear Configuration Register 2 */ | |
2014 FMPI2C_RESET_CR2(hfmpi2c); | |
2015 | |
2016 hfmpi2c->State = HAL_FMPI2C_STATE_READY; | |
2017 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; | |
2018 | |
2019 /* Process Unlocked */ | |
2020 __HAL_UNLOCK(hfmpi2c); | |
2021 | |
2022 return HAL_OK; | |
2023 } | |
2024 else | |
2025 { | |
2026 return HAL_BUSY; | |
2027 } | |
2028 } | |
2029 /** | |
2030 * @brief Write an amount of data in non-blocking mode with Interrupt to a specific memory address | |
2031 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
2032 * the configuration information for the specified FMPI2C. | |
2033 * @param DevAddress Target device address The device 7 bits address value | |
2034 * in datasheet must be shifted to the left before calling the interface | |
2035 * @param MemAddress Internal memory address | |
2036 * @param MemAddSize Size of internal memory address | |
2037 * @param pData Pointer to data buffer | |
2038 * @param Size Amount of data to be sent | |
2039 * @retval HAL status | |
2040 */ | |
2041 HAL_StatusTypeDef HAL_FMPI2C_Mem_Write_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size) | |
2042 { | |
2043 uint32_t tickstart = 0U; | |
2044 uint32_t xfermode = 0U; | |
2045 | |
2046 /* Check the parameters */ | |
2047 assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize)); | |
2048 | |
2049 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) | |
2050 { | |
2051 if ((pData == NULL) || (Size == 0U)) | |
2052 { | |
2053 return HAL_ERROR; | |
2054 } | |
2055 | |
2056 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET) | |
2057 { | |
2058 return HAL_BUSY; | |
2059 } | |
2060 | |
2061 /* Process Locked */ | |
2062 __HAL_LOCK(hfmpi2c); | |
2063 | |
2064 /* Init tickstart for timeout management*/ | |
2065 tickstart = HAL_GetTick(); | |
2066 | |
2067 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX; | |
2068 hfmpi2c->Mode = HAL_FMPI2C_MODE_MEM; | |
2069 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; | |
2070 | |
2071 /* Prepare transfer parameters */ | |
2072 hfmpi2c->pBuffPtr = pData; | |
2073 hfmpi2c->XferCount = Size; | |
2074 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; | |
2075 hfmpi2c->XferISR = FMPI2C_Master_ISR_IT; | |
2076 | |
2077 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) | |
2078 { | |
2079 hfmpi2c->XferSize = MAX_NBYTE_SIZE; | |
2080 xfermode = FMPI2C_RELOAD_MODE; | |
2081 } | |
2082 else | |
2083 { | |
2084 hfmpi2c->XferSize = hfmpi2c->XferCount; | |
2085 xfermode = FMPI2C_AUTOEND_MODE; | |
2086 } | |
2087 | |
2088 /* Send Slave Address and Memory Address */ | |
2089 if (FMPI2C_RequestMemoryWrite(hfmpi2c, DevAddress, MemAddress, MemAddSize, FMPI2C_TIMEOUT_FLAG, tickstart) != HAL_OK) | |
2090 { | |
2091 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) | |
2092 { | |
2093 /* Process Unlocked */ | |
2094 __HAL_UNLOCK(hfmpi2c); | |
2095 return HAL_ERROR; | |
2096 } | |
2097 else | |
2098 { | |
2099 /* Process Unlocked */ | |
2100 __HAL_UNLOCK(hfmpi2c); | |
2101 return HAL_TIMEOUT; | |
2102 } | |
2103 } | |
2104 | |
2105 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ | |
2106 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, xfermode, FMPI2C_NO_STARTSTOP); | |
2107 | |
2108 /* Process Unlocked */ | |
2109 __HAL_UNLOCK(hfmpi2c); | |
2110 | |
2111 /* Note : The FMPI2C interrupts must be enabled after unlocking current process | |
2112 to avoid the risk of FMPI2C interrupt handle execution before current | |
2113 process unlock */ | |
2114 | |
2115 /* Enable ERR, TC, STOP, NACK, TXI interrupt */ | |
2116 /* possible to enable all of these */ | |
2117 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */ | |
2118 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT); | |
2119 | |
2120 return HAL_OK; | |
2121 } | |
2122 else | |
2123 { | |
2124 return HAL_BUSY; | |
2125 } | |
2126 } | |
2127 | |
2128 /** | |
2129 * @brief Read an amount of data in non-blocking mode with Interrupt from a specific memory address | |
2130 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
2131 * the configuration information for the specified FMPI2C. | |
2132 * @param DevAddress Target device address The device 7 bits address value | |
2133 * in datasheet must be shifted to the left before calling the interface | |
2134 * @param MemAddress Internal memory address | |
2135 * @param MemAddSize Size of internal memory address | |
2136 * @param pData Pointer to data buffer | |
2137 * @param Size Amount of data to be sent | |
2138 * @retval HAL status | |
2139 */ | |
2140 HAL_StatusTypeDef HAL_FMPI2C_Mem_Read_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size) | |
2141 { | |
2142 uint32_t tickstart = 0U; | |
2143 uint32_t xfermode = 0U; | |
2144 | |
2145 /* Check the parameters */ | |
2146 assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize)); | |
2147 | |
2148 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) | |
2149 { | |
2150 if ((pData == NULL) || (Size == 0U)) | |
2151 { | |
2152 return HAL_ERROR; | |
2153 } | |
2154 | |
2155 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET) | |
2156 { | |
2157 return HAL_BUSY; | |
2158 } | |
2159 | |
2160 /* Process Locked */ | |
2161 __HAL_LOCK(hfmpi2c); | |
2162 | |
2163 /* Init tickstart for timeout management*/ | |
2164 tickstart = HAL_GetTick(); | |
2165 | |
2166 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX; | |
2167 hfmpi2c->Mode = HAL_FMPI2C_MODE_MEM; | |
2168 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; | |
2169 | |
2170 /* Prepare transfer parameters */ | |
2171 hfmpi2c->pBuffPtr = pData; | |
2172 hfmpi2c->XferCount = Size; | |
2173 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; | |
2174 hfmpi2c->XferISR = FMPI2C_Master_ISR_IT; | |
2175 | |
2176 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) | |
2177 { | |
2178 hfmpi2c->XferSize = MAX_NBYTE_SIZE; | |
2179 xfermode = FMPI2C_RELOAD_MODE; | |
2180 } | |
2181 else | |
2182 { | |
2183 hfmpi2c->XferSize = hfmpi2c->XferCount; | |
2184 xfermode = FMPI2C_AUTOEND_MODE; | |
2185 } | |
2186 | |
2187 /* Send Slave Address and Memory Address */ | |
2188 if (FMPI2C_RequestMemoryRead(hfmpi2c, DevAddress, MemAddress, MemAddSize, FMPI2C_TIMEOUT_FLAG, tickstart) != HAL_OK) | |
2189 { | |
2190 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) | |
2191 { | |
2192 /* Process Unlocked */ | |
2193 __HAL_UNLOCK(hfmpi2c); | |
2194 return HAL_ERROR; | |
2195 } | |
2196 else | |
2197 { | |
2198 /* Process Unlocked */ | |
2199 __HAL_UNLOCK(hfmpi2c); | |
2200 return HAL_TIMEOUT; | |
2201 } | |
2202 } | |
2203 | |
2204 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ | |
2205 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, xfermode, FMPI2C_GENERATE_START_READ); | |
2206 | |
2207 /* Process Unlocked */ | |
2208 __HAL_UNLOCK(hfmpi2c); | |
2209 | |
2210 /* Note : The FMPI2C interrupts must be enabled after unlocking current process | |
2211 to avoid the risk of FMPI2C interrupt handle execution before current | |
2212 process unlock */ | |
2213 | |
2214 /* Enable ERR, TC, STOP, NACK, RXI interrupt */ | |
2215 /* possible to enable all of these */ | |
2216 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */ | |
2217 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT); | |
2218 | |
2219 return HAL_OK; | |
2220 } | |
2221 else | |
2222 { | |
2223 return HAL_BUSY; | |
2224 } | |
2225 } | |
2226 /** | |
2227 * @brief Write an amount of data in non-blocking mode with DMA to a specific memory address | |
2228 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
2229 * the configuration information for the specified FMPI2C. | |
2230 * @param DevAddress Target device address The device 7 bits address value | |
2231 * in datasheet must be shifted to the left before calling the interface | |
2232 * @param MemAddress Internal memory address | |
2233 * @param MemAddSize Size of internal memory address | |
2234 * @param pData Pointer to data buffer | |
2235 * @param Size Amount of data to be sent | |
2236 * @retval HAL status | |
2237 */ | |
2238 HAL_StatusTypeDef HAL_FMPI2C_Mem_Write_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size) | |
2239 { | |
2240 uint32_t tickstart = 0U; | |
2241 uint32_t xfermode = 0U; | |
2242 | |
2243 /* Check the parameters */ | |
2244 assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize)); | |
2245 | |
2246 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) | |
2247 { | |
2248 if ((pData == NULL) || (Size == 0U)) | |
2249 { | |
2250 return HAL_ERROR; | |
2251 } | |
2252 | |
2253 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET) | |
2254 { | |
2255 return HAL_BUSY; | |
2256 } | |
2257 | |
2258 /* Process Locked */ | |
2259 __HAL_LOCK(hfmpi2c); | |
2260 | |
2261 /* Init tickstart for timeout management*/ | |
2262 tickstart = HAL_GetTick(); | |
2263 | |
2264 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX; | |
2265 hfmpi2c->Mode = HAL_FMPI2C_MODE_MEM; | |
2266 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; | |
2267 | |
2268 /* Prepare transfer parameters */ | |
2269 hfmpi2c->pBuffPtr = pData; | |
2270 hfmpi2c->XferCount = Size; | |
2271 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; | |
2272 hfmpi2c->XferISR = FMPI2C_Master_ISR_DMA; | |
2273 | |
2274 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) | |
2275 { | |
2276 hfmpi2c->XferSize = MAX_NBYTE_SIZE; | |
2277 xfermode = FMPI2C_RELOAD_MODE; | |
2278 } | |
2279 else | |
2280 { | |
2281 hfmpi2c->XferSize = hfmpi2c->XferCount; | |
2282 xfermode = FMPI2C_AUTOEND_MODE; | |
2283 } | |
2284 | |
2285 /* Send Slave Address and Memory Address */ | |
2286 if (FMPI2C_RequestMemoryWrite(hfmpi2c, DevAddress, MemAddress, MemAddSize, FMPI2C_TIMEOUT_FLAG, tickstart) != HAL_OK) | |
2287 { | |
2288 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) | |
2289 { | |
2290 /* Process Unlocked */ | |
2291 __HAL_UNLOCK(hfmpi2c); | |
2292 return HAL_ERROR; | |
2293 } | |
2294 else | |
2295 { | |
2296 /* Process Unlocked */ | |
2297 __HAL_UNLOCK(hfmpi2c); | |
2298 return HAL_TIMEOUT; | |
2299 } | |
2300 } | |
2301 | |
2302 /* Set the FMPI2C DMA transfer complete callback */ | |
2303 hfmpi2c->hdmatx->XferCpltCallback = FMPI2C_DMAMasterTransmitCplt; | |
2304 | |
2305 /* Set the DMA error callback */ | |
2306 hfmpi2c->hdmatx->XferErrorCallback = FMPI2C_DMAError; | |
2307 | |
2308 /* Set the unused DMA callbacks to NULL */ | |
2309 hfmpi2c->hdmatx->XferHalfCpltCallback = NULL; | |
2310 hfmpi2c->hdmatx->XferAbortCallback = NULL; | |
2311 | |
2312 /* Enable the DMA stream */ | |
2313 HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)pData, (uint32_t)&hfmpi2c->Instance->TXDR, hfmpi2c->XferSize); | |
2314 | |
2315 /* Send Slave Address */ | |
2316 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ | |
2317 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, xfermode, FMPI2C_NO_STARTSTOP); | |
2318 | |
2319 /* Update XferCount value */ | |
2320 hfmpi2c->XferCount -= hfmpi2c->XferSize; | |
2321 | |
2322 /* Process Unlocked */ | |
2323 __HAL_UNLOCK(hfmpi2c); | |
2324 | |
2325 /* Note : The FMPI2C interrupts must be enabled after unlocking current process | |
2326 to avoid the risk of FMPI2C interrupt handle execution before current | |
2327 process unlock */ | |
2328 /* Enable ERR and NACK interrupts */ | |
2329 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_ERROR_IT); | |
2330 | |
2331 /* Enable DMA Request */ | |
2332 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN; | |
2333 | |
2334 return HAL_OK; | |
2335 } | |
2336 else | |
2337 { | |
2338 return HAL_BUSY; | |
2339 } | |
2340 } | |
2341 | |
2342 /** | |
2343 * @brief Reads an amount of data in non-blocking mode with DMA from a specific memory address. | |
2344 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
2345 * the configuration information for the specified FMPI2C. | |
2346 * @param DevAddress Target device address The device 7 bits address value | |
2347 * in datasheet must be shifted to the left before calling the interface | |
2348 * @param MemAddress Internal memory address | |
2349 * @param MemAddSize Size of internal memory address | |
2350 * @param pData Pointer to data buffer | |
2351 * @param Size Amount of data to be read | |
2352 * @retval HAL status | |
2353 */ | |
2354 HAL_StatusTypeDef HAL_FMPI2C_Mem_Read_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size) | |
2355 { | |
2356 uint32_t tickstart = 0U; | |
2357 uint32_t xfermode = 0U; | |
2358 | |
2359 /* Check the parameters */ | |
2360 assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize)); | |
2361 | |
2362 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) | |
2363 { | |
2364 if ((pData == NULL) || (Size == 0U)) | |
2365 { | |
2366 return HAL_ERROR; | |
2367 } | |
2368 | |
2369 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET) | |
2370 { | |
2371 return HAL_BUSY; | |
2372 } | |
2373 | |
2374 /* Process Locked */ | |
2375 __HAL_LOCK(hfmpi2c); | |
2376 | |
2377 /* Init tickstart for timeout management*/ | |
2378 tickstart = HAL_GetTick(); | |
2379 | |
2380 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX; | |
2381 hfmpi2c->Mode = HAL_FMPI2C_MODE_MEM; | |
2382 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; | |
2383 | |
2384 /* Prepare transfer parameters */ | |
2385 hfmpi2c->pBuffPtr = pData; | |
2386 hfmpi2c->XferCount = Size; | |
2387 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; | |
2388 hfmpi2c->XferISR = FMPI2C_Master_ISR_DMA; | |
2389 | |
2390 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) | |
2391 { | |
2392 hfmpi2c->XferSize = MAX_NBYTE_SIZE; | |
2393 xfermode = FMPI2C_RELOAD_MODE; | |
2394 } | |
2395 else | |
2396 { | |
2397 hfmpi2c->XferSize = hfmpi2c->XferCount; | |
2398 xfermode = FMPI2C_AUTOEND_MODE; | |
2399 } | |
2400 | |
2401 /* Send Slave Address and Memory Address */ | |
2402 if (FMPI2C_RequestMemoryRead(hfmpi2c, DevAddress, MemAddress, MemAddSize, FMPI2C_TIMEOUT_FLAG, tickstart) != HAL_OK) | |
2403 { | |
2404 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) | |
2405 { | |
2406 /* Process Unlocked */ | |
2407 __HAL_UNLOCK(hfmpi2c); | |
2408 return HAL_ERROR; | |
2409 } | |
2410 else | |
2411 { | |
2412 /* Process Unlocked */ | |
2413 __HAL_UNLOCK(hfmpi2c); | |
2414 return HAL_TIMEOUT; | |
2415 } | |
2416 } | |
2417 | |
2418 /* Set the FMPI2C DMA transfer complete callback */ | |
2419 hfmpi2c->hdmarx->XferCpltCallback = FMPI2C_DMAMasterReceiveCplt; | |
2420 | |
2421 /* Set the DMA error callback */ | |
2422 hfmpi2c->hdmarx->XferErrorCallback = FMPI2C_DMAError; | |
2423 | |
2424 /* Set the unused DMA callbacks to NULL */ | |
2425 hfmpi2c->hdmarx->XferHalfCpltCallback = NULL; | |
2426 hfmpi2c->hdmarx->XferAbortCallback = NULL; | |
2427 | |
2428 /* Enable the DMA stream */ | |
2429 HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR, (uint32_t)pData, hfmpi2c->XferSize); | |
2430 | |
2431 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ | |
2432 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, xfermode, FMPI2C_GENERATE_START_READ); | |
2433 | |
2434 /* Update XferCount value */ | |
2435 hfmpi2c->XferCount -= hfmpi2c->XferSize; | |
2436 | |
2437 /* Process Unlocked */ | |
2438 __HAL_UNLOCK(hfmpi2c); | |
2439 | |
2440 /* Enable DMA Request */ | |
2441 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN; | |
2442 | |
2443 /* Note : The FMPI2C interrupts must be enabled after unlocking current process | |
2444 to avoid the risk of FMPI2C interrupt handle execution before current | |
2445 process unlock */ | |
2446 /* Enable ERR and NACK interrupts */ | |
2447 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_ERROR_IT); | |
2448 | |
2449 return HAL_OK; | |
2450 } | |
2451 else | |
2452 { | |
2453 return HAL_BUSY; | |
2454 } | |
2455 } | |
2456 | |
2457 /** | |
2458 * @brief Checks if target device is ready for communication. | |
2459 * @note This function is used with Memory devices | |
2460 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
2461 * the configuration information for the specified FMPI2C. | |
2462 * @param DevAddress Target device address The device 7 bits address value | |
2463 * in datasheet must be shifted to the left before calling the interface | |
2464 * @param Trials Number of trials | |
2465 * @param Timeout Timeout duration | |
2466 * @retval HAL status | |
2467 */ | |
2468 HAL_StatusTypeDef HAL_FMPI2C_IsDeviceReady(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout) | |
2469 { | |
2470 uint32_t tickstart = 0U; | |
2471 | |
2472 __IO uint32_t FMPI2C_Trials = 0U; | |
2473 | |
2474 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) | |
2475 { | |
2476 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET) | |
2477 { | |
2478 return HAL_BUSY; | |
2479 } | |
2480 | |
2481 /* Process Locked */ | |
2482 __HAL_LOCK(hfmpi2c); | |
2483 | |
2484 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY; | |
2485 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; | |
2486 | |
2487 do | |
2488 { | |
2489 /* Generate Start */ | |
2490 hfmpi2c->Instance->CR2 = FMPI2C_GENERATE_START(hfmpi2c->Init.AddressingMode, DevAddress); | |
2491 | |
2492 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ | |
2493 /* Wait until STOPF flag is set or a NACK flag is set*/ | |
2494 tickstart = HAL_GetTick(); | |
2495 while ((__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == RESET) && (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF) == RESET) && (hfmpi2c->State != HAL_FMPI2C_STATE_TIMEOUT)) | |
2496 { | |
2497 if (Timeout != HAL_MAX_DELAY) | |
2498 { | |
2499 if ((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout)) | |
2500 { | |
2501 /* Device is ready */ | |
2502 hfmpi2c->State = HAL_FMPI2C_STATE_READY; | |
2503 /* Process Unlocked */ | |
2504 __HAL_UNLOCK(hfmpi2c); | |
2505 return HAL_TIMEOUT; | |
2506 } | |
2507 } | |
2508 } | |
2509 | |
2510 /* Check if the NACKF flag has not been set */ | |
2511 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF) == RESET) | |
2512 { | |
2513 /* Wait until STOPF flag is reset */ | |
2514 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK) | |
2515 { | |
2516 return HAL_TIMEOUT; | |
2517 } | |
2518 | |
2519 /* Clear STOP Flag */ | |
2520 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); | |
2521 | |
2522 /* Device is ready */ | |
2523 hfmpi2c->State = HAL_FMPI2C_STATE_READY; | |
2524 | |
2525 /* Process Unlocked */ | |
2526 __HAL_UNLOCK(hfmpi2c); | |
2527 | |
2528 return HAL_OK; | |
2529 } | |
2530 else | |
2531 { | |
2532 /* Wait until STOPF flag is reset */ | |
2533 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK) | |
2534 { | |
2535 return HAL_TIMEOUT; | |
2536 } | |
2537 | |
2538 /* Clear NACK Flag */ | |
2539 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF); | |
2540 | |
2541 /* Clear STOP Flag, auto generated with autoend*/ | |
2542 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); | |
2543 } | |
2544 | |
2545 /* Check if the maximum allowed number of trials has been reached */ | |
2546 if (FMPI2C_Trials++ == Trials) | |
2547 { | |
2548 /* Generate Stop */ | |
2549 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_STOP; | |
2550 | |
2551 /* Wait until STOPF flag is reset */ | |
2552 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK) | |
2553 { | |
2554 return HAL_TIMEOUT; | |
2555 } | |
2556 | |
2557 /* Clear STOP Flag */ | |
2558 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); | |
2559 } | |
2560 } | |
2561 while (FMPI2C_Trials < Trials); | |
2562 | |
2563 hfmpi2c->State = HAL_FMPI2C_STATE_READY; | |
2564 | |
2565 /* Process Unlocked */ | |
2566 __HAL_UNLOCK(hfmpi2c); | |
2567 | |
2568 return HAL_TIMEOUT; | |
2569 } | |
2570 else | |
2571 { | |
2572 return HAL_BUSY; | |
2573 } | |
2574 } | |
2575 | |
2576 /** | |
2577 * @brief Sequential transmit in master FMPI2C mode an amount of data in non-blocking mode with Interrupt. | |
2578 * @note This interface allow to manage repeated start condition when a direction change during transfer | |
2579 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
2580 * the configuration information for the specified FMPI2C. | |
2581 * @param DevAddress Target device address The device 7 bits address value | |
2582 * in datasheet must be shifted to the left before calling the interface | |
2583 * @param pData Pointer to data buffer | |
2584 * @param Size Amount of data to be sent | |
2585 * @param XferOptions Options of Transfer, value of @ref FMPI2C_XFEROPTIONS | |
2586 * @retval HAL status | |
2587 */ | |
2588 HAL_StatusTypeDef HAL_FMPI2C_Master_Sequential_Transmit_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions) | |
2589 { | |
2590 uint32_t xfermode = 0U; | |
2591 uint32_t xferrequest = FMPI2C_GENERATE_START_WRITE; | |
2592 | |
2593 /* Check the parameters */ | |
2594 assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); | |
2595 | |
2596 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) | |
2597 { | |
2598 /* Process Locked */ | |
2599 __HAL_LOCK(hfmpi2c); | |
2600 | |
2601 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX; | |
2602 hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER; | |
2603 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; | |
2604 | |
2605 /* Prepare transfer parameters */ | |
2606 hfmpi2c->pBuffPtr = pData; | |
2607 hfmpi2c->XferCount = Size; | |
2608 hfmpi2c->XferOptions = XferOptions; | |
2609 hfmpi2c->XferISR = FMPI2C_Master_ISR_IT; | |
2610 | |
2611 /* If size > MAX_NBYTE_SIZE, use reload mode */ | |
2612 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) | |
2613 { | |
2614 hfmpi2c->XferSize = MAX_NBYTE_SIZE; | |
2615 xfermode = FMPI2C_RELOAD_MODE; | |
2616 } | |
2617 else | |
2618 { | |
2619 hfmpi2c->XferSize = hfmpi2c->XferCount; | |
2620 xfermode = hfmpi2c->XferOptions; | |
2621 } | |
2622 | |
2623 /* If transfer direction not change, do not generate Restart Condition */ | |
2624 /* Mean Previous state is same as current state */ | |
2625 if (hfmpi2c->PreviousState == FMPI2C_STATE_MASTER_BUSY_TX) | |
2626 { | |
2627 xferrequest = FMPI2C_NO_STARTSTOP; | |
2628 } | |
2629 | |
2630 /* Send Slave Address and set NBYTES to write */ | |
2631 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, xfermode, xferrequest); | |
2632 | |
2633 /* Process Unlocked */ | |
2634 __HAL_UNLOCK(hfmpi2c); | |
2635 | |
2636 /* Note : The FMPI2C interrupts must be enabled after unlocking current process | |
2637 to avoid the risk of FMPI2C interrupt handle execution before current | |
2638 process unlock */ | |
2639 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT); | |
2640 | |
2641 return HAL_OK; | |
2642 } | |
2643 else | |
2644 { | |
2645 return HAL_BUSY; | |
2646 } | |
2647 } | |
2648 | |
2649 /** | |
2650 * @brief Sequential receive in master FMPI2C mode an amount of data in non-blocking mode with Interrupt | |
2651 * @note This interface allow to manage repeated start condition when a direction change during transfer | |
2652 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
2653 * the configuration information for the specified FMPI2C. | |
2654 * @param DevAddress Target device address The device 7 bits address value | |
2655 * in datasheet must be shifted to the left before calling the interface | |
2656 * @param pData Pointer to data buffer | |
2657 * @param Size Amount of data to be sent | |
2658 * @param XferOptions Options of Transfer, value of @ref FMPI2C_XFEROPTIONS | |
2659 * @retval HAL status | |
2660 */ | |
2661 HAL_StatusTypeDef HAL_FMPI2C_Master_Sequential_Receive_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions) | |
2662 { | |
2663 uint32_t xfermode = 0U; | |
2664 uint32_t xferrequest = FMPI2C_GENERATE_START_READ; | |
2665 | |
2666 /* Check the parameters */ | |
2667 assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); | |
2668 | |
2669 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) | |
2670 { | |
2671 /* Process Locked */ | |
2672 __HAL_LOCK(hfmpi2c); | |
2673 | |
2674 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX; | |
2675 hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER; | |
2676 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; | |
2677 | |
2678 /* Prepare transfer parameters */ | |
2679 hfmpi2c->pBuffPtr = pData; | |
2680 hfmpi2c->XferCount = Size; | |
2681 hfmpi2c->XferOptions = XferOptions; | |
2682 hfmpi2c->XferISR = FMPI2C_Master_ISR_IT; | |
2683 | |
2684 /* If hfmpi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */ | |
2685 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) | |
2686 { | |
2687 hfmpi2c->XferSize = MAX_NBYTE_SIZE; | |
2688 xfermode = FMPI2C_RELOAD_MODE; | |
2689 } | |
2690 else | |
2691 { | |
2692 hfmpi2c->XferSize = hfmpi2c->XferCount; | |
2693 xfermode = hfmpi2c->XferOptions; | |
2694 } | |
2695 | |
2696 /* If transfer direction not change, do not generate Restart Condition */ | |
2697 /* Mean Previous state is same as current state */ | |
2698 if (hfmpi2c->PreviousState == FMPI2C_STATE_MASTER_BUSY_RX) | |
2699 { | |
2700 xferrequest = FMPI2C_NO_STARTSTOP; | |
2701 } | |
2702 | |
2703 /* Send Slave Address and set NBYTES to read */ | |
2704 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, xfermode, xferrequest); | |
2705 | |
2706 /* Process Unlocked */ | |
2707 __HAL_UNLOCK(hfmpi2c); | |
2708 | |
2709 /* Note : The FMPI2C interrupts must be enabled after unlocking current process | |
2710 to avoid the risk of FMPI2C interrupt handle execution before current | |
2711 process unlock */ | |
2712 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT); | |
2713 | |
2714 return HAL_OK; | |
2715 } | |
2716 else | |
2717 { | |
2718 return HAL_BUSY; | |
2719 } | |
2720 } | |
2721 | |
2722 /** | |
2723 * @brief Sequential transmit in slave/device FMPI2C mode an amount of data in non-blocking mode with Interrupt | |
2724 * @note This interface allow to manage repeated start condition when a direction change during transfer | |
2725 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
2726 * the configuration information for the specified FMPI2C. | |
2727 * @param pData Pointer to data buffer | |
2728 * @param Size Amount of data to be sent | |
2729 * @param XferOptions Options of Transfer, value of @ref FMPI2C_XFEROPTIONS | |
2730 * @retval HAL status | |
2731 */ | |
2732 HAL_StatusTypeDef HAL_FMPI2C_Slave_Sequential_Transmit_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions) | |
2733 { | |
2734 /* Check the parameters */ | |
2735 assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); | |
2736 | |
2737 if ((hfmpi2c->State & HAL_FMPI2C_STATE_LISTEN) == HAL_FMPI2C_STATE_LISTEN) | |
2738 { | |
2739 if ((pData == NULL) || (Size == 0U)) | |
2740 { | |
2741 return HAL_ERROR; | |
2742 } | |
2743 | |
2744 /* Disable Interrupts, to prevent preemption during treatment in case of multicall */ | |
2745 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_TX_IT); | |
2746 | |
2747 /* Process Locked */ | |
2748 __HAL_LOCK(hfmpi2c); | |
2749 | |
2750 /* FMPI2C cannot manage full duplex exchange so disable previous IT enabled if any */ | |
2751 /* and then toggle the HAL slave RX state to TX state */ | |
2752 if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX_LISTEN) | |
2753 { | |
2754 /* Disable associated Interrupts */ | |
2755 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT); | |
2756 } | |
2757 | |
2758 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX_LISTEN; | |
2759 hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE; | |
2760 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; | |
2761 | |
2762 /* Enable Address Acknowledge */ | |
2763 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK; | |
2764 | |
2765 /* Prepare transfer parameters */ | |
2766 hfmpi2c->pBuffPtr = pData; | |
2767 hfmpi2c->XferCount = Size; | |
2768 hfmpi2c->XferSize = hfmpi2c->XferCount; | |
2769 hfmpi2c->XferOptions = XferOptions; | |
2770 hfmpi2c->XferISR = FMPI2C_Slave_ISR_IT; | |
2771 | |
2772 if (FMPI2C_GET_DIR(hfmpi2c) == FMPI2C_DIRECTION_RECEIVE) | |
2773 { | |
2774 /* Clear ADDR flag after prepare the transfer parameters */ | |
2775 /* This action will generate an acknowledge to the Master */ | |
2776 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR); | |
2777 } | |
2778 | |
2779 /* Process Unlocked */ | |
2780 __HAL_UNLOCK(hfmpi2c); | |
2781 | |
2782 /* Note : The FMPI2C interrupts must be enabled after unlocking current process | |
2783 to avoid the risk of FMPI2C interrupt handle execution before current | |
2784 process unlock */ | |
2785 /* REnable ADDR interrupt */ | |
2786 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT | FMPI2C_XFER_LISTEN_IT); | |
2787 | |
2788 return HAL_OK; | |
2789 } | |
2790 else | |
2791 { | |
2792 return HAL_ERROR; | |
2793 } | |
2794 } | |
2795 | |
2796 /** | |
2797 * @brief Sequential receive in slave/device FMPI2C mode an amount of data in non-blocking mode with Interrupt | |
2798 * @note This interface allow to manage repeated start condition when a direction change during transfer | |
2799 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
2800 * the configuration information for the specified FMPI2C. | |
2801 * @param pData Pointer to data buffer | |
2802 * @param Size Amount of data to be sent | |
2803 * @param XferOptions Options of Transfer, value of @ref FMPI2C_XFEROPTIONS | |
2804 * @retval HAL status | |
2805 */ | |
2806 HAL_StatusTypeDef HAL_FMPI2C_Slave_Sequential_Receive_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions) | |
2807 { | |
2808 /* Check the parameters */ | |
2809 assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); | |
2810 | |
2811 if ((hfmpi2c->State & HAL_FMPI2C_STATE_LISTEN) == HAL_FMPI2C_STATE_LISTEN) | |
2812 { | |
2813 if ((pData == NULL) || (Size == 0U)) | |
2814 { | |
2815 return HAL_ERROR; | |
2816 } | |
2817 | |
2818 /* Disable Interrupts, to prevent preemption during treatment in case of multicall */ | |
2819 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_RX_IT); | |
2820 | |
2821 /* Process Locked */ | |
2822 __HAL_LOCK(hfmpi2c); | |
2823 | |
2824 /* FMPI2C cannot manage full duplex exchange so disable previous IT enabled if any */ | |
2825 /* and then toggle the HAL slave TX state to RX state */ | |
2826 if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX_LISTEN) | |
2827 { | |
2828 /* Disable associated Interrupts */ | |
2829 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT); | |
2830 } | |
2831 | |
2832 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX_LISTEN; | |
2833 hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE; | |
2834 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; | |
2835 | |
2836 /* Enable Address Acknowledge */ | |
2837 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK; | |
2838 | |
2839 /* Prepare transfer parameters */ | |
2840 hfmpi2c->pBuffPtr = pData; | |
2841 hfmpi2c->XferCount = Size; | |
2842 hfmpi2c->XferSize = hfmpi2c->XferCount; | |
2843 hfmpi2c->XferOptions = XferOptions; | |
2844 hfmpi2c->XferISR = FMPI2C_Slave_ISR_IT; | |
2845 | |
2846 if (FMPI2C_GET_DIR(hfmpi2c) == FMPI2C_DIRECTION_TRANSMIT) | |
2847 { | |
2848 /* Clear ADDR flag after prepare the transfer parameters */ | |
2849 /* This action will generate an acknowledge to the Master */ | |
2850 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR); | |
2851 } | |
2852 | |
2853 /* Process Unlocked */ | |
2854 __HAL_UNLOCK(hfmpi2c); | |
2855 | |
2856 /* Note : The FMPI2C interrupts must be enabled after unlocking current process | |
2857 to avoid the risk of FMPI2C interrupt handle execution before current | |
2858 process unlock */ | |
2859 /* REnable ADDR interrupt */ | |
2860 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT | FMPI2C_XFER_LISTEN_IT); | |
2861 | |
2862 return HAL_OK; | |
2863 } | |
2864 else | |
2865 { | |
2866 return HAL_ERROR; | |
2867 } | |
2868 } | |
2869 | |
2870 /** | |
2871 * @brief Enable the Address listen mode with Interrupt. | |
2872 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
2873 * the configuration information for the specified FMPI2C. | |
2874 * @retval HAL status | |
2875 */ | |
2876 HAL_StatusTypeDef HAL_FMPI2C_EnableListen_IT(FMPI2C_HandleTypeDef *hfmpi2c) | |
2877 { | |
2878 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) | |
2879 { | |
2880 hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN; | |
2881 hfmpi2c->XferISR = FMPI2C_Slave_ISR_IT; | |
2882 | |
2883 /* Enable the Address Match interrupt */ | |
2884 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT); | |
2885 | |
2886 return HAL_OK; | |
2887 } | |
2888 else | |
2889 { | |
2890 return HAL_BUSY; | |
2891 } | |
2892 } | |
2893 | |
2894 /** | |
2895 * @brief Disable the Address listen mode with Interrupt. | |
2896 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
2897 * the configuration information for the specified FMPI2C | |
2898 * @retval HAL status | |
2899 */ | |
2900 HAL_StatusTypeDef HAL_FMPI2C_DisableListen_IT(FMPI2C_HandleTypeDef *hfmpi2c) | |
2901 { | |
2902 /* Declaration of tmp to prevent undefined behavior of volatile usage */ | |
2903 uint32_t tmp; | |
2904 | |
2905 /* Disable Address listen mode only if a transfer is not ongoing */ | |
2906 if (hfmpi2c->State == HAL_FMPI2C_STATE_LISTEN) | |
2907 { | |
2908 tmp = (uint32_t)(hfmpi2c->State) & FMPI2C_STATE_MSK; | |
2909 hfmpi2c->PreviousState = tmp | (uint32_t)(hfmpi2c->Mode); | |
2910 hfmpi2c->State = HAL_FMPI2C_STATE_READY; | |
2911 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; | |
2912 hfmpi2c->XferISR = NULL; | |
2913 | |
2914 /* Disable the Address Match interrupt */ | |
2915 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT); | |
2916 | |
2917 return HAL_OK; | |
2918 } | |
2919 else | |
2920 { | |
2921 return HAL_BUSY; | |
2922 } | |
2923 } | |
2924 | |
2925 /** | |
2926 * @brief Abort a master FMPI2C IT or DMA process communication with Interrupt. | |
2927 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
2928 * the configuration information for the specified FMPI2C. | |
2929 * @param DevAddress Target device address The device 7 bits address value | |
2930 * in datasheet must be shifted to the left before calling the interface | |
2931 * @retval HAL status | |
2932 */ | |
2933 HAL_StatusTypeDef HAL_FMPI2C_Master_Abort_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress) | |
2934 { | |
2935 if (hfmpi2c->Mode == HAL_FMPI2C_MODE_MASTER) | |
2936 { | |
2937 /* Process Locked */ | |
2938 __HAL_LOCK(hfmpi2c); | |
2939 | |
2940 /* Disable Interrupts */ | |
2941 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT); | |
2942 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT); | |
2943 | |
2944 /* Set State at HAL_FMPI2C_STATE_ABORT */ | |
2945 hfmpi2c->State = HAL_FMPI2C_STATE_ABORT; | |
2946 | |
2947 /* Set NBYTES to 1 to generate a dummy read on FMPI2C peripheral */ | |
2948 /* Set AUTOEND mode, this will generate a NACK then STOP condition to abort the current transfer */ | |
2949 FMPI2C_TransferConfig(hfmpi2c, DevAddress, 1, FMPI2C_AUTOEND_MODE, FMPI2C_GENERATE_STOP); | |
2950 | |
2951 /* Process Unlocked */ | |
2952 __HAL_UNLOCK(hfmpi2c); | |
2953 | |
2954 /* Note : The FMPI2C interrupts must be enabled after unlocking current process | |
2955 to avoid the risk of FMPI2C interrupt handle execution before current | |
2956 process unlock */ | |
2957 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_CPLT_IT); | |
2958 | |
2959 return HAL_OK; | |
2960 } | |
2961 else | |
2962 { | |
2963 /* Wrong usage of abort function */ | |
2964 /* This function should be used only in case of abort monitored by master device */ | |
2965 return HAL_ERROR; | |
2966 } | |
2967 } | |
2968 | |
2969 /** | |
2970 * @} | |
2971 */ | |
2972 | |
2973 /** @defgroup FMPI2C_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks | |
2974 * @{ | |
2975 */ | |
2976 | |
2977 /** | |
2978 * @brief This function handles FMPI2C event interrupt request. | |
2979 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
2980 * the configuration information for the specified FMPI2C. | |
2981 * @retval None | |
2982 */ | |
2983 void HAL_FMPI2C_EV_IRQHandler(FMPI2C_HandleTypeDef *hfmpi2c) | |
2984 { | |
2985 /* Get current IT Flags and IT sources value */ | |
2986 uint32_t itflags = READ_REG(hfmpi2c->Instance->ISR); | |
2987 uint32_t itsources = READ_REG(hfmpi2c->Instance->CR1); | |
2988 | |
2989 /* FMPI2C events treatment -------------------------------------*/ | |
2990 if (hfmpi2c->XferISR != NULL) | |
2991 { | |
2992 hfmpi2c->XferISR(hfmpi2c, itflags, itsources); | |
2993 } | |
2994 } | |
2995 | |
2996 /** | |
2997 * @brief This function handles FMPI2C error interrupt request. | |
2998 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
2999 * the configuration information for the specified FMPI2C. | |
3000 * @retval None | |
3001 */ | |
3002 void HAL_FMPI2C_ER_IRQHandler(FMPI2C_HandleTypeDef *hfmpi2c) | |
3003 { | |
3004 uint32_t itflags = READ_REG(hfmpi2c->Instance->ISR); | |
3005 uint32_t itsources = READ_REG(hfmpi2c->Instance->CR1); | |
3006 | |
3007 /* FMPI2C Bus error interrupt occurred ------------------------------------*/ | |
3008 if (((itflags & FMPI2C_FLAG_BERR) != RESET) && ((itsources & FMPI2C_IT_ERRI) != RESET)) | |
3009 { | |
3010 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_BERR; | |
3011 | |
3012 /* Clear BERR flag */ | |
3013 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_BERR); | |
3014 } | |
3015 | |
3016 /* FMPI2C Over-Run/Under-Run interrupt occurred ----------------------------------------*/ | |
3017 if (((itflags & FMPI2C_FLAG_OVR) != RESET) && ((itsources & FMPI2C_IT_ERRI) != RESET)) | |
3018 { | |
3019 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_OVR; | |
3020 | |
3021 /* Clear OVR flag */ | |
3022 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_OVR); | |
3023 } | |
3024 | |
3025 /* FMPI2C Arbitration Loss error interrupt occurred -------------------------------------*/ | |
3026 if (((itflags & FMPI2C_FLAG_ARLO) != RESET) && ((itsources & FMPI2C_IT_ERRI) != RESET)) | |
3027 { | |
3028 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_ARLO; | |
3029 | |
3030 /* Clear ARLO flag */ | |
3031 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ARLO); | |
3032 } | |
3033 | |
3034 /* Call the Error Callback in case of Error detected */ | |
3035 if ((hfmpi2c->ErrorCode & (HAL_FMPI2C_ERROR_BERR | HAL_FMPI2C_ERROR_OVR | HAL_FMPI2C_ERROR_ARLO)) != HAL_FMPI2C_ERROR_NONE) | |
3036 { | |
3037 FMPI2C_ITError(hfmpi2c, hfmpi2c->ErrorCode); | |
3038 } | |
3039 } | |
3040 | |
3041 /** | |
3042 * @brief Master Tx Transfer completed callback. | |
3043 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
3044 * the configuration information for the specified FMPI2C. | |
3045 * @retval None | |
3046 */ | |
3047 __weak void HAL_FMPI2C_MasterTxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c) | |
3048 { | |
3049 /* Prevent unused argument(s) compilation warning */ | |
3050 UNUSED(hfmpi2c); | |
3051 | |
3052 /* NOTE : This function should not be modified, when the callback is needed, | |
3053 the HAL_FMPI2C_MasterTxCpltCallback could be implemented in the user file | |
3054 */ | |
3055 } | |
3056 | |
3057 /** | |
3058 * @brief Master Rx Transfer completed callback. | |
3059 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
3060 * the configuration information for the specified FMPI2C. | |
3061 * @retval None | |
3062 */ | |
3063 __weak void HAL_FMPI2C_MasterRxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c) | |
3064 { | |
3065 /* Prevent unused argument(s) compilation warning */ | |
3066 UNUSED(hfmpi2c); | |
3067 | |
3068 /* NOTE : This function should not be modified, when the callback is needed, | |
3069 the HAL_FMPI2C_MasterRxCpltCallback could be implemented in the user file | |
3070 */ | |
3071 } | |
3072 | |
3073 /** @brief Slave Tx Transfer completed callback. | |
3074 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
3075 * the configuration information for the specified FMPI2C. | |
3076 * @retval None | |
3077 */ | |
3078 __weak void HAL_FMPI2C_SlaveTxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c) | |
3079 { | |
3080 /* Prevent unused argument(s) compilation warning */ | |
3081 UNUSED(hfmpi2c); | |
3082 | |
3083 /* NOTE : This function should not be modified, when the callback is needed, | |
3084 the HAL_FMPI2C_SlaveTxCpltCallback could be implemented in the user file | |
3085 */ | |
3086 } | |
3087 | |
3088 /** | |
3089 * @brief Slave Rx Transfer completed callback. | |
3090 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
3091 * the configuration information for the specified FMPI2C. | |
3092 * @retval None | |
3093 */ | |
3094 __weak void HAL_FMPI2C_SlaveRxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c) | |
3095 { | |
3096 /* Prevent unused argument(s) compilation warning */ | |
3097 UNUSED(hfmpi2c); | |
3098 | |
3099 /* NOTE : This function should not be modified, when the callback is needed, | |
3100 the HAL_FMPI2C_SlaveRxCpltCallback could be implemented in the user file | |
3101 */ | |
3102 } | |
3103 | |
3104 /** | |
3105 * @brief Slave Address Match callback. | |
3106 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
3107 * the configuration information for the specified FMPI2C. | |
3108 * @param TransferDirection Master request Transfer Direction (Write/Read), value of @ref FMPI2C_XFERDIRECTION | |
3109 * @param AddrMatchCode Address Match Code | |
3110 * @retval None | |
3111 */ | |
3112 __weak void HAL_FMPI2C_AddrCallback(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t TransferDirection, uint16_t AddrMatchCode) | |
3113 { | |
3114 /* Prevent unused argument(s) compilation warning */ | |
3115 UNUSED(hfmpi2c); | |
3116 UNUSED(TransferDirection); | |
3117 UNUSED(AddrMatchCode); | |
3118 | |
3119 /* NOTE : This function should not be modified, when the callback is needed, | |
3120 the HAL_FMPI2C_AddrCallback() could be implemented in the user file | |
3121 */ | |
3122 } | |
3123 | |
3124 /** | |
3125 * @brief Listen Complete callback. | |
3126 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
3127 * the configuration information for the specified FMPI2C. | |
3128 * @retval None | |
3129 */ | |
3130 __weak void HAL_FMPI2C_ListenCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c) | |
3131 { | |
3132 /* Prevent unused argument(s) compilation warning */ | |
3133 UNUSED(hfmpi2c); | |
3134 | |
3135 /* NOTE : This function should not be modified, when the callback is needed, | |
3136 the HAL_FMPI2C_ListenCpltCallback() could be implemented in the user file | |
3137 */ | |
3138 } | |
3139 | |
3140 /** | |
3141 * @brief Memory Tx Transfer completed callback. | |
3142 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
3143 * the configuration information for the specified FMPI2C. | |
3144 * @retval None | |
3145 */ | |
3146 __weak void HAL_FMPI2C_MemTxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c) | |
3147 { | |
3148 /* Prevent unused argument(s) compilation warning */ | |
3149 UNUSED(hfmpi2c); | |
3150 | |
3151 /* NOTE : This function should not be modified, when the callback is needed, | |
3152 the HAL_FMPI2C_MemTxCpltCallback could be implemented in the user file | |
3153 */ | |
3154 } | |
3155 | |
3156 /** | |
3157 * @brief Memory Rx Transfer completed callback. | |
3158 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
3159 * the configuration information for the specified FMPI2C. | |
3160 * @retval None | |
3161 */ | |
3162 __weak void HAL_FMPI2C_MemRxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c) | |
3163 { | |
3164 /* Prevent unused argument(s) compilation warning */ | |
3165 UNUSED(hfmpi2c); | |
3166 | |
3167 /* NOTE : This function should not be modified, when the callback is needed, | |
3168 the HAL_FMPI2C_MemRxCpltCallback could be implemented in the user file | |
3169 */ | |
3170 } | |
3171 | |
3172 /** | |
3173 * @brief FMPI2C error callback. | |
3174 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
3175 * the configuration information for the specified FMPI2C. | |
3176 * @retval None | |
3177 */ | |
3178 __weak void HAL_FMPI2C_ErrorCallback(FMPI2C_HandleTypeDef *hfmpi2c) | |
3179 { | |
3180 /* Prevent unused argument(s) compilation warning */ | |
3181 UNUSED(hfmpi2c); | |
3182 | |
3183 /* NOTE : This function should not be modified, when the callback is needed, | |
3184 the HAL_FMPI2C_ErrorCallback could be implemented in the user file | |
3185 */ | |
3186 } | |
3187 | |
3188 /** | |
3189 * @brief FMPI2C abort callback. | |
3190 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
3191 * the configuration information for the specified FMPI2C. | |
3192 * @retval None | |
3193 */ | |
3194 __weak void HAL_FMPI2C_AbortCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c) | |
3195 { | |
3196 /* Prevent unused argument(s) compilation warning */ | |
3197 UNUSED(hfmpi2c); | |
3198 | |
3199 /* NOTE : This function should not be modified, when the callback is needed, | |
3200 the HAL_FMPI2C_AbortCpltCallback could be implemented in the user file | |
3201 */ | |
3202 } | |
3203 | |
3204 /** | |
3205 * @} | |
3206 */ | |
3207 | |
3208 /** @defgroup FMPI2C_Exported_Functions_Group3 Peripheral State, Mode and Error functions | |
3209 * @brief Peripheral State, Mode and Error functions | |
3210 * | |
3211 @verbatim | |
3212 =============================================================================== | |
3213 ##### Peripheral State, Mode and Error functions ##### | |
3214 =============================================================================== | |
3215 [..] | |
3216 This subsection permit to get in run-time the status of the peripheral | |
3217 and the data flow. | |
3218 | |
3219 @endverbatim | |
3220 * @{ | |
3221 */ | |
3222 | |
3223 /** | |
3224 * @brief Return the FMPI2C handle state. | |
3225 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
3226 * the configuration information for the specified FMPI2C. | |
3227 * @retval HAL state | |
3228 */ | |
3229 HAL_FMPI2C_StateTypeDef HAL_FMPI2C_GetState(FMPI2C_HandleTypeDef *hfmpi2c) | |
3230 { | |
3231 /* Return FMPI2C handle state */ | |
3232 return hfmpi2c->State; | |
3233 } | |
3234 | |
3235 /** | |
3236 * @brief Returns the FMPI2C Master, Slave, Memory or no mode. | |
3237 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
3238 * the configuration information for FMPI2C module | |
3239 * @retval HAL mode | |
3240 */ | |
3241 HAL_FMPI2C_ModeTypeDef HAL_FMPI2C_GetMode(FMPI2C_HandleTypeDef *hfmpi2c) | |
3242 { | |
3243 return hfmpi2c->Mode; | |
3244 } | |
3245 | |
3246 /** | |
3247 * @brief Return the FMPI2C error code. | |
3248 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
3249 * the configuration information for the specified FMPI2C. | |
3250 * @retval FMPI2C Error Code | |
3251 */ | |
3252 uint32_t HAL_FMPI2C_GetError(FMPI2C_HandleTypeDef *hfmpi2c) | |
3253 { | |
3254 return hfmpi2c->ErrorCode; | |
3255 } | |
3256 | |
3257 /** | |
3258 * @} | |
3259 */ | |
3260 | |
3261 /** | |
3262 * @} | |
3263 */ | |
3264 | |
3265 /** @addtogroup FMPI2C_Private_Functions | |
3266 * @{ | |
3267 */ | |
3268 | |
3269 /** | |
3270 * @brief Interrupt Sub-Routine which handle the Interrupt Flags Master Mode with Interrupt. | |
3271 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
3272 * the configuration information for the specified FMPI2C. | |
3273 * @param ITFlags Interrupt flags to handle. | |
3274 * @param ITSources Interrupt sources enabled. | |
3275 * @retval HAL status | |
3276 */ | |
3277 static HAL_StatusTypeDef FMPI2C_Master_ISR_IT(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags, uint32_t ITSources) | |
3278 { | |
3279 uint16_t devaddress = 0U; | |
3280 | |
3281 /* Process Locked */ | |
3282 __HAL_LOCK(hfmpi2c); | |
3283 | |
3284 if (((ITFlags & FMPI2C_FLAG_AF) != RESET) && ((ITSources & FMPI2C_IT_NACKI) != RESET)) | |
3285 { | |
3286 /* Clear NACK Flag */ | |
3287 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF); | |
3288 | |
3289 /* Set corresponding Error Code */ | |
3290 /* No need to generate STOP, it is automatically done */ | |
3291 /* Error callback will be send during stop flag treatment */ | |
3292 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF; | |
3293 | |
3294 /* Flush TX register */ | |
3295 FMPI2C_Flush_TXDR(hfmpi2c); | |
3296 } | |
3297 else if (((ITFlags & FMPI2C_FLAG_RXNE) != RESET) && ((ITSources & FMPI2C_IT_RXI) != RESET)) | |
3298 { | |
3299 /* Read data from RXDR */ | |
3300 (*hfmpi2c->pBuffPtr++) = hfmpi2c->Instance->RXDR; | |
3301 hfmpi2c->XferSize--; | |
3302 hfmpi2c->XferCount--; | |
3303 } | |
3304 else if (((ITFlags & FMPI2C_FLAG_TXIS) != RESET) && ((ITSources & FMPI2C_IT_TXI) != RESET)) | |
3305 { | |
3306 /* Write data to TXDR */ | |
3307 hfmpi2c->Instance->TXDR = (*hfmpi2c->pBuffPtr++); | |
3308 hfmpi2c->XferSize--; | |
3309 hfmpi2c->XferCount--; | |
3310 } | |
3311 else if (((ITFlags & FMPI2C_FLAG_TCR) != RESET) && ((ITSources & FMPI2C_IT_TCI) != RESET)) | |
3312 { | |
3313 if ((hfmpi2c->XferSize == 0U) && (hfmpi2c->XferCount != 0U)) | |
3314 { | |
3315 devaddress = (hfmpi2c->Instance->CR2 & FMPI2C_CR2_SADD); | |
3316 | |
3317 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) | |
3318 { | |
3319 hfmpi2c->XferSize = MAX_NBYTE_SIZE; | |
3320 FMPI2C_TransferConfig(hfmpi2c, devaddress, hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP); | |
3321 } | |
3322 else | |
3323 { | |
3324 hfmpi2c->XferSize = hfmpi2c->XferCount; | |
3325 if (hfmpi2c->XferOptions != FMPI2C_NO_OPTION_FRAME) | |
3326 { | |
3327 FMPI2C_TransferConfig(hfmpi2c, devaddress, hfmpi2c->XferSize, hfmpi2c->XferOptions, FMPI2C_NO_STARTSTOP); | |
3328 } | |
3329 else | |
3330 { | |
3331 FMPI2C_TransferConfig(hfmpi2c, devaddress, hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP); | |
3332 } | |
3333 } | |
3334 } | |
3335 else | |
3336 { | |
3337 /* Call TxCpltCallback() if no stop mode is set */ | |
3338 if (FMPI2C_GET_STOP_MODE(hfmpi2c) != FMPI2C_AUTOEND_MODE) | |
3339 { | |
3340 /* Call FMPI2C Master Sequential complete process */ | |
3341 FMPI2C_ITMasterSequentialCplt(hfmpi2c); | |
3342 } | |
3343 else | |
3344 { | |
3345 /* Wrong size Status regarding TCR flag event */ | |
3346 /* Call the corresponding callback to inform upper layer of End of Transfer */ | |
3347 FMPI2C_ITError(hfmpi2c, HAL_FMPI2C_ERROR_SIZE); | |
3348 } | |
3349 } | |
3350 } | |
3351 else if (((ITFlags & FMPI2C_FLAG_TC) != RESET) && ((ITSources & FMPI2C_IT_TCI) != RESET)) | |
3352 { | |
3353 if (hfmpi2c->XferCount == 0U) | |
3354 { | |
3355 if (FMPI2C_GET_STOP_MODE(hfmpi2c) != FMPI2C_AUTOEND_MODE) | |
3356 { | |
3357 /* Generate a stop condition in case of no transfer option */ | |
3358 if (hfmpi2c->XferOptions == FMPI2C_NO_OPTION_FRAME) | |
3359 { | |
3360 /* Generate Stop */ | |
3361 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_STOP; | |
3362 } | |
3363 else | |
3364 { | |
3365 /* Call FMPI2C Master Sequential complete process */ | |
3366 FMPI2C_ITMasterSequentialCplt(hfmpi2c); | |
3367 } | |
3368 } | |
3369 } | |
3370 else | |
3371 { | |
3372 /* Wrong size Status regarding TC flag event */ | |
3373 /* Call the corresponding callback to inform upper layer of End of Transfer */ | |
3374 FMPI2C_ITError(hfmpi2c, HAL_FMPI2C_ERROR_SIZE); | |
3375 } | |
3376 } | |
3377 | |
3378 if (((ITFlags & FMPI2C_FLAG_STOPF) != RESET) && ((ITSources & FMPI2C_IT_STOPI) != RESET)) | |
3379 { | |
3380 /* Call FMPI2C Master complete process */ | |
3381 FMPI2C_ITMasterCplt(hfmpi2c, ITFlags); | |
3382 } | |
3383 | |
3384 /* Process Unlocked */ | |
3385 __HAL_UNLOCK(hfmpi2c); | |
3386 | |
3387 return HAL_OK; | |
3388 } | |
3389 | |
3390 /** | |
3391 * @brief Interrupt Sub-Routine which handle the Interrupt Flags Slave Mode with Interrupt. | |
3392 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
3393 * the configuration information for the specified FMPI2C. | |
3394 * @param ITFlags Interrupt flags to handle. | |
3395 * @param ITSources Interrupt sources enabled. | |
3396 * @retval HAL status | |
3397 */ | |
3398 static HAL_StatusTypeDef FMPI2C_Slave_ISR_IT(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags, uint32_t ITSources) | |
3399 { | |
3400 /* Process locked */ | |
3401 __HAL_LOCK(hfmpi2c); | |
3402 | |
3403 if (((ITFlags & FMPI2C_FLAG_AF) != RESET) && ((ITSources & FMPI2C_IT_NACKI) != RESET)) | |
3404 { | |
3405 /* Check that FMPI2C transfer finished */ | |
3406 /* if yes, normal use case, a NACK is sent by the MASTER when Transfer is finished */ | |
3407 /* Mean XferCount == 0*/ | |
3408 /* So clear Flag NACKF only */ | |
3409 if (hfmpi2c->XferCount == 0U) | |
3410 { | |
3411 if (((hfmpi2c->XferOptions == FMPI2C_FIRST_AND_LAST_FRAME) || (hfmpi2c->XferOptions == FMPI2C_LAST_FRAME)) && \ | |
3412 (hfmpi2c->State == HAL_FMPI2C_STATE_LISTEN)) | |
3413 { | |
3414 /* Call FMPI2C Listen complete process */ | |
3415 FMPI2C_ITListenCplt(hfmpi2c, ITFlags); | |
3416 } | |
3417 else if ((hfmpi2c->XferOptions != FMPI2C_NO_OPTION_FRAME) && (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX_LISTEN)) | |
3418 { | |
3419 /* Clear NACK Flag */ | |
3420 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF); | |
3421 | |
3422 /* Flush TX register */ | |
3423 FMPI2C_Flush_TXDR(hfmpi2c); | |
3424 | |
3425 /* Last Byte is Transmitted */ | |
3426 /* Call FMPI2C Slave Sequential complete process */ | |
3427 FMPI2C_ITSlaveSequentialCplt(hfmpi2c); | |
3428 } | |
3429 else | |
3430 { | |
3431 /* Clear NACK Flag */ | |
3432 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF); | |
3433 } | |
3434 } | |
3435 else | |
3436 { | |
3437 /* if no, error use case, a Non-Acknowledge of last Data is generated by the MASTER*/ | |
3438 /* Clear NACK Flag */ | |
3439 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF); | |
3440 | |
3441 /* Set ErrorCode corresponding to a Non-Acknowledge */ | |
3442 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF; | |
3443 } | |
3444 } | |
3445 else if (((ITFlags & FMPI2C_FLAG_RXNE) != RESET) && ((ITSources & FMPI2C_IT_RXI) != RESET)) | |
3446 { | |
3447 if (hfmpi2c->XferCount > 0U) | |
3448 { | |
3449 /* Read data from RXDR */ | |
3450 (*hfmpi2c->pBuffPtr++) = hfmpi2c->Instance->RXDR; | |
3451 hfmpi2c->XferSize--; | |
3452 hfmpi2c->XferCount--; | |
3453 } | |
3454 | |
3455 if ((hfmpi2c->XferCount == 0U) && \ | |
3456 (hfmpi2c->XferOptions != FMPI2C_NO_OPTION_FRAME)) | |
3457 { | |
3458 /* Call FMPI2C Slave Sequential complete process */ | |
3459 FMPI2C_ITSlaveSequentialCplt(hfmpi2c); | |
3460 } | |
3461 } | |
3462 else if (((ITFlags & FMPI2C_FLAG_ADDR) != RESET) && ((ITSources & FMPI2C_IT_ADDRI) != RESET)) | |
3463 { | |
3464 FMPI2C_ITAddrCplt(hfmpi2c, ITFlags); | |
3465 } | |
3466 else if (((ITFlags & FMPI2C_FLAG_TXIS) != RESET) && ((ITSources & FMPI2C_IT_TXI) != RESET)) | |
3467 { | |
3468 /* Write data to TXDR only if XferCount not reach "0" */ | |
3469 /* A TXIS flag can be set, during STOP treatment */ | |
3470 /* Check if all Datas have already been sent */ | |
3471 /* If it is the case, this last write in TXDR is not sent, correspond to a dummy TXIS event */ | |
3472 if (hfmpi2c->XferCount > 0U) | |
3473 { | |
3474 /* Write data to TXDR */ | |
3475 hfmpi2c->Instance->TXDR = (*hfmpi2c->pBuffPtr++); | |
3476 hfmpi2c->XferCount--; | |
3477 hfmpi2c->XferSize--; | |
3478 } | |
3479 else | |
3480 { | |
3481 if ((hfmpi2c->XferOptions == FMPI2C_NEXT_FRAME) || (hfmpi2c->XferOptions == FMPI2C_FIRST_FRAME)) | |
3482 { | |
3483 /* Last Byte is Transmitted */ | |
3484 /* Call FMPI2C Slave Sequential complete process */ | |
3485 FMPI2C_ITSlaveSequentialCplt(hfmpi2c); | |
3486 } | |
3487 } | |
3488 } | |
3489 | |
3490 /* Check if STOPF is set */ | |
3491 if (((ITFlags & FMPI2C_FLAG_STOPF) != RESET) && ((ITSources & FMPI2C_IT_STOPI) != RESET)) | |
3492 { | |
3493 /* Call FMPI2C Slave complete process */ | |
3494 FMPI2C_ITSlaveCplt(hfmpi2c, ITFlags); | |
3495 } | |
3496 | |
3497 /* Process Unlocked */ | |
3498 __HAL_UNLOCK(hfmpi2c); | |
3499 | |
3500 return HAL_OK; | |
3501 } | |
3502 | |
3503 /** | |
3504 * @brief Interrupt Sub-Routine which handle the Interrupt Flags Master Mode with DMA. | |
3505 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
3506 * the configuration information for the specified FMPI2C. | |
3507 * @param ITFlags Interrupt flags to handle. | |
3508 * @param ITSources Interrupt sources enabled. | |
3509 * @retval HAL status | |
3510 */ | |
3511 static HAL_StatusTypeDef FMPI2C_Master_ISR_DMA(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags, uint32_t ITSources) | |
3512 { | |
3513 uint16_t devaddress = 0U; | |
3514 uint32_t xfermode = 0U; | |
3515 | |
3516 /* Process Locked */ | |
3517 __HAL_LOCK(hfmpi2c); | |
3518 | |
3519 if (((ITFlags & FMPI2C_FLAG_AF) != RESET) && ((ITSources & FMPI2C_IT_NACKI) != RESET)) | |
3520 { | |
3521 /* Clear NACK Flag */ | |
3522 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF); | |
3523 | |
3524 /* Set corresponding Error Code */ | |
3525 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF; | |
3526 | |
3527 /* No need to generate STOP, it is automatically done */ | |
3528 /* But enable STOP interrupt, to treat it */ | |
3529 /* Error callback will be send during stop flag treatment */ | |
3530 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_CPLT_IT); | |
3531 | |
3532 /* Flush TX register */ | |
3533 FMPI2C_Flush_TXDR(hfmpi2c); | |
3534 } | |
3535 else if (((ITFlags & FMPI2C_FLAG_TCR) != RESET) && ((ITSources & FMPI2C_IT_TCI) != RESET)) | |
3536 { | |
3537 /* Disable TC interrupt */ | |
3538 __HAL_FMPI2C_DISABLE_IT(hfmpi2c, FMPI2C_IT_TCI); | |
3539 | |
3540 if (hfmpi2c->XferCount != 0U) | |
3541 { | |
3542 /* Recover Slave address */ | |
3543 devaddress = (hfmpi2c->Instance->CR2 & FMPI2C_CR2_SADD); | |
3544 | |
3545 /* Prepare the new XferSize to transfer */ | |
3546 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) | |
3547 { | |
3548 hfmpi2c->XferSize = MAX_NBYTE_SIZE; | |
3549 xfermode = FMPI2C_RELOAD_MODE; | |
3550 } | |
3551 else | |
3552 { | |
3553 hfmpi2c->XferSize = hfmpi2c->XferCount; | |
3554 xfermode = FMPI2C_AUTOEND_MODE; | |
3555 } | |
3556 | |
3557 /* Set the new XferSize in Nbytes register */ | |
3558 FMPI2C_TransferConfig(hfmpi2c, devaddress, hfmpi2c->XferSize, xfermode, FMPI2C_NO_STARTSTOP); | |
3559 | |
3560 /* Update XferCount value */ | |
3561 hfmpi2c->XferCount -= hfmpi2c->XferSize; | |
3562 | |
3563 /* Enable DMA Request */ | |
3564 if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX) | |
3565 { | |
3566 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN; | |
3567 } | |
3568 else | |
3569 { | |
3570 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN; | |
3571 } | |
3572 } | |
3573 else | |
3574 { | |
3575 /* Wrong size Status regarding TCR flag event */ | |
3576 /* Call the corresponding callback to inform upper layer of End of Transfer */ | |
3577 FMPI2C_ITError(hfmpi2c, HAL_FMPI2C_ERROR_SIZE); | |
3578 } | |
3579 } | |
3580 else if (((ITFlags & FMPI2C_FLAG_STOPF) != RESET) && ((ITSources & FMPI2C_IT_STOPI) != RESET)) | |
3581 { | |
3582 /* Call FMPI2C Master complete process */ | |
3583 FMPI2C_ITMasterCplt(hfmpi2c, ITFlags); | |
3584 } | |
3585 | |
3586 /* Process Unlocked */ | |
3587 __HAL_UNLOCK(hfmpi2c); | |
3588 | |
3589 return HAL_OK; | |
3590 } | |
3591 | |
3592 /** | |
3593 * @brief Interrupt Sub-Routine which handle the Interrupt Flags Slave Mode with DMA. | |
3594 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
3595 * the configuration information for the specified FMPI2C. | |
3596 * @param ITFlags Interrupt flags to handle. | |
3597 * @param ITSources Interrupt sources enabled. | |
3598 * @retval HAL status | |
3599 */ | |
3600 static HAL_StatusTypeDef FMPI2C_Slave_ISR_DMA(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags, uint32_t ITSources) | |
3601 { | |
3602 /* Process locked */ | |
3603 __HAL_LOCK(hfmpi2c); | |
3604 | |
3605 if (((ITFlags & FMPI2C_FLAG_AF) != RESET) && ((ITSources & FMPI2C_IT_NACKI) != RESET)) | |
3606 { | |
3607 /* Check that FMPI2C transfer finished */ | |
3608 /* if yes, normal use case, a NACK is sent by the MASTER when Transfer is finished */ | |
3609 /* Mean XferCount == 0 */ | |
3610 /* So clear Flag NACKF only */ | |
3611 if (FMPI2C_GET_DMA_REMAIN_DATA(hfmpi2c) == 0U) | |
3612 { | |
3613 /* Clear NACK Flag */ | |
3614 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF); | |
3615 } | |
3616 else | |
3617 { | |
3618 /* if no, error use case, a Non-Acknowledge of last Data is generated by the MASTER*/ | |
3619 /* Clear NACK Flag */ | |
3620 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF); | |
3621 | |
3622 /* Set ErrorCode corresponding to a Non-Acknowledge */ | |
3623 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF; | |
3624 } | |
3625 } | |
3626 else if (((ITFlags & FMPI2C_FLAG_ADDR) != RESET) && ((ITSources & FMPI2C_IT_ADDRI) != RESET)) | |
3627 { | |
3628 /* Clear ADDR flag */ | |
3629 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR); | |
3630 } | |
3631 else if (((ITFlags & FMPI2C_FLAG_STOPF) != RESET) && ((ITSources & FMPI2C_IT_STOPI) != RESET)) | |
3632 { | |
3633 /* Call FMPI2C Slave complete process */ | |
3634 FMPI2C_ITSlaveCplt(hfmpi2c, ITFlags); | |
3635 } | |
3636 | |
3637 /* Process Unlocked */ | |
3638 __HAL_UNLOCK(hfmpi2c); | |
3639 | |
3640 return HAL_OK; | |
3641 } | |
3642 | |
3643 /** | |
3644 * @brief Master sends target device address followed by internal memory address for write request. | |
3645 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
3646 * the configuration information for the specified FMPI2C. | |
3647 * @param DevAddress Target device address The device 7 bits address value | |
3648 * in datasheet must be shifted to the left before calling the interface | |
3649 * @param MemAddress Internal memory address | |
3650 * @param MemAddSize Size of internal memory address | |
3651 * @param Timeout Timeout duration | |
3652 * @param Tickstart Tick start value | |
3653 * @retval HAL status | |
3654 */ | |
3655 static HAL_StatusTypeDef FMPI2C_RequestMemoryWrite(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart) | |
3656 { | |
3657 FMPI2C_TransferConfig(hfmpi2c, DevAddress, MemAddSize, FMPI2C_RELOAD_MODE, FMPI2C_GENERATE_START_WRITE); | |
3658 | |
3659 /* Wait until TXIS flag is set */ | |
3660 if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, Tickstart) != HAL_OK) | |
3661 { | |
3662 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) | |
3663 { | |
3664 return HAL_ERROR; | |
3665 } | |
3666 else | |
3667 { | |
3668 return HAL_TIMEOUT; | |
3669 } | |
3670 } | |
3671 | |
3672 /* If Memory address size is 8Bit */ | |
3673 if (MemAddSize == FMPI2C_MEMADD_SIZE_8BIT) | |
3674 { | |
3675 /* Send Memory Address */ | |
3676 hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_LSB(MemAddress); | |
3677 } | |
3678 /* If Memory address size is 16Bit */ | |
3679 else | |
3680 { | |
3681 /* Send MSB of Memory Address */ | |
3682 hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_MSB(MemAddress); | |
3683 | |
3684 /* Wait until TXIS flag is set */ | |
3685 if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, Tickstart) != HAL_OK) | |
3686 { | |
3687 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) | |
3688 { | |
3689 return HAL_ERROR; | |
3690 } | |
3691 else | |
3692 { | |
3693 return HAL_TIMEOUT; | |
3694 } | |
3695 } | |
3696 | |
3697 /* Send LSB of Memory Address */ | |
3698 hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_LSB(MemAddress); | |
3699 } | |
3700 | |
3701 /* Wait until TCR flag is set */ | |
3702 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout, Tickstart) != HAL_OK) | |
3703 { | |
3704 return HAL_TIMEOUT; | |
3705 } | |
3706 | |
3707 return HAL_OK; | |
3708 } | |
3709 | |
3710 /** | |
3711 * @brief Master sends target device address followed by internal memory address for read request. | |
3712 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
3713 * the configuration information for the specified FMPI2C. | |
3714 * @param DevAddress Target device address The device 7 bits address value | |
3715 * in datasheet must be shifted to the left before calling the interface | |
3716 * @param MemAddress Internal memory address | |
3717 * @param MemAddSize Size of internal memory address | |
3718 * @param Timeout Timeout duration | |
3719 * @param Tickstart Tick start value | |
3720 * @retval HAL status | |
3721 */ | |
3722 static HAL_StatusTypeDef FMPI2C_RequestMemoryRead(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart) | |
3723 { | |
3724 FMPI2C_TransferConfig(hfmpi2c, DevAddress, MemAddSize, FMPI2C_SOFTEND_MODE, FMPI2C_GENERATE_START_WRITE); | |
3725 | |
3726 /* Wait until TXIS flag is set */ | |
3727 if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, Tickstart) != HAL_OK) | |
3728 { | |
3729 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) | |
3730 { | |
3731 return HAL_ERROR; | |
3732 } | |
3733 else | |
3734 { | |
3735 return HAL_TIMEOUT; | |
3736 } | |
3737 } | |
3738 | |
3739 /* If Memory address size is 8Bit */ | |
3740 if (MemAddSize == FMPI2C_MEMADD_SIZE_8BIT) | |
3741 { | |
3742 /* Send Memory Address */ | |
3743 hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_LSB(MemAddress); | |
3744 } | |
3745 /* If Memory address size is 16Bit */ | |
3746 else | |
3747 { | |
3748 /* Send MSB of Memory Address */ | |
3749 hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_MSB(MemAddress); | |
3750 | |
3751 /* Wait until TXIS flag is set */ | |
3752 if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, Tickstart) != HAL_OK) | |
3753 { | |
3754 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) | |
3755 { | |
3756 return HAL_ERROR; | |
3757 } | |
3758 else | |
3759 { | |
3760 return HAL_TIMEOUT; | |
3761 } | |
3762 } | |
3763 | |
3764 /* Send LSB of Memory Address */ | |
3765 hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_LSB(MemAddress); | |
3766 } | |
3767 | |
3768 /* Wait until TC flag is set */ | |
3769 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TC, RESET, Timeout, Tickstart) != HAL_OK) | |
3770 { | |
3771 return HAL_TIMEOUT; | |
3772 } | |
3773 | |
3774 return HAL_OK; | |
3775 } | |
3776 | |
3777 /** | |
3778 * @brief FMPI2C Address complete process callback. | |
3779 * @param hfmpi2c FMPI2C handle. | |
3780 * @param ITFlags Interrupt flags to handle. | |
3781 * @retval None | |
3782 */ | |
3783 static void FMPI2C_ITAddrCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags) | |
3784 { | |
3785 uint8_t transferdirection = 0; | |
3786 uint16_t slaveaddrcode = 0; | |
3787 uint16_t ownadd1code = 0; | |
3788 uint16_t ownadd2code = 0; | |
3789 | |
3790 /* Prevent unused argument(s) compilation warning */ | |
3791 UNUSED(ITFlags); | |
3792 | |
3793 /* In case of Listen state, need to inform upper layer of address match code event */ | |
3794 if ((hfmpi2c->State & HAL_FMPI2C_STATE_LISTEN) == HAL_FMPI2C_STATE_LISTEN) | |
3795 { | |
3796 transferdirection = FMPI2C_GET_DIR(hfmpi2c); | |
3797 slaveaddrcode = FMPI2C_GET_ADDR_MATCH(hfmpi2c); | |
3798 ownadd1code = FMPI2C_GET_OWN_ADDRESS1(hfmpi2c); | |
3799 ownadd2code = FMPI2C_GET_OWN_ADDRESS2(hfmpi2c); | |
3800 | |
3801 /* If 10bits addressing mode is selected */ | |
3802 if (hfmpi2c->Init.AddressingMode == FMPI2C_ADDRESSINGMODE_10BIT) | |
3803 { | |
3804 if ((slaveaddrcode & SlaveAddr_MSK) == ((ownadd1code >> SlaveAddr_SHIFT) & SlaveAddr_MSK)) | |
3805 { | |
3806 slaveaddrcode = ownadd1code; | |
3807 hfmpi2c->AddrEventCount++; | |
3808 if (hfmpi2c->AddrEventCount == 2U) | |
3809 { | |
3810 /* Reset Address Event counter */ | |
3811 hfmpi2c->AddrEventCount = 0U; | |
3812 | |
3813 /* Clear ADDR flag */ | |
3814 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR); | |
3815 | |
3816 /* Process Unlocked */ | |
3817 __HAL_UNLOCK(hfmpi2c); | |
3818 | |
3819 /* Call Slave Addr callback */ | |
3820 HAL_FMPI2C_AddrCallback(hfmpi2c, transferdirection, slaveaddrcode); | |
3821 } | |
3822 } | |
3823 else | |
3824 { | |
3825 slaveaddrcode = ownadd2code; | |
3826 | |
3827 /* Disable ADDR Interrupts */ | |
3828 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT); | |
3829 | |
3830 /* Process Unlocked */ | |
3831 __HAL_UNLOCK(hfmpi2c); | |
3832 | |
3833 /* Call Slave Addr callback */ | |
3834 HAL_FMPI2C_AddrCallback(hfmpi2c, transferdirection, slaveaddrcode); | |
3835 } | |
3836 } | |
3837 /* else 7 bits addressing mode is selected */ | |
3838 else | |
3839 { | |
3840 /* Disable ADDR Interrupts */ | |
3841 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT); | |
3842 | |
3843 /* Process Unlocked */ | |
3844 __HAL_UNLOCK(hfmpi2c); | |
3845 | |
3846 /* Call Slave Addr callback */ | |
3847 HAL_FMPI2C_AddrCallback(hfmpi2c, transferdirection, slaveaddrcode); | |
3848 } | |
3849 } | |
3850 /* Else clear address flag only */ | |
3851 else | |
3852 { | |
3853 /* Clear ADDR flag */ | |
3854 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR); | |
3855 | |
3856 /* Process Unlocked */ | |
3857 __HAL_UNLOCK(hfmpi2c); | |
3858 } | |
3859 } | |
3860 | |
3861 /** | |
3862 * @brief FMPI2C Master sequential complete process. | |
3863 * @param hfmpi2c FMPI2C handle. | |
3864 * @retval None | |
3865 */ | |
3866 static void FMPI2C_ITMasterSequentialCplt(FMPI2C_HandleTypeDef *hfmpi2c) | |
3867 { | |
3868 /* Reset FMPI2C handle mode */ | |
3869 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; | |
3870 | |
3871 /* No Generate Stop, to permit restart mode */ | |
3872 /* The stop will be done at the end of transfer, when FMPI2C_AUTOEND_MODE enable */ | |
3873 if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX) | |
3874 { | |
3875 hfmpi2c->State = HAL_FMPI2C_STATE_READY; | |
3876 hfmpi2c->PreviousState = FMPI2C_STATE_MASTER_BUSY_TX; | |
3877 hfmpi2c->XferISR = NULL; | |
3878 | |
3879 /* Disable Interrupts */ | |
3880 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT); | |
3881 | |
3882 /* Process Unlocked */ | |
3883 __HAL_UNLOCK(hfmpi2c); | |
3884 | |
3885 /* Call the corresponding callback to inform upper layer of End of Transfer */ | |
3886 HAL_FMPI2C_MasterTxCpltCallback(hfmpi2c); | |
3887 } | |
3888 /* hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX */ | |
3889 else | |
3890 { | |
3891 hfmpi2c->State = HAL_FMPI2C_STATE_READY; | |
3892 hfmpi2c->PreviousState = FMPI2C_STATE_MASTER_BUSY_RX; | |
3893 hfmpi2c->XferISR = NULL; | |
3894 | |
3895 /* Disable Interrupts */ | |
3896 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT); | |
3897 | |
3898 /* Process Unlocked */ | |
3899 __HAL_UNLOCK(hfmpi2c); | |
3900 | |
3901 /* Call the corresponding callback to inform upper layer of End of Transfer */ | |
3902 HAL_FMPI2C_MasterRxCpltCallback(hfmpi2c); | |
3903 } | |
3904 } | |
3905 | |
3906 /** | |
3907 * @brief FMPI2C Slave sequential complete process. | |
3908 * @param hfmpi2c FMPI2C handle. | |
3909 * @retval None | |
3910 */ | |
3911 static void FMPI2C_ITSlaveSequentialCplt(FMPI2C_HandleTypeDef *hfmpi2c) | |
3912 { | |
3913 /* Reset FMPI2C handle mode */ | |
3914 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; | |
3915 | |
3916 if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX_LISTEN) | |
3917 { | |
3918 /* Remove HAL_FMPI2C_STATE_SLAVE_BUSY_TX, keep only HAL_FMPI2C_STATE_LISTEN */ | |
3919 hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN; | |
3920 hfmpi2c->PreviousState = FMPI2C_STATE_SLAVE_BUSY_TX; | |
3921 | |
3922 /* Disable Interrupts */ | |
3923 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT); | |
3924 | |
3925 /* Process Unlocked */ | |
3926 __HAL_UNLOCK(hfmpi2c); | |
3927 | |
3928 /* Call the Tx complete callback to inform upper layer of the end of transmit process */ | |
3929 HAL_FMPI2C_SlaveTxCpltCallback(hfmpi2c); | |
3930 } | |
3931 | |
3932 else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX_LISTEN) | |
3933 { | |
3934 /* Remove HAL_FMPI2C_STATE_SLAVE_BUSY_RX, keep only HAL_FMPI2C_STATE_LISTEN */ | |
3935 hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN; | |
3936 hfmpi2c->PreviousState = FMPI2C_STATE_SLAVE_BUSY_RX; | |
3937 | |
3938 /* Disable Interrupts */ | |
3939 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT); | |
3940 | |
3941 /* Process Unlocked */ | |
3942 __HAL_UNLOCK(hfmpi2c); | |
3943 | |
3944 /* Call the Rx complete callback to inform upper layer of the end of receive process */ | |
3945 HAL_FMPI2C_SlaveRxCpltCallback(hfmpi2c); | |
3946 } | |
3947 } | |
3948 | |
3949 /** | |
3950 * @brief FMPI2C Master complete process. | |
3951 * @param hfmpi2c FMPI2C handle. | |
3952 * @param ITFlags Interrupt flags to handle. | |
3953 * @retval None | |
3954 */ | |
3955 static void FMPI2C_ITMasterCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags) | |
3956 { | |
3957 /* Clear STOP Flag */ | |
3958 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); | |
3959 | |
3960 /* Clear Configuration Register 2 */ | |
3961 FMPI2C_RESET_CR2(hfmpi2c); | |
3962 | |
3963 /* Reset handle parameters */ | |
3964 hfmpi2c->PreviousState = FMPI2C_STATE_NONE; | |
3965 hfmpi2c->XferISR = NULL; | |
3966 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; | |
3967 | |
3968 if ((ITFlags & FMPI2C_FLAG_AF) != RESET) | |
3969 { | |
3970 /* Clear NACK Flag */ | |
3971 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF); | |
3972 | |
3973 /* Set acknowledge error code */ | |
3974 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF; | |
3975 } | |
3976 | |
3977 /* Flush TX register */ | |
3978 FMPI2C_Flush_TXDR(hfmpi2c); | |
3979 | |
3980 /* Disable Interrupts */ | |
3981 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT | FMPI2C_XFER_RX_IT); | |
3982 | |
3983 /* Call the corresponding callback to inform upper layer of End of Transfer */ | |
3984 if ((hfmpi2c->ErrorCode != HAL_FMPI2C_ERROR_NONE) || (hfmpi2c->State == HAL_FMPI2C_STATE_ABORT)) | |
3985 { | |
3986 /* Call the corresponding callback to inform upper layer of End of Transfer */ | |
3987 FMPI2C_ITError(hfmpi2c, hfmpi2c->ErrorCode); | |
3988 } | |
3989 /* hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX */ | |
3990 else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX) | |
3991 { | |
3992 hfmpi2c->State = HAL_FMPI2C_STATE_READY; | |
3993 | |
3994 if (hfmpi2c->Mode == HAL_FMPI2C_MODE_MEM) | |
3995 { | |
3996 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; | |
3997 | |
3998 /* Process Unlocked */ | |
3999 __HAL_UNLOCK(hfmpi2c); | |
4000 | |
4001 /* Call the corresponding callback to inform upper layer of End of Transfer */ | |
4002 HAL_FMPI2C_MemTxCpltCallback(hfmpi2c); | |
4003 } | |
4004 else | |
4005 { | |
4006 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; | |
4007 | |
4008 /* Process Unlocked */ | |
4009 __HAL_UNLOCK(hfmpi2c); | |
4010 | |
4011 /* Call the corresponding callback to inform upper layer of End of Transfer */ | |
4012 HAL_FMPI2C_MasterTxCpltCallback(hfmpi2c); | |
4013 } | |
4014 } | |
4015 /* hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX */ | |
4016 else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX) | |
4017 { | |
4018 hfmpi2c->State = HAL_FMPI2C_STATE_READY; | |
4019 | |
4020 if (hfmpi2c->Mode == HAL_FMPI2C_MODE_MEM) | |
4021 { | |
4022 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; | |
4023 | |
4024 /* Process Unlocked */ | |
4025 __HAL_UNLOCK(hfmpi2c); | |
4026 | |
4027 HAL_FMPI2C_MemRxCpltCallback(hfmpi2c); | |
4028 } | |
4029 else | |
4030 { | |
4031 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; | |
4032 | |
4033 /* Process Unlocked */ | |
4034 __HAL_UNLOCK(hfmpi2c); | |
4035 | |
4036 HAL_FMPI2C_MasterRxCpltCallback(hfmpi2c); | |
4037 } | |
4038 } | |
4039 } | |
4040 | |
4041 /** | |
4042 * @brief FMPI2C Slave complete process. | |
4043 * @param hfmpi2c FMPI2C handle. | |
4044 * @param ITFlags Interrupt flags to handle. | |
4045 * @retval None | |
4046 */ | |
4047 static void FMPI2C_ITSlaveCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags) | |
4048 { | |
4049 /* Clear STOP Flag */ | |
4050 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); | |
4051 | |
4052 /* Clear ADDR flag */ | |
4053 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR); | |
4054 | |
4055 /* Disable all interrupts */ | |
4056 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_TX_IT | FMPI2C_XFER_RX_IT); | |
4057 | |
4058 /* Disable Address Acknowledge */ | |
4059 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; | |
4060 | |
4061 /* Clear Configuration Register 2 */ | |
4062 FMPI2C_RESET_CR2(hfmpi2c); | |
4063 | |
4064 /* Flush TX register */ | |
4065 FMPI2C_Flush_TXDR(hfmpi2c); | |
4066 | |
4067 /* If a DMA is ongoing, Update handle size context */ | |
4068 if (((hfmpi2c->Instance->CR1 & FMPI2C_CR1_TXDMAEN) == FMPI2C_CR1_TXDMAEN) || | |
4069 ((hfmpi2c->Instance->CR1 & FMPI2C_CR1_RXDMAEN) == FMPI2C_CR1_RXDMAEN)) | |
4070 { | |
4071 hfmpi2c->XferCount = FMPI2C_GET_DMA_REMAIN_DATA(hfmpi2c); | |
4072 } | |
4073 | |
4074 /* All data are not transferred, so set error code accordingly */ | |
4075 if (hfmpi2c->XferCount != 0U) | |
4076 { | |
4077 /* Set ErrorCode corresponding to a Non-Acknowledge */ | |
4078 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF; | |
4079 } | |
4080 | |
4081 /* Store Last receive data if any */ | |
4082 if (((ITFlags & FMPI2C_FLAG_RXNE) != RESET)) | |
4083 { | |
4084 /* Read data from RXDR */ | |
4085 (*hfmpi2c->pBuffPtr++) = hfmpi2c->Instance->RXDR; | |
4086 | |
4087 if ((hfmpi2c->XferSize > 0U)) | |
4088 { | |
4089 hfmpi2c->XferSize--; | |
4090 hfmpi2c->XferCount--; | |
4091 | |
4092 /* Set ErrorCode corresponding to a Non-Acknowledge */ | |
4093 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF; | |
4094 } | |
4095 } | |
4096 | |
4097 hfmpi2c->PreviousState = FMPI2C_STATE_NONE; | |
4098 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; | |
4099 hfmpi2c->XferISR = NULL; | |
4100 | |
4101 if (hfmpi2c->ErrorCode != HAL_FMPI2C_ERROR_NONE) | |
4102 { | |
4103 /* Call the corresponding callback to inform upper layer of End of Transfer */ | |
4104 FMPI2C_ITError(hfmpi2c, hfmpi2c->ErrorCode); | |
4105 | |
4106 /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */ | |
4107 if (hfmpi2c->State == HAL_FMPI2C_STATE_LISTEN) | |
4108 { | |
4109 /* Call FMPI2C Listen complete process */ | |
4110 FMPI2C_ITListenCplt(hfmpi2c, ITFlags); | |
4111 } | |
4112 } | |
4113 else if (hfmpi2c->XferOptions != FMPI2C_NO_OPTION_FRAME) | |
4114 { | |
4115 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; | |
4116 hfmpi2c->State = HAL_FMPI2C_STATE_READY; | |
4117 | |
4118 /* Process Unlocked */ | |
4119 __HAL_UNLOCK(hfmpi2c); | |
4120 | |
4121 /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */ | |
4122 HAL_FMPI2C_ListenCpltCallback(hfmpi2c); | |
4123 } | |
4124 /* Call the corresponding callback to inform upper layer of End of Transfer */ | |
4125 else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX) | |
4126 { | |
4127 hfmpi2c->State = HAL_FMPI2C_STATE_READY; | |
4128 | |
4129 /* Process Unlocked */ | |
4130 __HAL_UNLOCK(hfmpi2c); | |
4131 | |
4132 /* Call the Slave Rx Complete callback */ | |
4133 HAL_FMPI2C_SlaveRxCpltCallback(hfmpi2c); | |
4134 } | |
4135 else | |
4136 { | |
4137 hfmpi2c->State = HAL_FMPI2C_STATE_READY; | |
4138 | |
4139 /* Process Unlocked */ | |
4140 __HAL_UNLOCK(hfmpi2c); | |
4141 | |
4142 /* Call the Slave Tx Complete callback */ | |
4143 HAL_FMPI2C_SlaveTxCpltCallback(hfmpi2c); | |
4144 } | |
4145 } | |
4146 | |
4147 /** | |
4148 * @brief FMPI2C Listen complete process. | |
4149 * @param hfmpi2c FMPI2C handle. | |
4150 * @param ITFlags Interrupt flags to handle. | |
4151 * @retval None | |
4152 */ | |
4153 static void FMPI2C_ITListenCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags) | |
4154 { | |
4155 /* Reset handle parameters */ | |
4156 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; | |
4157 hfmpi2c->PreviousState = FMPI2C_STATE_NONE; | |
4158 hfmpi2c->State = HAL_FMPI2C_STATE_READY; | |
4159 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; | |
4160 hfmpi2c->XferISR = NULL; | |
4161 | |
4162 /* Store Last receive data if any */ | |
4163 if (((ITFlags & FMPI2C_FLAG_RXNE) != RESET)) | |
4164 { | |
4165 /* Read data from RXDR */ | |
4166 (*hfmpi2c->pBuffPtr++) = hfmpi2c->Instance->RXDR; | |
4167 | |
4168 if ((hfmpi2c->XferSize > 0U)) | |
4169 { | |
4170 hfmpi2c->XferSize--; | |
4171 hfmpi2c->XferCount--; | |
4172 | |
4173 /* Set ErrorCode corresponding to a Non-Acknowledge */ | |
4174 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF; | |
4175 } | |
4176 } | |
4177 | |
4178 /* Disable all Interrupts*/ | |
4179 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_RX_IT | FMPI2C_XFER_TX_IT); | |
4180 | |
4181 /* Clear NACK Flag */ | |
4182 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF); | |
4183 | |
4184 /* Process Unlocked */ | |
4185 __HAL_UNLOCK(hfmpi2c); | |
4186 | |
4187 /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */ | |
4188 HAL_FMPI2C_ListenCpltCallback(hfmpi2c); | |
4189 } | |
4190 | |
4191 /** | |
4192 * @brief FMPI2C interrupts error process. | |
4193 * @param hfmpi2c FMPI2C handle. | |
4194 * @param ErrorCode Error code to handle. | |
4195 * @retval None | |
4196 */ | |
4197 static void FMPI2C_ITError(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ErrorCode) | |
4198 { | |
4199 /* Reset handle parameters */ | |
4200 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; | |
4201 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; | |
4202 hfmpi2c->XferCount = 0U; | |
4203 | |
4204 /* Set new error code */ | |
4205 hfmpi2c->ErrorCode |= ErrorCode; | |
4206 | |
4207 /* Disable Interrupts */ | |
4208 if ((hfmpi2c->State == HAL_FMPI2C_STATE_LISTEN) || | |
4209 (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX_LISTEN) || | |
4210 (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX_LISTEN)) | |
4211 { | |
4212 /* Disable all interrupts, except interrupts related to LISTEN state */ | |
4213 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT | FMPI2C_XFER_TX_IT); | |
4214 | |
4215 /* keep HAL_FMPI2C_STATE_LISTEN if set */ | |
4216 hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN; | |
4217 hfmpi2c->PreviousState = FMPI2C_STATE_NONE; | |
4218 hfmpi2c->XferISR = FMPI2C_Slave_ISR_IT; | |
4219 } | |
4220 else | |
4221 { | |
4222 /* Disable all interrupts */ | |
4223 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_RX_IT | FMPI2C_XFER_TX_IT); | |
4224 | |
4225 /* If state is an abort treatment on goind, don't change state */ | |
4226 /* This change will be do later */ | |
4227 if (hfmpi2c->State != HAL_FMPI2C_STATE_ABORT) | |
4228 { | |
4229 /* Set HAL_FMPI2C_STATE_READY */ | |
4230 hfmpi2c->State = HAL_FMPI2C_STATE_READY; | |
4231 } | |
4232 hfmpi2c->PreviousState = FMPI2C_STATE_NONE; | |
4233 hfmpi2c->XferISR = NULL; | |
4234 } | |
4235 | |
4236 /* Abort DMA TX transfer if any */ | |
4237 if ((hfmpi2c->Instance->CR1 & FMPI2C_CR1_TXDMAEN) == FMPI2C_CR1_TXDMAEN) | |
4238 { | |
4239 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN; | |
4240 | |
4241 /* Set the FMPI2C DMA Abort callback : | |
4242 will lead to call HAL_FMPI2C_ErrorCallback() at end of DMA abort procedure */ | |
4243 hfmpi2c->hdmatx->XferAbortCallback = FMPI2C_DMAAbort; | |
4244 | |
4245 /* Process Unlocked */ | |
4246 __HAL_UNLOCK(hfmpi2c); | |
4247 | |
4248 /* Abort DMA TX */ | |
4249 if (HAL_DMA_Abort_IT(hfmpi2c->hdmatx) != HAL_OK) | |
4250 { | |
4251 /* Call Directly XferAbortCallback function in case of error */ | |
4252 hfmpi2c->hdmatx->XferAbortCallback(hfmpi2c->hdmatx); | |
4253 } | |
4254 } | |
4255 /* Abort DMA RX transfer if any */ | |
4256 else if ((hfmpi2c->Instance->CR1 & FMPI2C_CR1_RXDMAEN) == FMPI2C_CR1_RXDMAEN) | |
4257 { | |
4258 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN; | |
4259 | |
4260 /* Set the FMPI2C DMA Abort callback : | |
4261 will lead to call HAL_FMPI2C_ErrorCallback() at end of DMA abort procedure */ | |
4262 hfmpi2c->hdmarx->XferAbortCallback = FMPI2C_DMAAbort; | |
4263 | |
4264 /* Process Unlocked */ | |
4265 __HAL_UNLOCK(hfmpi2c); | |
4266 | |
4267 /* Abort DMA RX */ | |
4268 if (HAL_DMA_Abort_IT(hfmpi2c->hdmarx) != HAL_OK) | |
4269 { | |
4270 /* Call Directly hfmpi2c->hdmarx->XferAbortCallback function in case of error */ | |
4271 hfmpi2c->hdmarx->XferAbortCallback(hfmpi2c->hdmarx); | |
4272 } | |
4273 } | |
4274 else if (hfmpi2c->State == HAL_FMPI2C_STATE_ABORT) | |
4275 { | |
4276 hfmpi2c->State = HAL_FMPI2C_STATE_READY; | |
4277 | |
4278 /* Process Unlocked */ | |
4279 __HAL_UNLOCK(hfmpi2c); | |
4280 | |
4281 /* Call the corresponding callback to inform upper layer of End of Transfer */ | |
4282 HAL_FMPI2C_AbortCpltCallback(hfmpi2c); | |
4283 } | |
4284 else | |
4285 { | |
4286 /* Process Unlocked */ | |
4287 __HAL_UNLOCK(hfmpi2c); | |
4288 | |
4289 /* Call the corresponding callback to inform upper layer of End of Transfer */ | |
4290 HAL_FMPI2C_ErrorCallback(hfmpi2c); | |
4291 } | |
4292 } | |
4293 | |
4294 /** | |
4295 * @brief FMPI2C Tx data register flush process. | |
4296 * @param hfmpi2c FMPI2C handle. | |
4297 * @retval None | |
4298 */ | |
4299 static void FMPI2C_Flush_TXDR(FMPI2C_HandleTypeDef *hfmpi2c) | |
4300 { | |
4301 /* If a pending TXIS flag is set */ | |
4302 /* Write a dummy data in TXDR to clear it */ | |
4303 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TXIS) != RESET) | |
4304 { | |
4305 hfmpi2c->Instance->TXDR = 0x00U; | |
4306 } | |
4307 | |
4308 /* Flush TX register if not empty */ | |
4309 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TXE) == RESET) | |
4310 { | |
4311 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_TXE); | |
4312 } | |
4313 } | |
4314 | |
4315 /** | |
4316 * @brief DMA FMPI2C master transmit process complete callback. | |
4317 * @param hdma DMA handle | |
4318 * @retval None | |
4319 */ | |
4320 static void FMPI2C_DMAMasterTransmitCplt(DMA_HandleTypeDef *hdma) | |
4321 { | |
4322 FMPI2C_HandleTypeDef *hfmpi2c = (FMPI2C_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; | |
4323 | |
4324 /* Disable DMA Request */ | |
4325 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN; | |
4326 | |
4327 /* If last transfer, enable STOP interrupt */ | |
4328 if (hfmpi2c->XferCount == 0U) | |
4329 { | |
4330 /* Enable STOP interrupt */ | |
4331 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_CPLT_IT); | |
4332 } | |
4333 /* else prepare a new DMA transfer and enable TCReload interrupt */ | |
4334 else | |
4335 { | |
4336 /* Update Buffer pointer */ | |
4337 hfmpi2c->pBuffPtr += hfmpi2c->XferSize; | |
4338 | |
4339 /* Set the XferSize to transfer */ | |
4340 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) | |
4341 { | |
4342 hfmpi2c->XferSize = MAX_NBYTE_SIZE; | |
4343 } | |
4344 else | |
4345 { | |
4346 hfmpi2c->XferSize = hfmpi2c->XferCount; | |
4347 } | |
4348 | |
4349 /* Enable the DMA stream */ | |
4350 HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)hfmpi2c->pBuffPtr, (uint32_t)&hfmpi2c->Instance->TXDR, hfmpi2c->XferSize); | |
4351 | |
4352 /* Enable TC interrupts */ | |
4353 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RELOAD_IT); | |
4354 } | |
4355 } | |
4356 | |
4357 /** | |
4358 * @brief DMA FMPI2C slave transmit process complete callback. | |
4359 * @param hdma DMA handle | |
4360 * @retval None | |
4361 */ | |
4362 static void FMPI2C_DMASlaveTransmitCplt(DMA_HandleTypeDef *hdma) | |
4363 { | |
4364 /* Prevent unused argument(s) compilation warning */ | |
4365 UNUSED(hdma); | |
4366 | |
4367 /* No specific action, Master fully manage the generation of STOP condition */ | |
4368 /* Mean that this generation can arrive at any time, at the end or during DMA process */ | |
4369 /* So STOP condition should be manage through Interrupt treatment */ | |
4370 } | |
4371 | |
4372 /** | |
4373 * @brief DMA FMPI2C master receive process complete callback. | |
4374 * @param hdma DMA handle | |
4375 * @retval None | |
4376 */ | |
4377 static void FMPI2C_DMAMasterReceiveCplt(DMA_HandleTypeDef *hdma) | |
4378 { | |
4379 FMPI2C_HandleTypeDef *hfmpi2c = (FMPI2C_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; | |
4380 | |
4381 /* Disable DMA Request */ | |
4382 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN; | |
4383 | |
4384 /* If last transfer, enable STOP interrupt */ | |
4385 if (hfmpi2c->XferCount == 0U) | |
4386 { | |
4387 /* Enable STOP interrupt */ | |
4388 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_CPLT_IT); | |
4389 } | |
4390 /* else prepare a new DMA transfer and enable TCReload interrupt */ | |
4391 else | |
4392 { | |
4393 /* Update Buffer pointer */ | |
4394 hfmpi2c->pBuffPtr += hfmpi2c->XferSize; | |
4395 | |
4396 /* Set the XferSize to transfer */ | |
4397 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) | |
4398 { | |
4399 hfmpi2c->XferSize = MAX_NBYTE_SIZE; | |
4400 } | |
4401 else | |
4402 { | |
4403 hfmpi2c->XferSize = hfmpi2c->XferCount; | |
4404 } | |
4405 | |
4406 /* Enable the DMA stream */ | |
4407 HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR, (uint32_t)hfmpi2c->pBuffPtr, hfmpi2c->XferSize); | |
4408 | |
4409 /* Enable TC interrupts */ | |
4410 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RELOAD_IT); | |
4411 } | |
4412 } | |
4413 | |
4414 /** | |
4415 * @brief DMA FMPI2C slave receive process complete callback. | |
4416 * @param hdma DMA handle | |
4417 * @retval None | |
4418 */ | |
4419 static void FMPI2C_DMASlaveReceiveCplt(DMA_HandleTypeDef *hdma) | |
4420 { | |
4421 /* Prevent unused argument(s) compilation warning */ | |
4422 UNUSED(hdma); | |
4423 | |
4424 /* No specific action, Master fully manage the generation of STOP condition */ | |
4425 /* Mean that this generation can arrive at any time, at the end or during DMA process */ | |
4426 /* So STOP condition should be manage through Interrupt treatment */ | |
4427 } | |
4428 | |
4429 /** | |
4430 * @brief DMA FMPI2C communication error callback. | |
4431 * @param hdma DMA handle | |
4432 * @retval None | |
4433 */ | |
4434 static void FMPI2C_DMAError(DMA_HandleTypeDef *hdma) | |
4435 { | |
4436 FMPI2C_HandleTypeDef *hfmpi2c = (FMPI2C_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; | |
4437 | |
4438 /* Disable Acknowledge */ | |
4439 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; | |
4440 | |
4441 /* Call the corresponding callback to inform upper layer of End of Transfer */ | |
4442 FMPI2C_ITError(hfmpi2c, HAL_FMPI2C_ERROR_DMA); | |
4443 } | |
4444 | |
4445 /** | |
4446 * @brief DMA FMPI2C communication abort callback | |
4447 * (To be called at end of DMA Abort procedure). | |
4448 * @param hdma DMA handle. | |
4449 * @retval None | |
4450 */ | |
4451 static void FMPI2C_DMAAbort(DMA_HandleTypeDef *hdma) | |
4452 { | |
4453 FMPI2C_HandleTypeDef *hfmpi2c = (FMPI2C_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; | |
4454 | |
4455 /* Disable Acknowledge */ | |
4456 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; | |
4457 | |
4458 /* Reset AbortCpltCallback */ | |
4459 hfmpi2c->hdmatx->XferAbortCallback = NULL; | |
4460 hfmpi2c->hdmarx->XferAbortCallback = NULL; | |
4461 | |
4462 /* Check if come from abort from user */ | |
4463 if (hfmpi2c->State == HAL_FMPI2C_STATE_ABORT) | |
4464 { | |
4465 hfmpi2c->State = HAL_FMPI2C_STATE_READY; | |
4466 | |
4467 /* Call the corresponding callback to inform upper layer of End of Transfer */ | |
4468 HAL_FMPI2C_AbortCpltCallback(hfmpi2c); | |
4469 } | |
4470 else | |
4471 { | |
4472 /* Call the corresponding callback to inform upper layer of End of Transfer */ | |
4473 HAL_FMPI2C_ErrorCallback(hfmpi2c); | |
4474 } | |
4475 } | |
4476 | |
4477 /** | |
4478 * @brief This function handles FMPI2C Communication Timeout. | |
4479 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
4480 * the configuration information for the specified FMPI2C. | |
4481 * @param Flag Specifies the FMPI2C flag to check. | |
4482 * @param Status The new Flag status (SET or RESET). | |
4483 * @param Timeout Timeout duration | |
4484 * @param Tickstart Tick start value | |
4485 * @retval HAL status | |
4486 */ | |
4487 static HAL_StatusTypeDef FMPI2C_WaitOnFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t Tickstart) | |
4488 { | |
4489 while (__HAL_FMPI2C_GET_FLAG(hfmpi2c, Flag) == Status) | |
4490 { | |
4491 /* Check for the Timeout */ | |
4492 if (Timeout != HAL_MAX_DELAY) | |
4493 { | |
4494 if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout)) | |
4495 { | |
4496 hfmpi2c->State = HAL_FMPI2C_STATE_READY; | |
4497 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; | |
4498 | |
4499 /* Process Unlocked */ | |
4500 __HAL_UNLOCK(hfmpi2c); | |
4501 return HAL_TIMEOUT; | |
4502 } | |
4503 } | |
4504 } | |
4505 return HAL_OK; | |
4506 } | |
4507 | |
4508 /** | |
4509 * @brief This function handles FMPI2C Communication Timeout for specific usage of TXIS flag. | |
4510 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
4511 * the configuration information for the specified FMPI2C. | |
4512 * @param Timeout Timeout duration | |
4513 * @param Tickstart Tick start value | |
4514 * @retval HAL status | |
4515 */ | |
4516 static HAL_StatusTypeDef FMPI2C_WaitOnTXISFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout, uint32_t Tickstart) | |
4517 { | |
4518 while (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TXIS) == RESET) | |
4519 { | |
4520 /* Check if a NACK is detected */ | |
4521 if (FMPI2C_IsAcknowledgeFailed(hfmpi2c, Timeout, Tickstart) != HAL_OK) | |
4522 { | |
4523 return HAL_ERROR; | |
4524 } | |
4525 | |
4526 /* Check for the Timeout */ | |
4527 if (Timeout != HAL_MAX_DELAY) | |
4528 { | |
4529 if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout)) | |
4530 { | |
4531 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT; | |
4532 hfmpi2c->State = HAL_FMPI2C_STATE_READY; | |
4533 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; | |
4534 | |
4535 /* Process Unlocked */ | |
4536 __HAL_UNLOCK(hfmpi2c); | |
4537 | |
4538 return HAL_TIMEOUT; | |
4539 } | |
4540 } | |
4541 } | |
4542 return HAL_OK; | |
4543 } | |
4544 | |
4545 /** | |
4546 * @brief This function handles FMPI2C Communication Timeout for specific usage of STOP flag. | |
4547 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
4548 * the configuration information for the specified FMPI2C. | |
4549 * @param Timeout Timeout duration | |
4550 * @param Tickstart Tick start value | |
4551 * @retval HAL status | |
4552 */ | |
4553 static HAL_StatusTypeDef FMPI2C_WaitOnSTOPFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout, uint32_t Tickstart) | |
4554 { | |
4555 while (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == RESET) | |
4556 { | |
4557 /* Check if a NACK is detected */ | |
4558 if (FMPI2C_IsAcknowledgeFailed(hfmpi2c, Timeout, Tickstart) != HAL_OK) | |
4559 { | |
4560 return HAL_ERROR; | |
4561 } | |
4562 | |
4563 /* Check for the Timeout */ | |
4564 if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout)) | |
4565 { | |
4566 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT; | |
4567 hfmpi2c->State = HAL_FMPI2C_STATE_READY; | |
4568 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; | |
4569 | |
4570 /* Process Unlocked */ | |
4571 __HAL_UNLOCK(hfmpi2c); | |
4572 | |
4573 return HAL_TIMEOUT; | |
4574 } | |
4575 } | |
4576 return HAL_OK; | |
4577 } | |
4578 | |
4579 /** | |
4580 * @brief This function handles FMPI2C Communication Timeout for specific usage of RXNE flag. | |
4581 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
4582 * the configuration information for the specified FMPI2C. | |
4583 * @param Timeout Timeout duration | |
4584 * @param Tickstart Tick start value | |
4585 * @retval HAL status | |
4586 */ | |
4587 static HAL_StatusTypeDef FMPI2C_WaitOnRXNEFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout, uint32_t Tickstart) | |
4588 { | |
4589 while (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_RXNE) == RESET) | |
4590 { | |
4591 /* Check if a NACK is detected */ | |
4592 if (FMPI2C_IsAcknowledgeFailed(hfmpi2c, Timeout, Tickstart) != HAL_OK) | |
4593 { | |
4594 return HAL_ERROR; | |
4595 } | |
4596 | |
4597 /* Check if a STOPF is detected */ | |
4598 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == SET) | |
4599 { | |
4600 /* Check if an RXNE is pending */ | |
4601 /* Store Last receive data if any */ | |
4602 if ((__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_RXNE) == SET) && (hfmpi2c->XferSize > 0U)) | |
4603 { | |
4604 /* Return HAL_OK */ | |
4605 /* The Reading of data from RXDR will be done in caller function */ | |
4606 return HAL_OK; | |
4607 } | |
4608 else | |
4609 { | |
4610 /* Clear STOP Flag */ | |
4611 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); | |
4612 | |
4613 /* Clear Configuration Register 2 */ | |
4614 FMPI2C_RESET_CR2(hfmpi2c); | |
4615 | |
4616 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; | |
4617 hfmpi2c->State = HAL_FMPI2C_STATE_READY; | |
4618 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; | |
4619 | |
4620 /* Process Unlocked */ | |
4621 __HAL_UNLOCK(hfmpi2c); | |
4622 | |
4623 return HAL_ERROR; | |
4624 } | |
4625 } | |
4626 | |
4627 /* Check for the Timeout */ | |
4628 if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout)) | |
4629 { | |
4630 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT; | |
4631 hfmpi2c->State = HAL_FMPI2C_STATE_READY; | |
4632 | |
4633 /* Process Unlocked */ | |
4634 __HAL_UNLOCK(hfmpi2c); | |
4635 | |
4636 return HAL_TIMEOUT; | |
4637 } | |
4638 } | |
4639 return HAL_OK; | |
4640 } | |
4641 | |
4642 /** | |
4643 * @brief This function handles Acknowledge failed detection during an FMPI2C Communication. | |
4644 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
4645 * the configuration information for the specified FMPI2C. | |
4646 * @param Timeout Timeout duration | |
4647 * @param Tickstart Tick start value | |
4648 * @retval HAL status | |
4649 */ | |
4650 static HAL_StatusTypeDef FMPI2C_IsAcknowledgeFailed(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout, uint32_t Tickstart) | |
4651 { | |
4652 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF) == SET) | |
4653 { | |
4654 /* Wait until STOP Flag is reset */ | |
4655 /* AutoEnd should be initiate after AF */ | |
4656 while (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == RESET) | |
4657 { | |
4658 /* Check for the Timeout */ | |
4659 if (Timeout != HAL_MAX_DELAY) | |
4660 { | |
4661 if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout)) | |
4662 { | |
4663 hfmpi2c->State = HAL_FMPI2C_STATE_READY; | |
4664 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; | |
4665 | |
4666 /* Process Unlocked */ | |
4667 __HAL_UNLOCK(hfmpi2c); | |
4668 return HAL_TIMEOUT; | |
4669 } | |
4670 } | |
4671 } | |
4672 | |
4673 /* Clear NACKF Flag */ | |
4674 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF); | |
4675 | |
4676 /* Clear STOP Flag */ | |
4677 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); | |
4678 | |
4679 /* Flush TX register */ | |
4680 FMPI2C_Flush_TXDR(hfmpi2c); | |
4681 | |
4682 /* Clear Configuration Register 2 */ | |
4683 FMPI2C_RESET_CR2(hfmpi2c); | |
4684 | |
4685 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_AF; | |
4686 hfmpi2c->State = HAL_FMPI2C_STATE_READY; | |
4687 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; | |
4688 | |
4689 /* Process Unlocked */ | |
4690 __HAL_UNLOCK(hfmpi2c); | |
4691 | |
4692 return HAL_ERROR; | |
4693 } | |
4694 return HAL_OK; | |
4695 } | |
4696 | |
4697 /** | |
4698 * @brief Handles FMPI2Cx communication when starting transfer or during transfer (TC or TCR flag are set). | |
4699 * @param hfmpi2c FMPI2C handle. | |
4700 * @param DevAddress Specifies the slave address to be programmed. | |
4701 * @param Size Specifies the number of bytes to be programmed. | |
4702 * This parameter must be a value between 0 and 255. | |
4703 * @param Mode New state of the FMPI2C START condition generation. | |
4704 * This parameter can be one of the following values: | |
4705 * @arg @ref FMPI2C_RELOAD_MODE Enable Reload mode . | |
4706 * @arg @ref FMPI2C_AUTOEND_MODE Enable Automatic end mode. | |
4707 * @arg @ref FMPI2C_SOFTEND_MODE Enable Software end mode. | |
4708 * @param Request New state of the FMPI2C START condition generation. | |
4709 * This parameter can be one of the following values: | |
4710 * @arg @ref FMPI2C_NO_STARTSTOP Don't Generate stop and start condition. | |
4711 * @arg @ref FMPI2C_GENERATE_STOP Generate stop condition (Size should be set to 0). | |
4712 * @arg @ref FMPI2C_GENERATE_START_READ Generate Restart for read request. | |
4713 * @arg @ref FMPI2C_GENERATE_START_WRITE Generate Restart for write request. | |
4714 * @retval None | |
4715 */ | |
4716 static void FMPI2C_TransferConfig(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t Size, uint32_t Mode, uint32_t Request) | |
4717 { | |
4718 /* Check the parameters */ | |
4719 assert_param(IS_FMPI2C_ALL_INSTANCE(hfmpi2c->Instance)); | |
4720 assert_param(IS_TRANSFER_MODE(Mode)); | |
4721 assert_param(IS_TRANSFER_REQUEST(Request)); | |
4722 | |
4723 /* update CR2 register */ | |
4724 MODIFY_REG(hfmpi2c->Instance->CR2, ((FMPI2C_CR2_SADD | FMPI2C_CR2_NBYTES | FMPI2C_CR2_RELOAD | FMPI2C_CR2_AUTOEND | (FMPI2C_CR2_RD_WRN & (uint32_t)(Request >> (31U - FMPI2C_CR2_RD_WRN_Pos))) | FMPI2C_CR2_START | FMPI2C_CR2_STOP)), \ | |
4725 (uint32_t)(((uint32_t)DevAddress & FMPI2C_CR2_SADD) | (((uint32_t)Size << FMPI2C_CR2_NBYTES_Pos) & FMPI2C_CR2_NBYTES) | (uint32_t)Mode | (uint32_t)Request)); | |
4726 } | |
4727 | |
4728 /** | |
4729 * @brief Manage the enabling of Interrupts. | |
4730 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
4731 * the configuration information for the specified FMPI2C. | |
4732 * @param InterruptRequest Value of @ref FMPI2C_Interrupt_configuration_definition. | |
4733 * @retval HAL status | |
4734 */ | |
4735 static HAL_StatusTypeDef FMPI2C_Enable_IRQ(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t InterruptRequest) | |
4736 { | |
4737 uint32_t tmpisr = 0U; | |
4738 | |
4739 if ((hfmpi2c->XferISR == FMPI2C_Master_ISR_DMA) || \ | |
4740 (hfmpi2c->XferISR == FMPI2C_Slave_ISR_DMA)) | |
4741 { | |
4742 if ((InterruptRequest & FMPI2C_XFER_LISTEN_IT) == FMPI2C_XFER_LISTEN_IT) | |
4743 { | |
4744 /* Enable ERR, STOP, NACK and ADDR interrupts */ | |
4745 tmpisr |= FMPI2C_IT_ADDRI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_ERRI; | |
4746 } | |
4747 | |
4748 if ((InterruptRequest & FMPI2C_XFER_ERROR_IT) == FMPI2C_XFER_ERROR_IT) | |
4749 { | |
4750 /* Enable ERR and NACK interrupts */ | |
4751 tmpisr |= FMPI2C_IT_ERRI | FMPI2C_IT_NACKI; | |
4752 } | |
4753 | |
4754 if ((InterruptRequest & FMPI2C_XFER_CPLT_IT) == FMPI2C_XFER_CPLT_IT) | |
4755 { | |
4756 /* Enable STOP interrupts */ | |
4757 tmpisr |= FMPI2C_IT_STOPI; | |
4758 } | |
4759 | |
4760 if ((InterruptRequest & FMPI2C_XFER_RELOAD_IT) == FMPI2C_XFER_RELOAD_IT) | |
4761 { | |
4762 /* Enable TC interrupts */ | |
4763 tmpisr |= FMPI2C_IT_TCI; | |
4764 } | |
4765 } | |
4766 else | |
4767 { | |
4768 if ((InterruptRequest & FMPI2C_XFER_LISTEN_IT) == FMPI2C_XFER_LISTEN_IT) | |
4769 { | |
4770 /* Enable ERR, STOP, NACK, and ADDR interrupts */ | |
4771 tmpisr |= FMPI2C_IT_ADDRI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_ERRI; | |
4772 } | |
4773 | |
4774 if ((InterruptRequest & FMPI2C_XFER_TX_IT) == FMPI2C_XFER_TX_IT) | |
4775 { | |
4776 /* Enable ERR, TC, STOP, NACK and RXI interrupts */ | |
4777 tmpisr |= FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_TXI; | |
4778 } | |
4779 | |
4780 if ((InterruptRequest & FMPI2C_XFER_RX_IT) == FMPI2C_XFER_RX_IT) | |
4781 { | |
4782 /* Enable ERR, TC, STOP, NACK and TXI interrupts */ | |
4783 tmpisr |= FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_RXI; | |
4784 } | |
4785 | |
4786 if ((InterruptRequest & FMPI2C_XFER_CPLT_IT) == FMPI2C_XFER_CPLT_IT) | |
4787 { | |
4788 /* Enable STOP interrupts */ | |
4789 tmpisr |= FMPI2C_IT_STOPI; | |
4790 } | |
4791 } | |
4792 | |
4793 /* Enable interrupts only at the end */ | |
4794 /* to avoid the risk of FMPI2C interrupt handle execution before */ | |
4795 /* all interrupts requested done */ | |
4796 __HAL_FMPI2C_ENABLE_IT(hfmpi2c, tmpisr); | |
4797 | |
4798 return HAL_OK; | |
4799 } | |
4800 | |
4801 /** | |
4802 * @brief Manage the disabling of Interrupts. | |
4803 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains | |
4804 * the configuration information for the specified FMPI2C. | |
4805 * @param InterruptRequest Value of @ref FMPI2C_Interrupt_configuration_definition. | |
4806 * @retval HAL status | |
4807 */ | |
4808 static HAL_StatusTypeDef FMPI2C_Disable_IRQ(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t InterruptRequest) | |
4809 { | |
4810 uint32_t tmpisr = 0U; | |
4811 | |
4812 if ((InterruptRequest & FMPI2C_XFER_TX_IT) == FMPI2C_XFER_TX_IT) | |
4813 { | |
4814 /* Disable TC and TXI interrupts */ | |
4815 tmpisr |= FMPI2C_IT_TCI | FMPI2C_IT_TXI; | |
4816 | |
4817 if ((hfmpi2c->State & HAL_FMPI2C_STATE_LISTEN) != HAL_FMPI2C_STATE_LISTEN) | |
4818 { | |
4819 /* Disable NACK and STOP interrupts */ | |
4820 tmpisr |= FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_ERRI; | |
4821 } | |
4822 } | |
4823 | |
4824 if ((InterruptRequest & FMPI2C_XFER_RX_IT) == FMPI2C_XFER_RX_IT) | |
4825 { | |
4826 /* Disable TC and RXI interrupts */ | |
4827 tmpisr |= FMPI2C_IT_TCI | FMPI2C_IT_RXI; | |
4828 | |
4829 if ((hfmpi2c->State & HAL_FMPI2C_STATE_LISTEN) != HAL_FMPI2C_STATE_LISTEN) | |
4830 { | |
4831 /* Disable NACK and STOP interrupts */ | |
4832 tmpisr |= FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_ERRI; | |
4833 } | |
4834 } | |
4835 | |
4836 if ((InterruptRequest & FMPI2C_XFER_LISTEN_IT) == FMPI2C_XFER_LISTEN_IT) | |
4837 { | |
4838 /* Disable ADDR, NACK and STOP interrupts */ | |
4839 tmpisr |= FMPI2C_IT_ADDRI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_ERRI; | |
4840 } | |
4841 | |
4842 if ((InterruptRequest & FMPI2C_XFER_ERROR_IT) == FMPI2C_XFER_ERROR_IT) | |
4843 { | |
4844 /* Enable ERR and NACK interrupts */ | |
4845 tmpisr |= FMPI2C_IT_ERRI | FMPI2C_IT_NACKI; | |
4846 } | |
4847 | |
4848 if ((InterruptRequest & FMPI2C_XFER_CPLT_IT) == FMPI2C_XFER_CPLT_IT) | |
4849 { | |
4850 /* Enable STOP interrupts */ | |
4851 tmpisr |= FMPI2C_IT_STOPI; | |
4852 } | |
4853 | |
4854 if ((InterruptRequest & FMPI2C_XFER_RELOAD_IT) == FMPI2C_XFER_RELOAD_IT) | |
4855 { | |
4856 /* Enable TC interrupts */ | |
4857 tmpisr |= FMPI2C_IT_TCI; | |
4858 } | |
4859 | |
4860 /* Disable interrupts only at the end */ | |
4861 /* to avoid a breaking situation like at "t" time */ | |
4862 /* all disable interrupts request are not done */ | |
4863 __HAL_FMPI2C_DISABLE_IT(hfmpi2c, tmpisr); | |
4864 | |
4865 return HAL_OK; | |
4866 } | |
4867 | |
4868 /** | |
4869 * @} | |
4870 */ | |
4871 #endif /* STM32F410xx || STM32F446xx || STM32F412Zx || STM32F412Vx || STM32F412Rx || STM32F412Cx || STM32F413xx || STM32F423xx */ | |
4872 #endif /* HAL_FMPI2C_MODULE_ENABLED */ | |
4873 /** | |
4874 * @} | |
4875 */ | |
4876 | |
4877 /** | |
4878 * @} | |
4879 */ | |
4880 | |
4881 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |