Skip to main content
Visitor II
December 5, 2024
Question

Problem with using DMA with SPI

  • December 5, 2024
  • 1 reply
  • 656 views

Hello everyone,

I am currently working on an STM32F411VET6 DISCOVERY board project where I am using DMA for SPI communication with an SSD1331 OLED display. However, I am encountering an issue where the system enters an infinite loop of DMA interrupts. The interrupts are repeatedly triggered, and the program does not seem to proceed past the DMA interrupt handler (HAL_DMA_IRQHandler). I also get this weird call on my stack called: <signal handler called>() at 0xfffffff9
I'm really new to this stuff so i'm sorry for any obvious questions in advance. Here is my code:

 

 

int main(void)
{

 /* USER CODE BEGIN 1 */
	uint8_t level = 0;
	uint8_t game_is_running = 1;
	uint8_t i, j = 4;
	uint8_t * frame_buffer = malloc(sizeof(uint8_t));
	if(frame_buffer == NULL)
		Error_Handler();
 /* USER CODE END 1 */

 /* MCU Configuration--------------------------------------------------------*/

 /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
 HAL_Init();

 /* 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_ADC1_Init();
 MX_SPI1_Init();
 MX_TIM2_Init();
 MX_TIM10_Init();
 /* USER CODE BEGIN 2 */
	//ADC1/TIM2/OLED INICIALIZATION
	HAL_TIM_Base_Start(&htim2);
	HAL_TIM_Base_Start_IT(&htim10);

	HAL_DMA_Init(&hdma_spi1_tx);


	if (HAL_ADC_Start_DMA(&hadc1, (uint32_t*) ADC_Buffer, 4) != HAL_OK)
		Error_Handler();

	ssd1331_init(); //<-stops at this function
	ssd1331_draw_bitmap(0, 0, image_data_grass_texture, 96, 64, 0);
	

 /* USER CODE END 2 */

 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
	while (game_is_running) {
		switch (level) {

		case 0:
			uint8_t lg_flag = 0;
			frame_buffer = realloc(frame_buffer, sizeof(uint8_t)*64*19*16);

			if(frame_buffer == NULL)
				Error_Handler();

			write_to_buffer(0, 0, image_data_grass_texture, 64, 19, frame_buffer);
			while (level == 0) {




				if (frame_update&&dma_transfer_complete) {

					if ((i < 9) && (lg_flag == 0)) {
						i++;
						ssd1331_set_window(16, 80, j, i + 15);
						write_to_buffer(0, 0, image_data_golf_logo, 64, 15, frame_buffer);
						if(HAL_SPI_Transmit_DMA(&hspi1, frame_buffer, sizeof(uint8_t)*64*19) == HAL_OK)
							dmacheck = 1;

						
						j = i;
						dma_transfer_complete = 0;
						frame_update = 0;
					} else {
						lg_flag = 1;
						j--;
						ssd1331_set_window(16, 80, j, i + 15);
						write_to_buffer(0, 0, image_data_golf_logo, 64, 15, frame_buffer);
						if(HAL_SPI_Transmit_DMA(&hspi1, frame_buffer, sizeof(uint8_t)*64*19))
							dmacheck = 1;

						

						dma_transfer_complete = 0;
						frame_update = 0;

						i = j;
						if ((i >= 4) && (i < 5))
							lg_flag = 0;
					}
				}





			}
			break;
		};

 /* USER CODE END WHILE */

 /* USER CODE BEGIN 3 */
	}
	free(frame_buffer);
 /* USER CODE END 3 */
}

void ssd1331_init(void)
{
	__SSD1331_RES_SET(); //RES set
	__SSD1331_CS_SET();

	ssd1331_write_byte(DISPLAY_OFF, SSD1331_CMD); //Display Off<--stop here
 ssd1331_write_byte(SET_CONTRAST_A, SSD1331_CMD); //Set contrast for color A
 ssd1331_write_byte(0xFF, SSD1331_CMD); //145 0x91
 ssd1331_write_byte(SET_CONTRAST_B, SSD1331_CMD); //Set contrast for color B
 ssd1331_write_byte(0xFF, SSD1331_CMD); //80 0x50
 ssd1331_write_byte(SET_CONTRAST_C, SSD1331_CMD); //Set contrast for color C
 ssd1331_write_byte(0xFF, SSD1331_CMD); //125 0x7D
 ssd1331_write_byte(MASTER_CURRENT_CONTROL, SSD1331_CMD);//master current control
 ssd1331_write_byte(0x06, SSD1331_CMD); //6
 ssd1331_write_byte(SET_PRECHARGE_SPEED_A, SSD1331_CMD);//Set Second Pre-change Speed For ColorA
 ssd1331_write_byte(0x64, SSD1331_CMD); //100
 ssd1331_write_byte(SET_PRECHARGE_SPEED_B, SSD1331_CMD);//Set Second Pre-change Speed For ColorB
 ssd1331_write_byte(0x78, SSD1331_CMD); //120
 ssd1331_write_byte(SET_PRECHARGE_SPEED_C, SSD1331_CMD);//Set Second Pre-change Speed For ColorC
 ssd1331_write_byte(0x64, SSD1331_CMD); //100
 ssd1331_write_byte(SET_REMAP, SSD1331_CMD); //set remap & data format
 ssd1331_write_byte(0x72, SSD1331_CMD); //0x72 
 ssd1331_write_byte(SET_DISPLAY_START_LINE, SSD1331_CMD);//Set display Start Line
 ssd1331_write_byte(0x0, SSD1331_CMD);
 ssd1331_write_byte(SET_DISPLAY_OFFSET, SSD1331_CMD); //Set display offset
 ssd1331_write_byte(0x0, SSD1331_CMD);
 ssd1331_write_byte(NORMAL_DISPLAY, SSD1331_CMD); //Set display mode
 ssd1331_write_byte(SET_MULTIPLEX_RATIO, SSD1331_CMD); //Set multiplex ratio
 ssd1331_write_byte(0x3F, SSD1331_CMD);
 ssd1331_write_byte(SET_MASTER_CONFIGURE, SSD1331_CMD); //Set master configuration
 ssd1331_write_byte(0x8E, SSD1331_CMD);
 ssd1331_write_byte(POWER_SAVE_MODE, SSD1331_CMD); //Set Power Save Mode
 ssd1331_write_byte(0x00, SSD1331_CMD); //0x00
 ssd1331_write_byte(PHASE_PERIOD_ADJUSTMENT, SSD1331_CMD);//phase 1 and 2 period adjustment
 ssd1331_write_byte(0x31, SSD1331_CMD); //0x31
 ssd1331_write_byte(DISPLAY_CLOCK_DIV, SSD1331_CMD); //display clock divider/oscillator frequency
 ssd1331_write_byte(0xF0, SSD1331_CMD);
 ssd1331_write_byte(SET_PRECHARGE_VOLTAGE, SSD1331_CMD);//Set Pre-Change Level
 ssd1331_write_byte(0x3A, SSD1331_CMD);
 ssd1331_write_byte(SET_V_VOLTAGE, SSD1331_CMD); //Set vcomH
 ssd1331_write_byte(0x3E, SSD1331_CMD);
 ssd1331_write_byte(DEACTIVE_SCROLLING, SSD1331_CMD); //disable scrolling
 ssd1331_write_byte(NORMAL_BRIGHTNESS_DISPLAY_ON, SSD1331_CMD);//set display on

 //ssd1331_fill_rect(0, 0, 96, 64, 0x0000);
 ssd1331_clear_screen(0x0000);
}

static void ssd1331_write_byte(uint8_t chData, uint8_t chCmd) 
{
	if (chCmd) {
	 	__SSD1331_DC_SET();
	} else {
	 	__SSD1331_DC_CLR();
	}

	__SSD1331_CS_CLR();
	__SSD1331_WRITE_BYTE(chData); //<-then here
	
	__SSD1331_CS_SET();
	__SSD1331_DC_SET();
}

#define __SSD1331_WRITE_BYTE(__DATA) HAL_SPI_Transmit_DMA(&hspi1, &__DATA, 1)

 

 

1 reply

KDJEM.1
Technical Moderator
December 12, 2024

Hello @tospros and welcome to the community;

 

Could you please check the DMA configuration and precisely the interrupt and priority is properly configured for the SPI communication.

Maybe SPI_FullDuplex_ComDMA example in STM32CubeF4 can help you.

 

Thank you.

Kaouthar

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.