Hi Maxime,
Hi Siarhei,
On Mon, 26 Sep 2016 21:24:28 +0200
Post by Maxime RipardYes, I guess apart from all the tests Siarhei suggested already,
disconnecting the device entirely and trying to make some transfers
would be a good test.
I did that now. I removed the slave (making the entire SPI bus open) and in order
to be able to measure a stable signal I put a resistor on the SPI bus (at SCLK) instead.
Then I sent some stuff via SPI (with 125 kHz).
When I made the resistor pull-up (2.2 kΩ to 3.3 V), it acted the same as it did with the
slave (weird dip at the very beginning of each message, fine otherwise).
When I made the resistor pull-down (2.2 kΩ to 0 V), it worked just fine, without dip.
It's 100% reproducible: Everytime I measure, I get that result (did it 27 times
now).
I've checked the sunxi-tools gpio output: There, for PC20 (SCLK), "pull" is "0"
(whatever that means).
Then I switched the mux of PC20 to GPIO mode and tried driving it myself. Works
just fine, no unexpected dips (though I can't get it faster than 200 μs period
that way and I didn't drive any other signals in parallel - no SSEL either).
The kernel version is 4.11.0-rc1.
The relevant part of the SPI program is:
/* probably sunxi specific */
#define MAX_LLTRANSFER_SIZE 64U
int LLinit(void) {
int fd = open("/dev/spidev32766.0" /* latter is CSIX */, O_RDWR);
if (fd == -1) {
perror("open");
return -1;
}
uint8_t mode = SPI_CPHA | SPI_CPOL; /* 3 */
int ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);
if (ret == -1)
perror("can't set spi mode");
ret = ioctl(fd, SPI_IOC_RD_MODE, &mode);
if (ret == -1)
perror("can't get spi mode");
uint8_t bits_per_word = 0U;
uint32_t max_write_speed = 125000U;
/* FIXME remove this because it's in the DTS file */
if (ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &max_write_speed) == -1) {
perror("ioctl");
return -1;
}
if (ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits_per_word) == -1) {
perror("ioctl SPI_IOC_WR_BITS_PER_WORD");
return -1;
}
return fd;
}
/** Sends some block and at the same time receives another block.
@param fd file descriptor for the spidev
@param regno TSS463AA register number
@param controlvalue TSS463AA control value
@param senderbuf buffer to send
@param receiverbuf buffer to receive to AT THE SAME TIME
@param bothbufsz number of Bytes of the buffer to send, and to receive
*/
void LLtransceive(int fd, unsigned char regno, unsigned char controlvalue,
const void* senderbuf, void* receiverbuf, size_t bothbufsz) {
printf("LLtransceive %d\n", (int) bothbufsz);
/* limited to 64 Byte for sun4i */
struct spi_ioc_transfer xfer[MAX_LLTRANSFER_SIZE];
uint8_t acbuf[MAX_LLTRANSFER_SIZE];
uint8_t bcbuf[MAX_LLTRANSFER_SIZE];
int i;
if (bothbufsz > MAX_LLTRANSFER_SIZE - 2)
abort();
acbuf[0] = regno;
acbuf[1] = controlvalue;
if (senderbuf)
memcpy(&acbuf[2], senderbuf, bothbufsz);
else
memset(&acbuf[2], 0xFF, bothbufsz);
memset(xfer, 0, sizeof xfer);
xfer[0].tx_buf = (unsigned long) &acbuf[0];
xfer[0].rx_buf = (unsigned long) &bcbuf[0];
// FIXME add xfer[0].delay_usecs = 16;
xfer[0].len = bothbufsz + 2;
//xfer[1].cs_change = 1;
if (ioctl(fd, SPI_IOC_MESSAGE(1), xfer) == -1)
abort();
if (bcbuf[0] != 0xAAU || bcbuf[1] != 0x55U) {
/* should have been sent by TSS463AA to ensure synchronization */
fprintf(stderr, "bcbuf wrong %X %X\n", (unsigned) bcbuf[0],
(unsigned) bcbuf[1]);
// exit(1);
} else
fprintf(stderr, "bcbuf OK\n");
}
Note: SPI2 pins are: PC19[= CS, gpio83], PC20[SCK, gpio84], PC21, PC22.
Next, I'll try to disable CS manual mode in drivers/spi/spi-sun4i.c and test - still with nothing but the resistor connected. Let's see...
--
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.