@@ -21,26 +21,33 @@ func initEndpoint(ep, config uint32) {
2121 offset := ep * 2 * usbBufferLen + 0x100
2222 val |= offset
2323
24+ // Bulk and interrupt endpoints must have their Packet ID reset to DATA0 when un-stalled.
25+ epXPIDReset [ep ] = false // Default to false in case an endpoint is re-initialized.
26+
2427 switch config {
2528 case usb .ENDPOINT_TYPE_INTERRUPT | usb .EndpointIn :
2629 val |= usbEpControlEndpointTypeInterrupt
2730 _usbDPSRAM .EPxControl [ep ].In .Set (val )
31+ epXPIDReset [ep ] = true
2832
2933 case usb .ENDPOINT_TYPE_BULK | usb .EndpointOut :
3034 val |= usbEpControlEndpointTypeBulk
3135 _usbDPSRAM .EPxControl [ep ].Out .Set (val )
3236 _usbDPSRAM .EPxBufferControl [ep ].Out .Set (usbBufferLen & usbBuf0CtrlLenMask )
3337 _usbDPSRAM .EPxBufferControl [ep ].Out .SetBits (usbBuf0CtrlAvail )
38+ epXPIDReset [ep ] = true
3439
3540 case usb .ENDPOINT_TYPE_INTERRUPT | usb .EndpointOut :
3641 val |= usbEpControlEndpointTypeInterrupt
3742 _usbDPSRAM .EPxControl [ep ].Out .Set (val )
3843 _usbDPSRAM .EPxBufferControl [ep ].Out .Set (usbBufferLen & usbBuf0CtrlLenMask )
3944 _usbDPSRAM .EPxBufferControl [ep ].Out .SetBits (usbBuf0CtrlAvail )
45+ epXPIDReset [ep ] = true
4046
4147 case usb .ENDPOINT_TYPE_BULK | usb .EndpointIn :
4248 val |= usbEpControlEndpointTypeBulk
4349 _usbDPSRAM .EPxControl [ep ].In .Set (val )
50+ epXPIDReset [ep ] = true
4451
4552 case usb .ENDPOINT_TYPE_CONTROL :
4653 val |= usbEpControlEndpointTypeControl
@@ -109,7 +116,12 @@ func handleEndpointRx(ep uint32) []byte {
109116}
110117
111118func handleEndpointRxComplete (ep uint32 ) {
112- epXdata0 [ep ] = ! epXdata0 [ep ]
119+ setEPDataPID (ep , ! epXdata0 [ep ])
120+ }
121+
122+ // Set the USB endpoint Packet ID to DATA0 or DATA1.
123+ func setEPDataPID (ep uint32 , dataOne bool ) {
124+ epXdata0 [ep ] = dataOne
113125 if epXdata0 [ep ] || ep == 0 {
114126 _usbDPSRAM .EPxBufferControl [ep ].Out .SetBits (usbBuf0CtrlData1Pid )
115127 }
@@ -138,7 +150,8 @@ func sendViaEPIn(ep uint32, data []byte, count int) {
138150 _usbDPSRAM .EPxBufferControl [ep & 0x7F ].In .Set (val )
139151}
140152
141- func sendStallViaEPIn (ep uint32 ) {
153+ // Set ENDPOINT_HALT/stall status on a USB IN endpoint.
154+ func (dev * USBDevice ) SetStallEPIn (ep uint32 ) {
142155 // Prepare buffer control register value
143156 if ep == 0 {
144157 armEPZeroStall ()
@@ -149,6 +162,37 @@ func sendStallViaEPIn(ep uint32) {
149162 _usbDPSRAM .EPxBufferControl [ep & 0x7F ].In .Set (val )
150163}
151164
165+ // Set ENDPOINT_HALT/stall status on a USB OUT endpoint.
166+ func (dev * USBDevice ) SetStallEPOut (ep uint32 ) {
167+ if ep == 0 {
168+ panic ("SetStallEPOut: EP0 OUT not valid" )
169+ }
170+ val := uint32 (usbBuf0CtrlStall )
171+ _usbDPSRAM .EPxBufferControl [ep & 0x7F ].Out .Set (val )
172+ }
173+
174+ // Clear the ENDPOINT_HALT/stall on a USB IN endpoint.
175+ func (dev * USBDevice ) ClearStallEPIn (ep uint32 ) {
176+ ep = ep & 0x7F
177+ val := uint32 (usbBuf0CtrlStall )
178+ _usbDPSRAM .EPxBufferControl [ep ].In .ClearBits (val )
179+ if epXPIDReset [ep ] {
180+ // Reset the PID to DATA0
181+ setEPDataPID (ep & 0x7F , false )
182+ }
183+ }
184+
185+ // Clear the ENDPOINT_HALT/stall on a USB OUT endpoint.
186+ func (dev * USBDevice ) ClearStallEPOut (ep uint32 ) {
187+ ep = ep & 0x7F
188+ val := uint32 (usbBuf0CtrlStall )
189+ _usbDPSRAM .EPxBufferControl [ep ].Out .ClearBits (val )
190+ if epXPIDReset [ep ] {
191+ // Reset the PID to DATA0
192+ setEPDataPID (ep , false )
193+ }
194+ }
195+
152196type usbDPSRAM struct {
153197 // Note that EPxControl[0] is not EP0Control but 8-byte setup data.
154198 EPxControl [16 ]usbEndpointControlRegister
@@ -173,9 +217,10 @@ type usbBuffer struct {
173217}
174218
175219var (
176- _usbDPSRAM = (* usbDPSRAM )(unsafe .Pointer (uintptr (0x50100000 )))
177- epXdata0 [16 ]bool
178- setupBytes [8 ]byte
220+ _usbDPSRAM = (* usbDPSRAM )(unsafe .Pointer (uintptr (0x50100000 )))
221+ epXdata0 [16 ]bool
222+ epXPIDReset [16 ]bool
223+ setupBytes [8 ]byte
179224)
180225
181226func (d * usbDPSRAM ) setupBytes () []byte {
0 commit comments