Is there a way to use the USB HID to control the specific GUI volume on Windows? - usb

I have a USB(1.1) audio project using a MCU with the USB HID to control the Host(Windows 10)
volume, this project combine with a UAC class and HID class.
I have successfully used the consumer page(0x09) to control Windows volume up/down, but now
I need to control specific Windows applications volume, Is there a way to use the USB HID to
control the specific applications volume on Windows ?
specific like a media play, or a brower playing yourbe music, or a
skype phone call volume, you can set every single volume via Windows
Sound Mixer
the follow is part of my hid report descriptor
0x05, 0x0C, // Usage Page (Consumer)
0x09, 0x01, // Usage(Consumer Control)
0xA1, 0x01, // Collection(Application )
0x85, 0x01, // Report ID (1)
0x15, 0x00, // Logical Minimum(0x0 )
0x25, 0x01, // Logical Maximum(0x1 )
0x09, 0xE2, // Usage(play back Mute) //1
0x09, 0xE9, // Usage(Volume Increment) //2
0x09, 0xB5, // Usage(Scan Next Track) //4
0x09, 0xEA, // Usage(Volume Decrement) //8
0x09, 0xB6, // Usage(Scan Previous Track) //10
0x09, 0xCD, // Usage(Play/Pause) //20
thank you

There is document available that lists HID Usages from Consumer Page (0x0C) that are supported in Windows 8. Regarding volume controls it lists:
Usage
Usage name
Usage type
0xE0
Volume
Linear Control (LC)
0xE2
Mute
On/Off Control (OOC)
0xE3
Bass
Linear Control (LC)
0xE4
Treble
Linear Control (LC)
0xE5
Bass Boost
On/Off Control (OOC)
0xE9
Volume Increment
Re-trigger Control (RTC)
0xEA
Volume Decrement
Re-trigger Control (RTC)
0x0152
Bass Increment
Re-trigger Control (RTC)
0x0153
Bass Decrement
Re-trigger Control (RTC)
0x0154
Treble Increment
Re-trigger Control (RTC)
0x0155
Treble Decrement
Re-trigger Control (RTC)
AFAIK that is what we got out of the box on Windows.
"15 Consumer Page (0x0C)" chapter of the HID Usage Tables spec has a bit bigger list of audio usages:
Usage ID
Usage Name
Usage Types
0xE0
Volume
LC
0xE1
Balance
LC
0xE2
Mute
OOC
0xE3
Bass
LC
0xE4
Treble
LC
0xE5
Bass Boost
OOC
0xE6
Surround Mode
OSC
0xE7
Loudness
OOC
0xE8
MPX
OOC
0xE9
Volume Increment
RTC
0xEA
Volume Decrement
RTC
0x0150
Balance Right
RTC
0x0151
Balance Left
RTC
0x0152
Bass Increment
RTC
0x0153
Bass Decrement
RTC
0x0154
Treble Increment
RTC
0x0155
Treble Decrement
RTC
If you really want to do "per-application volume" thing then you can report your volume knobs in Vendor-Defined Usage Page (any value in 0xFF00-0xFFFF range) and write a custom user-mode tool (or HID event filter driver for your VID/PID) that will read that data and do what you want:
enumerate audio sessions via IAudioSessionEnumerator
cast IAudioSessionControl to ISimpleAudioVolume
call ISimpleAudioVolume::SetMasterVolume method to set per-application (AudioSession) volume.

Related

GPIO interrupt for MSP430f2274

i am working on a project in msp430f2274 microcontroller. In my project i am trying to read an reed switch which is being connected to a GPIO pin at P2.3. Normally the pin will remain HIGH as it is being connected to pull up from the hardware. when once the switch is pressed/activated a LOW will come and it will trigger the Hardware. till here it is working fine. but now i want to read the other interrupt also, when it goes back to high. I have tried the interrupt type from low - high to high -low in ISR but still no efffect. please help.
i have added ISR from the code
static char x=0;
#pragma vector=PORT1_VECTOR
__interrupt void PORT1_ISR(void)
{
P1IES^=BIT2;
P1OUT^=(BIT0); // enrer the rest code for detection of door open or close.
P1IFG &= ~BIT2;
//P1IES&=~BIT2;
__bis_SR_register_on_exit(GIE+LPM0_bits); // Enter LPM3 on ISR exit
}
Just an idea, sry if this doesn't help.
You could use a timer that starts with the button click and triggers an interrupt when the button is released.

USB keyboard DataOut callback function and RxReady Callback

I am making a USB keyboard using stm32F0RBT6 micro-controller. I want to receive data from PC for Caps Lock and Scroll Lock leds. Do I need to initiate a callback funtion like those ones?
static uint8_t USBD_HID_EP0_RxReady (USBD_HandleTypeDef *pdev);
static uint8_t USBD_HID_DataOut (USBD_HandleTypeDef *pdev, uint8_t epnum);
Any help regarding receiving data would be appreciated. Thank you.
A USB keyboard uses the USB class HID (Human Interface Device), the specification can be found here. The state of the LEDs are set with a set_report message, which is transmitted over the setup endpoint (also called default endpoint in the document) which is also endpoint 0 (EP0).
The format of the report used for keyboards can be found in the specification (page 59).
Therefore you need to use the callback function USBD_HID_EP0_RxReady and parse the set_report message you received.

I'm trying to connect a Genius mouse to an Arduino using a PS2 mouse sketch, but it will not initialise the mouse

I have been using the mouse sketch at the bottom of this message (written by someone else) to try to get the motion data out of a PS/2 mouse. I have checked the specification for this mouse which says that it is PS/2 compatible. However, when I run it it appears to stop at the first line of mouse_init where it says, "mouse.write(0xff); // reset". This is a call to a function in ps2.h. ps2.h has been around since 2008 and has been used in a number of projects, so I assume it is okay, but I was wondering if there might be some peculiar features of USB mice connecting as PS/2 mice that this library was never designed to cope with. Does anyone have any experience that might shed some light on this?
I have been able to determine that mouse.write is changing the state of my Genius mouse, but it gets stuck at the point where the Mouse is supposed to bring the clock state low so that the host can proceed to transmit data. Before mouse.write starts the clock state is low, but it gets pushed high by the host a few lines into mouse.write and stays there. The mouse never pulls it low again. Any thoughts on what the trouble might be would be greatly appreciated.
#include <ps2.h>
/*
* an arduino sketch to interface with a ps/2 mouse.
* Also uses serial protocol to talk back to the host
* and report what it finds.
*/
/*
* Pin 5 is the mouse data pin, pin 6 is the clock pin
* Feel free to use whatever pins are convenient.
*/
PS2 mouse(6, 5);
/*
* initialize the mouse. Reset it, and place it into remote
* mode, so we can get the encoder data on demand.
*/
void mouse_init()
{
mouse.write(0xff); // reset
mouse.read(); // ack byte
mouse.read(); // blank */
mouse.read(); // blank */
mouse.write(0xf0); // remote mode
mouse.read(); // ack
delayMicroseconds(100);
}
void setup()
{
Serial.begin(9600);
mouse_init();
}
/*
* get a reading from the mouse and report it back to the
* host via the serial line.
*/
void loop()
{
char mstat;
char mx;
char my;
/* get a reading from the mouse */
mouse.write(0xeb); // give me data!
mouse.read(); // ignore ack
mstat = mouse.read();
mx = mouse.read();
my = mouse.read();
/* send the data back up */
Serial.print(mstat, BIN);
Serial.print("\tX=");
Serial.print(mx, DEC);
Serial.print("\tY=");
Serial.print(my, DEC);
Serial.println();
// delay(20); /* twiddle */
}
Solved it. As it turns out the Genius mouse I brought is not backward compatible with PS/2 even though the specification says it is. They must have exchanged the sensor chip for one where the PS/2 capability was not present at some point. I now have another USB mouse which is doing the job I wanted perfectly.

Storing of image in on-chip memory of MCB1700 evaluation board

I work with MCB1700 evaluation board.
It has (320 x 240) TF LCD Display.
IDE: Keil uvision4 4.03q.
My task is to download picture from PC to MCB1700, display it on LCD
and download on USB-stick (that connects to the board).
I need 320*240*2 = 153600 bytes of memory.
MCB1700 has only 64kB SRAM, and 512kB of on-chip Flash memory.
Obviously, I must store picture in Flash memory.
As I understand, I should bind pointer directly to memory address.
/* Base addresses */
#define LPC_FLASH_BASE (0x00000000UL) //beginning address of on-chip Flash
#define LPC_IMAGE_ADDR (LPC_FLASH_BASE + 0x10000)
#define ImagePtr ((unsigned short *) LPC_IMAGE_ADDR )
//read-write operations
ImagePtr[0] = 0x0124; //First pixel
…
ImagePtr[320*240] = 0xFA37; //Last pixel
unsigned short A = ImagePtr[0];
Is it correct?
I have a doubts because of Target’s options.
Flash memory’s area is defined like Read/Only IROM1.
Does it mean that we can only read data from Flash and must change Memory area in IROM and IRAM fields to perform writing operation? For example in such way:
You might do better to let the compiler/linker decide where to place the image in Flash:
static const unsigned short Image[320*240] = { <image data> } ;
will place Image as an array in ROM1 memory.
You cannot write directly to flash memory, it is normally read-only, and while write operations are word oriented, a word cannot be written unless it is previously erased and erasure is page or sector oriented - so it is somewhat more complex to manage that your example code.
In my suggestion above I have included an initialiser. Now it is obviously impractical to manually initialise 320*240 elements, but it is simple enough to write a PC based tool that will generate the necessary initialiser code directly from an image file.
Alternatively, if the image cannot be static, you might reserve part of your Flash for the image and then write code to write the flash memory and where necessary erase pages from data downloaded from a serial port or USB for example. In this case the Flash memory must be page aligned and comprise of an integer multiple of Flash pages.
For flexibility you should not rely on the target dialog settings and instead create a custom scatter file, where you can then create a custom section and allocate your image memory to it using armcc extension __attribute__ variable qualifiers.

Configuring PINB.4 and PINB.5 in AVR ATMega 169 to work as input pins and to enable pull up?

I want to configure two AVR butterfly boards in such a way that PORT D is an output port in the first one and two pins of this PORT D are connected to pins B.4 and B.5 of port B of the second AVR butterfly board. I also want to enable pull-ups on these port B pins. Is this configuration correct for the second AVR ? Is there something that i am missing?
//Init port pins
DDRB = 0x00;
PORTB |= 0X30;
//Enable pin change interrupt on PORTB
PCMSK1 = 0X30;
EIFR = 0XC0;
EIMSK = 0XC0;
SIGNAL(SIG_PIN_CHANGE1)-- Pin change interrupt of PIN B.4
{..}
SIGNAL(SIG_PIN_CHANGE2)-- Pin change interrupt of PIN B.5
{..... }
You have set up you PORT B correctly but it wouldn't hurt to improve your coding conventions a little.
DDRB&= ~(1<<PB0)|(1<<PB1);
PORTB|= (1<<PB0)|(1<<PB1);
Unless I am miss-understanding what your trying to accomplish, I don't think your interrupts are configured correctly.
PB4 and PB5 correspond to PCINT12 and PCINT13 respectively.
Since both correspond to Pin Change Interrupt Enable 1 you'll want to only have that pin enabled.
EIMSK = (1<<PCIE1);
You don't actually need to set EIFR unless your trying to manually trigger an interrupt. This register gets flagged automatically whenever a pin change occurs.
In PCMSK1 you want to set PCINT13 and PCINT12
PCMSK1 |= (1<<PCINT12)|(1<<PCINT13);
This enables interrupts on the corresponding pins.
Also SIGNAL is depreciated. #include avr/interrupt.h and use ISR.
ISR(PCINT1_vect){}
Both Pin changes will be handled by this vector.
Hope this clears things up a bit.