/* Betty-TV-Fernbedienung: Interrupt-Routinen */

/*
Bei der ARM-Toolchain kann man mit #pragma arm und #pragma thumb innerhalb einer
Quelldatei den Compilier-Modus umschalten. Bei der Gnu-Toolchain geht das nicht.
Deswegen müssen alle Interrupt-Routinen (die im ARM-Modus zu compilieren sind)
hier in einer separaten Quelle untergebracht werden.

Achtung: der GCC benötigt anstelle "__irq"  dies: "__attribute__ ((interrupt("IRQ")))"
Zur Umdefinition siehe "StdTypes.h"
*/

#include "LPC22xx.h"
#include "StdTypes.h"
#include "interrupts.h"
#include "serial.h"
#include "systemtick.h"
#include "Tasten.h"
#include "events.h"


/* für den ARM-Compiler geben wir dediziert ARM-Code an */

#if !defined (GCC)
#pragma arm
#endif


void __irq Uart0TxService (void)
{ volatile long IIR;
  int si, so;
  si = v24sin;
  so = v24sout;
  VICSoftIntClr = (1<<6);    /* evtl. Soft Int löschen */
  IIR = U0IIR;               /* Ident Register lesen   */
  if ((si!=so) &&            /* wenn es was zu senden gibt     */
      (U0LSR & (1<<5)))      /* und Tx ein Byte vertragen kann */
  {  U0THR = V24puffer[v24sout];        /* Zeichen senden      */
     v24sout = (so+1) & (v24bufsize-1); /* Index weiterstellen */
  }
  VICVectAddr = 0;           /* clear Interrupt             */
}

void __irq Timer0Service (void)
{ int i;

  T0IR  = 0xFF;                            /* IRQ im Timer löschen */
  T0MR0 = T0TC + 10;

  if (T0TC >= 86400000)                    /* wenn 1 Tag um ist */
  { T0TC = 0;
    i = 0;
    while (i<numtimers)
    { if (CurrTimers[i].aEvent)
          CurrTimers[i].endzeit = CurrTimers[i].endzeit - 86400000;
      ++i;
    }
  }

  Tasten_Bonze();
  ++Ticks;
  if ((Ticks==20)||
      (Ticks==40)||
      (Ticks==60)||
      (Ticks==80))  Add_Event(id_200_milli);
  if (Ticks >= 100)
  { Ticks = 0;
    Add_Event(idSekundeUm);
  }

  /* ladbare Timer bearbeiten */
   i = 0;
   while (i<numtimers)
   { if (CurrTimers[i].aEvent)
     { if (CurrTimers[i].endzeit < T0TC)    /* ob abgelaufen */
       {                                    /* hier ggf. Flags auswerten */
         Add_Event(CurrTimers[i].aEvent);
         CurrTimers[i].aEvent = 0;
       }
     }
     ++i;
   }

  VICVectAddr = 0;                         /* clear Interrupt             */
}










