Forum Discussion
Hello,
From the register values you posted, the first thing I would check is this: DCTL.sgoutnak = 1
SGOUTNAK means Set Global OUT NAK. It requests the controller to NAK OUT transactions globally. If this condition is active, the core can NAK the host’s OUT packet even if EP0 OUT has been enabled with: DOEPCTL0.epena = 1 DOEPCTL0.cnak = 1
For the status stage after sending the device descriptor, the host normally sends an OUT zero-length packet on EP0. Your DOEPTSIZ0 values are reasonable for that case: DOEPTSIZ0.xfersize = 0 DOEPTSIZ0.pktcnt = 1
However, before expecting the packet to be accepted, you should clear the global OUT NAK condition: DCTL.cgoutnak = 1
Then check the actual status bit: DCTL.goutnaksts == 0
A reasonable EP0 OUT status-stage sequence is:
DOEPTSIZ0 = DOEPTSIZ0_PKTCNT; // pktcnt = 1, xfersize = 0
DOEPINT0 = 0xffffffff; // clear stale W1C endpoint interrupts
DOEPCTL0 = read(DOEPCTL0) | EPENA | CNAK;
DCTL = read(DCTL) | CGOUTNAK; // clear global OUT NAK
After this, verify:
DCTL.goutnaksts = 0
DOEPCTL0.naksts = 0
DOEPCTL0.epena = 1
DOEPCTL0.stall = 0
The important distinction is that DOEPCTL0.cnak clears the NAK state for EP0 OUT only, while DCTL.cgoutnak clears the controller-level OUT NAK. Both have to allow the transfer.
So your DOEPINT0.nakintrpt = 1 observation is consistent with the controller still being in an OUT NAK state. I would start by removing the SGOUTNAK from the receive path, issuing CGOUTNAK before waiting for the OUT packet, and checking GOUTNAKSTS rather than assuming the endpoint enable alone is enough.
Hope this might help,
Fawaz.