aboutsummaryrefslogtreecommitdiffstats
path: root/notes
diff options
context:
space:
mode:
Diffstat (limited to 'notes')
-rw-r--r--notes/timers.txt73
-rw-r--r--notes/vga.txt26
2 files changed, 62 insertions, 37 deletions
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.
+