mirror of
				https://github.com/digistump/DigistumpArduino.git
				synced 2025-11-03 13:04:48 -08:00 
			
		
		
		
	Initial import of support files for all Digistump boards - Digispark, Pro, DigiX - including libraries, examples, tools, and other support files for the Arduino IDE
This commit is contained in:
		@@ -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/
 | 
			
		||||
@@ -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.
 | 
			
		||||
*/
 | 
			
		||||
@@ -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
 | 
			
		||||
@@ -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__ */
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								hardware/digistump/avr/libraries/DigiUSB/libs-device/osccal.o
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								hardware/digistump/avr/libraries/DigiUSB/libs-device/osccal.o
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							@@ -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
 | 
			
		||||
		Reference in New Issue
	
	Block a user