LuckFox SPI: обмен данными между устройствами Master и Slave |
![]() |
Добавил(а) microsin |
В этой статье демонстрируется пример конфигурирования обмена между двумя SPI-устройствами Rockchip, работающих в качестве Master и Slave, и непосредственного манипулирования интерфейсом SPI в user space, чтобы обеспечить обмен данными между Master и Slave (перевод документации [1]). Архив с кодом можно скачать с Google-диска (см. ссылку на Code.zip в оригинальной документации [1]). [1. Модификация конфигурации Kernel] 1.1. Сохраните файл и выполните очистку, после чего выполните перекомпиляцию. $ cd ~/SDK_directory/sysdrv/source/kernel
$ cp ./arch/arm/configs/luckfox_rv1106_linux_defconfig .config
$ make ARCH=arm menuconfig
1.2. Изменение конфигурации 1. Выберите "Device Drivers": 2. Выберите "Select "SPI support": 3. Сконфигурируйте user space на непосредственную работу с SPI: 4. Разрешите "Rockchip SPI controller driver" для Master выбором "Y": 5. Разрешите "SPI slave protocol handlers" для Slave выбором "Y": 1.3. Сохраните config, вернитесь в директорию SDK и перекомпилируйте ядро (kernel). $ make ARCH=arm savedefconfig
$ cp defconfig arch/arm/configs/luckfox_rv1106_linux_defconfig
$ cd ~/SDK_directory
$ ./build kernel
[2. Модификация Device Tree] 1. Файлы конфигурации устройств всех плат находятся в каталоге: < SDK directory>/project/cfg/BoardConfig_IPC/ Каждый *.mk файл в этом каталоге описывает конфигурационные параметры отдельной модели платы Luckfox Pico, такие как целевая архитектура (target architecture), загрузочный носитель (boot medium), используемый загрузчик (Uboot), ядро (kernel) и настройки таблицы разделов (partition settings). Переменная RK_KERNEL_DTS файла конфигурации платы указывает файл дерева устройств (Device Tree Source, DTS) для ядра. Если взять в качестве примера Luckfox Pico и открыть его файл конфигурации BoardConfig-EMMC-NONE-RV1103_Luckfox_Pico-IPC.mk, то мы увидим, что переменная RK_KERNEL_DTS указывает файл rv1103g-luckfox-pico.dts. Основываясь на значении переменной RK_KERNEL_DTS, путь файла дерева устройств платы Luckfox Pico определен следующим образом: < SDK directory>/sysdrv/source/kernel/arch/arm/boot/dts/rv1103g-luckfox-pico.dts 2. Измените файл Device Tree. На стороне Master: &spi0 { На стороне Slave: &spi0 { 2.2. Компиляция ядра 1. Конфигурирование компиляции осуществляется выбором в меню скрипта ./build.sh lunch одной из конфигураций для плат LuckFox Pico, LuckFox Pico Mini A, LuckFox Pico Mini B, LuckFox Pico Plus и LuckFox Pico Pro/Max: ~/luckfox-pico$ ./build.sh lunch
ls: cannot access 'BoardConfig*.mk': No such file or directory
В этом примере был выбран вариант 0, т. е. плата Luckfox Pico. 2. Перекомпилируйте ядро командой: ~/luckfox-pico$ ./build.sh kernel
2.3. Перепрошейте скомпилированное firmware. [3. SPI-обмен в программе на C] 3.1. Функция ioctl. При написании программы приложения функция ioctl используется для конфигурирования настроек SPI. Прототип этой функции следующий: #include < sys/ioctl.h> Когда функция ioctl используется для обмена через SPI, обычно применяют следующие параметры запроса: SPI_IOC_RD_MODE: используется для чтения настроек текущего режима обмена SPI. Этот параметр запроса читает информацию режима в целочисленную переменную для проверки текущих настроек полярности и фазы SPI (CPOL и CPHA). SPI_IOC_WR_MODE: используется для установки режима обмена SPI. Вам нужно предоставить целочисленное значение, обычно составленное из двух двоичных цифр для представления полярности и фазы обмена SPI. SPI_IOC_RD_BITS_PER_WORD: используется для чтения количества бит в слове данных. Прочитанное значение будет сохранено в предоставленную целочисленную переменную. SPI_IOC_WR_BITS_PER_WORD: используется для установки количества бит в слове данных. Вам нужно предоставить целочисленное значение, чтобы указать размер передаваемого и принимаемого слова в битах. SPI_IOC_RD_MAX_SPEED_HZ: используется для чтения максимальной скорости данных (частоты тактов) шины SPI. Этот параметр запроса считывает информацию скорости в целочисленную переменную. SPI_IOC_WR_MAX_SPEED_HZ: используется для установки максимальной скорости шины SPI. Вам нужно предоставить целочисленное значение для указания частоты тактов шины SPI. SPI_IOC_MESSAGE(N): используется для выполнения операций чтения и записи по шине SPI. Этот параметр запроса требует указателя на массив элементов структур spi_ioc_transfer, где каждый элемент описывает операцию транзакции SPI, благодаря чему можно выполнить несколько операций. 3.2. Пример программы. Следующие две программы осуществляют SPI-обмен друг с другом в качестве главного (Master) и подчиненного (Slave) устройства шины. На стороне Master: #include < stdio.h> На стороне Slave: #include < stdio.h> 3.3. Путь файла для устройства SPI задается строкой: #define SPI_DEVICE_PATH "/dev/spidev0.0"
3.4. Открытие устройства SPI. Эта секция кода пытается открыть указанный файл устройства SPI. if ((spi_file = open(SPI_DEVICE_PATH, O_RDWR)) < 0) { 3.5. Конфигурирование SPI. Следующий код используется для конфигурирования обмена в режиме SPI Mode 0 (clock polarity 0, clock phase 0) и устанавливает размер слова данных 8 бит, чтобы обеспечить корректность обмена данными SPI. uint8_t mode = SPI_MODE_0; Переменная transfer определяет структуру данных типа spi_ioc_transfer, содержащую параметры транзакции SPI. Здесь указываются буферы данных передачи и приема, длина транзакции, задержка, скорость SPI в Герцах и размер слова данных. Эта структура будет передаваться в SPI_IOC_MESSAGE функции ioctl, чтобы выполнилась транзакция SPI. struct spi_ioc_transfer transfer = { 3.6. Отправка данных. Следующий код использует функцию ioctl для выполнения транзакции SPI. Указывается количество транзакций 1 с помощью макроса SPI_IOC_MESSAGE(1), а в третьем параметре передается ссылка на переменную транзакции, сконфигурированной ранее. Если транзакция SPI была неудачной, то печатается сообщение об ошибке, и дескриптор файла устройства SPI закрывается. // Отправка данных: 3.7. Прием данных на стороне Slave Следующий сегмент кода начинается с очистки буфера данных, затем проверяется возвращаемое значение из функции ioctl, чтобы определить, были ли приняты данные. Если данные не были приняты, то происходит прокрутка цикла, таким способом происходит ожидание поступления данных от Master. При получении данных функция ioctl возвратит длину принятых данных. Затем принятые данные печатаются в hex-формате, и процесс повторяется - снова запускается цикл ожидания данных. while(1) { 3.8. Кросс компиляция. См. описание процесса компиляции в статье [2]. [4. Запуск программ] 4.1. Передача файла. Передача может быть осуществлена с помощью TFTP или ADB (см. [2]). $ adb push path_to_file destination_on_development_board
.. или: $ adb -s device_serial_number push path_to_file destination_on_development_board
Серийный номер в команде adb необходимо указывать, когда к хосту через USB подключено несколько устройств: $ adb -s d48936ed7d155xxx push spi /
4.2. Соединения между устройствами Master и Slave. 1. Соедините друг с другом землю устройств GND. 4.3. Запуск программы. Поменяйте права доступа на исполняемый файл spi и запустите программу на обоих устройствах: # chmod +x spi
# ./spi
4.4. Результаты работы программ На стороне Master осуществляется передача данных: На стороне Slave происходит вывод полученных данных: [Ссылки] 1. LuckFox SPI Master-Slave Communication site:wiki.luckfox.com. |