Close

Timeout/Interleave interrupt logic working OK

A project log for NSX-64

MSX adapter for Nintendo 64 controllers

danjovicdanjovic 08/15/2019 at 04:000 Comments

Arduino library ecosystem come in handy but sometimes you better read the datasheet and write your own code.

After I have spent a lot of time struggling with TimerOne library,  trying to figure out why the function to change the period weren't working I gave up and started to write my own code. Didn't need to write it from scratch, as I found most of the code that I needed from a AVR timer calculator .

The code snipped turned into a function:

#define _10ms 2499     // OCR1 values for timeout
#define _100ms 24999

///////////////////////////////////////////////////////////////////
// Timer 1 timeout configuration
//
inline void setTimer1 (uint16_t overflowTicks) {
   cli(); // disable interrupts
   TCCR1A = 0; 
   TCCR1B = 0;
   TCNT1  = 0; // initialize counter value to 0
   OCR1A = overflowTicks; // set compare register 

   TCCR1B |= (1 << WGM12);                     // CTC mode
   TCCR1B |= (0<<CS12)|(1<<CS11)|(1<<CS10); // prescaler = 64
   TIMSK1 |= (1 << OCIE1A);                 // ISR Timer1/Compare
    
   sei(); // enable interrupts
}

And it worked flawlessly:

The first image shows the Timer 1 callback running at 10ms (brown trace) until a paddle read pulse arrived (black trace). Then the paddle service runs (yellow trace) and the return from paddle service (interrupt) causes the cpu to wake and perform a new reading of the n64 controller (red trace). Right after that, the CPU sleeps again but this moment  the interval for the Timer to call the callback have changed to 100ms.

If no other paddle reading Pulse arrives within 100ms the Timer 1 callback service reprograms the interval to 10 ms and the sampling continues at 10ms intervals.

On the other hand if paddle reading Pulses keep arriving within and interval of 100ms the Timer 1 callback starves.

In other words... Success!!


Discussions