Subversion Repositories Projects

Rev

Rev 2598 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2598 Rev 2601
1
/****************************************************************************
1
/****************************************************************************
2
 *   Copyright (C) 2009-2017 by Claas Anders "CaScAdE" Rathje               *
2
 *   Copyright (C) 2009-2018 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
#include "usart0.h"
29
 
29
 
30
 
30
 
31
char conv_array[7]; // general array for number -> char conversation
31
char conv_array[7]; // general array for number -> char conversation
32
 
32
 
33
int int_pow(int a, int b) {
33
int int_pow(int a, int b) {
34
    if (b <= 0) return 1;
34
    if (b <= 0) return 1;
35
    int res = 1;
35
    int res = 1;
36
    while (b-- > 0) res *= a;
36
    while (b-- > 0) res *= a;
37
    return res;
37
    return res;
38
}
38
}
39
 
39
 
40
/* ##########################################################################
40
/* ##########################################################################
41
 * MAX7456 SPI & Display stuff
41
 * MAX7456 SPI & Display stuff
42
 * ##########################################################################*/
42
 * ##########################################################################*/
43
 
43
 
44
/**
44
/**
45
 * Send a byte through SPI
45
 * Send a byte through SPI
46
 * 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
47
 * 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
48
 * (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 :)
49
 */
49
 */
50
inline void spi_send(uint8_t byte) {
50
inline void spi_send(uint8_t byte) {
51
    for (int8_t i = 7; i >= 0; i--) {
51
    for (int8_t i = 7; i >= 0; i--) {
52
        if (((byte >> i) & 1)) {
52
        if (((byte >> i) & 1)) {
53
            MAX_SDIN_HIGH
53
            MAX_SDIN_HIGH
54
        } else {
54
        } else {
55
            MAX_SDIN_LOW
55
            MAX_SDIN_LOW
56
        }
56
        }
57
        MAX_SCLK_HIGH
57
        MAX_SCLK_HIGH
58
        MAX_SCLK_LOW
58
        MAX_SCLK_LOW
59
    }
59
    }
60
}
60
}
61
 
61
 
62
/**
62
/**
63
 *  Send <byte> to <address> of MAX7456
63
 *  Send <byte> to <address> of MAX7456
64
 */
64
 */
65
void spi_send_byte(uint8_t address, uint8_t byte) {
65
void spi_send_byte(uint8_t address, uint8_t byte) {
66
    // start sending
66
    // start sending
67
    MAX_CS_LOW
67
    MAX_CS_LOW
68
 
68
 
69
    spi_send(address);
69
    spi_send(address);
70
    spi_send(byte);
70
    spi_send(byte);
71
 
71
 
72
    // end sending
72
    // end sending
73
    MAX_CS_HIGH
73
    MAX_CS_HIGH
74
 
74
 
75
#ifdef SERIALDEBUGDRAW
75
#ifdef SERIALDEBUGDRAW
76
    uint8_t c = address + byte;
76
    uint8_t c = address + byte;
77
    usart0_puts("#3");
77
    usart0_puts("#3");
78
    usart0_putc(address);
78
    usart0_putc(address);
79
    usart0_putc(byte);
79
    usart0_putc(byte);
80
    usart0_putc(c);
80
    usart0_putc(c);
81
    usart0_puts("\n");
81
    usart0_puts("\n");
82
#endif
82
#endif
83
}
83
}
84
 
84
 
85
/**
85
/**
86
 *  write a <character> to <address> of MAX7456 display memory
86
 *  write a <character> to <address> of MAX7456 display memory
87
 */
87
 */
88
void write_char(uint16_t address, char character) {
88
void write_char(uint16_t address, char character) {
89
    spi_send_byte(MAX7456_DMAH, (address & 0xFF00) >> 8);
89
    spi_send_byte(MAX7456_DMAH, (address & 0xFF00) >> 8);
90
    spi_send_byte(MAX7456_DMAL, (address & 0x00FF));
90
    spi_send_byte(MAX7456_DMAL, (address & 0x00FF));
91
    spi_send_byte(MAX7456_DMDI, character);
91
    spi_send_byte(MAX7456_DMDI, character);
92
}
92
}
93
 
93
 
94
/**
94
/**
95
 *  clear display memory
95
 *  clear display memory
96
 *  (also sets 8bit mode)
96
 *  (also sets 8bit mode)
97
 */
97
 */
98
void clear(void) {
98
void clear(void) {
99
    /*uint16_t memory_address = 0;
99
    /*uint16_t memory_address = 0;
100
    for (unsigned int a = 0; a < 480; a++) {
100
    for (unsigned int a = 0; a < 480; a++) {
101
        write_char(memory_address++, 0);
101
        write_char(memory_address++, 0);
102
    }*/
102
    }*/
103
    // clear all display-mem (DMM)
103
    // clear all display-mem (DMM)
104
    spi_send_byte(MAX7456_DMM, 0b01000100);
104
    spi_send_byte(MAX7456_DMM, 0b01000100);
105
 
105
 
106
    // clearing takes 20us according to maxim so lets wait longer
106
    // clearing takes 20us according to maxim so lets wait longer
107
    _delay_us(21);
107
    _delay_us(21);
108
}
108
}
109
 
109
 
110
 
110
 
111
#if (ALLCHARSDEBUG|(WRITECHARS != -1))
111
#if (ALLCHARSDEBUG|(WRITECHARS != -1))
112
 
112
 
113
/**
113
/**
114
 * for testing write all chars to screen
114
 * for testing write all chars to screen
115
 */
115
 */
116
void write_all_chars() {
116
void write_all_chars() {
117
    uint16_t x = 3, y = 2, t = 0;
117
    uint16_t x = 3, y = 2, t = 0;
118
    while (t < 256) {
118
    while (t < 256) {
119
        write_char(x++ + y * 30, t++);
119
        write_char(x++ + y * 30, t++);
120
        if (x > 25) {
120
        if (x > 25) {
121
            y++;
121
            y++;
122
            x = 3;
122
            x = 3;
123
        }
123
        }
124
    }
124
    }
125
}
125
}
126
 
126
 
127
/**
127
/**
128
 * let the MAX7456 learn a new character at <number>
128
 * let the MAX7456 learn a new character at <number>
129
 * with <data>.
129
 * with <data>.
130
 */
130
 */
131
void learn_char(uint8_t number, unsigned char* data) {
131
void learn_char(uint8_t number, unsigned char* data) {
132
    // select character to write
132
    // select character to write
133
    spi_send_byte(MAX7456_CMAH, number);
133
    spi_send_byte(MAX7456_CMAH, number);
134
 
134
 
135
    for (uint8_t i = 0; i < 54; i++) {
135
    for (uint8_t i = 0; i < 54; i++) {
136
        // select 4pixel byte of char
136
        // select 4pixel byte of char
137
        spi_send_byte(MAX7456_CMAL, i);
137
        spi_send_byte(MAX7456_CMAL, i);
138
 
138
 
139
        // write 4pixel byte of char
139
        // write 4pixel byte of char
140
        spi_send_byte(MAX7456_CMDI, data[i]);
140
        spi_send_byte(MAX7456_CMDI, data[i]);
141
    }
141
    }
142
 
142
 
143
    // write to the NVM array from the shadow RAM
143
    // write to the NVM array from the shadow RAM
144
    spi_send_byte(MAX7456_CMM, 0b10100000);
144
    spi_send_byte(MAX7456_CMM, 0b10100000);
145
 
145
 
146
    // 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
147
    _delay_ms(120);
147
    _delay_ms(120);
148
}
148
}
149
#endif
149
#endif
150
 
150
 
151
#if !(ALLCHARSDEBUG|(WRITECHARS != -1))
151
#if !(ALLCHARSDEBUG|(WRITECHARS != -1))
152
 
152
 
153
/**
153
/**
154
 *  write a character <attribute> to <address> of MAX7456 display memory
154
 *  write a character <attribute> to <address> of MAX7456 display memory
155
 */
155
 */
156
void write_char_att(uint16_t address, char attribute) {
156
void write_char_att(uint16_t address, char attribute) {
157
    // the only important part is that the DMAH[1] is set
157
    // the only important part is that the DMAH[1] is set
158
    // so we add 2 which binary is the 2nd lowest byte
158
    // so we add 2 which binary is the 2nd lowest byte
159
    spi_send_byte(MAX7456_DMAH, ((address & 0xFF00) >> 8) | 2);
159
    spi_send_byte(MAX7456_DMAH, ((address & 0xFF00) >> 8) | 2);
160
    spi_send_byte(MAX7456_DMAL, (address & 0x00FF));
160
    spi_send_byte(MAX7456_DMAL, (address & 0x00FF));
161
    spi_send_byte(MAX7456_DMDI, attribute);
161
    spi_send_byte(MAX7456_DMDI, attribute);
162
}
162
}
163
 
163
 
164
/**
164
/**
165
 *  write a <character> at <x>/<y> to MAX7456 display memory
165
 *  write a <character> at <x>/<y> to MAX7456 display memory
166
 */
166
 */
167
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) {
168
    uint16_t address = y * 30 + x;
168
    uint16_t address = y * 30 + x;
169
    write_char(address, character);
169
    write_char(address, character);
170
}
170
}
171
 
171
 
172
/**
172
/**
173
 *  write a  character <attribute> at <x>/<y> to MAX7456 display memory
173
 *  write a  character <attribute> at <x>/<y> to MAX7456 display memory
174
 */
174
 */
175
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) {
176
    uint16_t address = y * 30 + x;
176
    uint16_t address = y * 30 + x;
177
    write_char_att(address, attribute);
177
    write_char_att(address, attribute);
178
}
178
}
179
 
179
 
180
/**
180
/**
181
 *  write an ascii <character> to <address> of MAX7456 display memory
181
 *  write an ascii <character> to <address> of MAX7456 display memory
182
 */
182
 */
183
void write_ascii_char(uint16_t address, char c) {
183
void write_ascii_char(uint16_t address, char c) {
184
    if (c == 32) c = 0; // remap space
184
    if (c == 32) c = 0; // remap space
185
    else if (c > 48 && c <= 57) c -= 48; // remap numbers
185
    else if (c > 48 && c <= 57) c -= 48; // remap numbers
186
    else if (c == '0') c = 10; // remap zero
186
    else if (c == '0') c = 10; // remap zero
187
    else if (c >= 65 && c <= 90) c -= 54; // remap big letters
187
    else if (c >= 65 && c <= 90) c -= 54; // remap big letters
188
    else if (c >= 97 && c <= 122) c -= 60; // remap small letters
188
    else if (c >= 97 && c <= 122) c -= 60; // remap small letters
189
    else if (c == '(') c = 63; // remap
189
    else if (c == '(') c = 63; // remap
190
    else if (c == ')') c = 64; // remap
190
    else if (c == ')') c = 64; // remap
191
    else if (c == '.') c = 65; // remap
191
    else if (c == '.') c = 65; // remap
192
    else if (c == '-') c = 73; // remap minus
192
    else if (c == '-') c = 73; // remap minus
193
    else if (c == ';') c = 67; // remap
193
    else if (c == ';') c = 67; // remap
194
    else if (c == ':') c = 68; // remap
194
    else if (c == ':') c = 68; // remap
195
    else if (c == ',') c = 69; // remap
195
    else if (c == ',') c = 69; // remap
196
    else if (c == '?') c = 66; // remap
196
    else if (c == '?') c = 66; // remap
197
    else if (c == '\\') c = 70; // remap
197
    else if (c == '\\') c = 70; // remap
198
    else if (c == '_') c = 0xE3; // remap
198
    else if (c == '_') c = 0xE3; // remap
199
    else if (c == '/') c = 71; // remap
199
    else if (c == '/') c = 71; // remap
200
    else if (c == '"') c = 72; // remap
200
    else if (c == '"') c = 72; // remap
201
    else if (c == '<') c = 74; // remap
201
    else if (c == '<') c = 74; // remap
202
    else if (c == '>') c = 75; // remap
202
    else if (c == '>') c = 75; // remap
203
    else if (c == '@') c = 76; // remap
203
    else if (c == '@') c = 76; // remap
204
    write_char(address, c);
204
    write_char(address, c);
205
}
205
}
206
 
206
 
207
/**
207
/**
208
 *  write an ascii <string> at <x>/<y> to MAX7456 display memory
208
 *  write an ascii <string> at <x>/<y> to MAX7456 display memory
209
 */
209
 */
210
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) {
211
    while (*string) {
211
    while (*string) {
212
        write_ascii_char(((x++)+(y * 30)), *string);
212
        write_ascii_char(((x++)+(y * 30)), *string);
213
        string++;
213
        string++;
214
    }
214
    }
215
}
215
}
216
 
216
 
217
/**
217
/**
218
 *  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
219
 */
219
 */
220
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) {
221
    while (len--) {
221
    while (len--) {
222
        write_ascii_char(((x++)+(y * 30)), *string);
222
        write_ascii_char(((x++)+(y * 30)), *string);
223
        string++;
223
        string++;
224
    }
224
    }
225
}
225
}
226
 
226
 
227
/**
227
/**
228
 *  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
229
 */
229
 */
230
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) {
231
    while (pgm_read_byte(string) != 0x00)
231
    while (pgm_read_byte(string) != 0x00)
232
        write_ascii_char(((x++)+(y * 30)), pgm_read_byte(string++));
232
        write_ascii_char(((x++)+(y * 30)), pgm_read_byte(string++));
233
}
233
}
234
 
234
 
235
/**
235
/**
236
 *  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
237
 */
237
 */
238
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) {
239
    while (length--)
239
    while (length--)
240
        write_char((x + (y++ * 30)), pgm_read_byte(string++));
240
        write_char((x + (y++ * 30)), pgm_read_byte(string++));
241
}
241
}
242
 
242
 
243
/**
243
/**
244
 * Write a unsigned <number> at <x>/<y> to MAX7456 display memory
244
 * Write a unsigned <number> at <x>/<y> to MAX7456 display memory
245
 * <length> represents the length to rightbound the number
245
 * <length> represents the length to rightbound the number
246
 * <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
247
 */
247
 */
248
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) {
249
    if (number >= int_pow(10, length)) {
249
    if (number >= int_pow(10, length)) {
250
        number = int_pow(10, length) - 1;
250
        number = int_pow(10, length) - 1;
251
    }
251
    }
252
    itoa(number, conv_array, 10);
252
    itoa(number, conv_array, 10);
253
    for (uint8_t i = 0; i < length - strlen(conv_array); i++) {
253
    for (uint8_t i = 0; i < length - strlen(conv_array); i++) {
254
        if (pad) write_char((x++)+(y * 30), 10);
254
        if (pad) write_char((x++)+(y * 30), 10);
255
        else write_ascii_char((x++)+(y * 30), 0);
255
        else write_ascii_char((x++)+(y * 30), 0);
256
    }
256
    }
257
    write_ascii_string(x, y, conv_array);
257
    write_ascii_string(x, y, conv_array);
258
}
258
}
259
 
259
 
260
/**
260
/**
261
 * Write a signed <number> at <x>/<y> to MAX7456 display memory
261
 * Write a signed <number> at <x>/<y> to MAX7456 display memory
262
 * <length> represents the length to rightbound the number
262
 * <length> represents the length to rightbound the number
263
 * <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
264
 */
264
 */
265
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) {
266
    if (number <= -int_pow(10, length)) {
266
    if (number <= -int_pow(10, length)) {
267
        number = -int_pow(10, length) + 1;
267
        number = -int_pow(10, length) + 1;
268
    } else if (number >= int_pow(10, length)) {
268
    } else if (number >= int_pow(10, length)) {
269
        number = int_pow(10, length) - 1;
269
        number = int_pow(10, length) - 1;
270
    }
270
    }
271
 
271
 
272
    itoa(number, conv_array, 10);
272
    itoa(number, conv_array, 10);
273
    if (strlen(conv_array) < length) {
273
    if (strlen(conv_array) < length) {
274
        for (uint8_t i = 0; i < length - strlen(conv_array); i++) {
274
        for (uint8_t i = 0; i < length - strlen(conv_array); i++) {
275
            if (pad) write_char((x++)+(y * 30), 10);
275
            if (pad) write_char((x++)+(y * 30), 10);
276
            else write_ascii_char((x++)+(y * 30), 0);
276
            else write_ascii_char((x++)+(y * 30), 0);
277
        }
277
        }
278
    }
278
    }
279
    write_ascii_string(x, y, conv_array);
279
    write_ascii_string(x, y, conv_array);
280
}
280
}
281
 
281
 
282
/**
282
/**
283
 * 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
284
 * <length> represents the length to rightbound the number
284
 * <length> represents the length to rightbound the number
285
 * <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
286
 */
286
 */
287
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) {
288
    if (number >= int_pow(10, length)) {
288
    if (number >= int_pow(10, length)) {
289
        number = int_pow(10, length) - 1;
289
        number = int_pow(10, length) - 1;
290
    }
290
    }
291
    itoa(number, conv_array, 10);
291
    itoa(number, conv_array, 10);
292
    uint8_t len = strlen(conv_array);
292
    uint8_t len = strlen(conv_array);
293
    for (uint8_t i = 0; i < length - len; i++) {
293
    for (uint8_t i = 0; i < length - len; i++) {
294
        if (pad) write_char((x++)+(y * 30), 10); //  zero
294
        if (pad) write_char((x++)+(y * 30), 10); //  zero
295
        else write_char((x++)+(y * 30), 0); // blank
295
        else write_char((x++)+(y * 30), 0); // blank
296
    }
296
    }
297
    char rest = conv_array[len - 1];
297
    char rest = conv_array[len - 1];
298
    conv_array[len - 1] = 0;
298
    conv_array[len - 1] = 0;
299
    if (len == 1) {
299
    if (len == 1) {
300
        write_char((x - 1)+(y * 30), 10); // zero
300
        write_char((x - 1)+(y * 30), 10); // zero
301
    } else if (len == 2 && conv_array[0] == '-') {
301
    } else if (len == 2 && conv_array[0] == '-') {
302
        write_char((x - 1)+(y * 30), 0x49); // minus
302
        write_char((x - 1)+(y * 30), 0x49); // minus
303
        write_char((x)+(y * 30), 10); // zero
303
        write_char((x)+(y * 30), 10); // zero
304
    } else {
304
    } else {
305
        write_ascii_string(x, y, conv_array);
305
        write_ascii_string(x, y, conv_array);
306
    }
306
    }
307
    x += len - 1;
307
    x += len - 1;
308
    write_char((x++)+(y * 30), 65); // decimal point
308
    write_char((x++)+(y * 30), 65); // decimal point
309
    write_ascii_char((x++)+(y * 30), rest); // after dot
309
    write_ascii_char((x++)+(y * 30), rest); // after dot
310
}
310
}
311
 
311
 
312
/**
312
/**
313
 * 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
314
 * <length> represents the length to rightbound the number
314
 * <length> represents the length to rightbound the number
315
 * <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
316
 */
316
 */
317
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) {
318
    if (number >= int_pow(10, length)) {
318
    if (number >= int_pow(10, length)) {
319
        number = int_pow(10, length) - 1;
319
        number = int_pow(10, length) - 1;
320
    }
320
    }
321
    itoa(number, conv_array, 10);
321
    itoa(number, conv_array, 10);
322
    uint8_t len = strlen(conv_array);
322
    uint8_t len = strlen(conv_array);
323
    for (uint8_t i = 0; i < length - len; i++) {
323
    for (uint8_t i = 0; i < length - len; i++) {
324
        if (pad) write_char((x++)+(y * 30), 10); //  zero
324
        if (pad) write_char((x++)+(y * 30), 10); //  zero
325
        else write_char((x++)+(y * 30), 0); // blank
325
        else write_char((x++)+(y * 30), 0); // blank
326
    }
326
    }
327
    char rest = conv_array[len - 1];
327
    char rest = conv_array[len - 1];
328
    conv_array[len - 1] = 0;
328
    conv_array[len - 1] = 0;
329
    if (len == 1) {
329
    if (len == 1) {
330
        write_char((x - 1)+(y * 30), 10); // zero
330
        write_char((x - 1)+(y * 30), 10); // zero
331
    } else if (len == 2 && conv_array[0] == '-') {
331
    } else if (len == 2 && conv_array[0] == '-') {
332
        write_char((x - 1)+(y * 30), 0x49); // minus
332
        write_char((x - 1)+(y * 30), 0x49); // minus
333
        write_char((x)+(y * 30), 10); // zero
333
        write_char((x)+(y * 30), 10); // zero
334
    } else {
334
    } else {
335
        write_ascii_string(x, y, conv_array);
335
        write_ascii_string(x, y, conv_array);
336
    }
336
    }
337
    x += len - 1;
337
    x += len - 1;
338
    write_char((x++)+(y * 30), 65); // decimal point
338
    write_char((x++)+(y * 30), 65); // decimal point
339
    write_ascii_char((x++)+(y * 30), rest); // after dot
339
    write_ascii_char((x++)+(y * 30), rest); // after dot
340
}
340
}
341
 
341
 
342
/**
342
/**
343
 *  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
344
 */
344
 */
345
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) {
346
    uint16_t min = seconds / 60;
346
    uint16_t min = seconds / 60;
347
    seconds -= min * 60;
347
    seconds -= min * 60;
348
    write_ndigit_number_u(x, y, min, 3, 0);
348
    write_ndigit_number_u(x, y, min, 3, 0);
349
    write_char_xy(x + 3, y, 68);
349
    write_char_xy(x + 3, y, 68);
350
    write_ndigit_number_u(x + 4, y, seconds, 2, 1);
350
    write_ndigit_number_u(x + 4, y, seconds, 2, 1);
351
}
351
}
352
 
352
 
353
/**
353
/**
354
 * 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
355
 */
355
 */
356
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) {
357
    if (position < 0) {
357
    if (position < 0) {
358
        position ^= ~0;
358
        position ^= ~0;
359
        position++;
359
        position++;
360
        write_char_xy(x++, y, 0x49); // minus
360
        write_char_xy(x++, y, 0x49); // minus
361
    } else {
361
    } else {
362
        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)
363
    }
363
    }
364
    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);
365
    write_char_xy(x + 3, y, 65); // decimal point
365
    write_char_xy(x + 3, y, 65); // decimal point
366
    position = position - ((position / (int32_t)10000000) * (int32_t)10000000);
366
    position = position - ((position / (int32_t)10000000) * (int32_t)10000000);
367
    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);
368
    position = position - ((uint16_t)(position / (int32_t)1000) * (int32_t)1000);
368
    position = position - ((uint16_t)(position / (int32_t)1000) * (int32_t)1000);
369
    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);
370
    write_char_xy(x + 11, y, 0xD0); // degree symbol
370
    write_char_xy(x + 11, y, 0xD0); // degree symbol
371
}
371
}
372
 
372
 
373
#endif
373
#endif
374
 
374