stm32fxxx.c (3823B)
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 #include <agent/flash.h> 18 #include <fw/io.h> 19 20 #define _FLASH_BASE 0x40023C00 21 #define FLASH_ACR (_FLASH_BASE + 0x00) 22 23 #define FLASH_KEYR (_FLASH_BASE + 0x04) 24 #define FLASH_KEYR_KEY1 0x45670123 25 #define FLASH_KEYR_KEY2 0xCDEF89AB 26 27 #define FLASH_SR (_FLASH_BASE + 0x0C) 28 #define FLASH_SR_BSY (1 << 16) 29 #define FLASH_SR_PGSERR (1 << 7) // sequence error 30 #define FLASH_SR_PGPERR (1 << 6) // parallelism error 31 #define FLASH_SR_PGAERR (1 << 5) // alignment error 32 #define FLASH_SR_WRPERR (1 << 4) // write-protect error 33 #define FLASH_SR_OPERR (1 << 1) // operation error 34 #define FLASH_SR_ERRMASK 0xF2 35 #define FLASH_SR_EOP (1 << 0) // end of operation 36 37 #define FLASH_CR (_FLASH_BASE + 0x10) 38 #define FLASH_CR_LOCK (1 << 31) 39 #define FLASH_CR_ERRIE (1 << 25) // error irq en 40 #define FLASH_CR_EOPIE (1 << 24) // end of op irq en 41 #define FLASH_CR_STRT (1 << 16) // start 42 #define FLASH_CR_PSIZE_8 (0 << 8) 43 #define FLASH_CR_PSIZE_16 (1 << 8) 44 #define FLASH_CR_PSIZE_32 (2 << 8) 45 #define FLASH_CR_PSIZE_64 (3 << 8) 46 #define FLASH_CR_SNB(n) (((n) & 15) << 3) // sector number 47 #define FLASH_CR_MER (1 << 2) // mass erase 48 #define FLASH_CR_SER (1 << 1) // sector erase 49 #define FLASH_CR_PG (1 << 0) // programming 50 51 52 #define SECTORS 12 53 54 static uint32_t sectors[SECTORS + 1] = { 55 0x00000000, 56 0x00004000, 57 0x00008000, 58 0x0000C000, 59 0x00010000, 60 0x00020000, 61 0x00040000, 62 0x00060000, 63 0x00080000, 64 0x000A0000, 65 0x000C0000, 66 0x000E0000, 67 0x00100000, 68 }; 69 70 int flash_agent_setup(flash_agent *agent) { 71 writel(FLASH_KEYR_KEY1, FLASH_KEYR); 72 writel(FLASH_KEYR_KEY2, FLASH_KEYR); 73 if (readl(FLASH_CR) & FLASH_CR_LOCK) { 74 return ERR_FAIL; 75 } else { 76 return ERR_NONE; 77 } 78 } 79 80 int flash_agent_erase(uint32_t flash_addr, uint32_t length) { 81 uint32_t v; 82 int n; 83 for (n = 0; n < SECTORS; n++) { 84 if (flash_addr == sectors[n]) goto ok; 85 } 86 return ERR_ALIGNMENT; 87 ok: 88 for (;;) { 89 writel(FLASH_CR_SER | FLASH_CR_SNB(n), FLASH_CR); 90 writel(FLASH_CR_STRT | FLASH_CR_SER | FLASH_CR_SNB(n), FLASH_CR); 91 while ((v = readl(FLASH_SR)) & FLASH_SR_BSY) ; 92 if (v & FLASH_SR_ERRMASK) { 93 return ERR_FAIL; 94 } 95 n++; 96 if (n == SECTORS) break; 97 if ((sectors[n] - flash_addr) >= length) break; 98 } 99 return ERR_NONE; 100 } 101 102 int flash_agent_write(uint32_t flash_addr, const void *_data, uint32_t length) { 103 const uint32_t *data = _data; 104 uint32_t v; 105 if ((flash_addr & 3) || (length & 3)) { 106 return ERR_ALIGNMENT; 107 } 108 writel(FLASH_CR_PG | FLASH_CR_PSIZE_32, FLASH_CR); 109 while (length > 0) { 110 writel(*data, flash_addr); 111 data++; 112 length -= 4; 113 flash_addr += 4; 114 while ((v = readl(FLASH_SR)) & FLASH_SR_BSY) ; 115 if (v & FLASH_SR_ERRMASK) { 116 writel(0, FLASH_CR); 117 return ERR_FAIL; 118 } 119 } 120 writel(0, FLASH_CR); 121 return ERR_NONE; 122 } 123 124 int flash_agent_ioctl(uint32_t op, void *ptr, uint32_t arg0, uint32_t arg1) { 125 return ERR_INVALID; 126 } 127 128 const flash_agent __attribute((section(".vectors"))) FlashAgent = { 129 .magic = AGENT_MAGIC, 130 .version = AGENT_VERSION, 131 .flags = 0, 132 .load_addr = LOADADDR, 133 .data_addr = LOADADDR + 0x400, 134 .data_size = 0x8000, 135 .flash_addr = FLASH_BASE, 136 .flash_size = FLASH_SIZE, 137 .setup = flash_agent_setup, 138 .erase = flash_agent_erase, 139 .write = flash_agent_write, 140 .ioctl = flash_agent_ioctl, 141 };