cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F769 SPDIFRX Interupt

MKocj.1
Associate II

Hello there, I am developing an application that takes data out of SPDIFRX port and I am trying to do this with interupts instead of polling

I am basing my code on polling example that you can find here: https://www.st.com/en/embedded-software/stm32cubef7.html

STM32Cube_FW_F7_V1.4.0\Projects\STM32F769I-Discovery\Examples\SPDIFRX\SPDIFRX_Loopback

Here is my code

SAI_HandleTypeDef            hsai;
DMA_HandleTypeDef            hSaiDma;
SPDIFRX_HandleTypeDef        SpdifrxHandle;
 
/* 16 bit Data Buffer for Transmission */ 
uint16_t Tab_Tx_16b[64] = {
0x5152, 0x5354, 0x5556, 0x5758, 0x595A, 0x5B5C, 0x5D5E, 0x5F60,
0x6162, 0x6364, 0x6566, 0x6768, 0x696A, 0x6B6C, 0x6D6E, 0x6F70,
0x7172, 0x7374, 0x7576, 0x7778, 0x797A, 0x7B7C, 0x7D7E, 0x7F80,
0x8182, 0x8384, 0x8586, 0x8788, 0x898A, 0x8B8C, 0x8D8E, 0x8F90,
0x5152, 0x5354, 0x5556, 0x5758, 0x595A, 0x5B5C, 0x5D5E, 0x5F60,
0x6162, 0x6364, 0x6566, 0x6768, 0x696A, 0x6B6C, 0x6D6E, 0x6F70,
0x7172, 0x7374, 0x7576, 0x7778, 0x797A, 0x7B7C, 0x7D7E, 0x7F80,
0x8182, 0x8384, 0x8586, 0x8788, 0x898A, 0x8B8C, 0x8D8E, 0x8F90};
uint32_t received_data_flow[64] ;
uint32_t data_cpt_occured = 0;
uint32_t control_cpt_occured = 0;
 
/* Private function prototypes -----------------------------------------------*/
static void MPU_Config(void);
static void SystemClock_Config(void);
static void CPU_CACHE_Enable(void);
static void SPDIF_Transmitt();
static void SPDIF_Receive_Configure();
static void SPDIF_Receive_Polling();
static void SPDIF_Receive_Interupt();
static int SPDIFBufferCmp(uint32_t* pBuffer1, uint16_t* pBuffer2, uint8_t size);
 
/* Private functions ---------------------------------------------------------*/
 
static void SPDIF_Transmitt()
{
 
	/* Configure SAI in SPDIF-Tx Mode */
	hsai.Instance = SAI2_Block_A;
	hsai.Init.AudioMode      = SAI_MODEMASTER_TX;
	hsai.Init.Synchro        = SAI_ASYNCHRONOUS;
	hsai.Init.SynchroExt     = SAI_SYNCEXT_DISABLE;
	hsai.Init.OutputDrive    = SAI_OUTPUTDRIVE_DISABLE;
	hsai.Init.NoDivider      = SAI_MASTERDIVIDER_ENABLE;
	hsai.Init.FIFOThreshold  = SAI_FIFOTHRESHOLD_EMPTY;
	hsai.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_96K;
	hsai.Init.Mckdiv         = 0;
	hsai.Init.MonoStereoMode = SAI_STEREOMODE;
	hsai.Init.CompandingMode = SAI_NOCOMPANDING;
	hsai.Init.TriState       = SAI_OUTPUT_NOTRELEASED;
	hsai.Init.Protocol       = SAI_SPDIF_PROTOCOL;
	hsai.Init.DataSize       = SAI_DATASIZE_24;
	hsai.Init.FirstBit       = SAI_FIRSTBIT_MSB;
	hsai.Init.ClockStrobing  = SAI_CLOCKSTROBING_FALLINGEDGE;
 
	hsai.FrameInit.FrameLength       = 64;
	hsai.FrameInit.ActiveFrameLength = 32;
	hsai.FrameInit.FSDefinition      = SAI_FS_STARTFRAME;
	hsai.FrameInit.FSPolarity        = SAI_FS_ACTIVE_LOW;
	hsai.FrameInit.FSOffset          = SAI_FS_FIRSTBIT;
 
	hsai.SlotInit.FirstBitOffset = 0;
	hsai.SlotInit.SlotSize       = SAI_SLOTSIZE_DATASIZE;
	hsai.SlotInit.SlotNumber     = 4;
	hsai.SlotInit.SlotActive     = SAI_SLOTACTIVE_ALL;
 
	if(HAL_SAI_Init(&hsai)!= HAL_OK )
	{
	  Error_Handler();
	}
}
static void SPDIF_Receive_Configure()
{
	/* Initialize reception buffer */
	for(uint32_t j = 0; j<64; j++)
	{
		received_data_flow[j] = 0;
	}
 
	/* Configure SPDIFRX Peripheral */
	SpdifrxHandle.Instance = SPDIFRX;
	HAL_SPDIFRX_DeInit(&SpdifrxHandle);
 
	SpdifrxHandle.Init.InputSelection = SPDIFRX_INPUT_IN1;
	SpdifrxHandle.Init.Retries = SPDIFRX_MAXRETRIES_15;
	SpdifrxHandle.Init.WaitForActivity = SPDIFRX_WAITFORACTIVITY_ON;
	SpdifrxHandle.Init.ChannelSelection = SPDIFRX_CHANNEL_A;
	SpdifrxHandle.Init.DataFormat = SPDIFRX_DATAFORMAT_MSB;
	SpdifrxHandle.Init.StereoMode = SPDIFRX_STEREOMODE_ENABLE;
	SpdifrxHandle.Init.PreambleTypeMask = SPDIFRX_PREAMBLETYPEMASK_ON;
	SpdifrxHandle.Init.ChannelStatusMask = SPDIFRX_CHANNELSTATUS_ON;
	if(HAL_SPDIFRX_Init(&SpdifrxHandle) != HAL_OK)
	{
		/* Initialization error */
		Error_Handler();
	}
}
 
static void SPDIF_Receive_Polling()
{
	volatile int returnCode = HAL_SPDIFRX_ReceiveDataFlow(&SpdifrxHandle, (uint32_t *)received_data_flow, 64, 0xFFF);
	if(SpdifrxHandle.ErrorCode != HAL_SPDIFRX_ERROR_NONE)
	{
		Error_Handler();
	}
}
 
static void SPDIF_Receive_Interupt()
{
	volatile int returnCode = HAL_SPDIFRX_ReceiveDataFlow_IT(&SpdifrxHandle, (uint32_t *)received_data_flow, 64);// == HAL_OK)
	if(SpdifrxHandle.ErrorCode != HAL_SPDIFRX_ERROR_NONE)
	{
		Error_Handler();
	}
	/*
	{
		/* We are receiving data *//*
		BSP_LED_Off(LED1);
		BSP_LED_On(LED2);
	}
	else
	{
		/* Receiving error *//*
		Error_Handler();
	}*/
}
 
/**
  * @brief  Main program
  * @param  None
  * @retval None
  */
int main(void)
{
  
  /* Configure the MPU attributes */
  MPU_Config();
 
  /* Enable the CPU Cache */
  CPU_CACHE_Enable();
 
  /* STM32F7xx HAL library initialization:
       - Configure the Flash prefetch
       - Systick timer is configured by default as source of time base, but user 
         can eventually implement his proper time base source (a general purpose 
         timer for example or other time source), keeping in mind that Time base 
         duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and 
         handled in milliseconds basis.
       - Set NVIC Group Priority to 4
       - Low Level Initialization
     */
  HAL_Init();
 
  /* Configure the system clock at 216 MHz */
  SystemClock_Config();
 
  /* Configure LED2 (Green)*/
  BSP_LED_Init(LED2);
  /* Configure LED1 (Red)*/
  BSP_LED_Init(LED1);
  
  SPDIF_Transmitt();
  
  /* Start transmission (DMA mode) */
  HAL_SAI_Transmit_DMA(&hsai, (uint8_t *)Tab_Tx_16b, 64);
  
  /* Reception in (Polling mode) */
  SPDIF_Receive_Configure();
  //SPDIF_Receive_Polling();
  SPDIF_Receive_Interupt();
 
  /* Compare the received data with the expected one */    
  if (SPDIFBufferCmp(received_data_flow, Tab_Tx_16b, 64) != 0)
  {
    /* Transmission error */
    Error_Handler();
  }
  else
  {
    /* Transmission succeeded */
    BSP_LED_On(LED2);
  }
  
  while(1);
}

The whole file can be found here: https://pastebin.com/tJMH31eu

No matter what I do, I always get HAL_ERROR on HAL_SPDIFRX_ReceiveDataFlow_IT if using interupts

For some reason on Polling mode (with HAL_SPDIFRX_ReceiveDataFlow) everything works fine, but I would like to to this with interupts

Hope someone knows what I am doing wrong

Thanks

2 REPLIES 2
Piranha
Chief II

The ***_IT() and ***_DMA() functions are non-blocking - they set up the hardware and return immediately.

oh, I see, so why is my interupt example not working then? (I mean how can I fix it so it will start to work?

I always get HAL_ERROR instead of HAL_OK back