# keyboard dependent files
SRC = keymap.c \
onekey.c \
+ vusb_osccal.c \
led.c
CONFIG_H = config.h
# so your program will run at the correct speed. You should also set this
# variable to same clock speed. The _delay_ms() macro uses this, and many
# examples use this variable to calculate timings. Do not add a "UL" here.
-F_CPU = 12000000
+#F_CPU = 12000000
+# Xtal-less internal RC oscillator
+F_CPU = 16500000
# Build Options
#---------------- Programming Options --------------------------
AVRDUDE = avrdude
# Type: avrdude -c ? to get a full listing.
-AVRDUDE_PROGRAMMER = usbasp
+#AVRDUDE_PROGRAMMER = usbasp
+AVRDUDE_PROGRAMMER = avrispmkii
AVRDUDE_PORT =
AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
--- /dev/null
+TMK with Xtal-less V-USB
+========================
+
+TMK onekey works on ATtiny85.
+
+ $ make -f Makefile.vusb
+
+ ...
+
+ Size after:
+ text data bss dec hex filename
+ 5518 14 254 5786 169a onekey_vusb.elf
+
+ -------- end --------
+
+
+https://i.imgur.com/sNa302J.jpg
+
+
+Program with AVRISPmkII
+-----------------------
+D- and D+ lines are need to be disconnected when programed.
+
+ $ avrdude -p attiny85 -c avrispmkii -U flash:w:onekey_vusb.hex
+
+
+Xtal-less internal RC
+---------------------
+http://codeandlife.com/2012/02/22/v-usb-with-attiny45-attiny85-without-a-crystal/
+
+Configure fuses for PLL, internal RC and BOD(Brown out detection).
+
+ $ avrdude -c avrispmkii -p attiny85 -U lfuse:w:0xe1:m -U hfuse:w:0xdd:m
+
+Set 16.5MHz to F_CPU in Makefile
+
+ F_CPU = 16500000
+
+Add settings for calibration in usbconfig.h
+
+ diff --git a/keyboard/onekey/usbconfig.h b/keyboard/onekey/usbconfig.h
+ index e9b4f98..01e5aa6 100644
+ --- a/keyboard/onekey/usbconfig.h
+ +++ b/keyboard/onekey/usbconfig.h
+ @@ -161,7 +161,11 @@ section at the end of this file).
+ * proceed, do a return after doing your things. One possible application
+ * (besides debugging) is to flash a status LED on each packet.
+ */
+ -/* #define USB_RESET_HOOK(resetStarts) if(!resetStarts){hadUsbReset();} */
+ +#define USB_RESET_HOOK(resetStarts) if(!resetStarts){hadUsbReset();}
+ +/* http://codeandlife.com/2012/02/22/v-usb-with-attiny45-attiny85-without-a-crystal/ */
+ +#ifndef __ASSEMBLER__
+ +extern void hadUsbReset(void); // define the function for usbdrv.c
+ +#endif
+ /* This macro is a hook if you need to know when an USB RESET occurs. It has
+ * one parameter which distinguishes between the start of RESET state and its
+ * end.
+ @@ -202,7 +206,7 @@ section at the end of this file).
+ * usbFunctionWrite(). Use the global usbCurrentDataToken and a static variable
+ * for each control- and out-endpoint to check for duplicate packets.
+ */
+ -#define USB_CFG_HAVE_MEASURE_FRAME_LENGTH 0
+ +#define USB_CFG_HAVE_MEASURE_FRAME_LENGTH 1
* proceed, do a return after doing your things. One possible application
* (besides debugging) is to flash a status LED on each packet.
*/
-/* #define USB_RESET_HOOK(resetStarts) if(!resetStarts){hadUsbReset();} */
+#define USB_RESET_HOOK(resetStarts) if(!resetStarts){hadUsbReset();}
+/* http://codeandlife.com/2012/02/22/v-usb-with-attiny45-attiny85-without-a-crystal/ */
+#ifndef __ASSEMBLER__
+extern void hadUsbReset(void); // define the function for usbdrv.c
+#endif
/* This macro is a hook if you need to know when an USB RESET occurs. It has
* one parameter which distinguishes between the start of RESET state and its
* end.
* usbFunctionWrite(). Use the global usbCurrentDataToken and a static variable
* for each control- and out-endpoint to check for duplicate packets.
*/
-#define USB_CFG_HAVE_MEASURE_FRAME_LENGTH 0
+#define USB_CFG_HAVE_MEASURE_FRAME_LENGTH 1
/* define this macro to 1 if you want the function usbMeasureFrameLength()
* compiled in. This function can be used to calibrate the AVR's RC oscillator.
*/
* obdev's free shared VID/PID pair. See the file USB-IDs-for-free.txt for
* details.
*/
-#define USB_CFG_DEVICE_NAME 'P', 'S', '/', '2', ' ', 'k', 'e', 'y', 'b', 'o', 'a', 'r', 'd', ' ', 'c', 'o', 'n', 'v', 'e', 'r', 't', 'e', 'r'
-#define USB_CFG_DEVICE_NAME_LEN 23
+#define USB_CFG_DEVICE_NAME 'O', 'n', 'e', 'k', 'e', 'y'
+#define USB_CFG_DEVICE_NAME_LEN 6
/* Same as above for the device name. If you don't want a device name, undefine
* the macros. See the file USB-IDs-for-free.txt before you assign a name if
* you use a shared VID/PID.
--- /dev/null
+// V-USB with ATtiny45 / ATtiny85 without a crystal
+// http://codeandlife.com/2012/02/22/v-usb-with-attiny45-attiny85-without-a-crystal/
+#include <avr/io.h>
+#include <usbdrv.h>
+
+
+#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;
+ uint8_t 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;
+}