Subversion Repositories Projects

Rev

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

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