Volume Control not working
Posted: Tue Aug 22, 2017 10:00 am
Hello ,
i dont get the Volume controle running .
This is my usb Hid Report Descriptor:
This is the complete code:
i dont get the Volume controle running .
This is my usb Hid Report Descriptor:
Code: Select all
#define USB_CFG_INTERFACE_CLASS 0x03 /* HID class */
#define USB_CFG_INTERFACE_SUBCLASS 0x01 /* Boot-device subclass */
#define USB_CFG_INTERFACE_PROTOCOL 0x01 /* Keyboard protocol */
#define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH 35
const PROGMEM char usbHidReportDescriptor[USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH] = { /* USB report descriptor */
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x06, // USAGE (Keyboard)
0xa1, 0x01, // COLLECTION (Application)
0x05, 0x07, // USAGE_PAGE (Keyboard)
0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x08, // REPORT_COUNT (8)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x08, // REPORT_SIZE (8)
0x25, 0x65, // LOGICAL_MAXIMUM (101)
0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
0x81, 0x00, // INPUT (Data,Ary,Abs)
0xc0 // END_COLLECTION
};
#define KEY_VOLUME_UP 0x80 // Keyboard Volume Up 0xE9
#define KEY_VOLUME_DOWN 0x81 // Keyboard Volume Down 0xEA
This is the complete code:
Code: Select all
#define F_CPU 12000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <avr/wdt.h>
#include "usbdrv/usbdrv.h"
/* ----------------------- hardware I/O abstraction ------------------------ */
/* pin assignments:
LED1 = PC1
LED2 = PC0
COL1 = PC2
COL2 = PC3
COL3 = PC4
COL4 = PC5
ROW1 = PD0
ROW2 = PD1
PB1 USB-
PB0 USB+ (int0)
*/
static void resetMatrix(void)
{
//Key Matrix
//COLS
DDRC &= ~(1 << PC2);//Input
PORTC &= ~(1 << PC2);//Low
DDRC &= ~(1 << PC3);//Input
PORTC &= ~(1 << PC3);//Low
DDRC &= ~(1 << PC4);//Input
PORTC &= ~(1 << PC4);//Low
DDRC &= ~(1 << PC5);//Input
PORTC &= ~(1 << PC5);//Low
//ROWS
DDRD &= ~(1 << PD0);//Input
PORTD &= ~(1 << PD0);//Low
DDRD &= ~(1 << PD1);//Input
PORTD &= ~(1 << PD1);//Low
}
static void hardwareInit(void)
{
uchar i, j;
j = 0;
while(--j){ /* USB Reset by device only required on Watchdog Reset */
i = 0;
while(--i); /* delay >10ms for USB reset */
}
/* configure timer 0 for a rate of 12M/(1024 * 256) = 45.78 Hz (~22ms) */
TCCR0 = 5; /* timer 0 prescaler: 1024 */
//Led
DDRC |= (1 << PC0); // Output
PORTC &= ~(1 << PC0); //PC0 LOW
DDRC |= (1 << PC1); // Output
PORTC &= ~(1 << PC1); //PC1 LOW
resetMatrix();
}
/* ------------------------------------------------------------------------- */
/* The following function returns an index for the first key pressed. It
* returns 0 if no key is pressed.
*/
static uchar keyPressed(void)
{
resetMatrix();
//ROW1 OUTPUT
DDRD |= (1 << PD0);
//ROW1 HIGH
PORTD |= (1 << PD0);
//ROW2 OUTPUT
DDRD |= (1 << PD1);
//ROW2 LOW
PORTD &= ~(1 << PD1);
//COL1 Input DOWN && PLUS
DDRC &= ~(1 << PC2);
PORTC |= (1 << PC2);
DDRC &= ~(1 << PC4);
PORTC |= (1 << PC4);
if (!(PINC & (1<<PC2)) && !(PINC & (1<<PC4))) {
return 10;
}
//COL1 Input DOWN && MINUS
DDRC &= ~(1 << PC2);
PORTC |= (1 << PC2);
DDRC &= ~(1 << PC5);
PORTC |= (1 << PC5);
if (!(PINC & (1<<PC2)) && !(PINC & (1<<PC5))) {
return 9;
}
resetMatrix();
//ROW1 OUTPUT
DDRD |= (1 << PD0);
//ROW1 LOW
PORTD &= ~(1 << PD0);
//ROW2 OUTPUT
DDRD |= (1 << PD1);
//ROW2 HIGH
PORTD |= (1 << PD1);
//COL1 Input LEFT
DDRC &= ~(1 << PC2);
PORTC |= (1 << PC2);
if (!(PINC & (1<<PC2))) {
return 6;
}
//COL2 Input UP
DDRC &= ~(1 << PC3);
PORTC |= (1 << PC3);
if (!(PINC & (1<<PC3))) {
return 7;
}
//COL3 Input FAV
DDRC &= ~(1 << PC4);
PORTC |= (1 << PC4);
if (!(PINC & (1<<PC4))) {
return 1;
}
//COL4 Input F5
DDRC &= ~(1 << PC5);
PORTC |= (1 << PC5);
if (!(PINC & (1<<PC5))) {
return 8;
}
resetMatrix();
//ROW1 OUTPUT
DDRD |= (1 << PD0);
//ROW1 HIGH
PORTD |= (1 << PD0);
//ROW2 OUTPUT
DDRD |= (1 << PD1);
//ROW2 LOW
PORTD &= ~(1 << PD1);
//COL1 Input DOWN
DDRC &= ~(1 << PC2);
PORTC |= (1 << PC2);
if (!(PINC & (1<<PC2))) {
return 2;
}
//COL2 Input RIGHT
DDRC &= ~(1 << PC3);
PORTC |= (1 << PC3);
if (!(PINC & (1<<PC3))) {
return 5;
}
//COL3 Input PLUS
DDRC &= ~(1 << PC4);
PORTC |= (1 << PC4);
if (!(PINC & (1<<PC4))) {
return 4; //3
}
//COL4 Input MINUS
DDRC &= ~(1 << PC5);
PORTC |= (1 << PC5);
if (!(PINC & (1<<PC5))) {
return 3; //4
}
return 0;
}
/* ------------------------------------------------------------------------- */
/* ----------------------------- USB interface ----------------------------- */
/* ------------------------------------------------------------------------- */
static uchar reportBuffer[2]; /* buffer for HID reports */
static uchar idleRate; /* in 4 ms units */
const PROGMEM char usbHidReportDescriptor[USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH] = { /* USB report descriptor */
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x06, // USAGE (Keyboard)
0xa1, 0x01, // COLLECTION (Application)
0x05, 0x07, // USAGE_PAGE (Keyboard)
0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x08, // REPORT_COUNT (8)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x08, // REPORT_SIZE (8)
0x25, 0x65, // LOGICAL_MAXIMUM (101)
0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
0x81, 0x00, // INPUT (Data,Ary,Abs)
0xc0 // END_COLLECTION
};
/* We use a simplifed keyboard report descriptor which does not support the
* boot protocol. We don't allow setting status LEDs and we only allow one
* simultaneous key press (except modifiers). We can therefore use short
* 2 byte input reports.
* The report descriptor has been created with usb.org's "HID Descriptor Tool"
* which can be downloaded from http://www.usb.org/developers/hidpage/.
* Redundant entries (such as LOGICAL_MINIMUM and USAGE_PAGE) have been omitted
* for the second INPUT item.
*/
enum keycodes {
KEY__ = 0,
KEY_errorRollOver,
KEY_POSTfail,
KEY_errorUndefined,
KEY_A, // 4
KEY_B,
KEY_C,
KEY_D,
KEY_E,
KEY_F,
KEY_G,
KEY_H,
KEY_I,
KEY_J,
KEY_K,
KEY_L,
KEY_M, // 0x10
KEY_N,
KEY_O,
KEY_P,
KEY_Q,
KEY_R,
KEY_S,
KEY_T,
KEY_U,
KEY_V,
KEY_W,
KEY_X,
KEY_Y,
KEY_Z,
KEY_1,
KEY_2,
KEY_3, // 0x20
KEY_4,
KEY_5,
KEY_6,
KEY_7,
KEY_8,
KEY_9,
KEY_0, // 0x27
KEY_enter,
KEY_esc,
KEY_bckspc, // backspace
KEY_tab,
KEY_spc, // space
KEY_minus, // - (and _)
KEY_equal, // = (and +)
KEY_lbr, // [
KEY_rbr, // ] -- 0x30
KEY_bckslsh, // \ (and |)
KEY_hash, // Non-US # and ~
KEY_smcol, // ; (and :)
KEY_ping, // ' and "
KEY_grave, // Grave accent and tilde
KEY_comma, // , (and <)
KEY_dot, // . (and >)
KEY_slash, // / (and ?)
KEY_cpslck, // capslock
KEY_F1,
KEY_F2,
KEY_F3,
KEY_F4,
KEY_F5,
KEY_F6,
KEY_F7, // 0x40
KEY_F8,
KEY_F9,
KEY_F10,
KEY_F11,
KEY_F12,
KEY_PrtScr,
KEY_scrlck,
KEY_break,
KEY_ins,
KEY_home,
KEY_pgup,
KEY_del,
KEY_end,
KEY_pgdn,
KEY_rarr,
KEY_larr, // 0x50
KEY_darr,
KEY_uarr,
KEY_numlock,
KEY_KPslash,
KEY_KPast,
KEY_KPminus,
KEY_KPplus,
KEY_KPenter,
KEY_KP1,
KEY_KP2,
KEY_KP3,
KEY_KP4,
KEY_KP5,
KEY_KP6,
KEY_KP7,
KEY_KP8, // 0x60
KEY_KP9,
KEY_KP0,
KEY_KPcomma,
KEY_Euro2,
/* These are NOT standard USB HID - handled specially in decoding,
so they will be mapped to the modifier byte in the USB report */
KEY_Modifiers,
MOD_LCTRL, // 0x01
MOD_LSHIFT, // 0x02
MOD_LALT, // 0x04
MOD_LGUI, // 0x08
MOD_RCTRL, // 0x10
MOD_RSHIFT, // 0x20
MOD_RALT, // 0x40
MOD_RGUI, // 0x80
};
#define KEY_VOLUME_UP 0x80 // Keyboard Volume Up 0xE9
#define KEY_VOLUME_DOWN 0x81 // Keyboard Volume Down 0xEA
#define NUM_KEYS 10
static const uchar keyReport[NUM_KEYS + 1][2] PROGMEM = {
/* none */{ 0 }, /* no key pressed */
/* 1 */{ 0, KEY_F },
/* 2 */{ 0, KEY_darr },
/* 3 */{ 0, KEY_KPplus },
/* 4 */{ 0, KEY_KPminus },
/* 5 */{ 0, KEY_rarr },
/* 6 */{ 0, KEY_larr },
/* 7 */{ 0, KEY_uarr },
/* 8 */{ 0, KEY_F5 },
/* 9 */{ 0, KEY_VOLUME_UP },
/* 10 */{ 0, KEY_VOLUME_DOWN },
};
static void buildReport(uchar key)
{
/* This (not so elegant) cast saves us 10 bytes of program memory */
*(int *)reportBuffer = pgm_read_word(keyReport[key]);
}
uchar usbFunctionSetup(uchar data[8])
{
usbRequest_t *rq = (void *)data;
usbMsgPtr = reportBuffer;
if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){ /* class request type */
if(rq->bRequest == USBRQ_HID_GET_REPORT){ /* wValue: ReportType (highbyte), ReportID (lowbyte) */
/* we only have one report type, so don't look at wValue */
buildReport(keyPressed());
return sizeof(reportBuffer);
}else if(rq->bRequest == USBRQ_HID_GET_IDLE){
usbMsgPtr = &idleRate;
return 1;
}else if(rq->bRequest == USBRQ_HID_SET_IDLE){
idleRate = rq->wValue.bytes[1];
}
}else{
/* no vendor specific requests implemented */
}
return 0;
}
/* ------------------------------------------------------------------------- */
int main(void)
{
uchar key, lastKey = 0, keyDidChange = 0;
uchar idleCounter = 0;
wdt_enable(WDTO_2S);
hardwareInit();
usbInit();
sei();
for(;;){ /* main event loop */
wdt_reset();
usbPoll();
key = keyPressed();
if(lastKey != key){
lastKey = key;
keyDidChange = 1;
}
if(TIFR & (1<<TOV0)){ /* 22 ms timer */
TIFR = 1<<TOV0;
if(idleRate != 0){
if(idleCounter > 40){
idleCounter -= 1; /* 22 ms in units of 4 ms */
}else{
idleCounter = idleRate;
keyDidChange = 1;
}
}
}
if(keyDidChange && usbInterruptIsReady()){
keyDidChange = 0;
/* use last key and not current key status in order to avoid lost
changes in key status. */
buildReport(lastKey);
usbSetInterrupt(reportBuffer, sizeof(reportBuffer));
}
}
return 0;
/*
uchar key, lastKey = 0, keyDidChange = 0;
uint16_t delaytime = 2, delaytimer = 0;
wdt_enable(WDTO_2S);
hardwareInit();
usbInit();
sei();
while (1){
wdt_reset();
usbPoll();
if (usbInterruptIsReady()){
buildReport(keyscan());
usbSetInterrupt(reportBuffer, sizeof(reportBuffer));
}
}
return 0;
*/
}
/* ------------------------------------------------------------------------- */