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

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

[avr-libc-dev] [RFC] Sleeping BOD API


From: Weddington, Eric
Subject: [avr-libc-dev] [RFC] Sleeping BOD API
Date: Thu, 5 Feb 2009 16:10:32 -0700

Hi All,

Below is a patch to include/sleep.h (1.6 branch) that adds functionality to 
disable the BOD for sleep.

The new macro sleep_bod_disable() implements inline assembly, however, I'm not 
sure if what I'm doing is ok, or that I'm somehow abusing gcc's inline assembly 
capabilities. I've looked at the generated code (in several different test 
cases) and so far it looks fine.

I'd like to implement this one soon, so I'd rather not get into deep 
philosophical discussions about this.

Thoughts?

Eric Weddington


Index: include/avr/sleep.h
===================================================================
RCS file: /sources/avr-libc/avr-libc/include/avr/sleep.h,v
retrieving revision 1.17.2.16
diff -u -p -r1.17.2.16 sleep.h
--- include/avr/sleep.h 29 Jan 2009 23:21:24 -0000      1.17.2.16
+++ include/avr/sleep.h 5 Feb 2009 23:06:44 -0000
@@ -102,6 +102,35 @@
     immediately after an \c SEI instruction.  As the intruction right
     after the \c SEI is guaranteed to be executed before an interrupt
     could trigger, it is sure the device will really be put to sleep.
+
+    Some devices have the ability to disable the Brown Out Detector (BOD) 
before 
+    going to disable. This will also reduce power while sleeping. If the
+    specific AVR device has this ability then an additional macro is defined:
+    \c sleep_bod_disable(). This macro generates inlined assembly code
+    that will correctly implement the timed sequence for disabling the BOD
+    before sleeping. However, there is a limited number of cycles after the
+    BOD has been disabled that the device can be put into sleep mode, otherwise
+    the BOD will not truly be disabled. Recommended practice is to disable
+    the BOD (\c sleep_bod_disable()), set the interrupts (\c sei()), and then
+    put the device to sleep (\c sleep_cpu()), like so:
+
+    \code
+    #include <avr/interrupt.h>
+    #include <avr/sleep.h>
+
+    ...
+      set_sleep_mode(<mode>);
+      cli();
+      if (some_condition)
+      {
+        sleep_enable();
+        sleep_bod_disable();
+        sei();
+        sleep_cpu();
+        sleep_disable();
+      }
+      sei();
+    \endcode
 */
 
 
@@ -480,6 +509,32 @@ do {                 \
 #endif
 
 
+#if defined(__DOXYGEN__)
+
+extern void sleep_bod_disable (void);
+
+#else
+
+#if defined(BODS) && defined(BODSE)
+
+#define sleep_bod_disable()  \
+(__extension__({             \
+    __asm__ __volatile__ (   \
+        "ori  %0,%1" \
+        : "+d" (MCUCR) \
+        : "i" (_BV(BODS) | _BV(BODSE)) \
+    ); \
+    __asm__ __volatile__ (   \
+        "andi  %0,%1" \
+        : "=d" (MCUCR) \
+        : "i" (~_BV(BODSE)) \
+    ); \
+}))
+
+#endif
+
+#endif
+
 
 /address@hidden/
 




reply via email to

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