summaryrefslogtreecommitdiff
path: root/ucoo
diff options
context:
space:
mode:
authorNicolas Schodet2015-11-25 17:11:43 +0100
committerNicolas Schodet2019-10-07 00:44:57 +0200
commitcd8dfb2c6cae2cb3c4a9440bb19773cefb1d0eb3 (patch)
treec77322da6186470de532b9ccd9ddd9e2a608094d /ucoo
parentdde0d4cfe6379e628729fe87aa5849db6cc11366 (diff)
ucoo/hal/self_programming: add STM32F1 support
Diffstat (limited to 'ucoo')
-rw-r--r--ucoo/hal/self_programming/Module3
-rw-r--r--ucoo/hal/self_programming/self_programming.hh4
-rw-r--r--ucoo/hal/self_programming/self_programming.stm32f1.cc73
-rw-r--r--ucoo/hal/self_programming/self_programming.stm32f4.cc12
4 files changed, 89 insertions, 3 deletions
diff --git a/ucoo/hal/self_programming/Module b/ucoo/hal/self_programming/Module
index 7b59d98..ac9d125 100644
--- a/ucoo/hal/self_programming/Module
+++ b/ucoo/hal/self_programming/Module
@@ -1 +1,2 @@
-ucoo_hal_self_programming_SOURCES := self_programming.stm32f4.cc
+ucoo_hal_self_programming_SOURCES := self_programming.stm32f4.cc \
+ self_programming.stm32f1.cc
diff --git a/ucoo/hal/self_programming/self_programming.hh b/ucoo/hal/self_programming/self_programming.hh
index 8964fb8..4e06709 100644
--- a/ucoo/hal/self_programming/self_programming.hh
+++ b/ucoo/hal/self_programming/self_programming.hh
@@ -27,6 +27,10 @@
namespace ucoo {
+/// Query flash size.
+int
+self_programming_flash_size ();
+
/// Erase flash, must be aligned on erase size.
void
self_programming_erase (uint32_t addr, int count);
diff --git a/ucoo/hal/self_programming/self_programming.stm32f1.cc b/ucoo/hal/self_programming/self_programming.stm32f1.cc
new file mode 100644
index 0000000..5d84561
--- /dev/null
+++ b/ucoo/hal/self_programming/self_programming.stm32f1.cc
@@ -0,0 +1,73 @@
+// ucoolib - Microcontroller object oriented library. {{{
+//
+// Copyright (C) 2015 Nicolas Schodet
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+//
+// }}}
+#include "ucoo/hal/self_programming/self_programming.hh"
+
+#include <libopencm3/stm32/flash.h>
+#include <libopencm3/stm32/desig.h>
+#include <libopencm3/stm32/dbgmcu.h>
+
+namespace ucoo {
+
+int
+self_programming_flash_size ()
+{
+ return DESIG_FLASH_SIZE * 1024;
+}
+
+void
+self_programming_erase (uint32_t addr, int count)
+{
+ assert (static_cast<int> (addr - FLASH_BASE + count)
+ <= self_programming_flash_size ());
+ uint32_t idcode = DBGMCU_IDCODE & DBGMCU_IDCODE_DEV_ID_MASK;
+ int page_size = idcode >= 0x414 ? 2048 : 1024;
+ assert ((addr & (page_size - 1)) == 0);
+ assert ((count & (page_size - 1)) == 0);
+ while (count)
+ {
+ flash_unlock ();
+ flash_erase_page (addr);
+ flash_lock ();
+ addr += page_size;
+ count -= page_size;
+ }
+ assert (count == 0);
+}
+
+void
+self_programming_write (uint32_t addr, const char *buf, int count)
+{
+ assert (addr % 2 == 0);
+ assert (reinterpret_cast<int> (buf) % 2 == 0);
+ assert (count % 2 == 0);
+ assert (static_cast<int> (addr - FLASH_BASE + count)
+ <= self_programming_flash_size ());
+ flash_unlock ();
+ for (int i = 0; i < count; i += 2)
+ flash_program_half_word (
+ addr + i, *reinterpret_cast<const uint16_t *> (buf + i));
+ flash_lock ();
+}
+
+} // namespace ucoo
diff --git a/ucoo/hal/self_programming/self_programming.stm32f4.cc b/ucoo/hal/self_programming/self_programming.stm32f4.cc
index 9d8aa56..9d352ac 100644
--- a/ucoo/hal/self_programming/self_programming.stm32f4.cc
+++ b/ucoo/hal/self_programming/self_programming.stm32f4.cc
@@ -46,10 +46,17 @@ static const uint32_t sector_addr[] = {
0x81e0000, 0x8200000,
};
+int
+self_programming_flash_size ()
+{
+ return DESIG_FLASH_SIZE * 1024;
+}
+
void
self_programming_erase (uint32_t addr, int count)
{
- assert (addr - sector_addr[0] + count <= DESIG_FLASH_SIZE * 1024);
+ assert (static_cast<int> (addr - sector_addr[0] + count)
+ <= self_programming_flash_size ());
int sector;
for (sector = 0; count && sector < lengthof (sector_addr); sector++)
{
@@ -72,7 +79,8 @@ self_programming_write (uint32_t addr, const char *buf, int count)
assert (addr % 4 == 0);
assert (reinterpret_cast<int> (buf) % 4 == 0);
assert (count % 4 == 0);
- assert (addr - sector_addr[0] + count <= DESIG_FLASH_SIZE * 1024);
+ assert (static_cast<int> (addr - sector_addr[0] + count)
+ <= self_programming_flash_size ());
flash_unlock ();
for (int i = 0; i < count; i += 4)
flash_program_word (addr + i,