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-2022 NXP
0004  * All rights reserved.
0005  *
0006  * SPDX-License-Identifier: BSD-3-Clause
0007  */
0008 
0009 #include "fsl_flexio_i2c_master.h"
0010 
0011 /*******************************************************************************
0012  * Definitions
0013  ******************************************************************************/
0014 
0015 /* Component ID definition, used by tools. */
0016 #ifndef FSL_COMPONENT_ID
0017 #define FSL_COMPONENT_ID "platform.drivers.flexio_i2c_master"
0018 #endif
0019 
0020 /*! @brief  FLEXIO I2C transfer state */
0021 enum _flexio_i2c_master_transfer_states
0022 {
0023     kFLEXIO_I2C_Idle             = 0x0U, /*!< I2C bus idle */
0024     kFLEXIO_I2C_Start            = 0x1U, /*!< I2C start phase */
0025     kFLEXIO_I2C_SendCommand      = 0x2U, /*!< Send command byte phase */
0026     kFLEXIO_I2C_SendData         = 0x3U, /*!< Send data transfer phase*/
0027     kFLEXIO_I2C_ReceiveDataBegin = 0x4U, /*!< Receive data begin transfer phase*/
0028     kFLEXIO_I2C_ReceiveData      = 0x5U, /*!< Receive data transfer phase*/
0029 };
0030 
0031 /*******************************************************************************
0032  * Prototypes
0033  ******************************************************************************/
0034 
0035 /*!
0036  * @brief Set up master transfer, send slave address and decide the initial
0037  * transfer state.
0038  *
0039  * @param base pointer to FLEXIO_I2C_Type structure
0040  * @param handle pointer to flexio_i2c_master_handle_t structure which stores the transfer state
0041  * @param transfer pointer to flexio_i2c_master_transfer_t structure
0042  */
0043 static status_t FLEXIO_I2C_MasterTransferInitStateMachine(FLEXIO_I2C_Type *base,
0044                                                           flexio_i2c_master_handle_t *handle,
0045                                                           flexio_i2c_master_transfer_t *xfer);
0046 
0047 /*!
0048  * @brief Master run transfer state machine to perform a byte of transfer.
0049  *
0050  * @param base pointer to FLEXIO_I2C_Type structure
0051  * @param handle pointer to flexio_i2c_master_handle_t structure which stores the transfer state
0052  * @param statusFlags flexio i2c hardware status
0053  * @retval kStatus_Success Successfully run state machine
0054  * @retval kStatus_FLEXIO_I2C_Nak Receive Nak during transfer
0055  */
0056 static status_t FLEXIO_I2C_MasterTransferRunStateMachine(FLEXIO_I2C_Type *base,
0057                                                          flexio_i2c_master_handle_t *handle,
0058                                                          uint32_t statusFlags);
0059 
0060 /*!
0061  * @brief Complete transfer, disable interrupt and call callback.
0062  *
0063  * @param base pointer to FLEXIO_I2C_Type structure
0064  * @param handle pointer to flexio_i2c_master_handle_t structure which stores the transfer state
0065  * @param status flexio transfer status
0066  */
0067 static void FLEXIO_I2C_MasterTransferComplete(FLEXIO_I2C_Type *base,
0068                                               flexio_i2c_master_handle_t *handle,
0069                                               status_t status);
0070 
0071 /*!
0072  * @brief introduce function FLEXIO_I2C_MasterTransferStateMachineStart.
0073  * This function was deal with Initial state, i2c start state.
0074  *
0075  * @param base pointer to FLEXIO_I2C_Type structure
0076  * @param handle pointer to flexio_i2c_master_handle_t structure which stores the transfer state
0077  */
0078 static void FLEXIO_I2C_MasterTransferStateMachineStart(FLEXIO_I2C_Type *base, flexio_i2c_master_handle_t *handle);
0079 
0080 /*!
0081  * @brief introduce function FLEXIO_I2C_MasterTransferStateMachineSendCommand.
0082  * This function was deal with Check address only needed for transfer with subaddress .
0083  *
0084  * @param base pointer to FLEXIO_I2C_Type structure
0085  * @param handle pointer to flexio_i2c_master_handle_t structure which stores the transfer state
0086  * @param statusFlags flexio i2c hardware status
0087  *
0088  * @return default is true when No abnormality.
0089  * @return false when time out.
0090  */
0091 static bool FLEXIO_I2C_MasterTransferStateMachineSendCommand(FLEXIO_I2C_Type *base,
0092                                                              flexio_i2c_master_handle_t *handle,
0093                                                              uint32_t statusFlags);
0094 
0095 /*!
0096  * @brief introduce function FLEXIO_I2C_MasterTransferStateMachineSendData.
0097  * This function was deal with Send command byte.
0098  *
0099  * @param base pointer to FLEXIO_I2C_Type structure
0100  * @param handle pointer to flexio_i2c_master_handle_t structure which stores the transfer state
0101  * @param statusFlags flexio i2c hardware status
0102  *
0103  * @return default is true when No abnormality.
0104  * @return false when time out.
0105  */
0106 static bool FLEXIO_I2C_MasterTransferStateMachineSendData(FLEXIO_I2C_Type *base,
0107                                                           flexio_i2c_master_handle_t *handle,
0108                                                           uint32_t statusFlags);
0109 
0110 /*!
0111  * @brief introduce function FLEXIO_I2C_MasterTransferStateMachineReceiveDataBegin.
0112  * This function was deal with Receive Data Begin.
0113  *
0114  * @param base pointer to FLEXIO_I2C_Type structure
0115  * @param handle pointer to flexio_i2c_master_handle_t structure which stores the transfer state
0116  * @param statusFlags flexio i2c hardware status
0117  *
0118  * @return default is true when No abnormality.
0119  * @return false when time out.
0120  */
0121 static bool FLEXIO_I2C_MasterTransferStateMachineReceiveDataBegin(FLEXIO_I2C_Type *base,
0122                                                                   flexio_i2c_master_handle_t *handle,
0123                                                                   uint32_t statusFlags);
0124 
0125 /*!
0126  * @brief introduce function Case_kFLEXIO_I2C_ReceiveDataBegin.
0127  * This function was deal with Receive Data.
0128  *
0129  * @param base pointer to FLEXIO_I2C_Type structure
0130  * @param handle pointer to flexio_i2c_master_handle_t structure which stores the transfer state
0131  * @param statusFlags flexio i2c hardware status
0132  *
0133  * @return default is kStatus_Success when No abnormality.
0134  * @return kStatus_FLEXIO_I2C_Nak when ReceiveNakFlag is not set.
0135  * @return kStatus_FLEXIO_I2C_Timeout when time out.
0136  */
0137 static status_t FLEXIO_I2C_MasterTransferStateMachineReceiveData(FLEXIO_I2C_Type *base,
0138                                                                  flexio_i2c_master_handle_t *handle,
0139                                                                  uint32_t statusFlags);
0140 
0141 /*******************************************************************************
0142  * Codes
0143  ******************************************************************************/
0144 
0145 static uint32_t FLEXIO_I2C_GetInstance(FLEXIO_I2C_Type *base)
0146 {
0147     return FLEXIO_GetInstance(base->flexioBase);
0148 }
0149 
0150 static status_t FLEXIO_I2C_MasterTransferInitStateMachine(FLEXIO_I2C_Type *base,
0151                                                           flexio_i2c_master_handle_t *handle,
0152                                                           flexio_i2c_master_transfer_t *xfer)
0153 {
0154     bool needRestart;
0155     uint32_t byteCount;
0156 
0157     /* Init the handle member. */
0158     handle->transfer.slaveAddress   = xfer->slaveAddress;
0159     handle->transfer.direction      = xfer->direction;
0160     handle->transfer.subaddress     = xfer->subaddress;
0161     handle->transfer.subaddressSize = xfer->subaddressSize;
0162     handle->transfer.data           = xfer->data;
0163     handle->transfer.dataSize       = xfer->dataSize;
0164     handle->transfer.flags          = xfer->flags;
0165     handle->transferSize            = xfer->dataSize;
0166 
0167     /* Initial state, i2c start state. */
0168     handle->state = (uint8_t)kFLEXIO_I2C_Start;
0169 
0170     /* Clear all status before transfer. */
0171     FLEXIO_I2C_MasterClearStatusFlags(base, (uint32_t)kFLEXIO_I2C_ReceiveNakFlag);
0172 
0173     /* Calculate whether need to send re-start. */
0174     needRestart         = (handle->transfer.subaddressSize != 0U) && (handle->transfer.direction == kFLEXIO_I2C_Read);
0175     handle->needRestart = needRestart;
0176 
0177     /* Calculate total byte count in a frame. */
0178     byteCount = 1U;
0179 
0180     if (!needRestart)
0181     {
0182         byteCount += handle->transfer.dataSize;
0183     }
0184 
0185     if (handle->transfer.subaddressSize != 0U)
0186     {
0187         byteCount += handle->transfer.subaddressSize;
0188     }
0189 
0190     /* Configure data count. */
0191     if (FLEXIO_I2C_MasterSetTransferCount(base, (uint16_t)byteCount) != kStatus_Success)
0192     {
0193         return kStatus_InvalidArgument;
0194     }
0195 
0196     /* Configure timer1 disable condition. */
0197     uint32_t tmpConfig = base->flexioBase->TIMCFG[base->timerIndex[1]];
0198     tmpConfig &= ~FLEXIO_TIMCFG_TIMDIS_MASK;
0199     tmpConfig |= FLEXIO_TIMCFG_TIMDIS(kFLEXIO_TimerDisableOnPreTimerDisable);
0200     base->flexioBase->TIMCFG[base->timerIndex[1]] = tmpConfig;
0201 
0202 #if I2C_RETRY_TIMES
0203     uint32_t waitTimes = I2C_RETRY_TIMES;
0204     while ((0U == (FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1UL << base->shifterIndex[0]))) &&
0205            (0U != --waitTimes))
0206     {
0207     }
0208     if (0U == waitTimes)
0209     {
0210         return kStatus_FLEXIO_I2C_Timeout;
0211     }
0212 #else
0213     while (0U == (FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1UL << base->shifterIndex[0])))
0214     {
0215     }
0216 #endif
0217 
0218     return kStatus_Success;
0219 }
0220 
0221 static void FLEXIO_I2C_MasterTransferStateMachineStart(FLEXIO_I2C_Type *base, flexio_i2c_master_handle_t *handle)
0222 {
0223     if (handle->needRestart)
0224     {
0225         FLEXIO_I2C_MasterStart(base, handle->transfer.slaveAddress, kFLEXIO_I2C_Write);
0226     }
0227     else
0228     {
0229         FLEXIO_I2C_MasterStart(base, handle->transfer.slaveAddress, handle->transfer.direction);
0230     }
0231     if (handle->transfer.subaddressSize == 0U)
0232     {
0233         if (handle->transfer.direction == kFLEXIO_I2C_Write)
0234         {
0235             /* Next state, send data. */
0236             handle->state = (uint8_t)kFLEXIO_I2C_SendData;
0237         }
0238         else
0239         {
0240             /* Next state, receive data begin. */
0241             handle->state = (uint8_t)kFLEXIO_I2C_ReceiveDataBegin;
0242         }
0243     }
0244     else
0245     {
0246         /* Next state, send command byte. */
0247         handle->state = (uint8_t)kFLEXIO_I2C_SendCommand;
0248     }
0249 }
0250 
0251 static bool FLEXIO_I2C_MasterTransferStateMachineSendCommand(FLEXIO_I2C_Type *base,
0252                                                              flexio_i2c_master_handle_t *handle,
0253                                                              uint32_t statusFlags)
0254 {
0255     if ((statusFlags & (uint32_t)kFLEXIO_I2C_TxEmptyFlag) != 0U)
0256     {
0257         if (handle->transfer.subaddressSize > 0U)
0258         {
0259             handle->transfer.subaddressSize--;
0260             FLEXIO_I2C_MasterWriteByte(base, ((handle->transfer.subaddress) >> (8U * handle->transfer.subaddressSize)));
0261 
0262             if (handle->transfer.subaddressSize == 0U)
0263             {
0264                 /* Load re-start in advance. */
0265                 if (handle->transfer.direction == kFLEXIO_I2C_Read)
0266                 {
0267 #if I2C_RETRY_TIMES
0268                     while ((0U == (FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1UL << base->shifterIndex[0]))) &&
0269                            (0U != --waitTimes))
0270                     {
0271                     }
0272                     if (0U == waitTimes)
0273                     {
0274                         return false;
0275                     }
0276 #else
0277                     while (0U == (FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1UL << base->shifterIndex[0])))
0278                     {
0279                     }
0280 #endif
0281                     FLEXIO_I2C_MasterRepeatedStart(base);
0282                 }
0283             }
0284         }
0285         else
0286         {
0287             if (handle->transfer.direction == kFLEXIO_I2C_Write)
0288             {
0289                 /* Send first byte of data. */
0290                 if (handle->transfer.dataSize > 0U)
0291                 {
0292                     /* Next state, send data. */
0293                     handle->state = (uint8_t)kFLEXIO_I2C_SendData;
0294 
0295                     FLEXIO_I2C_MasterWriteByte(base, *handle->transfer.data);
0296                     handle->transfer.data++;
0297                     handle->transfer.dataSize--;
0298                 }
0299                 else
0300                 {
0301                     FLEXIO_I2C_MasterStop(base);
0302 
0303 #if I2C_RETRY_TIMES
0304                     while ((0U == (FLEXIO_I2C_MasterGetStatusFlags(base) & (uint32_t)kFLEXIO_I2C_RxFullFlag)) &&
0305                            (0U != --waitTimes))
0306                     {
0307                     }
0308                     if (0U == waitTimes)
0309                     {
0310                         return false;
0311                     }
0312 #else
0313                     while (0U == (FLEXIO_I2C_MasterGetStatusFlags(base) & (uint32_t)kFLEXIO_I2C_RxFullFlag))
0314                     {
0315                     }
0316 #endif
0317                     (void)FLEXIO_I2C_MasterReadByte(base);
0318 
0319                     handle->state = (uint8_t)kFLEXIO_I2C_Idle;
0320                 }
0321             }
0322             else
0323             {
0324                 (void)FLEXIO_I2C_MasterSetTransferCount(base, (uint16_t)(handle->transfer.dataSize + 1U));
0325                 /* Delay at least one clock cycle so that the restart setup time is up to spec standard. */
0326                 SDK_DelayAtLeastUs(1000000UL / base->baudrate, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
0327                 FLEXIO_I2C_MasterStart(base, handle->transfer.slaveAddress, kFLEXIO_I2C_Read);
0328 
0329                 /* Next state, receive data begin. */
0330                 handle->state = (uint8_t)kFLEXIO_I2C_ReceiveDataBegin;
0331             }
0332         }
0333     }
0334     return true;
0335 }
0336 
0337 static bool FLEXIO_I2C_MasterTransferStateMachineSendData(FLEXIO_I2C_Type *base,
0338                                                           flexio_i2c_master_handle_t *handle,
0339                                                           uint32_t statusFlags)
0340 {
0341     if ((statusFlags & (uint32_t)kFLEXIO_I2C_TxEmptyFlag) != 0U)
0342     {
0343         /* Send one byte of data. */
0344         if (handle->transfer.dataSize > 0U)
0345         {
0346             FLEXIO_I2C_MasterWriteByte(base, *handle->transfer.data);
0347 
0348             handle->transfer.data++;
0349             handle->transfer.dataSize--;
0350         }
0351         else
0352         {
0353             FLEXIO_I2C_MasterStop(base);
0354 
0355 #if I2C_RETRY_TIMES
0356             while ((0U == (FLEXIO_I2C_MasterGetStatusFlags(base) & (uint32_t)kFLEXIO_I2C_RxFullFlag)) &&
0357                    (0U != --waitTimes))
0358             {
0359             }
0360             if (0U == waitTimes)
0361             {
0362                 return false;
0363             }
0364 #else
0365             while (0U == (FLEXIO_I2C_MasterGetStatusFlags(base) & (uint32_t)kFLEXIO_I2C_RxFullFlag))
0366             {
0367             }
0368 #endif
0369             (void)FLEXIO_I2C_MasterReadByte(base);
0370 
0371             handle->state = (uint8_t)kFLEXIO_I2C_Idle;
0372         }
0373     }
0374     return true;
0375 }
0376 
0377 static bool FLEXIO_I2C_MasterTransferStateMachineReceiveDataBegin(FLEXIO_I2C_Type *base,
0378                                                                   flexio_i2c_master_handle_t *handle,
0379                                                                   uint32_t statusFlags)
0380 {
0381     if ((statusFlags & (uint32_t)kFLEXIO_I2C_RxFullFlag) != 0U)
0382     {
0383         handle->state = (uint8_t)kFLEXIO_I2C_ReceiveData;
0384         /* Send nak at the last receive byte. */
0385         if (handle->transfer.dataSize == 1U)
0386         {
0387             FLEXIO_I2C_MasterEnableAck(base, false);
0388 #if I2C_RETRY_TIMES
0389             while ((0U == (FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1UL << base->shifterIndex[0]))) &&
0390                    (0U != --waitTimes))
0391             {
0392             }
0393             if (0U == waitTimes)
0394             {
0395                 return false;
0396             }
0397 #else
0398             while (0U == (FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1UL << base->shifterIndex[0])))
0399             {
0400             }
0401 #endif
0402             FLEXIO_I2C_MasterStop(base);
0403         }
0404         else
0405         {
0406             FLEXIO_I2C_MasterEnableAck(base, true);
0407         }
0408     }
0409     else if ((statusFlags & (uint32_t)kFLEXIO_I2C_TxEmptyFlag) != 0U)
0410     {
0411         /* Read one byte of data. */
0412         FLEXIO_I2C_MasterWriteByte(base, 0xFFFFFFFFU);
0413     }
0414     else
0415     {
0416         ; /* Avoid MISRA 2012 rule 15.7 */
0417     }
0418     return true;
0419 }
0420 
0421 static status_t FLEXIO_I2C_MasterTransferStateMachineReceiveData(FLEXIO_I2C_Type *base,
0422                                                                  flexio_i2c_master_handle_t *handle,
0423                                                                  uint32_t statusFlags)
0424 {
0425     if ((statusFlags & (uint32_t)kFLEXIO_I2C_RxFullFlag) != 0U)
0426     {
0427         *handle->transfer.data = FLEXIO_I2C_MasterReadByte(base);
0428         handle->transfer.data++;
0429         if (0U != handle->transfer.dataSize--)
0430         {
0431             if (handle->transfer.dataSize == 0U)
0432             {
0433                 FLEXIO_I2C_MasterDisableInterrupts(base, (uint32_t)kFLEXIO_I2C_RxFullInterruptEnable);
0434                 handle->state = (uint8_t)kFLEXIO_I2C_Idle;
0435                 /* Return nak if ReceiveNakFlag is not set */
0436                 if ((statusFlags & (uint32_t)kFLEXIO_I2C_ReceiveNakFlag) == 0U)
0437                 {
0438                     return kStatus_FLEXIO_I2C_Nak;
0439                 }
0440             }
0441 
0442             /* Send nak at the last receive byte. */
0443             if (handle->transfer.dataSize == 1U)
0444             {
0445                 FLEXIO_I2C_MasterEnableAck(base, false);
0446 #if I2C_RETRY_TIMES
0447                 while ((0U == (FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1UL << base->shifterIndex[0]))) &&
0448                        (0U != --waitTimes))
0449                 {
0450                 }
0451                 if (0U == waitTimes)
0452                 {
0453                     return kStatus_FLEXIO_I2C_Timeout;
0454                 }
0455 #else
0456                 while (0U == (FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1UL << base->shifterIndex[0])))
0457                 {
0458                 }
0459 #endif
0460                 FLEXIO_I2C_MasterStop(base);
0461             }
0462         }
0463     }
0464     else if ((statusFlags & (uint32_t)kFLEXIO_I2C_TxEmptyFlag) != 0U)
0465     {
0466         if (handle->transfer.dataSize > 1U)
0467         {
0468             FLEXIO_I2C_MasterWriteByte(base, 0xFFFFFFFFU);
0469         }
0470     }
0471     else
0472     {
0473         ; /* Avoid MISRA 2012 rule 15.7 */
0474     }
0475     return kStatus_Success;
0476 }
0477 
0478 static status_t FLEXIO_I2C_MasterTransferRunStateMachine(FLEXIO_I2C_Type *base,
0479                                                          flexio_i2c_master_handle_t *handle,
0480                                                          uint32_t statusFlags)
0481 {
0482     status_t status;
0483 #if I2C_RETRY_TIMES
0484     uint32_t waitTimes = I2C_RETRY_TIMES;
0485 #endif
0486 
0487     if ((statusFlags & (uint32_t)kFLEXIO_I2C_ReceiveNakFlag) != 0U)
0488     {
0489         /* Clear receive nak flag. */
0490         FLEXIO_ClearShifterErrorFlags(base->flexioBase, 1UL << base->shifterIndex[1]);
0491 
0492         if ((!((handle->state == (uint8_t)kFLEXIO_I2C_SendData) && (handle->transfer.dataSize == 0U))) &&
0493             (!(((handle->state == (uint8_t)kFLEXIO_I2C_ReceiveData) ||
0494                 (handle->state == (uint8_t)kFLEXIO_I2C_ReceiveDataBegin)) &&
0495                (handle->transfer.dataSize == 1U))))
0496         {
0497             (void)FLEXIO_I2C_MasterReadByte(base);
0498 
0499             FLEXIO_I2C_MasterAbortStop(base);
0500 
0501             /* Delay one clk cycle to ensure the bus is idle. */
0502             SDK_DelayAtLeastUs(1000000UL / base->baudrate, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
0503 
0504             handle->state = (uint8_t)kFLEXIO_I2C_Idle;
0505 
0506             return kStatus_FLEXIO_I2C_Nak;
0507         }
0508     }
0509 
0510     if (((statusFlags & (uint8_t)kFLEXIO_I2C_RxFullFlag) != 0U) && (handle->state != (uint8_t)kFLEXIO_I2C_ReceiveData))
0511     {
0512         (void)FLEXIO_I2C_MasterReadByte(base);
0513     }
0514 
0515     switch (handle->state)
0516     {
0517         /* Initial state, i2c start state. */
0518         case (uint8_t)kFLEXIO_I2C_Start:
0519             /* Send address byte first. */
0520             FLEXIO_I2C_MasterTransferStateMachineStart(base, handle);
0521             break;
0522 
0523         /* Check address only needed for transfer with subaddress */
0524         case (uint8_t)kFLEXIO_I2C_SendCommand:
0525             if (false == FLEXIO_I2C_MasterTransferStateMachineSendCommand(base, handle, statusFlags))
0526             {
0527                 return kStatus_FLEXIO_I2C_Timeout;
0528             }
0529             break;
0530 
0531         /* Send command byte. */
0532         case (uint8_t)kFLEXIO_I2C_SendData:
0533             if (false == FLEXIO_I2C_MasterTransferStateMachineSendData(base, handle, statusFlags))
0534             {
0535                 return kStatus_FLEXIO_I2C_Timeout;
0536             }
0537             break;
0538 
0539         case (uint8_t)kFLEXIO_I2C_ReceiveDataBegin:
0540             if (false == FLEXIO_I2C_MasterTransferStateMachineReceiveDataBegin(base, handle, statusFlags))
0541             {
0542                 return kStatus_FLEXIO_I2C_Timeout;
0543             }
0544             break;
0545 
0546         case (uint8_t)kFLEXIO_I2C_ReceiveData:
0547             status = FLEXIO_I2C_MasterTransferStateMachineReceiveData(base, handle, statusFlags);
0548             if (kStatus_Success != status)
0549             {
0550                 return status;
0551             }
0552             break;
0553 
0554         default:
0555             /* Add comment to avoid MISRA violation */
0556             break;
0557     }
0558 
0559     return kStatus_Success;
0560 }
0561 
0562 static void FLEXIO_I2C_MasterTransferComplete(FLEXIO_I2C_Type *base,
0563                                               flexio_i2c_master_handle_t *handle,
0564                                               status_t status)
0565 {
0566     FLEXIO_I2C_MasterDisableInterrupts(
0567         base, (uint32_t)kFLEXIO_I2C_TxEmptyInterruptEnable | (uint32_t)kFLEXIO_I2C_RxFullInterruptEnable);
0568 
0569     if (handle->completionCallback != NULL)
0570     {
0571         handle->completionCallback(base, handle, status, handle->userData);
0572     }
0573 }
0574 
0575 #if defined(FSL_FEATURE_FLEXIO_HAS_PIN_STATUS) && FSL_FEATURE_FLEXIO_HAS_PIN_STATUS
0576 /*!
0577  * brief Make sure the bus isn't already pulled down.
0578  *
0579  * Check the FLEXIO pin status to see whether either of SDA and SCL pin is pulled down.
0580  *
0581  * param base Pointer to FLEXIO_I2C_Type structure.
0582  * retval kStatus_Success
0583  * retval kStatus_FLEXIO_I2C_Busy
0584  */
0585 status_t FLEXIO_I2C_CheckForBusyBus(FLEXIO_I2C_Type *base)
0586 {
0587     uint32_t mask;
0588     /* If in certain loops the SDA/SCL is continuously pulled down, then return bus busy status. */
0589     /* The loop count is determined by maximum CPU clock frequency */
0590     for (uint32_t i = 0U; i < SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY / 600000U; ++i)
0591     {
0592         mask = 1UL << base->SDAPinIndex | 1UL << base->SCLPinIndex;
0593         if ((FLEXIO_ReadPinInput(base->flexioBase) & mask) == mask)
0594         {
0595             return kStatus_Success;
0596         }
0597     }
0598     return kStatus_FLEXIO_I2C_Busy;
0599 }
0600 #endif /*FSL_FEATURE_FLEXIO_HAS_PIN_STATUS*/
0601 
0602 /*!
0603  * brief Ungates the FlexIO clock, resets the FlexIO module, and configures the FlexIO I2C
0604  * hardware configuration.
0605  *
0606  * Example
0607    code
0608    FLEXIO_I2C_Type base = {
0609    .flexioBase = FLEXIO,
0610    .SDAPinIndex = 0,
0611    .SCLPinIndex = 1,
0612    .shifterIndex = {0,1},
0613    .timerIndex = {0,1}
0614    };
0615    flexio_i2c_master_config_t config = {
0616    .enableInDoze = false,
0617    .enableInDebug = true,
0618    .enableFastAccess = false,
0619    .baudRate_Bps = 100000
0620    };
0621    FLEXIO_I2C_MasterInit(base, &config, srcClock_Hz);
0622    endcode
0623  *
0624  * param base Pointer to FLEXIO_I2C_Type structure.
0625  * param masterConfig Pointer to flexio_i2c_master_config_t structure.
0626  * param srcClock_Hz FlexIO source clock in Hz.
0627  * retval kStatus_Success Initialization successful
0628  * retval kStatus_InvalidArgument The source clock exceed upper range limitation
0629 */
0630 status_t FLEXIO_I2C_MasterInit(FLEXIO_I2C_Type *base, flexio_i2c_master_config_t *masterConfig, uint32_t srcClock_Hz)
0631 {
0632     assert((base != NULL) && (masterConfig != NULL));
0633 
0634     flexio_shifter_config_t shifterConfig;
0635     flexio_timer_config_t timerConfig;
0636     uint32_t controlVal = 0;
0637     uint16_t timerDiv   = 0;
0638     status_t result     = kStatus_Success;
0639 
0640     (void)memset(&shifterConfig, 0, sizeof(shifterConfig));
0641     (void)memset(&timerConfig, 0, sizeof(timerConfig));
0642 
0643 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0644     /* Ungate flexio clock. */
0645     CLOCK_EnableClock(s_flexioClocks[FLEXIO_I2C_GetInstance(base)]);
0646 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
0647 
0648     /* Do hardware configuration. */
0649     /* 1. Configure the shifter 0 for tx. */
0650     shifterConfig.timerSelect   = base->timerIndex[2];
0651     shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive;
0652     shifterConfig.pinConfig     = kFLEXIO_PinConfigOpenDrainOrBidirection;
0653     shifterConfig.pinSelect     = base->SDAPinIndex;
0654     shifterConfig.pinPolarity   = kFLEXIO_PinActiveLow;
0655     shifterConfig.shifterMode   = kFLEXIO_ShifterModeTransmit;
0656     shifterConfig.inputSource   = kFLEXIO_ShifterInputFromPin;
0657     shifterConfig.shifterStop   = kFLEXIO_ShifterStopBitHigh;
0658     shifterConfig.shifterStart  = kFLEXIO_ShifterStartBitLow;
0659 
0660     FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[0], &shifterConfig);
0661 
0662     /* 2. Configure the shifter 1 for rx. */
0663     shifterConfig.timerSelect   = base->timerIndex[2];
0664     shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive;
0665     shifterConfig.pinConfig     = kFLEXIO_PinConfigOutputDisabled;
0666     shifterConfig.pinSelect     = base->SDAPinIndex;
0667     shifterConfig.pinPolarity   = kFLEXIO_PinActiveHigh;
0668     shifterConfig.shifterMode   = kFLEXIO_ShifterModeReceive;
0669     shifterConfig.inputSource   = kFLEXIO_ShifterInputFromPin;
0670     shifterConfig.shifterStop   = kFLEXIO_ShifterStopBitLow;
0671     shifterConfig.shifterStart  = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable;
0672 
0673     FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[1], &shifterConfig);
0674 
0675     /*3. Configure the timer 0 and timer 1 for generating bit clock. */
0676     /* timer 1 is used to config baudrate */
0677     timerConfig.triggerSelect   = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(base->shifterIndex[0]);
0678     timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow;
0679     timerConfig.triggerSource   = kFLEXIO_TimerTriggerSourceInternal;
0680     timerConfig.pinConfig       = kFLEXIO_PinConfigOpenDrainOrBidirection;
0681     timerConfig.pinSelect       = base->SCLPinIndex;
0682     timerConfig.pinPolarity     = kFLEXIO_PinActiveHigh;
0683     timerConfig.timerMode       = kFLEXIO_TimerModeSingle16Bit;
0684     timerConfig.timerOutput     = kFLEXIO_TimerOutputZeroNotAffectedByReset;
0685     timerConfig.timerDecrement  = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput;
0686     timerConfig.timerReset      = kFLEXIO_TimerResetOnTimerPinEqualToTimerOutput;
0687     timerConfig.timerDisable    = kFLEXIO_TimerDisableOnPreTimerDisable;
0688     timerConfig.timerEnable     = kFLEXIO_TimerEnableOnTriggerHigh;
0689     timerConfig.timerStop       = kFLEXIO_TimerStopBitDisabled;
0690     timerConfig.timerStart      = kFLEXIO_TimerStartBitDisabled;
0691 
0692     /* Set TIMCMP = (baud rate divider / 2) - 1. */
0693     timerDiv = (uint16_t)(srcClock_Hz / masterConfig->baudRate_Bps) / 2U - 1U;
0694     /* Calculate and assign the actual baudrate. */
0695     base->baudrate = srcClock_Hz / (2U * ((uint32_t)timerDiv + 1U));
0696 
0697     timerConfig.timerCompare = timerDiv;
0698 
0699     FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[1], &timerConfig);
0700 
0701     /* timer 0 is used to config total shift clock edges */
0702     timerConfig.triggerSelect   = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(base->shifterIndex[0]);
0703     timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow;
0704     timerConfig.triggerSource   = kFLEXIO_TimerTriggerSourceInternal;
0705     timerConfig.pinConfig       = kFLEXIO_PinConfigOutputDisabled;
0706     timerConfig.pinSelect       = base->SCLPinIndex;
0707     timerConfig.pinPolarity     = kFLEXIO_PinActiveHigh;
0708     timerConfig.timerMode       = kFLEXIO_TimerModeSingle16Bit;
0709     timerConfig.timerOutput     = kFLEXIO_TimerOutputOneNotAffectedByReset;
0710     timerConfig.timerDecrement  = kFLEXIO_TimerDecSrcOnPinInputShiftPinInput;
0711     timerConfig.timerReset      = kFLEXIO_TimerResetNever;
0712     timerConfig.timerDisable    = kFLEXIO_TimerDisableOnTimerCompare;
0713     timerConfig.timerEnable     = kFLEXIO_TimerEnableOnTriggerHigh;
0714     timerConfig.timerStop       = kFLEXIO_TimerStopBitDisabled;
0715     timerConfig.timerStart      = kFLEXIO_TimerStartBitDisabled;
0716 
0717     /* Set TIMCMP when confinguring transfer bytes. */
0718     FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[0], &timerConfig);
0719 
0720     /* 4. Configure the timer 2 for controlling shifters. */
0721     timerConfig.triggerSelect   = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(base->shifterIndex[0]);
0722     timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow;
0723     timerConfig.triggerSource   = kFLEXIO_TimerTriggerSourceInternal;
0724     timerConfig.pinConfig       = kFLEXIO_PinConfigOutputDisabled;
0725     timerConfig.pinSelect       = base->SCLPinIndex;
0726     timerConfig.pinPolarity     = kFLEXIO_PinActiveLow;
0727     timerConfig.timerMode       = kFLEXIO_TimerModeSingle16Bit;
0728     timerConfig.timerOutput     = kFLEXIO_TimerOutputOneNotAffectedByReset;
0729     timerConfig.timerDecrement  = kFLEXIO_TimerDecSrcOnPinInputShiftPinInput;
0730     timerConfig.timerReset      = kFLEXIO_TimerResetNever;
0731     timerConfig.timerDisable    = kFLEXIO_TimerDisableOnPreTimerDisable;
0732     timerConfig.timerEnable     = kFLEXIO_TimerEnableOnPrevTimerEnable;
0733     timerConfig.timerStop       = kFLEXIO_TimerStopBitEnableOnTimerCompare;
0734     timerConfig.timerStart      = kFLEXIO_TimerStartBitEnabled;
0735 
0736     /* Set TIMCMP[15:0] = (number of bits x 2) - 1. */
0737     timerConfig.timerCompare = 8U * 2U - 1U;
0738 
0739     FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[2], &timerConfig);
0740 
0741     /* Configure FLEXIO I2C Master. */
0742     controlVal = base->flexioBase->CTRL;
0743     controlVal &=
0744         ~(FLEXIO_CTRL_DOZEN_MASK | FLEXIO_CTRL_DBGE_MASK | FLEXIO_CTRL_FASTACC_MASK | FLEXIO_CTRL_FLEXEN_MASK);
0745     controlVal |= (FLEXIO_CTRL_DBGE(masterConfig->enableInDebug) | FLEXIO_CTRL_FASTACC(masterConfig->enableFastAccess) |
0746                    FLEXIO_CTRL_FLEXEN(masterConfig->enableMaster));
0747     if (!masterConfig->enableInDoze)
0748     {
0749         controlVal |= FLEXIO_CTRL_DOZEN_MASK;
0750     }
0751 
0752     base->flexioBase->CTRL = controlVal;
0753     /* Disable internal IRQs. */
0754     FLEXIO_I2C_MasterDisableInterrupts(
0755         base, (uint32_t)kFLEXIO_I2C_TxEmptyInterruptEnable | (uint32_t)kFLEXIO_I2C_RxFullInterruptEnable);
0756     return result;
0757 }
0758 
0759 /*!
0760  * brief De-initializes the FlexIO I2C master peripheral. Calling this API Resets the FlexIO I2C master
0761  * shifer and timer config, module can't work unless the FLEXIO_I2C_MasterInit is called.
0762  *
0763  * param base pointer to FLEXIO_I2C_Type structure.
0764  */
0765 void FLEXIO_I2C_MasterDeinit(FLEXIO_I2C_Type *base)
0766 {
0767     base->flexioBase->SHIFTCFG[base->shifterIndex[0]] = 0;
0768     base->flexioBase->SHIFTCTL[base->shifterIndex[0]] = 0;
0769     base->flexioBase->SHIFTCFG[base->shifterIndex[1]] = 0;
0770     base->flexioBase->SHIFTCTL[base->shifterIndex[1]] = 0;
0771     base->flexioBase->TIMCFG[base->timerIndex[0]]     = 0;
0772     base->flexioBase->TIMCMP[base->timerIndex[0]]     = 0;
0773     base->flexioBase->TIMCTL[base->timerIndex[0]]     = 0;
0774     base->flexioBase->TIMCFG[base->timerIndex[1]]     = 0;
0775     base->flexioBase->TIMCMP[base->timerIndex[1]]     = 0;
0776     base->flexioBase->TIMCTL[base->timerIndex[1]]     = 0;
0777     base->flexioBase->TIMCFG[base->timerIndex[2]]     = 0;
0778     base->flexioBase->TIMCMP[base->timerIndex[2]]     = 0;
0779     base->flexioBase->TIMCTL[base->timerIndex[2]]     = 0;
0780     /* Clear the shifter flag. */
0781     base->flexioBase->SHIFTSTAT = (1UL << base->shifterIndex[0]);
0782     base->flexioBase->SHIFTSTAT = (1UL << base->shifterIndex[1]);
0783     /* Clear the timer flag. */
0784     base->flexioBase->TIMSTAT = (1UL << base->timerIndex[0]);
0785     base->flexioBase->TIMSTAT = (1UL << base->timerIndex[1]);
0786     base->flexioBase->TIMSTAT = (1UL << base->timerIndex[2]);
0787 }
0788 
0789 /*!
0790  * brief Gets the default configuration to configure the FlexIO module. The configuration
0791  * can be used directly for calling the FLEXIO_I2C_MasterInit().
0792  *
0793  * Example:
0794    code
0795    flexio_i2c_master_config_t config;
0796    FLEXIO_I2C_MasterGetDefaultConfig(&config);
0797    endcode
0798  * param masterConfig Pointer to flexio_i2c_master_config_t structure.
0799 */
0800 void FLEXIO_I2C_MasterGetDefaultConfig(flexio_i2c_master_config_t *masterConfig)
0801 {
0802     assert(masterConfig != NULL);
0803 
0804     /* Initializes the configure structure to zero. */
0805     (void)memset(masterConfig, 0, sizeof(*masterConfig));
0806 
0807     masterConfig->enableMaster     = true;
0808     masterConfig->enableInDoze     = false;
0809     masterConfig->enableInDebug    = true;
0810     masterConfig->enableFastAccess = false;
0811 
0812     /* Default baud rate at 100kbps. */
0813     masterConfig->baudRate_Bps = 100000U;
0814 }
0815 
0816 /*!
0817  * brief Gets the FlexIO I2C master status flags.
0818  *
0819  * param base Pointer to FLEXIO_I2C_Type structure
0820  * return Status flag, use status flag to AND #_flexio_i2c_master_status_flags can get the related status.
0821  */
0822 
0823 uint32_t FLEXIO_I2C_MasterGetStatusFlags(FLEXIO_I2C_Type *base)
0824 {
0825     uint32_t status = 0;
0826 
0827     status =
0828         ((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1UL << base->shifterIndex[0])) >> base->shifterIndex[0]);
0829     status |=
0830         (((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1UL << base->shifterIndex[1])) >> (base->shifterIndex[1]))
0831          << 1U);
0832     status |=
0833         (((FLEXIO_GetShifterErrorFlags(base->flexioBase) & (1UL << base->shifterIndex[1])) >> (base->shifterIndex[1]))
0834          << 2U);
0835 
0836     return status;
0837 }
0838 
0839 /*!
0840  * brief Clears the FlexIO I2C master status flags.
0841  *
0842  * param base Pointer to FLEXIO_I2C_Type structure.
0843  * param mask Status flag.
0844  *      The parameter can be any combination of the following values:
0845  *          arg kFLEXIO_I2C_RxFullFlag
0846  *          arg kFLEXIO_I2C_ReceiveNakFlag
0847  */
0848 
0849 void FLEXIO_I2C_MasterClearStatusFlags(FLEXIO_I2C_Type *base, uint32_t mask)
0850 {
0851     if ((mask & (uint32_t)kFLEXIO_I2C_TxEmptyFlag) != 0U)
0852     {
0853         FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1UL << base->shifterIndex[0]);
0854     }
0855 
0856     if ((mask & (uint32_t)kFLEXIO_I2C_RxFullFlag) != 0U)
0857     {
0858         FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1UL << base->shifterIndex[1]);
0859     }
0860 
0861     if ((mask & (uint32_t)kFLEXIO_I2C_ReceiveNakFlag) != 0U)
0862     {
0863         FLEXIO_ClearShifterErrorFlags(base->flexioBase, 1UL << base->shifterIndex[1]);
0864     }
0865 }
0866 
0867 /*!
0868  * brief Enables the FlexIO i2c master interrupt requests.
0869  *
0870  * param base Pointer to FLEXIO_I2C_Type structure.
0871  * param mask Interrupt source.
0872  *     Currently only one interrupt request source:
0873  *     arg kFLEXIO_I2C_TransferCompleteInterruptEnable
0874  */
0875 void FLEXIO_I2C_MasterEnableInterrupts(FLEXIO_I2C_Type *base, uint32_t mask)
0876 {
0877     if ((mask & (uint32_t)kFLEXIO_I2C_TxEmptyInterruptEnable) != 0U)
0878     {
0879         FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1UL << base->shifterIndex[0]);
0880     }
0881     if ((mask & (uint32_t)kFLEXIO_I2C_RxFullInterruptEnable) != 0U)
0882     {
0883         FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1UL << base->shifterIndex[1]);
0884     }
0885 }
0886 
0887 /*!
0888  * brief Disables the FlexIO I2C master interrupt requests.
0889  *
0890  * param base Pointer to FLEXIO_I2C_Type structure.
0891  * param mask Interrupt source.
0892  */
0893 void FLEXIO_I2C_MasterDisableInterrupts(FLEXIO_I2C_Type *base, uint32_t mask)
0894 {
0895     if ((mask & (uint32_t)kFLEXIO_I2C_TxEmptyInterruptEnable) != 0U)
0896     {
0897         FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1UL << base->shifterIndex[0]);
0898     }
0899     if ((mask & (uint32_t)kFLEXIO_I2C_RxFullInterruptEnable) != 0U)
0900     {
0901         FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1UL << base->shifterIndex[1]);
0902     }
0903 }
0904 
0905 /*!
0906  * brief Sets the FlexIO I2C master transfer baudrate.
0907  *
0908  * param base Pointer to FLEXIO_I2C_Type structure
0909  * param baudRate_Bps the baud rate value in HZ
0910  * param srcClock_Hz source clock in HZ
0911  */
0912 void FLEXIO_I2C_MasterSetBaudRate(FLEXIO_I2C_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz)
0913 {
0914     uint16_t timerDiv       = 0;
0915     FLEXIO_Type *flexioBase = base->flexioBase;
0916 
0917     /* Set TIMCMP = (baud rate divider / 2) - 1.*/
0918     timerDiv = (uint16_t)((srcClock_Hz / baudRate_Bps) / 2U - 1U);
0919 
0920     flexioBase->TIMCMP[base->timerIndex[1]] = timerDiv;
0921 
0922     /* Calculate and assign the actual baudrate. */
0923     base->baudrate = srcClock_Hz / (2U * ((uint32_t)timerDiv + 1U));
0924 }
0925 
0926 /*!
0927  * brief Sets the number of bytes to be transferred from a start signal to a stop signal.
0928  *
0929  * note Call this API before a transfer begins because the timer generates a number of clocks according
0930  * to the number of bytes that need to be transferred.
0931  *
0932  * param base Pointer to FLEXIO_I2C_Type structure.
0933  * param count Number of bytes need to be transferred from a start signal to a re-start/stop signal
0934  * retval kStatus_Success Successfully configured the count.
0935  * retval kStatus_InvalidArgument Input argument is invalid.
0936  */
0937 status_t FLEXIO_I2C_MasterSetTransferCount(FLEXIO_I2C_Type *base, uint16_t count)
0938 {
0939     /* Calculate whether the transfer count is larger than the max value compare register can achieve */
0940     if (count > ((0xFFFFUL - 1UL) / (16UL + 1UL + 1UL)))
0941     {
0942         return kStatus_InvalidArgument;
0943     }
0944 
0945     uint32_t timerConfig    = 0U;
0946     FLEXIO_Type *flexioBase = base->flexioBase;
0947 
0948     flexioBase->TIMCMP[base->timerIndex[0]] = (uint32_t)count * 18U + 1U;
0949     timerConfig                             = flexioBase->TIMCFG[base->timerIndex[0]];
0950     timerConfig &= ~FLEXIO_TIMCFG_TIMDIS_MASK;
0951     timerConfig |= FLEXIO_TIMCFG_TIMDIS(kFLEXIO_TimerDisableOnTimerCompare);
0952     flexioBase->TIMCFG[base->timerIndex[0]] = timerConfig;
0953 
0954     return kStatus_Success;
0955 }
0956 
0957 /*!
0958  * brief Sends START + 7-bit address to the bus.
0959  *
0960  * note This API should be called when the transfer configuration is ready to send a START signal
0961  * and 7-bit address to the bus. This is a non-blocking API, which returns directly after the address
0962  * is put into the data register but the address transfer is not finished on the bus. Ensure that
0963  * the kFLEXIO_I2C_RxFullFlag status is asserted before calling this API.
0964  * param base Pointer to FLEXIO_I2C_Type structure.
0965  * param address 7-bit address.
0966  * param direction transfer direction.
0967  *     This parameter is one of the values in flexio_i2c_direction_t:
0968  *        arg kFLEXIO_I2C_Write: Transmit
0969  *        arg kFLEXIO_I2C_Read:  Receive
0970  */
0971 
0972 void FLEXIO_I2C_MasterStart(FLEXIO_I2C_Type *base, uint8_t address, flexio_i2c_direction_t direction)
0973 {
0974     uint32_t data;
0975 
0976     data = ((uint32_t)address) << 1U | ((direction == kFLEXIO_I2C_Read) ? 1U : 0U);
0977 
0978     FLEXIO_I2C_MasterWriteByte(base, data);
0979 }
0980 
0981 /*!
0982  * brief Sends the repeated start signal on the bus.
0983  *
0984  * param base Pointer to FLEXIO_I2C_Type structure.
0985  */
0986 void FLEXIO_I2C_MasterRepeatedStart(FLEXIO_I2C_Type *base)
0987 {
0988     /* Prepare for RESTART condition, no stop.*/
0989     FLEXIO_I2C_MasterWriteByte(base, 0xFFFFFFFFU);
0990 }
0991 
0992 /*!
0993  * brief Sends the stop signal on the bus.
0994  *
0995  * param base Pointer to FLEXIO_I2C_Type structure.
0996  */
0997 void FLEXIO_I2C_MasterStop(FLEXIO_I2C_Type *base)
0998 {
0999     /* Prepare normal stop. */
1000     (void)FLEXIO_I2C_MasterSetTransferCount(base, 0x0U);
1001     FLEXIO_I2C_MasterWriteByte(base, 0x0U);
1002 }
1003 
1004 /*!
1005  * brief Sends the stop signal when transfer is still on-going.
1006  *
1007  * param base Pointer to FLEXIO_I2C_Type structure.
1008  */
1009 void FLEXIO_I2C_MasterAbortStop(FLEXIO_I2C_Type *base)
1010 {
1011     uint32_t tmpConfig;
1012 
1013     /* Prepare abort stop. */
1014     /* Disable timer 0. */
1015     tmpConfig = base->flexioBase->TIMCFG[base->timerIndex[0]];
1016     tmpConfig &= ~FLEXIO_TIMCFG_TIMDIS_MASK;
1017     tmpConfig |= FLEXIO_TIMCFG_TIMDIS(kFLEXIO_TimerDisableOnPinBothEdge);
1018     base->flexioBase->TIMCFG[base->timerIndex[0]] = tmpConfig;
1019 
1020     /* Disable timer 1. */
1021     tmpConfig = base->flexioBase->TIMCFG[base->timerIndex[1]];
1022     tmpConfig &= ~FLEXIO_TIMCFG_TIMDIS_MASK;
1023     tmpConfig |= FLEXIO_TIMCFG_TIMDIS(kFLEXIO_TimerDisableOnPinBothEdge);
1024     base->flexioBase->TIMCFG[base->timerIndex[1]] = tmpConfig;
1025 }
1026 
1027 /*!
1028  * brief Configures the sent ACK/NAK for the following byte.
1029  *
1030  * param base Pointer to FLEXIO_I2C_Type structure.
1031  * param enable True to configure send ACK, false configure to send NAK.
1032  */
1033 void FLEXIO_I2C_MasterEnableAck(FLEXIO_I2C_Type *base, bool enable)
1034 {
1035     uint32_t tmpConfig = 0;
1036 
1037     tmpConfig = base->flexioBase->SHIFTCFG[base->shifterIndex[0]];
1038     tmpConfig &= ~FLEXIO_SHIFTCFG_SSTOP_MASK;
1039     if (enable)
1040     {
1041         tmpConfig |= FLEXIO_SHIFTCFG_SSTOP(kFLEXIO_ShifterStopBitLow);
1042     }
1043     else
1044     {
1045         tmpConfig |= FLEXIO_SHIFTCFG_SSTOP(kFLEXIO_ShifterStopBitHigh);
1046     }
1047     base->flexioBase->SHIFTCFG[base->shifterIndex[0]] = tmpConfig;
1048 }
1049 
1050 /*!
1051  * brief Sends a buffer of data in bytes.
1052  *
1053  * note This function blocks via polling until all bytes have been sent.
1054  *
1055  * param base Pointer to FLEXIO_I2C_Type structure.
1056  * param txBuff The data bytes to send.
1057  * param txSize The number of data bytes to send.
1058  * retval kStatus_Success Successfully write data.
1059  * retval kStatus_FLEXIO_I2C_Nak Receive NAK during writing data.
1060  * retval kStatus_FLEXIO_I2C_Timeout Timeout polling status flags.
1061  */
1062 status_t FLEXIO_I2C_MasterWriteBlocking(FLEXIO_I2C_Type *base, const uint8_t *txBuff, uint8_t txSize)
1063 {
1064     assert(txBuff != NULL);
1065     assert(txSize != 0U);
1066 
1067     uint32_t status;
1068 #if I2C_RETRY_TIMES
1069     uint32_t waitTimes = I2C_RETRY_TIMES;
1070 #endif
1071 
1072     while (0U != txSize--)
1073     {
1074         FLEXIO_I2C_MasterWriteByte(base, *txBuff++);
1075 
1076         /* Wait until data transfer complete. */
1077 #if I2C_RETRY_TIMES
1078         waitTimes = I2C_RETRY_TIMES;
1079         while ((0U == ((status = FLEXIO_I2C_MasterGetStatusFlags(base)) & (uint32_t)kFLEXIO_I2C_RxFullFlag)) &&
1080                (0U != --waitTimes))
1081         {
1082         }
1083         if (0U == waitTimes)
1084         {
1085             return kStatus_FLEXIO_I2C_Timeout;
1086         }
1087 #else
1088         while (0U == ((status = FLEXIO_I2C_MasterGetStatusFlags(base)) & (uint32_t)kFLEXIO_I2C_RxFullFlag))
1089         {
1090         }
1091 #endif
1092 
1093         if ((status & (uint32_t)kFLEXIO_I2C_ReceiveNakFlag) != 0U)
1094         {
1095             FLEXIO_ClearShifterErrorFlags(base->flexioBase, 1UL << base->shifterIndex[1]);
1096             return kStatus_FLEXIO_I2C_Nak;
1097         }
1098     }
1099     return kStatus_Success;
1100 }
1101 
1102 /*!
1103  * brief Receives a buffer of bytes.
1104  *
1105  * note This function blocks via polling until all bytes have been received.
1106  *
1107  * param base Pointer to FLEXIO_I2C_Type structure.
1108  * param rxBuff The buffer to store the received bytes.
1109  * param rxSize The number of data bytes to be received.
1110  * retval kStatus_Success Successfully read data.
1111  * retval kStatus_FLEXIO_I2C_Timeout Timeout polling status flags.
1112  */
1113 status_t FLEXIO_I2C_MasterReadBlocking(FLEXIO_I2C_Type *base, uint8_t *rxBuff, uint8_t rxSize)
1114 {
1115     assert(rxBuff != NULL);
1116     assert(rxSize != 0U);
1117 
1118 #if I2C_RETRY_TIMES
1119     uint32_t waitTimes = I2C_RETRY_TIMES;
1120 #endif
1121 
1122     while (0U != rxSize--)
1123     {
1124         /* Wait until data transfer complete. */
1125 #if I2C_RETRY_TIMES
1126         waitTimes = I2C_RETRY_TIMES;
1127         while ((0U == (FLEXIO_I2C_MasterGetStatusFlags(base) & (uint32_t)kFLEXIO_I2C_RxFullFlag)) &&
1128                (0U != --waitTimes))
1129         {
1130         }
1131         if (0U == waitTimes)
1132         {
1133             return kStatus_FLEXIO_I2C_Timeout;
1134         }
1135 #else
1136         while (0U == (FLEXIO_I2C_MasterGetStatusFlags(base) & (uint32_t)kFLEXIO_I2C_RxFullFlag))
1137         {
1138         }
1139 #endif
1140         *rxBuff++ = FLEXIO_I2C_MasterReadByte(base);
1141     }
1142     return kStatus_Success;
1143 }
1144 
1145 /*!
1146  * brief Performs a master polling transfer on the I2C bus.
1147  *
1148  * note The API does not return until the transfer succeeds or fails due
1149  * to receiving NAK.
1150  *
1151  * param base pointer to FLEXIO_I2C_Type structure.
1152  * param xfer pointer to flexio_i2c_master_transfer_t structure.
1153  * return status of status_t.
1154  */
1155 status_t FLEXIO_I2C_MasterTransferBlocking(FLEXIO_I2C_Type *base, flexio_i2c_master_transfer_t *xfer)
1156 {
1157     assert(xfer != NULL);
1158 
1159 #if defined(FSL_FEATURE_FLEXIO_HAS_PIN_STATUS) && FSL_FEATURE_FLEXIO_HAS_PIN_STATUS
1160     /* Return an error if the bus is already in use not by us.*/
1161     status_t status = FLEXIO_I2C_CheckForBusyBus(base);
1162     if (status != kStatus_Success)
1163     {
1164         return status;
1165     }
1166 #endif /*FSL_FEATURE_FLEXIO_HAS_PIN_STATUS*/
1167 
1168     flexio_i2c_master_handle_t tmpHandle;
1169     uint32_t statusFlags;
1170     status_t result = kStatus_Success;
1171 #if I2C_RETRY_TIMES
1172     uint32_t waitTimes = I2C_RETRY_TIMES;
1173 #endif
1174 
1175     /* Zero the handle. */
1176     (void)memset(&tmpHandle, 0, sizeof(tmpHandle));
1177 
1178     /* Set up transfer machine. */
1179     result = FLEXIO_I2C_MasterTransferInitStateMachine(base, &tmpHandle, xfer);
1180     if (result != kStatus_Success)
1181     {
1182         return result;
1183     }
1184 
1185     do
1186     {
1187         /* Wait either tx empty or rx full flag is asserted. */
1188 #if I2C_RETRY_TIMES
1189         waitTimes = I2C_RETRY_TIMES;
1190         while ((0U == ((statusFlags = FLEXIO_I2C_MasterGetStatusFlags(base)) &
1191                        ((uint32_t)kFLEXIO_I2C_TxEmptyFlag | (uint32_t)kFLEXIO_I2C_RxFullFlag))) &&
1192                (0U != --waitTimes))
1193         {
1194         }
1195         if (0U == waitTimes)
1196         {
1197             return kStatus_FLEXIO_I2C_Timeout;
1198         }
1199 #else
1200         while (0U == ((statusFlags = FLEXIO_I2C_MasterGetStatusFlags(base)) &
1201                       ((uint32_t)kFLEXIO_I2C_TxEmptyFlag | (uint32_t)kFLEXIO_I2C_RxFullFlag)))
1202         {
1203         }
1204 #endif
1205         FLEXIO_ClearTimerStatusFlags(base->flexioBase, ((1UL << base->timerIndex[0]) | (1UL << base->timerIndex[1])));
1206         result = FLEXIO_I2C_MasterTransferRunStateMachine(base, &tmpHandle, statusFlags);
1207 
1208     } while ((tmpHandle.state != (uint8_t)kFLEXIO_I2C_Idle) && (result == kStatus_Success));
1209 
1210     /* Timer disable on timer compare, wait until bit clock TSF set, which means timer disable and stop has been sent.
1211      */
1212     while (0U == (FLEXIO_GetTimerStatusFlags(base->flexioBase) & (1UL << base->timerIndex[1])))
1213     {
1214     }
1215 
1216     return result;
1217 }
1218 
1219 /*!
1220  * brief Initializes the I2C handle which is used in transactional functions.
1221  *
1222  * param base Pointer to FLEXIO_I2C_Type structure.
1223  * param handle Pointer to flexio_i2c_master_handle_t structure to store the transfer state.
1224  * param callback Pointer to user callback function.
1225  * param userData User param passed to the callback function.
1226  * retval kStatus_Success Successfully create the handle.
1227  * retval kStatus_OutOfRange The FlexIO type/handle/isr table out of range.
1228  */
1229 status_t FLEXIO_I2C_MasterTransferCreateHandle(FLEXIO_I2C_Type *base,
1230                                                flexio_i2c_master_handle_t *handle,
1231                                                flexio_i2c_master_transfer_callback_t callback,
1232                                                void *userData)
1233 {
1234     assert(handle != NULL);
1235 
1236     IRQn_Type flexio_irqs[] = FLEXIO_IRQS;
1237 
1238     /* Zero the handle. */
1239     (void)memset(handle, 0, sizeof(*handle));
1240 
1241     /* Register callback and userData. */
1242     handle->completionCallback = callback;
1243     handle->userData           = userData;
1244 
1245     /* Clear pending NVIC IRQ before enable NVIC IRQ. */
1246     NVIC_ClearPendingIRQ(flexio_irqs[FLEXIO_I2C_GetInstance(base)]);
1247     (void)EnableIRQ(flexio_irqs[FLEXIO_I2C_GetInstance(base)]);
1248 
1249     /* Save the context in global variables to support the double weak mechanism. */
1250     return FLEXIO_RegisterHandleIRQ(base, handle, FLEXIO_I2C_MasterTransferHandleIRQ);
1251 }
1252 
1253 /*!
1254  * brief Performs a master interrupt non-blocking transfer on the I2C bus.
1255  *
1256  * note The API returns immediately after the transfer initiates.
1257  * Call FLEXIO_I2C_MasterTransferGetCount to poll the transfer status to check whether
1258  * the transfer is finished. If the return status is not kStatus_FLEXIO_I2C_Busy, the transfer
1259  * is finished.
1260  *
1261  * param base Pointer to FLEXIO_I2C_Type structure
1262  * param handle Pointer to flexio_i2c_master_handle_t structure which stores the transfer state
1263  * param xfer pointer to flexio_i2c_master_transfer_t structure
1264  * retval kStatus_Success Successfully start a transfer.
1265  * retval kStatus_FLEXIO_I2C_Busy FlexIO I2C is not idle, is running another transfer.
1266  */
1267 status_t FLEXIO_I2C_MasterTransferNonBlocking(FLEXIO_I2C_Type *base,
1268                                               flexio_i2c_master_handle_t *handle,
1269                                               flexio_i2c_master_transfer_t *xfer)
1270 {
1271     assert(handle != NULL);
1272     assert(xfer != NULL);
1273 
1274     status_t result = kStatus_Success;
1275 
1276 #if defined(FSL_FEATURE_FLEXIO_HAS_PIN_STATUS) && FSL_FEATURE_FLEXIO_HAS_PIN_STATUS
1277     /* Return an error if the bus is already in use not by us.*/
1278     result = FLEXIO_I2C_CheckForBusyBus(base);
1279     if (result != kStatus_Success)
1280     {
1281         return result;
1282     }
1283 #endif /*FSL_FEATURE_FLEXIO_HAS_PIN_STATUS*/
1284 
1285     if (handle->state != (uint8_t)kFLEXIO_I2C_Idle)
1286     {
1287         return kStatus_FLEXIO_I2C_Busy;
1288     }
1289     else
1290     {
1291         /* Set up transfer machine. */
1292         result = FLEXIO_I2C_MasterTransferInitStateMachine(base, handle, xfer);
1293         if (result != kStatus_Success)
1294         {
1295             return result;
1296         }
1297 
1298         /* Enable both tx empty and rxfull interrupt. */
1299         FLEXIO_I2C_MasterEnableInterrupts(
1300             base, (uint32_t)kFLEXIO_I2C_TxEmptyInterruptEnable | (uint32_t)kFLEXIO_I2C_RxFullInterruptEnable);
1301 
1302         return kStatus_Success;
1303     }
1304 }
1305 
1306 /*!
1307  * brief Aborts an interrupt non-blocking transfer early.
1308  *
1309  * note This API can be called at any time when an interrupt non-blocking transfer initiates
1310  * to abort the transfer early.
1311  *
1312  * param base Pointer to FLEXIO_I2C_Type structure
1313  * param handle Pointer to flexio_i2c_master_handle_t structure which stores the transfer state
1314  */
1315 void FLEXIO_I2C_MasterTransferAbort(FLEXIO_I2C_Type *base, flexio_i2c_master_handle_t *handle)
1316 {
1317     assert(handle != NULL);
1318 
1319     /* Disable interrupts. */
1320     FLEXIO_I2C_MasterDisableInterrupts(
1321         base, (uint32_t)kFLEXIO_I2C_TxEmptyInterruptEnable | (uint32_t)kFLEXIO_I2C_RxFullInterruptEnable);
1322 
1323     /* Reset to idle state. */
1324     handle->state = (uint8_t)kFLEXIO_I2C_Idle;
1325 }
1326 
1327 /*!
1328  * brief Gets the master transfer status during a interrupt non-blocking transfer.
1329  *
1330  * param base Pointer to FLEXIO_I2C_Type structure.
1331  * param handle Pointer to flexio_i2c_master_handle_t structure which stores the transfer state.
1332  * param count Number of bytes transferred so far by the non-blocking transaction.
1333  * retval kStatus_InvalidArgument count is Invalid.
1334  * retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress.
1335  * retval kStatus_Success Successfully return the count.
1336  */
1337 status_t FLEXIO_I2C_MasterTransferGetCount(FLEXIO_I2C_Type *base, flexio_i2c_master_handle_t *handle, size_t *count)
1338 {
1339     if (NULL == count)
1340     {
1341         return kStatus_InvalidArgument;
1342     }
1343 
1344     /* Catch when there is not an active transfer. */
1345     if (handle->state == (uint8_t)kFLEXIO_I2C_Idle)
1346     {
1347         *count = 0;
1348         return kStatus_NoTransferInProgress;
1349     }
1350 
1351     *count = handle->transferSize - handle->transfer.dataSize;
1352 
1353     return kStatus_Success;
1354 }
1355 
1356 /*!
1357  * brief Master interrupt handler.
1358  *
1359  * param i2cType Pointer to FLEXIO_I2C_Type structure
1360  * param i2cHandle Pointer to flexio_i2c_master_transfer_t structure
1361  */
1362 void FLEXIO_I2C_MasterTransferHandleIRQ(void *i2cType, void *i2cHandle)
1363 {
1364     FLEXIO_I2C_Type *base              = (FLEXIO_I2C_Type *)i2cType;
1365     flexio_i2c_master_handle_t *handle = (flexio_i2c_master_handle_t *)i2cHandle;
1366     uint32_t statusFlags;
1367     status_t result;
1368 
1369     statusFlags = FLEXIO_I2C_MasterGetStatusFlags(base);
1370 
1371     result = FLEXIO_I2C_MasterTransferRunStateMachine(base, handle, statusFlags);
1372 
1373     if (handle->state == (uint8_t)kFLEXIO_I2C_Idle)
1374     {
1375         FLEXIO_I2C_MasterTransferComplete(base, handle, result);
1376     }
1377 }