Hello, I have been trying to perform USB communication between my AT89C5131A chip and pyUSB, to transmit some data to the microcontroller. I haven't been able to find any library which will help me achieve this and as a result I've been trying to understand the USB configuration mentioned in http://www.keil.com/dd/docs/datashts/atmel/at89c5131_ds.pdf.
On running the command dev.set_configuration(), I receive an error and I suppose this indicates a mistake in my configuration till that point.
My hardware bootloader however successfully runs with the dfu-programmer.
I've set the clock frequency correctly and enabled USBEN and FEN as mentioned.
1. Where am I going wrong? 2. Are there any good libraries for doing USB communication with AT89C5131A? 3. Should I switch to an AVR uC instead and use the LUFA library?
Thank you!
For AT89C5131A, Atmel has released a couple of USB device projects on Keil C51 on their website. This CDC implementation gives good starting point for your purpose.
USB Communication Device Class - Migration from RS-232 to USB www.atmel.com/.../doc4322.pdf www.atmel.com/.../c5131-usb-cdc-1_2_1.zip
You'll modify this example step by step. 1) run this example on your board - This example supposes a 16MHz crystal. Tune it for your crystal
config.h #define FOSC 16000
Your board should appear as a CDC device on your PC.
2) Implement a loop-back, to test it on PC terminal.
if ( uart_usb_tx_ready() && uart_usb_test_hit() ) { char c = uart_usb_getchar(); uart_usb_putchar( &c ); }
3) Replace the config descriptor into vendor-specific one, also VID/PID
config.h #define DEVICE_CLASS 0x02 <-- 0xFF (vendor) ... #define VENDOR_ID 0xEB03 /* Atmel vendor ID = 03EBh */ #define PRODUCT_ID 0x0920 /* Product ID: 2009h = CDC C5131 */ ... #define CONF_LENGTH 0x4300 <-- 0x2000 #define NB_INTERFACE 2 <-- 1 ... #define INTERFACE1_NB 1 <-- 0 ... #define INTERFACE1_CLASS 0x0A /* CDC ACM Data */ <-- 0xFF (vendor)
usb_cdc_enum.c code struct { struct usb_st_configuration_descriptor cfg; struct usb_st_interface_descriptor ifc1; struct usb_st_endpoint_descriptor ep1 ; struct usb_st_endpoint_descriptor ep2 ; } usb_configuration = { { 9, CONFIGURATION, CONF_LENGTH, NB_INTERFACE, CONF_NB, CONF_INDEX, CONF_ATTRIBUTES, MAX_POWER}, { 9, INTERFACE, INTERFACE1_NB, ALTERNATE1, NB_ENDPOINT1, INTERFACE1_CLASS, INTERFACE1_SUB_CLASS, INTERFACE1_PROTOCOL, INTERFACE1_INDEX }, { 7, ENDPOINT, ENDPOINT_NB_1, EP_ATTRIBUTES_1, EP_SIZE_1, EP_INTERVAL_1 }, { 7, ENDPOINT, ENDPOINT_NB_2, EP_ATTRIBUTES_2, EP_SIZE_2, EP_INTERVAL_2 }, };
Now that pyusb is able to see this device.
4) Lastly, clean up the source code.
Tsuneo
Hey Tsuneo, Thank you for the informative reply. Unfortunately, I'm running the evaluation version of Keil uVision 4 and I'm getting a code size limit when I try to edit and compile the USB CDC project by Atmel. What's the best workaround here? Is there some other compiler (like SDCC) which will work here?
Thanks, Kalpesh Krishna
Hey Tsuneo, I overcame the previous problem by using a PC having the full license. I successfully detected my device as a CDC device in pyusb. However, I'm a bit unsure about step 2. I added something like this to my main()
while(1) { if ( uart_usb_tx_ready() && uart_usb_test_hit() ) { char c = uart_usb_getchar(); uart_usb_putchar(c); } }
Is this the correct place to write this code? On running this with pyusb, I get the following :- (131 is the endpoint address)
>>> dev.write(131, msg, 1) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/local/lib/python2.7/dist-packages/usb/core.py", line 870, in write intf, ep = self._ctx.setup_request(self, endpoint) File "/usr/local/lib/python2.7/dist-packages/usb/core.py", line 190, in setup_request self.managed_claim_interface(device, intf) File "/usr/local/lib/python2.7/dist-packages/usb/core.py", line 146, in managed_claim_interface self.backend.claim_interface(self.handle, i) File "/usr/local/lib/python2.7/dist-packages/usb/backend/libusb1.py", line 747, in claim_interface _check(self.lib.libusb_claim_interface(dev_handle.handle, intf)) File "/usr/local/lib/python2.7/dist-packages/usb/backend/libusb1.py", line 552, in _check raise USBError(_strerror(ret), ret, _libusb_errno[ret]) usb.core.USBError: [Errno 16] Resource busy >>>
Which is the correct place to put the code for step 2)? What are some good resources to learn the USB protocol from?
Thank you, Kalpesh
Dear Tsuneo, We were successfully able to transfer data to and from the microncontroller using pyserial. I think this code will be a great starting point for our application. Thanks for all the help!