#include "stdio.h" typedef struct{ unsigned int Command; unsigned int Result; unsigned int Reserved1[4]; unsigned int Reserved2; unsigned int TargetAddr; unsigned int Length; unsigned int Reserved3; unsigned int Reserved4; unsigned int Reserved5; unsigned int Reserved6; unsigned int Reserved7; unsigned int Reserved8; INT8U Buf[8192]; }FLASH_INFO_Str; FLASH_INFO_Str Flash_Info; unsigned int EraseCounter = 0, NbrOfPage = 0, FLASHStatus = 0, MemoryProgramStatus = 0, HSEStartUpStatus = 0; #define RCC_CR *(unsigned int *)(0x40021000UL + 0x00) //MEMORY[0x40021000] #define RCC_CFGR *(unsigned int *)(0x40021000UL + 0x04) //MEMORY[0x40021004] #define RCC_CIR *(unsigned int *)(0x40021000UL + 0x08) //MEMORY[0x40021008] #define RCC_APB2RSTR *(unsigned int *)(0x40021000UL + 0x0c) //MEMORY[0x4002100C] #define RCC_APB1RSTR *(unsigned int *)(0x40021000UL + 0x10) //MEMORY[0x40021010] #define RCC_AHBENR *(unsigned int *)(0x40021000UL + 0x14) //MEMORY[0x40021014] #define RCC_APB2ENR *(unsigned int *)(0x40021000UL + 0x18) //MEMORY[0x40021018] #define RCC_APB1ENR *(unsigned int *)(0x40021000UL + 0x1c) //MEMORY[0x4002101C] #define CR_PLLON_BB *(unsigned int *)0x42420060 //MEMORY[0x42420060] #define FLASH_KEYR *(unsigned int *)0x40022004 //MEMORY[0x40022004] #define FLASH_SR *(unsigned int *)0x4002200c //MEMORY[0x4002200c] #define FLASH_CR *(unsigned int *)0x40022010 //MEMORY[0x40022010] #define FLASH_AR *(unsigned int *)0x40022014 //MEMORY[0x40022014] #define SCB_VTOR *(unsigned int *)0xE000ED08 //MEMORY[0xE000ED08] #define PASSED 1 #define FLASH_COMPLETE 4 void RCC_DeInit() { RCC_APB2RSTR = 0; RCC_APB1RSTR = 0; RCC_AHBENR = 20; RCC_APB2ENR = 0; RCC_APB1ENR = 0; RCC_CR |= 1u; RCC_CFGR &= 0xF8FF0000; RCC_CR &= 0xFEF6FFFF; RCC_CR &= ~0x40000u; RCC_CFGR &= 0xFF80FFFF; RCC_CIR = 0; } void __fastcall RCC_HSEConfig(u32 RCC_HSE) { RCC_CR &= ~0x10000u; RCC_CR &= ~0x40000u; if ( RCC_HSE == 0x10000 ) { RCC_CR |= 0x10000u; } else if ( RCC_HSE == 0x40000 ) { RCC_CR |= 0x50000u; } } void __fastcall RCC_GetFlagStatus(u8 RCC_FLAG) { ; } bool RCC_WaitForHSEStartUp() { int i; // r4 int v1; // r0 int v2; // r0 for ( i = 0; ; ++i ) { RCC_GetFlagStatus(0x31u); if ( v1 || i == 128 ) break; } RCC_GetFlagStatus(0x31u); return v2 != 0; } void RCC_HCLKConfig(u32 RCC_HCLK) { RCC_CFGR = RCC_CFGR & 0xFFFFFF0F | RCC_HCLK; } void RCC_PCLK2Config(u32 RCC_PCLK2) { RCC_CFGR = RCC_CFGR & 0xFFFFC7FF | (8 * RCC_PCLK2); } void RCC_PCLK1Config(u32 RCC_PCLK1) { RCC_CFGR = RCC_CFGR & 0xFFFFF8FF | RCC_PCLK1; } #define FLASH_ACR 0x40022000 //MEMORY[0x40022000] void FLASH_SetLatency(u32 FLASH_Latency) { FLASH_ACR = FLASH_ACR & 0x38; FLASH_ACR |= FLASH_Latency; } void FLASH_PrefetchBufferCmd(u32 FLASH_PrefetchBuffer) { FLASH_ACR &= ~0x10u; FLASH_ACR |= FLASH_PrefetchBuffer; } void RCC_PLLConfig(u32 RCC_PLLSource, u32 RCC_PLLMul) { RCC_CFGR = RCC_CFGR & 0xFFC0FFFF | RCC_PLLSource | RCC_PLLMul; } void RCC_PLLCmd(FunctionalState NewState) { CR_PLLON_BB = NewState; } void RCC_GetFlagStatus(u8 RCC_FLAG) { ; } void RCC_SYSCLKConfig(u32 RCC_SYSCLKSource) { RCC_CFGR = RCC_CFGR & 0xFFFFFFFC | RCC_SYSCLKSource; } int RCC_GetSYSCLKSource() { return RCC_CFGR & 0xC; } void RCC_Configuration() { int v0; // r0 RCC_DeInit(); RCC_HSEConfig(0x10000u); HSEStartUpStatus = RCC_WaitForHSEStartUp(); if ( HSEStartUpStatus == SUCCESS ) { RCC_HCLKConfig(0u); RCC_PCLK2Config(0u); RCC_PCLK1Config(0x400u); FLASH_SetLatency(2u); FLASH_PrefetchBufferCmd(0x10u); RCC_PLLConfig(0x10000u, 0x1C0000u); RCC_PLLCmd(ENABLE); do RCC_GetFlagStatus(0x39u); while ( !v0 ); RCC_SYSCLKConfig(2u); while ( RCC_GetSYSCLKSource() != 8 ) ; } } void NVIC_SetVectorTable(u32 NVIC_VectTab, u32 Offset) { SCB_VTOR = Offset & 0x1FFFFF80 | NVIC_VectTab; } void NVIC_Configuration() { NVIC_SetVectorTable(0x8000000u, 0u); } void FLASH_Unlock() { FLASH_KEYR = -839939669; } void FLASH_ClearFlag(u16 FLASH_FLAG) { FLASH_SR = FLASH_FLAG; } void Flash_Init() { FLASHStatus = FLASH_COMPLETE; MemoryProgramStatus = PASSED; RCC_Configuration(); NVIC_Configuration(); FLASH_Unlock(); NbrOfPage = 128; FLASH_ClearFlag(0x35u); } int FLASH_GetStatus() { if ( (FLASH_SR & 1) == 1 ) return 1; if ( (FLASH_SR & 4) != 0 ) return 2; if ( (FLASH_SR & 0x10) != 0 ) return 3; return 4; } void delay(void) { int i = 4095; while(i--); } FLASH_Status FLASH_WaitForLastOperation(u32 Timeout) { int v1; // r2 int Status; // r3 int v3; // r2 Status = FLASH_GetStatus(); while ( Status == 1 && v1 ) { delay(); Status = FLASH_GetStatus(); v1 = v3 - 1; } if ( !v1 ) (unsigned char)(Status) = 5; return (char)Status; } FLASH_Status FLASH_ErasePage(u32 Page_Address) { int Operation; // r5 Operation = FLASH_WaitForLastOperation(0xFFFu); if ( Operation == 4 ) { FLASH_CR |= 2u; FLASH_AR = Page_Address; FLASH_CR |= 0x40u; Operation = FLASH_WaitForLastOperation(0xFFFu); if ( Operation != 1 ) FLASH_CR = FLASH_CR & 0x1FFD; } return (char)Operation; } void EraseAll() { for ( EraseCounter = 0; EraseCounter < NbrOfPage && FLASHStatus == FLASH_COMPLETE; ++EraseCounter ) FLASHStatus = FLASH_ErasePage((EraseCounter << 10) + 0x8000000); Flash_Info.Result = 1; } FLASH_Status FLASH_ProgramHalfWord(u32 targetP, u16 *srcP) { int Operation; // r6 Operation = FLASH_WaitForLastOperation(0xFu); if ( Operation == 4 ) { FLASH_CR |= 1u; *(int *)targetP = *srcP; Operation = FLASH_WaitForLastOperation(0xFu); if ( Operation != 1 ) FLASH_CR = FLASH_CR & 0x1FFE; } return (char)Operation; } void EraseSector() { vu32 i; // r4 int v1; // r0 Flash_Info.Result = 0; for ( i = 0; NbrOfPage - 1 > i && ((i + 1) << 10) + 0x8000000 <= Flash_Info.TargetAddr; ++i ) ; while ( NbrOfPage - 1 > i && FLASHStatus == FLASH_COMPLETE && Flash_Info.TargetAddr + Flash_Info.Length > (i << 10) + 0x8000000 ) { v1 = FLASH_ErasePage((i << 10) + 0x8000000); FLASHStatus = (char)v1; if ( !v1 ) return; ++i; } Flash_Info.Result = 1; } void ReadChipID() { Flash_Info.Result = 1; } void Program() { u32 TargetAddr; // r4 u16 *Buf; // r5 u32 i; // r6 TargetAddr = Flash_Info.TargetAddr; Buf = (u16 *)Flash_Info.Buf; for ( i = 0; Flash_Info.Length > i; i += 2 ) { FLASHStatus = FLASH_ProgramHalfWord(TargetAddr, Buf); TargetAddr += 2; ++Buf; } Flash_Info.Result = 1; } void Main() { Flash_Init(); if ( Flash_Info.Command ) { switch ( Flash_Info.Command ) { case 1u: EraseAll(); break; case 2u: EraseSector(); break; case 3u: ReadChipID(); break; default: Flash_Info.Result = 0; break; } } else { Program(); } }