title: Interrupt handling in C
body: <p>There are two interrupts in this C code below. </p>
  
  <p>The first is by the usage of Key0 and it has the following properties:
  Once Key0 is pressed down, a "D" is written. Shortly thereafter, a "d" is written once the program resumes itself and this is assuming that I am still holding down the button. Upon releasing this button, a "U" is printed out.</p>
  
  <p>Should I not hold the button, a "dU" is printed out making the code into "DdU".</p>
  
  <p>The second is by the usage of a Toggle Key and it has the following properties:
  Once we toggle the toggle key, the program prints a "S". Shortly thereafter, a "s" is printed out.</p>
  
  <p>Now my question is as follows:
  Upon using key0 first and then the togglekey, Key0 is able to interrupt the program with togglekey being ignored. So we simply get "DdU" and both the "S" and "s" is ignored.</p>
  
  <p>Now I do not grasp why vice versa does not apply. It does but only to a certain extent. Upon toggling first, "S" gets written, "D" and "d" gets skipped. "s" Gets written but now comes the confusing part => Why does "U" get written at the end? How come key0's "D" and "d" are ignored but its "U" is not?</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false">
  <div class="snippet-code">
  <pre class="snippet-code-html lang-html prettyprint-override"><code>/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  /* Include header file for alt_irq_register() */
  #include &lt;sys/alt_irq.h&gt;
  
  /* Define the null pointer */
  #define NULL_POINTER ( (void *) 0)
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  void out_char_uart_0( int c )
  {
    /* Wait until transmitter is ready */
    while( (UART_0[2] &amp; 0x40) == 0 );
    /* Now send character */
    UART_0[1] = c &amp; 0xff;
  }
  
  /* This simple subroutine stalls
   * execution for a short while. */
  void somedelay( void )
  {
    int i = DELAYPARAM;
    while( (i = i - 1) &gt; 0);
  }
  
  /* This simple subroutine stalls
   * execution for a long while. */
  void bigdelay( void )
  {
    int j = BIGDELAYPARAM;
    while( (j = j - 1) &gt; 0) somedelay();
  }
  
  void keys_isr( void * context )
  {
    /* Read edge capture register of the de2_pio_keys4 device. */
    int edges = *de2_pio_keys4_edgecap;
    /* Clear edge capture register - writing
     * any value clears all bits. */
    *de2_pio_keys4_edgecap = 0;
    /* If action on KEY0 */
    if( edges &amp; 1 )
    {
      /* If KEY0 is pressed now */
      if( (*de2_pio_keys4_base &amp; 1) == 0 )
      {
        /* Turn on green LED LEDG0
         * in software copy of LED bits. */
        myleds = myleds | 1;
        /* Copy software LED bits to actual LEDs. */
        *de2_pio_greenled9 = myleds;
  
        /* Print an upper-case 'D' using out_char_uart_0. */
        out_char_uart_0( 'D' );
  
        /* Wait a long while */
        bigdelay();
        /* Print a lower-case 'd' using out_char_uart_0. */
        out_char_uart_0( 'd' );
      }
      /* If KEY0 is released now */
      else if( (*de2_pio_keys4_base &amp; 1) != 0 )
      {
        /* Turn off green LED LEDG0
         * in software copy of LED bits. */
        myleds = myleds &amp; 0xffffe;
  
        /* Print an 'U' using out_char_uart_0. */
        out_char_uart_0( 'U' );
        /* Copy software LED bits to actual LEDs. */
        *de2_pio_greenled9 = myleds;
      }
    }
  }
  
  /*
   * Initialize de2_pio_keys4 for interrupts.
   */
  void keysinit_int( void )
  {
    /* Declare a temporary for checking return values
     * from system-calls and library functions. */
    register int ret_val_check;
  
    /* Disable interrupts for de2_pio_keys4,
     * if they were enabled.
     *
     * The function alt_irq_disable returns an int,
     * which always has the value 0.
     * We use a type cast to void to tell the compiler
     * that we really want to ignore the return value. */
    (void) alt_ic_irq_disable( 0, de2_pio_keys4_intindex );
  
    /* Allow interrupts from KEY0 only. */
    *de2_pio_keys4_intmask = 1;
  
    /* Set up Altera's interrupt wrapper for
     * interrupts from the de2_pio_keys4 dev-ice.
     * The function alt_irq_register will enable
     * interrupts from de2_pio_keys4.
     * Return value is zero for success,
     * nonzero for failure. */
    ret_val_check = alt_ic_isr_register(0,de2_pio_keys4_intindex,keys_isr,NULL_POINTER,NULL_POINTER );
    /* If there was an error, terminate the program. */
    if( ret_val_check != 0 ) n2_fatal_error();
  }
  /*
   * Interrupt handler for timer_1.
   * The parameters are ignored here, but are
   * required for correct compilation.
   * The type alt_u32 is an Altera-defined
   * unsigned integer type.
   */
  void timer_isr( void * context )
  {
    *timer_1_status = 0; /* Acknowledge interrupt */
    tick( &amp;mytime );
    puttime( &amp;mytime );
  }
  
  /*
   * Initialize timer_1 for regular interrupts,
   * once every timeout period.
   * The timeout period is defined above,
   * see definition of TIMER_1_TIMEOUT
   */
  void timerinit_int( void )
  {
    /* Declare a local temporary variable
     * for checking return values
     * from system-calls and library functions. */
    register int ret_val_check;
  
    /* Disable interrupts for timer_1,
     * if they were enabled.
     *
     * The function alt_irq_disable returns an int,
     * which always has the value 0.
     * We use a type cast to void to tell the compiler
     * that we really want to ignore the return value. */
    (void) alt_ic_irq_disable( 0, timer_1_intindex );
  
    *timer_1_period_low = TIMER_1_TIMEOUT &amp; 0xffff;
    *timer_1_period_high = TIMER_1_TIMEOUT &gt;&gt; 16;
    *timer_1_control = 7;
    /* START bit (must always be a 1)
     * CONT bit (timer restarts on timeout)
     * ITO bit (interrupt on timeout) */
  
    /* Set up Altera's interrupt wrapper for
     * interrupts from the timer_1 device.
     * Return value is zero for success,
     * nonzero for failure. */
    ret_val_check = alt_ic_isr_register(0,timer_1_intindex,timer_isr,NULL_POINTER,NULL_POINTER );
    /* If there was an error, terminate the program. */
    if( ret_val_check != 0 ) n2_fatal_error();
  }
  
  void irq_handler_toggles(void * context)
  {
   /* Acknowledge the interrupt. */
   *de2_pio_toggles18_edgecap = 1;
  
   /* Light up the LED, print S, wait, turn off the LED and print s. */
   *de2_pio_redled18_base = 1;
   out_char_uart_0('S');
   bigdelay();
   *de2_pio_redled18_base = 0;
   out_char_uart_0('s');
  
  }
  
  void toggles_init()
  {
   /* Declare a temporary for checking return values
    * from system-calls and library functions. */
     register int ret_val_check;
  
     /*
      * Register the interrupt handler.
      */
     ret_val_check = alt_ic_isr_register(0,de2_pio_toggles18_intindex,irq_handler_toggles,NULL_POINTER,NULL_POINTER);
  
   /* If there was an error, terminate the program. */
     if( ret_val_check != 0 ) n2_fatal_error();
  
    /* Set up the mask for the keys.*/
   *de2_pio_toggles18_intmask = 1;
  }
  
  
  int main()
  {
    /* Remove unwanted interrupts.
     * initfix_int is supplied by KTH.
     * A nonzero return value indicates failure. */
    if( intfix() != 0 ) n2_fatal_error();
  
    /* Initialize de2_pio_keys4 for
     * interrupts. */
    keysinit_int();
  
    /* Initialize the toggle switches. */
    toggles_init();
  
    /* Initialize timer_1 for
     * continuous timeout interrupts. */
    timerinit_int();
  
    /* Loop forever. */
    while( 1 )
    {
      out_char_uart_0('_'); /* print an underscore */
  
      /* Programmed delay between underscores.
       * Defined earlier in this file. */
      somedelay();
    }
  }</code></pre>
  </div>
  </div>
  </p>