Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:22:59

0001 /*
0002  * Copyright (c) 2015, Freescale Semiconductor, Inc.
0003  * Copyright 2016-2020 NXP
0004  * All rights reserved.
0005  *
0006  * SPDX-License-Identifier: BSD-3-Clause
0007  */
0008 #ifndef _FSL_FLEXIO_I2C_MASTER_H_
0009 #define _FSL_FLEXIO_I2C_MASTER_H_
0010 
0011 #include "fsl_common.h"
0012 #include "fsl_flexio.h"
0013 
0014 /*!
0015  * @addtogroup flexio_i2c_master
0016  * @{
0017  */
0018 
0019 /*******************************************************************************
0020  * Definitions
0021  ******************************************************************************/
0022 
0023 /*! @name Driver version */
0024 /*@{*/
0025 #define FSL_FLEXIO_I2C_MASTER_DRIVER_VERSION (MAKE_VERSION(2, 5, 0))
0026 /*@}*/
0027 
0028 /*! @brief Retry times for waiting flag. */
0029 #ifndef I2C_RETRY_TIMES
0030 #define I2C_RETRY_TIMES 0U /* Define to zero means keep waiting until the flag is assert/deassert. */
0031 #endif
0032 
0033 /*! @brief FlexIO I2C transfer status*/
0034 enum
0035 {
0036     kStatus_FLEXIO_I2C_Busy    = MAKE_STATUS(kStatusGroup_FLEXIO_I2C, 0), /*!< I2C is busy doing transfer. */
0037     kStatus_FLEXIO_I2C_Idle    = MAKE_STATUS(kStatusGroup_FLEXIO_I2C, 1), /*!< I2C is busy doing transfer. */
0038     kStatus_FLEXIO_I2C_Nak     = MAKE_STATUS(kStatusGroup_FLEXIO_I2C, 2), /*!< NAK received during transfer. */
0039     kStatus_FLEXIO_I2C_Timeout = MAKE_STATUS(kStatusGroup_FLEXIO_I2C, 3), /*!< Timeout polling status flags. */
0040 };
0041 
0042 /*! @brief Define FlexIO I2C master interrupt mask. */
0043 enum _flexio_i2c_master_interrupt
0044 {
0045     kFLEXIO_I2C_TxEmptyInterruptEnable = 0x1U, /*!< Tx buffer empty interrupt enable. */
0046     kFLEXIO_I2C_RxFullInterruptEnable  = 0x2U, /*!< Rx buffer full interrupt enable. */
0047 };
0048 
0049 /*! @brief Define FlexIO I2C master status mask. */
0050 enum _flexio_i2c_master_status_flags
0051 {
0052     kFLEXIO_I2C_TxEmptyFlag    = 0x1U, /*!< Tx shifter empty flag. */
0053     kFLEXIO_I2C_RxFullFlag     = 0x2U, /*!< Rx shifter full/Transfer complete flag. */
0054     kFLEXIO_I2C_ReceiveNakFlag = 0x4U, /*!< Receive NAK flag. */
0055 };
0056 
0057 /*! @brief Direction of master transfer.*/
0058 typedef enum _flexio_i2c_direction
0059 {
0060     kFLEXIO_I2C_Write = 0x0U, /*!< Master send to slave. */
0061     kFLEXIO_I2C_Read  = 0x1U, /*!< Master receive from slave. */
0062 } flexio_i2c_direction_t;
0063 
0064 /*! @brief Define FlexIO I2C master access structure typedef. */
0065 typedef struct _flexio_i2c_type
0066 {
0067     FLEXIO_Type *flexioBase; /*!< FlexIO base pointer. */
0068     uint8_t SDAPinIndex;     /*!< Pin select for I2C SDA. */
0069     uint8_t SCLPinIndex;     /*!< Pin select for I2C SCL. */
0070     uint8_t shifterIndex[2]; /*!< Shifter index used in FlexIO I2C. */
0071     uint8_t timerIndex[3];   /*!< Timer index used in FlexIO I2C. */
0072     uint32_t baudrate;       /*!< Master transfer baudrate, used to calculate delay time. */
0073 } FLEXIO_I2C_Type;
0074 
0075 /*! @brief Define FlexIO I2C master user configuration structure. */
0076 typedef struct _flexio_i2c_master_config
0077 {
0078     bool enableMaster;     /*!< Enables the FlexIO I2C peripheral at initialization time. */
0079     bool enableInDoze;     /*!< Enable/disable FlexIO operation in doze mode. */
0080     bool enableInDebug;    /*!< Enable/disable FlexIO operation in debug mode. */
0081     bool enableFastAccess; /*!< Enable/disable fast access to FlexIO registers, fast access requires
0082                            the FlexIO clock to be at least twice the frequency of the bus clock. */
0083     uint32_t baudRate_Bps; /*!< Baud rate in Bps. */
0084 } flexio_i2c_master_config_t;
0085 
0086 /*! @brief Define FlexIO I2C master transfer structure. */
0087 typedef struct _flexio_i2c_master_transfer
0088 {
0089     uint32_t flags;                   /*!< Transfer flag which controls the transfer, reserved for FlexIO I2C. */
0090     uint8_t slaveAddress;             /*!< 7-bit slave address. */
0091     flexio_i2c_direction_t direction; /*!< Transfer direction, read or write. */
0092     uint32_t subaddress;              /*!< Sub address. Transferred MSB first. */
0093     uint8_t subaddressSize;           /*!< Size of command buffer. */
0094     uint8_t volatile *data;           /*!< Transfer buffer. */
0095     volatile size_t dataSize;         /*!< Transfer size. */
0096 } flexio_i2c_master_transfer_t;
0097 
0098 /*! @brief FlexIO I2C master handle typedef. */
0099 typedef struct _flexio_i2c_master_handle flexio_i2c_master_handle_t;
0100 
0101 /*! @brief FlexIO I2C master transfer callback typedef. */
0102 typedef void (*flexio_i2c_master_transfer_callback_t)(FLEXIO_I2C_Type *base,
0103                                                       flexio_i2c_master_handle_t *handle,
0104                                                       status_t status,
0105                                                       void *userData);
0106 
0107 /*! @brief Define FlexIO I2C master handle structure. */
0108 struct _flexio_i2c_master_handle
0109 {
0110     flexio_i2c_master_transfer_t transfer;                    /*!< FlexIO I2C master transfer copy. */
0111     size_t transferSize;                                      /*!< Total bytes to be transferred. */
0112     uint8_t state;                                            /*!< Transfer state maintained during transfer. */
0113     flexio_i2c_master_transfer_callback_t completionCallback; /*!< Callback function called at transfer event. */
0114                                                               /*!< Callback function called at transfer event. */
0115     void *userData;                                           /*!< Callback parameter passed to callback function. */
0116     bool needRestart;                                         /*!< Whether master needs to send re-start signal. */
0117 };
0118 
0119 /*******************************************************************************
0120  * API
0121  ******************************************************************************/
0122 
0123 #if defined(__cplusplus)
0124 extern "C" {
0125 #endif /*_cplusplus*/
0126 
0127 /*!
0128  * @name Initialization and deinitialization
0129  * @{
0130  */
0131 
0132 #if defined(FSL_FEATURE_FLEXIO_HAS_PIN_STATUS) && FSL_FEATURE_FLEXIO_HAS_PIN_STATUS
0133 /*!
0134  * @brief Make sure the bus isn't already pulled down.
0135  *
0136  * Check the FLEXIO pin status to see whether either of SDA and SCL pin is pulled down.
0137  *
0138  * @param base Pointer to FLEXIO_I2C_Type structure..
0139  * @retval kStatus_Success
0140  * @retval kStatus_FLEXIO_I2C_Busy
0141  */
0142 status_t FLEXIO_I2C_CheckForBusyBus(FLEXIO_I2C_Type *base);
0143 #endif /*FSL_FEATURE_FLEXIO_HAS_PIN_STATUS*/
0144 
0145 /*!
0146  * @brief Ungates the FlexIO clock, resets the FlexIO module, and configures the FlexIO I2C
0147  * hardware configuration.
0148  *
0149  * Example
0150    @code
0151    FLEXIO_I2C_Type base = {
0152    .flexioBase = FLEXIO,
0153    .SDAPinIndex = 0,
0154    .SCLPinIndex = 1,
0155    .shifterIndex = {0,1},
0156    .timerIndex = {0,1}
0157    };
0158    flexio_i2c_master_config_t config = {
0159    .enableInDoze = false,
0160    .enableInDebug = true,
0161    .enableFastAccess = false,
0162    .baudRate_Bps = 100000
0163    };
0164    FLEXIO_I2C_MasterInit(base, &config, srcClock_Hz);
0165    @endcode
0166  *
0167  * @param base Pointer to FLEXIO_I2C_Type structure.
0168  * @param masterConfig Pointer to flexio_i2c_master_config_t structure.
0169  * @param srcClock_Hz FlexIO source clock in Hz.
0170  * @retval kStatus_Success Initialization successful
0171  * @retval kStatus_InvalidArgument The source clock exceed upper range limitation
0172 */
0173 status_t FLEXIO_I2C_MasterInit(FLEXIO_I2C_Type *base, flexio_i2c_master_config_t *masterConfig, uint32_t srcClock_Hz);
0174 
0175 /*!
0176  * @brief De-initializes the FlexIO I2C master peripheral. Calling this API Resets the FlexIO I2C master
0177  * shifer and timer config, module can't work unless the FLEXIO_I2C_MasterInit is called.
0178  *
0179  * @param base pointer to FLEXIO_I2C_Type structure.
0180  */
0181 void FLEXIO_I2C_MasterDeinit(FLEXIO_I2C_Type *base);
0182 
0183 /*!
0184  * @brief Gets the default configuration to configure the FlexIO module. The configuration
0185  * can be used directly for calling the FLEXIO_I2C_MasterInit().
0186  *
0187  * Example:
0188    @code
0189    flexio_i2c_master_config_t config;
0190    FLEXIO_I2C_MasterGetDefaultConfig(&config);
0191    @endcode
0192  * @param masterConfig Pointer to flexio_i2c_master_config_t structure.
0193 */
0194 void FLEXIO_I2C_MasterGetDefaultConfig(flexio_i2c_master_config_t *masterConfig);
0195 
0196 /*!
0197  * @brief Enables/disables the FlexIO module operation.
0198  *
0199  * @param base Pointer to FLEXIO_I2C_Type structure.
0200  * @param enable Pass true to enable module, false does not have any effect.
0201  */
0202 static inline void FLEXIO_I2C_MasterEnable(FLEXIO_I2C_Type *base, bool enable)
0203 {
0204     if (enable)
0205     {
0206         base->flexioBase->CTRL |= FLEXIO_CTRL_FLEXEN_MASK;
0207     }
0208 }
0209 
0210 /* @} */
0211 
0212 /*!
0213  * @name Status
0214  * @{
0215  */
0216 
0217 /*!
0218  * @brief Gets the FlexIO I2C master status flags.
0219  *
0220  * @param base Pointer to FLEXIO_I2C_Type structure
0221  * @return Status flag, use status flag to AND #_flexio_i2c_master_status_flags can get the related status.
0222  */
0223 
0224 uint32_t FLEXIO_I2C_MasterGetStatusFlags(FLEXIO_I2C_Type *base);
0225 
0226 /*!
0227  * @brief Clears the FlexIO I2C master status flags.
0228  *
0229  * @param base Pointer to FLEXIO_I2C_Type structure.
0230  * @param mask Status flag.
0231  *      The parameter can be any combination of the following values:
0232  *          @arg kFLEXIO_I2C_RxFullFlag
0233  *          @arg kFLEXIO_I2C_ReceiveNakFlag
0234  */
0235 
0236 void FLEXIO_I2C_MasterClearStatusFlags(FLEXIO_I2C_Type *base, uint32_t mask);
0237 
0238 /*@}*/
0239 
0240 /*!
0241  * @name Interrupts
0242  * @{
0243  */
0244 
0245 /*!
0246  * @brief Enables the FlexIO i2c master interrupt requests.
0247  *
0248  * @param base Pointer to FLEXIO_I2C_Type structure.
0249  * @param mask Interrupt source.
0250  *     Currently only one interrupt request source:
0251  *     @arg kFLEXIO_I2C_TransferCompleteInterruptEnable
0252  */
0253 void FLEXIO_I2C_MasterEnableInterrupts(FLEXIO_I2C_Type *base, uint32_t mask);
0254 
0255 /*!
0256  * @brief Disables the FlexIO I2C master interrupt requests.
0257  *
0258  * @param base Pointer to FLEXIO_I2C_Type structure.
0259  * @param mask Interrupt source.
0260  */
0261 void FLEXIO_I2C_MasterDisableInterrupts(FLEXIO_I2C_Type *base, uint32_t mask);
0262 
0263 /*@}*/
0264 
0265 /*!
0266  * @name Bus Operations
0267  * @{
0268  */
0269 
0270 /*!
0271  * @brief Sets the FlexIO I2C master transfer baudrate.
0272  *
0273  * @param base Pointer to FLEXIO_I2C_Type structure
0274  * @param baudRate_Bps the baud rate value in HZ
0275  * @param srcClock_Hz source clock in HZ
0276  */
0277 void FLEXIO_I2C_MasterSetBaudRate(FLEXIO_I2C_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz);
0278 
0279 /*!
0280  * @brief Sends START + 7-bit address to the bus.
0281  *
0282  * @note This API should be called when the transfer configuration is ready to send a START signal
0283  * and 7-bit address to the bus. This is a non-blocking API, which returns directly after the address
0284  * is put into the data register but the address transfer is not finished on the bus. Ensure that
0285  * the kFLEXIO_I2C_RxFullFlag status is asserted before calling this API.
0286  * @param base Pointer to FLEXIO_I2C_Type structure.
0287  * @param address 7-bit address.
0288  * @param direction transfer direction.
0289  *     This parameter is one of the values in flexio_i2c_direction_t:
0290  *        @arg kFLEXIO_I2C_Write: Transmit
0291  *        @arg kFLEXIO_I2C_Read:  Receive
0292  */
0293 
0294 void FLEXIO_I2C_MasterStart(FLEXIO_I2C_Type *base, uint8_t address, flexio_i2c_direction_t direction);
0295 
0296 /*!
0297  * @brief Sends the stop signal on the bus.
0298  *
0299  * @param base Pointer to FLEXIO_I2C_Type structure.
0300  */
0301 void FLEXIO_I2C_MasterStop(FLEXIO_I2C_Type *base);
0302 
0303 /*!
0304  * @brief Sends the repeated start signal on the bus.
0305  *
0306  * @param base Pointer to FLEXIO_I2C_Type structure.
0307  */
0308 void FLEXIO_I2C_MasterRepeatedStart(FLEXIO_I2C_Type *base);
0309 
0310 /*!
0311  * @brief Sends the stop signal when transfer is still on-going.
0312  *
0313  * @param base Pointer to FLEXIO_I2C_Type structure.
0314  */
0315 void FLEXIO_I2C_MasterAbortStop(FLEXIO_I2C_Type *base);
0316 
0317 /*!
0318  * @brief Configures the sent ACK/NAK for the following byte.
0319  *
0320  * @param base Pointer to FLEXIO_I2C_Type structure.
0321  * @param enable True to configure send ACK, false configure to send NAK.
0322  */
0323 void FLEXIO_I2C_MasterEnableAck(FLEXIO_I2C_Type *base, bool enable);
0324 
0325 /*!
0326  * @brief Sets the number of bytes to be transferred from a start signal to a stop signal.
0327  *
0328  * @note Call this API before a transfer begins because the timer generates a number of clocks according
0329  * to the number of bytes that need to be transferred.
0330  *
0331  * @param base Pointer to FLEXIO_I2C_Type structure.
0332  * @param count Number of bytes need to be transferred from a start signal to a re-start/stop signal
0333  * @retval kStatus_Success Successfully configured the count.
0334  * @retval kStatus_InvalidArgument Input argument is invalid.
0335  */
0336 status_t FLEXIO_I2C_MasterSetTransferCount(FLEXIO_I2C_Type *base, uint16_t count);
0337 
0338 /*!
0339  * @brief Writes one byte of data to the I2C bus.
0340  *
0341  * @note This is a non-blocking API, which returns directly after the data is put into the
0342  * data register but the data transfer is not finished on the bus. Ensure that
0343  * the TxEmptyFlag is asserted before calling this API.
0344  *
0345  * @param base Pointer to FLEXIO_I2C_Type structure.
0346  * @param data a byte of data.
0347  */
0348 static inline void FLEXIO_I2C_MasterWriteByte(FLEXIO_I2C_Type *base, uint32_t data)
0349 {
0350     base->flexioBase->SHIFTBUFBBS[base->shifterIndex[0]] = data;
0351 }
0352 
0353 /*!
0354  * @brief Reads one byte of data from the I2C bus.
0355  *
0356  * @note This is a non-blocking API, which returns directly after the data is read from the
0357  * data register. Ensure that the data is ready in the register.
0358  *
0359  * @param base Pointer to FLEXIO_I2C_Type structure.
0360  * @return data byte read.
0361  */
0362 static inline uint8_t FLEXIO_I2C_MasterReadByte(FLEXIO_I2C_Type *base)
0363 {
0364     return (uint8_t)(base->flexioBase->SHIFTBUFBIS[base->shifterIndex[1]]);
0365 }
0366 
0367 /*!
0368  * @brief Sends a buffer of data in bytes.
0369  *
0370  * @note This function blocks via polling until all bytes have been sent.
0371  *
0372  * @param base Pointer to FLEXIO_I2C_Type structure.
0373  * @param txBuff The data bytes to send.
0374  * @param txSize The number of data bytes to send.
0375  * @retval kStatus_Success Successfully write data.
0376  * @retval kStatus_FLEXIO_I2C_Nak Receive NAK during writing data.
0377  * @retval kStatus_FLEXIO_I2C_Timeout Timeout polling status flags.
0378  */
0379 status_t FLEXIO_I2C_MasterWriteBlocking(FLEXIO_I2C_Type *base, const uint8_t *txBuff, uint8_t txSize);
0380 
0381 /*!
0382  * @brief Receives a buffer of bytes.
0383  *
0384  * @note This function blocks via polling until all bytes have been received.
0385  *
0386  * @param base Pointer to FLEXIO_I2C_Type structure.
0387  * @param rxBuff The buffer to store the received bytes.
0388  * @param rxSize The number of data bytes to be received.
0389  * @retval kStatus_Success Successfully read data.
0390  * @retval kStatus_FLEXIO_I2C_Timeout Timeout polling status flags.
0391  */
0392 status_t FLEXIO_I2C_MasterReadBlocking(FLEXIO_I2C_Type *base, uint8_t *rxBuff, uint8_t rxSize);
0393 
0394 /*!
0395  * @brief Performs a master polling transfer on the I2C bus.
0396  *
0397  * @note The API does not return until the transfer succeeds or fails due
0398  * to receiving NAK.
0399  *
0400  * @param base pointer to FLEXIO_I2C_Type structure.
0401  * @param xfer pointer to flexio_i2c_master_transfer_t structure.
0402  * @return status of status_t.
0403  */
0404 status_t FLEXIO_I2C_MasterTransferBlocking(FLEXIO_I2C_Type *base, flexio_i2c_master_transfer_t *xfer);
0405 /*@}*/
0406 
0407 /*Transactional APIs*/
0408 
0409 /*!
0410  * @name Transactional
0411  * @{
0412  */
0413 
0414 /*!
0415  * @brief Initializes the I2C handle which is used in transactional functions.
0416  *
0417  * @param base Pointer to FLEXIO_I2C_Type structure.
0418  * @param handle Pointer to flexio_i2c_master_handle_t structure to store the transfer state.
0419  * @param callback Pointer to user callback function.
0420  * @param userData User param passed to the callback function.
0421  * @retval kStatus_Success Successfully create the handle.
0422  * @retval kStatus_OutOfRange The FlexIO type/handle/isr table out of range.
0423  */
0424 status_t FLEXIO_I2C_MasterTransferCreateHandle(FLEXIO_I2C_Type *base,
0425                                                flexio_i2c_master_handle_t *handle,
0426                                                flexio_i2c_master_transfer_callback_t callback,
0427                                                void *userData);
0428 
0429 /*!
0430  * @brief Performs a master interrupt non-blocking transfer on the I2C bus.
0431  *
0432  * @note The API returns immediately after the transfer initiates.
0433  * Call FLEXIO_I2C_MasterTransferGetCount to poll the transfer status to check whether
0434  * the transfer is finished. If the return status is not kStatus_FLEXIO_I2C_Busy, the transfer
0435  * is finished.
0436  *
0437  * @param base Pointer to FLEXIO_I2C_Type structure
0438  * @param handle Pointer to flexio_i2c_master_handle_t structure which stores the transfer state
0439  * @param xfer pointer to flexio_i2c_master_transfer_t structure
0440  * @retval kStatus_Success Successfully start a transfer.
0441  * @retval kStatus_FLEXIO_I2C_Busy FlexIO I2C is not idle, is running another transfer.
0442  */
0443 status_t FLEXIO_I2C_MasterTransferNonBlocking(FLEXIO_I2C_Type *base,
0444                                               flexio_i2c_master_handle_t *handle,
0445                                               flexio_i2c_master_transfer_t *xfer);
0446 
0447 /*!
0448  * @brief Gets the master transfer status during a interrupt non-blocking transfer.
0449  *
0450  * @param base Pointer to FLEXIO_I2C_Type structure.
0451  * @param handle Pointer to flexio_i2c_master_handle_t structure which stores the transfer state.
0452  * @param count Number of bytes transferred so far by the non-blocking transaction.
0453  * @retval kStatus_InvalidArgument count is Invalid.
0454  * @retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress.
0455  * @retval kStatus_Success Successfully return the count.
0456  */
0457 status_t FLEXIO_I2C_MasterTransferGetCount(FLEXIO_I2C_Type *base, flexio_i2c_master_handle_t *handle, size_t *count);
0458 
0459 /*!
0460  * @brief Aborts an interrupt non-blocking transfer early.
0461  *
0462  * @note This API can be called at any time when an interrupt non-blocking transfer initiates
0463  * to abort the transfer early.
0464  *
0465  * @param base Pointer to FLEXIO_I2C_Type structure
0466  * @param handle Pointer to flexio_i2c_master_handle_t structure which stores the transfer state
0467  */
0468 void FLEXIO_I2C_MasterTransferAbort(FLEXIO_I2C_Type *base, flexio_i2c_master_handle_t *handle);
0469 
0470 /*!
0471  * @brief Master interrupt handler.
0472  *
0473  * @param i2cType Pointer to FLEXIO_I2C_Type structure
0474  * @param i2cHandle Pointer to flexio_i2c_master_transfer_t structure
0475  */
0476 void FLEXIO_I2C_MasterTransferHandleIRQ(void *i2cType, void *i2cHandle);
0477 
0478 /*@}*/
0479 
0480 #if defined(__cplusplus)
0481 }
0482 #endif /*_cplusplus*/
0483 /*@}*/
0484 
0485 #endif /*_FSL_FLEXIO_I2C_MASTER_H_*/