chipKIT® Development Platform

Inspired by Arduino™

Conflict between timer-based interrupt and library

Created Sat, 10 Sep 2011 23:24:14 +0000 by cornmander


cornmander

Sat, 10 Sep 2011 23:24:14 +0000

Hi all,

I am trying to create a basic nixie clock display and I have an RTC chip (ds3231) hooked up over i2c that I want to poll periodically to get the time. I am using display modules provided by a company called Ogi Lumen, which are just shift registers (74595) with a SPI-like interface. The company has created a basic library for their modules that I am using. However, trying to use the library seems to break my timer interrupt. Here is the relevant code:

void setup() {
  OpenTimer2(T2_ON | T2_PS_1_256 | T2_SOURCE_INT , 0xFFFF);
  ConfigIntTimer2(T2_INT_ON | T2_INT_PRIOR_3);

  Wire.begin();
  Serial.begin(9600);
}

#define DATAPIN 5
#define CLOCKPIN 6
#define LATCHPIN 7

Nixie nixie(DATAPIN,CLOCKPIN,LATCHPIN);
void loop() {
  if(!(disp_on % 3)) {
    refresh_display();
  } 
  else {
    nixie.clear(DIGITS); // <- this line smashes the interrupt
  }
  ++disp_on;
  
  delay(2);
}


#ifdef __cplusplus
extern "C" {
#endif
  void __ISR( _TIMER_2_VECTOR, IPL3AUTO) T2Interrupt( void)
  {
    get_datetime();
    Serial.println("test"); // <- never prints if I call clear()
    // clear interrupt flag and exit
    mT2ClearIntFlag();
  } // T2 Interrupt
#ifdef __cplusplus
}
#endif

Here is the offending code from the library:

void Nixie::clear(int digits)
{
  int i = 0;
  
  // Set the latch pin low
  digitalWrite(_latchPin, 0);

  // Write the digits out from right to left^M
  for(i = 0; i < digits; i++)
  {
    _serializeDigit(10);
  }

  // Set the latch pin high
  digitalWrite(_latchPin, 1);

  // Set the latch pin low
  digitalWrite(_latchPin, 0);
}

void Nixie::_serializeDigit(byte writeDigit)
{
  // local variables
  int i = 0;
  int bitmask = 8; // binary 1000

  // set data pin low
  digitalWrite(_dataPin, 0);

  // send out the bits of the nibble MSB -> LSB
  for (i = 0; i < 4; i++)
  {
    // set clock low
    digitalWrite(_clockPin, 0);

    // write bit to the data pin
    digitalWrite(_dataPin, (bitmask & writeDigit));
    
    // set the clock high
    digitalWrite(_clockPin, 1);
    
    // shift the bitmask
    bitmask = bitmask >> 1;
  }

  // set the data low
  digitalWrite(_dataPin, 0);

  // set the clock low
  digitalWrite(_clockPin, 0);
}

davec

Mon, 12 Sep 2011 21:14:24 +0000

This is a side-effect of the PWM support. If you're using a digital pin that supports PWM it turns off the timer for that pin when you call digitalWrite() and as luck would have it you picked pin 5 which is mapped to timer 2. See wiring_digital.c and pins_arduino_pic32_*.cxx for the source. Easiest fix is to use different digital pins.