Contributed by WangChong, curated by Ai-Thinker
Hello everyone. What I'm sharing today is actually not just a technical post, because technology is always changing and can never be fully learned. So how to develop the ability to get started quickly becomes especially important. Take the Xiao An Pai as an example: when you first get it, you may feel at a loss, not knowing where to start. Some people think of first looking at the official Examples to see how things are done. This is undoubtedly a smart approach, because it quickly verifies the chip's peripheral resources. Then, based on the methods used in the example, you look up the corresponding method definitions and develop quickly with the provided APIs.
Then, you might look for different header file definitions and learn from the comments, and use the IDE's code navigation to view the corresponding method descriptions or parameter definitions. However, the official code examples do not provide detailed comments on some structs and fields (experienced people can ignore this). It's hard to understand and use the corresponding functions just from the struct or method definitions. Also, there are too many files in the IDE, and frequent context switching makes it easy to forget what you were looking at. I just looked through the aithinker_Ai-M6X_SDK GitHub repository in detail and found the Bouffalo SDK documentation link:
The official documentation has very detailed usage and tutorials for various libraries: Cmake, debug, LHAL APIs, etc. 
For example, if I want to use the UART feature, I just need to find the detailed API description under the LHAL directory. 
Clicking the link jumps to this page. 
On the left of this page, the first-level menus are the Hal modules, data structures (all structs in the whole Bouffalo SDK, etc.) and files. We can ignore the data structures and files at the bottom, because if we don't understand them, we can jump directly from the functions to look them up.
Now let's find the UART module we need today in LHAL. 
The above is a relationship diagram of the UART module; you can see what the UART module contains in detail.
As shown below, the figure describes in detail the data structures needed by the current module and all the method definitions. 
After clicking the struct above, it jumps to the corresponding data structure description as shown below: the left side is the data structure name, the top is the UML class diagram, the middle shows the field types and names, and the bottom gives detailed descriptions of each parameter. 
We mainly use the following methods: initialization, sending one char, and receiving one char. 
I believe at this point everyone should be able to write a serial test demo by themselves. Below is the one I wrote. Please point out any mistakes; let's learn together. Thanks!
#include "board.h"
#include "bflb_uart.h"
struct bflb_device_s *uart;
int main(void)
{
board_init();
// get the peripheral resource uart0
uart = bflb_device_get_by_name("uart0");
// define a struct for initializing the uart configuration
struct bflb_uart_config_s cfg;
// struct configuration
cfg.baudrate = 2000000;
cfg.data_bits = UART_DATA_BITS_8;
cfg.stop_bits = UART_STOP_BITS_1;
cfg.parity = UART_PARITY_NONE;
cfg.flow_ctrl = 0;
cfg.tx_fifo_threshold = 7;
cfg.rx_fifo_threshold = 7;
bflb_uart_init(uart, &cfg);
int ch;
while (1) {
// receive data on the serial port
ch = bflb_uart_getchar(uart);
// returns -1 if nothing received; once received, forward it out
if (ch != -1) {
bflb_uart_putchar(uart, ch);
}
}
}The expected result: when the serial port is open and the software baud rate matches the code, sent messages are echoed back. 
Have questions?
For other questions, please visit the unified discussion area: Ai-Thinker Discussions

