目录

免按键自动复位下载

如果只是了解如何使用, 看这部分就可以了. 在项目中将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. Java(26)集合一Collection

    来源:季沐测试笔记 原文地址:https://www.cnblogs.com/testero/p/15228419.html 博客主页:https://www.cnblogs.com/testero ...

  2. C程序内存布局

    作为计算机专业的来说,程序入门基本都是从C语言开始的,了解C程序中的内存布局,对我们了解整个程序运行,分析程序出错原因,会起到事半功倍的作用 . C程序的内存布局包含五个段,分别是STACK(栈段), ...

  3. Windows内核开发-10-监听对象

    Windows内核开发-10-监听对象 Windows内核除了可以监听进程,线程.dll还可以监听特定的对象和注册表.这里先讲一下监听对象. 监听对象 内核提供了一种可以监听对特定的对象类型的句柄进行 ...

  4. 【数据结构与算法Python版学习笔记】目录索引

    引言 算法分析 基本数据结构 概览 栈 stack 队列 Queue 双端队列 Deque 列表 List,链表实现 递归(Recursion) 定义及应用:分形树.谢尔宾斯基三角.汉诺塔.迷宫 优化 ...

  5. [对对子队]Alpha阶段项目展示博客

    Alpha阶段项目展示博客 1 团队成员的简介和个人博客地址 成员 头像 岗位 博客 个人介绍 黄贤昊 PM 17373253 喜欢玩游戏和做游戏,项目经验基本都和游戏相关,擅长摸鱼,偶尔敬业. 刘子 ...

  6. Spring Cloud Gateway GatewayFilter的使用

    Spring Cloud Gateway GatewayFilter的使用 一.GatewayFilter的作用 二.Spring Cloud Gateway内置的 GatewayFilter 1.A ...

  7. 热身训练1 Blood Cousins Return

    点此看题 简要题面: 一棵树上有n个节点,每个节点有对应的名字(名字可重复). 每次询问,求深度比$vi$多$ki$的$vi$的儿子中,有多少种名字 分析: Step1: 我们可以懂$DFS$轻松找到 ...

  8. hdu 5178 pairs(BC第一题,,方法不止一种,,我用lower_bound那种。。。)

    题意: X坐标上有n个数.JOHN想知道有多少对数满足:x[a]-x[b]<=k(题意给)[a<b] 思路: 额,,,直接看代码吧,,,, 代码: int T,n,k; int x[100 ...

  9. JAVA笔记2__类/封闭性/构造方法/方法的重载/匿名对象

    public class Main { public static void main(String[] args) { Chicken c1 = new Chicken(); Chicken c2 ...

  10. Ubuntu16.04安装apache hive

    0.常规配置操作可参照以下网址: 0.1 Ubuntu安装hive,并配置mysql作为元数据库http://dblab.xmu.edu.cn/blog/install-hive/ ------以下为 ...