NXP iMX8X M4核心SPI開發(fā)

By Toradex胡珊逢

Colibri iMX8X?計算機(jī)模塊上的處理器具有?Cortex-A35?和?Cortex-M4F呻粹。在 ?A35?上運(yùn)行?Linux?操作系統(tǒng),?M4F?通常運(yùn)行一個實時擦操作系統(tǒng)例如?FreeRTOS决左。NXP?的MCUxpresso SDK?提供了Cortex-M4F?例程,能夠幫助用戶進(jìn)行開發(fā)浪册。但在MCUxpresso SDK?中只提供了少量的外設(shè)操作演示,本文將介紹如何修改配置文件缴川,并調(diào)用FreeRTOS API?創(chuàng)建一個SPI?例程厕诡,驅(qū)動SPI?接口的OLED?屏幕党远。


首先從NXP?網(wǎng)站下載?MCUxpresso SDK削解。根據(jù)所使用的模塊,分別選擇Select Development Board → Processors → I.MX → 8QuadXPlus → MIMX8QXx → MIMX8QX5xxxDZ/MIMX8QX6xxxDZ沟娱,最后點擊Build MCUXpresso SDK?即可下載氛驮。


在SDK?安裝目錄的boards/mekmimx8qx/rtos_examples/?位置創(chuàng)建一個freertos_lpspi?文件夾,里面工程文件可以從freertos_lpuart?復(fù)制然后進(jìn)行修改济似,我們也提供修改好的例程以便使用矫废。主要修改的內(nèi)容如下盏缤。

l?pin_mux.h

定義使用的引腳,包括輸出調(diào)試信息的串口磷脯,LPSPI?以及兩個?GPIO?用于?OLED?的復(fù)位和命令/數(shù)據(jù)選擇蛾找。

---------------------------------------

/* ADC_IN2 (coord V32), M40_UART0_RX */

#define BOARD_INITPINS_M40_UART0_RX_PIN_FUNCTION_ID SC_P_SCU_GPIO0_00 /*!< Pin function id */

/* ADC_IN3 (coord V30), M40_UART0_TX */

#define BOARD_INITPINS_M40_UART0_TX_PIN_FUNCTION_ID SC_P_SCU_GPIO0_01 /*!< Pin function id */

#define BOARD_INITPINS_SPI2_MOSI_PIN_FUNCTION_ID SC_P_SPI2_SDO

#define BOARD_INITPINS_SPI2_MISO_PIN_FUNCTION_ID SC_P_SPI2_SDI

#define BOARD_INITPINS_SPI2_CLK_PIN_FUNCTION_ID SC_P_SPI2_SCK

#define BOARD_INITPINS_SPI2_CS0_PIN_FUNCTION_ID SC_P_SPI2_CS0

#define BOARD_INITPINS_BB_UART2_TX_PIN_FUNCTION_ID SC_P_UART2_TX /* SODIMM21 GPIO1.IO23 OLED COMMAND/DATA SELECT*/

#define BOARD_INITPINS_BB_UART2_RX_PIN_FUNCTION_ID SC_P_UART2_RX /* SODIMM19 GPIO1.IO24 OLED RESET*/

---------------------------------------


l?pin_mux.c

初始化上面定義的引腳娩脾,并配置復(fù)用關(guān)系赵誓。設(shè)置在BOARD_InitPins函數(shù)中完成。

---------------------------------------

void BOARD_InitPins(sc_ipc_t ipc) /*!< Function assigned for the core: Cortex-M4F[m4] */

{

sc_err_t err = SC_ERR_NONE;

err = sc_pad_set_all(ipc, BOARD_INITPINS_M40_UART0_RX_PIN_FUNCTION_ID, 2U, SC_PAD_CONFIG_NORMAL, ????SC_PAD_ISO_OFF, 0x0 ,SC_PAD_WAKEUP_OFF);/* IOMUXD_ADC_IN2 register modification value */

if (SC_ERR_NONE != err)

{

assert(false);

}

---------------------------------------



l?freertos_lpspi.c

這里包括了對LPSPI?的設(shè)置柿赊,以及通過?SPI?發(fā)送數(shù)據(jù)俩功。

---------------------------------------

sc_pm_set_resource_power_mode(ipc, SC_R_SPI_2, SC_PM_PW_MODE_ON)

---------------------------------------


配置?LPSPI?的供電。

---------------------------------------

sc_pm_clock_enable(ipc, SC_R_SPI_2, SC_PM_CLK_PER, true, 0);if (CLOCK_SetIpFreq(kCLOCK_DMA_Lpspi2, SC_60MHZ) == 0)

---------------------------------------


設(shè)置?LPSPI?時鐘源碰声。

---------------------------------------

LPSPI_RTOS_Init(&handle, ADMA__LPSPI2, &lpspi_config, LPUART_CLK_FREQ)

---------------------------------------


完成對?LPSPI?工作狀態(tài)配置诡蜓,包括?SPI?時鐘頻率、相位胰挑、采樣點蔓罚、幀長等,這些包含在?lpspi_config?結(jié)構(gòu)體中瞻颂。

---------------------------------------

lpspi_master_config_t lpspi_config = {.baudRate = 6000000,.bitsPerFrame = 1024, /*!< Bits per frame, minimum 8, maximum 4096.*/.cpol = kLPSPI_ClockPolarityActiveLow,.cpha = kLPSPI_ClockPhaseSecondEdge,.direction = kLPSPI_MsbFirst,.pcsToSckDelayInNanoSec = 50,.lastSckToPcsDelayInNanoSec = 50,.betweenTransferDelayInNanoSec = 50,.whichPcs = kLPSPI_Pcs0,.pcsActiveHighOrLow = kLPSPI_PcsActiveLow,.pinCfg = kLPSPI_SdiInSdoOut,.dataOutConfig = kLpspiDataOutRetained,};

---------------------------------------


其中bitsPerFrame?是指?SPI?的幀長豺谈,根據(jù)?SPI?設(shè)備實際數(shù)據(jù)輸入要求需要做相應(yīng)的更改,通常指令和數(shù)據(jù)的長度是不一樣贡这。例如在這個例程里多次調(diào)用?LPSPI_RTOS_Init?函數(shù)對其進(jìn)行調(diào)整茬末。

---------------------------------------

LPSPI_RTOS_TransferBlocking(&handle, &spi_data)

---------------------------------------


該函數(shù)實現(xiàn)?SPI?數(shù)據(jù)發(fā)送。由于采用了阻塞的方式發(fā)送盖矫,需要等待數(shù)據(jù)傳輸完畢才推出函數(shù)丽惭。數(shù)據(jù)存儲在?lpspi_transfer_t ?格式的結(jié)構(gòu)體中。其中也包含了?SPI?一些配置辈双,例如使用哪個?CS?片選责掏,是否連續(xù)發(fā)送等。

---------------------------------------

lpspi_transfer_t spi_data = {

.txData = send_buffer,

.rxData = recv_buffer,

.dataSize = sizeof(send_buffer),

.configFlags = kLPSPI_MasterPcs0 | kLPSPI_MasterPcsContinuous | kLPSPI_MasterByteSwap,

};

---------------------------------------



上面SPI?相關(guān)API?主要來自devices/MIMX8QX6/drivers/fsl_lpspi_freertos.c湃望,fsl_lpspi.c拷橘。在默認(rèn)的fsl_lpspi_freertos.c?中只有非阻塞方式的SPI?傳輸函數(shù)?LPSPI_RTOS_Transfer()。因此在這里我們新構(gòu)建一個阻塞方式的函數(shù)?LPSPI_RTOS_TransferBlocking()喜爷。


---------------------------------------

status_t LPSPI_RTOS_TransferBlocking(lpspi_rtos_handle_t *handle, lpspi_transfer_t *transfer){??status_t status;??status = LPSPI_MasterTransferBlocking(handle->base, transfer);??if (status != kStatus_Success)??{????return status;??}??return status;}

---------------------------------------




在?fsl_lpspi_freertos.h?頭文件中申明該函數(shù)冗疮。

---------------------------------------

status_t LPSPI_RTOS_TransferBlocking(lpspi_rtos_handle_t *handle, lpspi_transfer_t *transfer);

---------------------------------------


另外為了支持編譯,在?devices/MIMX8QX6/drivers?目錄中創(chuàng)建?driver_lpspi_freertos_MIMX8QX6.cmake和?driver_lpspi_MIMX8QX6.cmake兩個文件檩帐。相應(yīng)地在上面項目工程目錄中的boards/mekmimx8qx/rtos_examples/freertos_lpspi/armgcc/CMakeLists.txt?中將?LPSPI?的驅(qū)動添加進(jìn)來术幔。

---------------------------------------

# include modulesinclude(driver_clock_MIMX8QX6)include(driver_lpspi_MIMX8QX6)include(driver_lpspi_freertos_MIMX8QX6)

---------------------------------------



到此我們已經(jīng)完成?LPSPI?在?FreeRTOS?的配置以及創(chuàng)建一個工程項目來使用?LPSPI?發(fā)送數(shù)據(jù)。上面的操作涉及SDK?中多處修改湃密,為了方便用戶測試诅挑,我們也提供經(jīng)修改的整個SDK四敞。


編譯好后,在?U-Boot?中通過?tftp?下載?M4?固件并運(yùn)行拔妥。

---------------------------------------

Colibri iMX8X # ??print m4boot_test

m4boot_test=tftp ${loadaddr} m4_0.bin; dcache flush; bootaux ${loadaddr} 0Colibri iMX8X # run m4boot_test

---------------------------------------



OLED?屏幕顯示如下忿危。


總結(jié)

通過上面的內(nèi)容介紹了如何在?M4?上使用默認(rèn)例程之外的外設(shè),SDK?中還提供了諸多外設(shè)的?FreeRTOS API没龙。用戶可以使用類似的方法進(jìn)行開發(fā)铺厨。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市硬纤,隨后出現(xiàn)的幾起案子解滓,更是在濱河造成了極大的恐慌,老刑警劉巖筝家,帶你破解...
    沈念sama閱讀 219,539評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件洼裤,死亡現(xiàn)場離奇詭異,居然都是意外死亡溪王,警方通過查閱死者的電腦和手機(jī)腮鞍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評論 3 396
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來莹菱,“玉大人移国,你說我怎么就攤上這事∶⒅椋” “怎么了桥狡?”我有些...
    開封第一講書人閱讀 165,871評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長皱卓。 經(jīng)常有香客問我裹芝,道長,這世上最難降的妖魔是什么娜汁? 我笑而不...
    開封第一講書人閱讀 58,963評論 1 295
  • 正文 為了忘掉前任嫂易,我火速辦了婚禮,結(jié)果婚禮上掐禁,老公的妹妹穿的比我還像新娘怜械。我一直安慰自己,他們只是感情好傅事,可當(dāng)我...
    茶點故事閱讀 67,984評論 6 393
  • 文/花漫 我一把揭開白布缕允。 她就那樣靜靜地躺著,像睡著了一般蹭越。 火紅的嫁衣襯著肌膚如雪障本。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,763評論 1 307
  • 那天,我揣著相機(jī)與錄音驾霜,去河邊找鬼案训。 笑死,一個胖子當(dāng)著我的面吹牛粪糙,可吹牛的內(nèi)容都是我干的强霎。 我是一名探鬼主播,決...
    沈念sama閱讀 40,468評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼蓉冈,長吁一口氣:“原來是場噩夢啊……” “哼城舞!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起洒擦,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤椿争,失蹤者是張志新(化名)和其女友劉穎怕膛,沒想到半個月后熟嫩,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,850評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡褐捻,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,002評論 3 338
  • 正文 我和宋清朗相戀三年掸茅,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片柠逞。...
    茶點故事閱讀 40,144評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡昧狮,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出板壮,到底是詐尸還是另有隱情逗鸣,我是刑警寧澤,帶...
    沈念sama閱讀 35,823評論 5 346
  • 正文 年R本政府宣布绰精,位于F島的核電站撒璧,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏笨使。R本人自食惡果不足惜卿樱,卻給世界環(huán)境...
    茶點故事閱讀 41,483評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望硫椰。 院中可真熱鬧繁调,春花似錦、人聲如沸靶草。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽奕翔。三九已至裕寨,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間糠悯,已是汗流浹背帮坚。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評論 1 272
  • 我被黑心中介騙來泰國打工妻往, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人试和。 一個月前我還...
    沈念sama閱讀 48,415評論 3 373
  • 正文 我出身青樓讯泣,卻偏偏與公主長得像,于是被迫代替她去往敵國和親阅悍。 傳聞我的和親對象是個殘疾皇子好渠,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,092評論 2 355

推薦閱讀更多精彩內(nèi)容