[feat][docs] add english docs

This commit is contained in:
qqwang 2021-08-05 20:33:12 +08:00
parent 0d9f65c145
commit ac418d27a3
437 changed files with 52529 additions and 0 deletions

View file

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 302 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 259 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 352 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 306 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 754 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 715 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 504 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 731 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 568 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 165 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 531 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 384 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View file

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

View file

@ -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
- ControllerThe 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 HardwareImplement 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.

View file

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

View file

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

View file

@ -0,0 +1,15 @@
DAC
=========================
Introduction
------------------------
DAC Structure Definition
---------------------------
DAC Parameter Configuration Table
------------------------------------
DAC Device Interface
------------------------

View file

@ -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.

View file

@ -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

View file

@ -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

View file

@ -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 <bclk>, crystal oscillator clock <xtal_ck>, 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

View file

@ -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

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