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;
  } 
