doc: Add 1.9 release notes
[fw/altos] / src / avr / ao_arch.h
index 96659aaf9c530c92fd16837b0975724da34a0918..6166c50e67f489fddae53c10b1182349adad1e71 100644 (file)
@@ -3,7 +3,8 @@
  *
  * 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; version 2 of the License.
+ * the Free Software Foundation; either version 2 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
 #define AO_STACK_SIZE  116
 #endif
 
+#define AO_PORT_TYPE   uint8_t
+
 /* Various definitions to make GCC look more like SDCC */
 
 #define ao_arch_naked_declare  __attribute__((naked))
 #define ao_arch_naked_define
-#define __pdata
-#define __data
-#define __xdata
-#define __code const
-#define __reentrant
-#define __critical
 #define __interrupt(n)
 #define __at(n)
 
@@ -112,7 +109,6 @@ extern uint8_t      ao_cpu_sleep_disable;
                asm("push r9" "\n\t" "push r8" "\n\t" "push r7" "\n\t" "push r6" "\n\t" "push r5"); \
                asm("push r4" "\n\t" "push r3" "\n\t" "push r2" "\n\t" "push r1" "\n\t" "push r0"); \
                asm("in r0, __SREG__" "\n\t" "push r0");                \
-               sei();                                                  \
        } while (0)
 
 #define ao_arch_save_stack() do {                                      \
@@ -124,16 +120,28 @@ extern uint8_t    ao_cpu_sleep_disable;
 
 #define ao_arch_isr_stack()    /* nothing */
 
-#define ao_arch_cpu_idle() do {                        \
-               if (!ao_cpu_sleep_disable)      \
+/* Idle the CPU (if possible) waiting for an interrupt. Enabling
+ * interrupts and sleeping the CPU must be adjacent to eliminate race
+ * conditions. In all cases, we execute a single nop with interrupts
+ * enabled
+ */
+#define ao_arch_wait_interrupt() do {          \
+               if (!ao_cpu_sleep_disable) {    \
+                       sleep_enable();         \
+                       sei();                  \
                        sleep_cpu();            \
+                       sleep_disable();        \
+               } else {                        \
+                       sei();                  \
+               }                               \
+               ao_arch_nop();                  \
+               cli();                          \
        } while (0)
 
 #define ao_arch_restore_stack() do { \
                uint8_t sp_l, sp_h;                                     \
                sp_l = (uint16_t) ao_cur_task->sp;                      \
                sp_h = ((uint16_t) ao_cur_task->sp) >> 8;               \
-               cli();                                                  \
                asm("out __SP_H__,%0" : : "r" (sp_h) );                 \
                asm("out __SP_L__,%0" : : "r" (sp_l) );                 \
                asm("pop r0"    "\n\t"                                  \
@@ -150,6 +158,9 @@ extern uint8_t      ao_cpu_sleep_disable;
 
 #define ao_arch_critical(b) do { cli(); do { b } while (0); sei(); } while (0)
 
+#define ao_arch_block_interrupts()     cli()
+#define ao_arch_release_interrupts()   sei()
+
 #define AO_TELESCIENCE_NUM_ADC 12
 
 #endif /* _AO_ARCH_H_ */