My Marlin configs for Fabrikator Mini and CTC i3 Pro B
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

pca9533.cpp 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /*
  2. * Marlin 3D Printer Firmware
  3. * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
  4. *
  5. * Based on Sprinter and grbl.
  6. * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
  7. *
  8. * This program is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation, either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  20. *
  21. */
  22. /**
  23. * PCA9533 LED controller driver (MightyBoard, FlashForge Creator Pro, etc.)
  24. * by @grauerfuchs - 1 Apr 2020
  25. */
  26. #include "../../inc/MarlinConfig.h"
  27. #if ENABLED(PCA9533)
  28. #include "pca9533.h"
  29. #include <Wire.h>
  30. void PCA9533_init() {
  31. Wire.begin();
  32. PCA9533_reset();
  33. }
  34. static void PCA9533_writeAllRegisters(uint8_t psc0, uint8_t pwm0, uint8_t psc1, uint8_t pwm1, uint8_t ls0) {
  35. uint8_t data[6] = { PCA9533_REG_PSC0 | PCA9533_REGM_AI, psc0, pwm0, psc1, pwm1, ls0 };
  36. Wire.beginTransmission(PCA9533_Addr >> 1);
  37. Wire.write(data, 6);
  38. Wire.endTransmission();
  39. delayMicroseconds(1);
  40. }
  41. static void PCA9533_writeRegister(uint8_t reg, uint8_t val) {
  42. uint8_t data[2] = { reg, val };
  43. Wire.beginTransmission(PCA9533_Addr >> 1);
  44. Wire.write(data, 2);
  45. Wire.endTransmission();
  46. delayMicroseconds(1);
  47. }
  48. // Reset (clear) all registers
  49. void PCA9533_reset() {
  50. PCA9533_writeAllRegisters(0, 0, 0, 0, 0);
  51. }
  52. // Turn all LEDs off
  53. void PCA9533_setOff() {
  54. PCA9533_writeRegister(PCA9533_REG_SEL, 0);
  55. }
  56. void PCA9533_set_rgb(uint8_t red, uint8_t green, uint8_t blue) {
  57. uint8_t r_pwm0 = 0; // Register data - PWM value
  58. uint8_t r_pwm1 = 0; // Register data - PWM value
  59. uint8_t op_g = 0, op_r = 0, op_b = 0; // Opcodes - Green, Red, Blue
  60. // Light theory! GREEN takes priority because
  61. // it's the most visible to the human eye.
  62. if (green == 0) op_g = PCA9533_LED_OP_OFF;
  63. else if (green == 255) op_g = PCA9533_LED_OP_ON;
  64. else { r_pwm0 = green; op_g = PCA9533_LED_OP_PWM0; }
  65. // RED
  66. if (red == 0) op_r = PCA9533_LED_OP_OFF;
  67. else if (red == 255) op_r = PCA9533_LED_OP_ON;
  68. else if (r_pwm0 == 0 || r_pwm0 == red) {
  69. r_pwm0 = red; op_r = PCA9533_LED_OP_PWM0;
  70. }
  71. else {
  72. r_pwm1 = red; op_r = PCA9533_LED_OP_PWM1;
  73. }
  74. // BLUE
  75. if (blue == 0) op_b = PCA9533_LED_OP_OFF;
  76. else if (blue == 255) op_b = PCA9533_LED_OP_ON;
  77. else if (r_pwm0 == 0 || r_pwm0 == blue) {
  78. r_pwm0 = blue; op_b = PCA9533_LED_OP_PWM0;
  79. }
  80. else if (r_pwm1 == 0 || r_pwm1 == blue) {
  81. r_pwm1 = blue; op_b = PCA9533_LED_OP_PWM1;
  82. }
  83. else {
  84. /**
  85. * Conflict. 3 values are requested but only 2 channels exist.
  86. * G is on channel 0 and R is on channel 1, so work from there.
  87. * Find the closest match, average the values, then use the free channel.
  88. */
  89. uint8_t dgb = ABS(green - blue),
  90. dgr = ABS(green - red),
  91. dbr = ABS(blue - red);
  92. if (dgb < dgr && dgb < dbr) { // Mix with G on channel 0.
  93. op_b = PCA9533_LED_OP_PWM0;
  94. r_pwm0 = uint8_t(((uint16_t)green + (uint16_t)blue) / 2);
  95. }
  96. else if (dbr <= dgr && dbr <= dgb) { // Mix with R on channel 1.
  97. op_b = PCA9533_LED_OP_PWM1;
  98. r_pwm1 = uint8_t(((uint16_t)red + (uint16_t)blue) / 2);
  99. }
  100. else { // Mix R+G on 0 and put B on 1.
  101. op_r = PCA9533_LED_OP_PWM0;
  102. r_pwm0 = uint8_t(((uint16_t)green + (uint16_t)red) / 2);
  103. op_b = PCA9533_LED_OP_PWM1;
  104. r_pwm1 = blue;
  105. }
  106. }
  107. // Write the changes to the hardware
  108. PCA9533_writeAllRegisters(0, r_pwm0, 0, r_pwm1,
  109. (op_g << PCA9533_LED_OFS_GRN) | (op_r << PCA9533_LED_OFS_RED) | (op_b << PCA9533_LED_OFS_BLU)
  110. );
  111. }
  112. #endif // PCA9533