aboutsummaryrefslogtreecommitdiffstats
path: root/libs-device
diff options
context:
space:
mode:
authorChristian Starkjohann <cs+github@obdev.at>2008-10-20 16:16:30 +0000
committerChristian Starkjohann <cs+github@obdev.at>2008-10-20 16:16:30 +0000
commitaa85f496bdb1738ba162594f1be21bff901d9ca3 (patch)
tree2e3743a487072e2c6ed9c0e3b268b7ee0644d3e5 /libs-device
parent49af025c988b13e64a6683fe65a31e2f80afe37b (diff)
downloadv-usb-aa85f496bdb1738ba162594f1be21bff901d9ca3.tar.gz
v-usb-aa85f496bdb1738ba162594f1be21bff901d9ca3.tar.bz2
v-usb-aa85f496bdb1738ba162594f1be21bff901d9ca3.zip
- fixed assembler code
Diffstat (limited to 'libs-device')
-rw-r--r--libs-device/osctune.h65
1 files changed, 44 insertions, 21 deletions
diff --git a/libs-device/osctune.h b/libs-device/osctune.h
index 3248152..a48f884 100644
--- a/libs-device/osctune.h
+++ b/libs-device/osctune.h
@@ -14,36 +14,59 @@ how the RC oscillator can be kept in sync to the USB frame rate. The code
shown here must be added to usbconfig.h or this header file is included from
there. This code works only if D- is wired to the interrupt, not D+!!!
-You may want to store a good calibration value in EEPROM. You know that the
-calibration value is good when the first USB message is received. Do not store
-the value on every received message because the EEPROM has a limited endurance.
+This is an alternative to the osccal routine in osccal.c. It has the advantage
+that the synchronization is done continuously and that it has more compact
+code size. The disadvantages are slow synchronization (it may take a while
+until the driver works), that messages immediately after the SOF pulse may be
+lost (and need to be retried by the host) and that the interrupt is on D-
+contrary to most examples.
+
+You may want to store a good calibration value in EEPROM for the next startup.
+You know that the calibration value is good when the first USB message is
+received. Do not store the value on every received message because the EEPROM
+has a limited endurance.
+
+Notes:
+Good values for Timer 0 prescaling depend on how precise the clock must be
+tuned and how far away from the default clock rate the target clock is. For
+precise tuning, choose a low prescaler factor, for a broad range of tuning
+choose a high one. A prescaler factor of 64 is good for the entire OSCCAL
+range and allows a precision of better than +/-1%. A prescaler factor of 8
+allows tuning to slightly more than +/-6% of the default frequency and is
+more precise than one step of OSCCAL. It is therefore not suitable to tune
+an 8 MHz oscillator to 12.5 MHz.
*/
-#define TIMER0_PRESCALING 8 /* must match the configuration for TIMER0 in main */
-#define TOLERATED_DEVIATION_PPT 5 /* max clock deviation before we tune in 1/10 % */
+#define TIMER0_PRESCALING 64 /* must match the configuration for TIMER0 in main */
+#define TOLERATED_DEVIATION_PPT 5 /* max clock deviation before we tune in 1/10 % */
/* derived constants: */
-#define EXPECTED_TIMER0_INCREMENT ((F_CPU / TIMER0_PRESCALING) & 0xff)
+#define EXPECTED_TIMER0_INCREMENT ((F_CPU / (1000 * TIMER0_PRESCALING)) & 0xff)
#define TOLERATED_DEVIATION (TOLERATED_DEVIATION_PPT * F_CPU / (1000000 * TIMER0_PRESCALING))
#ifdef __ASSEMBLER__
macro tuneOsccal
- in YL, TCNT0
- lds YH, lastTimer0Value
- sts lastTimer0Value, YL
- sub YL, YH ; time passed since last frame
- subi YL, EXPECTED_TIMER0_INCREMENT
- in YH, OSCCAL
- cpi YL, (TOLERATED_DEVIATION) + 1
- brlt notTooHigh
- dec YH ; clock rate was too high
- rjmp osctuneDone
+ push YH ;[0]
+ in YL, TCNT0 ;[2]
+ lds YH, lastTimer0Value ;[3]
+ sts lastTimer0Value, YL ;[5]
+ sub YL, YH ;[7] time passed since last frame
+ subi YL, EXPECTED_TIMER0_INCREMENT ;[8]
+ in YH, OSCCAL ;[9]
+ cpi YL, TOLERATED_DEVIATION + 1 ;[10]
+ brmi notTooHigh ;[11]
+ subi YH, 1 ;[12] clock rate was too high
+; brcs tuningOverflow ; optionally check for overflow
+ rjmp osctuneDone ;[13]
notTooHigh:
- cpi YL, -TOLERATED_DEVIATION
- brge osctuneDone ; not too low
- inc YH ; clock rate was too low
+ cpi YL, -TOLERATED_DEVIATION ;[13]
+ brpl osctuneDone ;[14] not too low
+ inc YH ;[15] clock rate was too low
+; breq tuningOverflow ; optionally check for overflow
osctuneDone:
- out OSCCAL, YH ; store tuned value
- endm
+ out OSCCAL, YH ;[15-16] store tuned value
+tuningOverflow:
+ pop YH ;[17]
+ endm ;[19] max number of cycles
#endif
#define USB_SOF_HOOK tuneOsccal