µTasker Forum > Luminary Micro TM LM3SXXXX

Code hitting irq_hard_fault(void)

<< < (2/2)

mark:
Hi Martin

I thought that I had removed this by clearing pending interrupts when entering new interrupts.

Certainly the reason is that the debugger stops the processor after it has run for a short time and has started timers (for example) and then its reset doesn't seem to be a (full) hardware reset, thus leaving timers running and some interrupts possibly pending.

When these interrupts are enabled this is performed before the timers have been started by the code and so it is not expected that they are already running and can already have interrupts pending. The result is that as soon as the interrupt source is enabled at source the interrupt fires even though its handler has not been entered yet. Also stopping or resetting the timer beforehand doesn't necessarily help since the interrupt is still pending in the NVIC.

I made the following change, which I thought that you had:


// Function used to enter processor interrupts
//
static void fnEnterInterrupt(int iInterruptID, unsigned char ucPriority, void (*InterruptFunc)(void))
{
    unsigned long *ptrIntSet = IRQ0_31_SER_ADD;
    unsigned char *ptrPriority = IRQ0_3_PRIORITY_REGISTER_ADD;
    VECTOR_TABLE *ptrVect;
    void ( **processor_ints )( void );
    unsigned long ulInterruptBit;
    ptrVect = (VECTOR_TABLE *)(START_OF_SRAM + RESERVE_DMA_MEMORY);
    processor_ints = (void (**)(void))&ptrVect->processor_interrupts;
    processor_ints += iInterruptID;
    *processor_ints = InterruptFunc;

    ptrIntSet += (iInterruptID/32);                                      // move to the corresponding set enable register address
    ulInterruptBit = (0x01 << (iInterruptID%32));
    *(ptrIntSet + (IRQ0_31_CPR_ADD - IRQ0_31_SER_ADD)) = ulInterruptBit; // {31} clear possibly pending bit (can occur when working with debugger)
    *ptrIntSet = ulInterruptBit;                                         // enable the interrupt

    ptrPriority += iInterruptID;
    *ptrPriority = ucPriority;                                           // define the interrupt's priority
}

[note that some simulator code has been removed for clarity].

This solved my problem (when developing some 16 bit timer code).

I don't know whether this is restricted to the Crossworks debugger or not(?)

Regards

Mark

mhoneywill:
Hi Mark,

Yes I have this code, but I still get the problem. I'm using Rowley 1.7b22 and the Luminary Micro ICDI as my Jtag.

What I was trying to do by moving

fnEnterInterrupt(irq_ADC_Sequence_0_ID, ptrADC_settings->int_priority, _ADC_sequence_0_complete); // enter the interrupt

was to ensure that the interupt handler was setup first, before the ADC was enabled.

Regards

Martin

mhoneywill:
Hi Mark,

I'd been ignoring this problem as most of my code does not use the ADC, but have just come across it again.

I think I've fixed my problem by doing the following

                    RCGC0 |= CGC_SARADC0;                                // enable clocks to ADC module
                    RCGC0 |= CGC_SARADC0;                                // repeat above command to give the ADC module time to wakeup
                    ADCACTSS_0 &= ~ASEN0;                                // ensure sequencer is disabled before configuring
                    ADCEMUX_0 &= ~SS0_MASK;                              // clear sequencer mode

Arround line 4657 in the function fnConfigureInterrupt in LM3Sxxxx.c I've added the above line in RED, I think the access to the ADCACTSS_0 register was happening before the ADC module had powered up. Hence I was getting an irq_hard_fault

It seems to be working fine now, I can download from Rowley in Debug mode and start debugging into the code. This may not have been your problem but it might be worth incorporating or checking out (Still not quite sure why the release build without the JTAG just worked)

Cheers

Martin

mark:
Hi Martin

It is true that it may take a few clocks before peripherals are ready for use after they are powered on.
I know that the Luminary library doesn't have this problem since it uses subroutine calls which slow the code down enough avoid this, but most code in the uTasker project avoids "unnecessary" subroutine calls or uses macros and so can encounter conditions where there could be such problems.
In most cases you will see that, where possible, code is inserted between the power up of the peripheral and the first access to it, which effectively also gives the peripheral some extra clock times to get ready.

In the case of the ADC I didn't notice any problems but it may be device and CPU speed dependent. In this case I have also added your suggestion so that this code location shouldn't become a potential source of difficulties.

Regards

Mark

Navigation

[0] Message Index

[*] Previous page

Go to full version