first cut at turnon scripts for EasyTimer v2
[fw/altos] / src / attiny / ao_async.c
index 9f7fd6d761d8072c7ac665b880d347319aaa47f7..945f4b1414b153867669f056417e10f958bdce2e 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
@@ -32,7 +33,7 @@ ao_async_start(void)
 void
 ao_async_stop(void)
 {
-       LED_PORT &= ~(1 << AO_LED_SERIAL);
+       LED_PORT &= (uint8_t) ~(1 << AO_LED_SERIAL);
 }
 
 void
@@ -44,18 +45,14 @@ ao_async_byte(uint8_t byte)
        uint8_t         bit;
        uint8_t         w_hi, w_lo;
 
-       /*    start           data           stop */
-       w = (0x000 << 0) | (byte << 1) | (0x001 << 9);
+       /*                start           data           stop */
+       w = (uint16_t) ((0x000 << 0) | (byte << 1) | (0x001 << 9));
 
-       w_hi = w >> 8;
-       w_lo = w;
+       w_hi = (uint8_t) (w >> 8);
+       w_lo = (uint8_t) w;
 
        ao_arch_block_interrupts();
 
-#if AO_LED_SERIAL != 4
-#error "expect AO_LED_SERIAL to be 4"
-#endif
-
        /* Ok, this is a bit painful.
         * We need this loop to be precisely timed, which
         * means knowing exactly how many instructions will
@@ -72,18 +69,45 @@ ao_async_byte(uint8_t byte)
                "       andi    %[v], %[led_mask]\n"    // mask to clear LED bit
                "       mov     %[bit], %[w_lo]\n"      // get current data byte
                "       andi    %[bit], 0x01\n"         // get current data bit
-               "       swap    %[bit]\n"               // rotate by 4 (AO_LED_SERIAL is 4)
-               "       andi    %[bit], 0xf0\n"         // mask off other 4 bits
-               "       or      %[v], %[bit]\n"         // add to register
-               "       out     %[port], %[v]\n"        // write current value
-               "       lsr     %[w_hi]\n"              // shift data
-               "       ror     %[w_lo]\n"              //  ...
+#if AO_LED_SERIAL >= 1
+               "       add     %[bit],%[bit]\n"        // shift by one
+#else
+               "       nop\n"
+#endif
+#if AO_LED_SERIAL >= 2
+               "       add     %[bit],%[bit]\n"        // shift by one
+#else
+               "       nop\n"
+#endif
+#if AO_LED_SERIAL >= 3
+               "       add     %[bit],%[bit]\n"        // shift by one
+#else
                "       nop\n"
+#endif
+#if AO_LED_SERIAL >= 4
+               "       add     %[bit],%[bit]\n"        // shift by one
+#else
                "       nop\n"
+#endif
+#if AO_LED_SERIAL >= 5
+               "       add     %[bit],%[bit]\n"        // shift by one
+#else
                "       nop\n"
+#endif
+#if AO_LED_SERIAL >= 6
+               "       add     %[bit],%[bit]\n"        // shift by one
+#else
                "       nop\n"
+#endif
+#if AO_LED_SERIAL >= 7
+               "       add     %[bit],%[bit]\n"        // shift by one
+#else
                "       nop\n"
-
+#endif
+               "       or      %[v], %[bit]\n"         // add to register
+               "       out     %[port], %[v]\n"        // write current value
+               "       lsr     %[w_hi]\n"              // shift data
+               "       ror     %[w_lo]\n"              //  ...
                "       nop\n"
                "       nop\n"
                "       nop\n"