Registers and SPI frames¶
What the driver sends over SPI: the 24-bit register frame, the three register banks, the two-frame read and the conversion burst.
Section and table numbers refer to the ADS9324 datasheet (SBASB22). The addresses are
constants in inc/ads9324_registers.hpp (namespace ads9324::reg).
The register frame¶
Every register access is one 24-bit frame, MSB first, CS low for all 24 clocks:
| Bits | 23:16 | 15:0 |
|---|---|---|
| SDI | Register address | 16-bit data |
SDI is latched on the SCLK rising edge; the write is decoded when CS rises (section 7.5.1). reg::PackWrite(addr,
data) builds the frame.
Register banks¶
The 16-bit registers sit in three banks addressed with 8 bits. BANK_SEL (address 0x02) is reachable from every
bank and selects which one later addresses decode in:
BANK_SEL value |
Bank | Holds |
|---|---|---|
0x0001 |
Common | GEN_CFG1 to GEN_CFG5, PDN_CTL, DRDY_ALARM_SEL, ANA_CFG½, ADC_CAL, DEVICE_ID |
0x0002 |
AIN1 to AIN8 | PGA_CONFIG, PGA_BW_SEL, OFS, GAN, DWC registers of channels 1 to 8 |
0x0004 |
AIN9 to AIN16 | The same for channels 9 to 16 |
The two channel banks have the same layout. API channel n (0 to 15) is in bank AIN1-8 when n < 8, with local
index n mod 8 (reg::BankForChannel(), reg::LocalChannel()). The driver writes BANK_SEL only when the bank
changes.
Reading a register¶
A read takes two frames (Table 7-17):
| Frame | SDI[23:16] | SDI[15:0] | SDOUT |
|---|---|---|---|
| 1 | 0x01 (GEN_CFG1) |
REG_ADDR in bits 15:8, REG_RD_EN = 1 in bit 0 | don't care |
| 2 | 0x00 |
0x0000 |
Bits 23:8 = the register's data, bits 7:0 = 0 |
The driver selects the bank first, so a read costs two or three frames. reg::ReadCommand() and
reg::UnpackRegData() build and unpack them.
Registers the driver uses¶
Common bank:
| Address | Name | Driver use |
|---|---|---|
0x01 |
GEN_CFG1 |
SW_RST (bit 1) in SoftwareReset(); register-read command |
0x02 |
BANK_SEL |
Bank selection |
0x08 |
PDN_CTL |
DEVICE_PDN (bit 0) in SetPowerDown() |
0x0A |
GEN_CFG3 |
EN_OFS_BINARY (12), DOUT_LANE_SEL (5:4), DOUT_LENGTH (3:2), ADC_DATA_SDOUT_EN (1) |
0x0C |
DRDY_ALARM_SEL |
ALRM_POL (4), DRDY_ALRM_SEL (3:0) in SetAlarmPin() |
0x10 |
ANA_CFG1 |
REFSEL_CTRL_DIS (1), EXT_REF_EN (0) in SetReference() |
0x11 |
ANA_CFG2 |
ADC_CH_SEL (6:4), ADC_NUM_SEL (3:2) in SetChannelCountMode() |
0x12 |
ADC_CAL |
SE_DIFF_MODE_AIN1_8 (13), SE_DIFF_MODE_AIN9_16 (12), ADC_CAL_TRIG (8), ADC_CAL_MODE (1:0) in RunAdcCalibration() |
0x14 |
DIG_FILTER |
BLK_AVG_OSR (7:4), INT_TRIG_MODE (1), DIG_FILT_SYSREF (0) in SetOversampling() |
0x15 |
GEN_CFG5 |
AVG_MODE_OVR_EN (1), then AVG_MODE (0), before the first SetOversampling() |
0x1D |
DEVICE_STATUS |
CALIB_BUSY_FLAG (3) polled by RunAdcCalibration() |
0x21 |
DEVICE_ID |
Read by ReadDeviceId(); 0x0004 on an ADS9324 |
Channel banks (the same address in AIN1-8 and AIN9-16):
| Address | Name | Driver use |
|---|---|---|
0x08 to 0x0B |
PGA_CONFIG_AINx_y |
Two channels per register, one byte each |
0x0C |
PGA_BW_SEL |
Two bits per channel |
0x11 to 0x18 |
OFS_AINn |
10-bit offset |
0x19 to 0x20 |
GAN_AINn |
14-bit gain |
0x21 |
DWC_CFG |
Window-comparator enable bit per channel |
0x22 to 0x29 |
DWC_TH_AINn |
High threshold (15:8), low threshold (7:0) |
0x37 |
GEN_CFG5 |
OFS_CORR_DIS (1), GAN_CORR_DIS (0) in SetSystemCorrection() |
The other registers (FIR and moving-average filters, phase delay, test patterns)
have addresses in ads9324_registers.hpp but no driver call. PGA and calibration
explains the channel registers.
Initialisation sequence¶
EnsureInitialized() follows Table 7-18, checks the ID, then writes the channel defaults:
| Step | Frame or action | Why |
|---|---|---|
| 1 | Wait 30 ms | Supplies and reference settle (tPU) |
| 2 | BANK_SEL = 0x0001, GEN_CFG1 = 0x0002 |
Software reset; the bank is selected first because GEN_CFG1 is in the common bank and the chip may have kept another bank across an MCU reset |
| 3 | Wait 1 ms | Reset settle |
| 4 | BANK_SEL = 0x0001 |
Common bank |
| 5 | GEN_CFG3 = 0x0032 |
1 lane, 16-bit words, conversion data on SDOUT |
| 6 | Read DEVICE_ID, expect 0x0004 |
Proves SDI, SDOUT, SCLK and CS work |
| 7 | PGA_CONFIG_AINx_y and PGA_BW_SEL of both channel banks |
The CONFIG_ADS9324_* range, input type and bandwidth defaults (Configuration) |
After reset the chip outputs conversion data on eight lanes (D0 to D7), which a plain SPI controller cannot read; step 5 is what makes SDOUT carry it.
The conversion burst¶
After CONVST and DRDY, the driver clocks one CS-low burst with SDI held at zero. Each channel is one word, MSB first, lowest channel first (Figure 5-5):
| Setting | Word | Burst for 16 channels |
|---|---|---|
DoutLength::Bits16 (default) |
16 bits | 32 bytes |
DoutLength::Bits24 |
24 bits; the driver keeps the top 16 | 48 bytes |
With ADC_NUM_SEL set to 8, 4 or 2 channels the burst is shorter and carries the Table 7-12 channel set, for
example AIN1 to AIN4 then AIN13 to AIN16; the driver stores each word under its channel
(API guide).
With the default two's-complement coding, 0 V is 0x0000, the most positive code is 0x7FFF and −FS is 0x8000. In
offset-binary coding midscale is 0x8000; the driver converts it to two's complement, so Snapshot::count is
always signed.