• AVR Freaks

Hot!PIC32MK1024MCF100 ADC interrupt in C

Author
MPaulHolmes
Junior Member
  • Total Posts : 76
  • Reward points : 0
  • Joined: 2009/10/31 10:52:40
  • Location: 0
  • Status: offline
2019/11/14 17:18:11 (permalink)
0

PIC32MK1024MCF100 ADC interrupt in C

With the C30 and xc16 compiler, and the dsPIC30F family, there were a bunch of interrupt functions like this:
void __attribute__ ((__interrupt__,auto_psv)) _ADCInterrupt(void);
void __attribute__ ((__interrupt__,auto_psv)) _CNInterrupt(void);
etc...
 
I just found the names of them I think in some random document.  Now, I'm using the xc32 compiler, and am wondering if there is a list of reserved C interrupt function names for analog to digital, change notification, UART, etc...  
post edited by MPaulHolmes - 2019/11/14 17:23:57
#1

8 Replies Related Threads

    jg_ee
    Super Member
    • Total Posts : 187
    • Reward points : 0
    • Joined: 2015/04/30 10:54:52
    • Location: Colorado
    • Status: offline
    Re: PIC32MK1024MCF100 ADC interrupt in C 2019/11/15 14:13:40 (permalink)
    5 (1)
    You can find the reserved vector names and numbers in the corresponding p32mk1024mcf100.h header file, which is included in the <xc.h> include.
     
     

    /* Vector Numbers */
    #define _CORE_TIMER_VECTOR 0
    #define _CORE_SOFTWARE_0_VECTOR 1
    #define _CORE_SOFTWARE_1_VECTOR 2
    #define _EXTERNAL_0_VECTOR 3
    #define _TIMER_1_VECTOR 4
    #define _INPUT_CAPTURE_1_ERROR_VECTOR 5
    #define _INPUT_CAPTURE_1_VECTOR 6
    #define _OUTPUT_COMPARE_1_VECTOR 7
    #define _EXTERNAL_1_VECTOR 8
    #define _TIMER_2_VECTOR 9
    #define _INPUT_CAPTURE_2_ERROR_VECTOR 10
    #define _INPUT_CAPTURE_2_VECTOR 11
    #define _OUTPUT_COMPARE_2_VECTOR 12
    #define _EXTERNAL_2_VECTOR 13
    #define _TIMER_3_VECTOR 14
    #define _INPUT_CAPTURE_3_ERROR_VECTOR 15
    #define _INPUT_CAPTURE_3_VECTOR 16
    #define _OUTPUT_COMPARE_3_VECTOR 17
    #define _EXTERNAL_3_VECTOR 18
    #define _TIMER_4_VECTOR 19
    #define _INPUT_CAPTURE_4_ERROR_VECTOR 20
    #define _INPUT_CAPTURE_4_VECTOR 21
    #define _OUTPUT_COMPARE_4_VECTOR 22
    #define _EXTERNAL_4_VECTOR 23
    #define _TIMER_5_VECTOR 24
    #define _INPUT_CAPTURE_5_ERROR_VECTOR 25
    #define _INPUT_CAPTURE_5_VECTOR 26
    #define _OUTPUT_COMPARE_5_VECTOR 27
    #define _RTCC_VECTOR 30
    #define _FLASH_CONTROL_VECTOR 31
    #define _COMPARATOR_1_VECTOR 32
    #define _COMPARATOR_2_VECTOR 33
    #define _USB_1_VECTOR 34
    #define _SPI1_FAULT_VECTOR 35
    #define _SPI1_RX_VECTOR 36
    #define _SPI1_TX_VECTOR 37
    #define _UART1_FAULT_VECTOR 38
    #define _UART1_RX_VECTOR 39
    #define _UART1_TX_VECTOR 40
    #define _I2C1_BUS_VECTOR 41
    #define _I2C1_SLAVE_VECTOR 42
    #define _I2C1_MASTER_VECTOR 43
    #define _CHANGE_NOTICE_A_VECTOR 44
    #define _CHANGE_NOTICE_B_VECTOR 45
    #define _CHANGE_NOTICE_C_VECTOR 46
    #define _CHANGE_NOTICE_D_VECTOR 47
    #define _CHANGE_NOTICE_E_VECTOR 48
    #define _CHANGE_NOTICE_F_VECTOR 49
    #define _CHANGE_NOTICE_G_VECTOR 50
    #define _PMP_VECTOR 51
    #define _PMP_ERROR_VECTOR 52
    #define _SPI2_FAULT_VECTOR 53
    #define _SPI2_RX_VECTOR 54
    #define _SPI2_TX_VECTOR 55
    #define _UART2_FAULT_VECTOR 56
    #define _UART2_RX_VECTOR 57
    #define _UART2_TX_VECTOR 58
    #define _I2C2_BUS_VECTOR 59
    #define _I2C2_SLAVE_VECTOR 60
    #define _I2C2_MASTER_VECTOR 61
    #define _UART3_FAULT_VECTOR 62
    #define _UART3_RX_VECTOR 63
    #define _UART3_TX_VECTOR 64
    #define _UART4_FAULT_VECTOR 65
    #define _UART4_RX_VECTOR 66
    #define _UART4_TX_VECTOR 67
    #define _UART5_FAULT_VECTOR 68
    #define _UART5_RX_VECTOR 69
    #define _UART5_TX_VECTOR 70
    #define _CTMU_VECTOR 71
    #define _DMA0_VECTOR 72
    #define _DMA1_VECTOR 73
    #define _DMA2_VECTOR 74
    #define _DMA3_VECTOR 75
    #define _TIMER_6_VECTOR 76
    #define _INPUT_CAPTURE_6_ERROR_VECTOR 77
    #define _INPUT_CAPTURE_6_VECTOR 78
    #define _OUTPUT_COMPARE_6_VECTOR 79
    #define _TIMER_7_VECTOR 80
    #define _INPUT_CAPTURE_7_ERROR_VECTOR 81
    #define _INPUT_CAPTURE_7_VECTOR 82
    #define _OUTPUT_COMPARE_7_VECTOR 83
    #define _TIMER_8_VECTOR 84
    #define _INPUT_CAPTURE_8_ERROR_VECTOR 85
    #define _INPUT_CAPTURE_8_VECTOR 86
    #define _OUTPUT_COMPARE_8_VECTOR 87
    #define _TIMER_9_VECTOR 88
    #define _INPUT_CAPTURE_9_ERROR_VECTOR 89
    #define _INPUT_CAPTURE_9_VECTOR 90
    #define _OUTPUT_COMPARE_9_VECTOR 91
    #define _ADC_VECTOR 92
    #define _ADC_DC1_VECTOR 94
    #define _ADC_DC2_VECTOR 95
    #define _ADC_DF1_VECTOR 96
    #define _ADC_DF2_VECTOR 97
    #define _ADC_DF3_VECTOR 98
    #define _ADC_DF4_VECTOR 99
    #define _ADC_FAULT_VECTOR 100
    #define _ADC_EOS_VECTOR 101
    #define _ADC_ARDY_VECTOR 102
    #define _ADC_URDY_VECTOR 103
    #define _ADC_DMA_VECTOR 104
    #define _ADC_EARLY_VECTOR 105
    #define _ADC_DATA0_VECTOR 106
    #define _ADC_DATA1_VECTOR 107
    #define _ADC_DATA2_VECTOR 108
    #define _ADC_DATA3_VECTOR 109
    #define _ADC_DATA4_VECTOR 110
    #define _ADC_DATA5_VECTOR 111
    #define _ADC_DATA6_VECTOR 112
    #define _ADC_DATA7_VECTOR 113
    #define _ADC_DATA8_VECTOR 114
    #define _ADC_DATA9_VECTOR 115
    #define _ADC_DATA10_VECTOR 116
    #define _ADC_DATA11_VECTOR 117
    #define _ADC_DATA12_VECTOR 118
    #define _ADC_DATA13_VECTOR 119
    #define _ADC_DATA14_VECTOR 120
    #define _ADC_DATA15_VECTOR 121
    #define _ADC_DATA16_VECTOR 122
    #define _ADC_DATA17_VECTOR 123
    #define _ADC_DATA18_VECTOR 124
    #define _ADC_DATA19_VECTOR 125
    #define _ADC_DATA20_VECTOR 126
    #define _ADC_DATA21_VECTOR 127
    #define _ADC_DATA22_VECTOR 128
    #define _ADC_DATA23_VECTOR 129
    #define _ADC_DATA24_VECTOR 130
    #define _ADC_DATA25_VECTOR 131
    #define _ADC_DATA26_VECTOR 132
    #define _ADC_DATA27_VECTOR 133
    #define _ADC_DATA33_VECTOR 139
    #define _ADC_DATA34_VECTOR 140
    #define _ADC_DATA35_VECTOR 141
    #define _ADC_DATA36_VECTOR 142
    #define _ADC_DATA37_VECTOR 143
    #define _ADC_DATA38_VECTOR 144
    #define _ADC_DATA39_VECTOR 145
    #define _ADC_DATA40_VECTOR 146
    #define _ADC_DATA41_VECTOR 147
    #define _ADC_DATA45_VECTOR 151
    #define _ADC_DATA46_VECTOR 152
    #define _ADC_DATA47_VECTOR 153
    #define _ADC_DATA48_VECTOR 154
    #define _ADC_DATA49_VECTOR 155
    #define _ADC_DATA50_VECTOR 156
    #define _ADC_DATA51_VECTOR 157
    #define _ADC_DATA52_VECTOR 158
    #define _ADC_DATA53_VECTOR 159
    #define _COMPARATOR_3_VECTOR 160
    #define _COMPARATOR_4_VECTOR 161
    #define _COMPARATOR_5_VECTOR 162
    #define _UART6_FAULT_VECTOR 164
    #define _UART6_RX_VECTOR 165
    #define _UART6_TX_VECTOR 166
    #define _CAN1_VECTOR 167
    #define _CAN2_VECTOR 168
    #define _QEI1_VECTOR 169
    #define _QEI2_VECTOR 170
    #define _PWM_PRI_VECTOR 171
    #define _PWM_SEC_VECTOR 172
    #define _PWM1_VECTOR 173
    #define _PWM2_VECTOR 174
    #define _PWM3_VECTOR 175
    #define _PWM4_VECTOR 176
    #define _PWM5_VECTOR 177
    #define _PWM6_VECTOR 178
    #define _I2C3_BUS_VECTOR 179
    #define _I2C3_SLAVE_VECTOR 180
    #define _I2C3_MASTER_VECTOR 181
    #define _DMA4_VECTOR 182
    #define _DMA5_VECTOR 183
    #define _DMA6_VECTOR 184
    #define _DMA7_VECTOR 185
    #define _DATA_EE_VECTOR 186
    #define _CAN3_VECTOR 187
    #define _CAN4_VECTOR 188
    #define _QEI3_VECTOR 189
    #define _QEI4_VECTOR 190
    #define _QEI5_VECTOR 191
    #define _QEI6_VECTOR 192
    #define _I2C4_BUS_VECTOR 194
    #define _I2C4_SLAVE_VECTOR 195
    #define _I2C4_MASTER_VECTOR 196
    #define _INPUT_CAPTURE_10_ERROR_VECTOR 197
    #define _INPUT_CAPTURE_10_VECTOR 198
    #define _OUTPUT_COMPARE_10_VECTOR 199
    #define _INPUT_CAPTURE_11_ERROR_VECTOR 200
    #define _INPUT_CAPTURE_11_VECTOR 201
    #define _OUTPUT_COMPARE_11_VECTOR 202
    #define _INPUT_CAPTURE_12_ERROR_VECTOR 203
    #define _INPUT_CAPTURE_12_VECTOR 204
    #define _OUTPUT_COMPARE_12_VECTOR 205
    #define _INPUT_CAPTURE_13_ERROR_VECTOR 206
    #define _INPUT_CAPTURE_13_VECTOR 207
    #define _OUTPUT_COMPARE_13_VECTOR 208
    #define _INPUT_CAPTURE_14_ERROR_VECTOR 209
    #define _INPUT_CAPTURE_14_VECTOR 210
    #define _OUTPUT_COMPARE_14_VECTOR 211
    #define _INPUT_CAPTURE_15_ERROR_VECTOR 212
    #define _INPUT_CAPTURE_15_VECTOR 213
    #define _OUTPUT_COMPARE_15_VECTOR 214
    #define _INPUT_CAPTURE_16_ERROR_VECTOR 215
    #define _INPUT_CAPTURE_16_VECTOR 216
    #define _OUTPUT_COMPARE_16_VECTOR 217
    #define _SPI3_FAULT_VECTOR 218
    #define _SPI3_RX_VECTOR 219
    #define _SPI3_TX_VECTOR 220
    #define _SPI4_FAULT_VECTOR 221
    #define _SPI4_RX_VECTOR 222
    #define _SPI4_TX_VECTOR 223
    #define _SPI5_FAULT_VECTOR 224
    #define _SPI5_RX_VECTOR 225
    #define _SPI5_TX_VECTOR 226
    #define _SPI6_FAULT_VECTOR 227
    #define _SPI6_RX_VECTOR 228
    #define _SPI6_TX_VECTOR 229
    #define _SYSTEM_BUS_PROTECTION_VECTOR 230
    #define _PWM7_VECTOR 238
    #define _PWM8_VECTOR 239
    #define _PWM9_VECTOR 240
    #define _PWM10_VECTOR 241
    #define _PWM11_VECTOR 242
    #define _PWM12_VECTOR 243
    #define _USB_2_VECTOR 244
    #define _ADC_DC3_VECTOR 245
    #define _ADC_DC4_VECTOR 246
    #define _CORE_PERF_COUNT_VECTOR 254
    #define _CORE_FAST_DEBUG_CHAN_VECTOR 255

    #2
    MPaulHolmes
    Junior Member
    • Total Posts : 76
    • Reward points : 0
    • Joined: 2009/10/31 10:52:40
    • Location: 0
    • Status: offline
    Re: PIC32MK1024MCF100 ADC interrupt in C 2019/11/16 09:24:08 (permalink)
    0
    Jackpot!!  Now, is there an example of exactly how to use them?  Like if I wanted to have the ADC be triggered by the center of the PWM period, and have it do all of the primary (adc0 to adc5) simultaneously, would it be something like:
     
    _some_statement_involving__ADC_VECTOR () {
    // Hurray, I now have all the data I need to drive down the road
    }
     
    EDIT:  I think I found it!  Here's an example in the MPLab XC32 compiler datasheet:
    void __ISR(_CORE_TIMER_VECTOR, IPL2SOFT) CoreTimerHandler(void);
     
    So, I would maybe do:
    void __ISR(_ADC_VECTOR, IPL3SOFT) MyNewgloriousADCISR(void);
     
    Thank you for pointing those things out to me.
     
    So, is the difference between 
    __ISR and 
    __ISR_AT_VECTOR basically like using an inline function vs a regular function?  the __ISR_AT_VECTOR is like the inline function?  So it's a tiny bit faster?
    post edited by MPaulHolmes - 2019/11/16 09:43:01
    #3
    Mysil
    Super Member
    • Total Posts : 3642
    • Reward points : 0
    • Joined: 2012/07/01 04:19:50
    • Location: Norway
    • Status: offline
    Re: PIC32MK1024MCF100 ADC interrupt in C 2019/11/16 11:50:31 (permalink)
    5 (1)
    Hi,
    Look in the datasheet for PIC32MK1024MCF100  device, for hints and example.
    See: TABLE 8-1:  Interrupt Latency Information, (datasheet page 118),
     
    Also see: XC32 C Compiler User's Guide.
     
    Your analogy with an inline function isn't quite precise.
    PIC32MK...     and also  PIC32MZ,
    have 256 registers in hardware, each to hold a offset pointer to a ISR function.
    Note that:   _ISR_VECTOR,   isn't a name of a  ISR_function(), it is an index into a table.
    The name of a ISR function does not matter, but as any function name, it must be unique.
     
    Since address offset of each ISR function is stored in a Register, interrupt hardware can know where to go in one step.  So maybe your analogy can be taken as a inline function in hardware.
     
    PIC32MK have 1 set of Shadow registers. You must decide which Interrupt Priority Level shall have the benefit of the shadow register set.   See datasheet for PRISS register, and set it according to your preference.
    (There are 2 General Register Sets, One of those have to be used by the main program and functions called from main,
    so that leave 1 set of registers that may be used as shadow registers in interrupts. )
     
    PIC32MK have 32 general registers, and also a FPU with 32 registers.
    If all of these need to be saved and restored at interrupt entry and leaving, that is a lot of CPU cycles in interrupt prolog and epilog code.
    If you use floating point calculations in some parts of the program,
    but Not in some ISR , then you may tell the compiler that saving Floating point registers is not needed.
     
    Some examples:
    void __attribute__((interrupt(IPL2AUTO), at_vector(_CHANGE_NOTICE_F_VECTOR), aligned(16), no_fpu)) 
    CNF_Interrupt(void)

        /* Interrupt code */
    }

    void __attribute__((interrupt(IPL2AUTO), at_vector(_CHANGE_NOTICE_G_VECTOR), aligned(16), no_fpu))
    CNG_Interrupt(void)
    {
        ...
    }

    void __attribute__((interrupt(IPL2AUTO), at_vector(_CORE_TIMER_VECTOR), aligned(16), no_fpu))
    CT_Interrupt(void)
    {        /* Interrupt code. */
    }
     
    void __attribute__ ((interrupt(IPL4SRS), at_vector(_TIMER_9_VECTOR), aligned(16), nomips16, no_fpu)) Timer9Interrupt(void)
    {
            /* Make sure that PRISS register is correctly programmed,
               before running program using interrupt routine using IPL4SRS */
            /* Interrupt code. */
    }   

     
    Notice, that XC32 compiler will optimize interrupt prolog and epilog code to save and restore only those registers
    that are actually used in ISR, If it can figure out what will actually be used used during compilation.
    This means that small ISR functions, like Timer service updates, that may be written without calling other functions,
    may work well without need for using SRS.
     
    Then you may reserve the SRS priority level, for that big ADC service, Motor Control, or PID regulator service
    that cannot do without calling other functions.
     
    Regards,
        Mysil
    post edited by Mysil - 2019/11/16 12:12:50
    #4
    MPaulHolmes
    Junior Member
    • Total Posts : 76
    • Reward points : 0
    • Joined: 2009/10/31 10:52:40
    • Location: 0
    • Status: offline
    Re: PIC32MK1024MCF100 ADC interrupt in C 2020/01/24 15:09:45 (permalink)
    0
    OK, I'm trying my first interrupt on this new chip now.  It's the timer 7 interrupt.  Does anyone see what I could be missing in this code?  This isn't the complete program of course, but is there anything obvious that I am doing wrong?  The Interrupt flag status bit for timer 7 gets set after TMR7 gets to PR7 + 1, but the interrupt is never run.

    void __attribute__((interrupt(IPL7AUTO), at_vector(_TIMER_7_VECTOR), aligned(16))) Timer7Interrupt (void)
    {
      if (O_PORT_LED == 0) {
        O_LAT_LED = 1;
      }
      else {
        O_LAT_LED = 0;
      }
      IFS2bits.T7IF = 0;
    }
     
    void InitTimers() {
      T7CONbits.T32 = 1; // 32 bit mode enabled.
      PR7 = 240000000 - 1; 
      T7CONbits.TCKPS = 0b0; // prescaler = 1. So, the timer runs at 60,000,000 Hz
      IPC20bits.T7IP = 7;
      IFS2bits.T7IF = 0; // clear the interrupt flag. On reset it starts cleared anyway.
      IEC2bits.T7IE = 1; // TURN on the interrupt.
      T7CONbits.ON = 1;
    }
     
    main() {
    ...
      InitIOPorts();
      InitTimers();
      while (1) {}
    }

     
    #5
    MPaulHolmes
    Junior Member
    • Total Posts : 76
    • Reward points : 0
    • Joined: 2009/10/31 10:52:40
    • Location: 0
    • Status: offline
    Re: PIC32MK1024MCF100 ADC interrupt in C 2020/01/24 15:49:45 (permalink)
    5 (1)
    Oh my goodness.  I had to "enable global interrupts" before I could enable the interrupt.  
    post edited by MPaulHolmes - 2020/01/24 16:07:24
    #6
    jg_ee
    Super Member
    • Total Posts : 187
    • Reward points : 0
    • Joined: 2015/04/30 10:54:52
    • Location: Colorado
    • Status: offline
    Re: PIC32MK1024MCF100 ADC interrupt in C 2020/01/24 15:51:54 (permalink)
    5 (1)
    Have you enabled interrupts globally?  Have you enabled multi-vector interrupts?
     
    INTCONSET = _INTCON_MVEC_MASK;
     __builtin_enable_interrupts();

     
    Also, try to get used to only using the atomic CLR instructions to clear the interrupt flag, and not the bit field call to avoid problems with read-modify-write.
     

    IFS2CLR = _IFS2_T7IF_MASK;

    #7
    MPaulHolmes
    Junior Member
    • Total Posts : 76
    • Reward points : 0
    • Joined: 2009/10/31 10:52:40
    • Location: 0
    • Status: offline
    Re: PIC32MK1024MCF100 ADC interrupt in C 2020/01/24 16:01:38 (permalink)
    0
    Thank you!!  OK I'll start doing the clr instructions instead.  This is... a whole new world, a new fantastic point of view!  haha
     
    So, I just need to set the mvec bit if I want to use both shadow registers?
    post edited by MPaulHolmes - 2020/01/24 16:06:56
    #8
    jg_ee
    Super Member
    • Total Posts : 187
    • Reward points : 0
    • Joined: 2015/04/30 10:54:52
    • Location: Colorado
    • Status: offline
    Re: PIC32MK1024MCF100 ADC interrupt in C 2020/01/24 16:13:53 (permalink)
    0
    It is not necessary for operation, but I generally used multi-vectored by default.  All of the advantages are explained in chapter 8 family reference manual.
    #9
    Jump to:
    © 2020 APG vNext Commercial Version 4.5