diff --git a/rt-thread-version/rt-thread-standard/_sidebar.md b/rt-thread-version/rt-thread-standard/_sidebar.md index 9bc12895d66370e49f3b6ede6a2b03e35be9c9a2..45013d81696a52aade0c9dadb70ffc9a313baf7f 100644 --- a/rt-thread-version/rt-thread-standard/_sidebar.md +++ b/rt-thread-version/rt-thread-standard/_sidebar.md @@ -193,6 +193,8 @@ - NXP-MCX系列 - [恩智浦FRDM-MCXN947开发实践指南](/rt-thread-version/rt-thread-standard/tutorial/make-bsp/NXP-MCX/恩智浦FRDM-MCX974实践指南.md) - [恩智浦FRDM-MCXN236开发实践指南](/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-N236/恩智浦FRDM-MCXN236实践指南.md) + - [恩智浦FRDM-MCXA153开发实践指南](/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/恩智浦FRDM-MCXA153实践指南.md) + - 官方开发板 - [星火一号](/rt-thread-version/rt-thread-standard/hw-board/spark-1/spark-1.md) - [ART-PI](/rt-thread-version/rt-thread-standard/hw-board/art-pi/art-pi.md) diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/0.0.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/0.0.png new file mode 100644 index 0000000000000000000000000000000000000000..a163753ded80ede4c6222d08a26535f6879f8cb3 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/0.0.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/1.0.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/1.0.png new file mode 100644 index 0000000000000000000000000000000000000000..145bf7c39a55d34de5230dc353fa6fba7c8053c3 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/1.0.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/1.2.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/1.2.png new file mode 100644 index 0000000000000000000000000000000000000000..1d0128f75695b86b9ac6ec85838871a6223f6aff Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/1.2.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/10.0.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/10.0.png new file mode 100644 index 0000000000000000000000000000000000000000..f69cd9a9fac03750da31b2f5e5e51e3bc15613db Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/10.0.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/10.1.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/10.1.png new file mode 100644 index 0000000000000000000000000000000000000000..9926dc243d6508ec6a586a2fdd26c63920b2ac06 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/10.1.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/10.2.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/10.2.png new file mode 100644 index 0000000000000000000000000000000000000000..4b052d552e9248e74bd5fe3226ff04fe8c12e8a7 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/10.2.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/10.3.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/10.3.png new file mode 100644 index 0000000000000000000000000000000000000000..3154e879b59fbe288dbc53ee55ba1aa5c745f2c8 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/10.3.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/10.4.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/10.4.png new file mode 100644 index 0000000000000000000000000000000000000000..4a821976f0123757a7e8fed5ec9b8de3d175767a Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/10.4.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/10.5.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/10.5.png new file mode 100644 index 0000000000000000000000000000000000000000..c68a8a6c4c2932da77b678870a1fd4a3987ba7ec Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/10.5.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/10.6.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/10.6.png new file mode 100644 index 0000000000000000000000000000000000000000..56adc5b7cf4cedacc63ee452bad6fd442731e6d9 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/10.6.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/2.0.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/2.0.png new file mode 100644 index 0000000000000000000000000000000000000000..956d4d6e2d407b3e3d1a04d44767e518922d4af9 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/2.0.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/3.0.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/3.0.png new file mode 100644 index 0000000000000000000000000000000000000000..5cc23c82d68a3afb46376526b76be8b0034ddb3e Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/3.0.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/3.1.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/3.1.png new file mode 100644 index 0000000000000000000000000000000000000000..2b5ec478cc494d80ff7abbc73daa19a507f5fab2 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/3.1.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/4.0.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/4.0.png new file mode 100644 index 0000000000000000000000000000000000000000..1ae3a694089777bb5a75d5351228119707a4d54d Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/4.0.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/4.1.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/4.1.png new file mode 100644 index 0000000000000000000000000000000000000000..382d4b81ca0dd40204a08d30d470e32d8389bf1c Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/4.1.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/5.0.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/5.0.png new file mode 100644 index 0000000000000000000000000000000000000000..c01df1562b83fe08452c2535a4132f8674239795 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/5.0.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/5.1.jpg b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/5.1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2ee067343308e492c3a416e83f6d0446d2befe67 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/5.1.jpg differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/5.2.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/5.2.png new file mode 100644 index 0000000000000000000000000000000000000000..57d5a54b2a82009fac0af97e87fe0c767420e14e Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/5.2.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/6.0.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/6.0.png new file mode 100644 index 0000000000000000000000000000000000000000..07c4954f160aba8f4fd3a793ec539bb998401152 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/6.0.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/7.0.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/7.0.png new file mode 100644 index 0000000000000000000000000000000000000000..935815d806524dfc00db4e685947625c57079d99 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/7.0.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/7.1.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/7.1.png new file mode 100644 index 0000000000000000000000000000000000000000..d1b6d168164c2127dcf9286da9d8739bc26c5144 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/7.1.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/7.2.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/7.2.png new file mode 100644 index 0000000000000000000000000000000000000000..7fb7347a0923f12e1e63e91261277c66d64eb1d8 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/7.2.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/7.3.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/7.3.png new file mode 100644 index 0000000000000000000000000000000000000000..32eed1213a9883c7da2f8faf80777853fc432138 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/7.3.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/7.4.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/7.4.png new file mode 100644 index 0000000000000000000000000000000000000000..b635cc21c6d1358f77b6d39f28e2f87d24339ae3 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/7.4.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/7.5.jpg b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/7.5.jpg new file mode 100644 index 0000000000000000000000000000000000000000..41b2628acae4217c13eac025f7bccf5ded65c6d2 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/7.5.jpg differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/8.0.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/8.0.png new file mode 100644 index 0000000000000000000000000000000000000000..4995b0152d7151338d31d5a8b300d3d693f1f4a2 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/8.0.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/8.1.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/8.1.png new file mode 100644 index 0000000000000000000000000000000000000000..03d1483280066b9eee69fae90d1e8f1c4d115c2f Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/8.1.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/8.2.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/8.2.png new file mode 100644 index 0000000000000000000000000000000000000000..763b4b8d79a86bdf12b2726282ab8d1544017a8f Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/8.2.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/8.3.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/8.3.png new file mode 100644 index 0000000000000000000000000000000000000000..32eed1213a9883c7da2f8faf80777853fc432138 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/8.3.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/8.4.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/8.4.png new file mode 100644 index 0000000000000000000000000000000000000000..b635cc21c6d1358f77b6d39f28e2f87d24339ae3 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/8.4.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/8.5.jpg b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/8.5.jpg new file mode 100644 index 0000000000000000000000000000000000000000..fe1825b462aa0306a0c9e3100b8845a607e1e30a Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/8.5.jpg differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/9.0.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/9.0.png new file mode 100644 index 0000000000000000000000000000000000000000..1af9f9027e55f26d2f4dc03049a904374aa4ff12 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/Book_Picture/9.0.png differ diff --git "a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/\346\201\251\346\231\272\346\265\246FRDM-MCXA153\345\256\236\350\267\265\346\214\207\345\215\227.md" "b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/\346\201\251\346\231\272\346\265\246FRDM-MCXA153\345\256\236\350\267\265\346\214\207\345\215\227.md" new file mode 100644 index 0000000000000000000000000000000000000000..fd5ddea0c1f4e9b8e531ba2d0dce1d1eda0ce761 --- /dev/null +++ "b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A153/\346\201\251\346\231\272\346\265\246FRDM-MCXA153\345\256\236\350\267\265\346\214\207\345\215\227.md" @@ -0,0 +1,1345 @@ +# **恩智浦FRDM-MCXA153开发实践指南** + +| **目录** | 作者 | +| -------------------------------------------- | ---------------------- | +| **零、实践指南说明** | **RT-Thread & 恩智浦** | +| **一、恩智浦FRDM-MCXA153上的UART实践** | 何剑波 | +| **二、恩智浦FRDM-MCXA153上的GPIO实践** | 何剑波 | +| **三、恩智浦FRDM-MCXA153上的ADC实践** | 何剑波 | +| **四、恩智浦FRDM-MCXA153上的Flash实践** | 何剑波 | +| **五、恩智浦FRDM-MCXA153上的SPI实践** | 莫海文 | +| **六、恩智浦FRDM-MCXA153上的PWM实践** | 莫海文 | +| **七、恩智浦FRDM-MCXA153上的 IIC(软件) 实践** | 大菠萝 | +| **八、恩智浦FRDM-MCXA153上的 IIC(硬件) 实践** | 大菠萝 | +| **九、恩智浦FRDM-MCXA153不能调试的解决办法** | 莫海文 | +| **FAQ** | **RT-Thread & 恩智浦** | + +# 《恩智浦FRDM-MCXA153开发实践指南》 **零、实践指南说明** +## 硬件介绍 +1. 开发板描述: +FRDM-MCXA153是一款紧凑且可扩展的开发板,可让您快速基于MCX A14和A15 MCU开展原型设计。它们提供行业标准的接口,可轻松访问MCU的I O、集成的开放标准串行接口、外部闪存和板载MCU-Link调试器。 +2. 开发板外观如下图所示: +![alt text](Book_Picture/0.0.png) +3. 该开发板常用 **板载资源** 如下: +* 微控制器 + * MCXA15x Arm® Cortex®-M33内核 + * 128KB的闪存 + * 32kB的RAM + * 8kB ECC LPLUART、LPSPI、LPI2C、FS USB、DMA和LDO +* 连接性 + * FS USB端口,具有可用作主机或设备的USB Type-C接头 + * HS USB Type-C接头 + * SPI I2C UART连接器(PMOD mikroBUS、DNP) + * Wi-Fi连接器(PMOD mikroBUS、DNP) +* 调试 + * 带有CMSIS-DAP的板载MCU-Link调试器 + * JTAG SWD连接器 +* 传感器 + * P3T1755DPJ I3C I2C温度传感器 +* 扩展选项 + * Arduino®排针 + * FRDM接头 + * FlexIO LCD接头 + * Pmod™ *DNP + * mikroBUS™ + * RGB用户LED、复位、ISP、唤醒按钮 + +开发板更多详细信息请参考 [**NXP官方网站**](https://www.nxp.com.cn/design/design-center/development-boards-and-designs/general-purpose-mcus/frdm-development-board-for-mcx-a14x-a15x-mcus:FRDM-MCXA153?cid=ps_pro240034g_tac1558850_baidu_pc_2024042614&cl_sr=Web&cl_ctnm=MCX-PC-240206_FRDM-MCXA153_%E7%89%A9%E8%81%94%E7%BD%91%E5%BC%80%E5%8F%91%E6%9D%BF&cl_source1=Baidu&bd_vid=7619009488344959422) + +**我有疑问:**[**RT-Thread 官方论坛**](https://club.rt-thread.org ) + +# **一、恩智浦FRDM-MCXA153 上的UART实践** (何剑波) + ## 1.实验目的 + rt-thread中UART2驱动添加 + ## 2. 步骤说明 + ### 2.1 UART层级结构 +![alt text](Book_Picture/1.0.png) +### 2.2 IO设备管理层 +向应用层提供接口(rt_device_read write等) +### 2.3 设备框架 +1. 源码是在serial_v2.c中,提供的功能如下: +* 对应上层的IO设备管理层 +* 对驱动层提供统一的UART操作接口如:configure, control, putc, getc, transmit等 +2. 驱动开发者需要实现的接口 +* 设备注册管理接口 rt_hw_serial_register 和 中断处理接口rt_hw_serial_isr +驱动代码在drv_usartv2.c中 +* UART驱动源码在 drv_usart.c中,实现 struct rt_uart_ops 的各种方法 +* 调用rt_hw_serial_register 注册到系统 +## 3.创建流程 +### 3.1 扩展 struct rt_serial_device +```c +struct mcx_uart +{ + struct rt_serial_device *serial;//设备信息和操作 + LPUART_Type *uart_base;//串口句柄 + IRQn_Type irqn;//中断 + clock_name_t clock_src;//时钟选择 + clock_attach_id_t clock_attach_id; + clock_ip_name_t clock_ip_name; + clock_div_name_t clock_div_name; + char *device_name; +}; +``` +### 3.2 配置 +![alt text](Book_Picture/1.2.png) +```c +struct serial_configure +{ + rt_uint32_t baud_rate; //比特率 + rt_uint32_t data_bits :4;//数据长度 + rt_uint32_t stop_bits :2;//停止位 + rt_uint32_t parity :2;//校验位 + rt_uint32_t bit_order :1;//小段发送 + rt_uint32_t invert :1;//模式选择 正常模式 归零编码方式 + rt_uint32_t bufsz :16;//buf大小 + rt_uint32_t flowcontrol :1;//硬件流控制 + rt_uint32_t reserved :5;//保留的位 +}; +``` +```c +struct rt_uart_ops +{ + rt_err_t (*configure)(struct rt_serial_device *serial, struct serial_configure *cfg); + rt_err_t (*control)(struct rt_serial_device *serial, int cmd, void *arg); + int (*putc)(struct rt_serial_device *serial, char c); + int (*getc)(struct rt_serial_device *serial); + rt_ssize_t (*dma_transmit)(struct rt_serial_device *serial, rt_uint8_t *buf, rt_size_t size, int direction); +}; + +``` +### 3.3 实现rt_uart_ops成员的接口 +1. configure :配置串口 +2. 配置串口基本属性:比特率等 +### 3.4 control :控制UART设备 +```c +#define RT_DEVICE_CTRL_RESUME 0x01 /**< resume device */ +#define RT_DEVICE_CTRL_SUSPEND 0x02 /**< suspend device */ +#define RT_DEVICE_CTRL_CONFIG 0x03 /**< configure device */ +#define RT_DEVICE_CTRL_CLOSE 0x04 /**< close device */ +#define RT_DEVICE_CTRL_NOTIFY_SET 0x05 /**< set notify func */ +#define RT_DEVICE_CTRL_SET_INT 0x06 /**< set interrupt */ +#define RT_DEVICE_CTRL_CLR_INT 0x07 /**< clear interrupt */ +#define RT_DEVICE_CTRL_GET_INT 0x08 /**< get interrupt status */ +#define RT_DEVICE_CTRL_CONSOLE_OFLAG 0x09 /**< get console open flag */ +#define RT_DEVICE_CTRL_MASK 0x1f /**< mask for contrl commands */ + +``` +### 3.5 putc: 发送一个字符 +```c + LPUART_WriteByte(uart->uart_base, ch); +``` + +### 3.6 getc: 接收一个字符 +```c +if (kLPUART_RxDataRegFullInterruptEnable & LPUART_GetStatusFlags(uart->uart_base)) + { + return LPUART_ReadByte(uart->uart_base); + } +``` +## 4.代码实现 +### 4.1 引脚初始化 +在pin_mux.c中初始化引脚 +### 4.2 接口实现 +在上文已经介绍,不再描述 +### 4.3 注册和使用 +```c +#define UART2_NAME "uart2" +static rt_device_t uart2_serial; +char str[] = "hello rttread!\n"; +uart2_serial = rt_device_find(UART2_NAME); +rt_device_open(uart2_serial, RT_DEVICE_FLAG_INT_RX); +rt_device_write(uart2_serial, 0, str, (sizeof(str) - 1)); +``` +## 5.原文连接 +原文连接:https://club.rt-thread.org/ask/article/29db335ea2a3c6a0.html + + +# **二、恩智浦FRDM-MCXA153上的GPIO实践** (何剑波) + +## 1.实验目的 + rt-thread中GPIO的使用 +## 2. 步骤说明 +### 2.1 Pin驱动框架 +![alt text](Book_Picture/2.0.png) +### 2.2 PIN设备驱动层 +单纯的提供接口给应用层用,其中PIN设备驱动框架接口包含rt_pin_read等,具体在pin.c 文件中查看 +* pin.c是提供应用接口 +* drv_gpio.c是具体实现 +### 2.3实现操作方法原理 +```c +struct rt_pin_ops +{ + void (*pin_mode)(struct rt_device *device, rt_base_t pin, rt_uint8_t mode); + void (*pin_write)(struct rt_device *device, rt_base_t pin, rt_uint8_t value); + rt_ssize_t (*pin_read)(struct rt_device *device, rt_base_t pin); + rt_err_t (*pin_attach_irq)(struct rt_device *device, rt_base_t pin, + rt_uint8_t mode, void (*hdr)(void *args), void *args); + rt_err_t (*pin_detach_irq)(struct rt_device *device, rt_base_t pin); + rt_err_t (*pin_irq_enable)(struct rt_device *device, rt_base_t pin, rt_uint8_t enabled); + rt_base_t (*pin_get)(const char *name); +#ifdef RT_USING_DM + rt_err_t (*pin_irq_mode)(struct rt_device *device, rt_base_t pin, rt_uint8_t mode); + rt_ssize_t (*pin_parse)(struct rt_device *device, struct rt_ofw_cell_args *args, rt_uint32_t *flags); +#endif +#ifdef RT_USING_PINCTRL + rt_err_t (*pin_ctrl_confs_apply)(struct rt_device *device, void *fw_conf_np); +#endif /* RT_USING_PINCTRL */ +}; +``` +rt_pin_ops 方法 +| 函数 | 功能| +| ----|----| +| pin_get | 获取引脚编号 | +| pin_mode | 设置引脚模式 | +| pin_write | 设置引脚电平 | +| pin_read | 读取引脚电平 | +| pin_attach_irq | 绑定引脚中断回调函数 | +| pin_irq_enable | 使能引脚中断 | +| pin_detach_irq | 脱离引脚中断回调函数 | + +#### 2.3.1 获取引脚编号 +```c +#define GET_GPIO_PORT(x) ((x) / 32) +#define GET_GPIO_PIN(x) ((x) % 32) +``` +#### 2.3.2 rt_pin_ops 赋值 +```c +rt_hw_pin_init() +{ + int ret = RT_EOK; + mcx_pin_ops.pin_mode = mcx_pin_mode; + mcx_pin_ops.pin_read = mcx_pin_read; + mcx_pin_ops.pin_write = mcx_pin_write; + mcx_pin_ops.pin_attach_irq = mcx_pin_attach_irq; + mcx_pin_ops.pin_detach_irq = mcx_pin_detach_irq; + mcx_pin_ops.pin_irq_enable = mcx_pin_irq_enable; + mcx_pin_ops.pin_get = RT_NULL, + ret = rt_device_pin_register("pin", &mcx_pin_ops, RT_NULL); + return ret; +} +INIT_BOARD_EXPORT(rt_hw_pin_init); +``` +### 2.4 添加Pin驱动代码流程 +#### 2.4.1 编写drv_pin.c文件 +* 实现 rt_pin_ops 的各种操作接口函数 +#### 2.4.2 利用 rt_hw_pin_init 进行链接驱动层 +* 实际上就是指针的赋值 +## 3. 实验代码 +```c +rt_pin_mode(LED_PIN, PIN_MODE_OUTPUT); /* Set GPIO as Output */ +rt_pin_mode(KEY_BAND, PIN_MODE_INPUT); +rt_kprintf("MCXA153 HelloWorld\r\n"); +while (1) +{ + rt_thread_mdelay(1000); + if(rt_pin_read(KEY_BAND)) + rt_pin_write(LED_PIN, PIN_HIGH); /* Set GPIO output 1 */ + else + rt_pin_write(LED_PIN, PIN_LOW); /* Set GPIO output 0 */ + #if 0 + rt_pin_write(LED_PIN, PIN_HIGH); /* Set GPIO output 1 */ + rt_thread_mdelay(500); /* Delay 500mS */ + rt_pin_write(LED_PIN, PIN_LOW); /* Set GPIO output 0 */ + rt_thread_mdelay(500); /* Delay 500mS */ + #endif +} + +``` +## 4.原文连接 +原文连接:https://club.rt-thread.org/ask/article/57ebc0a8e6e04df8.html + + +# **三、恩智浦FRDM-MCXA153上的ADC实践** (何剑波) +## 1.实验目的 + rt-thread中ADC的使用 +## 2. 步骤说明 +### 2.1 ADC驱动框架 +![alt text](Book_Picture/3.0.png) +### 2.2 ADC设备驱动层 +与具体硬件不相干,源码在adc.c中 +* 1. 为应用层提供接口:rt_adc_read rt_adc_enable rt_adc_disable 等 +* 2. 底层提供操作方法接口:struct rt_adc_ops +```C +struct rt_adc_ops +{ + rt_err_t (*enabled)(struct rt_adc_device *device, rt_int8_t channel, rt_bool_t enabled); + rt_err_t (*convert)(struct rt_adc_device *device, rt_int8_t channel, rt_uint32_t *value); + rt_uint8_t (*get_resolution)(struct rt_adc_device *device); + rt_int16_t (*get_vref) (struct rt_adc_device *device); +}; +``` +* 3. 提供注册接口 +```C +rt_err_t rt_hw_adc_register(rt_adc_device_t adc,const char *name, const struct rt_adc_ops *ops, const void *user_data); +``` +## 3. 代码实现 +1. 首先在rtconfig.h中添加宏 +```c +#define RT_USING_ADC +``` +2. 其次根据MCXA153的ADC外设配置流程写结构体 + struct mcx_adc 其成员包括 + - 通道 + - 指令ID + - triggerID + - ADC_Type * adc_base + - 还有最重要的 rt_adc_device_t (adc.c中) + ```c +#include "drv_lpadc.h" +#include "fsl_common.h" +#include "fsl_gpio.h" +#include "fsl_port.h" +#include "fsl_inputmux.h" +#include "fsl_lpadc.h" +#include +struct mcx_adc +{ + //IRQn_Type irqn; //中断向量 已经默认 + //clock_attach_id_t clock_attach_id; 已经默认 + //clock_div_name_t clock_div_name; 已经默认 + uint32_t channelNumber; //通道ID + uint32_t commandID; //指令ID command number are 1-15 + uint32_t triggerId; // 0 1 2 3 + char *device_name; + ADC_Type * adc_base; // + rt_adc_device_t mcx_adc_device; +}; +static struct mcx_adc adcs[] = { + { + 0U, + 1U, + 0U, + "adc1", + ADC0, + NULL, + }, +}; +rt_err_t mcx_enabled(struct rt_adc_device *device, rt_int8_t channel, rt_bool_t enabled) +{ + lpadc_config_t mLpadcConfigStruct; + lpadc_conv_trigger_config_t mLpadcTriggerConfigStruct; + lpadc_conv_command_config_t mLpadcCommandConfigStruct; + if(enabled) + { + CLOCK_SetClockDiv(kCLOCK_DivADC0, 1u); + CLOCK_AttachClk(kFRO12M_to_ADC0); + LPADC_GetDefaultConfig(&mLpadcConfigStruct); + mLpadcConfigStruct.enableAnalogPreliminary = true; + mLpadcConfigStruct.referenceVoltageSource = kLPADC_ReferenceVoltageAlt3;//vdda + #if defined(FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS) && FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS + mLpadcConfigStruct.conversionAverageMode = kLPADC_ConversionAverage128; + #endif + LPADC_Init(ADC0, &mLpadcConfigStruct); +#if defined(FSL_FEATURE_LPADC_HAS_CTRL_CALOFS) && FSL_FEATURE_LPADC_HAS_CTRL_CALOFS +#if defined(FSL_FEATURE_LPADC_HAS_OFSTRIM) && FSL_FEATURE_LPADC_HAS_OFSTRIM + /* Request offset calibration. */ +#if defined(DEMO_LPADC_DO_OFFSET_CALIBRATION) && DEMO_LPADC_DO_OFFSET_CALIBRATION + LPADC_DoOffsetCalibration(ADC0); +#else + //LPADC_SetOffsetValue(ADC0, DEMO_LPADC_OFFSET_VALUE_A, DEMO_LPADC_OFFSET_VALUE_B); +#endif /* DEMO_LPADC_DO_OFFSET_CALIBRATION */ +#endif /* FSL_FEATURE_LPADC_HAS_OFSTRIM */ +#if defined(FSL_FEATURE_LPADC_HAS_CTRL_CALOFSMODE) && FSL_FEATURE_LPADC_HAS_CTRL_CALOFSMODE + LPADC_SetOffsetCalibrationMode(ADC0, DEMO_LPADC_OFFSET_CALIBRATION_MODE); + LPADC_DoOffsetCalibration(ADC0); +#endif /* FSL_FEATURE_LPADC_HAS_CTRL_CALOFSMODE */ + /* Request gain calibration. */ + LPADC_DoAutoCalibration(ADC0); +#endif /* FSL_FEATURE_LPADC_HAS_CTRL_CALOFS */ + LPADC_GetDefaultConvCommandConfig(&mLpadcCommandConfigStruct); + mLpadcCommandConfigStruct.channelNumber = 0U; +#if defined(DEMO_LPADC_USE_HIGH_RESOLUTION) && DEMO_LPADC_USE_HIGH_RESOLUTION + mLpadcCommandConfigStruct.conversionResolutionMode = kLPADC_ConversionResolutionHigh; +#endif /* DEMO_LPADC_USE_HIGH_RESOLUTION */ + LPADC_SetConvCommandConfig(ADC0, 1U, &mLpadcCommandConfigStruct); + /* Set trigger configuration. */ + LPADC_GetDefaultConvTriggerConfig(&mLpadcTriggerConfigStruct); + mLpadcTriggerConfigStruct.targetCommandId = 1U; + mLpadcTriggerConfigStruct.enableHardwareTrigger = false; + LPADC_SetConvTriggerConfig(ADC0, 0U, &mLpadcTriggerConfigStruct); + } + else + { + LPADC_Deinit(ADC0); + } + return RT_EOK; +} +rt_err_t mcx_convert(struct rt_adc_device *device, rt_int8_t channel, rt_uint32_t *value) +{ + lpadc_conv_result_t mLpadcResultConfigStruct; + LPADC_DoSoftwareTrigger(ADC0, 1U); /* 1U is trigger0 mask. */ + while (!LPADC_GetConvResult(ADC0, &mLpadcResultConfigStruct)) + { + } + *value = mLpadcResultConfigStruct.convValue; + return RT_EOK; +} +rt_uint8_t mcx_get_resolution(struct rt_adc_device *device) +{ + return 1; +} +rt_int16_t mcx_get_vref (struct rt_adc_device *device) +{ + return 1; +} +struct rt_adc_ops mcx_adc_ops = +{ + mcx_enabled, + mcx_convert, + mcx_get_resolution, + mcx_get_vref, +}; +int rt_hw_adc_init(void) +{ + int i; + for (i = 0; i < 1; i++) + { + adcs[i].mcx_adc_device = (rt_adc_device_t)rt_malloc(sizeof(struct rt_adc_device)); + rt_memset(adcs[i].mcx_adc_device , 0, sizeof(struct rt_adc_device)); + rt_hw_adc_register(adcs[i].mcx_adc_device, "adc1", &mcx_adc_ops, adcs[i].adc_base); + } + return 0; +} +//INIT_BOARD_EXPORT(rt_hw_adc_init); + ``` +``` c +//注册 +rt_hw_adc_init(); +rt_adc_device_t adc_dev; +rt_uint32_t value; +//查找 +adc_dev = (rt_adc_device_t) rt_device_find("adc1"); +if(adc_dev == RT_NULL) + rt_kprintf("adc device find error\r\n"); +//使能 +rt_adc_enable(adc_dev, 0); +//读取 +value = rt_adc_read(adc_dev, 0); +rt_kprintf("adc value = %d\r\n",value); +``` +## 4. 总结 +- 代码中很多都是直接写成固定值,而不是通过参数去传递,后面再优化 +- INIT_BOARD_EXPORT(rt_hw_adc_init); 不能用此方式进行提前注册,会有硬件错误 +- 熟悉A153的ADC外设会更好的去写驱动 +![alt text](Book_Picture/3.1.png) +## 5.原文连接 +原文连接:https://club.rt-thread.org/ask/article/c51ca36f3733c61b.html + + +# **四、恩智浦FRDM-MCXA153上的Flash实践** (何剑波) +## 1.使用内部flash适配MTD NOR 设备驱动 +RT-thread 将常用的存储设备抽象成MTD(Memory Technology Device)设备驱动,此开发板的A153有128KB的片上flash,尝试将其中的512字节取出然后作为存储数据 通过RT-thread 的MTD nor 设备进行管理。 +## 2.MTD MOR 层级结构 +![alt text](Book_Picture/4.0.png) +- MTD设备驱动框架是在mtd_nand.c文件中,其基本功能是: +- 向文件系统提供 rt_mtd_nor_read, rt_mtd_nor_write,rt_mtd_nor_read_id等接口 +- 向底层提供 rt_mtd_nor_driver_ops 成员就是上述接口地址,俺就要实现这些功能 +- 注册接口 rt_mtd_nor_device +flash的底层操作,目前只用内部flash,读写操作就是调用NXP的底层接口了 +## 3. 代码实现 +### 3.1 创建MTD NOR 设备 +```c +struct rt_mtd_nor_device +{ + struct rt_device parent; + rt_uint32_t block_size; /* The Block size in the flash */ + rt_uint32_t block_start; /* The start of available block*/ + rt_uint32_t block_end; /* The end of available block */ + /* operations interface */ + const struct rt_mtd_nor_driver_ops* ops; +}; +``` +### 3.2 需要实现的接口 +```c +struct rt_mtd_nor_driver_ops +{ + rt_err_t (*read_id) (struct rt_mtd_nor_device* device); + rt_ssize_t (*read) (struct rt_mtd_nor_device* device, rt_off_t offset, rt_uint8_t* data, rt_size_t length); + rt_ssize_t (*write) (struct rt_mtd_nor_device* device, rt_off_t offset, const rt_uint8_t* data, rt_size_t length); + rt_err_t (*erase_block)(struct rt_mtd_nor_device* device, rt_off_t offset, rt_size_t length); +}; +``` +### 3.3 read +```c +/** + * device MTD nor 设备句柄 + * offset 偏移量 + * data 读取的数据 + * length 读取的数据长度 + */ +rt_ssize_t nxp_chipflash_read (struct rt_mtd_nor_device* device, rt_off_t offset, rt_uint8_t* data, rt_size_t length) +{ + for(int i = 0; i < length; i++) + { + *(data + i) = *(volatile rt_uint8_t *)(mtd.destAdrss + offset + i); + } + return length; +} +``` +### 3.4 write +```c +/** + * device MTD nor 设备句柄 + * offset 偏移量 + * data 读取的数据 + * length 读取的数据长度 + */ +rt_ssize_t nxp_chipflash_write (struct rt_mtd_nor_device* device, rt_off_t offset, const rt_uint8_t* data, rt_size_t length) +{ + rt_kprintf("%s %d\n","nxp_chipflash_write", *data); + int32_t status = FLASH_API->flash_program_page(&mtd.s_flashDriver, mtd.destAdrss + offset, (uint8_t *)data, length); + if (status != kStatus_Success) + { + return 0; + } + return length; +} +``` +### 3.5 erase_block +```c +/** + * device MTD nor 设备句柄 + * offset 偏移量 + * length 长度 + */ +rt_err_t nxp_chipflash_erase_block (struct rt_mtd_nor_device* device, rt_off_t offset, rt_size_t length) +{ + FLASH_API->flash_erase_sector(&mtd.s_flashDriver, mtd.destAdrss, mtd.pflashSectorSize, kFLASH_ApiEraseKey); + return RT_EOK; +} +``` +### 3.6 初始化 +```c +rt_err_t rt_onchipflash_init(const char* mtd_name) +{ + memset(&mtd.s_flashDriver, 0, sizeof(flash_config_t)); + if (FLASH_API->flash_init(&mtd.s_flashDriver) != kStatus_Success) + { + return RT_ERROR; + } + //获取参数 + FLASH_API->flash_get_property(&mtd.s_flashDriver, kFLASH_PropertyPflashBlockBaseAddr, &mtd.pflashBlockBase); + FLASH_API->flash_get_property(&mtd.s_flashDriver, kFLASH_PropertyPflashSectorSize, &mtd.pflashSectorSize); + FLASH_API->flash_get_property(&mtd.s_flashDriver, kFLASH_PropertyPflashTotalSize, &mtd.pflashTotalSize); + FLASH_API->flash_get_property(&mtd.s_flashDriver, kFLASH_PropertyPflashPageSize, &mtd.PflashPageSize); + //记录flash地址数据 + //flsh基地址+ flash中大小 - 数量* 扇区大小 + mtd.destAdrss = mtd.pflashBlockBase + (mtd.pflashTotalSize - (SECTOR_INDEX_FROM_END) * mtd.pflashSectorSize); + int32_t status = FLASH_API->flash_erase_sector(&mtd.s_flashDriver, mtd.destAdrss, mtd.pflashSectorSize, kFLASH_ApiEraseKey); + if (status != kStatus_Success) + { + return RT_ERROR; + } + mtd.mtd_device.block_start = 512; + mtd.mtd_device.block_start = 0; + mtd.mtd_device.ops = &mcx_mtd_chipflashops; + rt_mtd_nor_register_device(mtd_name, &(mtd.mtd_device)); + return RT_EOK; +} +``` +### 3.7 实验代码 +```c +rt_onchipflash_init("mflash"); +rt_onchipflash_init("mflash"); +static rt_device_t mtd = RT_NULL; +mtd = rt_device_find("mflash"); +if(!mtd) + rt_kprintf("rt find device failed.\n"); +else + rt_kprintf("rt find device ok.\n"); +rt_uint8_t number = 0x22; +rt_mtd_nor_write((struct rt_mtd_nor_device *)mtd, 0, &number, 1); +rt_uint8_t read = 0; +rt_mtd_nor_read((struct rt_mtd_nor_device *)mtd, 0, &read, 1); +rt_kprintf("rt mtd device read%d\n", read); +``` +## 4. 结果 +![alt text](Book_Picture/4.1.png) +- 操作FLASH_API 的时候需要更新 SDK 库 +- 由于没外部nor flash就使用了内部的,其实就是读写操作而已 +## 5.原文链接 +原文链接:https://club.rt-thread.org/ask/article/66a8140d56dacab9.html + +# **五、恩智浦FRDM-MCXA153上的SPI实践** (莫海文) +## 1. 介绍 +SPI总线由摩托罗拉公司开发,是一种全双工同步串行总线,由四个IO口组成:CS、SCLK、MISO、MOSI;通常用于CPU和外设之间进行通信,常见的SPI总线设备有:TFT LCD、QSPI FLASH、时钟模块、IMU等;NXP-MCXA153开发板上集成了两路SPI总线,本次实验将重点介绍RT-Thread系统中SPI BSP驱动的移植过程 +## 2. 移植流程 +以SPI0为例 +1. 在board里边添加相应的外设:配置spi0外设为复位状态、设置GPIO引脚功能 +2. 添加相应的Kconfig开关,用以指示相应的外设开启与关闭(本质是通过宏定义或者条件编译的方式) +3. 根据SDK_2_14_2_FRDM-MCXA153提供的spi示例工程编写spi总线驱动,需要实现几个关键的函数 +- rt_hw_spi_init +- spi_configure +- spixfer +4. 添加相应的库文件依赖:fsl_lpspi.c、fsl_lpspi_edma.c +引脚对应关系 +| 序号 | GPIO | function | +|------ |------ |--------- | +|1 | P1_3| CS | +|2 | P1_1| SCLK | +|3 | P1_2| MISO | +|4 | P1_0| MOSI | +## 3. 驱动文件 +### 3.1 board.c +在rt_hw_board_init函数里加入以下代码 +```c +edma_config_t userConfig = {0}; +EDMA_GetDefaultConfig(&userConfig); +EDMA_Init(DMA0, &userConfig); +``` +### 3.2 pin_mux.c +在BOARD_InitPins函数里加入以下代码 +```c +#ifdef BSP_USING_SPI0 + RESET_ReleasePeripheralReset(kLPSPI0_RST_SHIFT_RSTn); + const port_pin_config_t port1_0_pin56_config = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Low internal pull resistor value is selected. */ + kPORT_LowPullResistor, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive input filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain output is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Normal drive strength is configured */ + kPORT_NormalDriveStrength, + /* Pin is configured as LPSPI0_SDO */ + kPORT_MuxAlt2, + /* Digital input enabled */ + kPORT_InputBufferEnable, + /* Digital input is not inverted */ + kPORT_InputNormal, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORT1_0 (pin 56) is configured as LPSPI0_SDO */ + PORT_SetPinConfig(PORT1, 0U, &port1_0_pin56_config); + const port_pin_config_t port1_1_pin57_config = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Low internal pull resistor value is selected. */ + kPORT_LowPullResistor, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive input filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain output is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Normal drive strength is configured */ + kPORT_NormalDriveStrength, + /* Pin is configured as LPSPI0_SCK */ + kPORT_MuxAlt2, + /* Digital input enabled */ + kPORT_InputBufferEnable, + /* Digital input is not inverted */ + kPORT_InputNormal, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORT1_1 (pin 57) is configured as LPSPI0_SCK */ + PORT_SetPinConfig(PORT1, 1U, &port1_1_pin57_config); + const port_pin_config_t port1_2_pin58_config = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Low internal pull resistor value is selected. */ + kPORT_LowPullResistor, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive input filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain output is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Normal drive strength is configured */ + kPORT_NormalDriveStrength, + /* Pin is configured as LPSPI0_SDI */ + kPORT_MuxAlt2, + /* Digital input enabled */ + kPORT_InputBufferEnable, + /* Digital input is not inverted */ + kPORT_InputNormal, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORT1_2 (pin 58) is configured as LPSPI0_SDI */ + PORT_SetPinConfig(PORT1, 2U, &port1_2_pin58_config); + const port_pin_config_t port1_3_pin59_config = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Low internal pull resistor value is selected. */ + kPORT_LowPullResistor, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive input filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain output is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Normal drive strength is configured */ + kPORT_NormalDriveStrength, + /* Pin is configured as LPSPI0_PCS0 */ + kPORT_MuxAlt2, + /* Digital input enabled */ + kPORT_InputBufferEnable, + /* Digital input is not inverted */ + kPORT_InputNormal, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORT1_3 (pin 59) is configured as LPSPI0_PCS0 */ + PORT_SetPinConfig(PORT1, 3U, &port1_3_pin59_config); +#endif +``` +### 3.3 board Kconfig +加入SPI0相关配置 +```c +menuconfig BSP_USING_SPI + config BSP_USING_SPI + bool "Enable SPI" + select RT_USING_SPI + default y + if BSP_USING_SPI + config BSP_USING_SPI0 + bool "Enable SPI0" + default + endif +``` +### 3.4 drv_spi.c +spi驱动层修改如下 +```c + /* + * Copyright (c) 2006-2024, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2024-08-3 hywing The first version for MCXA + */ +#include "rtdevice.h" +#include "drv_spi.h" +#include "fsl_common.h" +#include "fsl_lpspi.h" +#include "fsl_lpspi_edma.h" +#define DMA_MAX_TRANSFER_COUNT (32767) +enum +{ +#ifdef BSP_USING_SPI0 + SPI1_INDEX, +#endif +}; +struct lpc_spi +{ + struct rt_spi_bus parent; + LPSPI_Type *LPSPIx; + clock_attach_id_t clock_attach_id; + clock_div_name_t clock_div_name; + clock_name_t clock_name; + DMA_Type *DMAx; + uint8_t tx_dma_chl; + uint8_t rx_dma_chl; + edma_handle_t dma_tx_handle; + edma_handle_t dma_rx_handle; + dma_request_source_t tx_dma_request; + dma_request_source_t rx_dma_request; + lpspi_master_edma_handle_t spi_dma_handle; + rt_sem_t sem; + char *name; +}; +static struct lpc_spi lpc_obj[] = +{ +#ifdef BSP_USING_SPI0 + { + .LPSPIx = LPSPI0, + .clock_attach_id = kFRO12M_to_LPSPI0, + .clock_div_name = kCLOCK_DivLPSPI0, + .clock_name = kCLOCK_Fro12M, + .tx_dma_request = kDma0RequestLPSPI0Tx, + .rx_dma_request = kDma0RequestLPSPI0Rx, + .DMAx = DMA0, + .tx_dma_chl = 0, + .rx_dma_chl = 1, + .name = "spi0", + }, +#endif +}; +struct lpc_sw_spi_cs +{ + rt_uint32_t pin; +}; +rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, rt_uint32_t pin) +{ + rt_err_t ret = RT_EOK; + struct rt_spi_device *spi_device = (struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device)); + struct lpc_sw_spi_cs *cs_pin = (struct lpc_sw_spi_cs *)rt_malloc(sizeof(struct lpc_sw_spi_cs)); + cs_pin->pin = pin; + rt_pin_mode(pin, PIN_MODE_OUTPUT); + rt_pin_write(pin, PIN_HIGH); + ret = rt_spi_bus_attach_device(spi_device, device_name, bus_name, (void *)cs_pin); + return ret; +} +static rt_err_t spi_configure(struct rt_spi_device *device, struct rt_spi_configuration *cfg) +{ + rt_err_t ret = RT_EOK; +// struct lpc_spi *spi = RT_NULL; +// spi = (struct lpc_spi *)(device->bus->parent.user_data); +// ret = lpc_spi_init(spi->SPIx, cfg); + return ret; +} +static void LPSPI_MasterUserCallback(LPSPI_Type *base, lpspi_master_edma_handle_t *handle, status_t status, void *userData) +{ + struct lpc_spi *spi = (struct lpc_spi *)userData; + rt_sem_release(spi->sem); +} +static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *message) +{ + int i; + lpspi_transfer_t transfer = {0}; + RT_ASSERT(device != RT_NULL); + RT_ASSERT(device->bus != RT_NULL); + RT_ASSERT(device->bus->parent.user_data != RT_NULL); + struct lpc_spi *spi = (struct lpc_spi *)(device->bus->parent.user_data); + struct lpc_sw_spi_cs *cs = device->parent.user_data; + if (message->cs_take) + { + rt_pin_write(cs->pin, PIN_LOW); + } + transfer.dataSize = message->length; + transfer.rxData = (uint8_t *)(message->recv_buf); + transfer.txData = (uint8_t *)(message->send_buf); + // if(message->length < MAX_DMA_TRANSFER_SIZE) + if (0) + { + LPSPI_MasterTransferBlocking(spi->LPSPIx, &transfer); + } + else + { + uint32_t block, remain; + block = message->length / DMA_MAX_TRANSFER_COUNT; + remain = message->length % DMA_MAX_TRANSFER_COUNT; + for (i = 0; i < block; i++) + { + transfer.dataSize = DMA_MAX_TRANSFER_COUNT; + if (message->recv_buf) transfer.rxData = (uint8_t *)(message->recv_buf + i * DMA_MAX_TRANSFER_COUNT); + if (message->send_buf) transfer.txData = (uint8_t *)(message->send_buf + i * DMA_MAX_TRANSFER_COUNT); + LPSPI_MasterTransferEDMA(spi->LPSPIx, &spi->spi_dma_handle, &transfer); + rt_sem_take(spi->sem, RT_WAITING_FOREVER); + } + if (remain) + { + transfer.dataSize = remain; + if (message->recv_buf) transfer.rxData = (uint8_t *)(message->recv_buf + i * DMA_MAX_TRANSFER_COUNT); + if (message->send_buf) transfer.txData = (uint8_t *)(message->send_buf + i * DMA_MAX_TRANSFER_COUNT); + LPSPI_MasterTransferEDMA(spi->LPSPIx, &spi->spi_dma_handle, &transfer); + rt_sem_take(spi->sem, RT_WAITING_FOREVER); + } + } + if (message->cs_release) + { + rt_pin_write(cs->pin, PIN_HIGH); + } + return message->length; +} +static struct rt_spi_ops lpc_spi_ops = +{ + .configure = spi_configure, + .xfer = spixfer +}; +int rt_hw_spi_init(void) +{ + int i; + for (i = 0; i < ARRAY_SIZE(lpc_obj); i++) + { + CLOCK_SetClockDiv(lpc_obj[i].clock_div_name, 1u); + CLOCK_AttachClk(lpc_obj[i].clock_attach_id); + lpc_obj[i].parent.parent.user_data = &lpc_obj[i]; + lpc_obj[i].sem = rt_sem_create("sem_spi", 0, RT_IPC_FLAG_FIFO); + lpspi_master_config_t masterConfig; + LPSPI_MasterGetDefaultConfig(&masterConfig); + masterConfig.baudRate = 12 * 1000 * 1000; + masterConfig.pcsToSckDelayInNanoSec = 1000000000U / masterConfig.baudRate * 1U; + masterConfig.lastSckToPcsDelayInNanoSec = 1000000000U / masterConfig.baudRate * 1U; + masterConfig.betweenTransferDelayInNanoSec = 1000000000U / masterConfig.baudRate * 1U; + LPSPI_MasterInit(lpc_obj[i].LPSPIx, &masterConfig, CLOCK_GetFreq(lpc_obj[i].clock_name)); + EDMA_CreateHandle(&lpc_obj[i].dma_tx_handle, lpc_obj[i].DMAx, lpc_obj[i].tx_dma_chl); + EDMA_CreateHandle(&lpc_obj[i].dma_rx_handle, lpc_obj[i].DMAx, lpc_obj[i].rx_dma_chl); + EDMA_SetChannelMux(lpc_obj[i].DMAx, lpc_obj[i].tx_dma_chl, lpc_obj[i].tx_dma_request); + EDMA_SetChannelMux(lpc_obj[i].DMAx, lpc_obj[i].rx_dma_chl, lpc_obj[i].rx_dma_request); + LPSPI_MasterTransferCreateHandleEDMA(lpc_obj[i].LPSPIx, &lpc_obj[i].spi_dma_handle, LPSPI_MasterUserCallback, &lpc_obj[i], &lpc_obj[i].dma_rx_handle, &lpc_obj[i].dma_tx_handle); + rt_spi_bus_register(&lpc_obj[i].parent, lpc_obj[i].name, &lpc_spi_ops); + } + return RT_EOK; +} +INIT_DEVICE_EXPORT(rt_hw_spi_init); +``` +### 3.5 SConscript +在Libraries/MCXA153/SConscript文件里边加上以下代码 +```c +if GetDepend('BSP_USING_SPI'): + src += ['MCXA153/drivers/fsl_lpspi.c'] + src += ['MCXA153/drivers/fsl_lpspi_edma.c'] +``` +## 4. 测试用例 +### 4.1打开menuconfig使能spi0驱动 +![alt text](Book_Picture/5.0.png) +### 4.2 短接MISO和MOSI引脚(P1_0和P1_2)进行自发自收测试 +![alt text](Book_Picture/5.1.jpg) +### 4.3测试程序 +```c +#include +#include "rtdevice.h" +#include "drv_spi.h" +#define SPI_BUS_NAME "spi0" +#define SPI_DEV_NAME "spi00" +static struct rt_spi_device *spi_device; +static void spi_sample(void) +{ + rt_err_t result; + struct rt_spi_configuration cfg; + uint8_t tx_buf[] = "Hello RT-Thread!"; + uint8_t rx_buf[sizeof(tx_buf)]; + rt_base_t cs = 1*32+3; + rt_hw_spi_device_attach(SPI_BUS_NAME, SPI_DEV_NAME, cs); + + spi_device = (struct rt_spi_device *)rt_device_find(SPI_DEV_NAME); + if (!spi_device) + { + rt_kprintf("can't find %s device!\n", SPI_BUS_NAME); + } + + cfg.data_width = 8; + cfg.mode = RT_SPI_MASTER | RT_SPI_MODE_0 | RT_SPI_MSB; + cfg.max_hz = 12* 1000 * 1000; + + rt_spi_configure(spi_device, &cfg); + result = rt_spi_transfer(spi_device, tx_buf, rx_buf, sizeof(tx_buf)); + if (result == sizeof(tx_buf)) + { + rt_kprintf("Send: %s\n", tx_buf); + rt_kprintf("Received: %s\n", rx_buf); + } + else + { + rt_kprintf("spi transfer failed! error code: %d\n", result); + } +} +int main(void) +{ + spi_sample(); + return 0; +} +``` +### 4.4 运行结果 +![alt text](Book_Picture/5.2.png) +* 另外,你也可以安装MCUXpresso Config Tools v16,通过图形方式配置时钟树、GPIO复用 + +## 5.原文链接 +原文链接:https: club.rt-thread.org ask article f60d86d2693b3229.html + +# **六、恩智浦FRDM-MCXA153上的PWM实践** (莫海文) +## 1. 移植流程 +1. 在board里边添加相应的外设:配置时钟分频、引脚功能等 +2. 添加相应的config开关、Kconfig开关,用以指示相应的外设开启与关闭(本质是通过宏定义或者条件编译的方式) +3. 根据SDK_2_14_2_FRDM-MCXA153提供的simple_pwm示例工程编写pwm总线驱动,需要实现几个关键的函数 +- mcx_pwm_init +- mcx_drv_pwm_control +- mcx_drv_pwm_enable +- mcx_drv_pwm_disable +## 2. 驱动文件 +### 2.1 drv_pwm.c +pwm驱动层适配如下 +```c + /* + * Copyright (c) 2006-2024, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2024-02-26 Yilin Sun Initial version. + */ +#include +#include +#include "fsl_ctimer.h" +#ifdef RT_USING_PWM +typedef struct +{ + struct rt_device_pwm pwm_device; + CTIMER_Type *ct_instance; + uint32_t timerClock; + const ctimer_match_t pwmPeriodChannel; + ctimer_match_t matchChannel; + char *name; +} mcx_pwm_obj_t; +static mcx_pwm_obj_t mcx_pwm_list[]= +{ +#ifndef BSP_USING_PWM0 + { + .ct_instance = CTIMER1, + .timerClock = 0, + .pwmPeriodChannel = kCTIMER_Match_3, + .matchChannel = kCTIMER_Match_2, + .name = "pwm0", + } +#endif +}; +volatile uint32_t g_pwmPeriod = 0U; +volatile uint32_t g_pulsePeriod = 0U; +static rt_err_t mcx_drv_pwm_get(mcx_pwm_obj_t *pwm, struct rt_pwm_configuration *configuration) +{ + return RT_EOK; +} +status_t CTIMER_GetPwmPeriodValue(uint32_t pwmFreqHz, uint8_t dutyCyclePercent, uint32_t timerClock_Hz) +{ + g_pwmPeriod = (timerClock_Hz / pwmFreqHz) - 1U; + g_pulsePeriod = (g_pwmPeriod + 1U) * (100 - dutyCyclePercent) / 100; + return kStatus_Success; +} +static rt_err_t mcx_drv_pwm_set(mcx_pwm_obj_t *pwm, struct rt_pwm_configuration *configuration) +{ + CTIMER_Type *ct = pwm->ct_instance; + uint32_t pwmFreqHz = 1000000000 / configuration->period; + uint8_t dutyCyclePercent = configuration->pulse * 100 / configuration->period; + CTIMER_GetPwmPeriodValue(pwmFreqHz, dutyCyclePercent, pwm->timerClock); + CTIMER_SetupPwmPeriod(ct, kCTIMER_Match_3, kCTIMER_Match_2, g_pwmPeriod, g_pulsePeriod, false); + return 0; +} +static rt_err_t mcx_drv_pwm_enable(mcx_pwm_obj_t *pwm, struct rt_pwm_configuration *configuration) +{ + CTIMER_StartTimer(pwm->ct_instance); + return 0; +} +static rt_err_t mcx_drv_pwm_disable(mcx_pwm_obj_t *pwm, struct rt_pwm_configuration *configuration) +{ + CTIMER_StopTimer(pwm->ct_instance); + return 0; +} +static rt_err_t mcx_drv_pwm_control(struct rt_device_pwm *device, int cmd, void *args) +{ + mcx_pwm_obj_t *pwm = device->parent.user_data; + struct rt_pwm_configuration *configuration = (struct rt_pwm_configuration *)args; + switch (cmd) + { + case PWM_CMD_ENABLE: + return mcx_drv_pwm_enable(pwm, configuration); + case PWM_CMD_DISABLE: + return mcx_drv_pwm_disable(pwm, configuration); + case PWM_CMD_SET: + return mcx_drv_pwm_set(pwm, configuration); + case PWM_CMD_GET: + return mcx_drv_pwm_get(pwm, configuration); + default: + return -RT_EINVAL; + } + return RT_EOK; +} +static struct rt_pwm_ops mcx_pwm_ops = +{ + .control = mcx_drv_pwm_control, +}; +int mcx_pwm_init(void) +{ + rt_err_t ret; + char name_buf[8]; + ctimer_config_t config; + CTIMER_GetDefaultConfig(&config); + for (uint8_t i = 0; i < ARRAY_SIZE(mcx_pwm_list); i++) + { + mcx_pwm_list[i].timerClock = CLOCK_GetCTimerClkFreq(1U) / (config.prescale + 1); + CTIMER_Init(mcx_pwm_list[i].ct_instance, &config); + ret = rt_device_pwm_register(&mcx_pwm_list[i].pwm_device, mcx_pwm_list[i].name, &mcx_pwm_ops, &mcx_pwm_list[i]); + if (ret != RT_EOK) + { + return ret; + } + } + return RT_EOK; +} +INIT_DEVICE_EXPORT(mcx_pwm_init); +#endif /* RT_USING_PWM */ +``` +### 2.2 pin_mux.c +在BOARD_InitPins函数里加入以下代码 +```c +#ifdef BSP_USING_PWM0 + ctimer_config_t config; + CTIMER_Init(CTIMER1, &config); + const port_pin_config_t port1_4_pin62_config = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Low internal pull resistor value is selected. */ + kPORT_LowPullResistor, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive input filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain output is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Normal drive strength is configured */ + kPORT_NormalDriveStrength, + /* Pin is configured as CT1_MAT2 */ + kPORT_MuxAlt4, + /* Digital input enabled */ + kPORT_InputBufferEnable, + /* Digital input is not inverted */ + kPORT_InputNormal, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORT1_4 (pin 62) is configured as CT1_MAT2 */ + PORT_SetPinConfig(PORT1, 4U, &port1_4_pin62_config); +#endif +``` +### 2.3 .config +加上PWM0相关开关 +```c +CONFIG_BSP_USING_PWM=y +CONFIG_BSP_USING_PWM0=y +``` +### 2.4 board/Kconfig +加入PWM0相关配置 +```c +menuconfig BSP_USING_PWM + config BSP_USING_PWM + bool "Enable PWM" + select RT_USING_PWM + default y + if BSP_USING_PWM + config BSP_USING_PWM0 + bool "Enable PWM0 output" + default y + endif +``` + +## 3. 测试用例 +生成频率1KHz,占空比为5%的方波 +```c +#include +#include +#include +#include "board.h" +#include +#define PWM_LED_DEV "pwm0" +#define PWM_CHANNEL 3 +int main(void) +{ + struct rt_device_pwm *pwm_dev = RT_NULL; + rt_uint32_t period, pulse; + period = 1000000; + pulse = 50000; + pwm_dev = (struct rt_device_pwm *)rt_device_find(PWM_LED_DEV); + if (pwm_dev == RT_NULL) + { + rt_kprintf("pwm device (%s) not found!\n", PWM_LED_DEV); + return RT_ERROR; + } + rt_pwm_enable(pwm_dev, PWM_CHANNEL); + rt_pwm_set(pwm_dev, PWM_CHANNEL, period, pulse); + while (1) + { + rt_thread_mdelay(1000); + } + return 0; +} +``` +## 4. 实验效果 +使用逻辑分析仪测量P1_4生成的波形,波形刚好频率为1KHz,占空比为5% +![alt text](Book_Picture/6.0.png) +## 5.原文链接 +原文链接:https://club.rt-thread.org/ask/article/689635e865d94049.html + +# **七、恩智浦FRDM-MCXA153上的 IIC(软件) 实践** (大菠萝) +## 1. 硬件介绍 +### 1.1 SSD1306 OLED +SSD1306是一款单片CMOS OLED PLED驱动器,具有有机 聚合物发光控制器二极管点阵图形显示系。SSD1306内置对比度控制、显示RAM和振荡器,减少了外部组件和功耗。它有256级亮度控制。数据 命令是从通用单片机通过硬件可选的6800 8000系列兼容并行接口发送,I2C接口或串行外围接口。它适用于许多紧凑型便携式应用程序,例如手机副显示屏、MP3播放器、计算器等。 +![alt text](Book_Picture/7.0.png) +## 2. 工程创建 +目前RT-Thread Studio尚未支持恩智浦FRDM-MCXA153开发板BSP,需要从gitee下载最新的主线,通过scons命令创建工程。下载好主线源码后,在rt-thread\bsp\nxp\mcx\mcxa\frdm-mcxa153 目录下打开scons环境,配置软件IIC驱动和SSD1306 OLED。 +### 2.1 软件IIC配置 +在恩智浦FRDM-MCXA153开发板板载的mikroBUS socket找到2个pin做软件IIC接口的SCL SDA,考虑到3.3V GND的需要,直接选择; P1_0和P1_2,具体可以从针脚图看到,下图红框处的针脚。 +![alt text](Book_Picture/7.1.png) +因为是软件IIC,直接在menuconfig的设备驱动中选择“Use GPIO to soft simulate I2C”,设置中直接配置到I2C1 bus上,之前选择了P1_0和P1_2作为SCL SDA,按照((port*32)+pin)的计算公式配置好即可,具体如下图。 +![alt text](Book_Picture/7.2.png) +其它的软件IIC的具体实现,都在RT-Thread的组件中实现了,不再介绍。 +### 2.2 SSD1306 OLED配置 +在menuconfig中选择enable SSD1306,并且设置好I2C bus name,I2C的地址默认是0x3c无需修改,同时打开SSD1306测试demo。 +![alt text](Book_Picture/7.3.png) +上述内容设置好之后,选择保存。分别执行下述2个命令: +- pkgs —update +- scons —target=mdk5 +待Keil工程生成后,打开工程编译程序。 +```c +Program Size: Code=83324 RO-data=25164 RW-data=784 ZI-data=7876 +Finished: 0 information, 2 warning and 0 error messages. +".\build\rtthread.axf" - 0 Error(s), 6 Warning(s). +Build Time Elapsed: 00:00:04 +``` +然后下载到恩智浦FRDM-MCXA153开发板上。 +![alt text](Book_Picture/7.4.png) +## 3. 软件IIC测试 +固件下载完成后,reset系统,可以看到软件IIC已经配置成功。 +```c +sram heap, begin: 0x0x200019d4, end: 0x0x20005c00 + \ | +- RT - Thread Operating System + | \ 5.2.0 build Jul 21 2024 15:49:40 + 2006 - 2024 Copyright by RT-Thread team +I I2C: I2C bus [i2c1] registered +D I2C_S: Software simulation i2c1 init done, SCL pin: 0x20, SDA pin: 0x22 +I I2C: I2C bus [i2c0] registered +using armclang, version: 6180002 +MCXA153 HelloWorld +msh > +``` +list device后,可以看到I2C1已经起来: +```c +msh >list device +device type ref count +-------- -------------------- ---------- +i2c0 I2C Bus 0 +i2c1 I2C Bus 0 +pin Pin Device 0 +uart0 Character Device 2 +msh > +``` +把ssd1306_TestAll的demo跑起来。 +![alt text](Book_Picture/7.5.jpg) +对比硬件IIC,软件IIC的刷屏速度的确差了很多。 +## 4.原文链接 +原文链接: https://club.rt-thread.org/ask/article/c0b78938726a4d7c.html +# **八、恩智浦FRDM-MCXA153上的 IIC(硬件) 实践** (大菠萝) +## 1. 工程创建 +目前RT-Thread Studio尚未支持恩智浦FRDM-MCXA153开发板BSP,需要从gitee下载最新的主线,通过scons命令创建工程。下载好主线源码后,在rt-thread\bsp\nxp\mcx\mcxa\frdm-mcxa153 目录下打开scons环境,配置IIC驱动和SSD1306 OLED。 +### 1.1 IIC配置 +恩智浦FRDM-MCXA153开发板板载的mikroBUS socket预留一个IIC接口,具体可以从针脚图看到,下图红框处的针脚。 +![alt text](Book_Picture/8.0.png) +NXP引入了一个Flexcomm概念,每个Flexcomm接口可通过软件选择作为USART、SPI或I2C接口。此处只需要在menuconfig中选择I2C0即可。 +![alt text](Book_Picture/8.1.png) +因为FRDM-MCXA153的BSP目前只有pin和Uart的驱动,需要增加drv_i2c.c文件,直接从已有的BSP(如N947)拷贝过来,同时修改baud、clock_attach_id、clock_div_name初始化值。 +![alt text](Book_Picture/8.2.png) +再修改pin mux的配置,首先在BOARD_InitPins函数中增加I2C0 reset实现: +```c +RESET_ReleasePeripheralReset(kLPI2C0_RST_SHIFT_RSTn); +``` +同时加上I2C0的SDA SCL针脚初始化代码: +```c +const port_pin_config_t port3_27_pin34_config = {/* Internal pull-up resistor is enabled */ + kPORT_PullUp, + /* Low internal pull resistor value is selected. */ + kPORT_LowPullResistor, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive input filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain output is enabled */ + kPORT_OpenDrainEnable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Normal drive strength is configured */ + kPORT_NormalDriveStrength, + /* Pin is configured as LPI2C0_SCL */ + kPORT_MuxAlt2, + /* Digital input enabled */ + kPORT_InputBufferEnable, + /* Digital input is not inverted */ + kPORT_InputNormal, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORT3_27 (pin 34) is configured as LPI2C0_SCL */ + PORT_SetPinConfig(PORT3, 27U, &port3_27_pin34_config); + const port_pin_config_t port3_28_pin33_config = {/* Internal pull-up resistor is enabled */ + kPORT_PullUp, + /* Low internal pull resistor value is selected. */ + kPORT_LowPullResistor, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive input filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain output is enabled */ + kPORT_OpenDrainEnable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Normal drive strength is configured */ + kPORT_NormalDriveStrength, + /* Pin is configured as LPI2C0_SDA */ + kPORT_MuxAlt2, + /* Digital input enabled */ + kPORT_InputBufferEnable, + /* Digital input is not inverted */ + kPORT_InputNormal, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORT3_28 (pin 33) is configured as LPI2C0_SDA */ + PORT_SetPinConfig(PORT3, 28U, &port3_28_pin33_config); +``` +### 1.2 SSD1306 OLED配置 +在menuconfig中选择enable SSD1306,并且设置好I2C bus name,I2C的地址默认是0x3c无需修改。 +![alt text](Book_Picture/8.3.png) +上述内容设置好之后,选择保存。分别执行下述2个命令: +- pkgs —update +- scons —target=mdk5 +待Keil工程生成后,打开工程编译程序。 +```c +Program Size: Code=79916 RO-data=24408 RW-data=768 ZI-data=7700 +Finished: 0 information, 2 warning and 0 error messages. +".\build\rtthread.axf" - 0 Error(s), 2 Warning(s). +Build Time Elapsed: 00:00:12 +``` +然后下载到恩智浦FRDM-MCXA153开发板上。 +![alt text](Book_Picture/8.4.png) +## 2. IIC测试 +固件下载完成后,reset系统 +```c + \ | +- RT - Thread Operating System + | \ 5.2.0 build Jul 17 2024 23:16:53 + 2006 - 2024 Copyright by RT-Thread team +I I2C: I2C bus [i2c0] registered +using armclang, version: 6180002 +MCXA153 HelloWorld +msh > +``` +list device后,可以看到IIC已经起来: +```c +msh >list device +device type ref count +-------- -------------------- ---------- +i2c0 I2C Bus 0 +pin Pin Device 0 +uart0 Character Device 2 +msh > +``` +因为之前在menuconfig选择ssd1306的时候同时选择了demo,跑起来。 +![alt text](Book_Picture/8.5.jpg) +## 3.原文链接 +原文链接: https://club.rt-thread.org/ask/article/29229e50ce678094.html +# **九、恩智浦FRDM-MCXA153不能调试的解决办法** (莫海文) +## 1. 前言 +新手接触到NXP的板子时,一个不留神把调试的GPIO(RXD、TXD)改掉,很容易出现MDK Keil无法识别CMSIS-DAP调试器的情况;主控进入了莫名其妙模式导致调试器无法识别了 +![alt text](Book_Picture/10.0.png) + +## 2. 解决办法 +下载并安装LinkServer,这里用的是1.6.133版本 +![alt text](Book_Picture/10.1.png) +下载安装MCU Link,这里用的是2.263版本 +![alt text](Book_Picture/10.2.png) +可以尝试在LinkServer控制台里边进行调试器固件更新(需要短接JP8引脚,然后再按RESET) +![alt text](Book_Picture/10.3.png) +然后命令行强刷axf固件,rtthread.axf必须是一个正常的固件,即RXD、TXD引脚没有被配错 + +```c +LinkServer.exe flash --probe #1 mcxa153 load rtthread.axf --erase-all +``` +输入命令回车后,等一段时间才会烧写完成 +![alt text](Book_Picture/10.4.png) +拔插USB连接线后发现在Keil里边又能识别CMISS-DAP调试器了,又可以继续浪没人管了 +![alt text](Book_Picture/10.5.png) + +## 3. 烧写命令 +检测烧写器是否存在:LinkServer.exe probes +检测烧写器是否需要升级:LinkServer.exe probes #1 update auto +![alt text](Book_Picture/10.6.png) +## 4. 总结 +网上说的RESET按键操作,其实不适合这个板子,要用LinkServer这个工具才行 +## 5.原文链接 +原文链接:https://club.rt-thread.org/ask/article/8366ed26e3c5480a.html