From 824c303782a62b57b6525875b3c2dee81056baa4 Mon Sep 17 00:00:00 2001 From: Jenna Fox Date: Sun, 23 Sep 2012 16:09:28 +1000 Subject: Begin work to convert embedded-creations USBaspLoader-tiny85 port to bootloadHID --- firmware/libs-device/osccal.c | 63 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 firmware/libs-device/osccal.c (limited to 'firmware/libs-device/osccal.c') diff --git a/firmware/libs-device/osccal.c b/firmware/libs-device/osccal.c new file mode 100644 index 0000000..939d5c3 --- /dev/null +++ b/firmware/libs-device/osccal.c @@ -0,0 +1,63 @@ +/* Name: osccal.c + * Author: Christian Starkjohann + * Creation Date: 2008-04-10 + * Tabsize: 4 + * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH + * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) + * This Revision: $Id: osccal.c 762 2009-08-12 17:10:30Z cs $ + */ + +#include + +#ifndef uchar +#define uchar unsigned char +#endif + +/* ------------------------------------------------------------------------- */ +/* ------------------------ Oscillator Calibration ------------------------- */ +/* ------------------------------------------------------------------------- */ + +/* Calibrate the RC oscillator. Our timing reference is the Start Of Frame + * signal (a single SE0 bit) repeating every millisecond immediately after + * a USB RESET. We first do a binary search for the OSCCAL value and then + * optimize this value with a neighboorhod search. + */ +void calibrateOscillator(void) +{ +uchar step = 128; +uchar trialValue = 0, optimumValue; +int x, optimumDev, targetValue = (unsigned)(1499 * (double)F_CPU / 10.5e6 + 0.5); + + /* do a binary search: */ + do{ + OSCCAL = trialValue + step; + x = usbMeasureFrameLength(); /* proportional to current real frequency */ + if(x < targetValue) /* frequency still too low */ + trialValue += step; + step >>= 1; + }while(step > 0); + /* We have a precision of +/- 1 for optimum OSCCAL here */ + /* now do a neighborhood search for optimum value */ + optimumValue = trialValue; + optimumDev = x; /* this is certainly far away from optimum */ + for(OSCCAL = trialValue - 1; OSCCAL <= trialValue + 1; OSCCAL++){ + x = usbMeasureFrameLength() - targetValue; + if(x < 0) + x = -x; + if(x < optimumDev){ + optimumDev = x; + optimumValue = OSCCAL; + } + } + OSCCAL = optimumValue; +} +/* +Note: This calibration algorithm may try OSCCAL values of up to 192 even if +the optimum value is far below 192. It may therefore exceed the allowed clock +frequency of the CPU in low voltage designs! +You may replace this search algorithm with any other algorithm you like if +you have additional constraints such as a maximum CPU clock. +For version 5.x RC oscillators (those with a split range of 2x128 steps, e.g. +ATTiny25, ATTiny45, ATTiny85), it may be useful to search for the optimum in +both regions. +*/ -- cgit v1.2.3