Committer:
Sergunb
Date:
Mon Sep 04 12:04:13 2017 +0000
Revision:
0:8f0d870509fe
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Sergunb 0:8f0d870509fe 1 /*
Sergunb 0:8f0d870509fe 2 print.c - Functions for formatting output strings
Sergunb 0:8f0d870509fe 3 Part of Grbl
Sergunb 0:8f0d870509fe 4
Sergunb 0:8f0d870509fe 5 Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
Sergunb 0:8f0d870509fe 6 Copyright (c) 2009-2011 Simen Svale Skogsrud
Sergunb 0:8f0d870509fe 7
Sergunb 0:8f0d870509fe 8 Grbl is free software: you can redistribute it and/or modify
Sergunb 0:8f0d870509fe 9 it under the terms of the GNU General Public License as published by
Sergunb 0:8f0d870509fe 10 the Free Software Foundation, either version 3 of the License, or
Sergunb 0:8f0d870509fe 11 (at your option) any later version.
Sergunb 0:8f0d870509fe 12
Sergunb 0:8f0d870509fe 13 Grbl is distributed in the hope that it will be useful,
Sergunb 0:8f0d870509fe 14 but WITHOUT ANY WARRANTY; without even the implied warranty of
Sergunb 0:8f0d870509fe 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Sergunb 0:8f0d870509fe 16 GNU General Public License for more details.
Sergunb 0:8f0d870509fe 17
Sergunb 0:8f0d870509fe 18 You should have received a copy of the GNU General Public License
Sergunb 0:8f0d870509fe 19 along with Grbl. If not, see <http://www.gnu.org/licenses/>.
Sergunb 0:8f0d870509fe 20 */
Sergunb 0:8f0d870509fe 21
Sergunb 0:8f0d870509fe 22 #include "grbl.h"
Sergunb 0:8f0d870509fe 23
Sergunb 0:8f0d870509fe 24
Sergunb 0:8f0d870509fe 25 void printString(const char *s)
Sergunb 0:8f0d870509fe 26 {
Sergunb 0:8f0d870509fe 27 while (*s)
Sergunb 0:8f0d870509fe 28 serial_write(*s++);
Sergunb 0:8f0d870509fe 29 }
Sergunb 0:8f0d870509fe 30
Sergunb 0:8f0d870509fe 31 #ifdef AVRTARGET
Sergunb 0:8f0d870509fe 32 // Print a string stored in PGM-memory
Sergunb 0:8f0d870509fe 33 void printPgmString(const char *s)
Sergunb 0:8f0d870509fe 34 {
Sergunb 0:8f0d870509fe 35 char c;
Sergunb 0:8f0d870509fe 36 while ((c = pgm_read_byte_near(s++)))
Sergunb 0:8f0d870509fe 37 serial_write(c);
Sergunb 0:8f0d870509fe 38 }
Sergunb 0:8f0d870509fe 39 #endif
Sergunb 0:8f0d870509fe 40
Sergunb 0:8f0d870509fe 41 // void printIntegerInBase(unsigned long n, unsigned long base)
Sergunb 0:8f0d870509fe 42 // {
Sergunb 0:8f0d870509fe 43 // unsigned char buf[8 * sizeof(long)]; // Assumes 8-bit chars.
Sergunb 0:8f0d870509fe 44 // unsigned long i = 0;
Sergunb 0:8f0d870509fe 45 //
Sergunb 0:8f0d870509fe 46 // if (n == 0) {
Sergunb 0:8f0d870509fe 47 // serial_write('0');
Sergunb 0:8f0d870509fe 48 // return;
Sergunb 0:8f0d870509fe 49 // }
Sergunb 0:8f0d870509fe 50 //
Sergunb 0:8f0d870509fe 51 // while (n > 0) {
Sergunb 0:8f0d870509fe 52 // buf[i++] = n % base;
Sergunb 0:8f0d870509fe 53 // n /= base;
Sergunb 0:8f0d870509fe 54 // }
Sergunb 0:8f0d870509fe 55 //
Sergunb 0:8f0d870509fe 56 // for (; i > 0; i--)
Sergunb 0:8f0d870509fe 57 // serial_write(buf[i - 1] < 10 ?
Sergunb 0:8f0d870509fe 58 // '0' + buf[i - 1] :
Sergunb 0:8f0d870509fe 59 // 'A' + buf[i - 1] - 10);
Sergunb 0:8f0d870509fe 60 // }
Sergunb 0:8f0d870509fe 61
Sergunb 0:8f0d870509fe 62
Sergunb 0:8f0d870509fe 63 // Prints an uint8 variable in base 10.
Sergunb 0:8f0d870509fe 64 void print_uint8_base10(uint8_t n)
Sergunb 0:8f0d870509fe 65 {
Sergunb 0:8f0d870509fe 66 uint8_t digit_a = 0;
Sergunb 0:8f0d870509fe 67 uint8_t digit_b = 0;
Sergunb 0:8f0d870509fe 68 if (n >= 100) { // 100-255
Sergunb 0:8f0d870509fe 69 digit_a = '0' + n % 10;
Sergunb 0:8f0d870509fe 70 n /= 10;
Sergunb 0:8f0d870509fe 71 }
Sergunb 0:8f0d870509fe 72 if (n >= 10) { // 10-99
Sergunb 0:8f0d870509fe 73 digit_b = '0' + n % 10;
Sergunb 0:8f0d870509fe 74 n /= 10;
Sergunb 0:8f0d870509fe 75 }
Sergunb 0:8f0d870509fe 76 serial_write('0' + n);
Sergunb 0:8f0d870509fe 77 if (digit_b) { serial_write(digit_b); }
Sergunb 0:8f0d870509fe 78 if (digit_a) { serial_write(digit_a); }
Sergunb 0:8f0d870509fe 79 }
Sergunb 0:8f0d870509fe 80
Sergunb 0:8f0d870509fe 81
Sergunb 0:8f0d870509fe 82 // Prints an uint8 variable in base 2 with desired number of desired digits.
Sergunb 0:8f0d870509fe 83 void print_uint8_base2_ndigit(uint8_t n, uint8_t digits) {
Sergunb 0:8f0d870509fe 84 #if defined(AVRTARGET) || defined(STM32F103C8)
Sergunb 0:8f0d870509fe 85 unsigned char buf[digits];
Sergunb 0:8f0d870509fe 86 #endif
Sergunb 0:8f0d870509fe 87 #ifdef WIN32
Sergunb 0:8f0d870509fe 88 unsigned char buf[20];
Sergunb 0:8f0d870509fe 89 #endif
Sergunb 0:8f0d870509fe 90 uint8_t i = 0;
Sergunb 0:8f0d870509fe 91
Sergunb 0:8f0d870509fe 92 for (; i < digits; i++) {
Sergunb 0:8f0d870509fe 93 buf[i] = n % 2 ;
Sergunb 0:8f0d870509fe 94 n /= 2;
Sergunb 0:8f0d870509fe 95 }
Sergunb 0:8f0d870509fe 96
Sergunb 0:8f0d870509fe 97 for (; i > 0; i--)
Sergunb 0:8f0d870509fe 98 serial_write('0' + buf[i - 1]);
Sergunb 0:8f0d870509fe 99 }
Sergunb 0:8f0d870509fe 100
Sergunb 0:8f0d870509fe 101
Sergunb 0:8f0d870509fe 102 void print_uint32_base10(uint32_t n)
Sergunb 0:8f0d870509fe 103 {
Sergunb 0:8f0d870509fe 104 if (n == 0) {
Sergunb 0:8f0d870509fe 105 serial_write('0');
Sergunb 0:8f0d870509fe 106 return;
Sergunb 0:8f0d870509fe 107 }
Sergunb 0:8f0d870509fe 108
Sergunb 0:8f0d870509fe 109 unsigned char buf[10];
Sergunb 0:8f0d870509fe 110 uint8_t i = 0;
Sergunb 0:8f0d870509fe 111
Sergunb 0:8f0d870509fe 112 while (n > 0) {
Sergunb 0:8f0d870509fe 113 buf[i++] = n % 10;
Sergunb 0:8f0d870509fe 114 n /= 10;
Sergunb 0:8f0d870509fe 115 }
Sergunb 0:8f0d870509fe 116
Sergunb 0:8f0d870509fe 117 for (; i > 0; i--)
Sergunb 0:8f0d870509fe 118 serial_write('0' + buf[i-1]);
Sergunb 0:8f0d870509fe 119 }
Sergunb 0:8f0d870509fe 120
Sergunb 0:8f0d870509fe 121
Sergunb 0:8f0d870509fe 122 void printInteger(long n)
Sergunb 0:8f0d870509fe 123 {
Sergunb 0:8f0d870509fe 124 if (n < 0) {
Sergunb 0:8f0d870509fe 125 serial_write('-');
Sergunb 0:8f0d870509fe 126 print_uint32_base10(-n);
Sergunb 0:8f0d870509fe 127 } else {
Sergunb 0:8f0d870509fe 128 print_uint32_base10(n);
Sergunb 0:8f0d870509fe 129 }
Sergunb 0:8f0d870509fe 130 }
Sergunb 0:8f0d870509fe 131
Sergunb 0:8f0d870509fe 132
Sergunb 0:8f0d870509fe 133 // Convert float to string by immediately converting to a long integer, which contains
Sergunb 0:8f0d870509fe 134 // more digits than a float. Number of decimal places, which are tracked by a counter,
Sergunb 0:8f0d870509fe 135 // may be set by the user. The integer is then efficiently converted to a string.
Sergunb 0:8f0d870509fe 136 // NOTE: AVR '%' and '/' integer operations are very efficient. Bitshifting speed-up
Sergunb 0:8f0d870509fe 137 // techniques are actually just slightly slower. Found this out the hard way.
Sergunb 0:8f0d870509fe 138 void printFloat(float n, uint8_t decimal_places)
Sergunb 0:8f0d870509fe 139 {
Sergunb 0:8f0d870509fe 140 if (n < 0) {
Sergunb 0:8f0d870509fe 141 serial_write('-');
Sergunb 0:8f0d870509fe 142 n = -n;
Sergunb 0:8f0d870509fe 143 }
Sergunb 0:8f0d870509fe 144
Sergunb 0:8f0d870509fe 145 uint8_t decimals = decimal_places;
Sergunb 0:8f0d870509fe 146 while (decimals >= 2) { // Quickly convert values expected to be E0 to E-4.
Sergunb 0:8f0d870509fe 147 n *= 100;
Sergunb 0:8f0d870509fe 148 decimals -= 2;
Sergunb 0:8f0d870509fe 149 }
Sergunb 0:8f0d870509fe 150 if (decimals) { n *= 10; }
Sergunb 0:8f0d870509fe 151 n += 0.5; // Add rounding factor. Ensures carryover through entire value.
Sergunb 0:8f0d870509fe 152
Sergunb 0:8f0d870509fe 153 // Generate digits backwards and store in string.
Sergunb 0:8f0d870509fe 154 unsigned char buf[13];
Sergunb 0:8f0d870509fe 155 uint8_t i = 0;
Sergunb 0:8f0d870509fe 156 uint32_t a = (long)n;
Sergunb 0:8f0d870509fe 157 while(a > 0) {
Sergunb 0:8f0d870509fe 158 buf[i++] = (a % 10) + '0'; // Get digit
Sergunb 0:8f0d870509fe 159 a /= 10;
Sergunb 0:8f0d870509fe 160 }
Sergunb 0:8f0d870509fe 161 while (i < decimal_places) {
Sergunb 0:8f0d870509fe 162 buf[i++] = '0'; // Fill in zeros to decimal point for (n < 1)
Sergunb 0:8f0d870509fe 163 }
Sergunb 0:8f0d870509fe 164 if (i == decimal_places) { // Fill in leading zero, if needed.
Sergunb 0:8f0d870509fe 165 buf[i++] = '0';
Sergunb 0:8f0d870509fe 166 }
Sergunb 0:8f0d870509fe 167
Sergunb 0:8f0d870509fe 168 // Print the generated string.
Sergunb 0:8f0d870509fe 169 for (; i > 0; i--) {
Sergunb 0:8f0d870509fe 170 if (i == decimal_places) { serial_write('.'); } // Insert decimal point in right place.
Sergunb 0:8f0d870509fe 171 serial_write(buf[i-1]);
Sergunb 0:8f0d870509fe 172 }
Sergunb 0:8f0d870509fe 173 }
Sergunb 0:8f0d870509fe 174
Sergunb 0:8f0d870509fe 175
Sergunb 0:8f0d870509fe 176 // Floating value printing handlers for special variables types used in Grbl and are defined
Sergunb 0:8f0d870509fe 177 // in the config.h.
Sergunb 0:8f0d870509fe 178 // - CoordValue: Handles all position or coordinate values in inches or mm reporting.
Sergunb 0:8f0d870509fe 179 // - RateValue: Handles feed rate and current velocity in inches or mm reporting.
Sergunb 0:8f0d870509fe 180 void printFloat_CoordValue(float n) {
Sergunb 0:8f0d870509fe 181 if (bit_istrue(settings.flags,BITFLAG_REPORT_INCHES)) {
Sergunb 0:8f0d870509fe 182 printFloat(n*INCH_PER_MM,N_DECIMAL_COORDVALUE_INCH);
Sergunb 0:8f0d870509fe 183 } else {
Sergunb 0:8f0d870509fe 184 printFloat(n,N_DECIMAL_COORDVALUE_MM);
Sergunb 0:8f0d870509fe 185 }
Sergunb 0:8f0d870509fe 186 }
Sergunb 0:8f0d870509fe 187
Sergunb 0:8f0d870509fe 188 void printFloat_RateValue(float n) {
Sergunb 0:8f0d870509fe 189 if (bit_istrue(settings.flags,BITFLAG_REPORT_INCHES)) {
Sergunb 0:8f0d870509fe 190 printFloat(n*INCH_PER_MM,N_DECIMAL_RATEVALUE_INCH);
Sergunb 0:8f0d870509fe 191 } else {
Sergunb 0:8f0d870509fe 192 printFloat(n,N_DECIMAL_RATEVALUE_MM);
Sergunb 0:8f0d870509fe 193 }
Sergunb 0:8f0d870509fe 194 }
Sergunb 0:8f0d870509fe 195
Sergunb 0:8f0d870509fe 196 // Debug tool to print free memory in bytes at the called point.
Sergunb 0:8f0d870509fe 197 // NOTE: Keep commented unless using. Part of this function always gets compiled in.
Sergunb 0:8f0d870509fe 198 // void printFreeMemory()
Sergunb 0:8f0d870509fe 199 // {
Sergunb 0:8f0d870509fe 200 // extern int __heap_start, *__brkval;
Sergunb 0:8f0d870509fe 201 // uint16_t free; // Up to 64k values.
Sergunb 0:8f0d870509fe 202 // free = (int) &free - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
Sergunb 0:8f0d870509fe 203 // printInteger((int32_t)free);
Sergunb 0:8f0d870509fe 204 // printString(" ");
Sergunb 0:8f0d870509fe 205 // }