Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
NXP 微控制器
NXP-MCXN947
NXP MCXN947测评之(二)SPI测评之loopback
发布于 2024-03-31 12:30:36 浏览:405
订阅该版
[tocm] 今天进入SPI测评主题,这里不做通用性的SPI介绍,[RT-Thread官方SPI文档](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/spi/spi "RT-Thread官方SPI文档")写得挺好的,不熟悉SPI的可以先跳转过去看一看。今天内容围绕MCXN947的SPI展开 # MCXN947 SPI简介 根据NXP官方的手册,芯片集成了被称为LP_FLEXCOMM(Low-Power Flexible Communication Interface)模块,这种模块可以当LPUART用,又可以当LPSPI用,也可以当LPI2C用。当然任意一时间点只能是LPSPI, LPUART, LPI2C这三者其中之一,用之前需要配置一下。这样的模块MCXN947芯片里总共集成了10个,编号分别为0, 1, ... 9。下面的内容中会简称这些LP_FLEXCOMM模块为FCn。模块对应的针脚称为FCn_P0, FCn_P1, ... FCn_P6(其中n=0, 1, 2, ...9)。显而易见,并不是所有针脚都会用上,比如当LPI2C用时其实只要两根SDA/SCL针脚,所以NXP手册在66.2.3 External Signals章节列了一个表格把FCn_Px针脚究竟是什么信号讲得很清楚,弄明白这点很重要,因为后面需要增加代码改动pinmux。 另外MCXN947芯片集成了2个eDMA(Enhanced Direct Memory Access Controller)模块,每个eDMA模块能支持128个channel,而且这128个channel可以和LP_FLEXCOMM模块任意搭配,这带来了非常大的灵活性,只是使用时需要注意DMA channel的不能重复。 # MCXN947 SPI在RT-Thread中实做 在测评这个时间点,RT-Thread主线仓库中,SPI只支持FC3所在模块当SPI用即SPI3。由FRDM-MCXN947原理图可知,对应SPI3的MISO针脚没引出,所以要完整测评SPI我们得找个FC模块且其SCLK、MISO、MOSI、CS针脚都引出的。仔细观察原理图,FC6进入我们的视野,针脚全引出不说,且正好位于mikroBUS J6插槽,非常方便用杜邦线接出做实验。 ## 增加FC6 pinmux 我们修改bsp/nxp/mcx/mcxn/frdm-mcxn947/board/MCUX_Config/board/pin_mux.c增加FC6 pinmux设置 ```bash - PORT3->PCR[20] = PORT_PCR_MUX(3) | PORT_PCR_PS(0) | PORT_PCR_IBE(1); /* FC6_P0 */ - PORT3->PCR[21] = PORT_PCR_MUX(3) | PORT_PCR_PS(0) | PORT_PCR_IBE(1); /* FC6_P1 */ + /* mikroBUS SPI6 */ + PORT3->PCR[20] = PORT_PCR_MUX(3) | PORT_PCR_PS(0) | PORT_PCR_PE(0) | PORT_PCR_IBE(1); /* FC6_P0 SDO/D[0], FC6_SPI_MOSI */ + PORT3->PCR[21] = PORT_PCR_MUX(3) | PORT_PCR_PS(0) | PORT_PCR_PE(0) | PORT_PCR_IBE(1); /* FC6_P1 SCK, FC6_SPI_CLK */ + PORT3->PCR[22] = PORT_PCR_MUX(3) | PORT_PCR_PS(0) | PORT_PCR_PE(0) | PORT_PCR_IBE(1); /* FC6_P2 SDI/D[1], FC3_SPI_MISO */ + PORT3->PCR[23] = PORT_PCR_MUX(0) | PORT_PCR_PS(0) | PORT_PCR_PE(0) | PORT_PCR_IBE(1); /* CS */ + ``` ## 增加SPI6主控实例 修改bsp/nxp/mcx/mcxn/Libraries/drivers/drv_spi.c增加SPI6主控实例,并和eDMA channel挂接 ```bash @@ -20,6 +20,9 @@ enum #ifdef BSP_USING_SPI3 SPI3_INDEX, #endif +#ifdef BSP_USING_SPI6 + SPI6_INDEX, +#endif }; @@ -61,6 +64,20 @@ static struct lpc_spi lpc_obj[] = .name = "spi3", }, #endif +#ifdef BSP_USING_SPI6 + { + .LPSPIx = LPSPI6, + .clock_attach_id = kFRO_HF_DIV_to_FLEXCOMM6, + .clock_div_name = kCLOCK_DivFlexcom6Clk, + .clock_name = kCLOCK_FroHf, + .tx_dma_request = kDmaRequestMuxLpFlexcomm6Tx, + .rx_dma_request = kDmaRequestMuxLpFlexcomm6Rx, + .DMAx = DMA0, + .tx_dma_chl = 4, + .rx_dma_chl = 5, + .name = "spi6", + }, +#endif }; ``` 经测试不挂eDMA channel也是可以,不用DMA搬FIFO数据而是用CPU去做,可以如下修改spixfer()函数,当然MCXN947提供的eDMA channel如此之多,不用白不用😀,我猜基本没人不用DMA吧,这么测试只是为了测评覆盖的完整性,实际产品中并不会使用。 ```bash @@ -133,7 +150,7 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_ message *m // if(message->length < MAX_DMA_TRANSFER_SIZE) - if(0) + if(1) { LPSPI_MasterTransferBlocking(spi->LPSPIx, &transfer); } ``` 如此SPI6主控已经添加完毕,接下来我们需要使用RT-Thread SPI API去发起SPI传输 # SPI外部loopback测试 要测SPI得接上一个SPI device,但在此之前我们不妨试试SPI主控的外部loopback测试。用杜邦线连接J6插槽的P3_20和P3_22,硬件准备完毕。我们需要写点loopback测试代码,幸运的是RT-Thread中已经有这样的例子,我们拿过来修改下即可。主要代码如下: ```c #define SPI_NAME "spi60" #define CS_PIN (3*32+23) static struct rt_spi_device *spi_dev; /* attach spi device */ static int rt_spi_device_init(void) { struct rt_spi_configuration cfg; rt_hw_spi_device_attach("spi6", SPI_NAME, CS_PIN); cfg.data_width = 8; cfg.mode = RT_SPI_MASTER | RT_SPI_MODE_0 | RT_SPI_MSB | RT_SPI_NO_CS; cfg.max_hz = 1 *1000 *1000; spi_dev = (struct rt_spi_device *)rt_device_find(SPI_NAME); if (RT_NULL == spi_dev) { rt_kprintf("spi sample run failed! can't find %s device!\n", SPI_NAME); return -RT_ERROR; } rt_spi_configure(spi_dev, &cfg); return RT_EOK; } INIT_APP_EXPORT(rt_spi_device_init); /* spi loopback mode test case */ static int spi_sample(int argc, char **argv) { rt_uint8_t t_buf[32], r_buf[32]; int i = 0; static struct rt_spi_message msg1; for (i = 0; i < sizeof(t_buf); i++) { t_buf[i] = i; } msg1.send_buf = &t_buf; msg1.recv_buf = &r_buf; msg1.length = sizeof(t_buf); msg1.cs_take = 1; msg1.cs_release = 1; msg1.next = RT_NULL; rt_spi_transfer_message(spi_dev, &msg1); rt_kprintf("spi rbuf : "); for (i = 0; i < sizeof(r_buf); i++) { rt_kprintf("%x ", r_buf[i]); } rt_kprintf("\nspi loopback mode test over!\n"); return RT_EOK; } MSH_CMD_EXPORT(spi_sample, spi loopback test); ``` 初始化时我们挂接一个SPI60 device到系统中。在spi_sample这个测试命令中,构造特别的t_buf用于传输,调用RT-Thread SPI api发送32个字节数据,传输完毕后打印r_buf。 # 配置编译和测试 ```bash scons --menuconfig中 Hardware Drivers Config ---> On-chip Peripheral Drivers ---> Enable SPI Enable Flexcomm6 as SPI Enable SPI6 BUS Sample ``` 选中Enable SPI, Enable Flexcomm6 as SPI和Enable SPI6 BUS Sample 编译完成烧录后测试log如下: ```bash msh >spi_sample spi rbuf : 0 1 2 3 4 5 6 7 8 9 a b c d e f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f spi loopback mode test over! ``` 上述所有代码即将发起RT-Thread仓库PR,应该有希望合入RT-Thread主线仓库。
0
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
rvcore
这家伙很懒,什么也没写!
文章
10
回答
7
被采纳
1
关注TA
发私信
相关文章
1
试贴-消灭0主题
2
LPC M4的一些资料
3
LPC4088的临时分支
4
lpc1788 ad 不稳定
5
1788 LCD控制器缓冲区字节问题
6
一起来学习LPC4088吧
7
上传LPC4088的realtouch主工程
8
RealBoard 4088预定帖 [第一批板子不多,预定提前结束]
9
晒RealBoard LPC4088开箱照啦,速带小板凳前来围观
10
4088主程序需要的SD卡资源
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
UART
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
rt_mq_消息队列_msg_queue
keil_MDK
ulog
MicroPython
C++_cpp
本月问答贡献
a1012112796
20
个答案
3
次被采纳
张世争
11
个答案
3
次被采纳
踩姑娘的小蘑菇
7
个答案
3
次被采纳
rv666
9
个答案
2
次被采纳
用户名由3_15位
13
个答案
1
次被采纳
本月文章贡献
程序员阿伟
9
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
RTT_逍遥
1
篇文章
6
次点赞
大龄码农
1
篇文章
5
次点赞
ThinkCode
1
篇文章
1
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部