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

Revision:
1:2666729acca1
Parent:
0:058d32b78e5d
Child:
2:336af413f75c
--- a/NbAnalogIn.cpp	Mon Mar 27 11:35:25 2017 +0000
+++ b/NbAnalogIn.cpp	Sun Apr 02 11:16:24 2017 +0000
@@ -1,8 +1,26 @@
 #include "NbAnalogIn.h"
 
+static inline int pos_inc(int i) {
+    
+    if (i < ADC_BUF_SIZE - 1) {
+        i++;
+    } else {
+        i = 0;
+    }    
+    return i;  
+}
+
+NbAnalogIn* NbAnalogIn::handlers[2] = {0};
+
 NbAnalogIn::NbAnalogIn(){
     
     NVIC_EnableIRQ(ADC_IRQn);
+    NVIC_SetVector(ADC_IRQn, (uint32_t)irq);
+    
+    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
     
     LPC_SC->PCONP |= (1 << 12); // turn power for ADC on
     
@@ -25,7 +43,8 @@
     // select 4, clkdiv = 7, enable, don't start yet
     LPC_ADC->ADCR  = (1 << 4) | (7 << 8) | (1 << 21) | (0 << 24) ;
     
-    printf("constructed \n");
+    
+
     
 }
 
@@ -43,9 +62,66 @@
     return (unsigned int)((LPC_ADC->ADGDR >> 4) & 0xFFF);
 }
 
-void NbAnalogIn::readNb(){
+void NbAnalogIn::triggerConv() {
     /* enable interrupts */
     LPC_ADC->ADINTEN = (1 << 4);
     
     LPC_ADC->ADCR  |= (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);
+    
+    /** for debug *///
+    static int count = 0;    
+    adc_result = count++;    
+    printf("NB! channel %d, result %d \n",channel, adc_result);
+    
+    
+    // call the right channel's handler
+    handlers[0]->handler(adc_result);
+    
+    
+    /* disable interrupt */
+    LPC_ADC->ADINTEN &= ~(1 << channel);   
+}
+
+void NbAnalogIn::handler( int adc_result ) {
+    
+    
+    buffer[write_pos] = adc_result;
+    
+    printf("ADC: %d written into pos %d \n",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("ADC: w=%d, r=%d \n", write_pos, read_pos);
+
+    
+}
+
+bool NbAnalogIn::readable() {
+    return  write_pos != read_pos;
+}
+
+int NbAnalogIn::readNb() {
+    
+    while(write_pos == read_pos);
+    
+    int result = buffer[read_pos];
+    
+    printf("MAIN: read %d from pos %d\n",buffer[read_pos], read_pos );
+    
+    read_pos = pos_inc( read_pos ); // increment reading position
+    
+    
+    
+    return result;
 }
\ No newline at end of file