USB Stack, bare metal, v4.03, CDC sending FIFO length data to host?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

USB Stack, bare metal, v4.03, CDC sending FIFO length data to host?

Jump to solution
1,013 Views
gigglerg
Contributor II

Hi,

When sending data to host a full FIFO from event USB_APP_DATA_RECEIVED

DataLength=16;     // RX size from host

...

if (USB_Class_CDC_Interface_DIC_Send_Data(USB_COMPOSITE_CONTROLLER_ID,(uint8_t*)&Data[0],DataLength)!=USB_OK) {

     for(;;);     // catch in debugger

}

else {

     Sent=1;

     ZLP=0;

}

The IN transaction is not complete without sending a zero length packet (ZLP).  This is as I understand it normal behaviour.

So in my transmit completion event I have:

...

else if (event_type==USB_APP_SEND_COMPLETE) {

     if (Sent) {

          if (!ZLP) {

               // ZLP on TX fifo, completion of last IN transaction

               if (USB_Class_CDC_Interface_DIC_Send_Data(USB_COMPOSITE_CONTROLLER_ID,NULL,0)!=USB_OK) {

                    for(;;);     // catch in debugger

               }

               ZLP=1;

          }else {

               // ZLP on RX fifo, completion of last OUT transaction, allowing host to begin again sending

               USB_Class_CDC_Interface_DIC_Recv_Data(USB_COMPOSITE_CONTROLLER_ID,NULL,0);

               Sent=0;

          }

     }

}

Here when we get completion of full FIFO sent, we check if we have to ZLP send.  Do it and only then do we free up the receiver.  Like the demo code, it's half duplex because by not sending ZLP on RX FIFO no more data comes in from host.

Thing is, it's flaky, sometimes works, sometimes does not and hangs.  I have not checking status of sending USB_Class_CDC_Interface_DIC_Recv_Data, should I?

Also it is not clear, do we get USB_APP_SEND_COMPLETE events on ZLP sending on both IN and OUT transactions since both are in a send, albeit of zero data in the data stage of transaction or in the receive the ack - I think?

I am trying to make the USB interface completely interrupt driven, but the biggest issue I have is that the callback to receive data is from the USB ISR as:

static CLASS_APP_CALLBACK_STRUCT callback = {

     .composite_class_callback =CDCApp_Class_Callback,

     .vendor_req_callback =NULL,

     .param_callback = CDCApp_PSTN_Notify_Callback,

     .param_specific_callback =NULL,

};

if we get a completion event, we send some more data but ... If one of the USB_Send... function calls come back as BUSY, I can't do anything, that results in no completion event because we could not initiate a send and the thing hangs.  I think also that is why you are doing things in half duplex mode, trying to ensure resources are free to use.  That is fine for a demo but not representative of any real world application.

I cannot use MQX because it does not support composite devices, I cannot block because of legacy code in our application connecting to hardware on PCB so calling it from main loop is not possible.

I have to say, I've used Atmel's free stack which is also what you could call bare metal for a number of years and have never had the amount of trouble I'm having with Freescale's implementation.

Regards,

dc

1 Solution
649 Views
gigglerg
Contributor II

I've written a PC program to repeatedly connect and dump variable length data ranging from 256 to 4096bytes, reading them back like the echo demo.  If the port opens OK without error, sometimes it does error, covered in another post I made today.

What I've found is that most of the time when sending from firmware so responding to host IN transactions complete, however 1 in 50 or there about's (read as random) finish in firmware but the host is missing data.  If you look at the firmware in the debugger, my buffer rx/tx counts are equal yet still some data is missing at PC host.

So I've changed the firmware code to *always* send data less than 1 FIFO and so far it's working.  I'd say the fixes from 402 to 403 for ZLP by the driver code in usb_dci_kinetis.c are not working correctly for K60.  It is certainly better than 402 but still very buggy.

dc

View solution in original post

3 Replies
650 Views
gigglerg
Contributor II

I've written a PC program to repeatedly connect and dump variable length data ranging from 256 to 4096bytes, reading them back like the echo demo.  If the port opens OK without error, sometimes it does error, covered in another post I made today.

What I've found is that most of the time when sending from firmware so responding to host IN transactions complete, however 1 in 50 or there about's (read as random) finish in firmware but the host is missing data.  If you look at the firmware in the debugger, my buffer rx/tx counts are equal yet still some data is missing at PC host.

So I've changed the firmware code to *always* send data less than 1 FIFO and so far it's working.  I'd say the fixes from 402 to 403 for ZLP by the driver code in usb_dci_kinetis.c are not working correctly for K60.  It is certainly better than 402 but still very buggy.

dc

649 Views
Monica
Senior Contributor III

Thanks for sharing solution with us, Giggler.

Awesome job!

Regards

0 Kudos
649 Views
gigglerg
Contributor II

Can you confirm v403 of bare metal stack now handles ZLP on data transfers.  I have removed my code to explicitly handle them that were used with 402 and it now seems to function sending full length FIFO's on the CDC data pipe.

Diffing usb_dci_kinetis.c, the driver for the device I am using, I notice its got significant changes to 402.

Regards,

dc

0 Kudos