2019-03-27 10:26 AM
I managed to get an old version of the USB CDC/VCP SPl library working
https://www.st.com/en/embedded-software/stsw-stm32046.html and modified the VCP example to send/receive data to a PC via USB serial port. I edited syscalls.c so that the printf() function sends data to the USB.
It all works well if the PC is connected to my board and I have a USB serial session open in, say, PuTTY. If there's no connection, though, the USB buffer fills immediately and the code stops executing, until a new USB Serial session is opened. Which is usually desirable, since it will prevent missing characters if too much data is sent at once and the USB serial port is still catching up. But if I want to use the USB serial port as a debug print, it must work if connected or not
How can I determine programmatically if the USB serial port is opened ? I know how to determine if the USB is connected to the PC or not, but that's not enough, since the board is also powered by USB, and always connected to a PC, even if the serial port is not open
I could not find a status function nor a register to read, and I got lost in the nested interrupts handling trying to figure out where to set a global flag. Thanks in advance for any suggestion
2019-03-28 01:00 AM
Hi,
What you can do is to have a global flag that is set when the serial port settings are modified. Usually upon opening the port, the PC soft will set the baudrate, parity, etc... When your code goes through this section you know that the serial port has been opened.
I don't remember at the moment if there is a way to know when the port is closed.
2019-03-28 03:17 PM
Thanks Kraal for the answer. I actually just tried your suggestion, but it only partially helps, unfortunately.
I just tried instrumenting the VCP_Ctrl() function, and upon connecting the USB cable to a Windows PC, the sequence of commands received is:
GET_LINE_CODING - SET_CONTROL_LINE_STATE - SET_LINE_CODING - GET_LINE_CODING
Upon connecting PuTTY, I get
4x GET_LINE_CODING - SET_LINE_CODING - GET_LINE_CODING - SET_CONTROL_LINE_STATE - SET_LINE_CODING - GET_LINE_CODING
I guess I could build a state machine that sets a flag based on that sequence, but I fear it would be pretty specific to a version of PuTTY, and might not work for other terminal apps. The fact that Windows sends the same commands upon USB connection makes it a bit unreliable
On the other hand, I found a way to achieve what I wanted: a way to printf() via the USB that works even if the USB is not connected to a terminal application. I was using this version of the VCP/USB library http://vedder.se/2012/07/usb-serial-on-stm32f4/ because the newest ST version doesn't work for me. It turns out that along the way, ST managed to solve the blocking issue, by masking the FIFOempty interrupt flag in the FIFO writing function. Here's the relevant portion, from the usb_dcd_int.c file:
static uint32_t DCD_WriteEmptyTxFifo(USB_OTG_CORE_HANDLE *pdev, uint32_t epnum)
{
USB_OTG_DTXFSTSn_TypeDef txstatus;
USB_OTG_EP *ep;
uint32_t len = 0;
uint32_t len32b;
txstatus.d32 = 0;
uint32_t fifoemptymsk; // added to unblock
ep = &pdev->dev.in_ep[epnum];
len = ep->xfer_len - ep->xfer_count;
if (len > ep->maxpacket)
{
len = ep->maxpacket;
}
len32b = (len + 3) / 4;
txstatus.d32 = USB_OTG_READ_REG32( &pdev->regs.INEP_REGS[epnum]->DTXFSTS);
while (txstatus.b.txfspcavail > len32b &&
ep->xfer_count < ep->xfer_len &&
ep->xfer_len != 0)
{
/* Write the FIFO */
len = ep->xfer_len - ep->xfer_count;
if (len > ep->maxpacket)
{
len = ep->maxpacket;
}
len32b = (len + 3) / 4;
USB_OTG_WritePacket (pdev , ep->xfer_buff, epnum, len);
ep->xfer_buff += len;
ep->xfer_count += len;
txstatus.d32 = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[epnum]->DTXFSTS);
/* Mask the TxFIFOEmpty interrupt */ //added to unblock
if (ep->xfer_len == ep->xfer_count)
{
fifoemptymsk = 0x1 << ep->num;
USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK,
fifoemptymsk, 0);
} // added to unblock
}
return 1;
}
this way I can just printf() and if the terminal is connected, it prints, if not, just discards the buffer and keeps running
I need to understand why the new USB library doesn't work for me, but right now I'm unblocked even using the older version