Author Topic: timer1 interrupt kills digiUSB  (Read 1722 times)

Klaus

  • Newbie
  • *
  • Posts: 3
timer1 interrupt kills digiUSB
« on: December 11, 2017, 09:38:47 am »
When trying to use the timer1 interrupt *and* digiUSB, digiUSB doesn't work any more (in the loop it prints only one line - see code). Without using a timer1 interrupt, digiUSB alone works. The timer1 interrupt works in both cases. Some time ago i read in some forum about a new version of the digiUSB library compatible with timer1 interrupts, but the link to it was not valid. Unfortunately i can't find it again.

Does anybody know a link to a digiUSB library which does not perturb/is not perturbed by the timer1 interrupt?

This is the code:

#define useTimer1 true  //to verify digiUSB, set useTimer1 false

#include <DigiUSB.h>
#include <avr/io.h>
#include <avr/interrupt.h>

#define adc_p2 1
#define outPin 0
#define ledPin 1  //LED on Model A  or Pro

volatile int y, u, w=500, p=100, a=500, ct=0, dt=1000;

static inline void initTimer1(void)
{
  TCCR1 |= (1 << CTC1);  // clear timer on compare match
  TCCR1 |= (1 << CS13) | (1 << CS12) | (1 << CS11); //clock prescaler 8192
  OCR1C = 255; // compare match value
  TIMSK |= (1 << OCIE1A); // enable compare match interrupt
}

ISR(TIMER1_COMPA_vect)
{
  int ct1 = millis();
  y = analogRead(adc_p2); if(y<1) y=1; if(y>999) y=999;
  u = control(y);
  analogWrite(outPin, u/4); 
  digitalWrite(ledPin, digitalRead(ledPin) ^ 1);  //toggle LED
  ct1 = ct1 - millis();
  ct = ct1;
}

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(outPin, OUTPUT);
  DigiUSB.begin();
  DigiUSB.println();

  if (useTimer1) {
    initTimer1();        // initialize timer registers
    sei();               // enable interrupts
  }
}

void loop() {
  DigiUSB.print(millis()/100);
  DigiUSB.print('\t');
  DigiUSB.println(ct);
  if (dt>0) DigiUSB.delay(dt);
  else DigiUSB.refresh();
}

int control(int y) { 
  int out;
  if (p<=0) out = a;
  else out = int(100.0*float(w-y)/float(p)) + a;
  if(out<0) out=0; if(out>999) out=999;
  return out;
}


Klaus

  • Newbie
  • *
  • Posts: 3
Re: timer1 interrupt kills digiUSB
« Reply #1 on: December 13, 2017, 04:37:25 am »
Same happens with DigiCDC / SerialUSB.
Does anybody know any USB library for digispark which does not perturb/is not perturbed by the timer1 interrupt?

Klaus

  • Newbie
  • *
  • Posts: 3
Re: timer1 interrupt kills digiUSB
« Reply #2 on: December 19, 2017, 08:26:03 am »
It's the millis() function which interferes with timer1. If i omit it and do the printouts within the ISR(TIMER1_COMPA_vect), it works. Moreover, in the loop() i can read other infos using DigiUSB.read() without interfering with the ISR(TIMER1_COMPA_vect).

PeterF

  • Hero Member
  • *****
  • Posts: 877
Re: timer1 interrupt kills digiUSB
« Reply #3 on: December 27, 2017, 07:43:15 pm »
I think your problem is probably stemming from the fact that "millis() relies on interrupts to count, so it will never increment inside an ISR"...

The reference to the timer1 compatible version of digiUSB was probably the once mentioned here, but I'm not sure that will help you as it mentions it hooks into the interrupts, and you then have the underlying problem of millis() needing interrupts in order to count, which naturally don't work when you call it within an interrupt service routine.

KamHiva

  • Newbie
  • *
  • Posts: 22
timer1 interrupt kills digiUSB
« Reply #4 on: August 12, 2019, 10:53:08 am »
APPL_RESET is only called when the samplerate changes.

Interrupt enable is set during software reset, so that could override the timer interrupt enable.

File playback itself should not touch interrupt enables or the timer. Application hook code is called in the decode context with interrupts enabled.