cancel
Showing results for 
Search instead for 
Did you mean: 

UART interrupt + TIM interrupt - problem

gflasza
Associate II
Posted on September 19, 2007 at 08:01

UART interrupt + TIM interrupt - problem

8 REPLIES 8
gflasza
Associate II
Posted on May 17, 2011 at 09:40

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. Greg

amira1
Associate II
Posted on May 17, 2011 at 09:40

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 ]

kmshim
Associate II
Posted on May 17, 2011 at 09:40

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.

gflasza
Associate II
Posted on May 17, 2011 at 09:40

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. Greg

amira1
Associate II
Posted on May 17, 2011 at 09:40

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,

mirou

jmazura
Associate II
Posted on May 17, 2011 at 09:40

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);

}

netz
Associate II
Posted on May 17, 2011 at 09:40

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?

lodedeschepper
Associate II
Posted on May 17, 2011 at 09:40

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