【前言】
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,然后运行程序,使用逻辑分析仪观查,可以看到两个开发板已经正常进行数据收发: