Blame |
Last modification |
View Log
| RSS feed
/****************************************************************/
/* */
/* NG-Video 5,8GHz */
/* */
/* Copyright (C) 2011 - gebad */
/* */
/* This code is distributed under the GNU Public License */
/* which can be found at http://www.gnu.org/licenses/gpl.txt */
/* */
/****************************************************************/
#include <stdlib.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#include "config.h"
#include "dogm.h"
#include "tools.h"
#include "messages.h"
#define MAX_POWER 10
#define getPower(x) (int32_t)pgm_read_dword(&powers[x])
const int32_t PROGMEM powers
[MAX_POWER
] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
/* Funktion zur Umwandlung einer vorzeichenbehafteten Integer
32-Bit "Festkomma-Zahl"(gedachtes Komma in Integer) in einen String
vereinfacht Variablenübergabe funktion change_value(uint16_t x),
kein printf, double oder float
siehe http://www.mikrocontroller.net/articles/Festkommaarithmetik
len: max 13, Gesamtlänge des Resultats inklusive Vorzeichen und Komma, Rest wird mit ' ' aufgefüllt
fixedPoint: Position des Kommas im Integer-Wert. Bei Wert in mm und Anzeige in m ist das z.B. 3
afterPoint: Ziffern nach dem Komma = wieviele der fixedPoint Ziffern angezeigt werden sollen
Ist nicht genug Platz für die Zahl vorhanden werden nur '*' Zeichen ausgegeben!
makefile derzeit somit auch ohne! Minimalistic printf version*/
char *my_itoa
(int32_t value
, uint8_t len
, uint8_t fixedPoint
, uint8_t afterPoint
)
{ int8_t i
;
int8_t digits
, digitsNeeded
;
uint8_t neg
= 0;
int32_t tmpvalue
;
static char str
[13];
// Terminate string
str
[len
] = '\0';
// Reduce precision of value if we're not supposed to show all of the mantissa
if (fixedPoint
> afterPoint
) {
value
/= getPower
(fixedPoint
- afterPoint
);
fixedPoint
= afterPoint
;
}
// Handle negative values
if (value
< 0) {
value
= -value
;
neg
= 1;
}
// Check how many digits we've got in total and if it fits in our space
for (digits
= 1; digits
< MAX_POWER
&& value
>= getPower
(digits
); digits
++);
if (neg
) digits
++; // We also need space for the sign
if (fixedPoint
) digits
++; // Plus space for decimal point
digitsNeeded
= digits
- len
;
if (digitsNeeded
> 0) {
// Not enough space, do something
if (digitsNeeded
== fixedPoint
|| (digitsNeeded
== fixedPoint
+ 1 && fixedPoint
)) { // +1 = space for decimal point that we can get rid of
// If space is just big enough for integer part then simply don't show mantissa BUT ROUND CORRECTLY
tmpvalue
= (value
+ 5 * getPower
(fixedPoint
- 1)) / getPower
(fixedPoint
);
for (digits
= 1; digits
< MAX_POWER
&& tmpvalue
>= getPower
(digits
); digits
++);
// wird durch Rundung Länge Darstellung überschritten?
if (digits
+ neg
<= len
)
value
= tmpvalue
;
else
value
/= 10;
fixedPoint
= 0;
}
else
if (digitsNeeded
< fixedPoint
) {
// We can reduce precision to make it fit (round correctly)
value
= (value
+ 5 * getPower
(digitsNeeded
- 1)) / getPower
(digitsNeeded
);
for (digits
= 1; digits
< MAX_POWER
&& value
>= getPower
(digits
); digits
++);
// wird durch Rundung Länge Darstellung überschritten?
if (digits
+ neg
<= len
) {
--fixedPoint
;
value
/= 10;
}
fixedPoint
-= digitsNeeded
;
}
else {
// Error, cannot display value! Let's show stars
for (i
= len
- 1; i
>= 0; --i
) str
[i
] = '*';
return str
;
}
}
for (i
= len
- 1; i
>= neg
; --i
) {
if (fixedPoint
&& i
== len
- fixedPoint
- 1) {
// Insert decimal point at the right location
str
[i
] = Msg
(MSG_KOMMA
)[0];
fixedPoint
= 0; // Now in integer part
} else {
str
[i
] = (value
% 10) + '0';
value
/= 10;
// Break if we're in integer part and there are only zeros from this point on
if (value
== 0 && fixedPoint
== 0) {
--i
;
break;
}
}
}
// Insert sign
if (neg
) str
[i
--] = '-';
// Rest is blank
for (; i
>= 0; --i
)
str
[i
] = ' ';
return str
;
}
// Trying to avoid floating point maths here. Converts a floating point string to an integer with a smaller unit
// i.e. floatStrToInt("4.5", 2) = 4.5 * 1E2 = 450
int32_t floatStrToInt
(const char *s
, int32_t power1
)
{ char *endPtr
;
int32_t v
= strtol(s
, &endPtr
, 10);
if (*endPtr
== '.') {
for (s
= endPtr
+ 1; *s
&& power1
; s
++) {
v
= v
* 10 + (*s
- '0');
--power1
;
}
}
if (power1
) {
// Table to avoid multiple multiplications
v
= v
* getPower
(power1
);
}
return v
;
}
// Delay helper
void delay_ms100x
(uint8_t delay
)
{
for ( uint8_t i
=0; i
<delay
; i
++)
_delay_ms
(100);
}
/************************************************************************************/
/* */
/* Zeitanzeige */
/* */
/************************************************************************************/
uint32_t TimeBase60
(char *str
, uint32_t time, uint8_t idx
)
{ uint32_t tmp
= time % 60;
str
[idx
] = (tmp
/ 10) + '0';
str
[idx
+ 1] = (tmp
% 10) + '0';
return time / 60;
}
void Displ_TimeMS
(int32_t time)
{ char str
[7];
str
[6] = '\0';
if (time < 0) {
time = abs(time);
str
[0] = '-';
}
else
str
[0] = ' ';
time = TimeBase60
(str
, time, 4);
str
[3] = ':';
TimeBase60
(str
, time, 1);
lcdPuts
(str
);
}
void Displ_TimeHMS
(uint32_t time)
{ char str
[9];
time /= T2SECDIV
; // Zähler aller 500µs
str
[8] = '\0';
time = TimeBase60
(str
, time, 6);
str
[5] = ':';
time = TimeBase60
(str
, time, 3);
str
[2] = ':';
TimeBase60
(str
, time, 0);
lcdPuts
(str
);
}