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 |