Rev 465 | Rev 467 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 465 | Rev 466 | ||
---|---|---|---|
Line 38... | Line 38... | ||
38 | * - verifiy correctness of values |
38 | * - verifiy correctness of values |
39 | * - clean up code :) |
39 | * - clean up code :) |
40 | */ |
40 | */ |
Line 41... | Line 41... | ||
41 | 41 | ||
42 | #if !(ALLCHARSDEBUG|(WRITECHARS != -1)) |
42 | #if !(ALLCHARSDEBUG|(WRITECHARS != -1)) |
43 | // data structs not needed for character flashin |
43 | // data structs not needed for character flashing |
Line 44... | Line 44... | ||
44 | #include "mk-data-structs.h" |
44 | #include "mk-data-structs.h" |
45 | 45 | ||
46 | /* ########################################################################## |
46 | /* ########################################################################## |
Line 58... | Line 58... | ||
58 | volatile uint8_t last_RC_Quality = 255; |
58 | volatile uint8_t last_RC_Quality = 255; |
Line 59... | Line 59... | ||
59 | 59 | ||
60 | // 16bit should be enough, normal LiPos don't last that long |
60 | // 16bit should be enough, normal LiPos don't last that long |
61 | volatile uint16_t uptime = 0; |
61 | volatile uint16_t uptime = 0; |
62 | volatile uint16_t timer = 0; |
- | |
Line 63... | Line 62... | ||
63 | volatile uint8_t short_timer = 0; |
62 | volatile uint16_t timer = 0; |
64 | 63 | ||
Line 65... | Line 64... | ||
65 | // remember last time data was received |
64 | // remember last time data was received |
Line 134... | Line 133... | ||
134 | * STROM TEST |
133 | * STROM TEST |
135 | * ##########################################################################*/ |
134 | * ##########################################################################*/ |
136 | #define INT0_HIGH PORTD |= (1 << PD2); |
135 | #define INT0_HIGH PORTD |= (1 << PD2); |
137 | #define INT0_LOW PORTD &= ~(1 << PD2); |
136 | #define INT0_LOW PORTD &= ~(1 << PD2); |
Line 138... | Line 137... | ||
138 | 137 | ||
139 | void SpiMasterInit(void) |
- | |
140 | { |
138 | void SpiMasterInit(void) { |
141 | volatile char IOReg; |
139 | volatile char IOReg; |
142 | // set PB4(/SS), PB5(MOSI), PB7(SCK) as output |
140 | // set PB4(/SS), PB5(MOSI), PB7(SCK) as output |
143 | DDRB = (1<<PB4)|(1<<PB5)|(1<<PB7); |
141 | DDRB = (1 << PB4) | (1 << PB5) | (1 << PB7); |
144 | PORTB |= (1 << PB4); // pullup SS |
142 | PORTB |= (1 << PB4); // pullup SS |
145 | // enable SPI Interrupt and SPI in Master Mode with SCK = CK/128 |
143 | // enable SPI Interrupt and SPI in Master Mode with SCK = CK/128 |
146 | SPCR = (1<<SPIE)|(1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<SPR1); |
144 | SPCR = (1 << SPIE) | (1 << SPE) | (1 << MSTR) | (1 << SPR0) | (1 << SPR1); |
147 | IOReg = SPSR; // clear SPIF bit in SPSR |
145 | IOReg = SPSR; // clear SPIF bit in SPSR |
148 | IOReg = SPDR; |
146 | IOReg = SPDR; |
149 | //sei(); // we do it later |
147 | //sei(); // we do it later |
Line 150... | Line 148... | ||
150 | } |
148 | } |
151 | 149 | ||
152 | volatile size_t icnt = 0; |
150 | volatile size_t icnt = 0; |
153 | volatile unsigned char * iptr; |
151 | volatile unsigned char * iptr; |
154 | volatile unsigned char spi_cmd[5]; |
152 | volatile unsigned char spi_cmd_buffer[5]; |
Line -... | Line 153... | ||
- | 153 | volatile uint8_t spi_ready = 1; |
|
155 | volatile uint8_t spi_ready = 1; |
154 | int16_t ampere = 0; |
156 | int16_t ampere = 0; |
155 | |
157 | - | ||
158 | ISR(SPI_STC_vect) |
156 | /** |
159 | { |
157 | * SPI interrupt handler |
160 | /* Empfangenes Byte im Puffer ablegen. */ |
158 | */ |
161 | *iptr++ = SPDR; |
- | |
162 | /* Zähler dekrementieren. */ |
159 | ISR(SPI_STC_vect) { |
163 | icnt--; |
- | |
164 | /* Falls Zähler noch nicht 0 ist... */ |
160 | *iptr++ = SPDR; // safe received byte to buffer |
165 | if (icnt) { |
161 | icnt--; // dec length |
166 | ///_delay_ms(1); |
- | |
167 | /* ...nächstes Byte senden. */ |
- | |
168 | //SPDR = *iptr; |
162 | if (icnt) { |
169 | spi_ready = 1; |
163 | //SPDR = *iptr; // send next byte |
170 | } |
164 | spi_ready = 1; // we _should_ send later because the slave needs more time |
171 | else { |
- | |
172 | /* ...andernfalls Interrupt Modus deaktivieren. */ |
- | |
173 | SPCR &= ~_BV(SPIE); |
165 | } else { |
174 | INT0_HIGH |
166 | SPCR &= ~_BV(SPIE); // deactivate interrupt |
Line -... | Line 167... | ||
- | 167 | INT0_HIGH // transfer is done, slave does not need to listen |
|
175 | //_delay_ms(1); |
168 | } |
176 | } |
169 | } |
- | 170 | ||
177 | } |
171 | /** |
178 | 172 | * check if SPI transfer is still busy |
|
Line -... | Line 173... | ||
- | 173 | */ |
|
- | 174 | int TransferIsBusy(void) { |
|
- | 175 | return SPCR & _BV(SPIE); |
|
179 | int TransferIsBusy(void) |
176 | } |
- | 177 | ||
180 | { |
178 | /** |
181 | return SPCR & _BV(SPIE); |
- | |
182 | } |
179 | * start a new transfer of <data> with length <len> |
183 | 180 | */ |
|
184 | void StartTransfer(unsigned char *data, size_t len) |
181 | void StartTransfer(unsigned char *data, size_t len) { |
185 | { |
182 | INT0_LOW // /SS LOW ^= SS HIGH ^= slave should listen |
186 | INT0_LOW |
- | |
187 | /* Interrupt Datenpointer und Zähler setzen. */ |
183 | |
188 | iptr = data; |
184 | // set up pointer and length for interrupt handler |
189 | icnt = len; |
185 | iptr = data; |
Line 190... | Line 186... | ||
190 | 186 | icnt = len; |
|
191 | /* SPI Interrupt aktivieren und Transfer anstossen. */ |
187 | |
192 | SPCR |= _BV(SPIE); |
188 | SPCR |= _BV(SPIE); // enable spi interrupt |
Line 193... | Line -... | ||
193 | SPDR = *iptr; |
- | |
194 | } |
189 | SPDR = *iptr; // start transfer by first bye |
195 | 190 | } |
|
196 | 191 | ||
197 | /* ########################################################################## |
192 | |
198 | * / STROM TEST END |
193 | /* ########################################################################## |
199 | * ##########################################################################*/ |
194 | * / STROM TEST END |
200 | 195 | * ##########################################################################*/ |
|
201 | 196 | ||
202 | /** |
197 | /** |
203 | * timer kicks in every 1000uS ^= 1ms |
198 | * timer kicks in every 1000uS ^= 1ms |
204 | */ |
199 | */ |
205 | ISR(TIMER0_OVF_vect) { |
200 | ISR(TIMER0_OVF_vect) { |
206 | OCR0 = 15; // preload |
201 | OCR0 = 15; // preload |
207 | if (!timer--) { |
202 | if (!timer--) { |
208 | uptime++; |
203 | uptime++; |
Line 209... | Line 204... | ||
209 | timer = 999; |
204 | timer = 999; |
210 | seconds_since_last_data++; |
205 | seconds_since_last_data++; |
211 | } |
206 | } |
Line 381... | Line 376... | ||
381 | #if FCONLY |
376 | #if FCONLY |
382 | write_ascii_string(2, 3, "FC only Mode"); |
377 | write_ascii_string(2, 3, "FC only Mode"); |
383 | #else |
378 | #else |
384 | write_ascii_string(2, 3, "NaviCtrl Mode"); |
379 | write_ascii_string(2, 3, "NaviCtrl Mode"); |
385 | #endif |
380 | #endif |
386 | write_ascii_string(2, 4, BUILDDATE); |
381 | write_ascii_string(2, 4, BUILDDATE); |
387 | uint8_t cellnum = 0; |
382 | uint8_t cellnum = 0; |
388 | if (CELL_NUM == -1) { |
383 | if (CELL_NUM == -1) { |
389 | write_ascii_string(2, 6, "Guessing Number of Cells"); |
384 | write_ascii_string(2, 6, "Guessing Number of Cells"); |
390 | do { |
385 | do { |
391 | cellnum++; |
386 | cellnum++; |
392 | } while (UBat > ((cellnum * CELL_VOLT_MAX) + 15)); |
387 | } while (UBat > ((cellnum * CELL_VOLT_MAX) + 23)); |
393 | } else { |
388 | } else { |
394 | cellnum = CELL_NUM; |
389 | cellnum = CELL_NUM; |
395 | } |
390 | } |
396 | min_voltage = cellnum * CELL_VOLT_MIN; |
391 | min_voltage = cellnum * CELL_VOLT_MIN; |
397 | max_voltage = cellnum * CELL_VOLT_MAX; |
392 | max_voltage = cellnum * CELL_VOLT_MAX; |
Line 411... | Line 406... | ||
411 | 406 | ||
412 | /* ########################################################################## |
407 | /* ########################################################################## |
413 | * MAIN |
408 | * MAIN |
414 | * ##########################################################################*/ |
409 | * ##########################################################################*/ |
415 | int main(void) { |
410 | int main(void) { |
416 | 411 | ||
417 | // set up FLAGS, compiler should flatten this one |
412 | // set up FLAGS, compiler should flatten this one |
418 | COSD_FLAGS = (NTSC << 0); |
413 | COSD_FLAGS = (NTSC << 0); |
419 | COSD_FLAGS |= (HUD << 1); |
414 | COSD_FLAGS |= (HUD << 1); |
420 | COSD_FLAGS |= (ARTHORIZON << 2); |
415 | COSD_FLAGS |= (ARTHORIZON << 2); |
Line 464... | Line 459... | ||
464 | LED4_OFF |
459 | LED4_OFF |
Line 465... | Line 460... | ||
465 | 460 | ||
466 | 461 | ||
467 | //Pushing NEW chars to the MAX7456 |
462 | //Pushing NEW chars to the MAX7456 |
468 | #if (WRITECHARS != -1) |
463 | #if (WRITECHARS != -1) |
469 | // DISABLE display (VM0) |
464 | // DISABLE display (VM0) |
470 | spi_send_byte(0x00, 0b00000000); |
465 | spi_send_byte(0x00, 0b00000000); |
Line 471... | Line 466... | ||
471 | #include "characters.c" |
466 | #include "characters.c" |
472 | #endif |
467 | #endif |
473 | 468 | ||
Line 499... | Line 494... | ||
499 | // set up timer |
494 | // set up timer |
500 | TCCR0 |= (1 << CS00) | (1 << CS01); // timer0 prescaler 64 |
495 | TCCR0 |= (1 << CS00) | (1 << CS01); // timer0 prescaler 64 |
501 | OCR0 = 15; // preload |
496 | OCR0 = 15; // preload |
502 | TIMSK |= (1 << TOIE0); // enable overflow timer0 |
497 | TIMSK |= (1 << TOIE0); // enable overflow timer0 |
Line 503... | Line 498... | ||
503 | 498 | ||
504 | DDRD |= (1 << PD2); // PD2 output (INT0) |
499 | DDRD |= (1 << PD2); // PD2 output (INT0) |
Line 505... | Line 500... | ||
505 | SpiMasterInit(); |
500 | SpiMasterInit(); |
506 | 501 | ||
507 | // enable interrupts |
502 | // enable interrupts |
508 | sei(); |
503 | sei(); |
Line 509... | Line 504... | ||
509 | 504 | ||
510 | #endif |
505 | #endif |
511 | 506 | ||
Line 512... | Line 507... | ||
512 | //write_ascii_string(2, 7, " CaScAdE "); |
507 | //write_ascii_string(2, 7, " CaScAdE "); |
513 | //write_ascii_string(2, 8, "is TESTING his open source"); |
508 | //write_ascii_string(2, 8, "is TESTING his open source"); |
Line 514... | Line 509... | ||
514 | //write_ascii_string(2, 9, " EPi OSD Firmware"); |
509 | //write_ascii_string(2, 9, " EPi OSD Firmware"); |
515 | 510 | ||
516 | // we are ready |
511 | // we are ready |
517 | LED3_ON |
512 | LED3_ON |
518 | 513 | ||
519 | #if ALLCHARSDEBUG | (WRITECHARS != -1) |
514 | #if ALLCHARSDEBUG | (WRITECHARS != -1) |
520 | clear(); |
515 | clear(); |
521 | write_all_chars(); |
516 | write_all_chars(); |
522 | #else |
517 | #else |
523 | // clear serial screen |
518 | // clear serial screen |
524 | //usart1_puts("\x1B[2J\x1B[H"); |
519 | //usart1_puts("\x1B[2J\x1B[H"); |
525 | //usart1_puts("hello world!\r\n"); |
520 | //usart1_puts("hello world!\r\n"); |
526 | #if FCONLY |
521 | #if FCONLY |
Line 527... | Line 522... | ||
527 | // request data ever 100ms from FC; |
522 | // request data ever 100ms from FC; |
528 | usart1_request_mk_data(0, 'd', 100); |
523 | usart1_request_mk_data(0, 'd', 100); |
529 | #else |
524 | #else |
Line 530... | Line 525... | ||
530 | // request OSD Data from NC every 100ms |
525 | // request OSD Data from NC every 100ms |
531 | usart1_request_mk_data(1, 'o', 100); |
526 | usart1_request_mk_data(1, 'o', 100); |
532 | 527 | ||
533 | // and disable debug... |
528 | // and disable debug... |
534 | usart1_request_mk_data(0, 'd', 0); |
529 | usart1_request_mk_data(0, 'd', 0); |
535 | #endif |
530 | #endif |
536 | 531 | ||
Line 537... | Line 532... | ||
537 | // stats for after flight |
532 | // stats for after flight |
538 | int16_t max_Altimeter = 0; |
533 | int16_t max_Altimeter = 0; |
Line 550... | Line 545... | ||
550 | #endif |
545 | #endif |
Line 551... | Line 546... | ||
551 | 546 | ||
- | 547 | ||
552 | 548 | ||
553 | 549 | while (1) { |
|
554 | while (1) { |
550 | // in case SPI is ready and there is nothing to send right now |
555 | if (!icnt && spi_ready) { |
551 | if (!icnt && spi_ready) { |
556 | short_timer = 0; |
552 | // correct transfer ends with d (done) |
557 | ampere = spi_cmd[1] << 8; |
- | |
558 | ampere |= spi_cmd[2]; |
553 | if (spi_cmd_buffer[0] == 'd') { |
559 | //write_ascii_char(7+4*30, spi_cmd[0]); |
554 | ampere = spi_cmd_buffer[1] << 8; |
560 | 555 | ampere |= spi_cmd_buffer[2]; |
|
561 | if (spi_cmd[0] == 'd') { |
556 | // update flags |
- | 557 | COSD_FLAGS2 |= COSD_FLAG_STROMREC; |
|
562 | COSD_FLAGS2 |= COSD_FLAG_STROMREC; |
558 | //write_ascii_char(8+4*30, 'v'); // valid |
563 | //write_ascii_char(8+4*30, 'v'); // valid |
559 | } else { |
564 | } else { |
560 | // update flags |
565 | COSD_FLAGS2 &= ~COSD_FLAG_STROMREC; |
561 | COSD_FLAGS2 &= ~COSD_FLAG_STROMREC; |
566 | //write_ascii_char(8+4*30, 'i'); // invalid |
562 | //write_ascii_char(8+4*30, 'i'); // invalid |
567 | } |
563 | } |
568 | spi_cmd[0] = 'A'; |
564 | spi_cmd_buffer[0] = 'A'; |
569 | spi_cmd[1] = 'B'; |
565 | spi_cmd_buffer[1] = 'B'; |
570 | spi_cmd[2] = 'C'; |
566 | spi_cmd_buffer[2] = 'C'; |
571 | StartTransfer((unsigned char*)spi_cmd, 3); |
567 | StartTransfer((unsigned char*) spi_cmd_buffer, 3); |
572 | } |
568 | } |
573 | if (rxd_buffer_locked) { |
569 | if (rxd_buffer_locked) { |
574 | if (COSD_FLAGS & COSD_FLAG_HUD) { |
570 | if (COSD_FLAGS & COSD_FLAG_HUD) { |
575 | #if FCONLY |
571 | #if FCONLY |
Line 576... | Line 572... | ||
576 | if (rxd_buffer[2] == 'D') { // FC Data |
572 | if (rxd_buffer[2] == 'D') { // FC Data |
577 | Decode64(); |
573 | Decode64(); |
578 | debugData = *((DebugOut_t*) pRxData); |
574 | debugData = *((DebugOut_t*) pRxData); |
579 | 575 | ||
580 | // init on first data retrival, distinguished by last battery :) |
576 | // init on first data retrival, distinguished by last battery :) |
581 | if (last_UBat == 255) { |
577 | if (last_UBat == 255) { |
582 | // fix for min_UBat |
578 | // fix for min_UBat |
583 | min_UBat = debugData.Analog[9]; |
579 | min_UBat = debugData.Analog[9]; |
584 | auto_config(debugData.Analog[9]); |
580 | auto_config(debugData.Analog[9]); |
585 | } |
581 | } |
586 | #include "osd_fcmode_default.c" |
582 | #include "osd_fcmode_default.c" |
587 | } |
583 | } |
588 | #else |
584 | #else |
589 | if (rxd_buffer[2] == 'O') { // NC OSD Data |
585 | if (rxd_buffer[2] == 'O') { // NC OSD Data |
590 | Decode64(); |
586 | Decode64(); |
591 | naviData = *((NaviData_t*) pRxData); |
587 | naviData = *((NaviData_t*) pRxData); |
592 | 588 | ||
593 | // init on first data retrival, distinguished by last battery :) |
589 | // init on first data retrival, distinguished by last battery :) |
594 | if (last_UBat == 255) { |
590 | if (last_UBat == 255) { |
595 | // fix for min_UBat |
591 | // fix for min_UBat |
596 | min_UBat = naviData.UBat; |
592 | min_UBat = naviData.UBat; |
597 | auto_config(naviData.UBat); |
593 | auto_config(naviData.UBat); |
598 | } |
594 | } |
599 | #include "osd_ncmode_default.c" |
595 | #include "osd_ncmode_default.c" |
600 | } |
596 | } |
601 | #endif |
597 | #endif |