Subversion Repositories Projects

Rev

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

Rev 1115 Rev 1117
1
 
1
 
2
/****************************************************************/
2
/****************************************************************/
3
/*                                                                                                                              */
3
/*                                                                                                                              */
4
/*                               NG-Video 5,8GHz                                                        */
4
/*                               NG-Video 5,8GHz                                                        */
5
/*                                                                                                                              */
5
/*                                                                                                                              */
6
/*                              Copyright (C) 2011 - gebad                                              */
6
/*                              Copyright (C) 2011 - gebad                                              */
7
/*                                                                                                                              */
7
/*                                                                                                                              */
8
/*  This code is distributed under the GNU Public License               */
8
/*  This code is distributed under the GNU Public License               */
9
/*      which can be found at http://www.gnu.org/licenses/gpl.txt       */
9
/*      which can be found at http://www.gnu.org/licenses/gpl.txt       */
10
/*                                                                                                                              */
10
/*                                                                                                                              */
11
/****************************************************************/
11
/****************************************************************/
12
 
12
 
13
#include <avr/io.h>
13
#include <avr/io.h>
14
#include <stdlib.h>
14
#include <stdlib.h>
15
#include <avr/interrupt.h>
15
#include <avr/interrupt.h>
16
#include <avr/eeprom.h>
16
#include <avr/eeprom.h>
17
#include <util/delay.h>
17
#include <util/delay.h>
18
 
18
 
19
#include "config.h"
19
#include "config.h"
20
#include "dogm.h"
20
#include "dogm.h"
21
#include "messages.h"
21
#include "messages.h"
22
#include "ngvideo.h"
22
#include "ngvideo.h"
23
#include "menue.h"
23
#include "menue.h"
24
#include "servo.h"
24
#include "servo.h"
25
#include "tracking.c"
25
#include "tracking.c"
26
 
26
 
27
 
27
 
28
/************************************************************************************/
28
/************************************************************************************/
29
/*  initialisiert den EEPROM mit default Werten, bzw. liest EEPROM gespeicherte         */
29
/*  initialisiert den EEPROM mit default Werten, bzw. liest EEPROM gespeicherte         */
30
/*  Werte in gloabale Variablen.                                                                                                        */
30
/*  Werte in gloabale Variablen.                                                                                                        */
31
/*      Parameter:                                                                                                                                              */
31
/*      Parameter:                                                                                                                                              */
32
/*  uint8_t ep_reset   :0 = zwangsweises Rückstetzen auf default-Werte                          */
32
/*  uint8_t ep_reset   :0 = zwangsweises Rückstetzen auf default-Werte                          */
33
/*                                                                                                                                                                      */
33
/*                                                                                                                                                                      */
34
/************************************************************************************/
34
/************************************************************************************/
35
void Init_EEPROM(uint8_t ep_reset)
35
void Init_EEPROM(uint8_t ep_reset)
36
{ char ver[sizeof(VERSION)];
36
{ char ver[sizeof(VERSION)];
37
  uint8_t eep_init;
37
  uint8_t eep_init;
38
 
38
 
39
  eep_init = eeprom_read_byte(&ep_eep_init);
39
  eep_init = eeprom_read_byte(&ep_eep_init);
40
  eeprom_read_block(&ver, &ep_version, sizeof(VERSION));
40
  eeprom_read_block(&ver, &ep_version, sizeof(VERSION));
41
  _delay_ms(1);
41
  _delay_ms(1);
42
 
42
 
43
  if ((eep_init != EEP_INITB) || (ep_reset == 0) || strcmp(VERSION, ver))
43
  if ((eep_init != EEP_INITB) || (ep_reset == 0) || strcmp(VERSION, ver))
44
  {
44
  {
45
     // nur bei Erstinitialisierung DOGM auf default 3,3V setzen
45
     // nur bei Erstinitialisierung DOGM auf default 3,3V setzen
46
        if ((eep_init != EEP_INITB) || strcmp(VERSION, ver)){
46
        if ((eep_init != EEP_INITB) || strcmp(VERSION, ver)){
47
          eeprom_write_byte(&ep_eep_init, EEP_INITB);
47
          eeprom_write_byte(&ep_eep_init, EEP_INITB);
48
          eeprom_write_byte(&ep_dogm_vers, DOGM3V);
48
          eeprom_write_byte(&ep_dogm_vers, DOGM3V);
49
          eeprom_write_byte(&ep_contrast, CONTRAST3V);
49
          eeprom_write_byte(&ep_contrast, CONTRAST3V);
50
      eeprom_write_block(&VERSION, &ep_version, sizeof(VERSION));
50
      eeprom_write_block(&VERSION, &ep_version, sizeof(VERSION));
51
    }
51
    }
52
        eeprom_write_byte(&ep_light_time, BACKGR_LIGHT_MAX);
52
        eeprom_write_byte(&ep_light_time, BACKGR_LIGHT_MAX);
53
        eeprom_write_byte(&ep_u_offset, U_OFFSET);
53
        eeprom_write_byte(&ep_u_offset, U_OFFSET);
54
        eeprom_write_dword(&ep_u_min, U_MIN);
54
        eeprom_write_dword(&ep_u_min, U_MIN);
55
    eeprom_write_byte(&ep_channel, CHANNEL);
55
    eeprom_write_byte(&ep_channel, CHANNEL);
56
    eeprom_write_byte(&ep_av_source, AV_SOURCE);
56
    eeprom_write_byte(&ep_av_source, AV_SOURCE);
57
        eeprom_write_byte(&ep_language, NO_LANGUAGE);
57
        eeprom_write_byte(&ep_language, NO_LANGUAGE);
58
    eeprom_write_word(&ep_udbm_min, UDBM_MIN);
58
    eeprom_write_word(&ep_udbm_min, UDBM_MIN);
59
        eeprom_write_word(&ep_udbm_max, UDBM_MAX);
59
        eeprom_write_word(&ep_udbm_max, UDBM_MAX);
60
        eeprom_write_word(&ep_udbm_korr_1, UDBM_KORR_FA);
60
        eeprom_write_word(&ep_udbm_korr_1, UDBM_KORR_FA);
61
        eeprom_write_word(&ep_udbm_korr_2, UDBM_KORR_FA);
61
        eeprom_write_word(&ep_udbm_korr_2, UDBM_KORR_FA);
62
    eeprom_write_byte(&ep_sIdxSteps, STEPS_255);
62
    eeprom_write_byte(&ep_sIdxSteps, STEPS_255);
63
        eeprom_write_block(&servo[0],&ep_servo[0],sizeof(servo_t));
63
        eeprom_write_block(&servo[0],&ep_servo[0],sizeof(servo_t));
64
        eeprom_write_block(&servo[1],&ep_servo[1],sizeof(servo_t));
64
        eeprom_write_block(&servo[1],&ep_servo[1],sizeof(servo_t));
65
        eeprom_write_byte(&ep_tracking, TRACKING_MIN);
65
        eeprom_write_byte(&ep_tracking, TRACKING_MIN);
66
        eeprom_write_byte(&ep_track_hyst, TRACKING_HYSTERESE);
66
        eeprom_write_byte(&ep_track_hyst, TRACKING_HYSTERESE);
67
        eeprom_write_byte(&ep_track_tx, 0);
67
        eeprom_write_byte(&ep_track_tx, 0);
68
        eeprom_write_byte(&ep_baudrate, BAUDRATE);
68
        eeprom_write_byte(&ep_baudrate, BAUDRATE);
69
        sIdxSteps = STEPS_255;
69
        sIdxSteps = STEPS_255;
70
  }
70
  }
71
  else
71
  else
72
  {
72
  {
73
        light_time = eeprom_read_byte(&ep_light_time);
73
        light_time = eeprom_read_byte(&ep_light_time);
74
        u_offset = eeprom_read_byte(&ep_u_offset);
74
        u_offset = eeprom_read_byte(&ep_u_offset);
75
        u_min = eeprom_read_dword(&ep_u_min);
75
        u_min = eeprom_read_dword(&ep_u_min);
76
    channel = eeprom_read_byte(&ep_channel);
76
    channel = eeprom_read_byte(&ep_channel);
77
    av_source = eeprom_read_byte(&ep_av_source);
77
    av_source = eeprom_read_byte(&ep_av_source);
78
        language = eeprom_read_byte(&ep_language);
78
        language = eeprom_read_byte(&ep_language);
79
        udbm_min = eeprom_read_word(&ep_udbm_min);
79
        udbm_min = eeprom_read_word(&ep_udbm_min);
80
        udbm_max = eeprom_read_word(&ep_udbm_max);
80
        udbm_max = eeprom_read_word(&ep_udbm_max);
81
        udbm_korr_1 = eeprom_read_word(&ep_udbm_korr_1);
81
        udbm_korr_1 = eeprom_read_word(&ep_udbm_korr_1);
82
        udbm_korr_2 = eeprom_read_word(&ep_udbm_korr_2);
82
        udbm_korr_2 = eeprom_read_word(&ep_udbm_korr_2);
83
        sIdxSteps = eeprom_read_byte(&ep_sIdxSteps);
83
        sIdxSteps = eeprom_read_byte(&ep_sIdxSteps);
84
        eeprom_read_block(&servo[0],&ep_servo[0],sizeof(servo_t));
84
        eeprom_read_block(&servo[0],&ep_servo[0],sizeof(servo_t));
85
        eeprom_read_block(&servo[1],&ep_servo[1],sizeof(servo_t));
85
        eeprom_read_block(&servo[1],&ep_servo[1],sizeof(servo_t));
86
    tracking = eeprom_read_byte(&ep_tracking);
86
    tracking = eeprom_read_byte(&ep_tracking);
87
    track_hyst = eeprom_read_byte(&ep_track_hyst);
87
    track_hyst = eeprom_read_byte(&ep_track_hyst);
88
        track_tx = eeprom_read_byte(&ep_track_tx);
88
        track_tx = eeprom_read_byte(&ep_track_tx);
89
        baudrate = eeprom_read_byte(&ep_baudrate);
89
        baudrate = eeprom_read_byte(&ep_baudrate);
90
 }
90
 }
91
  dogm_vers = eeprom_read_byte(&ep_dogm_vers);
91
  dogm_vers = eeprom_read_byte(&ep_dogm_vers);
92
  contrast = eeprom_read_byte(&ep_contrast);
92
  contrast = eeprom_read_byte(&ep_contrast);
93
  hyst_u_min = u_min;
93
  hyst_u_min = u_min;
94
  wudbm = RSSI_Calc_UdBm(pudbm); // Vergleichstabelle für dBm-Balken berechnen
94
  wudbm = RSSI_Calc_UdBm(pudbm); // Vergleichstabelle für dBm-Balken berechnen
95
  sw_avx = av_source;
95
  sw_avx = av_source;
96
  for (uint8_t i = 0; i < SERVO_NUM_CHANNELS; i++) {
96
  for (uint8_t i = 0; i < SERVO_NUM_CHANNELS; i++) {
97
        servoSet_rev(i, servo[i].rev);
97
        servoSet_rev(i, servo[i].rev);
98
        servoSet_min(i, servo[i].min);
98
        servoSet_min(i, servo[i].min);
99
        servoSet_max(i, servo[i].max);
99
        servoSet_max(i, servo[i].max);
100
        servoSet_mid(i, servo[i].mid);
100
        servoSet_mid(i, servo[i].mid);
101
  }
101
  }
102
  // Vorberechnung von ServoChannels[channel].duty
102
  // Vorberechnung von ServoChannels[channel].duty
103
  servoSetDefaultPos(); // Ausgangsstellung beider Servos
103
  servoSetDefaultPos(); // Ausgangsstellung beider Servos
104
  coldstart = 1;
104
  coldstart = 1;
105
  USART_Init_Baudrate();
105
  USART_Init_Baudrate();
106
  USART_RX_Mode(tracking);
106
  USART_RX_Mode(tracking);
107
}
107
}
108
 
108
 
109
void servoSetDefaultPos(void)
109
void servoSetDefaultPos(void)
110
{
110
{
111
  servoSetPosition(SERVO_PAN, ServoSteps()/2);  // Ausgangsstellung SERVO_PAN
111
  servoSetPosition(SERVO_PAN, ServoSteps()/2);  // Ausgangsstellung SERVO_PAN
112
  servoSetPosition(SERVO_TILT, 0);                              // Ausgangsstellung SERVO_TILT
112
  servoSetPosition(SERVO_TILT, 0);                              // Ausgangsstellung SERVO_TILT
113
}
113
}
114
 
114
 
115
void USART_Init_Baudrate(void)
115
void USART_Init_Baudrate(void)
116
{
116
{
117
  if (tracking == TRACKING_MKCOCKPIT)
117
  if (tracking == TRACKING_MKCOCKPIT)
118
    USART_Init(baud[baudrate]);
118
    USART_Init(baud[baudrate]);
119
  else
119
  else
120
    USART_Init(baud[6]);        //57600
120
    USART_Init(baud[6]);        //57600
121
}
121
}
122
 
122
 
123
/************************************************************************************/
123
/************************************************************************************/
124
/*  setzt Flag für 3,3V oder 5V DOGM                                                                                            */
124
/*  setzt Flag für 3,3V oder 5V DOGM                                                                                            */
125
/*      Parameter:                                                                                                                                              */
125
/*      Parameter:                                                                                                                                              */
126
/*  uint8_t dogm        :Version                                                                                                                */
126
/*  uint8_t dogm        :Version                                                                                                                */
127
/*                                                                                                                                                                      */
127
/*                                                                                                                                                                      */
128
/************************************************************************************/
128
/************************************************************************************/
129
void Set_DOGM_Version(void)
129
void Set_DOGM_Version(void)
130
{
130
{
131
  if(dogm_vers == DOGM5V) {
131
  if(dogm_vers == DOGM5V) {
132
    dogm_vers = DOGM3V;
132
    dogm_vers = DOGM3V;
133
        contrast = CONTRAST3V;
133
        contrast = CONTRAST3V;
134
  }
134
  }
135
  else {
135
  else {
136
    dogm_vers = DOGM5V;
136
    dogm_vers = DOGM5V;
137
        contrast = CONTRAST5V;
137
        contrast = CONTRAST5V;
138
  }
138
  }
139
  eeprom_write_byte(&ep_dogm_vers, dogm_vers);
139
  eeprom_write_byte(&ep_dogm_vers, dogm_vers);
140
  eeprom_write_byte(&ep_contrast, contrast);
140
  eeprom_write_byte(&ep_contrast, contrast);
141
}
141
}
142
 
142
 
143
/************************************************************************************/
143
/************************************************************************************/
144
/*  setzt den RX-Kanal von 1 bis 7                                                                                                      */
144
/*  setzt den RX-Kanal von 1 bis 7                                                                                                      */
145
/*      Parameter:                                                                                                                                              */
145
/*      Parameter:                                                                                                                                              */
146
/*  uint8_t channel     :Kanal                                                                                                                  */
146
/*  uint8_t channel     :Kanal                                                                                                                  */
147
/*                                                                                                                                                                      */
147
/*                                                                                                                                                                      */
148
/************************************************************************************/
148
/************************************************************************************/
149
void Set_Channel(uint8_t channel)
149
void Set_Channel(uint8_t channel)
150
{ uint8_t tmp;
150
{ uint8_t tmp;
151
 
151
 
152
  channel--;
152
  channel--;
153
  tmp = channel & 0b00000111;   // Kanal 1 bis 7 Werte 0 bis 6 setzen
153
  tmp = channel & 0b00000111;   // Kanal 1 bis 7 Werte 0 bis 6 setzen
154
  PORTA |= tmp;
154
  PORTA |= tmp;
155
  PORTB |= tmp;
155
  PORTB |= tmp;
156
  tmp = channel | 0b11111000;
156
  tmp = channel | 0b11111000;
157
  PORTA &= tmp;
157
  PORTA &= tmp;
158
  PORTB &= tmp;  
158
  PORTB &= tmp;  
159
}
159
}
160
 
160
 
161
/************************************************************************************/
161
/************************************************************************************/
162
/*  schaltet den MUX auf AV1 oder AV2 ohne Darstellung und en-/disabled Interrupt       */
162
/*  schaltet den MUX auf AV1 oder AV2 ohne Darstellung und en-/disabled Interrupt       */
163
/*  wird nur in main.c (Initialisierung) und Menü Sourceumschaltung eingesetzt          */
163
/*  wird nur in main.c (Initialisierung) und Menü Sourceumschaltung eingesetzt          */
164
/*  deswegen cli() und sei() nur in Menu_AV_Source(void)                                                        */
164
/*  deswegen cli() und sei() nur in Menu_AV_Source(void)                                                        */
165
/*  Parameter:                                                                                                                                          */
165
/*  Parameter:                                                                                                                                          */
166
/*  uint8_t src :0-AV1, 1-AV2                                                                                                           */
166
/*  uint8_t src :0-AV1, 1-AV2                                                                                                           */
167
/*                                                                                                                                                                      */
167
/*                                                                                                                                                                      */
168
/************************************************************************************/
168
/************************************************************************************/
169
void SetMux0(void) {
169
void SetMux0(void) {
170
  SET_MUX_0;
170
  SET_MUX_0;
171
  mux_X = 0;    // für Erkennung RX Zeitzähler
171
  mux_X = 0;    // für Erkennung RX Zeitzähler
172
}
172
}
173
 
173
 
174
void SetMux1(void) {
174
void SetMux1(void) {
175
  SET_MUX_1;
175
  SET_MUX_1;
176
  mux_X = 1;    // für Erkennung RX Zeitzähler
176
  mux_X = 1;    // für Erkennung RX Zeitzähler
177
}
177
}
178
 
178
 
179
uint8_t Set_AV_Source(uint8_t src)
179
uint8_t Set_AV_Source(uint8_t src)
180
{
180
{
181
  switch(src) {
181
  switch(src) {
182
    case AV1:           CLEAR_INT10;    // Interrupt für Sync ausschalten
182
    case AV1:           CLEAR_INT10;    // Interrupt für Sync ausschalten
183
                                        SetMux0();
183
                                        SetMux0();
184
                                        break;
184
                                        break;
185
    case AV2:           CLEAR_INT10;    // Interrupt für Sync ausschalten
185
    case AV2:           CLEAR_INT10;    // Interrupt für Sync ausschalten
186
                                        SetMux1();
186
                                        SetMux1();
187
                                        break;
187
                                        break;
188
    case DIVERSITY: SET_INT10;          // External Interrupt Mask Register ein
188
    case DIVERSITY: SET_INT10;          // External Interrupt Mask Register ein
189
                                        SetMux0();
189
                                        SetMux0();
190
                                        break;
190
                                        break;
191
  }
191
  }
192
  return(src);
192
  return(src);
193
}
193
}
194
 
194
 
195
 
195
 
196
/**************************************************************/
196
/**************************************************************/
197
/*                                                                                                                        */
197
/*                                                                                                                        */
198
/*                     LCD-Backlight                                              */
198
/*                     LCD-Backlight                                              */
199
/*                                                                                                                        */
199
/*                                                                                                                        */
200
/**************************************************************/
200
/**************************************************************/
201
 
201
 
202
void lcdSet_BackgrLight_Off(void)
202
void lcdSet_BackgrLight_Off(void)
203
{
203
{
204
  backgr_light = OFF;
204
  backgr_light = OFF;
205
  lcdBacklightOff();
205
  lcdBacklightOff();
206
}
206
}
207
 
207
 
208
void lcd_BackgrLight_On(void)
208
void lcd_BackgrLight_On(void)
209
{ // ...&& (light_count < light_time)) ==> sonst wird Beleuchtung laufend wieder eingeschaltet
209
{ // ...&& (light_count < light_time)) ==> sonst wird Beleuchtung laufend wieder eingeschaltet
210
  if ((backgr_light == OFF) && (light_time > BACKGR_LIGHT_MIN) && (light_count < light_time)) {
210
  if ((backgr_light == OFF) && (light_time > BACKGR_LIGHT_MIN) && (light_count < light_time)) {
211
    cli();
211
    cli();
212
        light_count = 0;
212
        light_count = 0;
213
        sei();
213
        sei();
214
        backgr_light = ON;
214
        backgr_light = ON;
215
        lcdBacklightOn();
215
        lcdBacklightOn();
216
  }
216
  }
217
}
217
}
218
 
218
 
219
void lcd_BackgrLight(void)
219
void lcd_BackgrLight(void)
220
{
220
{
221
  if (backgr_light == ON) {                                     // nur wenn Beleuchtung an
221
  if (backgr_light == ON) {                                     // nur wenn Beleuchtung an
222
    if (light_time == BACKGR_LIGHT_MIN)         // Hintergrundbeleuchtung immer aus?
222
    if (light_time == BACKGR_LIGHT_MIN)         // Hintergrundbeleuchtung immer aus?
223
      lcdSet_BackgrLight_Off();
223
      lcdSet_BackgrLight_Off();
224
        else
224
        else
225
          if (light_time < BACKGR_LIGHT_MAX) {  // Hintergrundbeleuchtung immer an?
225
          if (light_time < BACKGR_LIGHT_MAX) {  // Hintergrundbeleuchtung immer an?
226
            cli();
226
            cli();
227
                light_count++;
227
                light_count++;
228
                sei();
228
                sei();
229
                if (light_count >= light_time) lcdSet_BackgrLight_Off();
229
                if (light_count >= light_time) lcdSet_BackgrLight_Off();
230
          }
230
          }
231
  }
231
  }
232
}
232
}
233
 
233
 
234
/**************************************************************/
234
/**************************************************************/
235
/*                                                                                                                        */
235
/*                                                                                                                        */
236
/*                           ADC                                                      */
236
/*                           ADC                                                      */
237
/*                                                                                                                        */
237
/*                                                                                                                        */
238
/*      http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial  */
238
/*      http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial  */
239
/*                                                                                                                        */
239
/*                                                                                                                        */
240
/**************************************************************/
240
/**************************************************************/
241
 
241
 
242
void ADC_Init(void)
242
void ADC_Init(void)
243
{
243
{
244
  uint16_t result;
244
  uint16_t result;
245
 
245
 
246
  ADMUX = (0<<REFS1) | (1<<REFS0);              // AVcc als Referenz benutzen, da an AREF 4,8 V
246
  ADMUX = (0<<REFS1) | (1<<REFS0);              // AVcc als Referenz benutzen, da an AREF 4,8 V
247
  ADCSRA = (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);        // Frequenzvorteiler Prescaler 128
247
  ADCSRA = (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);        // Frequenzvorteiler Prescaler 128
248
  ADCSRA |= (1<<ADEN);                                  // ADC aktivieren
248
  ADCSRA |= (1<<ADEN);                                  // ADC aktivieren
249
 
249
 
250
  /* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest
250
  /* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest
251
     also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" */
251
     also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" */
252
 
252
 
253
  ADCSRA |= (1<<ADSC);                                  // eine ADC-Wandlung 
253
  ADCSRA |= (1<<ADSC);                                  // eine ADC-Wandlung 
254
  while (ADCSRA & (1<<ADSC) ) {}                // auf Abschluss der Konvertierung warten
254
  while (ADCSRA & (1<<ADSC) ) {}                // auf Abschluss der Konvertierung warten
255
  /* ADCW muss einmal gelesen werden, sonst wird Ergebnis der nächsten
255
  /* ADCW muss einmal gelesen werden, sonst wird Ergebnis der nächsten
256
     Wandlung nicht übernommen. */
256
     Wandlung nicht übernommen. */
257
  result = ADCW;
257
  result = ADCW;
258
}
258
}
259
 
259
 
260
/* ADC Einzelmessung */
260
/* ADC Einzelmessung */
261
uint16_t ADC_Read( uint8_t channel )
261
uint16_t ADC_Read( uint8_t channel )
262
{
262
{
263
  // Kanal waehlen, ohne andere Bits zu beeinflußen
263
  // Kanal waehlen, ohne andere Bits zu beeinflußen
264
  ADMUX = (ADMUX & ~(0x1F)) | (channel & 0x1F);
264
  ADMUX = (ADMUX & ~(0x1F)) | (channel & 0x1F);
265
  ADCSRA |= (1<<ADSC);                          // eine Wandlung "single conversion"
265
  ADCSRA |= (1<<ADSC);                          // eine Wandlung "single conversion"
266
  while (ADCSRA & (1<<ADSC) ) {}                // auf Abschluss der Konvertierung warten
266
  while (ADCSRA & (1<<ADSC) ) {}                // auf Abschluss der Konvertierung warten
267
  return ADCW;                                  // ADC auslesen und zurückgeben
267
  return ADCW;                                  // ADC auslesen und zurückgeben
268
}
268
}
269
 
269
 
270
/* ADC Mehrfachmessung mit Mittelwertbbildung */
270
/* ADC Mehrfachmessung mit Mittelwertbbildung */
271
uint16_t ADC_Read_Avg( uint8_t channel, uint16_t average )
271
uint16_t ADC_Read_Avg( uint8_t channel, uint16_t average )
272
{
272
{
273
  uint32_t result = 0;
273
  uint32_t result = 0;
274
 
274
 
275
  for (uint16_t i = 0; i < average; ++i ){
275
  for (uint16_t i = 0; i < average; ++i ){
276
    result += ADC_Read( channel );
276
    result += ADC_Read( channel );
277
        _delay_ms(1);
277
        _delay_ms(1);
278
  }
278
  }
279
  return (uint16_t)( result / average );
279
  return (uint16_t)( result / average );
280
}
280
}
281
 
281
 
282
 
282
 
283
/**************************************************************/
283
/**************************************************************/
284
/*                                                                                                                        */
284
/*                                                                                                                        */
285
/*                         Beeper                                                         */
285
/*                         Beeper                                                         */
286
/*                                                                                                                        */
286
/*                                                                                                                        */
287
/**************************************************************/
287
/**************************************************************/
288
 
288
 
289
void Beep(uint8_t time)
289
void Beep(uint8_t time)
290
{
290
{
291
  PORTB |= (1<<BEEPER);
291
  PORTB |= (1<<BEEPER);
292
//  PINB &= ~(1<<BEEPER);
-
 
293
  _delay_ms(time);
292
  _delay_ms(time);
294
//  PINB |= (1<<BEEPER);
-
 
295
  PORTB &= ~(1<<BEEPER);
293
  PORTB &= ~(1<<BEEPER);
296
}
294
}
297
 
295
 
298
void Double_Beep(uint8_t time, uint8_t pause)
296
void Double_Beep(uint8_t time, uint8_t pause)
299
{
297
{
300
        Beep(time);
298
        Beep(time);
301
        _delay_ms(pause);
299
        _delay_ms(pause);
302
        Beep(time);
300
        Beep(time);
303
}
301
}
304
 
302
 
305
/**************************************************************/
303
/**************************************************************/
306
/*                                                                                                                        */
304
/*                                                                                                                        */
307
/*                        U-Batterie                                              */
305
/*                        U-Batterie                                              */
308
/*                                                                                                                        */
306
/*                                                                                                                        */
309
/**************************************************************/
307
/**************************************************************/
310
 
308
 
311
/* Funktion zur Umwandlung einer vorzeichenbehafteten Integer
309
/* Funktion zur Umwandlung einer vorzeichenbehafteten Integer
312
   32-Bit "Festkomma-Zahl"(gedachtes Komma in Integer) in einen String
310
   32-Bit "Festkomma-Zahl"(gedachtes Komma in Integer) in einen String
313
   vereinfacht Variablenübergabe funktion change_value(uint32_t x),
311
   vereinfacht Variablenübergabe funktion change_value(uint32_t x),
314
   kein printf, double oder float
312
   kein printf, double oder float
315
   siehe http://www.mikrocontroller.net/articles/Festkommaarithmetik
313
   siehe http://www.mikrocontroller.net/articles/Festkommaarithmetik
316
   Vorz ==> 0 kein '-' trotz negativer Zahl, 1 wenn kein '-' bleibt Stelle leer
314
   Vorz ==> 0 kein '-' trotz negativer Zahl, 1 wenn kein '-' bleibt Stelle leer
317
   len max 11, Vorzeichen wird nicht mitgezählt aber Komma; Vorz 0 oder 1
315
   len max 11, Vorzeichen wird nicht mitgezählt aber Komma; Vorz 0 oder 1
318
   Festkomma ==> Position der Kommastelle bei Integerwert
316
   Festkomma ==> Position der Kommastelle bei Integerwert
319
   Nachkomma ==> angezeigte Nachkommastellen bei Festkomma
317
   Nachkomma ==> angezeigte Nachkommastellen bei Festkomma
320
   
318
   
321
   makefile derzeit somit auch ohne! Minimalistic printf version
319
   makefile derzeit somit auch ohne! Minimalistic printf version
322
   Achtung: keine Fehlerprüfung! */
320
   Achtung: keine Fehlerprüfung! */
323
 
321
 
324
char* my_itoa(int32_t zahl, uint8_t Vorz, uint8_t len, uint8_t Festkomma, uint8_t Nachkomma)
322
char* my_itoa(int32_t zahl, uint8_t Vorz, uint8_t len, uint8_t Festkomma, uint8_t Nachkomma)
325
{
323
{
326
  int8_t i;
324
  int8_t i;
327
  uint8_t neg = 0;
325
  uint8_t neg = 0;
328
  char Komma;                                   // Sprachversion Deutsch ',' andere '.'
326
  char Komma;                                   // Sprachversion Deutsch ',' andere '.'
329
  static char str[13];
327
  static char str[13];
330
 
328
 
331
  Komma = Msg(MSG_KOMMA)[0];    // [0] nur als Char, sonst wäre es ein String
329
  Komma = Msg(MSG_KOMMA)[0];    // [0] nur als Char, sonst wäre es ein String
332
  if( zahl < 0 ) {                              // ist die Zahl negativ?
330
  if( zahl < 0 ) {                              // ist die Zahl negativ?
333
    zahl = -zahl;
331
    zahl = -zahl;
334
    neg = 1;
332
    neg = 1;
335
  }
333
  }
336
  if (Vorz) str[0] = '0'; else len--;
334
  if (Vorz) str[0] = '0'; else len--;
337
  str[len+1]='\0';                              // String Terminator
335
  str[len+1]='\0';                              // String Terminator
338
  if (Nachkomma > 0) Nachkomma++;
336
  if (Nachkomma > 0) Nachkomma++;
339
 
337
 
340
  for(i=len; i>=Vorz; i--) {
338
  for(i=len; i>=Vorz; i--) {
341
    if ((len - Festkomma == i) && (Festkomma > 0))
339
    if ((len - Festkomma == i) && (Festkomma > 0))
342
                str[i]= Komma;                  // bei Bedarf Komma einfügen
340
                str[i]= Komma;                  // bei Bedarf Komma einfügen
343
        else {                                          // Integer-Dezimalumrechnung
341
        else {                                          // Integer-Dezimalumrechnung
344
          str[i]=(zahl % 10) +'0';      // Modulo rechnen, dann den ASCII-Code von '0' addieren
342
          str[i]=(zahl % 10) +'0';      // Modulo rechnen, dann den ASCII-Code von '0' addieren
345
      zahl /= 10;
343
      zahl /= 10;
346
        }
344
        }
347
        // festgelegt Festkomma aber verkleinern der Anzeige Mantisse
345
        // festgelegt Festkomma aber verkleinern der Anzeige Mantisse
348
        if ((Festkomma > 0) && (Festkomma >= Nachkomma) && (len - Festkomma + Nachkomma == i)) str[i]= '\0';
346
        if ((Festkomma > 0) && (Festkomma >= Nachkomma) && (len - Festkomma + Nachkomma == i)) str[i]= '\0';
349
  }
347
  }
350
  i=0;
348
  i=0;
351
  while  ((str[i+1] != Komma) && (i < len))  {
349
  while  ((str[i+1] != Komma) && (i < len))  {
352
        // Vorzeichen unmittelbar vor Zahl schreiben
350
        // Vorzeichen unmittelbar vor Zahl schreiben
353
        if((Vorz) && (neg) && ((str[i+1] != '0') || (str[i+2] == Komma))) str[i] = '-';
351
        if((Vorz) && (neg) && ((str[i+1] != '0') || (str[i+2] == Komma))) str[i] = '-';
354
    // eine 0 vor Komma lassen
352
    // eine 0 vor Komma lassen
355
        if(str[i] == '0') str[i++] = ' '; else break; // Vornullen entfernen
353
        if(str[i] == '0') str[i++] = ' '; else break; // Vornullen entfernen
356
  }
354
  }
357
  return(str);
355
  return(str);
358
}
356
}
359
 
357
 
360
// uint32_t u, da bei Displ_Fnct[fu_index](val) der größte Wert UBat gleich 32 Bit 
358
// uint32_t u, da bei Displ_Fnct[fu_index](val) der größte Wert UBat gleich 32 Bit 
361
void Displ_1Nk(uint32_t u)
359
void Displ_1Nk(uint32_t u)
362
{
360
{
363
  // 0 kein Vorzeichen, 5 => 2 Ziffern vor Komma + 1 Komma + 2 Mantisse, Festkomma, eine Ziffer Nachkomma darstellen
361
  // 0 kein Vorzeichen, 5 => 2 Ziffern vor Komma + 1 Komma + 2 Mantisse, Festkomma, eine Ziffer Nachkomma darstellen
364
  lcdPuts(my_itoa(u,0,5,2,1));
362
  lcdPuts(my_itoa(u,0,5,2,1));
365
}
363
}
366
 
364
 
367
void Displ_U_2Nk(uint32_t u)
365
void Displ_U_2Nk(uint32_t u)
368
{
366
{
369
  lcdPuts(my_itoa(u,0,5,2,2));
367
  lcdPuts(my_itoa(u,0,5,2,2));
370
  lcdPutc('V');
368
  lcdPutc('V');
371
}
369
}
372
 
370
 
373
// uint8_t beep_timer :Akku-leer-Beeper nur mit Task_0_1()-Intervalle bei Menü-Rücksprung
371
// uint8_t beep_timer :Akku-leer-Beeper nur mit Task_0_1()-Intervalle bei Menü-Rücksprung
374
uint32_t U_Messen_cmp(uint8_t beep_timer)
372
uint32_t U_Messen_cmp(uint8_t beep_timer)
375
{ uint32_t ubat;
373
{ uint32_t ubat;
376
  static struct
374
  static struct
377
  { uint8_t time;
375
  { uint8_t time;
378
        uint8_t count;
376
        uint8_t count;
379
  } beep_low;
377
  } beep_low;
380
 
378
 
381
/*       ubat = ((ADC_Read(VBAT) * Vref * (R104 + R103)) /(1024 * R103)) + UD10 (UD10 ist Offset)
379
/*       ubat = ((ADC_Read(VBAT) * Vref * (R104 + R103)) /(1024 * R103)) + UD10 (UD10 ist Offset)
382
         Verhältniswert * 100 *8192 ( Verhältniswert = realer Korrekturwert;
380
         Verhältniswert * 100 *8192 ( Verhältniswert = realer Korrekturwert;
383
         mal 100 da alle Werte 2 Nachkommastellen berücksichtigt, aber ohne gerechnet wird
381
         mal 100 da alle Werte 2 Nachkommastellen berücksichtigt, aber ohne gerechnet wird
384
         mal 8192 => ohne Bruch gerechnet aber dabei mehr Kommastellen berücksichtigt) */
382
         mal 8192 => ohne Bruch gerechnet aber dabei mehr Kommastellen berücksichtigt) */
385
  ubat = (ADC_Read(VBAT) * (uint64_t)43504 + (uint64_t)u_offset * 8192)/ 8192;
383
  ubat = (ADC_Read(VBAT) * (uint64_t)43504 + (uint64_t)u_offset * 8192)/ 8192;
386
  if ( ubat <= hyst_u_min )
384
  if ( ubat <= hyst_u_min )
387
  {
385
  {
388
    if (bat_low != 0) {         // nicht laufend Display neu schreiben
386
    if (bat_low != 0) {         // nicht laufend Display neu schreiben
389
          hyst_u_min = u_min + 20;      // 200mV Hysterese - beruhigt Anzeige
387
          hyst_u_min = u_min + 20;      // 200mV Hysterese - beruhigt Anzeige
390
          lcdClear();
388
          lcdClear();
391
          lcdPuts(Msg(MSG_ACCU_LOW));
389
          lcdPuts(Msg(MSG_ACCU_LOW));
392
          bat_low = 0;
390
          bat_low = 0;
393
          Beep(BEEPBAT);
391
          Beep(BEEPBAT);
394
          // da derzeit Fkt. aller 500ms aufgerufen, mit 2 Min Abstand beginnen
392
          // da derzeit Fkt. aller 500ms aufgerufen, mit 2 Min Abstand beginnen
395
          beep_low.time = BEEP_LOW_TIME;
393
          beep_low.time = BEEP_LOW_TIME;
396
          beep_low.count = 0;
394
          beep_low.count = 0;
397
        }
395
        }
398
        // Akku leer, in immer kürzeren Intervallen Beep
396
        // Akku leer, in immer kürzeren Intervallen Beep
399
        if ((beep_timer == 1) && (beep_low.count++ >= beep_low.time)){
397
        if ((beep_timer == 1) && (beep_low.count++ >= beep_low.time)){
400
          Beep(BEEPBAT);
398
          Beep(BEEPBAT);
401
          if (beep_low.time > 2)
399
          if (beep_low.time > 2)
402
            beep_low.time /= 2;
400
            beep_low.time /= 2;
403
          beep_low.count = 0;
401
          beep_low.count = 0;
404
        }
402
        }
405
  }
403
  }
406
  else {
404
  else {
407
    if (hyst_u_min > u_min) {   // falls Anzeige von Batterie leer
405
    if (hyst_u_min > u_min) {   // falls Anzeige von Batterie leer
408
          bat_low = 1;                          // und zurück geschaltet wird,
406
          bat_low = 1;                          // und zurück geschaltet wird,
409
          hyst_u_min = u_min;           // dann Main_Disp wieder darstellen
407
          hyst_u_min = u_min;           // dann Main_Disp wieder darstellen
410
          Displ_Main_Disp();
408
          Displ_Main_Disp();
411
        }
409
        }
412
  }
410
  }
413
  return(ubat);
411
  return(ubat);
414
}
412
}
415
 
413
 
416
void Displ_VBat(void) // da u_offset globale Variable
414
void Displ_VBat(void) // da u_offset globale Variable
417
{ uint32_t ubat;
415
{ uint32_t ubat;
418
 
416
 
419
  ubat = U_Messen_cmp(ENABLE_BTIMER);
417
  ubat = U_Messen_cmp(ENABLE_BTIMER);
420
  if (bat_low != 0) { // würde sonst Anzeige Akku leer überschreiben
418
  if (bat_low != 0) { // würde sonst Anzeige Akku leer überschreiben
421
    lcdGotoXY(11, 0);
419
    lcdGotoXY(11, 0);
422
    Displ_1Nk(ubat);
420
    Displ_1Nk(ubat);
423
  }
421
  }
424
}
422
}
425
 
423
 
426
 
424
 
427
/**************************************************************/
425
/**************************************************************/
428
/*                                                                                                                        */
426
/*                                                                                                                        */
429
/*                          RSSI                                                          */
427
/*                          RSSI                                                          */
430
/*                                                                                                                        */
428
/*                                                                                                                        */
431
/**************************************************************/
429
/**************************************************************/
432
 
430
 
433
/* RSSI Werte Korrekturfaktor berechnen */
431
/* RSSI Werte Korrekturfaktor berechnen */
434
uint16_t  RSSI_Calc_Korr(uint16_t u0, uint16_t u1)
432
uint16_t  RSSI_Calc_Korr(uint16_t u0, uint16_t u1)
435
{ uint16_t u_max;
433
{ uint16_t u_max;
436
 
434
 
437
  // immer nur den kleineren Wert vergrößern
435
  // immer nur den kleineren Wert vergrößern
438
  if (u0 < u1) {
436
  if (u0 < u1) {
439
    udbm_korr_1 = (((uint32_t)u1 * UDBM_KORR_FA) / u0)+0.5; // nur mit Integer und 2 Nachkommastellen rechnen
437
    udbm_korr_1 = (((uint32_t)u1 * UDBM_KORR_FA) / u0)+0.5; // nur mit Integer und 2 Nachkommastellen rechnen
440
        udbm_korr_2 = UDBM_KORR_FA;
438
        udbm_korr_2 = UDBM_KORR_FA;
441
        u_max = u1;
439
        u_max = u1;
442
  }
440
  }
443
  else {
441
  else {
444
    udbm_korr_2 = (((uint32_t)u0 * UDBM_KORR_FA) / u1)+0.5; // nur mit Integer und 2 Nachkommastellen rechnen
442
    udbm_korr_2 = (((uint32_t)u0 * UDBM_KORR_FA) / u1)+0.5; // nur mit Integer und 2 Nachkommastellen rechnen
445
    udbm_korr_1 = UDBM_KORR_FA;
443
    udbm_korr_1 = UDBM_KORR_FA;
446
        u_max = u0;
444
        u_max = u0;
447
  }
445
  }
448
  eeprom_write_word(&ep_udbm_korr_1, udbm_korr_1);
446
  eeprom_write_word(&ep_udbm_korr_1, udbm_korr_1);
449
  eeprom_write_word(&ep_udbm_korr_2, udbm_korr_2);
447
  eeprom_write_word(&ep_udbm_korr_2, udbm_korr_2);
450
  return(u_max);
448
  return(u_max);
451
}
449
}
452
 
450
 
453
void Displ_Calibr_Aktiv(void)
451
void Displ_Calibr_Aktiv(void)
454
{
452
{
455
  lcdClear();
453
  lcdClear();
456
  Displ_Str_mid(Msg(MSG_CALIBRATION),0);
454
  Displ_Str_mid(Msg(MSG_CALIBRATION),0);
457
  Displ_Str_mid(Msg(MSG_RUNNING),1);
455
  Displ_Str_mid(Msg(MSG_RUNNING),1);
458
}
456
}
459
 
457
 
460
void Displ_Error_TX(uint8_t message)
458
void Displ_Error_TX(uint8_t message)
461
{
459
{
462
  lcdClear();
460
  lcdClear();
463
  Displ_Str_mid(Msg(MSG_ERROR),0);
461
  Displ_Str_mid(Msg(MSG_ERROR),0);
464
  Displ_Str_mid(Msg(MSG_TX_NOT),1);
462
  Displ_Str_mid(Msg(MSG_TX_NOT),1);
465
  Displ_Str_mid(Msg(message), 2);
463
  Displ_Str_mid(Msg(message), 2);
466
  for ( uint8_t i=0; i<=30;i++)
464
  for ( uint8_t i=0; i<=30;i++)
467
    _delay_ms(100);
465
    _delay_ms(100);
468
}
466
}
469
 
467
 
470
void RSSI_Min_Calibrate(uint16_t *pudbm)
468
void RSSI_Min_Calibrate(uint16_t *pudbm)
471
{ uint16_t u0, u1;
469
{ uint16_t u0, u1;
472
 
470
 
473
  Displ_Calibr_Aktiv();
471
  Displ_Calibr_Aktiv();
474
  u0 = ADC_Read_Avg(RSSI0, 1000);               //1000 Wiederholungen mit
472
  u0 = ADC_Read_Avg(RSSI0, 1000);               //1000 Wiederholungen mit
475
  u1 = ADC_Read_Avg(RSSI1, 1000);               //Mittelwertbildung
473
  u1 = ADC_Read_Avg(RSSI1, 1000);               //Mittelwertbildung
476
  // Plausibilitätsprüfung ob Sender ausgeschaltet
474
  // Plausibilitätsprüfung ob Sender ausgeschaltet
477
  if (u0 + u1 > 500) {
475
  if (u0 + u1 > 500) {
478
    udbm_min = RSSI_Calc_Korr(u0, u1); // ist real die größere Spannung, aber der kleinere dbm Wert
476
    udbm_min = RSSI_Calc_Korr(u0, u1); // ist real die größere Spannung, aber der kleinere dbm Wert
479
    eeprom_write_word(&ep_udbm_min, udbm_min);
477
    eeprom_write_word(&ep_udbm_min, udbm_min);
480
        Double_Beep(DBEEPWR, DBEEPWRP);
478
        Double_Beep(DBEEPWR, DBEEPWRP);
481
        wudbm = RSSI_Calc_UdBm(pudbm);
479
        wudbm = RSSI_Calc_UdBm(pudbm);
482
  }
480
  }
483
  else Displ_Error_TX(MSG_TX_OFF);
481
  else Displ_Error_TX(MSG_TX_OFF);
484
}
482
}
485
 
483
 
486
void RSSI_Max_Calibrate(uint16_t *pudbm)
484
void RSSI_Max_Calibrate(uint16_t *pudbm)
487
{ uint16_t u0, u1;
485
{ uint16_t u0, u1;
488
 
486
 
489
  Displ_Calibr_Aktiv();
487
  Displ_Calibr_Aktiv();
490
  u0 = ADC_Read_Avg(RSSI0, 1000);       //1000 Wiederholungen mit
488
  u0 = ADC_Read_Avg(RSSI0, 1000);       //1000 Wiederholungen mit
491
  u1 = ADC_Read_Avg(RSSI1, 1000);       //Mittelwertbildung
489
  u1 = ADC_Read_Avg(RSSI1, 1000);       //Mittelwertbildung
492
  // Plausibilitätsprüfung ob Sender in der Nähe eingeschaltet
490
  // Plausibilitätsprüfung ob Sender in der Nähe eingeschaltet
493
  if (u0 + u1 < 400) {
491
  if (u0 + u1 < 400) {
494
    udbm_max = RSSI_Calc_Korr(u0, u1); // ist real die kleinere Spannung, aber der größere dbm Wert
492
    udbm_max = RSSI_Calc_Korr(u0, u1); // ist real die kleinere Spannung, aber der größere dbm Wert
495
    eeprom_write_word(&ep_udbm_max, udbm_max);
493
    eeprom_write_word(&ep_udbm_max, udbm_max);
496
        Double_Beep(DBEEPWR, DBEEPWRP);
494
        Double_Beep(DBEEPWR, DBEEPWRP);
497
    wudbm = RSSI_Calc_UdBm(pudbm);
495
    wudbm = RSSI_Calc_UdBm(pudbm);
498
  }
496
  }
499
  else Displ_Error_TX(MSG_TX_ON);
497
  else Displ_Error_TX(MSG_TX_ON);
500
}
498
}
501
 
499
 
502
// Vergleichstabelle für RSSI-Bargraph berechnen, vermeidet laufend gleiche Berechnung
500
// Vergleichstabelle für RSSI-Bargraph berechnen, vermeidet laufend gleiche Berechnung
503
uint8_t RSSI_Calc_UdBm(uint16_t *pudbm)
501
uint8_t RSSI_Calc_UdBm(uint16_t *pudbm)
504
{ uint8_t n;
502
{ uint8_t n;
505
  // -15 um Ende dBm Skala sicher zu erreichen; ohne verfeinerten Bahrgraph war Wert -3
503
  // -15 um Ende dBm Skala sicher zu erreichen; ohne verfeinerten Bahrgraph war Wert -3
506
  n = (udbm_min - udbm_max -15)/11;
504
  n = (udbm_min - udbm_max -15)/11;
507
  for (uint8_t i = 0; i < 12; i++)
505
  for (uint8_t i = 0; i < 12; i++)
508
    pudbm[i] = (udbm_min - i * n);
506
    pudbm[i] = (udbm_min - i * n);
509
  return(n / 5); // da 5 Pixel Breite pro Display-Zeichen; Anzeigebalken pro Pixel differenzieren
507
  return(n / 5); // da 5 Pixel Breite pro Display-Zeichen; Anzeigebalken pro Pixel differenzieren
510
}
508
}
511
 
509
 
512
void Displ_RSSI_Bargraph(uint16_t *pudbm, uint8_t wudbm, uint16_t uadc)
510
void Displ_RSSI_Bargraph(uint16_t *pudbm, uint8_t wudbm, uint16_t uadc)
513
{ char strBar[12];
511
{ char strBar[12];
514
  uint8_t i;
512
  uint8_t i;
515
  int8_t lz = 11;
513
  int8_t lz = 11;
516
  char b = 4;
514
  char b = 4;
517
 
515
 
518
  // Balken zeichnen - udbm
516
  // Balken zeichnen - udbm
519
  for (i = 0; i < 12; i++) {
517
  for (i = 0; i < 12; i++) {
520
        if ((b != ' ') && (uadc > pudbm[i])) {
518
        if ((b != ' ') && (uadc > pudbm[i])) {
521
          b  = ' ';
519
          b  = ' ';
522
          lz = i - 1;
520
          lz = i - 1;
523
        }
521
        }
524
    strBar[i] = b;
522
    strBar[i] = b;
525
  }
523
  }
526
  if (lz >= 0) {
524
  if (lz >= 0) {
527
        strBar[lz] = (pudbm[lz] - uadc) / wudbm ;// Anzeigebalken pro Pixel-"Breite" differenzieren
525
        strBar[lz] = (pudbm[lz] - uadc) / wudbm ;// Anzeigebalken pro Pixel-"Breite" differenzieren
528
        // bei Teilung 4 wäre richtig und keine Korr. erforderlich, so aber gleichmäßigerer Balkenverlauf
526
        // bei Teilung 4 wäre richtig und keine Korr. erforderlich, so aber gleichmäßigerer Balkenverlauf
529
    if (strBar[lz] > 4) strBar[lz] = 4;
527
    if (strBar[lz] > 4) strBar[lz] = 4;
530
  }
528
  }
531
  for (i = 0; i < 12; i++)// lcdPuts (ist auch for) funktioniert hier nicht, da Char'\0' für Zeichen auch Stringende
529
  for (i = 0; i < 12; i++)// lcdPuts (ist auch for) funktioniert hier nicht, da Char'\0' für Zeichen auch Stringende
532
    lcdPutc(strBar[i]);
530
    lcdPutc(strBar[i]);
533
}
531
}
534
 
532
 
535
uint8_t RSSI_Diversity(uint8_t src, uint16_t *pudbm, uint8_t visible)
533
uint8_t RSSI_Diversity(uint8_t src, uint16_t *pudbm, uint8_t visible)
536
{ uint16_t u0, u1;
534
{ uint16_t u0, u1;
537
  static uint8_t div_flag, ret_div_flag;
535
  static uint8_t div_flag, ret_div_flag;
538
  char marker;
536
  char marker;
539
 
537
 
540
  u0 = (ADC_Read(RSSI0) * (uint32_t)udbm_korr_1)/UDBM_KORR_FA;
538
  u0 = (ADC_Read(RSSI0) * (uint32_t)udbm_korr_1)/UDBM_KORR_FA;
541
  u1 = (ADC_Read(RSSI1) * (uint32_t)udbm_korr_2)/UDBM_KORR_FA;
539
  u1 = (ADC_Read(RSSI1) * (uint32_t)udbm_korr_2)/UDBM_KORR_FA;
542
 
540
 
543
  // falls beide RX gleich gut/schlecht synchronisieren
541
  // falls beide RX gleich gut/schlecht synchronisieren
544
  // Achtung! Niedrigere Spannung - größere Feldstärke
542
  // Achtung! Niedrigere Spannung - größere Feldstärke
545
  if (src == DIVERSITY) {
543
  if (src == DIVERSITY) {
546
    if (u0 < u1) {
544
    if (u0 < u1) {
547
          ret_div_flag = AV1;
545
          ret_div_flag = AV1;
548
          if ((vscount0 == 255) && (vscount1 == 255)) SetMux0();
546
          if ((vscount0 == 255) && (vscount1 == 255)) SetMux0();
549
    }
547
    }
550
    else {
548
    else {
551
          ret_div_flag = AV2;
549
          ret_div_flag = AV2;
552
          if ((vscount0 == 255) && (vscount1 == 255)) SetMux1();
550
          if ((vscount0 == 255) && (vscount1 == 255)) SetMux1();
553
    }
551
    }
554
  }
552
  }
555
  else ret_div_flag = src; // sonst leerer Returnwert
553
  else ret_div_flag = src; // sonst leerer Returnwert
556
   
554
   
557
  if (visible) {
555
  if (visible) {
558
    if (src == DIVERSITY) {
556
    if (src == DIVERSITY) {
559
          // Synchronisation vorrangig zur Feldstärke
557
          // Synchronisation vorrangig zur Feldstärke
560
      if ((vsync0 != vsync1) && ((vscount0 & vscount1) < 255)) {
558
      if ((vsync0 != vsync1) && ((vscount0 & vscount1) < 255)) {
561
            // ist nur zur Anzeige - Sync-MUX wird über Interrupt gesteuert
559
            // ist nur zur Anzeige - Sync-MUX wird über Interrupt gesteuert
562
        if (vsync0 == 0) {
560
        if (vsync0 == 0) {
563
              div_flag = AV1;
561
              div_flag = AV1;
564
            }
562
            }
565
            else {
563
            else {
566
              div_flag = AV2;
564
              div_flag = AV2;
567
            }
565
            }
568
            marker = MARKER_SYNC;
566
            marker = MARKER_SYNC;
569
      }
567
      }
570
          else {
568
          else {
571
            div_flag = ret_div_flag;
569
            div_flag = ret_div_flag;
572
                marker = MARKER_RSSI;
570
                marker = MARKER_RSSI;
573
          }
571
          }
574
    }
572
    }
575
    else marker = MARKER_AV;
573
    else marker = MARKER_AV;
576
        // wäre unschön - keine RSSI-Anzeige, aber Marker springt
574
        // wäre unschön - keine RSSI-Anzeige, aber Marker springt
577
        if ((u0 > pudbm[0]) && (u1 > pudbm[0])) marker = ' ';
575
        if ((u0 > pudbm[0]) && (u1 > pudbm[0])) marker = ' ';
578
        lcdGotoXY(2, 1);
576
        lcdGotoXY(2, 1);
579
    Displ_RSSI_Bargraph(pudbm, wudbm, u0);
577
    Displ_RSSI_Bargraph(pudbm, wudbm, u0);
580
    lcdGotoXY(2, 2);
578
    lcdGotoXY(2, 2);
581
        Displ_RSSI_Bargraph(pudbm, wudbm, u1);
579
        Displ_RSSI_Bargraph(pudbm, wudbm, u1);
582
        if (src == DIVERSITY) Displ_AV_Mark(div_flag, marker);
580
        if (src == DIVERSITY) Displ_AV_Mark(div_flag, marker);
583
  }
581
  }
584
  return(ret_div_flag);
582
  return(ret_div_flag);
585
}
583
}
586
 
584
 
587
/**************************************************************/
585
/**************************************************************/
588
/*                                                                                                                        */
586
/*                                                                                                                        */
589
/*      Diversity v-Synchronisation Interruptroutinen             */
587
/*      Diversity v-Synchronisation Interruptroutinen             */
590
/*                                                                                                                        */
588
/*                                                                                                                        */
591
/**************************************************************/
589
/**************************************************************/
592
 
590
 
593
/* Impulszähler für V-Synchronisation 0 und 1
591
/* Impulszähler für V-Synchronisation 0 und 1
594
   wird durch Interrupt des jewiligen vSync einzeln zurückgesetzt */
592
   wird durch Interrupt des jewiligen vSync einzeln zurückgesetzt */
595
ISR(TIMER2_OVF_vect)
593
ISR(TIMER2_OVF_vect)
596
{
594
{
597
  TCNT2 = (int8_t)(int16_t)-(F_CPU / 64 * 500e-6);  // preload
595
  TCNT2 = (int8_t)(int16_t)-(F_CPU / 64 * 500e-6);  // preload
598
  if (vscount0 < 255) ++vscount0; // Überlauf von vscount vermeiden
596
  if (vscount0 < 255) ++vscount0; // Überlauf von vscount vermeiden
599
  if (vscount1 < 255) ++vscount1; // Überlauf von vscount vermeiden
597
  if (vscount1 < 255) ++vscount1; // Überlauf von vscount vermeiden
600
  if (rx_timeout < RX_TIME_OLD) ++rx_timeout; // veranlasst bei GPS-Tracking MK Datensatz senden
598
  if (rx_timeout < RX_TIME_OLD) ++rx_timeout; // veranlasst bei GPS-Tracking MK Datensatz senden
601
  if ((tracking == TRACKING_GPS) && (MK_Motor_run)) { // MK-Motoren müssen laufen
599
  if ((tracking == TRACKING_GPS) && (MK_Motor_run)) { // MK-Motoren müssen laufen
602
    if (mux_X)
600
    if (mux_X)
603
          rxcount1++;   // kein Test auf Überlauf ==> Counter groß genug - bis Stunden
601
          rxcount1++;   // kein Test auf Überlauf ==> Counter groß genug - bis Stunden
604
        else
602
        else
605
          rxcount0++;
603
          rxcount0++;
606
  }
604
  }
607
}
605
}
608
 
606
 
609
/* Messung von Impulsabstand v-Synchronisation 0
607
/* Messung von Impulsabstand v-Synchronisation 0
610
   Zur Vermeidung von Bildstörunen erfolgt MUX-Umschaltung in Bildaustastung */
608
   Zur Vermeidung von Bildstörunen erfolgt MUX-Umschaltung in Bildaustastung */
611
ISR(INT0_vect)
609
ISR(INT0_vect)
612
{
610
{
613
  if ((vscount0 >= 79) && (vscount0 <= 81))
611
  if ((vscount0 >= 79) && (vscount0 <= 81))
614
    vsync0 = 0;
612
    vsync0 = 0;
615
  else {
613
  else {
616
    vsync0 = 1;
614
    vsync0 = 1;
617
        if (vsync1 == 0)
615
        if (vsync1 == 0)
618
          SetMux1();
616
          SetMux1();
619
  }
617
  }
620
  if (vsync0 == vsync1) { //nur wenn vSynchronisation gleich gut/schlecht ist greift RSSI 
618
  if (vsync0 == vsync1) { //nur wenn vSynchronisation gleich gut/schlecht ist greift RSSI 
621
    if (sw_avx == AV1) {
619
    if (sw_avx == AV1) {
622
          SetMux0();
620
          SetMux0();
623
        }
621
        }
624
        else
622
        else
625
          SetMux1();
623
          SetMux1();
626
  }
624
  }
627
  vscount0 = 0;
625
  vscount0 = 0;
628
}
626
}
629
 
627
 
630
/* Messung von Impulsabstand v-Synchronisation 1
628
/* Messung von Impulsabstand v-Synchronisation 1
631
   Zur Vermeidung von Bildstörunen erfolgt MUX-Umschaltung in Bildaustastung */
629
   Zur Vermeidung von Bildstörunen erfolgt MUX-Umschaltung in Bildaustastung */
632
ISR(INT1_vect)
630
ISR(INT1_vect)
633
{
631
{
634
 if ((vscount1 >= 79) && (vscount1 <= 81))
632
 if ((vscount1 >= 79) && (vscount1 <= 81))
635
    vsync1 = 0;
633
    vsync1 = 0;
636
  else {
634
  else {
637
    vsync1 = 1;
635
    vsync1 = 1;
638
    if (vsync0 == 0)
636
    if (vsync0 == 0)
639
          SetMux0();
637
          SetMux0();
640
  }
638
  }
641
  if (vsync0 == vsync1) { //nur wenn vSynchronisation gleich gut/schlecht ist greift RSSI
639
  if (vsync0 == vsync1) { //nur wenn vSynchronisation gleich gut/schlecht ist greift RSSI
642
    if (sw_avx == AV1) {
640
    if (sw_avx == AV1) {
643
          SetMux0();
641
          SetMux0();
644
        }
642
        }
645
        else
643
        else
646
          SetMux1();
644
          SetMux1();
647
  }
645
  }
648
  vscount1 = 0;
646
  vscount1 = 0;
649
}
647
}
650
 
648
 
651
/**************************************************************/
649
/**************************************************************/
652
/*                                                                                                                        */
650
/*                                                                                                                        */
653
/*                          Tasks                                                         */
651
/*                          Tasks                                                         */
654
/*        ermöglicht unterschiedliche Zeiten f. UBat, Sync...     */
652
/*        ermöglicht unterschiedliche Zeiten f. UBat, Sync...     */
655
/*                                                                                                                        */
653
/*                                                                                                                        */
656
/**************************************************************/
654
/**************************************************************/
657
 
655
 
658
void Task_0_1(void)
656
void Task_0_1(void)
659
{
657
{
660
  if (task_timer0_1) {
658
  if (task_timer0_1) {
661
    cli();
659
    cli();
662
        task_timer0_1 = 0;
660
        task_timer0_1 = 0;
663
        sei();
661
        sei();
664
    Displ_VBat();
662
    Displ_VBat();
665
   }
663
   }
666
 }
664
 }
667
 
665
 
668
void Task_0_2(void)
666
void Task_0_2(void)
669
{
667
{
670
  if (task_timer0_2) {
668
  if (task_timer0_2) {
671
    cli();
669
    cli();
672
        task_timer0_2 = 0;
670
        task_timer0_2 = 0;
673
        sei();
671
        sei();
674
        sw_avx = RSSI_Diversity(av_source, pudbm, bat_low);
672
        sw_avx = RSSI_Diversity(av_source, pudbm, bat_low);
675
  }
673
  }
676
}
674
}
677
 
675
 
678
void Task_0_3(void)
676
void Task_0_3(void)
679
{
677
{
680
  if (task_timer0_3) {
678
  if (task_timer0_3) {
681
    cli();
679
    cli();
682
        task_timer0_3 = 0;
680
        task_timer0_3 = 0;
683
        sei();
681
        sei();
684
    sw_avx = RSSI_Diversity(av_source, pudbm, 0);
682
    sw_avx = RSSI_Diversity(av_source, pudbm, 0);
685
        if (tracking == TRACKING_MKCOCKPIT) Tracking_MKCockpit();
683
        if (tracking == TRACKING_MKCOCKPIT) Tracking_MKCockpit();
686
  }
684
  }
687
}
685
}
688
 
686
 
689
void Task_0_4(void)
687
void Task_0_4(void)
690
{
688
{
691
  if (task_timer0_4) {
689
  if (task_timer0_4) {
692
    cli();
690
    cli();
693
        task_timer0_4 = 0;
691
        task_timer0_4 = 0;
694
        sei();
692
        sei();
695
    if (tracking == TRACKING_GPS) Tracking_GPS();
693
    if (tracking == TRACKING_GPS) Tracking_GPS();
696
        if (gps_display == GPS_RX_COUNT) Displ_RX_Time(); // aktualisieren der Empfängerzeiten
694
        if (gps_display == GPS_RX_COUNT) Displ_RX_Time(); // aktualisieren der Empfängerzeiten
697
  }
695
  }
698
}
696
}
699
 
697
 
700
void Task_0_5(void)                     // Nur für Tasten-Beschleunigung/-Wiederholrate! Hintergrund: Rücksetzung.
698
void Task_0_5(void)                     // Nur für Tasten-Beschleunigung/-Wiederholrate! Hintergrund: Rücksetzung.
701
{                                                       // Hintergrund: Rücksetzung. Beginnt nach jeden Tastendruck neu zu zählen.
699
{                                                       // Hintergrund: Rücksetzung. Beginnt nach jeden Tastendruck neu zu zählen.
702
  lcd_BackgrLight_On();         // muss bei beliebiger Taste sofort eingeschaltet werden
700
  lcd_BackgrLight_On();         // muss bei beliebiger Taste sofort eingeschaltet werden
703
  if (task_timer0_5) {
701
  if (task_timer0_5) {
704
    cli();
702
    cli();
705
        task_timer0_5 = 0;
703
        task_timer0_5 = 0;
706
        sei();
704
        sei();
707
        lcd_BackgrLight();
705
        lcd_BackgrLight();
708
  }
706
  }
709
}
707
}
710
 
708
 
711
void Tasks_unvisible(void)
709
void Tasks_unvisible(void)
712
{
710
{
713
  Task_0_3();
711
  Task_0_3();
714
  Task_0_4();
712
  Task_0_4();
715
  Task_0_5();
713
  Task_0_5();
716
  if (tracking == TRACKING_RSSI) Tracking_RSSI();
714
  if (tracking == TRACKING_RSSI) Tracking_RSSI();
717
}
715
}