cancel
Showing results for 
Search instead for 
Did you mean: 

Receiving SPDIF data with STM32F446RET/CubeMX does not work

CDupu.1
Associate II

I'm trying to receive SPDIF data using an STM32F446RET using PB7 as SPDIFRX. The signal itself is perfect, a clear and sharp waveform can be seen directly at the input pin. The whole stuff is configured in CubeMX which also generated the code for interrupt data reception. From what I can see in the CubeMX-generated code, there is no obvious mistake. The major configuration looks like this:

   hspdif.Instance = SPDIFRX;
   hspdif.Init.InputSelection = SPDIFRX_INPUT_IN0;
   hspdif.Init.Retries = SPDIFRX_MAXRETRIES_63;
   hspdif.Init.WaitForActivity = SPDIFRX_WAITFORACTIVITY_ON;
   hspdif.Init.ChannelSelection = SPDIFRX_CHANNEL_A;
   hspdif.Init.DataFormat = SPDIFRX_DATAFORMAT_LSB;
   hspdif.Init.StereoMode = SPDIFRX_STEREOMODE_ENABLE;
   hspdif.Init.PreambleTypeMask = SPDIFRX_PREAMBLETYPEMASK_ON;
   hspdif.Init.ChannelStatusMask = SPDIFRX_CHANNELSTATUS_ON;
   hspdif.Init.ValidityBitMask = SPDIFRX_VALIDITYMASK_ON;
   hspdif.Init.ParityErrorMask = SPDIFRX_PARITYERRORMASK_ON;
   if (HAL_SPDIFRX_Init(&hspdif) != HAL_OK)
   {
      Error_Handler();
   }
  
  ...
   GPIO_InitStruct.Pin = GPIO_PIN_7;
   GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
   GPIO_InitStruct.Pull = GPIO_PULLUP;
   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
   GPIO_InitStruct.Alternate = GPIO_AF8_SPDIFRX;
   HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
   /* SPDIFRX interrupt Init */
   HAL_NVIC_SetPriority(SPDIF_RX_IRQn, 0, 5);
   HAL_NVIC_EnableIRQ(SPDIF_RX_IRQn);

Interrupts (both, global and the SPDIF-one) are enabled and data reception is initiated via a call to:

if (HAL_SPDIFRX_ReceiveDataFlow_IT(&hspdif,recvBuffer,8)==HAL_OK)
{
   spdifRecvComplete=0;
}

The interrupt routine to announce the completion of data reception looks like this:

void HAL_SPDIFRX_RxCpltCallback(SPDIFRX_HandleTypeDef *hspdif)
{
   spdifRecvComplete=1;
}

So the whole code is more or less some straight-forward stuff which makes use if the HAL-interface's interrupt data transfer functionality.

My problem: this routine is never called. More than this, the low-level interrupt service function SPDIF_RX_IRQHandler() is also never called. One strange thing: I see the function SPDIF_RX_IRQHandler(), its definition but I can not see where it is defined as interrupt handler/where a pointer to this function is handed over to some IRQ hardware register.

As said, the SPDIF input signal is perfect, the only special thing here: it comes with 100 kHz clock, not 96 kHz or 192 kHz or something common like that.

So what could be the reason for my problems? Why are no SPDIF data received?

13 REPLIES 13
Piranha
Chief II

On most Cortex-M devices ISR adreses are loaded from a vector table pointed by SCB_VTOR register and typically located at the beginning of the FLASH memory. You probably have not enabled the SPDIFRX interrupt in NVIC.

Post edited to adhere community guidelines.

Read out and check the SPDIF_Rx registers content. If it does not work properly, there will be no interrupts either.

Some generic interrupt-related troubleshooting hints here.

JW

CDupu.1
Associate II

@Community member​ OK, what should I see in this register exactly?

The problem is: the ST-support already submitted an example project to me (CubeMX-generated too). This example makes use of SAI to generate a SPDIF-signal which then is looped back to the SPDIF-RX-input on the same device.

The ST-support says, it is working and the interrupts are called properly in this project. But when I use exactly the same project on my device (means with an SPDIF-input-signal from an external source instead of the loopback), I never see the interrupt function being called.

> OK, what should I see in this register exactly?

The SPDIF-Rx section in Reference Manual (RM) describes how the module works, read it. Then, the registers' content is detailed at the end, so by reading them out and checking against that description determine if the module has been set up properly. Bits in the Status Register will show you possible errors. And, at the end of the day, it's the bits in the Status Register which trigger the interrupt - for each bit, there's a description which other setup bit enables the respective interrupt.

Also, make sure by reading and checking RCC registers (and again checking against description in RCC chapter in RM) whether SPDIF-Rx has set up and enabled a valid clock.

Also, check the relevant GPIO pin's settings in respective GPIO register.

JW

LCE
Principal

Have you tried the ST project with the SPDIF signal from its own SAI?

Are you 100% sure that your SPDIF-input-signal from an external source is okay?

Could you check that with some other device?

CDupu.1
Associate II

@Community member​ I have not much doubts regarding the external signal. I have two very different devices generating such a signal. And I have an other device which acts as SPDIF receiver which works properly with the signals from these devices. So the only combination, where receiving does not work, is, when the STM is involved.

LCE
Principal

Okay.

I have only experience with the SPDIF TX from the SAI, which actually works without any trouble.

But does the ST example work?

Maybe you check that SPDIF signal on the scope and compare.

Anything on the RX part concerning sample rate / jitter / input clock / resolution?

CDupu.1
Associate II

@Community member​ the ST-example with the loopback works as long as I use the ST-internal generated signal, yes.

The only exotic thing at my real-world SPDIF-data is the sample clock of the signal, it runs at 100 kHz (and not at 96 kHz like one would expect it from standard audio stuff). The upper 4 data bits are fixed at 0100, then there are 20 bits varying payload. Validity-bit is 1, user-data and channel status bits are 0. So nothing special I think. On the scope the signal looks good. And when using an other receiver than the STM, it is received without any problems.

LCE
Principal

My guess is that there are clock / sampling problems in the RX "frontend" so that no valid data is received, and so the interrupts are not triggered.

Learn to use the registers, check all settings, the interrupt enables.

Maybe there are some error interrupts which can show you what the problem is.

And check the clock to the peripheral spdifrx_ker_ck (this is from a H7 manual - not F4!):

"The SPDIFRX tolerance to clock deviation depends on the number of sample clock cycles in

one bit slot. The fastest spdifrx_ker_ck is, the more robust the reception is. The ratio

between spdifrx_ker_ck frequency and the symbol rate must be at least 11.

Two kinds of phenomenon (at least) can degrade the reception quality:

• The cycle-to-cycle jitter which reflects the difference of transition length between two

consecutive transitions.

• The long term jitter which reflects a cumulative effect of the cycle-to-cycle jitter. It can

be seen as a low-frequency symbol modulation."

So at 100 kHz you have a "symbol rate" of 100k * 32 * 2 = 6.4M, so spdifrx_ker_ck must at least be 70.4 MHz. At least for a STM32H7.