static inline uint8_t flash_is_busy() { return ((FLASH->STATR & FLASH_STATR_BSY) == FLASH_STATR_BSY); } static inline void flash_wait_until_not_busy() { while(flash_is_busy()) {} } /* ---------------------------------------------------------- flash_unlock entsperrt den Flashspeicher zum Beschreiben oder Loeschen ---------------------------------------------------------- */ static inline void flash_unlock() { // KEY1 zum Entsperren zuerst FLASH->KEYR = FLASH_KEY1; FLASH->KEYR = FLASH_KEY2; } /* ---------------------------------------------------------- flash_lock sperrt den Flashspeicher, Beschreiben oder Loeschen aus dem Programm heraus nicht mehr moeglich ---------------------------------------------------------- */ static inline void flash_lock() { FLASH->CTLR |= FLASH_CTLR_LOCK; } /* ---------------------------------------------------------- fmem_writeword Beschreibt eine Speicherstelle im Flashspeicher mit einem 16-Bit Wert. Uebergabe: addr: bezeichnet die Adresse an der 2 Bytes gespeichert werden sollen data: zu schreibender 16-Bit Wert (2 Bytes) ---------------------------------------------------------- */ static inline void fmem_writeword(uint32_t addr, uint16_t data) { if(FLASH->CTLR & FLASH_CTLR_LOCK) { return; } // wenn Flash gelockt Funktion verlassen flash_wait_until_not_busy(); FLASH->CTLR |= CR_PG_Set; // beschreiben Flash zulassen *(uint16_t*)(uintptr_t)addr = data; // Datenwert schreiben flash_wait_until_not_busy(); FLASH->CTLR &= CR_PG_Reset; // beschreiben Flash sperren } /* ---------------------------------------------------------- flash_erase_sector loescht einen Speichersektor (1 kByte) ab der angegebenen Speicheraddresse 'addr' ---------------------------------------------------------- */ static inline void flash_erase_sector(uint32_t addr) { // bei gelocktem Flash Funktion verlassen if(FLASH->CTLR & FLASH_CTLR_LOCK) { return; } flash_wait_until_not_busy(); FLASH->CTLR |= CR_PER_Set; // sector erase bit im Control Register FLASH->ADDR = addr; // zu loeschende Speicheradresse FLASH->CTLR |= CR_STRT_Set; // Loeschvorgang starten flash_wait_until_not_busy(); // warten bis Loeschvorgang beendet FLASH->CTLR &= CR_PER_Reset; // Reset sector erase bit } /* ---------------------------------------------------------- start_user_prog verlaesst den Bootloader und startet das Anwederprogramm. Die Funktion ist nach einem Timeout aufzurufen, wenn nach PowerOn kein Kommando zum Neuschreiben des Flashspeichers eingegangen ist. Alle Programmanweisungen die nacht "start_user_prog" angegeben sind, werden logischerweise nicht ausgeführt weil dieses hier in etwa einem "return to userprogram" oder "jump to userprogram" entspricht ---------------------------------------------------------- */ static inline void start_user_prog(void) { FLASH->KEYR = FLASH_KEY1; FLASH->KEYR = FLASH_KEY2; FLASH->BOOT_MODEKEYR = FLASH_KEY1; FLASH->BOOT_MODEKEYR = FLASH_KEY2; // Reset-Value Status-Register == 0 // Bit14 == Mode // 0 == "after software reset, you FLASH->STATR = 0; // can switch to the user-area" FLASH->CTLR = CR_LOCK_Set; PFIC->SCTLR = 1<<31; }