Using custom USB stack in DA1469x SDK

I want to use my own USB stack in DA1469x sdk.

For this purpose I need to implement the following call back function as explained in da1469x platform reference:

Table 47 USB callback functions

Function

Description

hw_usb_ep_rx_read_by_driver()

This function will indicate if the USB driver should read the Rx data or if the Rx data is read by something else.

hw_usb_ep_get_rx_buffer()

This function will be called in order to get a buffer to store the data received.

hw_usb_ep_rx_done()

This function will be called when a receive operation has been completed.

hw_usb_ep_tx_done()

This function will be called when a transmit operation has been completed.

hw_usb_ep_nak()

This function will be called when a NAK has been received for an endpoint.

hw_usb_bus_event()

This function will be called to indicate bus events.

hw_usb_bus_frame()

This function will be called with the current USB frame number.

I successfull set up my project so that I can receive hw_usb_bus_event for RESET and I constantly get call hw_usb_bus_frame function. However when I try to read endpoint 0 I do not get a call for hw_usb_ep_rx_done.

I use usb_cdc example project that is provided in the SDK. 

I used functions 

hw_usb_ep_rx_enable(0) and hw_usb_rx_ep0() within my hw_usb_bus_frame callback. I think I am missing an init or a configuration. Please help me to find the missing piece.

  • HI There,

    Thank you for posting your question online.
    Let me check on this and I will get back to you as soon as possible.

    Kind Regards,
    OV_Renesas

  • Hi There,

    Could you kindly share the source code you have created up until this point?

    Kind Regards,
    OV_Renesas

  • Hi There,

    Please find below our first response on your initial statements:

    As described in the platform reference, a series of callback functions should be realized by the developer so that our USB driver can communicate events to the underlying USB stack or even raise requests e.g. the buffer for a given EP (OUT packets). Typically, these functions are part of the porting layer which is then integrated into the USB stack library. These callback functions are invoked explicitly by the USB low level driver.

    The hw_usb_bus_frame callback function should be called constantly as it reflects the update of the frame counter and thus, the reception of a valid SOF packet on the USB bus.

    The control EP, that is EP0, must always be available to receive packets and so it should first be enabled when the RESET event is detected on the USB bus. Here is a typical framework for the hw_usb_bus_event callback function implementation:

    static void hw_usb_bus_event(HW_USB_BUS_EVENT_TYPE event) {
      switch (event) {
      case UBE_SUSPEND:  
        /* Notify the underlying USB stack library that a suspend event (3 ms) has been reported on the USB bus. */
      	break;
      case UBE_RESUME:  
        /* Notify the underlying USB stack library that a resume event has been reported on the USB bus. */
       	break;
      case UBE_RESET:   
        /* Notify the underlying USB stack library that a resume event has been reported on the USB bus. */
    
        /* Enable the default address (0x0) for the control EP */
        hw_usb_bus_address(0);
        /* Enable receptions for the control EP */
        hw_usb_ep_rx_enable(0);
        break;
      default:
        /* Other actions... */
        break;
      }
    }

    Now, the OUT packets reception is disabled after every data packet is received or when a STALL handshake is returned in response to an OUT token. This condition is applicable to all EPs supported by our USB controller. In addition, the reception of SETUP packets is always enabled.

    Typically, the hw_usb_ep_rx_done callback function should evaluate the concerned EP number and decide whether the RX path should be re-enabled or not. EP0 is bidirectional and so the RX path should only be enabled in SETUP and OUT tokens (DATA and STATUS packets).

    static bool hw_usb_ep_rx_done(uint8_t ep_nr, uint8_t* buffer, uint16_t size) {
    
      if (ep_nr == 0) {
      	 /* Notify the underlying USB stack that a packet has been received and should further be parsed */
    
      	 /* 
      	  * Parse the received packet if necessary and calculate the current and next phase. 
      	  * Then return true if the next phase concerns SETUP or OUT tokens 
      	  * (DATA and STATUS), false otherwise.
      	  */
      } else {
        /* Notify the underlying USB stack that a packet has been received and should further be parsed */
    
      	/* Decide whether the RX path should be re-enabled or not and return true or false respectively */
    }

    We would recommend that the hw_usb_ep_nak callback function is implemented like this:

    static void hw_usb_ep_nak(uint8_t ep_nr) {
      if (ep_nr == 0) {
        hw_usb_ep_disable(USB_EP_DEFAULT, false);
        hw_usb_ep_rx_enable(USB_EP_DEFAULT);
      }
    }

    Typically, the following callback function is left empty. That is:

    static void hw_usb_bus_frame(uint16_t frame_nr) {
    
    }

    As for the usage of hw_usb_rx_ep0 API, it should not be utilized by the developer explicitly as it's invoked by hw_usb_interrupt_handler when an EP0_RX event is reported by the controller and the USB ISR is fired.  

    Last but not least, the hw_usb_ep_get_rx_buffer callback function should return the buffer for a given EP (to store OUT packets). Typically, a memory area is allocated during the initialization of a given EP.

    We hope that gives some hints.

    Kind Regards,
    OV_Renesas

  • Hello,

    Thank you for pointing out the functions to be added. I tried with those functions but it still didn't work.

    However I added the following function and now it works.

    void hw_usb_ep_tx_done(uint8_t ep_nr, uint8_t* buffer){
            if (ep_nr == 0) {
                    hw_usb_ep_rx_enable(0);
                    return;
            }
    }

    I used embox project from github to find this out. 

  • Hi There,

    Thank you for the reply and the feedback.
    Glad you were able to make it work and for sharing your solution on our Engineering Community.
    I have highlighted your answer as suggested, if you want you can verify it so you can help others in the Community as well.
    If you face any other issues, feel free to raise a new ticket.,

    Kind Regards,
    OV_Renesas