usbFunctionSetup and usbFunctionWrite in action?
usbFunctionSetup and usbFunctionWrite in action?
Hi: Any example of a usbFunctionSetup and usbFunctionWrite in action? Of course they are for the user to write them, but has some user tried to transfer data to the device via a control output transfer (8 bytes maximum if I understood it)?
-
- Rank 1
- Posts: 32
- Joined: Fri Nov 02, 2012 3:26 pm
Re: usbFunctionSetup and usbFunctionWrite in action?
Well, that won't do. What I need is source code. C source code of a usbFunctionSetup example. Thanks anyways.
Re: usbFunctionSetup and usbFunctionWrite in action?
When you download the v-usb code it comes with an example that demonstrates this in a command prompt. I wrote some code using PID. This is the set up.
The Write is proprietary to what I use if for but you just need to analyze the data.
uchar usbFunctionWrite(uchar *data, uchar len)
{
if (data[0]==1 && _setReport ){ _setReport=0; ...}
...
}
Code: Select all
unsigned usbFunctionSetup(uchar data[8])
{
usbRequest_t *rq = (void *)data;
usbMsgPtr = reportBuffer;
if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS)
{ /* class request type */
if(rq->bRequest == USBRQ_HID_GET_REPORT)
{
if ( rq->wValue.bytes[0] == 2 )
{//PID Block Load Report
char error=1;
if (_FFB_effect_index>4) error =2;
reportBuffer[0]=2; //report id 2
reportBuffer[1]=_FFB_effect_index;//effect index
reportBuffer[2]=error;//1 = success:2 = full: 3 = error
}
return USB_NO_MSG;
}
else if (rq->bRequest == USBRQ_HID_SET_REPORT)
{
if ( rq->wValue.bytes[0] == 1 ) _setReport=1;//set effect Report
return USB_NO_MSG;
}
}
return 0;
}
The Write is proprietary to what I use if for but you just need to analyze the data.
uchar usbFunctionWrite(uchar *data, uchar len)
{
if (data[0]==1 && _setReport ){ _setReport=0; ...}
...
}
Re: usbFunctionSetup and usbFunctionWrite in action?
Thanks for your post. Could you tell me what is wrong with the following attempt to transfer data from the PC to the device via a control OUT transfer?
in the host app. All this is only a test so if you find it meaningless don't care. In the device app:
Of course in a real app, in usbFunctionSetup I would save the setup context. The funny thing is that I do NOT use usbMsgPtr, in spite of the comment in usbdrv.h by the driver author. However, my code does not work. He says:
NOTE: in your usbFunctionWrite, it seems data[0] is the field bmRequestType of the USB device request sent by the host and not the actual data to be transfered after the data stage transaction.
Code: Select all
for(i=0;i<8;i++){
buffer[i]= i;
}
mode=0;
ret=usb_control_msg(d, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT, mode, 0, 0, (char *)buffer, sizeof(buffer), 5000);
in the host app. All this is only a test so if you find it meaningless don't care. In the device app:
Code: Select all
uchar usbFunctionWrite(uchar *data, uchar len){
int i;
for(i=0;i<len;i++){ // len expected to be 8.
Send data[i] to a display driven by the device
}
// The array data[8] here is buffer[8] in the host app.
return 1; // if we received it all (0 if not)
}
uchar usbFunctionSetup(uchar data[3]){
#define USB_NO_MSG 0xFF
return USB_NO_MSG;
}
Of course in a real app, in usbFunctionSetup I would save the setup context. The funny thing is that I do NOT use usbMsgPtr, in spite of the comment in usbdrv.h by the driver author. However, my code does not work. He says:
Code: Select all
extern uchar *usbMsgPtr;
/* This variable may be used to pass transmit data to the driver from the
* implementation of usbFunctionWrite(). It is also used internally by the
* driver for standard control requests.
*/
NOTE: in your usbFunctionWrite, it seems data[0] is the field bmRequestType of the USB device request sent by the host and not the actual data to be transfered after the data stage transaction.
Re: usbFunctionSetup and usbFunctionWrite in action?
Correct, I'm leaving that up to you to figure out.in your usbFunctionWrite, it seems data[0] is the field bmRequestType of the USB device request sent by the host and not the actual data to be transfered after the data stage transaction.
Your problem may be how you set up the pipes. Can you post your config in here?
Re: usbFunctionSetup and usbFunctionWrite in action?
Thank you. I'm posting a link to the usbconfig.h file:
http://www.filedropper.com/usbconfig
You don't need either to register or login. Just press the 'Download this file' button. The uP in the device is an ATtiny85.
http://www.filedropper.com/usbconfig
You don't need either to register or login. Just press the 'Download this file' button. The uP in the device is an ATtiny85.
Re: usbFunctionSetup and usbFunctionWrite in action?
no, sorry your USB device descriptor config. Normaaly at the top of the main.c file, shows your Interface Descriptors and endpoints...
Re: usbFunctionSetup and usbFunctionWrite in action?
This is usbdrv.c, the driver source (except the assembler part) which I post along with usbdrv.h:
http://www.filedropper.com/usbdrv
http://www.filedropper.com/usbdrv_1
At the top of usbdrv.c (first link) you'll find what you ask for. Thanks ulao.
http://www.filedropper.com/usbdrv
http://www.filedropper.com/usbdrv_1
At the top of usbdrv.c (first link) you'll find what you ask for. Thanks ulao.
Re: usbFunctionSetup and usbFunctionWrite in action?
This is how usbProcessRx ends in my usbdrv.c:
You'll be able to see that no matter what the result of usbFunctionSetup is, whether 0xFF (0xFF is USB_NO_MSG) or not, usbMsgLen will never get USB_NO_MSG as its value. Suppose from the host application I call
When in usbPoll, control reaches
and if usbTxLen < 0, usbBuildTxBlock will be called, even if there is nothing to transmit. I am looking at the Changelogs of newer versions to see where the bug was fixed.
Code: Select all
}else{ /* not a standard request -- must be vendor or class request */
#if USB_CFG_IMPLEMENT_FN_READ || USB_CFG_IMPLEMENT_FN_WRITE
uchar len;
replyLen = data[6]; /* if this is an OUT operation, the next token will reset usbMsgLen */
if((len = usbFunctionSetup(data)) != 0xff){
replyLen = len;
#if 1 /* USB-IO */
flags = 0; /* we have no valid msg, use read/write functions */
#endif
}else{
flags = 0; /* we have no valid msg, use read/write functions */
}
#else
replyLen = usbFunctionSetup(data);
#endif
}
}
usbMsgLen = replyLen;
usbMsgFlags = flags;
}else{ /* out request */
usbWrite(data, len);
}
}
You'll be able to see that no matter what the result of usbFunctionSetup is, whether 0xFF (0xFF is USB_NO_MSG) or not, usbMsgLen will never get USB_NO_MSG as its value. Suppose from the host application I call
Code: Select all
ret=usb_control_msg(d, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT, mode, 0, 0, (char *)buffer, sizeof(buffer), 5000);
When in usbPoll, control reaches
Code: Select all
void usbPoll(void)
{
uchar len;
if((len = usbRxLen) > 0){
/* We could check CRC16 here -- but ACK has already been sent anyway. If you
* need data integrity checks with this driver, check the CRC in your app
* code and report errors back to the host. Since the ACK was already sent,
* retries must be handled on application level.
* unsigned crc = usbCrc16((uchar *)(unsigned)(usbAppBuf + 1), usbRxLen - 3);
*/
len -= 3; /* remove PID and CRC */
if(len < 128){
usbProcessRx((uchar *)(unsigned)(usbAppBuf + 1), len);
}
usbRxLen = 0; /* mark rx buffer as available */
}
if(usbTxLen < 0){ /* TX system is idle */
if(usbMsgLen != 0xff){
usbBuildTxBlock();
}else if(usbNewDeviceId){
usbDeviceId = usbNewDeviceId;
#if 0 /* USB-IO */
DBG1(1, &usbNewDeviceId, 1);
#endif
usbNewDeviceId = 0;
}
}
and if usbTxLen < 0, usbBuildTxBlock will be called, even if there is nothing to transmit. I am looking at the Changelogs of newer versions to see where the bug was fixed.
Re: usbFunctionSetup and usbFunctionWrite in action?
Ok I see you didnt customize it, you left the default setup. Well I cant really help you go about it by answering your questions but consider.
1) You wont get this to work win only on endpoint. You need a control in and out. I also think ( don't quote me on this ) that you need the default that as well. Unless you are using the default and in that case your ok. So you really need two in one out. At very least one in and one out. Simply defining USB_CFG_IMPLEMENT_FN_WRITE does not do that AFAIK.
This is ugly,
why not just
anyways I think you need 2 here but depends on how you use it.
plus the third. This is missing in the usbconfig, its very clear on the new stuff.
2) Your way out of date here and full of bugs. Creation Date: 2005-04-01 ? the newer version makes end point much easier. Consider checking out the newer code.
Other then that I'm afraid my knowledge and the way I set up my code is not enough to help you with your problem.
1) You wont get this to work win only on endpoint. You need a control in and out. I also think ( don't quote me on this ) that you need the default that as well. Unless you are using the default and in that case your ok. So you really need two in one out. At very least one in and one out. Simply defining USB_CFG_IMPLEMENT_FN_WRITE does not do that AFAIK.
This is ugly,
Code: Select all
#if 1
#define USB_CFG_HAVE_INTRIN_ENDPOINT 1
#else
#define USB_CFG_HAVE_INTRIN_ENDPOINT 0
#endif
why not just
Code: Select all
#define USB_CFG_HAVE_INTRIN_ENDPOINT 1
//or
#define USB_CFG_HAVE_INTRIN_ENDPOINT 0
anyways I think you need 2 here but depends on how you use it.
plus the third. This is missing in the usbconfig, its very clear on the new stuff.
2) Your way out of date here and full of bugs. Creation Date: 2005-04-01 ? the newer version makes end point much easier. Consider checking out the newer code.
Other then that I'm afraid my knowledge and the way I set up my code is not enough to help you with your problem.
Re: usbFunctionSetup and usbFunctionWrite in action?
Well this is code from Objective Development used by Yoshiyasu Takefuji in a Circuit Cellar article from 2008 to control a programmable power supply via USB. As I implemented the circuit as he gave it, I did not touch the usbconfig.h file except for some things, namely, he transferred the voltage value to the device using the value field in the usbControlMsg call. So he did not use usbFunctionWrite, doing everything from usbFunctionSetup. Whereas I wanted to use usbFunctionWrite to transfer 8 bytes to the device. For this, I only needed control transfers. No Interrupt or any other type of transfers. Hence, with only the endpoint 0 I was done (if I am not wrong).
Anyways, because I think something was wrong in the usbdrv.c file that wouldn't let me use usbFunctionWrite, I now want to make a fresh start and am using avrusb-20080418 for the project (I am not interested in the power supply thing, only want to see USB working with usbFunctionWrite and a control out message). Maybe later on I'll date to use the current obdev code, but for the moment I pretend maximum simplicity, because it's a matter of understanding what I am doing and the simpler the code the easier to understand. Thanks very much for the time you lent me, ulao.
Anyways, because I think something was wrong in the usbdrv.c file that wouldn't let me use usbFunctionWrite, I now want to make a fresh start and am using avrusb-20080418 for the project (I am not interested in the power supply thing, only want to see USB working with usbFunctionWrite and a control out message). Maybe later on I'll date to use the current obdev code, but for the moment I pretend maximum simplicity, because it's a matter of understanding what I am doing and the simpler the code the easier to understand. Thanks very much for the time you lent me, ulao.
Re: usbFunctionSetup and usbFunctionWrite in action?
I would agree a fresh start is best. A simpler version is always best for the programmer and the help.