├── Kconfig ├── LICENSE ├── README.md ├── README_EN.md ├── bsp ├── st │ ├── README.md │ ├── README_EN.md │ ├── driver │ │ ├── drv_adc.c │ │ ├── drv_adc.h │ │ ├── drv_dac.c │ │ ├── drv_dac.h │ │ ├── drv_pin.c │ │ ├── drv_pin.h │ │ ├── drv_pwm.c │ │ ├── drv_pwm.h │ │ ├── drv_serial.c │ │ ├── drv_serial.h │ │ ├── drv_spi.c │ │ ├── drv_spi.h │ │ ├── drv_timer.c │ │ ├── drv_timer.h │ │ └── mr_board.c │ ├── stm32f103 │ │ └── driver │ │ │ ├── Kconfig │ │ │ └── mr_board.h │ ├── stm32f407 │ │ └── driver │ │ │ ├── Kconfig │ │ │ └── mr_board.h │ └── stm32f411 │ │ └── driver │ │ ├── Kconfig │ │ └── mr_board.h └── wch │ ├── README.md │ ├── README_EN.md │ ├── ch32v003 │ └── driver │ │ ├── Kconfig │ │ └── mr_board.h │ ├── ch32v203 │ └── driver │ │ ├── Kconfig │ │ └── mr_board.h │ ├── ch32v307 │ └── driver │ │ ├── Kconfig │ │ └── mr_board.h │ └── driver │ ├── drv_adc.c │ ├── drv_adc.h │ ├── drv_dac.c │ ├── drv_dac.h │ ├── drv_i2c.c │ ├── drv_i2c.h │ ├── drv_pin.c │ ├── drv_pin.h │ ├── drv_pwm.c │ ├── drv_pwm.h │ ├── drv_serial.c │ ├── drv_serial.h │ ├── drv_spi.c │ ├── drv_spi.h │ ├── drv_timer.c │ ├── drv_timer.h │ └── mr_board.c ├── components ├── Kconfig └── msh │ ├── Kconfig │ ├── msh.c │ └── msh_device.c ├── device ├── Kconfig ├── adc.c ├── can.c ├── dac.c ├── fast_pin.c ├── i2c.c ├── pin.c ├── pwm.c ├── serial.c ├── soft_i2c.c ├── spi.c └── timer.c ├── document ├── Kconfig │ ├── introduce_Kconfig.md │ └── introduce_Kconfig_EN.md ├── coding_style │ ├── coding_style.md │ └── coding_style_EN.md ├── components │ └── msh │ │ ├── msh.md │ │ ├── msh_EN.md │ │ ├── msh_device.md │ │ └── msh_device_EN.md ├── device │ ├── adc │ │ ├── adc.md │ │ └── adc_EN.md │ ├── dac │ │ ├── dac.md │ │ └── dac_EN.md │ ├── i2c │ │ ├── i2c.md │ │ └── i2c_EN.md │ ├── pin │ │ ├── pin.md │ │ └── pin_EN.md │ ├── pwm │ │ ├── pwm.md │ │ └── pwm_EN.md │ ├── serial │ │ ├── serial.md │ │ └── serial_EN.md │ ├── spi │ │ ├── spi.md │ │ └── spi_EN.md │ └── timer │ │ ├── timer.md │ │ └── timer_EN.md ├── mem_manager │ ├── mem_manager.md │ └── mem_manager_EN.md ├── picture │ ├── Kconfig │ │ ├── Kconfig.png │ │ ├── Kconfig1.png │ │ ├── Kconfig2.png │ │ ├── Kconfig3.png │ │ └── Kconfig4.png │ └── readme │ │ ├── README.png │ │ ├── build_m.png │ │ ├── build_mdk.png │ │ ├── cubemx_project.png │ │ ├── driver.png │ │ ├── kconfig_main1.png │ │ ├── kconfig_main2.png │ │ ├── msh_device1.png │ │ ├── msh_device2.png │ │ └── project.png └── tool │ ├── tool.md │ └── tool_EN.md ├── driver └── Kconfig ├── include ├── components │ └── mr_msh.h ├── device │ ├── mr_adc.h │ ├── mr_can.h │ ├── mr_dac.h │ ├── mr_i2c.h │ ├── mr_pin.h │ ├── mr_pwm.h │ ├── mr_serial.h │ ├── mr_soft_i2c.h │ ├── mr_spi.h │ └── mr_timer.h ├── mr_api.h ├── mr_config.h ├── mr_def.h ├── mr_lib.h └── mr_service.h ├── kconfig.py ├── source ├── device.c ├── memory.c └── service.c └── tool.py /Kconfig: -------------------------------------------------------------------------------- 1 | mainmenu "mr-library" 2 | 3 | menu "System configure" 4 | # Assert 5 | config MR_USING_ASSERT 6 | bool "Use assert" 7 | default y 8 | help 9 | "Use this option allows the use of assert statements in the code." 10 | 11 | # Heap 12 | config MR_CFG_HEAP_SIZE 13 | int "Heap size (Bytes)" 14 | default 4096 15 | range 32 2147483647 16 | help 17 | "This option sets the size of the heap used by the library." 18 | 19 | # Log 20 | menu "Log configure" 21 | config MR_USING_LOG_ERROR 22 | bool "Use error log" 23 | default y 24 | help 25 | "Use this option allows for the use of error log." 26 | 27 | config MR_USING_LOG_WARN 28 | bool "Use warning log" 29 | default y 30 | help 31 | "Use this option allows for the use of warning log." 32 | 33 | config MR_USING_LOG_INFO 34 | bool "Use info log" 35 | default y 36 | help 37 | "Use this option allows for the use of info log." 38 | 39 | config MR_USING_LOG_DEBUG 40 | bool "Use debug log" 41 | default y 42 | help 43 | "Use this option allows for the use of debug log." 44 | 45 | config MR_USING_LOG_SUCCESS 46 | bool "Use success log" 47 | default y 48 | help 49 | "Use this option allows for the use of success log." 50 | 51 | config MR_USING_LOG_COLOR 52 | bool "Use print color log" 53 | default n 54 | help 55 | "Use this option allows for the use of print color log." 56 | endmenu 57 | 58 | # Printf 59 | menu "Printf configure" 60 | config MR_CFG_PRINTF_BUFSZ 61 | int "Printf buffer size" 62 | default 128 63 | range 32 2147483647 64 | help 65 | "This option sets the buffer size used by the printf function." 66 | 67 | config MR_CFG_PRINTF_DEV_NAME 68 | string "Printf device name" 69 | default "serial1" 70 | help 71 | "This option sets the name of the device used by the printf function." 72 | 73 | config MR_USING_PRINTF_NONBLOCKING 74 | bool "Use printf non-blocking" 75 | default n 76 | help 77 | "Use this option allows for the use of the printf device non-blocking." 78 | endmenu 79 | endmenu 80 | 81 | # Device 82 | source "device/Kconfig" 83 | 84 | # Driver 85 | source "driver/Kconfig" 86 | 87 | # Components 88 | source "components/Kconfig" 89 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MR 框架 2 | 3 | [English](README_EN.md) 4 | 5 | ---------- 6 | 7 | 8 | * [MR 框架](#mr-框架) 9 | * [简介](#简介) 10 | * [关键特性](#关键特性) 11 | * [主要组成](#主要组成) 12 | * [标准化设备接口](#标准化设备接口) 13 | * [配置工具](#配置工具) 14 | * [目录结构](#目录结构) 15 | * [设备/组件支持一览表](#设备组件支持一览表) 16 | * [开始使用](#开始使用) 17 | * [验证Python环境](#验证python环境) 18 | * [将项目导入工程](#将项目导入工程) 19 | * [配置菜单选项](#配置菜单选项) 20 | * [先来点个灯吧](#先来点个灯吧) 21 | * [Hello World](#hello-world) 22 | * [现在您已经完成了入门教程,开始使用MR库吧](#现在您已经完成了入门教程开始使用mr库吧) 23 | 24 | 25 | ---------- 26 | 27 | # 简介 28 | 29 | `MR` 框架是专为嵌入式系统设计的轻量级框架。充分考虑了嵌入式系统在资源和性能方面的需求。 30 | 通过提供标准化的设备管理接口,极大简化了嵌入式应用开发的难度,帮助开发者快速构建嵌入式应用程序。 31 | 32 | 框架为开发者提供了标准化的开启(`open`)、关闭(`close`)、控制(`ioctl`)、读(`read`)、写(`write`) 33 | 等接口。它将应用程序与底层硬件驱动进行解耦。应用程序无需了解驱动的实现细节。 34 | 当硬件发生改变时,只需要适配底层驱动,应用程序就可以无缝迁移到新硬件上。这大大提高了软件的可重用性和应对新硬件的可扩展性。 35 | 36 | ---------- 37 | 38 | ![项目结构图](document/picture/readme/README.png) 39 | 40 | ---------- 41 | 42 | # 关键特性 43 | 44 | - 标准化的设备访问接口 45 | - 应用程序和驱动开发解耦 46 | - 简化底层驱动和应用程序开发 47 | - 轻量易上手,资源占用低 48 | - 模块化设计,各部分解耦合并独立开发,极低的硬件迁移成本 49 | - 支持在裸机环境和操作系统环境下使用 50 | 51 | # 主要组成 52 | 53 | - 设备框架:提供设备访问标准接口 54 | - 内存管理:动态内存管理 55 | - 工具:链表、队列、平衡树等常用数据结构 56 | - 各类功能组件 57 | 58 | ---------- 59 | 60 | # 标准化设备接口 61 | 62 | 设备的所有操作都可通过以下接口实现: 63 | 64 | | 接口 | 描述 | 65 | |:----------------|:--------| 66 | | mr_dev_register | 注册设备 | 67 | | mr_dev_open | 打开设备 | 68 | | mr_dev_close | 关闭设备 | 69 | | mr_dev_ioctl | 控制设备 | 70 | | mr_dev_read | 从设备读取数据 | 71 | | mr_dev_write | 向设备写入数据 | 72 | 73 | 示例: 74 | 75 | ```c 76 | int main(void) 77 | { 78 | /* 打开SPI1总线下的SPI10设备 */ 79 | int ds = mr_dev_open("spi1/spi10", MR_O_RDWR); 80 | 81 | /* 发送数据 */ 82 | uint8_t wr_buf[] = {0x01, 0x02, 0x03, 0x04}; 83 | mr_dev_write(ds, wr_buf, sizeof(wr_buf)); 84 | 85 | /* 接收数据 */ 86 | uint8_t rd_buf[4] = {0}; 87 | mr_dev_read(ds, rd_buf, sizeof(rd_buf)); 88 | 89 | /* 关闭设备 */ 90 | mr_dev_close(ds); 91 | } 92 | ``` 93 | 94 | 得益于标准化设备接口,所有设备自动支持 `msh` 设备命令,通过命令行可完成所有设备操作。 95 | 96 | ![设备命令1](document/picture/readme/msh_device1.png) 97 | 98 | ![设备命令2](document/picture/readme/msh_device2.png) 99 | 100 | ---------- 101 | 102 | # 配置工具 103 | 104 | `MR` 提供 `Kconfig` 可视化配置工具,开发者无需深入了解源代码即可进行配置。 105 | 106 | `Kconfig` 会根据配置文件自动生成配置选项界面。开发者可以通过简单的操作来选择需要启用的功能组件和设置相关参数。 107 | 108 | ![配置工具1](document/picture/readme/kconfig_main1.png) 109 | 110 | ![配置工具2](document/picture/readme/kconfig_main2.png) 111 | 112 | 通过修改参数,快速裁剪所需功能。配置完成后通过 `Python` 脚本自动生成配置文件。 113 | 114 | ---------- 115 | 116 | # 目录结构 117 | 118 | | 名称 | 描述 | 119 | |:-----------|:-------| 120 | | bsp | 板级支持包 | 121 | | components | 组件 | 122 | | device | 设备文件 | 123 | | document | 文档 | 124 | | driver | 驱动文件 | 125 | | include | 库头文件 | 126 | | source | 库源文件 | 127 | | Kconfig | 配置文件 | 128 | | LICENSE | 许可证 | 129 | | kconfig.py | 自动配置脚本 | 130 | | tool.py | 自动构建脚本 | 131 | 132 | ---------- 133 | 134 | # 设备/组件支持一览表 135 | 136 | | 设备/组件 | 计划 | 预览 | 稳定 | 文档 | 137 | |:-----------|:----|:----|:----|:----| 138 | | `ADC` | | | [√] | [√] | 139 | | `CAN` | | [√] | | | 140 | | `DAC` | | | [√] | [√] | 141 | | `I2C` | | | [√] | [√] | 142 | | `Soft-I2C` | | | [√] | [√] | 143 | | `Pin` | | | [√] | [√] | 144 | | `PWM` | | | [√] | [√] | 145 | | `Serial` | | | [√] | [√] | 146 | | `SPI` | | | [√] | [√] | 147 | | `Timer` | | | [√] | [√] | 148 | | `msh` | | | [√] | [√] | 149 | | `LCD` | [√] | | | | 150 | | `Senser` | [√] | | | | 151 | 152 | ---------- 153 | 154 | # 开始使用 155 | 156 | ## 验证Python环境 157 | 158 | 验证系统是否安装Python环境。在命令行中运行 `python --version` 检查Python版本(`MR` 脚本工具依赖Python ,若无Python环境请自行安装,暂不支持`3.11.7`以上的版本)。 159 | 160 | ## 将项目导入工程 161 | 162 | 1. 从 `Gitee` 或 `Github` 仓库下载最新版本源码到本地。 163 | 2. 将源码复制到您工程所在的目录。以 `MDK` 工程(CubeMX生成的标准工程)为例: 164 | 165 | ![CubeMX工程](document/picture/readme/cubemx_project.png) 166 | 167 | 3. 将 `bsp` 目录中对应芯片的驱动复制到 `driver`(请仔细阅读`bsp`中的文档): 168 | 169 | ![Driver目录](document/picture/readme/driver.png) 170 | 171 | 4. 移除不需要的文件 `bsp`、`document`目录(如不需要`GIT`也可以移除`.git`文件)。完成后,目录结构如下所示: 172 | 173 | ![工程目录](document/picture/readme/project.png) 174 | 175 | 5. 使用自动构建脚本,完成自动构建。在 `mr-library` 路径下,打开命令行工具,运行 `python tool.py -b` 176 | 177 | 以`MDK`为例: 178 | 179 | ![MDK自动构建](document/picture/readme/build_mdk.png) 180 | 181 | 注: 182 | - 支持`MDK5`、`Eclipse`。 183 | - `MDK`未先编译或版本过低可能导致`GNU`配置失败。 184 | 185 | ## 配置菜单选项 186 | 187 | 1. 在 `mr-library` 目录下打开命令行工具,运行 `python tool.py -m` 进行菜单配置。 188 | 189 | ![配置工具1](document/picture/readme/kconfig_main1.png) 190 | 191 | 运行失败: 192 | - 检查`Python`版本(暂不支持`3.11.7`以上的版本,重新安装并删除已安装的模块)。 193 | - 命令行工具不支持,推荐使用`powershell(win10及以上)`、`git bash(较新版本)`等。 194 | 195 | 2. 选中 `Device configure` 回车进入菜单,配置功能。 196 | 197 | ![配置工具2](document/picture/readme/kconfig_main2.png) 198 | 199 | 3. 配置完成后,按 `Q` 退出菜单配置界面,按`Y` 保存配置,脚本将自动生成配置文件。 200 | 201 | ![自动配置工具](document/picture/readme/build_m.png) 202 | 203 | 4. 工程中引入 `#include "include/mr_lib.h"` 并在 `main` 函数中添加 `mr_auto_init();` 自动初始化函数,即可开始使用。 204 | 205 | 注:更多命令可输入:`python tool.py -h` 查看。 206 | 207 | ---------- 208 | 209 | # 先来点个灯吧 210 | 211 | ```c 212 | #include "include/mr_lib.h" 213 | 214 | /* 定义LED引脚(PC13)*/ 215 | #define LED_PIN_NUMBER 45 216 | 217 | int main(void) 218 | { 219 | /* 自动初始化 */ 220 | mr_auto_init(); 221 | 222 | /* 打开PIN设备 */ 223 | int ds = mr_dev_open("pin", MR_O_WRONLY); 224 | /* 设置到LED引脚 */ 225 | mr_dev_ioctl(ds, MR_IOC_PIN_SET_NUMBER, MR_MAKE_LOCAL(int, LED_PIN_NUMBER)); 226 | /* 设置LED引脚为推挽输出模式 */ 227 | mr_dev_ioctl(ds, MR_IOC_PIN_SET_MODE, MR_MAKE_LOCAL(int, MR_PIN_MODE_OUTPUT)); 228 | 229 | while(1) 230 | { 231 | /* 点亮LED */ 232 | mr_dev_write(ds, MR_MAKE_LOCAL(uint8_t, 1), sizeof(uint8_t)); 233 | mr_delay_ms(500); 234 | mr_dev_write(ds, MR_MAKE_LOCAL(uint8_t, 0), sizeof(uint8_t)); 235 | mr_delay_ms(500); 236 | } 237 | } 238 | ``` 239 | 240 | # Hello World 241 | 242 | ```c 243 | #include "include/mr_lib.h" 244 | 245 | int main(void) 246 | { 247 | /* 自动初始化 */ 248 | mr_auto_init(); 249 | 250 | /* 打开Serial-1设备 */ 251 | int ds = mr_dev_open("serial1", MR_O_RDWR); 252 | /* 输出Hello World */ 253 | mr_dev_write(ds, "Hello World\r\n", sizeof("Hello World\r\n")); 254 | 255 | while(1); 256 | } 257 | ``` 258 | 259 | ---------- 260 | 261 | # 现在您已经完成了入门教程,开始使用MR库吧 262 | 263 | 1. [参考更多教程](document)。 264 | 2. 尝试基于某款芯片开发驱动,练习设备驱动编程。 265 | 3. 尝试编写更多设备模板和开发更多功能。 266 | 4. 欢迎您提出意见和建议。如果您对开发有兴趣,诚邀您参与到 `MR` 项目的开发中来,项目交流群:199915649(QQ)。 267 | -------------------------------------------------------------------------------- /bsp/st/README.md: -------------------------------------------------------------------------------- 1 | # ST配置教程 2 | 3 | [English](README_EN.md) 4 | 5 | 注: 6 | 7 | - 此`BSP`仅支持`HAL`库,暂不支持`标准`库(可使用`WCH`驱动,自行配置即可)或`LL`库需求。 8 | - 此`BSP`需与`CubeMx`结合使用。 9 | 10 | ## 创建工程 11 | 12 | 使用`CubeMx`创建对应芯片的工程。使能需要使用的功能(配置管脚映射关系等)。 13 | 14 | 注:禁止使能中断,否则会报重复定义错误(`MR`框架已接管中断)。 15 | 16 | ## 将项目导入工程(2.添加驱动) 17 | 18 | 复制`bsp/st/driver`和`stm32xxx/driver`文件至`driver`。 19 | 20 | ## 移植驱动 21 | 22 | 参考上一步中`stm32xxx/driver`路径下`Kconfig`和`mr_board.h`,修改参数,完成移植与裁剪(请注意,`BSP`是按同一系列中最高型号进行移植的, 23 | 在选择和使用外设时请先查阅芯片手册核对当前芯片是否有此外设)。 24 | 25 | ## 继续按仓库目录下`README`,添加 mr-library 26 | -------------------------------------------------------------------------------- /bsp/st/README_EN.md: -------------------------------------------------------------------------------- 1 | # ST configuration tutorial 2 | 3 | [中文](README.md) 4 | 5 | Note: 6 | 7 | - This `BSP` only supports the `HAL` library, and does not currently support `standard` library(`WCH` driver can be used, you can configure yourself) or `LL` library requirements. 8 | - This `BSP` needs to be used together with `CubeMx`. 9 | 10 | ## Create project 11 | 12 | Use `CubeMx` to create a project for the corresponding chip. Enable the required functions(Configure pin mapping, etc). 13 | 14 | Note: Do not enable interrupts, otherwise it will report redefinition errors (the `MR` framework has taken over 15 | interrupts). 16 | 17 | ## Import project into project (2. Add driver) 18 | 19 | Copy `bsp/st/driver` and `stm32xxx/driver` files to `driver`. 20 | 21 | ## Port driver 22 | 23 | Refer to the `stm32xxx/driver` path `Kconfig` and `mr_board.h` in the previous step to modify parameters and complete 24 | the migration and tailoring(Note that the `BSP` is ported to the highest model in the same series, 25 | When selecting and using peripherals, please refer to the chip manual to check whether the current chip has additional devices). 26 | 27 | ## Continue to add mr-library by pressing `README` in the repository directory 28 | -------------------------------------------------------------------------------- /bsp/st/driver/drv_adc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @copyright (c) 2023-2024, MR Development Team 3 | * 4 | * @license SPDX-License-Identifier: Apache-2.0 5 | * 6 | * @date 2023-11-11 MacRsh First version 7 | */ 8 | 9 | #include "drv_adc.h" 10 | 11 | #ifdef MR_USING_ADC 12 | 13 | #if !defined(MR_USING_ADC1) && !defined(MR_USING_ADC2) && !defined(MR_USING_ADC3) 14 | #warning "Please enable at least one ADC driver" 15 | #endif /* !defined(MR_USING_ADC1) && !defined(MR_USING_ADC2) && !defined(MR_USING_ADC3) */ 16 | 17 | enum drv_adc_index 18 | { 19 | #ifdef MR_USING_ADC1 20 | DRV_INDEX_ADC1, 21 | #endif /* MR_USING_ADC1 */ 22 | #ifdef MR_USING_ADC2 23 | DRV_INDEX_ADC2, 24 | #endif /* MR_USING_ADC2 */ 25 | #ifdef MR_USING_ADC3 26 | DRV_INDEX_ADC3, 27 | #endif /* MR_USING_ADC3 */ 28 | DRV_INDEX_ADC_MAX 29 | }; 30 | 31 | static const char *adc_path[] = 32 | { 33 | #ifdef MR_USING_ADC1 34 | "adc1", 35 | #endif /* MR_USING_ADC1 */ 36 | #ifdef MR_USING_ADC2 37 | "adc2", 38 | #endif /* MR_USING_ADC2 */ 39 | #ifdef MR_USING_ADC3 40 | "adc3", 41 | #endif /* MR_USING_ADC3 */ 42 | }; 43 | 44 | static struct drv_adc_data adc_drv_data[] = 45 | { 46 | #ifdef MR_USING_ADC1 47 | {{0}, ADC1}, 48 | #endif /* MR_USING_ADC1 */ 49 | #ifdef MR_USING_ADC2 50 | {{0}, ADC2}, 51 | #endif /* MR_USING_ADC2 */ 52 | #ifdef MR_USING_ADC3 53 | {{0}, ADC3}, 54 | #endif /* MR_USING_ADC3 */ 55 | }; 56 | 57 | static struct drv_adc_channel_data adc_channel_drv_data[] = DRV_ADC_CHANNEL_CONFIG; 58 | 59 | static struct mr_adc adc_dev[MR_ARRAY_NUM(adc_drv_data)]; 60 | 61 | static struct drv_adc_channel_data *drv_adc_get_channel_data(int channel) 62 | { 63 | if (channel >= MR_ARRAY_NUM(adc_channel_drv_data)) 64 | { 65 | return NULL; 66 | } 67 | return &adc_channel_drv_data[channel]; 68 | } 69 | 70 | static int drv_adc_configure(struct mr_adc *adc, int state) 71 | { 72 | struct drv_adc_data *adc_data = (struct drv_adc_data *)adc->dev.drv->data; 73 | adc_data->handle.Instance = adc_data->instance; 74 | 75 | if (state == ENABLE) 76 | { 77 | /* Configure ADC */ 78 | #if defined(ADC_RESOLUTION_12B) 79 | adc_data->handle.Init.Resolution = ADC_RESOLUTION_12B; 80 | #elif defined(ADC_RESOLUTION_10B) 81 | adc_data->handle.Init.Resolution = ADC_RESOLUTION_10B; 82 | #elif defined(ADC_RESOLUTION_8B) 83 | adc_data->handle.Init.Resolution = ADC_RESOLUTION_8B; 84 | #endif /* defined(ADC_RESOLUTION_12B) */ 85 | adc_data->handle.Init.ScanConvMode = DISABLE; 86 | adc_data->handle.Init.ContinuousConvMode = DISABLE; 87 | adc_data->handle.Init.DiscontinuousConvMode = DISABLE; 88 | adc_data->handle.Init.ExternalTrigConv = ADC_SOFTWARE_START; 89 | adc_data->handle.Init.DataAlign = ADC_DATAALIGN_RIGHT; 90 | adc_data->handle.Init.NbrOfConversion = 1; 91 | #if defined(ADC_EOC_SINGLE_CONV) 92 | adc_data->handle.Init.EOCSelection = ADC_EOC_SINGLE_CONV; 93 | #endif /* defined(ADC_EOC_SINGLE_CONV) */ 94 | HAL_ADC_Init(&adc_data->handle); 95 | } else 96 | { 97 | /* Configure ADC */ 98 | HAL_ADC_DeInit(&adc_data->handle); 99 | } 100 | return MR_EOK; 101 | } 102 | 103 | static int drv_adc_channel_configure(struct mr_adc *adc, int channel, int state) 104 | { 105 | return MR_EOK; 106 | } 107 | 108 | static int drv_adc_read(struct mr_adc *adc, int channel, uint32_t *data) 109 | { 110 | struct drv_adc_data *adc_data = (struct drv_adc_data *)adc->dev.drv->data; 111 | struct drv_adc_channel_data *adc_channel_data = drv_adc_get_channel_data(channel); 112 | ADC_ChannelConfTypeDef sConfig = {0}; 113 | 114 | #ifdef MR_USING_ADC_CHANNEL_CHECK 115 | /* Check channel is valid */ 116 | if (adc_channel_data == NULL) 117 | { 118 | return MR_EINVAL; 119 | } 120 | #endif /* MR_USING_ADC_CHANNEL_CHECK */ 121 | 122 | /* Read data */ 123 | sConfig.Channel = adc_channel_data->channel; 124 | sConfig.Rank = 1; 125 | #if defined(ADC_SAMPLETIME_55CYCLES_5) 126 | sConfig.SamplingTime = ADC_SAMPLETIME_55CYCLES_5; 127 | #elif defined(ADC_SAMPLETIME_56CYCLES) 128 | sConfig.SamplingTime = ADC_SAMPLETIME_56CYCLES; 129 | #elif defined(ADC_SAMPLETIME_71CYCLES_5) 130 | sConfig.SamplingTime = ADC_SAMPLETIME_71CYCLES_5; 131 | #elif defined(ADC_SAMPLETIME_84CYCLES) 132 | sConfig.SamplingTime = ADC_SAMPLETIME_84CYCLES; 133 | #elif defined(ADC_SAMPLETIME_112CYCLES) 134 | sConfig.SamplingTime = ADC_SAMPLETIME_112CYCLES; 135 | #elif defined(ADC_SAMPLETIME_144CYCLES) 136 | sConfig.SamplingTime = ADC_SAMPLETIME_144CYCLES; 137 | #elif defined(ADC_SAMPLETIME_239CYCLES_5) 138 | sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5; 139 | #elif defined(ADC_SAMPLETIME_247CYCLES_5) 140 | sConfig.SamplingTime = ADC_SAMPLETIME_247CYCLES_5; 141 | #elif defined(ADC_SAMPLETIME_480CYCLES) 142 | sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES; 143 | #endif /* defined(ADC_SAMPLETIME_55CYCLES_5) */ 144 | HAL_ADC_ConfigChannel(&adc_data->handle, &sConfig); 145 | HAL_ADC_Start(&adc_data->handle); 146 | if (HAL_ADC_PollForConversion(&adc_data->handle, UINT16_MAX) == HAL_OK) 147 | { 148 | *data = HAL_ADC_GetValue(&adc_data->handle); 149 | HAL_ADC_Stop(&adc_data->handle); 150 | return MR_EOK; 151 | } 152 | HAL_ADC_Stop(&adc_data->handle); 153 | return MR_ETIMEOUT; 154 | } 155 | 156 | static struct mr_adc_ops adc_drv_ops = 157 | { 158 | drv_adc_configure, 159 | drv_adc_channel_configure, 160 | drv_adc_read 161 | }; 162 | 163 | static struct mr_drv adc_drv[] = 164 | { 165 | #ifdef MR_USING_ADC1 166 | { 167 | &adc_drv_ops, 168 | &adc_drv_data[DRV_INDEX_ADC1], 169 | }, 170 | #endif /* MR_USING_ADC1 */ 171 | #ifdef MR_USING_ADC2 172 | { 173 | &adc_drv_ops, 174 | &adc_drv_data[DRV_INDEX_ADC2], 175 | }, 176 | #endif /* MR_USING_ADC2 */ 177 | #ifdef MR_USING_ADC3 178 | { 179 | &adc_drv_ops, 180 | &adc_drv_data[DRV_INDEX_ADC3], 181 | }, 182 | #endif /* MR_USING_ADC3 */ 183 | }; 184 | 185 | static void drv_adc_init(void) 186 | { 187 | for (size_t i = 0; i < MR_ARRAY_NUM(adc_dev); i++) 188 | { 189 | mr_adc_register(&adc_dev[i], adc_path[i], &adc_drv[i]); 190 | } 191 | } 192 | MR_INIT_DRV_EXPORT(drv_adc_init); 193 | 194 | #endif /* MR_USING_ADC */ 195 | -------------------------------------------------------------------------------- /bsp/st/driver/drv_adc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @copyright (c) 2023-2024, MR Development Team 3 | * 4 | * @license SPDX-License-Identifier: Apache-2.0 5 | * 6 | * @date 2023-11-11 MacRsh First version 7 | */ 8 | 9 | #ifndef _DRV_ADC_H_ 10 | #define _DRV_ADC_H_ 11 | 12 | #include "include/device/mr_adc.h" 13 | #include "mr_board.h" 14 | 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif /* __cplusplus */ 18 | 19 | #ifdef MR_USING_ADC 20 | 21 | struct drv_adc_data 22 | { 23 | ADC_HandleTypeDef handle; 24 | ADC_TypeDef *instance; 25 | }; 26 | 27 | struct drv_adc_channel_data 28 | { 29 | uint32_t channel; 30 | }; 31 | 32 | #endif /* MR_USING_ADC */ 33 | 34 | #ifdef __cplusplus 35 | } 36 | #endif /* __cplusplus */ 37 | 38 | #endif /* _DRV_ADC_H_ */ 39 | -------------------------------------------------------------------------------- /bsp/st/driver/drv_dac.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @copyright (c) 2023-2024, MR Development Team 3 | * 4 | * @license SPDX-License-Identifier: Apache-2.0 5 | * 6 | * @date 2024-01-22 MacRsh First version 7 | */ 8 | 9 | #include "drv_dac.h" 10 | 11 | #ifdef MR_USING_DAC 12 | 13 | #if !defined(MR_USING_DAC1) && !defined(MR_USING_DAC2) && !defined(MR_USING_DAC3) 14 | #warning "Please enable at least one DAC driver" 15 | #endif /* !defined(MR_USING_DAC1) && !defined(MR_USING_DAC2) && !defined(MR_USING_DAC3) */ 16 | 17 | enum drv_dac_index 18 | { 19 | #ifdef MR_USING_DAC1 20 | DRV_INDEX_DAC1, 21 | #endif /* MR_USING_DAC1 */ 22 | #ifdef MR_USING_DAC2 23 | DRV_INDEX_DAC2, 24 | #endif /* MR_USING_DAC2 */ 25 | #ifdef MR_USING_DAC3 26 | DRV_INDEX_DAC3, 27 | #endif /* MR_USING_DAC3 */ 28 | DRV_INDEX_DAC_MAX 29 | }; 30 | 31 | static const char *dac_name[] = 32 | { 33 | #ifdef MR_USING_DAC1 34 | "dac1", 35 | #endif /* MR_USING_DAC1 */ 36 | #ifdef MR_USING_DAC2 37 | "dac2", 38 | #endif /* MR_USING_DAC2 */ 39 | #ifdef MR_USING_DAC3 40 | "dac3", 41 | #endif /* MR_USING_DAC3 */ 42 | }; 43 | 44 | static struct drv_dac_data dac_drv_data[] = 45 | { 46 | #ifdef MR_USING_DAC1 47 | {{0}, DAC1}, 48 | #endif /* MR_USING_DAC1 */ 49 | #ifdef MR_USING_DAC2 50 | {{0}, DAC2}, 51 | #endif /* MR_USING_DAC2 */ 52 | #ifdef MR_USING_DAC3 53 | {{0}, DAC3}, 54 | #endif /* MR_USING_DAC3 */ 55 | }; 56 | 57 | static struct drv_dac_channel_data dac_channel_drv_data[] = DRV_DAC_CHANNEL_CONFIG; 58 | 59 | static struct mr_dac dac_dev[MR_ARRAY_NUM(dac_drv_data)]; 60 | 61 | static struct drv_dac_channel_data *drv_dac_get_channel_data(int channel) 62 | { 63 | if (channel >= MR_ARRAY_NUM(dac_channel_drv_data)) 64 | { 65 | return NULL; 66 | } 67 | return &dac_channel_drv_data[channel]; 68 | } 69 | 70 | static int drv_dac_configure(struct mr_dac *dac, int state) 71 | { 72 | struct drv_dac_data *dac_data = (struct drv_dac_data *)dac->dev.drv->data; 73 | dac_data->handle.Instance = dac_data->instance; 74 | 75 | if (state == ENABLE) 76 | { 77 | /* Configure DAC */ 78 | HAL_DAC_Init(&dac_data->handle); 79 | } else 80 | { 81 | /* Configure DAC */ 82 | HAL_DAC_DeInit(&dac_data->handle); 83 | } 84 | return MR_EOK; 85 | } 86 | 87 | static int drv_dac_channel_configure(struct mr_dac *dac, int channel, int state) 88 | { 89 | struct drv_dac_data *dac_data = (struct drv_dac_data *)dac->dev.drv->data; 90 | struct drv_dac_channel_data *dac_channel_data = drv_dac_get_channel_data(channel); 91 | DAC_ChannelConfTypeDef sConfig = {0}; 92 | 93 | #ifdef MR_USING_DAC_CHANNEL_CHECK 94 | /* Check channel is valid */ 95 | if (dac_channel_data == NULL) 96 | { 97 | return MR_EINVAL; 98 | } 99 | #endif /* MR_USING_DAC_CHANNEL_CHECK */ 100 | 101 | /* Configure Channel */ 102 | sConfig.DAC_Trigger = DAC_TRIGGER_NONE; 103 | sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_DISABLE; 104 | HAL_DAC_ConfigChannel(&dac_data->handle, &sConfig, dac_channel_data->channel); 105 | if (state == ENABLE) 106 | { 107 | HAL_DAC_SetValue(&dac_data->handle, dac_channel_data->channel, DAC_ALIGN_12B_R, 0); 108 | HAL_DAC_Start(&dac_data->handle, dac_channel_data->channel); 109 | } else 110 | { 111 | HAL_DAC_Stop(&dac_data->handle, dac_channel_data->channel); 112 | } 113 | return MR_EOK; 114 | } 115 | 116 | static int drv_dac_write(struct mr_dac *dac, int channel, uint32_t data) 117 | { 118 | struct drv_dac_data *dac_data = (struct drv_dac_data *)dac->dev.drv->data; 119 | struct drv_dac_channel_data *dac_channel_data = drv_dac_get_channel_data(channel); 120 | 121 | #ifdef MR_USING_DAC_CHANNEL_CHECK 122 | /* Check channel is valid */ 123 | if (dac_channel_data == NULL) 124 | { 125 | return MR_EINVAL; 126 | } 127 | #endif /* MR_USING_DAC_CHANNEL_CHECK */ 128 | 129 | /* Write data */ 130 | HAL_DAC_SetValue(&dac_data->handle, dac_channel_data->channel, DAC_ALIGN_12B_R, (data & 0xFFF)); 131 | } 132 | 133 | static struct mr_dac_ops dac_drv_ops = 134 | { 135 | drv_dac_configure, 136 | drv_dac_channel_configure, 137 | drv_dac_write, 138 | }; 139 | 140 | static struct mr_drv dac_drv[] = 141 | { 142 | #ifdef MR_USING_DAC1 143 | { 144 | MR_DRV_TYPE_DAC, 145 | &dac_drv_ops, 146 | &dac_drv_data[DRV_INDEX_DAC1], 147 | }, 148 | #endif /* MR_USING_DAC1 */ 149 | #ifdef MR_USING_DAC2 150 | { 151 | MR_DRV_TYPE_DAC, 152 | &dac_drv_ops, 153 | &dac_drv_data[DRV_INDEX_DAC2], 154 | } 155 | #endif /* MR_USING_DAC2 */ 156 | #ifdef MR_USING_DAC3 157 | { 158 | MR_DRV_TYPE_DAC, 159 | &dac_drv_ops, 160 | &dac_drv_data[DRV_INDEX_DAC3], 161 | } 162 | #endif /* MR_USING_DAC3 */ 163 | }; 164 | 165 | static void drv_dac_init(void) 166 | { 167 | for (size_t i = 0; i < MR_ARRAY_NUM(dac_dev); i++) 168 | { 169 | mr_dac_register(&dac_dev[i], dac_name[i], &dac_drv[i]); 170 | } 171 | } 172 | MR_INIT_DRV_EXPORT(drv_dac_init); 173 | 174 | #endif /* MR_USING_DAC */ 175 | -------------------------------------------------------------------------------- /bsp/st/driver/drv_dac.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @copyright (c) 2023-2024, MR Development Team 3 | * 4 | * @license SPDX-License-Identifier: Apache-2.0 5 | * 6 | * @date 2024-01-22 MacRsh First version 7 | */ 8 | 9 | #ifndef _DRV_DAC_H_ 10 | #define _DRV_DAC_H_ 11 | 12 | #include "include/device/mr_dac.h" 13 | #include "mr_board.h" 14 | 15 | #ifdef MR_USING_DAC 16 | 17 | struct drv_dac_data 18 | { 19 | DAC_HandleTypeDef handle; 20 | DAC_TypeDef *instance; 21 | }; 22 | 23 | struct drv_dac_channel_data 24 | { 25 | uint32_t channel; 26 | }; 27 | 28 | #endif /* MR_USING_DAC */ 29 | 30 | #endif /* _DRV_DAC_H_ */ 31 | -------------------------------------------------------------------------------- /bsp/st/driver/drv_pin.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @copyright (c) 2023-2024, MR Development Team 3 | * 4 | * @license SPDX-License-Identifier: Apache-2.0 5 | * 6 | * @date 2023-11-11 MacRsh First version 7 | */ 8 | 9 | #ifndef _DRV_PIN_H_ 10 | #define _DRV_PIN_H_ 11 | 12 | #include "include/device/mr_pin.h" 13 | #include "mr_board.h" 14 | 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif /* __cplusplus */ 18 | 19 | #ifdef MR_USING_PIN 20 | 21 | struct drv_pin_port_data 22 | { 23 | GPIO_TypeDef *port; 24 | }; 25 | 26 | struct drv_pin_data 27 | { 28 | uint32_t pin; 29 | }; 30 | 31 | #endif /* MR_USING_PIN */ 32 | 33 | #ifdef __cplusplus 34 | } 35 | #endif /* __cplusplus */ 36 | 37 | #endif /* _DRV_PIN_H_ */ 38 | -------------------------------------------------------------------------------- /bsp/st/driver/drv_pwm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @copyright (c) 2023-2024, MR Development Team 3 | * 4 | * @license SPDX-License-Identifier: Apache-2.0 5 | * 6 | * @date 2024-01-21 MacRsh First version 7 | */ 8 | 9 | #ifndef _DRV_PWM_H_ 10 | #define _DRV_PWM_H_ 11 | 12 | #include "include/device/mr_pwm.h" 13 | #include "mr_board.h" 14 | 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif /* __cplusplus */ 18 | 19 | #ifdef MR_USING_PWM 20 | 21 | struct drv_pwm_data 22 | { 23 | TIM_HandleTypeDef handle; 24 | TIM_TypeDef *instance; 25 | }; 26 | 27 | #endif /* MR_USING_PWM */ 28 | 29 | #ifdef __cplusplus 30 | } 31 | #endif /* __cplusplus */ 32 | 33 | #endif /* _DRV_PWM_H_ */ 34 | -------------------------------------------------------------------------------- /bsp/st/driver/drv_serial.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @copyright (c) 2023-2024, MR Development Team 3 | * 4 | * @license SPDX-License-Identifier: Apache-2.0 5 | * 6 | * @date 2023-11-10 MacRsh First version 7 | */ 8 | 9 | #ifndef _DRV_SERIAL_H_ 10 | #define _DRV_SERIAL_H_ 11 | 12 | #include "include/device/mr_serial.h" 13 | #include "mr_board.h" 14 | 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif /* __cplusplus */ 18 | 19 | #ifdef MR_USING_SERIAL 20 | 21 | struct drv_serial_data 22 | { 23 | UART_HandleTypeDef handle; 24 | USART_TypeDef *instance; 25 | IRQn_Type irq; 26 | }; 27 | 28 | #endif /* MR_USING_SERIAL */ 29 | 30 | #ifdef __cplusplus 31 | } 32 | #endif /* __cplusplus */ 33 | 34 | #endif /* _DRV_SERIAL_H_ */ 35 | -------------------------------------------------------------------------------- /bsp/st/driver/drv_spi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @copyright (c) 2023-2024, MR Development Team 3 | * 4 | * @license SPDX-License-Identifier: Apache-2.0 5 | * 6 | * @date 2023-11-10 MacRsh First version 7 | */ 8 | 9 | #ifndef _DRV_SPI_H_ 10 | #define _DRV_SPI_H_ 11 | 12 | #include "include/device/mr_spi.h" 13 | #include "mr_board.h" 14 | 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif /* __cplusplus */ 18 | 19 | #ifdef MR_USING_SPI 20 | 21 | struct drv_spi_bus_data 22 | { 23 | SPI_HandleTypeDef handle; 24 | SPI_TypeDef *instance; 25 | IRQn_Type irq; 26 | }; 27 | 28 | #endif /* MR_USING_SPI */ 29 | 30 | #ifdef __cplusplus 31 | } 32 | #endif /* __cplusplus */ 33 | 34 | #endif /* _DRV_SPI_H_ */ 35 | -------------------------------------------------------------------------------- /bsp/st/driver/drv_timer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @copyright (c) 2023-2024, MR Development Team 3 | * 4 | * @license SPDX-License-Identifier: Apache-2.0 5 | * 6 | * @date 2023-11-30 MacRsh First version 7 | */ 8 | 9 | #ifndef _DRV_TIMER_H_ 10 | #define _DRV_TIMER_H_ 11 | 12 | #include "include/device/mr_timer.h" 13 | #include "mr_board.h" 14 | 15 | #ifdef MR_USING_TIMER 16 | 17 | struct drv_timer_data 18 | { 19 | TIM_HandleTypeDef handle; 20 | TIM_TypeDef *instance; 21 | IRQn_Type irq; 22 | }; 23 | 24 | #endif /* MR_USING_TIMER */ 25 | 26 | #endif /* _DRV_TIMER_H_ */ 27 | -------------------------------------------------------------------------------- /bsp/st/driver/mr_board.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @copyright (c) 2023-2024, MR Development Team 3 | * 4 | * @license SPDX-License-Identifier: Apache-2.0 5 | * 6 | * @date 2023-11-10 MacRsh First version 7 | */ 8 | 9 | #include "mr_board.h" 10 | 11 | void mr_delay_ms(uint32_t ms) 12 | { 13 | HAL_Delay(ms); 14 | } 15 | -------------------------------------------------------------------------------- /bsp/st/stm32f103/driver/Kconfig: -------------------------------------------------------------------------------- 1 | menu "Driver configure" 2 | 3 | menu "ADC" 4 | config MR_USING_ADC1 5 | bool "Enable ADC1 driver" 6 | default n 7 | 8 | config MR_USING_ADC2 9 | bool "Enable ADC2 driver" 10 | default n 11 | 12 | config MR_USING_ADC3 13 | bool "Enable ADC3 driver" 14 | default n 15 | endmenu 16 | 17 | menu "DAC" 18 | config MR_USING_DAC1 19 | bool "Enable DAC1 driver" 20 | default n 21 | endmenu 22 | 23 | menu "PWM" 24 | config MR_USING_PWM1 25 | bool "Enable PWM1 driver" 26 | default n 27 | 28 | config MR_USING_PWM2 29 | bool "Enable PWM2 driver" 30 | default n 31 | 32 | config MR_USING_PWM3 33 | bool "Enable PWM3 driver" 34 | default n 35 | 36 | config MR_USING_PWM4 37 | bool "Enable PWM4 driver" 38 | default n 39 | 40 | config MR_USING_PWM5 41 | bool "Enable PWM5 driver" 42 | default n 43 | 44 | config MR_USING_PWM6 45 | bool "Enable PWM6 driver" 46 | default n 47 | 48 | config MR_USING_PWM7 49 | bool "Enable PWM7 driver" 50 | default n 51 | 52 | config MR_USING_PWM8 53 | bool "Enable PWM8 driver" 54 | default n 55 | 56 | config MR_USING_PWM9 57 | bool "Enable PWM9 driver" 58 | default n 59 | 60 | config MR_USING_PWM10 61 | bool "Enable PWM10 driver" 62 | default n 63 | 64 | config MR_USING_PWM11 65 | bool "Enable PWM11 driver" 66 | default n 67 | 68 | config MR_USING_PWM12 69 | bool "Enable PWM12 driver" 70 | default n 71 | 72 | config MR_USING_PWM13 73 | bool "Enable PWM13 driver" 74 | default n 75 | 76 | config MR_USING_PWM14 77 | bool "Enable PWM14 driver" 78 | default n 79 | endmenu 80 | 81 | menu "UART" 82 | config MR_USING_UART1 83 | bool "Enable UART1 driver" 84 | default n 85 | 86 | config MR_USING_UART2 87 | bool "Enable UART2 driver" 88 | default n 89 | 90 | config MR_USING_UART3 91 | bool "Enable UART3 driver" 92 | default n 93 | 94 | config MR_USING_UART4 95 | bool "Enable UART4 driver" 96 | default n 97 | 98 | config MR_USING_UART5 99 | bool "Enable UART5 driver" 100 | default n 101 | endmenu 102 | 103 | menu "SPI" 104 | config MR_USING_SPI1 105 | bool "Enable SPI1 driver" 106 | default n 107 | 108 | config MR_USING_SPI2 109 | bool "Enable SPI2 driver" 110 | default n 111 | 112 | config MR_USING_SPI3 113 | bool "Enable SPI3 driver" 114 | default n 115 | endmenu 116 | 117 | menu "Timer" 118 | config MR_USING_TIMER1 119 | bool "Enable Timer1 driver" 120 | default n 121 | 122 | config MR_USING_TIMER2 123 | bool "Enable Timer2 driver" 124 | default n 125 | 126 | config MR_USING_TIMER3 127 | bool "Enable Timer3 driver" 128 | default n 129 | 130 | config MR_USING_TIMER4 131 | bool "Enable Timer4 driver" 132 | default n 133 | 134 | config MR_USING_TIMER5 135 | bool "Enable Timer5 driver" 136 | default n 137 | 138 | config MR_USING_TIMER6 139 | bool "Enable Timer6 driver" 140 | default n 141 | 142 | config MR_USING_TIMER7 143 | bool "Enable Timer7 driver" 144 | default n 145 | 146 | config MR_USING_TIMER8 147 | bool "Enable Timer8 driver" 148 | default n 149 | 150 | config MR_USING_TIMER9 151 | bool "Enable Timer9 driver" 152 | default n 153 | 154 | config MR_USING_TIMER10 155 | bool "Enable Timer10 driver" 156 | default n 157 | 158 | config MR_USING_TIMER11 159 | bool "Enable Timer11 driver" 160 | default n 161 | 162 | config MR_USING_TIMER12 163 | bool "Enable Timer12 driver" 164 | default n 165 | 166 | config MR_USING_TIMER13 167 | bool "Enable Timer13 driver" 168 | default n 169 | 170 | config MR_USING_TIMER14 171 | bool "Enable Timer14 driver" 172 | default n 173 | endmenu 174 | 175 | endmenu 176 | -------------------------------------------------------------------------------- /bsp/st/stm32f103/driver/mr_board.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @copyright (c) 2023-2024, MR Development Team 3 | * 4 | * @license SPDX-License-Identifier: Apache-2.0 5 | * 6 | * @date 2023-12-12 MacRsh First version 7 | */ 8 | 9 | #ifndef _MR_BOARD_H_ 10 | #define _MR_BOARD_H_ 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif /* __cplusplus */ 15 | 16 | #include "stm32f1xx.h" 17 | 18 | #define DRV_ADC_CHANNEL_CONFIG \ 19 | { \ 20 | {ADC_CHANNEL_0}, \ 21 | {ADC_CHANNEL_1}, \ 22 | {ADC_CHANNEL_2}, \ 23 | {ADC_CHANNEL_3}, \ 24 | {ADC_CHANNEL_4}, \ 25 | {ADC_CHANNEL_5}, \ 26 | {ADC_CHANNEL_6}, \ 27 | {ADC_CHANNEL_7}, \ 28 | {ADC_CHANNEL_8}, \ 29 | {ADC_CHANNEL_9}, \ 30 | {ADC_CHANNEL_10}, \ 31 | {ADC_CHANNEL_11}, \ 32 | {ADC_CHANNEL_12}, \ 33 | {ADC_CHANNEL_13}, \ 34 | {ADC_CHANNEL_14}, \ 35 | {ADC_CHANNEL_15}, \ 36 | {ADC_CHANNEL_16}, \ 37 | {ADC_CHANNEL_17}, \ 38 | } 39 | 40 | #define DRV_DAC_CHANNEL_CONFIG \ 41 | { \ 42 | {NULL}, \ 43 | {DAC_CHANNEL_1}, \ 44 | {DAC_CHANNEL_2}, \ 45 | } 46 | 47 | #define DRV_PIN_IRQ_MAP_CONFIG \ 48 | { \ 49 | EXTI0_IRQn, \ 50 | EXTI1_IRQn, \ 51 | EXTI2_IRQn, \ 52 | EXTI3_IRQn, \ 53 | EXTI4_IRQn, \ 54 | EXTI9_5_IRQn, \ 55 | EXTI9_5_IRQn, \ 56 | EXTI9_5_IRQn, \ 57 | EXTI9_5_IRQn, \ 58 | EXTI9_5_IRQn, \ 59 | EXTI15_10_IRQn, \ 60 | EXTI15_10_IRQn, \ 61 | EXTI15_10_IRQn, \ 62 | EXTI15_10_IRQn, \ 63 | EXTI15_10_IRQn, \ 64 | EXTI15_10_IRQn, \ 65 | } 66 | 67 | #ifdef GPIOD 68 | #define DRV_PIN_PORT_D GPIOD, 69 | #else 70 | #define DRV_PIN_PORT_D 71 | #endif /* GPIOD */ 72 | #ifdef GPIOE 73 | #define DRV_PIN_PORT_E GPIOE, 74 | #else 75 | #define DRV_PIN_PORT_E 76 | #endif /* GPIOE */ 77 | #ifdef GPIOF 78 | #define DRV_PIN_PORT_F GPIOF, 79 | #else 80 | #define DRV_PIN_PORT_F 81 | #endif /* GPIOF */ 82 | #ifdef GPIOG 83 | #define DRV_PIN_PORT_G GPIOG, 84 | #else 85 | #define DRV_PIN_PORT_G 86 | #endif /* GPIOG */ 87 | 88 | #define DRV_PIN_PORT_CONFIG \ 89 | { \ 90 | GPIOA, \ 91 | GPIOB, \ 92 | GPIOC, \ 93 | DRV_PIN_PORT_D \ 94 | DRV_PIN_PORT_E \ 95 | DRV_PIN_PORT_F \ 96 | DRV_PIN_PORT_G \ 97 | } 98 | 99 | #define DRV_PIN_CONFIG \ 100 | { \ 101 | GPIO_PIN_0, \ 102 | GPIO_PIN_1, \ 103 | GPIO_PIN_2, \ 104 | GPIO_PIN_3, \ 105 | GPIO_PIN_4, \ 106 | GPIO_PIN_5, \ 107 | GPIO_PIN_6, \ 108 | GPIO_PIN_7, \ 109 | GPIO_PIN_8, \ 110 | GPIO_PIN_9, \ 111 | GPIO_PIN_10, \ 112 | GPIO_PIN_11, \ 113 | GPIO_PIN_12, \ 114 | GPIO_PIN_13, \ 115 | GPIO_PIN_14, \ 116 | GPIO_PIN_15, \ 117 | } 118 | 119 | #define DRV_PWM1_INFO_CONFIG \ 120 | {0, UINT16_MAX, UINT16_MAX} 121 | #define DRV_PWM2_INFO_CONFIG \ 122 | {0, UINT16_MAX, UINT16_MAX} 123 | #define DRV_PWM3_INFO_CONFIG \ 124 | {0, UINT16_MAX, UINT16_MAX} 125 | #define DRV_PWM4_INFO_CONFIG \ 126 | {0, UINT16_MAX, UINT16_MAX} 127 | #define DRV_PWM5_INFO_CONFIG \ 128 | {0, UINT16_MAX, UINT16_MAX} 129 | #define DRV_PWM6_INFO_CONFIG \ 130 | {0, UINT16_MAX, UINT16_MAX} 131 | #define DRV_PWM7_INFO_CONFIG \ 132 | {0, UINT16_MAX, UINT16_MAX} 133 | #define DRV_PWM8_INFO_CONFIG \ 134 | {0, UINT16_MAX, UINT16_MAX} 135 | #define DRV_PWM9_INFO_CONFIG \ 136 | {0, UINT16_MAX, UINT16_MAX} 137 | #define DRV_PWM10_INFO_CONFIG \ 138 | {0, UINT16_MAX, UINT16_MAX} 139 | #define DRV_PWM11_INFO_CONFIG \ 140 | {0, UINT16_MAX, UINT16_MAX} 141 | #define DRV_PWM12_INFO_CONFIG \ 142 | {0, UINT16_MAX, UINT16_MAX} 143 | #define DRV_PWM13_INFO_CONFIG \ 144 | {0, UINT16_MAX, UINT16_MAX} 145 | #define DRV_PWM14_INFO_CONFIG \ 146 | {0, UINT16_MAX, UINT16_MAX} 147 | 148 | #define DRV_TIMER1_INFO_CONFIG \ 149 | {0, UINT16_MAX, UINT16_MAX} 150 | #define DRV_TIMER2_INFO_CONFIG \ 151 | {0, UINT16_MAX, UINT16_MAX} 152 | #define DRV_TIMER3_INFO_CONFIG \ 153 | {0, UINT16_MAX, UINT16_MAX} 154 | #define DRV_TIMER4_INFO_CONFIG \ 155 | {0, UINT16_MAX, UINT16_MAX} 156 | #define DRV_TIMER5_INFO_CONFIG \ 157 | {0, UINT16_MAX, UINT16_MAX} 158 | #define DRV_TIMER6_INFO_CONFIG \ 159 | {0, UINT16_MAX, UINT16_MAX} 160 | #define DRV_TIMER7_INFO_CONFIG \ 161 | {0, UINT16_MAX, UINT16_MAX} 162 | #define DRV_TIMER8_INFO_CONFIG \ 163 | {0, UINT16_MAX, UINT16_MAX} 164 | #define DRV_TIMER9_INFO_CONFIG \ 165 | {0, UINT16_MAX, UINT16_MAX} 166 | #define DRV_TIMER10_INFO_CONFIG \ 167 | {0, UINT16_MAX, UINT16_MAX} 168 | #define DRV_TIMER11_INFO_CONFIG \ 169 | {0, UINT16_MAX, UINT16_MAX} 170 | #define DRV_TIMER12_INFO_CONFIG \ 171 | {0, UINT16_MAX, UINT16_MAX} 172 | #define DRV_TIMER13_INFO_CONFIG \ 173 | {0, UINT16_MAX, UINT16_MAX} 174 | #define DRV_TIMER14_INFO_CONFIG \ 175 | {0, UINT16_MAX, UINT16_MAX} 176 | 177 | #ifdef __cplusplus 178 | } 179 | #endif /* __cplusplus */ 180 | 181 | #endif /* _MR_BOARD_H_ */ 182 | -------------------------------------------------------------------------------- /bsp/st/stm32f407/driver/Kconfig: -------------------------------------------------------------------------------- 1 | menu "Driver configure" 2 | 3 | menu "ADC" 4 | config MR_USING_ADC1 5 | bool "Enable ADC1 driver" 6 | default n 7 | 8 | config MR_USING_ADC2 9 | bool "Enable ADC2 driver" 10 | default n 11 | 12 | config MR_USING_ADC3 13 | bool "Enable ADC3 driver" 14 | default n 15 | endmenu 16 | 17 | menu "DAC" 18 | config MR_USING_DAC1 19 | bool "Enable DAC1 driver" 20 | default n 21 | endmenu 22 | 23 | menu "PWM" 24 | config MR_USING_PWM1 25 | bool "Enable PWM1 driver" 26 | default n 27 | 28 | config MR_USING_PWM2 29 | bool "Enable PWM2 driver" 30 | default n 31 | 32 | config MR_USING_PWM3 33 | bool "Enable PWM3 driver" 34 | default n 35 | 36 | config MR_USING_PWM4 37 | bool "Enable PWM4 driver" 38 | default n 39 | 40 | config MR_USING_PWM5 41 | bool "Enable PWM5 driver" 42 | default n 43 | 44 | config MR_USING_PWM6 45 | bool "Enable PWM6 driver" 46 | default n 47 | 48 | config MR_USING_PWM7 49 | bool "Enable PWM7 driver" 50 | default n 51 | 52 | config MR_USING_PWM8 53 | bool "Enable PWM8 driver" 54 | default n 55 | 56 | config MR_USING_PWM9 57 | bool "Enable PWM9 driver" 58 | default n 59 | 60 | config MR_USING_PWM10 61 | bool "Enable PWM10 driver" 62 | default n 63 | 64 | config MR_USING_PWM11 65 | bool "Enable PWM11 driver" 66 | default n 67 | 68 | config MR_USING_PWM12 69 | bool "Enable PWM12 driver" 70 | default n 71 | 72 | config MR_USING_PWM13 73 | bool "Enable PWM13 driver" 74 | default n 75 | 76 | config MR_USING_PWM14 77 | bool "Enable PWM14 driver" 78 | default n 79 | endmenu 80 | 81 | menu "UART" 82 | config MR_USING_UART1 83 | bool "Enable UART1 driver" 84 | default n 85 | 86 | config MR_USING_UART2 87 | bool "Enable UART2 driver" 88 | default n 89 | 90 | config MR_USING_UART3 91 | bool "Enable UART3 driver" 92 | default n 93 | 94 | config MR_USING_UART4 95 | bool "Enable UART4 driver" 96 | default n 97 | 98 | config MR_USING_UART5 99 | bool "Enable UART5 driver" 100 | default n 101 | 102 | config MR_USING_UART6 103 | bool "Enable UART6 driver" 104 | default n 105 | endmenu 106 | 107 | menu "SPI" 108 | config MR_USING_SPI1 109 | bool "Enable SPI1 driver" 110 | default n 111 | 112 | config MR_USING_SPI2 113 | bool "Enable SPI2 driver" 114 | default n 115 | 116 | config MR_USING_SPI3 117 | bool "Enable SPI3 driver" 118 | default n 119 | endmenu 120 | 121 | menu "Timer" 122 | config MR_USING_TIMER1 123 | bool "Enable Timer1 driver" 124 | default n 125 | 126 | config MR_USING_TIMER2 127 | bool "Enable Timer2 driver" 128 | default n 129 | 130 | config MR_USING_TIMER3 131 | bool "Enable Timer3 driver" 132 | default n 133 | 134 | config MR_USING_TIMER4 135 | bool "Enable Timer4 driver" 136 | default n 137 | 138 | config MR_USING_TIMER5 139 | bool "Enable Timer5 driver" 140 | default n 141 | 142 | config MR_USING_TIMER6 143 | bool "Enable Timer6 driver" 144 | default n 145 | 146 | config MR_USING_TIMER7 147 | bool "Enable Timer7 driver" 148 | default n 149 | 150 | config MR_USING_TIMER8 151 | bool "Enable Timer8 driver" 152 | default n 153 | 154 | config MR_USING_TIMER9 155 | bool "Enable Timer9 driver" 156 | default n 157 | 158 | config MR_USING_TIMER10 159 | bool "Enable Timer10 driver" 160 | default n 161 | 162 | config MR_USING_TIMER11 163 | bool "Enable Timer11 driver" 164 | default n 165 | 166 | config MR_USING_TIMER12 167 | bool "Enable Timer12 driver" 168 | default n 169 | 170 | config MR_USING_TIMER13 171 | bool "Enable Timer13 driver" 172 | default n 173 | 174 | config MR_USING_TIMER14 175 | bool "Enable Timer14 driver" 176 | default n 177 | endmenu 178 | 179 | endmenu 180 | -------------------------------------------------------------------------------- /bsp/st/stm32f407/driver/mr_board.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @copyright (c) 2023-2024, MR Development Team 3 | * 4 | * @license SPDX-License-Identifier: Apache-2.0 5 | * 6 | * @date 2023-12-12 MacRsh First version 7 | */ 8 | 9 | #ifndef _MR_BOARD_H_ 10 | #define _MR_BOARD_H_ 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif /* __cplusplus */ 15 | 16 | #include "stm32f4xx.h" 17 | 18 | #define DRV_ADC_CHANNEL_CONFIG \ 19 | { \ 20 | {ADC_CHANNEL_0}, \ 21 | {ADC_CHANNEL_1}, \ 22 | {ADC_CHANNEL_2}, \ 23 | {ADC_CHANNEL_3}, \ 24 | {ADC_CHANNEL_4}, \ 25 | {ADC_CHANNEL_5}, \ 26 | {ADC_CHANNEL_6}, \ 27 | {ADC_CHANNEL_7}, \ 28 | {ADC_CHANNEL_8}, \ 29 | {ADC_CHANNEL_9}, \ 30 | {ADC_CHANNEL_10}, \ 31 | {ADC_CHANNEL_11}, \ 32 | {ADC_CHANNEL_12}, \ 33 | {ADC_CHANNEL_13}, \ 34 | {ADC_CHANNEL_14}, \ 35 | {ADC_CHANNEL_15}, \ 36 | {ADC_CHANNEL_16}, \ 37 | {ADC_CHANNEL_17}, \ 38 | } 39 | 40 | #define DRV_DAC_CHANNEL_CONFIG \ 41 | { \ 42 | {NULL}, \ 43 | {DAC_CHANNEL_1}, \ 44 | {DAC_CHANNEL_2}, \ 45 | } 46 | 47 | #define DRV_PIN_IRQ_MAP_CONFIG \ 48 | { \ 49 | EXTI0_IRQn, \ 50 | EXTI1_IRQn, \ 51 | EXTI2_IRQn, \ 52 | EXTI3_IRQn, \ 53 | EXTI4_IRQn, \ 54 | EXTI9_5_IRQn, \ 55 | EXTI9_5_IRQn, \ 56 | EXTI9_5_IRQn, \ 57 | EXTI9_5_IRQn, \ 58 | EXTI9_5_IRQn, \ 59 | EXTI15_10_IRQn, \ 60 | EXTI15_10_IRQn, \ 61 | EXTI15_10_IRQn, \ 62 | EXTI15_10_IRQn, \ 63 | EXTI15_10_IRQn, \ 64 | EXTI15_10_IRQn, \ 65 | } 66 | 67 | #ifdef GPIOD 68 | #define DRV_PIN_PORT_D GPIOD, 69 | #else 70 | #define DRV_PIN_PORT_D 71 | #endif /* GPIOD */ 72 | #ifdef GPIOE 73 | #define DRV_PIN_PORT_E GPIOE, 74 | #else 75 | #define DRV_PIN_PORT_E 76 | #endif /* GPIOE */ 77 | #ifdef GPIOF 78 | #define DRV_PIN_PORT_F GPIOF, 79 | #else 80 | #define DRV_PIN_PORT_F 81 | #endif /* GPIOF */ 82 | #ifdef GPIOG 83 | #define DRV_PIN_PORT_G GPIOG, 84 | #else 85 | #define DRV_PIN_PORT_G 86 | #endif /* GPIOG */ 87 | 88 | #define DRV_PIN_PORT_CONFIG \ 89 | { \ 90 | GPIOA, \ 91 | GPIOB, \ 92 | GPIOC, \ 93 | DRV_PIN_PORT_D \ 94 | DRV_PIN_PORT_E \ 95 | DRV_PIN_PORT_F \ 96 | DRV_PIN_PORT_G \ 97 | } 98 | 99 | #define DRV_PIN_CONFIG \ 100 | { \ 101 | GPIO_PIN_0, \ 102 | GPIO_PIN_1, \ 103 | GPIO_PIN_2, \ 104 | GPIO_PIN_3, \ 105 | GPIO_PIN_4, \ 106 | GPIO_PIN_5, \ 107 | GPIO_PIN_6, \ 108 | GPIO_PIN_7, \ 109 | GPIO_PIN_8, \ 110 | GPIO_PIN_9, \ 111 | GPIO_PIN_10, \ 112 | GPIO_PIN_11, \ 113 | GPIO_PIN_12, \ 114 | GPIO_PIN_13, \ 115 | GPIO_PIN_14, \ 116 | GPIO_PIN_15, \ 117 | } 118 | 119 | #define DRV_PWM1_INFO_CONFIG \ 120 | {0, UINT16_MAX, UINT16_MAX} 121 | #define DRV_PWM2_INFO_CONFIG \ 122 | {0, UINT16_MAX, UINT32_MAX} 123 | #define DRV_PWM3_INFO_CONFIG \ 124 | {0, UINT16_MAX, UINT16_MAX} 125 | #define DRV_PWM4_INFO_CONFIG \ 126 | {0, UINT16_MAX, UINT16_MAX} 127 | #define DRV_PWM5_INFO_CONFIG \ 128 | {0, UINT16_MAX, UINT32_MAX} 129 | #define DRV_PWM6_INFO_CONFIG \ 130 | {0, UINT16_MAX, UINT16_MAX} 131 | #define DRV_PWM7_INFO_CONFIG \ 132 | {0, UINT16_MAX, UINT16_MAX} 133 | #define DRV_PWM8_INFO_CONFIG \ 134 | {0, UINT16_MAX, UINT16_MAX} 135 | #define DRV_PWM9_INFO_CONFIG \ 136 | {0, UINT16_MAX, UINT16_MAX} 137 | #define DRV_PWM10_INFO_CONFIG \ 138 | {0, UINT16_MAX, UINT16_MAX} 139 | #define DRV_PWM11_INFO_CONFIG \ 140 | {0, UINT16_MAX, UINT16_MAX} 141 | #define DRV_PWM12_INFO_CONFIG \ 142 | {0, UINT16_MAX, UINT16_MAX} 143 | #define DRV_PWM13_INFO_CONFIG \ 144 | {0, UINT16_MAX, UINT16_MAX} 145 | #define DRV_PWM14_INFO_CONFIG \ 146 | {0, UINT16_MAX, UINT16_MAX} 147 | 148 | #define DRV_TIMER1_INFO_CONFIG \ 149 | {0, UINT16_MAX, UINT32_MAX} 150 | #define DRV_TIMER2_INFO_CONFIG \ 151 | {0, UINT16_MAX, UINT16_MAX} 152 | #define DRV_TIMER3_INFO_CONFIG \ 153 | {0, UINT16_MAX, UINT16_MAX} 154 | #define DRV_TIMER4_INFO_CONFIG \ 155 | {0, UINT16_MAX, UINT16_MAX} 156 | #define DRV_TIMER5_INFO_CONFIG \ 157 | {0, UINT16_MAX, UINT32_MAX} 158 | #define DRV_TIMER6_INFO_CONFIG \ 159 | {0, UINT16_MAX, UINT16_MAX} 160 | #define DRV_TIMER7_INFO_CONFIG \ 161 | {0, UINT16_MAX, UINT16_MAX} 162 | #define DRV_TIMER8_INFO_CONFIG \ 163 | {0, UINT16_MAX, UINT16_MAX} 164 | #define DRV_TIMER9_INFO_CONFIG \ 165 | {0, UINT16_MAX, UINT16_MAX} 166 | #define DRV_TIMER10_INFO_CONFIG \ 167 | {0, UINT16_MAX, UINT16_MAX} 168 | #define DRV_TIMER11_INFO_CONFIG \ 169 | {0, UINT16_MAX, UINT16_MAX} 170 | #define DRV_TIMER12_INFO_CONFIG \ 171 | {0, UINT16_MAX, UINT16_MAX} 172 | #define DRV_TIMER13_INFO_CONFIG \ 173 | {0, UINT16_MAX, UINT16_MAX} 174 | #define DRV_TIMER14_INFO_CONFIG \ 175 | {0, UINT16_MAX, UINT16_MAX} 176 | 177 | #ifdef __cplusplus 178 | } 179 | #endif /* __cplusplus */ 180 | 181 | #endif /* _MR_BOARD_H_ */ 182 | -------------------------------------------------------------------------------- /bsp/st/stm32f411/driver/Kconfig: -------------------------------------------------------------------------------- 1 | menu "Driver configure" 2 | 3 | menu "ADC" 4 | config MR_USING_ADC1 5 | bool "Enable ADC1 driver" 6 | default n 7 | endmenu 8 | 9 | menu "PWM" 10 | config MR_USING_PWM1 11 | bool "Enable PWM1 driver" 12 | default n 13 | 14 | config MR_USING_PWM2 15 | bool "Enable PWM2 driver" 16 | default n 17 | 18 | config MR_USING_PWM3 19 | bool "Enable PWM3 driver" 20 | default n 21 | 22 | config MR_USING_PWM4 23 | bool "Enable PWM4 driver" 24 | default n 25 | 26 | config MR_USING_PWM5 27 | bool "Enable PWM5 driver" 28 | default n 29 | 30 | config MR_USING_PWM9 31 | bool "Enable PWM9 driver" 32 | default n 33 | 34 | config MR_USING_PWM10 35 | bool "Enable PWM10 driver" 36 | default n 37 | 38 | config MR_USING_PWM11 39 | bool "Enable PWM11 driver" 40 | default n 41 | endmenu 42 | 43 | menu "UART" 44 | config MR_USING_UART1 45 | bool "Enable UART1 driver" 46 | default n 47 | 48 | config MR_USING_UART2 49 | bool "Enable UART2 driver" 50 | default n 51 | 52 | config MR_USING_UART6 53 | bool "Enable UART6 driver" 54 | default n 55 | endmenu 56 | 57 | menu "SPI" 58 | config MR_USING_SPI1 59 | bool "Enable SPI1 driver" 60 | default n 61 | 62 | config MR_USING_SPI2 63 | bool "Enable SPI2 driver" 64 | default n 65 | 66 | config MR_USING_SPI3 67 | bool "Enable SPI3 driver" 68 | default n 69 | 70 | config MR_USING_SPI4 71 | bool "Enable SPI3 driver" 72 | default n 73 | 74 | config MR_USING_SPI5 75 | bool "Enable SPI5 driver" 76 | default n 77 | endmenu 78 | 79 | menu "Timer" 80 | config MR_USING_TIMER1 81 | bool "Enable Timer1 driver" 82 | default n 83 | 84 | config MR_USING_TIMER2 85 | bool "Enable Timer2 driver" 86 | default n 87 | 88 | config MR_USING_TIMER3 89 | bool "Enable Timer3 driver" 90 | default n 91 | 92 | config MR_USING_TIMER4 93 | bool "Enable Timer4 driver" 94 | default n 95 | 96 | config MR_USING_TIMER5 97 | bool "Enable Timer5 driver" 98 | default n 99 | 100 | config MR_USING_TIMER9 101 | bool "Enable Timer9 driver" 102 | default n 103 | 104 | config MR_USING_TIMER10 105 | bool "Enable Timer10 driver" 106 | default n 107 | 108 | config MR_USING_TIMER11 109 | bool "Enable Timer11 driver" 110 | default n 111 | endmenu 112 | 113 | endmenu 114 | -------------------------------------------------------------------------------- /bsp/st/stm32f411/driver/mr_board.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @copyright (c) 2023-2024, MR Development Team 3 | * 4 | * @license SPDX-License-Identifier: Apache-2.0 5 | * 6 | * @date 2023-12-12 MacRsh First version 7 | */ 8 | 9 | #ifndef _MR_BOARD_H_ 10 | #define _MR_BOARD_H_ 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif /* __cplusplus */ 15 | 16 | #include "stm32f4xx.h" 17 | 18 | #define DRV_ADC_CHANNEL_CONFIG \ 19 | { \ 20 | {ADC_CHANNEL_0}, \ 21 | {ADC_CHANNEL_1}, \ 22 | {ADC_CHANNEL_2}, \ 23 | {ADC_CHANNEL_3}, \ 24 | {ADC_CHANNEL_4}, \ 25 | {ADC_CHANNEL_5}, \ 26 | {ADC_CHANNEL_6}, \ 27 | {ADC_CHANNEL_7}, \ 28 | {ADC_CHANNEL_8}, \ 29 | {ADC_CHANNEL_9}, \ 30 | {ADC_CHANNEL_10}, \ 31 | {ADC_CHANNEL_11}, \ 32 | {ADC_CHANNEL_12}, \ 33 | {ADC_CHANNEL_13}, \ 34 | {ADC_CHANNEL_14}, \ 35 | {ADC_CHANNEL_15}, \ 36 | {ADC_CHANNEL_16}, \ 37 | {ADC_CHANNEL_17}, \ 38 | } 39 | 40 | #define DRV_PIN_IRQ_MAP_CONFIG \ 41 | { \ 42 | EXTI0_IRQn, \ 43 | EXTI1_IRQn, \ 44 | EXTI2_IRQn, \ 45 | EXTI3_IRQn, \ 46 | EXTI4_IRQn, \ 47 | EXTI9_5_IRQn, \ 48 | EXTI9_5_IRQn, \ 49 | EXTI9_5_IRQn, \ 50 | EXTI9_5_IRQn, \ 51 | EXTI9_5_IRQn, \ 52 | EXTI15_10_IRQn, \ 53 | EXTI15_10_IRQn, \ 54 | EXTI15_10_IRQn, \ 55 | EXTI15_10_IRQn, \ 56 | EXTI15_10_IRQn, \ 57 | EXTI15_10_IRQn, \ 58 | } 59 | 60 | #ifdef GPIOD 61 | #define DRV_PIN_PORT_D GPIOD, 62 | #else 63 | #define DRV_PIN_PORT_D 64 | #endif /* GPIOD */ 65 | #ifdef GPIOE 66 | #define DRV_PIN_PORT_E GPIOE, 67 | #else 68 | #define DRV_PIN_PORT_E 69 | #endif /* GPIOE */ 70 | #ifdef GPIOF 71 | #define DRV_PIN_PORT_F GPIOF, 72 | #else 73 | #define DRV_PIN_PORT_F 74 | #endif /* GPIOF */ 75 | #ifdef GPIOG 76 | #define DRV_PIN_PORT_G GPIOG, 77 | #else 78 | #define DRV_PIN_PORT_G 79 | #endif /* GPIOG */ 80 | 81 | #define DRV_PIN_PORT_CONFIG \ 82 | { \ 83 | GPIOA, \ 84 | GPIOB, \ 85 | GPIOC, \ 86 | DRV_PIN_PORT_D \ 87 | DRV_PIN_PORT_E \ 88 | DRV_PIN_PORT_F \ 89 | DRV_PIN_PORT_G \ 90 | } 91 | 92 | #define DRV_PIN_CONFIG \ 93 | { \ 94 | GPIO_PIN_0, \ 95 | GPIO_PIN_1, \ 96 | GPIO_PIN_2, \ 97 | GPIO_PIN_3, \ 98 | GPIO_PIN_4, \ 99 | GPIO_PIN_5, \ 100 | GPIO_PIN_6, \ 101 | GPIO_PIN_7, \ 102 | GPIO_PIN_8, \ 103 | GPIO_PIN_9, \ 104 | GPIO_PIN_10, \ 105 | GPIO_PIN_11, \ 106 | GPIO_PIN_12, \ 107 | GPIO_PIN_13, \ 108 | GPIO_PIN_14, \ 109 | GPIO_PIN_15, \ 110 | } 111 | 112 | #define DRV_PWM1_INFO_CONFIG \ 113 | {0, UINT16_MAX, UINT16_MAX} 114 | #define DRV_PWM2_INFO_CONFIG \ 115 | {0, UINT16_MAX, UINT32_MAX} 116 | #define DRV_PWM3_INFO_CONFIG \ 117 | {0, UINT16_MAX, UINT16_MAX} 118 | #define DRV_PWM4_INFO_CONFIG \ 119 | {0, UINT16_MAX, UINT16_MAX} 120 | #define DRV_PWM5_INFO_CONFIG \ 121 | {0, UINT16_MAX, UINT32_MAX} 122 | #define DRV_PWM9_INFO_CONFIG \ 123 | {0, UINT16_MAX, UINT16_MAX} 124 | #define DRV_PWM10_INFO_CONFIG \ 125 | {0, UINT16_MAX, UINT16_MAX} 126 | #define DRV_PWM11_INFO_CONFIG \ 127 | {0, UINT16_MAX, UINT16_MAX} 128 | 129 | #define DRV_TIMER1_INFO_CONFIG \ 130 | {0, UINT16_MAX, UINT16_MAX} 131 | #define DRV_TIMER2_INFO_CONFIG \ 132 | {0, UINT16_MAX, UINT32_MAX} 133 | #define DRV_TIMER3_INFO_CONFIG \ 134 | {0, UINT16_MAX, UINT16_MAX} 135 | #define DRV_TIMER4_INFO_CONFIG \ 136 | {0, UINT16_MAX, UINT16_MAX} 137 | #define DRV_TIMER5_INFO_CONFIG \ 138 | {0, UINT16_MAX, UINT32_MAX} 139 | #define DRV_TIMER9_INFO_CONFIG \ 140 | {0, UINT16_MAX, UINT16_MAX} 141 | #define DRV_TIMER10_INFO_CONFIG \ 142 | {0, UINT16_MAX, UINT16_MAX} 143 | #define DRV_TIMER11_INFO_CONFIG \ 144 | {0, UINT16_MAX, UINT16_MAX} 145 | 146 | #ifdef __cplusplus 147 | } 148 | #endif /* __cplusplus */ 149 | 150 | #endif /* _MR_BOARD_H_ */ 151 | -------------------------------------------------------------------------------- /bsp/wch/README.md: -------------------------------------------------------------------------------- 1 | # WCH配置教程 2 | 3 | [English](README_EN.md) 4 | 5 | ## 将项目导入工程(2.添加驱动) 6 | 7 | 复制`bsp/wch/driver`和`ch32xxx/driver`文件至`driver`。 8 | 9 | ## 移植驱动 10 | 11 | 参考上一步中`ch32xxx/driver`路径下`Kconfig`和`mr_board.h`,修改参数,完成移植与裁剪。 12 | 13 | ## 继续按仓库目录下`README`,添加 mr-library 14 | -------------------------------------------------------------------------------- /bsp/wch/README_EN.md: -------------------------------------------------------------------------------- 1 | # WCH configuration tutorial 2 | 3 | [中文](README.md) 4 | 5 | ## Import project into project (2. Add driver) 6 | 7 | Copy `bsp/wch/driver` and `ch32xxx/driver` files to `driver`. 8 | 9 | ## Port driver 10 | 11 | Refer to the `ch32xxx/driver` path `Kconfig` and `mr_board.h` in the previous step to modify parameters and complete 12 | the migration and tailoring. 13 | 14 | ## Continue to add mr-library by pressing `README` in the repository directory 15 | -------------------------------------------------------------------------------- /bsp/wch/ch32v003/driver/Kconfig: -------------------------------------------------------------------------------- 1 | menu "Driver configure" 2 | 3 | config MR_USING_CH32V00X 4 | bool "Enable CH32V00X driver" 5 | default y 6 | 7 | menu "ADC" 8 | config MR_USING_ADC1 9 | bool "Enable ADC1 driver" 10 | default n 11 | endmenu 12 | 13 | menu "I2C" 14 | config MR_USING_I2C1 15 | bool "Enable I2C1 driver" 16 | default n 17 | 18 | menu "I2C1 driver configure" 19 | depends on MR_USING_I2C1 20 | 21 | config MR_CFG_I2C1_GROUP 22 | int "I2C1 Group" 23 | default 1 24 | range 1 3 25 | endmenu 26 | endmenu 27 | 28 | menu "UART" 29 | config MR_USING_UART1 30 | bool "Enable UART1 driver" 31 | default n 32 | 33 | menu "UART1 driver configure" 34 | depends on MR_USING_UART1 35 | 36 | config MR_CFG_UART1_GROUP 37 | int "UART1 Group" 38 | default 1 39 | range 1 4 40 | endmenu 41 | endmenu 42 | 43 | menu "SPI" 44 | config MR_USING_SPI1 45 | bool "Enable SPI1 driver" 46 | default n 47 | 48 | menu "SPI1 driver configure" 49 | depends on MR_USING_SPI1 50 | 51 | config MR_CFG_SPI1_GROUP 52 | int "SPI1 Group" 53 | default 1 54 | range 1 2 55 | endmenu 56 | endmenu 57 | 58 | menu "Timer" 59 | config MR_USING_TIMER1 60 | bool "Enable Timer1 driver" 61 | default n 62 | 63 | config MR_USING_TIMER2 64 | bool "Enable Timer2 driver" 65 | default n 66 | endmenu 67 | 68 | endmenu -------------------------------------------------------------------------------- /bsp/wch/ch32v003/driver/mr_board.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @copyright (c) 2023-2024, MR Development Team 3 | * 4 | * @license SPDX-License-Identifier: Apache-2.0 5 | * 6 | * @date 2023-11-10 MacRsh First version 7 | */ 8 | 9 | #ifndef _MR_BOARD_H_ 10 | #define _MR_BOARD_H_ 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif /* __cplusplus */ 15 | 16 | #include "ch32v00x.h" 17 | 18 | #define MR_USING_CH32V00X 19 | 20 | #define DRV_ADC_CHANNEL_CONFIG \ 21 | { \ 22 | {ADC_Channel_0, RCC_APB2Periph_GPIOA, GPIOA, GPIO_Pin_2}, \ 23 | {ADC_Channel_1, RCC_APB2Periph_GPIOA, GPIOA, GPIO_Pin_1}, \ 24 | {ADC_Channel_2, RCC_APB2Periph_GPIOC, GPIOC, GPIO_Pin_4}, \ 25 | {ADC_Channel_3, RCC_APB2Periph_GPIOD, GPIOD, GPIO_Pin_2}, \ 26 | {ADC_Channel_4, RCC_APB2Periph_GPIOD, GPIOD, GPIO_Pin_3}, \ 27 | {ADC_Channel_5, RCC_APB2Periph_GPIOD, GPIOD, GPIO_Pin_5}, \ 28 | {ADC_Channel_6, RCC_APB2Periph_GPIOD, GPIOD, GPIO_Pin_6}, \ 29 | {ADC_Channel_7, RCC_APB2Periph_GPIOD, GPIOD, GPIO_Pin_4}, \ 30 | {ADC_Channel_8, 0, NULL, 0}, \ 31 | {ADC_Channel_9, 0, NULL, 0}, \ 32 | } 33 | 34 | #if (MR_CFG_I2C1_GROUP == 1) 35 | #define DRV_I2C1_CONFIG \ 36 | {I2C1, RCC_APB1Periph_I2C1, RCC_APB2Periph_GPIOC, GPIOC, GPIO_Pin_2, GPIOC, GPIO_Pin_1, I2C1_EV_IRQn, 0} 37 | #elif (MR_CFG_I2C1_GROUP == 2) 38 | #define DRV_I2C1_CONFIG \ 39 | {I2C1, RCC_APB1Periph_I2C1, RCC_APB2Periph_GPIOD, GPIOD, GPIO_Pin_1, GPIOD, GPIO_Pin_0, I2C1_EV_IRQn, GPIO_PartialRemap_I2C1} 40 | #elif (MR_CFG_I2C1_GROUP == 3) 41 | #define DRV_I2C1_CONFIG \ 42 | {I2C1, RCC_APB1Periph_I2C1, RCC_APB2Periph_GPIOC, GPIOC, GPIO_Pin_5, GPIOC, GPIO_Pin_6, I2C1_EV_IRQn, GPIO_FullRemap_I2C1} 43 | #endif /* MR_CFG_I2C1_GROUP */ 44 | 45 | #define DRV_PIN_IRQ_MAP_CONFIG \ 46 | { \ 47 | EXTI7_0_IRQn, \ 48 | EXTI7_0_IRQn, \ 49 | EXTI7_0_IRQn, \ 50 | EXTI7_0_IRQn, \ 51 | EXTI7_0_IRQn, \ 52 | EXTI7_0_IRQn, \ 53 | EXTI7_0_IRQn, \ 54 | EXTI7_0_IRQn, \ 55 | } 56 | 57 | #define DRV_PIN_PORT_CONFIG \ 58 | { \ 59 | GPIOA, \ 60 | MR_NULL, \ 61 | GPIOC, \ 62 | GPIOD, \ 63 | } 64 | 65 | #define DRV_PIN_CONFIG \ 66 | { \ 67 | GPIO_Pin_0, \ 68 | GPIO_Pin_1, \ 69 | GPIO_Pin_2, \ 70 | GPIO_Pin_3, \ 71 | GPIO_Pin_4, \ 72 | GPIO_Pin_5, \ 73 | GPIO_Pin_6, \ 74 | GPIO_Pin_7, \ 75 | } 76 | 77 | #if (MR_CFG_UART1_GROUP == 1) 78 | #define DRV_UART1_CONFIG \ 79 | {USART1, RCC_APB2Periph_USART1, RCC_APB2Periph_GPIOD, GPIOD, GPIO_Pin_6, GPIOD, GPIO_Pin_5, USART1_IRQn, 0} 80 | #elif (MR_CFG_UART1_GROUP == 2) 81 | #define DRV_UART1_CONFIG \ 82 | {USART1, RCC_APB2Periph_USART1, RCC_APB2Periph_GPIOD, GPIOD, GPIO_Pin_1, GPIOD, GPIO_Pin_0, USART1_IRQn, GPIO_PartialRemap1_USART1) 83 | #elif (MR_CFG_UART1_GROUP == 3) 84 | #define DRV_UART1_CONFIG \ 85 | {USART1, RCC_APB2Periph_USART1, RCC_APB2Periph_GPIOD, GPIOD, GPIO_Pin_5, GPIOD, GPIO_Pin_6, USART1_IRQn, GPIO_PartialRemap2_USART1) 86 | #elif (MR_CFG_UART1_GROUP == 4) 87 | #define DRV_UART1_CONFIG \ 88 | {USART1, RCC_APB2Periph_USART1, RCC_APB2Periph_GPIOC, GPIOC, GPIO_Pin_1, GPIOC, GPIO_Pin_0, USART1_IRQn, GPIO_FullRemap_USART1) 89 | #endif /* MR_CFG_UART1_GROUP */ 90 | 91 | #if (MR_CFG_SPI1_GROUP == 1) 92 | #define DRV_SPI1_CONFIG \ 93 | {SPI1, RCC_APB2Periph_SPI1, RCC_APB2Periph_GPIOC, GPIOC, GPIO_Pin_1, GPIOC, GPIO_Pin_5, GPIOC, GPIO_Pin_7, GPIOC, GPIO_Pin_6, SPI1_IRQn, 0} 94 | #elif (MR_CFG_SPI1_GROUP == 2) 95 | #define DRV_SPI1_CONFIG \ 96 | {SPI1, RCC_APB2Periph_SPI1, RCC_APB2Periph_GPIOC, GPIOC, GPIO_Pin_0, GPIOC, GPIO_Pin_5, GPIOC, GPIO_Pin_7, GPIOC, GPIO_Pin_6, SPI1_IRQn, GPIO_Remap_SPI1} 97 | #endif /* MR_CFG_SPI1_GROUP */ 98 | 99 | #define DRV_TIMER1_CONFIG \ 100 | {TIM1, RCC_APB2Periph_TIM1, TIM1_UP_IRQn} 101 | #define DRV_TIMER2_CONFIG \ 102 | {TIM2, RCC_APB1Periph_TIM2, TIM2_IRQn} 103 | 104 | #define DRV_TIMER1_INFO_CONFIG \ 105 | {0, UINT16_MAX, UINT16_MAX} 106 | #define DRV_TIMER2_INFO_CONFIG \ 107 | {0, UINT16_MAX, UINT16_MAX} 108 | 109 | #ifdef __cplusplus 110 | } 111 | #endif /* __cplusplus */ 112 | 113 | #endif /* _MR_BOARD_H_ */ 114 | -------------------------------------------------------------------------------- /bsp/wch/ch32v203/driver/Kconfig: -------------------------------------------------------------------------------- 1 | menu "Driver configure" 2 | 3 | menu "ADC" 4 | config MR_USING_ADC1 5 | bool "Enable ADC1 driver" 6 | default n 7 | 8 | config MR_USING_ADC2 9 | bool "Enable ADC2 driver" 10 | default n 11 | endmenu 12 | 13 | menu "I2C" 14 | config MR_USING_I2C1 15 | bool "Enable I2C1 driver" 16 | default n 17 | 18 | menu "I2C1 driver configure" 19 | depends on MR_USING_I2C1 20 | 21 | config MR_CFG_I2C1_GROUP 22 | int "I2C1 Group" 23 | default 1 24 | range 1 2 25 | endmenu 26 | 27 | config MR_USING_I2C2 28 | bool "Enable I2C2 driver" 29 | default n 30 | 31 | menu "I2C2 driver configure" 32 | depends on MR_USING_I2C2 33 | 34 | config MR_CFG_I2C2_GROUP 35 | int "I2C2 Group" 36 | default 1 37 | range 1 1 38 | endmenu 39 | endmenu 40 | 41 | menu "PWM" 42 | config MR_USING_PWM1 43 | bool "Enable PWM1 driver" 44 | default n 45 | 46 | menu "PWM1 driver configure" 47 | depends on MR_USING_PWM1 48 | 49 | config MR_CFG_PWM1_GROUP 50 | int "PWM1 Group" 51 | default 1 52 | range 1 1 53 | endmenu 54 | 55 | config MR_USING_PWM2 56 | bool "Enable PWM2 driver" 57 | default n 58 | 59 | menu "PWM2 driver configure" 60 | depends on MR_USING_PWM2 61 | 62 | config MR_CFG_PWM2_GROUP 63 | int "PWM2 Group" 64 | default 1 65 | range 1 4 66 | endmenu 67 | 68 | config MR_USING_PWM3 69 | bool "Enable PWM3 driver" 70 | default n 71 | 72 | menu "PWM3 driver configure" 73 | depends on MR_USING_PWM3 74 | 75 | config MR_CFG_PWM3_GROUP 76 | int "PWM3 Group" 77 | default 1 78 | range 1 3 79 | endmenu 80 | 81 | config MR_USING_PWM4 82 | bool "Enable PWM4 driver" 83 | default n 84 | 85 | menu "PWM4 driver configure" 86 | depends on MR_USING_PWM4 87 | 88 | config MR_CFG_PWM4_GROUP 89 | int "PWM4 Group" 90 | default 1 91 | range 1 1 92 | endmenu 93 | 94 | config MR_USING_PWM5 95 | bool "Enable PWM5 driver" 96 | default n 97 | 98 | menu "PWM5 driver configure" 99 | depends on MR_USING_PWM5 100 | 101 | config MR_CFG_PWM5_GROUP 102 | int "PWM5 Group" 103 | default 1 104 | range 1 1 105 | endmenu 106 | endmenu 107 | 108 | menu "UART" 109 | config MR_USING_UART1 110 | bool "Enable UART1 driver" 111 | default n 112 | 113 | menu "UART1 driver configure" 114 | depends on MR_USING_UART1 115 | 116 | config MR_CFG_UART1_GROUP 117 | int "UART1 Group" 118 | default 1 119 | range 1 2 120 | endmenu 121 | 122 | config MR_USING_UART2 123 | bool "Enable UART2 driver" 124 | default n 125 | 126 | menu "UART2 driver configure" 127 | depends on MR_USING_UART2 128 | 129 | config MR_CFG_UART2_GROUP 130 | int "UART2 Group" 131 | default 1 132 | range 1 1 133 | endmenu 134 | 135 | config MR_USING_UART3 136 | bool "Enable UART3 driver" 137 | default n 138 | 139 | menu "UART3 driver configure" 140 | depends on MR_USING_UART3 141 | 142 | config MR_CFG_UART3_GROUP 143 | int "UART3 Group" 144 | default 1 145 | range 1 2 146 | endmenu 147 | 148 | config MR_USING_UART4 149 | bool "Enable UART4 driver" 150 | default n 151 | 152 | menu "UART4 driver configure" 153 | depends on MR_USING_UART4 154 | 155 | config MR_CFG_UART4_GROUP 156 | int "UART4 Group" 157 | default 1 158 | range 1 2 159 | endmenu 160 | endmenu 161 | 162 | menu "SPI" 163 | config MR_USING_SPI1 164 | bool "Enable SPI1 driver" 165 | default n 166 | 167 | menu "SPI1 driver configure" 168 | depends on MR_USING_SPI1 169 | 170 | config MR_CFG_SPI1_GROUP 171 | int "SPI1 Group" 172 | default 1 173 | range 1 2 174 | endmenu 175 | 176 | config MR_USING_SPI2 177 | bool "Enable SPI2 driver" 178 | default n 179 | 180 | menu "SPI2 driver configure" 181 | depends on MR_USING_SPI2 182 | 183 | config MR_CFG_SPI2_GROUP 184 | int "SPI2 Group" 185 | default 1 186 | range 1 1 187 | endmenu 188 | endmenu 189 | 190 | menu "Timer" 191 | config MR_USING_TIMER1 192 | bool "Enable Timer1 driver" 193 | default n 194 | 195 | config MR_USING_TIMER2 196 | bool "Enable Timer2 driver" 197 | default n 198 | 199 | config MR_USING_TIMER3 200 | bool "Enable Timer3 driver" 201 | default n 202 | 203 | config MR_USING_TIMER4 204 | bool "Enable Timer4 driver" 205 | default n 206 | 207 | config MR_USING_TIMER5 208 | bool "Enable Timer5 driver" 209 | default n 210 | endmenu 211 | 212 | endmenu 213 | -------------------------------------------------------------------------------- /bsp/wch/driver/drv_adc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @copyright (c) 2023-2024, MR Development Team 3 | * 4 | * @license SPDX-License-Identifier: Apache-2.0 5 | * 6 | * @date 2023-11-11 MacRsh First version 7 | */ 8 | 9 | #include "drv_adc.h" 10 | 11 | #ifdef MR_USING_ADC 12 | 13 | #if !defined(MR_USING_ADC1) && !defined(MR_USING_ADC2) 14 | #warning "Please enable at least one ADC driver" 15 | #endif /* !defined(MR_USING_ADC1) && !defined(MR_USING_ADC2) */ 16 | 17 | enum drv_adc_index 18 | { 19 | #ifdef MR_USING_ADC1 20 | DRV_INDEX_ADC1, 21 | #endif /* MR_USING_ADC1 */ 22 | #ifdef MR_USING_ADC2 23 | DRV_INDEX_ADC2, 24 | #endif /* MR_USING_ADC2 */ 25 | DRV_INDEX_ADC_MAX 26 | }; 27 | 28 | static const char *adc_path[] = 29 | { 30 | #ifdef MR_USING_ADC1 31 | "adc1", 32 | #endif /* MR_USING_ADC1 */ 33 | #ifdef MR_USING_ADC2 34 | "adc2", 35 | #endif /* MR_USING_ADC2 */ 36 | }; 37 | 38 | static struct drv_adc_data adc_drv_data[] = 39 | { 40 | #ifdef MR_USING_ADC1 41 | {ADC1, RCC_APB2Periph_ADC1}, 42 | #endif /* MR_USING_ADC1 */ 43 | #ifdef MR_USING_ADC2 44 | {ADC2, RCC_APB2Periph_ADC2}, 45 | #endif /* MR_USING_ADC2 */ 46 | }; 47 | 48 | static struct drv_adc_channel_data adc_channel_drv_data[] = DRV_ADC_CHANNEL_CONFIG; 49 | 50 | static struct mr_adc adc_dev[MR_ARRAY_NUM(adc_drv_data)]; 51 | 52 | static struct drv_adc_channel_data *drv_adc_get_channel_data(int channel) 53 | { 54 | if (channel >= MR_ARRAY_NUM(adc_channel_drv_data)) 55 | { 56 | return NULL; 57 | } 58 | return &adc_channel_drv_data[channel]; 59 | } 60 | 61 | static int drv_adc_configure(struct mr_adc *adc, int state) 62 | { 63 | struct drv_adc_data *adc_data = (struct drv_adc_data *)adc->dev.drv->data; 64 | ADC_InitTypeDef ADC_InitStructure = {0}; 65 | 66 | /* Configure clock */ 67 | RCC_APB2PeriphClockCmd(adc_data->clock, state); 68 | #ifdef MR_USING_CH32V00X 69 | RCC_ADCCLKConfig(RCC_PCLK2_Div4); 70 | #else 71 | RCC_ADCCLKConfig(RCC_PCLK2_Div8); 72 | #endif /* MR_USING_CH32V00X */ 73 | 74 | /* Configure ADC */ 75 | ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; 76 | ADC_InitStructure.ADC_ScanConvMode = DISABLE; 77 | ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; 78 | ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; 79 | ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; 80 | ADC_InitStructure.ADC_NbrOfChannel = 1; 81 | ADC_Init(adc_data->instance, &ADC_InitStructure); 82 | ADC_Cmd(adc_data->instance, state); 83 | return MR_EOK; 84 | } 85 | 86 | static int drv_adc_channel_configure(struct mr_adc *adc, int channel, int state) 87 | { 88 | struct drv_adc_channel_data *adc_channel_data = drv_adc_get_channel_data(channel); 89 | GPIO_InitTypeDef GPIO_InitStructure = {0}; 90 | 91 | /* Check channel is valid */ 92 | if (adc_channel_data == NULL) 93 | { 94 | return MR_EINVAL; 95 | } 96 | 97 | /* Configure clock */ 98 | RCC_APB2PeriphClockCmd(adc_channel_data->gpio_clock, ENABLE); 99 | 100 | /* Configure pin */ 101 | if (adc_channel_data->port != MR_NULL) 102 | { 103 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; 104 | GPIO_InitStructure.GPIO_Pin = adc_channel_data->pin; 105 | GPIO_Init(adc_channel_data->port, &GPIO_InitStructure); 106 | } 107 | 108 | #ifndef MR_USING_CH32V00X 109 | /* Configure temp-sensor */ 110 | if ((adc_channel_data->channel == ADC_Channel_16) || (adc_channel_data->channel == ADC_Channel_17)) 111 | { 112 | ADC_TempSensorVrefintCmd(ENABLE); 113 | } 114 | #endif /* MR_USING_CH32V00X */ 115 | return MR_EOK; 116 | } 117 | 118 | static int drv_adc_read(struct mr_adc *adc, int channel, uint32_t *data) 119 | { 120 | struct drv_adc_data *adc_data = (struct drv_adc_data *)adc->dev.drv->data; 121 | struct drv_adc_channel_data *adc_channel_data = drv_adc_get_channel_data(channel); 122 | size_t i = 0; 123 | 124 | #ifdef MR_USING_ADC_CHANNEL_CHECK 125 | /* Check channel is valid */ 126 | if (adc_channel_data == NULL) 127 | { 128 | return MR_EINVAL; 129 | } 130 | #endif /* MR_USING_ADC_CHANNEL_CHECK */ 131 | 132 | /* Read data */ 133 | #ifdef MR_USING_CH32V00X 134 | ADC_RegularChannelConfig(adc_data->instance, adc_channel_data->channel, 1, ADC_SampleTime_15Cycles); 135 | #else 136 | ADC_RegularChannelConfig(adc_data->instance, adc_channel_data->channel, 1, ADC_SampleTime_13Cycles5); 137 | #endif /* MR_USING_CH32V00X */ 138 | ADC_SoftwareStartConvCmd(adc_data->instance, ENABLE); 139 | while (ADC_GetFlagStatus(adc_data->instance, ADC_FLAG_EOC) == RESET) 140 | { 141 | i++; 142 | if (i > UINT16_MAX) 143 | { 144 | return MR_ETIMEOUT; 145 | } 146 | } 147 | ADC_ClearFlag(adc_data->instance, ADC_FLAG_EOC); 148 | *data = ADC_GetConversionValue(adc_data->instance); 149 | return MR_EOK; 150 | } 151 | 152 | static struct mr_adc_ops adc_drv_ops = 153 | { 154 | drv_adc_configure, 155 | drv_adc_channel_configure, 156 | drv_adc_read 157 | }; 158 | 159 | static struct mr_drv adc_drv[] = 160 | { 161 | #ifdef MR_USING_ADC1 162 | { 163 | &adc_drv_ops, 164 | &adc_drv_data[DRV_INDEX_ADC1], 165 | }, 166 | #endif /* MR_USING_ADC1 */ 167 | #ifdef MR_USING_ADC2 168 | { 169 | &adc_drv_ops, 170 | &adc_drv_data[DRV_INDEX_ADC2], 171 | }, 172 | #endif /* MR_USING_ADC2 */ 173 | }; 174 | 175 | static void drv_adc_init(void) 176 | { 177 | for (size_t i = 0; i < MR_ARRAY_NUM(adc_dev); i++) 178 | { 179 | mr_adc_register(&adc_dev[i], adc_path[i], &adc_drv[i]); 180 | } 181 | } 182 | MR_INIT_DRV_EXPORT(drv_adc_init); 183 | 184 | #endif /* MR_USING_ADC */ 185 | -------------------------------------------------------------------------------- /bsp/wch/driver/drv_adc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @copyright (c) 2023-2024, MR Development Team 3 | * 4 | * @license SPDX-License-Identifier: Apache-2.0 5 | * 6 | * @date 2023-11-11 MacRsh First version 7 | */ 8 | 9 | #ifndef _DRV_ADC_H_ 10 | #define _DRV_ADC_H_ 11 | 12 | #include "include/device/mr_adc.h" 13 | #include "mr_board.h" 14 | 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif /* __cplusplus */ 18 | 19 | #ifdef MR_USING_ADC 20 | 21 | struct drv_adc_data 22 | { 23 | ADC_TypeDef *instance; 24 | uint32_t clock; 25 | }; 26 | 27 | struct drv_adc_channel_data 28 | { 29 | uint32_t channel; 30 | uint32_t gpio_clock; 31 | GPIO_TypeDef *port; 32 | uint32_t pin; 33 | }; 34 | 35 | #endif /* MR_USING_ADC */ 36 | 37 | #ifdef __cplusplus 38 | } 39 | #endif /* __cplusplus */ 40 | 41 | #endif /* _DRV_ADC_H_ */ 42 | -------------------------------------------------------------------------------- /bsp/wch/driver/drv_dac.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @copyright (c) 2023-2024, MR Development Team 3 | * 4 | * @license SPDX-License-Identifier: Apache-2.0 5 | * 6 | * @date 2023-11-14 MacRsh First version 7 | */ 8 | 9 | #include "drv_dac.h" 10 | 11 | #ifdef MR_USING_DAC 12 | 13 | #if !defined(MR_USING_DAC1) 14 | #warning "Please enable at least one DAC driver" 15 | #endif /* !defined(MR_USING_DAC1) */ 16 | 17 | static struct drv_dac_data dac_drv_data[] = 18 | { 19 | #ifdef MR_USING_DAC1 20 | {RCC_APB1Periph_DAC} 21 | #endif /* MR_USING_DAC1 */ 22 | }; 23 | 24 | static struct drv_dac_channel_data dac_channel_drv_data[] = DRV_DAC_CHANNEL_CONFIG; 25 | 26 | static struct mr_dac dac_dev; 27 | 28 | static struct drv_dac_channel_data *drv_dac_get_channel_data(int channel) 29 | { 30 | if ((channel >= MR_ARRAY_NUM(dac_channel_drv_data)) || (dac_channel_drv_data[channel].port == NULL)) 31 | { 32 | return NULL; 33 | } 34 | return &dac_channel_drv_data[channel]; 35 | } 36 | 37 | static int drv_dac_configure(struct mr_dac *dac, int state) 38 | { 39 | struct drv_dac_data *dac_data = (struct drv_dac_data *)dac->dev.drv->data; 40 | 41 | /* Configure clock */ 42 | RCC_APB1PeriphClockCmd(dac_data->clock, state); 43 | return MR_EOK; 44 | } 45 | 46 | static int drv_dac_channel_configure(struct mr_dac *dac, int channel, int state) 47 | { 48 | struct drv_dac_channel_data *dac_channel_data = drv_dac_get_channel_data(channel); 49 | GPIO_InitTypeDef GPIO_InitStructure = {0}; 50 | DAC_InitTypeDef DAC_InitStructure = {0}; 51 | 52 | /* Check channel is valid */ 53 | if (dac_channel_data == NULL) 54 | { 55 | return MR_EINVAL; 56 | } 57 | 58 | /* Configure clock */ 59 | RCC_APB2PeriphClockCmd(dac_channel_data->gpio_clock, ENABLE); 60 | 61 | switch (dac_channel_data->channel) 62 | { 63 | #ifdef DAC_Channel_1 64 | case DAC_Channel_1: 65 | { 66 | DAC_SetChannel1Data(DAC_Align_12b_R, 0); 67 | break; 68 | } 69 | #endif /* DAC_Channel_1 */ 70 | #ifdef DAC_Channel_2 71 | case DAC_Channel_2: 72 | { 73 | DAC_SetChannel2Data(DAC_Align_12b_R, 0); 74 | break; 75 | } 76 | #endif /* DAC_Channel_2 */ 77 | default: 78 | { 79 | return MR_EINVAL; 80 | } 81 | } 82 | 83 | /* Configure pin */ 84 | if (dac_channel_data->port != MR_NULL) 85 | { 86 | if (state == MR_ENABLE) 87 | { 88 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; 89 | GPIO_InitStructure.GPIO_Pin = dac_channel_data->pin; 90 | GPIO_Init(dac_channel_data->port, &GPIO_InitStructure); 91 | } 92 | } 93 | 94 | /* Configure DAC */ 95 | DAC_InitStructure.DAC_Trigger = DAC_Trigger_None; 96 | DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None; 97 | DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0; 98 | DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable; 99 | DAC_Init(dac_channel_data->channel, &DAC_InitStructure); 100 | DAC_Cmd(dac_channel_data->channel, state); 101 | return MR_EOK; 102 | } 103 | 104 | static int drv_dac_write(struct mr_dac *dac, int channel, uint32_t data) 105 | { 106 | struct drv_dac_channel_data *dac_channel_data = drv_dac_get_channel_data(channel); 107 | 108 | #ifdef MR_USING_DAC_CHANNEL_CHECK 109 | /* Check channel is valid */ 110 | if (dac_channel_data == NULL) 111 | { 112 | return MR_EINVAL; 113 | } 114 | #endif /* MR_USING_DAC_CHANNEL_CHECK */ 115 | 116 | /* Write data */ 117 | switch (dac_channel_data->channel) 118 | { 119 | #ifdef DAC_Channel_1 120 | case DAC_Channel_1: 121 | { 122 | DAC_SetChannel1Data(DAC_Align_12b_R, data); 123 | break; 124 | } 125 | #endif /* DAC_Channel_1 */ 126 | #ifdef DAC_Channel_2 127 | case DAC_Channel_2: 128 | { 129 | DAC_SetChannel2Data(DAC_Align_12b_R, data); 130 | break; 131 | } 132 | #endif /* DAC_Channel_2 */ 133 | default: 134 | { 135 | return MR_EINVAL; 136 | } 137 | } 138 | } 139 | 140 | static struct mr_dac_ops dac_drv_ops = 141 | { 142 | drv_dac_configure, 143 | drv_dac_channel_configure, 144 | drv_dac_write, 145 | }; 146 | 147 | static struct mr_drv dac_drv = 148 | { 149 | &dac_drv_ops, 150 | &dac_drv_data, 151 | }; 152 | 153 | static void drv_dac_init(void) 154 | { 155 | mr_dac_register(&dac_dev, "dac1", &dac_drv); 156 | } 157 | MR_INIT_DRV_EXPORT(drv_dac_init); 158 | 159 | #endif /* MR_USING_DAC */ 160 | -------------------------------------------------------------------------------- /bsp/wch/driver/drv_dac.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @copyright (c) 2023-2024, MR Development Team 3 | * 4 | * @license SPDX-License-Identifier: Apache-2.0 5 | * 6 | * @date 2023-11-14 MacRsh First version 7 | */ 8 | 9 | #ifndef _DRV_DAC_H_ 10 | #define _DRV_DAC_H_ 11 | 12 | #include "include/device/mr_dac.h" 13 | #include "mr_board.h" 14 | 15 | #ifdef MR_USING_DAC 16 | 17 | struct drv_dac_data 18 | { 19 | uint32_t clock; 20 | }; 21 | 22 | struct drv_dac_channel_data 23 | { 24 | uint32_t channel; 25 | uint32_t gpio_clock; 26 | GPIO_TypeDef *port; 27 | uint32_t pin; 28 | }; 29 | 30 | #endif /* MR_USING_DAC */ 31 | 32 | #endif /* _DRV_DAC_H_ */ 33 | -------------------------------------------------------------------------------- /bsp/wch/driver/drv_i2c.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @copyright (c) 2023-2024, MR Development Team 3 | * 4 | * @license SPDX-License-Identifier: Apache-2.0 5 | * 6 | * @date 2023-11-13 MacRsh First version 7 | */ 8 | 9 | #ifndef _DRV_I2C_H_ 10 | #define _DRV_I2C_H_ 11 | 12 | #include "include/device/mr_i2c.h" 13 | #include "mr_board.h" 14 | 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif /* __cplusplus */ 18 | 19 | #ifdef MR_USING_I2C 20 | 21 | struct drv_i2c_bus_data 22 | { 23 | I2C_TypeDef *instance; 24 | uint32_t clock; 25 | uint32_t gpio_clock; 26 | GPIO_TypeDef *scl_port; 27 | uint32_t sda_pin; 28 | GPIO_TypeDef *sda_port; 29 | uint32_t scl_pin; 30 | IRQn_Type irq; 31 | uint32_t remap; 32 | }; 33 | 34 | #endif /* MR_USING_I2C */ 35 | 36 | #ifdef __cplusplus 37 | } 38 | #endif /* __cplusplus */ 39 | 40 | #endif /* _DRV_I2C_H_ */ 41 | -------------------------------------------------------------------------------- /bsp/wch/driver/drv_pin.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @copyright (c) 2023-2024, MR Development Team 3 | * 4 | * @license SPDX-License-Identifier: Apache-2.0 5 | * 6 | * @date 2023-11-11 MacRsh First version 7 | */ 8 | 9 | #ifndef _DRV_PIN_H_ 10 | #define _DRV_PIN_H_ 11 | 12 | #include "include/device/mr_pin.h" 13 | #include "mr_board.h" 14 | 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif /* __cplusplus */ 18 | 19 | #ifdef MR_USING_PIN 20 | 21 | struct drv_pin_port_data 22 | { 23 | GPIO_TypeDef *port; 24 | }; 25 | 26 | struct drv_pin_data 27 | { 28 | uint32_t pin; 29 | }; 30 | 31 | #endif /* MR_USING_PIN */ 32 | 33 | #ifdef __cplusplus 34 | } 35 | #endif /* __cplusplus */ 36 | 37 | #endif /* _DRV_PIN_H_ */ 38 | -------------------------------------------------------------------------------- /bsp/wch/driver/drv_pwm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @copyright (c) 2023-2024, MR Development Team 3 | * 4 | * @license SPDX-License-Identifier: Apache-2.0 5 | * 6 | * @date 2024-01-01 MacRsh First version 7 | */ 8 | 9 | #ifndef _DRV_PWM_H_ 10 | #define _DRV_PWM_H_ 11 | 12 | #include "include/device/mr_pwm.h" 13 | #include "mr_board.h" 14 | 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif /* __cplusplus */ 18 | 19 | #ifdef MR_USING_PWM 20 | 21 | struct drv_pwm_data 22 | { 23 | TIM_TypeDef *instance; 24 | uint32_t clock; 25 | uint32_t gpio_clock; 26 | GPIO_TypeDef *ch1_port; 27 | uint32_t ch1_pin; 28 | GPIO_TypeDef *ch2_port; 29 | uint32_t ch2_pin; 30 | GPIO_TypeDef *ch3_port; 31 | uint32_t ch3_pin; 32 | GPIO_TypeDef *ch4_port; 33 | uint32_t ch4_pin; 34 | uint32_t remap; 35 | }; 36 | 37 | #endif /* MR_USING_PWM */ 38 | 39 | #ifdef __cplusplus 40 | } 41 | #endif /* __cplusplus */ 42 | 43 | #endif /* _DRV_PWM_H_ */ 44 | -------------------------------------------------------------------------------- /bsp/wch/driver/drv_serial.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @copyright (c) 2023-2024, MR Development Team 3 | * 4 | * @license SPDX-License-Identifier: Apache-2.0 5 | * 6 | * @date 2023-11-10 MacRsh First version 7 | */ 8 | 9 | #ifndef _DRV_SERIAL_H_ 10 | #define _DRV_SERIAL_H_ 11 | 12 | #include "include/device/mr_serial.h" 13 | #include "mr_board.h" 14 | 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif /* __cplusplus */ 18 | 19 | #ifdef MR_USING_SERIAL 20 | 21 | struct drv_serial_data 22 | { 23 | USART_TypeDef *instance; 24 | uint32_t clock; 25 | uint32_t gpio_clock; 26 | GPIO_TypeDef *rx_port; 27 | uint32_t rx_pin; 28 | GPIO_TypeDef *tx_port; 29 | uint32_t tx_pin; 30 | IRQn_Type irq; 31 | uint32_t remap; 32 | }; 33 | 34 | #endif /* MR_USING_SERIAL */ 35 | 36 | #ifdef __cplusplus 37 | } 38 | #endif /* __cplusplus */ 39 | 40 | #endif /* _DRV_SERIAL_H_ */ 41 | -------------------------------------------------------------------------------- /bsp/wch/driver/drv_spi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @copyright (c) 2023-2024, MR Development Team 3 | * 4 | * @license SPDX-License-Identifier: Apache-2.0 5 | * 6 | * @date 2023-11-10 MacRsh First version 7 | */ 8 | 9 | #ifndef _DRV_SPI_H_ 10 | #define _DRV_SPI_H_ 11 | 12 | #include "include/device/mr_spi.h" 13 | #include "mr_board.h" 14 | 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif /* __cplusplus */ 18 | 19 | #ifdef MR_USING_SPI 20 | 21 | struct drv_spi_bus_data 22 | { 23 | SPI_TypeDef *instance; 24 | uint32_t clock; 25 | uint32_t gpio_clock; 26 | GPIO_TypeDef *nss_port; 27 | uint32_t nss_pin; 28 | GPIO_TypeDef *sck_port; 29 | uint32_t sck_pin; 30 | GPIO_TypeDef *miso_port; 31 | uint32_t miso_pin; 32 | GPIO_TypeDef *mosi_port; 33 | uint32_t mosi_pin; 34 | IRQn_Type irq; 35 | uint32_t remap; 36 | }; 37 | 38 | #endif /* MR_USING_SPI */ 39 | 40 | #ifdef __cplusplus 41 | } 42 | #endif /* __cplusplus */ 43 | 44 | #endif /* _DRV_SPI_H_ */ 45 | -------------------------------------------------------------------------------- /bsp/wch/driver/drv_timer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @copyright (c) 2023-2024, MR Development Team 3 | * 4 | * @license SPDX-License-Identifier: Apache-2.0 5 | * 6 | * @date 2023-11-30 MacRsh First version 7 | */ 8 | 9 | #ifndef _DRV_TIMER_H_ 10 | #define _DRV_TIMER_H_ 11 | 12 | #include "include/device/mr_timer.h" 13 | #include "mr_board.h" 14 | 15 | #ifdef MR_USING_TIMER 16 | 17 | struct drv_timer_data 18 | { 19 | TIM_TypeDef *instance; 20 | uint32_t clock; 21 | IRQn_Type irq; 22 | }; 23 | 24 | #endif /* MR_USING_TIMER */ 25 | 26 | #endif /* _DRV_TIMER_H_ */ 27 | -------------------------------------------------------------------------------- /bsp/wch/driver/mr_board.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @copyright (c) 2023-2024, MR Development Team 3 | * 4 | * @license SPDX-License-Identifier: Apache-2.0 5 | * 6 | * @date 2024-01-16 MacRsh First version 7 | */ 8 | 9 | #include "mr_board.h" 10 | 11 | void mr_delay_us(uint32_t us) 12 | { 13 | Delay_Us(us); 14 | } 15 | 16 | void mr_delay_ms(uint32_t ms) 17 | { 18 | Delay_Ms(ms); 19 | } 20 | -------------------------------------------------------------------------------- /components/Kconfig: -------------------------------------------------------------------------------- 1 | menu "Components configure" 2 | source "components/**/Kconfig" 3 | endmenu 4 | -------------------------------------------------------------------------------- /components/msh/Kconfig: -------------------------------------------------------------------------------- 1 | config MR_USING_MSH 2 | bool "Use msh component" 3 | default n 4 | help 5 | "Use this option allows for the use of the shell." 6 | menu "Msh configure" 7 | depends on MR_USING_MSH 8 | 9 | config MR_CFG_MSH_BUFSZ 10 | int "Msh buffer size" 11 | default 32 12 | range 16 1024 13 | help 14 | "This option sets the buffer size used by the shell." 15 | 16 | config MR_CFG_MSH_ARGS_NUM 17 | int "Msh argument max number" 18 | default 16 19 | range 4 64 20 | help 21 | "This option sets the max number of arguments." 22 | 23 | config MR_CFG_MSH_HISTORY_LINES 24 | int "Msh history max lines" 25 | default 4 26 | range 1 64 27 | help 28 | "This option sets the max number of history lines." 29 | 30 | config MR_CFG_MSH_DEV_NAME 31 | string "Msh device name" 32 | default "serial1" 33 | help 34 | "This option sets the name of the device used by the shell." 35 | 36 | config MR_CFG_MSH_NONBLOCKING 37 | bool "Use msh non-blocking" 38 | default n 39 | help 40 | "Use this option allows for the use of the shell non-blocking." 41 | 42 | config MR_CFG_MSH_PRINTF_BUFSZ 43 | int "Printf buffer size" 44 | default 128 45 | range 32 2147483647 46 | help 47 | "This option sets the buffer size used by the printf function." 48 | 49 | config MR_CFG_MSH_PROMPT 50 | string "Msh prompt" 51 | default "msh" 52 | help 53 | "This option sets the prompt of the shell." 54 | 55 | config MR_USING_MSH_PRINTF_COLOR 56 | bool "Use msh printf color" 57 | default n 58 | help 59 | "This option allows for the use of the printf color in the msh." 60 | 61 | config MR_USING_MSH_ECHO 62 | bool "Use msh echo" 63 | default y 64 | help 65 | "Use this option allows for the use of the echo in the msh." 66 | 67 | config MR_USING_MSH_DEV_CMD 68 | bool "Use msh device cmd" 69 | default y 70 | help 71 | "Use this option allows for the use of the device cmd in the msh." 72 | 73 | config MR_USING_ 74 | endmenu -------------------------------------------------------------------------------- /device/adc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @copyright (c) 2023-2024, MR Development Team 3 | * 4 | * @license SPDX-License-Identifier: Apache-2.0 5 | * 6 | * @date 2023-11-06 MacRsh First version 7 | */ 8 | 9 | #include "include/device/mr_adc.h" 10 | 11 | #ifdef MR_USING_ADC 12 | 13 | MR_INLINE int adc_channel_set_configure(struct mr_adc *adc, 14 | int channel, 15 | struct mr_adc_config config) 16 | { 17 | struct mr_adc_ops *ops = (struct mr_adc_ops *)adc->dev.drv->ops; 18 | 19 | if ((channel < 0) || (channel >= (sizeof(adc->channels) * 8))) { 20 | return MR_EINVAL; 21 | } 22 | 23 | int ret = ops->channel_configure(adc, channel, config.state); 24 | if (ret < 0) { 25 | return ret; 26 | } 27 | 28 | /* Enable or disable the channel */ 29 | if (config.state == MR_ENABLE) { 30 | MR_BIT_SET(adc->channels, (1 << channel)); 31 | } else { 32 | MR_BIT_CLR(adc->channels, (1 << channel)); 33 | } 34 | return MR_EOK; 35 | } 36 | 37 | MR_INLINE int adc_channel_get_configure(struct mr_adc *adc, 38 | int channel, 39 | struct mr_adc_config *config) 40 | { 41 | if ((channel < 0) || (channel >= (sizeof(adc->channels) * 8))) { 42 | return MR_EINVAL; 43 | } 44 | 45 | /* Get configure */ 46 | config->state = MR_BIT_IS_SET(adc->channels, (1 << channel)); 47 | return MR_EOK; 48 | } 49 | 50 | static int mr_adc_open(struct mr_dev *dev) 51 | { 52 | struct mr_adc *adc = (struct mr_adc *)dev; 53 | struct mr_adc_ops *ops = (struct mr_adc_ops *)dev->drv->ops; 54 | 55 | return ops->configure(adc, MR_ENABLE); 56 | } 57 | 58 | static int mr_adc_close(struct mr_dev *dev) 59 | { 60 | struct mr_adc *adc = (struct mr_adc *)dev; 61 | struct mr_adc_ops *ops = (struct mr_adc_ops *)dev->drv->ops; 62 | 63 | #ifdef MR_USING_ADC_AUTO_DISABLE 64 | /* Disable all channels */ 65 | for (size_t i = 0; i < (sizeof(adc->channels) * 8); i++) { 66 | if (MR_BIT_IS_SET(adc->channels, (1 << i)) == MR_ENABLE) { 67 | ops->channel_configure(adc, (int)i, MR_DISABLE); 68 | MR_BIT_CLR(adc->channels, (1 << i)); 69 | } 70 | } 71 | #endif /* MR_USING_ADC_AUTO_DISABLE */ 72 | 73 | return ops->configure(adc, MR_DISABLE); 74 | } 75 | 76 | static ssize_t mr_adc_read(struct mr_dev *dev, void *buf, size_t count) 77 | { 78 | struct mr_adc *adc = (struct mr_adc *)dev; 79 | struct mr_adc_ops *ops = (struct mr_adc_ops *)dev->drv->ops; 80 | uint32_t *rd_buf = (uint32_t *)buf; 81 | ssize_t rd_size; 82 | 83 | #ifdef MR_USING_ADC_CHANNEL_CHECK 84 | /* Check if the channel is enabled */ 85 | if ((dev->position < 0) || (MR_BIT_IS_SET(adc->channels, (1 << dev->position)) == MR_DISABLE)) { 86 | return MR_EINVAL; 87 | } 88 | #endif /* MR_USING_ADC_CHANNEL_CHECK */ 89 | 90 | for (rd_size = 0; rd_size < MR_ALIGN_DOWN(count, sizeof(*rd_buf)); rd_size += sizeof(*rd_buf)) { 91 | int ret = ops->read(adc, dev->position, rd_buf); 92 | if (ret < 0) { 93 | return (rd_size == 0) ? ret : rd_size; 94 | } 95 | rd_buf++; 96 | } 97 | return rd_size; 98 | } 99 | 100 | static int mr_adc_ioctl(struct mr_dev *dev, int cmd, void *args) 101 | { 102 | struct mr_adc *adc = (struct mr_adc *)dev; 103 | 104 | switch (cmd) { 105 | case MR_IOC_ADC_SET_CHANNEL_CONFIG: { 106 | if (args != MR_NULL) { 107 | struct mr_adc_config config = *((struct mr_adc_config *)args); 108 | 109 | int ret = adc_channel_set_configure(adc, dev->position, config); 110 | if (ret < 0) { 111 | return ret; 112 | } 113 | return sizeof(config); 114 | } 115 | return MR_EINVAL; 116 | } 117 | case MR_IOC_ADC_GET_CHANNEL_CONFIG: { 118 | if (args != MR_NULL) { 119 | struct mr_adc_config *config = (struct mr_adc_config *)args; 120 | 121 | int ret = adc_channel_get_configure(adc, dev->position, config); 122 | if (ret < 0) { 123 | return ret; 124 | } 125 | return sizeof(*config); 126 | } 127 | return MR_EINVAL; 128 | } 129 | default: { 130 | return MR_ENOTSUP; 131 | } 132 | } 133 | } 134 | 135 | /** 136 | * @brief This function registers an adc. 137 | * 138 | * @param adc The adc. 139 | * @param path The path of the adc. 140 | * @param drv The driver of the adc. 141 | * 142 | * @return 0 on success, otherwise an error code. 143 | */ 144 | int mr_adc_register(struct mr_adc *adc, const char *path, struct mr_drv *drv) 145 | { 146 | static struct mr_dev_ops ops = {mr_adc_open, 147 | mr_adc_close, 148 | mr_adc_read, 149 | MR_NULL, 150 | mr_adc_ioctl, 151 | MR_NULL}; 152 | 153 | MR_ASSERT(adc != MR_NULL); 154 | MR_ASSERT(path != MR_NULL); 155 | MR_ASSERT(drv != MR_NULL); 156 | MR_ASSERT(drv->ops != MR_NULL); 157 | 158 | /* Initialize the fields */ 159 | adc->channels = 0; 160 | 161 | /* Register the adc */ 162 | return mr_dev_register(&adc->dev, path, MR_DEV_TYPE_ADC, MR_O_RDONLY, &ops, drv); 163 | } 164 | 165 | #endif /* MR_USING_ADC */ 166 | -------------------------------------------------------------------------------- /device/dac.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @copyright (c) 2023-2024, MR Development Team 3 | * 4 | * @license SPDX-License-Identifier: Apache-2.0 5 | * 6 | * @date 2023-11-08 MacRsh First version 7 | */ 8 | 9 | #include "include/device/mr_dac.h" 10 | 11 | #ifdef MR_USING_DAC 12 | 13 | MR_INLINE int dac_channel_set_configure(struct mr_dac *dac, 14 | int channel, 15 | struct mr_dac_config config) 16 | { 17 | struct mr_dac_ops *ops = (struct mr_dac_ops *)dac->dev.drv->ops; 18 | 19 | if ((channel < 0) || (channel >= (sizeof(dac->channels) * 8))) { 20 | return MR_EINVAL; 21 | } 22 | 23 | int ret = ops->channel_configure(dac, channel, config.state); 24 | if (ret < 0) { 25 | return ret; 26 | } 27 | 28 | /* Enable or disable the channel */ 29 | if (config.state == MR_ENABLE) { 30 | MR_BIT_SET(dac->channels, (1 << channel)); 31 | } else { 32 | MR_BIT_CLR(dac->channels, (1 << channel)); 33 | } 34 | return MR_EOK; 35 | } 36 | 37 | MR_INLINE int dac_channel_get_configure(struct mr_dac *dac, 38 | int channel, 39 | struct mr_dac_config *config) 40 | { 41 | if ((channel < 0) || (channel >= (sizeof(dac->channels) * 8))) { 42 | return MR_EINVAL; 43 | } 44 | 45 | /* Get configure */ 46 | config->state = MR_BIT_IS_SET(dac->channels, (1 << channel)); 47 | return MR_EOK; 48 | } 49 | 50 | static int mr_dac_open(struct mr_dev *dev) 51 | { 52 | struct mr_dac *dac = (struct mr_dac *)dev; 53 | struct mr_dac_ops *ops = (struct mr_dac_ops *)dev->drv->ops; 54 | 55 | return ops->configure(dac, MR_ENABLE); 56 | } 57 | 58 | static int mr_dac_close(struct mr_dev *dev) 59 | { 60 | struct mr_dac *dac = (struct mr_dac *)dev; 61 | struct mr_dac_ops *ops = (struct mr_dac_ops *)dev->drv->ops; 62 | 63 | #ifdef MR_USING_DAC_AUTO_DISABLE 64 | /* Disable all channels */ 65 | for (size_t i = 0; i < (sizeof(dac->channels) * 8); i++) { 66 | if (MR_BIT_IS_SET(dac->channels, (1 << i)) == MR_ENABLE) { 67 | ops->channel_configure(dac, (int)i, MR_DISABLE); 68 | MR_BIT_CLR(dac->channels, (1 << i)); 69 | } 70 | } 71 | #endif /* MR_USING_DAC_AUTO_DISABLE */ 72 | 73 | return ops->configure(dac, MR_DISABLE); 74 | } 75 | 76 | static ssize_t mr_dac_write(struct mr_dev *dev, const void *buf, size_t count) 77 | { 78 | struct mr_dac *dac = (struct mr_dac *)dev; 79 | struct mr_dac_ops *ops = (struct mr_dac_ops *)dev->drv->ops; 80 | uint32_t *wr_buf = (uint32_t *)buf; 81 | ssize_t wr_size; 82 | 83 | #ifdef MR_USING_DAC_CHANNEL_CHECK 84 | /* Check if the channel is enabled */ 85 | if ((dev->position < 0) || (MR_BIT_IS_SET(dac->channels, (1 << dev->position)) == MR_DISABLE)) { 86 | return MR_EINVAL; 87 | } 88 | #endif /* MR_USING_DAC_CHANNEL_CHECK */ 89 | 90 | for (wr_size = 0; wr_size < MR_ALIGN_DOWN(count, sizeof(*wr_buf)); wr_size += sizeof(*wr_buf)) { 91 | int ret = ops->write(dac, dev->position, *wr_buf); 92 | if (ret < 0) { 93 | return (wr_size == 0) ? ret : wr_size; 94 | } 95 | wr_buf++; 96 | } 97 | return wr_size; 98 | } 99 | 100 | static int mr_dac_ioctl(struct mr_dev *dev, int cmd, void *args) 101 | { 102 | struct mr_dac *dac = (struct mr_dac *)dev; 103 | 104 | switch (cmd) { 105 | case MR_IOC_DAC_SET_CHANNEL_CONFIG: { 106 | if (args != MR_NULL) { 107 | struct mr_dac_config config = *((struct mr_dac_config *)args); 108 | 109 | int ret = dac_channel_set_configure(dac, dev->position, config); 110 | if (ret < 0) { 111 | return ret; 112 | } 113 | return sizeof(config); 114 | } 115 | return MR_EINVAL; 116 | } 117 | case MR_IOC_DAC_GET_CHANNEL_CONFIG: { 118 | if (args != MR_NULL) { 119 | struct mr_dac_config *config = (struct mr_dac_config *)args; 120 | 121 | int ret = dac_channel_get_configure(dac, dev->position, config); 122 | if (ret < 0) { 123 | return ret; 124 | } 125 | return sizeof(*config); 126 | } 127 | return MR_EINVAL; 128 | } 129 | default: { 130 | return MR_ENOTSUP; 131 | } 132 | } 133 | } 134 | 135 | /** 136 | * @brief This function registers an dac. 137 | * 138 | * @param dac The dac. 139 | * @param path The path of the dac. 140 | * @param drv The driver of the dac. 141 | * 142 | * @return 0 on success, otherwise an error code. 143 | */ 144 | int mr_dac_register(struct mr_dac *dac, const char *path, struct mr_drv *drv) 145 | { 146 | static struct mr_dev_ops ops = {mr_dac_open, 147 | mr_dac_close, 148 | MR_NULL, 149 | mr_dac_write, 150 | mr_dac_ioctl, 151 | MR_NULL}; 152 | 153 | MR_ASSERT(dac != MR_NULL); 154 | MR_ASSERT(path != MR_NULL); 155 | MR_ASSERT(drv != MR_NULL); 156 | MR_ASSERT(drv->ops != MR_NULL); 157 | 158 | /* Initialize the fields */ 159 | dac->channels = 0; 160 | 161 | /* Register the dac */ 162 | return mr_dev_register(&dac->dev, path, MR_DEV_TYPE_DAC, MR_O_WRONLY, &ops, drv); 163 | } 164 | 165 | #endif /* MR_USING_DAC */ 166 | -------------------------------------------------------------------------------- /device/fast_pin.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @copyright (c) 2023-2024, MR Development Team 3 | * 4 | * @license SPDX-License-Identifier: Apache-2.0 5 | * 6 | * @date 2024-11-08 MacRsh First version 7 | */ 8 | 9 | #include "include/device/mr_pin.h" 10 | 11 | #ifdef MR_USING_PIN 12 | 13 | /** 14 | * @addtogroup PIN 15 | * @{ 16 | */ 17 | 18 | /** 19 | * @brief This function get the fast pin device pointer. 20 | * 21 | * @param magic The magic number. 22 | * 23 | * @return The fast pin device pointer. 24 | * 25 | * @note Please do not appear the code in this file in the application layer. 26 | */ 27 | MR_INLINE struct mr_dev **_fast_pin_dev_get(uint32_t magic) 28 | { 29 | static struct mr_dev *dev = MR_NULL; 30 | 31 | /* If that doesn't stop you, feel free to use it */ 32 | if (magic == MR_MAGIC_NUMBER) { 33 | return &dev; 34 | } 35 | return MR_NULL; 36 | } 37 | 38 | /** 39 | * @brief This function initialize the fast pin device. 40 | * 41 | * @param dev The pin device. 42 | * 43 | * @note Please do not appear the code in this file in the application layer. 44 | */ 45 | void _mr_fast_pin_init(struct mr_dev *dev) 46 | { 47 | if (_fast_pin_dev_get(dev->magic) != MR_NULL) { 48 | *_fast_pin_dev_get(dev->magic) = dev; 49 | } 50 | } 51 | 52 | /** 53 | * @brief This function set the pin mode. 54 | * 55 | * @param number The pin number. 56 | * @param mode The pin mode. 57 | * 58 | * @return 0 on success, otherwise an error code. 59 | * 60 | * @note Please do not appear the code in this file in the application layer. 61 | */ 62 | int _mr_fast_pin_mode(int number, int mode) 63 | { 64 | struct mr_dev *dev = *_fast_pin_dev_get(MR_MAGIC_NUMBER); 65 | 66 | if (dev == MR_NULL) { 67 | return MR_ENOTFOUND; 68 | } 69 | return ((struct mr_pin_ops *)dev->drv->ops)->configure((struct mr_pin *)dev, number, mode); 70 | } 71 | 72 | /** 73 | * @brief This function read the pin value. 74 | * 75 | * @param number The pin number. 76 | * 77 | * @return The pin value. 78 | * 79 | * @note Please do not appear the code in this file in the application layer. 80 | */ 81 | uint8_t _mr_fast_pin_read(int number) 82 | { 83 | struct mr_dev *dev = *_fast_pin_dev_get(MR_MAGIC_NUMBER); 84 | uint8_t value = 0; 85 | 86 | ((struct mr_pin_ops *)dev->drv->ops)->read((struct mr_pin *)dev, number, &value); 87 | return value; 88 | } 89 | 90 | /** 91 | * @brief This function write the pin value. 92 | * 93 | * @param number The pin number. 94 | * @param value The pin value. 95 | * 96 | * @note Please do not appear the code in this file in the application layer. 97 | */ 98 | void _mr_fast_pin_write(int number, int value) 99 | { 100 | struct mr_dev *dev = *_fast_pin_dev_get(MR_MAGIC_NUMBER); 101 | 102 | ((struct mr_pin_ops *)dev->drv->ops)->write((struct mr_pin *)dev, number, value); 103 | } 104 | /** @} */ 105 | 106 | #endif /* MR_USING_PIN */ 107 | 108 | -------------------------------------------------------------------------------- /document/Kconfig/introduce_Kconfig.md: -------------------------------------------------------------------------------- 1 | # 如何为项目引入Kconfig配置系统 2 | 3 | [English](introduce_Kconfig_EN.md) 4 | 5 | 6 | * [如何为项目引入Kconfig配置系统](#如何为项目引入kconfig配置系统) 7 | * [验证 python 环境](#验证-python-环境) 8 | * [C语言头文件生成脚本](#c语言头文件生成脚本) 9 | * [应用](#应用) 10 | * [创建Kconfig](#创建kconfig) 11 | 12 | 13 | 项目中经常会有通过宏配置或选择参数: 14 | 15 | ```c 16 | #ifdef CFG_ENABLE 17 | #define CFG_ARGS "test" 18 | void printf_args(void) 19 | { 20 | printf("args: %s\n", CFG_ARGS); 21 | } 22 | #endif 23 | ``` 24 | 25 | 当项目规模较小,配置项和依赖关系相对简单时,我们可以通过手动修改源代码来实现配置功能。但是,随着项目规模的增长和配置复杂度的增加,这种方式也会出现一些问题。 26 | 27 | 随着代码体量和调用关系的增多,对配置者来说`很难完全熟悉` 28 | 代码结构及各模块之间的依赖关系。同时,如果配置项设置较为`随意且缺乏约束`,也很可能导致`错误配置`。这对项目质量和维护都带来一定难度。 29 | 30 | 对于规模较大的项目来说,需要一套专业的配置管理系统来解决这些问题。Kconfig正是为了应对这种需求而产生的。它通过配置脚本定义各配置选项及其依赖关系,并提供`图形化界面` 31 | 供配置者操作。同时还会检查配置`合理性`,帮助我们实现定制化构建的同时`防止错误配置`。 32 | 33 | 如果有接触过Linux或者RT-Thread等,相信对Kconfig系统都不陌生。Kconfig是Linux内核和许多其他系统广泛使用的一款配置管理工具。它可以让开发人员在编译时选择性地包含或排除某些功能模块。 34 | 35 | Kconfig使用配置脚本定义各种配置选项及其依赖关系。通过图形或字符型用户界面,开发者可以查看并设置各种配置。然后Kconfig会生成 `.config` 36 | 文件保存选择结果。在编译的时候,会根据 `.config` 文件里设置的符号自动包含或排除对应的源代码。 37 | 38 | ![Kconfig](../picture/Kconfig/Kconfig.png) 39 | 40 | ## 验证 python 环境 41 | 42 | Kconfig依赖于 ` python` ,如果没有 ` python` 环境请自行安装。 43 | 44 | 在命令行中使用所示命令验证: 45 | 46 | ```cmd 47 | python --version 48 | ``` 49 | 50 | 显示(正确显示版本即可): 51 | 52 | ```cmd 53 | Python 3.11.4 54 | ``` 55 | 56 | ## C语言头文件生成脚本 57 | 58 | Kconfiglib 生成的是 `.config` 文件,并非C语言文件,需要使用脚本生成,`将以下代码复制到文件中并命名为kconfig.py`。 59 | 60 | ```python 61 | import re 62 | import pip 63 | 64 | 65 | def log_print(level, text): 66 | # Log level colors 67 | LEVEL_COLORS = { 68 | 'error': '\033[31m', 69 | 'success': '\033[32m', 70 | 'warning': '\033[33m', 71 | 'info': '\033[34m', 72 | } 73 | RESET_COLOR = '\033[0m' 74 | # Log level name 75 | LEVEL_NAME = { 76 | 'error': 'ERROR', 77 | 'success': 'SUCCESS', 78 | 'warning': 'WARNING', 79 | 'info': 'INFO', 80 | } 81 | print(LEVEL_COLORS[level] + LEVEL_NAME[level] + ': ' + text + RESET_COLOR) 82 | 83 | 84 | def install_package(package): 85 | log_print('info', "%s package installing..." % package) 86 | pip.main(['install', package]) 87 | 88 | 89 | try: 90 | from kconfiglib import Kconfig 91 | except ImportError: 92 | install_package('kconfiglib') 93 | from kconfiglib import Kconfig 94 | 95 | try: 96 | import curses 97 | except ImportError: 98 | install_package('windows-curses') 99 | import curses 100 | 101 | 102 | def generate_config(kconfig_file, config_in, config_out, header_out): 103 | kconf = Kconfig(kconfig_file, warn=False, warn_to_stderr=False) 104 | 105 | # Load config 106 | kconf.load_config(config_in) 107 | kconf.write_config(config_out) 108 | kconf.write_autoconf(header_out) 109 | 110 | with open(header_out, 'r+') as header_file: 111 | content = header_file.read() 112 | header_file.truncate(0) 113 | header_file.seek(0) 114 | 115 | # Remove CONFIG_ and MR_USING_XXX following number 116 | content = content.replace("#define CONFIG_", "#define ") 117 | content = re.sub(r'#define MR_USING_(\w+) (\d+)', r'#define MR_USING_\1', content) 118 | 119 | # Add the micro 120 | header_file.write("#ifndef _MR_CONFIG_H_\n") 121 | header_file.write("#define _MR_CONFIG_H_\n\n") 122 | 123 | header_file.write("#ifdef __cplusplus\n") 124 | header_file.write("extern \"C\" {\n") 125 | header_file.write("#endif /* __cplusplus */\n\n") 126 | 127 | # Write back the original data 128 | header_file.write(content) 129 | 130 | # Add the micro 131 | header_file.write("\n#ifdef __cplusplus\n") 132 | header_file.write("}\n") 133 | header_file.write("#endif /* __cplusplus */\n\n") 134 | header_file.write("#endif /* _MR_CONFIG_H_ */\n") 135 | 136 | header_file.close() 137 | log_print('success', "menuconfig %s make success" % header_out) 138 | 139 | 140 | def main(): 141 | kconfig_file = '' 142 | config_in = '.config' 143 | config_out = '.config' 144 | header_out = 'config.h' 145 | generate_config(kconfig_file, config_in, config_out, header_out) 146 | 147 | 148 | if __name__ == "__main__": 149 | main() 150 | ``` 151 | 152 | 修改`main`函数中`header_out `可修改生成的函数文件名。 153 | 154 | 此脚本去除了Kconfig默认添加的`CONFIG_`前缀,并为其加上了`_CONFIG_H_` 和`C`声明。 155 | 156 | # 应用 157 | 158 | ## 创建Kconfig 159 | 160 | 新建一个名字为 `Kconfig` 的文件(注意没有后缀名),和上一步中中创建的 `kconfig.py` 的文件放在一起。 161 | 162 | ```Kconfig 163 | mainmenu "Demo" 164 | 165 | menu "Args configure" 166 | config CFG_ARG1 167 | bool "Enable arg1" 168 | default n 169 | 170 | config CFG_ARG2 171 | int "Arg2 number" 172 | default 8 173 | range 0 64 174 | 175 | endmenu 176 | ``` 177 | 178 | 在当前目录下调用命令行,输入: 179 | 180 | ```cmd 181 | menuconfig 182 | ``` 183 | 184 | 就可以看到我们刚刚写的Demo界面 185 | 186 | ![Kconfig1](../picture/Kconfig/Kconfig1.png) 187 | 188 | 回车后就可以看到配置的2个参数: 189 | 190 | ![Kconfig2](../picture/Kconfig/Kconfig2.png) 191 | 192 | 设置的范围也在输入时生效了: 193 | 194 | ![Kconfig3](../picture/Kconfig/Kconfig3.png) 195 | 196 | 配置完成后按`Q`退出,`Y`保存配置。 197 | 198 | 在当前目录下调用命令行,输入: 199 | 200 | ```cmd 201 | python kconfig.py 202 | ``` 203 | 204 | 运行 `python` 脚本生成`.h`文件。 205 | 206 | 显示生成`config.h`成功。打开这个文件: 207 | 208 | ![Kconfig4](../picture/Kconfig/Kconfig4.png) 209 | -------------------------------------------------------------------------------- /document/coding_style/coding_style.md: -------------------------------------------------------------------------------- 1 | # 格式与风格 2 | 3 | [English](coding_style_EN.md) 4 | 5 | 6 | * [格式与风格](#格式与风格) 7 | * [缩进与换行](#缩进与换行) 8 | * [空格与空行](#空格与空行) 9 | * [头文件](#头文件) 10 | * [命名规范](#命名规范) 11 | * [类型](#类型) 12 | * [函数与变量](#函数与变量) 13 | * [文件名](#文件名) 14 | * [宏](#宏) 15 | * [注释规范](#注释规范) 16 | 17 | 18 | ## 缩进与换行 19 | 20 | 1. 仅使用4个空格进行代码缩进,禁止使用tab键。 21 | 2. 每行代码长度控制在100个字符内,超过换行,下一行缩进4个空格。 22 | 3. 大括号定义时各自占一行,`if`等使用时紧跟行尾。 23 | 例如: 24 | 25 | ```c 26 | if (condition) { 27 | do_something(); 28 | } 29 | 30 | void func(void) 31 | { 32 | ... 33 | } 34 | ``` 35 | 36 | ## 空格与空行 37 | 38 | 1. 操作符两边各加一个空格,自加自减不加空格。 39 | 例如: 40 | 41 | ```c 42 | x = 1; 43 | a + b; 44 | i++; 45 | ``` 46 | 47 | 2. 逗号`,`后加一个空格。 48 | 例如: 49 | 50 | ```c 51 | void foo(int a, char b); 52 | ``` 53 | 54 | ## 头文件 55 | 56 | 1. 头文件为避免重复包含,使用`_FILE_H_`宏进行保护。 57 | 2. 头文件按字母顺序导入,库文件优先。库头文件使用`<>`导入,其余头文件使用`""`导入。 58 | 例如: 59 | 60 | ```c 61 | #include 62 | #include 63 | #include "bar.h" 64 | #include "foo.h" 65 | ``` 66 | 67 | # 命名规范 68 | 69 | ## 类型 70 | 71 | 1. 枚举类型命名全部小写,下划线分隔,枚举常量首字母大写。 72 | 例如: 73 | 74 | ```c 75 | enum color_type 76 | { 77 | Red, 78 | Green, 79 | Blue, 80 | Light_Pink, 81 | }; 82 | ``` 83 | 84 | 2. 结构体、联合体、类型定义命名小写,下划线分隔。 85 | 例如: 86 | 87 | ```c 88 | struct foo 89 | { 90 | char *name; 91 | union coordinate 92 | { 93 | int x; 94 | int y; 95 | } 96 | }; 97 | ``` 98 | 99 | ## 函数与变量 100 | 101 | 1. 函数命名小写,下划线分隔。 102 | 例如: 103 | 104 | ```c 105 | void do_something(int arg1, char arg2) 106 | { 107 | ... 108 | } 109 | ``` 110 | 111 | 2. 函数中功能模块应分块书写,当出现较大块且无法通过代码简单明了的解读时需要标注代码块功能。当返回值无特殊功能时允许紧贴其他代码块,当有其余功能时,需单独成块。 112 | 113 | ```c 114 | void do_something1(int arg1, char arg2) 115 | { 116 | /* do something */ 117 | ... 118 | 119 | /* do something */ 120 | ... 121 | return OK; 122 | } 123 | 124 | void do_something2(int arg1, char arg2) 125 | { 126 | /* do something */ 127 | ... 128 | 129 | /* do something */ 130 | ... 131 | 132 | return /* do something */; 133 | } 134 | ``` 135 | 136 | 3. 变量命名小写,下划线分隔 137 | 例如: 138 | 139 | ```c 140 | int num_times; 141 | char *pointer; 142 | ``` 143 | 144 | 4. 宏定义全部大写,下划线分隔。宏函数遵守函数命名规则。 145 | 例如: 146 | 147 | ```c 148 | #define PI 3.14 149 | ``` 150 | 151 | 5. typedef定义使用类型名加`_t`后缀(为使结构体或指针类型特征明显,对于结构体或指针请尽量不使用)。 152 | 例如: 153 | 154 | ```c 155 | typedef unsigned int uint32_t; 156 | ``` 157 | 158 | 6. 变量使用时请给出清晰的含义。对于指针当出现不需要写入时,请转换成变量使用。 159 | 例如: 160 | 161 | ```c 162 | void func(int *args) 163 | { 164 | /* 转换成变量,防止意外覆写 */ 165 | int value = *args; 166 | printf("%d\n", value); 167 | } 168 | ``` 169 | 170 | ## 文件名 171 | 172 | 1. 文件名使用小写字母和下划线,不使用大写字母,配置文件以`config`结尾。 173 | 例如: 174 | 175 | ```c 176 | foo_bar.c 177 | test_case.h 178 | mrconfig.h 179 | ``` 180 | 181 | ## 宏 182 | 183 | 1. 宏定义全部大写,下划线分隔,用户可修改的宏配置需加`CFG`标识。 184 | 例如: 185 | 186 | ```c 187 | #define MR_CFG_OBJECT_NAME_SIZE 15 188 | ``` 189 | 190 | # 注释规范 191 | 192 | 1. 单行注释使用`/* */`,多行注释使用: 193 | 194 | ```c 195 | /** 196 | * 多行注释 197 | * 第二行 198 | */ 199 | ``` 200 | 201 | 2. 函数注释使用Doxygen风格: 202 | 203 | ```c 204 | /** 205 | * @brief This function register a device. 206 | * 207 | * @param dev The device. 208 | * @param name The name of the device. 209 | * @param type The type of the device. 210 | * @param flags The support flags of the device. 211 | * @param ops The operations of the device. 212 | * @param drv The driver of the device. 213 | * 214 | * @return 0 on success, otherwise an error code. 215 | */ 216 | ``` 217 | 218 | 3. 结构体,宏等定义需添加注释: 219 | 220 | ```c 221 | /** 222 | * @brief Driver structure. 223 | */ 224 | struct mr_drv 225 | { 226 | uint32_t type; /**< Device type */ 227 | void *ops; /**< Driver operations */ 228 | void *data; /**< Driver data */ 229 | }; 230 | 231 | /** 232 | * @brief Null pointer. 233 | */ 234 | #define MR_NULL (void *)0 235 | ``` 236 | 237 | 4. 函数声明时需用注释将所有同类函数包含: 238 | 239 | ```c 240 | /** 241 | * @addtogroup Device description 242 | * @{ 243 | */ 244 | int mr_dev_open(const char *name, uint32_t flags); 245 | int mr_dev_close(int desc); 246 | ssize_t mr_dev_read(int desc, void *buf, size_t count); 247 | ssize_t mr_dev_write(int desc, const void *buf, size_t count); 248 | int mr_dev_ioctl(int desc, int cmd, void *args); 249 | /** @} */ 250 | ``` 251 | -------------------------------------------------------------------------------- /document/coding_style/coding_style_EN.md: -------------------------------------------------------------------------------- 1 | # Format and Style 2 | 3 | [中文](coding_style.md) 4 | 5 | 6 | * [Format and Style](#format-and-style) 7 | * [Indentation and Line Breaks](#indentation-and-line-breaks) 8 | * [Spaces and Empty Lines](#spaces-and-empty-lines) 9 | * [Header Files](#header-files) 10 | * [Naming Conventions](#naming-conventions) 11 | * [Types](#types) 12 | * [Functions and Variables](#functions-and-variables) 13 | * [File Names](#file-names) 14 | * [Macros](#macros) 15 | * [Comment Conventions](#comment-conventions) 16 | 17 | 18 | ## Indentation and Line Breaks 19 | 20 | 1. Only use 4 spaces for code indentation, tabs are forbidden. 21 | 2. Keep each line of code within 100 characters, break lines and indent the next line by 4 spaces if exceeded. 22 | 3. Braces are defined on a single line, and `if` etc. are used immediately at the end of the line. 23 | For example: 24 | 25 | ````c 26 | if (condition) 27 | { 28 | do_something(); 29 | } 30 | 31 | void func(void) 32 | { 33 | ... 34 | } 35 | ``` 36 | 37 | ## Spaces and Empty Lines 38 | 39 | 1. Add a space on each side of operators, without spaces for pre- / post-increment/decrement. 40 | For example: 41 | 42 | ````c 43 | x = 1; 44 | a + b; 45 | i++; 46 | ``` 47 | 48 | 2. Add a space after commas. 49 | For example: 50 | 51 | ````c 52 | void foo(int a, char b); 53 | ``` 54 | 55 | ## Header Files 56 | 57 | 1. Use the `_FILE_H_` macro to avoid duplicate includes. 58 | 2. Import headers in alphabetical order, with library headers first. Use `<>` for library headers and `""` for other 59 | headers. 60 | For example: 61 | 62 | ````c 63 | #include 64 | #include 65 | #include "bar.h" 66 | #include "foo.h" 67 | ``` 68 | 69 | # Naming Conventions 70 | 71 | ## Types 72 | 73 | 1. Enum types are all lowercase with underscores, enum constants start with uppercase. 74 | For example: 75 | 76 | ````c 77 | enum color_type 78 | { 79 | Red, 80 | Green, 81 | Blue, 82 | Light_Pink, 83 | }; 84 | ``` 85 | 86 | 2. Structures, unions and typedefs are lowercase with underscores. 87 | For example: 88 | 89 | ````c 90 | struct foo 91 | { 92 | char *name; 93 | union coordinate 94 | { 95 | int x; 96 | int y; 97 | } 98 | }; 99 | ``` 100 | 101 | ## Functions and Variables 102 | 103 | 1. Function names are lowercase with underscores. 104 | For example: 105 | 106 | ````c 107 | void do_something(int arg1, char arg2) 108 | { 109 | ... 110 | } 111 | ``` 112 | 113 | 2. Functions should be block written by modules, with comments for large blocks that cannot be easily understood through 114 | code. Returning values without special meaning can be adjacent to other blocks, otherwise they should be single 115 | blocks. 116 | 117 | 3. Variable names are lowercase with underscores. 118 | For example: 119 | 120 | ````c 121 | int num_times; 122 | char *pointer; 123 | ``` 124 | 125 | 4. Macro names are all uppercase with underscores. User configurable macros should have `CFG` prefix. 126 | For example: 127 | 128 | ````c 129 | #define MR_CFG_OBJECT_NAME_SIZE 15 130 | ``` 131 | 132 | 5. Typedefs use the type name with `_t` suffix (avoid for structs/pointers for clarity). 133 | For example: 134 | 135 | ````c 136 | typedef unsigned int uint32_t; 137 | ``` 138 | 139 | 6. Variables should have clear meaning when used. For pointers without writes, convert to variables. 140 | For example: 141 | 142 | ````c 143 | void func(int *args) 144 | { 145 | /* Convert to avoid accidental overwrite */ 146 | int value = *args; 147 | printf("%d\n", value); 148 | } 149 | ``` 150 | 151 | ## File Names 152 | 153 | 1. File names are lowercase with underscores, no uppercase letters, config files end with `config`. 154 | For example: 155 | 156 | ````c 157 | foo_bar.c 158 | test_case.h 159 | mrconfig.h 160 | ``` 161 | 162 | ## Macros 163 | 164 | 1. Macro names are ALL_CAPS with underscores, user configurable macros have `CFG` prefix. 165 | For example: 166 | 167 | ````c 168 | #define MR_CFG_OBJECT_NAME_SIZE 15 169 | ``` 170 | 171 | # Comment Conventions 172 | 173 | 1. Single line comments use `/* */`, multi-line comments: 174 | 175 | ```c 176 | /** 177 | * Multi-line comment 178 | * Second line 179 | */ 180 | ``` 181 | 182 | 2. Function comments use Doxygen style: 183 | 184 | ````c 185 | /** 186 | * @brief This function registers a device. 187 | * 188 | * @param dev The device. 189 | * @param name The name of the device. 190 | * @param type The type of the device. 191 | * @param flags The support flags of the device. 192 | * @param ops The operations of the device. 193 | * @param drv The driver of the device. 194 | * 195 | * @return 0 on success, otherwise an error code. 196 | */ 197 | ``` 198 | 199 | 3. Structs, macros etc need comments: 200 | 201 | ```c 202 | /** 203 | * @brief Driver structure. 204 | */ 205 | struct mr_drv 206 | { 207 | uint32_t type; /**< Device type */ 208 | void *ops; /**< Driver operations */ 209 | void *data; /**< Driver data */ 210 | }; 211 | 212 | /** 213 | * @brief Null pointer. 214 | */ 215 | #define MR_NULL (void *)0 216 | ```` 217 | 218 | 4. Function declarations need comments to include all similar functions: 219 | 220 | ```c 221 | /** 222 | * @addtogroup Device description 223 | * @{ 224 | */ 225 | int mr_dev_open(const char *name, uint32_t flags); 226 | int mr_dev_close(int desc); 227 | ssize_t mr_dev_read(int desc, void *buf, size_t count); 228 | ssize_t mr_dev_write(int desc, const void *buf, size_t count); 229 | int mr_dev_ioctl(int desc, int cmd, void *args); 230 | /** @} */ 231 | ``` -------------------------------------------------------------------------------- /document/components/msh/msh.md: -------------------------------------------------------------------------------- 1 | # MSH组件 2 | 3 | [English](msh_EN.md) 4 | 5 | 6 | * [MSH组件](#msh组件) 7 | * [支持的按键](#支持的按键) 8 | * [命令格式](#命令格式) 9 | * [内置命令](#内置命令) 10 | * [自定义命令](#自定义命令) 11 | * [参数访问](#参数访问) 12 | * [使用示例:](#使用示例) 13 | * [如何使用](#如何使用) 14 | 15 | 16 | `msh` 是 `mr-library`的命令行组件,`msh`是一个命令行解释器,提供用户交互的界面,用户通过在命令行中输入命令和参数,`msh` 17 | 负责解释和执行用户输入的命令。 18 | 19 | ## 支持的按键 20 | 21 | | 按键 | 描述 | 22 | |:------|:----------------| 23 | | 退格键 | 删除当前光标前的字符 | 24 | | 删除键 | 删除当前光标后的字符 | 25 | | 左右方向键 | 向左向右移动光标 | 26 | | Tab键 | 根据光标所在的位置自动补全命令 | 27 | | 回车键 | 运行命令 | 28 | 29 | ## 命令格式 30 | 31 | 所有命令均以空格分隔,格式为: 32 | 33 | `命令 [参数1] [参数2] ... [参数n]` 34 | 35 | ## 内置命令 36 | 37 | `msh`内置了一些基础命令如`help`、`clear`等。 38 | 39 | 启动后使用`help`命令可以查看所有内置命令帮助。 40 | 41 | ```c 42 | msh> help 43 | lsdev - List all devices. 44 | logo - Show the logo. 45 | clear - Clear the screen. 46 | help - Show help information. 47 | ``` 48 | 49 | ## 自定义命令 50 | 51 | 通过内置的宏将命令导出。 52 | 53 | ```c 54 | MR_MSH_CMD_EXPORT(name, fn, help); 55 | ``` 56 | 57 | | 参数 | 描述 | 58 | |:-----|:-------| 59 | | name | 命令名 | 60 | | fn | 命令处理函数 | 61 | | help | 命令帮助描述 | 62 | 63 | 命令处理函数: 64 | 65 | ```c 66 | int cmd_fn(int argc, void *argv) 67 | { 68 | 69 | } 70 | ``` 71 | 72 | | 参数 | 描述 | 73 | |:-----|:-----| 74 | | argc | 参数数量 | 75 | | argv | 参数表 | 76 | 77 | 注:命令处理函数中最后需要输出`\r\n`换行,否则提示词将紧跟在当前行。 78 | 79 | ## 参数访问 80 | 81 | ```c 82 | char *p = MR_MSH_GET_ARG(index); 83 | ``` 84 | 85 | ## 使用示例: 86 | 87 | ```c 88 | void hello_fn(int argc, void *argv) 89 | { 90 | for (size_t i = 1; i <= argc; i++) 91 | { 92 | mr_msh_printf("hello %s\r\n", MR_MSH_GET_ARG(i)); 93 | } 94 | return MR_EOK; 95 | } 96 | MR_MSH_CMD_EXPORT(hello, hello_fn, "Hello every one"); 97 | ``` 98 | 99 | 运行`hello`命令: 100 | 101 | ```c 102 | msh> hello 1 2 3 4 103 | hello 1 104 | hello 2 105 | hello 3 106 | hello 4 107 | msh> 108 | ``` 109 | 110 | ## 如何使用 111 | 112 | ```c 113 | int main(void) 114 | { 115 | /* 自动初始化 */ 116 | mr_auto_init(); 117 | 118 | while(1) 119 | { 120 | /* msh处理 */ 121 | mr_msh_handle(); 122 | } 123 | } 124 | ``` 125 | -------------------------------------------------------------------------------- /document/components/msh/msh_EN.md: -------------------------------------------------------------------------------- 1 | # MSH Component 2 | 3 | [中文](msh.md) 4 | 5 | 6 | * [MSH Component](#msh-component) 7 | * [Supported Keys](#supported-keys) 8 | * [Command Format](#command-format) 9 | * [Built-in Commands](#built-in-commands) 10 | * [Custom Commands](#custom-commands) 11 | * [Parameter Access](#parameter-access) 12 | * [Usage Example:](#usage-example) 13 | * [How to use](#how-to-use) 14 | 15 | 16 | The `msh` is a command line component of the `mr-library`. `msh` is a command line interpreter that provides a user 17 | interface for interaction. Users can input commands and parameters in the command line to have `msh` interpret and 18 | execute the user input commands. 19 | 20 | ## Supported Keys 21 | 22 | | Key | Description | 23 | |------------------|-----------------------------------------------------------| 24 | | Backspace | Delete the character before the cursor | 25 | | Delete | Delete the character after the cursor | 26 | | Left/Right Arrow | Move the cursor left and right | 27 | | Tab | Autocomplete the command according to the cursor position | 28 | | Enter | Run the command | 29 | 30 | ## Command Format 31 | 32 | All commands are separated by spaces, in the format of: 33 | 34 | `command [param1] [param2] ... [paramn]` 35 | 36 | ## Built-in Commands 37 | 38 | `msh` has some basic built-in commands such as `help` and `clear`. 39 | 40 | Use the `help` command after startup to view help information for all built-in commands. 41 | 42 | ```c 43 | msh> help 44 | lsdev - List all devices. 45 | logo - Show the logo. 46 | clear - Clear the screen. 47 | help - Show help information. 48 | ``` 49 | 50 | ## Custom Commands 51 | 52 | Export commands through built-in macros. 53 | 54 | ```c 55 | MR_MSH_CMD_EXPORT(name, fn, help); 56 | ``` 57 | 58 | | Parameter | Description | 59 | |-----------|---------------------------| 60 | | name | Command name | 61 | | fn | Command handling function | 62 | | help | Command help description | 63 | 64 | Command handling function: 65 | 66 | ```c 67 | int cmd_fn(int argc, void *argv) 68 | { 69 | 70 | } 71 | ``` 72 | 73 | | Parameter | Description | 74 | |-----------|----------------------| 75 | | argc | Number of parameters | 76 | | argv | Parameter table | 77 | 78 | Note: The command handling function needs to output `\r\n` at the end, otherwise the prompt will follow the current 79 | line. 80 | 81 | ## Parameter Access 82 | 83 | ```c 84 | char *p = MR_MSH_GET_ARG(index); 85 | ``` 86 | 87 | ## Usage Example: 88 | 89 | ```c 90 | void hello_fn(int argc, void *argv) 91 | { 92 | for (size_t i = 1; i <= argc; i++) 93 | { 94 | mr_msh_printf("hello %s\r\n", MR_MSH_GET_ARG(i)); 95 | } 96 | return MR_EOK; 97 | } 98 | MR_MSH_CMD_EXPORT(hello, hello_fn, "Hello every one"); 99 | ``` 100 | 101 | Run the `hello` command: 102 | 103 | ```c 104 | msh> hello 1 2 3 4 105 | hello 1 106 | hello 2 107 | hello 3 108 | hello 4 109 | msh> 110 | ``` 111 | 112 | ## How to use 113 | 114 | ```c 115 | int main(void) 116 | { 117 | /* Automatic initialization */ 118 | mr_auto_init(); 119 | 120 | while(1) 121 | { 122 | /* msh processing */ 123 | mr_msh_handle(); 124 | } 125 | } 126 | ``` 127 | -------------------------------------------------------------------------------- /document/components/msh/msh_device.md: -------------------------------------------------------------------------------- 1 | # msh-device使用教程 2 | 3 | ## 查看设备列表 4 | 首先,您需要了解系统中已注册的设备。这可以通过`dlist`命令完成。该命令将显示设备的类型(只读、只写、可读写等)以及设备路径。 5 | 6 | ```bash 7 | dlist 8 | ``` 9 | 10 | 输出将类似于: 11 | ``` 12 | msh /> dlist 13 | |----- dev 14 | |-r--- adc1 15 | |-r--- adc2 16 | |--w-- dac1 17 | |-rw-- pin 18 | |-rw-- pwm1 19 | |-rw-- pwm2 20 | |-rwn- serial1 [0] 21 | |-rwn- serial2 22 | |-rwn- serial3 23 | |-rw-- spi1 24 | |-rw-- spi2 25 | |-rw-- timer1 26 | |-rw-- timer2 27 | |-rw-- timer3 28 | |-rw-- i2c1 29 | |-rw-- i2c10 30 | |-rw-- i2c11 31 | msh /> 32 | ``` 33 | 34 | 前缀为设备支持的打开方式:`-r---` 只读、`--w--`只写、`-rw--`可读可写、`-rwn-`可非阻塞读写。 35 | 36 | 中间为设备名,按树状结构拼成完整路径,以 `i2c10` 设备为例,完整路径为:`/dev/i2c1/i2c10` , 可省略`dev`路径为 `i2c1/i2c10`。 37 | 38 | 后缀为设备描述符(后面会介绍)。 39 | 40 | ## 打开设备 41 | 42 | 要开始与设备交互,您需要先打开它。使用`dopen`命令,指定设备路径和打开模式(只读`r`、只写`w`、可读写`rw`、非阻塞 `-n`)。 43 | 44 | ```bash 45 | dopen [-n] 46 | ``` 47 | 48 | `<>` 必要参数,`[]`可选参数。 49 | 50 | - `path`:设备路径 51 | - `r`:只读 52 | - `w`:只写 53 | - `rw`:可读可写 54 | - `-g`:获取设备支持的打开方式 55 | - `-n`:非阻塞 56 | 57 | 以只读方式打开`adc1`设备。如果成功,输出将类似于: 58 | 59 | ``` 60 | msh /> dopen adc1 r 61 | msh /dev/adc1/-1> 62 | ``` 63 | 64 | 当正确打开命令后,`msh` 后将显示当前持有的设备路径 `/dev/adc1/-1`,最后的 `-1` 为当前的写入位置(对于`adc`设备而言是写入通道)。 65 | 66 | ## 配置设备 67 | 68 | 在读取或写入数据之前,您可能需要配置设备。使用`dioctl`命令来设置设备参数。 69 | 70 | ```bash 71 | dioctl 72 | dioctl pos 73 | dioctl cfg 74 | dioctl bufsz =0)|-g> <-r|-w> 75 | dioctl datasz <-c|-g> <-r|-w> 76 | ``` 77 | 78 | 标准格式为: 79 | 80 | - `cmd`:命令 81 | - `args`:参数 82 | - `-g`:获取设备参数 83 | 84 | 为方便操作,内置了一些常用命令: 85 | 86 | - `pos`:设置读写位置 87 | - `position`:读写位置 88 | - `-g`:获取读写位置 89 | 90 | 91 | - `cfg`:设置配置 92 | - `args`:配置参数 93 | - `-g`:获取配置参数 94 | 95 | 96 | - `bufsz`:设置缓冲区大小 97 | - `bufsz`:缓冲区大小 98 | - `-g`:获取缓冲区大小 99 | 100 | 101 | - `datasz`:设置数据大小 102 | - `-c`:字符数据 103 | - `-g`:获取数据大小 104 | 105 | 106 | 通过 `dioctl` 先设置写入位置 `pos` ,设置为通道`1`,此时路径变更为 `/dev/adc1/1`。同时通过`cfg -g`获取配置,配置通道`1`使能。 107 | 108 | ```bash 109 | msh /dev/adc1/-1> dioctl pos 1 110 | msh /dev/adc1/1> dioctl cfg -g 111 | 0 112 | msh /dev/adc1/1> dioctl cfg 1 113 | msh /dev/adc1/1> 114 | ``` 115 | 116 | ## 读取数据 117 | 118 | 使用`dread`命令从设备读取数据。您需要指定要读取的数据个数、单个数据字节长度和数据类型。 119 | 120 | ```bash 121 | dread [-1|-2|-4] [-x|-d|-u|-c] 122 | [-1]: 123 | [-2]: 124 | [-4]: 125 | ``` 126 | 127 | - `count`:要读取的数据个数 128 | - `-1|-2|-4`:单个数据字节长度 129 | - `-x|-d|-u|-c`:数据类型 130 | 131 | `count` 在单个数据字节长度不同时范围不同,单次读取缓冲区为 `128Byte` 132 | 133 | ```bash 134 | msh /dev/adc1/1> dread 10 -4 -d 135 | 729 592 506 454 416 394 377 366 360 356 136 | msh /dev/adc1/1> 137 | ``` 138 | 139 | ## 关闭设备 140 | 141 | 由于`adc`设备不支持写入,所以我们可以先关闭他(当然这不是必须的,后面会讲到其他方法)。 142 | 143 | 要关闭当前的设备直接使用`dclose`,当需要关闭其他设备时可以添加一个`desc`描述符参数(可能你还不了解描述符概念,不过没有关系,下文会详细介绍)。 144 | 145 | ```bash 146 | dclose [desc (>=0)] 147 | ``` 148 | 149 | - `desc`:设备描述符 150 | 151 | ```bash 152 | msh /dev/adc1/1> dclose 153 | msh /> 154 | ``` 155 | 156 | ## 写入数据 157 | 158 | 要向设备写入数据,使用`dwrite`命令。 159 | 160 | ```bash 161 | dwrite [-1|-2|-4] [-x|-d|-u|-c] 162 | ``` 163 | 164 | - `-1|-2|-4`:单个数据字节长度 165 | - `-x|-d|-u|-c`:数据类型 166 | - `data`:要写入的数据 167 | 168 | 先打开一个串口设备,为方便演示此处使用`msh`使用的串口1,通过`dwrite`写入数据,`-c`为数据类型,写入数据为`hello`直接打印在终端上。 169 | 170 | ```bash 171 | msh /> dopen serial1 rw 172 | msh /dev/serial1/-1> dioctl cfg -g 173 | 115200 8 1 0 0 0 174 | msh /dev/serial1/-1> dwrite -c h e l l o 175 | hellomsh /dev/serial1/-1> 176 | ``` 177 | 178 | ## 切换设备 179 | 180 | 在不关闭当前设备的情况下切换到其他设备,可以使用`dselect`命令。这允许您在多个设备之间快速切换。 181 | 182 | ```bash 183 | dselect =0)|-g> 184 | ``` 185 | 186 | - `desc`:设备描述符 187 | - `-g`:获取当前设备描述符 188 | 189 | 上文中我们做了一次`adc`切换到`serial1`设备,但是需要先关闭`adc`设备,这对于使用还是过于麻烦了,不过在此之前需要先介绍一下描述符。 190 | 191 | ### 描述符 192 | 193 | 可能用过文件系统的比较了解文件描述符,设备描述符也是类似的概念。 194 | 195 | 当打开设备(`dopen`)时,系统会自动分配一个描述符给用户使用,描述符记录了`操作的设备`、当前用户的`读写权限`、当前用户的`操作位置`等信息。 196 | 持有当前的描述符即代表着一个设备的使用者,拥有使用者的一切信息。 197 | 198 | 一个设备可以有无限的使用者(`描述符`),而 `msh` 拥有着最高权限(`坐在电脑面前的你`),可以任意使用其他用户的描述符, 199 | 可能是你刚刚打开的或者是代码中正在运行程序的描述符(`没错,作为上帝的你可以切换到这个描述符然后关掉它,你甚至可以关掉msh所使用的描述符,然后你的设备就和你失联了`)。 200 | 201 | 我们可以先`dlist`查看一下现在的设备,会发现和最初先比`serial1`后面的描述符多了`[1]`,也就是我们现在所持有的描述符。 202 | 203 | ```bash 204 | msh /> dlist 205 | |----- dev 206 | |-r--- adc1 207 | |-r--- adc2 208 | |--w-- dac1 209 | |-rw-- pin 210 | |-rw-- pwm1 211 | |-rw-- pwm2 212 | |-rwn- serial1 [0] [1] 213 | |-rwn- serial2 214 | |-rwn- serial3 215 | |-rw-- spi1 216 | |-rw-- spi2 217 | |-rw-- timer1 218 | |-rw-- timer2 219 | |-rw-- timer3 220 | |-rw-- i2c1 221 | |-rw-- i2c10 222 | |-rw-- i2c11 223 | msh /> 224 | ``` 225 | 226 | 我们可以先打开一下`pin`设备,然后再`dlist`查看一下: 227 | 228 | ```bash 229 | msh /> dlist 230 | |----- dev 231 | |-r--- adc1 232 | |-r--- adc2 233 | |--w-- dac1 234 | |-rw-- pin [2] 235 | |-rw-- pwm1 236 | |-rw-- pwm2 237 | |-rwn- serial1 [0] [1] 238 | |-rwn- serial2 239 | |-rwn- serial3 240 | |-rw-- spi1 241 | |-rw-- spi2 242 | |-rw-- timer1 243 | |-rw-- timer2 244 | |-rw-- timer3 245 | |-rw-- i2c1 246 | |-rw-- i2c10 247 | |-rw-- i2c11 248 | msh /> 249 | ``` 250 | 251 | 可以看到`pin`设备后多了`[2]`,就是我们刚打开分配的描述符。 252 | 253 | ```bash 254 | msh /dev/pin/-1> dselect 1 255 | msh /dev/serial1/-1> dselect -g 256 | 1 257 | msh /dev/serial1/-1> 258 | ``` 259 | 260 | 通过 `dselect` 命令可以不关闭当前设备的情况下切换到之前使用的`serial1`设备,使用 `-g` 可以获取当前使用的描述符。 261 | -------------------------------------------------------------------------------- /document/device/adc/adc.md: -------------------------------------------------------------------------------- 1 | # ADC设备 2 | 3 | [English](adc_EN.md) 4 | 5 | 6 | * [ADC设备](#adc设备) 7 | * [打开ADC设备](#打开adc设备) 8 | * [关闭ADC设备](#关闭adc设备) 9 | * [控制ADC设备](#控制adc设备) 10 | * [设置/获取通道编号](#设置获取通道编号) 11 | * [设置/获取通道配置](#设置获取通道配置) 12 | * [读取ADC设备通道值](#读取adc设备通道值) 13 | * [使用示例:](#使用示例) 14 | 15 | 16 | ## 打开ADC设备 17 | 18 | ```c 19 | int mr_dev_open(const char *path, int flags); 20 | ``` 21 | 22 | | 参数 | 描述 | 23 | |---------|---------| 24 | | path | 设备路径 | 25 | | flags | 打开设备的标志 | 26 | | **返回值** | | 27 | | `>=0` | 设备描述符 | 28 | | `<0` | 错误码 | 29 | 30 | - `path`:ADC设备路径一般为:`adcx`、`adc1`、`adc2`。 31 | - `flags`:打开设备的标志,支持 `MR_O_RDONLY`。 32 | 33 | 注:使用时应根据实际情况为不同的任务分别打开ADC设备,并使用适当的`flags`进行管理和权限控制,以确保它们不会相互影响。 34 | 35 | ## 关闭ADC设备 36 | 37 | ```c 38 | int mr_dev_close(int desc); 39 | ``` 40 | 41 | | 参数 | 描述 | 42 | |---------|-------| 43 | | desc | 设备描述符 | 44 | | **返回值** | | 45 | | `=0` | 关闭成功 | 46 | | `<0` | 错误码 | 47 | 48 | 注:关闭设备时所有的通道都将被自动恢复到默认配置,重新打开后需要重新配置通道(可关闭此功能)。 49 | 50 | ## 控制ADC设备 51 | 52 | ```c 53 | int mr_dev_ioctl(int desc, int cmd, void *args); 54 | ``` 55 | 56 | | 参数 | 描述 | 57 | |---------|-------| 58 | | desc | 设备描述符 | 59 | | cmd | 命令码 | 60 | | args | 命令参数 | 61 | | **返回值** | | 62 | | `=0` | 设置成功 | 63 | | `<0` | 错误码 | 64 | 65 | - `cmd`:命令码,支持以下命令: 66 | - `MR_IOC_ADC_SET_CHANNEL`:设置通道编号。 67 | - `MR_IOC_ADC_SET_CHANNEL_CONFIG`:设置通道配置。 68 | - `MR_IOC_ADC_GET_CHANNEL`:获取通道编号。 69 | - `MR_IOC_ADC_GET_CHANNEL_CONFIG`:获取通道配置。 70 | 71 | ### 设置/获取通道编号 72 | 73 | 通道编号范围:`0` ~ `31`。 74 | 75 | ```c 76 | /* 定义通道编号 */ 77 | #define CHANNEL_NUMBER 5 78 | 79 | /* 设置通道编号 */ 80 | mr_dev_ioctl(ds, MR_IOC_ADC_SET_CHANNEL, MR_MAKE_LOCAL(int, CHANNEL_NUMBER)); 81 | 82 | /* 获取通道编号 */ 83 | int number; 84 | mr_dev_ioctl(ds, MR_IOC_ADC_GET_CHANNEL, &number); 85 | ``` 86 | 87 | 不依赖ADC接口: 88 | 89 | ```c 90 | /* 定义通道编号 */ 91 | #define CHANNEL_NUMBER 5 92 | 93 | /* 设置通道编号 */ 94 | mr_dev_ioctl(ds, MR_IOC_SPOS, MR_MAKE_LOCAL(int, CHANNEL_NUMBER)); 95 | 96 | /* 获取通道编号 */ 97 | int number; 98 | mr_dev_ioctl(ds, MR_IOC_GPOS, &number); 99 | ``` 100 | 101 | ### 设置/获取通道配置 102 | 103 | 通道配置: 104 | 105 | - `MR_DISABLE`:禁用通道。 106 | - `MR_ENABLE`:启用通道。 107 | 108 | ```c 109 | /* 设置通道配置 */ 110 | mr_dev_ioctl(ds, MR_IOC_ADC_SET_CHANNEL_CONFIG, MR_MAKE_LOCAL(int, MR_ENABLE)); 111 | 112 | /* 获取通道配置 */ 113 | int state; 114 | mr_dev_ioctl(ds, MR_IOC_ADC_GET_CHANNEL_CONFIG, &state); 115 | ``` 116 | 117 | 不依赖ADC接口: 118 | 119 | ```c 120 | /* 设置通道配置 */ 121 | mr_dev_ioctl(ds, MR_IOC_SCFG, MR_MAKE_LOCAL(int, MR_ENABLE)); 122 | 123 | /* 获取通道配置 */ 124 | int state; 125 | mr_dev_ioctl(ds, MR_IOC_GCFG, &state); 126 | ``` 127 | 128 | ## 读取ADC设备通道值 129 | 130 | ```c 131 | ssize_t mr_dev_read(int desc, void *buf, size_t count); 132 | ``` 133 | 134 | | 参数 | 描述 | 135 | |---------|---------| 136 | | desc | 设备描述符 | 137 | | buf | 读取数据缓冲区 | 138 | | count | 读取数据大小 | 139 | | **返回值** | | 140 | | `>=0` | 读取数据大小 | 141 | | `<0` | 错误码 | 142 | 143 | ```c 144 | /* 读取通道值 */ 145 | uint32_t data; 146 | int ret = mr_dev_read(ds, &data, sizeof(data)); 147 | /* 是否读取成功 */ 148 | if (ret != sizeof(data)) 149 | { 150 | return ret; 151 | } 152 | ``` 153 | 154 | 注:读取数据为ADC原始数据。单次读取最小单位为`uint32_t`,即4个字节。 155 | 156 | ## 使用示例: 157 | 158 | ```c 159 | #include "include/mr_lib.h" 160 | 161 | /* 定义通道编号 */ 162 | #define CHANNEL_NUMBER 5 163 | 164 | /* 定义ADC设备描述符 */ 165 | int adc_ds = -1; 166 | 167 | void adc_init(void) 168 | { 169 | int ret = MR_EOK; 170 | 171 | /* 初始化ADC */ 172 | adc_ds = mr_dev_open("adc1", MR_O_RDONLY); 173 | if (adc_ds < 0) 174 | { 175 | mr_printf("ADC1 open failed: %s\r\n", mr_strerror(adc_ds)); 176 | return; 177 | } 178 | /* 打印ADC描述符 */ 179 | mr_printf("ADC1 desc: %d\r\n", adc_ds); 180 | /* 设置到通道5 */ 181 | mr_dev_ioctl(adc_ds, MR_IOC_ADC_SET_CHANNEL, MR_MAKE_LOCAL(int, CHANNEL_NUMBER)); 182 | /* 设置通道使能 */ 183 | ret = mr_dev_ioctl(adc_ds, MR_IOC_ADC_SET_CHANNEL_CONFIG, MR_MAKE_LOCAL(int, MR_ENABLE)); 184 | if (ret < 0) 185 | { 186 | mr_printf("Channel5 enable failed: %s\r\n", mr_strerror(ret)); 187 | } 188 | } 189 | /* 导出到自动初始化(APP级) */ 190 | MR_INIT_APP_EXPORT(adc_init); 191 | 192 | int main(void) 193 | { 194 | /* 自动初始化(adc_init函数将在此处自动调用) */ 195 | mr_auto_init(); 196 | 197 | while(1) 198 | { 199 | uint32_t data; 200 | int ret = mr_dev_read(adc_ds, &data, sizeof(data)); 201 | if (ret != sizeof(data)) 202 | { 203 | mr_printf("Read failed: %s\r\n", mr_strerror(ret)); 204 | } 205 | mr_printf("ADC value: %d\r\n", data); 206 | mr_delay_ms(1000); 207 | } 208 | } 209 | ``` 210 | 211 | ADC1通道5使能,间隔一秒读取一次ADC值并打印。 212 | -------------------------------------------------------------------------------- /document/device/adc/adc_EN.md: -------------------------------------------------------------------------------- 1 | # ADC Device 2 | 3 | [中文](adc.md) 4 | 5 | 6 | * [ADC Device](#adc-device) 7 | * [Open ADC Device](#open-adc-device) 8 | * [Close ADC Device](#close-adc-device) 9 | * [Control ADC Device](#control-adc-device) 10 | * [Set/Get Channel Number](#setget-channel-number) 11 | * [Set/Get Channel Configure](#setget-channel-configure) 12 | * [Read ADC Device Channel Value](#read-adc-device-channel-value) 13 | * [Usage Example:](#usage-example) 14 | 15 | 16 | ## Open ADC Device 17 | 18 | ```c 19 | int mr_dev_open(const char *path, int flags); 20 | ``` 21 | 22 | | Parameter | Description | 23 | |:----------------:|:-----------------:| 24 | | path | Device path | 25 | | flags | Open device flags | 26 | | **Return Value** | | 27 | | `>=0` | Device descriptor | 28 | | `<0` | Error code | 29 | 30 | - `path`: ADC device path usually is: `adcx`, `adc1`, `adc2`. 31 | - `flags`: Open device flags, support `MR_O_RDONLY`. 32 | 33 | Note: When using, the ADC device should be opened separately for different tasks according to actual situations, and the 34 | appropriate `flags` should be used for management and permission control to ensure they will not interfere with each 35 | other. 36 | 37 | ## Close ADC Device 38 | 39 | ```c 40 | int mr_dev_close(int desc); 41 | ``` 42 | 43 | | Parameter | Description | 44 | |------------------|--------------------| 45 | | desc | Device descriptor | 46 | | **Return Value** | | 47 | | `=0` | Close successfully | 48 | | `<0` | Error code | 49 | 50 | Note: When closing the device, all channels will be automatically restored to the default state. The channel needs to be 51 | reconfigured after reopening(This feature can be turned off). 52 | 53 | ## Control ADC Device 54 | 55 | ```c 56 | int mr_dev_ioctl(int desc, int cmd, void *args); 57 | ``` 58 | 59 | | Parameter | Description | 60 | |------------------|--------------------| 61 | | desc | Device descriptor | 62 | | cmd | Command code | 63 | | args | Command parameters | 64 | | **Return Value** | | 65 | | `=0` | Set successfully | 66 | | `<0` | Error code | 67 | 68 | - `cmd`: Command code, supports the following commands: 69 | - `MR_IOC_ADC_SET_CHANNEL`: Set channel number. 70 | - `MR_IOC_ADC_SET_CHANNEL_CONFIG`: Set channel configure. 71 | - `MR_IOC_ADC_GET_CHANNEL`: Get channel number. 72 | - `MR_IOC_ADC_GET_CHANNEL_CONFIG`: Get channel configure. 73 | 74 | ### Set/Get Channel Number 75 | 76 | Channel number range: `0` ~ `31`. 77 | 78 | ```c 79 | /* Define channel number */ 80 | #define CHANNEL_NUMBER 5 81 | 82 | /* Set channel number */ 83 | mr_dev_ioctl(ds, MR_IOC_ADC_SET_CHANNEL, MR_MAKE_LOCAL(int, CHANNEL_NUMBER)); 84 | 85 | /* Get channel number */ 86 | int number; 87 | mr_dev_ioctl(ds, MR_IOC_ADC_GET_CHANNEL, &number); 88 | ``` 89 | 90 | Independent of ADC interface: 91 | 92 | ```c 93 | /* Define channel number */ 94 | #define CHANNEL_NUMBER 5 95 | 96 | /* Set channel number */ 97 | mr_dev_ioctl(ds, MR_IOC_SPOS, MR_MAKE_LOCAL(int, CHANNEL_NUMBER)); 98 | 99 | /* Get channel number */ 100 | int number; 101 | mr_dev_ioctl(ds, MR_IOC_GPOS, &number); 102 | ``` 103 | 104 | ### Set/Get Channel Configure 105 | 106 | Channel configure: 107 | 108 | - `MR_DISABLE`: Disable channel. 109 | - `MR_ENABLE`: Enable channel. 110 | 111 | ```c 112 | /* Set channel configure */ 113 | mr_dev_ioctl(ds, MR_IOC_ADC_SET_CHANNEL_CONFIG, MR_MAKE_LOCAL(int, MR_ENABLE)); 114 | 115 | /* Get channel configure */ 116 | int state; 117 | mr_dev_ioctl(ds, MR_IOC_ADC_GET_CHANNEL_CONFIG, &state); 118 | ``` 119 | 120 | Independent of ADC interface: 121 | 122 | ```c 123 | /* Set channel configure */ 124 | mr_dev_ioctl(ds, MR_IOC_SCFG, MR_MAKE_LOCAL(int, MR_ENABLE)); 125 | 126 | /* Get channel configure */ 127 | int state; 128 | mr_dev_ioctl(ds, MR_IOC_GCFG, &state); 129 | ``` 130 | 131 | ## Read ADC Device Channel Value 132 | 133 | ```c 134 | ssize_t mr_dev_read(int desc, void *buf, size_t count); 135 | ``` 136 | 137 | | Parameter | Description | 138 | |------------------|-------------------| 139 | | | | 140 | | desc | Device descriptor | 141 | | buf | Read data buffer | 142 | | count | Read data size | 143 | | **Return Value** | | 144 | | `>=0` | Read data size | 145 | | `<0` | Error code | 146 | 147 | ```c 148 | /* Read channel value */ 149 | uint32_t data; 150 | int ret = mr_dev_read(ds, &data, sizeof(data)); 151 | /* Check if read successfully */ 152 | if (ret != sizeof(data)) 153 | { 154 | return ret; 155 | } 156 | ``` 157 | 158 | Note: The read data is the raw ADC data. The minimum read unit is `uint32_t`, that is, 4 bytes each time. 159 | 160 | ## Usage Example: 161 | 162 | ```c 163 | #include "include/mr_lib.h" 164 | 165 | /* Define channel number */ 166 | #define CHANNEL_NUMBER 5 167 | 168 | /* Define ADC device descriptor */ 169 | int adc_ds = -1; 170 | 171 | void adc_init(void) 172 | { 173 | int ret = MR_EOK; 174 | 175 | /* Initialize ADC */ 176 | adc_ds = mr_dev_open("adc1", MR_O_RDONLY); 177 | if (adc_ds < 0) 178 | { 179 | mr_printf("ADC1 open failed: %s\r\n", mr_strerror(adc_ds)); 180 | return; 181 | } 182 | /* Print ADC descriptor */ 183 | mr_printf("ADC1 desc: %d\r\n", adc_ds); 184 | /* Set to channel 5 */ 185 | mr_dev_ioctl(adc_ds, MR_IOC_ADC_SET_CHANNEL, MR_MAKE_LOCAL(int, CHANNEL_NUMBER)); 186 | /* Set channel enable */ 187 | ret = mr_dev_ioctl(adc_ds, MR_IOC_ADC_SET_CHANNEL_CONFIG, MR_MAKE_LOCAL(int, MR_ENABLE)); 188 | if (ret < 0) 189 | { 190 | mr_printf("Channel5 enable failed: %s\r\n", mr_strerror(ret)); 191 | } 192 | } 193 | /* Export to automatic initialization (APP level) */ 194 | MR_INIT_APP_EXPORT(adc_init); 195 | 196 | int main(void) 197 | { 198 | /* Automatic initialization (adc_init function will be automatically called here) */ 199 | mr_auto_init(); 200 | 201 | while(1) 202 | { 203 | uint32_t data; 204 | int ret = mr_dev_read(adc_ds, &data, sizeof(data)); 205 | if (ret != sizeof(data)) 206 | { 207 | mr_printf("Read failed: %s\r\n", mr_strerror(ret)); 208 | } 209 | mr_printf("ADC value: %d\r\n", data); 210 | mr_delay_ms(1000); 211 | } 212 | } 213 | ``` 214 | 215 | Enable ADC1 channel 5, read the ADC value every second and print it. 216 | -------------------------------------------------------------------------------- /document/device/dac/dac.md: -------------------------------------------------------------------------------- 1 | # DAC设备 2 | 3 | [English](dac_EN.md) 4 | 5 | 6 | * [DAC设备](#dac设备) 7 | * [打开DAC设备](#打开dac设备) 8 | * [关闭DAC设备](#关闭dac设备) 9 | * [控制DAC设备](#控制dac设备) 10 | * [设置/获取通道编号](#设置获取通道编号) 11 | * [设置/获取通道配置](#设置获取通道配置) 12 | * [写入DAC设备通道值](#写入dac设备通道值) 13 | * [使用示例:](#使用示例) 14 | 15 | 16 | ## 打开DAC设备 17 | 18 | ```c 19 | int mr_dev_open(const char *path, int flags); 20 | ``` 21 | 22 | | 参数 | 描述 | 23 | |---------|---------| 24 | | path | 设备路径 | 25 | | flags | 打开设备的标志 | 26 | | **返回值** | | 27 | | `>=0` | 设备描述符 | 28 | | `<0` | 错误码 | 29 | 30 | - `path`:DAC设备路径一般为:`dacx`、`dac1`、`dac2`。 31 | - `flags`:打开设备的标志,支持 `MR_O_WRONLY`。 32 | 33 | 注:使用时应根据实际情况为不同的任务分别打开DAC设备,并使用适当的`flags`进行管理和权限控制,以确保它们不会相互影响。 34 | 35 | ## 关闭DAC设备 36 | 37 | ```c 38 | int mr_dev_close(int desc); 39 | ``` 40 | 41 | | 参数 | 描述 | 42 | |---------|-------| 43 | | desc | 设备描述符 | 44 | | **返回值** | | 45 | | `=0` | 关闭成功 | 46 | | `<0` | 错误码 | 47 | 48 | 注:关闭设备时所有的通道都将被自动恢复到默认状态,重新打开后需要重新配置通道(可关闭此功能)。 49 | 50 | ## 控制DAC设备 51 | 52 | ```c 53 | int mr_dev_ioctl(int desc, int cmd, void *args); 54 | ``` 55 | 56 | | 参数 | 描述 | 57 | |---------|-------| 58 | | desc | 设备描述符 | 59 | | cmd | 命令码 | 60 | | args | 命令参数 | 61 | | **返回值** | | 62 | | `=0` | 设置成功 | 63 | | `<0` | 错误码 | 64 | 65 | - `cmd`:命令码,支持以下命令: 66 | - `MR_IOC_DAC_SET_CHANNEL`:设置通道编号。 67 | - `MR_IOC_DAC_SET_CHANNEL_CONFIG`:设置通道配置。 68 | - `MR_IOC_DAC_GET_CHANNEL`:获取通道编号。 69 | - `MR_IOC_DAC_GET_CHANNEL_CONFIG`:获取通道配置。 70 | 71 | ### 设置/获取通道编号 72 | 73 | 通道编号范围:`0` ~ `31`。 74 | 75 | ```c 76 | /* 定义通道编号 */ 77 | #define CHANNEL_NUMBER 5 78 | 79 | /* 设置通道编号 */ 80 | mr_dev_ioctl(ds, MR_IOC_DAC_SET_CHANNEL, MR_MAKE_LOCAL(int, CHANNEL_NUMBER)); 81 | 82 | /* 获取通道编号 */ 83 | int number; 84 | mr_dev_ioctl(ds, MR_IOC_DAC_GET_CHANNEL, &number); 85 | ``` 86 | 87 | 不依赖DAC接口: 88 | 89 | ```c 90 | /* 定义通道编号 */ 91 | #define CHANNEL_NUMBER 5 92 | 93 | /* 设置通道编号 */ 94 | mr_dev_ioctl(ds, MR_IOC_SPOS, MR_MAKE_LOCAL(int, CHANNEL_NUMBER)); 95 | 96 | /* 获取通道编号 */ 97 | int number; 98 | mr_dev_ioctl(ds, MR_IOC_GPOS, &number); 99 | ``` 100 | 101 | ### 设置/获取通道配置 102 | 103 | 通道配置: 104 | 105 | - `MR_DISABLE`:禁用通道。 106 | - `MR_ENABLE`:启用通道。 107 | 108 | ```c 109 | /* 设置通道配置 */ 110 | mr_dev_ioctl(ds, MR_IOC_DAC_SET_CHANNEL_CONFIG, MR_MAKE_LOCAL(int, MR_ENABLE)); 111 | 112 | /* 获取通道配置 */ 113 | int state; 114 | mr_dev_ioctl(ds, MR_IOC_DAC_GET_CHANNEL_CONFIG, &state); 115 | ``` 116 | 117 | 不依赖DAC接口: 118 | 119 | ```c 120 | /* 设置通道配置 */ 121 | mr_dev_ioctl(ds, MR_IOC_SCFG, MR_MAKE_LOCAL(int, MR_ENABLE)); 122 | 123 | /* 获取通道配置 */ 124 | int state; 125 | mr_dev_ioctl(ds, MR_IOC_GCFG, &state); 126 | ``` 127 | 128 | ## 写入DAC设备通道值 129 | 130 | ```c 131 | ssize_t mr_dev_write(int desc, const void *buf, size_t count); 132 | ``` 133 | 134 | | 参数 | 描述 | 135 | |---------|---------| 136 | | desc | 设备描述符 | 137 | | buf | 写入数据缓冲区 | 138 | | count | 写入数据大小 | 139 | | **返回值** | | 140 | | `>=0` | 写入数据大小 | 141 | | `<0` | 错误码 | 142 | 143 | ```c 144 | /* 写入通道值 */ 145 | uint32_t data = 2048; 146 | int ret = mr_dev_write(ds, &data, sizeof(data)); 147 | /* 是否写入成功 */ 148 | if (ret != sizeof(data)) 149 | { 150 | return ret; 151 | } 152 | ``` 153 | 154 | 注:写入数据为DAC原始数据。单次写入最小单位为`uint32_t`,即4个字节。 155 | 156 | ## 使用示例: 157 | 158 | ```c 159 | #include "include/mr_lib.h" 160 | 161 | /* 定义通道编号 */ 162 | #define CHANNEL_NUMBER 1 163 | 164 | /* 定义DAC设备描述符 */ 165 | int dac_ds = -1; 166 | 167 | void dac_init(void) 168 | { 169 | int ret = MR_EOK; 170 | 171 | /* 初始化DAC */ 172 | dac_ds = mr_dev_open("dac1", MR_O_WRONLY); 173 | if (dac_ds < 0) 174 | { 175 | mr_printf("DAC1 open failed: %s\r\n", mr_strerror(dac_ds)); 176 | return; 177 | } 178 | /* 打印DAC描述符 */ 179 | mr_printf("DAC1 desc: %d\r\n", dac_ds); 180 | /* 设置到通道1 */ 181 | mr_dev_ioctl(dac_ds, MR_IOC_DAC_SET_CHANNEL, MR_MAKE_LOCAL(int, CHANNEL_NUMBER)); 182 | /* 设置通道使能 */ 183 | ret = mr_dev_ioctl(dac_ds, MR_IOC_DAC_SET_CHANNEL_CONFIG, MR_MAKE_LOCAL(int, MR_ENABLE)); 184 | if (ret < 0) 185 | { 186 | mr_printf("Channel%d enable failed: %s\r\n", CHANNEL_NUMBER, mr_strerror(ret)); 187 | } 188 | } 189 | /* 导出到自动初始化(APP级) */ 190 | MR_INIT_APP_EXPORT(dac_init); 191 | 192 | /* 定义DAC数据最大值 */ 193 | #define DAC_DATA_MAX 4000 194 | 195 | int main(void) 196 | { 197 | /* 自动初始化(dac_init函数将在此处自动调用) */ 198 | mr_auto_init(); 199 | 200 | while(1) 201 | { 202 | uint32_t data = 0; 203 | for (data = 0; data <= DAC_DATA_MAX; data += 500) 204 | { 205 | int ret = mr_dev_write(dac_ds, &data, sizeof(data)); 206 | if (ret != sizeof(data)) 207 | { 208 | mr_printf("Write failed: %s\r\n", mr_strerror(ret)); 209 | } 210 | mr_printf("DAC value: %d\r\n", data); 211 | mr_delay_ms(500); 212 | } 213 | } 214 | } 215 | ``` 216 | 217 | DAC1通道1使能,间隔500毫秒输出一次DAC值并打印(输出值递增,步进500,直到达到最大值)。 218 | -------------------------------------------------------------------------------- /document/device/pwm/pwm.md: -------------------------------------------------------------------------------- 1 | # PWM设备 2 | 3 | [English](pwm_EN.md) 4 | 5 | 6 | * [PWM设备](#pwm设备) 7 | * [打开PWM设备](#打开pwm设备) 8 | * [关闭PWM设备](#关闭pwm设备) 9 | * [控制PWM设备](#控制pwm设备) 10 | * [设置/获取通道编号](#设置获取通道编号) 11 | * [设置/获取通道配置](#设置获取通道配置) 12 | * [设置/获取频率](#设置获取频率) 13 | * [读取PWM通道占空比](#读取pwm通道占空比) 14 | * [写入PWM通道占空比](#写入pwm通道占空比) 15 | * [使用示例:](#使用示例) 16 | 17 | 18 | ## 打开PWM设备 19 | 20 | ```c 21 | int mr_dev_open(const char *path, int flags); 22 | ``` 23 | 24 | | 参数 | 描述 | 25 | |---------|---------| 26 | | path | 设备路径 | 27 | | flags | 打开设备的标志 | 28 | | **返回值** | | 29 | | `>=0` | 设备描述符 | 30 | | `<0` | 错误码 | 31 | 32 | - `name`:PWM设备路径一般为:`pwmx`、`pwm1`、`pwm2`。 33 | - `flags`:打开设备的标志,支持 `MR_O_RDONLY`、 `MR_O_WRONLY`、 `MR_O_RDWR`。 34 | 35 | 注:使用时应根据实际情况为不同的任务分别打开PWM设备,并使用适当的`flags`进行管理和权限控制,以确保它们不会相互影响。 36 | 37 | ## 关闭PWM设备 38 | 39 | ```c 40 | int mr_dev_close(int desc); 41 | ``` 42 | 43 | | 参数 | 描述 | 44 | |---------|-------| 45 | | desc | 设备描述符 | 46 | | **返回值** | | 47 | | `=0` | 关闭成功 | 48 | | `<0` | 错误码 | 49 | 50 | 注:关闭设备时所有的通道都将被自动恢复到默认配置,重新打开后需要重新配置通道(可关闭此功能)。 51 | 52 | ## 控制PWM设备 53 | 54 | ```c 55 | int mr_dev_ioctl(int desc, int cmd, void *args); 56 | ``` 57 | 58 | | 参数 | 描述 | 59 | |---------|-------| 60 | | desc | 设备描述符 | 61 | | cmd | 命令码 | 62 | | args | 命令参数 | 63 | | **返回值** | | 64 | | `=0` | 设置成功 | 65 | | `<0` | 错误码 | 66 | 67 | - `cmd`:命令码,支持以下命令: 68 | - `MR_IOC_PWM_SET_CHANNEL`:设置通道编号。 69 | - `MR_IOC_PWM_SET_CHANNEL_CONFIG`:设置通道配置。 70 | - `MR_IOC_PWM_SET_FREQ`:设置频率。 71 | - `MR_IOC_PWM_GET_CHANNEL`:获取通道编号。 72 | - `MR_IOC_PWM_GET_CHANNEL_CONFIG`:获取通道配置。 73 | - `MR_IOC_PWM_GET_FREQ`:获取频率。 74 | 75 | ### 设置/获取通道编号 76 | 77 | 通道编号范围:`0` ~ `31`。 78 | 79 | ```c 80 | /* 定义通道编号 */ 81 | #define CHANNEL_NUMBER 1 82 | 83 | /* 设置通道编号 */ 84 | mr_dev_ioctl(ds, MR_IOC_PWM_SET_CHANNEL, MR_MAKE_LOCAL(int, CHANNEL_NUMBER)); 85 | 86 | /* 获取通道编号 */ 87 | int number; 88 | mr_dev_ioctl(ds, MR_IOC_PWM_GET_CHANNEL, &number); 89 | ``` 90 | 91 | 不依赖PWM接口: 92 | 93 | ```c 94 | /* 定义通道编号 */ 95 | #define CHANNEL_NUMBER 1 96 | 97 | /* 设置通道编号 */ 98 | mr_dev_ioctl(ds, MR_IOC_SPOS, MR_MAKE_LOCAL(int, CHANNEL_NUMBER)); 99 | 100 | /* 获取通道编号 */ 101 | int number; 102 | mr_dev_ioctl(ds, MR_IOC_GPOS, &number); 103 | ``` 104 | 105 | ### 设置/获取通道配置 106 | 107 | 通道配置: 108 | 109 | - `MR_DISABLE`:禁用通道。 110 | - `MR_ENABLE`:启用通道。 111 | 112 | ```c 113 | struct mr_pwm_config config = {MR_ENABLE, MR_PWM_POLARITY_NORMAL}; 114 | 115 | /* 设置通道配置 */ 116 | mr_dev_ioctl(ds, MR_IOC_PWM_SET_CHANNEL_CONFIG, &config); 117 | /* 获取通道配置 */ 118 | mr_dev_ioctl(ds, MR_IOC_PWM_GET_CHANNEL_CONFIG, &config); 119 | ``` 120 | 121 | 不依赖PWM接口: 122 | 123 | ```c 124 | int config[] = {MR_ENABLE, 0}; 125 | 126 | /* 设置通道配置 */ 127 | mr_dev_ioctl(ds, MR_IOC_SCFG, &config); 128 | /* 获取通道配置 */ 129 | mr_dev_ioctl(ds, MR_IOC_GCFG, &config); 130 | ``` 131 | 132 | ### 设置/获取频率 133 | 134 | ```c 135 | /* 定义频率 */ 136 | #define PWM_FREQ 1000 137 | 138 | /* 设置频率 */ 139 | mr_dev_ioctl(ds, MR_IOC_PWM_SET_FREQ, MR_MAKE_LOCAL(uint32_t, PWM_FREQ)); 140 | 141 | /* 获取频率 */ 142 | uint32_t freq; 143 | mr_dev_ioctl(ds, MR_IOC_PWM_GET_FREQ, &freq); 144 | ``` 145 | 146 | 不依赖PWM接口: 147 | 148 | ```c 149 | /* 定义频率 */ 150 | #define PWM_FREQ 1000 151 | 152 | /* 设置频率 */ 153 | mr_dev_ioctl(ds, (0x01), MR_MAKE_LOCAL(uint32_t, PWM_FREQ)); 154 | 155 | /* 获取频率 */ 156 | uint32_t freq; 157 | mr_dev_ioctl(ds, (-(0x01)), &freq); 158 | ``` 159 | 160 | ## 读取PWM通道占空比 161 | 162 | ```c 163 | ssize_t mr_dev_read(int desc, void *buf, size_t count); 164 | ``` 165 | 166 | | 参数 | 描述 | 167 | |---------|---------| 168 | | desc | 设备描述符 | 169 | | buf | 读取数据缓冲区 | 170 | | count | 读取数据大小 | 171 | | **返回值** | | 172 | | `>=0` | 读取数据大小 | 173 | | `<0` | 错误码 | 174 | 175 | ```c 176 | /* 读取占空比 */ 177 | uint32_t duty; 178 | int ret = mr_dev_read(ds, &duty, sizeof(duty)); 179 | /* 是否读取成功 */ 180 | if (ret != sizeof(duty)) 181 | { 182 | return ret; 183 | } 184 | ``` 185 | 186 | 注:读取数据为PWM占空比,范围:`0` ~ `1000000`。单次读取最小单位为`uint32_t`,即4个字节。 187 | 188 | ## 写入PWM通道占空比 189 | 190 | ```c 191 | ssize_t mr_dev_write(int desc, const void *buf, size_t count); 192 | ``` 193 | 194 | | 参数 | 描述 | 195 | |---------|---------| 196 | | desc | 设备描述符 | 197 | | buf | 写入数据缓冲区 | 198 | | count | 写入数据大小 | 199 | | **返回值** | | 200 | | `>=0` | 写入数据大小 | 201 | | `<0` | 错误码 | 202 | 203 | ```c 204 | /* 写入占空比 */ 205 | uint32_t duty = 500000; 206 | int ret = mr_dev_write(ds, &duty, sizeof(duty)); 207 | /* 是否写入成功 */ 208 | if (ret != sizeof(duty)) 209 | { 210 | return ret; 211 | } 212 | ``` 213 | 214 | 注:写入数据为PWM占空比,范围:`0` ~ `1000000`。单次写入最小单位为`uint32_t`,即4个字节。 215 | 216 | ## 使用示例: 217 | 218 | ```c 219 | #include "include/mr_lib.h" 220 | 221 | /* 定义通道编号和频率 */ 222 | #define CHANNEL_NUMBER 1 223 | #define FREQ 1000 224 | 225 | /* 定义PWM设备描述符 */ 226 | int pwm_ds = -1; 227 | 228 | void pwm_init(void) 229 | { 230 | int ret = MR_EOK; 231 | 232 | /* 初始化PWM */ 233 | pwm_ds = mr_dev_open("pwm1", MR_O_RDWR); 234 | if (pwm_ds < 0) 235 | { 236 | mr_printf("PWM1 open failed: %s\r\n", mr_strerror(pwm_ds)); 237 | return; 238 | } 239 | /* 打印PWM描述符 */ 240 | mr_printf("PWM1 desc: %d\r\n", pwm_ds); 241 | /* 设置到通道1 */ 242 | mr_dev_ioctl(pwm_ds, MR_IOC_PWM_SET_CHANNEL, MR_MAKE_LOCAL(int, CHANNEL_NUMBER)); 243 | /* 设置通道使能 */ 244 | ret = mr_dev_ioctl(pwm_ds, MR_IOC_PWM_SET_CHANNEL_CONFIG, MR_MAKE_LOCAL(struct mr_pwm_config, MR_ENABLE, MR_PWM_POLARITY_NORMAL)); 245 | if (ret < 0) 246 | { 247 | mr_printf("Channel%d enable failed: %s\r\n", CHANNEL_NUMBER, mr_strerror(ret)); 248 | return; 249 | } 250 | ret = mr_dev_ioctl(pwm_ds, MR_IOC_PWM_SET_FREQ, MR_MAKE_LOCAL(uint32_t, FREQ)); 251 | if (ret < 0) 252 | { 253 | mr_printf("Freq configure failed: %s\r\n", mr_strerror(ret)); 254 | } 255 | } 256 | /* 导出到自动初始化(APP级) */ 257 | MR_INIT_APP_EXPORT(pwm_init); 258 | 259 | int main(void) 260 | { 261 | /* 自动初始化(pwm_init函数将在此处自动调用) */ 262 | mr_auto_init(); 263 | 264 | /* 写入占空比 */ 265 | uint32_t duty = 500000; 266 | int ret = mr_dev_write(pwm_ds, &duty, sizeof(duty)); 267 | /* 是否写入成功 */ 268 | if (ret != sizeof(duty)) 269 | { 270 | mr_printf("Write failed: %s\r\n", mr_strerror(ret)); 271 | return ret; 272 | } 273 | 274 | while(1) 275 | { 276 | 277 | } 278 | } 279 | ``` 280 | 281 | PWM频率设置为1000Hz,通道1输出50%占空比。 282 | -------------------------------------------------------------------------------- /document/device/timer/timer.md: -------------------------------------------------------------------------------- 1 | # TIMER设备 2 | 3 | [English](timer_EN.md) 4 | 5 | 6 | * [TIMER设备](#timer设备) 7 | * [打开TIMER设备](#打开timer设备) 8 | * [关闭TIMER设备](#关闭timer设备) 9 | * [控制TIMER设备](#控制timer设备) 10 | * [设置/获取TIMER设备配置](#设置获取timer设备配置) 11 | * [设置/获取超时回调函数](#设置获取超时回调函数) 12 | * [读取TIMER设备运行时间](#读取timer设备运行时间) 13 | * [写入TIMER设备定时时间](#写入timer设备定时时间) 14 | * [使用示例](#使用示例) 15 | 16 | 17 | ## 打开TIMER设备 18 | 19 | ```c 20 | int mr_dev_open(const char *path, int flags); 21 | ``` 22 | 23 | | 参数 | 描述 | 24 | |---------|---------| 25 | | path | 设备路径 | 26 | | flags | 打开设备的标志 | 27 | | **返回值** | | 28 | | `>=0` | 设备描述符 | 29 | | `<0` | 错误码 | 30 | 31 | - `path`:TIMER设备路径一般为:`timerx`,例如:`timer1`、`timer2`、`timer3`。 32 | - `flags`:打开设备的标志,支持 `MR_O_RDONLY`、 `MR_O_WRONLY`、 `MR_O_RDWR`。 33 | 34 | 注:使用时应根据实际情况为不同的任务分别打开TIMER设备,并使用适当的`flags`进行管理和权限控制,以确保它们不会相互影响。 35 | 36 | ## 关闭TIMER设备 37 | 38 | ```c 39 | int mr_dev_close(int desc); 40 | ``` 41 | 42 | | 参数 | 描述 | 43 | |---------|-------| 44 | | desc | 设备描述符 | 45 | | **返回值** | | 46 | | `=0` | 关闭成功 | 47 | | `<0` | 错误码 | 48 | 49 | ## 控制TIMER设备 50 | 51 | ```c 52 | int mr_dev_ioctl(int desc, int cmd, void *args); 53 | ``` 54 | 55 | | 参数 | 描述 | 56 | |---------|-------| 57 | | desc | 设备描述符 | 58 | | cmd | 命令码 | 59 | | args | 命令参数 | 60 | | **返回值** | | 61 | | `=0` | 设置成功 | 62 | | `<0` | 错误码 | 63 | 64 | - `cmd`:命令码,支持以下命令: 65 | - `MR_IOC_TIMER_SET_MODE`:设置TIMER设备模式。 66 | - `MR_IOC_TIMER_SET_TIMEOUT_CALL`:设置超时回调函数。 67 | - `MR_IOC_TIMER_GET_MODE`:获取TIMER设备模式。 68 | - `MR_IOC_TIMER_GET_TIMEOUT_CALL`:获取超时回调函数。 69 | 70 | ### 设置/获取TIMER设备配置 71 | 72 | TIMER设备配置: 73 | 74 | - `mode`:周期或单次模式。 75 | 76 | ```c 77 | /* 定义TIMER设备模式 */ 78 | #define TIMER_MODE MR_TIMER_MODE_ONESHOT 79 | 80 | /* 设置TIMER设备模式 */ 81 | mr_dev_ioctl(ds, MR_IOC_TIMER_SET_MODE, MR_MAKE_LOCAL(int, TIMER_MODE)); 82 | 83 | /* 获取TIMER设备模式 */ 84 | int mode; 85 | mr_dev_ioctl(ds, MR_IOC_TIMER_GET_MODE, &mode); 86 | ``` 87 | 88 | 不依赖TIMER接口: 89 | 90 | ```c 91 | /* 定义TIMER设备模式 */ 92 | #define TIMER_MODE 1 93 | 94 | /* 设置TIMER设备模式 */ 95 | mr_dev_ioctl(ds, MR_IOC_SCFG, MR_MAKE_LOCAL(int, TIMER_MODE)); 96 | 97 | /* 获取TIMER设备模式 */ 98 | int mode; 99 | mr_dev_ioctl(ds, MR_IOC_GCFG, &mode); 100 | ``` 101 | 102 | 注:如未手动配置,默认配置为: 103 | 104 | - 模式:`MR_TIMER_MODE_PERIOD` 105 | 106 | ### 设置/获取超时回调函数 107 | 108 | ```c 109 | /* 定义回调函数 */ 110 | void fn(int desc, void *args) 111 | { 112 | /* 处理中断 */ 113 | } 114 | void (*callback)(int desc, void *args); 115 | 116 | /* 设置超时回调函数 */ 117 | mr_dev_ioctl(ds, MR_IOC_TIMER_SET_TIMEOUT_CALL, &fn); 118 | /* 获取超时回调函数 */ 119 | mr_dev_ioctl(ds, MR_IOC_TIMER_GET_TIMEOUT_CALL, &callback); 120 | ``` 121 | 122 | 不依赖TIMER接口: 123 | 124 | ```c 125 | /* 定义回调函数 */ 126 | void fn(int desc, void *args) 127 | { 128 | /* 处理中断 */ 129 | } 130 | void (*callback)(int desc, void *args); 131 | 132 | /* 设置超时回调函数 */ 133 | mr_dev_ioctl(ds, MR_IOC_SRCB, &fn); 134 | /* 获取超时回调函数 */ 135 | mr_dev_ioctl(ds, MR_IOC_GRCB, &callback); 136 | ``` 137 | 138 | ## 读取TIMER设备运行时间 139 | 140 | ```c 141 | ssize_t mr_dev_read(int desc, void *buf, size_t count); 142 | ``` 143 | 144 | | 参数 | 描述 | 145 | |---------|---------| 146 | | desc | 设备描述符 | 147 | | buf | 读取数据缓冲区 | 148 | | count | 读取数据大小 | 149 | | **返回值** | | 150 | | `>=0` | 读取数据大小 | 151 | | `<0` | 错误码 | 152 | 153 | ```c 154 | uint32_t time; 155 | /* 读取TIMER设备数据 */ 156 | ssize_t size = mr_dev_read(ds, &time, sizeof(time)); 157 | /* 是否读取成功 */ 158 | if (size < 0) 159 | { 160 | 161 | } 162 | ``` 163 | 164 | 注: 165 | 166 | - 时间单位为微妙。单次读取最小单位为`uint32_t`,即4个字节。 167 | - 运行时间指定时器启动后运行的时间,超时后重置。 168 | 169 | ## 写入TIMER设备定时时间 170 | 171 | ```c 172 | ssize_t mr_dev_write(int desc, const void *buf, size_t count); 173 | ``` 174 | 175 | | 参数 | 描述 | 176 | |---------|---------| 177 | | desc | 设备描述符 | 178 | | buf | 写入数据缓冲区 | 179 | | count | 写入数据大小 | 180 | | **返回值** | | 181 | | `>=0` | 写入数据大小 | 182 | | `<0` | 错误码 | 183 | 184 | 注: 185 | 186 | - 时间单位为微妙。单次写入最小单位为`uint32_t`,即4个字节。 187 | - 当有一次写入多个单位数据时,仅实际生效最后一个有效数据(如果最后一个有效数据为`0`将关闭定时器)。 188 | 189 | ## 使用示例 190 | 191 | ```c 192 | #include "include/mr_lib.h" 193 | 194 | void timeout_call(int desc, void *args) 195 | { 196 | mr_printf("Timeout\r\n"); 197 | } 198 | 199 | /* 定时时间 */ 200 | #define TIMEOUT 500000 201 | 202 | void timer_init(void) 203 | { 204 | /* 初始化TIMER */ 205 | int timer_ds = mr_dev_open("timer1", MR_O_RDWR); 206 | if (timer_ds < 0) 207 | { 208 | mr_printf("timer open failed: %s\r\n", mr_strerror(timer_ds)); 209 | return; 210 | } 211 | /* 打印TIMER描述符 */ 212 | mr_printf("TIMER desc: %d\r\n", timer_ds); 213 | /* 设置超时回调函数 */ 214 | mr_dev_ioctl(timer_ds, MR_IOC_TIMER_SET_TIMEOUT_CALL, timeout_call); 215 | /* 设置定时时间 */ 216 | uint32_t timeout = TIMEOUT; 217 | int ret = mr_dev_write(timer_ds, &timeout, sizeof(timeout)); 218 | if(ret < 0) 219 | { 220 | mr_printf("timer write failed: %s\r\n", mr_strerror(ret)); 221 | } 222 | } 223 | /* 导出到自动初始化(APP级) */ 224 | MR_INIT_APP_EXPORT(timer_init); 225 | 226 | int main(void) 227 | { 228 | /* 自动初始化(timer_init函数将在此处自动调用) */ 229 | mr_auto_init(); 230 | 231 | while(1) 232 | { 233 | 234 | } 235 | } 236 | ``` 237 | 238 | 定时器以500ms为周期,每500ms打印一次`Timeout`。 239 | -------------------------------------------------------------------------------- /document/mem_manager/mem_manager.md: -------------------------------------------------------------------------------- 1 | # 动态内存管理 2 | 3 | [English](mem_manager_EN.md) 4 | 5 | 6 | * [动态内存管理](#动态内存管理) 7 | * [主要功能:](#主要功能) 8 | * [内存合并的思路](#内存合并的思路) 9 | * [前合并的情况:](#前合并的情况) 10 | * [后合并的情况:](#后合并的情况) 11 | * [不合并的情况:](#不合并的情况) 12 | * [创建内存数组](#创建内存数组) 13 | * [创建内存管理结构体](#创建内存管理结构体) 14 | * [初始化内存管理](#初始化内存管理) 15 | * [分配内存](#分配内存) 16 | * [释放内存](#释放内存) 17 | * [插入内存块](#插入内存块) 18 | 19 | 20 | ## 主要功能: 21 | - 内存块的动态分配 - 根据应用的请求,从未分配内存块中选择一个块进行分配。 22 | - 内存块的释放回收 - 当块不再需要时,将其释放并标记为未分配状态。 23 | - 已分配与未分配块记录 - 使用链表或数组等数据结构实时跟踪各状态块的信息。 24 | - 内存块合并 - 在释放块后,检查相邻块状态,若均未分配则合并为一个大块减少碎片。 25 | 26 | ## 内存合并的思路 27 | 28 | ### 前合并的情况: 29 | 30 | ``` 31 | (START) -> (内存块A, size=5) -> (内存块B, size=3) 32 | 33 | 插入内存块C(size=2),发现C紧邻A,且A在前,则: 34 | 35 | (START) -> (内存块A+C, size=5+2=7) -> (内存块B, size=3) 36 | ``` 37 | 38 | ### 后合并的情况: 39 | ``` 40 | (START) -> (内存块A, size=5) -> (内存块B, size=3) -> (内存块C, size=2) 41 | 42 | 插入内存块D(size=3),发现D紧邻B,且B在后,则: 43 | 44 | (START) -> (内存块A, size=5) -> (内存块D+B, size=3+3=6) -> (内存块C, size=2) 45 | ``` 46 | ### 不合并的情况: 47 | 48 | ``` 49 | (START) -> (内存块A, size=5) -> (内存块B, size=3) -> (内存块C, size=2) 50 | 51 | 插入内存块D(size=1),D在A和B之间且都不相连,则: 52 | 53 | (START) -> (内存块A, size=5) -> (内存块D, size=1) -> (内存块B, size=3) -> (内存块C, size=2) 54 | ``` 55 | 56 | ## 创建内存数组 57 | 58 | 创建静态数组,用来作为内存管理分配的内存。 59 | 60 | ```c 61 | /* 定义4K空间 */ 62 | #define MR_CFG_HEAP_SIZE (4 * 1024) 63 | static uint8_t heap_mem[MR_CFG_HEAP_SIZE] = {0}; 64 | ``` 65 | 66 | ## 创建内存管理结构体 67 | 68 | 定义内存块,由下一块内存块指针、内存块大小、内存分配标志位组成。 69 | 70 | - 下一块内存块指针:用于实现链式内存块存储,表示下一个内存块的地址。 71 | - 内存块大小:记录该内存块的大小。 72 | - 内存分配标志位:使用1比特来表示内存块当前的状态,0表示未分配,1表示已分配。 73 | 74 | ```c 75 | #define MR_HEAP_BLOCK_FREE (0) 76 | #define MR_HEAP_BLOCK_ALLOCATED (1) 77 | #define MR_HEAP_BLOCK_MIN_SIZE (sizeof(struct mr_heap_block) << 1) 78 | 79 | static struct mr_heap_block 80 | { 81 | struct mr_heap_block *next; 82 | uint32_t size: 31; 83 | uint32_t allocated: 1; 84 | } heap_start = {MR_NULL, 0, MR_HEAP_BLOCK_FREE}; 85 | ``` 86 | 87 | ## 初始化内存管理 88 | 89 | 为内存初始化内存块,将整块内存作为单个内存块。 90 | 91 | ```c 92 | int mr_heap_init(void) 93 | { 94 | struct mr_heap_block *first_block = (struct mr_heap_block *)&heap_mem; 95 | 96 | /* 初始化内存块(消耗一个 sizeof(struct mr_heap_block)) */ 97 | first_block->next = MR_NULL; 98 | first_block->size = sizeof(heap_mem) - sizeof(struct mr_heap_block); 99 | first_block->allocated = MR_HEAP_BLOCK_FREE; 100 | 101 | /* 初始化起始内存块,启动内存管理 */ 102 | heap_start.next = first_block; 103 | return MR_EOK; 104 | } 105 | ``` 106 | 107 | ## 分配内存 108 | 109 | ```c 110 | void *mr_malloc(size_t size) 111 | { 112 | struct mr_heap_block *block_prev = &heap_start; 113 | struct mr_heap_block *block = block_prev->next; 114 | void *memory = MR_NULL; 115 | size_t residual = 0; 116 | 117 | /* 检查需要申请的内存过小、内存过大,以及内存管理器中还有无内存 */ 118 | if ((size == 0) || (size > (UINT32_MAX >> 1) || (block == MR_NULL))) 119 | { 120 | return MR_NULL; 121 | } 122 | 123 | /* 字节向上做4对齐 */ 124 | size = MR_ALIGN_UP(size, 4); 125 | 126 | /* 找到符合内存分配大小的内存块 */ 127 | while (block->size < size) 128 | { 129 | if (block->next == MR_NULL) 130 | { 131 | return MR_NULL; 132 | } 133 | /* 脱离合理的内存块 */ 134 | block_prev = block; 135 | block = block->next; 136 | } 137 | /* 断开内存块链接 */ 138 | block_prev->next = block->next; 139 | 140 | /* 生成新的内存块并返回内存 */ 141 | memory = (void *)((uint8_t *)block) + sizeof(struct mr_heap_block); 142 | /* 剩余内存大小*/ 143 | residual = block->size - size; 144 | 145 | /* 设置被分配的内存块 */ 146 | block->size = size; 147 | block->next = MR_NULL; 148 | block->allocated = MR_HEAP_BLOCK_ALLOCATED; 149 | 150 | /* 检测是否够空间生成新的内存块 (MR_HEAP_BLOCK_MIN_SIZE)左移两位等于2倍,需要有大于2个内存块大小,才生成新的内存块 */ 151 | if (residual > MR_HEAP_BLOCK_MIN_SIZE) 152 | { 153 | struct mr_heap_block *new_block = (struct mr_heap_block *)(((uint8_t *)memory) + size); 154 | 155 | /* 设置新内存块 */ 156 | new_block->size = residual - sizeof(struct mr_heap_block); 157 | new_block->next = MR_NULL; 158 | new_block->allocated = MR_HEAP_BLOCK_FREE; 159 | 160 | /* 将内存块插入到内存块链表中 */ 161 | heap_insert_block(new_block); 162 | } 163 | return memory; 164 | } 165 | ``` 166 | 167 | ## 释放内存 168 | 169 | ```c 170 | void mr_free(void *memory) 171 | { 172 | /* 判断内存是否为有效 */ 173 | if (memory != MR_NULL) 174 | { 175 | struct mr_heap_block *block = (struct mr_heap_block *)((uint8_t *)memory - sizeof(struct mr_heap_block)); 176 | 177 | /* 检查内存块是否可以释放 */ 178 | if (block->allocated == MR_HEAP_BLOCK_ALLOCATED && block->size != 0) 179 | { 180 | block->allocated = MR_HEAP_BLOCK_FREE; 181 | 182 | /* 将内存块插入到内存块链表中 */ 183 | heap_insert_block(block); 184 | } 185 | } 186 | } 187 | ``` 188 | 189 | ## 插入内存块 190 | 191 | ```c 192 | void heap_insert_block(struct mr_heap_block *block) 193 | { 194 | struct mr_heap_block *block_prev = &heap_start; 195 | 196 | /* 搜索前一内存块 */ 197 | while (((block_prev->next != MR_NULL) && ((uint32_t)block_prev->next < (uint32_t)block))) 198 | { 199 | block_prev = block_prev->next; 200 | } 201 | 202 | if (block_prev->next != MR_NULL) 203 | { 204 | /* 如果前一内存块与需要插入的内存块相连则向前合并 */ 205 | if ((void *)(((uint8_t *)block_prev) + sizeof(struct mr_heap_block) + block_prev->size) == (void *)block) 206 | { 207 | block_prev->size += block->size + sizeof(struct mr_heap_block); 208 | block = block_prev; 209 | } 210 | 211 | /* 如果需要插入的内存块与后一内存块于相连则向后合并 */ 212 | if ((void *)(((uint8_t *)block) + sizeof(struct mr_heap_block) + block->size) == (void *)block_prev->next) 213 | { 214 | block->size += block_prev->next->size + sizeof(struct mr_heap_block); 215 | block->next = block_prev->next->next; 216 | 217 | /* 判断当前内存块是否插入*/ 218 | if (block != block_prev) 219 | { 220 | block_prev->next = block; 221 | block = block_prev; 222 | } 223 | } 224 | } 225 | 226 | /* 若内存块未插入,则插入内存块 */ 227 | if (block != block_prev) 228 | { 229 | block->next = block_prev->next; 230 | block_prev->next = block; 231 | } 232 | } 233 | ``` 234 | -------------------------------------------------------------------------------- /document/picture/Kconfig/Kconfig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mac-Rsh/mr-library/1c37dceb140c0538b8fe4c2659401c9790e1d65c/document/picture/Kconfig/Kconfig.png -------------------------------------------------------------------------------- /document/picture/Kconfig/Kconfig1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mac-Rsh/mr-library/1c37dceb140c0538b8fe4c2659401c9790e1d65c/document/picture/Kconfig/Kconfig1.png -------------------------------------------------------------------------------- /document/picture/Kconfig/Kconfig2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mac-Rsh/mr-library/1c37dceb140c0538b8fe4c2659401c9790e1d65c/document/picture/Kconfig/Kconfig2.png -------------------------------------------------------------------------------- /document/picture/Kconfig/Kconfig3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mac-Rsh/mr-library/1c37dceb140c0538b8fe4c2659401c9790e1d65c/document/picture/Kconfig/Kconfig3.png -------------------------------------------------------------------------------- /document/picture/Kconfig/Kconfig4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mac-Rsh/mr-library/1c37dceb140c0538b8fe4c2659401c9790e1d65c/document/picture/Kconfig/Kconfig4.png -------------------------------------------------------------------------------- /document/picture/readme/README.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mac-Rsh/mr-library/1c37dceb140c0538b8fe4c2659401c9790e1d65c/document/picture/readme/README.png -------------------------------------------------------------------------------- /document/picture/readme/build_m.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mac-Rsh/mr-library/1c37dceb140c0538b8fe4c2659401c9790e1d65c/document/picture/readme/build_m.png -------------------------------------------------------------------------------- /document/picture/readme/build_mdk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mac-Rsh/mr-library/1c37dceb140c0538b8fe4c2659401c9790e1d65c/document/picture/readme/build_mdk.png -------------------------------------------------------------------------------- /document/picture/readme/cubemx_project.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mac-Rsh/mr-library/1c37dceb140c0538b8fe4c2659401c9790e1d65c/document/picture/readme/cubemx_project.png -------------------------------------------------------------------------------- /document/picture/readme/driver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mac-Rsh/mr-library/1c37dceb140c0538b8fe4c2659401c9790e1d65c/document/picture/readme/driver.png -------------------------------------------------------------------------------- /document/picture/readme/kconfig_main1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mac-Rsh/mr-library/1c37dceb140c0538b8fe4c2659401c9790e1d65c/document/picture/readme/kconfig_main1.png -------------------------------------------------------------------------------- /document/picture/readme/kconfig_main2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mac-Rsh/mr-library/1c37dceb140c0538b8fe4c2659401c9790e1d65c/document/picture/readme/kconfig_main2.png -------------------------------------------------------------------------------- /document/picture/readme/msh_device1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mac-Rsh/mr-library/1c37dceb140c0538b8fe4c2659401c9790e1d65c/document/picture/readme/msh_device1.png -------------------------------------------------------------------------------- /document/picture/readme/msh_device2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mac-Rsh/mr-library/1c37dceb140c0538b8fe4c2659401c9790e1d65c/document/picture/readme/msh_device2.png -------------------------------------------------------------------------------- /document/picture/readme/project.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mac-Rsh/mr-library/1c37dceb140c0538b8fe4c2659401c9790e1d65c/document/picture/readme/project.png -------------------------------------------------------------------------------- /document/tool/tool.md: -------------------------------------------------------------------------------- 1 | # 自动构建工具 2 | 3 | [English](tool_EN) 4 | 5 | 6 | * [自动构建工具](#自动构建工具) 7 | * [构建流程](#构建流程) 8 | * [支持的命令](#支持的命令) 9 | 10 | 11 | `MR` 框架提供自动化构建系统,通过脚本驱动的构建工具可以根据不同`IDE`自动、高效地完成引入与配置。大大降低了框架使用的学习成本以及与不同环境的集成难度。 12 | 13 | ## 构建流程 14 | 15 | 1. 在命令行中运行`python tool.py`,自动完成工具所需环境的安装。 16 | 2. 运行`python tool.py -m`,在图形化界面中完成`MR` 框架的配置。配置完成后,自动生成`mr_config.h`头文件。 17 | 3. 运行`python tool.py -b`,自动化构建项目。 18 | 19 | 自动构建工具将完成: 20 | 21 | - `MR` 框架文件的自动导入。 22 | - `MR` 框架头文件路径的自动添加。 23 | - 自动使能IDE编译工具链的`GNU`支持。 24 | 25 | ## 支持的命令 26 | 27 | - `-b`:为开发环境构建项目(支持MDK5、Eclipse) 28 | - `-m`:启动图形化配置界面 29 | - `-lic`:显示框架的许可证信息 30 | 31 | 构建脚本大大简化了配置和集成流程,开发者无需了解工程内部,就可以快速启动开发。 32 | -------------------------------------------------------------------------------- /document/tool/tool_EN.md: -------------------------------------------------------------------------------- 1 | # Automated Build Tool 2 | 3 | [中文](tool) 4 | 5 | 6 | * [Automated Build Tool](#automated-build-tool) 7 | * [Build Process](#build-process) 8 | * [Supported Commands](#supported-commands) 9 | 10 | 11 | The MR framework provides an automated build system. The script-driven build tool can automatically and efficiently 12 | complete the introduction and configuration according to different IDEs, greatly reducing the learning cost of using the 13 | framework and the difficulty of integration with different environments. 14 | 15 | ## Build Process 16 | 17 | 1. Run `python tool.py` in the command line to automatically install the required environment for the tool. 18 | 19 | 2. Run `python tool.py -m` to complete the configuration of the MR framework in a graphical interface. After the 20 | configuration is completed, automatically generate the `mr_config.h` header file. 21 | 22 | 3. Run `python tool.py -b` automated build projects. 23 | 24 | The automated build tool will complete: 25 | 26 | - Automatic import of MR framework files 27 | - Automatic addition of MR framework header file paths 28 | - Automatically enable GNU support for the IDE compilation toolchain 29 | 30 | ## Supported Commands 31 | 32 | - `-b`:Build projects for the development environment (MDK5, Eclipse support) 33 | - `-m`: Launches the graphical configuration interface 34 | - `lic`: Displays license information 35 | 36 | The build script greatly simplifies the configuration and integration process, allowing developers to quickly start 37 | development without needing to understand the internal workings of the project. -------------------------------------------------------------------------------- /driver/Kconfig: -------------------------------------------------------------------------------- 1 | menu "No driver configure" 2 | 3 | endmenu -------------------------------------------------------------------------------- /include/components/mr_msh.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @copyright (c) 2023-2024, MR Development Team 3 | * 4 | * @license SPDX-License-Identifier: Apache-2.0 5 | * 6 | * @date 2023-12-25 MacRsh First version 7 | */ 8 | 9 | #ifndef _MR_MSH_H_ 10 | #define _MR_MSH_H_ 11 | 12 | #include "include/mr_api.h" 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif /* __cplusplus */ 17 | 18 | #ifdef MR_USING_MSH 19 | 20 | /** 21 | * @addtogroup Msh 22 | * @{ 23 | */ 24 | 25 | /** 26 | * @brief MSH command structure. 27 | */ 28 | struct mr_msh_cmd 29 | { 30 | const char *name; /**< Name */ 31 | void (*fn)(int argc, void *args); /**< Callback function */ 32 | const char *help; /**< Help information */ 33 | }; 34 | 35 | /** 36 | * @brief This macro function exports a MSH command. 37 | * 38 | * @param name The name of the command. 39 | * @param fn The callback function. 40 | * @param help The help information. 41 | */ 42 | #define MR_MSH_CMD_EXPORT(name, fn, help) \ 43 | MR_USED const struct mr_msh_cmd _mr_msh_cmd_##name MR_SECTION("mr_msh_cmd.1") = {#name, fn, help}; 44 | 45 | /** 46 | * @brief This macro function gets the argument at the specified index. 47 | * 48 | * @param index The index of the argument. 49 | * 50 | * @note This macro must be called from a function where the first parameter is argc and the second parameter is args. 51 | * 1 -> argc, 2 -> args. 52 | */ 53 | #define MR_MSH_GET_ARG(index) \ 54 | (((index) <= (argc)) ? (((const char **)(argv))[(index) - 1]) : MR_NULL) 55 | 56 | /** 57 | * @brief MSH printf with color. 58 | */ 59 | #ifdef MR_USING_MSH_PRINTF_COLOR 60 | #define MR_MSH_COLOR_RED(str) "\033[31m"str"\033[0m" 61 | #define MR_MSH_COLOR_YELLOW(str) "\033[33m"str"\033[0m" 62 | #define MR_MSH_COLOR_BLUE(str) "\033[34m"str"\033[0m" 63 | #define MR_MSH_COLOR_PURPLE(str) "\033[35m"str"\033[0m" 64 | #define MR_MSH_COLOR_GREEN(str) "\033[32m"str"\033[0m" 65 | #else 66 | #define MR_MSH_COLOR_RED(str) str 67 | #define MR_MSH_COLOR_YELLOW(str) str 68 | #define MR_MSH_COLOR_BLUE(str) str 69 | #define MR_MSH_COLOR_PURPLE(str) str 70 | #define MR_MSH_COLOR_GREEN(str) str 71 | #endif /* MR_USING_MSH_PRINTF_COLOR */ 72 | 73 | int mr_msh_input(char *c); 74 | int mr_msh_printf(const char *fmt, ...); 75 | void mr_msh_set_prompt(char *prompt); 76 | void mr_msh_handle(void); 77 | /** @} */ 78 | #endif /* MR_USING_MSH */ 79 | 80 | #ifdef __cplusplus 81 | } 82 | #endif /* __cplusplus */ 83 | 84 | #endif /* _MR_MSH_H_ */ 85 | -------------------------------------------------------------------------------- /include/device/mr_adc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @copyright (c) 2023-2024, MR Development Team 3 | * 4 | * @license SPDX-License-Identifier: Apache-2.0 5 | * 6 | * @date 2023-11-06 MacRsh First version 7 | */ 8 | 9 | #ifndef _MR_ADC_H_ 10 | #define _MR_ADC_H_ 11 | 12 | #include "include/mr_api.h" 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif /* __cplusplus */ 17 | 18 | #ifdef MR_USING_ADC 19 | 20 | /** 21 | * @addtogroup ADC 22 | * @{ 23 | */ 24 | 25 | /** 26 | * @brief ADC configuration structure. 27 | */ 28 | struct mr_adc_config 29 | { 30 | int state; /**< Channel state */ 31 | }; 32 | 33 | /** 34 | * @brief ADC control command. 35 | */ 36 | #define MR_IOC_ADC_SET_CHANNEL MR_IOC_SPOS /**< Set channel command */ 37 | #define MR_IOC_ADC_SET_CHANNEL_CONFIG MR_IOC_SCFG /**< Set channel configuration command */ 38 | 39 | #define MR_IOC_ADC_GET_CHANNEL MR_IOC_GPOS /**< Get channel command */ 40 | #define MR_IOC_ADC_GET_CHANNEL_CONFIG MR_IOC_GCFG /**< Get channel configuration command */ 41 | 42 | /** 43 | * @brief ADC data type. 44 | */ 45 | typedef uint32_t mr_adc_data_t; /**< ADC read data type */ 46 | 47 | /** 48 | * @brief ADC structure. 49 | */ 50 | struct mr_adc 51 | { 52 | struct mr_dev dev; /**< Device */ 53 | 54 | uint32_t channels; /**< Channels */ 55 | }; 56 | 57 | /** 58 | * @brief ADC operations structure. 59 | */ 60 | struct mr_adc_ops 61 | { 62 | int (*configure)(struct mr_adc *adc, int state); 63 | int (*channel_configure)(struct mr_adc *adc, int channel, int state); 64 | int (*read)(struct mr_adc *adc, int channel, uint32_t *data); 65 | }; 66 | 67 | int mr_adc_register(struct mr_adc *adc, const char *path, struct mr_drv *drv); 68 | /** @} */ 69 | 70 | #endif /* MR_USING_ADC */ 71 | 72 | #ifdef __cplusplus 73 | } 74 | #endif /* __cplusplus */ 75 | 76 | #endif /* _MR_ADC_H_ */ 77 | -------------------------------------------------------------------------------- /include/device/mr_can.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @copyright (c) 2023-2024, MR Development Team 3 | * 4 | * @license SPDX-License-Identifier: Apache-2.0 5 | * 6 | * @date 2023-11-22 MacRsh First version 7 | */ 8 | 9 | #ifndef _MR_CAN_H_ 10 | #define _MR_CAN_H_ 11 | 12 | #include "include/mr_api.h" 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif /* __cplusplus */ 17 | 18 | #ifdef MR_USING_CAN 19 | 20 | /** 21 | * @addtogroup CAN 22 | * @{ 23 | */ 24 | 25 | /** 26 | * @brief CAN mode. 27 | */ 28 | #define MR_CAN_MODE_NORMAL (0) /**< Normal mode */ 29 | #define MR_CAN_MODE_LOOPBACK (1) /**< Loopback mode */ 30 | #define MR_CAN_MODE_SILENT (2) /**< Silent mode */ 31 | #define MR_CAN_MODE_SILENT_LOOPBACK (3) /**< Silent loopback mode */ 32 | 33 | /** 34 | * @brief CAN default configuration. 35 | */ 36 | #define MR_CAN_CONFIG_DEFAULT \ 37 | { \ 38 | 500000, \ 39 | MR_CAN_MODE_NORMAL, \ 40 | } 41 | 42 | /** 43 | * @brief CAN configuration structure. 44 | */ 45 | struct mr_can_config 46 | { 47 | uint32_t baud_rate; /**< Baud rate */ 48 | int mode; /**< Mode */ 49 | }; 50 | 51 | /** 52 | * @brief CAN control command. 53 | */ 54 | #define MR_IOC_CAN_SET_CONFIG MR_IOC_SCFG /**< Set configuration command */ 55 | #define MR_IOC_CAN_SET_RD_BUFSZ MR_IOC_SRBSZ /**< Set read buffer size command */ 56 | #define MR_IOC_CAN_CLR_RD_BUF MR_IOC_CRBD /**< Clear read buffer command */ 57 | #define MR_IOC_CAN_SET_RD_CALL MR_IOC_SRCB /**< Set read callback command */ 58 | #define MR_IOC_CAN_REMOTE_REQUEST (0x01) /**< Remote request command */ 59 | 60 | #define MR_IOC_CAN_GET_CONFIG MR_IOC_GCFG /**< Get configuration command */ 61 | #define MR_IOC_CAN_GET_RD_BUFSZ MR_IOC_GRBSZ /**< Get read buffer size command */ 62 | #define MR_IOC_CAN_GET_RD_DATASZ MR_IOC_GRBDSZ /**< Get read data size command */ 63 | #define MR_IOC_CAN_GET_RD_CALL MR_IOC_GRCB /**< Get read callback command */ 64 | 65 | /** 66 | * @brief CAN data type. 67 | */ 68 | typedef uint8_t mr_can_data_t; /**< CAN read/write data type */ 69 | 70 | /** 71 | * @brief CAN ISR events. 72 | */ 73 | #define MR_ISR_CAN_RD_INT (MR_ISR_RD | (0x01 << 8)) /**< Read interrupt event */ 74 | 75 | /** 76 | * @brief CAN bus structure. 77 | */ 78 | struct mr_can_bus 79 | { 80 | struct mr_dev dev; /**< Device */ 81 | 82 | struct mr_can_config config; /**< Configuration */ 83 | volatile void *owner; /**< Owner */ 84 | volatile int hold; /**< Owner hold */ 85 | }; 86 | 87 | /** 88 | * @brief CAN bus operations structure. 89 | */ 90 | struct mr_can_bus_ops 91 | { 92 | int (*configure)(struct mr_can_bus *can_bus, struct mr_can_config *config); 93 | int (*filter_configure)(struct mr_can_bus *can_bus, int id, int ide, int state); 94 | int (*read)(struct mr_can_bus *can_bus, int *id, int *ide, int *rtr, uint8_t *buf, size_t size); 95 | ssize_t (*write)(struct mr_can_bus *can_bus, int id, int ide, const uint8_t *buf, size_t size); 96 | int (*remote_request)(struct mr_can_bus *can_bus, int id, int ide); 97 | }; 98 | 99 | /** 100 | * @brief CAN ID type. 101 | */ 102 | #define MR_CAN_IDE_STD (0) /**< Standard ID */ 103 | #define MR_CAN_IDE_EXT (1) /**< Extended ID */ 104 | 105 | /** 106 | * @brief CAN device structure. 107 | */ 108 | struct mr_can_dev 109 | { 110 | struct mr_dev dev; /**< Device structure */ 111 | 112 | struct mr_can_config config; /**< Configuration */ 113 | struct mr_ringbuf rd_fifo; /**< Read FIFO */ 114 | size_t rd_bufsz; /**< Read buffer size */ 115 | int id; /**< ID */ 116 | int ide; /**< ID type */ 117 | }; 118 | 119 | int mr_can_bus_register(struct mr_can_bus *can_bus, const char *path, struct mr_drv *drv); 120 | int mr_can_dev_register(struct mr_can_dev *can_dev, const char *path, int id, int ide); 121 | /** @} */ 122 | 123 | #endif /* MR_USING_CAN */ 124 | 125 | #ifdef __cplusplus 126 | } 127 | #endif /* __cplusplus */ 128 | 129 | #endif /* _MR_CAN_H_ */ 130 | -------------------------------------------------------------------------------- /include/device/mr_dac.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @copyright (c) 2023-2024, MR Development Team 3 | * 4 | * @license SPDX-License-Identifier: Apache-2.0 5 | * 6 | * @date 2023-11-08 MacRsh First version 7 | */ 8 | 9 | #ifndef _MR_DAC_H_ 10 | #define _MR_DAC_H_ 11 | 12 | #include "include/mr_api.h" 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif /* __cplusplus */ 17 | 18 | #ifdef MR_USING_DAC 19 | 20 | /** 21 | * @addtogroup DAC 22 | * @{ 23 | */ 24 | 25 | /** 26 | * @brief DAC configuration structure. 27 | */ 28 | struct mr_dac_config 29 | { 30 | int state; /**< Channel state */ 31 | }; 32 | 33 | /** 34 | * @brief DAC control command. 35 | */ 36 | #define MR_IOC_DAC_SET_CHANNEL MR_IOC_SPOS /**< Set channel command */ 37 | #define MR_IOC_DAC_SET_CHANNEL_CONFIG MR_IOC_SCFG /**< Set channel configuration command */ 38 | 39 | #define MR_IOC_DAC_GET_CHANNEL MR_IOC_GPOS /**< Get channel command */ 40 | #define MR_IOC_DAC_GET_CHANNEL_CONFIG MR_IOC_GCFG /**< Get channel configuration command */ 41 | 42 | /** 43 | * @brief DAC data type. 44 | */ 45 | typedef uint32_t mr_dac_data_t; /**< DAC write data type */ 46 | 47 | /** 48 | * @brief DAC structure. 49 | */ 50 | struct mr_dac 51 | { 52 | struct mr_dev dev; /**< Device */ 53 | 54 | uint32_t channels; /**< Channels */ 55 | }; 56 | 57 | /** 58 | * @brief DAC operations structure. 59 | */ 60 | struct mr_dac_ops 61 | { 62 | int (*configure)(struct mr_dac *dac, int state); 63 | int (*channel_configure)(struct mr_dac *dac, int channel, int state); 64 | int (*write)(struct mr_dac *dac, int channel, uint32_t data); 65 | }; 66 | 67 | int mr_dac_register(struct mr_dac *dac, const char *path, struct mr_drv *drv); 68 | /** @} */ 69 | 70 | #endif /* MR_USING_DAC */ 71 | 72 | #ifdef __cplusplus 73 | } 74 | #endif /* __cplusplus */ 75 | 76 | #endif /* _MR_DAC_H_ */ 77 | -------------------------------------------------------------------------------- /include/device/mr_i2c.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @copyright (c) 2023-2024, MR Development Team 3 | * 4 | * @license SPDX-License-Identifier: Apache-2.0 5 | * 6 | * @date 2023-11-09 MacRsh First version 7 | */ 8 | 9 | #ifndef _MR_I2C_H_ 10 | #define _MR_I2C_H_ 11 | 12 | #include "include/mr_api.h" 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif /* __cplusplus */ 17 | 18 | #ifdef MR_USING_I2C 19 | 20 | /** 21 | * @addtogroup I2C 22 | * @{ 23 | */ 24 | 25 | /** 26 | * @brief I2C host/slave. 27 | */ 28 | #define MR_I2C_HOST (0) /**< I2C host */ 29 | #define MR_I2C_SLAVE (1) /**< I2C slave */ 30 | 31 | /** 32 | * @brief I2C register bits. 33 | */ 34 | #define MR_I2C_REG_BITS_8 (8) /**< 8 bits register */ 35 | #define MR_I2C_REG_BITS_16 (16) /**< 16 bits register */ 36 | #define MR_I2C_REG_BITS_32 (32) /**< 32 bits register */ 37 | 38 | /** 39 | * @brief I2C default configuration. 40 | */ 41 | #define MR_I2C_CONFIG_DEFAULT \ 42 | { \ 43 | 100000, \ 44 | MR_I2C_HOST, \ 45 | MR_I2C_REG_BITS_8, \ 46 | } 47 | 48 | /** 49 | * @brief I2C configuration structure. 50 | */ 51 | struct mr_i2c_config 52 | { 53 | uint32_t baud_rate; /**< Baud rate */ 54 | int host_slave; /**< Host/slave */ 55 | int reg_bits; /**< Register bits */ 56 | }; 57 | 58 | /** 59 | * @brief I2C control command. 60 | */ 61 | #define MR_IOC_I2C_SET_CONFIG MR_IOC_SCFG /**< Set configuration command */ 62 | #define MR_IOC_I2C_SET_REG MR_IOC_SPOS /**< Set register command */ 63 | #define MR_IOC_I2C_SET_RD_BUFSZ MR_IOC_SRBSZ /**< Set read buffer size command */ 64 | #define MR_IOC_I2C_CLR_RD_BUF MR_IOC_CRBD /**< Clear read buffer command */ 65 | #define MR_IOC_I2C_SET_RD_CALL MR_IOC_SRCB /**< Set read callback command */ 66 | 67 | #define MR_IOC_I2C_GET_CONFIG MR_IOC_GCFG /**< Get configuration command */ 68 | #define MR_IOC_I2C_GET_REG MR_IOC_GPOS /**< Get register command */ 69 | #define MR_IOC_I2C_GET_RD_BUFSZ MR_IOC_GRBSZ /**< Get read buffer size command */ 70 | #define MR_IOC_I2C_GET_RD_DATASZ MR_IOC_GRBDSZ /**< Get read data size command */ 71 | #define MR_IOC_I2C_GET_RD_CALL MR_IOC_GRCB /**< Get read callback command */ 72 | 73 | /** 74 | * @brief I2C data type. 75 | */ 76 | typedef uint8_t mr_i2c_data_t; /**< I2C read/write data type */ 77 | 78 | /** 79 | * @brief I2C ISR events. 80 | */ 81 | #define MR_ISR_I2C_RD_INT (MR_ISR_RD | (0x01)) /**< Read interrupt event */ 82 | 83 | /** 84 | * @brief I2C bus structure. 85 | */ 86 | struct mr_i2c_bus 87 | { 88 | struct mr_dev dev; /**< Device */ 89 | 90 | struct mr_i2c_config config; /**< Configuration */ 91 | volatile void *owner; /**< Owner */ 92 | volatile int hold; /**< Owner hold */ 93 | }; 94 | 95 | /** 96 | * @brief I2C bus operations structure. 97 | */ 98 | struct mr_i2c_bus_ops 99 | { 100 | int (*configure)(struct mr_i2c_bus *i2c_bus, 101 | struct mr_i2c_config *config, 102 | int addr, 103 | int addr_bits); 104 | void (*start)(struct mr_i2c_bus *i2c_bus); 105 | int (*send_addr)(struct mr_i2c_bus *i2c_bus, int addr, int addr_bits); 106 | void (*stop)(struct mr_i2c_bus *i2c_bus); 107 | int (*read)(struct mr_i2c_bus *i2c_bus, uint8_t *data, int ack_state); 108 | int (*write)(struct mr_i2c_bus *i2c_bus, uint8_t data); 109 | }; 110 | 111 | /** 112 | * @brief I2C device address bits. 113 | */ 114 | #define MR_I2C_ADDR_BITS_7 (7) /**< 7 bit address */ 115 | #define MR_I2C_ADDR_BITS_10 (10) /**< 10 bit address */ 116 | 117 | /** 118 | * @brief I2C device structure. 119 | */ 120 | struct mr_i2c_dev 121 | { 122 | struct mr_dev dev; /**< Device */ 123 | 124 | struct mr_i2c_config config; /**< Configuration */ 125 | struct mr_ringbuf rd_fifo; /**< Read FIFO */ 126 | size_t rd_bufsz; /**< Read buffer size */ 127 | int addr; /**< Address */ 128 | int addr_bits; /**< Address bits */ 129 | }; 130 | 131 | int mr_i2c_bus_register(struct mr_i2c_bus *i2c_bus, const char *path, struct mr_drv *drv); 132 | int mr_i2c_dev_register(struct mr_i2c_dev *i2c_dev, const char *path, int addr, int addr_bits); 133 | /** @} */ 134 | 135 | #endif /* MR_USING_I2C */ 136 | 137 | #ifdef __cplusplus 138 | } 139 | #endif /* __cplusplus */ 140 | 141 | #endif /* _MR_I2C_H_ */ 142 | -------------------------------------------------------------------------------- /include/device/mr_pin.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @copyright (c) 2023-2024, MR Development Team 3 | * 4 | * @license SPDX-License-Identifier: Apache-2.0 5 | * 6 | * @date 2023-11-08 MacRsh First version 7 | */ 8 | 9 | #ifndef _MR_PIN_H_ 10 | #define _MR_PIN_H_ 11 | 12 | #include "include/mr_api.h" 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif /* __cplusplus */ 17 | 18 | #ifdef MR_USING_PIN 19 | 20 | /** 21 | * @addtogroup PIN 22 | * @{ 23 | */ 24 | 25 | /** 26 | * @brief PIN mode. 27 | */ 28 | #define MR_PIN_MODE_NONE (0) /**< No mode */ 29 | #define MR_PIN_MODE_OUTPUT (1) /**< Output push-pull mode */ 30 | #define MR_PIN_MODE_OUTPUT_OD (2) /**< Output open-drain mode */ 31 | #define MR_PIN_MODE_INPUT (3) /**< Input mode */ 32 | #define MR_PIN_MODE_INPUT_DOWN (4) /**< Input pull-down mode */ 33 | #define MR_PIN_MODE_INPUT_UP (5) /**< Input pull-up mode */ 34 | 35 | /** 36 | * @brief PIN mode-interrupt. 37 | */ 38 | #define MR_PIN_MODE_IRQ_RISING (6) /**< Interrupt rising edge mode */ 39 | #define MR_PIN_MODE_IRQ_FALLING (7) /**< Interrupt falling edge mode */ 40 | #define MR_PIN_MODE_IRQ_EDGE (8) /**< Interrupt edge mode */ 41 | #define MR_PIN_MODE_IRQ_LOW (9) /**< Interrupt low level mode */ 42 | #define MR_PIN_MODE_IRQ_HIGH (10) /**< Interrupt high level mode */ 43 | 44 | /** 45 | * @brief PIN configuration structure. 46 | */ 47 | struct mr_pin_config 48 | { 49 | int mode; /**< Mode */ 50 | }; 51 | 52 | /** 53 | * @brief PIN control command. 54 | */ 55 | #define MR_IOC_PIN_SET_NUMBER MR_IOC_SPOS /**< Set pin number command */ 56 | #define MR_IOC_PIN_SET_MODE MR_IOC_SCFG /**< Set pin mode command */ 57 | #define MR_IOC_PIN_SET_EXTI_CALL MR_IOC_SRCB /**< Set pin exti callback command */ 58 | 59 | #define MR_IOC_PIN_GET_NUMBER MR_IOC_GPOS /**< Get pin number command */ 60 | #define MR_IOC_PIN_GET_MODE MR_IOC_GCFG /**< Get pin mode command */ 61 | #define MR_IOC_PIN_GET_EXTI_CALL MR_IOC_GRCB /**< Get pin exti callback command */ 62 | 63 | /** 64 | * @brief PIN data type. 65 | */ 66 | typedef uint8_t mr_pin_data_t; /**< PIN read/write data type */ 67 | 68 | /** 69 | * @brief PIN ISR events. 70 | */ 71 | #define MR_ISR_PIN_EXTI_INT (MR_ISR_RD | (0x01)) /**< Exti interrupt event */ 72 | 73 | /** 74 | * @brief PIN structure. 75 | */ 76 | struct mr_pin 77 | { 78 | struct mr_dev dev; /**< Device */ 79 | 80 | uint32_t pins[32]; /**< Pins */ 81 | }; 82 | 83 | /** 84 | * @brief PIN operations structure. 85 | */ 86 | struct mr_pin_ops 87 | { 88 | int (*configure)(struct mr_pin *pin, int number, int mode); 89 | int (*read)(struct mr_pin *pin, int number, uint8_t *value); 90 | int (*write)(struct mr_pin *pin, int number, uint8_t value); 91 | }; 92 | 93 | int mr_pin_register(struct mr_pin *pin, const char *path, struct mr_drv *drv); 94 | /** @} */ 95 | 96 | #endif /* MR_USING_PIN */ 97 | 98 | #ifdef __cplusplus 99 | } 100 | #endif /* __cplusplus */ 101 | 102 | #endif /* _MR_PIN_H_ */ 103 | -------------------------------------------------------------------------------- /include/device/mr_pwm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @copyright (c) 2023-2024, MR Development Team 3 | * 4 | * @license SPDX-License-Identifier: Apache-2.0 5 | * 6 | * @date 2023-12-10 MacRsh First version 7 | */ 8 | 9 | #ifndef _MR_PWM_H_ 10 | #define _MR_PWM_H_ 11 | 12 | #include "include/mr_api.h" 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif /* __cplusplus */ 17 | 18 | #ifdef MR_USING_PWM 19 | 20 | /** 21 | * @addtogroup PWM 22 | * @{ 23 | */ 24 | 25 | /** 26 | * @brief PWM channel polarity. 27 | */ 28 | #define MR_PWM_POLARITY_NORMAL (0) /**< PWM normal polarity */ 29 | #define MR_PWM_POLARITY_INVERTED (1) /**< PWM inverted polarity */ 30 | 31 | /** 32 | * @brief PWM configuration structure. 33 | */ 34 | struct mr_pwm_config 35 | { 36 | int state; /**< Channel state */ 37 | int polarity; /**< Channel polarity */ 38 | }; 39 | 40 | /** 41 | * @brief PWM control command. 42 | */ 43 | #define MR_IOC_PWM_SET_CHANNEL MR_IOC_SPOS /**< Set channel command */ 44 | #define MR_IOC_PWM_SET_CHANNEL_CONFIG MR_IOC_SCFG /**< Set channel configuration command */ 45 | #define MR_IOC_PWM_SET_FREQ (0x01) /**< Set frequency command */ 46 | 47 | #define MR_IOC_PWM_GET_CHANNEL MR_IOC_GPOS /**< Get channel command */ 48 | #define MR_IOC_PWM_GET_CHANNEL_CONFIG MR_IOC_GCFG /**< Get channel configuration command */ 49 | #define MR_IOC_PWM_GET_FREQ (-(0x01)) /**< Get frequency command */ 50 | 51 | /** 52 | * @brief PWM data type. 53 | */ 54 | typedef uint32_t mr_pwm_data_t; /**< PWM read/write data type */ 55 | 56 | /** 57 | * @brief PWM information structure. 58 | */ 59 | struct mr_pwm_info 60 | { 61 | uint32_t clk; /**< Clock(Hz) */ 62 | uint32_t prescaler_max; /**< Prescaler max */ 63 | uint32_t period_max; /**< Period max */ 64 | }; 65 | 66 | /** 67 | * @brief PWM structure. 68 | */ 69 | struct mr_pwm 70 | { 71 | struct mr_dev dev; /**< Device */ 72 | 73 | uint32_t freq; /**< Frequency */ 74 | uint32_t prescaler; /**< Prescaler */ 75 | uint32_t period; /**< Period */ 76 | uint32_t channel; /**< Channel */ 77 | uint32_t channel_polarity; /**< Channel polarity */ 78 | 79 | struct mr_pwm_info *info; /**< Information */ 80 | }; 81 | 82 | /** 83 | * @brief PWM operations structure. 84 | */ 85 | struct mr_pwm_ops 86 | { 87 | int (*configure)(struct mr_pwm *pwm, int state); 88 | int (*channel_configure)(struct mr_pwm *pwm, int channel, int state, int polarity); 89 | void (*start)(struct mr_pwm *pwm, uint32_t prescaler, uint32_t period); 90 | int (*read)(struct mr_pwm *pwm, int channel, uint32_t *compare_value); 91 | int (*write)(struct mr_pwm *pwm, int channel, uint32_t compare_value); 92 | }; 93 | 94 | int mr_pwm_register(struct mr_pwm *pwm, 95 | const char *path, 96 | struct mr_drv *drv, 97 | struct mr_pwm_info *info); 98 | /** @} */ 99 | 100 | #endif /* MR_USING_PWM */ 101 | 102 | #ifdef __cplusplus 103 | } 104 | #endif /* __cplusplus */ 105 | 106 | #endif /* _MR_PWM_H_ */ 107 | -------------------------------------------------------------------------------- /include/device/mr_soft_i2c.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @copyright (c) 2023-2024, MR Development Team 3 | * 4 | * @license SPDX-License-Identifier: Apache-2.0 5 | * 6 | * @date 2023-12-13 MacRsh First version 7 | */ 8 | 9 | #ifndef _MR_SOFT_I2C_H_ 10 | #define _MR_SOFT_I2C_H_ 11 | 12 | #include "include/mr_api.h" 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif /* __cplusplus */ 17 | 18 | #if defined(MR_USING_I2C) && defined(MR_USING_SOFT_I2C) 19 | 20 | #include "include/device/mr_i2c.h" 21 | 22 | /** 23 | * @addtogroup I2C 24 | * @{ 25 | */ 26 | 27 | /** 28 | * @brief Soft-I2C bus structure. 29 | */ 30 | struct mr_soft_i2c_bus 31 | { 32 | struct mr_i2c_bus i2c_bus; /**< I2C-bus device */ 33 | 34 | uint32_t delay; /**< Speed delay */ 35 | int scl_pin; /**< SCL pin */ 36 | int sda_pin; /**< SDA pin */ 37 | }; 38 | 39 | int mr_soft_i2c_bus_register(struct mr_soft_i2c_bus *soft_i2c_bus, 40 | const char *path, 41 | int scl_pin, 42 | int sda_pin); 43 | /** @} */ 44 | 45 | #endif /* defined(MR_USING_I2C) && defined(MR_USING_SOFT_I2C) */ 46 | 47 | #ifdef __cplusplus 48 | } 49 | #endif /* __cplusplus */ 50 | 51 | #endif /* _MR_SOFT_I2C_H_ */ 52 | -------------------------------------------------------------------------------- /include/device/mr_spi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @copyright (c) 2023-2024, MR Development Team 3 | * 4 | * @license SPDX-License-Identifier: Apache-2.0 5 | * 6 | * @date 2023-11-01 MacRsh First version 7 | */ 8 | 9 | #ifndef _MR_SPI_H_ 10 | #define _MR_SPI_H_ 11 | 12 | #include "include/mr_api.h" 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif /* __cplusplus */ 17 | 18 | #ifdef MR_USING_SPI 19 | 20 | /** 21 | * @addtogroup SPI 22 | * @{ 23 | */ 24 | 25 | /** 26 | * @brief SPI host/slave. 27 | */ 28 | #define MR_SPI_HOST (0) /**< SPI host */ 29 | #define MR_SPI_SLAVE (1) /**< SPI slave */ 30 | 31 | /** 32 | * @brief SPI mode. 33 | */ 34 | #define MR_SPI_MODE_0 (0) /**< CPOL = 0, CPHA = 0 */ 35 | #define MR_SPI_MODE_1 (1) /**< CPOL = 0, CPHA = 1 */ 36 | #define MR_SPI_MODE_2 (2) /**< CPOL = 1, CPHA = 0 */ 37 | #define MR_SPI_MODE_3 (3) /**< CPOL = 1, CPHA = 1 */ 38 | 39 | /** 40 | * @brief SPI bit order. 41 | */ 42 | #define MR_SPI_BIT_ORDER_LSB (0) /**< LSB first */ 43 | #define MR_SPI_BIT_ORDER_MSB (1) /**< MSB first */ 44 | 45 | /** 46 | * @brief SPI register bits. 47 | */ 48 | #define MR_SPI_REG_BITS_8 (8) /**< 8 bits register */ 49 | #define MR_SPI_REG_BITS_16 (16) /**< 16 bits register */ 50 | #define MR_SPI_REG_BITS_32 (32) /**< 32 bits register */ 51 | 52 | /** 53 | * @brief SPI default configuration. 54 | */ 55 | #define MR_SPI_CONFIG_DEFAULT \ 56 | { \ 57 | 3000000, \ 58 | MR_SPI_HOST, \ 59 | MR_SPI_MODE_0, \ 60 | MR_SPI_BIT_ORDER_MSB, \ 61 | MR_SPI_REG_BITS_8, \ 62 | } 63 | 64 | /** 65 | * @brief SPI configuration structure. 66 | */ 67 | struct mr_spi_config 68 | { 69 | uint32_t baud_rate; /**< Baud rate */ 70 | int host_slave; /**< Host/slave */ 71 | int mode; /**< Mode */ 72 | int bit_order; /**< Bit order */ 73 | int reg_bits; /**< Register bits */ 74 | }; 75 | 76 | /** 77 | * @brief SPI transfer structure. 78 | */ 79 | struct mr_spi_transfer 80 | { 81 | void *rd_buf; /**< Read buffer */ 82 | const void *wr_buf; /**< Write buffer */ 83 | size_t size; /**< Transfer size */ 84 | }; 85 | 86 | /** 87 | * @brief SPI control command. 88 | */ 89 | #define MR_IOC_SPI_SET_CONFIG MR_IOC_SCFG /**< Set configuration command */ 90 | #define MR_IOC_SPI_SET_REG MR_IOC_SPOS /**< Set register command */ 91 | #define MR_IOC_SPI_SET_RD_BUFSZ MR_IOC_SRBSZ /**< Set read buffer size command */ 92 | #define MR_IOC_SPI_CLR_RD_BUF MR_IOC_CRBD /**< Clear read buffer command */ 93 | #define MR_IOC_SPI_SET_RD_CALL MR_IOC_SRCB /**< Set read callback command */ 94 | #define MR_IOC_SPI_TRANSFER (0x01) /**< Transfer command */ 95 | 96 | #define MR_IOC_SPI_GET_CONFIG MR_IOC_GCFG /**< Get configuration command */ 97 | #define MR_IOC_SPI_GET_REG MR_IOC_GPOS /**< Get register command */ 98 | #define MR_IOC_SPI_GET_RD_BUFSZ MR_IOC_GRBSZ /**< Get read buffer size command */ 99 | #define MR_IOC_SPI_GET_RD_DATASZ MR_IOC_GRBDSZ /**< Get read data size command */ 100 | #define MR_IOC_SPI_GET_RD_CALL MR_IOC_GRCB /**< Get read callback command */ 101 | 102 | /** 103 | * @brief SPI data type. 104 | */ 105 | typedef uint8_t mr_spi_data_t; /**< SPI read/write data type */ 106 | 107 | /** 108 | * @brief SPI ISR events. 109 | */ 110 | #define MR_ISR_SPI_RD_INT (MR_ISR_RD | (0x01)) /**< Read interrupt event */ 111 | 112 | /** 113 | * @brief SPI bus structure. 114 | */ 115 | struct mr_spi_bus 116 | { 117 | struct mr_dev dev; /**< Device */ 118 | 119 | struct mr_spi_config config; /**< Configuration */ 120 | volatile void *owner; /**< Owner */ 121 | volatile int hold; /**< Owner hold */ 122 | int cs_desc; /**< CS descriptor */ 123 | }; 124 | 125 | /** 126 | * @brief SPI bus operations structure. 127 | */ 128 | struct mr_spi_bus_ops 129 | { 130 | int (*configure)(struct mr_spi_bus *spi_bus, struct mr_spi_config *config); 131 | int (*read)(struct mr_spi_bus *spi_bus, uint8_t *data); 132 | int (*write)(struct mr_spi_bus *spi_bus, uint8_t data); 133 | }; 134 | 135 | /** 136 | * @brief SPI CS active level. 137 | */ 138 | #define MR_SPI_CS_ACTIVE_LOW (0) /**< Active low */ 139 | #define MR_SPI_CS_ACTIVE_HIGH (1) /**< Active high */ 140 | #define MR_SPI_CS_ACTIVE_HARDWARE (2) /**< Hardware */ 141 | 142 | /** 143 | * @brief SPI device structure. 144 | */ 145 | struct mr_spi_dev 146 | { 147 | struct mr_dev dev; /**< Device */ 148 | 149 | struct mr_spi_config config; /**< Config */ 150 | struct mr_ringbuf rd_fifo; /**< Read FIFO */ 151 | size_t rd_bufsz; /**< Read buffer size */ 152 | int cs_pin; /**< CS pin */ 153 | int cs_active; /**< CS active level */ 154 | }; 155 | 156 | int mr_spi_bus_register(struct mr_spi_bus *spi_bus, const char *path, struct mr_drv *drv); 157 | int mr_spi_dev_register(struct mr_spi_dev *spi_dev, const char *path, int cs_pin, int cs_active); 158 | /** @} */ 159 | 160 | #endif /* MR_USING_SPI */ 161 | 162 | #ifdef __cplusplus 163 | } 164 | #endif /* __cplusplus */ 165 | 166 | #endif /* _MR_SPI_H_ */ 167 | -------------------------------------------------------------------------------- /include/device/mr_timer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @copyright (c) 2023-2024, MR Development Team 3 | * 4 | * @license SPDX-License-Identifier: Apache-2.0 5 | * 6 | * @date 2023-11-15 MacRsh First version 7 | */ 8 | 9 | #ifndef _MR_TIMER_H_ 10 | #define _MR_TIMER_H_ 11 | 12 | #include "include/mr_api.h" 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif /* __cplusplus */ 17 | 18 | #ifdef MR_USING_TIMER 19 | 20 | /** 21 | * @addtogroup Timer 22 | * @{ 23 | */ 24 | 25 | /** 26 | * @brief Timer mode. 27 | */ 28 | #define MR_TIMER_MODE_PERIOD (0) /**< Periodic mode */ 29 | #define MR_TIMER_MODE_ONESHOT (1) /**< One shot mode */ 30 | 31 | /** 32 | * @brief Timer default configuration. 33 | */ 34 | #define MR_TIMER_CONFIG_DEFAULT \ 35 | { \ 36 | MR_TIMER_MODE_PERIOD, \ 37 | } 38 | 39 | /** 40 | * @brief Timer configuration structure. 41 | */ 42 | struct mr_timer_config 43 | { 44 | int mode; /**< Mode */ 45 | }; 46 | 47 | /** 48 | * @brief Timer control command. 49 | */ 50 | #define MR_IOC_TIMER_SET_MODE MR_IOC_SCFG /**< Set timer mode command */ 51 | #define MR_IOC_TIMER_SET_TIMEOUT_CALL MR_IOC_SRCB /**< Set timeout callback command */ 52 | 53 | #define MR_IOC_TIMER_GET_MODE MR_IOC_GCFG /**< Get timer mode command */ 54 | #define MR_IOC_TIMER_GET_TIMEOUT_CALL MR_IOC_GRCB /**< Get timeout callback command */ 55 | 56 | /** 57 | * @brief Timer data type. 58 | */ 59 | typedef uint32_t mr_timer_data_t; /**< Timer read/write data type */ 60 | 61 | /** 62 | * @brief Timer ISR events. 63 | */ 64 | #define MR_ISR_TIMER_TIMEOUT_INT (MR_ISR_RD | (0x01)) /**< Timeout interrupt event */ 65 | 66 | /** 67 | * @brief Timer information structure. 68 | */ 69 | struct mr_timer_info 70 | { 71 | uint32_t clk; /**< Clock(Hz) */ 72 | uint32_t prescaler_max; /**< Prescaler max */ 73 | uint32_t period_max; /**< Period max */ 74 | }; 75 | 76 | /** 77 | * @brief Timer structure. 78 | */ 79 | struct mr_timer 80 | { 81 | struct mr_dev dev; /**< Device */ 82 | 83 | struct mr_timer_config config; /**< Config */ 84 | uint32_t reload; /**< Reload */ 85 | uint32_t count; /**< Count */ 86 | uint32_t timeout; /**< Timeout */ 87 | uint32_t prescaler; /**< Prescaler */ 88 | uint32_t period; /**< Period */ 89 | 90 | struct mr_timer_info *info; /**< Information */ 91 | }; 92 | 93 | /** 94 | * @brief Timer operations structure. 95 | */ 96 | struct mr_timer_ops 97 | { 98 | int (*configure)(struct mr_timer *timer, int state); 99 | void (*start)(struct mr_timer *timer, uint32_t prescaler, uint32_t period); 100 | void (*stop)(struct mr_timer *timer); 101 | uint32_t (*get_count)(struct mr_timer *timer); 102 | }; 103 | 104 | int mr_timer_register(struct mr_timer *timer, 105 | const char *path, 106 | struct mr_drv *drv, 107 | struct mr_timer_info *info); 108 | /** @} */ 109 | 110 | #endif /* MR_USING_TIMER */ 111 | 112 | #ifdef __cplusplus 113 | } 114 | #endif /* __cplusplus */ 115 | 116 | #endif /* _MR_TIMER_H_ */ 117 | -------------------------------------------------------------------------------- /include/mr_api.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @copyright (c) 2023-2024, MR Development Team 3 | * 4 | * @license SPDX-License-Identifier: Apache-2.0 5 | * 6 | * @date 2023-10-20 MacRsh First version 7 | */ 8 | 9 | #ifndef _MR_API_H_ 10 | #define _MR_API_H_ 11 | 12 | #include "mr_def.h" 13 | #include "mr_service.h" 14 | 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif /* __cplusplus */ 18 | 19 | /** 20 | * @addtogroup Interrupt 21 | * @{ 22 | */ 23 | void mr_interrupt_disable(void); 24 | void mr_interrupt_enable(void); 25 | /** @} */ 26 | 27 | /** 28 | * @addtogroup Delay 29 | * @{ 30 | */ 31 | void mr_delay_us(uint32_t us); 32 | void mr_delay_ms(uint32_t ms); 33 | /** @} */ 34 | 35 | /** 36 | * @addtogroup Memory 37 | * @{ 38 | */ 39 | void *mr_malloc(size_t size); 40 | void mr_free(void *memory); 41 | size_t mr_malloc_usable_size(void *memory); 42 | void *mr_calloc(size_t num, size_t size); 43 | void *mr_realloc(void *memory, size_t size); 44 | /** @} */ 45 | 46 | /** 47 | * @addtogroup String 48 | * @{ 49 | */ 50 | int mr_printf(const char *fmt, ...); 51 | const char *mr_strerror(int err); 52 | const char *mr_strflags(int flags); 53 | /** @} */ 54 | 55 | /** 56 | * @addtogroup Auto-init 57 | * @{ 58 | */ 59 | void mr_auto_init(void); 60 | /** @} */ 61 | 62 | /** 63 | * @addtogroup Ringbuffer 64 | * @{ 65 | */ 66 | void mr_ringbuf_init(struct mr_ringbuf *ringbuf, void *pool, size_t size); 67 | int mr_ringbuf_allocate(struct mr_ringbuf *ringbuf, size_t size); 68 | void mr_ringbuf_free(struct mr_ringbuf *ringbuf); 69 | void mr_ringbuf_reset(struct mr_ringbuf *ringbuf); 70 | size_t mr_ringbuf_get_data_size(struct mr_ringbuf *ringbuf); 71 | size_t mr_ringbuf_get_space_size(struct mr_ringbuf *ringbuf); 72 | size_t mr_ringbuf_get_bufsz(struct mr_ringbuf *ringbuf); 73 | size_t mr_ringbuf_pop(struct mr_ringbuf *ringbuf, uint8_t *data); 74 | size_t mr_ringbuf_read(struct mr_ringbuf *ringbuf, void *buffer, size_t size); 75 | size_t mr_ringbuf_push(struct mr_ringbuf *ringbuf, uint8_t data); 76 | size_t mr_ringbuf_push_force(struct mr_ringbuf *ringbuf, uint8_t data); 77 | size_t mr_ringbuf_write(struct mr_ringbuf *ringbuf, const void *buffer, size_t size); 78 | size_t mr_ringbuf_write_force(struct mr_ringbuf *ringbuf, const void *buffer, size_t size); 79 | /** @} */ 80 | 81 | /** 82 | * @addtogroup AVL-tree 83 | * @{ 84 | */ 85 | void mr_avl_init(struct mr_avl *node, uint32_t value); 86 | void mr_avl_insert(struct mr_avl **tree, struct mr_avl *node); 87 | void mr_avl_remove(struct mr_avl **tree, struct mr_avl *node); 88 | struct mr_avl *mr_avl_find(struct mr_avl *tree, uint32_t value); 89 | size_t mr_avl_get_length(struct mr_avl *tree); 90 | /** @} */ 91 | 92 | /** 93 | * @addtogroup Device 94 | * @{ 95 | */ 96 | int mr_dev_register(struct mr_dev *dev, 97 | const char *path, 98 | int type, 99 | int flags, 100 | struct mr_dev_ops *ops, 101 | struct mr_drv *drv); 102 | int mr_dev_isr(struct mr_dev *dev, int event, void *args); 103 | int mr_dev_open(const char *path, int flags); 104 | int mr_dev_close(int desc); 105 | ssize_t mr_dev_read(int desc, void *buf, size_t count); 106 | ssize_t mr_dev_write(int desc, const void *buf, size_t count); 107 | int mr_dev_ioctl(int desc, int cmd, void *args); 108 | /** @} */ 109 | 110 | #ifdef __cplusplus 111 | } 112 | #endif /* __cplusplus */ 113 | 114 | #endif /* _MR_API_H_ */ 115 | -------------------------------------------------------------------------------- /include/mr_config.h: -------------------------------------------------------------------------------- 1 | #ifndef _MR_CONFIG_H_ 2 | #define _MR_CONFIG_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif /* __cplusplus */ 7 | 8 | #ifdef __cplusplus 9 | } 10 | #endif /* __cplusplus */ 11 | 12 | #endif /* _MR_CONFIG_H_ */ 13 | -------------------------------------------------------------------------------- /include/mr_lib.h: -------------------------------------------------------------------------------- 1 | #ifndef _MR_LIB_H_ 2 | #define _MR_LIB_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif /* __cplusplus */ 7 | 8 | #include "mr_api.h" 9 | #include "mr_config.h" 10 | #include "mr_def.h" 11 | #include "mr_service.h" 12 | #include "components/mr_msh.h" 13 | #include "device/mr_adc.h" 14 | #include "device/mr_can.h" 15 | #include "device/mr_dac.h" 16 | #include "device/mr_i2c.h" 17 | #include "device/mr_pin.h" 18 | #include "device/mr_pwm.h" 19 | #include "device/mr_serial.h" 20 | #include "device/mr_soft_i2c.h" 21 | #include "device/mr_spi.h" 22 | #include "device/mr_timer.h" 23 | 24 | #ifdef __cplusplus 25 | } 26 | #endif /* __cplusplus */ 27 | 28 | #endif /* _MR_LIB_H_ */ 29 | -------------------------------------------------------------------------------- /kconfig.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | @copyright (c) 2023-2024, MR Development Team 5 | 6 | @license SPDX-License-Identifier: Apache-2.0 7 | 8 | @date 2023-12-17 MacRsh First version 9 | """ 10 | 11 | import re 12 | 13 | try: 14 | from tool import install_package 15 | except ImportError: 16 | exit(1) 17 | 18 | try: 19 | from kconfiglib import Kconfig 20 | except ImportError: 21 | install_package('kconfiglib') 22 | from kconfiglib import Kconfig 23 | 24 | try: 25 | import curses 26 | except ImportError: 27 | install_package('windows-curses') 28 | import curses 29 | 30 | try: 31 | from tool import log_print 32 | except ImportError: 33 | exit(1) 34 | 35 | 36 | def generate_config_file(kconfig_file, config_in, config_out, header_out): 37 | kconf = Kconfig(kconfig_file, warn=False, warn_to_stderr=False) 38 | 39 | # Load config 40 | kconf.load_config(config_in) 41 | kconf.write_config(config_out) 42 | kconf.write_autoconf(header_out) 43 | 44 | with open(header_out, 'r+') as header_file: 45 | content = header_file.read() 46 | header_file.truncate(0) 47 | header_file.seek(0) 48 | 49 | # Remove CONFIG_ and MR_USING_XXX following number 50 | content = content.replace("#define CONFIG_", "#define ") 51 | content = re.sub(r'#define MR_USING_(\w+) (\d+)', r'#define MR_USING_\1', content) 52 | 53 | # Add the micro 54 | header_file.write("#ifndef _MR_CONFIG_H_\n") 55 | header_file.write("#define _MR_CONFIG_H_\n\n") 56 | 57 | header_file.write("#ifdef __cplusplus\n") 58 | header_file.write("extern \"C\" {\n") 59 | header_file.write("#endif /* __cplusplus */\n\n") 60 | 61 | # Write back the original data 62 | header_file.write(content) 63 | 64 | # Add the micro 65 | header_file.write("\n#ifdef __cplusplus\n") 66 | header_file.write("}\n") 67 | header_file.write("#endif /* __cplusplus */\n\n") 68 | header_file.write("#endif /* _MR_CONFIG_H_ */\n") 69 | 70 | header_file.close() 71 | log_print('success', "mr-library config file make success") 72 | 73 | 74 | def main(): 75 | kconfig_file = 'Kconfig' 76 | config_in = '.config' 77 | config_out = '.config' 78 | header_out = 'include/mr_config.h' 79 | generate_config_file(kconfig_file, config_in, config_out, header_out) 80 | 81 | 82 | if __name__ == "__main__": 83 | main() 84 | --------------------------------------------------------------------------------