/// Perform a 32-bit volatile load operation from the target pointer. /// /// Do not use for inter-thread synchronization. @_transparent public func load() -> Pointee { UInt32(Builtin.atomicload_monotonic_volatile_Int32(_rawPointer)) } } /// Perform a 32-bit volatile store operation on the target pointer. /// /// Do not use for inter-thread synchronization. @_transparent public func store(_ value: Pointee) { Builtin.atomicstore_monotonic_volatile_Int32(_rawPointer, value._value) } https://github.com/swiftlang/swift/blob/6ee6d5bf4138eb59700463c032e83618d02e9919/stdlib/public/Volatile/Volatile.swift#L74-L90
encode(_ bits: [Bool]) -> [Bool] { bits.map { bit in if !bit { line.toggle() } return line } } } struct NRZIDecoder { private var line = true mutating func decode(_ states: [Bool]) -> [Bool] { states.map { state in let bit = (state == line) // 変わっていない = 1、変わった = 0 } } } line = state return bit
Reset to a clean slate before bringing it up (clk_usb assumes // Clocks.initialize has already run). Resets.reset(.usbctrl) Resets.unreset(.usbctrl) // 2. DPRAM holds undefined values right after power-on -> zero it out. DPRAM.clear() // 3. Controller core, wiring to the physical pins, and self-reported power. mainControl.store(controllerEnable) muxing.store(muxToPhySoftcon) power.store(vbusDetectOverride) // The Pico's detect pin isn't wired -> declare "power is present". // 4. Raise a flag on every EP0 completion / address 0 (accept newcomers). sieControl.store(ep0IntPerBuffer) addressEndpoint.store(0) // 5. The one bit that announces us. From here the host's script begins. sieControl.set(pullupEnable) } ... }
Reset to a clean slate before bringing it up (clk_usb assumes // Clocks.initialize has already run). Resets.reset(.usbctrl) Resets.unreset(.usbctrl) // 2. DPRAM holds undefined values right after power-on -> zero it out. DPRAM.clear() マルチプレクサーを操作して // 3. Controller core, wiring to the physical pins, and self-reported power. USBコントローラーをPhysical Layerに繋ぐ mainControl.store(controllerEnable) muxing.store(muxToPhySoftcon) power.store(vbusDetectOverride) // The Pico's detect pin isn't wired -> declare "power is present". // 4. Raise a flag on every EP0 completion / address 0 (accept newcomers). sieControl.store(ep0IntPerBuffer) addressEndpoint.store(0) // 5. The one bit that announces us. From here the host's script begins. sieControl.set(pullupEnable) } ... }
Reset to a clean slate before bringing it up (clk_usb assumes // Clocks.initialize has already run). Resets.reset(.usbctrl) Resets.unreset(.usbctrl) // 2. DPRAM holds undefined values right after power-on -> zero it out. DPRAM.clear() マルチプレクサーを操作して // 3. Controller core, wiring to the physical pins, and self-reported power. USBコントローラーをPhysical Layerに繋ぐ mainControl.store(controllerEnable) muxing.store(muxToPhySoftcon) power.store(vbusDetectOverride) // The Pico's detect pin isn't wired -> declare "power is present". // 4. Raise a flag on every EP0 completion / address 0 (accept newcomers). sieControl.store(ep0IntPerBuffer) addressEndpoint.store(0) D+をプルアップ // 5. The one bit that announces us. From here the host's script begins. sieControl.set(pullupEnable) } ... }
Reset to a clean slate before bringing it up (clk_usb assumes // Clocks.initialize has already run). Resets.reset(.usbctrl) Resets.unreset(.usbctrl) // 2. DPRAM holds undefined values right after power-on -> zero it out. DPRAM.clear() // 3. Controller core, wiring to the physical pins, and self-reported power. mainControl.store(controllerEnable) muxing.store(muxToPhySoftcon) power.store(vbusDetectOverride) // The Pico's detect pin isn't wired -> declare "power is present". // 4. Raise a flag on every EP0 completion / address 0 (accept newcomers). sieControl.store(ep0IntPerBuffer) addressEndpoint.store(0) // 5. The one bit that announces us. From here the host's script begins. sieControl.set(pullupEnable) } ... }
// 1. Reset to a clean slate before bringing it up (clk_usb assumes // Clocks.initialize has already run). コントローラーはまだ動いていない。リセット状態を解除しただけ。 Resets.reset(.usbctrl) Resets.unreset(.usbctrl) // 2. DPRAM holds undefined values right after power-on -> zero it out. DPRAM.clear() // 3. Controller core, wiring to the physical pins, and self-reported power. mainControl.store(controllerEnable) muxing.store(muxToPhySoftcon) power.store(vbusDetectOverride) // The Pico's detect pin isn't wired -> declare "power is present". // 4. Raise a flag on every EP0 completion / address 0 (accept newcomers). sieControl.store(ep0IntPerBuffer) addressEndpoint.store(0) // 5. The one bit that announces us. From here the host's script begins. sieControl.set(pullupEnable) } ... }
// 1. Reset to a clean slate before bringing it up (clk_usb assumes // Clocks.initialize has already run). コントローラーはまだ動いていない。リセット状態を解除しただけ。 Resets.reset(.usbctrl) Resets.unreset(.usbctrl) DPRAMをゼロで初期化 // 2. DPRAM holds undefined values right after power-on -> zero it out. DPRAM.clear() // 3. Controller core, wiring to the physical pins, and self-reported power. mainControl.store(controllerEnable) muxing.store(muxToPhySoftcon) power.store(vbusDetectOverride) // The Pico's detect pin isn't wired -> declare "power is present". // 4. Raise a flag on every EP0 completion / address 0 (accept newcomers). sieControl.store(ep0IntPerBuffer) addressEndpoint.store(0) // 5. The one bit that announces us. From here the host's script begins. sieControl.set(pullupEnable) } ... }
// 1. Reset to a clean slate before bringing it up (clk_usb assumes // Clocks.initialize has already run). コントローラーはまだ動いていない。リセット状態を解除しただけ。 Resets.reset(.usbctrl) Resets.unreset(.usbctrl) DPRAMをゼロで初期化 // 2. DPRAM holds undefined values right after power-on -> zero it out. DPRAM.clear() USBコントローラーを動かす // 3. Controller core, wiring to the physical pins, and self-reported power. mainControl.store(controllerEnable) muxing.store(muxToPhySoftcon) power.store(vbusDetectOverride) // The Pico's detect pin isn't wired -> declare "power is present". // 4. Raise a flag on every EP0 completion / address 0 (accept newcomers). sieControl.store(ep0IntPerBuffer) addressEndpoint.store(0) // 5. The one bit that announces us. From here the host's script begins. sieControl.set(pullupEnable) } ... }
// 1. Reset to a clean slate before bringing it up (clk_usb assumes // Clocks.initialize has already run). コントローラーはまだ動いていない。リセット状態を解除しただけ。 Resets.reset(.usbctrl) Resets.unreset(.usbctrl) DPRAMをゼロで初期化 // 2. DPRAM holds undefined values right after power-on -> zero it out. DPRAM.clear() USBコントローラーを動かす // 3. Controller core, wiring to the physical pins, and self-reported power. mainControl.store(controllerEnable) muxing.store(muxToPhySoftcon) power.store(vbusDetectOverride) // The Pico's detect pin isn't wired -> declare "power is present". セットアップパケットの送受信に使うEP0の準備 // 4. Raise a flag on every EP0 completion / address 0 (accept newcomers). デバイス自身のアドレスをゼロに sieControl.store(ep0IntPerBuffer) addressEndpoint.store(0) // 5. The one bit that announces us. From here the host's script begins. sieControl.set(pullupEnable) } ... }
Reset to a clean slate before bringing it up (clk_usb assumes // Clocks.initialize has already run). Resets.reset(.usbctrl) Resets.unreset(.usbctrl) // 2. DPRAM holds undefined values right after power-on -> zero it out. DPRAM.clear() // 3. Controller core, wiring to the physical pins, and self-reported power. mainControl.store(controllerEnable) muxing.store(muxToPhySoftcon) power.store(vbusDetectOverride) // The Pico's detect pin isn't wired -> declare "power is present". // 4. Raise a flag on every EP0 completion / address 0 (accept newcomers). sieControl.store(ep0IntPerBuffer) addressEndpoint.store(0) // 5. The one bit that announces us. From here the host's script begins. sieControl.set(pullupEnable) } ... }
Reset to a clean slate before bringing it up (clk_usb assumes // Clocks.initialize has already run). Resets.reset(.usbctrl) Resets.unreset(.usbctrl) // 2. DPRAM holds undefined values right after power-on -> zero it out. DPRAM.clear() // 3. Controller core, wiring to the physical pins, and self-reported power. mainControl.store(controllerEnable) muxing.store(muxToPhySoftcon) power.store(vbusDetectOverride) // The Pico's detect pin isn't wired -> declare "power is present". // 4. Raise a flag on every EP0 completion / address 0 (accept newcomers). sieControl.store(ep0IntPerBuffer) addressEndpoint.store(0) // 5. The one bit that announces us. From here the host's script begins. sieControl.set(pullupEnable) } ... }
Bus reset: "return to the initial state" if status & USB.busReset != 0 { USB.handleBusReset() ... } // SETUP: an 8-byte question arrived -> answer it if status & USB.setupReceived != 0 { USB.sieStatus.store(USB.setupReceived) // W1C (acknowledge receipt) let setup = Control.Setup.read() } } Enumeration.handle(setup) ...
= USB.sieStatus.load() // Bus reset: "return to the initial state" if status & (1 << 19) != 0 { sieStatus.store(1 << 19) // W1C: only the flag written with a 1 clears addressEndpoint.store(0) // back to accepting at address 0 ... } // SETUP: an 8-byte question arrived -> answer it if status & (1 << 17) != 0 { USB.sieStatus.store(1 << 17) // W1C (acknowledge receipt) let setup = Control.Setup.read() } } Enumeration.handle(setup) ...
status = USB.sieStatus.load() // Bus reset: "return to the initial state" W1C: 書いたビットをクリアする if status & (1 << 19) != 0 { sieStatus.store(1 << 19) // W1C: only the flag written with a 1 clears addressEndpoint.store(0) // back to accepting at address 0 ... } // SETUP: an 8-byte question arrived -> answer it if status & (1 << 17) != 0 { USB.sieStatus.store(1 << 17) // W1C (acknowledge receipt) let setup = Control.Setup.read() } } Enumeration.handle(setup) ...
status = USB.sieStatus.load() // Bus reset: "return to the initial state" if status & (1 << 19) != 0 { sieStatus.store(1 << 19) // W1C: only the flag written with a 1 clears addressEndpoint.store(0) // back to accepting at address 0 ... } // SETUP: an 8-byte question arrived -> answer it if status & (1 << 17) != 0 { USB.sieStatus.store(1 << 17) // W1C (acknowledge receipt) let setup = Control.Setup.read() } } Enumeration.handle(setup) ...
reset: "return to the initial state" if status & (1 << 19) != 0 { sieStatus.store(1 << 19) // W1C: only the flag written with a 1 clears addressEndpoint.store(0) // back to accepting at address 0 ... } // SETUP: an 8-byte question arrived -> answer it if status & (1 << 17) != 0 { USB.sieStatus.store(1 << 17) // W1C (acknowledge receipt) let setup = Control.Setup.read() } } Enumeration.handle(setup) ...
cation https://www.usb.org/document-library/usb-20-speci cation ‒ RP2040 Datasheet https://pip-assets.raspberrypi.com/categories/814-rp2040/documents/RP-008371-DS-1-rp2040-datasheet.pdf ‒ Xbox Universal Serial Bus Protocol (XUSB) Interface Extension https://learn.microsoft.com/en-us/openspecs/windows̲protocols/ms-xusbi/c79474e7-3968-43d1-8d2f-175d47bef43e fi fi ‒ USB Complete http://janaxelson.com/usbc.htm