BOOL lhlTxIsrHandler(void) { BOOL bRet=FALSE; uint32 asyTxStat; #ifdef _STATISTICS lhlStatistics.TxReqInt++; #endif //_STATISTICS llcLinkRegRead(ASY_TX_STAT_REG_DP, &asyTxStat); if (postedTxState.currTxContext) { if (asyTxStat & LLC_ASY_TX_CMPLT) { volatile POSTED_TX_CONTEXT * pContext = &postedTxState.contexts[postedTxState.currTxContext-1]; pContext->txStat = asyTxStat; pContext->bPosted = FALSE; fSYS_TRACE1(SYSDEBUG_TRACE_TESTS,postedTxState.currTxContext); pContext->tack = *((volatile uint32 *)TIMER2_CUR_VAL); if (pContext->semID) bRet |= TRUE; //_lTCSemaphoreSignal(pContext->semID); postedTxState.currTxContext=0; ChkAndSend(); } else { //spurious or request for posting } } else { //We have no context, so let's see if we have something to send ChkAndSend(); } fSYS_TRACE1(SYSDEBUG_TRACE_TESTS,bRet); return bRet; }
static void ChkAndSend(void) { uint32 asyTxStat; llcLinkRegRead(ASY_TX_STAT_REG_DP, &asyTxStat); if ((asyTxStat && LLC_ASY_TX_CMPLT) || ((asyTxStat && LLC_ASY_TX_STATUS_MASK) == LLC_ASY_TX_ST_IDLE)) { uint16 i=0; POSTED_TX_CONTEXT * pContext = postedTxState.contexts; while (i<MAX_TX_CONTEXTS) { if (pContext->bPosted) { pContext->tsnd = *((volatile uint32 *)TIMER2_CUR_VAL); pContext->tack = 0; //move the packet to the LLC llcSendContext(pContext->pPayload, pContext->header.quadlets, pContext->payloadLen, pContext->headerLen); postedTxState.currTxContext=i+1; return; } i++; pContext++; } } else { //in progress, we will get back when completed } }
uint32 llc_interrupt_isr(uint32 vector, void *data) { uint32 intEventReg; BOOL bDsr = FALSE; llcLinkRegRead(INTERRUPT_REG_CLEAR_DP, &intEventReg); //events which are not masked if ((intEventReg & LLC_INT_BIT(LLCID_INTR_OUT)) == 0) return CYG_ISR_HANDLED; //mask all those handled by DSR, DSR will unmask when done bDsr = intEventReg & llcIntInstalledMask; if (bDsr) llcLinkRegWrite(INTR_MASK_REG_CLEAR_DP, ~(HANDLE_BY_ISR | LLC_INT_BIT(LLCID_INTR_OUT))); // Clear the ones we are handeling here llcLinkRegWrite(INTERRUPT_REG_CLEAR_DP, intEventReg&(HANDLE_BY_ISR | LLC_INT_BIT(LLCID_INTR_OUT))); llcIntEvents++; //we need to look for bus reset and if we see it we must mask out LLCID_ASY_RX_PKT_AVL and leave it //to the DSR BR handler to read whatever is in the FIFO //The LLCID_BUS_RST_RXD might be masked waiting for DSR so we need to check the raw status uint32 rawEvent; llcLinkRegRead(INTERRUPT_REG_DP, &rawEvent); if (rawEvent & LLC_INT_BIT(LLCID_BUS_RST_RXD)) { //at some point the DSR will handle this, we really don't need and ISR processing for now llcLinkRegWrite(INTR_MASK_REG_CLEAR_DP, HANDLE_BY_ISR); //we have to rely on the DSR putting us back into normal mode } else { if (intEventReg & LLC_INT_BIT(LLCID_ASY_RX_PKT_AVL)) if (_llcIntEventIsrCallCallback(LLC_INT_ISR_RX)) llcIsrDsrRxEvent = 1; if (intEventReg & LLC_INT_BIT(LLCID_ASY_TX_CMPL)) if (_llcIntEventIsrCallCallback(LLC_INT_ISR_TX)) llcIsrDsrTxEvent = 1; } //as long as we have unhandled Isr->dsr's keep calling the DSR. if (llcIsrDsrRxEvent || llcIsrDsrTxEvent) bDsr = 1; return bDsr ? CYG_ISR_CALL_DSR : CYG_ISR_HANDLED; }
BOOL llcIntEventIsIntEnabled(uint32 index) { uint32 intEventReg; uint32 bit; if (index >= LLC_INT_ITEMS) { return FALSE; } bit = LLC_INT_BIT(index); llcLinkRegRead(INTR_MASK_REG_SET_DP, &intEventReg); return ((bit & intEventReg) == bit); }
// Reads and verifies selfID buffer HRESULT llcGetSelfIDs(SELFID_BUNDLE *pSelfID) { HRESULT hResult = NO_ERROR; uint16 tCode = TCODE_PHY_PACKET+1; int16 i = 0; int16 j = 0; uint32 dataCount; QUADLET PacketId; QUADLET SelfIDPacket; uint8 first; uint32 fifoStat; pSelfID->bValid = FALSE; pSelfID->numSIDQuads = 0; pSelfID->numNodes = 0; resetCount = 0; BusStatus = 0; // Checking bus status register bits llcLinkRegRead(BUS_STAT_REG_DP, &BusStatus); llcLinkRegRead(ASY_RX_FIFO_QLETS_REG_DP, &dataCount); dataCount &= LLC_RX_QLT_AVAIL_MASK; while(dataCount) { // Look for a headet which is a PHy package while ((tCode != TCODE_PHY_PACKET) && (dataCount)) { llcLinkRegRead(ASY_RX_FIFO_REG_DP, &PacketId); dataCount--; llcLinkRegRead(ARFIFO_STAT_REG_DP, &fifoStat); if (fifoStat & LLC_ARFIFO_HEAD) { // this quadlet is a head tCode = (uint16)((PacketId&MASK_TCODE)>>SHIFT_TCODE); } } if (tCode == TCODE_PHY_PACKET) // Check for PHY packets { llcSelfIDBuffer[0] = PacketId; i = 1; first = TRUE; while (dataCount) // Skip trailer { llcLinkRegRead(ASY_RX_FIFO_REG_DP, &SelfIDPacket); dataCount--; llcSelfIDBuffer[i++] = SelfIDPacket; if ((SelfIDPacket & LLC_SELFID_MASK) == LLC_SELFID_PACKET) // SelfIDPacket { if (first) { // Look for more SelfIDPacket bundles j = 0; pSelfID->numSIDQuads = 0; pSelfID->numNodes = 0; first = FALSE; } // Save self-ids pSelfID->sid[j++] = SelfIDPacket; // count self-ids after verified pSelfID->numSIDQuads++; // if a first-packet, count it as a unique node if ((SelfIDPacket & SELF_ID_CONT_PACKET) == 0) { pSelfID->numNodes++; } } else if ((SelfIDPacket & LLC_TRAILER_MASK) == LLC_TRAILER_PACKET) // Trailer { first = TRUE; resetCount = (uint8)((SelfIDPacket&LLC_BUS_RESET_CNT_MASK) >> LLC_BUS_RESET_CNT_SHIFT); //ML: Leave new packets in the buffer // This has been verified to fix problems with the first ReadRequests received after // a bus reset. //break; //so after reading the first Bundle we return. return hResult; } else // Any other packet { // Skip remaining packets !!!! // ML: we should never end here!! } } } else {
void llc_interrupt_dsr(uint32 vector, uint32 count, void * data) { uint32 intEventReg; llcLinkRegRead(INTERRUPT_REG_DP, &intEventReg); //read raw interrupt stat intEventReg &=llcIntInstalledMask; //and with handled stat //is there any ISR requests if (llcIsrDsrTxEvent) { intEventReg |= LLC_INT_BIT(LLCID_ASY_TX_CMPL); llcIsrDsrTxEvent = 0; } if (llcIsrDsrRxEvent) { intEventReg |= LLC_INT_BIT(LLCID_ASY_RX_PKT_AVL); llcIsrDsrRxEvent = 0; } //fSYS_TRACE1(SYSDEBUG_TRACE_TESTS,intEventReg); if (!intEventReg) { //should never happen llcLinkRegWrite(INTR_MASK_REG_SET_DP, llcIntInstalledMask & ~HANDLE_BY_ISR); return; } // Clear all pending interrupts serviced llcLinkRegWrite(INTERRUPT_REG_CLEAR_DP, intEventReg & ~(HANDLE_BY_ISR | LLC_INT_BIT(LLCID_INTR_OUT))); if (llcIntState == LLC_INT_STATE_WAIT_BUSRESET || llcIntState == LLC_INT_STATE_PROCESS_NORMAL || llcIntState == LLC_INT_STATE_PROCESS_SI) { if (intEventReg & LLC_INT_BIT(LLCID_BUS_RST_RXD)) //new bus reset { _llcIntEventSetState(LLC_INT_STATE_WAIT_SI_COMPLETE); llcIntEvent[LLCID_BUS_RST_RXD]++; _llcIntEventCallCallback(LLCID_BUS_RST_RXD); } } if (llcIntState == LLC_INT_STATE_WAIT_SI_COMPLETE) { if (intEventReg & LLC_INT_BIT(LLCID_BUS_INIT_OVR)) //new selfid complete { llcIntEvent[LLCID_BUS_INIT_OVR]++; _llcIntEventSetState(LLC_INT_STATE_PROCESS_SI); _llcIntEventCallCallback(LLCID_BUS_INIT_OVR); } } if (llcIntState == LLC_INT_STATE_PROCESS_NORMAL) { uint8 i; uint8 id; //only handle general items for optimization for (i = 0; i < LLCINT_EVENT_GENERAL_ITEMS; i++) { id = llcIntEventGeneral[i]; if (intEventReg & LLC_INT_BIT(id)) { llcIntEvent[id]++; _llcIntEventCallCallback(id); intEventReg &= ~LLC_INT_BIT(id); if (intEventReg == 0) break; } } } llcLinkRegWrite(INTR_MASK_REG_SET_DP, llcIntInstalledMask & ~(HANDLE_BY_ISR | LLC_INT_BIT(LLCID_INTR_OUT))); }