aboutsummaryrefslogtreecommitdiffstats
path: root/examples/custom-class/firmware/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'examples/custom-class/firmware/main.c')
-rw-r--r--examples/custom-class/firmware/main.c91
1 files changed, 91 insertions, 0 deletions
diff --git a/examples/custom-class/firmware/main.c b/examples/custom-class/firmware/main.c
new file mode 100644
index 0000000..2d93db9
--- /dev/null
+++ b/examples/custom-class/firmware/main.c
@@ -0,0 +1,91 @@
+/* Name: main.c
+ * Project: custom-class, a basic USB example
+ * Author: Christian Starkjohann
+ * Creation Date: 2008-04-09
+ * Tabsize: 4
+ * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
+ * License: GNU GPL v2 (see License.txt) or proprietary (CommercialLicense.txt)
+ * This Revision: $Id$
+ */
+
+/*
+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 assume that an LED is connected to port B bit 0. If you connect it to a
+different port or bit, change the macros below:
+*/
+#define LED_PORT_DDR DDRB
+#define LED_PORT_OUTPUT PORTB
+#define LED_BIT 0
+
+#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 */
+#include "requests.h" /* The custom request numbers we use */
+
+/* ------------------------------------------------------------------------- */
+/* ----------------------------- USB interface ----------------------------- */
+/* ------------------------------------------------------------------------- */
+
+uchar usbFunctionSetup(uchar data[8])
+{
+usbRequest_t *rq = (void *)data;
+
+ if(rq->bRequest == CUSTOM_RQ_SET_STATUS){
+ if(rq->wValue.bytes[0] & 1){ /* set LED */
+ LED_PORT_OUTPUT |= _BV(LED_BIT);
+ }else{ /* clear LED */
+ LED_PORT_OUTPUT &= ~_BV(LED_BIT);
+ }
+ }else if(rq->bRequest == CUSTOM_RQ_GET_STATUS){
+ static uchar dataBuffer[1]; /* buffer must stay valid when usbFunctionSetup returns */
+ dataBuffer[0] = ((LED_PORT_OUTPUT & _BV(LED_BIT)) != 0);
+ usbMsgPtr = dataBuffer; /* tell the driver which data to return */
+ return 1; /* tell the driver to send 1 byte */
+ }
+ 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();
+ LED_PORT_DDR |= _BV(LED_BIT); /* make the LED bit an output */
+ 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();
+ }
+ return 0;
+}
+
+/* ------------------------------------------------------------------------- */