[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[avr-libc-dev] [RFC] Patch to fix various sleep bugs.
From: |
E. Weddington |
Subject: |
[avr-libc-dev] [RFC] Patch to fix various sleep bugs. |
Date: |
Tue, 28 Dec 2004 17:33:51 -0700 |
User-agent: |
Mozilla Thunderbird 0.7.3 (Windows/20040803) |
Hello!
Attached is a patch that I think will fix the following bugs regarding
sleep.h:
#6352
#10489
#11425
It's a bit of a gory change. I would appreciate any looking over to see
if I've missed anything before I commit.
Thanks
Eric
Index: include/avr/sleep.h
===================================================================
RCS file: /cvsroot/avr-libc/avr-libc/include/avr/sleep.h,v
retrieving revision 1.8
diff -u -r1.8 sleep.h
--- include/avr/sleep.h 2 Nov 2004 18:16:07 -0000 1.8
+++ include/avr/sleep.h 29 Dec 2004 00:31:52 -0000
@@ -1,4 +1,5 @@
-/* Copyright (c) 2002,2004 Theodore A. Roth
+/* Copyright (c) 2002, 2004 Theodore A. Roth
+ Copyright (c) 2004 Eric B. Weddington
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -35,38 +36,63 @@
#include <avr/io.h>
-/* Figure out which type of sleep mode the selected device uses (1, 2 or 3
- bits) */
-#if defined(SM) && ! defined(SM0) && ! defined(SM1) && ! defined(SM2)
-# define _SLEEP_TYPE 1
-#elif ! defined(SM) && defined(SM0) && defined(SM1) && ! defined(SM2)
-# define _SLEEP_TYPE 2
-#elif ! defined(SM) && defined(SM0) && defined(SM1) && defined(SM2)
-# define _SLEEP_TYPE 3
+
+/* Define internal sleep types for the various devices. */
+/* Also define some internal masks for use in set_sleep_mode() */
+#if defined(__AVR_ATmega161__)
+
+#define _SLEEP_TYPE 5
+
+#elif defined(__AVR_ATmega162__) || defined(__AVR_ATmega8515__)
+
+#define _SLEEP_TYPE 4
+
+#elif defined(SM) && !defined(SM0) && !defined(SM1) && !defined(SM2)
+
+#define _SLEEP_TYPE 1
+#define _SLEEP_MODE_MASK _BV(SM)
+
+#elif !defined(SM) && defined(SM0) && defined(SM1) && !defined(SM2)
+
+#define _SLEEP_TYPE 2
+#define _SLEEP_MODE_MASK (_BV(SM0) | _BV(SM1))
+
+#elif !defined(SM) && defined(SM0) && defined(SM1) && defined(SM2)
+
+#define _SLEEP_TYPE 3
+#define _SLEEP_MODE_MASK (_BV(SM0) | _BV(SM1) | _BV(SM2))
+
+#else
+
+#error "No SLEEP mode defined for this device."
+
+#endif
+
+
+
+/* Define the internal control register to use for sleep_mode(). */
+#if defined(SMCR)
+
+#define _SLEEP_CONTROL_REG SMCR
+
+#else
+
+#define _SLEEP_CONTROL_REG MCUCR
+
#endif
+
+
/** \defgroup avr_sleep Power Management and Sleep Modes
\code #include <avr/sleep.h>\endcode
Use of the \c SLEEP instruction can allow your application to reduce it's
power comsumption considerably. AVR devices can be put into different
- sleep modes by changing the \c SMn bits of the \c MCU Control Register (
- \c MCUCR ). Refer to the datasheet for the details relating to the device
+ sleep modes. Refer to the datasheet for the details relating to the device
you are using. */
-/* Mask of all the sleep mode bits. */
-
-#if _SLEEP_TYPE == 1
-# define _SLEEP_MODE_MASK _BV(SM)
-#elif _SLEEP_TYPE == 2
-# define _SLEEP_MODE_MASK (_BV(SM0) | _BV(SM1))
-#elif _SLEEP_TYPE == 3
-# define _SLEEP_MODE_MASK (_BV(SM0) | _BV(SM1) | _BV(SM2))
-#else
-# error "No SLEEP mode defined for device."
-#endif
/** \name Sleep Modes
@@ -75,49 +101,69 @@
/* @{ */
-/** \ingroup avr_sleep
- \def SLEEP_MODE_IDLE
- Idle mode. */
-#define SLEEP_MODE_IDLE 0
+/* Define the sleep modes according to the internal sleep types. */
#if _SLEEP_TYPE == 1
+#define SLEEP_MODE_IDLE 0
+#define SLEEP_MODE_PWR_DOWN _BV(SM)
+#endif
-# define SLEEP_MODE_PWR_DOWN _BV(SM)
-
-#elif _SLEEP_TYPE == 2
-# define SLEEP_MODE_ADC _BV(SM0)
-# define SLEEP_MODE_PWR_DOWN _BV(SM1)
-# define SLEEP_MODE_PWR_SAVE (_BV(SM0) | _BV(SM1))
+#if _SLEEP_TYPE == 2
+#define SLEEP_MODE_IDLE 0
+#define SLEEP_MODE_ADC _BV(SM0)
+#define SLEEP_MODE_PWR_DOWN _BV(SM1)
+#define SLEEP_MODE_PWR_SAVE (_BV(SM0) | _BV(SM1))
+#endif
-#else /* _SLEEP_TYPE == 3 */
+#if _SLEEP_TYPE == 3
+/** \ingroup avr_sleep
+ \def SLEEP_MODE_IDLE
+ Idle mode. */
+#define SLEEP_MODE_IDLE 0
/** \ingroup avr_sleep
\def SLEEP_MODE_ADC
ADC Noise Reduction Mode. */
#define SLEEP_MODE_ADC _BV(SM0)
-
/** \ingroup avr_sleep
\def SLEEP_MODE_PWR_DOWN
Power Down Mode. */
#define SLEEP_MODE_PWR_DOWN _BV(SM1)
-
/** \ingroup avr_sleep
\def SLEEP_MODE_PWR_SAVE
Power Save Mode. */
#define SLEEP_MODE_PWR_SAVE (_BV(SM0) | _BV(SM1))
-
/** \ingroup avr_sleep
\def SLEEP_MODE_STANDBY
Standby Mode. */
#define SLEEP_MODE_STANDBY (_BV(SM1) | _BV(SM2))
-
/** \ingroup avr_sleep
\def SLEEP_MODE_EXT_STANDBY
Extended Standby Mode. */
#define SLEEP_MODE_EXT_STANDBY (_BV(SM0) | _BV(SM1) | _BV(SM2))
+#endif
+
+
+#if _SLEEP_TYPE == 4
+#define SLEEP_MODE_IDLE 0
+#define SLEEP_MODE_PWR_DOWN 1
+#define SLEEP_MODE_PWR_SAVE 2
+#define SLEEP_MODE_ADC 3
+#define SLEEP_MODE_STANDBY 4
+#define SLEEP_MODE_EXT_STANDBY 5
+#endif
+
+
+#if _SLEEP_TYPE == 5
+#define SLEEP_MODE_IDLE 0
+#define SLEEP_MODE_PWR_DOWN 1
+#define SLEEP_MODE_PWR_SAVE 2
+#endif
+
+
+
-#endif /* _SLEEP_TYPE == 3 */
/* @} */
@@ -127,37 +173,59 @@
/** \ingroup avr_sleep
- Set the bits in the \c MCUCR to select a sleep mode. */
+ Select a sleep mode. */
#if defined(DOXYGEN)
+
extern void set_sleep_mode (uint8_t mode);
-#else
-# if defined (SMCR)
-# define set_sleep_mode(mode) do { \
- (SMCR = ((SMCR & ~_SLEEP_MODE_MASK) | (mode))) \
-} while (0)
-# else
-# define set_sleep_mode(mode) do { \
- (MCUCR = ((MCUCR & ~_SLEEP_MODE_MASK) | (mode))) \
-} while (0)
-# endif
+
+#elif _SLEEP_TYPE == 5
+
+#define set_sleep_mode(mode) \
+do { \
+ MCUCR = ((MCUCR & ~_BV(SM1)) | ((mode) == SLEEP_MODE_PWR_DOWN || (mode) ==
SLEEP_MODE_PWR_SAVE ? _BV(SM1) : 0)); \
+ EMCUCR = ((EMCUCR & ~_BV(SM0)) | ((mode) == SLEEP_MODE_PWR_SAVE ? _BV(SM0)
: 0)); \
+} while(0)
+
+#elif _SLEEP_TYPE == 4
+
+#define set_sleep_mode(mode) \
+do { \
+ MCUCR = ((MCUCR & ~_BV(SM1)) | ((mode) == SLEEP_MODE_IDLE ? 0 :
_BV(SM1))); \
+ MCUCSR = ((MCUCSR & ~_BV(SM2)) | ((mode) == SLEEP_MODE_STANDBY || (mode)
== SLEEP_MODE_EXT_STANDBY ? _BV(SM2) : 0)); \
+ EMCUCR = ((EMCUCR & ~_BV(SM0)) | ((mode) == SLEEP_MODE_PWR_SAVE || (mode)
== SLEEP_MODE_EXT_STANDBY ? _BV(SM0) : 0)); \
+} while(0)
+
+#elif _SLEEP_TYPE == 3 || _SLEEP_TYPE == 2 || _SLEEP_TYPE == 1
+
+#define set_sleep_mode(mode) \
+do { \
+ _SLEEP_CONTROL_REG = ((_SLEEP_CONTROL_REG & ~_SLEEP_MODE_MASK) | (mode)); \
+} while(0)
+
#endif
+
+
+
/** \ingroup avr_sleep
Put the device in sleep mode. How the device is brought out of sleep mode
depends on the specific mode selected with the set_sleep_mode() function.
See the data sheet for your device for more details. */
-
#if defined(DOXYGEN)
+
extern void sleep_mode (void);
+
#else
-#define sleep_mode() \
+
+#define sleep_mode() \
do { \
- MCUCR |= _BV(SE); \
+ _SLEEP_CONTROL_REG |= _BV(SE); \
__asm__ __volatile__ ("sleep" "\n\t" :: ); \
- MCUCR &= ~_BV(SE); \
+ _SLEEP_CONTROL_REG &= ~_BV(SE); \
} while (0)
+
#endif
/address@hidden/
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [avr-libc-dev] [RFC] Patch to fix various sleep bugs.,
E. Weddington <=