/* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include struct StmFlash { volatile uint32_t ACR; volatile uint32_t KEYR; volatile uint32_t OPTKEYR; volatile uint32_t SR; volatile uint32_t CR; volatile uint32_t OPTCR; }; #define FLASH ((struct StmFlash*)0x40023C00UL) static void flashEraseAll(void); static void flashWriteOneK(uint32_t addr, const uint8_t* data); //i am too lazy to make a linker script. if this is first here, gcc will place it first in the file...live with it void __attribute__((naked)) _start(void) { asm volatile ( "b.w flashEraseAll \n" "b.w flashWriteOneK \n" ); } static void flashUnlock(void) { //this will PURPOSEFULLY hang in case of unlock error (since chip will not unlock till reset anyways) while (FLASH->CR & 0x80000000) { FLASH->KEYR = 0x45670123; FLASH->KEYR = 0xCDEF89AB; } } static void flashWait(void) { while (FLASH->SR & 0x00010000); } static void __attribute__((used)) flashEraseAll(void) { flashUnlock(); FLASH->CR = 0x00010004; //erase it all flashWait(); } static void __attribute__((used)) flashWriteOneK(uint32_t addr, const uint8_t* data) { const uint32_t *data32 = (const uint32_t*)data; uint32_t i; flashUnlock(); FLASH->CR = 0x201; //program word at a time for (i = 0; i < 1024; i += 4) { *(volatile uint32_t*)(addr + i) = *data32++; flashWait(); } }