Subversion Repositories Projects

Compare Revisions

Ignore whitespace Rev 518 → Rev 519

/C-OSD/trunk/max7456_software_spi.c
19,8 → 19,11
****************************************************************************/
 
#include <avr/io.h>
 
#include <util/delay.h>
#include <avr/pgmspace.h>
#include <string.h>
#include <stdlib.h>
#include "main.h"
#include "max7456_software_spi.h"
 
30,8 → 33,11
 
/**
* Send a byte through SPI
* inline because it increases the codesize currenlty 'only' by 110byte but saves
* the context-change on every char and attribute which is at least done twice
* (address and data byte), a significant speed-bost we do not want to miss :)
*/
void spi_send(uint8_t byte) {
inline void spi_send(uint8_t byte) {
for (int8_t i = 7; i >= 0; i--) {
if (((byte >> i) & 1)) {
MAX_SDIN_HIGH
204,151 → 210,78
}
 
/**
* Write only some digits of a unsigned <number> at <x>/<y> to MAX7456 display memory
* <num> represents the largest multiple of 10 that will still be displayable as
* the first digit, so num = 10 will be 0-99 and so on
* Write a unsigned <number> at <x>/<y> to MAX7456 display memory
* <length> represents the length to rightbound the number
* <pad> = 1 will cause blank spaced to be filled up with zeros e.g. 007 instead of 7
*/
void write_ndigit_number_u(uint8_t x, uint8_t y, uint16_t number, int16_t num, uint8_t pad) {
// if number is largar than 99[..]9 we must decrease it
while (number >= (num * 10)) {
number -= num * 10;
}
 
uint8_t started = 0;
 
while (num > 0) {
uint8_t b = number / num;
if (b > 0 || started || num == 1) {
write_ascii_char((x++)+(y * 30), '0' + b);
started = 1;
} else {
if (pad) write_ascii_char((x++)+(y * 30), '0');
else write_ascii_char((x++)+(y * 30), 0);
}
number -= b * num;
 
num /= 10;
}
void write_ndigit_number_u(uint8_t x, uint8_t y, uint16_t number, int16_t length, uint8_t pad) {
char s[7];
itoa(number, s, 10 );
for (uint8_t i = 0; i < length - strlen(s); i++) {
if (pad) write_char((x++)+(y * 30), 10);
else write_ascii_char((x++)+(y * 30), 0);
}
write_ascii_string(x, y, s);
}
 
/**
* Write only some digits of a signed <number> at <x>/<y> to MAX7456 display memory
* <num> represents the largest multiple of 10 that will still be displayable as
* the first digit, so num = 10 will be 0-99 and so on
* Write a signed <number> at <x>/<y> to MAX7456 display memory
* <length> represents the length to rightbound the number
* <pad> = 1 will cause blank spaced to be filled up with zeros e.g. 007 instead of 7
*/
void write_ndigit_number_s(uint8_t x, uint8_t y, int16_t number, int16_t num, uint8_t pad) {
if (((uint16_t) number) > 32767) {
number = number - 65536;
num *= -1;
 
// if number is smaller than -99[..]9 we must increase it
while (number <= (num * 10)) {
number -= num * 10;
}
 
uint8_t started = 0;
 
while (num < 0) {
uint8_t b = number / num;
if (pad) write_ascii_char((x)+(y * 30), '0');
if (b > 0 || started || num == 1) {
if (!started) write_char((x - 1)+(y * 30), 0x49);
write_ascii_char((x++)+(y * 30), '0' + b);
started = 1;
} else {
write_ascii_char((x++)+(y * 30), 0);
}
number -= b * num;
 
num /= 10;
}
} else {
write_char((x)+(y * 30), 0);
write_ndigit_number_u(x, y, number, num, pad);
}
void write_ndigit_number_s(uint8_t x, uint8_t y, int16_t number, int16_t length, uint8_t pad) {
char s[7];
itoa(number, s, 10 );
for (uint8_t i = 0; i < length - strlen(s); i++) {
if (pad) write_char((x++)+(y * 30), 10);
else write_ascii_char((x++)+(y * 30), 0);
}
write_ascii_string(x, y, s);
}
 
/**
* Write only some digits of a unsigned <number> at <x>/<y> to MAX7456 display memory
* as /10th of the value
* <num> represents the largest multiple of 10 that will still be displayable as
* the first digit, so num = 10 will be 0-99 and so on
* Write a unsigned <number> at <x>/<y> to MAX7456 display memory as /10th of value
* <length> represents the length to rightbound the number
* <pad> = 1 will cause blank spaced to be filled up with zeros e.g. 007 instead of 7
*/
void write_ndigit_number_u_10th(uint8_t x, uint8_t y, uint16_t number, int16_t num, uint8_t pad) {
// if number is largar than 99[..]9 we must decrease it
while (number >= (num * 10)) {
number -= num * 10;
}
 
uint8_t started = 0;
while (num > 0) {
uint8_t b = number / num;
if (b > 0 || started || num == 1) {
if ((num / 10) == 0) {
if (!started) write_ascii_char((x - 1)+(y * 30), '0');
write_char((x++)+(y * 30), 65); // decimal point
}
write_ascii_char((x++)+(y * 30), '0' + b);
started = 1;
} else {
if (pad) write_ascii_char((x++)+(y * 30), '0');
else write_ascii_char((x++)+(y * 30), ' ');
}
number -= b * num;
 
num /= 10;
}
void write_ndigit_number_u_10th(uint8_t x, uint8_t y, uint16_t number, int16_t length, uint8_t pad) {
char s[7];
itoa(number, s, 10 );
for (uint8_t i = 0; i < length - strlen(s); i++) {
if (pad) write_char((x++)+(y * 30), 10);
else write_ascii_char((x++)+(y * 30), 0);
}
char rest = s[strlen(s)-1];
s[strlen(s)-1] = 0;
if (number < 10) write_char((x-1)+(y * 30), 10); // zero
else write_ascii_string(x, y, s);
x += strlen(s);
write_char((x++)+(y * 30), 65); // decimal point
write_ascii_char((x++)+(y * 30), rest); // after dot
}
 
/**
* Write only some digits of a signed <number> at <x>/<y> to MAX7456 display memory
* as /10th of the value
* <num> represents the largest multiple of 10 that will still be displayable as
* the first digit, so num = 10 will be 0-99 and so on
* Write a signed <number> at <x>/<y> to MAX7456 display memory as /10th of value
* <length> represents the length to rightbound the number
* <pad> = 1 will cause blank spaced to be filled up with zeros e.g. 007 instead of 7
*/
void write_ndigit_number_s_10th(uint8_t x, uint8_t y, int16_t number, int16_t num, uint8_t pad) {
if (((uint16_t) number) > 32767) {
number = number - 65536;
num *= -1;
 
// if number is smaller than -99[..]9 we must increase it
while (number <= (num * 10)) {
number -= num * 10;
}
 
uint8_t started = 0;
 
while (num < 0) {
uint8_t b = number / num;
if (pad) write_ascii_char((x)+(y * 30), '0');
if (b > 0 || started || num == 1) {
if ((num / 10) == 0) {
if (!started) {
write_ascii_char((x - 2)+(y * 30), '-');
write_ascii_char((x - 1)+(y * 30), '0');
}
write_char((x++)+(y * 30), 65); // decimal point
} else if (!started) {
write_char((x - 1)+(y * 30), 0x49); // minus
}
write_ascii_char((x++)+(y * 30), '0' + b);
started = 1;
} else {
write_ascii_char((x++)+(y * 30), 0);
}
number -= b * num;
 
num /= 10;
}
} else {
write_char((x)+(y * 30), 0);
write_ndigit_number_u_10th(x, y, number, num, pad);
}
void write_ndigit_number_s_10th(uint8_t x, uint8_t y, int16_t number, int16_t length, uint8_t pad) {
char s[7];
itoa(number, s, 10 );
for (uint8_t i = 0; i < length - strlen(s); i++) {
if (pad) write_char((x++)+(y * 30), 10);
else write_char((x++)+(y * 30), 0);
}
char rest = s[strlen(s)-1];
s[strlen(s)-1] = 0;
if (number < 10) write_char((x)+(y * 30), 10); // zero
else {
write_ascii_string(x, y, s);
}
x += strlen(s);
write_char((x++)+(y * 30), 65); // decimal point
write_ascii_char((x++)+(y * 30), rest); // after dot
}
 
/**
357,9 → 290,9
void write_time(uint8_t x, uint8_t y, uint16_t seconds) {
uint16_t min = seconds / 60;
seconds -= min * 60;
write_ndigit_number_u(x, y, min, 100, 0);
write_ndigit_number_u(x, y, min, 3, 0);
write_char_xy(x + 3, y, 68);
write_ndigit_number_u(x + 4, y, seconds, 10, 1);
write_ndigit_number_u(x + 4, y, seconds, 2, 1);
}
 
/**
373,12 → 306,12
} else {
write_char_xy(x++, y, 0); // clear ('+' would be nice, maybe later)
}
write_ndigit_number_u(x, y, (uint16_t) (position / (int32_t) 10000000), 100, 1);
write_ndigit_number_u(x, y, (uint16_t) (position / (int32_t) 10000000), 3, 1);
write_char_xy(x + 3, y, 65); // decimal point
position = position - ((position / (int32_t) 10000000) * (int32_t) 10000000);
write_ndigit_number_u(x + 4, y, (uint16_t) (position / (int32_t) 1000), 1000, 1);
write_ndigit_number_u(x + 4, y, (uint16_t) (position / (int32_t) 1000), 4, 1);
position = position - ((uint16_t) (position / (int32_t) 1000) * (int32_t) 1000);
write_ndigit_number_u(x + 8, y, (uint16_t) position, 100, 1);
write_ndigit_number_u(x + 8, y, (uint16_t) position, 3, 1);
write_char_xy(x + 11, y, 0xD0); // degree symbol
}