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.

McASP transmit on a specific AXR pin hangs Linux

Other Parts Discussed in Thread: OMAP-L138, OMAPL138

Hello

I'm experiencing an unusal problem on my OMAP-L138 system. I'm using McASP for transmitting PCM voice data in my system. MCASP is supplied with an external clock and frame synchronization signal. There are all 16 serializers being used, 8 for transmit and 8 for receive. Serializers are written to/read from using EDMA3 LLD. Clock is 2048kHz, frames have 32 timeslots, 8-bit each.

I narrowed the problem to setting one bit in McASP configuration: when AXR15 pin is set to transmit data, Linux hangs when a first such transmision occurs. Oddly, the DSP works fine and DMA transfers occur. On the oscilloscoe I see a stable stream of 0xD5 (a-law silence) on AXR15 meaning that OMAP drives the pin in a proper manner.

My transmit/receive pins are grouped into pairs, ARX14 and AXR15 being one such pair. When I alter their functions (e. g. AXR14 transmits and AXR15 receives) Linux does not hang. I did not have the chance of testing if OMAP succesfully reads from AXR15 as the rest of my hardware is dependant on AXR15 to transmit and AXR14 to receive. I cannot make any alterations to the connections made because my custom-built board is multilayered.

Here is the code that hangs the system: 

mcasp_set_bits(DAVINCI_MCASP_BASE + DAVINCI_MCASP_SRCTL_REG(0), 1); //transmit
mcasp_set_bits(DAVINCI_MCASP_BASE + DAVINCI_MCASP_SRCTL_REG(3), 1); //transmit
mcasp_set_bits(DAVINCI_MCASP_BASE + DAVINCI_MCASP_SRCTL_REG(5), 1); //transmit
mcasp_set_bits(DAVINCI_MCASP_BASE + DAVINCI_MCASP_SRCTL_REG(7), 1); //transmit
mcasp_set_bits(DAVINCI_MCASP_BASE + DAVINCI_MCASP_SRCTL_REG(9), 1); //transmit
mcasp_set_bits(DAVINCI_MCASP_BASE + DAVINCI_MCASP_SRCTL_REG(11), 1); //transmit
mcasp_set_bits(DAVINCI_MCASP_BASE + DAVINCI_MCASP_SRCTL_REG(13), 1); //transmit
mcasp_set_bits(DAVINCI_MCASP_BASE + DAVINCI_MCASP_SRCTL_REG(15), 1); //transmit
   
mcasp_set_bits(DAVINCI_MCASP_BASE + DAVINCI_MCASP_SRCTL_REG(1), 2); //receive
mcasp_set_bits(DAVINCI_MCASP_BASE + DAVINCI_MCASP_SRCTL_REG(2), 2); //receive
mcasp_set_bits(DAVINCI_MCASP_BASE + DAVINCI_MCASP_SRCTL_REG(4), 2); //receive
mcasp_set_bits(DAVINCI_MCASP_BASE + DAVINCI_MCASP_SRCTL_REG(6), 2); //receive
mcasp_set_bits(DAVINCI_MCASP_BASE + DAVINCI_MCASP_SRCTL_REG(8), 2); //receive
mcasp_set_bits(DAVINCI_MCASP_BASE + DAVINCI_MCASP_SRCTL_REG(10), 2); //receive
mcasp_set_bits(DAVINCI_MCASP_BASE + DAVINCI_MCASP_SRCTL_REG(12), 2); //receive
mcasp_set_bits(DAVINCI_MCASP_BASE + DAVINCI_MCASP_SRCTL_REG(14), 2); //receive
  
mcasp_set_reg(DAVINCI_MCASP_BASE + DAVINCI_MCASP_PFUNC_REG, 0x00000000); //all pins as McASP
mcasp_set_reg(DAVINCI_MCASP_BASE + DAVINCI_MCASP_PDIR_REG, AXR(0) | AXR(3) | AXR(5) | AXR(7) | AXR(9) | AXR(11) | AXR(13) | AXR(15)); //set as output

AXR is a simple macro:

#define AXR(n)        (1<<n)

When I remove AXR(15) from being set in the PDIR register, yet setting AXR15 as a transmit pin, the system does not hang. This means that DMA configuration cannot be responsible the crash.

I tried many different workarounds and made many tests, but with no luck. PINMUX registers are correctly set (double-checked it with the PINMUX utility available on TI's website). Reducing the number of working PCM channels from 16 to 8 does not help either, it's 100% certaing that when OMAP starts transmitting on AXR15 everything goes bad.

Unlikely as it may sound I even started suspecting a hardware flaw. I tested my code on three boards, with identical results. I'm using an early silicon realease: XOMAPL138ZWT. There is no mention of anything similar to what I'm describing in the errata.

I would be grateful if you could look into my problem.

Kind regards.
Szymon Kukliński

  • Hi Szymon

    I moved this thread to the Linux forums, as at initial glance , it doesn't look like a device issue. Even though I moved it to this forum, we will have the device team also monitor this thread. I see no difference in AXR15 vs AXR14 from pin properties, default pu/pd configuration and power groups etc, so I am not sure what could be causing this phenomenon.  Having fielded some prior questions from you, I take it that you have custom hardware board?

    Additionally can you please confirm on the following

    1) What Linux PSP version etc in use?

    2) Can you share with us the snapshot of just your McASP i/f , in the schematics

    3) Have you (or is it possible) for you to try this outside the context of Linux, to see if the AXR15 does still give you the same issue

    4) I know you had a complex system, but in general what other peripheral drivers/concurrency do you have in this system or is it a standalone test?

    Regards

    Mukul

  • Hi Szymon,

    Is it feasible to connect to your board using JTAG after Linux hangs to get an idea of what exactly happened?

    Thanks,

    Sekhar

  • Hello

    @Sekhar Nori: Unfortunately I cannot connect my board to JTAG.

    I did some more research on my problem however and have some interesting information. The first thing I did was to execute only the most relevant code to take other components of my system from the equation. I did something like:
    - insmod dsplink.ko
    - run my DSP program through DSPLink that configures EDMA3 to work with McASP
    - configure McASP registers in a simple kernel module to start sending/receiving data

    Everything works fine on a 'clean' Linux system like that, so I started searching for errors in the code written by me or my colleagues and got to the point when enabling an interrupt on a certain GPIO pin messes things up:

    #define CCT_RTC_IRQ_PIN            GPIO_TO_PIN(6,12)

    int kbase_rtc_irq_init(void){
        int res;
        setPINMUX(13, 0x00008000);        // (6, 12) set as GPIO
        res = gpio_request(CCT_RTC_IRQ_PIN, "RTC irq\n");
        if (res < 0) {
            printk("RTC GPIO IRQ request failed: %d\n", res);
            gpio_free(CCT_RTC_IRQ_PIN);
            return res;
        }
        gpio_direction_input(CCT_RTC_IRQ_PIN);
        if ((res = request_irq(gpio_to_irq(CCT_RTC_IRQ_PIN), kbase_rtc_irq, IRQF_TRIGGER_FALLING, "KMOD_PBX RTC", NULL))) {
            printk ("SYSTEM : kbase_rtc_irq_init(): cannot register interrupt (res=%d)\n", res);
            return res;
        }           
        printk("wq_init RTC\n");
        wq_init(&wqueue_rtc, POLL_TYPE_READ);
        enable_irq(CCT_RTC_IRQ_PIN);
        return 0;
    }

    Up to the point when McASP starts transfer on AXR15 pin, my RTC interrupts are handled just fine. When McASP starts - Linux hangs. I cannot see any connection between GPIO(6,12) interrupts and AXR15 output so this really confused me. It is not a random issue - it happens 100% of the time. When I comment out enable_irq(CCT_RTC_IRQ_PIN); Linux does not hang but naturally I do not get extrnal RTC interrupts.

    Later on I did one more test. I mentioned that swaping AXR14 and AXR15 functions helps (AXR14 sends, AXR15 receives). It is only partially true. When I connect AXR14 and AXR15 together Linux stalls (AXR14 sends constant 0xD5, resambling a square wave). When I disconnet them, the system becomes responsive again (so basically in any of my situations Linux does not hang or crash, the CPU has to service a lot of interrupts, as many as 2 million per second that stall the system). So it seems like my GPIO(6,12) interrupts are triggered by AXR15 (?????). The first thing I checked was if AXR15 and GPIO(6,12) inputs are short circuit for some reason on my board. They are not (I checked with an oscilloscope).

    I tested this on two revisions of our board, one with XOMAPL138ZWT, the other with OMAPL138AZWT with the same results.

    When I made some alterations to my board and connected the RTC interrupt pin to GPIO(7,11) my system works just fine (McASP sends/receives without a problem, RTC issues interrupts as planned etc.). I cannot. however make alterations to tens of boards already made or being manufactured, so this walkaround is not an option.

    Linux taken from OMAP_L138_arm_1_00_00_06 package: Linux version 2.6.32-rc6 (szymonk@szymonk) (gcc version 4.0.0 (DENX ELDK 4.1 4.0.0)) #2 PREEMPT Thu Oct 21 11:04:48 CEST 2010

    I looked at the errata for OMAP-L138 once again in different light. There are some information regarding interrupt issues I cannot fully find them relevant to my problem.

    Regards
    Szymon

  • These are good clues, and I personally still think that we have a software/board level issue at hand. I think would need Sekhar to fill in the gaps in my understanding, but it would be interesting to understand how GP6[12] and GP7[11] are used on your custom board? GP6[12] is hooked up to the I2C expander on the LogicPD OMAPL138 board, as an INT input, and one of the outputs (though I don't think used) is the control for DEEPSLEEP pin. So perhaps there is some mingling of usage for the TI hardware/software to showcase suspend to ram (deep sleep mode) using either RTC wake up or DEEPSLEEP pin assertion , that you are using on your custom board and its causing some issues?

    Regards

    Mukul