1 year, 4 months ago.

3wire spi on a STM32F767

Hello, I'm trying to use 3 wire SPI to communicate with an AD clock distributor, not that that should matter. The chip requires 3 bytes for read/write operations, and I am trying to confirm that I can read/write to a register. I am not to the point of trying to communicate with the chip yet, as I am having a problem with the read/write commands. For my ease of understanding, I structure the write commands in the following way:

  HAL_SPI_Transmit(&spi, &first_8_bits, 1, 10);
  HAL_SPI_Transmit(&spi, &second_8_bits, 1, 10);
  HAL_SPI_Transmit(&spi, &value, 1, 10);

this seems to work. However, in trying to read:

  HAL_SPI_Transmit(&spi_dds, &first_8_bits, 1, 10);
  HAL_SPI_Transmit(&spi_dds, &second_8_bits, 1, 10);
  HAL_SPI_Transmit(&spi_dds, &null_bits, 1, 10);
  HAL_SPI_Receive(&spi_dds, value, 1, 10);

I find that seemingly the receive command is blocking, and this thread of my program never continues. I do the chip selection manually with a DigitalOut. If I change the configuration of the SPI bus to SPI_DIRECTION_2LINES, it all seems to work, but of course it is not 3 wire, as I understand it.

This is how I configure the GPIO/SPI in an attempt to use 3 wire.

  HAL_SPI_MspInit(&spi);
  __SPI1_CLK_ENABLE();

  GPIO_InitTypeDef GPIO_InitStruct;

  // MOSI PD_7
  __GPIOD_CLK_ENABLE();
  GPIO_InitStruct.Pin       = GPIO_PIN_7;
  GPIO_InitStruct.Mode      = STM_MODE_AF_PP;
  GPIO_InitStruct.Pull      = GPIO_NOPULL;
  GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_LOW;
  GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
  HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

  // Clock PA_5
  __GPIOA_CLK_ENABLE();
  GPIO_InitStruct.Pin       = GPIO_PIN_5;
  GPIO_InitStruct.Mode      = STM_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);

  spi_dds.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_128;
  spi_dds.Init.Direction = SPI_DIRECTION_1LINE;
  spi_dds.Init.CLKPhase = SPI_PHASE_1EDGE;
  spi_dds.Init.CLKPolarity = SPI_POLARITY_LOW;
  spi_dds.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  spi_dds.Init.CRCPolynomial = 7;
  spi_dds.Init.DataSize = SPI_DATASIZE_8BIT;
  spi_dds.Init.FirstBit = SPI_FIRSTBIT_MSB;
  spi_dds.Init.NSS = SPI_NSS_HARD_OUTPUT;
  spi_dds.Init.TIMode = SPI_TIMODE_DISABLE;
  spi_dds.Init.Mode = SPI_MODE_MASTER;

  __HAL_SPI_DISABLE(&spi);

  if (HAL_SPI_Init(&spi) != HAL_OK) {
    error("Cannot initialize SPI");
  }

  __HAL_SPI_ENABLE(&spi);

I think what I'm trying to do should be supported by this abstraction (HAL), so hopefully it's an oversight on my part. Any help would be greatly appreciated.

1 Answer

1 year, 4 months ago.

Uggh...why use ST HAL for this? Just use the mbed SPI interface. Configure it for the speed and which pins you are using.

Here is a snip from my code that works great for the same thing. I preload my array with the commands I want to send

    //Now send updated Bit stream to SPI bus
    for(ii = 3; ii >= 0; ii--)
    RxBuf[ii]=Spi_myDev.write(SR[ii]);
...
  //Toggle the chip select
...

To my knowledge, embed does not support 3wire. If I am wrong, that would be good to know. How did you set up the pins?

posted by alexander papageorge 05 Apr 2019