Browse Source

Fix up Max7219 orientations (#11596)

Scott Lahteine 7 years ago
parent
commit
8f0bbdcc9b
No account linked to committer's email address

+ 42
- 52
Marlin/src/feature/Max7219_Debug_LEDs.cpp View File

@@ -50,36 +50,32 @@
50 50
 
51 51
 Max7219 max7219;
52 52
 
53
-uint8_t Max7219::led_line[MAX7219_ROWS]; // = { 0 };
53
+uint8_t Max7219::led_line[MAX7219_LINES]; // = { 0 };
54 54
 
55
+#define LINE_REG(Q)     (max7219_reg_digit0 + ((Q) & 0x7))
55 56
 #if _ROT == 0 || _ROT == 270
56
-  #define _LED_BIT(Q)   (7 - ((Q) & 0x07))
57
+  #define _LED_BIT(Q)   (7 - ((Q) & 0x7))
58
+  #define _LED_UNIT(Q)  ((Q) & ~0x7)
57 59
 #else
58
-  #define _LED_BIT(Q)   ((Q) & 0x07)
60
+  #define _LED_BIT(Q)   ((Q) & 0x7)
61
+  #define _LED_UNIT(Q)  ((MAX7219_NUMBER_UNITS - 1 - ((Q) >> 3)) << 3)
59 62
 #endif
60
-#if _ROT >= 180
61
-  #define _LED_IND(P,Q) (P + ((Q) & ~0x07))
62
-  #define _ROW_REG(Q)   (max7219_reg_digit7 - ((Q) & 0x7))
63
+#if _ROT < 180
64
+  #define _LED_IND(P,Q) (_LED_UNIT(P) + (Q))
63 65
 #else
64
-  #define _LED_IND(P,Q) (P + ((Q) & ~0x07))
65
-  #define _ROW_REG(Q)   (max7219_reg_digit0 + ((Q) & 0x7))
66
+  #define _LED_IND(P,Q) (_LED_UNIT(P) + (7 - ((Q) & 0x7)))
66 67
 #endif
67 68
 #if _ROT == 0 || _ROT == 180
68
-  #define MAX7219_LINE_AXIS y
69
-  #define LED_IND(X,Y)  _LED_IND(Y,X)
69
+  #define LED_IND(X,Y)  _LED_IND(X,Y)
70 70
   #define LED_BIT(X,Y)  _LED_BIT(X)
71 71
 #elif _ROT == 90 || _ROT == 270
72
-  #define MAX7219_LINE_AXIS x
73
-  #define LED_IND(X,Y)  _LED_IND(X,Y)
72
+  #define LED_IND(X,Y)  _LED_IND(Y,X)
74 73
   #define LED_BIT(X,Y)  _LED_BIT(Y)
75
-#else
76
-  #error "MAX7219_ROTATE must be a multiple of +/- 90°."
77 74
 #endif
78
-
79
-#define XOR_7219(X,Y)     led_line[LED_IND(X,Y)] ^= _BV(LED_BIT(X,Y))
80
-#define SET_LED_7219(X,Y) led_line[LED_IND(X,Y)] |= _BV(LED_BIT(X,Y))
81
-#define CLR_LED_7219(X,Y) led_line[LED_IND(X,Y)] &= ~_BV(LED_BIT(X,Y))
82
-#define BIT_7219(X,Y)     TEST(led_line[LED_IND(X,Y)], LED_BIT(X,Y))
75
+#define XOR_7219(X,Y) do{ led_line[LED_IND(X,Y)] ^=  _BV(LED_BIT(X,Y)); }while(0)
76
+#define SET_7219(X,Y) do{ led_line[LED_IND(X,Y)] |=  _BV(LED_BIT(X,Y)); }while(0)
77
+#define CLR_7219(X,Y) do{ led_line[LED_IND(X,Y)] &= ~_BV(LED_BIT(X,Y)); }while(0)
78
+#define BIT_7219(X,Y) TEST(led_line[LED_IND(X,Y)], LED_BIT(X,Y))
83 79
 
84 80
 #ifdef CPU_32_BIT
85 81
   #define SIG_DELAY() DELAY_US(1)   // Approximate a 1µs delay on 32-bit ARM
@@ -93,7 +89,7 @@ uint8_t Max7219::led_line[MAX7219_ROWS]; // = { 0 };
93 89
 
94 90
 void Max7219::error(const char * const func, const int32_t v1, const int32_t v2/*=-1*/) {
95 91
   #if ENABLED(MAX7219_ERRORS)
96
-    SERIAL_ECHOPGM("??? Max7219");
92
+    SERIAL_ECHOPGM("??? Max7219::");
97 93
     serialprintPGM(func);
98 94
     SERIAL_CHAR('(');
99 95
     SERIAL_ECHO(v1);
@@ -130,6 +126,7 @@ void Max7219::noop() {
130 126
     SIG_DELAY();
131 127
     WRITE(MAX7219_CLK_PIN, LOW);
132 128
     SIG_DELAY();
129
+    SIG_DELAY();
133 130
     WRITE(MAX7219_CLK_PIN, HIGH);
134 131
     SIG_DELAY();
135 132
   }
@@ -170,26 +167,22 @@ void Max7219::send(const uint8_t reg, const uint8_t data) {
170 167
 }
171 168
 
172 169
 // Send out a single native row of bits to all units
173
-void Max7219::all(const uint8_t line) {
174
-  for (uint8_t u = 0; u < MAX7219_ROWS; u += 8)
175
-    send(_ROW_REG(line), led_line[u + (line & 0x7)]);
170
+void Max7219::refresh_line(const uint8_t line) {
171
+  for (uint8_t u = MAX7219_NUMBER_UNITS; u--;)
172
+    send(LINE_REG(line), led_line[(u << 3) | (line & 0x7)]);
176 173
   pulse_load();
177 174
 }
178 175
 
179 176
 // Send out a single native row of bits to just one unit
180
-void Max7219::one(const uint8_t line) {
181
-  for (uint8_t u = MAX7219_NUMBER_UNITS; u--;) {
182
-    if (u == (line >> 3))
183
-      send(_ROW_REG(line), led_line[line]);
184
-    else
185
-      noop();
186
-  }
177
+void Max7219::refresh_unit_line(const uint8_t line) {
178
+  for (uint8_t u = MAX7219_NUMBER_UNITS; u--;)
179
+    if (u == (line >> 3)) send(LINE_REG(line), led_line[line]); else noop();
187 180
   pulse_load();
188 181
 }
189 182
 
190 183
 void Max7219::set(const uint8_t line, const uint8_t bits) {
191 184
   led_line[line] = bits;
192
-  all(line);
185
+  refresh_line(line);
193 186
 }
194 187
 
195 188
 #if ENABLED(MAX7219_NUMERIC)
@@ -231,7 +224,7 @@ void Max7219::led_set(const uint8_t x, const uint8_t y, const bool on) {
231 224
   if (x > MAX7219_X_LEDS - 1 || y > MAX7219_Y_LEDS - 1) return error(PSTR("led_set"), x, y);
232 225
   if (BIT_7219(x, y) == on) return;
233 226
   XOR_7219(x, y);
234
-  all(MAX7219_LINE_AXIS);
227
+  refresh_line(LED_IND(x, y));
235 228
 }
236 229
 
237 230
 void Max7219::led_on(const uint8_t x, const uint8_t y) {
@@ -250,8 +243,8 @@ void Max7219::led_toggle(const uint8_t x, const uint8_t y) {
250 243
 }
251 244
 
252 245
 void Max7219::send_row(const uint8_t row) {
253
-  #if _ROT == 90 || _ROT == 270
254
-    all(row);
246
+  #if _ROT == 0 || _ROT == 180
247
+    refresh_line(LED_IND(0, row));
255 248
   #else
256 249
     UNUSED(row);
257 250
     refresh();
@@ -260,7 +253,7 @@ void Max7219::send_row(const uint8_t row) {
260 253
 
261 254
 void Max7219::send_column(const uint8_t col) {
262 255
   #if _ROT == 90 || _ROT == 270
263
-    all(col);                               // Send the "column" out and strobe
256
+    refresh_line(LED_IND(col, 0));
264 257
   #else
265 258
     UNUSED(col);
266 259
     refresh();
@@ -272,17 +265,20 @@ void Max7219::clear() {
272 265
   refresh();
273 266
 }
274 267
 
268
+void Max7219::fill() {
269
+  memset(led_line, 0xFF, sizeof(led_line));
270
+  refresh();
271
+}
272
+
275 273
 void Max7219::clear_row(const uint8_t row) {
276 274
   if (row >= MAX7219_Y_LEDS) return error(PSTR("clear_row"), row);
277
-  for (uint8_t x = 0; x < MAX7219_X_LEDS; x++)
278
-    CLR_LED_7219(MAX7219_X_LEDS - 1 - x, row);
275
+  for (uint8_t x = 0; x < MAX7219_X_LEDS; x++) CLR_7219(x, row);
279 276
   send_row(row);
280 277
 }
281 278
 
282 279
 void Max7219::clear_column(const uint8_t col) {
283 280
   if (col >= MAX7219_X_LEDS) return error(PSTR("set_column"), col);
284
-  for (uint8_t y = 0; y < MAX7219_Y_LEDS; y++)
285
-    CLR_LED_7219(col, MAX7219_Y_LEDS - y - 1);
281
+  for (uint8_t y = 0; y < MAX7219_Y_LEDS; y++) CLR_7219(col, y);
286 282
   send_column(col);
287 283
 }
288 284
 
@@ -293,13 +289,10 @@ void Max7219::clear_column(const uint8_t col) {
293 289
  */
294 290
 void Max7219::set_row(const uint8_t row, const uint32_t val) {
295 291
   if (row >= MAX7219_Y_LEDS) return error(PSTR("set_row"), row);
296
-  uint32_t mask = 0x0000001;
292
+  uint32_t mask = _BV32(MAX7219_X_LEDS - 1);
297 293
   for (uint8_t x = 0; x < MAX7219_X_LEDS; x++) {
298
-    if (val & mask)
299
-      SET_LED_7219(MAX7219_X_LEDS - 1 - x, row);
300
-    else
301
-      CLR_LED_7219(MAX7219_X_LEDS - 1 - x, row);
302
-    mask <<= 1;
294
+    if (val & mask) SET_7219(x, row); else CLR_7219(x, row);
295
+    mask >>= 1;
303 296
   }
304 297
   send_row(row);
305 298
 }
@@ -311,13 +304,10 @@ void Max7219::set_row(const uint8_t row, const uint32_t val) {
311 304
  */
312 305
 void Max7219::set_column(const uint8_t col, const uint32_t val) {
313 306
   if (col >= MAX7219_X_LEDS) return error(PSTR("set_column"), col);
314
-  uint32_t mask = 0x0000001;
307
+  uint32_t mask = _BV32(MAX7219_Y_LEDS - 1);
315 308
   for (uint8_t y = 0; y < MAX7219_Y_LEDS; y++) {
316
-    if (val & mask)
317
-      SET_LED_7219(col, MAX7219_Y_LEDS - y - 1);
318
-    else
319
-      CLR_LED_7219(col, MAX7219_Y_LEDS - y - 1);
320
-    mask <<= 1;
309
+    if (val & mask) SET_7219(col, y); else CLR_7219(col, y);
310
+    mask >>= 1;
321 311
   }
322 312
   send_column(col);
323 313
 }
@@ -378,8 +368,8 @@ void Max7219::set_columns_32bits(const uint8_t x, uint32_t val) {
378 368
   #endif
379 369
 }
380 370
 
371
+// Initialize the Max7219
381 372
 void Max7219::register_setup() {
382
-  // Initialize the Max7219
383 373
   for (uint8_t i = 0; i < MAX7219_NUMBER_UNITS; i++)
384 374
     send(max7219_reg_scanLimit, 0x07);
385 375
   pulse_load();                        // tell the chips to load the clocked out data

+ 13
- 10
Marlin/src/feature/Max7219_Debug_LEDs.h View File

@@ -31,7 +31,7 @@
31 31
  *   #define MAX7219_DIN_PIN   78
32 32
  *   #define MAX7219_LOAD_PIN  79
33 33
  *
34
- * Max7219_init() is called automatically at startup, and then there are a number of
34
+ * max7219.init() is called automatically at startup, and then there are a number of
35 35
  * support functions available to control the LEDs in the 8x8 grid.
36 36
  *
37 37
  * If you are using the Max7219 matrix for firmware debug purposes in time sensitive
@@ -47,14 +47,14 @@
47 47
 #endif
48 48
 #define _ROT ((MAX7219_ROTATE + 360) % 360)
49 49
 
50
-#define MAX7219_ROWS (8 * (MAX7219_NUMBER_UNITS))
50
+#define MAX7219_LINES (8 * (MAX7219_NUMBER_UNITS))
51 51
 
52 52
 #if _ROT == 0 || _ROT == 180
53 53
   #define MAX7219_Y_LEDS          8
54
-  #define MAX7219_X_LEDS          MAX7219_ROWS
54
+  #define MAX7219_X_LEDS          MAX7219_LINES
55 55
 #elif _ROT == 90 || _ROT == 270
56 56
   #define MAX7219_X_LEDS          8
57
-  #define MAX7219_Y_LEDS          MAX7219_ROWS
57
+  #define MAX7219_Y_LEDS          MAX7219_LINES
58 58
 #else
59 59
   #error "MAX7219_ROTATE must be a multiple of +/- 90°."
60 60
 #endif
@@ -80,7 +80,7 @@
80 80
 
81 81
 class Max7219 {
82 82
 public:
83
-  static uint8_t led_line[MAX7219_ROWS];
83
+  static uint8_t led_line[MAX7219_LINES];
84 84
 
85 85
   Max7219() { }
86 86
 
@@ -93,13 +93,13 @@ public:
93 93
   static void send(const uint8_t reg, const uint8_t data);
94 94
 
95 95
   // Refresh all units
96
-  inline static void refresh() { for (uint8_t i = 0; i < 8; i++) all(i); }
96
+  inline static void refresh() { for (uint8_t i = 0; i < 8; i++) refresh_line(i); }
97 97
 
98
-  // Update a single native row on all units
99
-  static void all(const uint8_t line);
98
+  // Update a single native line on all units
99
+  static void refresh_line(const uint8_t line);
100 100
 
101
-  // Update a single native row on the target unit
102
-  static void one(const uint8_t line);
101
+  // Update a single native line on just one unit
102
+  static void refresh_unit_line(const uint8_t line);
103 103
 
104 104
   // Set a single LED by XY coordinate
105 105
   static void led_set(const uint8_t x, const uint8_t y, const bool on);
@@ -126,6 +126,9 @@ public:
126 126
   // Quickly clear the whole matrix
127 127
   static void clear();
128 128
 
129
+  // Quickly fill the whole matrix
130
+  static void fill();
131
+
129 132
   // Apply custom code to update the matrix
130 133
   static void idle_tasks();
131 134
 

+ 9
- 11
Marlin/src/gcode/feature/leds/M7219.cpp View File

@@ -43,13 +43,11 @@
43 43
  */
44 44
 void GcodeSuite::M7219() {
45 45
   if (parser.seen('I')) {
46
-    max7219.clear();
47 46
     max7219.register_setup();
47
+    max7219.clear();
48 48
   }
49 49
 
50
-  if (parser.seen('F'))
51
-    for (uint8_t x = 0; x < MAX7219_X_LEDS; x++)
52
-      max7219.set_column(x, 0xFFFFFFFF);
50
+  if (parser.seen('F')) max7219.fill();
53 51
 
54 52
   const uint32_t v = parser.ulongval('V');
55 53
 
@@ -69,18 +67,18 @@ void GcodeSuite::M7219() {
69 67
       max7219.led_toggle(x, y);
70 68
   }
71 69
   else if (parser.seen('D')) {
72
-    const uint8_t r = parser.value_byte();
73
-    if (r < MAX7219_ROWS) {
74
-      max7219.led_line[r] = v;
75
-      return max7219.all(r);
70
+    const uint8_t line = parser.byteval('D') + (parser.byteval('U') << 3);
71
+    if (line < MAX7219_LINES) {
72
+      max7219.led_line[line] = v;
73
+      return max7219.refresh_line(line);
76 74
     }
77 75
   }
78 76
 
79 77
   if (parser.seen('P')) {
80
-    for (uint8_t r = 0; r < MAX7219_ROWS; r++) {
78
+    for (uint8_t r = 0; r < MAX7219_LINES; r++) {
81 79
       SERIAL_ECHOPGM("led_line[");
82
-      if (r < 10) SERIAL_CHAR('_');
83
-      SERIAL_ECHO(r);
80
+      if (r < 10) SERIAL_CHAR(' ');
81
+      SERIAL_ECHO(int(r));
84 82
       SERIAL_ECHO("]=");
85 83
       for (uint8_t b = 8; b--;) SERIAL_CHAR('0' + TEST(max7219.led_line[r], b));
86 84
       SERIAL_EOL();

Loading…
Cancel
Save