mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
385 lines
11 KiB
C
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 */
|