1
\$\begingroup\$

I am attempting to use the SPI2 peripheral on the STM32L471RG microcontroller in order to communicate with the ADS1234 and wanted to run my thoughts past some of you more experienced firmware developers!

Right now I am using the internal clock of the ADC, so I mainly need to focus on the DRDY/DOUT and SCLK pins. I'm going to have an initialize function that configures the other ADC pins.

The reference manual of the STM32L talks about the different modes of SPI that are possible, which leads to my question(s):

  1. I am planning on using simplex receive with SPI2 - does this mode sound reasonable based on the ADS1234 interface waveforms?
  2. The ADS1234 is 24-bit and the STM32L only goes up to 16-bits in the buffer. My thinking is to configure it for 12-bits and do two transfers, although I'm not sure if this will conflict with anything?
  3. Since using the DRDY function is not completely a part of the SPI protocol, I'm wondering how to have this trigger a data transfer. If the DRDY/DOUT pin state goes from high to low (indicating data is ready) should I configure for an interrupt-on-change (IOC) event and then go into completing a transfer?

Below is the data retrieval waveform of the ADS1234.

ADS1234 data retrieval

Thank you for any help. I'm mainly concerned about the logistics of everything.

\$\endgroup\$

3 Answers 3

1
\$\begingroup\$

I would do it completely other way.

  1. Set SPI2 MISO pin as GPIO input. Set the EXTI (falling edge) interrupt on this pin
  2. In the EXTI interrupt - Disable EXTI, change this pin to the MISO AF, and initiate 3 byte DMA transaction (send 3 dummy bytes as you need to generate clock for the ADS).
  3. In the DMA transfer complete interrupt change pin to the GPIO Input. Enable EXTI

Steps 2 & 3 will automatically repeat on every conversion.

\$\endgroup\$
11
  • \$\begingroup\$ Please excuse my ignorance: what is the AF acronym? \$\endgroup\$
    – Biff
    Commented Nov 13, 2017 at 20:12
  • \$\begingroup\$ Alternate Function - ie this port to act as SPI2 MISO. it is set by setting GPIOx MODER register to alternate mode, and setting the AF registers \$\endgroup\$ Commented Nov 13, 2017 at 20:12
  • \$\begingroup\$ Ah, understood. \$\endgroup\$
    – Biff
    Commented Nov 13, 2017 at 20:33
  • \$\begingroup\$ I should only need DMA for TX, correct? Or should I do full-duplex SPI with DMA1 and two channels for RX and TX? \$\endgroup\$
    – Biff
    Commented Nov 14, 2017 at 9:53
  • \$\begingroup\$ @Biff - DMA for RX, TX you can do DMA or not. \$\endgroup\$ Commented Nov 14, 2017 at 10:46
1
\$\begingroup\$

I am planning on using simplex receive with SPI2 - does this mode sound reasonable based on the ADS1234 interface waveforms?

Yes, you should be able to use a hardware SPI port on the STM32 to communicate with the ADS1234

The ADS1234 is 24-bit and the STM32L only goes up to 16-bits in the buffer. My thinking is to configure it for 12-bits and do two transfers, although I'm not sure if this will conflict with anything?

That will work, you can also set up the buffer for 8 bytes also. At the end of the transfer the buffer will fill up and generate an interrupt (if you set it up that way) which you will need to copy the data out of the buffer before you initiate another transfer.

Since using the DRDY function is not completely a part of the SPI protocol, I'm wondering how to have this trigger a data transfer. If the DRDY/DOUT pin state goes from high to low (indicating data is ready) should I configure for an interrupt-on-change (IOC) event and then go into completing a transfer?

There are two ways you could run the sampling of the ADC1234:

1) initiate an ADC sample and then deterministically wait with a timer or delay the data transfer until you know DRDY has gone low, then initiate a transfer.

2) Do what you suggest and wait for the DRDY to go low with a GPIO port using EXTI on the STM32 then initiate a transfer.

\$\endgroup\$
3
  • \$\begingroup\$ If I wait for DRDY to go low with an EXTI port, I would effectively be using two pins, correct? One for DOUT and another essentially for DRDY with EXTI, both in parallel? \$\endgroup\$
    – Biff
    Commented Nov 13, 2017 at 18:13
  • \$\begingroup\$ @laptop2d EXTI port on the STM32 (not all GPIOS support this) which one do not? EXTI on falling edge (not low level) \$\endgroup\$ Commented Nov 13, 2017 at 19:28
  • \$\begingroup\$ Yes, one for DOUT and one for DRDY. Actually I double checked the EXTI statment and I was wrong, I apologize, I will correct the answer \$\endgroup\$
    – Voltage Spike
    Commented Nov 13, 2017 at 20:21
0
\$\begingroup\$

I have an AD4115 ADC that has the same scheme for notifying the host uC that it's got data ready: it brings MISO/DOUT/~RDY low. I was able to get the STM32 to switch the pin between SPI and GPIO behavior.

void PA6_to_SPI1(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = { 0 };

    GPIO_InitStruct.Pin = GPIO_PIN_6;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

}

void PA6_to_EXTI(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = { 0 };
    GPIO_InitStruct.Pin = GPIO_PIN_6;
    GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

After doing some initialization to setup the AD4115 registers under main() where I need to use the pin as a MISO line, I switch it to EXTI mode. At the next falling edge the ISR will be called

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    if (GPIO_Pin != GPIO_PIN_6) return;

    /* turn PA6 back into a MOSI line */
    PA6_to_SPI1();
    adc_data = ad4115_read_reg(&hspi1, 4, 4);

    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);

    /* PA6 leaves SPI mode and becomes EXTI source */
    PA6_to_EXTI();

}

The ISR turns the pin back into its SPI self, reads out the 32-bit register, the clears any pending interrupts (I actually can't figure out why I need to do this but the ISR kept triggering itself if I didn't do it), then switches back to EXTI.

This is all using straight programmed I/O so about as basic as it comes. I'm only reading out at 1 kHz so currently the overhead is acceptable.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.