Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
USB
NXP 微控制器
NXP-MCXN947
RT-Thread 适配 NXP mcxn947 usbd驱动
发布于 2024-03-26 13:28:29 浏览:384
订阅该版
[tocm] **本文旨在介绍在RT-Thread操作系统下适配NXP mcxn947 usb device驱动的过程。不尽之处请comment或issue。 ** ## 一、准备阶段 1. 下载nxp官方sdk(这里我使用vscode插件进行下载) ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20240326/6bff6eacd79d147380e717e3d4876d72.png.webp) 2. 抽取目录和文件 $(NXP_SDK_DIR)/middleware/usb/device $(NXP_SDK_DIR)/middleware/usb/include $(NXP_SDK_DIR)/middleware/usb/phy $(NXP_SDK_DIR)/boards/frdmmcxn947/usb_examples/usb_device_cdc_vcom/bm/cm33_core0/usb_device_config.h 此文件抽取后放到$(NXP_SDK_DIR)/middleware/usb/include ## 二、修改阶段 1. 修改文件bsp/nxp/mcx/mcxn/Libraries/drivers/SConscript, 末尾添加内容 if GetDepend('BSP_USING_USB_DEVICE'): src += ['drv_usbd.c'] src += Glob('usb/device/*.c') src += Glob('usb/phy/*.c') path = [cwd, cwd + '/usb/device', cwd + '/usb/include', cwd + '/usb/phy'] 2. bsp/nxp/mcx/mcxn/frdm-mcxn947/board/Kconfig, 末尾添加内容 config BSP_USING_USB_DEVICE bool "Enable usb device" select RT_USING_USB_DEVICE default y 3. 添加文件bsp/nxp/mcx/mcxn/Libraries/drivers/drv_usbd.c 4. env -> menuconfig 添加虚拟串口 ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20240326/442f1ef3062c20c710190fc73216a378.png.webp) ## 三、驱动drv_usbd.c主要内容分析 1. USB_DeviceClockInit()函数 此函数主要配置了电压域和usb的时钟源。它是一个底层配置函数,与主控密切相关,参考官方的sdk可以实现。 ```c static void USB_DeviceClockInit(uint8_t controllerId) { #if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U) usb_phy_config_struct_t phyConfig = { BOARD_USB_PHY_D_CAL, BOARD_USB_PHY_TXCAL45DP, BOARD_USB_PHY_TXCAL45DM, }; #endif #if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U) SPC0->ACTIVE_VDELAY = 0x0500; /* Change the power DCDC to 1.8v (By deafult, DCDC is 1.8V), CORELDO to 1.1v (By deafult, CORELDO is 1.0V) */ SPC0->ACTIVE_CFG &= ~SPC_ACTIVE_CFG_CORELDO_VDD_DS_MASK; SPC0->ACTIVE_CFG |= SPC_ACTIVE_CFG_DCDC_VDD_LVL(0x3) | SPC_ACTIVE_CFG_CORELDO_VDD_LVL(0x3) | SPC_ACTIVE_CFG_SYSLDO_VDD_DS_MASK | SPC_ACTIVE_CFG_DCDC_VDD_DS(0x2u); /* Wait until it is done */ while (SPC0->SC & SPC_SC_BUSY_MASK) ; if (0u == (SCG0->LDOCSR & SCG_LDOCSR_LDOEN_MASK)) { SCG0->TRIM_LOCK = 0x5a5a0001U; SCG0->LDOCSR |= SCG_LDOCSR_LDOEN_MASK; /* wait LDO ready */ while (0U == (SCG0->LDOCSR & SCG_LDOCSR_VOUT_OK_MASK)) ; } SYSCON->AHBCLKCTRLSET[2] |= SYSCON_AHBCLKCTRL2_USB_HS_MASK | SYSCON_AHBCLKCTRL2_USB_HS_PHY_MASK; SCG0->SOSCCFG &= ~(SCG_SOSCCFG_RANGE_MASK | SCG_SOSCCFG_EREFS_MASK); /* xtal = 20 ~ 30MHz */ SCG0->SOSCCFG = (1U << SCG_SOSCCFG_RANGE_SHIFT) | (1U << SCG_SOSCCFG_EREFS_SHIFT); SCG0->SOSCCSR |= SCG_SOSCCSR_SOSCEN_MASK; while (1) { if (SCG0->SOSCCSR & SCG_SOSCCSR_SOSCVLD_MASK) { break; } } SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_CLKIN_ENA_MASK | SYSCON_CLOCK_CTRL_CLKIN_ENA_FM_USBH_LPT_MASK; CLOCK_EnableClock(kCLOCK_UsbHs); CLOCK_EnableClock(kCLOCK_UsbHsPhy); CLOCK_EnableUsbhsPhyPllClock(kCLOCK_Usbphy480M, 24000000U); CLOCK_EnableUsbhsClock(); USB_EhciPhyInit(controllerId, 24000000U, &phyConfig); #endif } ``` 2. USB1_HS_IRQHandler()中断 这是官方关于usb的中断函数,函数名称可以在向量表处查询得到。函数里直接调用了官方sdk包提供的USB_DeviceEhciIsrFunction(),可以轻松回调usb的中断。 ```c void USB1_HS_IRQHandler(void) { /* enter interrupt */ rt_interrupt_enter(); USB_DeviceEhciIsrFunction(ehci0_handle); /* leave interrupt */ rt_interrupt_leave(); } ``` 3. struct udcd_ops操作函数结构体的实现 这里的操作函数接口可以把板级的底层操作顺利接入到rtt的操作系统中,因此这里应该抽取nxp官方sdk的关于usb的对应底层操作来实现。 ```c const static struct udcd_ops _ehci0_udc_ops = { _ehci0_set_address, _ehci0_set_config, _ehci0_ep_set_stall, _ehci0_ep_clear_stall, _ehci0_ep_enable, _ehci0_ep_disable, _ehci0_ep_read_prepare, _ehci0_ep_read, _ehci0_ep_write, _ehci0_ep0_send_status, _ehci0_suspend, _ehci0_wakeup, }; ``` 4. usb device的初始化函数 函数里包含了底层的初始化,并且将操作函数,可以实现的端点池全部打包进行注册,以后rtt系统需要操作usbd这个设备便可以利用对应的ops实现了。 ```c static int rt_usbd_init(void) { rt_memset((void *)&_fsl_udc_0, 0, sizeof(struct udcd)); _fsl_udc_0.parent.type = RT_Device_Class_USBDevice; _fsl_udc_0.parent.init = drv_ehci0_usbd_init; _fsl_udc_0.ops = &_ehci0_udc_ops; /* Register endpoint infomation */ _fsl_udc_0.ep_pool = _ehci0_ep_pool; _fsl_udc_0.ep0.id = &_ehci0_ep_pool[0]; _fsl_udc_0.device_is_hs = RT_FALSE; rt_device_register((rt_device_t)&_fsl_udc_0, "usbd", 0); rt_usb_device_init(); return 0; } INIT_DEVICE_EXPORT(rt_usbd_init); ``` ## 四、应用程序main.c的分析 1. 找到虚拟串口设备描述符 `dev = rt_device_find("vcom");` 2. 打开虚拟串口设备 `err = rt_device_open(dev, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX);` 3. 设置设备的接收回调函数 `err = rt_device_set_rx_indicate(dev, &rx_ind);` 4. 在回调里读取串口数据 `rt_device_read(dev, 0, rx, size);` 五、实验现象: 开发板以1s间隔不断输出hello world到虚拟串口,pc端可以在任意时刻发送字符到开发板。 ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20240326/dc2f17223de001939a92dce5951d430d.png.webp) repo: https://gitee.com/makhouse/rt-thread.git
1
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
ZVML_9668
这家伙很懒,什么也没写!
文章
8
回答
0
被采纳
0
关注TA
发私信
相关文章
1
请教USB Host
2
STM32F4调试USB 读卡器(Slave)提示格式化
3
急求 STM32F4 USB Device MSC+SD 的相关问题
4
USB 框架问题
5
USB键盘
6
LPC17xx 如何添加USB HOST设备
7
RT-Thread目前支持USB HOST了吗?
8
USB HOST的支持问题
9
RTT 2.0.1 USB存储设备问题,枚举到USBREQ_GET_MAX_LUN后复位
10
USB库已经很久没更新了
推荐文章
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
keil_MDK
rt_mq_消息队列_msg_queue
ulog
C++_cpp
at_device
本月问答贡献
踩姑娘的小蘑菇
7
个答案
3
次被采纳
a1012112796
13
个答案
2
次被采纳
张世争
9
个答案
2
次被采纳
rv666
5
个答案
2
次被采纳
用户名由3_15位
11
个答案
1
次被采纳
本月文章贡献
程序员阿伟
9
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
大龄码农
1
篇文章
5
次点赞
RTT_逍遥
1
篇文章
2
次点赞
ThinkCode
1
篇文章
1
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部