Subversion Repositories Projects

Compare Revisions

Ignore whitespace Rev 1464 → Rev 1465

/NGVideo5_8/tags/V1.30/tools.c
0,0 → 1,179
 
/****************************************************************/
/* */
/* 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;
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) { // +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
value = (value + 5 * getPower(fixedPoint - 1)) / getPower(fixedPoint);
fixedPoint = 0;
} else if (digitsNeeded < fixedPoint) {
// We can reduce precision to make it fit (round correctly)
value = (value + 5 * getPower(digitsNeeded - 1)) / getPower(digitsNeeded);
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);
}