changeset 114:17b0511b243c

nuc-fw: continuing lowest-level BSP integration
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Thu, 24 Oct 2013 02:47:14 +0000
parents 3b2e941043d8
children 1e41550feec5
files nuc-fw/bsp/Makefile nuc-fw/bsp/timer.c nuc-fw/bsp/timer1.c nuc-fw/bsp/timer2.c nuc-fw/sysglue/Makefile nuc-fw/sysglue/irqfiq.S
diffstat 6 files changed, 705 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/nuc-fw/bsp/Makefile	Sun Oct 20 21:12:41 2013 +0000
+++ b/nuc-fw/bsp/Makefile	Thu Oct 24 02:47:14 2013 +0000
@@ -4,9 +4,9 @@
 AR=	arm-elf-ar
 RANLIB=	arm-elf-ranlib
 
-IOBJS=	armio.o inth.o niq32.o
+IOBJS=	niq32.o
 
-XTOBJS=	clkm.o niq.o
+XTOBJS=	armio.o clkm.o inth.o niq.o timer.o timer1.o timer2.o
 
 XOBJS=	${XTOBJS}
 AOBJS=	${IOBJS}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nuc-fw/bsp/timer.c	Thu Oct 24 02:47:14 2013 +0000
@@ -0,0 +1,267 @@
+/*******************************************************************************
+            TEXAS INSTRUMENTS INCORPORATED PROPRIETARY INFORMATION           
+                                                                             
+   Property of Texas Instruments -- For  Unrestricted  Internal  Use  Only 
+   Unauthorized reproduction and/or distribution is strictly prohibited.  This 
+   product  is  protected  under  copyright  law  and  trade  secret law as an 
+   unpublished work.  Created 1987, (C) Copyright 1997 Texas Instruments.  All 
+   rights reserved.                                                            
+                  
+                                                           
+   Filename         : timer.c
+
+   Description      : timer.c
+
+   Project          : drivers
+
+   Author           : pmonteil@tif.ti.com  Patrice Monteil.
+
+   Version number   : 1.3
+
+   Date and time    : 07/23/98 16:25:32
+   Previous delta   : 07/23/98 16:25:32
+
+   SCCS file        : /db/gsm_asp/db_ht96/dsp_0/gsw/rel_0/mcu_l1/release1.5/mod/emu/EMU_MCMP/eva3_drivers/source/SCCS/s.timer.c
+
+   Sccs Id  (SID)       : '@(#) timer.c 1.3 07/23/98 16:25:32 '
+
+ 
+*****************************************************************************/
+
+#include "../include/sys_types.h"
+
+#include "mem.h"
+#include "iq.h"
+#include "timer.h"
+
+
+/*--------------------------------------------------------------
+ *  TIMER_Read()
+ *--------------------------------------------------------------
+ * Parameters :	num of the register to be read
+ * Return     :value of the timer register read
+ * Functionality :  read one of the TIMER register
+ *--------------------------------------------------------------*/
+SYS_UWORD16 TIMER_Read (unsigned short regNum)
+{
+   SYS_UWORD16 timerReg;
+
+   switch (regNum) {
+   case 0:
+      timerReg = ( * (volatile SYS_UWORD16 *) TIMER_CNTL_REG) & TIMER_CNTL_MASK;
+      break;
+   case 1:
+      timerReg = *(volatile SYS_UWORD16 *) TIMER_READ_REG;
+      break;
+   case 2:
+      timerReg = ( * (volatile SYS_UWORD16 *) TIMER_MODE_REG) & TIMER_MODE_MASK;
+      break;
+   default:
+       break;
+   }
+   return(timerReg);
+}
+/*--------------------------------------------------------------
+ *  TM_ResetTimer()
+ *--------------------------------------------------------------
+ * Parameters : timer number (1 or 2) 
+ *              timer value, reload yes or not, scale
+ * Return     : none
+ * Functionality : Give the timewr state
+ *--------------------------------------------------------------*/
+void  TM_ResetTimer (SYS_UWORD16 timerNum,  SYS_UWORD16 countValue, 
+                     SYS_UWORD16 autoReload, SYS_UWORD16 clockScale)
+{
+     volatile SYS_UWORD16 *cntl;
+    
+    if (timerNum == 1) 
+    {
+        cntl = (volatile SYS_UWORD16 *) TIMER1_CNTL; 
+
+        *cntl &= ~(START_STOP | PTV);        /* stop and reset values */
+
+        (autoReload) ? (*cntl |= AR) : (*cntl &= ~AR);
+
+        *cntl |= (clockScale << 2 );
+
+        /*load the value */
+        *(volatile SYS_UWORD16 *) TIMER1_LOAD_TIM = countValue;
+
+        *cntl |= START_STOP;    
+    }
+    else 
+    {
+        cntl = (volatile SYS_UWORD16 *) TIMER2_CNTL; 
+
+        *cntl &= ~(START_STOP | PTV);        /* stop and reset values */
+
+        (autoReload) ? (*cntl |= AR) : (*cntl &= ~AR);
+
+        *cntl |= (clockScale << 2 );
+         
+        /*load the value */
+        *(volatile SYS_UWORD16 *) TIMER2_LOAD_TIM = countValue;
+
+        *cntl |= START_STOP;    
+    }
+}
+
+/*
+ *  TM_StopTimer
+ *
+ * Parameters : timer number (1 or 2)
+ */
+void   TM_StopTimer (int timerNum)
+{
+    volatile SYS_UWORD16 *cntl;
+
+    if (timerNum == 1) 
+    {
+        cntl = (volatile SYS_UWORD16 *) TIMER1_CNTL;
+    }
+    else
+    {
+        cntl = (volatile SYS_UWORD16 *) TIMER2_CNTL;
+    }
+    *cntl &= ~START_STOP;
+}   
+
+/*
+ * TM_ReadTimer
+ *
+ * Returns current timer value
+ *
+ * Parameters : timer number (1 or 2)
+ *
+ */
+SYS_UWORD16 TM_ReadTimer (int timerNum)
+{
+    if (timerNum == 1) 
+    {
+        return (* (SYS_UWORD16 *) TIMER1_READ_TIM);
+    }
+    else
+    {
+        return (* (SYS_UWORD16 *) TIMER2_READ_TIM);
+    }
+}   
+
+
+/*
+ * TM_StartTimer
+ *
+ * Parameters : timer number (1 or 2)
+ *
+ */
+void TM_StartTimer (int timerNum)
+{
+    volatile SYS_UWORD16 *cntl;
+    
+    if (timerNum == 1) 
+    {
+        cntl = (volatile SYS_UWORD16 *) TIMER1_CNTL;
+    }
+    else
+    {
+        cntl = (volatile SYS_UWORD16 *) TIMER2_CNTL;
+    }
+    *cntl |= START_STOP;
+}   
+
+void TM_DisableWatchdog (void)
+{
+   /* volatile variable needed due C to optimization */
+   volatile SYS_UWORD16 *reg = (volatile SYS_UWORD16 *) TIMER_MODE_REG;
+
+   *reg = 0xf5;                
+   *reg = 0xa0;
+}
+
+
+ /*
+ * TM_EnableWatchdog
+ * 
+ */
+void TM_EnableWatchdog(void)
+{
+    * ((volatile SYS_UWORD16 *) TIMER_MODE_REG) = TIMER_WDOG;
+}
+
+/*
+ * TM_ResetWatchdog
+ * 
+ * Parameter : Tick count 
+ * Use a different value each time, otherwise watchdog bites 
+ */
+void TM_ResetWatchdog(SYS_UWORD16 count)
+{
+  * ((volatile SYS_UWORD16 *) TIMER_LOAD_REG) = count;
+}
+
+/*
+* TM_EnableTimer (int TimerNum)
+* 
+* Parameter : TimerNum : timer to enable (timer1 or timer2)
+*
+*/
+void TM_EnableTimer (int TimerNum)
+{
+     volatile SYS_UWORD16 *cntl;
+    
+    if (TimerNum == 1) 
+    {
+        cntl = (volatile SYS_UWORD16 *) TIMER1_CNTL;
+    }
+    else
+    {
+        cntl = (volatile SYS_UWORD16 *) TIMER2_CNTL;
+    }
+    *cntl |= TIMER_CLK_EN;
+}
+
+/*
+* TM_DisableTimer (int TimerNum)
+* 
+* Parameter : TimerNum : timer to enable (timer1 or timer2)
+*
+*/
+void TM_DisableTimer (int TimerNum)
+{
+     volatile SYS_UWORD16 *cntl;
+    
+    if (TimerNum == 1) 
+    {
+        cntl = (volatile SYS_UWORD16 *) TIMER1_CNTL;
+    }
+    else
+    {
+        cntl = (volatile SYS_UWORD16 *) TIMER2_CNTL;
+    }
+    *cntl &= ~TIMER_CLK_EN;
+}
+
+/*--------------------------------------------------------------
+ *  TIMER_ReadValue()
+ *--------------------------------------------------------------
+ * Parameters : none
+ * Return     :	none
+ * Functionality :  Read timer value
+ *--------------------------------------------------------------*/
+
+unsigned short TIMER_ReadValue (void)
+{
+  return(* (SYS_UWORD16 *) TIMER_READ_REG);
+}
+
+/*--------------------------------------------------------------
+ *  TIMER_WriteValue()
+ *--------------------------------------------------------------
+ * Parameters : none
+ * Return     :	none
+ * Functionality :  Write timer value
+ *--------------------------------------------------------------*/
+
+void TIMER_WriteValue (SYS_UWORD16 value)
+{
+  * (SYS_UWORD16 *) TIMER_LOAD_REG = value;	/*load the value */
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nuc-fw/bsp/timer1.c	Thu Oct 24 02:47:14 2013 +0000
@@ -0,0 +1,180 @@
+/******************************************************************************
+            TEXAS INSTRUMENTS INCORPORATED PROPRIETARY INFORMATION           
+                                                                             
+   Property of Texas Instruments -- For  Unrestricted  Internal  Use  Only 
+   Unauthorized reproduction and/or distribution is strictly prohibited.  This 
+   product  is  protected  under  copyright  law  and  trade  secret law as an 
+   unpublished work.  Created 1987, (C) Copyright 1997 Texas Instruments.  All 
+   rights reserved.                                                            
+                  
+                                                           
+   Filename       	: timer1.c
+
+   Description    	: Set of useful functions for TIMER module test cases 
+
+   Project        	: drivers
+
+   Author         	: pmonteil@tif.ti.com  Patrice Monteil.
+
+   Version number	: 1.4
+
+   Date and time	: 08/18/00 14:42:35
+
+   Previous delta 	: 06/30/00 11:40:43
+
+   SCCS file      	: /db/gsm_asp/db_ht96/dsp_0/gsw/rel_0/mcu_l1/release_gprs/RELEASE_GPRS/drivers1/common/SCCS/s.timer1.c
+
+   Sccs Id  (SID)       : '@(#) timer1.c 1.4 08/18/00 14:42:35 '
+
+ 
+*****************************************************************************/
+
+#include "../include/sys_types.h"
+
+#include "mem.h" 
+#include "timer1.h" 
+
+/*--------------------------------------------------------------*/
+/*  Dtimer1_Get_cntlreg()					*/
+/*--------------------------------------------------------------*/
+/* Parameters : none						*/
+/* Return     :	none						*/
+/* Functionality : read one of the TIMER register		*/
+/*--------------------------------------------------------------*/
+
+SYS_UWORD16 Dtimer1_Get_cntlreg(void)
+{
+    SYS_UWORD16 timerReg;
+
+    timerReg = (( * (volatile SYS_UWORD16 *) D_TIMER_CNTL) & D_TIMER_CNTL_MASK);
+    return(timerReg);
+}
+
+
+/*--------------------------------------------------------------*/
+/*  Dtimer_Init_cntl()						*/
+/*--------------------------------------------------------------*/
+/* Parameters :start/stop,reload yes/no,pre scale,ext clk on/off*/
+/* Return     :	none						*/
+/* Functionality : initialize the timer start, autoreload, Ptv 	*/
+/*		   and clock enable				*/
+/*--------------------------------------------------------------*/
+
+void Dtimer1_Init_cntl (SYS_UWORD16 St, SYS_UWORD16 Reload, SYS_UWORD16 clockScale, SYS_UWORD16 clkon)
+{
+    SYS_UWORD16 cntl = * (volatile SYS_UWORD16 *) D_TIMER_CNTL; 
+
+
+    cntl &= ~(D_TIMER_ST | D_TIMER_PTV);    	/* stop and reset values */
+
+    (Reload) ? (cntl |= D_TIMER_AR) : (cntl &= ~D_TIMER_AR);
+
+    cntl |= (clockScale << 2 );
+
+    cntl |= ( clkon << 5 );
+
+
+    * (volatile SYS_UWORD16 *) D_TIMER_LOAD = St;
+
+    * (volatile SYS_UWORD16 *) D_TIMER_CNTL = cntl;
+    }
+
+/*--------------------------------------------------------------*/
+/*  Dtimer1_AR()						*/
+/*--------------------------------------------------------------*/
+/* Parameters :start/stop,reload yes/no,pre scale,ext clk on/off*/
+/* Return     :	none						*/
+/* Functionality : set the AR bit Ar = 0 | 1			*/
+/*--------------------------------------------------------------*/
+
+void Dtimer1_AR(SYS_UWORD16 Ar)
+{
+SYS_UWORD16 cntl = * (volatile SYS_UWORD16 *) D_TIMER_CNTL; 
+
+ cntl &= ~(D_TIMER_ST);			/* stop the timer */
+
+ cntl &= ~(D_TIMER_AR);
+
+ cntl |= ( Ar << 1 );
+
+ * (volatile SYS_UWORD16 *) D_TIMER_CNTL = cntl;
+}
+
+/*--------------------------------------------------------------*/
+/*  Dtimer1_PTV()						*/
+/*--------------------------------------------------------------*/
+/* Parameters : pre scale					*/
+/* Return     :	none						*/
+/* Functionality : set the Ptv bits Ptv = 0 => 7 		*/
+/*--------------------------------------------------------------*/
+
+void Dtimer1_PTV(SYS_UWORD16 Ptv)
+{
+SYS_UWORD16 cntl = * (volatile SYS_UWORD16 *) D_TIMER_CNTL;	
+ 
+ cntl &= ~(D_TIMER_ST);			/* stop the timer */
+
+ cntl &= ~(D_TIMER_PTV);		/* Ptv[4:0] set to 0 */
+
+ cntl |= ( Ptv << 2 );
+
+ * (volatile SYS_UWORD16 *) D_TIMER_CNTL = cntl;
+}
+
+/*--------------------------------------------------------------*/
+/*     Dtimer1_Clken()						*/
+/*--------------------------------------------------------------*/
+/* Parameters : ext clk on/off					*/
+/* Return     :	none						*/
+/* Functionality :  set the clock_enable bit En = 0 | 1 	*/
+/*--------------------------------------------------------------*/
+
+void Dtimer1_Clken(SYS_UWORD16 En)
+{
+SYS_UWORD16 cntl = * (volatile SYS_UWORD16 *) D_TIMER_CNTL;
+ 
+ cntl &= ( ~D_TIMER_CLK_EN);
+
+ cntl |= ( En << 5 );
+
+ * (volatile SYS_UWORD16 *) D_TIMER_CNTL = cntl;
+}
+
+
+
+/*--------------------------------------------------------------*/
+/*  Dtimer_Start()						*/
+/*--------------------------------------------------------------*/
+/* Parameters : on/off						*/
+/* Return     :	none						*/
+/* Functionality :  Start or stop the timer 			*/
+/*--------------------------------------------------------------*/
+
+void  Dtimer1_Start (SYS_UWORD16 startStop)
+{
+    (startStop == D_TIMER_ST) ? 	
+	((* (SYS_UWORD16 *) D_TIMER_CNTL) |=  D_TIMER_ST) :	/* condition vrai */
+ 	((* (SYS_UWORD16 *) D_TIMER_CNTL) &= ~D_TIMER_ST);    	/* condition fausse */
+}
+
+/*--------------------------------------------------------------*/
+/*  Dtimer_ReadValue()						*/
+/*--------------------------------------------------------------*/
+/* Parameters : on/off						*/
+/* Return     :	none						*/
+/* Functionality :  Read timer value				*/
+/*--------------------------------------------------------------*/
+SYS_UWORD16 Dtimer1_ReadValue (void)
+{
+ return(* (SYS_UWORD16 *) D_TIMER_READ);
+}
+
+/*--------------------------------------------------------------*/
+/* Parameters : on/off						*/
+/* Return     :	none						*/
+/* Functionality :  Write timer value				*/
+/*--------------------------------------------------------------*/
+void Dtimer1_WriteValue (SYS_UWORD16 value)
+{
+ (* (SYS_UWORD16 *) D_TIMER_LOAD) = value;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nuc-fw/bsp/timer2.c	Thu Oct 24 02:47:14 2013 +0000
@@ -0,0 +1,182 @@
+/******************************************************************************
+            TEXAS INSTRUMENTS INCORPORATED PROPRIETARY INFORMATION           
+                                                                             
+   Property of Texas Instruments -- For  Unrestricted  Internal  Use  Only 
+   Unauthorized reproduction and/or distribution is strictly prohibited.  This 
+   product  is  protected  under  copyright  law  and  trade  secret law as an 
+   unpublished work.  Created 1987, (C) Copyright 1997 Texas Instruments.  All 
+   rights reserved.                                                            
+                  
+                                                           
+   Filename       	: timer2.c
+
+   Description    	: Set of useful functions for TIMER module test cases 
+
+   Project        	: drivers
+
+   Author         	: pmonteil@tif.ti.com  Patrice Monteil.
+   Version number	: 1.3
+
+   Date and time	: 08/18/00 14:42:39
+
+   Previous delta 	: 07/10/00 16:15:18
+
+   SCCS file      	: /db/gsm_asp/db_ht96/dsp_0/gsw/rel_0/mcu_l1/release_gprs/RELEASE_GPRS/drivers1/common/SCCS/s.timer2.c
+
+   Sccs Id  (SID)       : '@(#) timer2.c 1.3 08/18/00 14:42:39 '
+
+
+ 
+*****************************************************************************/
+
+#include "../include/sys_types.h"
+
+#include "mem.h" 
+#include "timer2.h" 
+
+/*--------------------------------------------------------------*/
+/*  Dtimer2_Get_cntlreg()					*/
+/*--------------------------------------------------------------*/
+/* Parameters : none						*/
+/* Return     :	none						*/
+/* Functionality : read one of the TIMER register		*/
+/*--------------------------------------------------------------*/
+
+SYS_UWORD16 Dtimer2_Get_cntlreg(void)
+{
+    SYS_UWORD16 timerReg;
+
+    timerReg = (( * (volatile SYS_UWORD16 *) D_TIMER_CNTL) & D_TIMER_CNTL_MASK);
+    return(timerReg);
+}
+
+
+/*--------------------------------------------------------------*/
+/*  Dtimer2_Init_cntl()						*/
+/*--------------------------------------------------------------*/
+/* Parameters :start/stop,reload yes/no,pre scale,ext clk on/off*/
+/* Return     :	none						*/
+/* Functionality : initialize the timer start, autoreload, Ptv 	*/
+/*		   and clock enable				*/
+/*--------------------------------------------------------------*/
+
+void Dtimer2_Init_cntl (SYS_UWORD16 St, SYS_UWORD16 Reload, SYS_UWORD16 clockScale, SYS_UWORD16 clkon)
+{
+    SYS_UWORD16 cntl = * (volatile SYS_UWORD16 *) D_TIMER_CNTL; 
+
+
+    cntl &= ~(D_TIMER_ST | D_TIMER_PTV);    	/* stop and reset values */
+
+    (Reload) ? (cntl |= D_TIMER_AR) : (cntl &= ~D_TIMER_AR);
+
+    cntl |= (clockScale << 2 );
+
+    cntl |= ( clkon << 5 );
+
+
+    * (volatile SYS_UWORD16 *) D_TIMER_LOAD = St;
+
+    * (volatile SYS_UWORD16 *) D_TIMER_CNTL = cntl;
+    }
+
+/*--------------------------------------------------------------*/
+/*  Dtimer2_AR()						*/
+/*--------------------------------------------------------------*/
+/* Parameters :start/stop,reload yes/no,pre scale,ext clk on/off*/
+/* Return     :	none						*/
+/* Functionality : set the AR bit Ar = 0 | 1			*/
+/*--------------------------------------------------------------*/
+
+void Dtimer2_AR(SYS_UWORD16 Ar)
+{
+SYS_UWORD16 cntl = * (volatile SYS_UWORD16 *) D_TIMER_CNTL; 
+
+ cntl &= ~(D_TIMER_ST);			/* stop the timer */
+
+ cntl &= ~(D_TIMER_AR);
+
+ cntl |= ( Ar << 1 );
+
+ * (volatile SYS_UWORD16 *) D_TIMER_CNTL = cntl;
+}
+
+/*--------------------------------------------------------------*/
+/*  Dtimer2_PTV()						*/
+/*--------------------------------------------------------------*/
+/* Parameters : pre scale					*/
+/* Return     :	none						*/
+/* Functionality : set the Ptv bits Ptv = 0 => 7 		*/
+/*--------------------------------------------------------------*/
+
+void Dtimer2_PTV(SYS_UWORD16 Ptv)
+{
+SYS_UWORD16 cntl = * (volatile SYS_UWORD16 *) D_TIMER_CNTL;	
+ 
+ cntl &= ~(D_TIMER_ST);			/* stop the timer */
+
+ cntl &= ~(D_TIMER_PTV);		/* Ptv[4:0] set to 0 */
+
+ cntl |= ( Ptv << 2 );
+
+ * (volatile SYS_UWORD16 *) D_TIMER_CNTL = cntl;
+}
+
+/*--------------------------------------------------------------*/
+/*     Dtimer1_Clken()						*/
+/*--------------------------------------------------------------*/
+/* Parameters : ext clk on/off					*/
+/* Return     :	none						*/
+/* Functionality :  set the clock_enable bit En = 0 | 1 	*/
+/*--------------------------------------------------------------*/
+
+void Dtimer2_Clken(SYS_UWORD16 En)
+{
+SYS_UWORD16 cntl = * (volatile SYS_UWORD16 *) D_TIMER_CNTL;
+ 
+ cntl &= ( ~D_TIMER_CLK_EN);
+
+ cntl |= ( En << 5 );
+
+ * (volatile SYS_UWORD16 *) D_TIMER_CNTL = cntl;
+}
+
+
+
+/*--------------------------------------------------------------*/
+/*  Dtimer2_Start()						*/
+/*--------------------------------------------------------------*/
+/* Parameters : on/off						*/
+/* Return     :	none						*/
+/* Functionality :  Start or stop the timer 			*/
+/*--------------------------------------------------------------*/
+
+void  Dtimer2_Start (SYS_UWORD16 startStop)
+{
+    (startStop == D_TIMER_ST) ? 	
+	((* (SYS_UWORD16 *) D_TIMER_CNTL) |=  D_TIMER_ST) :	/* condition vrai */
+ 	((* (SYS_UWORD16 *) D_TIMER_CNTL) &= ~D_TIMER_ST);    	/* condition fausse */
+}
+
+/*--------------------------------------------------------------*/
+/*  Dtimer2_ReadValue()						*/
+/*--------------------------------------------------------------*/
+/* Parameters : on/off						*/
+/* Return     :	none						*/
+/* Functionality :  Read timer value				*/
+/*--------------------------------------------------------------*/
+
+SYS_UWORD16 Dtimer2_ReadValue (void)
+{
+ return(* (SYS_UWORD16 *) D_TIMER_READ);
+}
+
+/*--------------------------------------------------------------*/
+/* Parameters : on/off						*/
+/* Return     :	none						*/
+/* Functionality :  Write timer value				*/
+/*--------------------------------------------------------------*/
+
+void Dtimer2_WriteValue (SYS_UWORD16 value)
+{
+ (* (SYS_UWORD16 *) D_TIMER_LOAD) = value;
+}
--- a/nuc-fw/sysglue/Makefile	Sun Oct 20 21:12:41 2013 +0000
+++ b/nuc-fw/sysglue/Makefile	Thu Oct 24 02:47:14 2013 +0000
@@ -1,7 +1,7 @@
 CC=	arm-elf-gcc
 ASFLAGS=-mthumb-interwork
 
-OBJS=	sysinit.o
+OBJS=	irqfiq.o sysinit.o
 
 all:	${OBJS}
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nuc-fw/sysglue/irqfiq.S	Thu Oct 24 02:47:14 2013 +0000
@@ -0,0 +1,73 @@
+/*
+ * This module contains the assembly shells for IRQ and FIQ, separated
+ * from the architectured vectors only by some simple unconditional
+ * branch instructions.
+ *
+ * Note that TI's way of handling interrupts sacrifices Nucleus' ability
+ * to nest interrupts and minimize the IRQ-disabled window: if my (Falcon's)
+ * understanding is correct, TI's code leaves all further IRQs disabled
+ * for the full execution duration of an IRQ handler.  (IRQ handlers are
+ * really LISRs, but TI's GSM fw does not use Nucleus' LISR framework.)
+ */
+
+	.section	iram.text,"ax",%progbits
+	.code	32
+
+	.globl	_INT_IRQ
+_INT_IRQ:
+        STMDB   sp!,{a1-a4}                 @ Save a1-a4 on temporary IRQ stack
+
+/*
+ * Thanks to TI for discovering and documenting this apparent ARM7TDMI bug:
+
+BUG correction 1st part -------------------
+It looks like there is an issue with ARM7 IRQ masking in the CPSR register
+which leads to crashes in Nucleus+ scheduler.
+Basically the code below  (correct as LOCKOUT = 0xC0) is used in many places by N+ but do not 
+prevent from having an interrupt after the execution of the third line (I mean execution, not 
+fetch).
+        MRS     a1,CPSR                     ; Pickup current CPSR
+        ORR     a1,a1,#LOCKOUT              ; Build interrupt lockout value
+        MSR     CPSR,a1                     ; Lockout interrupts
+       * IRQ INTERRUPT ! *
+       Next instructions...
+
+SW workaround:
+When a task is interrupted at this point an interrupted context is stored on its task and will 
+be resumed later on at the next instruction but to make a long story short it leads to some 
+problem as the OS does not expect to be interrupted there.
+Further testing tends to show that the CPSR *seems* to be loaded with the proper masking value 
+but that the IRQ is still triggered (has been hardwarewise requested during the instruction 
+exectution by the ARM7 core?)
+*/
+
+        MRS     a1,spsr                     @ check for the IRQ bug:
+        TST     a1,#0x80                    @ if the I - flag is set,
+        BNE     IRQBUG                      @ then postpone execution of this IRQ
+/* Bug correction 1st part end --------------- */
+
+        SUB     a4,lr,#4                    @ Save IRQ's lr (return address)
+        BL      TCT_Interrupt_Context_Save  @ Call context save routine
+
+        BL      IQ_IRQ_isr			@ Call  int. service routine
+
+     /* IRQ interrupt processing is complete.  Restore context- Never 
+        returns!  */
+        B       TCT_Interrupt_Context_Restore
+
+/* BUG correction 2nd part  ------------------ */
+IRQBUG: LDMFD  sp!,{a1-a4}                  @ return from interrupt
+        SUBS   pc,r14,#4
+/* BUG correction 2nd part end  -------------- */
+
+	.globl	_INT_FIQ
+_INT_FIQ:
+        STMDB   sp!,{a1-a4}                 @ Save a1-a4 on temporary FIQ stack
+        SUB     a4,lr,#4                    @ Save FIQ's lr (return address)
+        BL      TCT_Interrupt_Context_Save  @ Call context save routine
+
+        BL      IQ_FIQ_isr                  @ Call the FIQ ISR
+
+     /* FIQ interrupt processing is complete.  Restore context- Never 
+        returns!  */
+        B       TCT_Interrupt_Context_Restore