\r
#include <ioavr.h>\r
#include <inavr.h>\r
+#include <intrinsics.h>\r
\r
#include "structs.h"\r
\r
* This ISR stores the sampled values in the ADC status-struct, then\r
* updates the ADC MUX to the next channel in the scanning-sequence.\n\r
* Once the sequence is completed, ADCS.Flag is set and unless\r
- * ADCS.Halt has been set, the sequence starts over. Otherwise, the ADC \r
+ * ADCS.Halt has been set, the sequence starts over. Otherwise, the ADC\r
* is disabled.\n\r
* If the mains voltage is below minimum, ADCS.Mains gets set to FALSE.\r
*\r
static unsigned char avgIndex = 0;\r
unsigned char i, Next, Signed;\r
signed int temp = 0;\r
- \r
+\r
Signed = FALSE; // Presume next conversion is unipolar.\r
ADCSRA &= ~(1<<ADEN); // Stop conversion before handling. This makes all\r
// conversions take at least 25 ADCCLK. (It is restarted later)\r
- \r
+\r
// Handle the conversion, depending on what channel it is from, then\r
// switch to the next channel in the sequence.\r
switch (ADCS.MUX){\r
Next=0x02;\r
break;\r
\r
- \r
+\r
// MUX = 0b000010 => ADC2 (PA2) = RID\r
case 0x02:\r
ADCS.rawRID = ADC;\r
Next=0x03;\r
break;\r
\r
- \r
+\r
// MUX = 0b000011 => ADC3 (PA4) = VIN-\r
case 0x03:\r
// Supply voltage is always divided by 16.\r
ADCS.VIN = ScaleU(4, (unsigned int)ADC); // Cast because ADC is short.\r
- \r
+\r
// Is mains failing?\r
if (ADCS.VIN < VIN_MIN) {\r
ADCS.Mains = FALSE;\r
} else {\r
ADCS.Mains = TRUE;\r
}\r
- \r
+\r
Next=0x05;\r
break;\r
\r
- \r
+\r
// MUX = 0b000101 => ADC5 (PA6) = VBAT-\r
case 0x05:\r
ADCS.rawVBAT = ADC;\r
- \r
+\r
// Scale voltage according to jumper setting.\r
ADCS.VBAT = ScaleU(VBAT_RANGE, (unsigned int)ADC); // ADC is a short.\r
+ __no_operation();\r
Next=0x17;\r
// Signed = TRUE; // Next conversion is bipolar. Halves sensitivity!\r
break;\r
case 0x17: // MUX = 0b010111 => 20 x [ADC6(PA7) - ADC5(PA6)] = IBAT\r
// If bipolar, from -512 to 0, to 511:\r
// 0x200 ... 0x3ff, 0x000, 0x001 ... 0x1FF\r
- \r
+\r
// Scale sample according to jumper setting, handle negative numbers.\r
if (ADC > 511) {\r
ADCS.IBAT = -(signed int)ScaleI(VBAT_RANGE,\r
for (i = 0; i < 4 ; i++) {\r
temp += ADCS.discIBAT[i];\r
}\r
- \r
+\r
ADCS.avgIBAT = (temp / 4);\r
- \r
+\r
ADCS.Flag = TRUE;\r
Next=0x01;\r
Signed = FALSE; // This is the only bipolar conversion.\r
break;\r
\r
- \r
+\r
default: // Should not happen. (Invalid MUX-channel)\r
Next=0x01; // Start at the beginning of sequence.\r
break;\r
}\r
- \r
+\r
// Update MUX to next channel in sequence, set a bipolar conversion if\r
// this has been flagged.\r
- ADCS.MUX = Next; \r
- ADMUX = (1<<REFS0) + ADCS.MUX; \r
+ ADCS.MUX = Next;\r
+ ADMUX = (1<<REFS0) + ADCS.MUX;\r
\r
if (Signed) {\r
- ADCSRB |= (1<<BIN); \r
+ ADCSRB |= (1<<BIN);\r
} else {\r
- ADCSRB &= ~(1<<BIN); \r
+ ADCSRB &= ~(1<<BIN);\r
}\r
\r
// Re-enable the ADC unless a halt has been flagged and a conversion\r
// cycle has completed.\r
if (!((ADCS.Halt) && (ADCS.Flag))) {\r
- ADCSRA |= (1<<ADEN)|(1<<ADSC); \r
+ ADCSRA |= (1<<ADEN)|(1<<ADSC);\r
}\r
}\r
\r
// Jumper setting 4: mV/LSB = 39.06 ~= 39 + 1/16\r
scaled = 39 * data;\r
scaled += (data >> 4);\r
- \r
+\r
if (setting <3) {\r
// Jumper setting 0: mV/LSB = 4.883 = 39.06 / 8\r
// 1: mV/LSB = 9.766 = 39.06 / 4\r
{\r
// Temporary variable needed.\r
unsigned int scaled = 0;\r
- \r
+\r
// Jumper setting 3: mA/LSB = 20.931mA ~= 21 - 1/16 + 1/128\r
if (setting == 3) {\r
scaled = 21 * data;\r
scaled = 28 * data;\r
scaled -= (data >> 3);\r
scaled += (data >> 5);\r
- \r
+\r
if (setting <3) {\r
// Jumper setting 0: mA/LSB = 3.489mA = 27.909 / 8\r
// 1: mA/LSB = 6.978mA = 27.909 / 4\r
scaled = (scaled >> (3-setting));\r
}\r
}\r
- \r
+\r
return(scaled);\r
}\r
\r
*\r
* This function clears the cycle complete-flag, then waits for it to be set\r
* again. This is then repeated once before the function exits.\r
- * \r
+ *\r
*/\r
void ADC_Wait(void)\r
{\r
// Clear ADC flag and wait for cycle to complete.\r
- ADCS.Flag = FALSE; \r
+ ADCS.Flag = FALSE;\r
do {\r
- } while (ADCS.Flag == FALSE); \r
- \r
+ } while (ADCS.Flag == FALSE);\r
+\r
// Repeat, so we are sure the data beong to the same cycle.\r
- ADCS.Flag = FALSE; \r
+ ADCS.Flag = FALSE;\r
do {\r
- } while (ADCS.Flag == FALSE); \r
+ } while (ADCS.Flag == FALSE);\r
}\r
\r
\r
\r
// Set ADC3 as reference, and MUX to measure the same pin.\r
ADMUX = (1<<REFS0) | (1<<MUX0) | (1<<MUX1);\r
- \r
+\r
ADCSRB = 0;\r
\r
// Start conversion, no interrupt (disable ADC-ISR).\r
- ADCSRA = (1<<ADEN) | (1<<ADSC) | ADC_PRESCALER; \r
+ ADCSRA = (1<<ADEN) | (1<<ADSC) | ADC_PRESCALER;\r
\r
do { // Wait for conversion to finish.\r
} while (!(ADCSRA & (1<<ADIF)));\r
ADCS.ADC3_G20_OS = ADC; // Save the sampled offset.\r
\r
ADMUX = (1<<REFS0) | 0x16; // ADC5/ADC5 (external ref.), 20x\r
- \r
+\r
// Start conversion, no interrupt. ADC_PRESCALER is defined in ADC.h.\r
- ADCSRA = (1<<ADEN) | (1<<ADSC) | ADC_PRESCALER; \r
+ ADCSRA = (1<<ADEN) | (1<<ADSC) | ADC_PRESCALER;\r
\r
do { // Wait for conversion to finish.\r
} while (!(ADCSRA & (1<<ADIF)));\r
ADCS.ADC5_G20_OS = ADC; // Save the sampled offset.\r
\r
// Reset the ADC-cycle.\r
- ADCS.Flag = FALSE; \r
- ADCS.MUX = 0x01; \r
- ADMUX = (1<<REFS0) | ADCS.MUX; \r
+ ADCS.Flag = FALSE;\r
+ ADCS.MUX = 0x01;\r
+ ADMUX = (1<<REFS0) | ADCS.MUX;\r
\r
// Clear averaged battery current and the discrete readings.\r
ADCS.avgIBAT = 0;\r
- \r
+\r
for (i = 0; i < 4; i++) {\r
- ADCS.discIBAT[i] = 0; \r
+ ADCS.discIBAT[i] = 0;\r
}\r
- \r
+\r
// Re-enable the ADC and ISR.\r
ADCSRA=(1<<ADEN)|(1<<ADSC)|(1<<ADIE)|ADC_PRESCALER;\r
- \r
+\r
__enable_interrupt();\r
\r
// Get a complete cycle of data before returning.\r