1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <stdint.h>
18 
19 
20 struct StmFlash {
21     volatile uint32_t ACR;
22     volatile uint32_t KEYR;
23     volatile uint32_t OPTKEYR;
24     volatile uint32_t SR;
25     volatile uint32_t CR;
26     volatile uint32_t OPTCR;
27 };
28 
29 #define FLASH	((struct StmFlash*)0x40023C00UL)
30 
31 static void flashEraseAll(void);
32 static void flashWriteOneK(uint32_t addr, const uint8_t* data);
33 
34 
35 //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
_start(void)36 void __attribute__((naked)) _start(void) {
37     asm volatile (
38         "b.w flashEraseAll    \n"
39         "b.w flashWriteOneK   \n"
40     );
41 }
42 
flashUnlock(void)43 static void flashUnlock(void)
44 {
45     //this will PURPOSEFULLY hang in case of unlock error (since chip will not unlock till reset anyways)
46     while (FLASH->CR & 0x80000000) {
47         FLASH->KEYR = 0x45670123;
48         FLASH->KEYR = 0xCDEF89AB;
49     }
50 }
51 
flashWait(void)52 static void flashWait(void)
53 {
54     while (FLASH->SR & 0x00010000);
55 }
56 
flashEraseAll(void)57 static void __attribute__((used)) flashEraseAll(void)
58 {
59     flashUnlock();
60     FLASH->CR = 0x00010004;		//erase it all
61     flashWait();
62 }
63 
flashWriteOneK(uint32_t addr,const uint8_t * data)64 static void __attribute__((used)) flashWriteOneK(uint32_t addr, const uint8_t* data)
65 {
66     const uint32_t *data32 = (const uint32_t*)data;
67     uint32_t i;
68 
69     flashUnlock();
70     FLASH->CR = 0x201;	//program word at a time
71 
72     for (i = 0; i < 1024; i += 4) {
73         *(volatile uint32_t*)(addr + i) = *data32++;
74         flashWait();
75     }
76 }
77 
78 
79