HID mouse touchscreen

General discussions about V-USB, our firmware-only implementation of a low speed USB device on Atmel's AVR microcontrollers
Post Reply
mn6500
Posts: 2
Joined: Fri Jun 03, 2011 1:47 pm

HID mouse touchscreen

Post by mn6500 » Sun Jun 12, 2011 10:07 am

Hi all
I want to make a touchpad HID mouse my micro is mega16 and crystal is also 16 MHz. i run HID-mouse (v-sub example) without any problems, but for a/d and my touch have problems. Have you please guide , thanks . this is my program :

/* Name: main.c
* Project: hid-mouse, a very simple HID example
* Author: Christian Starkjohann
* Creation Date: 2008-04-07
* Tabsize: 4
* Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
* This Revision: $Id: main.c 692 2008-11-07 15:07:40Z cs $

* Project: USB Touchscreen Mouse
* Author: M.N



* External 16MHz crystal. Fuse bits: LFuse 0xdf, HFuse 0xde


*/

/*
This example should run on most AVRs with only little changes. No special
hardware resources except INT0 are used. You may have to change usbconfig.h for
different I/O pins for USB. Please note that USB D+ must be the INT0 pin, or
at least be connected to INT0 as well.

We use VID/PID 0x046D/0xC00E which is taken from a Logitech mouse. Don't
publish any hardware using these IDs! This is for demonstration only!
*/

#include <stdlib.h>
#include <stdio.h>
#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/interrupt.h> /* for sei() */
#include <util/delay.h> /* for _delay_ms() */

#include <avr/pgmspace.h> /* required by usbdrv.h */
#include "usbdrv.h"
#include "oddebug.h" /* This is also an example for using debug macros */

#define sbi(var, mask) ((var) |= (uint8_t)(1 << mask))
#define cbi(var, mask) ((var) &= (uint8_t)~(1 << mask))

#define BUFFER 5 //how many samples to take from the ADC before moving the mouse
#define LOWACCURACY 1 //if values are higher than this move mouse
#define HIGHACCURACY 100 //if values are lower than this move mouse
#define SCALE 1 //speed of mouse

#define XDIFF (x_buffer[0]-x_buffer[BUFFER-1])
#define YDIFF (y_buffer[0]-y_buffer[BUFFER-1])

void read_x(void);
void read_y(void);
void timerinit(void);
void timerpoll(void);
void calc(void);

//Global Vars
//======================
uint16_t l;// xlow register
uint16_t h;// xhigh register
uint16_t l1;// ylow register
uint16_t h1;// yhigh register
int16_t x_buffer[BUFFER + 1];
int16_t y_buffer[BUFFER + 1];
char timerflag;
int i = 0;
char movex;
char movey;

/* ------------------------------------------------------------------------- */
/* ----------------------------- USB interface ----------------------------- */
/* ------------------------------------------------------------------------- */

PROGMEM char usbHidReportDescriptor[52] = { /* USB report descriptor, size must match usbconfig.h */
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x02, // USAGE (Mouse)
0xa1, 0x01, // COLLECTION (Application)
0x09, 0x01, // USAGE (Pointer)
0xA1, 0x00, // COLLECTION (Physical)
0x05, 0x09, // USAGE_PAGE (Button)
0x19, 0x01, // USAGE_MINIMUM
0x29, 0x03, // USAGE_MAXIMUM
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x95, 0x03, // REPORT_COUNT (3)
0x75, 0x01, // REPORT_SIZE (1)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x05, // REPORT_SIZE (5)
0x81, 0x03, // INPUT (Const,Var,Abs)
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x30, // USAGE (X)
0x09, 0x31, // USAGE (Y)
0x09, 0x38, // USAGE (Wheel)
0x15, 0x81, // LOGICAL_MINIMUM (-127)
0x25, 0x7F, // LOGICAL_MAXIMUM (127)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x03, // REPORT_COUNT (3)
0x81, 0x06, // INPUT (Data,Var,Rel)
0xC0, // END_COLLECTION
0xC0, // END COLLECTION
};
/* This is the same report descriptor as seen in a Logitech mouse. The data
* described by this descriptor consists of 4 bytes:
* . . . . . B2 B1 B0 .... one byte with mouse button states
* X7 X6 X5 X4 X3 X2 X1 X0 .... 8 bit signed relative coordinate x
* Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 .... 8 bit signed relative coordinate y
* W7 W6 W5 W4 W3 W2 W1 W0 .... 8 bit signed relative coordinate wheel
*/
typedef struct{
uchar buttonMask;
char dx;
char dy;
char dWheel;
}report_t;

static report_t reportBuffer;
static uchar idleRate; /* repeat rate for keyboards, never used for mice */

void calc(void)
{
timerpoll();

if(timerflag == 1) //if the timer overflow bit gets enabled
{
read_x();
read_y();
x_buffer[i] = h;
y_buffer[i] = h1;
timerflag = 0;
++i;
}

if(i == BUFFER + 1)
{

//char xshifted = (YDIFF>>2); //turns the 10bit ADC to a signed 8bit integer
//if (YDIFF<0) xshifted *= -1;


char xshifted = ((XDIFF>>3)|((XDIFF&0x8000)>>8)); //turns the 10bit ADC to a signed 8bit integer
char yshifted = ((YDIFF>>3)|((YDIFF&0x8000)>>8));

if((abs(xshifted) > LOWACCURACY) && (abs(xshifted) < HIGHACCURACY))
{
movex = SCALE * xshifted;
}
else movex = 0;

if((abs(yshifted) > LOWACCURACY) && (abs(yshifted) < HIGHACCURACY))
{
movey = -SCALE * yshifted;
}
else movey = 0;

if(h > 1000) movex = 0;//keeps the mouse cursor still if there is no touch
if(h1 > 1000) movey = 0;

i = 0;
}
}

static void moveMouse(void)
{
reportBuffer.dx = movex;
reportBuffer.dy = movey;
}

void read_x(void)
{
//DDRA = 0b00010010; // Output on PA4(5V) and PA1(GND), Input on PA4(ADC)
//sbi(PORTA, 4); //pull PA4 to 5V
//cbi(PORTA, 1); //pull PA1 to GND

//_delay_us(100); //wait for capacitance in screen to charge

//ADMUX = (1 << MUX1);//ADC2
//ADCSRA = (1 << ADEN)|(1 << ADSC)|(1<<ADPS2)|(1<<ADPS1);

//while(ADCSRA & (1 << ADSC));
//l = ADCL;
//h = ADCH & 0x03;
//h = h << 8;
//h = h + l;

int Xadc=0;
float y,x;//y[10],x[10];//,sum_y=0,sum_x=0;
//char i=0;


//for(i=0;i<1;i++)
//{
//y sense
DDRA = 0b00001010;
PORTA = 0b00001000;
_delay_us(150);
ADMUX &= 0xF8;
ADCSRA |= 0x40;
while((ADCSRA & 0x10)==0);
ADCSRA |= 0x10;
Xadc = ADCW;
//for vcc=4.5v
//y[i] = (4.5*Xadc)/1024;
y = Xadc ;
Xadc = 0x00;
ADCL = 0x00;
ADCH = 0x00;
ADCSRA &= 0xBF;
ADMUX &= 0xE0;

//x sense
DDRA = 0b00000101;
PORTA = 0b00000001;
_delay_us(150);
ADMUX |= 0x41;
ADCSRA |=0x40;
while((ADCSRA & 0x10)==0);
ADCSRA |= 0x10;
Xadc = ADCW;
//for vcc=4.5v
//x[i] = (4.5*Xadc)/1024;
x = Xadc;
Xadc = 0x00;
ADCW = 0x00;
ADCSRA &= 0xBF;
ADMUX &= 0xE0;

//delay_ms(10);
//}


//for(i=0;i<1;i++)
//{
// sum_y += y[i];
// sum_x += x[i];
//}
//sum_y /= 1;
//sum_x /= 1;
h = x;
h1 = y;
}

void read_y(void)
{
//DDRA = 0b00001100; // Output on PA2(5V) and PA3(GND), Input on PA4(ADC)
//sbi(PORTA, 2); //pull PA2 to 5V
//cbi(PORTA, 3); //pull PA3 to GND

//_delay_us(100); //wait for capacitance in screen to charge

//ADMUX = (1 << MUX2);//ADC4
//ADCSRA = (1 << ADEN)|(1 << ADSC)|(1<<ADPS2)|(1<<ADPS1);

//while(ADCSRA & (1 << ADSC));
//l1 = ADCL;
//h1 = ADCH & 0x03;
//h1 = h1 << 8;
//h1 = h1 + l1;
}

void timerinit(void)
{
TCCR0 = 0x01; // select clock: 16M/1k -> overflow rate = 16M/256k = 62.5 Hz
}

void timerpoll(void)
{
if(TIFR & (1 << TOV0))
{
TIFR = (1 << TOV0); /* clear overflow */
timerflag = 1;
}
}
/* ------------------------------------------------------------------------- */

usbMsgLen_t usbFunctionSetup(uchar data[8])
{
usbRequest_t *rq = (void *)data;

/* The following requests are never used. But since they are required by
* the specification, we implement them in this example.
*/
if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){ /* class request type */
DBG1(0x50, &rq->bRequest, 1); /* debug output: print our request */
if(rq->bRequest == USBRQ_HID_GET_REPORT){ /* wValue: ReportType (highbyte), ReportID (lowbyte) */
/* we only have one report type, so don't look at wValue */
usbMsgPtr = (void *)&reportBuffer;
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; /* default for not implemented requests: return no data back to host */
}

/* ------------------------------------------------------------------------- */

int main(void)
{
uchar i;

wdt_enable(WDTO_1S);
/* Even if you don't use the watchdog, turn it off here. On newer devices,
* the status of the watchdog (on/off, period) is PRESERVED OVER RESET!
*/
DBG1(0x00, 0, 0); /* debug output: main starts */
/* RESET status: all port bits are inputs without pull-up.
* That's the way we need D+ and D-. Therefore we don't need any
* additional hardware initialization.
*/
odDebugInit();
usbInit();
usbDeviceDisconnect(); /* enforce re-enumeration, do this while interrupts are disabled! */
i = 0;
while(--i){ /* fake USB disconnect for > 250 ms */
wdt_reset();
_delay_ms(1);
}
usbDeviceConnect();
timerinit();
sei();
DBG1(0x01, 0, 0); /* debug output: main loop starts */
for(;;){ /* main event loop */
DBG1(0x02, 0, 0); /* debug output: main loop iterates */
wdt_reset();
usbPoll();
if(usbInterruptIsReady()){
/* called after every poll of the interrupt endpoint */
calc();
moveMouse();
//DBG1(0x03, 0, 0); /* debug output: interrupt report prepared */
usbSetInterrupt((void *)&reportBuffer, sizeof(reportBuffer));
}

}
return 0;
}

/* ------------------------------------------------------------------------- */

annie

Re: HID mouse touchscreen

Post by annie » Fri Apr 19, 2013 9:07 am

I want to make your project
will you please give me the hardware setup for this..
the c file which you have posted over here is perfect for this project..?

Post Reply