Files
ch32v20x-examples/EVT/EXAM/USB/USBFS/HOST_IAP/APP/User/main.c
T
2023-02-01 14:19:13 +08:00

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;
}