Fix up Max7219 orientations (#11596)
This commit is contained in:
		
							parent
							
								
									d05b23941d
								
							
						
					
					
						commit
						8f0bbdcc9b
					
				| @ -50,35 +50,31 @@ | ||||
| 
 | ||||
| Max7219 max7219; | ||||
| 
 | ||||
| uint8_t Max7219::led_line[MAX7219_ROWS]; // = { 0 };
 | ||||
| uint8_t Max7219::led_line[MAX7219_LINES]; // = { 0 };
 | ||||
| 
 | ||||
| #define LINE_REG(Q)     (max7219_reg_digit0 + ((Q) & 0x7)) | ||||
| #if _ROT == 0 || _ROT == 270 | ||||
|   #define _LED_BIT(Q)   (7 - ((Q) & 0x07)) | ||||
|   #define _LED_BIT(Q)   (7 - ((Q) & 0x7)) | ||||
|   #define _LED_UNIT(Q)  ((Q) & ~0x7) | ||||
| #else | ||||
|   #define _LED_BIT(Q)   ((Q) & 0x07) | ||||
|   #define _LED_BIT(Q)   ((Q) & 0x7) | ||||
|   #define _LED_UNIT(Q)  ((MAX7219_NUMBER_UNITS - 1 - ((Q) >> 3)) << 3) | ||||
| #endif | ||||
| #if _ROT >= 180 | ||||
|   #define _LED_IND(P,Q) (P + ((Q) & ~0x07)) | ||||
|   #define _ROW_REG(Q)   (max7219_reg_digit7 - ((Q) & 0x7)) | ||||
| #if _ROT < 180 | ||||
|   #define _LED_IND(P,Q) (_LED_UNIT(P) + (Q)) | ||||
| #else | ||||
|   #define _LED_IND(P,Q) (P + ((Q) & ~0x07)) | ||||
|   #define _ROW_REG(Q)   (max7219_reg_digit0 + ((Q) & 0x7)) | ||||
|   #define _LED_IND(P,Q) (_LED_UNIT(P) + (7 - ((Q) & 0x7))) | ||||
| #endif | ||||
| #if _ROT == 0 || _ROT == 180 | ||||
|   #define MAX7219_LINE_AXIS y | ||||
|   #define LED_IND(X,Y)  _LED_IND(Y,X) | ||||
|   #define LED_IND(X,Y)  _LED_IND(X,Y) | ||||
|   #define LED_BIT(X,Y)  _LED_BIT(X) | ||||
| #elif _ROT == 90 || _ROT == 270 | ||||
|   #define MAX7219_LINE_AXIS x | ||||
|   #define LED_IND(X,Y)  _LED_IND(X,Y) | ||||
|   #define LED_IND(X,Y)  _LED_IND(Y,X) | ||||
|   #define LED_BIT(X,Y)  _LED_BIT(Y) | ||||
| #else | ||||
|   #error "MAX7219_ROTATE must be a multiple of +/- 90°." | ||||
| #endif | ||||
| 
 | ||||
| #define XOR_7219(X,Y)     led_line[LED_IND(X,Y)] ^= _BV(LED_BIT(X,Y)) | ||||
| #define SET_LED_7219(X,Y) led_line[LED_IND(X,Y)] |= _BV(LED_BIT(X,Y)) | ||||
| #define CLR_LED_7219(X,Y) led_line[LED_IND(X,Y)] &= ~_BV(LED_BIT(X,Y)) | ||||
| #define XOR_7219(X,Y) do{ led_line[LED_IND(X,Y)] ^=  _BV(LED_BIT(X,Y)); }while(0) | ||||
| #define SET_7219(X,Y) do{ led_line[LED_IND(X,Y)] |=  _BV(LED_BIT(X,Y)); }while(0) | ||||
| #define CLR_7219(X,Y) do{ led_line[LED_IND(X,Y)] &= ~_BV(LED_BIT(X,Y)); }while(0) | ||||
| #define BIT_7219(X,Y) TEST(led_line[LED_IND(X,Y)], LED_BIT(X,Y)) | ||||
| 
 | ||||
| #ifdef CPU_32_BIT | ||||
| @ -93,7 +89,7 @@ uint8_t Max7219::led_line[MAX7219_ROWS]; // = { 0 }; | ||||
| 
 | ||||
| void Max7219::error(const char * const func, const int32_t v1, const int32_t v2/*=-1*/) { | ||||
|   #if ENABLED(MAX7219_ERRORS) | ||||
|     SERIAL_ECHOPGM("??? Max7219"); | ||||
|     SERIAL_ECHOPGM("??? Max7219::"); | ||||
|     serialprintPGM(func); | ||||
|     SERIAL_CHAR('('); | ||||
|     SERIAL_ECHO(v1); | ||||
| @ -130,6 +126,7 @@ void Max7219::noop() { | ||||
|     SIG_DELAY(); | ||||
|     WRITE(MAX7219_CLK_PIN, LOW); | ||||
|     SIG_DELAY(); | ||||
|     SIG_DELAY(); | ||||
|     WRITE(MAX7219_CLK_PIN, HIGH); | ||||
|     SIG_DELAY(); | ||||
|   } | ||||
| @ -170,26 +167,22 @@ void Max7219::send(const uint8_t reg, const uint8_t data) { | ||||
| } | ||||
| 
 | ||||
| // Send out a single native row of bits to all units
 | ||||
| void Max7219::all(const uint8_t line) { | ||||
|   for (uint8_t u = 0; u < MAX7219_ROWS; u += 8) | ||||
|     send(_ROW_REG(line), led_line[u + (line & 0x7)]); | ||||
| void Max7219::refresh_line(const uint8_t line) { | ||||
|   for (uint8_t u = MAX7219_NUMBER_UNITS; u--;) | ||||
|     send(LINE_REG(line), led_line[(u << 3) | (line & 0x7)]); | ||||
|   pulse_load(); | ||||
| } | ||||
| 
 | ||||
| // Send out a single native row of bits to just one unit
 | ||||
| void Max7219::one(const uint8_t line) { | ||||
|   for (uint8_t u = MAX7219_NUMBER_UNITS; u--;) { | ||||
|     if (u == (line >> 3)) | ||||
|       send(_ROW_REG(line), led_line[line]); | ||||
|     else | ||||
|       noop(); | ||||
|   } | ||||
| void Max7219::refresh_unit_line(const uint8_t line) { | ||||
|   for (uint8_t u = MAX7219_NUMBER_UNITS; u--;) | ||||
|     if (u == (line >> 3)) send(LINE_REG(line), led_line[line]); else noop(); | ||||
|   pulse_load(); | ||||
| } | ||||
| 
 | ||||
| void Max7219::set(const uint8_t line, const uint8_t bits) { | ||||
|   led_line[line] = bits; | ||||
|   all(line); | ||||
|   refresh_line(line); | ||||
| } | ||||
| 
 | ||||
| #if ENABLED(MAX7219_NUMERIC) | ||||
| @ -231,7 +224,7 @@ void Max7219::led_set(const uint8_t x, const uint8_t y, const bool on) { | ||||
|   if (x > MAX7219_X_LEDS - 1 || y > MAX7219_Y_LEDS - 1) return error(PSTR("led_set"), x, y); | ||||
|   if (BIT_7219(x, y) == on) return; | ||||
|   XOR_7219(x, y); | ||||
|   all(MAX7219_LINE_AXIS); | ||||
|   refresh_line(LED_IND(x, y)); | ||||
| } | ||||
| 
 | ||||
| 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) { | ||||
| } | ||||
| 
 | ||||
| void Max7219::send_row(const uint8_t row) { | ||||
|   #if _ROT == 90 || _ROT == 270 | ||||
|     all(row); | ||||
|   #if _ROT == 0 || _ROT == 180 | ||||
|     refresh_line(LED_IND(0, row)); | ||||
|   #else | ||||
|     UNUSED(row); | ||||
|     refresh(); | ||||
| @ -260,7 +253,7 @@ void Max7219::send_row(const uint8_t row) { | ||||
| 
 | ||||
| void Max7219::send_column(const uint8_t col) { | ||||
|   #if _ROT == 90 || _ROT == 270 | ||||
|     all(col);                               // Send the "column" out and strobe
 | ||||
|     refresh_line(LED_IND(col, 0)); | ||||
|   #else | ||||
|     UNUSED(col); | ||||
|     refresh(); | ||||
| @ -272,17 +265,20 @@ void Max7219::clear() { | ||||
|   refresh(); | ||||
| } | ||||
| 
 | ||||
| void Max7219::fill() { | ||||
|   memset(led_line, 0xFF, sizeof(led_line)); | ||||
|   refresh(); | ||||
| } | ||||
| 
 | ||||
| void Max7219::clear_row(const uint8_t row) { | ||||
|   if (row >= MAX7219_Y_LEDS) return error(PSTR("clear_row"), row); | ||||
|   for (uint8_t x = 0; x < MAX7219_X_LEDS; x++) | ||||
|     CLR_LED_7219(MAX7219_X_LEDS - 1 - x, row); | ||||
|   for (uint8_t x = 0; x < MAX7219_X_LEDS; x++) CLR_7219(x, row); | ||||
|   send_row(row); | ||||
| } | ||||
| 
 | ||||
| void Max7219::clear_column(const uint8_t col) { | ||||
|   if (col >= MAX7219_X_LEDS) return error(PSTR("set_column"), col); | ||||
|   for (uint8_t y = 0; y < MAX7219_Y_LEDS; y++) | ||||
|     CLR_LED_7219(col, MAX7219_Y_LEDS - y - 1); | ||||
|   for (uint8_t y = 0; y < MAX7219_Y_LEDS; y++) CLR_7219(col, y); | ||||
|   send_column(col); | ||||
| } | ||||
| 
 | ||||
| @ -293,13 +289,10 @@ void Max7219::clear_column(const uint8_t col) { | ||||
|  */ | ||||
| void Max7219::set_row(const uint8_t row, const uint32_t val) { | ||||
|   if (row >= MAX7219_Y_LEDS) return error(PSTR("set_row"), row); | ||||
|   uint32_t mask = 0x0000001; | ||||
|   uint32_t mask = _BV32(MAX7219_X_LEDS - 1); | ||||
|   for (uint8_t x = 0; x < MAX7219_X_LEDS; x++) { | ||||
|     if (val & mask) | ||||
|       SET_LED_7219(MAX7219_X_LEDS - 1 - x, row); | ||||
|     else | ||||
|       CLR_LED_7219(MAX7219_X_LEDS - 1 - x, row); | ||||
|     mask <<= 1; | ||||
|     if (val & mask) SET_7219(x, row); else CLR_7219(x, row); | ||||
|     mask >>= 1; | ||||
|   } | ||||
|   send_row(row); | ||||
| } | ||||
| @ -311,13 +304,10 @@ void Max7219::set_row(const uint8_t row, const uint32_t val) { | ||||
|  */ | ||||
| void Max7219::set_column(const uint8_t col, const uint32_t val) { | ||||
|   if (col >= MAX7219_X_LEDS) return error(PSTR("set_column"), col); | ||||
|   uint32_t mask = 0x0000001; | ||||
|   uint32_t mask = _BV32(MAX7219_Y_LEDS - 1); | ||||
|   for (uint8_t y = 0; y < MAX7219_Y_LEDS; y++) { | ||||
|     if (val & mask) | ||||
|       SET_LED_7219(col, MAX7219_Y_LEDS - y - 1); | ||||
|     else | ||||
|       CLR_LED_7219(col, MAX7219_Y_LEDS - y - 1); | ||||
|     mask <<= 1; | ||||
|     if (val & mask) SET_7219(col, y); else CLR_7219(col, y); | ||||
|     mask >>= 1; | ||||
|   } | ||||
|   send_column(col); | ||||
| } | ||||
| @ -378,8 +368,8 @@ void Max7219::set_columns_32bits(const uint8_t x, uint32_t val) { | ||||
|   #endif | ||||
| } | ||||
| 
 | ||||
| void Max7219::register_setup() { | ||||
| // Initialize the Max7219
 | ||||
| void Max7219::register_setup() { | ||||
|   for (uint8_t i = 0; i < MAX7219_NUMBER_UNITS; i++) | ||||
|     send(max7219_reg_scanLimit, 0x07); | ||||
|   pulse_load();                        // tell the chips to load the clocked out data
 | ||||
|  | ||||
| @ -31,7 +31,7 @@ | ||||
|  *   #define MAX7219_DIN_PIN   78 | ||||
|  *   #define MAX7219_LOAD_PIN  79 | ||||
|  * | ||||
|  * Max7219_init() is called automatically at startup, and then there are a number of | ||||
|  * max7219.init() is called automatically at startup, and then there are a number of | ||||
|  * support functions available to control the LEDs in the 8x8 grid. | ||||
|  * | ||||
|  * If you are using the Max7219 matrix for firmware debug purposes in time sensitive | ||||
| @ -47,14 +47,14 @@ | ||||
| #endif | ||||
| #define _ROT ((MAX7219_ROTATE + 360) % 360) | ||||
| 
 | ||||
| #define MAX7219_ROWS (8 * (MAX7219_NUMBER_UNITS)) | ||||
| #define MAX7219_LINES (8 * (MAX7219_NUMBER_UNITS)) | ||||
| 
 | ||||
| #if _ROT == 0 || _ROT == 180 | ||||
|   #define MAX7219_Y_LEDS          8 | ||||
|   #define MAX7219_X_LEDS          MAX7219_ROWS | ||||
|   #define MAX7219_X_LEDS          MAX7219_LINES | ||||
| #elif _ROT == 90 || _ROT == 270 | ||||
|   #define MAX7219_X_LEDS          8 | ||||
|   #define MAX7219_Y_LEDS          MAX7219_ROWS | ||||
|   #define MAX7219_Y_LEDS          MAX7219_LINES | ||||
| #else | ||||
|   #error "MAX7219_ROTATE must be a multiple of +/- 90°." | ||||
| #endif | ||||
| @ -80,7 +80,7 @@ | ||||
| 
 | ||||
| class Max7219 { | ||||
| public: | ||||
|   static uint8_t led_line[MAX7219_ROWS]; | ||||
|   static uint8_t led_line[MAX7219_LINES]; | ||||
| 
 | ||||
|   Max7219() { } | ||||
| 
 | ||||
| @ -93,13 +93,13 @@ public: | ||||
|   static void send(const uint8_t reg, const uint8_t data); | ||||
| 
 | ||||
|   // Refresh all units
 | ||||
|   inline static void refresh() { for (uint8_t i = 0; i < 8; i++) all(i); } | ||||
|   inline static void refresh() { for (uint8_t i = 0; i < 8; i++) refresh_line(i); } | ||||
| 
 | ||||
|   // Update a single native row on all units
 | ||||
|   static void all(const uint8_t line); | ||||
|   // Update a single native line on all units
 | ||||
|   static void refresh_line(const uint8_t line); | ||||
| 
 | ||||
|   // Update a single native row on the target unit
 | ||||
|   static void one(const uint8_t line); | ||||
|   // Update a single native line on just one unit
 | ||||
|   static void refresh_unit_line(const uint8_t line); | ||||
| 
 | ||||
|   // Set a single LED by XY coordinate
 | ||||
|   static void led_set(const uint8_t x, const uint8_t y, const bool on); | ||||
| @ -126,6 +126,9 @@ public: | ||||
|   // Quickly clear the whole matrix
 | ||||
|   static void clear(); | ||||
| 
 | ||||
|   // Quickly fill the whole matrix
 | ||||
|   static void fill(); | ||||
| 
 | ||||
|   // Apply custom code to update the matrix
 | ||||
|   static void idle_tasks(); | ||||
| 
 | ||||
|  | ||||
| @ -43,13 +43,11 @@ | ||||
|  */ | ||||
| void GcodeSuite::M7219() { | ||||
|   if (parser.seen('I')) { | ||||
|     max7219.clear(); | ||||
|     max7219.register_setup(); | ||||
|     max7219.clear(); | ||||
|   } | ||||
| 
 | ||||
|   if (parser.seen('F')) | ||||
|     for (uint8_t x = 0; x < MAX7219_X_LEDS; x++) | ||||
|       max7219.set_column(x, 0xFFFFFFFF); | ||||
|   if (parser.seen('F')) max7219.fill(); | ||||
| 
 | ||||
|   const uint32_t v = parser.ulongval('V'); | ||||
| 
 | ||||
| @ -69,18 +67,18 @@ void GcodeSuite::M7219() { | ||||
|       max7219.led_toggle(x, y); | ||||
|   } | ||||
|   else if (parser.seen('D')) { | ||||
|     const uint8_t r = parser.value_byte(); | ||||
|     if (r < MAX7219_ROWS) { | ||||
|       max7219.led_line[r] = v; | ||||
|       return max7219.all(r); | ||||
|     const uint8_t line = parser.byteval('D') + (parser.byteval('U') << 3); | ||||
|     if (line < MAX7219_LINES) { | ||||
|       max7219.led_line[line] = v; | ||||
|       return max7219.refresh_line(line); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   if (parser.seen('P')) { | ||||
|     for (uint8_t r = 0; r < MAX7219_ROWS; r++) { | ||||
|     for (uint8_t r = 0; r < MAX7219_LINES; r++) { | ||||
|       SERIAL_ECHOPGM("led_line["); | ||||
|       if (r < 10) SERIAL_CHAR('_'); | ||||
|       SERIAL_ECHO(r); | ||||
|       if (r < 10) SERIAL_CHAR(' '); | ||||
|       SERIAL_ECHO(int(r)); | ||||
|       SERIAL_ECHO("]="); | ||||
|       for (uint8_t b = 8; b--;) SERIAL_CHAR('0' + TEST(max7219.led_line[r], b)); | ||||
|       SERIAL_EOL(); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user