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