Rockchip · AI & Linux Hub

Hardware interfaces

Rockchip FLEXBUS ADC/DAC Guide: Parallel Converters, DMA and IIO

Rockchip FLEXBUS ADC/DAC Guide: Parallel Converters, DMA and IIO with complete technical sections, code, parameters and source caveats.

· ArmSoM Editorial · Rockchip source documentation · 12 min read

This complete source-based technical article is an ArmSoM platform reference. Source scope: RK3576, Linux kernel 6.1. Verify the actual board, SoC, SDK/BSP branch, pins and peripherals before use. No board-level hardware validation has been performed, and support on all ArmSoM boards is not implied. Outputs and measurements are source examples, not ArmSoM test results.

Chinese follows the Chinese source; English follows the English source; Russian fully translates the English technical body. Code, comments and command output retain their source language. The source technical body contains no independent technical figures or tables; none have been invented.

Both source versions are V1.0.0.

Operational caution: reserved memory, DMA, pin multiplexing and device writes affect hardware. Commands are provided for reading; no hardware operations were executed. Verify the schematic, power, timing and actual device. Any xxx or ellipsis in DTS is a source placeholder, not a complete usable configuration.

Source issues: English §2.3.1 says iio:device1, whereas its command and the Chinese explanation use iio:device2. In both sources, §2.3.2 changes to device0 but the following prompt is device2. These original values are retained. Identify the DAC using its name file before writing; do not blindly copy device numbers.

Sources and repairs: EDITORIAL-NOTES。Official references: ArmSoM, Rockchip Linux.

Source product-version table (PDF p.2; source scope, not board-level validation):

Chipset Kernel Version
RK3576 6.1

1. FLEXBUS ADC mode

1.1 Overview

FLEXBUS ADC mode is FLEXBUS1 interfacing high-speed parallel ADC devices such as TI ADS6144 (https://www.ti.com/product/ADS6144) and ADI LTC2207 (https://www.analog.com/en/products/ltc2207.html). ADC devices with interface types such as SPI and I2C are not supported.

Clock frequency up to 100MHz

Resolution up to 16-Bit

1.2 Configuration

1.2.1 Hardware configuration

The LSB of the ADC device needs to be connected to FLEXBUS1_D0, such as 10-Bit ADC to FLEXBUS1_D[9:0], 16-Bit ADC to FLEXBUS1_D[15:0]

Slave mode indicates that the device provides CLK to FLEXBUS1, and master mode indicates that FLEXBUS1 provides CLK to the device

1.2.2 Kernel configuration

FLEXBUS ADC mode relies on the iio/adc framework.

Device Drivers -> Multifunction device drivers -> Rockchip Flexbus

Device Drivers -> Industrial I/O support -> Analog to digital converters -> Rockchip Flexbus ADC opmode driver

1.2.3 dtsi configuration

Take RK3576 platform and RK3576 TEST1 board, FLEXBUS1 for ADC as an example.

In rk3576.dtsi:

flexbus: flexbus@2a2f0000 {
    ......
    flexbus_adc: adc {
        compatible = "rockchip,flexbus-adc";
        #io-channel-cells = <0>;
        rockchip,slave-mode; // Configuring this is the slave mode, not configuring this is the master mode
        rockchip,free-sclk; // Configuring this is clock keeps output, not configuring this is clock follows data
        rockchip,auto-pad; // Default configuration
        rockchip,cpol; // Configuring this is CPOL = 1, not configuring this is 0
        rockchip,cpha; // Configuring this is CPHA = 1, not configuring this is 0
        rockchip,dfs = <16>; // data frames
        status = "disabled";
    };
    flexbus_dac: dac {
        ......
    };
};

rockchip,slave-mode: With configuring this is slave mode, the device provides CLK to FLEXBUS1; Without configuring this is master mode, FLEXBUS1 provides CLK to the device

rockchip,free-sclk: With configuring this, clock keeps output; Without configuring this, clock follow data (this configuration is only valid in master mode)

rockchip,cpol, rockchip,cpha: Same as SPI protocol definitions, configured according to the timing diagram in the device datasheet

rockchip,dfs: data frames, only support configuration of 4, 8, 16; If the resolution of the device is not 4, 8 or 16, it needs to be rounded up; For example, when using ADC devices with 14-Bit resolution, rockchip,dfs needs to be configured to 16, and only 14bit data is obtained through software processing when receiving data

In arch/arm64/boot/dts/rockchip/rk3576-test1.dtsi:

&flexbus {
    rockchip,flexbus0-opmode = <ROCKCHIP_FLEXBUS0_OPMODE_xxx>;
    rockchip,flexbus1-opmode = <ROCKCHIP_FLEXBUS1_OPMODE_ADC>; // FLEXBUS1 selects ADC mode
    status = "okay"; // Enable 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>;
// Configure IOMUX for FLEXBUS1 ADC mode
    status = "okay"; // Enable ADC mode
};

1.2.4 Driver file

The driver file is drivers/iio/adc/rockchip-flexbus-adc.c.

rockchip_flexbus_adc_read_block() is a function of reading ADC device data. The main operations are as follows:

(1) rockchip_flexbus_writel(rkfb, FLEXBUS_RX_NUM, num_of_dfs);

Configure the number of RX in dfs (rockchip,dfs in dtsi)

(2) rockchip_flexbus_writel(rkfb, FLEXBUS_DMA_DST_ADDR0, (ulong)dst_phys >> 2);

Configure physical address of dst buffer

(3) rockchip_flexbus_writel(rkfb, FLEXBUS_DMA_DST_LEN0, dst_len);

Configure length of dst buffer

(4) rockchip_flexbus_writel(rkfb, FLEXBUS_ENR, FLEXBUS_RX_ENR);

Enable RX transfer

(5) wait_for_completion_timeout(&rkfb_adc->completion, FLEXBUS_ADC_TIMEOUT)

Wait for the RX transfer to complete and generate an interrupt (the interrupt handler is rockchip_flexbus_adc_isr())

(6) rockchip_flexbus_writel(rkfb, FLEXBUS_ENR, FLEXBUS_RX_DIS);

Disable RX transfer

1.3 Common interface

1.3.1 Check the device corresponding to FLEXBUS ADC

For example:

root@rk3576-buildroot:/# cat /sys/bus/iio/devices/iio\:device0/name
2a2f0000.flexbus:adc

FLEXBUS ADC corresponds to iio:device0.

1.3.2 Get ADC value

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 Get and change clock frequency

Get clock frequency:

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

The current clock frequency is 99MHz.

Change clock frequency:

root@rk3576-buildroot:/sys/bus/iio/devices/iio:device0# echo 25000000 > in_voltage_sampling_frequency

The clock frequency is changed to 25MHz。

Note:

Only master mode supports getting and changing clock frequency. The CLK of slave mode comes from the ADC device

Clock frequency up to 100MHz

2. FLEXBUS DAC mode

2.1 Overview

FLEXBUS DAC mode is FLEXBUS0 interfacing high-speed parallel DAC devices such as ADI max5885 (https://www.analog.com/en/products/max5885.html) and ADI AD9744 (https://www.analog.com/en/products/ad9744.html). DAC devices with interface types such as SPI and I2C are not supported.

Clock frequency up to 100MHz

Resolution up to 16-Bit

2.2 Configuration

2.2.1 Hardware configuration

The LSB of the DAC device needs to be connected to FLEXBUS0_D0, such as 10-Bit DAC to FLEXBUS0_D[9:0], 16-Bit DAC to FLEXBUS0_D[15:0]

2.2.2 Kernel configuration

FLEXBUS DAC mode relies on the iio/dac framework.

Device Drivers -> Multifunction device drivers -> Rockchip Flexbus

Device Drivers -> Industrial I/O support -> Digital to analog converters -> Rockchip Flexbus DAC opmode driver

2.2.3 dtsi configuration

Take RK3576 platform and RK3576 TEST1 board, FLEXBUS0 for DAC as an example.

In rk3576.dtsi:

flexbus: flexbus@2a2f0000 {
    ......
    flexbus_adc: adc {
        ......
    };
    flexbus_dac: dac {
        compatible = "rockchip,flexbus-dac";
        #io-channel-cells = <0>;
        rockchip,free-sclk; // Configuring this is clock keeps output, not configuring this is clock follows data
        rockchip,cpol; // Configuring this is CPOL = 1, not configuring this is 0
        rockchip,cpha; // Configuring this is CPHA = 1, not configuring this is 0
        rockchip,dfs = <16>; // data frames
        status = "disabled";
    };
};

rockchip,free-sclk: With configuring this, clock keeps output; Without configuring this, clock follow data

rockchip,cpol, rockchip,cpha: Same as SPI protocol definitions, configured according to the timing diagram in the device datasheet

rockchip,dfs: data frames, only support configuration of 4, 8, 16; If the resolution of the device is not 4, 8 or 16, it needs to be rounded up; For example, when using DAC devices with 14-Bit resolution, rockchip,dfs needs to be configured to 16, and bit15 and bit14 of the sent data are replaced by 0.

In arch/arm64/boot/dts/rockchip/rk3576-test1.dtsi:

&flexbus {
    rockchip,flexbus0-opmode = <ROCKCHIP_FLEXBUS0_OPMODE_DAC>; // FLEXBUS0 selects DAC mode
    rockchip,flexbus1-opmode = <ROCKCHIP_FLEXBUS1_OPMODE_xxx>;
    status = "okay"; // Enable 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>;
// Configure IOMUX for FLEXBUS0 DAC mode
    status = "okay"; // Enable DAC mode
};

2.2.4 Driver file

The driver file is drivers/iio/dac/rockchip-flexbus-dac.c.

rockchip_flexbus_dac_write_block() is a function of sending data to DAC device. The main operations are as follows:

(1) rockchip_flexbus_writel(rkfb, FLEXBUS_TX_NUM, num_of_dfs);

Configure the number of TX in dfs (rockchip,dfs in dtsi)

(2) rockchip_flexbus_writel(rkfb, FLEXBUS_TXWAT_START, val);

Configure waterline

(3) rockchip_flexbus_writel(rkfb, FLEXBUS_DMA_SRC_ADDR0, (ulong)src_phys >> 2);

Configure physical address of src buffer

(4) rockchip_flexbus_writel(rkfb, FLEXBUS_DMA_SRC_LEN0, src_len);

Configure length of src buffer

(5) rockchip_flexbus_writel(rkfb, FLEXBUS_ENR, FLEXBUS_TX_ENR);

Enable TX transfer

(6) wait_for_completion_timeout(&rkfb_dac->completion, FLEXBUS_DAC_TIMEOUT)

Wait for the TX transfer to complete and generate an interrupt (the interrupt handler is rockchip_flexbus_dac_isr())

(7) rockchip_flexbus_writel(rkfb, FLEXBUS_ENR, FLEXBUS_TX_DIS);

Disable TX transfer

2.3 Common interface

2.3.1 Check the device corresponding to FLEXBUS DAC

For example:

root@rk3576-buildroot:/# cat /sys/bus/iio/devices/iio\:device2/name
2a2f0000.flexbus:dac

FLEXBUS DAC corresponds to iio:device1.

2.3.2 Send data to 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 Get and change clock frequency

Get clock frequency:

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

The current clock frequency is 99MHz.

Change clock frequency:

root@rk3576-buildroot:/sys/bus/iio/devices/iio:device2# echo 25000000 > out_voltage_sampling_frequency

The clock frequency is changed to 25MHz。

Note:

Clock frequency up to 100MHz

Explore this topic → · Learning paths →