4747#include < Storage/SdCardVolume.h>
4848#include < Accelerometers/Accelerometers.h>
4949
50+ #if SUPPORT_USB_DRIVE
51+ #include < TinyUsbInterface.h>
52+ #endif
53+
5054#if SAM4E || SAM4S || SAME70
5155# include < AnalogIn.h>
5256using LegacyAnalogIn::AdcBits;
@@ -2039,6 +2043,48 @@ GCodeResult Platform::HandleM575(GCodeBuffer& gb, const StringRef& reply) THROWS
20392043{
20402044 // Get the channel specified by the command and the corresponding GCode buffer
20412045 const size_t chan = gb.GetLimitedUIValue (' P' , NumSerialChannels);
2046+
2047+ bool modeChangeSeen = false ;
2048+ bool hostMode = false ;
2049+ gb.TryGetBValue (' H' , hostMode, modeChangeSeen);
2050+
2051+ #if SUPPORT_USB_DRIVE
2052+ if (chan == 0 )
2053+ {
2054+ bool result = SetUsbHostMode (hostMode, reply);
2055+
2056+ // If setting to host mode then return result immediately. However, if setting to device,
2057+ // check that succeeded first so that the rest of the M575 code can be executed.
2058+ if (hostMode)
2059+ {
2060+ return result ? GCodeResult::ok : GCodeResult::error;
2061+ }
2062+ else
2063+ {
2064+ if (!result)
2065+ {
2066+ return GCodeResult::error;
2067+ }
2068+ }
2069+ }
2070+ else
2071+ {
2072+ // H=1 is only valid on channel 0, otherwise ignored.
2073+ if (hostMode)
2074+ {
2075+ reply.printf (" USB host mode not supported on channel other than 0" );
2076+ return GCodeResult::error;
2077+ }
2078+ }
2079+ #else
2080+ // H=0 is ignored when USB host not supported.
2081+ if (modeChangeSeen && hostMode)
2082+ {
2083+ reply.printf (" USB host mode not supported" );
2084+ return GCodeResult::error;
2085+ }
2086+ #endif
2087+
20422088 GCodeBuffer * const gbp = reprap.GetGCodes ().GetSerialGCodeBuffer (chan);
20432089
20442090#if HAS_AUX_DEVICES
@@ -2109,7 +2155,7 @@ GCodeResult Platform::HandleM575(GCodeBuffer& gb, const StringRef& reply) THROWS
21092155 if ( gbp != nullptr
21102156 && newMode != AuxDevice::AuxMode::disabled
21112157 && newMode != AuxDevice::AuxMode::device
2112- )
2158+ )
21132159 {
21142160 gbp->Enable (val); // enable I/O and set the CRC and checksum requirements, also sets Marlin or PanelDue compatibility
21152161 }
@@ -2136,7 +2182,7 @@ GCodeResult Platform::HandleM575(GCodeBuffer& gb, const StringRef& reply) THROWS
21362182 {
21372183 if (!IsAuxEnabled (chan - 1 )
21382184 && (chan >= NumSerialChannels || auxDevices[chan - 1 ].GetMode () != AuxDevice::AuxMode::device)
2139- )
2185+ )
21402186 {
21412187 reply.printf (" Channel %u is disabled" , chan);
21422188 }
@@ -2170,6 +2216,7 @@ GCodeResult Platform::HandleM575(GCodeBuffer& gb, const StringRef& reply) THROWS
21702216 }
21712217 }
21722218 }
2219+
21732220 return GCodeResult::ok;
21742221}
21752222
@@ -3219,6 +3266,18 @@ void Platform::SetBaudRate(size_t chan, uint32_t br) noexcept
32193266 }
32203267}
32213268
3269+ #if SUPPORT_USB_DRIVE
3270+ bool Platform::SetUsbHostMode (bool hostMode, const StringRef& reply) noexcept
3271+ {
3272+ #if CORE_USES_TINYUSB && CFG_TUH_ENABLED
3273+ return CoreUsbSetHostMode (hostMode, reply);
3274+ #else
3275+ reply.copy (" Host mode not supported by USB stack" );
3276+ return false ; // unimplemented if not using tinyUSB
3277+ #endif
3278+ }
3279+ #endif
3280+
32223281uint32_t Platform::GetBaudRate (size_t chan) const noexcept
32233282{
32243283 return (chan != 0 && chan < NumSerialChannels) ? auxDevices[chan - 1 ].GetBaudRate () : 0 ;
0 commit comments