Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * Project: AVR ATtiny USB Tutorial at http://codeandlife.com/
- * Author: Joonas Pihlajamaa, joonas.pihlajamaa@iki.fi
- * Based on V-USB example code by Christian Starkjohann
- * Copyright: (C) 2012 by Joonas Pihlajamaa
- * License: GNU GPL v3 (see License.txt)
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- // this is libusb, see http://libusb.sourceforge.net/
- #include <usb.h>
- // same as in main.c
- #define USB_LED_OFF 0
- #define USB_LED_ON 1
- #define USB_DATA_OUT 2
- #define USB_DATA_WRITE 3
- #define USB_DATA_IN 4
- // used to get descriptor strings for device identification
- static int usbGetDescriptorString(usb_dev_handle *dev, int index, int langid,
- char *buf, int buflen) {
- char buffer[256];
- int rval, i;
- // make standard request GET_DESCRIPTOR, type string and given index
- // (e.g. dev->iProduct)
- rval = usb_control_msg(dev,
- USB_TYPE_STANDARD | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
- USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8) + index, langid,
- buffer, sizeof(buffer), 1000);
- if(rval < 0) // error
- return rval;
- // rval should be bytes read, but buffer[0] contains the actual response size
- if((unsigned char)buffer[0] < rval)
- rval = (unsigned char)buffer[0]; // string is shorter than bytes read
- if(buffer[1] != USB_DT_STRING) // second byte is the data type
- return 0; // invalid return type
- // we're dealing with UTF-16LE here so actual chars is half of rval,
- // and index 0 doesn't count
- rval /= 2;
- // lossy conversion to ISO Latin1
- for(i = 1; i < rval && i < buflen; i++) {
- if(buffer[2 * i + 1] == 0)
- buf[i-1] = buffer[2 * i];
- else
- buf[i-1] = '?'; // outside of ISO Latin1 range
- }
- buf[i-1] = 0;
- return i-1;
- }
- static usb_dev_handle * usbOpenDevice(int vendor, char *vendorName,
- int product, char *productName) {
- struct usb_bus *bus;
- struct usb_device *dev;
- char devVendor[256], devProduct[256];
- usb_dev_handle * handle = NULL;
- usb_init();
- usb_find_busses();
- usb_find_devices();
- for(bus=usb_get_busses(); bus; bus=bus->next) {
- for(dev=bus->devices; dev; dev=dev->next) {
- if(dev->descriptor.idVendor != vendor ||
- dev->descriptor.idProduct != product)
- continue;
- // we need to open the device in order to query strings
- if(!(handle = usb_open(dev))) {
- fprintf(stderr, "Warning: cannot open USB device: %sn",
- usb_strerror());
- continue;
- }
- // get vendor name
- if(usbGetDescriptorString(handle, dev->descriptor.iManufacturer, 0x0409, devVendor, sizeof(devVendor)) < 0) {
- fprintf(stderr,
- "Warning: cannot query manufacturer for device: %sn",
- usb_strerror());
- usb_close(handle);
- continue;
- }
- // get product name
- if(usbGetDescriptorString(handle, dev->descriptor.iProduct,
- 0x0409, devProduct, sizeof(devVendor)) < 0) {
- fprintf(stderr,
- "Warning: cannot query product for device: %sn",
- usb_strerror());
- usb_close(handle);
- continue;
- }
- if(strcmp(devVendor, vendorName) == 0 &&
- strcmp(devProduct, productName) == 0)
- return handle;
- else
- usb_close(handle);
- }
- }
- return NULL;
- }
- int main(int argc, char **argv) {
- usb_dev_handle *handle = NULL;
- int nBytes = 0;
- char buffer[256];
- if(argc < 2) {
- printf("Usage:n");
- printf("usbtext.exe onn");
- printf("usbtext.exe offn");
- printf("usbtext.exe outn");
- printf("usbtext.exe writen");
- printf("usbtext.exe in <string>n");
- exit(1);
- }
- handle = usbOpenDevice(0x16C0, "gholzam", 0x05DC, "USBexample");
- if(handle == NULL) {
- fprintf(stderr, "Could not find USB device!n");
- exit(1);
- }
- if(strcmp(argv[1], "on") == 0) {
- nBytes = usb_control_msg(handle,
- USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
- USB_LED_ON, 0, 0, (char *)buffer, sizeof(buffer), 5000);
- } else if(strcmp(argv[1], "off") == 0) {
- nBytes = usb_control_msg(handle,
- USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
- USB_LED_OFF, 0, 0, (char *)buffer, sizeof(buffer), 5000);
- } else if(strcmp(argv[1], "out") == 0) {
- nBytes = usb_control_msg(handle,
- USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
- USB_DATA_OUT, 0, 0, (char *)buffer, sizeof(buffer), 5000);
- printf("Got %d bytes: %sn", nBytes, buffer);
- } else if(strcmp(argv[1], "write") == 0) {
- nBytes = usb_control_msg(handle,
- USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
- USB_DATA_WRITE, 'T' + ('E' << 8), 'S' + ('T' << 8),
- (char *)buffer, sizeof(buffer), 5000);
- } else if(strcmp(argv[1], "in") == 0 && argc > 2) {
- nBytes = usb_control_msg(handle,
- USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT,
- USB_DATA_IN, 0, 0, argv[2], strlen(argv[2])+1, 5000);
- }
- if(nBytes < 0)
- fprintf(stderr, "USB error: %sn", usb_strerror());
- usb_close(handle);
- return 0;
- }
- CC= gcc
- CFLAGS= -O -Wall $(USBFLAGS)
- LIBS= $(USBLIBS)
- OBJ= usbtest.o
- PROGRAM= usbtest$(EXE_SUFFIX)
- all: $(PROGRAM)
- $(PROGRAM): $(OBJ)
- $(CC) -o $(PROGRAM) $(OBJ) $(LIBS)
- strip: $(PROGRAM)
- strip $(PROGRAM)
- clean:
- rm -f $(OBJ) $(PROGRAM)
- .c.o:
- $(CC) $(ARCH_COMPILE) $(CFLAGS) -c $*.c -o $*.o
- /**
- * Project: AVR ATtiny USB Tutorial at http://codeandlife.com/
- * Author: Joonas Pihlajamaa, joonas.pihlajamaa@iki.fi
- * Inspired by V-USB example code by Christian Starkjohann
- * Copyright: (C) 2012 by Joonas Pihlajamaa
- * License: GNU GPL v3 (see License.txt)
- */
- #include <avr/io.h>
- #include <avr/interrupt.h>
- #include <avr/wdt.h>
- #include "usbdrv.h"
- #define F_CPU 12000000L
- #include <util/delay.h>
- #define USB_LED_OFF 0
- #define USB_LED_ON 1
- #define USB_DATA_OUT 2
- #define USB_DATA_WRITE 3
- #define USB_DATA_IN 4
- static uchar replyBuf[16] = "Hello, USB!";
- static uchar dataReceived = 0, dataLength = 0; // for USB_DATA_IN
- // this gets called when custom control message is received
- USB_PUBLIC uchar usbFunctionSetup(uchar data[8]) {
- usbRequest_t *rq = (void *)data; // cast data to correct type
- switch(rq->bRequest) { // custom command is in the bRequest field
- case USB_LED_ON:
- PORTB |= 1; // turn LED on
- return 0;
- case USB_LED_OFF:
- PORTB &= ~1; // turn LED off
- return 0;
- case USB_DATA_OUT: // send data to PC
- usbMsgPtr = replyBuf;
- return sizeof(replyBuf);
- case USB_DATA_WRITE: // modify reply buffer
- replyBuf[7] = rq->wValue.bytes[0];
- replyBuf[8] = rq->wValue.bytes[1];
- replyBuf[9] = rq->wIndex.bytes[0];
- replyBuf[10] = rq->wIndex.bytes[1];
- return 0;
- case USB_DATA_IN: // receive data from PC
- dataLength = (uchar)rq->wLength.word;
- dataReceived = 0;
- if(dataLength > sizeof(replyBuf)) // limit to buffer size
- dataLength = sizeof(replyBuf);
- return USB_NO_MSG; // usbFunctionWrite will be called now
- }
- return 0; // should not get here
- }
- // This gets called when data is sent from PC to the device
- USB_PUBLIC uchar usbFunctionWrite(uchar *data, uchar len) {
- uchar i;
- for(i = 0; dataReceived < dataLength && i < len; i++, dataReceived++)
- replyBuf[dataReceived] = data[i];
- return (dataReceived == dataLength); // 1 if we received it all, 0 if not
- }
- int main() {
- uchar i;
- DDRB = 1; // PB0 as output
- wdt_enable(WDTO_1S); // enable 1s watchdog timer
- usbInit();
- usbDeviceDisconnect(); // enforce re-enumeration
- for(i = 0; i<250; i++) { // wait 500 ms
- wdt_reset(); // keep the watchdog happy
- _delay_ms(2);
- }
- usbDeviceConnect();
- sei(); // Enable interrupts after re-enumeration
- while(1) {
- wdt_reset(); // keep the watchdog happy
- usbPoll();
- }
- return 0;
- }
- # Name: Makefile
- # Project: hid-mouse example
- # Author: Christian Starkjohann
- # Creation Date: 2008-04-07
- # Tabsize: 4
- # Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
- # License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
- DEVICE = atmega8
- FUSE_L = # see below for fuse values for particular devices
- FUSE_H =
- AVRDUDE = avrdude -p m8 -P /dev/parport0 -c dapa -v# edit this line for your programmer
- CFLAGS = -Iusbdrv -I. -DDEBUG_LEVEL=0
- OBJECTS = usbdrv/usbdrv.o usbdrv/usbdrvasm.o usbdrv/oddebug.o main.o
- COMPILE = avr-gcc -Wall -Os $(CFLAGS) -mmcu=$(DEVICE)
- # symbolic targets:
- help:
- @echo "This Makefile has no default rule. Use one of the following:"
- @echo "make hex ....... to build main.hex"
- @echo "make program ... to flash fuses and firmware"
- @echo "make fuse ...... to flash the fuses"
- @echo "make flash ..... to flash the firmware (use this on metaboard)"
- @echo "make clean ..... to delete objects and hex file"
- hex: main.hex
- program: flash fuse
- # rule for programming fuse bits:
- fuse:
- @[ "$(FUSE_H)" != "" -a "$(FUSE_L)" != "" ] ||
- { echo "*** Edit Makefile and choose values for FUSE_L and FUSE_H!"; exit 1; }
- $(AVRDUDE) -U hfuse:w:$(FUSE_H):m -U lfuse:w:$(FUSE_L):m
- # rule for uploading firmware:
- flash: main.hex
- $(AVRDUDE) -U flash:w:main.hex:i
- # rule for deleting dependent files (those which can be built by Make):
- clean:
- 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
- # Generic rule for compiling C files:
- .c.o:
- $(COMPILE) -c $< -o $@
- # Generic rule for assembling Assembler source files:
- .S.o:
- $(COMPILE) -x assembler-with-cpp -c $< -o $@
- # "-x assembler-with-cpp" should not be necessary since this is the default
- # file type for the .S (with capital S) extension. However, upper case
- # characters are not always preserved on Windows. To ensure WinAVR
- # compatibility define the file type manually.
- # Generic rule for compiling C to assembler, used for debugging only.
- .c.s:
- $(COMPILE) -S $< -o $@
- # file targets:
- main.elf: usbdrv $(OBJECTS) # usbdrv dependency only needed because we copy it
- $(COMPILE) -o main.elf $(OBJECTS)
- main.hex: main.elf
- rm -f main.hex main.eep.hex
- avr-objcopy -j .text -j .data -O ihex main.elf main.hex
- avr-size main.hex
- # debugging targets:
- disasm: main.elf
- avr-objdump -d main.elf
- cpp:
- $(COMPILE) -E main.c
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement