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
 
50
 
51
 Max7219 max7219;
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
 #if _ROT == 0 || _ROT == 270
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
 #else
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
 #endif
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
 #else
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
 #endif
67
 #endif
67
 #if _ROT == 0 || _ROT == 180
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
   #define LED_BIT(X,Y)  _LED_BIT(X)
70
   #define LED_BIT(X,Y)  _LED_BIT(X)
71
 #elif _ROT == 90 || _ROT == 270
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
   #define LED_BIT(X,Y)  _LED_BIT(Y)
73
   #define LED_BIT(X,Y)  _LED_BIT(Y)
75
-#else
76
-  #error "MAX7219_ROTATE must be a multiple of +/- 90°."
77
 #endif
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
 #ifdef CPU_32_BIT
80
 #ifdef CPU_32_BIT
85
   #define SIG_DELAY() DELAY_US(1)   // Approximate a 1µs delay on 32-bit ARM
81
   #define SIG_DELAY() DELAY_US(1)   // Approximate a 1µs delay on 32-bit ARM
93
 
89
 
94
 void Max7219::error(const char * const func, const int32_t v1, const int32_t v2/*=-1*/) {
90
 void Max7219::error(const char * const func, const int32_t v1, const int32_t v2/*=-1*/) {
95
   #if ENABLED(MAX7219_ERRORS)
91
   #if ENABLED(MAX7219_ERRORS)
96
-    SERIAL_ECHOPGM("??? Max7219");
92
+    SERIAL_ECHOPGM("??? Max7219::");
97
     serialprintPGM(func);
93
     serialprintPGM(func);
98
     SERIAL_CHAR('(');
94
     SERIAL_CHAR('(');
99
     SERIAL_ECHO(v1);
95
     SERIAL_ECHO(v1);
130
     SIG_DELAY();
126
     SIG_DELAY();
131
     WRITE(MAX7219_CLK_PIN, LOW);
127
     WRITE(MAX7219_CLK_PIN, LOW);
132
     SIG_DELAY();
128
     SIG_DELAY();
129
+    SIG_DELAY();
133
     WRITE(MAX7219_CLK_PIN, HIGH);
130
     WRITE(MAX7219_CLK_PIN, HIGH);
134
     SIG_DELAY();
131
     SIG_DELAY();
135
   }
132
   }
170
 }
167
 }
171
 
168
 
172
 // Send out a single native row of bits to all units
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
   pulse_load();
173
   pulse_load();
177
 }
174
 }
178
 
175
 
179
 // Send out a single native row of bits to just one unit
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
   pulse_load();
180
   pulse_load();
188
 }
181
 }
189
 
182
 
190
 void Max7219::set(const uint8_t line, const uint8_t bits) {
183
 void Max7219::set(const uint8_t line, const uint8_t bits) {
191
   led_line[line] = bits;
184
   led_line[line] = bits;
192
-  all(line);
185
+  refresh_line(line);
193
 }
186
 }
194
 
187
 
195
 #if ENABLED(MAX7219_NUMERIC)
188
 #if ENABLED(MAX7219_NUMERIC)
231
   if (x > MAX7219_X_LEDS - 1 || y > MAX7219_Y_LEDS - 1) return error(PSTR("led_set"), x, y);
224
   if (x > MAX7219_X_LEDS - 1 || y > MAX7219_Y_LEDS - 1) return error(PSTR("led_set"), x, y);
232
   if (BIT_7219(x, y) == on) return;
225
   if (BIT_7219(x, y) == on) return;
233
   XOR_7219(x, y);
226
   XOR_7219(x, y);
234
-  all(MAX7219_LINE_AXIS);
227
+  refresh_line(LED_IND(x, y));
235
 }
228
 }
236
 
229
 
237
 void Max7219::led_on(const uint8_t x, const uint8_t y) {
230
 void Max7219::led_on(const uint8_t x, const uint8_t y) {
250
 }
243
 }
251
 
244
 
252
 void Max7219::send_row(const uint8_t row) {
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
   #else
248
   #else
256
     UNUSED(row);
249
     UNUSED(row);
257
     refresh();
250
     refresh();
260
 
253
 
261
 void Max7219::send_column(const uint8_t col) {
254
 void Max7219::send_column(const uint8_t col) {
262
   #if _ROT == 90 || _ROT == 270
255
   #if _ROT == 90 || _ROT == 270
263
-    all(col);                               // Send the "column" out and strobe
256
+    refresh_line(LED_IND(col, 0));
264
   #else
257
   #else
265
     UNUSED(col);
258
     UNUSED(col);
266
     refresh();
259
     refresh();
272
   refresh();
265
   refresh();
273
 }
266
 }
274
 
267
 
268
+void Max7219::fill() {
269
+  memset(led_line, 0xFF, sizeof(led_line));
270
+  refresh();
271
+}
272
+
275
 void Max7219::clear_row(const uint8_t row) {
273
 void Max7219::clear_row(const uint8_t row) {
276
   if (row >= MAX7219_Y_LEDS) return error(PSTR("clear_row"), row);
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
   send_row(row);
276
   send_row(row);
280
 }
277
 }
281
 
278
 
282
 void Max7219::clear_column(const uint8_t col) {
279
 void Max7219::clear_column(const uint8_t col) {
283
   if (col >= MAX7219_X_LEDS) return error(PSTR("set_column"), col);
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
   send_column(col);
282
   send_column(col);
287
 }
283
 }
288
 
284
 
293
  */
289
  */
294
 void Max7219::set_row(const uint8_t row, const uint32_t val) {
290
 void Max7219::set_row(const uint8_t row, const uint32_t val) {
295
   if (row >= MAX7219_Y_LEDS) return error(PSTR("set_row"), row);
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
   for (uint8_t x = 0; x < MAX7219_X_LEDS; x++) {
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
   send_row(row);
297
   send_row(row);
305
 }
298
 }
311
  */
304
  */
312
 void Max7219::set_column(const uint8_t col, const uint32_t val) {
305
 void Max7219::set_column(const uint8_t col, const uint32_t val) {
313
   if (col >= MAX7219_X_LEDS) return error(PSTR("set_column"), col);
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
   for (uint8_t y = 0; y < MAX7219_Y_LEDS; y++) {
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
   send_column(col);
312
   send_column(col);
323
 }
313
 }
378
   #endif
368
   #endif
379
 }
369
 }
380
 
370
 
371
+// Initialize the Max7219
381
 void Max7219::register_setup() {
372
 void Max7219::register_setup() {
382
-  // Initialize the Max7219
383
   for (uint8_t i = 0; i < MAX7219_NUMBER_UNITS; i++)
373
   for (uint8_t i = 0; i < MAX7219_NUMBER_UNITS; i++)
384
     send(max7219_reg_scanLimit, 0x07);
374
     send(max7219_reg_scanLimit, 0x07);
385
   pulse_load();                        // tell the chips to load the clocked out data
375
   pulse_load();                        // tell the chips to load the clocked out data

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

31
  *   #define MAX7219_DIN_PIN   78
31
  *   #define MAX7219_DIN_PIN   78
32
  *   #define MAX7219_LOAD_PIN  79
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
  * support functions available to control the LEDs in the 8x8 grid.
35
  * support functions available to control the LEDs in the 8x8 grid.
36
  *
36
  *
37
  * If you are using the Max7219 matrix for firmware debug purposes in time sensitive
37
  * If you are using the Max7219 matrix for firmware debug purposes in time sensitive
47
 #endif
47
 #endif
48
 #define _ROT ((MAX7219_ROTATE + 360) % 360)
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
 #if _ROT == 0 || _ROT == 180
52
 #if _ROT == 0 || _ROT == 180
53
   #define MAX7219_Y_LEDS          8
53
   #define MAX7219_Y_LEDS          8
54
-  #define MAX7219_X_LEDS          MAX7219_ROWS
54
+  #define MAX7219_X_LEDS          MAX7219_LINES
55
 #elif _ROT == 90 || _ROT == 270
55
 #elif _ROT == 90 || _ROT == 270
56
   #define MAX7219_X_LEDS          8
56
   #define MAX7219_X_LEDS          8
57
-  #define MAX7219_Y_LEDS          MAX7219_ROWS
57
+  #define MAX7219_Y_LEDS          MAX7219_LINES
58
 #else
58
 #else
59
   #error "MAX7219_ROTATE must be a multiple of +/- 90°."
59
   #error "MAX7219_ROTATE must be a multiple of +/- 90°."
60
 #endif
60
 #endif
80
 
80
 
81
 class Max7219 {
81
 class Max7219 {
82
 public:
82
 public:
83
-  static uint8_t led_line[MAX7219_ROWS];
83
+  static uint8_t led_line[MAX7219_LINES];
84
 
84
 
85
   Max7219() { }
85
   Max7219() { }
86
 
86
 
93
   static void send(const uint8_t reg, const uint8_t data);
93
   static void send(const uint8_t reg, const uint8_t data);
94
 
94
 
95
   // Refresh all units
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
   // Set a single LED by XY coordinate
104
   // Set a single LED by XY coordinate
105
   static void led_set(const uint8_t x, const uint8_t y, const bool on);
105
   static void led_set(const uint8_t x, const uint8_t y, const bool on);
126
   // Quickly clear the whole matrix
126
   // Quickly clear the whole matrix
127
   static void clear();
127
   static void clear();
128
 
128
 
129
+  // Quickly fill the whole matrix
130
+  static void fill();
131
+
129
   // Apply custom code to update the matrix
132
   // Apply custom code to update the matrix
130
   static void idle_tasks();
133
   static void idle_tasks();
131
 
134
 

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

43
  */
43
  */
44
 void GcodeSuite::M7219() {
44
 void GcodeSuite::M7219() {
45
   if (parser.seen('I')) {
45
   if (parser.seen('I')) {
46
-    max7219.clear();
47
     max7219.register_setup();
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
   const uint32_t v = parser.ulongval('V');
52
   const uint32_t v = parser.ulongval('V');
55
 
53
 
69
       max7219.led_toggle(x, y);
67
       max7219.led_toggle(x, y);
70
   }
68
   }
71
   else if (parser.seen('D')) {
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
   if (parser.seen('P')) {
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
       SERIAL_ECHOPGM("led_line[");
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
       SERIAL_ECHO("]=");
82
       SERIAL_ECHO("]=");
85
       for (uint8_t b = 8; b--;) SERIAL_CHAR('0' + TEST(max7219.led_line[r], b));
83
       for (uint8_t b = 8; b--;) SERIAL_CHAR('0' + TEST(max7219.led_line[r], b));
86
       SERIAL_EOL();
84
       SERIAL_EOL();

Loading…
Cancel
Save