0,0 → 1,195 |
|
/****************************************************************/ |
/* */ |
/* 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); |
} |