openmv/lib/alif/Alif_CMSIS/Source/Driver_I3C_I2C.c
iabdalkader daf2bb30da misc: Restructure repo.
Signed-off-by: iabdalkader <i.abdalkader@gmail.com>
2025-04-13 08:28:34 +02:00

385 lines
11 KiB
C

/* Copyright (C) 2023 Alif Semiconductor - All Rights Reserved.
* Use, distribution and modification of this code is permitted under the
* terms stated in the Alif Semiconductor Software License Agreement
*
* You should have received a copy of the Alif Semiconductor Software
* License Agreement with this file. If not, please write to:
* contact@alifsemi.com, or visit: https://alifsemi.com/license
*
*/
/******************************************************************************
* @file Driver_I3C_I2C.c
* @author Prasanna Ravi
* @email prasanna.ravi@alifsemi.com
* @version V1.0.0
* @date 24-Feb-2022
* @brief Driver for I2C over I3C adapter.
* @bug None.
* @Note None.
******************************************************************************/
#include "Driver_I2C.h"
#include "Driver_I3C.h"
#include "RTE_Device.h"
#if !(RTE_I3C)
#error "I3C is not enabled in the RTE_Device.h"
#endif
#if !(RTE_I2CI3C)
#error "I2CI3C is not enabled in the RTE_Device.h"
#endif
#define ARM_I3C_I2C_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(1, 0) /* driver version */
/* Driver Version */
static const ARM_DRIVER_VERSION DriverVersion = {
ARM_I2C_API_VERSION,
ARM_I3C_I2C_DRV_VERSION
};
/* I3C driver instance */
extern ARM_DRIVER_I3C Driver_I3C;
/* Pointer to \ref ARM_I2C_SignalEvent */
static ARM_I2C_SignalEvent_t i2c_event;
/* i2c status parameter */
static ARM_I2C_STATUS i2c_status;
/* Driver Capabilities */
static const ARM_I2C_CAPABILITIES DriverCapabilities = {
0, /* supports 10-bit addressing */
0 /* reserved */
};
/**
* @fn void i3c_driver_callback (uint32_t event)
* @brief callback routine from the i3c driver mapped to i2c signal events
* @param none
* @retval none
*/
static void i3c_driver_callback (uint32_t event)
{
if(event & ARM_I3C_EVENT_TRANSFER_DONE)
{
i2c_event(ARM_I2C_EVENT_TRANSFER_DONE);
}
if(event & ARM_I3C_EVENT_TRANSFER_ERROR)
{
i2c_event(ARM_I2C_EVENT_TRANSFER_INCOMPLETE);
}
}
/**
* @fn ARM_DRIVER_VERSION ARM_I3C_I2C_GetVersion (void)
* @brief get i2c over i3c driver version
* @param none
* @retval driver version
*/
static ARM_DRIVER_VERSION ARM_I3C_I2C_GetVersion (void)
{
return DriverVersion;
}
/**
* @fn static ARM_I2C_CAPABILITIES ARM_I3C_I2C_GetCapabilities (void)
* @brief get i2c over i3c capabilities
* @param none
* @retval driver capabilities
*/
static ARM_I2C_CAPABILITIES ARM_I3C_I2C_GetCapabilities (void)
{
return DriverCapabilities;
}
/**
* @fn int32_t ConvertI2CBusSpeedToI3C (uint32_t i2c_bus_speed)
* @brief get i2c over i3c bus speed
* @param i2c_bus_speed : i2c bus speed
* ARM_I2C_BUS_SPEED_STANDARD
* ARM_I2C_BUS_SPEED_FAST
* ARM_I2C_BUS_SPEED_FAST_PLUS
* @retval none
*/
static int32_t ConvertI2CBusSpeedToI3C (uint32_t i2c_bus_speed)
{
int32_t speed = 0;
switch (i2c_bus_speed)
{
case ARM_I2C_BUS_SPEED_STANDARD:
/* Standard Speed (100kHz) */
speed = I3C_BUS_MODE_MIXED_SLOW_I2C_SS_SPEED_100_KBPS;
break;
case ARM_I2C_BUS_SPEED_FAST:
/* Fast Speed (400kHz) */
speed = I3C_BUS_MODE_MIXED_FAST_I2C_FM_SPEED_400_KBPS;
break;
case ARM_I2C_BUS_SPEED_FAST_PLUS:
/* Fast+ Speed (1MHz) */
speed = I3C_BUS_MODE_MIXED_FAST_I2C_FMP_SPEED_1_MBPS;
break;
case ARM_I2C_BUS_SPEED_HIGH:
/* Fast+ Speed (3.4MHz) */
return ARM_DRIVER_ERROR_UNSUPPORTED;
break;
default:
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
return speed;
}
/**
* @fn int32_t ARM_I3C_I2C_Initialize (ARM_I2C_SignalEvent_t cb_event)
* @brief CMSIS-Driver i2c over i3c initialize.
* @param cb_event : Pointer to \ref ARM_I2C_SignalEvent
* @retval \ref execution_status
*/
static int32_t ARM_I3C_I2C_Initialize (ARM_I2C_SignalEvent_t cb_event)
{
if (cb_event == NULL)
{
return ARM_DRIVER_ERROR_PARAMETER;
}
i2c_event = cb_event;
return Driver_I3C.Initialize (i3c_driver_callback);
}
/**
* @fn int32_t ARM_I3C_I2C_Uninitialize (void)
* @brief CMSIS-Driver i2c over i3c uninitialize
* @note none
* @retval \ref execution_status
*/
static int32_t ARM_I3C_I2C_Uninitialize (void)
{
i2c_event = NULL;
return Driver_I3C.Uninitialize ();
}
/**
* @fn int32_t ARM_I3C_I2C_PowerControl (ARM_POWER_STATE state)
* @brief Power the driver and enable the NVIC
* @param state : Power state
* @return \ref execution_status
*/
static int32_t ARM_I3C_I2C_PowerControl (ARM_POWER_STATE state)
{
return Driver_I3C.PowerControl (state);
}
/**
* @fn static int32_t ARM_I3C_I2C_MasterTransmit (uint32_t addr,
const uint8_t *data,
uint32_t num,
bool xfer_pending)
* @brief CMSIS-Driver i2c master transmit
* Start sending data to i2c over i3c transmitter
* @param addr : Slave address (7-bit)
* @param data : Pointer to buffer with data to send to i2c transmitter
* @param num : Number of data items to send
* @retval \ref execution_status
*/
static int32_t ARM_I3C_I2C_MasterTransmit (uint32_t addr,
const uint8_t *data,
uint32_t num,
bool xfer_pending)
{
int32_t ret, detach_ret;
ARM_I3C_DEVICE_TYPE dev_type = ARM_I3C_DEVICE_TYPE_I2C;
/* Currently this feature is not supported */
(void) xfer_pending;
/* I2C Master Mode*/
i2c_status.mode = 1;
ret = Driver_I3C.AttachSlvDev(dev_type, addr);
if (ret != ARM_DRIVER_OK)
{
return ret;
}
ret = Driver_I3C.MasterTransmit (addr, data, num);
detach_ret = Driver_I3C.Detachdev (addr);
if(ret == ARM_DRIVER_OK)
{
ret = detach_ret;
}
return ret;
}
/**
* @fn static int32_t ARM_I3C_I2C_MasterReceive (uint32_t addr,
uint8_t *data,
uint32_t num,
bool xfer_pending)
* @brief CMSIS-Driver i2c master receive
* Start receiving data from i2c over i3c receiver.
* @param addr : addr Slave address (7-bit)
* @param data : Pointer to buffer for data to receive from i2c receiver
* @param num : Number of data items to receive
* @retval \ref execution_status
*/
static int32_t ARM_I3C_I2C_MasterReceive (uint32_t addr,
uint8_t *data,
uint32_t num,
bool xfer_pending)
{
int32_t ret, detach_ret;
ARM_I3C_DEVICE_TYPE dev_type = ARM_I3C_DEVICE_TYPE_I2C;
/* Currently this feature is not supported */
(void) xfer_pending;
/* I2C Master Mode*/
i2c_status.mode = 1;
ret = Driver_I3C.AttachSlvDev(dev_type, addr);
if (ret != ARM_DRIVER_OK)
{
return ret;
}
ret = Driver_I3C.MasterReceive (addr, data, num);
detach_ret = Driver_I3C.Detachdev (addr);
if(ret == ARM_DRIVER_OK)
{
ret = detach_ret;
}
return ret;
}
/**
* @fn int32_t ARM_I3C_I2C_SlaveTransmit (const uint8_t *data,
uint32_t num)
* @brief CMSIS-Driver i2c slave transmit
* Start sending data to i2c over i3c master.
* @param data : Pointer to buffer with data to send to i2c master
* @param num : Number of data items to send
* @retval \ref execution_status
*/
static int32_t ARM_I3C_I2C_SlaveTransmit (const uint8_t *data,
uint32_t num)
{
(void) data;
(void) num;
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
/**
* @fn int32_t ARM_I3C_I2C_SlaveReceive (uint8_t *data,
uint32_t num)
* @brief CMSIS-Driver i2c slave receive
* Start receiving data from i2c over i3c master.
* @param data : Pointer to buffer for data to receive from i2c master
* @param num : Number of data items to receive
* @retval \ref execution_status
*/
static int32_t ARM_I3C_I2C_SlaveReceive (uint8_t *data,
uint32_t num)
{
(void) data;
(void) num;
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
/**
* @fn int32_t ARM_I3C_I2C_GetDataCount (void)
* @brief CMSIS-Driver i2c get transfer data count
* @retval transfer data count
*/
static int32_t ARM_I3C_I2C_GetDataCount (void)
{
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
/**
* @fn int32_t ARM_I3C_I2C_Control (uint32_t control,
uint32_t arg)
* @brief CMSIS-Driver i2c control
* Control i2c over i3c Interface.
* @note none
* @param control : Operation
* @param arg : Argument of operation (optional)
* @retval common \ref execution_status and driver specific \ref i2c_execution_status
*/
static int32_t ARM_I3C_I2C_Control (uint32_t control,
uint32_t arg)
{
int32_t ret = ARM_DRIVER_OK;
int32_t speed = 0;
switch (control)
{
case ARM_I2C_OWN_ADDRESS:
return ARM_DRIVER_ERROR_UNSUPPORTED;
break;
case ARM_I2C_BUS_SPEED:
speed = ConvertI2CBusSpeedToI3C (arg);
if (speed == ARM_DRIVER_ERROR_UNSUPPORTED)
return ARM_DRIVER_ERROR_UNSUPPORTED;
ret = Driver_I3C.Control (I3C_MASTER_INIT, 0);
ret = Driver_I3C.Control (I3C_MASTER_SET_BUS_MODE, speed);
ret = Driver_I3C.Control (I3C_MASTER_SETUP_HOT_JOIN_ACCEPTANCE, 0);
ret = Driver_I3C.Control (I3C_MASTER_SETUP_MR_ACCEPTANCE, 0);
break;
case ARM_I2C_BUS_CLEAR:
return ARM_DRIVER_ERROR_UNSUPPORTED;
break;
case ARM_I2C_ABORT_TRANSFER:
return ARM_DRIVER_ERROR_UNSUPPORTED;
break;
default:
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
return ret;
}
/**
* @fn ARM_I2C_STATUS ARM_I3C_I2C_GetStatus (void)
* @brief CMSIS-Driver i2c get status
* @note none
* @retval ARM_i2c_STATUS
*/
static ARM_I2C_STATUS ARM_I3C_I2C_GetStatus (void)
{
return i2c_status;
}
/* I2CI3C Driver Instance */
#if (RTE_I2CI3C)
/* I2CI3C Driver Control Block */
extern ARM_DRIVER_I2C Driver_I2CI3C;
ARM_DRIVER_I2C Driver_I2CI3C = {
ARM_I3C_I2C_GetVersion,
ARM_I3C_I2C_GetCapabilities,
ARM_I3C_I2C_Initialize,
ARM_I3C_I2C_Uninitialize,
ARM_I3C_I2C_PowerControl,
ARM_I3C_I2C_MasterTransmit,
ARM_I3C_I2C_MasterReceive,
ARM_I3C_I2C_SlaveTransmit,
ARM_I3C_I2C_SlaveReceive,
ARM_I3C_I2C_GetDataCount,
ARM_I3C_I2C_Control,
ARM_I3C_I2C_GetStatus
};
#endif /* RTE_I2CI3C */