onekey: Add settings for Xtal-less V-USB
authortmk <hasu@tmk-kbd.com>
Thu, 14 Sep 2017 14:03:28 +0000 (23:03 +0900)
committertmk <hasu@tmk-kbd.com>
Thu, 14 Sep 2017 14:24:02 +0000 (23:24 +0900)
keyboard/onekey/Makefile.vusb
keyboard/onekey/VUSB.md [new file with mode: 0644]
keyboard/onekey/usbconfig.h
keyboard/onekey/vusb_osccal.c [new file with mode: 0644]

index 1af3ebbdfb44932e9ecad72d0a4783d1a8c62175..0684066687a0481a5489de588ff4dabbfd7b477f 100644 (file)
@@ -10,6 +10,7 @@ TARGET_DIR = .
 # keyboard dependent files
 SRC =  keymap.c \
        onekey.c \
+       vusb_osccal.c \
        led.c
 
 CONFIG_H = config.h
@@ -27,7 +28,9 @@ MCU = attiny85
 #   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
@@ -47,7 +50,8 @@ OPT_DEFS += -DNO_ACTION_MACRO
 #---------------- 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
diff --git a/keyboard/onekey/VUSB.md b/keyboard/onekey/VUSB.md
new file mode 100644 (file)
index 0000000..0cf18c0
--- /dev/null
@@ -0,0 +1,63 @@
+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
index e9b4f9824aaa2adc1cd8cf9f2e6d02ad59025385..01e5aa6d2fcb81c5a1c5d94c7f95079c884eb841 100644 (file)
@@ -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
 /* 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.
  */
@@ -250,8 +254,8 @@ section at the end of this file).
  * 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.
diff --git a/keyboard/onekey/vusb_osccal.c b/keyboard/onekey/vusb_osccal.c
new file mode 100644 (file)
index 0000000..26fde1f
--- /dev/null
@@ -0,0 +1,37 @@
+// 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;
+}
Imprint / Impressum