cancel
Showing results for 
Search instead for 
Did you mean: 

problem in LL SPI example code

HDaji.1
Senior

I have been testing Examples_LL code (SPI_TwoBoards_FullDuplex_DMA_Master_Init ) in STM32Cube_FW_G4_V1.4.0 package.

Here is my problem:

I modified the original code such that I only need one board.

/* Enable the SPI1 peripheral */
  Activate_SPI();
 
  /* Wait for the end of the transfer and check received data */
  /* LED blinking FAST during waiting time */
  //WaitAndCheckEndOfTransfer();
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
   LL_mDelay(1);
    //while (ubTransmissionComplete != 1)
    //{
    //}
 
    LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_3);
 
    /* USER CODE BEGIN 3 */
  }

In the while loop, I keeps calling LL_DMA_EnableChannel, expecting to see repeated transmitting SPI message.

I used PicoScope to monitor SCLK and MOSI lines signal as showed below (D3 and D4). I expected repeated signals in those two lines, which did not happen. As showed in the picture below SPI transmission only happens once.

0693W00000DmFfgQAF.jpg 

Another weird thing is that I define uint8_t aTxBuffer[] = {0x01, 0x02, 0x03, 0x04}; so I expect SPI to transmit 4 bytes out in MOSI line. What I captured is

 0693W00000DmFvZQAV.jpgD3 is clock and D4 is MOSI. Obviously, the signals are far off from what is expected.

In fact, I did something similar with Nucleo-F411RE and example code SPI_TwoBoards_FullDuplex_DMA in package STM32Cube_FW_F4_V1.26.0, for which there is no problem. The only difference I notice is the function call to transmit SPI data: in F4 package it is called LL_DMA_EnableStream, while in G4 LL_DMA_EnableChannel.

I cannot find LL_DMA_EnableStream in STM32G4 HAL and low-layer drivers manual. BTW, the function descriptions in both HAL and low-layer driver manuals are sometimes too simple to be helpful.

5 REPLIES 5
Amel NASRI
ST Employee

Hi @HDaji.1​ ,

DMA peripheral isn't the same when comparing STM32G4 to STM32F4.

You can review the following 2 application notes to understand more about the difference between both of them:

  • AN4031: Using the STM32F2, STM32F4 and STM32F7 Series DMA controller 
  • AN2548: Using the STM32F0/F1/F3/Gx/Lx Series DMA controller

Now, as you have only one board, why don't you use the example STM32Cube_FW_G4\Projects\NUCLEO-G474RE\Examples_LL\SPI\SPI_OneBoard_HalfDuplex_DMA?

-Amel

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

@Amel NASRI​ Thanks for your info.

I just want to transmit a few bytes to another device through SPI the fastest as the MCU can do.

HDaji.1
Senior

Purely based on example code in SPI_TwoBoards_FullDuplex_DMA: one possible way, to achieve repeated sending out a few bytes through SPI, could be to disable the DMA channel after SPI transmission has completed and re-enable it later. However, it seems not as efficient as the case in F4, whereby one enabling function does the job.

Another thing: why the SPI signals are so strange?

Hi Amel,

I modified main.c in such a way it continuously does SPI transmission.

I have two issues:

(1) I shortened the tx buffer to 3 chars, so it transmits 4 bytes. However, from enabling SPI DMA channel to Tx/Rx complete, it takes 2.5us for SPI data rate 4Mbps, which is supposed to be < 1us. What causes the delay?

(2) The whole loop takes more than 10us to finish. That's too slow. Is there anyway to reduce the delay. Some config or setting may just need to be done once, but I've tried a few times, it didn't work.

I have read those 2 documents you mentioned, not very helpful.

int main(void)
{
  /* USER CODE BEGIN 1 */
  /* USER CODE END 1 */
 
  /* MCU Configuration--------------------------------------------------------*/
 
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
 
  LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SYSCFG);
  LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR);
 
  NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
 
  /* System interrupt init*/
 
  /** Disable the internal Pull-Up in Dead Battery pins of UCPD peripheral
  */
  LL_PWR_DisableUCPDDeadBattery();
 
  /* USER CODE BEGIN Init */
 
  /* USER CODE END Init */
 
  /* Configure the system clock */
  SystemClock_Config();
 
  /* USER CODE BEGIN SysInit */
 
  /* USER CODE END SysInit */
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_SPI1_Init();
  /* USER CODE BEGIN 2 */
  UserButton_Init();
 
  /* Configure DMA channels */
 
  /* Enable DMA interrupts complete/error */
 
  /* Initialize FFIFO Threshold */
  //LL_SPI_SetRxFIFOThreshold(SPI1, LL_SPI_RX_FIFO_TH_QUARTER);
 
  /* Enable SPI1 DMA transfer interrupts */
 
  /* Wait for User push-button press to start transfer */
  WaitForUserButtonPress();
 
  /* Enable the SPI1 peripheral */
  //Enable_SPI();
 
  /* Wait for the end of the transfer and check received data */
  /* LED blinking FAST during waiting time */
  //WaitAndCheckEndOfTransfer();
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	/* one loop takes 12.5us to complete, too long*/
	LED_On();
 
    /* Configure DMA channels.   5 us */
	Config_SPIDMA_Ch();
 
	/* Enable DMA interrupts complete/error   2 us */
	Enable_DMA_IT();
 
	/* Initialize FFIFO Threshold  0.6 us */
	LL_SPI_SetRxFIFOThreshold(SPI1, LL_SPI_RX_FIFO_TH_QUARTER);
 
	/* Enable SPI1 DMA transfer interrupts 1 us */
	Enable_SPIDMA_TxRx_IT();
 
    /* Enable the SPI1 peripheral 0.7 us */
	Enable_SPI();
 
    /* Enable the SPI1 DMA Ch until Tx/Rx complete takes 3.5 us */
	Enable_SPIDMA_Ch();
 
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
 
	/* 1 - Wait end of transmission */
	while (ubTransmissionComplete != 1)	{ }
	ubTransmissionComplete = 0;
	/* 2 - Wait end of reception */
	while (ubReceptionComplete != 1) { }
	ubReceptionComplete = 0;
 
	/* about 1.9 us */
	Disable_SPIDMA_Ch();
	Disable_SPI();
	LED_Off();
  }
  /* USER CODE END 3 */
}