fubarino / fubarino.github.com

fubarino.github.com
15 stars 12 forks source link

Fubarino Mini Interrupts #27

Closed JacobChrist closed 3 years ago

JacobChrist commented 3 years ago

I'm working on an interrupt lab for the Fubarino Mini 2.0 for my class.

I have found that the macros PIN_INT0-4 are defined as the following in Board_Defs.h:

#define PIN_INT0    24      // B7   non-PPS
#define PIN_INT1    3       // B14  INT1R = RPB14 = 1
#define PIN_INT2    0       // B13  INT2R = RPB13 = 3
#define PIN_INT3    6       // A1   INT3R = RPA1 = 0
#define PIN_INT4    4       // B15  INT4R = RPB15 = 3

Board_Data.c has the following array defined:

const uint8_t external_int_to_digital_pin_PGM[] = {
    NOT_PPS_PIN,            // INT0 is not mappable
    PIN_INT1,               // INT1
    PIN_INT2,               // INT2
    PIN_INT3,               // INT3
    PIN_INT4                // INT4
};

If I use:

   attachInterrupt(PIN_INTx, isrX, MODE);

Where PIN_INTx is a defined interrupt pin and isrX is function that prints out a value if called that looks something like this:

void isr0() 
{ 
  digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); // toggle pin 1
  Serial.println("ISR0");
}

I find that:

PIN_INT1 is mapped to pin 6 RISING or FALING PIN_INT2 is mapped to pin 24 RISING or FALING PIN_INT4 is mapped to pin 4 RISING or FALING

None of the CHANGE interrupt modes work (there is no code to support this type in WInterrupts).

Also, PIN_INT0 and PIN_INT3 do not seem to be working, didn't dig too deep to understand why.

ricklon commented 3 years ago

I've had the same issue for a long time.

For the Autonomous Vehicle project Foocars. I've got custom code for the interrupts. I've been hoping we would support the change notice options to be compatible with the rotary encoder code from Paul at Teensy.

Here's the example sketch with change notice: https://github.com/fubarlabs/foocars/blob/master/cars/templatecar/arduino/FullAutoDrive-mini2/src/FullAutoDrive.ino


//This function pulls the data being populated by the input capture
interrupts.
//it corrects for the timer restarting.
inline int pulseRead(int RCindex){return
(pulseHighTime[RCindex]>0)?(int)(4.0*pulseHighTime[RCindex]/3.0):(int)(4.0*pulseHighTime[RCindex]/3.0+0xFFFF);}
//inline int pulseRead(int RCindex){return
(int)(0.8*pulseHighTime[RCindex]);}

//interrupt service routine for second input capture module
void __USER_ISR InputCaptureTHR_ISR(void) {
  static uint16_t risingEdgeTime = 0;
  static uint16_t fallingEdgeTime = 0;

  clearIntFlag(_INPUT_CAPTURE_4_IRQ);
  if (IC4CONbits.ICBNE == 1)
  {
    if (digitalRead(RC_INPUT_THR) == HIGH)
    {
      risingEdgeTime = IC4BUF;
      pulseLowTime[1] = risingEdgeTime - fallingEdgeTime;
    }
    else
    {
      fallingEdgeTime = IC4BUF;
      pulseHighTime[1] = fallingEdgeTime - risingEdgeTime;
    }
  }
}

//interrupt service routine for first input capture module
void __USER_ISR InputCaptureSTR_ISR(void) {
  static uint16_t risingEdgeTime = 0;
  static uint16_t fallingEdgeTime = 0;

  clearIntFlag(_INPUT_CAPTURE_1_IRQ);
  if (IC1CONbits.ICBNE == 1)
  {
    if (digitalRead(RC_INPUT_STR) == HIGH)
    {
      risingEdgeTime = IC1BUF;
      pulseLowTime[0] = risingEdgeTime - fallingEdgeTime;
    }
    else
    {
      fallingEdgeTime = IC1BUF;
      pulseHighTime[0] = fallingEdgeTime - risingEdgeTime;
    }
  }
}

void setup() {

    Serial.begin(9600);

    Serial.println( "Starting up..." );

    mapPps(0, PPS_IN_IC1);
    mapPps(10, PPS_IN_IC4);

        //setup input capture modules one and two
    IC1CON = 0;
    IC1CONbits.ICM = 1;   // Capture an interrupt on every rising and
falling edge
    IC1CONbits.ICTMR = 1; // Set to user Timer2
    IC1CONbits.ON = 1;    // Turn IC1 on

    IC4CON = 0;
    IC4CONbits.ICM = 1;   // Capture an interrupt on every rising and
falling edge
    IC4CONbits.ICTMR = 1; // Set to user Timer2
    IC4CONbits.ON = 1;    // Turn IC2 on

        /*We're using timer2 for the input capture. This shouldn't
interfere with pwm
          output, which uses timers 3-5.
        */
    PR2 = 0xFFFF;         // This tells timer 2 to count up to 0xFFFF,
after which it will restart at 0
    T2CONbits.TCKPS = 6;  // 1:64 prescale, which means 48MHz/64 or 0.75MHz
clock rate
    T2CONbits.TON = 1;    // Turn on Timer2

    pinMode(RC_INPUT_STR, INPUT);
    pinMode(RC_INPUT_THR, INPUT);
    pinMode(PIN_LED, OUTPUT);
    digitalWrite(PIN_LED, LOW);

        //these lines set up the interrupt functions to trigger
    setIntVector(_INPUT_CAPTURE_1_VECTOR, InputCaptureSTR_ISR);
    setIntPriority(_INPUT_CAPTURE_1_VECTOR, 4, 0);
    clearIntFlag(_INPUT_CAPTURE_1_IRQ);
    setIntEnable(_INPUT_CAPTURE_1_IRQ);

    setIntVector(_INPUT_CAPTURE_4_VECTOR, InputCaptureTHR_ISR);
    setIntPriority(_INPUT_CAPTURE_4_VECTOR, 4, 0);
    clearIntFlag(_INPUT_CAPTURE_4_IRQ);
    setIntEnable(_INPUT_CAPTURE_4_IRQ);
   }

void loop () {
  unsigned long STR_VAL = pulseRead(0); // Read pulse width of
   unsigned long THR_VAL = pulseRead(1); // each channel
}

I hope this is helpful.

--Rick

On Sun, Mar 7, 2021 at 2:26 PM Jacob Christ notifications@github.com wrote:

I'm working on an interrupt lab for the Fubarino Mini 2.0 for my class.

I have found that the macros PIN_INT0-4 are defined as the following in Board_Defs.h:

define PIN_INT0 24 // B7 non-PPS

define PIN_INT1 3 // B14 INT1R = RPB14 = 1

define PIN_INT2 0 // B13 INT2R = RPB13 = 3

define PIN_INT3 6 // A1 INT3R = RPA1 = 0

define PIN_INT4 4 // B15 INT4R = RPB15 = 3

Board_Data.c has the following array defined:

const uint8_t external_int_to_digital_pin_PGM[] = { NOT_PPS_PIN, // INT0 is not mappable PIN_INT1, // INT1 PIN_INT2, // INT2 PIN_INT3, // INT3 PIN_INT4 // INT4 };

If I use:

attachInterrupt(PIN_INTx, isrX, MODE);

Where PIN_INTx is a defined interrupt pin and isrX is function that prints out a value if called that looks something like this:

void isr0() { digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); // toggle pin 1 Serial.println("ISR0"); }

I find that:

PIN_INT1 is mapped to pin 6 RISING or FALING PIN_INT2 is mapped to pin 24 RISING or FALING PIN_INT4 is mapped to pin 4 RISING or FALING

None of the CHANGE interrupt modes work (there is no code to support this type in WInterrupts).

Also, PIN_INT0 and PIN_INT3 do not seem to be working, didn't dig too deep to understand why.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/fubarino/fubarino.github.com/issues/27, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABV3ZHFLOR2I6SSH6S34OLTCPHNJANCNFSM4YYFOXWA .

-- Co-founder Fair Use Building and Research (FUBAR) Labs http://fubarlabs.org

EmbeddedMan commented 3 years ago

Rick,

If you have a fix for the wrong interrupt pin definitions, could you submit a PR to chipKIT to fix them?

*Brian

On Sun, Mar 7, 2021 at 8:46 PM Rick Anderson notifications@github.com wrote:

I've had the same issue for a long time.

For the Autonomous Vehicle project Foocars. I've got custom code for the interrupts. I've been hoping we would support the change notice options to be compatible with the rotary encoder code from Paul at Teensy.

Here's the example sketch with change notice:

https://github.com/fubarlabs/foocars/blob/master/cars/templatecar/arduino/FullAutoDrive-mini2/src/FullAutoDrive.ino


//This function pulls the data being populated by the input capture
interrupts.
//it corrects for the timer restarting.
inline int pulseRead(int RCindex){return

(pulseHighTime[RCindex]>0)?(int)(4.0*pulseHighTime[RCindex]/3.0):(int)(4.0*pulseHighTime[RCindex]/3.0+0xFFFF);}
//inline int pulseRead(int RCindex){return
(int)(0.8*pulseHighTime[RCindex]);}

//interrupt service routine for second input capture module
void __USER_ISR InputCaptureTHR_ISR(void) {
static uint16_t risingEdgeTime = 0;
static uint16_t fallingEdgeTime = 0;

clearIntFlag(_INPUT_CAPTURE_4_IRQ);
if (IC4CONbits.ICBNE == 1)
{
if (digitalRead(RC_INPUT_THR) == HIGH)
{
risingEdgeTime = IC4BUF;
pulseLowTime[1] = risingEdgeTime - fallingEdgeTime;
}
else
{
fallingEdgeTime = IC4BUF;
pulseHighTime[1] = fallingEdgeTime - risingEdgeTime;
}
}
}

//interrupt service routine for first input capture module
void __USER_ISR InputCaptureSTR_ISR(void) {
static uint16_t risingEdgeTime = 0;
static uint16_t fallingEdgeTime = 0;

clearIntFlag(_INPUT_CAPTURE_1_IRQ);
if (IC1CONbits.ICBNE == 1)
{
if (digitalRead(RC_INPUT_STR) == HIGH)
{
risingEdgeTime = IC1BUF;
pulseLowTime[0] = risingEdgeTime - fallingEdgeTime;
}
else
{
fallingEdgeTime = IC1BUF;
pulseHighTime[0] = fallingEdgeTime - risingEdgeTime;
}
}
}

void setup() {

Serial.begin(9600);

Serial.println( "Starting up..." );

mapPps(0, PPS_IN_IC1);
mapPps(10, PPS_IN_IC4);

//setup input capture modules one and two
IC1CON = 0;
IC1CONbits.ICM = 1; // Capture an interrupt on every rising and
falling edge
IC1CONbits.ICTMR = 1; // Set to user Timer2
IC1CONbits.ON = 1; // Turn IC1 on

IC4CON = 0;
IC4CONbits.ICM = 1; // Capture an interrupt on every rising and
falling edge
IC4CONbits.ICTMR = 1; // Set to user Timer2
IC4CONbits.ON = 1; // Turn IC2 on

/*We're using timer2 for the input capture. This shouldn't
interfere with pwm
output, which uses timers 3-5.
*/
PR2 = 0xFFFF; // This tells timer 2 to count up to 0xFFFF,
after which it will restart at 0
T2CONbits.TCKPS = 6; // 1:64 prescale, which means 48MHz/64 or 0.75MHz
clock rate
T2CONbits.TON = 1; // Turn on Timer2

pinMode(RC_INPUT_STR, INPUT);
pinMode(RC_INPUT_THR, INPUT);
pinMode(PIN_LED, OUTPUT);
digitalWrite(PIN_LED, LOW);

//these lines set up the interrupt functions to trigger
setIntVector(_INPUT_CAPTURE_1_VECTOR, InputCaptureSTR_ISR);
setIntPriority(_INPUT_CAPTURE_1_VECTOR, 4, 0);
clearIntFlag(_INPUT_CAPTURE_1_IRQ);
setIntEnable(_INPUT_CAPTURE_1_IRQ);

setIntVector(_INPUT_CAPTURE_4_VECTOR, InputCaptureTHR_ISR);
setIntPriority(_INPUT_CAPTURE_4_VECTOR, 4, 0);
clearIntFlag(_INPUT_CAPTURE_4_IRQ);
setIntEnable(_INPUT_CAPTURE_4_IRQ);
}

void loop () {
unsigned long STR_VAL = pulseRead(0); // Read pulse width of
unsigned long THR_VAL = pulseRead(1); // each channel
}

I hope this is helpful.

--Rick

On Sun, Mar 7, 2021 at 2:26 PM Jacob Christ notifications@github.com wrote:

I'm working on an interrupt lab for the Fubarino Mini 2.0 for my class.

I have found that the macros PIN_INT0-4 are defined as the following in Board_Defs.h:

define PIN_INT0 24 // B7 non-PPS

define PIN_INT1 3 // B14 INT1R = RPB14 = 1

define PIN_INT2 0 // B13 INT2R = RPB13 = 3

define PIN_INT3 6 // A1 INT3R = RPA1 = 0

define PIN_INT4 4 // B15 INT4R = RPB15 = 3

Board_Data.c has the following array defined:

const uint8_t external_int_to_digital_pin_PGM[] = { NOT_PPS_PIN, // INT0 is not mappable PIN_INT1, // INT1 PIN_INT2, // INT2 PIN_INT3, // INT3 PIN_INT4 // INT4 };

If I use:

attachInterrupt(PIN_INTx, isrX, MODE);

Where PIN_INTx is a defined interrupt pin and isrX is function that prints out a value if called that looks something like this:

void isr0() { digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); // toggle pin 1 Serial.println("ISR0"); }

I find that:

PIN_INT1 is mapped to pin 6 RISING or FALING PIN_INT2 is mapped to pin 24 RISING or FALING PIN_INT4 is mapped to pin 4 RISING or FALING

None of the CHANGE interrupt modes work (there is no code to support this type in WInterrupts).

Also, PIN_INT0 and PIN_INT3 do not seem to be working, didn't dig too deep to understand why.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/fubarino/fubarino.github.com/issues/27, or unsubscribe < https://github.com/notifications/unsubscribe-auth/AABV3ZHFLOR2I6SSH6S34OLTCPHNJANCNFSM4YYFOXWA

.

-- Co-founder Fair Use Building and Research (FUBAR) Labs http://fubarlabs.org

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/fubarino/fubarino.github.com/issues/27#issuecomment-792421938, or unsubscribe https://github.com/notifications/unsubscribe-auth/AADN4CD3R6GRZ7AAME3A6CTTCQ27XANCNFSM4YYFOXWA .

ricklon commented 3 years ago

I can try. I've only worked around it by using the code example above. If that code is on the right track I could possibly figure out the problem. But I don't really know, yet.

--Rick

On Sun, Mar 7, 2021 at 9:47 PM Brian Schmalz notifications@github.com wrote:

Rick,

If you have a fix for the wrong interrupt pin definitions, could you submit a PR to chipKIT to fix them?

*Brian

On Sun, Mar 7, 2021 at 8:46 PM Rick Anderson notifications@github.com wrote:

I've had the same issue for a long time.

For the Autonomous Vehicle project Foocars. I've got custom code for the interrupts. I've been hoping we would support the change notice options to be compatible with the rotary encoder code from Paul at Teensy.

Here's the example sketch with change notice:

https://github.com/fubarlabs/foocars/blob/master/cars/templatecar/arduino/FullAutoDrive-mini2/src/FullAutoDrive.ino


//This function pulls the data being populated by the input capture
interrupts.
//it corrects for the timer restarting.
inline int pulseRead(int RCindex){return

(pulseHighTime[RCindex]>0)?(int)(4.0*pulseHighTime[RCindex]/3.0):(int)(4.0*pulseHighTime[RCindex]/3.0+0xFFFF);}
//inline int pulseRead(int RCindex){return
(int)(0.8*pulseHighTime[RCindex]);}

//interrupt service routine for second input capture module
void __USER_ISR InputCaptureTHR_ISR(void) {
static uint16_t risingEdgeTime = 0;
static uint16_t fallingEdgeTime = 0;

clearIntFlag(_INPUT_CAPTURE_4_IRQ);
if (IC4CONbits.ICBNE == 1)
{
if (digitalRead(RC_INPUT_THR) == HIGH)
{
risingEdgeTime = IC4BUF;
pulseLowTime[1] = risingEdgeTime - fallingEdgeTime;
}
else
{
fallingEdgeTime = IC4BUF;
pulseHighTime[1] = fallingEdgeTime - risingEdgeTime;
}
}
}

//interrupt service routine for first input capture module
void __USER_ISR InputCaptureSTR_ISR(void) {
static uint16_t risingEdgeTime = 0;
static uint16_t fallingEdgeTime = 0;

clearIntFlag(_INPUT_CAPTURE_1_IRQ);
if (IC1CONbits.ICBNE == 1)
{
if (digitalRead(RC_INPUT_STR) == HIGH)
{
risingEdgeTime = IC1BUF;
pulseLowTime[0] = risingEdgeTime - fallingEdgeTime;
}
else
{
fallingEdgeTime = IC1BUF;
pulseHighTime[0] = fallingEdgeTime - risingEdgeTime;
}
}
}

void setup() {

Serial.begin(9600);

Serial.println( "Starting up..." );

mapPps(0, PPS_IN_IC1);
mapPps(10, PPS_IN_IC4);

//setup input capture modules one and two
IC1CON = 0;
IC1CONbits.ICM = 1; // Capture an interrupt on every rising and
falling edge
IC1CONbits.ICTMR = 1; // Set to user Timer2
IC1CONbits.ON = 1; // Turn IC1 on

IC4CON = 0;
IC4CONbits.ICM = 1; // Capture an interrupt on every rising and
falling edge
IC4CONbits.ICTMR = 1; // Set to user Timer2
IC4CONbits.ON = 1; // Turn IC2 on

/*We're using timer2 for the input capture. This shouldn't
interfere with pwm
output, which uses timers 3-5.
*/
PR2 = 0xFFFF; // This tells timer 2 to count up to 0xFFFF,
after which it will restart at 0
T2CONbits.TCKPS = 6; // 1:64 prescale, which means 48MHz/64 or 0.75MHz
clock rate
T2CONbits.TON = 1; // Turn on Timer2

pinMode(RC_INPUT_STR, INPUT);
pinMode(RC_INPUT_THR, INPUT);
pinMode(PIN_LED, OUTPUT);
digitalWrite(PIN_LED, LOW);

//these lines set up the interrupt functions to trigger
setIntVector(_INPUT_CAPTURE_1_VECTOR, InputCaptureSTR_ISR);
setIntPriority(_INPUT_CAPTURE_1_VECTOR, 4, 0);
clearIntFlag(_INPUT_CAPTURE_1_IRQ);
setIntEnable(_INPUT_CAPTURE_1_IRQ);

setIntVector(_INPUT_CAPTURE_4_VECTOR, InputCaptureTHR_ISR);
setIntPriority(_INPUT_CAPTURE_4_VECTOR, 4, 0);
clearIntFlag(_INPUT_CAPTURE_4_IRQ);
setIntEnable(_INPUT_CAPTURE_4_IRQ);
}

void loop () {
unsigned long STR_VAL = pulseRead(0); // Read pulse width of
unsigned long THR_VAL = pulseRead(1); // each channel
}

I hope this is helpful.

--Rick

On Sun, Mar 7, 2021 at 2:26 PM Jacob Christ notifications@github.com wrote:

I'm working on an interrupt lab for the Fubarino Mini 2.0 for my class.

I have found that the macros PIN_INT0-4 are defined as the following in Board_Defs.h:

define PIN_INT0 24 // B7 non-PPS

define PIN_INT1 3 // B14 INT1R = RPB14 = 1

define PIN_INT2 0 // B13 INT2R = RPB13 = 3

define PIN_INT3 6 // A1 INT3R = RPA1 = 0

define PIN_INT4 4 // B15 INT4R = RPB15 = 3

Board_Data.c has the following array defined:

const uint8_t external_int_to_digital_pin_PGM[] = { NOT_PPS_PIN, // INT0 is not mappable PIN_INT1, // INT1 PIN_INT2, // INT2 PIN_INT3, // INT3 PIN_INT4 // INT4 };

If I use:

attachInterrupt(PIN_INTx, isrX, MODE);

Where PIN_INTx is a defined interrupt pin and isrX is function that prints out a value if called that looks something like this:

void isr0() { digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); // toggle pin 1 Serial.println("ISR0"); }

I find that:

PIN_INT1 is mapped to pin 6 RISING or FALING PIN_INT2 is mapped to pin 24 RISING or FALING PIN_INT4 is mapped to pin 4 RISING or FALING

None of the CHANGE interrupt modes work (there is no code to support this type in WInterrupts).

Also, PIN_INT0 and PIN_INT3 do not seem to be working, didn't dig too deep to understand why.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/fubarino/fubarino.github.com/issues/27, or unsubscribe <

https://github.com/notifications/unsubscribe-auth/AABV3ZHFLOR2I6SSH6S34OLTCPHNJANCNFSM4YYFOXWA

.

-- Co-founder Fair Use Building and Research (FUBAR) Labs http://fubarlabs.org

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub < https://github.com/fubarino/fubarino.github.com/issues/27#issuecomment-792421938 , or unsubscribe < https://github.com/notifications/unsubscribe-auth/AADN4CD3R6GRZ7AAME3A6CTTCQ27XANCNFSM4YYFOXWA

.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/fubarino/fubarino.github.com/issues/27#issuecomment-792422358, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABV3ZAGCZ5MWQF5N7OJYF3TCQ3FTANCNFSM4YYFOXWA .

-- Co-founder Fair Use Building and Research (FUBAR) Labs http://fubarlabs.org

EmbeddedMan commented 3 years ago

No worries Rick. I'll work on it too and see if I can get things straightened out.

*Brian

On Sun, Mar 7, 2021 at 8:54 PM Rick Anderson notifications@github.com wrote:

I can try. I've only worked around it by using the code example above. If that code is on the right track I could possibly figure out the problem. But I don't really know, yet.

--Rick

On Sun, Mar 7, 2021 at 9:47 PM Brian Schmalz notifications@github.com wrote:

Rick,

If you have a fix for the wrong interrupt pin definitions, could you submit a PR to chipKIT to fix them?

*Brian

On Sun, Mar 7, 2021 at 8:46 PM Rick Anderson notifications@github.com wrote:

I've had the same issue for a long time.

For the Autonomous Vehicle project Foocars. I've got custom code for the interrupts. I've been hoping we would support the change notice options to be compatible with the rotary encoder code from Paul at Teensy.

Here's the example sketch with change notice:

https://github.com/fubarlabs/foocars/blob/master/cars/templatecar/arduino/FullAutoDrive-mini2/src/FullAutoDrive.ino



//This function pulls the data being populated by the input capture
interrupts.
//it corrects for the timer restarting.
inline int pulseRead(int RCindex){return

(pulseHighTime[RCindex]>0)?(int)(4.0pulseHighTime[RCindex]/3.0):(int)(4.0pulseHighTime[RCindex]/3.0+0xFFFF);}

//inline int pulseRead(int RCindex){return (int)(0.8*pulseHighTime[RCindex]);}

//interrupt service routine for second input capture module void __USER_ISR InputCaptureTHR_ISR(void) { static uint16_t risingEdgeTime = 0; static uint16_t fallingEdgeTime = 0;

clearIntFlag(_INPUT_CAPTURE_4_IRQ); if (IC4CONbits.ICBNE == 1) { if (digitalRead(RC_INPUT_THR) == HIGH) { risingEdgeTime = IC4BUF; pulseLowTime[1] = risingEdgeTime - fallingEdgeTime; } else { fallingEdgeTime = IC4BUF; pulseHighTime[1] = fallingEdgeTime - risingEdgeTime; } } }

//interrupt service routine for first input capture module void __USER_ISR InputCaptureSTR_ISR(void) { static uint16_t risingEdgeTime = 0; static uint16_t fallingEdgeTime = 0;

clearIntFlag(_INPUT_CAPTURE_1_IRQ); if (IC1CONbits.ICBNE == 1) { if (digitalRead(RC_INPUT_STR) == HIGH) { risingEdgeTime = IC1BUF; pulseLowTime[0] = risingEdgeTime - fallingEdgeTime; } else { fallingEdgeTime = IC1BUF; pulseHighTime[0] = fallingEdgeTime - risingEdgeTime; } } }

void setup() {

Serial.begin(9600);

Serial.println( "Starting up..." );

mapPps(0, PPS_IN_IC1); mapPps(10, PPS_IN_IC4);

//setup input capture modules one and two IC1CON = 0; IC1CONbits.ICM = 1; // Capture an interrupt on every rising and falling edge IC1CONbits.ICTMR = 1; // Set to user Timer2 IC1CONbits.ON = 1; // Turn IC1 on

IC4CON = 0; IC4CONbits.ICM = 1; // Capture an interrupt on every rising and falling edge IC4CONbits.ICTMR = 1; // Set to user Timer2 IC4CONbits.ON = 1; // Turn IC2 on

/We're using timer2 for the input capture. This shouldn't interfere with pwm output, which uses timers 3-5. / PR2 = 0xFFFF; // This tells timer 2 to count up to 0xFFFF, after which it will restart at 0 T2CONbits.TCKPS = 6; // 1:64 prescale, which means 48MHz/64 or 0.75MHz clock rate T2CONbits.TON = 1; // Turn on Timer2

pinMode(RC_INPUT_STR, INPUT); pinMode(RC_INPUT_THR, INPUT); pinMode(PIN_LED, OUTPUT); digitalWrite(PIN_LED, LOW);

//these lines set up the interrupt functions to trigger setIntVector(_INPUT_CAPTURE_1_VECTOR, InputCaptureSTR_ISR); setIntPriority(_INPUT_CAPTURE_1_VECTOR, 4, 0); clearIntFlag(_INPUT_CAPTURE_1_IRQ); setIntEnable(_INPUT_CAPTURE_1_IRQ);

setIntVector(_INPUT_CAPTURE_4_VECTOR, InputCaptureTHR_ISR); setIntPriority(_INPUT_CAPTURE_4_VECTOR, 4, 0); clearIntFlag(_INPUT_CAPTURE_4_IRQ); setIntEnable(_INPUT_CAPTURE_4_IRQ); }

void loop () { unsigned long STR_VAL = pulseRead(0); // Read pulse width of unsigned long THR_VAL = pulseRead(1); // each channel }



I hope this is helpful.

--Rick

On Sun, Mar 7, 2021 at 2:26 PM Jacob Christ <notifications@github.com>
wrote:

> I'm working on an interrupt lab for the Fubarino Mini 2.0 for my
class.
>
> I have found that the macros PIN_INT0-4 are defined as the following
in
> Board_Defs.h:
>
> #define PIN_INT0 24 // B7 non-PPS
> #define PIN_INT1 3 // B14 INT1R = RPB14 = 1
> #define PIN_INT2 0 // B13 INT2R = RPB13 = 3
> #define PIN_INT3 6 // A1 INT3R = RPA1 = 0
> #define PIN_INT4 4 // B15 INT4R = RPB15 = 3
>
> Board_Data.c has the following array defined:
>
> const uint8_t external_int_to_digital_pin_PGM[] = {
> NOT_PPS_PIN, // INT0 is not mappable
> PIN_INT1, // INT1
> PIN_INT2, // INT2
> PIN_INT3, // INT3
> PIN_INT4 // INT4
> };
>
> If I use:
>
> attachInterrupt(PIN_INTx, isrX, MODE);
>
> Where PIN_INTx is a defined interrupt pin and isrX is function that
prints
> out a value if called that looks something like this:
>
> void isr0()
> {
> digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); // toggle pin 1
> Serial.println("ISR0");
> }
>
> I find that:
>
> PIN_INT1 is mapped to pin 6 RISING or FALING
> PIN_INT2 is mapped to pin 24 RISING or FALING
> PIN_INT4 is mapped to pin 4 RISING or FALING
>
> None of the CHANGE interrupt modes work (there is no code to support
this
> type in WInterrupts).
>
> Also, PIN_INT0 and PIN_INT3 do not seem to be working, didn't dig too
deep
> to understand why.
>
> —
> You are receiving this because you are subscribed to this thread.
> Reply to this email directly, view it on GitHub
> <https://github.com/fubarino/fubarino.github.com/issues/27>, or
> unsubscribe
> <

https://github.com/notifications/unsubscribe-auth/AABV3ZHFLOR2I6SSH6S34OLTCPHNJANCNFSM4YYFOXWA

.

-- Co-founder Fair Use Building and Research (FUBAR) Labs http://fubarlabs.org

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub <

https://github.com/fubarino/fubarino.github.com/issues/27#issuecomment-792421938

, or unsubscribe <

https://github.com/notifications/unsubscribe-auth/AADN4CD3R6GRZ7AAME3A6CTTCQ27XANCNFSM4YYFOXWA

.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub < https://github.com/fubarino/fubarino.github.com/issues/27#issuecomment-792422358 , or unsubscribe < https://github.com/notifications/unsubscribe-auth/AABV3ZAGCZ5MWQF5N7OJYF3TCQ3FTANCNFSM4YYFOXWA

.

-- Co-founder Fair Use Building and Research (FUBAR) Labs http://fubarlabs.org

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/fubarino/fubarino.github.com/issues/27#issuecomment-792424125, or unsubscribe https://github.com/notifications/unsubscribe-auth/AADN4CBRPLXYU3B5SXV6SBLTCQ36XANCNFSM4YYFOXWA .

ricklon commented 3 years ago

My code was about using INPUT CAPTURE. It required mapping the pins via:

 mapPps(0, PPS_IN_IC1);
 mapPps(10, PPS_IN_IC4);

On Sun, Mar 7, 2021 at 9:56 PM Brian Schmalz notifications@github.com wrote:

No worries Rick. I'll work on it too and see if I can get things straightened out.

*Brian

On Sun, Mar 7, 2021 at 8:54 PM Rick Anderson notifications@github.com wrote:

I can try. I've only worked around it by using the code example above. If that code is on the right track I could possibly figure out the problem. But I don't really know, yet.

--Rick

On Sun, Mar 7, 2021 at 9:47 PM Brian Schmalz notifications@github.com wrote:

Rick,

If you have a fix for the wrong interrupt pin definitions, could you submit a PR to chipKIT to fix them?

*Brian

On Sun, Mar 7, 2021 at 8:46 PM Rick Anderson <notifications@github.com

wrote:

I've had the same issue for a long time.

For the Autonomous Vehicle project Foocars. I've got custom code for the interrupts. I've been hoping we would support the change notice options to be compatible with the rotary encoder code from Paul at Teensy.

Here's the example sketch with change notice:

https://github.com/fubarlabs/foocars/blob/master/cars/templatecar/arduino/FullAutoDrive-mini2/src/FullAutoDrive.ino



//This function pulls the data being populated by the input capture
interrupts.
//it corrects for the timer restarting.
inline int pulseRead(int RCindex){return

(pulseHighTime[RCindex]>0)?(int)(4.0pulseHighTime[RCindex]/3.0):(int)(4.0pulseHighTime[RCindex]/3.0+0xFFFF);}

//inline int pulseRead(int RCindex){return (int)(0.8*pulseHighTime[RCindex]);}

//interrupt service routine for second input capture module void __USER_ISR InputCaptureTHR_ISR(void) { static uint16_t risingEdgeTime = 0; static uint16_t fallingEdgeTime = 0;

clearIntFlag(_INPUT_CAPTURE_4_IRQ); if (IC4CONbits.ICBNE == 1) { if (digitalRead(RC_INPUT_THR) == HIGH) { risingEdgeTime = IC4BUF; pulseLowTime[1] = risingEdgeTime - fallingEdgeTime; } else { fallingEdgeTime = IC4BUF; pulseHighTime[1] = fallingEdgeTime - risingEdgeTime; } } }

//interrupt service routine for first input capture module void __USER_ISR InputCaptureSTR_ISR(void) { static uint16_t risingEdgeTime = 0; static uint16_t fallingEdgeTime = 0;

clearIntFlag(_INPUT_CAPTURE_1_IRQ); if (IC1CONbits.ICBNE == 1) { if (digitalRead(RC_INPUT_STR) == HIGH) { risingEdgeTime = IC1BUF; pulseLowTime[0] = risingEdgeTime - fallingEdgeTime; } else { fallingEdgeTime = IC1BUF; pulseHighTime[0] = fallingEdgeTime - risingEdgeTime; } } }

void setup() {

Serial.begin(9600);

Serial.println( "Starting up..." );

mapPps(0, PPS_IN_IC1); mapPps(10, PPS_IN_IC4);

//setup input capture modules one and two IC1CON = 0; IC1CONbits.ICM = 1; // Capture an interrupt on every rising and falling edge IC1CONbits.ICTMR = 1; // Set to user Timer2 IC1CONbits.ON = 1; // Turn IC1 on

IC4CON = 0; IC4CONbits.ICM = 1; // Capture an interrupt on every rising and falling edge IC4CONbits.ICTMR = 1; // Set to user Timer2 IC4CONbits.ON = 1; // Turn IC2 on

/We're using timer2 for the input capture. This shouldn't interfere with pwm output, which uses timers 3-5. / PR2 = 0xFFFF; // This tells timer 2 to count up to 0xFFFF, after which it will restart at 0 T2CONbits.TCKPS = 6; // 1:64 prescale, which means 48MHz/64 or 0.75MHz clock rate T2CONbits.TON = 1; // Turn on Timer2

pinMode(RC_INPUT_STR, INPUT); pinMode(RC_INPUT_THR, INPUT); pinMode(PIN_LED, OUTPUT); digitalWrite(PIN_LED, LOW);

//these lines set up the interrupt functions to trigger setIntVector(_INPUT_CAPTURE_1_VECTOR, InputCaptureSTR_ISR); setIntPriority(_INPUT_CAPTURE_1_VECTOR, 4, 0); clearIntFlag(_INPUT_CAPTURE_1_IRQ); setIntEnable(_INPUT_CAPTURE_1_IRQ);

setIntVector(_INPUT_CAPTURE_4_VECTOR, InputCaptureTHR_ISR); setIntPriority(_INPUT_CAPTURE_4_VECTOR, 4, 0); clearIntFlag(_INPUT_CAPTURE_4_IRQ); setIntEnable(_INPUT_CAPTURE_4_IRQ); }

void loop () { unsigned long STR_VAL = pulseRead(0); // Read pulse width of unsigned long THR_VAL = pulseRead(1); // each channel }



I hope this is helpful.

--Rick

On Sun, Mar 7, 2021 at 2:26 PM Jacob Christ <
notifications@github.com>
wrote:

> I'm working on an interrupt lab for the Fubarino Mini 2.0 for my
class.
>
> I have found that the macros PIN_INT0-4 are defined as the
following
in
> Board_Defs.h:
>
> #define PIN_INT0 24 // B7 non-PPS
> #define PIN_INT1 3 // B14 INT1R = RPB14 = 1
> #define PIN_INT2 0 // B13 INT2R = RPB13 = 3
> #define PIN_INT3 6 // A1 INT3R = RPA1 = 0
> #define PIN_INT4 4 // B15 INT4R = RPB15 = 3
>
> Board_Data.c has the following array defined:
>
> const uint8_t external_int_to_digital_pin_PGM[] = {
> NOT_PPS_PIN, // INT0 is not mappable
> PIN_INT1, // INT1
> PIN_INT2, // INT2
> PIN_INT3, // INT3
> PIN_INT4 // INT4
> };
>
> If I use:
>
> attachInterrupt(PIN_INTx, isrX, MODE);
>
> Where PIN_INTx is a defined interrupt pin and isrX is function that
prints
> out a value if called that looks something like this:
>
> void isr0()
> {
> digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); // toggle
pin 1
> Serial.println("ISR0");
> }
>
> I find that:
>
> PIN_INT1 is mapped to pin 6 RISING or FALING
> PIN_INT2 is mapped to pin 24 RISING or FALING
> PIN_INT4 is mapped to pin 4 RISING or FALING
>
> None of the CHANGE interrupt modes work (there is no code to
support
this
> type in WInterrupts).
>
> Also, PIN_INT0 and PIN_INT3 do not seem to be working, didn't dig
too
deep
> to understand why.
>
> —
> You are receiving this because you are subscribed to this thread.
> Reply to this email directly, view it on GitHub
> <https://github.com/fubarino/fubarino.github.com/issues/27>, or
> unsubscribe
> <

https://github.com/notifications/unsubscribe-auth/AABV3ZHFLOR2I6SSH6S34OLTCPHNJANCNFSM4YYFOXWA

.

-- Co-founder Fair Use Building and Research (FUBAR) Labs http://fubarlabs.org

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub <

https://github.com/fubarino/fubarino.github.com/issues/27#issuecomment-792421938

, or unsubscribe <

https://github.com/notifications/unsubscribe-auth/AADN4CD3R6GRZ7AAME3A6CTTCQ27XANCNFSM4YYFOXWA

.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub <

https://github.com/fubarino/fubarino.github.com/issues/27#issuecomment-792422358

, or unsubscribe <

https://github.com/notifications/unsubscribe-auth/AABV3ZAGCZ5MWQF5N7OJYF3TCQ3FTANCNFSM4YYFOXWA

.

-- Co-founder Fair Use Building and Research (FUBAR) Labs http://fubarlabs.org

— You are receiving this because you commented. Reply to this email directly, view it on GitHub < https://github.com/fubarino/fubarino.github.com/issues/27#issuecomment-792424125 , or unsubscribe < https://github.com/notifications/unsubscribe-auth/AADN4CBRPLXYU3B5SXV6SBLTCQ36XANCNFSM4YYFOXWA

.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/fubarino/fubarino.github.com/issues/27#issuecomment-792424585, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABV3ZEB6PF4G2K7Q73VB73TCQ4EXANCNFSM4YYFOXWA .

-- Co-founder Fair Use Building and Research (FUBAR) Labs http://fubarlabs.org

EmbeddedMan commented 3 years ago

@JacobChrist So one of the issues here is that according to the Arduino documentation (https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/) the first argument to attachInterrupt() is NOT a pin, but an interrupt number.

So if you wanted to use INT1, you would do attachInterrupt(digitalPinToInterrupt(PIN_INT1), foo, RISING); That would 'look up' the actual interrupt number based on the pin PIN_INT1.

Having said that, using this does not fully solve our problem. I'm investigating now and will either provide an update to our FB Mini documentation, or a PR to chipKIT Core to fix the issue. In addition, I will update the example code here : https://github.com/fubarino/fubarino.github.com/wiki/Code-Examples to show the proper use of digitalPinToInterrupt().

EmbeddedMan commented 3 years ago

@JacobChrist OK, I have confirmed that the code is working as expected. No changes to chipKIT core are needed.

If you use the following code: attachInterrupt(digitalPinToInterrupt(PIN_INT4), intHandle, RISING); you will get the expected result. Use PIN_INT0 and it will be on digital pin 24. INT1 is pin 3, INT2 is pin 0, INT3 is pin 6 and INT4 is pin 4. I have verified all of these work as expected on Fubarino Mini 2.0.

I've updated the Fubarino Mini User's Guide with a section on interrupts. Note also that this page https://github.com/fubarino/fubarino.github.com/wiki/Fubarino-mini-board-pin-features already contains an Interrupt example for FBMini showing that you can also use a raw interrupt number for attachInterrupt().

So I feel like the interrupt-to-pin problems you were having are now all explained.

The lack of a CHANGE option is frustrating, but implementing that into chipKIT core is a bigger amount of work than I have time for right now. I'll make sure there is an issue documenting it, but I don't except it to get solved anytime soon unless somebody wants to go in and add it.

JacobChrist commented 3 years ago

Nice, makes since. I'll check it out (probably this weekend).

JacobChrist commented 3 years ago

Brian,

I just got to this and I agree it is working on the Fub Mini 2.0 and consistent with Arduino documentation on the subject. The PIN_INTx macro's appear to be intended for internal house keeping and probably are not meant be be use by the user.

Simply changing this code:

  attachInterrupt(digitalPinToInterrupt(PIN_INT0), isr0, RISING);
  attachInterrupt(digitalPinToInterrupt(PIN_INT1), isr1, RISING);
  attachInterrupt(digitalPinToInterrupt(PIN_INT2), isr2, RISING);
  attachInterrupt(digitalPinToInterrupt(PIN_INT3), isr3, RISING);
  attachInterrupt(digitalPinToInterrupt(PIN_INT4), isr4, RISING);

To this:

  attachInterrupt(digitalPinToInterrupt(24), isr0, RISING);
  attachInterrupt(digitalPinToInterrupt(3), isr1, RISING);
  attachInterrupt(digitalPinToInterrupt(0), isr2, RISING);
  attachInterrupt(digitalPinToInterrupt(6), isr3, RISING);
  attachInterrupt(digitalPinToInterrupt(4), isr4, RISING);

Makes things a lot more readable, you just need to know which pins can be interrupts. I'm telling you this not because you don't already know it but for when sometime in 2025 I need this information again that I can easily find it.