Merge pull request #75 from beewoolie/stm32lx-whole

STM32Lx target support.
This commit is contained in:
Gareth McMullin 2015-03-08 16:56:01 -07:00
commit 51f91092e7
11 changed files with 1677 additions and 4 deletions

View File

@ -1,5 +1,19 @@
These are the assembler routines for executing a flash write
on the supported targets. They are kept here for reference, but
are not used, as the compiled binary code is included in the
target drivers.
Flash Stubs
===========
For most of the targets, these are assembler routines for executing
a flash write on the supported targets. They are kept here for
reference, but are not used, as the compiled binary code is included
in the target drivers.
For the STM32l0x, the stubs are written in C++ and emitted as arrays
of half-words for inclusion in the target driver. The use of a higher
level language allows more detailed code and for easy revisions.
These stubs communicate with the driver through a structure defined in
the src/include/stm32l0-nvm.h header.
The dump-to-array.sh helper script uses sed to transform the output of
'objdump -d' into a half-word array of the instructions that may be
included in C code to declare the stub. FWIW, objcopy doesn't produce
the same output as objdump. It omits some of the instructions,
probably because the object file isn't linked.

11
flashstub/dump-to-array.sh Executable file
View File

@ -0,0 +1,11 @@
#!/bin/sh
#
# Convert the output of objdump to an array of half-words that can be
# included into C code to represent the stub.
#
# Invoke with something like this:
#
# objdump -z -d FILE.o | dump-to-array.sh > FILE.stub
#
sed -E "/^[ ][ ]*[0-9a-fA-F]+:/!d; s/([0-9a-fA-F]+):[ \t]+([0-9a-fA-F]+).*/[0x\1\/2] = 0x\2,/ ; s/0x(....)(....),/0x\2, 0x\1,/"

View File

@ -0,0 +1,93 @@
/* @file stm32l05x-nvm-prog-erase.cc
*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2014 Woollysoft
* Written by Marc Singer <elf@woollysoft.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* -----------
DESCRIPTION
-----------
NVM program flash erase stub for STM32L05x, a Cortex-M0+ core. The
stub uses SRAM to host the code fragment to perform the erase.
This stub works with the STM32L1xx given a few options.
If you plan to modify this routine and emit a new stub, make sure
to audit the code. We don't have a stack so we cannot make calls
that save the link pointer. IOW, the inline functions should be be
inlined.
*/
#include <stdint.h>
#include <string.h>
#include "../src/include/stm32lx-nvm.h"
/* Erase a region of flash. In the event that the erase is misaligned
with respect to pages, it will erase the pages that contain the
requested range of bytes. */
extern "C" void __attribute((naked)) stm32l05x_nvm_prog_erase() {
// Leave room for INFO at second word of routine
__asm volatile ("b 0f\n\t"
".align 2\n\t"
".word 0\n\t"
".word 0\n\t"
".word 0\n\t"
".word 0\n\t"
".word 0\n\t"
"0:");
auto& nvm = Nvm (Info.nvm);
// Align to the start of the first page so that we make sure to erase
// all of the target pages.
auto remainder = reinterpret_cast<uint32_t> (Info.destination)
& (Info.page_size - 1);
Info.size += remainder;
Info.destination -= remainder/sizeof (*Info.destination);
if (!unlock(nvm))
goto quit;
nvm.sr = STM32Lx_NVM_SR_ERR_M; // Clear errors
// Enable erasing
nvm.pecr = STM32Lx_NVM_PECR_PROG | STM32Lx_NVM_PECR_ERASE;
if ((nvm.pecr & (STM32Lx_NVM_PECR_PROG | STM32Lx_NVM_PECR_ERASE))
!= (STM32Lx_NVM_PECR_PROG | STM32Lx_NVM_PECR_ERASE))
goto quit;
while (Info.size > 0) {
*Info.destination = 0; // Initiate erase
Info.destination += Info.page_size/sizeof (*Info.destination);
Info.size -= Info.page_size;
}
quit:
lock(nvm);
__asm volatile ("bkpt");
}
/*
Local Variables:
compile-command: "/opt/arm/arm-none-eabi-g++ -mcpu=cortex-m0plus -g -c -std=c++11 -mthumb -o stm32l05x-nvm-prog-erase.o -Os -Wa,-ahndl=stm32l05x-nvm-prog-erase.lst stm32l05x-nvm-prog-erase.cc ; /opt/arm/arm-none-eabi-objdump -d -z stm32l05x-nvm-prog-erase.o | ./dump-to-array.sh > stm32l05x-nvm-prog-erase.stub"
End:
*/

View File

@ -0,0 +1,67 @@
[0x0/2] = 0xe00a,
[0x2/2] = 0x46c0,
[0x4/2] = 0x0000, 0x0000,
[0x8/2] = 0x0000, 0x0000,
[0xc/2] = 0x0000, 0x0000,
[0x10/2] = 0x0000, 0x0000,
[0x14/2] = 0x0000, 0x0000,
[0x18/2] = 0x491a,
[0x1a/2] = 0x8a08,
[0x1c/2] = 0x680c,
[0x1e/2] = 0x684d,
[0x20/2] = 0x1e42,
[0x22/2] = 0x4022,
[0x24/2] = 0x1955,
[0x26/2] = 0x0892,
[0x28/2] = 0x0092,
[0x2a/2] = 0x1aa2,
[0x2c/2] = 0x600a,
[0x2e/2] = 0x2201,
[0x30/2] = 0x68cb,
[0x32/2] = 0x604d,
[0x34/2] = 0x605a,
[0x36/2] = 0x4a14,
[0x38/2] = 0x60da,
[0x3a/2] = 0x4a14,
[0x3c/2] = 0x60da,
[0x3e/2] = 0x4a14,
[0x40/2] = 0x611a,
[0x42/2] = 0x4a14,
[0x44/2] = 0x611a,
[0x46/2] = 0x685a,
[0x48/2] = 0x0792,
[0x4a/2] = 0xd502,
[0x4c/2] = 0x2201,
[0x4e/2] = 0x605a,
[0x50/2] = 0xbe00,
[0x52/2] = 0x4a11,
[0x54/2] = 0x619a,
[0x56/2] = 0x2282,
[0x58/2] = 0x0092,
[0x5a/2] = 0x605a,
[0x5c/2] = 0x685c,
[0x5e/2] = 0x4014,
[0x60/2] = 0x4294,
[0x62/2] = 0xd1f3,
[0x64/2] = 0x0884,
[0x66/2] = 0x00a4,
[0x68/2] = 0x684d,
[0x6a/2] = 0x4a06,
[0x6c/2] = 0x2d00,
[0x6e/2] = 0xdded,
[0x70/2] = 0x2600,
[0x72/2] = 0x6815,
[0x74/2] = 0x602e,
[0x76/2] = 0x6815,
[0x78/2] = 0x192d,
[0x7a/2] = 0x6015,
[0x7c/2] = 0x6855,
[0x7e/2] = 0x1a2d,
[0x80/2] = 0x6055,
[0x82/2] = 0xe7f1,
[0x84/2] = 0x0004, 0x2000,
[0x88/2] = 0xcdef, 0x89ab,
[0x8c/2] = 0x0405, 0x0203,
[0x90/2] = 0xaebf, 0x8c9d,
[0x94/2] = 0x1516, 0x1314,
[0x98/2] = 0x0700, 0x0001,

View File

@ -0,0 +1,113 @@
/* @file stm32l05x-nvm-prog-write.cc
*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2014 Woollysoft
* Written by Marc Singer <elf@woollysoft.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* -----------
DESCRIPTION
-----------
NVM program flash writing stub for STM32L05x, a Cortex-M0+ core.
The stub uses SRAM to host the code fragment and source data to
perform a write to flash.
This stub works with the STM32L1xx given a few options.
If you plan to modify this routine and emit a new stub, make sure
to audit the code. We don't have a stack so we cannot make calls
that save the link pointer. IOW, the inline functions should be be
inlined.
*/
#include <stdint.h>
#include <string.h>
#include "../src/include/stm32lx-nvm.h"
/* Write a block of bytes to flash. The called is responsible for
making sure that the address are aligned and that the count is an
even multiple of words. */
extern "C" void __attribute((naked)) stm32l05x_nvm_prog_write() {
// Leave room for INFO at second word of routine
__asm volatile ("b 0f\n\t"
".align 2\n\t"
".word 0\n\t"
".word 0\n\t"
".word 0\n\t"
".word 0\n\t"
".word 0\n\t"
"0:");
auto& nvm = Nvm (Info.nvm);
if (!unlock(nvm))
goto quit;
nvm.sr = STM32Lx_NVM_SR_ERR_M; // Clear errors
while (Info.size > 0) {
// Either we're not half-page aligned or we have less
// than a half page to write
if (Info.size < Info.page_size/2
|| (reinterpret_cast<uint32_t> (Info.destination)
& (Info.page_size/2 - 1))) {
nvm.pecr = (Info.options & OPT_STM32L1) ? 0
: STM32Lx_NVM_PECR_PROG; // Word programming
size_t c = Info.page_size/2
- (reinterpret_cast<uint32_t> (Info.destination)
& (Info.page_size/2 - 1));
if (c > Info.size)
c = Info.size;
Info.size -= c;
c /= 4;
while (c--) {
uint32_t v = *Info.source++;
*Info.destination++ = v;
if (nvm.sr & STM32Lx_NVM_SR_ERR_M)
goto quit;
}
}
// Or we are writing a half-page(s)
else {
nvm.pecr = STM32Lx_NVM_PECR_PROG
| STM32Lx_NVM_PECR_FPRG; // Half-page prg
size_t c = Info.size & ~(Info.page_size/2 - 1);
Info.size -= c;
c /= 4;
while (c--) {
uint32_t v = *Info.source++;
*Info.destination++ = v;
}
if (nvm.sr & STM32Lx_NVM_SR_ERR_M)
goto quit;
}
}
quit:
lock(nvm);
__asm volatile ("bkpt");
}
/*
Local Variables:
compile-command: "/opt/arm/arm-none-eabi-g++ -mcpu=cortex-m0plus -g -c -std=c++11 -mthumb -o stm32l05x-nvm-prog-write.o -Os -Wa,-ahndl=stm32l05x-nvm-prog-write.lst stm32l05x-nvm-prog-write.cc ; /opt/arm/arm-none-eabi-objdump -d -z stm32l05x-nvm-prog-write.o | ./dump-to-array.sh > stm32l05x-nvm-prog-write.stub"
End:
*/

View File

@ -0,0 +1,99 @@
[0x0/2] = 0xe00a,
[0x2/2] = 0x46c0,
[0x4/2] = 0x0000, 0x0000,
[0x8/2] = 0x0000, 0x0000,
[0xc/2] = 0x0000, 0x0000,
[0x10/2] = 0x0000, 0x0000,
[0x14/2] = 0x0000, 0x0000,
[0x18/2] = 0x2201,
[0x1a/2] = 0x4b2a,
[0x1c/2] = 0x68d9,
[0x1e/2] = 0x604a,
[0x20/2] = 0x4a29,
[0x22/2] = 0x60ca,
[0x24/2] = 0x4a29,
[0x26/2] = 0x60ca,
[0x28/2] = 0x4a29,
[0x2a/2] = 0x610a,
[0x2c/2] = 0x4a29,
[0x2e/2] = 0x610a,
[0x30/2] = 0x684a,
[0x32/2] = 0x0792,
[0x34/2] = 0xd502,
[0x36/2] = 0x2301,
[0x38/2] = 0x604b,
[0x3a/2] = 0xbe00,
[0x3c/2] = 0x4826,
[0x3e/2] = 0x6188,
[0x40/2] = 0x685d,
[0x42/2] = 0x4e20,
[0x44/2] = 0x2d00,
[0x46/2] = 0xddf6,
[0x48/2] = 0x8a32,
[0x4a/2] = 0x0852,
[0x4c/2] = 0x1e54,
[0x4e/2] = 0x4295,
[0x50/2] = 0xdb02,
[0x52/2] = 0x6837,
[0x54/2] = 0x4227,
[0x56/2] = 0xd01d,
[0x58/2] = 0x2602,
[0x5a/2] = 0x8a5f,
[0x5c/2] = 0x4037,
[0x5e/2] = 0x427e,
[0x60/2] = 0x417e,
[0x62/2] = 0x00f6,
[0x64/2] = 0x604e,
[0x66/2] = 0x681e,
[0x68/2] = 0x4034,
[0x6a/2] = 0x1b12,
[0x6c/2] = 0x42aa,
[0x6e/2] = 0xd900,
[0x70/2] = 0x1c2a,
[0x72/2] = 0x1aad,
[0x74/2] = 0x605d,
[0x76/2] = 0x0892,
[0x78/2] = 0x3a01,
[0x7a/2] = 0xd3e1,
[0x7c/2] = 0x689c,
[0x7e/2] = 0x1d25,
[0x80/2] = 0x609d,
[0x82/2] = 0x6825,
[0x84/2] = 0x681c,
[0x86/2] = 0x1d26,
[0x88/2] = 0x601e,
[0x8a/2] = 0x6025,
[0x8c/2] = 0x698c,
[0x8e/2] = 0x4204,
[0x90/2] = 0xd0f2,
[0x92/2] = 0xe7d0,
[0x94/2] = 0x2481,
[0x96/2] = 0x4252,
[0x98/2] = 0x402a,
[0x9a/2] = 0x1aad,
[0x9c/2] = 0x00e4,
[0x9e/2] = 0x604c,
[0xa0/2] = 0x0892,
[0xa2/2] = 0x6075,
[0xa4/2] = 0x3a01,
[0xa6/2] = 0xd308,
[0xa8/2] = 0x689c,
[0xaa/2] = 0x1d25,
[0xac/2] = 0x609d,
[0xae/2] = 0x6825,
[0xb0/2] = 0x681c,
[0xb2/2] = 0x1d26,
[0xb4/2] = 0x601e,
[0xb6/2] = 0x6025,
[0xb8/2] = 0xe7f4,
[0xba/2] = 0x698a,
[0xbc/2] = 0x4202,
[0xbe/2] = 0xd0bf,
[0xc0/2] = 0xe7b9,
[0xc2/2] = 0x46c0,
[0xc4/2] = 0x0004, 0x2000,
[0xc8/2] = 0xcdef, 0x89ab,
[0xcc/2] = 0x0405, 0x0203,
[0xd0/2] = 0xaebf, 0x8c9d,
[0xd4/2] = 0x1516, 0x1314,
[0xd8/2] = 0x0700, 0x0001,

View File

@ -41,6 +41,7 @@ SRC = \
samd.c \
stm32f1.c \
stm32f4.c \
stm32l0.c \
stm32l1.c \
swdptap.c \
target.c \

View File

@ -251,6 +251,7 @@ cortexm_probe(struct target_s *target)
PROBE(stm32f1_probe);
PROBE(stm32f4_probe);
PROBE(stm32l0_probe); /* STM32L0xx & STM32L1xx */
PROBE(stm32l1_probe);
PROBE(lpc11xx_probe);
PROBE(lpc43xx_probe);

203
src/include/stm32lx-nvm.h Normal file
View File

@ -0,0 +1,203 @@
/* @file stm32lx-nvm.h
*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2014 Woollysoft
* Written by Marc Singer <elf@woollysoft.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#if !defined (STM32Lx_NVM_H_INCLUDED)
# define STM32Lx_NVM_H_INCLUDED
/* ----- Includes */
#include <stdint.h>
/* ----- Macros */
/* ----- Types */
enum {
STM32Lx_STUB_PHYS = 0x20000000ul,
STM32Lx_STUB_INFO_PHYS = 0x20000004ul,
STM32Lx_STUB_DATA_PHYS = (0x20000000ul + 1024),
STM32Lx_STUB_DATA_MAX = 2048,
STM32Lx_NVM_OPT_PHYS = 0x1ff80000ul,
STM32Lx_NVM_EEPROM_PHYS = 0x08080000ul,
STM32L0_NVM_PHYS = 0x40022000ul,
STM32L0_NVM_PROG_PAGE_SIZE = 128,
STM32L0_NVM_DATA_PAGE_SIZE = 4,
STM32L0_NVM_OPT_SIZE = 12,
STM32L0_NVM_EEPROM_SIZE = 2*1024,
STM32L1_NVM_PHYS = 0x40023c00ul,
STM32L1_NVM_PROG_PAGE_SIZE = 256,
STM32L1_NVM_DATA_PAGE_SIZE = 4,
STM32L1_NVM_OPT_SIZE = 32,
STM32L1_NVM_EEPROM_SIZE = 16*1024,
STM32Lx_NVM_PEKEY1 = 0x89abcdeful,
STM32Lx_NVM_PEKEY2 = 0x02030405ul,
STM32Lx_NVM_PRGKEY1 = 0x8c9daebful,
STM32Lx_NVM_PRGKEY2 = 0x13141516ul,
STM32Lx_NVM_OPTKEY1 = 0xfbead9c8ul,
STM32Lx_NVM_OPTKEY2 = 0x24252627ul,
STM32Lx_NVM_PECR_OBL_LAUNCH = (1<<18),
STM32Lx_NVM_PECR_ERRIE = (1<<17),
STM32Lx_NVM_PECR_EOPIE = (1<<16),
STM32Lx_NVM_PECR_FPRG = (1<<10),
STM32Lx_NVM_PECR_ERASE = (1<< 9),
STM32Lx_NVM_PECR_FIX = (1<< 8), /* FTDW */
STM32Lx_NVM_PECR_DATA = (1<< 4),
STM32Lx_NVM_PECR_PROG = (1<< 3),
STM32Lx_NVM_PECR_OPTLOCK = (1<< 2),
STM32Lx_NVM_PECR_PRGLOCK = (1<< 1),
STM32Lx_NVM_PECR_PELOCK = (1<< 0),
STM32Lx_NVM_SR_FWWERR = (1<<17),
STM32Lx_NVM_SR_NOTZEROERR = (1<<16),
STM32Lx_NVM_SR_RDERR = (1<<13),
STM32Lx_NVM_SR_OPTVER = (1<<11),
STM32Lx_NVM_SR_SIZERR = (1<<10),
STM32Lx_NVM_SR_PGAERR = (1<<9),
STM32Lx_NVM_SR_WRPERR = (1<<8),
STM32Lx_NVM_SR_READY = (1<<3),
STM32Lx_NVM_SR_HWOFF = (1<<2),
STM32Lx_NVM_SR_EOP = (1<<1),
STM32Lx_NVM_SR_BSY = (1<<0),
STM32Lx_NVM_SR_ERR_M = ( STM32Lx_NVM_SR_WRPERR
| STM32Lx_NVM_SR_PGAERR
| STM32Lx_NVM_SR_SIZERR
| STM32Lx_NVM_SR_NOTZEROERR),
STM32L0_NVM_OPTR_BOOT1 = (1<<31),
STM32L0_NVM_OPTR_WDG_SW = (1<<20),
STM32L0_NVM_OPTR_WPRMOD = (1<<8),
STM32L0_NVM_OPTR_RDPROT_S = (0),
STM32L0_NVM_OPTR_RDPROT_M = (0xff),
STM32L0_NVM_OPTR_RDPROT_0 = (0xaa),
STM32L0_NVM_OPTR_RDPROT_2 = (0xcc),
STM32L1_NVM_OPTR_nBFB2 = (1<<23),
STM32L1_NVM_OPTR_nRST_STDBY = (1<<22),
STM32L1_NVM_OPTR_nRST_STOP = (1<<21),
STM32L1_NVM_OPTR_WDG_SW = (1<<20),
STM32L1_NVM_OPTR_BOR_LEV_S = (16),
STM32L1_NVM_OPTR_BOR_LEV_M = (0xf),
STM32L1_NVM_OPTR_SPRMOD = (1<<8),
STM32L1_NVM_OPTR_RDPROT_S = (0),
STM32L1_NVM_OPTR_RDPROT_M = (0xff),
STM32L1_NVM_OPTR_RDPROT_0 = (0xaa),
STM32L1_NVM_OPTR_RDPROT_2 = (0xcc),
};
#if defined (__cplusplus)
namespace STM32 {
struct NVM {
volatile uint32_t acr;
volatile uint32_t pecr;
volatile uint32_t pdkeyr;
volatile uint32_t pkeyr;
volatile uint32_t prgkeyr;
volatile uint32_t optkeyr;
volatile uint32_t sr;
volatile uint32_t optr;
volatile uint32_t wrprot;
static constexpr uint32_t PKEY1 = 0x89abcdef;
static constexpr uint32_t PKEY2 = 0x02030405;
static constexpr uint32_t PRGKEY1 = 0x8c9daebf;
static constexpr uint32_t PRGKEY2 = 0x13141516;
static constexpr uint32_t OPTKEY1 = 0xfbead9c8;
static constexpr uint32_t OPTKEY2 = 0x24252627;
static constexpr uint32_t PDKEY1 = 0x04152637;
static constexpr uint32_t PDKEY2 = 0xfafbfcfd;
};
static_assert(sizeof (NVM) == 9*4, "NVM size error");
}
using stm32lx_stub_pointer_t = uint32_t*;
#define Nvm(nvm) (*reinterpret_cast<STM32::NVM*>(nvm))
#define Info (*reinterpret_cast<stm32lx_nvm_stub_info*>(STM32Lx_STUB_INFO_PHYS))
namespace {
inline __attribute((always_inline)) bool unlock (STM32::NVM& nvm) {
// Lock guarantees unlock
nvm.pecr = STM32Lx_NVM_PECR_PELOCK;
nvm.pkeyr = STM32::NVM::PKEY1;
nvm.pkeyr = STM32::NVM::PKEY2;
nvm.prgkeyr = STM32::NVM::PRGKEY1;
nvm.prgkeyr = STM32::NVM::PRGKEY2;
return !(nvm.pecr & STM32Lx_NVM_PECR_PRGLOCK);
}
inline __attribute((always_inline)) void lock (STM32::NVM& nvm) {
nvm.pecr = STM32Lx_NVM_PECR_PELOCK; }
}
#else
typedef uint32_t stm32lx_stub_pointer_t;
struct stm32lx_nvm {
volatile uint32_t acr;
volatile uint32_t pecr;
volatile uint32_t pdkeyr;
volatile uint32_t pekeyr;
volatile uint32_t prgkeyr;
volatile uint32_t optkeyr;
volatile uint32_t sr;
volatile uint32_t optr; /* or obr */
volatile uint32_t wrprot; /* or wprot1 */
};
#define STM32Lx_NVM(p) (*(struct stm32lx_nvm*) (p))
#define STM32Lx_NVM_PECR(p) ((uint32_t) &STM32Lx_NVM(p).pecr)
#define STM32Lx_NVM_PEKEYR(p) ((uint32_t) &STM32Lx_NVM(p).pekeyr)
#define STM32Lx_NVM_PRGKEYR(p) ((uint32_t) &STM32Lx_NVM(p).prgkeyr)
#define STM32Lx_NVM_OPTKEYR(p) ((uint32_t) &STM32Lx_NVM(p).optkeyr)
#define STM32Lx_NVM_SR(p) ((uint32_t) &STM32Lx_NVM(p).sr)
#define STM32Lx_NVM_OPTR(p) ((uint32_t) &STM32Lx_NVM(p).optr)
#endif
enum {
OPT_STM32L1 = 1<<1,
};
struct stm32lx_nvm_stub_info {
stm32lx_stub_pointer_t destination;
int32_t size;
stm32lx_stub_pointer_t source;
uint32_t nvm;
uint16_t page_size;
uint16_t options;
} __attribute__((packed));
/* ----- Globals */
/* ----- Prototypes */
#endif /* STM32Lx_NVM_H_INCLUDED */

View File

@ -216,6 +216,7 @@ void target_add_commands(target *t, const struct command_s *cmds, const char *na
bool cortexm_probe(struct target_s *target);
bool stm32f1_probe(struct target_s *target);
bool stm32f4_probe(struct target_s *target);
bool stm32l0_probe(struct target_s *target);
bool stm32l1_probe(struct target_s *target);
bool lmi_probe(struct target_s *target);
bool lpc11xx_probe(struct target_s *target);

1070
src/stm32l0.c Normal file

File diff suppressed because it is too large Load Diff