【前言】
I3C做为I2C的“升级版本”,他不但在速度上有很高的提升,而且也不限于以前的marster/slave模式。前面一篇,我对Controller进行了分配与分析:
【STM32H5系列】1、I3C之Controller配置-电子产品世界论坛 (eepw.com.cn)
本篇将对 Target的配置进行分析。
【实验环境】
STM32CubeMX 6.12
【开发板】
NUCLEO-H533RE
【配置】
一、配置模式为Target
二、Parameter Settings的配置,相比Controller的配置,参数会少很多,主要配置如下:

下面逐个进行分析:
1、Bus Available Duration (ns)
这个参数必须在1000—1028中间,默认为1000ns就行,这个参数的解释为:SDA和SCL至少在taval(ns)时处于高位的持续时间。
2、Target Characterics ID
这个为ID,为MIPI协议中的DCR ,规定这个只能在0x00-0xFF之间
3、MIPI Identifier
这个参数MIPI协议中的PID,默认值为0,这里我使用了自定的标签,在自定义中定义他为1:

4、Max Read Data Size
这个参数为Taget读取最大的字节数,他的值范围在0x00-0xFFFF之间。此次定义为0xff即一次可以读取0xff
5、Max Write Data Size
这个参数为Taget写入最大的字节数,他的值范围在0x00-0xFFFF之间。此次定义为0xff即一次可以读取0xff
6、跟Controller一样,Transmit Fifo Threshold也设置为4字节。
三、配置使能中断
四、生成的配置代码
/* Includes ------------------------------------------------------------------*/
#include "i3c.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
I3C_HandleTypeDef hi3c1;
/* I3C1 init function */
void MX_I3C1_Init(void)
{
/* USER CODE BEGIN I3C1_Init 0 */
/* USER CODE END I3C1_Init 0 */
I3C_FifoConfTypeDef sFifoConfig = {0};
I3C_TgtConfTypeDef sTgtConfig = {0};
/* USER CODE BEGIN I3C1_Init 1 */
/* USER CODE END I3C1_Init 1 */
hi3c1.Instance = I3C1;
hi3c1.Mode = HAL_I3C_MODE_TARGET;
hi3c1.Init.TgtBusCharacteristic.BusAvailableDuration = 0xf8;
if (HAL_I3C_Init(&hi3c1) != HAL_OK)
{
Error_Handler();
}
/** Configure FIFO
*/
sFifoConfig.RxFifoThreshold = HAL_I3C_RXFIFO_THRESHOLD_4_4;
sFifoConfig.TxFifoThreshold = HAL_I3C_TXFIFO_THRESHOLD_4_4;
sFifoConfig.ControlFifo = HAL_I3C_CONTROLFIFO_DISABLE;
sFifoConfig.StatusFifo = HAL_I3C_STATUSFIFO_DISABLE;
if (HAL_I3C_SetConfigFifo(&hi3c1, &sFifoConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Target
*/
sTgtConfig.Identifier = 0xC6;
sTgtConfig.MIPIIdentifier = DEVICE_ID;
sTgtConfig.CtrlRoleRequest = DISABLE;
sTgtConfig.HotJoinRequest = DISABLE;
sTgtConfig.IBIRequest = DISABLE;
sTgtConfig.IBIPayload = DISABLE;
sTgtConfig.IBIPayloadSize = HAL_I3C_PAYLOAD_EMPTY;
sTgtConfig.MaxReadDataSize = 0xFF;
sTgtConfig.MaxWriteDataSize = 0xFF;
sTgtConfig.CtrlCapability = DISABLE;
sTgtConfig.GroupAddrCapability = DISABLE;
sTgtConfig.DataTurnAroundDuration = HAL_I3C_TURNAROUND_TIME_TSCO_LESS_12NS;
sTgtConfig.MaxReadTurnAround = 0;
sTgtConfig.MaxDataSpeed = HAL_I3C_GETMXDS_FORMAT_1;
sTgtConfig.MaxSpeedLimitation = DISABLE;
sTgtConfig.HandOffActivityState = HAL_I3C_HANDOFF_ACTIVITY_STATE_0;
sTgtConfig.HandOffDelay = DISABLE;
sTgtConfig.PendingReadMDB = DISABLE;
if (HAL_I3C_Tgt_Config(&hi3c1, &sTgtConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN I3C1_Init 2 */
/* USER CODE END I3C1_Init 2 */
}
void HAL_I3C_MspInit(I3C_HandleTypeDef* i3cHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
if(i3cHandle->Instance==I3C1)
{
/* USER CODE BEGIN I3C1_MspInit 0 */
/* USER CODE END I3C1_MspInit 0 */
/** Initializes the peripherals clock
*/
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I3C1;
PeriphClkInitStruct.I3c1ClockSelection = RCC_I3C1CLKSOURCE_PCLK1;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
/* I3C1 clock enable */
__HAL_RCC_I3C1_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/**I3C1 GPIO Configuration
PB6 ------> I3C1_SCL
PB7 ------> I3C1_SDA
*/
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF3_I3C1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* I3C1 interrupt Init */
HAL_NVIC_SetPriority(I3C1_EV_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(I3C1_EV_IRQn);
HAL_NVIC_SetPriority(I3C1_ER_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(I3C1_ER_IRQn);
/* USER CODE BEGIN I3C1_MspInit 1 */
/* USER CODE END I3C1_MspInit 1 */
}
}
void HAL_I3C_MspDeInit(I3C_HandleTypeDef* i3cHandle)
{
if(i3cHandle->Instance==I3C1)
{
/* USER CODE BEGIN I3C1_MspDeInit 0 */
/* USER CODE END I3C1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_I3C1_CLK_DISABLE();
/**I3C1 GPIO Configuration
PB6 ------> I3C1_SCL
PB7 ------> I3C1_SDA
*/
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6|GPIO_PIN_7);
/* I3C1 interrupt Deinit */
HAL_NVIC_DisableIRQ(I3C1_EV_IRQn);
HAL_NVIC_DisableIRQ(I3C1_ER_IRQn);
/* USER CODE BEGIN I3C1_MspDeInit 1 */
/* USER CODE END I3C1_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */【测试效果】
将两个开发板连接上SDA/SCL,然后运行程序,使用逻辑分析仪观查,可以看到两个开发板已经正常进行数据收发:

我要赚赏金
