У меня следующая странная проблема. Я настроил BBB для активации модуля spi1. Модуль подключен к микросхеме F-RAM (FM25CL64B). Я сделал все необходимые настройки. Присутствует /dev/spidev1.0, и я написал небольшую программу для записи и чтения из чипа, открыв /dev/spidev1.0 и используя ioctl с макросом SPI_IOC_MESSAGE.
Использование этой программе мне удалось успешно записать 32 байта текста в чип F-RAM. Чтение также казалось успешным ... Откуда я знаю, что они оба были успешными? Я использовал анализатор logi c с активированным декодером SPI, чтобы реально увидеть, что происходит на всех четырех линиях SPI. Наблюдая за всеми линиями SPI, я мог видеть, что операции записи и чтения генерируют правильные сигналы с правильной синхронизацией, и все сигналы синхронизируются c. CS включает микросхему во время транзакции, CLK синхронизирует каждый байт в 8-битных словах (как настроено), строки данных показывают правильные значения, которые я мог видеть благодаря декодеру SPI, который показывает значение байта прямо над каждым 8- битовая сигнальная последовательность строк MOSI и MISO.
Проблема в том, что, хотя я вижу, что правильная информация передается по линии MISO во время операции чтения, буфер, который я предоставляю ioctl (iSPIR, SPI_IOC_MESSAGE ( 2), xfer) заполнен нулями.
Я намеренно инициализировал этот буфер другими значениями, так что я могу видеть, записывает ли ioctl даже в него. И это так. Нули.
Теперь тот факт, что я мог видеть все байты, отправленные по строке MISO во время операции чтения, доказывает, что операция записи не только выглядела правильно в анализаторе, но фактически записывала нужные данные во время предыдущего операция записи.
Я несколько раз проверял, правильно ли настроена строка MISO, в файле dts (который я могу перестроить и переустановить по требованию). Я проверил, правильный ли это вывод и настроен ли он как вход. Кажется, все настроено правильно.
Я запустил программу как root на случай проблем с разрешениями - без разницы.
Я также реализовал spi-связь в режиме GPIO. Т.е. модуль spi отключен, все линии настроены как GPIO. CE, CLK, MOSI настроены как отупуты, а MISO настроены как входные. Таким образом, я мог реализовать всю связь в программном обеспечении, чтобы иметь полный контроль над линиями. Сделав это, на этот раз мне удалось успешно заполнить буфер правильными данными из чипа F-RAM. Т.е. операция последовательного чтения прошла нормально с чипа F-RAM до моего буфера пользовательского пространства. Мне удалось распечатать данные в консоли. Однако это работало слишком медленно. Также я считаю неэффективным использование чисто программной реализации SPI com, когда есть модуль, доступный для использования.
Чтобы написать пример программы, я использовал spi_test. c пример с открытым исходным кодом, доступный онлайн. Я также собрал и запустил spi_test. c сам без изменений, тот же результат.
Вот список моей программы (Соответствующие фрагменты):
// SPI config ...
int InitSPIReadMode(const char* pstrDeviceF)
{
int file;
__u8 wr_mode = SPI_MODE_0, rd_mode = SPI_MODE_0, lsb = 0, bits = 8;
__u32 speed = CLOCK_FREQ_HZ; // 500kHz
if((file = open(pstrDeviceF, O_RDWR)) < 0)
{
printf("Failed to open the bus.");
/* ERROR HANDLING; you can check errno to see what went wrong */
exit(1);
}
if(ioctl(file, SPI_IOC_RD_MODE, &rd_mode) < 0)
{
printf("SPI rd_mode\n");
return -1;
}
if(ioctl(file, SPI_IOC_RD_LSB_FIRST, &lsb) < 0)
{
printf("SPI rd_lsb_fist\n");
return -1;
}
if(ioctl(file, SPI_IOC_RD_BITS_PER_WORD, &bits) < 0)
{
printf("SPI bits_per_word\n");
return -1;
}
if(ioctl(file, SPI_IOC_RD_MAX_SPEED_HZ, &speed) < 0)
{
printf("SPI max_speed_hz\n");
return -1;
}
printf("%s: spi wr-mode=%d, spi rd-mode=%d, %d bits per word, %s, %d Hz max\n", pstrDeviceF, wr_mode, rd_mode, bits, lsb ? "(lsb first) " : "(msb first)", speed);
xfer[0].cs_change = 0; /* Keep CS activated */
xfer[0].delay_usecs = 0; //delay in us
xfer[0].speed_hz = CLOCK_FREQ_HZ; //speed
xfer[0].bits_per_word = 8; // bites per word 8
xfer[1].cs_change = 0; /* Keep CS activated */
xfer[1].delay_usecs = 0;
xfer[1].speed_hz = CLOCK_FREQ_HZ;
xfer[1].bits_per_word = 8;
return file;
}
В основной функции: ( как показывает анализатор logi c, этот код правильно отправляет команду, адрес и затем синхронизирует 32 байта данных)
int iSPIR = InitSPIReadMode("/dev/spidev1.0"); //open("/dev/spidev1.0", O_RDWR | O_SYNC);
char arrInstruct[3] = { OPCO_READ, 0x00, 0x00 };
char arrFRamData[512];
for(int pos = 0; pos < 512; pos++) arrFRamData[pos] = pos;
xfer[0].tx_buf = (unsigned long)arrInstruct;
xfer[0].len = 3;
xfer[1].rx_buf = (unsigned long)arrFRamData;
xfer[1].len = 32;
if(ioctl(iSPIR, SPI_IOC_MESSAGE(2), xfer) < 0) printf("ioctl write error %s.\n", strerror(errno));
// hex dumping of the arrFRamData buffer.
xfer - глобальная переменная, определяемая как:
struct spi_ioc_transfer xfer[2];
Заранее большое спасибо! :)