diff --git a/docs/source/api_reference/components/bflog.rst b/docs/source/api_reference/components/bflog.rst deleted file mode 100644 index 5297eb8f..00000000 --- a/docs/source/api_reference/components/bflog.rst +++ /dev/null @@ -1,482 +0,0 @@ -BFLOG -============= - -简介 ------------- - -- BFLOG 是一个移植简单,功能多样的多线程日志记录库 -- 具有同步异步两种工作模式,异步模式如果缓冲区溢出会将最早的一条记录完整删除 -- 总体三部分、记录器、定向输出、格式化器 -- 一个记录器可多重定向输出,可同时输出到缓冲区、IO外设、文件、文件大小划分、文件时间划分 -- 定向到文件输出,支持设定保留数量,支持按文件大小划分,支持按时间划分 -- 每个定向输出可单独设定格式化器、输出等级、TAG标签过滤、输出方式、颜色 -- 格式化器支持简单格式、用户自定义格式、YAML格式(实现中)、CSV格式(规划中) -- 六级日志等级控制, FATAL、ERROR、WARNING、INFO、DEBUG、TRACE -- 支持等级、TAG标签、函数、行数、文件名、TICK数、TIME、线程信息输出 -- 支持等级、TAG标签过滤功能 -- 可对不需要的等级、功能、标签进行裁剪,缩小代码体积 - -.. figure:: img/bflog_log.png - :align: center - - log 样式 - -配置BFLOG相关功能 -------------------- - -如果需要配置BFLOG的相关功能需要在对应的工程目录下 `proj.conf` 文件中添加对应的代码,举例如下: - -以下是一个不支持文件输出的 `proj.conf` 配置 - -.. code-block:: cmake - :linenos: - - # 使能 BFLOG - set(CONFIG_BFLOG 1) - # 使能参数检查, 可不开启 - set(CONFIG_BFLOG_DEBUG 1) - -此外在 `proj.conf` 配置中添加以下配置可以使用用户的 **bflog_user.h** 配置文件,配置文件默认为 **bflog_default.h** - -.. code-block:: cmake - :linenos: - - # 使能 BFLOG_USER 配置文件 - set(CONFIG_BFLOG_USER 1) - -Macros ------------- - -BFLOG_CSI -^^^^^^^^^^^^^^^^^^^^ - -Control Sequence Introducer -用于控制终端 - -.. code-block:: c - :linenos: - - #define BFLOG_CSI_START "\033[" - #define BFLOG_CSI_CUU "A" - #define BFLOG_CSI_CUD "B" - #define BFLOG_CSI_CUF "C" - #define BFLOG_CSI_CUB "D" - #define BFLOG_CSI_CNL "E" - #define BFLOG_CSI_CPL "F" - #define BFLOG_CSI_CHA "G" - #define BFLOG_CSI_CUP "H" - #define BFLOG_CSI_ED "J" - #define BFLOG_CSI_EL "K" - #define BFLOG_CSI_SU "S" - #define BFLOG_CSI_SD "T" - #define BFLOG_CSI_SGR "m" - -BFLOG_SGR -^^^^^^^^^^^^^^^^^^^^ - -Select Graphic Rendition -用于文字图形 - -.. code-block:: c - :linenos: - - #define BFLOG_SGR_RESET "0" - #define BFLOG_SGR_BOLD "1" - #define BFLOG_SGR_FAINT "2" - #define BFLOG_SGR_ITALICS "3" - #define BFLOG_SGR_UNDERLINE "4" - #define BFLOG_SGR_BLINKS "5" - #define BFLOG_SGR_BLINKR "6" - #define BFLOG_SGR_REVERSE "7" - #define BFLOG_SGR_HIDE "8" - #define BFLOG_SGR_STRIKE "9" - #define BFLOG_SGR_NORMAL "22" - #define BFLOG_SGR_FG_BLACK "30" - #define BFLOG_SGR_FG_RED "31" - #define BFLOG_SGR_FG_GREEN "32" - #define BFLOG_SGR_FG_YELLOW "33" - #define BFLOG_SGR_FG_BLUE "34" - #define BFLOG_SGR_FG_MAGENTA "35" - #define BFLOG_SGR_FG_CYAN "36" - #define BFLOG_SGR_FG_WHITE "37" - #define BFLOG_SGR_BG_BLACK "40" - #define BFLOG_SGR_BG_RED "41" - #define BFLOG_SGR_BG_GREEN "42" - #define BFLOG_SGR_BG_YELLOW "43" - #define BFLOG_SGR_BG_BLUE "44" - #define BFLOG_SGR_BG_MAGENTA "45" - #define BFLOG_SGR_BG_CYAN "46" - #define BFLOG_SGR_BG_WHITE "47" - -BFLOG_COLOR -^^^^^^^^^^^^^^^^^^^^ - -一系列颜色用于配置使用 - -.. code-block:: c - :linenos: - - #define BFLOG_COLOR_START BFLOG_CSI_START - #define BFLOG_COLOR_END BFLOG_CSI_SGR - #define BFLOG_CLOLR_SEP ";" - #define BFLOG_COLOR_DEFAULT - #define BFLOG_COLOR_RESET BFLOG_SGR_RESET BFLOG_CLOLR_SEP - #define BFLOG_COLOR_FG_NONE - #define BFLOG_COLOR_FG_BLACK BFLOG_SGR_FG_BLACK BFLOG_CLOLR_SEP - #define BFLOG_COLOR_FG_RED BFLOG_SGR_FG_RED BFLOG_CLOLR_SEP - #define BFLOG_COLOR_FG_GREEN BFLOG_SGR_FG_GREEN BFLOG_CLOLR_SEP - #define BFLOG_COLOR_FG_YELLOW BFLOG_SGR_FG_YELLOW BFLOG_CLOLR_SEP - #define BFLOG_COLOR_FG_BLUE BFLOG_SGR_FG_BLUE BFLOG_CLOLR_SEP - #define BFLOG_COLOR_FG_MAGENTA BFLOG_SGR_FG_MAGENTA BFLOG_CLOLR_SEP - #define BFLOG_COLOR_FG_CYAN BFLOG_SGR_FG_CYAN BFLOG_CLOLR_SEP - #define BFLOG_COLOR_FG_WHITE BFLOG_SGR_FG_WHITE BFLOG_CLOLR_SEP - #define BFLOG_COLOR_BG_NONE - #define BFLOG_COLOR_BG_BLACK BFLOG_SGR_BG_BLACK BFLOG_CLOLR_SEP - #define BFLOG_COLOR_BG_RED BFLOG_SGR_BG_RED BFLOG_CLOLR_SEP - #define BFLOG_COLOR_BG_GREEN BFLOG_SGR_BG_GREEN BFLOG_CLOLR_SEP - #define BFLOG_COLOR_BG_YELLOW BFLOG_SGR_BG_YELLOW BFLOG_CLOLR_SEP - #define BFLOG_COLOR_BG_BLUE BFLOG_SGR_BG_BLUE BFLOG_CLOLR_SEP - #define BFLOG_COLOR_BG_MAGENTA BFLOG_SGR_BG_MAGENTA BFLOG_CLOLR_SEP - #define BFLOG_COLOR_BG_CYAN BFLOG_SGR_BG_CYAN BFLOG_CLOLR_SEP - #define BFLOG_COLOR_BG_WHITE BFLOG_SGR_BG_WHITE BFLOG_CLOLR_SEP - -BFLOG_COLOR_CONTROL -^^^^^^^^^^^^^^^^^^^^ - -默认配置的各等级LOG颜色 - -.. code-block:: c - :linenos: - - #ifndef BFLOG_COLOR_FATAL - #define BFLOG_COLOR_FATAL BFLOG_COLOR_FG_MAGENTA BFLOG_COLOR_BG_NONE BFLOG_SGR_BLINKS - #endif - - #ifndef BFLOG_COLOR_ERROR - #define BFLOG_COLOR_ERROR BFLOG_COLOR_FG_RED BFLOG_COLOR_BG_NONE BFLOG_SGR_NORMAL - #endif - - #ifndef BFLOG_COLOR_WARN - #define BFLOG_COLOR_WARN BFLOG_COLOR_FG_YELLOW BFLOG_COLOR_BG_NONE BFLOG_SGR_NORMAL - #endif - - #ifndef BFLOG_COLOR_INFO - #define BFLOG_COLOR_INFO BFLOG_COLOR_FG_NONE BFLOG_COLOR_BG_NONE BFLOG_SGR_RESET - #endif - - #ifndef BFLOG_COLOR_DEBUG - #define BFLOG_COLOR_DEBUG BFLOG_COLOR_FG_WHITE BFLOG_COLOR_BG_NONE BFLOG_SGR_NORMAL - #endif - - #ifndef BFLOG_COLOR_TRACE - #define BFLOG_COLOR_TRACE BFLOG_COLOR_FG_WHITE BFLOG_COLOR_BG_NONE BFLOG_SGR_FAINT - #endif - -BFLOG_LEVEL_STRING -^^^^^^^^^^^^^^^^^^^^ - -默认配置的各等级提示信息 - -.. code-block:: c - :linenos: - - #ifndef BFLOG_LEVEL_FATAL_STRING - #define BFLOG_LEVEL_FATAL_STRING "FATL" - #endif - - #ifndef BFLOG_LEVEL_ERROR_STRING - #define BFLOG_LEVEL_ERROR_STRING "ERRO" - #endif - - #ifndef BFLOG_LEVEL_WARN_STRING - #define BFLOG_LEVEL_WARN_STRING "WARN" - #endif - - #ifndef BFLOG_LEVEL_INFO_STRING - #define BFLOG_LEVEL_INFO_STRING "INFO" - #endif - - #ifndef BFLOG_LEVEL_DEBUG_STRING - #define BFLOG_LEVEL_DEBUG_STRING "DBUG" - #endif - - #ifndef BFLOG_LEVEL_TRACE_STRING - #define BFLOG_LEVEL_TRACE_STRING "TRAC" - #endif - -BFLOG_LEVEL -^^^^^^^^^^^^^^^^^^^^ - -用于配置 recorder 和 direct 的 LOG等级 - -.. code-block:: c - :linenos: - - #define BFLOG_LEVEL_FATAL 0x00 /*!< level fatal, create a panic */ - #define BFLOG_LEVEL_ERROR 0x01 /*!< level error */ - #define BFLOG_LEVEL_WARN 0x02 /*!< level warning */ - #define BFLOG_LEVEL_INFO 0x03 /*!< level information */ - #define BFLOG_LEVEL_DEBUG 0x04 /*!< level debug */ - #define BFLOG_LEVEL_TRACE 0x05 /*!< level trace information */ - - -BFLOG_FLAG -^^^^^^^^^^^^^^^^^^^^ - -用于配置 recorder 和 direct 的功能 - -.. code-block:: c - :linenos: - - #define BFLOG_FLAG_LEVEL ((uint8_t)0x01) /*!< supported print level */ - #define BFLOG_FLAG_TAG ((uint8_t)0x02) /*!< supported record tag */ - #define BFLOG_FLAG_FUNC ((uint8_t)0x04) /*!< supported record function */ - #define BFLOG_FLAG_LINE ((uint8_t)0x08) /*!< supported record line */ - #define BFLOG_FLAG_FILE ((uint8_t)0x10) /*!< supported record file */ - #define BFLOG_FLAG_CLK ((uint8_t)0x20) /*!< supported record clock */ - #define BFLOG_FLAG_TIME ((uint8_t)0x40) /*!< supported record time */ - #define BFLOG_FLAG_THREAD ((uint8_t)0x80) /*!< supported record thread */ - - -BFLOG_MODE -^^^^^^^^^^^^^^^^^^^^ - -用于配置 recorder 的模式 - -.. code-block:: c - :linenos: - - #define BFLOG_MODE_SYNC ((uint8_t)0x00) - #define BFLOG_MODE_ASYNC ((uint8_t)0x01) - -BFLOG_COMMAND -^^^^^^^^^^^^^^^^^^^^ - -用于 bflog_control 第二个参数 - -.. code-block:: c - :linenos: - - #define BFLOG_CMD_FLAG ((uint32_t)0x01) - #define BFLOG_CMD_LEVEL ((uint32_t)0x02) - #define BFLOG_CMD_QUEUE_POOL ((uint32_t)0x03) - #define BFLOG_CMD_QUEUE_SIZE ((uint32_t)0x04) - #define BFLOG_CMD_QUEUE_RST ((uint32_t)0x05) - #define BFLOG_CMD_ENTER_CRITICAL ((uint32_t)0x06) - #define BFLOG_CMD_EXIT_CRITICAL ((uint32_t)0x07) - #define BFLOG_CMD_FLUSH_NOTICE ((uint32_t)0x08) - #define BFLOG_CMD_MODE ((uint32_t)0x09) - -BFLOG_DIRECT_COMMAND -^^^^^^^^^^^^^^^^^^^^ - -用于 bflog_direct_control 第二个参数 - -.. code-block:: c - :linenos: - - #define BFLOG_DIRECT_CMD_ILLEGAL ((uint32_t)0x00) - #define BFLOG_DIRECT_CMD_LEVEL ((uint32_t)0x02) - #define BFLOG_DIRECT_CMD_LOCK ((uint32_t)0x06) - #define BFLOG_DIRECT_CMD_UNLOCK ((uint32_t)0x07) - #define BFLOG_DIRECT_CMD_COLOR ((uint32_t)0x0A) - -BFLOG_DIRECT_COMMAND -^^^^^^^^^^^^^^^^^^^^ - -用于 bflog_direct_create 第二个参数 - -.. code-block:: c - :linenos: - - #define BFLOG_DIRECT_TYPE_ILLEGAL ((uint8_t)0x00) - #define BFLOG_DIRECT_TYPE_BUFFER ((uint8_t)0x01) - #define BFLOG_DIRECT_TYPE_STREAM ((uint8_t)0x02) - #define BFLOG_DIRECT_TYPE_FILE ((uint8_t)0x03) - #define BFLOG_DIRECT_TYPE_FILE_TIME ((uint8_t)0x04) - #define BFLOG_DIRECT_TYPE_FILE_SIZE ((uint8_t)0x05) - -BFLOG_DIRECT_COLOR -^^^^^^^^^^^^^^^^^^^^ - -用于 bflog_direct_create 第三个参数 - -.. code-block:: c - :linenos: - - #define BFLOG_DIRECT_COLOR_DISABLE ((uint8_t)0) - #define BFLOG_DIRECT_COLOR_ENABLE ((uint8_t)1) - -BFLOG_LAYOUT_TYPE -^^^^^^^^^^^^^^^^^^^^ - -用于 bflog_layout_create 第二个参数 - -.. code-block:: c - :linenos: - - #define BFLOG_LAYOUT_TYPE_SIMPLE ((uint8_t)0) - #define BFLOG_LAYOUT_TYPE_FORMAT ((uint8_t)1) - #define BFLOG_LAYOUT_TYPE_YAML ((uint8_t)2) - -Port Functions ------------- - -bflog_clock -^^^^^^^^^^^^^^^^^^^^ - -获取当前cpu时钟数 - -.. code-block:: c - :linenos: - - uint64_t bflog_clock(void); - -bflog_time -^^^^^^^^^^^^^^^^^^^^ - -获取当前UTC时间戳 - -.. code-block:: c - :linenos: - - uint32_t bflog_time(void); - -bflog_thread -^^^^^^^^^^^^^^^^^^^^ - -获取当前线程名称 - -.. code-block:: c - :linenos: - - char *bflog_thread(void); - -Global Functions ------------- - -bflog_global_filter -^^^^^^^^^^^^^^^^^^^^ - -用于对标签过滤器进行全局的开关,会影响所有的recorder和direct - -.. code-block:: c - :linenos: - - int bflog_global_filter(void *tag_string, uint8_t enable); - -.. list-table:: - :widths: 10 10 - :header-rows: 1 - - * - parameter - - description - * - tag_string - - 标签字符串的指针 - * - enable - - 是否使能 - - -Recorder Functions ------------- - -recorder负责收集日志, 具有illegal、ready、running、suspend四种状态 -running状态可以收集日志, ready、suspend状态可以对其进行配置 -除level配置操作外, 其他配置操作必须在ready、suspend下 - -bflog_create -^^^^^^^^^^^^^^^^^^^^ - -创建一个recorder, 需要定义一个bflog_t结构体并将其指针传入,定义一块内存数组用于换冲 -成功返回0,失败返回-1 - -.. code-block:: c - :linenos: - - int bflog_create(bflog_t *log, void *pool, uint16_t size, uint8_t mode); - -.. list-table:: - :widths: 10 10 - :header-rows: 1 - - * - parameter - - description - * - log - - recorder 指针 - * - pool - - 用于缓冲的数组 - * - size - - 用户缓冲的数组大小 - * - mode - - BFLOG_MODE - -bflog_delete -^^^^^^^^^^^^^^^^^^^^ - -删除一个recorder -处于ready、suspend -线程安全的 -成功返回0,失败返回-1 - -.. code-block:: c - :linenos: - - int bflog_delete(bflog_t *log); - -.. list-table:: - :widths: 10 10 - :header-rows: 1 - - * - parameter - - description - * - log - - recorder 指针 - -bflog_append -^^^^^^^^^^^^^^^^^^^^ - -将一个direct添加到此recorder -处于ready、suspend -线程安全的 -成功返回0,失败返回-1 - -.. code-block:: c - :linenos: - - int bflog_append(bflog_t *log, bflog_direct_t *direct); - -.. list-table:: - :widths: 10 10 - :header-rows: 1 - - * - parameter - - description - * - log - - recorder 指针 - * - direct - - direct 指针 - -bflog_remove -^^^^^^^^^^^^^^^^^^^^ - -将一个direct从recorder移除 -处于ready、suspend -线程安全的 -成功返回0,失败返回-1 - -.. code-block:: c - :linenos: - - int bflog_remove(bflog_t *log, bflog_direct_t *direct); - -.. list-table:: - :widths: 10 10 - :header-rows: 1 - - * - parameter - - description - * - log - - recorder 指针 - * - direct - - direct 指针 - diff --git a/docs/source/api_reference/components/fatfs.rst b/docs/source/api_reference/components/fatfs.rst deleted file mode 100644 index 9bc77ac9..00000000 --- a/docs/source/api_reference/components/fatfs.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fatfs -============= \ No newline at end of file diff --git a/docs/source/api_reference/components/freertos.rst b/docs/source/api_reference/components/freertos.rst deleted file mode 100644 index 96ff86db..00000000 --- a/docs/source/api_reference/components/freertos.rst +++ /dev/null @@ -1,2 +0,0 @@ -FreeRTOS -============= \ No newline at end of file diff --git a/docs/source/api_reference/components/img/bflog_log.png b/docs/source/api_reference/components/img/bflog_log.png deleted file mode 100644 index a415d781..00000000 Binary files a/docs/source/api_reference/components/img/bflog_log.png and /dev/null differ diff --git a/docs/source/api_reference/components/index.rst b/docs/source/api_reference/components/index.rst deleted file mode 100644 index 9eaa615f..00000000 --- a/docs/source/api_reference/components/index.rst +++ /dev/null @@ -1,12 +0,0 @@ -======================= -Components -======================= - -.. toctree:: - :maxdepth: 1 - - BFLOG - Fatfs - FreeRTOS - LUA - Shell diff --git a/docs/source/api_reference/components/lua.rst b/docs/source/api_reference/components/lua.rst deleted file mode 100644 index bca44090..00000000 --- a/docs/source/api_reference/components/lua.rst +++ /dev/null @@ -1,31 +0,0 @@ -LUA -============= - -简介 ------------- -- 目前移植完成的LUA版本是5.4.4 -- LUA5.4中数字全部为number类型,但对应到c隐式分成浮点型和整形,需要在luaconf中配置浮点型和整形对应的类型 -- LUA交互式编程(REPL)还未移植完成 - -不兼容项 ------------- - -.. list-table:: - :header-rows: 1 - - * - 不兼容项名称 - - 描述 - * - string.format %p - - 输出始终为0x????????形式 - * - string.format %q - - 不支持浮点变量 - * - string.format %f - - 输出最大小数位数11位,更高位数会丢失精度 - * - string.format %a - - 不支持p-计数法 - * - os.getenv - - 返回为NULL - * - os.tmpname - - 返回为NULL - * - 文件操作的读取 - - 不支持”n”读取单独读数字 diff --git a/docs/source/api_reference/components/shell.rst b/docs/source/api_reference/components/shell.rst deleted file mode 100644 index 4b2034f2..00000000 --- a/docs/source/api_reference/components/shell.rst +++ /dev/null @@ -1,2 +0,0 @@ -Shell -============= \ No newline at end of file diff --git a/docs/source/get_started/flash_prog.rst b/docs/source/get_started/flash_prog.rst index cc74d328..4e26157a 100644 --- a/docs/source/get_started/flash_prog.rst +++ b/docs/source/get_started/flash_prog.rst @@ -20,13 +20,13 @@ Flash prog cfg.ini 的使用 # 0: not use isp mode, #1: isp mode boot2_isp_mode = 0 - [firmware] + [FW] filedir = ./build/build_out/xxx*_$(CHIPNAME).bin address = 0x0000 - **cfg** 表示烧录时的一些配置,正常不需要改动 -- **firmware** 要烧录的应用固件,必须使用 **firmware** 名称。 +- **FW** 要烧录的应用固件,必须使用 **FW** 名称。 - **filedir** 表示应用固件所在相对路径,正常来说是编译完后放在 `build/build_out` 目录。 ``_$(CHIPNAME).bin`` 是必须要的后缀,用于区分不同芯片。 ``xxx`` 表示应用固件名称,与 `CMakeLists.txt` 中 `project(xxx)` 中名称一致。 ``*`` 表示正则匹配,可用可不用。 - **address** 必须使用 0 地址 @@ -46,7 +46,7 @@ Flash prog cfg.ini 的使用 # 0: not use isp mode, #1: isp mode boot2_isp_mode = 0 - [firmware] + [FW] filedir = ./build/build_out/xxx*_$(CHIPNAME).bin address = 0x10000 @@ -63,7 +63,7 @@ Flash prog cfg.ini 的使用 address = 0x210000 - **cfg** 表示烧录时的一些配置,正常不需要改动 -- **firmware** 要烧录的应用固件,必须使用 **firmware** 名称。 +- **FW** 要烧录的应用固件,必须使用 **FW** 名称。 - **filedir** 表示应用固件所在相对路径,正常来说是编译完后放在 `build/build_out` 目录。 ``_$(CHIPNAME).bin`` 是必须要的后缀,用于区分不同芯片。 ``xxx`` 表示应用固件名称,与 `CMakeLists.txt` 中 `project(xxx)` 中名称一致。 - **address** 由 `partition_xxx.toml` 指定 diff --git a/docs/source/get_started/linux_wsl.rst b/docs/source/get_started/linux_wsl.rst index 07bb433c..63b97839 100644 --- a/docs/source/get_started/linux_wsl.rst +++ b/docs/source/get_started/linux_wsl.rst @@ -3,7 +3,7 @@ Build with Linux or WSL ================================ -本节主要介绍如何在 Linux 或者 WSL 下使用 **命令行** 进行开发。Windows 下如何安装 WSL 请自行百度。 +本节主要介绍如何在 Linux 或者 WSL 下使用 **命令行** 进行开发。Windows 下如何安装 WSL 以及 WSL1/WSL2 下如何使用串口请自行百度。 环境搭建 ----------------- @@ -67,22 +67,6 @@ Build with Linux or WSL Supported LTO compression algorithms: zlib gcc version 10.2.0 (Xuantie-900 elf newlib gcc Toolchain V2.2.5 B-20220323) - -- 在 linux 中,有严格的权限限制,通常一个用户对应一个权限,所以如果提示下面信息,表示需要设置权限。因此,我们将使用到的工具都设置好权限即可 - -.. figure:: img/cmake_error.png - :align: center - -进入 sdk 根目录,输入: - -.. code-block:: bash - :linenos: - - $ cd bouffalo_sdk - $ chmod 777 +x tools/cmake/bin/cmake - $ chmod 777 +x tools/bflb_tools/bflb_fw_post_proc/bflb_fw_post_proc - $ chmod 777 +x tools/bflb_tools/bouffalo_flash_cube/BLFlashCommand - 编译 ------------- @@ -94,7 +78,7 @@ Build with Linux or WSL :linenos: $ cd examples/helloworld - $ make CHIP=chip_name BOARD=board_name ## chip_name 为芯片型号,可以填写 bl602、bl702、bl616、bl808、bl606p, board_name 为开发板名称,详见 bsp/board 目录 + $ make CHIP=chip_name BOARD=board_name ## chip_name 为芯片型号,可以填写 bl702、bl616、bl808、bl606p, board_name 为开发板名称,详见 bsp/board 目录 - 使用 ninja 编译 @@ -102,14 +86,22 @@ Build with Linux or WSL :linenos: $ cd examples/helloworld - $ make ninja CHIP=chip_name BOARD=board_name ## chip_name 为芯片型号,可以填写 bl602、bl702、bl616、bl808、bl606p, board_name 为开发板名称,详见 bsp/board 目录 + $ make ninja CHIP=chip_name BOARD=board_name ## chip_name 为芯片型号,可以填写 bl702、bl616、bl808、bl606p, board_name 为开发板名称,详见 bsp/board 目录 .. note :: 如果使用 BL808 或者 BL606P,需要在上面基础上添加 CPU_ID=id ,id 可以为 m0 或者 d0 -- 烧录 +烧录 +------------- .. code-block:: bash :linenos: $ cd examples/helloworld - $ make flash CHIP=chip_name COMX=port_name ## port_name 为串口号名称,比如 linux 中/dev/ttyACMx,wsl 中对应使用 /dev/ttySx + $ make flash CHIP=chip_name COMX=port_name ## port_name 为串口号名称,比如 linux 中/dev/ttyACMx + +.. note :: 如果使用 BL808 或者 BL606P,需要在上面基础上添加 CPU_ID=id ,id 可以为 m0 或者 d0 + +调试 +------------- + +推荐使用 eclipse + cklink 调试,参考 :ref:`eclipse_gcc`,也可以使用命令行调试,这里不做介绍 \ No newline at end of file diff --git a/docs/source/get_started/repo.rst b/docs/source/get_started/repo.rst index 14197477..569d4f93 100644 --- a/docs/source/get_started/repo.rst +++ b/docs/source/get_started/repo.rst @@ -25,13 +25,7 @@ Repo 是谷歌用 Python 脚本写的调用 git 的一个脚本,可以实现 下载代码 ---------- -- 获取 SDK (只包含 BL616/BL618 版本) - -.. code-block:: bash - :linenos: - - repo init -u https://gerrit.bouffalolab.com/bouffalo/manifest/bouffalo_sdk -b master -m bl616-public.xml - +请与公司联系,申请账号。 同步代码 ---------- diff --git a/docs/source/get_started/windows_cmd.rst b/docs/source/get_started/windows_cmd.rst index 1371de2c..b4c0a6ea 100644 --- a/docs/source/get_started/windows_cmd.rst +++ b/docs/source/get_started/windows_cmd.rst @@ -73,7 +73,7 @@ Build with Windows CMD :linenos: $ cd .\examples\helloworld\ - $ make CHIP=chip_name BOARD=board_name ## chip_name 为芯片型号,可以填写 bl602、bl702、bl616、bl808、bl606p, board_name 为开发板名称,详见 bsp/board 目录 + $ make CHIP=chip_name BOARD=board_name ## chip_name 为芯片型号,可以填写 bl702、bl616、bl808、bl606p, board_name 为开发板名称,详见 bsp/board 目录 - 使用 ninja 编译 @@ -81,14 +81,22 @@ Build with Windows CMD :linenos: $ cd .\examples\helloworld\ - $ make ninja CHIP=chip_name BOARD=board_name ## chip_name 为芯片型号,可以填写 bl602、bl702、bl616、bl808、bl606p, board_name 为开发板名称,详见 bsp/board 目录 + $ make ninja CHIP=chip_name BOARD=board_name ## chip_name 为芯片型号,可以填写 bl702、bl616、bl808、bl606p, board_name 为开发板名称,详见 bsp/board 目录 .. note :: 如果使用 BL808 或者 BL606P,需要在上面基础上添加 CPU_ID=id ,id 可以为 m0 或者 d0 -- 烧录 +烧录 +------------- .. code-block:: bash :linenos: $ cd examples/helloworld $ make flash CHIP=chip_name COMX=port_name ## port_name 为串口号名称,比如 COM5 + +.. note :: 如果使用 BL808 或者 BL606P,需要在上面基础上添加 CPU_ID=id ,id 可以为 m0 或者 d0 + +调试 +------------- + +推荐使用 eclipse + cklink 调试,参考 :ref:`eclipse_gcc`,也可以使用命令行调试,这里不做介绍 \ No newline at end of file diff --git a/docs/source/notes/note_dma.rst b/docs/source/notes/note_dma.rst index 85d1bcf7..3f11253a 100644 --- a/docs/source/notes/note_dma.rst +++ b/docs/source/notes/note_dma.rst @@ -23,7 +23,7 @@ OK,那么当我们开始研究链表配置之前,我们需要了解一些前 支持长度不限制 -------------------- -由于每个 dma 链表最多支持 4905,假设位宽用的是字节,那么一个链表最多传输 4095 字节,很显然这个不能满足我们需求,性能太低。那么如何提高传输长度呢? +由于每个 dma 链表最多支持 4095,假设位宽用的是字节,那么一个链表最多传输 4095 字节,很显然这个不能满足我们需求,性能太低。那么如何提高传输长度呢? 我们可以使用多个链表,串接起来,这样就能够支持更大的传输长度了,并且传输的地址是连续的,dma 链表连接如图所示: diff --git a/docs/source/samples/components/freertos.rst b/docs/source/samples/components/freertos.rst deleted file mode 100644 index f807df0e..00000000 --- a/docs/source/samples/components/freertos.rst +++ /dev/null @@ -1,72 +0,0 @@ -FreeRTOS -==================== - -本 demo 主要演示 FreeRTOS 基本功能:任务创建和任务切换、信号量、内存管理。更详细的代码请参考 **examples/freertos**。 - -内存管理 ---------------- - -FreeRTOS 内存管理默认使用 heap5, 可以管理多块内存,并调用 ``vPortDefineHeapRegions`` 进行初始化。 - -中断管理 ---------------- - -FreeRTOS 为 RISC-V 提供了统一的中断和异常入口,名为 ``freertos_risc_v_trap_handler``,该函数主要作用如下: - -- 压栈 -- 根据 mcause 查找 `mtimer` 中断,并执行 ``xTaskIncrementTick`` -- 根据 mcause 查找 `ecall` 异常,并执行 ``vTaskSwitchContext`` -- 根据 mcause,如果是非 `ecall` 异常,则执行 ``exception_entry``;如果是非 `mtimer` 中断,则执行 ``portasmHANDLE_INTERRUPT``, ``portasmHANDLE_INTERRUPT`` 实际调用 ``interrupt_entry``。 -- 出栈 - -那么问题来了,是如何统一中断和异常的呢? - -通常 RISC-V SOC 中断支持 vector 模式和 direct 模式,博流系列芯片都使用了 vector 模式,在 `startup/start.S` 文件中可以看到 - -.. code-block:: C - :linenos: - - /* mtvec: for all exceptions and non-vector mode IRQs */ - la a0, default_trap_handler - ori a0, a0, 3 - csrw mtvec, a0 - - /* mtvt: for all vector mode IRQs */ - la a0, __Vectors - csrw mtvt, a0 - -在 `startup/interrupt` 中可以找到 ``__Vectors``: - -.. code-block:: C - :linenos: - - const pFunc __Vectors[] __attribute__((section(".init"), aligned(64))) = { - default_interrupt_handler, /* */ - default_interrupt_handler, /* */ - default_interrupt_handler, /* */ - .... - }; - -此时还没有跟 ``freertos_risc_v_trap_handler`` 扯上关系,在 `freertos/CMakelist.txt` 中配置了 ``freertos_risc_v_trap_handler`` 和 ``default_interrupt_handler`` 之间的关系。那么当中断触发时, -调用 ``default_interrupt_handler`` 其实就是调用 ``freertos_risc_v_trap_handler`` 了。 - -.. code-block:: C - :linenos: - - sdk_add_compile_definitions(-DportasmHANDLE_INTERRUPT=interrupt_entry -Ddefault_interrupt_handler=freertos_risc_v_trap_handler) - -在 `portASM.S` 文件中 ``xPortStartFirstTask`` 函数又重新配置了 ``mtvec`` 为 ``freertos_risc_v_trap_handler``,这个时候,中断和异常就统一使用 ``freertos_risc_v_trap_handler`` 函数了。 - -编译和烧录 ------------------------------ - -- **命令行编译** - -参考 :ref:`linux_cmd` 或者 :ref:`windows_cmd` - -- **烧录** - -参考 :ref:`bl_dev_cube` - -实验现象 ------------------------------ \ No newline at end of file diff --git a/docs/source/samples/components/index.rst b/docs/source/samples/components/index.rst deleted file mode 100644 index ec31c931..00000000 --- a/docs/source/samples/components/index.rst +++ /dev/null @@ -1,10 +0,0 @@ -======================= -Components -======================= - -组件例程如果没有特殊说明,则表示适用于博流所有系列芯片。 - -.. toctree:: - :maxdepth: 1 - - FreeRTOS diff --git a/docs/source/samples/peripherals/adc/adc_dma.rst b/docs/source/samples/peripherals/adc/adc_dma.rst new file mode 100644 index 00000000..efa7c71c --- /dev/null +++ b/docs/source/samples/peripherals/adc/adc_dma.rst @@ -0,0 +1,137 @@ +ADC - dma +==================== + +本 demo 主要演示 adc dma 单端模式下读取电压值。默认扫描通道 0 ~ 通道10。 **需要注意,有些芯片不一定支持全部通道**。 + +硬件连接 +----------------------------- + +本 demo 使用到的 gpio 参考 ``board_adc_gpio_init`` 。 + +软件实现 +----------------------------- + +更详细的代码请参考 **examples/peripherals/adc/adc_dma** + +.. code-block:: C + :linenos: + + board_init(); + +- ``board_init`` 中会开启 ADC IP 时钟,并选择 ADC 时钟源和分频(ADC 时钟必须小于等于 500K)。 + +.. code-block:: C + :linenos: + + board_adc_gpio_init(); + +- 配置相关引脚为 `ADC` 功能 + +.. code-block:: C + :linenos: + + adc = bflb_device_get_by_name("adc"); + + /* adc clock = XCLK / 2 / 32 */ + struct bflb_adc_config_s cfg; + cfg.clk_div = ADC_CLK_DIV_32; + cfg.scan_conv_mode = true; + cfg.continuous_conv_mode = true; + cfg.differential_mode = false; + cfg.resolution = ADC_RESOLUTION_16B; + cfg.vref = ADC_VREF_3P2V; + + bflb_adc_init(adc, &cfg); + +- 获取 `adc` 句柄,并初始化 adc 配置,设置 adc 采样频率为 500K + +.. code-block:: C + :linenos: + + bflb_adc_channel_config(adc, chan, TEST_ADC_CHANNELS); + +- 配置 adc 通道信息,使用的通道数通过 `TEST_ADC_CHANNELS` 可配,默认开启通道 0 ~ 10,根据 ``board_adc_gpio_init`` 需要选择性关闭其他通道。 + +.. code-block:: C + :linenos: + + bflb_adc_link_rxdma(adc, true); + +- 使能 adc rx dma 功能 + +.. code-block:: C + :linenos: + + dma0_ch0 = bflb_device_get_by_name("dma0_ch0"); + + struct bflb_dma_channel_config_s config; + + config.direction = DMA_PERIPH_TO_MEMORY; + config.src_req = DMA_REQUEST_ADC; + config.dst_req = DMA_REQUEST_NONE; + config.src_addr_inc = DMA_ADDR_INCREMENT_DISABLE; + config.dst_addr_inc = DMA_ADDR_INCREMENT_ENABLE; + config.src_burst_count = DMA_BURST_INCR1; + config.dst_burst_count = DMA_BURST_INCR1; + config.src_width = DMA_DATA_WIDTH_32BIT; + config.dst_width = DMA_DATA_WIDTH_32BIT; + bflb_dma_channel_init(dma0_ch0, &config); + + bflb_dma_channel_irq_attach(dma0_ch0, dma0_ch0_isr, NULL); + +- 配置 `DMA CH0` 为 `ADC RX` +- 注册 dma 通道中断 + +.. code-block:: C + :linenos: + + struct bflb_dma_channel_lli_pool_s lli[1]; /* max trasnfer size 4064 * 1 */ + struct bflb_dma_channel_lli_transfer_s transfers[1]; + + memset(raw_data, 0, sizeof(raw_data)); + + transfers[0].src_addr = (uint32_t)DMA_ADDR_ADC_RDR; + transfers[0].dst_addr = (uint32_t)raw_data; + transfers[0].nbytes = sizeof(raw_data); + + bflb_dma_channel_lli_reload(dma0_ch0, lli, 1, transfers, 1); + bflb_dma_channel_start(dma0_ch0); + + bflb_adc_start_conversion(adc); + + while (dma_tc_flag0 != 1) { + bflb_mtimer_delay_ms(1); + } + + bflb_adc_stop_conversion(adc); + + +- 分配一块 lli 内存池,个数为1,最多可以传输 4064 * 1 字节 +- 配置一块内存进行传输 +- 调用 ``bflb_dma_channel_lli_reload`` 初始化 +- 调用 ``bflb_dma_channel_start`` 启动传输 +- 调用 ``bflb_adc_start_conversion`` 启用 adc 的转换 +- 等待传输完成并进入中断 +- 调用 ``bflb_adc_stop_conversion`` 停止 adc 转换 + +.. code-block:: C + :linenos: + + for (size_t j = 0; j < TEST_ADC_CHANNELS * TEST_COUNT; j++) { + struct bflb_adc_result_s result; + printf("raw data:%08x\r\n", raw_data[j]); + bflb_adc_parse_result(adc, &raw_data[j], &result, 1); + printf("pos chan %d,%d mv \r\n", result.pos_chan, result.millivolt); + } + +- 调用 ``bflb_adc_parse_result`` 对 adc 的转换结果进行解析,解析的值保存到 ``result`` 结构体中 +- 打印通道号和电压值 + +编译和烧录 +----------------------------- + +参考 :ref:`linux_cmd` 或者 :ref:`windows_cmd` + +实验现象 +----------------------------- +打印 raw data,通道号以及通道对应的电压值。 \ No newline at end of file diff --git a/docs/source/samples/peripherals/adc/adc_int.rst b/docs/source/samples/peripherals/adc/adc_int.rst new file mode 100644 index 00000000..2b676775 --- /dev/null +++ b/docs/source/samples/peripherals/adc/adc_int.rst @@ -0,0 +1,97 @@ +ADC - int +==================== + +本 demo 主要演示 adc 中断模式下读取电压值。默认扫描通道 0 ~ 通道10。 **需要注意,有些芯片不一定支持全部通道**。 + +硬件连接 +----------------------------- + +本 demo 使用到的 gpio 参考 ``board_adc_gpio_init`` 。 + +软件实现 +----------------------------- + +更详细的代码请参考 **examples/peripherals/adc/adc_int** + +.. code-block:: C + :linenos: + + board_init(); + +- ``board_init`` 中会开启 ADC IP 时钟,并选择 ADC 时钟源和分频(ADC 时钟必须小于等于 500K)。 + +.. code-block:: C + :linenos: + + board_adc_gpio_init(); + +- 配置相关引脚为 `ADC` 功能 + +.. code-block:: C + :linenos: + + adc = bflb_device_get_by_name("adc"); + + /* adc clock = XCLK / 2 / 32 */ + struct bflb_adc_config_s cfg; + cfg.clk_div = ADC_CLK_DIV_32; + cfg.scan_conv_mode = true; + cfg.continuous_conv_mode = false; + cfg.differential_mode = false; + cfg.resolution = ADC_RESOLUTION_16B; + cfg.vref = ADC_VREF_3P2V; + + bflb_adc_init(adc, &cfg); + +- 获取 `adc` 句柄,并初始化 adc 配置,设置 adc 采样频率为 500K + +.. code-block:: C + :linenos: + + bflb_adc_channel_config(adc, chan, TEST_ADC_CHANNELS); + +- 配置 adc 通道信息,使用的对数根据 `TEST_ADC_CHANNELS` 可配,默认开启通道 0 ~ 10,根据 ``board_adc_gpio_init`` 需要选择性关闭其他通道。 + +.. code-block:: C + :linenos: + + bflb_adc_rxint_mask(adc, false); + bflb_irq_attach(adc->irq_num, adc_isr, NULL); + bflb_irq_enable(adc->irq_num); + +- 调用 `bflb_adc_rxint_mask` 打开 adc 转换完成中断 +- 调用 `bflb_irq_attach` 连接中断处理函数 +- 调用 `bflb_irq_enable` 使能中断 + +.. code-block:: C + :linenos: + + for (size_t i = 0; i < TEST_COUNT; i++) { + read_count = 0; + bflb_adc_start_conversion(adc); + + while (read_count < TEST_ADC_CHANNELS) { + bflb_mtimer_delay_ms(1); + } + for (size_t j = 0; j < TEST_ADC_CHANNELS; j++) { + struct bflb_adc_result_s result; + printf("raw data:%08x\r\n", raw_data[j]); + bflb_adc_parse_result(adc, (uint32_t *)&raw_data[j], &result, 1); + printf("pos chan %d,%d mv \r\n", result.pos_chan, result.millivolt); + } + bflb_adc_stop_conversion(adc); + bflb_mtimer_delay_ms(100); + } + +- 调用 ``bflb_adc_start_conversion(adc)`` 启用 adc 的转换 +- 调用 ``bflb_adc_parse_result(adc, (uint32_t *)&raw_data[j], &result, 1)`` 对 adc 的转换结果进行解析,解析的值保存到 ``result`` 结构体中 +- 调用 ``bflb_adc_stop_conversion(adc)`` 停止 adc 转换 + +编译和烧录 +----------------------------- + +参考 :ref:`linux_cmd` 或者 :ref:`windows_cmd` + +实验现象 +----------------------------- +打印 raw data,通道号以及通道对应的电压值。 \ No newline at end of file diff --git a/docs/source/samples/peripherals/adc/adc_poll.rst b/docs/source/samples/peripherals/adc/adc_poll.rst index fde28cbe..d4972579 100644 --- a/docs/source/samples/peripherals/adc/adc_poll.rst +++ b/docs/source/samples/peripherals/adc/adc_poll.rst @@ -18,7 +18,7 @@ ADC - poll board_init(); -- ``board_init`` 中会开启 ADC IP 时钟,并选择 ADC 时钟源和分频。 +- ``board_init`` 中会开启 ADC IP 时钟,并选择 ADC 时钟源和分频(ADC 时钟必须小于等于 500K)。 .. code-block:: C :linenos: @@ -83,13 +83,8 @@ ADC - poll 编译和烧录 ----------------------------- -- **命令行编译** - 参考 :ref:`linux_cmd` 或者 :ref:`windows_cmd` -- **烧录** - -参考 :ref:`bl_dev_cube` - 实验现象 ------------------------------ \ No newline at end of file +----------------------------- +打印 raw data,通道号以及通道对应的电压值。 \ No newline at end of file diff --git a/docs/source/samples/peripherals/adc/adc_poll_diff_mode.rst b/docs/source/samples/peripherals/adc/adc_poll_diff_mode.rst new file mode 100644 index 00000000..f895f704 --- /dev/null +++ b/docs/source/samples/peripherals/adc/adc_poll_diff_mode.rst @@ -0,0 +1,90 @@ +ADC - poll_diff_mode +==================== + +本 demo 主要演示 adc poll 差分模式下读取通道 2 和 通道 3 的电压值。 + +硬件连接 +----------------------------- + +本 demo 使用到的 gpio 参考 ``board_adc_gpio_init`` 。 + +软件实现 +----------------------------- + +更详细的代码请参考 **examples/peripherals/adc/adc_poll_diff_mode** + +.. code-block:: C + :linenos: + + board_init(); + +- ``board_init`` 中会开启 ADC IP 时钟,并选择 ADC 时钟源和分频(ADC 时钟必须小于等于 500K)。 + +.. code-block:: C + :linenos: + + board_adc_gpio_init(); + +- 配置相关引脚为 `ADC` 功能 + +.. code-block:: C + :linenos: + + adc = bflb_device_get_by_name("adc"); + + /* adc clock = XCLK / 2 / 32 */ + struct bflb_adc_config_s cfg; + cfg.clk_div = ADC_CLK_DIV_32; + cfg.scan_conv_mode = true; + cfg.continuous_conv_mode = false; + cfg.differential_mode = true; + cfg.resolution = ADC_RESOLUTION_16B; + cfg.vref = ADC_VREF_3P2V; + + bflb_adc_init(adc, &cfg); + +- 获取 `adc` 句柄,并初始化 adc 配置,设置 adc 采样频率为 500K + +.. code-block:: C + :linenos: + + bflb_adc_channel_config(adc, chan, TEST_ADC_CHANNELS); + +- 配置通道 2 和 通道 3 信息。 + +.. code-block:: C + :linenos: + + for (uint32_t i = 0; i < TEST_COUNT; i++) { + bflb_adc_start_conversion(adc); + + while (bflb_adc_get_count(adc) < TEST_ADC_CHANNELS) { + bflb_mtimer_delay_ms(1); + } + + for (size_t j = 0; j < TEST_ADC_CHANNELS; j++) { + struct bflb_adc_result_s result; + uint32_t raw_data = bflb_adc_read_raw(adc); + printf("raw data:%08x\r\n", raw_data); + bflb_adc_parse_result(adc, &raw_data, &result, 1); + printf("pos chan %d,neg chan %d,%d mv \r\n", result.pos_chan, result.neg_chan, result.millivolt); + } + + bflb_adc_stop_conversion(adc); + bflb_mtimer_delay_ms(100); + } + +- 调用 ``bflb_adc_start_conversion(adc)`` 启用 adc 的转换 +- 调用 ``bflb_adc_get_count(adc)`` 读取转换完成的个数 +- 调用 ``bflb_adc_read_raw(adc)`` 读取一次 adc 的转换值 +- 调用 ``bflb_adc_parse_result(adc, &raw_data, &result, 1)`` 对 adc 的转换结果进行解析,解析的值保存到 ``result`` 结构体中 +- 调用 ``bflb_adc_stop_conversion(adc)`` 停止 adc 转换 + +编译和烧录 +----------------------------- + +参考 :ref:`linux_cmd` 或者 :ref:`windows_cmd` + +实验现象 +----------------------------- +打印 raw data,正极和负极通道号以及对应的电压差值。 \ No newline at end of file diff --git a/docs/source/samples/peripherals/adc/adc_tsen.rst b/docs/source/samples/peripherals/adc/adc_tsen.rst new file mode 100644 index 00000000..e7312c15 --- /dev/null +++ b/docs/source/samples/peripherals/adc/adc_tsen.rst @@ -0,0 +1,75 @@ +ADC - tsen +==================== + +本 demo 主要演示通过 adc 测量二极管的电压差,计算得到环境温度。 + +软件实现 +----------------------------- + +更详细的代码请参考 **examples/peripherals/adc/adc_tsen** + +.. code-block:: C + :linenos: + + board_init(); + +- ``board_init`` 中会开启 ADC IP 时钟,并选择 ADC 时钟源和分频(ADC 时钟必须小于等于 500K)。 + +.. code-block:: C + :linenos: + + adc = bflb_device_get_by_name("adc"); + + /* adc clock = XCLK / 2 / 32 */ + struct bflb_adc_config_s cfg; + cfg.clk_div = ADC_CLK_DIV_32; + cfg.scan_conv_mode = false; + cfg.continuous_conv_mode = false; + cfg.differential_mode = false; + cfg.resolution = ADC_RESOLUTION_16B; + cfg.vref = ADC_VREF_2P0V; + + struct bflb_adc_channel_s chan; + + chan.pos_chan = ADC_CHANNEL_TSEN_P; + chan.neg_chan = ADC_CHANNEL_GND; + + bflb_adc_init(adc, &cfg); + +- 获取 `adc` 句柄,并初始化 adc 配置(参考电压必须设置为2.0V),设置 adc 采样频率为 500K。 + +.. code-block:: C + :linenos: + + bflb_adc_channel_config(adc, chan, 1); + +- 配置 adc 通道信息。 + +.. code-block:: C + :linenos: + + bflb_adc_tsen_init(adc, ADC_TSEN_MOD_INTERNAL_DIODE); + +- 开启 tsen 功能,使用内部二极管测量电压值。 + +.. code-block:: C + :linenos: + + for (i = 0; i < 50; i++) { + average_filter += bflb_adc_tsen_get_temp(adc); + bflb_mtimer_delay_ms(10); + } + + printf("temp = %d\r\n", (uint32_t)(average_filter / 50.0)); + average_filter = 0; + +- 调用 ``bflb_adc_tsen_get_temp(adc)`` 获取 adc tsen 计算得到的环境温度值。 + +编译和烧录 +----------------------------- + +参考 :ref:`linux_cmd` 或者 :ref:`windows_cmd` + +实验现象 +----------------------------- +打印计算得到的环境温度。 \ No newline at end of file diff --git a/docs/source/samples/peripherals/adc/adc_vbat.rst b/docs/source/samples/peripherals/adc/adc_vbat.rst new file mode 100644 index 00000000..26942594 --- /dev/null +++ b/docs/source/samples/peripherals/adc/adc_vbat.rst @@ -0,0 +1,86 @@ +ADC - vbat +==================== + +本 demo 主要演示 adc 测量芯片 VDD33 的电压值。 + +软件实现 +----------------------------- + +更详细的代码请参考 **examples/peripherals/adc/adc_vbat** + +.. code-block:: C + :linenos: + + board_init(); + +- ``board_init`` 中会开启 ADC IP 时钟,并选择 ADC 时钟源和分频(ADC 时钟必须小于等于 500K)。 + +.. code-block:: C + :linenos: + + adc = bflb_device_get_by_name("adc"); + + /* adc clock = XCLK / 2 / 32 */ + struct bflb_adc_config_s cfg; + cfg.clk_div = ADC_CLK_DIV_32; + cfg.scan_conv_mode = false; + cfg.continuous_conv_mode = false; + cfg.differential_mode = false; + cfg.resolution = ADC_RESOLUTION_16B; + cfg.vref = ADC_VREF_3P2V; + + struct bflb_adc_channel_s chan; + + chan.pos_chan = ADC_CHANNEL_VABT_HALF; + chan.neg_chan = ADC_CHANNEL_GND; + + bflb_adc_init(adc, &cfg); + +- 获取 `adc` 句柄,并初始化 adc 配置,设置 adc 采样频率为 500K。 + +.. code-block:: C + :linenos: + + bflb_adc_channel_config(adc, chan, 1); + +- 配置 adc 通道信息。 + +.. code-block:: C + :linenos: + + bflb_adc_vbat_enable(adc); + +- 开启 vbat 功能。 + +.. code-block:: C + :linenos: + + struct bflb_adc_result_s result; + for (uint16_t i = 0; i < 10; i++) { + bflb_adc_start_conversion(adc); + while (bflb_adc_get_count(adc) == 0) { + bflb_mtimer_delay_ms(1); + } + uint32_t raw_data = bflb_adc_read_raw(adc); + + bflb_adc_parse_result(adc, &raw_data, &result, 1); + printf("vBat = %d mV\r\n", (uint32_t)(result.millivolt * 2)); + bflb_adc_stop_conversion(adc); + + bflb_mtimer_delay_ms(500); + } + +- 调用 ``bflb_adc_start_conversion(adc)`` 启用 adc 的转换 +- 调用 ``bflb_adc_get_count(adc)`` 读取转换完成的个数 +- 调用 ``bflb_adc_read_raw(adc)`` 读取一次 adc 的转换值 +- 调用 ``bflb_adc_parse_result(adc, &raw_data, &result, 1)`` 对 adc 的转换结果进行解析,解析的值保存到 ``result`` 结构体中 +- 调用 ``bflb_adc_stop_conversion(adc)`` 停止 adc 转换 + +编译和烧录 +----------------------------- + +参考 :ref:`linux_cmd` 或者 :ref:`windows_cmd` + +实验现象 +----------------------------- +打印芯片 VDD33 的电压值。 \ No newline at end of file diff --git a/docs/source/samples/peripherals/adc/index.rst b/docs/source/samples/peripherals/adc/index.rst index d1f74688..8cd48702 100644 --- a/docs/source/samples/peripherals/adc/index.rst +++ b/docs/source/samples/peripherals/adc/index.rst @@ -5,4 +5,93 @@ ADC .. toctree:: :maxdepth: 1 - ADC - poll \ No newline at end of file + ADC - poll + ADC - dma + ADC - interrupt + ADC - poll_diff_mode + ADC - temperature sensor + ADC - vbat + + +ADC 各通道对应的 GPIO 如下表: + +.. table:: GPIO 口 + :widths: 30, 30, 40 + :width: 80% + :align: center + + +----------+-----------+---------------------------+ + | 名称 | 芯片系列 | GPIO | + +==========+===========+===========================+ + | Channel0 | BL702 | GPIO 8 | + + +-----------+---------------------------+ + | | BL808 | GPIO 17 | + + +-----------+---------------------------+ + | | BL616 | GPIO 20 | + +----------+-----------+---------------------------+ + | Channel1 | BL702 | GPIO 15 | + + +-----------+---------------------------+ + | | BL808 | GPIO 5 | + + +-----------+---------------------------+ + | | BL616 | GPIO 19 | + +----------+-----------+---------------------------+ + | Channel2 | BL702 | GPIO 17 | + + +-----------+---------------------------+ + | | BL808 | GPIO 4 | + + +-----------+---------------------------+ + | | BL616 | GPIO 2(Bootstrap 引脚) | + +----------+-----------+---------------------------+ + | Channel3 | BL702 | GPIO 11 | + + +-----------+---------------------------+ + | | BL808 | GPIO 11 | + + +-----------+---------------------------+ + | | BL616 | GPIO 3 | + +----------+-----------+---------------------------+ + | Channel4 | BL702 | GPIO 12 | + + +-----------+---------------------------+ + | | BL808 | GPIO 6 | + + +-----------+---------------------------+ + | | BL616 | GPIO 14 | + +----------+-----------+---------------------------+ + | Channel5 | BL702 | GPIO 14 | + + +-----------+---------------------------+ + | | BL808 | GPIO 40 | + + +-----------+---------------------------+ + | | BL616 | GPIO 13 | + +----------+-----------+---------------------------+ + | Channel6 | BL702 | GPIO 7 | + + +-----------+---------------------------+ + | | BL808 | GPIO 12 | + + +-----------+---------------------------+ + | | BL616 | GPIO 12 | + +----------+-----------+---------------------------+ + | Channel7 | BL702 | GPIO 9 | + + +-----------+---------------------------+ + | | BL808 | GPIO 13 | + + +-----------+---------------------------+ + | | BL616 | GPIO 10 | + +----------+-----------+---------------------------+ + | Channel8 | BL702 | GPIO 18 | + + +-----------+---------------------------+ + | | BL808 | GPIO 16 | + + +-----------+---------------------------+ + | | BL616 | GPIO 1 | + +----------+-----------+---------------------------+ + | Channel9 | BL702 | GPIO 19 | + + +-----------+---------------------------+ + | | BL808 | GPIO 18 | + + +-----------+---------------------------+ + | | BL616 | GPIO 0 | + +----------+-----------+---------------------------+ + | Channel10| BL702 | GPIO 20 | + + +-----------+---------------------------+ + | | BL808 | GPIO 19 | + + +-----------+---------------------------+ + | | BL616 | GPIO 27 | + +----------+-----------+---------------------------+ + | Channel11| BL702 | GPIO 21 | + + +-----------+---------------------------+ + | | BL808 | GPIO 34 | + + +-----------+---------------------------+ + | | BL616 | GPIO 28 | + +----------+-----------+---------------------------+ diff --git a/docs/source/samples/peripherals/dac/dac_dma.rst b/docs/source/samples/peripherals/dac/dac_dma.rst new file mode 100644 index 00000000..f666c36c --- /dev/null +++ b/docs/source/samples/peripherals/dac/dac_dma.rst @@ -0,0 +1,100 @@ +DAC - dma +==================== + +本 demo 主要介绍基于 DAC DMA 模式生成正弦波。 + +硬件连接 +----------------------------- + +本 demo 使用到的 gpio 参考 ``board_dac_gpio_init`` 。 + +软件实现 +----------------------------- + +更详细的代码请参考 **examples/peripherals/dac/dac_dma** + +.. code-block:: C + :linenos: + + board_init(); + +- ``board_init`` 中会开启 DAC IP 时钟,并选择 DAC 时钟源和分频。 + +.. code-block:: C + :linenos: + + board_dac_gpio_init(); + +- 配置相关引脚为 `DAC` 功能 + +.. code-block:: C + :linenos: + + dac = bflb_device_get_by_name("dac"); + + /* 512K / 1 = 512K */ + bflb_dac_init(dac, DAC_CLK_DIV_1); + bflb_dac_channel_enable(dac, DAC_CHANNEL_A); + bflb_dac_channel_enable(dac, DAC_CHANNEL_B); + bflb_dac_link_txdma(dac, true); + +- 获取 `dac` 句柄,并初始化 dac 频率为 512K +- ``bflb_dac_channel_enable`` 配置 dac 通道信息,当前使用的 A 通道和 B 通道 +- ``bflb_dac_link_txdma`` 开启 dac txdma 功能 + +.. code-block:: C + :linenos: + + dma0_ch0 = bflb_device_get_by_name("dma0_ch0"); + + struct bflb_dma_channel_config_s config; + + config.direction = DMA_MEMORY_TO_PERIPH; + config.src_req = DMA_REQUEST_NONE; + config.dst_req = DMA_REQUEST_DAC; + config.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE; + config.dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE; + config.src_burst_count = DMA_BURST_INCR1; + config.dst_burst_count = DMA_BURST_INCR1; + config.src_width = DMA_DATA_WIDTH_16BIT; + config.dst_width = DMA_DATA_WIDTH_16BIT; + bflb_dma_channel_init(dma0_ch0, &config); + + bflb_dma_channel_irq_attach(dma0_ch0, dma0_ch0_isr, NULL); + +- 配置 `DMA CH0` 为 `DAC` +- 注册 dma 通道中断 + +.. code-block:: C + :linenos: + + struct bflb_dma_channel_lli_pool_s lli[1]; /* max trasnfer size 4064 * 1 */ + struct bflb_dma_channel_lli_transfer_s transfers[1]; + + transfers[0].src_addr = (uint32_t)SIN_LIST; + transfers[0].dst_addr = (uint32_t)DMA_ADDR_DAC_TDR; + transfers[0].nbytes = sizeof(SIN_LIST); + bflb_l1c_dcache_clean_range((void*)SIN_LIST,sizeof(SIN_LIST)); + + bflb_dma_channel_lli_reload(dma0_ch0, lli, 1, transfers, 1); + bflb_dma_channel_start(dma0_ch0); + + while (dma_tc_flag0 != 1) { + bflb_mtimer_delay_ms(1); + } + +- 分配一块 lli 内存池,个数为1,最多可以传输 4064 * 1 字节 +- 配置一块内存进行传输 +- 调用 ``bflb_dma_channel_lli_reload`` 初始化 +- 调用 ``bflb_dma_channel_start`` 启动传输 +- 等待传输完成并进入中断 + +编译和烧录 +----------------------------- + +参考 :ref:`linux_cmd` 或者 :ref:`windows_cmd` + +实验现象 +----------------------------- + +DAC Channel A 和 B 对应的 GPIO 输出正弦波。 diff --git a/docs/source/samples/peripherals/dac/dac_polling.rst b/docs/source/samples/peripherals/dac/dac_polling.rst index e4704bae..1ba82d65 100644 --- a/docs/source/samples/peripherals/dac/dac_polling.rst +++ b/docs/source/samples/peripherals/dac/dac_polling.rst @@ -6,20 +6,7 @@ DAC - poll 硬件连接 ----------------------------- -本 demo 使用到的 gpio 如下表: - -.. table:: GPIO 口 - :widths: 30, 30, 40 - :width: 80% - :align: center - - +----------------+-----------+---------------------------+ - | 名称 | 芯片型号 | GPIO | - +================+===========+===========================+ - | DAC Channel A | BL702 | GPIO 11 | - + +-----------+---------------------------+ - | | BL616 | GPIO 3 | - +----------------+-----------+---------------------------+ +本 demo 使用到的 gpio 参考 ``board_adc_gpio_init`` 。 软件实现 ----------------------------- @@ -69,14 +56,8 @@ DAC - poll 编译和烧录 ----------------------------- -- **命令行编译** - 参考 :ref:`linux_cmd` 或者 :ref:`windows_cmd` -- **烧录** - -参考 :ref:`bl_dev_cube` - 实验现象 ----------------------------- diff --git a/docs/source/samples/peripherals/dac/index.rst b/docs/source/samples/peripherals/dac/index.rst index 720267bc..37d4e13b 100644 --- a/docs/source/samples/peripherals/dac/index.rst +++ b/docs/source/samples/peripherals/dac/index.rst @@ -5,4 +5,28 @@ DAC .. toctree:: :maxdepth: 1 - DAC - poll \ No newline at end of file + DAC - poll + DAC - dma + +DAC 各通道对应的 GPIO 如下表: + +.. table:: GPIO 口 + :widths: 25, 25, 25, 25 + :width: 80% + :align: center + + +----------+-----------+-----------+---------------------------+ + | 名称 | 芯片系列 | 精度 | GPIO | + +==========+===========+===========+===========================+ + | ChannelA | BL702 | 10-bit | GPIO 11 | + + +-----------+-----------+---------------------------+ + | | BL808 | 10-bit | GPIO 11 | + + +-----------+-----------+---------------------------+ + | | BL616 | 12-bit | GPIO 3 | + +----------+-----------+-----------+---------------------------+ + | ChannelB | BL702 | 10-bit | GPIO 17 | + + +-----------+-----------+---------------------------+ + | | BL808 | 10-bit | GPIO 4 | + + +-----------+-----------+---------------------------+ + | | BL616 | 12-bit | GPIO 2 | + +----------+-----------+-----------+---------------------------+ \ No newline at end of file diff --git a/docs/source/samples/peripherals/gpio/gpio_input_output.rst b/docs/source/samples/peripherals/gpio/gpio_input_output.rst new file mode 100644 index 00000000..f3a00726 --- /dev/null +++ b/docs/source/samples/peripherals/gpio/gpio_input_output.rst @@ -0,0 +1,58 @@ +GPIO - input/output +==================== + +本 demo 主要介绍 GPIO 0 输出和 GPIO 1 输入功能。 + +硬件连接 +----------------------------- + +使用杜邦线将 GPIO 0 和 GPIO 1 引脚连接。 + +软件实现 +----------------------------- + +更详细的代码请参考 **examples/peripherals/gpio/gpio_input_output** + +.. code-block:: C + :linenos: + + board_init(); + +- ``board_init`` 中开启时钟 + +.. code-block:: C + :linenos: + + gpio = bflb_device_get_by_name("gpio"); + + bflb_gpio_init(gpio, GPIO_PIN_0, GPIO_OUTPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_0); + bflb_gpio_init(gpio, GPIO_PIN_1, GPIO_INPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_0); + +- 配置 GPIO 0 为 GPIO_OUTPUT 功能,GPIO 1 为 GPIO_INPUT 功能。 + +.. code-block:: C + :linenos: + + while (1) { + bflb_gpio_set(gpio, GPIO_PIN_0); + printf("GPIO_PIN_1=%x\r\n", bflb_gpio_read(gpio, GPIO_PIN_1)); + bflb_mtimer_delay_ms(2000); + + bflb_gpio_reset(gpio, GPIO_PIN_0); + printf("GPIO_PIN_1=%x\r\n", bflb_gpio_read(gpio, GPIO_PIN_1)); + bflb_mtimer_delay_ms(2000); + } + +- ``bflb_gpio_set(gpio, GPIO_PIN_0)`` 将 GPIO 0 引脚置位 +- ``bflb_gpio_read(gpio, GPIO_PIN_1)`` 读取 GPIO 1 引脚电平 +- ``bflb_gpio_reset(gpio, GPIO_PIN_0)`` 将 GPIO 0 引脚置 0 + +编译和烧录 +----------------------------- + +参考 :ref:`linux_cmd` 或者 :ref:`windows_cmd` + +实验现象 +----------------------------- + +打印 GPIO 1 引脚电平。 diff --git a/docs/source/samples/peripherals/gpio/gpio_interrupt.rst b/docs/source/samples/peripherals/gpio/gpio_interrupt.rst new file mode 100644 index 00000000..359b11fd --- /dev/null +++ b/docs/source/samples/peripherals/gpio/gpio_interrupt.rst @@ -0,0 +1,52 @@ +GPIO - interrupt +==================== + +本 demo 主要介绍 GPIO 0 的同步低电平中断类型。 + +硬件连接 +----------------------------- + +将 GPIO 0 和 GND 连接。 + +软件实现 +----------------------------- + +更详细的代码请参考 **examples/peripherals/gpio/gpio_interrupt** + +.. code-block:: C + :linenos: + + board_init(); + +- ``board_init`` 中开启时钟 + +.. code-block:: C + :linenos: + + gpio = bflb_device_get_by_name("gpio"); + + bflb_gpio_int_init(gpio, GPIO_PIN_0, GPIO_INT_TRIG_MODE_SYNC_LOW_LEVEL); + +- 设置 GPIO 0 的中断类型。 + +.. code-block:: C + :linenos: + + bflb_gpio_int_mask(gpio, GPIO_PIN_0, false); + + bflb_irq_attach(gpio->irq_num, gpio_isr, gpio); + bflb_irq_enable(gpio->irq_num); + +- ``bflb_gpio_int_mask(gpio, GPIO_PIN_0, false)`` 打开 GPIO 0 中断 +- ``bflb_irq_attach(gpio->irq_num, gpio_isr, gpio)`` 注册 GPIO 中断函数 +- ``bflb_irq_enable(gpio->irq_num)`` 使能 GPIO 中断 + +编译和烧录 +----------------------------- + +参考 :ref:`linux_cmd` 或者 :ref:`windows_cmd` + +实验现象 +----------------------------- + +将 GPIO 0 引脚电平拉低,进入中断并打印中断次数。 diff --git a/docs/source/samples/peripherals/gpio/index.rst b/docs/source/samples/peripherals/gpio/index.rst new file mode 100644 index 00000000..1aff763e --- /dev/null +++ b/docs/source/samples/peripherals/gpio/index.rst @@ -0,0 +1,22 @@ +==== +GPIO +==== + +.. toctree:: + :maxdepth: 1 + + GPIO - input/output + GPIO - interrupt + +各开发板支持的 GPIO 引脚如下表: + +.. table:: GPIO 口 + :widths: 25, 25, 25, 25 + :width: 80% + :align: center + + +----------------------+--------------------------------------------------------------------------------+ + | 开发板 | GPIO | + +======================+================================================================================+ + | BL61x_MB_V1 | GPIO 0-34(其中 GPIO 2 为 BOOT 引脚,GPIO16/17默认为晶振引脚) | + +----------------------+--------------------------------------------------------------------------------+ diff --git a/docs/source/samples/peripherals/i2c/i2c_10_bit.rst b/docs/source/samples/peripherals/i2c/i2c_10_bit.rst new file mode 100644 index 00000000..6e40d800 --- /dev/null +++ b/docs/source/samples/peripherals/i2c/i2c_10_bit.rst @@ -0,0 +1,92 @@ +I2C - 10-bit +==================== + +本 demo 主要介绍 I2C 10-bit slave 模式数据传输。 + +硬件连接 +----------------------------- + +本 demo 使用到的 gpio 参考 ``board_i2c0_gpio_init`` ,将 USB 转 I2C 模块与开发板连接,具体引脚连接方式如下表(以BL616为例): + +.. table:: 硬件连接 + :widths: 50, 50 + :width: 80% + :align: center + + +-------------------+------------------+ + | 开发板 I2C 引脚 | USB 转 I2C 模块 | + +===================+==================+ + | SCL(GPIO14) | SCL | + +-------------------+------------------+ + | SDA(GPIO15) | SDA | + +-------------------+------------------+ + +软件实现 +----------------------------- + +更详细的代码请参考 **examples/peripherals/i2c/i2c_10_bit** + +.. code-block:: C + :linenos: + + board_init(); + +- ``board_init`` 中会开启 I2C IP 时钟,并选择 I2C 时钟源和分频。 + +.. code-block:: C + :linenos: + + board_i2c0_gpio_init(); + +- 配置相关引脚为 `I2C` 功能 + +.. code-block:: C + :linenos: + + i2c0 = bflb_device_get_by_name("i2c0"); + + bflb_i2c_init(i2c0, 400000); + +- 获取 `i2c0` 句柄,并初始化 i2c0 频率为 400K + +.. code-block:: C + :linenos: + + struct bflb_i2c_msg_s msgs[2]; + uint8_t subaddr[2] = { 0x00, 0x04}; + uint8_t write_data[I2C_10BIT_TRANSFER_LENGTH]; + + /* Write buffer init */ + write_data[0] = 0x55; + write_data[1] = 0x11; + write_data[2] = 0x22; + for (size_t i = 3; i < I2C_10BIT_TRANSFER_LENGTH; i++) { + write_data[i] = i; + } + + /* Write data */ + msgs[0].addr = I2C_10BIT_SLAVE_ADDR; + msgs[0].flags = I2C_M_NOSTOP | I2C_M_TEN; + msgs[0].buffer = subaddr; + msgs[0].length = 2; + + msgs[1].addr = I2C_10BIT_SLAVE_ADDR; + msgs[1].flags = 0; + msgs[1].buffer = write_data; + msgs[1].length = I2C_10BIT_TRANSFER_LENGTH; + + bflb_i2c_transfer(i2c0, msgs, 2); + +- 初始化发送数据(write_data)和配置从设备信息(msgs) +- ``bflb_i2c_transfer(i2c0, msgs, 2)`` 开启 i2c 传输 + +编译和烧录 +----------------------------- + +参考 :ref:`linux_cmd` 或者 :ref:`windows_cmd` + +实验现象 +----------------------------- + +通过串口(波特率大于115200)发送``04 00 06 01 03 55``命令给 USB 转 I2C 模块,设置 I2C 从机 10-bit 模式数据传输。 +按下开发板中 RST 按键,串口打印开发板发送的 write_data 数据。 diff --git a/docs/source/samples/peripherals/i2c/i2c_eeprom.rst b/docs/source/samples/peripherals/i2c/i2c_eeprom.rst new file mode 100644 index 00000000..783adfc3 --- /dev/null +++ b/docs/source/samples/peripherals/i2c/i2c_eeprom.rst @@ -0,0 +1,120 @@ +I2C - eeprom +==================== + +本 demo 主要介绍 I2C 读写 eeprom。 + +硬件连接 +----------------------------- + +本 demo 使用到的 gpio 参考 ``board_i2c0_gpio_init`` ,将 eeprom 模块与开发板连接,具体引脚连接方式如下表(以BL616为例): + +.. table:: 硬件连接 + :widths: 50, 50 + :width: 80% + :align: center + + +-------------------+------------------+ + | 开发板 I2C 引脚 | eeprom 模块 | + +===================+==================+ + | SCL(GPIO14) | SCL | + +-------------------+------------------+ + | SDA(GPIO15) | SDA | + +-------------------+------------------+ + | GND | GND | + +-------------------+------------------+ + | VCC | VCC | + +-------------------+------------------+ + +软件实现 +----------------------------- + +更详细的代码请参考 **examples/peripherals/i2c/i2c_eeprom** + +.. code-block:: C + :linenos: + + board_init(); + +- ``board_init`` 中会开启 I2C IP 时钟,并选择 I2C 时钟源和分频。 + +.. code-block:: C + :linenos: + + board_i2c0_gpio_init(); + +- 配置相关引脚为 `I2C` 功能 + +.. code-block:: C + :linenos: + + i2c0 = bflb_device_get_by_name("i2c0"); + + bflb_i2c_init(i2c0, 400000); + +- 获取 `i2c0` 句柄,并初始化 i2c0 频率为 400K + +.. code-block:: C + :linenos: + + struct bflb_i2c_msg_s msgs[2]; + uint8_t subaddr[2] = { 0x00, EEPROM_SELECT_PAGE0}; + uint8_t write_data[256]; + + /* Write and read buffer init */ + for (size_t i = 0; i < 256; i++) { + write_data[i] = i; + read_data[i] = 0; + } + + /* Write page 0 */ + msgs[0].addr = 0x50; + msgs[0].flags = I2C_M_NOSTOP; + msgs[0].buffer = subaddr; + msgs[0].length = 2; + + msgs[1].addr = 0x50; + msgs[1].flags = 0; + msgs[1].buffer = write_data; + msgs[1].length = EEPROM_TRANSFER_LENGTH; + + bflb_i2c_transfer(i2c0, msgs, 2); + +- 初始化发送数据(write_data),接收buffer和配置从设备信息(msgs) +- ``bflb_i2c_transfer(i2c0, msgs, 2)`` 开启 i2c 传输 + +.. code-block:: C + :linenos: + + uint8_t read_data[256]; + + /* Read page 0 */ + msgs[1].addr = 0x50; + msgs[1].flags = I2C_M_READ; + msgs[1].buffer = read_data; + msgs[1].length = EEPROM_TRANSFER_LENGTH; + bflb_i2c_transfer(i2c0, msgs, 2); + +- 读取从设备寄存器地址中的数据,存放至 read_data 中 +- ``bflb_i2c_transfer(i2c0, msgs, 2)`` 开启 i2c 传输 + +.. code-block:: C + :linenos: + + /* Check read data */ + for (uint8_t i = 0; i < EEPROM_TRANSFER_LENGTH; i++) { + if (write_data[i] != read_data[i]) { + printf("check fail, %d write: %02x, read: %02x\r\n", i, write_data[i], read_data[i]); + } + } + +- 检查发送和读取的数据是否一致 + +编译和烧录 +----------------------------- + +参考 :ref:`linux_cmd` 或者 :ref:`windows_cmd` + +实验现象 +----------------------------- + +按下 RST 按键,数据传输完成后,打印“write over”,“read over”和“check over”。 \ No newline at end of file diff --git a/docs/source/samples/peripherals/i2c/i2c_eeprom_dma.rst b/docs/source/samples/peripherals/i2c/i2c_eeprom_dma.rst new file mode 100644 index 00000000..a9fd472e --- /dev/null +++ b/docs/source/samples/peripherals/i2c/i2c_eeprom_dma.rst @@ -0,0 +1,202 @@ +I2C - eeprom_dma +==================== + +本 demo 主要介绍 I2C 使用 DMA 的方式读写 eeprom。 + +硬件连接 +----------------------------- + +本 demo 使用到的 gpio 参考 ``board_i2c0_gpio_init`` ,将 eeprom 模块与开发板连接,具体引脚连接方式如下表(以BL616为例): + +.. table:: 硬件连接 + :widths: 50, 50 + :width: 80% + :align: center + + +-------------------+------------------+ + | 开发板 I2C 引脚 | eeprom 模块 | + +===================+==================+ + | SCL(GPIO14) | SCL | + +-------------------+------------------+ + | SDA(GPIO15) | SDA | + +-------------------+------------------+ + | GND | GND | + +-------------------+------------------+ + | VCC | VCC | + +-------------------+------------------+ + +软件实现 +----------------------------- + +更详细的代码请参考 **examples/peripherals/i2c/i2c_eeprom_dma** + +.. code-block:: C + :linenos: + + board_init(); + +- ``board_init`` 中会开启 I2C IP 时钟,并选择 I2C 时钟源和分频。 + +.. code-block:: C + :linenos: + + board_i2c0_gpio_init(); + +- 配置相关引脚为 `I2C` 功能 + +.. code-block:: C + :linenos: + + /* Send and receive buffer init */ + for (size_t i = 0; i < 32; i++) { + ((uint8_t *)send_buffer)[i] = i; + ((uint8_t *)receive_buffer)[i] = 0; + } + + i2c0 = bflb_device_get_by_name("i2c0"); + + bflb_i2c_init(i2c0, 400000); + bflb_i2c_link_txdma(i2c0, true); + bflb_i2c_link_rxdma(i2c0, true); + +- 初始化发送和接收 buffer +- 获取 `i2c0` 句柄,并初始化 i2c0 频率为 400K +- ``bflb_i2c_link_txdma(i2c0, true)`` 开启 I2C TX DMA 功能 +- ``bflb_i2c_link_rxdma(i2c0, true)`` 开启 I2C RX DMA 功能 + +.. code-block:: C + :linenos: + + /* Write page 0 */ + dma0_ch0 = bflb_device_get_by_name("dma0_ch0"); + + struct bflb_dma_channel_config_s tx_config; + + tx_config.direction = DMA_MEMORY_TO_PERIPH; + tx_config.src_req = DMA_REQUEST_NONE; + tx_config.dst_req = DMA_REQUEST_I2C0_TX; + tx_config.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE; + tx_config.dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE; + tx_config.src_burst_count = DMA_BURST_INCR1; + tx_config.dst_burst_count = DMA_BURST_INCR1; + tx_config.src_width = DMA_DATA_WIDTH_32BIT; + tx_config.dst_width = DMA_DATA_WIDTH_32BIT; + bflb_dma_channel_init(dma0_ch0, &tx_config); + + bflb_dma_channel_irq_attach(dma0_ch0, dma0_ch0_isr, NULL); + +- 对于 TX, DMA 的配置如下:传输方向(direction)为内存到外设(MEMORY_TO_PERIPH),源请求(src_req)为内存,目标请求(dst_req)为 DMA_REQUEST_I2C0_TX +- 调用 ``bflb_dma_channel_init(dma0_ch0, &tx_config)`` 初始化 DMA +- 调用 ``bflb_dma_channel_irq_attach(dma0_ch0, dma0_ch0_isr, NULL)`` 注册 dma 通道 0 中断 + +.. code-block:: C + :linenos: + + struct bflb_dma_channel_lli_pool_s tx_llipool[20]; /* max trasnfer size 4064 * 20 */ + struct bflb_dma_channel_lli_transfer_s tx_transfers[1]; + tx_transfers[0].src_addr = (uint32_t)send_buffer; + tx_transfers[0].dst_addr = (uint32_t)DMA_ADDR_I2C0_TDR; + tx_transfers[0].nbytes = 32; + bflb_dma_channel_lli_reload(dma0_ch0, tx_llipool, 20, tx_transfers, 1); + + msgs[0].addr = 0x50; + msgs[0].flags = I2C_M_NOSTOP; + msgs[0].buffer = subaddr; + msgs[0].length = 2; + + msgs[1].addr = 0x50; + msgs[1].flags = I2C_M_DMA; + msgs[1].buffer = NULL; + msgs[1].length = 32; + bflb_i2c_transfer(i2c0, msgs, 2); + + bflb_dma_channel_start(dma0_ch0); + +- 分配二十块 lli 内存池,最多可以传输 4064 * 20 字节 +- 配置一块内存(tx_transfers)进行传输,源地址(src_addr)为存储发送数据的内存地址(send_buffer),目标地址(dst_addr)为 I2C TX FIFO地址(DMA_ADDR_I2C0_TDR) +- 调用 ``bflb_dma_channel_lli_reload(dma0_ch0, tx_llipool, 20, tx_transfers, 1)`` 初始化 +- 调用 ``bflb_i2c_transfer(i2c0, msgs, 2)`` 开启 I2C 传输 +- 调用 ``bflb_dma_channel_start(dma0_ch0)`` 启动 DMA 传输 + +.. code-block:: C + :linenos: + + /* Read page 0 */ + dma0_ch1 = bflb_device_get_by_name("dma0_ch1"); + + struct bflb_dma_channel_config_s rx_config; + + rx_config.direction = DMA_PERIPH_TO_MEMORY; + rx_config.src_req = DMA_REQUEST_I2C0_RX; + rx_config.dst_req = DMA_REQUEST_NONE; + rx_config.src_addr_inc = DMA_ADDR_INCREMENT_DISABLE; + rx_config.dst_addr_inc = DMA_ADDR_INCREMENT_ENABLE; + rx_config.src_burst_count = DMA_BURST_INCR1; + rx_config.dst_burst_count = DMA_BURST_INCR1; + rx_config.src_width = DMA_DATA_WIDTH_32BIT; + rx_config.dst_width = DMA_DATA_WIDTH_32BIT; + bflb_dma_channel_init(dma0_ch1, &rx_config); + + bflb_dma_channel_irq_attach(dma0_ch1, dma0_ch1_isr, NULL); + +- 对于 RX, DMA 的配置如下:传输方向(direction)为外设到内存(PERIPH_TO_MEMORY),源请求(src_req)为 DMA_REQUEST_I2C0_RX ,目标请求(dst_req)为内存 +- 调用 ``bflb_dma_channel_init(dma0_ch1, &rx_config)`` 初始化 DMA +- 调用 ``bflb_dma_channel_irq_attach(dma0_ch1, dma0_ch1_isr, NULL)`` 注册 dma 通道 1 中断 + +.. code-block:: C + :linenos: + + struct bflb_dma_channel_lli_pool_s rx_llipool[20]; + struct bflb_dma_channel_lli_transfer_s rx_transfers[1]; + rx_transfers[0].src_addr = (uint32_t)DMA_ADDR_I2C0_RDR; + rx_transfers[0].dst_addr = (uint32_t)receive_buffer; + rx_transfers[0].nbytes = 32; + + bflb_dma_channel_lli_reload(dma0_ch1, rx_llipool, 20, rx_transfers, 1); + + msgs[1].addr = 0x50; + msgs[1].flags = I2C_M_DMA | I2C_M_READ; + msgs[1].buffer = NULL; + msgs[1].length = 32; + bflb_i2c_transfer(i2c0, msgs, 2); + + bflb_dma_channel_start(dma0_ch1); + +- 分配二十块 lli 内存池,最多可以传输 4064 * 20 字节 +- 配置一块内存(rx_transfers)进行传输,源地址(src_addr)为 I2C RX FIFO地址(DMA_ADDR_I2C0_RDR),目标地址(dst_addr)为存储接收数据的内存地址(receive_buffer) +- 调用 ``bflb_dma_channel_lli_reload(dma0_ch1, rx_llipool, 20, rx_transfers, 1)`` 初始化 +- 调用 ``bflb_i2c_transfer(i2c0, msgs, 2)`` 开启 I2C 传输 +- 调用 ``bflb_dma_channel_start(dma0_ch1)`` 启动 DMA 传输 + +.. code-block:: C + :linenos: + + while (dma_tc_flag1 == 0) { + } + while ((bflb_i2c_get_intstatus(i2c0) & I2C_INTSTS_END) == 0) { + } + bflb_i2c_deinit(i2c0); + +- 数据传输完成后,复位 I2C 模块 + +.. code-block:: C + :linenos: + + /* Check read data */ + for (uint8_t i = 0; i < 32; i++) { + if (((uint8_t *)send_buffer)[i] != ((uint8_t *)receive_buffer)[i]) { + printf("check fail, %d write: %02x, read: %02x\r\n", i, ((uint8_t *)send_buffer)[i], ((uint8_t *)receive_buffer)[i]); + } + } + +- 检查发送和读取的数据是否一致 + +编译和烧录 +----------------------------- + +参考 :ref:`linux_cmd` 或者 :ref:`windows_cmd` + +实验现象 +----------------------------- + +按下 RST 按键,数据传输完成后,打印“write over”,“read over”和“check over”。 \ No newline at end of file diff --git a/docs/source/samples/peripherals/i2c/i2c_eeprom_interrupt.rst b/docs/source/samples/peripherals/i2c/i2c_eeprom_interrupt.rst new file mode 100644 index 00000000..29642bfa --- /dev/null +++ b/docs/source/samples/peripherals/i2c/i2c_eeprom_interrupt.rst @@ -0,0 +1,210 @@ +I2C - eeprom_interrupt +==================== + +本 demo 主要介绍 I2C 使用中断的方式读写 eeprom。 + +硬件连接 +----------------------------- + +本 demo 使用到的 gpio 参考 ``board_i2c0_gpio_init`` ,将 eeprom 模块与开发板连接,具体引脚连接方式如下表(以BL616为例): + +.. table:: 硬件连接 + :widths: 50, 50 + :width: 80% + :align: center + + +-------------------+------------------+ + | 开发板 I2C 引脚 | eeprom 模块 | + +===================+==================+ + | SCL(GPIO14) | SCL | + +-------------------+------------------+ + | SDA(GPIO15) | SDA | + +-------------------+------------------+ + | GND | GND | + +-------------------+------------------+ + | VCC | VCC | + +-------------------+------------------+ + +软件实现 +----------------------------- + +更详细的代码请参考 **examples/peripherals/i2c/i2c_eeprom_interrupt** + +.. code-block:: C + :linenos: + + board_init(); + +- ``board_init`` 中会开启 I2C IP 时钟,并选择 I2C 时钟源和分频。 + +.. code-block:: C + :linenos: + + board_i2c0_gpio_init(); + +- 配置相关引脚为 `I2C` 功能 + +.. code-block:: C + :linenos: + + i2c0 = bflb_device_get_by_name("i2c0"); + + bflb_i2c_init(i2c0, 400000); + +- 获取 `i2c0` 句柄,并初始化 i2c0 频率为 400K + +.. code-block:: C + :linenos: + + /* Set i2c interrupt */ + bflb_i2c_int_mask(i2c0, I2C_INTEN_END | I2C_INTEN_TX_FIFO | I2C_INTEN_RX_FIFO | I2C_INTEN_NACK | I2C_INTEN_ARB | I2C_INTEN_FER, false); + bflb_irq_attach(i2c0->irq_num, i2c_isr, NULL); + bflb_irq_enable(i2c0->irq_num); + +- 调用 ``bflb_i2c_int_mask(i2c0, I2C_INTEN_END | I2C_INTEN_TX_FIFO | I2C_INTEN_RX_FIFO | I2C_INTEN_NACK | I2C_INTEN_ARB | I2C_INTEN_FER, false)`` 打开 I2C 中断 +- 注册 I2C 中断 + +.. code-block:: C + :linenos: + + uint8_t write_data[256]; + uint8_t read_data[256]; + + /* Write and read buffer init */ + for (size_t i = 0; i < 256; i++) { + write_data[i] = i; + read_data[i] = 0; + } + +- 初始化发送和接收 buffer + +.. code-block:: C + :linenos: + + /* Write page 0 */ + subaddr[1] = EEPROM_SELECT_PAGE0; + + msgs[0].addr = 0x50; + msgs[0].flags = I2C_M_NOSTOP; + msgs[0].buffer = subaddr; + msgs[0].length = 2; + + msgs[1].addr = 0x50; + msgs[1].flags = 0; + msgs[1].buffer = write_data; + msgs[1].length = EEPROM_TRANSFER_LENGTH; + + bflb_i2c_transfer(i2c0, msgs, 2); + if (txFifoFlag) { + printf("TX FIFO Ready interrupt generated\r\n"); + txFifoFlag = 0; + } + if (rxFifoFlag) { + printf("RX FIFO Ready interrupt generated\r\n"); + rxFifoFlag = 0; + } + printf("write over\r\n\r\n"); + bflb_mtimer_delay_ms(100); + +- ``bflb_i2c_transfer(i2c0, msgs, 2)`` 开启 i2c 传输 + +.. code-block:: C + :linenos: + + /* Unmask interrupt */ + bflb_i2c_int_mask(i2c0, I2C_INTEN_END | I2C_INTEN_TX_FIFO | I2C_INTEN_RX_FIFO | I2C_INTEN_NACK | I2C_INTEN_ARB | I2C_INTEN_FER, false); + + /* Write page 1 */ + subaddr[1] = EEPROM_SELECT_PAGE1; + + msgs[1].addr = 0x50; + msgs[1].flags = 0; + msgs[1].buffer = write_data + EEPROM_TRANSFER_LENGTH; + msgs[1].length = EEPROM_TRANSFER_LENGTH; + + bflb_i2c_transfer(i2c0, msgs, 2); + if (txFifoFlag) { + printf("TX FIFO Ready interrupt generated\r\n"); + txFifoFlag = 0; + } + if (rxFifoFlag) { + printf("RX FIFO Ready interrupt generated\r\n"); + rxFifoFlag = 0; + } + printf("write over\r\n\r\n"); + bflb_mtimer_delay_ms(100); + +- 开启 I2C 中断,进行第二次数据传输 + +.. code-block:: C + :linenos: + + /* Unmask interrupt */ + bflb_i2c_int_mask(i2c0, I2C_INTEN_END | I2C_INTEN_TX_FIFO | I2C_INTEN_RX_FIFO | I2C_INTEN_NACK | I2C_INTEN_ARB | I2C_INTEN_FER, false); + + /* Read page 0 */ + subaddr[1] = EEPROM_SELECT_PAGE0; + + msgs[1].addr = 0x50; + msgs[1].flags = I2C_M_READ; + msgs[1].buffer = read_data; + msgs[1].length = EEPROM_TRANSFER_LENGTH; + bflb_i2c_transfer(i2c0, msgs, 2); + if (txFifoFlag) { + printf("TX FIFO Ready interrupt generated\r\n"); + txFifoFlag = 0; + } + if (rxFifoFlag) { + printf("RX FIFO Ready interrupt generated\r\n"); + rxFifoFlag = 0; + } + printf("read over\r\n\r\n"); + +- 读取 eeprom 的数据 + +.. code-block:: C + :linenos: + + /* Unmask interrupt */ + bflb_i2c_int_mask(i2c0, I2C_INTEN_END | I2C_INTEN_TX_FIFO | I2C_INTEN_RX_FIFO | I2C_INTEN_NACK | I2C_INTEN_ARB | I2C_INTEN_FER, false); + + /* Read page 1 */ + subaddr[1] = EEPROM_SELECT_PAGE1; + + msgs[1].addr = 0x50; + msgs[1].flags = I2C_M_READ; + msgs[1].buffer = read_data + EEPROM_TRANSFER_LENGTH; + msgs[1].length = EEPROM_TRANSFER_LENGTH; + bflb_i2c_transfer(i2c0, msgs, 2); + if (txFifoFlag) { + printf("TX FIFO Ready interrupt generated\r\n"); + txFifoFlag = 0; + } + if (rxFifoFlag) { + printf("RX FIFO Ready interrupt generated\r\n"); + rxFifoFlag = 0; + } + +- 第二次读取数据 + +.. code-block:: C + :linenos: + + /* Check read data */ + for (uint8_t i = 0; i < 2 * EEPROM_TRANSFER_LENGTH; i++) { + if (write_data[i] != read_data[i]) { + printf("check fail, %d write: %02x, read: %02x\r\n", i, write_data[i], read_data[i]); + } + } + +- 检查发送和读取的数据是否一致 + +编译和烧录 +----------------------------- + +参考 :ref:`linux_cmd` 或者 :ref:`windows_cmd` + +实验现象 +----------------------------- + +按下 RST 按键,数据传输完成后,打印“write over”,“read over”和“check over”。 \ No newline at end of file diff --git a/docs/source/samples/peripherals/i2c/index.rst b/docs/source/samples/peripherals/i2c/index.rst new file mode 100644 index 00000000..d0a9c549 --- /dev/null +++ b/docs/source/samples/peripherals/i2c/index.rst @@ -0,0 +1,34 @@ +==== +I2C +==== + +.. toctree:: + :maxdepth: 1 + + I2C - 10-bit + I2C - eeprom + I2C - eeprom_dma + I2C - eeprom_interrupt + +I2C 信号引脚对应的 GPIO 如下表: + +.. table:: GPIO 口 + :widths: 30, 30, 40 + :width: 80% + :align: center + + +----------+-----------+---------------------------+ + | 信号 | 芯片系列 | GPIO | + +==========+===========+===========================+ + | SCL | BL702 | | + + +-----------+---------------------------+ + | | BL808 | | + + +-----------+---------------------------+ + | | BL616 | GPIO 14 | + +----------+-----------+---------------------------+ + | SDA | BL702 | | + + +-----------+---------------------------+ + | | BL808 | | + + +-----------+---------------------------+ + | | BL616 | GPIO 15 | + +----------+-----------+---------------------------+ \ No newline at end of file diff --git a/docs/source/samples/peripherals/index.rst b/docs/source/samples/peripherals/index.rst index 89c9894b..d83df3e7 100644 --- a/docs/source/samples/peripherals/index.rst +++ b/docs/source/samples/peripherals/index.rst @@ -9,4 +9,8 @@ Peripherals ADC DAC + GPIO + I2C + IR + ISO11898 UART diff --git a/docs/source/samples/peripherals/ir/index.rst b/docs/source/samples/peripherals/ir/index.rst new file mode 100644 index 00000000..c678ae17 --- /dev/null +++ b/docs/source/samples/peripherals/ir/index.rst @@ -0,0 +1,34 @@ +==== +IR +==== + +.. toctree:: + :maxdepth: 1 + + IR - nec + IR - rc5 + IR - swm + IR - tx_dma + +各系列芯片对 IR 接收和发送的支持情况如下表: + +.. table:: GPIO 口 + :widths: 30, 30, 40 + :width: 80% + :align: center + + +----------+-----------+---------------------------+ + | 信号 | 芯片系列 | GPIO | + +==========+===========+===========================+ + | IR TX | BL702 | 支持 | + + +-----------+---------------------------+ + | | BL808 | 支持 | + + +-----------+---------------------------+ + | | BL616 | 不支持 | + +----------+-----------+---------------------------+ + | IR RX | BL702 | 支持 | + + +-----------+---------------------------+ + | | BL808 | 支持 | + + +-----------+---------------------------+ + | | BL616 | 支持 | + +----------+-----------+---------------------------+ \ No newline at end of file diff --git a/docs/source/samples/peripherals/ir/ir_nec.rst b/docs/source/samples/peripherals/ir/ir_nec.rst new file mode 100644 index 00000000..948ffb60 --- /dev/null +++ b/docs/source/samples/peripherals/ir/ir_nec.rst @@ -0,0 +1,115 @@ +IR - nec +==================== + +本 demo 主要介绍 IR 以 nec 协议收发数据。 + +硬件连接 +----------------------------- + +本 demo 使用到的 gpio 参考 ``board_ir_gpio_init`` ,将红外发射二极管和接收头与 IR 引脚连接,具体连接方式如下表(以BL808为例): + +.. table:: 硬件连接 + :widths: 50, 50 + :width: 80% + :align: center + + +-------------------+----------------------+ + | 开发板 IR 引脚 | 外接模块 | + +===================+======================+ + | VCC | 红外接收头 VCC | + +-------------------+----------------------+ + | GND | 红外接收头 GND | + +-------------------+----------------------+ + | RX(GPIO17) | 红外接收头 OUT | + +-------------------+----------------------+ + | VCC | 红外发射二极管正极 | + +-------------------+----------------------+ + | TX(GPIO11) | 红外发射二极管负极 | + +-------------------+----------------------+ + +软件实现 +----------------------------- + +更详细的代码请参考 **examples/peripherals/ir/ir_nec** + +.. code-block:: C + :linenos: + + board_init(); + +- ``board_init`` 中会开启 IR 时钟,并选择 IR 时钟源和分频。 + +.. code-block:: C + :linenos: + + board_ir_gpio_init(); + +- 配置相关引脚为 `IR` 功能 + +.. code-block:: C + :linenos: + + uint32_t tx_buffer[1] = { 0xE916FF00 }; + struct bflb_ir_tx_config_s tx_cfg; + + irtx = bflb_device_get_by_name("irtx"); + + /* TX init */ + tx_cfg.tx_mode = IR_TX_NEC; + bflb_ir_tx_init(irtx, &tx_cfg); + +- 获取 `irtx` 句柄 +- 设置 tx_mode 为 NEC 模式,调用 ``bflb_ir_tx_init(irtx, &tx_cfg)`` 初始化 ir tx + +.. code-block:: C + :linenos: + + uint64_t rx_data; + uint8_t rx_len; + struct bflb_ir_rx_config_s rx_cfg; + + irrx = bflb_device_get_by_name("irrx"); + + /* RX init */ + rx_cfg.rx_mode = IR_RX_NEC; + rx_cfg.input_inverse = true; + rx_cfg.deglitch_enable = false; + bflb_ir_rx_init(irrx, &rx_cfg); + + /* Enable rx, wait for sending */ + bflb_ir_rx_enable(irrx, true); + +- 获取 `irrx` 句柄 +- 设置 rx_mode 为 NEC 模式,调用 ``bflb_ir_rx_init(irrx, &rx_cfg)`` 初始化 ir rx +- 调用 ``bflb_ir_rx_enable(irrx, true)`` 使能 ir rx,等待数据发送 + +.. code-block:: C + :linenos: + + bflb_ir_send(irtx, tx_buffer, 1); + rx_len = bflb_ir_receive(irrx, &rx_data); + +- 调用 ``bflb_ir_send(irtx, tx_buffer, 1)`` 发送 tx_buffer 中的数据 +- 调用 ``bflb_ir_receive(irrx, &rx_data)`` 将接收到的数据存放在 rx_data 中 + +.. code-block:: C + :linenos: + + /* Check data received */ + if (rx_data != tx_buffer[0]) { + printf("Data error! receive bit: %d, value: 0x%016lx\r\n", rx_len, rx_data); + } else { + printf("Received correctly. receive bit: %d, value: 0x%016lx\r\n", rx_len, rx_data); + } + +- 检查发送和接收的数据是否一致 + +编译和烧录 +----------------------------- + +参考 :ref:`linux_cmd` 或者 :ref:`windows_cmd` + +实验现象 +----------------------------- + +按下开发板中 RST 按键,串口打印接收到的数据。 diff --git a/docs/source/samples/peripherals/ir/ir_rc5.rst b/docs/source/samples/peripherals/ir/ir_rc5.rst new file mode 100644 index 00000000..a6121572 --- /dev/null +++ b/docs/source/samples/peripherals/ir/ir_rc5.rst @@ -0,0 +1,115 @@ +IR - rc5 +==================== + +本 demo 主要介绍 IR 以 rc5 协议收发数据。 + +硬件连接 +----------------------------- + +本 demo 使用到的 gpio 参考 ``board_ir_gpio_init`` ,将红外发射二极管和接收头与 IR 引脚连接,具体连接方式如下表(以BL808为例): + +.. table:: 硬件连接 + :widths: 50, 50 + :width: 80% + :align: center + + +-------------------+----------------------+ + | 开发板 IR 引脚 | 外接模块 | + +===================+======================+ + | VCC | 红外接收头 VCC | + +-------------------+----------------------+ + | GND | 红外接收头 GND | + +-------------------+----------------------+ + | RX(GPIO17) | 红外接收头 OUT | + +-------------------+----------------------+ + | VCC | 红外发射二极管正极 | + +-------------------+----------------------+ + | TX(GPIO11) | 红外发射二极管负极 | + +-------------------+----------------------+ + +软件实现 +----------------------------- + +更详细的代码请参考 **examples/peripherals/ir/ir_rc5** + +.. code-block:: C + :linenos: + + board_init(); + +- ``board_init`` 中会开启 IR 时钟,并选择 IR 时钟源和分频。 + +.. code-block:: C + :linenos: + + board_ir_gpio_init(); + +- 配置相关引脚为 `IR` 功能 + +.. code-block:: C + :linenos: + + uint32_t tx_buffer[1] = { 0x123D }; + struct bflb_ir_tx_config_s tx_cfg; + + irtx = bflb_device_get_by_name("irtx"); + + /* TX init */ + tx_cfg.tx_mode = IR_TX_RC5; + bflb_ir_tx_init(irtx, &tx_cfg); + +- 获取 `irtx` 句柄 +- 设置 tx_mode 为 RC5 模式,调用 ``bflb_ir_tx_init(irtx, &tx_cfg)`` 初始化 ir tx + +.. code-block:: C + :linenos: + + uint64_t rx_data; + uint8_t rx_len; + struct bflb_ir_rx_config_s rx_cfg; + + irrx = bflb_device_get_by_name("irrx"); + + /* RX init */ + rx_cfg.rx_mode = IR_RX_RC5; + rx_cfg.input_inverse = true; + rx_cfg.deglitch_enable = false; + bflb_ir_rx_init(irrx, &rx_cfg); + + /* Enable rx, wait for sending */ + bflb_ir_rx_enable(irrx, true); + +- 获取 `irrx` 句柄 +- 设置 rx_mode 为 RC5 模式,调用 ``bflb_ir_rx_init(irrx, &rx_cfg)`` 初始化 ir rx +- 调用 ``bflb_ir_rx_enable(irrx, true)`` 使能 ir rx,等待数据发送 + +.. code-block:: C + :linenos: + + bflb_ir_send(irtx, tx_buffer, 1); + rx_len = bflb_ir_receive(irrx, &rx_data); + +- 调用 ``bflb_ir_send(irtx, tx_buffer, 1)`` 发送 tx_buffer 中的数据 +- 调用 ``bflb_ir_receive(irrx, &rx_data)`` 将接收到的数据存放在 rx_data 中 + +.. code-block:: C + :linenos: + + /* Check data received */ + if (rx_data != tx_buffer[0]) { + printf("Data error! receive bit: %d, value: 0x%016lx\r\n", rx_len, rx_data); + } else { + printf("Received correctly. receive bit: %d, value: 0x%016lx\r\n", rx_len, rx_data); + } + +- 检查发送和接收的数据是否一致 + +编译和烧录 +----------------------------- + +参考 :ref:`linux_cmd` 或者 :ref:`windows_cmd` + +实验现象 +----------------------------- + +按下开发板中 RST 按键,串口打印接收到的数据。 diff --git a/docs/source/samples/peripherals/ir/ir_swm.rst b/docs/source/samples/peripherals/ir/ir_swm.rst new file mode 100644 index 00000000..db828c7c --- /dev/null +++ b/docs/source/samples/peripherals/ir/ir_swm.rst @@ -0,0 +1,105 @@ +IR - swm +==================== + +本 demo 主要介绍 IR 以软件模式收发数据。 + +硬件连接 +----------------------------- + +本 demo 使用到的 gpio 参考 ``board_ir_gpio_init`` ,将红外发射二极管和接收头与 IR 引脚连接,具体连接方式如下表(以BL808为例): + +.. table:: 硬件连接 + :widths: 50, 50 + :width: 80% + :align: center + + +-------------------+----------------------+ + | 开发板 IR 引脚 | 外接模块 | + +===================+======================+ + | VCC | 红外接收头 VCC | + +-------------------+----------------------+ + | GND | 红外接收头 GND | + +-------------------+----------------------+ + | RX(GPIO17) | 红外接收头 OUT | + +-------------------+----------------------+ + | VCC | 红外发射二极管正极 | + +-------------------+----------------------+ + | TX(GPIO11) | 红外发射二极管负极 | + +-------------------+----------------------+ + +软件实现 +----------------------------- + +更详细的代码请参考 **examples/peripherals/ir/ir_swm** + +.. code-block:: C + :linenos: + + board_init(); + +- ``board_init`` 中会开启 IR 时钟,并选择 IR 时钟源和分频。 + +.. code-block:: C + :linenos: + + board_ir_gpio_init(); + +- 配置相关引脚为 `IR` 功能 + +.. code-block:: C + :linenos: + + uint16_t tx_buffer[] = { 1777, 1777, 3555, 3555, 1777, 1777, 1777, 1777, 1777, 1777, + 3555, 1777, 1777, 1777, 1777, 3555, 3555, 1777, 1777, 3555, 1777 }; + struct bflb_ir_tx_config_s tx_cfg; + + irtx = bflb_device_get_by_name("irtx"); + + /* TX init */ + tx_cfg.tx_mode = IR_TX_SWM; + bflb_ir_tx_init(irtx, &tx_cfg); + +- 获取 `irtx` 句柄 +- 设置 tx_mode 为 SWM 模式,调用 ``bflb_ir_tx_init(irtx, &tx_cfg)`` 初始化 ir tx + +.. code-block:: C + :linenos: + + uint16_t rx_buffer[30]; + uint8_t rx_len; + struct bflb_ir_rx_config_s rx_cfg; + + irrx = bflb_device_get_by_name("irrx"); + + /* RX init */ + rx_cfg.rx_mode = IR_RX_SWM; + rx_cfg.input_inverse = true; + rx_cfg.deglitch_enable = false; + rx_cfg.end_threshold = 3999; + bflb_ir_rx_init(irrx, &rx_cfg); + + /* Enable rx, wait for sending */ + bflb_ir_rx_enable(irrx, true); + +- 获取 `irrx` 句柄 +- 设置 rx_mode 为 SWM 模式,调用 ``bflb_ir_rx_init(irrx, &rx_cfg)`` 初始化 ir rx +- 调用 ``bflb_ir_rx_enable(irrx, true)`` 使能 ir rx,等待数据发送 + +.. code-block:: C + :linenos: + + bflb_ir_swm_send(irtx, tx_buffer, sizeof(tx_buffer) / sizeof(tx_buffer[0])); + rx_len = bflb_ir_swm_receive(irrx, rx_buffer, 30); + +- 调用 ``bflb_ir_swm_send(irtx, tx_buffer, sizeof(tx_buffer) / sizeof(tx_buffer[0]))`` 发送 tx_buffer 中的数据 +- 调用 ``bflb_ir_swm_receive(irrx, rx_buffer, 30)`` 将接收到的数据存放在 rx_buffer 中 + +编译和烧录 +----------------------------- + +参考 :ref:`linux_cmd` 或者 :ref:`windows_cmd` + +实验现象 +----------------------------- + +按下开发板中 RST 按键,串口打印接收到的数据。 diff --git a/docs/source/samples/peripherals/ir/ir_tx_dma.rst b/docs/source/samples/peripherals/ir/ir_tx_dma.rst new file mode 100644 index 00000000..55565dc0 --- /dev/null +++ b/docs/source/samples/peripherals/ir/ir_tx_dma.rst @@ -0,0 +1,151 @@ +IR - tx_dma +==================== + +本 demo 主要介绍 IR 使用 DMA 的方式发送数据。 + +硬件连接 +----------------------------- + +本 demo 使用到的 gpio 参考 ``board_ir_gpio_init`` ,将红外发射二极管与 IR 引脚连接,具体连接方式如下表(以BL808为例): + +.. table:: 硬件连接 + :widths: 50, 50 + :width: 80% + :align: center + + +-------------------+----------------------+ + | 开发板 IR 引脚 | 外接模块 | + +===================+======================+ + | VCC | 红外发射二极管正极 | + +-------------------+----------------------+ + | TX(GPIO11) | 红外发射二极管负极 | + +-------------------+----------------------+ + +软件实现 +----------------------------- + +更详细的代码请参考 **examples/peripherals/ir/ir_tx_dma** + +.. code-block:: C + :linenos: + + board_init(); + +- ``board_init`` 中会开启 IR 时钟,并选择 IR 时钟源和分频。 + +.. code-block:: C + :linenos: + + board_ir_gpio_init(); + +- 配置相关引脚为 `IR` 功能 + +.. code-block:: C + :linenos: + + struct bflb_ir_tx_config_s tx_cfg = { + .tx_mode = IR_TX_CUSTOMIZE, + .data_bits = 0, + .tail_inverse = 0, + .tail_enable = 0, + .head_inverse = 0, + .head_enable = 0, + .logic1_inverse = 1, + .logic0_inverse = 1, + .data_enable = 1, + .swm_enable = 0, + .output_modulation = 1, + .output_inverse = 0, + .freerun_enable = 1, + .continue_enable = 1, + .fifo_width = IR_TX_FIFO_WIDTH_24BIT, + .fifo_threshold = 1, + .logic0_pulse_width_1 = 0, + .logic0_pulse_width_0 = 0, + .logic1_pulse_width_1 = 2, + .logic1_pulse_width_0 = 0, + .head_pulse_width_1 = 0, + .head_pulse_width_0 = 0, + .tail_pulse_width_1 = 0, + .tail_pulse_width_0 = 0, + .modu_width_1 = 17, + .modu_width_0 = 34, + .pulse_width_unit = 1124, + }; + + irtx = bflb_device_get_by_name("irtx"); + + /* TX init */ + bflb_ir_tx_init(irtx, &tx_cfg); + bflb_ir_link_txdma(irtx, true); + bflb_ir_tx_enable(irtx, true); + +- 获取 `irtx` 句柄 +- 设置 tx_mode 为 IR_TX_CUSTOMIZE 模式,调用 ``bflb_ir_tx_init(irtx, &tx_cfg)`` 初始化 ir tx +- 调用 ``bflb_ir_link_txdma(irtx, true)`` 使能 ir tx dma 功能 +- 调用 ``bflb_ir_tx_enable(irtx, true)`` 开启 ir tx + +.. code-block:: C + :linenos: + + struct bflb_dma_channel_config_s dma_config = { + .direction = DMA_MEMORY_TO_PERIPH, + .src_req = DMA_REQUEST_NONE, + .dst_req = DMA_REQUEST_IR_TX, + .src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, + .dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE, + .src_burst_count = DMA_BURST_INCR1, + .dst_burst_count = DMA_BURST_INCR1, + .src_width = DMA_DATA_WIDTH_32BIT, + .dst_width = DMA_DATA_WIDTH_32BIT, + }; + + for (i = 0; i < 128; i++) { + tx_buffer[i] = i * 0x01010101; + } + + dma0_ch0 = bflb_device_get_by_name("dma0_ch0"); + bflb_dma_channel_init(dma0_ch0, &dma_config); + bflb_dma_channel_irq_attach(dma0_ch0, dma0_ch0_isr, NULL); + +- 对于 TX, DMA 的配置如下:传输方向(direction)为内存到外设(MEMORY_TO_PERIPH),源请求(src_req)为内存,目标请求(dst_req)为 DMA_REQUEST_IR_TX +- 初始化 tx_buffer +- 调用 ``bflb_dma_channel_init(dma0_ch0, &dma_config)`` 初始化 DMA +- 调用 ``bflb_dma_channel_irq_attach(dma0_ch0, dma0_ch0_isr, NULL)`` 注册 dma 通道 0 中断 + +.. code-block:: C + :linenos: + + struct bflb_dma_channel_lli_pool_s tx_llipool[1]; + struct bflb_dma_channel_lli_transfer_s tx_transfers[1]; + + tx_transfers[0].src_addr = (uint32_t)tx_buffer; + tx_transfers[0].dst_addr = (uint32_t)DMA_ADDR_IR_TDR; + tx_transfers[0].nbytes = 128 * 4; + bflb_dma_channel_lli_reload(dma0_ch0, tx_llipool, 1, tx_transfers, 1); + bflb_dma_channel_start(dma0_ch0); + +- 分配一块 lli 内存池,最多可以传输 4064 * 1 字节 +- 配置一块内存(tx_transfers)进行传输,源地址(src_addr)为存储发送数据的内存地址(tx_buffer),目标地址(dst_addr)为 IR TX FIFO地址(DMA_ADDR_IR_TDR) +- 调用 ``bflb_dma_channel_lli_reload(dma0_ch0, tx_llipool, 1, tx_transfers, 1)`` 初始化 +- 调用 ``bflb_dma_channel_start(dma0_ch0)`` 启动 DMA 传输 + +.. code-block:: C + :linenos: + + while (dma_tc_flag0 != 1) { + bflb_mtimer_delay_ms(1); + } + printf("Check wave\r\n"); + +- DMA 传输完成后,查看波形 + +编译和烧录 +----------------------------- + +参考 :ref:`linux_cmd` 或者 :ref:`windows_cmd` + +实验现象 +----------------------------- + +按下 RST 按键,数据传输完成后,查看波形是否正确。 \ No newline at end of file diff --git a/docs/source/samples/peripherals/iso11898/index.rst b/docs/source/samples/peripherals/iso11898/index.rst new file mode 100644 index 00000000..4cd442fe --- /dev/null +++ b/docs/source/samples/peripherals/iso11898/index.rst @@ -0,0 +1,32 @@ +==== +ISO11898 +==== + +.. toctree:: + :maxdepth: 1 + + ISO11898 - filter + ISO11898 - selftest + +ISO11898 引脚对应的 GPIO 如下表: + +.. table:: GPIO 口 + :widths: 30, 30, 40 + :width: 80% + :align: center + + +----------+-----------+---------------------------+ + | 名称 | 芯片系列 | GPIO | + +==========+===========+===========================+ + | TX | BL702 | | + + +-----------+---------------------------+ + | | BL808 | | + + +-----------+---------------------------+ + | | BL616 | GPIO 0 | + +----------+-----------+---------------------------+ + | RX | BL702 | | + + +-----------+---------------------------+ + | | BL808 | | + + +-----------+---------------------------+ + | | BL616 | GPIO 1 | + +----------+-----------+---------------------------+ \ No newline at end of file diff --git a/docs/source/samples/peripherals/iso11898/iso11898_selftest.rst b/docs/source/samples/peripherals/iso11898/iso11898_selftest.rst new file mode 100644 index 00000000..5437f7a9 --- /dev/null +++ b/docs/source/samples/peripherals/iso11898/iso11898_selftest.rst @@ -0,0 +1,68 @@ +ISO11898 - selftest +==================== + +本 demo 主要介绍 ISO11898 数据自发自收。 + +硬件连接 +----------------------------- + +本 demo 使用到的 gpio 参考 ``board_iso11898_gpio_init`` ,将 TX 和 RX 连接。 + +软件实现 +----------------------------- + +更详细的代码请参考 **examples/peripherals/iso11898/iso11898_selftest** + +.. code-block:: C + :linenos: + + board_init(); + +- ``board_init`` 中会开启 ISO11898 时钟,并选择时钟源和分频。 + +.. code-block:: C + :linenos: + + board_iso11898_gpio_init(); + +- 配置相关引脚为 `ISO11898` 功能 + +.. code-block:: C + :linenos: + + iso11898 = bflb_device_get_by_name("iso11898"); + + bflb_iso11898_init(iso11898, &cfg); + bflb_iso11898_set_filter(iso11898, &filter); + ret = bflb_iso11898_send(iso11898, &msg_tx, 1000); + +- 获取 `iso11898` 句柄 +- 调用 ``bflb_iso11898_init(iso11898, &cfg)`` 初始化 iso11898 +- 调用 ``bflb_iso11898_set_filter(iso11898, &filter)`` 开启接收标识符滤波功能 +- 调用 ``bflb_iso11898_send(iso11898, &msg_tx, 1000)`` 发送帧信息,ID 号以及数据 + +.. code-block:: C + :linenos: + + ret = bflb_iso11898_recv(iso11898, &msg_rx, 10000); + +- 调用 ``bflb_iso11898_recv(iso11898, &msg_rx, 10000)`` 将接收到的数据存放在 msg_rx 中 + +.. code-block:: C + :linenos: + + bflb_ir_send(irtx, tx_buffer, 1); + rx_len = bflb_ir_receive(irrx, &rx_data); + +- 调用 ``bflb_ir_send(irtx, tx_buffer, 1)`` 发送 tx_buffer 中的数据 +- 调用 ``bflb_ir_receive(irrx, &rx_data)`` 将接收到的数据存放在 rx_data 中 + +编译和烧录 +----------------------------- + +参考 :ref:`linux_cmd` 或者 :ref:`windows_cmd` + +实验现象 +----------------------------- + +按下开发板中 RST 按键,串口打印接收到的数据。 diff --git a/docs/source/samples/peripherals/uart/uart_dma.rst b/docs/source/samples/peripherals/uart/uart_dma.rst index 61a1ce9d..b24d8b34 100644 --- a/docs/source/samples/peripherals/uart/uart_dma.rst +++ b/docs/source/samples/peripherals/uart/uart_dma.rst @@ -146,14 +146,8 @@ UART - dma 编译和烧录 ----------------------------- -- **命令行编译** - 参考 :ref:`linux_cmd` 或者 :ref:`windows_cmd` -- **烧录** - -参考 :ref:`bl_dev_cube` - 实验现象 ----------------------------- diff --git a/docs/source/samples/peripherals/uart/uart_poll.rst b/docs/source/samples/peripherals/uart/uart_poll.rst index cc306ea8..0091b2fc 100644 --- a/docs/source/samples/peripherals/uart/uart_poll.rst +++ b/docs/source/samples/peripherals/uart/uart_poll.rst @@ -82,14 +82,8 @@ UART - poll 编译和烧录 ----------------------------- -- **命令行编译** - 参考 :ref:`linux_cmd` 或者 :ref:`windows_cmd` -- **烧录** - -参考 :ref:`bl_dev_cube` - 实验现象 -----------------------------