diff --git a/src/GCodes/GCodes2.cpp b/src/GCodes/GCodes2.cpp index 921c8c326..e39c7f35b 100644 --- a/src/GCodes/GCodes2.cpp +++ b/src/GCodes/GCodes2.cpp @@ -3771,72 +3771,90 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx case 575: // Set communications parameters { const size_t chan = gb.GetLimitedUIValue('P', NumSerialChannels); - GCodeBuffer * const gbp = (chan == 0) ? UsbGCode() : (chan == 1) ? AuxGCode() : Aux2GCode(); + bool hostMode = false; bool seen = false; - if (gb.Seen('B')) +#if SUPPORT_USB_DRIVE + if (chan == 0 && gb.TryGetBValue('H', hostMode, seen)) // switch modes first { - platform.SetBaudRate(chan, gb.GetUIValue()); - seen = true; + if (!platform.SetUsbHostMode(hostMode, reply)) + { + reply.printf("Unable to set to %s mode", hostMode ? "host" : "device"); + result = GCodeResult::error; + } } - - if (gb.Seen('S')) +#else + reply.printf("USB host mode unsupported"); + result = GCodeResult::error; +#endif + if (result == GCodeResult::ok && !hostMode) // switched to device mode with no error, handle other device mode args { - const uint32_t val = gb.GetUIValue(); - platform.SetCommsProperties(chan, val); - if (gbp != nullptr) + GCodeBuffer * const gbp = (chan == 0) ? UsbGCode() : (chan == 1) ? AuxGCode() : Aux2GCode(); + if (gb.Seen('B')) { - gbp->SetCommsProperties(val); -#if HAS_AUX_DEVICES - if (chan != 0) + platform.SetBaudRate(chan, gb.GetUIValue()); + seen = true; + } + + if (gb.Seen('S')) + { + const uint32_t val = gb.GetUIValue(); + platform.SetCommsProperties(chan, val); + if (gbp != nullptr) { - const bool rawMode = (val & 2u) != 0; - platform.SetAuxRaw(chan - 1, rawMode); - if (rawMode && !platform.IsAuxEnabled(chan - 1)) // if enabling aux for the first time and in raw mode, set Marlin compatibility + gbp->SetCommsProperties(val); +#if HAS_AUX_DEVICES + if (chan != 0) { - gbp->LatestMachineState().compatibility = Compatibility::Marlin; + const bool rawMode = (val & 2u) != 0; + platform.SetAuxRaw(chan - 1, rawMode); + if (rawMode && !platform.IsAuxEnabled(chan - 1)) // if enabling aux for the first time and in raw mode, set Marlin compatibility + { + gbp->LatestMachineState().compatibility = Compatibility::Marlin; + } } - } #endif + } + seen = true; } - seen = true; - } - if (seen) - { -#if HAS_AUX_DEVICES - if (chan != 0 && !platform.IsAuxEnabled(chan - 1)) + if (seen) { - platform.EnableAux(chan - 1); +#if HAS_AUX_DEVICES + if (chan != 0 && !platform.IsAuxEnabled(chan - 1)) + { + platform.EnableAux(chan - 1); + } + else + { + platform.ResetChannel(chan); + } } - else + else if (chan != 0 && !platform.IsAuxEnabled(chan - 1)) { - platform.ResetChannel(chan); - } - } - else if (chan != 0 && !platform.IsAuxEnabled(chan - 1)) - { - reply.printf("Channel %u is disabled", chan); + reply.printf("Channel %u is disabled", chan); #endif - } - else - { - const uint32_t cp = platform.GetCommsProperties(chan); - reply.printf("Channel %d: baud rate %" PRIu32 ", %s%s", chan, platform.GetBaudRate(chan), - (chan != 0 && platform.IsAuxRaw(chan - 1)) ? "raw mode, " : "", - (cp & 4) ? "requires CRC" - : (cp & 1) ? "requires checksum or CRC" - : "does not require checksum or CRC" - ); - if (chan == 0 && SERIAL_MAIN_DEVICE.IsConnected()) - { - reply.cat(", connected"); } -#if HAS_AUX_DEVICES - else if (chan != 0 && platform.IsAuxRaw(chan - 1)) + else { - reply.cat(", raw mode"); - } + const uint32_t cp = platform.GetCommsProperties(chan); + reply.printf("Channel %d: baud rate %" PRIu32 ", %s%s", chan, platform.GetBaudRate(chan), + (chan != 0 && platform.IsAuxRaw(chan - 1)) ? "raw mode, " : "", + (cp & 4) ? "requires CRC" + : (cp & 1) ? "requires checksum or CRC" + : "does not require checksum or CRC" + ); + + if (chan == 0 && SERIAL_MAIN_DEVICE.IsConnected()) + { + reply.cat(", connected"); + } +#if HAS_AUX_DEVICES + else if (chan != 0 && platform.IsAuxRaw(chan - 1)) + { + reply.cat(", raw mode"); + } #endif + } } } break; diff --git a/src/Hardware/SAME70/Devices.cpp b/src/Hardware/SAME70/Devices.cpp index 92ef11fba..f7963d5a8 100644 --- a/src/Hardware/SAME70/Devices.cpp +++ b/src/Hardware/SAME70/Devices.cpp @@ -122,8 +122,12 @@ void DeviceInit() noexcept #endif #if CORE_USES_TINYUSB +#if SUPPORT_USB_DRIVE && CFG_TUH_ENABLED + CoreUsbInit(NvicPriorityUSB, UsbVBusPin, UsbPowerSwitchPin, UsbModePin, UsbDetectPin); +#else CoreUsbInit(NvicPriorityUSB); - usbDeviceTask.Create(CoreUsbDeviceTask, "USBD", nullptr, TaskPriority::UsbPriority); +#endif + usbDeviceTask.Create(CoreUsbDeviceTask, "USBHD", nullptr, TaskPriority::UsbPriority); #endif } @@ -134,6 +138,7 @@ void StopAnalogTask() noexcept void StopUsbTask() noexcept { #if CORE_USES_TINYUSB + CoreUsbStop(); usbDeviceTask.TerminateAndUnlink(); #endif } diff --git a/src/Platform/Platform.cpp b/src/Platform/Platform.cpp index 0ddc5c461..8c3a3ecce 100644 --- a/src/Platform/Platform.cpp +++ b/src/Platform/Platform.cpp @@ -46,6 +46,10 @@ #include #include +#if SUPPORT_USB_DRIVE +#include +#endif + #if SAM4E || SAM4S || SAME70 # include using LegacyAnalogIn::AdcBits; @@ -3822,6 +3826,18 @@ void Platform::SetBaudRate(size_t chan, uint32_t br) noexcept } } +#if SUPPORT_USB_DRIVE +bool Platform::SetUsbHostMode(bool hostMode, const StringRef& reply) noexcept +{ +#if CORE_USES_TINYUSB && CFG_TUH_ENABLED + return CoreUsbSetHostMode(hostMode, reply); +#else + reply.copy("Host mode not supported by USB stack"); + return false; // unimplemented if not using tinyUSB +#endif +} +#endif + uint32_t Platform::GetBaudRate(size_t chan) const noexcept { return (chan < NumSerialChannels) ? baudRates[chan] : 0; diff --git a/src/Platform/Platform.h b/src/Platform/Platform.h index d20e23887..0de54f787 100644 --- a/src/Platform/Platform.h +++ b/src/Platform/Platform.h @@ -313,6 +313,9 @@ class Platform INHERIT_OBJECT_MODEL void SetGateWay(IPAddress gw) noexcept; IPAddress GateWay() const noexcept; void SetBaudRate(size_t chan, uint32_t br) noexcept; +#if SUPPORT_USB_DRIVE + bool SetUsbHostMode(bool host, const StringRef& reply) noexcept; +#endif uint32_t GetBaudRate(size_t chan) const noexcept; void SetCommsProperties(size_t chan, uint32_t cp) noexcept; uint32_t GetCommsProperties(size_t chan) const noexcept;