Subversion Repositories Projects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1465 - 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
        static char str[13];
43
 
44
        // Terminate string
45
        str[len] = '\0';
46
 
47
        // Reduce precision of value if we're not supposed to show all of the mantissa
48
        if (fixedPoint > afterPoint) {
49
                value /= getPower(fixedPoint - afterPoint);
50
                fixedPoint = afterPoint;
51
        }
52
 
53
        // Handle negative values
54
        if (value < 0) {
55
                value = -value;
56
                neg = 1;
57
        }
58
 
59
        // Check how many digits we've got in total and if it fits in our space
60
        for (digits = 1; digits < MAX_POWER && value >= getPower(digits); digits++);
61
        if (neg) digits++;                                      // We also need space for the sign
62
        if (fixedPoint) digits++;               // Plus space for decimal point
63
 
64
        digitsNeeded = digits - len;
65
        if (digitsNeeded > 0) {
66
                // Not enough space, do something
67
                if (digitsNeeded == fixedPoint || digitsNeeded == fixedPoint + 1) {             // +1 = space for decimal point that we can get rid of
68
                        // If space is just big enough for integer part then simply don't show mantissa BUT ROUND CORRECTLY
69
                        value = (value + 5 * getPower(fixedPoint - 1)) / getPower(fixedPoint);
70
                        fixedPoint = 0;
71
                } else if (digitsNeeded < fixedPoint) {
72
                        // We can reduce precision to make it fit (round correctly)
73
                        value = (value + 5 * getPower(digitsNeeded - 1)) / getPower(digitsNeeded);
74
                        fixedPoint -= digitsNeeded;
75
                } else {
76
                        // Error, cannot display value! Let's show stars
77
                        for (i = len - 1; i >= 0; --i) str[i] = '*';
78
                        return str;    
79
                }
80
        }
81
 
82
        for (i = len - 1; i >= neg; --i) {
83
            if (fixedPoint && i == len - fixedPoint - 1) {
84
                        // Insert decimal point at the right location
85
                        str[i] = Msg(MSG_KOMMA)[0];
86
                        fixedPoint = 0;                                 // Now in integer part
87
                } else {
88
                        str[i] = (value % 10) + '0';
89
                        value /= 10;
90
 
91
                        // Break if we're in integer part and there are only zeros from this point on
92
                        if (value == 0 && fixedPoint == 0) {
93
                                --i;
94
                                break;
95
                        }
96
                }
97
        }
98
 
99
        // Insert sign
100
        if (neg) str[i--] = '-';
101
 
102
        // Rest is blank
103
        for (; i >= 0; --i)
104
                str[i] = ' ';
105
 
106
        return str;
107
}
108
 
109
 
110
// Trying to avoid floating point maths here. Converts a floating point string to an integer with a smaller unit
111
// i.e. floatStrToInt("4.5", 2) = 4.5 * 1E2 = 450
112
int32_t floatStrToInt(const char *s, int32_t power1)
113
{       char                            *endPtr;
114
        int32_t                 v = strtol(s, &endPtr, 10);
115
 
116
        if (*endPtr == '.') {
117
                for (s = endPtr + 1; *s && power1; s++) {
118
                        v = v * 10 + (*s - '0');
119
                        --power1;                              
120
                }
121
        }
122
        if (power1) {
123
                // Table to avoid multiple multiplications
124
                v = v * getPower(power1);
125
        }                              
126
        return v;
127
}
128
 
129
 
130
// Delay helper
131
void delay_ms100x(uint8_t delay)
132
{
133
        for ( uint8_t i=0; i<delay; i++)
134
                _delay_ms(100);
135
}
136
 
137
 
138
/************************************************************************************/
139
/*                                                                                                                                                                                                                                                                                                                                      */
140
/*      Zeitanzeige                                                                                                                                                                                                                                                                                     */
141
/*                                                                                                                                                                                                                                                                                                                                      */
142
/************************************************************************************/
143
 
144
uint32_t TimeBase60(char *str, uint32_t time, uint8_t idx)
145
{       uint32_t tmp = time % 60;
146
 
147
        str[idx]                        = (tmp / 10) + '0';
148
        str[idx + 1]    = (tmp % 10) + '0';    
149
        return time / 60;
150
}
151
 
152
void Displ_TimeMS(int32_t time)
153
{       char str[7];
154
 
155
        str[6] = '\0';
156
        if (time < 0) {
157
                time = abs(time);
158
                str[0] = '-';
159
        }
160
        else
161
                str[0] = ' ';
162
        time = TimeBase60(str, time, 4);
163
        str[3] = ':';
164
        TimeBase60(str, time, 1);
165
        lcdPuts(str);
166
}
167
 
168
void Displ_TimeHMS(uint32_t time)
169
{       char str[9];
170
 
171
        time /= T2SECDIV; // Zähler aller 500µs
172
        str[8] = '\0';
173
        time = TimeBase60(str, time, 6);
174
        str[5] = ':';
175
        time = TimeBase60(str, time, 3);
176
        str[2] = ':';
177
        TimeBase60(str, time, 0);
178
        lcdPuts(str);
179
}