test program to power up two MAX11410 ADCs and check the inputs of ADC1. Uses MAX11410 library.

Dependencies:   mbed MAX11410

Fork of MAX11410-test by Dan Allen

main.cpp

Committer:
laserdad
Date:
2019-03-21
Revision:
17:f051190b4bff
Parent:
16:d25147dfdd5c

File content as of revision 17:f051190b4bff:

#include "mbed.h"
#include "MAX11410.h"

#define CS1 D9
#define CS2 D10
#define MOSI_1 D11
#define MISO_1 D12
#define SCLK_1 D13
#define VDD 3.3
#define NUM_AVGS 10 //this is for the IIR and AVG filters
#define NUM_CHANNELS 10
#define NUM_FILTER_TAPS 18 //this is for the FIR filter


AnalogOut vOut1(A3);
AnalogOut vOut2(A4);
DigitalOut cs_pin1(CS1);
DigitalOut cs_pin2(CS2);
SPI spi(MOSI_1, MISO_1, SCLK_1);
MAX11410 adc1(&spi,&cs_pin1);
MAX11410 adc2(&spi,&cs_pin2);
Serial pc(USBTX, USBRX,115200);
//Serial pc(USBTX, USBRX, 9600);
Serial rpi(PA_9,PA_10,115200);
Timer t;

int32_t channel_data[NUM_CHANNELS] = {0,0,0,0,0,0,0,0,0,0};
int32_t new_data = 0;;
int32_t avg_data[NUM_CHANNELS];
int32_t data_buffer[NUM_CHANNELS][10];
int32_t data_sum[NUM_CHANNELS];
int32_t ind = 0;
int num_samples = 0;
int num_avgs = NUM_AVGS;
int ptr =0;

void starting()
{
    pc.printf("this program has started\r\n");
}


char getNthByte(int32_t data, int ind)
{
    return (data>>(8*ind)) & 0x000000FF ;
}


void print8bitRegsAdc1(char start_reg,char end_reg)
{
    bool int_status;
    char val;
    for(int n=start_reg; n<=end_reg; n++) {
        val = adc1.read8bits(n,&int_status);
        pc.printf("reg %02x, val =%02x\r\n",n,val);
    }
}

void print8bitRegsAdc2(char start_reg,char end_reg)
{
    bool int_status;
    char val;
    for(int n=start_reg; n<=end_reg; n++) {
        val = adc2.read8bits(n,&int_status);
        pc.printf("reg %02x, val =%02x\r\n",n,val);
    }
}


void get_avgs()
{
    if (num_samples < num_avgs) {
        num_samples++; //increment number of samples
    } else {
        for (int n = 0; n<NUM_CHANNELS; n++) { //loop over channels
            data_sum[n] -= data_buffer[n][ptr]; //subtract oldest sample
        }
    }
    for (int n=0; n<NUM_CHANNELS; n++) {
        data_buffer[n][ptr] = channel_data[n]; //put new sample in buffer
        data_sum[n] += channel_data[n]; //add new sample
        avg_data[n] = data_sum[n] / num_avgs; //get new average
    }
    ptr++; //increment pointer
    if (ptr == num_avgs) {
        ptr = 0; //reset pointer
    }
}

float filter_buffer[NUM_CHANNELS][NUM_FILTER_TAPS];
//float lpf[NUM_FILTER_TAPS] = {
//    0.066753767,
//    0.288003606,
//    0.489209110,
//    0.333448254,
//    -0.066620544,
//    -0.194774726,
//    0.013641767,
//    0.112606208,
//    -0.010259249,
//    -0.061377259,
//    0.011435200,
//    0.029613752,
//    -0.007630463,
//    -0.008933779,
//    0.005065228,
//    993.16906E-6,
//    -0.001594816,
//    420.77505E-6
//};
//float lpf[NUM_FILTER_TAPS] = {
// 0.261120009762270400,
// 0.577407043230469430,
// 0.318153169307452854,
//-0.102856989837421975,
//-0.077312734575000375,
// 0.025405207067910347,
//-0.001960444494723064,
// 44.73953904209371050E-6};
//float lpf[NUM_FILTER_TAPS] = {
// 0.074209685703864631,
// 0.218596393892535157,
// 0.322579925396349776,
// 0.274804773971007665,
// 0.121138454342240451,
// 0.004556618102039918,
//-0.017928065442454785,
// 0.002042214034417321
//} ;
//float lpf[NUM_FILTER_TAPS] = {
// 0.021922032288610106,
// 0.092023100339809011,
// 0.202378776983641817,
// 0.290407730540869380,
// 0.283915707651621163,
// 0.175369892196639704,
// 0.037613514962477279,
//-0.044492932416232721,
//-0.049124217289769172,
//-0.017864664397846109,
// 0.003294185403418759,
// 0.004556873736760698
//};
//
////.64Hz 12 tap Kaiser min phase
//float lpf[NUM_FILTER_TAPS] = {
// 0.028436833059871377,
// 0.091256389686655018,
// 0.176613000083015115,
// 0.242496965064841336,
// 0.245802310397899182,
// 0.179348609303905254,
// 0.080910192685212115,
// 0.002992553404179661,
//-0.027308910150182431,
//-0.020673186464630775,
//-0.004453426075815317,
// 0.004578669005049506
//};

//0.8Hz 12 tap Kaiser min phase
//float lpf[NUM_FILTER_TAPS] = {
// 0.021922032288610106,
// 0.092023100339809011,
// 0.202378776983641817,
// 0.290407730540869380,
// 0.283915707651621163,
// 0.175369892196639704,
// 0.037613514962477279,
//-0.044492932416232721,
//-0.049124217289769172,
//-0.017864664397846109,
// 0.003294185403418759,
// 0.004556873736760698
//};

//0.48Hz 18 tap Kaiser min phase
float lpf[NUM_FILTER_TAPS] = {
 0.009102526098895891,
 0.028984102676961963,
 0.062642522588951172,
 0.106483963299688053,
 0.150349565029814058,
 0.180469040434368927,
 0.185261380809190523,
 0.161071159985581691,
 0.114518186128496568,
 0.059873816731079298,
 0.012753827718163288,
-0.016437685391431933,
-0.025878490374639303,
-0.021158078277756509,
-0.010912787629287718,
-0.002164072430294558,
 0.002163269630415508,
 0.002877752971803134
};


void iir() {
    for (int channel = 0; channel< NUM_CHANNELS; channel++) {
        avg_data[channel] += (channel_data[channel]-avg_data[channel])/NUM_AVGS;
    }   
}


void fir( ) {
    int coef_ptr;
    float filtered_data;
    for (int channel = 0; channel<NUM_CHANNELS; channel++) {
        coef_ptr = ptr;
        filter_buffer[channel][coef_ptr] = channel_data[channel];
        filtered_data = 0;
        if (num_samples < NUM_FILTER_TAPS) {
            num_samples++;
            avg_data[channel] = channel_data[channel];
        } else {//run the filter if we have enough samples
            for(uint8_t n=0; n<NUM_FILTER_TAPS; n++) {
                //            pc.printf("x = %d\r\n",(*x)[channel][ptr]);
                filtered_data += lpf[n]*(float)filter_buffer[channel][coef_ptr]; //incrementing throught the coeficients as we go back through samples.
                if (coef_ptr==0) {
                    coef_ptr = NUM_FILTER_TAPS-1; //wrap index
                } else {
                    coef_ptr--;
                }
            }
            avg_data[channel] = (int32_t)filtered_data;
        }
    }
    ptr++; //increment filter buffer
    if (ptr == NUM_FILTER_TAPS) {//loop buffer pointer index
        ptr = 0;
    }
}



int main()
{

//    int32_t channel_data2[NUM_CHANNELS];





    int32_t checksum2 =0;
    int32_t checksum = 0;
    char checksum_byte = 0;
    char byte2print[40];
    double vdiff=0.01;
    vOut1 = 0.5-vdiff/2;
    vOut2 = 0.5+vdiff/2;
    starting();

    bool int_state;
    spi.format(8,MAX11410_SPI_MODE); //configure number of spi bits 8, 16
    spi.frequency(8000000); // Max 8MHz
    //read chip ID

    pc.printf("chip ID %d\r\n",adc1.read8bits(REG_PART_ID,&int_state) );

    //config ADC 1
    adc1.reset(); //POR chip 1
    adc2.reset(); //POR chip 2

    //check default register configs
    pc.printf("default regs for ADC1\r\n");
    print8bitRegsAdc1(REG_PD,REG_WAIT_START);

    pc.printf("default regs for ADC2\r\n");
    print8bitRegsAdc2(REG_PD,REG_WAIT_START);

    //config interrupts, PGA, Buffer, polarity, reference
    char mode_config = MODE_NORMAL;
    adc1.write8bitReg(REG_PD,mode_config);      //got to normal mode
    adc2.write8bitReg(REG_PD,mode_config);      //got to normal mode

    char filter_config = FIR_SIXTY | _RATE(5) ; //five is the max at 35.6 sps
    adc1.write8bitReg( REG_FILTER,filter_config );
    adc2.write8bitReg( REG_FILTER,filter_config );

    char ctrl_config = INT_CLOCK | BIPOLAR | TWOS_COMP | _PBUF_EN(0) | _NBUF_EN(0) | REF_AVDD ; //ADC configuration
    adc1.write8bitReg( REG_CTRL, ctrl_config );
    adc2.write8bitReg( REG_CTRL, ctrl_config );

    char source_config = VBIAS_ACTIVE | BRN_OFF | _IDAC(0); //not sourcing current
    adc1.write8bitReg( REG_SOURCE,source_config );
    adc2.write8bitReg( REG_SOURCE,source_config );

    uint32_t status_ie_config = DATA_RDY_INT | CAL_RDY_INT | CONV_RDY_INT;
    adc1.write24bitReg(REG_STATUS_IE,status_ie_config);
    adc2.write8bitReg( REG_SOURCE,source_config );

    char gain_setting = 0;
    char pga_config = PGA | _GAIN_EXP(gain_setting) ; //no gain
    adc1.write8bitReg(REG_PGA,pga_config);
    adc2.write8bitReg(REG_PGA,pga_config);

    pc.printf("PGA gain = %d\r\n",1<<gain_setting);

    //check register writes
    pc.printf("checking register writes ADC1\r\n");
    pc.printf("reg %02x, val %02x, set to %02x\r\n",REG_PD,adc1.read8bits(REG_PD,&int_state),mode_config);
    pc.printf("reg %02x, val %02x, set to %02x\r\n",REG_FILTER,adc1.read8bits(REG_FILTER,&int_state),filter_config);
    pc.printf("reg %02x, val %02x, set to %02x\r\n",REG_CTRL,adc1.read8bits(REG_CTRL,&int_state),ctrl_config);
    pc.printf("reg %02x, val %02x, set to %02x\r\n",REG_SOURCE,adc1.read8bits(REG_SOURCE,&int_state),source_config);
    pc.printf("reg %02x, val %06x, set to %06x\r\n",REG_STATUS_IE,adc1.read24bits(REG_STATUS_IE,&int_state),status_ie_config);
    pc.printf("reg %02x, val %02x, set to %02x\r\n",REG_PGA,adc1.read8bits(REG_PGA,&int_state),pga_config);
    pc.printf("checking register writes ADC2\r\n");
    pc.printf("reg %02x, val %02x, set to %02x\r\n",REG_PD,adc2.read8bits(REG_PD,&int_state),mode_config);
    pc.printf("reg %02x, val %02x, set to %02x\r\n",REG_FILTER,adc2.read8bits(REG_FILTER,&int_state),filter_config);
    pc.printf("reg %02x, val %02x, set to %02x\r\n",REG_CTRL,adc2.read8bits(REG_CTRL,&int_state),ctrl_config);
    pc.printf("reg %02x, val %02x, set to %02x\r\n",REG_SOURCE,adc2.read8bits(REG_SOURCE,&int_state),source_config);
    pc.printf("reg %02x, val %06x, set to %06x\r\n",REG_STATUS_IE,adc2.read24bits(REG_STATUS_IE,&int_state),status_ie_config);
    pc.printf("reg %02x, val %02x, set to %02x\r\n",REG_PGA,adc2.read8bits(REG_PGA,&int_state),pga_config);


    pc.printf("beginning while loop\r\n");
    wait_ms(1000);
    t.start();
    while(1) {
        for(int n=0; n<5; n++) {
            //setup ADCs to read in parallel
            //select channel
            char p_ch = 2*n+1<<4;
            char n_ch = 2*n;
            adc1.write8bitReg(REG_MUX_CTRL0, p_ch | n_ch );
            adc2.write8bitReg(REG_MUX_CTRL0, p_ch | n_ch );

            //select data output register and begin conversion
            adc1.write8bitReg(REG_CONV_START, (_DEST(n) | SINGLE_CONV) );
            adc2.write8bitReg(REG_CONV_START, (_DEST(n) | SINGLE_CONV) );

            //optional: cal Gain

            //optional: cal Offset

            //optional: store cal parameters

            //begin conversion

            //wait for interrupt
            while(!adc1.interrupt() ) {
                wait_ms(CONV_DELAY_MS);//do nothing
//                pc.printf("waiting for int");
            }
            if  (channel_data[n] == 0) {
                channel_data[n] = adc1.read24bitsSigned(REG_DATA0+n,&int_state);
            } else {
                new_data = adc1.read24bitsSigned(REG_DATA0+n,&int_state);
//                channel_data[n] += (new_data-channel_data[n])/filterdiv;
                channel_data[n] = new_data;
            }
            while(!adc2.interrupt() ) {
                wait_ms(CONV_DELAY_MS);//do nothing
//                pc.printf("waiting for int");
            }
            //read conversion
            if  (channel_data[n+5] == 0) {
                channel_data[n+5] = adc2.read24bitsSigned(REG_DATA0+n,&int_state);
            } else {
                new_data = adc2.read24bitsSigned(REG_DATA0+n,&int_state);
                //channel_data[n+5] += (new_data-channel_data[n+5])/filterdiv;
                channel_data[n+5] = new_data;
            }
        }
        //            calc checksum
        checksum = 0x66 + 0x01;
//        for (int n=0; n<NUM_CHANNELS; n++)
//        {
//            checksum += channel_data[n];
//        }
//        checksum_byte = (char) checksum;

//****************************************************************************
        get_avgs(); //calculate running average
//        fir(); //run FIR filter on all channels
//        iir();
//****************************************************************************


        
        for (int n=0; n<NUM_CHANNELS; n++) {
            for(int m=0; m<4; m++) {
                byte2print[n*4+m] = getNthByte(avg_data[n],3-m);
                checksum += getNthByte(avg_data[n],3-m);
            }
        }
        checksum_byte = (char) checksum;

        //print data and checksum

        //            print header 0x6601
        rpi.putc(0x66);
        rpi.putc(0x01);
        for (int n =0; n<40; n++) {
            rpi.putc(byte2print[n]);
        }
        rpi.putc( checksum_byte );
//        now reassemble the bits and print them
//
//        for (int n=0;n<NUM_CHANNELS;n++)
//        {
//            channel_data2[n] = (byte2print[4*n]<<24 ) | ( byte2print[4*n+1]<<16 ) | ( byte2print[4*n+2] << 8 ) | byte2print[4*n+3];
//        }
//        pc.printf("orig  reconstructed\r\n");


//        pc.printf("%d, ",t.read_ms());
        for (int n=0; n<NUM_CHANNELS; n++) {
//        for (int n=3; n<7; n++) {
//            pc.printf("%d, %d\r\n",n,avg_data[n]);
            pc.printf("%d, ",avg_data[n]);
//            pc.printf("%d, ",channel_data[n]);
        }
        pc.printf("\r\n");
//        checksum2 = 0;
//        for(int n=0;n<NUM_CHANNELS;n++)
//        {
//            checksum2 += channel_data2[n];
//        }
//        pc.printf("checksum %02X, %08X, %08X\r\n",checksum_byte,checksum,checksum2);
    } //end while

} //END MAIN