altos: Broke TeleMetrum GPS reporting by holding the GPS mutex too much
[fw/altos] / src / core / ao_stdio.c
index 656b23c9e88fadc5f65b560af8487692d2b27c89..cd144d6b45899861d1640478ab1bed393f5f98c6 100644 (file)
 #define AO_NUM_STDIOS  (HAS_USB + PACKET_HAS_SLAVE + USE_SERIAL_STDIN)
 
 __xdata struct ao_stdio ao_stdios[AO_NUM_STDIOS];
+
+#if AO_NUM_STDIOS > 1
 __pdata int8_t ao_cur_stdio;
 __pdata int8_t ao_num_stdios;
+#else
+__pdata int8_t ao_cur_stdio;
+#define ao_cur_stdio   0
+#define ao_num_stdios  0
+#endif
 
 void
 putchar(char c)
@@ -96,21 +103,28 @@ flush(void)
 __xdata uint8_t ao_stdin_ready;
 
 char
-getchar(void) __reentrant __critical
+getchar(void) __reentrant
 {
-       char c;
-       int8_t stdio = ao_cur_stdio;
+       int c;
+       int8_t stdio;
 
+       ao_arch_block_interrupts();
+       stdio = ao_cur_stdio;
        for (;;) {
-               c = ao_stdios[stdio].pollchar();
+               c = ao_stdios[stdio]._pollchar();
                if (c != AO_READ_AGAIN)
                        break;
+#if AO_NUM_STDIOS > 1
                if (++stdio == ao_num_stdios)
                        stdio = 0;
                if (stdio == ao_cur_stdio)
+#endif
                        ao_sleep(&ao_stdin_ready);
        }
+#if AO_NUM_STDIOS > 1
        ao_cur_stdio = stdio;
+#endif
+       ao_arch_release_interrupts();
        return c;
 }
 
@@ -121,15 +135,21 @@ ao_echo(void)
 }
 
 int8_t
-ao_add_stdio(char (*pollchar)(void),
+ao_add_stdio(int (*_pollchar)(void),
             void (*putchar)(char),
             void (*flush)(void)) __reentrant
 {
+#if AO_NUM_STDIOS > 1
        if (ao_num_stdios == AO_NUM_STDIOS)
                ao_panic(AO_PANIC_STDIO);
-       ao_stdios[ao_num_stdios].pollchar = pollchar;
+#endif
+       ao_stdios[ao_num_stdios]._pollchar = _pollchar;
        ao_stdios[ao_num_stdios].putchar = putchar;
        ao_stdios[ao_num_stdios].flush = flush;
        ao_stdios[ao_num_stdios].echo = 1;
+#if AO_NUM_STDIOS > 1
        return ao_num_stdios++;
+#else
+       return 0;
+#endif
 }