v0.5 (first steps)
adds virtual ports 100-115 (maps to i2c ports 0-15) to m42 gcode
eg m42 p100 s255
new file pca9685.h add to main marlin directory
new file pca9685.cpp add to main marlin directory
add this to Configuration.h
add this near the top of Marlin_main.cpp after #include "parser.h"
Next find the M42 section of code in Marlin_main.cpp
and change it to
no idea how controller does the auto fan yet.... but this makes it somewhat useful.
adds virtual ports 100-115 (maps to i2c ports 0-15) to m42 gcode
eg m42 p100 s255
new file pca9685.h add to main marlin directory
/** * Driver for the Philips PCA9685 LED driver. * Written by Peter Ellens Dec 2018 Based on PCA9632 Driver by Robert Mendon Feb 2017. */ #ifndef __PCA9685_H__ #define __PCA9685_H__ /* Register addresses */ #define PCA9685_MODE1_REG (byte)0x00 #define PCA9685_MODE2_REG (byte)0x01 #define PCA9685_SUBADR1_REG (byte)0x02 #define PCA9685_SUBADR2_REG (byte)0x03 #define PCA9685_SUBADR3_REG (byte)0x04 #define PCA9685_ALLCALL_REG (byte)0x05 #define PCA9685_LED0_REG (byte)0x06 // Start of LEDx regs, 4B per reg, 2B on phase, 2B off phase, little-endian #define PCA9685_PRESCALE_REG (byte)0xFE #define PCA9685_ALLLED_REG (byte)0xFA // Mode1 register pin layout #define PCA9685_MODE_RESTART (byte)0x80 #define PCA9685_MODE_EXTCLK (byte)0x40 #define PCA9685_MODE_AUTOINC (byte)0x20 #define PCA9685_MODE_SLEEP (byte)0x10 #define PCA9685_MODE_SUBADR1 (byte)0x08 #define PCA9685_MODE_SUBADR2 (byte)0x04 #define PCA9685_MODE_SUBADR3 (byte)0x02 #define PCA9685_MODE_ALLCALL (byte)0x01 // Mode2 register pin layout #define PCA9685_MODE_INVRT (byte)0x10 #define PCA9685_MODE_OCH (byte)0x08 #define PCA9685_MODE_TOTEM_POLE (byte)0x04 #define PCA9685_MODE_OUTNE1 (byte)0x02 #define PCA9685_MODE_OUTNE0 (byte)0x01 #define PCA9685_PWM_FULL (uint16_t)0x01000 // Special value for full on/full off LEDx modes void pca9685_set_port_PWM8(const uint8_t port, uint16_t pwm); void pca9685_set_port_PWM16(const uint8_t port, uint16_t pwm); #endif // __PCA9685_H__
new file pca9685.cpp add to main marlin directory
/** * Driver for the Philips PCA9685 LED driver. * Written by Peter Ellens Dec 2018 Based on PCA9632 Driver by Robert Mendon Feb 2017. */ #include "MarlinConfig.h" #ifdef PCA9685 #include "pca9685.h" #include #define PCA9685_MODE1_VALUE PCA9685_MODE_ALLCALL|PCA9685_MODE_AUTOINC #define PCA9685_MODE2_VALUE PCA9685_MODE_TOTEM_POLE #define PCA9685_ADDRESS (byte)0x40 byte PCA9685_init = 0; static void PCA9685_WriteRegister(const byte addr, const byte regadd, const byte value) { Wire.beginTransmission(addr); Wire.write(regadd); Wire.write(value); Wire.endTransmission(); } static void PCA9685_WriteAllRegisters(const byte addr, const byte regadd, const byte value1, const byte value2, const byte value3, const byte value4) { Wire.beginTransmission(addr); Wire.write(regadd); Wire.write(value1); Wire.write(value2); Wire.write(value3); Wire.write(value3); Wire.endTransmission(); } void pca9685_set_port_PWM16(const uint8_t port, uint16_t pwm) { byte on_l=0; byte on_h=0; byte off_l=0; byte off_h=0; Wire.begin(); if (!PCA9685_init) { PCA9685_init = 1; PCA9685_WriteRegister(PCA9685_ADDRESS,PCA9685_MODE1_REG, PCA9685_MODE1_VALUE); PCA9685_WriteRegister(PCA9685_ADDRESS,PCA9685_MODE2_REG, PCA9685_MODE2_VALUE); } if (pwm > PCA9685_PWM_FULL ) pwm = PCA9685_PWM_FULL; if (pwm == PCA9685_PWM_FULL ) on_h = (PCA9685_PWM_FULL&0x1F00)>>8; else if (pwm == 0) off_h = (PCA9685_PWM_FULL&0x1F00)>>8; else { off_h = (pwm&0xF00)>>8; off_l = pwm&0xFF; } PCA9685_WriteAllRegisters(PCA9685_ADDRESS,PCA9685_LED0_REG+(4*port), on_h, on_l, off_h, off_l); } void pca9685_set_port_PWM8(const uint8_t port, uint16_t pwm) { if (pwm >= 255 ) pwm = 256; pca9685_set_port_PWM16(port, pwm<<4); } #endif // PCA9685
add this to Configuration.h
// Support for PCA9685 PWM driver #define PCA9685
add this near the top of Marlin_main.cpp after #include "parser.h"
#ifdef PCA9685 #include "pca9685.h" #endif
Next find the M42 section of code in Marlin_main.cpp
inline void gcode_M42() { if (!parser.seenval('S')) return; const byte pin_status = parser.value_byte(); const pin_t pin_number = parser.byteval('P', LED_PIN); if (pin_number < 0) return; if (!parser.boolval('I') && pin_is_protected(pin_number)) return protected_pin_err(); pinMode(pin_number, OUTPUT); digitalWrite(pin_number, pin_status); analogWrite(pin_number, pin_status);
and change it to
inline void gcode_M42() { if (!parser.seenval('S')) return; const byte pin_status = parser.value_byte(); const pin_t pin_number = parser.byteval('P', LED_PIN); if (pin_number < 0) return; if (!parser.boolval('I') && pin_is_protected(pin_number)) return protected_pin_err(); #ifdef PCA9685 if (pin_number < 100) { #endif pinMode(pin_number, OUTPUT); digitalWrite(pin_number, pin_status); analogWrite(pin_number, pin_status); #ifdef PCA9685 } else { pca9685_set_port_PWM8(pin_number-100, pin_status); } #endif
no idea how controller does the auto fan yet.... but this makes it somewhat useful.