![]() |
Energy Micro IEC60355 Library Example Project 1.0 (internal use only!) GCC-Version
Example project demonstrating POST and BIST library functions
|
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 *********************************/