Fit task code for updated Max7219

This commit is contained in:
Scott Lahteine 2018-09-10 04:16:25 -05:00
parent bef6b94b7e
commit 0bdea3f854
5 changed files with 84 additions and 81 deletions

View file

@ -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
}

View file

@ -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

View file

@ -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 <task.h>
#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__

View file

@ -516,6 +516,7 @@ private:
#endif
static void M101();
#if ENABLED(MAX7219_DEBUG)
static void M102();
#endif

View file

@ -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