2025-03-28 4:53 PM
I want to transfer a buffer and receive a buffer of data using a full duplex SPI port with DMA on a STM32H7S3L8H (on the NUCLEO-H7S3L8). My problem is I am not able to modify the transfer buffer and have the modified version sent. I only need to modify the 1st two bytes. Here's the code:
void ade9430_read_it(SPI_HandleTypeDef *hspi, uint16_t reg_addr, uint8_t *reg_data)
{
//int ret = HAL_OK;
//gTxData[0] = reg_addr >> 4;
//gTxData[1] = ADE9430_SPI_READ | reg_addr << 4;
uint16_t Size; //in bytes
if (reg_addr >= 0x800) {
static uint8_t gTxDmaData[60] = {0}; //{0x80, 0x18};
Size = 30; //debug test
gTxDmaData[0] = reg_addr >> 4;
gTxDmaData[1] = ADE9430_SPI_READ | reg_addr << 4;
HAL_SPI_TransmitReceive_DMA(hspi, (uint8_t *)gTxDmaData, reg_data, Size); //debug DMA test
}
Here is the resulting SPI activity:
Based on the reg_addr being passed the first two values should of been 0x80, 0x18.
Setting a breakpoint on line 14 and looking at the gTxDmaData[] array the first two values have been changed to 0x80, 0x18. However, the original array values of 0x0, 0x0 are what end up being sent.
I have initialized the gTxDmaData array with a pattern and verified that the original pattern is being sent and that the first two bytes are not changed by my code.
If I initialize the first two bytes to 0x80, 0x18 I get a valid response from my SPI slave, however the first two bytes of the response data buffer have not been changed from the original array but the rest of the response matches.
I am using:
Here's the initialization code:
void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
if(spiHandle->Instance==SPI5)
{
/* USER CODE BEGIN SPI5_MspInit 0 */
/* USER CODE END SPI5_MspInit 0 */
/** Initializes the peripherals clock
*/
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SPI45;
PeriphClkInit.Spi45ClockSelection = RCC_SPI45CLKSOURCE_PCLK2;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
/* SPI5 clock enable */
__HAL_RCC_SPI5_CLK_ENABLE();
__HAL_RCC_GPIOF_CLK_ENABLE();
/**SPI5 GPIO Configuration
PF8 ------> SPI5_MISO
PF7 ------> SPI5_SCK
PF6 ------> SPI5_NSS
PF9 ------> SPI5_MOSI
*/
GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_7|GPIO_PIN_6|GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI5;
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
/* SPI5 DMA Init */
/* GPDMA1_REQUEST_SPI5_TX Init */
handle_GPDMA1_Channel1.Instance = GPDMA1_Channel1;
handle_GPDMA1_Channel1.Init.Request = GPDMA1_REQUEST_SPI5_TX;
handle_GPDMA1_Channel1.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;
handle_GPDMA1_Channel1.Init.Direction = DMA_MEMORY_TO_PERIPH;
handle_GPDMA1_Channel1.Init.SrcInc = DMA_SINC_INCREMENTED;
handle_GPDMA1_Channel1.Init.DestInc = DMA_DINC_FIXED;
handle_GPDMA1_Channel1.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_BYTE;
handle_GPDMA1_Channel1.Init.DestDataWidth = DMA_DEST_DATAWIDTH_BYTE;
handle_GPDMA1_Channel1.Init.Priority = DMA_HIGH_PRIORITY;
handle_GPDMA1_Channel1.Init.SrcBurstLength = 1;
handle_GPDMA1_Channel1.Init.DestBurstLength = 1;
handle_GPDMA1_Channel1.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0|DMA_DEST_ALLOCATED_PORT0;
handle_GPDMA1_Channel1.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
handle_GPDMA1_Channel1.Init.Mode = DMA_NORMAL;
if (HAL_DMA_Init(&handle_GPDMA1_Channel1) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(spiHandle, hdmatx, handle_GPDMA1_Channel1);
if (HAL_DMA_ConfigChannelAttributes(&handle_GPDMA1_Channel1, DMA_CHANNEL_NPRIV) != HAL_OK)
{
Error_Handler();
}
/* GPDMA1_REQUEST_SPI5_RX Init */
handle_GPDMA1_Channel0.Instance = GPDMA1_Channel0;
handle_GPDMA1_Channel0.Init.Request = GPDMA1_REQUEST_SPI5_RX;
handle_GPDMA1_Channel0.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;
handle_GPDMA1_Channel0.Init.Direction = DMA_PERIPH_TO_MEMORY;
handle_GPDMA1_Channel0.Init.SrcInc = DMA_SINC_FIXED;
handle_GPDMA1_Channel0.Init.DestInc = DMA_DINC_INCREMENTED;
handle_GPDMA1_Channel0.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_BYTE;
handle_GPDMA1_Channel0.Init.DestDataWidth = DMA_DEST_DATAWIDTH_BYTE;
handle_GPDMA1_Channel0.Init.Priority = DMA_HIGH_PRIORITY;
handle_GPDMA1_Channel0.Init.SrcBurstLength = 1;
handle_GPDMA1_Channel0.Init.DestBurstLength = 1;
handle_GPDMA1_Channel0.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0|DMA_DEST_ALLOCATED_PORT1;
handle_GPDMA1_Channel0.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
handle_GPDMA1_Channel0.Init.Mode = DMA_NORMAL;
if (HAL_DMA_Init(&handle_GPDMA1_Channel0) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(spiHandle, hdmarx, handle_GPDMA1_Channel0);
if (HAL_DMA_ConfigChannelAttributes(&handle_GPDMA1_Channel0, DMA_CHANNEL_NPRIV) != HAL_OK)
{
Error_Handler();
}
/* SPI5 interrupt Init */
HAL_NVIC_SetPriority(SPI5_IRQn, 3, 0);
HAL_NVIC_EnableIRQ(SPI5_IRQn);
/* USER CODE BEGIN SPI5_MspInit 1 */
HAL_SPI_RegisterCallback(&hspi5, HAL_SPI_TX_RX_COMPLETE_CB_ID, SPI_ReceiveCompleteCallback);
HAL_SPI_RegisterCallback(&hspi5, HAL_SPI_TX_COMPLETE_CB_ID, SPI_TransmitCompleteCallback);
HAL_SPI_RegisterCallback(&hspi5, HAL_SPI_ERROR_CB_ID, SPI_ErrorCallback);
//HAL_SPI_RegisterCallback(&hspi5, HAL_SPI_RxCpltCallback, SPI_ReceiveCompleteCallback);
//HAL_SPI_RegisterCallback(&hspi5, HAL_SPI_TX_COMPLETE_CB_ID, SPI_TransmitCompleteCallback);
/* USER CODE END SPI5_MspInit 1 */
}
}
void HAL_SPI_MspDeInit(SPI_HandleTypeDef* spiHandle)
{
if(spiHandle->Instance==SPI5)
{
/* USER CODE BEGIN SPI5_MspDeInit 0 */
/* USER CODE END SPI5_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_SPI5_CLK_DISABLE();
/**SPI5 GPIO Configuration
PF8 ------> SPI5_MISO
PF7 ------> SPI5_SCK
PF6 ------> SPI5_NSS
PF9 ------> SPI5_MOSI
*/
HAL_GPIO_DeInit(GPIOF, GPIO_PIN_8|GPIO_PIN_7|GPIO_PIN_6|GPIO_PIN_9);
/* SPI5 DMA DeInit */
HAL_DMA_DeInit(spiHandle->hdmatx);
HAL_DMA_DeInit(spiHandle->hdmarx);
/* SPI5 interrupt Deinit */
HAL_NVIC_DisableIRQ(SPI5_IRQn);
/* USER CODE BEGIN SPI5_MspDeInit 1 */
/* USER CODE END SPI5_MspDeInit 1 */
}
}
Any insight is appreciated!
Solved! Go to Solution.
2025-03-28 4:59 PM
Is data cache enabled? Try disabling it. Could also make gTxDmaData volatile.
2025-03-28 4:59 PM
Is data cache enabled? Try disabling it. Could also make gTxDmaData volatile.
2025-03-28 7:39 PM
TDK
Disabling the data cache fixed the issue.
I started with gTxDmaData as a volatile global and ended up with it just local to try to find a fix. I will be setting it back to a global volatile.
I will also be setting up a dedicated memory block for these data buffers (64KB) and I will make sure data cache is disabled.
Thanks!
2025-03-28 8:16 PM
You can keep cache enabled if you align it properly and clean/invalidate at appropriate times. Sure is simpler to just disable it if you don't need the speed, though. Or disable it on only a portion of memory using MPU settings.