54,10 → 54,11 |
/* ########################################################################## |
* FLAGS usable during runtime |
* ##########################################################################*/ |
#define COSD_FLAG_NTSC 1 |
#define COSD_FLAG_ARTHORIZON 2 |
#define COSD_FLAG_NOOSD 4 |
#define COSD_FLAG_NOOSD_BUT_WRN 8 |
#define COSD_FLAG_NTSC 1 |
#define COSD_FLAG_ARTHORIZON 2 |
#define COSD_FLAG_NOOSD 4 |
#define COSD_FLAG_NOOSD_BUT_WRN 8 |
#define COSD_ICONS_WRITTEN 16 |
|
/* ########################################################################## |
* Software SPI to communicate with MAX7456 |
198,7 → 199,34 |
volatile uint16_t timer = 0; |
|
#endif // ends !(ALLCHARSDEBUG|WRITECHARS) |
|
// general PAL|NTSC distingiusch stuff |
uint8_t top_line = 1; |
uint8_t bottom_line = 14; |
|
// Flags |
uint8_t COSD_FLAGS = 0; |
|
/* ########################################################################## |
* debounce buttons |
* ##########################################################################*/ |
int s1_pressed() { |
if (S1_PRESSED) { |
_delay_ms(25); |
if (S1_PRESSED) return 1; |
} |
return 0; |
} |
|
int s2_pressed() { |
if (S2_PRESSED) { |
_delay_ms(25); |
if (S2_PRESSED) return 1; |
} |
return 0; |
} |
|
/* ########################################################################## |
* MAX7456 SPI & Display stuff |
* ##########################################################################*/ |
|
770,14 → 798,73 |
//write_number_s(18,11,roll); |
} |
|
#endif |
/* ########################################################################## |
* A simple config menu for the flags |
* ##########################################################################*/ |
void config_menu(void) { |
// disable interrupts (makes the menu more smoothely) |
cli(); |
|
// clear screen |
clear(); |
|
char* menu[4] = {"Normal OSD ", |
"+ Art.Horizon ", |
"NO OSD ", |
"NO OSD but WRN "}; |
|
uint8_t inmenu = 1; |
uint8_t chosen = 0; |
write_ascii_string(10, 4, "Config Menu"); |
|
// clear all mode flags |
COSD_FLAGS &= ~(COSD_FLAG_ARTHORIZON | COSD_FLAG_NOOSD | COSD_FLAG_NOOSD_BUT_WRN); |
|
// wait a bit before doing stuff so user has chance to release button |
_delay_ms(250); |
|
while (inmenu) { |
write_ascii_string(2, 7, menu[chosen]); |
if (s2_pressed()) { |
chosen = (chosen + 1) % 4; |
_delay_ms(500); |
} else if (s1_pressed()) { |
switch (chosen) { |
case 1: // artificial horizon |
COSD_FLAGS |= COSD_FLAG_ARTHORIZON; |
break; |
case 2: // everything off |
COSD_FLAGS |= COSD_FLAG_NOOSD; |
break; |
case 3: // only warning |
COSD_FLAGS |= COSD_FLAG_NOOSD_BUT_WRN; |
break; |
//default: // normal OSD, so let the flags cleared |
} |
// leave menu |
inmenu = 0; |
_delay_ms(500); |
} |
} |
|
// clear screen up again |
clear(); |
|
// update flags to paint display again if needed |
COSD_FLAGS &= ~COSD_ICONS_WRITTEN; |
|
// enable interrupts again |
sei(); |
} |
|
#endif // ends !(ALLCHARSDEBUG|WRITECHARS) |
|
/* ########################################################################## |
* MAIN |
* ##########################################################################*/ |
int main(void) { |
// set up FLAGS, compiler should flatten this one |
uint8_t COSD_FLAGS = (NTSC << (COSD_FLAG_NTSC - 1)); |
COSD_FLAGS = (NTSC << (COSD_FLAG_NTSC - 1)); |
COSD_FLAGS |= (ARTHORIZON << (COSD_FLAG_ARTHORIZON - 1)); |
COSD_FLAGS |= (NOOSD << (COSD_FLAG_NOOSD - 1)); |
COSD_FLAGS |= (NOOSD_BUT_WRN << (COSD_FLAG_NOOSD_BUT_WRN - 1)); |
806,11 → 893,19 |
DDRC &= ~(1 << PC5); // PC5 input (SET) |
PORTC |= (1 << PC5); // pullup |
|
// set up top and bottom lines |
if (COSD_FLAGS & COSD_FLAG_NTSC) { |
bottom_line = 12; |
} else { |
bottom_line = 14; |
} |
|
// reset the MAX7456 to be sure any undefined states do no harm |
MAX_RESET_LOW |
MAX_RESET_HIGH |
|
// check for keypress at startup |
if (S2_PRESSED) { // togle COSD_FLAG_ARTHORIZON |
if (s2_pressed()) { // togle COSD_FLAG_ARTHORIZON |
COSD_FLAGS ^= (1 << (COSD_FLAG_ARTHORIZON - 1)); |
_delay_ms(100); |
} |
851,7 → 946,10 |
* easy char creation: |
* http://cascade.dyndns.org/~cascade/scripts/max7456/ |
*/ |
// GPS |
// flashing more than 8 chars per time is not proven to be safe |
// so take care |
#if WRITECHARS == 200 |
// GPS |
unsigned char cc8[54] = {0x55, 0x50, 0x55, 0x55, 0x4a, 0x15, 0x55, 0x2a, |
0x85, 0x55, 0x2a, 0xa1, 0x55, 0x4a, 0xa8, 0x55, |
0x52, 0xa8, 0x55, 0x54, 0xaa, 0x55, 0x55, 0x09, |
923,7 → 1021,17 |
0x28, 0x55, 0x55, 0x28, 0x55, 0x55, 0x28, 0x55, |
0x55, 0x28, 0x55, 0x55, 0x00, 0x55}; |
|
// degree symbol |
learn_char(200, cc8); |
learn_char(201, cc9); |
learn_char(202, cca); |
learn_char(203, ccb); |
learn_char(204, ccc); |
learn_char(205, ccd); |
learn_char(206, cce); |
learn_char(207, ccf); |
#endif |
#if WRITECHARS == 208 |
// degree symbol |
unsigned char cd0[54] = {0x55, 0x55, 0x55, 0x54, 0x01, 0x55, 0x52, 0xa8, |
0x55, 0x48, 0x02, 0x15, 0x48, 0x52, 0x15, 0x48, |
0x52, 0x15, 0x48, 0x02, 0x15, 0x52, 0xa8, 0x55, |
995,6 → 1103,16 |
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, |
0x55, 0x55, 0x55, 0x55, 0x55, 0x55}; |
|
learn_char(208, cd0); |
learn_char(209, cd1); |
learn_char(210, cd2); |
learn_char(211, cd3); |
learn_char(212, cd4); |
learn_char(213, cd5); |
learn_char(214, cd6); |
learn_char(215, cd7); |
#endif |
#if WRITECHARS == 216 |
// compass line |
unsigned char cd8[54] = {0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, |
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, |
1067,7 → 1185,17 |
0x28, 0x55, 0x55, 0x41, 0x55, 0x55, 0x55, 0x55, |
0x55, 0x55, 0x55, 0x55, 0x55, 0x55}; |
|
// arrow right-down |
learn_char(216, cd8); |
learn_char(217, cd9); |
learn_char(218, cda); |
learn_char(219, cdb); |
learn_char(220, cdc); |
learn_char(221, cdd); |
learn_char(222, cde); |
learn_char(223, cdf); |
#endif |
#if WRITECHARS == 224 |
// arrow right-down |
unsigned char ce0[54] ={0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, |
0x55, 0x55, 0x55, 0x55, 0x54, 0x55, 0x55, 0x52, |
0x15, 0x55, 0x4a, 0x85, 0x55, 0x52, 0xa1, 0x51, |
1139,40 → 1267,6 |
0xaa, 0x15, 0x54, 0xaa, 0x15, 0x55, 0x28, 0x55, |
0x55, 0x41, 0x55, 0x55, 0x55, 0x55}; |
|
|
// flashing more than 8 chars per time is not proven to be safe |
// so take care |
#if WRITECHARS == 200 |
learn_char(200, cc8); |
learn_char(201, cc9); |
learn_char(202, cca); |
learn_char(203, ccb); |
learn_char(204, ccc); |
learn_char(205, ccd); |
learn_char(206, cce); |
learn_char(207, ccf); |
#endif |
#if WRITECHARS == 208 |
learn_char(208, cd0); |
learn_char(209, cd1); |
learn_char(210, cd2); |
learn_char(211, cd3); |
learn_char(212, cd4); |
learn_char(213, cd5); |
learn_char(214, cd6); |
learn_char(215, cd7); |
#endif |
#if WRITECHARS == 216 |
learn_char(216, cd8); |
learn_char(217, cd9); |
learn_char(218, cda); |
learn_char(219, cdb); |
learn_char(220, cdc); |
learn_char(221, cdd); |
learn_char(222, cde); |
learn_char(223, cdf); |
#endif |
#if WRITECHARS == 224 |
learn_char(224, ce0); |
learn_char(225, ce1); |
learn_char(226, ce2); |
1188,16 → 1282,12 |
* ##########################################################################*/ |
|
// Setup Video Mode |
uint8_t top_line = 1; |
uint8_t bottom_line = 0; |
if (COSD_FLAGS & COSD_FLAG_NTSC) { |
// NTSC + enable display immediately (VM0) |
spi_send_byte(0x00, 0b00001000); |
bottom_line = 12; |
} else { |
// PAL + enable display immediately (VM0) |
spi_send_byte(0x00, 0b01001000); |
bottom_line = 14; |
} |
|
// clear all display-mem (DMM) |
1221,7 → 1311,7 |
OCR0 = 6; // preload |
TIMSK |= (1 << TOIE0); // enable overflow timer0 |
|
// unmask interrupts |
// enable interrupts |
sei(); |
#endif |
|
1228,11 → 1318,7 |
//write_ascii_string(2, 7, " CaScAdE "); |
//write_ascii_string(2, 8, "is TESTING his open source"); |
//write_ascii_string(2, 9, " EPi OSD Firmware"); |
//write_ascii_string(2, 10, "Scheiss Kompass"); |
|
|
|
|
// custom char preview |
/*write_char_xy( 2, 7, 200); |
write_char_xy( 3, 7, 201); |
1286,21 → 1372,23 |
// flags from last round to check for changes |
uint8_t old_MKFlags = 0; |
|
// write fix characters, only update the data dependend |
write_char_xy(5, top_line, 203); // km/h |
write_char_xy(10, top_line, 202); // RC-transmitter |
write_char_xy(16, top_line, 208); // degree symbol |
write_char_xy(27, top_line, 204); // small meters m |
write_ascii_string(6, bottom_line, "V"); // voltage |
write_char_xy(14, bottom_line, 209); // on clock |
write_char_xy(22, bottom_line, 210); // fly clock |
write_char_xy(26, bottom_line, 200); // sat1 |
write_char_xy(27, bottom_line, 201); // sat2 |
|
char* directions[8] = {"NE", "E ", "SE", "S ", "SW", "W ", "NW", "N "}; |
char arrowdir[8] = { 218, 217, 224, 223, 222, 221, 220, 219}; |
|
while (1) { |
// write icons at init or after menu/mode-switch |
if (!(COSD_FLAGS & COSD_ICONS_WRITTEN)) { |
write_char_xy(5, top_line, 203); // km/h |
write_char_xy(10, top_line, 202); // RC-transmitter |
write_char_xy(16, top_line, 208); // degree symbol |
write_char_xy(27, top_line, 204); // small meters m |
write_ascii_string(6, bottom_line, "V"); // voltage |
write_char_xy(14, bottom_line, 209); // on clock |
write_char_xy(22, bottom_line, 210); // fly clock |
write_char_xy(26, bottom_line, 200); // sat1 |
write_char_xy(27, bottom_line, 201); // sat2 |
COSD_FLAGS |= COSD_ICONS_WRITTEN; |
} |
if (rxd_buffer_locked) { |
if (rxd_buffer[2] == 'D') { // FC Data |
/*Decode64(); |
1431,17 → 1519,18 |
rxd_buffer_locked = 0; |
} |
// handle keypress |
if (S1_PRESSED) { |
uptime = 0; |
_delay_ms(100); |
} |
if (S2_PRESSED) { |
if (s1_pressed()) { |
//sendMKData('d', 1, (unsigned char*) 0, 1); |
// request OSD Data from NC every 100ms |
unsigned char ms = 10; |
/*unsigned char ms = 10; |
sendMKData('o', 1, &ms, 1); |
_delay_ms(500); |
_delay_ms(500);*/ |
config_menu(); |
} |
if (s2_pressed()) { |
uptime = 0; |
_delay_ms(100); |
} |
} |
#endif |
return 0; |