This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Low priority accumulation Hwi interrupt

Other Parts Discussed in Thread: SYSBIOS

Hello,

I'm trying to use high/low priority accumulation  queues with an HWI held to dsp.

On "KeyStone Architecture  Multicore Navigator" (SPRUGR9D) document, table 5-1 and 5-6 is reported:

... The low priority accumulator uses up to 512 queues divided into
16 channels, each channel being 32 continuous queues. Each channel triggers one broadcast interrupt. These
queues can also be used as general purpose queues. 

while for high priority queues:

The high priority accumulator uses up to 32 queues, one per
channel. Each channel triggers a core-specific interrupt. These queues can also be used as general purpose
queues.

 

So with high priority queues I have one interrupt for one queue and all works fine. But with low priority I have one interrupt for a set of 32 queues. 

How can I discriminate in ISR wich queues generates the interrupt?

The folliwing code works for one low priority queue number 0

/* program the low priority accumulator */
 memset ((Void *) &tcp3dRxLoPrioList, 0, sizeof (tcp3dRxLoPrioList));
 cfgLo.channel = accChannelNum; //0
cfgLo.command = Qmss_AccCmd_ENABLE_CHANNEL;
 cfgLo.queueEnMask = 0x00000001;
 cfgLo.listAddress = ((UInt32) tcp3dRxLoPrioList); 
/* Get queue manager and queue number from handle */
queInfo = Qmss_getQueueNumber (rxQueHnd);
cfgLo.queMgrIndex = queInfo.qNum;
cfgLo.maxPageEntries = 2;//ACC_ENTRY_SIZE;
cfgLo.timerLoadCount = 0;
cfgLo.interruptPacingMode = Qmss_AccPacingMode_NONE;
cfgLo.listEntrySize = Qmss_AccEntrySize_REG_D;
cfgLo.listCountMode = Qmss_AccCountMode_ENTRY_COUNT;
cfgLo.multiQueueMode = Qmss_AccQueueMode_SINGLE_QUEUE;

if ((result = Qmss_programAccumulator (Qmss_PdspId_PDSP2, &cfgLo)) != QMSS_ACC_SOK)
{
System_printf ("Error programming high priority accumulator for channel : %d queue : %d error code : %d\n",
cfgLo.channel, cfgLo.queMgrIndex, result);
return;
}
else
System_printf ("high priority accumulator programmed for channel : %d queue : %d\n",
cfgLo.channel, cfgLo.queMgrIndex); 

 

eventId = 32;
vectId = 10;

Hwi_Params_init(&hwiParams);

hwiParams.arg = (UArg)NULL;
hwiParams.eventId = eventId;
hwiParams.enableInt = FALSE;

Hwi_create(vectId, (ti_sysbios_hal_Hwi_FuncPtr) Tcp3d_HiPriorityAccumISR, &hwiParams, NULL);

/* Enable interrupt. */
Hwi_enableInterrupt(vectId); 

 

 

void Tcp3d_HiPriorityAccumISR(void)
{
UInt8 count = 0;
Uint8 i = 0;
Qmss_Queue rxReturnQInfo;
Cppi_Desc* pCppiDesc;

 
/* Process ISR.
*
* Get the number of entries in accumulator list.
* The hardware enqueues data alternatively to Ping/Pong buffer lists in
* the accumulator. Hence, we need to track which list (Ping/Pong)
* we serviced the last time and accordingly process the other one
* this time around.
*/
if(!tcp3dIsAccPingListUsed)
{
/* Serviced Pong list last time. So read off the Ping list now */
 count = tcp3dRxLoPrioList[0];
 tcp3dLoRxLoPrioList[0] = 0;
}
else
{
/* Serviced Pong list last time. So read off the Ping list now */
 count = tcp3dRxLoPrioList[TCP3D_ACC_ENTRY_SIZE];
 tcp3dRxLoPrioList[TCP3D_ACC_ENTRY_SIZE] = 0;
}

/* Process all the Results received
*
* Skip the first entry in the list that contains the
* entry count and proceed processing results.
*/
for(i = 1; i <= count; i ++)
{
/* Get the result descriptor.
*
* The hardware enqueues data alternatively to Ping/Pong buffer lists in
* the accumulator. Hence, we need to track which list (Ping/Pong)
* we serviced the last time and accordingly process the other one
* this time around.
*/
if(!tcp3dIsAccPingListUsed)
{
/* Serviced Pong list last time. So read off the Ping list now */
 tcp3dRxPktList[i - 1] = tcp3dRxLoPrioList[i];
 tcp3dRxLoPrioList [i] = NULL;
}
else
{
/* Serviced Ping list last time. So read off the Pong list now
*
* Skip over Ping list length to arrive at Pong list start.
*/
 tcp3dRxPktList[i - 1] = tcp3dRxLoPrioList [i + TCP3D_ACC_ENTRY_SIZE];
 tcp3dRxLoPrioList[i + TCP3D_ACC_ENTRY_SIZE] = NULL;
}

/* Increment the number of packets received and saved for application processing */
tcp3dRxPktListCtr++;

pCppiDesc = (Cppi_Desc*)tcp3dRxPktList[i - 1];
rxReturnQInfo = Cppi_getReturnQueue(Cppi_getDescType(pCppiDesc), pCppiDesc);

/* Push descriptor back to free queue */
Qmss_queuePushDescSize((Qmss_QueueHnd) rxReturnQInfo.qNum, pCppiDesc, QMSS_DESC_SIZE(pCppiDesc));
}

/* Clear the accumulator list and save whether we used Ping/Pong
* list information for next time around.
*/
if(!tcp3dIsAccPingListUsed)
{
/* Just processed Ping list */
tcp3dIsAccPingListUsed = 1;
}
else
{
/* Just processed Pong list */
tcp3dIsAccPingListUsed = 0;
 }

/* Clear INTD */
Qmss_ackInterrupt(32+QMSS_ACC_TCP3D_A_CH_RX, 1);
Qmss_setEoiVector(Qmss_IntdInterruptType_LOW, QMSS_ACC_TCP3D_A_CH_RX);

/* Done processing interrupt. Return */
return;

 

If I want to use also queue number 1 I think that I have to change  cfgLo.queueEnMask = 0x00000011;

But dsp interrupt remain the same for both queues. How can I know which queue (0 or 1) generates the interrupt in the ISR?

 

Regards,

Luca