<?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/10991" />

	<title>Objective Development Forums</title>
	
	<link href="https://forums.obdev.at/index.php" />
	<updated>2017-08-22T14:49:51+02:00</updated>

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

		<entry>
		<author><name><![CDATA[ripper121]]></name></author>
		<updated>2017-08-22T14:49:51+02:00</updated>

		<published>2017-08-22T14:49:51+02:00</published>
		<id>https://forums.obdev.at/viewtopic.php?t=10991&amp;p=32897#p32897</id>
		<link href="https://forums.obdev.at/viewtopic.php?t=10991&amp;p=32897#p32897"/>
		<title type="html"><![CDATA[Re: Volume Control not working]]></title>

		
		<content type="html" xml:base="https://forums.obdev.at/viewtopic.php?t=10991&amp;p=32897#p32897"><![CDATA[
Found a solution:<br />I used the Tinker code from adafruit:<br /><br />Here my new working FW:<br /><!-- m --><a class="postlink" href="https://github.com/ripper121/Keyboard/tree/master/Firmware">https://github.com/ripper121/Keyboard/t ... r/Firmware</a><!-- m --><p>Statistics: Posted by <a href="https://forums.obdev.at/memberlist.php?mode=viewprofile&amp;u=20591">ripper121</a> — Tue Aug 22, 2017 2:49 pm</p><hr />
]]></content>
	</entry>
		<entry>
		<author><name><![CDATA[ripper121]]></name></author>
		<updated>2017-08-22T10:00:26+02:00</updated>

		<published>2017-08-22T10:00:26+02:00</published>
		<id>https://forums.obdev.at/viewtopic.php?t=10991&amp;p=32896#p32896</id>
		<link href="https://forums.obdev.at/viewtopic.php?t=10991&amp;p=32896#p32896"/>
		<title type="html"><![CDATA[Volume Control not working]]></title>

		
		<content type="html" xml:base="https://forums.obdev.at/viewtopic.php?t=10991&amp;p=32896#p32896"><![CDATA[
Hello <img class="smilies" src="./../../../images/smilies/icon_smile.gif" alt=":)" title="Smile" />,<br /><br />i dont get the Volume controle running <img class="smilies" src="./../../../images/smilies/icon_sad.gif" alt=":(" title="Sad" />.<br /><br />This is my usb Hid Report Descriptor:<br /><div class="codebox"><p>Code: </p><pre><code>#define USB_CFG_INTERFACE_CLASS     0x03    /* HID class */<br />#define USB_CFG_INTERFACE_SUBCLASS  0x01    /* Boot-device subclass */<br />#define USB_CFG_INTERFACE_PROTOCOL  0x01    /* Keyboard protocol */<br /><br />#define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH    35<br /><br />const PROGMEM char usbHidReportDescriptor&#91;USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH&#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 /><br />#define KEY_VOLUME_UP         0x80     // Keyboard Volume Up 0xE9<br />#define KEY_VOLUME_DOWN       0x81     // Keyboard Volume Down 0xEA<br /></code></pre></div><br /><br /><br />This is the complete code:<br /><br /><div class="codebox"><p>Code: </p><pre><code>#define F_CPU 12000000UL<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 &quot;usbdrv/usbdrv.h&quot;<br /><br />/* ----------------------- hardware I/O abstraction ------------------------ */<br /><br />/* pin assignments:<br />LED1 = PC1<br />LED2 = PC0<br /><br />COL1 = PC2<br />COL2 = PC3<br />COL3 = PC4<br />COL4 = PC5<br /><br />ROW1 = PD0<br />ROW2 = PD1<br /><br />PB1   USB-<br />PB0   USB+ (int0)<br />*/<br /><br />static void resetMatrix(void)<br />{<br />   //Key Matrix<br />   //COLS<br />   DDRC &amp;= ~(1 &lt;&lt; PC2);//Input<br />   PORTC &amp;= ~(1 &lt;&lt; PC2);//Low<br />   DDRC &amp;= ~(1 &lt;&lt; PC3);//Input<br />   PORTC &amp;= ~(1 &lt;&lt; PC3);//Low<br />   DDRC &amp;= ~(1 &lt;&lt; PC4);//Input<br />   PORTC &amp;= ~(1 &lt;&lt; PC4);//Low<br />   DDRC &amp;= ~(1 &lt;&lt; PC5);//Input<br />   PORTC &amp;= ~(1 &lt;&lt; PC5);//Low<br />   //ROWS<br />   DDRD &amp;= ~(1 &lt;&lt; PD0);//Input<br />   PORTD &amp;= ~(1 &lt;&lt; PD0);//Low<br />   DDRD &amp;= ~(1 &lt;&lt; PD1);//Input<br />   PORTD &amp;= ~(1 &lt;&lt; PD1);//Low<br />}<br /><br />static void hardwareInit(void)<br />{<br />   uchar   i, j;<br />   j = 0;<br />   while(--j){     /* USB Reset by device only required on Watchdog Reset */<br />      i = 0;<br />      while(--i); /* delay &gt;10ms for USB reset */<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 />   //Led<br />   DDRC |= (1 &lt;&lt; PC0); // Output<br />   PORTC &amp;= ~(1 &lt;&lt; PC0);  //PC0 LOW<br />   DDRC |= (1 &lt;&lt; PC1); // Output<br />   PORTC &amp;= ~(1 &lt;&lt; PC1);  //PC1 LOW<br />   <br />   resetMatrix();<br />}<br /><br />/* ------------------------------------------------------------------------- */<br /><br />/* The following function returns an index for the first key pressed. It<br />* returns 0 if no key is pressed.<br />*/<br />static uchar    keyPressed(void)<br />{<br />   resetMatrix();<br />   //ROW1 OUTPUT<br />   DDRD |= (1 &lt;&lt; PD0);<br />   //ROW1 HIGH<br />   PORTD |= (1 &lt;&lt; PD0);<br />   //ROW2 OUTPUT<br />   DDRD |= (1 &lt;&lt; PD1);<br />   //ROW2 LOW<br />   PORTD &amp;= ~(1 &lt;&lt; PD1);<br />   <br />   //COL1 Input DOWN &amp;&amp; PLUS<br />   DDRC &amp;= ~(1 &lt;&lt; PC2);<br />   PORTC |= (1 &lt;&lt; PC2);<br />   DDRC &amp;= ~(1 &lt;&lt; PC4);<br />   PORTC |= (1 &lt;&lt; PC4);<br />   if (!(PINC &amp; (1&lt;&lt;PC2)) &amp;&amp; !(PINC &amp; (1&lt;&lt;PC4))) {<br />      return 10;<br />   }<br />   <br />   //COL1 Input DOWN &amp;&amp; MINUS<br />   DDRC &amp;= ~(1 &lt;&lt; PC2);<br />   PORTC |= (1 &lt;&lt; PC2);<br />   DDRC &amp;= ~(1 &lt;&lt; PC5);<br />   PORTC |= (1 &lt;&lt; PC5);<br />   if (!(PINC &amp; (1&lt;&lt;PC2)) &amp;&amp; !(PINC &amp; (1&lt;&lt;PC5))) {<br />      return 9;<br />   }<br />   <br />   resetMatrix();<br />   <br />   //ROW1 OUTPUT<br />   DDRD |= (1 &lt;&lt; PD0);<br />   //ROW1 LOW<br />   PORTD &amp;= ~(1 &lt;&lt; PD0);<br />   <br />   //ROW2 OUTPUT<br />   DDRD |= (1 &lt;&lt; PD1);<br />   //ROW2 HIGH<br />   PORTD |= (1 &lt;&lt; PD1);<br />   <br />   //COL1 Input LEFT<br />   DDRC &amp;= ~(1 &lt;&lt; PC2);<br />   PORTC |= (1 &lt;&lt; PC2);<br />   if (!(PINC &amp; (1&lt;&lt;PC2))) {<br />      return 6;<br />   }<br />   <br />   //COL2 Input UP<br />   DDRC &amp;= ~(1 &lt;&lt; PC3);<br />   PORTC |= (1 &lt;&lt; PC3);<br />   if (!(PINC &amp; (1&lt;&lt;PC3))) {<br />      return 7;<br />   }<br />   <br />   //COL3 Input FAV<br />   DDRC &amp;= ~(1 &lt;&lt; PC4);<br />   PORTC |= (1 &lt;&lt; PC4);<br />   if (!(PINC &amp; (1&lt;&lt;PC4))) {<br />      return 1;<br />   }<br />   <br />   //COL4 Input F5<br />   DDRC &amp;= ~(1 &lt;&lt; PC5);<br />   PORTC |= (1 &lt;&lt; PC5);<br />   if (!(PINC &amp; (1&lt;&lt;PC5))) {<br />      return 8;<br />   }<br />   <br />   resetMatrix();<br />   <br />   //ROW1 OUTPUT<br />   DDRD |= (1 &lt;&lt; PD0);<br />   //ROW1 HIGH<br />   PORTD |= (1 &lt;&lt; PD0);<br />   <br />   <br />   //ROW2 OUTPUT<br />   DDRD |= (1 &lt;&lt; PD1);<br />   //ROW2 LOW<br />   PORTD &amp;= ~(1 &lt;&lt; PD1);<br />   <br />   //COL1 Input DOWN<br />   DDRC &amp;= ~(1 &lt;&lt; PC2);<br />   PORTC |= (1 &lt;&lt; PC2);<br />   if (!(PINC &amp; (1&lt;&lt;PC2))) {<br />      return 2;<br />   }<br />   <br />   //COL2 Input RIGHT<br />   DDRC &amp;= ~(1 &lt;&lt; PC3);<br />   PORTC |= (1 &lt;&lt; PC3);<br />   if (!(PINC &amp; (1&lt;&lt;PC3))) {<br />      return 5;<br />   }<br />   <br />   //COL3 Input PLUS<br />   DDRC &amp;= ~(1 &lt;&lt; PC4);<br />   PORTC |= (1 &lt;&lt; PC4);<br />   if (!(PINC &amp; (1&lt;&lt;PC4))) {<br />      return 4; //3<br />   }<br />   <br />   //COL4 Input MINUS<br />   DDRC &amp;= ~(1 &lt;&lt; PC5);<br />   PORTC |= (1 &lt;&lt; PC5);<br />   if (!(PINC &amp; (1&lt;&lt;PC5))) {<br />      return 3; //4<br />   }<br />   <br />   <br />   return 0;<br /><br />}<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;USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH&#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 />enum keycodes {<br />   KEY__ = 0,<br />   KEY_errorRollOver,<br />   KEY_POSTfail,<br />   KEY_errorUndefined,<br />   KEY_A,        // 4<br />   KEY_B,<br />   KEY_C,<br />   KEY_D,<br />   KEY_E,<br />   KEY_F,<br />   KEY_G,<br />   KEY_H,<br />   KEY_I,<br />   KEY_J,<br />   KEY_K,<br />   KEY_L,<br />   KEY_M,        // 0x10<br />   KEY_N,<br />   KEY_O,<br />   KEY_P,<br />   KEY_Q,<br />   KEY_R,<br />   KEY_S,<br />   KEY_T,<br />   KEY_U,<br />   KEY_V,<br />   KEY_W,<br />   KEY_X,<br />   KEY_Y,<br />   KEY_Z,<br />   KEY_1,<br />   KEY_2,<br />   KEY_3,        // 0x20<br />   KEY_4,<br />   KEY_5,<br />   KEY_6,<br />   KEY_7,<br />   KEY_8,<br />   KEY_9,<br />   KEY_0,        // 0x27<br />   KEY_enter,<br />   KEY_esc,<br />   KEY_bckspc,   // backspace<br />   KEY_tab,<br />   KEY_spc,      // space<br />   KEY_minus,    // - (and _)<br />   KEY_equal,    // = (and +)<br />   KEY_lbr,      // &#91;<br />   KEY_rbr,      // &#93;  -- 0x30<br />   KEY_bckslsh,  // \ (and |)<br />   KEY_hash,     // Non-US # and ~<br />   KEY_smcol,    // ; (and :)<br />   KEY_ping,     // ' and &quot;<br />   KEY_grave,    // Grave accent and tilde<br />   KEY_comma,    // , (and &lt;)<br />   KEY_dot,      // . (and &gt;)<br />   KEY_slash,    // / (and ?)<br />   KEY_cpslck,   // capslock<br />   KEY_F1,<br />   KEY_F2,<br />   KEY_F3,<br />   KEY_F4,<br />   KEY_F5,<br />   KEY_F6,<br />   KEY_F7,       // 0x40<br />   KEY_F8,<br />   KEY_F9,<br />   KEY_F10,<br />   KEY_F11,<br />   KEY_F12,<br />   KEY_PrtScr,<br />   KEY_scrlck,<br />   KEY_break,<br />   KEY_ins,<br />   KEY_home,<br />   KEY_pgup,<br />   KEY_del,<br />   KEY_end,<br />   KEY_pgdn,<br />   KEY_rarr,<br />   KEY_larr,     // 0x50<br />   KEY_darr,<br />   KEY_uarr,<br />   KEY_numlock,<br />   KEY_KPslash,<br />   KEY_KPast,<br />   KEY_KPminus,<br />   KEY_KPplus,<br />   KEY_KPenter,<br />   KEY_KP1,<br />   KEY_KP2,<br />   KEY_KP3,<br />   KEY_KP4,<br />   KEY_KP5,<br />   KEY_KP6,<br />   KEY_KP7,<br />   KEY_KP8,      // 0x60<br />   KEY_KP9,<br />   KEY_KP0,<br />   KEY_KPcomma,<br />   KEY_Euro2,<br /><br />   /* These are NOT standard USB HID - handled specially in decoding,<br />   so they will be mapped to the modifier byte in the USB report */<br />   KEY_Modifiers,<br />   MOD_LCTRL,    // 0x01<br />   MOD_LSHIFT,   // 0x02<br />   MOD_LALT,     // 0x04<br />   MOD_LGUI,     // 0x08<br />   MOD_RCTRL,    // 0x10<br />   MOD_RSHIFT,   // 0x20<br />   MOD_RALT,     // 0x40<br />   MOD_RGUI,     // 0x80<br />};<br /><br />#define KEY_VOLUME_UP         0x80     // Keyboard Volume Up 0xE9<br />#define KEY_VOLUME_DOWN       0x81     // Keyboard Volume Down 0xEA<br /><br />#define NUM_KEYS    10<br />static const uchar  keyReport&#91;NUM_KEYS + 1&#93;&#91;2&#93; PROGMEM = {<br />   /* none */{ 0 },                   /* no key pressed */<br />   /*  1 */{ 0, KEY_F },<br />   /*  2 */{ 0, KEY_darr },<br />   /*  3 */{ 0, KEY_KPplus },<br />   /*  4 */{ 0, KEY_KPminus },<br />   /*  5 */{ 0, KEY_rarr },<br />   /*  6 */{ 0, KEY_larr },<br />   /*  7 */{ 0, KEY_uarr },<br />   /*  8 */{ 0, KEY_F5 },<br />   /*  9 */{ 0, KEY_VOLUME_UP },<br />   /*  10 */{ 0, KEY_VOLUME_DOWN },<br />};<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(keyPressed());<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 /><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 />   usbInit();<br />   sei();<br />   for(;;){   /* main event loop */<br />      wdt_reset();<br />      usbPoll();<br />      key = keyPressed();<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; 40){<br />               idleCounter -= 1;   /* 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 />   /*<br /><br />   uchar   key, lastKey = 0, keyDidChange = 0;<br />   uint16_t delaytime = 2, delaytimer = 0;<br /><br />   wdt_enable(WDTO_2S);<br />   hardwareInit();<br />   usbInit();<br />   sei();<br /><br />   while (1){<br /><br />   wdt_reset();<br />   usbPoll();<br /><br />   if (usbInterruptIsReady()){<br />   buildReport(keyscan());<br />   usbSetInterrupt(reportBuffer, sizeof(reportBuffer));<br />   }<br /><br />   }<br /><br />   return 0;<br />   */<br />}<br /><br />/* ------------------------------------------------------------------------- */<br /></code></pre></div><p>Statistics: Posted by <a href="https://forums.obdev.at/memberlist.php?mode=viewprofile&amp;u=20591">ripper121</a> — Tue Aug 22, 2017 10:00 am</p><hr />
]]></content>
	</entry>
	</feed>
