forked from amaximchuk/u-osd
-
Notifications
You must be signed in to change notification settings - Fork 0
/
setup.h
153 lines (135 loc) · 6.57 KB
/
setup.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/*u-osd - A simple open source osd for G-OSD
Copyright (C) 2013 Alex Maximchuk
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef SETUP_H_
#define SETUP_H_
//62 is caused by the voltage divider on the pcb.
//There is a 5.1k and a 1k resistor in the voltage divider.
//Using ohms law we get that Vout = (Z_2 / (Z_1 + Z_2)) * Vin.
//Flipping some numbers (Vout = 5, Z_1 = 5.1k, Z_2 = 1k) we get Vin = 6,1 * Vout.
//Since we don't want floats we use 61 and divide with 10 later. But due to some testing I found that 62 was better. :-)
//temp = ADCW;
//#ifdef ADC_ENABLE_RAW
//gAnalogInputsRaw[i] = temp;
//#endif
//temp = (temp * 5 * 62) / 10;
//temp *= gAnalogMult[i];
//temp /= gAnalogDiv[i];
//adcHigh = temp / 1024;
//temp -= (u16)(adcHigh) * 1024;
//adcLow = (temp * 100) / 1024;
//
//gAnalogInputs[i].low = adcLow;
//gAnalogInputs[i].high = adcHigh;
//
//
//As per Atmel spec for 10 bit conversions:
//
//ADC value = Vin * 1024 / Vref
//
//Vref is set to AVCC (5 Volt IIRC) on setupAdc().
//
//So for the RSSI pin (G-OSD) we can get 0-5V for Vin. The gAnalogDiv[] value for this input is 6 (hardware.h, ADC_DIV definition).
//
//For 1V the ADC value would be 0xCC => 204 which is available in the variable temp.
//
//What the code does is this:
//
//temp = (204 * 5 * 62) / 10 = 6324
//temp = 6324 / 6 = 1054 // 6 comes from gAnalogDiv[i]
//adcHigh = 1054 / 1024 = 1 => 1V for display
//temp = 1054 - 1024 = 30
//adcLow = 30 * 100 / 1024 = 2 => .02V for display
static void setup_adc() {
// ADC setup
DIDR0 = 0x00;
ADMUX |= (1<<REFS0); // Ref is AVCC
ADCSRA |= (1<<ADPS2) | (1<<ADPS1); // | (1<<ADPS0);
ADCSRB = 0; // Free running
}
static void setup_gps() {
// USART setup
UBRR0H = (u8)(GPS_UBRR>>8);// set baud
UBRR0L = (u8)GPS_UBRR;
UCSR0C = (3<<UCSZ00); // 8N1
UCSR0B = (1<<RXEN0); // Enable RX
memset (&g_gps_data, 0,sizeof(g_gps_data));
memset (&g_gps_valid_data, 0,sizeof(g_gps_valid_data));
}
static void setup_layout() {
print_text (&g_text_sign, TEXT_CALL_SIGN, TRUE);
#ifdef DEBUG_TEXT
g_text_dbg_ptr = str_ptr(g_text_dbg.p.y,g_text_dbg.p.x);
#endif // DEBUG_TEXT
}
static void setup_line() {
// Line trigger
EICRA = (1<<ISC00) | (1<<ISC01); //set INT0 as rising edge trigger
EIMSK = (1<<INT0); //enable INT0 in global interrupt mask
ACSR = (1<<ACD); //Comparator disabled
ADCSRB = 0x00;
// SPI setup
// SPDR:
// The SPI Data Register is a read/write register used for data transfer between the Register File and the SPI Shift Register.
// Writing to the register initiates data transmission. Reading the register causes the Shift Register receive buffer to be read.
// Finally, here is a code snippet to generate a data transfer between a Master and a Slave.
SPDR = 0x00; // Clear SPI reg or thrash will show on video
// SPSR:
// SPI2x (Double SPI Speed) bit: This feature is not implemented in all AVRs (check the particular data sheet).
// When this bit is set to one, the SPI speed will be doubled when the SPI is in Master mode.
// SPIF (SPI Interrupt Flag) bit: This is a read only bit. It is set by hardware when a serial transfer is complete.
// SPIF is cleared by hardware when the SPI interrupt handling vector is executed, or when the SPIF bit and the SPDR register are read.
//#ifdef TEXT_SMALL_ENABLED
// SPSR |= (1<<SPI2X); // Set dual speed
//#else
SPSR &= ~(1<<SPI2X); // Clear dual speed
//#endif //TEXT_SMALL_ENABLED
// SPCR:
// Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
// SPIE SPE DORD MSTR CPOL CPHA SPR1 SPR0
// SPIE (SPI Interrupt Enable) bit: Set SPIE to one if you want the SPI interrupt to be executed when a serial transfer is completed.
// SPE (SPI Enable) bit: If you want to use the SPI, you must set this bit.
// DORD (Data Order) bit: You can choose in which order the data will be transmitted. Set DORD to one to send the least significant bit (LSB) first. Set DORD to zero to send the most significant bit (MSB) first.
// MSTR (Master/Slave Select) bit: Set MSTR to configure the AVR as a Master SPI device. Clear MSTR to configure it as a Slave.
// CPOL (Clock Polarity) and CPHA (Clock Phase) bits: As stated previously, Master and Slave must agree on how to interpret the clock signal. The first thing to do is to configure which logic level the clock will be in when the SPI is idle. If CPOL is set to one, SCK is high when idle, and if CPOL is set to zero, SCK is low when idle. The second thing is to configure during which clock transition the data will be sampled. Set CPHA to sample the data on the trailing (last) edge, and clear CPHA to sample the data in the leading (first) edge.
// So, there are four different ways of configuring the clock generation, which are known as 'SPI modes'. The following table summarizes the four SPI modes.
// SPI Mode CPOL CPHA Sample
// 0 0 0 Leading (Rising) Edge
// 1 0 1 Trailing (Falling) Edge
// 2 1 0 Leading (Falling) Edge
// 3 1 1 Trailing (Rising) Edge
// SPR1 and SPR2 (SPI Clock Rate Select) bits: The SPR bits configure the frequency of the clock signal. Since the Slave reads the clock from an input pin, the SPR bits have no effect on the Slave. The frequency of the SPI clock is related to the frequency of the AVR oscillator. The faster the SPI clock signal is, the faster the data trasfer will be, however, you must respect the maximum clock frequency specified by the Slave (as usual, read the datasheet). The following table summarizes the relationship between the SCK frequency and the SPR bits:
// SPR1 SPR0 SCK frequency
// 0 0 fosc/4
// 0 1 fosc/16
// 1 0 fosc/64
// 1 1 fosc/128
SPCR = (1<<SPE) | (1<<MSTR) | (1<<CPHA);
}
static void setup(void)
{
// Port setup
PORTD = KEY; // key pullup & led off
DDRD = LED; // led output
BIT_CLEAR(PORTB, BLACK_OUT);
DDRB = WHITE_MASK | SS_MASK;
TIMSK1 |= (1 << TOIE1);// Enable overflow interrupt
TCCR1B |= (1 << CS11); // Start timer at Fcpu/8
setup_line ();
setup_layout();
setup_adc ();
setup_gps ();
sei ();
}
#endif /* SETUP_H_ */