219 lines
7.5 KiB
C
219 lines
7.5 KiB
C
/********************************** (C) COPYRIGHT *******************************
|
|
* File Name : main.c
|
|
* Author : WCH
|
|
* Version : V1.0.0
|
|
* Date : 2022/08/20
|
|
* Description : Main program body.
|
|
*********************************************************************************
|
|
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
|
* Attention: This software (modified or not) and binary are used for
|
|
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
|
*******************************************************************************/
|
|
|
|
/*
|
|
*@Note
|
|
With HOST_IAP, with as IAP's supporting APP use. The generated Hex file needs to be converted to a bin file.
|
|
*/
|
|
|
|
#include "debug.h"
|
|
#include "stdio.h"
|
|
#include "string.h"
|
|
|
|
/*******************************************************************************/
|
|
/* Macro Definitions */
|
|
#define DEF_FLASH_PAGE_SIZE 0x100
|
|
|
|
/* APP CODE ADDR Setting */
|
|
#define DEF_APP_CODE_START_ADDR 0x08005000 /* IAP Flash Operation start address, user code start address */
|
|
#ifdef CH32V20x_D6
|
|
#define DEF_APP_CODE_END_ADDR 0x08010000 /* IAP Flash Operation end address, user code end address */
|
|
/* Please refer to link.ld file for accuracy flash size, the size here is the smallest available size */
|
|
/* CH32V203C8/G8/F8 - 0x08010000 (64K), CH32F203C6 - 0x08008000 (32K) */
|
|
#else
|
|
#define DEF_APP_CODE_END_ADDR 0x08020000 /* IAP Flash Operation end address, user code end address */
|
|
/* Please refer to link.ld file for accuracy flash size, the size here is the smallest available size */
|
|
/* CH32V203RB/208x - 0x08020000 (128K) */
|
|
#endif
|
|
#define DEF_APP_CODE_MAXLEN (DEF_APP_CODE_END_ADDR-DEF_APP_CODE_START_ADDR) /* IAP Flash Operation size, user code max size */
|
|
|
|
/* Verify CODE ADDR Setting */
|
|
#define DEF_VERIFY_CODE_START_ADDR 0x08004F00 /* IAP Flash verify-code start address */
|
|
#define DEF_VERIFY_CODE_END_ADDR 0x08005000 /* IAP Flash verify-code end address */
|
|
#define DEF_VERIFY_CODE_MAXLEN (DEF_VERIFY_CODE_END_ADDR-DEF_VERIFY_CODE_START_ADDR) /* IAP Flash verify-code max size */
|
|
#define DEF_VERIFY_CODE_LEN 0x10 /* IAP Flash verify-code actual length, be careful not to exceed the DEF_VERIFY_CODE_MAXLEN */
|
|
|
|
/* Flash Operation Key Setting */
|
|
#define DEF_FLASH_OPERATION_KEY_CODE_0 0x1A86FF00 /* IAP Flash operation Key-code 0 */
|
|
#define DEF_FLASH_OPERATION_KEY_CODE_1 0x55AA55AA /* IAP Flash operation Key-code 1 */
|
|
|
|
/*******************************************************************************/
|
|
/* Flash Operation Key */
|
|
volatile uint32_t Flash_Operation_Key0;
|
|
volatile uint32_t Flash_Operation_Key1;
|
|
|
|
/*******************************************************************************/
|
|
/* Function Statement */
|
|
void GPIO_Cfg_init( void );
|
|
uint8_t PA0_Check( void );
|
|
uint8_t IAP_VerifyCode_Erase( void );
|
|
uint8_t IAP_Flash_Erase( uint32_t address, uint32_t length );
|
|
|
|
/*********************************************************************
|
|
* @fn main
|
|
*
|
|
* @brief Main program.
|
|
*
|
|
* @return none
|
|
*/
|
|
int main(void)
|
|
{
|
|
uint8_t ret;
|
|
Delay_Init( );
|
|
Delay_Ms(500);
|
|
USART_Printf_Init(115200);
|
|
printf("SystemClk:%d\r\n",SystemCoreClock);
|
|
printf("This is a APP code for a IAP application\n" );
|
|
GPIO_Cfg_init( );
|
|
|
|
Flash_Operation_Key0 = DEF_FLASH_OPERATION_KEY_CODE_0;
|
|
|
|
while(1)
|
|
{
|
|
ret = PA0_Check( );
|
|
if( ret )
|
|
{
|
|
printf( "Reset Chip, prepare to Jump To IAP\r\n" );
|
|
printf( "Erase Verify-Code\r\n" );
|
|
IAP_VerifyCode_Erase( );
|
|
NVIC_SystemReset( );
|
|
}
|
|
Delay_Ms( 200 );
|
|
printf( "USER Code\r\n" );
|
|
}
|
|
}
|
|
|
|
/*********************************************************************
|
|
* @fn IAP_Flash_Erase
|
|
*
|
|
* @brief Erase Flash In page(256 bytes),Specify length & address,
|
|
* Based On Fast Flash Operation,
|
|
* With address protection and program runaway protection.
|
|
*
|
|
* @return 0: Operation Success
|
|
* See notes for other errors
|
|
*/
|
|
uint8_t IAP_Flash_Erase( uint32_t address, uint32_t length )
|
|
{
|
|
uint32_t i;
|
|
uint32_t erase_addr;
|
|
uint32_t erase_len;
|
|
volatile uint32_t page_cnts;
|
|
volatile uint32_t page_addr;
|
|
|
|
/* Set initial value */
|
|
erase_addr = address;
|
|
page_addr = address;
|
|
erase_len = length;
|
|
if( (erase_len%256) == 0 )
|
|
{
|
|
page_cnts = erase_len/256;
|
|
}
|
|
else
|
|
{
|
|
page_cnts = (erase_len/256) + 1;
|
|
}
|
|
|
|
/* Verify Keys, No flash operation if keys are not correct */
|
|
if( (Flash_Operation_Key0 != DEF_FLASH_OPERATION_KEY_CODE_0) || (Flash_Operation_Key1 != DEF_FLASH_OPERATION_KEY_CODE_1) )
|
|
{
|
|
/* ERR: Risk of code running away */
|
|
return 0xFF;
|
|
}
|
|
/* Verify Address, No flash operation if the address is out of range */
|
|
if( ((erase_addr >= DEF_APP_CODE_START_ADDR) && (erase_addr <= DEF_APP_CODE_END_ADDR)) || ((erase_addr >= DEF_VERIFY_CODE_START_ADDR) && (erase_addr <= DEF_VERIFY_CODE_END_ADDR)) )
|
|
{
|
|
for( i=0; i<page_cnts; i++ )
|
|
{
|
|
/* Verify Keys, No flash operation if keys are not correct */
|
|
if( Flash_Operation_Key0 != DEF_FLASH_OPERATION_KEY_CODE_0 )
|
|
{
|
|
/* ERR: Risk of code running away */
|
|
return 0xFF;
|
|
}
|
|
FLASH_Unlock_Fast( );
|
|
FLASH_ErasePage_Fast( page_addr );
|
|
page_addr += DEF_FLASH_PAGE_SIZE;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*********************************************************************
|
|
* @fn IAP_VerifyCode_Erase
|
|
*
|
|
* @brief Erase IAP VerifyCode, Based On Fast Flash Operation.
|
|
* With address protection and program runaway protection.
|
|
*
|
|
* @return ret : The meaning of 'ret' can be found in the notes of the
|
|
* corresponding function.
|
|
*/
|
|
uint8_t IAP_VerifyCode_Erase( void )
|
|
{
|
|
uint8_t ret;
|
|
|
|
/* Verify Code Erase */
|
|
Flash_Operation_Key1 = DEF_FLASH_OPERATION_KEY_CODE_1;
|
|
ret = IAP_Flash_Erase( DEF_VERIFY_CODE_START_ADDR, DEF_VERIFY_CODE_MAXLEN );
|
|
Flash_Operation_Key1 = 0;
|
|
if( ret != 0 )
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*********************************************************************
|
|
* @fn GPIO_Cfg_init
|
|
*
|
|
* @brief GPIO init
|
|
*
|
|
* @return none
|
|
*/
|
|
void GPIO_Cfg_init( void )
|
|
{
|
|
GPIO_InitTypeDef GPIO_InitStructure;
|
|
|
|
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
|
|
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
|
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
|
|
GPIO_Init(GPIOA, &GPIO_InitStructure);
|
|
}
|
|
|
|
/*********************************************************************
|
|
* @fn PA0_Check
|
|
*
|
|
* @brief Check PA0 state
|
|
*
|
|
* @return 0 - not Press Down
|
|
* 1 - Press Down
|
|
*/
|
|
uint8_t PA0_Check( void )
|
|
{
|
|
u8 i;
|
|
GPIO_Cfg_init();
|
|
i = GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0);
|
|
if (i == 0)
|
|
{
|
|
Delay_Ms(200);
|
|
i = GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0);
|
|
if (i == 0)
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|