This post was last edited by KING_阿飞 on 2022-8-2 15:40
[Atria AT32WB415 series Bluetooth BLE 5.0 MCU] Transplant MCU to control Bluetooth, Bluetooth firmware burning
I am honored to have the opportunity to review the Arteli AT32WB415 series Bluetooth BLE 5.0 MCU. For this reason, in accordance with my previous review habits, my Github : All review codes are open source and shared.
If you cannot access Github due to network problems, you can download it from Gitee. It may not be updated in time. Gitee: My_AT32WB415_Demo: Arteli Technology AT32WB415 series learning, starting from each peripheral, learning each function. (gitee.com)
1. Bluetooth firmware code burning
Artery AT32WB415 is a combined chip, an MCU plus a Bluetooth, with a serial port in the middle, with 2 UARTs, of which UART21 is connected to MCU USART3. We can burn the firmware code through the ArteryICPProgrammer software. The version I use here is V3.0.03. Please upgrade the AT-Link firmware for the first download, and this software can be upgraded.
The first firmware on the page is the Bluetooth firmware, and the other one is the firmware of our MCU.
The official Bluetooth firmware package can be found under the Arterytek page: The innovative leader in 32-bit microcontrollers! (arterytek.com)
This project is an ARM9 project and requires Legacy Support to be installed before it can be compiled. Users can download it according to their own environment in the following path: www2.keil.com/mdk5/legacy . Here I put the bin file I compiled in the warehouse, and you can take it if you need it.
The guide in the official document explains it clearly, so I won't go into details here. Here are a few points to note: the Bluetooth address is 0x000000, there should be a timing problem during reset, you need to reset the MCU first and then reset the Bluetooth, and our mobile phone's Bluetooth must be connected using software like LightBlue, it cannot be connected directly, I haven't touched on this part, it's a knowledge blind spot. I hope someone can study this aspect.
2. MCU code transplantation
In fact, the official documentation has also written about it, so there is no need for us to continue reinventing the wheel (actually it’s just laziness )
I won't go into the specific steps of the transplant, which are relatively simple. If you have any questions, you can ask them in the comments section. Here are some of the problems I encountered during the transplant process, which will have a better effect.
FreeRTOS stuck: I found that it would keep waiting during debugging. After research, I found that the delay in the official at32_button_press key detection function was delay_ms. Here I changed it to the delay in FreeRTOS.
I won’t post all the code here, it’s all on Github, and you can see every change and know which files I added.
Here are some must-haves:
#include "bsp_usart.h"
void usart3_init(uint32_t baudrate)
{
gpio_init_type gpio_init_struct;
crm_periph_clock_enable(CRM_USART3_PERIPH_CLOCK, TRUE);
crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
crm_periph_clock_enable(CRM_IOMUX_PERIPH_CLOCK, TRUE);
gpio_pin_remap_config(USART3_GMUX_0010, TRUE);
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
gpio_init_struct.gpio_pins = GPIO_PINS_7;
gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
gpio_init(GPIOA, &gpio_init_struct);
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
gpio_init_struct.gpio_mode = GPIO_MODE_INPUT;
gpio_init_struct.gpio_pins = GPIO_PINS_6;
gpio_init_struct.gpio_pull = GPIO_PULL_UP;
gpio_init(GPIOA, &gpio_init_struct);
nvic_irq_enable(USART3_IRQn, 0, 0);
/* configure uart param */
usart_init(USART3, baudrate, USART_DATA_8BITS, USART_STOP_1_BIT);
usart_transmitter_enable(USART3, TRUE);
usart_receiver_enable(USART3, TRUE);
/* Enable the USARTx Interrupt */
usart_interrupt_enable(USART3, USART_RDBF_INT, TRUE);
usart_enable(USART3, TRUE);
}
#include "at_task.h"
#include "at32wb415_board.h"
#include "at_cmd.h"
#include "tp_mode.h"
#include "stdio.h"
#include "string.h"
#include "FreeRTOS.h"
#include "task.h"
//#define BT_FLASH_WR_TEST
#define SIZEOFMSG (sizeof(at_cmd_list)/sizeof(struct at_cmd_msg))
extern cmd_flash_read_status fr_flag;
extern cmd_rsp_status cmd_result;
extern flag_status recv_cmp_flag;
extern uint8_t bt_flash_data;
extern char recv_data[];
extern uartstruct tp_mode_rx_uart;
extern uartstruct tp_mode_tx_uart;
flag_status UART_TP_MODE = RESET;
flag_status switch_mode_flag = RESET;
void at_cmd_handler(void);
struct at_cmd_msg at_cmd_list[] =
{
{AT_CMD_IO_SET_LOW, AT_CMD_IOSET0},
{AT_CMD_IO_SET_HIGH, AT_CMD_IOSET1},
{AT_CMD_IO_GET, AT_CMD_IOGET},
};
button_type BUTTON;
void AT_Task(void *pvParameters)
{
printf("AT-Task Start!!\r\n");
while(1){
if(at32_button_press() == USER_BUTTON)
{
UART_TP_MODE = (flag_status)!UART_TP_MODE;
if(UART_TP_MODE)
{
switch_mode_flag = SET;
at_cmd_send(AT_CMD_TP_MODE_ON);
while(cmd_rsp_get(AT_TP_MODE_OK1) != RSP_OK);
switch_mode_flag = RESET;
at32_led_on(LED3);
printf("enter uart tp mode\r\n");
}
else
{
switch_mode_flag = SET;
at_cmd_send(AT_CMD_TP_MODE_OFF);
while(cmd_rsp_get(AT_TP_MODE_OK0) != RSP_OK);
switch_mode_flag = RESET;
at32_led_off(LED3);
printf("leave uart tp mode\r\n");
}
}
if(UART_TP_MODE)
{
tp_mode_rx_handler();
tp_mode_tx_handler();
}
else
{
at_cmd_handler();
}
vTaskDelay(100);
}
}
/**
* @brief handle input at command, it will response corresponding formats.
* @param none
* @retval none
*/
void at_cmd_handler(void)
{
uint8_t msg_id = SIZEOFMSG-1, i;
if(recv_cmp_flag == SET)
{
for(i = 0; i <= SIZEOFMSG; i++)
{
if(memcmp(recv_data, at_cmd_list.at_cmd_string, strlen(recv_data)) == 0)
{
printf("%s", recv_data);
msg_id = i;
break;
}
}
switch(at_cmd_list[msg_id].msg_id)
{
case AT_CMD_IOSET0:
{
at32_led_off(LED2);
at_cmd_send(AT_RESULT_OK0);
break;
}
case AT_CMD_IOSET1:
{
at32_led_on(LED2);
at_cmd_send(AT_RESULT_OK1);
break;
}
case AT_CMD_IOGET:
{
if(gpio_output_data_bit_read(GPIOB, GPIO_PINS_7))
{
at_cmd_send(AT_RESULT_OK1);
}
else
{
at_cmd_send(AT_RESULT_OK0);
}
break;
}
default:
{
at_cmd_send(AT_RSP_ERROR);
break;
}
}
recv_cmp_flag = RESET;
memset(recv_data, 0, strlen(recv_data));
}
}
3. Effect Demonstration
8月2日