cancel
Showing results for 
Search instead for 
Did you mean: 

F407VG's USB CDC And Getting Data To The PC

Workalot
Associate III
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
}

1 REPLY 1
Workalot
Associate III
Posted on January 12, 2016 at 10:04

Workalot's Travail, Workalot's Prevail.

No prevail (just yet) - still stuck on EP2 bulk IN transfers.

The behaviour being observed is that on a cyclic call (every second) to output a short CDC/VCP data packet (20 bytes), the data is being loaded into the Tx FIFO (done at TXFE interrupt), and is observed as being present at 0x50020300 (Tx FIFO2's RAM address).

On the next cylic call the data packet is appended in the Tx FIFO. There is no emission of the previous data packet.

So, where be the problem lay? 

Endpoint Descriptor for EP2 IN? ( { 7, 5, 0x82, 2, 64, 0 } ).

Endpoint enable? DIEPTSIZ2 = 0x00080014, DIEPCTL2: 0x80888040.

Have reviewed assumptions and have googled, found Infinion's XMC4500 which implements a similar core and its programming manual (xmc4500_um.pdf, pages 1306, 1307) offers a flow diagram of a bulk IN transfer.

Hmmm...