)
1. RK3568设备树中的I2C总线配置第一次接触RK3568设备树中的I2C配置时我也是一头雾水。但当我把它和STM32的I2C初始化对比后发现两者本质上是相通的。我们先看STM32的I2C初始化代码I2C_HandleTypeDef hi2c1; hi2c1.Instance I2C1; hi2c1.Init.ClockSpeed 100000; hi2c1.Init.DutyCycle I2C_DUTYCYCLE_2; hi2c1.Init.OwnAddress1 0; hi2c1.Init.AddressingMode I2C_ADDRESSINGMODE_7BIT; hi2c1.Init.DualAddressMode I2C_DUALADDRESS_DISABLE; hi2c1.Init.OwnAddress2 0; hi2c1.Init.GeneralCallMode I2C_GENERALCALL_DISABLE; hi2c1.Init.NoStretchMode I2C_NOSTRETCH_DISABLE; HAL_I2C_Init(hi2c1);这段代码定义了I2C实例、时钟速度、占空比、地址模式等参数。而在RK3568设备树中I2C的配置是这样的i2c1: i2cfe5a0000 { compatible rockchip,rk3568-i2c, snps,designware-i2c; reg 0x0 0xfe5a0000 0x0 0x100; interrupts GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH; clocks cru CLK_I2C1, cru PCLK_I2C1; clock-names i2c, pclk; pinctrl-names default; pinctrl-0 i2c1_xfer; #address-cells 1; #size-cells 0; status disabled; };设备树中的配置包含了寄存器地址、中断号、时钟、引脚复用等硬件相关信息。与STM32相比RK3568把这些硬件信息都抽象到了设备树中而驱动代码则变得通用化。实际项目中我们需要修改的主要是以下几个部分启用I2C控制器将status从disabled改为okay配置引脚复用确保pinctrl-0指向正确的引脚组添加设备节点在I2C控制器下添加具体的设备节点比如要添加一个AT24C02 EEPROM设备可以这样配置i2c1 { status okay; pinctrl-0 i2c1_xfer; eeprom50 { compatible atmel,24c02; reg 0x50; pagesize 8; }; };这里有几个关键点需要注意compatible属性必须与驱动匹配reg属性指定设备地址0x50pagesize是设备特定参数2. CAN总线配置详解CAN总线的配置比I2C稍微复杂一些因为涉及CAN控制器和收发器的配合。我们还是先看STM32的CAN初始化CAN_HandleTypeDef hcan; hcan.Instance CAN1; hcan.Init.Prescaler 16; hcan.Init.Mode CAN_MODE_NORMAL; hcan.Init.SyncJumpWidth CAN_SJW_1TQ; hcan.Init.TimeSeg1 CAN_BS1_13TQ; hcan.Init.TimeSeg2 CAN_BS2_2TQ; hcan.Init.TimeTriggeredMode DISABLE; hcan.Init.AutoBusOff DISABLE; hcan.Init.AutoWakeUp DISABLE; hcan.Init.AutoRetransmission DISABLE; hcan.Init.ReceiveFifoLocked DISABLE; hcan.Init.TransmitFifoPriority DISABLE; HAL_CAN_Init(hcan);而在RK3568设备树中CAN控制器的配置如下can0: canfe570000 { compatible rockchip,rk3568-can; reg 0x0 0xfe570000 0x0 0x1000; interrupts GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH; clocks cru CLK_CAN0, cru PCLK_CAN0; clock-names baudclk, apb_pclk; resets cru SRST_CAN0, cru SRST_P_CAN0; reset-names can, can-apb; pinctrl-names default; pinctrl-0 can0_pins; status disabled; };实际使用中我们需要关注以下几个配置项时钟配置确保时钟频率与所需波特率匹配引脚复用正确配置CAN_TX和CAN_RX引脚收发器使能通常需要控制收发器的STB引脚一个完整的CAN节点配置示例can0 { status okay; pinctrl-0 can0_pins; assigned-clocks cru CLK_CAN0; assigned-clock-rates 50000000; // 50MHz }; pinctrl { can0_pins: can0-pins { rockchip,pins /* can0_rx */ 1 RK_PB1 2 pcfg_pull_none, /* can0_tx */ 1 RK_PB2 2 pcfg_pull_none; }; };CAN总线的波特率计算比较特殊需要在驱动中配置。设备树只提供时钟基准实际波特率在驱动初始化时计算设置。3. I2C与CAN配置的常见问题在实际项目中I2C和CAN的配置经常会遇到各种问题。根据我的经验最常见的有以下几种I2C设备无响应检查设备地址是否正确注意7位/8位地址区别确认上拉电阻是否合适通常4.7kΩ用示波器检查SCL/SDA波形是否正常CAN总线通信失败确认终端电阻是否匹配通常120Ω检查波特率配置是否正确验证收发器供电是否正常引脚复用冲突确保没有其他功能占用相同引脚检查pinctrl配置是否正确时钟问题I2C时钟频率是否在设备支持范围内CAN时钟基准是否满足波特率需求对于调试我建议采用以下步骤首先确认硬件连接正确检查设备树配置是否被正确加载cat /proc/device-tree/i2cfe5a0000/status查看内核日志是否有错误信息dmesg | grep i2c使用工具验证总线通信I2C可以使用i2c-toolsi2cdetect -y 1CAN可以使用can-utilscandump can04. 进阶配置技巧掌握了基础配置后下面分享几个进阶技巧I2C多设备管理 当总线上有多个设备时需要注意确保设备地址不冲突考虑总线负载电容效应必要时使用I2C多路复用器示例配置i2c1 { status okay; sensor48 { compatible ti,tmp112; reg 0x48; }; eeprom50 { compatible atmel,24c02; reg 0x50; }; };CAN FD配置 RK3568支持CAN FD配置时需要设置更高的时钟频率配置数据段波特率使用兼容的收发器示例配置can0 { status okay; assigned-clocks cru CLK_CAN0; assigned-clock-rates 100000000; // 100MHz rockchip,can-fd 1; };电源管理 对于低功耗应用可以配置自动休眠i2c1 { rockchip,sleep-mode 1; wakeup-source; };DMA配置 高性能应用可以启用DMAi2c1 { dmas dmac0 10, dmac0 11; dma-names tx, rx; };这些配置都需要驱动支持在修改前务必确认内核版本和驱动能力。