Part Number: AM3357
Other Parts Discussed in Thread: ADS7950, DAC104S085
Hello,
I have the following setup:
- CPU: Sitara AM3357,
- Analog: ADS7957
- SPI1 chip select on GPIO0.13
- OS: Yocto Linux based on TI kernel v4.19.94rt (taken from https://git.ti.com/cgit/processor-sdk/processor-sdk-linux?h=processor-sdk-linux-rt-4.19.y, commit a242ccf3f13f03d41d521411ce2cc09775c873a2).
In the device tree I have the following configuration (only relevant parts):
&am33xx_pinmux {
pinctrl-names = "default";
spi1_pins: pinmux_spi1_pins {
pinctrl-single,pins = <
AM33XX_IOPAD(0x90c, PIN_INPUT | MUX_MODE2) /* (H17) gmii1_crs.spi1_d0 */
AM33XX_IOPAD(0x910, PIN_INPUT | MUX_MODE2) /* (J15) gmii1_rxer.spi1_d1 */
AM33XX_IOPAD(0x964, PIN_INPUT | MUX_MODE4) /* (C18) eCAP0_in_PWM0_out.spi1_sclk */
AM33XX_IOPAD(0x978, PIN_INPUT | MUX_MODE7) /* (D18) uart1_ctsn.gpio0[12] */
AM33XX_IOPAD(0x97c, PIN_INPUT | MUX_MODE7) /* (D19) uart1_rtsn.gpio0[13] */
>;
};
};
&spi1 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&spi1_pins>;
cs-gpios = <&gpio0 12 GPIO_ACTIVE_LOW>, <&gpio0 13 GPIO_ACTIVE_LOW>;
spi-max-frequency = <60000000>;
ads7957: adc@1 {
compatible = "ti,ads7957";
reg = <1>;
#io-channel-cells = <1>;
spi-max-frequency = <10000000>;
};
};
TI's Linux driver is properly loaded and IIO subsystem detects ADS7957 chip:
root@am335x-cmpc30:~# dmesg | grep ads [ 5.806242] ads7950 spi1.1: spi1.1 supply vref not found, using dummy regulator [ 5.878974] ads7950 spi1.1: Linked as a consumer to regulator.0
However I'm unable to read any channel except first and last (and values are wrong). Here is output from the iio_info Linux tool:
root@am335x-cmpc30:~# iio_info
Library version: 0.15 (git tag: v0.15)
Compiled with backends: local xml ip usb
IIO context created with local backend.
Backend version: 0.15 (git tag: v0.15)
Backend description string: Linux am335x-cmpc30 4.19.94-rt39cmpc30_v8-ga242ccf3f1 #1 PREEMPT RT Fri Oct 23 10:26:45 UTC 2020 armv7l
IIO context has 1 attributes:
local,kernel: 4.19.94-rt39cmpc30_v8-ga242ccf3f1
IIO context has 1 devices:
iio:device0: ads7957 (buffer capable)
17 channels found:
voltage0: (input, index: 0, format: be:u10/16>>2)
2 channel-specific attributes found:
attr 0: raw value: 1
attr 1: scale ERROR: Invalid argument (-22)
voltage1: (input, index: 1, format: be:u10/16>>2)
2 channel-specific attributes found:
attr 0: raw ERROR: Input/output error (-5)
attr 1: scale ERROR: Invalid argument (-22)
voltage2: (input, index: 2, format: be:u10/16>>2)
2 channel-specific attributes found:
attr 0: raw ERROR: Input/output error (-5)
attr 1: scale ERROR: Invalid argument (-22)
voltage3: (input, index: 3, format: be:u10/16>>2)
2 channel-specific attributes found:
attr 0: raw ERROR: Input/output error (-5)
attr 1: scale ERROR: Invalid argument (-22)
voltage4: (input, index: 4, format: be:u10/16>>2)
2 channel-specific attributes found:
attr 0: raw ERROR: Input/output error (-5)
attr 1: scale ERROR: Invalid argument (-22)
voltage5: (input, index: 5, format: be:u10/16>>2)
2 channel-specific attributes found:
attr 0: raw ERROR: Input/output error (-5)
attr 1: scale ERROR: Invalid argument (-22)
voltage6: (input, index: 6, format: be:u10/16>>2)
2 channel-specific attributes found:
attr 0: raw ERROR: Input/output error (-5)
attr 1: scale ERROR: Invalid argument (-22)
voltage7: (input, index: 7, format: be:u10/16>>2)
2 channel-specific attributes found:
attr 0: raw ERROR: Input/output error (-5)
attr 1: scale ERROR: Invalid argument (-22)
voltage8: (input, index: 8, format: be:u10/16>>2)
2 channel-specific attributes found:
attr 0: raw ERROR: Input/output error (-5)
attr 1: scale ERROR: Invalid argument (-22)
voltage9: (input, index: 9, format: be:u10/16>>2)
2 channel-specific attributes found:
attr 0: raw ERROR: Input/output error (-5)
attr 1: scale ERROR: Invalid argument (-22)
voltage10: (input, index: 10, format: be:u10/16>>2)
2 channel-specific attributes found:
attr 0: raw ERROR: Input/output error (-5)
attr 1: scale ERROR: Invalid argument (-22)
voltage11: (input, index: 11, format: be:u10/16>>2)
2 channel-specific attributes found:
attr 0: raw ERROR: Input/output error (-5)
attr 1: scale ERROR: Invalid argument (-22)
voltage12: (input, index: 12, format: be:u10/16>>2)
2 channel-specific attributes found:
attr 0: raw ERROR: Input/output error (-5)
attr 1: scale ERROR: Invalid argument (-22)
voltage13: (input, index: 13, format: be:u10/16>>2)
2 channel-specific attributes found:
attr 0: raw ERROR: Input/output error (-5)
attr 1: scale ERROR: Invalid argument (-22)
voltage14: (input, index: 14, format: be:u10/16>>2)
2 channel-specific attributes found:
attr 0: raw ERROR: Input/output error (-5)
attr 1: scale ERROR: Invalid argument (-22)
voltage15: (input, index: 15, format: be:u10/16>>2)
2 channel-specific attributes found:
attr 0: raw value: 523
attr 1: scale ERROR: Invalid argument (-22)
timestamp: (input, index: 16, format: le:S64/64>>0)
1 device-specific attributes found:
attr 0: current_timestamp_clock value: realtime
2 buffer-specific attributes found:
attr 0: watermark value: 1
attr 1: data_available value: 0
Scale returns error, because I didn't specify regulator in device tree. This is on purpose, because ADS7957 has hardwired 3.3V voltage on my PCB. But channels should work correctly.
While debugging, I added kernel logs in the TI's ADS7957 driver and the following errors showed up:
[ 598.869235] chan->address != TI_ADS7950_EXTRACT(ret, 12, 4) -> (1 != 0) [ 598.880442] chan->address != TI_ADS7950_EXTRACT(ret, 12, 4) -> (2 != 1) [ 598.891315] chan->address != TI_ADS7950_EXTRACT(ret, 12, 4) -> (3 != 1) [ 598.902920] chan->address != TI_ADS7950_EXTRACT(ret, 12, 4) -> (4 != 2) [ 598.912788] chan->address != TI_ADS7950_EXTRACT(ret, 12, 4) -> (5 != 2) [ 598.923756] chan->address != TI_ADS7950_EXTRACT(ret, 12, 4) -> (6 != 3) [ 598.934229] chan->address != TI_ADS7950_EXTRACT(ret, 12, 4) -> (7 != 3) [ 598.945349] chan->address != TI_ADS7950_EXTRACT(ret, 12, 4) -> (8 != 12) [ 598.956098] chan->address != TI_ADS7950_EXTRACT(ret, 12, 4) -> (9 != 12) [ 598.966881] chan->address != TI_ADS7950_EXTRACT(ret, 12, 4) -> (10 != 13) [ 598.977712] chan->address != TI_ADS7950_EXTRACT(ret, 12, 4) -> (11 != 13) [ 598.988269] chan->address != TI_ADS7950_EXTRACT(ret, 12, 4) -> (12 != 14) [ 598.999733] chan->address != TI_ADS7950_EXTRACT(ret, 12, 4) -> (13 != 14) [ 599.010557] chan->address != TI_ADS7950_EXTRACT(ret, 12, 4) -> (14 != 15)
So it seems, that for every read value driver detects, that it is coming from different channel that it expected.
I checked the SPI transmission with logic analyzer and decoded bytes looks valid (transmission ends with a correct value read from correct channel).
The same PCB works fine with self-coded baremetal driver on SYS/BIOS, so chip is working.
What am I doing wrong?