This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM437x SPI read returns unexpected values

Hi Forum,

I am currently developing an spidev on am437x gpevm based custom board on spi port 4.
 below is my dts declaration.

myspi1_pins_default: myspi1_pins_default {
	pinctrl-single,pins = <
		0x250 ( PIN_INPUT | MUX_MODE0 ) /* (P25) spi4_sclk.spi4_sclk */
		0x254 ( PIN_OUTPUT | MUX_MODE0 ) /* (R24) spi4_d0.spi4_d0 */
		0x258 ( PIN_INPUT | MUX_MODE0 ) /* (P24) spi4_d1.spi4_d1 */
		0x25c ( PIN_OUTPUT | MUX_MODE0 ) /* (N25) spi4_cs0.spi4_cs0 */
		0x230 ( PIN_OUTPUT | MUX_MODE2 ) /* (H22) uart3_ctsn.spi4_cs1 */
	>;
};

 

     &spi4 {
            status = "okay";
            pinctrl-names = "default";
            pinctrl-0 = <&spi4_pins>;
            spidev@0 {
                spi-max-frequency = <24000000>;
                reg = <0>;
                compatible = "rohm,dh2228fv";
           };
      };

I have written my soi read write functions as below.

uint32_t write_spi(uint32_t address,uint32_t data)
{
	uint8_t mode =SPI_MODE_0;
	uint8_t bits=8;
	uint32_t spi_speed = 500000;
	uint32_t ret = 0;
	uint32_t fd;
	uint8_t wbuf[2];
	uint8_t rbuf[ARRAY_SIZE(wbuf)];
	int i;
	char *device = "/dev/spidev3.0";
	wbuf [1]=data;
	wbuf [0]=address+128;
	uint16_t delay=0;

	fd = open(device, O_RDWR);
	if (fd < 0)
		pabort("can't open device");
	printf("spi mode: %d\n", mode);
	printf("bits per word: %d\n", bits);
	printf("max speed: %d Hz (%d KHz)\n", spi_speed, spi_speed/1000);

	struct spi_ioc_transfer tr = {
		.tx_buf = (uint32_t)wbuf,
		.rx_buf = (uint32_t)rbuf,
		.len = ARRAY_SIZE(wbuf),
		.delay_usecs = delay,
		.speed_hz = spi_speed,
		.bits_per_word = bits,
	};

	ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
	printf("return value= %d \n",ret);
	if (ret < 1){
		pabort("can't send spi message");
	}
	else{
		for (ret = 0; ret < ARRAY_SIZE(wbuf); ret++) {
			printf("tx[%d]=%.2X\n",ret, wbuf[ret])   ;
		}
		puts("");
		printf("SPI message Sent\n");

	}


	close(fd);
	return ret;
}


uint32_t read_spi(uint32_t address,uint32_t ch_offset)
{
	uint8_t wbuf[2];
	uint8_t rbuf[(ARRAY_SIZE(wbuf)+2)];
	int n=0,a;

	uint8_t mode =SPI_MODE_0;
	uint8_t bits=8;
	uint32_t spi_speed = 500000;
	uint32_t ret = 0;
	uint32_t fd;
	char *device = "/dev/spidev3.0";
	wbuf [0]= address;
	fd = open(device, O_RDWR);
	if (fd < 0)
		pabort("can't open device");
	ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);
	if (ret == -1)
		pabort("can't set spi mode");

	ret = ioctl(fd, SPI_IOC_RD_MODE, &mode);
	if (ret == -1)
		pabort("can't get spi mode");
	struct spi_ioc_transfer tr = {
		.tx_buf = (uint32_t)wbuf,
		.rx_buf = (uint32_t)rbuf,
		.len = ARRAY_SIZE(wbuf),
		.delay_usecs = 0,
		.speed_hz = spi_speed,
		.bits_per_word = bits,

	};

	ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
	printf("ret: %d \n",ret);
	if (ret < 1){
		printf ("The device is not registed and can't be used.\n") ;
	}

	for (ret = 0; ret < ARRAY_SIZE(wbuf); ret++) {
		printf("rx[%d]=%x\n",ret,rbuf[ret])   ;
	}
	puts("");
        return rbuf[1];

}

i can see the correct read back on my logic analyzer. but when i get the read backs in the buffer i get wrong values. for example in this test case Iam writing value three to address 0 to the device connected to spi.

root@alpha-image:/bin# ./hc1 spi1wr 0x00 0x03
spi mode: 0
bits per word: 8
max speed: 500000 Hz (500 KHz)
return value= 2
tx[0]=80
tx[1]=03

SPI message Sent
0 device address
3 register address
spi1 write ---> OK
root@alpha-image:/bin# ./hc1 spi1rd 0x00
[ 2689.322770] spidev spi3.0: not using DMA for McSPI
ret: 2
rx[0]=ff
rx[1]=f

0 device address
b6 value
spi1 read ---> OK
root@alpha-image:/bin#


below are my logic analyzer outputs for write and reds returning the correct values.

read command logic analyzer

Has anyone faced a similar problem where you see proper reads in the logic analyzer but the reads returns are wrong. Any suggestions can be appreciated.

Regards

-Parker