coolestDisplayName
coolestDisplayName

Reputation: 171

Confused with output to console, C / USB CDC / PIC18F2550

I have a problem that is probably a simple misunderstanding on my end. I have a PIC18F2550 device with a USB CDC firmware. I would like to send it a command to output something to the console every second. However, it doesn't seem to work. I put in a loop to iterate for 5 seconds and display an output message every second, but it won't actually output anything. It passes through the 5 second loop until the end where it DOES display the final message after the loop was executed. It won't output anything DURING the loop though.

I included my entire ProcessIO function because I think it's important for this issue, but I commented where I placed the exact command I'm trying to figure out.

Thanks for any suggestions you guys have, I appreciate it. I'm a mechanical engineer trying to learn some embedded stuff.

/********************************************************************
* Function:        void ProcessIO(void)
* Overview:        This function is a place holder for other user
*                  routines. It is a mixture of both USB and
*                  non-USB tasks.
*******************************************************************/
void ProcessIO(void)
{
BYTE numBytesRead;

// User Application USB tasks
if((USBDeviceState < CONFIGURED_STATE)||(USBSuspendControl==1)) return;

if (USBUSARTIsTxTrfReady())
{
    if((CDCattached == 0x01) && (CDCattachedcount == 2))
    {
        putUSBUSART((char*)"Text Message\r\n",49);
        CDCTxService();
        CDCattachedcount = 0;
        CDCattached = 0x00;
    }
    numBytesRead = getsUSBUSART(USB_Out_Buffer, 64);
    if (numBytesRead == 1)
    {
        if ((USB_Out_Buffer[0] == '\r'))                      //Received ENTER? Ues-> End of Command
        {
            if (pos >0)
            {
                command_recvd = 0x01;
                Command[pos++] = '\0';
                pos = 0;
            }
        }
        else if ((USB_Out_Buffer[0] == 0x7F) || (USB_Out_Buffer[0] == 0x08))
        {
            if (pos > 0) pos--;
            Command[pos] = '\0';
            putUSBUSART ((char*) USB_Out_Buffer, 1);
        }
        else
        {
            Command[pos++] = USB_Out_Buffer[0];
            putUSBUSART((char*) USB_Out_Buffer, 1);
            Command[pos]='\0';
        }       //No:- Store Character to String
    }
    else if ((numBytesRead > 1))
    {
        strncpy(Command,USB_Out_Buffer,numBytesRead);
        for(int indx = numBytesRead; indx < 64; indx++)
        {
            Command[indx]='\0';
        }
        pos = numBytesRead--;
        command_recvd = 0x01;
        Command[pos++] = '\0';
        // putUSBUSART((char*) USB_Out_Buffer, 1);
        pos = 0;
    }

    if (command_recvd == 0x01)
    {
        for (int aaa = 0; aaa <= 63; aaa++)
        {
            output_message[aaa]= '\0';
        }


************** THIS IS WHERE MY TEST COMMAND IS ***************

        if (strnicmp((char*) Command, (char*) "test", 4) == 0)
        {
            sprintf(output_message, "\r\nStarting loop...\r\n");
            for int bbb = 0; bbb < 5; bbb++)
            {
                sprintf(output_message, "\r\nLooping...\r\n");
                for (delayIndex = 0; delayIndex < 1000; delayIndex++)
                {
                     __delay_ms(1);
                }
            }
            sprintf(output_message, "\r\nLoop finished!\r\n");
        }
        else
        {
            invalidCommand:
            sprintf(output_message, "\r\nInvalid Command Received. Please Retry.\r\n\0");
        }
        command_recvd = 0x00;
    }
}
CDCTxService();
}

Upvotes: 0

Views: 970

Answers (2)

Smasho
Smasho

Reputation: 1180

You should call putUSBUSART() and CDCTxService() before overwriting output_message Also, CDCTxService() needs to be called frequently, so you have to call it during the delay loop.

        for int bbb = 0; bbb < 5; bbb++)
        {
            sprintf(output_message, "\r\nLooping...\r\n");
            putsUSBUSART(output_message);

            for (delayIndex = 0; delayIndex < 1000; delayIndex++)
            {
                 __delay_ms(1); 

                 if(USBUSARTIsTxTrfReady()) {
                      sprintf(output_message, "\r\nInside inner loop\r\n");
                      putsUSBUSART(output_message);
                 }
                 CDCTxService();
            }
        }

Although that kind of bloking delays could work ( __delay_ms() ), a better aproach is to check for an ellapsed timer, or a timestamp. Something like:

        for int bbb = 0; bbb < 5; bbb++)
        {
            sprintf(output_message, "\r\nLooping...\r\n");
            putsUSBUSART(output_message);

            timestamp = TickGet(); 
            while (TickDiff(timestamp, TickGet()) < TICK_SECOND)
            {
                 if(USBUSARTIsTxTrfReady()) {
                      sprintf(output_message, "\r\nInside inner loop\r\n");
                      putsUSBUSART(output_message);
                 }
                 CDCTxService();
            }
        }

TickGet and TickDiff are functions you have to implement yourself, however there are lots of examples on Microchip libraries

Upvotes: 1

user149341
user149341

Reputation:

Short version: this approach won't work. You'll need to rethink how you're doing this.

USB devices cannot delay while processing events — they must be able to respond promptly to every request sent from the host. Delaying for as long as a second will typically cause the host to assume the device has been disconnected.

It's critical to understand here that the USB device model is based (almost) entirely around the host sending requests to a device, and the device replying. Devices cannot generate unsolicited responses.

Now, the reason you're not seeing the expected results here is because sprintf() doesn't send the results to the host; all it does is put a message into a buffer to prepare it to be sent back. Calling it multiple times overwrites that buffer, rather than sending multiple messages back.

Upvotes: 0

Related Questions