blob: 32481520509994342099b831095eb1cd67715235 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
/* Name: osctune.h
* Author: Christian Starkjohann
* Creation Date: 2008-10-18
* Tabsize: 4
* Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
* License: GNU GPL v2 (see License.txt) or proprietary (CommercialLicense.txt)
* This Revision: $Id$
*/
/*
General Description:
This file is declared as C-header file although it is mostly documentation
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.
*/
#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 % */
/* derived constants: */
#define EXPECTED_TIMER0_INCREMENT ((F_CPU / 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
notTooHigh:
cpi YL, -TOLERATED_DEVIATION
brge osctuneDone ; not too low
inc YH ; clock rate was too low
osctuneDone:
out OSCCAL, YH ; store tuned value
endm
#endif
#define USB_SOF_HOOK tuneOsccal
|