summaryrefslogtreecommitdiffstats
path: root/firmware/libs-device
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/libs-device')
-rw-r--r--firmware/libs-device/Readme.txt22
-rw-r--r--firmware/libs-device/osccal.c183
-rw-r--r--firmware/libs-device/osccal.h57
-rw-r--r--firmware/libs-device/osccalASM.S228
-rw-r--r--firmware/libs-device/osctune.h88
5 files changed, 0 insertions, 578 deletions
diff --git a/firmware/libs-device/Readme.txt b/firmware/libs-device/Readme.txt
deleted file mode 100644
index 76518dc..0000000
--- a/firmware/libs-device/Readme.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-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.
-
-osctune.h
- This header file contains a code snippet for usbconfig.h. With this code,
- you can keep the AVR's internal RC oscillator in sync with the USB frame
- clock. This is a continuous synchronization, not a single calibration at
- USB reset as with osccal.c above. Please note that this code works only
- if D- is wired to the interrupt, not D+.
-
-----------------------------------------------------------------------------
-(c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH.
-http://www.obdev.at/
diff --git a/firmware/libs-device/osccal.c b/firmware/libs-device/osccal.c
deleted file mode 100644
index 8debe49..0000000
--- a/firmware/libs-device/osccal.c
+++ /dev/null
@@ -1,183 +0,0 @@
-/* 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 <avr/io.h>
-#include <avr/interrupt.h>
-#ifndef uchar
-#define uchar unsigned char
-#endif
-
-int usbMeasureFrameLengthDecreasing(int);
-
-/* ------------------------------------------------------------------------- */
-/* ------------------------ 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.
- *
- *
- * Optimized version by cpldcpu@gmail.com, Nov 3rd 2013.
- *
- * Benefits:
- * - Codesize reduced by 54 bytes.
- * - Improved robustness due to removing timeout from frame length measurement and
- * inserted NOP after OSCCAL writes.
- *
- * Changes:
- * - The new routine performs a combined binary and neighborhood search
- * in a single loop.
- * Note that the neighborhood search is necessary due to the quasi-monotonic
- * nature of OSCCAL. (See Atmel application note AVR054).
- * - Inserted NOP after writes to OSCCAL to avoid CPU errors during oscillator
- * stabilization.
- * - Implemented new routine to measure frame time "usbMeasureFrameLengthDecreasing".
- * This routine takes the target time as a parameter and returns the deviation.
- * - usbMeasureFrameLengthDecreasing measures in multiples of 5 cycles and is thus
- * slighly more accurate.
- * - usbMeasureFrameLengthDecreasing does not support time out anymore. The original
- * implementation returned zero in case of time out, which would have caused the old
- * calibrateOscillator() implementation to increase OSSCAL to 255, effictively
- * overclocking and most likely crashing the CPU. The new implementation will enter
- * an infinite loop when no USB activity is encountered. The user program should
- * use the watchdog to escape from situations like this.
- *
- * This routine will work both on controllers with and without split OSCCAL range.
- * The first trial value is 128 which is the lowest value of the upper OSCCAL range
- * on Attiny85 and will effectively limit the search to the upper range, unless the
- * RC oscillator frequency is unusually high. Under normal operation, the highest
- * tested frequency setting is 192. This corresponds to ~20 Mhz core frequency and
- * is still within spec for a 5V device.
- */
-
-void calibrateOscillator(void)
-{
- uchar step, trialValue, optimumValue;
- int x, targetValue;
- uchar optimumDev;
- uchar i,xl;
-
- targetValue = (unsigned)((double)F_CPU * 999e-6 / 5.0 + 0.5); /* Time is measured in multiples of 5 cycles. Target is 0.999µs */
- optimumDev = 0xff;
- // optimumValue = OSCCAL;
- step=64;
- trialValue = 128;
-
- cli(); // disable interrupts
-
- /*
- Performs seven iterations of a binary search (stepwidth decreasing9
- with three additional steps of a neighborhood search (step=1, trialvalue will oscillate around target value to find optimum)
- */
-
- for(i=0; i<10; i++){
- OSCCAL = trialValue;
- asm volatile(" NOP");
-
- x = usbMeasureFrameLengthDecreasing(targetValue);
-
- if(x < 0) /* frequency too high */
- {
- trialValue -= step;
- xl=(uchar)-x;
- }
- else /* frequency too low */
- {
- trialValue += step;
- xl=(uchar)x;
- }
-
- /*
- Halve stepwidth to perform binary search. Logical oring with 1 to ensure step is never equal to zero.
- This results in a neighborhood search with stepwidth 1 after binary search is finished.
- Once the neighbourhood search stage is reached, x will be smaller than +-255, hence more code can be
- saved by only working with the lower 8 bits.
- */
-
- step >>= 1;
-
- if (step==0)
- {
- step=1;
- if(xl <= optimumDev){
- optimumDev = xl;
- optimumValue = OSCCAL;
- }
- }
-
- }
-
- OSCCAL = optimumValue;
- asm volatile(" NOP");
-
- sei(); // enable interrupts
-}
-
-void calibrateOscillator_old(void)
-{
- uchar step, trialValue, optimumValue;
- int x, optimumDev, targetValue;
- uchar i;
-
- targetValue = (unsigned)((double)F_CPU * 999e-6 / 5.0 + 0.5); /* Time is measured in multiples of 5 cycles. Target is 0.999µs */
- optimumDev = 0x7f00; // set to high positive value
- optimumValue = OSCCAL;
- step=64;
- trialValue = 128;
-
- /*
- Performs seven iterations of a binary search (stepwidth decreasing9
- with three additional steps of a neighborhood search (step=1, trialvalue will oscillate around target value to find optimum)
- */
-
- for(i=0; i<10; i++){
- OSCCAL = trialValue;
- asm volatile(" NOP");
-
- x = usbMeasureFrameLengthDecreasing(targetValue);
-
- if(x < 0) /* frequency too high */
- {
- trialValue -= step;
- x = -x;
- }
- else /* frequency too low */
- {
- trialValue += step;
- }
-
- /*
- Halve stepwidth to perform binary search. Logical oring with 1 to ensure step is never equal to zero.
- This results in a neighborhood search with stepwidth 1 after binary search is finished.
- */
-
- step >>= 1;
- step |=1;
-
- if(x < optimumDev){
- optimumDev = x;
- optimumValue = OSCCAL;
- }
- }
-
- OSCCAL = optimumValue;
- asm volatile(" NOP");
-}
-
-/*
-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/firmware/libs-device/osccal.h b/firmware/libs-device/osccal.h
deleted file mode 100644
index af37a43..0000000
--- a/firmware/libs-device/osccal.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* Name: osccal.h
- * Author: Christian Starkjohann
- * Creation Date: 2008-04-10
- * Changes 2013-11-04 cpldcpu@gmail.com
- * Tabsize: 4
- * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
- * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
- */
-
-/*
-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.
-The size optimized assembler implementation includes its own implementation
-of usbMeasureFrameLength. Therefore USB_CFG_HAVE_MEASURE_FRAME_LENGTH should
-be set to 0 to avoid including unused code sections. It is recommended to call
-calibrateOscillatorASM() from the reset hook in usbconfig.h by including osccal.h:
-
-#include "osccal.h"
-
-This routine is an alternative to the continuous synchronization described
-in osctune.h.
-
-Algorithm used: See osccalASM.x
-
-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 12.8 MHz and
-16.5 MHz versions of V-USB (with built-in receiver PLL) can tolerate this
-deviation! All other frequency modules require at least 0.2% precision.
-*/
-
-#ifndef __OSCCAL_H_INCLUDED__
-#define __OSCCAL_H_INCLUDED__
-
-#ifndef __ASSEMBLER__
- void calibrateOscillatorASM(void);
-# define USB_RESET_HOOK(resetStarts) if(!resetStarts){ calibrateOscillatorASM();}
-# define USB_CFG_HAVE_MEASURE_FRAME_LENGTH 0
-#endif
-/* 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__ */
diff --git a/firmware/libs-device/osccalASM.S b/firmware/libs-device/osccalASM.S
deleted file mode 100644
index 9a317f1..0000000
--- a/firmware/libs-device/osccalASM.S
+++ /dev/null
@@ -1,228 +0,0 @@
-/* Name: osccalASM.S
- * Author: cpldcpu@gmail.com
- * Creation Date: 2013-11-3
- * Tabsize: 4
- * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
- */
-
-/* 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.
- *
- *
- * Benefits:
- * - Codesize reduced by 90 bytes.
- * - Improved robustness due to removing timeout from frame length measurement and
- * inserted NOP after OSCCAL writes.
- *
- * Changes:
- * - The new routine performs a combined binary and neighborhood search
- * in a single loop.
- * Note that the neighborhood search is necessary due to the quasi-monotonic
- * nature of OSCCAL. (See Atmel application note AVR054).
- * - Inserted NOP after writes to OSCCAL to avoid CPU errors during oscillator
- * stabilization.
- * - Implemented new routine to measure frame time "usbMeasureFrameLengthDecreasing".
- * This routine takes the target time as a parameter and returns the deviation.
- * - usbMeasureFrameLengthDecreasing measures in multiples of 5 cycles and is thus
- * slighly more accurate.
- * - usbMeasureFrameLengthDecreasing does not support time out anymore. The original
- * implementation returned zero in case of time out, which would have caused the old
- * calibrateOscillator() implementation to increase OSSCAL to 255, effictively
- * overclocking and most likely crashing the CPU. The new implementation will enter
- * an infinite loop when no USB activity is encountered. The user program should
- * use the watchdog to escape from situations like this.
- *
- * This routine will work both on controllers with and without split OSCCAL range.
- * The first trial value is 128 which is the lowest value of the upper OSCCAL range
- * on Attiny85 and will effectively limit the search to the upper range, unless the
- * RC oscillator frequency is unusually high. Under normal operation, the highest
- * tested frequency setting is 192. This corresponds to ~20 Mhz core frequency and
- * is still within spec for a 5V device.
- */
-
-
-#define __SFR_OFFSET 0 /* used by avr-libc's register definitions */
-#include "./usbdrv/usbdrv.h" /* for common defs */
-
-#ifdef __IAR_SYSTEMS_ASM__
-/* Register assignments for usbMeasureFrameLengthDecreasing on IAR cc */
-/* Calling conventions on IAR:
- * First parameter passed in r16/r17, second in r18/r19 and so on.
- * Callee must preserve r4-r15, r24-r29 (r28/r29 is frame pointer)
- * Result is passed in r16/r17
- * In case of the "tiny" memory model, pointers are only 8 bit with no
- * padding. We therefore pass argument 1 as "16 bit unsigned".
- */
-
-//Untested
-
-# define i r20
-# define opV r19
-# define opD r18
-# define try r21
-# define stp r22
-
-# define cnt16L r30
-# define cnt16H r31
-
-
-#else /* __IAR_SYSTEMS_ASM__ */
-/* Register assignments for usbMeasureFrameLength on gcc */
-/* Calling conventions on gcc:
- * First parameter passed in r24/r25, second in r22/23 and so on.
- * Callee must preserve r1-r17, r28/r29
- * Result is passed in r24/r25
- */
-
-# define i r20
-# define opV r19
-# define opD r18
-# define try r27
-# define stp r26
-# define cnt16L r24
-# define cnt16H r25
-#endif
-# define cnt16 cnt16L
-
-; extern void calibrateOscillatorASM(void);
-
-.global calibrateOscillatorASM
-calibrateOscillatorASM:
-
- cli
- ldi opD, 255
-
- ldi try, 128 ; calibration start value
- ldi stp, 64 ; initial step width
- ldi i, 10 ; 10 iterations
-
-usbCOloop:
-
- out OSCCAL, try
- nop
-
- ; Delay values = F_CPU * 999e-6 / 5 + 0.5
-
-#if (F_CPU == 16500000)
- ldi cnt16L, lo8(3297)
- ldi cnt16H, hi8(3297)
-#elif (F_CPU == 12800000)
- ldi cnt16L, lo8(2557)
- ldi cnt16H, hi8(2557)
-#else
- #error "calibrateOscillatorASM: no delayvalues defined for this F_CPU setting"
-#endif
-
-usbCOWaitStrobe: ; first wait for D- == 0 (idle strobe)
- sbic USBIN, USBMINUS ;
- rjmp usbCOWaitStrobe ;
-usbCOWaitIdle: ; then wait until idle again
- sbis USBIN, USBMINUS ;1 wait for D- == 1
- rjmp usbCOWaitIdle ;2
-usbCOWaitLoop:
- sbiw cnt16,1 ;[0] [5]
- sbic USBIN, USBMINUS ;[2]
- rjmp usbCOWaitLoop ;[3]
-
- sbrs cnt16H, 7 ;delay overflow?
- rjmp usbCOclocktoolow
- sub try, stp
- neg cnt16L
- rjmp usbCOclocktoohigh
-usbCOclocktoolow:
- add try, stp
-usbCOclocktoohigh:
- lsr stp
- brne usbCOnoneighborhoodsearch
- cp opD, cnt16L
- brcs usbCOnoimprovement
- in opV, OSCCAL
- mov opD, cnt16L
-usbCOnoimprovement:
- ldi stp, 1
-usbCOnoneighborhoodsearch:
- subi i, 1
- brne usbCOloop
-
- out OSCCAL, opV
- nop
- sei
- ret
-
-#undef i
-#undef opV
-#undef opD
-#undef try
-#undef stp
-#undef cnt16
-#undef cnt16L
-#undef cnt16H
-
-/* ------------------------------------------------------------------------- */
-/* ------ Original C Implementation of improved calibrateOscillator -------- */
-/* ---------------------- for Reference only ----------------------------- */
-/* ------------------------------------------------------------------------- */
-
-#if 0
-void calibrateOscillator(void)
-{
- uchar step, trialValue, optimumValue;
- int x, targetValue;
- uchar optimumDev;
- uchar i,xl;
-
- targetValue = (unsigned)((double)F_CPU * 999e-6 / 5.0 + 0.5); /* Time is measured in multiples of 5 cycles. Target is 0.999µs */
- optimumDev = 0xff;
- // optimumValue = OSCCAL;
- step=64;
- trialValue = 128;
-
- cli(); // disable interrupts
-
- /*
- Performs seven iterations of a binary search (stepwidth decreasing9
- with three additional steps of a neighborhood search (step=1, trialvalue will oscillate around target value to find optimum)
- */
-
- for(i=0; i<10; i++){
- OSCCAL = trialValue;
- asm volatile(" NOP");
-
- x = usbMeasureFrameLengthDecreasing(targetValue);
-
- if(x < 0) /* frequency too high */
- {
- trialValue -= step;
- xl=(uchar)-x;
- }
- else /* frequency too low */
- {
- trialValue += step;
- xl=(uchar)x;
- }
-
- /*
- Halve stepwidth to perform binary search. At step=1 the mode changes to neighbourhood search.
- Once the neighbourhood search stage is reached, x will be smaller than +-255, hence more code can be
- saved by only working with the lower 8 bits.
- */
-
- step >>= 1;
-
- if (step==0) // Enter neighborhood search mode
- {
- step=1;
- if(xl <= optimumDev){
- optimumDev = xl;
- optimumValue = OSCCAL;
- }
- }
- }
-
- OSCCAL = optimumValue;
- asm volatile(" NOP");
-
- sei(); // enable interrupts
-}
-#endif \ No newline at end of file
diff --git a/firmware/libs-device/osctune.h b/firmware/libs-device/osctune.h
deleted file mode 100644
index c751648..0000000
--- a/firmware/libs-device/osctune.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/* 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), GNU GPL v3 or proprietary (CommercialLicense.txt)
- * This Revision: $Id: osctune.h 692 2008-11-07 15:07:40Z cs $
- */
-
-/*
-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+!!!
-
-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:
-(*) You must declare the global character variable "lastTimer0Value" in your
-main code.
-
-(*) Timer 0 must be free running (not written by your code) and the prescaling
-must be consistent with the TIMER0_PRESCALING define.
-
-(*) 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.
-
-Thanks to Henrik Haftmann for the idea to this routine!
-*/
-
-#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 / (1000 * TIMER0_PRESCALING)) & 0xff)
-#define TOLERATED_DEVIATION (TOLERATED_DEVIATION_PPT * F_CPU / (1000000 * TIMER0_PRESCALING))
-
-#ifdef __ASSEMBLER__
-macro tuneOsccal
- 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]
-#if OSCCAL > 0x3f /* outside I/O addressable range */
- lds YH, OSCCAL ;[6]
-#else
- in YH, OSCCAL ;[6] assembler modle uses __SFR_OFFSET == 0
-#endif
- 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 ;[13]
- brpl osctuneDone ;[14] not too low
- inc YH ;[15] clock rate was too low
-; breq tuningOverflow ; optionally check for overflow
-osctuneDone:
-#if OSCCAL > 0x3f /* outside I/O addressable range */
- sts OSCCAL, YH ;[12-13] store tuned value
-#else
- out OSCCAL, YH ;[12-13] store tuned value
-#endif
-tuningOverflow:
- pop YH ;[17]
- endm ;[19] max number of cycles
-#endif
-
-#define USB_SOF_HOOK tuneOsccal