1 /*
2 * Copyright (c) 2015, Freescale Semiconductor, Inc.
3 * Copyright 2016-2020 NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8 #ifndef _FSL_FLEXIO_I2C_MASTER_H_
9 #define _FSL_FLEXIO_I2C_MASTER_H_
10
11 #include "fsl_common.h"
12 #include "fsl_flexio.h"
13
14 /*!
15 * @addtogroup flexio_i2c_master
16 * @{
17 */
18
19 /*******************************************************************************
20 * Definitions
21 ******************************************************************************/
22
23 /*! @name Driver version */
24 /*@{*/
25 /*! @brief FlexIO I2C master driver version 2.4.0. */
26 #define FSL_FLEXIO_I2C_MASTER_DRIVER_VERSION (MAKE_VERSION(2, 4, 0))
27 /*@}*/
28
29 /*! @brief Retry times for waiting flag. */
30 #ifndef I2C_RETRY_TIMES
31 #define I2C_RETRY_TIMES 0U /* Define to zero means keep waiting until the flag is assert/deassert. */
32 #endif
33
34 /*! @brief FlexIO I2C transfer status*/
35 enum
36 {
37 kStatus_FLEXIO_I2C_Busy = MAKE_STATUS(kStatusGroup_FLEXIO_I2C, 0), /*!< I2C is busy doing transfer. */
38 kStatus_FLEXIO_I2C_Idle = MAKE_STATUS(kStatusGroup_FLEXIO_I2C, 1), /*!< I2C is busy doing transfer. */
39 kStatus_FLEXIO_I2C_Nak = MAKE_STATUS(kStatusGroup_FLEXIO_I2C, 2), /*!< NAK received during transfer. */
40 kStatus_FLEXIO_I2C_Timeout = MAKE_STATUS(kStatusGroup_FLEXIO_I2C, 3), /*!< Timeout polling status flags. */
41 };
42
43 /*! @brief Define FlexIO I2C master interrupt mask. */
44 enum _flexio_i2c_master_interrupt
45 {
46 kFLEXIO_I2C_TxEmptyInterruptEnable = 0x1U, /*!< Tx buffer empty interrupt enable. */
47 kFLEXIO_I2C_RxFullInterruptEnable = 0x2U, /*!< Rx buffer full interrupt enable. */
48 };
49
50 /*! @brief Define FlexIO I2C master status mask. */
51 enum _flexio_i2c_master_status_flags
52 {
53 kFLEXIO_I2C_TxEmptyFlag = 0x1U, /*!< Tx shifter empty flag. */
54 kFLEXIO_I2C_RxFullFlag = 0x2U, /*!< Rx shifter full/Transfer complete flag. */
55 kFLEXIO_I2C_ReceiveNakFlag = 0x4U, /*!< Receive NAK flag. */
56 };
57
58 /*! @brief Direction of master transfer.*/
59 typedef enum _flexio_i2c_direction
60 {
61 kFLEXIO_I2C_Write = 0x0U, /*!< Master send to slave. */
62 kFLEXIO_I2C_Read = 0x1U, /*!< Master receive from slave. */
63 } flexio_i2c_direction_t;
64
65 /*! @brief Define FlexIO I2C master access structure typedef. */
66 typedef struct _flexio_i2c_type
67 {
68 FLEXIO_Type *flexioBase; /*!< FlexIO base pointer. */
69 uint8_t SDAPinIndex; /*!< Pin select for I2C SDA. */
70 uint8_t SCLPinIndex; /*!< Pin select for I2C SCL. */
71 uint8_t shifterIndex[2]; /*!< Shifter index used in FlexIO I2C. */
72 uint8_t timerIndex[3]; /*!< Timer index used in FlexIO I2C. */
73 uint32_t baudrate; /*!< Master transfer baudrate, used to calculate delay time. */
74 } FLEXIO_I2C_Type;
75
76 /*! @brief Define FlexIO I2C master user configuration structure. */
77 typedef struct _flexio_i2c_master_config
78 {
79 bool enableMaster; /*!< Enables the FlexIO I2C peripheral at initialization time. */
80 bool enableInDoze; /*!< Enable/disable FlexIO operation in doze mode. */
81 bool enableInDebug; /*!< Enable/disable FlexIO operation in debug mode. */
82 bool enableFastAccess; /*!< Enable/disable fast access to FlexIO registers, fast access requires
83 the FlexIO clock to be at least twice the frequency of the bus clock. */
84 uint32_t baudRate_Bps; /*!< Baud rate in Bps. */
85 } flexio_i2c_master_config_t;
86
87 /*! @brief Define FlexIO I2C master transfer structure. */
88 typedef struct _flexio_i2c_master_transfer
89 {
90 uint32_t flags; /*!< Transfer flag which controls the transfer, reserved for FlexIO I2C. */
91 uint8_t slaveAddress; /*!< 7-bit slave address. */
92 flexio_i2c_direction_t direction; /*!< Transfer direction, read or write. */
93 uint32_t subaddress; /*!< Sub address. Transferred MSB first. */
94 uint8_t subaddressSize; /*!< Size of command buffer. */
95 uint8_t volatile *data; /*!< Transfer buffer. */
96 volatile size_t dataSize; /*!< Transfer size. */
97 } flexio_i2c_master_transfer_t;
98
99 /*! @brief FlexIO I2C master handle typedef. */
100 typedef struct _flexio_i2c_master_handle flexio_i2c_master_handle_t;
101
102 /*! @brief FlexIO I2C master transfer callback typedef. */
103 typedef void (*flexio_i2c_master_transfer_callback_t)(FLEXIO_I2C_Type *base,
104 flexio_i2c_master_handle_t *handle,
105 status_t status,
106 void *userData);
107
108 /*! @brief Define FlexIO I2C master handle structure. */
109 struct _flexio_i2c_master_handle
110 {
111 flexio_i2c_master_transfer_t transfer; /*!< FlexIO I2C master transfer copy. */
112 size_t transferSize; /*!< Total bytes to be transferred. */
113 uint8_t state; /*!< Transfer state maintained during transfer. */
114 flexio_i2c_master_transfer_callback_t completionCallback; /*!< Callback function called at transfer event. */
115 /*!< Callback function called at transfer event. */
116 void *userData; /*!< Callback parameter passed to callback function. */
117 bool needRestart; /*!< Whether master needs to send re-start signal. */
118 };
119
120 /*******************************************************************************
121 * API
122 ******************************************************************************/
123
124 #if defined(__cplusplus)
125 extern "C" {
126 #endif /*_cplusplus*/
127
128 /*!
129 * @name Initialization and deinitialization
130 * @{
131 */
132
133 #if defined(FSL_FEATURE_FLEXIO_HAS_PIN_STATUS) && FSL_FEATURE_FLEXIO_HAS_PIN_STATUS
134 /*!
135 * @brief Make sure the bus isn't already pulled down.
136 *
137 * Check the FLEXIO pin status to see whether either of SDA and SCL pin is pulled down.
138 *
139 * @param base Pointer to FLEXIO_I2C_Type structure..
140 * @retval kStatus_Success
141 * @retval kStatus_FLEXIO_I2C_Busy
142 */
143 status_t FLEXIO_I2C_CheckForBusyBus(FLEXIO_I2C_Type *base);
144 #endif /*FSL_FEATURE_FLEXIO_HAS_PIN_STATUS*/
145
146 /*!
147 * @brief Ungates the FlexIO clock, resets the FlexIO module, and configures the FlexIO I2C
148 * hardware configuration.
149 *
150 * Example
151 @code
152 FLEXIO_I2C_Type base = {
153 .flexioBase = FLEXIO,
154 .SDAPinIndex = 0,
155 .SCLPinIndex = 1,
156 .shifterIndex = {0,1},
157 .timerIndex = {0,1}
158 };
159 flexio_i2c_master_config_t config = {
160 .enableInDoze = false,
161 .enableInDebug = true,
162 .enableFastAccess = false,
163 .baudRate_Bps = 100000
164 };
165 FLEXIO_I2C_MasterInit(base, &config, srcClock_Hz);
166 @endcode
167 *
168 * @param base Pointer to FLEXIO_I2C_Type structure.
169 * @param masterConfig Pointer to flexio_i2c_master_config_t structure.
170 * @param srcClock_Hz FlexIO source clock in Hz.
171 * @retval kStatus_Success Initialization successful
172 * @retval kStatus_InvalidArgument The source clock exceed upper range limitation
173 */
174 status_t FLEXIO_I2C_MasterInit(FLEXIO_I2C_Type *base, flexio_i2c_master_config_t *masterConfig, uint32_t srcClock_Hz);
175
176 /*!
177 * @brief De-initializes the FlexIO I2C master peripheral. Calling this API Resets the FlexIO I2C master
178 * shifer and timer config, module can't work unless the FLEXIO_I2C_MasterInit is called.
179 *
180 * @param base pointer to FLEXIO_I2C_Type structure.
181 */
182 void FLEXIO_I2C_MasterDeinit(FLEXIO_I2C_Type *base);
183
184 /*!
185 * @brief Gets the default configuration to configure the FlexIO module. The configuration
186 * can be used directly for calling the FLEXIO_I2C_MasterInit().
187 *
188 * Example:
189 @code
190 flexio_i2c_master_config_t config;
191 FLEXIO_I2C_MasterGetDefaultConfig(&config);
192 @endcode
193 * @param masterConfig Pointer to flexio_i2c_master_config_t structure.
194 */
195 void FLEXIO_I2C_MasterGetDefaultConfig(flexio_i2c_master_config_t *masterConfig);
196
197 /*!
198 * @brief Enables/disables the FlexIO module operation.
199 *
200 * @param base Pointer to FLEXIO_I2C_Type structure.
201 * @param enable Pass true to enable module, false does not have any effect.
202 */
FLEXIO_I2C_MasterEnable(FLEXIO_I2C_Type * base,bool enable)203 static inline void FLEXIO_I2C_MasterEnable(FLEXIO_I2C_Type *base, bool enable)
204 {
205 if (enable)
206 {
207 base->flexioBase->CTRL |= FLEXIO_CTRL_FLEXEN_MASK;
208 }
209 }
210
211 /* @} */
212
213 /*!
214 * @name Status
215 * @{
216 */
217
218 /*!
219 * @brief Gets the FlexIO I2C master status flags.
220 *
221 * @param base Pointer to FLEXIO_I2C_Type structure
222 * @return Status flag, use status flag to AND #_flexio_i2c_master_status_flags can get the related status.
223 */
224
225 uint32_t FLEXIO_I2C_MasterGetStatusFlags(FLEXIO_I2C_Type *base);
226
227 /*!
228 * @brief Clears the FlexIO I2C master status flags.
229 *
230 * @param base Pointer to FLEXIO_I2C_Type structure.
231 * @param mask Status flag.
232 * The parameter can be any combination of the following values:
233 * @arg kFLEXIO_I2C_RxFullFlag
234 * @arg kFLEXIO_I2C_ReceiveNakFlag
235 */
236
237 void FLEXIO_I2C_MasterClearStatusFlags(FLEXIO_I2C_Type *base, uint32_t mask);
238
239 /*@}*/
240
241 /*!
242 * @name Interrupts
243 * @{
244 */
245
246 /*!
247 * @brief Enables the FlexIO i2c master interrupt requests.
248 *
249 * @param base Pointer to FLEXIO_I2C_Type structure.
250 * @param mask Interrupt source.
251 * Currently only one interrupt request source:
252 * @arg kFLEXIO_I2C_TransferCompleteInterruptEnable
253 */
254 void FLEXIO_I2C_MasterEnableInterrupts(FLEXIO_I2C_Type *base, uint32_t mask);
255
256 /*!
257 * @brief Disables the FlexIO I2C master interrupt requests.
258 *
259 * @param base Pointer to FLEXIO_I2C_Type structure.
260 * @param mask Interrupt source.
261 */
262 void FLEXIO_I2C_MasterDisableInterrupts(FLEXIO_I2C_Type *base, uint32_t mask);
263
264 /*@}*/
265
266 /*!
267 * @name Bus Operations
268 * @{
269 */
270
271 /*!
272 * @brief Sets the FlexIO I2C master transfer baudrate.
273 *
274 * @param base Pointer to FLEXIO_I2C_Type structure
275 * @param baudRate_Bps the baud rate value in HZ
276 * @param srcClock_Hz source clock in HZ
277 */
278 void FLEXIO_I2C_MasterSetBaudRate(FLEXIO_I2C_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz);
279
280 /*!
281 * @brief Sends START + 7-bit address to the bus.
282 *
283 * @note This API should be called when the transfer configuration is ready to send a START signal
284 * and 7-bit address to the bus. This is a non-blocking API, which returns directly after the address
285 * is put into the data register but the address transfer is not finished on the bus. Ensure that
286 * the kFLEXIO_I2C_RxFullFlag status is asserted before calling this API.
287 * @param base Pointer to FLEXIO_I2C_Type structure.
288 * @param address 7-bit address.
289 * @param direction transfer direction.
290 * This parameter is one of the values in flexio_i2c_direction_t:
291 * @arg kFLEXIO_I2C_Write: Transmit
292 * @arg kFLEXIO_I2C_Read: Receive
293 */
294
295 void FLEXIO_I2C_MasterStart(FLEXIO_I2C_Type *base, uint8_t address, flexio_i2c_direction_t direction);
296
297 /*!
298 * @brief Sends the stop signal on the bus.
299 *
300 * @param base Pointer to FLEXIO_I2C_Type structure.
301 */
302 void FLEXIO_I2C_MasterStop(FLEXIO_I2C_Type *base);
303
304 /*!
305 * @brief Sends the repeated start signal on the bus.
306 *
307 * @param base Pointer to FLEXIO_I2C_Type structure.
308 */
309 void FLEXIO_I2C_MasterRepeatedStart(FLEXIO_I2C_Type *base);
310
311 /*!
312 * @brief Sends the stop signal when transfer is still on-going.
313 *
314 * @param base Pointer to FLEXIO_I2C_Type structure.
315 */
316 void FLEXIO_I2C_MasterAbortStop(FLEXIO_I2C_Type *base);
317
318 /*!
319 * @brief Configures the sent ACK/NAK for the following byte.
320 *
321 * @param base Pointer to FLEXIO_I2C_Type structure.
322 * @param enable True to configure send ACK, false configure to send NAK.
323 */
324 void FLEXIO_I2C_MasterEnableAck(FLEXIO_I2C_Type *base, bool enable);
325
326 /*!
327 * @brief Sets the number of bytes to be transferred from a start signal to a stop signal.
328 *
329 * @note Call this API before a transfer begins because the timer generates a number of clocks according
330 * to the number of bytes that need to be transferred.
331 *
332 * @param base Pointer to FLEXIO_I2C_Type structure.
333 * @param count Number of bytes need to be transferred from a start signal to a re-start/stop signal
334 * @retval kStatus_Success Successfully configured the count.
335 * @retval kStatus_InvalidArgument Input argument is invalid.
336 */
337 status_t FLEXIO_I2C_MasterSetTransferCount(FLEXIO_I2C_Type *base, uint16_t count);
338
339 /*!
340 * @brief Writes one byte of data to the I2C bus.
341 *
342 * @note This is a non-blocking API, which returns directly after the data is put into the
343 * data register but the data transfer is not finished on the bus. Ensure that
344 * the TxEmptyFlag is asserted before calling this API.
345 *
346 * @param base Pointer to FLEXIO_I2C_Type structure.
347 * @param data a byte of data.
348 */
FLEXIO_I2C_MasterWriteByte(FLEXIO_I2C_Type * base,uint32_t data)349 static inline void FLEXIO_I2C_MasterWriteByte(FLEXIO_I2C_Type *base, uint32_t data)
350 {
351 base->flexioBase->SHIFTBUFBBS[base->shifterIndex[0]] = data;
352 }
353
354 /*!
355 * @brief Reads one byte of data from the I2C bus.
356 *
357 * @note This is a non-blocking API, which returns directly after the data is read from the
358 * data register. Ensure that the data is ready in the register.
359 *
360 * @param base Pointer to FLEXIO_I2C_Type structure.
361 * @return data byte read.
362 */
FLEXIO_I2C_MasterReadByte(FLEXIO_I2C_Type * base)363 static inline uint8_t FLEXIO_I2C_MasterReadByte(FLEXIO_I2C_Type *base)
364 {
365 return (uint8_t)(base->flexioBase->SHIFTBUFBIS[base->shifterIndex[1]]);
366 }
367
368 /*!
369 * @brief Sends a buffer of data in bytes.
370 *
371 * @note This function blocks via polling until all bytes have been sent.
372 *
373 * @param base Pointer to FLEXIO_I2C_Type structure.
374 * @param txBuff The data bytes to send.
375 * @param txSize The number of data bytes to send.
376 * @retval kStatus_Success Successfully write data.
377 * @retval kStatus_FLEXIO_I2C_Nak Receive NAK during writing data.
378 * @retval kStatus_FLEXIO_I2C_Timeout Timeout polling status flags.
379 */
380 status_t FLEXIO_I2C_MasterWriteBlocking(FLEXIO_I2C_Type *base, const uint8_t *txBuff, uint8_t txSize);
381
382 /*!
383 * @brief Receives a buffer of bytes.
384 *
385 * @note This function blocks via polling until all bytes have been received.
386 *
387 * @param base Pointer to FLEXIO_I2C_Type structure.
388 * @param rxBuff The buffer to store the received bytes.
389 * @param rxSize The number of data bytes to be received.
390 * @retval kStatus_Success Successfully read data.
391 * @retval kStatus_FLEXIO_I2C_Timeout Timeout polling status flags.
392 */
393 status_t FLEXIO_I2C_MasterReadBlocking(FLEXIO_I2C_Type *base, uint8_t *rxBuff, uint8_t rxSize);
394
395 /*!
396 * @brief Performs a master polling transfer on the I2C bus.
397 *
398 * @note The API does not return until the transfer succeeds or fails due
399 * to receiving NAK.
400 *
401 * @param base pointer to FLEXIO_I2C_Type structure.
402 * @param xfer pointer to flexio_i2c_master_transfer_t structure.
403 * @return status of status_t.
404 */
405 status_t FLEXIO_I2C_MasterTransferBlocking(FLEXIO_I2C_Type *base, flexio_i2c_master_transfer_t *xfer);
406 /*@}*/
407
408 /*Transactional APIs*/
409
410 /*!
411 * @name Transactional
412 * @{
413 */
414
415 /*!
416 * @brief Initializes the I2C handle which is used in transactional functions.
417 *
418 * @param base Pointer to FLEXIO_I2C_Type structure.
419 * @param handle Pointer to flexio_i2c_master_handle_t structure to store the transfer state.
420 * @param callback Pointer to user callback function.
421 * @param userData User param passed to the callback function.
422 * @retval kStatus_Success Successfully create the handle.
423 * @retval kStatus_OutOfRange The FlexIO type/handle/isr table out of range.
424 */
425 status_t FLEXIO_I2C_MasterTransferCreateHandle(FLEXIO_I2C_Type *base,
426 flexio_i2c_master_handle_t *handle,
427 flexio_i2c_master_transfer_callback_t callback,
428 void *userData);
429
430 /*!
431 * @brief Performs a master interrupt non-blocking transfer on the I2C bus.
432 *
433 * @note The API returns immediately after the transfer initiates.
434 * Call FLEXIO_I2C_MasterTransferGetCount to poll the transfer status to check whether
435 * the transfer is finished. If the return status is not kStatus_FLEXIO_I2C_Busy, the transfer
436 * is finished.
437 *
438 * @param base Pointer to FLEXIO_I2C_Type structure
439 * @param handle Pointer to flexio_i2c_master_handle_t structure which stores the transfer state
440 * @param xfer pointer to flexio_i2c_master_transfer_t structure
441 * @retval kStatus_Success Successfully start a transfer.
442 * @retval kStatus_FLEXIO_I2C_Busy FlexIO I2C is not idle, is running another transfer.
443 */
444 status_t FLEXIO_I2C_MasterTransferNonBlocking(FLEXIO_I2C_Type *base,
445 flexio_i2c_master_handle_t *handle,
446 flexio_i2c_master_transfer_t *xfer);
447
448 /*!
449 * @brief Gets the master transfer status during a interrupt non-blocking transfer.
450 *
451 * @param base Pointer to FLEXIO_I2C_Type structure.
452 * @param handle Pointer to flexio_i2c_master_handle_t structure which stores the transfer state.
453 * @param count Number of bytes transferred so far by the non-blocking transaction.
454 * @retval kStatus_InvalidArgument count is Invalid.
455 * @retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress.
456 * @retval kStatus_Success Successfully return the count.
457 */
458 status_t FLEXIO_I2C_MasterTransferGetCount(FLEXIO_I2C_Type *base, flexio_i2c_master_handle_t *handle, size_t *count);
459
460 /*!
461 * @brief Aborts an interrupt non-blocking transfer early.
462 *
463 * @note This API can be called at any time when an interrupt non-blocking transfer initiates
464 * to abort the transfer early.
465 *
466 * @param base Pointer to FLEXIO_I2C_Type structure
467 * @param handle Pointer to flexio_i2c_master_handle_t structure which stores the transfer state
468 */
469 void FLEXIO_I2C_MasterTransferAbort(FLEXIO_I2C_Type *base, flexio_i2c_master_handle_t *handle);
470
471 /*!
472 * @brief Master interrupt handler.
473 *
474 * @param i2cType Pointer to FLEXIO_I2C_Type structure
475 * @param i2cHandle Pointer to flexio_i2c_master_transfer_t structure
476 */
477 void FLEXIO_I2C_MasterTransferHandleIRQ(void *i2cType, void *i2cHandle);
478
479 /*@}*/
480
481 #if defined(__cplusplus)
482 }
483 #endif /*_cplusplus*/
484 /*@}*/
485
486 #endif /*_FSL_FLEXIO_I2C_MASTER_H_*/
487