SBAS853A January 2020 – April 2021 ADS131M02
PRODUCTION DATA
This section contains example pseudocode for a simple program that configures and streams data from the ADS131M02. The pseudocode is written to resemble C code. The code uses several descriptive precompiler-defined constants that are indicated in upper case. The definitions are not included for brevity. The program works in three sections: MCU initialization, ADC configuration, and data streaming.
The MCU is initialized by enabling the necessary peripherals for this example. These peripherals include an SPI port, a GPIO configured as an input for the ADS131M02DRDY output, a clock output to connect to the ADS131M02 CLKIN input, and a direct memory access (DMA) module that streams data from the SPI port into memory without significant processor intervention. The SPI port is configured to a 24-bit word size because the ADC default SPI word size is 24 bits. The CS pin is configured to remain low as long as the SPI port is busy so that it does not de-assert in the middle of a frame.
The ADC is configured through register writes. A function referred to as adcRegisterWrite writes an ADC register using the SPI peripheral. No CRC data integrity is used in this example for simplicity, but is recommended. The ADC outputs are initially disabled so short frames can be written during initialization consistent with the guidance provided in the Section 8.5.1.11 section. The ADC is configured to output DRDY as pulses, the gain is changed to 32 for channels 1 and 3, and the DC block filter is used with a corner frequency of 622 mHz. Finally, the ADC word size is changed to 32 bits with an MSB sign extension to accommodate the MCU memory length and to allow for 32-bit DMA transfers. All other settings are left as defaults.
Data streaming is performed by using an interrupt that is configured to trigger on a negative edge received on the GPIO connected to the DRDY pin. The interrupt service routine, referred to as DRDYinterrupt, sends six 32-bit dummy words to assert CS and to toggle SCLK for the length of the entire ADC output frame. The ADC output frame consists of one 32-bit status word, four 32-bit ADC conversion data words, and an optional 32-bit CRC word. The frame is long enough for output CRC even though the CRC word is disabled in this example. The DMA module is configured to trigger upon receiving data on the SPI input. The DMA automatically sends the ADC data to a predetermined memory location as soon as the data are shifted into the MCU through the SPI input.
numFrameWords = 4; // Number of words in a full ADS131M02 SPI frame
unsigned long spiDummyWord[numFrameWords] =
{ 0x00000000,
0x00000000,
0x00000000,
0x00000000}; // Dummy word frame to write ADC during ADC data reads
bool firstRead = true; // Flag to tell us if we are reading ADC data for the// first time
signed long adcData; // Location where DMA will store ADC data in memory,
// length defined elsewhere/*
Interrupt the MCU each time DRDY asserts when collecting data
*/
DRDYinterupt(){
if(firstRead){ // Clear the ADC's 2-deep FIFO on the first read
for(i=0; i<numFrameWords; i++){
SPI.write(spiDummyWord + i);
}
for(i=0; i<numFrameWords; i++){
SPI.read();
}
firstRead = false; // Clear the flag
DMA.enable(); // Let the DMA start sending ADC data to memory
}
for (i=0; i<numFrameWords; i++){// Send the dummy data to the ADC to get// the ADC data
SPI.write(spiDummyWord + i);
}
}
/*
adcRegisterWrite
Short function that writes one ADC register at a time. Blocks return until SPI
is idle. Returns false if the word length is wrong.
param
addrMask: 16-bit register address mask
data: data to write
adcWordLength: word length which ADC expects. Either 16, 24 or 32.
return
true if word length was valid
false if not
*/
bool adcRegisterWrite(unsigned short addrMask, unsigned short data,
unsigned char adcWordLength){
unsigned char shiftValue; // Stores the amount of bit shift based on
// ADC word length
if(adcWordLength==16){
shiftValue = 0; // If length is 16, no shift
}else if(adcWordLength==24){
shiftValue = 8; // If length is 24, shift left by 8
}else if(adcWordLength==32){
shiftValue = 16; // If length is 32, shift left by 16
}else{
return false; // If not, invalid length
}
SPI.write((WREG_OPCODE | // Write address and opcode
addrMask) << shiftValue);// Shift to accommodate ADC word length
SPI.write(data << shiftValue);// Write register data
while(SPI.isBusy()); // Wait for data to complete sending
return true;
}
/*
main routine
*/
main(){
enableSupplies();
GPIO.inputEnable('input'); // Enable GPIO connected to DRDY
clkout.enable(8192000); // Enable 8.192 MHz clock to CLKIN
SPI.enable(); // Enable SPI port
SPI.wordLengthSet(24); // ADC default word length is 24 bits
SPI.configCS(STAY_ASSERTED);// Configure CS to remain asserted until frame// is complete
while(!GPIO.read()){} // Wait for DRDY to go high indicating it is ok// to talk to ADC
adcRegisterWrite(CLOCK_ADDR, // Write CLOCK register
ALL_CH_DISABLE_MASK | // Turn off all channels so short// frames can be written during// config
OSR_1024_MASK | PWR_HR_MASK, 24); // Re-write defaults for other bits// in CLOCK register
adcRegisterWrite(MODE_ADDR, // Write MODE register
RESET_MASK | DRDY_FMT_PULSE_MASK | // Clear the RESET flag, make DRDY// active low pulse
WLENGTH_24_MASK | // Re-write defaults for other bits
SPI_TIMEOUT_MASK, 24; // in MODE register
adcRegisterWrite(GAIN1_ADDR, // Write GAIN1 register
PGAGAIN3_32_MASK | // Set channels 1 and 3 PGA gain to
PGAGAIN1_32_MASK, 24); // 32 in this example// Leave channels 0 and 2 at default// gain of 1
adcRegisterWrite(THRSHLD_LSB_ADDR, // Write THRSHLD_LSB register
0x09, 24); // Set DCBLOCK filter to have a// corner frequency of 622 mHz
DMA.triggerSet(SPI);// Configure DMA to trigger when data comes in// on the MCU SPI port
DMA.txAddrSet(SPI.rxAddr());// Set the DMA to take from the incoming SPI
// port
DMA.rxAddrSet(&adcData);// Set the DMA to send ADC data to a predefined
// memory location
adcRegisterWrite(MODE_ADDR, // Write MODE register
WLENGTH_32_SIGN_EXTEND_MASK | // Make ADC word size 32 bits to// accommodate DMA
DRDY_FMT_PULSE_MASK | // Re-write other set bits in MODE
SPI_TIMEOUT_MASK, 24); // register
SPI.wordLengthSet(32); // Set SPI word size to 32 bits to// accomodate DMA
adcRegisterWrite(CLOCK_ADDR, // Write CLOCK register
ALL_CH_ENABLE_MASK | // Turn on all ADC channels
OSR_1024_MASK | PWR_HR_MASK, 32); // Re-write defaults for other bits// in CLOCK register
GPIO.interuptEnable();// Enable DRDY interrupt and begin streaming data
}