i am trying to make a USB-hid device with a atmega328p and i want to use multiple ADC channels.
i have looked at the examples on the main site of objective develpment, but i still can't get it to work propperly.
i have managed to get two channels to work but al other channels just have somekind of noise.
Here is the code.
Code: Select all
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include <avr/pgmspace.h>
#include <stdlib.h>
#define F_CPU 20000000L
#include <util/delay.h>
#include "usbdrv.h"
#include "oddebug.h"
const PROGMEM char usbHidReportDescriptor[77] = {
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x09, 0x04, // USAGE (Joystick)
0xa1, 0x01, // COLLECTION (Application)
0x05, 0x02, // USAGE_PAGE (Simulation Controls)
0x09, 0xbb, // USAGE (Throttle)
0x15, 0x81, // LOGICAL_MINIMUM (-127)
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x01, // REPORT_COUNT (1)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x01, // USAGE (Pointer)
0xa1, 0x00, // COLLECTION (Physical)
0x09, 0x30, // USAGE (X)
0x09, 0x31, // USAGE (Y)
0x95, 0x02, // REPORT_COUNT (2)
0x81, 0x02, // INPUT (Data,Var,Abs)
0xc0, // END_COLLECTION
0x09, 0x39, // USAGE (Hat switch)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x03, // LOGICAL_MAXIMUM (3)
0x35, 0x00, // PHYSICAL_MINIMUM (0)
0x46, 0x0e, 0x01, // PHYSICAL_MAXIMUM (270)
0x65, 0x14, // UNIT (Eng Rot:Angular Pos)
0x75, 0x04, // REPORT_SIZE (4)
0x95, 0x01, // REPORT_COUNT (1)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x05, 0x09, // USAGE_PAGE (Button)
0x19, 0x01, // USAGE_MINIMUM (Button 1)
0x29, 0x04, // USAGE_MAXIMUM (Button 4)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x04, // REPORT_COUNT (4)
0x55, 0x00, // UNIT_EXPONENT (0)
0x65, 0x00, // UNIT (None)
0x81, 0x02, // INPUT (Data,Var,Abs)
0xc0 // END_COLLECTION
};
typedef struct{
char throttle;
char x;
char y;
char buttons;
}report_t;
static report_t joystick_report;
static uchar idleRate;
usbMsgLen_t usbFunctionSetup(uint8_t data[8])
{
usbRequest_t *rq = (void *)data;
if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){ /* class request type */
if(rq->bRequest == USBRQ_HID_GET_REPORT){ /* wValue: ReportType (highbyte), ReportID (lowbyte) */
usbMsgPtr = (void *)&joystick_report;
return sizeof(joystick_report);
}
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 input(void)
{
//ADCSRA |= 1<<ADSC;
char pins = 0, pinInv;
pins = PINB;
pinInv = ~pins;
//int throttle = (ADCH + 128);
//uint8_t throttle = ;
//uint8_t x = ;
//uint8_t y = ;
//joystick_report.x = (x + 128);
//joystick_report.y = (y + 128);
joystick_report.buttons = pinInv << 2;
}
static void hardwareInit(void)
{
PORTB = 0xff; /* activate all pull-ups */
DDRB = 0; /* all pins input */
DDRC = 0; /* all pins input */
PORTD = 0xfa; /* 1111 1010 bin: activate pull-ups except on USB lines */
uchar i;
wdt_enable(WDTO_1S);
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();
}
int main(void)
{
hardwareInit();
usbInit();
sei();
for(;;)
{
wdt_reset();
usbPoll();
input();
if(usbInterruptIsReady()){
/* called after every poll of the interrupt endpoint */
usbSetInterrupt((void *)&joystick_report, sizeof(joystick_report));
}
}
}
ISR(ADC_vect) {
//confige ADC
//enable prescaler - determent by internal/ external clock 20,000,000/128
ADCSRA |= ((1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0));
//8-bit
ADMUX |= 1<<ADLAR;
//set voltage reference
ADMUX |= 1<<REFS0; //0110 0000 60
//Select input
//ADMUX |= ((0<<MUX3) | (1<<MUX2) | (0<<MUX1) | (1<<MUX0));
//enable interrupts function in ADC
//ADCSRA |= 1<<ADIE;
//enable global interrupts
sei();
//turn on the ADC features
ADCSRA |= 1<<ADEN;
//start the first conversion
ADCSRA |= 1<<ADSC;
ADCSRA |= 1<<ADSC;
//ADMUX |= ch;
// ADCSRA |= (1<<ADSC);
//while (!(ADCSRA & (1<<ADIF)));
// ADCSRA |= (1<<ADIF);
// return ADC;
}