Skip to content

Commit 1883e3e

Browse files
committed
fix premature exit from ADC10 read caused by WDT_ISR
1 parent 4443466 commit 1883e3e

File tree

1 file changed

+34
-30
lines changed

1 file changed

+34
-30
lines changed

hardware/msp430/cores/msp430/wiring_analog.c

Lines changed: 34 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -157,39 +157,43 @@ void analogWrite(uint8_t pin, int val)
157157

158158
uint16_t analogRead(uint8_t pin)
159159
{
160-
161160
// make sure we have an ADC
162161
#if defined(__MSP430_HAS_ADC10__)
163-
// 0000 A0
164-
// 0001 A1
165-
// 0010 A2
166-
// 0011 A3
167-
// 0100 A4
168-
// 0101 A5
169-
// 0110 A6
170-
// 0111 A7
171-
// 1010 Internal temperature sensor
172-
173-
//TODO: Only int. temp. sensor requires Tsample > 30us.
174-
// The below ADC configuration applies this rule to all channels right now.
175-
// ADC10CLK = 5MHz / 5 = 1Mhz
176-
// Tsample = S&H / ADC10CLK = 64 / 1 MHz = 64 us
177-
// Tconver = 13 / ADC10CLK = 13 / 1 MHz = 13 us
178-
// Total time per sample = Tconvert + Tsample = 64 + 13 = 67 us = ~15k samples / sec
179-
if(pin > 7 && pin != 10) // ADC on pin?
180-
return 0;
181-
ADC10CTL0 &= ~ENC; // disable ADC
182-
ADC10CTL0 = analog_reference + // set analog reference
183-
ADC10ON + ADC10SHT_3 + ADC10IE; // turn ADC ON; sample + hold @ 64 × ADC10CLKs; Enable interrupts
184-
ADC10CTL1 = ADC10SSEL_0 + ADC10DIV_5 + // ADC10OSC as ADC10CLK (~5MHz) / 5
185-
(pin << 12); // select channel
186-
__delay_cycles (128); // Delay to allow Ref to settle
187-
ADC10CTL0 |= ENC + ADC10SC; // enable ADC and start conversion
188-
__bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enabled
189-
return ADC10MEM; // return sampled value after returning to active mode in ADC10_ISR
162+
// 0000 A0
163+
// 0001 A1
164+
// 0010 A2
165+
// 0011 A3
166+
// 0100 A4
167+
// 0101 A5
168+
// 0110 A6
169+
// 0111 A7
170+
// 1010 Internal temperature sensor
171+
172+
//TODO: Only int. temp. sensor requires Tsample > 30us.
173+
// The below ADC configuration applies this rule to all channels right now.
174+
// ADC10CLK = 5MHz / 5 = 1Mhz
175+
// Tsample = S&H / ADC10CLK = 64 / 1 MHz = 64 us
176+
// Tconvert = 13 / ADC10CLK = 13 / 1 MHz = 13 us
177+
// Total time per sample = Tconvert + Tsample = 64 + 13 = 67 us = ~15k samples / sec
178+
if (pin > 7 && pin != 10) { // Is this a valid ADC pin?
179+
return 0;
180+
}
181+
182+
ADC10CTL0 &= ~ENC; // disable ADC
183+
ADC10CTL0 = analog_reference | // set analog reference
184+
ADC10ON | ADC10SHT_3 | ADC10IE; // turn ADC ON; sample + hold @ 64 × ADC10CLKs; Enable interrupts
185+
ADC10CTL1 = ADC10SSEL_0 | ADC10DIV_5 | // ADC10OSC as ADC10CLK (~5MHz) / 5
186+
(pin << 12); // select channel
187+
__delay_cycles(128); // Delay to allow Ref to settle
188+
ADC10CTL0 |= ENC | ADC10SC; // enable ADC and start conversion
189+
while (ADC10CTL1 & ADC10BUSY) { // sleep and wait for completion
190+
__bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enabled
191+
}
192+
193+
return ADC10MEM; // return sampled value after returning to active mode in ADC10_ISR
190194
#else
191-
// no ADC
192-
return 0;
195+
// no ADC
196+
return 0;
193197
#endif
194198
}
195199

0 commit comments

Comments
 (0)