X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=bertos%2Fcpu%2Farm%2Fdrv%2Fadc_at91.c;h=7fd50ddf24eae8ff05fe80a0f3b21953720de41e;hb=32d1445272120a254d77ce8d1af1f527da7a2c17;hp=46ba341370ceb03e1bd4f2e9acbb4b406ee5d4ae;hpb=b0c536ad873bb29ed977417a6a5b1aa586414d3b;p=bertos.git diff --git a/bertos/cpu/arm/drv/adc_at91.c b/bertos/cpu/arm/drv/adc_at91.c index 46ba3413..7fd50ddf 100644 --- a/bertos/cpu/arm/drv/adc_at91.c +++ b/bertos/cpu/arm/drv/adc_at91.c @@ -84,7 +84,7 @@ * ADC ISR. * Simply signal the adc process that convertion is complete. */ - static void ISR_FUNC adc_conversion_end_irq(void) + static DECLARE_ISR(adc_conversion_end_irq) { sig_signal(adc_process, SIG_ADC_COMPLETE); @@ -114,7 +114,7 @@ * Select mux channel \a ch. * \todo only first 8 channels are selectable! */ -INLINE void adc_hw_select_ch(uint8_t ch) +void adc_hw_select_ch(uint8_t ch) { //Disable all channels ADC_CHDR = ADC_CH_MASK; @@ -126,13 +126,13 @@ INLINE void adc_hw_select_ch(uint8_t ch) /** * Start an ADC convertion. * If a kernel is present, preempt until convertion is complete, otherwise - * a busy wait on ADCS bit is done. + * a busy wait on ADC_DRDY bit is done. */ -INLINE uint16_t adc_hw_read(void) +uint16_t adc_hw_read(void) { - ASSERT(!(ADC_SR & ADC_EOC_MASK)); - #if CONFIG_KERN + /* Ensure ADC is not already in use by another process */ + ASSERT(adc_process == NULL); adc_process = proc_current(); #endif @@ -143,19 +143,25 @@ INLINE uint16_t adc_hw_read(void) // Ensure IRQs enabled. IRQ_ASSERT_ENABLED(); sig_wait(SIG_ADC_COMPLETE); + + /* Prevent race condition in case of preemptive kernel */ + uint16_t ret = ADC_LCDR; + MEMORY_BARRIER; + adc_process = NULL; + return ret; #else //Wait in polling until is done while (!(ADC_SR & BV(ADC_DRDY))); - #endif - //Return the last converted data - return(ADC_LCDR); + //Return the last converted data + return(ADC_LCDR); + #endif } /** * Init ADC hardware. */ -INLINE void adc_hw_init(void) +void adc_hw_init(void) { //Init ADC pins. ADC_INIT_PINS();