Доброго дня!
Необходимо по SPI управлять матрицей VITA1300, на плате стоит процессор DM365, используется linux-2.6.18.
Технические особенности SPI на устройствах:
DM365: сдвиговый регистр 16 бит
VITA1300: адрес 9 бит, данные 16 бит
В качестве программы используется пример идущий в составе ядра.
Чтение регистра:
CODE
uint8_t tx[] = {0, 8};
uint8_t rx[ARRAY_SIZE(tx)] = {0, 0};
struct spi_ioc_transfer tr = {
.tx_buf = (unsigned long)tx,
.rx_buf = (unsigned long)rx,
.len = ARRAY_SIZE(tx),
.delay_usecs = delay,
.speed_hz = speed,
.bits_per_word = 26,
};
ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
Запись в регистр:
CODE
uint8_t trv[] = {1, 8};
uint8_t twv[] = {7, 9};
struct spi_ioc_transfer wr[2] = {
[0] = {
.tx_buf = (unsigned long)trv,
.rx_buf = (unsigned long)NULL,//rx,
.len = ARRAY_SIZE(trv),
.delay_usecs = delay,
.speed_hz = speed,
.bits_per_word = 10
},
[1] = {
.tx_buf = (unsigned long)twv,
.rx_buf = (unsigned long)NULL,//rx,
.len = ARRAY_SIZE(twv),
.delay_usecs = delay,
.speed_hz = speed,
.bits_per_word = 16
}
};
ret = ioctl(fd, SPI_IOC_MESSAGE(2), wr);
К чтению вопросов нет, возвращаемые значения соответствуют указанным в документации.
А вот с записью проблема, сама команда проходит без ошибок, но следующая команда чтения возвращает не изменённое значение.
В драйвер были вставлены отладочные сообщения, вывод следующий:
CODE
starting davinci_spi_setup
davinci_spi_setup_transfer: bits_per_word 8, hz 2500000
davinci_spi_setup_transfer: bits_per_word 8
starting davinci_spi_setup
davinci_spi_setup_transfer: bits_per_word 8, hz 2500000
davinci_spi_setup_transfer: bits_per_word 8
starting spidev_message
txbuf: [0] 0, [1davinci_spi_setup_transfer: bits_per_word 8, hz 2500000
] 0x8
davinci_spi_setup_transfer: bits_per_word 10
davinci_spi_chipselect: value 1
starting davinci_spi_bufs_pio
davinci_spi_bufs_pio, conv 2, count 1, len 2
starting davinci_spi_bufs_prep
davinci_spi_bufs_pio: data1_reg_val 268435456, cs_hold 1 << chhold_shift 28,
davinci_spi_bufs_pio: t->tx_buf
davinci_spi_bufs_pio: SPIINT 0x0, SPIFLG 0x1000200
#############################
davinci_spi_tx_buf_u16: tx 0x801
davinci_spi_bufs_pio, bits_per_word 8
davinci_spi_bufs_pio: data1_reg_val |= (mask & tx_data) 0x10fe0801 |= (0xFFFF & 0x801)
davinci_spi_bufs_pio: buf_val 0x80ff00c0
davinci_spi_bufs_pio: SPIFMT0 val 0x300a
davinci_spi_bufs_pio: SPIFMT1 val 0x300a
davinci_spi_bufs_pio: SPIFMT2 val 0x300a
davinci_spi_bufs_pio: SPIFMT3 val 0x300a
davinci_spi_bufs_pio: buf_val 0x80ff00c0 & SPI_SPIBUF_TXFULL_MASK 0x20000000 = 0x0
davinci_spi_bufs_pio: SPIFLG 0x1000200, count 0
#######################
davinci_spi_bufs_pio: int_status 0x1000200
starting davinci_spi_check_error
davinci_spi_check_error: ret 0
davinci_spi_bufs_pio: davinci_spi->count 2, t->len 2
davinci_spi_setup_transfer: bits_per_word 8, hz 2500000
davinci_spi_setup_transfer: bits_per_word 16
starting davinci_spi_bufs_pio
davinci_spi_bufs_pio, conv 2, count 1, len 2
starting davinci_spi_bufs_prep
davinci_spi_bufs_pio: data1_reg_val 268435456, cs_hold 1 << chhold_shift 28,
davinci_spi_bufs_pio: t->tx_buf
davinci_spi_bufs_pio: SPIINT 0x0, SPIFLG 0x1000200
#############################
davinci_spi_tx_buf_u16: tx 0x907
davinci_spi_bufs_pio, bits_per_word 8
davinci_spi_bufs_pio: data1_reg_val |= (mask & tx_data) 0x10fe0907 |= (0xFFFF & 0x907)
davinci_spi_bufs_pio: buf_val 0x80fe0000
davinci_spi_bufs_pio: SPIFMT0 val 0x3010
davinci_spi_bufs_pio: SPIFMT1 val 0x3010
davinci_spi_bufs_pio: SPIFMT2 val 0x3010
davinci_spi_bufs_pio: SPIFMT3 val 0x3010
davinci_spi_bufs_pio: buf_val 0x80fe0000 & SPI_SPIBUF_TXFULL_MASK 0x20000000 = 0x0
davinci_spi_bufs_pio: SPIFLG 0x1000200, count 0
#######################
davinci_spi_bufs_pio: int_status 0x1000200
starting davinci_spi_check_error
davinci_spi_check_error: ret 0
davinci_spi_bufs_pio: davinci_spi->count 2, t->len 2
davinci_spi_setup_transfer: bits_per_word 8, hz 2500000
davinci_spi_setup_transfer: bits_per_word 8
davinci_spi_chipselect: value 0
transfer: ret = 4
00 00
Видно, что в драйвер попадают все данные которые я ему отправляю. Обработка всех данных происходит за одну транзакцию, chip-select не меняет своего состояния. Под первый данные выделено 10 clock-в, что подтверждается значением SPIFMT, последнее значение A, под вторые данные выделено 16 clock-в, последнее значение 10 в SPIFMT. Таким образом суммарная посылка составляет 26 бит, 9 бит адрес + 1 бит команда + 16 бит данные.
К сожалению на осцилограффе удаётся отловить только вторую посылку и данные там корректны.
Но увы, запись значения в регистр не происходит. В чём ошибка?
Спасибо.