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
 ****************************************************************************/
Line 20... Line 20...
20
 
20
 
-
 
21
#include <avr/io.h>
21
#include <avr/io.h>
22
 
22
#include <util/delay.h>
23
#include <util/delay.h>
-
 
24
#include <avr/pgmspace.h> 
-
 
25
#include <string.h>
23
#include <avr/pgmspace.h> 
26
#include <stdlib.h>
24
#include "main.h"
27
#include "main.h"
Line 25... Line 28...
25
#include "max7456_software_spi.h"
28
#include "max7456_software_spi.h"
26
 
29
 
27
/* ##########################################################################
30
/* ##########################################################################
Line 28... Line 31...
28
 * MAX7456 SPI & Display stuff
31
 * MAX7456 SPI & Display stuff
29
 * ##########################################################################*/
32
 * ##########################################################################*/
-
 
33
 
-
 
34
/**
-
 
35
 * Send a byte through SPI
30
 
36
 * inline because it increases the codesize currenlty 'only' by 110byte but saves
31
/**
37
 * the context-change on every char and attribute which is at least done twice
32
 * Send a byte through SPI
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)) {
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
}
Line 205... Line 211...
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
-
 
209
 * the first digit, so num = 10 will be 0-99 and so on
214
 * <length> represents the length to rightbound the number
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) {
-
 
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
 
217
void write_ndigit_number_u(uint8_t x, uint8_t y, uint16_t number, int16_t length, uint8_t pad) {
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) {
-
 
223
                            write_ascii_char((x++)+(y * 30), '0' + b);
-
 
224
                            started = 1;
-
 
225
                        } else {
220
        for (uint8_t i = 0; i < length - strlen(s); i++) {
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;
-
 
230
 
-
 
231
                        num /= 10;
-
 
232
                }
224
        write_ascii_string(x,  y, s);
Line 233... Line 225...
233
}
225
}
234
 
226
 
235
/**
227
/**
236
 * Write only some digits of a signed <number> at <x>/<y> to MAX7456 display memory
-
 
237
 * <num> represents the largest multiple of 10 that will still be displayable as
228
 * Write a signed <number> at <x>/<y> to MAX7456 display memory
238
 * the first digit, so num = 10 will be 0-99 and so on
229
 * <length> represents the length to rightbound the number
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
 */
-
 
241
void write_ndigit_number_s(uint8_t x, uint8_t y, int16_t number, int16_t num, uint8_t pad) {
-
 
242
    if (((uint16_t) number) > 32767) {
231
 */
243
        number = number - 65536;
-
 
244
                num *= -1;
-
 
245
 
232
void write_ndigit_number_s(uint8_t x, uint8_t y, int16_t number, int16_t length, uint8_t pad) {
246
                // if number is smaller than -99[..]9 we must increase it
-
 
247
                while (number <= (num * 10)) {
-
 
248
                        number -= num * 10;
-
 
249
                }
-
 
250
 
-
 
251
                uint8_t started = 0;
-
 
252
 
233
        char s[7];
253
                while (num < 0) {
234
        itoa(number, s, 10 );
254
                        uint8_t b = number / num;
-
 
255
                        if (pad) write_ascii_char((x)+(y * 30), '0');
-
 
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;
235
        for (uint8_t i = 0; i < length - strlen(s); i++) {
260
                        } else {
-
 
261
                                write_ascii_char((x++)+(y * 30), 0);
-
 
262
                        }
-
 
263
                        number -= b * num;
-
 
264
 
236
                if (pad) write_char((x++)+(y * 30), 10);
265
                        num /= 10;
-
 
266
                }
237
                else write_ascii_char((x++)+(y * 30), 0);
267
        } else {
-
 
268
        write_char((x)+(y * 30), 0);
-
 
269
        write_ndigit_number_u(x, y, number, num, pad);
238
        }
Line 270... Line 239...
270
    }
239
        write_ascii_string(x,  y, s);
271
}
240
}
272
 
-
 
273
/**
241
 
274
 * Write only some digits of a unsigned <number> at <x>/<y> to MAX7456 display memory
-
 
275
 * as /10th of the value
242
/**
276
 * <num> represents the largest multiple of 10 that will still be displayable as
243
 * Write a unsigned <number> at <x>/<y> to MAX7456 display memory as /10th of value
277
 * the first digit, so num = 10 will be 0-99 and so on
244
 * <length> represents the length to rightbound the number
-
 
245
 * <pad> = 1 will cause blank spaced to be filled up with zeros e.g. 007 instead of   7
-
 
246
 */
278
 * <pad> = 1 will cause blank spaced to be filled up with zeros e.g. 007 instead of   7
247
void write_ndigit_number_u_10th(uint8_t x, uint8_t y, uint16_t number, int16_t length, uint8_t pad) {
279
 */
248
        char s[7];
280
void write_ndigit_number_u_10th(uint8_t x, uint8_t y, uint16_t number, int16_t num, uint8_t pad) {
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)) {
-
 
283
                        number -= num * 10;
-
 
284
                }
251
                if (pad) write_char((x++)+(y * 30), 10);
285
               
252
                else write_ascii_char((x++)+(y * 30), 0);
286
 
-
 
287
                uint8_t started = 0;
-
 
288
                while (num > 0) {
-
 
289
                        uint8_t b = number / num;
253
        }
290
                        if (b > 0 || started || num == 1) {
-
 
291
                                if ((num / 10) == 0) {
-
 
292
                                        if (!started) write_ascii_char((x - 1)+(y * 30), '0');
254
        char rest = s[strlen(s)-1];
293
                                        write_char((x++)+(y * 30), 65); // decimal point
255
        s[strlen(s)-1] = 0;
294
                                }
-
 
295
                                write_ascii_char((x++)+(y * 30), '0' + b);
256
        if (number < 10) write_char((x-1)+(y * 30), 10); // zero
296
                            started = 1;
257
        else write_ascii_string(x,  y, s);
297
                        } else {
-
 
298
                                if (pad) write_ascii_char((x++)+(y * 30), '0');
-
 
299
                                else write_ascii_char((x++)+(y * 30), ' ');
-
 
300
                        }
-
 
301
                        number -= b * num;
-
 
302
 
258
        x += strlen(s);
Line 303... Line 259...
303
                        num /= 10;
259
        write_char((x++)+(y * 30), 65); // decimal point
304
                }
260
        write_ascii_char((x++)+(y * 30), rest); // after dot
305
}
-
 
306
 
261
}
307
/**
-
 
308
 * Write only some digits of a signed <number> at <x>/<y> to MAX7456 display memory
262
 
309
 * as /10th of the value
263
/**
310
 * <num> represents the largest multiple of 10 that will still be displayable as
264
 * Write a signed <number> at <x>/<y> to MAX7456 display memory as /10th of value
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
-
 
313
 */
265
 * <length> represents the length to rightbound the number
314
void write_ndigit_number_s_10th(uint8_t x, uint8_t y, int16_t number, int16_t num, uint8_t pad) {
-
 
315
    if (((uint16_t) number) > 32767) {
-
 
316
        number = number - 65536;
266
 * <pad> = 1 will cause blank spaced to be filled up with zeros e.g. 007 instead of   7
317
                num *= -1;
-
 
318
 
-
 
319
                // if number is smaller than -99[..]9 we must increase it
-
 
320
                while (number <= (num * 10)) {
-
 
321
                        number -= num * 10;
-
 
322
                }
-
 
323
 
267
 */
324
                uint8_t started = 0;
268
void write_ndigit_number_s_10th(uint8_t x, uint8_t y, int16_t number, int16_t length, uint8_t pad) {
325
 
-
 
326
                while (num < 0) {
-
 
327
                        uint8_t b = number / num;
-
 
328
                        if (pad) write_ascii_char((x)+(y * 30), '0');
-
 
329
                        if (b > 0 || started || num == 1) {
269
        char s[7];
330
                                if ((num / 10) == 0) {
270
        itoa(number, s, 10 );
331
                                        if (!started) {
-
 
332
                                                write_ascii_char((x - 2)+(y * 30), '-');
271
        for (uint8_t i = 0; i < length - strlen(s); i++) {
333
                                                write_ascii_char((x - 1)+(y * 30), '0');
272
                if (pad) write_char((x++)+(y * 30), 10);
334
                                        }
-
 
335
                                        write_char((x++)+(y * 30), 65); // decimal point
273
                else write_char((x++)+(y * 30), 0);
336
                                } else if (!started) {
-
 
337
                                        write_char((x - 1)+(y * 30), 0x49); // minus
274
        }
338
                                }
275
        char rest = s[strlen(s)-1];
339
                            write_ascii_char((x++)+(y * 30), '0' + b);
-
 
340
                            started = 1;
-
 
341
                        } else {
-
 
342
                                write_ascii_char((x++)+(y * 30), 0);
-
 
343
                        }
276
        s[strlen(s)-1] = 0;
344
                        number -= b * num;
277
        if (number < 10) write_char((x)+(y * 30), 10); // zero
345
 
278
        else {
346
                        num /= 10;
279
                write_ascii_string(x,  y, s);
347
                }
280
        }
348
        } else {
281
        x += strlen(s);
Line 349... Line 282...
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;
Line 359... Line 292...
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);
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
}
Line 384... Line 317...
384
 
317