I am working on a project using two daisy-chained AD5207 digital potentiometer ICs controlled by the SPI interface of an STM32 micro. I'm following the directions given on P.9 of the AD5207 datasheet, but I am a little confused about how to properly format the serial data, since the AD5207 wants 10 bits of serial information, whereas the SPI hardware port will write bits in multiples of 8, meaning there will be extra unused bits at the beginning or end.
I can think of two ways this could be handled. One is treating each 10-bit packet as a 16-bit write, with 6 blank bits at the beginning or end, and doing two 16-bit writes in a row. Another would be offsetting the two 10-bit packets within 3 8-bit writes, with 4 blank bits at the beginning or end. Please advise which method is correct.
Here is the example code for each scenario. Which is correct?
static void ad5207_write_spi_dual(uint8_t pot, uint8_t val1, uint8_t val2) {
// pot selects pot channel a or b, val1 controls IC 1, val2 controls IC 2
#if 1
// 4 8-bit writes, leading 0's
uint8_t spi_block[4] = { 0, 0, 0, 0 };
spi_block[0] = pot;
spi_block[1] = val2;
spi_block[2] = pot;
spi_block[3] = val1;
#elif 0
// 4 8-bit writes, trailing 0's
uint8_t spi_block[4] = {0, 0, 0, 0};
spi_block[0] = (pot << 6) | (val2 >> 2);
spi_block[1] = (val2 << 6) & 255;
spi_block[2] = (pot << 6) | (val1 >> 2);
spi_block[3] = (val1 << 6) & 255;
#elif 0
// 3 8-bit writes, leading 0's
uint8_t spi_block[3] = {0, 0, 0};
spi_block[0] = (pot << 2) | (val2 >> 6);
spi_block[1] = pot | ((val2 << 2) & 255);
spi_block[2] = val1;
#else
// 3 8 bit writes, trailing 0's
uint8_t spi_block[3] = { 0, 0, 0 };
spi_block[0] = (pot << 6) | (val2 >> 2);
spi_block[1] = (pot << 4) | ((val2 << 6) & 255) | (val1 >> 4);
spi_block[2] = (val1 << 4) & 255;
#endif
HAL_GPIO_WritePin(SPI1_SEL_GPIO_Port, SPI1_SEL_Pin, GPIO_PIN_RESET);
delay(1);
HAL_SPI_Transmit(&hspi1, (uint8_t*) spi_block, sizeof(spi_block), 5);
delay(1);
HAL_GPIO_WritePin(SPI1_SEL_GPIO_Port, SPI1_SEL_Pin, GPIO_PIN_SET);
delay(1);
}
Here is the serial data word format defined by the datasheet, and the daisy chain instructions given on P.9 for reference:
The serial-data-output (SDO) pin contains an open drain n-channel FET. This output requires a pull-up resistor in order to transfer data to the next package’s SDI pin. The pull-up resistor termination voltage may be larger than the VDD supply of the AD5207 SDO output device, e.g., the AD5207 could operate at VDD = 3.3 V and the pull-up for interface to the next device could be set at 5 V. This allows for daisy chaining several RDACs from a single processor serial-data line. The clock period may need to be increased when using a pull-up resistor to the SDI pin of the following devices in series. Capacitive loading at the daisy chain node SDO–SDI between devices may add time delay to subsequent devices. User should be aware of this potential problem in order to successfully achieve data transfer. See Figure 3. When configuring devices for daisy-chaining, the CS should be kept low until all the bits of every package are clocked into their respective serial registers, ensuring that the address bit and data bits are in the proper decoding location. This requires 20 bits of address and data complying with the data word in Table I if two AD5207 RDACs are daisy chained.