Nesting interrupt enables

General discussion on mikroC PRO for dsPIC30/33 and PIC24.
Post Reply
Author
Message
TariqDin
Posts: 2
Joined: 13 Dec 2019 19:44

Nesting interrupt enables

#1 Post by TariqDin » 04 Oct 2020 15:26

Hey,

I'm using a PIC24FJ128GA306 for this project.

As can be seen in the code below i'm trying to enable and disable interrupts on the fly, however my interrupt2 isn't working.
Is it possible to even enable and disable interrupts on the fly? or do I have to go about this in a different way?

Program is supposed to work as follows:
I send a command over uart, once this commands get matched we move a motor till a certain point. This triggers the first interrupt. Once the 1st interrupt has triggered only then do I want interrupt2 to be enabled.
After which I execute whatever in interrupt2. In that same interrupt I want to enable interrupt 1 again and interrupt3. And move them to said pos.

Any suggestions are more than welcome!

Code: Select all

#include "FUNCTIONS.H"

#include "COMMANDS.H"


/*Code written by Tariq Dinmohamed*/

//Version control
char CompileDate[] = __DATE__;
char CompileTime[] = __TIME__;

int xx = 1;
int yy = 1;

/* Definitions Chars/ints for calculations related to UART*/
char receive;
char input[16];

int _flag_1 = 0;
//First interrupt mapped, Get from register 0x000003C(defined by datasheet). ICS is left at auto.
void interrupt1() iv 0x000003C ics ICS_AUTO {
  //Disable interrupt 1 and enable interrupt 2
  IEC1.INT1IE = 0; // Disable interrupt nul bit
  IEC1.INT2IE = 1; // Enable interrupt saftey 2

  IFS1.INT1IF = 0;
  GET_CURRENT_POS();
  _flag_1 = 1;
  //Clear the interrupt flag

}

int _flag_2 = 0;
//Second interrupt mapped, Get from register 0x000004E(defined by datasheet). ICS is left at auto.
void interrupt2() iv 0x000004E ics ICS_AUTO {
  //Clear the interrupt flag
  //IFS1.INT2IF = 0;
  _flag_2 = 1;

  uart1_write_text("interrupt2");

  if (_flag_2 == 1 && PORTD.F4 == 1) {
    uart1_write_text("flag2");
    GET_CURRENT_POS();
    _flag_2 = 0;
    delay_ms(150);
    MOTOR_COMMAND(RORAT5, sizeof(RORAT5));
    while (xx) {
      if (PORTD.F4 == 0) {
        GET_CURRENT_POS();
        xx = 0;
        /*Disable interrupt saftey 1, Enable interrupt saftey 2*/
        IEC1.INT1IE = 1;
        IEC1.INT2IE = 0;
        IEC3.INT3IE = 1;
      }
    }
  }

}

int _flag_3 = 0;
void interrupt3() iv 0x000007E ics ICS_AUTO {
  //Clear the interrupt flag
  IFS1.INT3IF = 0; // Clear interrupt saftey 2 bit
  _flag_3 = 1;

  if (_flag_3 && PORTD.F5 == 1) {
    GET_CURRENT_POS();
    _flag_3 = 0;
    delay_ms(150);
    MOTOR_COMMAND(RORAT5, sizeof(RORAT5));
    while (yy) {
      if (PORTD.F5 == 0) {
        GET_CURRENT_POS();
        yy = 0;
        //Disable interrupt 3
        IEC1.INT1IE = 0;
        IEC1.INT2IE = 0;
        IEC3.INT3IE = 0; // Disable interrupt saftey 2    
      }
    }
  }

}

/* Main Program */
void main() {

  //Setting TRIS&ANS register for pinout
  TRISB = 0x7EEF;
  TRISC = 0xFFFF;
  TRISD = 0xFFFF;
  TRISE = 0xFFFF;
  TRISF = 0x0000;
  TRISG = 0xFFF3;
  ANSD = 0x0000;
  ANSB = 0x0000;

  //Init of UART at 9600 Baudrate
  UART1_Init(9600);
  UART3_Init(9600);

  Delay_ms(1500);
  LATB.F8 = 1;

  Unlock_IOLOCK();
  //UART 1 for device to PC
  PPS_Mapping_NoLock(28, _INPUT, _U1RX); // Sets pin 15 to be Input, and maps RX3/DT3 Input to it
  PPS_Mapping_NoLock(18, _OUTPUT, _U1TX); // Sets pin 5 to be Output

  //UART3 for device to stepperdriver
  PPS_Mapping_NoLock(14, _INPUT, _U3RX); // Sets pin 15 to be Input, and maps RX3/DT3 Input to it
  PPS_Mapping_NoLock(29, _OUTPUT, _U3TX); // Sets pin 5 to be Output

  //interrupt to remappable pins
  PPS_Mapping_NoLock(22, _INPUT, _INT1); // Sets pin 22 to be Input, and maps interrupt
  PPS_Mapping_NoLock(25, _INPUT, _INT2); // Sets pin 25 to be Input, and maps interrupt
  PPS_Mapping_NoLock(20, _INPUT, _INT3); // Sets pin 20 to be Input, and maps interrupt

  Lock_IOLOCK();

  //Interrupt nesting enable
  INTCON1.NSTDIS = 0;
  
  //Interrupt enable bits
  IEC3.INT3IE = 0; // Disable interrupt saftey 2
  IEC1.INT2IE = 0; // Disable interrupt saftey 1

  while (1) {

    //if there is data do something.
    if (uart1_Data_Ready()) {
      uart1_read_text(input, "\r\n", sizeof(input)); // Read String data up to 10th charachter if \r if found stop looking and put data in input.
      //compare what we got in input to whatever we define as a commmand up at the variables.
      if (strcmp(input, COMMAND_START) == 0) {
        /*Actual T3439 testing routine*/
        //Start by moving the UUT right
        MOTOR_COMMAND(ROLAT5, sizeof(ROLAT5));

      } else if (strcmp(input, COMMMAND_STOP) == 0) {
        uart1_write_text("Stopped!");
        MOTOR_COMMAND(STOP, sizeof(STOP));
      } else if (strcmp(input, COMMAND_RESET) == 0) {
        asm {
          reset
        }
      } else {}
    }

    if (PORTD.F4 == 0 && PORTD.F5 == 0) {
      IEC1.INT1IE = 1; //Nul ENABLE TO START TEST    
    }

  }
}

User avatar
filip
mikroElektronika team
Posts: 11874
Joined: 25 Jan 2008 09:56

Re: Nesting interrupt enables

#2 Post by filip » 13 Oct 2020 09:02

Hi,

I apologize for the late reply, have you been able to sort out this issue ?

Regards,
Filip.

TariqDin
Posts: 2
Joined: 13 Dec 2019 19:44

Re: Nesting interrupt enables

#3 Post by TariqDin » 15 Oct 2020 10:41

Yeah, Not sure what really changed here. But I rolled back to an older version.

Code for those interested:

Code: Select all

#include "FUNCTIONS.h"
#include "COMMANDS.h"

/*Code written by Tariq Dinmohamed*/

/*This version works with hand movements, next is adding automated motor movements*/

/* Definitions Chars/ints for calculations related to UART*/
//Char for receiving
char receive;
char input[16] = "";

//Version control
char CompileDate[] = __DATE__;
char CompileTime[] = __TIME__;

int _flag_1 = 1;
int _flag_2 = 0;
int _flag_3 = 0;
int _flag_4 = 0;
int _flag_5 = 0;
int _flag_6 = 0;

//First interrupt mapped, Get from register 0x000003C(defined by datasheet). ICS is left at auto.
void interrupt1() iv 0x000003C ics ICS_AUTO {

  if (_flag_1 == 1) {
    GET_CURRENT_POS();
    delay_ms(500);
    _flag_1 = 0;
    _flag_2 = 1;

    //Disable interrupt 1 and enable interrupt 2
    //Clear interrupt flag:
    IFS1.INT1IF = 0; // Clear interrupt nul bit
    IEC1.INT1IE = 0; // Disable interrupt nul bit
    IEC1.INT2IE = 1; // Enable interrupt saftey 2
  }
  if (_flag_4 == 1) {
    GET_CURRENT_POS();
    _flag_4 = 0;
    _flag_5 = 1;

    //Clear interrupt flag:
    IFS1.INT1IF = 0; // Clear interrupt nul bit
    IEC1.INT1IE = 0; // Disable interrupt nul bit
    IEC3.INT3IE = 1; // Enable interrupt saftey 2
  }
}

//Second interrupt mapped, Get from register 0x000004E(defined by datasheet). ICS is left at auto.
void interrupt2_low() iv 0x000004E ics ICS_AUTO {

  
  if (PORTD.F4 == 1 && _flag_2 == 1) {
    GET_CURRENT_POS();
    _flag_2 = 0;
    _flag_3 = 1;
    delay_ms(500);
    Motor_Command(RORAT5, sizeof(RORAT5));
    
    IFS1.INT2IF = 0; // Clear Safety flag bit
    INTCON2.INT2EP = 1; //Set Safety bit to negative edge detect.
  }
  if (PORTD.F4 == 0 && _flag_3 == 1) {
    GET_CURRENT_POS();
    _flag_3 = 0;
    _flag_4 = 1;
    
    IEC1.INT2IE = 0; // Disable interrupt saftey 2
    IEC1.INT1IE = 1; // Enable interrupt nul bit

  }

}

void interrupt3() iv 0x000007E ics ICS_AUTO {

  
  if (PORTD.F5 == 1 && _flag_5 == 1) {
    GET_CURRENT_POS();
    _flag_5 = 0;
    _flag_6 = 1;
    delay_ms(500);
    Motor_Command(ROLAT5, sizeof(ROLAT5));
    
    IFS1.INT3IF = 0; // Clear interrupt saftey 2 bit
    INTCON2.INT3EP = 1; //Set Safety2 bit to negative edge detect
  }
  if (PORTD.F5 == 0 && _flag_6 == 1) {
    GET_CURRENT_POS();
    _flag_6 = 0;
    delay_ms(50);
    Motor_Command(STOP, sizeof(STOP));
    
    IEC3.INT3IE = 0; // Enable interrupt saftey 2
  }

}

void Get_Command() {
  //if there is data do something.
  if (uart1_Data_Ready()) {
    char input[20];
    uart1_read_text(input, "\r\n", sizeof(input)); // Read String data up to 10th charachter if \r if found stop looking and put data in input.
    //compare what we got in input to whatever we define as a commmand up at the variables.
    if (strcmp(input, COMMAND_GET_POS) == 0) {
      Motor_Command(GET_POS, sizeof(GET_POS));
    } else if (strcmp(input, COMMMAND_SET_0_POS) == 0) {
      Motor_Command(SET_0_POS, sizeof(SET_0_POS));
    } else if (strcmp(input, COMMMAND_MV_ABS_0) == 0) {
      Motor_Command(MV_ABS_0, sizeof(MV_ABS_0));
    } else if (strcmp(input, COMMMAND_RORAT5) == 0) {
      Motor_Command(RORAT5, sizeof(RORAT5));
    } else if (strcmp(input, COMMMAND_ROLAT5) == 0) {
      Motor_Command(ROLAT5, sizeof(ROLAT5));
    } else if (strcmp(input, COMMAND_START) == 0) {

      /*Actual T3439 testing routine*/
      //Start by moving the UUT right
      Motor_Command(ROLAT5, sizeof(ROLAT5));
      delay_ms(1000);

    } else if (strcmp(input, COMMMAND_STOP) == 0) {
      uart1_write_text("Stopped!");
      Motor_Command(STOP, sizeof(STOP));
    } else if (strcmp(input, COMMAND_RESET) == 0) {
      asm {
        reset
      }
    } else {}
  }
}

/* Main Program */
void main() {

  //Setting TRIS&ANS register for pinout
  TRISB = 0x7EEF;
  TRISC = 0xFFFF;
  TRISD = 0xFFFF;
  TRISE = 0xFFFF;
  TRISF = 0x0000;
  TRISG = 0xFFF3;
  ANSD = 0x0000;
  ANSB = 0x0000;

  //Init of UART at 9600 Baudrate
  UART1_Init(9600);
  UART3_Init(9600);

  Delay_ms(3000);
  LATB.F8 = 1;

  Unlock_IOLOCK();
  //UART 1 for device to PC
  PPS_Mapping_NoLock(28, _INPUT, _U1RX); // Sets pin 15 to be Input, and maps RX3/DT3 Input to it
  PPS_Mapping_NoLock(18, _OUTPUT, _U1TX); // Sets pin 5 to be Output

  //UART3 for device to stepperdriver
  PPS_Mapping_NoLock(14, _INPUT, _U3RX); // Sets pin 15 to be Input, and maps RX3/DT3 Input to it
  PPS_Mapping_NoLock(29, _OUTPUT, _U3TX); // Sets pin 5 to be Output

  //interrupt to remappable pins
  PPS_Mapping_NoLock(22, _INPUT, _INT1); // Sets pin 22 to be Input, and maps interrupt
  PPS_Mapping_NoLock(25, _INPUT, _INT2); // Sets pin 25 to be Input, and maps interrupt
  PPS_Mapping_NoLock(20, _INPUT, _INT3); // Sets pin 20 to be Input, and maps interrupt

  Lock_IOLOCK();

  //Interrupt nesting enable
  INTCON1.NSTDIS = 0;
  //Interrupt enable bits
  IEC3.INT3IE = 0; // Disable interrupt saftey 2
  IEC1.INT2IE = 0; // Disable interrupt saftey 1
  IEC1.INT1IE = 1; //Nul ENABLE TO START TEST

  while (1) {

    Get_Command();

  }
}

Post Reply

Return to “mikroC PRO for dsPIC30/33 and PIC24 General”