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.

CCS/TMS320F28375D: Using EMIF1MSEL in interrupts.

Part Number: TMS320F28375D

Tool/software: Code Composer Studio

Please tell me about EMIF1MSEL change during interrupt processing.

[environment]
TMS320F28375D
・ CCS8.1.0.00011

The following EMIF code is created in a dual environment.

/ ************************************************* *********************************** /
void emif1 (uint16_t * u16Mod, uint16_t * u16Src)
{
    uint32_t t = 0;

    while (1) {
        EALLOW;
        t = Emif1ConfigRegs.EMIF1MSEL.all;
        EDIS;
        if (t == 0) {// EMIF1 no Grab
            break;
        }
    }
    EALLOW;
    Emif1ConfigRegs.EMIF1MSEL.all = 0x93A5CE71;
    EDIS;
    * u16Mod = * u16Src; // Or memcpy
    EALLOW;
    Emif1ConfigRegs.EMIF1MSEL.all = 0x93A5CE70;
    EDIS;
}
/ ************************************************* *********************************** /

Using this code,

- Main routine
- External interrupt

During the above state, data is being written to the external memory.

There is a problem with this code, for example
  01.Acquiring EMIF1MSEL in the main routine
  02.External interrupt occurs when EMIF1MSEL is 1
  03.Since EMIF1MSEL is 1, external interrupt cannot grab EMIF
For this reason, the processing loops.
(The condition of processing when t == 1 is not implemented because a new problem may appear.)

In order to avoid the above problem, interrupt disable processing is used.
  Asm ("setc INTM")
  Asm ("clrc INTM")
Although set above and below the main routine EMIF processing,
A processing loop like the example above will occur.
Isn't this instruction set to disable interrupts?


The parameters set in EMIF are as follows.
================================================== =============================
    // Configure to run EMIF1 on full Rate (EMIF1CLK = CPU1SYSCLK)
    EALLOW;
    ClkCfgRegs.PERCLKDIVSEL.bit.EMIF1CLKDIV = 0x0;
    // release EMIF1
    Emif1ConfigRegs.EMIF1MSEL.all = 0x93A5CE70;
    // Configure the access timing for CS2 space
    EDIS;
    ASync_cs2_config (0,0x01,0x03,0x01,0x08,0x01,0x01,0x02,0x01,0x00,0x00);
================================================== =============================


I would like one more thing.
Is there a way to make the above EMIF processing faster?
There is no room in the processing time of 1 loop of CPU1, (within 1Loop 10us)
With the above EMIF code, EMIF processing takes up a lot of processing time.

best regard.

  • Hi,

    Can you provide more details on the issue? What do you mean by external interrupt cannot grab EMIF? Does the ISR tries to read data through EMIF. Make sure the above piece of code is used for CPU1 only as for CPU2 to grab EMIF, MSEL value should be 2.

    Thanks

    Vasudha

  • Hi, Vasudha.

    Sorry for the poor explanation.


    As a premise, EMIF1 is used for both Core1 main routine and Core1 external interrupt.
    This external interrupt is one and is called periodically.
    Core2 also uses the above EMIF code, and the value of MSEL is set to 10b.

      01.External memory processing using the above EMIF in the main routine
      02. An external interrupt occurs during execution
      03.Use the above EMIF code to operate the external memory in the processing of external interrupt
      04.Because MSEL is already set to 01b at the first "while" of the EMIF code, an external interrupt becomes a permanent loop.

    I want to solve this problem.
    When MSEL == 01b is judged at the first "while", MSEL is set to 0 when the interrupt EMIF ends.
    If the interrupted side has not yet completed external memory processing, it will execute EMIF with MSEL = 0.
    I don't want to add MSEL == 01b to the "while" judgment.

    In order to solve this, I put the assembler code that is an interrupt prohibition flag in every place where the EMIF on the main routine side is used, but for some reason it seems to endlessly loop with while == 01b.
      asm ("setc INTM")
      asm ("clrc INTM")


    If the main routine processing is disabled, an endless loop does not occur, so this is a deadlock due to the simultaneous use of the main and external interrupt EMIF.
    Interrupts are prohibited in the section where the assembler code is inserted, and I thought that deadlock can be avoided, but it does not seem to work.


    Below are questions.

    -Is my handling wrong in the first place?
    -Is assembler code that disables interrupts valid in the same environment?
    -Or is there any other solution?

    best regard.

  • Hi,

    gouki ono said:
    When MSEL == 01b is judged at the first "while", MSEL is set to 0 when the interrupt EMIF ends.
    If the interrupted side has not yet completed external memory processing, it will execute EMIF with MSEL = 0.
    I don't want to add MSEL == 01b to the "while" judgment.

    Can you share any sample code for more clarity on the above mentioned scenario?

    Thanks

    Vasudha

  • Have you tried using the "DINT" instruction instead of ASM code which you have to disable the interrupt. If not please use that and see if it works.

    Regards,

    Vivek Singh

  • Hi Vivek Singh.

    Thank you.
    It has been confirmed that interrupts are stopped using EINT and DINT.
    However, EMIF deadlocks occur.

    Core has a main routine and interrupt handling.
    Since I don't think the same interrupt will start during interrupt processing,
    I think that it is moving through the "interrupt stop processing" placed in the main routine processing.

    I don't know the reason, but “interrupt stop processing” is normally working normally.
    EMIF deadlock does not occur during normal processing.

    Deadlock occurs when EMIF is used more than normal processing on the other core side.
    This simply adds code to the program when writing information to the outside for debugging, etc.
    If this code is deleted, the deadlock will not occur.


    Hi Vasudha.

    / ************************************************* *********************************** /
    void emif1 (uint16_t * u16Mod, uint16_t * u16Src)
    {
        uint32_t t = 0;

        while (1) {
            EALLOW;
            t = Emif1ConfigRegs.EMIF1MSEL.all;
            EDIS;
            / * ======= CHG ======= * /
            if (t == 0 || t == 1) (// EMIF1 no Grab, or EMIF1 grab CPU1
            / * ======= CHG ======= * /
                 break;
            }
        }
        EALLOW;
        Emif1ConfigRegs.EMIF1MSEL.all = 0x93A5CE71;
        EDIS;
        * u16Mod = * u16Src; // Or memcpy
        EALLOW;
        Emif1ConfigRegs.EMIF1MSEL.all = 0x93A5CE70;
        EDIS;
    }
    / ************************************************* *********************************** /

    I'm thinking about the changes made above.
    In this code, when CPU1 is holding EMIF in the main loop,
    Interrupt processing occurs. By judging MSEL == 1 in the EMIF in the interrupt, exit the "While" loop,
    EMIF processing can be executed.
    However, with this code, when interrupt processing exits the EMIF, MSEL is set to 0,
    It will be executed in MSEL0 in the main loop that has returned from the end of interrupt processing.

    In order to avoid this, for example, using the Static variable, count the number of simultaneous EMIF usage in the same core,
    Although it is possible to determine whether or not to execute the process of returning MSEL to 0,
    Until the interrupt processing is completed, another Core cannot use the EMIF.
    Because this time is strict, I want to avoid waiting for the end of interrupt processing.


    I'm sorry for the poor explanation.

    Regards.

  • Hi,

    I think if you check for  t != 2 in while condition in CPU1 main code and ISR code, this problem should be resolved. In case t!=2, you can grab it in main or ISR code if not already grabbed. If the EMIF is already grabbed, you can just directly perform the write operation. Let me know if this resolves your issue.

    Thanks

    Vasudha

  • Summarize what you want to hear.

    1. Use CPU1,2.
    2. Both CPUs have main routine and interrupt.
    3. Use EMIF in the above 4 threads. (CPU1 = MSEL1, CPU2 = MSEL2)
    4. When using EMIF on the same CPU, deadlock will occur if EMIF is used for interrupts while the main uses EMIF.    Therefore, when EMIF is used in the main routine, processing is sandwiched between DINT and EINT.
    (See the first question in the EMIF code.)

    If the process runs in this state, the EMIF runs and ignores the fourth "DINT, EINT".

    What is the reason for ignoring DINT and EINT?

    [Conditions that cause problems]
    If multiple EMIF processes are added to CPU1 interrupt,
    CPU2 frequently ignores DINT and EINT.

  • Hi,

    I am not sure why are you seeing the deadlock here. Inside ISR you should always read the EMIF1MSEL value just after entering the ISR  and restore that value just before exiting the ISR.  

    Regards,

    Vivek Singh