Hi
In sd_loopback example, I am trying to replace the capture FVID_exchange with a callback based on mask VPORT_INT_CCMP (0x04). The reason for doing so is to prevent the blocking condition in capture FVID_exchange when a buffer is not available. The structure of the callback is:
extern "C" void VideoCallback(Arg id, Arg mask)
{
if (mask & VPORT_INT_CCMP)
{
status = FVID_dequeue(capChInfo.chanHandle, &(capChInfo.frame));
status = MBX_post(hmbxProcess, &capChInfo, SYS_FOREVER);
}
return;
}
The main while loop is shown below. The problem is that dequeue doesn't block the first time the callback fires, but the second time the callback fires, dequeue blocks. When I say "works", I mean that the first time i leave the mbx pend, I can break at the display FVID_exchange and can see the correct video image in disChInfo.frame.
Is there a way I can debug this? I have looked that the QUE next and prev addresses and tried to understand if a buffer isn't available but no luck. I think I need to get at the Channel object parameter queEmpty or numQueBuf to understand what the blocking issue is. Can you recommend any APIs or registers to debug this issue? Or maybe I am going about this the wrong way?
Also, if I move the callback registration before the VPORT_CMD_START, the dequeue blocks the first time the callback occurs.
Another strange thing is the callback registration does not exit before the callback is called by the video driver.
FVID_control(disChInfo.chanHandle, VPORT_CMD_START, NULL);
FVID_control(capChInfo.chanHandle, VPORT_CMD_START, NULL);
vport_callback_params.cbArg = CAP_CALLBACK_ID;
vport_callback_params.vIntCbFxn = VideoCallback;
vport_callback_params.vIntMask = VPORT_INT_CCMP; // Capture complete interrupt mask.
status |= FVID_control (capChInfo.chanHandle, VPORT_CMD_SET_VINTCB, &vport_callback_params);
// Enter main processing loop.
while (1)
{
MBX_pend(hmbxProcess, &buf, SYS_FOREVER)
std::memcpy((Uint8 *)disChInfo.frame->frame.iFrm.y1, (Uint8 *)buf.frame->frame.iFrm.y1, FRAME_SIZE);
/* Invalidate the buffer before giving to capture driver */
BCACHE_inv((Uint8 *)buf.frame->frame.iFrm.y1, (FRAME_SIZE), TRUE);
// Give capture buffer back to vport capture driver.
if (FVID_queue(buf.chanHandle, &(buf.frame)) != IOM_COMPLETED)
BCACHE_wbInv((Uint8 *)disChInfo.frame->frame.iFrm.y1, (FRAME_SIZE), TRUE);
status = FVID_exchange(disChInfo.chanHandle, &(disChInfo.frame));
}/* while (1) */
I removed the LOG_printf's in the above code to make it easier for viewing, but the trace shows no issues other than blocking in dequeue. The text in () are my comments I added to decode my log output for you.
0 Successfully initialized EDMA3
1 Successfully created capture channel 2. Status = 0
2 Creating display channel
3 Successfully created display channel. Status = 0
4 Start display and capture
5 ent cb 84 (enter callback, mask = 0x84)
6 ent cb dq (enter callback dequeue)
7 x cb dq (exit callback dequeue)
8 x cb reg (exit callback registration)
9 mbxpend (enter mbx pend)
10 x mbxpend (exit mbxpend)
11 x memcpy (exit memcopy)
12 dis exchg (enter display exchange)
13 ent cb 84 (enter callback, mask = 0x84)
14 ent cb dq (enter callback dequeue) <- It stays here forever. Arg. [:(]
I am using dvsdk_1_10_00_26_DM648 and BIOS 5.33.06. Code Gen v6.08 and CCS 3.3.82.
Thanks