Arduino NG Code not running on Mini

Hi!

I have some code interfacing with a touchpad PS/2 using interrupts. The Code is running on the NG pretty good but on the Mini it won’t work! Any idea why? Is there a difference the Mini deals with interrupts?

#define LOOP_DELAY 100
#define SEND_BYTES_DELAY 20
//The time from the rising edge of a clock pulse to a Data transition must be at least 5 microseconds.
#define DATA_TO_FALLING_DELAY 5
//The time from a data transition to the falling edge of a clock pulse must be at least 5 microseconds and no greater than 25 microseconds.  
#define RISING_TO_DATA_DELAY 15

#define Z_TRESHOLD 10
#define PAD_IDLECOUNTER_MAX 3

// define data and clock pin (RELATIVE - NOT ABSOLUTE, add 0 (pad1) or 1 (pad2))
// Pad1 CLK  = 2 + 0 = PIN2
// Pad1 DATA = 4 + 0 = PIN4
#define MDATA 10
#define MCLK 3


// define variables that change during interrupt
volatile boolean read_pad0 = false;

// define global variables
boolean parityError[2];
int x[2], y[2], z[2];
boolean bl[2], br[2], f[2];

int idlecounter_pad0 = 0;

byte inByte = 0x00;


// the interrupt routines
void interrupt0() {
  detachInterrupt(0);
  golo(2); //go low to put a hold on the incoming data...
  read_pad0 = true;
}

// get parity errors recognized
int isParityOdd(byte p) {
  p = p ^ (p >> 4); //continuously Xor until the last bit is parity
  p = p ^ (p >> 2);
  p = p ^ (p >> 1);
  return p & 1;
}



// basic ps2-functions
void gohi(int pin)
{
  DDRD &= ~(1<<pin); //set pin as input
}

void golo(int pin)
{
  DDRD |= (1<<pin); //set pin as output
  PORTD &= ~(1<<pin);//golo
}

void isfalling(int pin)
{
  DDRD &= ~(1<<pin); //set pin as input
  while(PIND & (1<<pin))
    ; //when received bit is 1
}

void isrising(int pin)
{
  DDRD &= ~(1<<pin); //set pin as input
  while(!(PIND & (1<<pin)))
    ; //when received bit is 0
}

void onelo(int pad)
{
  DDRD &= ~(1<<MDATA + pad); //set pin as input
  DDRD &= ~(1<<MCLK + pad); //set pin as input
  while(!(PIND & (1<<MDATA + pad)) || !(PIND & (1<<MCLK + pad)) )
    ; //when received bit is 0
}



char mouse_read(int pad)
{
  char response = 0x00;
  int response_array[8];
  int j =0;
  int i = 0;
  int parity = 0;
  int calc_parity = 0;
  for (j=0;j<8;j++) //clear the array initially
    response_array[j] = 0;
  
  isfalling(MCLK + pad); // wait for low clock
  delayMicroseconds(DATA_TO_FALLING_DELAY); 
  
  //the first bit is the start bit, no need to store it
  isrising(MCLK + pad); //when the clock rises again
  delayMicroseconds(RISING_TO_DATA_DELAY);
  
  //here the touchpad begins setting the data bits
RX_Bits:
  isfalling(MCLK + pad); //when the clock falls begin reading--host always reads data when the clock is low
  delayMicroseconds(DATA_TO_FALLING_DELAY); //delay a bit to be sure that we never read on a clock edge
  
  if (i==8){ //receive the parity bit if i==8 (all 8 data bits have been received)
    if (PIND & (1<<MDATA + pad))
      parity = 1;
    else
      parity = 0;
  }//end if i==8
  else{
    if (PIND & (1<<MDATA + pad))
      response_array[i] = 1;
    else
      response_array[i] = 0;
  }//end else
  
  isrising(MCLK + pad); //wait for clock line to rise before moving on--touchpad always changes  data when the clock is high
  delayMicroseconds(RISING_TO_DATA_DELAY);
  
  if (i<8){
    i++;
    goto RX_Bits;
  }//end if
  
  isfalling(MCLK + pad); //now wait for the clock line to fall for the stop flag
  delayMicroseconds(DATA_TO_FALLING_DELAY);
  
  //here is the stop flag
  isrising(MCLK + pad); //wait for clock to rise, and the stop has been received
  delayMicroseconds(RISING_TO_DATA_DELAY);  
  
  //layMicroseconds(35);
  
  //we've received all 8 data bits and the parity bit
  //translate that into a char
  if (response_array[0])
    response |= 0x01;
  if (response_array[1])
    response |= 0x02;
  if (response_array[2])
    response |= 0x04;
  if (response_array[3])
    response |= 0x08;
  if (response_array[4])
    response |= 0x10;
  if (response_array[5])
    response |= 0x20;
  if (response_array[6])
    response |= 0x40;
  if (response_array[7])
    response |= 0x80;
    
  //calculate parity
  calc_parity = !(isParityOdd(response));
  //and check to make sure received parity is the same as calculated parity
  parityError[pad] = calc_parity != parity;
  
  return response;
}//end get_response




void mouse_write(byte data, int pad)
{
  int i;
  int parity = 1;

  gohi(MDATA + pad);
  gohi(MCLK + pad);
  delayMicroseconds(300);
  golo(MCLK + pad);
  delayMicroseconds(300);
  golo(MDATA + pad);
  delayMicroseconds(10);
  /* start bit */
  gohi(MCLK + pad);
  /* wait for mouse to take control of clock); */
  isfalling(MCLK + pad);

  /* clock is low, and we are clear to send data */
  for (i=0; i < 8; i++) {
    if (data & 0x01) {
      gohi(MDATA + pad);
    } 
    else {
      golo(MDATA + pad);
    }
    /* wait for clock cycle */
    isrising(MCLK + pad);

    isfalling(MCLK + pad);

    parity = parity ^ (data & 0x01);
    data = data >> 1;
  }  
  /* parity */
  if (parity) {
    gohi(MDATA + pad);
  } 
  else {
    golo(MDATA + pad);
  }
  isrising(MCLK + pad);

  isfalling(MCLK + pad);

  /* stop bit */
  gohi(MDATA + pad);
  delayMicroseconds(50);
  isfalling(MCLK + pad);

  /* wait for mouse to switch modes */
  onelo(pad);

  /* put a hold on the incoming data. */
  golo(MCLK + pad);
  /* read acknowledge byte */
  mouse_read(pad);
  //  Serial.print("done.\n");
}


...

…2.part of the code

void pad_init(int pad)
{
  byte response;
  
  gohi(MCLK + pad);
  gohi(MDATA + pad);
 
  delayMicroseconds(200); 
  //Serial.print("# Resetting PAD ");
  //Serial.println(pad);
  mouse_write(0xff, pad); /* > reset */
  response = mouse_read(pad);      /* < blank AA*/
  response = mouse_read(pad);      /* < blank 00*/

  delayMicroseconds(200);
  mouse_write(0xff, pad); /* > reset */
  response = mouse_read(pad);      /* < blank AA*/
  response = mouse_read(pad);      /* < blank 00*/

  delayMicroseconds(200);
  mouse_write(0xe9, pad); /* > status */
  response = mouse_read(pad);      /* < blank 00*/
  response = mouse_read(pad);      /* < blank 02*/
  response = mouse_read(pad);      /* < blank 64*/

  delayMicroseconds(200);  
  mouse_write(0xf5, pad); // > disable /  
  
  delayMicroseconds(200);  
  mouse_write(0x26, pad); // > not defined
  response = mouse_read(pad);      /* < blank 88*/
  response = mouse_read(pad);      /* < blank 05*/
  response = mouse_read(pad);      /* < blank VERSIONNUMBER*/
  
  delayMicroseconds(200);
  mouse_write(0xf4, pad); // > enable
  
  Serial.print("# PAD READY ");
  Serial.println(pad);
}

boolean read_absolute_remote_mode(int pad) 
{
  byte c1, c2, c3, c4, c5;
  boolean totalParityError = false;
  
  gohi(MCLK + pad);                               // The clock signal must be continuously in high level...
  delayMicroseconds(70);                          // for at least 50 microseconds before the device can start transmitting the data.
  DDRD &= ~(1<<MCLK + pad);                       // release clock by setting it input... ready to receive data

  /* get a reading from the mouse */
  c1 = (byte)mouse_read(pad);
  totalParityError |= parityError[pad];
  c2 = (byte)mouse_read(pad);
  totalParityError |= parityError[pad];
  c3 = (byte)mouse_read(pad);
  totalParityError |= parityError[pad];
  c4 = (byte)mouse_read(pad);
  totalParityError |= parityError[pad];
  c5 = (byte)mouse_read(pad);
  totalParityError |= parityError[pad];
  
  
  if (!totalParityError && (c5 & 128) < 1) // update coords only if no error
  {
    x[pad] = (c1 & 127) + ((c3 & 120) << 4);
    y[pad] = (c2 & 127) + ((c4 & 120) << 4);
    z[pad] = (c5 & 127);
  
    bl[pad]   = (c3 & 1) > 0;
    br[pad]   = (c3 & 2) > 0; 
   
    if(z[pad]>Z_TRESHOLD) 
      f[pad] = true;
    else
      f[pad] = false;
    }
  
    return totalParityError;
}


void readTouchpad1()
{
  if (read_pad0){
    read_absolute_remote_mode(0);        // read pad0
    read_pad0 = false;                     // reset the ready-to-send variable
    attachInterrupt(0, interrupt0, LOW);   // attach interrupt again (got detached befor..)
  }
  else {
    idlecounter_pad0++;                    // count how many times the pad didnt got read
  }
  
  if(idlecounter_pad0 > PAD_IDLECOUNTER_MAX){
    f[0] = false;                          // more than x times? finger-var has to be 0
    idlecounter_pad0 = 0;                  // reset idlecounter
  }
}

void serialOutput()
{
  Serial.print(x[0], DEC);
  Serial.print("\t");
  Serial.print(y[0], DEC);           
  Serial.print("\t");
  Serial.print(z[0], DEC);
  Serial.print("\n");
}


void setup()
{
  Serial.begin(115200);                   

  pad_init(0);                             // set modes on pad 0
  
  // init interrupt
  attachInterrupt(1, interrupt0, LOW);     // enable interrupt on pin 2
}


void loop()
{
  readTouchpad1();                         // get data if pad is ready to send
  
  delay(10);                               // artificial delay...                         
  
  serialOutput();                          // send all the values to application
}

There shouldn't be. Are you sure you have it wired correctly? Do you have an ATmega8 or ATmega168 on the NG?

Everything is wired correctly. i checked and rewired everything a hundret times. The NG has an Atmega8 chip. Is there a difference between the external interrupt pins on the Mini and the NG?

The external interrupt pins should be more or less the same, but it’s a different chip, so there are likely to be many things that are slightly different between the two that could cause problems. What exactly happens differently?

OK I got it! It has nothing to do with the Mini or the ATmega16/8. Its the pins! I’m using 1 interrupt pin and 1 of the other DPs. The data-pin is working on 4,5,6,7 - NOT on any higher pin! Is there any reason why? Same with Mini and NG.