diff --git a/docs/development_guide_en/Makefile b/docs/development_guide_en/Makefile new file mode 100644 index 00000000..d0c3cbf1 --- /dev/null +++ b/docs/development_guide_en/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = source +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/development_guide_en/build/doctrees/api_reference/api_overview.doctree b/docs/development_guide_en/build/doctrees/api_reference/api_overview.doctree new file mode 100644 index 00000000..6b4a5674 Binary files /dev/null and b/docs/development_guide_en/build/doctrees/api_reference/api_overview.doctree differ diff --git a/docs/development_guide_en/build/doctrees/api_reference/bluetooth/api_ble.doctree b/docs/development_guide_en/build/doctrees/api_reference/bluetooth/api_ble.doctree new file mode 100644 index 00000000..769c050b Binary files /dev/null and b/docs/development_guide_en/build/doctrees/api_reference/bluetooth/api_ble.doctree differ diff --git a/docs/development_guide_en/build/doctrees/api_reference/peripheral/api_adc.doctree b/docs/development_guide_en/build/doctrees/api_reference/peripheral/api_adc.doctree new file mode 100644 index 00000000..e09d761b Binary files /dev/null and b/docs/development_guide_en/build/doctrees/api_reference/peripheral/api_adc.doctree differ diff --git a/docs/development_guide_en/build/doctrees/api_reference/peripheral/api_clock.doctree b/docs/development_guide_en/build/doctrees/api_reference/peripheral/api_clock.doctree new file mode 100644 index 00000000..0c2910b3 Binary files /dev/null and b/docs/development_guide_en/build/doctrees/api_reference/peripheral/api_clock.doctree differ diff --git a/docs/development_guide_en/build/doctrees/api_reference/peripheral/api_dac.doctree b/docs/development_guide_en/build/doctrees/api_reference/peripheral/api_dac.doctree new file mode 100644 index 00000000..68465f2a Binary files /dev/null and b/docs/development_guide_en/build/doctrees/api_reference/peripheral/api_dac.doctree differ diff --git a/docs/development_guide_en/build/doctrees/api_reference/peripheral/api_dma.doctree b/docs/development_guide_en/build/doctrees/api_reference/peripheral/api_dma.doctree new file mode 100644 index 00000000..9b7606d1 Binary files /dev/null and b/docs/development_guide_en/build/doctrees/api_reference/peripheral/api_dma.doctree differ diff --git a/docs/development_guide_en/build/doctrees/api_reference/peripheral/api_gpio.doctree b/docs/development_guide_en/build/doctrees/api_reference/peripheral/api_gpio.doctree new file mode 100644 index 00000000..36ee3f93 Binary files /dev/null and b/docs/development_guide_en/build/doctrees/api_reference/peripheral/api_gpio.doctree differ diff --git a/docs/development_guide_en/build/doctrees/api_reference/peripheral/api_i2c.doctree b/docs/development_guide_en/build/doctrees/api_reference/peripheral/api_i2c.doctree new file mode 100644 index 00000000..63cf9281 Binary files /dev/null and b/docs/development_guide_en/build/doctrees/api_reference/peripheral/api_i2c.doctree differ diff --git a/docs/development_guide_en/build/doctrees/api_reference/peripheral/api_pwm.doctree b/docs/development_guide_en/build/doctrees/api_reference/peripheral/api_pwm.doctree new file mode 100644 index 00000000..eb68cafb Binary files /dev/null and b/docs/development_guide_en/build/doctrees/api_reference/peripheral/api_pwm.doctree differ diff --git a/docs/development_guide_en/build/doctrees/api_reference/peripheral/api_spi.doctree b/docs/development_guide_en/build/doctrees/api_reference/peripheral/api_spi.doctree new file mode 100644 index 00000000..86dce922 Binary files /dev/null and b/docs/development_guide_en/build/doctrees/api_reference/peripheral/api_spi.doctree differ diff --git a/docs/development_guide_en/build/doctrees/api_reference/peripheral/api_timer.doctree b/docs/development_guide_en/build/doctrees/api_reference/peripheral/api_timer.doctree new file mode 100644 index 00000000..17f1b499 Binary files /dev/null and b/docs/development_guide_en/build/doctrees/api_reference/peripheral/api_timer.doctree differ diff --git a/docs/development_guide_en/build/doctrees/api_reference/peripheral/api_uart.doctree b/docs/development_guide_en/build/doctrees/api_reference/peripheral/api_uart.doctree new file mode 100644 index 00000000..e0684279 Binary files /dev/null and b/docs/development_guide_en/build/doctrees/api_reference/peripheral/api_uart.doctree differ diff --git a/docs/development_guide_en/build/doctrees/api_reference/peripheral/index.doctree b/docs/development_guide_en/build/doctrees/api_reference/peripheral/index.doctree new file mode 100644 index 00000000..d3768f2b Binary files /dev/null and b/docs/development_guide_en/build/doctrees/api_reference/peripheral/index.doctree differ diff --git a/docs/development_guide_en/build/doctrees/environment.pickle b/docs/development_guide_en/build/doctrees/environment.pickle new file mode 100644 index 00000000..b76562c4 Binary files /dev/null and b/docs/development_guide_en/build/doctrees/environment.pickle differ diff --git a/docs/development_guide_en/build/doctrees/get_started/Linux_quick_start_ubuntu.doctree b/docs/development_guide_en/build/doctrees/get_started/Linux_quick_start_ubuntu.doctree new file mode 100644 index 00000000..d7725c56 Binary files /dev/null and b/docs/development_guide_en/build/doctrees/get_started/Linux_quick_start_ubuntu.doctree differ diff --git a/docs/development_guide_en/build/doctrees/get_started/Windows_quick_start_cdk.doctree b/docs/development_guide_en/build/doctrees/get_started/Windows_quick_start_cdk.doctree new file mode 100644 index 00000000..84601c9e Binary files /dev/null and b/docs/development_guide_en/build/doctrees/get_started/Windows_quick_start_cdk.doctree differ diff --git a/docs/development_guide_en/build/doctrees/get_started/Windows_quick_start_eclipse.doctree b/docs/development_guide_en/build/doctrees/get_started/Windows_quick_start_eclipse.doctree new file mode 100644 index 00000000..493f80d4 Binary files /dev/null and b/docs/development_guide_en/build/doctrees/get_started/Windows_quick_start_eclipse.doctree differ diff --git a/docs/development_guide_en/build/doctrees/get_started/bl_dev_cube.doctree b/docs/development_guide_en/build/doctrees/get_started/bl_dev_cube.doctree new file mode 100644 index 00000000..13a49714 Binary files /dev/null and b/docs/development_guide_en/build/doctrees/get_started/bl_dev_cube.doctree differ diff --git a/docs/development_guide_en/build/doctrees/get_started/board.doctree b/docs/development_guide_en/build/doctrees/get_started/board.doctree new file mode 100644 index 00000000..61aaacc3 Binary files /dev/null and b/docs/development_guide_en/build/doctrees/get_started/board.doctree differ diff --git a/docs/development_guide_en/build/doctrees/get_started/cdk_ck_link.doctree b/docs/development_guide_en/build/doctrees/get_started/cdk_ck_link.doctree new file mode 100644 index 00000000..a08284a9 Binary files /dev/null and b/docs/development_guide_en/build/doctrees/get_started/cdk_ck_link.doctree differ diff --git a/docs/development_guide_en/build/doctrees/get_started/cdk_new_project_quick_start.doctree b/docs/development_guide_en/build/doctrees/get_started/cdk_new_project_quick_start.doctree new file mode 100644 index 00000000..31119a3b Binary files /dev/null and b/docs/development_guide_en/build/doctrees/get_started/cdk_new_project_quick_start.doctree differ diff --git a/docs/development_guide_en/build/doctrees/get_started/cdk_rv_debugger_plus.doctree b/docs/development_guide_en/build/doctrees/get_started/cdk_rv_debugger_plus.doctree new file mode 100644 index 00000000..58e5b164 Binary files /dev/null and b/docs/development_guide_en/build/doctrees/get_started/cdk_rv_debugger_plus.doctree differ diff --git a/docs/development_guide_en/build/doctrees/get_started/cmake_quick_start.doctree b/docs/development_guide_en/build/doctrees/get_started/cmake_quick_start.doctree new file mode 100644 index 00000000..8d606871 Binary files /dev/null and b/docs/development_guide_en/build/doctrees/get_started/cmake_quick_start.doctree differ diff --git a/docs/development_guide_en/build/doctrees/get_started/connecting_hardware.doctree b/docs/development_guide_en/build/doctrees/get_started/connecting_hardware.doctree new file mode 100644 index 00000000..ab5da9b6 Binary files /dev/null and b/docs/development_guide_en/build/doctrees/get_started/connecting_hardware.doctree differ diff --git a/docs/development_guide_en/build/doctrees/get_started/get_started.doctree b/docs/development_guide_en/build/doctrees/get_started/get_started.doctree new file mode 100644 index 00000000..15e9f4a7 Binary files /dev/null and b/docs/development_guide_en/build/doctrees/get_started/get_started.doctree differ diff --git a/docs/development_guide_en/build/doctrees/get_started/index.doctree b/docs/development_guide_en/build/doctrees/get_started/index.doctree new file mode 100644 index 00000000..4e2a9995 Binary files /dev/null and b/docs/development_guide_en/build/doctrees/get_started/index.doctree differ diff --git a/docs/development_guide_en/build/doctrees/index.doctree b/docs/development_guide_en/build/doctrees/index.doctree new file mode 100644 index 00000000..e6f2f601 Binary files /dev/null and b/docs/development_guide_en/build/doctrees/index.doctree differ diff --git a/docs/development_guide_en/build/doctrees/samples/advance samples/ble_scan_demo.doctree b/docs/development_guide_en/build/doctrees/samples/advance samples/ble_scan_demo.doctree new file mode 100644 index 00000000..c604e96b Binary files /dev/null and b/docs/development_guide_en/build/doctrees/samples/advance samples/ble_scan_demo.doctree differ diff --git a/docs/development_guide_en/build/doctrees/samples/advance samples/boot2_iap_info.doctree b/docs/development_guide_en/build/doctrees/samples/advance samples/boot2_iap_info.doctree new file mode 100644 index 00000000..143acf2c Binary files /dev/null and b/docs/development_guide_en/build/doctrees/samples/advance samples/boot2_iap_info.doctree differ diff --git a/docs/development_guide_en/build/doctrees/samples/advance samples/fatfs_demo.doctree b/docs/development_guide_en/build/doctrees/samples/advance samples/fatfs_demo.doctree new file mode 100644 index 00000000..2c82f4e4 Binary files /dev/null and b/docs/development_guide_en/build/doctrees/samples/advance samples/fatfs_demo.doctree differ diff --git a/docs/development_guide_en/build/doctrees/samples/advance samples/lowpower_demo.doctree b/docs/development_guide_en/build/doctrees/samples/advance samples/lowpower_demo.doctree new file mode 100644 index 00000000..131532d5 Binary files /dev/null and b/docs/development_guide_en/build/doctrees/samples/advance samples/lowpower_demo.doctree differ diff --git a/docs/development_guide_en/build/doctrees/samples/advance samples/shell_demo.doctree b/docs/development_guide_en/build/doctrees/samples/advance samples/shell_demo.doctree new file mode 100644 index 00000000..a64f87a7 Binary files /dev/null and b/docs/development_guide_en/build/doctrees/samples/advance samples/shell_demo.doctree differ diff --git a/docs/development_guide_en/build/doctrees/samples/basic samples/adc/adc_key_demo.doctree b/docs/development_guide_en/build/doctrees/samples/basic samples/adc/adc_key_demo.doctree new file mode 100644 index 00000000..2fd4c557 Binary files /dev/null and b/docs/development_guide_en/build/doctrees/samples/basic samples/adc/adc_key_demo.doctree differ diff --git a/docs/development_guide_en/build/doctrees/samples/basic samples/adc/index.doctree b/docs/development_guide_en/build/doctrees/samples/basic samples/adc/index.doctree new file mode 100644 index 00000000..e75c27f1 Binary files /dev/null and b/docs/development_guide_en/build/doctrees/samples/basic samples/adc/index.doctree differ diff --git a/docs/development_guide_en/build/doctrees/samples/basic samples/dma/dma_m2m_demo.doctree b/docs/development_guide_en/build/doctrees/samples/basic samples/dma/dma_m2m_demo.doctree new file mode 100644 index 00000000..d22f6f75 Binary files /dev/null and b/docs/development_guide_en/build/doctrees/samples/basic samples/dma/dma_m2m_demo.doctree differ diff --git a/docs/development_guide_en/build/doctrees/samples/basic samples/dma/index.doctree b/docs/development_guide_en/build/doctrees/samples/basic samples/dma/index.doctree new file mode 100644 index 00000000..8087c542 Binary files /dev/null and b/docs/development_guide_en/build/doctrees/samples/basic samples/dma/index.doctree differ diff --git a/docs/development_guide_en/build/doctrees/samples/basic samples/gpio/blink_demo.doctree b/docs/development_guide_en/build/doctrees/samples/basic samples/gpio/blink_demo.doctree new file mode 100644 index 00000000..dfd68b4d Binary files /dev/null and b/docs/development_guide_en/build/doctrees/samples/basic samples/gpio/blink_demo.doctree differ diff --git a/docs/development_guide_en/build/doctrees/samples/basic samples/gpio/button_demo.doctree b/docs/development_guide_en/build/doctrees/samples/basic samples/gpio/button_demo.doctree new file mode 100644 index 00000000..f28939e5 Binary files /dev/null and b/docs/development_guide_en/build/doctrees/samples/basic samples/gpio/button_demo.doctree differ diff --git a/docs/development_guide_en/build/doctrees/samples/basic samples/gpio/index.doctree b/docs/development_guide_en/build/doctrees/samples/basic samples/gpio/index.doctree new file mode 100644 index 00000000..b55fe858 Binary files /dev/null and b/docs/development_guide_en/build/doctrees/samples/basic samples/gpio/index.doctree differ diff --git a/docs/development_guide_en/build/doctrees/samples/basic samples/i2c/i2c_eeprom_demo.doctree b/docs/development_guide_en/build/doctrees/samples/basic samples/i2c/i2c_eeprom_demo.doctree new file mode 100644 index 00000000..817ce9f4 Binary files /dev/null and b/docs/development_guide_en/build/doctrees/samples/basic samples/i2c/i2c_eeprom_demo.doctree differ diff --git a/docs/development_guide_en/build/doctrees/samples/basic samples/i2c/index.doctree b/docs/development_guide_en/build/doctrees/samples/basic samples/i2c/index.doctree new file mode 100644 index 00000000..6879ed66 Binary files /dev/null and b/docs/development_guide_en/build/doctrees/samples/basic samples/i2c/index.doctree differ diff --git a/docs/development_guide_en/build/doctrees/samples/basic samples/mtimer/index.doctree b/docs/development_guide_en/build/doctrees/samples/basic samples/mtimer/index.doctree new file mode 100644 index 00000000..70acb4a2 Binary files /dev/null and b/docs/development_guide_en/build/doctrees/samples/basic samples/mtimer/index.doctree differ diff --git a/docs/development_guide_en/build/doctrees/samples/basic samples/mtimer/mtimer_demo.doctree b/docs/development_guide_en/build/doctrees/samples/basic samples/mtimer/mtimer_demo.doctree new file mode 100644 index 00000000..3cb41279 Binary files /dev/null and b/docs/development_guide_en/build/doctrees/samples/basic samples/mtimer/mtimer_demo.doctree differ diff --git a/docs/development_guide_en/build/doctrees/samples/basic samples/pwm/index.doctree b/docs/development_guide_en/build/doctrees/samples/basic samples/pwm/index.doctree new file mode 100644 index 00000000..02709113 Binary files /dev/null and b/docs/development_guide_en/build/doctrees/samples/basic samples/pwm/index.doctree differ diff --git a/docs/development_guide_en/build/doctrees/samples/basic samples/pwm/pwm_breath_demo.doctree b/docs/development_guide_en/build/doctrees/samples/basic samples/pwm/pwm_breath_demo.doctree new file mode 100644 index 00000000..74da3eb3 Binary files /dev/null and b/docs/development_guide_en/build/doctrees/samples/basic samples/pwm/pwm_breath_demo.doctree differ diff --git a/docs/development_guide_en/build/doctrees/samples/basic samples/pwm/pwm_step_motor.doctree b/docs/development_guide_en/build/doctrees/samples/basic samples/pwm/pwm_step_motor.doctree new file mode 100644 index 00000000..26bbc98e Binary files /dev/null and b/docs/development_guide_en/build/doctrees/samples/basic samples/pwm/pwm_step_motor.doctree differ diff --git a/docs/development_guide_en/build/doctrees/samples/basic samples/spi/index.doctree b/docs/development_guide_en/build/doctrees/samples/basic samples/spi/index.doctree new file mode 100644 index 00000000..1a24b9b6 Binary files /dev/null and b/docs/development_guide_en/build/doctrees/samples/basic samples/spi/index.doctree differ diff --git a/docs/development_guide_en/build/doctrees/samples/basic samples/spi/spi_lcd_demo.doctree b/docs/development_guide_en/build/doctrees/samples/basic samples/spi/spi_lcd_demo.doctree new file mode 100644 index 00000000..b2d4f1b7 Binary files /dev/null and b/docs/development_guide_en/build/doctrees/samples/basic samples/spi/spi_lcd_demo.doctree differ diff --git a/docs/development_guide_en/build/doctrees/samples/basic samples/timer/index.doctree b/docs/development_guide_en/build/doctrees/samples/basic samples/timer/index.doctree new file mode 100644 index 00000000..6c1e14eb Binary files /dev/null and b/docs/development_guide_en/build/doctrees/samples/basic samples/timer/index.doctree differ diff --git a/docs/development_guide_en/build/doctrees/samples/basic samples/timer/timer_interrupt_demo.doctree b/docs/development_guide_en/build/doctrees/samples/basic samples/timer/timer_interrupt_demo.doctree new file mode 100644 index 00000000..e342b097 Binary files /dev/null and b/docs/development_guide_en/build/doctrees/samples/basic samples/timer/timer_interrupt_demo.doctree differ diff --git a/docs/development_guide_en/build/doctrees/samples/basic samples/uart/index.doctree b/docs/development_guide_en/build/doctrees/samples/basic samples/uart/index.doctree new file mode 100644 index 00000000..6dadf1e7 Binary files /dev/null and b/docs/development_guide_en/build/doctrees/samples/basic samples/uart/index.doctree differ diff --git a/docs/development_guide_en/build/doctrees/samples/basic samples/uart/uart_loopback_demo.doctree b/docs/development_guide_en/build/doctrees/samples/basic samples/uart/uart_loopback_demo.doctree new file mode 100644 index 00000000..46b26250 Binary files /dev/null and b/docs/development_guide_en/build/doctrees/samples/basic samples/uart/uart_loopback_demo.doctree differ diff --git a/docs/development_guide_en/build/html/.buildinfo b/docs/development_guide_en/build/html/.buildinfo new file mode 100644 index 00000000..39c1178c --- /dev/null +++ b/docs/development_guide_en/build/html/.buildinfo @@ -0,0 +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: 98115eb567cdad088d75d44e83f6fe22 +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/docs/development_guide_en/build/html/_images/Linux_logo.png b/docs/development_guide_en/build/html/_images/Linux_logo.png new file mode 100644 index 00000000..1112db65 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/Linux_logo.png differ diff --git a/docs/development_guide_en/build/html/_images/adc_key_demo.png b/docs/development_guide_en/build/html/_images/adc_key_demo.png new file mode 100644 index 00000000..5706aff6 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/adc_key_demo.png differ diff --git a/docs/development_guide_en/build/html/_images/adc_key_result.png b/docs/development_guide_en/build/html/_images/adc_key_result.png new file mode 100644 index 00000000..0a4f5d7a Binary files /dev/null and b/docs/development_guide_en/build/html/_images/adc_key_result.png differ diff --git a/docs/development_guide_en/build/html/_images/bl706_avb.png b/docs/development_guide_en/build/html/_images/bl706_avb.png new file mode 100644 index 00000000..328064d6 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/bl706_avb.png differ diff --git a/docs/development_guide_en/build/html/_images/bl706_avb_ck_link.png b/docs/development_guide_en/build/html/_images/bl706_avb_ck_link.png new file mode 100644 index 00000000..da39cae4 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/bl706_avb_ck_link.png differ diff --git a/docs/development_guide_en/build/html/_images/bl706_avb_rv_debugger_plus.png b/docs/development_guide_en/build/html/_images/bl706_avb_rv_debugger_plus.png new file mode 100644 index 00000000..8deac670 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/bl706_avb_rv_debugger_plus.png differ diff --git a/docs/development_guide_en/build/html/_images/bl706_iot.png b/docs/development_guide_en/build/html/_images/bl706_iot.png new file mode 100644 index 00000000..04119f55 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/bl706_iot.png differ diff --git a/docs/development_guide_en/build/html/_images/ble_client.png b/docs/development_guide_en/build/html/_images/ble_client.png new file mode 100644 index 00000000..df9f9a00 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/ble_client.png differ diff --git a/docs/development_guide_en/build/html/_images/ble_data.png b/docs/development_guide_en/build/html/_images/ble_data.png new file mode 100644 index 00000000..c9c50a6e Binary files /dev/null and b/docs/development_guide_en/build/html/_images/ble_data.png differ diff --git a/docs/development_guide_en/build/html/_images/ble_server.png b/docs/development_guide_en/build/html/_images/ble_server.png new file mode 100644 index 00000000..84cb9790 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/ble_server.png differ diff --git a/docs/development_guide_en/build/html/_images/blink_breath_sch.png b/docs/development_guide_en/build/html/_images/blink_breath_sch.png new file mode 100644 index 00000000..25786009 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/blink_breath_sch.png differ diff --git a/docs/development_guide_en/build/html/_images/blink_breath_sch1.png b/docs/development_guide_en/build/html/_images/blink_breath_sch1.png new file mode 100644 index 00000000..25786009 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/blink_breath_sch1.png differ diff --git a/docs/development_guide_en/build/html/_images/button_sch.png b/docs/development_guide_en/build/html/_images/button_sch.png new file mode 100644 index 00000000..9ca54be0 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/button_sch.png differ diff --git a/docs/development_guide_en/build/html/_images/cdk1.png b/docs/development_guide_en/build/html/_images/cdk1.png new file mode 100644 index 00000000..b3d99c82 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/cdk1.png differ diff --git a/docs/development_guide_en/build/html/_images/cdk10.png b/docs/development_guide_en/build/html/_images/cdk10.png new file mode 100644 index 00000000..c0279b10 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/cdk10.png differ diff --git a/docs/development_guide_en/build/html/_images/cdk11.png b/docs/development_guide_en/build/html/_images/cdk11.png new file mode 100644 index 00000000..eb1932dd Binary files /dev/null and b/docs/development_guide_en/build/html/_images/cdk11.png differ diff --git a/docs/development_guide_en/build/html/_images/cdk3.png b/docs/development_guide_en/build/html/_images/cdk3.png new file mode 100644 index 00000000..ad453712 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/cdk3.png differ diff --git a/docs/development_guide_en/build/html/_images/cdk4.png b/docs/development_guide_en/build/html/_images/cdk4.png new file mode 100644 index 00000000..5c198917 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/cdk4.png differ diff --git a/docs/development_guide_en/build/html/_images/cdk5.png b/docs/development_guide_en/build/html/_images/cdk5.png new file mode 100644 index 00000000..1c3c2513 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/cdk5.png differ diff --git a/docs/development_guide_en/build/html/_images/cdk6.png b/docs/development_guide_en/build/html/_images/cdk6.png new file mode 100644 index 00000000..2478ba24 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/cdk6.png differ diff --git a/docs/development_guide_en/build/html/_images/cdk7.png b/docs/development_guide_en/build/html/_images/cdk7.png new file mode 100644 index 00000000..7eb65431 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/cdk7.png differ diff --git a/docs/development_guide_en/build/html/_images/cdk8.png b/docs/development_guide_en/build/html/_images/cdk8.png new file mode 100644 index 00000000..e208d88f Binary files /dev/null and b/docs/development_guide_en/build/html/_images/cdk8.png differ diff --git a/docs/development_guide_en/build/html/_images/cdk9.png b/docs/development_guide_en/build/html/_images/cdk9.png new file mode 100644 index 00000000..10ec6582 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/cdk9.png differ diff --git a/docs/development_guide_en/build/html/_images/cdk_start_1.png b/docs/development_guide_en/build/html/_images/cdk_start_1.png new file mode 100644 index 00000000..4f2a1549 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/cdk_start_1.png differ diff --git a/docs/development_guide_en/build/html/_images/cdk_start_2.png b/docs/development_guide_en/build/html/_images/cdk_start_2.png new file mode 100644 index 00000000..01c0ef2f Binary files /dev/null and b/docs/development_guide_en/build/html/_images/cdk_start_2.png differ diff --git a/docs/development_guide_en/build/html/_images/cdk_start_3.png b/docs/development_guide_en/build/html/_images/cdk_start_3.png new file mode 100644 index 00000000..1e23de95 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/cdk_start_3.png differ diff --git a/docs/development_guide_en/build/html/_images/cdk_start_4.png b/docs/development_guide_en/build/html/_images/cdk_start_4.png new file mode 100644 index 00000000..d211581a Binary files /dev/null and b/docs/development_guide_en/build/html/_images/cdk_start_4.png differ diff --git a/docs/development_guide_en/build/html/_images/cdk_start_5.png b/docs/development_guide_en/build/html/_images/cdk_start_5.png new file mode 100644 index 00000000..a26426ae Binary files /dev/null and b/docs/development_guide_en/build/html/_images/cdk_start_5.png differ diff --git a/docs/development_guide_en/build/html/_images/ck_link_connect_bl706_iot.png b/docs/development_guide_en/build/html/_images/ck_link_connect_bl706_iot.png new file mode 100644 index 00000000..34d3625b Binary files /dev/null and b/docs/development_guide_en/build/html/_images/ck_link_connect_bl706_iot.png differ diff --git a/docs/development_guide_en/build/html/_images/config_wizard.png b/docs/development_guide_en/build/html/_images/config_wizard.png new file mode 100644 index 00000000..23b64b1a Binary files /dev/null and b/docs/development_guide_en/build/html/_images/config_wizard.png differ diff --git a/docs/development_guide_en/build/html/_images/config_wizard_example1.png b/docs/development_guide_en/build/html/_images/config_wizard_example1.png new file mode 100644 index 00000000..a2cdc1ef Binary files /dev/null and b/docs/development_guide_en/build/html/_images/config_wizard_example1.png differ diff --git a/docs/development_guide_en/build/html/_images/config_wizard_example2.png b/docs/development_guide_en/build/html/_images/config_wizard_example2.png new file mode 100644 index 00000000..fd1cc605 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/config_wizard_example2.png differ diff --git a/docs/development_guide_en/build/html/_images/configuration_wizard_1.png b/docs/development_guide_en/build/html/_images/configuration_wizard_1.png new file mode 100644 index 00000000..cdf7b65d Binary files /dev/null and b/docs/development_guide_en/build/html/_images/configuration_wizard_1.png differ diff --git a/docs/development_guide_en/build/html/_images/configuration_wizard_2.png b/docs/development_guide_en/build/html/_images/configuration_wizard_2.png new file mode 100644 index 00000000..fc23f618 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/configuration_wizard_2.png differ diff --git a/docs/development_guide_en/build/html/_images/connect_camera_1.png b/docs/development_guide_en/build/html/_images/connect_camera_1.png new file mode 100644 index 00000000..7c692e36 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/connect_camera_1.png differ diff --git a/docs/development_guide_en/build/html/_images/connect_camera_2.png b/docs/development_guide_en/build/html/_images/connect_camera_2.png new file mode 100644 index 00000000..cf9740a0 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/connect_camera_2.png differ diff --git a/docs/development_guide_en/build/html/_images/connect_camera_3.png b/docs/development_guide_en/build/html/_images/connect_camera_3.png new file mode 100644 index 00000000..090f279b Binary files /dev/null and b/docs/development_guide_en/build/html/_images/connect_camera_3.png differ diff --git a/docs/development_guide_en/build/html/_images/connect_camera_4.png b/docs/development_guide_en/build/html/_images/connect_camera_4.png new file mode 100644 index 00000000..3d0ba64e Binary files /dev/null and b/docs/development_guide_en/build/html/_images/connect_camera_4.png differ diff --git a/docs/development_guide_en/build/html/_images/connect_codec_1.png b/docs/development_guide_en/build/html/_images/connect_codec_1.png new file mode 100644 index 00000000..a9e1f306 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/connect_codec_1.png differ diff --git a/docs/development_guide_en/build/html/_images/dev_cube_download.png b/docs/development_guide_en/build/html/_images/dev_cube_download.png new file mode 100644 index 00000000..89b6a10e Binary files /dev/null and b/docs/development_guide_en/build/html/_images/dev_cube_download.png differ diff --git a/docs/development_guide_en/build/html/_images/dev_cube_view_mcu.png b/docs/development_guide_en/build/html/_images/dev_cube_view_mcu.png new file mode 100644 index 00000000..43d4c360 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/dev_cube_view_mcu.png differ diff --git a/docs/development_guide_en/build/html/_images/eclipse_run.png b/docs/development_guide_en/build/html/_images/eclipse_run.png new file mode 100644 index 00000000..aa6e3363 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/eclipse_run.png differ diff --git a/docs/development_guide_en/build/html/_images/image1.png b/docs/development_guide_en/build/html/_images/image1.png new file mode 100644 index 00000000..f39cf53e Binary files /dev/null and b/docs/development_guide_en/build/html/_images/image1.png differ diff --git a/docs/development_guide_en/build/html/_images/image2.png b/docs/development_guide_en/build/html/_images/image2.png new file mode 100644 index 00000000..9cbc0447 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/image2.png differ diff --git a/docs/development_guide_en/build/html/_images/jlink_connect_bl706_iot.png b/docs/development_guide_en/build/html/_images/jlink_connect_bl706_iot.png new file mode 100644 index 00000000..58e58581 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/jlink_connect_bl706_iot.png differ diff --git a/docs/development_guide_en/build/html/_images/linux1.png b/docs/development_guide_en/build/html/_images/linux1.png new file mode 100644 index 00000000..0f55ebdb Binary files /dev/null and b/docs/development_guide_en/build/html/_images/linux1.png differ diff --git a/docs/development_guide_en/build/html/_images/lowpower_arch.png b/docs/development_guide_en/build/html/_images/lowpower_arch.png new file mode 100644 index 00000000..48477c99 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/lowpower_arch.png differ diff --git a/docs/development_guide_en/build/html/_images/phone_connect.jpg b/docs/development_guide_en/build/html/_images/phone_connect.jpg new file mode 100644 index 00000000..198aa627 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/phone_connect.jpg differ diff --git a/docs/development_guide_en/build/html/_images/phone_connected.png b/docs/development_guide_en/build/html/_images/phone_connected.png new file mode 100644 index 00000000..a76d6668 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/phone_connected.png differ diff --git a/docs/development_guide_en/build/html/_images/pic1.png b/docs/development_guide_en/build/html/_images/pic1.png new file mode 100644 index 00000000..9866e309 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/pic1.png differ diff --git a/docs/development_guide_en/build/html/_images/pic10.png b/docs/development_guide_en/build/html/_images/pic10.png new file mode 100644 index 00000000..b61cbfa9 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/pic10.png differ diff --git a/docs/development_guide_en/build/html/_images/pic11.png b/docs/development_guide_en/build/html/_images/pic11.png new file mode 100644 index 00000000..9fe441dd Binary files /dev/null and b/docs/development_guide_en/build/html/_images/pic11.png differ diff --git a/docs/development_guide_en/build/html/_images/pic12.png b/docs/development_guide_en/build/html/_images/pic12.png new file mode 100644 index 00000000..f60184f9 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/pic12.png differ diff --git a/docs/development_guide_en/build/html/_images/pic14.png b/docs/development_guide_en/build/html/_images/pic14.png new file mode 100644 index 00000000..bf018a3a Binary files /dev/null and b/docs/development_guide_en/build/html/_images/pic14.png differ diff --git a/docs/development_guide_en/build/html/_images/pic15.png b/docs/development_guide_en/build/html/_images/pic15.png new file mode 100644 index 00000000..73b97316 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/pic15.png differ diff --git a/docs/development_guide_en/build/html/_images/pic2.png b/docs/development_guide_en/build/html/_images/pic2.png new file mode 100644 index 00000000..2d5129bc Binary files /dev/null and b/docs/development_guide_en/build/html/_images/pic2.png differ diff --git a/docs/development_guide_en/build/html/_images/pic3.png b/docs/development_guide_en/build/html/_images/pic3.png new file mode 100644 index 00000000..0e20a992 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/pic3.png differ diff --git a/docs/development_guide_en/build/html/_images/pic4.png b/docs/development_guide_en/build/html/_images/pic4.png new file mode 100644 index 00000000..9424826d Binary files /dev/null and b/docs/development_guide_en/build/html/_images/pic4.png differ diff --git a/docs/development_guide_en/build/html/_images/pic5.png b/docs/development_guide_en/build/html/_images/pic5.png new file mode 100644 index 00000000..40158e36 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/pic5.png differ diff --git a/docs/development_guide_en/build/html/_images/pic6.png b/docs/development_guide_en/build/html/_images/pic6.png new file mode 100644 index 00000000..009a704e Binary files /dev/null and b/docs/development_guide_en/build/html/_images/pic6.png differ diff --git a/docs/development_guide_en/build/html/_images/pic7.png b/docs/development_guide_en/build/html/_images/pic7.png new file mode 100644 index 00000000..c88657dc Binary files /dev/null and b/docs/development_guide_en/build/html/_images/pic7.png differ diff --git a/docs/development_guide_en/build/html/_images/pic8.png b/docs/development_guide_en/build/html/_images/pic8.png new file mode 100644 index 00000000..445b10d1 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/pic8.png differ diff --git a/docs/development_guide_en/build/html/_images/pic9.png b/docs/development_guide_en/build/html/_images/pic9.png new file mode 100644 index 00000000..28e7756c Binary files /dev/null and b/docs/development_guide_en/build/html/_images/pic9.png differ diff --git a/docs/development_guide_en/build/html/_images/powerTable.png b/docs/development_guide_en/build/html/_images/powerTable.png new file mode 100644 index 00000000..0fe2faa6 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/powerTable.png differ diff --git a/docs/development_guide_en/build/html/_images/pwm_demo.gif b/docs/development_guide_en/build/html/_images/pwm_demo.gif new file mode 100644 index 00000000..88e2d694 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/pwm_demo.gif differ diff --git a/docs/development_guide_en/build/html/_images/pwm_step_motor.gif b/docs/development_guide_en/build/html/_images/pwm_step_motor.gif new file mode 100644 index 00000000..09a0cee7 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/pwm_step_motor.gif differ diff --git a/docs/development_guide_en/build/html/_images/pwm_step_motor.png b/docs/development_guide_en/build/html/_images/pwm_step_motor.png new file mode 100644 index 00000000..5d8faec1 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/pwm_step_motor.png differ diff --git a/docs/development_guide_en/build/html/_images/pwm_step_motor1.png b/docs/development_guide_en/build/html/_images/pwm_step_motor1.png new file mode 100644 index 00000000..3180f0b6 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/pwm_step_motor1.png differ diff --git a/docs/development_guide_en/build/html/_images/pwm_step_motor2.png b/docs/development_guide_en/build/html/_images/pwm_step_motor2.png new file mode 100644 index 00000000..775d5da5 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/pwm_step_motor2.png differ diff --git a/docs/development_guide_en/build/html/_images/pwm_step_motor3.png b/docs/development_guide_en/build/html/_images/pwm_step_motor3.png new file mode 100644 index 00000000..a2b8d8d2 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/pwm_step_motor3.png differ diff --git a/docs/development_guide_en/build/html/_images/receive_data.png b/docs/development_guide_en/build/html/_images/receive_data.png new file mode 100644 index 00000000..1194d576 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/receive_data.png differ diff --git a/docs/development_guide_en/build/html/_images/shell_demo.gif b/docs/development_guide_en/build/html/_images/shell_demo.gif new file mode 100644 index 00000000..7cbd5138 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/shell_demo.gif differ diff --git a/docs/development_guide_en/build/html/_images/sipeed_rv_debugger_1.png b/docs/development_guide_en/build/html/_images/sipeed_rv_debugger_1.png new file mode 100644 index 00000000..a9a4fb14 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/sipeed_rv_debugger_1.png differ diff --git a/docs/development_guide_en/build/html/_images/sipeed_rv_debugger_2.png b/docs/development_guide_en/build/html/_images/sipeed_rv_debugger_2.png new file mode 100644 index 00000000..b82fe2d1 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/sipeed_rv_debugger_2.png differ diff --git a/docs/development_guide_en/build/html/_images/sipeed_rv_debugger_3.png b/docs/development_guide_en/build/html/_images/sipeed_rv_debugger_3.png new file mode 100644 index 00000000..4db6ab8c Binary files /dev/null and b/docs/development_guide_en/build/html/_images/sipeed_rv_debugger_3.png differ diff --git a/docs/development_guide_en/build/html/_images/sipeed_rv_debugger_4.png b/docs/development_guide_en/build/html/_images/sipeed_rv_debugger_4.png new file mode 100644 index 00000000..f971757a Binary files /dev/null and b/docs/development_guide_en/build/html/_images/sipeed_rv_debugger_4.png differ diff --git a/docs/development_guide_en/build/html/_images/sipeed_rv_debugger_6.png b/docs/development_guide_en/build/html/_images/sipeed_rv_debugger_6.png new file mode 100644 index 00000000..e3c5e69b Binary files /dev/null and b/docs/development_guide_en/build/html/_images/sipeed_rv_debugger_6.png differ diff --git a/docs/development_guide_en/build/html/_images/sipeed_rv_debugger_7.png b/docs/development_guide_en/build/html/_images/sipeed_rv_debugger_7.png new file mode 100644 index 00000000..d825504e Binary files /dev/null and b/docs/development_guide_en/build/html/_images/sipeed_rv_debugger_7.png differ diff --git a/docs/development_guide_en/build/html/_images/sipeed_rv_debugger_8.png b/docs/development_guide_en/build/html/_images/sipeed_rv_debugger_8.png new file mode 100644 index 00000000..09b85980 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/sipeed_rv_debugger_8.png differ diff --git a/docs/development_guide_en/build/html/_images/sipeed_rv_debugger_plus.png b/docs/development_guide_en/build/html/_images/sipeed_rv_debugger_plus.png new file mode 100644 index 00000000..9e5345d7 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/sipeed_rv_debugger_plus.png differ diff --git a/docs/development_guide_en/build/html/_images/spi_lcd.png b/docs/development_guide_en/build/html/_images/spi_lcd.png new file mode 100644 index 00000000..0feaac4b Binary files /dev/null and b/docs/development_guide_en/build/html/_images/spi_lcd.png differ diff --git a/docs/development_guide_en/build/html/_images/step_motor.png b/docs/development_guide_en/build/html/_images/step_motor.png new file mode 100644 index 00000000..8281cf8c Binary files /dev/null and b/docs/development_guide_en/build/html/_images/step_motor.png differ diff --git a/docs/development_guide_en/build/html/_images/step_motor_info.png b/docs/development_guide_en/build/html/_images/step_motor_info.png new file mode 100644 index 00000000..ce561ca6 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/step_motor_info.png differ diff --git a/docs/development_guide_en/build/html/_images/sw_arch.png b/docs/development_guide_en/build/html/_images/sw_arch.png new file mode 100644 index 00000000..fa2148e2 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/sw_arch.png differ diff --git a/docs/development_guide_en/build/html/_images/uln2003.png b/docs/development_guide_en/build/html/_images/uln2003.png new file mode 100644 index 00000000..7ef6a395 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/uln2003.png differ diff --git a/docs/development_guide_en/build/html/_images/windows_cdk_logo.png b/docs/development_guide_en/build/html/_images/windows_cdk_logo.png new file mode 100644 index 00000000..f98ab7fc Binary files /dev/null and b/docs/development_guide_en/build/html/_images/windows_cdk_logo.png differ diff --git a/docs/development_guide_en/build/html/_images/windows_eclipse_logo.png b/docs/development_guide_en/build/html/_images/windows_eclipse_logo.png new file mode 100644 index 00000000..e78349ce Binary files /dev/null and b/docs/development_guide_en/build/html/_images/windows_eclipse_logo.png differ diff --git a/docs/development_guide_en/build/html/_images/write_data.jpg b/docs/development_guide_en/build/html/_images/write_data.jpg new file mode 100644 index 00000000..dffeb6f6 Binary files /dev/null and b/docs/development_guide_en/build/html/_images/write_data.jpg differ diff --git a/docs/development_guide_en/build/html/_images/xShell_lowpower.png b/docs/development_guide_en/build/html/_images/xShell_lowpower.png new file mode 100644 index 00000000..5a16356f Binary files /dev/null and b/docs/development_guide_en/build/html/_images/xShell_lowpower.png differ diff --git a/docs/development_guide_en/build/html/_sources/api_reference/api_overview.rst.txt b/docs/development_guide_en/build/html/_sources/api_reference/api_overview.rst.txt new file mode 100644 index 00000000..42ecb8fb --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/api_reference/api_overview.rst.txt @@ -0,0 +1,288 @@ +API Overview +========================= + +Introduction +------------------ + +**bl_mcu_sdk** code hierarchy is divided into the following main layers. + +- The application layer: codes written by users. +- The component layer: some opensource components,the interface calls the HAL layer, while the wireless layer is used for wireless functions. +- HAL layer and wireless layer for adaptation to different MCUs, where the HAL layer is divided into two layers + - Device driver management: provides a standard set of interfaces, which are implemented by the peripheral driver adaptation layer + - Peripheral driver adaptation layer: implements the standard interface of the device driver management and extends its own unique interface +- Standard driver layer based on register packaging +- Hardware layer, also known as the register layer + +.. figure:: img/sw_arch.png + :alt: + + code structure + +Device driver management layer +--------------------------------- + +The realization of the device driver management layer adopts the object-oriented idea. First of all, we regard the peripheral as a device or a file, adhering to the concept of **everything is a file**, and files have standard calling interfaces: ``open``, ``close``, ``ctrl``, ``write``, ``read``, ``callback``. Different file types are different (such as serial device, ADC device, SPI device), and the way of opening is also different (such as polling, interrupt, DMA), from this, we can construct a base class (parent class) of an object. + +**Base class** + +.. 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; + }; + +**Base class member: name** + +Name the device and use ``device_find`` to find the device. + +**Base class member: type** + +``type`` records the category of the current device, and the ``type`` that can be selected are as follows. + +.. 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, + } ; + +**Base class member: status** + +``status`` is used to record the current status of the device and provides 4 statuses. + +.. code-block:: C + + enum device_status_type + { + DEVICE_UNREGISTER = 0, + DEVICE_REGISTERED, + DEVICE_OPENED, + DEVICE_CLOSED + } ; + +**Base class member: oflag** + +``oflag`` records the flag information filled in during registration and the ``oflag`` information filled in when using ``device_open``. + +**Base class members: list** + +The addition and deletion of equipment is stored in a doubly linked list, which saves memory. + +**Base class members: standard function pointers** + +Provides a standard function interface for different peripherals. When the peripheral implements this type of interface and assigns it to the member, the function of rewriting can be achieved. + +Device driver management layer standard interface +--------------------------------------------------- + +**device_register** +^^^^^^^^^^^^^^^^^^^^ + +``device_register`` is used to register the device and register the device information in the linked list. + +.. code-block:: C + + int device_register(struct device *dev, const char *name); + +- dev: device handle. +- name: the name of the device. +- return: return error code, 0 means registration is successful, others mean errors. + +**device_unregister** +^^^^^^^^^^^^^^^^^^^^^^^ + +``device_unregister`` is used to delete the device and delete the device information from the linked list. + +.. code-block:: C + + int device_unregister(const char *name); + +- dev: device handle +- name: the name of the device to be deleted +- return: error code, 0 means delete, others mean error + +**device_find** +^^^^^^^^^^^^^^^^ + +``device_find`` is used to find the device from the linked list according to ``name``, and return the first address of the device handle. + +.. code-block:: C + + struct device *device_find(const char *name); + +- dev: device handle +- name: the name of the device to be searched +- return: error code,! 0 means the device handle was found, NULL means the device was not found. + + +**device_open** +^^^^^^^^^^^^^^^^ + +``device_open`` is used to open the device, and ``oflag`` represents the opening method. Currently, there are 6 opening methods available. The bottom layer calls the ``open`` member in the ``dev`` handle. + +.. code-block:: C + + int device_open(struct device *dev, uint16_t oflag); + +- dev: device handle +- oflag: open method +- return: error code, 0 means opening is successful, others mean errors + +``oflag`` can write the following parameters: + +.. code-block:: C + + #define DEVICE_OFLAG_STREAM_TX 0x001 /* The device is turned on in polling sending mode */ + #define DEVICE_OFLAG_STREAM_RX 0x002 /* The device is turned on in polling receiving mode */ + #define DEVICE_OFLAG_INT_TX 0x004 /* The device is turned on in interrupt sending mode */ + #define DEVICE_OFLAG_INT_RX 0x008 /* The device is turned on in interrupt receiving mode */ + #define DEVICE_OFLAG_DMA_TX 0x010 /* The device is turned on in DMA transmission mode */ + #define DEVICE_OFLAG_DMA_RX 0x020 /* The device is turned on in DMA receiving mode */ + +**device_close** +^^^^^^^^^^^^^^^^ + +``device_close`` is used to close the device. The bottom layer calls the ``close`` member in the ``dev`` handle. + +.. code-block:: C + + int device_close(struct device *dev); + +-dev: device handle +-return: error code, 0 means closing is successful, others mean error + +**device_control** +^^^^^^^^^^^^^^^^^^^ + +``device_control`` is used to control the device and modify parameters according to commands. The bottom layer calls the ``control`` member in the ``dev`` handle. + +.. code-block:: C + + int device_control(struct device *dev, int cmd, void *args); + +- dev: device handle +- cmd: device control command +- args: control parameters +- return: Different control commands return different meanings. + +``cmd`` provides the following standard commands. In addition, different peripherals also have their own commands + +.. 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`` is used to send data, and the sending mode can be polling, interrupt, dma. The bottom layer calls the ``write`` member in the ``dev`` handle. + +.. code-block:: C + + int device_write(struct device *dev, uint32_t pos, const void *buffer, uint32_t size); + +- dev: device handle +- pos: different devices have different meanings for pos +- buffer: the buffer to be written +- size: the length to be written +- return: error code, 0 means writing is successful, others mean errors + +**device_read** +^^^^^^^^^^^^^^^^ + +``device_read`` is used to receive data, and the receiving mode can be polling, interrupt, dma. The bottom layer calls the ``read`` member in the ``dev`` handle. + +.. code-block:: C + + int device_read(struct device *dev, uint32_t pos, void *buffer, uint32_t size); + +- dev: device handle +- pos: different devices have different meanings for pos +- buffer: the buffer to be read +- size: the length to be read +- return: error code, 0 means successful reading, others mean errors + +**device_set_callback** +^^^^^^^^^^^^^^^^^^^^^^^^ + +``device_set_callback`` is used to register interrupt callback function. The bottom layer calls the ``callback`` member in the ``dev`` handle. + +.. code-block:: C + + int device_set_callback(struct device *dev, void (*callback)(struct device *dev, void *args, uint32_t size, uint32_t event)); + +- dev: device handle +- callback: the interrupt callback function to be registered + + + * dev: device handle + * args: Different peripherals have different meanings + * size: transmission length + * event: interrupt event type + +Peripheral driver adaptation layer +--------------------------------------- + +**Subclass inherits from parent class** + +The first member of different peripherals is ``struct device``, which is equivalent to the inheritance of the parent class, so that the subclass can be used to access the parent class member. When the subclass is used to modify the members of the parent class, it has its own functions. The realization principle is that the first address of different structures is the address of the first member in the structure. + +.. code-block:: C + + typedef struct xxx_device + { + struct device parent; + + } xxx_device_t; + +**Rewrite standard interface** + +Each peripheral has a ``xxx_register`` function, which is used to rewrite the standard interface. + +.. code-block:: C + + dev->open = xxx_open; + dev->close = xxx_close; + dev->control = xxx_control; + dev->write = xxx_write; + dev->read = xxx_read; diff --git a/docs/development_guide_en/build/html/_sources/api_reference/bluetooth/api_ble.rst.txt b/docs/development_guide_en/build/html/_sources/api_reference/bluetooth/api_ble.rst.txt new file mode 100644 index 00000000..0a7d871f --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/api_reference/bluetooth/api_ble.rst.txt @@ -0,0 +1,708 @@ +.. _ble-index: + +BLE +================== + +Introduction +------------------- +- Features + + HOST + - GAP support peripheral and Central, Observer and Broadcaster + - GATT support server and Client + - Support pairing with the secure connection feature in Bluetooth 4.2 + - Support permanent storage of Bluetooth specific settings and data + + mesh + - TODO + +- The architecture of the BLE protocol stack: + .. figure:: img/image1.png + + + There are 3 main layers, which together form a complete Bluetooth low power protocol stack + - Host: Under the application program, it is composed of multiple (non-real-time) networks and transmission protocols, enabling the application program to communicate with peer devices in a standard and interoperable manner + - Controller:The controller implements the link layer (LE LL), which is a low-level real-time protocol that provides standard interoperability for over-the-air communication with the radio. LL handles the reception and transmission of packets, guarantees the transfer of data, and handles all LL control procedures + - Radio Hardware:Implement analog and digital baseband functions, allowing link layer firmware to transmit and receive in the 2.4GHz band of the spectrum + +- Master Host: + .. figure:: img/image2.png + + * The Bluetooth Host layer implements all high-level protocols and configuration files, the most important thing is that it provides high-level APIs for applications + - HCI: Host and controller interface + - L2CAP: Logical Link Control and Adaptation Protocol + - GATT: Generic Attribute Profile + - GAP: Generic Access Profile + - SMP: Security Manager Specification + +- Application + * The application layer contains the necessary protocol stack parameter settings and api reference. We analyze the two devices separately from the Bluetooth slave and the Bluetooth master + * Bluetooth slave + - Hardware and basic service initialization + - Set broadcast parameters: broadcast data, broadcast interval, scan response, etc + - Profile settings: add slave services, feature values, and set callback functions to receive host data, etc + - Set pairing parameters (optional) + - Start the broadcast, start running + - Waiting for related events, and event processing, such as receiving data from the host, being linked, etc + * Bluetooth host + - Related hardware and basic service initialization + - Set scan parameters + - Set connection parameters + - Set pairing parameters (optional) + - Start the protocol stack and start running + - Wait for related events, and event processing, such as scan events, Notify events from slaves, etc + +API +---------- + +- API introduction + +``void ble_controller_init(uint8_t task_priority)`` + +:: + + /** + * function Controller layer initialization + * @param[in] task_priority: task priority + * @return None + */ + +``int hci_driver_init(void)`` + +:: + + /** + * function HCI interface driver initialization + * @param[in] None + * @return 0: success, !=0: fail + */ + +``int bt_enable(bt_ready_cb_t cb)`` + +:: + + /** + * function BLE enable + * @param[in] cb: Call the callback function if successful + * @return 0: success, !=0: fail + */ + +``int bt_le_adv_start(const struct bt_le_adv_param *param,const struct bt_data *ad, size_t ad_len,`` + ``const struct bt_data *sd, size_t sd_len)`` + +:: + + /** + * function Turn on BLE broadcast + * + * @param[in] param: Pointer to broadcast configuration parameter + * @param[in] ad: Pointer to the data in the broadcast packet + * @param[in] ad_len: The length of the data in the broadcast packet + * @param[in] sd: Pointer to scan response packet data + * @param[in] sd_len: Scan response packet data length + * @return 0: success, !=0: fail + */ + + +``int bt_le_adv_update_data(const struct bt_data *ad, size_t ad_len,const struct bt_data *sd, size_t sd_len)`` + + +:: + + /** + * function Update BLE broadcast data + * @param[in] ad: Pointer to the data in the broadcast packet + * @param[in] ad_len: The length of the data in the broadcast packet + * @param[in] sd: Pointer to scan response packet data + * @param[in] sd_len: Scan response packet data length + * @return 0: success, !=0: fail + */ + +``int bt_le_adv_stop(void)`` + + +:: + + /** + * function Stop BLE broadcast + * @param[in] None + * @return 0: success, !=0: fail + */ + + +``int bt_le_scan_start(const struct bt_le_scan_param *param, bt_le_scan_cb_t cb)`` + +:: + + /** + * function Turn on BLE scanning + * @param[in] param: Pointer to scan parameter + * @param[in] cb: Scan callback function + * @return 0: success, !=0: fail + */ + +``int bt_le_scan_stop(void)`` + +:: + + /** + * function Stop BLE scanning + * @param[in] None + * @return 0: success, !=0: fail + */ + +``int bt_le_whitelist_add(const bt_addr_le_t *addr)`` + +:: + + /** + * function Add devices to the whitelist by address + * @param[in] addr: Pointer to the address of the device that needs to be added + * @return 0: success, !=0: fail + */ + +``int bt_le_whitelist_rem(const bt_addr_le_t *addr)`` + +:: + + + /** + * function Remove the device from the whitelist + * @param[in] addr: Pointer to the address of the device that needs to be removed + * @return 0: success, !=0: fail + */ + +``int bt_le_whitelist_clear(void)`` + + +:: + + /** + * function Clear the whitelist list + * @param[in] None + * @return 0: success, !=0: fail + */ + +``int bt_le_set_chan_map(u8_t chan_map[5])`` + +:: + + /** + * function Set (LE) channel mapping + * @param[in] chan_map: channel array + * @return 0: success, !=0: fail + */ + +``int bt_unpair(u8_t id, const bt_addr_le_t *addr)`` + +:: + + /** + * function Clear pairing information + * @param[in] id: Local ID (mostly just the default BT ID) + * @param[in] addr: Remote device address, NULL or BT_ADDR_LE_ANY to clear all remote devices + * @return 0: success, !=0: fail + */ + +``int bt_conn_get_info(const struct bt_conn *conn, struct bt_conn_info *info)`` + +:: + + /** + * function Get the information of the currently connected device + * @param[in] conn: Pointer to the current connection + * @param[in] info: Pointer to the information of the currently connected device + * @return 0: success, !=0: fail + */ + + +``int bt_conn_get_remote_dev_info(struct bt_conn_info *info)`` + +:: + + /** + * function Get information about connected devices + * @param[in] info: Pointer to the information of the currently connected device + * @return Number of connected devices + */ + +``int bt_conn_le_param_update(struct bt_conn *conn,const struct bt_le_conn_param *param)`` + +:: + + /** + * function Update connection parameters + * @param[in] conn: Pointer to the current connection + * @param[in] param: Pointer to connection parameter + * @return 0: success, !=0: fail + */ + +``int bt_conn_disconnect(struct bt_conn *conn, u8_t reason)`` + +:: + + /** + * function Disconnect current connection + * @param[in] conn: pointer to the current connection + * @param[in] reason: the reason for disconnecting the current connection + * @return 0: success, !=0: fail + */ + +``struct bt_conn *bt_conn_create_le(const bt_addr_le_t *peer,const struct bt_le_conn_param *param)`` + +:: + + /** + * function Create connection + * @param[in] peer: The pointer of the device address that needs to be connected + * @param[in] param: Pointer to connection parameter + * @return Success: a valid connection object, otherwise it fails + */ + + +``int bt_conn_create_auto_le(const struct bt_le_conn_param *param)`` + +:: + + /** + * function Automatically create and connect to devices in the whitelist + * @param[in] param: pointer to connection parameter + * @return 0: success, !=0: fail + */ + +``int bt_conn_create_auto_stop(void)`` + +:: + + /** + * function Stop automatic creation and connect to devices in the whitelist + * @param[in] None + * @return 0: success, !=0: fail + */ + +``int bt_le_set_auto_conn(const bt_addr_le_t *addr,const struct bt_le_conn_param *param)`` + +:: + + /** + * function Automatically create a connection to the remote device + * @param[in] addr: Remote device address pointer + * @param[in] param: Pointer to connection parameter + * @return 0: success, !=0: fail + */ + +``struct bt_conn *bt_conn_create_slave_le(const bt_addr_le_t *peer,const struct bt_le_adv_param *param)`` + +:: + + /** + * function Initiate a directed broadcast packet to the remote device + * @param[in] peer: Remote device address pointer + * @param[in] param: Pointer to broadcast parameters + * @return Success: a valid connection object, otherwise it fails + */ + +``int bt_conn_set_security(struct bt_conn *conn, bt_security_t sec)`` + +:: + + /** + * function Set the connection security level + * @param[in] conn: Pointer to the connection object + * @param[in] sec: Security level + * @return 0: success, !=0: fail + */ + +``bt_security_t bt_conn_get_security(struct bt_conn *conn)`` + +:: + + /** + * function Get the security level of the current connection + * @param[in] conn: Pointer to the connection object + * @return Security Level + */ + + +``u8_t bt_conn_enc_key_size(struct bt_conn *conn)`` + +:: + + /** + * function Get the size of the encryption key of the current connection + * @param[in] conn: Pointer to the connection object + * @return The size of the encryption key + */ + + +``void bt_conn_cb_register(struct bt_conn_cb *cb)`` + +:: + + /** + * function Register connection callback function + * @param[in] cb: Connection callback function + * @return None + */ + +``void bt_set_bondable(bool enable)`` + +:: + + /** + * function Set/clear the binding flag in the SMP pairing request/response to the data authentication request + * @param[in] enable: 1: enable, 0: disable + * @return None + */ + +``int bt_conn_auth_cb_register(const struct bt_conn_auth_cb *cb)`` + +:: + + /** + * function Register authentication callback function + * @param[in] cb: Callback function pointer + * @return 0: success, !=0: failure + */ + +``int bt_conn_auth_passkey_entry(struct bt_conn *conn, unsigned int passkey)`` + +:: + + /** + * function Reply with the key + * @param[in] conn: Connect object pointer + * @param[in] passkey: the key entered + * @return 0: success, !=0: failure + */ + +``int bt_conn_auth_cancel(struct bt_conn *conn)`` + +:: + + /** + * function Cancel the authentication process + * @param[in] conn: Connection object pointer + * @return 0: success, !=0: failure + */ + +``int bt_conn_auth_passkey_confirm(struct bt_conn *conn)`` + +:: + + /** + * function If the password matches, reply to the other side + * @param[in] conn: Pointer to connection object + * @return 0: success, !=0: failure + */ + +``int bt_conn_auth_pincode_entry(struct bt_conn *conn, const char *pin)`` + +:: + + /** + * function Reply with PIN code + * @param[in] conn: Pointer to connection object + * @param[in] pin: PIN code pointer + * @return 0: success, !=0: failure + */ + +``int bt_le_read_rssi(u16_t handle,int8_t *rssi)`` + +:: + + /** + * function Read the RSSI value of the opposite device + * @param[in] handle: The handle value of the connection + * @param[in] rssi: rssi pointer + * @return 0: success, !=0: failure + */ + +``int bt_get_local_address(bt_addr_le_t *adv_addr)`` + +:: + + /** + * function Read the address of the machine + * @param[in] adv_addr: Pointer to address + * @return 0: success, !=0: failure + */ + +``int bt_set_tx_pwr(int8_t power)`` + +:: + + /** + * function Set the transmit power of this device + * @param[in] power: power value + * @return 0: success, !=0: failure + */ + +Data structure reference +----------------------------- + +``bt_le_adv_param``\ data structure: + +.. code:: c + + /** LE Advertising Parameters. */ + struct bt_le_adv_param { + /** Local identity */ + u8_t id; + + /** Bit-field of advertising options */ + u8_t options; + + /** Minimum Advertising Interval (N * 0.625) */ + u16_t interval_min; + + /** Maximum Advertising Interval (N * 0.625) */ + u16_t interval_max; + + #if defined(CONFIG_BT_STACK_PTS) + u8_t addr_type; + #endif + }; + +This data structure is used to configure broadcast parameters, including local identification, broadcast option bit fields, broadcast gaps, etc. The broadcast option bit fields have the following enumerated type parameters to choose from: + +.. code:: c + + enum { + /** Convenience value when no options are specified. */ + BT_LE_ADV_OPT_NONE = 0, + + /** Advertise as connectable. Type of advertising is determined by + * providing SCAN_RSP data and/or enabling local privacy support. + */ + BT_LE_ADV_OPT_CONNECTABLE = BIT(0), + + /** Don't try to resume connectable advertising after a connection. + * This option is only meaningful when used together with + * BT_LE_ADV_OPT_CONNECTABLE. If set the advertising will be stopped + * when bt_le_adv_stop() is called or when an incoming (slave) + * connection happens. If this option is not set the stack will + * take care of keeping advertising enabled even as connections + * occur. + */ + BT_LE_ADV_OPT_ONE_TIME = BIT(1), + + /** Advertise using the identity address as the own address. + * @warning This will compromise the privacy of the device, so care + * must be taken when using this option. + */ + BT_LE_ADV_OPT_USE_IDENTITY = BIT(2), + + /** Advertise using GAP device name */ + BT_LE_ADV_OPT_USE_NAME = BIT(3), + + /** Use low duty directed advertising mode, otherwise high duty mode + * will be used. This option is only effective when used with + * bt_conn_create_slave_le(). + */ + BT_LE_ADV_OPT_DIR_MODE_LOW_DUTY = BIT(4), + + /** Enable use of Resolvable Private Address (RPA) as the target address + * in directed advertisements when CONFIG_BT_PRIVACY is not enabled. + * This is required if the remote device is privacy-enabled and + * supports address resolution of the target address in directed + * advertisement. + * It is the responsibility of the application to check that the remote + * device supports address resolution of directed advertisements by + * reading its Central Address Resolution characteristic. + */ + BT_LE_ADV_OPT_DIR_ADDR_RPA = BIT(5), + + /** Use whitelist to filter devices that can request scan response + * data. + */ + BT_LE_ADV_OPT_FILTER_SCAN_REQ = BIT(6), + + /** Use whitelist to filter devices that can connect. */ + BT_LE_ADV_OPT_FILTER_CONN = BIT(7), + }; + +If you need to send a broadcast packet, the configuration can be as follows: + +.. code:: c + + param.id = 0; + param.options = (BT_LE_ADV_OPT_CONNECTABLE | BT_LE_ADV_OPT_USE_NAME | BT_LE_ADV_OPT_ONE_TIME); + param.interval_min = 0x00a0; + param.interval_max = 0x00f0; + +``bt_data``\ data structure: + +.. code:: c + + struct bt_data { + u8_t type; + u8_t data_len; + const u8_t *data; + }; + +This data structure is used to fill the data in the broadcast packet, the specific data packet type can refer to the following: + +.. code:: c + + Service UUID + Local Name + Flags + Manufacturer Specific Data + TX Power Level + Secure Simple Pairing OOB + Security Manager OOB + Security Manager TK Value + Slave Connection Interval Range + Service Solicitation + Service Data + Appearance + Public Target Address + Random Target Address + Advertising Interval + LE Bluetooth Device Address + LE Role + Uniform Resource Identifier + LE Supported Features + Channel Map Update Indication + +Use this data structure to configure a broadcast packet data, as shown below: + +.. code:: c + + struct bt_data ad_discov[] = { + BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)), + BT_DATA(BT_DATA_NAME_COMPLETE, "BL602-BLE-DEV", 13), + }; + +``bt_le_scan_param``\ data structure: + +.. code:: c + + /** LE scan parameters */ + struct bt_le_scan_param { + /** Scan type (BT_LE_SCAN_TYPE_ACTIVE or BT_LE_SCAN_TYPE_PASSIVE) */ + u8_t type; + + /** Bit-field of scanning filter options. */ + u8_t filter_dup; + + /** Scan interval (N * 0.625 ms) */ + u16_t interval; + + /** Scan window (N * 0.625 ms) */ + u16_t window; + }; + +This data structure is used to fill scan parameters, +type: There are two types of scan types: BT_LE_SCAN_TYPE_ACTIVE (0x01) and BT_LE_SCAN_TYPE_PASSIVE (0x00) +filter_dup: 0x00, except for targeted advertisements, accept all broadcast and scan responses, 0x01, only receive broadcast and scan responses from devices in the whitelist +interval: Scan interval +window: Scan window + +If the scan request is enabled, it can be configured as follows: + +.. code:: c + + scan_param.type = BT_LE_SCAN_TYPE_PASSIVE + scan_param.filter_dup = 0x00 + interval=BT_GAP_SCAN_SLOW_INTERVAL_1 + window=BT_GAP_SCAN_SLOW_WINDOW_1 + + +``bt_le_conn_param``\ data structure: + +.. code:: c + + /** Connection parameters for LE connections */ + struct bt_le_conn_param { + u16_t interval_min; + u16_t interval_max; + u16_t latency; + u16_t timeout; + + #if defined(CONFIG_BT_STACK_PTS) + u8_t own_address_type; + #endif + }; + +This data structure is used to fill in the connection parameters, interval_min: the minimum value of the connection interval (0x0018), interval_max: the maximum value of the connection interval (0x0028), +latency: The maximum slave latency allowed for connection events +timeout: The time for the connection to time out + +Configure the data structure as follows: + +.. code:: c + + interval_min=BT_GAP_INIT_CONN_INT_MIN(0x0018) + interval_max=BT_GAP_INIT_CONN_INT_MAX(0x0028) + latency=0 + timeout=400 + +``bt_conn``\ data structure: + +.. code:: c + + struct bt_conn { + u16_t handle; + u8_t type; + u8_t role; + + ATOMIC_DEFINE(flags, BT_CONN_NUM_FLAGS); + + /* Which local identity address this connection uses */ + u8_t id; + + #if defined(CONFIG_BT_SMP) || defined(CONFIG_BT_BREDR) + bt_security_t sec_level; + bt_security_t required_sec_level; + u8_t encrypt; + #endif /* CONFIG_BT_SMP || CONFIG_BT_BREDR */ + + /* Connection error or reason for disconnect */ + u8_t err; + + bt_conn_state_t state; + + u16_t rx_len; + struct net_buf *rx; + + /* Sent but not acknowledged TX packets with a callback */ + sys_slist_t tx_pending; + /* Sent but not acknowledged TX packets without a callback before + * the next packet (if any) in tx_pending. + */ + u32_t pending_no_cb; + + /* Completed TX for which we need to call the callback */ + sys_slist_t tx_complete; + struct k_work tx_complete_work; + + + /* Queue for outgoing ACL data */ + struct k_fifo tx_queue; + + /* Active L2CAP channels */ + sys_slist_t channels; + + atomic_t ref; + + /* Delayed work for connection update and other deferred tasks */ + struct k_delayed_work update_work; + + union { + struct bt_conn_le le; + #if defined(CONFIG_BT_BREDR) + struct bt_conn_br br; + struct bt_conn_sco sco; + #endif + }; + + #if defined(CONFIG_BT_REMOTE_VERSION) + struct bt_conn_rv { + u8_t version; + u16_t manufacturer; + u16_t subversion; + } rv; + #endif + }; + +This data structure is the current connection data structure, which includes the parameters related to the BLE connection. After the connection is successful, the data structure can be called by the user. + diff --git a/docs/development_guide_en/build/html/_sources/api_reference/peripheral/api_adc.rst.txt b/docs/development_guide_en/build/html/_sources/api_reference/peripheral/api_adc.rst.txt new file mode 100644 index 00000000..f5bb2b3e --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/api_reference/peripheral/api_adc.rst.txt @@ -0,0 +1,252 @@ +ADC +========================= + +Introduction +------------------------ +ADC (Analog-to-digital Converter) can convert continuous analog signals into discrete digital signals. + +The ADC module in BL MCU series has the following characteristics: + +- Support selecting 12/14/16 bits conversion result output +- ADC maximum working clock is 2MHZ +- Support 2.0V, 3.2V optional internal reference voltage +- DMA support +- Support four modes: single channel single conversion, continuous single channel conversion, single multi-channel conversion and continuous multi-channel conversion mode +- Support both single-ended and differential input modes +- 12 external analog channels +- 2 DAC internal channels +- 1 VBAT /2 channel + +ADC Device Structure Definition +--------------------------------- +.. code-block:: C + + typedef struct adc_device { + struct device parent; + adc_clk_div_t clk_div; + adc_vref_t vref; + bool continuous_conv_mode; + bool differential_mode; + adc_data_width_t data_width; + adc_fifo_threshold_t fifo_threshold; + adc_pga_gain_t gain; + } adc_device_t; + +- **parent** inherits the properties of the parent class +- **clk_div** Partial frequency clock in ADC module +- **vref** 2.0/3.2V reference voltage optional +- **continuous_conv_mode** Whether to select continuous mode. If it is in continuous mode, once adc_start operation, ADC will continue to work until adc_stop. If it is not in continuous mode, adc will only convert the result once every adc_start. +- **differential_mode** Whether it is in differential mode, if it is in differential mode, negative voltage can be measured. +- **data_width** Measurement width selection, the actual accuracy of ADC is 12 bits, but the accuracy of 14bits / 16bits can be achieved by averaging multiple times through OSR. Note that when a higher data width is selected, the frequency will decrease due to averaging. For details, please refer to the enumeration information. +- **fifo_threshold** This parameter affects the DMA handling threshold and ADC FIFO interrupt threshold +- **gain** ADC gain selection for input signal +- Others to be added + +ADC Device Parameter Configuration Table +------------------------------------------ + +Each ADC has a parameter configuration macro, the macro definition is located in the ``peripheral_config.h`` file under the ``bsp/board/xxx`` directory, and the variable definition is located in ``hal_adc.c``, so there is no need for the user to define it by himself . When the user opens the macro of the corresponding device, the configuration of the device will take effect. For example, open the macro ``BSP_USING_ADC0`` to take effect, and at the same time, the ``ADC`` device can be registered and used. + +.. code-block:: C + + /*Parameter configuration macro*/ + #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 + + /*Variable definitions*/ + static adc_device_t adcx_device[ADC_MAX_INDEX] = { + #ifdef BSP_USING_ADC0 + ADC0_CONFIG, + #endif + }; + +.. note:: The above configuration can be modified through ``ADC_DEV(dev)->xxx`` and can only be used before ``device_open``. + +ADC Device Interface +------------------------ + +ADC device interfaces all follow the interfaces provided by the standard device driver management layer. + +**adc_register** +^^^^^^^^^^^^^^^^^^^^^^^^ + +``adc_register`` is used to register an ADC device standard driver interface.Before registering, you need to open the macro definition of the corresponding ADC device. For example, define the macro ``BSP_USING_ADC0`` to use the ``ADC0`` device. After the registration is completed, other interfaces can be used. If no macro is defined, the ``ADC0`` device cannot be used. + +.. code-block:: C + + int adc_register(enum adc_index_type index, const char *name); + +- **index** device index to be registered +- **name** device name to be registered + +``index`` is used to select ADC device configuration, one index corresponds to one ADC device configuration, for example, ``ADC0_INDEX`` corresponds to ``ADC0_CONFIG`` configuration. ``index`` has the following optional types: + +.. code-block:: C + + enum adc_index_type + { + #ifdef BSP_USING_ADC0 + ADC0_INDEX, + #endif + ADC_MAX_INDEX + }; + +**device_open** +^^^^^^^^^^^^^^^^ + +``device_open`` is used to open an ADC device,this funtion calls ``adc_open`` actually. + +.. code-block:: C + + int device_open(struct device *dev, uint16_t oflag); + +- **dev** device handle +- **oflag** open mode +- **return** Error code, 0: open successfully, others: error + +``oflag`` provides the following types + +.. code-block:: C + + #define DEVICE_OFLAG_STREAM_TX 0x001 /* The device is turned on in rotation sending mode */ + #define DEVICE_OFLAG_STREAM_RX 0x002 /* The device is turned on in rotation receiving mode */ + #define DEVICE_OFLAG_INT_TX 0x004 /* The device is turned on in interrupt sending mode */ + #define DEVICE_OFLAG_INT_RX 0x008 /* The device is turned on in interrupt receiving mode */ + #define DEVICE_OFLAG_DMA_TX 0x010 /* The device is turned on in DMA transmission mode */ + #define DEVICE_OFLAG_DMA_RX 0x020 /* The device is turned on in DMA receiving mode */ + +**device_close** +^^^^^^^^^^^^^^^^ + +``device_close`` is used to close an ADC device,this funtion calls ``adc_close`` actually. + +.. code-block:: C + + int device_close(struct device *dev); + +- **dev** device handle +- **return** Error code, 0: open successfully, others: error + +**device_control** +^^^^^^^^^^^^^^^^^^^ + +``device_control`` is used to control and modify the parameters of the adc device according to commands.This funtion calls ``adc_control`` actually. + +.. code-block:: C + + int device_control(struct device *dev, int cmd, void *args); + +- **dev** Device handle +- **cmd** Device control commands +- **args** Control parameter +- **return** Different control commands return different meanings. + +In addition to standard control commands, serial devices also have their own special control commands. + +.. code-block:: C + + #define DEVICE_CTRL_ADC_CHANNEL_START 0x10 + #define DEVICE_CTRL_ADC_CHANNEL_STOP 0x11 + #define DEVICE_CTRL_ADC_CHANNEL_CONFIG 0x12 + #define DEVICE_CTRL_ADC_VBAT_ON 0x13 + #define DEVICE_CTRL_ADC_VBAT_OFF 0x14 + #define DEVICE_CTRL_ADC_TSEN_ON 0x15 + #define DEVICE_CTRL_ADC_TSEN_OFF 0x16 + +``args`` input is different depending on ``cmd``, the list is as follows: + +.. list-table:: table1 + :widths: 15 10 30 + :header-rows: 1 + + * - cmd + - args + - description + * - DEVICE_CTRL_SET_INT + - adc_it_type + - Enable ADC device interrupt + * - DEVICE_CTRL_CLR_INT + - adc_it_type + - Disable ADC device interrupt + * - DEVICE_CTRL_CONFIG + - ADC_param_cfg_t + - Modify ADC configuration + * - DEVICE_CTRL_ADC_CHANNEL_CONFIG + - adc_channel_cfg_t + - Modify ADC channel configuration + * - DEVICE_CTRL_ATTACH_RX_DMA + - struct device* + - Link receiving DMA device + * - DEVICE_CTRL_ADC_CHANNEL_START + - NULL + - Start/continue ADC conversion + * - DEVICE_CTRL_ADC_CHANNEL_STOP + - NULL + - Stop ADC conversion + * - DEVICE_CTRL_ADC_VBAT_ON + - NULL + - Turn on the internal VDD measurement circuit + * - DEVICE_CTRL_ADC_VBAT_OFF + - NULL + - Turn off the internal VDD measurement circuit + * - DEVICE_CTRL_ADC_TSEN_ON + - NULL + - Turn on the internal temperature measurement circuit (requires hardware support) + * - DEVICE_CTRL_ADC_TSEN_OFF + - NULL + - Turn off the internal temperature measurement circuit (requires hardware support) + +**device_read** +^^^^^^^^^^^^^^^^ + +``device_read`` is used to receive the data of ADC device, the receiving mode can be polling, interrupt, dma. + +.. code-block:: C + + int device_read(struct device *dev, uint32_t pos, void *buffer, uint32_t size); + +- **dev** Dvice handle +- **pos** No effect +- **buffer** Buffer to read +- **size** Length to read +- **return** Error code, 0: open successfully, others: error + +**device_set_callback** +^^^^^^^^^^^^^^^^^^^^^^^^ + +``device_set_callback`` is used to register an ADC threshold interrupt callback function. + +.. code-block:: C + + int device_set_callback(struct device *dev, void (*callback)(struct device *dev, void *args, uint32_t size, uint32_t event)); + +- **dev** Device handle +- **callback** The interrupt callback function to be registered + + - **dev** Device handle + - **args** Receive and send buffer, the data type is uint8_t* + - **size** Transmission length + - **event** Type of interrupt event + +``event`` type is as follows: + +.. code-block:: C + + enum ADC_event_type + { + ADC_EVENT_FIFO_READY, + ADC_EVENT_OVERRUN, + ADC_EVENT_UNDERRUN, + }; \ No newline at end of file diff --git a/docs/development_guide_en/build/html/_sources/api_reference/peripheral/api_clock.rst.txt b/docs/development_guide_en/build/html/_sources/api_reference/peripheral/api_clock.rst.txt new file mode 100644 index 00000000..ea6251a1 --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/api_reference/peripheral/api_clock.rst.txt @@ -0,0 +1,63 @@ +Clock tree +========================= + +Introduction +------------------------ + +The BL series chips have a lot of clock source selection and provide a clock tree configuration table to facilitate user configuration. Users do not need to call the clock setting interface. Users only need to care about the final system clock and peripheral clock frequency. The clock configuration table is located in the ``clock_config.h`` file under the ``bsp/board/xxx_board`` directory. + +Clock Frequency Acquisition Interface +--------------------------------------- + +**system_clock_get** +^^^^^^^^^^^^^^^^^^^^^^^^ + +``system_clock_get`` is used to get the system clock frequency. + +.. code-block:: C + + uint32_t system_clock_get(enum system_clock_type type); + +- **type** the type of system clock frequency + +``type`` provide the following types + +.. code-block:: C + + enum system_clock_type + { + SYSTEM_CLOCK_ROOT_CLOCK = 0, + SYSTEM_CLOCK_FCLK, + SYSTEM_CLOCK_BCLK, + SYSTEM_CLOCK_XCLK, + SYSTEM_CLOCK_32K_CLK, + SYSTEM_CLOCK_AUPLL, + }; + + +**peripheral_clock_get** +^^^^^^^^^^^^^^^^^^^^^^^^ + +``peripheral_clock_get`` is used to get the peripheral clock frequency. + +.. code-block:: C + + uint32_t peripheral_clock_get(enum peripheral_clock_type type); + +- **type** peripheral clock frequency type + +``type`` provide the following types + +.. 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, + PERIPHERAL_CLOCK_PWM, + PERIPHERAL_CLOCK_CAM, + }; \ No newline at end of file diff --git a/docs/development_guide_en/build/html/_sources/api_reference/peripheral/api_dac.rst.txt b/docs/development_guide_en/build/html/_sources/api_reference/peripheral/api_dac.rst.txt new file mode 100644 index 00000000..a72cff97 --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/api_reference/peripheral/api_dac.rst.txt @@ -0,0 +1,15 @@ +DAC +========================= + +Introduction +------------------------ + + +DAC Structure Definition +--------------------------- + +DAC Parameter Configuration Table +------------------------------------ + +DAC Device Interface +------------------------ diff --git a/docs/development_guide_en/build/html/_sources/api_reference/peripheral/api_dma.rst.txt b/docs/development_guide_en/build/html/_sources/api_reference/peripheral/api_dma.rst.txt new file mode 100644 index 00000000..b2ce9840 --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/api_reference/peripheral/api_dma.rst.txt @@ -0,0 +1,434 @@ +DMA +========================= + +Introduction +------------------------ + +DMA is a memory access technology that can directly read and write system memory independently without processor intervention. Under the same degree of processor burden, DMA is a fast data transfer method. The DMA device in BL series MCU has the following characteristics: + +- 8 independent dedicated channels +- Four transmission directions: memory to memory, memory to peripheral, peripheral to memory, peripheral to peripheral +- LLI linked list + +DMA Device Structure Definition +---------------------------------- + +.. 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** inherits the properties of the parent class +- **id** DMA id number, default 0, currently there is only one DMA +- **ch** channel number +- **direction** transmission direction +- **transfer_mode** transfer mode +- **src_req** source request +- **dst_req** destination request +- **src_burst_size** source burst bytes +- **dst_burst_size** destination number of burst bytes +- **src_width** source transmission bit width +- **dst_width** destination transmission bit width +- **lli_cfg** used to store some information of the dma channel, the user does not need to worry about it + +``direction`` provides the following types + +.. 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`` provides the following types + +.. code-block:: C + + #define DMA_LLI_ONCE_MODE 0 + #define DMA_LLI_CYCLE_MODE 1 + +``src_req`` provides the following types + +.. 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`` provides the following types + +.. 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`` provides the following types + +.. 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`` provides the following types + +.. 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`` provides the following types + +.. code-block:: C + + #define DMA_TRANSFER_WIDTH_8BIT 0 + #define DMA_TRANSFER_WIDTH_16BIT 1 + #define DMA_TRANSFER_WIDTH_32BIT 2 + +``dst_width``: provide the following types + +.. code-block:: C + + #define DMA_TRANSFER_WIDTH_8BIT 0 + #define DMA_TRANSFER_WIDTH_16BIT 1 + #define DMA_TRANSFER_WIDTH_32BIT 2 + +DMA Device Parameter Configuration Table +------------------------------------------------ + +Each DMA device has a parameter configuration macro, the macro definition is located in the ``peripheral_config.h`` file under the ``bsp/board/xxx`` directory, and the variable definition is located in ``hal_dma.c``, so there is no need for the user himself Define variables. When the user opens the macro of the corresponding device, the configuration of the device will take effect. For example, open the macro ``BSP_USING_DMA0_CH0``, ``DMA0_CH0_CONFIG`` will take effect, and the DMA channel 0 device can be registered and used. + +.. code-block:: C + + /*Parameter configuration macro*/ + #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 + + + /*Variable definitions*/ + 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:: + The above configuration can be modified through ``DMA_DEV(dev)->xxx`` and can only be used before calling ``device_open``. + +DMA Device Interface +------------------------ + +The DMA device interface follows which provided by the standard device driver management layer. In order to facilitate the user to call, some standard interfaces are redefined using macros. + +**dma_register** +^^^^^^^^^^^^^^^^^^^^^^^^ + +``dma_register`` is used to register a DMA device standard driver interface. Before registering, you need to open the channel macro definition of the corresponding DMA device. For example, after defining the macro ``BSP_USING_DMA_CH0``, the 0 channel of the ``DMA`` device can be used. After the registration is completed, other interfaces can be used. If the macro is not defined, the 0 channel of the ``DMA`` device cannot be used. + +.. code-block:: C + + int dma_register(enum dma_index_type index, const char *name); + +- **index** device index to be registered +- **name** device name to be registered + +``index`` is used to select the configuration of a certain channel of DMA, an index corresponds to a channel configuration of a DMA, for example, ``DMA_CH0_INDEX`` corresponds to the configuration of DMA channel 0, and ``index`` has the following optional types + +.. 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`` is used to open a channel of a dma device,this funtion calls ``dma_open`` actually. + +.. code-block:: C + + int device_open(struct device *dev, uint16_t oflag); + +- **dev** device handle +- **oflag** open mode +- **return** Error code, 0 means opening is successful, other means error + +``oflag`` provides the following types + +.. code-block:: C + + #define DEVICE_OFLAG_STREAM_TX 0x001 /* The device is turned on in polling sending mode */ + #define DEVICE_OFLAG_STREAM_RX 0x002 /* The device is turned on in polling receiving mode */ + #define DEVICE_OFLAG_INT_TX 0x004 /* The device is turned on in interrupt sending mode */ + #define DEVICE_OFLAG_INT_RX 0x008 /* The device is turned on in interrupt receiving mode */ + #define DEVICE_OFLAG_DMA_TX 0x010 /* The device is turned on in DMA transmission mode */ + #define DEVICE_OFLAG_DMA_RX 0x020 /* The device is turned on in DMA receiving mode */ + +**device_close** +^^^^^^^^^^^^^^^^ + +``device_close`` is used to close a channel of a dma device,this funtion calls ``dma_close`` actually. + +.. code-block:: C + + int device_close(struct device *dev); + +- **dev** device handle +- **return** error code, 0 means closing is successful, others mean error + +**device_control** +^^^^^^^^^^^^^^^^^^^ + +``device_control`` is used to control and modify the parameters of the dma device according to commands.This funtion calls ``dma_control`` actually. + +.. code-block:: C + + int device_control(struct device *dev, int cmd, void *args); + +- **dev** device handle +- **cmd** device control command +- **args** control parameters +- **return** different control commands return different meanings + +In addition to standard control commands, DMA devices also have their own special control commands. + +.. 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`` input is different depending on ``cmd``, the list is as follows: + +.. list-table:: table1 + :widths: 15 10 30 + :header-rows: 1 + + * - cmd + - args + - description + * - DEVICE_CTRL_SET_INT + - NULL + - Enable DMA transfer completion interrupt + * - DEVICE_CTRL_CLR_INT + - NULL + - Disable DMA transfer completion interrupt + * - DMA_CHANNEL_GET_STATUS + - NULL + - Get DMA channel completion status + * - DMA_CHANNEL_START + - NULL + - Open dma channel + * - DMA_CHANNEL_STOP + - NULL + - Close dma channel + * - DMA_CHANNEL_UPDATE + - NULL + - Update dma transmission configuration + +**device_set_callback** +^^^^^^^^^^^^^^^^^^^^^^^^ + +``device_set_callback`` is used to register a DMA channel interrupt callback function. + +.. code-block:: C + + int device_set_callback(struct device *dev, void (*callback)(struct device *dev, void *args, uint32_t size, uint32_t event)); + +- **dev** Device handle +- **callback** The interrupt callback function to be registered + + - **dev** device handle + - **args** unused + - **size** unused + - **event** interrupt event type + +``event`` type definition is as follows: + +.. code-block:: C + + enum dma_event_type + { + DMA_EVENT_COMPLETE, + }; + + +**dma_channel_start** +^^^^^^^^^^^^^^^^^^^^^^ + +``dma_channel_start`` is used to open the DMA channel. It actually calls ``device_control``, where ``cmd`` is ``DMA_CHANNEL_START``. + +.. code-block:: C + + dma_channel_start(dev) + +- **dev** dma channel handle that needs to be opened + + +**dma_channel_stop** +^^^^^^^^^^^^^^^^^^^^^^ + +``dma_channel_stop`` is used to close the DMA channel. It actually calls ``device_control``, where ``cmd`` is ``DMA_CHANNEL_STOP``. + +.. code-block:: C + + dma_channel_stop(dev) + +- **dev** dma channel handle that needs to be closed + + +**dma_channel_update** +^^^^^^^^^^^^^^^^^^^^^^^ + +``dma_channel_update`` is used to update the DMA configuration. The actual call is ``device_control``, where ``cmd`` is ``DMA_CHANNEL_UPDATE``. + +.. code-block:: C + + dma_channel_update(dev,list) + +- **dev** dma channel handle that needs to be updated +- **list** dma_lli_ctrl_t handle + + +**dma_channel_check_busy** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``dma_channel_check_busy`` is used to query whether the currently used DMA channel has completed the transfer. It actually calls ``device_control``, where ``cmd`` is ``DMA_CHANNEL_GET_STATUS``. + +.. code-block:: C + + dma_channel_check_busy(dev) + +- **dev** DMA channel handle to be queried +- **return** return the current DMA status, 0 means the transfer is complete, 1 means the transfer is not complete + +**dma_reload** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``dma_reload`` is used to update the configuration of a certain channel of DMA. Compared with ``dma_channel_update``, this function does not require the user to pass many parameters, but only needs to fill in the source address, destination address, and length. After this function is called, the DMA channel is not turned on. You need to manually call the ``dma_channel_start`` function. + +.. code-block:: C + + int dma_reload(struct device *dev, uint32_t src_addr, uint32_t dst_addr, uint32_t transfer_size); + +- **dev** DMA channel handle to be queried +- **src_addr** transmission source address +- **dst_addr** transmission destination address +- **transfer_size** the total length of transferred bytes. If the number of bits transferred is 16 bits or 32 bits, it needs to be converted into byte length here. + diff --git a/docs/development_guide_en/build/html/_sources/api_reference/peripheral/api_gpio.rst.txt b/docs/development_guide_en/build/html/_sources/api_reference/peripheral/api_gpio.rst.txt new file mode 100644 index 00000000..9d528791 --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/api_reference/peripheral/api_gpio.rst.txt @@ -0,0 +1,114 @@ +GPIO +========================= + +Introduction +------------------------ + +The full name of GPIO is General Purpose Input Output. The GPIO peripherals of BL series chips mainly have the following functions. + +- General input and output pull-up and pull-down +- Multiplex function pull-up and pull-down +- Simulation function +- External interrupt (rising edge, falling edge, high level, low level) +- Hardware eliminate jitter +- Drive capacity control + +The pin configuration of bl mcu sdk is divided into two kinds. + +- GPIO multiplexing function is through a special **pinmux table**, users only need to modify the functions of related pins in the table, and the program will automatically configure these pins. **pinmux table** is located in the ``pinmux_config.h`` file under the ``bsp/board/xxx_board`` directory. +- Configure the pins through the standard GPIO device interface. The disadvantage is that only common input and output and interrupt functions can be configured. It is recommended to use the table to configure the multiplexing functions. + +GPIO Device Interface +------------------------ + +**gpio_set_mode** +^^^^^^^^^^^^^^^^^^^^^^^^ + +``gpio_set_mode`` is used to configure the mode of gpio. + +.. code-block:: C + + void gpio_set_mode(uint32_t pin, uint32_t mode); + +- **pin** the pin to be configured +- **mode** pin function to be configured + +``mode`` provides the following types + +.. 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`` is used to set pin level + +.. code-block:: C + + void gpio_write(uint32_t pin, uint32_t value); + + +- **pin** the pin to be set +- **value** the level to be set + +**gpio_toggle** +^^^^^^^^^^^^^^^^^^^^^^^^ + +``gpio_toggle``: is used to toggle pin level + +.. code-block:: C + + void gpio_toggle(uint32_t pin); + +- pin: the pin to be toggled + +**gpio_read** +^^^^^^^^^^^^^^^^^^^^^^^^ + +``gpio_read`` is used to read pin level + +.. code-block:: C + + int gpio_read(uint32_t pin); + + +- **pin** the pin to read the level +- **return** 0 is low level, 1 is high level + +**gpio_attach_irq** +^^^^^^^^^^^^^^^^^^^^^^^^ + +``gpio_attach_irq`` is used to attache an interrupt callback function to the interrupt pin + +.. code-block:: C + + void gpio_attach_irq(uint32_t pin, void (*cbfun)(uint32_t pin)); + +- **pin** the pin to which the interrupt callback is attached +- **cbfun** register interrupt callback + +**gpio_irq_enable** +^^^^^^^^^^^^^^^^^^^^^^^^ + +``gpio_irq_enable`` is used to enable gpio interrupt + +.. code-block:: C + + void gpio_irq_enable(uint32_t pin,uint8_t enabled); + +- **pin** the pin to turn on or off the interrupt +- **enabled** 0 is to close the interrupt, 1 is to open the interrupt diff --git a/docs/development_guide_en/build/html/_sources/api_reference/peripheral/api_i2c.rst.txt b/docs/development_guide_en/build/html/_sources/api_reference/peripheral/api_i2c.rst.txt new file mode 100644 index 00000000..5c3d8c8f --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/api_reference/peripheral/api_i2c.rst.txt @@ -0,0 +1,160 @@ +I2C +========================= + +Introduction +------------------------ + +I2C (Inter-Intergrated Circuit) is a serial communication bus that uses a multi-master-slave architecture to connect low-speed peripheral devices. Each device has a unique address identification, and can be used as a transmitter or receiver. Each device connected to the bus can set the address with software through a unique address and the always-existing relationship between master and slave, and the host can be used as a host transmitter or host receiver. If two or more hosts are initialized at the same time, data transmission can prevent data from being destroyed through conflict detection and arbitration. The I2C devices in the BL series MCU have the following characteristics: + +- Flexible configuration of slave address ``slaveAddr``, register address ``subAddr`` +- Clock frequency that can be flexibly adjusted +- Support polling, interrupt, DMA transfer + + +I2C Device Structure Definition +---------------------------------- + +.. code-block:: C + + typedef struct i2c_device + { + struct device parent; + uint8_t id; + uint8_t mode; + uint32_t phase; + } i2c_device_t; + +- **parent** inherit the properties of the parent class +- **ch** i2c id, 0 means i2c0, 1 means i2c1 +- **mode** i2c transmission mode, 0 means using hardware i2c, 1 means using software i2c, current software i2c is temporarily invalid +- **phase** i2c clock phase div, i2c_clk = i2c_source_clk/(4*(phase+1)) +- TODO + +I2C Device Parameter Configuration Table +-------------------------------------------- + +Each I2C device has a parameter configuration macro, the macro definition is located in the ``peripheral_config.h`` file under the ``bsp/board/xxx`` directory, and the variable definition is located in ``hal_i2c.c``, so the user does not need to define variable. When the user opens the macro of the corresponding device, the configuration of the device will take effect. For example, open the macro ``BSP_USING_I2C0``, ``I2C0_CONFIG`` will take effect, and the ``I2C`` device can be registered and used. + +.. code-block:: C + + /*Parameter configuration macro*/ + #if defined(BSP_USING_I2C0) + #ifndef I2C0_CONFIG + #define I2C0_CONFIG \ + { \ + .id = 0, \ + .mode = I2C_HW_MODE,\ + .phase = 15, \ + } + #endif + #endif + + /*Variable definition*/ + static i2c_device_t i2cx_device[I2C_MAX_INDEX] = + { + #ifdef BSP_USING_I2C0 + I2C0_CONFIG, + #endif + }; + +.. note:: + The above configuration can be modified through ``I2C_DEV(dev)->xxx`` and can only be used before calling ``device_open``. + +I2C Device Interface +------------------------ + +The I2C device standard interface currently only uses ``device_open``, and provides a standard data transceiver interface. + +**i2c_register** +^^^^^^^^^^^^^^^^^^^^^^^^ + +``i2c_register`` is used to register an I2C device standard driver interface. The macro definition of the corresponding I2C device needs to be opened before registration. For example, define the macro ``BSP_USING_I2C0`` to use the ``I2C0`` device. After the registration is completed, other interfaces can be used. If the macro is not defined, the ``I2C0`` device cannot be used. + +.. code-block:: C + + int i2c_register(enum i2c_index_type index, const char *name); + +- **index** device index to be registered +- **name** device name to be registered + +``index`` is used to select I2C device, one index corresponds to one I2C device configuration, for example, ``I2C0_INDEX`` corresponds to ``I2C0_CONFIG`` configuration, ``index`` has the following optional types + +.. code-block:: C + + enum i2c_index_type + { + #ifdef BSP_USING_I2C0 + I2C0_INDEX, + #endif + I2C_MAX_INDEX + }; + +**device_open** +^^^^^^^^^^^^^^^^ + +``device_open`` is used to open an i2c device, this funtion calls ``i2c_open`` actually. + +.. code-block:: C + + int device_open(struct device *dev, uint16_t oflag); + +- **dev** device handle +- **oflag** open mode +- **return** error code, 0 means opening is successful, others mean errors + +``oflag`` provides the following types + +.. code-block:: C + + #define DEVICE_OFLAG_STREAM_TX 0x001 /* The device is turned on in polling sending mode */ + #define DEVICE_OFLAG_STREAM_RX 0x002 /* The device is turned on in polling receiving mode */ + #define DEVICE_OFLAG_INT_TX 0x004 /* The device is turned on in interrupt sending mode */ + #define DEVICE_OFLAG_INT_RX 0x008 /* The device is turned on in interrupt receiving mode */ + #define DEVICE_OFLAG_DMA_TX 0x010 /* The device is turned on in DMA transmission mode */ + #define DEVICE_OFLAG_DMA_RX 0x020 /* The device is turned on in DMA receiving mode */ + +**i2c_transfer** +^^^^^^^^^^^^^^^^ + +``i2c_transfer`` is used to transfer i2c msg. The member ``flags`` in ``i2c_msg_t`` structure indicates whether the direction of the transfer is writing or reading, and the length of the specified register address is 0, 1, 2. + +.. code-block:: C + + int i2c_transfer(struct device *dev, i2c_msg_t msgs[], uint32_t num); + +- **dev** device handle +- **msgs** message to be transmitted +- **num** the number of messages +- **return** error code, 0 means opening is successful, others mean error + +``i2c_msg_t`` structure is defined as follows: + +.. 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 slave device 7-bit slave address +- **subaddr** i2c slave device register address +- **flags** read and write mode and register address length +- **len** transmission data length +- **buf** data buffer + +``flags`` definition is as follows: + +.. code-block:: C + + /*Read and write mode*/ + #define I2C_WR 0x0000 + #define I2C_RD 0x0001 + + /*Register address length*/ + #define SUB_ADDR_0BYTE 0x0010 + #define SUB_ADDR_1BYTE 0x0020 + #define SUB_ADDR_2BYTE 0x0040 \ No newline at end of file diff --git a/docs/development_guide_en/build/html/_sources/api_reference/peripheral/api_pwm.rst.txt b/docs/development_guide_en/build/html/_sources/api_reference/peripheral/api_pwm.rst.txt new file mode 100644 index 00000000..13516655 --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/api_reference/peripheral/api_pwm.rst.txt @@ -0,0 +1,283 @@ +PWM +========================= + +Introduction +------------------------ + +PWM is a technology that implements analog voltage control in a digital way. It modulates the width of a series of pulses, equivalent to the required waveform (including shape and amplitude), and digitally encodes the analog signal level. That is to say, by adjusting the change of the duty cycle to adjust the change of the signal, energy, etc. The duty cycle refers to the percentage of the entire signal period when the signal is at a high level. For example, the duty cycle of a square wave is 50%. The DMA device in BL series MCU has the following characteristics: + +- Support 5-channel PWM +- Three clock sources can be selected (bus clock , crystal oscillator clock , slow clock <32k>), with 16-bit clock divider +- Double threshold domain setting, increase pulse flexibility + +PWM Device Structure Definition +--------------------------------- + +.. code-block:: C + + typedef struct pwm_device { + struct device parent; + uint8_t ch; + uint8_t polarity_invert_mode; + uint16_t period; + uint16_t threshold_low; + uint16_t threshold_high; + uint16_t it_pulse_count; + + } pwm_device_t; + +- **parent** inherit the properties of the parent class +- **ch** channel number, ch is 0 if PWM channel 0 is enabled, ch is 1 if PWM channel 1 is enabled, and so on +- **polarity_invert_mode** polarity invert enable +- **period** PWM period value +- **threshold_low** PWM low threshold +- **threshold_high** PWM high threshold +- **it_pulse_count** The cycle count value that triggered the interrupt condition + +.. note:: + PWM actual frequency = pwm_clock_source/frequency_division/period, period is not the actual PWM period,it just has the same name. + +.. note:: PWM Duty cycle = (threshold_high-threshold_low)/period * 100% + +PWM Device Parameter Configuration Table +------------------------------------------ + +Each PWM device has a parameter configuration macro, the macro definition is located in the ``peripheral_config.h`` file under the ``bsp/board/xxx`` directory, and the variable definition is located in ``hal_pwm.c``, so the user does not need to define variable. When the user opens the macro of the corresponding device, the configuration of the device will take effect. For example, open the macro ``BSP_USING_PWM_CH2``, and ``PWM_CH2_CONFIG`` will take effect, and at the same time, channel 2 of the ``PWM`` device can be registered and used. + +.. code-block:: C + + /*Parameter configuration macro*/ + #if defined(BSP_USING_PWM_CH2) + #ifndef PWM_CH2_CONFIG + #define PWM_CH2_CONFIG \ + { \ + .ch = 2, \ + .polarity_invert_mode = DISABLE, \ + .period = 0, \ + .threshold_low = 0, \ + .threshold_high = 0, \ + .it_pulse_count = 0, \ + } + #endif + #endif + + + /*Variable definitions*/ + 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:: + The above configuration can be modified through ``PWM_DEV(dev)->xxx``, and can only be used before calling ``device_open``. + +PWM device interface +------------------------ + +The PWM device interfaces all follow the interfaces provided by the standard device driver management layer. And in order to facilitate the user to call, some standard interfaces are redefined using macros. + +**pwm_register** +^^^^^^^^^^^^^^^^^^^^^^^^ + +``pwm_register`` is used to register a channel of the PWM device standard driver interface. Before registering, you need to open the macro definition of a certain channel of the corresponding PWM device. For example, define ``BSP_USING_PWM_CH0`` before you can use the ``PWM`` channel 0 device. After the registration is completed, other interfaces can be used. If no macro is defined, the PWM device cannot be used. + +.. code-block:: C + + int pwm_register(enum pwm_index_type index, const char *name); + +- **index** the index of the device to be registered +- **name** name the registered device + +``index`` is used to select the configuration of a certain channel of the PWM device. An index corresponds to a channel configuration of a PWM device. For example, ``PWM_CH0_INDEX`` corresponds to the configuration of PWM channel 0, and ``index`` has the following optional types: + +.. 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`` is used to open a channel of a pwm device,this funtion calls ``pwm_open`` actually. + +.. code-block:: C + + int device_open(struct device *dev, uint16_t oflag); + +- **dev** device handle +- **oflag** open mode +- **return** error code, 0 means opening is successful, others mean errors + +``oflag`` provides the following types + +.. code-block:: C + + #define DEVICE_OFLAG_STREAM_TX 0x001 /* The device is turned on in polling sending mode */ + #define DEVICE_OFLAG_STREAM_RX 0x002 /* The device is turned on in polling receiving mode */ + #define DEVICE_OFLAG_INT_TX 0x004 /* The device is turned on in interrupt sending mode */ + #define DEVICE_OFLAG_INT_RX 0x008 /* The device is turned on in interrupt receiving mode */ + #define DEVICE_OFLAG_DMA_TX 0x010 /* The device is turned on in DMA transmission mode */ + #define DEVICE_OFLAG_DMA_RX 0x020 /* The device is turned on in DMA receiving mode */ + +**device_close** +^^^^^^^^^^^^^^^^ + +``device_close`` is used to close a channel of a pwm device.this funtion calls ``pwm_close`` actually. + +.. code-block:: C + + int device_close(struct device *dev); + +- **dev** device handle +- **return** error code, 0 means closing is successful, others mean error + +**device_control** +^^^^^^^^^^^^^^^^^^^ + +``device_control`` is used to control and modify the parameters of the PWM device according to commands.This funtion calls ``pwm_control`` actually. + +.. code-block:: C + + int device_control(struct device *dev, int cmd, void *args); + +- **dev** device handle +- **cmd** device control command +- **args** control parameters +- **return** different control commands return different meanings + +In addition to standard control commands, PWM devices also have their own special control commands. + +.. code-block:: C + + #define DEIVCE_CTRL_PWM_IT_PULSE_COUNT_CONFIG 0x10 + +``args`` input is different depending on ``cmd``, the list is as follows: + +.. list-table:: table1 + :widths: 15 10 30 + :header-rows: 1 + + * - cmd + - args + - description + * - DEVICE_CTRL_RESUME + - NULL + - Enable the current PWM channel + * - DEVICE_CTRL_SUSPEND + - NULL + - Disable the current PWM channel + * - DEVICE_CTRL_PWM_FREQUENCE_CONFIG + - uint32_t + - Configure the current PWM channel period + * - DEVICE_CTRL_PWM_DUTYCYCLE_CONFIG + - pwm_dutycycle_config_t + - Configure the current PWM channel duty cycle + * - DEVICE_CTRL_PWM_IT_PULSE_COUNT_CONFIG + - uint32_t + - Configure the trigger PWM interrupt period value + +**device_set_callback** +^^^^^^^^^^^^^^^^^^^^^^^^ + +``device_set_callback`` is used to register a PWM channel interrupt callback function. + +.. code-block:: C + + int device_set_callback(struct device *dev, void (*callback)(struct device *dev, void *args, uint32_t size, uint32_t event)); + +- **dev** device handle +- **callback** the interrupt callback function to be registered + + - **dev** device handle + - **args** unused + - **size** unused + - **event** interrupt event type + +``event`` type definition is as follows: + +.. code-block:: C + + enum pwm_event_type + { + PWM_EVENT_COMPLETE, + }; + +**pwm_channel_start** +^^^^^^^^^^^^^^^^^^^^^^ + +``pwm_channel_start`` is used to start the PWM channel. It actually calls ``device_control``, where ``cmd`` is ``DEVICE_CTRL_RESUME``. + +.. code-block:: C + + pwm_channel_start(dev) + +- **dev** pwm channel handle that needs to be opened + + +**pwm_channel_stop** +^^^^^^^^^^^^^^^^^^^^^^ + +``pwm_channel_stop`` is used to close the PWM channel. It actually calls ``device_control``, where ``cmd`` is ``DEVICE_CTRL_SUSPEND``. + +.. code-block:: C + + pwm_channel_stop(dev) + +- **dev** pwm channel handle that needs to be closed + + +**pwm_channel_update** +^^^^^^^^^^^^^^^^^^^^^^^ + +``pwm_channel_update`` is used to update the frequency and duty cycle of the PWM channel. The actual call is ``device_control``, where ``cmd`` is ``DEVICE_CTRL_CONFIG``. + +.. code-block:: C + + pwm_channel_update(dev,cfg) + +- **dev** pwm channel handle that needs to be updated +- **cfg** pwm_config_t handle + + +**pwm_it_pulse_count_update** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``pwm_it_pulse_count_update`` is used to update the count value of the PWM channel. The PWM interrupt needs to be enabled before it takes effect. When the PWM count reaches the set period count value, an interrupt will be generated. The actual call is ``device_control``, where ``cmd`` is ``DEIVCE_CTRL_PWM_IT_PULSE_COUNT_CONFIG``. + +.. code-block:: C + + pwm_it_pulse_count_update(dev,count) + +- **dev** pwm channel handle that needs to update the cycle count value +- **count** cycle count value + diff --git a/docs/development_guide_en/build/html/_sources/api_reference/peripheral/api_spi.rst.txt b/docs/development_guide_en/build/html/_sources/api_reference/peripheral/api_spi.rst.txt new file mode 100644 index 00000000..ac1255b1 --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/api_reference/peripheral/api_spi.rst.txt @@ -0,0 +1,363 @@ +SPI +========================= + +Introduction +------------------------ + +Serial Peripheral Interface Bus (SPI) is a synchronous serial communication interface specification for short-range communication. The full-duplex communication mode is used between devices, which is a master-slave mode of one master and one or more slaves, and requires at least 4 wires. In fact, 3 wires are also available (when transmitting in one direction), including SDI (data input), SDO (data output), SCLK (clock), CS (chip select). The SPI devices in the BL series MCU have the following characteristics: + +- It can be used as both SPI master and SPI slave. +- The transmit and receive channels each have a FIFO with a depth of 4 words +- Both master and slave devices support 4 clock formats (CPOL, CPHA) +- Both master and slave devices support 1/2/3/4 byte transmission mode +- Flexible clock configuration, up to 40M clock +- Configurable MSB/LSB priority transmission +- Receive filter function +- Timeout mechanism under slave device +- Support polling, interrupt, DMA transfer + +SPI Device Structure Definition +---------------------------------- + +.. 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** inherit the properties of the parent class +- **id** SPI id, 0 means SPI0 +- **clk** SPI clock frequency +- **mode** master mode or slave mode +- **direction** transmission first mode +- **clk_polaraity** clock polarity +- **clk_phase** clock phase +- **datasize** data transmission bit width +- **fifo_threshold** fifo threshold, the maximum is 4 +- **tx_dma** additional send dma handle +- **rx_dma** dditional receive dma handle + +``mode`` provides the following types + +.. code-block:: C + + #define SPI_SLVAE_MODE 0 + #define SPI_MASTER_MODE 1 + +``direction`` provides the following types + +.. 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`` provides the following types + +.. code-block:: C + + #define SPI_POLARITY_LOW 0 + #define SPI_POLARITY_HIGH 1 + +``clk_phase`` provides the following types + +.. code-block:: C + + #define SPI_PHASE_1EDGE 0 + #define SPI_PHASE_2EDGE 1 + + +``datasize`` provides the following types + +.. code-block:: C + + #define SPI_DATASIZE_8BIT 0 + #define SPI_DATASIZE_16BIT 1 + #define SPI_DATASIZE_24BIT 2 + #define SPI_DATASIZE_32BIT 3 + +SPI Device Parameter Configuration Table +------------------------------------------ + +Each SPI device has a parameter configuration macro, the macro definition is located in the ``peripheral_config.h`` file under the ``bsp/board/xxx`` directory, and the variable definition is located in ``hal_spi.c``, so the user does not need to define variable. When the user opens the macro of the corresponding device, the configuration of the device will take effect. For example, open the macro ``BSP_USING_SPI0``, ``SPI0_CONFIG`` will take effect, and the ``SPI0`` device can be registered and used. + +.. code-block:: C + + /*Parameter configuration macro*/ + #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 + + /*Variable definition*/ + static spi_device_t spix_device[SPI_MAX_INDEX] = + { + #ifdef BSP_USING_SPI0 + SPI0_CONFIG, + #endif + }; + +.. note:: + The above configuration can be modified through ``SPI_DEV(dev)->xxx`` and can only be used before calling ``device_open``. + + +SPI Device Interface +------------------------ + +SPI device interface follows which provided by the standard device driver management layer. + +**spi_register** +^^^^^^^^^^^^^^^^^^^^^^^^ + +``spi_register`` is used to register an SPI device standard driver interface. Before registering, you need to open the macro definition of the corresponding SPI device. For example, define the macro ``BSP_USING_SPI0`` before you can use the SPI0 device. After the registration is completed, other interfaces can be used. If no macro is defined, the SPI device cannot be used. + +.. code-block:: C + + int spi_register(enum spi_index_type index, const char *name); + +- **index** device index to be registered +- **name** device name to be registered + +``index`` is used to select SPI device configuration, one index corresponds to one SPI device configuration, for example, ``SPI0_INDEX`` corresponds to ``SPI0_CONFIG`` configuration, and ``index`` has the following optional types + +.. code-block:: C + + enum spi_index_type + { + #ifdef BSP_USING_SPI0 + SPI0_INDEX, + #endif + SPI_MAX_INDEX + }; + +**device_open** +^^^^^^^^^^^^^^^^ + +``device_open`` is used to open the device,this funtion calls ``spi_open`` actually. + +.. code-block:: C + + int device_open(struct device *dev, uint16_t oflag); + +- **dev** device handle +- **oflag** open mode +- **return** error code, 0 means opening is successful, others mean errors + +``oflag`` provides the following types + +.. code-block:: C + + #define DEVICE_OFLAG_STREAM_TX 0x001 /* The device is turned on in polling sending mode */ + #define DEVICE_OFLAG_STREAM_RX 0x002 /* The device is turned on in polling receiving mode */ + #define DEVICE_OFLAG_INT_TX 0x004 /* The device is turned on in interrupt sending mode */ + #define DEVICE_OFLAG_INT_RX 0x008 /* The device is turned on in interrupt receiving mode */ + #define DEVICE_OFLAG_DMA_TX 0x010 /* The device is turned on in DMA transmission mode */ + #define DEVICE_OFLAG_DMA_RX 0x020 /* The device is turned on in DMA receiving mode */ + +**device_close** +^^^^^^^^^^^^^^^^ + +``device_close`` is used to close the device,this funtion calls ``spi_close`` actually. + +.. code-block:: C + + int device_close(struct device *dev); + +- **dev** device handle +- **return** error code, 0 means closing is successful, others means error + +**device_control** +^^^^^^^^^^^^^^^^^^^ + +``device_control`` is used to control the device and modify parameters according to commands.This funtion calls ``spi_control`` actually. + +.. code-block:: C + + int device_control(struct device *dev, int cmd, void *args); + +- **dev** device handle +- **cmd** device control command +- **args** control parameters +- **return** Different control commands return different meanings. + +In addition to standard control commands, SPI devices also have their own special control commands. + +.. code-block:: C + + #define DEVICE_CTRL_SPI_CONFIG_CLOCK 0x10 + +``args`` input is different depending on ``cmd``, the list is as follows: + +.. list-table:: table1 + :widths: 15 10 30 + :header-rows: 1 + + * - cmd + - args + - description + * - DEVICE_CTRL_SET_INT + - NULL + - Enable spi device interrupt + * - DEVICE_CTRL_CLR_INT + - NULL + - Disable spi device interrupt + * - DEVICE_CTRL_RESUME + - NULL + - Resume spi device + * - DEVICE_CTRL_SUSPEND + - NULL + - Suspend spi device + * - DEVICE_CTRL_ATTACH_TX_DMA + - NULL + - Link to tx dma device + * - DEVICE_CTRL_ATTACH_RX_DMA + - NULL + - Link to rx dma device + * - DEVICE_CTRL_SPI_CONFIG_CLOCK + - NULL + - Modify SPI device clock + * - DEVICE_CTRL_TX_DMA_SUSPEND + - NULL + - Suspend spi tx dma mode + * - DEVICE_CTRL_RX_DMA_SUSPEND + - NULL + - Suspend spi rx dma mode + * - DEVICE_CTRL_TX_DMA_RESUME + - NULL + - Resume spi tx dma mode + * - DEVICE_CTRL_RX_DMA_RESUME + - NULL + - Resume spi rx dma mode + +**device_write** +^^^^^^^^^^^^^^^^ + +``device_write`` is used to send data. The sending mode can be polling, interrupt, dma according to the open mode.This funtion calls ``spi_write`` actually. + +.. code-block:: C + + int device_write(struct device *dev, uint32_t pos, const void *buffer, uint32_t size); + +- **dev** device handle +- **pos** useless +- **buffer** the buffer to be written +- **size** the length to be written +- **return** error code, 0 means writing is successful, others mean errors + +**device_read** +^^^^^^^^^^^^^^^^ + +``device_read`` is used to receive data, and the receiving mode can be polling, interrupt, dma according to the open mode.This funtion calls ``spi_read`` actually. + +.. code-block:: C + + int device_read(struct device *dev, uint32_t pos, void *buffer, uint32_t size); + +- **dev** device handle +- **pos** useless +- **buffer** the buffer to be read +- **size** the length to be read +- **return** error code, 0 means successful reading, others mean errors + +**device_set_callback** +^^^^^^^^^^^^^^^^^^^^^^^^ + +``device_set_callback`` is used to register an SPI device interrupt callback function. + +.. code-block:: C + + int device_set_callback(struct device *dev, void (*callback)(struct device *dev, void *args, uint32_t size, uint32_t event)); + +- **dev** device handle +- **callback** the interrupt callback function to be registered + + - **dev** device handle + - **args** receive and send buffer, the data type is uint8_t* + - **size** transmission length + - **event** interrupt event type + +``event`` type definition is as follows: + +.. code-block:: C + + enum spi_event_type + { + SPI_EVENT_TX_FIFO, + SPI_EVENT_RX_FIFO, + SPI_EVENT_UNKNOWN + }; + +**spi_transmit** +^^^^^^^^^^^^^^^^^^^^^^^^ + +``spi_transmit`` is used to send data from SPI devices. + +.. code-block:: C + + int spi_transmit(struct device *dev, void *buffer, uint32_t size, uint8_t type); + +- **dev** device handle +- **buffer** send data buffer +- **size** send length +- **type** send bit width type + +``type`` provides the following types + +.. 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`` is used to receive data from SPI devices. + +.. code-block:: C + + int spi_receive(struct device *dev, void *buffer, uint32_t size, uint8_t type); + +- **dev** device handle +- **buffer** receive data buffer +- **size** receiving length +- **type** bit width type + +**spi_transmit_receive** +^^^^^^^^^^^^^^^^^^^^^^^^ + +``spi_transmit_receive`` is used to send and receive data from SPI devices. + +.. code-block:: C + + int spi_transmit_receive(struct device *dev, const void *send_buf, void *recv_buf, uint32_t length, uint8_t type); + +- **dev** device handle +- **send_buf** send data buffer +- **recv_buf** receive data buffer +- **length** send and receive length +- **type** bit width type diff --git a/docs/development_guide_en/build/html/_sources/api_reference/peripheral/api_timer.rst.txt b/docs/development_guide_en/build/html/_sources/api_reference/peripheral/api_timer.rst.txt new file mode 100644 index 00000000..595f470b --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/api_reference/peripheral/api_timer.rst.txt @@ -0,0 +1,282 @@ +TIMER +========================= + +Introduction +------------------------ + +The TIMER device in BL series MCU has the following characteristics: + +- Multiple clock source options +- 8-bit clock divider, the division factor is 1-256 +- Two 32-bit timers +- Each timer can independently set three groups of alarm values +- Support FreeRun mode and PreLoad mode +- 16-bit watchdog +- Support write protection to prevent system abnormalities caused by incorrect settings +- Support two watchdog overflow modes, interrupt or reset + +TIMER Device Structure Definition +------------------------------------ + +.. code-block:: C + + typedef struct timer_device { + struct device parent; + uint8_t id; + enum timer_cnt_mode_type cnt_mode; + enum timer_preload_trigger_type trigger; + uint32_t reload; + uint32_t timeout1; + uint32_t timeout2; + uint32_t timeout3; + } timer_device_t; + +- **parent** inherit the properties of the parent class +- **id** timer id +- **cnt_mode** counting mode:FreeRun and preload +- **trigger** source of preload comparator +- **reload** reload value in preload mode +- **timeout1** compare source 0 timout value ,unit is us +- **timeout2** compare source 1 timout value ,unit is us +- **timeout3** compare source 2 timout value ,unit is us + +``ch`` provides the following types + +.. code-block:: C + + enum timer_index_type { + TIMER0_INDEX, + TIMER1_INDEX, + TIMER_MAX_INDEX + }; + +``cnt_mode`` provides the following types + +.. code-block:: C + + enum timer_cnt_mode_type { + TIMER_CNT_PRELOAD, + TIMER_CNT_FREERUN, + }; + +``pl_trig_src`` provides the following types + +.. code-block:: C + + enum timer_preload_trigger_type { + TIMER_PRELOAD_TRIGGER_NONE, + TIMER_PRELOAD_TRIGGER_COMP0, + TIMER_PRELOAD_TRIGGER_COMP1, + TIMER_PRELOAD_TRIGGER_COMP2, + }; + +TIMER Device Parameter Configuration Table +--------------------------------------------- + +Each TIMER has a parameter configuration macro, the macro definition is located in the ``peripheral_config.h`` file under the ``bsp/board/xxx`` directory, and the variable definition is located in ``hal_timer.c``, so the user does not need to define the variable . When the user opens the macro of the corresponding device, the configuration of the device will take effect. For example, open the macro ``BSP_USING_TIMER_CH0``, ``TIMER_CH0_CONFIG`` will take effect, and the ``TIMER_CH0_INDEX`` device can be registered and used. + +.. code-block:: C + + /*Parameter configuration macro*/ + #if defined(BSP_USING_TIMER0) + #ifndef TIMER0_CONFIG + #define TIMER0_CONFIG \ + { \ + .id = 0, \ + .cnt_mode = TIMER_CNT_PRELOAD, \ + .trigger = TIMER_PRELOAD_TRIGGER_COMP2, \ + .reload = 0, \ + .timeout1 = 1000000, \ + .timeout2 = 2000000, \ + .timeout3 = 3000000, \ + } + #endif + #endif + + #if defined(BSP_USING_TIMER1) + #ifndef TIMER1_CONFIG + #define TIMER1_CONFIG \ + { \ + .id = 1, \ + .cnt_mode = TIMER_CNT_PRELOAD, \ + .trigger = TIMER_PRELOAD_TRIGGER_COMP0, \ + .reload = 0, \ + .timeout1 = 1000000, \ + .timeout2 = 2000000, \ + .timeout3 = 3000000, \ + } + #endif + #endif + + /*Variable definitions*/ + static timer_device_t timerx_device[TIMER_MAX_INDEX] = { + #ifdef BSP_USING_TIMER0 + TIMER0_CONFIG, + #endif + #ifdef BSP_USING_TIMER1 + TIMER1_CONFIG, + #endif + }; + +.. note:: + The above configuration can be modified through ``TIMER_DEV(dev)->xxx`` and can only be used before calling ``device_open``. + +TIMER Device Interface +------------------------ + +TIMER device interface follows which provided by the standard device driver management layer. + +**timer_register** +^^^^^^^^^^^^^^^^^^^^^^^^ + +``timer_register`` is used to register a TIMER device standard driver interface. Before registering, you need to open the macro definition of the corresponding TIMER device. For example, define the macro ``BSP_USING_TIMER_CH0`` to use the ``TIMER_CH0_INDEX`` device. After the registration is completed, other interfaces can be used. If the macro is not defined, the ``TIMER_CH0_INDEX`` device cannot be used. + +.. code-block:: C + + int timer_register(enum timer_index_type index, const char *name); + +- **index** the index of the device to be registered +- **name** Name the device + +``index`` is used to select TIMER device configuration, one index corresponds to a TIMER device configuration, for example, ``TIMER_CH0_INDEX`` corresponds to ``TIMER_CH0_CONFIG`` configuration, and ``index`` has the following optional types + +.. code-block:: C + + enum timer_index_type { + #ifdef BSP_USING_TIMER0 + TIMER0_INDEX, + #endif + #ifdef BSP_USING_TIMER1 + TIMER1_INDEX, + #endif + TIMER_MAX_INDEX + }; + +**device_open** +^^^^^^^^^^^^^^^^ + +``device_open`` is used to open a TIMER device, this funtion calls ``timer_open`` actually. + +.. code-block:: C + + int device_open(struct device *dev, uint16_t oflag); + +- **dev** device handle +- **oflag** open method +- **return** error code, 0 means opening is successful, others mean error + +``oflag`` provides the following types + +.. code-block:: C + + #define DEVICE_OFLAG_STREAM_TX 0x001 /* The device is turned on in polling sending mode */ + #define DEVICE_OFLAG_STREAM_RX 0x002 /* The device is turned on in polling receiving mode */ + #define DEVICE_OFLAG_INT_TX 0x004 /* The device is turned on in interrupt sending mode */ + #define DEVICE_OFLAG_INT_RX 0x008 /* The device is turned on in interrupt receiving mode */ + #define DEVICE_OFLAG_DMA_TX 0x010 /* The device is turned on in DMA transmission mode */ + #define DEVICE_OFLAG_DMA_RX 0x020 /* The device is turned on in DMA receiving mode */ + +**device_close** +^^^^^^^^^^^^^^^^ + +``device_close`` is used to close a TIMER device,this funtion calls ``timer_open`` actually. + +.. code-block:: C + + int device_close(struct device *dev); + +- **dev** device handle +- **return** error code, 0 means closing is successful, others mean error + +**device_control** +^^^^^^^^^^^^^^^^^^^ + +``device_control`` is used to control and modify the parameters of the TIMER device according to commands.This funtion calls ``timer_control`` actually. + +.. code-block:: C + + int device_control(struct device *dev, int cmd, void *args); + +- **dev** device handle +- **cmd** device control command +- **args** control parameters +- **return** different control commands return different meanings + +In addition to standard control commands, TIMER device also has its own special control commands. + +.. code-block:: C + + #define DEVICE_CTRL_TIMER_CH_START 0x80 + #define DEVICE_CTRL_TIMER_CH_STOP 0x81 + #define DEVICE_CTRL_GET_MATCH_STATUS 0x82 + +``args`` input is different depending on ``cmd``, the list is as follows: + +.. list-table:: table1 + :widths: 15 10 30 + :header-rows: 1 + + * - cmd + - args + - description + * - DEVICE_CTRL_SET_INT + - timer_it_type + - Enable TIMER interrupt + * - DEVICE_CTRL_CLR_INT + - timer_it_type + - Disable TIMER interrupt + * - DEVICE_CTRL_GET_INT + - NULL + - Get TIMER interrupt status + * - DEVICE_CTRL_RESUME + - NULL + - Enable TIMER + * - DEVICE_CTRL_SUSPEND + - NULL + - Disable TIMER + * - DEVICE_CTRL_GET_CONFIG + - NULL + - Get TIMER current count + +**device_write** +^^^^^^^^^^^^^^^^ + +``device_write`` is used to config timer device timeout value.This funtion calls ``timer_write`` actually. + +.. code-block:: C + + int device_write(struct device *dev, uint32_t pos, const void *buffer, uint32_t size); + +- **dev** device handle +- **pos** unused +- **buffer** timer_timeout_cfg_t handle +- **size** the length of timer_timeout_cfg_t +- **return** error code, 0 means writing is successful, others mean errors + +**device_set_callback** +^^^^^^^^^^^^^^^^^^^^^^^^ + +``device_set_callback`` is used to register a timer compare interrupt callback function. + +.. code-block:: C + + int device_set_callback(struct device *dev, void (*callback)(struct device *dev, void *args, uint32_t size, uint32_t event)); + +- **dev** device handle +- **callback** the interrupt callback function to be registered + + - **dev** device handle + - **args** unused + - **size** unused + - **event** interrupt event type + +``event`` type definition is as follows: + +.. code-block:: C + + enum timer_event_type { + TIMER_EVENT_COMP0, + TIMER_EVENT_COMP1, + TIMER_EVENT_COMP2, + TIMER_EVENT_UNKNOWN + }; \ No newline at end of file diff --git a/docs/development_guide_en/build/html/_sources/api_reference/peripheral/api_uart.rst.txt b/docs/development_guide_en/build/html/_sources/api_reference/peripheral/api_uart.rst.txt new file mode 100644 index 00000000..020bd3b9 --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/api_reference/peripheral/api_uart.rst.txt @@ -0,0 +1,308 @@ +UART +========================= + +Introduction +------------------------ + +UART is a universal asynchronous transmitter-receiver, which provides a flexible way for full-duplex data exchange with external devices. The UART device in BL series MCU has the following characteristics: + +- Data bit length can choose 5/6/7/8 bits +- Stop bit length can be selected 0.5/1/1.5/2 bits +- Support odd/even/no parity bit +- Support hardware flow control (RTS/CTS) +- Automatic baud rate detection +- Support LIN protocol (transceive BREAK/SYNC) +- Send/receive FIFO +- Support polling, interrupt, DMA transfer +- Unique rto interrupt + +UART Device Structure Definition +---------------------------------- + +.. 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** inherit the properties of the parent class +- **id** serial port id, if serial port 0 is enabled, id is 0, if serial port 1 is enabled, id is 1, and so on +- **baudrate** baud rate +- **databits** data bits +- **stopbits** stop bits +- **parity** parity +- **fifo_threshold** fifo threshold, the maximum value of different mcu is different +- **tx_dma** additional send dma handle +- **rx_dma** additional receive dma handle + +``databits`` provides the following types + +.. 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`` provides the following types + +.. 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`` provides the following types + +.. 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 Device Parameter Configuration Table +------------------------------------------- + +Each UART device has a parameter configuration macro, the macro definition is located in the ``peripheral_config.h`` file under the ``bsp/board/xxx`` directory, and the variable definition is located in ``hal_uart.c``, so the user does not need to define variable. When the user opens the macro of the corresponding device, the configuration of the device will take effect. For example, open the macro ``BSP_USING_UART0``, ``UART0_CONFIG`` will take effect, and the ``UART0`` device can be registered and used. + +.. code-block:: C + + /*Parameter configuration macro*/ + #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 + + /*Variable definitions*/ + static uart_device_t uartx_device[UART_MAX_INDEX] = + { + #ifdef BSP_USING_UART0 + UART0_CONFIG, + #endif + #ifdef BSP_USING_UART1 + UART1_CONFIG, + #endif + }; + +.. note:: + The above configuration can be modified through ``UART_DEV(dev)->xxx`` and can only be used before calling ``device_open``. + +UART Device Interface +------------------------ + +UART device interface follows which provided by the standard device driver management layer. + +**uart_register** +^^^^^^^^^^^^^^^^^^^^^^^^ + +``uart_register`` is used to register a UART device standard driver interface. Before registering, you need to open the macro definition of the corresponding UART device. For example, define the macro ``BSP_USING_UART0`` to use the ``UART0`` device. After the registration is completed, other interfaces can be used. If the macro is not defined, the ``UART0`` device cannot be used. + +.. code-block:: C + + int uart_register(enum uart_index_type index, const char *name); + +- **index** the index of the device to be registered +- **name** device name + +``index`` is used to select UART device configuration, one index corresponds to a UART device configuration, such as ``UART0_INDEX`` corresponds to ``UART0_CONFIG`` configuration, ``index`` has the following optional types + +.. 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`` is used to open a UART device, this funtion calls ``uart_open`` actually. + +.. code-block:: C + + int device_open(struct device *dev, uint16_t oflag); + +- **dev** device handle +- **oflag** open mode +- **return** error code, 0 means opening is successful, others mean errors + +``oflag`` provides the following types + +.. code-block:: C + + #define DEVICE_OFLAG_STREAM_TX 0x001 /* The device is turned on in polling sending mode */ + #define DEVICE_OFLAG_STREAM_RX 0x002 /* The device is turned on in rotation receiving mode */ + #define DEVICE_OFLAG_INT_TX 0x004 /* The device is turned on in interrupt sending mode */ + #define DEVICE_OFLAG_INT_RX 0x008 /* The device is turned on in interrupt receiving mode */ + #define DEVICE_OFLAG_DMA_TX 0x010 /* The device is turned on in DMA transmission mode */ + #define DEVICE_OFLAG_DMA_RX 0x020 /* The device is turned on in DMA receiving mode */ + +**device_close** +^^^^^^^^^^^^^^^^ + +``device_close`` is used to close a UART device,this funtion calls ``uart_close`` actually. + +.. code-block:: C + + int device_close(struct device *dev); + +- **dev** device handle +- **return** error code, 0 means closing is successful, others mean error + +**device_control** +^^^^^^^^^^^^^^^^^^^ + +``device_control`` is used to control and modify the parameters of the UART device according to commands.This funtion calls ``uart_control`` actually. + +.. code-block:: C + + int device_control(struct device *dev, int cmd, void *args); + +- **dev** device handle +- **cmd** device control command +- **args** control parameters +- **return** different control commands return different meanings. + +In addition to standard control commands, UART device also has its own special control commands. + +.. code-block:: C + + #define DEVICE_CTRL_UART_GET_TX_FIFO 0x10 + #define DEVICE_CTRL_UART_GET_RX_FIFO 0x11 + +``args`` input is different depending on ``cmd``, the list is as follows: + +.. list-table:: table1 + :widths: 15 10 30 + :header-rows: 1 + + * - cmd + - args + - description + * - DEVICE_CTRL_SET_INT + - uart_it_type + - Enable uart device interrupt + * - DEVICE_CTRL_CLR_INT + - uart_it_type + - Disable uart device interrupt + * - DEVICE_CTRL_CONFIG + - uart_param_cfg_t* + - Modify the serial port configuration + * - DEVICE_CTRL_ATTACH_TX_DMA + - NULL + - Link to tx dma device + * - DEVICE_CTRL_ATTACH_RX_DMA + - NULL + - Link to rx dma device + * - DEVICE_CTRL_TX_DMA_SUSPEND + - NULL + - Suspend uart tx dma mode + * - DEVICE_CTRL_RX_DMA_SUSPEND + - NULL + - Suspend uart rx dma mode + * - DEVICE_CTRL_TX_DMA_RESUME + - NULL + - Resume uart tx dma mode + * - DEVICE_CTRL_RX_DMA_RESUME + - NULL + - Resume uart rx dma mode + * - DEVICE_CTRL_UART_GET_TX_FIFO + - uint32_t* + - Get the number of uart tx fifo + * - DEVICE_CTRL_UART_GET_RX_FIFO + - uint32_t* + - Get the number of uart rx fifo + +**device_write** +^^^^^^^^^^^^^^^^ + +``device_write`` is used to send data. The sending mode can be polling, interrupt, dma according to the open mode.This funtion calls ``uart_write`` actually. + +.. code-block:: C + + int device_write(struct device *dev, uint32_t pos, const void *buffer, uint32_t size); + +- **dev** device handle +- **pos** useless +- **buffer** the buffer to be written +- **size** the length to be written +- **return** error code, 0 means writing is successful, others mean errors + +**device_read** +^^^^^^^^^^^^^^^^ + +``device_read`` is used to receive data. The receiving mode can be polling, interrupt, dma according to the open mode.This funtion calls ``uart_read`` actually. + +.. code-block:: C + + int device_read(struct device *dev, uint32_t pos, void *buffer, uint32_t size); + +- **dev** device handle +- **pos** useless +- **buffer** the buffer to be read +- **size** the length to be read +- **return** error code, 0 means successful reading, others mean errors + +**device_set_callback** +^^^^^^^^^^^^^^^^^^^^^^^^ + +``device_set_callback`` is used to register a uart interrupt callback function. + +.. code-block:: C + + int device_set_callback(struct device *dev, void (*callback)(struct device *dev, void *args, uint32_t size, uint32_t event)); + +- **dev** device handle +- **callback** the interrupt callback function to be registered + + - **dev** device handle + - **args** receive and send buffer, the data type is uint8_t* + - **size** transmission length + - **event** interrupt event type + +``event`` type definition is as follows: + +.. 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 + }; \ No newline at end of file diff --git a/docs/development_guide_en/build/html/_sources/api_reference/peripheral/index.rst.txt b/docs/development_guide_en/build/html/_sources/api_reference/peripheral/index.rst.txt new file mode 100644 index 00000000..9df68676 --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/api_reference/peripheral/index.rst.txt @@ -0,0 +1,19 @@ +============== +Peripheral +============== + +.. toctree:: + :maxdepth: 1 + + Clock Tree + GPIO Device + UART Device + PWM Device + DMA Device + I2C Device + #I2S Device + SPI Device + ADC Device + DAC Device + TIMER Device + #USB Device \ No newline at end of file diff --git a/docs/development_guide_en/build/html/_sources/get_started/Linux_quick_start_ubuntu.rst.txt b/docs/development_guide_en/build/html/_sources/get_started/Linux_quick_start_ubuntu.rst.txt new file mode 100644 index 00000000..32588655 --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/get_started/Linux_quick_start_ubuntu.rst.txt @@ -0,0 +1,133 @@ +Linux OR WSL environment development guide +============================================ + +This document introduces how to install and configure the software development tools needed for BL702 series MCUs in Linux. The installation and configuration method under WSL system is the same as under linux, please install WSL system by yourself. The difference is that one runs on a pure linux system and the other runs on windows. If you don't want to install a virtual machine or a linux system, you can choose WSL. + +**Windows Subsystem for Linux** (WSL) is a compatibility layer that can run native Linux binary executable files (ELF format) on Windows 10. It was developed by Microsoft and Canonical in cooperation. Its goal is to enable the pure Ubuntu image to be downloaded and decompressed to the user's local computer, and the tools in the image can run on this subsystem. Therefore, the operation mode under WSL is exactly the same as the operation mode under linux. + +Software and hardware environment +------------------------------------ + +- A mini USB data cable +- A USB-TTL serial port module +- Several Dupont lines + +Configure RISC-V toolchain +----------------------------- + +.. 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 -rf ~/riscv64-elf-20210120 /usr/bin + $ echo "export PATH=\"$PATH:/usr/bin/riscv64-elf-20210120/bin\"" >> ~/.bashrc + $ source ~/.bashrc + +Configure cmake & make tools +------------------------------- + +.. 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 -rf ~/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 + + +Hardware connection +---------------------- + +- For the connection of the board, please refer to :ref:`connect_hardware` +- Please make sure that the board is set correctly before proceeding to the following steps (Serial connection is recommended under Linux) + +Get bl_mcu_sdk +--------------------------- + +- Open the terminal and enter the following command to get bl_mcu_sdk + +.. code-block:: bash + :linenos: + + $ cd ~ + $ git clone https://gitee.com/bouffalolab/bl_mcu_sdk.git --recursive + + +Test Hello World project +------------------------------ + +Open Hello World +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- After obtaining the SDK, enter ``examples/hellowd/helloworld`` in the SDK, open ``main.c``, and then edit the related code of helloworld. + +.. code-block:: bash + :linenos: + + $ cd ~/bl_mcu_sdk/examples/hellowd/helloworld + $ vi main.c + +- After editing, save the changes and close the file, and then compile + +Compile Hello World +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: bash + :linenos: + + $ cd ~/bl_mcu_sdk + $ make build BOARD=bl706_iot APP=helloworld + + +Program Hello World +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Please confirm the programming method first. If you use serial programming, please press and hold the ``boot`` key on the board and don't release it. At this time, press the ``rst`` key, and then release the two keys. The board enters the boot_rom state. +- At this time, enter the following command in the terminal to program + +.. code-block:: bash + :linenos: + + $ cd ~/bl_mcu_sdk + $ make download INTERFACE=uart COMx=/dev/ttyUSB1 + +- If the download fails, please check: + + - 1. Whether the serial port is used for programming, whether the development board is powered, and whether the hardware connection is correct. + - 2. Is the programming command executed in the ``bl_mcu_sdk`` directory + - 3. Whether to enter boot_rom mode + - 4. Whether the serial port is occupied, and whether your available serial port is selected correctly, if your serial port is not ``ttyUSB1``, then please specify the correct serial port + +Run Hello World +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Open a new terminal, install and run the serial port tool + +.. code-block:: bash + :linenos: + + $ sudo apt install picocom # Ignore if it is already installed + $ picocom -b 2000000 /dev/ttyUSB1 # Pay attention to your available serial port number (if you use the serial port of Sipeed RV-debugger Plus, it will be ``ttyUSB1``) + +- Press the ``rst`` key on the board, you can see ``hello world!`` in the serial terminal. + +.. figure:: img/linux1.png + :alt: + + helloworld! + + +Debug Hello World +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + + diff --git a/docs/development_guide_en/build/html/_sources/get_started/Windows_quick_start_cdk.rst.txt b/docs/development_guide_en/build/html/_sources/get_started/Windows_quick_start_cdk.rst.txt new file mode 100644 index 00000000..5390eb9c --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/get_started/Windows_quick_start_cdk.rst.txt @@ -0,0 +1,65 @@ +.. _windows_cdk_quick_start: + +Guide to using CDK (like MDK Keil) under Windows +=================================================== + +This document introduces the use of the CDK developed by `T-HEAD Semiconductor `_ under Windows to complete the related software development of BL702 series MCU. + +Regarding T-HEAD CDK, this is an integrated development environment developed by T-HEAD. It has operations and settings that are very similar to the traditional MCU development environment, and aims to fully access cloud development resources without changing user development habits, combined with graphical debugging and analysis tools such as OSTracer and Profiling, to accelerate user product development. + +Software and hardware environment +-------------------------------------- + +- T-HEAD CDK software +- One USB Type-A data cable, one Type-C data cable +- A CK-Link emulator or a Sipeed RV-Debugger Plus debugger +- A USB-TTL serial port module +- Several Dupont lines + + +Download CDK +----------------------------- + +- `CDK `_ software can be obtained from the official website of T-HEAD OCC + +- After the download is complete, unzip, double-click ``setup.exe``, follow the prompts, and complete the software installation + +Download bl_mcu_sdk +---------------------------- + +- Download bl_mcu_sdk from the open source community. + + - You can use ``git clone`` or directly ``download`` to download the SDK + - Before using ``git clone``, please make sure that ``git`` has been installed correctly, open a terminal that supports ``git`` and enter the following command to get the latest SDK + + .. code-block:: bash + :linenos: + :emphasize-lines: 1 + + $ git clone https://gitee.com/bouffalolab/bl_mcu_sdk.git --recursive + + +Hardware connection +----------------------- + +- For specific connection methods, please refer to :ref:`connect_hardware` +- Please make sure that the board is set up correctly before proceeding to the following steps + +Test the Hello World project +------------------------------ + +**When using Sipeed RV-Debugger Plus to debug a project, please follow the steps below:** + +.. toctree:: + :maxdepth: 1 + + Use Sipeed RV-Debugger + +**When using CK-Link to debug the project, please follow the steps below:** + +.. toctree:: + :maxdepth: 1 + + Use CK-Link + + diff --git a/docs/development_guide_en/build/html/_sources/get_started/Windows_quick_start_eclipse.rst.txt b/docs/development_guide_en/build/html/_sources/get_started/Windows_quick_start_eclipse.rst.txt new file mode 100644 index 00000000..477a319c --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/get_started/Windows_quick_start_eclipse.rst.txt @@ -0,0 +1,170 @@ +Eclipse Development Guide under Windows +========================================== + +This document introduces the use of eclipse under Windows to build a software development environment for BL702 series MCU. + +Software and hardware environment +------------------------------------ + +- Eclipse free installation package +- Serial port assistant software +- A USB Type-A data cable +- A j-link emulator +- A USB-TTL serial port module +- Several Dupont lines + + +Download Eclipse +----------------------------- + +- Download the installation package with the RISC-V toolchain from the Bouffalo Lab developer community `Eclipse https://dev.bouffalolab.com/download `_ . + +Download bl_mcu_sdk +----------------------------- + +- Download from the open source community `bl_mcu_sdk `_. + +- You can use ``git clone`` or directly ``download`` to download the SDK +- Before using ``git clone``, please make sure that ``git`` has been installed correctly. Open a terminal that supports ``git`` and enter the following command to get the latest SDK. + +.. code-block:: bash + :linenos: + :emphasize-lines: 1 + + $ git clone https://gitee.com/bouffalolab/bl_mcu_sdk.git --recursive + + +Configure eclipse +---------------------------- + +- Copy the eclipse compressed package to the working directory, unzip the eclipse compressed package +- Enter the eclipse directory, double-click ``eclipse.exe`` to start eclipse +- Select your ``Workspace`` directory, click ``Launch`` to enter the workspace + + .. figure:: img/pic1.png + :alt: + +- Click ``Window->preferences`` in the menu bar to open the environment configuration related page, ready to import the related configuration environment + + + .. figure:: img/pic2.png + :alt: + +- Click the icon at "1" in the figure below to open the import configuration interface, follow the steps shown in the figure, and select the ``bflb_mcu_preferences.epf`` configuration file in the ``eclipse.exe`` directory. + .. figure:: img/pic3.png + :alt: + +- After selecting the corresponding file, click ``Finish``, select and click ``cancel`` in the dialog box without restarting. + + .. figure:: img/pic4.png + :alt: + +Import bl_mcu_sdk +-------------------------- + +- Click on the menu bar ``File->Import`` to open the configuration interface of the imported project + + .. figure:: img/pic5.png + :alt: + +- In the opened ``Import`` window, select ``General->Existing Projects into Workspace``, and then click ``Next`` + + .. figure:: img/pic6.png + :alt: + +- After loading the project path of bl_mcu_sdk, click ``Finsh`` to complete the import + + .. figure:: img/pic7.png + :alt: + +- After the import is complete, close the ``Welcome`` window to see the imported project + + .. figure:: img/pic8.png + :alt: + + .. figure:: img/pic9.png + :alt: + +- Expand ``Build Target``, you can see the three function buttons ``bl_clean``, ``bl_make``, and ``download``. + + - Double-click the ``bl_clean`` button, it will clear the compilation cache in the ``build`` and ``out`` directories + - Double-click the ``bl_make`` button, the set case will be compiled normally, if the default configuration is not modified, the ``helloworld`` project will be compiled + - Double-click the ``download`` button, the code will be downloaded to the chip, if it is not compiled successfully, the default or last ``.bin`` file will be downloaded + +Hardware connection +---------------------- + +- For specific board connection, please refer to :ref:`connect_hardware`; (The eclipse environment recommends using ``j-link`` for programming and debugging) +- Please make sure that the development board is set up correctly before proceeding to the following steps + +Test the Hello World project +------------------------------- + +Open Hello World +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Open ``examples/hellowd/helloworld/main.c``, you can edit and modify the code of the ``helloworld`` test demo. If you modify it, please save it and execute the compilation + +Compile Hello World +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Double click ``bl_make`` to compile the helloworld project + +- After successful compilation, you can see the log information as shown in the figure below in the ``Console`` window + +.. figure:: img/pic10.png + + +Program Hello World +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Double-click ``download`` to program the helloworld project ``bin`` file to the chip + +- After the download is successful, you can see the log information as shown in the figure below in the ``Console`` window + +.. figure:: img/pic11.png + + +Run Hello World +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Connect the ``TXD0``, ``RXD0`` and ``GND`` pins of the board to the USB-TTL serial port module with a DuPont cable, insert the serial port module into the PC, and use any serial port assistant software to open the serial port +- After the programming is successful, press the ``rst`` button on the board. If the download is correct, you can see the log information as shown in the figure below in the serial port assistant software. + +.. figure:: img/eclipse_run.png + + +Debug Hello World +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Click the ``Debug`` button in the eclipse toolbar to enter the debug configuration window +- Select ``GDB SEGGER J-Link Debugging->Jlink_bl_mcu_sdk``, select the ``.elf`` file that needs to be debugged in ``C/C++ Application:`` +- Click ``Apply`` first, then click ``Debug`` to start ``Debug`` + +.. figure:: img/pic14.png + :alt: + +- After entering the Debug interface, you can see that the program stops at ``main``, click the ``Step Over`` button in the upper toolbar to perform single-step debugging of the code project. + +.. figure:: img/pic15.png + :alt: + + Eclipse Debugging + + +Compile and program different target projects +------------------------------------------------- + +- When you right-click the ``bl_make`` button and click ``Edit``, the configuration interface for replacing the target project will pop up, as shown in the figure below + +.. figure:: img/pic12.png + :alt: + + +- Where ``APP=xxx`` can be changed to the name of the target project that needs to be compiled and programmed. For example, if you want to compile and program the ``gpio/gpio_blink`` project, modify it to ``APP=gpio_blink``. +- ``make BOARD=bl706_iot`` in ``Build command`` will specify different Board types to adapt to different types of boards. + +- The ``Board`` type determines the corresponding ``borad`` header file when compiling. The default selection is ``make build BOARD=bl706_iot`` + + + diff --git a/docs/development_guide_en/build/html/_sources/get_started/bl_dev_cube.rst.txt b/docs/development_guide_en/build/html/_sources/get_started/bl_dev_cube.rst.txt new file mode 100644 index 00000000..917c807a --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/get_started/bl_dev_cube.rst.txt @@ -0,0 +1,90 @@ +.. _bl_dev_cube: + +BLDevCube start guide +=============================== + +This document mainly introduces the use of Bouffalo Lab Dev Cube for code programming. For more details, please refer to `BLDevCube user manual `_ + +Download Bouffalo Lab Dev Cube +------------------------------------ + +- Download the version suitable for your operating system from the developer community, download address:`https://dev.bouffalolab.com/download `_ + + - For users who do not have a registered account, click on the guest portal + +- After the download is complete, you can use it after decompression + + +Configure tool download method +---------------------------------- + +- Double-click ``BLDevCube.exe``, in the ``Chip Type`` drop-down box, select the corresponding chip model, click ``Finish`` to enter the ``Dev Cube`` interface +- Enter the interface, select ``MCU`` under ``View`` in the menu bar to enter the MCU program download interface + +.. figure:: img/dev_cube_view_mcu.png + :alt: + + select mcu + +- Select the corresponding download method in the ``Interface`` column under ``Image``, and choose according to your actual physical connection +- ``Image file`` configure the absolute path of the downloaded image, click ``Browse`` to select the **Bin** file +- When you click ``click here to show advanced options``, the advanced mirroring configuration will be expanded, usually keep the default configuration; it should be noted that ``Flash Clock`` will affect the clock frequency of Flash and PSRAM at the same time , If you need to use PSRAM, you can increase the clock frequency to get better performance + +Download with UART +^^^^^^^^^^^^^^^^^^^^^ + +- ``COM Port`` is used for UART download, select the COM number connected to the chip, and click ``Refresh`` to refresh the COM number +- When ``Uart Speed`` is used for UART download, configure the appropriate baud rate, the default is 2M + +- Please make sure the hardware configuration is correct before downloading: + + - Use ``Type-C USB`` or ``Mini USB`` to connect to the corresponding USB ``Type-C`` port or ``Mini`` port on the board. + - Press the ``Boot`` key on the board, don't release it + - Press the ``RST`` key on the board, now you have entered ``Boot ROM`` model, you can release the two keys + - At this time, you can see the corresponding serial port ``COM`` number from the ``Bouffalo Lab Dev Cube``, if it does not appear, please click the ``Refresh`` button to refresh + +- After completing the above configuration correctly, click the ``Create&Program`` button to download + +- After the download is successful, you will see the status bar turn green and display ``Success`` + +.. figure:: img/dev_cube_download.png + :alt: + + download success! + +Download with Openocd +^^^^^^^^^^^^^^^^^^^^^^^^ + +- Download using openocd is basically the same as using serial port download option configuration, just switch ``Interface`` to ``Openocd`` +- The hardware connection needs to be changed to a debugger connection that supports Openocd (this tutorial takes Sipeed RV Debugger as an example): + + - 1. Connect the RV debugger to the USB port of the computer, open the device manager, you will find that the debugger is recognized as two serial ports (note: not the serial port on the board) + + .. figure:: img/sipeed_rv_debugger_1.png + + - 2. Download the ``zadig-2.4`` replacement driver from sipeed. Download link: `http://dl.sipeed.com/MAIX/tools/sipeed-rv-debugger/zadig-2.4.exe `_ + - 3. After downloading, double-click to open ``zadig-2.4.exe``, and check List All Devices in Options. + - 4. Find JTAG Debugger (Interface 0), then select the replacement driver as WinUSB and click Replace Driver to replace + - 5. Open the device manager again and see that one of the serial ports has been replaced with a universal serial bus device, indicating that the installation is successful + + .. figure:: img/sipeed_rv_debugger_2.png + + - 6. Connect the JTAG pins of the debugger with the JTAG pins of the board + +- After completing the above configuration correctly, click the ``Create&Program`` button to download +- After the download is successful, you will see the status bar turn green and display ``Success`` + +Download with Jlink +^^^^^^^^^^^^^^^^^^^^^^ + +- The tool configuration for downloading using Jlink and Openocd is basically the same, just switch ``Interface`` to ``Jlink`` +- The hardware connection needs to be changed to use Jlink connection (this tutorial takes Jlink V11 as an example, it is recommended to use Jlink V10 or later): + + - 1. Download the appropriate Jlink driver from Segger official website and install it + - 2. Connect the Jlink debugger to the USB port of the computer + - 3. Connect the JTAG pins of the JLink debugger with the JTAG pins of the board + +- After completing the above configuration correctly, click the ``Create&Program`` button to download + +- After the download is successful, you will see the status bar turn green and display ``Success`` + diff --git a/docs/development_guide_en/build/html/_sources/get_started/board.rst.txt b/docs/development_guide_en/build/html/_sources/get_started/board.rst.txt new file mode 100644 index 00000000..d3846f0c --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/get_started/board.rst.txt @@ -0,0 +1,189 @@ +Board Configuration System User Guide +========================================= + +In order to implement the idea of **everything is a file**, we propose a Board configuration system for embedded applications with different hardware configuration requirements. The **Board configuration system** is mainly used for initializing the three basic elements of clock, GPIO, and peripheral default configuration in embedded applications. + +**Board Configuration System** contains three configuration files, and a ``bl_config_wizard`` graphical configuration software + +- **clock_config.h** Clock configuration Include file +- **peripheral_config.h** Peripheral configuration Include file +- **pinmux_config.h** Pin Function Configuration Include file +- **bl_config_wizard** The graphical interface configures the above three types of files + +The user only needs to modify three configuration files and the system will be initialized automatically, thus eliminating the need to call a series of complex and lengthy initialization functions in the user program. Boufflao Lab provides ``bl_config_wizard`` configuration software for users to quickly and easily generate configuration files for their projects. + +`bl_config_wizard`_ supports PC-side online configuration, but currently does not support mobile terminal online configuration. + +.. _bl_config_wizard: https://dev.bouffalolab.com/media/config/index.html + +.. figure:: img/config_wizard.png + :alt: + + bl_config_wizard Preview + + +The features of each file in the Board configuration system +---------------------------------------------------------------- + +The board system is mainly used for different boards, different boards create different board files and put them in ``bsp/board`` directory, and a board file, in the case of **pins not conflicting**, can be shared to different demos, no need to create multiple projects and reduce the project file size. + +.. error:: If there is a pin conflict and you have to use the same Board file, please modify the pins yourself + +**board.c** +^^^^^^^^^^^^^^^^^^^^ + +``board.c`` Main initialization of clock and pins + +**blxxx_config.h** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``blxxx_config.h`` Mainly contains some header files for the HAL layer driver. + +.. hint:: The above two files do not need to be changed by the user, and the same MCU can be copied and pasted directly into your own board directory for use + +**clock_config.h** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``clock_config.h`` Mainly configures the clock sources for the system and peripherals as well as the frequency division system. + +**peripheral_config.h** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``peripheral_config.h`` It mainly contains the enablement of peripherals and the configuration of parameters. + +.. warning:: Macros starting with ``#define BSP_USING_XXX`` are used to enable the configuration of the peripheral, if the macro is not enabled, all functions of the peripheral cannot be used + +.. warning:: Macro starting with ``XXX_CONFIG``, used to initialize the configuration of the peripheral, which is later used by calling ``device_open`` + + +**pinmux_config.h** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``pinmux_config.h`` Mainly configures the GPIO pin function of the peripheral. + +.. warning:: In mcu sdk, all demos share this file, so some demos are not usable and require frequent changes to the pin function configuration in this file. If the user has already set the pin assignments, there is no need to modify them frequently. + +Use of the Board configuration tool **bl_config_wizard** +--------------------------------------------------------------- + +- The ``bl_config_wizard`` can be accessed by clicking on this link `https://dev.bouffalolab.com/media/config/index.html `_ wizard in the online version. Chrome, Firefox, Microsoft Edge browsers are recommended. + +Generate a new **pinmux_config.h** file +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +1. Select ``Pin & Peripheral Configuration`` in the window bar. +#. Select MCU model, currently supports ``BL706 pin configuration``, ``BL704 pin configuration``, ``BL702 pin configuration``. +#. Select the function of the pin, take ``BL706 pin configuration`` as an example, click on the drop-down box of **PAD_GPIO_XX** and select the desired function, as shown in the figure. + +.. figure:: img/config_wizard_example1.png + :alt: + + Select pin function + + +4. After configuring all the pin functions, click ``Export Configuration File`` and then you can select the path and modify the file name in the pop-up box, as shown in the figure. + +.. figure:: img/config_wizard_example2.png + :alt: + + Exporting configuration files + +Modify the original **pinmux_config.h** file +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Often in use, instead of generating a new **pinmux_config.h** file, we make changes to the original **pinmux_config.h** file, and ``bl_config_wizard`` supports such a need. + +1. Select ``Pin & Peripheral Configuration`` in the window bar. +#. Select MCU model, currently supports ``BL706 pin configuration``, ``BL704 pin configuration``, ``BL702 pin configuration``. +#. Click on ``import configuration file`` and select the **pinmux_config.h** file in the pop-up box. +#. Select the pin to be modified and click on its drop-down box to change the pin function +#. When you are done, click ``Export Profile`` and then you can select the path and modify the file name in the pop-up box. + + +Modify the **pinmux_config.h** file in the CDK tool +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- **pinmux_config.h** Also supports the use of graphical configuration wizards in the CDK for adjusting the corresponding pin functions +- Drag the **pinmux_config.h** file directly into the CDK text editor interface, and you will see the ``Configuration Wizard`` tab at the bottom of the text editor + + .. figure:: img/configuration_wizard_1.png + :alt: + + Configuration Wizard + +- Click on the ``Configuration Wizard`` tab to open the graphical configuration wizard interface +- The functions supported by the pin can be selected by selecting the drop-down box + + .. figure:: img/configuration_wizard_2.png + :alt: + + Graphical configuration wizard to set pin functions + +- Please refer to the Graphical Configuration Wizard section of CDK Help for more information on the specific functions and code rules of the Graphical Configuration Wizard. + + + +Differences with STM32CUBEMX Configuration Tool +-------------------------------------------------- + +STM32CUBEMX is also a tool to configure the clock, peripherals and GPIO initialization, eventually generating a complete project with initialization at the very beginning of ``main.c``, and the GPIO and peripheral initialization base will be called in ``stm32xxx_hal_msp.c``. + +.. code-block:: C + + /* MCU Configuration--------------------------------------------------------*/ + + /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ + HAL_Init(); + + /* USER CODE BEGIN Init */ + + /* USER CODE END Init */ + + /* Configure the system clock */ + SystemClock_Config(); + + /* USER CODE BEGIN SysInit */ + + /* USER CODE END SysInit */ + + /* Initialize all configured peripherals */ + MX_GPIO_Init(); + MX_USART1_UART_Init(); + MX_QUADSPI_Init(); + +.. code-block:: C + + void HAL_UART_MspInit(UART_HandleTypeDef* huart) + { + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(huart->Instance==UART5) + { + /* USER CODE BEGIN UART5_MspInit 0 */ + + /* USER CODE END UART5_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_UART5_CLK_ENABLE(); + + __HAL_RCC_GPIOB_CLK_ENABLE(); + /**UART5 GPIO Configuration + PB12 ------> UART5_RX + PB13 ------> UART5_TX + */ + GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_13; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF14_UART5; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /* UART5 interrupt Init */ + HAL_NVIC_SetPriority(UART5_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(UART5_IRQn); + /* USER CODE BEGIN UART5_MspInit 1 */ + + /* USER CODE END UART5_MspInit 1 */ + } + + } + +.. hint:: The projects generated by stm32 all work for one project and cannot be compiled for more than one project at the same time. If you use more than one project, you have to generate more than one of these two files. When using multiple projects, it will indirectly increase the file size and add duplicate files. diff --git a/docs/development_guide_en/build/html/_sources/get_started/cdk_ck_link.rst.txt b/docs/development_guide_en/build/html/_sources/get_started/cdk_ck_link.rst.txt new file mode 100644 index 00000000..6799a468 --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/get_started/cdk_ck_link.rst.txt @@ -0,0 +1,112 @@ +Use CDK + CK-Link to compile and debug +========================================= + + +Open Hello World +------------------------------ + +- After obtaining the SDK, enter the ``examples/hellowd/helloworld/cdk`` directory in the SDK, double-click ``helloworld.cdkproj``, and you can open the ``Helloworld`` project + +Compile Hello World +------------------------------ + +.. figure:: img/cdk1.png + :alt: + + helloworld.cdkproj + +- In the drop-down menu, you can select the ``CK_Link_Debug`` or ``OpenOCD_Debug`` project, this tutorial is based on the ``CK_Link_Debug`` project + +- In the CDK toolbar, click the compile icon to compile the project + + - Click the icon ``Build Project`` at ``1`` to compile the currently selected project + - Click the icon ``Clean Project`` at ``2`` to clear the result of the last compilation + - Click the ``3`` icon ``Flash Download`` to download the compiled code to the chip + - Click the icon ``Start/Stop Debug`` at ``4`` to perform debugging related operations (when using ``CK-Link``, you can load the code to flash first) + - Click the ``5`` icon ``Start/Stop Debug whitout Download`` to debug directly without loading the current bin file + - You can also right-click the project name in ``Project``, and compile the project through the options in the right-click menu + +Program Hello World +---------------------------- + +- Since our flash algorithm is not currently included in the CDK software, we need to put the flash algorithm in the CDK installation directory. The specific operations are as follows: + + - Enter the ``tools\cdk_flashloader`` directory under the SDK directory + - Copy the ``bl70x_flasher.elf`` file in the directory to the ``C-Sky\CDK\CSKY\Flash`` directory of the CDK tool + + .. figure:: img/cdk7.png + :alt: + + CDK Flash Loader + + + +.. figure:: img/cdk8.png + :alt: + + CDK Project Setting + +- Click the project setting button in the ``Project View`` to open the ``Project Setting`` window, or open it through the ``Project`` menu bar + +- In the opened ``Project Setting`` window, select the ``Flash`` tab to configure the required Flash algorithm + +.. figure:: img/cdk9.png + :alt: + + CDK Project Flash setting + +- In the ``Flash`` tab, click the ``Add`` button, select the ``bl70x_flash`` algorithm in the opened list, and click ``Add`` to add it to the project. Others in ``Flash`` configuration, as shown in the figure: + +- After clicking OK, if the configuration is correct, click ``Flash Download`` to download the compiled code to the chip + + +.. figure:: img/cdk5.png + :alt: + + CDK Flashdownload Success + +- If the download fails, please check: + + - 1. Whether the code is compiled correctly and generate files such as ``.elf``, ``.bin``, etc. + - 2. Is the Flash algorithm correctly set? + - 3. Whether the CK-Link and the board are properly connected + - 4. Whether the development board is powered normally and whether the power indicator is on + +Run Hello World +---------------------------- + +- From the menu bar of the CDK ``View->Serial Pane``, open the serial port panel, right-click in the opened ``Serial Pane``, set the serial port, select your corresponding serial port number and baud rate + +.. figure:: img/cdk4.png +.. figure:: img/cdk3.png + :alt: + + CDK Serial Pane setting + +- Press the ``RST`` key on the board, you can see the result of the code in the serial port + +.. figure:: img/cdk6.png + :alt: + + HelloWorld! + + +Debug Hello World +---------------------------- + +- Click the ``Start/Stop Debugger`` button at the top of the toolbar to enter the debug interface, as shown in the figure below + +.. figure:: img/cdk10.png + :alt: + + Debug HelloWorld! + +- In the debug interface, the ``Register`` window can view the ``CPU`` internal register data; the ``Peripherals`` peripheral panel, you can view the corresponding peripheral register data, the top menu bar ``Peripherals-> System Viewer`` can select peripherals; click the relevant debugging button in the upper toolbar to perform operations such as breakpoint setting, single-step debugging, single-step instruction, and full-speed operation. Of course, these operations have corresponding shortcut keys and shortcut setting methods. For details, please refer to ``CDK Help``. + +- We click the single step button to run the code, and we can see that the cursor moves to the next sentence of code, and we can see our output ``Hello World!`` displayed in the serial port panel. + +.. figure:: img/cdk11.png + :alt: + + Debug HelloWorld! + diff --git a/docs/development_guide_en/build/html/_sources/get_started/cdk_new_project_quick_start.rst.txt b/docs/development_guide_en/build/html/_sources/get_started/cdk_new_project_quick_start.rst.txt new file mode 100644 index 00000000..dc11d649 --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/get_started/cdk_new_project_quick_start.rst.txt @@ -0,0 +1,76 @@ +New Project Guide based on CDK +================================== + +This document will briefly explain how to create a new CDK project based on this SDK, please make sure that the CDK IDE is properly installed before following this tutorial. + +Examples directory structure +---------------------------------- + +There are two levels of subdirectories under ``bl_mcu_sdk/examples``, the first level is the folders of different peripherals. The second level is a specific test case of the peripheral, The second level directory usually also contains a directory named ``cdk`` and the source code associated with the case. +The ``cdk`` directory usually contains a ``xxx.cdkproj`` file, which is a CDK project file. If the **CDK** IDE is properly installed, double-click the project to open it. The newly created project should be at the same level as the case level in the current ``examples`` directory. + + +.. note:: The source file must contain the c program entry, usually the ``main`` function, the source file may not be called ``main.c`` + +- Create a new ``my_case`` folder under ``examples`` to store your case +- Create a new folder that needs to be tested in the ``my_case`` directory, such as ``gpio_case`` +- Then add the ``main.c`` file and ``cdk`` directory in the ``gpio_case`` directory + + +The directory structure is as follows: + +.. code-block:: bash + :linenos: + + bl_mcu_sdk + ├── examples + ├── my_case + ├── gpio_case + │ ├── cdk + │ │ ├──gpio_case.cdkproj + │ ├── CMakeLists.txt + │ └── main.c + └── xxxx_case + + +Add cdk project related files +-------------------------------- + +Since the current version of CDK does not support new pure ``Empty`` projects, please follow the steps below + +- Copy ``helloworld.cdkproj`` from the cdk directory in the ``helloworld`` case to your own cdk directory +- Change the file name to your case name, for example: ``gpio_case.cdkproj`` +- Open the ``gpio_case.cdkproj`` file with a text editor and change ``Project Name`` to your project name, for example: ``gpio_case`` + + +.. figure:: img/cdk_start_1.png + :alt: + + +- After editing, save the file and double-click ``gpio_case.cdkproj`` to open the project +- Once you open the project, you can right-click on the appropriate folder and add the source code files you need + +.. figure:: img/cdk_start_2.png + :alt: + + +- Right-click the project, open ``Project Settings``, select the Compiler tab, and add the corresponding header files needed for the new file in ``Include paths``. +- Relative paths are recommended for header file paths +- Click ``OK`` to save the edit + + +.. figure:: img/cdk_start_3.png + :alt: + + +- In case of floating point printouts, you need to add the flag option ``-u _printf_float`` in the Linker tag, in ``Other flags``, otherwise you can't printf floating point properly + +.. figure:: img/cdk_start_4.png + :alt: + + +- In the case of using different development boards, pay attention to choose different board file references, usually, the default configuration is **bl706_iot** + +.. figure:: img/cdk_start_5.png + :alt: + diff --git a/docs/development_guide_en/build/html/_sources/get_started/cdk_rv_debugger_plus.rst.txt b/docs/development_guide_en/build/html/_sources/get_started/cdk_rv_debugger_plus.rst.txt new file mode 100644 index 00000000..d9ae8348 --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/get_started/cdk_rv_debugger_plus.rst.txt @@ -0,0 +1,66 @@ +Use CDK + Sipeed RV-Debugger Plus to compile and debug +========================================================== + +Open Hello World +------------------------------ + +- After obtaining the SDK, enter the ``examples/hellowd/helloworld/cdk`` directory and double-click ``helloworld.cdkproj`` to open the ``Helloworld`` project + +Compile Hello World +------------------------------ + +.. figure:: img/cdk1.png + :alt: + + helloworld.cdkproj + +- Select the ``OpenOCD_Debug`` project in the drop-down menu. Since Sipeed RV-Debugger Plus uses OpenOCD for debugging, this tutorial is based on the ``OpenOCD_Debug`` project; +- If Sipeed RV-Debugger Plus does not install the driver correctly, please refer to :ref:`sipeed_rv_debugger_plus`, set up the driver, and then proceed to the following steps + +- In the CDK toolbar, click the compile icon to compile the project + + - Click ``1`` ``Build Project`` to compile the currently selected project + - Click ``2`` ``Clean Project`` to clear the results of the last compilation + - Click ``3`` ``Flash Download`` to download the compiled code to the chip (**Flash download function cannot be used with OpenOCD Debug**) + - Click ``5`` ``Start/Stop Debug whitout Download`` to debug directly without loading the current bin file + - You can also right-click the project name in ``Project``, and compile the project through the options in the right-click menu + + +Program Hello World +---------------------------- + +- When using the OpenOCD mode debugging method in the CDK, it is not currently supported to directly use the CDK related ``flash`` tool to download the code, so please use the BL Dev Cube tool to program, please refer to :ref:`bl_dev_cube` +- Use CDK to debug after the code is programmed + +Run Hello World +---------------------------- + +- From the menu bar of the CDK ``View->Serial Pane``, open the serial port panel, right-click in the opened ``Serial Pane``, set the serial port, select your corresponding serial port number and baud rate + +.. figure:: img/cdk4.png +.. figure:: img/cdk3.png + :alt: + + CDK Serial Pane setting + +- Press the ``RST`` key on the board, you can see the result of the code in the serial port + +.. figure:: img/cdk6.png + :alt: + + HelloWorld! + + +Debug Hello World +---------------------------- + +- Click the ``Start/Stop Debugger`` button at the top of the toolbar to enter the debug interface, as shown in the figure below + +.. figure:: img/cdk10.png + :alt: + + Debug HelloWorld! + +- In the debug interface, the ``Register`` window can view the ``CPU`` internal register data; the ``Peripherals`` peripheral panel, you can view the corresponding peripheral register data, the top menu bar ``Peripherals-> System Viewer`` can select peripherals; click the relevant debugging button in the upper toolbar to perform operations such as breakpoint setting, single-step debugging, single-step instruction, and full-speed operation. Of course, these operations have corresponding shortcut keys and shortcut setting methods. For details, please refer to ``CDK Help``. + +- We click the single step button to run the code, and we can see that the cursor moves to the next sentence of code, and we can see our output ``Hello World!`` displayed in the serial port panel. diff --git a/docs/development_guide_en/build/html/_sources/get_started/cmake_quick_start.rst.txt b/docs/development_guide_en/build/html/_sources/get_started/cmake_quick_start.rst.txt new file mode 100644 index 00000000..0b32fe2b --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/get_started/cmake_quick_start.rst.txt @@ -0,0 +1,207 @@ +New Project Guide based on cmake framework +============================================= + +This document will introduce how to create a new project based on this SDK. + +Examples directory structure +------------------------------------ + +There are two levels of subdirectories under ``bl_mcu_sdk/examples``, the first level is the folders of different peripherals. The second level is a specific test case of the peripheral, and the directory usually contains a ``CMakeList.txt`` and the source code related to the case. + + +Add a single source file project +----------------------------------- + +.. note:: + The source file must contain the c program entry, usually the ``main`` function, the source file may not be called ``main.c`` + +- Create a new ``my_case`` folder under ``examples`` to store your case +- Create a new folder that needs to be tested in the ``my_case`` directory, such as ``gpio_case`` +- Then add the ``main.c`` and ``CMakeLists.txt`` files in the ``gpio_case`` directory + + +The directory structure is as follows: + +.. code-block:: bash + :linenos: + + bl_mcu_sdk + ├── examples + ├── my_case + ├── gpio_case + │ ├──CMakeLists.txt + │ └──main.c + └── xxxx_case + +`CMakeLists.txt`: + +.. code-block:: cmake + :linenos: + :emphasize-lines: 1-2 + + set(mains main.c) + generate_bin() + +- After writing the code in main.c, compile it in the bl_mcu_sdk directory. The compilation command is as follows: + +.. code-block:: bash + :linenos: + + make BOARD=bl706_iot APP=gpio_case + + +Add multiple source file projects +------------------------------------- + +.. note:: + One of the source files must contain the c program entry, usually the ``main`` function, the source file does not need to be called ``main.c``. This source file depends on other source files. + +- The steps for adding a multi-source file project are the same as the basic steps for adding a single source file project +- Add ``test1.c``, ``test1.h``, ``test2.c``, ``test2.h`` and other source files and header files that need to be relied on in the ``gpio_case`` directory + +The directory structure is as follows: + +.. code-block:: bash + :linenos: + + bl_mcu_sdk + ├── examples + ├── my_case + ├── gpio_case + │ ├──CMakeLists.txt + │ ├──test1.c + │ ├──test1.h + │ ├──test2.c + │ ├──test2.h + │ └──main.c + └── xxxx_case + +- At this time, the ``CMakeLists.txt`` file needs to add the corresponding dependent source file, the content is as follows: + +`CMakeLists.txt`: + +.. code-block:: cmake + :linenos: + :emphasize-lines: 2 + + set(mains main.c) + set(TARGET_REQUIRED_SRCS test1.c test2.c) + generate_bin() + +- After writing the code, compile it in the bl_mcu_sdk directory. The compilation command is as follows: + +.. code-block:: bash + :linenos: + + make BOARD=bl706_iot APP=gpio_case + + +Add a new project with dependent libraries +--------------------------------------------- + +- The steps for adding a new project with dependent libraries are the same as the basic steps for adding a single source file project +- If the dependent library used already exists in this SDK, you only need to modify CMakeLists.txt + + - If the dependent library does not exist, you need to add it yourself, please refer to the follow-up instructions for details + + +If it already exists, the directory structure is as follows: + +.. code-block:: bash + :linenos: + + bl_mcu_sdk + ├── examples + ├── my_case + ├── gpio_case + │ ├──CMakeLists.txt + │ └──main.c + └── xxxx_case + +- At this time, the ``CMakeLists.txt`` file needs to add the corresponding dependent library files. For example, we add the FreeRTOS component library, the content is as follows: + +`CMakeLists.txt`: + +.. code-block:: cmake + :linenos: + :emphasize-lines: 1 + + set(TARGET_REQUIRED_LIBS freertos) + set(mains main.c) + generate_bin() + +- After writing the code, compile it in the bl_mcu_sdk directory. The compilation command is as follows: + +.. code-block:: bash + :linenos: + + make BOARD=bl706_iot APP=gpio_case SUPPORT_FREERTOS=y + +Add a new project and set the private compilation option (gcc option) +------------------------------------------------------------------------- + +- The steps of adding a new project are basically the same as adding a single source file project +- Mainly modify the CMakeLists.txt file and add private compilation options + +`CMakeLists.txt`: + +.. code-block:: cmake + :linenos: + :emphasize-lines: 2 + + set(mains main.c) + set(TARGET_REQUIRED_PRIVATE_OPTIONS -Ofast) + generate_bin() + +- After writing the code, compile it in the bl_mcu_sdk directory. The compilation command is as follows: + +.. code-block:: bash + :linenos: + + make BOARD=bl706_iot APP=gpio_case + + +Add a new project and set up a private link script (ld) +------------------------------------------------------------ + +- The steps of adding a new project are basically the same as adding a single source file project +- Add a private link script file, such as ``gpio_test_case.ld`` + +The directory structure is as follows: + +.. code-block:: bash + :linenos: + + bl_mcu_sdk + ├── examples + ├── my_case + ├── gpio_case + │ ├──CMakeLists.txt + │ ├──gpio_test_case.ld + │ └──main.c + └── xxxx_case + +- Modify the CMakeLists.txt file and add private link script settings + +`CMakeLists.txt`: + +.. code-block:: cmake + :linenos: + :emphasize-lines: 1 + + set(LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/gpio_test_case.ld) + set(mains main.c) + generate_bin() + +- After writing the code, compile it in the bl_mcu_sdk directory. The compilation command is as follows: + +.. code-block:: bash + :linenos: + + make BOARD=bl706_iot APP=gpio_case + + +Add a new project and its dependent source files and library files +---------------------------------------------------------------------- + + diff --git a/docs/development_guide_en/build/html/_sources/get_started/connecting_hardware.rst.txt b/docs/development_guide_en/build/html/_sources/get_started/connecting_hardware.rst.txt new file mode 100644 index 00000000..203cb607 --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/get_started/connecting_hardware.rst.txt @@ -0,0 +1,194 @@ +.. _connect_hardware: + +Hardware connection +======================= + +This document introduces how to connect the board of BL70x series MCU. + +BL706_IOT +------------------------- + +Use CK-Link to Programming and debug +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Connect the CK-Link USB interface to the PC with a suitable USB data cable +- Connect the standard ``JTAG`` pin of the ``HD3`` group of the Iot board with the ``JTAG`` pin of ``CK-Link`` using a DuPont cable +- If you do not use CK-Link to power the board, you need to power the board separately + + +:: + + bl706-iot board CK-Link + ------------------------------- + JTAG_TDI <--> TDI + JTAG_TDO <--> TDO + JTAG_TCK <--> TCK + JTAG_TMS <--> TMS + VDD33 <--> VREF + GND <--> GND + + +.. figure:: img/ck_link_connect_bl706_iot.png + :alt: + + ck_link connect bl706-iot board + +Use J-Link to Programming and debug +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Connect the USB interface of j-link to the PC with a USB data cable +- Connect the standard ``JTAG`` pins of the ``HD3`` group of the Iot board with the ``JTAG`` pins of the ``j-link`` using DuPont wires +- In the case of j-link connection, the board needs to be independently powered, and the power supply of the board is connected to the ``VTref`` pin of j-link + +:: + + bl706-iot board j-link + ------------------------------- + JTAG_TDI <--> TDI + JTAG_TDO <--> TDO + JTAG_TCK <--> TCK + JTAG_TMS <--> TMS + VDD33 <--> VTref + GND <--> GND + + +.. figure:: img/jlink_connect_bl706_iot.png + :alt: + + jlink connect bl706-iot board + + +Use serial port to Programming +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Before using the serial port to Programming, please make sure that ``Bouffalo Lab Dev Cube`` or the command programming tool is installed correctly + + - Use ``Type-C USB`` data cable or ``Mini USB`` data cable to connect to the ``Type-C`` interface or ``Mini`` interface on the board. + - Press the ``Boot`` key on the board, don't release it. + - Press the ``RST`` key on the board, now you have entered ``Boot ROM``, you can release the two keys. + - At this time, you can see the corresponding serial port ``COM`` number from the ``Bouffalo Lab Dev Cube``, if it does not appear, please click the ``Refresh`` key to refresh. + + +- If you don't have a suitable data cable, you can also use some common ``USB-TTL`` modules to connect to the UART0 port of the development board for programming. ``UART0`` is on the ``HD1`` group, the connection method is as follows: + +:: + + USB-TTL BL702_IoT + ---------------------- + 3V3 <--> VDD + TXD <--> RX0 + RXD <--> TX0 + GND <--> GND + +- The programming step is the same as above + +BL706_AVB +-------------------------- + +.. important:: + BL706_AVB has multiple multiplexed pins, please check carefully whether the required function pins are multiplexed; FUNC1: "Default: PIX; Connect: I2S/JTAG", FUNC2: "Default: I2S; Connect: SPI" ; **If you need to debug, please remember to connect the FUNC1 jumper** + +Use Sipeed RV-Debugger Plus to programming and debug +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Powering the BL706_AVB +- Connect the RV-Debugger Plus debugger to the USB port of the computer. If the driver is not installed correctly, please refer to :ref:`sipeed_rv_debugger_plus`, set the driver, and proceed to the following steps +- Connect the debugger and the BL706_AVB with a cable (as shown in the figure below) + +.. important:: + The FUNC1 jumper must be connected when debugging, otherwise the pins will be multiplexed with other functions and the JTAG function cannot be used; the serial port function can be used normally + +.. figure:: img/bl706_avb_rv_debugger_plus.png + :alt: + + RV-Debugger connect bl706_avb board + +Use CK-Link to programming and debug +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Connect the CK-Link USB interface to the PC with a suitable USB data cable +- Connect the FUNC1 jump caps of the bl706_avb +- Connect the pins of the ``HD8`` group to the adapter board using a flat cable +- Connect the ``JTAG`` pin of the adapter board with the corresponding ``JTAG`` pin of ``CK-Link`` using a Dupont wire +- If you do not use CK-Link to power the board, you need to power the board separately + +:: + + bl706-avb board CK-Link + ------------------------------- + JTAG_TDI <--> TDI + JTAG_TDO <--> TDO + JTAG_TCK <--> TCK + JTAG_TMS <--> TMS + VDD33 <--> VREF + GND <--> GND + + +.. figure:: img/bl706_avb_ck_link.png + :alt: + + ck_link connect bl706_avb board + +Use serial port to programming +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Before using the serial port to programming, please make sure that ``Bouffalo Lab Dev Cube`` or the command programming tool is installed correctly + + - Use the ``Type-C USB`` or ``Mini USB`` data cable to connect to the corresponding ``Type-C`` port or ``Mini`` port on the board. + - Press the ``Boot`` key on the board, don't release it. + - Press the ``RST`` key on the board, now you have entered ``Boot ROM``, you can release the two keys. + - At this time, you can see the corresponding serial port ``COM`` number from the ``Bouffalo Lab Dev Cube``, if it does not appear, please click the ``Refresh`` button to refresh. + + +- If you don't have a suitable data cable, you can also use some common ``USB-TTL`` modules to connect to the UART0 port of the development board for programming. ``UART0`` on the ``HD12`` group, the connection method is as follows: + +- If you use Sipeed RV-Debugger Plus to connect BL706_AVB through a flat cable, you can also use the serial port of Sipeed RV Debugger Plus + +:: + + USB-TTL BL706_AVB + ---------------------- + TXD <--> RX0 + RXD <--> TX0 + GND <--> GND + + +Connect BL706 AVB sub-modules +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- This section describes how to connect the BL706_AVB board with other modules, mainly including camera connection, Audio Codec module connection, and SPI screen connection. + +**BL706_AVB Connects to GC0308 Camera Module** + +- 1. First, take the black locking part of the ``J5`` drawer type FPC cable holder on the back of the BL706_AVB development board and pull it out from the edge + +.. figure:: img/connect_camera_1.png + :alt: + + +- 2. When fully disconnected, as shown in the figure below. + +.. figure:: img/connect_camera_2.png + :alt: + + +- 3. The FPC cable holder is a drawer down type, so next insert the camera with the side without metal contact points facing upwards into the FPC cable holder + +.. figure:: img/connect_camera_3.png + :alt: + + +- After inserting the camera, press the black latch tightly + +.. figure:: img/connect_camera_4.png + :alt: + + +**BL706_AVB Connecting Audio Codec Modules** + +- Insert the ``HD19`` group of pins of Audio Codec module into the ``HD11`` row female socket of BL706_AVB development board; note that the module is extended outward. +- The schematic diagram is as follows: + +.. figure:: img/connect_codec_1.png + :alt: + diff --git a/docs/development_guide_en/build/html/_sources/get_started/get_started.rst.txt b/docs/development_guide_en/build/html/_sources/get_started/get_started.rst.txt new file mode 100644 index 00000000..208d61cc --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/get_started/get_started.rst.txt @@ -0,0 +1,118 @@ +Preparation +============================= + +Hardware environment +----------------------------- + +- At least one board for BL702 series MCU: + + - BL706_IOT + - BL706_AVB + +BL706_Iot as shown in the figure below + +.. figure:: img/bl706_iot.png + :alt: + + BL706_IoT + +BL706_AVB as shown in the figure below + +.. figure:: img/bl706_avb.png + :alt: + + BL706_AVB + +- A debugger that supports standard JTAG, just choose one of the following debuggers: + + - CK-Link + - Jlink V11 + - Sipeed RV-Debugger Plus + - Bouffalo Lab Debugger + +- One PC host (Windows or Linux system) + +Software Environment +-------------------------------- + +In order to better use the BL702 series MCU, it is recommended that you have at least one of the following development environments: + +- Use `CDK `_ for Windows (Windows 7 or above is recommended) +- `Windows `_ Use Eclipse (Windows 7 or above is recommended) +- `Linux `_ (LTS version above Ubuntu 18 is recommended) + +.. _sipeed_rv_debugger_plus: + +Sipeed RV-Debugger Plus driver installation settings +--------------------------------------------------------- + +- This section mainly introduces the driver installation settings of the **Sipeed RV-Debugger Plus** debugger. ``If you use **CK-Link** or **J-Link**, you don’t need to read this section.`` + +.. figure:: img/sipeed_rv_debugger_plus.png + :alt: + + Sipeed RV-Debugger plus + +**Windows** + +- To use the Sipeed RV-Debugger Plus debugger on Windows we need to change the driver to the ``Win USB`` driver + + - 1. First, connect the Type-C USB interface of the debugger to the PC with a USB data cable, open the device manager of the PC, and you can see that the debugger is recognized as two serial ports in the port column (*Note: not the Serial port of the board's Boot interface*), or in the ``Universal Serial Bus Controller``, you see ``USB Serial Converter A`` and ``USB Serial Converter B`` + + .. figure:: img/sipeed_rv_debugger_1.png + + .. figure:: img/sipeed_rv_debugger_4.png + + .. important:: 1. The debugger port number must start with ``usb serial port``, if you plug in more than one similar device, please leave only one, confirm the debugger port number + .. important:: 2. If you see "USB Serial Device (COM*)" in the Device Manager, it means that the debugger has entered the "Boot" mode. Please power off the debugger and power it on again, and be careful not to connect the debugger to the target board; at this time, go to the device manager to see if it is normal + + .. figure:: img/sipeed_rv_debugger_7.png + + .. important:: 3. If the serial port is not shown in the device manager, only other devices are shown, or if you only see ``USB Serial Converter A`` and ``USB Serial Converter B`` in the Universal Serial Bus Controller, please go to the `FTDI official website `_ Download the driver that matches your system + + .. figure:: img/sipeed_rv_debugger_6.png + + - 2. Download the ``zadig-2.4`` replacement driver from the sipeed website. Download : `http://dl.sipeed.com/MAIX/tools/sipeed-rv-debugger/zadig-2.4.exe `_ + - 3. After downloading, double-click to open ``zadig-2.4.exe``, select ``Options`` and check ``List All Devices``. + + .. figure:: img/sipeed_rv_debugger_3.png + + - 4. Find JTAG Debugger (Interface 0), then select the replacement driver as ``WinUSB`` and click ``Replace Driver`` to replace + - 5. Open the device manager again and see that one of the serial ports has been replaced with a universal serial bus device, indicating that the installation is successful + + .. figure:: img/sipeed_rv_debugger_2.png + + - 6. At this point, the device driver of Sipeed RV-Debugger Plus has been replaced, and then you can play happily~ + + +**Possible problems:** + +.. caution:: 1. There are no two serial ports when the debugger is connected, and an LED on the debugger is always on, then it should be in Boot mode. Please power off the debugger and power it on again. Be careful not to connect the debugger to the target board; after the debugger is powered on, the two LED lights will flicker and go out under normal circumstances; at this time, check whether the device in the task manager is correct. + +.. caution:: 2. If you still can’t use it normally after the above operations, and there is no correct phenomenon, it is recommended to download from the official Sipeed repository `GitHub `_ obtain the firmware and re-write; press and hold the ``Boot`` button on the debugger without releasing it, insert the debugger into the computer and power on, make the debugger enter the Boot mode, and flash the firmware again; power off and restart + +**Linux** + +- First, connect the Type-C USB interface of the debugger to the PC host using the USB cable, open Terminal, and enter the command ``lsusb`` in the terminal to see the device with the following information + +.. code-block:: bash + + $ lsusb + ... + Bus 001 Device 003: ID 0403:6010 Future Technology Devices International, Ltd FT2232C Dual USB-UART/FIFO IC + ... + +.. figure:: img/sipeed_rv_debugger_8.png + +- If the above diagram does not show the ``FT2232C``, you need to install the ftdi driver + +.. code-block:: bash + + $ sudo apt install libusb-dev libftdi-dev libhidapi-dev + +- Re-plug the debugger to make the changes take effect + +- Debugging code requires openocd to be installed, using openocd version 0.11 + +.. note:: In Linux system, /dev/ttyUSB1 is used for serial port, /dev/ttyUSB0 is used for debug port, if /dev/ttyACM0 is displayed, it means boot mode is entered. + diff --git a/docs/development_guide_en/build/html/_sources/get_started/index.rst.txt b/docs/development_guide_en/build/html/_sources/get_started/index.rst.txt new file mode 100644 index 00000000..c611b940 --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/get_started/index.rst.txt @@ -0,0 +1,35 @@ + +.. _get_started_index: + +======================================= +Development environment setup guide +======================================= + +Before the formal development, please set up a suitable development environment. The specific steps are as follows: + +.. toctree:: + :hidden: + + Windows_CDK + Windows_eclipse + Linux + ++-------------------+--------------------+-------------------+ +| |cdk-logo| | |eclipse-logo| | |linux-logo| | ++-------------------+--------------------+-------------------+ +| `Windows_CDK`_ | `Windows_eclipse`_ | `Linux`_ | ++-------------------+--------------------+-------------------+ + +.. |cdk-logo| image:: img/windows_cdk_logo.png + :target: Windows_quick_start_cdk.html + +.. |eclipse-logo| image:: img/windows_eclipse_logo.png + :target: Windows_quick_start_eclipse.html + +.. |linux-logo| image:: img/Linux_logo.png + :target: Linux_quick_start_ubuntu.html + +.. _Windows_CDK: Windows_quick_start_cdk.html +.. _Windows_eclipse: Windows_quick_start_eclipse.html +.. _Linux: Linux_quick_start_ubuntu.html + diff --git a/docs/development_guide_en/build/html/_sources/index.rst.txt b/docs/development_guide_en/build/html/_sources/index.rst.txt new file mode 100644 index 00000000..ebf8b78c --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/index.rst.txt @@ -0,0 +1,69 @@ +.. bl_mcu_sdk_development_guide documentation master file, created by + sphinx-quickstart on Fri Mar 12 16:32:56 2021. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +======================================================== +BL MCU SDK development guide +======================================================== + +The `BL702 `_ series products are general-purpose microcontrollers based on "SiFive E24 Core" `RISC-V `_ , with network functions such as BLE 5.0, zigbee and Ethernet, as well as other rich peripherals. +It can be used in a wide range of `IoT `_ and other low-power applications. +Supports programming and debugging of the chip through `JTAG `_ , and also supports through `UART `_ programming. +BL MCU SDK will provide users with comprehensive support for BL70X series MCU development. + +.. toctree:: + :maxdepth: 1 + :caption: Quick Development Guide + :numbered: 3 + + get_started/get_started + get_started/connecting_hardware + get_started/index + get_started/cmake_quick_start + get_started/cdk_new_project_quick_start + get_started/bl_dev_cube + get_started/board + + + +.. toctree:: + :maxdepth: 1 + :caption: API Manuals + :numbered: + + api_reference/api_overview + api_reference/peripheral/index + #api_reference/shell/api_shell + #api_reference/usb stack/api_usb_stack + api_reference/bluetooth/api_ble + +.. toctree:: + :maxdepth: 1 + :caption: Basic Peripheral Samples + :numbered: + + samples/basic samples/gpio/index + samples/basic samples/uart/index + samples/basic samples/pwm/index + samples/basic samples/mtimer/index + samples/basic samples/dma/index + samples/basic samples/spi/index + samples/basic samples/i2c/index + #samples/basic samples/i2s/index + samples/basic samples/adc/index + samples/basic samples/timer/index + + +.. toctree:: + :maxdepth: 1 + :caption: Advance Samples + :numbered: + + samples/advance samples/shell_demo + samples/advance samples/fatfs_demo + #samples/advance samples/usb/index + samples/advance samples/lowpower_demo + samples/advance samples/boot2_iap_info + samples/advance samples/ble_scan_demo + diff --git a/docs/development_guide_en/build/html/_sources/samples/advance samples/ble_scan_demo.rst.txt b/docs/development_guide_en/build/html/_sources/samples/advance samples/ble_scan_demo.rst.txt new file mode 100644 index 00000000..c2ae45d8 --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/samples/advance samples/ble_scan_demo.rst.txt @@ -0,0 +1,199 @@ +BLE Client And Server Interconnection +======================================= + +This demo is based on **bl702** to demonstrate the connection and data sending and receiving of **ble server** and **ble client**. + +Prepare +----------------------- + +- Two bl702 boards or one bl702 board + mobile app + +Software Implementation +---------------------------- + +BLE client software Implementation +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- For the software code, see ``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); + } + } + +- In the ``bt_conn_cb_register`` function, register the ``callback`` function for successful connection and disconnection + +- In the ``ble_start_scan`` function, the device will start scanning + +- In the ``device_found`` function, the device uploads the scanned Bluetooth device, the code uses ``adv_name`` to find the Bluetooth device that needs to be connected, and initiate the connection + +.. 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); + } + } + +- After the connection is successful, in the ``ble_write_data_task`` function, the client sends the data in ``buf`` to the 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); + +- After the connection is successful, in the ``notify_func`` function, the client receives the data from the server, ``data`` is the data content, ``length`` is the data length + +BLE server software implementation +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- See ``examples/ble/ble_peripheral`` for the software code + +.. 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); + } + +- In the ``ble_start_adv`` function, ``adv_name`` sets the name of the broadcast device, and the device starts to broadcast + +.. 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); + +-After the connection is successful, in ``ble_tp_recv_wr``, the server receives the data from the client, ``buf`` is the data content, ``len`` is the data length + +.. 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(¬ify_poll_sem); + while(1) + { + k_sem_take(¬ify_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); + + } + } + +- After the connection is successful, in the ``ble_tp_notify_task`` function, the server sends the data in ``data`` to the client. + +Compile and program +----------------------------- + +- **CDK tool compilation** + + Not currently supported + +- **Command compilation** + +.. code-block:: bash + :linenos: + + $ cd /bl_mcu_sdk + $ make BOARD=bl706_iot APP=ble_peripheral SUPPORT_FREERTOS=y SUPPORT_FLOAT=y SUPPORT_BLE=y + +.. code-block:: bash + :linenos: + + $ cd /bl_mcu_sdk + $ make BOARD=bl706_iot APP=ble_central SUPPORT_FREERTOS=y SUPPORT_FLOAT=y SUPPORT_BLE=y + + +- **Program** + + See :ref:`bl_dev_cube` + +Experimental phenomena +----------------------------- + +- **Two bl702 connections** + +.. figure:: img/ble_client.png + :alt: + +.. figure:: img/ble_server.png + :alt: + + +- **Mobile phone connect bl702** + +.. figure:: img/phone_connect.jpg + :alt: + +- The connection is successful, as shown in the figure below + +.. figure:: img/phone_connected.png + :alt: + +- Steps to send and receive data + + - Click ``1`` ``Unknow Service`` to display specific service properties + + - Click ``2`` to turn on ``Notification``, allowing the server to send data to the client + + - Click ``3`` where the client sends data to the server, fill in the data you want to send, and click the ``SEND`` button + + +.. figure:: img/ble_data.png + :alt: + +.. figure:: img/receive_data.png + :alt: + +.. figure:: img/write_data.jpg + :alt: + + + diff --git a/docs/development_guide_en/build/html/_sources/samples/advance samples/boot2_iap_info.rst.txt b/docs/development_guide_en/build/html/_sources/samples/advance samples/boot2_iap_info.rst.txt new file mode 100644 index 00000000..d4f65217 --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/samples/advance samples/boot2_iap_info.rst.txt @@ -0,0 +1,23 @@ +BOOT2 IAP +============================ + +IAP (In Application Programming) is to program some areas of User Flash during the running of the user program. The purpose is to update the firmware program in the product through the reserved communication port after the product is released. + +If you need to realize the IAP function, that is, it will be automatically updated when the user program is running. Need to write two project codes when designing the firmware program. The first project program does not perform normal functional operations, but only receives programs or data through some communication channel (such as USB, USART) to update the second part of the code, and the second project code is the real function Code. + +Bouffalo Lab provides the boot2_iap.bin file and releases it simultaneously with the Dev Cube software package. Users can use Dev Cube to program boot2_iap.bin into the target board. After programming once, the user code can be updated online through the IAP function. + +bl_mcu_sdk contains the source code of boot2_iap, users can check the code in examples/boot2_iap, and complete the compilation and programming. For the compilation and programming process, please refer to the introduction of "Quick Development Guide". + +Prepare +----------------------- + +- The latest version of Dev Cube +- Bl706 +- TTL-USB + + +Experimental phenomena +----------------------------- + +For the specific steps of using Dev Cube to complete the IAP function, please refer to `DevCube User Manual `_ "IAP Program Download". diff --git a/docs/development_guide_en/build/html/_sources/samples/advance samples/fatfs_demo.rst.txt b/docs/development_guide_en/build/html/_sources/samples/advance samples/fatfs_demo.rst.txt new file mode 100644 index 00000000..1d8dbd3a --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/samples/advance samples/fatfs_demo.rst.txt @@ -0,0 +1,2 @@ +FATFS Read And Write +======================= diff --git a/docs/development_guide_en/build/html/_sources/samples/advance samples/lowpower_demo.rst.txt b/docs/development_guide_en/build/html/_sources/samples/advance samples/lowpower_demo.rst.txt new file mode 100644 index 00000000..497df8a3 --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/samples/advance samples/lowpower_demo.rst.txt @@ -0,0 +1,93 @@ +LowPower Evaluation +========================= + +Introduction +------------------------ +BL series chips have rich low-power features to adapt to different low-power applications. In order to facilitate users to quickly evaluate and use the low-power performance of bl series MCUs, bl_mcu_sdk provides a set of low-power interfaces. The low-power levels are divided into four levels. + +1. Running: The power consumption when the CPU is running normally, and the power consumption is determined by the function executed by the customer application code. + +2. WFI: WFI mode, the clock of the CPU is in the Gating state, the CPU stops running, and the program will continue to run when the user exits the WFI mode. + +3. PDS: In PDS mode, most power domains on the chip are turned off, and the CPU is turned off at the same time. RAMs such as ITCM and DTCM in the same power domain as the CPU cannot be used. Only 64K OCTAM can save data. The internal RTC can be used to wake up, or use GPIO pins (when the GPIO power domain is not turned off) to wake up. + +4. HBN: HBN mode, shuts down most of the power domains on the chip, shuts down the CPU and 64K OCRAM, only 4K RAM in the AON domain can save data. The internal RTC can be used to wake up, or a specific wake-up pin (pin located in the AON domain) can be used to wake up. + + +bl_mcu_sdk provides a simple low-power reference example (bl_mcu_sdk examples/power/lowpower_test/) to help users quickly evaluate low-power features. If you need to further adapt to your own low-power scenarios and adopt different low-power methods, please refer to the relevant datasheet or seek technical support from Boufflao Lab. +In this example, the clock selection of peripherals and CPU are both crystal oscillator 32M. The power consumption measurement results based on this example are shown in the following table: + + +------------+---------------------+------------+------------------------------+-----------------------------------------------------------+ + |Mode |Reference current |Basic mode |Wake-up source |Remark | + +============+=====================+============+==============================+===========================================================+ + |Running |5.68 mA |Run | |All peripheral clocks are turned on | + +------------+---------------------+------------+------------------------------+-----------------------------------------------------------+ + |WFI |3.14 mA |WFI |Any interruption |Except the serial port, other peripheral clocks are closed | + +------------+---------------------+------------+------------------------------+-----------------------------------------------------------+ + |PDS |10 uA |PDS 31 |Internal RTC/pin interrupt |64K OCRAM to save data | + +------------+---------------------+------------+------------------------------+-----------------------------------------------------------+ + |HBN |1 uA |HBN 1 |Internal RTC/pin interrupt |4K AON RAM to save data | + +------------+---------------------+------------+------------------------------+-----------------------------------------------------------+ + + +The reference current in the above table is obtained through the sample firmware test. The definition of four levels of "run" " wfi" "pds" "hbn" simplifies the original setting of hbn level and pds level. + +See bl702_bl704_bl706_DS_EN_Combo_1.9.pdf page 28 + +.. figure:: img/powerTable.png + + +**Low power consumption example test method** +------------------------------------------------- + +**Compile low-power sample code** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Write ``make APP=lowpower_test SUPPORT_SHELL=y BOARD=bl706_lp`` in the project directory to complete the compilation of the low power consumption example bl706, or use the CDK project directly to complete the compilation and download. +You can refer to this document "Quick Development Guide" to get more information about compiling and programming. + +When the compilation and programming are successful, connect the serial port to the computer and reset the chip, Xshell will display the page as shown in the figure below. + +.. figure:: img/xShell_lowpower.png + + +**Prepare the hardware environment required for low-power testing** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- It is possible to connect the ammeter and the circuit board of the power supply side in series +- Ammeter +- PC (running Windows or Linux system) +- TTL to USB + +As shown in the figure below, connect the ammeter in series into the power supply circuit of the bl706 module, and issue different low-power commands through the serial debugging assistant software on the PC side, so that the bl706 enters the corresponding low-power mode. +Observe the indicated current value and complete the evaluation. + +.. figure:: img/lowpower_arch.png + +**Use Xshell to start evaluating low-power performance** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +The user can enter the corresponding low power consumption mode by entering the following commands in Xshell. + +``run`` + +- After resetting the chip, it enters the run mode by default without entering any low power consumption mode. The chip is actually running the while(1); statement. + +``wfi`` + + +- Enter wfi mode without adding any parameters. After entering, the CPU is in clock gating state to reduce power consumption +- After entering wfi mode, any interrupt will wake up, such as uart interrupt. Pressing Enter in Xshell will trigger the BL706 UART RX interrupt, so the wfi low power consumption mode can be awakened by this method. + +``pds sleeptime`` + + +- pds can choose to take the parameter "sleeptime" to determine its internal RTC wake-up time. If the command does not carry this parameter, the RTC internal wake-up is not used by default. The current firmware only supports power-on reset wake-up. +- If the instruction contains the sleeptime parameter, pds will be awakened at the moment of ``sleeptime * clock_period``, which will behave as resetting the chip and reprinting the initial message. +- After entering the low-power mode, the RTC clock is 32K, so when the sleeptime is 32768, it appears to wake up after a second of sleep. + +``hbn sleeptime`` + + +- hbn can choose to take the parameter "sleeptime" to determine its internal RTC wake-up time. If the command does not carry this parameter, the RTC internal wake-up is not used by default. The current firmware only supports power-on reset wake-up. +- If the instruction contains the sleeptime parameter, hbn will be awakened at the moment of ``sleeptime * clock_period``, which will behave as resetting the chip and printing the start message again. +- After entering the low-power mode, the RTC clock is 32K, so when the sleeptime is 32768, it appears to wake up after a second of sleep. \ No newline at end of file diff --git a/docs/development_guide_en/build/html/_sources/samples/advance samples/shell_demo.rst.txt b/docs/development_guide_en/build/html/_sources/samples/advance samples/shell_demo.rst.txt new file mode 100644 index 00000000..ac64453e --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/samples/advance samples/shell_demo.rst.txt @@ -0,0 +1,217 @@ +SHELL Command Debugging +========================= + +In order to facilitate the user to use the pc or other controllers to debug the functions of the development board (non-emulator debugging), we provide users with a shell command component, which is similar to the command operation under linux. The user sends commands on the PC or other control terminals, and sends the data to the shell of the development board through serial port, usb, Ethernet, Bluetooth, wifi, etc. The shell will read the received commands for analysis and scan the registered internal functions. After scanning the matching function, execute the matching function, and return the incoming key value and the result of the function execution to the pc or control terminal in real time . It should be noted that the controller side needs to send the key value of the standard keyboard. +This demo will demonstrate how to use **shell** to debug commands through the serial port. + +This shell component has the following functions: + +- Support standard keyboard character control +- Support command auto completion +- Support up and down keys to view historical commands +- Support left and right keys to modify commands +- Support file system and network system debugging + +Prepare +----------------------- + +- PC control terminal uses serial terminal software: xshell or mobaxterm +- Connection medium: usb to serial port or network or usb + +Hardware Connection +----------------------------- + +This demo is based on BL706_IOT and the connection method is as follows + +:: + + GPIO function GPIO pin + ---------------------------------- + UART0_TX <--> GPIO14 + UART0_RX <--> GPIO15 + + +Software Implementation +-------------------------- + +Shell porting to serial port +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- See ``examples/shell`` for the software code + +.. code-block:: C + :linenos: + + #define BSP_UART_CLOCK_SOURCE ROOT_CLOCK_SOURCE_PLL_96M + #define BSP_UART_CLOCK_DIV 0 + +- Configure the ``UART`` device clock source, see ``bsp/board/bl706_iot/clock_config.h`` + +.. code-block:: C + :linenos: + + #define CONFIG_GPIO14_FUNC GPIO_FUN_UART0_TX + #define CONFIG_GPIO15_FUNC GPIO_FUN_UART0_RX + +- Configure ``UART`` device multiplexing pins, see ``bsp/board/bl706_iot/pinmux_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 + +- Enable ``BSP_USING_UART0`` and configure ``UART`` device configuration, see ``bsp/board/bl706_iot/peripheral_config.h`` + +.. code-block:: C + :linenos: + + bflb_platform_init(); + +- In the ``bflb_platform_init`` function, we have registered and opened a serial port device for debugging, to provide users with a basic function of ``MSG`` for printing out messages. The specific implementation is as follows + +.. 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, NULL); + device_control(uart, DEVICE_CTRL_CLR_INT, (void *)(UART_RX_FIFO_IT)); + } + +- First call the ``uart_register`` function to register the ``UART`` device, currently register ``UART0`` +- Then use the ``find`` function to find the handle corresponding to the device and save it in the ``uart`` handle +- Finally use ``device_open`` to open the ``uart`` device with polling sending and interrupt receiving, the interrupt is closed by default and the receiving interrupt callback function is not registered + + +.. code-block:: C + :linenos: + + struct device *uart = device_find("debug_log"); + if (uart) { + device_set_callback(uart, shell_irq_callback); + device_control(uart, DEVICE_CTRL_SET_INT, (void *)(UART_RX_FIFO_IT)); + } + +- Register the receive interrupt service function for ``UART0`` through the ``device_set_callback`` function. Open the ``UART_RX_FIFO_IT`` interrupt via the ``device_control`` function + +.. code-block:: C + :linenos: + + void shell_irq_callback(struct device *dev, void *args, uint32_t size, uint32_t state) + { + uint8_t data; + if (state == UART_EVENT_RX_FIFO) { + data = *(uint8_t *)args; + shell_handler(data); + } + } + +-In the interrupt callback function, judge whether the ``state`` is ``UART_EVENT_RX_FIFO``, and if it is, pass the received byte to the ``shell_handler`` function. + +.. code-block:: C + :linenos: + + shell_init(); + +- Call ``shell_init`` to initialize the shell components. + + +SHELL Command Registration +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Shell command registration uses the following two macros + +.. code-block:: C + :linenos: + + void hellowd() + { + MSG("hello World\r\n"); + } + + int echo(int argc, char *argv[]) + { + MSG("%dparameter(s)\r\n", argc); + + for (uint8_t i = 1; i < argc; i++) { + MSG("%s\r\n", argv[i]); + } + + return 0; + } + + SHELL_CMD_EXPORT(hellowd, hellowd test) + SHELL_CMD_EXPORT(echo, echo test) + +.. code-block:: C + :linenos: + + void hellowd() + { + MSG("hello World\r\n"); + } + + int cmd_echo(int argc, char *argv[]) + { + MSG("%dparameter(s)\r\n", argc); + + for (uint8_t i = 1; i < argc; i++) { + MSG("%s\r\n", argv[i]); + } + + return 0; + } + + SHELL_CMD_EXPORT_ALIAS(hellowd, hellwd,hellowd test) + SHELL_CMD_EXPORT_ALIAS(cmd_echo, echo,echo test) + + + +Compile and Program +----------------------------- + +- **CDK compile** + + Open project:shell.cdkproj + + Refer to the steps of :ref:`windows_cdk_quick_start` to compile and download + +- **Command compilation** + +.. code-block:: bash + :linenos: + + $ cd /bl_mcu_sdk + $ make BOARD=bl706_iot APP=shell SUPPORT_SHELL=y + +- **Program** + + See :ref:`bl_dev_cube` + + +Experimental Phenomena +----------------------------- + +.. figure:: img/shell_demo.gif + :alt: + +shell test + diff --git a/docs/development_guide_en/build/html/_sources/samples/basic samples/adc/adc_key_demo.rst.txt b/docs/development_guide_en/build/html/_sources/samples/basic samples/adc/adc_key_demo.rst.txt new file mode 100644 index 00000000..8103d0c1 --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/samples/basic samples/adc/adc_key_demo.rst.txt @@ -0,0 +1,150 @@ +ADC - Key Detection Voltage +============================== + +This demo mainly introduces the key functions of the ADC. The ADC is used to detect the voltage value of the key input pin and judge whether the corresponding key is pressed according to different voltage divisions. + +Hardware Connection +----------------------------- +This demo is based on BL706_AVB: + +:: + + GPIO function GPIO pin + ---------------------------------- + ADC CH8 <--> GPIO18 + +**Voltage divider circuit:** + +.. figure:: img/adc_key_demo.png + :alt: + + adc key + +Software Implementation +----------------------------- + +- For the code see ``examples/adc/adc_key`` + +.. code-block:: C + :linenos: + + #define BSP_ADC_CLOCK_SOURCE ROOT_CLOCK_SOURCE_XCLK + #define BSP_ADC_CLOCK_DIV 0 + +- Configure the ``ADC`` device clock source, see ``bsp/board/bl706_avb/clock_config.h`` + +.. code-block:: C + :linenos: + + #define CONFIG_GPIO18_FUNC GPIO_FUN_ADC + +- Configure ``ADC`` device multiplexing pins, see ``bsp/board/bl706_avb/pinmux_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 + +- Enable ``BSP_USING_ADC0`` and configure the ``ADC`` device, see ``bsp/board/bl706_iot/peripheral_config.h`` + +.. 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); + +- First call the ``adc_register`` function to register the ``adc_key`` device, which is currently registered as ADC0 +- Then use the ``find`` function to find the handle corresponding to the device and save it in the ``adc_key`` handle +- Then use ``device_open`` to open the ``adc_key`` device in polling mode, and call ``device_control`` to complete the ADC related configuration +- Finally call ``adc_channel_start`` to enable ADC conversion + +.. 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)); + } + +- Call ``device_read`` to read the ``adc_key`` device information and save it to the ``result_val`` structure +- Call the ``get_adc_key_value`` function to get the current key value and voltage value + + +Compile and Program +----------------------------- + +- **CDK compilation** + + Open project:adc_key.cdkproj + + Refer to the steps of :ref:`windows_cdk_quick_start` to compile and download + +- **Command compilation** + +.. code-block:: bash + :linenos: + + $ cd /bl_mcu_sdk + $ make BOARD=bl706_avb APP=adc_key + +- **Program** + + See :ref:`bl_dev_cube` + + +Experimental Phenomena +----------------------------- +In this experiment, pressing SW1 ~ SW5 on the board in turn will get different voltage values: + +- key 0: ~0V +- key 1: ~0.1V +- key 2: ~0.2V +- key 3: ~0.3V +- key 4: ~0.43V + +operation result: + +.. figure:: img/adc_key_result.png + + +Video display: + +.. raw:: html + + + diff --git a/docs/development_guide_en/build/html/_sources/samples/basic samples/adc/index.rst.txt b/docs/development_guide_en/build/html/_sources/samples/basic samples/adc/index.rst.txt new file mode 100644 index 00000000..bbc00597 --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/samples/basic samples/adc/index.rst.txt @@ -0,0 +1,9 @@ +======================= +ADC +======================= + + +.. toctree:: + :maxdepth: 1 + + ADC - Key Detection Voltage \ No newline at end of file diff --git a/docs/development_guide_en/build/html/_sources/samples/basic samples/dma/dma_m2m_demo.rst.txt b/docs/development_guide_en/build/html/_sources/samples/basic samples/dma/dma_m2m_demo.rst.txt new file mode 100644 index 00000000..4b21fdc4 --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/samples/basic samples/dma/dma_m2m_demo.rst.txt @@ -0,0 +1,113 @@ +DMA - Data Transfer Between RAM +================================= + +This demo is based on the memory to memory mode of DMA for data transfer. + +Hardware Connection +----------------------------- +None + +Software Implementation +----------------------------- + +- For the code see ``examples/dma/dma_m2m`` + +.. 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 + +- Enable ``BSP_USING_DMA0_CH0`` and configure the ``DMA`` device, see ``bsp/board/bl706_iot/peripheral_config.h`` + +.. 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); + } + +- First call the ``dma_register`` function to register a channel of the ``DMA`` device, currently register ``DMA_CH0`` +- Then use the ``find`` function to find the handle corresponding to the device and save it in the ``dma`` handle +- Finally use ``device_open`` to open the ``dma`` device in the default mode, call ``device_set_callback`` to register a dma channel 0 interrupt callback function, and call ``device_control`` to open the dma transmission completion interrupt + +.. code-block:: C + :linenos: + + dma_reload(dma,(uint32_t)dma_src_buffer,(uint32_t)dma_dst_buffer,8000); + dma_channel_start(dma); + +- Call the ``dma_reload`` function to supplement the configuration of dma channel 0. A part of the configuration has been supplemented in ``DMA0_CH0_CONFIG``. Here we mainly supplement the source data address, destination data address and total transmission length +- Call ``dma_channel_start`` to start dma transmission + +.. 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"); + } + + } + +- Check whether the data transmission is correct in the interrupt function + +Compile and Program +----------------------------- + +- **CDK compilation** + + Open project:dma_m2m.cdkproj + + Refer to the steps of :ref:`windows_cdk_quick_start` to compile and download + +- **Command compilation** + +.. code-block:: bash + :linenos: + + $ cd /bl_mcu_sdk + $ make BOARD=bl706_iot APP=dma_m2m + +- **Program** + + 详见 :ref:`bl_dev_cube` + + +Experimental Phenomena +----------------------------- +The data in the ``dma_src_buffer`` array is transferred to the ``dma_dst_buffer`` array through DMA channel 0 with a source 32-bit width and a target 32-bit width. After the data transfer is completed, the serial port prints ``dma transfer success``. diff --git a/docs/development_guide_en/build/html/_sources/samples/basic samples/dma/index.rst.txt b/docs/development_guide_en/build/html/_sources/samples/basic samples/dma/index.rst.txt new file mode 100644 index 00000000..df41f443 --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/samples/basic samples/dma/index.rst.txt @@ -0,0 +1,9 @@ +======================= +DMA +======================= + + +.. toctree:: + :maxdepth: 1 + + DMA - Data Transfer Between RAM \ No newline at end of file diff --git a/docs/development_guide_en/build/html/_sources/samples/basic samples/gpio/blink_demo.rst.txt b/docs/development_guide_en/build/html/_sources/samples/basic samples/gpio/blink_demo.rst.txt new file mode 100644 index 00000000..bf4bf297 --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/samples/basic samples/gpio/blink_demo.rst.txt @@ -0,0 +1,75 @@ +GPIO output - Lamp LED +========================= + +This demo is based on the output mode of GPIO. + +Hardware Connection +----------------------------- + +This demo is based on BL706_IOT and the connection method is as follows + +:: + + GPIO function GPIO pin + ---------------------------------- + D0 <--> GPIO22 + D1 <--> GPIO29 + D2 <--> GPIO30 + D3 <--> GPIO31 + + +.. figure:: img/blink_breath_sch.png + :alt: + +Software Implementation +----------------------------- + +- See ``examples/gpio/gpio_blink`` for the software code + +.. 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); + +- Use the above code to configure ``GPIO22`` ``GPIO29`` ``GPIO30`` ``GPIO31`` to output pull-up mode. + +.. code-block:: C + :linenos: + + gpio_write(GPIO_PIN_22, 0); + +- Use the above code to modify the output level value. + +Compile and Program +----------------------------- + +- **CDK compilation** + + Open project:gpio_blink.cdkproj + + Refer to the steps of :ref:`windows_cdk_quick_start` to compile and download + +- **Command compilation** + +.. code-block:: bash + :linenos: + + $ cd /bl_mcu_sdk + $ make BOARD=bl706_iot APP=gpio_blink + +- **Program** + + See :ref:`bl_dev_cube` + + +Experimental Phenomena +----------------------------- + +Video display: + +.. raw:: html + + diff --git a/docs/development_guide_en/build/html/_sources/samples/basic samples/gpio/button_demo.rst.txt b/docs/development_guide_en/build/html/_sources/samples/basic samples/gpio/button_demo.rst.txt new file mode 100644 index 00000000..33e652f8 --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/samples/basic samples/gpio/button_demo.rst.txt @@ -0,0 +1,64 @@ +GPIO interrupt - Button detection +==================================== + +This demo is based on GPIO external interrupt mode. + +Hardware Connection +----------------------------- + +This demo is based on BL706_IOT, add the button circuit by yourself, the connection method is as follows + +:: + + GPIO function GPIO pin + ---------------------------------- + SW1 <--> GPIO11 + +.. figure:: img/button_sch.png + :alt: + +Software Implementation +----------------------------- + +- See ``examples/gpio/gpio_int`` for the software code + +.. 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); + +- Use the above code to configure ``GPIO11`` as the GPIO rising edge interrupt trigger mode, and register the interrupt callback function. + +Compile and Program +----------------------------- + +- **CDK compilation** + + Open project:gpio_int.cdkproj + + Refer to the steps of :ref:`windows_cdk_quick_start` to compile and download + +- **Command compilation** + +.. code-block:: bash + :linenos: + + $ cd /bl_mcu_sdk + $ make BOARD=bl706_iot APP=gpio_int + +- **Program** + + See :ref:`bl_dev_cube` + + +Experimental Phenomena +----------------------------- + +When the button is pressed, the serial port will print ``"gpio rising trigger !"`` \ No newline at end of file diff --git a/docs/development_guide_en/build/html/_sources/samples/basic samples/gpio/index.rst.txt b/docs/development_guide_en/build/html/_sources/samples/basic samples/gpio/index.rst.txt new file mode 100644 index 00000000..12cc9281 --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/samples/basic samples/gpio/index.rst.txt @@ -0,0 +1,10 @@ +======================= +GPIO +======================= + + +.. toctree:: + :maxdepth: 1 + + GPIO output - Lamp LED + GPIO interrupt - Button Detection \ No newline at end of file diff --git a/docs/development_guide_en/build/html/_sources/samples/basic samples/i2c/i2c_eeprom_demo.rst.txt b/docs/development_guide_en/build/html/_sources/samples/basic samples/i2c/i2c_eeprom_demo.rst.txt new file mode 100644 index 00000000..cb7289e8 --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/samples/basic samples/i2c/i2c_eeprom_demo.rst.txt @@ -0,0 +1,116 @@ +I2C - AT24CXX read and write +================================ + +Hardware Connection +----------------------------- + +This demo is based on BL706_IOT, add AT24CXX circuit by yourself, the connection method is as follows + +:: + + GPIO function GPIO pin + ---------------------------------- + I2C_SCL <--> GPIO11 + I2C_SDA <--> GPIO16 + + +Software Implementation +----------------------------- + +- See ``examples/i2c/i2c_at24cxx`` for the software code + +.. code-block:: C + :linenos: + + #define BSP_I2C_CLOCK_SOURCE ROOT_CLOCK_SOURCE_BCLK + #define BSP_I2C_CLOCK_DIV 0 + +- Configure the ``I2C`` device clock source, see ``bsp/board/bl706_iot/clock_config.h`` + +.. code-block:: C + :linenos: + + #define CONFIG_GPIO11_FUNC GPIO_FUN_I2C + #define CONFIG_GPIO16_FUNC GPIO_FUN_I2C + +- Configure ``I2C`` device multiplexing pins, see ``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 + +- Enable ``BSP_USING_I2C0`` and configure ``I2C`` device, see ``bsp/board/bl706_iot/peripheral_config.h`` + +.. 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); + } + +- First call the ``i2c_register`` function to register the ``I2C`` device, currently register ``I2C0`` +- Then use the ``find`` function to find the handle corresponding to the device and save it in the ``i2c0`` handle +- Finally use ``device_open`` to open the ``I2C0`` device in the default mode + +.. 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]); + +- Call ``i2c_transfer`` to transfer two ``msg``, one ``msg`` represents writing 8-byte data to eeprom, and one ``msg`` represents reading 8-byte data from eeprom + +Compile and Program +----------------------------- + +- **CDK compilation** + + Open project:i2c_at24cxx.cdkproj + + Refer to the steps of :ref:`windows_cdk_quick_start` to compile and download + +- **Command compilation** + +.. code-block:: bash + :linenos: + + $ cd /bl_mcu_sdk + $ make BOARD=bl706_iot APP=i2c_at24cxx + +- **Program** + + See :ref:`bl_dev_cube` + +Experimental Phenomena +----------------------------- diff --git a/docs/development_guide_en/build/html/_sources/samples/basic samples/i2c/index.rst.txt b/docs/development_guide_en/build/html/_sources/samples/basic samples/i2c/index.rst.txt new file mode 100644 index 00000000..7c6cc8fe --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/samples/basic samples/i2c/index.rst.txt @@ -0,0 +1,9 @@ +======================= +I2C +======================= + + +.. toctree:: + :maxdepth: 1 + + I2C - AT24CXX Read And Write \ No newline at end of file diff --git a/docs/development_guide_en/build/html/_sources/samples/basic samples/mtimer/index.rst.txt b/docs/development_guide_en/build/html/_sources/samples/basic samples/mtimer/index.rst.txt new file mode 100644 index 00000000..6c2633d4 --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/samples/basic samples/mtimer/index.rst.txt @@ -0,0 +1,9 @@ +======================= +MTIMER +======================= + + +.. toctree:: + :maxdepth: 1 + + MTIMER - System Timer \ No newline at end of file diff --git a/docs/development_guide_en/build/html/_sources/samples/basic samples/mtimer/mtimer_demo.rst.txt b/docs/development_guide_en/build/html/_sources/samples/basic samples/mtimer/mtimer_demo.rst.txt new file mode 100644 index 00000000..938c8e9f --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/samples/basic samples/mtimer/mtimer_demo.rst.txt @@ -0,0 +1,56 @@ +MTIMER - System Timer +======================== + +This demo is based on a 64-bit timer (MTIMER) that comes with the risc-v kernel. This demo can provide reference for os tick. + +Hardware Connection +----------------------------- +None + +Software Implementation +----------------------------- + +- See ``examples/systick`` for the software code + +.. note:: + The ``mtimer`` clock defaults to 1M after frequency division, which is convenient for later use and reduces calculation time. + +.. 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); + +- Use the above code to set the mtimer timing time to 1s, and register the interrupt callback function. + +Compile and Program +----------------------------- + +- **CDK compilation** + + Open project:systick.cdkproj + + Refer to the steps of :ref:`windows_cdk_quick_start` to compile and download + +- **Command compilation** + +.. code-block:: bash + :linenos: + + $ cd /bl_mcu_sdk + $ make BOARD=bl706_iot APP=systick + +- **Program** + + See :ref:`bl_dev_cube` + +Experimental Phenomena +----------------------------- + +The ``tick`` value is incremented by 1 per second and printed through the serial port. diff --git a/docs/development_guide_en/build/html/_sources/samples/basic samples/pwm/index.rst.txt b/docs/development_guide_en/build/html/_sources/samples/basic samples/pwm/index.rst.txt new file mode 100644 index 00000000..d1160140 --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/samples/basic samples/pwm/index.rst.txt @@ -0,0 +1,10 @@ +======================= +PWM +======================= + + +.. toctree:: + :maxdepth: 1 + + PWM - Breathing LED + PWM - Drive Stepper Motor \ No newline at end of file diff --git a/docs/development_guide_en/build/html/_sources/samples/basic samples/pwm/pwm_breath_demo.rst.txt b/docs/development_guide_en/build/html/_sources/samples/basic samples/pwm/pwm_breath_demo.rst.txt new file mode 100644 index 00000000..b532cdc7 --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/samples/basic samples/pwm/pwm_breath_demo.rst.txt @@ -0,0 +1,130 @@ +PWM - Breathing LED +========================= + + This demo is based on PWM polling mode. + +Hardware Connection +----------------------------- + +This demo is based on BL706_IOT, and the connection method is as follows + +:: + + GPIO function GPIO pin + ---------------------------------- + PWM_CH2 <--> GPIO22 + +.. figure:: img/blink_breath_sch.png + :alt: + +Software Implementation +----------------------------- + +-See ``examples/pwm/pwm_breath_led`` for the software code + +.. code-block:: C + :linenos: + + #define BSP_PWM_CLOCK_SOURCE ROOT_CLOCK_SOURCE_XCLK + #define BSP_PWM_CLOCK_DIV 1 + +- Configure the ``PWM`` device clock source, see ``bsp/board/bl706_iot/clock_config.h`` + +.. code-block:: C + :linenos: + + #define CONFIG_GPIO22_FUNC GPIO_FUN_PWM + +- Configure ``PWM`` device multiplexing pins, see ``bsp/board/bl706_iot/pinmux_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 + +- Enable ``BSP_USING_PWM_CH2`` and configure ``PWM`` device configuration, see ``bsp/board/bl706_iot/peripheral_config.h`` + +.. 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) { + PWM_DEV(led_breath)->period = 32; //frequence = 32M/1/32 = 1Mhz + PWM_DEV(led_breath)->threshold_low = 16; + PWM_DEV(led_breath)->threshold_high = 32; + device_open(led_breath, DEVICE_OFLAG_STREAM_TX); + pwm_channel_start(led_breath); + } + + +- First call the ``pwm_register`` function to register a channel of the ``PWM`` device, currently register ``PWM_CH2`` +- Then use the ``find`` function to find the handle corresponding to the device and save it in the ``led_breath`` handle +- Set the frequency of ``PWM_CH2`` to 1Mhz, and the duty cycle to 50% +- Use ``device_open`` to open the ``led_breath`` device in polling mode + +.. code-block:: C + :linenos: + + for (pwm_cfg.threshold_high = 0; pwm_cfg.threshold_high <= 32; pwm_cfg.threshold_high++) { + device_control(led_breath, DEIVCE_CTRL_PWM_DUTYCYCLE_CONFIG, &pwm_cfg); + bflb_platform_delay_ms(50); + } + + for (pwm_cfg.threshold_high = 32; 0 <= pwm_cfg.threshold_high && pwm_cfg.threshold_high <= 32; pwm_cfg.threshold_high--) { + device_control(led_breath, DEIVCE_CTRL_PWM_DUTYCYCLE_CONFIG, &pwm_cfg); + bflb_platform_delay_ms(50); + } + +- Use the ``device_contorl`` function with the ``DEIVCE_CTRL_PWM_DUTYCYCLE_CONFIG`` instruction to modify the duty cycle of the current PWM channel. + +Compile and Program +----------------------------- + +- **CDK compilation** + + Open project:pwm_breath_led.cdkproj + + Refer to the steps of :ref:`windows_cdk_quick_start` to compile and download + +- **Command compilation** + +.. code-block:: bash + :linenos: + + $ cd /bl_mcu_sdk + $ make BOARD=bl706_iot APP=pwm_breath_led + +- **Program** + + See :ref:`bl_dev_cube` + + +Experimental Phenomena +----------------------------- + + +.. figure:: img/pwm_demo.gif + :alt: + +pwm breath led! + +Video display: + +.. raw:: html + + diff --git a/docs/development_guide_en/build/html/_sources/samples/basic samples/pwm/pwm_step_motor.rst.txt b/docs/development_guide_en/build/html/_sources/samples/basic samples/pwm/pwm_step_motor.rst.txt new file mode 100644 index 00000000..356ce0ba --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/samples/basic samples/pwm/pwm_step_motor.rst.txt @@ -0,0 +1,281 @@ +PWM - 驱动步进电机 +==================== + +步进电机是一种将电脉冲转化为角位移的执行机构。当步进驱动器接收到一个脉冲信号,它就驱动步进电机按设定的方向转动一个固定的角度(及步进角)。可以通过控制脉冲个来控制角位移量,从而达到准确定位的目的;同时可以通过控制脉冲频率来控制电机转动的速度和加速度,从而达到调速的目的。 + +本 demo 采用步进电机 28BYJ48 型四相八拍电机,使用 ULN2003 芯片驱动,电压为 DC5V—DC12V。当对步进电机施加一系列连续不断的控制脉冲时,它可以连续不断地转动。每一个脉冲信号对应步进电机的某一相或两相绕组的通电状态改变一次,也就对应转子转过一定的角度(一个步距角)。当通电状态的改变完成一个循环时,转子转过一个齿距。 + +.. figure:: img/step_motor.png + :alt: + + 28BYJ48 + +.. figure:: img/uln2003.png + :alt: + + ULN2003 + +这个步进电机内部有个真正的步进马达转子,每一个脉冲能使这个真正的转子转动5.625°,看下图的数据表格中的减速比是1:64,意思是这个真正的步进马达转子转动64周才能让输出轴转动1周,因此下图的表格中步距角度才写的是5.625°/64,表明的意思是一个脉冲可以让输出轴转动5.625°/64的角度。所以要让马达转一周(360°), 则需要360/5.625*64=4096个脉冲。 +脉冲(或拍)的数量决定转动的角度,单位时间内脉冲(或拍)的数量决定转动的速度 + +.. figure:: img/step_motor_info.png + :alt: + +四相步进电机可以在不同的通电方式下运行,常见的通电方式有如下三种: + +- 一相励磁:单(单相绕组通电)四拍(A+,B+,A-,B-......) + +.. figure:: img/pwm_step_motor1.png + :alt: + +- 二相励磁:双(双相绕组通电)四拍(A+B+,B+A-,A-B-,B-A+......) + +.. figure:: img/pwm_step_motor2.png + :alt: + +- 一二相励磁:八拍(A+B+,B+,B+A-,A-,A-B-,B-,B-A+,A+......) + +.. figure:: img/pwm_step_motor3.png + :alt: + + +硬件连接 +----------------------------- + +本 demo 基于BL706_IOT开发板,连接方式如下 + +:: + + GPIO function GPIO pin + ---------------------------------- + PWM_CH0 <--> GPIO10 + PWM_CH1 <--> GPIO11 + PWM_CH2 <--> GPIO12 + PWM_CH3 <--> GPIO3 + +.. figure:: img/pwm_step_motor.png + :alt: + + 参考电路 + +软件实现 +----------------------------- + +- 软件代码见 ``examples/pwm/pwm_step_motor`` + +.. code-block:: C + :linenos: + + #define BSP_PWM_CLOCK_SOURCE ROOT_CLOCK_SOURCE_RC_32K + #define BSP_PWM_CLOCK_DIV 32 + +- 配置 ``PWM`` 设备时钟源,见 ``bsp/board/bl706_iot/clock_config.h`` + +.. code-block:: C + :linenos: + + #define CONFIG_GPIO3_FUNC GPIO_FUN_PWM + #define CONFIG_GPIO10_FUNC GPIO_FUN_PWM + #define CONFIG_GPIO11_FUNC GPIO_FUN_PWM + #define CONFIG_GPIO12_FUNC GPIO_FUN_PWM + +- 配置 ``PWM`` 设备复用引脚,见 ``bsp/board/bl706_iot/pinmux_config.h`` + +.. code-block:: C + :linenos: + + #define BSP_USING_PWM_CH0 + #define BSP_USING_PWM_CH1 + #define BSP_USING_PWM_CH2 + #define BSP_USING_PWM_CH3 + + #if defined(BSP_USING_PWM_CH0) + #ifndef PWM_CH0_CONFIG + #define PWM_CH0_CONFIG \ + { \ + .ch = 0, \ + .polarity_invert_mode = DISABLE, \ + .period = 0, \ + .threshold_low = 0, \ + .threshold_high = 0, \ + .it_pulse_count = 0, \ + } + #endif + #endif + + #if defined(BSP_USING_PWM_CH1) + #ifndef PWM_CH1_CONFIG + #define PWM_CH1_CONFIG \ + { \ + .ch = 1, \ + .polarity_invert_mode = DISABLE, \ + .period = 0, \ + .threshold_low = 0, \ + .threshold_high = 0, \ + .it_pulse_count = 0, \ + } + #endif + #endif + + #if defined(BSP_USING_PWM_CH2) + #ifndef PWM_CH2_CONFIG + #define PWM_CH2_CONFIG \ + { \ + .ch = 2, \ + .polarity_invert_mode = DISABLE, \ + .period = 0, \ + .threshold_low = 0, \ + .threshold_high = 0, \ + .it_pulse_count = 0, \ + } + #endif + #endif + + #if defined(BSP_USING_PWM_CH3) + #ifndef PWM_CH3_CONFIG + #define PWM_CH3_CONFIG \ + { \ + .ch = 3, \ + .polarity_invert_mode = DISABLE, \ + .period = 0, \ + .threshold_low = 0, \ + .threshold_high = 0, \ + .it_pulse_count = 0, \ + } + #endif + #endif + + +- 使能 ``BSP_USING_PWM_CH0``, ``BSP_USING_PWM_CH1`` , ``BSP_USING_PWM_CH2``, ``BSP_USING_PWM_CH3`` 并配置 ``PWM`` 设备配置,见 ``bsp/board/bl706_iot/peripheral_config.h`` + +.. code-block:: C + :linenos: + + pwm_register(PWM_CH0_INDEX, "motor_ch0", DEVICE_OFLAG_RDWR); + pwm_register(PWM_CH1_INDEX, "motor_ch1", DEVICE_OFLAG_RDWR); + pwm_register(PWM_CH2_INDEX, "motor_ch2", DEVICE_OFLAG_RDWR); + pwm_register(PWM_CH3_INDEX, "motor_ch3", DEVICE_OFLAG_RDWR); + + motor_ch0 = device_find("motor_ch0"); + motor_ch1 = device_find("motor_ch1"); + motor_ch2 = device_find("motor_ch2"); + motor_ch3 = device_find("motor_ch3"); + + if (motor_ch0) { + PWM_DEV(motor_ch0)->period = 8; //frequence = 32K/160/8 = 25hz + PWM_DEV(motor_ch0)->threshold_low = 2; + PWM_DEV(motor_ch0)->threshold_high = 7; + PWM_DEV(motor_ch0)->polarity_invert_mode = ENABLE; + device_open(motor_ch0, DEVICE_OFLAG_STREAM_TX); + } + if (motor_ch1) { + PWM_DEV(motor_ch1)->period = 8; //frequence = 32K/160/8 = 25hz + PWM_DEV(motor_ch1)->threshold_low = 1; + PWM_DEV(motor_ch1)->threshold_high = 4; + device_open(motor_ch1, DEVICE_OFLAG_STREAM_TX); + } + if (motor_ch2) { + PWM_DEV(motor_ch2)->period = 8; //frequence = 32K/160/8 = 25hz + PWM_DEV(motor_ch2)->threshold_low = 3; + PWM_DEV(motor_ch2)->threshold_high = 6; + device_open(motor_ch2, DEVICE_OFLAG_STREAM_TX); + } + if (motor_ch3) { + PWM_DEV(motor_ch3)->period = 8; //frequence = 32K/160/8 = 25hz + PWM_DEV(motor_ch3)->threshold_low = 5; + PWM_DEV(motor_ch3)->threshold_high = 8; + device_open(motor_ch3, DEVICE_OFLAG_STREAM_TX); + } + pwm_channel_start(motor_ch0); + pwm_channel_start(motor_ch1); + pwm_channel_start(motor_ch2); + pwm_channel_start(motor_ch3); + + +- 首先调用 ``pwm_register`` 函数注册 ``PWM`` 设备的一个通道,当前注册 PWM 通道0/1/2/3 +- 然后通过 ``find`` 函数找到设备对应的句柄,保存于4个句柄中 +- 设置 4个通道 的频率为 125hz,占空比为37.5% +- 使用 ``device_open`` 以轮询模式来打开 4个通道 + +.. code-block:: C + :linenos: + + enum motor_dir_type { + CW, + CCW, + STOP + }; + + void motor_set_dir(enum motor_dir_type dir) + { + pwm_dutycycle_config_t pwm_cfg[4]; + + if (dir == CW) { + pwm_cfg[0].threshold_low = 2; + pwm_cfg[0].threshold_high = 7; + pwm_cfg[1].threshold_low = 1; + pwm_cfg[1].threshold_high = 4; + pwm_cfg[2].threshold_low = 3; + pwm_cfg[2].threshold_high = 6; + pwm_cfg[3].threshold_low = 5; + pwm_cfg[3].threshold_high = 8; + } + + else if (dir == CCW) { + pwm_cfg[0].threshold_low = 2; + pwm_cfg[0].threshold_high = 7; + pwm_cfg[1].threshold_low = 5; + pwm_cfg[1].threshold_high = 8; + pwm_cfg[2].threshold_low = 3; + pwm_cfg[2].threshold_high = 6; + pwm_cfg[3].threshold_low = 1; + pwm_cfg[3].threshold_high = 4; + } else if (dir == STOP) { + pwm_cfg[0].threshold_low = 0; + pwm_cfg[0].threshold_high = 0; + pwm_cfg[1].threshold_low = 0; + pwm_cfg[1].threshold_high = 0; + pwm_cfg[2].threshold_low = 0; + pwm_cfg[2].threshold_high = 0; + pwm_cfg[3].threshold_low = 0; + pwm_cfg[3].threshold_high = 0; + } + device_control(motor_ch0, DEIVCE_CTRL_PWM_DUTYCYCLE_CONFIG, &pwm_cfg[0]); + device_control(motor_ch1, DEIVCE_CTRL_PWM_DUTYCYCLE_CONFIG, &pwm_cfg[1]); + device_control(motor_ch2, DEIVCE_CTRL_PWM_DUTYCYCLE_CONFIG, &pwm_cfg[2]); + device_control(motor_ch3, DEIVCE_CTRL_PWM_DUTYCYCLE_CONFIG, &pwm_cfg[3]); + } + +- 使用 ``device_contorl`` 函数,配合 ``DEIVCE_CTRL_PWM_DUTYCYCLE_CONFIG`` 指令,修改4个 PWM 通道的的高低阈值。 + +.. note:: 该函数的功能主要用于切换步进电机的方向 + +编译和烧录 +----------------------------- + +- **CDK 编译** + + 打开项目中提供的工程文件:pwm_step_motor.cdkproj + + 参照 :ref:`windows_cdk_quick_start` 的步骤编译下载即可 + +- **命令行编译** + +.. code-block:: bash + :linenos: + + $ cd /bl_mcu_sdk + $ make BOARD=bl706_iot APP=pwm_step_motor + +- **烧录** + + 详见 :ref:`bl_dev_cube` + + +实验现象 +----------------------------- + +.. figure:: img/pwm_step_motor.gif + :alt: + + diff --git a/docs/development_guide_en/build/html/_sources/samples/basic samples/spi/index.rst.txt b/docs/development_guide_en/build/html/_sources/samples/basic samples/spi/index.rst.txt new file mode 100644 index 00000000..a2786d8d --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/samples/basic samples/spi/index.rst.txt @@ -0,0 +1,9 @@ +======================= +SPI +======================= + + +.. toctree:: + :maxdepth: 1 + + SPI - TFT LCD Display \ No newline at end of file diff --git a/docs/development_guide_en/build/html/_sources/samples/basic samples/spi/spi_lcd_demo.rst.txt b/docs/development_guide_en/build/html/_sources/samples/basic samples/spi/spi_lcd_demo.rst.txt new file mode 100644 index 00000000..41e56108 --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/samples/basic samples/spi/spi_lcd_demo.rst.txt @@ -0,0 +1,154 @@ +SPI - TFT LCD Display +======================= + +Hardware Connection +----------------------------- + +This demo is based on BL706_AVB, and the connection method is as follows + +:: + + GPIO function GPIO pin + ---------------------------------- + LCD_CS <--> GPIO10 + LCD_DC <--> GPIO22 + SPI_SCK <--> GPIO19 + SPI_MISO <--> GPIO20 + SPI_MOSI <--> GPIO21 + + +Software Implementation +----------------------------- + +- See ``examples/spi/spi_lcd`` for the software code + +.. code-block:: C + :linenos: + + #define BSP_SPI_CLOCK_SOURCE ROOT_CLOCK_SOURCE_BCLK + #define BSP_SPI_CLOCK_DIV 0 + +- Configure the ``SPI`` device clock source, see ``bsp/board/bl706_avb/clock_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 + +- Configure ``SPI`` device multiplexing pins, see ``bsp/board/bl706_avb/pinmux_config.h`` + +.. note:: + ``bsp/board/bl706_avb/pinmux_config.h`` is currently used by all demo demos, so you need to select ``PINMUX_SELECT`` as ``PINMUX_LVGL``, and open one of the demos + +.. note:: + In order to adapt to the bl702_avb hardware, the MOSI and MISO of SPI have been swapped by default. If you want to restore the default, modify ``SPI_SWAP_ENABLE`` in ``drivers/bl702_driver/hal_drv/default_config/spi_config.h`` to 0 + +.. 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 + +- Enable ``BSP_USING_SPI0`` and configure ``SPI`` device, see ``bsp/board/bl706_avb/peripheral_config.h`` + +.. 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); + } + +- Configure the ``LCD_CS`` and ``LCD_DC`` pins as output mode and pull up +- Call ``spi_register`` function to register ``SPI`` device, currently register ``SPI0`` +- Then use the ``find`` function to find the handle corresponding to the device and save it in the ``spi0`` handle +- Finally use ``device_open`` to open the ``spi0`` device in polling sending mode + +.. 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; + } + +- Provide interface for LCD display driver + +Compile and Program +----------------------------- + +- **CDK compilation** + + Open project:spi_lcd.cdkproj + + Refer to the steps of :ref:`windows_cdk_quick_start` to compile and download + +- **Command compilation** + +.. code-block:: bash + :linenos: + + $ cd /bl_mcu_sdk + $ make BOARD=bl706_avb APP=spi_lcd + +- **Program** + + See :ref:`bl_dev_cube` + +Experimental Phenomena +----------------------------- + +.. figure:: img/spi_lcd.png + :alt: + +spi display! diff --git a/docs/development_guide_en/build/html/_sources/samples/basic samples/timer/index.rst.txt b/docs/development_guide_en/build/html/_sources/samples/basic samples/timer/index.rst.txt new file mode 100644 index 00000000..7a858bb2 --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/samples/basic samples/timer/index.rst.txt @@ -0,0 +1,9 @@ +======================= +TIMER +======================= + + +.. toctree:: + :maxdepth: 1 + + TIMER - Second Timing Interrupt \ No newline at end of file diff --git a/docs/development_guide_en/build/html/_sources/samples/basic samples/timer/timer_interrupt_demo.rst.txt b/docs/development_guide_en/build/html/_sources/samples/basic samples/timer/timer_interrupt_demo.rst.txt new file mode 100644 index 00000000..ed9b2219 --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/samples/basic samples/timer/timer_interrupt_demo.rst.txt @@ -0,0 +1,109 @@ +TIMER - Second Timing Interrupt +================================== + + This demo is based on TIMER interrupt mode with second timing. + +Hardware Connection +----------------------------- +None + +Software Implementation +----------------------------- + +- See ``examples/timer/timer_int`` for the software code + +.. code-block:: C + :linenos: + + #define BSP_TIMER0_CLOCK_SOURCE ROOT_CLOCK_SOURCE_FCLK + #define BSP_TIMER0_CLOCK_DIV 0 + +- Configure ``TIMER`` device clock source,see ``bsp/board/bl706_iot/clock_config.h`` + +.. code-block:: C + :linenos: + + #define BSP_USING_TIMER0 + + #if defined(BSP_USING_TIMER0) + #ifndef TIMER0_CONFIG + #define TIMER0_CONFIG \ + { \ + .id = 0, \ + .cnt_mode = TIMER_CNT_PRELOAD, \ + .trigger = TIMER_PRELOAD_TRIGGER_COMP2, \ + .reload = 0, \ + .timeout1 = 1000000, \ + .timeout2 = 2000000, \ + .timeout3 = 3000000, \ + } + #endif + #endif + +- Enable ``BSP_USING_TIMER0`` and configure ``TIMER0`` device,see ``bsp/board/bl706_iot/peripheral_config.h`` + +.. code-block:: C + :linenos: + + timer_register(TIMER0_INDEX, "timer0"); + + timer0 = device_find("timer0"); + + if (timer0) { + device_open(timer0, DEVICE_OFLAG_INT_TX); /* 1s,2s,3s timing*/ + device_set_callback(timer0, timer0_irq_callback); + device_control(timer0, DEVICE_CTRL_SET_INT, (void *)(TIMER_COMP0_IT | TIMER_COMP1_IT | TIMER_COMP2_IT)); + } else { + MSG("timer device open failed! \n"); + } + +- Call ``timer_register`` function to register ``TIMER`` device, currently register ``TIMER0`` +- Then use the ``find`` function to find the handle corresponding to the device and save it in the ``timer0`` handle +- Finally use ``device_open`` to open the ``timer0`` device in interrupt mode +- Call ``device_set_callback`` to register irq callback named ``timer0_irq_callback``. Call ``device_control`` to enable irq and configure timing period. + +.. code-block:: C + :linenos: + + void timer0_irq_callback(struct device *dev, void *args, uint32_t size, uint32_t state) + { + if (state == TIMER_EVENT_COMP0) { + MSG("timer event comp0! \r\n"); + } else if (state == TIMER_EVENT_COMP1) { + MSG("timer event comp1! \r\n"); + } else if (state == TIMER_EVENT_COMP2) { + BL_CASE_SUCCESS; + timer_timeout_cfg_t cfg = { 2, 12000000 }; /*modify compare id 2 timeout 12s*/ + device_write(dev, 0, &cfg, sizeof(timer_timeout_cfg_t)); + MSG("timer event comp2! \r\n"); + } + } + +- In irq callback,try to determine whether compare id flag is coming. +- Call ``device_write`` to modify compare id 2 timeout with 12s. + +Compile and Program +----------------------------- + +- **CDK compilation** + + Open project:timer_int.cdkproj + + Refer to the steps of :ref:`windows_cdk_quick_start` to compile and download + +- **Command compilation** + +.. code-block:: bash + :linenos: + + $ cd /bl_mcu_sdk + $ make BOARD=bl706_iot APP=timer_int + +- **Program** + + See :ref:`bl_dev_cube` + + +Experimental Phenomena +----------------------------- + diff --git a/docs/development_guide_en/build/html/_sources/samples/basic samples/uart/index.rst.txt b/docs/development_guide_en/build/html/_sources/samples/basic samples/uart/index.rst.txt new file mode 100644 index 00000000..972dbfed --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/samples/basic samples/uart/index.rst.txt @@ -0,0 +1,9 @@ +======================= +UART +======================= + + +.. toctree:: + :maxdepth: 1 + + UART - Loopback \ No newline at end of file diff --git a/docs/development_guide_en/build/html/_sources/samples/basic samples/uart/uart_loopback_demo.rst.txt b/docs/development_guide_en/build/html/_sources/samples/basic samples/uart/uart_loopback_demo.rst.txt new file mode 100644 index 00000000..83350d5c --- /dev/null +++ b/docs/development_guide_en/build/html/_sources/samples/basic samples/uart/uart_loopback_demo.rst.txt @@ -0,0 +1,150 @@ +UART - Loopback +==================== + +This demo is based on UART polling sending and receiving FIFO interrupt mode. + +Hardware Connection +----------------------------- + +This demo is based on BL706_IOT and the connection method is as follows + +:: + + GPIO function GPIO pin + ---------------------------------- + UART0_TX <--> GPIO14 + UART0_RX <--> GPIO15 + +Software Implementation +----------------------------- + +- See ``examples/uart/uart_echo`` for the software code + +.. code-block:: C + :linenos: + + #define BSP_UART_CLOCK_SOURCE ROOT_CLOCK_SOURCE_PLL_96M + #define BSP_UART_CLOCK_DIV 0 + +-Configure the ``UART`` device clock source, see ``bsp/board/bl706_iot/clock_config.h`` + +.. code-block:: C + :linenos: + + #define CONFIG_GPIO14_FUNC GPIO_FUN_UART0_TX + #define CONFIG_GPIO15_FUNC GPIO_FUN_UART0_RX + +- Configure ``UART`` device multiplexing pins, see ``bsp/board/bl706_iot/pinmux_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 + +- Enable ``BSP_USING_UART0`` and configure the ``UART`` device, see ``bsp/board/bl706_iot/peripheral_config.h`` + +.. code-block:: C + :linenos: + + bflb_platform_init(); + +- In the ``bflb_platform_init`` function, we have registered and opened a serial port device for debugging, to provide users with a basic function of ``MSG`` for printing out messages. The specific implementation is as follows + +.. 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, NULL); + device_control(uart, DEVICE_CTRL_CLR_INT, (void *)(UART_RX_FIFO_IT)); + } + +- First call the ``uart_register`` function to register the ``UART`` device, currently register ``UART0`` +- Then use the ``find`` function to find the handle corresponding to the device and save it in the ``uart`` handle +- Finally use ``device_open`` to open the ``uart`` device with polling sending and interrupt receiving, the interrupt is closed by default and the receiving interrupt callback function is not registered + +.. 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)); + } + +- Register the user-specified ``UART0`` receiving interrupt service function through the ``device_set_callback`` function. Open the ``RX_FIFO`` and ``RTO`` interrupts through the ``device_control`` function + +.. 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); + } + } + + +- This function is the interrupt service function of the example, and its function is to send out the received data. + + - ``state`` will return the interrupt type of the ``UART`` device + - ``args`` contains the return data pointer + - ``size`` contains the length of the returned data + - ``dev`` is the handle of the interrupted ``uart`` device + +- When an interrupt occurs, the ``device_write`` function will be called to send the received data back. + +Compile and Program +----------------------------- + +- **CDK compilation** + + Open project:uart_echo.cdkproj + + Refer to the steps of :ref:`windows_cdk_quick_start` to compile and download + +- **Command compilation** + +.. code-block:: bash + :linenos: + + $ cd /bl_mcu_sdk + $ make BOARD=bl706_iot APP=uart_echo + +- **Program** + + See :ref:`bl_dev_cube` + + +Experimental Phenomena +----------------------------- + +Video display: + +.. raw:: html + + + diff --git a/docs/development_guide_en/build/html/_static/basic.css b/docs/development_guide_en/build/html/_static/basic.css new file mode 100644 index 00000000..6acc2a73 --- /dev/null +++ b/docs/development_guide_en/build/html/_static/basic.css @@ -0,0 +1,856 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li div.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 450px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +a.brackets:before, +span.brackets > a:before{ + content: "["; +} + +a.brackets:after, +span.brackets > a:after { + content: "]"; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} + +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ + +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +table.footnote td, table.footnote th { + border: 0 !important; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +dl.footnote > dt, +dl.citation > dt { + float: left; + margin-right: 0.5em; +} + +dl.footnote > dd, +dl.citation > dd { + margin-bottom: 0em; +} + +dl.footnote > dd:after, +dl.citation > dd:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dt:after { + content: ":"; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0.5em; + content: ":"; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.doctest > div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.descname { + background-color: transparent; + font-weight: bold; + font-size: 1.2em; +} + +code.descclassname { + background-color: transparent; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/docs/development_guide_en/build/html/_static/css/badge_only.css b/docs/development_guide_en/build/html/_static/css/badge_only.css new file mode 100644 index 00000000..e380325b --- /dev/null +++ b/docs/development_guide_en/build/html/_static/css/badge_only.css @@ -0,0 +1 @@ +.fa:before{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}} \ No newline at end of file diff --git a/docs/development_guide_en/build/html/_static/css/fonts/Roboto-Slab-Bold.woff b/docs/development_guide_en/build/html/_static/css/fonts/Roboto-Slab-Bold.woff new file mode 100644 index 00000000..6cb60000 Binary files /dev/null and b/docs/development_guide_en/build/html/_static/css/fonts/Roboto-Slab-Bold.woff differ diff --git a/docs/development_guide_en/build/html/_static/css/fonts/Roboto-Slab-Bold.woff2 b/docs/development_guide_en/build/html/_static/css/fonts/Roboto-Slab-Bold.woff2 new file mode 100644 index 00000000..7059e231 Binary files /dev/null and b/docs/development_guide_en/build/html/_static/css/fonts/Roboto-Slab-Bold.woff2 differ diff --git a/docs/development_guide_en/build/html/_static/css/fonts/Roboto-Slab-Regular.woff b/docs/development_guide_en/build/html/_static/css/fonts/Roboto-Slab-Regular.woff new file mode 100644 index 00000000..f815f63f Binary files /dev/null and b/docs/development_guide_en/build/html/_static/css/fonts/Roboto-Slab-Regular.woff differ diff --git a/docs/development_guide_en/build/html/_static/css/fonts/Roboto-Slab-Regular.woff2 b/docs/development_guide_en/build/html/_static/css/fonts/Roboto-Slab-Regular.woff2 new file mode 100644 index 00000000..f2c76e5b Binary files /dev/null and b/docs/development_guide_en/build/html/_static/css/fonts/Roboto-Slab-Regular.woff2 differ diff --git a/docs/development_guide_en/build/html/_static/css/fonts/fontawesome-webfont.eot b/docs/development_guide_en/build/html/_static/css/fonts/fontawesome-webfont.eot new file mode 100644 index 00000000..e9f60ca9 Binary files /dev/null and b/docs/development_guide_en/build/html/_static/css/fonts/fontawesome-webfont.eot differ diff --git a/docs/development_guide_en/build/html/_static/css/fonts/fontawesome-webfont.svg b/docs/development_guide_en/build/html/_static/css/fonts/fontawesome-webfont.svg new file mode 100644 index 00000000..855c845e --- /dev/null +++ b/docs/development_guide_en/build/html/_static/css/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/development_guide_en/build/html/_static/css/fonts/fontawesome-webfont.ttf b/docs/development_guide_en/build/html/_static/css/fonts/fontawesome-webfont.ttf new file mode 100644 index 00000000..35acda2f Binary files /dev/null and b/docs/development_guide_en/build/html/_static/css/fonts/fontawesome-webfont.ttf differ diff --git a/docs/development_guide_en/build/html/_static/css/fonts/fontawesome-webfont.woff b/docs/development_guide_en/build/html/_static/css/fonts/fontawesome-webfont.woff new file mode 100644 index 00000000..400014a4 Binary files /dev/null and b/docs/development_guide_en/build/html/_static/css/fonts/fontawesome-webfont.woff differ diff --git a/docs/development_guide_en/build/html/_static/css/fonts/fontawesome-webfont.woff2 b/docs/development_guide_en/build/html/_static/css/fonts/fontawesome-webfont.woff2 new file mode 100644 index 00000000..4d13fc60 Binary files /dev/null and b/docs/development_guide_en/build/html/_static/css/fonts/fontawesome-webfont.woff2 differ diff --git a/docs/development_guide_en/build/html/_static/css/fonts/lato-bold-italic.woff b/docs/development_guide_en/build/html/_static/css/fonts/lato-bold-italic.woff new file mode 100644 index 00000000..88ad05b9 Binary files /dev/null and b/docs/development_guide_en/build/html/_static/css/fonts/lato-bold-italic.woff differ diff --git a/docs/development_guide_en/build/html/_static/css/fonts/lato-bold-italic.woff2 b/docs/development_guide_en/build/html/_static/css/fonts/lato-bold-italic.woff2 new file mode 100644 index 00000000..c4e3d804 Binary files /dev/null and b/docs/development_guide_en/build/html/_static/css/fonts/lato-bold-italic.woff2 differ diff --git a/docs/development_guide_en/build/html/_static/css/fonts/lato-bold.woff b/docs/development_guide_en/build/html/_static/css/fonts/lato-bold.woff new file mode 100644 index 00000000..c6dff51f Binary files /dev/null and b/docs/development_guide_en/build/html/_static/css/fonts/lato-bold.woff differ diff --git a/docs/development_guide_en/build/html/_static/css/fonts/lato-bold.woff2 b/docs/development_guide_en/build/html/_static/css/fonts/lato-bold.woff2 new file mode 100644 index 00000000..bb195043 Binary files /dev/null and b/docs/development_guide_en/build/html/_static/css/fonts/lato-bold.woff2 differ diff --git a/docs/development_guide_en/build/html/_static/css/fonts/lato-normal-italic.woff b/docs/development_guide_en/build/html/_static/css/fonts/lato-normal-italic.woff new file mode 100644 index 00000000..76114bc0 Binary files /dev/null and b/docs/development_guide_en/build/html/_static/css/fonts/lato-normal-italic.woff differ diff --git a/docs/development_guide_en/build/html/_static/css/fonts/lato-normal-italic.woff2 b/docs/development_guide_en/build/html/_static/css/fonts/lato-normal-italic.woff2 new file mode 100644 index 00000000..3404f37e Binary files /dev/null and b/docs/development_guide_en/build/html/_static/css/fonts/lato-normal-italic.woff2 differ diff --git a/docs/development_guide_en/build/html/_static/css/fonts/lato-normal.woff b/docs/development_guide_en/build/html/_static/css/fonts/lato-normal.woff new file mode 100644 index 00000000..ae1307ff Binary files /dev/null and b/docs/development_guide_en/build/html/_static/css/fonts/lato-normal.woff differ diff --git a/docs/development_guide_en/build/html/_static/css/fonts/lato-normal.woff2 b/docs/development_guide_en/build/html/_static/css/fonts/lato-normal.woff2 new file mode 100644 index 00000000..3bf98433 Binary files /dev/null and b/docs/development_guide_en/build/html/_static/css/fonts/lato-normal.woff2 differ diff --git a/docs/development_guide_en/build/html/_static/css/theme.css b/docs/development_guide_en/build/html/_static/css/theme.css new file mode 100644 index 00000000..8cd4f101 --- /dev/null +++ b/docs/development_guide_en/build/html/_static/css/theme.css @@ -0,0 +1,4 @@ +html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a,.wy-menu-vertical li.current>a span.toctree-expand:before,.wy-menu-vertical li.on a,.wy-menu-vertical li.on a span.toctree-expand:before,.wy-menu-vertical li span.toctree-expand:before,.wy-nav-top a,.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li span.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p.caption .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a span.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a span.fa-pull-left.toctree-expand,.wy-menu-vertical li span.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p.caption .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a span.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a span.fa-pull-right.toctree-expand,.wy-menu-vertical li span.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p.caption .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a span.pull-left.toctree-expand,.wy-menu-vertical li.on a span.pull-left.toctree-expand,.wy-menu-vertical li span.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p.caption .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a span.pull-right.toctree-expand,.wy-menu-vertical li.on a span.pull-right.toctree-expand,.wy-menu-vertical li span.pull-right.toctree-expand{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a span.toctree-expand:before,.wy-menu-vertical li.on a span.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li span.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li span.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a span.toctree-expand:before,.wy-menu-vertical li.on a span.toctree-expand:before,.wy-menu-vertical li span.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li a span.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li span.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p.caption .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a span.toctree-expand,.btn .wy-menu-vertical li.on a span.toctree-expand,.btn .wy-menu-vertical li span.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p.caption .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a span.toctree-expand,.nav .wy-menu-vertical li.on a span.toctree-expand,.nav .wy-menu-vertical li span.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p.caption .btn .headerlink,.rst-content p.caption .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn span.toctree-expand,.wy-menu-vertical li.current>a .btn span.toctree-expand,.wy-menu-vertical li.current>a .nav span.toctree-expand,.wy-menu-vertical li .nav span.toctree-expand,.wy-menu-vertical li.on a .btn span.toctree-expand,.wy-menu-vertical li.on a .nav span.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p.caption .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li span.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p.caption .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li span.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p.caption .btn .fa-large.headerlink,.rst-content p.caption .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn span.fa-large.toctree-expand,.wy-menu-vertical li .nav span.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p.caption .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li span.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p.caption .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li span.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p.caption .btn .fa-spin.headerlink,.rst-content p.caption .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn span.fa-spin.toctree-expand,.wy-menu-vertical li .nav span.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p.caption .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li span.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p.caption .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li span.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p.caption .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li span.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p.caption .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini span.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol li,.rst-content ol.arabic li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content ol.arabic li p:last-child,.rst-content ol.arabic li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol li ul li,.rst-content ol.arabic li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs li{display:inline-block}.wy-breadcrumbs li.wy-breadcrumbs-aside{float:right}.wy-breadcrumbs li a{display:inline-block;padding:5px}.wy-breadcrumbs li a:first-child{padding-left:0}.rst-content .wy-breadcrumbs li tt,.wy-breadcrumbs li .rst-content tt,.wy-breadcrumbs li code{padding:5px;border:none;background:none}.rst-content .wy-breadcrumbs li tt.literal,.wy-breadcrumbs li .rst-content tt.literal,.wy-breadcrumbs li code.literal{color:#404040}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li span.toctree-expand{display:block;float:left;margin-left:-1.2em;font-size:.8em;line-height:1.6em;color:#4d4d4d}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover span.toctree-expand,.wy-menu-vertical li.on a:hover span.toctree-expand{color:grey}.wy-menu-vertical li.current>a span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand{display:block;font-size:.8em;line-height:1.6em;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover span.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 span.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 span.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover span.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active span.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search>a:hover{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.version{margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p.caption .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p.caption .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version span.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}.rst-content img{max-width:100%;height:auto}.rst-content div.figure{margin-bottom:24px}.rst-content div.figure p.caption{font-style:italic}.rst-content div.figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp{user-select:none;pointer-events:none}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content table>caption .headerlink{visibility:hidden;font-size:14px}.rst-content .code-block-caption .headerlink:after,.rst-content .toctree-wrapper>p.caption .headerlink:after,.rst-content dl dt .headerlink:after,.rst-content h1 .headerlink:after,.rst-content h2 .headerlink:after,.rst-content h3 .headerlink:after,.rst-content h4 .headerlink:after,.rst-content h5 .headerlink:after,.rst-content h6 .headerlink:after,.rst-content p.caption .headerlink:after,.rst-content table>caption .headerlink:after{content:"\f0c1";font-family:FontAwesome}.rst-content .code-block-caption:hover .headerlink:after,.rst-content .toctree-wrapper>p.caption:hover .headerlink:after,.rst-content dl dt:hover .headerlink:after,.rst-content h1:hover .headerlink:after,.rst-content h2:hover .headerlink:after,.rst-content h3:hover .headerlink:after,.rst-content h4:hover .headerlink:after,.rst-content h5:hover .headerlink:after,.rst-content h6:hover .headerlink:after,.rst-content p.caption:hover .headerlink:after,.rst-content table>caption:hover .headerlink:after{visibility:visible}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .hlist{width:100%}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl dt span.classifier:before{content:" : "}html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.field-list>dt:after,html.writer-html5 .rst-content dl.footnote>dt:after{content:":"}html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.footnote>dt>span.brackets{margin-right:.5rem}html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{font-style:italic}html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.footnote>dd p,html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{font-size:inherit;line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.field-list)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dl:not(.field-list)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.field-list)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dl:not(.field-list)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code,html.writer-html4 .rst-content dl:not(.docutils) tt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) code,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) tt{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel{border:1px solid #7fbbe3;background:#e7f2fa;font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block} \ No newline at end of file diff --git a/docs/development_guide_en/build/html/_static/doctools.js b/docs/development_guide_en/build/html/_static/doctools.js new file mode 100644 index 00000000..61ac9d26 --- /dev/null +++ b/docs/development_guide_en/build/html/_static/doctools.js @@ -0,0 +1,321 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for all documentation. + * + * :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/** + * select a different prefix for underscore + */ +$u = _.noConflict(); + +/** + * make the code below compatible with browsers without + * an installed firebug like debugger +if (!window.console || !console.firebug) { + var names = ["log", "debug", "info", "warn", "error", "assert", "dir", + "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", + "profile", "profileEnd"]; + window.console = {}; + for (var i = 0; i < names.length; ++i) + window.console[names[i]] = function() {}; +} + */ + +/** + * small helper function to urldecode strings + * + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL + */ +jQuery.urldecode = function(x) { + if (!x) { + return x + } + return decodeURIComponent(x.replace(/\+/g, ' ')); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && + !jQuery(node.parentNode).hasClass(className) && + !jQuery(node.parentNode).hasClass("nohighlight")) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + var bbox = node.parentElement.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute('class', className); + addItems.push({ + "parent": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} + +/** + * Small JavaScript module for the documentation. + */ +var Documentation = { + + init : function() { + this.fixFirefoxAnchorBug(); + this.highlightSearchWords(); + this.initIndexTable(); + if (DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) { + this.initOnKeyListeners(); + } + }, + + /** + * i18n support + */ + TRANSLATIONS : {}, + PLURAL_EXPR : function(n) { return n === 1 ? 0 : 1; }, + LOCALE : 'unknown', + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext : function(string) { + var translated = Documentation.TRANSLATIONS[string]; + if (typeof translated === 'undefined') + return string; + return (typeof translated === 'string') ? translated : translated[0]; + }, + + ngettext : function(singular, plural, n) { + var translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated === 'undefined') + return (n == 1) ? singular : plural; + return translated[Documentation.PLURALEXPR(n)]; + }, + + addTranslations : function(catalog) { + for (var key in catalog.messages) + this.TRANSLATIONS[key] = catalog.messages[key]; + this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); + this.LOCALE = catalog.locale; + }, + + /** + * add context elements like header anchor links + */ + addContextElements : function() { + $('div[id] > :header:first').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this headline')). + appendTo(this); + }); + $('dt[id]').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this definition')). + appendTo(this); + }); + }, + + /** + * workaround a firefox stupidity + * see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075 + */ + fixFirefoxAnchorBug : function() { + if (document.location.hash && $.browser.mozilla) + window.setTimeout(function() { + document.location.href += ''; + }, 10); + }, + + /** + * highlight the search words provided in the url in the text + */ + highlightSearchWords : function() { + var params = $.getQueryParameters(); + var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; + if (terms.length) { + var body = $('div.body'); + if (!body.length) { + body = $('body'); + } + window.setTimeout(function() { + $.each(terms, function() { + body.highlightText(this.toLowerCase(), 'highlighted'); + }); + }, 10); + $('') + .appendTo($('#searchbox')); + } + }, + + /** + * init the domain index toggle buttons + */ + initIndexTable : function() { + var togglers = $('img.toggler').click(function() { + var src = $(this).attr('src'); + var idnum = $(this).attr('id').substr(7); + $('tr.cg-' + idnum).toggle(); + if (src.substr(-9) === 'minus.png') + $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); + else + $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); + }).css('display', ''); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { + togglers.click(); + } + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords : function() { + $('#searchbox .highlight-link').fadeOut(300); + $('span.highlighted').removeClass('highlighted'); + }, + + /** + * make the url absolute + */ + makeURL : function(relativeURL) { + return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; + }, + + /** + * get the current relative url + */ + getCurrentURL : function() { + var path = document.location.pathname; + var parts = path.split(/\//); + $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { + if (this === '..') + parts.pop(); + }); + var url = parts.join('/'); + return path.substring(url.lastIndexOf('/') + 1, path.length - 1); + }, + + initOnKeyListeners: function() { + $(document).keydown(function(event) { + var activeElementType = document.activeElement.tagName; + // don't navigate when in search box, textarea, dropdown or button + if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT' + && activeElementType !== 'BUTTON' && !event.altKey && !event.ctrlKey && !event.metaKey + && !event.shiftKey) { + switch (event.keyCode) { + case 37: // left + var prevHref = $('link[rel="prev"]').prop('href'); + if (prevHref) { + window.location.href = prevHref; + return false; + } + case 39: // right + var nextHref = $('link[rel="next"]').prop('href'); + if (nextHref) { + window.location.href = nextHref; + return false; + } + } + } + }); + } +}; + +// quick alias for translations +_ = Documentation.gettext; + +$(document).ready(function() { + Documentation.init(); +}); diff --git a/docs/development_guide_en/build/html/_static/documentation_options.js b/docs/development_guide_en/build/html/_static/documentation_options.js new file mode 100644 index 00000000..bf5777ad --- /dev/null +++ b/docs/development_guide_en/build/html/_static/documentation_options.js @@ -0,0 +1,12 @@ +var DOCUMENTATION_OPTIONS = { + URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), + VERSION: '0.3', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + BUILDER: 'html', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false +}; \ No newline at end of file diff --git a/docs/development_guide_en/build/html/_static/file.png b/docs/development_guide_en/build/html/_static/file.png new file mode 100644 index 00000000..a858a410 Binary files /dev/null and b/docs/development_guide_en/build/html/_static/file.png differ diff --git a/docs/development_guide_en/build/html/_static/jquery-3.5.1.js b/docs/development_guide_en/build/html/_static/jquery-3.5.1.js new file mode 100644 index 00000000..50937333 --- /dev/null +++ b/docs/development_guide_en/build/html/_static/jquery-3.5.1.js @@ -0,0 +1,10872 @@ +/*! + * jQuery JavaScript Library v3.5.1 + * https://jquery.com/ + * + * Includes Sizzle.js + * https://sizzlejs.com/ + * + * Copyright JS Foundation and other contributors + * Released under the MIT license + * https://jquery.org/license + * + * Date: 2020-05-04T22:49Z + */ +( function( global, factory ) { + + "use strict"; + + if ( typeof module === "object" && typeof module.exports === "object" ) { + + // For CommonJS and CommonJS-like environments where a proper `window` + // is present, execute the factory and get jQuery. + // For environments that do not have a `window` with a `document` + // (such as Node.js), expose a factory as module.exports. + // This accentuates the need for the creation of a real `window`. + // e.g. var jQuery = require("jquery")(window); + // See ticket #14549 for more info. + module.exports = global.document ? + factory( global, true ) : + function( w ) { + if ( !w.document ) { + throw new Error( "jQuery requires a window with a document" ); + } + return factory( w ); + }; + } else { + factory( global ); + } + +// Pass this if window is not defined yet +} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { + +// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 +// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode +// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common +// enough that all such attempts are guarded in a try block. +"use strict"; + +var arr = []; + +var getProto = Object.getPrototypeOf; + +var slice = arr.slice; + +var flat = arr.flat ? function( array ) { + return arr.flat.call( array ); +} : function( array ) { + return arr.concat.apply( [], array ); +}; + + +var push = arr.push; + +var indexOf = arr.indexOf; + +var class2type = {}; + +var toString = class2type.toString; + +var hasOwn = class2type.hasOwnProperty; + +var fnToString = hasOwn.toString; + +var ObjectFunctionString = fnToString.call( Object ); + +var support = {}; + +var isFunction = function isFunction( obj ) { + + // Support: Chrome <=57, Firefox <=52 + // In some browsers, typeof returns "function" for HTML elements + // (i.e., `typeof document.createElement( "object" ) === "function"`). + // We don't want to classify *any* DOM node as a function. + return typeof obj === "function" && typeof obj.nodeType !== "number"; + }; + + +var isWindow = function isWindow( obj ) { + return obj != null && obj === obj.window; + }; + + +var document = window.document; + + + + var preservedScriptAttributes = { + type: true, + src: true, + nonce: true, + noModule: true + }; + + function DOMEval( code, node, doc ) { + doc = doc || document; + + var i, val, + script = doc.createElement( "script" ); + + script.text = code; + if ( node ) { + for ( i in preservedScriptAttributes ) { + + // Support: Firefox 64+, Edge 18+ + // Some browsers don't support the "nonce" property on scripts. + // On the other hand, just using `getAttribute` is not enough as + // the `nonce` attribute is reset to an empty string whenever it + // becomes browsing-context connected. + // See https://github.com/whatwg/html/issues/2369 + // See https://html.spec.whatwg.org/#nonce-attributes + // The `node.getAttribute` check was added for the sake of + // `jQuery.globalEval` so that it can fake a nonce-containing node + // via an object. + val = node[ i ] || node.getAttribute && node.getAttribute( i ); + if ( val ) { + script.setAttribute( i, val ); + } + } + } + doc.head.appendChild( script ).parentNode.removeChild( script ); + } + + +function toType( obj ) { + if ( obj == null ) { + return obj + ""; + } + + // Support: Android <=2.3 only (functionish RegExp) + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call( obj ) ] || "object" : + typeof obj; +} +/* global Symbol */ +// Defining this global in .eslintrc.json would create a danger of using the global +// unguarded in another place, it seems safer to define global only for this module + + + +var + version = "3.5.1", + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }; + +jQuery.fn = jQuery.prototype = { + + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + + // Return all the elements in a clean array + if ( num == null ) { + return slice.call( this ); + } + + // Return just the one element from the set + return num < 0 ? this[ num + this.length ] : this[ num ]; + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + each: function( callback ) { + return jQuery.each( this, callback ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map( this, function( elem, i ) { + return callback.call( elem, i, elem ); + } ) ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + even: function() { + return this.pushStack( jQuery.grep( this, function( _elem, i ) { + return ( i + 1 ) % 2; + } ) ); + }, + + odd: function() { + return this.pushStack( jQuery.grep( this, function( _elem, i ) { + return i % 2; + } ) ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); + }, + + end: function() { + return this.prevObject || this.constructor(); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: arr.sort, + splice: arr.splice +}; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[ 0 ] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // Skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !isFunction( target ) ) { + target = {}; + } + + // Extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + + // Only deal with non-null/undefined values + if ( ( options = arguments[ i ] ) != null ) { + + // Extend the base object + for ( name in options ) { + copy = options[ name ]; + + // Prevent Object.prototype pollution + // Prevent never-ending loop + if ( name === "__proto__" || target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject( copy ) || + ( copyIsArray = Array.isArray( copy ) ) ) ) { + src = target[ name ]; + + // Ensure proper type for the source value + if ( copyIsArray && !Array.isArray( src ) ) { + clone = []; + } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { + clone = {}; + } else { + clone = src; + } + copyIsArray = false; + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend( { + + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), + + // Assume jQuery is ready without the ready module + isReady: true, + + error: function( msg ) { + throw new Error( msg ); + }, + + noop: function() {}, + + isPlainObject: function( obj ) { + var proto, Ctor; + + // Detect obvious negatives + // Use toString instead of jQuery.type to catch host objects + if ( !obj || toString.call( obj ) !== "[object Object]" ) { + return false; + } + + proto = getProto( obj ); + + // Objects with no prototype (e.g., `Object.create( null )`) are plain + if ( !proto ) { + return true; + } + + // Objects with prototype are plain iff they were constructed by a global Object function + Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; + return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; + }, + + isEmptyObject: function( obj ) { + var name; + + for ( name in obj ) { + return false; + } + return true; + }, + + // Evaluates a script in a provided context; falls back to the global one + // if not specified. + globalEval: function( code, options, doc ) { + DOMEval( code, { nonce: options && options.nonce }, doc ); + }, + + each: function( obj, callback ) { + var length, i = 0; + + if ( isArrayLike( obj ) ) { + length = obj.length; + for ( ; i < length; i++ ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } else { + for ( i in obj ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } + + return obj; + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArrayLike( Object( arr ) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + return arr == null ? -1 : indexOf.call( arr, elem, i ); + }, + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; + + for ( ; j < len; j++ ) { + first[ i++ ] = second[ j ]; + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var length, value, + i = 0, + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArrayLike( elems ) ) { + length = elems.length; + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return flat( ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support +} ); + +if ( typeof Symbol === "function" ) { + jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; +} + +// Populate the class2type map +jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), +function( _i, name ) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +} ); + +function isArrayLike( obj ) { + + // Support: real iOS 8.2 only (not reproducible in simulator) + // `in` check used to prevent JIT error (gh-2145) + // hasOwn isn't used here due to false negatives + // regarding Nodelist length in IE + var length = !!obj && "length" in obj && obj.length, + type = toType( obj ); + + if ( isFunction( obj ) || isWindow( obj ) ) { + return false; + } + + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; +} +var Sizzle = +/*! + * Sizzle CSS Selector Engine v2.3.5 + * https://sizzlejs.com/ + * + * Copyright JS Foundation and other contributors + * Released under the MIT license + * https://js.foundation/ + * + * Date: 2020-03-14 + */ +( function( window ) { +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + 1 * new Date(), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + nonnativeSelectorCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // Instance methods + hasOwn = ( {} ).hasOwnProperty, + arr = [], + pop = arr.pop, + pushNative = arr.push, + push = arr.push, + slice = arr.slice, + + // Use a stripped-down indexOf as it's faster than native + // https://jsperf.com/thor-indexof-vs-for/5 + indexOf = function( list, elem ) { + var i = 0, + len = list.length; + for ( ; i < len; i++ ) { + if ( list[ i ] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" + + "ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + + // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram + identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace + + "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+", + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + + // "Attribute values must be CSS identifiers [capture 5] + // or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + + whitespace + "*\\]", + + pseudos = ":(" + identifier + ")(?:\\((" + + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rwhitespace = new RegExp( whitespace + "+", "g" ), + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + + "*" ), + rdescend = new RegExp( whitespace + "|>" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + identifier + ")" ), + "CLASS": new RegExp( "^\\.(" + identifier + ")" ), + "TAG": new RegExp( "^(" + identifier + "|[*])" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + + whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + + whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rhtml = /HTML$/i, + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + + // CSS escapes + // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ), + funescape = function( escape, nonHex ) { + var high = "0x" + escape.slice( 1 ) - 0x10000; + + return nonHex ? + + // Strip the backslash prefix from a non-hex escape sequence + nonHex : + + // Replace a hexadecimal escape sequence with the encoded Unicode code point + // Support: IE <=11+ + // For values outside the Basic Multilingual Plane (BMP), manually construct a + // surrogate pair + high < 0 ? + String.fromCharCode( high + 0x10000 ) : + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }, + + // CSS string/identifier serialization + // https://drafts.csswg.org/cssom/#common-serializing-idioms + rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, + fcssescape = function( ch, asCodePoint ) { + if ( asCodePoint ) { + + // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER + if ( ch === "\0" ) { + return "\uFFFD"; + } + + // Control characters and (dependent upon position) numbers get escaped as code points + return ch.slice( 0, -1 ) + "\\" + + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; + } + + // Other potentially-special ASCII characters get backslash-escaped + return "\\" + ch; + }, + + // Used for iframes + // See setDocument() + // Removing the function wrapper causes a "Permission Denied" + // error in IE + unloadHandler = function() { + setDocument(); + }, + + inDisabledFieldset = addCombinator( + function( elem ) { + return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset"; + }, + { dir: "parentNode", next: "legend" } + ); + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + ( arr = slice.call( preferredDoc.childNodes ) ), + preferredDoc.childNodes + ); + + // Support: Android<4.0 + // Detect silently failing push.apply + // eslint-disable-next-line no-unused-expressions + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + pushNative.apply( target, slice.call( els ) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + + // Can't trust NodeList.length + while ( ( target[ j++ ] = els[ i++ ] ) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var m, i, elem, nid, match, groups, newSelector, + newContext = context && context.ownerDocument, + + // nodeType defaults to 9, since context defaults to document + nodeType = context ? context.nodeType : 9; + + results = results || []; + + // Return early from calls with invalid selector or context + if ( typeof selector !== "string" || !selector || + nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { + + return results; + } + + // Try to shortcut find operations (as opposed to filters) in HTML documents + if ( !seed ) { + setDocument( context ); + context = context || document; + + if ( documentIsHTML ) { + + // If the selector is sufficiently simple, try using a "get*By*" DOM method + // (excepting DocumentFragment context, where the methods don't exist) + if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) { + + // ID selector + if ( ( m = match[ 1 ] ) ) { + + // Document context + if ( nodeType === 9 ) { + if ( ( elem = context.getElementById( m ) ) ) { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + + // Element context + } else { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( newContext && ( elem = newContext.getElementById( m ) ) && + contains( context, elem ) && + elem.id === m ) { + + results.push( elem ); + return results; + } + } + + // Type selector + } else if ( match[ 2 ] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Class selector + } else if ( ( m = match[ 3 ] ) && support.getElementsByClassName && + context.getElementsByClassName ) { + + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // Take advantage of querySelectorAll + if ( support.qsa && + !nonnativeSelectorCache[ selector + " " ] && + ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) && + + // Support: IE 8 only + // Exclude object elements + ( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) { + + newSelector = selector; + newContext = context; + + // qSA considers elements outside a scoping root when evaluating child or + // descendant combinators, which is not what we want. + // In such cases, we work around the behavior by prefixing every selector in the + // list with an ID selector referencing the scope context. + // The technique has to be used as well when a leading combinator is used + // as such selectors are not recognized by querySelectorAll. + // Thanks to Andrew Dupont for this technique. + if ( nodeType === 1 && + ( rdescend.test( selector ) || rcombinators.test( selector ) ) ) { + + // Expand context for sibling selectors + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || + context; + + // We can use :scope instead of the ID hack if the browser + // supports it & if we're not changing the context. + if ( newContext !== context || !support.scope ) { + + // Capture the context ID, setting it first if necessary + if ( ( nid = context.getAttribute( "id" ) ) ) { + nid = nid.replace( rcssescape, fcssescape ); + } else { + context.setAttribute( "id", ( nid = expando ) ); + } + } + + // Prefix every selector in the list + groups = tokenize( selector ); + i = groups.length; + while ( i-- ) { + groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " + + toSelector( groups[ i ] ); + } + newSelector = groups.join( "," ); + } + + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch ( qsaError ) { + nonnativeSelectorCache( selector, true ); + } finally { + if ( nid === expando ) { + context.removeAttribute( "id" ); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {function(string, object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return ( cache[ key + " " ] = value ); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created element and returns a boolean result + */ +function assert( fn ) { + var el = document.createElement( "fieldset" ); + + try { + return !!fn( el ); + } catch ( e ) { + return false; + } finally { + + // Remove from its parent by default + if ( el.parentNode ) { + el.parentNode.removeChild( el ); + } + + // release memory in IE + el = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split( "|" ), + i = arr.length; + + while ( i-- ) { + Expr.attrHandle[ arr[ i ] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + a.sourceIndex - b.sourceIndex; + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( ( cur = cur.nextSibling ) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return ( name === "input" || name === "button" ) && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for :enabled/:disabled + * @param {Boolean} disabled true for :disabled; false for :enabled + */ +function createDisabledPseudo( disabled ) { + + // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable + return function( elem ) { + + // Only certain elements can match :enabled or :disabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled + if ( "form" in elem ) { + + // Check for inherited disabledness on relevant non-disabled elements: + // * listed form-associated elements in a disabled fieldset + // https://html.spec.whatwg.org/multipage/forms.html#category-listed + // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled + // * option elements in a disabled optgroup + // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled + // All such elements have a "form" property. + if ( elem.parentNode && elem.disabled === false ) { + + // Option elements defer to a parent optgroup if present + if ( "label" in elem ) { + if ( "label" in elem.parentNode ) { + return elem.parentNode.disabled === disabled; + } else { + return elem.disabled === disabled; + } + } + + // Support: IE 6 - 11 + // Use the isDisabled shortcut property to check for disabled fieldset ancestors + return elem.isDisabled === disabled || + + // Where there is no isDisabled, check manually + /* jshint -W018 */ + elem.isDisabled !== !disabled && + inDisabledFieldset( elem ) === disabled; + } + + return elem.disabled === disabled; + + // Try to winnow out elements that can't be disabled before trusting the disabled property. + // Some victims get caught in our net (label, legend, menu, track), but it shouldn't + // even exist on them, let alone have a boolean value. + } else if ( "label" in elem ) { + return elem.disabled === disabled; + } + + // Remaining elements are neither :enabled nor :disabled + return false; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction( function( argument ) { + argument = +argument; + return markFunction( function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ ( j = matchIndexes[ i ] ) ] ) { + seed[ j ] = !( matches[ j ] = seed[ j ] ); + } + } + } ); + } ); +} + +/** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ +function testContext( context ) { + return context && typeof context.getElementsByTagName !== "undefined" && context; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ +isXML = Sizzle.isXML = function( elem ) { + var namespace = elem.namespaceURI, + docElem = ( elem.ownerDocument || elem ).documentElement; + + // Support: IE <=8 + // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes + // https://bugs.jquery.com/ticket/4833 + return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" ); +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, subWindow, + doc = node ? node.ownerDocument || node : preferredDoc; + + // Return early if doc is invalid or already selected + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Update global variables + document = doc; + docElem = document.documentElement; + documentIsHTML = !isXML( document ); + + // Support: IE 9 - 11+, Edge 12 - 18+ + // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( preferredDoc != document && + ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) { + + // Support: IE 11, Edge + if ( subWindow.addEventListener ) { + subWindow.addEventListener( "unload", unloadHandler, false ); + + // Support: IE 9 - 10 only + } else if ( subWindow.attachEvent ) { + subWindow.attachEvent( "onunload", unloadHandler ); + } + } + + // Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only, + // Safari 4 - 5 only, Opera <=11.6 - 12.x only + // IE/Edge & older browsers don't support the :scope pseudo-class. + // Support: Safari 6.0 only + // Safari 6.0 supports :scope but it's an alias of :root there. + support.scope = assert( function( el ) { + docElem.appendChild( el ).appendChild( document.createElement( "div" ) ); + return typeof el.querySelectorAll !== "undefined" && + !el.querySelectorAll( ":scope fieldset div" ).length; + } ); + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties + // (excepting IE8 booleans) + support.attributes = assert( function( el ) { + el.className = "i"; + return !el.getAttribute( "className" ); + } ); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert( function( el ) { + el.appendChild( document.createComment( "" ) ); + return !el.getElementsByTagName( "*" ).length; + } ); + + // Support: IE<9 + support.getElementsByClassName = rnative.test( document.getElementsByClassName ); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programmatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert( function( el ) { + docElem.appendChild( el ).id = expando; + return !document.getElementsByName || !document.getElementsByName( expando ).length; + } ); + + // ID filter and find + if ( support.getById ) { + Expr.filter[ "ID" ] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute( "id" ) === attrId; + }; + }; + Expr.find[ "ID" ] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var elem = context.getElementById( id ); + return elem ? [ elem ] : []; + } + }; + } else { + Expr.filter[ "ID" ] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== "undefined" && + elem.getAttributeNode( "id" ); + return node && node.value === attrId; + }; + }; + + // Support: IE 6 - 7 only + // getElementById is not reliable as a find shortcut + Expr.find[ "ID" ] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var node, i, elems, + elem = context.getElementById( id ); + + if ( elem ) { + + // Verify the id attribute + node = elem.getAttributeNode( "id" ); + if ( node && node.value === id ) { + return [ elem ]; + } + + // Fall back on getElementsByName + elems = context.getElementsByName( id ); + i = 0; + while ( ( elem = elems[ i++ ] ) ) { + node = elem.getAttributeNode( "id" ); + if ( node && node.value === id ) { + return [ elem ]; + } + } + } + + return []; + } + }; + } + + // Tag + Expr.find[ "TAG" ] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( tag ); + + // DocumentFragment nodes don't have gEBTN + } else if ( support.qsa ) { + return context.querySelectorAll( tag ); + } + } : + + function( tag, context ) { + var elem, + tmp = [], + i = 0, + + // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( ( elem = results[ i++ ] ) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find[ "CLASS" ] = support.getElementsByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See https://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) { + + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert( function( el ) { + + var input; + + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // https://bugs.jquery.com/ticket/12359 + docElem.appendChild( el ).innerHTML = "" + + ""; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if ( el.querySelectorAll( "[msallowcapture^='']" ).length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !el.querySelectorAll( "[selected]" ).length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ + if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { + rbuggyQSA.push( "~=" ); + } + + // Support: IE 11+, Edge 15 - 18+ + // IE 11/Edge don't find elements on a `[name='']` query in some cases. + // Adding a temporary attribute to the document before the selection works + // around the issue. + // Interestingly, IE 10 & older don't seem to have the issue. + input = document.createElement( "input" ); + input.setAttribute( "name", "" ); + el.appendChild( input ); + if ( !el.querySelectorAll( "[name='']" ).length ) { + rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" + + whitespace + "*(?:''|\"\")" ); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !el.querySelectorAll( ":checked" ).length ) { + rbuggyQSA.push( ":checked" ); + } + + // Support: Safari 8+, iOS 8+ + // https://bugs.webkit.org/show_bug.cgi?id=136851 + // In-page `selector#id sibling-combinator selector` fails + if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { + rbuggyQSA.push( ".#.+[+~]" ); + } + + // Support: Firefox <=3.6 - 5 only + // Old Firefox doesn't throw on a badly-escaped identifier. + el.querySelectorAll( "\\\f" ); + rbuggyQSA.push( "[\\r\\n\\f]" ); + } ); + + assert( function( el ) { + el.innerHTML = "" + + ""; + + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = document.createElement( "input" ); + input.setAttribute( "type", "hidden" ); + el.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( el.querySelectorAll( "[name=d]" ).length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( el.querySelectorAll( ":enabled" ).length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: IE9-11+ + // IE's :disabled selector does not pick up the children of disabled fieldsets + docElem.appendChild( el ).disabled = true; + if ( el.querySelectorAll( ":disabled" ).length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: Opera 10 - 11 only + // Opera 10-11 does not throw on post-comma invalid pseudos + el.querySelectorAll( "*,:x" ); + rbuggyQSA.push( ",.*:" ); + } ); + } + + if ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector ) ) ) ) { + + assert( function( el ) { + + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( el, "*" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( el, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + } ); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( "|" ) ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully self-exclusive + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + ) ); + } : + function( a, b ) { + if ( b ) { + while ( ( b = b.parentNode ) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // Calculate position if both inputs belong to the same document + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + ( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) { + + // Choose the first element that is related to our preferred document + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( a == document || a.ownerDocument == preferredDoc && + contains( preferredDoc, a ) ) { + return -1; + } + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( b == document || b.ownerDocument == preferredDoc && + contains( preferredDoc, b ) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + /* eslint-disable eqeqeq */ + return a == document ? -1 : + b == document ? 1 : + /* eslint-enable eqeqeq */ + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( ( cur = cur.parentNode ) ) { + ap.unshift( cur ); + } + cur = b; + while ( ( cur = cur.parentNode ) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[ i ] === bp[ i ] ) { + i++; + } + + return i ? + + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[ i ], bp[ i ] ) : + + // Otherwise nodes in our document sort first + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + /* eslint-disable eqeqeq */ + ap[ i ] == preferredDoc ? -1 : + bp[ i ] == preferredDoc ? 1 : + /* eslint-enable eqeqeq */ + 0; + }; + + return document; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + setDocument( elem ); + + if ( support.matchesSelector && documentIsHTML && + !nonnativeSelectorCache[ expr + " " ] && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch ( e ) { + nonnativeSelectorCache( expr, true ); + } + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + + // Set document vars if needed + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( ( context.ownerDocument || context ) != document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + + // Set document vars if needed + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( ( elem.ownerDocument || elem ) != document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val !== undefined ? + val : + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + ( val = elem.getAttributeNode( name ) ) && val.specified ? + val.value : + null; +}; + +Sizzle.escape = function( sel ) { + return ( sel + "" ).replace( rcssescape, fcssescape ); +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( ( elem = results[ i++ ] ) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + + // If no nodeType, this is expected to be an array + while ( ( node = elem[ i++ ] ) ) { + + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[ 1 ] = match[ 1 ].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[ 3 ] = ( match[ 3 ] || match[ 4 ] || + match[ 5 ] || "" ).replace( runescape, funescape ); + + if ( match[ 2 ] === "~=" ) { + match[ 3 ] = " " + match[ 3 ] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[ 1 ] = match[ 1 ].toLowerCase(); + + if ( match[ 1 ].slice( 0, 3 ) === "nth" ) { + + // nth-* requires argument + if ( !match[ 3 ] ) { + Sizzle.error( match[ 0 ] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[ 4 ] = +( match[ 4 ] ? + match[ 5 ] + ( match[ 6 ] || 1 ) : + 2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) ); + match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" ); + + // other types prohibit arguments + } else if ( match[ 3 ] ) { + Sizzle.error( match[ 0 ] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[ 6 ] && match[ 2 ]; + + if ( matchExpr[ "CHILD" ].test( match[ 0 ] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[ 3 ] ) { + match[ 2 ] = match[ 4 ] || match[ 5 ] || ""; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + + // Get excess from tokenize (recursively) + ( excess = tokenize( unquoted, true ) ) && + + // advance to the next closing parenthesis + ( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) { + + // excess is a negative index + match[ 0 ] = match[ 0 ].slice( 0, excess ); + match[ 2 ] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { + return true; + } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + ( pattern = new RegExp( "(^|" + whitespace + + ")" + className + "(" + whitespace + "|$)" ) ) && classCache( + className, function( elem ) { + return pattern.test( + typeof elem.className === "string" && elem.className || + typeof elem.getAttribute !== "undefined" && + elem.getAttribute( "class" ) || + "" + ); + } ); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + /* eslint-disable max-len */ + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + /* eslint-enable max-len */ + + }; + }, + + "CHILD": function( type, what, _argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, _context, xml ) { + var cache, uniqueCache, outerCache, node, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType, + diff = false; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( ( node = node[ dir ] ) ) { + if ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) { + + return false; + } + } + + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + + // Seek `elem` from a previously-cached index + + // ...in a gzip-friendly way + node = parent; + outerCache = node[ expando ] || ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex && cache[ 2 ]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( ( node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + ( diff = nodeIndex = 0 ) || start.pop() ) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + } else { + + // Use previously-cached element index if available + if ( useCache ) { + + // ...in a gzip-friendly way + node = elem; + outerCache = node[ expando ] || ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex; + } + + // xml :nth-child(...) + // or :nth-last-child(...) or :nth(-last)?-of-type(...) + if ( diff === false ) { + + // Use the same loop as above to seek `elem` from the start + while ( ( node = ++nodeIndex && node && node[ dir ] || + ( diff = nodeIndex = 0 ) || start.pop() ) ) { + + if ( ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) && + ++diff ) { + + // Cache the index of each encountered element + if ( useCache ) { + outerCache = node[ expando ] || + ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + uniqueCache[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction( function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf( seed, matched[ i ] ); + seed[ idx ] = !( matches[ idx ] = matched[ i ] ); + } + } ) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + + // Potentially complex pseudos + "not": markFunction( function( selector ) { + + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction( function( seed, matches, _context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( ( elem = unmatched[ i ] ) ) { + seed[ i ] = !( matches[ i ] = elem ); + } + } + } ) : + function( elem, _context, xml ) { + input[ 0 ] = elem; + matcher( input, null, xml, results ); + + // Don't keep the element (issue #299) + input[ 0 ] = null; + return !results.pop(); + }; + } ), + + "has": markFunction( function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + } ), + + "contains": markFunction( function( text ) { + text = text.replace( runescape, funescape ); + return function( elem ) { + return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1; + }; + } ), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + + // lang value must be a valid identifier + if ( !ridentifier.test( lang || "" ) ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( ( elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( ( elem = elem.parentNode ) && elem.nodeType === 1 ); + return false; + }; + } ), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && + ( !document.hasFocus || document.hasFocus() ) && + !!( elem.type || elem.href || ~elem.tabIndex ); + }, + + // Boolean properties + "enabled": createDisabledPseudo( false ), + "disabled": createDisabledPseudo( true ), + + "checked": function( elem ) { + + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return ( nodeName === "input" && !!elem.checked ) || + ( nodeName === "option" && !!elem.selected ); + }, + + "selected": function( elem ) { + + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + // eslint-disable-next-line no-unused-expressions + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos[ "empty" ]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( ( attr = elem.getAttribute( "type" ) ) == null || + attr.toLowerCase() === "text" ); + }, + + // Position-in-collection + "first": createPositionalPseudo( function() { + return [ 0 ]; + } ), + + "last": createPositionalPseudo( function( _matchIndexes, length ) { + return [ length - 1 ]; + } ), + + "eq": createPositionalPseudo( function( _matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + } ), + + "even": createPositionalPseudo( function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "odd": createPositionalPseudo( function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "lt": createPositionalPseudo( function( matchIndexes, length, argument ) { + var i = argument < 0 ? + argument + length : + argument > length ? + length : + argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "gt": createPositionalPseudo( function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ) + } +}; + +Expr.pseudos[ "nth" ] = Expr.pseudos[ "eq" ]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +tokenize = Sizzle.tokenize = function( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || ( match = rcomma.exec( soFar ) ) ) { + if ( match ) { + + // Don't consume trailing commas as valid + soFar = soFar.slice( match[ 0 ].length ) || soFar; + } + groups.push( ( tokens = [] ) ); + } + + matched = false; + + // Combinators + if ( ( match = rcombinators.exec( soFar ) ) ) { + matched = match.shift(); + tokens.push( { + value: matched, + + // Cast descendant combinators to space + type: match[ 0 ].replace( rtrim, " " ) + } ); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] || + ( match = preFilters[ type ]( match ) ) ) ) { + matched = match.shift(); + tokens.push( { + value: matched, + type: type, + matches: match + } ); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +}; + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[ i ].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + skip = combinator.next, + key = skip || dir, + checkNonElements = base && key === "parentNode", + doneName = done++; + + return combinator.first ? + + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + return false; + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, uniqueCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching + if ( xml ) { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || ( elem[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ elem.uniqueID ] || + ( outerCache[ elem.uniqueID ] = {} ); + + if ( skip && skip === elem.nodeName.toLowerCase() ) { + elem = elem[ dir ] || elem; + } else if ( ( oldCache = uniqueCache[ key ] ) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return ( newCache[ 2 ] = oldCache[ 2 ] ); + } else { + + // Reuse newcache so results back-propagate to previous elements + uniqueCache[ key ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) { + return true; + } + } + } + } + } + return false; + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[ i ]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[ 0 ]; +} + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[ i ], results ); + } + return results; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( ( elem = unmatched[ i ] ) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction( function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( + selector || "*", + context.nodeType ? [ context ] : context, + [] + ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( ( elem = temp[ i ] ) ) { + matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem ); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( ( elem = matcherOut[ i ] ) ) { + + // Restore matcherIn since elem is not yet a final match + temp.push( ( matcherIn[ i ] = elem ) ); + } + } + postFinder( null, ( matcherOut = [] ), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( ( elem = matcherOut[ i ] ) && + ( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) { + + seed[ temp ] = !( results[ temp ] = elem ); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + } ); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[ 0 ].type ], + implicitRelative = leadingRelative || Expr.relative[ " " ], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + ( checkContext = context ).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + + // Avoid hanging onto element (issue #299) + checkContext = null; + return ret; + } ]; + + for ( ; i < len; i++ ) { + if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) { + matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; + } else { + matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[ j ].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens + .slice( 0, i - 1 ) + .concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } ) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, outermost ) { + var elem, j, matcher, + matchedCount = 0, + i = "0", + unmatched = seed && [], + setMatched = [], + contextBackup = outermostContext, + + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find[ "TAG" ]( "*", outermost ), + + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ), + len = elems.length; + + if ( outermost ) { + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + outermostContext = context == document || context || outermost; + } + + // Add elements passing elementMatchers directly to results + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id + for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( !context && elem.ownerDocument != document ) { + setDocument( elem ); + xml = !documentIsHTML; + } + while ( ( matcher = elementMatchers[ j++ ] ) ) { + if ( matcher( elem, context || document, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + + // They will have gone through all possible matchers + if ( ( elem = !matcher && elem ) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // `i` is now the count of elements visited above, and adding it to `matchedCount` + // makes the latter nonnegative. + matchedCount += i; + + // Apply set filters to unmatched elements + // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` + // equals `i`), unless we didn't visit _any_ elements in the above loop because we have + // no element matchers and no seed. + // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that + // case, which will result in a "00" `matchedCount` that differs from `i` but is also + // numerically zero. + if ( bySet && i !== matchedCount ) { + j = 0; + while ( ( matcher = setMatchers[ j++ ] ) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !( unmatched[ i ] || setMatched[ i ] ) ) { + setMatched[ i ] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + + // Generate a function of recursive functions that can be used to check each element + if ( !match ) { + match = tokenize( selector ); + } + i = match.length; + while ( i-- ) { + cached = matcherFromTokens( match[ i ] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( + selector, + matcherFromGroupMatchers( elementMatchers, setMatchers ) + ); + + // Save selector and tokenization + cached.selector = selector; + } + return cached; +}; + +/** + * A low-level selection function that works with Sizzle's compiled + * selector functions + * @param {String|Function} selector A selector or a pre-compiled + * selector function built with Sizzle.compile + * @param {Element} context + * @param {Array} [results] + * @param {Array} [seed] A set of elements to match against + */ +select = Sizzle.select = function( selector, context, results, seed ) { + var i, tokens, token, type, find, + compiled = typeof selector === "function" && selector, + match = !seed && tokenize( ( selector = compiled.selector || selector ) ); + + results = results || []; + + // Try to minimize operations if there is only one selector in the list and no seed + // (the latter of which guarantees us context) + if ( match.length === 1 ) { + + // Reduce context if the leading compound selector is an ID + tokens = match[ 0 ] = match[ 0 ].slice( 0 ); + if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" && + context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) { + + context = ( Expr.find[ "ID" ]( token.matches[ 0 ] + .replace( runescape, funescape ), context ) || [] )[ 0 ]; + if ( !context ) { + return results; + + // Precompiled matchers will still verify ancestry, so step up a level + } else if ( compiled ) { + context = context.parentNode; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr[ "needsContext" ].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[ i ]; + + // Abort if we hit a combinator + if ( Expr.relative[ ( type = token.type ) ] ) { + break; + } + if ( ( find = Expr.find[ type ] ) ) { + + // Search, expanding context for leading sibling combinators + if ( ( seed = find( + token.matches[ 0 ].replace( runescape, funescape ), + rsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) || + context + ) ) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + + // Compile and execute a filtering function if one is not provided + // Provide `match` to avoid retokenization if we modified the selector above + ( compiled || compile( selector, match ) )( + seed, + context, + !documentIsHTML, + results, + !context || rsibling.test( selector ) && testContext( context.parentNode ) || context + ); + return results; +}; + +// One-time assignments + +// Sort stability +support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando; + +// Support: Chrome 14-35+ +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = !!hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert( function( el ) { + + // Should return 1, but returns 4 (following) + return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1; +} ); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert( function( el ) { + el.innerHTML = ""; + return el.firstChild.getAttribute( "href" ) === "#"; +} ) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + } ); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert( function( el ) { + el.innerHTML = ""; + el.firstChild.setAttribute( "value", "" ); + return el.firstChild.getAttribute( "value" ) === ""; +} ) ) { + addHandle( "value", function( elem, _name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + } ); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert( function( el ) { + return el.getAttribute( "disabled" ) == null; +} ) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return elem[ name ] === true ? name.toLowerCase() : + ( val = elem.getAttributeNode( name ) ) && val.specified ? + val.value : + null; + } + } ); +} + +return Sizzle; + +} )( window ); + + + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; + +// Deprecated +jQuery.expr[ ":" ] = jQuery.expr.pseudos; +jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; +jQuery.escapeSelector = Sizzle.escape; + + + + +var dir = function( elem, dir, until ) { + var matched = [], + truncate = until !== undefined; + + while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { + if ( elem.nodeType === 1 ) { + if ( truncate && jQuery( elem ).is( until ) ) { + break; + } + matched.push( elem ); + } + } + return matched; +}; + + +var siblings = function( n, elem ) { + var matched = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + matched.push( n ); + } + } + + return matched; +}; + + +var rneedsContext = jQuery.expr.match.needsContext; + + + +function nodeName( elem, name ) { + + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + +}; +var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); + + + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + return !!qualifier.call( elem, i, elem ) !== not; + } ); + } + + // Single element + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + } ); + } + + // Arraylike of elements (jQuery, arguments, Array) + if ( typeof qualifier !== "string" ) { + return jQuery.grep( elements, function( elem ) { + return ( indexOf.call( qualifier, elem ) > -1 ) !== not; + } ); + } + + // Filtered directly for both simple and complex selectors + return jQuery.filter( qualifier, elements, not ); +} + +jQuery.filter = function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + if ( elems.length === 1 && elem.nodeType === 1 ) { + return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; + } + + return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + } ) ); +}; + +jQuery.fn.extend( { + find: function( selector ) { + var i, ret, + len = this.length, + self = this; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter( function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + } ) ); + } + + ret = this.pushStack( [] ); + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + return len > 1 ? jQuery.uniqueSort( ret ) : ret; + }, + filter: function( selector ) { + return this.pushStack( winnow( this, selector || [], false ) ); + }, + not: function( selector ) { + return this.pushStack( winnow( this, selector || [], true ) ); + }, + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + } +} ); + + +// Initialize a jQuery object + + +// A central reference to the root jQuery(document) +var rootjQuery, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + // Shortcut simple #id case for speed + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, + + init = jQuery.fn.init = function( selector, context, root ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Method init() accepts an alternate rootjQuery + // so migrate can support jQuery.sub (gh-2101) + root = root || rootjQuery; + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector[ 0 ] === "<" && + selector[ selector.length - 1 ] === ">" && + selector.length >= 3 ) { + + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && ( match[ 1 ] || !context ) ) { + + // HANDLE: $(html) -> $(array) + if ( match[ 1 ] ) { + context = context instanceof jQuery ? context[ 0 ] : context; + + // Option to run scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge( this, jQuery.parseHTML( + match[ 1 ], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + + // Properties of context are called as methods if possible + if ( isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[ 2 ] ); + + if ( elem ) { + + // Inject the element directly into the jQuery object + this[ 0 ] = elem; + this.length = 1; + } + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || root ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this[ 0 ] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( isFunction( selector ) ) { + return root.ready !== undefined ? + root.ready( selector ) : + + // Execute immediately if ready is not present + selector( jQuery ); + } + + return jQuery.makeArray( selector, this ); + }; + +// Give the init function the jQuery prototype for later instantiation +init.prototype = jQuery.fn; + +// Initialize central reference +rootjQuery = jQuery( document ); + + +var rparentsprev = /^(?:parents|prev(?:Until|All))/, + + // Methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend( { + has: function( target ) { + var targets = jQuery( target, this ), + l = targets.length; + + return this.filter( function() { + var i = 0; + for ( ; i < l; i++ ) { + if ( jQuery.contains( this, targets[ i ] ) ) { + return true; + } + } + } ); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + matched = [], + targets = typeof selectors !== "string" && jQuery( selectors ); + + // Positional selectors never match, since there's no _selection_ context + if ( !rneedsContext.test( selectors ) ) { + for ( ; i < l; i++ ) { + for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { + + // Always skip document fragments + if ( cur.nodeType < 11 && ( targets ? + targets.index( cur ) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector( cur, selectors ) ) ) { + + matched.push( cur ); + break; + } + } + } + } + + return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); + }, + + // Determine the position of an element within the set + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; + } + + // Index in selector + if ( typeof elem === "string" ) { + return indexOf.call( jQuery( elem ), this[ 0 ] ); + } + + // Locate the position of the desired element + return indexOf.call( this, + + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[ 0 ] : elem + ); + }, + + add: function( selector, context ) { + return this.pushStack( + jQuery.uniqueSort( + jQuery.merge( this.get(), jQuery( selector, context ) ) + ) + ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter( selector ) + ); + } +} ); + +function sibling( cur, dir ) { + while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} + return cur; +} + +jQuery.each( { + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, _i, until ) { + return dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, _i, until ) { + return dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, _i, until ) { + return dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return siblings( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return siblings( elem.firstChild ); + }, + contents: function( elem ) { + if ( elem.contentDocument != null && + + // Support: IE 11+ + // elements with no `data` attribute has an object + // `contentDocument` with a `null` prototype. + getProto( elem.contentDocument ) ) { + + return elem.contentDocument; + } + + // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only + // Treat the template element as a regular one in browsers that + // don't support it. + if ( nodeName( elem, "template" ) ) { + elem = elem.content || elem; + } + + return jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var matched = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + matched = jQuery.filter( selector, matched ); + } + + if ( this.length > 1 ) { + + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + jQuery.uniqueSort( matched ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + matched.reverse(); + } + } + + return this.pushStack( matched ); + }; +} ); +var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); + + + +// Convert String-formatted options into Object-formatted ones +function createOptions( options ) { + var object = {}; + jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { + object[ flag ] = true; + } ); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + createOptions( options ) : + jQuery.extend( {}, options ); + + var // Flag to know if list is currently firing + firing, + + // Last fire value for non-forgettable lists + memory, + + // Flag to know if list was already fired + fired, + + // Flag to prevent firing + locked, + + // Actual callback list + list = [], + + // Queue of execution data for repeatable lists + queue = [], + + // Index of currently firing callback (modified by add/remove as needed) + firingIndex = -1, + + // Fire callbacks + fire = function() { + + // Enforce single-firing + locked = locked || options.once; + + // Execute callbacks for all pending executions, + // respecting firingIndex overrides and runtime changes + fired = firing = true; + for ( ; queue.length; firingIndex = -1 ) { + memory = queue.shift(); + while ( ++firingIndex < list.length ) { + + // Run callback and check for early termination + if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && + options.stopOnFalse ) { + + // Jump to end and forget the data so .add doesn't re-fire + firingIndex = list.length; + memory = false; + } + } + } + + // Forget the data if we're done with it + if ( !options.memory ) { + memory = false; + } + + firing = false; + + // Clean up if we're done firing for good + if ( locked ) { + + // Keep an empty list if we have data for future add calls + if ( memory ) { + list = []; + + // Otherwise, this object is spent + } else { + list = ""; + } + } + }, + + // Actual Callbacks object + self = { + + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + + // If we have memory from a past run, we should fire after adding + if ( memory && !firing ) { + firingIndex = list.length - 1; + queue.push( memory ); + } + + ( function add( args ) { + jQuery.each( args, function( _, arg ) { + if ( isFunction( arg ) ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && toType( arg ) !== "string" ) { + + // Inspect recursively + add( arg ); + } + } ); + } )( arguments ); + + if ( memory && !firing ) { + fire(); + } + } + return this; + }, + + // Remove a callback from the list + remove: function() { + jQuery.each( arguments, function( _, arg ) { + var index; + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + + // Handle firing indexes + if ( index <= firingIndex ) { + firingIndex--; + } + } + } ); + return this; + }, + + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? + jQuery.inArray( fn, list ) > -1 : + list.length > 0; + }, + + // Remove all callbacks from the list + empty: function() { + if ( list ) { + list = []; + } + return this; + }, + + // Disable .fire and .add + // Abort any current/pending executions + // Clear all callbacks and values + disable: function() { + locked = queue = []; + list = memory = ""; + return this; + }, + disabled: function() { + return !list; + }, + + // Disable .fire + // Also disable .add unless we have memory (since it would have no effect) + // Abort any pending executions + lock: function() { + locked = queue = []; + if ( !memory && !firing ) { + list = memory = ""; + } + return this; + }, + locked: function() { + return !!locked; + }, + + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( !locked ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + queue.push( args ); + if ( !firing ) { + fire(); + } + } + return this; + }, + + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + +function Identity( v ) { + return v; +} +function Thrower( ex ) { + throw ex; +} + +function adoptValue( value, resolve, reject, noValue ) { + var method; + + try { + + // Check for promise aspect first to privilege synchronous behavior + if ( value && isFunction( ( method = value.promise ) ) ) { + method.call( value ).done( resolve ).fail( reject ); + + // Other thenables + } else if ( value && isFunction( ( method = value.then ) ) ) { + method.call( value, resolve, reject ); + + // Other non-thenables + } else { + + // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: + // * false: [ value ].slice( 0 ) => resolve( value ) + // * true: [ value ].slice( 1 ) => resolve() + resolve.apply( undefined, [ value ].slice( noValue ) ); + } + + // For Promises/A+, convert exceptions into rejections + // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in + // Deferred#then to conditionally suppress rejection. + } catch ( value ) { + + // Support: Android 4.0 only + // Strict mode functions invoked without .call/.apply get global-object context + reject.apply( undefined, [ value ] ); + } +} + +jQuery.extend( { + + Deferred: function( func ) { + var tuples = [ + + // action, add listener, callbacks, + // ... .then handlers, argument index, [final state] + [ "notify", "progress", jQuery.Callbacks( "memory" ), + jQuery.Callbacks( "memory" ), 2 ], + [ "resolve", "done", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 0, "resolved" ], + [ "reject", "fail", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 1, "rejected" ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + "catch": function( fn ) { + return promise.then( null, fn ); + }, + + // Keep pipe for back-compat + pipe: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + + return jQuery.Deferred( function( newDefer ) { + jQuery.each( tuples, function( _i, tuple ) { + + // Map tuples (progress, done, fail) to arguments (done, fail, progress) + var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; + + // deferred.progress(function() { bind to newDefer or newDefer.notify }) + // deferred.done(function() { bind to newDefer or newDefer.resolve }) + // deferred.fail(function() { bind to newDefer or newDefer.reject }) + deferred[ tuple[ 1 ] ]( function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && isFunction( returned.promise ) ) { + returned.promise() + .progress( newDefer.notify ) + .done( newDefer.resolve ) + .fail( newDefer.reject ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( + this, + fn ? [ returned ] : arguments + ); + } + } ); + } ); + fns = null; + } ).promise(); + }, + then: function( onFulfilled, onRejected, onProgress ) { + var maxDepth = 0; + function resolve( depth, deferred, handler, special ) { + return function() { + var that = this, + args = arguments, + mightThrow = function() { + var returned, then; + + // Support: Promises/A+ section 2.3.3.3.3 + // https://promisesaplus.com/#point-59 + // Ignore double-resolution attempts + if ( depth < maxDepth ) { + return; + } + + returned = handler.apply( that, args ); + + // Support: Promises/A+ section 2.3.1 + // https://promisesaplus.com/#point-48 + if ( returned === deferred.promise() ) { + throw new TypeError( "Thenable self-resolution" ); + } + + // Support: Promises/A+ sections 2.3.3.1, 3.5 + // https://promisesaplus.com/#point-54 + // https://promisesaplus.com/#point-75 + // Retrieve `then` only once + then = returned && + + // Support: Promises/A+ section 2.3.4 + // https://promisesaplus.com/#point-64 + // Only check objects and functions for thenability + ( typeof returned === "object" || + typeof returned === "function" ) && + returned.then; + + // Handle a returned thenable + if ( isFunction( then ) ) { + + // Special processors (notify) just wait for resolution + if ( special ) { + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ) + ); + + // Normal processors (resolve) also hook into progress + } else { + + // ...and disregard older resolution values + maxDepth++; + + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ), + resolve( maxDepth, deferred, Identity, + deferred.notifyWith ) + ); + } + + // Handle all other returned values + } else { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Identity ) { + that = undefined; + args = [ returned ]; + } + + // Process the value(s) + // Default process is resolve + ( special || deferred.resolveWith )( that, args ); + } + }, + + // Only normal processors (resolve) catch and reject exceptions + process = special ? + mightThrow : + function() { + try { + mightThrow(); + } catch ( e ) { + + if ( jQuery.Deferred.exceptionHook ) { + jQuery.Deferred.exceptionHook( e, + process.stackTrace ); + } + + // Support: Promises/A+ section 2.3.3.3.4.1 + // https://promisesaplus.com/#point-61 + // Ignore post-resolution exceptions + if ( depth + 1 >= maxDepth ) { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Thrower ) { + that = undefined; + args = [ e ]; + } + + deferred.rejectWith( that, args ); + } + } + }; + + // Support: Promises/A+ section 2.3.3.3.1 + // https://promisesaplus.com/#point-57 + // Re-resolve promises immediately to dodge false rejection from + // subsequent errors + if ( depth ) { + process(); + } else { + + // Call an optional hook to record the stack, in case of exception + // since it's otherwise lost when execution goes async + if ( jQuery.Deferred.getStackHook ) { + process.stackTrace = jQuery.Deferred.getStackHook(); + } + window.setTimeout( process ); + } + }; + } + + return jQuery.Deferred( function( newDefer ) { + + // progress_handlers.add( ... ) + tuples[ 0 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onProgress ) ? + onProgress : + Identity, + newDefer.notifyWith + ) + ); + + // fulfilled_handlers.add( ... ) + tuples[ 1 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onFulfilled ) ? + onFulfilled : + Identity + ) + ); + + // rejected_handlers.add( ... ) + tuples[ 2 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onRejected ) ? + onRejected : + Thrower + ) + ); + } ).promise(); + }, + + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 5 ]; + + // promise.progress = list.add + // promise.done = list.add + // promise.fail = list.add + promise[ tuple[ 1 ] ] = list.add; + + // Handle state + if ( stateString ) { + list.add( + function() { + + // state = "resolved" (i.e., fulfilled) + // state = "rejected" + state = stateString; + }, + + // rejected_callbacks.disable + // fulfilled_callbacks.disable + tuples[ 3 - i ][ 2 ].disable, + + // rejected_handlers.disable + // fulfilled_handlers.disable + tuples[ 3 - i ][ 3 ].disable, + + // progress_callbacks.lock + tuples[ 0 ][ 2 ].lock, + + // progress_handlers.lock + tuples[ 0 ][ 3 ].lock + ); + } + + // progress_handlers.fire + // fulfilled_handlers.fire + // rejected_handlers.fire + list.add( tuple[ 3 ].fire ); + + // deferred.notify = function() { deferred.notifyWith(...) } + // deferred.resolve = function() { deferred.resolveWith(...) } + // deferred.reject = function() { deferred.rejectWith(...) } + deferred[ tuple[ 0 ] ] = function() { + deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); + return this; + }; + + // deferred.notifyWith = list.fireWith + // deferred.resolveWith = list.fireWith + // deferred.rejectWith = list.fireWith + deferred[ tuple[ 0 ] + "With" ] = list.fireWith; + } ); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( singleValue ) { + var + + // count of uncompleted subordinates + remaining = arguments.length, + + // count of unprocessed arguments + i = remaining, + + // subordinate fulfillment data + resolveContexts = Array( i ), + resolveValues = slice.call( arguments ), + + // the master Deferred + master = jQuery.Deferred(), + + // subordinate callback factory + updateFunc = function( i ) { + return function( value ) { + resolveContexts[ i ] = this; + resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; + if ( !( --remaining ) ) { + master.resolveWith( resolveContexts, resolveValues ); + } + }; + }; + + // Single- and empty arguments are adopted like Promise.resolve + if ( remaining <= 1 ) { + adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject, + !remaining ); + + // Use .then() to unwrap secondary thenables (cf. gh-3000) + if ( master.state() === "pending" || + isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { + + return master.then(); + } + } + + // Multiple arguments are aggregated like Promise.all array elements + while ( i-- ) { + adoptValue( resolveValues[ i ], updateFunc( i ), master.reject ); + } + + return master.promise(); + } +} ); + + +// These usually indicate a programmer mistake during development, +// warn about them ASAP rather than swallowing them by default. +var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; + +jQuery.Deferred.exceptionHook = function( error, stack ) { + + // Support: IE 8 - 9 only + // Console exists when dev tools are open, which can happen at any time + if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { + window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack ); + } +}; + + + + +jQuery.readyException = function( error ) { + window.setTimeout( function() { + throw error; + } ); +}; + + + + +// The deferred used on DOM ready +var readyList = jQuery.Deferred(); + +jQuery.fn.ready = function( fn ) { + + readyList + .then( fn ) + + // Wrap jQuery.readyException in a function so that the lookup + // happens at the time of error handling instead of callback + // registration. + .catch( function( error ) { + jQuery.readyException( error ); + } ); + + return this; +}; + +jQuery.extend( { + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + } +} ); + +jQuery.ready.then = readyList.then; + +// The ready event handler and self cleanup method +function completed() { + document.removeEventListener( "DOMContentLoaded", completed ); + window.removeEventListener( "load", completed ); + jQuery.ready(); +} + +// Catch cases where $(document).ready() is called +// after the browser event has already occurred. +// Support: IE <=9 - 10 only +// Older IE sometimes signals "interactive" too soon +if ( document.readyState === "complete" || + ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { + + // Handle it asynchronously to allow scripts the opportunity to delay ready + window.setTimeout( jQuery.ready ); + +} else { + + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed ); +} + + + + +// Multifunctional method to get and set values of a collection +// The value/s can optionally be executed if it's a function +var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + len = elems.length, + bulk = key == null; + + // Sets many values + if ( toType( key ) === "object" ) { + chainable = true; + for ( i in key ) { + access( elems, fn, i, key[ i ], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, _key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < len; i++ ) { + fn( + elems[ i ], key, raw ? + value : + value.call( elems[ i ], i, fn( elems[ i ], key ) ) + ); + } + } + } + + if ( chainable ) { + return elems; + } + + // Gets + if ( bulk ) { + return fn.call( elems ); + } + + return len ? fn( elems[ 0 ], key ) : emptyGet; +}; + + +// Matches dashed string for camelizing +var rmsPrefix = /^-ms-/, + rdashAlpha = /-([a-z])/g; + +// Used by camelCase as callback to replace() +function fcamelCase( _all, letter ) { + return letter.toUpperCase(); +} + +// Convert dashed to camelCase; used by the css and data modules +// Support: IE <=9 - 11, Edge 12 - 15 +// Microsoft forgot to hump their vendor prefix (#9572) +function camelCase( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); +} +var acceptData = function( owner ) { + + // Accepts only: + // - Node + // - Node.ELEMENT_NODE + // - Node.DOCUMENT_NODE + // - Object + // - Any + return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); +}; + + + + +function Data() { + this.expando = jQuery.expando + Data.uid++; +} + +Data.uid = 1; + +Data.prototype = { + + cache: function( owner ) { + + // Check if the owner object already has a cache + var value = owner[ this.expando ]; + + // If not, create one + if ( !value ) { + value = {}; + + // We can accept data for non-element nodes in modern browsers, + // but we should not, see #8335. + // Always return an empty object. + if ( acceptData( owner ) ) { + + // If it is a node unlikely to be stringify-ed or looped over + // use plain assignment + if ( owner.nodeType ) { + owner[ this.expando ] = value; + + // Otherwise secure it in a non-enumerable property + // configurable must be true to allow the property to be + // deleted when data is removed + } else { + Object.defineProperty( owner, this.expando, { + value: value, + configurable: true + } ); + } + } + } + + return value; + }, + set: function( owner, data, value ) { + var prop, + cache = this.cache( owner ); + + // Handle: [ owner, key, value ] args + // Always use camelCase key (gh-2257) + if ( typeof data === "string" ) { + cache[ camelCase( data ) ] = value; + + // Handle: [ owner, { properties } ] args + } else { + + // Copy the properties one-by-one to the cache object + for ( prop in data ) { + cache[ camelCase( prop ) ] = data[ prop ]; + } + } + return cache; + }, + get: function( owner, key ) { + return key === undefined ? + this.cache( owner ) : + + // Always use camelCase key (gh-2257) + owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; + }, + access: function( owner, key, value ) { + + // In cases where either: + // + // 1. No key was specified + // 2. A string key was specified, but no value provided + // + // Take the "read" path and allow the get method to determine + // which value to return, respectively either: + // + // 1. The entire cache object + // 2. The data stored at the key + // + if ( key === undefined || + ( ( key && typeof key === "string" ) && value === undefined ) ) { + + return this.get( owner, key ); + } + + // When the key is not a string, or both a key and value + // are specified, set or extend (existing objects) with either: + // + // 1. An object of properties + // 2. A key and value + // + this.set( owner, key, value ); + + // Since the "set" path can have two possible entry points + // return the expected data based on which path was taken[*] + return value !== undefined ? value : key; + }, + remove: function( owner, key ) { + var i, + cache = owner[ this.expando ]; + + if ( cache === undefined ) { + return; + } + + if ( key !== undefined ) { + + // Support array or space separated string of keys + if ( Array.isArray( key ) ) { + + // If key is an array of keys... + // We always set camelCase keys, so remove that. + key = key.map( camelCase ); + } else { + key = camelCase( key ); + + // If a key with the spaces exists, use it. + // Otherwise, create an array by matching non-whitespace + key = key in cache ? + [ key ] : + ( key.match( rnothtmlwhite ) || [] ); + } + + i = key.length; + + while ( i-- ) { + delete cache[ key[ i ] ]; + } + } + + // Remove the expando if there's no more data + if ( key === undefined || jQuery.isEmptyObject( cache ) ) { + + // Support: Chrome <=35 - 45 + // Webkit & Blink performance suffers when deleting properties + // from DOM nodes, so set to undefined instead + // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) + if ( owner.nodeType ) { + owner[ this.expando ] = undefined; + } else { + delete owner[ this.expando ]; + } + } + }, + hasData: function( owner ) { + var cache = owner[ this.expando ]; + return cache !== undefined && !jQuery.isEmptyObject( cache ); + } +}; +var dataPriv = new Data(); + +var dataUser = new Data(); + + + +// Implementation Summary +// +// 1. Enforce API surface and semantic compatibility with 1.9.x branch +// 2. Improve the module's maintainability by reducing the storage +// paths to a single mechanism. +// 3. Use the same single mechanism to support "private" and "user" data. +// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) +// 5. Avoid exposing implementation details on user objects (eg. expando properties) +// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 + +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, + rmultiDash = /[A-Z]/g; + +function getData( data ) { + if ( data === "true" ) { + return true; + } + + if ( data === "false" ) { + return false; + } + + if ( data === "null" ) { + return null; + } + + // Only convert to a number if it doesn't change the string + if ( data === +data + "" ) { + return +data; + } + + if ( rbrace.test( data ) ) { + return JSON.parse( data ); + } + + return data; +} + +function dataAttr( elem, key, data ) { + var name; + + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = getData( data ); + } catch ( e ) {} + + // Make sure we set the data so it isn't changed later + dataUser.set( elem, key, data ); + } else { + data = undefined; + } + } + return data; +} + +jQuery.extend( { + hasData: function( elem ) { + return dataUser.hasData( elem ) || dataPriv.hasData( elem ); + }, + + data: function( elem, name, data ) { + return dataUser.access( elem, name, data ); + }, + + removeData: function( elem, name ) { + dataUser.remove( elem, name ); + }, + + // TODO: Now that all calls to _data and _removeData have been replaced + // with direct calls to dataPriv methods, these can be deprecated. + _data: function( elem, name, data ) { + return dataPriv.access( elem, name, data ); + }, + + _removeData: function( elem, name ) { + dataPriv.remove( elem, name ); + } +} ); + +jQuery.fn.extend( { + data: function( key, value ) { + var i, name, data, + elem = this[ 0 ], + attrs = elem && elem.attributes; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = dataUser.get( elem ); + + if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { + i = attrs.length; + while ( i-- ) { + + // Support: IE 11 only + // The attrs elements can be null (#14894) + if ( attrs[ i ] ) { + name = attrs[ i ].name; + if ( name.indexOf( "data-" ) === 0 ) { + name = camelCase( name.slice( 5 ) ); + dataAttr( elem, name, data[ name ] ); + } + } + } + dataPriv.set( elem, "hasDataAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each( function() { + dataUser.set( this, key ); + } ); + } + + return access( this, function( value ) { + var data; + + // The calling jQuery object (element matches) is not empty + // (and therefore has an element appears at this[ 0 ]) and the + // `value` parameter was not undefined. An empty jQuery object + // will result in `undefined` for elem = this[ 0 ] which will + // throw an exception if an attempt to read a data cache is made. + if ( elem && value === undefined ) { + + // Attempt to get data from the cache + // The key will always be camelCased in Data + data = dataUser.get( elem, key ); + if ( data !== undefined ) { + return data; + } + + // Attempt to "discover" the data in + // HTML5 custom data-* attrs + data = dataAttr( elem, key ); + if ( data !== undefined ) { + return data; + } + + // We tried really hard, but the data doesn't exist. + return; + } + + // Set the data... + this.each( function() { + + // We always store the camelCased key + dataUser.set( this, key, value ); + } ); + }, null, value, arguments.length > 1, null, true ); + }, + + removeData: function( key ) { + return this.each( function() { + dataUser.remove( this, key ); + } ); + } +} ); + + +jQuery.extend( { + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = dataPriv.get( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || Array.isArray( data ) ) { + queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // Clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // Not public - generate a queueHooks object, or return the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { + empty: jQuery.Callbacks( "once memory" ).add( function() { + dataPriv.remove( elem, [ type + "queue", key ] ); + } ) + } ); + } +} ); + +jQuery.fn.extend( { + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[ 0 ], type ); + } + + return data === undefined ? + this : + this.each( function() { + var queue = jQuery.queue( this, type, data ); + + // Ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + } ); + }, + dequeue: function( type ) { + return this.each( function() { + jQuery.dequeue( this, type ); + } ); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while ( i-- ) { + tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +} ); +var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; + +var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); + + +var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; + +var documentElement = document.documentElement; + + + + var isAttached = function( elem ) { + return jQuery.contains( elem.ownerDocument, elem ); + }, + composed = { composed: true }; + + // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only + // Check attachment across shadow DOM boundaries when possible (gh-3504) + // Support: iOS 10.0-10.2 only + // Early iOS 10 versions support `attachShadow` but not `getRootNode`, + // leading to errors. We need to check for `getRootNode`. + if ( documentElement.getRootNode ) { + isAttached = function( elem ) { + return jQuery.contains( elem.ownerDocument, elem ) || + elem.getRootNode( composed ) === elem.ownerDocument; + }; + } +var isHiddenWithinTree = function( elem, el ) { + + // isHiddenWithinTree might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + + // Inline style trumps all + return elem.style.display === "none" || + elem.style.display === "" && + + // Otherwise, check computed style + // Support: Firefox <=43 - 45 + // Disconnected elements can have computed display: none, so first confirm that elem is + // in the document. + isAttached( elem ) && + + jQuery.css( elem, "display" ) === "none"; + }; + + + +function adjustCSS( elem, prop, valueParts, tween ) { + var adjusted, scale, + maxIterations = 20, + currentValue = tween ? + function() { + return tween.cur(); + } : + function() { + return jQuery.css( elem, prop, "" ); + }, + initial = currentValue(), + unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), + + // Starting value computation is required for potential unit mismatches + initialInUnit = elem.nodeType && + ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && + rcssNum.exec( jQuery.css( elem, prop ) ); + + if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { + + // Support: Firefox <=54 + // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) + initial = initial / 2; + + // Trust units reported by jQuery.css + unit = unit || initialInUnit[ 3 ]; + + // Iteratively approximate from a nonzero starting point + initialInUnit = +initial || 1; + + while ( maxIterations-- ) { + + // Evaluate and update our best guess (doubling guesses that zero out). + // Finish if the scale equals or crosses 1 (making the old*new product non-positive). + jQuery.style( elem, prop, initialInUnit + unit ); + if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) { + maxIterations = 0; + } + initialInUnit = initialInUnit / scale; + + } + + initialInUnit = initialInUnit * 2; + jQuery.style( elem, prop, initialInUnit + unit ); + + // Make sure we update the tween properties later on + valueParts = valueParts || []; + } + + if ( valueParts ) { + initialInUnit = +initialInUnit || +initial || 0; + + // Apply relative offset (+=/-=) if specified + adjusted = valueParts[ 1 ] ? + initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : + +valueParts[ 2 ]; + if ( tween ) { + tween.unit = unit; + tween.start = initialInUnit; + tween.end = adjusted; + } + } + return adjusted; +} + + +var defaultDisplayMap = {}; + +function getDefaultDisplay( elem ) { + var temp, + doc = elem.ownerDocument, + nodeName = elem.nodeName, + display = defaultDisplayMap[ nodeName ]; + + if ( display ) { + return display; + } + + temp = doc.body.appendChild( doc.createElement( nodeName ) ); + display = jQuery.css( temp, "display" ); + + temp.parentNode.removeChild( temp ); + + if ( display === "none" ) { + display = "block"; + } + defaultDisplayMap[ nodeName ] = display; + + return display; +} + +function showHide( elements, show ) { + var display, elem, + values = [], + index = 0, + length = elements.length; + + // Determine new display value for elements that need to change + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + + display = elem.style.display; + if ( show ) { + + // Since we force visibility upon cascade-hidden elements, an immediate (and slow) + // check is required in this first loop unless we have a nonempty display value (either + // inline or about-to-be-restored) + if ( display === "none" ) { + values[ index ] = dataPriv.get( elem, "display" ) || null; + if ( !values[ index ] ) { + elem.style.display = ""; + } + } + if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { + values[ index ] = getDefaultDisplay( elem ); + } + } else { + if ( display !== "none" ) { + values[ index ] = "none"; + + // Remember what we're overwriting + dataPriv.set( elem, "display", display ); + } + } + } + + // Set the display of the elements in a second loop to avoid constant reflow + for ( index = 0; index < length; index++ ) { + if ( values[ index ] != null ) { + elements[ index ].style.display = values[ index ]; + } + } + + return elements; +} + +jQuery.fn.extend( { + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state ) { + if ( typeof state === "boolean" ) { + return state ? this.show() : this.hide(); + } + + return this.each( function() { + if ( isHiddenWithinTree( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + } ); + } +} ); +var rcheckableType = ( /^(?:checkbox|radio)$/i ); + +var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i ); + +var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i ); + + + +( function() { + var fragment = document.createDocumentFragment(), + div = fragment.appendChild( document.createElement( "div" ) ), + input = document.createElement( "input" ); + + // Support: Android 4.0 - 4.3 only + // Check state lost if the name is set (#11217) + // Support: Windows Web Apps (WWA) + // `name` and `type` must use .setAttribute for WWA (#14901) + input.setAttribute( "type", "radio" ); + input.setAttribute( "checked", "checked" ); + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + + // Support: Android <=4.1 only + // Older WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE <=11 only + // Make sure textarea (and checkbox) defaultValue is properly cloned + div.innerHTML = ""; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; + + // Support: IE <=9 only + // IE <=9 replaces "; + support.option = !!div.lastChild; +} )(); + + +// We have to close these tags to support XHTML (#13200) +var wrapMap = { + + // XHTML parsers do not magically insert elements in the + // same way that tag soup parsers do. So we cannot shorten + // this by omitting or other required elements. + thead: [ 1, "", "
" ], + col: [ 2, "", "
" ], + tr: [ 2, "", "
" ], + td: [ 3, "", "
" ], + + _default: [ 0, "", "" ] +}; + +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// Support: IE <=9 only +if ( !support.option ) { + wrapMap.optgroup = wrapMap.option = [ 1, "" ]; +} + + +function getAll( context, tag ) { + + // Support: IE <=9 - 11 only + // Use typeof to avoid zero-argument method invocation on host objects (#15151) + var ret; + + if ( typeof context.getElementsByTagName !== "undefined" ) { + ret = context.getElementsByTagName( tag || "*" ); + + } else if ( typeof context.querySelectorAll !== "undefined" ) { + ret = context.querySelectorAll( tag || "*" ); + + } else { + ret = []; + } + + if ( tag === undefined || tag && nodeName( context, tag ) ) { + return jQuery.merge( [ context ], ret ); + } + + return ret; +} + + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + dataPriv.set( + elems[ i ], + "globalEval", + !refElements || dataPriv.get( refElements[ i ], "globalEval" ) + ); + } +} + + +var rhtml = /<|&#?\w+;/; + +function buildFragment( elems, context, scripts, selection, ignored ) { + var elem, tmp, tag, wrap, attached, j, + fragment = context.createDocumentFragment(), + nodes = [], + i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( toType( elem ) === "object" ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); + + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; + + // Descend through wrappers to the right content + j = wrap[ 0 ]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, tmp.childNodes ); + + // Remember the top-level container + tmp = fragment.firstChild; + + // Ensure the created nodes are orphaned (#12392) + tmp.textContent = ""; + } + } + } + + // Remove wrapper from fragment + fragment.textContent = ""; + + i = 0; + while ( ( elem = nodes[ i++ ] ) ) { + + // Skip elements already in the context collection (trac-4087) + if ( selection && jQuery.inArray( elem, selection ) > -1 ) { + if ( ignored ) { + ignored.push( elem ); + } + continue; + } + + attached = isAttached( elem ); + + // Append to fragment + tmp = getAll( fragment.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( attached ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( ( elem = tmp[ j++ ] ) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + return fragment; +} + + +var + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +// Support: IE <=9 - 11+ +// focus() and blur() are asynchronous, except when they are no-op. +// So expect focus to be synchronous when the element is already active, +// and blur to be synchronous when the element is not already active. +// (focus and blur are always synchronous in other supported browsers, +// this just defines when we can count on it). +function expectSync( elem, type ) { + return ( elem === safeActiveElement() ) === ( type === "focus" ); +} + +// Support: IE <=9 only +// Accessing document.activeElement can throw unexpectedly +// https://bugs.jquery.com/ticket/13393 +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +function on( elem, types, selector, data, fn, one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + on( elem, type, selector, data, types[ type ], one ); + } + return elem; + } + + if ( data == null && fn == null ) { + + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return elem; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return elem.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + } ); +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + + var handleObjIn, eventHandle, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.get( elem ); + + // Only attach events to objects that accept data + if ( !acceptData( elem ) ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Ensure that invalid selectors throw exceptions at attach time + // Evaluate against documentElement in case elem is a non-element node (e.g., document) + if ( selector ) { + jQuery.find.matchesSelector( documentElement, selector ); + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !( events = elemData.events ) ) { + events = elemData.events = Object.create( null ); + } + if ( !( eventHandle = elemData.handle ) ) { + eventHandle = elemData.handle = function( e ) { + + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? + jQuery.event.dispatch.apply( elem, arguments ) : undefined; + }; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend( { + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join( "." ) + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !( handlers = events[ type ] ) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener if the special events handler returns false + if ( !special.setup || + special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var j, origCount, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); + + if ( !elemData || !( events = elemData.events ) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[ 2 ] && + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || + selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || + special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove data and the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + dataPriv.remove( elem, "handle events" ); + } + }, + + dispatch: function( nativeEvent ) { + + var i, j, ret, matched, handleObj, handlerQueue, + args = new Array( arguments.length ), + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( nativeEvent ), + + handlers = ( + dataPriv.get( this, "events" ) || Object.create( null ) + )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[ 0 ] = event; + + for ( i = 1; i < arguments.length; i++ ) { + args[ i ] = arguments[ i ]; + } + + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( ( handleObj = matched.handlers[ j++ ] ) && + !event.isImmediatePropagationStopped() ) { + + // If the event is namespaced, then each handler is only invoked if it is + // specially universal or its namespaces are a superset of the event's. + if ( !event.rnamespace || handleObj.namespace === false || + event.rnamespace.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || + handleObj.handler ).apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( ( event.result = ret ) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var i, handleObj, sel, matchedHandlers, matchedSelectors, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + if ( delegateCount && + + // Support: IE <=9 + // Black-hole SVG instance trees (trac-13180) + cur.nodeType && + + // Support: Firefox <=42 + // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) + // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click + // Support: IE 11 only + // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) + !( event.type === "click" && event.button >= 1 ) ) { + + for ( ; cur !== this; cur = cur.parentNode || this ) { + + // Don't check non-elements (#13208) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { + matchedHandlers = []; + matchedSelectors = {}; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matchedSelectors[ sel ] === undefined ) { + matchedSelectors[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) > -1 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matchedSelectors[ sel ] ) { + matchedHandlers.push( handleObj ); + } + } + if ( matchedHandlers.length ) { + handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); + } + } + } + } + + // Add the remaining (directly-bound) handlers + cur = this; + if ( delegateCount < handlers.length ) { + handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); + } + + return handlerQueue; + }, + + addProp: function( name, hook ) { + Object.defineProperty( jQuery.Event.prototype, name, { + enumerable: true, + configurable: true, + + get: isFunction( hook ) ? + function() { + if ( this.originalEvent ) { + return hook( this.originalEvent ); + } + } : + function() { + if ( this.originalEvent ) { + return this.originalEvent[ name ]; + } + }, + + set: function( value ) { + Object.defineProperty( this, name, { + enumerable: true, + configurable: true, + writable: true, + value: value + } ); + } + } ); + }, + + fix: function( originalEvent ) { + return originalEvent[ jQuery.expando ] ? + originalEvent : + new jQuery.Event( originalEvent ); + }, + + special: { + load: { + + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + click: { + + // Utilize native event to ensure correct state for checkable inputs + setup: function( data ) { + + // For mutual compressibility with _default, replace `this` access with a local var. + // `|| data` is dead code meant only to preserve the variable through minification. + var el = this || data; + + // Claim the first handler + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { + + // dataPriv.set( el, "click", ... ) + leverageNative( el, "click", returnTrue ); + } + + // Return false to allow normal processing in the caller + return false; + }, + trigger: function( data ) { + + // For mutual compressibility with _default, replace `this` access with a local var. + // `|| data` is dead code meant only to preserve the variable through minification. + var el = this || data; + + // Force setup before triggering a click + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { + + leverageNative( el, "click" ); + } + + // Return non-false to allow normal event-path propagation + return true; + }, + + // For cross-browser consistency, suppress native .click() on links + // Also prevent it if we're currently inside a leveraged native-event stack + _default: function( event ) { + var target = event.target; + return rcheckableType.test( target.type ) && + target.click && nodeName( target, "input" ) && + dataPriv.get( target, "click" ) || + nodeName( target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Support: Firefox 20+ + // Firefox doesn't alert if the returnValue field is not set. + if ( event.result !== undefined && event.originalEvent ) { + event.originalEvent.returnValue = event.result; + } + } + } + } +}; + +// Ensure the presence of an event listener that handles manually-triggered +// synthetic events by interrupting progress until reinvoked in response to +// *native* events that it fires directly, ensuring that state changes have +// already occurred before other listeners are invoked. +function leverageNative( el, type, expectSync ) { + + // Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add + if ( !expectSync ) { + if ( dataPriv.get( el, type ) === undefined ) { + jQuery.event.add( el, type, returnTrue ); + } + return; + } + + // Register the controller as a special universal handler for all event namespaces + dataPriv.set( el, type, false ); + jQuery.event.add( el, type, { + namespace: false, + handler: function( event ) { + var notAsync, result, + saved = dataPriv.get( this, type ); + + if ( ( event.isTrigger & 1 ) && this[ type ] ) { + + // Interrupt processing of the outer synthetic .trigger()ed event + // Saved data should be false in such cases, but might be a leftover capture object + // from an async native handler (gh-4350) + if ( !saved.length ) { + + // Store arguments for use when handling the inner native event + // There will always be at least one argument (an event object), so this array + // will not be confused with a leftover capture object. + saved = slice.call( arguments ); + dataPriv.set( this, type, saved ); + + // Trigger the native event and capture its result + // Support: IE <=9 - 11+ + // focus() and blur() are asynchronous + notAsync = expectSync( this, type ); + this[ type ](); + result = dataPriv.get( this, type ); + if ( saved !== result || notAsync ) { + dataPriv.set( this, type, false ); + } else { + result = {}; + } + if ( saved !== result ) { + + // Cancel the outer synthetic event + event.stopImmediatePropagation(); + event.preventDefault(); + return result.value; + } + + // If this is an inner synthetic event for an event with a bubbling surrogate + // (focus or blur), assume that the surrogate already propagated from triggering the + // native event and prevent that from happening again here. + // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the + // bubbling surrogate propagates *after* the non-bubbling base), but that seems + // less bad than duplication. + } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) { + event.stopPropagation(); + } + + // If this is a native event triggered above, everything is now in order + // Fire an inner synthetic event with the original arguments + } else if ( saved.length ) { + + // ...and capture the result + dataPriv.set( this, type, { + value: jQuery.event.trigger( + + // Support: IE <=9 - 11+ + // Extend with the prototype to reset the above stopImmediatePropagation() + jQuery.extend( saved[ 0 ], jQuery.Event.prototype ), + saved.slice( 1 ), + this + ) + } ); + + // Abort handling of the native event + event.stopImmediatePropagation(); + } + } + } ); +} + +jQuery.removeEvent = function( elem, type, handle ) { + + // This "if" is needed for plain objects + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle ); + } +}; + +jQuery.Event = function( src, props ) { + + // Allow instantiation without the 'new' keyword + if ( !( this instanceof jQuery.Event ) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented || + src.defaultPrevented === undefined && + + // Support: Android <=2.3 only + src.returnValue === false ? + returnTrue : + returnFalse; + + // Create target properties + // Support: Safari <=6 - 7 only + // Target should not be a text node (#504, #13143) + this.target = ( src.target && src.target.nodeType === 3 ) ? + src.target.parentNode : + src.target; + + this.currentTarget = src.currentTarget; + this.relatedTarget = src.relatedTarget; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || Date.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + constructor: jQuery.Event, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + isSimulated: false, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + + if ( e && !this.isSimulated ) { + e.preventDefault(); + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopPropagation(); + } + }, + stopImmediatePropagation: function() { + var e = this.originalEvent; + + this.isImmediatePropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopImmediatePropagation(); + } + + this.stopPropagation(); + } +}; + +// Includes all common event props including KeyEvent and MouseEvent specific props +jQuery.each( { + altKey: true, + bubbles: true, + cancelable: true, + changedTouches: true, + ctrlKey: true, + detail: true, + eventPhase: true, + metaKey: true, + pageX: true, + pageY: true, + shiftKey: true, + view: true, + "char": true, + code: true, + charCode: true, + key: true, + keyCode: true, + button: true, + buttons: true, + clientX: true, + clientY: true, + offsetX: true, + offsetY: true, + pointerId: true, + pointerType: true, + screenX: true, + screenY: true, + targetTouches: true, + toElement: true, + touches: true, + + which: function( event ) { + var button = event.button; + + // Add which for key events + if ( event.which == null && rkeyEvent.test( event.type ) ) { + return event.charCode != null ? event.charCode : event.keyCode; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) { + if ( button & 1 ) { + return 1; + } + + if ( button & 2 ) { + return 3; + } + + if ( button & 4 ) { + return 2; + } + + return 0; + } + + return event.which; + } +}, jQuery.event.addProp ); + +jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) { + jQuery.event.special[ type ] = { + + // Utilize native event if possible so blur/focus sequence is correct + setup: function() { + + // Claim the first handler + // dataPriv.set( this, "focus", ... ) + // dataPriv.set( this, "blur", ... ) + leverageNative( this, type, expectSync ); + + // Return false to allow normal processing in the caller + return false; + }, + trigger: function() { + + // Force setup before trigger + leverageNative( this, type ); + + // Return non-false to allow normal event-path propagation + return true; + }, + + delegateType: delegateType + }; +} ); + +// Create mouseenter/leave events using mouseover/out and event-time checks +// so that event delegation works in jQuery. +// Do the same for pointerenter/pointerleave and pointerover/pointerout +// +// Support: Safari 7 only +// Safari sends mouseenter too often; see: +// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 +// for the description of the bug (it existed in older Chrome versions as well). +jQuery.each( { + mouseenter: "mouseover", + mouseleave: "mouseout", + pointerenter: "pointerover", + pointerleave: "pointerout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mouseenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +} ); + +jQuery.fn.extend( { + + on: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn ); + }, + one: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? + handleObj.origType + "." + handleObj.namespace : + handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each( function() { + jQuery.event.remove( this, types, fn, selector ); + } ); + } +} ); + + +var + + // Support: IE <=10 - 11, Edge 12 - 13 only + // In IE/Edge using regex groups here causes severe slowdowns. + // See https://connect.microsoft.com/IE/feedback/details/1736512/ + rnoInnerhtml = /\s*$/g; + +// Prefer a tbody over its parent table for containing new rows +function manipulationTarget( elem, content ) { + if ( nodeName( elem, "table" ) && + nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { + + return jQuery( elem ).children( "tbody" )[ 0 ] || elem; + } + + return elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { + elem.type = elem.type.slice( 5 ); + } else { + elem.removeAttribute( "type" ); + } + + return elem; +} + +function cloneCopyEvent( src, dest ) { + var i, l, type, pdataOld, udataOld, udataCur, events; + + if ( dest.nodeType !== 1 ) { + return; + } + + // 1. Copy private data: events, handlers, etc. + if ( dataPriv.hasData( src ) ) { + pdataOld = dataPriv.get( src ); + events = pdataOld.events; + + if ( events ) { + dataPriv.remove( dest, "handle events" ); + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + } + + // 2. Copy user data + if ( dataUser.hasData( src ) ) { + udataOld = dataUser.access( src ); + udataCur = jQuery.extend( {}, udataOld ); + + dataUser.set( dest, udataCur ); + } +} + +// Fix IE bugs, see support tests +function fixInput( src, dest ) { + var nodeName = dest.nodeName.toLowerCase(); + + // Fails to persist the checked state of a cloned checkbox or radio button. + if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + dest.checked = src.checked; + + // Fails to return the selected option to the default selected state when cloning options + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +function domManip( collection, args, callback, ignored ) { + + // Flatten any nested arrays + args = flat( args ); + + var fragment, first, scripts, hasScripts, node, doc, + i = 0, + l = collection.length, + iNoClone = l - 1, + value = args[ 0 ], + valueIsFunction = isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( valueIsFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return collection.each( function( index ) { + var self = collection.eq( index ); + if ( valueIsFunction ) { + args[ 0 ] = value.call( this, index, self.html() ); + } + domManip( self, args, callback, ignored ); + } ); + } + + if ( l ) { + fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + // Require either new content or an interest in ignored elements to invoke the callback + if ( first || ignored ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item + // instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( collection[ i ], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !dataPriv.access( node, "globalEval" ) && + jQuery.contains( doc, node ) ) { + + if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { + + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl && !node.noModule ) { + jQuery._evalUrl( node.src, { + nonce: node.nonce || node.getAttribute( "nonce" ) + }, doc ); + } + } else { + DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc ); + } + } + } + } + } + } + + return collection; +} + +function remove( elem, selector, keepData ) { + var node, + nodes = selector ? jQuery.filter( selector, elem ) : elem, + i = 0; + + for ( ; ( node = nodes[ i ] ) != null; i++ ) { + if ( !keepData && node.nodeType === 1 ) { + jQuery.cleanData( getAll( node ) ); + } + + if ( node.parentNode ) { + if ( keepData && isAttached( node ) ) { + setGlobalEval( getAll( node, "script" ) ); + } + node.parentNode.removeChild( node ); + } + } + + return elem; +} + +jQuery.extend( { + htmlPrefilter: function( html ) { + return html; + }, + + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var i, l, srcElements, destElements, + clone = elem.cloneNode( true ), + inPage = isAttached( elem ); + + // Fix IE cloning issues + if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && + !jQuery.isXMLDoc( elem ) ) { + + // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + fixInput( srcElements[ i ], destElements[ i ] ); + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + cloneCopyEvent( srcElements[ i ], destElements[ i ] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + // Return the cloned set + return clone; + }, + + cleanData: function( elems ) { + var data, elem, type, + special = jQuery.event.special, + i = 0; + + for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { + if ( acceptData( elem ) ) { + if ( ( data = elem[ dataPriv.expando ] ) ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataPriv.expando ] = undefined; + } + if ( elem[ dataUser.expando ] ) { + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataUser.expando ] = undefined; + } + } + } + } +} ); + +jQuery.fn.extend( { + detach: function( selector ) { + return remove( this, selector, true ); + }, + + remove: function( selector ) { + return remove( this, selector ); + }, + + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().each( function() { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + this.textContent = value; + } + } ); + }, null, value, arguments.length ); + }, + + append: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + } ); + }, + + prepend: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + } ); + }, + + before: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + } ); + }, + + after: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + } ); + }, + + empty: function() { + var elem, + i = 0; + + for ( ; ( elem = this[ i ] ) != null; i++ ) { + if ( elem.nodeType === 1 ) { + + // Prevent memory leaks + jQuery.cleanData( getAll( elem, false ) ); + + // Remove any remaining nodes + elem.textContent = ""; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + } ); + }, + + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; + + if ( value === undefined && elem.nodeType === 1 ) { + return elem.innerHTML; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { + + value = jQuery.htmlPrefilter( value ); + + try { + for ( ; i < l; i++ ) { + elem = this[ i ] || {}; + + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch ( e ) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var ignored = []; + + // Make the changes, replacing each non-ignored context element with the new content + return domManip( this, arguments, function( elem ) { + var parent = this.parentNode; + + if ( jQuery.inArray( this, ignored ) < 0 ) { + jQuery.cleanData( getAll( this ) ); + if ( parent ) { + parent.replaceChild( elem, this ); + } + } + + // Force callback invocation + }, ignored ); + } +} ); + +jQuery.each( { + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1, + i = 0; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone( true ); + jQuery( insert[ i ] )[ original ]( elems ); + + // Support: Android <=4.0 only, PhantomJS 1 only + // .get() because push.apply(_, arraylike) throws on ancient WebKit + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +} ); +var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); + +var getStyles = function( elem ) { + + // Support: IE <=11 only, Firefox <=30 (#15098, #14150) + // IE throws on elements created in popups + // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" + var view = elem.ownerDocument.defaultView; + + if ( !view || !view.opener ) { + view = window; + } + + return view.getComputedStyle( elem ); + }; + +var swap = function( elem, options, callback ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.call( elem ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; +}; + + +var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); + + + +( function() { + + // Executing both pixelPosition & boxSizingReliable tests require only one layout + // so they're executed at the same time to save the second computation. + function computeStyleTests() { + + // This is a singleton, we need to execute it only once + if ( !div ) { + return; + } + + container.style.cssText = "position:absolute;left:-11111px;width:60px;" + + "margin-top:1px;padding:0;border:0"; + div.style.cssText = + "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + + "margin:auto;border:1px;padding:1px;" + + "width:60%;top:1%"; + documentElement.appendChild( container ).appendChild( div ); + + var divStyle = window.getComputedStyle( div ); + pixelPositionVal = divStyle.top !== "1%"; + + // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 + reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; + + // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 + // Some styles come back with percentage values, even though they shouldn't + div.style.right = "60%"; + pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; + + // Support: IE 9 - 11 only + // Detect misreporting of content dimensions for box-sizing:border-box elements + boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; + + // Support: IE 9 only + // Detect overflow:scroll screwiness (gh-3699) + // Support: Chrome <=64 + // Don't get tricked when zoom affects offsetWidth (gh-4029) + div.style.position = "absolute"; + scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12; + + documentElement.removeChild( container ); + + // Nullify the div so it wouldn't be stored in the memory and + // it will also be a sign that checks already performed + div = null; + } + + function roundPixelMeasures( measure ) { + return Math.round( parseFloat( measure ) ); + } + + var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, + reliableTrDimensionsVal, reliableMarginLeftVal, + container = document.createElement( "div" ), + div = document.createElement( "div" ); + + // Finish early in limited (non-browser) environments + if ( !div.style ) { + return; + } + + // Support: IE <=9 - 11 only + // Style of cloned element affects source element cloned (#8908) + div.style.backgroundClip = "content-box"; + div.cloneNode( true ).style.backgroundClip = ""; + support.clearCloneStyle = div.style.backgroundClip === "content-box"; + + jQuery.extend( support, { + boxSizingReliable: function() { + computeStyleTests(); + return boxSizingReliableVal; + }, + pixelBoxStyles: function() { + computeStyleTests(); + return pixelBoxStylesVal; + }, + pixelPosition: function() { + computeStyleTests(); + return pixelPositionVal; + }, + reliableMarginLeft: function() { + computeStyleTests(); + return reliableMarginLeftVal; + }, + scrollboxSize: function() { + computeStyleTests(); + return scrollboxSizeVal; + }, + + // Support: IE 9 - 11+, Edge 15 - 18+ + // IE/Edge misreport `getComputedStyle` of table rows with width/height + // set in CSS while `offset*` properties report correct values. + // Behavior in IE 9 is more subtle than in newer versions & it passes + // some versions of this test; make sure not to make it pass there! + reliableTrDimensions: function() { + var table, tr, trChild, trStyle; + if ( reliableTrDimensionsVal == null ) { + table = document.createElement( "table" ); + tr = document.createElement( "tr" ); + trChild = document.createElement( "div" ); + + table.style.cssText = "position:absolute;left:-11111px"; + tr.style.height = "1px"; + trChild.style.height = "9px"; + + documentElement + .appendChild( table ) + .appendChild( tr ) + .appendChild( trChild ); + + trStyle = window.getComputedStyle( tr ); + reliableTrDimensionsVal = parseInt( trStyle.height ) > 3; + + documentElement.removeChild( table ); + } + return reliableTrDimensionsVal; + } + } ); +} )(); + + +function curCSS( elem, name, computed ) { + var width, minWidth, maxWidth, ret, + + // Support: Firefox 51+ + // Retrieving style before computed somehow + // fixes an issue with getting wrong values + // on detached elements + style = elem.style; + + computed = computed || getStyles( elem ); + + // getPropertyValue is needed for: + // .css('filter') (IE 9 only, #12537) + // .css('--customProperty) (#3144) + if ( computed ) { + ret = computed.getPropertyValue( name ) || computed[ name ]; + + if ( ret === "" && !isAttached( elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Android Browser returns percentage for some values, + // but width seems to be reliably pixels. + // This is against the CSSOM draft spec: + // https://drafts.csswg.org/cssom/#resolved-values + if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { + + // Remember the original values + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + // Put in the new values to get a computed value out + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + // Revert the changed values + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret !== undefined ? + + // Support: IE <=9 - 11 only + // IE returns zIndex value as an integer. + ret + "" : + ret; +} + + +function addGetHookIf( conditionFn, hookFn ) { + + // Define the hook, we'll check on the first run if it's really needed. + return { + get: function() { + if ( conditionFn() ) { + + // Hook not needed (or it's not possible to use it due + // to missing dependency), remove it. + delete this.get; + return; + } + + // Hook needed; redefine it so that the support test is not executed again. + return ( this.get = hookFn ).apply( this, arguments ); + } + }; +} + + +var cssPrefixes = [ "Webkit", "Moz", "ms" ], + emptyStyle = document.createElement( "div" ).style, + vendorProps = {}; + +// Return a vendor-prefixed property or undefined +function vendorPropName( name ) { + + // Check for vendor prefixed names + var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in emptyStyle ) { + return name; + } + } +} + +// Return a potentially-mapped jQuery.cssProps or vendor prefixed property +function finalPropName( name ) { + var final = jQuery.cssProps[ name ] || vendorProps[ name ]; + + if ( final ) { + return final; + } + if ( name in emptyStyle ) { + return name; + } + return vendorProps[ name ] = vendorPropName( name ) || name; +} + + +var + + // Swappable if display is none or starts with table + // except "table", "table-cell", or "table-caption" + // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rcustomProp = /^--/, + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: "0", + fontWeight: "400" + }; + +function setPositiveNumber( _elem, value, subtract ) { + + // Any relative (+/-) values have already been + // normalized at this point + var matches = rcssNum.exec( value ); + return matches ? + + // Guard against undefined "subtract", e.g., when used as in cssHooks + Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : + value; +} + +function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { + var i = dimension === "width" ? 1 : 0, + extra = 0, + delta = 0; + + // Adjustment may not be necessary + if ( box === ( isBorderBox ? "border" : "content" ) ) { + return 0; + } + + for ( ; i < 4; i += 2 ) { + + // Both box models exclude margin + if ( box === "margin" ) { + delta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); + } + + // If we get here with a content-box, we're seeking "padding" or "border" or "margin" + if ( !isBorderBox ) { + + // Add padding + delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + + // For "border" or "margin", add border + if ( box !== "padding" ) { + delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + + // But still keep track of it otherwise + } else { + extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + + // If we get here with a border-box (content + padding + border), we're seeking "content" or + // "padding" or "margin" + } else { + + // For "content", subtract padding + if ( box === "content" ) { + delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + } + + // For "content" or "padding", subtract border + if ( box !== "margin" ) { + delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } + } + + // Account for positive content-box scroll gutter when requested by providing computedVal + if ( !isBorderBox && computedVal >= 0 ) { + + // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border + // Assuming integer scroll gutter, subtract the rest and round down + delta += Math.max( 0, Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + computedVal - + delta - + extra - + 0.5 + + // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter + // Use an explicit zero to avoid NaN (gh-3964) + ) ) || 0; + } + + return delta; +} + +function getWidthOrHeight( elem, dimension, extra ) { + + // Start with computed style + var styles = getStyles( elem ), + + // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322). + // Fake content-box until we know it's needed to know the true value. + boxSizingNeeded = !support.boxSizingReliable() || extra, + isBorderBox = boxSizingNeeded && + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + valueIsBorderBox = isBorderBox, + + val = curCSS( elem, dimension, styles ), + offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ); + + // Support: Firefox <=54 + // Return a confounding non-pixel value or feign ignorance, as appropriate. + if ( rnumnonpx.test( val ) ) { + if ( !extra ) { + return val; + } + val = "auto"; + } + + + // Support: IE 9 - 11 only + // Use offsetWidth/offsetHeight for when box sizing is unreliable. + // In those cases, the computed value can be trusted to be border-box. + if ( ( !support.boxSizingReliable() && isBorderBox || + + // Support: IE 10 - 11+, Edge 15 - 18+ + // IE/Edge misreport `getComputedStyle` of table rows with width/height + // set in CSS while `offset*` properties report correct values. + // Interestingly, in some cases IE 9 doesn't suffer from this issue. + !support.reliableTrDimensions() && nodeName( elem, "tr" ) || + + // Fall back to offsetWidth/offsetHeight when value is "auto" + // This happens for inline elements with no explicit setting (gh-3571) + val === "auto" || + + // Support: Android <=4.1 - 4.3 only + // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) + !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) && + + // Make sure the element is visible & connected + elem.getClientRects().length ) { + + isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; + + // Where available, offsetWidth/offsetHeight approximate border box dimensions. + // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the + // retrieved value as a content box dimension. + valueIsBorderBox = offsetProp in elem; + if ( valueIsBorderBox ) { + val = elem[ offsetProp ]; + } + } + + // Normalize "" and auto + val = parseFloat( val ) || 0; + + // Adjust for the element's box model + return ( val + + boxModelAdjustment( + elem, + dimension, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox, + styles, + + // Provide the current computed size to request scroll gutter calculation (gh-3589) + val + ) + ) + "px"; +} + +jQuery.extend( { + + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + } + } + } + }, + + // Don't automatically add "px" to these possibly-unitless properties + cssNumber: { + "animationIterationCount": true, + "columnCount": true, + "fillOpacity": true, + "flexGrow": true, + "flexShrink": true, + "fontWeight": true, + "gridArea": true, + "gridColumn": true, + "gridColumnEnd": true, + "gridColumnStart": true, + "gridRow": true, + "gridRowEnd": true, + "gridRowStart": true, + "lineHeight": true, + "opacity": true, + "order": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: {}, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ), + style = elem.style; + + // Make sure that we're working with the right name. We don't + // want to query the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Gets hook for the prefixed version, then unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // Convert "+=" or "-=" to relative numbers (#7345) + if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { + value = adjustCSS( elem, name, ret ); + + // Fixes bug #9237 + type = "number"; + } + + // Make sure that null and NaN values aren't set (#7116) + if ( value == null || value !== value ) { + return; + } + + // If a number was passed in, add the unit (except for certain CSS properties) + // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append + // "px" to a few hardcoded values. + if ( type === "number" && !isCustomProp ) { + value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); + } + + // background-* props affect original clone's values + if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { + style[ name ] = "inherit"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !( "set" in hooks ) || + ( value = hooks.set( elem, value, extra ) ) !== undefined ) { + + if ( isCustomProp ) { + style.setProperty( name, value ); + } else { + style[ name ] = value; + } + } + + } else { + + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && + ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { + + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, extra, styles ) { + var val, num, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ); + + // Make sure that we're working with the right name. We don't + // want to modify the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Try prefixed name followed by the unprefixed name + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name, styles ); + } + + // Convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Make numeric if forced or a qualifier was provided and val looks numeric + if ( extra === "" || extra ) { + num = parseFloat( val ); + return extra === true || isFinite( num ) ? num || 0 : val; + } + + return val; + } +} ); + +jQuery.each( [ "height", "width" ], function( _i, dimension ) { + jQuery.cssHooks[ dimension ] = { + get: function( elem, computed, extra ) { + if ( computed ) { + + // Certain elements can have dimension info if we invisibly show them + // but it must have a current display style that would benefit + return rdisplayswap.test( jQuery.css( elem, "display" ) ) && + + // Support: Safari 8+ + // Table columns in Safari have non-zero offsetWidth & zero + // getBoundingClientRect().width unless display is changed. + // Support: IE <=11 only + // Running getBoundingClientRect on a disconnected node + // in IE throws an error. + ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? + swap( elem, cssShow, function() { + return getWidthOrHeight( elem, dimension, extra ); + } ) : + getWidthOrHeight( elem, dimension, extra ); + } + }, + + set: function( elem, value, extra ) { + var matches, + styles = getStyles( elem ), + + // Only read styles.position if the test has a chance to fail + // to avoid forcing a reflow. + scrollboxSizeBuggy = !support.scrollboxSize() && + styles.position === "absolute", + + // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991) + boxSizingNeeded = scrollboxSizeBuggy || extra, + isBorderBox = boxSizingNeeded && + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + subtract = extra ? + boxModelAdjustment( + elem, + dimension, + extra, + isBorderBox, + styles + ) : + 0; + + // Account for unreliable border-box dimensions by comparing offset* to computed and + // faking a content-box to get border and padding (gh-3699) + if ( isBorderBox && scrollboxSizeBuggy ) { + subtract -= Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + parseFloat( styles[ dimension ] ) - + boxModelAdjustment( elem, dimension, "border", false, styles ) - + 0.5 + ); + } + + // Convert to pixels if value adjustment is needed + if ( subtract && ( matches = rcssNum.exec( value ) ) && + ( matches[ 3 ] || "px" ) !== "px" ) { + + elem.style[ dimension ] = value; + value = jQuery.css( elem, dimension ); + } + + return setPositiveNumber( elem, value, subtract ); + } + }; +} ); + +jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, + function( elem, computed ) { + if ( computed ) { + return ( parseFloat( curCSS( elem, "marginLeft" ) ) || + elem.getBoundingClientRect().left - + swap( elem, { marginLeft: 0 }, function() { + return elem.getBoundingClientRect().left; + } ) + ) + "px"; + } + } +); + +// These hooks are used by animate to expand properties +jQuery.each( { + margin: "", + padding: "", + border: "Width" +}, function( prefix, suffix ) { + jQuery.cssHooks[ prefix + suffix ] = { + expand: function( value ) { + var i = 0, + expanded = {}, + + // Assumes a single number if not a string + parts = typeof value === "string" ? value.split( " " ) : [ value ]; + + for ( ; i < 4; i++ ) { + expanded[ prefix + cssExpand[ i ] + suffix ] = + parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; + } + + return expanded; + } + }; + + if ( prefix !== "margin" ) { + jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; + } +} ); + +jQuery.fn.extend( { + css: function( name, value ) { + return access( this, function( elem, name, value ) { + var styles, len, + map = {}, + i = 0; + + if ( Array.isArray( name ) ) { + styles = getStyles( elem ); + len = name.length; + + for ( ; i < len; i++ ) { + map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); + } + + return map; + } + + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + } +} ); + + +function Tween( elem, options, prop, end, easing ) { + return new Tween.prototype.init( elem, options, prop, end, easing ); +} +jQuery.Tween = Tween; + +Tween.prototype = { + constructor: Tween, + init: function( elem, options, prop, end, easing, unit ) { + this.elem = elem; + this.prop = prop; + this.easing = easing || jQuery.easing._default; + this.options = options; + this.start = this.now = this.cur(); + this.end = end; + this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + }, + cur: function() { + var hooks = Tween.propHooks[ this.prop ]; + + return hooks && hooks.get ? + hooks.get( this ) : + Tween.propHooks._default.get( this ); + }, + run: function( percent ) { + var eased, + hooks = Tween.propHooks[ this.prop ]; + + if ( this.options.duration ) { + this.pos = eased = jQuery.easing[ this.easing ]( + percent, this.options.duration * percent, 0, 1, this.options.duration + ); + } else { + this.pos = eased = percent; + } + this.now = ( this.end - this.start ) * eased + this.start; + + if ( this.options.step ) { + this.options.step.call( this.elem, this.now, this ); + } + + if ( hooks && hooks.set ) { + hooks.set( this ); + } else { + Tween.propHooks._default.set( this ); + } + return this; + } +}; + +Tween.prototype.init.prototype = Tween.prototype; + +Tween.propHooks = { + _default: { + get: function( tween ) { + var result; + + // Use a property on the element directly when it is not a DOM element, + // or when there is no matching style property that exists. + if ( tween.elem.nodeType !== 1 || + tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { + return tween.elem[ tween.prop ]; + } + + // Passing an empty string as a 3rd parameter to .css will automatically + // attempt a parseFloat and fallback to a string if the parse fails. + // Simple values such as "10px" are parsed to Float; + // complex values such as "rotate(1rad)" are returned as-is. + result = jQuery.css( tween.elem, tween.prop, "" ); + + // Empty strings, null, undefined and "auto" are converted to 0. + return !result || result === "auto" ? 0 : result; + }, + set: function( tween ) { + + // Use step hook for back compat. + // Use cssHook if its there. + // Use .style if available and use plain properties where available. + if ( jQuery.fx.step[ tween.prop ] ) { + jQuery.fx.step[ tween.prop ]( tween ); + } else if ( tween.elem.nodeType === 1 && ( + jQuery.cssHooks[ tween.prop ] || + tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) { + jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); + } else { + tween.elem[ tween.prop ] = tween.now; + } + } + } +}; + +// Support: IE <=9 only +// Panic based approach to setting things on disconnected nodes +Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { + set: function( tween ) { + if ( tween.elem.nodeType && tween.elem.parentNode ) { + tween.elem[ tween.prop ] = tween.now; + } + } +}; + +jQuery.easing = { + linear: function( p ) { + return p; + }, + swing: function( p ) { + return 0.5 - Math.cos( p * Math.PI ) / 2; + }, + _default: "swing" +}; + +jQuery.fx = Tween.prototype.init; + +// Back compat <1.8 extension point +jQuery.fx.step = {}; + + + + +var + fxNow, inProgress, + rfxtypes = /^(?:toggle|show|hide)$/, + rrun = /queueHooks$/; + +function schedule() { + if ( inProgress ) { + if ( document.hidden === false && window.requestAnimationFrame ) { + window.requestAnimationFrame( schedule ); + } else { + window.setTimeout( schedule, jQuery.fx.interval ); + } + + jQuery.fx.tick(); + } +} + +// Animations created synchronously will run synchronously +function createFxNow() { + window.setTimeout( function() { + fxNow = undefined; + } ); + return ( fxNow = Date.now() ); +} + +// Generate parameters to create a standard animation +function genFx( type, includeWidth ) { + var which, + i = 0, + attrs = { height: type }; + + // If we include width, step value is 1 to do all cssExpand values, + // otherwise step value is 2 to skip over Left and Right + includeWidth = includeWidth ? 1 : 0; + for ( ; i < 4; i += 2 - includeWidth ) { + which = cssExpand[ i ]; + attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; + } + + if ( includeWidth ) { + attrs.opacity = attrs.width = type; + } + + return attrs; +} + +function createTween( value, prop, animation ) { + var tween, + collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), + index = 0, + length = collection.length; + for ( ; index < length; index++ ) { + if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { + + // We're done with this property + return tween; + } + } +} + +function defaultPrefilter( elem, props, opts ) { + var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, + isBox = "width" in props || "height" in props, + anim = this, + orig = {}, + style = elem.style, + hidden = elem.nodeType && isHiddenWithinTree( elem ), + dataShow = dataPriv.get( elem, "fxshow" ); + + // Queue-skipping animations hijack the fx hooks + if ( !opts.queue ) { + hooks = jQuery._queueHooks( elem, "fx" ); + if ( hooks.unqueued == null ) { + hooks.unqueued = 0; + oldfire = hooks.empty.fire; + hooks.empty.fire = function() { + if ( !hooks.unqueued ) { + oldfire(); + } + }; + } + hooks.unqueued++; + + anim.always( function() { + + // Ensure the complete handler is called before this completes + anim.always( function() { + hooks.unqueued--; + if ( !jQuery.queue( elem, "fx" ).length ) { + hooks.empty.fire(); + } + } ); + } ); + } + + // Detect show/hide animations + for ( prop in props ) { + value = props[ prop ]; + if ( rfxtypes.test( value ) ) { + delete props[ prop ]; + toggle = toggle || value === "toggle"; + if ( value === ( hidden ? "hide" : "show" ) ) { + + // Pretend to be hidden if this is a "show" and + // there is still data from a stopped show/hide + if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { + hidden = true; + + // Ignore all other no-op show/hide data + } else { + continue; + } + } + orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); + } + } + + // Bail out if this is a no-op like .hide().hide() + propTween = !jQuery.isEmptyObject( props ); + if ( !propTween && jQuery.isEmptyObject( orig ) ) { + return; + } + + // Restrict "overflow" and "display" styles during box animations + if ( isBox && elem.nodeType === 1 ) { + + // Support: IE <=9 - 11, Edge 12 - 15 + // Record all 3 overflow attributes because IE does not infer the shorthand + // from identically-valued overflowX and overflowY and Edge just mirrors + // the overflowX value there. + opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; + + // Identify a display type, preferring old show/hide data over the CSS cascade + restoreDisplay = dataShow && dataShow.display; + if ( restoreDisplay == null ) { + restoreDisplay = dataPriv.get( elem, "display" ); + } + display = jQuery.css( elem, "display" ); + if ( display === "none" ) { + if ( restoreDisplay ) { + display = restoreDisplay; + } else { + + // Get nonempty value(s) by temporarily forcing visibility + showHide( [ elem ], true ); + restoreDisplay = elem.style.display || restoreDisplay; + display = jQuery.css( elem, "display" ); + showHide( [ elem ] ); + } + } + + // Animate inline elements as inline-block + if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { + if ( jQuery.css( elem, "float" ) === "none" ) { + + // Restore the original display value at the end of pure show/hide animations + if ( !propTween ) { + anim.done( function() { + style.display = restoreDisplay; + } ); + if ( restoreDisplay == null ) { + display = style.display; + restoreDisplay = display === "none" ? "" : display; + } + } + style.display = "inline-block"; + } + } + } + + if ( opts.overflow ) { + style.overflow = "hidden"; + anim.always( function() { + style.overflow = opts.overflow[ 0 ]; + style.overflowX = opts.overflow[ 1 ]; + style.overflowY = opts.overflow[ 2 ]; + } ); + } + + // Implement show/hide animations + propTween = false; + for ( prop in orig ) { + + // General show/hide setup for this element animation + if ( !propTween ) { + if ( dataShow ) { + if ( "hidden" in dataShow ) { + hidden = dataShow.hidden; + } + } else { + dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); + } + + // Store hidden/visible for toggle so `.stop().toggle()` "reverses" + if ( toggle ) { + dataShow.hidden = !hidden; + } + + // Show elements before animating them + if ( hidden ) { + showHide( [ elem ], true ); + } + + /* eslint-disable no-loop-func */ + + anim.done( function() { + + /* eslint-enable no-loop-func */ + + // The final step of a "hide" animation is actually hiding the element + if ( !hidden ) { + showHide( [ elem ] ); + } + dataPriv.remove( elem, "fxshow" ); + for ( prop in orig ) { + jQuery.style( elem, prop, orig[ prop ] ); + } + } ); + } + + // Per-property setup + propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); + if ( !( prop in dataShow ) ) { + dataShow[ prop ] = propTween.start; + if ( hidden ) { + propTween.end = propTween.start; + propTween.start = 0; + } + } + } +} + +function propFilter( props, specialEasing ) { + var index, name, easing, value, hooks; + + // camelCase, specialEasing and expand cssHook pass + for ( index in props ) { + name = camelCase( index ); + easing = specialEasing[ name ]; + value = props[ index ]; + if ( Array.isArray( value ) ) { + easing = value[ 1 ]; + value = props[ index ] = value[ 0 ]; + } + + if ( index !== name ) { + props[ name ] = value; + delete props[ index ]; + } + + hooks = jQuery.cssHooks[ name ]; + if ( hooks && "expand" in hooks ) { + value = hooks.expand( value ); + delete props[ name ]; + + // Not quite $.extend, this won't overwrite existing keys. + // Reusing 'index' because we have the correct "name" + for ( index in value ) { + if ( !( index in props ) ) { + props[ index ] = value[ index ]; + specialEasing[ index ] = easing; + } + } + } else { + specialEasing[ name ] = easing; + } + } +} + +function Animation( elem, properties, options ) { + var result, + stopped, + index = 0, + length = Animation.prefilters.length, + deferred = jQuery.Deferred().always( function() { + + // Don't match elem in the :animated selector + delete tick.elem; + } ), + tick = function() { + if ( stopped ) { + return false; + } + var currentTime = fxNow || createFxNow(), + remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), + + // Support: Android 2.3 only + // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) + temp = remaining / animation.duration || 0, + percent = 1 - temp, + index = 0, + length = animation.tweens.length; + + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( percent ); + } + + deferred.notifyWith( elem, [ animation, percent, remaining ] ); + + // If there's more to do, yield + if ( percent < 1 && length ) { + return remaining; + } + + // If this was an empty animation, synthesize a final progress notification + if ( !length ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + } + + // Resolve the animation and report its conclusion + deferred.resolveWith( elem, [ animation ] ); + return false; + }, + animation = deferred.promise( { + elem: elem, + props: jQuery.extend( {}, properties ), + opts: jQuery.extend( true, { + specialEasing: {}, + easing: jQuery.easing._default + }, options ), + originalProperties: properties, + originalOptions: options, + startTime: fxNow || createFxNow(), + duration: options.duration, + tweens: [], + createTween: function( prop, end ) { + var tween = jQuery.Tween( elem, animation.opts, prop, end, + animation.opts.specialEasing[ prop ] || animation.opts.easing ); + animation.tweens.push( tween ); + return tween; + }, + stop: function( gotoEnd ) { + var index = 0, + + // If we are going to the end, we want to run all the tweens + // otherwise we skip this part + length = gotoEnd ? animation.tweens.length : 0; + if ( stopped ) { + return this; + } + stopped = true; + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( 1 ); + } + + // Resolve when we played the last frame; otherwise, reject + if ( gotoEnd ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + deferred.resolveWith( elem, [ animation, gotoEnd ] ); + } else { + deferred.rejectWith( elem, [ animation, gotoEnd ] ); + } + return this; + } + } ), + props = animation.props; + + propFilter( props, animation.opts.specialEasing ); + + for ( ; index < length; index++ ) { + result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); + if ( result ) { + if ( isFunction( result.stop ) ) { + jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = + result.stop.bind( result ); + } + return result; + } + } + + jQuery.map( props, createTween, animation ); + + if ( isFunction( animation.opts.start ) ) { + animation.opts.start.call( elem, animation ); + } + + // Attach callbacks from options + animation + .progress( animation.opts.progress ) + .done( animation.opts.done, animation.opts.complete ) + .fail( animation.opts.fail ) + .always( animation.opts.always ); + + jQuery.fx.timer( + jQuery.extend( tick, { + elem: elem, + anim: animation, + queue: animation.opts.queue + } ) + ); + + return animation; +} + +jQuery.Animation = jQuery.extend( Animation, { + + tweeners: { + "*": [ function( prop, value ) { + var tween = this.createTween( prop, value ); + adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); + return tween; + } ] + }, + + tweener: function( props, callback ) { + if ( isFunction( props ) ) { + callback = props; + props = [ "*" ]; + } else { + props = props.match( rnothtmlwhite ); + } + + var prop, + index = 0, + length = props.length; + + for ( ; index < length; index++ ) { + prop = props[ index ]; + Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; + Animation.tweeners[ prop ].unshift( callback ); + } + }, + + prefilters: [ defaultPrefilter ], + + prefilter: function( callback, prepend ) { + if ( prepend ) { + Animation.prefilters.unshift( callback ); + } else { + Animation.prefilters.push( callback ); + } + } +} ); + +jQuery.speed = function( speed, easing, fn ) { + var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { + complete: fn || !fn && easing || + isFunction( speed ) && speed, + duration: speed, + easing: fn && easing || easing && !isFunction( easing ) && easing + }; + + // Go to the end state if fx are off + if ( jQuery.fx.off ) { + opt.duration = 0; + + } else { + if ( typeof opt.duration !== "number" ) { + if ( opt.duration in jQuery.fx.speeds ) { + opt.duration = jQuery.fx.speeds[ opt.duration ]; + + } else { + opt.duration = jQuery.fx.speeds._default; + } + } + } + + // Normalize opt.queue - true/undefined/null -> "fx" + if ( opt.queue == null || opt.queue === true ) { + opt.queue = "fx"; + } + + // Queueing + opt.old = opt.complete; + + opt.complete = function() { + if ( isFunction( opt.old ) ) { + opt.old.call( this ); + } + + if ( opt.queue ) { + jQuery.dequeue( this, opt.queue ); + } + }; + + return opt; +}; + +jQuery.fn.extend( { + fadeTo: function( speed, to, easing, callback ) { + + // Show any hidden elements after setting opacity to 0 + return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() + + // Animate to the value specified + .end().animate( { opacity: to }, speed, easing, callback ); + }, + animate: function( prop, speed, easing, callback ) { + var empty = jQuery.isEmptyObject( prop ), + optall = jQuery.speed( speed, easing, callback ), + doAnimation = function() { + + // Operate on a copy of prop so per-property easing won't be lost + var anim = Animation( this, jQuery.extend( {}, prop ), optall ); + + // Empty animations, or finishing resolves immediately + if ( empty || dataPriv.get( this, "finish" ) ) { + anim.stop( true ); + } + }; + doAnimation.finish = doAnimation; + + return empty || optall.queue === false ? + this.each( doAnimation ) : + this.queue( optall.queue, doAnimation ); + }, + stop: function( type, clearQueue, gotoEnd ) { + var stopQueue = function( hooks ) { + var stop = hooks.stop; + delete hooks.stop; + stop( gotoEnd ); + }; + + if ( typeof type !== "string" ) { + gotoEnd = clearQueue; + clearQueue = type; + type = undefined; + } + if ( clearQueue ) { + this.queue( type || "fx", [] ); + } + + return this.each( function() { + var dequeue = true, + index = type != null && type + "queueHooks", + timers = jQuery.timers, + data = dataPriv.get( this ); + + if ( index ) { + if ( data[ index ] && data[ index ].stop ) { + stopQueue( data[ index ] ); + } + } else { + for ( index in data ) { + if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { + stopQueue( data[ index ] ); + } + } + } + + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && + ( type == null || timers[ index ].queue === type ) ) { + + timers[ index ].anim.stop( gotoEnd ); + dequeue = false; + timers.splice( index, 1 ); + } + } + + // Start the next in the queue if the last step wasn't forced. + // Timers currently will call their complete callbacks, which + // will dequeue but only if they were gotoEnd. + if ( dequeue || !gotoEnd ) { + jQuery.dequeue( this, type ); + } + } ); + }, + finish: function( type ) { + if ( type !== false ) { + type = type || "fx"; + } + return this.each( function() { + var index, + data = dataPriv.get( this ), + queue = data[ type + "queue" ], + hooks = data[ type + "queueHooks" ], + timers = jQuery.timers, + length = queue ? queue.length : 0; + + // Enable finishing flag on private data + data.finish = true; + + // Empty the queue first + jQuery.queue( this, type, [] ); + + if ( hooks && hooks.stop ) { + hooks.stop.call( this, true ); + } + + // Look for any active animations, and finish them + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && timers[ index ].queue === type ) { + timers[ index ].anim.stop( true ); + timers.splice( index, 1 ); + } + } + + // Look for any animations in the old queue and finish them + for ( index = 0; index < length; index++ ) { + if ( queue[ index ] && queue[ index ].finish ) { + queue[ index ].finish.call( this ); + } + } + + // Turn off finishing flag + delete data.finish; + } ); + } +} ); + +jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) { + var cssFn = jQuery.fn[ name ]; + jQuery.fn[ name ] = function( speed, easing, callback ) { + return speed == null || typeof speed === "boolean" ? + cssFn.apply( this, arguments ) : + this.animate( genFx( name, true ), speed, easing, callback ); + }; +} ); + +// Generate shortcuts for custom animations +jQuery.each( { + slideDown: genFx( "show" ), + slideUp: genFx( "hide" ), + slideToggle: genFx( "toggle" ), + fadeIn: { opacity: "show" }, + fadeOut: { opacity: "hide" }, + fadeToggle: { opacity: "toggle" } +}, function( name, props ) { + jQuery.fn[ name ] = function( speed, easing, callback ) { + return this.animate( props, speed, easing, callback ); + }; +} ); + +jQuery.timers = []; +jQuery.fx.tick = function() { + var timer, + i = 0, + timers = jQuery.timers; + + fxNow = Date.now(); + + for ( ; i < timers.length; i++ ) { + timer = timers[ i ]; + + // Run the timer and safely remove it when done (allowing for external removal) + if ( !timer() && timers[ i ] === timer ) { + timers.splice( i--, 1 ); + } + } + + if ( !timers.length ) { + jQuery.fx.stop(); + } + fxNow = undefined; +}; + +jQuery.fx.timer = function( timer ) { + jQuery.timers.push( timer ); + jQuery.fx.start(); +}; + +jQuery.fx.interval = 13; +jQuery.fx.start = function() { + if ( inProgress ) { + return; + } + + inProgress = true; + schedule(); +}; + +jQuery.fx.stop = function() { + inProgress = null; +}; + +jQuery.fx.speeds = { + slow: 600, + fast: 200, + + // Default speed + _default: 400 +}; + + +// Based off of the plugin by Clint Helfers, with permission. +// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ +jQuery.fn.delay = function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = window.setTimeout( next, time ); + hooks.stop = function() { + window.clearTimeout( timeout ); + }; + } ); +}; + + +( function() { + var input = document.createElement( "input" ), + select = document.createElement( "select" ), + opt = select.appendChild( document.createElement( "option" ) ); + + input.type = "checkbox"; + + // Support: Android <=4.3 only + // Default value for a checkbox should be "on" + support.checkOn = input.value !== ""; + + // Support: IE <=11 only + // Must access selectedIndex to make default options select + support.optSelected = opt.selected; + + // Support: IE <=11 only + // An input loses its value after becoming a radio + input = document.createElement( "input" ); + input.value = "t"; + input.type = "radio"; + support.radioValue = input.value === "t"; +} )(); + + +var boolHook, + attrHandle = jQuery.expr.attrHandle; + +jQuery.fn.extend( { + attr: function( name, value ) { + return access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each( function() { + jQuery.removeAttr( this, name ); + } ); + } +} ); + +jQuery.extend( { + attr: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set attributes on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + // Attribute hooks are determined by the lowercase version + // Grab necessary hook if one is defined + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + hooks = jQuery.attrHooks[ name.toLowerCase() ] || + ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); + } + + if ( value !== undefined ) { + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + } + + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + elem.setAttribute( name, value + "" ); + return value; + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + ret = jQuery.find.attr( elem, name ); + + // Non-existent attributes return null, we normalize to undefined + return ret == null ? undefined : ret; + }, + + attrHooks: { + type: { + set: function( elem, value ) { + if ( !support.radioValue && value === "radio" && + nodeName( elem, "input" ) ) { + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + } + }, + + removeAttr: function( elem, value ) { + var name, + i = 0, + + // Attribute names can contain non-HTML whitespace characters + // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 + attrNames = value && value.match( rnothtmlwhite ); + + if ( attrNames && elem.nodeType === 1 ) { + while ( ( name = attrNames[ i++ ] ) ) { + elem.removeAttribute( name ); + } + } + } +} ); + +// Hooks for boolean attributes +boolHook = { + set: function( elem, value, name ) { + if ( value === false ) { + + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + elem.setAttribute( name, name ); + } + return name; + } +}; + +jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) { + var getter = attrHandle[ name ] || jQuery.find.attr; + + attrHandle[ name ] = function( elem, name, isXML ) { + var ret, handle, + lowercaseName = name.toLowerCase(); + + if ( !isXML ) { + + // Avoid an infinite loop by temporarily removing this function from the getter + handle = attrHandle[ lowercaseName ]; + attrHandle[ lowercaseName ] = ret; + ret = getter( elem, name, isXML ) != null ? + lowercaseName : + null; + attrHandle[ lowercaseName ] = handle; + } + return ret; + }; +} ); + + + + +var rfocusable = /^(?:input|select|textarea|button)$/i, + rclickable = /^(?:a|area)$/i; + +jQuery.fn.extend( { + prop: function( name, value ) { + return access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + return this.each( function() { + delete this[ jQuery.propFix[ name ] || name ]; + } ); + } +} ); + +jQuery.extend( { + prop: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set properties on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + return ( elem[ name ] = value ); + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + return elem[ name ]; + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + + // Support: IE <=9 - 11 only + // elem.tabIndex doesn't always return the + // correct value when it hasn't been explicitly set + // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + // Use proper attribute retrieval(#12072) + var tabindex = jQuery.find.attr( elem, "tabindex" ); + + if ( tabindex ) { + return parseInt( tabindex, 10 ); + } + + if ( + rfocusable.test( elem.nodeName ) || + rclickable.test( elem.nodeName ) && + elem.href + ) { + return 0; + } + + return -1; + } + } + }, + + propFix: { + "for": "htmlFor", + "class": "className" + } +} ); + +// Support: IE <=11 only +// Accessing the selectedIndex property +// forces the browser to respect setting selected +// on the option +// The getter ensures a default option is selected +// when in an optgroup +// eslint rule "no-unused-expressions" is disabled for this code +// since it considers such accessions noop +if ( !support.optSelected ) { + jQuery.propHooks.selected = { + get: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent && parent.parentNode ) { + parent.parentNode.selectedIndex; + } + return null; + }, + set: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent ) { + parent.selectedIndex; + + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + } + }; +} + +jQuery.each( [ + "tabIndex", + "readOnly", + "maxLength", + "cellSpacing", + "cellPadding", + "rowSpan", + "colSpan", + "useMap", + "frameBorder", + "contentEditable" +], function() { + jQuery.propFix[ this.toLowerCase() ] = this; +} ); + + + + + // Strip and collapse whitespace according to HTML spec + // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace + function stripAndCollapse( value ) { + var tokens = value.match( rnothtmlwhite ) || []; + return tokens.join( " " ); + } + + +function getClass( elem ) { + return elem.getAttribute && elem.getAttribute( "class" ) || ""; +} + +function classesToArray( value ) { + if ( Array.isArray( value ) ) { + return value; + } + if ( typeof value === "string" ) { + return value.match( rnothtmlwhite ) || []; + } + return []; +} + +jQuery.fn.extend( { + addClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + classes = classesToArray( value ); + + if ( classes.length ) { + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + if ( cur.indexOf( " " + clazz + " " ) < 0 ) { + cur += clazz + " "; + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + if ( !arguments.length ) { + return this.attr( "class", "" ); + } + + classes = classesToArray( value ); + + if ( classes.length ) { + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + + // This expression is here for better compressibility (see addClass) + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + + // Remove *all* instances + while ( cur.indexOf( " " + clazz + " " ) > -1 ) { + cur = cur.replace( " " + clazz + " ", " " ); + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isValidValue = type === "string" || Array.isArray( value ); + + if ( typeof stateVal === "boolean" && isValidValue ) { + return stateVal ? this.addClass( value ) : this.removeClass( value ); + } + + if ( isFunction( value ) ) { + return this.each( function( i ) { + jQuery( this ).toggleClass( + value.call( this, i, getClass( this ), stateVal ), + stateVal + ); + } ); + } + + return this.each( function() { + var className, i, self, classNames; + + if ( isValidValue ) { + + // Toggle individual class names + i = 0; + self = jQuery( this ); + classNames = classesToArray( value ); + + while ( ( className = classNames[ i++ ] ) ) { + + // Check each className given, space separated list + if ( self.hasClass( className ) ) { + self.removeClass( className ); + } else { + self.addClass( className ); + } + } + + // Toggle whole class name + } else if ( value === undefined || type === "boolean" ) { + className = getClass( this ); + if ( className ) { + + // Store className if set + dataPriv.set( this, "__className__", className ); + } + + // If the element has a class name or if we're passed `false`, + // then remove the whole classname (if there was one, the above saved it). + // Otherwise bring back whatever was previously saved (if anything), + // falling back to the empty string if nothing was stored. + if ( this.setAttribute ) { + this.setAttribute( "class", + className || value === false ? + "" : + dataPriv.get( this, "__className__" ) || "" + ); + } + } + } ); + }, + + hasClass: function( selector ) { + var className, elem, + i = 0; + + className = " " + selector + " "; + while ( ( elem = this[ i++ ] ) ) { + if ( elem.nodeType === 1 && + ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { + return true; + } + } + + return false; + } +} ); + + + + +var rreturn = /\r/g; + +jQuery.fn.extend( { + val: function( value ) { + var hooks, ret, valueIsFunction, + elem = this[ 0 ]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || + jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && + "get" in hooks && + ( ret = hooks.get( elem, "value" ) ) !== undefined + ) { + return ret; + } + + ret = elem.value; + + // Handle most common string cases + if ( typeof ret === "string" ) { + return ret.replace( rreturn, "" ); + } + + // Handle cases where value is null/undef or number + return ret == null ? "" : ret; + } + + return; + } + + valueIsFunction = isFunction( value ); + + return this.each( function( i ) { + var val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( valueIsFunction ) { + val = value.call( this, i, jQuery( this ).val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + + } else if ( typeof val === "number" ) { + val += ""; + + } else if ( Array.isArray( val ) ) { + val = jQuery.map( val, function( value ) { + return value == null ? "" : value + ""; + } ); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + } ); + } +} ); + +jQuery.extend( { + valHooks: { + option: { + get: function( elem ) { + + var val = jQuery.find.attr( elem, "value" ); + return val != null ? + val : + + // Support: IE <=10 - 11 only + // option.text throws exceptions (#14686, #14858) + // Strip and collapse whitespace + // https://html.spec.whatwg.org/#strip-and-collapse-whitespace + stripAndCollapse( jQuery.text( elem ) ); + } + }, + select: { + get: function( elem ) { + var value, option, i, + options = elem.options, + index = elem.selectedIndex, + one = elem.type === "select-one", + values = one ? null : [], + max = one ? index + 1 : options.length; + + if ( index < 0 ) { + i = max; + + } else { + i = one ? index : 0; + } + + // Loop through all the selected options + for ( ; i < max; i++ ) { + option = options[ i ]; + + // Support: IE <=9 only + // IE8-9 doesn't update selected after form reset (#2551) + if ( ( option.selected || i === index ) && + + // Don't return options that are disabled or in a disabled optgroup + !option.disabled && + ( !option.parentNode.disabled || + !nodeName( option.parentNode, "optgroup" ) ) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + }, + + set: function( elem, value ) { + var optionSet, option, + options = elem.options, + values = jQuery.makeArray( value ), + i = options.length; + + while ( i-- ) { + option = options[ i ]; + + /* eslint-disable no-cond-assign */ + + if ( option.selected = + jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 + ) { + optionSet = true; + } + + /* eslint-enable no-cond-assign */ + } + + // Force browsers to behave consistently when non-matching value is set + if ( !optionSet ) { + elem.selectedIndex = -1; + } + return values; + } + } + } +} ); + +// Radios and checkboxes getter/setter +jQuery.each( [ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + set: function( elem, value ) { + if ( Array.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); + } + } + }; + if ( !support.checkOn ) { + jQuery.valHooks[ this ].get = function( elem ) { + return elem.getAttribute( "value" ) === null ? "on" : elem.value; + }; + } +} ); + + + + +// Return jQuery for attributes-only inclusion + + +support.focusin = "onfocusin" in window; + + +var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + stopPropagationCallback = function( e ) { + e.stopPropagation(); + }; + +jQuery.extend( jQuery.event, { + + trigger: function( event, data, elem, onlyHandlers ) { + + var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, + eventPath = [ elem || document ], + type = hasOwn.call( event, "type" ) ? event.type : event, + namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; + + cur = lastElement = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "." ) > -1 ) { + + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split( "." ); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf( ":" ) < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join( "." ); + event.rnamespace = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === ( elem.ownerDocument || document ) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { + lastElement = cur; + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( + dataPriv.get( cur, "events" ) || Object.create( null ) + )[ event.type ] && + dataPriv.get( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && handle.apply && acceptData( cur ) ) { + event.result = handle.apply( cur, data ); + if ( event.result === false ) { + event.preventDefault(); + } + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( ( !special._default || + special._default.apply( eventPath.pop(), data ) === false ) && + acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name as the event. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + + if ( event.isPropagationStopped() ) { + lastElement.addEventListener( type, stopPropagationCallback ); + } + + elem[ type ](); + + if ( event.isPropagationStopped() ) { + lastElement.removeEventListener( type, stopPropagationCallback ); + } + + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + // Piggyback on a donor event to simulate a different one + // Used only for `focus(in | out)` events + simulate: function( type, elem, event ) { + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true + } + ); + + jQuery.event.trigger( e, null, elem ); + } + +} ); + +jQuery.fn.extend( { + + trigger: function( type, data ) { + return this.each( function() { + jQuery.event.trigger( type, data, this ); + } ); + }, + triggerHandler: function( type, data ) { + var elem = this[ 0 ]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +} ); + + +// Support: Firefox <=44 +// Firefox doesn't have focus(in | out) events +// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 +// +// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 +// focus(in | out) events fire after focus & blur events, +// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order +// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 +if ( !support.focusin ) { + jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler on the document while someone wants focusin/focusout + var handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + + // Handle: regular nodes (via `this.ownerDocument`), window + // (via `this.document`) & document (via `this`). + var doc = this.ownerDocument || this.document || this, + attaches = dataPriv.access( doc, fix ); + + if ( !attaches ) { + doc.addEventListener( orig, handler, true ); + } + dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); + }, + teardown: function() { + var doc = this.ownerDocument || this.document || this, + attaches = dataPriv.access( doc, fix ) - 1; + + if ( !attaches ) { + doc.removeEventListener( orig, handler, true ); + dataPriv.remove( doc, fix ); + + } else { + dataPriv.access( doc, fix, attaches ); + } + } + }; + } ); +} +var location = window.location; + +var nonce = { guid: Date.now() }; + +var rquery = ( /\?/ ); + + + +// Cross-browser xml parsing +jQuery.parseXML = function( data ) { + var xml; + if ( !data || typeof data !== "string" ) { + return null; + } + + // Support: IE 9 - 11 only + // IE throws on parseFromString with invalid input. + try { + xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); + } catch ( e ) { + xml = undefined; + } + + if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; +}; + + +var + rbracket = /\[\]$/, + rCRLF = /\r?\n/g, + rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, + rsubmittable = /^(?:input|select|textarea|keygen)/i; + +function buildParams( prefix, obj, traditional, add ) { + var name; + + if ( Array.isArray( obj ) ) { + + // Serialize array item. + jQuery.each( obj, function( i, v ) { + if ( traditional || rbracket.test( prefix ) ) { + + // Treat each array item as a scalar. + add( prefix, v ); + + } else { + + // Item is non-scalar (array or object), encode its numeric index. + buildParams( + prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", + v, + traditional, + add + ); + } + } ); + + } else if ( !traditional && toType( obj ) === "object" ) { + + // Serialize object item. + for ( name in obj ) { + buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); + } + + } else { + + // Serialize scalar item. + add( prefix, obj ); + } +} + +// Serialize an array of form elements or a set of +// key/values into a query string +jQuery.param = function( a, traditional ) { + var prefix, + s = [], + add = function( key, valueOrFunction ) { + + // If value is a function, invoke it and use its return value + var value = isFunction( valueOrFunction ) ? + valueOrFunction() : + valueOrFunction; + + s[ s.length ] = encodeURIComponent( key ) + "=" + + encodeURIComponent( value == null ? "" : value ); + }; + + if ( a == null ) { + return ""; + } + + // If an array was passed in, assume that it is an array of form elements. + if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { + + // Serialize the form elements + jQuery.each( a, function() { + add( this.name, this.value ); + } ); + + } else { + + // If traditional, encode the "old" way (the way 1.3.2 or older + // did it), otherwise encode params recursively. + for ( prefix in a ) { + buildParams( prefix, a[ prefix ], traditional, add ); + } + } + + // Return the resulting serialization + return s.join( "&" ); +}; + +jQuery.fn.extend( { + serialize: function() { + return jQuery.param( this.serializeArray() ); + }, + serializeArray: function() { + return this.map( function() { + + // Can add propHook for "elements" to filter or add form elements + var elements = jQuery.prop( this, "elements" ); + return elements ? jQuery.makeArray( elements ) : this; + } ) + .filter( function() { + var type = this.type; + + // Use .is( ":disabled" ) so that fieldset[disabled] works + return this.name && !jQuery( this ).is( ":disabled" ) && + rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && + ( this.checked || !rcheckableType.test( type ) ); + } ) + .map( function( _i, elem ) { + var val = jQuery( this ).val(); + + if ( val == null ) { + return null; + } + + if ( Array.isArray( val ) ) { + return jQuery.map( val, function( val ) { + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ); + } + + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ).get(); + } +} ); + + +var + r20 = /%20/g, + rhash = /#.*$/, + rantiCache = /([?&])_=[^&]*/, + rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, + + // #7653, #8125, #8152: local protocol detection + rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, + rnoContent = /^(?:GET|HEAD)$/, + rprotocol = /^\/\//, + + /* Prefilters + * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) + * 2) These are called: + * - BEFORE asking for a transport + * - AFTER param serialization (s.data is a string if s.processData is true) + * 3) key is the dataType + * 4) the catchall symbol "*" can be used + * 5) execution will start with transport dataType and THEN continue down to "*" if needed + */ + prefilters = {}, + + /* Transports bindings + * 1) key is the dataType + * 2) the catchall symbol "*" can be used + * 3) selection will start with transport dataType and THEN go to "*" if needed + */ + transports = {}, + + // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression + allTypes = "*/".concat( "*" ), + + // Anchor tag for parsing the document origin + originAnchor = document.createElement( "a" ); + originAnchor.href = location.href; + +// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport +function addToPrefiltersOrTransports( structure ) { + + // dataTypeExpression is optional and defaults to "*" + return function( dataTypeExpression, func ) { + + if ( typeof dataTypeExpression !== "string" ) { + func = dataTypeExpression; + dataTypeExpression = "*"; + } + + var dataType, + i = 0, + dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; + + if ( isFunction( func ) ) { + + // For each dataType in the dataTypeExpression + while ( ( dataType = dataTypes[ i++ ] ) ) { + + // Prepend if requested + if ( dataType[ 0 ] === "+" ) { + dataType = dataType.slice( 1 ) || "*"; + ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); + + // Otherwise append + } else { + ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); + } + } + } + }; +} + +// Base inspection function for prefilters and transports +function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { + + var inspected = {}, + seekingTransport = ( structure === transports ); + + function inspect( dataType ) { + var selected; + inspected[ dataType ] = true; + jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { + var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); + if ( typeof dataTypeOrTransport === "string" && + !seekingTransport && !inspected[ dataTypeOrTransport ] ) { + + options.dataTypes.unshift( dataTypeOrTransport ); + inspect( dataTypeOrTransport ); + return false; + } else if ( seekingTransport ) { + return !( selected = dataTypeOrTransport ); + } + } ); + return selected; + } + + return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); +} + +// A special extend for ajax options +// that takes "flat" options (not to be deep extended) +// Fixes #9887 +function ajaxExtend( target, src ) { + var key, deep, + flatOptions = jQuery.ajaxSettings.flatOptions || {}; + + for ( key in src ) { + if ( src[ key ] !== undefined ) { + ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; + } + } + if ( deep ) { + jQuery.extend( true, target, deep ); + } + + return target; +} + +/* Handles responses to an ajax request: + * - finds the right dataType (mediates between content-type and expected dataType) + * - returns the corresponding response + */ +function ajaxHandleResponses( s, jqXHR, responses ) { + + var ct, type, finalDataType, firstDataType, + contents = s.contents, + dataTypes = s.dataTypes; + + // Remove auto dataType and get content-type in the process + while ( dataTypes[ 0 ] === "*" ) { + dataTypes.shift(); + if ( ct === undefined ) { + ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); + } + } + + // Check if we're dealing with a known content-type + if ( ct ) { + for ( type in contents ) { + if ( contents[ type ] && contents[ type ].test( ct ) ) { + dataTypes.unshift( type ); + break; + } + } + } + + // Check to see if we have a response for the expected dataType + if ( dataTypes[ 0 ] in responses ) { + finalDataType = dataTypes[ 0 ]; + } else { + + // Try convertible dataTypes + for ( type in responses ) { + if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { + finalDataType = type; + break; + } + if ( !firstDataType ) { + firstDataType = type; + } + } + + // Or just use first one + finalDataType = finalDataType || firstDataType; + } + + // If we found a dataType + // We add the dataType to the list if needed + // and return the corresponding response + if ( finalDataType ) { + if ( finalDataType !== dataTypes[ 0 ] ) { + dataTypes.unshift( finalDataType ); + } + return responses[ finalDataType ]; + } +} + +/* Chain conversions given the request and the original response + * Also sets the responseXXX fields on the jqXHR instance + */ +function ajaxConvert( s, response, jqXHR, isSuccess ) { + var conv2, current, conv, tmp, prev, + converters = {}, + + // Work with a copy of dataTypes in case we need to modify it for conversion + dataTypes = s.dataTypes.slice(); + + // Create converters map with lowercased keys + if ( dataTypes[ 1 ] ) { + for ( conv in s.converters ) { + converters[ conv.toLowerCase() ] = s.converters[ conv ]; + } + } + + current = dataTypes.shift(); + + // Convert to each sequential dataType + while ( current ) { + + if ( s.responseFields[ current ] ) { + jqXHR[ s.responseFields[ current ] ] = response; + } + + // Apply the dataFilter if provided + if ( !prev && isSuccess && s.dataFilter ) { + response = s.dataFilter( response, s.dataType ); + } + + prev = current; + current = dataTypes.shift(); + + if ( current ) { + + // There's only work to do if current dataType is non-auto + if ( current === "*" ) { + + current = prev; + + // Convert response if prev dataType is non-auto and differs from current + } else if ( prev !== "*" && prev !== current ) { + + // Seek a direct converter + conv = converters[ prev + " " + current ] || converters[ "* " + current ]; + + // If none found, seek a pair + if ( !conv ) { + for ( conv2 in converters ) { + + // If conv2 outputs current + tmp = conv2.split( " " ); + if ( tmp[ 1 ] === current ) { + + // If prev can be converted to accepted input + conv = converters[ prev + " " + tmp[ 0 ] ] || + converters[ "* " + tmp[ 0 ] ]; + if ( conv ) { + + // Condense equivalence converters + if ( conv === true ) { + conv = converters[ conv2 ]; + + // Otherwise, insert the intermediate dataType + } else if ( converters[ conv2 ] !== true ) { + current = tmp[ 0 ]; + dataTypes.unshift( tmp[ 1 ] ); + } + break; + } + } + } + } + + // Apply converter (if not an equivalence) + if ( conv !== true ) { + + // Unless errors are allowed to bubble, catch and return them + if ( conv && s.throws ) { + response = conv( response ); + } else { + try { + response = conv( response ); + } catch ( e ) { + return { + state: "parsererror", + error: conv ? e : "No conversion from " + prev + " to " + current + }; + } + } + } + } + } + } + + return { state: "success", data: response }; +} + +jQuery.extend( { + + // Counter for holding the number of active queries + active: 0, + + // Last-Modified header cache for next request + lastModified: {}, + etag: {}, + + ajaxSettings: { + url: location.href, + type: "GET", + isLocal: rlocalProtocol.test( location.protocol ), + global: true, + processData: true, + async: true, + contentType: "application/x-www-form-urlencoded; charset=UTF-8", + + /* + timeout: 0, + data: null, + dataType: null, + username: null, + password: null, + cache: null, + throws: false, + traditional: false, + headers: {}, + */ + + accepts: { + "*": allTypes, + text: "text/plain", + html: "text/html", + xml: "application/xml, text/xml", + json: "application/json, text/javascript" + }, + + contents: { + xml: /\bxml\b/, + html: /\bhtml/, + json: /\bjson\b/ + }, + + responseFields: { + xml: "responseXML", + text: "responseText", + json: "responseJSON" + }, + + // Data converters + // Keys separate source (or catchall "*") and destination types with a single space + converters: { + + // Convert anything to text + "* text": String, + + // Text to html (true = no transformation) + "text html": true, + + // Evaluate text as a json expression + "text json": JSON.parse, + + // Parse text as xml + "text xml": jQuery.parseXML + }, + + // For options that shouldn't be deep extended: + // you can add your own custom options here if + // and when you create one that shouldn't be + // deep extended (see ajaxExtend) + flatOptions: { + url: true, + context: true + } + }, + + // Creates a full fledged settings object into target + // with both ajaxSettings and settings fields. + // If target is omitted, writes into ajaxSettings. + ajaxSetup: function( target, settings ) { + return settings ? + + // Building a settings object + ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : + + // Extending ajaxSettings + ajaxExtend( jQuery.ajaxSettings, target ); + }, + + ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), + ajaxTransport: addToPrefiltersOrTransports( transports ), + + // Main method + ajax: function( url, options ) { + + // If url is an object, simulate pre-1.5 signature + if ( typeof url === "object" ) { + options = url; + url = undefined; + } + + // Force options to be an object + options = options || {}; + + var transport, + + // URL without anti-cache param + cacheURL, + + // Response headers + responseHeadersString, + responseHeaders, + + // timeout handle + timeoutTimer, + + // Url cleanup var + urlAnchor, + + // Request state (becomes false upon send and true upon completion) + completed, + + // To know if global events are to be dispatched + fireGlobals, + + // Loop variable + i, + + // uncached part of the url + uncached, + + // Create the final options object + s = jQuery.ajaxSetup( {}, options ), + + // Callbacks context + callbackContext = s.context || s, + + // Context for global events is callbackContext if it is a DOM node or jQuery collection + globalEventContext = s.context && + ( callbackContext.nodeType || callbackContext.jquery ) ? + jQuery( callbackContext ) : + jQuery.event, + + // Deferreds + deferred = jQuery.Deferred(), + completeDeferred = jQuery.Callbacks( "once memory" ), + + // Status-dependent callbacks + statusCode = s.statusCode || {}, + + // Headers (they are sent all at once) + requestHeaders = {}, + requestHeadersNames = {}, + + // Default abort message + strAbort = "canceled", + + // Fake xhr + jqXHR = { + readyState: 0, + + // Builds headers hashtable if needed + getResponseHeader: function( key ) { + var match; + if ( completed ) { + if ( !responseHeaders ) { + responseHeaders = {}; + while ( ( match = rheaders.exec( responseHeadersString ) ) ) { + responseHeaders[ match[ 1 ].toLowerCase() + " " ] = + ( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] ) + .concat( match[ 2 ] ); + } + } + match = responseHeaders[ key.toLowerCase() + " " ]; + } + return match == null ? null : match.join( ", " ); + }, + + // Raw string + getAllResponseHeaders: function() { + return completed ? responseHeadersString : null; + }, + + // Caches the header + setRequestHeader: function( name, value ) { + if ( completed == null ) { + name = requestHeadersNames[ name.toLowerCase() ] = + requestHeadersNames[ name.toLowerCase() ] || name; + requestHeaders[ name ] = value; + } + return this; + }, + + // Overrides response content-type header + overrideMimeType: function( type ) { + if ( completed == null ) { + s.mimeType = type; + } + return this; + }, + + // Status-dependent callbacks + statusCode: function( map ) { + var code; + if ( map ) { + if ( completed ) { + + // Execute the appropriate callbacks + jqXHR.always( map[ jqXHR.status ] ); + } else { + + // Lazy-add the new callbacks in a way that preserves old ones + for ( code in map ) { + statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; + } + } + } + return this; + }, + + // Cancel the request + abort: function( statusText ) { + var finalText = statusText || strAbort; + if ( transport ) { + transport.abort( finalText ); + } + done( 0, finalText ); + return this; + } + }; + + // Attach deferreds + deferred.promise( jqXHR ); + + // Add protocol if not provided (prefilters might expect it) + // Handle falsy url in the settings object (#10093: consistency with old signature) + // We also use the url parameter if available + s.url = ( ( url || s.url || location.href ) + "" ) + .replace( rprotocol, location.protocol + "//" ); + + // Alias method option to type as per ticket #12004 + s.type = options.method || options.type || s.method || s.type; + + // Extract dataTypes list + s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; + + // A cross-domain request is in order when the origin doesn't match the current origin. + if ( s.crossDomain == null ) { + urlAnchor = document.createElement( "a" ); + + // Support: IE <=8 - 11, Edge 12 - 15 + // IE throws exception on accessing the href property if url is malformed, + // e.g. http://example.com:80x/ + try { + urlAnchor.href = s.url; + + // Support: IE <=8 - 11 only + // Anchor's host property isn't correctly set when s.url is relative + urlAnchor.href = urlAnchor.href; + s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== + urlAnchor.protocol + "//" + urlAnchor.host; + } catch ( e ) { + + // If there is an error parsing the URL, assume it is crossDomain, + // it can be rejected by the transport if it is invalid + s.crossDomain = true; + } + } + + // Convert data if not already a string + if ( s.data && s.processData && typeof s.data !== "string" ) { + s.data = jQuery.param( s.data, s.traditional ); + } + + // Apply prefilters + inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); + + // If request was aborted inside a prefilter, stop there + if ( completed ) { + return jqXHR; + } + + // We can fire global events as of now if asked to + // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) + fireGlobals = jQuery.event && s.global; + + // Watch for a new set of requests + if ( fireGlobals && jQuery.active++ === 0 ) { + jQuery.event.trigger( "ajaxStart" ); + } + + // Uppercase the type + s.type = s.type.toUpperCase(); + + // Determine if request has content + s.hasContent = !rnoContent.test( s.type ); + + // Save the URL in case we're toying with the If-Modified-Since + // and/or If-None-Match header later on + // Remove hash to simplify url manipulation + cacheURL = s.url.replace( rhash, "" ); + + // More options handling for requests with no content + if ( !s.hasContent ) { + + // Remember the hash so we can put it back + uncached = s.url.slice( cacheURL.length ); + + // If data is available and should be processed, append data to url + if ( s.data && ( s.processData || typeof s.data === "string" ) ) { + cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; + + // #9682: remove data so that it's not used in an eventual retry + delete s.data; + } + + // Add or update anti-cache param if needed + if ( s.cache === false ) { + cacheURL = cacheURL.replace( rantiCache, "$1" ); + uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) + + uncached; + } + + // Put hash and anti-cache on the URL that will be requested (gh-1732) + s.url = cacheURL + uncached; + + // Change '%20' to '+' if this is encoded form body content (gh-2658) + } else if ( s.data && s.processData && + ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { + s.data = s.data.replace( r20, "+" ); + } + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + if ( jQuery.lastModified[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); + } + if ( jQuery.etag[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); + } + } + + // Set the correct header, if data is being sent + if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { + jqXHR.setRequestHeader( "Content-Type", s.contentType ); + } + + // Set the Accepts header for the server, depending on the dataType + jqXHR.setRequestHeader( + "Accept", + s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? + s.accepts[ s.dataTypes[ 0 ] ] + + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : + s.accepts[ "*" ] + ); + + // Check for headers option + for ( i in s.headers ) { + jqXHR.setRequestHeader( i, s.headers[ i ] ); + } + + // Allow custom headers/mimetypes and early abort + if ( s.beforeSend && + ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { + + // Abort if not done already and return + return jqXHR.abort(); + } + + // Aborting is no longer a cancellation + strAbort = "abort"; + + // Install callbacks on deferreds + completeDeferred.add( s.complete ); + jqXHR.done( s.success ); + jqXHR.fail( s.error ); + + // Get transport + transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); + + // If no transport, we auto-abort + if ( !transport ) { + done( -1, "No Transport" ); + } else { + jqXHR.readyState = 1; + + // Send global event + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); + } + + // If request was aborted inside ajaxSend, stop there + if ( completed ) { + return jqXHR; + } + + // Timeout + if ( s.async && s.timeout > 0 ) { + timeoutTimer = window.setTimeout( function() { + jqXHR.abort( "timeout" ); + }, s.timeout ); + } + + try { + completed = false; + transport.send( requestHeaders, done ); + } catch ( e ) { + + // Rethrow post-completion exceptions + if ( completed ) { + throw e; + } + + // Propagate others as results + done( -1, e ); + } + } + + // Callback for when everything is done + function done( status, nativeStatusText, responses, headers ) { + var isSuccess, success, error, response, modified, + statusText = nativeStatusText; + + // Ignore repeat invocations + if ( completed ) { + return; + } + + completed = true; + + // Clear timeout if it exists + if ( timeoutTimer ) { + window.clearTimeout( timeoutTimer ); + } + + // Dereference transport for early garbage collection + // (no matter how long the jqXHR object will be used) + transport = undefined; + + // Cache response headers + responseHeadersString = headers || ""; + + // Set readyState + jqXHR.readyState = status > 0 ? 4 : 0; + + // Determine if successful + isSuccess = status >= 200 && status < 300 || status === 304; + + // Get response data + if ( responses ) { + response = ajaxHandleResponses( s, jqXHR, responses ); + } + + // Use a noop converter for missing script + if ( !isSuccess && jQuery.inArray( "script", s.dataTypes ) > -1 ) { + s.converters[ "text script" ] = function() {}; + } + + // Convert no matter what (that way responseXXX fields are always set) + response = ajaxConvert( s, response, jqXHR, isSuccess ); + + // If successful, handle type chaining + if ( isSuccess ) { + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + modified = jqXHR.getResponseHeader( "Last-Modified" ); + if ( modified ) { + jQuery.lastModified[ cacheURL ] = modified; + } + modified = jqXHR.getResponseHeader( "etag" ); + if ( modified ) { + jQuery.etag[ cacheURL ] = modified; + } + } + + // if no content + if ( status === 204 || s.type === "HEAD" ) { + statusText = "nocontent"; + + // if not modified + } else if ( status === 304 ) { + statusText = "notmodified"; + + // If we have data, let's convert it + } else { + statusText = response.state; + success = response.data; + error = response.error; + isSuccess = !error; + } + } else { + + // Extract error from statusText and normalize for non-aborts + error = statusText; + if ( status || !statusText ) { + statusText = "error"; + if ( status < 0 ) { + status = 0; + } + } + } + + // Set data for the fake xhr object + jqXHR.status = status; + jqXHR.statusText = ( nativeStatusText || statusText ) + ""; + + // Success/Error + if ( isSuccess ) { + deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); + } else { + deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); + } + + // Status-dependent callbacks + jqXHR.statusCode( statusCode ); + statusCode = undefined; + + if ( fireGlobals ) { + globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", + [ jqXHR, s, isSuccess ? success : error ] ); + } + + // Complete + completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); + + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); + + // Handle the global AJAX counter + if ( !( --jQuery.active ) ) { + jQuery.event.trigger( "ajaxStop" ); + } + } + } + + return jqXHR; + }, + + getJSON: function( url, data, callback ) { + return jQuery.get( url, data, callback, "json" ); + }, + + getScript: function( url, callback ) { + return jQuery.get( url, undefined, callback, "script" ); + } +} ); + +jQuery.each( [ "get", "post" ], function( _i, method ) { + jQuery[ method ] = function( url, data, callback, type ) { + + // Shift arguments if data argument was omitted + if ( isFunction( data ) ) { + type = type || callback; + callback = data; + data = undefined; + } + + // The url can be an options object (which then must have .url) + return jQuery.ajax( jQuery.extend( { + url: url, + type: method, + dataType: type, + data: data, + success: callback + }, jQuery.isPlainObject( url ) && url ) ); + }; +} ); + +jQuery.ajaxPrefilter( function( s ) { + var i; + for ( i in s.headers ) { + if ( i.toLowerCase() === "content-type" ) { + s.contentType = s.headers[ i ] || ""; + } + } +} ); + + +jQuery._evalUrl = function( url, options, doc ) { + return jQuery.ajax( { + url: url, + + // Make this explicit, since user can override this through ajaxSetup (#11264) + type: "GET", + dataType: "script", + cache: true, + async: false, + global: false, + + // Only evaluate the response if it is successful (gh-4126) + // dataFilter is not invoked for failure responses, so using it instead + // of the default converter is kludgy but it works. + converters: { + "text script": function() {} + }, + dataFilter: function( response ) { + jQuery.globalEval( response, options, doc ); + } + } ); +}; + + +jQuery.fn.extend( { + wrapAll: function( html ) { + var wrap; + + if ( this[ 0 ] ) { + if ( isFunction( html ) ) { + html = html.call( this[ 0 ] ); + } + + // The elements to wrap the target around + wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); + + if ( this[ 0 ].parentNode ) { + wrap.insertBefore( this[ 0 ] ); + } + + wrap.map( function() { + var elem = this; + + while ( elem.firstElementChild ) { + elem = elem.firstElementChild; + } + + return elem; + } ).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( isFunction( html ) ) { + return this.each( function( i ) { + jQuery( this ).wrapInner( html.call( this, i ) ); + } ); + } + + return this.each( function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + } ); + }, + + wrap: function( html ) { + var htmlIsFunction = isFunction( html ); + + return this.each( function( i ) { + jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); + } ); + }, + + unwrap: function( selector ) { + this.parent( selector ).not( "body" ).each( function() { + jQuery( this ).replaceWith( this.childNodes ); + } ); + return this; + } +} ); + + +jQuery.expr.pseudos.hidden = function( elem ) { + return !jQuery.expr.pseudos.visible( elem ); +}; +jQuery.expr.pseudos.visible = function( elem ) { + return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); +}; + + + + +jQuery.ajaxSettings.xhr = function() { + try { + return new window.XMLHttpRequest(); + } catch ( e ) {} +}; + +var xhrSuccessStatus = { + + // File protocol always yields status code 0, assume 200 + 0: 200, + + // Support: IE <=9 only + // #1450: sometimes IE returns 1223 when it should be 204 + 1223: 204 + }, + xhrSupported = jQuery.ajaxSettings.xhr(); + +support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); +support.ajax = xhrSupported = !!xhrSupported; + +jQuery.ajaxTransport( function( options ) { + var callback, errorCallback; + + // Cross domain only allowed if supported through XMLHttpRequest + if ( support.cors || xhrSupported && !options.crossDomain ) { + return { + send: function( headers, complete ) { + var i, + xhr = options.xhr(); + + xhr.open( + options.type, + options.url, + options.async, + options.username, + options.password + ); + + // Apply custom fields if provided + if ( options.xhrFields ) { + for ( i in options.xhrFields ) { + xhr[ i ] = options.xhrFields[ i ]; + } + } + + // Override mime type if needed + if ( options.mimeType && xhr.overrideMimeType ) { + xhr.overrideMimeType( options.mimeType ); + } + + // X-Requested-With header + // For cross-domain requests, seeing as conditions for a preflight are + // akin to a jigsaw puzzle, we simply never set it to be sure. + // (it can always be set on a per-request basis or even using ajaxSetup) + // For same-domain requests, won't change header if already provided. + if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { + headers[ "X-Requested-With" ] = "XMLHttpRequest"; + } + + // Set headers + for ( i in headers ) { + xhr.setRequestHeader( i, headers[ i ] ); + } + + // Callback + callback = function( type ) { + return function() { + if ( callback ) { + callback = errorCallback = xhr.onload = + xhr.onerror = xhr.onabort = xhr.ontimeout = + xhr.onreadystatechange = null; + + if ( type === "abort" ) { + xhr.abort(); + } else if ( type === "error" ) { + + // Support: IE <=9 only + // On a manual native abort, IE9 throws + // errors on any property access that is not readyState + if ( typeof xhr.status !== "number" ) { + complete( 0, "error" ); + } else { + complete( + + // File: protocol always yields status 0; see #8605, #14207 + xhr.status, + xhr.statusText + ); + } + } else { + complete( + xhrSuccessStatus[ xhr.status ] || xhr.status, + xhr.statusText, + + // Support: IE <=9 only + // IE9 has no XHR2 but throws on binary (trac-11426) + // For XHR2 non-text, let the caller handle it (gh-2498) + ( xhr.responseType || "text" ) !== "text" || + typeof xhr.responseText !== "string" ? + { binary: xhr.response } : + { text: xhr.responseText }, + xhr.getAllResponseHeaders() + ); + } + } + }; + }; + + // Listen to events + xhr.onload = callback(); + errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); + + // Support: IE 9 only + // Use onreadystatechange to replace onabort + // to handle uncaught aborts + if ( xhr.onabort !== undefined ) { + xhr.onabort = errorCallback; + } else { + xhr.onreadystatechange = function() { + + // Check readyState before timeout as it changes + if ( xhr.readyState === 4 ) { + + // Allow onerror to be called first, + // but that will not handle a native abort + // Also, save errorCallback to a variable + // as xhr.onerror cannot be accessed + window.setTimeout( function() { + if ( callback ) { + errorCallback(); + } + } ); + } + }; + } + + // Create the abort callback + callback = callback( "abort" ); + + try { + + // Do send the request (this may raise an exception) + xhr.send( options.hasContent && options.data || null ); + } catch ( e ) { + + // #14683: Only rethrow if this hasn't been notified as an error yet + if ( callback ) { + throw e; + } + } + }, + + abort: function() { + if ( callback ) { + callback(); + } + } + }; + } +} ); + + + + +// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) +jQuery.ajaxPrefilter( function( s ) { + if ( s.crossDomain ) { + s.contents.script = false; + } +} ); + +// Install script dataType +jQuery.ajaxSetup( { + accepts: { + script: "text/javascript, application/javascript, " + + "application/ecmascript, application/x-ecmascript" + }, + contents: { + script: /\b(?:java|ecma)script\b/ + }, + converters: { + "text script": function( text ) { + jQuery.globalEval( text ); + return text; + } + } +} ); + +// Handle cache's special case and crossDomain +jQuery.ajaxPrefilter( "script", function( s ) { + if ( s.cache === undefined ) { + s.cache = false; + } + if ( s.crossDomain ) { + s.type = "GET"; + } +} ); + +// Bind script tag hack transport +jQuery.ajaxTransport( "script", function( s ) { + + // This transport only deals with cross domain or forced-by-attrs requests + if ( s.crossDomain || s.scriptAttrs ) { + var script, callback; + return { + send: function( _, complete ) { + script = jQuery( " + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

1. API Overview

+
+

1.1. Introduction

+

bl_mcu_sdk code hierarchy is divided into the following main layers.

+
    +
  • The application layer: codes written by users.

  • +
  • The component layer: some opensource components,the interface calls the HAL layer, while the wireless layer is used for wireless functions.

  • +
  • +
    HAL layer and wireless layer for adaptation to different MCUs, where the HAL layer is divided into two layers
      +
    • Device driver management: provides a standard set of interfaces, which are implemented by the peripheral driver adaptation layer

    • +
    • Peripheral driver adaptation layer: implements the standard interface of the device driver management and extends its own unique interface

    • +
    +
    +
    +
  • +
  • Standard driver layer based on register packaging

  • +
  • Hardware layer, also known as the register layer

  • +
+
+ +

code structure

+
+
+
+

1.2. Device driver management layer

+

The realization of the device driver management layer adopts the object-oriented idea. First of all, we regard the peripheral as a device or a file, adhering to the concept of everything is a file, and files have standard calling interfaces: open, close, ctrl, write, read, callback. Different file types are different (such as serial device, ADC device, SPI device), and the way of opening is also different (such as polling, interrupt, DMA), from this, we can construct a base class (parent class) of an object.

+

Base class

+
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;
+};
+
+
+

Base class member: name

+

Name the device and use device_find to find the device.

+

Base class member: type

+

type records the category of the current device, and the type that can be selected are as follows.

+
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,
+} ;
+
+
+

Base class member: status

+

status is used to record the current status of the device and provides 4 statuses.

+
enum device_status_type
+{
+    DEVICE_UNREGISTER = 0,
+    DEVICE_REGISTERED,
+    DEVICE_OPENED,
+    DEVICE_CLOSED
+} ;
+
+
+

Base class member: oflag

+

oflag records the flag information filled in during registration and the oflag information filled in when using device_open.

+

Base class members: list

+

The addition and deletion of equipment is stored in a doubly linked list, which saves memory.

+

Base class members: standard function pointers

+

Provides a standard function interface for different peripherals. When the peripheral implements this type of interface and assigns it to the member, the function of rewriting can be achieved.

+
+
+

1.3. Device driver management layer standard interface

+
+

1.3.1. device_register

+

device_register is used to register the device and register the device information in the linked list.

+
int device_register(struct device *dev, const char *name);
+
+
+
    +
  • dev: device handle.

  • +
  • name: the name of the device.

  • +
  • return: return error code, 0 means registration is successful, others mean errors.

  • +
+
+
+

1.3.2. device_unregister

+

device_unregister is used to delete the device and delete the device information from the linked list.

+
int device_unregister(const char *name);
+
+
+
    +
  • dev: device handle

  • +
  • name: the name of the device to be deleted

  • +
  • return: error code, 0 means delete, others mean error

  • +
+
+
+

1.3.3. device_find

+

device_find is used to find the device from the linked list according to name, and return the first address of the device handle.

+
struct device *device_find(const char *name);
+
+
+
    +
  • dev: device handle

  • +
  • name: the name of the device to be searched

  • +
  • return: error code,! 0 means the device handle was found, NULL means the device was not found.

  • +
+
+
+

1.3.4. device_open

+

device_open is used to open the device, and oflag represents the opening method. Currently, there are 6 opening methods available. The bottom layer calls the open member in the dev handle.

+
int device_open(struct device *dev, uint16_t oflag);
+
+
+
    +
  • dev: device handle

  • +
  • oflag: open method

  • +
  • return: error code, 0 means opening is successful, others mean errors

  • +
+

oflag can write the following parameters:

+
#define DEVICE_OFLAG_STREAM_TX  0x001 /* The device is turned on in polling sending mode */
+#define DEVICE_OFLAG_STREAM_RX  0x002 /* The device is turned on in polling receiving mode */
+#define DEVICE_OFLAG_INT_TX     0x004 /* The device is turned on in interrupt sending mode */
+#define DEVICE_OFLAG_INT_RX     0x008 /* The device is turned on in interrupt receiving mode */
+#define DEVICE_OFLAG_DMA_TX     0x010 /* The device is turned on in DMA transmission mode */
+#define DEVICE_OFLAG_DMA_RX     0x020 /* The device is turned on in DMA receiving mode */
+
+
+
+
+

1.3.5. device_close

+

device_close is used to close the device. The bottom layer calls the close member in the dev handle.

+
int device_close(struct device *dev);
+
+
+

-dev: device handle +-return: error code, 0 means closing is successful, others mean error

+
+
+

1.3.6. device_control

+

device_control is used to control the device and modify parameters according to commands. The bottom layer calls the control member in the dev handle.

+
int device_control(struct device *dev, int cmd, void *args);
+
+
+
    +
  • dev: device handle

  • +
  • cmd: device control command

  • +
  • args: control parameters

  • +
  • return: Different control commands return different meanings.

  • +
+

cmd provides the following standard commands. In addition, different peripherals also have their own commands

+
#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
+
+
+
+
+

1.3.7. device_write

+

device_write is used to send data, and the sending mode can be polling, interrupt, dma. The bottom layer calls the write member in the dev handle.

+
int device_write(struct device *dev, uint32_t pos, const void *buffer, uint32_t size);
+
+
+
    +
  • dev: device handle

  • +
  • pos: different devices have different meanings for pos

  • +
  • buffer: the buffer to be written

  • +
  • size: the length to be written

  • +
  • return: error code, 0 means writing is successful, others mean errors

  • +
+
+
+

1.3.8. device_read

+

device_read is used to receive data, and the receiving mode can be polling, interrupt, dma. The bottom layer calls the read member in the dev handle.

+
int device_read(struct device *dev, uint32_t pos, void *buffer, uint32_t size);
+
+
+
    +
  • dev: device handle

  • +
  • pos: different devices have different meanings for pos

  • +
  • buffer: the buffer to be read

  • +
  • size: the length to be read

  • +
  • return: error code, 0 means successful reading, others mean errors

  • +
+
+
+

1.3.9. device_set_callback

+

device_set_callback is used to register interrupt callback function. The bottom layer calls the callback member in the dev handle.

+
int device_set_callback(struct device *dev, void (*callback)(struct device *dev, void *args, uint32_t size, uint32_t event));
+
+
+
    +
  • dev: device handle

  • +
  • callback: the interrupt callback function to be registered

    +
    +
      +
    • dev: device handle

    • +
    • args: Different peripherals have different meanings

    • +
    • size: transmission length

    • +
    • event: interrupt event type

    • +
    +
    +
  • +
+
+
+
+

1.4. Peripheral driver adaptation layer

+

Subclass inherits from parent class

+

The first member of different peripherals is struct device, which is equivalent to the inheritance of the parent class, so that the subclass can be used to access the parent class member. When the subclass is used to modify the members of the parent class, it has its own functions. The realization principle is that the first address of different structures is the address of the first member in the structure.

+
typedef struct xxx_device
+{
+    struct device parent;
+
+} xxx_device_t;
+
+
+

Rewrite standard interface

+

Each peripheral has a xxx_register function, which is used to rewrite the standard interface.

+
dev->open = xxx_open;
+dev->close = xxx_close;
+dev->control = xxx_control;
+dev->write = xxx_write;
+dev->read = xxx_read;
+
+
+
+
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/api_reference/bluetooth/api_ble.html b/docs/development_guide_en/build/html/api_reference/bluetooth/api_ble.html new file mode 100644 index 00000000..890c0e59 --- /dev/null +++ b/docs/development_guide_en/build/html/api_reference/bluetooth/api_ble.html @@ -0,0 +1,910 @@ + + + + + + + + + + 3. BLE — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

3. BLE

+
+

3.1. Introduction

+
    +
  • +
    Features
      +
    • +
      HOST
        +
      • GAP support peripheral and Central, Observer and Broadcaster

      • +
      • GATT support server and Client

      • +
      • Support pairing with the secure connection feature in Bluetooth 4.2

      • +
      • Support permanent storage of Bluetooth specific settings and data

      • +
      +
      +
      +
    • +
    • +
      mesh
        +
      • TODO

      • +
      +
      +
      +
    • +
    +
    +
    +
  • +
  • +
    The architecture of the BLE protocol stack:
    +
    +../../_images/image1.png +
    +
    +
      +
    • +
      There are 3 main layers, which together form a complete Bluetooth low power protocol stack
        +
      • Host: Under the application program, it is composed of multiple (non-real-time) networks and transmission protocols, enabling the application program to communicate with peer devices in a standard and interoperable manner

      • +
      • Controller:The controller implements the link layer (LE LL), which is a low-level real-time protocol that provides standard interoperability for over-the-air communication with the radio. LL handles the reception and transmission of packets, guarantees the transfer of data, and handles all LL control procedures

      • +
      • Radio Hardware:Implement analog and digital baseband functions, allowing link layer firmware to transmit and receive in the 2.4GHz band of the spectrum

      • +
      +
      +
      +
    • +
    +
    +
    +
  • +
  • +
    Master Host:
    +
    +../../_images/image2.png +
    +
    +
      +
    • +
      The Bluetooth Host layer implements all high-level protocols and configuration files, the most important thing is that it provides high-level APIs for applications
        +
      • HCI: Host and controller interface

      • +
      • L2CAP: Logical Link Control and Adaptation Protocol

      • +
      • GATT: Generic Attribute Profile

      • +
      • GAP: Generic Access Profile

      • +
      • SMP: Security Manager Specification

      • +
      +
      +
      +
    • +
    +
    +
    +
  • +
  • +
    Application
      +
    • +
      The application layer contains the necessary protocol stack parameter settings and api reference. We analyze the two devices separately from the Bluetooth slave and the Bluetooth master
        +
      • +
        Bluetooth slave
          +
        • Hardware and basic service initialization

        • +
        • Set broadcast parameters: broadcast data, broadcast interval, scan response, etc

        • +
        • Profile settings: add slave services, feature values, and set callback functions to receive host data, etc

        • +
        • Set pairing parameters (optional)

        • +
        • Start the broadcast, start running

        • +
        • Waiting for related events, and event processing, such as receiving data from the host, being linked, etc

        • +
        +
        +
        +
      • +
      • +
        Bluetooth host
          +
        • Related hardware and basic service initialization

        • +
        • Set scan parameters

        • +
        • Set connection parameters

        • +
        • Set pairing parameters (optional)

        • +
        • Start the protocol stack and start running

        • +
        • Wait for related events, and event processing, such as scan events, Notify events from slaves, etc

        • +
        +
        +
        +
      • +
      +
      +
      +
    • +
    +
    +
    +
  • +
+
+
+

3.2. API

+
    +
  • API introduction

  • +
+

void ble_controller_init(uint8_t task_priority)

+
/**
+* function      Controller layer initialization
+* @param[in]    task_priority: task priority
+* @return       None
+*/
+
+
+

int hci_driver_init(void)

+
/**
+* function      HCI interface driver initialization
+* @param[in]    None
+* @return       0: success, !=0: fail
+*/
+
+
+

int bt_enable(bt_ready_cb_t cb)

+
/**
+* function      BLE enable
+* @param[in]    cb: Call the callback function if successful
+* @return       0: success, !=0: fail
+*/
+
+
+
+
int bt_le_adv_start(const struct bt_le_adv_param *param,const struct bt_data *ad, size_t ad_len,

const struct bt_data *sd, size_t sd_len)

+
+
+
/**
+* function      Turn on BLE broadcast
+*
+* @param[in]    param:  Pointer to broadcast configuration parameter
+* @param[in]    ad:     Pointer to the data in the broadcast packet
+* @param[in]    ad_len: The length of the data in the broadcast packet
+* @param[in]    sd:     Pointer to scan response packet data
+* @param[in]    sd_len: Scan response packet data length
+* @return               0: success, !=0: fail
+*/
+
+
+

int bt_le_adv_update_data(const struct bt_data *ad, size_t ad_len,const struct bt_data *sd, size_t sd_len)

+
/**
+* function      Update BLE broadcast data
+* @param[in]    ad:     Pointer to the data in the broadcast packet
+* @param[in]    ad_len: The length of the data in the broadcast packet
+* @param[in]    sd:     Pointer to scan response packet data
+* @param[in]    sd_len: Scan response packet data length
+* @return               0: success, !=0: fail
+*/
+
+
+

int bt_le_adv_stop(void)

+
/**
+* function      Stop BLE broadcast
+* @param[in]    None
+* @return       0: success, !=0: fail
+*/
+
+
+

int bt_le_scan_start(const struct bt_le_scan_param *param, bt_le_scan_cb_t cb)

+
/**
+* function      Turn on BLE scanning
+* @param[in]    param: Pointer to scan parameter
+* @param[in]    cb:    Scan callback function
+* @return              0: success, !=0: fail
+*/
+
+
+

int bt_le_scan_stop(void)

+
/**
+* function      Stop BLE scanning
+* @param[in]    None
+* @return       0: success, !=0: fail
+*/
+
+
+

int bt_le_whitelist_add(const bt_addr_le_t *addr)

+
/**
+* function      Add devices to the whitelist by address
+* @param[in]    addr: Pointer to the address of the device that needs to be added
+* @return       0: success, !=0: fail
+*/
+
+
+

int bt_le_whitelist_rem(const bt_addr_le_t *addr)

+
/**
+* function      Remove the device from the whitelist
+* @param[in]    addr: Pointer to the address of the device that needs to be removed
+* @return       0: success, !=0: fail
+*/
+
+
+

int bt_le_whitelist_clear(void)

+
/**
+* function      Clear the whitelist list
+* @param[in]    None
+* @return       0: success, !=0: fail
+*/
+
+
+

int bt_le_set_chan_map(u8_t chan_map[5])

+
/**
+* function      Set (LE) channel mapping
+* @param[in]    chan_map: channel array
+* @return       0: success, !=0: fail
+*/
+
+
+

int bt_unpair(u8_t id, const bt_addr_le_t *addr)

+
/**
+* function      Clear pairing information
+* @param[in]    id: Local ID (mostly just the default BT ID)
+* @param[in]    addr: Remote device address, NULL or BT_ADDR_LE_ANY to clear all remote devices
+* @return       0: success, !=0: fail
+*/
+
+
+

int bt_conn_get_info(const struct bt_conn *conn, struct bt_conn_info *info)

+
/**
+* function      Get the information of the currently connected device
+* @param[in]    conn: Pointer to the current connection
+* @param[in]    info: Pointer to the information of the currently connected device
+* @return       0: success, !=0: fail
+*/
+
+
+

int bt_conn_get_remote_dev_info(struct bt_conn_info *info)

+
/**
+* function      Get information about connected devices
+* @param[in]    info: Pointer to the information of the currently connected device
+* @return       Number of connected devices
+*/
+
+
+

int bt_conn_le_param_update(struct bt_conn *conn,const struct bt_le_conn_param *param)

+
/**
+* function      Update connection parameters
+* @param[in]    conn: Pointer to the current connection
+* @param[in]    param: Pointer to connection parameter
+* @return       0: success, !=0: fail
+*/
+
+
+

int bt_conn_disconnect(struct bt_conn *conn, u8_t reason)

+
/**
+* function      Disconnect current connection
+* @param[in]    conn: pointer to the current connection
+* @param[in]    reason: the reason for disconnecting the current connection
+* @return       0: success, !=0: fail
+*/
+
+
+

struct bt_conn *bt_conn_create_le(const bt_addr_le_t *peer,const struct bt_le_conn_param *param)

+
/**
+* function      Create connection
+* @param[in]    peer: The pointer of the device address that needs to be connected
+* @param[in]    param: Pointer to connection parameter
+* @return       Success: a valid connection object, otherwise it fails
+*/
+
+
+

int bt_conn_create_auto_le(const struct bt_le_conn_param *param)

+
/**
+* function      Automatically create and connect to devices in the whitelist
+* @param[in]    param: pointer to connection parameter
+* @return       0: success, !=0: fail
+*/
+
+
+

int bt_conn_create_auto_stop(void)

+
/**
+* function      Stop automatic creation and connect to devices in the whitelist
+* @param[in]    None
+* @return       0: success, !=0: fail
+*/
+
+
+

int bt_le_set_auto_conn(const bt_addr_le_t *addr,const struct bt_le_conn_param *param)

+
/**
+* function      Automatically create a connection to the remote device
+* @param[in]    addr: Remote device address pointer
+* @param[in]    param: Pointer to connection parameter
+* @return       0: success, !=0: fail
+*/
+
+
+

struct bt_conn *bt_conn_create_slave_le(const bt_addr_le_t *peer,const struct bt_le_adv_param *param)

+
/**
+* function      Initiate a directed broadcast packet to the remote device
+* @param[in]    peer: Remote device address pointer
+* @param[in]    param: Pointer to broadcast parameters
+* @return       Success: a valid connection object, otherwise it fails
+*/
+
+
+

int bt_conn_set_security(struct bt_conn *conn, bt_security_t sec)

+
/**
+* function      Set the connection security level
+* @param[in]    conn: Pointer to the connection object
+* @param[in]    sec: Security level
+* @return       0: success, !=0: fail
+*/
+
+
+

bt_security_t bt_conn_get_security(struct bt_conn *conn)

+
/**
+* function      Get the security level of the current connection
+* @param[in]    conn: Pointer to the connection object
+* @return       Security Level
+*/
+
+
+

u8_t bt_conn_enc_key_size(struct bt_conn *conn)

+
/**
+* function      Get the size of the encryption key of the current connection
+* @param[in]    conn: Pointer to the connection object
+* @return       The size of the encryption key
+*/
+
+
+

void bt_conn_cb_register(struct bt_conn_cb *cb)

+
/**
+* function      Register connection callback function
+* @param[in]    cb: Connection callback function
+* @return       None
+*/
+
+
+

void bt_set_bondable(bool enable)

+
/**
+* function      Set/clear the binding flag in the SMP pairing request/response to the data authentication request
+* @param[in]    enable: 1: enable, 0: disable
+* @return       None
+*/
+
+
+

int bt_conn_auth_cb_register(const struct bt_conn_auth_cb *cb)

+
/**
+* function      Register authentication callback function
+* @param[in]    cb: Callback function pointer
+* @return       0: success, !=0: failure
+*/
+
+
+

int bt_conn_auth_passkey_entry(struct bt_conn *conn, unsigned int passkey)

+
/**
+* function      Reply with the key
+* @param[in]    conn: Connect object pointer
+* @param[in]    passkey: the key entered
+* @return       0: success, !=0: failure
+*/
+
+
+

int bt_conn_auth_cancel(struct bt_conn *conn)

+
/**
+* function      Cancel the authentication process
+* @param[in]    conn: Connection object pointer
+* @return       0: success, !=0: failure
+*/
+
+
+

int bt_conn_auth_passkey_confirm(struct bt_conn *conn)

+
/**
+* function      If the password matches, reply to the other side
+* @param[in]    conn: Pointer to connection object
+* @return       0: success, !=0: failure
+*/
+
+
+

int bt_conn_auth_pincode_entry(struct bt_conn *conn, const char *pin)

+
/**
+* function      Reply with PIN code
+* @param[in]    conn: Pointer to connection object
+* @param[in]    pin: PIN code pointer
+* @return       0: success, !=0: failure
+*/
+
+
+

int bt_le_read_rssi(u16_t handle,int8_t *rssi)

+
/**
+* function      Read the RSSI value of the opposite device
+* @param[in]    handle: The handle value of the connection
+* @param[in]    rssi: rssi pointer
+* @return       0: success, !=0: failure
+*/
+
+
+

int bt_get_local_address(bt_addr_le_t *adv_addr)

+
/**
+* function      Read the address of the machine
+* @param[in]    adv_addr: Pointer to address
+* @return       0: success, !=0: failure
+*/
+
+
+

int bt_set_tx_pwr(int8_t power)

+
/**
+* function      Set the transmit power of this device
+* @param[in]    power: power value
+* @return       0: success, !=0: failure
+*/
+
+
+
+
+

3.3. Data structure reference

+

bt_le_adv_paramdata structure:

+
/** LE Advertising Parameters. */
+struct bt_le_adv_param {
+    /** Local identity */
+    u8_t  id;
+
+    /** Bit-field of advertising options */
+    u8_t  options;
+
+    /** Minimum Advertising Interval (N * 0.625) */
+    u16_t interval_min;
+
+    /** Maximum Advertising Interval (N * 0.625) */
+    u16_t interval_max;
+
+    #if defined(CONFIG_BT_STACK_PTS)
+    u8_t  addr_type;
+    #endif
+};
+
+
+

This data structure is used to configure broadcast parameters, including local identification, broadcast option bit fields, broadcast gaps, etc. The broadcast option bit fields have the following enumerated type parameters to choose from:

+
enum {
+    /** Convenience value when no options are specified. */
+    BT_LE_ADV_OPT_NONE = 0,
+
+    /** Advertise as connectable. Type of advertising is determined by
+        * providing SCAN_RSP data and/or enabling local privacy support.
+        */
+    BT_LE_ADV_OPT_CONNECTABLE = BIT(0),
+
+    /** Don't try to resume connectable advertising after a connection.
+        *  This option is only meaningful when used together with
+        *  BT_LE_ADV_OPT_CONNECTABLE. If set the advertising will be stopped
+        *  when bt_le_adv_stop() is called or when an incoming (slave)
+        *  connection happens. If this option is not set the stack will
+        *  take care of keeping advertising enabled even as connections
+        *  occur.
+        */
+    BT_LE_ADV_OPT_ONE_TIME = BIT(1),
+
+    /** Advertise using the identity address as the own address.
+        *  @warning This will compromise the privacy of the device, so care
+        *           must be taken when using this option.
+        */
+    BT_LE_ADV_OPT_USE_IDENTITY = BIT(2),
+
+    /** Advertise using GAP device name */
+    BT_LE_ADV_OPT_USE_NAME = BIT(3),
+
+    /** Use low duty directed advertising mode, otherwise high duty mode
+        *  will be used. This option is only effective when used with
+        *  bt_conn_create_slave_le().
+        */
+    BT_LE_ADV_OPT_DIR_MODE_LOW_DUTY = BIT(4),
+
+    /** Enable use of Resolvable Private Address (RPA) as the target address
+        *  in directed advertisements when CONFIG_BT_PRIVACY is not enabled.
+        *  This is required if the remote device is privacy-enabled and
+        *  supports address resolution of the target address in directed
+        *  advertisement.
+        *  It is the responsibility of the application to check that the remote
+        *  device supports address resolution of directed advertisements by
+        *  reading its Central Address Resolution characteristic.
+        */
+    BT_LE_ADV_OPT_DIR_ADDR_RPA = BIT(5),
+
+    /** Use whitelist to filter devices that can request scan response
+        *  data.
+        */
+    BT_LE_ADV_OPT_FILTER_SCAN_REQ = BIT(6),
+
+    /** Use whitelist to filter devices that can connect. */
+    BT_LE_ADV_OPT_FILTER_CONN = BIT(7),
+};
+
+
+

If you need to send a broadcast packet, the configuration can be as follows:

+
param.id = 0;
+param.options = (BT_LE_ADV_OPT_CONNECTABLE | BT_LE_ADV_OPT_USE_NAME | BT_LE_ADV_OPT_ONE_TIME);
+param.interval_min = 0x00a0;
+param.interval_max = 0x00f0;
+
+
+

bt_datadata structure:

+
struct bt_data {
+    u8_t type;
+    u8_t data_len;
+    const u8_t *data;
+};
+
+
+

This data structure is used to fill the data in the broadcast packet, the specific data packet type can refer to the following:

+
Service UUID
+Local Name
+Flags
+Manufacturer Specific Data
+TX Power Level
+Secure Simple Pairing OOB
+Security Manager OOB
+Security Manager TK Value
+Slave Connection Interval Range
+Service Solicitation
+Service Data
+Appearance
+Public Target Address
+Random Target Address
+Advertising Interval
+LE Bluetooth Device Address
+LE Role
+Uniform Resource Identifier
+LE Supported Features
+Channel Map Update Indication
+
+
+

Use this data structure to configure a broadcast packet data, as shown below:

+
struct bt_data ad_discov[] = {
+    BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
+    BT_DATA(BT_DATA_NAME_COMPLETE, "BL602-BLE-DEV", 13),
+};
+
+
+

bt_le_scan_paramdata structure:

+
/** LE scan parameters */
+struct bt_le_scan_param {
+    /** Scan type (BT_LE_SCAN_TYPE_ACTIVE or BT_LE_SCAN_TYPE_PASSIVE) */
+    u8_t  type;
+
+    /** Bit-field of scanning filter options. */
+    u8_t  filter_dup;
+
+    /** Scan interval (N * 0.625 ms) */
+    u16_t interval;
+
+    /** Scan window (N * 0.625 ms) */
+    u16_t window;
+};
+
+
+

This data structure is used to fill scan parameters, +type: There are two types of scan types: BT_LE_SCAN_TYPE_ACTIVE (0x01) and BT_LE_SCAN_TYPE_PASSIVE (0x00) +filter_dup: 0x00, except for targeted advertisements, accept all broadcast and scan responses, 0x01, only receive broadcast and scan responses from devices in the whitelist +interval: Scan interval +window: Scan window

+

If the scan request is enabled, it can be configured as follows:

+
scan_param.type = BT_LE_SCAN_TYPE_PASSIVE
+scan_param.filter_dup = 0x00
+interval=BT_GAP_SCAN_SLOW_INTERVAL_1
+window=BT_GAP_SCAN_SLOW_WINDOW_1
+
+
+

bt_le_conn_paramdata structure:

+
/** Connection parameters for LE connections */
+struct bt_le_conn_param {
+    u16_t interval_min;
+    u16_t interval_max;
+    u16_t latency;
+    u16_t timeout;
+
+    #if defined(CONFIG_BT_STACK_PTS)
+    u8_t  own_address_type;
+    #endif
+};
+
+
+

This data structure is used to fill in the connection parameters, interval_min: the minimum value of the connection interval (0x0018), interval_max: the maximum value of the connection interval (0x0028), +latency: The maximum slave latency allowed for connection events +timeout: The time for the connection to time out

+

Configure the data structure as follows:

+
interval_min=BT_GAP_INIT_CONN_INT_MIN(0x0018)
+interval_max=BT_GAP_INIT_CONN_INT_MAX(0x0028)
+latency=0
+timeout=400
+
+
+

bt_conndata structure:

+
struct bt_conn {
+    u16_t                   handle;
+    u8_t                    type;
+    u8_t                    role;
+
+    ATOMIC_DEFINE(flags, BT_CONN_NUM_FLAGS);
+
+    /* Which local identity address this connection uses */
+    u8_t                    id;
+
+#if defined(CONFIG_BT_SMP) || defined(CONFIG_BT_BREDR)
+    bt_security_t           sec_level;
+    bt_security_t           required_sec_level;
+    u8_t                    encrypt;
+#endif /* CONFIG_BT_SMP || CONFIG_BT_BREDR */
+
+    /* Connection error or reason for disconnect */
+    u8_t                    err;
+
+    bt_conn_state_t         state;
+
+    u16_t                   rx_len;
+    struct net_buf          *rx;
+
+    /* Sent but not acknowledged TX packets with a callback */
+    sys_slist_t             tx_pending;
+    /* Sent but not acknowledged TX packets without a callback before
+    * the next packet (if any) in tx_pending.
+    */
+    u32_t                   pending_no_cb;
+
+    /* Completed TX for which we need to call the callback */
+    sys_slist_t             tx_complete;
+    struct k_work           tx_complete_work;
+
+
+    /* Queue for outgoing ACL data */
+    struct k_fifo           tx_queue;
+
+    /* Active L2CAP channels */
+    sys_slist_t             channels;
+
+    atomic_t                ref;
+
+    /* Delayed work for connection update and other deferred tasks */
+    struct k_delayed_work   update_work;
+
+    union {
+        struct bt_conn_le   le;
+#if defined(CONFIG_BT_BREDR)
+        struct bt_conn_br   br;
+        struct bt_conn_sco  sco;
+#endif
+    };
+
+#if defined(CONFIG_BT_REMOTE_VERSION)
+    struct bt_conn_rv {
+        u8_t  version;
+        u16_t manufacturer;
+        u16_t subversion;
+    } rv;
+#endif
+};
+
+
+

This data structure is the current connection data structure, which includes the parameters related to the BLE connection. After the connection is successful, the data structure can be called by the user.

+
+
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/api_reference/peripheral/api_adc.html b/docs/development_guide_en/build/html/api_reference/peripheral/api_adc.html new file mode 100644 index 00000000..ac85363e --- /dev/null +++ b/docs/development_guide_en/build/html/api_reference/peripheral/api_adc.html @@ -0,0 +1,531 @@ + + + + + + + + + + 2.8. ADC — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

2.8. ADC

+
+

2.8.1. Introduction

+

ADC (Analog-to-digital Converter) can convert continuous analog signals into discrete digital signals.

+

The ADC module in BL MCU series has the following characteristics:

+
    +
  • Support selecting 12/14/16 bits conversion result output

  • +
  • ADC maximum working clock is 2MHZ

  • +
  • Support 2.0V, 3.2V optional internal reference voltage

  • +
  • DMA support

  • +
  • Support four modes: single channel single conversion, continuous single channel conversion, single multi-channel conversion and continuous multi-channel conversion mode

  • +
  • Support both single-ended and differential input modes

  • +
  • 12 external analog channels

  • +
  • 2 DAC internal channels

  • +
  • 1 VBAT /2 channel

  • +
+
+
+

2.8.2. ADC Device Structure Definition

+
typedef struct adc_device {
+    struct device parent;
+    adc_clk_div_t clk_div;
+    adc_vref_t vref;
+    bool continuous_conv_mode;
+    bool differential_mode;
+    adc_data_width_t data_width;
+    adc_fifo_threshold_t fifo_threshold;
+    adc_pga_gain_t gain;
+} adc_device_t;
+
+
+
    +
  • parent inherits the properties of the parent class

  • +
  • clk_div Partial frequency clock in ADC module

  • +
  • vref 2.0/3.2V reference voltage optional

  • +
  • continuous_conv_mode Whether to select continuous mode. If it is in continuous mode, once adc_start operation, ADC will continue to work until adc_stop. If it is not in continuous mode, adc will only convert the result once every adc_start.

  • +
  • differential_mode Whether it is in differential mode, if it is in differential mode, negative voltage can be measured.

  • +
  • data_width Measurement width selection, the actual accuracy of ADC is 12 bits, but the accuracy of 14bits / 16bits can be achieved by averaging multiple times through OSR. Note that when a higher data width is selected, the frequency will decrease due to averaging. For details, please refer to the enumeration information.

  • +
  • fifo_threshold This parameter affects the DMA handling threshold and ADC FIFO interrupt threshold

  • +
  • gain ADC gain selection for input signal

  • +
  • Others to be added

  • +
+
+
+

2.8.3. ADC Device Parameter Configuration Table

+

Each ADC has a parameter configuration macro, the macro definition is located in the peripheral_config.h file under the bsp/board/xxx directory, and the variable definition is located in hal_adc.c, so there is no need for the user to define it by himself . When the user opens the macro of the corresponding device, the configuration of the device will take effect. For example, open the macro BSP_USING_ADC0 to take effect, and at the same time, the ADC device can be registered and used.

+
/*Parameter configuration macro*/
+#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
+
+/*Variable definitions*/
+static adc_device_t adcx_device[ADC_MAX_INDEX] = {
+#ifdef BSP_USING_ADC0
+    ADC0_CONFIG,
+#endif
+};
+
+
+
+

Note

+

The above configuration can be modified through ADC_DEV(dev)->xxx and can only be used before device_open.

+
+
+
+

2.8.4. ADC Device Interface

+

ADC device interfaces all follow the interfaces provided by the standard device driver management layer.

+
+

2.8.4.1. adc_register

+

adc_register is used to register an ADC device standard driver interface.Before registering, you need to open the macro definition of the corresponding ADC device. For example, define the macro BSP_USING_ADC0 to use the ADC0 device. After the registration is completed, other interfaces can be used. If no macro is defined, the ADC0 device cannot be used.

+
int adc_register(enum adc_index_type index, const char *name);
+
+
+
    +
  • index device index to be registered

  • +
  • name device name to be registered

  • +
+

index is used to select ADC device configuration, one index corresponds to one ADC device configuration, for example, ADC0_INDEX corresponds to ADC0_CONFIG configuration. index has the following optional types:

+
enum adc_index_type
+{
+#ifdef BSP_USING_ADC0
+    ADC0_INDEX,
+#endif
+    ADC_MAX_INDEX
+};
+
+
+
+
+

2.8.4.2. device_open

+

device_open is used to open an ADC device,this funtion calls adc_open actually.

+
int device_open(struct device *dev, uint16_t oflag);
+
+
+
    +
  • dev device handle

  • +
  • oflag open mode

  • +
  • return Error code, 0: open successfully, others: error

  • +
+

oflag provides the following types

+
#define DEVICE_OFLAG_STREAM_TX  0x001 /* The device is turned on in rotation sending mode */
+#define DEVICE_OFLAG_STREAM_RX  0x002 /* The device is turned on in rotation receiving mode */
+#define DEVICE_OFLAG_INT_TX     0x004 /* The device is turned on in interrupt sending mode */
+#define DEVICE_OFLAG_INT_RX     0x008 /* The device is turned on in interrupt receiving mode */
+#define DEVICE_OFLAG_DMA_TX     0x010 /* The device is turned on in DMA transmission mode */
+#define DEVICE_OFLAG_DMA_RX     0x020 /* The device is turned on in DMA receiving mode */
+
+
+
+
+

2.8.4.3. device_close

+

device_close is used to close an ADC device,this funtion calls adc_close actually.

+
int device_close(struct device *dev);
+
+
+
    +
  • dev device handle

  • +
  • return Error code, 0: open successfully, others: error

  • +
+
+
+

2.8.4.4. device_control

+

device_control is used to control and modify the parameters of the adc device according to commands.This funtion calls adc_control actually.

+
int device_control(struct device *dev, int cmd, void *args);
+
+
+
    +
  • dev Device handle

  • +
  • cmd Device control commands

  • +
  • args Control parameter

  • +
  • return Different control commands return different meanings.

  • +
+

In addition to standard control commands, serial devices also have their own special control commands.

+
#define DEVICE_CTRL_ADC_CHANNEL_START  0x10
+#define DEVICE_CTRL_ADC_CHANNEL_STOP   0x11
+#define DEVICE_CTRL_ADC_CHANNEL_CONFIG 0x12
+#define DEVICE_CTRL_ADC_VBAT_ON        0x13
+#define DEVICE_CTRL_ADC_VBAT_OFF       0x14
+#define DEVICE_CTRL_ADC_TSEN_ON        0x15
+#define DEVICE_CTRL_ADC_TSEN_OFF       0x16
+
+
+

args input is different depending on cmd, the list is as follows:

+ + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
table1

cmd

args

description

DEVICE_CTRL_SET_INT

adc_it_type

Enable ADC device interrupt

DEVICE_CTRL_CLR_INT

adc_it_type

Disable ADC device interrupt

DEVICE_CTRL_CONFIG

ADC_param_cfg_t

Modify ADC configuration

DEVICE_CTRL_ADC_CHANNEL_CONFIG

adc_channel_cfg_t

Modify ADC channel configuration

DEVICE_CTRL_ATTACH_RX_DMA

struct device*

Link receiving DMA device

DEVICE_CTRL_ADC_CHANNEL_START

NULL

Start/continue ADC conversion

DEVICE_CTRL_ADC_CHANNEL_STOP

NULL

Stop ADC conversion

DEVICE_CTRL_ADC_VBAT_ON

NULL

Turn on the internal VDD measurement circuit

DEVICE_CTRL_ADC_VBAT_OFF

NULL

Turn off the internal VDD measurement circuit

DEVICE_CTRL_ADC_TSEN_ON

NULL

Turn on the internal temperature measurement circuit (requires hardware support)

DEVICE_CTRL_ADC_TSEN_OFF

NULL

Turn off the internal temperature measurement circuit (requires hardware support)

+
+
+

2.8.4.5. device_read

+

device_read is used to receive the data of ADC device, the receiving mode can be polling, interrupt, dma.

+
int device_read(struct device *dev, uint32_t pos, void *buffer, uint32_t size);
+
+
+
    +
  • dev Dvice handle

  • +
  • pos No effect

  • +
  • buffer Buffer to read

  • +
  • size Length to read

  • +
  • return Error code, 0: open successfully, others: error

  • +
+
+
+

2.8.4.6. device_set_callback

+

device_set_callback is used to register an ADC threshold interrupt callback function.

+
int device_set_callback(struct device *dev, void (*callback)(struct device *dev, void *args, uint32_t size, uint32_t event));
+
+
+
    +
  • dev Device handle

  • +
  • callback The interrupt callback function to be registered

    +
    +
      +
    • dev Device handle

    • +
    • args Receive and send buffer, the data type is uint8_t*

    • +
    • size Transmission length

    • +
    • event Type of interrupt event

    • +
    +
    +
  • +
+

event type is as follows:

+
enum ADC_event_type
+{
+    ADC_EVENT_FIFO_READY,
+    ADC_EVENT_OVERRUN,
+    ADC_EVENT_UNDERRUN,
+};
+
+
+
+
+
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/api_reference/peripheral/api_clock.html b/docs/development_guide_en/build/html/api_reference/peripheral/api_clock.html new file mode 100644 index 00000000..02cf30b0 --- /dev/null +++ b/docs/development_guide_en/build/html/api_reference/peripheral/api_clock.html @@ -0,0 +1,320 @@ + + + + + + + + + + 2.1. Clock tree — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

2.1. Clock tree

+
+

2.1.1. Introduction

+

The BL series chips have a lot of clock source selection and provide a clock tree configuration table to facilitate user configuration. Users do not need to call the clock setting interface. Users only need to care about the final system clock and peripheral clock frequency. The clock configuration table is located in the clock_config.h file under the bsp/board/xxx_board directory.

+
+
+

2.1.2. Clock Frequency Acquisition Interface

+
+

2.1.2.1. system_clock_get

+

system_clock_get is used to get the system clock frequency.

+
uint32_t system_clock_get(enum system_clock_type type);
+
+
+
    +
  • type the type of system clock frequency

  • +
+

type provide the following types

+
enum system_clock_type
+{
+    SYSTEM_CLOCK_ROOT_CLOCK = 0,
+    SYSTEM_CLOCK_FCLK,
+    SYSTEM_CLOCK_BCLK,
+    SYSTEM_CLOCK_XCLK,
+    SYSTEM_CLOCK_32K_CLK,
+    SYSTEM_CLOCK_AUPLL,
+};
+
+
+
+
+

2.1.2.2. peripheral_clock_get

+

peripheral_clock_get is used to get the peripheral clock frequency.

+
uint32_t peripheral_clock_get(enum peripheral_clock_type type);
+
+
+
    +
  • type peripheral clock frequency type

  • +
+

type provide the following types

+
enum peripheral_clock_type
+{
+    PERIPHERAL_CLOCK_UART = 0,
+    PERIPHERAL_CLOCK_SPI,
+    PERIPHERAL_CLOCK_I2C,
+    PERIPHERAL_CLOCK_ADC,
+    PERIPHERAL_CLOCK_DAC,
+    PERIPHERAL_CLOCK_I2S,
+    PERIPHERAL_CLOCK_PWM,
+    PERIPHERAL_CLOCK_CAM,
+};
+
+
+
+
+
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/api_reference/peripheral/api_dac.html b/docs/development_guide_en/build/html/api_reference/peripheral/api_dac.html new file mode 100644 index 00000000..0e8df0ec --- /dev/null +++ b/docs/development_guide_en/build/html/api_reference/peripheral/api_dac.html @@ -0,0 +1,277 @@ + + + + + + + + + + 2.9. DAC — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

2.9. DAC

+
+

2.9.1. Introduction

+
+
+

2.9.2. DAC Structure Definition

+
+
+

2.9.3. DAC Parameter Configuration Table

+
+
+

2.9.4. DAC Device Interface

+
+
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/api_reference/peripheral/api_dma.html b/docs/development_guide_en/build/html/api_reference/peripheral/api_dma.html new file mode 100644 index 00000000..31494220 --- /dev/null +++ b/docs/development_guide_en/build/html/api_reference/peripheral/api_dma.html @@ -0,0 +1,685 @@ + + + + + + + + + + 2.5. DMA — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

2.5. DMA

+
+

2.5.1. Introduction

+

DMA is a memory access technology that can directly read and write system memory independently without processor intervention. Under the same degree of processor burden, DMA is a fast data transfer method. The DMA device in BL series MCU has the following characteristics:

+
    +
  • 8 independent dedicated channels

  • +
  • Four transmission directions: memory to memory, memory to peripheral, peripheral to memory, peripheral to peripheral

  • +
  • LLI linked list

  • +
+
+
+

2.5.2. DMA Device Structure Definition

+
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 inherits the properties of the parent class

  • +
  • id DMA id number, default 0, currently there is only one DMA

  • +
  • ch channel number

  • +
  • direction transmission direction

  • +
  • transfer_mode transfer mode

  • +
  • src_req source request

  • +
  • dst_req destination request

  • +
  • src_burst_size source burst bytes

  • +
  • dst_burst_size destination number of burst bytes

  • +
  • src_width source transmission bit width

  • +
  • dst_width destination transmission bit width

  • +
  • lli_cfg used to store some information of the dma channel, the user does not need to worry about it

  • +
+

direction provides the following types

+
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 provides the following types

+
#define DMA_LLI_ONCE_MODE     0
+#define DMA_LLI_CYCLE_MODE    1
+
+
+

src_req provides the following types

+
#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 provides the following types

+
#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 provides the following types

+
#define DMA_BURST_1BYTE     0
+#define DMA_BURST_4BYTE     1
+#define DMA_BURST_8BYTE     2
+#define DMA_BURST_16BYTE    3
+
+
+

dst_burst_size provides the following types

+
#define DMA_BURST_1BYTE     0
+#define DMA_BURST_4BYTE     1
+#define DMA_BURST_8BYTE     2
+#define DMA_BURST_16BYTE    3
+
+
+

src_width provides the following types

+
#define DMA_TRANSFER_WIDTH_8BIT  0
+#define DMA_TRANSFER_WIDTH_16BIT 1
+#define DMA_TRANSFER_WIDTH_32BIT 2
+
+
+

dst_width: provide the following types

+
#define DMA_TRANSFER_WIDTH_8BIT  0
+#define DMA_TRANSFER_WIDTH_16BIT 1
+#define DMA_TRANSFER_WIDTH_32BIT 2
+
+
+
+
+

2.5.3. DMA Device Parameter Configuration Table

+

Each DMA device has a parameter configuration macro, the macro definition is located in the peripheral_config.h file under the bsp/board/xxx directory, and the variable definition is located in hal_dma.c, so there is no need for the user himself Define variables. When the user opens the macro of the corresponding device, the configuration of the device will take effect. For example, open the macro BSP_USING_DMA0_CH0, DMA0_CH0_CONFIG will take effect, and the DMA channel 0 device can be registered and used.

+
/*Parameter configuration macro*/
+#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
+
+
+/*Variable definitions*/
+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

+

The above configuration can be modified through DMA_DEV(dev)->xxx and can only be used before calling device_open.

+
+
+
+

2.5.4. DMA Device Interface

+

The DMA device interface follows which provided by the standard device driver management layer. In order to facilitate the user to call, some standard interfaces are redefined using macros.

+
+

2.5.4.1. dma_register

+

dma_register is used to register a DMA device standard driver interface. Before registering, you need to open the channel macro definition of the corresponding DMA device. For example, after defining the macro BSP_USING_DMA_CH0, the 0 channel of the DMA device can be used. After the registration is completed, other interfaces can be used. If the macro is not defined, the 0 channel of the DMA device cannot be used.

+
int dma_register(enum dma_index_type index, const char *name);
+
+
+
    +
  • index device index to be registered

  • +
  • name device name to be registered

  • +
+

index is used to select the configuration of a certain channel of DMA, an index corresponds to a channel configuration of a DMA, for example, DMA_CH0_INDEX corresponds to the configuration of DMA channel 0, and index has the following optional types

+
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
+};
+
+
+
+
+

2.5.4.2. device_open

+

device_open is used to open a channel of a dma device,this funtion calls dma_open actually.

+
int device_open(struct device *dev, uint16_t oflag);
+
+
+
    +
  • dev device handle

  • +
  • oflag open mode

  • +
  • return Error code, 0 means opening is successful, other means error

  • +
+

oflag provides the following types

+
#define DEVICE_OFLAG_STREAM_TX  0x001 /* The device is turned on in polling sending mode */
+#define DEVICE_OFLAG_STREAM_RX  0x002 /* The device is turned on in polling receiving mode */
+#define DEVICE_OFLAG_INT_TX     0x004 /* The device is turned on in interrupt sending mode */
+#define DEVICE_OFLAG_INT_RX     0x008 /* The device is turned on in interrupt receiving mode */
+#define DEVICE_OFLAG_DMA_TX     0x010 /* The device is turned on in DMA transmission mode */
+#define DEVICE_OFLAG_DMA_RX     0x020 /* The device is turned on in DMA receiving mode */
+
+
+
+
+

2.5.4.3. device_close

+

device_close is used to close a channel of a dma device,this funtion calls dma_close actually.

+
int device_close(struct device *dev);
+
+
+
    +
  • dev device handle

  • +
  • return error code, 0 means closing is successful, others mean error

  • +
+
+
+

2.5.4.4. device_control

+

device_control is used to control and modify the parameters of the dma device according to commands.This funtion calls dma_control actually.

+
int device_control(struct device *dev, int cmd, void *args);
+
+
+
    +
  • dev device handle

  • +
  • cmd device control command

  • +
  • args control parameters

  • +
  • return different control commands return different meanings

  • +
+

In addition to standard control commands, DMA devices also have their own special control commands.

+
#define DMA_CHANNEL_GET_STATUS  0x10
+#define DMA_CHANNEL_START       0x11
+#define DMA_CHANNEL_STOP        0x12
+#define DMA_CHANNEL_UPDATE      0x13
+
+
+

args input is different depending on cmd, the list is as follows:

+ + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
table1

cmd

args

description

DEVICE_CTRL_SET_INT

NULL

Enable DMA transfer completion interrupt

DEVICE_CTRL_CLR_INT

NULL

Disable DMA transfer completion interrupt

DMA_CHANNEL_GET_STATUS

NULL

Get DMA channel completion status

DMA_CHANNEL_START

NULL

Open dma channel

DMA_CHANNEL_STOP

NULL

Close dma channel

DMA_CHANNEL_UPDATE

NULL

Update dma transmission configuration

+
+
+

2.5.4.5. device_set_callback

+

device_set_callback is used to register a DMA channel interrupt callback function.

+
int device_set_callback(struct device *dev, void (*callback)(struct device *dev, void *args, uint32_t size, uint32_t event));
+
+
+
    +
  • dev Device handle

  • +
  • callback The interrupt callback function to be registered

    +
    +
      +
    • dev device handle

    • +
    • args unused

    • +
    • size unused

    • +
    • event interrupt event type

    • +
    +
    +
  • +
+

event type definition is as follows:

+
enum dma_event_type
+{
+    DMA_EVENT_COMPLETE,
+};
+
+
+
+
+

2.5.4.6. dma_channel_start

+

dma_channel_start is used to open the DMA channel. It actually calls device_control, where cmd is DMA_CHANNEL_START.

+
dma_channel_start(dev)
+
+
+
    +
  • dev dma channel handle that needs to be opened

  • +
+
+
+

2.5.4.7. dma_channel_stop

+

dma_channel_stop is used to close the DMA channel. It actually calls device_control, where cmd is DMA_CHANNEL_STOP.

+
dma_channel_stop(dev)
+
+
+
    +
  • dev dma channel handle that needs to be closed

  • +
+
+
+

2.5.4.8. dma_channel_update

+

dma_channel_update is used to update the DMA configuration. The actual call is device_control, where cmd is DMA_CHANNEL_UPDATE.

+
dma_channel_update(dev,list)
+
+
+
    +
  • dev dma channel handle that needs to be updated

  • +
  • list dma_lli_ctrl_t handle

  • +
+
+
+

2.5.4.9. dma_channel_check_busy

+

dma_channel_check_busy is used to query whether the currently used DMA channel has completed the transfer. It actually calls device_control, where cmd is DMA_CHANNEL_GET_STATUS.

+
dma_channel_check_busy(dev)
+
+
+
    +
  • dev DMA channel handle to be queried

  • +
  • return return the current DMA status, 0 means the transfer is complete, 1 means the transfer is not complete

  • +
+
+
+

2.5.4.10. dma_reload

+

dma_reload is used to update the configuration of a certain channel of DMA. Compared with dma_channel_update, this function does not require the user to pass many parameters, but only needs to fill in the source address, destination address, and length. After this function is called, the DMA channel is not turned on. You need to manually call the dma_channel_start function.

+
int dma_reload(struct device *dev, uint32_t src_addr, uint32_t dst_addr, uint32_t transfer_size);
+
+
+
    +
  • dev DMA channel handle to be queried

  • +
  • src_addr transmission source address

  • +
  • dst_addr transmission destination address

  • +
  • transfer_size the total length of transferred bytes. If the number of bits transferred is 16 bits or 32 bits, it needs to be converted into byte length here.

  • +
+
+
+
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/api_reference/peripheral/api_gpio.html b/docs/development_guide_en/build/html/api_reference/peripheral/api_gpio.html new file mode 100644 index 00000000..a8e203f3 --- /dev/null +++ b/docs/development_guide_en/build/html/api_reference/peripheral/api_gpio.html @@ -0,0 +1,373 @@ + + + + + + + + + + 2.2. GPIO — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

2.2. GPIO

+
+

2.2.1. Introduction

+

The full name of GPIO is General Purpose Input Output. The GPIO peripherals of BL series chips mainly have the following functions.

+
    +
  • General input and output pull-up and pull-down

  • +
  • Multiplex function pull-up and pull-down

  • +
  • Simulation function

  • +
  • External interrupt (rising edge, falling edge, high level, low level)

  • +
  • Hardware eliminate jitter

  • +
  • Drive capacity control

  • +
+

The pin configuration of bl mcu sdk is divided into two kinds.

+
    +
  • GPIO multiplexing function is through a special pinmux table, users only need to modify the functions of related pins in the table, and the program will automatically configure these pins. pinmux table is located in the pinmux_config.h file under the bsp/board/xxx_board directory.

  • +
  • Configure the pins through the standard GPIO device interface. The disadvantage is that only common input and output and interrupt functions can be configured. It is recommended to use the table to configure the multiplexing functions.

  • +
+
+
+

2.2.2. GPIO Device Interface

+
+

2.2.2.1. gpio_set_mode

+

gpio_set_mode is used to configure the mode of gpio.

+
void gpio_set_mode(uint32_t pin, uint32_t mode);
+
+
+
    +
  • pin the pin to be configured

  • +
  • mode pin function to be configured

  • +
+

mode provides the following types

+
#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
+
+
+
+
+

2.2.2.2. gpio_write

+

gpio_write is used to set pin level

+
void gpio_write(uint32_t pin, uint32_t value);
+
+
+
    +
  • pin the pin to be set

  • +
  • value the level to be set

  • +
+
+
+

2.2.2.3. gpio_toggle

+

gpio_toggle: is used to toggle pin level

+
void gpio_toggle(uint32_t pin);
+
+
+
    +
  • pin: the pin to be toggled

  • +
+
+
+

2.2.2.4. gpio_read

+

gpio_read is used to read pin level

+
int  gpio_read(uint32_t pin);
+
+
+
    +
  • pin the pin to read the level

  • +
  • return 0 is low level, 1 is high level

  • +
+
+
+

2.2.2.5. gpio_attach_irq

+

gpio_attach_irq is used to attache an interrupt callback function to the interrupt pin

+
void gpio_attach_irq(uint32_t pin, void (*cbfun)(uint32_t pin));
+
+
+
    +
  • pin the pin to which the interrupt callback is attached

  • +
  • cbfun register interrupt callback

  • +
+
+
+

2.2.2.6. gpio_irq_enable

+

gpio_irq_enable is used to enable gpio interrupt

+
void gpio_irq_enable(uint32_t pin,uint8_t enabled);
+
+
+
    +
  • pin the pin to turn on or off the interrupt

  • +
  • enabled 0 is to close the interrupt, 1 is to open the interrupt

  • +
+
+
+
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/api_reference/peripheral/api_i2c.html b/docs/development_guide_en/build/html/api_reference/peripheral/api_i2c.html new file mode 100644 index 00000000..ea6f3ce2 --- /dev/null +++ b/docs/development_guide_en/build/html/api_reference/peripheral/api_i2c.html @@ -0,0 +1,415 @@ + + + + + + + + + + 2.6. I2C — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

2.6. I2C

+
+

2.6.1. Introduction

+

I2C (Inter-Intergrated Circuit) is a serial communication bus that uses a multi-master-slave architecture to connect low-speed peripheral devices. Each device has a unique address identification, and can be used as a transmitter or receiver. Each device connected to the bus can set the address with software through a unique address and the always-existing relationship between master and slave, and the host can be used as a host transmitter or host receiver. If two or more hosts are initialized at the same time, data transmission can prevent data from being destroyed through conflict detection and arbitration. The I2C devices in the BL series MCU have the following characteristics:

+
    +
  • Flexible configuration of slave address slaveAddr, register address subAddr

  • +
  • Clock frequency that can be flexibly adjusted

  • +
  • Support polling, interrupt, DMA transfer

  • +
+
+
+

2.6.2. I2C Device Structure Definition

+
typedef struct i2c_device
+{
+    struct device parent;
+    uint8_t id;
+    uint8_t mode;
+    uint32_t phase;
+} i2c_device_t;
+
+
+
    +
  • parent inherit the properties of the parent class

  • +
  • ch i2c id, 0 means i2c0, 1 means i2c1

  • +
  • mode i2c transmission mode, 0 means using hardware i2c, 1 means using software i2c, current software i2c is temporarily invalid

  • +
  • phase i2c clock phase div, i2c_clk = i2c_source_clk/(4*(phase+1))

  • +
  • TODO

  • +
+
+
+

2.6.3. I2C Device Parameter Configuration Table

+

Each I2C device has a parameter configuration macro, the macro definition is located in the peripheral_config.h file under the bsp/board/xxx directory, and the variable definition is located in hal_i2c.c, so the user does not need to define variable. When the user opens the macro of the corresponding device, the configuration of the device will take effect. For example, open the macro BSP_USING_I2C0, I2C0_CONFIG will take effect, and the I2C device can be registered and used.

+
/*Parameter configuration macro*/
+#if defined(BSP_USING_I2C0)
+#ifndef I2C0_CONFIG
+#define I2C0_CONFIG \
+{   \
+.id = 0, \
+.mode = I2C_HW_MODE,\
+.phase = 15, \
+}
+#endif
+#endif
+
+/*Variable definition*/
+static i2c_device_t i2cx_device[I2C_MAX_INDEX] =
+{
+#ifdef BSP_USING_I2C0
+    I2C0_CONFIG,
+#endif
+};
+
+
+
+

Note

+

The above configuration can be modified through I2C_DEV(dev)->xxx and can only be used before calling device_open.

+
+
+
+

2.6.4. I2C Device Interface

+

The I2C device standard interface currently only uses device_open, and provides a standard data transceiver interface.

+
+

2.6.4.1. i2c_register

+

i2c_register is used to register an I2C device standard driver interface. The macro definition of the corresponding I2C device needs to be opened before registration. For example, define the macro BSP_USING_I2C0 to use the I2C0 device. After the registration is completed, other interfaces can be used. If the macro is not defined, the I2C0 device cannot be used.

+
int i2c_register(enum i2c_index_type index, const char *name);
+
+
+
    +
  • index device index to be registered

  • +
  • name device name to be registered

  • +
+

index is used to select I2C device, one index corresponds to one I2C device configuration, for example, I2C0_INDEX corresponds to I2C0_CONFIG configuration, index has the following optional types

+
enum i2c_index_type
+{
+#ifdef BSP_USING_I2C0
+    I2C0_INDEX,
+#endif
+    I2C_MAX_INDEX
+};
+
+
+
+
+

2.6.4.2. device_open

+

device_open is used to open an i2c device, this funtion calls i2c_open actually.

+
int device_open(struct device *dev, uint16_t oflag);
+
+
+
    +
  • dev device handle

  • +
  • oflag open mode

  • +
  • return error code, 0 means opening is successful, others mean errors

  • +
+

oflag provides the following types

+
#define DEVICE_OFLAG_STREAM_TX  0x001 /* The device is turned on in polling sending mode */
+#define DEVICE_OFLAG_STREAM_RX  0x002 /* The device is turned on in polling receiving mode */
+#define DEVICE_OFLAG_INT_TX     0x004 /* The device is turned on in interrupt sending mode */
+#define DEVICE_OFLAG_INT_RX     0x008 /* The device is turned on in interrupt receiving mode */
+#define DEVICE_OFLAG_DMA_TX     0x010 /* The device is turned on in DMA transmission mode */
+#define DEVICE_OFLAG_DMA_RX     0x020 /* The device is turned on in DMA receiving mode */
+
+
+
+
+

2.6.4.3. i2c_transfer

+

i2c_transfer is used to transfer i2c msg. The member flags in i2c_msg_t structure indicates whether the direction of the transfer is writing or reading, and the length of the specified register address is 0, 1, 2.

+
int i2c_transfer(struct device *dev, i2c_msg_t msgs[], uint32_t num);
+
+
+
    +
  • dev device handle

  • +
  • msgs message to be transmitted

  • +
  • num the number of messages

  • +
  • return error code, 0 means opening is successful, others mean error

  • +
+

i2c_msg_t structure is defined as follows:

+
typedef struct i2c_msg
+{
+    uint8_t slaveaddr;
+    uint32_t subaddr;
+    uint16_t flags;
+    uint16_t len;
+    uint8_t *buf;
+} i2c_msg_t;
+
+
+
    +
  • slaveaddr i2c slave device 7-bit slave address

  • +
  • subaddr i2c slave device register address

  • +
  • flags read and write mode and register address length

  • +
  • len transmission data length

  • +
  • buf data buffer

  • +
+

flags definition is as follows:

+
/*Read and write mode*/
+#define I2C_WR 0x0000
+#define I2C_RD 0x0001
+
+/*Register address length*/
+#define SUB_ADDR_0BYTE 0x0010
+#define SUB_ADDR_1BYTE 0x0020
+#define SUB_ADDR_2BYTE 0x0040
+
+
+
+
+
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/api_reference/peripheral/api_pwm.html b/docs/development_guide_en/build/html/api_reference/peripheral/api_pwm.html new file mode 100644 index 00000000..018d6dca --- /dev/null +++ b/docs/development_guide_en/build/html/api_reference/peripheral/api_pwm.html @@ -0,0 +1,553 @@ + + + + + + + + + + 2.4. PWM — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

2.4. PWM

+
+

2.4.1. Introduction

+

PWM is a technology that implements analog voltage control in a digital way. It modulates the width of a series of pulses, equivalent to the required waveform (including shape and amplitude), and digitally encodes the analog signal level. That is to say, by adjusting the change of the duty cycle to adjust the change of the signal, energy, etc. The duty cycle refers to the percentage of the entire signal period when the signal is at a high level. For example, the duty cycle of a square wave is 50%. The DMA device in BL series MCU has the following characteristics:

+
    +
  • Support 5-channel PWM

  • +
  • Three clock sources can be selected (bus clock <bclk>, crystal oscillator clock <xtal_ck>, slow clock <32k>), with 16-bit clock divider

  • +
  • Double threshold domain setting, increase pulse flexibility

  • +
+
+
+

2.4.2. PWM Device Structure Definition

+
typedef struct pwm_device {
+    struct device parent;
+    uint8_t ch;
+    uint8_t polarity_invert_mode;
+    uint16_t period;
+    uint16_t threshold_low;
+    uint16_t threshold_high;
+    uint16_t it_pulse_count;
+
+} pwm_device_t;
+
+
+
    +
  • parent inherit the properties of the parent class

  • +
  • ch channel number, ch is 0 if PWM channel 0 is enabled, ch is 1 if PWM channel 1 is enabled, and so on

  • +
  • polarity_invert_mode polarity invert enable

  • +
  • period PWM period value

  • +
  • threshold_low PWM low threshold

  • +
  • threshold_high PWM high threshold

  • +
  • it_pulse_count The cycle count value that triggered the interrupt condition

  • +
+
+

Note

+

PWM actual frequency = pwm_clock_source/frequency_division/period, period is not the actual PWM period,it just has the same name.

+
+
+

Note

+

PWM Duty cycle = (threshold_high-threshold_low)/period * 100%

+
+
+
+

2.4.3. PWM Device Parameter Configuration Table

+

Each PWM device has a parameter configuration macro, the macro definition is located in the peripheral_config.h file under the bsp/board/xxx directory, and the variable definition is located in hal_pwm.c, so the user does not need to define variable. When the user opens the macro of the corresponding device, the configuration of the device will take effect. For example, open the macro BSP_USING_PWM_CH2, and PWM_CH2_CONFIG will take effect, and at the same time, channel 2 of the PWM device can be registered and used.

+
/*Parameter configuration macro*/
+#if defined(BSP_USING_PWM_CH2)
+#ifndef PWM_CH2_CONFIG
+#define PWM_CH2_CONFIG                   \
+    {                                    \
+        .ch = 2,                         \
+        .polarity_invert_mode = DISABLE, \
+        .period = 0,                     \
+        .threshold_low = 0,              \
+        .threshold_high = 0,             \
+        .it_pulse_count = 0,             \
+    }
+#endif
+#endif
+
+
+/*Variable definitions*/
+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

+

The above configuration can be modified through PWM_DEV(dev)->xxx, and can only be used before calling device_open.

+
+
+
+

2.4.4. PWM device interface

+

The PWM device interfaces all follow the interfaces provided by the standard device driver management layer. And in order to facilitate the user to call, some standard interfaces are redefined using macros.

+
+

2.4.4.1. pwm_register

+

pwm_register is used to register a channel of the PWM device standard driver interface. Before registering, you need to open the macro definition of a certain channel of the corresponding PWM device. For example, define BSP_USING_PWM_CH0 before you can use the PWM channel 0 device. After the registration is completed, other interfaces can be used. If no macro is defined, the PWM device cannot be used.

+
int pwm_register(enum pwm_index_type index, const char *name);
+
+
+
    +
  • index the index of the device to be registered

  • +
  • name name the registered device

  • +
+

index is used to select the configuration of a certain channel of the PWM device. An index corresponds to a channel configuration of a PWM device. For example, PWM_CH0_INDEX corresponds to the configuration of PWM channel 0, and index has the following optional types:

+
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
+};
+
+
+
+
+

2.4.4.2. device_open

+

device_open is used to open a channel of a pwm device,this funtion calls pwm_open actually.

+
int device_open(struct device *dev, uint16_t oflag);
+
+
+
    +
  • dev device handle

  • +
  • oflag open mode

  • +
  • return error code, 0 means opening is successful, others mean errors

  • +
+

oflag provides the following types

+
#define DEVICE_OFLAG_STREAM_TX  0x001 /* The device is turned on in polling sending mode */
+#define DEVICE_OFLAG_STREAM_RX  0x002 /* The device is turned on in polling receiving mode */
+#define DEVICE_OFLAG_INT_TX     0x004 /* The device is turned on in interrupt sending mode */
+#define DEVICE_OFLAG_INT_RX     0x008 /* The device is turned on in interrupt receiving mode */
+#define DEVICE_OFLAG_DMA_TX     0x010 /* The device is turned on in DMA transmission mode */
+#define DEVICE_OFLAG_DMA_RX     0x020 /* The device is turned on in DMA receiving mode */
+
+
+
+
+

2.4.4.3. device_close

+

device_close is used to close a channel of a pwm device.this funtion calls pwm_close actually.

+
int device_close(struct device *dev);
+
+
+
    +
  • dev device handle

  • +
  • return error code, 0 means closing is successful, others mean error

  • +
+
+
+

2.4.4.4. device_control

+

device_control is used to control and modify the parameters of the PWM device according to commands.This funtion calls pwm_control actually.

+
int device_control(struct device *dev, int cmd, void *args);
+
+
+
    +
  • dev device handle

  • +
  • cmd device control command

  • +
  • args control parameters

  • +
  • return different control commands return different meanings

  • +
+

In addition to standard control commands, PWM devices also have their own special control commands.

+
#define DEIVCE_CTRL_PWM_IT_PULSE_COUNT_CONFIG 0x10
+
+
+

args input is different depending on cmd, the list is as follows:

+ + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
table1

cmd

args

description

DEVICE_CTRL_RESUME

NULL

Enable the current PWM channel

DEVICE_CTRL_SUSPEND

NULL

Disable the current PWM channel

DEVICE_CTRL_PWM_FREQUENCE_CONFIG

uint32_t

Configure the current PWM channel period

DEVICE_CTRL_PWM_DUTYCYCLE_CONFIG

pwm_dutycycle_config_t

Configure the current PWM channel duty cycle

DEVICE_CTRL_PWM_IT_PULSE_COUNT_CONFIG

uint32_t

Configure the trigger PWM interrupt period value

+
+
+

2.4.4.5. device_set_callback

+

device_set_callback is used to register a PWM channel interrupt callback function.

+
int device_set_callback(struct device *dev, void (*callback)(struct device *dev, void *args, uint32_t size, uint32_t event));
+
+
+
    +
  • dev device handle

  • +
  • callback the interrupt callback function to be registered

    +
    +
      +
    • dev device handle

    • +
    • args unused

    • +
    • size unused

    • +
    • event interrupt event type

    • +
    +
    +
  • +
+

event type definition is as follows:

+
enum pwm_event_type
+{
+    PWM_EVENT_COMPLETE,
+};
+
+
+
+
+

2.4.4.6. pwm_channel_start

+

pwm_channel_start is used to start the PWM channel. It actually calls device_control, where cmd is DEVICE_CTRL_RESUME.

+
pwm_channel_start(dev)
+
+
+
    +
  • dev pwm channel handle that needs to be opened

  • +
+
+
+

2.4.4.7. pwm_channel_stop

+

pwm_channel_stop is used to close the PWM channel. It actually calls device_control, where cmd is DEVICE_CTRL_SUSPEND.

+
pwm_channel_stop(dev)
+
+
+
    +
  • dev pwm channel handle that needs to be closed

  • +
+
+
+

2.4.4.8. pwm_channel_update

+

pwm_channel_update is used to update the frequency and duty cycle of the PWM channel. The actual call is device_control, where cmd is DEVICE_CTRL_CONFIG.

+
pwm_channel_update(dev,cfg)
+
+
+
    +
  • dev pwm channel handle that needs to be updated

  • +
  • cfg pwm_config_t handle

  • +
+
+
+

2.4.4.9. pwm_it_pulse_count_update

+

pwm_it_pulse_count_update is used to update the count value of the PWM channel. The PWM interrupt needs to be enabled before it takes effect. When the PWM count reaches the set period count value, an interrupt will be generated. The actual call is device_control, where cmd is DEIVCE_CTRL_PWM_IT_PULSE_COUNT_CONFIG.

+
pwm_it_pulse_count_update(dev,count)
+
+
+
    +
  • dev pwm channel handle that needs to update the cycle count value

  • +
  • count cycle count value

  • +
+
+
+
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/api_reference/peripheral/api_spi.html b/docs/development_guide_en/build/html/api_reference/peripheral/api_spi.html new file mode 100644 index 00000000..bd40696c --- /dev/null +++ b/docs/development_guide_en/build/html/api_reference/peripheral/api_spi.html @@ -0,0 +1,626 @@ + + + + + + + + + + 2.7. SPI — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

2.7. SPI

+
+

2.7.1. Introduction

+

Serial Peripheral Interface Bus (SPI) is a synchronous serial communication interface specification for short-range communication. The full-duplex communication mode is used between devices, which is a master-slave mode of one master and one or more slaves, and requires at least 4 wires. In fact, 3 wires are also available (when transmitting in one direction), including SDI (data input), SDO (data output), SCLK (clock), CS (chip select). The SPI devices in the BL series MCU have the following characteristics:

+
    +
  • It can be used as both SPI master and SPI slave.

  • +
  • The transmit and receive channels each have a FIFO with a depth of 4 words

  • +
  • Both master and slave devices support 4 clock formats (CPOL, CPHA)

  • +
  • Both master and slave devices support 1/2/3/4 byte transmission mode

  • +
  • Flexible clock configuration, up to 40M clock

  • +
  • Configurable MSB/LSB priority transmission

  • +
  • Receive filter function

  • +
  • Timeout mechanism under slave device

  • +
  • Support polling, interrupt, DMA transfer

  • +
+
+
+

2.7.2. SPI Device Structure Definition

+
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 inherit the properties of the parent class

  • +
  • id SPI id, 0 means SPI0

  • +
  • clk SPI clock frequency

  • +
  • mode master mode or slave mode

  • +
  • direction transmission first mode

  • +
  • clk_polaraity clock polarity

  • +
  • clk_phase clock phase

  • +
  • datasize data transmission bit width

  • +
  • fifo_threshold fifo threshold, the maximum is 4

  • +
  • tx_dma additional send dma handle

  • +
  • rx_dma dditional receive dma handle

  • +
+

mode provides the following types

+
#define SPI_SLVAE_MODE                                0
+#define SPI_MASTER_MODE                               1
+
+
+

direction provides the following types

+
#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 provides the following types

+
#define SPI_POLARITY_LOW                              0
+#define SPI_POLARITY_HIGH                             1
+
+
+

clk_phase provides the following types

+
#define SPI_PHASE_1EDGE                               0
+#define SPI_PHASE_2EDGE                               1
+
+
+

datasize provides the following types

+
#define SPI_DATASIZE_8BIT                            0
+#define SPI_DATASIZE_16BIT                           1
+#define SPI_DATASIZE_24BIT                           2
+#define SPI_DATASIZE_32BIT                           3
+
+
+
+
+

2.7.3. SPI Device Parameter Configuration Table

+

Each SPI device has a parameter configuration macro, the macro definition is located in the peripheral_config.h file under the bsp/board/xxx directory, and the variable definition is located in hal_spi.c, so the user does not need to define variable. When the user opens the macro of the corresponding device, the configuration of the device will take effect. For example, open the macro BSP_USING_SPI0, SPI0_CONFIG will take effect, and the SPI0 device can be registered and used.

+
/*Parameter configuration macro*/
+#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
+
+/*Variable definition*/
+static spi_device_t spix_device[SPI_MAX_INDEX] =
+{
+#ifdef BSP_USING_SPI0
+    SPI0_CONFIG,
+#endif
+};
+
+
+
+

Note

+

The above configuration can be modified through SPI_DEV(dev)->xxx and can only be used before calling device_open.

+
+
+
+

2.7.4. SPI Device Interface

+

SPI device interface follows which provided by the standard device driver management layer.

+
+

2.7.4.1. spi_register

+

spi_register is used to register an SPI device standard driver interface. Before registering, you need to open the macro definition of the corresponding SPI device. For example, define the macro BSP_USING_SPI0 before you can use the SPI0 device. After the registration is completed, other interfaces can be used. If no macro is defined, the SPI device cannot be used.

+
int spi_register(enum spi_index_type index, const char *name);
+
+
+
    +
  • index device index to be registered

  • +
  • name device name to be registered

  • +
+

index is used to select SPI device configuration, one index corresponds to one SPI device configuration, for example, SPI0_INDEX corresponds to SPI0_CONFIG configuration, and index has the following optional types

+
enum spi_index_type
+{
+#ifdef BSP_USING_SPI0
+    SPI0_INDEX,
+#endif
+    SPI_MAX_INDEX
+};
+
+
+
+
+

2.7.4.2. device_open

+

device_open is used to open the device,this funtion calls spi_open actually.

+
int device_open(struct device *dev, uint16_t oflag);
+
+
+
    +
  • dev device handle

  • +
  • oflag open mode

  • +
  • return error code, 0 means opening is successful, others mean errors

  • +
+

oflag provides the following types

+
#define DEVICE_OFLAG_STREAM_TX  0x001 /* The device is turned on in polling sending mode */
+#define DEVICE_OFLAG_STREAM_RX  0x002 /* The device is turned on in polling receiving mode */
+#define DEVICE_OFLAG_INT_TX     0x004 /* The device is turned on in interrupt sending mode */
+#define DEVICE_OFLAG_INT_RX     0x008 /* The device is turned on in interrupt receiving mode */
+#define DEVICE_OFLAG_DMA_TX     0x010 /* The device is turned on in DMA transmission mode */
+#define DEVICE_OFLAG_DMA_RX     0x020 /* The device is turned on in DMA receiving mode */
+
+
+
+
+

2.7.4.3. device_close

+

device_close is used to close the device,this funtion calls spi_close actually.

+
int device_close(struct device *dev);
+
+
+
    +
  • dev device handle

  • +
  • return error code, 0 means closing is successful, others means error

  • +
+
+
+

2.7.4.4. device_control

+

device_control is used to control the device and modify parameters according to commands.This funtion calls spi_control actually.

+
int device_control(struct device *dev, int cmd, void *args);
+
+
+
    +
  • dev device handle

  • +
  • cmd device control command

  • +
  • args control parameters

  • +
  • return Different control commands return different meanings.

  • +
+

In addition to standard control commands, SPI devices also have their own special control commands.

+
#define DEVICE_CTRL_SPI_CONFIG_CLOCK       0x10
+
+
+

args input is different depending on cmd, the list is as follows:

+ + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
table1

cmd

args

description

DEVICE_CTRL_SET_INT

NULL

Enable spi device interrupt

DEVICE_CTRL_CLR_INT

NULL

Disable spi device interrupt

DEVICE_CTRL_RESUME

NULL

Resume spi device

DEVICE_CTRL_SUSPEND

NULL

Suspend spi device

DEVICE_CTRL_ATTACH_TX_DMA

NULL

Link to tx dma device

DEVICE_CTRL_ATTACH_RX_DMA

NULL

Link to rx dma device

DEVICE_CTRL_SPI_CONFIG_CLOCK

NULL

Modify SPI device clock

DEVICE_CTRL_TX_DMA_SUSPEND

NULL

Suspend spi tx dma mode

DEVICE_CTRL_RX_DMA_SUSPEND

NULL

Suspend spi rx dma mode

DEVICE_CTRL_TX_DMA_RESUME

NULL

Resume spi tx dma mode

DEVICE_CTRL_RX_DMA_RESUME

NULL

Resume spi rx dma mode

+
+
+

2.7.4.5. device_write

+

device_write is used to send data. The sending mode can be polling, interrupt, dma according to the open mode.This funtion calls spi_write actually.

+
int device_write(struct device *dev, uint32_t pos, const void *buffer, uint32_t size);
+
+
+
    +
  • dev device handle

  • +
  • pos useless

  • +
  • buffer the buffer to be written

  • +
  • size the length to be written

  • +
  • return error code, 0 means writing is successful, others mean errors

  • +
+
+
+

2.7.4.6. device_read

+

device_read is used to receive data, and the receiving mode can be polling, interrupt, dma according to the open mode.This funtion calls spi_read actually.

+
int device_read(struct device *dev, uint32_t pos, void *buffer, uint32_t size);
+
+
+
    +
  • dev device handle

  • +
  • pos useless

  • +
  • buffer the buffer to be read

  • +
  • size the length to be read

  • +
  • return error code, 0 means successful reading, others mean errors

  • +
+
+
+

2.7.4.7. device_set_callback

+

device_set_callback is used to register an SPI device interrupt callback function.

+
int device_set_callback(struct device *dev, void (*callback)(struct device *dev, void *args, uint32_t size, uint32_t event));
+
+
+
    +
  • dev device handle

  • +
  • callback the interrupt callback function to be registered

    +
    +
      +
    • dev device handle

    • +
    • args receive and send buffer, the data type is uint8_t*

    • +
    • size transmission length

    • +
    • event interrupt event type

    • +
    +
    +
  • +
+

event type definition is as follows:

+
enum spi_event_type
+{
+    SPI_EVENT_TX_FIFO,
+    SPI_EVENT_RX_FIFO,
+    SPI_EVENT_UNKNOWN
+};
+
+
+
+
+

2.7.4.8. spi_transmit

+

spi_transmit is used to send data from SPI devices.

+
int spi_transmit(struct device *dev, void *buffer, uint32_t size, uint8_t type);
+
+
+
    +
  • dev device handle

  • +
  • buffer send data buffer

  • +
  • size send length

  • +
  • type send bit width type

  • +
+

type provides the following types

+
#define SPI_TRANSFER_TYPE_8BIT    0
+#define SPI_TRANSFER_TYPE_16BIT   1
+#define SPI_TRANSFER_TPYE_24BIT   2
+#define SPI_TRANSFER_TYPE_32BIT   3
+
+
+
+
+

2.7.4.9. spi_receive

+

spi_receive is used to receive data from SPI devices.

+
int spi_receive(struct device *dev, void *buffer, uint32_t size, uint8_t type);
+
+
+
    +
  • dev device handle

  • +
  • buffer receive data buffer

  • +
  • size receiving length

  • +
  • type bit width type

  • +
+
+
+

2.7.4.10. spi_transmit_receive

+

spi_transmit_receive is used to send and receive data from SPI devices.

+
int spi_transmit_receive(struct device *dev, const void *send_buf, void *recv_buf, uint32_t length, uint8_t type);
+
+
+
    +
  • dev device handle

  • +
  • send_buf send data buffer

  • +
  • recv_buf receive data buffer

  • +
  • length send and receive length

  • +
  • type bit width type

  • +
+
+
+
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/api_reference/peripheral/api_timer.html b/docs/development_guide_en/build/html/api_reference/peripheral/api_timer.html new file mode 100644 index 00000000..97778cf9 --- /dev/null +++ b/docs/development_guide_en/build/html/api_reference/peripheral/api_timer.html @@ -0,0 +1,548 @@ + + + + + + + + + + 2.10. TIMER — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

2.10. TIMER

+
+

2.10.1. Introduction

+

The TIMER device in BL series MCU has the following characteristics:

+
    +
  • Multiple clock source options

  • +
  • 8-bit clock divider, the division factor is 1-256

  • +
  • Two 32-bit timers

  • +
  • Each timer can independently set three groups of alarm values

  • +
  • Support FreeRun mode and PreLoad mode

  • +
  • 16-bit watchdog

  • +
  • Support write protection to prevent system abnormalities caused by incorrect settings

  • +
  • Support two watchdog overflow modes, interrupt or reset

  • +
+
+
+

2.10.2. TIMER Device Structure Definition

+
typedef struct timer_device {
+    struct device parent;
+    uint8_t id;
+    enum timer_cnt_mode_type cnt_mode;
+    enum timer_preload_trigger_type trigger;
+    uint32_t reload;
+    uint32_t timeout1;
+    uint32_t timeout2;
+    uint32_t timeout3;
+} timer_device_t;
+
+
+
    +
  • parent inherit the properties of the parent class

  • +
  • id timer id

  • +
  • cnt_mode counting mode:FreeRun and preload

  • +
  • trigger source of preload comparator

  • +
  • reload reload value in preload mode

  • +
  • timeout1 compare source 0 timout value ,unit is us

  • +
  • timeout2 compare source 1 timout value ,unit is us

  • +
  • timeout3 compare source 2 timout value ,unit is us

  • +
+

ch provides the following types

+
enum timer_index_type {
+    TIMER0_INDEX,
+    TIMER1_INDEX,
+    TIMER_MAX_INDEX
+};
+
+
+

cnt_mode provides the following types

+
enum timer_cnt_mode_type {
+    TIMER_CNT_PRELOAD,
+    TIMER_CNT_FREERUN,
+};
+
+
+

pl_trig_src provides the following types

+
enum timer_preload_trigger_type {
+    TIMER_PRELOAD_TRIGGER_NONE,
+    TIMER_PRELOAD_TRIGGER_COMP0,
+    TIMER_PRELOAD_TRIGGER_COMP1,
+    TIMER_PRELOAD_TRIGGER_COMP2,
+};
+
+
+
+
+

2.10.3. TIMER Device Parameter Configuration Table

+

Each TIMER has a parameter configuration macro, the macro definition is located in the peripheral_config.h file under the bsp/board/xxx directory, and the variable definition is located in hal_timer.c, so the user does not need to define the variable . When the user opens the macro of the corresponding device, the configuration of the device will take effect. For example, open the macro BSP_USING_TIMER_CH0, TIMER_CH0_CONFIG will take effect, and the TIMER_CH0_INDEX device can be registered and used.

+
/*Parameter configuration macro*/
+#if defined(BSP_USING_TIMER0)
+#ifndef TIMER0_CONFIG
+#define TIMER0_CONFIG                           \
+    {                                           \
+        .id = 0,                                \
+        .cnt_mode = TIMER_CNT_PRELOAD,          \
+        .trigger = TIMER_PRELOAD_TRIGGER_COMP2, \
+        .reload = 0,                            \
+        .timeout1 = 1000000,                    \
+        .timeout2 = 2000000,                    \
+        .timeout3 = 3000000,                    \
+    }
+#endif
+#endif
+
+#if defined(BSP_USING_TIMER1)
+#ifndef TIMER1_CONFIG
+#define TIMER1_CONFIG                           \
+    {                                           \
+        .id = 1,                                \
+        .cnt_mode = TIMER_CNT_PRELOAD,          \
+        .trigger = TIMER_PRELOAD_TRIGGER_COMP0, \
+        .reload = 0,                            \
+        .timeout1 = 1000000,                    \
+        .timeout2 = 2000000,                    \
+        .timeout3 = 3000000,                    \
+    }
+#endif
+#endif
+
+/*Variable definitions*/
+static timer_device_t timerx_device[TIMER_MAX_INDEX] = {
+#ifdef BSP_USING_TIMER0
+    TIMER0_CONFIG,
+#endif
+#ifdef BSP_USING_TIMER1
+    TIMER1_CONFIG,
+#endif
+};
+
+
+
+

Note

+

The above configuration can be modified through TIMER_DEV(dev)->xxx and can only be used before calling device_open.

+
+
+
+

2.10.4. TIMER Device Interface

+

TIMER device interface follows which provided by the standard device driver management layer.

+
+

2.10.4.1. timer_register

+

timer_register is used to register a TIMER device standard driver interface. Before registering, you need to open the macro definition of the corresponding TIMER device. For example, define the macro BSP_USING_TIMER_CH0 to use the TIMER_CH0_INDEX device. After the registration is completed, other interfaces can be used. If the macro is not defined, the TIMER_CH0_INDEX device cannot be used.

+
int timer_register(enum timer_index_type index, const char *name);
+
+
+
    +
  • index the index of the device to be registered

  • +
  • name Name the device

  • +
+

index is used to select TIMER device configuration, one index corresponds to a TIMER device configuration, for example, TIMER_CH0_INDEX corresponds to TIMER_CH0_CONFIG configuration, and index has the following optional types

+
enum timer_index_type {
+#ifdef BSP_USING_TIMER0
+    TIMER0_INDEX,
+#endif
+#ifdef BSP_USING_TIMER1
+    TIMER1_INDEX,
+#endif
+    TIMER_MAX_INDEX
+};
+
+
+
+
+

2.10.4.2. device_open

+

device_open is used to open a TIMER device, this funtion calls timer_open actually.

+
int device_open(struct device *dev, uint16_t oflag);
+
+
+
    +
  • dev device handle

  • +
  • oflag open method

  • +
  • return error code, 0 means opening is successful, others mean error

  • +
+

oflag provides the following types

+
#define DEVICE_OFLAG_STREAM_TX  0x001 /* The device is turned on in polling sending mode */
+#define DEVICE_OFLAG_STREAM_RX  0x002 /* The device is turned on in polling receiving mode */
+#define DEVICE_OFLAG_INT_TX     0x004 /* The device is turned on in interrupt sending mode */
+#define DEVICE_OFLAG_INT_RX     0x008 /* The device is turned on in interrupt receiving mode */
+#define DEVICE_OFLAG_DMA_TX     0x010 /* The device is turned on in DMA transmission mode */
+#define DEVICE_OFLAG_DMA_RX     0x020 /* The device is turned on in DMA receiving mode */
+
+
+
+
+

2.10.4.3. device_close

+

device_close is used to close a TIMER device,this funtion calls timer_open actually.

+
int device_close(struct device *dev);
+
+
+
    +
  • dev device handle

  • +
  • return error code, 0 means closing is successful, others mean error

  • +
+
+
+

2.10.4.4. device_control

+

device_control is used to control and modify the parameters of the TIMER device according to commands.This funtion calls timer_control actually.

+
int device_control(struct device *dev, int cmd, void *args);
+
+
+
    +
  • dev device handle

  • +
  • cmd device control command

  • +
  • args control parameters

  • +
  • return different control commands return different meanings

  • +
+

In addition to standard control commands, TIMER device also has its own special control commands.

+
#define DEVICE_CTRL_TIMER_CH_START   0x80
+#define DEVICE_CTRL_TIMER_CH_STOP    0x81
+#define DEVICE_CTRL_GET_MATCH_STATUS 0x82
+
+
+

args input is different depending on cmd, the list is as follows:

+ + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
table1

cmd

args

description

DEVICE_CTRL_SET_INT

timer_it_type

Enable TIMER interrupt

DEVICE_CTRL_CLR_INT

timer_it_type

Disable TIMER interrupt

DEVICE_CTRL_GET_INT

NULL

Get TIMER interrupt status

DEVICE_CTRL_RESUME

NULL

Enable TIMER

DEVICE_CTRL_SUSPEND

NULL

Disable TIMER

DEVICE_CTRL_GET_CONFIG

NULL

Get TIMER current count

+
+
+

2.10.4.5. device_write

+

device_write is used to config timer device timeout value.This funtion calls timer_write actually.

+
int device_write(struct device *dev, uint32_t pos, const void *buffer, uint32_t size);
+
+
+
    +
  • dev device handle

  • +
  • pos unused

  • +
  • buffer timer_timeout_cfg_t handle

  • +
  • size the length of timer_timeout_cfg_t

  • +
  • return error code, 0 means writing is successful, others mean errors

  • +
+
+
+

2.10.4.6. device_set_callback

+

device_set_callback is used to register a timer compare interrupt callback function.

+
int device_set_callback(struct device *dev, void (*callback)(struct device *dev, void *args, uint32_t size, uint32_t event));
+
+
+
    +
  • dev device handle

  • +
  • callback the interrupt callback function to be registered

    +
    +
      +
    • dev device handle

    • +
    • args unused

    • +
    • size unused

    • +
    • event interrupt event type

    • +
    +
    +
  • +
+

event type definition is as follows:

+
enum timer_event_type {
+    TIMER_EVENT_COMP0,
+    TIMER_EVENT_COMP1,
+    TIMER_EVENT_COMP2,
+    TIMER_EVENT_UNKNOWN
+};
+
+
+
+
+
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/api_reference/peripheral/api_uart.html b/docs/development_guide_en/build/html/api_reference/peripheral/api_uart.html new file mode 100644 index 00000000..2fcd458b --- /dev/null +++ b/docs/development_guide_en/build/html/api_reference/peripheral/api_uart.html @@ -0,0 +1,579 @@ + + + + + + + + + + 2.3. UART — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

2.3. UART

+
+

2.3.1. Introduction

+

UART is a universal asynchronous transmitter-receiver, which provides a flexible way for full-duplex data exchange with external devices. The UART device in BL series MCU has the following characteristics:

+
    +
  • Data bit length can choose 5/6/7/8 bits

  • +
  • Stop bit length can be selected 0.5/1/1.5/2 bits

  • +
  • Support odd/even/no parity bit

  • +
  • Support hardware flow control (RTS/CTS)

  • +
  • Automatic baud rate detection

  • +
  • Support LIN protocol (transceive BREAK/SYNC)

  • +
  • Send/receive FIFO

  • +
  • Support polling, interrupt, DMA transfer

  • +
  • Unique rto interrupt

  • +
+
+
+

2.3.2. UART Device Structure Definition

+
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 inherit the properties of the parent class

  • +
  • id serial port id, if serial port 0 is enabled, id is 0, if serial port 1 is enabled, id is 1, and so on

  • +
  • baudrate baud rate

  • +
  • databits data bits

  • +
  • stopbits stop bits

  • +
  • parity parity

  • +
  • fifo_threshold fifo threshold, the maximum value of different mcu is different

  • +
  • tx_dma additional send dma handle

  • +
  • rx_dma additional receive dma handle

  • +
+

databits provides the following types

+
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 provides the following types

+
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 provides the following types

+
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;
+
+
+
+
+

2.3.3. UART Device Parameter Configuration Table

+

Each UART device has a parameter configuration macro, the macro definition is located in the peripheral_config.h file under the bsp/board/xxx directory, and the variable definition is located in hal_uart.c, so the user does not need to define variable. When the user opens the macro of the corresponding device, the configuration of the device will take effect. For example, open the macro BSP_USING_UART0, UART0_CONFIG will take effect, and the UART0 device can be registered and used.

+
/*Parameter configuration macro*/
+#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
+
+/*Variable definitions*/
+static uart_device_t uartx_device[UART_MAX_INDEX] =
+{
+#ifdef BSP_USING_UART0
+        UART0_CONFIG,
+#endif
+#ifdef BSP_USING_UART1
+        UART1_CONFIG,
+#endif
+};
+
+
+
+

Note

+

The above configuration can be modified through UART_DEV(dev)->xxx and can only be used before calling device_open.

+
+
+
+

2.3.4. UART Device Interface

+

UART device interface follows which provided by the standard device driver management layer.

+
+

2.3.4.1. uart_register

+

uart_register is used to register a UART device standard driver interface. Before registering, you need to open the macro definition of the corresponding UART device. For example, define the macro BSP_USING_UART0 to use the UART0 device. After the registration is completed, other interfaces can be used. If the macro is not defined, the UART0 device cannot be used.

+
int uart_register(enum uart_index_type index, const char *name);
+
+
+
    +
  • index the index of the device to be registered

  • +
  • name device name

  • +
+

index is used to select UART device configuration, one index corresponds to a UART device configuration, such as UART0_INDEX corresponds to UART0_CONFIG configuration, index has the following optional types

+
enum uart_index_type
+{
+#ifdef BSP_USING_UART0
+    UART0_INDEX,
+#endif
+#ifdef BSP_USING_UART1
+    UART1_INDEX,
+#endif
+    UART_MAX_INDEX
+};
+
+
+
+
+

2.3.4.2. device_open

+

device_open is used to open a UART device, this funtion calls uart_open actually.

+
int device_open(struct device *dev, uint16_t oflag);
+
+
+
    +
  • dev device handle

  • +
  • oflag open mode

  • +
  • return error code, 0 means opening is successful, others mean errors

  • +
+

oflag provides the following types

+
#define DEVICE_OFLAG_STREAM_TX  0x001 /* The device is turned on in polling sending mode */
+#define DEVICE_OFLAG_STREAM_RX  0x002 /* The device is turned on in rotation receiving mode */
+#define DEVICE_OFLAG_INT_TX     0x004 /* The device is turned on in interrupt sending mode */
+#define DEVICE_OFLAG_INT_RX     0x008 /* The device is turned on in interrupt receiving mode */
+#define DEVICE_OFLAG_DMA_TX     0x010 /* The device is turned on in DMA transmission mode */
+#define DEVICE_OFLAG_DMA_RX     0x020 /* The device is turned on in DMA receiving mode */
+
+
+
+
+

2.3.4.3. device_close

+

device_close is used to close a UART device,this funtion calls uart_close actually.

+
int device_close(struct device *dev);
+
+
+
    +
  • dev device handle

  • +
  • return error code, 0 means closing is successful, others mean error

  • +
+
+
+

2.3.4.4. device_control

+

device_control is used to control and modify the parameters of the UART device according to commands.This funtion calls uart_control actually.

+
int device_control(struct device *dev, int cmd, void *args);
+
+
+
    +
  • dev device handle

  • +
  • cmd device control command

  • +
  • args control parameters

  • +
  • return different control commands return different meanings.

  • +
+

In addition to standard control commands, UART device also has its own special control commands.

+
#define DEVICE_CTRL_UART_GET_TX_FIFO        0x10
+#define DEVICE_CTRL_UART_GET_RX_FIFO        0x11
+
+
+

args input is different depending on cmd, the list is as follows:

+ + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
table1

cmd

args

description

DEVICE_CTRL_SET_INT

uart_it_type

Enable uart device interrupt

DEVICE_CTRL_CLR_INT

uart_it_type

Disable uart device interrupt

DEVICE_CTRL_CONFIG

uart_param_cfg_t*

Modify the serial port configuration

DEVICE_CTRL_ATTACH_TX_DMA

NULL

Link to tx dma device

DEVICE_CTRL_ATTACH_RX_DMA

NULL

Link to rx dma device

DEVICE_CTRL_TX_DMA_SUSPEND

NULL

Suspend uart tx dma mode

DEVICE_CTRL_RX_DMA_SUSPEND

NULL

Suspend uart rx dma mode

DEVICE_CTRL_TX_DMA_RESUME

NULL

Resume uart tx dma mode

DEVICE_CTRL_RX_DMA_RESUME

NULL

Resume uart rx dma mode

DEVICE_CTRL_UART_GET_TX_FIFO

uint32_t*

Get the number of uart tx fifo

DEVICE_CTRL_UART_GET_RX_FIFO

uint32_t*

Get the number of uart rx fifo

+
+
+

2.3.4.5. device_write

+

device_write is used to send data. The sending mode can be polling, interrupt, dma according to the open mode.This funtion calls uart_write actually.

+
int device_write(struct device *dev, uint32_t pos, const void *buffer, uint32_t size);
+
+
+
    +
  • dev device handle

  • +
  • pos useless

  • +
  • buffer the buffer to be written

  • +
  • size the length to be written

  • +
  • return error code, 0 means writing is successful, others mean errors

  • +
+
+
+

2.3.4.6. device_read

+

device_read is used to receive data. The receiving mode can be polling, interrupt, dma according to the open mode.This funtion calls uart_read actually.

+
int device_read(struct device *dev, uint32_t pos, void *buffer, uint32_t size);
+
+
+
    +
  • dev device handle

  • +
  • pos useless

  • +
  • buffer the buffer to be read

  • +
  • size the length to be read

  • +
  • return error code, 0 means successful reading, others mean errors

  • +
+
+
+

2.3.4.7. device_set_callback

+

device_set_callback is used to register a uart interrupt callback function.

+
int device_set_callback(struct device *dev, void (*callback)(struct device *dev, void *args, uint32_t size, uint32_t event));
+
+
+
    +
  • dev device handle

  • +
  • callback the interrupt callback function to be registered

    +
    +
      +
    • dev device handle

    • +
    • args receive and send buffer, the data type is uint8_t*

    • +
    • size transmission length

    • +
    • event interrupt event type

    • +
    +
    +
  • +
+

event type definition is as follows:

+
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
+};
+
+
+
+
+
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/api_reference/peripheral/index.html b/docs/development_guide_en/build/html/api_reference/peripheral/index.html new file mode 100644 index 00000000..33815657 --- /dev/null +++ b/docs/development_guide_en/build/html/api_reference/peripheral/index.html @@ -0,0 +1,271 @@ + + + + + + + + + + 2. Peripheral — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+ + +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/genindex.html b/docs/development_guide_en/build/html/genindex.html new file mode 100644 index 00000000..6dfea318 --- /dev/null +++ b/docs/development_guide_en/build/html/genindex.html @@ -0,0 +1,240 @@ + + + + + + + + + + Index — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
    + +
  • »
  • + +
  • Index
  • + + +
  • + + + +
  • + +
+ + +
+
+
+
+ + +

Index

+ +
+ +
+ + +
+ +
+
+ +
+ +
+

+ © Copyright 2021, BouffaloLab Co., Ltd. + +

+
+ + + + Built with Sphinx using a + + theme + + provided by Read the Docs. + +
+
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/get_started/Linux_quick_start_ubuntu.html b/docs/development_guide_en/build/html/get_started/Linux_quick_start_ubuntu.html new file mode 100644 index 00000000..9db61347 --- /dev/null +++ b/docs/development_guide_en/build/html/get_started/Linux_quick_start_ubuntu.html @@ -0,0 +1,415 @@ + + + + + + + + + + 3.3. Linux OR WSL environment development guide — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

3.3. Linux OR WSL environment development guide

+

This document introduces how to install and configure the software development tools needed for BL702 series MCUs in Linux. The installation and configuration method under WSL system is the same as under linux, please install WSL system by yourself. The difference is that one runs on a pure linux system and the other runs on windows. If you don’t want to install a virtual machine or a linux system, you can choose WSL.

+

Windows Subsystem for Linux (WSL) is a compatibility layer that can run native Linux binary executable files (ELF format) on Windows 10. It was developed by Microsoft and Canonical in cooperation. Its goal is to enable the pure Ubuntu image to be downloaded and decompressed to the user’s local computer, and the tools in the image can run on this subsystem. Therefore, the operation mode under WSL is exactly the same as the operation mode under linux.

+
+

3.3.1. Software and hardware environment

+
    +
  • A mini USB data cable

  • +
  • A USB-TTL serial port module

  • +
  • Several Dupont lines

  • +
+
+
+

3.3.2. Configure RISC-V toolchain

+
1
+2
+3
+4
+5
+6
+7
$ 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 -rf ~/riscv64-elf-20210120  /usr/bin
+$ echo "export PATH=\"$PATH:/usr/bin/riscv64-elf-20210120/bin\""  >> ~/.bashrc
+$ source ~/.bashrc
+
+
+
+
+

3.3.3. Configure cmake & make tools

+
1
+2
+3
+4
+5
+6
+7
+8
$ 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 -rf ~/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
+
+
+
+
+

3.3.4. Hardware connection

+
    +
  • For the connection of the board, please refer to Hardware connection

  • +
  • Please make sure that the board is set correctly before proceeding to the following steps (Serial connection is recommended under Linux)

  • +
+
+
+

3.3.5. Get bl_mcu_sdk

+
    +
  • Open the terminal and enter the following command to get bl_mcu_sdk

  • +
+
1
+2
 $ cd ~
+ $ git clone https://gitee.com/bouffalolab/bl_mcu_sdk.git  --recursive
+
+
+
+
+

3.3.6. Test Hello World project

+
+

Open Hello World

+
    +
  • After obtaining the SDK, enter examples/hellowd/helloworld in the SDK, open main.c, and then edit the related code of helloworld.

  • +
+
1
+2
 $ cd ~/bl_mcu_sdk/examples/hellowd/helloworld
+ $ vi main.c
+
+
+
    +
  • After editing, save the changes and close the file, and then compile

  • +
+
+
+

Compile Hello World

+
1
+2
 $ cd ~/bl_mcu_sdk
+ $ make build BOARD=bl706_iot APP=helloworld
+
+
+
+
+

Program Hello World

+
    +
  • Please confirm the programming method first. If you use serial programming, please press and hold the boot key on the board and don’t release it. At this time, press the rst key, and then release the two keys. The board enters the boot_rom state.

  • +
  • At this time, enter the following command in the terminal to program

  • +
+
1
+2
 $ cd ~/bl_mcu_sdk
+ $ make download INTERFACE=uart COMx=/dev/ttyUSB1
+
+
+
    +
  • If the download fails, please check:

    +
    +
      +
      1. +
      2. Whether the serial port is used for programming, whether the development board is powered, and whether the hardware connection is correct.

      3. +
      +
    • +
      1. +
      2. Is the programming command executed in the bl_mcu_sdk directory

      3. +
      +
    • +
      1. +
      2. Whether to enter boot_rom mode

      3. +
      +
    • +
      1. +
      2. Whether the serial port is occupied, and whether your available serial port is selected correctly, if your serial port is not ttyUSB1, then please specify the correct serial port

      3. +
      +
    • +
    +
    +
  • +
+
+
+

Run Hello World

+
    +
  • Open a new terminal, install and run the serial port tool

  • +
+
1
+2
 $ sudo apt install picocom   # Ignore if it is already installed
+ $ picocom -b 2000000 /dev/ttyUSB1 # Pay attention to your available serial port number (if you use the serial port of Sipeed RV-debugger Plus, it will be ``ttyUSB1``)
+
+
+
    +
  • Press the rst key on the board, you can see hello world! in the serial terminal.

  • +
+
+ +

helloworld!

+
+
+
+

Debug Hello World

+
+
+
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/get_started/Windows_quick_start_cdk.html b/docs/development_guide_en/build/html/get_started/Windows_quick_start_cdk.html new file mode 100644 index 00000000..670899da --- /dev/null +++ b/docs/development_guide_en/build/html/get_started/Windows_quick_start_cdk.html @@ -0,0 +1,320 @@ + + + + + + + + + + 3.1. Guide to using CDK (like MDK Keil) under Windows — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

3.1. Guide to using CDK (like MDK Keil) under Windows

+

This document introduces the use of the CDK developed by T-HEAD Semiconductor under Windows to complete the related software development of BL702 series MCU.

+

Regarding T-HEAD CDK, this is an integrated development environment developed by T-HEAD. It has operations and settings that are very similar to the traditional MCU development environment, and aims to fully access cloud development resources without changing user development habits, combined with graphical debugging and analysis tools such as OSTracer and Profiling, to accelerate user product development.

+
+

3.1.1. Software and hardware environment

+
    +
  • T-HEAD CDK software

  • +
  • One USB Type-A data cable, one Type-C data cable

  • +
  • A CK-Link emulator or a Sipeed RV-Debugger Plus debugger

  • +
  • A USB-TTL serial port module

  • +
  • Several Dupont lines

  • +
+
+
+

3.1.2. Download CDK

+
    +
  • CDK software can be obtained from the official website of T-HEAD OCC

  • +
  • After the download is complete, unzip, double-click setup.exe, follow the prompts, and complete the software installation

  • +
+
+
+

3.1.3. Download bl_mcu_sdk

+
    +
  • Download bl_mcu_sdk from the open source community.

    +
    +
      +
    • You can use git clone or directly download to download the SDK

    • +
    • Before using git clone, please make sure that git has been installed correctly, open a terminal that supports git and enter the following command to get the latest SDK

    • +
    +
    1
    $ git clone https://gitee.com/bouffalolab/bl_mcu_sdk.git  --recursive
    +
    +
    +
    +
  • +
+
+
+

3.1.4. Hardware connection

+
    +
  • For specific connection methods, please refer to Hardware connection

  • +
  • Please make sure that the board is set up correctly before proceeding to the following steps

  • +
+
+
+

3.1.5. Test the Hello World project

+

When using Sipeed RV-Debugger Plus to debug a project, please follow the steps below:

+ +

When using CK-Link to debug the project, please follow the steps below:

+
+ +
+
+
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/get_started/Windows_quick_start_eclipse.html b/docs/development_guide_en/build/html/get_started/Windows_quick_start_eclipse.html new file mode 100644 index 00000000..6eb72550 --- /dev/null +++ b/docs/development_guide_en/build/html/get_started/Windows_quick_start_eclipse.html @@ -0,0 +1,456 @@ + + + + + + + + + + 3.2. Eclipse Development Guide under Windows — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

3.2. Eclipse Development Guide under Windows

+

This document introduces the use of eclipse under Windows to build a software development environment for BL702 series MCU.

+
+

3.2.1. Software and hardware environment

+
    +
  • Eclipse free installation package

  • +
  • Serial port assistant software

  • +
  • A USB Type-A data cable

  • +
  • A j-link emulator

  • +
  • A USB-TTL serial port module

  • +
  • Several Dupont lines

  • +
+
+
+

3.2.2. Download Eclipse

+ +
+
+

3.2.3. Download bl_mcu_sdk

+
    +
  • Download from the open source community bl_mcu_sdk.

  • +
  • You can use git clone or directly download to download the SDK

  • +
  • Before using git clone, please make sure that git has been installed correctly. Open a terminal that supports git and enter the following command to get the latest SDK.

  • +
+
1
$ git clone https://gitee.com/bouffalolab/bl_mcu_sdk.git  --recursive
+
+
+
+
+

3.2.4. Configure eclipse

+
    +
  • Copy the eclipse compressed package to the working directory, unzip the eclipse compressed package

  • +
  • Enter the eclipse directory, double-click eclipse.exe to start eclipse

  • +
  • Select your Workspace directory, click Launch to enter the workspace

    +
    +
    + +
    +
    +
  • +
  • Click Window->preferences in the menu bar to open the environment configuration related page, ready to import the related configuration environment

    +
    +
    + +
    +
    +
  • +
  • +
    Click the icon at “1” in the figure below to open the import configuration interface, follow the steps shown in the figure, and select the bflb_mcu_preferences.epf configuration file in the eclipse.exe directory.
    + +
    +
    +
    +
  • +
  • After selecting the corresponding file, click Finish, select and click cancel in the dialog box without restarting.

    +
    +
    + +
    +
    +
  • +
+
+
+

3.2.5. Import bl_mcu_sdk

+
    +
  • Click on the menu bar File->Import to open the configuration interface of the imported project

    +
    +
    + +
    +
    +
  • +
  • In the opened Import window, select General->Existing Projects into Workspace, and then click Next

    +
    +
    + +
    +
    +
  • +
  • After loading the project path of bl_mcu_sdk, click Finsh to complete the import

    +
    +
    + +
    +
    +
  • +
  • After the import is complete, close the Welcome window to see the imported project

    +
    +
    + +
    +
    + +
    +
    +
  • +
  • Expand Build Target, you can see the three function buttons bl_clean, bl_make, and download.

    +
    +
      +
    • Double-click the bl_clean button, it will clear the compilation cache in the build and out directories

    • +
    • Double-click the bl_make button, the set case will be compiled normally, if the default configuration is not modified, the helloworld project will be compiled

    • +
    • Double-click the download button, the code will be downloaded to the chip, if it is not compiled successfully, the default or last .bin file will be downloaded

    • +
    +
    +
  • +
+
+
+

3.2.6. Hardware connection

+
    +
  • For specific board connection, please refer to Hardware connection; (The eclipse environment recommends using j-link for programming and debugging)

  • +
  • Please make sure that the development board is set up correctly before proceeding to the following steps

  • +
+
+
+

3.2.7. Test the Hello World project

+
+

Open Hello World

+
    +
  • Open examples/hellowd/helloworld/main.c, you can edit and modify the code of the helloworld test demo. If you modify it, please save it and execute the compilation

  • +
+
+
+

Compile Hello World

+
    +
  • Double click bl_make to compile the helloworld project

  • +
  • After successful compilation, you can see the log information as shown in the figure below in the Console window

  • +
+
+../_images/pic10.png +
+
+
+

Program Hello World

+
    +
  • Double-click download to program the helloworld project bin file to the chip

  • +
  • After the download is successful, you can see the log information as shown in the figure below in the Console window

  • +
+
+../_images/pic11.png +
+
+
+

Run Hello World

+
    +
  • Connect the TXD0, RXD0 and GND pins of the board to the USB-TTL serial port module with a DuPont cable, insert the serial port module into the PC, and use any serial port assistant software to open the serial port

  • +
  • After the programming is successful, press the rst button on the board. If the download is correct, you can see the log information as shown in the figure below in the serial port assistant software.

  • +
+
+../_images/eclipse_run.png +
+
+
+

Debug Hello World

+
    +
  • Click the Debug button in the eclipse toolbar to enter the debug configuration window

  • +
  • Select GDB SEGGER J-Link Debugging->Jlink_bl_mcu_sdk, select the .elf file that needs to be debugged in C/C++ Application:

  • +
  • Click Apply first, then click Debug to start Debug

  • +
+
+ +
+
    +
  • After entering the Debug interface, you can see that the program stops at main, click the Step Over button in the upper toolbar to perform single-step debugging of the code project.

  • +
+
+ +

Eclipse Debugging

+
+
+
+
+

3.2.8. Compile and program different target projects

+
    +
  • When you right-click the bl_make button and click Edit, the configuration interface for replacing the target project will pop up, as shown in the figure below

  • +
+
+ +
+
    +
  • Where APP=xxx can be changed to the name of the target project that needs to be compiled and programmed. For example, if you want to compile and program the gpio/gpio_blink project, modify it to APP=gpio_blink.

  • +
  • make BOARD=bl706_iot in Build command will specify different Board types to adapt to different types of boards.

  • +
  • The Board type determines the corresponding borad header file when compiling. The default selection is make build BOARD=bl706_iot

  • +
+
+
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/get_started/bl_dev_cube.html b/docs/development_guide_en/build/html/get_started/bl_dev_cube.html new file mode 100644 index 00000000..a578e30e --- /dev/null +++ b/docs/development_guide_en/build/html/get_started/bl_dev_cube.html @@ -0,0 +1,377 @@ + + + + + + + + + + 6. BLDevCube start guide — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

6. BLDevCube start guide

+

This document mainly introduces the use of Bouffalo Lab Dev Cube for code programming. For more details, please refer to BLDevCube user manual

+
+

6.1. Download Bouffalo Lab Dev Cube

+
    +
  • Download the version suitable for your operating system from the developer community, download address:https://dev.bouffalolab.com/download

    +
      +
    • For users who do not have a registered account, click on the guest portal

    • +
    +
  • +
  • After the download is complete, you can use it after decompression

  • +
+
+
+

6.2. Configure tool download method

+
    +
  • Double-click BLDevCube.exe, in the Chip Type drop-down box, select the corresponding chip model, click Finish to enter the Dev Cube interface

  • +
  • Enter the interface, select MCU under View in the menu bar to enter the MCU program download interface

  • +
+
+ +

select mcu

+
+
    +
  • Select the corresponding download method in the Interface column under Image, and choose according to your actual physical connection

  • +
  • Image file configure the absolute path of the downloaded image, click Browse to select the Bin file

  • +
  • When you click click here to show advanced options, the advanced mirroring configuration will be expanded, usually keep the default configuration; it should be noted that Flash Clock will affect the clock frequency of Flash and PSRAM at the same time , If you need to use PSRAM, you can increase the clock frequency to get better performance

  • +
+
+

6.2.1. Download with UART

+
    +
  • COM Port is used for UART download, select the COM number connected to the chip, and click Refresh to refresh the COM number

  • +
  • When Uart Speed is used for UART download, configure the appropriate baud rate, the default is 2M

  • +
  • Please make sure the hardware configuration is correct before downloading:

    +
      +
    • Use Type-C USB or Mini USB to connect to the corresponding USB Type-C port or Mini port on the board.

    • +
    • Press the Boot key on the board, don’t release it

    • +
    • Press the RST key on the board, now you have entered Boot ROM model, you can release the two keys

    • +
    • At this time, you can see the corresponding serial port COM number from the Bouffalo Lab Dev Cube, if it does not appear, please click the Refresh button to refresh

    • +
    +
  • +
  • After completing the above configuration correctly, click the Create&Program button to download

  • +
  • After the download is successful, you will see the status bar turn green and display Success

  • +
+
+ +

download success!

+
+
+
+

6.2.2. Download with Openocd

+
    +
  • Download using openocd is basically the same as using serial port download option configuration, just switch Interface to Openocd

  • +
  • The hardware connection needs to be changed to a debugger connection that supports Openocd (this tutorial takes Sipeed RV Debugger as an example):

    +
    +
      +
      1. +
      2. Connect the RV debugger to the USB port of the computer, open the device manager, you will find that the debugger is recognized as two serial ports (note: not the serial port on the board)

      3. +
      +
    • +
    +
    +../_images/sipeed_rv_debugger_1.png +
    +
      +
      1. +
      2. Download the zadig-2.4 replacement driver from sipeed. Download link: http://dl.sipeed.com/MAIX/tools/sipeed-rv-debugger/zadig-2.4.exe

      3. +
      +
    • +
      1. +
      2. After downloading, double-click to open zadig-2.4.exe, and check List All Devices in Options.

      3. +
      +
    • +
      1. +
      2. Find JTAG Debugger (Interface 0), then select the replacement driver as WinUSB and click Replace Driver to replace

      3. +
      +
    • +
      1. +
      2. Open the device manager again and see that one of the serial ports has been replaced with a universal serial bus device, indicating that the installation is successful

      3. +
      +
    • +
    +
    +../_images/sipeed_rv_debugger_2.png +
    +
      +
      1. +
      2. Connect the JTAG pins of the debugger with the JTAG pins of the board

      3. +
      +
    • +
    +
    +
  • +
  • After completing the above configuration correctly, click the Create&Program button to download

  • +
  • After the download is successful, you will see the status bar turn green and display Success

  • +
+
+ +
+
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/get_started/board.html b/docs/development_guide_en/build/html/get_started/board.html new file mode 100644 index 00000000..018b239a --- /dev/null +++ b/docs/development_guide_en/build/html/get_started/board.html @@ -0,0 +1,440 @@ + + + + + + + + + + 7. Board Configuration System User Guide — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
    + +
  • »
  • + +
  • 7. Board Configuration System User Guide
  • + + +
  • + + + View page source + + +
  • + +
+ + +
+
+
+
+ +
+

7. Board Configuration System User Guide

+

In order to implement the idea of everything is a file, we propose a Board configuration system for embedded applications with different hardware configuration requirements. The Board configuration system is mainly used for initializing the three basic elements of clock, GPIO, and peripheral default configuration in embedded applications.

+

Board Configuration System contains three configuration files, and a bl_config_wizard graphical configuration software

+
    +
  • clock_config.h Clock configuration Include file

  • +
  • peripheral_config.h Peripheral configuration Include file

  • +
  • pinmux_config.h Pin Function Configuration Include file

  • +
  • bl_config_wizard The graphical interface configures the above three types of files

  • +
+

The user only needs to modify three configuration files and the system will be initialized automatically, thus eliminating the need to call a series of complex and lengthy initialization functions in the user program. Boufflao Lab provides bl_config_wizard configuration software for users to quickly and easily generate configuration files for their projects.

+

bl_config_wizard supports PC-side online configuration, but currently does not support mobile terminal online configuration.

+
+ +

bl_config_wizard Preview

+
+
+

7.1. The features of each file in the Board configuration system

+

The board system is mainly used for different boards, different boards create different board files and put them in bsp/board directory, and a board file, in the case of pins not conflicting, can be shared to different demos, no need to create multiple projects and reduce the project file size.

+
+

Error

+

If there is a pin conflict and you have to use the same Board file, please modify the pins yourself

+
+
+

7.1.1. board.c

+

board.c Main initialization of clock and pins

+
+
+

7.1.2. blxxx_config.h

+

blxxx_config.h Mainly contains some header files for the HAL layer driver.

+
+

Hint

+

The above two files do not need to be changed by the user, and the same MCU can be copied and pasted directly into your own board directory for use

+
+
+
+

7.1.3. clock_config.h

+

clock_config.h Mainly configures the clock sources for the system and peripherals as well as the frequency division system.

+
+
+

7.1.4. peripheral_config.h

+

peripheral_config.h It mainly contains the enablement of peripherals and the configuration of parameters.

+
+

Warning

+

Macros starting with #define BSP_USING_XXX are used to enable the configuration of the peripheral, if the macro is not enabled, all functions of the peripheral cannot be used

+
+
+

Warning

+

Macro starting with XXX_CONFIG, used to initialize the configuration of the peripheral, which is later used by calling device_open

+
+
+
+

7.1.5. pinmux_config.h

+

pinmux_config.h Mainly configures the GPIO pin function of the peripheral.

+
+

Warning

+

In mcu sdk, all demos share this file, so some demos are not usable and require frequent changes to the pin function configuration in this file. If the user has already set the pin assignments, there is no need to modify them frequently.

+
+
+
+
+

7.2. Use of the Board configuration tool bl_config_wizard

+ +
+

7.2.1. Generate a new pinmux_config.h file

+
    +
  1. Select Pin & Peripheral Configuration in the window bar.

  2. +
  3. Select MCU model, currently supports BL706 pin configuration, BL704 pin configuration, BL702 pin configuration.

  4. +
  5. Select the function of the pin, take BL706 pin configuration as an example, click on the drop-down box of PAD_GPIO_XX and select the desired function, as shown in the figure.

  6. +
+
+ +

Select pin function

+
+
    +
  1. After configuring all the pin functions, click Export Configuration File and then you can select the path and modify the file name in the pop-up box, as shown in the figure.

  2. +
+
+ +

Exporting configuration files

+
+
+
+

7.2.2. Modify the original pinmux_config.h file

+

Often in use, instead of generating a new pinmux_config.h file, we make changes to the original pinmux_config.h file, and bl_config_wizard supports such a need.

+
    +
  1. Select Pin & Peripheral Configuration in the window bar.

  2. +
  3. Select MCU model, currently supports BL706 pin configuration, BL704 pin configuration, BL702 pin configuration.

  4. +
  5. Click on import configuration file and select the pinmux_config.h file in the pop-up box.

  6. +
  7. Select the pin to be modified and click on its drop-down box to change the pin function

  8. +
  9. When you are done, click Export Profile and then you can select the path and modify the file name in the pop-up box.

  10. +
+
+
+

7.2.3. Modify the pinmux_config.h file in the CDK tool

+
    +
  • pinmux_config.h Also supports the use of graphical configuration wizards in the CDK for adjusting the corresponding pin functions

  • +
  • Drag the pinmux_config.h file directly into the CDK text editor interface, and you will see the Configuration Wizard tab at the bottom of the text editor

    +
    + +

    Configuration Wizard

    +
    +
  • +
  • Click on the Configuration Wizard tab to open the graphical configuration wizard interface

  • +
  • The functions supported by the pin can be selected by selecting the drop-down box

    +
    + +

    Graphical configuration wizard to set pin functions

    +
    +
  • +
  • Please refer to the Graphical Configuration Wizard section of CDK Help for more information on the specific functions and code rules of the Graphical Configuration Wizard.

  • +
+
+
+
+

7.3. Differences with STM32CUBEMX Configuration Tool

+

STM32CUBEMX is also a tool to configure the clock, peripherals and GPIO initialization, eventually generating a complete project with initialization at the very beginning of main.c, and the GPIO and peripheral initialization base will be called in stm32xxx_hal_msp.c.

+
/* MCU Configuration--------------------------------------------------------*/
+
+/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
+HAL_Init();
+
+/* USER CODE BEGIN Init */
+
+/* USER CODE END Init */
+
+/* Configure the system clock */
+SystemClock_Config();
+
+/* USER CODE BEGIN SysInit */
+
+/* USER CODE END SysInit */
+
+/* Initialize all configured peripherals */
+MX_GPIO_Init();
+MX_USART1_UART_Init();
+MX_QUADSPI_Init();
+
+
+
void HAL_UART_MspInit(UART_HandleTypeDef* huart)
+{
+    GPIO_InitTypeDef GPIO_InitStruct = {0};
+    if(huart->Instance==UART5)
+    {
+    /* USER CODE BEGIN UART5_MspInit 0 */
+
+    /* USER CODE END UART5_MspInit 0 */
+        /* Peripheral clock enable */
+        __HAL_RCC_UART5_CLK_ENABLE();
+
+        __HAL_RCC_GPIOB_CLK_ENABLE();
+        /**UART5 GPIO Configuration
+        PB12     ------> UART5_RX
+        PB13     ------> UART5_TX
+        */
+        GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_13;
+        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+        GPIO_InitStruct.Pull = GPIO_NOPULL;
+        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+        GPIO_InitStruct.Alternate = GPIO_AF14_UART5;
+        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+
+        /* UART5 interrupt Init */
+        HAL_NVIC_SetPriority(UART5_IRQn, 0, 0);
+        HAL_NVIC_EnableIRQ(UART5_IRQn);
+    /* USER CODE BEGIN UART5_MspInit 1 */
+
+    /* USER CODE END UART5_MspInit 1 */
+    }
+
+}
+
+
+
+

Hint

+

The projects generated by stm32 all work for one project and cannot be compiled for more than one project at the same time. If you use more than one project, you have to generate more than one of these two files. When using multiple projects, it will indirectly increase the file size and add duplicate files.

+
+
+
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/get_started/cdk_ck_link.html b/docs/development_guide_en/build/html/get_started/cdk_ck_link.html new file mode 100644 index 00000000..621a00f1 --- /dev/null +++ b/docs/development_guide_en/build/html/get_started/cdk_ck_link.html @@ -0,0 +1,394 @@ + + + + + + + + + + Use CDK + CK-Link to compile and debug — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ + + + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/get_started/cdk_new_project_quick_start.html b/docs/development_guide_en/build/html/get_started/cdk_new_project_quick_start.html new file mode 100644 index 00000000..2b2bd632 --- /dev/null +++ b/docs/development_guide_en/build/html/get_started/cdk_new_project_quick_start.html @@ -0,0 +1,323 @@ + + + + + + + + + + 5. New Project Guide based on CDK — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
    + +
  • »
  • + +
  • 5. New Project Guide based on CDK
  • + + +
  • + + + View page source + + +
  • + +
+ + +
+
+
+
+ +
+

5. New Project Guide based on CDK

+

This document will briefly explain how to create a new CDK project based on this SDK, please make sure that the CDK IDE is properly installed before following this tutorial.

+
+

5.1. Examples directory structure

+

There are two levels of subdirectories under bl_mcu_sdk/examples, the first level is the folders of different peripherals. The second level is a specific test case of the peripheral, The second level directory usually also contains a directory named cdk and the source code associated with the case. +The cdk directory usually contains a xxx.cdkproj file, which is a CDK project file. If the CDK IDE is properly installed, double-click the project to open it. The newly created project should be at the same level as the case level in the current examples directory.

+
+

Note

+

The source file must contain the c program entry, usually the main function, the source file may not be called main.c

+
+
    +
  • Create a new my_case folder under examples to store your case

  • +
  • Create a new folder that needs to be tested in the my_case directory, such as gpio_case

  • +
  • Then add the main.c file and cdk directory in the gpio_case directory

  • +
+

The directory structure is as follows:

+
1
+2
+3
+4
+5
+6
+7
+8
+9
bl_mcu_sdk
+├── examples
+    ├── my_case
+        ├── gpio_case
+        │   ├── cdk
+        │   │   ├──gpio_case.cdkproj
+        │   ├── CMakeLists.txt
+        │   └── main.c
+        └── xxxx_case
+
+
+
+ +
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/get_started/cdk_rv_debugger_plus.html b/docs/development_guide_en/build/html/get_started/cdk_rv_debugger_plus.html new file mode 100644 index 00000000..41169424 --- /dev/null +++ b/docs/development_guide_en/build/html/get_started/cdk_rv_debugger_plus.html @@ -0,0 +1,334 @@ + + + + + + + + + + Use CDK + Sipeed RV-Debugger Plus to compile and debug — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

Use CDK + Sipeed RV-Debugger Plus to compile and debug

+
+

Open Hello World

+
    +
  • After obtaining the SDK, enter the examples/hellowd/helloworld/cdk directory and double-click helloworld.cdkproj to open the Helloworld project

  • +
+
+
+

Compile Hello World

+
+ +

helloworld.cdkproj

+
+
    +
  • Select the OpenOCD_Debug project in the drop-down menu. Since Sipeed RV-Debugger Plus uses OpenOCD for debugging, this tutorial is based on the OpenOCD_Debug project;

  • +
  • If Sipeed RV-Debugger Plus does not install the driver correctly, please refer to Sipeed RV-Debugger Plus driver installation settings, set up the driver, and then proceed to the following steps

  • +
  • In the CDK toolbar, click the compile icon to compile the project

    +
    +
      +
    • Click 1 Build Project to compile the currently selected project

    • +
    • Click 2 Clean Project to clear the results of the last compilation

    • +
    • Click 3 Flash Download to download the compiled code to the chip (Flash download function cannot be used with OpenOCD Debug)

    • +
    • Click 5 Start/Stop Debug whitout Download to debug directly without loading the current bin file

    • +
    • You can also right-click the project name in Project, and compile the project through the options in the right-click menu

    • +
    +
    +
  • +
+
+
+

Program Hello World

+
    +
  • When using the OpenOCD mode debugging method in the CDK, it is not currently supported to directly use the CDK related flash tool to download the code, so please use the BL Dev Cube tool to program, please refer to BLDevCube start guide

  • +
  • Use CDK to debug after the code is programmed

  • +
+
+
+

Run Hello World

+
    +
  • From the menu bar of the CDK View->Serial Pane, open the serial port panel, right-click in the opened Serial Pane, set the serial port, select your corresponding serial port number and baud rate

  • +
+
+../_images/cdk4.png +
+
+ +

CDK Serial Pane setting

+
+
    +
  • Press the RST key on the board, you can see the result of the code in the serial port

  • +
+
+ +

HelloWorld!

+
+
+
+

Debug Hello World

+
    +
  • Click the Start/Stop Debugger button at the top of the toolbar to enter the debug interface, as shown in the figure below

  • +
+
+ +

Debug HelloWorld!

+
+
    +
  • In the debug interface, the Register window can view the CPU internal register data; the Peripherals peripheral panel, you can view the corresponding peripheral register data, the top menu bar Peripherals-> System Viewer can select peripherals; click the relevant debugging button in the upper toolbar to perform operations such as breakpoint setting, single-step debugging, single-step instruction, and full-speed operation. Of course, these operations have corresponding shortcut keys and shortcut setting methods. For details, please refer to CDK Help.

  • +
  • We click the single step button to run the code, and we can see that the cursor moves to the next sentence of code, and we can see our output Hello World! displayed in the serial port panel.

  • +
+
+
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/get_started/cmake_quick_start.html b/docs/development_guide_en/build/html/get_started/cmake_quick_start.html new file mode 100644 index 00000000..26691f84 --- /dev/null +++ b/docs/development_guide_en/build/html/get_started/cmake_quick_start.html @@ -0,0 +1,463 @@ + + + + + + + + + + 4. New Project Guide based on cmake framework — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
    + +
  • »
  • + +
  • 4. New Project Guide based on cmake framework
  • + + +
  • + + + View page source + + +
  • + +
+ + +
+
+
+
+ +
+

4. New Project Guide based on cmake framework

+

This document will introduce how to create a new project based on this SDK.

+
+

4.1. Examples directory structure

+

There are two levels of subdirectories under bl_mcu_sdk/examples, the first level is the folders of different peripherals. The second level is a specific test case of the peripheral, and the directory usually contains a CMakeList.txt and the source code related to the case.

+
+
+

4.2. Add a single source file project

+
+

Note

+

The source file must contain the c program entry, usually the main function, the source file may not be called main.c

+
+
    +
  • Create a new my_case folder under examples to store your case

  • +
  • Create a new folder that needs to be tested in the my_case directory, such as gpio_case

  • +
  • Then add the main.c and CMakeLists.txt files in the gpio_case directory

  • +
+

The directory structure is as follows:

+
1
+2
+3
+4
+5
+6
+7
bl_mcu_sdk
+├── examples
+    ├── my_case
+        ├── gpio_case
+        │   ├──CMakeLists.txt
+        │   └──main.c
+        └── xxxx_case
+
+
+

CMakeLists.txt:

+
1
+2
set(mains main.c)
+generate_bin()
+
+
+
    +
  • After writing the code in main.c, compile it in the bl_mcu_sdk directory. The compilation command is as follows:

  • +
+
1
make BOARD=bl706_iot APP=gpio_case
+
+
+
+
+

4.3. Add multiple source file projects

+
+

Note

+

One of the source files must contain the c program entry, usually the main function, the source file does not need to be called main.c. This source file depends on other source files.

+
+
    +
  • The steps for adding a multi-source file project are the same as the basic steps for adding a single source file project

  • +
  • Add test1.c, test1.h, test2.c, test2.h and other source files and header files that need to be relied on in the gpio_case directory

  • +
+

The directory structure is as follows:

+
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
bl_mcu_sdk
+├── examples
+    ├── my_case
+        ├── gpio_case
+        │   ├──CMakeLists.txt
+        │   ├──test1.c
+        │   ├──test1.h
+        │   ├──test2.c
+        │   ├──test2.h
+        │   └──main.c
+        └── xxxx_case
+
+
+
    +
  • At this time, the CMakeLists.txt file needs to add the corresponding dependent source file, the content is as follows:

  • +
+

CMakeLists.txt:

+
1
+2
+3
set(mains main.c)
+set(TARGET_REQUIRED_SRCS test1.c test2.c)
+generate_bin()
+
+
+
    +
  • After writing the code, compile it in the bl_mcu_sdk directory. The compilation command is as follows:

  • +
+
1
make BOARD=bl706_iot APP=gpio_case
+
+
+
+
+

4.4. Add a new project with dependent libraries

+
    +
  • The steps for adding a new project with dependent libraries are the same as the basic steps for adding a single source file project

  • +
  • If the dependent library used already exists in this SDK, you only need to modify CMakeLists.txt

    +
    +
      +
    • If the dependent library does not exist, you need to add it yourself, please refer to the follow-up instructions for details

    • +
    +
    +
  • +
+

If it already exists, the directory structure is as follows:

+
1
+2
+3
+4
+5
+6
+7
bl_mcu_sdk
+├── examples
+    ├── my_case
+        ├── gpio_case
+        │   ├──CMakeLists.txt
+        │   └──main.c
+        └── xxxx_case
+
+
+
    +
  • At this time, the CMakeLists.txt file needs to add the corresponding dependent library files. For example, we add the FreeRTOS component library, the content is as follows:

  • +
+

CMakeLists.txt:

+
1
+2
+3
set(TARGET_REQUIRED_LIBS freertos)
+set(mains main.c)
+generate_bin()
+
+
+
    +
  • After writing the code, compile it in the bl_mcu_sdk directory. The compilation command is as follows:

  • +
+
1
make BOARD=bl706_iot APP=gpio_case  SUPPORT_FREERTOS=y
+
+
+
+
+

4.5. Add a new project and set the private compilation option (gcc option)

+
    +
  • The steps of adding a new project are basically the same as adding a single source file project

  • +
  • Mainly modify the CMakeLists.txt file and add private compilation options

  • +
+

CMakeLists.txt:

+
1
+2
+3
set(mains main.c)
+set(TARGET_REQUIRED_PRIVATE_OPTIONS -Ofast)
+generate_bin()
+
+
+
    +
  • After writing the code, compile it in the bl_mcu_sdk directory. The compilation command is as follows:

  • +
+
1
make BOARD=bl706_iot APP=gpio_case
+
+
+
+ +
+

4.7. Add a new project and its dependent source files and library files

+
+
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/get_started/connecting_hardware.html b/docs/development_guide_en/build/html/get_started/connecting_hardware.html new file mode 100644 index 00000000..8199a8b4 --- /dev/null +++ b/docs/development_guide_en/build/html/get_started/connecting_hardware.html @@ -0,0 +1,450 @@ + + + + + + + + + + 2. Hardware connection — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

2. Hardware connection

+

This document introduces how to connect the board of BL70x series MCU.

+
+

2.1. BL706_IOT

+ + +
+

2.1.3. Use serial port to Programming

+
    +
  • Before using the serial port to Programming, please make sure that Bouffalo Lab Dev Cube or the command programming tool is installed correctly

    +
      +
    • Use Type-C USB data cable or Mini USB data cable to connect to the Type-C interface or Mini interface on the board.

    • +
    • Press the Boot key on the board, don’t release it.

    • +
    • Press the RST key on the board, now you have entered Boot ROM, you can release the two keys.

    • +
    • At this time, you can see the corresponding serial port COM number from the Bouffalo Lab Dev Cube, if it does not appear, please click the Refresh key to refresh.

    • +
    +
  • +
  • If you don’t have a suitable data cable, you can also use some common USB-TTL modules to connect to the UART0 port of the development board for programming. UART0 is on the HD1 group, the connection method is as follows:

  • +
+
USB-TTL      BL702_IoT
+----------------------
+  3V3   <-->   VDD
+  TXD   <-->   RX0
+  RXD   <-->   TX0
+  GND   <-->   GND
+
+
+
    +
  • The programming step is the same as above

  • +
+
+
+
+

2.2. BL706_AVB

+
+

Important

+

BL706_AVB has multiple multiplexed pins, please check carefully whether the required function pins are multiplexed; FUNC1: “Default: PIX; Connect: I2S/JTAG”, FUNC2: “Default: I2S; Connect: SPI” ; If you need to debug, please remember to connect the FUNC1 jumper

+
+
+

2.2.1. Use Sipeed RV-Debugger Plus to programming and debug

+
    +
  • Powering the BL706_AVB

  • +
  • Connect the RV-Debugger Plus debugger to the USB port of the computer. If the driver is not installed correctly, please refer to Sipeed RV-Debugger Plus driver installation settings, set the driver, and proceed to the following steps

  • +
  • Connect the debugger and the BL706_AVB with a cable (as shown in the figure below)

  • +
+
+

Important

+

The FUNC1 jumper must be connected when debugging, otherwise the pins will be multiplexed with other functions and the JTAG function cannot be used; the serial port function can be used normally

+
+
+ +

RV-Debugger connect bl706_avb board

+
+
+
+

2.2.2. Use CK-Link to programming and debug

+
    +
  • Connect the CK-Link USB interface to the PC with a suitable USB data cable

  • +
  • Connect the FUNC1 jump caps of the bl706_avb

  • +
  • Connect the pins of the HD8 group to the adapter board using a flat cable

  • +
  • Connect the JTAG pin of the adapter board with the corresponding JTAG pin of CK-Link using a Dupont wire

  • +
  • If you do not use CK-Link to power the board, you need to power the board separately

  • +
+
bl706-avb board         CK-Link
+-------------------------------
+    JTAG_TDI     <-->     TDI
+    JTAG_TDO     <-->     TDO
+    JTAG_TCK     <-->     TCK
+    JTAG_TMS     <-->     TMS
+    VDD33        <-->     VREF
+    GND          <-->     GND
+
+
+
+ +

ck_link connect bl706_avb board

+
+
+
+

2.2.3. Use serial port to programming

+
    +
  • Before using the serial port to programming, please make sure that Bouffalo Lab Dev Cube or the command programming tool is installed correctly

    +
      +
    • Use the Type-C USB or Mini USB data cable to connect to the corresponding Type-C port or Mini port on the board.

    • +
    • Press the Boot key on the board, don’t release it.

    • +
    • Press the RST key on the board, now you have entered Boot ROM, you can release the two keys.

    • +
    • At this time, you can see the corresponding serial port COM number from the Bouffalo Lab Dev Cube, if it does not appear, please click the Refresh button to refresh.

    • +
    +
  • +
  • If you don’t have a suitable data cable, you can also use some common USB-TTL modules to connect to the UART0 port of the development board for programming. UART0 on the HD12 group, the connection method is as follows:

  • +
  • If you use Sipeed RV-Debugger Plus to connect BL706_AVB through a flat cable, you can also use the serial port of Sipeed RV Debugger Plus

  • +
+
USB-TTL      BL706_AVB
+----------------------
+  TXD   <-->   RX0
+  RXD   <-->   TX0
+  GND   <-->   GND
+
+
+
+
+

2.2.4. Connect BL706 AVB sub-modules

+
    +
  • This section describes how to connect the BL706_AVB board with other modules, mainly including camera connection, Audio Codec module connection, and SPI screen connection.

  • +
+

BL706_AVB Connects to GC0308 Camera Module

+
    +
    1. +
    2. First, take the black locking part of the J5 drawer type FPC cable holder on the back of the BL706_AVB development board and pull it out from the edge

    3. +
    +
  • +
+
+ +
+
    +
    1. +
    2. When fully disconnected, as shown in the figure below.

    3. +
    +
  • +
+
+ +
+
    +
    1. +
    2. The FPC cable holder is a drawer down type, so next insert the camera with the side without metal contact points facing upwards into the FPC cable holder

    3. +
    +
  • +
+
+ +
+
    +
  • After inserting the camera, press the black latch tightly

  • +
+
+ +
+

BL706_AVB Connecting Audio Codec Modules

+
    +
  • Insert the HD19 group of pins of Audio Codec module into the HD11 row female socket of BL706_AVB development board; note that the module is extended outward.

  • +
  • The schematic diagram is as follows:

  • +
+
+ +
+
+
+
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/get_started/get_started.html b/docs/development_guide_en/build/html/get_started/get_started.html new file mode 100644 index 00000000..269ee9f3 --- /dev/null +++ b/docs/development_guide_en/build/html/get_started/get_started.html @@ -0,0 +1,414 @@ + + + + + + + + + + 1. Preparation — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

1. Preparation

+
+

1.1. Hardware environment

+
    +
  • At least one board for BL702 series MCU:

    +
      +
    • BL706_IOT

    • +
    • BL706_AVB

    • +
    +
  • +
+

BL706_Iot as shown in the figure below

+
+ +

BL706_IoT

+
+

BL706_AVB as shown in the figure below

+
+ +

BL706_AVB

+
+
    +
  • A debugger that supports standard JTAG, just choose one of the following debuggers:

    +
      +
    • CK-Link

    • +
    • Jlink V11

    • +
    • Sipeed RV-Debugger Plus

    • +
    • Bouffalo Lab Debugger

    • +
    +
  • +
  • One PC host (Windows or Linux system)

  • +
+
+
+

1.2. Software Environment

+

In order to better use the BL702 series MCU, it is recommended that you have at least one of the following development environments:

+
    +
  • Use CDK for Windows (Windows 7 or above is recommended)

  • +
  • Windows Use Eclipse (Windows 7 or above is recommended)

  • +
  • Linux (LTS version above Ubuntu 18 is recommended)

  • +
+
+
+

1.3. Sipeed RV-Debugger Plus driver installation settings

+
    +
  • This section mainly introduces the driver installation settings of the Sipeed RV-Debugger Plus debugger. If you use **CK-Link** or **J-Link**, you don’t need to read this section.

  • +
+
+ +

Sipeed RV-Debugger plus

+
+

Windows

+
    +
  • To use the Sipeed RV-Debugger Plus debugger on Windows we need to change the driver to the Win USB driver

    +
      +
      1. +
      2. First, connect the Type-C USB interface of the debugger to the PC with a USB data cable, open the device manager of the PC, and you can see that the debugger is recognized as two serial ports in the port column (Note: not the Serial port of the board’s Boot interface), or in the Universal Serial Bus Controller, you see USB Serial Converter A and USB Serial Converter B

      3. +
      +
    • +
    +
    +../_images/sipeed_rv_debugger_1.png +
    +
    +../_images/sipeed_rv_debugger_4.png +
    +
    +

    Important

    +
      +
    1. The debugger port number must start with usb serial port, if you plug in more than one similar device, please leave only one, confirm the debugger port number

    2. +
    +
    +
    +

    Important

    +
      +
    1. If you see “USB Serial Device (COM*)” in the Device Manager, it means that the debugger has entered the “Boot” mode. Please power off the debugger and power it on again, and be careful not to connect the debugger to the target board; at this time, go to the device manager to see if it is normal

    2. +
    +
    +
    +../_images/sipeed_rv_debugger_7.png +
    +
    +

    Important

    +
      +
    1. If the serial port is not shown in the device manager, only other devices are shown, or if you only see USB Serial Converter A and USB Serial Converter B in the Universal Serial Bus Controller, please go to the FTDI official website Download the driver that matches your system

    2. +
    +
    +
    +../_images/sipeed_rv_debugger_6.png +
    + +
    +../_images/sipeed_rv_debugger_3.png +
    +
      +
      1. +
      2. Find JTAG Debugger (Interface 0), then select the replacement driver as WinUSB and click Replace Driver to replace

      3. +
      +
    • +
      1. +
      2. Open the device manager again and see that one of the serial ports has been replaced with a universal serial bus device, indicating that the installation is successful

      3. +
      +
    • +
    +
    +../_images/sipeed_rv_debugger_2.png +
    +
      +
      1. +
      2. At this point, the device driver of Sipeed RV-Debugger Plus has been replaced, and then you can play happily~

      3. +
      +
    • +
    +
  • +
+

Possible problems:

+
+

Caution

+
    +
  1. There are no two serial ports when the debugger is connected, and an LED on the debugger is always on, then it should be in Boot mode. Please power off the debugger and power it on again. Be careful not to connect the debugger to the target board; after the debugger is powered on, the two LED lights will flicker and go out under normal circumstances; at this time, check whether the device in the task manager is correct.

  2. +
+
+
+

Caution

+
    +
  1. If you still can’t use it normally after the above operations, and there is no correct phenomenon, it is recommended to download from the official Sipeed repository GitHub obtain the firmware and re-write; press and hold the Boot button on the debugger without releasing it, insert the debugger into the computer and power on, make the debugger enter the Boot mode, and flash the firmware again; power off and restart

  2. +
+
+

Linux

+
    +
  • First, connect the Type-C USB interface of the debugger to the PC host using the USB cable, open Terminal, and enter the command lsusb in the terminal to see the device with the following information

  • +
+
$ lsusb
+...
+Bus 001 Device 003: ID 0403:6010 Future Technology Devices International, Ltd FT2232C Dual USB-UART/FIFO IC
+...
+
+
+
+../_images/sipeed_rv_debugger_8.png +
+
    +
  • If the above diagram does not show the FT2232C, you need to install the ftdi driver

  • +
+
$ sudo apt install libusb-dev libftdi-dev libhidapi-dev
+
+
+
    +
  • Re-plug the debugger to make the changes take effect

  • +
  • Debugging code requires openocd to be installed, using openocd version 0.11

  • +
+
+

Note

+

In Linux system, /dev/ttyUSB1 is used for serial port, /dev/ttyUSB0 is used for debug port, if /dev/ttyACM0 is displayed, it means boot mode is entered.

+
+
+
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/get_started/index.html b/docs/development_guide_en/build/html/get_started/index.html new file mode 100644 index 00000000..69ac0d0c --- /dev/null +++ b/docs/development_guide_en/build/html/get_started/index.html @@ -0,0 +1,270 @@ + + + + + + + + + + 3. Development environment setup guide — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
    + +
  • »
  • + +
  • 3. Development environment setup guide
  • + + +
  • + + + View page source + + +
  • + +
+ + +
+
+
+
+ +
+

3. Development environment setup guide

+

Before the formal development, please set up a suitable development environment. The specific steps are as follows:

+
+
+ +++++ + + + + + + + + + + +

cdk-logo

eclipse-logo

linux-logo

Windows_CDK

Windows_eclipse

Linux

+
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/index.html b/docs/development_guide_en/build/html/index.html new file mode 100644 index 00000000..0dfc9bbe --- /dev/null +++ b/docs/development_guide_en/build/html/index.html @@ -0,0 +1,291 @@ + + + + + + + + + + BL MCU SDK development guide — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

BL MCU SDK development guide

+

The BL702 series products are general-purpose microcontrollers based on “SiFive E24 Core” RISC-V , with network functions such as BLE 5.0, zigbee and Ethernet, as well as other rich peripherals. +It can be used in a wide range of IoT and other low-power applications. +Supports programming and debugging of the chip through JTAG , and also supports through UART programming. +BL MCU SDK will provide users with comprehensive support for BL70X series MCU development.

+ +
+

API Manuals

+ +
+
+

Basic Peripheral Samples

+ +
+ +
+ + +
+ +
+
+ + +
+ +
+

+ © Copyright 2021, BouffaloLab Co., Ltd. + +

+
+ + + + Built with Sphinx using a + + theme + + provided by Read the Docs. + +
+
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/objects.inv b/docs/development_guide_en/build/html/objects.inv new file mode 100644 index 00000000..8900e1f6 Binary files /dev/null and b/docs/development_guide_en/build/html/objects.inv differ diff --git a/docs/development_guide_en/build/html/samples/advance samples/ble_scan_demo.html b/docs/development_guide_en/build/html/samples/advance samples/ble_scan_demo.html new file mode 100644 index 00000000..1ea93dbb --- /dev/null +++ b/docs/development_guide_en/build/html/samples/advance samples/ble_scan_demo.html @@ -0,0 +1,505 @@ + + + + + + + + + + 5. BLE Client And Server Interconnection — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
    + +
  • »
  • + +
  • 5. BLE Client And Server Interconnection
  • + + +
  • + + + View page source + + +
  • + +
+ + +
+
+
+
+ +
+

5. BLE Client And Server Interconnection

+

This demo is based on bl702 to demonstrate the connection and data sending and receiving of ble server and ble client.

+
+

5.1. Prepare

+
    +
  • Two bl702 boards or one bl702 board + mobile app

  • +
+
+
+

5.2. Software Implementation

+
+

5.2.1. BLE client software Implementation

+
    +
  • For the software code, see examples/ble/ble_central

  • +
+
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
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);
+    }
+}
+
+
+
    +
  • In the bt_conn_cb_register function, register the callback function for successful connection and disconnection

  • +
  • In the ble_start_scan function, the device will start scanning

  • +
  • In the device_found function, the device uploads the scanned Bluetooth device, the code uses adv_name to find the Bluetooth device that needs to be connected, and initiate the connection

  • +
+
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
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);
+   }
+}
+
+
+
    +
  • After the connection is successful, in the ble_write_data_task function, the client sends the data in buf to the server

  • +
+
1
static u8_t notify_func(struct bt_conn *conn,struct bt_gatt_subscribe_params *params,const void *data, u16_t length);
+
+
+
    +
  • After the connection is successful, in the notify_func function, the client receives the data from the server, data is the data content, length is the data length

  • +
+
+
+

5.2.2. BLE server software implementation

+
    +
  • See examples/ble/ble_peripheral for the software code

  • +
+
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
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);
+}
+
+
+
    +
  • In the ble_start_adv function, adv_name sets the name of the broadcast device, and the device starts to broadcast

  • +
+
1
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);
+
+
+

-After the connection is successful, in ble_tp_recv_wr, the server receives the data from the client, buf is the data content, len is the data length

+
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
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);
+
+    }
+}
+
+
+
    +
  • After the connection is successful, in the ble_tp_notify_task function, the server sends the data in data to the client.

  • +
+
+
+
+

5.3. Compile and program

+
    +
  • CDK tool compilation

    +
    +

    Not currently supported

    +
    +
  • +
  • Command compilation

  • +
+
1
+2
 $ cd <sdk_path>/bl_mcu_sdk
+ $ make BOARD=bl706_iot APP=ble_peripheral SUPPORT_FREERTOS=y SUPPORT_FLOAT=y SUPPORT_BLE=y
+
+
+
1
+2
 $ cd <sdk_path>/bl_mcu_sdk
+ $ make BOARD=bl706_iot APP=ble_central SUPPORT_FREERTOS=y SUPPORT_FLOAT=y SUPPORT_BLE=y
+
+
+ +
+
+

5.4. Experimental phenomena

+
    +
  • Two bl702 connections

  • +
+
+ +
+
+ +
+
    +
  • Mobile phone connect bl702

  • +
+
+ +
+
    +
  • The connection is successful, as shown in the figure below

  • +
+
+ +
+
    +
  • Steps to send and receive data

    +
    +
      +
    • Click 1 Unknow Service to display specific service properties

    • +
    • Click 2 to turn on Notification, allowing the server to send data to the client

    • +
    • Click 3 where the client sends data to the server, fill in the data you want to send, and click the SEND button

    • +
    +
    +
  • +
+
+ +
+
+ +
+
+ +
+
+
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/samples/advance samples/boot2_iap_info.html b/docs/development_guide_en/build/html/samples/advance samples/boot2_iap_info.html new file mode 100644 index 00000000..13d8f339 --- /dev/null +++ b/docs/development_guide_en/build/html/samples/advance samples/boot2_iap_info.html @@ -0,0 +1,265 @@ + + + + + + + + + + 4. BOOT2 IAP — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

4. BOOT2 IAP

+

IAP (In Application Programming) is to program some areas of User Flash during the running of the user program. The purpose is to update the firmware program in the product through the reserved communication port after the product is released.

+

If you need to realize the IAP function, that is, it will be automatically updated when the user program is running. Need to write two project codes when designing the firmware program. The first project program does not perform normal functional operations, but only receives programs or data through some communication channel (such as USB, USART) to update the second part of the code, and the second project code is the real function Code.

+

Bouffalo Lab provides the boot2_iap.bin file and releases it simultaneously with the Dev Cube software package. Users can use Dev Cube to program boot2_iap.bin into the target board. After programming once, the user code can be updated online through the IAP function.

+

bl_mcu_sdk contains the source code of boot2_iap, users can check the code in examples/boot2_iap, and complete the compilation and programming. For the compilation and programming process, please refer to the introduction of “Quick Development Guide”.

+
+

4.1. Prepare

+
    +
  • The latest version of Dev Cube

  • +
  • Bl706

  • +
  • TTL-USB

  • +
+
+
+

4.2. Experimental phenomena

+

For the specific steps of using Dev Cube to complete the IAP function, please refer to DevCube User Manual “IAP Program Download”.

+
+
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/samples/advance samples/fatfs_demo.html b/docs/development_guide_en/build/html/samples/advance samples/fatfs_demo.html new file mode 100644 index 00000000..a6feafae --- /dev/null +++ b/docs/development_guide_en/build/html/samples/advance samples/fatfs_demo.html @@ -0,0 +1,245 @@ + + + + + + + + + + 2. FATFS Read And Write — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

2. FATFS Read And Write

+
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/samples/advance samples/lowpower_demo.html b/docs/development_guide_en/build/html/samples/advance samples/lowpower_demo.html new file mode 100644 index 00000000..a0f90d04 --- /dev/null +++ b/docs/development_guide_en/build/html/samples/advance samples/lowpower_demo.html @@ -0,0 +1,367 @@ + + + + + + + + + + 3. LowPower Evaluation — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

3. LowPower Evaluation

+
+

3.1. Introduction

+

BL series chips have rich low-power features to adapt to different low-power applications. In order to facilitate users to quickly evaluate and use the low-power performance of bl series MCUs, bl_mcu_sdk provides a set of low-power interfaces. The low-power levels are divided into four levels.

+
    +
  1. Running: The power consumption when the CPU is running normally, and the power consumption is determined by the function executed by the customer application code.

  2. +
  3. WFI: WFI mode, the clock of the CPU is in the Gating state, the CPU stops running, and the program will continue to run when the user exits the WFI mode.

  4. +
  5. PDS: In PDS mode, most power domains on the chip are turned off, and the CPU is turned off at the same time. RAMs such as ITCM and DTCM in the same power domain as the CPU cannot be used. Only 64K OCTAM can save data. The internal RTC can be used to wake up, or use GPIO pins (when the GPIO power domain is not turned off) to wake up.

  6. +
  7. HBN: HBN mode, shuts down most of the power domains on the chip, shuts down the CPU and 64K OCRAM, only 4K RAM in the AON domain can save data. The internal RTC can be used to wake up, or a specific wake-up pin (pin located in the AON domain) can be used to wake up.

  8. +
+

bl_mcu_sdk provides a simple low-power reference example (bl_mcu_sdk examples/power/lowpower_test/) to help users quickly evaluate low-power features. If you need to further adapt to your own low-power scenarios and adopt different low-power methods, please refer to the relevant datasheet or seek technical support from Boufflao Lab. +In this example, the clock selection of peripherals and CPU are both crystal oscillator 32M. The power consumption measurement results based on this example are shown in the following table:

+
+
+++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Mode

Reference current

Basic mode

Wake-up source

Remark

Running

5.68 mA

Run

All peripheral clocks are turned on

WFI

3.14 mA

WFI

Any interruption

Except the serial port, other peripheral clocks are closed

PDS

10 uA

PDS 31

Internal RTC/pin interrupt

64K OCRAM to save data

HBN

1 uA

HBN 1

Internal RTC/pin interrupt

4K AON RAM to save data

+
+

The reference current in the above table is obtained through the sample firmware test. The definition of four levels of “run” ” wfi” “pds” “hbn” simplifies the original setting of hbn level and pds level.

+

See bl702_bl704_bl706_DS_EN_Combo_1.9.pdf page 28

+
+../../_images/powerTable.png +
+
+
+

3.2. Low power consumption example test method

+
+

3.2.1. Compile low-power sample code

+

Write make APP=lowpower_test SUPPORT_SHELL=y BOARD=bl706_lp in the project directory to complete the compilation of the low power consumption example bl706, or use the CDK project directly to complete the compilation and download. +You can refer to this document “Quick Development Guide” to get more information about compiling and programming.

+

When the compilation and programming are successful, connect the serial port to the computer and reset the chip, Xshell will display the page as shown in the figure below.

+
+../../_images/xShell_lowpower.png +
+
+
+

3.2.2. Prepare the hardware environment required for low-power testing

+
    +
  • It is possible to connect the ammeter and the circuit board of the power supply side in series

  • +
  • Ammeter

  • +
  • PC (running Windows or Linux system)

  • +
  • TTL to USB

  • +
+

As shown in the figure below, connect the ammeter in series into the power supply circuit of the bl706 module, and issue different low-power commands through the serial debugging assistant software on the PC side, so that the bl706 enters the corresponding low-power mode. +Observe the indicated current value and complete the evaluation.

+
+../../_images/lowpower_arch.png +
+
+
+

3.2.3. Use Xshell to start evaluating low-power performance

+

The user can enter the corresponding low power consumption mode by entering the following commands in Xshell.

+

run

+
    +
  • After resetting the chip, it enters the run mode by default without entering any low power consumption mode. The chip is actually running the while(1); statement.

  • +
+

wfi

+
    +
  • Enter wfi mode without adding any parameters. After entering, the CPU is in clock gating state to reduce power consumption

  • +
  • After entering wfi mode, any interrupt will wake up, such as uart interrupt. Pressing Enter in Xshell will trigger the BL706 UART RX interrupt, so the wfi low power consumption mode can be awakened by this method.

  • +
+

pds sleeptime

+
    +
  • pds can choose to take the parameter “sleeptime” to determine its internal RTC wake-up time. If the command does not carry this parameter, the RTC internal wake-up is not used by default. The current firmware only supports power-on reset wake-up.

  • +
  • If the instruction contains the sleeptime parameter, pds will be awakened at the moment of sleeptime * clock_period, which will behave as resetting the chip and reprinting the initial message.

  • +
  • After entering the low-power mode, the RTC clock is 32K, so when the sleeptime is 32768, it appears to wake up after a second of sleep.

  • +
+

hbn sleeptime

+
    +
  • hbn can choose to take the parameter “sleeptime” to determine its internal RTC wake-up time. If the command does not carry this parameter, the RTC internal wake-up is not used by default. The current firmware only supports power-on reset wake-up.

  • +
  • If the instruction contains the sleeptime parameter, hbn will be awakened at the moment of sleeptime * clock_period, which will behave as resetting the chip and printing the start message again.

  • +
  • After entering the low-power mode, the RTC clock is 32K, so when the sleeptime is 32768, it appears to wake up after a second of sleep.

  • +
+
+
+
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/samples/advance samples/shell_demo.html b/docs/development_guide_en/build/html/samples/advance samples/shell_demo.html new file mode 100644 index 00000000..648bb106 --- /dev/null +++ b/docs/development_guide_en/build/html/samples/advance samples/shell_demo.html @@ -0,0 +1,515 @@ + + + + + + + + + + 1. SHELL Command Debugging — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

1. SHELL Command Debugging

+

In order to facilitate the user to use the pc or other controllers to debug the functions of the development board (non-emulator debugging), we provide users with a shell command component, which is similar to the command operation under linux. The user sends commands on the PC or other control terminals, and sends the data to the shell of the development board through serial port, usb, Ethernet, Bluetooth, wifi, etc. The shell will read the received commands for analysis and scan the registered internal functions. After scanning the matching function, execute the matching function, and return the incoming key value and the result of the function execution to the pc or control terminal in real time . It should be noted that the controller side needs to send the key value of the standard keyboard. +This demo will demonstrate how to use shell to debug commands through the serial port.

+

This shell component has the following functions:

+
    +
  • Support standard keyboard character control

  • +
  • Support command auto completion

  • +
  • Support up and down keys to view historical commands

  • +
  • Support left and right keys to modify commands

  • +
  • Support file system and network system debugging

  • +
+
+

1.1. Prepare

+
    +
  • PC control terminal uses serial terminal software: xshell or mobaxterm

  • +
  • Connection medium: usb to serial port or network or usb

  • +
+
+
+

1.2. Hardware Connection

+

This demo is based on BL706_IOT and the connection method is as follows

+
   GPIO function         GPIO pin
+----------------------------------
+    UART0_TX      <-->     GPIO14
+    UART0_RX      <-->     GPIO15
+
+
+
+
+

1.3. Software Implementation

+
+

1.3.1. Shell porting to serial port

+
    +
  • See examples/shell for the software code

  • +
+
1
+2
#define BSP_UART_CLOCK_SOURCE  ROOT_CLOCK_SOURCE_PLL_96M
+#define BSP_UART_CLOCK_DIV  0
+
+
+
    +
  • Configure the UART device clock source, see bsp/board/bl706_iot/clock_config.h

  • +
+
1
+2
#define CONFIG_GPIO14_FUNC GPIO_FUN_UART0_TX
+#define CONFIG_GPIO15_FUNC GPIO_FUN_UART0_RX
+
+
+
    +
  • Configure UART device multiplexing pins, see bsp/board/bl706_iot/pinmux_config.h

  • +
+
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
#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
+
+
+
    +
  • Enable BSP_USING_UART0 and configure UART device configuration, see bsp/board/bl706_iot/peripheral_config.h

  • +
+
1
bflb_platform_init();
+
+
+
    +
  • In the bflb_platform_init function, we have registered and opened a serial port device for debugging, to provide users with a basic function of MSG for printing out messages. The specific implementation is as follows

  • +
+
1
+2
+3
+4
+5
+6
+7
+8
+9
    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, NULL);
+        device_control(uart, DEVICE_CTRL_CLR_INT, (void *)(UART_RX_FIFO_IT));
+    }
+
+
+
    +
  • First call the uart_register function to register the UART device, currently register UART0

  • +
  • Then use the find function to find the handle corresponding to the device and save it in the uart handle

  • +
  • Finally use device_open to open the uart device with polling sending and interrupt receiving, the interrupt is closed by default and the receiving interrupt callback function is not registered

  • +
+
1
+2
+3
+4
+5
struct device *uart = device_find("debug_log");
+if (uart) {
+    device_set_callback(uart, shell_irq_callback);
+    device_control(uart, DEVICE_CTRL_SET_INT, (void *)(UART_RX_FIFO_IT));
+}
+
+
+
    +
  • Register the receive interrupt service function for UART0 through the device_set_callback function. Open the UART_RX_FIFO_IT interrupt via the device_control function

  • +
+
1
+2
+3
+4
+5
+6
+7
+8
void shell_irq_callback(struct device *dev, void *args, uint32_t size, uint32_t state)
+{
+    uint8_t data;
+    if (state == UART_EVENT_RX_FIFO) {
+        data = *(uint8_t *)args;
+        shell_handler(data);
+    }
+}
+
+
+

-In the interrupt callback function, judge whether the state is UART_EVENT_RX_FIFO, and if it is, pass the received byte to the shell_handler function.

+
1
shell_init();
+
+
+
    +
  • Call shell_init to initialize the shell components.

  • +
+
+
+

1.3.2. SHELL Command Registration

+

Shell command registration uses the following two macros

+
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
void hellowd()
+{
+    MSG("hello World\r\n");
+}
+
+int echo(int argc, char *argv[])
+{
+    MSG("%dparameter(s)\r\n", argc);
+
+    for (uint8_t i = 1; i < argc; i++) {
+        MSG("%s\r\n", argv[i]);
+    }
+
+    return 0;
+}
+
+SHELL_CMD_EXPORT(hellowd, hellowd test)
+SHELL_CMD_EXPORT(echo, echo test)
+
+
+
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
void hellowd()
+{
+    MSG("hello World\r\n");
+}
+
+int cmd_echo(int argc, char *argv[])
+{
+    MSG("%dparameter(s)\r\n", argc);
+
+    for (uint8_t i = 1; i < argc; i++) {
+        MSG("%s\r\n", argv[i]);
+    }
+
+    return 0;
+}
+
+SHELL_CMD_EXPORT_ALIAS(hellowd, hellwd,hellowd test)
+SHELL_CMD_EXPORT_ALIAS(cmd_echo, echo,echo test)
+
+
+
+
+
+

1.4. Compile and Program

+ +
1
+2
 $ cd <sdk_path>/bl_mcu_sdk
+ $ make BOARD=bl706_iot APP=shell SUPPORT_SHELL=y
+
+
+ +
+
+

1.5. Experimental Phenomena

+
+ +
+

shell test

+
+
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/samples/basic samples/adc/adc_key_demo.html b/docs/development_guide_en/build/html/samples/basic samples/adc/adc_key_demo.html new file mode 100644 index 00000000..912eb156 --- /dev/null +++ b/docs/development_guide_en/build/html/samples/basic samples/adc/adc_key_demo.html @@ -0,0 +1,427 @@ + + + + + + + + + + 8.1. ADC - Key Detection Voltage — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

8.1. ADC - Key Detection Voltage

+

This demo mainly introduces the key functions of the ADC. The ADC is used to detect the voltage value of the key input pin and judge whether the corresponding key is pressed according to different voltage divisions.

+
+

8.1.1. Hardware Connection

+

This demo is based on BL706_AVB:

+
   GPIO function         GPIO pin
+----------------------------------
+    ADC CH8      <-->     GPIO18
+
+
+

Voltage divider circuit:

+
+ +

adc key

+
+
+
+

8.1.2. Software Implementation

+
    +
  • For the code see examples/adc/adc_key

  • +
+
1
+2
#define BSP_ADC_CLOCK_SOURCE  ROOT_CLOCK_SOURCE_XCLK
+#define BSP_ADC_CLOCK_DIV  0
+
+
+
    +
  • Configure the ADC device clock source, see bsp/board/bl706_avb/clock_config.h

  • +
+
1
#define CONFIG_GPIO18_FUNC GPIO_FUN_ADC
+
+
+
    +
  • Configure ADC device multiplexing pins, see bsp/board/bl706_avb/pinmux_config.h

  • +
+
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
#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
+
+
+
    +
  • Enable BSP_USING_ADC0 and configure the ADC device, see bsp/board/bl706_iot/peripheral_config.h

  • +
+
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
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);
+
+
+
    +
  • First call the adc_register function to register the adc_key device, which is currently registered as ADC0

  • +
  • Then use the find function to find the handle corresponding to the device and save it in the adc_key handle

  • +
  • Then use device_open to open the adc_key device in polling mode, and call device_control to complete the ADC related configuration

  • +
  • Finally call adc_channel_start to enable ADC conversion

  • +
+
1
+2
+3
+4
+5
+6
+7
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));
+}
+
+
+
    +
  • Call device_read to read the adc_key device information and save it to the result_val structure

  • +
  • Call the get_adc_key_value function to get the current key value and voltage value

  • +
+
+
+

8.1.3. Compile and Program

+ +
1
+2
 $ cd <sdk_path>/bl_mcu_sdk
+ $ make BOARD=bl706_avb APP=adc_key
+
+
+ +
+
+

8.1.4. Experimental Phenomena

+

In this experiment, pressing SW1 ~ SW5 on the board in turn will get different voltage values:

+
    +
  • key 0: ~0V

  • +
  • key 1: ~0.1V

  • +
  • key 2: ~0.2V

  • +
  • key 3: ~0.3V

  • +
  • key 4: ~0.43V

  • +
+

operation result:

+
+../../../_images/adc_key_result.png +
+

Video display:

+
+
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/samples/basic samples/adc/index.html b/docs/development_guide_en/build/html/samples/basic samples/adc/index.html new file mode 100644 index 00000000..aef41c96 --- /dev/null +++ b/docs/development_guide_en/build/html/samples/basic samples/adc/index.html @@ -0,0 +1,253 @@ + + + + + + + + + + 8. ADC — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ + + + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/samples/basic samples/dma/dma_m2m_demo.html b/docs/development_guide_en/build/html/samples/basic samples/dma/dma_m2m_demo.html new file mode 100644 index 00000000..b5365b92 --- /dev/null +++ b/docs/development_guide_en/build/html/samples/basic samples/dma/dma_m2m_demo.html @@ -0,0 +1,404 @@ + + + + + + + + + + 5.1. DMA - Data Transfer Between RAM — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

5.1. DMA - Data Transfer Between RAM

+

This demo is based on the memory to memory mode of DMA for data transfer.

+
+

5.1.1. Hardware Connection

+

None

+
+
+

5.1.2. Software Implementation

+
    +
  • For the code see examples/dma/dma_m2m

  • +
+
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
#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
+
+
+
    +
  • Enable BSP_USING_DMA0_CH0 and configure the DMA device, see bsp/board/bl706_iot/peripheral_config.h

  • +
+
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
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);
+}
+
+
+
    +
  • First call the dma_register function to register a channel of the DMA device, currently register DMA_CH0

  • +
  • Then use the find function to find the handle corresponding to the device and save it in the dma handle

  • +
  • Finally use device_open to open the dma device in the default mode, call device_set_callback to register a dma channel 0 interrupt callback function, and call device_control to open the dma transmission completion interrupt

  • +
+
1
+2
dma_reload(dma,(uint32_t)dma_src_buffer,(uint32_t)dma_dst_buffer,8000);
+dma_channel_start(dma);
+
+
+
    +
  • Call the dma_reload function to supplement the configuration of dma channel 0. A part of the configuration has been supplemented in DMA0_CH0_CONFIG. Here we mainly supplement the source data address, destination data address and total transmission length

  • +
  • Call dma_channel_start to start dma transmission

  • +
+
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
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");
+    }
+
+}
+
+
+
    +
  • Check whether the data transmission is correct in the interrupt function

  • +
+
+
+

5.1.3. Compile and Program

+ +
1
+2
 $ cd <sdk_path>/bl_mcu_sdk
+ $ make BOARD=bl706_iot APP=dma_m2m
+
+
+ +
+
+

5.1.4. Experimental Phenomena

+

The data in the dma_src_buffer array is transferred to the dma_dst_buffer array through DMA channel 0 with a source 32-bit width and a target 32-bit width. After the data transfer is completed, the serial port prints dma transfer success.

+
+
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/samples/basic samples/dma/index.html b/docs/development_guide_en/build/html/samples/basic samples/dma/index.html new file mode 100644 index 00000000..54c3706b --- /dev/null +++ b/docs/development_guide_en/build/html/samples/basic samples/dma/index.html @@ -0,0 +1,253 @@ + + + + + + + + + + 5. DMA — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ + + + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/samples/basic samples/gpio/blink_demo.html b/docs/development_guide_en/build/html/samples/basic samples/gpio/blink_demo.html new file mode 100644 index 00000000..5176bfd2 --- /dev/null +++ b/docs/development_guide_en/build/html/samples/basic samples/gpio/blink_demo.html @@ -0,0 +1,321 @@ + + + + + + + + + + 1.1. GPIO output - Lamp LED — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

1.1. GPIO output - Lamp LED

+

This demo is based on the output mode of GPIO.

+
+

1.1.1. Hardware Connection

+

This demo is based on BL706_IOT and the connection method is as follows

+
   GPIO function         GPIO pin
+----------------------------------
+    D0      <-->     GPIO22
+    D1      <-->     GPIO29
+    D2      <-->     GPIO30
+    D3      <-->     GPIO31
+
+
+
+ +
+
+
+

1.1.2. Software Implementation

+
    +
  • See examples/gpio/gpio_blink for the software code

  • +
+
1
+2
+3
+4
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);
+
+
+
    +
  • Use the above code to configure GPIO22 GPIO29 GPIO30 GPIO31 to output pull-up mode.

  • +
+
1
gpio_write(GPIO_PIN_22, 0);
+
+
+
    +
  • Use the above code to modify the output level value.

  • +
+
+
+

1.1.3. Compile and Program

+ +
1
+2
 $ cd <sdk_path>/bl_mcu_sdk
+ $ make BOARD=bl706_iot APP=gpio_blink
+
+
+ +
+
+

1.1.4. Experimental Phenomena

+

Video display:

+
+
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/samples/basic samples/gpio/button_demo.html b/docs/development_guide_en/build/html/samples/basic samples/gpio/button_demo.html new file mode 100644 index 00000000..544c341e --- /dev/null +++ b/docs/development_guide_en/build/html/samples/basic samples/gpio/button_demo.html @@ -0,0 +1,320 @@ + + + + + + + + + + 1.2. GPIO interrupt - Button detection — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

1.2. GPIO interrupt - Button detection

+

This demo is based on GPIO external interrupt mode.

+
+

1.2.1. Hardware Connection

+

This demo is based on BL706_IOT, add the button circuit by yourself, the connection method is as follows

+
   GPIO function         GPIO pin
+----------------------------------
+    SW1      <-->     GPIO11
+
+
+
+ +
+
+
+

1.2.2. Software Implementation

+
    +
  • See examples/gpio/gpio_int for the software code

  • +
+
1
+2
+3
+4
+5
+6
+7
+8
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);
+
+
+
    +
  • Use the above code to configure GPIO11 as the GPIO rising edge interrupt trigger mode, and register the interrupt callback function.

  • +
+
+
+

1.2.3. Compile and Program

+ +
1
+2
 $ cd <sdk_path>/bl_mcu_sdk
+ $ make BOARD=bl706_iot APP=gpio_int
+
+
+ +
+
+

1.2.4. Experimental Phenomena

+

When the button is pressed, the serial port will print "gpio rising trigger !"

+
+
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/samples/basic samples/gpio/index.html b/docs/development_guide_en/build/html/samples/basic samples/gpio/index.html new file mode 100644 index 00000000..c7e41fe1 --- /dev/null +++ b/docs/development_guide_en/build/html/samples/basic samples/gpio/index.html @@ -0,0 +1,255 @@ + + + + + + + + + + 1. GPIO — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+ + +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/samples/basic samples/i2c/i2c_eeprom_demo.html b/docs/development_guide_en/build/html/samples/basic samples/i2c/i2c_eeprom_demo.html new file mode 100644 index 00000000..21926f5a --- /dev/null +++ b/docs/development_guide_en/build/html/samples/basic samples/i2c/i2c_eeprom_demo.html @@ -0,0 +1,397 @@ + + + + + + + + + + 7.1. I2C - AT24CXX read and write — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

7.1. I2C - AT24CXX read and write

+
+

7.1.1. Hardware Connection

+

This demo is based on BL706_IOT, add AT24CXX circuit by yourself, the connection method is as follows

+
   GPIO function         GPIO pin
+----------------------------------
+    I2C_SCL      <-->     GPIO11
+    I2C_SDA      <-->     GPIO16
+
+
+
+
+

7.1.2. Software Implementation

+
    +
  • See examples/i2c/i2c_at24cxx for the software code

  • +
+
1
+2
#define BSP_I2C_CLOCK_SOURCE  ROOT_CLOCK_SOURCE_BCLK
+#define BSP_I2C_CLOCK_DIV  0
+
+
+
    +
  • Configure the I2C device clock source, see bsp/board/bl706_iot/clock_config.h

  • +
+
1
+2
#define CONFIG_GPIO11_FUNC GPIO_FUN_I2C
+#define CONFIG_GPIO16_FUNC GPIO_FUN_I2C
+
+
+
    +
  • Configure I2C device multiplexing pins, see bsp/board/bl706_iot/peripheral_config.h

  • +
+
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
#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
+
+
+
    +
  • Enable BSP_USING_I2C0 and configure I2C device, see bsp/board/bl706_iot/peripheral_config.h

  • +
+
1
+2
+3
+4
+5
+6
+7
+8
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);
+}
+
+
+
    +
  • First call the i2c_register function to register the I2C device, currently register I2C0

  • +
  • Then use the find function to find the handle corresponding to the device and save it in the i2c0 handle

  • +
  • Finally use device_open to open the I2C0 device in the default mode

  • +
+
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
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]);
+
+
+
    +
  • Call i2c_transfer to transfer two msg, one msg represents writing 8-byte data to eeprom, and one msg represents reading 8-byte data from eeprom

  • +
+
+
+

7.1.3. Compile and Program

+ +
1
+2
 $ cd <sdk_path>/bl_mcu_sdk
+ $ make BOARD=bl706_iot APP=i2c_at24cxx
+
+
+ +
+
+

7.1.4. Experimental Phenomena

+
+
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/samples/basic samples/i2c/index.html b/docs/development_guide_en/build/html/samples/basic samples/i2c/index.html new file mode 100644 index 00000000..90f345b5 --- /dev/null +++ b/docs/development_guide_en/build/html/samples/basic samples/i2c/index.html @@ -0,0 +1,253 @@ + + + + + + + + + + 7. I2C — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ + + + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/samples/basic samples/mtimer/index.html b/docs/development_guide_en/build/html/samples/basic samples/mtimer/index.html new file mode 100644 index 00000000..d382c862 --- /dev/null +++ b/docs/development_guide_en/build/html/samples/basic samples/mtimer/index.html @@ -0,0 +1,253 @@ + + + + + + + + + + 4. MTIMER — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

4. MTIMER

+ +
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/samples/basic samples/mtimer/mtimer_demo.html b/docs/development_guide_en/build/html/samples/basic samples/mtimer/mtimer_demo.html new file mode 100644 index 00000000..3e9a9290 --- /dev/null +++ b/docs/development_guide_en/build/html/samples/basic samples/mtimer/mtimer_demo.html @@ -0,0 +1,315 @@ + + + + + + + + + + 4.1. MTIMER - System Timer — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

4.1. MTIMER - System Timer

+

This demo is based on a 64-bit timer (MTIMER) that comes with the risc-v kernel. This demo can provide reference for os tick.

+
+

4.1.1. Hardware Connection

+

None

+
+
+

4.1.2. Software Implementation

+
    +
  • See examples/systick for the software code

  • +
+
+

Note

+

The mtimer clock defaults to 1M after frequency division, which is convenient for later use and reduces calculation time.

+
+
1
+2
+3
+4
+5
+6
+7
+8
void systick_isr()
+{
+    static uint32_t tick=0;
+    tick++;
+    MSG("tick:%d\r\n",tick);
+}
+
+bflb_platform_set_alarm_time(1000000,systick_isr);
+
+
+
    +
  • Use the above code to set the mtimer timing time to 1s, and register the interrupt callback function.

  • +
+
+
+

4.1.3. Compile and Program

+ +
1
+2
 $ cd <sdk_path>/bl_mcu_sdk
+ $ make BOARD=bl706_iot APP=systick
+
+
+ +
+
+

4.1.4. Experimental Phenomena

+

The tick value is incremented by 1 per second and printed through the serial port.

+
+
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/samples/basic samples/pwm/index.html b/docs/development_guide_en/build/html/samples/basic samples/pwm/index.html new file mode 100644 index 00000000..294f095b --- /dev/null +++ b/docs/development_guide_en/build/html/samples/basic samples/pwm/index.html @@ -0,0 +1,255 @@ + + + + + + + + + + 3. PWM — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+ + +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/samples/basic samples/pwm/pwm_breath_demo.html b/docs/development_guide_en/build/html/samples/basic samples/pwm/pwm_breath_demo.html new file mode 100644 index 00000000..f443b24a --- /dev/null +++ b/docs/development_guide_en/build/html/samples/basic samples/pwm/pwm_breath_demo.html @@ -0,0 +1,399 @@ + + + + + + + + + + 3.1. PWM - Breathing LED — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

3.1. PWM - Breathing LED

+
+

This demo is based on PWM polling mode.

+
+
+

3.1.1. Hardware Connection

+

This demo is based on BL706_IOT, and the connection method is as follows

+
   GPIO function         GPIO pin
+----------------------------------
+    PWM_CH2      <-->     GPIO22
+
+
+
+ +
+
+
+

3.1.2. Software Implementation

+

-See examples/pwm/pwm_breath_led for the software code

+
1
+2
#define BSP_PWM_CLOCK_SOURCE  ROOT_CLOCK_SOURCE_XCLK
+#define BSP_PWM_CLOCK_DIV  1
+
+
+
    +
  • Configure the PWM device clock source, see bsp/board/bl706_iot/clock_config.h

  • +
+
1
#define CONFIG_GPIO22_FUNC GPIO_FUN_PWM
+
+
+
    +
  • Configure PWM device multiplexing pins, see bsp/board/bl706_iot/pinmux_config.h

  • +
+
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
#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
+
+
+
    +
  • Enable BSP_USING_PWM_CH2 and configure PWM device configuration, see bsp/board/bl706_iot/peripheral_config.h

  • +
+
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
pwm_register(PWM_CH2_INDEX, "led_breath", DEVICE_OFLAG_RDWR);
+
+struct device *led_breath = device_find("led_breath");
+
+if (led_breath) {
+    PWM_DEV(led_breath)->period = 32; //frequence = 32M/1/32 = 1Mhz
+    PWM_DEV(led_breath)->threshold_low = 16;
+    PWM_DEV(led_breath)->threshold_high = 32;
+    device_open(led_breath, DEVICE_OFLAG_STREAM_TX);
+    pwm_channel_start(led_breath);
+}
+
+
+
    +
  • First call the pwm_register function to register a channel of the PWM device, currently register PWM_CH2

  • +
  • Then use the find function to find the handle corresponding to the device and save it in the led_breath handle

  • +
  • Set the frequency of PWM_CH2 to 1Mhz, and the duty cycle to 50%

  • +
  • Use device_open to open the led_breath device in polling mode

  • +
+
1
+2
+3
+4
+5
+6
+7
+8
+9
    for (pwm_cfg.threshold_high = 0; pwm_cfg.threshold_high <= 32; pwm_cfg.threshold_high++) {
+        device_control(led_breath, DEIVCE_CTRL_PWM_DUTYCYCLE_CONFIG, &pwm_cfg);
+        bflb_platform_delay_ms(50);
+    }
+
+    for (pwm_cfg.threshold_high = 32; 0 <= pwm_cfg.threshold_high && pwm_cfg.threshold_high <= 32; pwm_cfg.threshold_high--) {
+        device_control(led_breath, DEIVCE_CTRL_PWM_DUTYCYCLE_CONFIG, &pwm_cfg);
+        bflb_platform_delay_ms(50);
+    }
+
+
+
    +
  • Use the device_contorl function with the DEIVCE_CTRL_PWM_DUTYCYCLE_CONFIG instruction to modify the duty cycle of the current PWM channel.

  • +
+
+
+

3.1.3. Compile and Program

+ +
1
+2
 $ cd <sdk_path>/bl_mcu_sdk
+ $ make BOARD=bl706_iot APP=pwm_breath_led
+
+
+ +
+
+

3.1.4. Experimental Phenomena

+
+ +
+

pwm breath led!

+

Video display:

+
+
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/samples/basic samples/pwm/pwm_step_motor.html b/docs/development_guide_en/build/html/samples/basic samples/pwm/pwm_step_motor.html new file mode 100644 index 00000000..3a06d718 --- /dev/null +++ b/docs/development_guide_en/build/html/samples/basic samples/pwm/pwm_step_motor.html @@ -0,0 +1,666 @@ + + + + + + + + + + 3.2. PWM - 驱动步进电机 — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

3.2. PWM - 驱动步进电机

+

步进电机是一种将电脉冲转化为角位移的执行机构。当步进驱动器接收到一个脉冲信号,它就驱动步进电机按设定的方向转动一个固定的角度(及步进角)。可以通过控制脉冲个来控制角位移量,从而达到准确定位的目的;同时可以通过控制脉冲频率来控制电机转动的速度和加速度,从而达到调速的目的。

+

本 demo 采用步进电机 28BYJ48 型四相八拍电机,使用 ULN2003 芯片驱动,电压为 DC5V—DC12V。当对步进电机施加一系列连续不断的控制脉冲时,它可以连续不断地转动。每一个脉冲信号对应步进电机的某一相或两相绕组的通电状态改变一次,也就对应转子转过一定的角度(一个步距角)。当通电状态的改变完成一个循环时,转子转过一个齿距。

+
+ +

28BYJ48

+
+
+ +

ULN2003

+
+

这个步进电机内部有个真正的步进马达转子,每一个脉冲能使这个真正的转子转动5.625°,看下图的数据表格中的减速比是1:64,意思是这个真正的步进马达转子转动64周才能让输出轴转动1周,因此下图的表格中步距角度才写的是5.625°/64,表明的意思是一个脉冲可以让输出轴转动5.625°/64的角度。所以要让马达转一周(360°), 则需要360/5.625*64=4096个脉冲。 +脉冲(或拍)的数量决定转动的角度,单位时间内脉冲(或拍)的数量决定转动的速度

+
+ +
+

四相步进电机可以在不同的通电方式下运行,常见的通电方式有如下三种:

+
    +
  • 一相励磁:单(单相绕组通电)四拍(A+,B+,A-,B-……)

  • +
+
+ +
+
    +
  • 二相励磁:双(双相绕组通电)四拍(A+B+,B+A-,A-B-,B-A+……)

  • +
+
+ +
+
    +
  • 一二相励磁:八拍(A+B+,B+,B+A-,A-,A-B-,B-,B-A+,A+……)

  • +
+
+ +
+
+

3.2.1. 硬件连接

+

本 demo 基于BL706_IOT开发板,连接方式如下

+
   GPIO function         GPIO pin
+----------------------------------
+    PWM_CH0      <-->     GPIO10
+    PWM_CH1      <-->     GPIO11
+    PWM_CH2      <-->     GPIO12
+    PWM_CH3      <-->     GPIO3
+
+
+
+ +

参考电路

+
+
+
+

3.2.2. 软件实现

+
    +
  • 软件代码见 examples/pwm/pwm_step_motor

  • +
+
1
+2
#define BSP_PWM_CLOCK_SOURCE  ROOT_CLOCK_SOURCE_RC_32K
+#define BSP_PWM_CLOCK_DIV  32
+
+
+
    +
  • 配置 PWM 设备时钟源,见 bsp/board/bl706_iot/clock_config.h

  • +
+
1
+2
+3
+4
#define CONFIG_GPIO3_FUNC GPIO_FUN_PWM
+#define CONFIG_GPIO10_FUNC GPIO_FUN_PWM
+#define CONFIG_GPIO11_FUNC GPIO_FUN_PWM
+#define CONFIG_GPIO12_FUNC GPIO_FUN_PWM
+
+
+
    +
  • 配置 PWM 设备复用引脚,见 bsp/board/bl706_iot/pinmux_config.h

  • +
+
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
#define BSP_USING_PWM_CH0
+#define BSP_USING_PWM_CH1
+#define BSP_USING_PWM_CH2
+#define BSP_USING_PWM_CH3
+
+#if defined(BSP_USING_PWM_CH0)
+#ifndef PWM_CH0_CONFIG
+#define PWM_CH0_CONFIG                   \
+    {                                    \
+        .ch = 0,                         \
+        .polarity_invert_mode = DISABLE, \
+        .period = 0,                     \
+        .threshold_low = 0,              \
+        .threshold_high = 0,             \
+        .it_pulse_count = 0,             \
+    }
+#endif
+#endif
+
+#if defined(BSP_USING_PWM_CH1)
+#ifndef PWM_CH1_CONFIG
+#define PWM_CH1_CONFIG                   \
+    {                                    \
+        .ch = 1,                         \
+        .polarity_invert_mode = DISABLE, \
+        .period = 0,                     \
+        .threshold_low = 0,              \
+        .threshold_high = 0,             \
+        .it_pulse_count = 0,             \
+    }
+#endif
+#endif
+
+#if defined(BSP_USING_PWM_CH2)
+#ifndef PWM_CH2_CONFIG
+#define PWM_CH2_CONFIG                   \
+    {                                    \
+        .ch = 2,                         \
+        .polarity_invert_mode = DISABLE, \
+        .period = 0,                     \
+        .threshold_low = 0,              \
+        .threshold_high = 0,             \
+        .it_pulse_count = 0,             \
+    }
+#endif
+#endif
+
+#if defined(BSP_USING_PWM_CH3)
+#ifndef PWM_CH3_CONFIG
+#define PWM_CH3_CONFIG                   \
+    {                                    \
+        .ch = 3,                         \
+        .polarity_invert_mode = DISABLE, \
+        .period = 0,                     \
+        .threshold_low = 0,              \
+        .threshold_high = 0,             \
+        .it_pulse_count = 0,             \
+    }
+#endif
+#endif
+
+
+
    +
  • 使能 BSP_USING_PWM_CH0, BSP_USING_PWM_CH1 , BSP_USING_PWM_CH2, BSP_USING_PWM_CH3 并配置 PWM 设备配置,见 bsp/board/bl706_iot/peripheral_config.h

  • +
+
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
pwm_register(PWM_CH0_INDEX, "motor_ch0", DEVICE_OFLAG_RDWR);
+pwm_register(PWM_CH1_INDEX, "motor_ch1", DEVICE_OFLAG_RDWR);
+pwm_register(PWM_CH2_INDEX, "motor_ch2", DEVICE_OFLAG_RDWR);
+pwm_register(PWM_CH3_INDEX, "motor_ch3", DEVICE_OFLAG_RDWR);
+
+motor_ch0 = device_find("motor_ch0");
+motor_ch1 = device_find("motor_ch1");
+motor_ch2 = device_find("motor_ch2");
+motor_ch3 = device_find("motor_ch3");
+
+if (motor_ch0) {
+    PWM_DEV(motor_ch0)->period = 8; //frequence = 32K/160/8 = 25hz
+    PWM_DEV(motor_ch0)->threshold_low = 2;
+    PWM_DEV(motor_ch0)->threshold_high = 7;
+    PWM_DEV(motor_ch0)->polarity_invert_mode = ENABLE;
+    device_open(motor_ch0, DEVICE_OFLAG_STREAM_TX);
+}
+if (motor_ch1) {
+    PWM_DEV(motor_ch1)->period = 8; //frequence = 32K/160/8 = 25hz
+    PWM_DEV(motor_ch1)->threshold_low = 1;
+    PWM_DEV(motor_ch1)->threshold_high = 4;
+    device_open(motor_ch1, DEVICE_OFLAG_STREAM_TX);
+}
+if (motor_ch2) {
+    PWM_DEV(motor_ch2)->period = 8; //frequence = 32K/160/8 = 25hz
+    PWM_DEV(motor_ch2)->threshold_low = 3;
+    PWM_DEV(motor_ch2)->threshold_high = 6;
+    device_open(motor_ch2, DEVICE_OFLAG_STREAM_TX);
+}
+if (motor_ch3) {
+    PWM_DEV(motor_ch3)->period = 8; //frequence = 32K/160/8 = 25hz
+    PWM_DEV(motor_ch3)->threshold_low = 5;
+    PWM_DEV(motor_ch3)->threshold_high = 8;
+    device_open(motor_ch3, DEVICE_OFLAG_STREAM_TX);
+}
+pwm_channel_start(motor_ch0);
+pwm_channel_start(motor_ch1);
+pwm_channel_start(motor_ch2);
+pwm_channel_start(motor_ch3);
+
+
+
    +
  • 首先调用 pwm_register 函数注册 PWM 设备的一个通道,当前注册 PWM 通道0/1/2/3

  • +
  • 然后通过 find 函数找到设备对应的句柄,保存于4个句柄中

  • +
  • 设置 4个通道 的频率为 125hz,占空比为37.5%

  • +
  • 使用 device_open 以轮询模式来打开 4个通道

  • +
+
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
enum motor_dir_type {
+    CW,
+    CCW,
+    STOP
+};
+
+void motor_set_dir(enum motor_dir_type dir)
+{
+    pwm_dutycycle_config_t pwm_cfg[4];
+
+    if (dir == CW) {
+        pwm_cfg[0].threshold_low = 2;
+        pwm_cfg[0].threshold_high = 7;
+        pwm_cfg[1].threshold_low = 1;
+        pwm_cfg[1].threshold_high = 4;
+        pwm_cfg[2].threshold_low = 3;
+        pwm_cfg[2].threshold_high = 6;
+        pwm_cfg[3].threshold_low = 5;
+        pwm_cfg[3].threshold_high = 8;
+    }
+
+    else if (dir == CCW) {
+        pwm_cfg[0].threshold_low = 2;
+        pwm_cfg[0].threshold_high = 7;
+        pwm_cfg[1].threshold_low = 5;
+        pwm_cfg[1].threshold_high = 8;
+        pwm_cfg[2].threshold_low = 3;
+        pwm_cfg[2].threshold_high = 6;
+        pwm_cfg[3].threshold_low = 1;
+        pwm_cfg[3].threshold_high = 4;
+    } else if (dir == STOP) {
+        pwm_cfg[0].threshold_low = 0;
+        pwm_cfg[0].threshold_high = 0;
+        pwm_cfg[1].threshold_low = 0;
+        pwm_cfg[1].threshold_high = 0;
+        pwm_cfg[2].threshold_low = 0;
+        pwm_cfg[2].threshold_high = 0;
+        pwm_cfg[3].threshold_low = 0;
+        pwm_cfg[3].threshold_high = 0;
+    }
+    device_control(motor_ch0, DEIVCE_CTRL_PWM_DUTYCYCLE_CONFIG, &pwm_cfg[0]);
+    device_control(motor_ch1, DEIVCE_CTRL_PWM_DUTYCYCLE_CONFIG, &pwm_cfg[1]);
+    device_control(motor_ch2, DEIVCE_CTRL_PWM_DUTYCYCLE_CONFIG, &pwm_cfg[2]);
+    device_control(motor_ch3, DEIVCE_CTRL_PWM_DUTYCYCLE_CONFIG, &pwm_cfg[3]);
+}
+
+
+
    +
  • 使用 device_contorl 函数,配合 DEIVCE_CTRL_PWM_DUTYCYCLE_CONFIG 指令,修改4个 PWM 通道的的高低阈值。

  • +
+
+

Note

+

该函数的功能主要用于切换步进电机的方向

+
+
+
+

3.2.3. 编译和烧录

+ +
1
+2
 $ cd <sdk_path>/bl_mcu_sdk
+ $ make BOARD=bl706_iot APP=pwm_step_motor
+
+
+ +
+
+

3.2.4. 实验现象

+
+ +
+
+
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/samples/basic samples/spi/index.html b/docs/development_guide_en/build/html/samples/basic samples/spi/index.html new file mode 100644 index 00000000..1349f4e9 --- /dev/null +++ b/docs/development_guide_en/build/html/samples/basic samples/spi/index.html @@ -0,0 +1,253 @@ + + + + + + + + + + 6. SPI — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

6. SPI

+ +
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/samples/basic samples/spi/spi_lcd_demo.html b/docs/development_guide_en/build/html/samples/basic samples/spi/spi_lcd_demo.html new file mode 100644 index 00000000..571627e3 --- /dev/null +++ b/docs/development_guide_en/build/html/samples/basic samples/spi/spi_lcd_demo.html @@ -0,0 +1,459 @@ + + + + + + + + + + 6.1. SPI - TFT LCD Display — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

6.1. SPI - TFT LCD Display

+
+

6.1.1. Hardware Connection

+

This demo is based on BL706_AVB, and the connection method is as follows

+
   GPIO function         GPIO pin
+----------------------------------
+    LCD_CS      <-->     GPIO10
+    LCD_DC      <-->     GPIO22
+    SPI_SCK     <-->     GPIO19
+    SPI_MISO    <-->     GPIO20
+    SPI_MOSI    <-->     GPIO21
+
+
+
+
+

6.1.2. Software Implementation

+
    +
  • See examples/spi/spi_lcd for the software code

  • +
+
1
+2
#define BSP_SPI_CLOCK_SOURCE  ROOT_CLOCK_SOURCE_BCLK
+#define BSP_SPI_CLOCK_DIV  0
+
+
+
    +
  • Configure the SPI device clock source, see bsp/board/bl706_avb/clock_config.h

  • +
+
1
+2
+3
#define CONFIG_GPIO19_FUNC GPIO_FUN_SPI
+#define CONFIG_GPIO20_FUNC GPIO_FUN_SPI
+#define CONFIG_GPIO21_FUNC GPIO_FUN_SPI
+
+
+
    +
  • Configure SPI device multiplexing pins, see bsp/board/bl706_avb/pinmux_config.h

  • +
+
+

Note

+

bsp/board/bl706_avb/pinmux_config.h is currently used by all demo demos, so you need to select PINMUX_SELECT as PINMUX_LVGL, and open one of the demos

+
+
+

Note

+

In order to adapt to the bl702_avb hardware, the MOSI and MISO of SPI have been swapped by default. If you want to restore the default, modify SPI_SWAP_ENABLE in drivers/bl702_driver/hal_drv/default_config/spi_config.h to 0

+
+
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
#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
+
+
+
    +
  • Enable BSP_USING_SPI0 and configure SPI device, see bsp/board/bl706_avb/peripheral_config.h

  • +
+
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
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);
+}
+
+
+
    +
  • Configure the LCD_CS and LCD_DC pins as output mode and pull up

  • +
  • Call spi_register function to register SPI device, currently register SPI0

  • +
  • Then use the find function to find the handle corresponding to the device and save it in the spi0 handle

  • +
  • Finally use device_open to open the spi0 device in polling sending mode

  • +
+
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
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;
+}
+
+
+
    +
  • Provide interface for LCD display driver

  • +
+
+
+

6.1.3. Compile and Program

+ +
1
+2
 $ cd <sdk_path>/bl_mcu_sdk
+ $ make BOARD=bl706_avb APP=spi_lcd
+
+
+ +
+
+

6.1.4. Experimental Phenomena

+
+ +
+

spi display!

+
+
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/samples/basic samples/timer/index.html b/docs/development_guide_en/build/html/samples/basic samples/timer/index.html new file mode 100644 index 00000000..fa9d55f8 --- /dev/null +++ b/docs/development_guide_en/build/html/samples/basic samples/timer/index.html @@ -0,0 +1,253 @@ + + + + + + + + + + 9. TIMER — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ + + + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/samples/basic samples/timer/timer_interrupt_demo.html b/docs/development_guide_en/build/html/samples/basic samples/timer/timer_interrupt_demo.html new file mode 100644 index 00000000..f5cb759e --- /dev/null +++ b/docs/development_guide_en/build/html/samples/basic samples/timer/timer_interrupt_demo.html @@ -0,0 +1,396 @@ + + + + + + + + + + 9.1. TIMER - Second Timing Interrupt — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

9.1. TIMER - Second Timing Interrupt

+
+

This demo is based on TIMER interrupt mode with second timing.

+
+
+

9.1.1. Hardware Connection

+

None

+
+
+

9.1.2. Software Implementation

+
    +
  • See examples/timer/timer_int for the software code

  • +
+
1
+2
#define BSP_TIMER0_CLOCK_SOURCE ROOT_CLOCK_SOURCE_FCLK
+#define BSP_TIMER0_CLOCK_DIV    0
+
+
+
    +
  • Configure TIMER device clock source,see bsp/board/bl706_iot/clock_config.h

  • +
+
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
#define BSP_USING_TIMER0
+
+#if defined(BSP_USING_TIMER0)
+#ifndef TIMER0_CONFIG
+#define TIMER0_CONFIG                           \
+    {                                           \
+        .id = 0,                                \
+        .cnt_mode = TIMER_CNT_PRELOAD,          \
+        .trigger = TIMER_PRELOAD_TRIGGER_COMP2, \
+        .reload = 0,                            \
+        .timeout1 = 1000000,                    \
+        .timeout2 = 2000000,                    \
+        .timeout3 = 3000000,                    \
+    }
+#endif
+#endif
+
+
+
    +
  • Enable BSP_USING_TIMER0 and configure TIMER0 device,see bsp/board/bl706_iot/peripheral_config.h

  • +
+
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
timer_register(TIMER0_INDEX, "timer0");
+
+timer0 = device_find("timer0");
+
+if (timer0) {
+    device_open(timer0, DEVICE_OFLAG_INT_TX); /* 1s,2s,3s timing*/
+    device_set_callback(timer0, timer0_irq_callback);
+    device_control(timer0, DEVICE_CTRL_SET_INT, (void *)(TIMER_COMP0_IT | TIMER_COMP1_IT | TIMER_COMP2_IT));
+} else {
+    MSG("timer device open failed! \n");
+}
+
+
+
    +
  • Call timer_register function to register TIMER device, currently register TIMER0

  • +
  • Then use the find function to find the handle corresponding to the device and save it in the timer0 handle

  • +
  • Finally use device_open to open the timer0 device in interrupt mode

  • +
  • Call device_set_callback to register irq callback named timer0_irq_callback. Call device_control to enable irq and configure timing period.

  • +
+
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
void timer0_irq_callback(struct device *dev, void *args, uint32_t size, uint32_t state)
+{
+    if (state == TIMER_EVENT_COMP0) {
+        MSG("timer event comp0! \r\n");
+    } else if (state == TIMER_EVENT_COMP1) {
+        MSG("timer event comp1! \r\n");
+    } else if (state == TIMER_EVENT_COMP2) {
+        BL_CASE_SUCCESS;
+        timer_timeout_cfg_t cfg = { 2, 12000000 }; /*modify compare id 2 timeout 12s*/
+        device_write(dev, 0, &cfg, sizeof(timer_timeout_cfg_t));
+        MSG("timer event comp2! \r\n");
+    }
+}
+
+
+
    +
  • In irq callback,try to determine whether compare id flag is coming.

  • +
  • Call device_write to modify compare id 2 timeout with 12s.

  • +
+
+
+

9.1.3. Compile and Program

+ +
1
+2
 $ cd <sdk_path>/bl_mcu_sdk
+ $ make BOARD=bl706_iot APP=timer_int
+
+
+ +
+
+

9.1.4. Experimental Phenomena

+
+
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/samples/basic samples/uart/index.html b/docs/development_guide_en/build/html/samples/basic samples/uart/index.html new file mode 100644 index 00000000..30f4a9cc --- /dev/null +++ b/docs/development_guide_en/build/html/samples/basic samples/uart/index.html @@ -0,0 +1,253 @@ + + + + + + + + + + 2. UART — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

2. UART

+ +
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/samples/basic samples/uart/uart_loopback_demo.html b/docs/development_guide_en/build/html/samples/basic samples/uart/uart_loopback_demo.html new file mode 100644 index 00000000..6496c9e3 --- /dev/null +++ b/docs/development_guide_en/build/html/samples/basic samples/uart/uart_loopback_demo.html @@ -0,0 +1,425 @@ + + + + + + + + + + 2.1. UART - Loopback — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

2.1. UART - Loopback

+

This demo is based on UART polling sending and receiving FIFO interrupt mode.

+
+

2.1.1. Hardware Connection

+

This demo is based on BL706_IOT and the connection method is as follows

+
   GPIO function         GPIO pin
+----------------------------------
+    UART0_TX      <-->     GPIO14
+    UART0_RX      <-->     GPIO15
+
+
+
+
+

2.1.2. Software Implementation

+
    +
  • See examples/uart/uart_echo for the software code

  • +
+
1
+2
#define BSP_UART_CLOCK_SOURCE  ROOT_CLOCK_SOURCE_PLL_96M
+#define BSP_UART_CLOCK_DIV  0
+
+
+

-Configure the UART device clock source, see bsp/board/bl706_iot/clock_config.h

+
1
+2
#define CONFIG_GPIO14_FUNC GPIO_FUN_UART0_TX
+#define CONFIG_GPIO15_FUNC GPIO_FUN_UART0_RX
+
+
+
    +
  • Configure UART device multiplexing pins, see bsp/board/bl706_iot/pinmux_config.h

  • +
+
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
#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
+
+
+
    +
  • Enable BSP_USING_UART0 and configure the UART device, see bsp/board/bl706_iot/peripheral_config.h

  • +
+
1
bflb_platform_init();
+
+
+
    +
  • In the bflb_platform_init function, we have registered and opened a serial port device for debugging, to provide users with a basic function of MSG for printing out messages. The specific implementation is as follows

  • +
+
1
+2
+3
+4
+5
+6
+7
+8
+9
    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, NULL);
+        device_control(uart, DEVICE_CTRL_CLR_INT, (void *)(UART_RX_FIFO_IT));
+    }
+
+
+
    +
  • First call the uart_register function to register the UART device, currently register UART0

  • +
  • Then use the find function to find the handle corresponding to the device and save it in the uart handle

  • +
  • Finally use device_open to open the uart device with polling sending and interrupt receiving, the interrupt is closed by default and the receiving interrupt callback function is not registered

  • +
+
1
+2
+3
+4
+5
if (uart)
+{
+    device_set_callback(uart, uart_irq_callback);
+    device_control(uart, DEVICE_CTRL_SET_INT, (void *)(UART_RX_FIFO_IT|UART_RTO_IT));
+}
+
+
+
    +
  • Register the user-specified UART0 receiving interrupt service function through the device_set_callback function. Open the RX_FIFO and RTO interrupts through the device_control function

  • +
+
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
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);
+    }
+}
+
+
+
    +
  • This function is the interrupt service function of the example, and its function is to send out the received data.

    +
    +
      +
    • state will return the interrupt type of the UART device

    • +
    • args contains the return data pointer

    • +
    • size contains the length of the returned data

    • +
    • dev is the handle of the interrupted uart device

    • +
    +
    +
  • +
  • When an interrupt occurs, the device_write function will be called to send the received data back.

  • +
+
+
+

2.1.3. Compile and Program

+ +
1
+2
 $ cd <sdk_path>/bl_mcu_sdk
+ $ make BOARD=bl706_iot APP=uart_echo
+
+
+ +
+
+

2.1.4. Experimental Phenomena

+

Video display:

+
+
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/search.html b/docs/development_guide_en/build/html/search.html new file mode 100644 index 00000000..cb67b0b2 --- /dev/null +++ b/docs/development_guide_en/build/html/search.html @@ -0,0 +1,253 @@ + + + + + + + + + + Search — BL_MCU_SDK Development Guide 0.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
    + +
  • »
  • + +
  • Search
  • + + +
  • + +
  • + +
+ + +
+
+
+
+ + + + +
+ +
+ +
+ +
+
+ +
+ +
+

+ © Copyright 2021, BouffaloLab Co., Ltd. + +

+
+ + + + Built with Sphinx using a + + theme + + provided by Read the Docs. + +
+
+
+ +
+ +
+ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/development_guide_en/build/html/searchindex.js b/docs/development_guide_en/build/html/searchindex.js new file mode 100644 index 00000000..095b140e --- /dev/null +++ b/docs/development_guide_en/build/html/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({docnames:["api_reference/api_overview","api_reference/bluetooth/api_ble","api_reference/peripheral/api_adc","api_reference/peripheral/api_clock","api_reference/peripheral/api_dac","api_reference/peripheral/api_dma","api_reference/peripheral/api_gpio","api_reference/peripheral/api_i2c","api_reference/peripheral/api_pwm","api_reference/peripheral/api_spi","api_reference/peripheral/api_timer","api_reference/peripheral/api_uart","api_reference/peripheral/index","get_started/Linux_quick_start_ubuntu","get_started/Windows_quick_start_cdk","get_started/Windows_quick_start_eclipse","get_started/bl_dev_cube","get_started/board","get_started/cdk_ck_link","get_started/cdk_new_project_quick_start","get_started/cdk_rv_debugger_plus","get_started/cmake_quick_start","get_started/connecting_hardware","get_started/get_started","get_started/index","index","samples/advance samples/ble_scan_demo","samples/advance samples/boot2_iap_info","samples/advance samples/fatfs_demo","samples/advance samples/lowpower_demo","samples/advance samples/shell_demo","samples/basic samples/adc/adc_key_demo","samples/basic samples/adc/index","samples/basic samples/dma/dma_m2m_demo","samples/basic samples/dma/index","samples/basic samples/gpio/blink_demo","samples/basic samples/gpio/button_demo","samples/basic samples/gpio/index","samples/basic samples/i2c/i2c_eeprom_demo","samples/basic samples/i2c/index","samples/basic samples/mtimer/index","samples/basic samples/mtimer/mtimer_demo","samples/basic samples/pwm/index","samples/basic samples/pwm/pwm_breath_demo","samples/basic samples/pwm/pwm_step_motor","samples/basic samples/spi/index","samples/basic samples/spi/spi_lcd_demo","samples/basic samples/timer/index","samples/basic samples/timer/timer_interrupt_demo","samples/basic samples/uart/index","samples/basic samples/uart/uart_loopback_demo"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":3,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":2,"sphinx.domains.rst":2,"sphinx.domains.std":2,sphinx:56},filenames:["api_reference\\api_overview.rst","api_reference\\bluetooth\\api_ble.rst","api_reference\\peripheral\\api_adc.rst","api_reference\\peripheral\\api_clock.rst","api_reference\\peripheral\\api_dac.rst","api_reference\\peripheral\\api_dma.rst","api_reference\\peripheral\\api_gpio.rst","api_reference\\peripheral\\api_i2c.rst","api_reference\\peripheral\\api_pwm.rst","api_reference\\peripheral\\api_spi.rst","api_reference\\peripheral\\api_timer.rst","api_reference\\peripheral\\api_uart.rst","api_reference\\peripheral\\index.rst","get_started\\Linux_quick_start_ubuntu.rst","get_started\\Windows_quick_start_cdk.rst","get_started\\Windows_quick_start_eclipse.rst","get_started\\bl_dev_cube.rst","get_started\\board.rst","get_started\\cdk_ck_link.rst","get_started\\cdk_new_project_quick_start.rst","get_started\\cdk_rv_debugger_plus.rst","get_started\\cmake_quick_start.rst","get_started\\connecting_hardware.rst","get_started\\get_started.rst","get_started\\index.rst","index.rst","samples\\advance samples\\ble_scan_demo.rst","samples\\advance samples\\boot2_iap_info.rst","samples\\advance samples\\fatfs_demo.rst","samples\\advance samples\\lowpower_demo.rst","samples\\advance samples\\shell_demo.rst","samples\\basic samples\\adc\\adc_key_demo.rst","samples\\basic samples\\adc\\index.rst","samples\\basic samples\\dma\\dma_m2m_demo.rst","samples\\basic samples\\dma\\index.rst","samples\\basic samples\\gpio\\blink_demo.rst","samples\\basic samples\\gpio\\button_demo.rst","samples\\basic samples\\gpio\\index.rst","samples\\basic samples\\i2c\\i2c_eeprom_demo.rst","samples\\basic samples\\i2c\\index.rst","samples\\basic samples\\mtimer\\index.rst","samples\\basic samples\\mtimer\\mtimer_demo.rst","samples\\basic samples\\pwm\\index.rst","samples\\basic samples\\pwm\\pwm_breath_demo.rst","samples\\basic samples\\pwm\\pwm_step_motor.rst","samples\\basic samples\\spi\\index.rst","samples\\basic samples\\spi\\spi_lcd_demo.rst","samples\\basic samples\\timer\\index.rst","samples\\basic samples\\timer\\timer_interrupt_demo.rst","samples\\basic samples\\uart\\index.rst","samples\\basic samples\\uart\\uart_loopback_demo.rst"],objects:{},objnames:{},objtypes:{},terms:{"001":23,"003":23,"0403":23,"0x00":[1,38],"0x0000":7,"0x00000000":5,"0x00000001":5,"0x00000002":5,"0x00000003":5,"0x00000006":5,"0x00000007":5,"0x0000000a":5,"0x0000000b":5,"0x00000014":5,"0x00000015":5,"0x00000016":5,"0x00000017":5,"0x00000018":5,"0x00000019":5,"0x0000001a":5,"0x0000001b":5,"0x0000001c":5,"0x0000001d":5,"0x0000001e":5,"0x0000001f":5,"0x0001":7,"0x001":[0,2,5,7,8,9,10,11],"0x0010":7,"0x0018":1,"0x002":[0,2,5,7,8,9,10,11],"0x0020":7,"0x0028":1,"0x004":[0,2,5,7,8,9,10,11],"0x0040":7,"0x008":[0,2,5,7,8,9,10,11],"0x00a0":1,"0x00f0":1,"0x01":[0,1,26],"0x010":[0,2,5,7,8,9,10,11],"0x0180":26,"0x02":[0,26],"0x020":[0,2,5,7,8,9,10,11],"0x03":[0,26],"0x04":[0,26],"0x05":[0,26],"0x06":[0,26],"0x07":[0,26],"0x08":[0,26],"0x09":[0,26],"0x0a":0,"0x0b":0,"0x0c":0,"0x0d":0,"0x0e":0,"0x0f":0,"0x10":[2,5,8,9,11],"0x11":[2,5,11],"0x12":[2,5,26],"0x13":[2,5,26],"0x14":2,"0x15":2,"0x16":2,"0x18":26,"0x1812":26,"0x50":38,"0x71":26,"0x80":[10,26],"0x81":10,"0x82":10,"0xff":33,"100":8,"1000":31,"1000000":[10,41,43,48],"12000000":48,"125hz":44,"12s":48,"14bit":2,"160":44,"16bit":2,"18000000":9,"1mhz":43,"2000000":[10,11,13,30,48,50],"20210120":13,"244":26,"256":10,"25hz":44,"28byj48":44,"2mhz":2,"3000000":[10,48],"32768":29,"32k":[8,29,44],"32m":[29,43],"360":44,"36000000":46,"3v3":22,"400":1,"4096\u4e2a\u8109\u51b2":44,"40m":9,"43v":31,"4\u4e2a\u901a\u9053":44,"4ghz":1,"6010":23,"625":[1,44],"64\u7684\u89d2\u5ea6":44,"64k":29,"8000":33,"\u4e00\u4e2a\u6b65\u8ddd\u89d2":44,"\u4e00\u4e8c\u76f8\u52b1\u78c1":44,"\u4e00\u76f8\u52b1\u78c1":44,"\u4e5f\u5c31\u5bf9\u5e94\u8f6c\u5b50\u8f6c\u8fc7\u4e00\u5b9a\u7684\u89d2\u5ea6":44,"\u4e8c\u76f8\u52b1\u78c1":44,"\u4ece\u800c\u8fbe\u5230\u51c6\u786e\u5b9a\u4f4d\u7684\u76ee\u7684":44,"\u4ece\u800c\u8fbe\u5230\u8c03\u901f\u7684\u76ee\u7684":44,"\u4ee5\u8f6e\u8be2\u6a21\u5f0f\u6765\u6253\u5f00":44,"\u4f7f\u7528":44,"\u4f7f\u80fd":44,"\u4fdd\u5b58\u4e8e4\u4e2a\u53e5\u67c4\u4e2d":44,"\u4fee\u65394\u4e2a":44,"\u516b\u62cd":44,"\u51fd\u6570":44,"\u51fd\u6570\u627e\u5230\u8bbe\u5907\u5bf9\u5e94\u7684\u53e5\u67c4":44,"\u51fd\u6570\u6ce8\u518c":44,"\u5219\u9700\u8981360":44,"\u5355":44,"\u5355\u4f4d\u65f6\u95f4\u5185\u8109\u51b2":44,"\u5355\u76f8\u7ed5\u7ec4\u901a\u7535":44,"\u5360\u7a7a\u6bd4\u4e3a37":44,"\u53c2\u7167":44,"\u53c2\u8003\u7535\u8def":44,"\u53ca\u6b65\u8fdb\u89d2":44,"\u53cc":44,"\u53cc\u76f8\u7ed5\u7ec4\u901a\u7535":44,"\u53ef\u4ee5\u901a\u8fc7\u63a7\u5236\u8109\u51b2\u4e2a\u6765\u63a7\u5236\u89d2\u4f4d\u79fb\u91cf":44,"\u540c\u65f6\u53ef\u4ee5\u901a\u8fc7\u63a7\u5236\u8109\u51b2\u9891\u7387\u6765\u63a7\u5236\u7535\u673a\u8f6c\u52a8\u7684\u901f\u5ea6\u548c\u52a0\u901f\u5ea6":44,"\u547d\u4ee4\u884c\u7f16\u8bd1":44,"\u56db\u62cd":44,"\u56db\u76f8\u6b65\u8fdb\u7535\u673a\u53ef\u4ee5\u5728\u4e0d\u540c\u7684\u901a\u7535\u65b9\u5f0f\u4e0b\u8fd0\u884c":44,"\u56e0\u6b64\u4e0b\u56fe\u7684\u8868\u683c\u4e2d\u6b65\u8ddd\u89d2\u5ea6\u624d\u5199\u7684\u662f5":44,"\u578b\u56db\u76f8\u516b\u62cd\u7535\u673a":44,"\u57fa\u4e8ebl706_iot\u5f00\u53d1\u677f":44,"\u5b83\u53ef\u4ee5\u8fde\u7eed\u4e0d\u65ad\u5730\u8f6c\u52a8":44,"\u5b83\u5c31\u9a71\u52a8\u6b65\u8fdb\u7535\u673a\u6309\u8bbe\u5b9a\u7684\u65b9\u5411\u8f6c\u52a8\u4e00\u4e2a\u56fa\u5b9a\u7684\u89d2\u5ea6":44,"\u5e38\u89c1\u7684\u901a\u7535\u65b9\u5f0f\u6709\u5982\u4e0b\u4e09\u79cd":44,"\u5e76\u914d\u7f6e":44,"\u5f53\u524d\u6ce8\u518c":44,"\u5f53\u5bf9\u6b65\u8fdb\u7535\u673a\u65bd\u52a0\u4e00\u7cfb\u5217\u8fde\u7eed\u4e0d\u65ad\u7684\u63a7\u5236\u8109\u51b2\u65f6":44,"\u5f53\u6b65\u8fdb\u9a71\u52a8\u5668\u63a5\u6536\u5230\u4e00\u4e2a\u8109\u51b2\u4fe1\u53f7":44,"\u5f53\u901a\u7535\u72b6\u6001\u7684\u6539\u53d8\u5b8c\u6210\u4e00\u4e2a\u5faa\u73af\u65f6":44,"\u610f\u601d\u662f\u8fd9\u4e2a\u771f\u6b63\u7684\u6b65\u8fdb\u9a6c\u8fbe\u8f6c\u5b50\u8f6c\u52a864\u5468\u624d\u80fd\u8ba9\u8f93\u51fa\u8f74\u8f6c\u52a81\u5468":44,"\u6216\u62cd":44,"\u6240\u4ee5\u8981\u8ba9\u9a6c\u8fbe\u8f6c\u4e00\u5468":44,"\u6253\u5f00\u9879\u76ee\u4e2d\u63d0\u4f9b\u7684\u5de5\u7a0b\u6587\u4ef6":44,"\u6307\u4ee4":44,"\u672c":44,"\u6b65\u8fdb\u7535\u673a\u662f\u4e00\u79cd\u5c06\u7535\u8109\u51b2\u8f6c\u5316\u4e3a\u89d2\u4f4d\u79fb\u7684\u6267\u884c\u673a\u6784":44,"\u6bcf\u4e00\u4e2a\u8109\u51b2\u4fe1\u53f7\u5bf9\u5e94\u6b65\u8fdb\u7535\u673a\u7684\u67d0\u4e00\u76f8\u6216\u4e24\u76f8\u7ed5\u7ec4\u7684\u901a\u7535\u72b6\u6001\u6539\u53d8\u4e00\u6b21":44,"\u6bcf\u4e00\u4e2a\u8109\u51b2\u80fd\u4f7f\u8fd9\u4e2a\u771f\u6b63\u7684\u8f6c\u5b50\u8f6c\u52a85":44,"\u70e7\u5f55":44,"\u7136\u540e\u901a\u8fc7":44,"\u7535\u538b\u4e3a":44,"\u7684\u6570\u91cf\u51b3\u5b9a\u8f6c\u52a8\u7684\u89d2\u5ea6":44,"\u7684\u6570\u91cf\u51b3\u5b9a\u8f6c\u52a8\u7684\u901f\u5ea6":44,"\u7684\u6b65\u9aa4\u7f16\u8bd1\u4e0b\u8f7d\u5373\u53ef":44,"\u7684\u9891\u7387\u4e3a":44,"\u770b\u4e0b\u56fe\u7684\u6570\u636e\u8868\u683c\u4e2d\u7684\u51cf\u901f\u6bd4\u662f1":44,"\u7f16\u8bd1":44,"\u8109\u51b2":44,"\u82af\u7247\u9a71\u52a8":44,"\u8868\u660e\u7684\u610f\u601d\u662f\u4e00\u4e2a\u8109\u51b2\u53ef\u4ee5\u8ba9\u8f93\u51fa\u8f74\u8f6c\u52a85":44,"\u89c1":44,"\u8bbe\u5907\u590d\u7528\u5f15\u811a":44,"\u8bbe\u5907\u65f6\u949f\u6e90":44,"\u8bbe\u5907\u7684\u4e00\u4e2a\u901a\u9053":44,"\u8bbe\u5907\u914d\u7f6e":44,"\u8bbe\u7f6e":44,"\u8be5\u51fd\u6570\u7684\u529f\u80fd\u4e3b\u8981\u7528\u4e8e\u5207\u6362\u6b65\u8fdb\u7535\u673a\u7684\u65b9\u5411":44,"\u8be6\u89c1":[33,44],"\u8f6c\u5b50\u8f6c\u8fc7\u4e00\u4e2a\u9f7f\u8ddd":44,"\u8f6f\u4ef6\u4ee3\u7801\u89c1":44,"\u8fd9\u4e2a\u6b65\u8fdb\u7535\u673a\u5185\u90e8\u6709\u4e2a\u771f\u6b63\u7684\u6b65\u8fdb\u9a6c\u8fbe\u8f6c\u5b50":44,"\u8fde\u63a5\u65b9\u5f0f\u5982\u4e0b":44,"\u901a\u90530":44,"\u901a\u9053\u7684\u7684\u9ad8\u4f4e\u9608\u503c":44,"\u914d\u5408":44,"\u914d\u7f6e":44,"\u91c7\u7528\u6b65\u8fdb\u7535\u673a":44,"\u9996\u5148\u8c03\u7528":44,"break":11,"byte":[5,9,30,38],"case":[15,17,19,21,22],"char":[0,1,2,5,7,8,9,10,11,26,30],"class":[0,2,5,7,8,9,10,11],"const":[0,1,2,5,7,8,9,10,11,26],"default":[1,5,15,16,17,19,22,29,30,33,38,41,46,50],"enum":[0,1,2,3,5,7,8,9,10,11,44],"export":[13,17],"final":[3,30,31,33,38,46,48,50],"float":19,"function":[0,1,2,5,6,8,9,10,11,15,17,19,20,21,22,25,26,27,29,30,31,33,35,36,38,41,43,44,46,48,50],"import":[1,17],"int":[0,1,2,5,6,7,8,9,10,11,26,30],"new":[13,25],"null":[0,1,2,5,8,9,10,11,26,30,33,50],"public":1,"return":[0,1,2,5,6,7,8,9,10,11,26,30,50],"short":9,"static":[2,5,7,8,9,10,11,26,36,41],"switch":16,"try":[1,48],"void":[0,1,2,5,6,8,9,10,11,17,26,30,31,33,36,41,44,46,48,50],"while":[0,26,29],And:[8,25,39],Bus:[9,23],CTS:11,For:[2,5,7,8,9,10,11,13,14,15,16,18,20,21,26,27,31,33],I2S:[5,22],IDE:19,Its:13,LTS:23,Not:26,One:[11,14,21,23],PDS:29,RTS:11,TMS:22,That:8,The:[0,1,2,3,5,6,7,8,9,10,11,13,15,16,18,19,21,22,23,24,25,26,27,29,30,31,33,41,50],Then:[19,21,30,31,33,38,43,46,48,50],There:[1,19,21,23],Use:[1,14,16,23,35,36,41,43],__hal_rcc_gpiob_clk_en:17,__hal_rcc_uart5_clk_en:17,_printf_float:19,abnorm:10,about:[1,3,5,29],abov:[2,5,7,8,9,10,11,16,17,22,23,29,35,36,41],absolut:16,acceler:14,accept:1,access:[0,1,5,14,17],accord:[0,2,5,8,9,10,11,16,31],account:16,accuraci:2,achiev:[0,2],acknowledg:1,acl:1,activ:1,actual:[2,5,7,8,9,10,11,16,29],ad_discov:1,ad_len:1,adapt:[1,15,22,29,46],adc0:[2,5,31],adc0_config:[2,31],adc0_index:[2,31],adc:[0,12,25],adc_channel_cfg:31,adc_channel_cfg_t:[2,31],adc_channel_start:31,adc_clk_div_t:2,adc_clock_div_32:[2,31],adc_clos:2,adc_control:2,adc_data_width_16b_with_256_averag:[2,31],adc_data_width_t:2,adc_dev:[2,31],adc_devic:2,adc_device_t:2,adc_event_fifo_readi:2,adc_event_overrun:2,adc_event_typ:2,adc_event_underrun:2,adc_fifo_threshold_1byt:[2,31],adc_fifo_threshold_t:2,adc_gain_1:[2,31],adc_index_typ:2,adc_it_typ:2,adc_kei:31,adc_max_index:2,adc_open:2,adc_param_cfg_t:2,adc_pga_gain_t:2,adc_regist:31,adc_start:2,adc_stop:2,adc_vref_3p2v:[2,31],adc_vref_t:2,adcx_devic:2,add:[1,17,18,36,38],added:[1,2],adding:[21,29],addit:[0,2,5,8,9,10,11],addr:1,addr_typ:1,address:[0,1,5,7,16,33],adher:0,adjust:[7,8,17],adopt:[0,29],adv:26,adv_addr:1,adv_data:26,adv_nam:26,adv_param:26,advanc:[16,25],advertis:1,affect:[2,16],after:[1,2,5,7,8,9,10,11,13,14,15,16,17,18,19,20,21,22,23,26,27,29,30,33,41],again:[16,23,29],aim:14,air:1,alarm:10,algorithm:18,all:[0,1,2,8,16,17,23,29,46],allow:[1,26],alreadi:[13,17,21],also:[0,2,5,8,9,10,11,17,18,19,20,22,25],altern:17,alwai:[7,23],ammet:29,amplitud:8,analog:[1,2,8],analysi:[14,30],analyz:1,ani:[1,15,29],aon:29,api:25,app:[13,15,21,26,29,30,31,33,35,36,38,41,43,44,46,48,50],appear:[1,16,22,29],appli:15,applic:[0,1,15,17,25,27,29],appropri:[16,19],apt:[13,23],arbitr:7,architectur:[1,7],area:27,arg:[0,2,5,8,9,10,11,30,33,48,50],argc:30,argv:30,arrai:[1,33],array_s:26,assign:[0,17],assist:[15,29],associ:19,asynchron:11,at24cxx:39,atomic_defin:1,atomic_t:1,attach:6,attent:[13,19],attr:26,attribut:1,audio:22,authent:1,auto:30,automat:[1,6,11,17,27],avail:[0,9,13],averag:2,awaken:29,back:[22,50],band:1,bar:[15,16,17,18,20],base:[0,17,18,20,25,26,29,30,31,33,35,36,38,41,43,46,48,50],baseband:1,bashrc:13,basic:[1,16,17,21,25,29,30,50],baud:[11,16,18,20],baudrat:[11,30,50],bclk:8,been:[14,15,16,23,33,46],befor:[1,2,5,7,8,9,10,11,13,14,15,16,19,22,24],begin:17,behav:29,being:[1,7],below:[1,14,15,18,19,20,22,23,26,29],better:[16,23],between:[7,9,34],bflb_mcu_prefer:15,bflb_platform_delay_m:43,bflb_platform_init:[30,50],bflb_platform_set_alarm_tim:41,bin:[13,15,16,18,20,27],binari:13,bind:1,bit:[1,2,5,7,8,9,10,11,33,41],bl602:1,bl702:[13,14,15,17,23,25,26],bl702_avb:46,bl702_bl704_bl706_ds_en_combo_1:29,bl702_driver:46,bl702_iot:22,bl704:17,bl706:[17,27,29],bl706_avb:[23,31,46],bl706_iot:[13,15,19,21,23,26,30,31,33,35,36,38,41,43,44,48,50],bl706_lp:29,bl70x:[22,25],bl70x_flash:18,bl70x_flasher:18,bl_case_success:48,bl_clean:15,bl_make:15,bl_mcu_sdk:[0,19,21,26,27,29,30,31,33,35,36,38,41,43,44,46,48,50],bl_test_01:26,black:22,bldevcub:[20,25,26,30,31,33,35,36,38,41,43,44,46,48,50],ble:25,ble_centr:26,ble_controller_init:1,ble_peripher:26,ble_start_adv:26,ble_start_scan:26,ble_tp_conn:26,ble_tp_conn_callback:26,ble_tp_connect:26,ble_tp_disconnect:26,ble_tp_init:26,ble_tp_notify_task:26,ble_tp_recv_wr:26,ble_write_data:26,ble_write_data_task:26,bluetooth:[1,26,30],board:[2,3,5,6,7,8,9,10,11,13,14,15,16,18,19,20,21,22,23,25,26,27,29,30,31,33,35,36,38,41,43,44,46,48,50],board_get_debug_uart_index:[30,50],bool:[1,2],boot2:25,boot2_iap:27,boot:[13,16,22,23],boot_rom:13,borad:15,both:[2,9,29],bottom:[0,17],bouffalo:[15,22,23,27],bouffalolab:[13,14,15,16,17],boufflao:[17,29],box:[15,16,17],breakpoint:[18,20],breath:42,briefli:19,broadcast:[1,26],brows:16,browser:17,bsp:[2,3,5,6,7,8,9,10,11,17,30,31,33,38,43,44,46,48,50],bsp_adc_clock_div:31,bsp_adc_clock_sourc:31,bsp_i2c_clock_div:38,bsp_i2c_clock_sourc:38,bsp_pwm_clock_div:[43,44],bsp_pwm_clock_sourc:[43,44],bsp_spi_clock_div:46,bsp_spi_clock_sourc:46,bsp_timer0_clock_div:48,bsp_timer0_clock_sourc:48,bsp_uart_clock_div:[30,50],bsp_uart_clock_sourc:[30,50],bsp_using_adc0:[2,31],bsp_using_dma0_ch0:[5,33],bsp_using_dma0_ch1:5,bsp_using_dma0_ch2:5,bsp_using_dma0_ch3:5,bsp_using_dma0_ch4:5,bsp_using_dma0_ch5:5,bsp_using_dma0_ch6:5,bsp_using_dma0_ch7:5,bsp_using_dma_ch0:5,bsp_using_i2c0:[7,38],bsp_using_pwm_ch0:[8,44],bsp_using_pwm_ch1:[8,44],bsp_using_pwm_ch2:[8,43,44],bsp_using_pwm_ch3:[8,44],bsp_using_pwm_ch4:8,bsp_using_spi0:[9,46],bsp_using_timer0:[10,48],bsp_using_timer1:10,bsp_using_timer_ch0:10,bsp_using_uart0:[11,30,50],bsp_using_uart1:11,bsp_using_xxx:17,bt_addr_le_ani:1,bt_addr_le_t:1,bt_char_ble_tp_not_attr_val_index:26,bt_conn:[1,26],bt_conn_auth_cancel:1,bt_conn_auth_cb:1,bt_conn_auth_cb_regist:1,bt_conn_auth_passkey_confirm:1,bt_conn_auth_passkey_entri:1,bt_conn_auth_pincode_entri:1,bt_conn_br:1,bt_conn_cb:[1,26],bt_conn_cb_regist:[1,26],bt_conn_create_auto_l:1,bt_conn_create_auto_stop:1,bt_conn_create_l:1,bt_conn_create_slave_l:1,bt_conn_disconnect:1,bt_conn_enc_key_s:1,bt_conn_get_info:1,bt_conn_get_remote_dev_info:1,bt_conn_get_secur:1,bt_conn_info:1,bt_conn_l:1,bt_conn_le_param_upd:1,bt_conn_num_flag:1,bt_conn_rv:1,bt_conn_sco:1,bt_conn_set_secur:1,bt_conn_state_t:1,bt_data:[1,26],bt_data_byt:1,bt_data_flag:[1,26],bt_data_gap_appear:26,bt_data_manufacturer_data:26,bt_data_name_complet:[1,26],bt_data_uuid16_al:26,bt_enabl:1,bt_gap_adv_fast_int_max_3:26,bt_gap_adv_fast_int_min_3:26,bt_gap_init_conn_int_max:1,bt_gap_init_conn_int_min:1,bt_gap_scan_slow_interval_1:1,bt_gap_scan_slow_window_1:1,bt_gatt_attr:26,bt_gatt_notifi:26,bt_gatt_subscribe_param:26,bt_gatt_write_without_respons:26,bt_get_local_address:1,bt_le_ad_gener:1,bt_le_ad_limit:26,bt_le_ad_no_bredr:[1,26],bt_le_adv_opt_connect:1,bt_le_adv_opt_dir_addr_rpa:1,bt_le_adv_opt_dir_mode_low_duti:1,bt_le_adv_opt_filter_conn:1,bt_le_adv_opt_filter_scan_req:1,bt_le_adv_opt_non:1,bt_le_adv_opt_one_tim:1,bt_le_adv_opt_use_ident:1,bt_le_adv_opt_use_nam:1,bt_le_adv_param:[1,26],bt_le_adv_start:[1,26],bt_le_adv_stop:1,bt_le_adv_update_data:1,bt_le_conn_param:1,bt_le_read_rssi:1,bt_le_scan_cb_t:1,bt_le_scan_param:1,bt_le_scan_start:1,bt_le_scan_stop:1,bt_le_scan_type_act:1,bt_le_scan_type_pass:1,bt_le_set_auto_conn:1,bt_le_set_chan_map:1,bt_le_whitelist_add:1,bt_le_whitelist_clear:1,bt_le_whitelist_rem:1,bt_ready_cb_t:1,bt_security_t:1,bt_set_bond:1,bt_set_tx_pwr:1,bt_unpair:1,bt_warn:26,buf:[7,26,38],buffer:[0,2,7,9,10,11],build:[13,15,18,20],burden:5,burst:5,bus:[7,8,16,23],button:[15,16,18,20,22,23,26,37],cabl:[13,14,15,22,23],cach:15,calcul:41,call:[0,1,2,3,5,7,8,9,10,11,17,19,21,30,31,33,38,43,46,48,50],callback:[0,1,2,5,6,8,9,10,11,26,30,33,36,41,48,50],camera:22,can:[0,1,2,5,6,7,8,9,10,11,13,14,15,16,17,18,19,20,22,23,25,27,29,41],cancel:[1,15],cannot:[2,5,7,8,9,10,11,17,20,22,29],canon:13,cap:22,capac:6,care:[1,3,23],carefulli:22,carri:29,categori:0,caus:10,cbfun:6,ccw:44,cdk:[23,25,26,29,30,31,33,35,36,38,41,43,44,46,48,50],cdk_flashload:18,cdkproj:[18,19,20,30,31,33,35,36,38,41,43,44,46,48,50],central:1,certain:[5,8],cfg:[8,48],ch8:31,chan_map:1,chang:[8,13,14,15,16,17,19,23],channel:[1,2,5,8,9,27,33,43],char_hdl:26,charact:30,characterist:[1,2,5,7,8,9,10,11],check:[1,13,16,18,22,23,27,33],chip:[3,6,9,15,16,18,20,25,29],choos:[1,11,13,16,19,23,29],chrome:17,circuit:[2,7,29,31,36,38],circumst:23,ck_link:22,ck_link_debug:18,clean:[18,20],clear:[0,1,15,18,20],click:[14,15,16,17,18,19,20,22,23,26],client:[1,25],clk:[9,46],clk_div:[2,31],clk_phase:[9,46],clk_polara:[9,46],clock:[2,7,8,9,10,12,16,17,29,30,31,38,41,43,46,48,50],clock_config:[3,30,31,38,43,44,46,48,50],clock_period:29,clone:[13,14,15],close:[0,2,5,6,8,9,10,11,13,15,29,30,50],cloud:14,cmake:25,cmake_current_source_dir:21,cmakelist:[19,21],cmd:[0,2,5,8,9,10,11],cmd_echo:30,cnt_mode:[10,48],code:[0,1,2,5,7,8,9,10,11,13,15,16,17,18,19,20,21,23,26,27,30,31,33,35,36,38,41,43,46,48,50],codec:22,column:[16,23],com:[13,14,15,16,17,22,23],combin:14,come:[41,48],command:[0,2,5,8,9,10,11,13,14,15,21,22,23,25,26,29,31,33,35,36,38,41,43,46,48,50],common:[6,22],commun:[1,7,9,14,15,16,27],comp0:48,comp1:48,comp2:48,compar:[5,10,48],compat:13,compil:[17,19,27],complet:[1,2,5,7,8,9,10,11,14,15,16,17,26,27,29,30,31,33],complex:17,compon:[0,21,30],compos:1,comprehens:25,compress:15,compromis:1,comput:[13,16,22,23,29],comx:13,concept:0,condit:8,config:[0,10,17],config_bt_bredr:1,config_bt_privaci:1,config_bt_remote_vers:1,config_bt_smp:1,config_bt_stack_pt:1,config_gpio10_func:44,config_gpio11_func:[38,44],config_gpio12_func:44,config_gpio14_func:[30,50],config_gpio15_func:[30,50],config_gpio16_func:38,config_gpio18_func:31,config_gpio19_func:46,config_gpio20_func:46,config_gpio21_func:46,config_gpio22_func:43,config_gpio3_func:44,configur:[0,1,3,6,18,19,25,30,31,33,35,36,38,43,46,48,50],confirm:[13,23],conflict:[7,17],conn:[1,26],connect:[1,7,16,18,23,25,26,29],consol:15,construct:0,contact:22,contain:[1,17,19,21,27,29,50],content:[21,26],continu:[2,29],continuous_conv_mod:[2,31],control:[0,1,2,5,6,8,9,10,11,23,30],conveni:[1,41],convers:[2,31],convert:[2,5,23],cooper:13,copi:[15,17,18,19],core:25,correct:[13,15,16,18,23,33],correctli:[13,14,15,16,18,20,22],correspond:[2,5,7,8,9,10,11,15,16,17,18,19,20,21,22,29,30,31,33,38,43,46,48,50],count:[8,10],cours:[18,20],cpha:9,cpol:9,cpu:[18,20,29],creat:[1,16,17,19,21],creation:1,crystal:[8,29],cs1:46,cs1_high:46,cs1_low:46,csky:18,ctrl:0,cube:[20,22,27],current:[0,1,5,7,8,10,17,18,19,20,26,29,30,31,33,38,43,46,48,50],cursor:[18,20],custom:29,cycl:[8,43],dac0:5,dac:[2,12],data:[0,2,5,7,9,11,13,14,15,18,20,22,23,26,27,29,30,34,38,46,50],data_appear:26,data_len:1,data_manu:26,data_uuid:26,data_width:[2,31],databit:[11,30,50],datas:[9,46],datasheet:29,dc12v:44,dc5v:44,dc_high:46,ddition:9,debug:[14,23,25,29,50],debug_log:[30,50],debugg:[13,14,16,18],decompress:[13,16],decreas:2,dedic:5,default_config:46,defer:1,defin:[0,1,2,5,6,7,8,9,10,11,17,30,31,33,38,43,44,46,48,50],definit:29,degre:5,deivce_ctrl_pwm_dutycycle_config:[43,44],deivce_ctrl_pwm_it_pulse_count_config:8,delai:1,delet:0,demo:[15,17,26,30,31,33,35,36,38,41,43,44,46,48,50],demonstr:[26,30],depend:[2,5,8,9,10,11],depth:9,describ:22,descript:[2,5,8,9,10,11],design:27,desir:17,destin:[5,33],destroi:7,detail:[2,16,18,20,21],detect:[7,11,32,37],determin:[1,15,29,48],dev:[0,1,2,5,7,8,9,10,11,13,15,17,20,22,23,27,30,33,48,50],devcub:27,develop:[14,16,18,19,22,23,27,29,30],devic:[1,12,16,23,26,30,31,33,38,43,46,48,50],device_class_adc:0,device_class_camera:0,device_class_dma:0,device_class_gpio:0,device_class_i2:0,device_class_i2c:0,device_class_non:0,device_class_pwm:0,device_class_sdio:0,device_class_sec_hash:0,device_class_spi:0,device_class_tim:0,device_class_typ:0,device_class_uart:0,device_class_usb:0,device_clos:46,device_contorl:[43,44],device_control:[30,31,33,43,44,48,50],device_ctrl_adc_channel_config:[2,31],device_ctrl_adc_channel_start:2,device_ctrl_adc_channel_stop:2,device_ctrl_adc_tsen_off:2,device_ctrl_adc_tsen_on:2,device_ctrl_adc_vbat_off:2,device_ctrl_adc_vbat_on:2,device_ctrl_attach_rx_dma:[0,2,9,11],device_ctrl_attach_tx_dma:[0,9,11],device_ctrl_clr_int:[0,2,5,9,10,11,30,50],device_ctrl_config:[0,2,8,11],device_ctrl_get_config:[0,10],device_ctrl_get_int:[0,10],device_ctrl_get_match_statu:10,device_ctrl_pwm_dutycycle_config:8,device_ctrl_pwm_frequence_config:8,device_ctrl_pwm_it_pulse_count_config:8,device_ctrl_resum:[0,8,9,10],device_ctrl_resvd1:0,device_ctrl_resvd2:0,device_ctrl_rx_dma_resum:[0,9,11],device_ctrl_rx_dma_suspend:[0,9,11],device_ctrl_set_int:[0,2,5,9,10,11,30,33,48,50],device_ctrl_spi_config_clock:9,device_ctrl_suspend:[0,8,9,10],device_ctrl_timer_ch_start:10,device_ctrl_timer_ch_stop:10,device_ctrl_tx_dma_resum:[0,9,11],device_ctrl_tx_dma_suspend:[0,9,11],device_ctrl_uart_get_rx_fifo:11,device_ctrl_uart_get_tx_fifo:11,device_find:[30,31,33,38,43,44,46,48,50],device_found:26,device_oflag_dma_rx:[0,2,5,7,8,9,10,11],device_oflag_dma_tx:[0,2,5,7,8,9,10,11],device_oflag_int_rx:[0,2,5,7,8,9,10,11,30,50],device_oflag_int_tx:[0,2,5,7,8,9,10,11,48],device_oflag_rdwr:[30,33,38,43,44,46,50],device_oflag_stream_rx:[0,2,5,7,8,9,10,11,31,46],device_oflag_stream_tx:[0,2,5,7,8,9,10,11,30,43,44,46,50],device_open:[17,30,31,33,38,43,44,46,48,50],device_read:31,device_set_callback:[30,33,48,50],device_status_typ:0,device_writ:[48,50],diagram:[22,23],dialog:15,differ:[0,2,5,8,9,10,11,13,19,21,29,31],differenti:2,differential_mod:[2,31],digit:[1,2,8],dir:44,direct:[1,5,7,9,33,46],directli:[5,14,15,17,18,20,29],directori:[2,3,5,6,7,8,9,10,11,13,15,17,18,20,29],disabl:[1,2,5,8,9,10,11,31,44],disadvantag:6,disconnect:[1,22,26],discret:2,displai:[16,18,20,23,26,29,31,35,43,45,50],div:7,divid:[0,6,8,10,29,31],divis:[10,17,31,41],dlist_t:0,dma0_ch0_config:[5,33],dma0_ch0_index:[5,33],dma0_ch1_config:5,dma0_ch1_index:5,dma0_ch2_config:5,dma0_ch2_index:5,dma0_ch3_config:5,dma0_ch3_index:5,dma0_ch4_config:5,dma0_ch4_index:5,dma0_ch5_config:5,dma0_ch5_index:5,dma0_ch6_config:5,dma0_ch6_index:5,dma0_ch7_config:5,dma0_ch7_index:5,dma:[0,2,7,8,9,10,11,12,25],dma_burst_16byt:5,dma_burst_1byt:5,dma_burst_4byt:5,dma_burst_8byt:5,dma_ch0:33,dma_ch0_index:5,dma_channel_get_statu:5,dma_channel_start:33,dma_clos:5,dma_control:5,dma_dev:5,dma_devic:5,dma_device_t:5,dma_dst_buff:33,dma_event_complet:5,dma_event_typ:5,dma_index_typ:5,dma_lli_ctrl_t:5,dma_lli_cycle_mod:5,dma_lli_once_mod:[5,33],dma_m2m:33,dma_max_index:5,dma_memory_to_memori:[5,33],dma_memory_to_periph:5,dma_open:5,dma_periph_to_memori:5,dma_periph_to_periph:5,dma_regist:33,dma_reload:33,dma_request_adc0:5,dma_request_dac0:5,dma_request_i2c0_rx:5,dma_request_i2c0_tx:5,dma_request_i2s_rx:5,dma_request_i2s_tx:5,dma_request_non:[5,33],dma_request_spi0_rx:5,dma_request_spi0_tx:5,dma_request_uart0_rx:5,dma_request_uart0_tx:5,dma_request_uart1_rx:5,dma_request_uart1_tx:5,dma_request_usb_ep0:5,dma_request_usb_ep1:5,dma_request_usb_ep2:5,dma_request_usb_ep3:5,dma_request_usb_ep4:5,dma_request_usb_ep5:5,dma_request_usb_ep6:5,dma_request_usb_ep7:5,dma_src_buff:33,dma_transfer_dir_typ:5,dma_transfer_don:33,dma_transfer_width_16bit:5,dma_transfer_width_32bit:[5,33],dma_transfer_width_8bit:5,dmax_devic:5,document:[13,14,15,16,19,21,22,29],doe:[5,7,8,9,10,11,16,17,19,20,21,22,23,27,29],domain:[8,29],don:[1,13,16,22,23],done:[17,33],doubl:[8,14,15,16,18,19,20,23],doubli:0,down:[6,16,17,18,20,22,29,30],download:[13,18,20,23,27,29,30,31,33,35,36,38,41,43,46,48,50],dparamet:30,drag:17,drawer:22,drive:[6,42],driver:[1,2,5,7,8,9,10,11,16,17,20,22,46],drop:[16,17,18,20],dst_addr:5,dst_burst_siz:5,dst_req:[5,33],dst_width:[5,33],dtcm:29,dual:23,due:2,duplex:[9,11],duplic:17,dupont:[13,14,15,22],dure:[0,27],duti:[1,8,43],dutycycl:43,dvice:2,e24:25,each:[0,2,5,7,8,9,10,11],easili:17,echo:[13,30],eclips:23,edg:[6,17,22,36],edit:[13,15,19],editor:[17,19],eeprom:38,effect:[1,2,5,7,8,9,10,11,23],element:17,elf:[13,15,18],elimin:[6,17],els:[31,44,46,48,50],embed:17,empti:19,emul:[14,15,30],enabl:[1,2,5,6,8,9,10,11,13,17,30,31,33,36,38,43,44,46,48,50],encod:8,encrypt:1,end:[2,17],endif:[1,2,5,7,8,9,10,11,30,31,33,38,43,44,46,48,50],energi:8,enter:[1,13,14,15,16,18,20,22,23,29],entir:8,entri:[19,21],enumer:[1,2],environ:25,ep0:5,ep1:5,ep2:5,ep3:5,ep4:5,ep5:5,ep6:5,ep7:5,epf:15,equip:0,equival:[0,8],err:[1,26],error:[0,1,2,5,7,8,9,10,11,26,33],etc:[1,8,18,30],ethernet:[25,30],evalu:25,even:[1,11],event:[0,1,2,5,8,9,10,11,48],eventu:17,everi:2,everyth:[0,17],exactli:13,exampl:[2,5,7,8,9,10,11,13,15,16,17,18,20,26,27,30,31,33,35,36,38,41,43,44,46,48,50],except:[1,29],exchang:11,exe:[14,15,16,23],execut:[13,15,29,30],exist:[7,15,21],exit:29,expand:[15,16],experi:31,explain:19,extend:[0,22],extern:[2,6,11,36],face:22,facilit:[3,5,8,29,30],fact:9,factor:10,fail:[1,13,18,31,48],failur:1,fall:6,fast:5,fatf:25,featur:[1,29],femal:22,field:1,fifo:[2,9,11,23,50],fifo_threshold:[2,9,11,30,31,46,50],figur:[15,17,18,20,22,23,26,29],file:[0,1,2,3,5,6,7,8,9,10,11,13,15,16,18,20,27,30],fill:[0,1,5,26],filter:[1,9],filter_dup:1,find:[0,16,23,26,30,31,33,38,43,44,46,48,50],finish:[15,16],finsh:15,firefox:17,firmwar:[1,23,27,29],first:[0,9,13,15,18,19,21,22,23,27,30,31,33,38,43,50],flag:[0,1,7,19,26,38,48],flash:[16,17,18,20,23,27],flashdownload:18,flat:22,flexibl:[7,8,9,11],flicker:23,flow:11,folder:[19,21],follow:[0,1,2,3,5,6,7,8,9,10,11,13,14,15,18,19,20,21,22,23,24,29,30,35,36,38,43,46,50],form:1,formal:24,format:[9,13],found:0,four:[2,5,29],fpc:22,framework:25,free:15,freerto:21,freerun:10,frequenc:[2,7,8,9,16,17,41,43,44],frequency_divis:8,frequent:17,from:[0,1,7,9,14,15,16,18,19,20,22,23,26,29,38],ft2232c:23,ftdi:23,full:[6,9,11,18,20],fulli:[14,22],func1:22,func2:22,funtion:[2,5,7,8,9,10,11],further:29,futur:23,gain:[2,31],gap:1,gate:29,gatt:1,gc0308:22,gdb:15,gener:[1,6,8,15,18,25],generate_bin:21,get:[0,1,3,5,10,11,14,15,16,29,31],get_adc_key_valu:31,get_attr:26,git:[13,14,15],gite:[13,14,15],github:23,gnd:[15,22],goal:13,gpio10:[44,46],gpio11:[36,38,44],gpio11_int_callback:36,gpio12:44,gpio14:[30,50],gpio15:[30,50],gpio16:38,gpio18:31,gpio19:46,gpio20:46,gpio21:46,gpio22:[35,43,46],gpio29:35,gpio30:35,gpio31:35,gpio3:44,gpio:[12,15,17,25,29,30,31,38,43,44,46,50],gpio_af14_uart5:17,gpio_async_falling_triger_int_mod:6,gpio_async_high_level_int_mod:6,gpio_async_low_level_int_mod:6,gpio_async_rising_triger_int_mod:6,gpio_attach_irq:36,gpio_blink:[15,35],gpio_cas:[19,21],gpio_fun_adc:31,gpio_fun_i2c:38,gpio_fun_pwm:[43,44],gpio_fun_spi:46,gpio_fun_uart0_rx:[30,50],gpio_fun_uart0_tx:[30,50],gpio_initstruct:17,gpio_inittypedef:17,gpio_input_mod:6,gpio_input_pd_mod:6,gpio_input_pp_mod:6,gpio_int:36,gpio_irq_en:36,gpio_mode_af_pp:17,gpio_nopul:17,gpio_output_mod:[6,46],gpio_output_pd_mod:6,gpio_output_pp_mod:[6,35],gpio_pin_11:36,gpio_pin_12:17,gpio_pin_13:17,gpio_pin_22:35,gpio_pin_29:35,gpio_pin_30:35,gpio_pin_31:35,gpio_set_mod:[35,36,46],gpio_speed_freq_low:17,gpio_sync_falling_triger_int_mod:6,gpio_sync_high_level_int_mod:6,gpio_sync_low_level_int_mod:6,gpio_sync_rising_triger_int_mod:[6,36],gpio_test_cas:21,gpio_writ:[35,46],gpiob:17,graphic:[14,17],green:16,group:[10,22],guarante:1,guest:16,guid:[20,26,27,29,30,31,33,35,36,38,41,43,44,46,48,50],habit:14,hal:[0,17],hal_adc:2,hal_dma:5,hal_drv:46,hal_gpio_init:17,hal_i2c:7,hal_init:17,hal_nvic_enableirq:17,hal_nvic_setprior:17,hal_pwm:8,hal_spi:9,hal_tim:10,hal_uart:11,hal_uart_mspinit:17,handl:[0,1,2,5,7,8,9,10,11,30,31,33,38,43,46,48,50],happen:1,happili:23,hardwar:[0,1,2,6,7,11,16,17,25],has:[0,2,5,7,8,9,10,11,14,15,16,17,22,23,30,33],have:[0,1,2,3,5,6,7,8,9,16,17,18,20,22,23,29,30,46,50],hbn:29,hci:1,hci_driver_init:1,hd11:22,hd12:22,hd19:22,hd1:22,hd3:22,hd8:22,head:14,header:[15,17,19,21],hello:30,hellowd:[13,15,18,20,30],helloworld:[13,15,18,19,20],hellwd:30,help:[17,18,20,29],here:[5,16,33],hierarchi:0,high:[1,6,8],higher:2,himself:[2,5],histor:30,hold:[13,23],holder:22,host:[1,7,23],how:[13,19,21,22,30],html:17,http:[13,14,15,16,17,23],huart:17,i2c0:[7,38],i2c0_config:[7,38],i2c0_index:[7,38],i2c1:7,i2c:[5,12,25],i2c_at24cxx:38,i2c_clk:7,i2c_dev:7,i2c_devic:7,i2c_device_t:7,i2c_hw_mod:[7,38],i2c_index_typ:7,i2c_max_index:7,i2c_msg:7,i2c_msg_t:[7,38],i2c_open:7,i2c_rd:[7,38],i2c_regist:38,i2c_scl:38,i2c_sda:38,i2c_source_clk:7,i2c_transf:38,i2c_wr:[7,38],i2cx_devic:7,iap:25,icon:[15,18,20],idea:[0,17],ident:1,identif:[1,7],identifi:1,ifdef:[2,5,7,8,9,10,11],ifndef:[2,5,7,8,9,10,11,30,31,33,38,43,44,46,48,50],ignor:13,imag:[13,16],implement:[0,1,8,17],includ:[1,8,9,17,18,19,22],incom:[1,30],incorrect:10,increas:[8,16,17],increment:41,independ:[5,10,22],index:[2,5,7,8,9,10,11,17,33],indic:[1,7,16,18,23,29],indirectli:17,info:1,inform:[0,1,2,5,15,17,23,29,31],inherit:[0,2,5,7,8,9,10,11],init:17,initi:[1,7,17,26,29,30],input:[2,5,6,8,9,10,11,31],insert:[15,22,23],instal:[13,14,15,16,18,19,20,22],instanc:17,instead:17,instruct:[18,20,21,29,43],int8_t:1,integr:14,inter:7,interconnect:25,interfac:[1,13,15,16,17,18,20,22,23,29,46],intergr:7,intern:[2,18,20,23,29,30],interoper:1,interrupt:[0,2,5,6,7,8,9,10,11,17,29,30,33,37,41,47,50],interv:1,interval_max:[1,26],interval_min:[1,26],intervent:5,introduc:[13,14,15,16,21,22,23,31],introduct:27,invalid:7,invert:8,iot:[22,25],irq:48,isregist:26,issu:29,it_pulse_count:[8,43,44],itcm:29,its:[0,1,10,11,17,29,50],jitter:6,jlink:[22,23],jlink_bl_mcu_sdk:15,jtag:[16,22,23,25],jtag_tck:22,jtag_tdi:22,jtag_tdo:22,jtag_tm:22,judg:[30,31],jump:22,jumper:22,just:[1,8,16,23],k_delayed_work:1,k_fifo:1,k_forev:26,k_sem_giv:26,k_sem_tak:26,k_work:1,keep:[1,16],kei:[1,13,16,18,20,22,30,32],keil:[30,31,33,35,36,38,41,43,44,46,48,50],kernel:41,key_no_valu:31,keyboard:30,keyvalu:31,kind:6,known:0,l2cap:1,lab:[15,17,22,23,27,29],lamp:37,last:[15,18,20],latch:22,latenc:1,later:[16,17,41],latest:[14,15,27],launch:15,layer:[1,2,5,8,9,10,11,13,17],lcd:45,lcd_c:46,lcd_cs_pin:46,lcd_dc:46,lcd_dc_pin:46,lcd_wr_byte:46,lcd_wr_halfword:46,lcd_wr_word:46,least:[9,23],leav:23,led:[23,37,42],led_breath:43,left:30,len:[7,26,38],length:[0,1,2,5,7,9,10,11,26,33,50],lengthi:17,level:[1,6,8,19,21,29,35],libftdi:23,libhidapi:23,libusb:23,light:23,like:[30,31,33,35,36,38,41,43,44,46,48,50],lin:11,line:[13,14,15],link:[0,1,2,5,9,11,14,15,16,17,23],linker:19,linker_script:21,linux:[23,24,29,30],list:[0,1,2,5,8,9,10,11,16,18,23],lli:5,lli_cfg:5,load:[15,18,20],loader:18,local:[1,13],locat:[2,3,5,6,7,8,9,10,11,29],lock:22,log:15,logic:1,loopback:49,lot:3,low:[1,6,7,8,25],lowpow:25,lowpower_test:29,lsb:9,lsusb:23,ltd:23,machin:[1,13],macro:[2,5,7,8,9,10,11,17,30],mai:[19,21],main:[0,1,13,15,17,19,21],mainli:[6,16,17,21,22,23,31,33],maix:[16,23],make:[14,15,16,17,19,21,22,23,26,29,30,31,33,35,36,38,41,43,44,46,48,50],manag:[1,2,5,8,9,10,11,16,23],mani:5,manner:1,manual:[5,16,25,27],manufactur:1,map:1,master:[1,7,9],match:[1,23,30],maximum:[1,2,9,11],mcu:[0,2,5,6,7,8,9,10,11,13,14,15,16,17,22,23,29],mdk:[30,31,33,35,36,38,41,43,44,46,48,50],mean:[0,2,5,7,8,9,10,11,23],meaning:1,measur:[2,29],mechan:9,media:[13,17],medium:30,member:[0,7],memori:[0,5,33],menu:[15,16,18,20],mesh:1,messag:[7,29,30,50],metal:22,method:[0,5,10,13,14,18,20,22,30,35,36,38,43,46,50],microcontrol:25,microsoft:[13,17],mini:[13,16,22],minimum:1,mirror:16,miso:46,mkdir:13,mobaxterm:30,mobil:[17,26],mode:[0,1,2,5,6,7,8,9,10,11,13,17,20,23,29,31,33,35,36,38,43,46,48,50],model:[16,17],modifi:[0,2,5,6,7,8,9,10,11,15,21,30,35,43,46,48],modul:[2,8,13,14,15,29],moment:29,more:[7,9,16,17,23,29],mosi:46,most:[1,29],mostli:1,motor:42,motor_ch0:44,motor_ch1:44,motor_ch2:44,motor_ch3:44,motor_dir_typ:44,motor_set_dir:44,move:[18,20],msb:9,msg:[7,30,31,33,36,38,41,48,50],mtimer:25,multi:[2,7,21],multipl:[1,2,10,17,22],multiplex:[6,22,30,31,38,43,46,50],must:[1,19,21,22,23,26],mx_gpio_init:17,mx_quadspi_init:17,mx_usart1_uart_init:17,my_cas:[19,21],name:[0,1,2,5,6,7,8,9,10,11,15,17,18,19,20,26,48],name_max:0,nativ:13,necessari:1,need:[1,2,3,5,6,7,8,9,10,11,13,15,16,17,18,19,21,22,23,26,27,29,30,46],neg:2,neg_channel:31,negchlist:31,net_buf:1,network:[1,25,30],newli:19,next:[1,15,18,20,22],node:0,non:[1,30],none:[1,5,33,41,48],normal:[15,18,22,23,27,29],note:[2,16,22,23,30],notif:26,notifi:[1,26],notify_func:26,notify_poll_sem:26,now:[16,22],num:7,number:[1,5,7,8,11,13,16,18,20,22,23],object:[0,1],observ:[1,29],obtain:[13,14,18,20,23,29],occ:14,occupi:13,occur:[1,50],ocram:29,octam:29,odd:11,ofast:21,off:[2,6,23,29],offici:[14,16,23],offset:26,oflag:[0,2,5,7,8,9,10,11],often:17,onc:[2,19,27],one:[2,5,7,9,10,11,13,14,16,17,23,26,38,46],onli:[1,2,3,5,6,7,8,9,10,11,17,21,23,27,29],onlin:[17,27],oob:1,open:[0,2,5,6,7,8,9,10,11,14,16,17,19,23,30,31,33,35,36,38,41,43,46,48,50],openocd:[20,23],openocd_debug:[18,20],opensourc:0,oper:[2,13,14,16,18,20,23,27,30,31],opposit:1,option:[1,2,5,7,8,9,10,11,16,18,19,20,23,26],order:[5,8,17,23,29,30,46],org:13,orient:0,origin:29,oscil:[8,29],osr:2,ostrac:14,other:[0,1,2,5,7,8,9,10,11,13,18,19,21,22,23,25,29,30],otherwis:[1,19,22],our:[18,20],out:[1,15,22,23,30,50],outgo:1,output:[2,6,9,18,20,37,46],outward:22,over:[1,15],overflow:10,overview:25,own:[0,1,2,5,8,9,10,11,17,19,29],own_address_typ:1,packag:[0,15,27],packet:1,pad_gpio_xx:17,page:[15,29],pai:[13,19],pair:1,pane:[18,20],panel:[18,20],param:[1,26],paramet:[0,1,17,29],parent:[0,2,5,7,8,9,10,11],pariti:[11,30,50],part:[22,27,33],partial:2,pass:[5,30],passkei:1,password:1,past:17,path:[13,15,16,17,19],pb12:17,pb13:17,pdf:29,pds:29,peer:1,pending_no_cb:1,per:41,percentag:8,perform:[15,16,18,20,27],period:[8,43,44,48],peripher:[1,3,5,6,7,9,17,18,19,20,21,25,29],peripheral_clock_adc:3,peripheral_clock_cam:3,peripheral_clock_dac:3,peripheral_clock_i2:3,peripheral_clock_i2c:3,peripheral_clock_pwm:3,peripheral_clock_spi:3,peripheral_clock_typ:3,peripheral_clock_uart:3,peripheral_config:[2,5,7,8,9,10,11,30,31,33,38,43,44,46,48,50],perman:1,phase:[7,9,38],phenomenon:23,phone:26,physic:16,picocom:13,pin:[1,6,15,16,17,22,29,30,31,35,36,38,43,44,46,50],pinmux:6,pinmux_config:[6,30,31,43,44,46,50],pinmux_lvgl:46,pinmux_select:46,pix:22,pl_trig_src:10,plai:23,pleas:[2,13,14,15,16,17,18,19,20,21,22,23,24,27,29],plu:[13,14],plug:23,point:[19,22,23],pointer:[0,1,50],polar:[8,9],polarity_invert_mod:[8,44],poll:[0,2,5,7,8,9,10,11,30,31,43,46,50],pop:[15,17],port:[11,13,14,15,16,18,20,23,27,29,33,36,41,50],portal:16,pos:[0,2,9,10,11],pos_channel:31,poschlist:31,possibl:[23,29],power:[1,13,18,22,23,25],prefer:15,preload:10,prepar:25,press:[13,15,16,18,20,22,23,29,31,36],prevent:[7,10],preview:17,principl:0,print:[29,30,33,36,41,50],printf:19,printout:19,prioriti:[1,9],privaci:1,privat:1,problem:23,proce:[20,22],procedur:1,proceed:[13,14,15],process:[1,27],processor:5,product:[14,25,27],profil:[1,14,17],program:[1,6,16,17,19,21,25,27,29],project:[17,18,20,25,27,29,30,31,33,35,36,38,41,43,46,48,50],prompt:14,properli:[18,19],properti:[2,5,7,8,9,10,11,26],propos:17,protect:10,protocol:[1,11],provid:[0,1,2,3,5,6,7,8,9,10,11,17,25,27,29,30,41,46,50],psram:16,pull:[6,17,22,35,46],puls:8,pure:[13,19],purpos:[6,25,27],put:[17,18],pvparamet:26,pwm:[12,25],pwm_breath_l:43,pwm_cfg:[43,44],pwm_ch0:44,pwm_ch0_config:[8,44],pwm_ch0_index:[8,44],pwm_ch1:44,pwm_ch1_config:[8,44],pwm_ch1_index:[8,44],pwm_ch2:[43,44],pwm_ch2_config:[8,43,44],pwm_ch2_index:[8,43,44],pwm_ch3:44,pwm_ch3_config:[8,44],pwm_ch3_index:[8,44],pwm_ch4_config:8,pwm_ch4_index:8,pwm_channel_start:[43,44],pwm_clock_sourc:8,pwm_close:8,pwm_config_t:8,pwm_control:8,pwm_dev:[8,43,44],pwm_devic:8,pwm_device_t:8,pwm_dutycycle_config_t:[8,44],pwm_event_complet:8,pwm_event_typ:8,pwm_index_typ:8,pwm_max_index:8,pwm_open:8,pwm_regist:[43,44],pwm_step_motor:44,pwmx_devic:8,queri:5,queue:1,quick:[25,27,29],quickli:[17,29],radio:1,ram:[29,34],random:1,rang:[1,9,25],rate:[11,16,18,20],reach:8,read:[0,1,2,5,6,7,9,11,23,25,30,31,39],readi:15,real:[1,27,30],realiz:[0,27],reason:1,receiv:[0,1,2,5,7,8,9,10,11,26,27,30,50],recept:1,recogn:[16,23],recommend:[6,13,15,16,17,19,23],record:0,recurs:[13,14,15],recv_buf:9,redefin:[5,8],reduc:[17,29,41],ref:1,refer:[2,8,13,14,15,16,17,18,19,20,21,22,27,29,30,31,33,35,36,38,41,43,46,48,50],refresh:[16,22],regard:[0,14],regist:[0,1,2,5,6,7,8,9,10,11,16,18,20,26,30,31,33,36,38,41,43,46,48,50],registr:[0,2,5,7,8,9,10,11],rel:19,relat:[1,6,13,14,15,18,20,21,31],relationship:7,releas:[13,16,22,23,27],relev:[18,20,29],reli:21,reload:[10,48],remark:29,rememb:22,remot:1,remov:1,replac:[15,16,23],repli:1,repositori:23,repres:[0,38],reprint:29,request:[1,5],requir:[1,2,5,8,9,17,18,22,23],required_sec_level:1,reserv:27,reset:[10,17,29],resolut:1,resolv:1,resourc:[1,14],respons:1,restart:[15,23],restor:46,result:[2,18,20,29,30,31],result_v:31,resum:[0,1,9,11],rewrit:0,rich:[25,29],right:[15,18,19,20,30],risc:[15,25,41],riscv64:13,rise:[6,36],role:1,rom:[16,22],root_clock_source_bclk:[38,46],root_clock_source_fclk:48,root_clock_source_pll_96m:[30,50],root_clock_source_rc_32k:44,root_clock_source_xclk:[31,43],rotat:[2,11],row:22,rpa:1,rssi:1,rst:[13,15,16,18,20,22],rtc:29,rto:[11,50],rule:17,run:[1,27,29],rx0:22,rx_dma:[9,11],rx_fifo:50,rx_len:1,rxd0:15,rxd:22,sai:8,same:[2,5,7,8,13,16,17,19,21,22,26,29],sampl:25,save:[0,13,15,19,29,30,31,33,38,43,46,48,50],scan:[1,26,30],scan_param:1,scan_rsp:1,scenario:29,schemat:22,sclk:9,sco:1,screen:22,sd_len:1,sdi:9,sdk:[6,13,14,15,17,18,19,20,21],sdk_path:[26,30,31,33,35,36,38,41,43,44,46,48,50],sdo:9,search:0,sec:1,sec_level:1,second:[19,21,27,29,41,47],section:[17,22,23],secur:1,see:[13,15,16,17,18,20,22,23,26,29,30,31,33,35,36,38,41,43,46,48,50],seek:29,segger:[15,16],select:[0,2,3,5,7,8,9,10,11,13,15,16,17,18,19,20,23,29,46],semiconductor:14,send:[0,1,2,5,7,8,9,10,11,26,30,46,50],send_buf:9,sent:1,sentenc:[18,20],separ:[1,22],seri:[2,3,5,6,7,8,9,10,11,13,14,15,17,22,23,25,29],serial:[0,2,7,9,11,13,14,15,16,18,20,23,29,33,36,41,50],server:[1,25],servic:[1,26,30,50],set:[0,1,3,6,7,8,10,13,14,15,17,18,19,20,22,24,26,29,41,43],setup:[14,25],sever:[13,14,15],shape:8,share:17,shell:25,shell_cmd_export:30,shell_cmd_export_alia:30,shell_handl:30,shell_init:30,shell_irq_callback:30,shortcut:[18,20],should:[16,19,23,30],show:[16,23],shown:[1,15,17,18,20,22,23,26,29],shut:29,side:[1,17,22,29,30],sifiv:25,signal:[2,8],similar:[14,23,30],simpl:[1,29],simplifi:29,simul:6,simultan:27,sinc:[18,19,20],singl:[2,15,18,20],sipe:[13,14,16],size:[0,1,2,5,8,9,10,11,17,30,33,48,50],size_t:1,sizeof:[26,48],sky:18,slave:[1,7,9],slaveaddr:[7,38],sleep:29,sleeptim:29,slow:8,smp:1,socket:22,softwar:[7,17,18,27,29],solicit:1,some:[0,5,8,17,22,27],sourc:[3,5,8,10,13,14,15,17,19,27,29,30,31,33,38,43,46,48,50],special:[2,5,6,8,9,10,11],specif:[1,9,14,15,17,18,19,21,24,26,27,29,30,50],specifi:[1,7,13,15,50],spectrum:1,speed:[7,16,17,18,20],spi0:[9,46],spi0_config:[9,46],spi0_index:[9,46],spi:[0,5,12,22,25],spi_clos:9,spi_config:46,spi_control:9,spi_datasize_16bit:9,spi_datasize_24bit:9,spi_datasize_32bit:9,spi_datasize_8bit:[9,46],spi_dev:9,spi_devic:9,spi_device_t:9,spi_event_rx_fifo:9,spi_event_tx_fifo:9,spi_event_typ:9,spi_event_unknown:9,spi_index_typ:9,spi_lcd:46,spi_lsb_byte0_direction_first:9,spi_lsb_byte3_direction_first:9,spi_master_mod:[9,46],spi_max_index:9,spi_miso:46,spi_mosi:46,spi_msb_byte0_direction_first:[9,46],spi_msb_byte3_direction_first:9,spi_open:9,spi_phase_1edg:[9,46],spi_phase_2edg:9,spi_polarity_high:9,spi_polarity_low:[9,46],spi_read:9,spi_regist:46,spi_sck:46,spi_slvae_mod:9,spi_swap_en:46,spi_transfer_tpye_24bit:9,spi_transfer_type_16bit:[9,46],spi_transfer_type_32bit:[9,46],spi_transfer_type_8bit:[9,46],spi_transmit:46,spi_writ:9,spix_devic:9,squar:8,src_addr:5,src_burst_siz:5,src_req:[5,33],src_width:[5,33],stack:1,standard:[1,2,5,6,7,8,9,10,11,22,23,30],start:[1,2,8,15,17,18,20,23,25,26,30,31,33,35,36,38,41,43,44,46,48,50],state:[1,13,29,30,33,48,50],statement:29,statu:[0,5,10,16],status:0,step:[13,14,15,18,19,20,21,22,24,26,27,30,31,33,35,36,38,41,43,46,48,50],stepper:42,still:23,stm32:17,stm32xxx_hal_msp:17,stop:[1,2,11,15,18,20,29,44],stopbit:[11,30,50],storag:1,store:[0,5,19,21],strlen:26,struct:[0,1,2,5,7,8,9,10,11,26,30,33,38,43,48,50],structur:[0,31],sub_addr_0byt:7,sub_addr_1byt:[7,38],sub_addr_2byt:7,subaddr:[7,38],subclass:0,subdirectori:[19,21],subsystem:13,subvers:1,success:[0,1,5,7,8,9,10,11,15,16,18,23,26,29,33,38],successfulli:[2,15],sudo:[13,23],suitabl:[16,22,24],supplement:33,suppli:[22,29],support:[1,2,7,8,9,10,11,14,15,16,17,19,20,23,25,26,29,30],support_bl:26,support_float:26,support_freerto:[21,26],support_shel:[29,30],sure:[13,14,15,16,19,22],suspend:[0,9,11],sw1:[31,36],sw5:31,swap:46,sync:11,synchron:9,sys_slist_t:1,sysinit:17,system:[3,5,10,13,16,18,20,23,25,29,30,40],system_clock_32k_clk:3,system_clock_aupl:3,system_clock_bclk:3,system_clock_fclk:3,system_clock_root_clock:3,system_clock_typ:3,system_clock_xclk:3,systemclock_config:17,systick:[17,41],systick_isr:41,tab:[17,18,19],tabl:[3,6,29],tag:19,take:[1,2,5,7,8,9,10,11,16,17,22,23,29],taken:1,tar:13,target:[1,23,27,33],target_required_lib:21,target_required_private_opt:21,target_required_src:21,task:[1,23,33],task_prior:1,tck:22,tdi:22,tdo:22,technic:29,technolog:[5,8,23],temperatur:2,temporarili:7,termin:[13,14,15,17,23,30],test1:21,test2:21,test:[19,21,30],text:[17,19],tft:45,than:[17,23],them:17,therefor:13,thi:[0,1,2,5,7,8,9,10,11,13,14,15,16,17,18,19,20,21,22,23,26,29,30,31,33,35,36,38,41,43,46,48,50],thing:1,three:[8,10,15,17],threshold:[2,8,9,11],threshold_high:[8,43,44],threshold_low:[8,43,44],through:[2,5,6,7,8,9,10,11,18,20,22,25,27,29,30,33,41,50],thu:17,tick:41,tightli:22,time:[1,2,7,8,13,16,17,21,22,23,26,29,30,41,47],timeout1:[10,48],timeout2:[10,48],timeout3:[10,48],timeout:[1,9,10,48],timer0:48,timer0_config:[10,48],timer0_index:[10,48],timer0_irq_callback:48,timer1_config:10,timer1_index:10,timer:[12,25,40],timer_ch0_config:10,timer_ch0_index:10,timer_cnt_freerun:10,timer_cnt_mode_typ:10,timer_cnt_preload:[10,48],timer_comp0_it:48,timer_comp1_it:48,timer_comp2_it:48,timer_control:10,timer_dev:10,timer_devic:10,timer_device_t:10,timer_event_comp0:[10,48],timer_event_comp1:[10,48],timer_event_comp2:[10,48],timer_event_typ:10,timer_event_unknown:10,timer_index_typ:10,timer_int:48,timer_it_typ:10,timer_max_index:10,timer_open:10,timer_preload_trigger_comp0:10,timer_preload_trigger_comp1:10,timer_preload_trigger_comp2:[10,48],timer_preload_trigger_non:10,timer_preload_trigger_typ:10,timer_regist:48,timer_timeout_cfg_t:[10,48],timer_writ:10,timerx_devic:10,timout:10,todo:[1,7],togeth:1,toggl:6,tool:[14,18,20,22,23,26],toolbar:[15,18,20],toolchain:15,top:[18,20],total:[5,33],tp_wr_hdl:26,tradit:14,transceiv:[7,11],transfer:[1,5,7,9,11,34,38],transfer_mod:[5,33],transfer_s:5,transmiss:[0,1,2,5,7,8,9,10,11,33],transmit:[1,7,9],transmitt:[7,11],tree:12,trigger:[8,10,29,36,48],ttl:[13,14,15,22,27,29],ttyacm0:23,ttyusb0:23,ttyusb1:[13,23],turn:[0,1,2,5,6,7,8,9,10,11,16,26,29,31],tutori:[16,18,19,20],two:[0,1,6,7,10,11,13,16,17,19,21,22,23,26,27,30,38],tx0:22,tx_complet:1,tx_complete_work:1,tx_dma:[9,11],tx_mtu_siz:26,tx_pend:1,tx_queue:1,txd0:15,txd:22,txt:[19,21],tyep:5,type:[0,1,2,3,5,6,7,8,9,10,11,14,15,16,17,22,23,50],typedef:[0,2,5,7,8,9,10,11],u16_t:[1,26],u32_t:1,u8_t:[1,26],uart0:[5,11,22,30,50],uart0_config:[11,30,50],uart0_index:11,uart0_rx:[30,50],uart0_tx:[30,50],uart1:5,uart1_config:11,uart1_index:11,uart5:17,uart5_irqn:17,uart5_mspinit:17,uart5_rx:17,uart5_tx:17,uart:[12,13,23,25,29,30],uart_clos:11,uart_control:11,uart_data_len_5:11,uart_data_len_6:11,uart_data_len_7:11,uart_data_len_8:[11,30,50],uart_databits_t:11,uart_dev:11,uart_devic:11,uart_device_t:11,uart_echo:50,uart_event_rto:[11,50],uart_event_rx_end:11,uart_event_rx_fifo:[11,30,50],uart_event_tx_end:11,uart_event_tx_fifo:11,uart_event_typ:11,uart_event_unknown:11,uart_handletypedef:17,uart_index_typ:11,uart_irq_callback:50,uart_it_typ:11,uart_max_index:11,uart_open:11,uart_par_even:11,uart_par_non:[11,30,50],uart_par_odd:11,uart_param_cfg_t:11,uart_parity_t:11,uart_read:11,uart_regist:[30,50],uart_rto_it:50,uart_rx_fifo_it:[30,50],uart_stop_on:[11,30,50],uart_stop_one_d_f:11,uart_stop_two:11,uart_stopbits_t:11,uart_writ:11,uartx_devic:11,ubuntu:[13,23],uint16_t:[0,2,5,7,8,9,10,11,46],uint32_t:[0,2,3,5,6,7,8,9,10,11,30,33,36,41,46,48,50],uint8_t:[1,2,5,6,7,8,9,10,11,26,30,38,46,50],uln2003:44,under:[1,2,3,5,6,7,8,9,10,11,13,16,18,19,21,23,30,31,33,35,36,38,41,43,44,46,48,50],undirect:26,uniform:1,union:1,uniqu:[0,7,11],unit:10,univers:[11,16,23],unknow:26,unsign:1,until:2,unus:[5,8,10],unzip:[14,15],updat:[1,5,8,13,27],update_work:1,upload:[13,26],upper:[15,18,20],upward:22,usabl:17,usart:27,usb:[5,13,14,15,16,22,23,27,29,30],use:[0,1,2,6,7,8,9,10,11,13,14,15,16,17,20,22,23,27,29,30,31,33,38,41,43,46,48,50],used:[0,1,2,3,5,6,7,8,9,10,11,13,16,17,20,21,22,23,25,29,31,46],useless:[9,11],user:[0,1,2,3,5,6,7,8,9,10,11,13,14,16,25,27,29,30,50],uses:[1,7,20,26,30],using:[0,1,5,7,8,15,16,17,18,19,20,22,23,27,30,31,33,35,36,38,41,43,44,46,48,50],usr:13,usual:[16,19,21],uuid:1,v10:16,v11:[16,23],valid:1,valu:[1,6,8,10,11,29,30,31,35,41],variabl:[2,5,7,8,9,10,11],vbat:2,vdd33:22,vdd:[2,22],veri:[14,17],version:[1,16,17,19,23,27],via:30,video:[31,35,43,50],view:[16,18,20,30],viewer:[18,20],virtual:13,volt:31,voltag:[2,8,32],vref:[2,22,31],vtref:22,wai:[0,8,11],wait:1,wake:29,want:[13,15,26,46],warn:1,watchdog:10,wave:8,waveform:8,websit:[14,16,23],welcom:15,well:[17,25],wfi:29,wget:13,when:[0,1,2,5,7,8,9,10,11,14,15,16,17,18,20,22,23,27,29,36,50],where:[0,5,8,15,26],whether:[2,5,7,13,18,22,23,30,31,33,48],which:[0,1,5,6,9,10,11,17,19,29,30,31,41],whitelist:1,whitout:[18,20],who:16,wide:25,width:[2,5,8,9,33],wifi:30,win:23,window:[1,13,17,18,20,23,29,30,31,33,35,36,38,41,43,44,46,48,50],windows_cdk:24,windows_eclips:24,winusb:[16,23],wire:[9,22],wireless:0,without:[1,5,14,15,18,20,22,23,29],wizard:17,word:9,work:[1,2,15,17],workspac:15,world:30,worri:5,write:[0,5,7,9,10,11,21,23,25,26,27,29,39],write_data_poll_sem:26,written:[0,9,11],x86_64:13,xshell:30,xtal_ck:8,xxx:[2,5,7,8,9,10,11,15,19],xxx_board:[3,6],xxx_close:0,xxx_config:17,xxx_control:0,xxx_devic:0,xxx_device_t:0,xxx_open:0,xxx_read:0,xxx_regist:0,xxx_write:0,xxxx_case:[19,21],you:[1,2,5,8,9,10,11,13,14,15,16,17,18,19,20,21,22,23,26,27,29,46],your:[13,15,16,17,18,19,20,21,23,29],yourself:[13,17,21,36,38],zadig:[16,23],zigbe:25,zxvf:13},titles:["1. API Overview","3. BLE","2.8. ADC","2.1. Clock tree","2.9. DAC","2.5. DMA","2.2. GPIO","2.6. I2C","2.4. PWM","2.7. SPI","2.10. TIMER","2.3. UART","2. Peripheral","3.3. Linux OR WSL environment development guide","3.1. Guide to using CDK (like MDK Keil) under Windows","3.2. Eclipse Development Guide under Windows","6. BLDevCube start guide","7. Board Configuration System User Guide","Use CDK + CK-Link to compile and debug","5. New Project Guide based on CDK","Use CDK + Sipeed RV-Debugger Plus to compile and debug","4. New Project Guide based on cmake framework","2. Hardware connection","1. Preparation","3. Development environment setup guide","BL MCU SDK development guide","5. BLE Client And Server Interconnection","4. BOOT2 IAP","2. FATFS Read And Write","3. LowPower Evaluation","1. SHELL Command Debugging","8.1. ADC - Key Detection Voltage","8. ADC","5.1. DMA - Data Transfer Between RAM","5. DMA","1.1. GPIO output - Lamp LED","1.2. GPIO interrupt - Button detection","1. GPIO","7.1. I2C - AT24CXX read and write","7. I2C","4. MTIMER","4.1. MTIMER - System Timer","3. PWM","3.1. PWM - Breathing LED","3.2. PWM - \u9a71\u52a8\u6b65\u8fdb\u7535\u673a","6. SPI","6.1. SPI - TFT LCD Display","9. TIMER","9.1. TIMER - Second Timing Interrupt","2. UART","2.1. UART - Loopback"],titleterms:{"\u5b9e\u9a8c\u73b0\u8c61":44,"\u786c\u4ef6\u8fde\u63a5":44,"\u7f16\u8bd1\u548c\u70e7\u5f55":44,"\u8f6f\u4ef6\u5b9e\u73b0":44,"\u9a71\u52a8\u6b65\u8fdb\u7535\u673a":44,"import":15,"new":[17,19,21],And:[26,28],The:17,Use:[17,18,20,22,29],acquisit:3,adapt:0,adc:[2,31,32],adc_regist:2,add:[19,21],api:[0,1],at24cxx:38,avb:22,base:[19,21],between:33,bl706:22,bl706_avb:22,bl706_iot:22,bl_config_wizard:17,bl_mcu_sdk:[13,14,15],bldevcub:16,ble:[1,26],blxxx_config:17,board:17,boot2:27,bouffalo:16,breath:43,button:36,cdk:[14,17,18,19,20],client:26,clock:3,clock_config:17,cmake:[13,21],code:29,command:30,compil:[13,15,18,20,21,26,29,30,31,33,35,36,38,41,43,46,48,50],configur:[2,4,5,7,8,9,10,11,13,15,16,17],connect:[13,14,15,22,30,31,33,35,36,38,41,43,46,48,50],consumpt:29,cube:16,dac:4,data:[1,33],debug:[13,15,18,20,22,30],debugg:[20,22,23],definit:[2,4,5,7,8,9,10,11],depend:21,detect:[31,36],dev:16,develop:[13,15,24,25],devic:[0,2,4,5,6,7,8,9,10,11],device_clos:[0,2,5,8,9,10,11],device_control:[0,2,5,8,9,10,11],device_find:0,device_open:[0,2,5,7,8,9,10,11],device_read:[0,2,9,11],device_regist:0,device_set_callback:[0,2,5,8,9,10,11],device_unregist:0,device_writ:[0,9,10,11],differ:[15,17],directori:[19,21],displai:46,dma:[5,33,34],dma_channel_check_busi:5,dma_channel_start:5,dma_channel_stop:5,dma_channel_upd:5,dma_regist:5,dma_reload:5,download:[14,15,16],driver:[0,23],each:17,eclips:15,environ:[13,14,15,23,24,29],evalu:29,exampl:[19,21,29],experiment:[26,27,30,31,33,35,36,38,41,43,46,48,50],fatf:28,featur:17,file:[17,19,21],framework:21,frequenc:3,gcc:21,gener:17,get:13,gpio:[6,35,36,37],gpio_attach_irq:6,gpio_irq_en:6,gpio_read:6,gpio_set_mod:6,gpio_toggl:6,gpio_writ:6,guid:[13,14,15,16,17,19,21,24,25],hardwar:[13,14,15,22,23,29,30,31,33,35,36,38,41,43,46,48,50],hello:[13,14,15,18,20],i2c:[7,38,39],i2c_regist:7,i2c_transf:7,iap:27,implement:[26,30,31,33,35,36,38,41,43,46,48,50],instal:23,interconnect:26,interfac:[0,2,3,4,5,6,7,8,9,10,11],interrupt:[36,48],introduct:[0,1,2,3,4,5,6,7,8,9,10,11,29],its:21,jlink:16,kei:31,keil:14,lab:16,lamp:35,layer:0,lcd:46,led:[35,43],librari:21,like:14,link:[18,21,22],linux:13,loopback:50,low:29,lowpow:29,make:13,manag:0,mcu:25,mdk:14,method:[16,29],modifi:17,modul:22,mtimer:[40,41],multipl:21,open:[13,15,18,20],openocd:16,option:21,origin:17,output:35,overview:0,paramet:[2,4,5,7,8,9,10,11],perform:29,peripher:[0,12],peripheral_clock_get:3,peripheral_config:17,phenomena:[26,27,30,31,33,35,36,38,41,43,46,48,50],pinmux_config:17,plu:[20,22,23],port:[22,30],power:29,prepar:[23,26,27,29,30],privat:21,program:[13,15,18,20,22,26,30,31,33,35,36,38,41,43,46,48,50],project:[13,14,15,19,21],pwm:[8,42,43,44],pwm_channel_start:8,pwm_channel_stop:8,pwm_channel_upd:8,pwm_it_pulse_count_upd:8,pwm_regist:8,ram:33,read:[28,38],refer:1,registr:30,relat:19,requir:29,risc:13,run:[13,15,18,20],sampl:29,script:21,sdk:25,second:48,serial:[22,30],server:26,set:[21,23],setup:24,shell:30,singl:21,sipe:[20,22,23],softwar:[13,14,15,23,26,30,31,33,35,36,38,41,43,46,48,50],sourc:21,spi:[9,45,46],spi_rec:9,spi_regist:9,spi_transmit:9,spi_transmit_rec:9,standard:0,start:[16,29],stm32cubemx:17,structur:[1,2,4,5,7,8,9,10,11,19,21],sub:22,system:[17,41],system_clock_get:3,tabl:[2,4,5,7,8,9,10,11],table1:[2,5,8,9,10,11],target:15,test:[13,14,15,29],tft:46,time:48,timer:[10,41,47,48],timer_regist:10,tool:[13,16,17],toolchain:13,transfer:33,tree:3,uart:[11,16,49,50],uart_regist:11,under:[14,15],user:17,using:14,voltag:31,window:[14,15],world:[13,14,15,18,20],write:[28,38],wsl:13,xshell:29}}) \ No newline at end of file diff --git a/docs/development_guide_en/make.bat b/docs/development_guide_en/make.bat new file mode 100644 index 00000000..6247f7e2 --- /dev/null +++ b/docs/development_guide_en/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=source +set BUILDDIR=build + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/docs/development_guide_en/source/api_reference/api_overview.rst b/docs/development_guide_en/source/api_reference/api_overview.rst new file mode 100644 index 00000000..42ecb8fb --- /dev/null +++ b/docs/development_guide_en/source/api_reference/api_overview.rst @@ -0,0 +1,288 @@ +API Overview +========================= + +Introduction +------------------ + +**bl_mcu_sdk** code hierarchy is divided into the following main layers. + +- The application layer: codes written by users. +- The component layer: some opensource components,the interface calls the HAL layer, while the wireless layer is used for wireless functions. +- HAL layer and wireless layer for adaptation to different MCUs, where the HAL layer is divided into two layers + - Device driver management: provides a standard set of interfaces, which are implemented by the peripheral driver adaptation layer + - Peripheral driver adaptation layer: implements the standard interface of the device driver management and extends its own unique interface +- Standard driver layer based on register packaging +- Hardware layer, also known as the register layer + +.. figure:: img/sw_arch.png + :alt: + + code structure + +Device driver management layer +--------------------------------- + +The realization of the device driver management layer adopts the object-oriented idea. First of all, we regard the peripheral as a device or a file, adhering to the concept of **everything is a file**, and files have standard calling interfaces: ``open``, ``close``, ``ctrl``, ``write``, ``read``, ``callback``. Different file types are different (such as serial device, ADC device, SPI device), and the way of opening is also different (such as polling, interrupt, DMA), from this, we can construct a base class (parent class) of an object. + +**Base class** + +.. 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; + }; + +**Base class member: name** + +Name the device and use ``device_find`` to find the device. + +**Base class member: type** + +``type`` records the category of the current device, and the ``type`` that can be selected are as follows. + +.. 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, + } ; + +**Base class member: status** + +``status`` is used to record the current status of the device and provides 4 statuses. + +.. code-block:: C + + enum device_status_type + { + DEVICE_UNREGISTER = 0, + DEVICE_REGISTERED, + DEVICE_OPENED, + DEVICE_CLOSED + } ; + +**Base class member: oflag** + +``oflag`` records the flag information filled in during registration and the ``oflag`` information filled in when using ``device_open``. + +**Base class members: list** + +The addition and deletion of equipment is stored in a doubly linked list, which saves memory. + +**Base class members: standard function pointers** + +Provides a standard function interface for different peripherals. When the peripheral implements this type of interface and assigns it to the member, the function of rewriting can be achieved. + +Device driver management layer standard interface +--------------------------------------------------- + +**device_register** +^^^^^^^^^^^^^^^^^^^^ + +``device_register`` is used to register the device and register the device information in the linked list. + +.. code-block:: C + + int device_register(struct device *dev, const char *name); + +- dev: device handle. +- name: the name of the device. +- return: return error code, 0 means registration is successful, others mean errors. + +**device_unregister** +^^^^^^^^^^^^^^^^^^^^^^^ + +``device_unregister`` is used to delete the device and delete the device information from the linked list. + +.. code-block:: C + + int device_unregister(const char *name); + +- dev: device handle +- name: the name of the device to be deleted +- return: error code, 0 means delete, others mean error + +**device_find** +^^^^^^^^^^^^^^^^ + +``device_find`` is used to find the device from the linked list according to ``name``, and return the first address of the device handle. + +.. code-block:: C + + struct device *device_find(const char *name); + +- dev: device handle +- name: the name of the device to be searched +- return: error code,! 0 means the device handle was found, NULL means the device was not found. + + +**device_open** +^^^^^^^^^^^^^^^^ + +``device_open`` is used to open the device, and ``oflag`` represents the opening method. Currently, there are 6 opening methods available. The bottom layer calls the ``open`` member in the ``dev`` handle. + +.. code-block:: C + + int device_open(struct device *dev, uint16_t oflag); + +- dev: device handle +- oflag: open method +- return: error code, 0 means opening is successful, others mean errors + +``oflag`` can write the following parameters: + +.. code-block:: C + + #define DEVICE_OFLAG_STREAM_TX 0x001 /* The device is turned on in polling sending mode */ + #define DEVICE_OFLAG_STREAM_RX 0x002 /* The device is turned on in polling receiving mode */ + #define DEVICE_OFLAG_INT_TX 0x004 /* The device is turned on in interrupt sending mode */ + #define DEVICE_OFLAG_INT_RX 0x008 /* The device is turned on in interrupt receiving mode */ + #define DEVICE_OFLAG_DMA_TX 0x010 /* The device is turned on in DMA transmission mode */ + #define DEVICE_OFLAG_DMA_RX 0x020 /* The device is turned on in DMA receiving mode */ + +**device_close** +^^^^^^^^^^^^^^^^ + +``device_close`` is used to close the device. The bottom layer calls the ``close`` member in the ``dev`` handle. + +.. code-block:: C + + int device_close(struct device *dev); + +-dev: device handle +-return: error code, 0 means closing is successful, others mean error + +**device_control** +^^^^^^^^^^^^^^^^^^^ + +``device_control`` is used to control the device and modify parameters according to commands. The bottom layer calls the ``control`` member in the ``dev`` handle. + +.. code-block:: C + + int device_control(struct device *dev, int cmd, void *args); + +- dev: device handle +- cmd: device control command +- args: control parameters +- return: Different control commands return different meanings. + +``cmd`` provides the following standard commands. In addition, different peripherals also have their own commands + +.. 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`` is used to send data, and the sending mode can be polling, interrupt, dma. The bottom layer calls the ``write`` member in the ``dev`` handle. + +.. code-block:: C + + int device_write(struct device *dev, uint32_t pos, const void *buffer, uint32_t size); + +- dev: device handle +- pos: different devices have different meanings for pos +- buffer: the buffer to be written +- size: the length to be written +- return: error code, 0 means writing is successful, others mean errors + +**device_read** +^^^^^^^^^^^^^^^^ + +``device_read`` is used to receive data, and the receiving mode can be polling, interrupt, dma. The bottom layer calls the ``read`` member in the ``dev`` handle. + +.. code-block:: C + + int device_read(struct device *dev, uint32_t pos, void *buffer, uint32_t size); + +- dev: device handle +- pos: different devices have different meanings for pos +- buffer: the buffer to be read +- size: the length to be read +- return: error code, 0 means successful reading, others mean errors + +**device_set_callback** +^^^^^^^^^^^^^^^^^^^^^^^^ + +``device_set_callback`` is used to register interrupt callback function. The bottom layer calls the ``callback`` member in the ``dev`` handle. + +.. code-block:: C + + int device_set_callback(struct device *dev, void (*callback)(struct device *dev, void *args, uint32_t size, uint32_t event)); + +- dev: device handle +- callback: the interrupt callback function to be registered + + + * dev: device handle + * args: Different peripherals have different meanings + * size: transmission length + * event: interrupt event type + +Peripheral driver adaptation layer +--------------------------------------- + +**Subclass inherits from parent class** + +The first member of different peripherals is ``struct device``, which is equivalent to the inheritance of the parent class, so that the subclass can be used to access the parent class member. When the subclass is used to modify the members of the parent class, it has its own functions. The realization principle is that the first address of different structures is the address of the first member in the structure. + +.. code-block:: C + + typedef struct xxx_device + { + struct device parent; + + } xxx_device_t; + +**Rewrite standard interface** + +Each peripheral has a ``xxx_register`` function, which is used to rewrite the standard interface. + +.. code-block:: C + + dev->open = xxx_open; + dev->close = xxx_close; + dev->control = xxx_control; + dev->write = xxx_write; + dev->read = xxx_read; diff --git a/docs/development_guide_en/source/api_reference/bluetooth/api_ble.rst b/docs/development_guide_en/source/api_reference/bluetooth/api_ble.rst new file mode 100644 index 00000000..0a7d871f --- /dev/null +++ b/docs/development_guide_en/source/api_reference/bluetooth/api_ble.rst @@ -0,0 +1,708 @@ +.. _ble-index: + +BLE +================== + +Introduction +------------------- +- Features + + HOST + - GAP support peripheral and Central, Observer and Broadcaster + - GATT support server and Client + - Support pairing with the secure connection feature in Bluetooth 4.2 + - Support permanent storage of Bluetooth specific settings and data + + mesh + - TODO + +- The architecture of the BLE protocol stack: + .. figure:: img/image1.png + + + There are 3 main layers, which together form a complete Bluetooth low power protocol stack + - Host: Under the application program, it is composed of multiple (non-real-time) networks and transmission protocols, enabling the application program to communicate with peer devices in a standard and interoperable manner + - Controller:The controller implements the link layer (LE LL), which is a low-level real-time protocol that provides standard interoperability for over-the-air communication with the radio. LL handles the reception and transmission of packets, guarantees the transfer of data, and handles all LL control procedures + - Radio Hardware:Implement analog and digital baseband functions, allowing link layer firmware to transmit and receive in the 2.4GHz band of the spectrum + +- Master Host: + .. figure:: img/image2.png + + * The Bluetooth Host layer implements all high-level protocols and configuration files, the most important thing is that it provides high-level APIs for applications + - HCI: Host and controller interface + - L2CAP: Logical Link Control and Adaptation Protocol + - GATT: Generic Attribute Profile + - GAP: Generic Access Profile + - SMP: Security Manager Specification + +- Application + * The application layer contains the necessary protocol stack parameter settings and api reference. We analyze the two devices separately from the Bluetooth slave and the Bluetooth master + * Bluetooth slave + - Hardware and basic service initialization + - Set broadcast parameters: broadcast data, broadcast interval, scan response, etc + - Profile settings: add slave services, feature values, and set callback functions to receive host data, etc + - Set pairing parameters (optional) + - Start the broadcast, start running + - Waiting for related events, and event processing, such as receiving data from the host, being linked, etc + * Bluetooth host + - Related hardware and basic service initialization + - Set scan parameters + - Set connection parameters + - Set pairing parameters (optional) + - Start the protocol stack and start running + - Wait for related events, and event processing, such as scan events, Notify events from slaves, etc + +API +---------- + +- API introduction + +``void ble_controller_init(uint8_t task_priority)`` + +:: + + /** + * function Controller layer initialization + * @param[in] task_priority: task priority + * @return None + */ + +``int hci_driver_init(void)`` + +:: + + /** + * function HCI interface driver initialization + * @param[in] None + * @return 0: success, !=0: fail + */ + +``int bt_enable(bt_ready_cb_t cb)`` + +:: + + /** + * function BLE enable + * @param[in] cb: Call the callback function if successful + * @return 0: success, !=0: fail + */ + +``int bt_le_adv_start(const struct bt_le_adv_param *param,const struct bt_data *ad, size_t ad_len,`` + ``const struct bt_data *sd, size_t sd_len)`` + +:: + + /** + * function Turn on BLE broadcast + * + * @param[in] param: Pointer to broadcast configuration parameter + * @param[in] ad: Pointer to the data in the broadcast packet + * @param[in] ad_len: The length of the data in the broadcast packet + * @param[in] sd: Pointer to scan response packet data + * @param[in] sd_len: Scan response packet data length + * @return 0: success, !=0: fail + */ + + +``int bt_le_adv_update_data(const struct bt_data *ad, size_t ad_len,const struct bt_data *sd, size_t sd_len)`` + + +:: + + /** + * function Update BLE broadcast data + * @param[in] ad: Pointer to the data in the broadcast packet + * @param[in] ad_len: The length of the data in the broadcast packet + * @param[in] sd: Pointer to scan response packet data + * @param[in] sd_len: Scan response packet data length + * @return 0: success, !=0: fail + */ + +``int bt_le_adv_stop(void)`` + + +:: + + /** + * function Stop BLE broadcast + * @param[in] None + * @return 0: success, !=0: fail + */ + + +``int bt_le_scan_start(const struct bt_le_scan_param *param, bt_le_scan_cb_t cb)`` + +:: + + /** + * function Turn on BLE scanning + * @param[in] param: Pointer to scan parameter + * @param[in] cb: Scan callback function + * @return 0: success, !=0: fail + */ + +``int bt_le_scan_stop(void)`` + +:: + + /** + * function Stop BLE scanning + * @param[in] None + * @return 0: success, !=0: fail + */ + +``int bt_le_whitelist_add(const bt_addr_le_t *addr)`` + +:: + + /** + * function Add devices to the whitelist by address + * @param[in] addr: Pointer to the address of the device that needs to be added + * @return 0: success, !=0: fail + */ + +``int bt_le_whitelist_rem(const bt_addr_le_t *addr)`` + +:: + + + /** + * function Remove the device from the whitelist + * @param[in] addr: Pointer to the address of the device that needs to be removed + * @return 0: success, !=0: fail + */ + +``int bt_le_whitelist_clear(void)`` + + +:: + + /** + * function Clear the whitelist list + * @param[in] None + * @return 0: success, !=0: fail + */ + +``int bt_le_set_chan_map(u8_t chan_map[5])`` + +:: + + /** + * function Set (LE) channel mapping + * @param[in] chan_map: channel array + * @return 0: success, !=0: fail + */ + +``int bt_unpair(u8_t id, const bt_addr_le_t *addr)`` + +:: + + /** + * function Clear pairing information + * @param[in] id: Local ID (mostly just the default BT ID) + * @param[in] addr: Remote device address, NULL or BT_ADDR_LE_ANY to clear all remote devices + * @return 0: success, !=0: fail + */ + +``int bt_conn_get_info(const struct bt_conn *conn, struct bt_conn_info *info)`` + +:: + + /** + * function Get the information of the currently connected device + * @param[in] conn: Pointer to the current connection + * @param[in] info: Pointer to the information of the currently connected device + * @return 0: success, !=0: fail + */ + + +``int bt_conn_get_remote_dev_info(struct bt_conn_info *info)`` + +:: + + /** + * function Get information about connected devices + * @param[in] info: Pointer to the information of the currently connected device + * @return Number of connected devices + */ + +``int bt_conn_le_param_update(struct bt_conn *conn,const struct bt_le_conn_param *param)`` + +:: + + /** + * function Update connection parameters + * @param[in] conn: Pointer to the current connection + * @param[in] param: Pointer to connection parameter + * @return 0: success, !=0: fail + */ + +``int bt_conn_disconnect(struct bt_conn *conn, u8_t reason)`` + +:: + + /** + * function Disconnect current connection + * @param[in] conn: pointer to the current connection + * @param[in] reason: the reason for disconnecting the current connection + * @return 0: success, !=0: fail + */ + +``struct bt_conn *bt_conn_create_le(const bt_addr_le_t *peer,const struct bt_le_conn_param *param)`` + +:: + + /** + * function Create connection + * @param[in] peer: The pointer of the device address that needs to be connected + * @param[in] param: Pointer to connection parameter + * @return Success: a valid connection object, otherwise it fails + */ + + +``int bt_conn_create_auto_le(const struct bt_le_conn_param *param)`` + +:: + + /** + * function Automatically create and connect to devices in the whitelist + * @param[in] param: pointer to connection parameter + * @return 0: success, !=0: fail + */ + +``int bt_conn_create_auto_stop(void)`` + +:: + + /** + * function Stop automatic creation and connect to devices in the whitelist + * @param[in] None + * @return 0: success, !=0: fail + */ + +``int bt_le_set_auto_conn(const bt_addr_le_t *addr,const struct bt_le_conn_param *param)`` + +:: + + /** + * function Automatically create a connection to the remote device + * @param[in] addr: Remote device address pointer + * @param[in] param: Pointer to connection parameter + * @return 0: success, !=0: fail + */ + +``struct bt_conn *bt_conn_create_slave_le(const bt_addr_le_t *peer,const struct bt_le_adv_param *param)`` + +:: + + /** + * function Initiate a directed broadcast packet to the remote device + * @param[in] peer: Remote device address pointer + * @param[in] param: Pointer to broadcast parameters + * @return Success: a valid connection object, otherwise it fails + */ + +``int bt_conn_set_security(struct bt_conn *conn, bt_security_t sec)`` + +:: + + /** + * function Set the connection security level + * @param[in] conn: Pointer to the connection object + * @param[in] sec: Security level + * @return 0: success, !=0: fail + */ + +``bt_security_t bt_conn_get_security(struct bt_conn *conn)`` + +:: + + /** + * function Get the security level of the current connection + * @param[in] conn: Pointer to the connection object + * @return Security Level + */ + + +``u8_t bt_conn_enc_key_size(struct bt_conn *conn)`` + +:: + + /** + * function Get the size of the encryption key of the current connection + * @param[in] conn: Pointer to the connection object + * @return The size of the encryption key + */ + + +``void bt_conn_cb_register(struct bt_conn_cb *cb)`` + +:: + + /** + * function Register connection callback function + * @param[in] cb: Connection callback function + * @return None + */ + +``void bt_set_bondable(bool enable)`` + +:: + + /** + * function Set/clear the binding flag in the SMP pairing request/response to the data authentication request + * @param[in] enable: 1: enable, 0: disable + * @return None + */ + +``int bt_conn_auth_cb_register(const struct bt_conn_auth_cb *cb)`` + +:: + + /** + * function Register authentication callback function + * @param[in] cb: Callback function pointer + * @return 0: success, !=0: failure + */ + +``int bt_conn_auth_passkey_entry(struct bt_conn *conn, unsigned int passkey)`` + +:: + + /** + * function Reply with the key + * @param[in] conn: Connect object pointer + * @param[in] passkey: the key entered + * @return 0: success, !=0: failure + */ + +``int bt_conn_auth_cancel(struct bt_conn *conn)`` + +:: + + /** + * function Cancel the authentication process + * @param[in] conn: Connection object pointer + * @return 0: success, !=0: failure + */ + +``int bt_conn_auth_passkey_confirm(struct bt_conn *conn)`` + +:: + + /** + * function If the password matches, reply to the other side + * @param[in] conn: Pointer to connection object + * @return 0: success, !=0: failure + */ + +``int bt_conn_auth_pincode_entry(struct bt_conn *conn, const char *pin)`` + +:: + + /** + * function Reply with PIN code + * @param[in] conn: Pointer to connection object + * @param[in] pin: PIN code pointer + * @return 0: success, !=0: failure + */ + +``int bt_le_read_rssi(u16_t handle,int8_t *rssi)`` + +:: + + /** + * function Read the RSSI value of the opposite device + * @param[in] handle: The handle value of the connection + * @param[in] rssi: rssi pointer + * @return 0: success, !=0: failure + */ + +``int bt_get_local_address(bt_addr_le_t *adv_addr)`` + +:: + + /** + * function Read the address of the machine + * @param[in] adv_addr: Pointer to address + * @return 0: success, !=0: failure + */ + +``int bt_set_tx_pwr(int8_t power)`` + +:: + + /** + * function Set the transmit power of this device + * @param[in] power: power value + * @return 0: success, !=0: failure + */ + +Data structure reference +----------------------------- + +``bt_le_adv_param``\ data structure: + +.. code:: c + + /** LE Advertising Parameters. */ + struct bt_le_adv_param { + /** Local identity */ + u8_t id; + + /** Bit-field of advertising options */ + u8_t options; + + /** Minimum Advertising Interval (N * 0.625) */ + u16_t interval_min; + + /** Maximum Advertising Interval (N * 0.625) */ + u16_t interval_max; + + #if defined(CONFIG_BT_STACK_PTS) + u8_t addr_type; + #endif + }; + +This data structure is used to configure broadcast parameters, including local identification, broadcast option bit fields, broadcast gaps, etc. The broadcast option bit fields have the following enumerated type parameters to choose from: + +.. code:: c + + enum { + /** Convenience value when no options are specified. */ + BT_LE_ADV_OPT_NONE = 0, + + /** Advertise as connectable. Type of advertising is determined by + * providing SCAN_RSP data and/or enabling local privacy support. + */ + BT_LE_ADV_OPT_CONNECTABLE = BIT(0), + + /** Don't try to resume connectable advertising after a connection. + * This option is only meaningful when used together with + * BT_LE_ADV_OPT_CONNECTABLE. If set the advertising will be stopped + * when bt_le_adv_stop() is called or when an incoming (slave) + * connection happens. If this option is not set the stack will + * take care of keeping advertising enabled even as connections + * occur. + */ + BT_LE_ADV_OPT_ONE_TIME = BIT(1), + + /** Advertise using the identity address as the own address. + * @warning This will compromise the privacy of the device, so care + * must be taken when using this option. + */ + BT_LE_ADV_OPT_USE_IDENTITY = BIT(2), + + /** Advertise using GAP device name */ + BT_LE_ADV_OPT_USE_NAME = BIT(3), + + /** Use low duty directed advertising mode, otherwise high duty mode + * will be used. This option is only effective when used with + * bt_conn_create_slave_le(). + */ + BT_LE_ADV_OPT_DIR_MODE_LOW_DUTY = BIT(4), + + /** Enable use of Resolvable Private Address (RPA) as the target address + * in directed advertisements when CONFIG_BT_PRIVACY is not enabled. + * This is required if the remote device is privacy-enabled and + * supports address resolution of the target address in directed + * advertisement. + * It is the responsibility of the application to check that the remote + * device supports address resolution of directed advertisements by + * reading its Central Address Resolution characteristic. + */ + BT_LE_ADV_OPT_DIR_ADDR_RPA = BIT(5), + + /** Use whitelist to filter devices that can request scan response + * data. + */ + BT_LE_ADV_OPT_FILTER_SCAN_REQ = BIT(6), + + /** Use whitelist to filter devices that can connect. */ + BT_LE_ADV_OPT_FILTER_CONN = BIT(7), + }; + +If you need to send a broadcast packet, the configuration can be as follows: + +.. code:: c + + param.id = 0; + param.options = (BT_LE_ADV_OPT_CONNECTABLE | BT_LE_ADV_OPT_USE_NAME | BT_LE_ADV_OPT_ONE_TIME); + param.interval_min = 0x00a0; + param.interval_max = 0x00f0; + +``bt_data``\ data structure: + +.. code:: c + + struct bt_data { + u8_t type; + u8_t data_len; + const u8_t *data; + }; + +This data structure is used to fill the data in the broadcast packet, the specific data packet type can refer to the following: + +.. code:: c + + Service UUID + Local Name + Flags + Manufacturer Specific Data + TX Power Level + Secure Simple Pairing OOB + Security Manager OOB + Security Manager TK Value + Slave Connection Interval Range + Service Solicitation + Service Data + Appearance + Public Target Address + Random Target Address + Advertising Interval + LE Bluetooth Device Address + LE Role + Uniform Resource Identifier + LE Supported Features + Channel Map Update Indication + +Use this data structure to configure a broadcast packet data, as shown below: + +.. code:: c + + struct bt_data ad_discov[] = { + BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)), + BT_DATA(BT_DATA_NAME_COMPLETE, "BL602-BLE-DEV", 13), + }; + +``bt_le_scan_param``\ data structure: + +.. code:: c + + /** LE scan parameters */ + struct bt_le_scan_param { + /** Scan type (BT_LE_SCAN_TYPE_ACTIVE or BT_LE_SCAN_TYPE_PASSIVE) */ + u8_t type; + + /** Bit-field of scanning filter options. */ + u8_t filter_dup; + + /** Scan interval (N * 0.625 ms) */ + u16_t interval; + + /** Scan window (N * 0.625 ms) */ + u16_t window; + }; + +This data structure is used to fill scan parameters, +type: There are two types of scan types: BT_LE_SCAN_TYPE_ACTIVE (0x01) and BT_LE_SCAN_TYPE_PASSIVE (0x00) +filter_dup: 0x00, except for targeted advertisements, accept all broadcast and scan responses, 0x01, only receive broadcast and scan responses from devices in the whitelist +interval: Scan interval +window: Scan window + +If the scan request is enabled, it can be configured as follows: + +.. code:: c + + scan_param.type = BT_LE_SCAN_TYPE_PASSIVE + scan_param.filter_dup = 0x00 + interval=BT_GAP_SCAN_SLOW_INTERVAL_1 + window=BT_GAP_SCAN_SLOW_WINDOW_1 + + +``bt_le_conn_param``\ data structure: + +.. code:: c + + /** Connection parameters for LE connections */ + struct bt_le_conn_param { + u16_t interval_min; + u16_t interval_max; + u16_t latency; + u16_t timeout; + + #if defined(CONFIG_BT_STACK_PTS) + u8_t own_address_type; + #endif + }; + +This data structure is used to fill in the connection parameters, interval_min: the minimum value of the connection interval (0x0018), interval_max: the maximum value of the connection interval (0x0028), +latency: The maximum slave latency allowed for connection events +timeout: The time for the connection to time out + +Configure the data structure as follows: + +.. code:: c + + interval_min=BT_GAP_INIT_CONN_INT_MIN(0x0018) + interval_max=BT_GAP_INIT_CONN_INT_MAX(0x0028) + latency=0 + timeout=400 + +``bt_conn``\ data structure: + +.. code:: c + + struct bt_conn { + u16_t handle; + u8_t type; + u8_t role; + + ATOMIC_DEFINE(flags, BT_CONN_NUM_FLAGS); + + /* Which local identity address this connection uses */ + u8_t id; + + #if defined(CONFIG_BT_SMP) || defined(CONFIG_BT_BREDR) + bt_security_t sec_level; + bt_security_t required_sec_level; + u8_t encrypt; + #endif /* CONFIG_BT_SMP || CONFIG_BT_BREDR */ + + /* Connection error or reason for disconnect */ + u8_t err; + + bt_conn_state_t state; + + u16_t rx_len; + struct net_buf *rx; + + /* Sent but not acknowledged TX packets with a callback */ + sys_slist_t tx_pending; + /* Sent but not acknowledged TX packets without a callback before + * the next packet (if any) in tx_pending. + */ + u32_t pending_no_cb; + + /* Completed TX for which we need to call the callback */ + sys_slist_t tx_complete; + struct k_work tx_complete_work; + + + /* Queue for outgoing ACL data */ + struct k_fifo tx_queue; + + /* Active L2CAP channels */ + sys_slist_t channels; + + atomic_t ref; + + /* Delayed work for connection update and other deferred tasks */ + struct k_delayed_work update_work; + + union { + struct bt_conn_le le; + #if defined(CONFIG_BT_BREDR) + struct bt_conn_br br; + struct bt_conn_sco sco; + #endif + }; + + #if defined(CONFIG_BT_REMOTE_VERSION) + struct bt_conn_rv { + u8_t version; + u16_t manufacturer; + u16_t subversion; + } rv; + #endif + }; + +This data structure is the current connection data structure, which includes the parameters related to the BLE connection. After the connection is successful, the data structure can be called by the user. + diff --git a/docs/development_guide_en/source/api_reference/bluetooth/img/image1.png b/docs/development_guide_en/source/api_reference/bluetooth/img/image1.png new file mode 100644 index 00000000..f39cf53e Binary files /dev/null and b/docs/development_guide_en/source/api_reference/bluetooth/img/image1.png differ diff --git a/docs/development_guide_en/source/api_reference/bluetooth/img/image2.png b/docs/development_guide_en/source/api_reference/bluetooth/img/image2.png new file mode 100644 index 00000000..9cbc0447 Binary files /dev/null and b/docs/development_guide_en/source/api_reference/bluetooth/img/image2.png differ diff --git a/docs/development_guide_en/source/api_reference/img/image1.png b/docs/development_guide_en/source/api_reference/img/image1.png new file mode 100644 index 00000000..f39cf53e Binary files /dev/null and b/docs/development_guide_en/source/api_reference/img/image1.png differ diff --git a/docs/development_guide_en/source/api_reference/img/image2.png b/docs/development_guide_en/source/api_reference/img/image2.png new file mode 100644 index 00000000..9cbc0447 Binary files /dev/null and b/docs/development_guide_en/source/api_reference/img/image2.png differ diff --git a/docs/development_guide_en/source/api_reference/img/sw_arch.png b/docs/development_guide_en/source/api_reference/img/sw_arch.png new file mode 100644 index 00000000..fa2148e2 Binary files /dev/null and b/docs/development_guide_en/source/api_reference/img/sw_arch.png differ diff --git a/docs/development_guide_en/source/api_reference/peripheral/api_adc.rst b/docs/development_guide_en/source/api_reference/peripheral/api_adc.rst new file mode 100644 index 00000000..f5bb2b3e --- /dev/null +++ b/docs/development_guide_en/source/api_reference/peripheral/api_adc.rst @@ -0,0 +1,252 @@ +ADC +========================= + +Introduction +------------------------ +ADC (Analog-to-digital Converter) can convert continuous analog signals into discrete digital signals. + +The ADC module in BL MCU series has the following characteristics: + +- Support selecting 12/14/16 bits conversion result output +- ADC maximum working clock is 2MHZ +- Support 2.0V, 3.2V optional internal reference voltage +- DMA support +- Support four modes: single channel single conversion, continuous single channel conversion, single multi-channel conversion and continuous multi-channel conversion mode +- Support both single-ended and differential input modes +- 12 external analog channels +- 2 DAC internal channels +- 1 VBAT /2 channel + +ADC Device Structure Definition +--------------------------------- +.. code-block:: C + + typedef struct adc_device { + struct device parent; + adc_clk_div_t clk_div; + adc_vref_t vref; + bool continuous_conv_mode; + bool differential_mode; + adc_data_width_t data_width; + adc_fifo_threshold_t fifo_threshold; + adc_pga_gain_t gain; + } adc_device_t; + +- **parent** inherits the properties of the parent class +- **clk_div** Partial frequency clock in ADC module +- **vref** 2.0/3.2V reference voltage optional +- **continuous_conv_mode** Whether to select continuous mode. If it is in continuous mode, once adc_start operation, ADC will continue to work until adc_stop. If it is not in continuous mode, adc will only convert the result once every adc_start. +- **differential_mode** Whether it is in differential mode, if it is in differential mode, negative voltage can be measured. +- **data_width** Measurement width selection, the actual accuracy of ADC is 12 bits, but the accuracy of 14bits / 16bits can be achieved by averaging multiple times through OSR. Note that when a higher data width is selected, the frequency will decrease due to averaging. For details, please refer to the enumeration information. +- **fifo_threshold** This parameter affects the DMA handling threshold and ADC FIFO interrupt threshold +- **gain** ADC gain selection for input signal +- Others to be added + +ADC Device Parameter Configuration Table +------------------------------------------ + +Each ADC has a parameter configuration macro, the macro definition is located in the ``peripheral_config.h`` file under the ``bsp/board/xxx`` directory, and the variable definition is located in ``hal_adc.c``, so there is no need for the user to define it by himself . When the user opens the macro of the corresponding device, the configuration of the device will take effect. For example, open the macro ``BSP_USING_ADC0`` to take effect, and at the same time, the ``ADC`` device can be registered and used. + +.. code-block:: C + + /*Parameter configuration macro*/ + #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 + + /*Variable definitions*/ + static adc_device_t adcx_device[ADC_MAX_INDEX] = { + #ifdef BSP_USING_ADC0 + ADC0_CONFIG, + #endif + }; + +.. note:: The above configuration can be modified through ``ADC_DEV(dev)->xxx`` and can only be used before ``device_open``. + +ADC Device Interface +------------------------ + +ADC device interfaces all follow the interfaces provided by the standard device driver management layer. + +**adc_register** +^^^^^^^^^^^^^^^^^^^^^^^^ + +``adc_register`` is used to register an ADC device standard driver interface.Before registering, you need to open the macro definition of the corresponding ADC device. For example, define the macro ``BSP_USING_ADC0`` to use the ``ADC0`` device. After the registration is completed, other interfaces can be used. If no macro is defined, the ``ADC0`` device cannot be used. + +.. code-block:: C + + int adc_register(enum adc_index_type index, const char *name); + +- **index** device index to be registered +- **name** device name to be registered + +``index`` is used to select ADC device configuration, one index corresponds to one ADC device configuration, for example, ``ADC0_INDEX`` corresponds to ``ADC0_CONFIG`` configuration. ``index`` has the following optional types: + +.. code-block:: C + + enum adc_index_type + { + #ifdef BSP_USING_ADC0 + ADC0_INDEX, + #endif + ADC_MAX_INDEX + }; + +**device_open** +^^^^^^^^^^^^^^^^ + +``device_open`` is used to open an ADC device,this funtion calls ``adc_open`` actually. + +.. code-block:: C + + int device_open(struct device *dev, uint16_t oflag); + +- **dev** device handle +- **oflag** open mode +- **return** Error code, 0: open successfully, others: error + +``oflag`` provides the following types + +.. code-block:: C + + #define DEVICE_OFLAG_STREAM_TX 0x001 /* The device is turned on in rotation sending mode */ + #define DEVICE_OFLAG_STREAM_RX 0x002 /* The device is turned on in rotation receiving mode */ + #define DEVICE_OFLAG_INT_TX 0x004 /* The device is turned on in interrupt sending mode */ + #define DEVICE_OFLAG_INT_RX 0x008 /* The device is turned on in interrupt receiving mode */ + #define DEVICE_OFLAG_DMA_TX 0x010 /* The device is turned on in DMA transmission mode */ + #define DEVICE_OFLAG_DMA_RX 0x020 /* The device is turned on in DMA receiving mode */ + +**device_close** +^^^^^^^^^^^^^^^^ + +``device_close`` is used to close an ADC device,this funtion calls ``adc_close`` actually. + +.. code-block:: C + + int device_close(struct device *dev); + +- **dev** device handle +- **return** Error code, 0: open successfully, others: error + +**device_control** +^^^^^^^^^^^^^^^^^^^ + +``device_control`` is used to control and modify the parameters of the adc device according to commands.This funtion calls ``adc_control`` actually. + +.. code-block:: C + + int device_control(struct device *dev, int cmd, void *args); + +- **dev** Device handle +- **cmd** Device control commands +- **args** Control parameter +- **return** Different control commands return different meanings. + +In addition to standard control commands, serial devices also have their own special control commands. + +.. code-block:: C + + #define DEVICE_CTRL_ADC_CHANNEL_START 0x10 + #define DEVICE_CTRL_ADC_CHANNEL_STOP 0x11 + #define DEVICE_CTRL_ADC_CHANNEL_CONFIG 0x12 + #define DEVICE_CTRL_ADC_VBAT_ON 0x13 + #define DEVICE_CTRL_ADC_VBAT_OFF 0x14 + #define DEVICE_CTRL_ADC_TSEN_ON 0x15 + #define DEVICE_CTRL_ADC_TSEN_OFF 0x16 + +``args`` input is different depending on ``cmd``, the list is as follows: + +.. list-table:: table1 + :widths: 15 10 30 + :header-rows: 1 + + * - cmd + - args + - description + * - DEVICE_CTRL_SET_INT + - adc_it_type + - Enable ADC device interrupt + * - DEVICE_CTRL_CLR_INT + - adc_it_type + - Disable ADC device interrupt + * - DEVICE_CTRL_CONFIG + - ADC_param_cfg_t + - Modify ADC configuration + * - DEVICE_CTRL_ADC_CHANNEL_CONFIG + - adc_channel_cfg_t + - Modify ADC channel configuration + * - DEVICE_CTRL_ATTACH_RX_DMA + - struct device* + - Link receiving DMA device + * - DEVICE_CTRL_ADC_CHANNEL_START + - NULL + - Start/continue ADC conversion + * - DEVICE_CTRL_ADC_CHANNEL_STOP + - NULL + - Stop ADC conversion + * - DEVICE_CTRL_ADC_VBAT_ON + - NULL + - Turn on the internal VDD measurement circuit + * - DEVICE_CTRL_ADC_VBAT_OFF + - NULL + - Turn off the internal VDD measurement circuit + * - DEVICE_CTRL_ADC_TSEN_ON + - NULL + - Turn on the internal temperature measurement circuit (requires hardware support) + * - DEVICE_CTRL_ADC_TSEN_OFF + - NULL + - Turn off the internal temperature measurement circuit (requires hardware support) + +**device_read** +^^^^^^^^^^^^^^^^ + +``device_read`` is used to receive the data of ADC device, the receiving mode can be polling, interrupt, dma. + +.. code-block:: C + + int device_read(struct device *dev, uint32_t pos, void *buffer, uint32_t size); + +- **dev** Dvice handle +- **pos** No effect +- **buffer** Buffer to read +- **size** Length to read +- **return** Error code, 0: open successfully, others: error + +**device_set_callback** +^^^^^^^^^^^^^^^^^^^^^^^^ + +``device_set_callback`` is used to register an ADC threshold interrupt callback function. + +.. code-block:: C + + int device_set_callback(struct device *dev, void (*callback)(struct device *dev, void *args, uint32_t size, uint32_t event)); + +- **dev** Device handle +- **callback** The interrupt callback function to be registered + + - **dev** Device handle + - **args** Receive and send buffer, the data type is uint8_t* + - **size** Transmission length + - **event** Type of interrupt event + +``event`` type is as follows: + +.. code-block:: C + + enum ADC_event_type + { + ADC_EVENT_FIFO_READY, + ADC_EVENT_OVERRUN, + ADC_EVENT_UNDERRUN, + }; \ No newline at end of file diff --git a/docs/development_guide_en/source/api_reference/peripheral/api_clock.rst b/docs/development_guide_en/source/api_reference/peripheral/api_clock.rst new file mode 100644 index 00000000..ea6251a1 --- /dev/null +++ b/docs/development_guide_en/source/api_reference/peripheral/api_clock.rst @@ -0,0 +1,63 @@ +Clock tree +========================= + +Introduction +------------------------ + +The BL series chips have a lot of clock source selection and provide a clock tree configuration table to facilitate user configuration. Users do not need to call the clock setting interface. Users only need to care about the final system clock and peripheral clock frequency. The clock configuration table is located in the ``clock_config.h`` file under the ``bsp/board/xxx_board`` directory. + +Clock Frequency Acquisition Interface +--------------------------------------- + +**system_clock_get** +^^^^^^^^^^^^^^^^^^^^^^^^ + +``system_clock_get`` is used to get the system clock frequency. + +.. code-block:: C + + uint32_t system_clock_get(enum system_clock_type type); + +- **type** the type of system clock frequency + +``type`` provide the following types + +.. code-block:: C + + enum system_clock_type + { + SYSTEM_CLOCK_ROOT_CLOCK = 0, + SYSTEM_CLOCK_FCLK, + SYSTEM_CLOCK_BCLK, + SYSTEM_CLOCK_XCLK, + SYSTEM_CLOCK_32K_CLK, + SYSTEM_CLOCK_AUPLL, + }; + + +**peripheral_clock_get** +^^^^^^^^^^^^^^^^^^^^^^^^ + +``peripheral_clock_get`` is used to get the peripheral clock frequency. + +.. code-block:: C + + uint32_t peripheral_clock_get(enum peripheral_clock_type type); + +- **type** peripheral clock frequency type + +``type`` provide the following types + +.. 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, + PERIPHERAL_CLOCK_PWM, + PERIPHERAL_CLOCK_CAM, + }; \ No newline at end of file diff --git a/docs/development_guide_en/source/api_reference/peripheral/api_dac.rst b/docs/development_guide_en/source/api_reference/peripheral/api_dac.rst new file mode 100644 index 00000000..a72cff97 --- /dev/null +++ b/docs/development_guide_en/source/api_reference/peripheral/api_dac.rst @@ -0,0 +1,15 @@ +DAC +========================= + +Introduction +------------------------ + + +DAC Structure Definition +--------------------------- + +DAC Parameter Configuration Table +------------------------------------ + +DAC Device Interface +------------------------ diff --git a/docs/development_guide_en/source/api_reference/peripheral/api_dma.rst b/docs/development_guide_en/source/api_reference/peripheral/api_dma.rst new file mode 100644 index 00000000..b2ce9840 --- /dev/null +++ b/docs/development_guide_en/source/api_reference/peripheral/api_dma.rst @@ -0,0 +1,434 @@ +DMA +========================= + +Introduction +------------------------ + +DMA is a memory access technology that can directly read and write system memory independently without processor intervention. Under the same degree of processor burden, DMA is a fast data transfer method. The DMA device in BL series MCU has the following characteristics: + +- 8 independent dedicated channels +- Four transmission directions: memory to memory, memory to peripheral, peripheral to memory, peripheral to peripheral +- LLI linked list + +DMA Device Structure Definition +---------------------------------- + +.. 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** inherits the properties of the parent class +- **id** DMA id number, default 0, currently there is only one DMA +- **ch** channel number +- **direction** transmission direction +- **transfer_mode** transfer mode +- **src_req** source request +- **dst_req** destination request +- **src_burst_size** source burst bytes +- **dst_burst_size** destination number of burst bytes +- **src_width** source transmission bit width +- **dst_width** destination transmission bit width +- **lli_cfg** used to store some information of the dma channel, the user does not need to worry about it + +``direction`` provides the following types + +.. 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`` provides the following types + +.. code-block:: C + + #define DMA_LLI_ONCE_MODE 0 + #define DMA_LLI_CYCLE_MODE 1 + +``src_req`` provides the following types + +.. 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`` provides the following types + +.. 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`` provides the following types + +.. 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`` provides the following types + +.. 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`` provides the following types + +.. code-block:: C + + #define DMA_TRANSFER_WIDTH_8BIT 0 + #define DMA_TRANSFER_WIDTH_16BIT 1 + #define DMA_TRANSFER_WIDTH_32BIT 2 + +``dst_width``: provide the following types + +.. code-block:: C + + #define DMA_TRANSFER_WIDTH_8BIT 0 + #define DMA_TRANSFER_WIDTH_16BIT 1 + #define DMA_TRANSFER_WIDTH_32BIT 2 + +DMA Device Parameter Configuration Table +------------------------------------------------ + +Each DMA device has a parameter configuration macro, the macro definition is located in the ``peripheral_config.h`` file under the ``bsp/board/xxx`` directory, and the variable definition is located in ``hal_dma.c``, so there is no need for the user himself Define variables. When the user opens the macro of the corresponding device, the configuration of the device will take effect. For example, open the macro ``BSP_USING_DMA0_CH0``, ``DMA0_CH0_CONFIG`` will take effect, and the DMA channel 0 device can be registered and used. + +.. code-block:: C + + /*Parameter configuration macro*/ + #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 + + + /*Variable definitions*/ + 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:: + The above configuration can be modified through ``DMA_DEV(dev)->xxx`` and can only be used before calling ``device_open``. + +DMA Device Interface +------------------------ + +The DMA device interface follows which provided by the standard device driver management layer. In order to facilitate the user to call, some standard interfaces are redefined using macros. + +**dma_register** +^^^^^^^^^^^^^^^^^^^^^^^^ + +``dma_register`` is used to register a DMA device standard driver interface. Before registering, you need to open the channel macro definition of the corresponding DMA device. For example, after defining the macro ``BSP_USING_DMA_CH0``, the 0 channel of the ``DMA`` device can be used. After the registration is completed, other interfaces can be used. If the macro is not defined, the 0 channel of the ``DMA`` device cannot be used. + +.. code-block:: C + + int dma_register(enum dma_index_type index, const char *name); + +- **index** device index to be registered +- **name** device name to be registered + +``index`` is used to select the configuration of a certain channel of DMA, an index corresponds to a channel configuration of a DMA, for example, ``DMA_CH0_INDEX`` corresponds to the configuration of DMA channel 0, and ``index`` has the following optional types + +.. 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`` is used to open a channel of a dma device,this funtion calls ``dma_open`` actually. + +.. code-block:: C + + int device_open(struct device *dev, uint16_t oflag); + +- **dev** device handle +- **oflag** open mode +- **return** Error code, 0 means opening is successful, other means error + +``oflag`` provides the following types + +.. code-block:: C + + #define DEVICE_OFLAG_STREAM_TX 0x001 /* The device is turned on in polling sending mode */ + #define DEVICE_OFLAG_STREAM_RX 0x002 /* The device is turned on in polling receiving mode */ + #define DEVICE_OFLAG_INT_TX 0x004 /* The device is turned on in interrupt sending mode */ + #define DEVICE_OFLAG_INT_RX 0x008 /* The device is turned on in interrupt receiving mode */ + #define DEVICE_OFLAG_DMA_TX 0x010 /* The device is turned on in DMA transmission mode */ + #define DEVICE_OFLAG_DMA_RX 0x020 /* The device is turned on in DMA receiving mode */ + +**device_close** +^^^^^^^^^^^^^^^^ + +``device_close`` is used to close a channel of a dma device,this funtion calls ``dma_close`` actually. + +.. code-block:: C + + int device_close(struct device *dev); + +- **dev** device handle +- **return** error code, 0 means closing is successful, others mean error + +**device_control** +^^^^^^^^^^^^^^^^^^^ + +``device_control`` is used to control and modify the parameters of the dma device according to commands.This funtion calls ``dma_control`` actually. + +.. code-block:: C + + int device_control(struct device *dev, int cmd, void *args); + +- **dev** device handle +- **cmd** device control command +- **args** control parameters +- **return** different control commands return different meanings + +In addition to standard control commands, DMA devices also have their own special control commands. + +.. 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`` input is different depending on ``cmd``, the list is as follows: + +.. list-table:: table1 + :widths: 15 10 30 + :header-rows: 1 + + * - cmd + - args + - description + * - DEVICE_CTRL_SET_INT + - NULL + - Enable DMA transfer completion interrupt + * - DEVICE_CTRL_CLR_INT + - NULL + - Disable DMA transfer completion interrupt + * - DMA_CHANNEL_GET_STATUS + - NULL + - Get DMA channel completion status + * - DMA_CHANNEL_START + - NULL + - Open dma channel + * - DMA_CHANNEL_STOP + - NULL + - Close dma channel + * - DMA_CHANNEL_UPDATE + - NULL + - Update dma transmission configuration + +**device_set_callback** +^^^^^^^^^^^^^^^^^^^^^^^^ + +``device_set_callback`` is used to register a DMA channel interrupt callback function. + +.. code-block:: C + + int device_set_callback(struct device *dev, void (*callback)(struct device *dev, void *args, uint32_t size, uint32_t event)); + +- **dev** Device handle +- **callback** The interrupt callback function to be registered + + - **dev** device handle + - **args** unused + - **size** unused + - **event** interrupt event type + +``event`` type definition is as follows: + +.. code-block:: C + + enum dma_event_type + { + DMA_EVENT_COMPLETE, + }; + + +**dma_channel_start** +^^^^^^^^^^^^^^^^^^^^^^ + +``dma_channel_start`` is used to open the DMA channel. It actually calls ``device_control``, where ``cmd`` is ``DMA_CHANNEL_START``. + +.. code-block:: C + + dma_channel_start(dev) + +- **dev** dma channel handle that needs to be opened + + +**dma_channel_stop** +^^^^^^^^^^^^^^^^^^^^^^ + +``dma_channel_stop`` is used to close the DMA channel. It actually calls ``device_control``, where ``cmd`` is ``DMA_CHANNEL_STOP``. + +.. code-block:: C + + dma_channel_stop(dev) + +- **dev** dma channel handle that needs to be closed + + +**dma_channel_update** +^^^^^^^^^^^^^^^^^^^^^^^ + +``dma_channel_update`` is used to update the DMA configuration. The actual call is ``device_control``, where ``cmd`` is ``DMA_CHANNEL_UPDATE``. + +.. code-block:: C + + dma_channel_update(dev,list) + +- **dev** dma channel handle that needs to be updated +- **list** dma_lli_ctrl_t handle + + +**dma_channel_check_busy** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``dma_channel_check_busy`` is used to query whether the currently used DMA channel has completed the transfer. It actually calls ``device_control``, where ``cmd`` is ``DMA_CHANNEL_GET_STATUS``. + +.. code-block:: C + + dma_channel_check_busy(dev) + +- **dev** DMA channel handle to be queried +- **return** return the current DMA status, 0 means the transfer is complete, 1 means the transfer is not complete + +**dma_reload** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``dma_reload`` is used to update the configuration of a certain channel of DMA. Compared with ``dma_channel_update``, this function does not require the user to pass many parameters, but only needs to fill in the source address, destination address, and length. After this function is called, the DMA channel is not turned on. You need to manually call the ``dma_channel_start`` function. + +.. code-block:: C + + int dma_reload(struct device *dev, uint32_t src_addr, uint32_t dst_addr, uint32_t transfer_size); + +- **dev** DMA channel handle to be queried +- **src_addr** transmission source address +- **dst_addr** transmission destination address +- **transfer_size** the total length of transferred bytes. If the number of bits transferred is 16 bits or 32 bits, it needs to be converted into byte length here. + diff --git a/docs/development_guide_en/source/api_reference/peripheral/api_gpio.rst b/docs/development_guide_en/source/api_reference/peripheral/api_gpio.rst new file mode 100644 index 00000000..9d528791 --- /dev/null +++ b/docs/development_guide_en/source/api_reference/peripheral/api_gpio.rst @@ -0,0 +1,114 @@ +GPIO +========================= + +Introduction +------------------------ + +The full name of GPIO is General Purpose Input Output. The GPIO peripherals of BL series chips mainly have the following functions. + +- General input and output pull-up and pull-down +- Multiplex function pull-up and pull-down +- Simulation function +- External interrupt (rising edge, falling edge, high level, low level) +- Hardware eliminate jitter +- Drive capacity control + +The pin configuration of bl mcu sdk is divided into two kinds. + +- GPIO multiplexing function is through a special **pinmux table**, users only need to modify the functions of related pins in the table, and the program will automatically configure these pins. **pinmux table** is located in the ``pinmux_config.h`` file under the ``bsp/board/xxx_board`` directory. +- Configure the pins through the standard GPIO device interface. The disadvantage is that only common input and output and interrupt functions can be configured. It is recommended to use the table to configure the multiplexing functions. + +GPIO Device Interface +------------------------ + +**gpio_set_mode** +^^^^^^^^^^^^^^^^^^^^^^^^ + +``gpio_set_mode`` is used to configure the mode of gpio. + +.. code-block:: C + + void gpio_set_mode(uint32_t pin, uint32_t mode); + +- **pin** the pin to be configured +- **mode** pin function to be configured + +``mode`` provides the following types + +.. 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`` is used to set pin level + +.. code-block:: C + + void gpio_write(uint32_t pin, uint32_t value); + + +- **pin** the pin to be set +- **value** the level to be set + +**gpio_toggle** +^^^^^^^^^^^^^^^^^^^^^^^^ + +``gpio_toggle``: is used to toggle pin level + +.. code-block:: C + + void gpio_toggle(uint32_t pin); + +- pin: the pin to be toggled + +**gpio_read** +^^^^^^^^^^^^^^^^^^^^^^^^ + +``gpio_read`` is used to read pin level + +.. code-block:: C + + int gpio_read(uint32_t pin); + + +- **pin** the pin to read the level +- **return** 0 is low level, 1 is high level + +**gpio_attach_irq** +^^^^^^^^^^^^^^^^^^^^^^^^ + +``gpio_attach_irq`` is used to attache an interrupt callback function to the interrupt pin + +.. code-block:: C + + void gpio_attach_irq(uint32_t pin, void (*cbfun)(uint32_t pin)); + +- **pin** the pin to which the interrupt callback is attached +- **cbfun** register interrupt callback + +**gpio_irq_enable** +^^^^^^^^^^^^^^^^^^^^^^^^ + +``gpio_irq_enable`` is used to enable gpio interrupt + +.. code-block:: C + + void gpio_irq_enable(uint32_t pin,uint8_t enabled); + +- **pin** the pin to turn on or off the interrupt +- **enabled** 0 is to close the interrupt, 1 is to open the interrupt diff --git a/docs/development_guide_en/source/api_reference/peripheral/api_i2c.rst b/docs/development_guide_en/source/api_reference/peripheral/api_i2c.rst new file mode 100644 index 00000000..5c3d8c8f --- /dev/null +++ b/docs/development_guide_en/source/api_reference/peripheral/api_i2c.rst @@ -0,0 +1,160 @@ +I2C +========================= + +Introduction +------------------------ + +I2C (Inter-Intergrated Circuit) is a serial communication bus that uses a multi-master-slave architecture to connect low-speed peripheral devices. Each device has a unique address identification, and can be used as a transmitter or receiver. Each device connected to the bus can set the address with software through a unique address and the always-existing relationship between master and slave, and the host can be used as a host transmitter or host receiver. If two or more hosts are initialized at the same time, data transmission can prevent data from being destroyed through conflict detection and arbitration. The I2C devices in the BL series MCU have the following characteristics: + +- Flexible configuration of slave address ``slaveAddr``, register address ``subAddr`` +- Clock frequency that can be flexibly adjusted +- Support polling, interrupt, DMA transfer + + +I2C Device Structure Definition +---------------------------------- + +.. code-block:: C + + typedef struct i2c_device + { + struct device parent; + uint8_t id; + uint8_t mode; + uint32_t phase; + } i2c_device_t; + +- **parent** inherit the properties of the parent class +- **ch** i2c id, 0 means i2c0, 1 means i2c1 +- **mode** i2c transmission mode, 0 means using hardware i2c, 1 means using software i2c, current software i2c is temporarily invalid +- **phase** i2c clock phase div, i2c_clk = i2c_source_clk/(4*(phase+1)) +- TODO + +I2C Device Parameter Configuration Table +-------------------------------------------- + +Each I2C device has a parameter configuration macro, the macro definition is located in the ``peripheral_config.h`` file under the ``bsp/board/xxx`` directory, and the variable definition is located in ``hal_i2c.c``, so the user does not need to define variable. When the user opens the macro of the corresponding device, the configuration of the device will take effect. For example, open the macro ``BSP_USING_I2C0``, ``I2C0_CONFIG`` will take effect, and the ``I2C`` device can be registered and used. + +.. code-block:: C + + /*Parameter configuration macro*/ + #if defined(BSP_USING_I2C0) + #ifndef I2C0_CONFIG + #define I2C0_CONFIG \ + { \ + .id = 0, \ + .mode = I2C_HW_MODE,\ + .phase = 15, \ + } + #endif + #endif + + /*Variable definition*/ + static i2c_device_t i2cx_device[I2C_MAX_INDEX] = + { + #ifdef BSP_USING_I2C0 + I2C0_CONFIG, + #endif + }; + +.. note:: + The above configuration can be modified through ``I2C_DEV(dev)->xxx`` and can only be used before calling ``device_open``. + +I2C Device Interface +------------------------ + +The I2C device standard interface currently only uses ``device_open``, and provides a standard data transceiver interface. + +**i2c_register** +^^^^^^^^^^^^^^^^^^^^^^^^ + +``i2c_register`` is used to register an I2C device standard driver interface. The macro definition of the corresponding I2C device needs to be opened before registration. For example, define the macro ``BSP_USING_I2C0`` to use the ``I2C0`` device. After the registration is completed, other interfaces can be used. If the macro is not defined, the ``I2C0`` device cannot be used. + +.. code-block:: C + + int i2c_register(enum i2c_index_type index, const char *name); + +- **index** device index to be registered +- **name** device name to be registered + +``index`` is used to select I2C device, one index corresponds to one I2C device configuration, for example, ``I2C0_INDEX`` corresponds to ``I2C0_CONFIG`` configuration, ``index`` has the following optional types + +.. code-block:: C + + enum i2c_index_type + { + #ifdef BSP_USING_I2C0 + I2C0_INDEX, + #endif + I2C_MAX_INDEX + }; + +**device_open** +^^^^^^^^^^^^^^^^ + +``device_open`` is used to open an i2c device, this funtion calls ``i2c_open`` actually. + +.. code-block:: C + + int device_open(struct device *dev, uint16_t oflag); + +- **dev** device handle +- **oflag** open mode +- **return** error code, 0 means opening is successful, others mean errors + +``oflag`` provides the following types + +.. code-block:: C + + #define DEVICE_OFLAG_STREAM_TX 0x001 /* The device is turned on in polling sending mode */ + #define DEVICE_OFLAG_STREAM_RX 0x002 /* The device is turned on in polling receiving mode */ + #define DEVICE_OFLAG_INT_TX 0x004 /* The device is turned on in interrupt sending mode */ + #define DEVICE_OFLAG_INT_RX 0x008 /* The device is turned on in interrupt receiving mode */ + #define DEVICE_OFLAG_DMA_TX 0x010 /* The device is turned on in DMA transmission mode */ + #define DEVICE_OFLAG_DMA_RX 0x020 /* The device is turned on in DMA receiving mode */ + +**i2c_transfer** +^^^^^^^^^^^^^^^^ + +``i2c_transfer`` is used to transfer i2c msg. The member ``flags`` in ``i2c_msg_t`` structure indicates whether the direction of the transfer is writing or reading, and the length of the specified register address is 0, 1, 2. + +.. code-block:: C + + int i2c_transfer(struct device *dev, i2c_msg_t msgs[], uint32_t num); + +- **dev** device handle +- **msgs** message to be transmitted +- **num** the number of messages +- **return** error code, 0 means opening is successful, others mean error + +``i2c_msg_t`` structure is defined as follows: + +.. 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 slave device 7-bit slave address +- **subaddr** i2c slave device register address +- **flags** read and write mode and register address length +- **len** transmission data length +- **buf** data buffer + +``flags`` definition is as follows: + +.. code-block:: C + + /*Read and write mode*/ + #define I2C_WR 0x0000 + #define I2C_RD 0x0001 + + /*Register address length*/ + #define SUB_ADDR_0BYTE 0x0010 + #define SUB_ADDR_1BYTE 0x0020 + #define SUB_ADDR_2BYTE 0x0040 \ No newline at end of file diff --git a/docs/development_guide_en/source/api_reference/peripheral/api_pwm.rst b/docs/development_guide_en/source/api_reference/peripheral/api_pwm.rst new file mode 100644 index 00000000..13516655 --- /dev/null +++ b/docs/development_guide_en/source/api_reference/peripheral/api_pwm.rst @@ -0,0 +1,283 @@ +PWM +========================= + +Introduction +------------------------ + +PWM is a technology that implements analog voltage control in a digital way. It modulates the width of a series of pulses, equivalent to the required waveform (including shape and amplitude), and digitally encodes the analog signal level. That is to say, by adjusting the change of the duty cycle to adjust the change of the signal, energy, etc. The duty cycle refers to the percentage of the entire signal period when the signal is at a high level. For example, the duty cycle of a square wave is 50%. The DMA device in BL series MCU has the following characteristics: + +- Support 5-channel PWM +- Three clock sources can be selected (bus clock , crystal oscillator clock , slow clock <32k>), with 16-bit clock divider +- Double threshold domain setting, increase pulse flexibility + +PWM Device Structure Definition +--------------------------------- + +.. code-block:: C + + typedef struct pwm_device { + struct device parent; + uint8_t ch; + uint8_t polarity_invert_mode; + uint16_t period; + uint16_t threshold_low; + uint16_t threshold_high; + uint16_t it_pulse_count; + + } pwm_device_t; + +- **parent** inherit the properties of the parent class +- **ch** channel number, ch is 0 if PWM channel 0 is enabled, ch is 1 if PWM channel 1 is enabled, and so on +- **polarity_invert_mode** polarity invert enable +- **period** PWM period value +- **threshold_low** PWM low threshold +- **threshold_high** PWM high threshold +- **it_pulse_count** The cycle count value that triggered the interrupt condition + +.. note:: + PWM actual frequency = pwm_clock_source/frequency_division/period, period is not the actual PWM period,it just has the same name. + +.. note:: PWM Duty cycle = (threshold_high-threshold_low)/period * 100% + +PWM Device Parameter Configuration Table +------------------------------------------ + +Each PWM device has a parameter configuration macro, the macro definition is located in the ``peripheral_config.h`` file under the ``bsp/board/xxx`` directory, and the variable definition is located in ``hal_pwm.c``, so the user does not need to define variable. When the user opens the macro of the corresponding device, the configuration of the device will take effect. For example, open the macro ``BSP_USING_PWM_CH2``, and ``PWM_CH2_CONFIG`` will take effect, and at the same time, channel 2 of the ``PWM`` device can be registered and used. + +.. code-block:: C + + /*Parameter configuration macro*/ + #if defined(BSP_USING_PWM_CH2) + #ifndef PWM_CH2_CONFIG + #define PWM_CH2_CONFIG \ + { \ + .ch = 2, \ + .polarity_invert_mode = DISABLE, \ + .period = 0, \ + .threshold_low = 0, \ + .threshold_high = 0, \ + .it_pulse_count = 0, \ + } + #endif + #endif + + + /*Variable definitions*/ + 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:: + The above configuration can be modified through ``PWM_DEV(dev)->xxx``, and can only be used before calling ``device_open``. + +PWM device interface +------------------------ + +The PWM device interfaces all follow the interfaces provided by the standard device driver management layer. And in order to facilitate the user to call, some standard interfaces are redefined using macros. + +**pwm_register** +^^^^^^^^^^^^^^^^^^^^^^^^ + +``pwm_register`` is used to register a channel of the PWM device standard driver interface. Before registering, you need to open the macro definition of a certain channel of the corresponding PWM device. For example, define ``BSP_USING_PWM_CH0`` before you can use the ``PWM`` channel 0 device. After the registration is completed, other interfaces can be used. If no macro is defined, the PWM device cannot be used. + +.. code-block:: C + + int pwm_register(enum pwm_index_type index, const char *name); + +- **index** the index of the device to be registered +- **name** name the registered device + +``index`` is used to select the configuration of a certain channel of the PWM device. An index corresponds to a channel configuration of a PWM device. For example, ``PWM_CH0_INDEX`` corresponds to the configuration of PWM channel 0, and ``index`` has the following optional types: + +.. 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`` is used to open a channel of a pwm device,this funtion calls ``pwm_open`` actually. + +.. code-block:: C + + int device_open(struct device *dev, uint16_t oflag); + +- **dev** device handle +- **oflag** open mode +- **return** error code, 0 means opening is successful, others mean errors + +``oflag`` provides the following types + +.. code-block:: C + + #define DEVICE_OFLAG_STREAM_TX 0x001 /* The device is turned on in polling sending mode */ + #define DEVICE_OFLAG_STREAM_RX 0x002 /* The device is turned on in polling receiving mode */ + #define DEVICE_OFLAG_INT_TX 0x004 /* The device is turned on in interrupt sending mode */ + #define DEVICE_OFLAG_INT_RX 0x008 /* The device is turned on in interrupt receiving mode */ + #define DEVICE_OFLAG_DMA_TX 0x010 /* The device is turned on in DMA transmission mode */ + #define DEVICE_OFLAG_DMA_RX 0x020 /* The device is turned on in DMA receiving mode */ + +**device_close** +^^^^^^^^^^^^^^^^ + +``device_close`` is used to close a channel of a pwm device.this funtion calls ``pwm_close`` actually. + +.. code-block:: C + + int device_close(struct device *dev); + +- **dev** device handle +- **return** error code, 0 means closing is successful, others mean error + +**device_control** +^^^^^^^^^^^^^^^^^^^ + +``device_control`` is used to control and modify the parameters of the PWM device according to commands.This funtion calls ``pwm_control`` actually. + +.. code-block:: C + + int device_control(struct device *dev, int cmd, void *args); + +- **dev** device handle +- **cmd** device control command +- **args** control parameters +- **return** different control commands return different meanings + +In addition to standard control commands, PWM devices also have their own special control commands. + +.. code-block:: C + + #define DEIVCE_CTRL_PWM_IT_PULSE_COUNT_CONFIG 0x10 + +``args`` input is different depending on ``cmd``, the list is as follows: + +.. list-table:: table1 + :widths: 15 10 30 + :header-rows: 1 + + * - cmd + - args + - description + * - DEVICE_CTRL_RESUME + - NULL + - Enable the current PWM channel + * - DEVICE_CTRL_SUSPEND + - NULL + - Disable the current PWM channel + * - DEVICE_CTRL_PWM_FREQUENCE_CONFIG + - uint32_t + - Configure the current PWM channel period + * - DEVICE_CTRL_PWM_DUTYCYCLE_CONFIG + - pwm_dutycycle_config_t + - Configure the current PWM channel duty cycle + * - DEVICE_CTRL_PWM_IT_PULSE_COUNT_CONFIG + - uint32_t + - Configure the trigger PWM interrupt period value + +**device_set_callback** +^^^^^^^^^^^^^^^^^^^^^^^^ + +``device_set_callback`` is used to register a PWM channel interrupt callback function. + +.. code-block:: C + + int device_set_callback(struct device *dev, void (*callback)(struct device *dev, void *args, uint32_t size, uint32_t event)); + +- **dev** device handle +- **callback** the interrupt callback function to be registered + + - **dev** device handle + - **args** unused + - **size** unused + - **event** interrupt event type + +``event`` type definition is as follows: + +.. code-block:: C + + enum pwm_event_type + { + PWM_EVENT_COMPLETE, + }; + +**pwm_channel_start** +^^^^^^^^^^^^^^^^^^^^^^ + +``pwm_channel_start`` is used to start the PWM channel. It actually calls ``device_control``, where ``cmd`` is ``DEVICE_CTRL_RESUME``. + +.. code-block:: C + + pwm_channel_start(dev) + +- **dev** pwm channel handle that needs to be opened + + +**pwm_channel_stop** +^^^^^^^^^^^^^^^^^^^^^^ + +``pwm_channel_stop`` is used to close the PWM channel. It actually calls ``device_control``, where ``cmd`` is ``DEVICE_CTRL_SUSPEND``. + +.. code-block:: C + + pwm_channel_stop(dev) + +- **dev** pwm channel handle that needs to be closed + + +**pwm_channel_update** +^^^^^^^^^^^^^^^^^^^^^^^ + +``pwm_channel_update`` is used to update the frequency and duty cycle of the PWM channel. The actual call is ``device_control``, where ``cmd`` is ``DEVICE_CTRL_CONFIG``. + +.. code-block:: C + + pwm_channel_update(dev,cfg) + +- **dev** pwm channel handle that needs to be updated +- **cfg** pwm_config_t handle + + +**pwm_it_pulse_count_update** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``pwm_it_pulse_count_update`` is used to update the count value of the PWM channel. The PWM interrupt needs to be enabled before it takes effect. When the PWM count reaches the set period count value, an interrupt will be generated. The actual call is ``device_control``, where ``cmd`` is ``DEIVCE_CTRL_PWM_IT_PULSE_COUNT_CONFIG``. + +.. code-block:: C + + pwm_it_pulse_count_update(dev,count) + +- **dev** pwm channel handle that needs to update the cycle count value +- **count** cycle count value + diff --git a/docs/development_guide_en/source/api_reference/peripheral/api_spi.rst b/docs/development_guide_en/source/api_reference/peripheral/api_spi.rst new file mode 100644 index 00000000..ac1255b1 --- /dev/null +++ b/docs/development_guide_en/source/api_reference/peripheral/api_spi.rst @@ -0,0 +1,363 @@ +SPI +========================= + +Introduction +------------------------ + +Serial Peripheral Interface Bus (SPI) is a synchronous serial communication interface specification for short-range communication. The full-duplex communication mode is used between devices, which is a master-slave mode of one master and one or more slaves, and requires at least 4 wires. In fact, 3 wires are also available (when transmitting in one direction), including SDI (data input), SDO (data output), SCLK (clock), CS (chip select). The SPI devices in the BL series MCU have the following characteristics: + +- It can be used as both SPI master and SPI slave. +- The transmit and receive channels each have a FIFO with a depth of 4 words +- Both master and slave devices support 4 clock formats (CPOL, CPHA) +- Both master and slave devices support 1/2/3/4 byte transmission mode +- Flexible clock configuration, up to 40M clock +- Configurable MSB/LSB priority transmission +- Receive filter function +- Timeout mechanism under slave device +- Support polling, interrupt, DMA transfer + +SPI Device Structure Definition +---------------------------------- + +.. 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** inherit the properties of the parent class +- **id** SPI id, 0 means SPI0 +- **clk** SPI clock frequency +- **mode** master mode or slave mode +- **direction** transmission first mode +- **clk_polaraity** clock polarity +- **clk_phase** clock phase +- **datasize** data transmission bit width +- **fifo_threshold** fifo threshold, the maximum is 4 +- **tx_dma** additional send dma handle +- **rx_dma** dditional receive dma handle + +``mode`` provides the following types + +.. code-block:: C + + #define SPI_SLVAE_MODE 0 + #define SPI_MASTER_MODE 1 + +``direction`` provides the following types + +.. 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`` provides the following types + +.. code-block:: C + + #define SPI_POLARITY_LOW 0 + #define SPI_POLARITY_HIGH 1 + +``clk_phase`` provides the following types + +.. code-block:: C + + #define SPI_PHASE_1EDGE 0 + #define SPI_PHASE_2EDGE 1 + + +``datasize`` provides the following types + +.. code-block:: C + + #define SPI_DATASIZE_8BIT 0 + #define SPI_DATASIZE_16BIT 1 + #define SPI_DATASIZE_24BIT 2 + #define SPI_DATASIZE_32BIT 3 + +SPI Device Parameter Configuration Table +------------------------------------------ + +Each SPI device has a parameter configuration macro, the macro definition is located in the ``peripheral_config.h`` file under the ``bsp/board/xxx`` directory, and the variable definition is located in ``hal_spi.c``, so the user does not need to define variable. When the user opens the macro of the corresponding device, the configuration of the device will take effect. For example, open the macro ``BSP_USING_SPI0``, ``SPI0_CONFIG`` will take effect, and the ``SPI0`` device can be registered and used. + +.. code-block:: C + + /*Parameter configuration macro*/ + #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 + + /*Variable definition*/ + static spi_device_t spix_device[SPI_MAX_INDEX] = + { + #ifdef BSP_USING_SPI0 + SPI0_CONFIG, + #endif + }; + +.. note:: + The above configuration can be modified through ``SPI_DEV(dev)->xxx`` and can only be used before calling ``device_open``. + + +SPI Device Interface +------------------------ + +SPI device interface follows which provided by the standard device driver management layer. + +**spi_register** +^^^^^^^^^^^^^^^^^^^^^^^^ + +``spi_register`` is used to register an SPI device standard driver interface. Before registering, you need to open the macro definition of the corresponding SPI device. For example, define the macro ``BSP_USING_SPI0`` before you can use the SPI0 device. After the registration is completed, other interfaces can be used. If no macro is defined, the SPI device cannot be used. + +.. code-block:: C + + int spi_register(enum spi_index_type index, const char *name); + +- **index** device index to be registered +- **name** device name to be registered + +``index`` is used to select SPI device configuration, one index corresponds to one SPI device configuration, for example, ``SPI0_INDEX`` corresponds to ``SPI0_CONFIG`` configuration, and ``index`` has the following optional types + +.. code-block:: C + + enum spi_index_type + { + #ifdef BSP_USING_SPI0 + SPI0_INDEX, + #endif + SPI_MAX_INDEX + }; + +**device_open** +^^^^^^^^^^^^^^^^ + +``device_open`` is used to open the device,this funtion calls ``spi_open`` actually. + +.. code-block:: C + + int device_open(struct device *dev, uint16_t oflag); + +- **dev** device handle +- **oflag** open mode +- **return** error code, 0 means opening is successful, others mean errors + +``oflag`` provides the following types + +.. code-block:: C + + #define DEVICE_OFLAG_STREAM_TX 0x001 /* The device is turned on in polling sending mode */ + #define DEVICE_OFLAG_STREAM_RX 0x002 /* The device is turned on in polling receiving mode */ + #define DEVICE_OFLAG_INT_TX 0x004 /* The device is turned on in interrupt sending mode */ + #define DEVICE_OFLAG_INT_RX 0x008 /* The device is turned on in interrupt receiving mode */ + #define DEVICE_OFLAG_DMA_TX 0x010 /* The device is turned on in DMA transmission mode */ + #define DEVICE_OFLAG_DMA_RX 0x020 /* The device is turned on in DMA receiving mode */ + +**device_close** +^^^^^^^^^^^^^^^^ + +``device_close`` is used to close the device,this funtion calls ``spi_close`` actually. + +.. code-block:: C + + int device_close(struct device *dev); + +- **dev** device handle +- **return** error code, 0 means closing is successful, others means error + +**device_control** +^^^^^^^^^^^^^^^^^^^ + +``device_control`` is used to control the device and modify parameters according to commands.This funtion calls ``spi_control`` actually. + +.. code-block:: C + + int device_control(struct device *dev, int cmd, void *args); + +- **dev** device handle +- **cmd** device control command +- **args** control parameters +- **return** Different control commands return different meanings. + +In addition to standard control commands, SPI devices also have their own special control commands. + +.. code-block:: C + + #define DEVICE_CTRL_SPI_CONFIG_CLOCK 0x10 + +``args`` input is different depending on ``cmd``, the list is as follows: + +.. list-table:: table1 + :widths: 15 10 30 + :header-rows: 1 + + * - cmd + - args + - description + * - DEVICE_CTRL_SET_INT + - NULL + - Enable spi device interrupt + * - DEVICE_CTRL_CLR_INT + - NULL + - Disable spi device interrupt + * - DEVICE_CTRL_RESUME + - NULL + - Resume spi device + * - DEVICE_CTRL_SUSPEND + - NULL + - Suspend spi device + * - DEVICE_CTRL_ATTACH_TX_DMA + - NULL + - Link to tx dma device + * - DEVICE_CTRL_ATTACH_RX_DMA + - NULL + - Link to rx dma device + * - DEVICE_CTRL_SPI_CONFIG_CLOCK + - NULL + - Modify SPI device clock + * - DEVICE_CTRL_TX_DMA_SUSPEND + - NULL + - Suspend spi tx dma mode + * - DEVICE_CTRL_RX_DMA_SUSPEND + - NULL + - Suspend spi rx dma mode + * - DEVICE_CTRL_TX_DMA_RESUME + - NULL + - Resume spi tx dma mode + * - DEVICE_CTRL_RX_DMA_RESUME + - NULL + - Resume spi rx dma mode + +**device_write** +^^^^^^^^^^^^^^^^ + +``device_write`` is used to send data. The sending mode can be polling, interrupt, dma according to the open mode.This funtion calls ``spi_write`` actually. + +.. code-block:: C + + int device_write(struct device *dev, uint32_t pos, const void *buffer, uint32_t size); + +- **dev** device handle +- **pos** useless +- **buffer** the buffer to be written +- **size** the length to be written +- **return** error code, 0 means writing is successful, others mean errors + +**device_read** +^^^^^^^^^^^^^^^^ + +``device_read`` is used to receive data, and the receiving mode can be polling, interrupt, dma according to the open mode.This funtion calls ``spi_read`` actually. + +.. code-block:: C + + int device_read(struct device *dev, uint32_t pos, void *buffer, uint32_t size); + +- **dev** device handle +- **pos** useless +- **buffer** the buffer to be read +- **size** the length to be read +- **return** error code, 0 means successful reading, others mean errors + +**device_set_callback** +^^^^^^^^^^^^^^^^^^^^^^^^ + +``device_set_callback`` is used to register an SPI device interrupt callback function. + +.. code-block:: C + + int device_set_callback(struct device *dev, void (*callback)(struct device *dev, void *args, uint32_t size, uint32_t event)); + +- **dev** device handle +- **callback** the interrupt callback function to be registered + + - **dev** device handle + - **args** receive and send buffer, the data type is uint8_t* + - **size** transmission length + - **event** interrupt event type + +``event`` type definition is as follows: + +.. code-block:: C + + enum spi_event_type + { + SPI_EVENT_TX_FIFO, + SPI_EVENT_RX_FIFO, + SPI_EVENT_UNKNOWN + }; + +**spi_transmit** +^^^^^^^^^^^^^^^^^^^^^^^^ + +``spi_transmit`` is used to send data from SPI devices. + +.. code-block:: C + + int spi_transmit(struct device *dev, void *buffer, uint32_t size, uint8_t type); + +- **dev** device handle +- **buffer** send data buffer +- **size** send length +- **type** send bit width type + +``type`` provides the following types + +.. 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`` is used to receive data from SPI devices. + +.. code-block:: C + + int spi_receive(struct device *dev, void *buffer, uint32_t size, uint8_t type); + +- **dev** device handle +- **buffer** receive data buffer +- **size** receiving length +- **type** bit width type + +**spi_transmit_receive** +^^^^^^^^^^^^^^^^^^^^^^^^ + +``spi_transmit_receive`` is used to send and receive data from SPI devices. + +.. code-block:: C + + int spi_transmit_receive(struct device *dev, const void *send_buf, void *recv_buf, uint32_t length, uint8_t type); + +- **dev** device handle +- **send_buf** send data buffer +- **recv_buf** receive data buffer +- **length** send and receive length +- **type** bit width type diff --git a/docs/development_guide_en/source/api_reference/peripheral/api_timer.rst b/docs/development_guide_en/source/api_reference/peripheral/api_timer.rst new file mode 100644 index 00000000..595f470b --- /dev/null +++ b/docs/development_guide_en/source/api_reference/peripheral/api_timer.rst @@ -0,0 +1,282 @@ +TIMER +========================= + +Introduction +------------------------ + +The TIMER device in BL series MCU has the following characteristics: + +- Multiple clock source options +- 8-bit clock divider, the division factor is 1-256 +- Two 32-bit timers +- Each timer can independently set three groups of alarm values +- Support FreeRun mode and PreLoad mode +- 16-bit watchdog +- Support write protection to prevent system abnormalities caused by incorrect settings +- Support two watchdog overflow modes, interrupt or reset + +TIMER Device Structure Definition +------------------------------------ + +.. code-block:: C + + typedef struct timer_device { + struct device parent; + uint8_t id; + enum timer_cnt_mode_type cnt_mode; + enum timer_preload_trigger_type trigger; + uint32_t reload; + uint32_t timeout1; + uint32_t timeout2; + uint32_t timeout3; + } timer_device_t; + +- **parent** inherit the properties of the parent class +- **id** timer id +- **cnt_mode** counting mode:FreeRun and preload +- **trigger** source of preload comparator +- **reload** reload value in preload mode +- **timeout1** compare source 0 timout value ,unit is us +- **timeout2** compare source 1 timout value ,unit is us +- **timeout3** compare source 2 timout value ,unit is us + +``ch`` provides the following types + +.. code-block:: C + + enum timer_index_type { + TIMER0_INDEX, + TIMER1_INDEX, + TIMER_MAX_INDEX + }; + +``cnt_mode`` provides the following types + +.. code-block:: C + + enum timer_cnt_mode_type { + TIMER_CNT_PRELOAD, + TIMER_CNT_FREERUN, + }; + +``pl_trig_src`` provides the following types + +.. code-block:: C + + enum timer_preload_trigger_type { + TIMER_PRELOAD_TRIGGER_NONE, + TIMER_PRELOAD_TRIGGER_COMP0, + TIMER_PRELOAD_TRIGGER_COMP1, + TIMER_PRELOAD_TRIGGER_COMP2, + }; + +TIMER Device Parameter Configuration Table +--------------------------------------------- + +Each TIMER has a parameter configuration macro, the macro definition is located in the ``peripheral_config.h`` file under the ``bsp/board/xxx`` directory, and the variable definition is located in ``hal_timer.c``, so the user does not need to define the variable . When the user opens the macro of the corresponding device, the configuration of the device will take effect. For example, open the macro ``BSP_USING_TIMER_CH0``, ``TIMER_CH0_CONFIG`` will take effect, and the ``TIMER_CH0_INDEX`` device can be registered and used. + +.. code-block:: C + + /*Parameter configuration macro*/ + #if defined(BSP_USING_TIMER0) + #ifndef TIMER0_CONFIG + #define TIMER0_CONFIG \ + { \ + .id = 0, \ + .cnt_mode = TIMER_CNT_PRELOAD, \ + .trigger = TIMER_PRELOAD_TRIGGER_COMP2, \ + .reload = 0, \ + .timeout1 = 1000000, \ + .timeout2 = 2000000, \ + .timeout3 = 3000000, \ + } + #endif + #endif + + #if defined(BSP_USING_TIMER1) + #ifndef TIMER1_CONFIG + #define TIMER1_CONFIG \ + { \ + .id = 1, \ + .cnt_mode = TIMER_CNT_PRELOAD, \ + .trigger = TIMER_PRELOAD_TRIGGER_COMP0, \ + .reload = 0, \ + .timeout1 = 1000000, \ + .timeout2 = 2000000, \ + .timeout3 = 3000000, \ + } + #endif + #endif + + /*Variable definitions*/ + static timer_device_t timerx_device[TIMER_MAX_INDEX] = { + #ifdef BSP_USING_TIMER0 + TIMER0_CONFIG, + #endif + #ifdef BSP_USING_TIMER1 + TIMER1_CONFIG, + #endif + }; + +.. note:: + The above configuration can be modified through ``TIMER_DEV(dev)->xxx`` and can only be used before calling ``device_open``. + +TIMER Device Interface +------------------------ + +TIMER device interface follows which provided by the standard device driver management layer. + +**timer_register** +^^^^^^^^^^^^^^^^^^^^^^^^ + +``timer_register`` is used to register a TIMER device standard driver interface. Before registering, you need to open the macro definition of the corresponding TIMER device. For example, define the macro ``BSP_USING_TIMER_CH0`` to use the ``TIMER_CH0_INDEX`` device. After the registration is completed, other interfaces can be used. If the macro is not defined, the ``TIMER_CH0_INDEX`` device cannot be used. + +.. code-block:: C + + int timer_register(enum timer_index_type index, const char *name); + +- **index** the index of the device to be registered +- **name** Name the device + +``index`` is used to select TIMER device configuration, one index corresponds to a TIMER device configuration, for example, ``TIMER_CH0_INDEX`` corresponds to ``TIMER_CH0_CONFIG`` configuration, and ``index`` has the following optional types + +.. code-block:: C + + enum timer_index_type { + #ifdef BSP_USING_TIMER0 + TIMER0_INDEX, + #endif + #ifdef BSP_USING_TIMER1 + TIMER1_INDEX, + #endif + TIMER_MAX_INDEX + }; + +**device_open** +^^^^^^^^^^^^^^^^ + +``device_open`` is used to open a TIMER device, this funtion calls ``timer_open`` actually. + +.. code-block:: C + + int device_open(struct device *dev, uint16_t oflag); + +- **dev** device handle +- **oflag** open method +- **return** error code, 0 means opening is successful, others mean error + +``oflag`` provides the following types + +.. code-block:: C + + #define DEVICE_OFLAG_STREAM_TX 0x001 /* The device is turned on in polling sending mode */ + #define DEVICE_OFLAG_STREAM_RX 0x002 /* The device is turned on in polling receiving mode */ + #define DEVICE_OFLAG_INT_TX 0x004 /* The device is turned on in interrupt sending mode */ + #define DEVICE_OFLAG_INT_RX 0x008 /* The device is turned on in interrupt receiving mode */ + #define DEVICE_OFLAG_DMA_TX 0x010 /* The device is turned on in DMA transmission mode */ + #define DEVICE_OFLAG_DMA_RX 0x020 /* The device is turned on in DMA receiving mode */ + +**device_close** +^^^^^^^^^^^^^^^^ + +``device_close`` is used to close a TIMER device,this funtion calls ``timer_open`` actually. + +.. code-block:: C + + int device_close(struct device *dev); + +- **dev** device handle +- **return** error code, 0 means closing is successful, others mean error + +**device_control** +^^^^^^^^^^^^^^^^^^^ + +``device_control`` is used to control and modify the parameters of the TIMER device according to commands.This funtion calls ``timer_control`` actually. + +.. code-block:: C + + int device_control(struct device *dev, int cmd, void *args); + +- **dev** device handle +- **cmd** device control command +- **args** control parameters +- **return** different control commands return different meanings + +In addition to standard control commands, TIMER device also has its own special control commands. + +.. code-block:: C + + #define DEVICE_CTRL_TIMER_CH_START 0x80 + #define DEVICE_CTRL_TIMER_CH_STOP 0x81 + #define DEVICE_CTRL_GET_MATCH_STATUS 0x82 + +``args`` input is different depending on ``cmd``, the list is as follows: + +.. list-table:: table1 + :widths: 15 10 30 + :header-rows: 1 + + * - cmd + - args + - description + * - DEVICE_CTRL_SET_INT + - timer_it_type + - Enable TIMER interrupt + * - DEVICE_CTRL_CLR_INT + - timer_it_type + - Disable TIMER interrupt + * - DEVICE_CTRL_GET_INT + - NULL + - Get TIMER interrupt status + * - DEVICE_CTRL_RESUME + - NULL + - Enable TIMER + * - DEVICE_CTRL_SUSPEND + - NULL + - Disable TIMER + * - DEVICE_CTRL_GET_CONFIG + - NULL + - Get TIMER current count + +**device_write** +^^^^^^^^^^^^^^^^ + +``device_write`` is used to config timer device timeout value.This funtion calls ``timer_write`` actually. + +.. code-block:: C + + int device_write(struct device *dev, uint32_t pos, const void *buffer, uint32_t size); + +- **dev** device handle +- **pos** unused +- **buffer** timer_timeout_cfg_t handle +- **size** the length of timer_timeout_cfg_t +- **return** error code, 0 means writing is successful, others mean errors + +**device_set_callback** +^^^^^^^^^^^^^^^^^^^^^^^^ + +``device_set_callback`` is used to register a timer compare interrupt callback function. + +.. code-block:: C + + int device_set_callback(struct device *dev, void (*callback)(struct device *dev, void *args, uint32_t size, uint32_t event)); + +- **dev** device handle +- **callback** the interrupt callback function to be registered + + - **dev** device handle + - **args** unused + - **size** unused + - **event** interrupt event type + +``event`` type definition is as follows: + +.. code-block:: C + + enum timer_event_type { + TIMER_EVENT_COMP0, + TIMER_EVENT_COMP1, + TIMER_EVENT_COMP2, + TIMER_EVENT_UNKNOWN + }; \ No newline at end of file diff --git a/docs/development_guide_en/source/api_reference/peripheral/api_uart.rst b/docs/development_guide_en/source/api_reference/peripheral/api_uart.rst new file mode 100644 index 00000000..020bd3b9 --- /dev/null +++ b/docs/development_guide_en/source/api_reference/peripheral/api_uart.rst @@ -0,0 +1,308 @@ +UART +========================= + +Introduction +------------------------ + +UART is a universal asynchronous transmitter-receiver, which provides a flexible way for full-duplex data exchange with external devices. The UART device in BL series MCU has the following characteristics: + +- Data bit length can choose 5/6/7/8 bits +- Stop bit length can be selected 0.5/1/1.5/2 bits +- Support odd/even/no parity bit +- Support hardware flow control (RTS/CTS) +- Automatic baud rate detection +- Support LIN protocol (transceive BREAK/SYNC) +- Send/receive FIFO +- Support polling, interrupt, DMA transfer +- Unique rto interrupt + +UART Device Structure Definition +---------------------------------- + +.. 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** inherit the properties of the parent class +- **id** serial port id, if serial port 0 is enabled, id is 0, if serial port 1 is enabled, id is 1, and so on +- **baudrate** baud rate +- **databits** data bits +- **stopbits** stop bits +- **parity** parity +- **fifo_threshold** fifo threshold, the maximum value of different mcu is different +- **tx_dma** additional send dma handle +- **rx_dma** additional receive dma handle + +``databits`` provides the following types + +.. 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`` provides the following types + +.. 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`` provides the following types + +.. 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 Device Parameter Configuration Table +------------------------------------------- + +Each UART device has a parameter configuration macro, the macro definition is located in the ``peripheral_config.h`` file under the ``bsp/board/xxx`` directory, and the variable definition is located in ``hal_uart.c``, so the user does not need to define variable. When the user opens the macro of the corresponding device, the configuration of the device will take effect. For example, open the macro ``BSP_USING_UART0``, ``UART0_CONFIG`` will take effect, and the ``UART0`` device can be registered and used. + +.. code-block:: C + + /*Parameter configuration macro*/ + #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 + + /*Variable definitions*/ + static uart_device_t uartx_device[UART_MAX_INDEX] = + { + #ifdef BSP_USING_UART0 + UART0_CONFIG, + #endif + #ifdef BSP_USING_UART1 + UART1_CONFIG, + #endif + }; + +.. note:: + The above configuration can be modified through ``UART_DEV(dev)->xxx`` and can only be used before calling ``device_open``. + +UART Device Interface +------------------------ + +UART device interface follows which provided by the standard device driver management layer. + +**uart_register** +^^^^^^^^^^^^^^^^^^^^^^^^ + +``uart_register`` is used to register a UART device standard driver interface. Before registering, you need to open the macro definition of the corresponding UART device. For example, define the macro ``BSP_USING_UART0`` to use the ``UART0`` device. After the registration is completed, other interfaces can be used. If the macro is not defined, the ``UART0`` device cannot be used. + +.. code-block:: C + + int uart_register(enum uart_index_type index, const char *name); + +- **index** the index of the device to be registered +- **name** device name + +``index`` is used to select UART device configuration, one index corresponds to a UART device configuration, such as ``UART0_INDEX`` corresponds to ``UART0_CONFIG`` configuration, ``index`` has the following optional types + +.. 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`` is used to open a UART device, this funtion calls ``uart_open`` actually. + +.. code-block:: C + + int device_open(struct device *dev, uint16_t oflag); + +- **dev** device handle +- **oflag** open mode +- **return** error code, 0 means opening is successful, others mean errors + +``oflag`` provides the following types + +.. code-block:: C + + #define DEVICE_OFLAG_STREAM_TX 0x001 /* The device is turned on in polling sending mode */ + #define DEVICE_OFLAG_STREAM_RX 0x002 /* The device is turned on in rotation receiving mode */ + #define DEVICE_OFLAG_INT_TX 0x004 /* The device is turned on in interrupt sending mode */ + #define DEVICE_OFLAG_INT_RX 0x008 /* The device is turned on in interrupt receiving mode */ + #define DEVICE_OFLAG_DMA_TX 0x010 /* The device is turned on in DMA transmission mode */ + #define DEVICE_OFLAG_DMA_RX 0x020 /* The device is turned on in DMA receiving mode */ + +**device_close** +^^^^^^^^^^^^^^^^ + +``device_close`` is used to close a UART device,this funtion calls ``uart_close`` actually. + +.. code-block:: C + + int device_close(struct device *dev); + +- **dev** device handle +- **return** error code, 0 means closing is successful, others mean error + +**device_control** +^^^^^^^^^^^^^^^^^^^ + +``device_control`` is used to control and modify the parameters of the UART device according to commands.This funtion calls ``uart_control`` actually. + +.. code-block:: C + + int device_control(struct device *dev, int cmd, void *args); + +- **dev** device handle +- **cmd** device control command +- **args** control parameters +- **return** different control commands return different meanings. + +In addition to standard control commands, UART device also has its own special control commands. + +.. code-block:: C + + #define DEVICE_CTRL_UART_GET_TX_FIFO 0x10 + #define DEVICE_CTRL_UART_GET_RX_FIFO 0x11 + +``args`` input is different depending on ``cmd``, the list is as follows: + +.. list-table:: table1 + :widths: 15 10 30 + :header-rows: 1 + + * - cmd + - args + - description + * - DEVICE_CTRL_SET_INT + - uart_it_type + - Enable uart device interrupt + * - DEVICE_CTRL_CLR_INT + - uart_it_type + - Disable uart device interrupt + * - DEVICE_CTRL_CONFIG + - uart_param_cfg_t* + - Modify the serial port configuration + * - DEVICE_CTRL_ATTACH_TX_DMA + - NULL + - Link to tx dma device + * - DEVICE_CTRL_ATTACH_RX_DMA + - NULL + - Link to rx dma device + * - DEVICE_CTRL_TX_DMA_SUSPEND + - NULL + - Suspend uart tx dma mode + * - DEVICE_CTRL_RX_DMA_SUSPEND + - NULL + - Suspend uart rx dma mode + * - DEVICE_CTRL_TX_DMA_RESUME + - NULL + - Resume uart tx dma mode + * - DEVICE_CTRL_RX_DMA_RESUME + - NULL + - Resume uart rx dma mode + * - DEVICE_CTRL_UART_GET_TX_FIFO + - uint32_t* + - Get the number of uart tx fifo + * - DEVICE_CTRL_UART_GET_RX_FIFO + - uint32_t* + - Get the number of uart rx fifo + +**device_write** +^^^^^^^^^^^^^^^^ + +``device_write`` is used to send data. The sending mode can be polling, interrupt, dma according to the open mode.This funtion calls ``uart_write`` actually. + +.. code-block:: C + + int device_write(struct device *dev, uint32_t pos, const void *buffer, uint32_t size); + +- **dev** device handle +- **pos** useless +- **buffer** the buffer to be written +- **size** the length to be written +- **return** error code, 0 means writing is successful, others mean errors + +**device_read** +^^^^^^^^^^^^^^^^ + +``device_read`` is used to receive data. The receiving mode can be polling, interrupt, dma according to the open mode.This funtion calls ``uart_read`` actually. + +.. code-block:: C + + int device_read(struct device *dev, uint32_t pos, void *buffer, uint32_t size); + +- **dev** device handle +- **pos** useless +- **buffer** the buffer to be read +- **size** the length to be read +- **return** error code, 0 means successful reading, others mean errors + +**device_set_callback** +^^^^^^^^^^^^^^^^^^^^^^^^ + +``device_set_callback`` is used to register a uart interrupt callback function. + +.. code-block:: C + + int device_set_callback(struct device *dev, void (*callback)(struct device *dev, void *args, uint32_t size, uint32_t event)); + +- **dev** device handle +- **callback** the interrupt callback function to be registered + + - **dev** device handle + - **args** receive and send buffer, the data type is uint8_t* + - **size** transmission length + - **event** interrupt event type + +``event`` type definition is as follows: + +.. 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 + }; \ No newline at end of file diff --git a/docs/development_guide_en/source/api_reference/peripheral/index.rst b/docs/development_guide_en/source/api_reference/peripheral/index.rst new file mode 100644 index 00000000..9df68676 --- /dev/null +++ b/docs/development_guide_en/source/api_reference/peripheral/index.rst @@ -0,0 +1,19 @@ +============== +Peripheral +============== + +.. toctree:: + :maxdepth: 1 + + Clock Tree + GPIO Device + UART Device + PWM Device + DMA Device + I2C Device + #I2S Device + SPI Device + ADC Device + DAC Device + TIMER Device + #USB Device \ No newline at end of file diff --git a/docs/development_guide_en/source/conf.py b/docs/development_guide_en/source/conf.py new file mode 100644 index 00000000..ced6d090 --- /dev/null +++ b/docs/development_guide_en/source/conf.py @@ -0,0 +1,76 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +# import os +# import sys +# sys.path.insert(0, os.path.abspath('.')) + + +# -- Project information ----------------------------------------------------- + +project = 'BL_MCU_SDK Development Guide' +copyright = '2021, BouffaloLab Co., Ltd' +author = 'BouffaloLab MCU Team' + +version = '0.3' + +# The full version, including alpha/beta/rc tags +release = '0.3' + + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx.ext.autodoc', + 'sphinx.ext.imgmath', +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +source_suffix = '.rst' + +master_doc = 'index' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = 'en' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = [] + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'sphinx_rtd_theme' + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +#html_static_path = ['_static'] + +man_pages = [ + (master_doc, 'bl702', 'BouffaloLab Documentation', + [author], 1) +] + diff --git a/docs/development_guide_en/source/get_started/Linux_quick_start_ubuntu.rst b/docs/development_guide_en/source/get_started/Linux_quick_start_ubuntu.rst new file mode 100644 index 00000000..32588655 --- /dev/null +++ b/docs/development_guide_en/source/get_started/Linux_quick_start_ubuntu.rst @@ -0,0 +1,133 @@ +Linux OR WSL environment development guide +============================================ + +This document introduces how to install and configure the software development tools needed for BL702 series MCUs in Linux. The installation and configuration method under WSL system is the same as under linux, please install WSL system by yourself. The difference is that one runs on a pure linux system and the other runs on windows. If you don't want to install a virtual machine or a linux system, you can choose WSL. + +**Windows Subsystem for Linux** (WSL) is a compatibility layer that can run native Linux binary executable files (ELF format) on Windows 10. It was developed by Microsoft and Canonical in cooperation. Its goal is to enable the pure Ubuntu image to be downloaded and decompressed to the user's local computer, and the tools in the image can run on this subsystem. Therefore, the operation mode under WSL is exactly the same as the operation mode under linux. + +Software and hardware environment +------------------------------------ + +- A mini USB data cable +- A USB-TTL serial port module +- Several Dupont lines + +Configure RISC-V toolchain +----------------------------- + +.. 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 -rf ~/riscv64-elf-20210120 /usr/bin + $ echo "export PATH=\"$PATH:/usr/bin/riscv64-elf-20210120/bin\"" >> ~/.bashrc + $ source ~/.bashrc + +Configure cmake & make tools +------------------------------- + +.. 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 -rf ~/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 + + +Hardware connection +---------------------- + +- For the connection of the board, please refer to :ref:`connect_hardware` +- Please make sure that the board is set correctly before proceeding to the following steps (Serial connection is recommended under Linux) + +Get bl_mcu_sdk +--------------------------- + +- Open the terminal and enter the following command to get bl_mcu_sdk + +.. code-block:: bash + :linenos: + + $ cd ~ + $ git clone https://gitee.com/bouffalolab/bl_mcu_sdk.git --recursive + + +Test Hello World project +------------------------------ + +Open Hello World +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- After obtaining the SDK, enter ``examples/hellowd/helloworld`` in the SDK, open ``main.c``, and then edit the related code of helloworld. + +.. code-block:: bash + :linenos: + + $ cd ~/bl_mcu_sdk/examples/hellowd/helloworld + $ vi main.c + +- After editing, save the changes and close the file, and then compile + +Compile Hello World +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: bash + :linenos: + + $ cd ~/bl_mcu_sdk + $ make build BOARD=bl706_iot APP=helloworld + + +Program Hello World +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Please confirm the programming method first. If you use serial programming, please press and hold the ``boot`` key on the board and don't release it. At this time, press the ``rst`` key, and then release the two keys. The board enters the boot_rom state. +- At this time, enter the following command in the terminal to program + +.. code-block:: bash + :linenos: + + $ cd ~/bl_mcu_sdk + $ make download INTERFACE=uart COMx=/dev/ttyUSB1 + +- If the download fails, please check: + + - 1. Whether the serial port is used for programming, whether the development board is powered, and whether the hardware connection is correct. + - 2. Is the programming command executed in the ``bl_mcu_sdk`` directory + - 3. Whether to enter boot_rom mode + - 4. Whether the serial port is occupied, and whether your available serial port is selected correctly, if your serial port is not ``ttyUSB1``, then please specify the correct serial port + +Run Hello World +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Open a new terminal, install and run the serial port tool + +.. code-block:: bash + :linenos: + + $ sudo apt install picocom # Ignore if it is already installed + $ picocom -b 2000000 /dev/ttyUSB1 # Pay attention to your available serial port number (if you use the serial port of Sipeed RV-debugger Plus, it will be ``ttyUSB1``) + +- Press the ``rst`` key on the board, you can see ``hello world!`` in the serial terminal. + +.. figure:: img/linux1.png + :alt: + + helloworld! + + +Debug Hello World +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + + diff --git a/docs/development_guide_en/source/get_started/Windows_quick_start_cdk.rst b/docs/development_guide_en/source/get_started/Windows_quick_start_cdk.rst new file mode 100644 index 00000000..5390eb9c --- /dev/null +++ b/docs/development_guide_en/source/get_started/Windows_quick_start_cdk.rst @@ -0,0 +1,65 @@ +.. _windows_cdk_quick_start: + +Guide to using CDK (like MDK Keil) under Windows +=================================================== + +This document introduces the use of the CDK developed by `T-HEAD Semiconductor `_ under Windows to complete the related software development of BL702 series MCU. + +Regarding T-HEAD CDK, this is an integrated development environment developed by T-HEAD. It has operations and settings that are very similar to the traditional MCU development environment, and aims to fully access cloud development resources without changing user development habits, combined with graphical debugging and analysis tools such as OSTracer and Profiling, to accelerate user product development. + +Software and hardware environment +-------------------------------------- + +- T-HEAD CDK software +- One USB Type-A data cable, one Type-C data cable +- A CK-Link emulator or a Sipeed RV-Debugger Plus debugger +- A USB-TTL serial port module +- Several Dupont lines + + +Download CDK +----------------------------- + +- `CDK `_ software can be obtained from the official website of T-HEAD OCC + +- After the download is complete, unzip, double-click ``setup.exe``, follow the prompts, and complete the software installation + +Download bl_mcu_sdk +---------------------------- + +- Download bl_mcu_sdk from the open source community. + + - You can use ``git clone`` or directly ``download`` to download the SDK + - Before using ``git clone``, please make sure that ``git`` has been installed correctly, open a terminal that supports ``git`` and enter the following command to get the latest SDK + + .. code-block:: bash + :linenos: + :emphasize-lines: 1 + + $ git clone https://gitee.com/bouffalolab/bl_mcu_sdk.git --recursive + + +Hardware connection +----------------------- + +- For specific connection methods, please refer to :ref:`connect_hardware` +- Please make sure that the board is set up correctly before proceeding to the following steps + +Test the Hello World project +------------------------------ + +**When using Sipeed RV-Debugger Plus to debug a project, please follow the steps below:** + +.. toctree:: + :maxdepth: 1 + + Use Sipeed RV-Debugger + +**When using CK-Link to debug the project, please follow the steps below:** + +.. toctree:: + :maxdepth: 1 + + Use CK-Link + + diff --git a/docs/development_guide_en/source/get_started/Windows_quick_start_eclipse.rst b/docs/development_guide_en/source/get_started/Windows_quick_start_eclipse.rst new file mode 100644 index 00000000..477a319c --- /dev/null +++ b/docs/development_guide_en/source/get_started/Windows_quick_start_eclipse.rst @@ -0,0 +1,170 @@ +Eclipse Development Guide under Windows +========================================== + +This document introduces the use of eclipse under Windows to build a software development environment for BL702 series MCU. + +Software and hardware environment +------------------------------------ + +- Eclipse free installation package +- Serial port assistant software +- A USB Type-A data cable +- A j-link emulator +- A USB-TTL serial port module +- Several Dupont lines + + +Download Eclipse +----------------------------- + +- Download the installation package with the RISC-V toolchain from the Bouffalo Lab developer community `Eclipse https://dev.bouffalolab.com/download `_ . + +Download bl_mcu_sdk +----------------------------- + +- Download from the open source community `bl_mcu_sdk `_. + +- You can use ``git clone`` or directly ``download`` to download the SDK +- Before using ``git clone``, please make sure that ``git`` has been installed correctly. Open a terminal that supports ``git`` and enter the following command to get the latest SDK. + +.. code-block:: bash + :linenos: + :emphasize-lines: 1 + + $ git clone https://gitee.com/bouffalolab/bl_mcu_sdk.git --recursive + + +Configure eclipse +---------------------------- + +- Copy the eclipse compressed package to the working directory, unzip the eclipse compressed package +- Enter the eclipse directory, double-click ``eclipse.exe`` to start eclipse +- Select your ``Workspace`` directory, click ``Launch`` to enter the workspace + + .. figure:: img/pic1.png + :alt: + +- Click ``Window->preferences`` in the menu bar to open the environment configuration related page, ready to import the related configuration environment + + + .. figure:: img/pic2.png + :alt: + +- Click the icon at "1" in the figure below to open the import configuration interface, follow the steps shown in the figure, and select the ``bflb_mcu_preferences.epf`` configuration file in the ``eclipse.exe`` directory. + .. figure:: img/pic3.png + :alt: + +- After selecting the corresponding file, click ``Finish``, select and click ``cancel`` in the dialog box without restarting. + + .. figure:: img/pic4.png + :alt: + +Import bl_mcu_sdk +-------------------------- + +- Click on the menu bar ``File->Import`` to open the configuration interface of the imported project + + .. figure:: img/pic5.png + :alt: + +- In the opened ``Import`` window, select ``General->Existing Projects into Workspace``, and then click ``Next`` + + .. figure:: img/pic6.png + :alt: + +- After loading the project path of bl_mcu_sdk, click ``Finsh`` to complete the import + + .. figure:: img/pic7.png + :alt: + +- After the import is complete, close the ``Welcome`` window to see the imported project + + .. figure:: img/pic8.png + :alt: + + .. figure:: img/pic9.png + :alt: + +- Expand ``Build Target``, you can see the three function buttons ``bl_clean``, ``bl_make``, and ``download``. + + - Double-click the ``bl_clean`` button, it will clear the compilation cache in the ``build`` and ``out`` directories + - Double-click the ``bl_make`` button, the set case will be compiled normally, if the default configuration is not modified, the ``helloworld`` project will be compiled + - Double-click the ``download`` button, the code will be downloaded to the chip, if it is not compiled successfully, the default or last ``.bin`` file will be downloaded + +Hardware connection +---------------------- + +- For specific board connection, please refer to :ref:`connect_hardware`; (The eclipse environment recommends using ``j-link`` for programming and debugging) +- Please make sure that the development board is set up correctly before proceeding to the following steps + +Test the Hello World project +------------------------------- + +Open Hello World +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Open ``examples/hellowd/helloworld/main.c``, you can edit and modify the code of the ``helloworld`` test demo. If you modify it, please save it and execute the compilation + +Compile Hello World +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Double click ``bl_make`` to compile the helloworld project + +- After successful compilation, you can see the log information as shown in the figure below in the ``Console`` window + +.. figure:: img/pic10.png + + +Program Hello World +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Double-click ``download`` to program the helloworld project ``bin`` file to the chip + +- After the download is successful, you can see the log information as shown in the figure below in the ``Console`` window + +.. figure:: img/pic11.png + + +Run Hello World +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Connect the ``TXD0``, ``RXD0`` and ``GND`` pins of the board to the USB-TTL serial port module with a DuPont cable, insert the serial port module into the PC, and use any serial port assistant software to open the serial port +- After the programming is successful, press the ``rst`` button on the board. If the download is correct, you can see the log information as shown in the figure below in the serial port assistant software. + +.. figure:: img/eclipse_run.png + + +Debug Hello World +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Click the ``Debug`` button in the eclipse toolbar to enter the debug configuration window +- Select ``GDB SEGGER J-Link Debugging->Jlink_bl_mcu_sdk``, select the ``.elf`` file that needs to be debugged in ``C/C++ Application:`` +- Click ``Apply`` first, then click ``Debug`` to start ``Debug`` + +.. figure:: img/pic14.png + :alt: + +- After entering the Debug interface, you can see that the program stops at ``main``, click the ``Step Over`` button in the upper toolbar to perform single-step debugging of the code project. + +.. figure:: img/pic15.png + :alt: + + Eclipse Debugging + + +Compile and program different target projects +------------------------------------------------- + +- When you right-click the ``bl_make`` button and click ``Edit``, the configuration interface for replacing the target project will pop up, as shown in the figure below + +.. figure:: img/pic12.png + :alt: + + +- Where ``APP=xxx`` can be changed to the name of the target project that needs to be compiled and programmed. For example, if you want to compile and program the ``gpio/gpio_blink`` project, modify it to ``APP=gpio_blink``. +- ``make BOARD=bl706_iot`` in ``Build command`` will specify different Board types to adapt to different types of boards. + +- The ``Board`` type determines the corresponding ``borad`` header file when compiling. The default selection is ``make build BOARD=bl706_iot`` + + + diff --git a/docs/development_guide_en/source/get_started/bl_dev_cube.rst b/docs/development_guide_en/source/get_started/bl_dev_cube.rst new file mode 100644 index 00000000..917c807a --- /dev/null +++ b/docs/development_guide_en/source/get_started/bl_dev_cube.rst @@ -0,0 +1,90 @@ +.. _bl_dev_cube: + +BLDevCube start guide +=============================== + +This document mainly introduces the use of Bouffalo Lab Dev Cube for code programming. For more details, please refer to `BLDevCube user manual `_ + +Download Bouffalo Lab Dev Cube +------------------------------------ + +- Download the version suitable for your operating system from the developer community, download address:`https://dev.bouffalolab.com/download `_ + + - For users who do not have a registered account, click on the guest portal + +- After the download is complete, you can use it after decompression + + +Configure tool download method +---------------------------------- + +- Double-click ``BLDevCube.exe``, in the ``Chip Type`` drop-down box, select the corresponding chip model, click ``Finish`` to enter the ``Dev Cube`` interface +- Enter the interface, select ``MCU`` under ``View`` in the menu bar to enter the MCU program download interface + +.. figure:: img/dev_cube_view_mcu.png + :alt: + + select mcu + +- Select the corresponding download method in the ``Interface`` column under ``Image``, and choose according to your actual physical connection +- ``Image file`` configure the absolute path of the downloaded image, click ``Browse`` to select the **Bin** file +- When you click ``click here to show advanced options``, the advanced mirroring configuration will be expanded, usually keep the default configuration; it should be noted that ``Flash Clock`` will affect the clock frequency of Flash and PSRAM at the same time , If you need to use PSRAM, you can increase the clock frequency to get better performance + +Download with UART +^^^^^^^^^^^^^^^^^^^^^ + +- ``COM Port`` is used for UART download, select the COM number connected to the chip, and click ``Refresh`` to refresh the COM number +- When ``Uart Speed`` is used for UART download, configure the appropriate baud rate, the default is 2M + +- Please make sure the hardware configuration is correct before downloading: + + - Use ``Type-C USB`` or ``Mini USB`` to connect to the corresponding USB ``Type-C`` port or ``Mini`` port on the board. + - Press the ``Boot`` key on the board, don't release it + - Press the ``RST`` key on the board, now you have entered ``Boot ROM`` model, you can release the two keys + - At this time, you can see the corresponding serial port ``COM`` number from the ``Bouffalo Lab Dev Cube``, if it does not appear, please click the ``Refresh`` button to refresh + +- After completing the above configuration correctly, click the ``Create&Program`` button to download + +- After the download is successful, you will see the status bar turn green and display ``Success`` + +.. figure:: img/dev_cube_download.png + :alt: + + download success! + +Download with Openocd +^^^^^^^^^^^^^^^^^^^^^^^^ + +- Download using openocd is basically the same as using serial port download option configuration, just switch ``Interface`` to ``Openocd`` +- The hardware connection needs to be changed to a debugger connection that supports Openocd (this tutorial takes Sipeed RV Debugger as an example): + + - 1. Connect the RV debugger to the USB port of the computer, open the device manager, you will find that the debugger is recognized as two serial ports (note: not the serial port on the board) + + .. figure:: img/sipeed_rv_debugger_1.png + + - 2. Download the ``zadig-2.4`` replacement driver from sipeed. Download link: `http://dl.sipeed.com/MAIX/tools/sipeed-rv-debugger/zadig-2.4.exe `_ + - 3. After downloading, double-click to open ``zadig-2.4.exe``, and check List All Devices in Options. + - 4. Find JTAG Debugger (Interface 0), then select the replacement driver as WinUSB and click Replace Driver to replace + - 5. Open the device manager again and see that one of the serial ports has been replaced with a universal serial bus device, indicating that the installation is successful + + .. figure:: img/sipeed_rv_debugger_2.png + + - 6. Connect the JTAG pins of the debugger with the JTAG pins of the board + +- After completing the above configuration correctly, click the ``Create&Program`` button to download +- After the download is successful, you will see the status bar turn green and display ``Success`` + +Download with Jlink +^^^^^^^^^^^^^^^^^^^^^^ + +- The tool configuration for downloading using Jlink and Openocd is basically the same, just switch ``Interface`` to ``Jlink`` +- The hardware connection needs to be changed to use Jlink connection (this tutorial takes Jlink V11 as an example, it is recommended to use Jlink V10 or later): + + - 1. Download the appropriate Jlink driver from Segger official website and install it + - 2. Connect the Jlink debugger to the USB port of the computer + - 3. Connect the JTAG pins of the JLink debugger with the JTAG pins of the board + +- After completing the above configuration correctly, click the ``Create&Program`` button to download + +- After the download is successful, you will see the status bar turn green and display ``Success`` + diff --git a/docs/development_guide_en/source/get_started/board.rst b/docs/development_guide_en/source/get_started/board.rst new file mode 100644 index 00000000..d3846f0c --- /dev/null +++ b/docs/development_guide_en/source/get_started/board.rst @@ -0,0 +1,189 @@ +Board Configuration System User Guide +========================================= + +In order to implement the idea of **everything is a file**, we propose a Board configuration system for embedded applications with different hardware configuration requirements. The **Board configuration system** is mainly used for initializing the three basic elements of clock, GPIO, and peripheral default configuration in embedded applications. + +**Board Configuration System** contains three configuration files, and a ``bl_config_wizard`` graphical configuration software + +- **clock_config.h** Clock configuration Include file +- **peripheral_config.h** Peripheral configuration Include file +- **pinmux_config.h** Pin Function Configuration Include file +- **bl_config_wizard** The graphical interface configures the above three types of files + +The user only needs to modify three configuration files and the system will be initialized automatically, thus eliminating the need to call a series of complex and lengthy initialization functions in the user program. Boufflao Lab provides ``bl_config_wizard`` configuration software for users to quickly and easily generate configuration files for their projects. + +`bl_config_wizard`_ supports PC-side online configuration, but currently does not support mobile terminal online configuration. + +.. _bl_config_wizard: https://dev.bouffalolab.com/media/config/index.html + +.. figure:: img/config_wizard.png + :alt: + + bl_config_wizard Preview + + +The features of each file in the Board configuration system +---------------------------------------------------------------- + +The board system is mainly used for different boards, different boards create different board files and put them in ``bsp/board`` directory, and a board file, in the case of **pins not conflicting**, can be shared to different demos, no need to create multiple projects and reduce the project file size. + +.. error:: If there is a pin conflict and you have to use the same Board file, please modify the pins yourself + +**board.c** +^^^^^^^^^^^^^^^^^^^^ + +``board.c`` Main initialization of clock and pins + +**blxxx_config.h** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``blxxx_config.h`` Mainly contains some header files for the HAL layer driver. + +.. hint:: The above two files do not need to be changed by the user, and the same MCU can be copied and pasted directly into your own board directory for use + +**clock_config.h** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``clock_config.h`` Mainly configures the clock sources for the system and peripherals as well as the frequency division system. + +**peripheral_config.h** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``peripheral_config.h`` It mainly contains the enablement of peripherals and the configuration of parameters. + +.. warning:: Macros starting with ``#define BSP_USING_XXX`` are used to enable the configuration of the peripheral, if the macro is not enabled, all functions of the peripheral cannot be used + +.. warning:: Macro starting with ``XXX_CONFIG``, used to initialize the configuration of the peripheral, which is later used by calling ``device_open`` + + +**pinmux_config.h** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``pinmux_config.h`` Mainly configures the GPIO pin function of the peripheral. + +.. warning:: In mcu sdk, all demos share this file, so some demos are not usable and require frequent changes to the pin function configuration in this file. If the user has already set the pin assignments, there is no need to modify them frequently. + +Use of the Board configuration tool **bl_config_wizard** +--------------------------------------------------------------- + +- The ``bl_config_wizard`` can be accessed by clicking on this link `https://dev.bouffalolab.com/media/config/index.html `_ wizard in the online version. Chrome, Firefox, Microsoft Edge browsers are recommended. + +Generate a new **pinmux_config.h** file +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +1. Select ``Pin & Peripheral Configuration`` in the window bar. +#. Select MCU model, currently supports ``BL706 pin configuration``, ``BL704 pin configuration``, ``BL702 pin configuration``. +#. Select the function of the pin, take ``BL706 pin configuration`` as an example, click on the drop-down box of **PAD_GPIO_XX** and select the desired function, as shown in the figure. + +.. figure:: img/config_wizard_example1.png + :alt: + + Select pin function + + +4. After configuring all the pin functions, click ``Export Configuration File`` and then you can select the path and modify the file name in the pop-up box, as shown in the figure. + +.. figure:: img/config_wizard_example2.png + :alt: + + Exporting configuration files + +Modify the original **pinmux_config.h** file +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Often in use, instead of generating a new **pinmux_config.h** file, we make changes to the original **pinmux_config.h** file, and ``bl_config_wizard`` supports such a need. + +1. Select ``Pin & Peripheral Configuration`` in the window bar. +#. Select MCU model, currently supports ``BL706 pin configuration``, ``BL704 pin configuration``, ``BL702 pin configuration``. +#. Click on ``import configuration file`` and select the **pinmux_config.h** file in the pop-up box. +#. Select the pin to be modified and click on its drop-down box to change the pin function +#. When you are done, click ``Export Profile`` and then you can select the path and modify the file name in the pop-up box. + + +Modify the **pinmux_config.h** file in the CDK tool +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- **pinmux_config.h** Also supports the use of graphical configuration wizards in the CDK for adjusting the corresponding pin functions +- Drag the **pinmux_config.h** file directly into the CDK text editor interface, and you will see the ``Configuration Wizard`` tab at the bottom of the text editor + + .. figure:: img/configuration_wizard_1.png + :alt: + + Configuration Wizard + +- Click on the ``Configuration Wizard`` tab to open the graphical configuration wizard interface +- The functions supported by the pin can be selected by selecting the drop-down box + + .. figure:: img/configuration_wizard_2.png + :alt: + + Graphical configuration wizard to set pin functions + +- Please refer to the Graphical Configuration Wizard section of CDK Help for more information on the specific functions and code rules of the Graphical Configuration Wizard. + + + +Differences with STM32CUBEMX Configuration Tool +-------------------------------------------------- + +STM32CUBEMX is also a tool to configure the clock, peripherals and GPIO initialization, eventually generating a complete project with initialization at the very beginning of ``main.c``, and the GPIO and peripheral initialization base will be called in ``stm32xxx_hal_msp.c``. + +.. code-block:: C + + /* MCU Configuration--------------------------------------------------------*/ + + /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ + HAL_Init(); + + /* USER CODE BEGIN Init */ + + /* USER CODE END Init */ + + /* Configure the system clock */ + SystemClock_Config(); + + /* USER CODE BEGIN SysInit */ + + /* USER CODE END SysInit */ + + /* Initialize all configured peripherals */ + MX_GPIO_Init(); + MX_USART1_UART_Init(); + MX_QUADSPI_Init(); + +.. code-block:: C + + void HAL_UART_MspInit(UART_HandleTypeDef* huart) + { + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(huart->Instance==UART5) + { + /* USER CODE BEGIN UART5_MspInit 0 */ + + /* USER CODE END UART5_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_UART5_CLK_ENABLE(); + + __HAL_RCC_GPIOB_CLK_ENABLE(); + /**UART5 GPIO Configuration + PB12 ------> UART5_RX + PB13 ------> UART5_TX + */ + GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_13; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF14_UART5; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /* UART5 interrupt Init */ + HAL_NVIC_SetPriority(UART5_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(UART5_IRQn); + /* USER CODE BEGIN UART5_MspInit 1 */ + + /* USER CODE END UART5_MspInit 1 */ + } + + } + +.. hint:: The projects generated by stm32 all work for one project and cannot be compiled for more than one project at the same time. If you use more than one project, you have to generate more than one of these two files. When using multiple projects, it will indirectly increase the file size and add duplicate files. diff --git a/docs/development_guide_en/source/get_started/cdk_ck_link.rst b/docs/development_guide_en/source/get_started/cdk_ck_link.rst new file mode 100644 index 00000000..6799a468 --- /dev/null +++ b/docs/development_guide_en/source/get_started/cdk_ck_link.rst @@ -0,0 +1,112 @@ +Use CDK + CK-Link to compile and debug +========================================= + + +Open Hello World +------------------------------ + +- After obtaining the SDK, enter the ``examples/hellowd/helloworld/cdk`` directory in the SDK, double-click ``helloworld.cdkproj``, and you can open the ``Helloworld`` project + +Compile Hello World +------------------------------ + +.. figure:: img/cdk1.png + :alt: + + helloworld.cdkproj + +- In the drop-down menu, you can select the ``CK_Link_Debug`` or ``OpenOCD_Debug`` project, this tutorial is based on the ``CK_Link_Debug`` project + +- In the CDK toolbar, click the compile icon to compile the project + + - Click the icon ``Build Project`` at ``1`` to compile the currently selected project + - Click the icon ``Clean Project`` at ``2`` to clear the result of the last compilation + - Click the ``3`` icon ``Flash Download`` to download the compiled code to the chip + - Click the icon ``Start/Stop Debug`` at ``4`` to perform debugging related operations (when using ``CK-Link``, you can load the code to flash first) + - Click the ``5`` icon ``Start/Stop Debug whitout Download`` to debug directly without loading the current bin file + - You can also right-click the project name in ``Project``, and compile the project through the options in the right-click menu + +Program Hello World +---------------------------- + +- Since our flash algorithm is not currently included in the CDK software, we need to put the flash algorithm in the CDK installation directory. The specific operations are as follows: + + - Enter the ``tools\cdk_flashloader`` directory under the SDK directory + - Copy the ``bl70x_flasher.elf`` file in the directory to the ``C-Sky\CDK\CSKY\Flash`` directory of the CDK tool + + .. figure:: img/cdk7.png + :alt: + + CDK Flash Loader + + + +.. figure:: img/cdk8.png + :alt: + + CDK Project Setting + +- Click the project setting button in the ``Project View`` to open the ``Project Setting`` window, or open it through the ``Project`` menu bar + +- In the opened ``Project Setting`` window, select the ``Flash`` tab to configure the required Flash algorithm + +.. figure:: img/cdk9.png + :alt: + + CDK Project Flash setting + +- In the ``Flash`` tab, click the ``Add`` button, select the ``bl70x_flash`` algorithm in the opened list, and click ``Add`` to add it to the project. Others in ``Flash`` configuration, as shown in the figure: + +- After clicking OK, if the configuration is correct, click ``Flash Download`` to download the compiled code to the chip + + +.. figure:: img/cdk5.png + :alt: + + CDK Flashdownload Success + +- If the download fails, please check: + + - 1. Whether the code is compiled correctly and generate files such as ``.elf``, ``.bin``, etc. + - 2. Is the Flash algorithm correctly set? + - 3. Whether the CK-Link and the board are properly connected + - 4. Whether the development board is powered normally and whether the power indicator is on + +Run Hello World +---------------------------- + +- From the menu bar of the CDK ``View->Serial Pane``, open the serial port panel, right-click in the opened ``Serial Pane``, set the serial port, select your corresponding serial port number and baud rate + +.. figure:: img/cdk4.png +.. figure:: img/cdk3.png + :alt: + + CDK Serial Pane setting + +- Press the ``RST`` key on the board, you can see the result of the code in the serial port + +.. figure:: img/cdk6.png + :alt: + + HelloWorld! + + +Debug Hello World +---------------------------- + +- Click the ``Start/Stop Debugger`` button at the top of the toolbar to enter the debug interface, as shown in the figure below + +.. figure:: img/cdk10.png + :alt: + + Debug HelloWorld! + +- In the debug interface, the ``Register`` window can view the ``CPU`` internal register data; the ``Peripherals`` peripheral panel, you can view the corresponding peripheral register data, the top menu bar ``Peripherals-> System Viewer`` can select peripherals; click the relevant debugging button in the upper toolbar to perform operations such as breakpoint setting, single-step debugging, single-step instruction, and full-speed operation. Of course, these operations have corresponding shortcut keys and shortcut setting methods. For details, please refer to ``CDK Help``. + +- We click the single step button to run the code, and we can see that the cursor moves to the next sentence of code, and we can see our output ``Hello World!`` displayed in the serial port panel. + +.. figure:: img/cdk11.png + :alt: + + Debug HelloWorld! + diff --git a/docs/development_guide_en/source/get_started/cdk_new_project_quick_start.rst b/docs/development_guide_en/source/get_started/cdk_new_project_quick_start.rst new file mode 100644 index 00000000..dc11d649 --- /dev/null +++ b/docs/development_guide_en/source/get_started/cdk_new_project_quick_start.rst @@ -0,0 +1,76 @@ +New Project Guide based on CDK +================================== + +This document will briefly explain how to create a new CDK project based on this SDK, please make sure that the CDK IDE is properly installed before following this tutorial. + +Examples directory structure +---------------------------------- + +There are two levels of subdirectories under ``bl_mcu_sdk/examples``, the first level is the folders of different peripherals. The second level is a specific test case of the peripheral, The second level directory usually also contains a directory named ``cdk`` and the source code associated with the case. +The ``cdk`` directory usually contains a ``xxx.cdkproj`` file, which is a CDK project file. If the **CDK** IDE is properly installed, double-click the project to open it. The newly created project should be at the same level as the case level in the current ``examples`` directory. + + +.. note:: The source file must contain the c program entry, usually the ``main`` function, the source file may not be called ``main.c`` + +- Create a new ``my_case`` folder under ``examples`` to store your case +- Create a new folder that needs to be tested in the ``my_case`` directory, such as ``gpio_case`` +- Then add the ``main.c`` file and ``cdk`` directory in the ``gpio_case`` directory + + +The directory structure is as follows: + +.. code-block:: bash + :linenos: + + bl_mcu_sdk + ├── examples + ├── my_case + ├── gpio_case + │ ├── cdk + │ │ ├──gpio_case.cdkproj + │ ├── CMakeLists.txt + │ └── main.c + └── xxxx_case + + +Add cdk project related files +-------------------------------- + +Since the current version of CDK does not support new pure ``Empty`` projects, please follow the steps below + +- Copy ``helloworld.cdkproj`` from the cdk directory in the ``helloworld`` case to your own cdk directory +- Change the file name to your case name, for example: ``gpio_case.cdkproj`` +- Open the ``gpio_case.cdkproj`` file with a text editor and change ``Project Name`` to your project name, for example: ``gpio_case`` + + +.. figure:: img/cdk_start_1.png + :alt: + + +- After editing, save the file and double-click ``gpio_case.cdkproj`` to open the project +- Once you open the project, you can right-click on the appropriate folder and add the source code files you need + +.. figure:: img/cdk_start_2.png + :alt: + + +- Right-click the project, open ``Project Settings``, select the Compiler tab, and add the corresponding header files needed for the new file in ``Include paths``. +- Relative paths are recommended for header file paths +- Click ``OK`` to save the edit + + +.. figure:: img/cdk_start_3.png + :alt: + + +- In case of floating point printouts, you need to add the flag option ``-u _printf_float`` in the Linker tag, in ``Other flags``, otherwise you can't printf floating point properly + +.. figure:: img/cdk_start_4.png + :alt: + + +- In the case of using different development boards, pay attention to choose different board file references, usually, the default configuration is **bl706_iot** + +.. figure:: img/cdk_start_5.png + :alt: + diff --git a/docs/development_guide_en/source/get_started/cdk_rv_debugger_plus.rst b/docs/development_guide_en/source/get_started/cdk_rv_debugger_plus.rst new file mode 100644 index 00000000..d9ae8348 --- /dev/null +++ b/docs/development_guide_en/source/get_started/cdk_rv_debugger_plus.rst @@ -0,0 +1,66 @@ +Use CDK + Sipeed RV-Debugger Plus to compile and debug +========================================================== + +Open Hello World +------------------------------ + +- After obtaining the SDK, enter the ``examples/hellowd/helloworld/cdk`` directory and double-click ``helloworld.cdkproj`` to open the ``Helloworld`` project + +Compile Hello World +------------------------------ + +.. figure:: img/cdk1.png + :alt: + + helloworld.cdkproj + +- Select the ``OpenOCD_Debug`` project in the drop-down menu. Since Sipeed RV-Debugger Plus uses OpenOCD for debugging, this tutorial is based on the ``OpenOCD_Debug`` project; +- If Sipeed RV-Debugger Plus does not install the driver correctly, please refer to :ref:`sipeed_rv_debugger_plus`, set up the driver, and then proceed to the following steps + +- In the CDK toolbar, click the compile icon to compile the project + + - Click ``1`` ``Build Project`` to compile the currently selected project + - Click ``2`` ``Clean Project`` to clear the results of the last compilation + - Click ``3`` ``Flash Download`` to download the compiled code to the chip (**Flash download function cannot be used with OpenOCD Debug**) + - Click ``5`` ``Start/Stop Debug whitout Download`` to debug directly without loading the current bin file + - You can also right-click the project name in ``Project``, and compile the project through the options in the right-click menu + + +Program Hello World +---------------------------- + +- When using the OpenOCD mode debugging method in the CDK, it is not currently supported to directly use the CDK related ``flash`` tool to download the code, so please use the BL Dev Cube tool to program, please refer to :ref:`bl_dev_cube` +- Use CDK to debug after the code is programmed + +Run Hello World +---------------------------- + +- From the menu bar of the CDK ``View->Serial Pane``, open the serial port panel, right-click in the opened ``Serial Pane``, set the serial port, select your corresponding serial port number and baud rate + +.. figure:: img/cdk4.png +.. figure:: img/cdk3.png + :alt: + + CDK Serial Pane setting + +- Press the ``RST`` key on the board, you can see the result of the code in the serial port + +.. figure:: img/cdk6.png + :alt: + + HelloWorld! + + +Debug Hello World +---------------------------- + +- Click the ``Start/Stop Debugger`` button at the top of the toolbar to enter the debug interface, as shown in the figure below + +.. figure:: img/cdk10.png + :alt: + + Debug HelloWorld! + +- In the debug interface, the ``Register`` window can view the ``CPU`` internal register data; the ``Peripherals`` peripheral panel, you can view the corresponding peripheral register data, the top menu bar ``Peripherals-> System Viewer`` can select peripherals; click the relevant debugging button in the upper toolbar to perform operations such as breakpoint setting, single-step debugging, single-step instruction, and full-speed operation. Of course, these operations have corresponding shortcut keys and shortcut setting methods. For details, please refer to ``CDK Help``. + +- We click the single step button to run the code, and we can see that the cursor moves to the next sentence of code, and we can see our output ``Hello World!`` displayed in the serial port panel. diff --git a/docs/development_guide_en/source/get_started/cmake_quick_start.rst b/docs/development_guide_en/source/get_started/cmake_quick_start.rst new file mode 100644 index 00000000..0b32fe2b --- /dev/null +++ b/docs/development_guide_en/source/get_started/cmake_quick_start.rst @@ -0,0 +1,207 @@ +New Project Guide based on cmake framework +============================================= + +This document will introduce how to create a new project based on this SDK. + +Examples directory structure +------------------------------------ + +There are two levels of subdirectories under ``bl_mcu_sdk/examples``, the first level is the folders of different peripherals. The second level is a specific test case of the peripheral, and the directory usually contains a ``CMakeList.txt`` and the source code related to the case. + + +Add a single source file project +----------------------------------- + +.. note:: + The source file must contain the c program entry, usually the ``main`` function, the source file may not be called ``main.c`` + +- Create a new ``my_case`` folder under ``examples`` to store your case +- Create a new folder that needs to be tested in the ``my_case`` directory, such as ``gpio_case`` +- Then add the ``main.c`` and ``CMakeLists.txt`` files in the ``gpio_case`` directory + + +The directory structure is as follows: + +.. code-block:: bash + :linenos: + + bl_mcu_sdk + ├── examples + ├── my_case + ├── gpio_case + │ ├──CMakeLists.txt + │ └──main.c + └── xxxx_case + +`CMakeLists.txt`: + +.. code-block:: cmake + :linenos: + :emphasize-lines: 1-2 + + set(mains main.c) + generate_bin() + +- After writing the code in main.c, compile it in the bl_mcu_sdk directory. The compilation command is as follows: + +.. code-block:: bash + :linenos: + + make BOARD=bl706_iot APP=gpio_case + + +Add multiple source file projects +------------------------------------- + +.. note:: + One of the source files must contain the c program entry, usually the ``main`` function, the source file does not need to be called ``main.c``. This source file depends on other source files. + +- The steps for adding a multi-source file project are the same as the basic steps for adding a single source file project +- Add ``test1.c``, ``test1.h``, ``test2.c``, ``test2.h`` and other source files and header files that need to be relied on in the ``gpio_case`` directory + +The directory structure is as follows: + +.. code-block:: bash + :linenos: + + bl_mcu_sdk + ├── examples + ├── my_case + ├── gpio_case + │ ├──CMakeLists.txt + │ ├──test1.c + │ ├──test1.h + │ ├──test2.c + │ ├──test2.h + │ └──main.c + └── xxxx_case + +- At this time, the ``CMakeLists.txt`` file needs to add the corresponding dependent source file, the content is as follows: + +`CMakeLists.txt`: + +.. code-block:: cmake + :linenos: + :emphasize-lines: 2 + + set(mains main.c) + set(TARGET_REQUIRED_SRCS test1.c test2.c) + generate_bin() + +- After writing the code, compile it in the bl_mcu_sdk directory. The compilation command is as follows: + +.. code-block:: bash + :linenos: + + make BOARD=bl706_iot APP=gpio_case + + +Add a new project with dependent libraries +--------------------------------------------- + +- The steps for adding a new project with dependent libraries are the same as the basic steps for adding a single source file project +- If the dependent library used already exists in this SDK, you only need to modify CMakeLists.txt + + - If the dependent library does not exist, you need to add it yourself, please refer to the follow-up instructions for details + + +If it already exists, the directory structure is as follows: + +.. code-block:: bash + :linenos: + + bl_mcu_sdk + ├── examples + ├── my_case + ├── gpio_case + │ ├──CMakeLists.txt + │ └──main.c + └── xxxx_case + +- At this time, the ``CMakeLists.txt`` file needs to add the corresponding dependent library files. For example, we add the FreeRTOS component library, the content is as follows: + +`CMakeLists.txt`: + +.. code-block:: cmake + :linenos: + :emphasize-lines: 1 + + set(TARGET_REQUIRED_LIBS freertos) + set(mains main.c) + generate_bin() + +- After writing the code, compile it in the bl_mcu_sdk directory. The compilation command is as follows: + +.. code-block:: bash + :linenos: + + make BOARD=bl706_iot APP=gpio_case SUPPORT_FREERTOS=y + +Add a new project and set the private compilation option (gcc option) +------------------------------------------------------------------------- + +- The steps of adding a new project are basically the same as adding a single source file project +- Mainly modify the CMakeLists.txt file and add private compilation options + +`CMakeLists.txt`: + +.. code-block:: cmake + :linenos: + :emphasize-lines: 2 + + set(mains main.c) + set(TARGET_REQUIRED_PRIVATE_OPTIONS -Ofast) + generate_bin() + +- After writing the code, compile it in the bl_mcu_sdk directory. The compilation command is as follows: + +.. code-block:: bash + :linenos: + + make BOARD=bl706_iot APP=gpio_case + + +Add a new project and set up a private link script (ld) +------------------------------------------------------------ + +- The steps of adding a new project are basically the same as adding a single source file project +- Add a private link script file, such as ``gpio_test_case.ld`` + +The directory structure is as follows: + +.. code-block:: bash + :linenos: + + bl_mcu_sdk + ├── examples + ├── my_case + ├── gpio_case + │ ├──CMakeLists.txt + │ ├──gpio_test_case.ld + │ └──main.c + └── xxxx_case + +- Modify the CMakeLists.txt file and add private link script settings + +`CMakeLists.txt`: + +.. code-block:: cmake + :linenos: + :emphasize-lines: 1 + + set(LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/gpio_test_case.ld) + set(mains main.c) + generate_bin() + +- After writing the code, compile it in the bl_mcu_sdk directory. The compilation command is as follows: + +.. code-block:: bash + :linenos: + + make BOARD=bl706_iot APP=gpio_case + + +Add a new project and its dependent source files and library files +---------------------------------------------------------------------- + + diff --git a/docs/development_guide_en/source/get_started/connecting_hardware.rst b/docs/development_guide_en/source/get_started/connecting_hardware.rst new file mode 100644 index 00000000..203cb607 --- /dev/null +++ b/docs/development_guide_en/source/get_started/connecting_hardware.rst @@ -0,0 +1,194 @@ +.. _connect_hardware: + +Hardware connection +======================= + +This document introduces how to connect the board of BL70x series MCU. + +BL706_IOT +------------------------- + +Use CK-Link to Programming and debug +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Connect the CK-Link USB interface to the PC with a suitable USB data cable +- Connect the standard ``JTAG`` pin of the ``HD3`` group of the Iot board with the ``JTAG`` pin of ``CK-Link`` using a DuPont cable +- If you do not use CK-Link to power the board, you need to power the board separately + + +:: + + bl706-iot board CK-Link + ------------------------------- + JTAG_TDI <--> TDI + JTAG_TDO <--> TDO + JTAG_TCK <--> TCK + JTAG_TMS <--> TMS + VDD33 <--> VREF + GND <--> GND + + +.. figure:: img/ck_link_connect_bl706_iot.png + :alt: + + ck_link connect bl706-iot board + +Use J-Link to Programming and debug +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Connect the USB interface of j-link to the PC with a USB data cable +- Connect the standard ``JTAG`` pins of the ``HD3`` group of the Iot board with the ``JTAG`` pins of the ``j-link`` using DuPont wires +- In the case of j-link connection, the board needs to be independently powered, and the power supply of the board is connected to the ``VTref`` pin of j-link + +:: + + bl706-iot board j-link + ------------------------------- + JTAG_TDI <--> TDI + JTAG_TDO <--> TDO + JTAG_TCK <--> TCK + JTAG_TMS <--> TMS + VDD33 <--> VTref + GND <--> GND + + +.. figure:: img/jlink_connect_bl706_iot.png + :alt: + + jlink connect bl706-iot board + + +Use serial port to Programming +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Before using the serial port to Programming, please make sure that ``Bouffalo Lab Dev Cube`` or the command programming tool is installed correctly + + - Use ``Type-C USB`` data cable or ``Mini USB`` data cable to connect to the ``Type-C`` interface or ``Mini`` interface on the board. + - Press the ``Boot`` key on the board, don't release it. + - Press the ``RST`` key on the board, now you have entered ``Boot ROM``, you can release the two keys. + - At this time, you can see the corresponding serial port ``COM`` number from the ``Bouffalo Lab Dev Cube``, if it does not appear, please click the ``Refresh`` key to refresh. + + +- If you don't have a suitable data cable, you can also use some common ``USB-TTL`` modules to connect to the UART0 port of the development board for programming. ``UART0`` is on the ``HD1`` group, the connection method is as follows: + +:: + + USB-TTL BL702_IoT + ---------------------- + 3V3 <--> VDD + TXD <--> RX0 + RXD <--> TX0 + GND <--> GND + +- The programming step is the same as above + +BL706_AVB +-------------------------- + +.. important:: + BL706_AVB has multiple multiplexed pins, please check carefully whether the required function pins are multiplexed; FUNC1: "Default: PIX; Connect: I2S/JTAG", FUNC2: "Default: I2S; Connect: SPI" ; **If you need to debug, please remember to connect the FUNC1 jumper** + +Use Sipeed RV-Debugger Plus to programming and debug +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Powering the BL706_AVB +- Connect the RV-Debugger Plus debugger to the USB port of the computer. If the driver is not installed correctly, please refer to :ref:`sipeed_rv_debugger_plus`, set the driver, and proceed to the following steps +- Connect the debugger and the BL706_AVB with a cable (as shown in the figure below) + +.. important:: + The FUNC1 jumper must be connected when debugging, otherwise the pins will be multiplexed with other functions and the JTAG function cannot be used; the serial port function can be used normally + +.. figure:: img/bl706_avb_rv_debugger_plus.png + :alt: + + RV-Debugger connect bl706_avb board + +Use CK-Link to programming and debug +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Connect the CK-Link USB interface to the PC with a suitable USB data cable +- Connect the FUNC1 jump caps of the bl706_avb +- Connect the pins of the ``HD8`` group to the adapter board using a flat cable +- Connect the ``JTAG`` pin of the adapter board with the corresponding ``JTAG`` pin of ``CK-Link`` using a Dupont wire +- If you do not use CK-Link to power the board, you need to power the board separately + +:: + + bl706-avb board CK-Link + ------------------------------- + JTAG_TDI <--> TDI + JTAG_TDO <--> TDO + JTAG_TCK <--> TCK + JTAG_TMS <--> TMS + VDD33 <--> VREF + GND <--> GND + + +.. figure:: img/bl706_avb_ck_link.png + :alt: + + ck_link connect bl706_avb board + +Use serial port to programming +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Before using the serial port to programming, please make sure that ``Bouffalo Lab Dev Cube`` or the command programming tool is installed correctly + + - Use the ``Type-C USB`` or ``Mini USB`` data cable to connect to the corresponding ``Type-C`` port or ``Mini`` port on the board. + - Press the ``Boot`` key on the board, don't release it. + - Press the ``RST`` key on the board, now you have entered ``Boot ROM``, you can release the two keys. + - At this time, you can see the corresponding serial port ``COM`` number from the ``Bouffalo Lab Dev Cube``, if it does not appear, please click the ``Refresh`` button to refresh. + + +- If you don't have a suitable data cable, you can also use some common ``USB-TTL`` modules to connect to the UART0 port of the development board for programming. ``UART0`` on the ``HD12`` group, the connection method is as follows: + +- If you use Sipeed RV-Debugger Plus to connect BL706_AVB through a flat cable, you can also use the serial port of Sipeed RV Debugger Plus + +:: + + USB-TTL BL706_AVB + ---------------------- + TXD <--> RX0 + RXD <--> TX0 + GND <--> GND + + +Connect BL706 AVB sub-modules +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- This section describes how to connect the BL706_AVB board with other modules, mainly including camera connection, Audio Codec module connection, and SPI screen connection. + +**BL706_AVB Connects to GC0308 Camera Module** + +- 1. First, take the black locking part of the ``J5`` drawer type FPC cable holder on the back of the BL706_AVB development board and pull it out from the edge + +.. figure:: img/connect_camera_1.png + :alt: + + +- 2. When fully disconnected, as shown in the figure below. + +.. figure:: img/connect_camera_2.png + :alt: + + +- 3. The FPC cable holder is a drawer down type, so next insert the camera with the side without metal contact points facing upwards into the FPC cable holder + +.. figure:: img/connect_camera_3.png + :alt: + + +- After inserting the camera, press the black latch tightly + +.. figure:: img/connect_camera_4.png + :alt: + + +**BL706_AVB Connecting Audio Codec Modules** + +- Insert the ``HD19`` group of pins of Audio Codec module into the ``HD11`` row female socket of BL706_AVB development board; note that the module is extended outward. +- The schematic diagram is as follows: + +.. figure:: img/connect_codec_1.png + :alt: + diff --git a/docs/development_guide_en/source/get_started/get_started.rst b/docs/development_guide_en/source/get_started/get_started.rst new file mode 100644 index 00000000..208d61cc --- /dev/null +++ b/docs/development_guide_en/source/get_started/get_started.rst @@ -0,0 +1,118 @@ +Preparation +============================= + +Hardware environment +----------------------------- + +- At least one board for BL702 series MCU: + + - BL706_IOT + - BL706_AVB + +BL706_Iot as shown in the figure below + +.. figure:: img/bl706_iot.png + :alt: + + BL706_IoT + +BL706_AVB as shown in the figure below + +.. figure:: img/bl706_avb.png + :alt: + + BL706_AVB + +- A debugger that supports standard JTAG, just choose one of the following debuggers: + + - CK-Link + - Jlink V11 + - Sipeed RV-Debugger Plus + - Bouffalo Lab Debugger + +- One PC host (Windows or Linux system) + +Software Environment +-------------------------------- + +In order to better use the BL702 series MCU, it is recommended that you have at least one of the following development environments: + +- Use `CDK `_ for Windows (Windows 7 or above is recommended) +- `Windows `_ Use Eclipse (Windows 7 or above is recommended) +- `Linux `_ (LTS version above Ubuntu 18 is recommended) + +.. _sipeed_rv_debugger_plus: + +Sipeed RV-Debugger Plus driver installation settings +--------------------------------------------------------- + +- This section mainly introduces the driver installation settings of the **Sipeed RV-Debugger Plus** debugger. ``If you use **CK-Link** or **J-Link**, you don’t need to read this section.`` + +.. figure:: img/sipeed_rv_debugger_plus.png + :alt: + + Sipeed RV-Debugger plus + +**Windows** + +- To use the Sipeed RV-Debugger Plus debugger on Windows we need to change the driver to the ``Win USB`` driver + + - 1. First, connect the Type-C USB interface of the debugger to the PC with a USB data cable, open the device manager of the PC, and you can see that the debugger is recognized as two serial ports in the port column (*Note: not the Serial port of the board's Boot interface*), or in the ``Universal Serial Bus Controller``, you see ``USB Serial Converter A`` and ``USB Serial Converter B`` + + .. figure:: img/sipeed_rv_debugger_1.png + + .. figure:: img/sipeed_rv_debugger_4.png + + .. important:: 1. The debugger port number must start with ``usb serial port``, if you plug in more than one similar device, please leave only one, confirm the debugger port number + .. important:: 2. If you see "USB Serial Device (COM*)" in the Device Manager, it means that the debugger has entered the "Boot" mode. Please power off the debugger and power it on again, and be careful not to connect the debugger to the target board; at this time, go to the device manager to see if it is normal + + .. figure:: img/sipeed_rv_debugger_7.png + + .. important:: 3. If the serial port is not shown in the device manager, only other devices are shown, or if you only see ``USB Serial Converter A`` and ``USB Serial Converter B`` in the Universal Serial Bus Controller, please go to the `FTDI official website `_ Download the driver that matches your system + + .. figure:: img/sipeed_rv_debugger_6.png + + - 2. Download the ``zadig-2.4`` replacement driver from the sipeed website. Download : `http://dl.sipeed.com/MAIX/tools/sipeed-rv-debugger/zadig-2.4.exe `_ + - 3. After downloading, double-click to open ``zadig-2.4.exe``, select ``Options`` and check ``List All Devices``. + + .. figure:: img/sipeed_rv_debugger_3.png + + - 4. Find JTAG Debugger (Interface 0), then select the replacement driver as ``WinUSB`` and click ``Replace Driver`` to replace + - 5. Open the device manager again and see that one of the serial ports has been replaced with a universal serial bus device, indicating that the installation is successful + + .. figure:: img/sipeed_rv_debugger_2.png + + - 6. At this point, the device driver of Sipeed RV-Debugger Plus has been replaced, and then you can play happily~ + + +**Possible problems:** + +.. caution:: 1. There are no two serial ports when the debugger is connected, and an LED on the debugger is always on, then it should be in Boot mode. Please power off the debugger and power it on again. Be careful not to connect the debugger to the target board; after the debugger is powered on, the two LED lights will flicker and go out under normal circumstances; at this time, check whether the device in the task manager is correct. + +.. caution:: 2. If you still can’t use it normally after the above operations, and there is no correct phenomenon, it is recommended to download from the official Sipeed repository `GitHub `_ obtain the firmware and re-write; press and hold the ``Boot`` button on the debugger without releasing it, insert the debugger into the computer and power on, make the debugger enter the Boot mode, and flash the firmware again; power off and restart + +**Linux** + +- First, connect the Type-C USB interface of the debugger to the PC host using the USB cable, open Terminal, and enter the command ``lsusb`` in the terminal to see the device with the following information + +.. code-block:: bash + + $ lsusb + ... + Bus 001 Device 003: ID 0403:6010 Future Technology Devices International, Ltd FT2232C Dual USB-UART/FIFO IC + ... + +.. figure:: img/sipeed_rv_debugger_8.png + +- If the above diagram does not show the ``FT2232C``, you need to install the ftdi driver + +.. code-block:: bash + + $ sudo apt install libusb-dev libftdi-dev libhidapi-dev + +- Re-plug the debugger to make the changes take effect + +- Debugging code requires openocd to be installed, using openocd version 0.11 + +.. note:: In Linux system, /dev/ttyUSB1 is used for serial port, /dev/ttyUSB0 is used for debug port, if /dev/ttyACM0 is displayed, it means boot mode is entered. + diff --git a/docs/development_guide_en/source/get_started/img/Linux_logo.png b/docs/development_guide_en/source/get_started/img/Linux_logo.png new file mode 100644 index 00000000..1112db65 Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/Linux_logo.png differ diff --git a/docs/development_guide_en/source/get_started/img/Windows_eclipse_logo.png b/docs/development_guide_en/source/get_started/img/Windows_eclipse_logo.png new file mode 100644 index 00000000..e78349ce Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/Windows_eclipse_logo.png differ diff --git a/docs/development_guide_en/source/get_started/img/bl706_avb.png b/docs/development_guide_en/source/get_started/img/bl706_avb.png new file mode 100644 index 00000000..328064d6 Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/bl706_avb.png differ diff --git a/docs/development_guide_en/source/get_started/img/bl706_avb_ck_link.png b/docs/development_guide_en/source/get_started/img/bl706_avb_ck_link.png new file mode 100644 index 00000000..da39cae4 Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/bl706_avb_ck_link.png differ diff --git a/docs/development_guide_en/source/get_started/img/bl706_avb_rv_debugger_plus.png b/docs/development_guide_en/source/get_started/img/bl706_avb_rv_debugger_plus.png new file mode 100644 index 00000000..8deac670 Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/bl706_avb_rv_debugger_plus.png differ diff --git a/docs/development_guide_en/source/get_started/img/bl706_iot.png b/docs/development_guide_en/source/get_started/img/bl706_iot.png new file mode 100644 index 00000000..04119f55 Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/bl706_iot.png differ diff --git a/docs/development_guide_en/source/get_started/img/blink_breath_sch.png b/docs/development_guide_en/source/get_started/img/blink_breath_sch.png new file mode 100644 index 00000000..ee8fd3bc Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/blink_breath_sch.png differ diff --git a/docs/development_guide_en/source/get_started/img/cdk1.png b/docs/development_guide_en/source/get_started/img/cdk1.png new file mode 100644 index 00000000..b3d99c82 Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/cdk1.png differ diff --git a/docs/development_guide_en/source/get_started/img/cdk10.png b/docs/development_guide_en/source/get_started/img/cdk10.png new file mode 100644 index 00000000..c0279b10 Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/cdk10.png differ diff --git a/docs/development_guide_en/source/get_started/img/cdk11.png b/docs/development_guide_en/source/get_started/img/cdk11.png new file mode 100644 index 00000000..eb1932dd Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/cdk11.png differ diff --git a/docs/development_guide_en/source/get_started/img/cdk2.png b/docs/development_guide_en/source/get_started/img/cdk2.png new file mode 100644 index 00000000..80cf2231 Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/cdk2.png differ diff --git a/docs/development_guide_en/source/get_started/img/cdk3.png b/docs/development_guide_en/source/get_started/img/cdk3.png new file mode 100644 index 00000000..ad453712 Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/cdk3.png differ diff --git a/docs/development_guide_en/source/get_started/img/cdk4.png b/docs/development_guide_en/source/get_started/img/cdk4.png new file mode 100644 index 00000000..5c198917 Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/cdk4.png differ diff --git a/docs/development_guide_en/source/get_started/img/cdk5.png b/docs/development_guide_en/source/get_started/img/cdk5.png new file mode 100644 index 00000000..1c3c2513 Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/cdk5.png differ diff --git a/docs/development_guide_en/source/get_started/img/cdk6.png b/docs/development_guide_en/source/get_started/img/cdk6.png new file mode 100644 index 00000000..2478ba24 Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/cdk6.png differ diff --git a/docs/development_guide_en/source/get_started/img/cdk7.png b/docs/development_guide_en/source/get_started/img/cdk7.png new file mode 100644 index 00000000..7eb65431 Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/cdk7.png differ diff --git a/docs/development_guide_en/source/get_started/img/cdk8.png b/docs/development_guide_en/source/get_started/img/cdk8.png new file mode 100644 index 00000000..e208d88f Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/cdk8.png differ diff --git a/docs/development_guide_en/source/get_started/img/cdk9.png b/docs/development_guide_en/source/get_started/img/cdk9.png new file mode 100644 index 00000000..10ec6582 Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/cdk9.png differ diff --git a/docs/development_guide_en/source/get_started/img/cdk_start_1.png b/docs/development_guide_en/source/get_started/img/cdk_start_1.png new file mode 100644 index 00000000..4f2a1549 Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/cdk_start_1.png differ diff --git a/docs/development_guide_en/source/get_started/img/cdk_start_2.png b/docs/development_guide_en/source/get_started/img/cdk_start_2.png new file mode 100644 index 00000000..01c0ef2f Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/cdk_start_2.png differ diff --git a/docs/development_guide_en/source/get_started/img/cdk_start_3.png b/docs/development_guide_en/source/get_started/img/cdk_start_3.png new file mode 100644 index 00000000..1e23de95 Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/cdk_start_3.png differ diff --git a/docs/development_guide_en/source/get_started/img/cdk_start_4.png b/docs/development_guide_en/source/get_started/img/cdk_start_4.png new file mode 100644 index 00000000..d211581a Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/cdk_start_4.png differ diff --git a/docs/development_guide_en/source/get_started/img/cdk_start_5.png b/docs/development_guide_en/source/get_started/img/cdk_start_5.png new file mode 100644 index 00000000..a26426ae Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/cdk_start_5.png differ diff --git a/docs/development_guide_en/source/get_started/img/ck_link_connect_bl706_iot.png b/docs/development_guide_en/source/get_started/img/ck_link_connect_bl706_iot.png new file mode 100644 index 00000000..34d3625b Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/ck_link_connect_bl706_iot.png differ diff --git a/docs/development_guide_en/source/get_started/img/config_wizard.png b/docs/development_guide_en/source/get_started/img/config_wizard.png new file mode 100644 index 00000000..23b64b1a Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/config_wizard.png differ diff --git a/docs/development_guide_en/source/get_started/img/config_wizard_example1.png b/docs/development_guide_en/source/get_started/img/config_wizard_example1.png new file mode 100644 index 00000000..a2cdc1ef Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/config_wizard_example1.png differ diff --git a/docs/development_guide_en/source/get_started/img/config_wizard_example2.png b/docs/development_guide_en/source/get_started/img/config_wizard_example2.png new file mode 100644 index 00000000..fd1cc605 Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/config_wizard_example2.png differ diff --git a/docs/development_guide_en/source/get_started/img/configuration_wizard_1.png b/docs/development_guide_en/source/get_started/img/configuration_wizard_1.png new file mode 100644 index 00000000..cdf7b65d Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/configuration_wizard_1.png differ diff --git a/docs/development_guide_en/source/get_started/img/configuration_wizard_2.png b/docs/development_guide_en/source/get_started/img/configuration_wizard_2.png new file mode 100644 index 00000000..fc23f618 Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/configuration_wizard_2.png differ diff --git a/docs/development_guide_en/source/get_started/img/connect_camera_1.png b/docs/development_guide_en/source/get_started/img/connect_camera_1.png new file mode 100644 index 00000000..7c692e36 Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/connect_camera_1.png differ diff --git a/docs/development_guide_en/source/get_started/img/connect_camera_2.png b/docs/development_guide_en/source/get_started/img/connect_camera_2.png new file mode 100644 index 00000000..cf9740a0 Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/connect_camera_2.png differ diff --git a/docs/development_guide_en/source/get_started/img/connect_camera_3.png b/docs/development_guide_en/source/get_started/img/connect_camera_3.png new file mode 100644 index 00000000..090f279b Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/connect_camera_3.png differ diff --git a/docs/development_guide_en/source/get_started/img/connect_camera_4.png b/docs/development_guide_en/source/get_started/img/connect_camera_4.png new file mode 100644 index 00000000..3d0ba64e Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/connect_camera_4.png differ diff --git a/docs/development_guide_en/source/get_started/img/connect_codec_1.png b/docs/development_guide_en/source/get_started/img/connect_codec_1.png new file mode 100644 index 00000000..a9e1f306 Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/connect_codec_1.png differ diff --git a/docs/development_guide_en/source/get_started/img/dev_cube_download.png b/docs/development_guide_en/source/get_started/img/dev_cube_download.png new file mode 100644 index 00000000..89b6a10e Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/dev_cube_download.png differ diff --git a/docs/development_guide_en/source/get_started/img/dev_cube_view_mcu.png b/docs/development_guide_en/source/get_started/img/dev_cube_view_mcu.png new file mode 100644 index 00000000..43d4c360 Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/dev_cube_view_mcu.png differ diff --git a/docs/development_guide_en/source/get_started/img/eclipse_run.png b/docs/development_guide_en/source/get_started/img/eclipse_run.png new file mode 100644 index 00000000..aa6e3363 Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/eclipse_run.png differ diff --git a/docs/development_guide_en/source/get_started/img/jlink_connect_bl706_iot.png b/docs/development_guide_en/source/get_started/img/jlink_connect_bl706_iot.png new file mode 100644 index 00000000..58e58581 Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/jlink_connect_bl706_iot.png differ diff --git a/docs/development_guide_en/source/get_started/img/linux1.png b/docs/development_guide_en/source/get_started/img/linux1.png new file mode 100644 index 00000000..0f55ebdb Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/linux1.png differ diff --git a/docs/development_guide_en/source/get_started/img/pic1.png b/docs/development_guide_en/source/get_started/img/pic1.png new file mode 100644 index 00000000..9866e309 Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/pic1.png differ diff --git a/docs/development_guide_en/source/get_started/img/pic10.png b/docs/development_guide_en/source/get_started/img/pic10.png new file mode 100644 index 00000000..b61cbfa9 Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/pic10.png differ diff --git a/docs/development_guide_en/source/get_started/img/pic11.png b/docs/development_guide_en/source/get_started/img/pic11.png new file mode 100644 index 00000000..9fe441dd Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/pic11.png differ diff --git a/docs/development_guide_en/source/get_started/img/pic12.png b/docs/development_guide_en/source/get_started/img/pic12.png new file mode 100644 index 00000000..f60184f9 Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/pic12.png differ diff --git a/docs/development_guide_en/source/get_started/img/pic13.png b/docs/development_guide_en/source/get_started/img/pic13.png new file mode 100644 index 00000000..2b7ec966 Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/pic13.png differ diff --git a/docs/development_guide_en/source/get_started/img/pic14.png b/docs/development_guide_en/source/get_started/img/pic14.png new file mode 100644 index 00000000..bf018a3a Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/pic14.png differ diff --git a/docs/development_guide_en/source/get_started/img/pic15.png b/docs/development_guide_en/source/get_started/img/pic15.png new file mode 100644 index 00000000..73b97316 Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/pic15.png differ diff --git a/docs/development_guide_en/source/get_started/img/pic2.png b/docs/development_guide_en/source/get_started/img/pic2.png new file mode 100644 index 00000000..2d5129bc Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/pic2.png differ diff --git a/docs/development_guide_en/source/get_started/img/pic20.png b/docs/development_guide_en/source/get_started/img/pic20.png new file mode 100644 index 00000000..f040e625 Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/pic20.png differ diff --git a/docs/development_guide_en/source/get_started/img/pic3.png b/docs/development_guide_en/source/get_started/img/pic3.png new file mode 100644 index 00000000..0e20a992 Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/pic3.png differ diff --git a/docs/development_guide_en/source/get_started/img/pic4.png b/docs/development_guide_en/source/get_started/img/pic4.png new file mode 100644 index 00000000..9424826d Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/pic4.png differ diff --git a/docs/development_guide_en/source/get_started/img/pic5.png b/docs/development_guide_en/source/get_started/img/pic5.png new file mode 100644 index 00000000..40158e36 Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/pic5.png differ diff --git a/docs/development_guide_en/source/get_started/img/pic6.png b/docs/development_guide_en/source/get_started/img/pic6.png new file mode 100644 index 00000000..009a704e Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/pic6.png differ diff --git a/docs/development_guide_en/source/get_started/img/pic7.png b/docs/development_guide_en/source/get_started/img/pic7.png new file mode 100644 index 00000000..c88657dc Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/pic7.png differ diff --git a/docs/development_guide_en/source/get_started/img/pic8.png b/docs/development_guide_en/source/get_started/img/pic8.png new file mode 100644 index 00000000..445b10d1 Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/pic8.png differ diff --git a/docs/development_guide_en/source/get_started/img/pic9.png b/docs/development_guide_en/source/get_started/img/pic9.png new file mode 100644 index 00000000..28e7756c Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/pic9.png differ diff --git a/docs/development_guide_en/source/get_started/img/pic99.png b/docs/development_guide_en/source/get_started/img/pic99.png new file mode 100644 index 00000000..400d0e1a Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/pic99.png differ diff --git a/docs/development_guide_en/source/get_started/img/sipeed_rv_debugger_1.png b/docs/development_guide_en/source/get_started/img/sipeed_rv_debugger_1.png new file mode 100644 index 00000000..a9a4fb14 Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/sipeed_rv_debugger_1.png differ diff --git a/docs/development_guide_en/source/get_started/img/sipeed_rv_debugger_2.png b/docs/development_guide_en/source/get_started/img/sipeed_rv_debugger_2.png new file mode 100644 index 00000000..b82fe2d1 Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/sipeed_rv_debugger_2.png differ diff --git a/docs/development_guide_en/source/get_started/img/sipeed_rv_debugger_3.png b/docs/development_guide_en/source/get_started/img/sipeed_rv_debugger_3.png new file mode 100644 index 00000000..4db6ab8c Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/sipeed_rv_debugger_3.png differ diff --git a/docs/development_guide_en/source/get_started/img/sipeed_rv_debugger_4.png b/docs/development_guide_en/source/get_started/img/sipeed_rv_debugger_4.png new file mode 100644 index 00000000..f971757a Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/sipeed_rv_debugger_4.png differ diff --git a/docs/development_guide_en/source/get_started/img/sipeed_rv_debugger_5.png b/docs/development_guide_en/source/get_started/img/sipeed_rv_debugger_5.png new file mode 100644 index 00000000..c929cc08 Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/sipeed_rv_debugger_5.png differ diff --git a/docs/development_guide_en/source/get_started/img/sipeed_rv_debugger_6.png b/docs/development_guide_en/source/get_started/img/sipeed_rv_debugger_6.png new file mode 100644 index 00000000..e3c5e69b Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/sipeed_rv_debugger_6.png differ diff --git a/docs/development_guide_en/source/get_started/img/sipeed_rv_debugger_7.png b/docs/development_guide_en/source/get_started/img/sipeed_rv_debugger_7.png new file mode 100644 index 00000000..d825504e Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/sipeed_rv_debugger_7.png differ diff --git a/docs/development_guide_en/source/get_started/img/sipeed_rv_debugger_8.png b/docs/development_guide_en/source/get_started/img/sipeed_rv_debugger_8.png new file mode 100644 index 00000000..09b85980 Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/sipeed_rv_debugger_8.png differ diff --git a/docs/development_guide_en/source/get_started/img/sipeed_rv_debugger_plus.png b/docs/development_guide_en/source/get_started/img/sipeed_rv_debugger_plus.png new file mode 100644 index 00000000..9e5345d7 Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/sipeed_rv_debugger_plus.png differ diff --git a/docs/development_guide_en/source/get_started/img/sw_arch.svg b/docs/development_guide_en/source/get_started/img/sw_arch.svg new file mode 100644 index 00000000..c04e3d29 --- /dev/null +++ b/docs/development_guide_en/source/get_started/img/sw_arch.svg @@ -0,0 +1,311 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + Application + STD + Hardware + HAL(Peripheral driver adaptation ) + HAL(Device driver management ) + Wireless + + + + BLE + Wifi + ZigBee + + diff --git a/docs/development_guide_en/source/get_started/img/uart_loop_sch.png b/docs/development_guide_en/source/get_started/img/uart_loop_sch.png new file mode 100644 index 00000000..e6bb7e45 Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/uart_loop_sch.png differ diff --git a/docs/development_guide_en/source/get_started/img/windows_cdk_logo.png b/docs/development_guide_en/source/get_started/img/windows_cdk_logo.png new file mode 100644 index 00000000..f98ab7fc Binary files /dev/null and b/docs/development_guide_en/source/get_started/img/windows_cdk_logo.png differ diff --git a/docs/development_guide_en/source/get_started/index.rst b/docs/development_guide_en/source/get_started/index.rst new file mode 100644 index 00000000..c611b940 --- /dev/null +++ b/docs/development_guide_en/source/get_started/index.rst @@ -0,0 +1,35 @@ + +.. _get_started_index: + +======================================= +Development environment setup guide +======================================= + +Before the formal development, please set up a suitable development environment. The specific steps are as follows: + +.. toctree:: + :hidden: + + Windows_CDK + Windows_eclipse + Linux + ++-------------------+--------------------+-------------------+ +| |cdk-logo| | |eclipse-logo| | |linux-logo| | ++-------------------+--------------------+-------------------+ +| `Windows_CDK`_ | `Windows_eclipse`_ | `Linux`_ | ++-------------------+--------------------+-------------------+ + +.. |cdk-logo| image:: img/windows_cdk_logo.png + :target: Windows_quick_start_cdk.html + +.. |eclipse-logo| image:: img/windows_eclipse_logo.png + :target: Windows_quick_start_eclipse.html + +.. |linux-logo| image:: img/Linux_logo.png + :target: Linux_quick_start_ubuntu.html + +.. _Windows_CDK: Windows_quick_start_cdk.html +.. _Windows_eclipse: Windows_quick_start_eclipse.html +.. _Linux: Linux_quick_start_ubuntu.html + diff --git a/docs/development_guide_en/source/index.rst b/docs/development_guide_en/source/index.rst new file mode 100644 index 00000000..ebf8b78c --- /dev/null +++ b/docs/development_guide_en/source/index.rst @@ -0,0 +1,69 @@ +.. bl_mcu_sdk_development_guide documentation master file, created by + sphinx-quickstart on Fri Mar 12 16:32:56 2021. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +======================================================== +BL MCU SDK development guide +======================================================== + +The `BL702 `_ series products are general-purpose microcontrollers based on "SiFive E24 Core" `RISC-V `_ , with network functions such as BLE 5.0, zigbee and Ethernet, as well as other rich peripherals. +It can be used in a wide range of `IoT `_ and other low-power applications. +Supports programming and debugging of the chip through `JTAG `_ , and also supports through `UART `_ programming. +BL MCU SDK will provide users with comprehensive support for BL70X series MCU development. + +.. toctree:: + :maxdepth: 1 + :caption: Quick Development Guide + :numbered: 3 + + get_started/get_started + get_started/connecting_hardware + get_started/index + get_started/cmake_quick_start + get_started/cdk_new_project_quick_start + get_started/bl_dev_cube + get_started/board + + + +.. toctree:: + :maxdepth: 1 + :caption: API Manuals + :numbered: + + api_reference/api_overview + api_reference/peripheral/index + #api_reference/shell/api_shell + #api_reference/usb stack/api_usb_stack + api_reference/bluetooth/api_ble + +.. toctree:: + :maxdepth: 1 + :caption: Basic Peripheral Samples + :numbered: + + samples/basic samples/gpio/index + samples/basic samples/uart/index + samples/basic samples/pwm/index + samples/basic samples/mtimer/index + samples/basic samples/dma/index + samples/basic samples/spi/index + samples/basic samples/i2c/index + #samples/basic samples/i2s/index + samples/basic samples/adc/index + samples/basic samples/timer/index + + +.. toctree:: + :maxdepth: 1 + :caption: Advance Samples + :numbered: + + samples/advance samples/shell_demo + samples/advance samples/fatfs_demo + #samples/advance samples/usb/index + samples/advance samples/lowpower_demo + samples/advance samples/boot2_iap_info + samples/advance samples/ble_scan_demo + diff --git a/docs/development_guide_en/source/samples/advance samples/ble_scan_demo.rst b/docs/development_guide_en/source/samples/advance samples/ble_scan_demo.rst new file mode 100644 index 00000000..c2ae45d8 --- /dev/null +++ b/docs/development_guide_en/source/samples/advance samples/ble_scan_demo.rst @@ -0,0 +1,199 @@ +BLE Client And Server Interconnection +======================================= + +This demo is based on **bl702** to demonstrate the connection and data sending and receiving of **ble server** and **ble client**. + +Prepare +----------------------- + +- Two bl702 boards or one bl702 board + mobile app + +Software Implementation +---------------------------- + +BLE client software Implementation +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- For the software code, see ``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); + } + } + +- In the ``bt_conn_cb_register`` function, register the ``callback`` function for successful connection and disconnection + +- In the ``ble_start_scan`` function, the device will start scanning + +- In the ``device_found`` function, the device uploads the scanned Bluetooth device, the code uses ``adv_name`` to find the Bluetooth device that needs to be connected, and initiate the connection + +.. 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); + } + } + +- After the connection is successful, in the ``ble_write_data_task`` function, the client sends the data in ``buf`` to the 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); + +- After the connection is successful, in the ``notify_func`` function, the client receives the data from the server, ``data`` is the data content, ``length`` is the data length + +BLE server software implementation +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- See ``examples/ble/ble_peripheral`` for the software code + +.. 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); + } + +- In the ``ble_start_adv`` function, ``adv_name`` sets the name of the broadcast device, and the device starts to broadcast + +.. 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); + +-After the connection is successful, in ``ble_tp_recv_wr``, the server receives the data from the client, ``buf`` is the data content, ``len`` is the data length + +.. 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(¬ify_poll_sem); + while(1) + { + k_sem_take(¬ify_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); + + } + } + +- After the connection is successful, in the ``ble_tp_notify_task`` function, the server sends the data in ``data`` to the client. + +Compile and program +----------------------------- + +- **CDK tool compilation** + + Not currently supported + +- **Command compilation** + +.. code-block:: bash + :linenos: + + $ cd /bl_mcu_sdk + $ make BOARD=bl706_iot APP=ble_peripheral SUPPORT_FREERTOS=y SUPPORT_FLOAT=y SUPPORT_BLE=y + +.. code-block:: bash + :linenos: + + $ cd /bl_mcu_sdk + $ make BOARD=bl706_iot APP=ble_central SUPPORT_FREERTOS=y SUPPORT_FLOAT=y SUPPORT_BLE=y + + +- **Program** + + See :ref:`bl_dev_cube` + +Experimental phenomena +----------------------------- + +- **Two bl702 connections** + +.. figure:: img/ble_client.png + :alt: + +.. figure:: img/ble_server.png + :alt: + + +- **Mobile phone connect bl702** + +.. figure:: img/phone_connect.jpg + :alt: + +- The connection is successful, as shown in the figure below + +.. figure:: img/phone_connected.png + :alt: + +- Steps to send and receive data + + - Click ``1`` ``Unknow Service`` to display specific service properties + + - Click ``2`` to turn on ``Notification``, allowing the server to send data to the client + + - Click ``3`` where the client sends data to the server, fill in the data you want to send, and click the ``SEND`` button + + +.. figure:: img/ble_data.png + :alt: + +.. figure:: img/receive_data.png + :alt: + +.. figure:: img/write_data.jpg + :alt: + + + diff --git a/docs/development_guide_en/source/samples/advance samples/boot2_iap_info.rst b/docs/development_guide_en/source/samples/advance samples/boot2_iap_info.rst new file mode 100644 index 00000000..d4f65217 --- /dev/null +++ b/docs/development_guide_en/source/samples/advance samples/boot2_iap_info.rst @@ -0,0 +1,23 @@ +BOOT2 IAP +============================ + +IAP (In Application Programming) is to program some areas of User Flash during the running of the user program. The purpose is to update the firmware program in the product through the reserved communication port after the product is released. + +If you need to realize the IAP function, that is, it will be automatically updated when the user program is running. Need to write two project codes when designing the firmware program. The first project program does not perform normal functional operations, but only receives programs or data through some communication channel (such as USB, USART) to update the second part of the code, and the second project code is the real function Code. + +Bouffalo Lab provides the boot2_iap.bin file and releases it simultaneously with the Dev Cube software package. Users can use Dev Cube to program boot2_iap.bin into the target board. After programming once, the user code can be updated online through the IAP function. + +bl_mcu_sdk contains the source code of boot2_iap, users can check the code in examples/boot2_iap, and complete the compilation and programming. For the compilation and programming process, please refer to the introduction of "Quick Development Guide". + +Prepare +----------------------- + +- The latest version of Dev Cube +- Bl706 +- TTL-USB + + +Experimental phenomena +----------------------------- + +For the specific steps of using Dev Cube to complete the IAP function, please refer to `DevCube User Manual `_ "IAP Program Download". diff --git a/docs/development_guide_en/source/samples/advance samples/fatfs_demo.rst b/docs/development_guide_en/source/samples/advance samples/fatfs_demo.rst new file mode 100644 index 00000000..1d8dbd3a --- /dev/null +++ b/docs/development_guide_en/source/samples/advance samples/fatfs_demo.rst @@ -0,0 +1,2 @@ +FATFS Read And Write +======================= diff --git a/docs/development_guide_en/source/samples/advance samples/img/ble_client.png b/docs/development_guide_en/source/samples/advance samples/img/ble_client.png new file mode 100644 index 00000000..df9f9a00 Binary files /dev/null and b/docs/development_guide_en/source/samples/advance samples/img/ble_client.png differ diff --git a/docs/development_guide_en/source/samples/advance samples/img/ble_data.png b/docs/development_guide_en/source/samples/advance samples/img/ble_data.png new file mode 100644 index 00000000..c9c50a6e Binary files /dev/null and b/docs/development_guide_en/source/samples/advance samples/img/ble_data.png differ diff --git a/docs/development_guide_en/source/samples/advance samples/img/ble_server.png b/docs/development_guide_en/source/samples/advance samples/img/ble_server.png new file mode 100644 index 00000000..84cb9790 Binary files /dev/null and b/docs/development_guide_en/source/samples/advance samples/img/ble_server.png differ diff --git a/docs/development_guide_en/source/samples/advance samples/img/lowpower_arch.png b/docs/development_guide_en/source/samples/advance samples/img/lowpower_arch.png new file mode 100644 index 00000000..48477c99 Binary files /dev/null and b/docs/development_guide_en/source/samples/advance samples/img/lowpower_arch.png differ diff --git a/docs/development_guide_en/source/samples/advance samples/img/phone_connect.jpg b/docs/development_guide_en/source/samples/advance samples/img/phone_connect.jpg new file mode 100644 index 00000000..198aa627 Binary files /dev/null and b/docs/development_guide_en/source/samples/advance samples/img/phone_connect.jpg differ diff --git a/docs/development_guide_en/source/samples/advance samples/img/phone_connected.png b/docs/development_guide_en/source/samples/advance samples/img/phone_connected.png new file mode 100644 index 00000000..a76d6668 Binary files /dev/null and b/docs/development_guide_en/source/samples/advance samples/img/phone_connected.png differ diff --git a/docs/development_guide_en/source/samples/advance samples/img/powerTable.png b/docs/development_guide_en/source/samples/advance samples/img/powerTable.png new file mode 100644 index 00000000..0fe2faa6 Binary files /dev/null and b/docs/development_guide_en/source/samples/advance samples/img/powerTable.png differ diff --git a/docs/development_guide_en/source/samples/advance samples/img/receive_data.png b/docs/development_guide_en/source/samples/advance samples/img/receive_data.png new file mode 100644 index 00000000..1194d576 Binary files /dev/null and b/docs/development_guide_en/source/samples/advance samples/img/receive_data.png differ diff --git a/docs/development_guide_en/source/samples/advance samples/img/shell_demo.gif b/docs/development_guide_en/source/samples/advance samples/img/shell_demo.gif new file mode 100644 index 00000000..7cbd5138 Binary files /dev/null and b/docs/development_guide_en/source/samples/advance samples/img/shell_demo.gif differ diff --git a/docs/development_guide_en/source/samples/advance samples/img/write_data.jpg b/docs/development_guide_en/source/samples/advance samples/img/write_data.jpg new file mode 100644 index 00000000..dffeb6f6 Binary files /dev/null and b/docs/development_guide_en/source/samples/advance samples/img/write_data.jpg differ diff --git a/docs/development_guide_en/source/samples/advance samples/img/xShell_lowpower.png b/docs/development_guide_en/source/samples/advance samples/img/xShell_lowpower.png new file mode 100644 index 00000000..5a16356f Binary files /dev/null and b/docs/development_guide_en/source/samples/advance samples/img/xShell_lowpower.png differ diff --git a/docs/development_guide_en/source/samples/advance samples/lowpower_demo.rst b/docs/development_guide_en/source/samples/advance samples/lowpower_demo.rst new file mode 100644 index 00000000..497df8a3 --- /dev/null +++ b/docs/development_guide_en/source/samples/advance samples/lowpower_demo.rst @@ -0,0 +1,93 @@ +LowPower Evaluation +========================= + +Introduction +------------------------ +BL series chips have rich low-power features to adapt to different low-power applications. In order to facilitate users to quickly evaluate and use the low-power performance of bl series MCUs, bl_mcu_sdk provides a set of low-power interfaces. The low-power levels are divided into four levels. + +1. Running: The power consumption when the CPU is running normally, and the power consumption is determined by the function executed by the customer application code. + +2. WFI: WFI mode, the clock of the CPU is in the Gating state, the CPU stops running, and the program will continue to run when the user exits the WFI mode. + +3. PDS: In PDS mode, most power domains on the chip are turned off, and the CPU is turned off at the same time. RAMs such as ITCM and DTCM in the same power domain as the CPU cannot be used. Only 64K OCTAM can save data. The internal RTC can be used to wake up, or use GPIO pins (when the GPIO power domain is not turned off) to wake up. + +4. HBN: HBN mode, shuts down most of the power domains on the chip, shuts down the CPU and 64K OCRAM, only 4K RAM in the AON domain can save data. The internal RTC can be used to wake up, or a specific wake-up pin (pin located in the AON domain) can be used to wake up. + + +bl_mcu_sdk provides a simple low-power reference example (bl_mcu_sdk examples/power/lowpower_test/) to help users quickly evaluate low-power features. If you need to further adapt to your own low-power scenarios and adopt different low-power methods, please refer to the relevant datasheet or seek technical support from Boufflao Lab. +In this example, the clock selection of peripherals and CPU are both crystal oscillator 32M. The power consumption measurement results based on this example are shown in the following table: + + +------------+---------------------+------------+------------------------------+-----------------------------------------------------------+ + |Mode |Reference current |Basic mode |Wake-up source |Remark | + +============+=====================+============+==============================+===========================================================+ + |Running |5.68 mA |Run | |All peripheral clocks are turned on | + +------------+---------------------+------------+------------------------------+-----------------------------------------------------------+ + |WFI |3.14 mA |WFI |Any interruption |Except the serial port, other peripheral clocks are closed | + +------------+---------------------+------------+------------------------------+-----------------------------------------------------------+ + |PDS |10 uA |PDS 31 |Internal RTC/pin interrupt |64K OCRAM to save data | + +------------+---------------------+------------+------------------------------+-----------------------------------------------------------+ + |HBN |1 uA |HBN 1 |Internal RTC/pin interrupt |4K AON RAM to save data | + +------------+---------------------+------------+------------------------------+-----------------------------------------------------------+ + + +The reference current in the above table is obtained through the sample firmware test. The definition of four levels of "run" " wfi" "pds" "hbn" simplifies the original setting of hbn level and pds level. + +See bl702_bl704_bl706_DS_EN_Combo_1.9.pdf page 28 + +.. figure:: img/powerTable.png + + +**Low power consumption example test method** +------------------------------------------------- + +**Compile low-power sample code** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Write ``make APP=lowpower_test SUPPORT_SHELL=y BOARD=bl706_lp`` in the project directory to complete the compilation of the low power consumption example bl706, or use the CDK project directly to complete the compilation and download. +You can refer to this document "Quick Development Guide" to get more information about compiling and programming. + +When the compilation and programming are successful, connect the serial port to the computer and reset the chip, Xshell will display the page as shown in the figure below. + +.. figure:: img/xShell_lowpower.png + + +**Prepare the hardware environment required for low-power testing** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- It is possible to connect the ammeter and the circuit board of the power supply side in series +- Ammeter +- PC (running Windows or Linux system) +- TTL to USB + +As shown in the figure below, connect the ammeter in series into the power supply circuit of the bl706 module, and issue different low-power commands through the serial debugging assistant software on the PC side, so that the bl706 enters the corresponding low-power mode. +Observe the indicated current value and complete the evaluation. + +.. figure:: img/lowpower_arch.png + +**Use Xshell to start evaluating low-power performance** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +The user can enter the corresponding low power consumption mode by entering the following commands in Xshell. + +``run`` + +- After resetting the chip, it enters the run mode by default without entering any low power consumption mode. The chip is actually running the while(1); statement. + +``wfi`` + + +- Enter wfi mode without adding any parameters. After entering, the CPU is in clock gating state to reduce power consumption +- After entering wfi mode, any interrupt will wake up, such as uart interrupt. Pressing Enter in Xshell will trigger the BL706 UART RX interrupt, so the wfi low power consumption mode can be awakened by this method. + +``pds sleeptime`` + + +- pds can choose to take the parameter "sleeptime" to determine its internal RTC wake-up time. If the command does not carry this parameter, the RTC internal wake-up is not used by default. The current firmware only supports power-on reset wake-up. +- If the instruction contains the sleeptime parameter, pds will be awakened at the moment of ``sleeptime * clock_period``, which will behave as resetting the chip and reprinting the initial message. +- After entering the low-power mode, the RTC clock is 32K, so when the sleeptime is 32768, it appears to wake up after a second of sleep. + +``hbn sleeptime`` + + +- hbn can choose to take the parameter "sleeptime" to determine its internal RTC wake-up time. If the command does not carry this parameter, the RTC internal wake-up is not used by default. The current firmware only supports power-on reset wake-up. +- If the instruction contains the sleeptime parameter, hbn will be awakened at the moment of ``sleeptime * clock_period``, which will behave as resetting the chip and printing the start message again. +- After entering the low-power mode, the RTC clock is 32K, so when the sleeptime is 32768, it appears to wake up after a second of sleep. \ No newline at end of file diff --git a/docs/development_guide_en/source/samples/advance samples/shell_demo.rst b/docs/development_guide_en/source/samples/advance samples/shell_demo.rst new file mode 100644 index 00000000..ac64453e --- /dev/null +++ b/docs/development_guide_en/source/samples/advance samples/shell_demo.rst @@ -0,0 +1,217 @@ +SHELL Command Debugging +========================= + +In order to facilitate the user to use the pc or other controllers to debug the functions of the development board (non-emulator debugging), we provide users with a shell command component, which is similar to the command operation under linux. The user sends commands on the PC or other control terminals, and sends the data to the shell of the development board through serial port, usb, Ethernet, Bluetooth, wifi, etc. The shell will read the received commands for analysis and scan the registered internal functions. After scanning the matching function, execute the matching function, and return the incoming key value and the result of the function execution to the pc or control terminal in real time . It should be noted that the controller side needs to send the key value of the standard keyboard. +This demo will demonstrate how to use **shell** to debug commands through the serial port. + +This shell component has the following functions: + +- Support standard keyboard character control +- Support command auto completion +- Support up and down keys to view historical commands +- Support left and right keys to modify commands +- Support file system and network system debugging + +Prepare +----------------------- + +- PC control terminal uses serial terminal software: xshell or mobaxterm +- Connection medium: usb to serial port or network or usb + +Hardware Connection +----------------------------- + +This demo is based on BL706_IOT and the connection method is as follows + +:: + + GPIO function GPIO pin + ---------------------------------- + UART0_TX <--> GPIO14 + UART0_RX <--> GPIO15 + + +Software Implementation +-------------------------- + +Shell porting to serial port +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- See ``examples/shell`` for the software code + +.. code-block:: C + :linenos: + + #define BSP_UART_CLOCK_SOURCE ROOT_CLOCK_SOURCE_PLL_96M + #define BSP_UART_CLOCK_DIV 0 + +- Configure the ``UART`` device clock source, see ``bsp/board/bl706_iot/clock_config.h`` + +.. code-block:: C + :linenos: + + #define CONFIG_GPIO14_FUNC GPIO_FUN_UART0_TX + #define CONFIG_GPIO15_FUNC GPIO_FUN_UART0_RX + +- Configure ``UART`` device multiplexing pins, see ``bsp/board/bl706_iot/pinmux_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 + +- Enable ``BSP_USING_UART0`` and configure ``UART`` device configuration, see ``bsp/board/bl706_iot/peripheral_config.h`` + +.. code-block:: C + :linenos: + + bflb_platform_init(); + +- In the ``bflb_platform_init`` function, we have registered and opened a serial port device for debugging, to provide users with a basic function of ``MSG`` for printing out messages. The specific implementation is as follows + +.. 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, NULL); + device_control(uart, DEVICE_CTRL_CLR_INT, (void *)(UART_RX_FIFO_IT)); + } + +- First call the ``uart_register`` function to register the ``UART`` device, currently register ``UART0`` +- Then use the ``find`` function to find the handle corresponding to the device and save it in the ``uart`` handle +- Finally use ``device_open`` to open the ``uart`` device with polling sending and interrupt receiving, the interrupt is closed by default and the receiving interrupt callback function is not registered + + +.. code-block:: C + :linenos: + + struct device *uart = device_find("debug_log"); + if (uart) { + device_set_callback(uart, shell_irq_callback); + device_control(uart, DEVICE_CTRL_SET_INT, (void *)(UART_RX_FIFO_IT)); + } + +- Register the receive interrupt service function for ``UART0`` through the ``device_set_callback`` function. Open the ``UART_RX_FIFO_IT`` interrupt via the ``device_control`` function + +.. code-block:: C + :linenos: + + void shell_irq_callback(struct device *dev, void *args, uint32_t size, uint32_t state) + { + uint8_t data; + if (state == UART_EVENT_RX_FIFO) { + data = *(uint8_t *)args; + shell_handler(data); + } + } + +-In the interrupt callback function, judge whether the ``state`` is ``UART_EVENT_RX_FIFO``, and if it is, pass the received byte to the ``shell_handler`` function. + +.. code-block:: C + :linenos: + + shell_init(); + +- Call ``shell_init`` to initialize the shell components. + + +SHELL Command Registration +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Shell command registration uses the following two macros + +.. code-block:: C + :linenos: + + void hellowd() + { + MSG("hello World\r\n"); + } + + int echo(int argc, char *argv[]) + { + MSG("%dparameter(s)\r\n", argc); + + for (uint8_t i = 1; i < argc; i++) { + MSG("%s\r\n", argv[i]); + } + + return 0; + } + + SHELL_CMD_EXPORT(hellowd, hellowd test) + SHELL_CMD_EXPORT(echo, echo test) + +.. code-block:: C + :linenos: + + void hellowd() + { + MSG("hello World\r\n"); + } + + int cmd_echo(int argc, char *argv[]) + { + MSG("%dparameter(s)\r\n", argc); + + for (uint8_t i = 1; i < argc; i++) { + MSG("%s\r\n", argv[i]); + } + + return 0; + } + + SHELL_CMD_EXPORT_ALIAS(hellowd, hellwd,hellowd test) + SHELL_CMD_EXPORT_ALIAS(cmd_echo, echo,echo test) + + + +Compile and Program +----------------------------- + +- **CDK compile** + + Open project:shell.cdkproj + + Refer to the steps of :ref:`windows_cdk_quick_start` to compile and download + +- **Command compilation** + +.. code-block:: bash + :linenos: + + $ cd /bl_mcu_sdk + $ make BOARD=bl706_iot APP=shell SUPPORT_SHELL=y + +- **Program** + + See :ref:`bl_dev_cube` + + +Experimental Phenomena +----------------------------- + +.. figure:: img/shell_demo.gif + :alt: + +shell test + diff --git a/docs/development_guide_en/source/samples/basic samples/adc/adc_key_demo.rst b/docs/development_guide_en/source/samples/basic samples/adc/adc_key_demo.rst new file mode 100644 index 00000000..8103d0c1 --- /dev/null +++ b/docs/development_guide_en/source/samples/basic samples/adc/adc_key_demo.rst @@ -0,0 +1,150 @@ +ADC - Key Detection Voltage +============================== + +This demo mainly introduces the key functions of the ADC. The ADC is used to detect the voltage value of the key input pin and judge whether the corresponding key is pressed according to different voltage divisions. + +Hardware Connection +----------------------------- +This demo is based on BL706_AVB: + +:: + + GPIO function GPIO pin + ---------------------------------- + ADC CH8 <--> GPIO18 + +**Voltage divider circuit:** + +.. figure:: img/adc_key_demo.png + :alt: + + adc key + +Software Implementation +----------------------------- + +- For the code see ``examples/adc/adc_key`` + +.. code-block:: C + :linenos: + + #define BSP_ADC_CLOCK_SOURCE ROOT_CLOCK_SOURCE_XCLK + #define BSP_ADC_CLOCK_DIV 0 + +- Configure the ``ADC`` device clock source, see ``bsp/board/bl706_avb/clock_config.h`` + +.. code-block:: C + :linenos: + + #define CONFIG_GPIO18_FUNC GPIO_FUN_ADC + +- Configure ``ADC`` device multiplexing pins, see ``bsp/board/bl706_avb/pinmux_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 + +- Enable ``BSP_USING_ADC0`` and configure the ``ADC`` device, see ``bsp/board/bl706_iot/peripheral_config.h`` + +.. 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); + +- First call the ``adc_register`` function to register the ``adc_key`` device, which is currently registered as ADC0 +- Then use the ``find`` function to find the handle corresponding to the device and save it in the ``adc_key`` handle +- Then use ``device_open`` to open the ``adc_key`` device in polling mode, and call ``device_control`` to complete the ADC related configuration +- Finally call ``adc_channel_start`` to enable ADC conversion + +.. 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)); + } + +- Call ``device_read`` to read the ``adc_key`` device information and save it to the ``result_val`` structure +- Call the ``get_adc_key_value`` function to get the current key value and voltage value + + +Compile and Program +----------------------------- + +- **CDK compilation** + + Open project:adc_key.cdkproj + + Refer to the steps of :ref:`windows_cdk_quick_start` to compile and download + +- **Command compilation** + +.. code-block:: bash + :linenos: + + $ cd /bl_mcu_sdk + $ make BOARD=bl706_avb APP=adc_key + +- **Program** + + See :ref:`bl_dev_cube` + + +Experimental Phenomena +----------------------------- +In this experiment, pressing SW1 ~ SW5 on the board in turn will get different voltage values: + +- key 0: ~0V +- key 1: ~0.1V +- key 2: ~0.2V +- key 3: ~0.3V +- key 4: ~0.43V + +operation result: + +.. figure:: img/adc_key_result.png + + +Video display: + +.. raw:: html + + + diff --git a/docs/development_guide_en/source/samples/basic samples/adc/img/adc_key_demo.png b/docs/development_guide_en/source/samples/basic samples/adc/img/adc_key_demo.png new file mode 100644 index 00000000..5706aff6 Binary files /dev/null and b/docs/development_guide_en/source/samples/basic samples/adc/img/adc_key_demo.png differ diff --git a/docs/development_guide_en/source/samples/basic samples/adc/img/adc_key_result.png b/docs/development_guide_en/source/samples/basic samples/adc/img/adc_key_result.png new file mode 100644 index 00000000..0a4f5d7a Binary files /dev/null and b/docs/development_guide_en/source/samples/basic samples/adc/img/adc_key_result.png differ diff --git a/docs/development_guide_en/source/samples/basic samples/adc/index.rst b/docs/development_guide_en/source/samples/basic samples/adc/index.rst new file mode 100644 index 00000000..bbc00597 --- /dev/null +++ b/docs/development_guide_en/source/samples/basic samples/adc/index.rst @@ -0,0 +1,9 @@ +======================= +ADC +======================= + + +.. toctree:: + :maxdepth: 1 + + ADC - Key Detection Voltage \ No newline at end of file diff --git a/docs/development_guide_en/source/samples/basic samples/dma/dma_m2m_demo.rst b/docs/development_guide_en/source/samples/basic samples/dma/dma_m2m_demo.rst new file mode 100644 index 00000000..4b21fdc4 --- /dev/null +++ b/docs/development_guide_en/source/samples/basic samples/dma/dma_m2m_demo.rst @@ -0,0 +1,113 @@ +DMA - Data Transfer Between RAM +================================= + +This demo is based on the memory to memory mode of DMA for data transfer. + +Hardware Connection +----------------------------- +None + +Software Implementation +----------------------------- + +- For the code see ``examples/dma/dma_m2m`` + +.. 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 + +- Enable ``BSP_USING_DMA0_CH0`` and configure the ``DMA`` device, see ``bsp/board/bl706_iot/peripheral_config.h`` + +.. 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); + } + +- First call the ``dma_register`` function to register a channel of the ``DMA`` device, currently register ``DMA_CH0`` +- Then use the ``find`` function to find the handle corresponding to the device and save it in the ``dma`` handle +- Finally use ``device_open`` to open the ``dma`` device in the default mode, call ``device_set_callback`` to register a dma channel 0 interrupt callback function, and call ``device_control`` to open the dma transmission completion interrupt + +.. code-block:: C + :linenos: + + dma_reload(dma,(uint32_t)dma_src_buffer,(uint32_t)dma_dst_buffer,8000); + dma_channel_start(dma); + +- Call the ``dma_reload`` function to supplement the configuration of dma channel 0. A part of the configuration has been supplemented in ``DMA0_CH0_CONFIG``. Here we mainly supplement the source data address, destination data address and total transmission length +- Call ``dma_channel_start`` to start dma transmission + +.. 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"); + } + + } + +- Check whether the data transmission is correct in the interrupt function + +Compile and Program +----------------------------- + +- **CDK compilation** + + Open project:dma_m2m.cdkproj + + Refer to the steps of :ref:`windows_cdk_quick_start` to compile and download + +- **Command compilation** + +.. code-block:: bash + :linenos: + + $ cd /bl_mcu_sdk + $ make BOARD=bl706_iot APP=dma_m2m + +- **Program** + + 详见 :ref:`bl_dev_cube` + + +Experimental Phenomena +----------------------------- +The data in the ``dma_src_buffer`` array is transferred to the ``dma_dst_buffer`` array through DMA channel 0 with a source 32-bit width and a target 32-bit width. After the data transfer is completed, the serial port prints ``dma transfer success``. diff --git a/docs/development_guide_en/source/samples/basic samples/dma/index.rst b/docs/development_guide_en/source/samples/basic samples/dma/index.rst new file mode 100644 index 00000000..df41f443 --- /dev/null +++ b/docs/development_guide_en/source/samples/basic samples/dma/index.rst @@ -0,0 +1,9 @@ +======================= +DMA +======================= + + +.. toctree:: + :maxdepth: 1 + + DMA - Data Transfer Between RAM \ No newline at end of file diff --git a/docs/development_guide_en/source/samples/basic samples/gpio/blink_demo.rst b/docs/development_guide_en/source/samples/basic samples/gpio/blink_demo.rst new file mode 100644 index 00000000..bf4bf297 --- /dev/null +++ b/docs/development_guide_en/source/samples/basic samples/gpio/blink_demo.rst @@ -0,0 +1,75 @@ +GPIO output - Lamp LED +========================= + +This demo is based on the output mode of GPIO. + +Hardware Connection +----------------------------- + +This demo is based on BL706_IOT and the connection method is as follows + +:: + + GPIO function GPIO pin + ---------------------------------- + D0 <--> GPIO22 + D1 <--> GPIO29 + D2 <--> GPIO30 + D3 <--> GPIO31 + + +.. figure:: img/blink_breath_sch.png + :alt: + +Software Implementation +----------------------------- + +- See ``examples/gpio/gpio_blink`` for the software code + +.. 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); + +- Use the above code to configure ``GPIO22`` ``GPIO29`` ``GPIO30`` ``GPIO31`` to output pull-up mode. + +.. code-block:: C + :linenos: + + gpio_write(GPIO_PIN_22, 0); + +- Use the above code to modify the output level value. + +Compile and Program +----------------------------- + +- **CDK compilation** + + Open project:gpio_blink.cdkproj + + Refer to the steps of :ref:`windows_cdk_quick_start` to compile and download + +- **Command compilation** + +.. code-block:: bash + :linenos: + + $ cd /bl_mcu_sdk + $ make BOARD=bl706_iot APP=gpio_blink + +- **Program** + + See :ref:`bl_dev_cube` + + +Experimental Phenomena +----------------------------- + +Video display: + +.. raw:: html + + diff --git a/docs/development_guide_en/source/samples/basic samples/gpio/button_demo.rst b/docs/development_guide_en/source/samples/basic samples/gpio/button_demo.rst new file mode 100644 index 00000000..33e652f8 --- /dev/null +++ b/docs/development_guide_en/source/samples/basic samples/gpio/button_demo.rst @@ -0,0 +1,64 @@ +GPIO interrupt - Button detection +==================================== + +This demo is based on GPIO external interrupt mode. + +Hardware Connection +----------------------------- + +This demo is based on BL706_IOT, add the button circuit by yourself, the connection method is as follows + +:: + + GPIO function GPIO pin + ---------------------------------- + SW1 <--> GPIO11 + +.. figure:: img/button_sch.png + :alt: + +Software Implementation +----------------------------- + +- See ``examples/gpio/gpio_int`` for the software code + +.. 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); + +- Use the above code to configure ``GPIO11`` as the GPIO rising edge interrupt trigger mode, and register the interrupt callback function. + +Compile and Program +----------------------------- + +- **CDK compilation** + + Open project:gpio_int.cdkproj + + Refer to the steps of :ref:`windows_cdk_quick_start` to compile and download + +- **Command compilation** + +.. code-block:: bash + :linenos: + + $ cd /bl_mcu_sdk + $ make BOARD=bl706_iot APP=gpio_int + +- **Program** + + See :ref:`bl_dev_cube` + + +Experimental Phenomena +----------------------------- + +When the button is pressed, the serial port will print ``"gpio rising trigger !"`` \ No newline at end of file diff --git a/docs/development_guide_en/source/samples/basic samples/gpio/img/blink_breath_sch.png b/docs/development_guide_en/source/samples/basic samples/gpio/img/blink_breath_sch.png new file mode 100644 index 00000000..25786009 Binary files /dev/null and b/docs/development_guide_en/source/samples/basic samples/gpio/img/blink_breath_sch.png differ diff --git a/docs/development_guide_en/source/samples/basic samples/gpio/img/button_sch.png b/docs/development_guide_en/source/samples/basic samples/gpio/img/button_sch.png new file mode 100644 index 00000000..9ca54be0 Binary files /dev/null and b/docs/development_guide_en/source/samples/basic samples/gpio/img/button_sch.png differ diff --git a/docs/development_guide_en/source/samples/basic samples/gpio/index.rst b/docs/development_guide_en/source/samples/basic samples/gpio/index.rst new file mode 100644 index 00000000..12cc9281 --- /dev/null +++ b/docs/development_guide_en/source/samples/basic samples/gpio/index.rst @@ -0,0 +1,10 @@ +======================= +GPIO +======================= + + +.. toctree:: + :maxdepth: 1 + + GPIO output - Lamp LED + GPIO interrupt - Button Detection \ No newline at end of file diff --git a/docs/development_guide_en/source/samples/basic samples/i2c/i2c_eeprom_demo.rst b/docs/development_guide_en/source/samples/basic samples/i2c/i2c_eeprom_demo.rst new file mode 100644 index 00000000..cb7289e8 --- /dev/null +++ b/docs/development_guide_en/source/samples/basic samples/i2c/i2c_eeprom_demo.rst @@ -0,0 +1,116 @@ +I2C - AT24CXX read and write +================================ + +Hardware Connection +----------------------------- + +This demo is based on BL706_IOT, add AT24CXX circuit by yourself, the connection method is as follows + +:: + + GPIO function GPIO pin + ---------------------------------- + I2C_SCL <--> GPIO11 + I2C_SDA <--> GPIO16 + + +Software Implementation +----------------------------- + +- See ``examples/i2c/i2c_at24cxx`` for the software code + +.. code-block:: C + :linenos: + + #define BSP_I2C_CLOCK_SOURCE ROOT_CLOCK_SOURCE_BCLK + #define BSP_I2C_CLOCK_DIV 0 + +- Configure the ``I2C`` device clock source, see ``bsp/board/bl706_iot/clock_config.h`` + +.. code-block:: C + :linenos: + + #define CONFIG_GPIO11_FUNC GPIO_FUN_I2C + #define CONFIG_GPIO16_FUNC GPIO_FUN_I2C + +- Configure ``I2C`` device multiplexing pins, see ``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 + +- Enable ``BSP_USING_I2C0`` and configure ``I2C`` device, see ``bsp/board/bl706_iot/peripheral_config.h`` + +.. 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); + } + +- First call the ``i2c_register`` function to register the ``I2C`` device, currently register ``I2C0`` +- Then use the ``find`` function to find the handle corresponding to the device and save it in the ``i2c0`` handle +- Finally use ``device_open`` to open the ``I2C0`` device in the default mode + +.. 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]); + +- Call ``i2c_transfer`` to transfer two ``msg``, one ``msg`` represents writing 8-byte data to eeprom, and one ``msg`` represents reading 8-byte data from eeprom + +Compile and Program +----------------------------- + +- **CDK compilation** + + Open project:i2c_at24cxx.cdkproj + + Refer to the steps of :ref:`windows_cdk_quick_start` to compile and download + +- **Command compilation** + +.. code-block:: bash + :linenos: + + $ cd /bl_mcu_sdk + $ make BOARD=bl706_iot APP=i2c_at24cxx + +- **Program** + + See :ref:`bl_dev_cube` + +Experimental Phenomena +----------------------------- diff --git a/docs/development_guide_en/source/samples/basic samples/i2c/index.rst b/docs/development_guide_en/source/samples/basic samples/i2c/index.rst new file mode 100644 index 00000000..7c6cc8fe --- /dev/null +++ b/docs/development_guide_en/source/samples/basic samples/i2c/index.rst @@ -0,0 +1,9 @@ +======================= +I2C +======================= + + +.. toctree:: + :maxdepth: 1 + + I2C - AT24CXX Read And Write \ No newline at end of file diff --git a/docs/development_guide_en/source/samples/basic samples/mtimer/index.rst b/docs/development_guide_en/source/samples/basic samples/mtimer/index.rst new file mode 100644 index 00000000..6c2633d4 --- /dev/null +++ b/docs/development_guide_en/source/samples/basic samples/mtimer/index.rst @@ -0,0 +1,9 @@ +======================= +MTIMER +======================= + + +.. toctree:: + :maxdepth: 1 + + MTIMER - System Timer \ No newline at end of file diff --git a/docs/development_guide_en/source/samples/basic samples/mtimer/mtimer_demo.rst b/docs/development_guide_en/source/samples/basic samples/mtimer/mtimer_demo.rst new file mode 100644 index 00000000..938c8e9f --- /dev/null +++ b/docs/development_guide_en/source/samples/basic samples/mtimer/mtimer_demo.rst @@ -0,0 +1,56 @@ +MTIMER - System Timer +======================== + +This demo is based on a 64-bit timer (MTIMER) that comes with the risc-v kernel. This demo can provide reference for os tick. + +Hardware Connection +----------------------------- +None + +Software Implementation +----------------------------- + +- See ``examples/systick`` for the software code + +.. note:: + The ``mtimer`` clock defaults to 1M after frequency division, which is convenient for later use and reduces calculation time. + +.. 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); + +- Use the above code to set the mtimer timing time to 1s, and register the interrupt callback function. + +Compile and Program +----------------------------- + +- **CDK compilation** + + Open project:systick.cdkproj + + Refer to the steps of :ref:`windows_cdk_quick_start` to compile and download + +- **Command compilation** + +.. code-block:: bash + :linenos: + + $ cd /bl_mcu_sdk + $ make BOARD=bl706_iot APP=systick + +- **Program** + + See :ref:`bl_dev_cube` + +Experimental Phenomena +----------------------------- + +The ``tick`` value is incremented by 1 per second and printed through the serial port. diff --git a/docs/development_guide_en/source/samples/basic samples/pwm/img/blink_breath_sch.png b/docs/development_guide_en/source/samples/basic samples/pwm/img/blink_breath_sch.png new file mode 100644 index 00000000..25786009 Binary files /dev/null and b/docs/development_guide_en/source/samples/basic samples/pwm/img/blink_breath_sch.png differ diff --git a/docs/development_guide_en/source/samples/basic samples/pwm/img/pwm_demo.gif b/docs/development_guide_en/source/samples/basic samples/pwm/img/pwm_demo.gif new file mode 100644 index 00000000..88e2d694 Binary files /dev/null and b/docs/development_guide_en/source/samples/basic samples/pwm/img/pwm_demo.gif differ diff --git a/docs/development_guide_en/source/samples/basic samples/pwm/img/pwm_step_motor.gif b/docs/development_guide_en/source/samples/basic samples/pwm/img/pwm_step_motor.gif new file mode 100644 index 00000000..09a0cee7 Binary files /dev/null and b/docs/development_guide_en/source/samples/basic samples/pwm/img/pwm_step_motor.gif differ diff --git a/docs/development_guide_en/source/samples/basic samples/pwm/img/pwm_step_motor.png b/docs/development_guide_en/source/samples/basic samples/pwm/img/pwm_step_motor.png new file mode 100644 index 00000000..5d8faec1 Binary files /dev/null and b/docs/development_guide_en/source/samples/basic samples/pwm/img/pwm_step_motor.png differ diff --git a/docs/development_guide_en/source/samples/basic samples/pwm/img/pwm_step_motor1.png b/docs/development_guide_en/source/samples/basic samples/pwm/img/pwm_step_motor1.png new file mode 100644 index 00000000..3180f0b6 Binary files /dev/null and b/docs/development_guide_en/source/samples/basic samples/pwm/img/pwm_step_motor1.png differ diff --git a/docs/development_guide_en/source/samples/basic samples/pwm/img/pwm_step_motor2.png b/docs/development_guide_en/source/samples/basic samples/pwm/img/pwm_step_motor2.png new file mode 100644 index 00000000..775d5da5 Binary files /dev/null and b/docs/development_guide_en/source/samples/basic samples/pwm/img/pwm_step_motor2.png differ diff --git a/docs/development_guide_en/source/samples/basic samples/pwm/img/pwm_step_motor3.png b/docs/development_guide_en/source/samples/basic samples/pwm/img/pwm_step_motor3.png new file mode 100644 index 00000000..a2b8d8d2 Binary files /dev/null and b/docs/development_guide_en/source/samples/basic samples/pwm/img/pwm_step_motor3.png differ diff --git a/docs/development_guide_en/source/samples/basic samples/pwm/img/step_motor.png b/docs/development_guide_en/source/samples/basic samples/pwm/img/step_motor.png new file mode 100644 index 00000000..8281cf8c Binary files /dev/null and b/docs/development_guide_en/source/samples/basic samples/pwm/img/step_motor.png differ diff --git a/docs/development_guide_en/source/samples/basic samples/pwm/img/step_motor_info.png b/docs/development_guide_en/source/samples/basic samples/pwm/img/step_motor_info.png new file mode 100644 index 00000000..ce561ca6 Binary files /dev/null and b/docs/development_guide_en/source/samples/basic samples/pwm/img/step_motor_info.png differ diff --git a/docs/development_guide_en/source/samples/basic samples/pwm/img/uln2003.png b/docs/development_guide_en/source/samples/basic samples/pwm/img/uln2003.png new file mode 100644 index 00000000..7ef6a395 Binary files /dev/null and b/docs/development_guide_en/source/samples/basic samples/pwm/img/uln2003.png differ diff --git a/docs/development_guide_en/source/samples/basic samples/pwm/index.rst b/docs/development_guide_en/source/samples/basic samples/pwm/index.rst new file mode 100644 index 00000000..d1160140 --- /dev/null +++ b/docs/development_guide_en/source/samples/basic samples/pwm/index.rst @@ -0,0 +1,10 @@ +======================= +PWM +======================= + + +.. toctree:: + :maxdepth: 1 + + PWM - Breathing LED + PWM - Drive Stepper Motor \ No newline at end of file diff --git a/docs/development_guide_en/source/samples/basic samples/pwm/pwm_breath_demo.rst b/docs/development_guide_en/source/samples/basic samples/pwm/pwm_breath_demo.rst new file mode 100644 index 00000000..b532cdc7 --- /dev/null +++ b/docs/development_guide_en/source/samples/basic samples/pwm/pwm_breath_demo.rst @@ -0,0 +1,130 @@ +PWM - Breathing LED +========================= + + This demo is based on PWM polling mode. + +Hardware Connection +----------------------------- + +This demo is based on BL706_IOT, and the connection method is as follows + +:: + + GPIO function GPIO pin + ---------------------------------- + PWM_CH2 <--> GPIO22 + +.. figure:: img/blink_breath_sch.png + :alt: + +Software Implementation +----------------------------- + +-See ``examples/pwm/pwm_breath_led`` for the software code + +.. code-block:: C + :linenos: + + #define BSP_PWM_CLOCK_SOURCE ROOT_CLOCK_SOURCE_XCLK + #define BSP_PWM_CLOCK_DIV 1 + +- Configure the ``PWM`` device clock source, see ``bsp/board/bl706_iot/clock_config.h`` + +.. code-block:: C + :linenos: + + #define CONFIG_GPIO22_FUNC GPIO_FUN_PWM + +- Configure ``PWM`` device multiplexing pins, see ``bsp/board/bl706_iot/pinmux_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 + +- Enable ``BSP_USING_PWM_CH2`` and configure ``PWM`` device configuration, see ``bsp/board/bl706_iot/peripheral_config.h`` + +.. 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) { + PWM_DEV(led_breath)->period = 32; //frequence = 32M/1/32 = 1Mhz + PWM_DEV(led_breath)->threshold_low = 16; + PWM_DEV(led_breath)->threshold_high = 32; + device_open(led_breath, DEVICE_OFLAG_STREAM_TX); + pwm_channel_start(led_breath); + } + + +- First call the ``pwm_register`` function to register a channel of the ``PWM`` device, currently register ``PWM_CH2`` +- Then use the ``find`` function to find the handle corresponding to the device and save it in the ``led_breath`` handle +- Set the frequency of ``PWM_CH2`` to 1Mhz, and the duty cycle to 50% +- Use ``device_open`` to open the ``led_breath`` device in polling mode + +.. code-block:: C + :linenos: + + for (pwm_cfg.threshold_high = 0; pwm_cfg.threshold_high <= 32; pwm_cfg.threshold_high++) { + device_control(led_breath, DEIVCE_CTRL_PWM_DUTYCYCLE_CONFIG, &pwm_cfg); + bflb_platform_delay_ms(50); + } + + for (pwm_cfg.threshold_high = 32; 0 <= pwm_cfg.threshold_high && pwm_cfg.threshold_high <= 32; pwm_cfg.threshold_high--) { + device_control(led_breath, DEIVCE_CTRL_PWM_DUTYCYCLE_CONFIG, &pwm_cfg); + bflb_platform_delay_ms(50); + } + +- Use the ``device_contorl`` function with the ``DEIVCE_CTRL_PWM_DUTYCYCLE_CONFIG`` instruction to modify the duty cycle of the current PWM channel. + +Compile and Program +----------------------------- + +- **CDK compilation** + + Open project:pwm_breath_led.cdkproj + + Refer to the steps of :ref:`windows_cdk_quick_start` to compile and download + +- **Command compilation** + +.. code-block:: bash + :linenos: + + $ cd /bl_mcu_sdk + $ make BOARD=bl706_iot APP=pwm_breath_led + +- **Program** + + See :ref:`bl_dev_cube` + + +Experimental Phenomena +----------------------------- + + +.. figure:: img/pwm_demo.gif + :alt: + +pwm breath led! + +Video display: + +.. raw:: html + + diff --git a/docs/development_guide_en/source/samples/basic samples/pwm/pwm_step_motor.rst b/docs/development_guide_en/source/samples/basic samples/pwm/pwm_step_motor.rst new file mode 100644 index 00000000..356ce0ba --- /dev/null +++ b/docs/development_guide_en/source/samples/basic samples/pwm/pwm_step_motor.rst @@ -0,0 +1,281 @@ +PWM - 驱动步进电机 +==================== + +步进电机是一种将电脉冲转化为角位移的执行机构。当步进驱动器接收到一个脉冲信号,它就驱动步进电机按设定的方向转动一个固定的角度(及步进角)。可以通过控制脉冲个来控制角位移量,从而达到准确定位的目的;同时可以通过控制脉冲频率来控制电机转动的速度和加速度,从而达到调速的目的。 + +本 demo 采用步进电机 28BYJ48 型四相八拍电机,使用 ULN2003 芯片驱动,电压为 DC5V—DC12V。当对步进电机施加一系列连续不断的控制脉冲时,它可以连续不断地转动。每一个脉冲信号对应步进电机的某一相或两相绕组的通电状态改变一次,也就对应转子转过一定的角度(一个步距角)。当通电状态的改变完成一个循环时,转子转过一个齿距。 + +.. figure:: img/step_motor.png + :alt: + + 28BYJ48 + +.. figure:: img/uln2003.png + :alt: + + ULN2003 + +这个步进电机内部有个真正的步进马达转子,每一个脉冲能使这个真正的转子转动5.625°,看下图的数据表格中的减速比是1:64,意思是这个真正的步进马达转子转动64周才能让输出轴转动1周,因此下图的表格中步距角度才写的是5.625°/64,表明的意思是一个脉冲可以让输出轴转动5.625°/64的角度。所以要让马达转一周(360°), 则需要360/5.625*64=4096个脉冲。 +脉冲(或拍)的数量决定转动的角度,单位时间内脉冲(或拍)的数量决定转动的速度 + +.. figure:: img/step_motor_info.png + :alt: + +四相步进电机可以在不同的通电方式下运行,常见的通电方式有如下三种: + +- 一相励磁:单(单相绕组通电)四拍(A+,B+,A-,B-......) + +.. figure:: img/pwm_step_motor1.png + :alt: + +- 二相励磁:双(双相绕组通电)四拍(A+B+,B+A-,A-B-,B-A+......) + +.. figure:: img/pwm_step_motor2.png + :alt: + +- 一二相励磁:八拍(A+B+,B+,B+A-,A-,A-B-,B-,B-A+,A+......) + +.. figure:: img/pwm_step_motor3.png + :alt: + + +硬件连接 +----------------------------- + +本 demo 基于BL706_IOT开发板,连接方式如下 + +:: + + GPIO function GPIO pin + ---------------------------------- + PWM_CH0 <--> GPIO10 + PWM_CH1 <--> GPIO11 + PWM_CH2 <--> GPIO12 + PWM_CH3 <--> GPIO3 + +.. figure:: img/pwm_step_motor.png + :alt: + + 参考电路 + +软件实现 +----------------------------- + +- 软件代码见 ``examples/pwm/pwm_step_motor`` + +.. code-block:: C + :linenos: + + #define BSP_PWM_CLOCK_SOURCE ROOT_CLOCK_SOURCE_RC_32K + #define BSP_PWM_CLOCK_DIV 32 + +- 配置 ``PWM`` 设备时钟源,见 ``bsp/board/bl706_iot/clock_config.h`` + +.. code-block:: C + :linenos: + + #define CONFIG_GPIO3_FUNC GPIO_FUN_PWM + #define CONFIG_GPIO10_FUNC GPIO_FUN_PWM + #define CONFIG_GPIO11_FUNC GPIO_FUN_PWM + #define CONFIG_GPIO12_FUNC GPIO_FUN_PWM + +- 配置 ``PWM`` 设备复用引脚,见 ``bsp/board/bl706_iot/pinmux_config.h`` + +.. code-block:: C + :linenos: + + #define BSP_USING_PWM_CH0 + #define BSP_USING_PWM_CH1 + #define BSP_USING_PWM_CH2 + #define BSP_USING_PWM_CH3 + + #if defined(BSP_USING_PWM_CH0) + #ifndef PWM_CH0_CONFIG + #define PWM_CH0_CONFIG \ + { \ + .ch = 0, \ + .polarity_invert_mode = DISABLE, \ + .period = 0, \ + .threshold_low = 0, \ + .threshold_high = 0, \ + .it_pulse_count = 0, \ + } + #endif + #endif + + #if defined(BSP_USING_PWM_CH1) + #ifndef PWM_CH1_CONFIG + #define PWM_CH1_CONFIG \ + { \ + .ch = 1, \ + .polarity_invert_mode = DISABLE, \ + .period = 0, \ + .threshold_low = 0, \ + .threshold_high = 0, \ + .it_pulse_count = 0, \ + } + #endif + #endif + + #if defined(BSP_USING_PWM_CH2) + #ifndef PWM_CH2_CONFIG + #define PWM_CH2_CONFIG \ + { \ + .ch = 2, \ + .polarity_invert_mode = DISABLE, \ + .period = 0, \ + .threshold_low = 0, \ + .threshold_high = 0, \ + .it_pulse_count = 0, \ + } + #endif + #endif + + #if defined(BSP_USING_PWM_CH3) + #ifndef PWM_CH3_CONFIG + #define PWM_CH3_CONFIG \ + { \ + .ch = 3, \ + .polarity_invert_mode = DISABLE, \ + .period = 0, \ + .threshold_low = 0, \ + .threshold_high = 0, \ + .it_pulse_count = 0, \ + } + #endif + #endif + + +- 使能 ``BSP_USING_PWM_CH0``, ``BSP_USING_PWM_CH1`` , ``BSP_USING_PWM_CH2``, ``BSP_USING_PWM_CH3`` 并配置 ``PWM`` 设备配置,见 ``bsp/board/bl706_iot/peripheral_config.h`` + +.. code-block:: C + :linenos: + + pwm_register(PWM_CH0_INDEX, "motor_ch0", DEVICE_OFLAG_RDWR); + pwm_register(PWM_CH1_INDEX, "motor_ch1", DEVICE_OFLAG_RDWR); + pwm_register(PWM_CH2_INDEX, "motor_ch2", DEVICE_OFLAG_RDWR); + pwm_register(PWM_CH3_INDEX, "motor_ch3", DEVICE_OFLAG_RDWR); + + motor_ch0 = device_find("motor_ch0"); + motor_ch1 = device_find("motor_ch1"); + motor_ch2 = device_find("motor_ch2"); + motor_ch3 = device_find("motor_ch3"); + + if (motor_ch0) { + PWM_DEV(motor_ch0)->period = 8; //frequence = 32K/160/8 = 25hz + PWM_DEV(motor_ch0)->threshold_low = 2; + PWM_DEV(motor_ch0)->threshold_high = 7; + PWM_DEV(motor_ch0)->polarity_invert_mode = ENABLE; + device_open(motor_ch0, DEVICE_OFLAG_STREAM_TX); + } + if (motor_ch1) { + PWM_DEV(motor_ch1)->period = 8; //frequence = 32K/160/8 = 25hz + PWM_DEV(motor_ch1)->threshold_low = 1; + PWM_DEV(motor_ch1)->threshold_high = 4; + device_open(motor_ch1, DEVICE_OFLAG_STREAM_TX); + } + if (motor_ch2) { + PWM_DEV(motor_ch2)->period = 8; //frequence = 32K/160/8 = 25hz + PWM_DEV(motor_ch2)->threshold_low = 3; + PWM_DEV(motor_ch2)->threshold_high = 6; + device_open(motor_ch2, DEVICE_OFLAG_STREAM_TX); + } + if (motor_ch3) { + PWM_DEV(motor_ch3)->period = 8; //frequence = 32K/160/8 = 25hz + PWM_DEV(motor_ch3)->threshold_low = 5; + PWM_DEV(motor_ch3)->threshold_high = 8; + device_open(motor_ch3, DEVICE_OFLAG_STREAM_TX); + } + pwm_channel_start(motor_ch0); + pwm_channel_start(motor_ch1); + pwm_channel_start(motor_ch2); + pwm_channel_start(motor_ch3); + + +- 首先调用 ``pwm_register`` 函数注册 ``PWM`` 设备的一个通道,当前注册 PWM 通道0/1/2/3 +- 然后通过 ``find`` 函数找到设备对应的句柄,保存于4个句柄中 +- 设置 4个通道 的频率为 125hz,占空比为37.5% +- 使用 ``device_open`` 以轮询模式来打开 4个通道 + +.. code-block:: C + :linenos: + + enum motor_dir_type { + CW, + CCW, + STOP + }; + + void motor_set_dir(enum motor_dir_type dir) + { + pwm_dutycycle_config_t pwm_cfg[4]; + + if (dir == CW) { + pwm_cfg[0].threshold_low = 2; + pwm_cfg[0].threshold_high = 7; + pwm_cfg[1].threshold_low = 1; + pwm_cfg[1].threshold_high = 4; + pwm_cfg[2].threshold_low = 3; + pwm_cfg[2].threshold_high = 6; + pwm_cfg[3].threshold_low = 5; + pwm_cfg[3].threshold_high = 8; + } + + else if (dir == CCW) { + pwm_cfg[0].threshold_low = 2; + pwm_cfg[0].threshold_high = 7; + pwm_cfg[1].threshold_low = 5; + pwm_cfg[1].threshold_high = 8; + pwm_cfg[2].threshold_low = 3; + pwm_cfg[2].threshold_high = 6; + pwm_cfg[3].threshold_low = 1; + pwm_cfg[3].threshold_high = 4; + } else if (dir == STOP) { + pwm_cfg[0].threshold_low = 0; + pwm_cfg[0].threshold_high = 0; + pwm_cfg[1].threshold_low = 0; + pwm_cfg[1].threshold_high = 0; + pwm_cfg[2].threshold_low = 0; + pwm_cfg[2].threshold_high = 0; + pwm_cfg[3].threshold_low = 0; + pwm_cfg[3].threshold_high = 0; + } + device_control(motor_ch0, DEIVCE_CTRL_PWM_DUTYCYCLE_CONFIG, &pwm_cfg[0]); + device_control(motor_ch1, DEIVCE_CTRL_PWM_DUTYCYCLE_CONFIG, &pwm_cfg[1]); + device_control(motor_ch2, DEIVCE_CTRL_PWM_DUTYCYCLE_CONFIG, &pwm_cfg[2]); + device_control(motor_ch3, DEIVCE_CTRL_PWM_DUTYCYCLE_CONFIG, &pwm_cfg[3]); + } + +- 使用 ``device_contorl`` 函数,配合 ``DEIVCE_CTRL_PWM_DUTYCYCLE_CONFIG`` 指令,修改4个 PWM 通道的的高低阈值。 + +.. note:: 该函数的功能主要用于切换步进电机的方向 + +编译和烧录 +----------------------------- + +- **CDK 编译** + + 打开项目中提供的工程文件:pwm_step_motor.cdkproj + + 参照 :ref:`windows_cdk_quick_start` 的步骤编译下载即可 + +- **命令行编译** + +.. code-block:: bash + :linenos: + + $ cd /bl_mcu_sdk + $ make BOARD=bl706_iot APP=pwm_step_motor + +- **烧录** + + 详见 :ref:`bl_dev_cube` + + +实验现象 +----------------------------- + +.. figure:: img/pwm_step_motor.gif + :alt: + + diff --git a/docs/development_guide_en/source/samples/basic samples/spi/img/spi_lcd.png b/docs/development_guide_en/source/samples/basic samples/spi/img/spi_lcd.png new file mode 100644 index 00000000..0feaac4b Binary files /dev/null and b/docs/development_guide_en/source/samples/basic samples/spi/img/spi_lcd.png differ diff --git a/docs/development_guide_en/source/samples/basic samples/spi/index.rst b/docs/development_guide_en/source/samples/basic samples/spi/index.rst new file mode 100644 index 00000000..a2786d8d --- /dev/null +++ b/docs/development_guide_en/source/samples/basic samples/spi/index.rst @@ -0,0 +1,9 @@ +======================= +SPI +======================= + + +.. toctree:: + :maxdepth: 1 + + SPI - TFT LCD Display \ No newline at end of file diff --git a/docs/development_guide_en/source/samples/basic samples/spi/spi_lcd_demo.rst b/docs/development_guide_en/source/samples/basic samples/spi/spi_lcd_demo.rst new file mode 100644 index 00000000..41e56108 --- /dev/null +++ b/docs/development_guide_en/source/samples/basic samples/spi/spi_lcd_demo.rst @@ -0,0 +1,154 @@ +SPI - TFT LCD Display +======================= + +Hardware Connection +----------------------------- + +This demo is based on BL706_AVB, and the connection method is as follows + +:: + + GPIO function GPIO pin + ---------------------------------- + LCD_CS <--> GPIO10 + LCD_DC <--> GPIO22 + SPI_SCK <--> GPIO19 + SPI_MISO <--> GPIO20 + SPI_MOSI <--> GPIO21 + + +Software Implementation +----------------------------- + +- See ``examples/spi/spi_lcd`` for the software code + +.. code-block:: C + :linenos: + + #define BSP_SPI_CLOCK_SOURCE ROOT_CLOCK_SOURCE_BCLK + #define BSP_SPI_CLOCK_DIV 0 + +- Configure the ``SPI`` device clock source, see ``bsp/board/bl706_avb/clock_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 + +- Configure ``SPI`` device multiplexing pins, see ``bsp/board/bl706_avb/pinmux_config.h`` + +.. note:: + ``bsp/board/bl706_avb/pinmux_config.h`` is currently used by all demo demos, so you need to select ``PINMUX_SELECT`` as ``PINMUX_LVGL``, and open one of the demos + +.. note:: + In order to adapt to the bl702_avb hardware, the MOSI and MISO of SPI have been swapped by default. If you want to restore the default, modify ``SPI_SWAP_ENABLE`` in ``drivers/bl702_driver/hal_drv/default_config/spi_config.h`` to 0 + +.. 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 + +- Enable ``BSP_USING_SPI0`` and configure ``SPI`` device, see ``bsp/board/bl706_avb/peripheral_config.h`` + +.. 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); + } + +- Configure the ``LCD_CS`` and ``LCD_DC`` pins as output mode and pull up +- Call ``spi_register`` function to register ``SPI`` device, currently register ``SPI0`` +- Then use the ``find`` function to find the handle corresponding to the device and save it in the ``spi0`` handle +- Finally use ``device_open`` to open the ``spi0`` device in polling sending mode + +.. 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; + } + +- Provide interface for LCD display driver + +Compile and Program +----------------------------- + +- **CDK compilation** + + Open project:spi_lcd.cdkproj + + Refer to the steps of :ref:`windows_cdk_quick_start` to compile and download + +- **Command compilation** + +.. code-block:: bash + :linenos: + + $ cd /bl_mcu_sdk + $ make BOARD=bl706_avb APP=spi_lcd + +- **Program** + + See :ref:`bl_dev_cube` + +Experimental Phenomena +----------------------------- + +.. figure:: img/spi_lcd.png + :alt: + +spi display! diff --git a/docs/development_guide_en/source/samples/basic samples/timer/index.rst b/docs/development_guide_en/source/samples/basic samples/timer/index.rst new file mode 100644 index 00000000..7a858bb2 --- /dev/null +++ b/docs/development_guide_en/source/samples/basic samples/timer/index.rst @@ -0,0 +1,9 @@ +======================= +TIMER +======================= + + +.. toctree:: + :maxdepth: 1 + + TIMER - Second Timing Interrupt \ No newline at end of file diff --git a/docs/development_guide_en/source/samples/basic samples/timer/timer_interrupt_demo.rst b/docs/development_guide_en/source/samples/basic samples/timer/timer_interrupt_demo.rst new file mode 100644 index 00000000..ed9b2219 --- /dev/null +++ b/docs/development_guide_en/source/samples/basic samples/timer/timer_interrupt_demo.rst @@ -0,0 +1,109 @@ +TIMER - Second Timing Interrupt +================================== + + This demo is based on TIMER interrupt mode with second timing. + +Hardware Connection +----------------------------- +None + +Software Implementation +----------------------------- + +- See ``examples/timer/timer_int`` for the software code + +.. code-block:: C + :linenos: + + #define BSP_TIMER0_CLOCK_SOURCE ROOT_CLOCK_SOURCE_FCLK + #define BSP_TIMER0_CLOCK_DIV 0 + +- Configure ``TIMER`` device clock source,see ``bsp/board/bl706_iot/clock_config.h`` + +.. code-block:: C + :linenos: + + #define BSP_USING_TIMER0 + + #if defined(BSP_USING_TIMER0) + #ifndef TIMER0_CONFIG + #define TIMER0_CONFIG \ + { \ + .id = 0, \ + .cnt_mode = TIMER_CNT_PRELOAD, \ + .trigger = TIMER_PRELOAD_TRIGGER_COMP2, \ + .reload = 0, \ + .timeout1 = 1000000, \ + .timeout2 = 2000000, \ + .timeout3 = 3000000, \ + } + #endif + #endif + +- Enable ``BSP_USING_TIMER0`` and configure ``TIMER0`` device,see ``bsp/board/bl706_iot/peripheral_config.h`` + +.. code-block:: C + :linenos: + + timer_register(TIMER0_INDEX, "timer0"); + + timer0 = device_find("timer0"); + + if (timer0) { + device_open(timer0, DEVICE_OFLAG_INT_TX); /* 1s,2s,3s timing*/ + device_set_callback(timer0, timer0_irq_callback); + device_control(timer0, DEVICE_CTRL_SET_INT, (void *)(TIMER_COMP0_IT | TIMER_COMP1_IT | TIMER_COMP2_IT)); + } else { + MSG("timer device open failed! \n"); + } + +- Call ``timer_register`` function to register ``TIMER`` device, currently register ``TIMER0`` +- Then use the ``find`` function to find the handle corresponding to the device and save it in the ``timer0`` handle +- Finally use ``device_open`` to open the ``timer0`` device in interrupt mode +- Call ``device_set_callback`` to register irq callback named ``timer0_irq_callback``. Call ``device_control`` to enable irq and configure timing period. + +.. code-block:: C + :linenos: + + void timer0_irq_callback(struct device *dev, void *args, uint32_t size, uint32_t state) + { + if (state == TIMER_EVENT_COMP0) { + MSG("timer event comp0! \r\n"); + } else if (state == TIMER_EVENT_COMP1) { + MSG("timer event comp1! \r\n"); + } else if (state == TIMER_EVENT_COMP2) { + BL_CASE_SUCCESS; + timer_timeout_cfg_t cfg = { 2, 12000000 }; /*modify compare id 2 timeout 12s*/ + device_write(dev, 0, &cfg, sizeof(timer_timeout_cfg_t)); + MSG("timer event comp2! \r\n"); + } + } + +- In irq callback,try to determine whether compare id flag is coming. +- Call ``device_write`` to modify compare id 2 timeout with 12s. + +Compile and Program +----------------------------- + +- **CDK compilation** + + Open project:timer_int.cdkproj + + Refer to the steps of :ref:`windows_cdk_quick_start` to compile and download + +- **Command compilation** + +.. code-block:: bash + :linenos: + + $ cd /bl_mcu_sdk + $ make BOARD=bl706_iot APP=timer_int + +- **Program** + + See :ref:`bl_dev_cube` + + +Experimental Phenomena +----------------------------- + diff --git a/docs/development_guide_en/source/samples/basic samples/uart/index.rst b/docs/development_guide_en/source/samples/basic samples/uart/index.rst new file mode 100644 index 00000000..972dbfed --- /dev/null +++ b/docs/development_guide_en/source/samples/basic samples/uart/index.rst @@ -0,0 +1,9 @@ +======================= +UART +======================= + + +.. toctree:: + :maxdepth: 1 + + UART - Loopback \ No newline at end of file diff --git a/docs/development_guide_en/source/samples/basic samples/uart/uart_loopback_demo.rst b/docs/development_guide_en/source/samples/basic samples/uart/uart_loopback_demo.rst new file mode 100644 index 00000000..83350d5c --- /dev/null +++ b/docs/development_guide_en/source/samples/basic samples/uart/uart_loopback_demo.rst @@ -0,0 +1,150 @@ +UART - Loopback +==================== + +This demo is based on UART polling sending and receiving FIFO interrupt mode. + +Hardware Connection +----------------------------- + +This demo is based on BL706_IOT and the connection method is as follows + +:: + + GPIO function GPIO pin + ---------------------------------- + UART0_TX <--> GPIO14 + UART0_RX <--> GPIO15 + +Software Implementation +----------------------------- + +- See ``examples/uart/uart_echo`` for the software code + +.. code-block:: C + :linenos: + + #define BSP_UART_CLOCK_SOURCE ROOT_CLOCK_SOURCE_PLL_96M + #define BSP_UART_CLOCK_DIV 0 + +-Configure the ``UART`` device clock source, see ``bsp/board/bl706_iot/clock_config.h`` + +.. code-block:: C + :linenos: + + #define CONFIG_GPIO14_FUNC GPIO_FUN_UART0_TX + #define CONFIG_GPIO15_FUNC GPIO_FUN_UART0_RX + +- Configure ``UART`` device multiplexing pins, see ``bsp/board/bl706_iot/pinmux_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 + +- Enable ``BSP_USING_UART0`` and configure the ``UART`` device, see ``bsp/board/bl706_iot/peripheral_config.h`` + +.. code-block:: C + :linenos: + + bflb_platform_init(); + +- In the ``bflb_platform_init`` function, we have registered and opened a serial port device for debugging, to provide users with a basic function of ``MSG`` for printing out messages. The specific implementation is as follows + +.. 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, NULL); + device_control(uart, DEVICE_CTRL_CLR_INT, (void *)(UART_RX_FIFO_IT)); + } + +- First call the ``uart_register`` function to register the ``UART`` device, currently register ``UART0`` +- Then use the ``find`` function to find the handle corresponding to the device and save it in the ``uart`` handle +- Finally use ``device_open`` to open the ``uart`` device with polling sending and interrupt receiving, the interrupt is closed by default and the receiving interrupt callback function is not registered + +.. 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)); + } + +- Register the user-specified ``UART0`` receiving interrupt service function through the ``device_set_callback`` function. Open the ``RX_FIFO`` and ``RTO`` interrupts through the ``device_control`` function + +.. 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); + } + } + + +- This function is the interrupt service function of the example, and its function is to send out the received data. + + - ``state`` will return the interrupt type of the ``UART`` device + - ``args`` contains the return data pointer + - ``size`` contains the length of the returned data + - ``dev`` is the handle of the interrupted ``uart`` device + +- When an interrupt occurs, the ``device_write`` function will be called to send the received data back. + +Compile and Program +----------------------------- + +- **CDK compilation** + + Open project:uart_echo.cdkproj + + Refer to the steps of :ref:`windows_cdk_quick_start` to compile and download + +- **Command compilation** + +.. code-block:: bash + :linenos: + + $ cd /bl_mcu_sdk + $ make BOARD=bl706_iot APP=uart_echo + +- **Program** + + See :ref:`bl_dev_cube` + + +Experimental Phenomena +----------------------------- + +Video display: + +.. raw:: html + + +