I'm currently trying to receive S/PDIF data using a MIMXRT101-EVK board via the interrupt method. In general it is working well - except the fact that all my received frames are empty and contain only 0. This is true even for the auxiliary part which is set to 0100 by the sender always.
The receiving operation in general works: when no signal is applied to my input GPIO_10 (configured as SPDIF:IN), the callback-handler is never called. As soon as I apply a S/PDIF-signal at this input, I can see the callback is called with kStatus_SPDIF_RxIdle, but the related buffer contains no data. I even can place a breakpoint to the interrupt service routine, when stepping through the related code I can see the related registers for left and right are read, but these reigsters also contain only zeros.
When measuring with an oscilloscope directly at pin 2 of the MCU, I can see my valid S/PDIF frames with their data, so they are definitely there.
So that's what I have:
My peripheral configuration is the default one except for the fact that I'm receiving only and enable the interrupt for my own.
This is the initialisation sequence and where I start transfer of data:
SPDIF_TransferRxCreateHandle(SPDIF_PERIPHERAL,&rxHandle,rxCallback,NULL);
EnableIRQ(SPDIF_IRQN);
rxXfer.dataSize = BUFFER_SIZE;
rxXfer.data = audioBuff;
SPDIF_TransferReceiveNonBlocking(SPDIF_PERIPHERAL, &rxHandle, &rxXfer);
And that's the callback function where I regularly get an kStatus_SPDIF_rxIdle but the related buffer does not contain the data to be expected.
static void rxCallback(SPDIF_Type *base, spdif_handle_t *handle, status_t status, void *userData)
{
if (status == kStatus_SPDIF_RxIdle)
{
dataReceived=true;
SPDIF_TransferReceiveNonBlocking(SPDIF_PERIPHERAL, &rxHandle, &rxXfer);
}
}
What I don't understand: when I receive these frames, this means the receiver must have identified at least the preamble and the valid-flag of each frame? So receiving of the frames works but the data do not get through!?
So...any idea what could be missing here?
2nd update: it has nothign to do with the Valid-flag, even when it is not set (aka the data are marked as valid), the result is the same.
Hi @Elmi77
I hope you are doing well!
I am sorry for the delay, but as I let you know via email, here is my feedback, divided in some couple pointers.
1 In your callback I recommend you all of the possible status you can get from the SPDIF. Or directly debug into your SPDIF_TransferRxHandleIRQ().
2 Is the kSPDIF_RxFIFOFull status being sent? This is where the SPDIF_TransferRxHandleIRQ() copies data from internal SPDIF buffers to your audioBuff. Below an screenshot.
3 You can check if the sample rate matches to the expected frames calling the function SPDIF_GetRxSampleRate() .
Actually this function requires you to give clockSourceFreq_Hz for your SPDIF.
4 In your provided code, I have not seen, which clock divider you are providing to your SPDIF initialization.
Here is an example below:
5 I am attaching an SPDIF example for the RT1050. This demo receives SPIDIF data and then does a transmission. You can actually double check muxing for your IN pin from the demo.
All the best,
Diego
Hello Diego,
thank you for your kind feedback. About your suggestions/answers:
1. When I enabgle all interrupts available (even the ones for signals I'm not interested in), SPDIF_TransferRxHandleIRQ() dies:
HardFault_Handler() at semihost_hardfault.c:61 0x60004d8e
<signal handler called>() at 0xfffffff1
SPDIF_TransferRxHandleIRQ() at fsl_spdif.c:796 0x600033a4
This is somehow caused by data = SPDIF_ReadLeftData(base);
2. I already checked what happens in SPDIF_TransferRxHandleIRQ(). When doing that only with kSPDIF_RxFIFOFull used, even the calls to SPDIF_ReadLeftData() and SPDIF_ReadRightData() return 0, so that's where the empty buffers come from.
3. I tried this in my receive-callback in case of a kStatus_SPDIF_RxIdle:
const uint32_t clock=CLOCK_GetPllFreq(kCLOCK_PllAudio);
sRate=SPDIF_GetRxSampleRate(SPDIF_PERIPHERAL,clock);
clock is 24000000 (somewhat surprising as the clock configuration says the SPDIF is running at 30 MHz). SPDIF_GetRxSampleRate() never returns, it fails at this loop which never becomes true:
while ((base->SRPC & SPDIF_SRPC_LOCK_MASK) == 0U)
{
}
4. This is part aof the auto-generated code. The clock-config-tool says, this should result in a 30MHz clock fpr the SPDIF:
/* Set SPDIF0_CLK_PRED. */
CLOCK_SetDiv(kCLOCK_Spdif0PreDiv, 1);
/* Set SPDIF0_CLK_PODF. */
CLOCK_SetDiv(kCLOCK_Spdif0Div, 7);
/* Set Spdif clock source. */
CLOCK_SetMux(kCLOCK_SpdifMux, 3);
5. I already tried this (this is where I have taken the RxCallback-stuff from).
Hi @Elmi77
Many thanks for your reply and patience!
Regarding #1 and ##2,, I understand, that even the IRQ goes to copy receive buffer contents to your array, the data copied is zero.
Regarding, #3
It seems that we are having problems to recover the SPDIF Rx clock, that may explain why the function.
SPDIF_GetRxSampleRate() is is stuck in.
while ((base->SRPC & SPDIF_SRPC_LOCK_MASK) == 0U)
{
}
If we look into SRPC register, the function is waiting for the DPLL to be locked. The internal DPLL is the one in charge of measuring the frequency of SPDIF Rx clock. I would think the issue we are seeing is because clock settings.
Regarding #4,
I would suggest, trying the transmitter side. I just want to see if you are able to even transmit data. Try to mimic the demo code clock selection and divider settings.
Regarding #5, understood.
I am sorry for not being able to get back to you sooner.
Kindly
Diego
Hello Diego,
don't worry about the delay. About the DPLL clock problem, there are following observations:
Your suggestion to add the code-part to transmit some data via SPDIF was not yet successful:
static spdif_handle_t txHandle = {0};
static spdif_transfer_t txXfer = {0};
#define BUFFER_SIZE 96
AT_NONCACHEABLE_SECTION_ALIGN(uint8_t audioBuffRx[BUFFER_SIZE], 4);
SPDIF_TransferTxCreateHandle(SPDIF_PERIPHERAL, &txHandle, txCallback, NULL);
txXfer.dataSize = BUFFER_SIZE;
txXfer.data = audioBuffTx;
ret=SPDIF_TransferSendNonBlocking(SPDIF_PERIPHERAL, &txHandle, &txXfer);*/
Surprisingly this dies when jumping into SPDIF_TransferSendNonBlocking() - yes, when jumping into that function, not somewhere inside it.
So...may be there is something fundamental wrong here?
Hi @Elmi77
Thanks for your patience,
Regarding point
To discard problems, did you find any improvement with the code that my colleague shared with you?
Thank you!
OK, I made some progress: in my S/PDIF-data the validity flag is always set. Amazingly an set validity-flag means "invalid", so it has the opposite meaning.
As my S/PDIF-data have this flag always set, my question is, how can I ensure to receive these data also in case they are marked as "invalid"?