PIC32 Input Capture Interrupt not generating

m4l490n wrote on Monday, September 01, 2014:

Hello everybody

I’m having problems with the Input Capture Interrupt and the problem is that is not generating. I have other interrupts in the system and these are working ok. Here are the files I’m using and their contents.


incap2_isr_wrapper.S

#include <p32xxxx.h>
#include <sys/asm.h>
#include "ISR_Support.h"

	.set	nomips16
	.set 	noreorder
 	
	.extern vInputCapture2InterruptHandler
	.extern xISRStackTop
	.global	vInputCapture2InterruptWrapper

	.set	noreorder
	.set 	noat
	.ent	vInputCapture2InterruptWrapper

vInputCapture2InterruptWrapper:

	portSAVE_CONTEXT
	jal vInputCapture2InterruptHandler
	nop
	portRESTORE_CONTEXT

	.end	vInputCapture2InterruptWrapper


isr.c

void __ISR(_INPUT_CAPTURE_2_VECTOR, ipl6) vInputCapture2InterruptWrapper(void);

void vInputCapture2InterruptHandler(void)
{
   static portBASE_TYPE xHigherPriorityTaskWoken;
   uint16_t input_capture = 0; /* Varable where the input capture value is read */

   xHigherPriorityTaskWoken = pdFALSE;

   // Clear the interrupt flag
   INTClearFlag(INT_SOURCE_INPUT_CAP(INT_IC2));

   /*--------------------------- Add Application Code Here ------------------------------- */

   if (mIC2CaptureReady())
   {
      /* Read captures while there still data in the capture buffer */
      do
      {
         input_capture = mIC2ReadCapture();
      }while(mIC2CaptureReady());
   }

   xQueueSendFromISR(InputCapDrvEventQueue, &input_capture, xHigherPriorityTaskWoken);

   /* ------------------------------------------------------------------------------------ */

   /* If DMA interrupt necessitates a context switch, then switch now. */
   portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
}

input_compare.c

static void Input_Cap_Driver_Setup(void)
{
   /* Set INT controller priority */
   INTSetVectorPriority(INT_VECTOR_INPUT_CAP(INT_INPUT_CAPTURE_2_VECTOR), (configKERNEL_INTERRUPT_PRIORITY + 2));
   INTSetVectorSubPriority(INT_VECTOR_INPUT_CAP(INT_INPUT_CAPTURE_2_VECTOR), (configMAX_SYSCALL_INTERRUPT_PRIORITY));

   OpenTimer2(T2_ON | T2_SOURCE_INT | T2_PS_1_256 | T2_IDLE_CON, PERIOD);

   OpenCapture2(IC_EVERY_RISE_EDGE | IC_INT_1CAPTURE | IC_TIMER2_SRC | IC_CAP_16BIT | IC_IDLE_CON | IC_ON);

   INTEnable(INT_IC2, INT_ENABLED);
}

I think everything is alright but if I put a breakpoint in the handler the execution doesn’t stop. If I hit “pause” in the debug session then the IFS0 register show that the IC2IF is set and also the IC2CON shows that there is a capture present (ICBNE = 1). Also I’ve verified that IC2IE at IEC0 is set so I don’t know what happens.

Has anybody used the PIC32 Input Capture module with FreeRTOS and have a working example?

By the way, I have a 25Hz 50% duty cycle pwm signal at the IC2 input pin so I think that’s not the problem.

Regards

rtel wrote on Monday, September 01, 2014:

Does the interrupt work if you are not using FreeRTOS? It might not be a FreeRTOS question.

Regards.

m4l490n wrote on Monday, September 01, 2014:

Thanks for answering

You are right, I haven’t checked if the interrupt works without FreeRTOS, I jumped directly in to FreeRTOS. I’ll check that.

Regards.

m4l490n wrote on Monday, September 01, 2014:

Hi there

I implemented the isolated code to use the Input Capture for the PIC32 usig this code.

#include <xc.h>
#include <plib.h>
#include <stdint.h>

#pragma config UPLLEN   = ON            // USB PLL Enabled
#pragma config FPLLMUL  = MUL_20
#pragma config UPLLIDIV = DIV_2         // USB PLL Input Divider
#pragma config FPLLIDIV = DIV_2
#pragma config FPLLODIV = DIV_1
#pragma config FPBDIV   = DIV_2
#pragma config FWDTEN   = OFF
#pragma config POSCMOD  = HS
#pragma config FNOSC    = PRIPLL
#pragma config CP       = OFF
#pragma config BWP      = OFF
#pragma config PWP      = OFF
#pragma config FSRSSEL  = PRIORITY_7

#define SYS_FREQ (80000000L)
#define PERIOD  0xFFFF
#define SIZE    1000

uint16_t CaptureTime[SIZE]; // Used to store the captured timer value
volatile uint32_t array_index = 0;

int main(void)
{
    SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);

    OpenTimer2(T2_ON | T2_SOURCE_INT | T2_PS_1_256, PERIOD);

    OpenCapture2(IC_EVERY_RISE_EDGE | IC_INT_1CAPTURE | IC_TIMER2_SRC | IC_CAP_16BIT | IC_IDLE_CON | IC_ON);

    // Set up the input capture 1 interrupt with a priority of 2, subpriority of 0
    INTEnable(INT_IC2, INT_ENABLED);
    INTSetVectorPriority(INT_INPUT_CAPTURE_2_VECTOR, INT_PRIORITY_LEVEL_2);
    INTSetVectorSubPriority(INT_INPUT_CAPTURE_2_VECTOR, INT_SUB_PRIORITY_LEVEL_0);

    // Enable multi-vector interrupts
    INTConfigureSystem(INT_SYSTEM_CONFIG_MULT_VECTOR);
    INTEnableInterrupts();

    while(1)
    {
       // Waiting for input capture event (stuck in this loop)
    }

    // Not executed
    CloseCapture2();
    CloseTimer2();

    return 0;
}

// Configure the input capture interrupt handler
void __ISR(_INPUT_CAPTURE_2_VECTOR, ipl2) InputCapture_Handler(void)
{
    // Clear the interrupt flag
    INTClearFlag(INT_IC2);

    if(mIC2CaptureReady())
    {
       do
       {
          // Store the timer value of the capture event into CaptureTime variable
          CaptureTime[array_index++] = mIC2ReadCapture();

          if(SIZE == array_index)
          {
             array_index = 0;
             Nop();
          }
       }while(mIC2CaptureReady());
    }
}

And it works perfectly. If I put a breakpoint in the Nop(); then I can see my CaptureTime array filled with 1000 captures that reflect the exact frequency of my input.

So, the input compare feature is working isolated and without FreeRTOS.

Have anyone implemented Input Capture for the PIC32 with FreeRTOS that can help me please?

Regards.