<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-gb">
	<link rel="self" type="application/atom+xml" href="https://forums.obdev.at/app.php/feed/topic/9250" />

	<title>Objective Development Forums</title>
	
	<link href="https://forums.obdev.at/index.php" />
	<updated>2014-08-27T02:33:08+02:00</updated>

	<author><name><![CDATA[Objective Development Forums]]></name></author>
	<id>https://forums.obdev.at/app.php/feed/topic/9250</id>

		<entry>
		<author><name><![CDATA[blargg]]></name></author>
		<updated>2014-08-27T02:33:08+02:00</updated>

		<published>2014-08-27T02:33:08+02:00</published>
		<id>https://forums.obdev.at/viewtopic.php?t=9250&amp;p=28034#p28034</id>
		<link href="https://forums.obdev.at/viewtopic.php?t=9250&amp;p=28034#p28034"/>
		<title type="html"><![CDATA[Re: USBASP / ISP Programmer as V-USB]]></title>

		
		<content type="html" xml:base="https://forums.obdev.at/viewtopic.php?t=9250&amp;p=28034#p28034"><![CDATA[
Three problems fixed and your code works for me. First, you mistakenly used PINxx as the bit number almost everywhere:<br /><br /><div class="codebox"><p>Code: </p><pre><code>      if (!(PIND &amp; (1&lt;&lt;PIND0))) { // error<br />      <br />      if (!(PIND &amp; (1&lt;&lt;PD0))) { // correct<br />      <br />      if (!(PIND &amp; (1&lt;&lt;0))) { // what I use<br /></code></pre></div><br /><br />The Pxx constants for port bits aren't very useful IMO. I just use the bit number. True, the Pxx constants shield code from Atmel some day putting bit 0 of a port on a different bit in the register, but that seems too remote to guard against.<br /><br />The next problem is a minor logic error:<br /><br /><div class="codebox"><p>Code: </p><pre><code>   uint8_t keyscan( void )<br />   {      <br />      PORTB |= ( (1&lt;&lt;PB4) );  // PB4 Pull-Up einschalten<br />      &#91;...&#93;<br />      PORTB &amp;= ~(1 &lt;&lt; PB5); //Low<br /><br />      if (!(PIND &amp; (1&lt;&lt;PD1))){<br />         if (!(PINB &amp; (1&lt;&lt;PB4))) {    <br />            return 1;   <br />         }<br />      }      <br /></code></pre></div><br /><br />You check PB4 for low when you've got it pulled up. I thought you meant to check PB5, but that would be pointless since you know PB5 is low. I'm thinking maybe this is a check for multiple keys pressed (ghosting) so you don't rept a phantom key press. In that case, maybe you wanted if(PINB &amp; (1&lt;&lt;PB4)).<br /><br />Finally, put a delay after setting the scan lines, to give them time to reach their new levels. This is especially true if you're checking for phantom keys by using the one pulled up, as that will take a little time to reach high level. 200 microseconds works for me:<br /><br /><div class="codebox"><p>Code: </p><pre><code>   uint8_t keyscan( void )<br />   {      <br />      PORTB |= ( (1&lt;&lt;PB4) );  // PB4 Pull-Up einschalten<br />      &#91;...&#93;<br />      PORTB &amp;= ~(1 &lt;&lt; PB5); //Low<br /><br />      _delay_us( 200 ); // added<br />      <br />      if (!(PIND &amp; (1&lt;&lt;PD1))){<br />         if ((PINB &amp; (1&lt;&lt;PB4))) {    <br />            return 1;   <br />         }<br />      }      <br /></code></pre></div><br /><br />One final change, as the original code doesn't do any debouncing. Only scan the keys when USB is ready for new updates. This puts an 8ms delay after key changes and avoids most bouncing:<br /><br /><div class="codebox"><p>Code: </p><pre><code>   for(;;){   /* main event loop */<br />      wdt_reset();<br />      usbPoll();<br />      if(TIFR &amp; (1&lt;&lt;TOV0)){   /* 22 ms timer */<br />         TIFR = 1&lt;&lt;TOV0;<br />         if(idleRate != 0){<br />            if(idleCounter &gt; 4){<br />               idleCounter -= 5;   /* 22 ms in units of 4 ms */<br />            }else{<br />               idleCounter = idleRate;<br />               keyDidChange = 1;<br />            }<br />         }<br />      }<br />      if(usbInterruptIsReady()){ // only scan if USB is ready<br />           key = keyscan();      <br />         if(lastKey != key){<br />            lastKey = key;<br />            keyDidChange = 1;<br />         }<br />         if(keyDidChange){<br />            keyDidChange = 0;<br />            /* use last key and not current key status in order to avoid lost<br />               changes in key status. */<br />            buildReport(lastKey);<br />            usbSetInterrupt(reportBuffer, sizeof(reportBuffer));<br />         }<br />      }<br />   }<br /></code></pre></div><br /><br />Complete main.c:<br /><br /><div class="codebox"><p>Code: </p><pre><code>/* Name: main.c<br /> * Project: HID-Test<br /> * Author: Christian Starkjohann<br /> * Creation Date: 2006-02-02<br /> * Tabsize: 4<br /> * Copyright: (c) 2006 by OBJECTIVE DEVELOPMENT Software GmbH<br /> * License: GNU GPL v2 (see License.txt) or proprietary (CommercialLicense.txt)<br /> * This Revision: $Id$<br /> */<br /><br />#include &lt;avr/io.h&gt;<br />#include &lt;avr/interrupt.h&gt;<br />#include &lt;avr/pgmspace.h&gt;<br />#include &lt;avr/wdt.h&gt;<br />#include &lt;util/delay.h&gt;<br /><br />#include &quot;usbdrv.h&quot;<br />#include &quot;oddebug.h&quot;<br /><br />/* ----------------------- hardware I/O abstraction ------------------------ */<br /><br />/* pin assignments:<br />PB0   Key 1<br />PB1   Key 2<br />PB2   Key 3<br />PB3   Key 4<br />PB4   Key 5<br />PB5 Key 6<br /><br />PC0   Key 7<br />PC1   Key 8<br />PC2   Key 9<br />PC3   Key 10<br />PC4   Key 11<br />PC5   Key 12<br /><br />PD0   USB-<br />PD1   debug tx<br />PD2   USB+ (int0)<br />PD3   Key 13<br />PD4   Key 14<br />PD5   Key 15<br />PD6   Key 16<br />PD7   Key 17<br />*/<br /><br /><br />uint8_t keyscan( void )<br />{<br />      DDRB &amp;= ~( (1&lt;&lt;PB4) );  // PB4 als Eingaenge<br />      PORTB |= ( (1&lt;&lt;PB4) );  // PB4 Pull-Up einschalten<br />      DDRB |= (1 &lt;&lt; PB5); // Ausgang<br />      PORTB &amp;= ~(1 &lt;&lt; PB5); //Low<br />      <br />      _delay_us( 200 );<br />      <br />      if (!(PIND &amp; (1&lt;&lt;PD1))){<br />         if ((PINB &amp; (1&lt;&lt;PB4))) {            <br />            return 1;   <br />         }<br />      }      <br />      if (!(PIND &amp; (1&lt;&lt;PD0))) {<br />         if ((PINB &amp; (1&lt;&lt;PB4))) {            <br />            return 2;   <br />         }<br />      }      <br />      if (!(PINB &amp; (1&lt;&lt;PB2))) {            <br />         if ((PINB &amp; (1&lt;&lt;PB4))) {            <br />            return 3;   <br />         }   <br />      }      <br />      if (!(PINB &amp; (1&lt;&lt;PB3))) {            <br />         if ((PINB &amp; (1&lt;&lt;PB4))) {            <br />            return 4;   <br />         }         <br />      }<br />      <br />      DDRB &amp;= ~( (1&lt;&lt;PB5) );  // PB5 als Eingaenge<br />      PORTB |= ( (1&lt;&lt;PB5) );  // PB5 Pull-Up einschalten<br />      DDRB |= (1 &lt;&lt; PB4); // Ausgang<br />      PORTB &amp;= ~(1 &lt;&lt; PB4); //Low<br /><br />      _delay_us( 200 );<br />      <br />      if (!(PIND &amp; (1&lt;&lt;PD1))) {<br />         if ((PINB &amp; (1&lt;&lt;PB5))) {            <br />            return 5;   <br />         }<br />      }      <br />      if (!(PIND &amp; (1&lt;&lt;PD0))) {<br />         if ((PINB &amp; (1&lt;&lt;PB5))) {            <br />            return 6;   <br />         }   <br />      }      <br />      if (!(PINB &amp; (1&lt;&lt;PB2))) {      <br />         if ((PINB &amp; (1&lt;&lt;PB5))) {            <br />            return 7;   <br />         }   <br />      }      <br />      if (!(PINB &amp; (1&lt;&lt;PB3))) {<br />         if ((PINB &amp; (1&lt;&lt;PB5))) {            <br />            return 8;   <br />         }         <br />      }<br />      return 0;<br />}<br /><br /><br />static void hardwareInit(void)<br />{<br />   DDRC |= (1 &lt;&lt; PC0); // Ausgang<br />   PORTC &amp;= ~(1 &lt;&lt; PC0);  //PB1 High<br />   DDRC |= (1 &lt;&lt; PC1); // Ausgang<br />   PORTC &amp;= ~(1 &lt;&lt; PC1);  //PB1 High<br />   DDRB &amp;= ~( (1&lt;&lt;PB2) );  // PB2 als Eingaenge<br />   PORTB |= ( (1&lt;&lt;PB2) );  // PB2 Pull-Up einschalten<br />   DDRB &amp;= ~( (1&lt;&lt;PB3) );  // PB3 als Eingaenge<br />   PORTB |= ( (1&lt;&lt;PB3) );  // PB3 Pull-Up einschalten<br />   DDRD &amp;= ~( (1&lt;&lt;PD0) );  // PD0 als Eingaenge<br />   PORTD |= ( (1&lt;&lt;PD0) );  // PD0 Pull-Up einschalten<br />   DDRD &amp;= ~( (1&lt;&lt;PD1) );  // PD1 als Eingaenge<br />   PORTD |= ( (1&lt;&lt;PD1) );  // PD1 Pull-Up einschalten   <br />   <br />   /* configure timer 0 for a rate of 12M/(1024 * 256) = 45.78 Hz (~22ms) */<br />   TCCR0 = 5;      /* timer 0 prescaler: 1024 */<br />}<br /><br />/* ------------------------------------------------------------------------- */<br /><br />#define NUM_KEYS    8<br /><br />/* ------------------------------------------------------------------------- */<br />/* ----------------------------- USB interface ----------------------------- */<br />/* ------------------------------------------------------------------------- */<br /><br />static uchar    reportBuffer&#91;2&#93;;    /* buffer for HID reports */<br />static uchar    idleRate;           /* in 4 ms units */<br /><br />const PROGMEM char usbHidReportDescriptor&#91;35&#93; = {   /* USB report descriptor */<br />    0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)<br />    0x09, 0x06,                    // USAGE (Keyboard)<br />    0xa1, 0x01,                    // COLLECTION (Application)<br />    0x05, 0x07,                    //   USAGE_PAGE (Keyboard)<br />    0x19, 0xe0,                    //   USAGE_MINIMUM (Keyboard LeftControl)<br />    0x29, 0xe7,                    //   USAGE_MAXIMUM (Keyboard Right GUI)<br />    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)<br />    0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)<br />    0x75, 0x01,                    //   REPORT_SIZE (1)<br />    0x95, 0x08,                    //   REPORT_COUNT (8)<br />    0x81, 0x02,                    //   INPUT (Data,Var,Abs)<br />    0x95, 0x01,                    //   REPORT_COUNT (1)<br />    0x75, 0x08,                    //   REPORT_SIZE (8)<br />    0x25, 0x65,                    //   LOGICAL_MAXIMUM (101)<br />    0x19, 0x00,                    //   USAGE_MINIMUM (Reserved (no event indicated))<br />    0x29, 0x65,                    //   USAGE_MAXIMUM (Keyboard Application)<br />    0x81, 0x00,                    //   INPUT (Data,Ary,Abs)<br />    0xc0                           // END_COLLECTION<br />};<br />/* We use a simplifed keyboard report descriptor which does not support the<br /> * boot protocol. We don't allow setting status LEDs and we only allow one<br /> * simultaneous key press (except modifiers). We can therefore use short<br /> * 2 byte input reports.<br /> * The report descriptor has been created with usb.org's &quot;HID Descriptor Tool&quot;<br /> * which can be downloaded from http://www.usb.org/developers/hidpage/.<br /> * Redundant entries (such as LOGICAL_MINIMUM and USAGE_PAGE) have been omitted<br /> * for the second INPUT item.<br /> */<br /><br />/* Keyboard usage values, see usb.org's HID-usage-tables document, chapter<br /> * 10 Keyboard/Keypad Page for more codes.<br /> */<br />#define MOD_CONTROL_LEFT    (1&lt;&lt;0)<br />#define MOD_SHIFT_LEFT      (1&lt;&lt;1)<br />#define MOD_ALT_LEFT        (1&lt;&lt;2)<br />#define MOD_GUI_LEFT        (1&lt;&lt;3)<br />#define MOD_CONTROL_RIGHT   (1&lt;&lt;4)<br />#define MOD_SHIFT_RIGHT     (1&lt;&lt;5)<br />#define MOD_ALT_RIGHT       (1&lt;&lt;6)<br />#define MOD_GUI_RIGHT       (1&lt;&lt;7)<br /><br />#define KEY_A       4<br />#define KEY_B       5<br />#define KEY_C       6<br />#define KEY_D       7<br />#define KEY_E       8<br />#define KEY_F       9<br />#define KEY_G       10<br />#define KEY_H       11<br />#define KEY_I       12<br />#define KEY_J       13<br />#define KEY_K       14<br />#define KEY_L       15<br />#define KEY_M       16<br />#define KEY_N       17<br />#define KEY_O       18<br />#define KEY_P       19<br />#define KEY_Q       20<br />#define KEY_R       21<br />#define KEY_S       22<br />#define KEY_T       23<br />#define KEY_U       24<br />#define KEY_V       25<br />#define KEY_W       26<br />#define KEY_X       27<br />#define KEY_Y       28<br />#define KEY_Z       29<br />#define KEY_1       30<br />#define KEY_2       31<br />#define KEY_3       32<br />#define KEY_4       33<br />#define KEY_5       34<br />#define KEY_6       35<br />#define KEY_7       36<br />#define KEY_8       37<br />#define KEY_9       38<br />#define KEY_0       39<br /><br />#define KEY_F1      58<br />#define KEY_F2      59<br />#define KEY_F3      60<br />#define KEY_F4      61<br />#define KEY_F5      62<br />#define KEY_F6      63<br />#define KEY_F7      64<br />#define KEY_F8      65<br />#define KEY_F9      66<br />#define KEY_F10     67<br />#define KEY_F11     68<br />#define KEY_F12     69<br /><br />static const uchar  keyReport&#91;NUM_KEYS + 1&#93;&#91;2&#93; PROGMEM = {<br />/* none */  {0, 0},                     /* no key pressed */<br />/*  1 */    {MOD_SHIFT_LEFT, KEY_A},<br />/*  2 */    {MOD_SHIFT_LEFT, KEY_B},<br />/*  3 */    {MOD_SHIFT_LEFT, KEY_C},<br />/*  4 */    {MOD_SHIFT_LEFT, KEY_D},<br />/*  5 */    {MOD_SHIFT_LEFT, KEY_E},<br />/*  6 */    {MOD_SHIFT_LEFT, KEY_F},<br />/*  7 */    {MOD_SHIFT_LEFT, KEY_G},<br />/*  8 */    {MOD_SHIFT_LEFT, KEY_H},<br />};<br /><br />static void buildReport(uchar key)<br />{<br />/* This (not so elegant) cast saves us 10 bytes of program memory */<br />    *(int *)reportBuffer = pgm_read_word(keyReport&#91;key&#93;);<br />}<br /><br />uchar   usbFunctionSetup(uchar data&#91;8&#93;)<br />{<br />usbRequest_t    *rq = (void *)data;<br /><br />    usbMsgPtr = reportBuffer;<br />    if((rq-&gt;bmRequestType &amp; USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){    /* class request type */<br />        if(rq-&gt;bRequest == USBRQ_HID_GET_REPORT){  /* wValue: ReportType (highbyte), ReportID (lowbyte) */<br />            /* we only have one report type, so don't look at wValue */<br />            buildReport(keyscan());<br />            return sizeof(reportBuffer);<br />        }else if(rq-&gt;bRequest == USBRQ_HID_GET_IDLE){<br />            usbMsgPtr = &amp;idleRate;<br />            return 1;<br />        }else if(rq-&gt;bRequest == USBRQ_HID_SET_IDLE){<br />            idleRate = rq-&gt;wValue.bytes&#91;1&#93;;<br />        }<br />    }else{<br />        /* no vendor specific requests implemented */<br />    }<br />   return 0;<br />}<br /><br />/* ------------------------------------------------------------------------- */<br /><br />int   main(void)<br />{<br />uchar   key, lastKey = 0, keyDidChange = 0;<br />uchar   idleCounter = 0;<br /><br />   wdt_enable(WDTO_2S);<br />    hardwareInit();<br />   odDebugInit();<br />   usbInit();<br />   sei();<br />    DBG1(0x00, 0, 0);<br />   for(;;){   /* main event loop */<br />      wdt_reset();<br />      usbPoll();<br />      if(TIFR &amp; (1&lt;&lt;TOV0)){   /* 22 ms timer */<br />         TIFR = 1&lt;&lt;TOV0;<br />         if(idleRate != 0){<br />            if(idleCounter &gt; 4){<br />               idleCounter -= 5;   /* 22 ms in units of 4 ms */<br />            }else{<br />               idleCounter = idleRate;<br />               keyDidChange = 1;<br />            }<br />         }<br />      }<br />      if(usbInterruptIsReady()){<br />           key = keyscan();      <br />         if(lastKey != key){<br />            lastKey = key;<br />            keyDidChange = 1;<br />         }<br />         if(keyDidChange){<br />            keyDidChange = 0;<br />            /* use last key and not current key status in order to avoid lost<br />               changes in key status. */<br />            buildReport(lastKey);<br />            usbSetInterrupt(reportBuffer, sizeof(reportBuffer));<br />         }<br />      }<br />   }<br />   return 0;<br />}<br /><br />/* ------------------------------------------------------------------------- */<br /></code></pre></div><p>Statistics: Posted by <a href="https://forums.obdev.at/memberlist.php?mode=viewprofile&amp;u=20076">blargg</a> — Wed Aug 27, 2014 2:33 am</p><hr />
]]></content>
	</entry>
		<entry>
		<author><name><![CDATA[ripper121]]></name></author>
		<updated>2014-08-26T18:50:44+02:00</updated>

		<published>2014-08-26T18:50:44+02:00</published>
		<id>https://forums.obdev.at/viewtopic.php?t=9250&amp;p=28025#p28025</id>
		<link href="https://forums.obdev.at/viewtopic.php?t=9250&amp;p=28025#p28025"/>
		<title type="html"><![CDATA[Re: USBASP / ISP Programmer as V-USB]]></title>

		
		<content type="html" xml:base="https://forums.obdev.at/viewtopic.php?t=9250&amp;p=28025#p28025"><![CDATA[
This is my schematic.<br /><br /><a href="http://i61.tinypic.com/2zishut.jpg" class="postlink"><img src="http://i61.tinypic.com/2zishut.png" class="postimage" alt="Image" /></a><br /><br />This is my source:<br /><a href="https://drive.google.com/file/d/0B8CnI1PuBigbT3c3Zmpzb2M1TzQ/edit?usp=sharing" class="postlink">Download</a><br /><br /><div class="codebox"><p>Code: </p><pre><code>/* Name: main.c<br /> * Project: HID-Test<br /> * Author: Christian Starkjohann<br /> * Creation Date: 2006-02-02<br /> * Tabsize: 4<br /> * Copyright: (c) 2006 by OBJECTIVE DEVELOPMENT Software GmbH<br /> * License: GNU GPL v2 (see License.txt) or proprietary (CommercialLicense.txt)<br /> * This Revision: $Id$<br /> */<br /><br />#include &lt;avr/io.h&gt;<br />#include &lt;avr/interrupt.h&gt;<br />#include &lt;avr/pgmspace.h&gt;<br />#include &lt;avr/wdt.h&gt;<br /><br />#include &quot;usbdrv.h&quot;<br />#include &quot;oddebug.h&quot;<br /><br />/* ----------------------- hardware I/O abstraction ------------------------ */<br /><br />/* pin assignments:<br />PB0   Key 1<br />PB1   Key 2<br />PB2   Key 3<br />PB3   Key 4<br />PB4   Key 5<br />PB5 Key 6<br /><br />PC0   Key 7<br />PC1   Key 8<br />PC2   Key 9<br />PC3   Key 10<br />PC4   Key 11<br />PC5   Key 12<br /><br />PD0   USB-<br />PD1   debug tx<br />PD2   USB+ (int0)<br />PD3   Key 13<br />PD4   Key 14<br />PD5   Key 15<br />PD6   Key 16<br />PD7   Key 17<br />*/<br /><br /><br />uint8_t keyscan( void )<br />{      <br />   <br />      DDRB &amp;= ~( (1&lt;&lt;PB4) );  // PB4 als Eingaenge<br />      PORTB |= ( (1&lt;&lt;PB4) );  // PB4 Pull-Up einschalten<br />      DDRB |= (1 &lt;&lt; PB5); // Ausgang<br />      PORTB &amp;= ~(1 &lt;&lt; PB5); //Low<br />      <br />      if (!(PIND &amp; (1&lt;&lt;PIND1))){<br />         if (!(PINB &amp; (1&lt;&lt;PINB4))) {            <br />            return 1;   <br />         }<br />      }      <br />      if (!(PIND &amp; (1&lt;&lt;PIND0))) {<br />         if (!(PINB &amp; (1&lt;&lt;PINB4))) {            <br />            return 2;   <br />         }<br />      }      <br />      if (!(PINB &amp; (1&lt;&lt;PINB2))) {            <br />         if (!(PINB &amp; (1&lt;&lt;PINB4))) {            <br />            return 3;   <br />         }   <br />      }      <br />      if (!(PINB &amp; (1&lt;&lt;PINB3))) {            <br />         if (!(PINB &amp; (1&lt;&lt;PINB4))) {            <br />            return 4;   <br />         }         <br />      }<br />      <br />      DDRB &amp;= ~( (1&lt;&lt;PB5) );  // PB5 als Eingaenge<br />      PORTB |= ( (1&lt;&lt;PB5) );  // PB5 Pull-Up einschalten<br />      DDRB |= (1 &lt;&lt; PB4); // Ausgang<br />      PORTB &amp;= ~(1 &lt;&lt; PB4); //Low<br /><br />      if (!(PIND &amp; (1&lt;&lt;PIND1))) {<br />         if (!(PINB &amp; (1&lt;&lt;PINB5))) {            <br />            return 5;   <br />         }<br />      }      <br />      if (!(PIND &amp; (1&lt;&lt;PIND0))) {<br />         if (!(PINB &amp; (1&lt;&lt;PINB5))) {            <br />            return 6;   <br />         }   <br />      }      <br />      if (!(PINB &amp; (1&lt;&lt;PINB2))) {      <br />         if (!(PINB &amp; (1&lt;&lt;PINB5))) {            <br />            return 7;   <br />         }   <br />      }      <br />      if (!(PINB &amp; (1&lt;&lt;PINB3))) {<br />         if (!(PINB &amp; (1&lt;&lt;PINB5))) {            <br />            return 8;   <br />         }         <br />      }<br />      return 0;<br />}<br /><br /><br />static void hardwareInit(void)<br />{<br />   DDRC |= (1 &lt;&lt; PC0); // Ausgang<br />   PORTC &amp;= ~(1 &lt;&lt; PC0);  //PB1 High<br />   DDRC |= (1 &lt;&lt; PC1); // Ausgang<br />   PORTC &amp;= ~(1 &lt;&lt; PC1);  //PB1 High<br />   DDRB &amp;= ~( (1&lt;&lt;PB2) );  // PB2 als Eingaenge<br />   PORTB |= ( (1&lt;&lt;PB2) );  // PB2 Pull-Up einschalten<br />   DDRB &amp;= ~( (1&lt;&lt;PB3) );  // PB3 als Eingaenge<br />   PORTB |= ( (1&lt;&lt;PB3) );  // PB3 Pull-Up einschalten<br />   DDRD &amp;= ~( (1&lt;&lt;PD0) );  // PD0 als Eingaenge<br />   PORTD |= ( (1&lt;&lt;PD0) );  // PD0 Pull-Up einschalten<br />   DDRD &amp;= ~( (1&lt;&lt;PD1) );  // PD1 als Eingaenge<br />   PORTD |= ( (1&lt;&lt;PD1) );  // PD1 Pull-Up einschalten   <br />   <br />   /* configure timer 0 for a rate of 12M/(1024 * 256) = 45.78 Hz (~22ms) */<br />   TCCR0 = 5;      /* timer 0 prescaler: 1024 */<br />}<br /><br />/* ------------------------------------------------------------------------- */<br /><br />#define NUM_KEYS    8<br /><br />/* ------------------------------------------------------------------------- */<br />/* ----------------------------- USB interface ----------------------------- */<br />/* ------------------------------------------------------------------------- */<br /><br />static uchar    reportBuffer&#91;2&#93;;    /* buffer for HID reports */<br />static uchar    idleRate;           /* in 4 ms units */<br /><br />const PROGMEM char usbHidReportDescriptor&#91;35&#93; = {   /* USB report descriptor */<br />    0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)<br />    0x09, 0x06,                    // USAGE (Keyboard)<br />    0xa1, 0x01,                    // COLLECTION (Application)<br />    0x05, 0x07,                    //   USAGE_PAGE (Keyboard)<br />    0x19, 0xe0,                    //   USAGE_MINIMUM (Keyboard LeftControl)<br />    0x29, 0xe7,                    //   USAGE_MAXIMUM (Keyboard Right GUI)<br />    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)<br />    0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)<br />    0x75, 0x01,                    //   REPORT_SIZE (1)<br />    0x95, 0x08,                    //   REPORT_COUNT (8)<br />    0x81, 0x02,                    //   INPUT (Data,Var,Abs)<br />    0x95, 0x01,                    //   REPORT_COUNT (1)<br />    0x75, 0x08,                    //   REPORT_SIZE (8)<br />    0x25, 0x65,                    //   LOGICAL_MAXIMUM (101)<br />    0x19, 0x00,                    //   USAGE_MINIMUM (Reserved (no event indicated))<br />    0x29, 0x65,                    //   USAGE_MAXIMUM (Keyboard Application)<br />    0x81, 0x00,                    //   INPUT (Data,Ary,Abs)<br />    0xc0                           // END_COLLECTION<br />};<br />/* We use a simplifed keyboard report descriptor which does not support the<br /> * boot protocol. We don't allow setting status LEDs and we only allow one<br /> * simultaneous key press (except modifiers). We can therefore use short<br /> * 2 byte input reports.<br /> * The report descriptor has been created with usb.org's &quot;HID Descriptor Tool&quot;<br /> * which can be downloaded from http://www.usb.org/developers/hidpage/.<br /> * Redundant entries (such as LOGICAL_MINIMUM and USAGE_PAGE) have been omitted<br /> * for the second INPUT item.<br /> */<br /><br />/* Keyboard usage values, see usb.org's HID-usage-tables document, chapter<br /> * 10 Keyboard/Keypad Page for more codes.<br /> */<br />#define MOD_CONTROL_LEFT    (1&lt;&lt;0)<br />#define MOD_SHIFT_LEFT      (1&lt;&lt;1)<br />#define MOD_ALT_LEFT        (1&lt;&lt;2)<br />#define MOD_GUI_LEFT        (1&lt;&lt;3)<br />#define MOD_CONTROL_RIGHT   (1&lt;&lt;4)<br />#define MOD_SHIFT_RIGHT     (1&lt;&lt;5)<br />#define MOD_ALT_RIGHT       (1&lt;&lt;6)<br />#define MOD_GUI_RIGHT       (1&lt;&lt;7)<br /><br />#define KEY_A       4<br />#define KEY_B       5<br />#define KEY_C       6<br />#define KEY_D       7<br />#define KEY_E       8<br />#define KEY_F       9<br />#define KEY_G       10<br />#define KEY_H       11<br />#define KEY_I       12<br />#define KEY_J       13<br />#define KEY_K       14<br />#define KEY_L       15<br />#define KEY_M       16<br />#define KEY_N       17<br />#define KEY_O       18<br />#define KEY_P       19<br />#define KEY_Q       20<br />#define KEY_R       21<br />#define KEY_S       22<br />#define KEY_T       23<br />#define KEY_U       24<br />#define KEY_V       25<br />#define KEY_W       26<br />#define KEY_X       27<br />#define KEY_Y       28<br />#define KEY_Z       29<br />#define KEY_1       30<br />#define KEY_2       31<br />#define KEY_3       32<br />#define KEY_4       33<br />#define KEY_5       34<br />#define KEY_6       35<br />#define KEY_7       36<br />#define KEY_8       37<br />#define KEY_9       38<br />#define KEY_0       39<br /><br />#define KEY_F1      58<br />#define KEY_F2      59<br />#define KEY_F3      60<br />#define KEY_F4      61<br />#define KEY_F5      62<br />#define KEY_F6      63<br />#define KEY_F7      64<br />#define KEY_F8      65<br />#define KEY_F9      66<br />#define KEY_F10     67<br />#define KEY_F11     68<br />#define KEY_F12     69<br /><br />static const uchar  keyReport&#91;NUM_KEYS + 1&#93;&#91;2&#93; PROGMEM = {<br />/* none */  {0, 0},                     /* no key pressed */<br />/*  1 */    {MOD_SHIFT_LEFT, KEY_A},<br />/*  2 */    {MOD_SHIFT_LEFT, KEY_B},<br />/*  3 */    {MOD_SHIFT_LEFT, KEY_C},<br />/*  4 */    {MOD_SHIFT_LEFT, KEY_D},<br />/*  5 */    {MOD_SHIFT_LEFT, KEY_E},<br />/*  6 */    {MOD_SHIFT_LEFT, KEY_F},<br />/*  7 */    {MOD_SHIFT_LEFT, KEY_G},<br />/*  8 */    {MOD_SHIFT_LEFT, KEY_H},<br />};<br /><br />static void buildReport(uchar key)<br />{<br />/* This (not so elegant) cast saves us 10 bytes of program memory */<br />    *(int *)reportBuffer = pgm_read_word(keyReport&#91;key&#93;);<br />}<br /><br />uchar   usbFunctionSetup(uchar data&#91;8&#93;)<br />{<br />usbRequest_t    *rq = (void *)data;<br /><br />    usbMsgPtr = reportBuffer;<br />    if((rq-&gt;bmRequestType &amp; USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){    /* class request type */<br />        if(rq-&gt;bRequest == USBRQ_HID_GET_REPORT){  /* wValue: ReportType (highbyte), ReportID (lowbyte) */<br />            /* we only have one report type, so don't look at wValue */<br />            buildReport(keyscan());<br />            return sizeof(reportBuffer);<br />        }else if(rq-&gt;bRequest == USBRQ_HID_GET_IDLE){<br />            usbMsgPtr = &amp;idleRate;<br />            return 1;<br />        }else if(rq-&gt;bRequest == USBRQ_HID_SET_IDLE){<br />            idleRate = rq-&gt;wValue.bytes&#91;1&#93;;<br />        }<br />    }else{<br />        /* no vendor specific requests implemented */<br />    }<br />   return 0;<br />}<br /><br />/* ------------------------------------------------------------------------- */<br /><br />int   main(void)<br />{<br />uchar   key, lastKey = 0, keyDidChange = 0;<br />uchar   idleCounter = 0;<br /><br />   wdt_enable(WDTO_2S);<br />    hardwareInit();<br />   odDebugInit();<br />   usbInit();<br />   sei();<br />    DBG1(0x00, 0, 0);<br />   for(;;){   /* main event loop */<br />      wdt_reset();<br />      usbPoll();<br />        key = keyscan();      <br />         if(lastKey != key){<br />            lastKey = key;<br />            keyDidChange = 1;<br />         }<br />         if(TIFR &amp; (1&lt;&lt;TOV0)){   /* 22 ms timer */<br />            TIFR = 1&lt;&lt;TOV0;<br />            if(idleRate != 0){<br />               if(idleCounter &gt; 4){<br />                  idleCounter -= 5;   /* 22 ms in units of 4 ms */<br />               }else{<br />                  idleCounter = idleRate;<br />                  keyDidChange = 1;<br />               }<br />            }<br />         }<br />         if(keyDidChange &amp;&amp; usbInterruptIsReady()){<br />            keyDidChange = 0;<br />            /* use last key and not current key status in order to avoid lost<br />               changes in key status. */<br />            buildReport(lastKey);<br />            usbSetInterrupt(reportBuffer, sizeof(reportBuffer));<br />         }<br />   }<br />   return 0;<br />}<br /><br />/* ------------------------------------------------------------------------- */<br /></code></pre></div><br /><br />But it dont work for me, i cant read out the Key Matrix <img class="smilies" src="./../../../images/smilies/icon_sad.gif" alt=":(" title="Sad" />.<p>Statistics: Posted by <a href="https://forums.obdev.at/memberlist.php?mode=viewprofile&amp;u=20591">ripper121</a> — Tue Aug 26, 2014 6:50 pm</p><hr />
]]></content>
	</entry>
		<entry>
		<author><name><![CDATA[ripper121]]></name></author>
		<updated>2014-08-16T20:56:57+02:00</updated>

		<published>2014-08-16T20:56:57+02:00</published>
		<id>https://forums.obdev.at/viewtopic.php?t=9250&amp;p=27954#p27954</id>
		<link href="https://forums.obdev.at/viewtopic.php?t=9250&amp;p=27954#p27954"/>
		<title type="html"><![CDATA[Re: USBASP / ISP Programmer as V-USB]]></title>

		
		<content type="html" xml:base="https://forums.obdev.at/viewtopic.php?t=9250&amp;p=27954#p27954"><![CDATA[
Ok big thanks. <br />Can't wait to test it.<p>Statistics: Posted by <a href="https://forums.obdev.at/memberlist.php?mode=viewprofile&amp;u=20591">ripper121</a> — Sat Aug 16, 2014 8:56 pm</p><hr />
]]></content>
	</entry>
		<entry>
		<author><name><![CDATA[blargg]]></name></author>
		<updated>2014-08-16T20:49:24+02:00</updated>

		<published>2014-08-16T20:49:24+02:00</published>
		<id>https://forums.obdev.at/viewtopic.php?t=9250&amp;p=27953#p27953</id>
		<link href="https://forums.obdev.at/viewtopic.php?t=9250&amp;p=27953#p27953"/>
		<title type="html"><![CDATA[Re: USBASP / ISP Programmer as V-USB]]></title>

		
		<content type="html" xml:base="https://forums.obdev.at/viewtopic.php?t=9250&amp;p=27953#p27953"><![CDATA[
I use avrdude to flash it. I didn't change any fusebits since naturally USBasp needs the same settings as almost any V-USB program would. It is a 12MHz quartz crystal with atmega8A. That is' not an atmega8L shouldn't matter for this use.<br /><br /><blockquote class="uncited"><div><blockquote class="uncited"><div>Can you help me to Implement a 4 Button HID Keyboard?</div></blockquote><br /><br />But it should work with 8 keys.</div></blockquote><br /><br />Oh, change in requirements to double the number of keys I see. <img class="smilies" src="./../../../images/smilies/icon_smile.gif" alt=":)" title="Smile" />  For double the number, a scanning line would probably be best. I can add that to the code as I'm experimenting with it further today.<br /><br />I'll contact you in e-mail once you get your boards and have something definite to work with. I'm sharing the rest here in the forum so others can benefit too.<p>Statistics: Posted by <a href="https://forums.obdev.at/memberlist.php?mode=viewprofile&amp;u=20076">blargg</a> — Sat Aug 16, 2014 8:49 pm</p><hr />
]]></content>
	</entry>
		<entry>
		<author><name><![CDATA[ripper121]]></name></author>
		<updated>2014-08-16T11:52:25+02:00</updated>

		<published>2014-08-16T11:52:25+02:00</published>
		<id>https://forums.obdev.at/viewtopic.php?t=9250&amp;p=27952#p27952</id>
		<link href="https://forums.obdev.at/viewtopic.php?t=9250&amp;p=27952#p27952"/>
		<title type="html"><![CDATA[Re: USBASP / ISP Programmer as V-USB]]></title>

		
		<content type="html" xml:base="https://forums.obdev.at/viewtopic.php?t=9250&amp;p=27952#p27952"><![CDATA[
With what for software do you upload it?<br />Do you have change any Fusebits or settings to flash it?<br />Can you write me pleas a mail? <br />Is this the 12MHz quarz on the stick and a Atmega8 L?<br /><br />Ripper121[at]googlemail.com<br /><br />I need exactly what you have done. But it should work with 8 keys.<p>Statistics: Posted by <a href="https://forums.obdev.at/memberlist.php?mode=viewprofile&amp;u=20591">ripper121</a> — Sat Aug 16, 2014 11:52 am</p><hr />
]]></content>
	</entry>
		<entry>
		<author><name><![CDATA[blargg]]></name></author>
		<updated>2014-08-16T02:13:23+02:00</updated>

		<published>2014-08-16T02:13:23+02:00</published>
		<id>https://forums.obdev.at/viewtopic.php?t=9250&amp;p=27950#p27950</id>
		<link href="https://forums.obdev.at/viewtopic.php?t=9250&amp;p=27950#p27950"/>
		<title type="html"><![CDATA[Re: USBASP / ISP Programmer as V-USB]]></title>

		
		<content type="html" xml:base="https://forums.obdev.at/viewtopic.php?t=9250&amp;p=27950#p27950"><![CDATA[
I <a href="http://blargg.8bitalley.com/avr/HIDKeys.2012-12-08-usbasp.zip" class="postlink">modified HIDKeys to work with the usbasp</a> and four switches connected to PB2-PB5 and <a href="http://imgur.com/a/YFRri" class="postlink">took pictures of the steps</a>. In the pictures I show how an inexpensive set of &quot;dupont&quot; male-male cables makes it nice to use with a breadboard.<br /><br />My steps: connect one programmer to another, bridge JP2 on the one being programmed (not connected to USB). Connect other to USB. <em class="text-italics">make flash</em> to put HIDKeys on. Disconnect reprogrammed USBasp. Connect switches (one between PB2 and GND, next PB3 and GND, etc.). Verify wiring. Connect to PC. Type ABCD.<br /><br />Oh and once all this is working and you're comfortable with it, you can put the USBaspLoader bootloader on the device and be able to reflash it without having to connect the programmer.<p>Statistics: Posted by <a href="https://forums.obdev.at/memberlist.php?mode=viewprofile&amp;u=20076">blargg</a> — Sat Aug 16, 2014 2:13 am</p><hr />
]]></content>
	</entry>
		<entry>
		<author><name><![CDATA[Anonymous]]></name></author>
		<updated>2014-08-16T00:04:36+02:00</updated>

		<published>2014-08-16T00:04:36+02:00</published>
		<id>https://forums.obdev.at/viewtopic.php?t=9250&amp;p=27949#p27949</id>
		<link href="https://forums.obdev.at/viewtopic.php?t=9250&amp;p=27949#p27949"/>
		<title type="html"><![CDATA[Re: USBASP / ISP Programmer as V-USB]]></title>

		
		<content type="html" xml:base="https://forums.obdev.at/viewtopic.php?t=9250&amp;p=27949#p27949"><![CDATA[
Yes my way of thinking. Cheapest hardware i found was 1,72€.<br />And this version has 5 (6 when i use the reset also) free pins and with 6pins = 6 bit there are 63 Keys possible.<br /><br />If you can test it with a USBASP stick can you send me pleas the code?<br />I can begin to develope and test i hope next week when i recive the parts.<br /><br />my Mail is: Ripper121(at)gmail.com for future contact<p>Statistics: Posted by Guest — Sat Aug 16, 2014 12:04 am</p><hr />
]]></content>
	</entry>
		<entry>
		<author><name><![CDATA[blargg]]></name></author>
		<updated>2014-08-15T22:48:40+02:00</updated>

		<published>2014-08-15T22:48:40+02:00</published>
		<id>https://forums.obdev.at/viewtopic.php?t=9250&amp;p=27948#p27948</id>
		<link href="https://forums.obdev.at/viewtopic.php?t=9250&amp;p=27948#p27948"/>
		<title type="html"><![CDATA[Re: USBASP / ISP Programmer as V-USB]]></title>

		
		<content type="html" xml:base="https://forums.obdev.at/viewtopic.php?t=9250&amp;p=27948#p27948"><![CDATA[
Yes, it can be used for V-USB (and in fact the USBasp firmware itself uses V-USB). You can easily reprogram the second one with the first. It would be great for a four-button keyboard, as it has at least four I/O pins on the end connector: PB2, PB3, PB4, and PB5:<br /><br /><div class="codebox"><p>Code: </p><pre><code>          ------<br />MOSI PB3 | 1  2 | +5V<br />     N/C | 3  4 | PD1 TXD (via 1K resistor)<br />/RES PB2   5  6 | PD0 RXD<br /> SCK PB5 | 7  8 | GND<br />MISO PB4 | 9 10 | GND<br />          ------<br /><br />Male end on programmer<br /></code></pre></div><br /><br />Once you get them I'd be glad to help out, as I love using USBasp sticks as inexpensive V-USB development boards.<p>Statistics: Posted by <a href="https://forums.obdev.at/memberlist.php?mode=viewprofile&amp;u=20076">blargg</a> — Fri Aug 15, 2014 10:48 pm</p><hr />
]]></content>
	</entry>
		<entry>
		<author><name><![CDATA[Anonymous]]></name></author>
		<updated>2014-08-15T12:14:10+02:00</updated>

		<published>2014-08-15T12:14:10+02:00</published>
		<id>https://forums.obdev.at/viewtopic.php?t=9250&amp;p=27943#p27943</id>
		<link href="https://forums.obdev.at/viewtopic.php?t=9250&amp;p=27943#p27943"/>
		<title type="html"><![CDATA[USBASP / ISP Programmer as V-USB]]></title>

		
		<content type="html" xml:base="https://forums.obdev.at/viewtopic.php?t=9250&amp;p=27943#p27943"><![CDATA[
I have ordered 2 USBASP sticks.<br />This is the schematic:<br /><img src="http://www.mikrocontroller.net/attachment/226803/AC-PG-USBASP_03_LRG_1_.jpg" class="postimage" alt="Image" /><br /><br />Can I use this device as V-USB device?<br />Can you help me to Implement a 4 Button HID Keyboard?<br /><br />Ripper121<p>Statistics: Posted by Guest — Fri Aug 15, 2014 12:14 pm</p><hr />
]]></content>
	</entry>
	</feed>
