From dd52d66d034c943380d4a95d7677cff7772109df Mon Sep 17 00:00:00 2001 From: bnewbold Date: Fri, 2 Jul 2010 00:57:35 -0400 Subject: timers progress examples code cleanup, more descriptive comments, more notes --- notes/timers.txt | 73 ++++++++++++++++++++++++++++++++++---------------------- notes/vga.txt | 26 +++++++++++++------- 2 files changed, 62 insertions(+), 37 deletions(-) (limited to 'notes') diff --git a/notes/timers.txt b/notes/timers.txt index 3e6bb9c..3f5b9f4 100644 --- a/notes/timers.txt +++ b/notes/timers.txt @@ -12,54 +12,69 @@ Timer2,Ch 3+4 are D0 and D1, which conflict with Serial2. USART should work fine as long as pins aren't in output mode? and timers should work fine if Serial2 isn't in use? +Caveats +------------------------------------------------------------------------------ +There are probably subtle bugs with the way register settings get read in; eg, +it is often required to have the counter fully overflow before new settings +come into effect? +Getting really good timing is still an art, not a science here... usually you +need to fiddle with an oscilloscope and the exact overflow/compare numbers to +get just the right time values. +Any other interrupts (SysTick, USB, Serial, etc) can blow away all the nice +timing stuff. + Misc Notes ------------------------------------------------------------------------------ -implementation with case/switch in the interrupt handlers doesn't work; a lot +Implementation with case/switch in the interrupt handlers doesn't work; a lot of the time multiple interrupt flags are active at the same time (or become active?) TODO ------------------------------------------------------------------------------ +- document carefully (eg, determine clock-wise and overflow-wise behavior for + each function) +- track down and handle all pin conflicts +- implement the update interrupt as a "5th channel" +- "pulse in" stuff, both c and c++ - function to read out CCR registers - allow comparison output to the pin (a la PWM) - additional modes and configuration (up, down, up/down, etc) -- Wirish (C++) higher level implementation -- implement the update interrupt as a "5th channel" -- track down and handle all pin conflicts -- document Possible Wirish implementation ------------------------------------------------------------------------------ -This recent implementation seems pretty clean: +Inspired by Timer1 Library for arduino http://arduino.cc/pipermail/developers_arduino.cc/2010-June/002845.html - class Timer1Class { - public: - static void (*isrCompareA)(void); - static void (*isrCompareB)(void); - - static const uint8_t PRESCALE1 = 1; - static const uint8_t PRESCALE8 = 2; - static const uint8_t PRESCALE64 = 3; - static const uint8_t PRESCALE256 = 4; - static const uint8_t PRESCALE1024 = 5; + class HardwareTimer { - const static uint8_t NORMAL = 0; - const static uint8_t CTC = 4; + public: - void setPrescaleFactor(uint8_t factor); - void setMode(uint8_t mode); - uint16_t read(); - void write(uint16_t val); - void writeCompareA(uint16_t val); - void writeCompareB(uint16_t val); - void attachCompareAInterrupt(void (*f)(void)); - void attachCompareBInterrupt(void (*f)(void)); - void detachCompareAInterrupt(); - void detachCompareBInterrupt(); + void pause(); + void resume(); + void setPrescaleFactor(uint8 factor); + void setOverflow(uint16 val); // truncates to overflow + void setCount(uint16 val); // truncates to overflow + uint16 getCount(); + uint16 setPeriod(uint32 microseconds); // tries to set prescaler and overflow wisely; returns overflow + void setMode(uint8 mode); + void setCompare1(uint16 val); // truncates to overflow + void setCompare2(uint16 val); // truncates to overflow + void setCompare3(uint16 val); // truncates to overflow + void setCompare4(uint16 val); // truncates to overflow + void attachCompare1Interrupt(void (*f)(void)); + void attachCompare2Interrupt(void (*f)(void)); + void attachCompare3Interrupt(void (*f)(void)); + void attachCompare4Interrupt(void (*f)(void)); + void detachCompare1Interrupt(); + void detachCompare2Interrupt(); + void detachCompare3Interrupt(); + void detachCompare4Interrupt(); }; - extern Timer1Class Timer1; + HardwareTimer Timer1 = HardwareTimer(1); + HardwareTimer Timer2 = HardwareTimer(2); + HardwareTimer Timer3 = HardwareTimer(3); + HardwareTimer Timer4 = HardwareTimer(4); Here's one of the more standard libaries out there: http://www.arduino.cc/playground/Code/Timer1 diff --git a/notes/vga.txt b/notes/vga.txt index 2230f57..d75281a 100644 --- a/notes/vga.txt +++ b/notes/vga.txt @@ -1,32 +1,42 @@ -classic digitalWrite() gives ~500ns pulse time (2MHz) +Notes on GPIO Writing +------------------------------------------------------------------------------ +Classic digitalWrite() gives ~500ns pulse time (2MHz) gpio_write_bit() is about 360ns (2.78MHz) -writing to GPIO?_BASE is about 60ns (16.6MHz -> 18MHz) +Writing to GPIO?_BASE is about 60ns (16.6MHz -> 18MHz) -pwm write 0x0001 is about 30ns (33MHz) +pwm write 0x0001 is about 30ns (33MHz) with prescaler as 1 (default) pwm write 0x0001 is about 14ns (72MHz) with prescaler as 0 (!) -1/25.125MHz = 39.72ns +VGA Timing +------------------------------------------------------------------------------ +1/25.125MHz = 39.72ns (640x480 pixel clock) -crude 640x480 directions: - www.epanorama.net/documents/pc/vga_timing.html +Crude 640x480 directions: + From www.epanorama.net/documents/pc/vga_timing.html 480 lines 31.77 us horizontal line length -> 2287.44 clock cycles -> 2287 3.77 us sync period -> 271 clocks -> 271 1.89 us front porch? -> 136 clocks -> 136 25.17 us video -> 1812.24 clocks -> 1812 - so... + So... 2287 reload 271 1: Hsync high 407 2: Video on 2219 3: Video off 2287 4: Hsync low - vertically, it's + Vertically, it's 480 lines active video 11 lines front porch 2 lines Vsync (low) 31 lines back porch + +Currently, setting vs. clearing GPIO registers seems to take a different amount +of time? Or perhaps i'm not analyzing branching correctly. Regardless, if you +SET 100x times then UNSET on one line, then UNSET 100x then SET the next line, +the two changes in color will generally not line up. + -- cgit v1.2.3