// // Created by cfif on 22.09.2025. // #include "Clock.h" #include "fc7xxx_driver_fmc.h" #include "InternalFlashPage.h" #include "fc7xxx_driver_rgm.h" #include "memory.h" #include "BootJump.h" #define _BootloaderSize (64 * 1024) #define _BootloaderBegin 0x01000000 #define _FirmwareMainBegin (_BootloaderBegin + _BootloaderSize) /* static void swap_bank(uint8_t eBank) { uint32_t u32RegVal = FMC1->OTA_CTRL[1]; if (u32RegVal == 0U) { // Аппаратный OTA не включен // 1. Снимаем блокировку OTA (бит 6 = 0) u32RegVal &= ~(1u << 6u); // 2. Устанавливаем активный банк (бит 5) if (0 == eBank) { u32RegVal &= ~(1u << 5u); // Банк 0 } else { u32RegVal |= (1u << 5u); // Банк 1 } // 3. Устанавливаем OTA_EN = 0xA (биты 4-0) // НЕЛЬЗЯ использовать & ~0x1F, потому что это сбросит бит 5! u32RegVal = (u32RegVal & ~0x1F) | 0xA; // ← ОСТАВЛЯЕМ БИТ 5 // 4. Записываем обратно FMC1->OTA_CTRL[1] = u32RegVal; } } */ #define FMC_FB_FPELCK_COUNT_V2 3 #define FMC_FB_CPELCK_COUNT_V2 2 #define FMC_OTA_VER_LOC_COUNT_V2 2 #define FMC_OTA_ACT_VER_COUNT_V2 2 typedef struct { __IO uint32_t FAPC0; /* Flash Access Port Control Register0, offset: 0x0 */ __IO uint32_t FAPC1; /* Flash Access Port Control Register1, offset: 0x4 */ uint8_t RESERVED_0[8]; __IO uint32_t FEEC; /* Flash ECC Error Control Register, offset: 0x10 */ uint8_t RESERVED_1[748]; __IO uint32_t FPESA_L; /* Flash Program Erase Start Address Logical Register, offset: 0x300 */ __I uint32_t FPESA_P; /* Flash Program Erase Start Address Physical Register, offset: 0x304 */ uint8_t RESERVED_2[56]; __IO uint32_t FB_FPELCK[FMC_FB_FPELCK_COUNT_V2]; /* Flash Block n Fine Program Erase Lock Register, offset: 0x340 */ uint8_t RESERVED_3[12]; __IO uint32_t FN_FPELCK; /* Flash NVR Fine Program Erase Lock Register, offset: 0x358 */ __IO uint32_t FB_CPELCK[FMC_FB_CPELCK_COUNT_V2]; /* Flash Block n Coarse Program Erase Lock Register, offset: 0x35c */ uint8_t RESERVED_4[412]; __IO uint32_t OTA_CTRL; /* OTA Control Register, offset: 0x500 */ uint8_t RESERVED_5[4]; __I uint32_t OTA_VER_LOC[FMC_OTA_VER_LOC_COUNT_V2]; /* OTA Version Location Register, offset: 0x508 */ __I uint32_t OTA_ACT_VER[FMC_OTA_ACT_VER_COUNT_V2]; /* OTA Active Version Register, offset: 0x510 */ } FMC_Type_V2; #define FMC0_BASE_V2 (0x4001e000u) #define FMC0_V2 ((FMC_Type_V2 *)FMC0_BASE_V2) static void swap_bank(uint8_t eBank) { if (0U == (FMC0_V2->OTA_CTRL)) { if (0 == eBank) { FMC0_V2->OTA_CTRL &= (~(1u << 5u)); } else { FMC0_V2->OTA_CTRL |= (1u << 5u); } FMC0_V2->OTA_CTRL |= 0xA; } } void DefaultISR(void) { // *((volatile unsigned int *)(0x40014030)) = 0x00000A55; } //#define vPortSVCHandler SVC_Handler //#define xPortPendSVHandler PendSV_Handler //void xPortPendSVHandler(void) __attribute__((naked)); //void vPortSVCHandler(void) __attribute__((naked)); static void Boot2App(void) { uint32_t u32StackAddr = *((uint32_t *) ((uint32_t) _FirmwareMainBegin)); uint32_t u32ResetAddr = *((uint32_t *) (((uint32_t) _FirmwareMainBegin) + 4U)); SCB->VTOR = (uint32_t) _FirmwareMainBegin; __asm volatile("MOV R0, %0\n" "MOV SP, R0\n" "MOV R0, %1\n" "MOV PC, R0" : : "r"(u32StackAddr), "r"(u32ResetAddr) : "memory", "r0" ); } bool is_jtag_debug_active(void) { // Проверяем, включена ли отладка return (CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk) != 0; } uint64_t NumberBank = 0; int main(void) { Bsp_CLOCK_Init(); if (is_jtag_debug_active()) { D_bInternalFlashPage_Clear(0x04000000, NULL, NULL); } NumberBank = (*(__IO uint64_t *) (0x04000000)); if (NumberBank == 0x1122334455667788) { swap_bank(1); } else { swap_bank(0); } // swap_bank(0); // BootJumpToAddress(_FirmwareMainBegin); // BootFastJumpToAddress(_FirmwareMainBegin); Boot2App(); }