void InitADC(void) { unsigned char cmd[2]; unsigned char txBuf[ADC_COUNT * 2]; // First byte = read cmd, rest = garbage // Ensure that we get a FULL RESET (> 1.2 uS) since InitIO call put us in reset DEASSERT_ADC_RESET; // First real CONVST must wait 15 mS AFTER the reset is De-asserted __delay_cycles(DELAY_100US); // SW Mode Sequencer Configuration Steps(From ADS8686S manual section 7.4.2.5.2) // Step 1: Program the Analog Input range for each channel. We use A0-A4 & B0 - B4. // All channels use a 10 V range which is the default range. So no additional init is required. // Step 2: Program the sequencer stack registers to selectc sequence channels // Seq_stk_0 is already ADC_CH_A0 & ADC_CH_B0 after reset // configure the ADC_REG_SEQ_STK_0 cmd[0] = ADC_WRITE + ADC_REG_SEQ_STK_0; cmd[1] = (ADC_CH_A0 + ADC_CH_B0 ); gpSpiTxBuf = cmd; WriteGPSPI(GS_BLD_ADC); // Write the Register // Start by configuring the ADC_REG_SEQ_STK_1 cmd[0] = ADC_WRITE + ADC_REG_SEQ_STK_1; cmd[1] = (ADC_CH_A1 + ADC_CH_B1 ); gpSpiTxBuf = cmd; WriteGPSPI(GS_BLD_ADC); // Write the Register // configure the ADC_REG_SEQ_STK_2 cmd[0] = ADC_WRITE + ADC_REG_SEQ_STK_2; cmd[1] = (ADC_CH_A2 + ADC_CH_B2 ); gpSpiTxBuf = cmd; WriteGPSPI(GS_BLD_ADC); // Write the Register // configure the ADC_REG_SEQ_STK_3 cmd[0] = ADC_WRITE + ADC_REG_SEQ_STK_3; cmd[1] = (ADC_CH_A3 + ADC_CH_B3 ); gpSpiTxBuf = cmd; WriteGPSPI(GS_BLD_ADC); // Write the Register // configure the ADC_REG_SEQ_STK_4. Note CH_A4 is not used. // Step 3: Add the SSREN marker for the last sequence cmd[0] = ADC_WRITE + ADC_REG_SEQ_STK_4 + SSREN; cmd[1] = (ADC_CH_A_AAAA + ADC_CH_B4 ); // Note that A4 is used as a test input gpSpiTxBuf = cmd; WriteGPSPI(GS_BLD_ADC); // Write the Register // Step 4: Set SEQEN in the config register cmd[0] = ADC_WRITE + ADC_REG_CONFIG; cmd[1] = SEQEN + OSR_2 + BURSTEN; gpSpiTxBuf = cmd; gpSpiTxCount = 2; WriteGPSPI(GS_BLD_ADC); // Step 5A: Provide a dummy CONVST pulse ASSERT_CONVST; txBuf[0] = ADC_READ; // Adding an instruction inbetween to ensure CONVST pulse is long enough gpSpiTxBuf = txBuf; DEASSERT_CONVST; while(P2IN_bit.P2IN6); // Wait till conv completes. // Step 6: Assert another CONVST then read back the conversion results ASSERT_CONVST; gpSpiRxBuf = adcResults; // Adding an instruction inbetween to ensure CONVST pulse is long enough gpSpiRxCount = (ADC_COUNT * 2); DEASSERT_CONVST; while(P2IN_bit.P2IN6); // Wait till conv completes. ReadGPSPI(GS_BLD_ADC); // Reading all 5 sequences in BURST mode // Look for unexpected results if ( (adcResults[16] != 0xAA) || (adcResults[17] != 0xAA)) __no_operation(); // For Debug breakpoint only } // This is the example of ADC reading with 2 CONVST pulses. Normally only one CONVST is applied. void ReadADCs(void) { unsigned char txBuf[ADC_COUNT * 2]; // First byte = read cmd, rest = garbage readADCError = false; ASSERT_CONVST; // Conversion starts at the CONVST rising edge gpSpiRxCount = (ADC_COUNT * 2); // Put other instructions here while converting gpSpiRxBuf = adcResults; DEASSERT_CONVST; while(P2IN_bit.P2IN6); // Wait till conv completes. (BUSY pin) // CONVST needs to stay asserted only 50 nS. Measured to stay asserted for at // least 275 nS with the one instruction inbetween ASSERT_CONVST; // Conversion starts at the CONVST rising edge txBuf[0] = ADC_READ;; gpSpiTxBuf = txBuf; // Contents of TXBuf can remain garbage. DEASSERT_CONVST; while(P2IN_bit.P2IN6); // Wait till conv completes. ReadGPSPI(GS_BLD_ADC); // Call the SPI IO handler with SPI CH name // Look for unexpected results if ( (adcResults[16] != 0xAA) || (adcResults[17] != 0xAA)) { memset(adcResults, 0x00, ADC_COUNT * 2); readADCError = true; } __no_operation(); // For Debug breakpoint only } //////////////////////////////////////////////////////////////////////////// // The header file contents: // ADS8686 ADC Register definitions #define ADC_READ (0x00) #define ADC_WRITE (0x80) #define ADC_REG_CONFIG (0x02 <<1) #define ADC_REG_CH_SEL (0x03 <<1) #define ADC_REG_RNG_A1 (0x04 <<1) #define ADC_REG_RNG_A2 (0x05 <<1) #define ADC_REG_RNG_B1 (0x06 <<1) #define ADC_REG_RNG_B2 (0x07 <<1) #define ADC_REG_STATUS (0x08 <<1) #define ADC_REG_ORS_A (0x0A <<1) #define ADC_REG_LPF_CONF (0x0D <<1) #define ADC_REG_DEV_ID (0x10 <<1) #define ADC_REG_SEQ_STK_0 (0x20 <<1) #define ADC_REG_SEQ_STK_1 (0x21 <<1) #define ADC_REG_SEQ_STK_2 (0x22 <<1) #define ADC_REG_SEQ_STK_3 (0x23 <<1) #define ADC_REG_SEQ_STK_4 (0x24 <<1) #define ADC_REG_SEQ_STK_5 (0x25 <<1) #define ADC_REG_SEQ_STK_6 (0x26 <<1) #define ADC_REG_SEQ_STK_7 (0x27 <<1) #define ADC_REG_SEQ_STK_8 (0x28 <<1) #define ADC_REG_SEQ_STK_9 (0x29 <<1) #define ADC_REG_SEQ_STK_10 (0x2A <<1) #define ADC_IN_RNG_2P5 0x01 // +- 2.5 V Range #define ADC_IN_RNG_5 0x02 // +- 5 V Range #define ADC_IN_RNG_10 0x03 // +- 10 V Range // ADC_REG_SEQ_STK_? Regs: #define ADC_CH_A0 0x00 #define ADC_CH_A1 0x01 #define ADC_CH_A2 0x02 #define ADC_CH_A3 0x03 #define ADC_CH_A4 0x04 #define ADC_CH_A5 0x05 #define ADC_CH_A6 0x06 #define ADC_CH_A7 0x07 #define ADC_CH_B0 0x00 #define ADC_CH_B1 0x10 #define ADC_CH_B2 0x20 #define ADC_CH_B3 0x30 #define ADC_CH_B4 0x40 #define ADC_CH_B5 0x50 #define ADC_CH_B6 0x60 #define ADC_CH_B7 0x70 #define ADC_CH_A_AVDD 0x08 #define ADC_CH_B_AVDD 0x80 #define ADC_CH_A_ALDO 0x09 #define ADC_CH_B_ALDO 0x90 #define ADC_CH_A_AAAA 0x0B #define ADC_CH_B_5555 0xB0 #define SSREN 0x01 //Config Reg: #define SDEF 0x80 #define BURSTEN 0x40 #define SEQEN 0x20 // Bits 4-2: OSR #define OSR_0 (0x00 <<2) // No oversampling / OS Disbaled #define OSR_2 (0x01 <<2) #define OSR_4 (0x02 <<2) #define OSR_8 (0x03 <<2) #define OSR_16 (0x04 <<2) #define OSR_32 (0x05 <<2) #define OSR_64 (0x06 <<2) #define OSR_128 (0x07 <<2) #define STATUSEN 0x02 #define CRCEN 0x01 // The ADC sequence conversion order #define AIN_0A 0 #define AIN_0B 1 #define AIN_1A 2 #define AIN_1B 3 #define AIN_2A 4 #define AIN_2B 5 #define AIN_3A 6 #define AIN_3B 7 #define AIN_4A 8 #define AIN_4B 9