This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

spurious interrupts not simlated in arm7

spurious interrupts not simlated in arm7

Parents
  • Please refer to the philips LPC2134 datasheet for details on spurious interrupt.

    In my case, it happened in both serial port and ADC. I will give the details.

    1. End of AD conversion will trigger the interrupt.
    2. One of the instructions, which is in the main function, is to write ADC register. This intruction takes 2 machine circles.
    3. Just as the instruction is been executed, the "end of ADC" occurs, and the core get an interrupt request.
    4. But after the instruction, the interrupt is cleared by the instruction. So when the core responses to the interrupt request, the VIC cannot identify who is generating the request, and thus the spurious interrupt is generated.
    5. if the VICDefVectAddr in not initialized to a valid handler, then the process will start from address 00000000.


    In the case of serial port, the similar situation occurs:

    1. we call printf, which will in turn call putchar
    2. putchar will check whether the serial port is sending in progress
    3. if the serial port is sending, then just add the new byte to a queue;
    4. otherwise just write

    U0THR = byte;
    to start the serial port tranmission, and the following bytes will be transmitted in the interrupt service.
    But as the instruction is been executed, the serial port interrupt ocurred. After the instruction, when the core tries to service the interrupt, it fail to identified the interrupt, because the writing to U0THR will clear the interrupt. so the suprious interrupt is generated.


    Other problems:
    1. The serial port interrupt timing sequence is not well simuluated.
    2. The simulation is very very slow, each real second only simulate 0.02 second for ARM7.

Reply
  • Please refer to the philips LPC2134 datasheet for details on spurious interrupt.

    In my case, it happened in both serial port and ADC. I will give the details.

    1. End of AD conversion will trigger the interrupt.
    2. One of the instructions, which is in the main function, is to write ADC register. This intruction takes 2 machine circles.
    3. Just as the instruction is been executed, the "end of ADC" occurs, and the core get an interrupt request.
    4. But after the instruction, the interrupt is cleared by the instruction. So when the core responses to the interrupt request, the VIC cannot identify who is generating the request, and thus the spurious interrupt is generated.
    5. if the VICDefVectAddr in not initialized to a valid handler, then the process will start from address 00000000.


    In the case of serial port, the similar situation occurs:

    1. we call printf, which will in turn call putchar
    2. putchar will check whether the serial port is sending in progress
    3. if the serial port is sending, then just add the new byte to a queue;
    4. otherwise just write

    U0THR = byte;
    to start the serial port tranmission, and the following bytes will be transmitted in the interrupt service.
    But as the instruction is been executed, the serial port interrupt ocurred. After the instruction, when the core tries to service the interrupt, it fail to identified the interrupt, because the writing to U0THR will clear the interrupt. so the suprious interrupt is generated.


    Other problems:
    1. The serial port interrupt timing sequence is not well simuluated.
    2. The simulation is very very slow, each real second only simulate 0.02 second for ARM7.

Children
  • By the way, I resolve the problems by
    1. use the software interrupt to start serial port transmission.

    void __irq UART0Isr (void)
    {
    	uint8 i;
    	VICSoftIntClear = 1<<ISN_UART0;
            .....
    }
    void putch(uint8 dat)
    {
    	while( ! uart0_xmit_queue.Add(dat))
    	{
    	}
    	if((U0LSR & 0X20) == 0X20)
    	{
    		VICSoftInt = 1<<ISN_UART0;
    	}
    }
    
    
    2. Set a valid handler for VICDefVectAddr:
    void __irq DefIrq()
    {
    }
    
    void SetDefaultIrq()
    {
    	VICDefVectAddr = (uint32)DefIrq;
    }