Explain what the global variables do.
[dmxpainter.git] / src / dmx.c
index 58ba6a5..934cb2f 100644 (file)
--- a/src/dmx.c
+++ b/src/dmx.c
@@ -5,96 +5,42 @@
 #include "buf.h"
 
 /*********************************************************************/
+/* Declaration of private global variables.                          */
 
-void enable_timer(int8_t us)
-{
-  // Prepare timer counter.
-  TCNT0 = 0xFF - 2 * us;
-
-  // Enable timer, use a frequency prescaler of 8 (p72).
-  bits_mask_on(TCCR0, (1 << CS01));
-}
-
-void disable_timer(void)
-{
-  // Disable timer (p72).
-  bits_mask_off(TCCR0, (1 << CS02) | (1 << CS01) | (1 << CS00));
-}
-
-
-void enable_trigger(void)
-{
-  // Enable interrupt triggered by edge on pin.
-  bits_on(GICR, INT0);
-}
-
-void disable_trigger(void)
-{
-  // Disable interrupt triggered by edge on pin.
-  bits_off(GICR, INT0);
-}
-
-void enable_usart(void)
-{
-  // Enable RXD.
-  bits_on(UCSRB, RXEN);
-}
-
-void disable_usart(void)
-{
-  // Disable RXD.
-  bits_off(UCSRB, RXEN);
-}
-
-/*********************************************************************/
-
-void dmx_init(void)
-{
-  // Configure both pins as input.
-  pin_in(PIN_DMX_INT);
-  pin_in(PIN_DMX_RXD);
-
-  // Initialize USART (p156) with
-  // 250kbaud    (UBRR = 3),
-  // 8 data bits (UCSZ = 011),
-  // 2 stop bits (USBS = 1),
-  // no parity   (UPM  = 00).
-  UBRRL = F_CPU / (16 * 250e3) - 1;
-  UBRRH = (0 << URSEL) | 0;
-  UCSRC = (1 << URSEL)
-        | bits_value(UCSZ1) | bits_value(UCSZ0)
-        | bits_value(USBS);
-  // Enable USART RXD interrupt (and clear UCSZ2 and *XEN).
-  UCSRB = bits_value(RXCIE);
-
-  // Enable timer interrupt (p72).
-  bits_on(TIMSK, TOIE0);
-
-  // Trigger INT0 on any edge (ISC0 = 01, p67).
-  bits_on(MCUCR, ISC00);
-  // But explicitly disable it for now.
-  disable_trigger();
-}
-
-void dmx_exec(void)
-{
-  // Just enable the trigger for the pin.
-  enable_trigger();
-}
-
-/*********************************************************************/
-
-static enum state {
+/**
+ * The DMX parser is driven by a state machine using these states.
+ */
+enum state {
   STATE_IDLE,
   STATE_SYNC,
   STATE_WAIT,
   STATE_RECV,
   STATE_STOR
 };
+/**
+ * The current state of the DMX state machine.
+ */
 static volatile enum state state_;
+/**
+ * Index of current DMX frame (between 0 and 512).
+ */
 static          int16_t index_;
 
 
+/*********************************************************************/
+/* Declaration of private functions.                                 */
+
+static void enable_timer(int8_t us);
+static void disable_timer(void);
+static void enable_trigger(void);
+static void disable_trigger(void);
+static void enable_usart(void);
+static void disable_usart(void);
+
+
+/*********************************************************************/
+/* Implementation of public interrupts.                              */
+
 void dmx_int_timer0_ovf(void)
 {
   // Disable this interrupt.
@@ -108,7 +54,7 @@ void dmx_int_timer0_ovf(void)
     }
     case STATE_RECV:
     case STATE_STOR: {
-      // We got a timeout, back to Idle.
+    // We got a timeout, back to Idle.
       disable_usart();
       enable_trigger();
       state_ = STATE_IDLE;
@@ -118,7 +64,6 @@ void dmx_int_timer0_ovf(void)
       break;
     }
   }
-  
 }
 
 void dmx_int_ext(void)
@@ -170,8 +115,8 @@ void dmx_int_usart_rxc(void)
     case STATE_RECV: {
       // TODO: Check for valid start byte.
       /*if (rxd != 0x00) {
-        goto last;
-      }*/
+      goto last;
+    }*/
 
       // Switch to data storage.
       index_ = 0;
@@ -197,8 +142,90 @@ void dmx_int_usart_rxc(void)
   return;
 last:
   // Either an invalid or the last frame appeared, stop DMX.
-  disable_usart();
+    disable_usart();
   enable_trigger();
   state_ = STATE_IDLE;
   return;
 }
+
+
+/*********************************************************************/
+/* Implementation of public functions.                               */
+
+void dmx_init(void)
+{
+  // Configure both pins as input.
+  pin_in(PIN_DMX_INT);
+  pin_in(PIN_DMX_RXD);
+
+  // Initialize USART (p156) with
+  // 250kbaud    (UBRR = 3),
+  // 8 data bits (UCSZ = 011),
+  // 2 stop bits (USBS = 1),
+  // no parity   (UPM  = 00).
+  UBRRL = F_CPU / (16 * 250e3) - 1;
+  UBRRH = (0 << URSEL) | 0;
+  UCSRC = (1 << URSEL)
+        | bits_value(UCSZ1) | bits_value(UCSZ0)
+        | bits_value(USBS);
+  // Enable USART RXD interrupt (and clear UCSZ2 and *XEN).
+  UCSRB = bits_value(RXCIE);
+
+  // Enable timer interrupt (p72).
+  bits_on(TIMSK, TOIE0);
+
+  // Trigger INT0 on any edge (ISC0 = 01, p67).
+  bits_on(MCUCR, ISC00);
+  // But explicitly disable it for now.
+  disable_trigger();
+}
+
+void dmx_exec(void)
+{
+  // Just enable the trigger for the pin.
+  enable_trigger();
+}
+
+
+/*********************************************************************/
+/* Implementation of private functions.                              */
+
+static void enable_timer(int8_t us)
+{
+  // Prepare timer counter.
+  TCNT0 = 0xFF - 2 * us;
+
+  // Enable timer, use a frequency prescaler of 8 (p72).
+  bits_mask_on(TCCR0, (1 << CS01));
+}
+
+static void disable_timer(void)
+{
+  // Disable timer (p72).
+  bits_mask_off(TCCR0, (1 << CS02) | (1 << CS01) | (1 << CS00));
+}
+
+
+static void enable_trigger(void)
+{
+  // Enable interrupt triggered by edge on pin.
+  bits_on(GICR, INT0);
+}
+
+static void disable_trigger(void)
+{
+  // Disable interrupt triggered by edge on pin.
+  bits_off(GICR, INT0);
+}
+
+static void enable_usart(void)
+{
+  // Enable RXD.
+  bits_on(UCSRB, RXEN);
+}
+
+static void disable_usart(void)
+{
+  // Disable RXD.
+  bits_off(UCSRB, RXEN);
+}