[feat] update peripheral api and demo

This commit is contained in:
jzlv 2021-06-04 17:40:12 +08:00
parent 658b0761db
commit a11dcbed30
341 changed files with 26075 additions and 2575 deletions

View File

@ -1,4 +1,4 @@
# Sphinx build info version 1
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
config: cc25d7d982b3f2727b74849d9127cb3d
config: 5e2136c8889edd21ef4392d0839f5aa1
tags: 645f666f9bcd5a90fca523b33c5a78b7

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

View File

@ -0,0 +1,15 @@
ADC 设备
=========================
简介
------------------------
ADC 设备结构体定义
------------------------
ADC 设备参数配置表
------------------------
ADC 设备接口
------------------------

View File

@ -0,0 +1,60 @@
时钟树
=========================
简介
------------------------
博流系列芯片拥有丰富的时钟源选择,为方便用户配置,提供了时钟树配置表,不需要用户手动调用时钟设置接口,用户只需要关心最终的系统时钟和外设时钟频率即可。时钟配置表位于 ``bsp/board/xxx_board`` 目录下 ``xxx_clock_config.h`` 文件。
时钟频率获取接口
------------------------
**system_clock_get**
^^^^^^^^^^^^^^^^^^^^^^^^
``system_clock_get`` 用来获取系统时钟频率。
.. code-block:: C
uint32_t system_clock_get(enum system_clock_type type);
- type 获取的系统时钟频率类型
``type`` 提供以下几种类型
.. code-block:: C
enum system_clock_type
{
SYSTEM_CLOCK_ROOT_CLOCK = 0,
SYSTEM_CLOCK_FCLK,
SYSTEM_CLOCK_BCLK,
SYSTEM_CLOCK_XCLK,
};
**peripheral_clock_get**
^^^^^^^^^^^^^^^^^^^^^^^^
``peripheral_clock_get`` 用来获取外设时钟频率。
.. code-block:: C
uint32_t peripheral_clock_get(enum peripheral_clock_type type);
- type 获取的外设时钟频率类型
``type`` 提供以下几种类型
.. code-block:: C
enum peripheral_clock_type
{
PERIPHERAL_CLOCK_UART = 0,
PERIPHERAL_CLOCK_SPI,
PERIPHERAL_CLOCK_I2C,
PERIPHERAL_CLOCK_ADC,
PERIPHERAL_CLOCK_DAC,
PERIPHERAL_CLOCK_I2S,
};

View File

@ -0,0 +1,15 @@
DAC 设备
=========================
简介
------------------------
DAC 设备结构体定义
------------------------
DAC 设备参数配置表
------------------------
DAC 设备接口
------------------------

View File

@ -0,0 +1,424 @@
DMA 设备
=========================
简介
------------------------
DMA(Direct Memory Access) 是一种内存存取技术,可以独立地直接读写系统内存,而不需处理器介入处理。在同等
程度的处理器负担下DMA 是一种快速的数据传送方式。博流系列 MCU 中 DMA 设备具有以下特性:
- 控制器有 8 组独立专用通道
- 四种传输方向:内存至内存、内存至外设、外设至内存、外设到外设
- LLI 链表工作模式。
DMA 设备结构体定义
------------------------
.. code-block:: C
typedef struct dma_device
{
struct device parent;
uint8_t id;
uint8_t ch;
uint8_t direction;
uint8_t transfer_mode;
uint32_t src_req;
uint32_t dst_req;
uint8_t src_burst_size;
uint8_t dst_burst_size;
uint8_t src_width;
uint8_t dst_width;
dma_lli_ctrl_t *lli_cfg;
} dma_device_t;
- parent 继承父类属性
- id DMA id号默认0当前只有一个DMA
- ch 通道号
- direction 传输方向
- transfer_mode 传输模式
- src_req 源请求
- dst_req 目标请求
- src_burst_size 源突发字节数
- dst_burst_size 目标突发字节数
- src_width 源传输位宽
- dst_width 目标传输位宽
- lli_cfg 用来存储dma通道的一些信息用户不用管
``direction`` 提供以下类型
.. code-block:: C
typedef enum {
DMA_MEMORY_TO_MEMORY = 0, /*!< DMA transfer tyep:memory to memory */
DMA_MEMORY_TO_PERIPH, /*!< DMA transfer tyep:memory to peripheral */
DMA_PERIPH_TO_MEMORY, /*!< DMA transfer tyep:peripheral to memory */
DMA_PERIPH_TO_PERIPH, /*!< DMA transfer tyep:peripheral to peripheral */
}dma_transfer_dir_type;
``transfer_mode`` 提供以下类型
.. code-block:: C
#define DMA_LLI_ONCE_MODE 0
#define DMA_LLI_CYCLE_MODE 1
``src_req`` 提供以下类型
.. code-block:: C
#define DMA_REQUEST_NONE 0x00000000 /*!< DMA request peripheral:None */
#define DMA_REQUEST_UART0_RX 0x00000000 /*!< DMA request peripheral:UART0 RX */
#define DMA_REQUEST_UART0_TX 0x00000001 /*!< DMA request peripheral:UART0 TX */
#define DMA_REQUEST_UART1_RX 0x00000002 /*!< DMA request peripheral:UART1 RX */
#define DMA_REQUEST_UART1_TX 0x00000003 /*!< DMA request peripheral:UART1 TX */
#define DMA_REQUEST_I2C0_RX 0x00000006 /*!< DMA request peripheral:I2C RX */
#define DMA_REQUEST_I2C0_TX 0x00000007 /*!< DMA request peripheral:I2C TX */
#define DMA_REQUEST_SPI0_RX 0x0000000A /*!< DMA request peripheral:SPI RX */
#define DMA_REQUEST_SPI0_TX 0x0000000B /*!< DMA request peripheral:SPI TX */
#define DMA_REQUEST_I2S_RX 0x00000014 /*!< DMA request peripheral:I2S RX */
#define DMA_REQUEST_I2S_TX 0x00000015 /*!< DMA request peripheral:I2S TX */
#define DMA_REQUEST_ADC0 0x00000016 /*!< DMA request peripheral:ADC0 */
#define DMA_REQUEST_DAC0 0x00000017 /*!< DMA request peripheral:DAC0 */
#define DMA_REQUEST_USB_EP0 0x00000018 /*!< DMA request peripheral:USB EP0*/
#define DMA_REQUEST_USB_EP1 0x00000019 /*!< DMA request peripheral:USB EP1*/
#define DMA_REQUEST_USB_EP2 0x0000001A /*!< DMA request peripheral:USB EP2*/
#define DMA_REQUEST_USB_EP3 0x0000001B /*!< DMA request peripheral:USB EP3*/
#define DMA_REQUEST_USB_EP4 0x0000001C /*!< DMA request peripheral:USB EP4*/
#define DMA_REQUEST_USB_EP5 0x0000001D /*!< DMA request peripheral:USB EP5*/
#define DMA_REQUEST_USB_EP6 0x0000001E /*!< DMA request peripheral:USB EP6*/
#define DMA_REQUEST_USB_EP7 0x0000001F /*!< DMA request peripheral:USB EP7 */
``dst_req`` 提供以下类型
.. code-block:: C
#define DMA_REQUEST_NONE 0x00000000 /*!< DMA request peripheral:None */
#define DMA_REQUEST_UART0_RX 0x00000000 /*!< DMA request peripheral:UART0 RX */
#define DMA_REQUEST_UART0_TX 0x00000001 /*!< DMA request peripheral:UART0 TX */
#define DMA_REQUEST_UART1_RX 0x00000002 /*!< DMA request peripheral:UART1 RX */
#define DMA_REQUEST_UART1_TX 0x00000003 /*!< DMA request peripheral:UART1 TX */
#define DMA_REQUEST_I2C0_RX 0x00000006 /*!< DMA request peripheral:I2C RX */
#define DMA_REQUEST_I2C0_TX 0x00000007 /*!< DMA request peripheral:I2C TX */
#define DMA_REQUEST_SPI0_RX 0x0000000A /*!< DMA request peripheral:SPI RX */
#define DMA_REQUEST_SPI0_TX 0x0000000B /*!< DMA request peripheral:SPI TX */
#define DMA_REQUEST_I2S_RX 0x00000014 /*!< DMA request peripheral:I2S RX */
#define DMA_REQUEST_I2S_TX 0x00000015 /*!< DMA request peripheral:I2S TX */
#define DMA_REQUEST_ADC0 0x00000016 /*!< DMA request peripheral:ADC0 */
#define DMA_REQUEST_DAC0 0x00000017 /*!< DMA request peripheral:DAC0 */
#define DMA_REQUEST_USB_EP0 0x00000018 /*!< DMA request peripheral:USB EP0*/
#define DMA_REQUEST_USB_EP1 0x00000019 /*!< DMA request peripheral:USB EP1*/
#define DMA_REQUEST_USB_EP2 0x0000001A /*!< DMA request peripheral:USB EP2*/
#define DMA_REQUEST_USB_EP3 0x0000001B /*!< DMA request peripheral:USB EP3*/
#define DMA_REQUEST_USB_EP4 0x0000001C /*!< DMA request peripheral:USB EP4*/
#define DMA_REQUEST_USB_EP5 0x0000001D /*!< DMA request peripheral:USB EP5*/
#define DMA_REQUEST_USB_EP6 0x0000001E /*!< DMA request peripheral:USB EP6*/
#define DMA_REQUEST_USB_EP7 0x0000001F /*!< DMA request peripheral:USB EP7 */
``src_burst_size`` 提供以下类型
.. code-block:: C
#define DMA_BURST_1BYTE 0
#define DMA_BURST_4BYTE 1
#define DMA_BURST_8BYTE 2
#define DMA_BURST_16BYTE 3
``dst_burst_size`` 提供以下类型
.. code-block:: C
#define DMA_BURST_1BYTE 0
#define DMA_BURST_4BYTE 1
#define DMA_BURST_8BYTE 2
#define DMA_BURST_16BYTE 3
``src_width`` 提供以下类型
.. code-block:: C
#define DMA_TRANSFER_WIDTH_8BIT 0
#define DMA_TRANSFER_WIDTH_16BIT 1
#define DMA_TRANSFER_WIDTH_32BIT 2
``dst_width`` 提供以下类型
.. code-block:: C
#define DMA_TRANSFER_WIDTH_8BIT 0
#define DMA_TRANSFER_WIDTH_16BIT 1
#define DMA_TRANSFER_WIDTH_32BIT 2
DMA 设备参数配置表
------------------------
每一个 DMA 设备都有一个参数配置宏,宏定义位于 ``bsp/board/xxx`` 目录下 ``peripheral_config.h`` 文件,变量定义位于 ``hal_dma.c`` 中,因此无需用户自己定义变量。当用户打开对应设备的宏,该设备的配置才生效。例如打开宏 ``BSP_USING_DMA0_CH0`` ``DMA0_CH0_CONFIG`` 即生效同时DMA 通道0设备就可以进行注册和使用了。
.. code-block:: C
/*参数配置宏*/
#if defined(BSP_USING_DMA0_CH0)
#ifndef DMA0_CH0_CONFIG
#define DMA0_CH0_CONFIG \
{ \
.id = 0, \
.ch = 0,\
.direction = DMA_MEMORY_TO_MEMORY,\
.transfer_mode = DMA_LLI_ONCE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_NONE, \
.src_width = DMA_TRANSFER_WIDTH_32BIT , \
.dst_width = DMA_TRANSFER_WIDTH_32BIT , \
}
#endif
#endif
/*变量定义*/
static dma_device_t dmax_device[DMA_MAX_INDEX] =
{
#ifdef BSP_USING_DMA0_CH0
DMA0_CH0_CONFIG,
#endif
#ifdef BSP_USING_DMA0_CH1
DMA0_CH1_CONFIG,
#endif
#ifdef BSP_USING_DMA0_CH2
DMA0_CH2_CONFIG,
#endif
#ifdef BSP_USING_DMA0_CH3
DMA0_CH3_CONFIG,
#endif
#ifdef BSP_USING_DMA0_CH4
DMA0_CH4_CONFIG,
#endif
#ifdef BSP_USING_DMA0_CH5
DMA0_CH5_CONFIG,
#endif
#ifdef BSP_USING_DMA0_CH6
DMA0_CH6_CONFIG,
#endif
#ifdef BSP_USING_DMA0_CH7
DMA0_CH7_CONFIG,
#endif
};
.. note:: 上述配置可以通过 ``DMA_DEV(dev)->xxx`` 进行修改,只能在调用 ``device_open`` 之前使用。
DMA 设备接口
------------------------
DMA 设备接口全部遵循标准设备驱动管理层提供的接口。并且为了方便用户调用,将某些标准接口使用宏来重定义。
**dma_register**
^^^^^^^^^^^^^^^^^^^^^^^^
``dma_register`` 用来注册一个 DMA 设备的一个通道,在注册之前需要打开对应 DMA 设备的通道宏定义。例如定义宏 ``BSP_USING_DMA_CH0`` 方可使用 ``DMA`` 设备的 0 通道,注册完成以后才可以使用其他接口,如果没有定义宏,则无法使用 ``DMA`` 设备的 0 通道。
.. code-block:: C
int dma_register(enum dma_index_type index, const char *name, uint16_t flag);
- index 要注册的设备索引
- name 为注册的设备命名
- flag 默认可读可写属性
``index`` 用来选择 DMA 设备某个通道的配置,一个 index 对应一个 DMA 设备的一个通道配置,比如 ``DMA_CH0_INDEX`` 对应 DMA 通道0 配置,``index`` 有如下可选类型
.. code-block:: C
enum dma_index_type
{
#ifdef BSP_USING_DMA0_CH0
DMA0_CH0_INDEX,
#endif
#ifdef BSP_USING_DMA0_CH1
DMA0_CH1_INDEX,
#endif
#ifdef BSP_USING_DMA0_CH2
DMA0_CH2_INDEX,
#endif
#ifdef BSP_USING_DMA0_CH3
DMA0_CH3_INDEX,
#endif
#ifdef BSP_USING_DMA0_CH4
DMA0_CH4_INDEX,
#endif
#ifdef BSP_USING_DMA0_CH5
DMA0_CH5_INDEX,
#endif
#ifdef BSP_USING_DMA0_CH6
DMA0_CH6_INDEX,
#endif
#ifdef BSP_USING_DMA0_CH7
DMA0_CH7_INDEX,
#endif
DMA_MAX_INDEX
};
**device_open**
^^^^^^^^^^^^^^^^
``device_open`` 用于设备的打开,``oflag`` 表示以何种方式打开。
.. code-block:: C
int device_open(struct device *dev, uint16_t oflag);
- dev 设备句柄
- oflag 设备的打开方式
- return 错误码0 表示打开成功,其他表示错误
``oflag`` 可以写入以下参数:
.. code-block:: C
#define DEVICE_OFLAG_STREAM_TX 0x001 /* 设备以轮训发送模式打开 */
#define DEVICE_OFLAG_STREAM_RX 0x002 /* 设备以轮训接收模式打开 */
#define DEVICE_OFLAG_INT_TX 0x004 /* 设备以中断发送模式打开 */
#define DEVICE_OFLAG_INT_RX 0x008 /* 设备以中断接收模式打开 */
#define DEVICE_OFLAG_DMA_TX 0x010 /* 设备以 DMA 发送模式打开 */
#define DEVICE_OFLAG_DMA_RX 0x020 /* 设备以 DMA 接收模式打开 */
**device_close**
^^^^^^^^^^^^^^^^
``device_close`` 用于设备的关闭。
.. code-block:: C
int device_close(struct device *dev);
- dev 设备句柄
- return 错误码0 表示关闭成功,其他表示错误
**device_control**
^^^^^^^^^^^^^^^^^^^
``device_control`` 用于根据命令对设备进行控制和参数的修改。
.. code-block:: C
int device_control(struct device *dev, int cmd, void *args);
- dev 设备句柄
- cmd 设备控制命令
- args 控制参数
- return 不同的控制命令返回的意义不同。
DMA 设备除了标准的控制命令,还具有自己特殊的控制命令。
.. code-block:: C
#define DMA_CHANNEL_GET_STATUS 0x10
#define DMA_CHANNEL_START 0x11
#define DMA_CHANNEL_STOP 0x12
#define DMA_CHANNEL_UPDATE 0x13
``args`` 根据不同的 ``cmd`` 传入不同,具体如下:
+---------------------------+-------------+------------------------+
|cmd |args |description |
+===========================+=============+========================+
|DEVICE_CTRL_SET_INT |NULL |开启dma传输完成中断 |
+---------------------------+-------------+------------------------+
|DEVICE_CTRL_CLR_INT |NULL |关闭dma传输完成中断 |
+---------------------------+-------------+------------------------+
|DMA_CHANNEL_GET_STATUS |NULL |获取dma通道完成状态 |
+---------------------------+-------------+------------------------+
|DMA_CHANNEL_START |NULL |开启dma通道 |
+---------------------------+-------------+------------------------+
|DMA_CHANNEL_STOP |NULL |关闭dma通道 |
+---------------------------+-------------+------------------------+
|DMA_CHANNEL_UPDATE |uint32_t |更新dma传输配置 |
+---------------------------+-------------+------------------------+
**device_set_callback**
^^^^^^^^^^^^^^^^^^^^^^^^
``device_set_callback`` 用于注册一个DMA通道中断回调函数。
.. code-block:: C
int device_set_callback(struct device *dev, void (*callback)(struct device *dev, void *args, uint32_t size, uint32_t event));
- dev 设备句柄
- callback 要注册的中断回调函数
- dev 设备句柄
- args 无用
- size 无用
- event 中断事件类型
DMA 设备 ``event`` 类型如下
.. code-block:: C
enum dma_event_type
{
DMA_EVENT_COMPLETE,
};
**dma_channel_start**
^^^^^^^^^^^^^^^^^^^^^^
``dma_channel_start`` 用于开启DMA通道。实际是调用 ``device_control`` ,其中 ``cmd`` 为 ``DMA_CHANNEL_START``。
.. code-block:: C
dma_channel_start(dev)
- dev 需要开启的pwm通道句柄
**dma_channel_stop**
^^^^^^^^^^^^^^^^^^^^^^
``dma_channel_stop`` 用于关闭DMA通道。实际是调用 ``device_control`` ,其中 ``cmd`` 为 ``DMA_CHANNEL_STOP``。
.. code-block:: C
dma_channel_stop(dev)
- dev 需要关闭的pwm通道句柄
**dma_channel_update**
^^^^^^^^^^^^^^^^^^^^^^^
``dma_channel_update`` 用于更新DMA配置。实际是调用 ``device_control`` ,其中 ``cmd`` 为 ``DMA_CHANNEL_UPDATE``。
.. code-block:: C
dma_channel_update(dev,list)
- dev 需要更新的pwm通道句柄
- list dma_lli_ctrl_t句柄
**dma_channel_check_busy**
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
``dma_channel_check_busy`` 用于查询当前使用的DMA通道是否传输完成。实际是调用 ``device_control`` ,其中 ``cmd`` 为 ``DMA_CHANNEL_GET_STATUS``。
.. code-block:: C
dma_channel_check_busy(dev)
- dev 需要查询的DMA通道句柄
- 返回当前DMA状态0为传输完成1为未传输完成
**dma_reload**
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
``dma_reload`` 用于更新DMA某个通道的配置相比于 ``dma_channel_update`` ,该函数无需用户传递很多参数只需要填入源地址和目标地址以及长度内部会自己计算后再进行配置。此函数调用后DMA通道是没有开启的需要手动调用 ``dma_channel_start`` 函数。
.. code-block:: C
int dma_reload(struct device *dev, uint32_t src_addr, uint32_t dst_addr, uint32_t transfer_size);
- dev 需要查询的DMA通道句柄
- src_addr 传输源地址
- dst_addr 传输目标地址
- transfer_size 传输字节总长度如果传输的位数是16位、32位这里需要进行转换成字节长度。

View File

@ -0,0 +1,114 @@
GPIO 设备
=========================
简介
------------------------
GPIO 全称 General Purpose Input Output通用输入 / 输出),博流系列芯片的 GPIO 外设主要有以下功能。
- 普通输入输出带上下拉
- 复用功能带上下拉
- 模拟功能
- 外部中断(上升沿、下降沿、高电平、低电平)
- 硬件消抖
- 驱动能力控制
bl mcu sdk 的引脚配置方式分为两种。
- GPIO 复用功能通过专门的 **pinmux table** ,用户只需要修改 table 中的相关引脚的功能,程序会自动配置这些引脚。**pinmux table** 位于 ``bsp/board/xxx_board`` 目录下 ``pinmux_config.h`` 文件。
- 通过标准的 GPIO 设备接口配置引脚,缺点是只能配置普通的输入输出和中断功能,复用功能建议还是使用 table 进行配置。
GPIO 设备接口
------------------------
**gpio_set_mode**
^^^^^^^^^^^^^^^^^^^^^^^^
``gpio_set_mode`` 用来配置 gpio 的模式。
.. code-block:: C
void gpio_set_mode(uint32_t pin, uint32_t mode);
- pin 要配置的引脚
- mode 要配置的引脚功能
``mode`` 提供以下几种类型
.. code-block:: C
#define GPIO_OUTPUT_MODE 0
#define GPIO_OUTPUT_PP_MODE 1
#define GPIO_OUTPUT_PD_MODE 2
#define GPIO_INPUT_MODE 3
#define GPIO_INPUT_PP_MODE 4
#define GPIO_INPUT_PD_MODE 5
#define GPIO_ASYNC_RISING_TRIGER_INT_MODE 6
#define GPIO_ASYNC_FALLING_TRIGER_INT_MODE 7
#define GPIO_ASYNC_HIGH_LEVEL_INT_MODE 8
#define GPIO_ASYNC_LOW_LEVEL_INT_MODE 9
#define GPIO_SYNC_RISING_TRIGER_INT_MODE 10
#define GPIO_SYNC_FALLING_TRIGER_INT_MODE 11
#define GPIO_SYNC_HIGH_LEVEL_INT_MODE 12
#define GPIO_SYNC_LOW_LEVEL_INT_MODE 13
**gpio_write**
^^^^^^^^^^^^^^^^^^^^^^^^
``gpio_write`` 设置引脚电平
.. code-block:: C
void gpio_write(uint32_t pin, uint32_t value);
- pin 要设置的引脚
- value 要设置的电平
**gpio_toggle**
^^^^^^^^^^^^^^^^^^^^^^^^
``gpio_toggle`` 翻转引脚电平
.. code-block:: C
void gpio_toggle(uint32_t pin);
- pin 要翻转的引脚
**gpio_read**
^^^^^^^^^^^^^^^^^^^^^^^^
``gpio_read`` 读取引脚电平
.. code-block:: C
int gpio_read(uint32_t pin);
- pin 要读取电平的引脚
- return 0 为低电平1 为高电平
**gpio_attach_irq**
^^^^^^^^^^^^^^^^^^^^^^^^
``gpio_attach_irq`` 为中断引脚附加中断回调函数
.. code-block:: C
void gpio_attach_irq(uint32_t pin, void (*cbfun)(uint32_t pin));
- pin 要附加中断回调的引脚
- cbfun 要注册的中断回调函数
**gpio_irq_enable**
^^^^^^^^^^^^^^^^^^^^^^^^
``gpio_irq_enable`` 开启gpio某个引脚的中断
.. code-block:: C
void gpio_irq_enable(uint32_t pin,uint8_t enabled);
- pin 要开启或者关闭中断的引脚
- enabled 0 为关闭中断1 为打开中断

View File

@ -0,0 +1,164 @@
I2C 设备
=========================
简介
------------------------
I2C (Inter-Intergrated Circuit) 是一种串行通讯总线,使用多主从架构,用来连接低速外围装置。每个器件都有一个唯
一的地址识别,并且都可以作为一个发送器或接收器。每个连接到总线的器件都可以通过唯一的地址和一直存在的主、
从机关系用软件设置地址,主机可以作为主机发送器或主机接收器。如果有两个或多个主机同时初始化,数据传输可
以通过冲突检测和仲裁防止数据被破坏。博流系列 MCU 中 I2C 设备具有以下特性:
- 灵活配置的从机地址 ``slaveAddr`` 、寄存器地址 ``subAddr``
- 可以灵活调整的时钟频率
- 支持轮询、中断、DMA传输
I2C 设备结构体定义
------------------------
.. code-block:: C
typedef struct i2c_device
{
struct device parent;
uint8_t id;
uint8_t mode;
uint32_t phase;
} i2c_device_t;
- parent 继承父类属性
- ch i2c id0表示i2c0,1表示i2c1
- mode i2c传输模式0 为使用硬件i2c1为使用软件i2c当前软件i2c暂时无效
- phase
- 其他待补充
I2C 设备参数配置表
------------------------
每一个 I2C 设备都有一个参数配置宏,宏定义位于 ``bsp/board/xxx`` 目录下 ``peripheral_config.h`` 文件,变量定义位于 ``hal_pwm.c`` 中,因此无需用户自己定义变量。当用户打开对应设备的宏,该设备的配置才生效。例如打开宏 ``BSP_USING_I2C0`` ``I2C0_CONFIG`` 即生效,同时 ``I2C`` 设备就可以进行注册和使用了。
.. code-block:: C
/*参数配置宏*/
#if defined(BSP_USING_I2C0)
#ifndef I2C0_CONFIG
#define I2C0_CONFIG \
{ \
.id = 0, \
.mode = I2C_HW_MODE,\
.phase = 15, \
}
#endif
#endif
/*变量定义*/
static i2c_device_t i2cx_device[I2C_MAX_INDEX] =
{
#ifdef BSP_USING_I2C0
I2C0_CONFIG,
#endif
};
.. note:: 上述配置可以通过 ``I2C_DEV(dev)->xxx`` 进行修改,只能在调用 ``device_open`` 之前使用。
I2C 设备接口
------------------------
I2C 设备标准接口当前仅使用 ``device_open`` , 并提供标准的数据收发接口。
**i2c_register**
^^^^^^^^^^^^^^^^^^^^^^^^
``i2c_register`` 用来注册一个 I2C 设备,在注册之前需要打开对应 I2C 设备的宏定义。例如定义宏 ``BSP_USING_I2C0`` 方可使用 ``I2C0`` 设备,注册完成以后才可以使用其他接口,如果没有定义宏,则无法使用 ``I2C0`` 设备。
.. code-block:: C
int i2c_register(enum i2c_index_type index, const char *name, uint16_t flag);
- index 要注册的设备索引
- name 为注册的设备命名
- flag 默认可读可写属性
``index`` 用来选择 I2C 设备,一个 index 对应一个 I2C 设备配置,比如 ``I2C0_INDEX`` 对应 ``I2C0_CONFIG`` 配置,``index`` 有如下可选类型
.. code-block:: C
enum i2c_index_type
{
#ifdef BSP_USING_I2C0
I2C0_INDEX,
#endif
I2C_MAX_INDEX
};
**device_open**
^^^^^^^^^^^^^^^^
``device_open`` 用于设备的打开,``oflag`` 表示以何种方式打开。
.. code-block:: C
int device_open(struct device *dev, uint16_t oflag);
- dev 设备句柄
- oflag 设备的打开方式
- return 错误码0 表示打开成功,其他表示错误
``oflag`` 可以写入以下参数:
.. code-block:: C
#define DEVICE_OFLAG_STREAM_TX 0x001 /* 设备以轮训发送模式打开 */
#define DEVICE_OFLAG_STREAM_RX 0x002 /* 设备以轮训接收模式打开 */
#define DEVICE_OFLAG_INT_TX 0x004 /* 设备以中断发送模式打开 */
#define DEVICE_OFLAG_INT_RX 0x008 /* 设备以中断接收模式打开 */
#define DEVICE_OFLAG_DMA_TX 0x010 /* 设备以 DMA 发送模式打开 */
#define DEVICE_OFLAG_DMA_RX 0x020 /* 设备以 DMA 接收模式打开 */
**i2c_transfer**
^^^^^^^^^^^^^^^^
``i2c_transfer`` 用于设备的数据传输,形参中 ``msgs`` 中的成员 ``flags`` 指示传输的方向是写还是读并且指定寄存器地址长度是0、1、2。
.. code-block:: C
int i2c_transfer(struct device *dev, i2c_msg_t msgs[], uint32_t num);
- dev 设备句柄
- msgs 需要传输的消息
- num 消息个数
- return 错误码0 表示打开成功,其他表示错误
``i2c_msg_t`` 结构体定义如下:
.. code-block:: C
typedef struct i2c_msg
{
uint8_t slaveaddr;
uint32_t subaddr;
uint16_t flags;
uint16_t len;
uint8_t *buf;
} i2c_msg_t;
- slaveaddr i2c从设备7位从机地址
- subaddr i2c从设备寄存器地址
- flags 读写模式以及寄存器地址长度
- len 传输数据长度
- buf 数据缓冲区
其中 ``flags`` 有如下定义:
.. code-block:: C
/*读写模式*/
#define I2C_WR 0x0000
#define I2C_RD 0x0001
/*寄存器地址长度*/
#define SUB_ADDR_0BYTE 0x0010
#define SUB_ADDR_1BYTE 0x0020
#define SUB_ADDR_2BYTE 0x0040

View File

@ -0,0 +1,263 @@
PWM 设备
=========================
简介
------------------------
脉冲宽度调制Pulse width modulation简称 PWM是一种用数字方式实现模拟电压控制的技术。它是通过对一系列脉冲的宽度进行调制等效出所需要的波形包含形状以及幅值对模拟信号电平进行数字编码也就是说通过调节占空比的变化来调节信号、能量等的变化占空比就是指在一个周期内信号处于高电平的时间占据整个信号周期的百分比例如方波的占空比就是50%。博流系列 MCU 中 DMA 设备具有以下特性:
- 支持5通道PWM信号生成
- 三种时钟源可选择(总线时钟 <bclk>、晶振时钟 <xtal_ck>、慢速时钟 <32k>),搭配 16-bit 时钟分频器
- 双门限值域设定,增加脉冲弹性
PWM 设备结构体定义
------------------------
.. code-block:: C
typedef struct pwm_device
{
struct device parent;
uint8_t ch;
uint32_t frequency;
uint8_t dutycycle;
uint16_t it_pulse_count;
} pwm_device_t;
- parent 继承父类属性
- ch 通道号使能PWM通道0则ch为0使能PWM通道0则ch为1以此类推
- frequency 默认频率
- dutycycle 默认占空比0-100
- it_pulse_count 触发中断条件的周期计数值
PWM 设备参数配置表
------------------------
每一个 PWM 设备都有一个参数配置宏,宏定义位于 ``bsp/board/xxx`` 目录下 ``peripheral_config.h`` 文件,变量定义位于 ``hal_pwm.c`` 中,因此无需用户自己定义变量。当用户打开对应设备的宏,该设备的配置才生效。例如打开宏 ``BSP_USING_PWM_CH2`` ``PWM_CH2_CONFIG`` 即生效,同时 ``PWM`` 设备的通道2就可以进行注册和使用了。
.. code-block:: C
/*参数配置宏*/
#if defined(BSP_USING_PWM_CH2)
#ifndef PWM_CH2_CONFIG
#define PWM_CH2_CONFIG \
{ \
.ch = 2, \
.frequency = 1000000, \
.dutycycle = 0, \
}
#endif
#endif
/*变量定义*/
static pwm_device_t pwmx_device[PWM_MAX_INDEX] = {
#ifdef BSP_USING_PWM_CH0
PWM_CH0_CONFIG,
#endif
#ifdef BSP_USING_PWM_CH1
PWM_CH1_CONFIG,
#endif
#ifdef BSP_USING_PWM_CH2
PWM_CH2_CONFIG,
#endif
#ifdef BSP_USING_PWM_CH3
PWM_CH3_CONFIG,
#endif
#ifdef BSP_USING_PWM_CH4
PWM_CH4_CONFIG,
#endif
};
.. note:: 上述配置可以通过 ``PWM_DEV(dev)->xxx`` 进行修改,只能在调用 ``device_open`` 之前使用。
PWM 设备接口
------------------------
PWM 设备接口全部遵循标准设备驱动管理层提供的接口。并且为了方便用户调用,将某些标准接口使用宏来重定义。
**pwm_register**
^^^^^^^^^^^^^^^^^^^^^^^^
``pwm_register`` 用来注册一个 PWM 设备的一个通道,在注册之前需要打开对应 PWM 设备某个通道的宏定义,例如定义 ``BSP_USING_PWM_CH0`` 方可使用 ``PWM`` 通道0 设备。注册完成以后才可以使用其他接口,如果没有定义宏,则无法使用 PWM 设备。
.. code-block:: C
int pwm_register(enum pwm_index_type index, const char *name, uint16_t flag);
- index 要注册的设备索引
- name 为注册的设备命名
- flag 默认可读可写属性
``index`` 用来选择 PWM 设备某个通道的配置,一个 index 对应一个 PWM 设备的一个通道配置,比如 ``PWM_CH0_INDEX`` 对应 PWM 通道0 配置,``index`` 有如下可选类型
.. code-block:: C
enum pwm_index_type
{
#ifdef BSP_USING_PWM_CH0
PWM_CH0_INDEX,
#endif
#ifdef BSP_USING_PWM_CH1
PWM_CH1_INDEX,
#endif
#ifdef BSP_USING_PWM_CH2
PWM_CH2_INDEX,
#endif
#ifdef BSP_USING_PWM_CH3
PWM_CH3_INDEX,
#endif
#ifdef BSP_USING_PWM_CH4
PWM_CH4_INDEX,
#endif
PWM_MAX_INDEX
};
**device_open**
^^^^^^^^^^^^^^^^
``device_open`` 用于设备的打开,``oflag`` 表示以何种方式打开。
.. code-block:: C
int device_open(struct device *dev, uint16_t oflag);
- dev 设备句柄
- oflag 设备的打开方式
- return 错误码0 表示打开成功,其他表示错误
``oflag`` 可以写入以下参数:
.. code-block:: C
#define DEVICE_OFLAG_STREAM_TX 0x001 /* 设备以轮训发送模式打开 */
#define DEVICE_OFLAG_STREAM_RX 0x002 /* 设备以轮训接收模式打开 */
#define DEVICE_OFLAG_INT_TX 0x004 /* 设备以中断发送模式打开 */
#define DEVICE_OFLAG_INT_RX 0x008 /* 设备以中断接收模式打开 */
#define DEVICE_OFLAG_DMA_TX 0x010 /* 设备以 DMA 发送模式打开 */
#define DEVICE_OFLAG_DMA_RX 0x020 /* 设备以 DMA 接收模式打开 */
**device_close**
^^^^^^^^^^^^^^^^
``device_close`` 用于设备的关闭。
.. code-block:: C
int device_close(struct device *dev);
- dev 设备句柄
- return 错误码0 表示关闭成功,其他表示错误
**device_control**
^^^^^^^^^^^^^^^^^^^
``device_control`` 用于根据命令对设备进行控制和参数的修改。
.. code-block:: C
int device_control(struct device *dev, int cmd, void *args);
- dev 设备句柄
- cmd 设备控制命令
- args 控制参数
- return 不同的控制命令返回的意义不同。
PWM 设备除了标准的控制命令,还具有自己特殊的控制命令。
.. code-block:: C
#define DEIVCE_CTRL_PWM_IT_PULSE_COUNT_CONFIG 0x10
``args`` 根据不同的 ``cmd`` 传入不同,具体如下:
+------------------------------------------+-----------------+----------------------------+
|cmd |args |description |
+==========================================+=================+============================+
|DEVICE_CTRL_SET_INT |NULL |开启pwm传输完成中断 |
+------------------------------------------+-----------------+----------------------------+
|DEVICE_CTRL_CLR_INT |NULL |关闭pwm传输完成中断 |
+------------------------------------------+-----------------+----------------------------+
|DEVICE_CTRL_RESUME |NULL |恢复pwm通道 |
+------------------------------------------+-----------------+----------------------------+
|DEVICE_CTRL_SUSPEND |NULL |挂起pwm通道 |
+------------------------------------------+-----------------+----------------------------+
|DEVICE_CTRL_CONFIG |pwm_config_t |配置pwm通道频率和占空比 |
+------------------------------------------+-----------------+----------------------------+
|DEIVCE_CTRL_PWM_IT_PULSE_COUNT_CONFIG |uint32_t* |配置中断计数阈值 |
+------------------------------------------+-----------------+----------------------------+
**device_set_callback**
^^^^^^^^^^^^^^^^^^^^^^^^
``device_set_callback`` 用于注册一个PWM通道中断回调函数。
.. code-block:: C
int device_set_callback(struct device *dev, void (*callback)(struct device *dev, void *args, uint32_t size, uint32_t event));
- dev 设备句柄
- callback 要注册的中断回调函数
- dev 设备句柄
- args 无用
- size 无用
- event 中断事件类型
PWM设备 ``event`` 类型如下
.. code-block:: C
enum pwm_event_type
{
PWM_EVENT_COMPLETE,
};
**pwm_channel_start**
^^^^^^^^^^^^^^^^^^^^^^
``pwm_channel_start`` 用于开启PWM通道。实际是调用 ``device_control`` ,其中 ``cmd`` 为 ``DEVICE_CTRL_RESUME``。
.. code-block:: C
pwm_channel_start(dev)
- dev 需要开启的pwm通道句柄
**pwm_channel_stop**
^^^^^^^^^^^^^^^^^^^^^^
``pwm_channel_stop`` 用于关闭PWM通道。实际是调用 ``device_control`` ,其中 ``cmd`` 为 ``DEVICE_CTRL_SUSPEND``。
.. code-block:: C
pwm_channel_stop(dev)
- dev 需要关闭的pwm通道句柄
**pwm_channel_update**
^^^^^^^^^^^^^^^^^^^^^^^
``pwm_channel_update`` 用于更新PWM通道的频率和占空比。实际是调用 ``device_control`` ,其中 ``cmd`` 为 ``DEVICE_CTRL_CONFIG``。
.. code-block:: C
pwm_channel_update(dev,cfg)
- dev 需要更新的pwm通道句柄
- cfg pwm_config_t句柄
**pwm_it_pulse_count_update**
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
``pwm_it_pulse_count_update`` 用于更新PWM通道的计数值需要先使能PWM中断才起作用当pwm计数达到设置的周期计数值则会产生中断。实际是调用 ``device_control`` ,其中 ``cmd`` 为 ``DEIVCE_CTRL_PWM_IT_PULSE_COUNT_CONFIG``。
.. code-block:: C
pwm_it_pulse_count_update(dev,count)
- dev 需要更新周期计数值的pwm通道句柄
- count 周期计数值

View File

@ -0,0 +1,350 @@
SPI 设备
=========================
简介
------------------------
串行外设接口Serial Peripheral Interface Bus, SPI是一种用于短程通信的同步串行通信接口规范装置之间使用全
双工模式通信,是一个主机和一个或多个从机的主从模式。需要至少 4 根线,事实上 3 根也可以(单向传输时), 包括
SDI数据输入、SDO数据输出、SCLK时钟、CS片选。博流系列 MCU 中 SPI 设备具有以下特性:
- 既可以作为 SPI 主机也可以作为 SPI 从机。
- 发送和接收通道各有深度为 4 个字的 FIFO
- 主从设备都支持 4 种时钟格式CPOLCPHA
- 主从设备都支持 1/2/3/4 字节传输模式
- 灵活的时钟配置,最高可支持 40M 时钟
- 可配置 MSB/LSB 优先传输
- 接收过滤功能
- 从设备下的超时机制
- 支持轮询、中断、DMA传输
SPI 设备结构体定义
------------------------
.. code-block:: C
typedef struct spi_device
{
struct device parent;
uint8_t id;
uint32_t clk;
uint8_t mode;
uint8_t direction;
uint8_t clk_polaraity;
uint8_t clk_phase;
uint8_t datasize;
uint8_t fifo_threshold;
void* tx_dma;
void* rx_dma;
} spi_device_t;
- parent 继承父类属性
- id SPI id0表示 SPI0
- clk SPI 时钟频率
- mode 主机模式或者从机模式
- direction 传输先行模式
- clk_polaraity 时钟极性
- clk_phase 时钟相位
- datasize 数据传输位宽
- fifo_threshold fifo 阈值, 最大为4
- tx_dma 附加的发送 dma 句柄
- rx_dma 附加的接收 dma 句柄
``mode`` 提供以下类型
.. code-block:: C
#define SPI_SLVAE_MODE 0
#define SPI_MASTER_MODE 1
``direction`` 提供以下类型
.. code-block:: C
#define SPI_LSB_BYTE0_DIRECTION_FIRST 0
#define SPI_LSB_BYTE3_DIRECTION_FIRST 1
#define SPI_MSB_BYTE0_DIRECTION_FIRST 2
#define SPI_MSB_BYTE3_DIRECTION_FIRST 3
``clk_polaraity`` 提供以下类型
.. code-block:: C
#define SPI_POLARITY_LOW 0
#define SPI_POLARITY_HIGH 1
``clk_phase`` 提供以下类型
.. code-block:: C
#define SPI_PHASE_1EDGE 0
#define SPI_PHASE_2EDGE 1
``datasize`` 提供以下类型
.. code-block:: C
#define SPI_DATASIZE_8BIT 0
#define SPI_DATASIZE_16BIT 1
#define SPI_DATASIZE_24BIT 2
#define SPI_DATASIZE_32BIT 3
SPI 设备参数配置表
------------------------
每一个 SPI 设备都有一个参数配置宏,宏定义位于 ``bsp/board/xxx`` 目录下 ``peripheral_config.h`` 文件,变量定义位于 ``hal_uart.c`` 中,因此无需用户自己定义变量。当用户打开对应设备的宏,该设备的配置才生效。例如打开宏 ``BSP_USING_SPI0`` ``SPI0_CONFIG`` 即生效,同时 ``SPI0`` 设备就可以进行注册和使用了。
.. code-block:: C
/*参数配置宏*/
#if defined(BSP_USING_SPI0)
#ifndef SPI0_CONFIG
#define SPI0_CONFIG \
{ \
.id = 0, \
.clk = 18000000,\
.mode = SPI_MASTER_MODE, \
.direction = SPI_MSB_BYTE0_DIRECTION_FIRST, \
.clk_polaraity = SPI_POLARITY_LOW, \
.clk_phase = SPI_PHASE_1EDGE, \
.datasize = SPI_DATASIZE_8BIT, \
.fifo_threshold = 1, \
}
#endif
#endif
/*变量定义*/
static spi_device_t spix_device[SPI_MAX_INDEX] =
{
#ifdef BSP_USING_SPI0
SPI0_CONFIG,
#endif
};
.. note:: 上述配置可以通过 ``SPI_DEV(dev)->xxx`` 进行修改,只能在调用 ``device_open`` 之前使用。
SPI 设备接口
------------------------
SPI 设备接口全部遵循标准设备驱动管理层提供的接口。
**spi_register**
^^^^^^^^^^^^^^^^^^^^^^^^
``spi_register`` 用来注册一个 SPI 设备,在注册之前需要打开对应 SPI 设备的宏定义,例如定义宏 ``BSP_USING_SPI0`` 方可使用 SPI0 设备。注册完成以后才可以使用其他接口,如果没有定义宏,则无法使用 SPI 设备。
.. code-block:: C
int spi_register(enum spi_index_type index, const char *name, uint16_t flag);
- index 要注册的设备索引
- name 为注册的设备命名
- flag 默认可读可写属性
``index`` 用来选择 SPI 设备配置,一个 index 对应一个 SPI 设备配置,比如 ``SPI0_INDEX`` 对应 ``SPI0_CONFIG`` 配置,``index`` 有如下可选类型
.. code-block:: C
enum spi_index_type
{
#ifdef BSP_USING_SPI0
SPI0_INDEX,
#endif
SPI_MAX_INDEX
};
**device_open**
^^^^^^^^^^^^^^^^
``device_open`` 用于设备的打开,``oflag`` 表示以何种方式打开。
.. code-block:: C
int device_open(struct device *dev, uint16_t oflag);
- dev 设备句柄
- oflag 设备的打开方式
- return 错误码0 表示打开成功,其他表示错误
``oflag`` 可以写入以下参数:
.. code-block:: C
#define DEVICE_OFLAG_STREAM_TX 0x001 /* 设备以轮训发送模式打开 */
#define DEVICE_OFLAG_STREAM_RX 0x002 /* 设备以轮训接收模式打开 */
#define DEVICE_OFLAG_INT_TX 0x004 /* 设备以中断发送模式打开 */
#define DEVICE_OFLAG_INT_RX 0x008 /* 设备以中断接收模式打开 */
#define DEVICE_OFLAG_DMA_TX 0x010 /* 设备以 DMA 发送模式打开 */
#define DEVICE_OFLAG_DMA_RX 0x020 /* 设备以 DMA 接收模式打开 */
**device_close**
^^^^^^^^^^^^^^^^
``device_close`` 用于设备的关闭。
.. code-block:: C
int device_close(struct device *dev);
- dev 设备句柄
- return 错误码0 表示关闭成功,其他表示错误
**device_control**
^^^^^^^^^^^^^^^^^^^
``device_control`` 用于根据命令对设备进行控制和参数的修改。
.. code-block:: C
int device_control(struct device *dev, int cmd, void *args);
- dev 设备句柄
- cmd 设备控制命令
- args 控制参数
- return 不同的控制命令返回的意义不同。
SPI 设备除了标准的控制命令,还具有自己特殊的控制命令。
.. code-block:: C
#define DEVICE_CTRL_SPI_CONFIG_CLOCK 0x10
``args`` 根据不同的 ``cmd`` 传入不同,具体如下:
+---------------------------------+-------------------+-----------------------+
|cmd |args |description |
+=================================+===================+=======================+
|DEVICE_CTRL_SET_INT |NULL |开启spi设备中断 |
+---------------------------------+-------------------+-----------------------+
|DEVICE_CTRL_CLR_INT |NULL |关闭spi设备中断 |
+---------------------------------+-------------------+-----------------------+
|DEVICE_CTRL_RESUME |NULL |恢复spi设备 |
+---------------------------------+-------------------+-----------------------+
|DEVICE_CTRL_SUSPEND |NULL |挂起spi设备 |
+---------------------------------+-------------------+-----------------------+
|DEVICE_CTRL_ATTACH_TX_DMA |struct device* |链接发送dma设备 |
+---------------------------------+-------------------+-----------------------+
|DEVICE_CTRL_ATTACH_RX_DMA |struct device* |链接接收dma设备 |
+---------------------------------+-------------------+-----------------------+
|DEVICE_CTRL_SPI_CONFIG_CLOCK |uint32_t |修改SPI设备时钟 |
+---------------------------------+-------------------+-----------------------+
|DEVICE_CTRL_TX_DMA_SUSPEND |NULL |挂起spi tx dma模式 |
+---------------------------------+-------------------+-----------------------+
|DEVICE_CTRL_RX_DMA_SUSPEND |NULL |挂起spi rx dma模式 |
+---------------------------------+-------------------+-----------------------+
|DEVICE_CTRL_TX_DMA_RESUME |NULL |恢复spi tx dma模式 |
+---------------------------------+-------------------+-----------------------+
|DEVICE_CTRL_RX_DMA_RESUME |NULL |恢复spi rx dma模式 |
+---------------------------------+-------------------+-----------------------+
**device_write**
^^^^^^^^^^^^^^^^
``device_write`` 用于 SPI 设备数据的发送发送方式根据打开方式可以是轮询、中断、dma。
.. code-block:: C
int device_write(struct device *dev, uint32_t pos, const void *buffer, uint32_t size);
- dev 设备句柄
- pos 无作用
- buffer 要写入的 buffer 缓冲区
- size 要写入的长度
- return 错误码0 表示写入成功,其他表示错误
**device_read**
^^^^^^^^^^^^^^^^
``device_read`` 用于 SPI 设备数据的接收接收方式根据打开方式可以是轮询、中断、dma。
.. code-block:: C
int device_read(struct device *dev, uint32_t pos, void *buffer, uint32_t size);
- dev 设备句柄
- pos 无作用
- buffer 要读入的 buffer 缓冲区
- size 要读入的长度
- return 错误码0 表示读入成功,其他表示错误
**device_set_callback**
^^^^^^^^^^^^^^^^^^^^^^^^
``device_set_callback`` 用于注册一个 SPI 设备中断回调函数。
.. code-block:: C
int device_set_callback(struct device *dev, void (*callback)(struct device *dev, void *args, uint32_t size, uint32_t event));
- dev 设备句柄
- callback 要注册的中断回调函数
- dev 设备句柄
- args 接收发送缓冲区,数据类型为 uint8_t*
- size 传输长度
- event 中断事件类型
SPI 设备 ``event`` 类型如下
.. code-block:: C
enum spi_event_type
{
SPI_EVENT_TX_FIFO,
SPI_EVENT_RX_FIFO,
SPI_EVENT_UNKNOWN
};
**spi_transmit**
^^^^^^^^^^^^^^^^^^^^^^^^
``spi_transmit`` 用于 SPI 设备数据的发送。
.. code-block:: C
int spi_transmit(struct device *dev, void *buffer, uint32_t size, uint8_t type);
- dev 设备句柄
- buffer 发送数据缓冲区
- size 发送长度
- type 发送位宽类型
``type`` 提供以下类型
.. code-block:: C
#define SPI_TRANSFER_TYPE_8BIT 0
#define SPI_TRANSFER_TYPE_16BIT 1
#define SPI_TRANSFER_TPYE_24BIT 2
#define SPI_TRANSFER_TYPE_32BIT 3
**spi_receive**
^^^^^^^^^^^^^^^^^^^^^^^^
``spi_receive`` 用于 SPI 设备数据的接收。
.. code-block:: C
int spi_receive(struct device *dev, void *buffer, uint32_t size, uint8_t type);
- dev 设备句柄
- buffer 接收数据缓冲区
- size 接收长度
- type 位宽类型
**spi_transmit_receive**
^^^^^^^^^^^^^^^^^^^^^^^^
``spi_transmit_receive`` 用于 SPI 设备数据的发送和接收。
.. code-block:: C
int spi_transmit_receive(struct device *dev, const void *send_buf, void *recv_buf, uint32_t length, uint8_t type);
- dev 设备句柄
- send_buf 发送数据缓冲区
- recv_buf 接收数据缓冲区
- length 收发长度
- type 位宽类型

View File

@ -0,0 +1,299 @@
API 分层模型
=========================
简介
----
为了不影响用户应用层代码因为芯片驱动的不同而频繁修改,**bl_mcu_sdk** 的外设 API 采用了 HAL 层的思想,屏蔽了底层硬件的实现。而 HAL 层又分为两大类:
- 设备驱动管理层:提供一套标准的接口,具体实现由外设驱动适配层实现。
- 外设驱动适配层:实现设备驱动管理层的标准接口,并且拓展自己的独特的接口。
整体的代码分层框架如图所示:
.. figure:: img/api1.png
:alt:
code structure
- 应用层是用户自己编写的代码,接口则是调用 hal 层的接口。
- HAL 层提供给应用层接口,底层调用 std 层,不同的芯片调用不同的 std 层。
- STD 层则是对硬件寄存器进行简单封装,由外设驱动适配层进行调用。
设备驱动管理层实现
---------------------
设备驱动管理层的实现采用了面向对象的思想,首先我们将外设看成是一个设备或者是文件,秉承 **一切皆文件** 的理念,而文件又都具有标准的调用接口:``open``、``close``、``ctrl``、``write``、``read``、``callback``不同文件类别不同比如串口设备、ADC设备、SPI设备并且打开的方式也不同比如轮询、中断、DMA由此我们可以构建出一个对象的基类父类
**基类**
.. code-block:: C
struct device
{
char name[NAME_MAX]; /*name of device */
dlist_t list; /*list node of device */
enum device_status_type status; /*status of device */
enum device_class_type type; /*type of device */
uint16_t oflag; /*oflag of device */
int (*open)(struct device *dev, uint16_t oflag);
int (*close)(struct device *dev);
int (*control)(struct device *dev, int cmd, void *args);
int (*write)(struct device *dev, uint32_t pos, const void *buffer, uint32_t size);
int (*read)(struct device *dev, uint32_t pos, void *buffer, uint32_t size);
void (*callback)(struct device *dev, void *args, uint32_t size, uint32_t event);
void *handle;
};
**基类成员name**
给设备取名,后面会使用 ``device_find`` 找到这个设备。
**基类成员type**
``type`` 记录当前设备的类别,可以选择的 ``type`` 类型如下。
.. code-block:: C
enum device_class_type
{
DEVICE_CLASS_NONE = 0,
DEVICE_CLASS_GPIO,
DEVICE_CLASS_UART,
DEVICE_CLASS_SPI,
DEVICE_CLASS_I2C,
DEVICE_CLASS_ADC,
DEVICE_CLASS_DMA,
DEVICE_CLASS_TIMER,
DEVICE_CLASS_PWM,
DEVICE_CLASS_SDIO,
DEVICE_CLASS_USB,
DEVICE_CLASS_I2S,
DEVICE_CLASS_CAMERA,
DEVICE_CLASS_SEC_HASH,
} ;
**基类成员status**
``status`` 用来记录当前设备的状态,当前提供 4 种状态。
.. code-block:: C
enum device_status_type
{
DEVICE_UNREGISTER = 0,
DEVICE_REGISTERED,
DEVICE_OPENED,
DEVICE_CLOSED
} ;
**基类成员oflag**
``oflag`` 记录 注册时填入的 flag 信息以及使用 ``device_open`` 时填入的 ``oflag`` 信息。
**基类成员list**
设备的增加和删除使用双向链表进行存储,节省内存。
**基类成员:标准的函数指针**
为不同的外设提供了标准的函数接口,当外设实现此类接口并赋值给该成员,便能达到重写的功能。
设备驱动管理层标准接口
-----------------------
**device_register**
^^^^^^^^^^^^^^^^^^^^
``device_register`` 用于设备的注册,将设备信息注册到链表当中。
.. code-block:: C
int device_register(struct device *dev, const char *name, uint16_t flag);
- dev 设备句柄。
- name 设备名称。
- flag 设备的读写属性
- return 返回错误码0 表示注册成功,其他表示错误。
``flag`` 可以写入以下参数,表示:**只读**、**只写**、**可读可写**。
.. code-block:: C
#define DEVICE_OFLAG_RDONLY 0x1000 /* 以只读方式打开设备 */
#define DEVICE_OFLAG_WRONLY 0x2000 /* 以只写方式打开设备 */
#define DEVICE_OFLAG_RDWR 0x3000 /* 以读写方式打开设备 */
**device_unregister**
^^^^^^^^^^^^^^^^^^^^^^^
``device_unregister`` 用于设备的删除,将设备信息从链表中删除。
.. code-block:: C
int device_unregister(const char *name);
- dev 设备句柄
- name 要删除的设备名称
- return 错误码0 表示删除,其他表示错误
**device_find**
^^^^^^^^^^^^^^^^
``device_find`` 用于根据 ``name`` 从链表中寻找设备,并返回设备句柄的首地址。
.. code-block:: C
struct device *device_find(const char *name);
- dev 设备句柄
- name 要查找的设备名称
- return 错误码,不为 0 表示找到的设备句柄NULL 表示未找到该设备。
**device_open**
^^^^^^^^^^^^^^^^
``device_open`` 用于设备的打开,``oflag`` 表示以何种方式打开,目前提供 6 种打开方式。底层调用 ``dev`` 句柄中的 ``open`` 成员。
.. code-block:: C
int device_open(struct device *dev, uint16_t oflag);
- dev 设备句柄
- oflag 设备的打开方式
- return 错误码0 表示打开成功,其他表示错误
``oflag`` 可以写入以下参数:
.. code-block:: C
#define DEVICE_OFLAG_STREAM_TX 0x001 /* 设备以轮训发送模式打开 */
#define DEVICE_OFLAG_STREAM_RX 0x002 /* 设备以轮训接收模式打开 */
#define DEVICE_OFLAG_INT_TX 0x004 /* 设备以中断发送模式打开 */
#define DEVICE_OFLAG_INT_RX 0x008 /* 设备以中断接收模式打开 */
#define DEVICE_OFLAG_DMA_TX 0x010 /* 设备以 DMA 发送模式打开 */
#define DEVICE_OFLAG_DMA_RX 0x020 /* 设备以 DMA 接收模式打开 */
**device_close**
^^^^^^^^^^^^^^^^
``device_close`` 用于设备的关闭。底层调用 ``dev`` 句柄中的 ``close`` 成员。
.. code-block:: C
int device_close(struct device *dev);
- dev 设备句柄
- return 错误码0 表示关闭成功,其他表示错误
**device_control**
^^^^^^^^^^^^^^^^^^^
``device_control`` 用于根据命令对设备进行控制和参数的修改。底层调用 ``dev`` 句柄中的 ``control`` 成员。
.. code-block:: C
int device_control(struct device *dev, int cmd, void *args);
- dev 设备句柄
- cmd 设备控制命令
- args 控制参数
- return 不同的控制命令返回的意义不同。
``cmd`` 提供了以下标准命令,除此之外,不同外设还具有自己的命令
.. code-block:: C
#define DEVICE_CTRL_SET_INT 0x01 /* set interrupt */
#define DEVICE_CTRL_CLR_INT 0x02 /* clear interrupt */
#define DEVICE_CTRL_GET_INT 0x03 /* get interrupt status*/
#define DEVICE_CTRL_RESUME 0x04 /* resume device */
#define DEVICE_CTRL_SUSPEND 0x05 /* suspend device */
#define DEVICE_CTRL_CONFIG 0x06 /* config device */
#define DEVICE_CTRL_GET_CONFIG 0x07 /* get device configuration */
#define DEVICE_CTRL_ATTACH_TX_DMA 0x08
#define DEVICE_CTRL_ATTACH_RX_DMA 0x09
#define DEVICE_CTRL_TX_DMA_SUSPEND 0x0a
#define DEVICE_CTRL_RX_DMA_SUSPEND 0x0b
#define DEVICE_CTRL_TX_DMA_RESUME 0x0c
#define DEVICE_CTRL_RX_DMA_RESUME 0x0d
#define DEVICE_CTRL_RESVD1 0x0E
#define DEVICE_CTRL_RESVD2 0x0F
**device_write**
^^^^^^^^^^^^^^^^
``device_write`` 用于数据的发送发送方式根据打开方式可以是轮询、中断、dma。底层调用 ``dev`` 句柄中的 ``write`` 成员。
.. code-block:: C
int device_write(struct device *dev, uint32_t pos, const void *buffer, uint32_t size);
- dev 设备句柄
- pos 不同的设备 pos 的意义不同
- buffer 要写入的 buffer 缓冲区
- size 要写入的长度
- return 错误码0 表示写入成功,其他表示错误
**device_read**
^^^^^^^^^^^^^^^^
``device_read`` 用于数据的接收接收方式根据打开方式可以是轮询、中断、dma。底层调用 ``dev`` 句柄中的 ``read`` 成员。
.. code-block:: C
int device_read(struct device *dev, uint32_t pos, void *buffer, uint32_t size);
- dev 设备句柄
- pos 不同的设备 pos 的意义不同
- buffer 要读入的 buffer 缓冲区
- size 要读入的长度
- return 错误码0 表示读入成功,其他表示错误
**device_set_callback**
^^^^^^^^^^^^^^^^^^^^^^^^
``device_set_callback`` 用于中断回调函数的注册。底层调用 ``dev`` 句柄中的 ``callback`` 成员。
.. code-block:: C
int device_set_callback(struct device *dev, void (*callback)(struct device *dev, void *args, uint32_t size, uint32_t event));
- dev 设备句柄
- callback 要注册的中断回调函数
* dev 设备句柄
* args 不同外设意义不同
* size 传输长度
* event 中断事件类型
外设驱动适配层实现
------------------------
**子类继承父类**
不同的外设首成员为 ``struct device`` ,这就相当于父类的继承,从而可以使用子类来访问父类成员,当使用子类修改父类成员时,便拥有了子类自己的功能。实现原理是不同结构体的首地址是该结构体中首个成员的地址。
.. code-block:: C
typedef struct xxx_device
{
struct device parent;
} xxx_device_t;
**重写标准接口**
每个外设都有一个 ``xxx_register`` 函数,用来重写标准接口。
.. code-block:: C
dev->open = xxx_open;
dev->close = xxx_close;
dev->control = xxx_control;
dev->write = xxx_write;
dev->read = xxx_read;

View File

@ -0,0 +1,296 @@
UART 设备
=========================
简介
------------------------
UART 全称Universal Asynchronous Receiver/Transmitter通用异步收发传输器提供了与外部设备进行全双工数据交换的灵活方式。博流系列 MCU 中 UART 设备具有以下特性:
- 数据位长度可选择 5/6/7/8 比特
- 停止位长度可选择 0.5/1/1.5/2 比特
- 支持奇/偶/无校验比特
- 支持硬件流控RTS/CTS
- 自动波特率检测
- 支持 LIN 协议(收发 BREAK/SYNC
- 硬件字节发送/接收 FIFO
- 支持轮询、中断、DMA传输
- 特有的 rto 中断
UART 设备结构体定义
------------------------
.. code-block:: C
typedef struct uart_device
{
struct device parent;
uint8_t id;
uint32_t baudrate;
uart_databits_t databits;
uart_stopbits_t stopbits;
uart_parity_t parity;
uint8_t fifo_threshold;
void* tx_dma;
void* rx_dma;
} uart_device_t;
- parent 继承父类属性
- id 串口 id使能串口0则id为0使能串口1则id为1以此类推
- baudrate 波特率
- databits 数据位
- stopbits 停止位
- parity 校验位
- fifo_threshold fifo 阈值,不同 mcu 最大值不同
- tx_dma 附加的发送 dma 句柄
- rx_dma 附加的接收 dma 句柄
``databits`` 提供以下类型
.. code-block:: C
typedef enum
{
UART_DATA_LEN_5 = 0, /*!< Data length is 5 bits */
UART_DATA_LEN_6 = 1, /*!< Data length is 6 bits */
UART_DATA_LEN_7 = 2, /*!< Data length is 7 bits */
UART_DATA_LEN_8 = 3 /*!< Data length is 8 bits */
} uart_databits_t;
``stopbits`` 提供以下类型
.. code-block:: C
typedef enum
{
UART_STOP_ONE = 0, /*!< One stop bit */
UART_STOP_ONE_D_FIVE = 1, /*!< 1.5 stop bit */
UART_STOP_TWO = 2 /*!< Two stop bits */
} uart_stopbits_t;
``parity`` 提供以下类型
.. code-block:: C
typedef enum
{
UART_PAR_NONE = 0, /*!< No parity */
UART_PAR_ODD = 1, /*!< Parity bit is odd */
UART_PAR_EVEN = 2, /*!< Parity bit is even */
} uart_parity_t;
UART 设备参数配置表
------------------------
每一个 UART 设备都有一个参数配置宏,宏定义位于 ``bsp/board/xxx`` 目录下 ``peripheral_config.h`` 文件,变量定义位于 ``hal_uart.c`` 中,因此无需用户自己定义变量。当用户打开对应设备的宏,该设备的配置才生效。例如打开宏 ``BSP_USING_UART0`` ``UART0_CONFIG`` 即生效,同时 ``UART0`` 设备就可以进行注册和使用了。
.. code-block:: C
/*参数配置宏*/
#if defined(BSP_USING_UART0)
#ifndef UART0_CONFIG
#define UART0_CONFIG \
{ \
.id = 0, \
.baudrate = 2000000,\
.databits = UART_DATA_LEN_8, \
.stopbits = UART_STOP_ONE, \
.parity = UART_PAR_NONE, \
.fifo_threshold = 1, \
}
#endif
#endif
/*变量定义*/
static uart_device_t uartx_device[UART_MAX_INDEX] =
{
#ifdef BSP_USING_UART0
UART0_CONFIG,
#endif
#ifdef BSP_USING_UART1
UART1_CONFIG,
#endif
};
.. note:: 上述配置可以通过 ``UART_DEV(dev)->xxx`` 进行修改,只能在调用 ``device_open`` 之前使用。
UART 设备接口
------------------------
UART 设备接口全部遵循标准设备驱动管理层提供的接口。
**uart_register**
^^^^^^^^^^^^^^^^^^^^^^^^
``uart_register`` 用来注册一个 UART 设备,在注册之前需要打开对应 UART 设备的宏定义。例如定义宏 ``BSP_USING_UART0`` 方可使用 ``UART0`` 设备,注册完成以后才可以使用其他接口,如果没有定义宏,则无法使用 ``UART0`` 设备。
.. code-block:: C
int uart_register(enum uart_index_type index, const char *name, uint16_t flag);
- index 要注册的设备索引
- name 为注册的设备命名
- flag 默认可读可写属性
``index`` 用来选择 UART 设备配置,一个 index 对应一个 UART 设备配置,比如 ``UART0_INDEX`` 对应 ``UART0_CONFIG`` 配置,``index`` 有如下可选类型
.. code-block:: C
enum uart_index_type
{
#ifdef BSP_USING_UART0
UART0_INDEX,
#endif
#ifdef BSP_USING_UART1
UART1_INDEX,
#endif
UART_MAX_INDEX
};
**device_open**
^^^^^^^^^^^^^^^^
``device_open`` 用于 UART 设备的打开,``oflag`` 表示以何种方式打开。
.. code-block:: C
int device_open(struct device *dev, uint16_t oflag);
- dev 设备句柄
- oflag 设备的打开方式
- return 错误码0 表示打开成功,其他表示错误
``oflag`` 可以写入以下参数:
.. code-block:: C
#define DEVICE_OFLAG_STREAM_TX 0x001 /* 设备以轮训发送模式打开 */
#define DEVICE_OFLAG_STREAM_RX 0x002 /* 设备以轮训接收模式打开 */
#define DEVICE_OFLAG_INT_TX 0x004 /* 设备以中断发送模式打开 */
#define DEVICE_OFLAG_INT_RX 0x008 /* 设备以中断接收模式打开 */
#define DEVICE_OFLAG_DMA_TX 0x010 /* 设备以 DMA 发送模式打开 */
#define DEVICE_OFLAG_DMA_RX 0x020 /* 设备以 DMA 接收模式打开 */
**device_close**
^^^^^^^^^^^^^^^^
``device_close`` 用于设备的关闭。
.. code-block:: C
int device_close(struct device *dev);
- dev 设备句柄
- return 错误码0 表示关闭成功,其他表示错误
**device_control**
^^^^^^^^^^^^^^^^^^^
``device_control`` 用于根据命令对 UART 设备进行控制和参数的修改。
.. code-block:: C
int device_control(struct device *dev, int cmd, void *args);
- dev 设备句柄
- cmd 设备控制命令
- args 控制参数
- return 不同的控制命令返回的意义不同。
串口设备除了标准的控制命令,还具有自己特殊的控制命令。
.. code-block:: C
#define DEVICE_CTRL_UART_GET_TX_FIFO 0x10
#define DEVICE_CTRL_UART_GET_RX_FIFO 0x11
``args`` 根据不同的 ``cmd`` 传入不同,具体如下:
+---------------------------------+---------------------+------------------------------+
|cmd |args |description |
+=================================+=====================+==============================+
|DEVICE_CTRL_SET_INT |uart_it_type |开启spi设备中断 |
+---------------------------------+---------------------+------------------------------+
|DEVICE_CTRL_CLR_INT |uart_it_type |关闭spi设备中断 |
+---------------------------------+---------------------+------------------------------+
|DEVICE_CTRL_CONFIG |uart_param_cfg_t* |修改串口配置 |
+---------------------------------+---------------------+------------------------------+
|DEVICE_CTRL_ATTACH_TX_DMA |struct device* |链接发送dma设备 |
+---------------------------------+---------------------+------------------------------+
|DEVICE_CTRL_ATTACH_RX_DMA |struct device* |链接接收dma设备 |
+---------------------------------+---------------------+------------------------------+
|DEVICE_CTRL_ATTACH_RX_DMA |struct device* |链接接收dma设备 |
+---------------------------------+---------------------+------------------------------+
|DEVICE_CTRL_TX_DMA_SUSPEND |NULL |挂起uart tx dma模式 |
+---------------------------------+---------------------+------------------------------+
|DEVICE_CTRL_RX_DMA_SUSPEND |NULL |挂起uart rx dma模式 |
+---------------------------------+---------------------+------------------------------+
|DEVICE_CTRL_TX_DMA_RESUME |NULL |恢复uart tx dma模式 |
+---------------------------------+---------------------+------------------------------+
|DEVICE_CTRL_RX_DMA_RESUME |NULL |恢复uart rx dma模式 |
+---------------------------------+---------------------+------------------------------+
|DEVICE_CTRL_UART_GET_TX_FIFO |uint32_t* |获取uart 发送fifo数据个数 |
+---------------------------------+---------------------+------------------------------+
|DEVICE_CTRL_UART_GET_RX_FIFO |uint32_t* |获取uart 接收fifo数据个数 |
+---------------------------------+---------------------+------------------------------+
**device_write**
^^^^^^^^^^^^^^^^
``device_write`` 用于 UART 设备数据的发送发送方式根据打开方式可以是轮询、中断、dma。
.. code-block:: C
int device_write(struct device *dev, uint32_t pos, const void *buffer, uint32_t size);
- dev 设备句柄
- pos 无作用
- buffer 要写入的 buffer 缓冲区
- size 要写入的长度
- return 错误码0 表示写入成功,其他表示错误
**device_read**
^^^^^^^^^^^^^^^^
``device_read`` 用于 UART 设备数据的接收接收方式根据打开方式可以是轮询、中断、dma。
.. code-block:: C
int device_read(struct device *dev, uint32_t pos, void *buffer, uint32_t size);
- dev 设备句柄
- pos 无作用
- buffer 要读入的 buffer 缓冲区
- size 要读入的长度
- return 错误码0 表示读入成功,其他表示错误
**device_set_callback**
^^^^^^^^^^^^^^^^^^^^^^^^
``device_set_callback`` 用于注册一个串口中断回调函数。
.. code-block:: C
int device_set_callback(struct device *dev, void (*callback)(struct device *dev, void *args, uint32_t size, uint32_t event));
- dev 设备句柄
- callback 要注册的中断回调函数
- dev 设备句柄
- args 接收发送缓冲区,数据类型为 uint8_t*
- size 传输长度
- event 中断事件类型
串口设备 ``event`` 类型如下
.. code-block:: C
enum uart_event_type
{
UART_EVENT_TX_END,
UART_EVENT_TX_FIFO,
UART_EVENT_RX_END,
UART_EVENT_RX_FIFO,
UART_EVENT_RTO,
UART_EVENT_UNKNOWN
};

View File

@ -0,0 +1,136 @@
Linux OR WSL 环境开发指南
=============================
本文档介绍了如何在 Linux 安装配置 BL702 系列 MCU 需要的软件开发工具。而 WSL 的安装配置方式与 linux 下一样。唯一的区别就是一个运行在linux上比如 Ubuntu ,一个运行在 windows 上。如果不想装虚拟机或者linux系统可以选择 WSL。
**Windows Subsystem for Linux** (简称 WSL )是一个在 Windows 10 上能够运行原生 Linux 二进制可执行文件ELF格式的兼容层。它是由微软与Canonical公司合作开发其目标是使纯正的Ubuntu 14.04 "Trusty Tahr"映像能下载和解压到用户的本地计算机,并且映像内的工具和实用工具能在此子系统上原生运行。因此,在 WSL 下的操作方式和 linux 下的操作方式是完全相同的。
需要的软硬件环境
-----------------------------
- 一根 mini USB 数据线
- 一个 USB-TTL 串口模块
- 杜邦线若干
配置 RISC-V 工具链
-----------------------------
.. code-block:: bash
:linenos:
:emphasize-lines: 4-6
$ cd ~
$ wget -c https://dev.bouffalolab.com/media/upload/download/riscv64-elf-x86_64-20210120.tar.gz
$ mkdir -p riscv64-elf-20210120
$ tar -zxvf riscv64-elf-x86_64-20210120.tar.gz -C riscv64-elf-20210120
$ sudo cp ~/riscv64-elf-20210120 /usr/bin
$ echo "export PATH=\"$PATH:/usr/bin/riscv64-elf-20210120/bin\"" >> ~/.bashrc
$ source ~/.bashrc
配置 cmake & make 工具
----------------------------
.. code-block:: bash
:linenos:
:emphasize-lines: 5-7
$ sudo apt update
$ sudo apt install make
$ cd ~
$ wget -c https://cmake.org/files/v3.19/cmake-3.19.3-Linux-x86_64.tar.gz
$ tar -zxvf cmake-3.19.3-Linux-x86_64.tar.gz
$ sudo cp ~/cmake-3.19.3-Linux-x86_64 /usr/bin
$ echo "export PATH=\"$PATH:/usr/bin/cmake-3.19.3-Linux-x86_64/bin\"" >> ~/.bashrc
$ source ~/.bashrc
硬件连接
----------------------
- 具体开发板的连接, 请参考 :ref:`connect_hardware` 部分
- 请确保开发板正确设置后再进行下面的步骤 (建议 Linux 下采用串口连接)
获取 bl_mcu_sdk
---------------------------
- 打开终端输入以下命令获取 bl_mcu_sdk
.. code-block:: bash
:linenos:
$ cd ~
$ git clone https://gitee.com/bouffalolab/bl_mcu_sdk.git --recursive
测试 Hello World 工程
------------------------------
打开 Hello World
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- 获取到 SDK 后,进入 sdk 中的 ``examples/hellowd/helloworld`` 目录下,打开 ``main.c``,即可编辑 helloworld 的相关代码。
.. code-block:: bash
:linenos:
$ cd ~/bl_mcu_sdk/examples/hellowd/helloworld
$ vi main.c
- 若编辑完成后,保存修改并关闭文件,接下来进行编译
编译 Hello World
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. code-block:: bash
:linenos:
$ cd ~/bl_mcu_sdk
$ make build BOARD=bl706_iot APP=helloworld
烧写 Hello World
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- 烧写前请先确认烧写方式,若采用串口烧写,请先按住板子上的 ``boot`` 键不要释放,此时在按下 ``rst`` 键,然后释放两个键,此时板子进入 boot_rom 状态。
- 这时在终端中输入以下命令进行烧写
.. code-block:: bash
:linenos:
$ cd ~/bl_mcu_sdk
$ make download INTERFACE=uart
- 如果下载失败请检查:
- 1. 是否使用串口烧写,开发板是否供电,硬件连接是否正确。
- 2. 烧写命令是否在 ``bl_mcu_sdk`` 目录下执行
- 3. 是否进入 boot_rom 模式
- 4. 串口是否被占用
运行 Hello World
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- 打开新的终端,安装、运行串口工具
.. code-block:: bash
:linenos:
$ sudo apt install picocom # 若已经安装请忽略
$ picocom -b 2000000 /dev/ttyUSB0
- 按一下开发板上的 ``rst`` 按键,即可在串口终端中看到 ``hello world``
.. figure:: img/linux1.png
:alt:
helloworld!
调试 Hello World
^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -0,0 +1,166 @@
.. _windows_cdk_quick_start:
Windows 下使用 CDK (类 MDK Keil)开发指南
=============================================
本文档介绍了如何在 Windows 下使用 `平头哥半导体 <https://www.t-heah.cn/about>`_ 开发的 CDK 集成开发环境,
来完成博流 BL702 系列 MCU 的相关软件开发工作。
关于剑池 CDK ,这是一款由平头哥半导体开发打造的集成开发环境。它拥有和传统 MCU 开发环境十分近似的操作和设置,旨在不改变用户开发习惯的基础上,全面接入云端开发资源,结合图形化的 OSTracer、Profiling 等调试分析工具,加速用户产品开发。
需要的软硬件环境
-----------------------------
- 剑池 CDK 软件
- 一根 USB Type-A 数据线
- 一个 CK-Link 仿真器
- 一个 USB-TTL 串口模块
- 杜邦线若干
下载剑池 CDK 软件安装包
-----------------------------
- `剑池CDK <https://occ.t-head.cn/development/series/download?id=3864775351511420928&type=kind&softPlatformType=4#sticky>`_ 软件安装可以从平头哥半导体 OCC 官网获取到。
- 下载完成后,解压缩,双击 ``setup.exe``,按照其提示,完成软件安装即可。
下载 bl_mcu_sdk 软件开发包
----------------------------
- 从开源社区下载 bl_mcu_sdk 软件开发包。
- 可以使用 ``git clone`` 或者直接 ``download`` 的方式下 SDK
- 使用 ``git clone`` 前请确保已正确安装 ``git``,打开支持 ``git`` 的终端输入以下命令即可获取最新的 SDK。
.. code-block:: bash
:linenos:
:emphasize-lines: 1
$ git clone https://gitee.com/bouffalolab/bl_mcu_sdk.git --recursive
硬件连接
----------------------
- 具体开发板的连接, 请参考 :ref:`connect_hardware` 部分
- 请确保开发板被正确设置后再进行下面的步骤
测试 Hello World 工程
------------------------------
打开 Hello World
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- 获取到 SDK 后,进入 sdk 中的 ``examples/hellowd/helloworld/cdk`` 目录下,双击 ``helloworld.cdkproj``,即可打开 ``Helloworld`` 工程。
编译 Hello World
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. figure:: img/cdk1.png
:alt:
helloworld.cdkproj
- 在 CDK 工具栏中,点击编译图标即可编译工程
- 点击 ``1`` 处 图标 ``Build Project`` 即可编译当前选中的工程
- 点击 ``2`` 处 图标 ``Clean Project`` 即可清除上次编译的结果
- 点击 ``3`` 处 图标 ``Flash Download`` 即可将编译好的代码下载到芯片中
- 点击 ``4`` 处 图标 ``Start/Stop Debug`` 即可进行 debug 的相关操作
- 也可以在 ``Project`` 中,右击工程名称,通过右击菜单中的选项对项目进行编译等操作
烧写 Hello World
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- 由于目前 CDK 软件中还没有包含我们的 flash 算法,所以需要我们手动将 flash 算法放到 CDK 安装目录,具体操作如下:
- 进入 SDK 目录下 ``tools\cdk_flashloader`` 目录
- 将目录下的 ``bl70x_flasher.elf`` 文件,拷贝到 CDK 工具的 ``C-Sky\CDK\CSKY\Flash`` 目录中
.. figure:: img/cdk7.png
:alt:
CDK Flash Loader
.. figure:: img/cdk8.png
:alt:
CDK Project Setting
- 点击 ``Project View`` 中的项目设置按钮,打开 ``Project Setting`` 窗口,或者通过右击 ``Project`` 名称中右击菜单栏中打开
- 在打开的 ``Project Setting`` 窗口中,选择 ``Flash`` 标签,配置需要的 Flash 算法
.. figure:: img/cdk9.png
:alt:
CDK Project Flash setting
- 在 ``Flash`` 标签中,点击 ``Add`` 按纽,在打开的列表中选择 ``bl70x_flash`` 算法,点击 ``Add`` 添加到工程中,``Flash`` 标签下的其他设置,如图所示:
- 点击 OK 后,如配置正确,点击 ``Flash Download`` 即可将编译好的代码下载到芯片中
.. figure:: img/cdk5.png
:alt:
CDK Flashdownload Success
- 如下载失败请检查:
- 1. 代码是否被正确编译,并生成 ``.elf`` ``.bin`` 等文件
- 2. Flash 算法是否被正确设置
- 3. CK-Link 与开发板是否正确连接
- 4. 开发板是否正常供电,电源指示灯是否点亮
运行 Hello World
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- 从 CDK 的菜单栏 ``View->Serial Pane``,打开串口面板,在打开的 ``Serial Pane`` 中右击,进行串口设置,选择你对应的串口号和波特率
.. figure:: img/cdk4.png
.. figure:: img/cdk3.png
:alt:
CDK Serial Pane setting
- 按下板子上的 ``RST`` 按键,即可在串口中看到代码的运行结果
.. figure:: img/cdk6.png
:alt:
HelloWorld
调试 Hello World
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- 点击工具栏上方的 ``Start/Stop Debugger`` 按钮,进入 debug 界面,如下图所示
.. figure:: img/cdk10.png
:alt:
Debug HelloWorld
- 在 debug 界面下,左侧的 ``Register`` 窗口中,可以查看 ``CPU`` 内部寄存器数据;右侧的 ``Peripherals`` 外设面板中,
可以查看相应外设寄存器数据,外设的选择可以在顶部菜单栏的 ``Peripherals->System Viewer`` 选择;
点击上方工具栏中的相关调试按钮可以进行断点设置、单步调试、指令单步和全速运行等操作。
当然这些操作都有相应的快捷键和快捷设置方法,详情请参考 ``CDK Help``,这里就不作过多介绍了。
- 我们点击单步运行按钮,运行代码,即可看到指示光标移动到下一句代码,同时可以看到串口面板中显示了我们输出的 ``Hello World``
.. figure:: img/cdk11.png
:alt:
Debug HelloWorld

View File

@ -0,0 +1,175 @@
Windows 下使用 Eclipse 开发指南
================================
本文档介绍了如何在 Windows 下使用 eclipse构建 BL702 系列 MCU 的软件开发环境。
需要的软硬件环境
-----------------------------
- Eclipse 免安装软件包
- 串口助手软件
- 一根 USB Type-A 数据线
- 一个 j-link 仿真器
- 一个 USB-TTL 串口模块
- 杜邦线若干
下载 Eclipse 安装包
-----------------------------
- 从 Bouffalo Lab 开发者社区下载带有 RISC-V 工具链的 `Eclipse https://dev.bouffalolab.com/download <https://dev.bouffalolab.com/media/upload/download/BouffaloLab_eclipse_x86_64_win.zip>`_ 安装包。
下载 bl_mcu_sdk
-----------------------------
- 从开源社区下载 `bl_mcu_sdk <https://gitee.com/bouffalolab/bl_mcu_sdk.git>`_ 软件开发包。
- 可以使用 ``git clone`` 或者直接 ``download`` 的方式下 SDK
- 使用 ``git clone`` 前请确保已正确安装 ``git``,打开支持 ``git`` 的终端输入以下命令即可获取最新的 SDK。
.. code-block:: bash
:linenos:
:emphasize-lines: 1
$ git clone https://gitee.com/bouffalolab/bl_mcu_sdk.git --recursive
配置 eclipse 开发环境
----------------------------
- 将获取到的 eclipse 压缩包拷贝到您的工作目录,解压 eclipse 压缩包
- 进入 eclipse 目录,双击 ``eclipse.exe`` 启动 eclipse
- 选择您的 ``Workspace`` 目录,点击 ``Launch`` 进入工作空间
.. figure:: img/pic1.png
:alt:
- 点击菜单栏中 ``Window->preferences`` 打开环境配置相关页面,准备导入相关的配置环境
.. figure:: img/pic2.png
:alt:
- 点击下图 1 处的图标,打开导入配置界面,按照如图所示步骤,选择 ``eclipse.exe`` 目录下的 ``bflb_mcu_preferences.epf`` 配置文件。
.. figure:: img/pic3.png
:alt:
- 选择好对应的文件后,点击 ``Finish``,在弹出的对话框选中点击 ``cancel`` ,不用重新启动。
.. figure:: img/pic4.png
:alt:
导入 bl_mcu_sdk
--------------------------
- 点击 菜单栏 ``File->Import`` ,打开导入项目的配置界面
.. figure:: img/pic5.png
:alt:
- 在打开的 ``Import`` 窗口中选择 ``General->Existing Projects into Workspace`` ,然后点击 ``Next``
.. figure:: img/pic6.png
:alt:
- 加载 bl_mcu_sdk 的工程路径后,点击 ``Finsh`` 完成导入
.. figure:: img/pic7.png
:alt:
- 导入完成后,关闭 ``Welcome`` 窗口即可看到导入的工程
.. figure:: img/pic8.png
:alt:
.. figure:: img/pic9.png
:alt:
- 展开 ``Build Target`` 目录,即可看到 ``bl_clean``、``bl_make``、``download`` 三个功能按钮。
- 双击 ``bl_clean`` 按钮,会清除 ``build`` 和 ``out`` 两个目录下的编译缓存
- 双击 ``bl_make`` 按钮,会正常编译设置的 case若没有修改默认配置则会编译 ``helloworld`` 工程
- 双击 ``download`` 按钮,会下载代码到芯片中,若没有编译成功则会下载默认的或者上一次的 ``.bin`` 文件
硬件连接
----------------------
- 具体开发板的连接, 请参考 :ref:`connect_hardware` 部分eclipse 环境建议使用 ``j-link`` 烧写、调试)
- 请确保开发板正确设置后再进行下面的步骤
测试 Hello World 工程
------------------------------
打开 Hello World
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- 打开 ``examples/hellowd/helloworld/main.c`` 文件,即可编辑、修改 ``helloworld`` 测试 demo 的代码,若修改了,请保存后在执行编译
编译 Hello World
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- 双击 ``bl_make`` 即可编 helloworld 工程
- 编译成功后 ``Console`` 窗口可以看到如下图所示的 log 信息
.. figure:: img/pic10.png
烧写 Hello World
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- 双击 ``download`` 即可烧写 helloworld 工程 ``bin`` 文件到芯片中
- 下载成功后 ``Console`` 窗口可以看到如下图所示的 log 信息
.. figure:: img/pic11.png
运行 Hello World
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- 将开发板的 ``TXD0``、``RXD0`` 和 ``GND`` 引脚使用杜邦线连接到 USB-TTL 串口模块,将串口模块插入 PC 主机, 使用任意的串口助手软件打开串口
- 烧写成功后,按下板子上的 ``rst`` 按键,如果下载正确,即可在串口助手软件中看到如下图所示的 log 信息。
.. figure:: img/eclipse_run.png
调试 Hello World
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- 点击 eclipse 工具栏中的 ``Debug`` 按钮,进入 debug 配置窗口
- 选择 ``GDB SEGGER J-Link Debugging->Jlink_bl_mcu_sdk`` Debug 配置,在 ``C/C++ Application:`` 选项中选择需要调试的 ``.elf`` 文件
- 先点击 ``Apply`` 后,在点击 ``Debug`` 即可进行 ``Debug``
.. figure:: img/pic14.png
:alt:
- 进入 Debug 界面后,即可看到程序停在了 ``main``,点击上方工具栏中的 ``Step Over``,按钮即可对代码工程进行单步调试。
.. figure:: img/pic15.png
:alt:
Eclipse Debugging
编译烧写不同的目标工程
-----------------------
- 当右击 ``bl_make`` 按钮,点击 ``Edit`` 后,会弹出更换目标工程的配置界面,如下图所示
.. figure:: img/pic12.png
:alt:
- 其中 ``APP=xxx`` 用户可以修改其内容,改为需要编译烧写的目标工程名,例如想要编译烧写 ``gpio/gpio_blink`` 工程,将其修改为 ``APP=gpio_blink`` 即可
- ``Build command`` 中 ``make BOARD=bl706_iot`` 会指定不同的 Board 类型以指定适配不同类型的开发板。
- ``Board`` 类型决定编译时选择相应的 ``borad`` 头文件。默认选择的是 BL706 的 iot 开发板 ``make build BOARD=bl706_iot``

View File

@ -0,0 +1,94 @@
.. _bl_dev_cube:
BLDevCube 烧录工具指南
=======================
本文档将简要介绍一下如何使用 Bouffalo Lab Dev Cube 集成开发工具进行代码的烧写,更多详情请参考 `BLDevCube 用户手册 <https://dev.bouffalolab.com/media/upload/doc/DevCube%E7%94%A8%E6%88%B7%E6%89%8B%E5%86%8Cv1.2.pdf>`_
下载安装 Bouffalo Lab Dev Cube 工具
------------------------------------
- 从博流智能开发者社区下载适合您操作系统的版本,下载地址:`https://dev.bouffalolab.com/download <https://dev.bouffalolab.com/download>`_ ,从这里可以获取到最新版本工具
- 没有注册开发者账号的用户,可以点击开发者入口,使用 ``guest`` 用户进入
- 下载完成后,解压后即可使用
配置工具下载方式
----------------
- 双击解压后文件夹的 ``BLDevCube.exe``, 在 ``Chip Selection`` 对话框中,在 ``Chip Type`` 的下拉框中,选择您要开发的对应芯片的型号,点击 ``Finish`` 进入 ``Dev Cube`` 主界面
- 进入主界面后在上方的菜单栏 ``View`` 标签下选择 ``MCU`` 下载方式,进入 MCU 程序下载主界面
.. figure:: img/dev_cube_view_mcu.png
:alt:
select mcu
- 在 ``Image`` 标签下 ``Interface`` 栏选择相应的下载方式,根据您的实际物理链接进行选择
- ``Image file`` 栏配置您想要下载的镜像绝对路径地址,可以点击 ``Browse`` 按钮来选择您的 **Bin** 文件
- 点击 ``click here to show advanced options`` 时,会展开高级镜像配置,通常情况下保持默认配置即可;需要注意的是, ``Flash Clock`` 会同时影响到 Flash 和 PSRAM 的时钟频率,在需要使用 PSRAM 的情况下可以适当提高该时钟频率以获得更好的性能
使用 UART 下载程序
^^^^^^^^^^^^^^^^^^
- ``COM Port`` 栏用于使用 UART 进行下载时,选择与芯片连接的 COM 口号,可以点击 Refresh 按钮进行 COM 号的刷新
- ``Uart Speed`` 栏用于使用 UART 下时,配置合适的波特率,默认 2M
- 下载前请确保硬件配置正确:
- 使用 ``Type-C USB`` 数据线 or ``Mini USB`` 数据线连接到开发板上对应的 USB ``Type-C`` 接口 or ``Mini`` 接口上。
- 按下开发板上的 ``Boot`` 键,不要释放
- 按下开发板上的 ``RST`` 键,此时已经进入 ``Boot ROM``,可以释放两个按键
- 这时就可以从 ``Bouffalo Lab Dev Cube`` 中看到相应的串口 ``COM`` 号,如没有出现,请点击 ``Refresh`` 按钮刷新一下
- 在正确完成上述配置后,点击 ``Create&Program`` 按钮进行下载
- 下载成功后即可看到状态栏变成绿色并显示 ``Success``
.. figure:: img/dev_cube_download.png
:alt:
download success!
使用 Openocd 下载程序
^^^^^^^^^^^^^^^^^^^^^^
- 使用 openocd 下载程序与使用串口下载时工具配置基本相同,只需要将 ``Interface`` 切换成 ``Openocd`` 即可
- 硬件连接需要更改为支持 Openocd 的调试器连接(本教程以 Sipeed RV Debugger 为例):
- 1. 首先将 RV 调试器连接到电脑的 USB 接口,打开设备管理器,会发现调试器被识别为两个串口(注:不是开发板上的串口)
.. figure:: img/sipeed_rv_debugger_1.png
- 2. 从 sipeed 下载 ``zadig-2.4`` 替换驱动程序。下载地址:`http://dl.sipeed.com/MAIX/tools/sipeed-rv-debugger/zadig-2.4.exe <http://dl.sipeed.com/MAIX/tools/sipeed-rv-debugger/zadig-2.4.exe>`_
- 3. 下载好双击打开 ``zadig-2.4.exe``,选择 Options 勾选 List All Devices.
.. figure:: img/sipeed_rv_debugger_3.png
- 4. 找到 JTAG Debugger(Interface 0),然后选择替换的驱动为 WinUSB 点击 Replace Driver 替换
- 5. 再次打开设备管理器, 看到其中一个串口被替换成通用串行总线设备就说明安装成功
.. figure:: img/sipeed_rv_debugger_2.png
- 6.将调试器的 JTAG 引脚与开发板的 JTAG 引脚连接起来
- 在正确完成上述配置后,点击 ``Create&Program`` 按钮进行下载
- 下载成功后即可看到状态栏变成绿色并显示 ``Success``
使用 Jlink 下载程序
^^^^^^^^^^^^^^^^^^^^^^
- 使用 Jlink 下载程序与使用 Openocd 下载时工具配置基本相同,只需要将 ``Interface`` 切换成 ``Jlink`` 即可
- 硬件连接需要更改为使用 Jlink 连接(本教程以 Jlink V11 为例,建议使用 Jlink V10 以上版本):
- 1. 首先从 Segger 官网下载合适的 Jlink 驱动程序并安装
- 2. 将 Jlink 调试器连接到电脑的 USB 接口
- 3. 将 JLink 调试器的 JTAG 引脚与开发板的 JTAG 引脚连接起来
- 在正确完成上述配置后,点击 ``Create&Program`` 按钮进行下载
- 下载成功后即可看到状态栏变成绿色并显示 ``Success``

View File

@ -0,0 +1,20 @@
基于 cmake 框架构建自己的工程
================================
添加demo工程
---------------
添加demo工程+依赖源文件
-----------------------
添加demo工程+依赖库
-----------------------
添加demo工程+私有编译选项gcc option
----------------------------------------
添加demo工程+私有链接脚本ld
---------------------------------
添加demo工程+依赖源文件+依赖库
---------------------------------

View File

@ -34,7 +34,7 @@ BL706_IOT 开发板
使用 J-Link 烧写、调试连接方法
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- 将 j-link 的 USB 接口使用合适的 USB 数据线正确连接到 PC 主机
- 将 Iot 开发板的 ``HD3`` 组的标准 ``JTAG`` 引脚使用杜邦线与 ``j-link`` 对应的 ``JTAG`` 引脚连接起来
@ -86,7 +86,7 @@ BL702_AVB 开发板
--------------------------
使用 CK-Link 烧写、调试连接方法
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- ``TO DO``

View File

@ -18,11 +18,14 @@ BL MCU SDK 将为您提供博流 BL70X 系列 MCU 开发的全方位支持。
:caption: 快速开发指南
:numbered:
get_started
Windows_quick_start_cdk
Windows_quick_start_eclipse
Linux_quick_start_ubuntu
connecting_hardware
get_started/get_started
get_started/Windows_quick_start_cdk
get_started/Windows_quick_start_eclipse
get_started/Linux_quick_start_ubuntu
get_started/bl_dev_cube
get_started/cmake_quick_start
get_started/connecting_hardware
@ -31,15 +34,40 @@ BL MCU SDK 将为您提供博流 BL70X 系列 MCU 开发的全方位支持。
:caption: API 手册
:numbered:
api_guide
api_reference/api_structure
api_reference/api_clock
api_reference/api_gpio
api_reference/api_uart
api_reference/api_pwm
api_reference/api_dma
api_reference/api_i2c
api_reference/api_spi
api_reference/api_adc
api_reference/api_dac
.. toctree::
:maxdepth: 1
:caption: 示例代码
:caption: 基础外设例程
:numbered:
blink_demo_introduce
breath_pwm_demo_introduce
uart_loopback_demo_introduce
samples/basic samples/blink_demo
samples/basic samples/button_demo
samples/basic samples/breath_pwm_demo
samples/basic samples/uart_loopback_demo
samples/basic samples/mtimer_demo
samples/basic samples/dma_m2m_demo
samples/basic samples/i2c_eeprom_demo
samples/basic samples/spi_lcd_demo
samples/basic samples/adc_key_demo
.. toctree::
:maxdepth: 1
:caption: 进阶例程
:numbered:
samples/advance samples/shell_demo
samples/advance samples/fatfs_demo
samples/advance samples/lowpower_demo
samples/advance samples/ble_scan_demo
samples/advance samples/boot2_iap_info

View File

@ -0,0 +1,201 @@
BLE 客户端和服务端互连
=======================
本 demo 基于 **bl702** 演示 **ble server** 和 **ble client** 连接和数据收发。
准备工具
-----------------------
- 两块 bl702 开发板 or 一块 bl702 开发板 + 手机 app
软件实现
-----------------------
BLE client 软件实现
^^^^^^^^^^^^^^^^^^^^^^^^
- 软件代码见 ``examples/ble/ble_central``
.. code-block:: C
:linenos:
static struct bt_conn_cb ble_tp_conn_callbacks = {
.connected = ble_tp_connected,
.disconnected = ble_tp_disconnected,
}
void ble_tp_init()
{
if( !isRegister )
{
isRegister = 1;
bt_conn_cb_register(&ble_tp_conn_callbacks);
}
}
- 在 ``bt_conn_cb_register`` 函数中,注册连接成功和断开连接的 ``callback`` 函数
- 在 ``ble_start_scan`` 函数中,设备就开始进行扫描
- 在 ``device_found`` 函数中,设备上传扫描到的蓝牙设备,代码通过 ``adv_name`` 来找到需要连接的蓝牙设备,发起连接
.. code-block:: C
:linenos:
static void ble_write_data_task(void *pvParameters)
{
int error;
uint8_t buf[20] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
while(1)
{
k_sem_take(&write_data_poll_sem, K_FOREVER);
BT_WARN("ble_write_data\r\n");
// Send data to server
error = bt_gatt_write_without_response(ble_tp_conn,char_hdl.tp_wr_hdl,buf,20,0);
BT_WARN("Write Complete (err %d)\r\n", error);
}
}
- 连接成功后,在 ``ble_write_data_task`` 函数, client 发送 ``buf`` 里面的数据到 server
.. code-block:: C
:linenos:
static u8_t notify_func(struct bt_conn *conn,struct bt_gatt_subscribe_params *params,const void *data, u16_t length);
- 连接成功后,在 ``notify_func`` 函数, client 接收来自 server 的数据, ``data`` 是数据内容, ``length`` 是数据长度
BLE server 软件实现
^^^^^^^^^^^^^^^^^^^^^^^^
- 软件代码见 ``examples/ble/ble_peripheral``
.. code-block:: C
:linenos:
int ble_start_adv(void)
{
struct bt_le_adv_param adv_param = {
//options:3, connectable undirected, adv one time
.options = 3, \
.interval_min = BT_GAP_ADV_FAST_INT_MIN_3, \
.interval_max = BT_GAP_ADV_FAST_INT_MAX_3, \
};
char *adv_name = "BL_TEST_01"; // This name must be the same as adv_name in ble_central
uint8_t data[1] = {(BT_LE_AD_LIMITED | BT_LE_AD_NO_BREDR)};
uint8_t data_uuid[2] = {0x12, 0x18};//0x1812
uint8_t data_appearance[2] = {0x80, 0x01};//0x0180
uint8_t data_manu[4] = {0x71, 0x01, 0x04, 0x13};
struct bt_data adv_data[] = {
BT_DATA(BT_DATA_FLAGS, data, 1),
BT_DATA(BT_DATA_UUID16_ALL, data_uuid, sizeof(data_uuid)),
BT_DATA(BT_DATA_GAP_APPEARANCE, data_appearance, sizeof(data_appearance)),
BT_DATA(BT_DATA_NAME_COMPLETE, adv_name, strlen(adv_name)),
BT_DATA(BT_DATA_MANUFACTURER_DATA, data_manu, sizeof(data_manu))
};
return bt_le_adv_start(&adv_param, adv_data, ARRAY_SIZE(adv_data), NULL, 0);
}
- 在 ``ble_start_adv`` 函数中, ``adv_name`` 设置这次广播的设备名称,设备就开始进行广播
.. code-block:: C
:linenos:
static int ble_tp_recv_wr(struct bt_conn *conn, const struct bt_gatt_attr *attr,const void *buf, u16_t len, u16_t offset, u8_t flags);
- 连接成功后, 在 ``ble_tp_recv_wr`` 中server接收来自client的数据 ``buf`` 是数据内容, ``len`` 是数据长度
.. code-block:: C
:linenos:
static void ble_tp_notify_task(void *pvParameters)
{
int err = -1;
char data[244] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09};
k_sem_give(&notify_poll_sem);
while(1)
{
k_sem_take(&notify_poll_sem, K_FOREVER);
//send data to client
err = bt_gatt_notify(ble_tp_conn, get_attr(BT_CHAR_BLE_TP_NOT_ATTR_VAL_INDEX), data, (tx_mtu_size - 3));
BT_WARN("ble tp send notify : %d\n", err);
}
}
- 连接成功后,在 ``ble_tp_notify_task`` 函数, server 发送 ``data`` 里面的数据到 client.
编译和烧录
-----------------------------
- **CDK工具编译**
暂不支持
- **命令行编译**
.. code-block:: bash
:linenos:
$ cd <sdk_path>/bl_mcu_sdk
$ make BOARD=bl706_iot APP=ble_peripheral SUPPORT_FREERTOS=y SUPPORT_FLOAT=y SUPPORT_BLE=y
.. code-block:: bash
:linenos:
$ cd <sdk_path>/bl_mcu_sdk
$ make BOARD=bl706_iot APP=ble_central SUPPORT_FREERTOS=y SUPPORT_FLOAT=y SUPPORT_BLE=y
- **烧录**
见 ``使用bouffalo_dev_cube烧录代码``
实验现象
-----------------------------
- **两个 bl702 对连**
.. figure:: img/ble_client.png
:alt:
.. figure:: img/ble_server.png
:alt:
- **手机连接 bl702**
.. figure:: img/phone_connect.jpg
:alt:
- 连接成功,如下图所示
.. figure:: img/phone_connected.png
:alt:
- 收发数据步骤
- 点击 ``1`` 处 图标 ``Unknow Service`` 显示具体的 service 属性
- 点击 ``2`` 处 图标 开启 ``Notification`` ,允许 server 发送数据给 client
- 点击 ``3`` 处 图标 client 发送数据给 server填写自己想要发送的数据点击 ``SEND`` 按钮
.. figure:: img/ble_data.png
:alt:
.. figure:: img/receive_data.png
:alt:
.. figure:: img/write_data.jpg
:alt:

View File

@ -0,0 +1,28 @@
BOOT2 IAP
============================
IAP 是 In Application Programming 的首字母缩写IAP 是用户自己的程序在运行过程中对 User Flash的部分区域进行烧写
目的是为了在产品发布后可以方便地通过预留的通信口对产品中的固件程序进行更新升级。
通常在用户需要实现 IAP 功能时,即用户程序运行中作自身的更新操作,需要在设计固件程序时编写两个项目代码,
第一个项目程序不执行正常的功能操作,而只是通过某种通信管道(如 USB、USART )接收程序或数据,
执行对第二部分代码的更新;第二个项目代码才是真正的功能代码。
Bouffalo Lab 为 IAP 功能应用提供了相应的 boot2_iap.bin 文件,并将其与 Dev Cube 软件包同步发布。
用户可以配合 Dev Cube 图形界面烧写软件,将已有的 boot2_iap.bin 文件烧录进目标板,烧录
一次之后,就可以通过 IAP 功能,在线更新用户代码。
bl_mcu_sdk 开源了 boot2_iap 的软件源码,用户可以到 examples/boot2_iap 查阅代码,并完成编译烧写。编译烧写过程可以参考《快速开发指南》介绍。
准备工具
-----------------------
- 最新版本的 Dev Cube
- Bl706 开发板
- TTL-USB 电平转换芯片
实验现象
-----------------------------
使用 Dev Cube 完成 IAP 功能的具体步骤,请参阅 `DevCube用户手册 <https://dev.bouffalolab.com/media/upload/doc/DevCube%E7%94%A8%E6%88%B7%E6%89%8B%E5%86%8Cv1.2.pdf>`_ <IAP程序下载>章节。

View File

@ -0,0 +1,2 @@
FATFS 文件系统读写
====================

View File

@ -0,0 +1,95 @@
LowPower 低功耗评估
=========================
简介
------------------------
博流系列芯片拥有丰富的低功耗特性,以适配不同的低功耗应用场合。为了方便用户快速的评测使用 bl 系列 MCU 低功耗性能 bl_mcu_sdk 提供了一套抽象的低功耗接口,将低功耗等级分为四个等级,分别为
1. Running : Running 为代码正常运行时的功耗,由客户应用代码决定功耗。
2. WFI WFI 模式,只关闭了 CPU 以节省功耗,当用户退出 WFI 模式的时候程序将会继续运行。
3. PDS : PDS 模式,关闭了芯片上大多数电源域,同时关闭了 CPU ,可以通过内部 RTC 进行唤醒,或者使用特定的唤醒引脚唤醒。
4. HBN : HBN 模式,关闭了芯片上绝大多数电源域,关闭了 CPU ,可以通过内部 RTC 进行唤醒,或者使用特定的唤醒引脚唤醒。
如下表所示
+------------+------------+------------+---------------------+
|模式 |参考电流 |对应基础模式|唤醒源 |
+============+============+============+=====================+
|running |6.28 mA |run | |
+------------+------------+------------+---------------------+
|WFI |5.14 mA |WFI |任意中断 |
+------------+------------+------------+---------------------+
|PDS |10 uA |PDS 31 |内部RTC/引脚中断 |
+------------+------------+------------+---------------------+
|HBN |1 uA |HBN 1 |内部RTC/引脚中断 |
+------------+------------+------------+---------------------+
bl_mcu_sdk 提供了一个简单的低功耗参考示例 (bl_mcu_sdk Examples/power/powerTest/) ,旨在帮助用户快速评估低功耗功能,如果需要进一步适配自身的低功耗场景,采取不同的低功耗策略,请查阅相关 datasheet 或者寻找 Boufflao Lab 的技术支持。
上表中的参考电流是通过示例固件测试得出的。符合 bl70x 系列 MCU 的 spec 的描述, run wfi pds hbn 四种等级的定义简化了原先的 hbn level以及 pds level的设定。
见 bl702_bl704_bl706_DS_EN_Combo_1.9.pdf page 28
.. figure:: img/powerTable.png
**低功耗示例测试方法**
------------------------
**编译低功耗示例代码**
^^^^^^^^^^^^^^^^^^^^^^^^
在工程目录下键入 ``make APP=lowpower_test SUPPORT_SHELL=y BOARD=bl706_lp`` 完成低功耗示例 bl706 的编译。或者直接使用CDK工程完成编译下载
您可以参考本文档《快速开发指南》来获取更多编译烧写的信息。
当编译并烧写成功后连接串口到电脑端并复位芯片Xshell 会出现如下图所示的页面。
.. figure:: img/xShell页面.png
**准备低功耗测试所需的硬件环境**
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- 可以串联电流表到电源端的电路板
- 电流表
- 一台 PC 主机(运行 Windows 或者 Linux 系统)
- TTL转USB
如下图所示,将电流表串联进入 bl706 模组的供电线路通过PC端的串口调试助手软件下发不同的低功耗指令使得 bl706 进入对应的低功耗模式
观察电流表示值,完成评估。
.. figure:: img/低功耗示意图.png
**使用Xshell开始评估低功耗性能**
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
用户可以通过在 Xshell输入下述指令进入对应的低功耗模式。
``run``
- 复位芯片之后默认进入run模式没有进入任何低功耗模式芯片实际在运行 while(1); 语句。
``wfi``
- 进入wfi模式后面不加任何参数进入之后关闭CPU降低功耗
- 进入wfi模式后任何中断会唤醒例如uart中断。在Xshell中敲击回车会触发 bl706 UART RX中断因此可以通过此方法唤醒wfi低功耗模式。
``pds sleepTim``
- pds 可以选择带一个 sleepTim 的参数,决定其内部 RTC 唤醒时间。如果指令不带此参数,那么默认不使用 RTC 内部唤醒,目前的固件仅支持上电复位唤醒。
- 如果指令包含 sleepTim 参数pds 将会在sleepTim * clock_period 的时刻被唤醒,表现为复位芯片,重新打印起始报文。
- 进入低功耗模式后RTC的时钟是32K ,因此 sleepTim 为32768时表现为睡眠 1S 后唤醒。
``hbn sleepTim``
- hbn 可以选择带一个 sleepTim 的参数决定其内部RTC唤醒时间。如果指令不带此参数那么默认不使用 RTC 内部唤醒,目前的固件仅支持上电复位唤醒。
- 如果指令包含 sleepTim 参数hbn 将会在 sleepTim * clock_period 的时刻被唤醒,表现为复位芯片,重新打印起始报文。
- 进入低功耗模式后RTC的时钟是32K ,因此 sleepTim 为32768时表现为睡眠1S 后唤醒。

View File

@ -0,0 +1,32 @@
SHELL 命令行调试
====================
为方便用户使用 pc 或者其他控制器对开发板进行功能的调试(非仿真器调试),这里提供了 shell 命令行组件,类似于在 linux 下进行命令行操作。用户在 PC 端或者其他控制端进行命令的发送通过串口、usb、以太网、蓝牙、wifi等方式将数据发送给开发板的 shell 中shell 会读取接收的命令进行解析并对已经注册的内部函数扫描,扫描到与之匹配的函数以后,执行匹配的函数,并实时返回传入的键值和函数执行的结果给 pc or 控制端。其中需要注意,控制器端需要发送标准键盘的键值。
本 demo 将演示如何使用 **shell** 通过串口进行命令行调试。
准备工具
-----------------------
- pc控制端使用串口终端软件xshell或者mobaxterm
- 连接介质usb转串口 or 网络 or usb
软件实现
-------------------------
串口中使用 SHELL
^^^^^^^^^^^^^^^^^^^^
BLE 中使用 SHELL
^^^^^^^^^^^^^^^^^^^^
以太网中使用 SHELL
^^^^^^^^^^^^^^^^^^^^
SHELL 命令注册
^^^^^^^^^^^^^^^^^^^^
编译和烧录
-----------------------------
实验现象
-----------------------------

View File

@ -0,0 +1,143 @@
ADC - 按键检测电压
====================
本demo基于ADC使用按键的方式检测外部输入引脚的电压值。
硬件连接
-----------------------------
本demo基于BL706_AVB开发板:
::
GPIO function GPIO pin
----------------------------------
ADC CH8 <--> GPIO18
软件实现
-----------------------------
- 软件代码见 ``examples/adc/adc_key``
- ``ADC`` 设备的时钟源由板级描述文件 ``bsp/board/bl706_iot/clock_config.h`` 来配置
.. code-block:: C
:linenos:
#define BSP_ADC_CLOCK_SOURCE ROOT_CLOCK_SOURCE_XCLK
#define BSP_ADC_CLOCK_DIV 0
- ``ADC`` 设备的复用引脚由板级描述文件 ``bsp/board/bl706_iot/pinmux_config.h`` 来配置
.. code-block:: C
:linenos:
#define CONFIG_GPIO18_FUNC GPIO_FUN_ADC
- ``ADC`` 设备配置由板级描述文件 ``bsp/board/bl706_iot/peripheral_config.h`` 来配置
.. code-block:: C
:linenos:
#define BSP_USING_ADC0
#if defined(BSP_USING_ADC0)
#ifndef ADC0_CONFIG
#define ADC0_CONFIG \
{ \
.clk_div = ADC_CLOCK_DIV_32,\
.vref = ADC_VREF_3P2V,\
.continuous_conv_mode = DISABLE,\
.differential_mode = DISABLE,\
.data_width = ADC_DATA_WIDTH_16B_WITH_256_AVERAGE,\
.fifo_threshold = ADC_FIFO_THRESHOLD_1BYTE,\
.gain = ADC_GAIN_1\
}
#endif
#endif
.. code-block:: C
:linenos:
adc_channel_cfg_t adc_channel_cfg;
adc_channel_cfg.pos_channel = posChList;
adc_channel_cfg.neg_channel = negChList;
adc_register(ADC0_INDEX, "adc_key", DEVICE_OFLAG_STREAM_RX);
adc_key = device_find("adc_key");
if(adc_key)
{
ADC_DEV(adc_key)->continuous_conv_mode = ENABLE;
device_open(adc_key, DEVICE_OFLAG_STREAM_RX);
device_control(adc_key,DEVICE_CTRL_ADC_CHANNEL_CONFIG,&adc_channel_cfg);
}else{
MSG("device open failed\r\n");
}
adc_channel_start(adc_key);
- 首先调用 ``adc_register`` 函数注册 ``adc_key`` 设备当前注册为ADC0
- 然后通过 ``find`` 函数找到设备对应的句柄,保存于 ``adc_key`` 句柄中
- 然后使用 ``device_open`` 以轮询模式来打开 ``adc_key`` 设备,调用 ``device_control`` 完成ADC相关的配置
- 最后调用 ``adc_channel_start`` 启用ADC的转换
.. code-block:: C
:linenos:
device_read(adc_key,0,(void *)&result_val,1);
keyValue = get_adc_key_value(result_val.volt * 1000);
if( keyValue!=KEY_NO_VALUE){
MSG("key %d pressed\r\n",keyValue);
MSG("result_val.volt: %0.2f mv\n", (result_val.volt * 1000));
}
- 调用 ``device_read`` 读取 ``adc_key`` 设备信息保存到 ``result_val`` 结构体中
- 调用 ``get_adc_key_value`` 函数获取当前的键值和电压值
编译和烧录
-----------------------------
- **CDK工具编译**
打开项目中提供的工程文件adc_key.cdkproj
参照 :ref:`windows_cdk_quick_start` 的步骤编译下载即可
- **命令行编译**
.. code-block:: bash
:linenos:
$ cd <sdk_path>/bl_mcu_sdk
$ make BOARD=bl706_avb APP=adc_key
- **烧录**
详见 :ref:`bl_dev_cube`
实验现象
-----------------------------
本实验依次按下开发板上的SW1 ~ SW5会得到不同的电压值:
- key 0: 0V左右
- key 1: 0.1V左右
- key 2: 0.2V左右
- key 3: 0.3V左右
- key 4: 0.43V左右
实际运行结果如下图所示:
.. figure:: img/adc_key_result.png
见视频展示:
.. raw:: html
<iframe src="//player.bilibili.com/player.html?aid=887712205&bvid=BV1xK4y1P7ur&cid=330261457&page=5" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true"> </iframe>

View File

@ -0,0 +1,75 @@
GPIO 输出 - 流水灯
====================
本demo基于GPIO外设的输出模式编写。
硬件连接
-----------------------------
本 demo 基于BL706_IOT开发板连接方式如下
::
GPIO function GPIO pin
----------------------------------
D0 <--> GPIO22
D1 <--> GPIO29
D2 <--> GPIO30
D3 <--> GPIO31
.. figure:: img/blink_breath_sch.png
:alt:
软件实现
-----------------------------
- 软件代码见 ``examples/gpio/gpio_blink``
.. code-block:: C
:linenos:
gpio_set_mode(GPIO_PIN_22, GPIO_OUTPUT_PP_MODE);
gpio_set_mode(GPIO_PIN_29, GPIO_OUTPUT_PP_MODE);
gpio_set_mode(GPIO_PIN_30, GPIO_OUTPUT_PP_MODE);
gpio_set_mode(GPIO_PIN_31, GPIO_OUTPUT_PP_MODE);
- 使用上述代码将 ``GPIO22`` ``GPIO29`` ``GPIO30`` ``GPIO31`` 配置为输出上拉模式。
.. code-block:: C
:linenos:
gpio_write(GPIO_PIN_22, 0);
- 使用上述代码修改输出的电平值。
编译和烧录
-----------------------------
- **CDK 编译**
打开项目中提供的工程文件gpio_blink.cdkproj
参照 :ref:`windows_cdk_quick_start` 的步骤编译下载即可
- **命令行编译**
.. code-block:: bash
:linenos:
$ cd <sdk_path>/bl_mcu_sdk
$ make BOARD=bl706_iot APP=gpio_blink
- **烧录**
详见 :ref:`bl_dev_cube`
实验现象
-----------------------------
见视频展示:
.. raw:: html
<iframe src="//player.bilibili.com/player.html?aid=887712205&bvid=BV1xK4y1P7ur&cid=326226616&page=3" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true"> </iframe>

View File

@ -0,0 +1,110 @@
PWM - 呼吸灯
====================
本demo基于PWM外设轮询模式编写。
硬件连接
-----------------------------
本 demo 基于BL706_IOT开发板连接方式如下
::
GPIO function GPIO pin
----------------------------------
PWM_CH2 <--> GPIO22
.. figure:: img/blink_breath_sch.png
:alt:
软件实现
-----------------------------
- 软件代码见 ``examples/pwm/pwm_breath_led``
- ``PWM`` 复用引脚由板级描述文件 ``bsp/board/bl706_iot/pinmux_config.h`` 来配置
.. code-block:: C
:linenos:
#define CONFIG_GPIO22_FUNC GPIO_FUN_PWM
- ``PWM`` 设备配置由板级描述文件 ``bsp/board/bl706_iot/peripheral_config.h`` 来配置
.. code-block:: C
:linenos:
#define BSP_USING_PWM_CH2
#if defined(BSP_USING_PWM_CH2)
#ifndef PWM_CH2_CONFIG
#define PWM_CH2_CONFIG \
{ \
.ch = 2, \
.frequency = 1000000, \
.dutycycle = 0, \
.it_pulse_count = 0,\
}
#endif
#endif
.. code-block:: C
:linenos:
pwm_register(PWM_CH2_INDEX, "led_breath", DEVICE_OFLAG_RDWR);
struct device *led_breath = device_find("led_breath");
if (led_breath)
{
device_open(led_breath, DEVICE_OFLAG_STREAM_TX);
pwm_channel_start(led_breath);
}
- 首先调用 ``pwm_register`` 函数注册 ``PWM`` 设备的一个通道,当前注册 ``PWM_CH2``
- 然后通过 ``find`` 函数找到设备对应的句柄,保存于 ``led_breath`` 句柄中
- 使用 ``device_open`` 以轮询模式来打开 ``led_breath`` 设备
.. code-block:: C
:linenos:
pwm_config_t pwm_cfg = {
1000000,
0,
};
device_control(led_breath, DEVICE_CTRL_CONFIG, &pwm_cfg);
- 使用 ``device_contorl`` 函数,配合 ``DEVICE_CTRL_CONFIG`` 指令可以修改当前PWM通道的频率和占空比。
编译和烧录
-----------------------------
- **CDK 编译**
打开项目中提供的工程文件pwm_breath_led.cdkproj
参照 :ref:`windows_cdk_quick_start` 的步骤编译下载即可
- **命令行编译**
.. code-block:: bash
:linenos:
$ cd <sdk_path>/bl_mcu_sdk
$ make BOARD=bl706_iot APP=pwm_breath_led
- **烧录**
详见 :ref:`bl_dev_cube`
实验现象
-----------------------------
见视频展示:
.. raw:: html
<iframe src="//player.bilibili.com/player.html?aid=887712205&bvid=BV1xK4y1P7ur&cid=326227924&page=4" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true"> </iframe>

View File

@ -0,0 +1,64 @@
GPIO 中断 - 按键检测
====================
本demo基于GPIO外设外部中断模式编写。
硬件连接
-----------------------------
本 demo 基于BL706_IOT开发板自行添加按键电路连接方式如下
::
GPIO function GPIO pin
----------------------------------
SW1 <--> GPIO11
.. figure:: img/button_sch.png
:alt:
软件实现
-----------------------------
- 软件代码见 ``examples/gpio/gpio_int``
.. code-block:: C
:linenos:
static void gpio11_int_callback(uint32_t pin)
{
MSG("gpio rising trigger !\r\n");
}
gpio_set_mode(GPIO_PIN_11,GPIO_SYNC_RISING_TRIGER_INT_MODE);
gpio_attach_irq(GPIO_PIN_11,gpio11_int_callback);
gpio_irq_enable(GPIO_PIN_11,ENABLE);
- 使用上述代码将 ``GPIO11`` 配置为GPIO上升沿中断触发模式并注册中断回调函数。
编译和烧录
-----------------------------
- **CDK 编译**
打开项目中提供的工程文件gpio_int.cdkproj
参照 :ref:`windows_cdk_quick_start` 的步骤编译下载即可
- **命令行编译**
.. code-block:: bash
:linenos:
$ cd <sdk_path>/bl_mcu_sdk
$ make BOARD=bl706_iot APP=gpio_int
- **烧录**
详见 :ref:`bl_dev_cube`
实验现象
-----------------------------
当按键按下时,串口会打印 ``"gpio rising trigger !"``

View File

@ -0,0 +1,113 @@
DMA - RAM间数据搬运
====================
本demo基于DMA方向为memory to memory 模式,进行数据的搬运。
硬件连接
-----------------------------
软件实现
-----------------------------
- 软件代码见 ``examples/dma/dma_m2m``
- ``DMA`` 设备配置由板级描述文件 ``bsp/board/bl706_iot/peripheral_config.h`` 来配置
.. code-block:: C
:linenos:
#define BSP_USING_DMA0_CH0
#if defined(BSP_USING_DMA0_CH0)
#ifndef DMA0_CH0_CONFIG
#define DMA0_CH0_CONFIG \
{ \
.id = 0, \
.ch = 0,\
.direction = DMA_MEMORY_TO_MEMORY,\
.transfer_mode = DMA_LLI_ONCE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_NONE, \
.src_width = DMA_TRANSFER_WIDTH_32BIT , \
.dst_width = DMA_TRANSFER_WIDTH_32BIT , \
}
#endif
#endif
.. code-block:: C
:linenos:
dma_register(DMA0_CH0_INDEX, "DMA", DEVICE_OFLAG_RDWR);
struct device *dma = device_find("DMA");
if (dma)
{
device_open(dma, 0);
device_set_callback(dma, dma_transfer_done);
device_control(dma, DEVICE_CTRL_SET_INT, NULL);
}
- 首先调用 ``dma_register`` 函数注册 ``DMA`` 设备的一个通道,当前注册 ``DMA_CH0``
- 然后通过 ``find`` 函数找到设备对应的句柄,保存于 ``dma`` 句柄中
- 最后使用 ``device_open`` 以默认模式来打开 ``dma`` 设备,调用 ``device_set_callback`` 注册一个dma通道0中断回调函数调用 ``device_control`` 开启dma传输完成中断
.. code-block:: C
:linenos:
dma_reload(dma,(uint32_t)dma_src_buffer,(uint32_t)dma_dst_buffer,8000);
dma_channel_start(dma);
- 调用 ``dma_reload`` 函数对dma 通道0的配置进行补充``DMA0_CH0_CONFIG`` 中已经补充了一部分配置,这边主要补充源数据地址和目标数据地址以及传输总长度
- 调用 ``dma_channel_start`` 开启dma传输
.. code-block:: C
:linenos:
void dma_transfer_done(struct device *dev, void *args, uint32_t size, uint32_t state)
{
uint32_t index=0;
if(!state)
{
MSG("dma transfer task done\r\n");
for(index=0;index<8000;index++){
if(dma_dst_buffer[index]!=0xff){
MSG("dma transfer error\r\n");
}
}
MSG("dma transfer success\r\n");
}
}
- 在中断函数中判断数据传输是否正确
编译和烧录
-----------------------------
- **CDK 编译**
打开项目中提供的工程文件dma_m2m.cdkproj
参照 :ref:`windows_cdk_quick_start` 的步骤编译下载即可
- **命令行编译**
.. code-block:: bash
:linenos:
$ cd <sdk_path>/bl_mcu_sdk
$ make BOARD=bl706_iot APP=dma_m2m
- **烧录**
详见 :ref:`bl_dev_cube`
实验现象
-----------------------------
``dma_src_buffer`` 数组中的数据通过DMA 通道0 以源32位宽、目标32位宽传输到 ``dma_dst_buffer`` 数组中,数据传输完成并完整,串口打印 ``dma transfer success``。

View File

@ -0,0 +1,117 @@
I2C - AT24CXX 读写
====================
硬件连接
-----------------------------
本 demo 基于BL706_IOT开发板自行添加 AT24CXX 电路,连接方式如下
::
GPIO function GPIO pin
----------------------------------
I2C_SCL <--> GPIO11
I2C_SDA <--> GPIO16
软件实现
-----------------------------
- 软件代码见 ``examples/i2c/i2c_at24cxx``
- ``I2C`` 设备的时钟源由板级描述文件 ``bsp/board/bl706_iot/clock_config.h`` 来配置
.. code-block:: C
:linenos:
#define BSP_I2C_CLOCK_SOURCE ROOT_CLOCK_SOURCE_BCLK
#define BSP_I2C_CLOCK_DIV 0
- ``I2C`` 设备的复用引脚由板级描述文件 ``bsp/board/bl706_iot/pinmux_config.h`` 来配置
.. code-block:: C
:linenos:
#define CONFIG_GPIO11_FUNC GPIO_FUN_I2C
#define CONFIG_GPIO16_FUNC GPIO_FUN_I2C
- ``I2C`` 设备配置由板级描述文件 ``bsp/board/bl706_iot/peripheral_config.h`` 来配置
.. code-block:: C
:linenos:
#define BSP_USING_I2C0
#if defined(BSP_USING_I2C0)
#ifndef I2C0_CONFIG
#define I2C0_CONFIG \
{ \
.id = 0, \
.mode = I2C_HW_MODE,\
.phase = 15, \
}
#endif
#endif
.. code-block:: C
:linenos:
i2c_register(I2C0_INDEX, "i2c", DEVICE_OFLAG_RDWR);
struct device *i2c0 = device_find("i2c");
if (i2c0)
{
MSG("device find success\r\n");
device_open(i2c0, 0);
}
- 首先调用 ``i2c_register`` 函数注册 ``I2C`` 设备,当前注册 ``I2C0``
- 然后通过 ``find`` 函数找到设备对应的句柄,保存于 ``i2c0`` 句柄中
- 最后使用 ``device_open`` 以默认模式来打开 ``I2C0`` 设备
.. code-block:: C
:linenos:
i2c_msg_t msg[2];
uint8_t buf[8] = {0};
msg[0].buf = buf;
msg[0].flags = SUB_ADDR_1BYTE | I2C_WR;
msg[0].len = 8;
msg[0].slaveaddr = 0x50;
msg[0].subaddr = 0x00;
msg[1].buf = buf;
msg[1].flags = SUB_ADDR_1BYTE | I2C_RD;
msg[1].len = 8;
msg[1].slaveaddr = 0x50;
msg[1].subaddr = 0x00;
if (i2c_transfer(i2c0, &msg[0], 2) == 0)
MSG("\r\n read:%0x\r\n", msg[1].buf[0] << 8 | msg[1].buf[1]);
- 调用 ``i2c_transfer`` 传输两个 ``msg``,一个 ``msg`` 代表向 eeprom 写入8字节数据一个 ``msg`` 代表从 eeprom 读取8字节数据
编译和烧录
-----------------------------
- **CDK 编译**
打开项目中提供的工程文件i2c_at24cxx.cdkproj
参照 :ref:`windows_cdk_quick_start` 的步骤编译下载即可
- **命令行编译**
.. code-block:: bash
:linenos:
$ cd <sdk_path>/bl_mcu_sdk
$ make BOARD=bl706_iot APP=i2c_at24cxx
- **烧录**
详见 :ref:`bl_dev_cube`
实验现象
-----------------------------

View File

@ -0,0 +1,55 @@
MTIMER - 内核定时器
====================
本demo基于 risc-v 内核自带的一个64位定时器MTIMER编写。MTIMER最大可以定时500年本demo可以为后面os tick提供参考。
硬件连接
-----------------------------
软件实现
-----------------------------
- 软件代码见 ``examples/systick``
- ``mtimer`` 时钟默认经过分频以后为 1M方便后面使用减少计算时间。
.. code-block:: C
:linenos:
void systick_isr()
{
static uint32_t tick=0;
tick++;
MSG("tick:%d\r\n",tick);
}
bflb_platform_set_alarm_time(1000000,systick_isr);
- 使用上述代码设置mtimer定时时间为1s并且注册中断回调函数。
编译和烧录
-----------------------------
- **CDK 编译**
打开项目中提供的工程文件systick.cdkproj
参照 :ref:`windows_cdk_quick_start` 的步骤编译下载即可
- **命令行编译**
.. code-block:: bash
:linenos:
$ cd <sdk_path>/bl_mcu_sdk
$ make BOARD=bl706_iot APP=systick
- **烧录**
详见 :ref:`bl_dev_cube`
实验现象
-----------------------------
``tick`` 值每秒自增1并通过串口打印。

View File

@ -0,0 +1,145 @@
SPI - TFT LCD 显示
====================
硬件连接
-----------------------------
本 demo 基于BL706_AVB开发板**其中 MISO 和MOSI 默认进行了调换**,连接方式如下
::
GPIO function GPIO pin
----------------------------------
LCD_CS <--> GPIO10
LCD_DC <--> GPIO22
SPI_SCK <--> GPIO19
SPI_MISO <--> GPIO20
SPI_MOSI <--> GPIO21
软件实现
-----------------------------
- 软件代码见 ``examples/spi/spi_lcd``
- ``SPI`` 设备的时钟源由板级描述文件 ``bsp/board/bl706_avb/clock_config.h`` 来配置
.. code-block:: C
:linenos:
#define BSP_SPI_CLOCK_SOURCE ROOT_CLOCK_SOURCE_BCLK
#define BSP_SPI_CLOCK_DIV 0
- ``SPI`` 设备的复用引脚由板级描述文件 ``bsp/board/bl706_avb/pinmux_config.h`` 来配置
.. code-block:: C
:linenos:
#define CONFIG_GPIO19_FUNC GPIO_FUN_SPI
#define CONFIG_GPIO20_FUNC GPIO_FUN_SPI
#define CONFIG_GPIO21_FUNC GPIO_FUN_SPI
- ``SPI`` 设备配置由板级描述文件 ``bsp/board/bl706_avb/peripheral_config.h`` 来配置
.. code-block:: C
:linenos:
#define BSP_USING_SPI0
#if defined(BSP_USING_SPI0)
#ifndef SPI0_CONFIG
#define SPI0_CONFIG \
{ \
.id = 0, \
.clk = 36000000,\
.mode = SPI_MASTER_MODE, \
.direction = SPI_MSB_BYTE0_DIRECTION_FIRST, \
.clk_polaraity = SPI_POLARITY_LOW, \
.clk_phase = SPI_PHASE_1EDGE, \
.datasize = SPI_DATASIZE_8BIT, \
.fifo_threshold = 4, \
}
#endif
#endif
.. code-block:: C
:linenos:
gpio_set_mode(LCD_CS_PIN,GPIO_OUTPUT_MODE);
gpio_set_mode(LCD_DC_PIN,GPIO_OUTPUT_MODE);
gpio_write(LCD_CS_PIN,1); //CS1
gpio_write(LCD_DC_PIN,1); //DC
spi0 = device_find("spi0");
if(spi0)
{
device_close(spi0);
}
else{
spi_register(SPI0_INDEX,"spi0",DEVICE_OFLAG_RDWR);
spi0 = device_find("spi0");
}
if(spi0)
{
device_open(spi0,DEVICE_OFLAG_STREAM_TX|DEVICE_OFLAG_STREAM_RX);
}
- 配置 ``LCD_CS`` 和 ``LCD_DC`` 引脚为输出模式并拉高
- 调用 ``spi_register`` 函数注册 ``SPI`` 设备,当前注册 ``SPI0``
- 然后通过 ``find`` 函数找到设备对应的句柄,保存于 ``spi0`` 句柄中
- 最后使用 ``device_open`` 以轮询发送模式来打开 ``spi0`` 设备
.. code-block:: C
:linenos:
void LCD_WR_Byte(uint8_t data)
{
CS1_LOW;
DC_HIGH;
spi_transmit(spi0,&data,1,SPI_TRANSFER_TYPE_8BIT);
CS1_HIGH;
}
void LCD_WR_HalfWord(uint16_t data)
{
CS1_LOW;
DC_HIGH;
spi_transmit(spi0,&data,1,SPI_TRANSFER_TYPE_16BIT);
CS1_HIGH;
}
void LCD_WR_Word(uint32_t data)
{
CS1_LOW;
DC_HIGH;
spi_transmit(spi0,&data,1,SPI_TRANSFER_TYPE_32BIT);
CS1_HIGH;
}
- 为 LCD 显示驱动提供接口
编译和烧录
-----------------------------
- **CDK 编译**
打开项目中提供的工程文件spi_lcd.cdkproj
参照 :ref:`windows_cdk_quick_start` 的步骤编译下载即可
- **命令行编译**
.. code-block:: bash
:linenos:
$ cd <sdk_path>/bl_mcu_sdk
$ make BOARD=bl706_avb APP=spi_lcd
- **烧录**
详见 :ref:`bl_dev_cube`
实验现象
-----------------------------

View File

@ -0,0 +1,151 @@
UART - 数据自收发
====================
本demo基于 UART 外设轮询发送、接收FIFO中断模式编写。
硬件连接
-----------------------------
本 demo 基于BL706_IOT开发板连接方式如下
::
GPIO function GPIO pin
----------------------------------
UART0_TX <--> GPIO14
UART0_RX <--> GPIO15
软件实现
-----------------------------
- 软件代码见 ``examples/uart/uart_echo``
- ``UART`` 设备的时钟源由板级描述文件 ``bsp/board/bl706_iot/clock_config.h`` 来配置
.. code-block:: C
:linenos:
#define BSP_UART_CLOCK_SOURCE ROOT_CLOCK_SOURCE_PLL_96M
#define BSP_UART_CLOCK_DIV 0
- ``UART`` 设备的复用引脚由板级描述文件 ``bsp/board/bl706_iot/pinmux_config.h`` 来配置
.. code-block:: C
:linenos:
#define CONFIG_GPIO14_FUNC GPIO_FUN_UART0_TX
#define CONFIG_GPIO15_FUNC GPIO_FUN_UART0_RX
- ``UART`` 设备配置由板级描述文件 ``bsp/board/bl706_iot/peripheral_config.h`` 来配置
.. code-block:: C
:linenos:
#define BSP_USING_UART0
#if defined(BSP_USING_UART0)
#ifndef UART0_CONFIG
#define UART0_CONFIG \
{ \
.id = 0, \
.baudrate = 2000000,\
.databits = UART_DATA_LEN_8, \
.stopbits = UART_STOP_ONE, \
.parity = UART_PAR_NONE, \
.fifo_threshold = 1, \
}
#endif
#endif
.. code-block:: C
:linenos:
bflb_platform_init();
- 在 ``bflb_platform_init`` 函数中,我们已经注册并且打开了一个调试用的串口设备,给用户实现一个 ``MSG`` 的基本功能用作打印输出报文。具体实现如下
.. code-block:: C
:linenos:
uart_register(board_get_debug_uart_index(), "debug_log", DEVICE_OFLAG_RDWR);
struct device *uart = device_find("debug_log");
if (uart)
{
device_open(uart, DEVICE_OFLAG_STREAM_TX | DEVICE_OFLAG_INT_RX);
device_set_callback(uart, uart_iqr_callback);
device_control(uart, DEVICE_CTRL_SET_INT, (void *)(UART_RX_FIFO_IT));
}
- 首先调用 ``uart_register`` 函数注册 ``UART`` 设备,当前注册 ``UART0``
- 然后通过 ``find`` 函数找到设备对应的句柄,保存于 ``uart`` 句柄中
- 最后使用 ``device_open`` 以轮询发送和中断接收来打开 ``uart`` 设备,调用 ``device_set_callback`` 注册一个 ``UART0`` 中断回调函数,调用 ``device_control`` 开启 ``UART RX FIFO`` 中断
.. code-block:: C
:linenos:
if (uart)
{
device_set_callback(uart, uart_irq_callback);
device_control(uart, DEVICE_CTRL_SET_INT, (void *)(UART_RX_FIFO_IT|UART_RTO_IT));
}
- 通过 ``device_set_callback`` 函数,注册用户指定的中断服务函数。通过 ``device_control`` 函数打开 ``RX FIFO`` 和 ``RTO`` 中断
.. code-block:: C
:linenos:
void uart_irq_callback(struct device *dev, void *args, uint32_t size, uint32_t state)
{
if (state == UART_EVENT_RX_FIFO)
{
device_write(dev,0,(uint8_t *)args,size);
}
else if (state == UART_EVENT_RTO)
{
device_write(dev,0,(uint8_t *)args,size);
}
}
- 此函数是示例的中断服务函数,作用是将接受到的数据原封不动的发送出去。
- ``state`` 会返回 ``UART`` 设备的中断类型
- ``args`` 包含了返回数据指针
- ``size`` 包含返回数据的长度
- ``dev`` 为中断的 ``uart`` 设备句柄
- 当中断产生,将会调用 ``device_write`` 函数将接受到的数据发送回去。
编译和烧录
-----------------------------
- **CDK 编译**
打开项目中提供的工程文件uart_echo.cdkproj
参照 :ref:`windows_cdk_quick_start` 的步骤编译下载即可
- **命令行编译**
.. code-block:: bash
:linenos:
$ cd <sdk_path>/bl_mcu_sdk
$ make BOARD=bl706_iot APP=uart_echo
- **烧录**
详见 :ref:`bl_dev_cube`
实验现象
-----------------------------
见视频展示:
.. raw:: html
<iframe src="//player.bilibili.com/player.html?aid=887712205&bvid=BV1xK4y1P7ur&cid=330261457&page=5" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true"> </iframe>

View File

@ -1,6 +1,6 @@
var DOCUMENTATION_OPTIONS = {
URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
VERSION: '0.1',
VERSION: '0.2',
LANGUAGE: 'zh_CN',
COLLAPSE_INDEX: false,
BUILDER: 'html',

Some files were not shown because too many files have changed in this diff Show More