NXP iMX8X M4核心SPI开发

By Toradex胡珊逢

Colibri iMX8X 计算机模块上的处理器具有 Cortex-A35 和 Cortex-M4F。在  A35 上运行 Linux 操作系统, M4F 通常运行一个实时擦操作系统例如 FreeRTOS。NXP 的MCUxpresso SDK 提供了Cortex-M4F 例程,能够帮助用户进行开发。但在MCUxpresso SDK 中只提供了少量的外设操作演示,本文将介绍如何修改配置文件,并调用FreeRTOS API 创建一个SPI 例程,驱动SPI 接口的OLED 屏幕。


首先从NXP 网站下载 MCUxpresso SDK。根据所使用的模块,分别选择Select Development Board → Processors → I.MX → 8QuadXPlus → MIMX8QXx → MIMX8QX5xxxDZ/MIMX8QX6xxxDZ,最后点击Build MCUXpresso SDK 即可下载。


在SDK 安装目录的boards/mekmimx8qx/rtos_examples/ 位置创建一个freertos_lpspi 文件夹,里面工程文件可以从freertos_lpuart 复制然后进行修改,我们也提供修改好的例程以便使用。主要修改的内容如下。

l pin_mux.h

定义使用的引脚,包括输出调试信息的串口,LPSPI 以及两个 GPIO 用于 OLED 的复位和命令/数据选择。

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

/* 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

初始化上面定义的引脚,并配置复用关系。设置在BOARD_InitPins函数中完成。

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

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 的设置,以及通过 SPI 发送数据。

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

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)

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


设置 LPSPI 时钟源。

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

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

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


完成对 LPSPI 工作状态配置,包括 SPI 时钟频率、相位、采样点、帧长等,这些包含在 lpspi_config 结构体中。

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

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 的帧长,根据 SPI 设备实际数据输入要求需要做相应的更改,通常指令和数据的长度是不一样。例如在这个例程里多次调用 LPSPI_RTOS_Init 函数对其进行调整。

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

LPSPI_RTOS_TransferBlocking(&handle, &spi_data)

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


该函数实现 SPI 数据发送。由于采用了阻塞的方式发送,需要等待数据传输完毕才推出函数。数据存储在 lpspi_transfer_t  格式的结构体中。其中也包含了 SPI 一些配置,例如使用哪个 CS 片选,是否连续发送等。

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

lpspi_transfer_t spi_data = {

.txData = send_buffer,

.rxData = recv_buffer,

.dataSize = sizeof(send_buffer),

.configFlags = kLPSPI_MasterPcs0 | kLPSPI_MasterPcsContinuous | kLPSPI_MasterByteSwap,

};

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



上面SPI 相关API 主要来自devices/MIMX8QX6/drivers/fsl_lpspi_freertos.c,fsl_lpspi.c。在默认的fsl_lpspi_freertos.c 中只有非阻塞方式的SPI 传输函数 LPSPI_RTOS_Transfer()。因此在这里我们新构建一个阻塞方式的函数 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 头文件中申明该函数。

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

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

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


另外为了支持编译,在 devices/MIMX8QX6/drivers 目录中创建 driver_lpspi_freertos_MIMX8QX6.cmake和 driver_lpspi_MIMX8QX6.cmake两个文件。相应地在上面项目工程目录中的boards/mekmimx8qx/rtos_examples/freertos_lpspi/armgcc/CMakeLists.txt 中将 LPSPI 的驱动添加进来。

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

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

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



到此我们已经完成 LPSPI 在 FreeRTOS 的配置以及创建一个工程项目来使用 LPSPI 发送数据。上面的操作涉及SDK 中多处修改,为了方便用户测试,我们也提供经修改的整个SDK


编译好后,在 U-Boot 中通过 tftp 下载 M4 固件并运行。

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

Colibri iMX8X #   print m4boot_test

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

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



OLED 屏幕显示如下。


总结

通过上面的内容介绍了如何在 M4 上使用默认例程之外的外设,SDK 中还提供了诸多外设的 FreeRTOS API。用户可以使用类似的方法进行开发。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268

推荐阅读更多精彩内容