77 "device/nrf"
88 "runtime/interrupt"
99 "runtime/volatile"
10- "unicode/utf16"
1110 "unsafe"
1211)
1312
@@ -21,17 +20,13 @@ type USBCDC struct {
2120func (usbcdc USBCDC ) WriteByte (c byte ) error {
2221 // Supposedly to handle problem with Windows USB serial ports?
2322 if usbLineInfo .lineState > 0 {
24- cdcInBusy . Set ( 1 )
23+ enterCriticalSection ( )
2524 udd_ep_in_cache_buffer [usb_CDC_ENDPOINT_IN ][0 ] = c
2625 sendViaEPIn (
2726 usb_CDC_ENDPOINT_IN ,
2827 & udd_ep_in_cache_buffer [usb_CDC_ENDPOINT_IN ][0 ],
2928 1 ,
3029 )
31-
32- for cdcInBusy .Get () == 1 {
33- arm .Asm ("wfi" )
34- }
3530 }
3631
3732 return nil
@@ -46,7 +41,8 @@ func (usbcdc USBCDC) RTS() bool {
4641}
4742
4843var (
49- USB = USBCDC {Buffer : NewRingBuffer ()}
44+ USB = USBCDC {Buffer : NewRingBuffer ()}
45+
5046 usbEndpointDescriptors [8 ]usbDeviceDescriptor
5147
5248 udd_ep_in_cache_buffer [7 ][128 ]uint8
6864 usbLineInfo = cdcLineInfo {115200 , 0x00 , 0x00 , 0x08 , 0x00 }
6965 epinen uint32
7066 epouten uint32
71- cdcInBusy volatile.Register8
67+ easyDMABusy volatile.Register8
7268)
7369
70+ // enterCriticalSection is used to protect access to easyDMA - only one thing
71+ // can be done with it at a time
72+ func enterCriticalSection () {
73+ waitForEasyDMA ()
74+ easyDMABusy .SetBits (1 )
75+ }
76+
77+ func waitForEasyDMA () {
78+ for easyDMABusy .HasBits (1 ) {
79+ arm .Asm ("wfi" )
80+ }
81+ }
82+
83+ func exitCriticalSection () {
84+ easyDMABusy .ClearBits (1 )
85+ }
86+
7487// Configure the USB CDC interface. The config is here for compatibility with the UART interface.
7588func (usbcdc * USBCDC ) Configure (config UARTConfig ) {
7689 // enable IRQ
@@ -83,7 +96,7 @@ func (usbcdc *USBCDC) Configure(config UARTConfig) {
8396
8497 // enable interrupt for end of reset and start of frame
8598 nrf .USBD .INTENSET .Set (
86- nrf .USBD_INTENSET_SOF |
99+ nrf .USBD_INTENSET_EPDATA |
87100 nrf .USBD_INTENSET_EP0DATADONE |
88101 nrf .USBD_INTENSET_USBEVENT |
89102 nrf .USBD_INTENSET_EP0SETUP ,
@@ -110,12 +123,6 @@ func (usbcdc *USBCDC) handleInterrupt(interrupt.Interrupt) {
110123 nrf .USBD .EVENTCAUSE .Set (0 )
111124 }
112125
113- // Start of frame
114- if nrf .USBD .EVENTS_SOF .Get () == 1 {
115- nrf .USBD .EVENTS_SOF .Set (0 )
116- // if you want to blink LED showing traffic, this would be the place...
117- }
118-
119126 if nrf .USBD .EVENTS_EP0DATADONE .Get () == 1 {
120127 // done sending packet - either need to send another or enter status stage
121128 nrf .USBD .EVENTS_EP0DATADONE .Set (0 )
@@ -164,29 +171,40 @@ func (usbcdc *USBCDC) handleInterrupt(interrupt.Interrupt) {
164171 if nrf .USBD .EVENTS_EPDATA .Get () > 0 {
165172 nrf .USBD .EVENTS_EPDATA .Set (0 )
166173 epDataStatus := nrf .USBD .EPDATASTATUS .Get ()
167- nrf .USBD .EPDATASTATUS .Set (0 )
174+ nrf .USBD .EPDATASTATUS .Set (epDataStatus )
168175 var i uint32
169176 for i = 1 ; i < uint32 (len (endPoints )); i ++ {
170177 // Check if endpoint has a pending interrupt
171- inDataDone := epDataStatus & (1 << i ) > 0
172- outDataDone := epDataStatus & (0x10000 << i ) > 0
178+ inDataDone := epDataStatus & (nrf . USBD_EPDATASTATUS_EPIN1 << ( i - 1 ) ) > 0
179+ outDataDone := epDataStatus & (nrf . USBD_EPDATASTATUS_EPOUT1 << ( i - 1 ) ) > 0
173180 if inDataDone || outDataDone {
174181 switch i {
175182 case usb_CDC_ENDPOINT_OUT :
176- nrf .USBD .EPOUT [i ].PTR .Set (uint32 (uintptr (unsafe .Pointer (& udd_ep_out_cache_buffer [i ]))))
177- nrf .USBD .EPOUT [i ].MAXCNT .Set (64 )
178- nrf .USBD .TASKS_STARTEPOUT [i ].Set (1 )
179- case usb_CDC_ENDPOINT_IN , usb_CDC_ENDPOINT_ACM :
180- cdcInBusy .Set (0 )
183+ // setup buffer to receive from host
184+ if outDataDone {
185+ enterCriticalSection ()
186+ nrf .USBD .EPOUT [i ].PTR .Set (uint32 (uintptr (unsafe .Pointer (& udd_ep_out_cache_buffer [i ]))))
187+ count := nrf .USBD .SIZE .EPOUT [i ].Get ()
188+ nrf .USBD .EPOUT [i ].MAXCNT .Set (count )
189+ nrf .USBD .TASKS_STARTEPOUT [i ].Set (1 )
190+ }
191+ case usb_CDC_ENDPOINT_IN : //, usb_CDC_ENDPOINT_ACM:
192+ if inDataDone {
193+ exitCriticalSection ()
194+ }
181195 }
182196 }
183197 }
184198 }
185199
200+ // ENDEPOUT[n] events
186201 for i := 0 ; i < len (endPoints ); i ++ {
187202 if nrf .USBD .EVENTS_ENDEPOUT [i ].Get () > 0 {
188203 nrf .USBD .EVENTS_ENDEPOUT [i ].Set (0 )
189- handleEndpoint (uint32 (i ))
204+ if i == usb_CDC_ENDPOINT_OUT {
205+ handleEndpoint (uint32 (i ))
206+ }
207+ exitCriticalSection ()
190208 }
191209 }
192210}
@@ -208,7 +226,6 @@ func initEndpoint(ep, config uint32) {
208226 enableEPIn (ep )
209227
210228 case usb_ENDPOINT_TYPE_BULK | usbEndpointOut :
211- nrf .USBD .INTENSET .Set (nrf .USBD_INTENSET_EPDATA )
212229 nrf .USBD .INTENSET .Set (nrf .USBD_INTENSET_ENDEPOUT0 << ep )
213230 nrf .USBD .SIZE .EPOUT [ep ].Set (0 )
214231 enableEPOut (ep )
@@ -219,7 +236,6 @@ func initEndpoint(ep, config uint32) {
219236 enableEPOut (ep )
220237
221238 case usb_ENDPOINT_TYPE_BULK | usbEndpointIn :
222- nrf .USBD .INTENSET .Set (nrf .USBD_INTENSET_EPDATA )
223239 enableEPIn (ep )
224240
225241 case usb_ENDPOINT_TYPE_CONTROL :
@@ -238,7 +254,6 @@ func handleStandardSetup(setup usbSetup) bool {
238254 buf := []byte {0 , 0 }
239255
240256 if setup .bmRequestType != 0 { // endpoint
241- // TODO: actually check if the endpoint in question is currently halted
242257 if isEndpointHalt {
243258 buf [0 ] = 1
244259 }
@@ -354,9 +369,6 @@ func cdcSetup(setup usbSetup) bool {
354369 }
355370
356371 if setup .bRequest == usb_CDC_SEND_BREAK {
357- // TODO: something with this value?
358- // breakValue = ((uint16_t)setup.wValueH << 8) | setup.wValueL;
359- // return false;
360372 nrf .USBD .TASKS_EP0STATUS .Set (1 )
361373 }
362374 return true
@@ -431,11 +443,19 @@ func sendDescriptor(setup usbSetup) {
431443
432444 case usb_IPRODUCT :
433445 b := strToUTF16LEDescriptor (usb_STRING_PRODUCT )
434- sendUSBPacket (0 , b [:setup .wLength ])
446+ if setup .wLength == 2 {
447+ sendUSBPacket (0 , b [:2 ])
448+ } else {
449+ sendUSBPacket (0 , b )
450+ }
435451
436452 case usb_IMANUFACTURER :
437453 b := strToUTF16LEDescriptor (usb_STRING_MANUFACTURER )
438- sendUSBPacket (0 , b [:setup .wLength ])
454+ if setup .wLength == 2 {
455+ sendUSBPacket (0 , b [:2 ])
456+ } else {
457+ sendUSBPacket (0 , b )
458+ }
439459
440460 case usb_ISERIAL :
441461 // TODO: allow returning a product serial number
@@ -500,7 +520,7 @@ func sendConfiguration(setup usbSetup) {
500520
501521func handleEndpoint (ep uint32 ) {
502522 // get data
503- count := int (nrf .USBD .SIZE . EPOUT [ep ].Get ())
523+ count := int (nrf .USBD .EPOUT [ep ]. AMOUNT .Get ())
504524
505525 // move to ring buffer
506526 for i := 0 ; i < count ; i ++ {
@@ -516,7 +536,6 @@ func sendViaEPIn(ep uint32, ptr *byte, count int) {
516536 uint32 (uintptr (unsafe .Pointer (ptr ))),
517537 )
518538 nrf .USBD .EPIN [ep ].MAXCNT .Set (uint32 (count ))
519- nrf .USBD .EVENTS_ENDEPIN [ep ].Set (0 )
520539 nrf .USBD .TASKS_STARTEPIN [ep ].Set (1 )
521540}
522541
@@ -529,17 +548,3 @@ func enableEPIn(ep uint32) {
529548 epinen = epinen | (nrf .USBD_EPINEN_IN0 << ep )
530549 nrf .USBD .EPINEN .Set (epinen )
531550}
532-
533- func strToUTF16LEDescriptor (in string ) []byte {
534- runes := []rune (in )
535- encoded := utf16 .Encode (runes )
536- size := (len (encoded ) << 1 ) + 2
537- out := make ([]byte , size )
538- out [0 ] = byte (size )
539- out [1 ] = 0x03
540- for i , value := range encoded {
541- out [(i << 1 )+ 2 ] = byte (value & 0xff )
542- out [(i << 1 )+ 3 ] = byte (value >> 8 )
543- }
544- return out
545- }
0 commit comments