stm32f0xx.c (4293B)
1 // agents/stm-main.c 2 // 3 // Copyright 2015 Brian Swetland <swetland@frotz.net> 4 // 5 // Licensed under the Apache License, Version 2.0 (the "License"); 6 // you may not use this file except in compliance with the License. 7 // You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, software 12 // distributed under the License is distributed on an "AS IS" BASIS, 13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 // See the License for the specific language governing permissions and 15 // limitations under the License. 16 17 #define LOADADDR 0x20000400 18 19 #define FLASH_BASE 0x08000000 20 #define FLASH_SIZE 0x00004000 21 22 #include <agent/flash.h> 23 #include <fw/io.h> 24 25 #define _FLASH_BASE 0x40022000 26 #define FLASH_ACR (_FLASH_BASE + 0x00) 27 28 #define FLASH_KEYR (_FLASH_BASE + 0x04) 29 #define FLASH_KEYR_KEY1 0x45670123 30 #define FLASH_KEYR_KEY2 0xCDEF89AB 31 32 #define FLASH_SR (_FLASH_BASE + 0x0C) 33 #define FLASH_SR_EOP (1 << 5) // end of operation 34 #define FLASH_SR_WP_ERR (1 << 4) // write protect error 35 #define FLASH_SR_PG_ERR (1 << 2) // programming error 36 #define FLASH_SR_BSY (1 << 0) // busy 37 #define FLASH_SR_ERR_MASK (FLASH_SR_WP_ERR | FLASH_SR_PG_ERR) 38 39 #define FLASH_CR (_FLASH_BASE + 0x10) 40 #define FLASH_CR_OBL_LAUNCH (1 << 13) // reload option byte & reset system 41 #define FLASH_CR_EOPIE (1 << 12) // enable end-of-op irq 42 #define FLASH_CR_ERRIE (1 << 10) // enable error irq 43 #define FLASH_CR_OPTWRE (1 << 9) // option byte write enable 44 #define FLASH_CR_LOCK (1 << 7) // indicates flash is locked 45 #define FLASH_CR_STRT (1 << 6) // start erase operation 46 #define FLASH_CR_OPTER (1 << 5) // option byte erase 47 #define FLASH_CR_OPTPG (1 << 4) // option byte program 48 #define FLASH_CR_MER (1 << 2) // mass erase 49 #define FLASH_CR_PER (1 << 1) // page erase 50 #define FLASH_CR_PG (1 << 0) // programming 51 #define FLASH_CR_MASK (~0x000036F7) // bits to not modify 52 53 #define FLASH_AR (_FLASH_BASE + 0x14) 54 55 static unsigned FLASH_PAGE_SIZE = 1024; 56 57 int flash_agent_setup(flash_agent *agent) { 58 59 // check MCU ID 60 switch (readl(0x40015800) & 0xFFF) { 61 case 0x444: // F03x 62 case 0x445: // F04x 63 case 0x440: // F05x 64 break; 65 case 0x448: // F07x 66 case 0x442: // F09x 67 FLASH_PAGE_SIZE = 2048; 68 break; 69 default: 70 // unknown part 71 return ERR_INVALID; 72 } 73 74 // check flash size 75 agent->flash_size = readw(0x1FFFF7CC) * 1024; 76 77 writel(FLASH_KEYR_KEY1, FLASH_KEYR); 78 writel(FLASH_KEYR_KEY2, FLASH_KEYR); 79 if (readl(FLASH_CR) & FLASH_CR_LOCK) { 80 return ERR_FAIL; 81 } else { 82 return ERR_NONE; 83 } 84 } 85 86 int flash_agent_erase(uint32_t flash_addr, uint32_t length) { 87 uint32_t cr; 88 int n; 89 if (flash_addr & (FLASH_PAGE_SIZE - 1)) { 90 return ERR_ALIGNMENT; 91 } 92 cr = readl(FLASH_CR) & FLASH_CR_MASK; 93 94 while (length > 0) { 95 if (length > FLASH_PAGE_SIZE) { 96 length -= FLASH_PAGE_SIZE; 97 } else { 98 length = 0; 99 } 100 writel(cr | FLASH_CR_PER, FLASH_CR); 101 writel(flash_addr, FLASH_AR); 102 writel(cr | FLASH_CR_PER | FLASH_CR_STRT, FLASH_CR); 103 while (readl(FLASH_SR) & FLASH_SR_BSY) ; 104 for (n = 0; n < FLASH_PAGE_SIZE; n += 4) { 105 if (readl(flash_addr + n) != 0xFFFFFFFF) { 106 return ERR_FAIL; 107 } 108 } 109 flash_addr += FLASH_PAGE_SIZE; 110 } 111 return ERR_NONE; 112 } 113 114 int flash_agent_write(uint32_t flash_addr, const void *_data, uint32_t length) { 115 const unsigned short *data = _data; 116 uint32_t v, cr; 117 if ((flash_addr & 3) || (length & 3)) { 118 return ERR_ALIGNMENT; 119 } 120 cr = readl(FLASH_CR) & FLASH_CR_MASK; 121 writel(cr | FLASH_CR_PG, FLASH_CR); 122 while (length > 0) { 123 writew(*data, flash_addr); 124 while ((v = readl(FLASH_SR)) & FLASH_SR_BSY) ; 125 if (readw(flash_addr) != *data) { 126 writel(cr, FLASH_CR); 127 return ERR_FAIL; 128 } 129 data++; 130 length -= 2; 131 flash_addr += 2; 132 } 133 writel(cr, FLASH_CR); 134 return ERR_NONE; 135 } 136 137 int flash_agent_ioctl(uint32_t op, void *ptr, uint32_t arg0, uint32_t arg1) { 138 return ERR_INVALID; 139 } 140 141 const flash_agent __attribute((section(".vectors"))) FlashAgent = { 142 .magic = AGENT_MAGIC, 143 .version = AGENT_VERSION, 144 .flags = 0, 145 .load_addr = LOADADDR, 146 .data_addr = LOADADDR + 0x400, 147 .data_size = 0x1000, 148 .flash_addr = FLASH_BASE, 149 .flash_size = FLASH_SIZE, 150 .setup = flash_agent_setup, 151 .erase = flash_agent_erase, 152 .write = flash_agent_write, 153 .ioctl = flash_agent_ioctl, 154 };