2007-09-18 11:01 PM
UART interrupt + TIM interrupt - problem
2011-05-17 12:40 AM
Hello
I use UART0 transmition with interrupt and TIM0 also with interrupt. When I use only UART0 - program works correctly, but when I enable TIM0 interrupt the UART0 transmition stops after a few seconds and starts again and stops ans so on. I work on STR912FW44X6 chip with number 631. I use Anglia IDEaliST Compiler ver 1.52 Could you tell me how to solve this problem step by step? With regards. Greg2011-05-17 12:40 AM
Hi Greg,
You find attached a working example using UART interrupt and Timer interrupt may be you have something wrong in your code. Please let me know if your problem persists. Best regards, mirou [ This message was edited by: mirou on 03-04-2007 17:20 ]2011-05-17 12:40 AM
Hi, Greg
The problem,you mentioned,I think that cause of nested interrupt. so, check the IRQ handler macro(the code switching IRQ to USR mode) in 91x_vect.s,modify and test as following ;//MSR cpsr_c,#0x1F ;// Switch to SYS mode and enable IRQ --> MSR cpsr_c,#0x1F | I_Bit;// Switch to SYS mode and disable IRQ modified by KMSHIM, 2007/03/15 this method do not allow the nested interrupt mode good luck.2011-05-17 12:40 AM
Hi
Here are stutup files : vector.s from Anglia compiler and STR91x.s from Keil uVision3 When I use Keil an add these two default functions program works correctly /////////////////////////////////////////////////////////////////////////// __irq void def_irq0 (void) { temp_cnt_irq0++; /* Do nothing */ VIC0->VAR = 0; } __irq void def_irq1 (void) { temp_cnt_irq1++; /* Do nothing */ VIC1->VAR = 0; } VIC0->DVAR = (unsigned int)def_irq0; VIC1->DVAR = (unsigned int)def_irq1; /////////////////////////////////////////////////////////////////////////// But it works only when i use my definitions of ISR like this /////////////////////////////////////////////////////////////////////////// __irq void ADC_IRQ_Handler (void) { AD_last = ADC->DR0 & 0x03FF; ADC->CR &= 0xFFFE; ADC->CR &= 0x7FFF; VIC0->VAR = 0; VIC1->VAR = 0; AD_in_progress = 0; } /////////////////////////////////////////////////////////////////////////// If i try to use ISR form library program dosen't work I wonder what is the equivalent of ''__irq'' in Anglia Compiler? Best regards. Greg2011-05-17 12:40 AM
Hi GrzesiekFl,
It's a problem of spurious interrupt. In fact, you need to handle this spurious interrupt, by initalizing the Default Vector address register and using the undefinedIRQ handler (as you did) to solve this problem. Kind regards, mirou2011-05-17 12:40 AM
Hello,
I had the same problem with External interrupt + Tim0 interrupt. When I use modified macro (MSR cpsr_c,#0x1F | I_Bit;// Switch to SYS mode and disable IRQ modified by KMSHIM, 2007/03/15 ), program works correctly. But it will often happen that all variables used in ISRs forced zero. Have anybody same problem? Best regards. Maca Here is my code: #include ''91x_lib.h'' //#include ''str91x.h'' #include ''stdio.h'' #define ON_3V3 GPIO_Pin_4 #define ON_5V GPIO_Pin_5 TIM_InitTypeDef TIM_InitStructure; WIU_InitTypeDef WIU_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; EMI_InitTypeDef EMI_InitStruct; volatile u16 Disp_Temp; volatile u8 Freq_State; volatile u32 Freq_SwTimer1; void Init_Clock(void); void EMI(void); void Disp_Out(void); void FreqExt_IntrHandler(void); void FreqTim_IntrHandler(void); void Freq_Init(void); main(){ #ifdef DEBUG debug(); #endif Init_Clock(); EMI(); GPIO_WriteBit(GPIO4,ON_5V,Bit_SET); Disp_Temp |= 0x8000; Disp_Out(); Freq_State = 0; Freq_SwTimer1 = 0; Freq_Init(); while(1); } void FreqExt_IntrHandler(void){ static u16 i; static float pole[30]; static u16 Freq_ImpCount; static float Freq; // u32 IntrState; // // IntrState = disable_IRQ(); WIU_ClearITPendingBit(WIU_Line31); Freq_ImpCount++; if(Freq_State == 1){ Freq_State = 0; Freq = (float)(Freq_ImpCount * 1000000) / (float)(Freq_SwTimer1 * 200); pole[i] = Freq; i++; //printf(''%i \n'',i); if(i == 30){ for(i = 0;i < 30;i++){ printf(''%f \n'',pole[i]); } VIC_ITCmd(EXTIT3_ITLine, DISABLE); } Freq_SwTimer1 = 0; Freq_ImpCount = 0; } // restore_IRQ(IntrState); } void FreqTim_IntrHandler(void){ static u32 Freq_SwTimer0; // u32 IntrState; // // IntrState = disable_IRQ(); TIM0->OC1R += 200; TIM_ClearFlag(TIM0,TIM_FLAG_OC1); Freq_SwTimer1++; if (Freq_SwTimer0++ > 49998){ Freq_State = 1; Freq_SwTimer0 = 0; } // restore_IRQ(IntrState); } void Init_Clock(void){ // Clock SCU_MCLKSourceConfig(SCU_MCLK_OSC); // master clk - OSC clk // Flash controller init SCU_FMICLKDivisorConfig(SCU_FMICLK_Div1); FMI_Config(FMI_READ_WAIT_STATE_2,FMI_WRITE_WAIT_STATE_0, FMI_PWD_ENABLE, FMI_LVD_ENABLE,FMI_FREQ_HIGH); // Set clks dividers SCU_RCLKDivisorConfig(SCU_RCLK_Div1); SCU_HCLKDivisorConfig(SCU_HCLK_Div1); SCU_PCLKDivisorConfig(SCU_PCLK_Div2); // Init PLL = 96 MHz SCU_PLLFactorsConfig(192,25,2); // PLL Enabled SCU_PLLCmd(ENABLE); // Switch clk MCLK = PLL SCU_MCLKSourceConfig(SCU_MCLK_PLL); } void Freq_Init(void){ SCU_APBPeriphClockConfig( __TIM01 | __WIU , ENABLE); TIM_DeInit(TIM0); TIM_StructInit(&TIM_InitStructure); TIM_InitStructure.TIM_Mode = TIM_OCM_CHANNEL_1; // OUTPUT COMPARE CHANNEL 1 Mode TIM_InitStructure.TIM_OC1_Modes = TIM_TIMING; // OCMP1 pin is disabled TIM_InitStructure.TIM_Clock_Source = TIM_CLK_APB; // assign PCLK to TIM_Clk TIM_InitStructure.TIM_Prescaler = 48 - 1; // 1us resolution TIM_InitStructure.TIM_Pulse_Length_1 = 200; // 200 us period TIM_Init(TIM0, &TIM_InitStructure); TIM_ITConfig(TIM0, TIM_IT_OC1, ENABLE); TIM_CounterCmd(TIM0, TIM_CLEAR); TIM_CounterCmd(TIM0, TIM_START); WIU_DeInit(); WIU_InitStructure.WIU_Mode = WIU_Mode_Interrupt; WIU_InitStructure.WIU_TriggerEdge = WIU_RisingEdge; WIU_InitStructure.WIU_Line = WIU_Line31; WIU_Init(&WIU_InitStructure); SCU_WakeUpLineConfig(31); // Clear WIU line 31 pending interrupt flag WIU_ClearITPendingBit(WIU_Line31); SCU_AHBPeriphClockConfig(__VIC, ENABLE); // VIC Deinitialization VIC_DeInit(); // VIC configuration VIC_Config(TIM0_ITLine, VIC_IRQ, 0); VIC_ITCmd(TIM0_ITLine, ENABLE); VIC_Config(EXTIT3_ITLine, VIC_IRQ,0); VIC_ITCmd(EXTIT3_ITLine, ENABLE); } void EMI(void){ SCU_AHBPeriphClockConfig(__EMI | __EMI_MEM_CLK, ENABLE);/* Enable the clock for EMI*/ SCU_EMIBCLKDivisorConfig(SCU_EMIBCLK_Div1); SCU_EMIModeConfig(SCU_EMI_MUX);/*mux mode*/ SCU_APBPeriphClockConfig(__GPIO7 ,ENABLE); SCU_EMIALEConfig(SCU_EMIALE_LEN2, SCU_EMIALE_POLLow); GPIO_EMIConfig(ENABLE);/* GPIO8,GPIO9 Configuration*/ EMI_DeInit(); /* EMI default configuration : Reset configuration*/ /* GPIO7 Configuration --------------------------------------------------------*/ GPIO_DeInit(GPIO7); GPIO_InitStructure.GPIO_Direction = GPIO_PinOutput; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; GPIO_InitStructure.GPIO_Type = GPIO_Type_PushPull ; GPIO_InitStructure.GPIO_Alternate = GPIO_OutputAlt3; GPIO_Init (GPIO7, &GPIO_InitStructure); EMI_StructInit(&EMI_InitStruct); EMI_InitStruct.EMI_Bank_IDCY=0x03 ;/* Number of bus turnaround cycles added between read and write accesses.*/ EMI_InitStruct.EMI_Bank_WSTRD=0x02 ; /* Number of wait states for read accesses*/ EMI_InitStruct.EMI_Bank_WSTWR=0x02 ;/* Number of wait states for write accesses*/ EMI_InitStruct.EMI_Bank_WSTROEN= 0x02;/*Output enable assertion delay from chip select assertion*/ EMI_InitStruct.EMI_Bank_WSTWEN= 0x02;/*Write enable assertion delay from chip select assertion*/ EMI_InitStruct.EMI_Bank_MemWidth= EMI_Width_Byte;/*This member Controls the memory width*/ EMI_InitStruct.EMI_Bank_WriteProtection= EMI_Bank_NonWriteProtect;/*Write protection feature */ EMI_InitStruct.EMI_PageModeRead_TransferLength= EMI_4Data; /* page transfer length for page mode read */ EMI_InitStruct.EMI_PageModeRead_Selection= EMI_NormalMode;/*Select or deselect the page mode read*/ EMI_Init( EMI_Bank2, &EMI_InitStruct);/*use Bank2 (CS2)*/ } void Disp_Out(void){ *(u8*)0x34000000 = (u8)(Disp_Temp % 256); *(u8*)0x34000100 = (u8)(Disp_Temp / 256); }2011-05-17 12:40 AM
Hello,
I've tried your tips, but it doesn't work. I have got TIM0-Int for 1ms regularly. It works for so long, I don't get an RX-Int. After this IRQ-Handler, the Timer has the OCFA/OCAIE- bits are set, but the Int is never served. :( my 71x_vec.s has the history-date:;* 13/01/2006 : V3.1 Any Idea?2011-05-17 12:40 AM
Hello,
When having a 2ms timer IRQ and fequent I2C interrupts I had the phenomenon that the processor jumps to its reset vector after a certain time. I have been able to solve this problem by declaring 2 default IRQ functions. In these functions both VICx->VAR must be cleared. VIC0->VAR = 0; VIC1->VAR = 0; For more details: please read my post on the 'Problem on Interrupt (VIC0 and VIC1)'. Best regards, Louis XIV