Hi everyone,
My setup is the following :
I would like to be able to use spidev driver to communicate with some sensors from a user-space application.
I managed to get the /dev/spidev3.0 showing up (thanks to Alvaro Martinez answer on this topic), but I can't write anything on the bus.
I am using the following command :
echo hello > /dev/spidev3.0
I then verified with my logic analyzer (on Arduino header J1704), nothing happens...
I also tested with spidev_test.c, and even by shorting MISO and MOSI pins I do not get the desired output :
spi mode: 0x0
bits per word: 8
max speed: 500000 Hz (500 KHz)
RX | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ............................
Can anyone help me ?
Thank you in advance.
Arnaud
已解决! 转到解答。
Hi Arnaud,
You need to populate and remove some resistors. Review in the schematic the resistors : R1724, R1725, R1726, R1727, R1731,R1633, R1634, R1635, R1636
Luis
Hi Arnaud,
Thanks for posting your example device tree file, it helped me to get up and running :-)
A minor point and fairly easy to spot but line 39 is missing a '6', it should be:
MX6UL_PAD_ENET2_TX_EN__ECSPI4_MOSI 0x100b1
Neil
Hi Luis,
Thank you for your quick answer !
I moved resistors R1633, R1634, R1635, R1636 to R1724, R1725, R1726, R1727 and it works like a charm.
I did not change R1731 though.
I still have to handle the CS line as it does not toggle but I think it is due to a misconfiguration in my device tree :
&ecspi4 {
#address-cells = <1>;
#size-cells = <0>;
fsl,spi-num-chipselects = <1>;
cs-gpios = <0>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_ecspi4>;
status = "okay";
spidev@0x00 {
compatible = "spidev";
spi-max-frequency = <20000000>;
reg = <0>;
};
};
I am pretty new to Embedded Linux development, and device-trees, but I think that the variable cs-gpios is wrong ?
--------------------------------------------------------------------------------------------------------------------------------------------------------
Updated: Following Luis answer permitted me to get the CS pin to work, I put the updated device tree right below.
If anyone is interested in the modifications I had to make to make the spidev work on iMX6UL-EVK :
1 - Device tree (I used Yocto Project)
I disabled fec2, which is Ethernet PHY 2 as it cannot be used anymore in this configuration
#include "imx6ul-14x14-evk.dts"
/ {
spi3 {
status = "okay";
};
};
&fec2 {
status = "disabled";
};
&ecspi4 {
#address-cells = <1>;
#size-cells = <0>;
fsl,spi-num-chipselects = <1>;
cs-gpios = <&gpio2 15 0>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_ecspi4>;
status = "okay";
spidev@0x00 {
compatible = "spidev";
spi-max-frequency = <80000000>;
reg = <0>;
};
};
&iomuxc {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_hog_1>;
imx6ul-evk {
pinctrl_ecspi4: ecspi4grp {
fsl,pins = <
MX6UL_PAD_ENET2_TX_CLK__ECSPI4_MISO 0x100b1
MXUL_PAD_ENET2_TX_EN__ECSPI4_MOSI 0x100b1
MX6UL_PAD_ENET2_TX_DATA1__ECSPI4_SCLK 0x100b1
MX6UL_PAD_ENET2_RX_ER__ECSPI4_SS0 0x10b0
>;
};
};
};
2 - Move resistors R1633, R1634, R1635, R1636 to R1724, R1725, R1726, R1727. These resistors are near J1703 and on the back of the board (in the middle).
3 - Compile spidev_test.c for the iMX6UL and use it as following (remember to short MISO and MOSI pins) :
./a.out -s 1000000 -v
-s indicates the speed in Hz, here 1MHz.
-v is verbose mode (use -h to see all options)
Thank you Luis Casado, and Alvaro Martinez (cf. on this topic) again. I will have a look into CS pin handling tomorrow.
Arnaud
Hello Arnaud,
Try :
&ecspi4 {
fsl,spi-num-chipselects = <1>;
cs-gpios = <&gpio2 15 0>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_ecspi4>;
status = "okay";
spidev0: spi@0 {
reg = <0>;
compatible = "spidev";
spi-max-frequency = <1000000>;
};
};
….
pinctrl_ecspi4: ecspi4grp {
fsl,pins = <
MX6UL_PAD_ENET2_RX_ER__GPIO2_IO15 0x10b0
MX6UL_PAD_ENET2_TX_EN__ECSPI4_MOSI 0x100b1
MX6UL_PAD_ENET2_TX_DATA1__ECSPI4_SCLK 0x100b1
MX6UL_PAD_ENET2_TX_CLK__ECSPI4_MISO 0x100b1
>;
};
Luis
Thank you Luis for your answer,
It works like a charm ! CS Pin is now properly toggled.
However, I still have a problem with the CS handling in the spidev driver. This is my method (SPI interface is configured elsewhere) :
IOBus_Error SPI::message(const unsigned char *txBuffer, unsigned char *rxBuffer, ssize_t &length, long flags) {
IOBus_Error error = IOBus_Error_None;
int status;
if (handle <= 0) openHandle();
// Build transfer
struct spi_ioc_transfer transfer;
memset(&transfer, 0, sizeof(spi_ioc_transfer));
transfer.tx_buf = (unsigned long)&txBuffer[0];
transfer.rx_buf = (unsigned long)&rxBuffer[0];
transfer.len = length;
transfer.delay_usecs = 0;
transfer.speed_hz = configuration.speed;
transfer.bits_per_word = configuration.bits;
transfer.cs_change = flags & SPI_Flag_CSChange;
// Execute transfers
status = ioctl(handle, SPI_IOC_MESSAGE(1), &transfer);
// Check for errors
if ( status < 0) return IOBus_Error_Write;
return IOBus_Error_None;
}
For example, I want to read one byte at the address 0x24 of my device, so my buffers are the following :
txBuffer = {0x24, 0x00}
rxBuffer = {0x00, 0x00}
cs_change is set to 0 and length to 2
When I use my logic analyzer, I can see that the CS line is pulled up between the 0x24 and 0x00 bytes causing my device not to answer.
I then tried to use 16 bits per word in the SPI configuration to keep the CS line low, and it worked. But it is certainly not the way it has to be handled...
I also tried to set cs_change to 1 but it did not change anything on the CS line. And as I am aware of, cs_change must be 0 to let the CS line unselected between transfers.
Here is a capture of the wrong output on my logic analyzer :
And this is a capture of the wanted output using 16 bits per word, we can see that in this case my device correctly answers (0x05 is the value I was waiting for) :
What am I doing wrong ?
-----------------------------------------------------------------------------------------------------------------------------------------------------
Thanks Luis for your help with the device-tree, I will update my previous comment to reflect the configuration you just gave to me.
I still have another questions about the device-tree configuration:
Thanks in advance,
Arnaud
Hello,
o https://www.kernel.org/doc/Documentation/devicetree/bindings/spi/spi-bus.txt
o You can select GPIO or native CS.
Luis
Thank you for your answer, it makes sense to me now.
I used MX6UL_PAD_ENET2_RX_ER__GPIO2_IO15 instead of MX6UL_PAD_ENET2_RX_ER__ECSPI4_SS0 in my device tree, and the CS pin behavior is now perfect.
Thanks again,
Arnaud