aboutsummaryrefslogtreecommitdiffstats
path: root/libs-device
diff options
context:
space:
mode:
authorChristian Starkjohann <cs+github@obdev.at>2008-04-17 19:00:20 +0000
committerChristian Starkjohann <cs+github@obdev.at>2008-04-17 19:00:20 +0000
commit95ca3f5bd696b5450820929e1b1a444d02f0bd1e (patch)
tree70ac0161a0e4548acaf2f89d2ecb77132579ff7a /libs-device
parent2f465daef9e6c5a6b7bda3074c050cd7e8515770 (diff)
downloadv-usb-95ca3f5bd696b5450820929e1b1a444d02f0bd1e.tar.gz
v-usb-95ca3f5bd696b5450820929e1b1a444d02f0bd1e.tar.bz2
v-usb-95ca3f5bd696b5450820929e1b1a444d02f0bd1e.zip
- imported new files into project
Diffstat (limited to 'libs-device')
-rw-r--r--libs-device/Readme.txt16
-rw-r--r--libs-device/osccal.c64
-rw-r--r--libs-device/osccal.h53
3 files changed, 133 insertions, 0 deletions
diff --git a/libs-device/Readme.txt b/libs-device/Readme.txt
new file mode 100644
index 0000000..7c0e311
--- /dev/null
+++ b/libs-device/Readme.txt
@@ -0,0 +1,16 @@
+This is the Readme file for the libs-device directory. This directory contains
+code snippets which may be useful for USB device firmware.
+
+
+WHAT IS INCLUDED IN THIS DIRECTORY?
+===================================
+
+osccal.c and osccal.h
+ This module contains a function which calibrates the AVR's built-in RC
+ oscillator based on the USB frame clock. See osccal.h for a documentation
+ of the API.
+
+
+----------------------------------------------------------------------------
+(c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH.
+http://www.obdev.at/
diff --git a/libs-device/osccal.c b/libs-device/osccal.c
new file mode 100644
index 0000000..5734a84
--- /dev/null
+++ b/libs-device/osccal.c
@@ -0,0 +1,64 @@
+/* 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) or proprietary (CommercialLicense.txt)
+ * This Revision: $Id$
+ */
+
+#include <avr/io.h>
+
+/* ------------------------------------------------------------------------- */
+/* ------------------------ 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.
+ * This algorithm may also be used to calibrate the RC oscillator directly to
+ * 12 MHz (no PLL involved, can therefore be used on almost ALL AVRs), but this
+ * is wide outside the spec for the OSCCAL value and the required precision for
+ * the 12 MHz clock! Use the RC oscillator calibrated to 12 MHz for
+ * experimental purposes only!
+ */
+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.
+*/
diff --git a/libs-device/osccal.h b/libs-device/osccal.h
new file mode 100644
index 0000000..8bd0209
--- /dev/null
+++ b/libs-device/osccal.h
@@ -0,0 +1,53 @@
+/* Name: osccal.h
+ * 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) or proprietary (CommercialLicense.txt)
+ * This Revision: $Id$
+ */
+
+/*
+General Description:
+This module contains a function which calibrates the AVR's internal RC
+oscillator so that the CPU runs at F_CPU (F_CPU is a macro which must be
+defined when the module is compiled, best passed in the compiler command
+line). The time reference is the USB frame clock of 1 kHz available
+immediately after a USB RESET condition. Timing is done by counting CPU
+cycles, so all interrupts must be disabled while the calibration runs. For
+low level timing measurements, usbMeasureFrameLength() is called. This
+function must be enabled in usbconfig.h by defining
+USB_CFG_HAVE_MEASURE_FRAME_LENGTH to 1.
+
+Algorithm used:
+calibrateOscillator() first does a binary search in the OSCCAL register for
+the best matching oscillator frequency. Then it does a next neighbor search
+to find the value with the lowest clock rate deviation. It is guaranteed to
+find the best match among neighboring values, but for version 5 oscillators
+(which have a discontinuous relationship between OSCCAL and frequency) a
+better match might be available in another OSCCAL region.
+
+Limitations:
+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!
+Precision depends on the OSCCAL vs. frequency dependency of the oscillator.
+Typical precision for an ATMega168 (derived from the OSCCAL vs. F_RC diagram
+in the data sheet) should be in the range of 0.4%. Only the 16.5 MHz version
+of AVR-USB (with built-in receiver PLL) can tolerate this deviation! All other
+frequency modules require at least 0.3% precision.
+*/
+
+#ifndef __OSCCAL_H_INCLUDED__
+#define __OSCCAL_H_INCLUDED__
+
+void calibrateOscillator(void);
+/* This function calibrates the RC oscillator so that the CPU runs at F_CPU.
+ * It MUST be called immediately after the end of a USB RESET condition!
+ * Disable all interrupts during the call!
+ * It is recommended that you store the resulting value in EEPROM so that a
+ * good guess value is available after the next reset.
+ */
+
+
+#endif /* __OSCCAL_H_INCLUDED__ */