test program to power up two MAX11410 ADCs and check the inputs of ADC1. Uses MAX11410 library.
Fork of MAX11410-test by
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