forked from tmk/tmk_keyboard
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvusb_osccal.c
37 lines (29 loc) · 1.21 KB
/
vusb_osccal.c
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
// V-USB with ATtiny45 / ATtiny85 without a crystal
// http://codeandlife.com/2012/02/22/v-usb-with-attiny45-attiny85-without-a-crystal/
#include <avr/io.h>
#include <usbdrv.h>
#define abs(x) ((x) > 0 ? (x) : (-x))
// Called by V-USB after device reset
void hadUsbReset() {
int frameLength, targetLength = (unsigned)(1499 * (double)F_CPU / 10.5e6 + 0.5);
int bestDeviation = 9999;
uint8_t trialCal, bestCal, step, region;
// do a binary search in regions 0-127 and 128-255 to get optimum OSCCAL
for(region = 0; region <= 1; region++) {
frameLength = 0;
trialCal = (region == 0) ? 0 : 128;
for(step = 64; step > 0; step >>= 1) {
if(frameLength < targetLength) // true for initial iteration
trialCal += step; // frequency too low
else
trialCal -= step; // frequency too high
OSCCAL = trialCal;
frameLength = usbMeasureFrameLength();
if(abs(frameLength-targetLength) < bestDeviation) {
bestCal = trialCal; // new optimum found
bestDeviation = abs(frameLength -targetLength);
}
}
}
OSCCAL = bestCal;
}