Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

USB CCID class with nordic nRF52840

I am developing USB CCID driver class for nordic nRF52840. I used USB CDC-ACM class as reference and tried to implement for USB CCID. I have developed the device descriptor for it.

USB CCID class has 1 interface and 3 endpoints(1 for interrupt, 1 for bulk IN and 1 for bulk OUT). Now the windows is detecting as Microsoft Usbccid smart card reader(WUDF)

In modify the app_usbd_ccid_internal.h, i need to know modification to be done in 

1. class instance data (app_usbd_ccid_inst_t)

2. CCID class specific request handled via control endpoint (app_usbd_ccid_req_t)

3.  ccid context (app_usbd_ccid_ctx_t)

I have attached my app_usbd_ccid_internal.h file with tis for refrence.

app_usbd_ccid_internal.h

Parents Reply Children
  • Hi,

    Thanks for your response.

    Can you specify your answer more clearly where i can refer in the cdc code for receive the data from endpoint.

    For example, to send the data in endpoint(EP0), i use the following code,

    ret_code_t ret;
    nrf_drv_usbd_transfer_t transfer =
    {
       .p_data = {.tx = p_data},
       .size = size
    };
    ret = nrf_drv_usbd_ep_transfer(NRF_DRV_USBD_EPIN0, &transfer);

    As per your above statement, once the NRF_DRV_USBD_EVT_EPTRANSFER event is generated, it calls cdc_acm_endpoint_ev where the type of endpoint is check.

    If it is bulkout endpoint, cdc_acm_rx_block_finished is called once the NRF_USBD_EP_OK is OK.

    But i need to know how to copy the data from the endpoint.

  • Hi,

      

    Mohammad said:
    ret = nrf_drv_usbd_ep_transfer(NRF_DRV_USBD_EPIN0, &transfer);

    In that function, you check if it is IN or OUT direction, based on the EP.

    In the case of the cdc_acm, it uses the app_usbd_ep_handled_transfer(), which schedules a callback just prior to when the transfer is to occur, as per the header documentation in nrfx_usbd.h:

    /**
     * @brief Start sending data over the endpoint using the transfer handler function.
     *
     * This function initializes an endpoint transmission.
     * Just before data is transmitted, the transfer handler
     * is called and it prepares a data chunk.
     *
     * @param[in] ep        Endpoint number.
     *                      For an IN endpoint, sending is initiated.
     *                      For an OUT endpoint, receiving is initiated.
     * @param[in] p_handler Transfer handler - feeder for IN direction and consumer for
     *                      OUT direction.
     *
     * @retval NRFX_SUCCESS             Transfer queued or started.
     * @retval NRFX_ERROR_BUSY          Selected endpoint is pending.
     * @retval NRFX_ERROR_INVALID_ADDR  Unexpected transfer on EPIN0 or EPOUT0.
     */
    nrfx_err_t nrfx_usbd_ep_handled_transfer(nrfx_usbd_ep_t ep,
                                             nrfx_usbd_handler_desc_t const * p_handler);

    You can also fetch this using app_usbd_ep_transfer() (for both directions, filtered on the input EP).

      

    Mohammad said:

    If it is bulkout endpoint, cdc_acm_rx_block_finished is called once the NRF_USBD_EP_OK is OK.

    But i need to know how to copy the data from the endpoint.

      That specific function has CDC specific buffering logic, which makes it complicated wrt. where the USB data is read. It's essentially the call to "app_usbd_ep_handled_transfer" that handles it. The rest is buffer logic.

     

    Kind regards,

    Håkon

  • Hi,

    Thanks for your reply.

    Now i can send and receive the data through the endpoints.

    I have tested the following CCID message functions working good

    PC_TO_RDR_GETSLOTSTATUS
    PC_TO_RDR_ICCPOWERON
    PC_TO_RDR_ICCPOWEROFF

    RDR_to_PC_DataBlock
    RDR_to_PC_SlotStatus
    RDR_to_PC_NotifySlotChange

    But i have problem that the program stucks in infinte loop at this part

    while (app_usbd_event_queue_process())
    {
    /* Nothing to do */
    }

    Help me to solve this issue.

    Ouput:

    <info> app: USBD CCID example started.
    <info> usbd_ccid: ccid_event_handler = 11
    <info> app: USB power detected
    <info> usbd_ccid: ccid_event_handler = 8
    <info> app: USB ready
    <info> usbd_ccid: ccid_event_handler = 10
    <info> usbd_ccid: ccid_event_handler = 15
    <info> usbd_ccid: ccid_event_handler = 13
    <info> usbd_ccid: ccid_event_handler = 2
    <info> usbd_ccid: ccid_event_handler = 3
    <info> usbd_ccid: ccid_event_handler = 15
    <info> usbd_ccid: ccid_event_handler = 1
    <info> usbd_ccid: ccid_event_handler = 1
    <info> usbd_ccid: ccid_event_handler = 15
    <info> usbd_ccid: ccid_event_handler = 5
    <info> usbd_ccid: setup_event_handler
    <info> usbd_ccid: setup_req_std_in
    <info> usbd_ccid: NRF_ERROR_NOT_SUPPORTED
    <info> usbd_ccid: ccid_event_handler = 15
    <info> usbd_ccid: ccid_event_handler = 6
    <info> usbd_ccid: ccid_endpoint_ev
    <info> usbd_ccid: Current EP address = 0x2
    <info> usbd_ccid: NRF_USBD_EP_WAITING
    <info> usbd_ccid: Length of the data received = 10
    <info> usbd_ccid: CCID Message type = 65 and bseq = 1
    <info> usbd_ccid: PC_TO_RDR_GETSLOTSTATUS
    <info> usbd_ccid: OK = 0
    <info> usbd_ccid: EPOUT_DATA: 02 done
    <info> usbd_ccid: ------------------------
    <info> usbd_ccid: ccid_event_handler = 6
    <info> usbd_ccid: ccid_endpoint_ev
    <info> usbd_ccid: Current EP address = 0x2
    <info> usbd_ccid: Length of the data received = 10
    <info> usbd_ccid: CCID Message type = 81 and bseq = 1
    <info> usbd_ccid: OK = 1
    <info> usbd_ccid: EPOUT_DATA: 02 done
    <info> usbd_ccid: ------------------------
    <info> usbd_ccid: ccid_event_handler = 6
    <info> usbd_ccid: ccid_endpoint_ev
    <info> usbd_ccid: Current EP address = 0x82
    <info> usbd_ccid: EPIN_DATA: 82 done
    <info> usbd_ccid: RDR_to_PC_NotifySlotChange = 50, 03
    <info> usbd_ccid: ------------------------
    <info> usbd_ccid: ccid_event_handler = 6
    <info> usbd_ccid: ccid_endpoint_ev
    <info> usbd_ccid: Current EP address = 0x81
    <info> usbd_ccid: EPIN_CON: notify
    <info> usbd_ccid: EPIN_CON: 81 done
    <info> usbd_ccid: ------------------------
    <info> usbd_ccid: ccid_event_handler = 6
    <info> usbd_ccid: ccid_endpoint_ev
    <info> usbd_ccid: Current EP address = 0x2
    <info> usbd_ccid: Length of the data received = 10
    <info> usbd_ccid: CCID Message type = 63 and bseq = 2
    <info> usbd_ccid: PC_TO_RDR_ICCPOWEROFF
    <info> usbd_ccid: OK = 0
    <info> usbd_ccid: EPOUT_DATA: 02 done
    <info> usbd_ccid: ------------------------
    <info> usbd_ccid: ccid_event_handler = 6
    <info> usbd_ccid: ccid_endpoint_ev
    <info> usbd_ccid: Current EP address = 0x82
    <info> usbd_ccid: EPIN_DATA: 82 done
    <info> usbd_ccid: ------------------------
    <info> usbd_ccid: ccid_event_handler = 6
    <info> usbd_ccid: ccid_endpoint_ev
    <info> usbd_ccid: Current EP address = 0x2
    <info> usbd_ccid: Length of the data received = 10
    <info> usbd_ccid: CCID Message type = 62 and bseq = 3
    <info> usbd_ccid: PC_TO_RDR_ICCPOWERON
    <info> usbd_ccid: OK = 0
    <info> usbd_ccid: EPOUT_DATA: 02 done
    <info> usbd_ccid: ------------------------
    <info> usbd_ccid: ccid_event_handler = 6
    <info> usbd_ccid: ccid_endpoint_ev
    <info> usbd_ccid: Current EP address = 0x82
    <info> usbd_ccid: EPIN_DATA: 82 done
    <info> usbd_ccid: ------------------------
    <info> usbd_ccid: ccid_event_handler = 6
    <info> usbd_ccid: ccid_endpoint_ev
    <info> usbd_ccid: Current EP address = 0x2
    <info> usbd_ccid: Length of the data received = 10
    <info> usbd_ccid: CCID Message type = 63 and bseq = 4
    <info> usbd_ccid: PC_TO_RDR_ICCPOWEROFF
    <info> usbd_ccid: OK = 0
    <info> usbd_ccid: EPOUT_DATA: 02 done
    <info> usbd_ccid: ------------------------
    <info> usbd_ccid: ccid_event_handler = 6
    <info> usbd_ccid: ccid_endpoint_ev
    <info> usbd_ccid: Current EP address = 0x82
    <info> usbd_ccid: EPIN_DATA: 82 done
    <info> usbd_ccid: ------------------------
    <info> usbd_ccid: ccid_event_handler = 6
    <info> usbd_ccid: ccid_endpoint_ev
    <info> usbd_ccid: Current EP address = 0x2
    <info> usbd_ccid: Length of the data received = 10
    <info> usbd_ccid: CCID Message type = 62 and bseq = 5
    <info> usbd_ccid: PC_TO_RDR_ICCPOWERON
    <info> usbd_ccid: OK = 0
    <info> usbd_ccid: EPOUT_DATA: 02 done
    <info> usbd_ccid: ------------------------
    <info> usbd_ccid: ccid_event_handler = 6
    <info> usbd_ccid: ccid_endpoint_ev
    <info> usbd_ccid: Current EP address = 0x82
    <info> usbd_ccid: EPIN_DATA: 82 done
    <info> usbd_ccid: ------------------------
    <info> usbd_ccid: ccid_event_handler = 6
    <info> usbd_ccid: ccid_endpoint_ev
    <info> usbd_ccid: Current EP address = 0x2
    <info> usbd_ccid: Length of the data received = 10
    <info> usbd_ccid: CCID Message type = 63 and bseq = 6
    <info> usbd_ccid: PC_TO_RDR_ICCPOWEROFF
    <info> usbd_ccid: OK = 0
    <info> usbd_ccid: EPOUT_DATA: 02 done
    <info> usbd_ccid: ------------------------
    <info> usbd_ccid: ccid_event_handler = 6
    <info> usbd_ccid: ccid_endpoint_ev
    <info> usbd_ccid: Current EP address = 0x82
    <info> usbd_ccid: EPIN_DATA: 82 done
    <info> usbd_ccid: ------------------------
    <info> usbd_ccid: ccid_event_handler = 6
    <info> usbd_ccid: ccid_endpoint_ev
    <info> usbd_ccid: Current EP address = 0x2
    <info> usbd_ccid: Length of the data received = 10
    <info> usbd_ccid: CCID Message type = 62 and bseq = 7
    <info> usbd_ccid: PC_TO_RDR_ICCPOWERON
    <info> usbd_ccid: OK = 0
    <info> usbd_ccid: EPOUT_DATA: 02 done
    <info> usbd_ccid: ------------------------
    <info> usbd_ccid: ccid_event_handler = 6
    <info> usbd_ccid: ccid_endpoint_ev
    <info> usbd_ccid: Current EP address = 0x82
    <info> usbd_ccid: EPIN_DATA: 82 done
    <info> usbd_ccid: ------------------------
    <info> usbd_ccid: ccid_event_handler = 5
    <info> usbd_ccid: setup_event_handler
    <info> usbd_ccid: setup_req_std_in
    <info> usbd_ccid: NRF_ERROR_NOT_SUPPORTED
    <info> usbd_ccid: ccid_event_handler = 5
    <info> usbd_ccid: setup_event_handler
    <info> usbd_ccid: setup_req_std_in
    <info> usbd_ccid: NRF_ERROR_NOT_SUPPORTED
    <info> usbd_ccid: ccid_event_handler = 5
    <info> usbd_ccid: setup_event_handler
    <info> usbd_ccid: setup_req_std_in
    <info> usbd_ccid: NRF_ERROR_NOT_SUPPORTED

  • Hi,

     

    Mohammad said:
    <info> usbd_ccid: ccid_event_handler = 5
    <info> usbd_ccid: setup_event_handler
    <info> usbd_ccid: setup_req_std_in
    <info> usbd_ccid: NRF_ERROR_NOT_SUPPORTED

     What is '5' in this case? Is that the p_event->app_evt.type? If yes, then that is the setup APP_USBD_EVT_DRV_SETUP, which should handle class specific requests. I do not have extensive knowledge about CCID, unfortunately, so I cannot state what should be implemented for this specific USB class.

     

    Mohammad said:
    But i have problem that the program stucks in infinte loop at this part

    while (app_usbd_event_queue_process())
    {
    /* Nothing to do */
    }

     Is it stuck inside there, or just not processing any events? It sounds like there's some CCID specific events that are not implemented?

     

    Kind regards,

    Håkon

  • Hi,

    Yes, it is  p_event->app_evt.type.

    NRF_LOG_INFO("ccid_event_handler = %d", p_event->app_evt.type);

     Is it stuck inside there, or just not processing any events? It sounds like there's some CCID specific events that are not implemented?

    Yes, it processes the events.

Related