From 0bdea3f8542a59d2f0d3ffbede3255d29dea8218 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Mon, 10 Sep 2018 04:16:25 -0500 Subject: [PATCH] Fit task code for updated Max7219 --- Marlin/src/Marlin.cpp | 37 ++++------ Marlin/src/feature/Max7219_Debug_LEDs.cpp | 90 ++++++++++++----------- Marlin/src/feature/Max7219_Debug_LEDs.h | 36 +++++---- Marlin/src/gcode/gcode.h | 1 + platformio.ini | 1 + 5 files changed, 84 insertions(+), 81 deletions(-) diff --git a/Marlin/src/Marlin.cpp b/Marlin/src/Marlin.cpp index 6188d7f954..69f725f416 100644 --- a/Marlin/src/Marlin.cpp +++ b/Marlin/src/Marlin.cpp @@ -532,7 +532,6 @@ void manage_inactivity(const bool ignore_stepper_queue/*=false*/) { } #if ENABLED(MAX7219_DEBUG) - QueueHandle_t Max7219_Queue = NULL; unsigned long int zz = 0, // Temporary - will go away soon - used by loop() zzz = 0, // Temporary - will go away soon - used by Marlin_idle() zzzz = 0, // Temporary - will go away soon - used by Marlin_main_loop() @@ -549,7 +548,7 @@ void idle( ) { #if ENABLED(MAX7219_DEBUG) zzzzz++; - Max7219_Do_Cmd(LED_SET_ROW, 0, 5, uint8_t(zzzzz >> 5)); + max7219.do_command(LED_SET_ROW, 0, 5, uint8_t(zzzzz >> 5)); #endif lcd_update(); @@ -692,22 +691,10 @@ void setup() { #if ENABLED(MAX7219_DEBUG) max7219.init(); - - Max7219_Queue = xQueueCreate(3 /* # of queue items */, sizeof(LED_Msg)); - if (Max7219_Queue == NULL) { - Max7219_Set_Row(0, 0xe5); - for (;;); - } - - // Create the Max7219 debug task. It is very low priority in an attempt to not affect the - // normal timing of Marlin. But if too many messages are sent too quickly to the task, - // the command queue will fill up and the sender will block until a message has been drained - // to make room for the next message. - xTaskCreate((TaskFunction_t)Max7219_Cmd_Processor, "Max7219_LEDs", 200 /* Stack size */, NULL, 2 /* priority */, NULL); #endif - ptr = (char *) malloc(75); // reserve some memory for the RTOS to use later. It will be given - // back after the Marlin-loop task is started. + ptr = (char*)malloc(75); // reserve some memory for the RTOS to use later. It will be given + // back after the Marlin-loop task is started. xTaskCreate((TaskFunction_t) Marlin_idle, "Marlin_idle", 450 /* Stack size */, NULL, 4 /* priority */, NULL ); @@ -720,7 +707,7 @@ void setup() { if (pdPASS == xTaskCreate((TaskFunction_t) Marlin_main_loop, "Marlin_loop", ss /* Stack size */, NULL, 5 /* priority */, NULL)) break; - if (ss < 350) for (;;); // Die if Marlin_main_loop didn't get enough memory. + if (ss < 350) for (;;) { /* nada */ } // Die if Marlin_main_loop didn't get enough memory. free(ptr); // give back the memory we reserved for generic RTOS usage @@ -986,15 +973,17 @@ TaskFunction_t Marlin_main_loop() { // In the mean time... settings.load() is run at the start of the Marlin_main_loop() // task. This approach seems to work around what ever the problem is. - Max7219_Do_Cmd(LED_CLEAR_MATRIX, 0, 0, 0); + #if ENABLED(MAX7219_DEBUG) + max7219.do_command(LED_CLEAR_MATRIX, 0, 0, 0); + #endif for (;;) { #if ENABLED(MAX7219_DEBUG) zzzz++; - Max7219_Do_Cmd(LED_SET_ROW, 0, 7, uint8_t(zzzz >> 4)); + max7219.do_command(LED_SET_ROW, 0, 7, uint8_t(zzzz >> 4)); if ((zzzz & 0x20) == 0x20) - Max7219_Do_Cmd(LED_TOGGLE, 5, 1, 0); + max7219.do_command(LED_TOGGLE, 5, 1, 0); #endif #if ENABLED(SDSUPPORT) @@ -1033,7 +1022,11 @@ TaskFunction_t Marlin_main_loop() { TaskFunction_t Marlin_idle() { for (;;) { - Max7219_Do_Cmd(LED_SET_ROW, 0, 6, (uint8_t) (zzz++>>3)); + + #if ENABLED(MAX7219_DEBUG) + max7219.do_command(LED_SET_ROW, 0, 6, (uint8_t) (zzz++ >> 3)); + #endif + vTaskDelay(3); } } @@ -1050,6 +1043,6 @@ TaskFunction_t Marlin_idle() { void loop() { #if ENABLED(MAX7219_DEBUG) - Max7219_LED_Toggle(7, 0); // Max7219_Do_Cmd(LED_TOGGLE, 7, 0, 0); can not be used because loop() is not allowed to block! + max7219.led_toggle(7, 0); // max7219.do_command(LED_TOGGLE, 7, 0, 0); // can't be used because loop() is not allowed to block! #endif } diff --git a/Marlin/src/feature/Max7219_Debug_LEDs.cpp b/Marlin/src/feature/Max7219_Debug_LEDs.cpp index cf522739cd..39ae5a16b4 100644 --- a/Marlin/src/feature/Max7219_Debug_LEDs.cpp +++ b/Marlin/src/feature/Max7219_Debug_LEDs.cpp @@ -55,6 +55,8 @@ Max7219 max7219; uint8_t Max7219::led_line[MAX7219_LINES]; // = { 0 }; +QueueHandle_t Max7219::queue; // = NULL + #define LINE_REG(Q) (max7219_reg_digit0 + ((Q) & 0x7)) #if _ROT == 0 || _ROT == 270 #define _LED_BIT(Q) (7 - ((Q) & 0x7)) @@ -104,58 +106,42 @@ void Max7219::error(const char * const func, const int32_t v1, const int32_t v2/ #endif } -extern QueueHandle_t Max7219_Queue; -struct LED_Msg incoming_led_msg; -#define MSG incoming_led_msg +void Max7219::do_command(uint8_t msg, uint8_t col, uint8_t row, uint32_t val ) { + led_msg_t out_led_msg; -void Max7219_Do_Cmd(uint8_t msg, uint8_t col, uint8_t row, uint32_t val ) { - struct LED_Msg out_going_led_msg; + out_led_msg.operation = msg; + out_led_msg.col = col; + out_led_msg.row = row; + out_led_msg.val = val; - out_going_led_msg.operation = msg; - out_going_led_msg.col = col; - out_going_led_msg.row = row; - out_going_led_msg.val = val; - - while (pdPASS != xQueueSendToBack(Max7219_Queue, &out_going_led_msg, 100)) { /* nada */ } + while (pdPASS != xQueueSendToBack(queue, &out_led_msg, 100)) { /* nada */ } } -TaskFunction_t Max7219_Cmd_Processor(void *ptr) { +TaskFunction_t Max7219::command_processor(void *ptr) { - while (Max7219_Queue == NULL) // wait until the message queue is set up to look for stuff to process - vTaskDelay(50); + static led_msg_t in_led_msg; + + while (queue == NULL) vTaskDelay(50); // wait until the message queue is set up before processing for (;;) { - while (pdPASS != xQueueReceive( Max7219_Queue, &incoming_led_msg, 2000)) { /* nada */ } + while (pdPASS != xQueueReceive(queue, &in_led_msg, 2000)) { /* nada */ } - switch (MSG.operation) { - case LED_NOP: break; - case LED_INIT: Max7219_init(); - break; - case LED_LOAD_REGS: Max7219_register_setup(); - break; - case LED_ON: Max7219_LED_On(MSG.col, MSG.row); - break; - case LED_OFF: Max7219_LED_Off(MSG.col, MSG.row); - break; - case LED_TOGGLE: Max7219_LED_Toggle(MSG.col, MSG.row); - break; - case LED_CLEAR_MATRIX: Max7219_Clear(); - break; - case LED_CLEAR_ROW: Max7219_Clear_Row(MSG.row); - break; - case LED_CLEAR_COLUMN: Max7219_Clear_Column(MSG.col); - break; - case LED_SET_ROW: Max7219_Set_Row(MSG.row, (uint8_t) MSG.val); - break; - case LED_SET_2_ROWS: Max7219_Set_2_Rows(MSG.row, (uint16_t) MSG.val); - break; - case LED_SET_4_ROWS: Max7219_Set_4_Rows(MSG.row, MSG.val); - break; - case LED_SET_COLUMN: Max7219_Set_Column(MSG.col, (uint8_t) MSG.val); - break; - case LED_IDLE_TASK: Max7219_idle_tasks(); - break; + switch (in_led_msg.operation) { + case LED_NOP: break; + case LED_INIT: max7219.reinit(); break; + case LED_LOAD_REGS: max7219.register_setup(); break; + case LED_ON: max7219.led_on(in_led_msg.col, in_led_msg.row); break; + case LED_OFF: max7219.led_off(in_led_msg.col, in_led_msg.row); break; + case LED_TOGGLE: max7219.led_toggle(in_led_msg.col, in_led_msg.row); break; + case LED_CLEAR_MATRIX: max7219.clear(); break; + case LED_CLEAR_ROW: max7219.clear_row(in_led_msg.row); break; + case LED_CLEAR_COLUMN: max7219.clear_column(in_led_msg.col); break; + case LED_SET_ROW: max7219.set_row(in_led_msg.row, (uint8_t)in_led_msg.val); break; + case LED_SET_2_ROWS: max7219.set_rows_16bits(in_led_msg.row, (uint16_t)in_led_msg.val); break; + case LED_SET_4_ROWS: max7219.set_rows_32bits(in_led_msg.row, in_led_msg.val); break; + case LED_SET_COLUMN: max7219.set_column(in_led_msg.col, (uint8_t)in_led_msg.val); break; + case LED_IDLE_TASK: max7219.idle_tasks(); break; } } } @@ -485,7 +471,7 @@ void Max7219::register_setup() { #endif #endif // MAX7219_INIT_TEST -void Max7219::init() { +void Max7219::reinit() { SET_OUTPUT(MAX7219_DIN_PIN); SET_OUTPUT(MAX7219_CLK_PIN); OUT_WRITE(MAX7219_LOAD_PIN, HIGH); @@ -516,6 +502,22 @@ void Max7219::init() { #endif } +void Max7219::init() { + reinit(); + + queue = xQueueCreate(3 /* # of queue items */, sizeof(led_msg_t)); + if (!queue) { + max7219.set_row(0, 0xE5); + for (;;) { /* nada */ } + } + + // Create the Max7219 debug task. It is very low priority in an attempt to not affect the + // normal timing of Marlin. But if too many messages are sent too quickly to the task, + // the command queue will fill up and the sender will block until a message has been drained + // to make room for the next message. + xTaskCreate((TaskFunction_t)max7219.command_processor, "Max7219::LEDs", 200 /* Stack size */, NULL, 2 /* priority */, NULL); +} + /** * This code demonstrates some simple debugging using a single 8x8 LED Matrix. If your feature could * benefit from matrix display, add its code here. Very little processing is required, so the 7219 is diff --git a/Marlin/src/feature/Max7219_Debug_LEDs.h b/Marlin/src/feature/Max7219_Debug_LEDs.h index 08ed7ccfe9..1f0b497f0e 100644 --- a/Marlin/src/feature/Max7219_Debug_LEDs.h +++ b/Marlin/src/feature/Max7219_Debug_LEDs.h @@ -36,12 +36,14 @@ * * If you are using the Max7219 matrix for firmware debug purposes in time sensitive * areas of the code, please be aware that the orientation (rotation) of the display can - * affect the speed. The Max7219 can update a single column fairly fast. It is much - * faster to do a Max7219_Set_Column() with a rotation of 90 or 270 degrees than to do - * a Max7219_Set_Row(). The opposite is true for rotations of 0 or 180 degrees. + * affect the speed. The Max7219 can update a single column fairly fast. It is much + * faster to do a max7219.set_column() with a rotation of 90 or 270 degrees than to do + * a max7219.set_row(). The opposite is true for rotations of 0 or 180 degrees. */ #pragma once +#include + #ifndef MAX7219_ROTATE #define MAX7219_ROTATE 0 #endif @@ -83,11 +85,22 @@ class Max7219 { public: + + typedef struct { + uint8_t operation; + uint8_t row, col; + uint32_t val; + } led_msg_t; + + static led_msg_t led_msg; + QueueHandle_t queue; + static uint8_t led_line[MAX7219_LINES]; Max7219() { } static void init(); + static void reinit(); static void register_setup(); static void putbyte(uint8_t data); static void pulse_load(); @@ -135,6 +148,10 @@ public: // Apply custom code to update the matrix static void idle_tasks(); + // RTOS hooks + static void do_command(uint8_t msg, uint8_t row, uint8_t col, uint32_t val); + TaskFunction_t command_processor(void*); + private: static void error(const char * const func, const int32_t v1, const int32_t v2=-1); static void noop(); @@ -156,13 +173,9 @@ private: extern Max7219 max7219; -// RTOS hooks -void Max7219_Do_Cmd(uint8_t msg, uint8_t row, uint8_t col, uint32_t val); -TaskFunction_t Max7219_Cmd_Processor(void*); - #define LED_NOP 0x00 #define LED_LOAD_REGS 0x01 -#define LED_INIT 0x02 +#define LED_REINIT 0x02 #define LED_ON 0x03 #define LED_OFF 0x04 #define LED_TOGGLE 0x05 @@ -175,11 +188,4 @@ TaskFunction_t Max7219_Cmd_Processor(void*); #define LED_SET_COLUMN 0x0c #define LED_IDLE_TASK 0x0d -struct LED_Msg { - uint8_t operation; - uint8_t row; - uint8_t col; - uint32_t val; -}; - #endif // __MAX7219_DEBUG_LEDS_H__ diff --git a/Marlin/src/gcode/gcode.h b/Marlin/src/gcode/gcode.h index 382e20b206..b050ec0348 100644 --- a/Marlin/src/gcode/gcode.h +++ b/Marlin/src/gcode/gcode.h @@ -516,6 +516,7 @@ private: #endif static void M101(); + #if ENABLED(MAX7219_DEBUG) static void M102(); #endif diff --git a/platformio.ini b/platformio.ini index 77756c6640..694efa729a 100644 --- a/platformio.ini +++ b/platformio.ini @@ -29,6 +29,7 @@ build_flags = -fmax-errors=5 -g -ggdb lib_deps = + FreeRTOS https://github.com/MarlinFirmware/U8glib-HAL/archive/dev.zip LiquidCrystal@1.3.4 TMC2130Stepper