V-USB with ATtiny45 / ATtiny85

ATtiny45 and ATtiny85 are smaller than ATtiny2313 and have an internal oscillator that can be calibrated to provide 16.5 MHz clock, accurate enough for V-USB to do its magic. I challenge anyone to drastically shorten these wire runs!

Step 1: Schematic

In the photo, I used a 4-pin header to show the place of the USB cable so the zener diodes would not get obstructed. Note that due to the angle it can seem like the 0.1 uF tantalum cap (light brown one) is wired to PB4 when it really is going to GND pin! Here’s the schematic:

Step 2: Note: 2.2 kohm pullup for D- was missing in the schematic, it has now been corrected.

Main code changes needed are the change of pins to PORTB. Also, the oscillator calibration routine needs a hook added to the config. Here are the changes I made to usbconfig.h:

#define USB_CFG_IOPORTNAME      B

#define USB_CFG_DMINUS_BIT      1
#define USB_CFG_DPLUS_BIT       2
#define USB_CFG_CLOCK_KHZ       (F_CPU/1000)
#define USB_CFG_HAVE_MEASURE_FRAME_LENGTH   1

// The following needs to be uncommented
#define USB_RESET_HOOK(resetStarts)     if(!resetStarts){hadUsbReset();}

// Add the following after USB_RESET_HOOK
#ifndef __ASSEMBLER__
extern void hadUsbReset(void); // define the function for usbdrv.c
#endif

Note that USB_CFG_CLOCK_KHZ now relies on F_CPU constant. Furthermore, F_CPU can be set in the Makefile by passing -DF_CPU=16500000 as a command-line argument to gcc, so defining it can also be omitted frommain.c. Another thing we need to change in the makefile is to set mcu/part code to attiny85 for both avrdude and gcc.

In main.c, we only need to remove definition of F_CPU, change the LED pin from PB0 to PB3, and add the calibration routine. The calibration routine in EasyLogger has a slightly mind-bending binary search which, while short, does not take into account that ATtiny45 and ATtiny85 have OSCCAL which works in two overlapping frequency regions, 0..127 and 128..255. So I made my own which is as short but does search the two spaces separately for the optimum value (on the other hand, my routine does not descend to 0 or 128, which should not be an issue).

#define abs(x) ((x) > 0 ? (x) : (-x))

// Called by V-USB after device reset
void hadUsbReset() {
    int frameLength, targetLength = (unsigned)(1499 * (double)F_CPU / 10.5e6 + 0.5);
    int bestDeviation = 9999;
    uchar trialCal, bestCal, step, region;

    // do a binary search in regions 0-127 and 128-255 to get optimum OSCCAL
    for(region = 0; region <= 1; region++) {
        frameLength = 0;
        trialCal = (region == 0) ? 0 : 128;
        
        for(step = 64; step > 0; step >>= 1) { 
            if(frameLength < targetLength) // true for initial iteration
                trialCal += step; // frequency too low
            else
                trialCal -= step; // frequency too high
                
            OSCCAL = trialCal;
            frameLength = usbMeasureFrameLength();
            
            if(abs(frameLength-targetLength) < bestDeviation) {
                bestCal = trialCal; // new optimum found
                bestDeviation = abs(frameLength -targetLength);
            }
        }
    }

    OSCCAL = bestCal;
}

That’s it. Again, the full main.c and usbconfig.h along with modified makefile, updated schematic and rest of the needed stuff (driver, libusb, usbdrv folders) are available as one zip file released under GPL. Interface to the new device is unchanged, “usbtest on”, “usbtest out” etc. should work from command-line like they did with the ATtiny2313-powered device.

Step 3: Fuse bits

Oh and one last thing – the fuse bits need of course be changed. Remove the 8x clock divider and switch to High Frequency PLL clock (CKSEL=0001) with slowly rising power (SUT=10). For ATtiny45/85 this should result in low fuse byte of 0xE1. You might also consider 2.7 V brown-out detection, making the high byte 0xDD:

avrdude -c usbtiny -p attiny85 -U lfuse:w:0xe1:m -U hfuse:w:0xdd:m



Mar 19,2015
3,350 viewsReport item
  • Comments(2)
  • Likes(2)
You can only upload 1 files in total. Each file cannot exceed 2MB. Supports JPG, JPEG, GIF, PNG, BMP
0 / 10000

    You might like