Subversion Repositories Projects

Rev

Rev 514 | Rev 523 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 514 Rev 519
Line 17... Line 17...
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
Line 202... Line 208...
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
 */
Line 371... Line 304...
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