2020-08-24 11:59 PM
Hello
Im working on a multimaster setup, but having alot of problems setting it up.
the processor in use is stm32f765zg
This is my pin setup(msp):
SPI2_SCK_GPIO_CLK_ENABLE();
SPI2_MISO_GPIO_CLK_ENABLE();
SPI2_MOSI_GPIO_CLK_ENABLE();
SPI2_CS_GPIO_CLK_ENABLE();
SPI2_MASTR_TRIG_GPIO_CLK_ENABLE();
/* Enable SPI2 clock */
SPI2_CLK_ENABLE();
/* Enable DMA clock */
DMA1_CLK_ENABLE();
/*##-2- Configure peripheral GPIO ##########################################*/
/* SPI SCK GPIO pin configuration */
GPIO_InitStruct.Pin = SPI_SCK_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
HAL_GPIO_Init(SPI_SCK_GPIO_Port, &GPIO_InitStruct);
// SPI MOSI GPIO pin configuration
GPIO_InitStruct.Pin = SPI_MOSI_Pin;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
HAL_GPIO_Init(SPI_MOSI_GPIO_Port, &GPIO_InitStruct);
// SPI MISO GPIO pin configuration
GPIO_InitStruct.Pin = SPI_MISO_Pin;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI2 ;
HAL_GPIO_Init(SPI_MISO_GPIO_Port, &GPIO_InitStruct);
// SPI CS GPIO pin configuration
GPIO_InitStruct.Pin = SPI_CS_Pin;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
HAL_GPIO_Init(SPI_CS_GPIO_Port, &GPIO_InitStruct);
// SPI master com trigger GPIO pin configuration(used to set NSS low on receiving slave mcu)
GPIO_InitStruct.Pin = SPI_MASTER_TRIG_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP ;
GPIO_InitStruct.Alternate = GPIO_AF0_SPI2;
HAL_GPIO_Init(SPI_WIRELESS_MASTER_TRIG_Port, &GPIO_InitStruct)
//##-3- Configure the DMA ##################################################
// Configure the DMA handler for Transmission process
hdma_tx.Instance = DMA1_Stream4;
hdma_tx.Init.Channel = DMA_CHANNEL_0;
hdma_tx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
hdma_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
hdma_tx.Init.MemBurst = DMA_MBURST_INC8;
hdma_tx.Init.PeriphBurst = DMA_PBURST_INC8;
hdma_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_tx.Init.Mode = DMA_NORMAL;
hdma_tx.Init.Priority = DMA_PRIORITY_HIGH;
result |= HAL_DMA_Init(&hdma_tx);
/* Associate the initialized DMA handle to the the SPI handle */
__HAL_LINKDMA(hspi, hdmatx, hdma_tx);
/* Configure the DMA handler for Transmission process */
hdma_rx.Instance = DMA1_Stream3;
hdma_rx.Init.Channel = DMA_CHANNEL_0;
hdma_rx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
hdma_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
hdma_rx.Init.MemBurst = DMA_MBURST_INC8;
hdma_rx.Init.PeriphBurst = DMA_PBURST_INC8;
hdma_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_rx.Init.Mode = DMA_NORMAL;
hdma_rx.Init.Priority = DMA_PRIORITY_HIGH;
result |= HAL_DMA_Init(&hdma_rx);
if (result != HAL_OK) {
result = HAL_OK;
}
/* Associate the initialized DMA handle to the the SPI handle */
__HAL_LINKDMA(hspi, hdmarx, hdma_rx);
/*##-4- Configure the NVIC for DMA #########################################*/
/* NVIC configuration for DMA transfer complete interrupt (SPI2_TX) */
HAL_NVIC_SetPriority(DMA1_Stream4_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream4_IRQn);
/* NVIC configuration for DMA transfer complete interrupt (SPI2_RX) */
HAL_NVIC_SetPriority(DMA1_Stream3_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream3_IRQn);
HAL_NVIC_SetPriority(SPI2_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(SPI2_IRQn);
and this is my SPI handle setup:
pSpiHandle->Instance = SPI2;
pSpiHandle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
pSpiHandle->Init.Direction = SPI_DIRECTION_2LINES;
pSpiHandle->Init.CLKPhase = SPI_PHASE_1EDGE;
pSpiHandle->Init.CLKPolarity = SPI_POLARITY_HIGH;
pSpiHandle->Init.DataSize = SPI_DATASIZE_8BIT;
pSpiHandle->Init.FirstBit = SPI_FIRSTBIT_MSB;
pSpiHandle->Init.TIMode = SPI_TIMODE_DISABLE;
pSpiHandle->Init.CRCCalculation = SPI_CRCCALCULATION_ENABLE;
pSpiHandle->Init.CRCPolynomial = 7;
pSpiHandle->Init.NSSPMode = SPI_NSS_PULSE_DISABLED;
pSpiHandle->Init.NSS = SPI_NSS_HARD_INPUT;
the running code is then very simple:
//setup spi handle and run HAL_SPI_Init(pSpiHandle);
status = initSpiDmaHandle(&SpiHandle, SPI_MODE_MASTER) ;
HAL_GPIO_WritePin(SPI_MASTER_TRIG_Port, SPI_MASTER_TRIG_Pin, GPIO_PIN_RESET);
status |= HAL_SPI_TransmitReceive_DMA(&SpiHandle,(uint8_t*) aTxBuffer, (uint8_t*)aRxBuffer, BUFFERSIZE);
The slave is doing:
status = initSpiDmaHandle(&SpiHandle, SPI_MODE_SLAVE) ;
status |= HAL_SPI_TransmitReceive_DMA(&SpiHandle,(uint8_t*) aTxBuffer, (uint8_t*)aRxBuffer, BUFFERSIZE);
before master starts its transmit/receive procedure
THE PROBLEM:
When both tx bufferts consist of "hello", everything works fine, but when i change it to "hello, THIS IS MASTER TESTING" / "hello, THIS IS SLAVE1 TESTING" i.e same sizes on both "sides"
the data is currupt and I only get part of the message(parts like "lo, " and then rubbish )
Anyone who has an Idéa on this?
2020-08-25 06:26 AM
Are the clocks exactly the same? Might want to make sure the slave clock is 2x of the master.
Can you see what's happening on the line? Logic analyzer or scope?
2020-08-25 07:45 AM
@TDK Thank you for answer
Do you mean by setting prescaler? Changed it to this:
Master has setting pSpiHandle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_128;
Slave has setting pSpiHandle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;
but without improvement,
I also set GPIO speed for slave to GPIO_SPEED_FREQ_VERY_HIGH
Please see picture below from logic analyzer reading
The message is definitely improved but some letters are off and the start of the message is cut of for some reason
The messages sent is: "hello I am Master" and "hello I am Slave1"
2020-08-25 10:19 AM
2020-08-25 11:03 PM
The intresting thing is that while the trace looks like this, the message that gets put in the Rx buffer is "o\0\0\0 \0\0\0I\0\0\0 am M"
Could it have something to do with dma buffert/burst/memInc or datasize?
Turning DMA off, i.e. using HAL_SPI_TransmitReceive() instead of HAL_SPI_TransmitReceive_DMA() results in Rx buffer containing "hello I am SlavSe"
A great improvement but still not perfect.
But still, DMA settings seems to have something to do with it.