-
Demonstration Videos
08/19/2019 at 03:09 • 0 commentsFirst video is a test program written in BASIC language:
Second video is a brief gameplay of Zanac. Video shoot is terrible as I was playing the game with one hand and hold the camera with another (both videos were did like that)
It is possible to notice some lag from the analog stick and the ship moving in the screen. As the controller is being sampled at 100Hz (10ms) this lag is not caused by software, it is caused by the time I spent to move the stick to the opposite position until it passes a given threshold around the center. It can be reduced either by lowering the threshold value or by deducing the movement direction by the rate of change of the analog stick.
-
First working version!
08/18/2019 at 01:12 • 0 commentsAfter implement the autofire using a DDS technique to make the autofire work (more on that later) I have the first full working version ready. Source is available at Github.
The autofire function modulates the TRIGGER A button at 8 Hz with duty cycle very close to 50%.
When Paddles are being serviced it is possible to observe3 the envelope of the autofire modulator.
Worth to mention that both captures have been done with Z button continously pressed to generate TRIGGER A + AUTOFIRE -
Timeout/Interleave interrupt logic working OK
08/15/2019 at 04:00 • 0 commentsArduino 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!!
-
Progress
08/13/2019 at 23:29 • 0 commentsButton activation logic is OK now! The adapter is already usable to play games!
Todo:
-
Autofire (button Z),-
Timeout logic. -
Running code on actual hardware
08/12/2019 at 01:59 • 0 commentsRunning the code on real hardware I have found some stuff
- Arduino Timer 0 shall be powered off before enter interrupt, otherwise it will wake up processor (and we don't want that)
void loop() { do_N64(); // Sample and Update Outputs digitalWrite(debugPin2,LOW); // debug // put AVR to sleep set_sleep_mode(SLEEP_MODE_IDLE); sleep_enable(); power_timer0_disable(); // Arduino keeps this timer running sleep_mode(); sleep_disable(); digitalWrite(debugPin2,HIGH); // debug }
- Button activation logic still still need some working
- I will probably have to use Timer 2 to modulate autofire
Working now to find why Timer 1 does not change the timeout value to 100 ms after the paddle interrupt service.
- Arduino Timer 0 shall be powered off before enter interrupt, otherwise it will wake up processor (and we don't want that)