source: firmware/FSC/src/application.c@ 12679

Last change on this file since 12679 was 10910, checked in by neise, 13 years ago
File size: 8.4 KB
Line 
1//-----------------------------------------------------------------------------
2
3#include "application.h"
4#include "usart.h"
5#include <avr/wdt.h>
6
7// in order to implement the "registers" I work with a quite long
8// char-array like this:
9
10U08 FSCregister[FSC_REGISTER_LENGTH];
11// but this register is not only accessible by
12// FSCregister[i], but as well by special pointers like this:
13U32 *status = (U32*)&FSCregister[0];
14U32 *time_sec = (U32*)&(FSCregister[4]);
15U16 *time_ms = (U16*)&(FSCregister[6]);
16U16 *FR_period = (U16*)&(FSCregister[8]);
17U16 *ref_resistor = (U16*)&(FSCregister[10]);
18
19
20U32 *ad7719_values = (U32*)&FSCregister[68];
21U08 *ad7719_enables = &FSCregister[30];
22U08 *ad7719_channels_ready = &FSCregister[49];
23U08 *ad7719_readings_since_last_muxing = &FSCregister[14];
24U08 *ad7719_current_channel = &FSCregister[15];
25U32 *ad7719_current_reading = (U32*)&FSCregister[16];
26
27U16 *adc_values = (U16*) &FSCregister[324];
28U08 *adc_enables = &FSCregister[38];
29U08 *adc_channels_ready = &FSCregister[57];
30U08 *adc_readings_since_last_muxing = &FSCregister[20];
31U08 *adc_current_channel = &FSCregister[21];
32U16 *adc_current_reading = (U16*) &FSCregister[22];
33
34// using these pointers one can manipulate measurement values like this:
35// res_value[3] = 453212;
36// and then readout the most significant byte of this same value by accessing:
37// FSCregister[92];
38// I like this very much for asking the boards status ... this is just a copy of the registers,
39// into the W5100 TX FIFO.
40// submitting the measurement values is just a partial copy...
41
42//-----------------------------------------------------------------------------
43
44//-----------------------------------------------------------------------------
45
46volatile U08 app_reset_source;
47//-----------------------------------------------------------------------------
48
49void app_init(void) {
50 app_reset_source = MCUSR; // Save last reset source
51 MCUSR = 0x00; // Clear reset source for next reset cycle
52
53
54 // Dangerous here: I still do not know much about the watchdog.
55 // This code is still from Udo Juerss.
56
57 // The watchdog timer is disabled by default ("startup.asm")
58 #ifdef USE_WATCHDOG
59 WDTCSR = WDTOE | (1 << WDE); // Enable watchdog reset (~16ms)
60 #endif
61
62 // define PORTS
63 // USART
64 DDRD &= ~(1<<PD0); // PD0 = RXD is input
65 DDRD |= 1<<PD1; // PD1 = TXD is output
66
67
68 // SPARE OUT/-INPUTS
69 DDRB |= (1<<PB2) | (1<<PB3); // set Out1_spare & out2_spare as outputs
70 DDRA &= ~(1<<PA7); // set In1_spare as input
71 DDRC &= ~(1<<PC7); // set In2_spare as input
72 //PORTA |= (1<<PA7); // swtich on pullup on In1_spare
73 //PORTC |= (1<<PC7); // swtich on pullup on In2_spare
74
75 // ATmega internal ADC input
76 DDRA &= ~(1<<PA6);
77
78 // MUXER ADDRESS OUTs
79 DDRA |= 0x3F; // SA-pins -> output
80 DDRC |= 0x7F; // SB-pins -> output
81
82 // SPI
83 // set all CS's: output
84 DDRB |= (1 << SPI_E_CS);
85 DDRD |= (1 << SPI_AD_CS) |(1 << SPI_M_CS) |(1 << SPI_A_CS);
86
87 // set all Chips selects HIGH
88 PORTB |= (1 << SPI_E_CS);
89 PORTD |= (1 << SPI_AD_CS) |(1 << SPI_M_CS) |(1 << SPI_A_CS);
90
91 // set MOSI and SCK: output & // set MISO: input
92 SPI_DDR |= (1 << SPI_MOSI);
93 SPI_DDR |= (1 << SPI_SCLK);
94 SPI_DDR &= ~(1 << SPI_MISO);
95
96 // set MOSI, SCK: HIGH. MISO leave alone.
97 SPI_PRT |= (1 << SPI_MOSI);
98 SPI_PRT |= (1 << SPI_SCLK);
99 //SPI_PRT |= (1 << SPI_MISO);
100
101 // ADC
102 DDRD &= ~(1<<PD6); // PD6 is AD_READY input
103 DDRD |= 1<<PD7; // PD7 is AD_RESET output
104
105 // ACCELEROMETER
106 DDRD &= ~(1<<PD2); // PD2 is ACC_READY input
107
108 //MAX6662 <--- not assembled
109 // DDRB &= ~(1<<PB0); // PB0 is over temperature alert input
110 // DDRB &= ~(1<<PB1); // PB1 is general temperature altert input
111}
112
113
114
115//-----------------------------------------------------------------------------
116
117void app_set_watchdog_prescaler(tWDT_PRESCALE wdt_prescale) // Set watchdog prescale
118{
119 U08 sreg_backup = SREG; // Copy status register to variable
120 U08 wdtcsr_value = WDE + wdt_prescale; // Set new prescale value to variable
121
122 cli(); // Disable interrups
123 wdt_reset(); // Reset watchdog
124
125 WDTCR |= (1 << WDTOE) | (1 << WDE); // Unlock register access, 4 cycles to store new value
126 WDTCR = wdtcsr_value; // Set new watchdog prescaler
127 SREG = sreg_backup; // Restore status register
128}
129
130void set_ad7719_enable_register() {
131
132 usart_write_str((pU08)"\n set enable bits of AD7719 Port ");
133 if ((usart_received_chars>=5) &&
134 (usart_rx_buffer[2] >= 'A' && usart_rx_buffer[2] <= 'H'))
135 {
136 usart_write_char(usart_rx_buffer[2]);
137 usart_write_str((pU08)" to ");
138 usart_write_U08_hex(usart_rx_buffer[4]);
139 usart_write_char('\n');
140 ad7719_enables[usart_rx_buffer[2]-'A']=usart_rx_buffer[4];
141 ad7719_channels_ready[usart_rx_buffer[2]-'A']=0x00;
142 }
143 else if ((usart_received_chars=3) &&
144 (usart_rx_buffer[1] >= 'A' && usart_rx_buffer[1] <= 'H'))
145 {
146 usart_write_char(usart_rx_buffer[1]);
147 if (usart_rx_buffer[2]!='0') {
148 usart_write_str((pU08)" to 0xFF\n");
149 ad7719_enables[usart_rx_buffer[1]-'A']=0xFF;
150 } else
151 {
152 usart_write_str((pU08)" to 0x00\n");
153 ad7719_enables[usart_rx_buffer[1]-'A']=0x00;
154 }
155 ad7719_channels_ready[usart_rx_buffer[1]-'A']=0x00;
156 }
157 else
158 {
159 usart_write_str((pU08)"\n something wrong\n");
160 usart_write_str((pU08)"usart_rx_buffer_index: ");
161 usart_write_U08(usart_received_chars, 3);
162 usart_write_str((pU08)"\n usart_rx_buffer[2]: ");
163 usart_write_char(usart_rx_buffer[2]);
164 usart_write_str((pU08)"\n usart_rx_buffer[4]: ");
165 usart_write_U08_hex(usart_rx_buffer[4]);
166 usart_write_char('\n');
167 }
168}
169
170void set_adc_enable_register() {
171 // TODO
172 usart_write_str((pU08)"setting of ATmega internal ADC enable registers is not supported. yet.\n");
173}
174
175U08 increase_adc (U08 channel){
176U08 effective_channel;
177 for ( U08 increase = 1 ; increase <= VOLTAGE_CHANNELS; increase++)
178 {
179 effective_channel = (channel + increase) % (VOLTAGE_CHANNELS);
180 if (adc_enables[effective_channel/8] & (1<<effective_channel%8)) {
181 if (debug_mode)
182 {
183 usart_write_U08(effective_channel,3);
184 usart_write_crlf();
185 }
186 return effective_channel;
187 }
188 }
189 if (debug_mode)
190 {
191 usart_write_U08(channel,3);
192 usart_write_crlf();
193 }
194 return channel;
195} // end if increase_adc;
196
197U08 increase_ad7719 (U08 channel){
198U08 effective_channel;
199 for ( U08 increase = 1 ; increase <= RESISTANCE_CHANNELS; increase++)
200 {
201 effective_channel = (channel + increase) % (RESISTANCE_CHANNELS);
202 if (ad7719_enables[effective_channel/8] & (1<<effective_channel%8))
203 return effective_channel;
204 }
205 return channel;
206} // end if increase_adc;
207
208void check_if_measured_all() {
209 adc_measured_all = true;
210 for ( U08 i=0; i<(VOLTAGE_REGS); ++i ) {
211 if ((adc_enables[i] ^ adc_channels_ready[i]) != 0x00) {
212 adc_measured_all = false;
213 break;
214 }
215 }
216 ad7719_measured_all = true;
217 for ( U08 i=0; i<(RESISTANCE_CHANNELS/8); ++i ) {
218 if ((ad7719_enables[i] ^ ad7719_channels_ready[i]) != 0x00) {
219 ad7719_measured_all = false;
220 break;
221 }
222 }
223
224
225}
226
227// an U08 array containts bitmaps, which encode, which channel is enabled and which is not.
228// a measurement is done, when all (or more) enabled channels were already measured.
229// a similar U08 array contains a bitmap, encoding which channels are already done.
230// note: "or more" above is important, if we check to strictly,
231// we will never finish, in case a disabled channel get measured by any mistake...
232//
233// lets assume:
234// enabled = 1110.0011 1110.0011
235// done = 1111.0011 0111.0010
236//
237// and = 1110.0011 0110.0010
238// nand = 0001.0011 1001.1101
239// or = 1111.0011 1111.0011
240// xor = 0001.0000 1001.0001
241//
242//
243// (en xor done) and enabled =
244// xor = 0001.0000 1001.0001
245// enabled = 1110.0011 1110.0011
246// --------- ---------
247// 0000.0000 1000.0001
248// if this statement evaluates to zero,
249bool check_if_adc_measurement_done(){
250 adc_measured_all = true;
251 for ( U08 i=0; i<VOLTAGE_REGS; ++i ) {
252 if (( (adc_enables[i] ^ adc_channels_ready[i]) & adc_enables[i] ) != 0x00) {
253 adc_measured_all = false;
254 break;
255 }
256 }
257 return adc_measured_all;
258}
259
260bool check_if_ad7719_measurement_done(){
261 ad7719_measured_all = true;
262 for ( U08 i=0; i<RESISTANCE_CHANNELS/8; ++i ) {
263 if (( (ad7719_enables[i] ^ ad7719_channels_ready[i]) & ad7719_enables[i]) != 0x00) {
264 ad7719_measured_all = false;
265 break;
266 }
267 }
268 return ad7719_measured_all;
269}
Note: See TracBrowser for help on using the repository browser.