Is your suggested improvement related to an existing problem? Please describe.
I'm looking to add status indicator lights (like this) to the printer to help visualize the current status at a glance. For this, I'd like to get access to the GPIOs on the expansion connector from G-code.
Describe the expected functionality
There are two free GPIOs on the expansion connector (STM pins PE0 and PB5, mapping to #64 and #21). There is not much missing for them to be accessible via the M42 command. However, the way the firmware works at the moment, trying to issue an M42 command for either pin currently fails with a "blue screen". The error message is always
?HWIO error
pin #21 (0x15)
analog write
This comes from the fact that the M42 implementation tries to digitalWrite() and analogWrite() the pin at the same time:
I guess the Marlin code for the M42 implementation assumes that digitalWrite()/analogWrite() fail silently on an undefined pin instead of panicking.
To me it is completely reasonable that digitalWrite()/analogWrite() fail with noise when receiving unknown inputs and it is the caller's responsibility (M42 implementation) to check for pin type and validity. However, it looks to me like there isn't really a way to check for pin type at the moment. For digital pins, there seems to be an isOutputPin() used in digitalWrite(), but that's commented out right now, so I don't know if it is actually working:
OTOH analogWrite() seems to hard-code known analog pins, so there is no way to check for pin type.
I see multiple possible solutions:
Simply never analogWrite() because the only pins that matter are digital pins anyway. Should work, but is the least flexible.
Define a function that reports whether a pin is analog and only call analogWrite() for those. I am not sure how this would fit in with the arduino style API that seems to be used here, though...
Printer type - [MINI]
Is your suggested improvement related to an existing problem? Please describe. I'm looking to add status indicator lights (like this) to the printer to help visualize the current status at a glance. For this, I'd like to get access to the GPIOs on the expansion connector from G-code.
Describe the expected functionality There are two free GPIOs on the expansion connector (STM pins
PE0
andPB5
, mapping to#64
and#21
). There is not much missing for them to be accessible via the M42 command. However, the way the firmware works at the moment, trying to issue an M42 command for either pin currently fails with a "blue screen". The error message is alwaysThis comes from the fact that the M42 implementation tries to
digitalWrite()
andanalogWrite()
the pin at the same time:https://github.com/prusa3d/Prusa-Firmware-Buddy/blob/b46ac81aee5bfaad7a85d352957ffafb60dde51c/lib/Marlin/Marlin/src/gcode/control/M42.cpp#L56-L58
The
digitalWrite()
actually seems to pass, but theanalogWrite()
then panics, because the pin is not a known analog output:https://github.com/prusa3d/Prusa-Firmware-Buddy/blob/b46ac81aee5bfaad7a85d352957ffafb60dde51c/src/common/hwio_buddy_2209_02.cpp#L534-L535
I guess the Marlin code for the
M42
implementation assumes thatdigitalWrite()
/analogWrite()
fail silently on an undefined pin instead of panicking.To me it is completely reasonable that
digitalWrite()
/analogWrite()
fail with noise when receiving unknown inputs and it is the caller's responsibility (M42
implementation) to check for pin type and validity. However, it looks to me like there isn't really a way to check for pin type at the moment. For digital pins, there seems to be anisOutputPin()
used indigitalWrite()
, but that's commented out right now, so I don't know if it is actually working:https://github.com/prusa3d/Prusa-Firmware-Buddy/blob/b46ac81aee5bfaad7a85d352957ffafb60dde51c/src/common/hwio_buddy_2209_02.cpp#L469-L475
OTOH
analogWrite()
seems to hard-code known analog pins, so there is no way to check for pin type.I see multiple possible solutions:
analogWrite()
because the only pins that matter are digital pins anyway. Should work, but is the least flexible.analogWrite()
for those. I am not sure how this would fit in with the arduino style API that seems to be used here, though...References: #3649, #3711