switch to setup for Arduino Boards Manager

This commit is contained in:
Erik Tylek Kettenburg
2015-06-23 12:42:35 -07:00
parent bc55c9bb45
commit 6ca6b114d5
3581 changed files with 93 additions and 51 deletions

View File

@@ -0,0 +1,22 @@
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/

View File

@@ -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 <avr/io.h>
#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.
*/

View File

@@ -0,0 +1,106 @@
GAS LISTING C:\Users\Erik\AppData\Local\Temp/ccabieCZ.s page 1
1 .file "osccal.c"
2 __SREG__ = 0x3f
3 __SP_H__ = 0x3e
4 __SP_L__ = 0x3d
5 __CCP__ = 0x34
6 __tmp_reg__ = 0
7 __zero_reg__ = 1
8 .text
9 .global calibrateOscillator
10 .type calibrateOscillator, @function
11 calibrateOscillator:
12 0000 FF92 push r15
13 0002 0F93 push r16
14 0004 1F93 push r17
15 0006 CF93 push r28
16 0008 DF93 push r29
17 /* prologue: function */
18 /* frame size = 0 */
19 000a 80E8 ldi r24,lo8(-128)
20 000c F82E mov r15,r24
21 000e 00E0 ldi r16,lo8(0)
22 0010 C0E0 ldi r28,lo8(0)
23 0012 D0E0 ldi r29,hi8(0)
24 .L4:
25 0014 102F mov r17,r16
26 0016 1F0D add r17,r15
27 0018 11BF out 81-32,r17
28 001a 00D0 rcall usbMeasureFrameLength
29 001c 29E0 ldi r18,hi8(2356)
30 001e 8433 cpi r24,lo8(2356)
31 0020 9207 cpc r25,r18
32 0022 04F0 brlt .L2
33 0024 102F mov r17,r16
34 .L2:
35 0026 F694 lsr r15
36 0028 2196 adiw r28,1
37 002a C830 cpi r28,8
38 002c D105 cpc r29,__zero_reg__
39 002e 01F0 breq .L3
40 0030 012F mov r16,r17
41 0032 00C0 rjmp .L4
42 .L3:
43 0034 1150 subi r17,lo8(-(-1))
44 0036 11BF out 81-32,r17
45 0038 1F5F subi r17,lo8(-(1))
46 003a 012F mov r16,r17
47 003c EC01 movw r28,r24
48 003e 00C0 rjmp .L5
49 .L8:
50 0040 00D0 rcall usbMeasureFrameLength
51 0042 8453 subi r24,lo8(-(-2356))
52 0044 9940 sbci r25,hi8(-(-2356))
53 0046 97FF sbrs r25,7
54 0048 00C0 rjmp .L6
55 004a 9095 com r25
56 004c 8195 neg r24
57 004e 9F4F sbci r25,lo8(-1)
GAS LISTING C:\Users\Erik\AppData\Local\Temp/ccabieCZ.s page 2
58 .L6:
59 0050 8C17 cp r24,r28
60 0052 9D07 cpc r25,r29
61 0054 04F4 brge .L7
62 0056 01B7 in r16,81-32
63 0058 EC01 movw r28,r24
64 .L7:
65 005a 81B7 in r24,81-32
66 005c 8F5F subi r24,lo8(-(1))
67 005e 81BF out 81-32,r24
68 .L5:
69 0060 21B7 in r18,81-32
70 0062 30E0 ldi r19,lo8(0)
71 0064 812F mov r24,r17
72 0066 90E0 ldi r25,lo8(0)
73 0068 0196 adiw r24,1
74 006a 8217 cp r24,r18
75 006c 9307 cpc r25,r19
76 006e 04F4 brge .L8
77 0070 01BF out 81-32,r16
78 /* epilogue start */
79 0072 DF91 pop r29
80 0074 CF91 pop r28
81 0076 1F91 pop r17
82 0078 0F91 pop r16
83 007a FF90 pop r15
84 007c 0895 ret
85 .size calibrateOscillator, .-calibrateOscillator
GAS LISTING C:\Users\Erik\AppData\Local\Temp/ccabieCZ.s page 3
DEFINED SYMBOLS
*ABS*:00000000 osccal.c
C:\Users\Erik\AppData\Local\Temp/ccabieCZ.s:2 *ABS*:0000003f __SREG__
C:\Users\Erik\AppData\Local\Temp/ccabieCZ.s:3 *ABS*:0000003e __SP_H__
C:\Users\Erik\AppData\Local\Temp/ccabieCZ.s:4 *ABS*:0000003d __SP_L__
C:\Users\Erik\AppData\Local\Temp/ccabieCZ.s:5 *ABS*:00000034 __CCP__
C:\Users\Erik\AppData\Local\Temp/ccabieCZ.s:6 *ABS*:00000000 __tmp_reg__
C:\Users\Erik\AppData\Local\Temp/ccabieCZ.s:7 *ABS*:00000001 __zero_reg__
C:\Users\Erik\AppData\Local\Temp/ccabieCZ.s:11 .text:00000000 calibrateOscillator
UNDEFINED SYMBOLS
usbMeasureFrameLength

View File

@@ -0,0 +1,65 @@
/* 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), GNU GPL v3 or proprietary (CommercialLicense.txt)
* This Revision: $Id: osccal.h 762 2009-08-12 17:10:30Z cs $
*/
/*
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. It is recommended to call
calibrateOscillator() from the reset hook in usbconfig.h:
*/
#ifndef __ASSEMBLER__
#include <avr/interrupt.h> // for sei()
extern void calibrateOscillator(void);
#endif
#define USB_RESET_HOOK(resetStarts) if(!resetStarts){cli(); calibrateOscillator(); sei();}
/*
This routine is an alternative to the continuous synchronization described
in osctune.h.
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 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__
//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__ */

View File

@@ -0,0 +1,88 @@
/* 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