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 |
} |
|