Problem when using USBD_VCOM

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Not applicable
Hi,

I want to make the microcontroller to read from an input pin using ADC001 which produces an interrupt on NVIC002, I am also using a timer SYSTM001. Until here everything works fine, the problem starts when I add USBD_VCOM, even I initialize it, when I connect the microcontroller to the computer it cannot be recognized. Should mention that before starting this, I used USBD_VCOM alone in a simple project, and it worked perfectly.

I show you my Main,c file below:

int main(void)
{
// status_t status; // Declaration of return variable for DAVE3 APIs (toggle comment if required)
handle_t timer_1s;
uint32_t timer_1s_status = SYSTM001_ERROR;

DAVE_Init(); // Initialization of DAVE Apps
USBD_VCOM_Init();
ADC001_Init();

//Creating timers
timer_1s = SYSTM001_CreateTimer(1000, SYSTM001_PERIODIC, timer_1s_event, NULL);
if ( timer_1s != 0 ){
//Times is created successfully
SYSTM001_StartTimer(timer_1s);
if( timer_1s_status == DAVEApp_SUCCESS)
{
//Timer started
}
}

//Initialising values
position = 0;
count_1s = 0;
sample_frequency_determined = 0;

/* Generate Load Event*/
ADC001_GenerateLoadEvent(&ADC001_Handle0);

while(1)
{
//Here infinite main loop
}
return 0;
0 Likes
6 Replies
Not applicable
Hi,

Where is the USB management task function "CDC_Device_USBTask(&USBD_VCOM_CDCInterface)"?
You need to loop this function periodically in order for USB to work properly.
0 Likes
Not applicable
I wrote a smaller project to test this feature and it worked properly, even I did not use the function you mentioned, this function sends each second a byte stream composed by 8 bytes through the USB port.

-----------------

void sendString(){
//USBD_VCOM_SendString((const char *)"Hello World");
int8_t message[8];
message[0] = 0x04;
message[1] = 0x04;
message[2] = 0xFF;
message[3] = 0xFF;
message[4] = 0xFF;
message[5] = 0xFF;
message[6] = 0x07;
message[7] = 0x07;
USBD_VCOM_SendData((const char *)message, 8);
}

int main(void)
{
// status_t status; // Declaration of return variable for DAVE3 APIs (toggle comment if required)
handle_t timer_1s;
uint32_t Status = SYSTM001_ERROR;

DAVE_Init(); // Initialization of DAVE Apps
USBD_VCOM_Init();

//Timer1 initialization
timer_1s = SYSTM001_CreateTimer(1000,SYSTM001_PERIODIC, sendString, NULL);
Status = SYSTM001_StartTimer(timer_1s);
if ( Status == DAVEApp_SUCCESS){
//success;
}

while(1)
{

}
return 0;
}


-----------------
This previous and short code works properly, as expected, but now I write you below my target code which is not working, it is the same, but adding the ADC001, and its appropiate functions to make it sample through some pin. When using the previous shown code (the short one), the computer recognizes the microcontroller as COM4, but when using the long code shown below, the computer cannot identify the device the shows the next message: "USB device not recognized, The last USB device you connected to this computer malfunctioned, and Windows does not recognize it" (I already installed the required CDC driver, and it works properly for the previous code, I can watch through a serial terminal the 8-byte stream).
-----------------

/* To store the conversion result */
ADC001_ResultHandleType Result;

double buffer[BUFFER_LENGTH], aux_buffer[BUFFER_LENGTH], out[BUFFER_LENGTH];
int position, count_1s, frequency;
int sample_frequency, sample_frequency_determined;
double aux; //Only for development and debug

// Timer_1s event function
void timer_1s_event(void* Temp){
count_1s += position;
if (sample_frequency_determined < SAMPLING_FREQUENCY_DETERMINATION_TIME){
sample_frequency_determined++;
sample_frequency = count_1s;
}else{ //Send information to the Android Device
int8_t message[8];
//Filling message to send
message[0] = 0x04; //Frame start mark
message[1] = 0x04; //Frame start mark
message[2] = (frequency>>16)&0xFF; //High byte of frequency (can be neglected due to our work range)
message[3] = (frequency>>8)&0xFF; //Middle byte of frequency
message[4] = (frequency)&0xFF; //Low byte of frequency
message[5] = 0; //For future uses
message[6] = 0x07; //Frame end mark
message[7] = 0x07; //Frame end mark
//Sending byte stream
USBD_VCOM_SendData((const char *)message, 8);
}
count_1s = 0;
}

int main(void)
{
// status_t status; // Declaration of return variable for DAVE3 APIs (toggle comment if required)
handle_t timer_1s;
uint32_t timer_1s_status = SYSTM001_ERROR;

DAVE_Init(); // Initialization of DAVE Apps
USBD_VCOM_Init();
ADC001_Init();

//Creating timers
timer_1s = SYSTM001_CreateTimer(1000, SYSTM001_PERIODIC, timer_1s_event, NULL);
if ( timer_1s != 0 ){
//Times is created successfully
SYSTM001_StartTimer(timer_1s);
if( timer_1s_status == DAVEApp_SUCCESS)
{
//Timer started
}
}

//Initialising values
position = 0;
count_1s = 0;
sample_frequency_determined = 0;

/* Generate Load Event*/
ADC001_GenerateLoadEvent(&ADC001_Handle0);

while(1)
{
//Here infinite main loop
}
return 0;
}

/* Global Result Register ISR*/
void GlobalResultEvent(void)
{
/* Read the Result Register*/
if (position < BUFFER_LENGTH){
ADC001_GetResult(&ADC001_Handle0,&Result);
buffer[position] = (double)Result.Result;
position++;
}else{
if (sample_frequency_determined >= SAMPLING_FREQUENCY_DETERMINATION_TIME){
//This function only starts after 1 second, once the sampling frequency has
//been already determined.
ADC001_DisableResultEvt(&ADC001_Handle0);

//Signal processing code starts here
autocorrelation(buffer, aux_buffer, out, BUFFER_LENGTH);
aux = findPeaks(buffer, aux_buffer, BUFFER_LENGTH);
frequency = sample_frequency/aux;
//Signal processing code ends here

ADC001_EnableResultEvt(&ADC001_Handle0);
}
ADC001_GetResult(&ADC001_Handle0,&Result); //Read value because of wait-for-read
count_1s += position;
position = 0;
}
}


-------------
I show you below both S/W App Connectivity views:
780.attach
0 Likes
Not applicable
Hi,

Can you please add in the "CDC_Device_USBTask(&USBD_VCOM_CDCInterface)" to your program and try?
This function basically check the status from the host and update the USB driver to the correct state. That is also why you need to keep looping this function.
Therefore, without running this, the device is not change to the correct state and that could be the reason the Host did not recognize the device.
0 Likes
Not applicable
Hi,

I added this function you told me, but the same problem still remains, if I go to the Windows' device manager, the name of the device is: "Unknown USB Device (Device Descriptor Request Failed)"

int main(void)
{
// status_t status; // Declaration of return variable for DAVE3 APIs (toggle comment if required)
handle_t timer_1s;
uint32_t timer_1s_status = SYSTM001_ERROR;

DAVE_Init(); // Initialization of DAVE Apps
USBD_VCOM_Init();
ADC001_Init();

//Creating timers
timer_1s = SYSTM001_CreateTimer(1000, SYSTM001_PERIODIC, timer_1s_event, NULL);
if ( timer_1s != 0 ){
//Times is created successfully
SYSTM001_StartTimer(timer_1s);
if( timer_1s_status == DAVEApp_SUCCESS)
{
//Timer started
}
}

//Initialising values
position = 0;
count_1s = 0;
sample_frequency_determined = 0;

/* Generate Load Event*/
ADC001_GenerateLoadEvent(&ADC001_Handle0);

USBD_VCOM_SendString((const char *)"Hello World");

while(1)
{
CDC_Device_USBTask(&USBD_VCOM_CDCInterface);
}
return 0;
}
0 Likes
Not applicable
Hi,

It seems the USB device did not respond back to the Host.
Do you have interrupt for your ADC? Is your ADC running in refill mode?
It could be that the ADC interrupt is so fast and periodic that the program did not go into the while loop.
Can you try not generate the load event and see if the USB is working?
0 Likes
Not applicable
Hi Jackson,

You were right, ADC was working by interruptions with a really low period (67ns), now I keep this frequency but I enable the interruptions after 1 second, until what, only the function you provided me is executed. Now everything works properly. Thank you!
0 Likes