Prusa MINI Firmware overview
pinsDebug.h
Go to the documentation of this file.
1 /**
2  * Marlin 3D Printer Firmware
3  * Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  *
18  */
19 
20 #include "../inc/MarlinConfig.h"
21 
22 #define MAX_NAME_LENGTH 39 // one place to specify the format of all the sources of names
23  // "-" left justify, "39" minimum width of name, pad with blanks
24 
25 /**
26  * This routine minimizes RAM usage by creating a FLASH resident array to
27  * store the pin names, pin numbers and analog/digital flag.
28  *
29  * Creating the array in FLASH is a two pass process. The first pass puts the
30  * name strings into FLASH. The second pass actually creates the array.
31  *
32  * Both passes use the same pin list. The list contains two macro names. The
33  * actual macro definitions are changed depending on which pass is being done.
34  *
35  */
36 
37 // first pass - put the name strings into FLASH
38 
39 #define _ADD_PIN_2(PIN_NAME, ENTRY_NAME) static const char ENTRY_NAME[] PROGMEM = { PIN_NAME };
40 #define _ADD_PIN(PIN_NAME, COUNTER) _ADD_PIN_2(PIN_NAME, entry_NAME_##COUNTER)
41 #define REPORT_NAME_DIGITAL(COUNTER, NAME) _ADD_PIN(#NAME, COUNTER)
42 #define REPORT_NAME_ANALOG(COUNTER, NAME) _ADD_PIN(#NAME, COUNTER)
43 
44 #include "pinsDebug_list.h"
45 #line 46
46 
47 // manually add pins that have names that are macros which don't play well with these macros
48 #if SERIAL_PORT == 0 && (AVR_ATmega2560_FAMILY || AVR_ATmega1284_FAMILY || defined(ARDUINO_ARCH_SAM))
49  static const char RXD_NAME[] PROGMEM = { "RXD" };
50  static const char TXD_NAME[] PROGMEM = { "TXD" };
51 #endif
52 
53 /////////////////////////////////////////////////////////////////////////////
54 
55 // second pass - create the array
56 
57 #undef _ADD_PIN_2
58 #undef _ADD_PIN
59 #undef REPORT_NAME_DIGITAL
60 #undef REPORT_NAME_ANALOG
61 
62 #define _ADD_PIN_2(ENTRY_NAME, NAME, IS_DIGITAL) { ENTRY_NAME, NAME, IS_DIGITAL },
63 #define _ADD_PIN(NAME, COUNTER, IS_DIGITAL) _ADD_PIN_2(entry_NAME_##COUNTER, NAME, IS_DIGITAL)
64 #define REPORT_NAME_DIGITAL(COUNTER, NAME) _ADD_PIN(NAME, COUNTER, true)
65 #define REPORT_NAME_ANALOG(COUNTER, NAME) _ADD_PIN(analogInputToDigitalPin(NAME), COUNTER, false)
66 
67 
68 typedef struct {
69  PGM_P const name;
71  bool is_digital;
72 } PinInfo;
73 
74 const PinInfo pin_array[] PROGMEM = {
75 
76  /**
77  * [pin name] [pin number] [is digital or analog] 1 = digital, 0 = analog
78  * Each entry takes up 6 bytes in FLASH:
79  * 2 byte pointer to location of the name string
80  * 2 bytes containing the pin number
81  * analog pin numbers were convereted to digital when the array was created
82  * 2 bytes containing the digital/analog bool flag
83  */
84 
85  // manually add pins ...
86  #if SERIAL_PORT == 0
87  #if (AVR_ATmega2560_FAMILY || defined(ARDUINO_ARCH_SAM))
88  { RXD_NAME, 0, true },
89  { TXD_NAME, 1, true },
90  #elif AVR_ATmega1284_FAMILY
91  { RXD_NAME, 8, true },
92  { TXD_NAME, 9, true },
93  #endif
94  #endif
95 
96  #include "pinsDebug_list.h"
97  #line 98
98 
99 };
100 
101 #include HAL_PATH(../HAL, pinsDebug.h) // get the correct support file for this CPU
102 
103 #ifndef M43_NEVER_TOUCH
104  #define M43_NEVER_TOUCH(Q) false
105 #endif
106 
107 static void print_input_or_output(const bool isout) {
108  serialprintPGM(isout ? PSTR("Output = ") : PSTR("Input = "));
109 }
110 
111 // pretty report with PWM info
112 inline void report_pin_state_extended(pin_t pin, bool ignore, bool extended = false, const char *start_string = "") {
113  char buffer[MAX_NAME_LENGTH + 1]; // for the sprintf statements
114  bool found = false, multi_name_pin = false;
115 
116  for (uint8_t x = 0; x < COUNT(pin_array); x++) { // scan entire array and report all instances of this pin
117  if (GET_ARRAY_PIN(x) == pin) {
118  if (found) multi_name_pin = true;
119  found = true;
120  if (!multi_name_pin) { // report digital and analog pin number only on the first time through
121  sprintf_P(buffer, PSTR("%sPIN: "), start_string); // digital pin number
122  SERIAL_ECHO(buffer);
123  PRINT_PIN(pin);
124  PRINT_PORT(pin);
125  if (int8_t(DIGITAL_PIN_TO_ANALOG_PIN(pin)) >= 0) {
126  sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); // analog pin number
127  SERIAL_ECHO(buffer);
128  }
129  else SERIAL_ECHO_SP(8); // add padding if not an analog pin
130  }
131  else {
132  SERIAL_CHAR('.');
133  SERIAL_ECHO_SP(MULTI_NAME_PAD + strlen(start_string)); // add padding if not the first instance found
134  }
135  PRINT_ARRAY_NAME(x);
136  if (extended) {
137  if (pin_is_protected(pin) && !ignore)
138  SERIAL_ECHOPGM("protected ");
139  else {
140  #if AVR_AT90USB1286_FAMILY //Teensy IDEs don't know about these pins so must use FASTIO
141  if (pin == 46 || pin == 47) {
142  if (pin == 46) {
144  SERIAL_CHAR('0' + READ(46));
145  }
146  else if (pin == 47) {
148  SERIAL_CHAR('0' + READ(47));
149  }
150  }
151  else
152  #endif
153  {
154  if (!GET_ARRAY_IS_DIGITAL(x)) {
155  sprintf_P(buffer, PSTR("Analog in = %5ld"), (long)analogRead(DIGITAL_PIN_TO_ANALOG_PIN(pin)));
156  SERIAL_ECHO(buffer);
157  }
158  else {
159  if (!GET_PINMODE(pin)) {
160  //pinMode(pin, INPUT_PULLUP); // make sure input isn't floating - stopped doing this
161  // because this could interfere with inductive/capacitive
162  // sensors (high impedance voltage divider) and with Pt100 amplifier
163  print_input_or_output(false);
165  }
166  else if (pwm_status(pin)) {
167  // do nothing
168  }
169  else {
170  print_input_or_output(true);
172  }
173  }
174  if (!multi_name_pin && extended) pwm_details(pin); // report PWM capabilities only on the first pass & only if doing an extended report
175  }
176  }
177  }
178  SERIAL_EOL();
179  } // end of IF
180  } // end of for loop
181 
182  if (!found) {
183  sprintf_P(buffer, PSTR("%sPIN: "), start_string);
184  SERIAL_ECHO(buffer);
185  PRINT_PIN(pin);
186  PRINT_PORT(pin);
187  if (int8_t(DIGITAL_PIN_TO_ANALOG_PIN(pin)) >= 0) {
188  sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); // analog pin number
189  SERIAL_ECHO(buffer);
190  }
191  else
192  SERIAL_ECHO_SP(8); // add padding if not an analog pin
193  SERIAL_ECHOPGM("<unused/unknown>");
194  if (extended) {
195  #if AVR_AT90USB1286_FAMILY //Teensy IDEs don't know about these pins so must use FASTIO
196  if (pin == 46 || pin == 47) {
197  SERIAL_ECHO_SP(12);
198  if (pin == 46) {
200  SERIAL_CHAR('0' + READ(46));
201  }
202  else {
204  SERIAL_CHAR('0' + READ(47));
205  }
206  }
207  else
208  #endif
209  {
210  if (pwm_status(pin)) {
211  // do nothing
212  }
213  else if (GET_PINMODE(pin)) {
215  print_input_or_output(true);
217  }
218  else {
219  if (IS_ANALOG(pin)) {
220  sprintf_P(buffer, PSTR(" Analog in = %5ld"), (long)analogRead(DIGITAL_PIN_TO_ANALOG_PIN(pin)));
221  SERIAL_ECHO(buffer);
222  SERIAL_ECHOPGM(" ");
223  }
224  else
225  SERIAL_ECHO_SP(MAX_NAME_LENGTH - 16); // add padding if not an analog pin
226 
227  print_input_or_output(false);
229  }
230  //if (!pwm_status(pin)) SERIAL_CHAR(' '); // add padding if it's not a PWM pin
231  if (extended) {
233  pwm_details(pin); // report PWM capabilities only if doing an extended report
234  }
235  }
236  }
237  SERIAL_EOL();
238  }
239 }
SERIAL_CHAR
#define SERIAL_CHAR(x)
Definition: serial.h:69
PROGMEM
const volatile uint8_t *const PWM_other[][3] PROGMEM
Definition: pinsDebug.h:154
SERIAL_ECHO
#define SERIAL_ECHO(x)
Definition: serial.h:70
pin_is_protected
bool pin_is_protected(const pin_t pin)
Definition: Marlin.cpp:258
IS_ANALOG
#define IS_ANALOG(P)
Definition: pinsDebug.h:59
digitalRead_mod
int digitalRead_mod(const int8_t pin)
Definition: pinsDebug.h:354
print_input_or_output
static void print_input_or_output(const bool isout)
Definition: pinsDebug.h:107
PGM_P
#define PGM_P
Definition: pgmspace.h:30
pwm_details
void pwm_details(int32_t pin)
Definition: pinsDebug.h:47
IS_OUTPUT
#define IS_OUTPUT(IO)
Definition: fastio.h:106
DIGITAL_PIN_TO_ANALOG_PIN
int8_t DIGITAL_PIN_TO_ANALOG_PIN(const pin_t p)
analogRead
uint32_t analogRead(uint32_t ulPin)
Definition: wiring_analog.c:8
sprintf_P
#define sprintf_P(s,...)
Definition: pgmspace.h:72
SERIAL_ECHO_SP
#define SERIAL_ECHO_SP(C)
Definition: serial.h:186
MULTI_NAME_PAD
#define MULTI_NAME_PAD
Definition: pinsDebug.h:62
pin_t
int8_t pin_t
Definition: HAL.h:65
PinInfo
Definition: pinsDebug.h:68
PSTR
#define PSTR(str)
Definition: pgmspace.h:31
COUNT
#define COUNT(a)
Definition: macros.h:200
PRINT_ARRAY_NAME
void PRINT_ARRAY_NAME(uint8_t x)
Definition: pinsDebug.h:64
GET_PINMODE
bool GET_PINMODE(int8_t pin)
Definition: pinsDebug.h:49
report_pin_state_extended
void report_pin_state_extended(pin_t pin, bool ignore, bool extended=false, const char *start_string="")
Definition: pinsDebug.h:112
SERIAL_ECHOPGM
#define SERIAL_ECHOPGM(S)
Definition: serial.h:173
PRINT_PORT
#define PRINT_PORT(p)
Definition: pinsDebug.h:392
PRINT_PIN
#define PRINT_PIN(p)
Definition: pinsDebug.h:396
pinsDebug_list.h
uint8_t
const uint8_t[]
Definition: 404_html.c:3
MAX_NAME_LENGTH
#define MAX_NAME_LENGTH
Definition: pinsDebug.h:22
PinInfo::is_digital
bool is_digital
Definition: pinsDebug.h:71
SERIAL_EOL
#define SERIAL_EOL()
Definition: serial.h:181
PinInfo::pin
pin_t pin
Definition: pinsDebug.h:70
serialprintPGM
void serialprintPGM(PGM_P str)
Definition: serial.cpp:35
READ
#define READ(IO)
Definition: fastio.h:95
GET_ARRAY_PIN
#define GET_ARRAY_PIN(p)
Definition: pinsDebug.h:61
pwm_status
#define pwm_status(pin)
Definition: pinsDebug.h:30
PinInfo::name
const PGM_P name
Definition: pinsDebug.h:69
GET_ARRAY_IS_DIGITAL
bool GET_ARRAY_IS_DIGITAL(pin_t pin)
Definition: pinsDebug.h:57