Question
F407VG's USB CDC And Getting Data To The PC
Posted on January 06, 2016 at 07:15
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 1
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
}