Subversion Repositories Projects

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1687 - 1
 
2
/****************************************************************/
3
/*                                                                                                                                                                                                                                                      */
4
/*                                                                       NG-Video 5,8GHz                                                                                                                */
5
/*                                                                                                                                                                                                                                                      */
6
/*                                                      Copyright (C) 2011 - gebad                                                                                      */
7
/*                                                                                                                                                                                                                                                      */
8
/*      This code is distributed under the GNU Public License                           */
9
/*      which can be found at http://www.gnu.org/licenses/gpl.txt               */
10
/*                                                                                                                                                                                                                                                      */
11
/****************************************************************/
12
 
13
#include <stdlib.h>
14
#include <util/delay.h>
15
#include <avr/pgmspace.h>
16
 
17
#include "config.h"
18
#include "dogm.h"
19
#include "tools.h"
20
#include "messages.h"
21
 
22
#define MAX_POWER                               10
23
#define getPower(x)                     (int32_t)pgm_read_dword(&powers[x])
24
const int32_t PROGMEM           powers[MAX_POWER] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
25
 
26
/* Funktion zur Umwandlung einer vorzeichenbehafteten Integer
27
         32-Bit "Festkomma-Zahl"(gedachtes Komma in Integer) in einen String
28
         vereinfacht Variablenübergabe funktion change_value(uint16_t x),
29
         kein printf, double oder float
30
         siehe http://www.mikrocontroller.net/articles/Festkommaarithmetik
31
         len: max 13, Gesamtlänge des Resultats inklusive Vorzeichen und Komma, Rest wird mit ' ' aufgefüllt
32
         fixedPoint: Position des Kommas im Integer-Wert. Bei Wert in mm und Anzeige in m ist das z.B. 3
33
         afterPoint: Ziffern nach dem Komma = wieviele der fixedPoint Ziffern angezeigt werden sollen
34
 
35
         Ist nicht genug Platz für die Zahl vorhanden werden nur '*' Zeichen ausgegeben!         
36
         makefile derzeit somit auch ohne! Minimalistic printf version*/
37
 
38
char *my_itoa(int32_t value, uint8_t len, uint8_t fixedPoint, uint8_t afterPoint)
39
{       int8_t  i;
40
        int8_t  digits, digitsNeeded;
41
        uint8_t neg = 0;
42
        int32_t tmpvalue;
43
        static char str[13];
44
 
45
        // Terminate string
46
        str[len] = '\0';
47
 
48
        // Reduce precision of value if we're not supposed to show all of the mantissa
49
        if (fixedPoint > afterPoint) {
50
                value /= getPower(fixedPoint - afterPoint);
51
                fixedPoint = afterPoint;
52
        }
53
 
54
        // Handle negative values
55
        if (value < 0) {
56
                value = -value;
57
                neg = 1;
58
        }
59
 
60
        // Check how many digits we've got in total and if it fits in our space
61
        for (digits = 1; digits < MAX_POWER && value >= getPower(digits); digits++);
62
        if (neg) digits++;                                      // We also need space for the sign
63
        if (fixedPoint) digits++;               // Plus space for decimal point
64
 
65
        digitsNeeded = digits - len;
66
        if (digitsNeeded > 0) {
67
                // Not enough space, do something
68
                if (digitsNeeded == fixedPoint || (digitsNeeded == fixedPoint + 1 && fixedPoint)) {             // +1 = space for decimal point that we can get rid of
69
                        // If space is just big enough for integer part then simply don't show mantissa BUT ROUND CORRECTLY
70
                        tmpvalue = (value + 5 * getPower(fixedPoint - 1)) / getPower(fixedPoint);
71
                        for (digits = 1; digits < MAX_POWER && tmpvalue >= getPower(digits); digits++);
72
                        // wird durch Rundung Länge Darstellung überschritten?
73
                        if (digits + neg <= len)
74
                                value = tmpvalue;
75
                        else
76
                                value /= 10;
77
                        fixedPoint = 0;
78
                }
79
                else
80
                        if (digitsNeeded < fixedPoint) {
81
                                // We can reduce precision to make it fit (round correctly)
82
                                value = (value + 5 * getPower(digitsNeeded - 1)) / getPower(digitsNeeded);
83
                                for (digits = 1; digits < MAX_POWER && value >= getPower(digits); digits++);
84
                                // wird durch Rundung Länge Darstellung überschritten?
85
                                if (digits + neg <= len) {
86
                                        --fixedPoint;
87
                                        value /= 10;
88
                                }
89
                                fixedPoint -= digitsNeeded;
90
                        }
91
                        else {
92
                                // Error, cannot display value! Let's show stars
93
                                for (i = len - 1; i >= 0; --i) str[i] = '*';
94
                                return str;    
95
                }
96
        }
97
 
98
        for (i = len - 1; i >= neg; --i) {
99
            if (fixedPoint && i == len - fixedPoint - 1) {
100
                        // Insert decimal point at the right location
101
                        str[i] = Msg(MSG_KOMMA)[0];
102
                        fixedPoint = 0;                                 // Now in integer part
103
                } else {
104
                        str[i] = (value % 10) + '0';
105
                        value /= 10;
106
 
107
                        // Break if we're in integer part and there are only zeros from this point on
108
                        if (value == 0 && fixedPoint == 0) {
109
                                --i;
110
                                break;
111
                        }
112
                }
113
        }
114
 
115
        // Insert sign
116
        if (neg) str[i--] = '-';
117
 
118
        // Rest is blank
119
        for (; i >= 0; --i)
120
                str[i] = ' ';
121
 
122
        return str;
123
}
124
 
125
 
126
// Trying to avoid floating point maths here. Converts a floating point string to an integer with a smaller unit
127
// i.e. floatStrToInt("4.5", 2) = 4.5 * 1E2 = 450
128
int32_t floatStrToInt(const char *s, int32_t power1)
129
{       char                            *endPtr;
130
        int32_t                 v = strtol(s, &endPtr, 10);
131
 
132
        if (*endPtr == '.') {
133
                for (s = endPtr + 1; *s && power1; s++) {
134
                        v = v * 10 + (*s - '0');
135
                        --power1;                              
136
                }
137
        }
138
        if (power1) {
139
                // Table to avoid multiple multiplications
140
                v = v * getPower(power1);
141
        }                              
142
        return v;
143
}
144
 
145
 
146
// Delay helper
147
void delay_ms100x(uint8_t delay)
148
{
149
        for ( uint8_t i=0; i<delay; i++)
150
                _delay_ms(100);
151
}
152
 
153
 
154
/************************************************************************************/
155
/*                                                                                                                                                                                                                                                                                                                                      */
156
/*      Zeitanzeige                                                                                                                                                                                                                                                                                     */
157
/*                                                                                                                                                                                                                                                                                                                                      */
158
/************************************************************************************/
159
 
160
uint32_t TimeBase60(char *str, uint32_t time, uint8_t idx)
161
{       uint32_t tmp = time % 60;
162
 
163
        str[idx]                        = (tmp / 10) + '0';
164
        str[idx + 1]    = (tmp % 10) + '0';    
165
        return time / 60;
166
}
167
 
168
void Displ_TimeMS(int32_t time)
169
{       char str[7];
170
 
171
        str[6] = '\0';
172
        if (time < 0) {
173
                time = abs(time);
174
                str[0] = '-';
175
        }
176
        else
177
                str[0] = ' ';
178
        time = TimeBase60(str, time, 4);
179
        str[3] = ':';
180
        TimeBase60(str, time, 1);
181
        lcdPuts(str);
182
}
183
 
184
void Displ_TimeHMS(uint32_t time)
185
{       char str[9];
186
 
187
        time /= T2SECDIV; // Zähler aller 500µs
188
        str[8] = '\0';
189
        time = TimeBase60(str, time, 6);
190
        str[5] = ':';
191
        time = TimeBase60(str, time, 3);
192
        str[2] = ':';
193
        TimeBase60(str, time, 0);
194
        lcdPuts(str);
195
}