Energy Micro IEC60355 Library Example Project 1.0 (internal use only!) GCC-Version
Example project demonstrating POST and BIST library functions

iec60335_class_b_interrupt_test.c

Go to the documentation of this file.
00001 /***************************************************************************/
00031 #include "iec60335_class_b_interrupt_test.h"
00036 #if defined (__CC_ARM)                              /*--RealView Compiler --*/
00037     #define __ASM    __asm                          
00038 /* ARM armcc specific function */
00039 void __call_Vect(uint32_t vect)
00040 {
00041   uint32_t *org_vector = (uint32_t *)vect;
00042   void (*Process)(void)= (void(*)(void))(*org_vector);
00043   Process();
00044 }
00045 
00046 #define __ENABLE_IRQ()     __enable_irq();          
00047 #define __DISABLE_IRQ()    __disable_irq()          
00050 #elif (defined (__ICCARM__))                        /*-- ICC Compiler --*/
00051 
00052     #define __ASM    __asm                          
00053 /* IAR specific function */
00054 void __call_Vect(uint32_t vect)
00055 {
00056   uint32_t *org_vector = (uint32_t *)vect;
00057   void (*Process)(void) = (void(*)(void))(*org_vector);
00058   Process();
00059 }
00060 
00061 #define __ENABLE_IRQ     __enable_interrupt         
00062 #define __DISABLE_IRQ    __disable_interrupt        
00065 #elif (defined (__GNUC__))                          /*-- GNU Compiler --*/
00066 
00067     #define __ASM    __asm                          
00068 /* GCC specific function */
00069 void __call_Vect(uint32_t vect)
00070 {
00071   uint32_t *org_vector = (uint32_t *)vect;
00072   void (*Process)(void) = (void(*)(void))(*org_vector);
00073   Process();
00074 }
00075 
00076 static __INLINE void __ENABLE_IRQ(void)
00077 {
00078   __ASM volatile ("cpsie i");
00079 }
00080 static __INLINE void __DISABLE_IRQ(void)
00081 {
00082   __ASM volatile ("cpsid i");
00083 }
00086 #elif defined   (__TASKING__)
00087 
00088 #error "not implemented yet !"                  
00090 #else
00091 #error "iec60355_class_b_interrupt_test.c: undefined compiler"
00092 #endif
00093 
00094 IEC60335_IRQ_Test_t IEC60335_IRQ_Test;
00095 IEC60335_IRQ_Test_t *pIEC60335_IRQ_Test = 0;
00096 
00097 /* replacement vector table */
00098 #if defined (__ICCARM__)
00099 #pragma data_alignment=0x100
00100 uint32_t IRQVectorTable[64];
00101 #else
00102 uint32_t IRQVectorTable[64] __attribute__((aligned(0x100)));
00103 #endif
00104 /* test data array first element is SysTick_IRQn */
00105 #ifdef TESSY
00106 uint32_t IRQCounterTable[32];
00107 #else
00108 static uint32_t IRQCounterTable[32];
00109 #endif
00110 
00112 #if defined (__ICCARM__)
00113 #pragma section="IEC60335_code"
00114 #else
00115 __attribute__((section(".IEC60335_code")))
00116 #endif
00117 
00118 void IEC60335_IRQReplacementHandler(void)
00119 {
00120   int32_t       IRQ_Idx;
00121   IRQTestData_t *IRQ_Test;
00122   /* get active interrupt number */
00123   IRQ_Idx = ((int32_t)(SCB->ICSR) & SCB_ICSR_VECTACTIVE_Msk) - 16;
00124   /* set counter, first element is SysTick_IRQn */
00125   if (IRQ_Idx > PendSV_IRQn)
00126   {
00127     IRQ_Test = (IRQTestData_t *) IRQCounterTable[IRQ_Idx+1];
00128     /* check test active */
00129     if (pIEC60335_IRQ_Test->Active & (0x1 << (IRQ_Idx+1)))
00130     {
00131       IRQ_Test->EffectiveCount++;
00132     }
00133   }
00134   /* call original vector */
00135   if ((IRQ_Idx <= PendSV_IRQn) || (pIEC60335_IRQ_Test->Mode & (0x1 << (IRQ_Idx+1))))
00136   {
00137     /* call original vector from flash */
00138     __call_Vect((IRQ_Idx + 16) * 4);
00139   }
00140 }
00141 
00143 #if defined (__ICCARM__)
00144     #pragma section="IEC60335_code"
00145 #else
00146 __attribute__((section(".IEC60335_code")))
00147 #endif
00148 
00149 void IEC60335_ClassB_InitInterruptTest(IRQn_Type IRQn, uint8_t Mode, IRQTestData_t *CountSetup)
00150 {
00151   /* test only peripheral IRQs, first element is SysTick_IRQn */
00152   if (IRQn > PendSV_IRQn)
00153   {
00154     /* check initial usage */
00155     if (pIEC60335_IRQ_Test == 0)
00156     {
00157       __disable_irq();
00158       pIEC60335_IRQ_Test = &IEC60335_IRQ_Test;
00159       /* copy vector table */
00160       util_memcpy(&IRQVectorTable[0], 0, 64 * 4);
00161       pIEC60335_IRQ_Test->Active = 0x00;            /* clear all tests active */
00162       pIEC60335_IRQ_Test->Mode   = 0x00;            /* clear all flags */
00163       /* change offset to RAM */
00164       SCB->VTOR = ((0x1 << SCB_VTOR_TBLBASE_Pos) +
00165                    (((uint32_t) &IRQVectorTable[0]) & 0xFFFF));
00166       __enable_irq();
00167     }
00168 
00169     __disable_irq();
00170     /* toggle status active flag */
00171     if (pIEC60335_IRQ_Test->Active & (1 << (IRQn + 1)))
00172     {
00173       pIEC60335_IRQ_Test->Active &= ~(1 << (IRQn + 1));
00174       /* original vector */
00175       util_memcpy(&IRQVectorTable[IRQn + 16], (void *)(IRQn + 16), 4);
00176     }
00177     else       /* activate */
00178     {
00179       pIEC60335_IRQ_Test->Active |= (1 << (IRQn + 1));
00180       /* replace vector */
00181       IRQVectorTable[IRQn + 16] = (uint32_t) &IEC60335_IRQReplacementHandler;
00182 
00183       /* reset the counter */
00184       IRQCounterTable[IRQn + 1]  = (uint32_t) CountSetup;
00185       CountSetup->EffectiveCount = 0;
00186 
00187       /* toggle mode of calling original vectors */
00188       if (Mode)
00189       {
00190         pIEC60335_IRQ_Test->Mode |= (1 << (IRQn + 1));
00191       }
00192       else
00193       {
00194         pIEC60335_IRQ_Test->Mode &= ~(1 << (IRQn + 1));
00195       }
00196     }
00197     __enable_irq();
00198   }
00199   else
00200   {
00201     __disable_irq();
00202     /* disable all tested IRQs */
00203     IEC60335_IRQ_Test.Mode   = 0;
00204     IEC60335_IRQ_Test.Active = 0;
00205     pIEC60335_IRQ_Test         = (IEC60335_IRQ_Test_t *) 0;
00206     SCB->VTOR                  = 0;
00207     __enable_irq();
00208   }
00209 }
00210 
00212 #if defined (__ICCARM__)
00213     #pragma section="IEC60335_code"
00214 #else
00215 __attribute__((section(".IEC60335_code")))
00216 #endif
00217 
00218 testResult_t IEC60335_ClassB_InterruptCheck(IRQn_Type IRQn)
00219 {
00220   testResult_t  Result = IEC60335_testFailed;
00221   IRQTestData_t *Counter;
00222   /* valid Index */
00223   if (IRQn > PendSV_IRQn)
00224   {
00225     /* check test active */
00226     if (pIEC60335_IRQ_Test->Active & (1 << (IRQn + 1)))
00227     {
00228       Counter = (IRQTestData_t *) IRQCounterTable[IRQn + 1];
00229 
00230       if ((Counter->EffectiveCount < Counter->MaxThres) && (Counter->EffectiveCount > Counter->MinThres))
00231       {
00232         Result                  = IEC60335_testPassed;
00233         Counter->EffectiveCount = 0;
00234       }
00235     }
00236   }
00237   return Result;
00238 }
00239 
00244 /************************************** EOF *********************************/