Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 5 of 5

Thread: Issue with analog.c

  1. #1
    Senior Member
    Join Date
    Jul 2014
    Posts
    2,157

    Issue with analog.c

    I try to modify resolution and averaging of ADC object but it fails

    Code:
    /*
     * Simple ADC test
     */
    #include "input_adc.h"
    #include "record_queue.h"
    
    #define STEP 0
    
    // GUItool: begin automatically generated code
    AudioInputAnalog         adc1;         //xy=165,237
    AudioRecordQueue         queue1;       //xy=348,308
    AudioConnection          patchCord1(adc1, queue1);
    // GUItool: end automatically generated code
    
    void setup() {
      // put your setup code here, to run once:
    
      AudioMemory (4);
      while(!Serial);
      Serial.println("Start");
    
    #if (STEP ==1)
      Serial.println("change1");
      analogReadRes(10);
      analogReference(INTERNAL); // range 0 to 1.2 volts
      analogReadAveraging(1);
    #endif
      queue1.begin();
    }
    
    void loop() {
      // put your main code here, to run repeatedly:
      static uint32_t count=0;
     if(queue1.available())
     {  // fetch data from queue
        int16_t * data =queue1.readBuffer();
        queue1.freeBuffer(); 
        count++;
     }
     
     static uint32_t t0;
     if(millis()>t0+1000)
     {  Serial.printf("loop: ");
        Serial.printf("%d %d %d\n",count, PDB0_CNT, PDB0_MOD);
        t0=millis();
        count=0;
     }
    }
    compiled as is generates:
    Code:
    Start
    loop: 199 163 1359
    loop: 345 1119 1359
    loop: 345 801 1359
    loop: 345 476 1359
    loop: 345 149 1359
    loop: 345 1184 1359
    loop: 345 895 1359
    loop: 345 563 1359
    loop: 345 220 1359
    which is OK
    first number after loop is number of blocks retrieved from queue, the other two numbers are from PDB

    However, compiled with #define STEP 1, that is with the additional code in setup() to modify ADC setup, the result becomes:
    Code:
    Start
    change1
    loop: 0 1342 1359
    loop: 0 906 1359
    loop: 0 570 1359
    loop: 0 252 1359
    loop: 0 1282 1359
    loop: 0 980 1359
    loop: 0 636 1359
    loop: 0 304 1359
    that is, no buffers are found on queue.

    It seems that the call to the analog.c functions are not always handled correctly and crashed ADC operation.

    Note, I have no problem with generating my own ADC object or use Pelvide's ADC library, but here I wanted to use Audio Library without modifications to the library.

  2. #2
    Senior Member
    Join Date
    Jul 2014
    Posts
    2,157
    Post/Code removed, as not correct
    Last edited by WMXZ; 01-13-2018 at 02:18 PM.

  3. #3
    Senior Member
    Join Date
    Jul 2014
    Posts
    2,157
    Printing out PDC0_CH0S after the calls to analog.c indicates a sequence error
    (according to Manual: )
    Sequence error detected on PDB channel's corresponding pre-trigger. ADCn block can be triggered
    for a conversion by one pre-trigger from PDB channel n. When one conversion, which is triggered by
    one of the pre-triggers from PDB channel n, is in progress, new trigger from PDB channel's
    corresponding pre-trigger m cannot be accepted by ADCn, and ERR[m] is set. Writing 0s to clear the
    sequence error flags.
    commenting the "analogReadRes(10);" line or equivalently setting resolution to 16 (function in analog.c will skip)
    PDB sequence error will not show up and results are as expected.

    Edit, but not always
    Last edited by WMXZ; 01-13-2018 at 02:43 PM.

  4. #4
    Senior Member+ Theremingenieur's Avatar
    Join Date
    Feb 2014
    Location
    Colmar, France
    Posts
    2,385
    Since you use the ADC object from the audio library, I think it is not a good idea to try to modify it with external or standard functions since at a first glance, one doesn’t know how the ADC parameters are handled and set inside that object.
    If I were you, I’d clone the ADC input object first and then add the needed additional member vars and functions directly to that object to get a clean code and clean functioning.

  5. #5
    Senior Member
    Join Date
    Jul 2014
    Posts
    2,157
    Quote Originally Posted by Theremingenieur View Post
    Since you use the ADC object from the audio library, I think it is not a good idea to try to modify it with external or standard functions since at a first glance, one doesnt know how the ADC parameters are handled and set inside that object.
    If I were you, Id clone the ADC input object first and then add the needed additional member vars and functions directly to that object to get a clean code and clean functioning.
    Well,
    I know and I have my own set of libraries, that are tuned to the application I'm interested in.
    Custom software has, unfortunately, the drawback of not to being very usable outside the original context.

    Meanwhile, I found a work around of the problem (reading some threads on the NXP forum)

    it does not solve the problem with the calls to the functions in analog.c but it is a possible solution.

    The code is nearly identical to the code in analog.c, with the exception that after setting ADC0 there is no calibration.
    I do not know if this is needed, but I wanted first I code that seems to work.

    Obviously, this mods are part of a larger program, which I will present shortly.

    Anyhow, here comes the work around.


    Code:
    /*
     * Simple ADC test modified
     */
    #include "input_adc.h"
    #include "record_queue.h"
    
    #define STEP 1
    
    // GUItool: begin automatically generated code
    AudioInputAnalog         adc1;         //xy=165,237
    AudioRecordQueue         queue1;       //xy=348,308
    AudioConnection          patchCord1(adc1, queue1);
    // GUItool: end automatically generated code
    
    /*
     * ---------------------------------------------------------------------- 
     * following Mark Butcher: https://community.nxp.com/thread/434148
     * code does not do calibration, so improvements are possible
     */
     void modifyADC(int16_t res, uint16_t avg)
     {
    #if (F_BUS==60000000)
      #define ADC_CFG1_16BIT  ADC_CFG1_ADIV(2) + ADC_CFG1_ADICLK(1) // 7.5 MHz
      #define ADC_CFG1_12BIT  ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(1) // 15 MHz
      #define ADC_CFG1_10BIT  ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(1) // 15 MHz
      #define ADC_CFG1_8BIT   ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(1) // 15 MHz
    #else
      #error "F_BUS must be 60 MHz, please adjust"
    #endif
    
    // stop PDB
      PDB0_CH0C1 = 0;   // disable ADC triggering
      PDB0_SC &= ~PDB_SC_PDBEN;
      //
      if(res==16)
      {
    //  analogReadRes(16);
        ADC0_CFG1 = ADC_CFG1_16BIT + ADC_CFG1_MODE(3) + ADC_CFG1_ADLSMP;
        ADC0_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(2);
      }
      else if(res==12)
      {
    //  analogReadRes(12);
        ADC0_CFG1 = ADC_CFG1_12BIT + ADC_CFG1_MODE(2) + ADC_CFG1_ADLSMP;
        ADC0_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(2);
      }
      else if(res==10)
      {
    //  analogReadRes(10);
        ADC0_CFG1 = ADC_CFG1_10BIT + ADC_CFG1_MODE(2) + ADC_CFG1_ADLSMP;
        ADC0_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(3);
      }
      else if(res==8)
      {
    //  analogReadRes(8);
        ADC0_CFG1 = ADC_CFG1_8BIT + ADC_CFG1_MODE(0);
        ADC0_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(3);
      }
    
    //  analogReference(INTERNAL); // range 0 to 1.2 volts
        ADC0_SC2 = ADC_SC2_REFSEL(1);
    
    //  analogReadAveraging(4);
      if (avg <= 1) {
        ADC0_SC3 = 0;  // begin cal
      } else if (avg <= 4) {
        ADC0_SC3 = ADC_SC3_AVGE + ADC_SC3_AVGS(0);
      } else if (avg <= 8) {
        ADC0_SC3 = ADC_SC3_AVGE + ADC_SC3_AVGS(1);
      } else if (avg <= 16) {
        ADC0_SC3 = ADC_SC3_AVGE + ADC_SC3_AVGS(2);
      } else {
        ADC0_SC3 = ADC_SC3_AVGE + ADC_SC3_AVGS(3);
      }
    //
        ADC0_SC2 |= ADC_SC2_ADTRG | ADC_SC2_DMAEN;  // reassert HW trigger
    
    // restart PDB
      (void)ADC0_RA;
      PDB0_CH0C1 = 0x0101;
      PDB0_SC |= PDB_SC_PDBEN ;
      PDB0_SC |= PDB_SC_SWTRIG ;  // kick off the PDB* - just once  
     }
    
    void setup() {
      // put your setup code here, to run once:
    
      AudioMemory (10);
      while(!Serial);
      Serial.println("Start");
    
    #if (STEP ==1)
      Serial.println("change1");
      modifyADC(10,1);
    #endif
    
      queue1.begin();
    }
    
    void loop() {
      // put your main code here, to run repeatedly:
      static uint32_t count=0;
     if(queue1.available())
     {  // fetch data from queue
        int16_t * data =queue1.readBuffer();
        queue1.freeBuffer(); 
        count++;
     }
     
     static uint32_t t0;
     if(millis()>t0+1000)
     {  Serial.printf("loop: ");
        Serial.printf("%d %d %d %d\n",AudioMemoryUsageMax(),count, PDB0_CNT, PDB0_MOD);
        t0=millis();
        count=0;
        AudioMemoryUsageMaxReset();
     }
    }
    result:
    Code:
    Start
    change1
    loop: 2 199 1170 1359
    loop: 2 345 795 1359
    loop: 2 345 489 1359
    loop: 2 345 115 1359
    loop: 2 345 1146 1359
    loop: 2 345 831 1359

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •