Using USB CDC to control program flow on E70/V71

Go To Last Post
2 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi all,

I am trying to pass a string (possibly quite a long string) to the E70 using a COM port via the USB connection for the purpose of controlling program flow of the E70 from a PC. As far as I can tell, the simplest way to do this is using the USB CDC protocol and I am using the ASF example to try and understand how this works.

 

I am able to get the example project to work with the two terminal windows echoing the input.

 

Up to a point, I am able to follow the example and I can see that the data is being processed by various functions in udi_cdc.c. However, this all seems to be occurring in the USART ISR (which is in uart_sam.c), even when the data is coming in through the USB port.

 

So my questions are:

  1. Where the USB data is coming in – i.e. what register(s) does this data occupy?
  2. How is the USART ISR being triggered by the USB?
  3. It also appears that the data is coming in one character at a time. How would one best go about sending, for example, 1000 characters to the E70? Individually processing each one doesn’t feel right, but I think if the data is coming into some register then the DMA can probably be used quite efficiently.
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The example is indeed driven by the usart ISR and as such not typical for cdc usage. But you can modify it, remove the uart integration (the uart_open and uart_close calls at least) and you can test a main loop that collects data 

int main(void)
{

    irq_initialize_vectors();
    cpu_irq_enable();

    // Initialize the sleep manager
    sleepmgr_init();

#if !SAM0
    sysclk_init();
    board_init();
#else
    system_init();
#endif
    ui_init();
    ui_powerdown();

    // Start USB stack to authorize VBus monitoring
    udc_start();

    char buf[4000];
    size_t bufPos = 0;
    while (true) {
        if (!main_b_cdc_enable) {
            continue;
        }
        iram_size_t nRead = udi_cdc_read_no_polling(buf + bufPos, sizeof(buf) - 1 - bufPos);
        if (nRead > 0) {
            bufPos += nRead;
            if (buf[bufPos-1] == '\n' || bufPos >= sizeof(buf) - 1) {
                buf[bufPos] = '\0';
                // do something with the buffer, sending it back like this
                // is not recommended, it could starve the receive
                udi_cdc_write_buf(buf, bufPos);
                bufPos = 0;
	    }
        }
    }
}

Focus on the udi_cdc_ API functions and you probably don't need to know how actually USB data is coming in. There is buffering (nRead will be up to 64 if I send a file to the above).

/Lars