avr-libc-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[avr-libc-dev] Fixing boot.h to use out instead of sts


From: Shaun Jackman
Subject: [avr-libc-dev] Fixing boot.h to use out instead of sts
Date: Fri, 14 Dec 2007 16:29:42 -0700

>From boot.h:
    \todo From email with Marek: On smaller devices (all except ATmega64/128),
    __SPM_REG is in the I/O space, accessible with the shorter "in" and "out"
    instructions - since the boot loader has a limited size, this could be an
    important optimization.

I'm writing a boot-loader that has to fit into the 256 byte
boot-loader space of the 8 kB parts. Here is my proposed solution to
fix this matter. I've only done the __boot_xxx_normal variants, but
the same logic could easily be extended to the __boot_xxx_alternate
and __boot_xxx_extended variants.

Cheers,
Shaun

Index: include/avr/boot.h
===================================================================
RCS file: /sources/avr-libc/avr-libc/include/avr/boot.h,v
retrieving revision 1.26
diff -u -p -r1.26 boot.h
--- include/avr/boot.h  23 Jan 2007 15:32:48 -0000      1.26
+++ include/avr/boot.h  14 Dec 2007 23:14:47 -0000
@@ -187,23 +187,29 @@
 #define __BOOT_RWW_ENABLE         (_BV(SPMEN) | _BV(__COMMON_ASRE))
 #define __BOOT_LOCK_BITS_SET      (_BV(SPMEN) | _BV(BLBSET))

-#define __boot_page_fill_normal(address, data)   \
-({                                               \
-    __asm__ __volatile__                         \
-    (                                            \
-        "movw  r0, %3\n\t"                       \
-        "movw r30, %2\n\t"                       \
-        "sts %0, %1\n\t"                         \
-        "spm\n\t"                                \
-        "clr  r1\n\t"                            \
-        :                                        \
-        : "i" (_SFR_MEM_ADDR(__SPM_REG)),        \
-          "r" ((uint8_t)__BOOT_PAGE_FILL),       \
-          "r" ((uint16_t)address),               \
-          "r" ((uint16_t)data)                   \
-        : "r0", "r30", "r31"                     \
-    );                                           \
-})
+static inline void __spm(uint8_t __command, uint16_t __address)
+{
+    register uint16_t __a asm("r30") = __address;
+    __SPM_REG = __command;
+    __asm__ __volatile__ ("spm" :: "z" (__a));
+}
+
+static inline void __spm_data(uint8_t __command,
+        uint16_t __address, uint16_t __data)
+{
+    register uint16_t __a asm("r30") = __address;
+    register uint16_t __d asm("r0") = __data;
+    __SPM_REG = __command;
+    __asm__ __volatile__
+    (
+        "spm\n\t"
+        "clr __zero_reg__"
+        :: "z" (__a), "r" (__d)
+    );
+}
+
+#define __boot_page_fill_normal(address, data) \
+    __spm_data(__BOOT_PAGE_FILL, address, data)

 #define __boot_page_fill_alternate(address, data)\
 ({                                               \
@@ -245,20 +251,8 @@
     );                                           \
 })

-#define __boot_page_erase_normal(address)        \
-({                                               \
-    __asm__ __volatile__                         \
-    (                                            \
-        "movw r30, %2\n\t"                       \
-        "sts %0, %1\n\t"                         \
-        "spm\n\t"                                \
-        :                                        \
-        : "i" (_SFR_MEM_ADDR(__SPM_REG)),        \
-          "r" ((uint8_t)__BOOT_PAGE_ERASE),      \
-          "r" ((uint16_t)address)                \
-        : "r30", "r31"                           \
-    );                                           \
-})
+#define __boot_page_erase_normal(address) \
+        __spm(__BOOT_PAGE_ERASE, address)

 #define __boot_page_erase_alternate(address)     \
 ({                                               \
@@ -294,20 +288,8 @@
     );                                           \
 })

-#define __boot_page_write_normal(address)        \
-({                                               \
-    __asm__ __volatile__                         \
-    (                                            \
-        "movw r30, %2\n\t"                       \
-        "sts %0, %1\n\t"                         \
-        "spm\n\t"                                \
-        :                                        \
-        : "i" (_SFR_MEM_ADDR(__SPM_REG)),        \
-          "r" ((uint8_t)__BOOT_PAGE_WRITE),      \
-          "r" ((uint16_t)address)                \
-        : "r30", "r31"                           \
-    );                                           \
-})
+#define __boot_page_write_normal(address) \
+        __spm(__BOOT_PAGE_WRITE, address)

 #define __boot_page_write_alternate(address)     \
 ({                                               \




reply via email to

[Prev in Thread] Current Thread [Next in Thread]