Subversion Repositories Projects

Rev

Rev 902 | Rev 1437 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 902 Rev 932
1
/****************************************************************************
1
/****************************************************************************
2
 *   Copyright (C) 2009-2011 by Claas Anders "CaScAdE" Rathje               *
2
 *   Copyright (C) 2009-2011 by Claas Anders "CaScAdE" Rathje               *
3
 *   admiralcascade@gmail.com                                               *
3
 *   admiralcascade@gmail.com                                               *
4
 *   Project-URL: http://www.mylifesucks.de/oss/c-osd/                      *
4
 *   Project-URL: http://www.mylifesucks.de/oss/c-osd/                      *
5
 *                                                                          *
5
 *                                                                          *
6
 *   This program is free software; you can redistribute it and/or modify   *
6
 *   This program is free software; you can redistribute it and/or modify   *
7
 *   it under the terms of the GNU General Public License as published by   *
7
 *   it under the terms of the GNU General Public License as published by   *
8
 *   the Free Software Foundation; either version 2 of the License.         *
8
 *   the Free Software Foundation; either version 2 of the License.         *
9
 *                                                                          *
9
 *                                                                          *
10
 *   This program is distributed in the hope that it will be useful,        *
10
 *   This program is distributed in the hope that it will be useful,        *
11
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
11
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
12
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
12
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
13
 *   GNU General Public License for more details.                           *
13
 *   GNU General Public License for more details.                           *
14
 *                                                                          *
14
 *                                                                          *
15
 *   You should have received a copy of the GNU General Public License      *
15
 *   You should have received a copy of the GNU General Public License      *
16
 *   along with this program; if not, write to the                          *
16
 *   along with this program; if not, write to the                          *
17
 *   Free Software Foundation, Inc.,                                        *
17
 *   Free Software Foundation, Inc.,                                        *
18
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.              *
18
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.              *
19
 ****************************************************************************/
19
 ****************************************************************************/
20
 
20
 
21
#include "main.h"
21
#include "main.h"
22
#include <avr/io.h>
22
#include <avr/io.h>
23
#include <util/delay.h>
23
#include <util/delay.h>
24
#include <avr/pgmspace.h> 
24
#include <avr/pgmspace.h> 
25
#include <string.h>
25
#include <string.h>
26
#include <stdlib.h>
26
#include <stdlib.h>
27
#include "max7456_software_spi.h"
27
#include "max7456_software_spi.h"
-
 
28
#include "usart0.h"
28
 
29
 
29
 
30
 
30
char conv_array[7]; // general array for number -> char conversation
31
char conv_array[7]; // general array for number -> char conversation
31
 
32
 
32
int pow(int a, int b) {
33
int pow(int a, int b) {
33
    if (b <= 0) return 1;
34
    if (b <= 0) return 1;
34
    int res = 1;
35
    int res = 1;
35
    while (b-- > 0) res *= a;
36
    while (b-- > 0) res *= a;
36
    return res;
37
    return res;
37
}
38
}
38
 
39
 
39
/* ##########################################################################
40
/* ##########################################################################
40
 * MAX7456 SPI & Display stuff
41
 * MAX7456 SPI & Display stuff
41
 * ##########################################################################*/
42
 * ##########################################################################*/
42
 
43
 
43
/**
44
/**
44
 * Send a byte through SPI
45
 * Send a byte through SPI
45
 * inline because it increases the codesize currenlty 'only' by 110byte but saves
46
 * inline because it increases the codesize currenlty 'only' by 110byte but saves
46
 * the context-change on every char and attribute which is at least done twice
47
 * the context-change on every char and attribute which is at least done twice
47
 * (address and data byte), a significant speed-bost we do not want to miss :)
48
 * (address and data byte), a significant speed-bost we do not want to miss :)
48
 */
49
 */
49
inline void spi_send(uint8_t byte) {
50
inline void spi_send(uint8_t byte) {
50
    for (int8_t i = 7; i >= 0; i--) {
51
    for (int8_t i = 7; i >= 0; i--) {
51
        if (((byte >> i) & 1)) {
52
        if (((byte >> i) & 1)) {
52
            MAX_SDIN_HIGH
53
            MAX_SDIN_HIGH
53
        } else {
54
        } else {
54
            MAX_SDIN_LOW
55
            MAX_SDIN_LOW
55
        }
56
        }
56
        MAX_SCLK_HIGH
57
        MAX_SCLK_HIGH
57
        MAX_SCLK_LOW
58
        MAX_SCLK_LOW
58
    }
59
    }
59
}
60
}
60
 
61
 
61
/**
62
/**
62
 *  Send <byte> to <address> of MAX7456
63
 *  Send <byte> to <address> of MAX7456
63
 */
64
 */
64
void spi_send_byte(uint8_t address, uint8_t byte) {
65
void spi_send_byte(uint8_t address, uint8_t byte) {
65
    // start sending
66
    // start sending
66
    MAX_CS_LOW
67
    MAX_CS_LOW
67
 
68
 
68
    spi_send(address);
69
    spi_send(address);
69
    spi_send(byte);
70
    spi_send(byte);
70
 
71
 
71
    // end sending
72
    // end sending
72
    MAX_CS_HIGH
73
    MAX_CS_HIGH
-
 
74
 
-
 
75
#ifdef SERIALDEBUGDRAW
-
 
76
    uint8_t c = address + byte;
-
 
77
    usart0_puts("#3");
-
 
78
    usart0_putc(address);
-
 
79
    usart0_putc(byte);
-
 
80
    usart0_putc(c);
-
 
81
    usart0_puts("\n");
-
 
82
#endif
73
}
83
}
74
 
84
 
75
/**
85
/**
76
 *  write a <character> to <address> of MAX7456 display memory
86
 *  write a <character> to <address> of MAX7456 display memory
77
 */
87
 */
78
void write_char(uint16_t address, char character) {
88
void write_char(uint16_t address, char character) {
79
    spi_send_byte(0x05, (address & 0xFF00) >> 8); // DMAH
89
    spi_send_byte(0x05, (address & 0xFF00) >> 8); // DMAH
80
    spi_send_byte(0x06, (address & 0x00FF)); // DMAL
90
    spi_send_byte(0x06, (address & 0x00FF)); // DMAL
81
    spi_send_byte(0x07, character); // DMDI
91
    spi_send_byte(0x07, character); // DMDI
82
}
92
}
83
 
93
 
84
/**
94
/**
85
 *  clear display memory
95
 *  clear display memory
86
 *  (also sets 8bit mode)
96
 *  (also sets 8bit mode)
87
 */
97
 */
88
void clear(void) {
98
void clear(void) {
89
    /*uint16_t memory_address = 0;
99
    /*uint16_t memory_address = 0;
90
    for (unsigned int a = 0; a < 480; a++) {
100
    for (unsigned int a = 0; a < 480; a++) {
91
        write_char(memory_address++, 0);
101
        write_char(memory_address++, 0);
92
    }*/
102
    }*/
93
    // clear all display-mem (DMM)
103
    // clear all display-mem (DMM)
94
    spi_send_byte(0x04, 0b01000100);
104
    spi_send_byte(0x04, 0b01000100);
95
 
105
 
96
    // clearing takes 12uS according to maxim so lets wait longer
106
    // clearing takes 12uS according to maxim so lets wait longer
97
    _delay_us(20);
107
    _delay_us(20);
98
}
108
}
99
 
109
 
100
 
110
 
101
#if (ALLCHARSDEBUG|(WRITECHARS != -1))
111
#if (ALLCHARSDEBUG|(WRITECHARS != -1))
102
 
112
 
103
/**
113
/**
104
 * for testing write all chars to screen
114
 * for testing write all chars to screen
105
 */
115
 */
106
void write_all_chars() {
116
void write_all_chars() {
107
    uint16_t x = 3, y = 2, t = 0;
117
    uint16_t x = 3, y = 2, t = 0;
108
    while (t < 256) {
118
    while (t < 256) {
109
        write_char(x++ + y * 30, t++);
119
        write_char(x++ + y * 30, t++);
110
        if (x > 25) {
120
        if (x > 25) {
111
            y++;
121
            y++;
112
            x = 3;
122
            x = 3;
113
        }
123
        }
114
    }
124
    }
115
}
125
}
116
 
126
 
117
/**
127
/**
118
 * let the MAX7456 learn a new character at <number>
128
 * let the MAX7456 learn a new character at <number>
119
 * with <data>.
129
 * with <data>.
120
 */
130
 */
121
void learn_char(uint8_t number, unsigned char* data) {
131
void learn_char(uint8_t number, unsigned char* data) {
122
    // select character to write (CMAH)
132
    // select character to write (CMAH)
123
    spi_send_byte(0x09, number);
133
    spi_send_byte(0x09, number);
124
 
134
 
125
    for (uint8_t i = 0; i < 54; i++) {
135
    for (uint8_t i = 0; i < 54; i++) {
126
        // select 4pixel byte of char (CMAL)
136
        // select 4pixel byte of char (CMAL)
127
        spi_send_byte(0x0A, i);
137
        spi_send_byte(0x0A, i);
128
 
138
 
129
        // write 4pixel byte of char (CMDI)
139
        // write 4pixel byte of char (CMDI)
130
        spi_send_byte(0x0B, data[i]);
140
        spi_send_byte(0x0B, data[i]);
131
    }
141
    }
132
 
142
 
133
    // write to the NVM array from the shadow RAM (CMM)
143
    // write to the NVM array from the shadow RAM (CMM)
134
    spi_send_byte(0x08, 0b10100000);
144
    spi_send_byte(0x08, 0b10100000);
135
 
145
 
136
    // according to maxim writing to nvram takes about 12ms, lets wait longer
146
    // according to maxim writing to nvram takes about 12ms, lets wait longer
137
    _delay_ms(120);
147
    _delay_ms(120);
138
}
148
}
139
#endif
149
#endif
140
 
150
 
141
#if !(ALLCHARSDEBUG|(WRITECHARS != -1))
151
#if !(ALLCHARSDEBUG|(WRITECHARS != -1))
142
 
152
 
143
/**
153
/**
144
 *  write a character <attribute> to <address> of MAX7456 display memory
154
 *  write a character <attribute> to <address> of MAX7456 display memory
145
 */
155
 */
146
void write_char_att(uint16_t address, char attribute) {
156
void write_char_att(uint16_t address, char attribute) {
147
    // the only important part is that the DMAH[1] is set
157
    // the only important part is that the DMAH[1] is set
148
    // so we add 2 which binary is the 2nd lowest byte
158
    // so we add 2 which binary is the 2nd lowest byte
149
    spi_send_byte(0x05, ((address & 0xFF00) >> 8) | 2); // DMAH
159
    spi_send_byte(0x05, ((address & 0xFF00) >> 8) | 2); // DMAH
150
    spi_send_byte(0x06, (address & 0x00FF)); // DMAL
160
    spi_send_byte(0x06, (address & 0x00FF)); // DMAL
151
    spi_send_byte(0x07, attribute); // DMDI
161
    spi_send_byte(0x07, attribute); // DMDI
152
}
162
}
153
 
163
 
154
/**
164
/**
155
 *  write a <character> at <x>/<y> to MAX7456 display memory
165
 *  write a <character> at <x>/<y> to MAX7456 display memory
156
 */
166
 */
157
void write_char_xy(uint8_t x, uint8_t y, char character) {
167
void write_char_xy(uint8_t x, uint8_t y, char character) {
158
    uint16_t address = y * 30 + x;
168
    uint16_t address = y * 30 + x;
159
    write_char(address, character);
169
    write_char(address, character);
160
}
170
}
161
 
171
 
162
/**
172
/**
163
 *  write a  character <attribute> at <x>/<y> to MAX7456 display memory
173
 *  write a  character <attribute> at <x>/<y> to MAX7456 display memory
164
 */
174
 */
165
void write_char_att_xy(uint8_t x, uint8_t y, char attribute) {
175
void write_char_att_xy(uint8_t x, uint8_t y, char attribute) {
166
    uint16_t address = y * 30 + x;
176
    uint16_t address = y * 30 + x;
167
    write_char_att(address, attribute);
177
    write_char_att(address, attribute);
168
}
178
}
169
 
179
 
170
/**
180
/**
171
 *  write an ascii <character> to <address> of MAX7456 display memory
181
 *  write an ascii <character> to <address> of MAX7456 display memory
172
 */
182
 */
173
void write_ascii_char(uint16_t address, char c) {
183
void write_ascii_char(uint16_t address, char c) {
174
    if (c == 32) c = 0; // remap space
184
    if (c == 32) c = 0; // remap space
175
    else if (c > 48 && c <= 57) c -= 48; // remap numbers
185
    else if (c > 48 && c <= 57) c -= 48; // remap numbers
176
    else if (c == '0') c = 10; // remap zero
186
    else if (c == '0') c = 10; // remap zero
177
    else if (c >= 65 && c <= 90) c -= 54; // remap big letters
187
    else if (c >= 65 && c <= 90) c -= 54; // remap big letters
178
    else if (c >= 97 && c <= 122) c -= 60; // remap small letters
188
    else if (c >= 97 && c <= 122) c -= 60; // remap small letters
179
    else if (c == '(') c = 63; // remap
189
    else if (c == '(') c = 63; // remap
180
    else if (c == ')') c = 64; // remap
190
    else if (c == ')') c = 64; // remap
181
    else if (c == '.') c = 65; // remap
191
    else if (c == '.') c = 65; // remap
182
    else if (c == '-') c = 73; // remap minus
192
    else if (c == '-') c = 73; // remap minus
183
    else if (c == ';') c = 67; // remap
193
    else if (c == ';') c = 67; // remap
184
    else if (c == ':') c = 68; // remap
194
    else if (c == ':') c = 68; // remap
185
    else if (c == ',') c = 69; // remap
195
    else if (c == ',') c = 69; // remap
186
    else if (c == '?') c = 66; // remap
196
    else if (c == '?') c = 66; // remap
187
    else if (c == '\\') c = 70; // remap
197
    else if (c == '\\') c = 70; // remap
188
    else if (c == '_') c = 0xE3; // remap
198
    else if (c == '_') c = 0xE3; // remap
189
    else if (c == '/') c = 71; // remap
199
    else if (c == '/') c = 71; // remap
190
    else if (c == '"') c = 72; // remap
200
    else if (c == '"') c = 72; // remap
191
    else if (c == '<') c = 74; // remap
201
    else if (c == '<') c = 74; // remap
192
    else if (c == '>') c = 75; // remap
202
    else if (c == '>') c = 75; // remap
193
    else if (c == '@') c = 76; // remap
203
    else if (c == '@') c = 76; // remap
194
    write_char(address, c);
204
    write_char(address, c);
195
}
205
}
196
 
206
 
197
/**
207
/**
198
 *  write an ascii <string> at <x>/<y> to MAX7456 display memory
208
 *  write an ascii <string> at <x>/<y> to MAX7456 display memory
199
 */
209
 */
200
void write_ascii_string(uint8_t x, uint8_t y, char *string) {
210
void write_ascii_string(uint8_t x, uint8_t y, char *string) {
201
    while (*string) {
211
    while (*string) {
202
        write_ascii_char(((x++)+(y * 30)), *string);
212
        write_ascii_char(((x++)+(y * 30)), *string);
203
        string++;
213
        string++;
204
    }
214
    }
205
}
215
}
206
 
216
 
207
/**
217
/**
208
 *  write an ascii <string> with lenght <len> at <x>/<y> to MAX7456 display memory
218
 *  write an ascii <string> with lenght <len> at <x>/<y> to MAX7456 display memory
209
 */
219
 */
210
void write_ascii_string_len(uint8_t x, uint8_t y, char *string, uint8_t len) {
220
void write_ascii_string_len(uint8_t x, uint8_t y, char *string, uint8_t len) {
211
    while (len--) {
221
    while (len--) {
212
        write_ascii_char(((x++)+(y * 30)), *string);
222
        write_ascii_char(((x++)+(y * 30)), *string);
213
        string++;
223
        string++;
214
    }
224
    }
215
}
225
}
216
 
226
 
217
/**
227
/**
218
 *  write an ascii <string> from progmen at <x>/<y> to MAX7456 display memory
228
 *  write an ascii <string> from progmen at <x>/<y> to MAX7456 display memory
219
 */
229
 */
220
void write_ascii_string_pgm(uint8_t x, uint8_t y, const char *string) {
230
void write_ascii_string_pgm(uint8_t x, uint8_t y, const char *string) {
221
    while (pgm_read_byte(string) != 0x00)
231
    while (pgm_read_byte(string) != 0x00)
222
        write_ascii_char(((x++)+(y * 30)), pgm_read_byte(string++));
232
        write_ascii_char(((x++)+(y * 30)), pgm_read_byte(string++));
223
}
233
}
224
 
234
 
225
/**
235
/**
226
 *  write an <string> from progmen at <x>/<y> downwards to MAX7456 display memory
236
 *  write an <string> from progmen at <x>/<y> downwards to MAX7456 display memory
227
 */
237
 */
228
void write_string_pgm_down(uint8_t x, uint8_t y, const char *string, uint8_t length) {
238
void write_string_pgm_down(uint8_t x, uint8_t y, const char *string, uint8_t length) {
229
    while (length--)
239
    while (length--)
230
        write_char((x + (y++ * 30)), pgm_read_byte(string++));
240
        write_char((x + (y++ * 30)), pgm_read_byte(string++));
231
}
241
}
232
 
242
 
233
/**
243
/**
234
 * Write a unsigned <number> at <x>/<y> to MAX7456 display memory
244
 * Write a unsigned <number> at <x>/<y> to MAX7456 display memory
235
 * <length> represents the length to rightbound the number
245
 * <length> represents the length to rightbound the number
236
 * <pad> = 1 will cause blank spaced to be filled up with zeros e.g. 007 instead of   7
246
 * <pad> = 1 will cause blank spaced to be filled up with zeros e.g. 007 instead of   7
237
 */
247
 */
238
void write_ndigit_number_u(uint8_t x, uint8_t y, uint16_t number, int16_t length, uint8_t pad) {
248
void write_ndigit_number_u(uint8_t x, uint8_t y, uint16_t number, int16_t length, uint8_t pad) {
239
    if (number >= pow(10, length)) {
249
    if (number >= pow(10, length)) {
240
        number = pow(10, length) - 1;
250
        number = pow(10, length) - 1;
241
    }
251
    }
242
    itoa(number, conv_array, 10);
252
    itoa(number, conv_array, 10);
243
    for (uint8_t i = 0; i < length - strlen(conv_array); i++) {
253
    for (uint8_t i = 0; i < length - strlen(conv_array); i++) {
244
        if (pad) write_char((x++)+(y * 30), 10);
254
        if (pad) write_char((x++)+(y * 30), 10);
245
        else write_ascii_char((x++)+(y * 30), 0);
255
        else write_ascii_char((x++)+(y * 30), 0);
246
    }
256
    }
247
    write_ascii_string(x, y, conv_array);
257
    write_ascii_string(x, y, conv_array);
248
}
258
}
249
 
259
 
250
/**
260
/**
251
 * Write a signed <number> at <x>/<y> to MAX7456 display memory
261
 * Write a signed <number> at <x>/<y> to MAX7456 display memory
252
 * <length> represents the length to rightbound the number
262
 * <length> represents the length to rightbound the number
253
 * <pad> = 1 will cause blank spaced to be filled up with zeros e.g. 007 instead of   7
263
 * <pad> = 1 will cause blank spaced to be filled up with zeros e.g. 007 instead of   7
254
 */
264
 */
255
void write_ndigit_number_s(uint8_t x, uint8_t y, int16_t number, int16_t length, uint8_t pad) {
265
void write_ndigit_number_s(uint8_t x, uint8_t y, int16_t number, int16_t length, uint8_t pad) {
256
    if (number <= -pow(10, length)) {
266
    if (number <= -pow(10, length)) {
257
        number = -pow(10, length) + 1;
267
        number = -pow(10, length) + 1;
258
    } else if (number >= pow(10, length)) {
268
    } else if (number >= pow(10, length)) {
259
        number = pow(10, length) - 1;
269
        number = pow(10, length) - 1;
260
    }
270
    }
261
 
271
 
262
    itoa(number, conv_array, 10);
272
    itoa(number, conv_array, 10);
263
    if (strlen(conv_array) < length) {
273
    if (strlen(conv_array) < length) {
264
        for (uint8_t i = 0; i < length - strlen(conv_array); i++) {
274
        for (uint8_t i = 0; i < length - strlen(conv_array); i++) {
265
            if (pad) write_char((x++)+(y * 30), 10);
275
            if (pad) write_char((x++)+(y * 30), 10);
266
            else write_ascii_char((x++)+(y * 30), 0);
276
            else write_ascii_char((x++)+(y * 30), 0);
267
        }
277
        }
268
    }
278
    }
269
    write_ascii_string(x, y, conv_array);
279
    write_ascii_string(x, y, conv_array);
270
}
280
}
271
 
281
 
272
/**
282
/**
273
 * Write a unsigned <number> at <x>/<y> to MAX7456 display memory as /10th of value
283
 * Write a unsigned <number> at <x>/<y> to MAX7456 display memory as /10th of value
274
 * <length> represents the length to rightbound the number
284
 * <length> represents the length to rightbound the number
275
 * <pad> = 1 will cause blank spaced to be filled up with zeros e.g. 007 instead of   7
285
 * <pad> = 1 will cause blank spaced to be filled up with zeros e.g. 007 instead of   7
276
 */
286
 */
277
void write_ndigit_number_u_10th(uint8_t x, uint8_t y, uint16_t number, int16_t length, uint8_t pad) {
287
void write_ndigit_number_u_10th(uint8_t x, uint8_t y, uint16_t number, int16_t length, uint8_t pad) {
278
    if (number >= pow(10, length)) {
288
    if (number >= pow(10, length)) {
279
        number = pow(10, length) - 1;
289
        number = pow(10, length) - 1;
280
    }
290
    }
281
    itoa(number, conv_array, 10);
291
    itoa(number, conv_array, 10);
282
    uint8_t len = strlen(conv_array);
292
    uint8_t len = strlen(conv_array);
283
    for (uint8_t i = 0; i < length - len; i++) {
293
    for (uint8_t i = 0; i < length - len; i++) {
284
        if (pad) write_char((x++)+(y * 30), 10); //  zero
294
        if (pad) write_char((x++)+(y * 30), 10); //  zero
285
        else write_char((x++)+(y * 30), 0); // blank
295
        else write_char((x++)+(y * 30), 0); // blank
286
    }
296
    }
287
    char rest = conv_array[len - 1];
297
    char rest = conv_array[len - 1];
288
    conv_array[len - 1] = 0;
298
    conv_array[len - 1] = 0;
289
    if (len == 1) {
299
    if (len == 1) {
290
        write_char((x - 1)+(y * 30), 10); // zero
300
        write_char((x - 1)+(y * 30), 10); // zero
291
    } else if (len == 2 && conv_array[0] == '-') {
301
    } else if (len == 2 && conv_array[0] == '-') {
292
        write_char((x - 1)+(y * 30), 0x49); // minus
302
        write_char((x - 1)+(y * 30), 0x49); // minus
293
        write_char((x)+(y * 30), 10); // zero
303
        write_char((x)+(y * 30), 10); // zero
294
    } else {
304
    } else {
295
        write_ascii_string(x, y, conv_array);
305
        write_ascii_string(x, y, conv_array);
296
    }
306
    }
297
    x += len - 1;
307
    x += len - 1;
298
    write_char((x++)+(y * 30), 65); // decimal point
308
    write_char((x++)+(y * 30), 65); // decimal point
299
    write_ascii_char((x++)+(y * 30), rest); // after dot
309
    write_ascii_char((x++)+(y * 30), rest); // after dot
300
}
310
}
301
 
311
 
302
/**
312
/**
303
 * Write a signed <number> at <x>/<y> to MAX7456 display memory as /10th of value
313
 * Write a signed <number> at <x>/<y> to MAX7456 display memory as /10th of value
304
 * <length> represents the length to rightbound the number
314
 * <length> represents the length to rightbound the number
305
 * <pad> = 1 will cause blank spaced to be filled up with zeros e.g. 007 instead of   7
315
 * <pad> = 1 will cause blank spaced to be filled up with zeros e.g. 007 instead of   7
306
 */
316
 */
307
void write_ndigit_number_s_10th(uint8_t x, uint8_t y, int16_t number, int16_t length, uint8_t pad) {
317
void write_ndigit_number_s_10th(uint8_t x, uint8_t y, int16_t number, int16_t length, uint8_t pad) {
308
    if (number >= pow(10, length)) {
318
    if (number >= pow(10, length)) {
309
        number = pow(10, length) - 1;
319
        number = pow(10, length) - 1;
310
    }
320
    }
311
    itoa(number, conv_array, 10);
321
    itoa(number, conv_array, 10);
312
    uint8_t len = strlen(conv_array);
322
    uint8_t len = strlen(conv_array);
313
    for (uint8_t i = 0; i < length - len; i++) {
323
    for (uint8_t i = 0; i < length - len; i++) {
314
        if (pad) write_char((x++)+(y * 30), 10); //  zero
324
        if (pad) write_char((x++)+(y * 30), 10); //  zero
315
        else write_char((x++)+(y * 30), 0); // blank
325
        else write_char((x++)+(y * 30), 0); // blank
316
    }
326
    }
317
    char rest = conv_array[len - 1];
327
    char rest = conv_array[len - 1];
318
    conv_array[len - 1] = 0;
328
    conv_array[len - 1] = 0;
319
    if (len == 1) {
329
    if (len == 1) {
320
        write_char((x - 1)+(y * 30), 10); // zero
330
        write_char((x - 1)+(y * 30), 10); // zero
321
    } else if (len == 2 && conv_array[0] == '-') {
331
    } else if (len == 2 && conv_array[0] == '-') {
322
        write_char((x - 1)+(y * 30), 0x49); // minus
332
        write_char((x - 1)+(y * 30), 0x49); // minus
323
        write_char((x)+(y * 30), 10); // zero
333
        write_char((x)+(y * 30), 10); // zero
324
    } else {
334
    } else {
325
        write_ascii_string(x, y, conv_array);
335
        write_ascii_string(x, y, conv_array);
326
    }
336
    }
327
    x += len - 1;
337
    x += len - 1;
328
    write_char((x++)+(y * 30), 65); // decimal point
338
    write_char((x++)+(y * 30), 65); // decimal point
329
    write_ascii_char((x++)+(y * 30), rest); // after dot
339
    write_ascii_char((x++)+(y * 30), rest); // after dot
330
}
340
}
331
 
341
 
332
/**
342
/**
333
 *  write <seconds> as human readable time at <x>/<y> to MAX7456 display mem
343
 *  write <seconds> as human readable time at <x>/<y> to MAX7456 display mem
334
 */
344
 */
335
void write_time(uint8_t x, uint8_t y, uint16_t seconds) {
345
void write_time(uint8_t x, uint8_t y, uint16_t seconds) {
336
    uint16_t min = seconds / 60;
346
    uint16_t min = seconds / 60;
337
    seconds -= min * 60;
347
    seconds -= min * 60;
338
    write_ndigit_number_u(x, y, min, 3, 0);
348
    write_ndigit_number_u(x, y, min, 3, 0);
339
    write_char_xy(x + 3, y, 68);
349
    write_char_xy(x + 3, y, 68);
340
    write_ndigit_number_u(x + 4, y, seconds, 2, 1);
350
    write_ndigit_number_u(x + 4, y, seconds, 2, 1);
341
}
351
}
342
 
352
 
343
/**
353
/**
344
 * wirte a <position> at <x>/<y> assuming it is a gps position for long-/latitude
354
 * wirte a <position> at <x>/<y> assuming it is a gps position for long-/latitude
345
 */
355
 */
346
void write_gps_pos(uint8_t x, uint8_t y, int32_t position) {
356
void write_gps_pos(uint8_t x, uint8_t y, int32_t position) {
347
    if (position < 0) {
357
    if (position < 0) {
348
        position ^= ~0;
358
        position ^= ~0;
349
        position++;
359
        position++;
350
        write_char_xy(x++, y, 0x49); // minus
360
        write_char_xy(x++, y, 0x49); // minus
351
    } else {
361
    } else {
352
        write_char_xy(x++, y, 0); // clear ('+' would be nice, maybe later)
362
        write_char_xy(x++, y, 0); // clear ('+' would be nice, maybe later)
353
    }
363
    }
354
    write_ndigit_number_u(x, y, (uint16_t)(position / (int32_t)10000000), 3, 1);
364
    write_ndigit_number_u(x, y, (uint16_t)(position / (int32_t)10000000), 3, 1);
355
    write_char_xy(x + 3, y, 65); // decimal point
365
    write_char_xy(x + 3, y, 65); // decimal point
356
    position = position - ((position / (int32_t)10000000) * (int32_t)10000000);
366
    position = position - ((position / (int32_t)10000000) * (int32_t)10000000);
357
    write_ndigit_number_u(x + 4, y, (uint16_t)(position / (int32_t)1000), 4, 1);
367
    write_ndigit_number_u(x + 4, y, (uint16_t)(position / (int32_t)1000), 4, 1);
358
    position = position - ((uint16_t)(position / (int32_t)1000) * (int32_t)1000);
368
    position = position - ((uint16_t)(position / (int32_t)1000) * (int32_t)1000);
359
    write_ndigit_number_u(x + 8, y, (uint16_t)position, 3, 1);
369
    write_ndigit_number_u(x + 8, y, (uint16_t)position, 3, 1);
360
    write_char_xy(x + 11, y, 0xD0); // degree symbol
370
    write_char_xy(x + 11, y, 0xD0); // degree symbol
361
}
371
}
362
 
372
 
363
#endif
373
#endif
364
 
374