From 5ae8378f29aedc627f3d69610b4f9fa299045868 Mon Sep 17 00:00:00 2001
From: Oleg Hahm <oleg@hobbykeller.org>
Date: Tue, 27 Aug 2013 18:09:32 +0200
Subject: [PATCH] fixed interrupt implementation (#27)

removed TIMERB0 interrupt (since we don't use SFD information for now)

enable FIFOP interrupt in init_interrupts()
---
 telosb/driver_cc2420.c | 71 ++++++++++++++----------------------------
 1 file changed, 23 insertions(+), 48 deletions(-)

diff --git a/telosb/driver_cc2420.c b/telosb/driver_cc2420.c
index 67d926855f..4ee7ce9d1d 100644
--- a/telosb/driver_cc2420.c
+++ b/telosb/driver_cc2420.c
@@ -94,6 +94,11 @@ int cc2420_get_gio1(void)
     return  CC2420_GIO1;
 }
 
+int cc2420_get_fifop(void)
+{
+    return  CC2420_FIFOP;
+}
+
 int cc2420_get_sfd(void)
 {
     return CC2420_SFD;
@@ -140,9 +145,16 @@ void cc2420_init_interrupts(void)
 {
     unsigned int state = disableIRQ();  /* Disable all interrupts */
     P1SEL &= ~CC2420_FIFOP_PIN;         /* must be <> 1 to use interrupts */
+    P1SEL &= ~CC2420_GIO0_PIN;         /* must be <> 1 to use interrupts */
+
+    /* FIFO <-> GIO0 interrupt */
+    P1IES |= CC2420_GIO0_PIN;      /* Enables external interrupt on falling edge (for GIO0/FIFO) */
+    P1IE |= CC2420_GIO0_PIN;       /* Enable interrupt */
+    P1IFG &= ~CC2420_GIO0_PIN;     /* Clears the interrupt flag */
 
-    P1IE &= ~CC2420_FIFOP_PIN;      /* Disable interrupt for GIO0 */
-    P1IFG &= ~CC2420_FIFOP_PIN;     /* Clear IFG for GIO0 */
+    /* FIFOP <-> Packet interrupt */
+    P1IE |= CC2420_FIFOP_PIN;      /* Enable interrupt for FIFOP */
+    P1IFG &= ~CC2420_FIFOP_PIN;     /* Clear IFG for FIFOP */
     restoreIRQ(state);              /* Enable all interrupts */
 }
 
@@ -185,63 +197,26 @@ void cc2420_spi_init(void)
 /*
  * CC1100 receive interrupt
  */
-interrupt (PORT1_VECTOR) __attribute__ ((naked)) cc2420_isr(void){
+interrupt (PORT1_VECTOR) __attribute__ ((naked)) cc2420_isr(void)
+{
     __enter_isr();
      /* Check IFG */
     if ((P1IFG & CC2420_FIFOP_PIN) != 0) {
         P1IFG &= ~CC2420_FIFOP_PIN;
-        if (cc2420_get_gio0()) {
-            cc2420_rx_irq();
-            DEBUG("rx interrupt");
-        }
-        else {
+        cc2420_rx_irq();
+        DEBUG("rx interrupt");
+    }
+    /* GIO0 is falling => check if FIFOP is high, indicating an RXFIFO overflow */
+    else if ((P1IFG & CC2420_GIO0) != 0) {
+        P1IFG &= ~CC2420_GIO0_PIN;
+        if (cc2420_get_fifop()) {
             cc2420_rxoverflow_irq();
             DEBUG("[CC2420] rxfifo overflow");
         }
     }
-
     else {
         puts("cc2420_isr(): unexpected IFG!");
         /* Should not occur - only GDO1 and GIO1 interrupts are enabled */
     }
     __exit_isr();
 }
-    
-/**
-\brief TimerB CCR1-6 interrupt service routine (taken from OpenWSN)
-*/
-interrupt (TIMERB0_VECTOR) __attribute__ ((naked)) radiotimer_isr(void) {
-   uint16_t tbiv_local;
-   
-   /* reading TBIV returns the value of the highest pending interrupt flag */
-   /* and automatically resets that flag. We therefore copy its value to the */
-   /* tbiv_local local variable exactly once. If there is more than one  */
-   /* interrupt pending, we will reenter this function after having just left */
-   /* it. */
-   tbiv_local = TBIV;
-   
-   switch (tbiv_local) {
-      case 0x0002: /* CCR1 fires */
-        if (TBCCTL1 & CCI) {
-            /* SFD pin is high */
-            DEBUG("start of a frame\n");
-        }
-        else {
-            /* SFD pin is low */
-            DEBUG("end of a frame\n");
-         }
-         break;
-      case 0x0004: /* CCR2 fires */
-         break;
-      case 0x0006: /* CCR3 fires */
-         break;
-      case 0x0008: /* CCR4 fires */
-         break;
-      case 0x000a: /* CCR5 fires */
-         break;
-      case 0x000c: /* CCR6 fires */
-         break;
-      case 0x000e: /* timer overflow */
-         break;
-   }
-}
-- 
GitLab