obdev/v-usb — pull request #3 by cpldcpu (2013-11-03 19:02:36+00:00)
Title: optimized size and robustness of calibrateOscillator(void)

I spent some time optimizing ```calibrateOscillator(void)```. The new implementation has been debugged on an ATtiny 85 and was confirmed to converge to the same osccal value as the previous implementation. If desired, I can also supply some debug data. I used a SPI connection monitor the new implementation in real time.

One thing that is still lacking is a separate define for ```USB_CFG_HAVE_MEASURE_FRAME_LENGTH``` to chose only the new implementation of ```usbMeasureFrameLength```.

### 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
implemented 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.