+#define ao_arch_save_stack() do { \
+ uint8_t sp_l, sp_h; \
+ asm("in %0,__SP_L__" : "=&r" (sp_l) ); \
+ asm("in %0,__SP_H__" : "=&r" (sp_h) ); \
+ ao_cur_task->sp = (uint8_t *) ((uint16_t) sp_l | ((uint16_t) sp_h << 8)); \
+ } while (0)
+
+#define ao_arch_isr_stack() /* nothing */
+
+/* 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; \
+ asm("out __SP_H__,%0" : : "r" (sp_h) ); \
+ asm("out __SP_L__,%0" : : "r" (sp_l) ); \
+ asm("pop r0" "\n\t" \
+ "out __SREG__, r0"); \
+ asm("pop r0" "\n\t" "pop r1" "\n\t" "pop r2" "\n\t" "pop r3" "\n\t" "pop r4"); \
+ asm("pop r5" "\n\t" "pop r6" "\n\t" "pop r7" "\n\t" "pop r8" "\n\t" "pop r9"); \
+ asm("pop r10" "\n\t" "pop r11" "\n\t" "pop r12" "\n\t" "pop r13" "\n\t" "pop r14"); \
+ asm("pop r15" "\n\t" "pop r16" "\n\t" "pop r17" "\n\t" "pop r18" "\n\t" "pop r19"); \
+ asm("pop r20" "\n\t" "pop r21" "\n\t" "pop r22" "\n\t" "pop r23" "\n\t" "pop r24"); \
+ asm("pop r25" "\n\t" "pop r26" "\n\t" "pop r27" "\n\t" "pop r28" "\n\t" "pop r29"); \
+ asm("pop r30" "\n\t" "pop r31"); \
+ asm("ret"); \
+ } while(0)
+
+#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
+