main.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. /* Name: main.c
  2. * Project: hid-data, example how to use HID for data transfer
  3. * Author: Christian Starkjohann
  4. * Creation Date: 2008-04-11
  5. * Tabsize: 4
  6. * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
  7. * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
  8. * This Revision: $Id: main.c 692 2008-11-07 15:07:40Z cs $
  9. */
  10. /*
  11. This example should run on most AVRs with only little changes. No special
  12. hardware resources except INT0 are used. You may have to change usbconfig.h for
  13. different I/O pins for USB. Please note that USB D+ must be the INT0 pin, or
  14. at least be connected to INT0 as well.
  15. */
  16. #include <avr/io.h>
  17. #include <avr/wdt.h>
  18. #include <avr/interrupt.h> /* for sei() */
  19. #include <util/delay.h> /* for _delay_ms() */
  20. #include <avr/eeprom.h>
  21. #include <avr/pgmspace.h> /* required by usbdrv.h */
  22. #include "usbdrv.h"
  23. #include "oddebug.h" /* This is also an example for using debug macros */
  24. /* ------------------------------------------------------------------------- */
  25. /* ----------------------------- USB interface ----------------------------- */
  26. /* ------------------------------------------------------------------------- */
  27. PROGMEM char usbHidReportDescriptor[22] = { /* USB report descriptor */
  28. 0x06, 0x00, 0xff, // USAGE_PAGE (Generic Desktop)
  29. 0x09, 0x01, // USAGE (Vendor Usage 1)
  30. 0xa1, 0x01, // COLLECTION (Application)
  31. 0x15, 0x00, // LOGICAL_MINIMUM (0)
  32. 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
  33. 0x75, 0x08, // REPORT_SIZE (8)
  34. 0x95, 0x80, // REPORT_COUNT (128)
  35. 0x09, 0x00, // USAGE (Undefined)
  36. 0xb2, 0x02, 0x01, // FEATURE (Data,Var,Abs,Buf)
  37. 0xc0 // END_COLLECTION
  38. };
  39. /* Since we define only one feature report, we don't use report-IDs (which
  40. * would be the first byte of the report). The entire report consists of 128
  41. * opaque data bytes.
  42. */
  43. /* The following variables store the status of the current data transfer */
  44. static uchar currentAddress;
  45. static uchar bytesRemaining;
  46. /* ------------------------------------------------------------------------- */
  47. /* usbFunctionRead() is called when the host requests a chunk of data from
  48. * the device. For more information see the documentation in usbdrv/usbdrv.h.
  49. */
  50. uchar usbFunctionRead(uchar *data, uchar len)
  51. {
  52. if(len > bytesRemaining)
  53. len = bytesRemaining;
  54. eeprom_read_block(data, (uchar *)0 + currentAddress, len);
  55. currentAddress += len;
  56. bytesRemaining -= len;
  57. return len;
  58. }
  59. /* usbFunctionWrite() is called when the host sends a chunk of data to the
  60. * device. For more information see the documentation in usbdrv/usbdrv.h.
  61. */
  62. uchar usbFunctionWrite(uchar *data, uchar len)
  63. {
  64. if(bytesRemaining == 0)
  65. return 1; /* end of transfer */
  66. if(len > bytesRemaining)
  67. len = bytesRemaining;
  68. eeprom_write_block(data, (uchar *)0 + currentAddress, len);
  69. currentAddress += len;
  70. bytesRemaining -= len;
  71. return bytesRemaining == 0; /* return 1 if this was the last chunk */
  72. }
  73. /* ------------------------------------------------------------------------- */
  74. usbMsgLen_t usbFunctionSetup(uchar data[8])
  75. {
  76. usbRequest_t *rq = (void *)data;
  77. if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){ /* HID class request */
  78. if(rq->bRequest == USBRQ_HID_GET_REPORT){ /* wValue: ReportType (highbyte), ReportID (lowbyte) */
  79. /* since we have only one report type, we can ignore the report-ID */
  80. bytesRemaining = 128;
  81. currentAddress = 0;
  82. return USB_NO_MSG; /* use usbFunctionRead() to obtain data */
  83. }else if(rq->bRequest == USBRQ_HID_SET_REPORT){
  84. /* since we have only one report type, we can ignore the report-ID */
  85. bytesRemaining = 128;
  86. currentAddress = 0;
  87. return USB_NO_MSG; /* use usbFunctionWrite() to receive data from host */
  88. }
  89. }else{
  90. /* ignore vendor type requests, we don't use any */
  91. }
  92. return 0;
  93. }
  94. /* ------------------------------------------------------------------------- */
  95. int main(void)
  96. {
  97. uchar i;
  98. wdt_enable(WDTO_1S);
  99. /* Even if you don't use the watchdog, turn it off here. On newer devices,
  100. * the status of the watchdog (on/off, period) is PRESERVED OVER RESET!
  101. */
  102. DBG1(0x00, 0, 0); /* debug output: main starts */
  103. /* RESET status: all port bits are inputs without pull-up.
  104. * That's the way we need D+ and D-. Therefore we don't need any
  105. * additional hardware initialization.
  106. */
  107. odDebugInit();
  108. usbInit();
  109. usbDeviceDisconnect(); /* enforce re-enumeration, do this while interrupts are disabled! */
  110. i = 0;
  111. while(--i){ /* fake USB disconnect for > 250 ms */
  112. wdt_reset();
  113. _delay_ms(1);
  114. }
  115. usbDeviceConnect();
  116. sei();
  117. DBG1(0x01, 0, 0); /* debug output: main loop starts */
  118. for(;;){ /* main event loop */
  119. DBG1(0x02, 0, 0); /* debug output: main loop iterates */
  120. wdt_reset();
  121. usbPoll();
  122. }
  123. return 0;
  124. }
  125. /* ------------------------------------------------------------------------- */