diff options
Diffstat (limited to 'firmware/libs-device/osccalASM.S')
| -rw-r--r-- | firmware/libs-device/osccalASM.S | 228 | 
1 files changed, 0 insertions, 228 deletions
| 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 | 
