source: firmware/FSC/src/application.c

Last change on this file was 17629, checked in by dneise, 11 years ago
a lot of changes for the new firmware version. Mostly the global registers were changed
File size: 7.9 KB
Line 
1#include "application.h"
2#include "w5100_spi_interface.h"
3#include <avr/wdt.h>
4
5// ---------------- These are the global variables that represent the registers
6// of the entire FSC, everything is stored here and can thus be sent down ----
7FSCRegisterType gReg;
8volatile VolatileRegisterType gVolReg;
9
10
11
12
13void app_init(void) {
14 gVolReg.app_reset_source = MCUSR; // Save last reset source
15 MCUSR = 0x00; // Clear reset source for next reset cycle
16
17 // Dangerous here: I still do not know much about the watchdog.
18 // This code is still from Udo Juerss.
19 // The watchdog timer is disabled by default ("startup.asm")
20 #ifdef USE_WATCHDOG
21 WDTCSR = WDTOE | (1 << WDE); // Enable watchdog reset (~16ms)
22 #endif
23
24 // define PORTS
25 // USART
26 DDRD &= ~(1<<PD0); // PD0 = RXD is input
27 DDRD |= 1<<PD1; // PD1 = TXD is output
28
29 // SPARE OUT/-INPUTS
30 DDRB |= (1<<PB2); // set Out1_spare as output
31 DDRB |= (1<<PB3); // set Out2_spare as output
32 DDRA &= ~(1<<PA7); // set In1_spare as input
33 DDRC &= ~(1<<PC7); // set In2_spare as input
34 //PORTA |= (1<<PA7); // swtich on pullup on In1_spare
35 //PORTC |= (1<<PC7); // swtich on pullup on In2_spare
36
37 // ATmega internal ADC input
38 DDRA &= ~(1<<PA6);
39
40 // MUXER ADDRESS OUTs
41 DDRA |= 0x3F; // SA-pins -> output
42 DDRC |= 0x7F; // SB-pins -> output
43
44 // SPI
45 // set all CS's: output
46 DDRB |= (1 << SPI_E_CS);
47 DDRD |= (1 << SPI_AD_CS);
48 DDRD |= (1 << SPI_M_CS);
49 DDRD |= (1 << SPI_A_CS);
50
51 // set all Chips selects HIGH
52 PORTB |= (1 << SPI_E_CS);
53 PORTD |= (1 << SPI_AD_CS);
54 PORTD |= (1 << SPI_M_CS);
55 PORTD |= (1 << SPI_A_CS);
56
57 // set MOSI and SCK: output & // set MISO: input
58 SPI_DDR |= (1 << SPI_MOSI);
59 SPI_DDR |= (1 << SPI_SCLK);
60 SPI_DDR &= ~(1 << SPI_MISO);
61
62 // set MOSI, SCK: HIGH. MISO leave alone.
63 SPI_PRT |= (1 << SPI_MOSI);
64 SPI_PRT |= (1 << SPI_SCLK);
65 //SPI_PRT |= (1 << SPI_MISO);
66
67 // ADC
68 DDRD &= ~(1<<PD6); // PD6 is AD_READY input
69 DDRD |= 1<<PD7; // PD7 is AD_RESET output
70
71 // ACCELEROMETER
72 DDRD &= ~(1<<PD2); // PD2 is ACC_READY input
73
74 //MAX6662 <--- not assembled
75 // DDRB &= ~(1<<PB0); // PB0 is over temperature alert input
76 // DDRB &= ~(1<<PB1); // PB1 is general temperature altert input
77}
78
79// Set watchdog prescale
80void app_set_watchdog_prescaler(tWDT_PRESCALE wdt_prescale) {
81
82 U08 sreg_backup = SREG; // Copy status register to variable
83 U08 wdtcsr_value = WDE + wdt_prescale; // Set new prescale value to variable
84
85 cli(); // Disable interrups
86 wdt_reset(); // Reset watchdog
87
88 WDTCR |= (1 << WDTOE) | (1 << WDE); // Unlock register access, 4 cycles to store new value
89 WDTCR = wdtcsr_value; // Set new watchdog prescaler
90 SREG = sreg_backup; // Restore status register
91}
92
93
94//U08* en = gReg.adc_enables;
95//U08 size = VOLTAGE_CHANNELS;
96U08 increase (U08 channel, U08* enables_ptr, U08 size){
97 for ( U08 increase = 1 ; increase <= size; increase++) {
98 U08 effective_channel = (channel + increase) % size;
99 if (enables_ptr[effective_channel/8] & (1<<effective_channel%8)) {
100 return effective_channel;
101 }
102 }
103 return channel;
104}
105U08 increase_ad7719 (U08 channel) {
106 return increase( channel, gReg.ad7719_enables, RESISTANCE_CHANNELS);
107}
108U08 increase_adc (U08 channel) {
109 return increase( channel, gReg.adc_enables, VOLTAGE_CHANNELS);
110}
111
112
113/* Explaination of bit banging:
114 * an U08 array containts bitmaps, which encode, which channel is enabled and which is not.
115 * a measurement is done, when all (or more) enabled channels were already measured.
116 * a similar U08 array contains a bitmap, encoding which channels are already done.
117 * note: "or more" above is important, if we check to strictly,
118 * we will never finish, in case a disabled channel get measured by any mistake...
119 *
120 * lets assume:
121 * enabled = 1110.0011 1110.0011
122 * done = 1111.0011 0111.0010
123 *
124 * and = 1110.0011 0110.0010
125 * nand = 0001.0011 1001.1101
126 * or = 1111.0011 1111.0011
127 * xor = 0001.0000 1001.0001
128 *
129 * (en xor done) and enabled =
130 * xor = 0001.0000 1001.0001
131 * enabled = 1110.0011 1110.0011
132 * --------- ---------
133 * 0000.0000 1000.0001
134 * if this statement evaluates to zero,
135 *
136 *
137 * size = VOLTAGE_REGS | RESISTANCE_REGS
138 * en = gReg.adc_enables | gReg.ad7719_enables
139 * dry = gReg.adc_channels_ready | gReg.ad7719_channels_ready
140 */
141bool check_if_measurement_done(U08* en, U08*rdy, U08 size) {
142 U08 temp = true;
143 for ( U08 i=0; i<size; ++i ) {
144 if (((en[i]^rdy[i])&en[i]) != 0x00) {
145 temp = false;
146 break;
147 }
148 }
149 return temp;
150}
151bool check_if_adc_measurement_done() { // operates on global gReg
152 return gReg.adc_measured_all = check_if_measurement_done(
153 gReg.adc_enables,
154 gReg.adc_channels_ready,
155 VOLTAGE_REGS);
156}
157bool check_if_ad7719_measurement_done() { // operates on global gReg
158 return gReg.ad7719_measured_all = check_if_measurement_done(
159 gReg.ad7719_enables,
160 gReg.ad7719_channels_ready,
161 RESISTANCE_REGS);
162}
163bool check_if_measured_all() { // operates on global gReg
164 return check_if_adc_measurement_done() && check_if_ad7719_measurement_done();
165}
166
167void reset_voltage_done(){ // operates on global gReg
168 for (U08 i=0; i < (VOLTAGE_REGS); i++){
169 gReg.adc_channels_ready[i] = 0;
170 }
171}
172void reset_voltage_values(){ // operates on global gReg
173 for (U08 i=0; i < VOLTAGE_CHANNELS; i++){
174 gReg.adc_values[i] = 0;
175 }
176}
177void reset_resistance_done(){ // operates on global gReg
178 for (U08 i=0; i < (RESISTANCE_REGS); i++){
179 gReg.ad7719_channels_ready[i] = 0;
180 }
181}
182void reset_resistance_values(){ // operates on global gReg
183 for (U08 i=0; i < RESISTANCE_CHANNELS; i++){
184 gReg.ad7719_values[i] = 0;
185 }
186}
187void reset_done(){
188 reset_resistance_done();
189 reset_voltage_done();
190}
191
192
193void write_status_via_eth() {
194 gReg.ad7719_values_checksum = fletcher16( (U08*)gReg.ad7719_values, RESISTANCE_CHANNELS * sizeof(U32) );
195 gReg.adc_values_checksum = fletcher16( (U08*)gReg.adc_values, VOLTAGE_CHANNELS * sizeof(U16) );
196
197 U16 bytes_to_be_sent = sizeof(gReg);
198 U16 bytes_already_sent = 0;
199 U16 bytes_really_sent_away = 0;
200 while (bytes_to_be_sent){
201 bytes_really_sent_away = w5100_set_TX( (U08*)&gReg+bytes_already_sent, bytes_to_be_sent);
202 bytes_to_be_sent -= bytes_really_sent_away;
203 bytes_already_sent += bytes_really_sent_away;
204 }
205 bytes_to_be_sent = sizeof(gVolReg);
206 bytes_already_sent = 0;
207 bytes_really_sent_away = 0;
208 while (bytes_to_be_sent){
209 bytes_really_sent_away = w5100_set_TX( (U08*)&gVolReg+bytes_already_sent, bytes_to_be_sent);
210 bytes_to_be_sent -= bytes_really_sent_away;
211 bytes_already_sent += bytes_really_sent_away;
212 }
213}
214
215
216U16 fletcher16( U08 const *data, U16 bytes ) {
217 U16 sum1 = 0xff, sum2 = 0xff;
218
219 while (bytes) {
220 U16 tlen = bytes > 20 ? 20 : bytes;
221 bytes -= tlen;
222 do {
223 sum2 += sum1 += *data++;
224 } while (--tlen);
225 sum1 = (sum1 & 0xff) + (sum1 >> 8);
226 sum2 = (sum2 & 0xff) + (sum2 >> 8);
227 }
228 /* Second reduction step to reduce sums to 8 bits */
229 sum1 = (sum1 & 0xff) + (sum1 >> 8);
230 sum2 = (sum2 & 0xff) + (sum2 >> 8);
231 return sum2 << 8 | sum1;
232}
Note: See TracBrowser for help on using the repository browser.