本文完整整理原厂技术正文,作为 ArmSoM 平台参考。原文适用范围:RK3576,Linux kernel 6.1。使用前须核对实际板卡、SoC、SDK/BSP 分支、引脚与外设配置;未做板级硬件验证,不代表所有 ArmSoM 板卡均支持。文中输出和数值为原文示例,不是 ArmSoM 实测。
中文保留中文原稿正文,英文保留英文原稿,俄文完整翻译英文正文;代码、注释和命令输出保留源语言。 原稿技术正文没有独立技术配图或表格,没有补造配图。
中英文原稿版本均为 V1.0.0。
操作注意:预留内存、DMA、引脚复用和设备写操作会影响实际硬件。所有命令仅供阅读,未执行硬件读写;先核对原理图、供电、时序和实际设备。DTS 中 xxx 和省略号是原文占位示例,不能直接当作完整配置。
原文待核对:英文 §2.3.1 说明写 iio:device1,但命令和中文说明使用 iio:device2;两份原稿 §2.3.2 的 cd 指向 device0,而下一行提示符是 device2。本文保留这些原值;实际写入前必须通过 name 文件确认 DAC 设备,不能直接照抄设备编号。
来源与修复详见 EDITORIAL-NOTES。官方参考:ArmSoM, Rockchip Linux.
原文产品版本表(PDF p.2;仅表示原稿范围,非板级验证结论):
| 芯片名称 | 内核版本 |
|---|---|
| RK3576 | 6.1 |
1. FLEXBUS ADC 模式
1.1 概述
FLEXBUS ADC 模式指的是 FLEXBUS1 对接高速并行 ADC 器件,例如 TI 的 ADS6144(https://www.ti.com.cn/product/cn/ADS6144)、ADI 的 LTC2207(https://www.analog.com/cn/products/ltc2207.html)。不支持 SPI、I2C 等接口类型的 ADC 器件。
时钟频率最高 100MHz
分辨率最高 16-Bit
1.2 配置
1.2.1 硬件配置
只支持将 ADC 器件的 LSB 连接到 FLEXBUS1_D0,例如 10-Bit ADC 连接至 FLEXBUS1_D[9:0]、16-Bit ADC 连接至 FLEXBUS1_D[15:0]
slave 模式为器件向 FLEXBUS1 提供 CLK,master 模式为 FLEXBUS1 向器件提供 CLK
1.2.2 内核配置
FLEXBUS ADC 模式依赖 iio/adc 框架。
Device Drivers -> Multifunction device drivers -> Rockchip Flexbus
Device Drivers -> Industrial I/O support -> Analog to digital converters -> Rockchip Flexbus ADCopmode driver
1.2.3 dtsi 配置
以 RK3576 平台和 RK3576 TEST1 板子,FLEXBUS1 对接 ADC 为例。
rk3576.dtsi 中:
flexbus: flexbus@2a2f0000 {
......
flexbus_adc: adc {
compatible = "rockchip,flexbus-adc";
#io-channel-cells = <0>;
rockchip,slave-mode; // 配置 slave 模式,不配置则为 master 模式
rockchip,free-sclk; // 配置时钟保持输出,不配置则时钟跟随数据
rockchip,auto-pad; // 默认配置
rockchip,cpol; // 配置 CPOL = 1,不配置则为 0
rockchip,cpha; // 配置 CPHA = 1,不配置则为 0
rockchip,dfs = <16>; // data frames
status = "disabled";
};
flexbus_dac: dac {
......
};
};
rockchip,slave-mode:配置了为 slave 模式为器件向 FLEXBUS1 提供 CLK;不配置为 master 模式,FLEXBUS1 向器件提供 CLK
rockchip,free-sclk:配置了则时钟一直保持输出,不配置则只在数据传输时输出时钟(该配置仅在master 模式有效)
rockchip,cpol、rockchip,cpha:与 SPI 协议的定义相同,根据器件手册的时序图配置
rockchip,dfs:数据的位宽,仅支持配置成 4、8、16;如果器件分辨率不是 4、8 或 16,需要向上取整;例如对接 14-Bit 分辨率的 ADC 器件时,需要把 rockchip,dfs 配成 16,接收数据时通过软件处理只取 14bit 的数据
arch/arm64/boot/dts/rockchip/rk3576-test1.dtsi 中:
&flexbus {
rockchip,flexbus0-opmode = <ROCKCHIP_FLEXBUS0_OPMODE_xxx>;
rockchip,flexbus1-opmode = <ROCKCHIP_FLEXBUS1_OPMODE_ADC>; // FLEXBUS1 选择 ADC 模式
status = "okay"; // 使能 FLEXBUS
};
&flexbus_adc {
pinctrl-names = "default";
pinctrl-0 = <&flexbus1m4_csn &flexbus1_clk
&flexbus1_d0 &flexbus1_d1 &flexbus1_d2 &flexbus1_d3
&flexbus1_d4 &flexbus1_d5 &flexbus1_d6 &flexbus1_d7
&flexbus1_d8 &flexbus1_d9 &flexbus1_d10 &flexbus1_d11
&flexbus1m1_d12 &flexbus1m1_d13 &flexbus1m1_d14 &flexbus1m1_d15>;
// 配置 FLEXBUS1 ADC 模式需要的 IOMUX
status = "okay"; // 使能 ADC 模式
};
1.2.4 驱动文件
驱动文件为 drivers/iio/adc/rockchip-flexbus-adc.c。
其中 rockchip_flexbus_adc_read_block() 是 read ADC 器件数据的函数,主要操作有:
(1) rockchip_flexbus_writel(rkfb, FLEXBUS_RX_NUM, num_of_dfs);
配置 RX 数量,单位是 dfs(dtsi 中的 rockchip,dfs)
(2) rockchip_flexbus_writel(rkfb, FLEXBUS_DMA_DST_ADDR0, (ulong)dst_phys >> 2);
配置 dst buffer 的物理地址
(3) rockchip_flexbus_writel(rkfb, FLEXBUS_DMA_DST_LEN0, dst_len);
配置 dst buffer 的长度
(4) rockchip_flexbus_writel(rkfb, FLEXBUS_ENR, FLEXBUS_RX_ENR);
Enable RX 传输
(5) wait_for_completion_timeout(&rkfb_adc->completion, FLEXBUS_ADC_TIMEOUT)
等待 RX 传输完成,产生中断(中断处理函数为 rockchip_flexbus_adc_isr())
(6) rockchip_flexbus_writel(rkfb, FLEXBUS_ENR, FLEXBUS_RX_DIS);
Disable RX 传输
1.3 常用接口
1.3.1 确认 FLEXBUS ADC 对应的 device
例如:
root@rk3576-buildroot:/# cat /sys/bus/iio/devices/iio\:device0/name
2a2f0000.flexbus:adc
说明 FLEXBUS ADC 对应 iio:device0
1.3.2 获取 ADC 值
root@rk3576-buildroot:/# cd /sys/bus/iio/devices/iio\:device0
root@rk3576-buildroot:/sys/bus/iio/devices/iio:device0# cat in_voltage_raw
33004
1.3.3 获取和修改时钟频率
获取时钟频率:
root@rk3576-buildroot:/# cd /sys/bus/iio/devices/iio\:device0
root@rk3576-buildroot:/sys/bus/iio/devices/iio:device0# cat in_voltage_sampling_frequency
99000000
说明当前时钟频率为 99MHz。
修改时钟频率:
root@rk3576-buildroot:/sys/bus/iio/devices/iio:device0# echo 25000000 > in_voltage_sampling_frequency
时钟频率就被改为 25MHz。
Note:
只有 master 模式支持获取和修改时钟频率,slave 模式的 CLK 来源于 ADC 器件
时钟频率最高 100MHz
2. FLEXBUS DAC 模式
2.1 概述
FLEXBUS DAC 模式指的是 FLEXBUS0 对接高速并行 DAC 器件,例如 ADI 的 MAX5885(https://www.analog.com/cn/products/max5885.html)、ADI 的 AD9744(https://www.analog.com/cn/products/ad9744.html)。不支持 SPI、I2C 等接口类型的 DAC 器件。
时钟频率最高 100MHz
分辨率最高 16-Bit
2.2 配置
2.2.1 硬件配置
只支持将 DAC 器件的 LSB 连接到 FLEXBUS0_D0,例如 10-Bit DAC 连接至 FLEXBUS0_D[9:0]、16-Bit DAC 连接至 FLEXBUS0_D[15:0]
2.2.2 内核配置
FLEXBUS DAC 模式依赖 iio/dac 框架。
Device Drivers -> Multifunction device drivers -> Rockchip Flexbus
Device Drivers -> Industrial I/O support -> Digital to analog converters -> Rockchip Flexbus DACopmode driver
2.2.3 dtsi 配置
以 RK3576 平台和 RK3576 TEST1 板子,FLEXBUS0 对接 DAC 为例。
rk3576.dtsi 中:
flexbus: flexbus@2a2f0000 {
......
flexbus_adc: adc {
......
};
flexbus_dac: dac {
compatible = "rockchip,flexbus-dac";
#io-channel-cells = <0>;
rockchip,free-sclk; // 配置时钟保持输出,不配置则时钟跟随数据
rockchip,cpol; // 配置 CPOL = 1,不配置则为 0
rockchip,cpha; // 配置 CPHA = 1,不配置则为 0
rockchip,dfs = <16>; // data frames
status = "disabled";
};
};
rockchip,free-sclk:配置了则时钟一直保持输出,不配置则只在数据传输时输出时钟
rockchip,cpol、rockchip,cpha:与 SPI 协议的定义相同,根据器件手册的时序图配置
rockchip,dfs:数据的位宽,仅支持配置成 4、8、16;如果器件分辨率不是 4、8 或 16,需要向上取整;例如对接 14-Bit 分辨率的 DAC 器件时,需要把 rockchip,dfs 配成 16,发送数据的 bit15、14 补 0
arch/arm64/boot/dts/rockchip/rk3576-test1.dtsi 中:
&flexbus {
rockchip,flexbus0-opmode = <ROCKCHIP_FLEXBUS0_OPMODE_DAC>; // FLEXBUS0 选择 DAC 模式
rockchip,flexbus1-opmode = <ROCKCHIP_FLEXBUS1_OPMODE_xxx>;
status = "okay"; // 使能 FLEXBUS
};
&flexbus_dac {
pinctrl-names = "default";
pinctrl-0 = <&flexbus0m4_csn &flexbus0_clk
&flexbus0_d0 &flexbus0_d1 &flexbus0_d2 &flexbus0_d3
&flexbus0_d4 &flexbus0_d5 &flexbus0_d6 &flexbus0_d7
&flexbus0_d8 &flexbus0_d9 &flexbus0_d10 &flexbus0_d11
&flexbus0_d12 &flexbus0m0_d13 &flexbus0m0_d14 &flexbus0m0_d15>;
// 配置 FLEXBUS0 DAC 模式需要的 IOMUX
status = "okay"; // 使能 DAC 模式
};
2.2.4 驱动文件
驱动文件为 drivers/iio/dac/rockchip-flexbus-dac.c。
其中 rockchip_flexbus_dac_write_block() 是向 DAC 器件发送数据的函数,主要操作有:
(1) rockchip_flexbus_writel(rkfb, FLEXBUS_TX_NUM, num_of_dfs);
配置 TX 数量,单位是 dfs(dtsi 中的 rockchip,dfs)
(2) rockchip_flexbus_writel(rkfb, FLEXBUS_TXWAT_START, val);
配置水线
(3) rockchip_flexbus_writel(rkfb, FLEXBUS_DMA_SRC_ADDR0, (ulong)src_phys >> 2);
配置 src buffer 的物理地址
(4) rockchip_flexbus_writel(rkfb, FLEXBUS_DMA_SRC_LEN0, src_len);
配置 src buffer 的长度
(5) rockchip_flexbus_writel(rkfb, FLEXBUS_ENR, FLEXBUS_TX_ENR);
Enable TX 传输
(6) wait_for_completion_timeout(&rkfb_dac->completion, FLEXBUS_DAC_TIMEOUT)
等待 TX 传输完成,产生中断(中断处理函数为 rockchip_flexbus_dac_isr())
(7) rockchip_flexbus_writel(rkfb, FLEXBUS_ENR, FLEXBUS_TX_DIS);
Disable TX 传输
2.3 常用接口
2.3.1 确认 FLEXBUS DAC 对应的 device
例如:
root@rk3576-buildroot:/# cat /sys/bus/iio/devices/iio\:device2/name
2a2f0000.flexbus:dac
说明 FLEXBUS DAC 对应 iio:device2
2.3.2 向 DAC 发送数据
root@rk3576-buildroot:/# cd /sys/bus/iio/devices/iio\:device0
root@rk3576-buildroot:/sys/bus/iio/devices/iio:device2# echo 16383 > out_voltage_raw
2.3.3 获取和修改时钟频率
获取时钟频率:
root@rk3576-buildroot:/# cd /sys/bus/iio/devices/iio\:device2
root@rk3576-buildroot:/sys/bus/iio/devices/iio:device2# cat out_voltage_sampling_frequency
99000000
说明当前时钟频率为 99MHz。
修改时钟频率:
root@rk3576-buildroot:/sys/bus/iio/devices/iio:device2# echo 25000000 > out_voltage_sampling_frequency
时钟频率就被改为 25MHz。
Note:
时钟频率最高 100MHz
