No-button automatic reset download
If you just want to know how to use it, just read this part. Update the SDK to the latest version in the project, find this file include/arch/xt804/csi_config.h in the SDK, and change the value of the following line from 0 to 1
#define USE_UART0_AUTO_DL 0 // Auto download, 0:OFF, 1:ON
Then compile and burn it to the development board according to the normal operation process. After that, the burning can be automatically downloaded without pressing buttons. It will automatically reset before downloading and after downloading.
Notice:
This feature is only suitable for development and testing stages and cannot be used in production environments.
This function (and the default printf printing) will occupy UART0. If your project needs to use UART0 to communicate with other devices, you must turn off this function.
Functional analysis of keyless downloading
Analysis of the instructions for burning and downloading
In tools/W806/rules.mk
flash:all
@$(WM_TOOL) -c $(DL_PORT) -rs at -ds $(DL_BAUD) -dl $(FIRMWAREDIR)/$(TARGET)/$(TARGET).fls
You can see that make flash will first compile, then call wm_tool to download the fls file to the device according to the preset download port and download baud rate. In the normal download process, you need to reset the development board to enter the download mode first, then the actual download will start. After the download is completed, the development board will still be in the download mode. At this time, you need to reset the development board to enter the normal mode and run the user program. Now these two steps are completed manually by pressing the Reset key.
Burn download reset code
In the above command, there is a parameter -rs at, the description of this parameter is
-rs reset_action, set device reset method, default is manual control 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 The option corresponding to at is to use AT command to restart the device. There are two places corresponding to the restart action, which are the two time points where you need to press the Reset button manually. Reset before downloading For the reset before downloading, the processing in wm_tool is 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,0rn", strlen("AT+&FLSW=8002000,0rn")); if (ret <= 0) { wm_tool_printf("destroy secboot failed.rn"); wm_tool_uart_close(); return -3; } wm_tool_delay_ms(300); } #endif ret = wm_tool_uart_write("AT+Zrn", strlen("AT+Zrn")); if (ret <= 0) { wm_tool_printf("reset error.rn"); 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 */ It can be seen that the actual operation of wm_tool is to send the AT+Zrn command through the serial port, and then wait for 500ms to detect whether it is reset. Reset after download For the reset after download, only the rts option is processed in the code, and the at option is used here without any action. ... 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.rn"); } } ... Implementation of automatic reset during burning of W806 According to the above analysis, the automatic reset of W806 needs to be implemented in two places, one before downloading and one after downloading. Reset implementation before downloading Before downloading, the development board is still running in normal mode. At this time, the serial port is controlled by the user program. If you need to respond to serial port commands, you need to add the RX interrupt and command judgment of serial port 0 in the user program. For this step, you can refer to the implementation of UART0 as printf print output in SDK. Add UART0 initialization Add initialization code in platform/arch/xt804/bsp/board_init.c, and enable UART0 receive interrupt when configured as enabled ... 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 ... } Add UART0 receive interrupt response and command detection Add a new component under platform/component and implement interrupt response and command detection in the 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 Reset after successful download After the download is successful, the development board is still running in download mode, so just find the corresponding reset command in download mode. This command is 0x21, 0x06, 0x00, 0xc7, 0x7c, 0x3f, 0x00, 0x00, 0x00 Correspondingly, add this command constant in wm_tool.c const static unsigned char wm_tool_chip_cmd_reset[] = {0x21, 0x06, 0x00, 0xc7, 0x7c, 0x3f, 0x00, 0x00, 0x00}; And the processing logic for AT mode 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.rn"); }else{ wm_tool_printf("reset command sending failed.rn"); } right = 0; } ... }
Previous article:HLK-W806 (IV): Software SPI and hardware SPI driver for ST7735 LCD
Next article:Lianshengde HLK-W806 (Part 2): Development environment configuration, compilation and burning instructions under Win10
- Popular Resources
- Popular amplifiers
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- Huawei's Strategic Department Director Gai Gang: The cumulative installed base of open source Euler operating system exceeds 10 million sets
- Download from the Internet--ARM Getting Started Notes
- Learn ARM development(22)
- Learn ARM development(21)
- Learn ARM development(20)
- Learn ARM development(19)
- Learn ARM development(14)
- Learn ARM development(15)
- Analysis of the application of several common contact parts in high-voltage connectors of new energy vehicles
- Wiring harness durability test and contact voltage drop test method
- "New Concept Analog Circuit" - Signal Processing Circuit, Yang Jianguo's new book
- How to use the IP of Video On-Screen Display in zynq
- Review Weekly Report 20220516: Mil Allwinner Automotive-Grade CPU Development Board MYC-YT507, Award-winning Review is here
- What is the state of Industry 4.0? Check out the results of this global survey
- Unlocking the Potential of Full-Duplex DOCSIS 3.1 Architectures with DPD and 75Ω Cable TV Switches
- [Synopsys IP Resources] What kind of processor architecture is needed for the next generation of smart car chips?
- [Silicon Labs BG22-EK4108A Bluetooth Development Evaluation] 2. Hardware Testing: Lighting and Code Explanation
- How to use the Smart Analog Combo in MSP430 MCUs
- [phyBOARD-i.MX 8M Plus Development Board] Part 3: Demo Program Compilation, Download and Run
- STM32F103 brushless DC motor control program