USB Echo

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

I'm working on USB CDC on ATSAMD21. The code which i'm using is ATMEL START example for USB CD Echo on D21. I'm working on atmel studio

 

Requirement:

In my application the host send data to the device and i need to read that data and send back different data to the host from different function.

Here in echo example the data reception and transfer is using the call back.

 

Example Echo program is working fine.

Then i tried to send the data via USB from some other function and its not working

 

The read function in call back is working fine and iam getting the data populated in buff

 

/**
 * \brief USB CDC ACM Function Read Data
 */
int32_t cdcdf_acm_read(uint8_t *buf, uint32_t size)
{
    if (!cdcdf_acm_is_enabled()) {
        return ERR_DENIED;
    }
    return usbdc_xfer(_cdcdf_acm_funcd.func_ep_out, buf, size, false);
}

 

 

The write function

/**
 * \brief USB CDC ACM Function Write Data
 */
int32_t cdcdf_acm_write(uint8_t *buf, uint32_t size)
{
    if (!cdcdf_acm_is_enabled()) {
        return ERR_DENIED;
    }
    return usbdc_xfer(_cdcdf_acm_funcd.func_ep_in[CDCDF_ACM_DATA_EP_INDEX], buf, size, true);
}

 

 

As you see below The wite function inside the if statement is not working but the same function outside the if statement working , I also debugged whether it is going inside if statement and its going also, when i call the write functionn from different function  its not working ,

 

void cdcd_acm_example(void)
{
    while (!cdcdf_acm_is_enabled()) {
        // wait cdc acm to be installed
    };

    

    adc_sync_enable_channel(&ADC_0, 0);
        

    cdcdf_acm_register_callback(CDCDF_ACM_CB_STATE_C, (FUNC_PTR)usb_device_cb_state_c);

    while (1) {
        //adc_sync_read_channel(&ADC_0, 0, buffer, 2);
        if ((uint8_t *)usbd_cdc_buffer[0] == 8356097)
        {
            adc_read_func();
            _adc_sync_set_inputs(&ADC_0, ADC_INPUTCTRL_MUXPOS_PIN4, ADC_INPUTCTRL_MUXNEG_GND, 0);
                      
              adc_sync_read_channel(&ADC_0, 0, buffer, 2);
                      
            cdcdf_acm_write((uint8_t *)buffer, 2);   // Not working
            

        }
            
        cdcdf_acm_write((uint8_t *)buffer, 2);  //Working
    }
}

 

 

When i tried to debug and go by satement by statementit worked, i thought it might be delay issue but even after giving delay it dint work.

 

Can any one help me with this

Revanth A

Last Edited: Tue. Jun 18, 2019 - 08:20 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am having a similar problem. I am making USB Vendor using SAME70-Xplained board.

The problem is that I have an older working project, but when I try to implement the USB vendor in a separate solution it does odd things:

the buffer corrupts and sends '\0' string, if I am trying to manipulate buffer data and send back a different response instead of echo.

 

The difference between two projects is ASF version (older uses 3.38 and now I am using 3.46)

 

I am using PC to connect to the device. PC is sending "Device Status request" and is supposed to receive "Running" as a response.

 

 

When running the code bellow, PC receives: "Device Status Request" (echo)

When uncommenting two lines in main_vendor_int_out_received, PC receives: "Device S".

 

 

 

This code is made following Atmel AVR4901: ASF - USB Vendor Class Application document (pg. 10) 

http://ww1.microchip.com/downloads/en/appnotes/doc8481.pdf

 

 

#include <asf.h>
#include <string.h>

uint8_t _global_data[1000];

static bool my_flag_autorize_vendor_transfert = false;
void main_vendor_int_out_received(udd_ep_status_t status, iram_size_t nb_transfered);
void main_vendor_int_in_received(udd_ep_status_t status, iram_size_t nb_transfered);


int main (void)
{
    /* Insert system clock initialization code here (sysclk_init()). */

    sysclk_init();
    irq_initialize_vectors();
    
    cpu_irq_enable();
    board_init();
    /* Insert application code here, after the board has been initialized. */
    udc_start();	
}

void user_callback_vbus_action(bool b_vbus_high)
{
    udc_attach();
}

bool my_callback_vendor_enable(void)
{
    my_flag_autorize_vendor_transfert = true;
    bool result = udi_vendor_bulk_out_run(_global_data, 1000, &main_vendor_int_out_received);

    return true;
}
void my_callback_vendor_disable(void)
{
    my_flag_autorize_vendor_transfert = false;
}
// When a OUT data is received, then send this data on IN 
void main_vendor_int_out_received(udd_ep_status_t status, iram_size_t nb_transfered)
{
    if (UDD_EP_TRANSFER_OK != status) {
        return; // Tranfert aborted, then stop loopback
    }
    
    // Send on IN endpoint the data received on endpoint OUT
    
        //memcpy( _global_data, "Running\0", 9);      //NOT working
        //if(strcmp(_global_data, "Running\0") == 0)  //NOT working
        {
            bool result = udi_vendor_bulk_in_run(&_global_data,  (uint32_t)(strlen((char *)_global_data) + 2), &main_vendor_int_in_received);
        }
}

// When a IN data has been sent, then the OUT transfer is enabled again 
void main_vendor_int_in_received(udd_ep_status_t status, iram_size_t nb_transfered)
{
    if (UDD_EP_TRANSFER_OK != status) {
            return; // Tranfert aborted, then stop loopback
    }
        //ui_loop_back_state(false);
        // Wait a full buffer
        bool result = udi_vendor_bulk_out_run(_global_data,	sizeof(_global_data),	&main_vendor_int_out_received);
}

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@rev3005 

1. You have to step over up to the line   cdcdf_acm_write((uint8_t *)buffer, 2);       inside if() loop

If you don't get there - trace down what happened in ADC routines ...

2. if you get there an it does not work, that means the interrupt needed for the USB transfer does not work - possible collision of the interrupt handling of ADC routines preventing calls to the USB CDC interrupts handlers