• AVR Freaks

Helpful ReplyHot!How to disable all interrupts in pic32

Author
hisoka
Starting Member
  • Total Posts : 44
  • Reward points : 0
  • Joined: 2015/11/30 04:49:14
  • Location: 0
  • Status: offline
2016/04/11 02:29:33 (permalink)
0

How to disable all interrupts in pic32

Hello,
Is there a function to disable all interrupts and then re-enable them instead of disable one a time ?
#1
Totem
Super Member
  • Total Posts : 266
  • Reward points : 0
  • Joined: 2014/12/04 02:18:11
  • Location: Mars
  • Status: offline
Re: How to disable all interrupts in pic32 2016/04/11 02:42:17 (permalink)
3.67 (3)
INTDisableInterrupts()
INTEnableInterrupts()
with MLA library installed on xc32.
 
SYS_INT_Disable()
SYS_INT_Enable()
with MPLAB Harmony.
#2
MatthewM
Super Member
  • Total Posts : 204
  • Reward points : 0
  • Joined: 2014/08/08 03:49:49
  • Location: UK
  • Status: offline
Re: How to disable all interrupts in pic32 2016/04/11 02:45:29 (permalink)
4 (1)
DS61108G is the reference manual for PIC32s.
 
They list in an example (8-1, 8-2, 8-3) to disable interrupts:

 
asm volatile(“di”); // Disable all interrupts
asm volatile(“ehb”); // Disable all interrupt
 

 
Alternatively you can 
 

<edit> Removed string.
post edited by MatthewM - 2016/04/11 03:46:37
#3
Mysil
Super Member
  • Total Posts : 3321
  • Reward points : 0
  • Joined: 2012/07/01 04:19:50
  • Location: Norway
  • Status: offline
Re: How to disable all interrupts in pic32 2016/04/11 03:44:15 (permalink)
4.33 (3)
Hi,
The most direct way to disable and enable interrupts are:
    asm volatile ("di");                /* Disable interrupts. */
    asm volatile ("ei");                /* Enable interrupts. */

These are assembler instructions written as inline assembly in C.
They manipulate the general interrupt enable flag in
the system control coprocessor CP0 in the MIPS core.
The register containing this bit is named: 'Status' and may be watched in the debugger as a SFR register.
See PIC32 Family Reference Manual section 2:
http://ww1.microchip.com/downloads/en/DeviceDoc/61113E.pdf
As far as I know, these interrupt disable and enable instructions are the same for MZ.
There are other differences described is another document for PIC32MZ.
 
If you disable and enable interrupts in general code with nested subroutines,
it is recommended to read the current state of the interrupt flag before changing it,
and restore it to what it was before:
    unsigned int status = 0;

    asm volatile("di    %0" : "=r"(status));        /* This will get the current setting, and then disable interrupts */
/* Critical section of code  ... */
    if (status)
        asm volatile("ei    %0" : "=r"(status));    /* Enable interrupts if enabled before. */



There also exists built in functions in XC32 compiler to handle these operations:
    unsigned int saved_state;

/*    Save current Interrupt Enable state and Disable Interrupts. */
    saved_state = __builtin_get_isr_state();
    __builtin_disable_interrupts();


/*  Other code ... */
    __builtin_set_isr_state(saved_state);    /* Set back to what was before. */

See XC32 Compiler User's Guide.
 
Then in libraries like Harmony or Plib, there exists wrappers for these operations.
 
Regards,
   Mysil
#4
hisoka
Starting Member
  • Total Posts : 44
  • Reward points : 0
  • Joined: 2015/11/30 04:49:14
  • Location: 0
  • Status: offline
Re: How to disable all interrupts in pic32 2016/04/11 04:42:56 (permalink)
0
thanks every one.
Another question I have  disabling interrupts does not mean clearing interrupts flags , correct ?
I mean if an interrupt happen after disabling the interrupts, the uC will jump to the ISR after re-enable the interrupts ? correct ?
I hope I was clear.
 
#5
andersm
Super Member
  • Total Posts : 2576
  • Reward points : 0
  • Joined: 2012/10/07 14:57:44
  • Location: 0
  • Status: offline
Re: How to disable all interrupts in pic32 2016/04/11 05:16:14 (permalink)
3 (1)
Mysil
    if (status)
        asm volatile("ei    %0" : "=r"(status));    /* Enable interrupts if enabled before. */ [/code]

This is not correct, because the status value returned by "di" can have other, unrelated bits set. The right way is to restore the previous value of the status register with an mtc0 instruction.
 
hisokaAnother question I have  disabling interrupts does not mean clearing interrupts flags , correct ?
I mean if an interrupt happen after disabling the interrupts, the uC will jump to the ISR after re-enable the interrupts ? correct ?

Yes, that is right.
#6
Mysil
Super Member
  • Total Posts : 3321
  • Reward points : 0
  • Joined: 2012/07/01 04:19:50
  • Location: Norway
  • Status: offline
Re: How to disable all interrupts in pic32 2016/04/11 08:11:35 (permalink) ☄ Helpfulby Maddy_me 2018/10/22 15:38:03
4 (3)
andersm is right,
"di" instruction return the entire contents of Status register,
so test will need mask to test value of IE bit.
Bit and field definitions for coprocessor 0 is available in <cp0defs.h>
#include <cp0defs.h>
   unsigned int status = 0;

    asm volatile("di    %0" : "=r"(status));        /* This will get the current setting, and then disable interrupts */
    asm volatile("ehb");                            /* Execution Hazard Barrier instruction, to make sure previous instruction take effect before proceeding. */
/* Critical section of code  ... */
    if (status & _CP0_STATUS_IE_MASK)               /* Test if Interrupt Enable was set. */
        asm volatile("ei    %0" : "=r"(status));    /* Enable interrupts if enabled before. */

Also "ehb" instruction inserted, inspiration from MatthewM in message #3.
 
   Mysil
#7
gaiuscosades
New Member
  • Total Posts : 7
  • Reward points : 0
  • Joined: 2019/02/06 02:42:05
  • Location: Austria
  • Status: offline
Re: How to disable all interrupts in pic32 2019/04/21 09:45:43 (permalink)
0
Mysil
andersm is right,
"di" instruction return the entire contents of Status register,
so test will need mask to test value of IE bit.
Bit and field definitions for coprocessor 0 is available in <cp0defs.h>
#include <cp0defs.h>
 
   unsigned int status = 0;

    asm volatile("di    %0" : "=r"(status));        /* This will get the current setting, and then disable interrupts */
 
    asm volatile("ehb");                            /* Execution Hazard Barrier instruction, to make sure previous instruction take effect before proceeding. */
/* Critical section of code  ... */
 
    if (status & _CP0_STATUS_IE_MASK)               /* Test if Interrupt Enable was set. */
 
        asm volatile("ei    %0" : "=r"(status));    /* Enable interrupts if enabled before. */

Also "ehb" instruction inserted, inspiration from MatthewM in message #3.
 
   Mysil




Thanks for this post!
 
But isn't the status load in the line after the if statement useless? As I see it the ei instruction also loads the status register and sets the Interrupt Enable afterwards, but with the status register unused afterwards this seems kind of redundant, or am I misunderstanding something?
#8
andersm
Super Member
  • Total Posts : 2576
  • Reward points : 0
  • Joined: 2012/10/07 14:57:44
  • Location: 0
  • Status: offline
Re: How to disable all interrupts in pic32 2019/04/21 10:32:25 (permalink)
0
gaiuscosadesAs I see it the ei instruction also loads the status register and sets the Interrupt Enable afterwards, but with the status register unused afterwards this seems kind of redundant, or am I misunderstanding something?

I think you mean the status variable? If you're not interested in the previous value of the status register, then yes, you can omit the register argument of the ei instruction (which is the same as specifying $r0 as the argument).
#9
gaiuscosades
New Member
  • Total Posts : 7
  • Reward points : 0
  • Joined: 2019/02/06 02:42:05
  • Location: Austria
  • Status: offline
Re: How to disable all interrupts in pic32 2019/04/21 10:40:49 (permalink)
0
andersm
gaiuscosadesAs I see it the ei instruction also loads the status register and sets the Interrupt Enable afterwards, but with the status register unused afterwards this seems kind of redundant, or am I misunderstanding something?

I think you mean the status variable? If you're not interested in the previous value of the status register, then yes, you can omit the register argument of the ei instruction (which is the same as specifying $r0 as the argument).



Ok. but in what case should I care for the status variable after the if? The status should not be modified in the critical section anyway...
I am just trying to understand in which case, getting the status inside the if clause could be usefull, for the further program?
Thanks.
#10
andersm
Super Member
  • Total Posts : 2576
  • Reward points : 0
  • Joined: 2012/10/07 14:57:44
  • Location: 0
  • Status: offline
Re: How to disable all interrupts in pic32 2019/04/22 07:27:59 (permalink)
0
You can try locating the instruction set designers, and ask them what use cases they had in mind. I half suspect it's just to provide symmetry with the di instruction.
#11
gaiuscosades
New Member
  • Total Posts : 7
  • Reward points : 0
  • Joined: 2019/02/06 02:42:05
  • Location: Austria
  • Status: offline
Re: How to disable all interrupts in pic32 2019/04/22 07:58:01 (permalink)
0
With that I am pretty sure you are right, because so they can reuse the same opcode decoding logic for both and just insert the one bit that is different for the "ei" and "di" instruction opcodes into the new value of the status register.
 
But my question was only if you had a specific reason to write *asm volatile("ei    %0" : "=r"(status));* instead of *asm volatile("ei");* and that I did understand something wrong about the code put forward. But, so it seems, it was just convinience and symmetry also, which is of course also perfectly fine!
Thanks for the clarification.
#12
Jump to:
© 2019 APG vNext Commercial Version 4.5