Cant read from Out endpoint + with python usb

335 views
Skip to first unread message

Anders D

unread,
Jan 24, 2012, 4:35:16 PM1/24/12
to LUFA Library Support List
Hello

Im fooling around with lufa and pythonusb and cant get communication
to the uC to work (endpoint out). I can read from the uC (endpoint
in).

Does anyone have any ideas.

I'll post releveant (i hope =) ) parts of the code below. The code was
originally a lufa example that i have modified.
Configuration
/** Endpoint number of the USBMISSILE data OUT endpoint. */
#define USBMISSILE_DATA_OUT_EPNUM 2
/** Endpoint number of the USBMISSILE data IN endpoint. */
#define USBMISSILE_DATA_IN_EPNUM 2
/** Size in bytes of the USBMISSILE data endpoint. */
#define USBMISSILE_DATA_IN_EPSIZE 1
#define USBMISSILE_DATA_OUT_EPSIZE 1

The actual use of the code
I cant get into the If that checks the OUT endpoint
[code]
void USBMissile_Task(void) {
/* Device must be connected and configured for the task to run */
if (USB_DeviceState != DEVICE_STATE_Configured)
return;
Endpoint_SelectEndpoint(USBMISSILE_DATA_OUT_EPNUM);
Endpoint_SetEndpointDirection(ENDPOINT_DIR_OUT);
LEDs_SetAllLEDs(LEDMASK_BUSY);
if (Endpoint_IsOUTReceived()) {
data = Endpoint_Read_8();
MotorModelCmd(data);<--- I cant get in here.
Endpoint_ClearOUT();
//Cant seem to get here
}
Endpoint_SelectEndpoint(USBMISSILE_DATA_IN_EPNUM);
Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
if (Endpoint_IsINReady()) {
Endpoint_Write_8(recbytes[1]);
recbytes[1]=recbytes[1]+1;
//Endpoint_Write_8(MotorModelGetEndswitchState());
Endpoint_ClearIN();
}

LEDs_SetAllLEDs(LEDMASK_USB_READY);

}[/code]

Python code to read write
[code]
import usb

class MissileDevice:
def __init__(self):
self.dev=UsbDevice(0x03eb, 0x2040)
self.dev.open()
self.dev.handle.reset()
self.dev.open()
self.GO_LEFT=0x01
self.GO_RIGHT=0x02
self.GO_UP=0x04
self.GO_DOWN=0x08
self.FIRE=0x10
self.STOP=0x00
self.LEFT_ENDSWITCH=0x01
self.RIGHT_ENDSWITCH=0x02
self.UP_ENDSWITCH=0x04
self.DOWN_ENDSWITCH=0x08

def write(self, msg):
return self.dev.handle.bulkWrite(0x02,bytes(chr(msg)))

def read(self,length):
return self.dev.handle.bulkRead(0x82,length)

class UsbDevice:
def __init__(self, vendor_id, product_id):
busses = usb.busses()
self.handle = None
for bus in busses:
devices = bus.devices
for dev in devices:
if dev.idVendor==vendor_id and
dev.idProduct==product_id:
self.dev = dev
self.conf = self.dev.configurations[0]
self.intf = self.conf.interfaces[0][0]
self.endpoints = []
for endpoint in self.intf.endpoints:
self.endpoints.append(endpoint)
return

def open(self):
if self.handle:
self.handle = None
self.handle = self.dev.open()
self.handle.setConfiguration(self.conf)
self.handle.claimInterface(self.intf)
self.handle.setAltInterface(self.intf)

md=MissileDevice()
md.write(0x01)
md.write(0x02)
[/code]


Any ideas?

BR
Anders

Dean Camera

unread,
Jan 29, 2012, 10:34:13 AM1/29/12
to LUFA Library Support List
Anders,

I see you've defined your IN and OUT data endpoints to have the same
number. In the USB specification, it is possible for two endpoints
(one IN, one OUT) to share the same endpoint number - the logical
address will differ by the most significant bit to indicate the IN
endpoint - however the USB AVR8s do not support this configuration.
Try changing one of the endpoints to use a different endpoint index
and recompile. I also see you've set both endpoint sizes to one byte,
which is invalid - you need to specify a power of two between 8 and 64
for BULK type endpoints. Try this:

/** Endpoint number of the USBMISSILE data OUT endpoint. */
#define USBMISSILE_DATA_OUT_EPNUM 1
/** Endpoint number of the USBMISSILE data IN endpoint. */
#define USBMISSILE_DATA_IN_EPNUM 2
/** Size in bytes of the USBMISSILE data endpoint. */
#define USBMISSILE_DATA_IN_EPSIZE 64
#define USBMISSILE_DATA_OUT_EPSIZE 64

Depending on how your operating system caches the device descriptors,
you may also need to alter the device descriptor's VID, PID or version
field to force the OS to re-cache the updated configuration with the
corrected endpoint addresses.

Cheers!
- Dean

Anders D

unread,
Jan 31, 2012, 2:30:31 PM1/31/12
to LUFA Library Support List
Thats an annoyingly easy fix =) I did read some of the standard and
thought i was home free.

I'll try it sometime this week.

One followup regarding the endpoint sizes.
If use 8 byte for the IN ep but only actually write one. Will the
stack handle eventual padding of the data or must i write 8 bytes
every time? So that i can always read 8 bytes from my python app and
discard seven of them. Or will the actual messages only have one byte
payload?

Cheers
Anders

Anders D

unread,
Feb 2, 2012, 3:10:58 PM2/2/12
to LUFA Library Support List
Still cant seem to get it right. With no changes to the python code
(except the adress obviously)

on the avr side i defined endpoints 2 and 3 and both with size 8
bytes.
#define USBMISSILE_DATA_OUT_EPNUM 2
#define USBMISSILE_DATA_IN_EPNUM 3

#define USBMISSILE_DATA_IN_EPSIZE 8
#define USBMISSILE_DATA_OUT_EPSIZE 8

To do the communication i use the following code. data is a global
array.

Endpoint_SelectEndpoint(USBMISSILE_DATA_OUT_EPNUM);
Endpoint_SetEndpointDirection(ENDPOINT_DIR_OUT);
if (Endpoint_IsOUTReceived()) {
data[0] = Endpoint_Read_8();
Endpoint_ClearOUT();
}

Endpoint_SelectEndpoint(USBMISSILE_DATA_IN_EPNUM);
Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
if (Endpoint_IsINReady()) {
Endpoint_Write_8(data[0]);
Endpoint_ClearIN();
}

what i would like to see is all data echoed back.

Any thoughts?

Cheers
Anders

Opendous Support

unread,
Feb 3, 2012, 6:02:15 AM2/3/12
to lufa-s...@googlegroups.com
Why are you setting endpoint direction? You have distinct IN and OUT EPs.

>what i would like to see is all data echoed back

That cannot be guaranteed since you only grab one byte of data per
transaction. That also means you limit your throughput to about
1kbyte/second.

Use the LUFA Stream functions to read and write from your endpoints
into buffers.
http://code.google.com/p/micropendous/source/browse/trunk/Micropendous/Firmware/LoopBack/LoopBack.c#267

The Python USB code can then be used to read/write whole strings/arrays:
http://code.google.com/p/micropendous/source/browse/trunk/Micropendous/Firmware/LoopBack/DeviceAccessPy.py#47

> --
> You received this message because you are subscribed to the Google Groups "LUFA Library Support List" group.
> To post to this group, send email to lufa-s...@googlegroups.com.
> To unsubscribe from this group, send email to lufa-support...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/lufa-support?hl=en.
>

Dean Camera

unread,
Feb 5, 2012, 7:58:05 AM2/5/12
to LUFA Library Support List
Remember to also change the device's VID/PID or revision number once
you edit the Configuration Descriptor, so that the host PC (Windows)
re-fetches the changed descriptors. If you don't, it'll still think
the device uses the previous incorrect endpoints and the communication
will still fail.

- Dean

Anders D

unread,
Feb 5, 2012, 4:44:28 PM2/5/12
to LUFA Library Support List
@Dean, Im a linuxman and i checked with lsusb that the endpoints are
reread, so that should be fine.

@Opendous
I removed the setting of direction. Speed is of no concern for this
application. I only use usb to learn more about it. I have a project
in the que that will use big endpoints for some data recording. I will
probably use the stream then.
That is also the reason i use bulk endpoints now, to figure them out
so that i know what to do in the next project. I really only need a
byte now and then in this project.

However i still cant get it to work.

My c-code

void USBMissile_Task(void) {
/* Device must be connected and configured for the task to run */
if (USB_DeviceState != DEVICE_STATE_Configured)
return;
Endpoint_SelectEndpoint(USBMISSILE_DATA_OUT_EPNUM);
if (Endpoint_IsOUTReceived()) {
if (Endpoint_IsReadWriteAllowed()){
data[0] = Endpoint_Read_8();
}
Endpoint_ClearOUT();
}

Endpoint_SelectEndpoint(USBMISSILE_DATA_IN_EPNUM);
if (Endpoint_IsReadWriteAllowed()){
Endpoint_Write_8(0xFF);
Endpoint_Write_8(0xF6);
Endpoint_Write_8(0xF6);
Endpoint_Write_8(0xF5);
Endpoint_Write_8(0xF3);
Endpoint_Write_8(0xF2);
Endpoint_Write_8(0xF1);
Endpoint_Write_8(0xF0);
Endpoint_ClearIN();
}
LEDs_SetAllLEDs(LEDMASK_USB_READY);

}

And is use the python code from
http://code.google.com/p/micropendous/source/browse/trunk/Micropendous/Firmware/LoopBack/TestLoopBackThroughput.py
with modified pid/vid and ep types and configuration
but buffer remains empty

Any thoughts?

Maybe i should compile the opendous example code.

BR
ANders

Anders D

unread,
Feb 12, 2012, 7:34:51 AM2/12/12
to LUFA Library Support List
I found the error. It was a rather stupid one. =)

I did not configure the IN endpoint on the avr, only the OUT endpoint.
Now that i added configuration for both endpoints it works like a
charm

Anyways thanks a lot for the help and pointers. I did learn more about
the bulk endpoint. If all goes well I'll post a working video of it
working in a week or two.

Thanks
Anders
> And is use the python code fromhttp://code.google.com/p/micropendous/source/browse/trunk/Micropendou...
> ...
>
> read more »

Dean Camera

unread,
Feb 12, 2012, 8:05:13 AM2/12/12
to LUFA Library Support List
Anders,

Glad to hear it. I've still got a bunch of unanswered posts here I
haven't got to yet, and yours was one of them. I look forward to the
video!

Cheers!
- Dean
> ...
>
> read more »
Reply all
Reply to author
Forward
0 new messages