xdebug

next generation of mdebug (work in progress)
git clone http://frotz.net/git/xdebug.git
Log | Files | Refs | README

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 };