M42 implementation in Repetier-Firmware

Hi,

I'm working to understand how you can set a pin on a 3D-Printer with the "M42" Code. Plattform is an Arduino Mega2560. Why would you use

digitalWrite(pin_number, com->S);
analogWrite(pin_number, com->S);

directly after each other on the same PIN "com->S"? Doesn't the "analogWrite" just overrides the previous "digitalWrite" command?

Here's the full code in "Commands.cpp":

void Commands::processMCode(GCode *com) {
    switch( com->M ) [...]
        case 42: //M42 -Change pin status via gcode
            if (com->hasP()) {
                int pin_number = com->P;
                for(uint8_t i = 0; i < (uint8_t)sizeof(sensitive_pins); i++) {
                    if (pgm_read_byte(&sensitive_pins[i]) == pin_number) {
                        pin_number = -1;
                        break;
                    }
                }
                if (pin_number > -1) {
                    if(com->hasS()) {
                        if(com->S >= 0 && com->S <= 255) {
                            pinMode(pin_number, OUTPUT);
//-----------------------------------------------------------------------
                            digitalWrite(pin_number, com->S);
                            analogWrite(pin_number, com->S);
//-----------------------------------------------------------------------
                            Com::printF(Com::tSetOutputSpace, pin_number);
                            Com::printFLN(Com::tSpaceToSpace,(int)com->S);
                        } else
                            Com::printErrorFLN(PSTR("Illegal S value for M42"));
                    } else {
                        pinMode(pin_number, INPUT_PULLUP);
                        Com::printF(Com::tSpaceToSpace, pin_number);
                        Com::printFLN(Com::tSpaceIsSpace, digitalRead(pin_number));
                    }
                } else {
                    Com::printErrorFLN(PSTR("Pin can not be set by M42, is in sensitive pins! "));
                }
            }
            break;
}

Just a guess. Not all pins support PWM. Maybe that's the reason. Are you free to configure which pin is used as S ?

That's a good point. Some "sensitive_pins" can't be changed with "M42" such as heater, stepper motors etc. which is defined in "pins.h"

#define SENSITIVE_PINS {0, 1, ORIG_X_STEP_PIN, [...]}

So if PWM is not available, it falls back to digitalWrite(). Actually, on an Arduino, this is not necessary, because the definition of analogWrite() is

case NOT_ON_TIMER:
default:
	if (val < 128) {
		digitalWrite(pin, LOW);
	} else {
		digitalWrite(pin, HIGH);
	}

as pin output level after analogWrite() on non PWM pins - Suggestions for the Arduino Project - Arduino Forum suggests.

But because Repetier-Firmware works on multiple platforms, this double definition could make sense.

It's a bug. The way it is written, 0 and 1 which would be normal for digitalWrite() are going to be OFF and OFF for strictly digital pins and OFF and NEARLY OFF for PWM pins because the analogWrite() will immediately overwrite the OFF/ON effect of the digitalWrite(). They might as well get rid of the digitalWrite().

The RepRap wiki (G-code - RepRap) says that RepRap firmware only supports values of 0 or 1. It says nothing about the Repetier firmware needing 0 and 255 for OFF and ON. I hope that is documented somewhere.