cancel
Showing results for 
Search instead for 
Did you mean: 

Problem with using DMA with SPI

tospros
Associate

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 1
KDJEM.1
ST Employee

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.