/******************************************************************************!
* \file firmware.c
* \author Sebastien Beaugrand
* \sa http://beaugrand.chez.com/
* \copyright GNU GPLv2 or GNU GPLv3, or proprietary
* \note Modified from :
* http://yveslebrac.blogspot.com/2008/10/cheapest-dual-trace-scope-in-galaxy.html
* http://www.reality.be/files/firmwarev3.zip
* Based on :
* https://github.com/obdev/v-usb
******************************************************************************/
/* Project: Data input based on AVR USB driver with TINY45
* V3: 2 inputs ADC2/PB4 ADC3/PB3, pas de switch, led sur PB1 (on=0)
* Author: Jacques Lepot
* Creation Date: 2008-04-19
* Copyright: (c) 2008 by Jacques Lepot
* License: Proprietary, free under certain conditions.
*/
#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/eeprom.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include "usbdrv.h"
#include "wiring.h"
uchar reportBuffer[5]; // buffer for HID reports, type game cntrler
uchar idleRate; // in 4 ms units
static uchar adchanel;
static int adcval1;
static int adcval2;
PROGMEM const const char usbHidReportDescriptor[
USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH] = { /* USB report descriptor */
0x05, 0x01, // USAGE_PAGE (Generic Desktop = 01)
0x09, 0x05, // USAGE (Game Pad = 05)
0xa1, 0x01, // COLLECTION (Application)
0x09, 0x01, // USAGE (Pointer)
0xa1, 0x00, // COLLECTION (Physical)
0x09, 0x30, // USAGE (X)
0x09, 0x31, // USAGE (Y)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
0x75, 0x08, // REPORT_SIZE (8bits)
0x95, 0x04, // REPORT_COUNT (2)
0x81, 0x02, // INPUT (Data,Var,Abs)
0xc0, // END_COLLECTION
0x05, 0x09, // USAGE_PAGE (Button)
0x19, 0x01, // USAGE_MINIMUM (Button 1)
0x29, 0x08, // USAGE_MAXIMUM (Button 8)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x01, // REPORT_SIZE (1bit)
0x95, 0x08, // REPORT_COUNT (8)
0x81, 0x02, // INPUT (Data,Var,Abs)
0xc0 // END_COLLECTION
};
/******************************************************************************!
* \fn buildReport
******************************************************************************/
void buildReport()
{
reportBuffer[0] = adcval1 >> 8;
reportBuffer[1] = adcval1;
reportBuffer[2] = adcval2 >> 8;
reportBuffer[3] = adcval2;
reportBuffer[4] = 0x01;
}
/******************************************************************************!
* \fn adcPoll
******************************************************************************/
static void adcPoll()
{
int adc;
if (adchanel) {
adc = analogRead(PINB4);
} else {
adc = analogRead(PINB3);
}
if (adc != -1) {
if (adchanel) {
adcval1 = adc + adc + (adc >> 1); // adc * 2.5 for output in mV
} else {
adcval2 = adc + adc + (adc >> 1); // adc * 2.5 for output in mV
}
adchanel = ! adchanel;
}
}
/******************************************************************************!
* \fn usbEventResetReady
******************************************************************************/
void usbEventResetReady()
{
calibrateOscillator();
eeprom_write_byte(0, OSCCAL); // store the calibrated value in EEPROM
}
/******************************************************************************!
* \fn setup
******************************************************************************/
void setup()
{
uchar i;
uchar calibrationValue;
calibrationValue = eeprom_read_byte(0); // calibration value from last time
if (calibrationValue != 0xff) {
OSCCAL = calibrationValue;
}
usbDeviceDisconnect();
for (i = 0; i < 20; i++) { // 300 ms disconnect
_delay_ms(15);
}
usbDeviceConnect();
digitalInit(PINB1, OUTPUT);
wdt_enable(WDTO_1S);
analogInit();
usbInit();
sei();
digitalWrite(PINB1, 0);
}
/******************************************************************************!
* \fn loop
******************************************************************************/
void loop()
{
wdt_reset();
usbPoll();
if (usbInterruptIsReady()) {
buildReport();
usbSetInterrupt(reportBuffer, sizeof(reportBuffer));
}
adcPoll();
}
/******************************************************************************!
* \fn main
******************************************************************************/
int main()
{
setup();
for (;;) {
loop();
}
return 0;
}