Pages: [1]   Go Down
Author Topic: Override attachInterrupt()  (Read 830 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Full Member
***
Karma: 1
Posts: 160
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi everyone,
I'm working on an Arduino Due custom board and i need to use interrupts on other pins not numbered on the orginal board.
Thus i rewrited the attachInterrupt function in this way:
Code:
void attachInterrupt(Pio* pPio, uint32_t dwMask, void (*callback)(void), uint32_t mode)
{
static int enabled = 0;
if (!enabled)
{
__initialize();
enabled = 1;
}

uint32_t pos = 0;
uint32_t t;

for (t = dwMask; t > 1; t >>= 1; pos++);

// Set callback function
if (pPio == PIOA) callbacksPioA[pos] = callback;
if (pPio == PIOB) callbacksPioB[pos] = callback;
if (pPio == PIOC) callbacksPioC[pos] = callback;
if (pPio == PIOD) callbacksPioD[pos] = callback;

// Configure the Interrupt mode
if (mode == CHANGE)
{
// Disable additional interupt mode (detects both rising and falling edge)
pPio -> PIO_AIMDR = dwMask;
}
else
{
// Enable aditional interrupt mode
pPio -> PIO_AIMER = dwMask;

if (mode == LOW)
{
pPio -> PIO_LSR = dwMask;       // Level select register
pPio -> PIOFELLSR = dwMask;     // Falling edge/ Low level Select Register
}
if (mode == HIGH)
{
pPio -> PIO_LSR = dwMask;     // Level select register
pPio -> PIO_REHLSR = dwMask;  // Rising Edge High Level Select Register
}
if (mode == FALLING)
{
pPio -> PIO_ESR = dwMask;     // Edge select register
pPio -> PIO_FELLSR = dwMask;  //Falling Edge Low Level Select Register
}
if (mode == RISING)
{
pPio -> PIO_ESR = dwMask;      //Edge Select Register
pPio -> PIO_REHLSR = dwMask;   //Rising Edge High Level Select Register
}
}

//Enable Interrupt
pPio -> PIO_IER = dwMask;

}

My first try has been to override the function, but when compiling it tells me that the two functions do conflict.  is there anything wrong in the code i wrote?

 i did anything but allowing attachInterrupt to be used declaring Port e bitmask to select the rught pin
« Last Edit: January 07, 2014, 06:36:15 am by aureliusss » Logged

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 126
Posts: 8477
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

You can't just write another function with the same name unless the original is declared as "weak", which I doubt is the case with attachInterrupt().

Why not just use your own function name?

______
Rob
Logged

Rob Gray aka the GRAYnomad www.robgray.com

0
Offline Offline
Shannon Member
****
Karma: 201
Posts: 11744
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You can't override a function, only a method.  Methods belong to a class, a sub-class can
override method implementations, but functions are global and unique.
Logged

[ I won't respond to messages, use the forum please ]

Offline Offline
Full Member
***
Karma: 1
Posts: 160
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

OK, then i added a new function in WInterrupts.h/.c implemented like this:
Code:
void _attachInterrupt(Pio* pPio, uint32_t dwMask, void (*callback)(void), uint32_t mode)
{
static int enabled = 0;
if (!enabled)
{
__initialize();
enabled = 1;
}

uint32_t pos = 0;
uint32_t t;

for (t = dwMask; t > 1; t >>= 1, pos++);

// Set callback function
if (pPio == PIOA) callbacksPioA[pos] = callback;
if (pPio == PIOB) callbacksPioB[pos] = callback;
if (pPio == PIOC) callbacksPioC[pos] = callback;
if (pPio == PIOD) callbacksPioD[pos] = callback;

// Configure the Interrupt mode
if (mode == CHANGE)
{
// Disable additional interupt mode (detects both rising and falling edge)
pPio -> PIO_AIMDR = dwMask;
}
else
{
// Enable aditional interrupt mode
pPio -> PIO_AIMER = dwMask;

if (mode == LOW)
{
pPio -> PIO_LSR = dwMask;       // Level select register
pPio -> PIO_FELLSR = dwMask;     // Falling edge/ Low level Select Register
}
if (mode == HIGH)
{
pPio -> PIO_LSR = dwMask;     // Level select register
pPio -> PIO_REHLSR = dwMask;  // Rising Edge High Level Select Register
}
if (mode == FALLING)
{
pPio -> PIO_ESR = dwMask;     // Edge select register
pPio -> PIO_FELLSR = dwMask;  //Falling Edge Low Level Select Register
}
if (mode == RISING)
{
pPio -> PIO_ESR = dwMask;      //Edge Select Register
pPio -> PIO_REHLSR = dwMask;   //Rising Edge High Level Select Register
}
}

//Enable Interrupt
pPio -> PIO_IER = dwMask;

}

just the same as the orginal attachInterrupt(), the only difference stays in the fact that i can directly pass PIO port and BitMask to use a pin not declared in variant.h (I need to attach an Interrupt to PIOB3, one of the ethernet pins).

Of course this is not working, or at least it make the code to get stucked:
this is the working code:

Code:

volatile boolean off = false;

void setup()
{
  Serial3.begin(115200);
  delay(20);
  init_motor_pins();
 
  pmc_enable_sleepmode(0);
}

void loop()
{

  if (off)
  {
    off = false;
   //Set OUT_CPU pin LOW
    PIOB -> PIO_CODR = OUT_CPU_BM;
  }

  for (uint8_t k = 0; k < 28; k++)
  {
    value[k] = readCapacitivePin(k);
    //    Serial3.println(value[k]);
  }
  //Serial3.println();

  for (uint8_t k = 0; k < 28; k++)
  {
    if ((value[k] > edge[k] + range) & (pressed[k] == 0))
    {
      //Serial3.print("TOCCATO ");
      //Serial3.println(k);
      touched(k);
      pressed[k] = 1;
    }
    if ((value[k] <= edge[k]) & (pressed[k] == 1))
    {
      //Serial3.print("RILASCIATO ");
      //Serial3.println(k);
      pressed[k] = 0;
    }
  }

  pmc_enable_sleepmode(0);

  if (Serial3.available())
  { //change Serial3 to Serial31 if using BT
    char lettera = (char)Serial3.read();
Serial.print(lettera);
}

void _off()
{
delay(5);
off = true;
}

if add my _attachInterrupt() function in the setup everything stop working:

Code:
void setup()
{
  Serial3.begin(115200);
  delay(20);
  init_motor_pins();
 
/////////////////////////////////////
_attachInterrupt(PIOB, IN_CPU_BM, _off, LOW);
////////////////////////////////////

  pmc_enable_sleepmode(0);
}

do you have any idea of what could be happening and why the code it's not working anymore?
Logged

Offline Offline
Full Member
***
Karma: 1
Posts: 160
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

with a couple of printing i saw that it stops right when _attachInterrupt is called. It does not go further! How come?
Logged

Offline Offline
Full Member
***
Karma: 1
Posts: 160
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

replacing my version  _attachInterrupt() with the original attaInterrupt() does not change how the code works. it just stops as soon as i call the function in the setup.
has anyone ever meet this kind of problem?
Logged

0
Offline Offline
Shannon Member
****
Karma: 201
Posts: 11744
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I presume you've understood the relevant parts of the SAM3X8E datasheet and the
existing attachInterrupt code?  Its a significantly more complex chip to interface to
than the ATmega's, you have to be careful and methodical.
Logged

[ I won't respond to messages, use the forum please ]

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 126
Posts: 8477
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm not familiar with the SAM regs, but what's in __initialize();? You should post that as well for those who are. There is real potential for a screw up in there I would think.

And why do all 4 interrupts get the same callback func?

______
Rob
Logged

Rob Gray aka the GRAYnomad www.robgray.com

Offline Offline
Full Member
***
Karma: 1
Posts: 160
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

__initialize() function is explained in WInterrupts.h/.c
Logged

Pages: [1]   Go Up
Jump to: