Author Topic: 32F417 - what could stop this memory-SPI3 DMA transfer running?  (Read 2978 times)

0 Members and 1 Guest are viewing this topic.

Offline wek

  • Frequent Contributor
  • **
  • Posts: 497
  • Country: sk
Re: 32F417 - what could stop this memory-SPI3 DMA transfer running?
« Reply #25 on: November 03, 2022, 07:49:01 pm »
Yes, you normally configure SPI with SPE being zero. The clock for SPI as a module comes from RCC so it has to be enabled there, but it probably is all the time.

SPE enables SPI's internal state machine, i.e. it starts to transmit, receive etc.  At SPE down the internal counters are reset. If you change e.g. CPOL/CPHA or number of bits while SPE is not clear, the results may be surprising (guess how do I know).

JW
 

Offline peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 3743
  • Country: gb
  • Doing electronics since the 1960s...
Re: 32F417 - what could stop this memory-SPI3 DMA transfer running?
« Reply #26 on: November 03, 2022, 09:46:10 pm »
I wonder if anyone has been able to find anything in those register bits. Sorry I couldn't get them in binary :)

All I can think of is that HAL SPI function exits with SPI enabled, and I wasn't disabling SPI prior to using SPI. However the function which initialises (configures)SPI (for each different device, if there has been a change) does disable SPI and leaves it disabled:

Code: [Select]
   */
void KDE_spi3_set_mode(uint8_t mode)
{
// SPI configuration
switch (mode) {

case KDE_SPI_MODE_STLED316: // options *** below work but should not
m_spi.Init.Direction = SPI_DIRECTION_2LINES;
m_spi.Init.DataSize = SPI_DATASIZE_8BIT;
// m_spi.Init.CLKPolarity = SPI_POLARITY_HIGH; // ****
m_spi.Init.CLKPolarity = SPI_POLARITY_LOW; // ***
// m_spi.Init.CLKPhase = SPI_PHASE_2EDGE; // ****
m_spi.Init.CLKPhase = SPI_PHASE_1EDGE; // ***
m_spi.Init.NSS = SPI_NSS_SOFT;
m_spi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64; // 650kHz (max 1MHz)
m_spi.Init.FirstBit = SPI_FIRSTBIT_LSB; // LSB first - unusual
m_spi.Init.CRCPolynomial = 7;
m_spi.Init.Mode = SPI_MODE_MASTER;
m_spi.Instance = STLED316S_SPI;
break;

case KDE_SPI_MODE_ADS1118:
m_spi.Init.Direction = SPI_DIRECTION_2LINES;
m_spi.Init.DataSize = SPI_DATASIZE_16BIT;
m_spi.Init.CLKPolarity = SPI_POLARITY_LOW; // correct per data sheet
m_spi.Init.CLKPhase = SPI_PHASE_2EDGE; // likewise - sample on -ve ck edge
m_spi.Init.NSS = SPI_NSS_SOFT;
m_spi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;  // 2.6MHz (max 4MHz for ADS1118)
m_spi.Init.FirstBit = SPI_FIRSTBIT_MSB;
m_spi.Init.CRCPolynomial = 7;
m_spi.Init.Mode = SPI_MODE_MASTER;
m_spi.Instance = ADS1118_SPI;
break;

case KDE_SPI_MODE_MCP3550:
m_spi.Init.Direction = SPI_DIRECTION_2LINES_RXONLY;
m_spi.Init.DataSize = SPI_DATASIZE_8BIT;
m_spi.Init.CLKPolarity = SPI_POLARITY_HIGH;
// m_spi.Init.CLKPolarity = SPI_POLARITY_LOW; // ***
m_spi.Init.CLKPhase = SPI_PHASE_2EDGE;
// m_spi.Init.CLKPhase = SPI_PHASE_1EDGE; // ***
m_spi.Init.NSS = SPI_NSS_SOFT;
m_spi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;  // 2.6MHz (max 5MHz for MCP3550)
m_spi.Init.FirstBit = SPI_FIRSTBIT_MSB;
m_spi.Init.CRCPolynomial = 7;
m_spi.Init.Mode = SPI_MODE_MASTER;
m_spi.Instance = MCP3550_SPI;
break;

case KDE_SPI_MODE_HI3593:
m_spi.Init.Direction = SPI_DIRECTION_2LINES;
m_spi.Init.DataSize = SPI_DATASIZE_8BIT;
m_spi.Init.CLKPolarity = SPI_POLARITY_LOW; // This is actually correct per data sheet
m_spi.Init.CLKPhase = SPI_PHASE_1EDGE; // and so is this
m_spi.Init.NSS = SPI_NSS_SOFT;
m_spi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;  // 5.2MHz (max 10MHz for HI3593)
// m_spi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;  // 10.5MHz (max 10MHz for HI3593)
m_spi.Init.FirstBit = SPI_FIRSTBIT_MSB;
m_spi.Init.CRCPolynomial = 7;
m_spi.Init.Mode = SPI_MODE_MASTER;
m_spi.Instance = HI3593_SPI;
break;

case KDE_SPI_MODE_NEO_M9N:
m_spi.Init.Direction = SPI_DIRECTION_2LINES;
m_spi.Init.DataSize = SPI_DATASIZE_8BIT;
m_spi.Init.CLKPolarity = SPI_POLARITY_LOW;
m_spi.Init.CLKPhase = SPI_PHASE_1EDGE;
m_spi.Init.NSS = SPI_NSS_SOFT;
m_spi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64; // 64: 650kHz (max 1MHz for 125kbyte/sec max data rate)
m_spi.Init.FirstBit = SPI_FIRSTBIT_MSB;
m_spi.Init.CRCPolynomial = 7;
m_spi.Init.Mode = SPI_MODE_MASTER;
m_spi.Instance = NEO_M9N_SPI;
break;

case KDE_SPI_MODE_LY68L6400:
m_spi.Init.Direction = SPI_DIRECTION_2LINES;
m_spi.Init.DataSize = SPI_DATASIZE_8BIT;
m_spi.Init.CLKPolarity = SPI_POLARITY_LOW;
m_spi.Init.CLKPhase = SPI_PHASE_1EDGE;
m_spi.Init.NSS = SPI_NSS_SOFT;
m_spi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; // 2: 21MHz - max possible on KDE
m_spi.Init.FirstBit = SPI_FIRSTBIT_MSB;
m_spi.Init.CRCPolynomial = 7;
m_spi.Init.Mode = SPI_MODE_MASTER;
m_spi.Instance = LY68L6400_SPI;
break;

default:
break;

}

HAL_SPI_Init(&m_spi);

}

Code: [Select]
/**
  * @brief  Initialize the SPI according to the specified parameters
  *         in the SPI_InitTypeDef and initialize the associated handle.
  * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
  *               the configuration information for SPI module.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi)
{
  /* Check the SPI handle allocation */
  if (hspi == NULL)
  {
    return HAL_ERROR;
  }

  hspi->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;

  if (hspi->State == HAL_SPI_STATE_RESET)
  {
    /* Init the low level hardware : GPIO, CLOCK, NVIC... */
    HAL_SPI_MspInit(hspi);
  }

  /* Disable the selected SPI peripheral */
  __HAL_SPI_DISABLE(hspi);

  /*----------------------- SPIx CR1 & CR2 Configuration ---------------------*/
  /* Configure : SPI Mode, Communication Mode, Data size, Clock polarity and phase, NSS management,
  Communication speed, First bit and CRC calculation state */
  WRITE_REG(hspi->Instance->CR1, (hspi->Init.Mode | hspi->Init.Direction | hspi->Init.DataSize |
                                  hspi->Init.CLKPolarity | hspi->Init.CLKPhase | (hspi->Init.NSS & SPI_CR1_SSM) |
                                  hspi->Init.BaudRatePrescaler | hspi->Init.FirstBit  | hspi->Init.CRCCalculation));

  /* Configure : NSS management, TI Mode */
  WRITE_REG(hspi->Instance->CR2, (((hspi->Init.NSS >> 16U) & SPI_CR2_SSOE) | hspi->Init.TIMode));

#if defined(SPI_I2SCFGR_I2SMOD)
  /* Activate the SPI mode (Make sure that I2SMOD bit in I2SCFGR register is reset) */
  CLEAR_BIT(hspi->Instance->I2SCFGR, SPI_I2SCFGR_I2SMOD);
#endif /* SPI_I2SCFGR_I2SMOD */

  hspi->ErrorCode = HAL_SPI_ERROR_NONE;

  return HAL_OK;
}

I think it is right to always leave SPI disabled. And obviously it needs to be enabled before any usage. And it should be disabled before any configuration change. I am doing all that now.
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf