diff --git a/chip/lm4/adc.c b/chip/lm4/adc.c index e58945605e..f797317688 100644 --- a/chip/lm4/adc.c +++ b/chip/lm4/adc.c @@ -18,6 +18,9 @@ #include "timer.h" #include "util.h" +/* Maximum time we allow for an ADC conversion */ +#define ADC_TIMEOUT_US SECOND + static task_id_t task_waiting_on_ss[LM4_ADC_SEQ_COUNT]; static void configure_gpio(void) @@ -74,13 +77,21 @@ static int flush_and_read(enum lm4_adc_sequencer seq) /* Clear the interrupt status */ LM4_ADC_ADCISC |= 0x01 << seq; + /* Enable interrupt */ + LM4_ADC_ADCIM |= 0x01 << seq; + /* Initiate sample sequence */ LM4_ADC_ADCPSSI |= 0x01 << seq; /* Wait for interrupt */ - event = task_wait_event(SECOND); + event = task_wait_event_mask(TASK_EVENT_ADC_DONE, ADC_TIMEOUT_US); + + /* Disable interrupt */ + LM4_ADC_ADCIM &= ~(0x01 << seq); + task_waiting_on_ss[seq] = TASK_ID_INVALID; - if (event == TASK_EVENT_TIMER) + + if (!(event & TASK_EVENT_ADC_DONE)) return ADC_READ_ERROR; /* Read the FIFO and convert to temperature */ @@ -159,6 +170,7 @@ int adc_read_channel(enum adc_channel ch) if (rv == ADC_READ_ERROR) return ADC_READ_ERROR; + return rv * adc->factor_mul / adc->factor_div + adc->shift; } @@ -189,7 +201,7 @@ static void handle_interrupt(int ss) /* Wake up the task which was waiting on the interrupt, if any */ if (id != TASK_ID_INVALID) - task_wake(id); + task_set_event(id, TASK_EVENT_ADC_DONE, 0); } void ss0_interrupt(void) { handle_interrupt(0); } @@ -255,8 +267,7 @@ static void adc_init(void) for (i = 0; i < LM4_ADC_SEQ_COUNT; i++) task_waiting_on_ss[i] = TASK_ID_INVALID; - /* Enable interrupt */ - LM4_ADC_ADCIM = 0xF; + /* Enable IRQs */ task_enable_irq(LM4_IRQ_ADC0_SS0); task_enable_irq(LM4_IRQ_ADC0_SS1); task_enable_irq(LM4_IRQ_ADC0_SS2); diff --git a/include/task.h b/include/task.h index 6b10c649b1..00368fbc34 100644 --- a/include/task.h +++ b/include/task.h @@ -13,7 +13,9 @@ /* Task event bitmasks */ /* Tasks may use the bits in TASK_EVENT_CUSTOM for their own events */ -#define TASK_EVENT_CUSTOM(x) (x & 0x0fffffff) +#define TASK_EVENT_CUSTOM(x) (x & 0x07ffffff) +/* ADC interrupt handler event */ +#define TASK_EVENT_ADC_DONE (1 << 27) /* I2C interrupt handler event */ #define TASK_EVENT_I2C_IDLE (1 << 28) /* task_wake() called on task */