AnsweredAssumed Answered

F407VG's USB CDC And Getting Data To The PC

Question asked by Workalot on Jan 6, 2016
Latest reply on Jan 12, 2016 by Workalot
Getting a working CDC VCP on the STM32F4DISCOVERY is almost there. Device enumeration, SET/GET_LINE_CODING, SET_CONTROL_LINE_STATE and VCP PC -> STM32 data delivery are in place.

Workalot is stuck on getting VCP PC <- STM32 data and notification transfers. These being EP2 IN bulk transfers and EP1 IN interrupt transfers.

RM0090 rev 10, page 1355 makes for testing reading. Maybe there are translators out there?

Direct register manipulation is practiced rather than using ST's library. To have data emitted on EP2 IN...

USB_OTG_DIEPTSIZx_TypeDef   Diepsiz;
unsigned int                uiRegVal;
 
// RM0090, page 1355.
Diepsiz.d32 = 0;
Diepsiz.b.pktcnt = g_Uotgfs.Ep2.uiInBytesToSend / 64;
if ( g_Uotgfs.Ep2.uiInBytesToSend % 64 )
{
    Diepsiz.b.pktcnt++;
}
else if ( g_Uotgfs.Ep2.uiInBytesToSend )
{
    // Exact multiple of max packet size - IN ZLP???
}
 
Diepsiz.b.xfersize = uiInBytesToSend;
 
UOTGFS->DIEPTSIZ2 = Diepsiz.d32;
 
uiRegVal  = UOTGFS->DIEPCTL2;
uiRegVal |= UOTGFS_DIEPCTLx_SD0PID |  // RM0090, page 1342
       UOTGFS_DIEPCTLx_CNAK   |
       UOTGFS_DIEPCTLx_EPENA;
UOTGFS->DIEPCTL2 = uiRegVal;
 
// Invoke an TXFE interrupt upon which the TXFIFO is loaded
UOTGFS->DIEPEMPMSK |= UOTGFS_DIEPEMPMSK_EP2_IN;


 ... in the TXFE interrupt...

USB_OTG_DIEPTSIZx_TypeDef   Diepsiz;
USB_OTG_DTXFSTSx_TypeDef    Dtxfsts;
unsigned int*               puiSrc;
unsigned int                uiWordsToLoad;
 
Diepsiz.d32 = UOTGFS->DIEPTSIZ2;
uiWordsToLoad = ( Diepsiz.b.xfersize + 3 ) / 4;
 
puiSrc = (unsigned int*)g_Uotgfs.Ep2.pucInSrc;
 
Dtxfsts.d32 = UOTGFS->DTXFSTS2;
 
while ( Dtxfsts.b.ineptfsav )
{
    UOTGFS->DFIFO2 = *puiSrc++;
    uiWordsToLoad--;
 
    if ( 0 == uiWordsToLoad )
    {
        break;
    }
 
    Dtxfsts.d32 = UOTGFS->DTXFSTS2;
}
 
// Update indexers
g_Uotgfs.Ep2.uiInBytesToSend -= Diepsiz.b.xfersize;     // Adjust remaining count
g_Uotgfs.Ep2.pucInSrc += Diepsiz.b.xfersize;            // Advance pointer
 
if ( 0 == g_Uotgfs.Ep2.uiInBytesToSend )
{
    // No more bytes to send no more TXFE interrupts
 
    UOTGFS->DIEPEMPMSK &= ~UOTGFS_DIEPEMPMSK_EP2_IN;   // Disable TXFE interrupts
}


Outcomes