2022-12-07 04:03 AM
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
2022-12-07 09:38 AM
The ***_IT() and ***_DMA() functions are non-blocking - they set up the hardware and return immediately.
2022-12-07 09:48 AM
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