/* * Copyright 2019 NXP * All rights reserved. * * * SPDX-License-Identifier: BSD-3-Clause */ #include "fsl_common.h" #include "fsl_i2c.h" #include "fsl_adapter_i2c.h" /******************************************************************************* * Definitions ******************************************************************************/ /*! @brief i2c master state structure. */ typedef struct _hal_i2c_master { hal_i2c_master_transfer_callback_t callback; void *callbackParam; i2c_master_handle_t hardwareHandle; uint8_t instance; } hal_i2c_master_t; /*! @brief i2c slave state structure. */ typedef struct _hal_i2c_slave { hal_i2c_slave_transfer_callback_t callback; void *callbackParam; hal_i2c_slave_transfer_t transfer; i2c_slave_handle_t hardwareHandle; uint8_t instance; } hal_i2c_slave_t; /******************************************************************************* * Prototypes ******************************************************************************/ /******************************************************************************* * Variables ******************************************************************************/ /*! @brief Pointers to i2c bases for each instance. */ static I2C_Type *const s_i2cBases[] = I2C_BASE_PTRS; /******************************************************************************* * Code ******************************************************************************/ static hal_i2c_status_t HAL_I2cGetStatus(status_t status) { hal_i2c_status_t returnStatus; switch (status) { case kStatus_Success: { returnStatus = kStatus_HAL_I2cSuccess; /* Successfully */ break; } case kStatus_I2C_Busy: { returnStatus = kStatus_HAL_I2cBusy; /* HAL I2C is busy with current transfer */ break; } case kStatus_I2C_Idle: { returnStatus = kStatus_HAL_I2cIdle; /* HAL I2C transmitter is idle */ break; } case kStatus_I2C_Nak: { returnStatus = kStatus_HAL_I2cNak; /* NAK received during transfer */ break; } case kStatus_I2C_ArbitrationLost: { returnStatus = kStatus_HAL_I2cArbitrationLost; /* Arbitration lost during transfer */ break; } case kStatus_I2C_Timeout: { returnStatus = kStatus_HAL_I2cTimeout; /* Timeout */ break; } default: { returnStatus = kStatus_HAL_I2cError; /* Error occurs on HAL I2C */ break; } } return returnStatus; } static void HAL_I2cMasterCallback(I2C_Type *base, i2c_master_handle_t *handle, status_t status, void *callbackParam) { hal_i2c_master_t *i2cMasterHandle; assert(callbackParam); i2cMasterHandle = (hal_i2c_master_t *)callbackParam; if (NULL != i2cMasterHandle->callback) { i2cMasterHandle->callback(i2cMasterHandle, HAL_I2cGetStatus(status), i2cMasterHandle->callbackParam); /* Enter I2c master callback */ } } static void HAL_I2cSlaveCallback(I2C_Type *base, volatile i2c_slave_transfer_t *xfer, void *callbackParam) { hal_i2c_slave_t *i2cSlaveHandle; assert(callbackParam); i2cSlaveHandle = (hal_i2c_slave_t *)callbackParam; if (NULL != i2cSlaveHandle->callback) { i2cSlaveHandle->transfer.event = (hal_i2c_slave_transfer_event_t)xfer->event; i2cSlaveHandle->transfer.completionStatus = HAL_I2cGetStatus(xfer->completionStatus); i2cSlaveHandle->transfer.transferredCount = xfer->transferredCount; i2cSlaveHandle->callback(i2cSlaveHandle, &i2cSlaveHandle->transfer, i2cSlaveHandle->callbackParam); /* Enter I2c slave callback */ if (kI2C_SlaveTransmitEvent == xfer->event) { /*slave-transmitter role*/ xfer->txData = i2cSlaveHandle->transfer.data; xfer->txSize = i2cSlaveHandle->transfer.dataSize; } else { /*slave-receiver role*/ xfer->rxData = i2cSlaveHandle->transfer.data; xfer->rxSize = i2cSlaveHandle->transfer.dataSize; } } } hal_i2c_status_t HAL_I2cMasterInit(hal_i2c_master_handle_t handle, const hal_i2c_master_config_t *halI2cConfig) { hal_i2c_master_t *i2cMasterHandle; i2c_master_config_t i2cConfig; assert(handle); assert(halI2cConfig); assert(HAL_I2C_MASTER_HANDLE_SIZE >= sizeof(hal_i2c_master_t)); i2cMasterHandle = (hal_i2c_master_t *)handle; I2C_MasterGetDefaultConfig(&i2cConfig); /* Get a default configuration of master */ i2cConfig.enableMaster = halI2cConfig->enableMaster; i2cConfig.baudRate_Bps = halI2cConfig->baudRate_Bps; i2cMasterHandle->instance = halI2cConfig->instance; /* I2C Master initization*/ I2C_MasterInit(s_i2cBases[i2cMasterHandle->instance], &i2cConfig, halI2cConfig->srcClock_Hz); return kStatus_HAL_I2cSuccess; } hal_i2c_status_t HAL_I2cSlaveInit(hal_i2c_slave_handle_t handle, const hal_i2c_slave_config_t *halI2cConfig) { hal_i2c_slave_t *i2cSlaveHandle; i2c_slave_config_t i2cConfig; assert(handle); assert(halI2cConfig); assert(HAL_I2C_SLAVE_HANDLE_SIZE >= sizeof(hal_i2c_slave_t)); i2cSlaveHandle = (hal_i2c_slave_t *)handle; I2C_SlaveGetDefaultConfig(&i2cConfig); /* To get a default configuration of slave*/ i2cConfig.enableSlave = halI2cConfig->enableSlave; i2cConfig.address0.address = (uint8_t)halI2cConfig->slaveAddress; i2cSlaveHandle->instance = halI2cConfig->instance; /* I2C Slave initization*/ (void)I2C_SlaveInit(s_i2cBases[i2cSlaveHandle->instance], &i2cConfig, halI2cConfig->srcClock_Hz); return kStatus_HAL_I2cSuccess; } hal_i2c_status_t HAL_I2cMasterDeinit(hal_i2c_master_handle_t handle) { hal_i2c_master_t *i2cMasterHandle; assert(handle); i2cMasterHandle = (hal_i2c_master_t *)handle; I2C_MasterDeinit(s_i2cBases[i2cMasterHandle->instance]); /*Deinitializes the I2C master peripheral*/ return kStatus_HAL_I2cSuccess; } hal_i2c_status_t HAL_I2cSlaveDeinit(hal_i2c_slave_handle_t handle) { hal_i2c_slave_t *i2cSlaveHandle; assert(handle); i2cSlaveHandle = (hal_i2c_slave_t *)handle; I2C_SlaveDeinit(s_i2cBases[i2cSlaveHandle->instance]); /*Deinitializes the I2C slave peripheral*/ return kStatus_HAL_I2cSuccess; } hal_i2c_status_t HAL_I2cMasterWriteBlocking(hal_i2c_master_handle_t handle, const uint8_t *txBuff, size_t txSize, uint32_t flags) { hal_i2c_master_t *i2cMasterHandle; assert(handle); i2cMasterHandle = (hal_i2c_master_t *)handle; /*Performs a polling send transfer on the I2C bus*/ return HAL_I2cGetStatus(I2C_MasterWriteBlocking(s_i2cBases[i2cMasterHandle->instance], txBuff, txSize, flags)); } hal_i2c_status_t HAL_I2cMasterReadBlocking(hal_i2c_master_handle_t handle, uint8_t *rxBuff, size_t rxSize, uint32_t flags) { hal_i2c_master_t *i2cMasterHandle; assert(handle); i2cMasterHandle = (hal_i2c_master_t *)handle; return HAL_I2cGetStatus(I2C_MasterReadBlocking(s_i2cBases[i2cMasterHandle->instance], rxBuff, rxSize, flags)); } hal_i2c_status_t HAL_I2cSlaveWriteBlocking(hal_i2c_slave_handle_t handle, const uint8_t *txBuff, size_t txSize) { hal_i2c_slave_t *i2cSlaveHandle; assert(handle); i2cSlaveHandle = (hal_i2c_slave_t *)handle; /*Performs a polling receive transfer on the I2C bus.*/ return HAL_I2cGetStatus(I2C_SlaveWriteBlocking(s_i2cBases[i2cSlaveHandle->instance], txBuff, txSize)); } hal_i2c_status_t HAL_I2cSlaveReadBlocking(hal_i2c_slave_handle_t handle, uint8_t *rxBuff, size_t rxSize) { hal_i2c_slave_t *i2cSlaveHandle; assert(handle); i2cSlaveHandle = (hal_i2c_slave_t *)handle; return HAL_I2cGetStatus(I2C_SlaveReadBlocking(s_i2cBases[i2cSlaveHandle->instance], rxBuff, rxSize)); } hal_i2c_status_t HAL_I2cMasterTransferBlocking(hal_i2c_master_handle_t handle, hal_i2c_master_transfer_t *xfer) { hal_i2c_master_t *i2cMasterHandle; i2c_master_transfer_t transfer; assert(handle); assert(xfer); i2cMasterHandle = (hal_i2c_master_t *)handle; transfer.flags = xfer->flags; transfer.slaveAddress = xfer->slaveAddress; transfer.direction = (kHAL_I2cRead == xfer->direction) ? kI2C_Read : kI2C_Write; transfer.subaddress = xfer->subaddress; transfer.subaddressSize = xfer->subaddressSize; transfer.data = xfer->data; transfer.dataSize = xfer->dataSize; return HAL_I2cGetStatus(I2C_MasterTransferBlocking(s_i2cBases[i2cMasterHandle->instance], &transfer)); } hal_i2c_status_t HAL_I2cMasterTransferInstallCallback(hal_i2c_master_handle_t handle, hal_i2c_master_transfer_callback_t callback, void *callbackParam) { hal_i2c_master_t *i2cMasterHandle; assert(handle); i2cMasterHandle = (hal_i2c_master_t *)handle; i2cMasterHandle->callback = callback; i2cMasterHandle->callbackParam = callbackParam; I2C_MasterTransferCreateHandle(s_i2cBases[i2cMasterHandle->instance], &i2cMasterHandle->hardwareHandle, HAL_I2cMasterCallback, i2cMasterHandle); return kStatus_HAL_I2cSuccess; } hal_i2c_status_t HAL_I2cMasterTransferNonBlocking(hal_i2c_master_handle_t handle, hal_i2c_master_transfer_t *xfer) { hal_i2c_master_t *i2cMasterHandle; i2c_master_transfer_t transfer; assert(handle); assert(xfer); i2cMasterHandle = (hal_i2c_master_t *)handle; transfer.flags = xfer->flags; transfer.slaveAddress = xfer->slaveAddress; transfer.direction = (kHAL_I2cRead == xfer->direction) ? kI2C_Read : kI2C_Write; transfer.subaddress = xfer->subaddress; transfer.subaddressSize = xfer->subaddressSize; transfer.data = xfer->data; transfer.dataSize = xfer->dataSize; return HAL_I2cGetStatus(I2C_MasterTransferNonBlocking(s_i2cBases[i2cMasterHandle->instance], &i2cMasterHandle->hardwareHandle, &transfer)); } hal_i2c_status_t HAL_I2cMasterTransferGetCount(hal_i2c_master_handle_t handle, size_t *count) { hal_i2c_master_t *i2cMasterHandle; assert(handle); assert(count); i2cMasterHandle = (hal_i2c_master_t *)handle; return HAL_I2cGetStatus( I2C_MasterTransferGetCount(s_i2cBases[i2cMasterHandle->instance], &i2cMasterHandle->hardwareHandle, count)); } hal_i2c_status_t HAL_I2cMasterTransferAbort(hal_i2c_master_handle_t handle) { hal_i2c_master_t *i2cMasterHandle; assert(handle); i2cMasterHandle = (hal_i2c_master_t *)handle; return HAL_I2cGetStatus( I2C_MasterTransferAbort(s_i2cBases[i2cMasterHandle->instance], &i2cMasterHandle->hardwareHandle)); } hal_i2c_status_t HAL_I2cSlaveTransferInstallCallback(hal_i2c_slave_handle_t handle, hal_i2c_slave_transfer_callback_t callback, void *callbackParam) { hal_i2c_slave_t *i2cSlaveHandle; assert(handle); i2cSlaveHandle = (hal_i2c_slave_t *)handle; i2cSlaveHandle->callback = callback; i2cSlaveHandle->callbackParam = callbackParam; I2C_SlaveTransferCreateHandle(s_i2cBases[i2cSlaveHandle->instance], &i2cSlaveHandle->hardwareHandle, HAL_I2cSlaveCallback, i2cSlaveHandle); return kStatus_HAL_I2cSuccess; } hal_i2c_status_t HAL_I2cSlaveTransferNonBlocking(hal_i2c_slave_handle_t handle, uint32_t eventMask) { hal_i2c_slave_t *i2cSlaveHandle; assert(handle); i2cSlaveHandle = (hal_i2c_slave_t *)handle; return HAL_I2cGetStatus( I2C_SlaveTransferNonBlocking(s_i2cBases[i2cSlaveHandle->instance], &i2cSlaveHandle->hardwareHandle, eventMask)); } hal_i2c_status_t HAL_I2cSlaveTransferAbort(hal_i2c_slave_handle_t handle) { hal_i2c_slave_t *i2cSlaveHandle; assert(handle); i2cSlaveHandle = (hal_i2c_slave_t *)handle; I2C_SlaveTransferAbort(s_i2cBases[i2cSlaveHandle->instance], &i2cSlaveHandle->hardwareHandle); return kStatus_HAL_I2cSuccess; } hal_i2c_status_t HAL_I2cSlaveTransferGetCount(hal_i2c_slave_handle_t handle, size_t *count) { hal_i2c_slave_t *i2cSlaveHandle; assert(handle); assert(count); i2cSlaveHandle = (hal_i2c_slave_t *)handle; return HAL_I2cGetStatus( I2C_SlaveTransferGetCount(s_i2cBases[i2cSlaveHandle->instance], &i2cSlaveHandle->hardwareHandle, count)); }