目录

免按键自动复位下载

如果只是了解如何使用, 看这部分就可以了. 在项目中将SDK更新到最新版本, 在SDK中找到这个文件 include/arch/xt804/csi_config.h, 将下面这行的值从0改成1

#define USE_UART0_AUTO_DL          0 // Auto download, 0:OFF, 1:ON

然后编译, 按正常的操作流程烧录到开发板. 之后的烧录就可以免按键自动下载了, 在下载前会自动复位, 下载后也会自动复位.

注意:

  1. 这个功能仅仅适用于开发和测试阶段, 不能用在生产环境.
  2. 这个功能(以及默认的printf打印)会占用UART0, 如果你的项目需要使用UART0与其它设备通信, 必须关闭这个功能

免按键下载的功能分析

烧录下载的指令分析

在tools/W806/rules.mk中

flash:all
@$(WM_TOOL) -c $(DL_PORT) -rs at -ds $(DL_BAUD) -dl $(FIRMWAREDIR)/$(TARGET)/$(TARGET).fls

可以看到make flash会先执行编译, 然后调用 wm_tool 根据预设的下载端口, 下载波特率, 将fls文件下载到设备. 在正常的下载过程中, 需要先复位开发板进入下载模式, 这时候才开始实际的下载, 下载结束后开发板会依然处于下载模式, 此时需要复位开发板进入普通模式, 运行用户程序. 现在这两步都是手工按Reset键完成的.

烧录下载复位的代码

在上面的命令中, 有一个参数是-rs at, 这个参数的说明是

-rs reset_action, set device reset method, default is manual control <none | at | rts>
none - manual control device reset
at - use the at command to control the device reset
rts - use the serial port rts pin to control the device reset

at对应的选项是使用AT命令去重启设备, 重启动作对应的有两处, 分别就是需要手工按Reset按钮的两个时间点.

下载前复位

对于下载前复位, wm_tool中的处理是

if (WM_TOOL_DL_ACTION_AT == wm_tool_dl_action)
{
if (WM_TOOL_DEFAULT_BAUD_RATE != wm_tool_normal_serial_rate)
wm_tool_uart_set_speed(wm_tool_normal_serial_rate); #if 0 /* use erase option */
if (WM_TOOL_DL_TYPE_FLS == wm_tool_dl_type)
{
ret = wm_tool_uart_write("AT+&FLSW=8002000,0\r\n", strlen("AT+&FLSW=8002000,0\r\n"));
if (ret <= 0)
{
wm_tool_printf("destroy secboot failed.\r\n");
wm_tool_uart_close();
return -3;
}
wm_tool_delay_ms(300);
}
#endif ret = wm_tool_uart_write("AT+Z\r\n", strlen("AT+Z\r\n"));
if (ret <= 0)
{
wm_tool_printf("reset error.\r\n");
wm_tool_uart_close();
return -4;
} if (WM_TOOL_DEFAULT_BAUD_RATE != wm_tool_normal_serial_rate)
wm_tool_uart_set_speed(WM_TOOL_DEFAULT_BAUD_RATE);
} ... wm_tool_printf("wait serial sync...");
wm_tool_send_esc2uart(500);/* used for delay */

可以看到wm_tool的实际操作是通过串口发出AT+Z\r\n指令, 然后等待500ms再检测是否复位

下载后复位

对于下载后的复位, 在代码中只处理了rts选项, 这里使用at选项是无动作的

...

if (WM_TOOL_DL_TYPE_FLS == wm_tool_dl_type)
{
if (WM_TOOL_DL_ACTION_RTS == wm_tool_dl_action)/* auto reset */
{
wm_tool_uart_set_dtr(0);
wm_tool_uart_set_rts(1);
wm_tool_delay_ms(50);
wm_tool_uart_set_dtr(1);
wm_tool_uart_set_rts(0);
wm_tool_delay_ms(50);
wm_tool_uart_set_dtr(0);
}
else
{
wm_tool_printf("please manually reset the device.\r\n");
}
}
...

W806的烧录自动复位实现

根据上面的分析, W806的自动复位需要实现两处, 一处是下载前, 一处是下载完成后

下载前的复位实现

下载前开发板还运行在普通模式, 此时串口由用户程序控制, 如果需要响应串口命令, 需要在用户程序中添加串口0的RX中断和命令判断. 这一步可以参考SDK中UART0作为printf打印输出的实现

增加UART0初始化

在 platform/arch/xt804/bsp/board_init.c 中增加初始化代码, 当配置为开启时, 开启UART0接收中断

...
static void uart0Init (int bandrate)
{
unsigned int bd; #if USE_UART0_AUTO_DL
WRITE_REG(UART0->INTM, ~UART_RX_INT_FLAG);
NVIC_ClearPendingIRQ(UART0_IRQn);
NVIC_EnableIRQ(UART0_IRQn);
#else
NVIC_DisableIRQ(UART0_IRQn);
NVIC_ClearPendingIRQ(UART0_IRQn);
#endif
...
}

增加UART0接收中断响应和命令检测

在 platform/component 下新增一个组件, 在组件中实现中断响应和命令检测

/******************************************************************************
**
* \file auto_dl.c
* \author Xu Ruijun | 1687701765@qq.com
* \date
* \brief Reset device with UART0 AT+Z command
* \note Set USE_UART0_AUTO_DL = 1 to enable this feature
* \version
* \ingroup
* \remarks
*
******************************************************************************/ #include "wm_hal.h" #if USE_UART0_AUTO_DL #define __AUTO_DL_UART_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->INTS |= __FLAG__)
#define __AUTO_DL_TIMEOUT 5
#define __AUTO_DL_BUF_SIZE 32 const static uint8_t auto_dl_cmd[] = {'A', 'T', '+', 'Z', '\r', '\n'};
uint8_t auto_dl_buf[__AUTO_DL_BUF_SIZE] = {0}, auto_dl_buf_pt = 0, auto_dl_cmd_pt = 0;
uint32_t auto_dl_act_ts = 0; void AUTO_DL_Reset(void)
{
CLEAR_REG(RCC->RST); // reset all peripherals
uint32_t rv = *(uint32_t*)(0x00000000U); // get reset vector
((void (*)())(rv))(); // go to ROM
} __attribute__((weak)) void USER_UART0_RX(uint8_t ch)
{
UNUSED(ch);
} void AUTO_DL_UART_IRQHandler(USART_TypeDef* huart)
{
uint8_t ch, count;
uint32_t ts, isrflags = READ_REG(huart->INTS), isrmasks = READ_REG(huart->INTM);
// Clear interrupts
__AUTO_DL_UART_CLEAR_FLAG(huart, isrflags); if (((isrflags & UART_RX_INT_FLAG) != RESET) && ((isrmasks & UART_RX_INT_FLAG) == RESET))
{
/**
* 1) Data always comes in as single bytes, so the count is always 1(or 0);
* 2) Each byte will comes in twice, the second time with count=0 will be ignored;
*/
count = ((READ_REG(huart->FIFOS) & UART_FIFOS_RFC) >> UART_FIFOS_RFC_Pos);
while (count-- > 0)
{
// Write ch to ring buffer
ch = (uint8_t)(huart->RDW);
auto_dl_buf[auto_dl_buf_pt++] = ch;
if (auto_dl_buf_pt == __AUTO_DL_BUF_SIZE) auto_dl_buf_pt = 0; // Command detection
ts = HAL_GetTick();
if ((ts - auto_dl_act_ts) > __AUTO_DL_TIMEOUT)
{
// Restart the comparison if timeout
auto_dl_cmd_pt = 0;
if (auto_dl_cmd[auto_dl_cmd_pt] == ch)
{
auto_dl_cmd_pt++;
}
}
else
{
// Avoid starting new comparison in the middle of RX
if ((auto_dl_cmd[auto_dl_cmd_pt] == ch) && (auto_dl_cmd_pt > 0))
{
auto_dl_cmd_pt++;
if (auto_dl_cmd_pt == sizeof(auto_dl_cmd))
{
AUTO_DL_Reset();
}
}
else
{
// Restart the comparison
auto_dl_cmd_pt = 0;
}
}
// Record last active timestamp
auto_dl_act_ts = ts;
USER_UART0_RX(ch);
}
} if (((isrflags & UART_INTS_TL) != RESET) && ((isrmasks & UART_INTM_RL) == RESET))
{
//UART_Transmit_IT(huart);
} if (((isrflags & UART_INTS_TEMPT) != RESET) && ((isrmasks & UART_INTM_TEMPT) == RESET))
{
//UART_EndTransmit_IT(huart);
}
} __attribute__((isr)) void UART0_IRQHandler(void)
{
AUTO_DL_UART_IRQHandler(UART0);
} #endif

下载成功后的复位实现

下载成功后, 开发板还运行在下载模式, 因此找到下载模式下对应复位的命令就可以了, 这个命令是

0x21, 0x06, 0x00, 0xc7, 0x7c, 0x3f, 0x00, 0x00, 0x00

对应的, 在 wm_tool.c中增加这个命令常量

const static unsigned char wm_tool_chip_cmd_reset[]    = {0x21, 0x06, 0x00, 0xc7, 0x7c, 0x3f, 0x00, 0x00, 0x00};

和对AT模式的处理逻辑

if (WM_TOOL_DL_TYPE_FLS == wm_tool_dl_type)
{
if (WM_TOOL_DL_ACTION_RTS == wm_tool_dl_action) // Use UART RTS pin to control the device reset
{
...
}
else if(WM_TOOL_DL_ACTION_AT == wm_tool_dl_action) // Use AT command to reset the device
{
wm_tool_delay_ms(500);
ret = wm_tool_uart_write(wm_tool_chip_cmd_reset, sizeof(wm_tool_chip_cmd_reset));
wm_tool_delay_ms(30);
if(ret > 0){
wm_tool_printf("reset command has been sent.\r\n");
}else{
wm_tool_printf("reset command sending failed.\r\n");
}
ret = 0;
}
...
}

联盛德 HLK-W806 (三): 免按键自动下载和复位的更多相关文章

  1. 联盛德 HLK-W806 (一): Ubuntu20.04下的开发环境配置, 编译和烧录说明

    目录 联盛德 HLK-W806 (一): Ubuntu20.04下的开发环境配置, 编译和烧录说明 联盛德 HLK-W806 (二): Win10下的开发环境配置, 编译和烧录说明 联盛德 HLK-W ...

  2. 联盛德 HLK-W806 (五): W801开发板上手报告

    目录 联盛德 HLK-W806 (一): Ubuntu20.04下的开发环境配置, 编译和烧录说明 联盛德 HLK-W806 (二): Win10下的开发环境配置, 编译和烧录说明 联盛德 HLK-W ...

  3. 联盛德 HLK-W806 (二): Win10下的开发环境配置, 编译和烧录说明

    目录 联盛德 HLK-W806 (一): Ubuntu20.04下的开发环境配置, 编译和烧录说明 联盛德 HLK-W806 (二): Win10下的开发环境配置, 编译和烧录说明 联盛德 HLK-W ...

  4. 联盛德 HLK-W806 (四): 软件SPI和硬件SPI驱动ST7735液晶LCD

    目录 联盛德 HLK-W806 (一): Ubuntu20.04下的开发环境配置, 编译和烧录说明 联盛德 HLK-W806 (二): Win10下的开发环境配置, 编译和烧录说明 联盛德 HLK-W ...

  5. 联盛德 HLK-W806 (六): I2C驱动SSD1306 128x64 OLED液晶屏

    目录 联盛德 HLK-W806 (一): Ubuntu20.04下的开发环境配置, 编译和烧录说明 联盛德 HLK-W806 (二): Win10下的开发环境配置, 编译和烧录说明 联盛德 HLK-W ...

  6. 联盛德 HLK-W806 (八): 4线SPI驱动SSD1306/SSD1315 128x64 OLED液晶屏

    目录 联盛德 HLK-W806 (一): Ubuntu20.04下的开发环境配置, 编译和烧录说明 联盛德 HLK-W806 (二): Win10下的开发环境配置, 编译和烧录说明 联盛德 HLK-W ...

  7. 联盛德 HLK-W806 (七): 兼容开发板 LuatOS Air103

    目录 联盛德 HLK-W806 (一): Ubuntu20.04下的开发环境配置, 编译和烧录说明 联盛德 HLK-W806 (二): Win10下的开发环境配置, 编译和烧录说明 联盛德 HLK-W ...

  8. 联盛德 HLK-W806 (十): 在 CDK IDE开发环境中使用WM-SDK-W806

    目录 联盛德 HLK-W806 (一): Ubuntu20.04下的开发环境配置, 编译和烧录说明 联盛德 HLK-W806 (二): Win10下的开发环境配置, 编译和烧录说明 联盛德 HLK-W ...

  9. 联盛德 HLK-W806 (九): 软件SPI和硬件SPI驱动ST7789V液晶LCD

    目录 联盛德 HLK-W806 (一): Ubuntu20.04下的开发环境配置, 编译和烧录说明 联盛德 HLK-W806 (二): Win10下的开发环境配置, 编译和烧录说明 联盛德 HLK-W ...

随机推荐

  1. Netty 了解

    1.1 Netty 是什么? Netty is an asynchronous event-driven network application framework for rapid develop ...

  2. FastAPI 学习之路(二十)接口文档配置相关

    系列文章: FastAPI 学习之路(一)fastapi--高性能web开发框架 FastAPI 学习之路(二) FastAPI 学习之路(三) FastAPI 学习之路(四) FastAPI 学习之 ...

  3. 1.2 Simple Code!(翻译)

    Simple Code! 简洁编码 Playing football is very simple, but playing simple football is the hardest thing ...

  4. MySQL:提高笔记-4

    MySQL:提高笔记-4 学完基础的语法后,进一步对 MySQL 进行学习,前几篇为: MySQL:提高笔记-1 MySQL:提高笔记-2 MySQL:提高笔记-3 MySQL:提高笔记-4,本文 说 ...

  5. 【二食堂】Alpha - Scrum Meeting 3

    Scrum Meeting 3 例会时间:4.13 12:00 - 12:30 进度情况 组员 昨日进度 今日任务 李健 1. 继续学习前端知识,寻找一些可用的框架.issue 1. 搭建主页html ...

  6. 无网络下,配置yum本地源

    1. 新建一个没有iso镜像文件的虚拟机: 2. 本地上传一个镜像文件(CentOS7的镜像),到虚拟机已创建的目录: 例如:上传一个镜像文件CentOS-7-x86_64-Everything-17 ...

  7. 镜头Lens Image circle像圈的解释是什么意思

    Image circle镜头中指的是:像圈 像圈(image circle)是指入射光线通过镜头后,在焦平面上呈现出的圆形的明亮清晰的影像幅面,也称像面大小.镜头像圈由镜头光学结构决定,一旦设计完成, ...

  8. 从0到1使用Kubernetes系列(四):搭建第一个应用程序

    传统Kubernetes应用搭建 创建Namespace 在一个Kubernetes集群中可以创建多个Namespace进行"环境隔离",当项目和人员众多的时候,可以考虑根据项目的 ...

  9. tar 解压分割压缩文件

    被分割后的压缩文件必须先合并成一个压缩文件才能正常的解压. 第一步.合并压缩文件 第二步.正常解压 $ls TINA-1.3.tar.gzaa TINA-1.3.tar.gzab TINA-1.3.t ...

  10. Github图床设置

    创建新仓库 点击右上角加号->新建仓库,填写基本信息后点击下面的创建即可 https://github.com/new 创建新令牌 点击设置->开发者设置->私人令牌->生成新 ...