Fast AnalogIn module which asks for a single non blocking reading and causes and interrupt when done.

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