coder44
25.04.2013, 14:28
Hallo leute,
ich habe ein Projekt gebaut mit einem ATmega168. LCD und USB und ein paar Taster u. RGB-LEDS sind vorhanden.
Nun will ich das Device per USB mit meinem PC verbinden. Soweit klappt auch alles wunderbar.
Ich habe beispielsweise in BASCOM alles zu laufen bekommen. Ich kann Daten vom Device lesen und auch Daten vom PC auf das Device senden.
Auf der PC Seite verwende ich LibUSBDotNet mit dem libusb Treiber. Mit der mitgelieferten Software "Test_Bulk" teste ich immer das senden und empfangen.
Nun wollte ich das Projekt umschreiben und in C zum laufen bekommen. Bisher klappt auch fast alles. Device wird vom PC erkannt, kann auch die Daten
mit dem PC vom Device lesen ABER ich kann keine Daten vom PC an das Device schicken. Dann erhalte ich immer die Fehlermeldung:
Win32Error:PipeTransferSubmit Ep 0x02
87:Falscher Parameter.
Hier mal mein Code...
#define F_CPU 12000000UL
#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/interrupt.h> /* for sei() */
#include <util/delay.h> /* for _delay_ms() */
#include <avr/eeprom.h>
#include <avr/pgmspace.h> /* required by usbdrv.h */
#include "usbdrv/usbdrv.h"
#include "usbdrv/oddebug.h" /* This is also an example for using debug macros */
#include "lcd-routines.h"
#define farbe PORTB
#define rot 4
#define gruen 5
#define blau 3
#define SETBIT(ADDRESS,BIT) (ADDRESS |= (1<<BIT))
#define CLEARBIT(ADDRESS,BIT) (ADDRESS &= ~(1<<BIT))
#define FLIPBIT(ADDRESS,BIT) (ADDRESS ^= (1<<BIT))
#define CHECKBIT(ADDRESS,BIT) (ADDRESS & (1<<BIT))
#define WRITEBIT(RADDRESS,RBIT,WADDRESS,WBIT) (CHECKBIT(RADDRESS,RBIT) ? SETBIT(WADDRESS,WBIT) : CLEARBIT(WADDRESS,WBIT))
/* ------------------------------------------------------------------------- */
/* ----------------------------- USB interface ----------------------------- */
/* ------------------------------------------------------------------------- */
PROGMEM const char usbHidReportDescriptor[] = { /* USB report descriptor */
0x06, 0x00, 0xff, // USAGE_PAGE (Generic Desktop)
0x09, 0x01, // USAGE (Vendor Usage 1)
0xa1, 0x02, // COLLECTION (Application)
// Input Report
0x09, 0x01, // Usage ID - vendor defined
0x15, 0x00, // Logical Minimum (0)
0x25, 0xFF, // Logical Maximum (255)
0x75, 0x08, // Report Size (8 bits)
0x95, 0x01, // Report Count (8 fields)
0x81, 0x02, // Input (Data, Variable, Absolute)
// Output report
0x09, 0x01, // Usage ID - vendor defined
0x15, 0x00, // Logical Minimum (0)
0x26, 0xFF, 0x00, // Logical Maximum (255)
0x75, 0x08, // Report Size (8 bits)
0x95, 0x01, // Report Count (8 fields)
0x91, 0x02, // Output (Data, Variable, Absolute)
0xc0 // END_COLLECTION
};
/* The following variables store the status of the current data transfer */
static uchar currentAddress;
static uchar bytesRemaining;
static uchar inbuf[8], outbuf[8], outlen;
/* ------------------------------------------------------------------------- */
/* usbFunctionRead() is called when the host requests a chunk of data from
* the device. For more information see the documentation in usbdrv/usbdrv.h.
*/
uchar usbFunctionRead(uchar *data, uchar len)
{
lcd_clear();
lcd_string("func read");
an(blau, 3);
if(len > bytesRemaining)
len = bytesRemaining;
eeprom_read_block(data, (uchar *)0 + currentAddress, len);
currentAddress += len;
bytesRemaining -= len;
return len;
}
/* usbFunctionWrite() is called when the host sends a chunk of data to the
* device. For more information see the documentation in usbdrv/usbdrv.h.
*/
uchar usbFunctionWrite(uchar *data, uchar len)
{
lcd_clear();
lcd_string("func write");
an(blau, 2);
if(bytesRemaining == 0)
return 1; /* end of transfer */
if(len > bytesRemaining)
len = bytesRemaining;
eeprom_write_block(data, (uchar *)0 + currentAddress, len);
lcd_clear();
lcd_string(data);
an(rot, 1);
currentAddress += len;
bytesRemaining -= len;
return bytesRemaining == 0; /* return 1 if this was the last chunk */
}
/* ------------------------------------------------------------------------- */
usbMsgLen_t usbFunctionSetup(uchar data[8])
{
lcd_clear();
lcd_string("func setup");
an(rot, 1);
usbRequest_t *rq = (void *)data;
lcd_clear();
lcd_string(rq->bRequest);
}
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
void an(int col, int led)
{
SETBIT(PORTC, led);
SETBIT(PORTB, col);
_delay_ms(90);
CLEARBIT(PORTC, led);
CLEARBIT(PORTB, col);
}
int main(void)
{
DDRC = 0xff;
lcd_init();
SETBIT(DDRB, PB3);
CLEARBIT(DDRB, PB0);
lcd_string("System ready...");
uchar i;
wdt_enable(WDTO_1S);
odDebugInit();
DBG1(0x00, 0, 0);
usbInit();
an(blau, 1);
usbDeviceDisconnect();
i = 0;
while(--i){ /* fake USB disconnect for > 250 ms */
wdt_reset();
_delay_ms(1);
}
usbDeviceConnect();
sei();
DBG1(0x01, 0, 0);
for(;;){ /* main event loop */
DBG1(0x02, 0, 0);
wdt_reset();
usbPoll();
if(usbInterruptIsReady())
{
SETBIT(PORTC, 5);
SETBIT(PORTB, gruen);
inbuf[0] = 'a';
inbuf[1] = 'b';
inbuf[2] = 'c';
inbuf[3] = '\n';
usbSetInterrupt(inbuf, sizeof(inbuf)); //damit lese ich am PC "abc" aus
}
else
{
CLEARBIT(PORTC, 5);
CLEARBIT(PORTB, gruen);
}
}
return 0;
}
In meiner usbconfig.h ist folgends eingestellt:
#define USB_CFG_IOPORTNAME D
#define USB_CFG_DMINUS_BIT 3
#define USB_CFG_DPLUS_BIT 2
#define USB_CFG_CLOCK_KHZ (F_CPU/12000)
#define USB_CFG_CHECK_CRC 0
#define USB_CFG_HAVE_INTRIN_ENDPOINT 1
#define USB_CFG_HAVE_INTRIN_ENDPOINT3 0
#define USB_CFG_EP3_NUMBER 3
#define USB_CFG_IMPLEMENT_HALT 0
#define USB_CFG_SUPPRESS_INTR_CODE 0
#define USB_CFG_INTR_POLL_INTERVAL 10
#define USB_CFG_IS_SELF_POWERED 1
#define USB_CFG_MAX_BUS_POWER 50
#define USB_CFG_IMPLEMENT_FN_WRITE 1
#define USB_CFG_IMPLEMENT_FN_READ 1
#define USB_CFG_IMPLEMENT_FN_WRITEOUT 0
#define USB_CFG_HAVE_FLOWCONTROL 0
#define USB_CFG_DRIVER_FLASH_PAGE 0
#define USB_CFG_LONG_TRANSFERS 0
#define USB_COUNT_SOF 0
#define USB_CFG_CHECK_DATA_TOGGLING 0
#define USB_CFG_HAVE_MEASURE_FRAME_LENGTH 0
#define USB_USE_FAST_CRC 0
/* -------------------------- Device Description --------------------------- */
#define USB_CFG_VENDOR_ID 0x8f, 0x19 /* = 0x16c0 = 5824 = voti.nl */
#define USB_CFG_DEVICE_ID 0xe9, 0x17 /* obdev's shared PID for HIDs */
#define USB_CFG_DEVICE_VERSION 0x00, 0x01
#define USB_CFG_VENDOR_NAME 'o', 'b', 'd', 'e', 'v', '.', 'a', 't'
#define USB_CFG_VENDOR_NAME_LEN 8
#define USB_CFG_DEVICE_NAME 'D', 'a', 't', 'a', 'S', 't', 'o', 'r', 'e'
#define USB_CFG_DEVICE_NAME_LEN 9
#define USB_CFG_DEVICE_CLASS 0
#define USB_CFG_DEVICE_SUBCLASS 0
#define USB_CFG_INTERFACE_CLASS 3
#define USB_CFG_INTERFACE_SUBCLASS 0
#define USB_CFG_INTERFACE_PROTOCOL 0
#define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH 33
#define USB_CFG_DESCR_PROPS_DEVICE 0
#define USB_CFG_DESCR_PROPS_CONFIGURATION 0
#define USB_CFG_DESCR_PROPS_STRINGS 0
#define USB_CFG_DESCR_PROPS_STRING_0 0
#define USB_CFG_DESCR_PROPS_STRING_VENDOR 0
#define USB_CFG_DESCR_PROPS_STRING_PRODUCT 0
#define USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER 0
#define USB_CFG_DESCR_PROPS_HID 0
#define USB_CFG_DESCR_PROPS_HID_REPORT 0
#define USB_CFG_DESCR_PROPS_UNKNOWN 0
LCD und die LEDs funktionieren alle wunderbar. Nur das USB will nicht. :(
Ich hoffe jemand kann mir helfen warum ich keine Daten vom PC an das Device schicken kann.
Hab auch irgendwie das Gefühl das die Funktionen usbFunctionSetup und usbFunctionWrite überhaupt nicht aufgerufen werden. Mein LCD bleibt immer bei "System Ready" stehen.
Danke schon im vorraus für die Mühe.
Gruß
coder44
ich habe ein Projekt gebaut mit einem ATmega168. LCD und USB und ein paar Taster u. RGB-LEDS sind vorhanden.
Nun will ich das Device per USB mit meinem PC verbinden. Soweit klappt auch alles wunderbar.
Ich habe beispielsweise in BASCOM alles zu laufen bekommen. Ich kann Daten vom Device lesen und auch Daten vom PC auf das Device senden.
Auf der PC Seite verwende ich LibUSBDotNet mit dem libusb Treiber. Mit der mitgelieferten Software "Test_Bulk" teste ich immer das senden und empfangen.
Nun wollte ich das Projekt umschreiben und in C zum laufen bekommen. Bisher klappt auch fast alles. Device wird vom PC erkannt, kann auch die Daten
mit dem PC vom Device lesen ABER ich kann keine Daten vom PC an das Device schicken. Dann erhalte ich immer die Fehlermeldung:
Win32Error:PipeTransferSubmit Ep 0x02
87:Falscher Parameter.
Hier mal mein Code...
#define F_CPU 12000000UL
#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/interrupt.h> /* for sei() */
#include <util/delay.h> /* for _delay_ms() */
#include <avr/eeprom.h>
#include <avr/pgmspace.h> /* required by usbdrv.h */
#include "usbdrv/usbdrv.h"
#include "usbdrv/oddebug.h" /* This is also an example for using debug macros */
#include "lcd-routines.h"
#define farbe PORTB
#define rot 4
#define gruen 5
#define blau 3
#define SETBIT(ADDRESS,BIT) (ADDRESS |= (1<<BIT))
#define CLEARBIT(ADDRESS,BIT) (ADDRESS &= ~(1<<BIT))
#define FLIPBIT(ADDRESS,BIT) (ADDRESS ^= (1<<BIT))
#define CHECKBIT(ADDRESS,BIT) (ADDRESS & (1<<BIT))
#define WRITEBIT(RADDRESS,RBIT,WADDRESS,WBIT) (CHECKBIT(RADDRESS,RBIT) ? SETBIT(WADDRESS,WBIT) : CLEARBIT(WADDRESS,WBIT))
/* ------------------------------------------------------------------------- */
/* ----------------------------- USB interface ----------------------------- */
/* ------------------------------------------------------------------------- */
PROGMEM const char usbHidReportDescriptor[] = { /* USB report descriptor */
0x06, 0x00, 0xff, // USAGE_PAGE (Generic Desktop)
0x09, 0x01, // USAGE (Vendor Usage 1)
0xa1, 0x02, // COLLECTION (Application)
// Input Report
0x09, 0x01, // Usage ID - vendor defined
0x15, 0x00, // Logical Minimum (0)
0x25, 0xFF, // Logical Maximum (255)
0x75, 0x08, // Report Size (8 bits)
0x95, 0x01, // Report Count (8 fields)
0x81, 0x02, // Input (Data, Variable, Absolute)
// Output report
0x09, 0x01, // Usage ID - vendor defined
0x15, 0x00, // Logical Minimum (0)
0x26, 0xFF, 0x00, // Logical Maximum (255)
0x75, 0x08, // Report Size (8 bits)
0x95, 0x01, // Report Count (8 fields)
0x91, 0x02, // Output (Data, Variable, Absolute)
0xc0 // END_COLLECTION
};
/* The following variables store the status of the current data transfer */
static uchar currentAddress;
static uchar bytesRemaining;
static uchar inbuf[8], outbuf[8], outlen;
/* ------------------------------------------------------------------------- */
/* usbFunctionRead() is called when the host requests a chunk of data from
* the device. For more information see the documentation in usbdrv/usbdrv.h.
*/
uchar usbFunctionRead(uchar *data, uchar len)
{
lcd_clear();
lcd_string("func read");
an(blau, 3);
if(len > bytesRemaining)
len = bytesRemaining;
eeprom_read_block(data, (uchar *)0 + currentAddress, len);
currentAddress += len;
bytesRemaining -= len;
return len;
}
/* usbFunctionWrite() is called when the host sends a chunk of data to the
* device. For more information see the documentation in usbdrv/usbdrv.h.
*/
uchar usbFunctionWrite(uchar *data, uchar len)
{
lcd_clear();
lcd_string("func write");
an(blau, 2);
if(bytesRemaining == 0)
return 1; /* end of transfer */
if(len > bytesRemaining)
len = bytesRemaining;
eeprom_write_block(data, (uchar *)0 + currentAddress, len);
lcd_clear();
lcd_string(data);
an(rot, 1);
currentAddress += len;
bytesRemaining -= len;
return bytesRemaining == 0; /* return 1 if this was the last chunk */
}
/* ------------------------------------------------------------------------- */
usbMsgLen_t usbFunctionSetup(uchar data[8])
{
lcd_clear();
lcd_string("func setup");
an(rot, 1);
usbRequest_t *rq = (void *)data;
lcd_clear();
lcd_string(rq->bRequest);
}
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
void an(int col, int led)
{
SETBIT(PORTC, led);
SETBIT(PORTB, col);
_delay_ms(90);
CLEARBIT(PORTC, led);
CLEARBIT(PORTB, col);
}
int main(void)
{
DDRC = 0xff;
lcd_init();
SETBIT(DDRB, PB3);
CLEARBIT(DDRB, PB0);
lcd_string("System ready...");
uchar i;
wdt_enable(WDTO_1S);
odDebugInit();
DBG1(0x00, 0, 0);
usbInit();
an(blau, 1);
usbDeviceDisconnect();
i = 0;
while(--i){ /* fake USB disconnect for > 250 ms */
wdt_reset();
_delay_ms(1);
}
usbDeviceConnect();
sei();
DBG1(0x01, 0, 0);
for(;;){ /* main event loop */
DBG1(0x02, 0, 0);
wdt_reset();
usbPoll();
if(usbInterruptIsReady())
{
SETBIT(PORTC, 5);
SETBIT(PORTB, gruen);
inbuf[0] = 'a';
inbuf[1] = 'b';
inbuf[2] = 'c';
inbuf[3] = '\n';
usbSetInterrupt(inbuf, sizeof(inbuf)); //damit lese ich am PC "abc" aus
}
else
{
CLEARBIT(PORTC, 5);
CLEARBIT(PORTB, gruen);
}
}
return 0;
}
In meiner usbconfig.h ist folgends eingestellt:
#define USB_CFG_IOPORTNAME D
#define USB_CFG_DMINUS_BIT 3
#define USB_CFG_DPLUS_BIT 2
#define USB_CFG_CLOCK_KHZ (F_CPU/12000)
#define USB_CFG_CHECK_CRC 0
#define USB_CFG_HAVE_INTRIN_ENDPOINT 1
#define USB_CFG_HAVE_INTRIN_ENDPOINT3 0
#define USB_CFG_EP3_NUMBER 3
#define USB_CFG_IMPLEMENT_HALT 0
#define USB_CFG_SUPPRESS_INTR_CODE 0
#define USB_CFG_INTR_POLL_INTERVAL 10
#define USB_CFG_IS_SELF_POWERED 1
#define USB_CFG_MAX_BUS_POWER 50
#define USB_CFG_IMPLEMENT_FN_WRITE 1
#define USB_CFG_IMPLEMENT_FN_READ 1
#define USB_CFG_IMPLEMENT_FN_WRITEOUT 0
#define USB_CFG_HAVE_FLOWCONTROL 0
#define USB_CFG_DRIVER_FLASH_PAGE 0
#define USB_CFG_LONG_TRANSFERS 0
#define USB_COUNT_SOF 0
#define USB_CFG_CHECK_DATA_TOGGLING 0
#define USB_CFG_HAVE_MEASURE_FRAME_LENGTH 0
#define USB_USE_FAST_CRC 0
/* -------------------------- Device Description --------------------------- */
#define USB_CFG_VENDOR_ID 0x8f, 0x19 /* = 0x16c0 = 5824 = voti.nl */
#define USB_CFG_DEVICE_ID 0xe9, 0x17 /* obdev's shared PID for HIDs */
#define USB_CFG_DEVICE_VERSION 0x00, 0x01
#define USB_CFG_VENDOR_NAME 'o', 'b', 'd', 'e', 'v', '.', 'a', 't'
#define USB_CFG_VENDOR_NAME_LEN 8
#define USB_CFG_DEVICE_NAME 'D', 'a', 't', 'a', 'S', 't', 'o', 'r', 'e'
#define USB_CFG_DEVICE_NAME_LEN 9
#define USB_CFG_DEVICE_CLASS 0
#define USB_CFG_DEVICE_SUBCLASS 0
#define USB_CFG_INTERFACE_CLASS 3
#define USB_CFG_INTERFACE_SUBCLASS 0
#define USB_CFG_INTERFACE_PROTOCOL 0
#define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH 33
#define USB_CFG_DESCR_PROPS_DEVICE 0
#define USB_CFG_DESCR_PROPS_CONFIGURATION 0
#define USB_CFG_DESCR_PROPS_STRINGS 0
#define USB_CFG_DESCR_PROPS_STRING_0 0
#define USB_CFG_DESCR_PROPS_STRING_VENDOR 0
#define USB_CFG_DESCR_PROPS_STRING_PRODUCT 0
#define USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER 0
#define USB_CFG_DESCR_PROPS_HID 0
#define USB_CFG_DESCR_PROPS_HID_REPORT 0
#define USB_CFG_DESCR_PROPS_UNKNOWN 0
LCD und die LEDs funktionieren alle wunderbar. Nur das USB will nicht. :(
Ich hoffe jemand kann mir helfen warum ich keine Daten vom PC an das Device schicken kann.
Hab auch irgendwie das Gefühl das die Funktionen usbFunctionSetup und usbFunctionWrite überhaupt nicht aufgerufen werden. Mein LCD bleibt immer bei "System Ready" stehen.
Danke schon im vorraus für die Mühe.
Gruß
coder44