|
本文小編將從應用角度為大家講解飛凌嵌入式OKMX8MP-C開(kāi)發(fā)板的M核SPI間通訊的實(shí)現方式。
01SPI主模式
1. SPI初始化
SPI初始化主要包括總線(xiàn)時(shí)鐘、管腳和相應寄存器的初始化。具體如下:
(1)SPI總線(xiàn)時(shí)鐘:現將SPI總線(xiàn)倍頻到800MHz,再10分頻到80MHz。
[url=]復制[/url]
CLOCK_SetRootMux(kCLOCK_RootEcspi2, kCLOCK_EcspiRootmuxSysPll1); //SPI2總線(xiàn)時(shí)鐘使用PLL1-800MHz CLOCK_SetRootDivider(kCLOCK_RootEcspi2, 2U, 5U); //分頻因子為2*5=10,設置SPI2總線(xiàn)時(shí)鐘為80MHz
(2)管腳配置:選擇SPI2的四個(gè)管腳。
[url=]復制[/url]
IOMUXC_SetPinMux(IOMUXC_ECSPI2_MISO_ECSPI2_MISO, 0U); // SPI2-MISO IOMUXC_SetPinMux(IOMUXC_ECSPI2_MOSI_ECSPI2_MOSI, 0U); // SPI2-MOSI IOMUXC_SetPinMux(IOMUXC_ECSPI2_SCLK_ECSPI2_SCLK, 0U); // SPI2-SCLK IOMUXC_SetPinMux(IOMUXC_ECSPI2_SS0_ECSPI2_SS0, 0U); // SPI2-SSO
(3)SPI速率:設置速率為500K。
[url=]復制[/url]
#define TRANSFER_BAUDRATE 500000U // 速率 500K
(4)數據長(cháng)度選擇:8bit。
[url=]復制[/url]
config->burstLength = 8; // 數據長(cháng)度 8bit
(5)四種模式選擇:CPOL和CPHA的四種組合即為SPI的四種模式。
[url=]復制[/url]
config->clockInactiveState = kECSPI_ClockInactiveStateLow; // 時(shí)鐘SCL: 活動(dòng)時(shí)低電平,空閑時(shí)高電平 config->dataLineInactiveState = kECSPI_DataLineInactiveStateLow;// 數據MOSI&MISO: 活動(dòng)時(shí)低電平,空閑時(shí)高電平 config->chipSlectActiveState = kECSPI_ChipSelectActiveStateLow;// 片選SS: 低電平選中,高電平無(wú)效 config->polarity = kECSPI_PolarityActiveHigh; // 時(shí)鐘信號極性,即CPOL為0的話(huà) SCLK高電平有效(空閑的時(shí)候為低電平),為1的話(huà)SCLK低電平有效(空閑的時(shí)候為高電平)。 config->phase = kECSPI_ClockPhaseFirstEdge; // 時(shí)鐘相位,即CPHA為0的話(huà)串行時(shí)鐘的第一個(gè)跳變沿(上升沿或下降沿)采集數據,為1的話(huà)串行時(shí)鐘的第二個(gè)跳變沿(上升沿或下降沿)采集數據。
(6)主模式選擇:設置SPI為主模式。
[url=]復制[/url]
config->channelConfig.channelMode = kECSPI_Master; // 主模式
(7)通道選擇:一個(gè) SPI 有四個(gè)硬件片選信號,每個(gè)片選信號是一個(gè)硬件通道,本程序選擇通道0。
[url=]復制[/url]
config->channel = kECSPI_Channel0; // 通道0
(8)關(guān)閉自回環(huán):如果開(kāi)啟了自回環(huán),那么SPI數據會(huì )在芯片內回環(huán),不會(huì )到外部管腳,在程序調試時(shí)可以排除外部端子的干擾,但真實(shí)應用時(shí),需要關(guān)閉自回環(huán),從外部管腳收發(fā)數據。
[url=]復制[/url]
Config->enableLoopBack = false; // 不回環(huán),使用外部管腳
2. SPI收發(fā)流程
我們分別將兩塊OKMX8MP-C開(kāi)發(fā)板命名為開(kāi)發(fā)板1和開(kāi)發(fā)板2,并且將開(kāi)發(fā)板1的SPI接口采用主模式,使能收發(fā)中斷;將開(kāi)發(fā)板2的SPI接口采用從模式,使能收發(fā)中斷。
SPI主發(fā)送64字節數據,SPI從接收后,將數據回傳。SPI主接收回傳信息后,比對接收和發(fā)送的數據是否一致,輸出比對結果。如一致,本次傳輸結束,等待輸入任何按鍵啟動(dòng)下一次傳輸。
(1)SPI發(fā)送數據:EXAMPLE_ECSPI_MASTER_BASEADDR 表示為SPI2,g_m_handle為SPI實(shí)例,包含了發(fā)送接收中斷及其回調函數,masterXfer為要發(fā)送的64字節數據。
[url=]復制[/url]
ECSPI_MasterTransferNonBlocking(EXAMPLE_ECSPI_MASTER_BASEADDR, &g_m_handle, &masterXfer); //主模式中斷方式發(fā)送數據
(2)SPI接收數據:SPI總線(xiàn)的發(fā)送和接收都是主模式控制的,因此接收函數的過(guò)程和發(fā)送是一致的。
(3)接收和發(fā)送數據對比:
[url=]復制[/url]
"#000000">for (i = 0U; i < TRANSFER_SIZE; i++) { if (masterTxData</font> != masterRxDatafont>) { errorCount++; } }
02SPI從模式
1. SPI初始化
SPI從模式初始化與主模式要保持一致,除了將工作模式設為從模式,其他設置均一樣。主從模式選擇:設置SPI為從模式。
[url=]復制[/url]
config->channelConfig.channelMode = kECSPI_Slave; //從模式
2. SPI收發(fā)流程
開(kāi)發(fā)板2的SPI接口采用從模式,使能收發(fā)中斷。
SPI從進(jìn)入等待接收狀態(tài),在片選有效后,通過(guò)接收中斷獲取數據,并回傳信息,再次進(jìn)入接收狀態(tài)。
(1)SPI接收數據:[url=]復制[/url]
EXAMPLE_ECSPI_SLAVE_BASEADDR表示為SPI2,g_m_handle為SPI實(shí)例,包含了發(fā)送接收中斷及其回調函數,slaveXfer存儲接收的數據。
ECSPI_SlaveTransferNonBlocking(EXAMPLE_ECSPI_SLAVE_BASEADDR, &g_s_handle, &slaveXfer); //從模式中斷方式接收數據
(2)SPI發(fā)送數據:SPI總線(xiàn)的發(fā)送和接收都是主模式控制的,因此接收函數的過(guò)程和發(fā)送是一致的。
03A核修改
A核設備樹(shù)中若保留SPI2,內核解析設備樹(shù),在/dev下生成設備文件spidev1.0。這樣待M核運行后,A核將重新對SPI2初始化,造成M核SPI功能異常,因此需要去除A核對SPI的控制。
1. 修改設備樹(shù)
(1)在設備樹(shù)OK8MP-C.dts中,刪除SPI2設備節點(diǎn)相關(guān)信息。
[url=]復制[/url]
&ecspi2 { #address-cells = <1>; #size-cells = <0>; fsl,spi-num-chipselects = <1>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi2 &pinctrl_ecspi2_cs>; cs-gpios = <&gpio5 13 GPIO_ACTIVE_LOW>; status = "okay"; spidev1: spi@0 { reg = <0>; compatible = "rohm,dh2228fv"; spi-max-frequency = <500000>; }; }; pinctrl_ecspi2: ecspi2grp { fsl,pins = < MX8MP_IOMUXC_ECSPI2_SCLK__ECSPI2_SCLK 0x82 MX8MP_IOMUXC_ECSPI2_MOSI__ECSPI2_MOSI 0x82 MX8MP_IOMUXC_ECSPI2_MISO__ECSPI2_MISO 0x82 >; }; pinctrl_ecspi2_cs: ecspi2cs { fsl,pins = < MX8MP_IOMUXC_ECSPI2_SS0__GPIO5_IO13 0x40000 >; };
(2)編譯生成新的內核鏡像Image及設備樹(shù)OK8MP-C.dtb。
(3)將生成的OK8MP-C.dtb和Image拷貝至開(kāi)發(fā)板/run/media/mmcblk2p1/目錄下,輸入sync命令,重啟開(kāi)發(fā)板。
(4)輸ls /dev查看發(fā)現沒(méi)有SPI2設備文件spidev1.0。
04程序驗證
1. 硬件連接
使用杜邦線(xiàn)將兩塊OKMX8MP-C開(kāi)發(fā)板的SPI一一對應連接,線(xiàn)序如下:
開(kāi)發(fā)板1--SPI主模式
| 開(kāi)發(fā)板2--SPI從模式
| 管腳名稱(chēng)
| 開(kāi)發(fā)板位置
| 管腳名稱(chēng)
| 開(kāi)發(fā)板位置
| MISO
| P40-10
| MISO
| P40-10
| MOSI
| P40-8
| MOSI
| P40-8
| SCK
| P40-1
| SCK
| P40-1
| SS0
| P40-3
| SS0
| P40-3
| GND
| P40-4/P40-7
| GND
| P40-4/P40-7
|
2. M核程序
修改uboot環(huán)境變量設置M核自啟動(dòng),同時(shí)將M核程序forlinx_m7_tcm_firmware.bin
放到/run/media/mmcblk2p1/目錄下。注意,SPI主模式程序須放入開(kāi)發(fā)板1,SPI從模式程序須放入開(kāi)發(fā)板2
3. 實(shí)際測試
(1)開(kāi)發(fā)板2先上電,M核程序啟動(dòng),完成SPI初始化后,進(jìn)入接收等待狀態(tài);
(2)開(kāi)發(fā)板1后上電,M核程序啟動(dòng),完成SPI初始化后,主動(dòng)發(fā)送64字節數據;
(3)開(kāi)發(fā)板2的SPI接收數據,通過(guò)串口打印接收的數據,并將接收的數據再次發(fā)送;
[
(4)開(kāi)發(fā)板1的SPI接收到回傳信息,通過(guò)串口打印接收的數據。和發(fā)送數據比對,輸出結果。
(5)此時(shí)在開(kāi)發(fā)板1調試串口輸入任意鍵,即可開(kāi)啟新一輪的SPI發(fā)送和接收流程。
END
|
|