Rev 902 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 902 | Rev 1437 | ||
---|---|---|---|
1 | /**************************************************************************** |
1 | /**************************************************************************** |
2 | * Copyright (C) 2009-2011 by Claas Anders "CaScAdE" Rathje * |
2 | * Copyright (C) 2009-2012 by Claas Anders "CaScAdE" Rathje * |
3 | * admiralcascade@gmail.com * |
3 | * admiralcascade@gmail.com * |
4 | * Project-URL: http://www.mylifesucks.de/oss/c-strom/ * |
4 | * Project-URL: http://www.mylifesucks.de/oss/c-strom/ * |
5 | * * |
5 | * * |
6 | * This program is free software; you can redistribute it and/or modify * |
6 | * This program is free software; you can redistribute it and/or modify * |
7 | * it under the terms of the GNU General Public License as published by * |
7 | * it under the terms of the GNU General Public License as published by * |
8 | * the Free Software Foundation; either version 2 of the License. * |
8 | * the Free Software Foundation; either version 2 of the License. * |
9 | * * |
9 | * * |
10 | * This program is distributed in the hope that it will be useful, * |
10 | * This program is distributed in the hope that it will be useful, * |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * |
13 | * GNU General Public License for more details. * |
13 | * GNU General Public License for more details. * |
14 | * * |
14 | * * |
15 | * You should have received a copy of the GNU General Public License * |
15 | * You should have received a copy of the GNU General Public License * |
16 | * along with this program; if not, write to the * |
16 | * along with this program; if not, write to the * |
17 | * Free Software Foundation, Inc., * |
17 | * Free Software Foundation, Inc., * |
18 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * |
18 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * |
19 | * * |
19 | * * |
20 | * Thanks to: * |
20 | * Thanks to: * |
21 | * Klaus "akku" Buettner for the hardware * |
21 | * Klaus "akku" Buettner for the hardware * |
22 | * All people at http://www.rn-wissen.de especially for the i2c stuff * |
22 | * All people at http://www.rn-wissen.de especially for the i2c stuff * |
23 | * * |
23 | * * |
24 | ****************************************************************************/ |
24 | ****************************************************************************/ |
25 | 25 | ||
26 | #include <avr/io.h> |
26 | #include <avr/io.h> |
27 | #include <avr/eeprom.h> |
27 | #include <avr/eeprom.h> |
28 | #include <avr/pgmspace.h> |
28 | #include <avr/pgmspace.h> |
29 | #include <avr/interrupt.h> |
29 | #include <avr/interrupt.h> |
30 | #include <util/delay.h> |
30 | #include <util/delay.h> |
31 | #include <stdlib.h> |
31 | #include <stdlib.h> |
32 | #include <string.h> |
32 | #include <string.h> |
33 | #include "C-Strom.h" |
33 | #include "C-Strom.h" |
34 | #include "spi_union.h" |
34 | #include "spi_union.h" |
35 | #include "i2c_slave.h" |
35 | #include "i2c_slave.h" |
36 | 36 | ||
37 | uint8_t EEMEM ee_checkbyte1 = CHECKBYTE1; |
37 | uint8_t EEMEM ee_checkbyte1 = CHECKBYTE1; |
38 | uint8_t EEMEM ee_checkbyte2 = CHECKBYTE2; |
38 | uint8_t EEMEM ee_checkbyte2 = CHECKBYTE2; |
39 | uint16_t EEMEM ee_cal_ampere = 512; |
39 | uint16_t EEMEM ee_cal_ampere = 512; |
40 | uint8_t EEMEM ee_sensor = 50; |
40 | uint8_t EEMEM ee_sensor = 50; |
41 | uint8_t EEMEM ee_prim_r1 = 47, ee_prim_r2 = 150; |
41 | uint8_t EEMEM ee_prim_r1 = 47, ee_prim_r2 = 150; |
42 | uint8_t EEMEM ee_anin_r1 = 47, ee_anin_r2 = 150; |
42 | uint8_t EEMEM ee_anin_r1 = 47, ee_anin_r2 = 150; |
43 | uint8_t EEMEM ee_config = 0; |
43 | uint8_t EEMEM ee_config = 0; |
44 | 44 | ||
45 | volatile uint8_t CSTROM_FLAGS = 0; |
45 | volatile uint8_t CSTROM_FLAGS = 0; |
46 | volatile uint8_t CSTROM_CONFIG = 0; |
46 | volatile uint8_t CSTROM_CONFIG = 0; |
47 | 47 | ||
48 | // we could use ee_cal_ampere but eeprom is slow :) |
48 | // we could use ee_cal_ampere but eeprom is slow :) |
49 | volatile uint16_t cal_ampere = 512; |
49 | volatile uint16_t cal_ampere = 512; |
50 | volatile uint8_t sensor = 50; |
50 | volatile uint8_t sensor = 50; |
51 | volatile uint8_t prim_r1 = 47, prim_r2 = 150; |
51 | volatile uint8_t prim_r1 = 47, prim_r2 = 150; |
52 | volatile uint8_t anin_r1 = 47, anin_r2 = 150; |
52 | volatile uint8_t anin_r1 = 47, anin_r2 = 150; |
53 | volatile int16_t ampere, volt, anin_volt, transfer_ampere; |
53 | volatile int16_t ampere, volt, anin_volt, transfer_ampere; |
54 | volatile int32_t transfer_mah, mah; |
54 | volatile int32_t transfer_mah, mah; |
55 | volatile int16_t average_ampere = 0; |
55 | volatile int16_t average_ampere = 0; |
56 | volatile uint8_t hwver = 10; |
56 | volatile uint8_t hwver = 10; |
57 | // global space for int conversion to string |
57 | // global space for int conversion to string |
58 | char s[10]; |
58 | char s[10]; |
59 | 59 | ||
60 | // spi buffer |
60 | // spi buffer |
61 | union SPI_buffer_t SPI_buffer; |
61 | union SPI_buffer_t SPI_buffer; |
62 | 62 | ||
63 | // PD7 High |
63 | // PD7 High |
64 | void PD7_H() { |
64 | void PD7_H() { |
65 | PORTD |= (1 << PD7); |
65 | PORTD |= (1 << PD7); |
66 | } |
66 | } |
67 | 67 | ||
68 | // PD7 Low |
68 | // PD7 Low |
69 | void PD7_L() { |
69 | void PD7_L() { |
70 | PORTD &= ~(1 << PD7); |
70 | PORTD &= ~(1 << PD7); |
71 | } |
71 | } |
72 | 72 | ||
73 | void (*LED_ON)(void) = PD7_H; |
73 | void (*LED_ON)(void) = PD7_H; |
74 | void (*LED_OFF)(void) = PD7_L; |
74 | void (*LED_OFF)(void) = PD7_L; |
75 | 75 | ||
76 | 76 | ||
77 | void ampere_calibrate(); |
77 | void ampere_calibrate(); |
78 | void save_eeprom(); |
78 | void save_eeprom(); |
79 | void help(uint8_t); |
79 | void help(uint8_t); |
80 | 80 | ||
81 | /*ISR(__vector_default) { |
81 | /*ISR(__vector_default) { |
82 | asm("nop"); |
82 | asm("nop"); |
83 | }*/ |
83 | }*/ |
84 | 84 | ||
85 | /** |
85 | /** |
86 | * decimal itoa for 10th values |
86 | * decimal itoa for 10th values |
87 | */ |
87 | */ |
88 | char *itoa_dec(int val, char* s) { |
88 | char *itoa_dec(int val, char* s) { |
89 | itoa(val, s, 10); |
89 | itoa(val, s, 10); |
90 | //char x = 0; |
90 | //char x = 0; |
91 | for (uint8_t i = 0; i < 9; i++) { |
91 | for (uint8_t i = 0; i < 9; i++) { |
92 | if (s[i] == 0 && i > 0) { |
92 | if (s[i] == 0 && i > 0) { |
93 | if (i == 1) { |
93 | if (i == 1) { |
94 | s[i+1] = s[i-1]; |
94 | s[i+1] = s[i-1]; |
95 | s[i-1] = '0'; |
95 | s[i-1] = '0'; |
96 | s[i] = '.'; |
96 | s[i] = '.'; |
97 | s[i+2] = 0; |
97 | s[i+2] = 0; |
98 | } else { |
98 | } else { |
99 | s[i] = s[i-1]; |
99 | s[i] = s[i-1]; |
100 | s[i-1] = '.'; |
100 | s[i-1] = '.'; |
101 | s[i+1] = 0; |
101 | s[i+1] = 0; |
102 | } |
102 | } |
103 | break; |
103 | break; |
104 | } |
104 | } |
105 | } |
105 | } |
106 | return s; |
106 | return s; |
107 | } |
107 | } |
108 | 108 | ||
109 | /** |
109 | /** |
110 | * init uart |
110 | * init uart |
111 | */ |
111 | */ |
112 | void uart_init() { |
112 | void uart_init() { |
113 | UBRRL = (F_CPU / (16UL * BAUD_RATE)) - 1; |
113 | UBRRL = (F_CPU / (16UL * BAUD_RATE)) - 1; |
114 | 114 | ||
115 | // Enable receiver and transmitter; enable RX interrupt |
115 | // Enable receiver and transmitter; enable RX interrupt |
116 | UCSRB = (1 << RXEN) | (1 << TXEN) | (1 << RXCIE); |
116 | UCSRB = (1 << RXEN) | (1 << TXEN) | (1 << RXCIE); |
117 | 117 | ||
118 | //asynchronous 8N1 |
118 | //asynchronous 8N1 |
119 | UCSRC = (1 << URSEL) | (3 << UCSZ0); |
119 | UCSRC = (1 << URSEL) | (3 << UCSZ0); |
120 | } |
120 | } |
121 | 121 | ||
122 | /** |
122 | /** |
123 | * send a single <character> through uart |
123 | * send a single <character> through uart |
124 | */ |
124 | */ |
125 | void uart_putc(unsigned char character) { |
125 | void uart_putc(unsigned char character) { |
126 | // wait until UDR ready |
126 | // wait until UDR ready |
127 | while (!(UCSRA & (1 << UDRE))); |
127 | while (!(UCSRA & (1 << UDRE))); |
128 | UDR = character; |
128 | UDR = character; |
129 | } |
129 | } |
130 | 130 | ||
131 | /** |
131 | /** |
132 | * send a <string> throught uart |
132 | * send a <string> throught uart |
133 | */ |
133 | */ |
134 | void uart_puts(char *s) { |
134 | void uart_puts(char *s) { |
135 | while (*s) { |
135 | while (*s) { |
136 | uart_putc(*s); |
136 | uart_putc(*s); |
137 | s++; |
137 | s++; |
138 | } |
138 | } |
139 | } |
139 | } |
140 | 140 | ||
141 | /** |
141 | /** |
142 | * send a <string> from pgm space throught uart |
142 | * send a <string> from pgm space throught uart |
143 | */ |
143 | */ |
144 | void uart_puts_pgm(char *string) { |
144 | void uart_puts_pgm(char *string) { |
145 | while (pgm_read_byte(string) != 0x00) |
145 | while (pgm_read_byte(string) != 0x00) |
146 | uart_putc(pgm_read_byte(string++)); |
146 | uart_putc(pgm_read_byte(string++)); |
147 | } |
147 | } |
148 | 148 | ||
149 | /** |
149 | /** |
150 | * change the sensor type |
150 | * change the sensor type |
151 | */ |
151 | */ |
152 | void sensor_change(uint8_t new_value) { |
152 | void sensor_change(uint8_t new_value) { |
153 | if (new_value < 10) new_value = 0; |
153 | if (new_value < 10) new_value = 0; |
154 | else if (new_value > 250) new_value = 250; |
154 | else if (new_value > 250) new_value = 250; |
155 | sensor = new_value; |
155 | sensor = new_value; |
156 | uart_puts_pgm(PSTR("\r\nSensor is now: ")); |
156 | uart_puts_pgm(PSTR("\r\nSensor is now: ")); |
157 | uart_puts(itoa(sensor, s, 10)); |
157 | uart_puts(itoa(sensor, s, 10)); |
158 | uart_puts("A\r\n"); |
158 | uart_puts("A\r\n"); |
159 | } |
159 | } |
160 | 160 | ||
161 | /** |
161 | /** |
162 | * change the r2 value |
162 | * change the r2 value |
163 | */ |
163 | */ |
164 | void r2_change(uint8_t which, uint8_t new_value) { |
164 | void r2_change(uint8_t which, uint8_t new_value) { |
165 | if (which == V_ANIN) { |
165 | if (which == V_ANIN) { |
166 | uart_puts_pgm(PSTR("\r\nANIN R2 is now: ")); |
166 | uart_puts_pgm(PSTR("\r\nANIN R2 is now: ")); |
167 | anin_r2 = new_value; |
167 | anin_r2 = new_value; |
168 | uart_puts(itoa_dec(anin_r2, s)); |
168 | uart_puts(itoa_dec(anin_r2, s)); |
169 | } else { |
169 | } else { |
170 | uart_puts_pgm(PSTR("\r\nPRIMARY R2 is now: ")); |
170 | uart_puts_pgm(PSTR("\r\nPRIMARY R2 is now: ")); |
171 | prim_r2 = new_value; |
171 | prim_r2 = new_value; |
172 | uart_puts(itoa_dec(prim_r2, s)); |
172 | uart_puts(itoa_dec(prim_r2, s)); |
173 | } |
173 | } |
174 | uart_puts_pgm(PSTR("kOhm\r\n")); |
174 | uart_puts_pgm(PSTR("kOhm\r\n")); |
175 | } |
175 | } |
176 | 176 | ||
177 | /** |
177 | /** |
178 | * enable/disable TWI |
178 | * enable/disable TWI |
179 | */ |
179 | */ |
180 | void twi_change() { |
180 | void twi_change() { |
181 | uart_puts_pgm(PSTR("\r\nTWI turned ")); |
181 | uart_puts_pgm(PSTR("\r\nTWI turned ")); |
182 | if (CSTROM_CONFIG & CSTROM_TWI) { |
182 | if (CSTROM_CONFIG & CSTROM_TWI) { |
183 | uart_puts_pgm(PSTR("ON")); |
183 | uart_puts_pgm(PSTR("ON")); |
184 | } else { |
184 | } else { |
185 | uart_puts_pgm(PSTR("OFF")); |
185 | uart_puts_pgm(PSTR("OFF")); |
186 | } |
186 | } |
187 | uart_puts_pgm(PSTR(". Please restart...\r\n")); |
187 | uart_puts_pgm(PSTR(". Please restart...\r\n")); |
188 | } |
188 | } |
189 | 189 | ||
190 | 190 | ||
191 | 191 | ||
192 | 192 | ||
193 | /** |
193 | /** |
194 | * Interrupt handler for received data through UART1 |
194 | * Interrupt handler for received data through UART1 |
195 | */ |
195 | */ |
196 | SIGNAL(SIG_UART_RECV) { |
196 | SIGNAL(SIG_UART_RECV) { |
197 | unsigned char c = UDR; |
197 | unsigned char c = UDR; |
198 | switch (c) { |
198 | switch (c) { |
199 | case 'c': |
199 | case 'c': |
200 | ampere_calibrate(); |
200 | ampere_calibrate(); |
201 | break; |
201 | break; |
202 | case 's': |
202 | case 's': |
203 | save_eeprom(); |
203 | save_eeprom(); |
204 | break; |
204 | break; |
205 | case '+': |
205 | case '+': |
206 | sensor_change(100); |
206 | sensor_change(100); |
207 | break; |
207 | break; |
208 | case '-': |
208 | case '-': |
209 | sensor_change(50); |
209 | sensor_change(50); |
210 | break; |
210 | break; |
211 | case 'e': |
211 | case 'e': |
212 | if (hwver == 11) r2_change(V_ANIN, anin_r2 + 1); |
212 | if (hwver == 11) r2_change(V_ANIN, anin_r2 + 1); |
213 | break; |
213 | break; |
214 | case 'd': |
214 | case 'd': |
215 | if (hwver == 11) r2_change(V_ANIN, anin_r2 - 1); |
215 | if (hwver == 11) r2_change(V_ANIN, anin_r2 - 1); |
216 | break; |
216 | break; |
217 | case 'r': |
217 | case 'r': |
218 | r2_change(V_PRIMARY, prim_r2 + 1); |
218 | r2_change(V_PRIMARY, prim_r2 + 1); |
219 | break; |
219 | break; |
220 | case 'f': |
220 | case 'f': |
221 | r2_change(V_PRIMARY, prim_r2 - 1); |
221 | r2_change(V_PRIMARY, prim_r2 - 1); |
222 | break; |
222 | break; |
223 | case 'T': |
223 | case 'T': |
224 | CSTROM_CONFIG ^= CSTROM_TWI; |
224 | CSTROM_CONFIG ^= CSTROM_TWI; |
225 | twi_change(); |
225 | twi_change(); |
226 | break; |
226 | break; |
227 | case 'h': |
227 | case 'h': |
228 | help(0); |
228 | help(0); |
229 | break; |
229 | break; |
230 | default: |
230 | default: |
231 | asm("nop"); // :-) |
231 | asm("nop"); // :-) |
232 | } |
232 | } |
233 | } |
233 | } |
234 | 234 | ||
235 | /** |
235 | /** |
236 | * Interrupt handler for transmitting data through UART1 |
236 | * Interrupt handler for transmitting data through UART1 |
237 | */ |
237 | */ |
238 | SIGNAL(SIG_UART_TRANS) { |
238 | SIGNAL(SIG_UART_TRANS) { |
239 | } |
239 | } |
240 | 240 | ||
241 | /** |
241 | /** |
242 | * Read out the ADC channel <channel> |
242 | * Read out the ADC channel <channel> |
243 | */ |
243 | */ |
244 | uint16_t readADC(uint8_t channel) { |
244 | uint16_t readADC(uint8_t channel) { |
245 | uint8_t i; |
245 | uint8_t i; |
246 | uint16_t result = 0; |
246 | uint16_t result = 0; |
247 | 247 | ||
248 | // enable ADC and set clk div to 64 |
248 | // enable ADC and set clk div to 64 |
249 | ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1); |
249 | ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1); |
250 | 250 | ||
251 | _delay_us(5); |
251 | _delay_us(5); |
252 | 252 | ||
253 | // set up channel |
253 | // set up channel |
254 | ADMUX = channel; |
254 | ADMUX = channel; |
255 | // use internal reference |
255 | // use internal reference |
256 | //ADMUX |= (1<<REFS1) | (1<<REFS0); |
256 | //ADMUX |= (1<<REFS1) | (1<<REFS0); |
257 | 257 | ||
258 | // init ADC for a dummy readout |
258 | // init ADC for a dummy readout |
259 | ADCSRA |= (1<<ADSC); |
259 | ADCSRA |= (1<<ADSC); |
260 | // wait for conversion to be complete |
260 | // wait for conversion to be complete |
261 | while(ADCSRA & (1<<ADSC)); |
261 | while(ADCSRA & (1<<ADSC)); |
262 | 262 | ||
263 | // read in three times and get the average |
263 | // read in three times and get the average |
264 | for(i=0; i<3; i++) { |
264 | for(i=0; i<3; i++) { |
265 | // start conversion |
265 | // start conversion |
266 | ADCSRA |= (1<<ADSC); |
266 | ADCSRA |= (1<<ADSC); |
267 | 267 | ||
268 | // wait for conversion to be complete |
268 | // wait for conversion to be complete |
269 | while(ADCSRA & (1<<ADSC)); |
269 | while(ADCSRA & (1<<ADSC)); |
270 | 270 | ||
271 | // add up result |
271 | // add up result |
272 | result += ADCW; |
272 | result += ADCW; |
273 | } |
273 | } |
274 | 274 | ||
275 | // disable ADC |
275 | // disable ADC |
276 | ADCSRA &= ~(1<<ADEN); |
276 | ADCSRA &= ~(1<<ADEN); |
277 | 277 | ||
278 | // get average |
278 | // get average |
279 | result /= 3; |
279 | result /= 3; |
280 | 280 | ||
281 | return result; |
281 | return result; |
282 | } |
282 | } |
283 | 283 | ||
284 | 284 | ||
285 | /** |
285 | /** |
286 | * init SPI slave interrupt conrolled |
286 | * init SPI slave interrupt conrolled |
287 | */ |
287 | */ |
288 | void Init_Slave_IntContr (void) { |
288 | void Init_Slave_IntContr (void) { |
289 | volatile char IOReg; |
289 | volatile char IOReg; |
290 | // Set PB4(MISO) as output |
290 | // Set PB4(MISO) as output |
291 | DDRB = (1<<PB4); |
291 | DDRB = (1<<PB4); |
292 | // MOSI Pullup |
292 | // MOSI Pullup |
293 | PORTB |= _BV(3); |
293 | PORTB |= _BV(3); |
294 | // Enable SPI Interrupt and SPI in Slave Mode |
294 | // Enable SPI Interrupt and SPI in Slave Mode |
295 | SPCR = (1<<SPIE)|(1<<SPE); |
295 | SPCR = (1<<SPIE)|(1<<SPE); |
296 | IOReg = SPSR; // Clear SPIF bit in SPSR |
296 | IOReg = SPSR; // Clear SPIF bit in SPSR |
297 | IOReg = SPDR; |
297 | IOReg = SPDR; |
298 | SPCR |= _BV(SPIE); // duplicated |
298 | SPCR |= _BV(SPIE); // duplicated |
299 | } |
299 | } |
300 | 300 | ||
301 | 301 | ||
302 | 302 | ||
303 | /** |
303 | /** |
304 | * SPI interrupt handling |
304 | * SPI interrupt handling |
305 | */ |
305 | */ |
306 | ISR(SPI_STC_vect) { |
306 | ISR(SPI_STC_vect) { |
307 | LED_ON(); |
307 | LED_ON(); |
308 | 308 | ||
309 | unsigned char foo; |
309 | unsigned char foo; |
310 | foo = SPDR; |
310 | foo = SPDR; |
311 | //uart_putc(foo); |
311 | //uart_putc(foo); |
312 | switch (foo) { |
312 | switch (foo) { |
313 | case 'A': // requested ampere high bits for next transmission |
313 | case 'A': // requested ampere high bits for next transmission |
314 | CSTROM_FLAGS |= CSTROM_SPILOCKED; |
314 | CSTROM_FLAGS |= CSTROM_SPILOCKED; |
315 | foo = SPI_buffer.buffer.c[0]; |
315 | foo = SPI_buffer.buffer.c[0]; |
316 | break; |
316 | break; |
317 | case 'B': // requested low bits |
317 | case 'B': // requested low bits |
318 | foo = SPI_buffer.buffer.c[1]; |
318 | foo = SPI_buffer.buffer.c[1]; |
319 | break; |
319 | break; |
320 | case 'C': // wasted ampere high bits in next |
320 | case 'C': // wasted ampere high bits in next |
321 | foo = SPI_buffer.buffer.c[2]; |
321 | foo = SPI_buffer.buffer.c[2]; |
322 | break; |
322 | break; |
323 | case 'D': // 2nd highest 8bits |
323 | case 'D': // 2nd highest 8bits |
324 | foo = SPI_buffer.buffer.c[3]; |
324 | foo = SPI_buffer.buffer.c[3]; |
325 | break; |
325 | break; |
326 | case 'E': // 3rd highest 8bits |
326 | case 'E': // 3rd highest 8bits |
327 | foo = SPI_buffer.buffer.c[4]; |
327 | foo = SPI_buffer.buffer.c[4]; |
328 | break; |
328 | break; |
329 | case 'F': // lowest 8bits |
329 | case 'F': // lowest 8bits |
330 | foo = SPI_buffer.buffer.c[5]; |
330 | foo = SPI_buffer.buffer.c[5]; |
331 | break; |
331 | break; |
332 | case 'G': // lowest 8bits |
332 | case 'G': // lowest 8bits |
333 | foo = SPI_buffer.buffer.c[6]; |
333 | foo = SPI_buffer.buffer.c[6]; |
334 | break; |
334 | break; |
335 | case 'H': // lowest 8bits |
335 | case 'H': // lowest 8bits |
336 | foo = SPI_buffer.buffer.c[7]; |
336 | foo = SPI_buffer.buffer.c[7]; |
337 | break; |
337 | break; |
338 | case 'I': // challange over |
338 | case 'I': // challange over |
339 | foo = 'd'; // done :) |
339 | foo = 'd'; // done :) |
340 | CSTROM_FLAGS &= ~CSTROM_SPILOCKED; |
340 | CSTROM_FLAGS &= ~CSTROM_SPILOCKED; |
341 | break; |
341 | break; |
342 | default: // what else? nothin now |
342 | default: // what else? nothin now |
343 | foo = 'X'; |
343 | foo = 'X'; |
344 | } |
344 | } |
345 | // write back foo in next transmission |
345 | // write back foo in next transmission |
346 | SPDR = foo; |
346 | SPDR = foo; |
347 | 347 | ||
348 | //uart_putc(foo); |
348 | //uart_putc(foo); |
349 | 349 | ||
350 | LED_OFF(); |
350 | LED_OFF(); |
351 | } |
351 | } |
352 | 352 | ||
353 | /** |
353 | /** |
354 | * read data saved in eeprom |
354 | * read data saved in eeprom |
355 | */ |
355 | */ |
356 | void get_eeprom() { |
356 | void get_eeprom() { |
357 | if (eeprom_read_byte(&ee_checkbyte1) == CHECKBYTE1 && eeprom_read_byte(&ee_checkbyte2) == CHECKBYTE2) { |
357 | if (eeprom_read_byte(&ee_checkbyte1) == CHECKBYTE1 && eeprom_read_byte(&ee_checkbyte2) == CHECKBYTE2) { |
358 | uart_puts("\tLoading data from eeprom..."); |
358 | uart_puts("\tLoading data from eeprom..."); |
359 | sensor = eeprom_read_byte(&ee_sensor); |
359 | sensor = eeprom_read_byte(&ee_sensor); |
360 | cal_ampere = eeprom_read_word(&ee_cal_ampere); |
360 | cal_ampere = eeprom_read_word(&ee_cal_ampere); |
361 | anin_r1 = eeprom_read_byte(&ee_anin_r1); |
361 | anin_r1 = eeprom_read_byte(&ee_anin_r1); |
362 | anin_r2 = eeprom_read_byte(&ee_anin_r2); |
362 | anin_r2 = eeprom_read_byte(&ee_anin_r2); |
363 | prim_r1 = eeprom_read_byte(&ee_prim_r1); |
363 | prim_r1 = eeprom_read_byte(&ee_prim_r1); |
364 | prim_r2 = eeprom_read_byte(&ee_prim_r2); |
364 | prim_r2 = eeprom_read_byte(&ee_prim_r2); |
365 | CSTROM_CONFIG = eeprom_read_byte(&ee_config); |
365 | CSTROM_CONFIG = eeprom_read_byte(&ee_config); |
366 | uart_puts("done\r\n"); |
366 | uart_puts("done\r\n"); |
367 | } else { |
367 | } else { |
368 | uart_puts("\tNo data found in eeprom, using default data...\r\n"); |
368 | uart_puts("\tNo data found in eeprom, using default data...\r\n"); |
369 | } |
369 | } |
370 | } |
370 | } |
371 | 371 | ||
372 | /** |
372 | /** |
373 | * save data to eeprom |
373 | * save data to eeprom |
374 | */ |
374 | */ |
375 | void save_eeprom() { |
375 | void save_eeprom() { |
376 | uart_puts("\r\nSaving data to eeprom..."); |
376 | uart_puts("\r\nSaving data to eeprom..."); |
377 | eeprom_write_byte(&ee_checkbyte1, CHECKBYTE1); |
377 | eeprom_write_byte(&ee_checkbyte1, CHECKBYTE1); |
378 | eeprom_write_byte(&ee_checkbyte2, CHECKBYTE2); |
378 | eeprom_write_byte(&ee_checkbyte2, CHECKBYTE2); |
379 | eeprom_write_byte(&ee_sensor, sensor); |
379 | eeprom_write_byte(&ee_sensor, sensor); |
380 | eeprom_write_word(&ee_cal_ampere, cal_ampere); |
380 | eeprom_write_word(&ee_cal_ampere, cal_ampere); |
381 | //if (hwver == 11) { |
381 | //if (hwver == 11) { |
382 | // why not saving when not needed, there is space |
382 | // why not saving when not needed, there is space |
383 | eeprom_write_byte(&ee_anin_r1, anin_r1); |
383 | eeprom_write_byte(&ee_anin_r1, anin_r1); |
384 | eeprom_write_byte(&ee_anin_r2, anin_r2); |
384 | eeprom_write_byte(&ee_anin_r2, anin_r2); |
385 | //} |
385 | //} |
386 | eeprom_write_byte(&ee_prim_r1, prim_r1); |
386 | eeprom_write_byte(&ee_prim_r1, prim_r1); |
387 | eeprom_write_byte(&ee_prim_r2, prim_r2); |
387 | eeprom_write_byte(&ee_prim_r2, prim_r2); |
388 | eeprom_write_byte(&ee_config, CSTROM_CONFIG); |
388 | eeprom_write_byte(&ee_config, CSTROM_CONFIG); |
389 | uart_puts("done\r\n"); |
389 | uart_puts("done\r\n"); |
390 | } |
390 | } |
391 | 391 | ||
392 | /** |
392 | /** |
393 | * calibrate the current sensor... has to be 0A during this time! |
393 | * calibrate the current sensor... has to be 0A during this time! |
394 | */ |
394 | */ |
395 | void ampere_calibrate() { |
395 | void ampere_calibrate() { |
396 | cli(); |
396 | cli(); |
397 | uart_puts("\r\nCalibrating..."); |
397 | uart_puts("\r\nCalibrating..."); |
398 | uint16_t temp_cal = 0; |
398 | uint16_t temp_cal = 0; |
399 | for (uint8_t i = 0; i < 10; i++) { |
399 | for (uint8_t i = 0; i < 10; i++) { |
400 | temp_cal += readADC(0); |
400 | temp_cal += readADC(0); |
401 | uart_puts("#"); |
401 | uart_puts("#"); |
402 | _delay_ms(100); |
402 | _delay_ms(100); |
403 | } |
403 | } |
404 | cal_ampere = temp_cal / 10; |
404 | cal_ampere = temp_cal / 10; |
405 | uart_puts("done. Offset is now: "); |
405 | uart_puts("done. Offset is now: "); |
406 | uart_puts(itoa(cal_ampere, s, 10)); |
406 | uart_puts(itoa(cal_ampere, s, 10)); |
407 | uart_puts("\r\n"); |
407 | uart_puts("\r\n"); |
408 | sei(); |
408 | sei(); |
409 | } |
409 | } |
410 | 410 | ||
411 | 411 | ||
412 | volatile uint16_t timer = 0, cs = 0; |
412 | volatile uint16_t timer = 0, cs = 0; |
413 | /** |
413 | /** |
414 | * init timer0 |
414 | * init timer0 |
415 | */ |
415 | */ |
416 | void init_timer0(void){ |
416 | void init_timer0(void){ |
417 | // set up timer |
417 | // set up timer |
418 | TCCR0 |= (1 << CS00) | (1 << CS01); // timer0 prescaler 64 |
418 | TCCR0 |= (1 << CS00) | (1 << CS01); // timer0 prescaler 64 |
419 | TIMSK |= (1 << TOIE0); // enable overflow timer0 |
419 | TIMSK |= (1 << TOIE0); // enable overflow timer0 |
420 | } |
420 | } |
421 | 421 | ||
422 | /** |
422 | /** |
423 | * timer overflow handler, should be 1ms |
423 | * timer overflow handler, should be 1ms |
424 | */ |
424 | */ |
425 | SIGNAL(SIG_OVERFLOW0) { |
425 | SIGNAL(SIG_OVERFLOW0) { |
426 | TCNT0 = 131; // preload |
426 | TCNT0 = 131; // preload |
427 | timer++; |
427 | timer++; |
428 | // this should be 100ms |
428 | // this should be 100ms |
429 | if (timer == 100) { |
429 | if (timer == 100) { |
430 | timer = 0; |
430 | timer = 0; |
431 | cs++; |
431 | cs++; |
432 | average_ampere += ampere; |
432 | average_ampere += ampere; |
433 | CSTROM_FLAGS |= CSTROM_WRITEUART; |
433 | CSTROM_FLAGS |= CSTROM_WRITEUART; |
434 | } |
434 | } |
435 | // this should be 1s |
435 | // this should be 1s |
436 | if (cs == 10) { |
436 | if (cs == 10) { |
437 | cs = 0; |
437 | cs = 0; |
438 | mah += average_ampere / 360; |
438 | mah += average_ampere / 360; |
439 | average_ampere = 0; |
439 | average_ampere = 0; |
440 | } |
440 | } |
441 | } |
441 | } |
442 | 442 | ||
443 | /** |
443 | /** |
444 | * write <len> through uart spaces |
444 | * write <len> through uart spaces |
445 | */ |
445 | */ |
446 | void write_space(uint8_t len) { |
446 | void write_space(uint8_t len) { |
447 | while (len--) { |
447 | while (len--) { |
448 | uart_putc(' '); |
448 | uart_putc(' '); |
449 | } |
449 | } |
450 | } |
450 | } |
451 | 451 | ||
452 | 452 | ||
453 | 453 | ||
454 | /** |
454 | /** |
455 | * check which hardware version we have here |
455 | * check which hardware version we have here |
456 | */ |
456 | */ |
457 | void check_hw() { |
457 | void check_hw() { |
458 | // check if pin was output and has pullup |
458 | // check if pin was output and has pullup |
459 | uint8_t old_DDRD7 = DDRD & (1 << PD7); |
459 | uint8_t old_DDRD7 = DDRD & (1 << PD7); |
460 | uint8_t old_PORTD7 = PORTD & (1 << PD7); |
460 | uint8_t old_PORTD7 = PORTD & (1 << PD7); |
461 | 461 | ||
462 | // if it was, make it input |
462 | // if it was, make it input |
463 | if (old_DDRD7) DDRD &= ~(1 << PD7); // PD7 input (LED) |
463 | if (old_DDRD7) DDRD &= ~(1 << PD7); // PD7 input (LED) |
464 | if (!old_PORTD7) PORTD |= (1 << PD7); // PD7 enable pullup (LED) |
464 | if (!old_PORTD7) PORTD |= (1 << PD7); // PD7 enable pullup (LED) |
465 | 465 | ||
466 | 466 | ||
467 | if (PIND & (1 << PD7)) { |
467 | if (PIND & (1 << PD7)) { |
468 | hwver = 11; |
468 | hwver = 11; |
469 | LED_ON = PD7_L; |
469 | LED_ON = PD7_L; |
470 | LED_OFF = PD7_H; |
470 | LED_OFF = PD7_H; |
471 | } |
471 | } |
472 | 472 | ||
473 | 473 | ||
474 | // output again |
474 | // output again |
475 | if (!old_PORTD7) PORTD &= ~(1 << PD7); // PD7 disable pullup (LED) |
475 | if (!old_PORTD7) PORTD &= ~(1 << PD7); // PD7 disable pullup (LED) |
476 | if (old_DDRD7) DDRD |= (1 << PD7); // PD7 output (LED) |
476 | if (old_DDRD7) DDRD |= (1 << PD7); // PD7 output (LED) |
477 | } |
477 | } |
478 | 478 | ||
479 | 479 | ||
480 | /** |
480 | /** |
481 | * call for help whenever needed |
481 | * call for help whenever needed |
482 | */ |
482 | */ |
483 | void help(uint8_t load) { |
483 | void help(uint8_t load) { |
484 | uart_puts_pgm(PSTR("\r\nC-STROM\r\n\tBUILD: ")); |
484 | uart_puts_pgm(PSTR("\r\nC-STROM\r\n\tBUILD: ")); |
485 | uart_puts_pgm(PSTR(BUILDDATE)); |
485 | uart_puts_pgm(PSTR(BUILDDATE)); |
486 | uart_puts("\r\n\tHW: "); |
486 | uart_puts("\r\n\tHW: "); |
487 | uart_puts(itoa_dec(hwver, s)); |
487 | uart_puts(itoa_dec(hwver, s)); |
488 | 488 | ||
489 | uart_puts("\r\n"); |
489 | uart_puts("\r\n"); |
490 | 490 | ||
491 | if (load) get_eeprom(); |
491 | if (load) get_eeprom(); |
492 | 492 | ||
493 | uart_puts_pgm(PSTR("\tSensor: ")); |
493 | uart_puts_pgm(PSTR("\tSensor: ")); |
494 | uart_puts(itoa(sensor, s, 10)); |
494 | uart_puts(itoa(sensor, s, 10)); |
495 | uart_puts_pgm(PSTR("A\tCalibration: ")); |
495 | uart_puts_pgm(PSTR("A\tCalibration: ")); |
496 | uart_puts(itoa(cal_ampere, s, 10)); |
496 | uart_puts(itoa(cal_ampere, s, 10)); |
497 | 497 | ||
498 | uart_puts_pgm(PSTR("\r\n\tTWI is ")); |
498 | uart_puts_pgm(PSTR("\r\n\tTWI is ")); |
499 | if (CSTROM_CONFIG & CSTROM_TWI) { |
499 | if (CSTROM_CONFIG & CSTROM_TWI) { |
500 | uart_puts_pgm(PSTR("ON, SPI may not work!!!")); |
500 | uart_puts_pgm(PSTR("ON, SPI may not work!!!")); |
501 | } else { |
501 | } else { |
502 | uart_puts_pgm(PSTR("OFF")); |
502 | uart_puts_pgm(PSTR("OFF")); |
503 | } |
503 | } |
504 | 504 | ||
505 | 505 | ||
506 | uart_puts_pgm(PSTR("\r\n\tPIMARY R2: ")); |
506 | uart_puts_pgm(PSTR("\r\n\tPIMARY R2: ")); |
507 | uart_puts(itoa_dec(prim_r2, s)); |
507 | uart_puts(itoa_dec(prim_r2, s)); |
508 | if (hwver == 11) { |
508 | if (hwver == 11) { |
509 | uart_puts_pgm(PSTR("kOhm")); |
509 | uart_puts_pgm(PSTR("kOhm")); |
510 | uart_puts_pgm(PSTR("\tANIN R2: ")); |
510 | uart_puts_pgm(PSTR("\tANIN R2: ")); |
511 | uart_puts(itoa_dec(anin_r2, s)); |
511 | uart_puts(itoa_dec(anin_r2, s)); |
512 | } |
512 | } |
513 | uart_puts_pgm(PSTR("kOhm\r\n")); |
513 | uart_puts_pgm(PSTR("kOhm\r\n")); |
514 | 514 | ||
515 | uart_puts_pgm(PSTR("\tCommands available:\r\n")); |
515 | uart_puts_pgm(PSTR("\tCommands available:\r\n")); |
516 | uart_puts_pgm(PSTR("\t\th : help on commands (this)\r\n")); |
516 | uart_puts_pgm(PSTR("\t\th : help on commands (this)\r\n")); |
517 | uart_puts_pgm(PSTR("\t\tc : calibrate ampere\r\n")); |
517 | uart_puts_pgm(PSTR("\t\tc : calibrate ampere\r\n")); |
518 | uart_puts_pgm(PSTR("\t\tT : toggle TWI (may break SPI communication!)\r\n")); |
518 | uart_puts_pgm(PSTR("\t\tT : toggle TWI (may break SPI communication!)\r\n")); |
519 | uart_puts_pgm(PSTR("\t\t+/- : to change sensor\r\n")); |
519 | uart_puts_pgm(PSTR("\t\t+/- : to change sensor\r\n")); |
520 | uart_puts_pgm(PSTR("\t\tr/f : to change PRIMARY-R2 Value\r\n")); |
520 | uart_puts_pgm(PSTR("\t\tr/f : to change PRIMARY-R2 Value\r\n")); |
521 | if (hwver == 11) { |
521 | if (hwver == 11) { |
522 | uart_puts_pgm(PSTR("\t\te/d : to change ANIN-R2 Value\r\n")); |
522 | uart_puts_pgm(PSTR("\t\te/d : to change ANIN-R2 Value\r\n")); |
523 | } |
523 | } |
524 | uart_puts_pgm(PSTR("\t\ts : save values\r\n")); |
524 | uart_puts_pgm(PSTR("\t\ts : save values\r\n")); |
525 | uart_puts_pgm(PSTR("\tnow enjoy it and have fun...\r\n\r\n")); |
525 | uart_puts_pgm(PSTR("\tnow enjoy it and have fun...\r\n\r\n")); |
526 | } |
526 | } |
527 | 527 | ||
528 | 528 | ||
529 | /** |
529 | /** |
530 | * Main |
530 | * Main |
531 | */ |
531 | */ |
532 | int main (void) { |
532 | int main (void) { |
533 | DDRD |= (1 << PD7); // PD7 output (LED) |
533 | DDRD |= (1 << PD7); // PD7 output (LED) |
534 | 534 | ||
535 | check_hw(); |
535 | check_hw(); |
536 | uart_init(); |
536 | uart_init(); |
537 | 537 | ||
538 | Init_Slave_IntContr(); |
538 | Init_Slave_IntContr(); |
539 | init_timer0(); |
539 | init_timer0(); |
540 | 540 | ||
541 | sei(); // Enable Global Interrupts |
541 | sei(); // Enable Global Interrupts |
542 | 542 | ||
543 | uart_puts("\x1B[2J\x1B[H"); // clear serial |
543 | uart_puts("\x1B[2J\x1B[H"); // clear serial |
544 | 544 | ||
545 | help(1); |
545 | help(1); |
546 | 546 | ||
547 | if (CSTROM_CONFIG & CSTROM_TWI) init_twi_slave(CSTROM_I2C); |
547 | if (CSTROM_CONFIG & CSTROM_TWI) init_twi_slave(CSTROM_I2C); |
548 | 548 | ||
549 | int16_t raw_volt = 0, raw_ampere = 0, raw_aninvolt = 0; |
549 | int16_t raw_volt = 0, raw_ampere = 0, raw_aninvolt = 0; |
550 | char c[10] = " "; |
550 | char c[10] = " "; |
551 | c[9] = 0; |
551 | c[9] = 0; |
552 | 552 | ||
553 | //strom_data = *((SPI_strom_data_t*) &spi_buffer); |
553 | //strom_data = *((SPI_strom_data_t*) &spi_buffer); |
554 | //*spi_buffer = *((uint8_t*) (void*) &strom_data); |
554 | //*spi_buffer = *((uint8_t*) (void*) &strom_data); |
555 | 555 | ||
556 | LED_ON(); |
556 | LED_ON(); |
557 | 557 | ||
558 | while (1) { // Loop Forever |
558 | while (1) { // Loop Forever |
559 | 559 | ||
560 | // we have got a normal voltage measuring circuit that takes the lipo-voltage |
560 | // we have got a normal voltage measuring circuit that takes the lipo-voltage |
561 | raw_volt = readADC(1); |
561 | raw_volt = readADC(1); |
562 | /* according to what i read about voltage divider it is |
562 | /* according to what i read about voltage divider it is |
563 | Uo = Ue * (R1 / (R2 + R1)) |
563 | Uo = Ue * (R1 / (R2 + R1)) |
564 | Ue = Uo * (R2 + R1) / R1 |
564 | Ue = Uo * (R2 + R1) / R1 |
565 | the board has got r1 = 4.7k and r2 = 15k |
565 | the board has got r1 = 4.7k and r2 = 15k |
566 | but since 1step is 0,0048828125V = 4,8828125mV and not 5mV there |
566 | but since 1step is 0,0048828125V = 4,8828125mV and not 5mV there |
567 | is some conversion to do for raw_volt --**-> Uo |
567 | is some conversion to do for raw_volt --**-> Uo |
568 | this should end up in 10th of volts */ |
568 | this should end up in 10th of volts */ |
569 | raw_volt = ((uint32_t)raw_volt * (uint32_t)48828) / (uint32_t)10000; |
569 | raw_volt = ((uint32_t)raw_volt * (uint32_t)48828) / (uint32_t)10000; |
570 | volt = (int16_t) (((uint32_t)raw_volt * (uint32_t)(prim_r1 + prim_r2)) / (uint32_t)prim_r1) / 100; |
570 | volt = (int16_t) (((uint32_t)raw_volt * (uint32_t)(prim_r1 + prim_r2)) / (uint32_t)prim_r1) / 100; |
571 | if (volt < 0) volt = 0; |
571 | if (volt < 0) volt = 0; |
572 | 572 | ||
573 | // and we have got a seccond voltage measuring circuit for user voltages |
573 | // and we have got a seccond voltage measuring circuit for user voltages |
574 | raw_aninvolt = readADC(2); |
574 | raw_aninvolt = readADC(2); |
575 | /* some conversion to do for raw_volt --**-> Uo |
575 | /* some conversion to do for raw_volt --**-> Uo |
576 | this should end up in 10th of volts */ |
576 | this should end up in 10th of volts */ |
577 | raw_aninvolt = ((uint32_t)raw_aninvolt * (uint32_t)48828) / (uint32_t)10000; |
577 | raw_aninvolt = ((uint32_t)raw_aninvolt * (uint32_t)48828) / (uint32_t)10000; |
578 | anin_volt = (int16_t) (((uint32_t)raw_aninvolt * (uint32_t)(anin_r1 + anin_r2)) / (uint32_t)anin_r1) / 100; |
578 | anin_volt = (int16_t) (((uint32_t)raw_aninvolt * (uint32_t)(anin_r1 + anin_r2)) / (uint32_t)anin_r1) / 100; |
579 | if (anin_volt < 0) anin_volt = 0; |
579 | if (anin_volt < 0) anin_volt = 0; |
580 | 580 | ||
581 | raw_ampere = readADC(0); |
581 | raw_ampere = readADC(0); |
582 | /* according to datasheet sensitivity is nominal 40mV per A for the 50A chip |
582 | /* according to datasheet sensitivity is nominal 40mV per A for the 50A chip |
583 | this would mean 50A ^= 2V since 0A is set to 2.5V output Voltage we get |
583 | this would mean 50A ^= 2V since 0A is set to 2.5V output Voltage we get |
584 | a range of 0.5V till 4.5V for the full range. |
584 | a range of 0.5V till 4.5V for the full range. |
585 | the atmega ADC features 0...5V range divided into 10bit ^= 1024 steps |
585 | the atmega ADC features 0...5V range divided into 10bit ^= 1024 steps |
586 | so 0,0048828125V, or 4,8828125mV, is one step |
586 | so 0,0048828125V, or 4,8828125mV, is one step |
587 | this leads us to 0,8192 steps per 0,1A and somehow the below formula |
587 | this leads us to 0,8192 steps per 0,1A and somehow the below formula |
588 | and i know that 32bit is evil, but what else does this device has to do? :) |
588 | and i know that 32bit is evil, but what else does this device has to do? :) |
589 | this should end up in 100th of ampere */ |
589 | this should end up in 100th of ampere */ |
590 | ampere = (int16_t) (((int32_t)(((int16_t)raw_ampere - (int16_t)cal_ampere)) * (int32_t)10000) / (int32_t) 819); |
590 | ampere = (int16_t) (((int32_t)(((int16_t)raw_ampere - (int16_t)cal_ampere)) * (int32_t)10000) / (int32_t) 819); |
591 | if (sensor == 100) ampere *= 2; |
591 | if (sensor == 100) ampere *= 2; |
592 | 592 | ||
593 | if ((CSTROM_FLAGS & CSTROM_WRITEUART)) { |
593 | if ((CSTROM_FLAGS & CSTROM_WRITEUART)) { |
594 | uart_puts("V: "); |
594 | uart_puts("V: "); |
595 | uart_puts(itoa_dec(volt, s)); |
595 | uart_puts(itoa_dec(volt, s)); |
596 | write_space(10-strlen(s)); |
596 | write_space(10-strlen(s)); |
597 | 597 | ||
598 | uart_puts("AN-IN V: "); |
598 | uart_puts("AN-IN V: "); |
599 | uart_puts(itoa_dec(anin_volt, s)); |
599 | uart_puts(itoa_dec(anin_volt, s)); |
600 | write_space(10-strlen(s)); |
600 | write_space(10-strlen(s)); |
601 | 601 | ||
602 | uart_puts("A: "); |
602 | uart_puts("A: "); |
603 | uart_puts(itoa(ampere, s, 10)); |
603 | uart_puts(itoa(ampere, s, 10)); |
604 | write_space(10-strlen(s)); |
604 | write_space(10-strlen(s)); |
605 | 605 | ||
606 | uart_puts("C: "); |
606 | uart_puts("C: "); |
607 | uart_puts(itoa(mah, s, 10)); |
607 | uart_puts(itoa(mah, s, 10)); |
608 | write_space(10-strlen(s)); |
608 | write_space(10-strlen(s)); |
609 | 609 | ||
610 | uart_puts("\r"); |
610 | uart_puts("\r"); |
611 | CSTROM_FLAGS &= ~CSTROM_WRITEUART; |
611 | CSTROM_FLAGS &= ~CSTROM_WRITEUART; |
612 | } |
612 | } |
613 | 613 | ||
614 | //spi_buff |
614 | //spi_buff |
615 | if (!(CSTROM_FLAGS & CSTROM_SPILOCKED)) { |
615 | if (!(CSTROM_FLAGS & CSTROM_SPILOCKED)) { |
616 | // TESTTING |
616 | // TESTTING |
617 | if (!(CSTROM_CONFIG & CSTROM_TWI)) CSTROM_FLAGS |= CSTROM_SPILOCKED; |
617 | if (!(CSTROM_CONFIG & CSTROM_TWI)) CSTROM_FLAGS |= CSTROM_SPILOCKED; |
618 | SPI_buffer.data.ampere = ampere; |
618 | SPI_buffer.data.ampere = ampere; |
619 | SPI_buffer.data.mah = mah; |
619 | SPI_buffer.data.mah = mah; |
620 | if (hwver == 11) { |
620 | if (hwver == 11) { |
621 | SPI_buffer.data.volt = anin_volt; |
621 | SPI_buffer.data.volt = anin_volt; |
622 | } else { |
622 | } else { |
623 | SPI_buffer.data.volt = volt; |
623 | SPI_buffer.data.volt = volt; |
624 | } |
624 | } |
625 | } |
625 | } |
626 | } |
626 | } |
627 | return 0; |
627 | return 0; |
628 | } |
628 | } |
629 | 629 |