mirror of
https://github.com/Fishwaldo/bl_mcu_sdk.git
synced 2025-07-12 07:48:42 +00:00
[doc] update demo rst
This commit is contained in:
parent
dd161b698b
commit
24d03e890b
42 changed files with 2148 additions and 691 deletions
|
@ -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`
|
||||
|
||||
实验现象
|
||||
-----------------------------
|
|
@ -1,10 +0,0 @@
|
|||
=======================
|
||||
Components
|
||||
=======================
|
||||
|
||||
组件例程如果没有特殊说明,则表示适用于博流所有系列芯片。
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
FreeRTOS <freertos>
|
137
docs/source/samples/peripherals/adc/adc_dma.rst
Normal file
137
docs/source/samples/peripherals/adc/adc_dma.rst
Normal file
|
@ -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,通道号以及通道对应的电压值。
|
97
docs/source/samples/peripherals/adc/adc_int.rst
Normal file
97
docs/source/samples/peripherals/adc/adc_int.rst
Normal file
|
@ -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,通道号以及通道对应的电压值。
|
|
@ -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`
|
||||
|
||||
实验现象
|
||||
-----------------------------
|
||||
-----------------------------
|
||||
打印 raw data,通道号以及通道对应的电压值。
|
90
docs/source/samples/peripherals/adc/adc_poll_diff_mode.rst
Normal file
90
docs/source/samples/peripherals/adc/adc_poll_diff_mode.rst
Normal file
|
@ -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,正极和负极通道号以及对应的电压差值。
|
75
docs/source/samples/peripherals/adc/adc_tsen.rst
Normal file
75
docs/source/samples/peripherals/adc/adc_tsen.rst
Normal file
|
@ -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`
|
||||
|
||||
实验现象
|
||||
-----------------------------
|
||||
打印计算得到的环境温度。
|
86
docs/source/samples/peripherals/adc/adc_vbat.rst
Normal file
86
docs/source/samples/peripherals/adc/adc_vbat.rst
Normal file
|
@ -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 的电压值。
|
|
@ -5,4 +5,93 @@ ADC
|
|||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
ADC - poll <adc_poll>
|
||||
ADC - poll <adc_poll>
|
||||
ADC - dma <adc_dma>
|
||||
ADC - interrupt <adc_int>
|
||||
ADC - poll_diff_mode <adc_poll_diff_mode>
|
||||
ADC - temperature sensor <adc_tsen>
|
||||
ADC - vbat <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 |
|
||||
+----------+-----------+---------------------------+
|
||||
|
|
100
docs/source/samples/peripherals/dac/dac_dma.rst
Normal file
100
docs/source/samples/peripherals/dac/dac_dma.rst
Normal file
|
@ -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 输出正弦波。
|
|
@ -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`
|
||||
|
||||
实验现象
|
||||
-----------------------------
|
||||
|
||||
|
|
|
@ -5,4 +5,28 @@ DAC
|
|||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
DAC - poll <dac_polling>
|
||||
DAC - poll <dac_polling>
|
||||
DAC - dma <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 |
|
||||
+----------+-----------+-----------+---------------------------+
|
58
docs/source/samples/peripherals/gpio/gpio_input_output.rst
Normal file
58
docs/source/samples/peripherals/gpio/gpio_input_output.rst
Normal file
|
@ -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 引脚电平。
|
52
docs/source/samples/peripherals/gpio/gpio_interrupt.rst
Normal file
52
docs/source/samples/peripherals/gpio/gpio_interrupt.rst
Normal file
|
@ -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 引脚电平拉低,进入中断并打印中断次数。
|
22
docs/source/samples/peripherals/gpio/index.rst
Normal file
22
docs/source/samples/peripherals/gpio/index.rst
Normal file
|
@ -0,0 +1,22 @@
|
|||
====
|
||||
GPIO
|
||||
====
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
GPIO - input/output <gpio_input_output>
|
||||
GPIO - interrupt <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默认为晶振引脚) |
|
||||
+----------------------+--------------------------------------------------------------------------------+
|
92
docs/source/samples/peripherals/i2c/i2c_10_bit.rst
Normal file
92
docs/source/samples/peripherals/i2c/i2c_10_bit.rst
Normal file
|
@ -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 数据。
|
120
docs/source/samples/peripherals/i2c/i2c_eeprom.rst
Normal file
120
docs/source/samples/peripherals/i2c/i2c_eeprom.rst
Normal file
|
@ -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”。
|
202
docs/source/samples/peripherals/i2c/i2c_eeprom_dma.rst
Normal file
202
docs/source/samples/peripherals/i2c/i2c_eeprom_dma.rst
Normal file
|
@ -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”。
|
210
docs/source/samples/peripherals/i2c/i2c_eeprom_interrupt.rst
Normal file
210
docs/source/samples/peripherals/i2c/i2c_eeprom_interrupt.rst
Normal file
|
@ -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”。
|
34
docs/source/samples/peripherals/i2c/index.rst
Normal file
34
docs/source/samples/peripherals/i2c/index.rst
Normal file
|
@ -0,0 +1,34 @@
|
|||
====
|
||||
I2C
|
||||
====
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
I2C - 10-bit <i2c_10_bit>
|
||||
I2C - eeprom <i2c_eeprom>
|
||||
I2C - eeprom_dma <i2c_eeprom_dma>
|
||||
I2C - eeprom_interrupt <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 |
|
||||
+----------+-----------+---------------------------+
|
|
@ -9,4 +9,8 @@ Peripherals
|
|||
|
||||
ADC <adc/index>
|
||||
DAC <dac/index>
|
||||
GPIO <gpio/index>
|
||||
I2C <i2c/index>
|
||||
IR <ir/index>
|
||||
ISO11898 <iso11898/index>
|
||||
UART <uart/index>
|
||||
|
|
34
docs/source/samples/peripherals/ir/index.rst
Normal file
34
docs/source/samples/peripherals/ir/index.rst
Normal file
|
@ -0,0 +1,34 @@
|
|||
====
|
||||
IR
|
||||
====
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
IR - nec <ir_nec>
|
||||
IR - rc5 <ir_rc5>
|
||||
IR - swm <ir_swm>
|
||||
IR - tx_dma <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 | 支持 |
|
||||
+----------+-----------+---------------------------+
|
115
docs/source/samples/peripherals/ir/ir_nec.rst
Normal file
115
docs/source/samples/peripherals/ir/ir_nec.rst
Normal file
|
@ -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 按键,串口打印接收到的数据。
|
115
docs/source/samples/peripherals/ir/ir_rc5.rst
Normal file
115
docs/source/samples/peripherals/ir/ir_rc5.rst
Normal file
|
@ -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 按键,串口打印接收到的数据。
|
105
docs/source/samples/peripherals/ir/ir_swm.rst
Normal file
105
docs/source/samples/peripherals/ir/ir_swm.rst
Normal file
|
@ -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 按键,串口打印接收到的数据。
|
151
docs/source/samples/peripherals/ir/ir_tx_dma.rst
Normal file
151
docs/source/samples/peripherals/ir/ir_tx_dma.rst
Normal file
|
@ -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 按键,数据传输完成后,查看波形是否正确。
|
32
docs/source/samples/peripherals/iso11898/index.rst
Normal file
32
docs/source/samples/peripherals/iso11898/index.rst
Normal file
|
@ -0,0 +1,32 @@
|
|||
====
|
||||
ISO11898
|
||||
====
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
ISO11898 - filter <iso11898_filter>
|
||||
ISO11898 - selftest <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 |
|
||||
+----------+-----------+---------------------------+
|
|
@ -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 按键,串口打印接收到的数据。
|
|
@ -146,14 +146,8 @@ UART - dma
|
|||
编译和烧录
|
||||
-----------------------------
|
||||
|
||||
- **命令行编译**
|
||||
|
||||
参考 :ref:`linux_cmd` 或者 :ref:`windows_cmd`
|
||||
|
||||
- **烧录**
|
||||
|
||||
参考 :ref:`bl_dev_cube`
|
||||
|
||||
实验现象
|
||||
-----------------------------
|
||||
|
||||
|
|
|
@ -82,14 +82,8 @@ UART - poll
|
|||
编译和烧录
|
||||
-----------------------------
|
||||
|
||||
- **命令行编译**
|
||||
|
||||
参考 :ref:`linux_cmd` 或者 :ref:`windows_cmd`
|
||||
|
||||
- **烧录**
|
||||
|
||||
参考 :ref:`bl_dev_cube`
|
||||
|
||||
实验现象
|
||||
-----------------------------
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue