This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

DTM UART communication through USB port instead of Tx Rx

Hi everyone!

I am currently working on a custom prototype that is using the nrf52840 chip and sdk 15, and now want to perform DTM tests on the device. Looking at the DTM example code and description, I see that the application uses 2 pins (tx,rx) in order to perform the UART communication. In my case with the custom prototype board that is not possible since we have not included these pins. Is there any other way to perform the UART communication through the USB port instead. One idea that I am currently thinking of is to implement USB CDC and use that instead, does it sound reasonable and/or are there any other easier way to do that?

Would be very thankful for any help I can get!

/Hadi

  • Hi Torbjørn,

    No, I have been using SDK 15.0 only

    I have tried bleoff, tx and rx commands with my code and all of them fail (PC<-->NRF52840 and running a python script). I can see that the port is opening and that a message is sent through the led indications, but all of the commands fail. I tested the code you provided with sdk 14.2, and it works perfectly.  However, when I perform the exact same operations on sdk 15.0, it does not work. 

    I had problems with compiling the application when having the "UART_LEGACY_SUPPORT 1" in the sdk_config.h, get the following error:

    /opt/gcc-arm-none-eabi-8-2019-q3-update/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld: _build/nrf52840_xxaa/nrfx_uarte.c.o: in function `UARTE0_UART0_IRQHandler':
    /home/dek/sdk/nRF5_SDK_15.0.0_a53641a/examples/dtm/direct_test_mode/pca10056/blank/armgcc/../../../../../../modules/nrfx/drivers/src/nrfx_uarte.c:571: multiple definition of `UARTE0_UART0_IRQHandler'; _build/nrf52840_xxaa/nrfx_uart.c.o:/home/dek/sdk/nRF5_SDK_15.0.0_a53641a/examples/dtm/direct_test_mode/pca10056/blank/armgcc/../../../../../../modules/nrfx/drivers/src/nrfx_uart.c:644: first defined here

    I do not know whether this flag in the sdk_config.h might be the problem?

    EDIT: I put some nrf_logs in my cdc event handler, and can see that the port is opened and also performs the tx done. However, the rx done is never executed.

    EDIT 1:35 pm: Through further investigations I have noticed that the "APP_USBD_CDC_ACM_USER_EVT_RX_DONE" event is never called even if data is sent. When I connected to the port with a serial terminal application, I noticed that whatever I send nothing will be received at the DK side

    EDIT 3:30 pm: Changing the UART_LEGACY_SUPPORT to 1, did not resolve the issue and seem to be something else that prevents the application to call APP_USBD_CDC_ACM_USER_EVT_RX_DONE when new data is available

    /Hadi

  • Update 10 Sep:

    I have implemented the DTM example instead in the usb cdc example, hoping that this would solve the problem... Unfortunately, the problem persisted and still does not fire the APP_USBD_CDC_ACM_USER_EVT_RX_DONE when data is sent to the DK. It seems like the problem either is that some configuration need to be changed or that there is some bug somewhere that cause the application to forget to call this specific event. The rest of the events are called directly without any problem, except the APP_USBD_CDC_ACM_USER_EVT_RX_DONE event.

    Update 10 Sep 3:50 pm:

    After some further investigations I finally found the cause of the "problem". The issue seem to be with the buffer of the rx when the data is received. Looking in app_usbd_cdc_acm.c in this function, cdc_acm_endpoint_ev, I notice that in the first switch case for rx:

    if (NRF_USBD_EPOUT_CHECK(p_event->drv_evt.data.eptransfer.ep))
        {
            switch (p_event->drv_evt.data.eptransfer.status)
            {
                case NRF_USBD_EP_OK:
                    ret = cdc_acm_rx_block_finished(p_inst);
                    NRF_LOG_INFO("EPOUT_DATA: %02x done", p_event->drv_evt.data.eptransfer.ep);
                    user_event_handler(p_inst, APP_USBD_CDC_ACM_USER_EVT_RX_DONE);
                    return ret;
                case NRF_USBD_EP_WAITING:
                case NRF_USBD_EP_ABORTED:
                    return NRF_SUCCESS;
                default:
                    return NRF_ERROR_INTERNAL;
            }
        }

    it checks if the buffer is filled, else it won't trigger the event. When I send 1024 bytes of data, the event was fired directly and printed out all of the data.

    My question now is how do I change this in order to continuously receive the data when there is something new sent??? (See answer below!)

    Never mind, found where it is initialized and seem to be when the port is opened and we execute the cdc_read function with the size of our buffer:

    static char m_rx_buffer[NRF_DRV_USBD_EPSIZE * 16]; /*<--64*16 = 1024*/
    
    app_usbd_cdc_acm_read(&m_app_cdc_acm,
                          m_rx_buffer,
                          sizeof(m_rx_buffer));
    
    

    Seem that the DK is expecting to receive 1024 bytes before calling the Rx event, in earlier SDK this was no problem and would call Rx whenever there was new data in the buffer :/

    Is there any way to trigger the rx done event as fast as I receive any data?

    Thanks in advance!

    /Hadi

  • Hi,

    Apparently since SDK 15.0 there is a new function called  app_usbd_cdc_acm_read_any, which calls the rx done whenever there is new data in the buffer. I have now changed to this function, however, my tests still fail when I run my script. I can see that the bytes are received but when the dtm application performs the tx write, nothing is received on the computer side. Also, I tried manually sending some data and seems that the application stops receiving/transmitting any data after the application have sent the last result. (See updated answer below)

    I have attached the most recent code below on dtm+cdc that I am using currently.

    Would really appreciate any help I could get on getting the dtm+cdc application to work

    Update!

    The tests now runs successfully without any problem. I had by mistake changed the rx buffer size to 1 when initializing the variable. I'll upload the code here that works with sdk 15 in case any other would need this in the future...

    cdc_dtm_SDK15.zip

    /Hadi

  • Hi Hadi

    Good to hear you found the issue, and thanks for sharing the code Slight smile

    I will consider the case closed then. 

    Best regards
    Torbjørn

  • Hi Torbjørn

    Sorry to disturb you, I have a question regarding this application that you uploaded. I have tested mine application and yours also, and it seems like it does not work and is not sending any RF signals on either low, mid or high. I have tested with the original dtm application with tx rx and can see that it works and transmits a signal on the right frequency, however, with the modified example it is not transmitting any signal at all. Did you test your application that it was working? Because I couldn't get it to transmit any signals, neither did it work on the sdk 15.0 application that I made. How did you test it if it worked?

    In my application it seems like the problem is when the command is received and then building the uint16_t command, but can't figure out whether it is the cdc read that is the problem or the fifo buffer that is causing this problem.

    Best regards

    Hadi

Related