Advertisement
Guest User

Untitled

a guest
Dec 19th, 2014
166
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.72 KB | None | 0 0
  1. /**
  2. * Project: AVR ATtiny USB Tutorial at http://codeandlife.com/
  3. * Author: Joonas Pihlajamaa, joonas.pihlajamaa@iki.fi
  4. * Based on V-USB example code by Christian Starkjohann
  5. * Copyright: (C) 2012 by Joonas Pihlajamaa
  6. * License: GNU GPL v3 (see License.txt)
  7. */
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11.  
  12. // this is libusb, see http://libusb.sourceforge.net/
  13. #include <usb.h>
  14.  
  15. // same as in main.c
  16. #define USB_LED_OFF 0
  17. #define USB_LED_ON 1
  18. #define USB_DATA_OUT 2
  19. #define USB_DATA_WRITE 3
  20. #define USB_DATA_IN 4
  21.  
  22. // used to get descriptor strings for device identification
  23. static int usbGetDescriptorString(usb_dev_handle *dev, int index, int langid,
  24. char *buf, int buflen) {
  25. char buffer[256];
  26. int rval, i;
  27.  
  28. // make standard request GET_DESCRIPTOR, type string and given index
  29. // (e.g. dev->iProduct)
  30. rval = usb_control_msg(dev,
  31. USB_TYPE_STANDARD | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
  32. USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8) + index, langid,
  33. buffer, sizeof(buffer), 1000);
  34.  
  35. if(rval < 0) // error
  36. return rval;
  37.  
  38. // rval should be bytes read, but buffer[0] contains the actual response size
  39. if((unsigned char)buffer[0] < rval)
  40. rval = (unsigned char)buffer[0]; // string is shorter than bytes read
  41.  
  42. if(buffer[1] != USB_DT_STRING) // second byte is the data type
  43. return 0; // invalid return type
  44.  
  45. // we're dealing with UTF-16LE here so actual chars is half of rval,
  46. // and index 0 doesn't count
  47. rval /= 2;
  48.  
  49. // lossy conversion to ISO Latin1
  50. for(i = 1; i < rval && i < buflen; i++) {
  51. if(buffer[2 * i + 1] == 0)
  52. buf[i-1] = buffer[2 * i];
  53. else
  54. buf[i-1] = '?'; // outside of ISO Latin1 range
  55. }
  56. buf[i-1] = 0;
  57.  
  58. return i-1;
  59. }
  60.  
  61. static usb_dev_handle * usbOpenDevice(int vendor, char *vendorName,
  62. int product, char *productName) {
  63. struct usb_bus *bus;
  64. struct usb_device *dev;
  65. char devVendor[256], devProduct[256];
  66.  
  67. usb_dev_handle * handle = NULL;
  68.  
  69. usb_init();
  70. usb_find_busses();
  71. usb_find_devices();
  72.  
  73. for(bus=usb_get_busses(); bus; bus=bus->next) {
  74. for(dev=bus->devices; dev; dev=dev->next) {
  75. if(dev->descriptor.idVendor != vendor ||
  76. dev->descriptor.idProduct != product)
  77. continue;
  78.  
  79. // we need to open the device in order to query strings
  80. if(!(handle = usb_open(dev))) {
  81. fprintf(stderr, "Warning: cannot open USB device: %sn",
  82. usb_strerror());
  83. continue;
  84. }
  85.  
  86. // get vendor name
  87. if(usbGetDescriptorString(handle, dev->descriptor.iManufacturer, 0x0409, devVendor, sizeof(devVendor)) < 0) {
  88. fprintf(stderr,
  89. "Warning: cannot query manufacturer for device: %sn",
  90. usb_strerror());
  91. usb_close(handle);
  92. continue;
  93. }
  94.  
  95. // get product name
  96. if(usbGetDescriptorString(handle, dev->descriptor.iProduct,
  97. 0x0409, devProduct, sizeof(devVendor)) < 0) {
  98. fprintf(stderr,
  99. "Warning: cannot query product for device: %sn",
  100. usb_strerror());
  101. usb_close(handle);
  102. continue;
  103. }
  104.  
  105. if(strcmp(devVendor, vendorName) == 0 &&
  106. strcmp(devProduct, productName) == 0)
  107. return handle;
  108. else
  109. usb_close(handle);
  110. }
  111. }
  112.  
  113. return NULL;
  114. }
  115.  
  116. int main(int argc, char **argv) {
  117. usb_dev_handle *handle = NULL;
  118. int nBytes = 0;
  119. char buffer[256];
  120.  
  121. if(argc < 2) {
  122. printf("Usage:n");
  123. printf("usbtext.exe onn");
  124. printf("usbtext.exe offn");
  125. printf("usbtext.exe outn");
  126. printf("usbtext.exe writen");
  127. printf("usbtext.exe in <string>n");
  128. exit(1);
  129. }
  130.  
  131. handle = usbOpenDevice(0x16C0, "gholzam", 0x05DC, "USBexample");
  132.  
  133. if(handle == NULL) {
  134. fprintf(stderr, "Could not find USB device!n");
  135. exit(1);
  136. }
  137.  
  138. if(strcmp(argv[1], "on") == 0) {
  139. nBytes = usb_control_msg(handle,
  140. USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
  141. USB_LED_ON, 0, 0, (char *)buffer, sizeof(buffer), 5000);
  142. } else if(strcmp(argv[1], "off") == 0) {
  143. nBytes = usb_control_msg(handle,
  144. USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
  145. USB_LED_OFF, 0, 0, (char *)buffer, sizeof(buffer), 5000);
  146. } else if(strcmp(argv[1], "out") == 0) {
  147. nBytes = usb_control_msg(handle,
  148. USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
  149. USB_DATA_OUT, 0, 0, (char *)buffer, sizeof(buffer), 5000);
  150. printf("Got %d bytes: %sn", nBytes, buffer);
  151. } else if(strcmp(argv[1], "write") == 0) {
  152. nBytes = usb_control_msg(handle,
  153. USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
  154. USB_DATA_WRITE, 'T' + ('E' << 8), 'S' + ('T' << 8),
  155. (char *)buffer, sizeof(buffer), 5000);
  156. } else if(strcmp(argv[1], "in") == 0 && argc > 2) {
  157. nBytes = usb_control_msg(handle,
  158. USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT,
  159. USB_DATA_IN, 0, 0, argv[2], strlen(argv[2])+1, 5000);
  160. }
  161.  
  162. if(nBytes < 0)
  163. fprintf(stderr, "USB error: %sn", usb_strerror());
  164.  
  165. usb_close(handle);
  166.  
  167. return 0;
  168. }
  169.  
  170. CC= gcc
  171. CFLAGS= -O -Wall $(USBFLAGS)
  172. LIBS= $(USBLIBS)
  173.  
  174. OBJ= usbtest.o
  175. PROGRAM= usbtest$(EXE_SUFFIX)
  176.  
  177. all: $(PROGRAM)
  178.  
  179. $(PROGRAM): $(OBJ)
  180. $(CC) -o $(PROGRAM) $(OBJ) $(LIBS)
  181.  
  182. strip: $(PROGRAM)
  183. strip $(PROGRAM)
  184.  
  185. clean:
  186. rm -f $(OBJ) $(PROGRAM)
  187.  
  188. .c.o:
  189. $(CC) $(ARCH_COMPILE) $(CFLAGS) -c $*.c -o $*.o
  190.  
  191. /**
  192. * Project: AVR ATtiny USB Tutorial at http://codeandlife.com/
  193. * Author: Joonas Pihlajamaa, joonas.pihlajamaa@iki.fi
  194. * Inspired by V-USB example code by Christian Starkjohann
  195. * Copyright: (C) 2012 by Joonas Pihlajamaa
  196. * License: GNU GPL v3 (see License.txt)
  197. */
  198. #include <avr/io.h>
  199. #include <avr/interrupt.h>
  200. #include <avr/wdt.h>
  201.  
  202. #include "usbdrv.h"
  203.  
  204. #define F_CPU 12000000L
  205. #include <util/delay.h>
  206.  
  207. #define USB_LED_OFF 0
  208. #define USB_LED_ON 1
  209. #define USB_DATA_OUT 2
  210. #define USB_DATA_WRITE 3
  211. #define USB_DATA_IN 4
  212.  
  213. static uchar replyBuf[16] = "Hello, USB!";
  214. static uchar dataReceived = 0, dataLength = 0; // for USB_DATA_IN
  215.  
  216. // this gets called when custom control message is received
  217. USB_PUBLIC uchar usbFunctionSetup(uchar data[8]) {
  218. usbRequest_t *rq = (void *)data; // cast data to correct type
  219.  
  220. switch(rq->bRequest) { // custom command is in the bRequest field
  221. case USB_LED_ON:
  222. PORTB |= 1; // turn LED on
  223. return 0;
  224. case USB_LED_OFF:
  225. PORTB &= ~1; // turn LED off
  226. return 0;
  227. case USB_DATA_OUT: // send data to PC
  228. usbMsgPtr = replyBuf;
  229. return sizeof(replyBuf);
  230. case USB_DATA_WRITE: // modify reply buffer
  231. replyBuf[7] = rq->wValue.bytes[0];
  232. replyBuf[8] = rq->wValue.bytes[1];
  233. replyBuf[9] = rq->wIndex.bytes[0];
  234. replyBuf[10] = rq->wIndex.bytes[1];
  235. return 0;
  236. case USB_DATA_IN: // receive data from PC
  237. dataLength = (uchar)rq->wLength.word;
  238. dataReceived = 0;
  239.  
  240. if(dataLength > sizeof(replyBuf)) // limit to buffer size
  241. dataLength = sizeof(replyBuf);
  242.  
  243. return USB_NO_MSG; // usbFunctionWrite will be called now
  244. }
  245.  
  246. return 0; // should not get here
  247. }
  248.  
  249. // This gets called when data is sent from PC to the device
  250. USB_PUBLIC uchar usbFunctionWrite(uchar *data, uchar len) {
  251. uchar i;
  252.  
  253. for(i = 0; dataReceived < dataLength && i < len; i++, dataReceived++)
  254. replyBuf[dataReceived] = data[i];
  255.  
  256. return (dataReceived == dataLength); // 1 if we received it all, 0 if not
  257. }
  258.  
  259. int main() {
  260. uchar i;
  261.  
  262. DDRB = 1; // PB0 as output
  263.  
  264. wdt_enable(WDTO_1S); // enable 1s watchdog timer
  265.  
  266. usbInit();
  267.  
  268. usbDeviceDisconnect(); // enforce re-enumeration
  269. for(i = 0; i<250; i++) { // wait 500 ms
  270. wdt_reset(); // keep the watchdog happy
  271. _delay_ms(2);
  272. }
  273. usbDeviceConnect();
  274.  
  275. sei(); // Enable interrupts after re-enumeration
  276.  
  277. while(1) {
  278. wdt_reset(); // keep the watchdog happy
  279. usbPoll();
  280. }
  281.  
  282. return 0;
  283. }
  284.  
  285. # Name: Makefile
  286. # Project: hid-mouse example
  287. # Author: Christian Starkjohann
  288. # Creation Date: 2008-04-07
  289. # Tabsize: 4
  290. # Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
  291. # License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
  292.  
  293. DEVICE = atmega8
  294.  
  295. FUSE_L = # see below for fuse values for particular devices
  296. FUSE_H =
  297. AVRDUDE = avrdude -p m8 -P /dev/parport0 -c dapa -v# edit this line for your programmer
  298.  
  299. CFLAGS = -Iusbdrv -I. -DDEBUG_LEVEL=0
  300. OBJECTS = usbdrv/usbdrv.o usbdrv/usbdrvasm.o usbdrv/oddebug.o main.o
  301.  
  302. COMPILE = avr-gcc -Wall -Os $(CFLAGS) -mmcu=$(DEVICE)
  303.  
  304. # symbolic targets:
  305. help:
  306. @echo "This Makefile has no default rule. Use one of the following:"
  307. @echo "make hex ....... to build main.hex"
  308. @echo "make program ... to flash fuses and firmware"
  309. @echo "make fuse ...... to flash the fuses"
  310. @echo "make flash ..... to flash the firmware (use this on metaboard)"
  311. @echo "make clean ..... to delete objects and hex file"
  312.  
  313. hex: main.hex
  314.  
  315. program: flash fuse
  316.  
  317. # rule for programming fuse bits:
  318. fuse:
  319. @[ "$(FUSE_H)" != "" -a "$(FUSE_L)" != "" ] ||
  320. { echo "*** Edit Makefile and choose values for FUSE_L and FUSE_H!"; exit 1; }
  321. $(AVRDUDE) -U hfuse:w:$(FUSE_H):m -U lfuse:w:$(FUSE_L):m
  322.  
  323. # rule for uploading firmware:
  324. flash: main.hex
  325. $(AVRDUDE) -U flash:w:main.hex:i
  326.  
  327. # rule for deleting dependent files (those which can be built by Make):
  328. clean:
  329. rm -f main.hex main.lst main.obj main.cof main.list main.map main.eep.hex main.elf *.o usbdrv/*.o main.s usbdrv/oddebug.s usbdrv/usbdrv.s
  330.  
  331. # Generic rule for compiling C files:
  332. .c.o:
  333. $(COMPILE) -c $< -o $@
  334.  
  335. # Generic rule for assembling Assembler source files:
  336. .S.o:
  337. $(COMPILE) -x assembler-with-cpp -c $< -o $@
  338. # "-x assembler-with-cpp" should not be necessary since this is the default
  339. # file type for the .S (with capital S) extension. However, upper case
  340. # characters are not always preserved on Windows. To ensure WinAVR
  341. # compatibility define the file type manually.
  342.  
  343. # Generic rule for compiling C to assembler, used for debugging only.
  344. .c.s:
  345. $(COMPILE) -S $< -o $@
  346.  
  347. # file targets:
  348.  
  349. main.elf: usbdrv $(OBJECTS) # usbdrv dependency only needed because we copy it
  350. $(COMPILE) -o main.elf $(OBJECTS)
  351.  
  352. main.hex: main.elf
  353. rm -f main.hex main.eep.hex
  354. avr-objcopy -j .text -j .data -O ihex main.elf main.hex
  355. avr-size main.hex
  356.  
  357. # debugging targets:
  358.  
  359. disasm: main.elf
  360. avr-objdump -d main.elf
  361.  
  362. cpp:
  363. $(COMPILE) -E main.c
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement