This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

BIOS6 MCASP interrupt turned off by BIOS clock?

Other Parts Discussed in Thread: SYSBIOS

Hi!

I'm using BIOS 6.21.02.19 with CCS4 and a C6748

I'm setting up MCASP to transmit audio data and generate an XDATA interrupt for each sample. This works ok for a while, I'm getting a few interrupts before it stops sending data. The amount of time it takes before it stops I found is dependent on the Clock.tickPeriod value in the cfg file. This leads me to believe that the timer interrupt for the kernel turns off or somehow messes with the mcasp interrupt. I am not using the ECM. Why is this and how can I avoid it?

Here is my interrupt init code:

   Hwi_Params_init(&hwiParams);
   hwiParams.eventId = 61;
   hwiParams.enableInt = false;
   hwi0 = Hwi_create(4, mcaspIsr, &hwiParams, NULL);

The interrupt is enabled later with

   Hwi_enableInterrupt(4);
   SETBIT(MCASP->XINTCTL, 0x21);

Here is my isr:

void mcaspIsr(UArg ipr)
{
    uint32_t regVal;
    regVal = MCASP->XSTAT;
    if(CHKBIT(regVal, 0x20))
    {  
        MCASP->XBUF0 = sinetable[sample++];
        if (sample>=48) sample=0;
        SETBIT((*EVTCLR1), 0x20000000);
    }
    if(CHKBIT(regVal, 0x01)) {
        mcasperrflag++;
        SETBIT((*EVTCLR1), 0x20000000);
    }
}

There is no Hwi setup done in the bios.cfg file.

After it stops working I print out some register values:

MCASP status:
mcasp0 xstat: 0x0000015d
mcasp0 xintctl: 0x00000021
mcasp0 xgblctl: 0x00001f1f
IER: 0x00004013 IFR: 0x00000000 CSR: 0x14000103
mcasp0 sample: 11, error 1
INTMUX1: 0x0706053d
INTMUX2: 0x0b0a0908
INTMUX3: 0x0f040d0c
EVTFLAG0: 0x00000019
EVTFLAG1: 0x00000000
EVTFLAG2: 0x00000000
EVTFLAG3: 0x04000001

It seems the eventflag for mcasp is now cleared and is never set again even though it is still enabled in xintctl and IER. What am I missing?

Thanks for reading,

Ole Gauteplass

  • what is your Clock.tickPeriod frequency?   What is the McASP frequency?   Is it possible to make a small test case that runs on the EVM?  When the problem occurs, do you still get timer interrupts?   You can use ROV to look at ti.sysbios.Clock module view and see if Clock is still incrementing.   Or place b/p on the interrupt vector associated with the timer (14 in your case).  Vector base address can be found in ISTP register.

    It's been a long time since I worked with the McASP or McBSP but are you sure that you need the 'SETBIT((*EVTCLR1), 0x20000000);' statements?  Sometimes the act of reading hte tx register is enough to clear the event?    We never touch IFR in BIOS.  Is it possible that you have some code that is clearing IFR (with ICR register I think?).

    The timer interrupt should not intefere with McASP in any way.  I've never heard of any problems related to this.  One thing you could try to get more data on this is to also set masking option to "ALL" to make the McASP interrupt highest priority and not allow any other interrupts (like the timer) to preempt you.

     

       Hwi_Params_init(&hwiParams);
       hwiParams.eventId = 61;  
       hwiParams.enableInt = false;
       hwiParams.maskSetting = Hwi_MaskingOption_ALL;
       hwi0 = Hwi_create(4, mcaspIsr, &hwiParams, NULL);

     

  • Hi Karl, thank you for your reply.

    First I'll answer your questions:

    Clock.tickPeriod = 1000

    Mcasp is 48kHz stereo so one interrupt approx every 10us

    It is possible to make a module test to run on the EVM, but it will take some time so it might not happen soon.

    I am not sure I need the SETBIT((*EVTCLR1), 0x20000000); in fact it doesn't seem to matter if it's there or not. I seems to recall reding about it in a document, but maybe it's only needed when using the ECM.

    Your question about samplerate led me to try and lower it, the lowest I can go is 12kHz (interrupts every 40us). This did indeed help, the mcasp now runs much longer. Adding hwiParams.maskSetting = Hwi_MaskingOption_ALL; as well makes it even more stable.

    I can however make mcasp stop by either calling printf or bios functions such as Task_create or Task_delete. I know that these are large functions that uses many cycles, but I still don't understand why they should hold off interrupts while executing.

    In any case it seems it's not the timer that is causing it, but using BIOS (or printf) is not an option when having many interrupts. This was just a intermediary step anyway, the next step is to service the mcasp with edma, so I'm satisfied for now.

    Best regards, Ole

  • Ole J Gauteplass said:

    I can however make mcasp stop by either calling printf or bios functions such as Task_create or Task_delete. I know that these are large functions that uses many cycles, but I still don't understand why they should hold off interrupts while executing.

    In any case it seems it's not the timer that is causing it, but using BIOS (or printf) is not an option when having many interrupts. This was just a intermediary step anyway, the next step is to service the mcasp with edma, so I'm satisfied for now.

    Best regards, Ole

    Hi Ole --

    What you are trying to do should work.   48kHz interrupt rate is modest and Task_create/delete(), etc. shouldn't interfere.  Unless there's a cache artifact in the mix here (see #2 below).

    A few more ideas:

    (1)  Can you do a quick check to verify that your device is running at the right frequency?    There are TSCH/L registers that you can read.  These are available in register view.  TSCH/L count at CPU frequency.  Run core for 10 seconds and make sure that TSCH/L matches what you think your frequency is.  If not correct, then review your PLL setup.

    (2)  Where are you placing your code and data?  Is it in on-chip "L2" memory memory or external?   If external, you should review your platform and consider making a custom platform that sets aside some of the on-chip memory for the L2 cache.  The link below shows how to use the platform wizard to make a new platform.  If your program is small, then consider placing all the code and data in L2.  You can do this with 'Program.sectMap[".text"] = "IRAM" or some such.

    http://rtsc.eclipse.org/docs-3.16/Demo_of_the_RTSC_Platform_Wizard_in_CCSv4

    (3)  Be careful with printf() though.  Printf() has internal breakpoint to communicate with CCS.   You need to make sure you have McASP set up correctly to work with emulation halt.  There are FREE/SOFT bits for this.

     

  • Hi Karl,

    1) After running for ~10 sek the TSCL value is 3028666913 which should indicate that it is indeed running at 300MHz

    2) Some code and data is placed in DDR. L1P and L1D is enabled. I can play around some more with code and data sections and also enable L2 cache to see if it makes a difference.

    3) This is news to me. Where can I read more about the FREE/SOFT bits? It's not mentioned in the mcasp document SPRUFM1.

    Thanks,

    Ole

  • Sorry about that.  It's been awhile.  Looks like the McASP doesn't have these bits.   Older peripherals like McBSP did.

    Main point is that it would be worth experiment to remove the printf() calls since these halt the processor to communicate with CCS.   Depending on how your AIC is configured, this can cause problems with frame synchs and clocking.   This may be red herring.  Take my warning with grain of salt since it has it's been a long time.

    Can you please mark this thread answered?

    Thanks,
    -Karl-