Fast AnalogIn module which asks for a single non blocking reading and causes and interrupt when done.
Diff: NbAnalogIn.cpp
- Revision:
- 2:336af413f75c
- Parent:
- 1:2666729acca1
- Child:
- 3:d4f99bc10643
--- a/NbAnalogIn.cpp Sun Apr 02 11:16:24 2017 +0000 +++ b/NbAnalogIn.cpp Mon Apr 03 10:59:17 2017 +0000 @@ -10,83 +10,112 @@ return i; } -NbAnalogIn* NbAnalogIn::handlers[2] = {0}; +static const PinMap PinMap_ADC[] = { + P0_23, ADC0_0, 1, + P0_24, ADC0_1, 1, + P0_25, ADC0_2, 1, + P0_26, ADC0_3, 1, + P1_30, ADC0_4, 3, + P1_31, ADC0_5, 3, + P0_2, ADC0_7, 2, + P0_3, ADC0_6, 2, + NC, NC, 0 +}; -NbAnalogIn::NbAnalogIn(){ +//set the static handlers array to 0 +NbAnalogIn* NbAnalogIn::handlers[ADC_CHANNELS] = {0}; +volatile bool NbAnalogIn::converting = false; + +NbAnalogIn::NbAnalogIn( PinName pin, void (*irqfunc)() ) { NVIC_EnableIRQ(ADC_IRQn); NVIC_SetVector(ADC_IRQn, (uint32_t)irq); + cirq = irqfunc; + + channel = (ADCName)pinmap_peripheral(pin, PinMap_ADC); + if (channel == (uint32_t)NC) + error("ADC pin mapping failed"); + + write_pos = 0; // next position to be written to read_pos = 0; // next position to be read from - handlers[0] = this; // put a pointer to this object into the handlers array + handlers[channel] = this; // put a pointer to this object into the handlers array LPC_SC->PCONP |= (1 << 12); // turn power for ADC on + // set peripheral clock registers to provide clock for ADC (bits 24 & 25) // set to 00 for PCLK = CCLK LPC_SC->PCLKSEL0 &= ~(0x3 << 24); // clear bits LPC_SC->PCLKSEL0 |= (0x1 << 24); // set bits - - //set P1.30 as AD0.4 - LPC_PINCON->PINSEL3 |= (3<<28); + - - //Set PINMODE of AD0.4 as no pull-up/down resistors - LPC_PINCON->PINMODE3 &= ~(3<<28); - LPC_PINCON->PINMODE3 |= (2<<28); - + //Map pins + pinmap_pinout(pin, PinMap_ADC); /* set the A/D control register */ - // select 4, clkdiv = 7, enable, don't start yet - LPC_ADC->ADCR = (1 << 4) | (7 << 8) | (1 << 21) | (0 << 24) ; - - - - + // select clkdiv = 7, enable, don't start yet + LPC_ADC->ADCR |= (7 << 8) // set CLKDIV=7 (the fastest) + | (1 << 21) // Power On + | (0 << 24) ; // Don't Start yet + + LPC_ADC->ADINTEN |= (1 << 8); } -unsigned int NbAnalogIn::read() { +int NbAnalogIn::readBl() { - /* disable interrupts */ - LPC_ADC->ADINTEN &= ~(1 << 4); - LPC_ADC->ADINTEN = 0; + /* disable interrupt */ + NVIC_EnableIRQ(ADC_IRQn); - LPC_ADC->ADCR |= (1 << 24) ; // start conversion + LPC_ADC->ADCR &= ~( 0xff ); // disable all other channels + LPC_ADC->ADCR |= (1 << channel) + | (1 << 24) ; // start conversion + - while((LPC_ADC->ADSTAT & (1<<4)) == 0); + while((LPC_ADC->ADSTAT & (1 << channel)) == 0); - return (unsigned int)((LPC_ADC->ADGDR >> 4) & 0xFFF); + int adc_result = (int)( (LPC_ADC->ADGDR >> 4) & 0xFFF ); + + NVIC_EnableIRQ(ADC_IRQn); + return adc_result; } -void NbAnalogIn::triggerConv() { - /* enable interrupts */ - LPC_ADC->ADINTEN = (1 << 4); +void NbAnalogIn::triggerConv( bool wait) { + + if(wait) { + while(converting); + } - LPC_ADC->ADCR |= (1 << 24) ; // start conversion + converting = true; + LPC_ADC->ADCR &= ~( 0xff ); // disable all other channels + LPC_ADC->ADCR |= (1 << channel) + | (1 << 24) ; // start conversion + + } // static interrupt handler void NbAnalogIn::irq() { + int adc_result = (int)((LPC_ADC->ADGDR >> 4) & 0xFFF); - uint8_t channel = (uint8_t)((LPC_ADC->ADGDR >> 24) & 0x7); + uint8_t adc_channel = (uint8_t)((LPC_ADC->ADGDR >> 24) & 0x7); - /** for debug */// + converting = false; + + /** for debug static int count = 0; adc_result = count++; - printf("NB! channel %d, result %d \n",channel, adc_result); - + printf("NbAnalogIn::irq(): channel %d, result %d \n",adc_channel, adc_result); + */ // call the right channel's handler - handlers[0]->handler(adc_result); - + handlers[adc_channel]->handler(adc_result); - /* disable interrupt */ - LPC_ADC->ADINTEN &= ~(1 << channel); } void NbAnalogIn::handler( int adc_result ) { @@ -94,34 +123,34 @@ buffer[write_pos] = adc_result; - printf("ADC: %d written into pos %d \n",adc_result, write_pos); + //printf("NbAnalogIn::handler(c%d): %d written into pos %d \n", channel,adc_result, write_pos); write_pos = pos_inc( write_pos ); // loop around if( write_pos == read_pos ) { read_pos = pos_inc( read_pos ); // keep read position ahead of write position - printf("ADC: LOOP AROUND!!! incremented r \n"); + //printf("NbAnalogIn::handler(c%d): LOOP AROUND!!! incremented r \n", channel); } - printf("ADC: w=%d, r=%d \n", write_pos, read_pos); + //printf("NbAnalogIn::handler(c%d): w=%d, r=%d \n", channel, write_pos, read_pos); - + // call custom irq handler if set + if (cirq) + cirq(); } bool NbAnalogIn::readable() { return write_pos != read_pos; } -int NbAnalogIn::readNb() { +int NbAnalogIn::read() { while(write_pos == read_pos); int result = buffer[read_pos]; - printf("MAIN: read %d from pos %d\n",buffer[read_pos], read_pos ); + //printf("NbAnalogIn::readNb(c%d): read %d from pos %d\n", channel, buffer[read_pos], read_pos ); read_pos = pos_inc( read_pos ); // increment reading position - - return result; } \ No newline at end of file