最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

ArmSoM---SPI開發(fā)指南

2023-10-27 19:03 作者:磊子啊_  | 我要投稿

1. 簡介

  • RK3588從入門到精通

  • 本?主要介紹在Rockchip平臺配置spi接口并且使用的方法

  • 開發(fā)板:ArmSoM-W3

  • Kernel:5.10.160

  • OS:Debian11


2. SPI接口概述

SPI(Serial Peripheral Interface),即串行外圍設(shè)備接口,是一種同步的,全雙工的,多設(shè)備的,多主機的通信協(xié)議,用于連接外圍設(shè)備,如ADC、DAC、數(shù)據(jù)存儲器、定時器、接受器等。


2.1 spi接口的結(jié)構(gòu)

ArmSom-W3_SPI_structure.png
  1. 主機:主機是SPI總線的控制者,它負責控制數(shù)據(jù)傳輸?shù)姆较蚝蛡鬏斔俣取?br>

  2. 從機:從機是SPI總線的被控制者,它根據(jù)主機發(fā)出的指令,發(fā)出或接收數(shù)據(jù)。

  3. MOSI(Master Out Slave In):主機輸出從機輸入,用于傳輸從主機到從機的數(shù)據(jù)。

  4. MISO(Master In Slave Out):主機輸入從機輸出,用于傳輸從從機到主機的數(shù)據(jù)。

  5. CK(Serial Clock):時鐘線,用于同步主機和從機之間的數(shù)據(jù)傳輸。

  6. CS(Chip Select):片選線,用于控制主機和從機之間的數(shù)據(jù)傳輸。

此外,SPI接口還有其他可選項,如中斷線(INT)、復位線(RESET)等。


2.2 SPI接口的工作原理

在SPI接口通信過程中,主機發(fā)出一個片選信號,然后在時鐘信號的控制下,主機發(fā)出一個字節(jié)的數(shù)據(jù),從機接收到數(shù)據(jù)之后,也會發(fā)出一個字節(jié)的數(shù)據(jù),主機接收到數(shù)據(jù)之后,發(fā)出一個片選信號,結(jié)束一次通信。

SPI接口有兩種工作模式:主模式和從模式。主模式下,主機控制從機,從機接收主機發(fā)出的指令。從模式下,從機可以接收主機發(fā)出的指令,并向主機發(fā)送數(shù)據(jù)。


3.SPI硬件接口

RK3588旗艦芯片上可使用的spi接口有5組,ArmSoM SOM-3588-LGA核心板采用LGA 506引腳封裝方式將spi資源全部引出,ArmSoM-W3開發(fā)板上40PIN引腳中有兩組spi接口:

ArmSom-W3_SPI_40PIN.png


4.spi設(shè)備配置

spi驅(qū)動相關(guān)代碼路徑:

drivers/spi/spi.c spi驅(qū)動框架
drivers/spi/spi-rockchip.c rk spi各接口實現(xiàn)
drivers/spi/spidev.c 創(chuàng)建spi設(shè)備節(jié)點,用戶態(tài)使用。
drivers/spi/spi-rockchip-test.c spi測試驅(qū)動,需要自己手動添加到Makefile編譯
Documentation/spi/spidev_test.c 用戶態(tài)spi測試工具


4.1 配置 DTS 節(jié)點

&spi1 {
status = "okay";
//assigned-clock-rates = <200000000>; //默認不用配置,SPI 設(shè)備工作時鐘
max-freq = <48000000>; /* spi internal clk, don't modify */
//dma-names = "tx","rx"; //使能DMA模式
//rx-sample-delay-ns = <10>; //默認不用配置,讀采樣延時
spi_dev@0 {
?compatible = "rockchip,spidev";
?reg = <0>;
?spi-max-frequency = <12000000>;
?spi-lsb-first; //IO 先傳輸 lsb ?
};
};

  • status:如果要啟用 SPI,則設(shè)為 okay,如不啟用,設(shè)為 disable。

  • spi_dev@0:本例子使用 CS0,故此處設(shè)為 0,如果使用 CS1,則設(shè)為 1。

  • compatible:這里的屬性必須與驅(qū)動中的結(jié)構(gòu)體:of_device_id 中的成員 compatible 保持一致。

  • reg:此處與 spi_dev@0 保持一致,這里設(shè)為0。

  • spi-max-frequency:此處設(shè)置 spi 使用的最高頻率,ITX-3588J 最高支持 50000000。


這里使用的驅(qū)動是drivers/spi/spidev.c,驅(qū)動設(shè)備加載注冊成功后,會出現(xiàn)類似這個名字的設(shè)備:/dev/spidev1.0。

一些常見的SPI驅(qū)動API接口:

Linux SPI API:

  • spi_register_driver():注冊SPI設(shè)備驅(qū)動程序。

  • spi_unregister_driver():注銷SPI設(shè)備驅(qū)動程序。

  • spi_setup():設(shè)置SPI總線和設(shè)備的參數(shù)。

  • spi_sync():同步方式進行SPI數(shù)據(jù)傳輸。

  • spi_message_init():初始化SPI消息結(jié)構(gòu)。

  • spi_message_add_tail():向SPI消息添加傳輸操作。

  • spi_sync():同步方式進行SPI數(shù)據(jù)傳輸。

  • spi_transfer():進行SPI數(shù)據(jù)傳輸。

SPI驅(qū)動中常用的ioctl請求值,這些請求值用于設(shè)置和讀取SPI設(shè)備的各種參數(shù),包括通信模式、字長、數(shù)據(jù)模式和通信速率等。這些請求值通常用于Linux的SPI驅(qū)動編程。以下是一些常用的SPI ioctl請求值:

  • SPI_IOC_RD_MODE: 讀取SPI設(shè)備的通信模式。

  • SPI_IOC_WR_MODE: 設(shè)置SPI設(shè)備的通信模式。

  • SPI_IOC_RD_MODE32: 讀取SPI設(shè)備的32位通信模式。

  • SPI_IOC_WR_MODE32: 設(shè)置SPI設(shè)備的32位通信模式。

  • SPI_IOC_RD_LSB_FIRST: 讀取SPI設(shè)備的LSB(Least Significant Bit)優(yōu)先模式。

  • SPI_IOC_WR_LSB_FIRST: 設(shè)置SPI設(shè)備的LSB優(yōu)先模式。

  • SPI_IOC_RD_BITS_PER_WORD: 讀取SPI設(shè)備的字長。

  • SPI_IOC_WR_BITS_PER_WORD: 設(shè)置SPI設(shè)備的字長。

  • SPI_IOC_RD_MAX_SPEED_HZ: 讀取SPI設(shè)備的最大通信速率。

  • SPI_IOC_WR_MAX_SPEED_HZ: 設(shè)置SPI設(shè)備的最大通信速率。

  • SPI_IOC_MESSAGE(N): 一次進行N次雙向或多次讀寫操作。


4.2 SPI測試實驗

將上述設(shè)備樹以及驅(qū)動修改之后更新板卡的內(nèi)核,通過SPI設(shè)備文件來判斷spi驅(qū)動是否加載成功

這里測試使用的是spi1這一組spi相關(guān)接口,檢查spi設(shè)備:

root@linaro-alip:~# ls /dev/spi*
/dev/spidev1.0
root@linaro-alip:~#

測試SPI接口,使用/dev/spidev1.0設(shè)備節(jié)點,實現(xiàn)短接MOSI和MISO線路以自發(fā)自收數(shù)據(jù),同時在未短接時報告錯誤


4.2.1 硬件連接

將SPI1的 MIOS與MOSI引腳(板卡上的7和8)短接即可,如下圖所示

ArmSom-W3_SPI_connect.png


4.2.2 測試程序

用戶應用層使用spidev驅(qū)動的步驟如下:

  1. 打開SPI設(shè)備文件:用戶可以通過打開/dev/spidevX.Y文件來訪問SPI設(shè)備,其中X是SPI控制器的編號,Y是SPI設(shè)備的編號。

  2. 配置SPI參數(shù):用戶可以使用ioctl命令SPI_IOC_WR_MODE、SPI_IOC_WR_BITS_PER_WORD和SPI_IOC_WR_MAX_SPEED_HZ來設(shè)置SPI模式、數(shù)據(jù)位數(shù)和時鐘速度等參數(shù)。

  1. 發(fā)送和接收數(shù)據(jù):用戶可以使用read和write系統(tǒng)調(diào)用來發(fā)送和接收SPI數(shù)據(jù)。寫入的數(shù)據(jù)將被傳輸?shù)絊PI設(shè)備,而從設(shè)備讀取的數(shù)據(jù)將被存儲在用戶提供的緩沖區(qū)中。

  2. 關(guān)閉SPI設(shè)備文件:當不再需要與SPI設(shè)備通信時,用戶應該關(guān)閉SPI設(shè)備文件。

總結(jié)起來,spidev驅(qū)動提供了一種簡單而靈活的方式來與SPI設(shè)備進行通信,使得用戶可以輕松地在Linux系統(tǒng)上開發(fā)和控制SPI設(shè)備。

armsom團隊 的測試程序spi_test.c如下:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/spi/spidev.h>

#define SPI_DEV_PATH "/dev/spidev1.0"

int fd;
static unsigned mode = SPI_MODE_0;
static uint8_t bits = 8;
static uint32_t speed = 1000000; // 設(shè)置SPI速度為1MHz
static uint16_t delay;

void transfer(int fd, uint8_t const *tx, uint8_t *rx, size_t len)
{
? ?int ret;
? ?struct spi_ioc_transfer tr = {
? ? ? ?.tx_buf = (unsigned long)tx,
? ? ? ?.rx_buf = (unsigned long)rx,
? ? ? ?.len = len,
? ? ? ?.delay_usecs = delay,
? ? ? ?.speed_hz = speed,
? ? ? ?.bits_per_word = bits,
? ? ? ?.cs_change = 0, // 設(shè)置為1以在每次傳輸前切換片選,這里不切換片選
? ?};

? ?ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);

? ?if (ret < 1) {
? ? ? ?perror("SPI transfer failed");
? ?}
}

void spi_init(void)
{
? ?int ret;
? ?// 打開 SPI 設(shè)備
? ?fd = open(SPI_DEV_PATH, O_RDWR);
? ?if (fd < 0) {
? ? ? ?perror("Can't open SPI device");
? ? ? ?exit(1);
? ?}

? ?// 設(shè)置 SPI 工作模式
? ?ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);
? ?if (ret == -1) {
? ? ? ?perror("Can't set SPI mode");
? ? ? ?exit(1);
? ?}

? ?// 設(shè)置位數(shù)
? ?ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
? ?if (ret == -1) {
? ? ? ?perror("Can't set bits per word");
? ? ? ?exit(1);
? ?}

? ?// 設(shè)置SPI速度
? ?ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
? ?if (ret == -1) {
? ? ? ?perror("Can't set max speed");
? ? ? ?exit(1);
? ?}

? ?// 打印設(shè)置
? ?printf("SPI mode: 0x%x\n", mode);
? ?printf("Bits per word: %d\n", bits);
? ?printf("Max speed: %d Hz\n", speed);
}

int main(int argc, char *argv[])
{
? ?if (argc != 2) {
? ? ? ?printf("Usage: %s <string_to_send>\n", argv[0]);
? ? ? ?return 1;
? ?}

? ?char *tx_buffer = argv[1]; // 獲取要發(fā)送的字符串作為命令行參數(shù)

? ?// 初始化SPI接口
? ?spi_init();

? ?// 設(shè)置要接收數(shù)據(jù)的緩沖區(qū)
? ?unsigned char rx_buffer[strlen(tx_buffer) + 1];

? ?// 執(zhí)行SPI數(shù)據(jù)傳輸
? ?transfer(fd, tx_buffer, rx_buffer, strlen(tx_buffer));

? ?// 打印發(fā)送和接收的數(shù)據(jù)
? ?printf("Sent: %s\n", tx_buffer);
? ?printf("Received: %s\n", rx_buffer);

? ?// 關(guān)閉SPI設(shè)備
? ?close(fd);

? ?return 0;
}


4.2.3 編譯&運行

開發(fā)板上下載gcc編譯器:

apt upgrade
apt update
apt install gcc

編譯:

gcc spi_test.c -o spi

短接與不短接的運行情況如下:

ArmSom-W3_SPI_run.png


ArmSoM---SPI開發(fā)指南的評論 (共 條)

分享到微博請遵守國家法律
泰顺县| 玉环县| 军事| 扎兰屯市| 闻喜县| 光泽县| 蛟河市| 班玛县| 德州市| 车致| 江北区| 壤塘县| 湘西| 河西区| 海兴县| 上虞市| 诸城市| 新巴尔虎右旗| 馆陶县| 石台县| 繁峙县| 长垣县| 临西县| 东乌| 绥德县| 日土县| 金乡县| 收藏| 江源县| 贵州省| 若尔盖县| 德州市| 贵德县| 沽源县| 蓬莱市| 溧阳市| 夏邑县| 斗六市| 光山县| 邯郸市| 旌德县|