Example #1
0
/*****************************************************************************
 * FUNCTION: ProcessInterruptServiceResult
 *
 * RETURNS: N/A
 *
 * PARAMS:
 *      N/A
 *
 *
 *  NOTES: Processes EXINT from MRF24W.  Called by WFProcess().
 *****************************************************************************/
static void ProcessInterruptServiceResult(void)
{
    uint8_t  hostIntRegValue;
    uint8_t  hostIntMaskRegValue;
    uint8_t  hostInt;

    /* read hostInt register to determine cause of interrupt */
    hostIntRegValue = Read8BitWFRegister(WF_HOST_INTR_REG);

    // OR in the saved interrupts during the time when we were waiting for raw complete, set by WFEintHandler()
    hostIntRegValue |= g_HostIntSaved;

    // done with the saved interrupts, clear variable
    g_HostIntSaved = 0;


    hostIntMaskRegValue  = Read8BitWFRegister(WF_HOST_MASK_REG);

    // AND the two registers together to determine which active, enabled interrupt has occurred
    hostInt = hostIntRegValue & hostIntMaskRegValue;

    // if received a level 2 interrupt (should not happen!)
    if((hostInt & WF_HOST_INT_MASK_INT2) == WF_HOST_INT_MASK_INT2)
    {
        /* read the 16 bit interrupt register */
        /* CURRENTLY unhandled interrupt */
        WF_ASSERT(false);
        WF_EintEnable();
    }
    // else if got a FIFO 1 Threshold interrupt (Management Fifo)
    else if((hostInt & WF_HOST_INT_MASK_FIFO_1_THRESHOLD) == WF_HOST_INT_MASK_FIFO_1_THRESHOLD)
    {
        /* clear this interrupt */
        Write8BitWFRegister(WF_HOST_INTR_REG, WF_HOST_INT_MASK_FIFO_1_THRESHOLD);
        // notify MAC state machine that management message needs to be processed
        g_MgmtReadMsgReady = true;
    }
    // else if got a FIFO 0 Threshold Interrupt (Data Fifo)
    else if((hostInt & WF_HOST_INT_MASK_FIFO_0_THRESHOLD) == WF_HOST_INT_MASK_FIFO_0_THRESHOLD)
    {
        /* clear this interrupt */
        Write8BitWFRegister(WF_HOST_INTR_REG, WF_HOST_INT_MASK_FIFO_0_THRESHOLD);

        g_HostRAWDataPacketReceived = true;  /* this global flag is used in MACGetHeader() to determine a received data packet */
    }
    // else got a Host interrupt that we don't handle
    else if(hostInt)
    {
        /* unhandled interrupt */
       /* clear this interrupt */
        Write8BitWFRegister(WF_HOST_INTR_REG, hostInt);
        WF_EintEnable();
    }
    // we got a spurious interrupt (no bits set in register)
    else
    {
        /* spurious interrupt */
        WF_EintEnable();
    }
}
Example #2
0
/*****************************************************************************
 * FUNCTION: WFEintHandler
 *
 * RETURNS: N/A
 *
 * PARAMS:
 *      N/A
 *
 *
 *  NOTES: This function must be called once, each time an external interrupt
 *      is received from the WiFi device.   The WiFi Driver will schedule any
 *      subsequent SPI communication to process the interrupt.
 *
 * IMPORTANT NOTE: This function, and functions that are called by this function
 *                 must NOT use local variables.  The PIC18, or any other processor
 *                 that uses overlay memory will corrupt the logical stack within
 *                 overlay memory if the interrupt uses local variables.  
 *                 If local variables are used within an interrupt routine the toolchain 
 *                 cannot properly determine how not to overwrite local variables in 
 *                 non-interrupt releated functions, specifically the function that was 
 *                 interrupted.
 *****************************************************************************/
void WFEintHandler(void)
{
    /*--------------------------------------------------------*/    
    /* if driver is waiting for a RAW Move Complete interrupt */
    /*--------------------------------------------------------*/
	if (RawMoveState.waitingForRawMoveCompleteInterrupt)
	{
		/* read hostInt register and hostIntMask register to determine cause of interrupt */
		g_EintHostIntRegValue      = Read8BitWFRegister(WF_HOST_INTR_REG);
		g_EintHostIntMaskRegValue  = Read8BitWFRegister(WF_HOST_MASK_REG);
    
		// AND the two registers together to determine which active, enabled interrupt has occurred
		g_EintHostInt = g_EintHostIntRegValue & g_EintHostIntMaskRegValue;

        /* if a RAW0 or RAW1 interrupt occurred, signifying RAW Move completed */
		if(g_EintHostInt & (WF_HOST_INT_MASK_RAW_0_INT_0 | WF_HOST_INT_MASK_RAW_1_INT_0))
		{
    		/* save the copy of the active interrupts */
			RawMoveState.rawInterrupt = g_EintHostInt;
			RawMoveState.waitingForRawMoveCompleteInterrupt = FALSE;
			
			/* if no other interrupts occurred other than a RAW0 or RAW1 interrupt */
			if((g_EintHostInt & ~(WF_HOST_INT_MASK_RAW_0_INT_0 | WF_HOST_INT_MASK_RAW_1_INT_0)) == 0u)
			{
				/* clear the RAW interrupts, re-enable interrupts, and exit */
				Write8BitWFRegister(WF_HOST_INTR_REG, (WF_HOST_INT_MASK_RAW_0_INT_0 | WF_HOST_INT_MASK_RAW_1_INT_0));
				WF_EintEnable();
				return;
			}
			/* else we got a RAW0 or RAW1 interrupt, but, there is also at least one other interrupt present */
    		else
    		{
    			// save the other interrupts and clear them for now
    			// keep interrupts disabled
    			g_HostIntSaved |= (g_EintHostInt & ~(WF_HOST_INT_MASK_RAW_0_INT_0 | WF_HOST_INT_MASK_RAW_1_INT_0));
    			Write8BitWFRegister(WF_HOST_INTR_REG, g_EintHostInt);
    		}
	    }
	    /*----------------------------------------------------------------------------------*/	    
	    /* else we did not get a RAW interrupt, but we did get at least one other interrupt */
	    /*----------------------------------------------------------------------------------*/
	    else
        {
			g_HostIntSaved |= g_EintHostInt;
			Write8BitWFRegister(WF_HOST_INTR_REG, g_EintHostInt);
			WF_EintEnable();
        }
	}

   	// Once we're in here, external interrupts have already been disabled so no need to call WF_EintDisable() in here
   
    /* notify state machine that an interrupt occurred */
    g_ExIntNeedsServicing = TRUE;
}
Example #3
0
/*****************************************************************************
 * FUNCTION: RawMove
 *
 * RETURNS: Number of bytes that were overlayed (not always applicable)
 *
 * PARAMS:
 *      rawId   - RAW ID
 *      srcDest - MRF24W object that will either source or destination of move
 *      rawIsDestination - TRUE if RAW engine is the destination, FALSE if its the source
 *      size    - number of bytes to overlay (not always applicable)
 *
 *  NOTES: Performs a RAW move operation between a RAW engine and a MRF24W object
 *****************************************************************************/
 static UINT16 RawMove(UINT16   rawId,           
                       UINT16   srcDest,         
                       BOOL     rawIsDestination,  
                       UINT16   size)              
{
    UINT16 byteCount;
    UINT8 regId;
    UINT8  regValue8;
    UINT16 ctrlVal = 0;

    if (rawIsDestination)
    {
        ctrlVal |= 0x8000;
    }
    
    /* fix later, simply need to ensure that size is 12 bits are less */
    ctrlVal |= (srcDest << 8);              /* defines are already shifted by 4 bits */
    ctrlVal |= ((size >> 8) & 0x0f) << 8;   /* MS 4 bits of size (bits 11:8)         */
    ctrlVal |= (size & 0x00ff);             /* LS 8 bits of size (bits 7:0)          */

    /* Clear the interrupt bit in the register */
    regValue8 = (rawId == RAW_ID_0)? WF_HOST_INT_MASK_RAW_0_INT_0 : WF_HOST_INT_MASK_RAW_1_INT_0;
    Write8BitWFRegister(WF_HOST_INTR_REG, regValue8);

    /* write update control value to register to control register */
    regId = (rawId == RAW_ID_0) ? RAW_0_CTRL_0_REG : RAW_1_CTRL_0_REG;
    Write16BitWFRegister(regId, ctrlVal);

    // Wait for the RAW move operation to complete, and read back the number of bytes, if any, that were overlayed
    byteCount = WaitForRawMoveComplete(rawId);

    return byteCount;
}
/*****************************************************************************
  Function: UINT16 RawMove(UINT16 rawId, 
                           UINT16 srcDest, 
                           BOOL rawIsDestination, 
                           UINT16 size)

  Summary:
	Performs RAW Move operation

  Description:
	Raw Moves perform a variety of operations (e.g. allocating tx buffers, 
	mounting rx buffers, copying from one raw window to another, etc.)

  Precondition:
	None

  Parameters:
	rawId -- Raw ID 0 thru 5, except is srcDest is RAW_COPY, in which case rawId 
	         contains the source address in the upper 4 bits and destination 
	         address in lower 4 bits.
	         
	srcDest -- object that will either be the source or destination of the move:
	              RAW_MAC          
                  RAW_MGMT_POOL    
                  RAW_DATA_POOL    
                  RAW_SCRATCH_POOL 
                  RAW_STACK_MEM    
                  RAW_COPY (this object not allowed, handled in RawToRawCopy() )         
                  
    rawIsDestination -- true is srcDest is the destination, false if srcDest is 
                        the source of the move

	size -- number of bytes to overlay (not always applicable)
	             
  Returns:
  	Not always applicable, depending on the type of the raw move.  When applicable, 
  	this function returns the number of bytes overlayed by the raw move.
  	
  Remarks:
	None
*****************************************************************************/
static UINT16 RawMove(UINT16    rawId,           
                       UINT16   srcDest,         
                       BOOL     rawIsDestination,  
                       UINT16   size)              
{
    UINT16 byteCount;
    UINT8  regId;
    UINT8  regValue;
    UINT16 ctrlVal = 0;
    
    /* create control value that will be written to raw control register, which initiates the raw move */
    if (rawIsDestination)
    {
        ctrlVal |= 0x8000;
    }
    /* fix later, simply need to ensure that size is 12 bits are less */
    ctrlVal |= (srcDest << 8);              /* defines are already shifted by 4 bits */
    ctrlVal |= ((size >> 8) & 0x0f) << 8;   /* MS 4 bits of size (bits 11:8)         */
    ctrlVal |= (size & 0x00ff);             /* LS 8 bits of size (bits 7:0)          */

    /*---------------------------------------------------------------------------------------*/
    /* this next 'if' block is used to ensure the expected raw interrupt signifying raw move */
    /* complete is cleared                                                                   */
    /*---------------------------------------------------------------------------------------*/
    
    /* if doing a raw move on Raw 0 or 1 (data rx or data tx) */
    if (rawId <= RAW_ID_1)
    {
        /* Clear the interrupt bit in the host interrupt register (Raw 0 and 1 are in 8-bit host intr reg) */
        regValue = (UINT8)g_RawIntMask[rawId];
        Write8BitWFRegister(WF_HOST_INTR_REG, regValue);
    }
    /* else doing raw move on mgmt rx, mgmt tx, or scratch */
    else
    {
        /* Clear the interrupt bit in the host interrupt 2 register (Raw 2,3, and 4 are in 16-bit host intr2 reg */
        regValue = g_RawIntMask[rawId];
        Write16BitWFRegister(WF_HOST_INTR2_REG, regValue);
    }  

    /*------------------------------------------------------------------------------------------------*/
    /* now that the expected raw move complete interrupt has been cleared and we are ready to receive */
    /* it, initiate the raw move operation by writing to the appropriate RawCtrl0.                    */
    /*------------------------------------------------------------------------------------------------*/
    regId = g_RawCtrl0Reg[rawId];                   /* get RawCtrl0 register address for desired raw ID */
    Write16BitWFRegister(regId, ctrlVal);           /* write ctrl value to register                     */
    byteCount = WaitForRawMoveComplete(rawId);      /* wait for raw move to complete                    */

    /* byte count is not valid for all raw move operations */
    return byteCount;
}
Example #5
0
/*****************************************************************************
 * FUNCTION: HostInterruptRegInit
 *
 * RETURNS: N/A
 *
 * PARAMS:
 *      hostIntrMaskRegMask - The bit mask to be modified.
 *      state -  one of WF_EXINT_DISABLE, WF_EXINT_ENABLE where
 *                Disable implies clearing the bits and enable sets the bits.
 *
 *
 *  NOTES: Initializes the 8-bit Host Interrupt register on the MRF24WB0M with the
 *      specified mask value either setting or clearing the mask register
 *      as determined by the input parameter state.  The process requires
 *      2 spi operations which are performed in a blocking fashion.  The
 *      function does not return until both spi operations have completed.
 *****************************************************************************/
static void HostInterruptRegInit(UINT8 hostIntrMaskRegMask,
                                 UINT8 state)
{
    UINT8 hostIntMaskValue;

    /* Host Int Register is a status register where each bit indicates a specific event  */
    /* has occurred. In addition, writing a 1 to a bit location in this register clears  */
    /* the event.                                                                        */

    /* Host Int Mask Register is used to enable those events activated in Host Int Register */
    /* to cause an interrupt to the host                                                    */

    /* read current state of Host Interrupt Mask register */
    hostIntMaskValue = Read8BitWFRegister(WF_HOST_MASK_REG);

    /* if caller is disabling a set of interrupts */
    if (state == WF_INT_DISABLE)
    {
        /* zero out that set of interrupts in the interrupt mask copy */
        hostIntMaskValue = (hostIntMaskValue & ~hostIntrMaskRegMask);
    }
    /* else caller is enabling a set of interrupts */
    else
    {
        /* set to 1 that set of interrupts in the interrupt mask copy */
        hostIntMaskValue = (hostIntMaskValue & ~hostIntrMaskRegMask) | hostIntrMaskRegMask;
    }

    /* write out new interrupt mask value */
    Write8BitWFRegister(WF_HOST_MASK_REG, hostIntMaskValue);

    /* ensure that pending interrupts from those updated interrupts are cleared */
    Write8BitWFRegister(WF_HOST_INTR_REG, hostIntrMaskRegMask);
    
    
}
Example #6
0
/*****************************************************************************
 * FUNCTION: RawMove
 *
 * RETURNS: Number of bytes that were overlayed (not always applicable)
 *
 * PARAMS:
 *      rawId   - RAW ID
 *      srcDest - MRF24W object that will either source or destination of move
 *      rawIsDestination - true if RAW engine is the destination, false if its the source
 *      size    - number of bytes to overlay (not always applicable)
 *
 *  NOTES: Performs a RAW move operation between a RAW engine and a MRF24W object
 *****************************************************************************/
 static uint16_t RawMove(uint16_t   rawId,
                         uint16_t   srcDest,
                         bool       rawIsDestination,
                         uint16_t   size)
{
    uint16_t byteCount;
    uint8_t regId;
    uint8_t  regValue8;
    uint16_t ctrlVal = 0;

    if (rawIsDestination)
    {
        ctrlVal |= 0x8000;
    }

    /* fix later, simply need to ensure that size is 12 bits are less */
    /* if size is legal, (bits 11:0) of ctrlVal contains the information of size, */
    /* (bits 15:12) of ctriVal contains the information of srcDest */
    ctrlVal |= (srcDest << 8);              /* defines are already shifted by 4 bits */
    ctrlVal |= ((size >> 8) & 0x0f) << 8;   /* MS 4 bits of size (bits 11:8)         */
    ctrlVal |= (size & 0x00ff);             /* LS 8 bits of size (bits 7:0)          */

    /* Clear the interrupt bit in the register */
    regValue8 = (rawId == RAW_ID_0) ? WF_HOST_INT_MASK_RAW_0_INT_0:WF_HOST_INT_MASK_RAW_1_INT_0;
    Write8BitWFRegister(WF_HOST_INTR_REG, regValue8);

    /* write update control value to register to control register */
    regId = (rawId==RAW_ID_0) ? RAW_0_CTRL_0_REG:RAW_1_CTRL_0_REG;
    gIntDisabled = WF_EintIsDisabled();
    WF_EintDisable();
    Write16BitWFRegister(regId, ctrlVal);

    // Wait for the RAW move operation to complete, and read back the number of bytes, if any, that were overlayed
    byteCount = WaitForRawMoveComplete(rawId);

    return byteCount;
}
Example #7
0
/*****************************************************************************
 * FUNCTION: ProcessInterruptServiceResult
 *
 * RETURNS: N/A
 *
 * PARAMS:
 *      N/A
 *
 *
 *  NOTES: Processes EXINT from MRF24WB0M.  Called by WFProcess().
 *****************************************************************************/
static void ProcessInterruptServiceResult(void)
{
    UINT8  hostIntRegValue;
    UINT8  hostIntMaskRegValue;
    UINT8  hostInt;

    /* Ensure the MRF24WB0M stays awake (only applies if PS-Poll was enabled) */
    EnsureWFisAwake();

    /* read hostInt register to determine cause of interrupt */
    hostIntRegValue = Read8BitWFRegister(WF_HOST_INTR_REG);

    // OR in the saved interrupts during the time when we were waiting for raw complete, set by WFEintHandler()
    hostIntRegValue |= g_HostIntSaved;
    
    // done with the saved interrupts, clear variable
    g_HostIntSaved = 0;


    hostIntMaskRegValue  = Read8BitWFRegister(WF_HOST_MASK_REG);

    // AND the two registers together to determine which active, enabled interrupt has occurred
    hostInt = hostIntRegValue & hostIntMaskRegValue;

    // if received a level 2 interrupt (should not happen!)
    if((hostInt & WF_HOST_INT_MASK_INT2) == WF_HOST_INT_MASK_INT2)
    {
        /* read the 16 bit interrupt register */
        /* CURRENTLY unhandled interrupt */
        WF_ASSERT(FALSE);
        WF_EintEnable();
    }
    // else if got a FIFO 1 Threshold interrupt (Management Fifo)
    else if((hostInt & WF_HOST_INT_MASK_FIFO_1_THRESHOLD) == WF_HOST_INT_MASK_FIFO_1_THRESHOLD)
    {
        /* clear this interrupt */
        Write8BitWFRegister(WF_HOST_INTR_REG, WF_HOST_INT_MASK_FIFO_1_THRESHOLD);
        // notify MAC state machine that management message needs to be processed
        g_MgmtReadMsgReady = TRUE; 
    }
    // else if got a FIFO 0 Threshold Interrupt (Data Fifo)
    else if((hostInt & WF_HOST_INT_MASK_FIFO_0_THRESHOLD) == WF_HOST_INT_MASK_FIFO_0_THRESHOLD)
    {
        /* clear this interrupt */
        Write8BitWFRegister(WF_HOST_INTR_REG, WF_HOST_INT_MASK_FIFO_0_THRESHOLD);

        g_HostRAWDataPacketReceived = TRUE;  /* this global flag is used in MACGetHeader() to determine a received data packet */
#if defined(WF_USE_DATA_TX_RX_FUNCTIONS)
        {
            UINT16 rxDataPacketLength;
            /* determine length of packet and signal the rx data packet event */
            rxDataPacketLength = Read16BitWFRegister(WF_HOST_RFIFO_BCNT0_REG) & 0x0fff; /* LS 12 bits are the data length */
            WF_ProcessEvent(WF_EVENT_RX_PACKET_RECEIVED, rxDataPacketLength); 
        }
#endif
    }
    // else got a Host interrupt that we don't handle
    else if(hostInt)
    {
        /* unhandled interrupt */
       /* clear this interrupt */
        Write8BitWFRegister(WF_HOST_INTR_REG, hostInt);
        WF_EintEnable();
    }
    // we got a spurious interrupt (no bits set in register)
    else
    {
        /* spurious interrupt */
        WF_EintEnable();
    }
}
Example #8
0
/*****************************************************************************
  Function: uint16_t RawMove(uint16_t rawId,
                           uint16_t srcDest,
                           bool     rawIsDestination,
                           uint16_t size)

  Summary:
    Performs RAW Move operation

  Description:
    Raw Moves perform a variety of operations (e.g. allocating tx buffers,
    mounting rx buffers, copying from one raw window to another, etc.)

  Precondition:
    None

  Parameters:
    rawId -- Raw ID 0 thru 5, except is srcDest is RAW_COPY, in which case rawId
             contains the source address in the upper 4 bits and destination
             address in lower 4 bits.

    srcDest -- object that will either be the source or destination of the move:
                  RAW_MAC
                  RAW_MGMT_POOL
                  RAW_DATA_POOL
                  RAW_SCRATCH_POOL
                  RAW_STACK_MEM
                  RAW_COPY (this object not allowed, handled in RawToRawCopy() )

    rawIsDestination -- true is srcDest is the destination, false if srcDest is
                        the source of the move

    size -- number of bytes to overlay (not always applicable)

  Returns:
     Not always applicable, depending on the type of the raw move.  When applicable,
     this function returns the number of bytes overlayed by the raw move.

  Remarks:
    None
*****************************************************************************/
uint16_t RawMove(uint16_t rawId,
                 uint16_t srcDest,
                 bool     rawIsDestination,
                 uint16_t size)
{
    uint16_t byteCount;
    uint8_t  regId;
    uint8_t  regValue;
    uint16_t ctrlVal = 0;
    bool intDisabled;

    // save current state of External interrupt and disable it
    intDisabled = WF_isEintDisabled();
    WF_EintDisable();

    /*
    These variables are shared with the ISR so need to be careful when setting them.
    the WF_EintHandler() is the isr that will touch these variables but will only touch
    them if RawMoveState.waitingForRawMoveCompleteInterrupt is set to TRUE.
    RawMoveState.waitingForRawMoveCompleteInterrupt is only set TRUE here and only here.
    so as long as we set RawMoveState.rawInterrupt first and then set RawMoveState.waitingForRawMoveCompleteInterrupt
    to TRUE, we are guaranteed that the ISR won't touch RawMoveState.rawInterrupt and
    RawMoveState.waitingForRawMoveCompleteInterrupt.
    */
    RawMoveState.rawInterruptMask  = 0;
    RawMoveState.waitingForRawMoveCompleteInterrupt = true;

    /* create control value that will be written to raw control register, which initiates the raw move */
    if (rawIsDestination)
    {
        ctrlVal |= 0x8000;
    }
    /* fix later, simply need to ensure that size is 12 bits are less */
    ctrlVal |= (srcDest << 8);              /* defines are already shifted by 4 bits */
    ctrlVal |= ((size >> 8) & 0x0f) << 8;   /* MS 4 bits of size (bits 11:8)         */
    ctrlVal |= (size & 0x00ff);             /* LS 8 bits of size (bits 7:0)          */

    /*---------------------------------------------------------------------------------------*/
    /* this next 'if' block is used to ensure the expected raw interrupt signifying raw move */
    /* complete is cleared                                                                   */
    /*---------------------------------------------------------------------------------------*/

    /* if doing a raw move on Raw 0 or 1 (data rx or data tx) */
    if (rawId <= RAW_ID_1)
    {
        /* Clear the interrupt bit in the host interrupt register (Raw 0 and 1 are in 8-bit host intr reg) */
        regValue = (uint8_t)g_RawIntMask[rawId];
        Write8BitWFRegister(WF_HOST_INTR_REG, regValue);
    }
    /* else doing raw move on mgmt rx, mgmt tx, or scratch */
    else
    {
        /* Clear the interrupt bit in the host interrupt 2 register (Raw 2,3, and 4 are in 16-bit host intr2 reg */
        regValue = g_RawIntMask[rawId];
        Write16BitWFRegister(WF_HOST_INTR2_REG, regValue);
    }

    /*------------------------------------------------------------------------------------------------*/
    /* now that the expected raw move complete interrupt has been cleared and we are ready to receive */
    /* it, initiate the raw move operation by writing to the appropriate RawCtrl0.                    */
    /*------------------------------------------------------------------------------------------------*/
    regId = g_RawCtrl0Reg[rawId];                   /* get RawCtrl0 register address for desired raw ID */
    Write16BitWFRegister(regId, ctrlVal);           /* write ctrl value to register                     */

    // enable interrupts so we get raw move complete interrupt
    WF_EintEnable();
    byteCount = WaitForRawMoveComplete(rawId);      /* wait for raw move to complete                    */

    // if interrupts were disabled coming into this function, put back to that state
    if (intDisabled)
    {
        WF_EintDisable();
    }

    /* byte count is not valid for all raw move operations */
    return byteCount;
}
/*****************************************************************************
 * FUNCTION: ProcessInterruptServiceResult
 *
 * RETURNS: N/A
 *
 * PARAMS:
 *      N/A
 *
 *
 *  NOTES: Processes EXINT from MRF24W.  Called by WFProcess().
 *****************************************************************************/
static void ProcessInterruptServiceResult(void)
{
    UINT8  hostIntRegValue;
    UINT8  hostIntMaskRegValue;
    UINT8  hostInt;

    /* read hostInt register to determine cause of interrupt */
    hostIntRegValue = Read8BitWFRegister(WF_HOST_INTR_REG);

    // OR in the saved interrupts during the time when we were waiting for raw complete, set by WFEintHandler()
    hostIntRegValue |= g_HostIntSaved;
    
    // done with the saved interrupts, clear variable
    g_HostIntSaved = 0;


    hostIntMaskRegValue  = Read8BitWFRegister(WF_HOST_MASK_REG);

    // AND the two registers together to determine which active, enabled interrupt has occurred
    hostInt = hostIntRegValue & hostIntMaskRegValue;

    /* if received a level 2 interrupt (either a mgmt tx or mgmt rx Raw move complete occurred */
    if((hostInt & WF_HOST_INT_MASK_INT2) == WF_HOST_INT_MASK_INT2)
    {
        UINT16 hostInt2;

        hostInt2 = Read16BitWFRegister(WF_HOST_INTR2_REG);
        if (hostInt2 & WF_HOST_INT_MASK_MAIL_BOX_0_WRT)
        {
            // the MRF24WG module CPU has hit an assert condition
            // display the assert info and do a WF_ASSERT
            #if defined(MRF24WG)
                WF_DisplayModuleAssertInfo();
            #endif
            WF_ASSERT(FALSE);
        }

        WF_ASSERT(FALSE); /* This should not happen. Other than the module assert, this interrupt is only used to     */
                          /* signify RAW Move Complete for RAW2/3/4.  This event should be cleared in EintHandler().  */
        /* clear this interrupt */
        Write16BitWFRegister(WF_HOST_INTR2_REG, WF_HOST_INT_MASK_INT2);
    }
    /* else if got a FIFO 1 Threshold interrupt (Management Fifo).  Mgmt Rx msg ready to proces. */
    else if((hostInt & WF_HOST_INT_MASK_FIFO_1_THRESHOLD) == WF_HOST_INT_MASK_FIFO_1_THRESHOLD)
    {
        /* clear this interrupt */
        Write8BitWFRegister(WF_HOST_INTR_REG, WF_HOST_INT_MASK_FIFO_1_THRESHOLD);
        
        // notify MAC state machine that management message needs to be processed
        g_MgmtReadMsgReady = TRUE; 
    }
    /* else if got a FIFO 0 Threshold Interrupt (Data Fifo).  Data Rx msg ready to process. */
    else if((hostInt & WF_HOST_INT_MASK_FIFO_0_THRESHOLD) == WF_HOST_INT_MASK_FIFO_0_THRESHOLD)
    {
        /* clear this interrupt */
        Write8BitWFRegister(WF_HOST_INTR_REG, WF_HOST_INT_MASK_FIFO_0_THRESHOLD);
        
        /* notify MAC state machine that data message needs to be processed */
        g_HostRAWDataPacketReceived = TRUE;  
    }
    /* else got a Host interrupt that we don't handle */
    else if(hostInt)
    {
        /* clear this interrupt */
        Write8BitWFRegister(WF_HOST_INTR_REG, hostInt);
        WF_EintEnable();
    }
    /* we got a spurious interrupt (no bits set in register) */
    else
    {
        /* spurious interrupt */
        WF_EintEnable();
    }
}
Example #10
0
/*
 * MRF24WG interrupt handler, called directly from the the interrupt routine,
 * _WFInterrupt() in wf_eint_stub.c.
 *
 * Must be called, once, for each MRF24WG interrupt.
 *
 * IMPORTANT: This function, and functions called from this function must not
 * use local variables, especially if the MCU uses overlay memory
 * like the Microchip PIC18 MCU.  The logical stack is contained
 * within the overlay memory, and if the interrupt uses local variables
 * the toolchain cannot be relied on to not overwrite local variables
 * in non-interrupt functions, specifically the function that was
 * interrupted by this interrupt.
 */
void WF_EintHandler()
{
    /*--------------------------------------------------------*/
    /* if driver is waiting for a RAW Move Complete interrupt */
    /*--------------------------------------------------------*/
    if (isWaitingForRawMoveCompleteInterrupt())
    {
        // read hostInt register and hostIntMask register to determine cause of interrupt
        // TODO: [NOTE: Stellaris requires two reads to get proper SPI read?]
        g_EintHostIntRegValue      = Read8BitWFRegister(WF_HOST_INTR_REG);
        g_EintHostIntRegValue      = Read8BitWFRegister(WF_HOST_INTR_REG);

        g_EintHostIntMaskRegValue  = Read8BitWFRegister(WF_HOST_MASK_REG);

        // AND the two registers together to determine which active, enabled interrupt has occurred
        g_EintHostInt = g_EintHostIntRegValue & g_EintHostIntMaskRegValue;


        // If a Raw move complete interrupt occurred
        if (g_EintHostInt & (WF_HOST_INT_MASK_RAW_0_INT_0 | WF_HOST_INT_MASK_RAW_1_INT_0 | WF_HOST_INT_MASK_INT2))
        {
            // Let the Raw driver know which interrupt occurred and clear the flag
            SignalRawInterruptEvent(g_EintHostInt);
            ClearWaitingForRawMoveCompleteInterrupt();

            /* if no other interrupts occurred other than a RAW0/RAW1/RAW2/RAW3/RAW4 Raw Move Complete */
            if ((g_EintHostInt & ~(WF_HOST_INT_MASK_RAW_0_INT_0 |
                                   WF_HOST_INT_MASK_RAW_1_INT_0 |
                                   WF_HOST_INT_MASK_INT2)) == 0)
            {
                /* clear the RAW interrupts, re-enable interrupts, and exit */
                Write8BitWFRegister(WF_HOST_INTR_REG, (WF_HOST_INT_MASK_RAW_0_INT_0 |
                                                       WF_HOST_INT_MASK_RAW_1_INT_0 |
                                                       WF_HOST_INT_MASK_INT2));

                Write16BitWFRegister(WF_HOST_INTR2_REG, (WF_HOST_INT_MASK_RAW_2_INT_0 |
                                                         WF_HOST_INT_MASK_RAW_3_INT_0 |
                                                         WF_HOST_INT_MASK_RAW_4_INT_0 |
                                                         WF_HOST_INT_MASK_RAW_5_INT_0));

                WF_EintEnable();
                return;
            }
            /* else we got a RAW0/RAW1/RAW2/RAW3/RAW4/RAW5 Raw Move Complete interrupt, but, there is also at */
            /* least one other interrupt present                                                               */
            else
            {
                // save the other interrupts and clear them, along with the Raw Move Complete interrupts
                // keep interrupts disabled
                Write16BitWFRegister(WF_HOST_INTR2_REG, (WF_HOST_INT_MASK_RAW_2_INT_0   |
                                                         WF_HOST_INT_MASK_RAW_3_INT_0   |
                                                         WF_HOST_INT_MASK_RAW_4_INT_0   |
                                                         WF_HOST_INT_MASK_RAW_5_INT_0));
                g_HostIntSaved |= (g_EintHostInt & ~(WF_HOST_INT_MASK_RAW_0_INT_0 | WF_HOST_INT_MASK_RAW_1_INT_0 | WF_HOST_INT_MASK_INT2));
                Write8BitWFRegister(WF_HOST_INTR_REG, g_EintHostInt);

                // leave interrupt disabled for now
            }
        }
        /*--------------------------------------------------------------------------------------------------*/
        /* else we did not get a 'RAW Move Complete' interrupt, but we did get at least one other interrupt */
        /*--------------------------------------------------------------------------------------------------*/
        else
        {
            g_HostIntSaved |= g_EintHostInt;
            Write8BitWFRegister(WF_HOST_INTR_REG, g_EintHostInt);
            WF_EintEnable();
        }
    }

    // used by InterruptCheck()
    g_ExIntNeedsServicing = true;
}
Example #11
0
/*
 * Periodically called to check if the MRF24WG external interrupt occurred, and
 * completes the interrupt processing.
 *
 * Some processing takes place in the actual interrupt routine, and some processing
 * takes place later in the round robin.  This function checks if an interrupt
 * has occurred, and if so, performs the rest of the interrupt processing.
 */
void InterruptCheck()
{
    uint8_t  hostIntRegValue;
    uint8_t  hostIntMaskRegValue;
    uint8_t  hostInt;
    uint16_t hostInt2;
    uint32_t assertInfo;

    // in no interrupt to process
    if (!g_ExIntNeedsServicing)
    {
        return;
    }

    g_ExIntNeedsServicing = false;

     /* read hostInt register to determine cause of interrupt */
    hostIntRegValue = Read8BitWFRegister(WF_HOST_INTR_REG);

    // OR in the saved interrupts during the time when we were waiting for raw complete, set by WFEintHandler()
    hostIntRegValue |= g_HostIntSaved;

    // done with the saved interrupts, clear variable
    g_HostIntSaved = 0;

    hostIntMaskRegValue  = Read8BitWFRegister(WF_HOST_MASK_REG);

    // AND the two registers together to determine which active, enabled interrupt has occurred
    hostInt = hostIntRegValue & hostIntMaskRegValue;

    // if received a level 2 interrupt
    if ((hostInt & WF_HOST_INT_MASK_INT2) == WF_HOST_INT_MASK_INT2)
    {
        // Either a mgmt tx or mgmt rx Raw move complete occurred, which is how
        // this interrupt is normally used.  If this is the case, the event was
        // already handled in WF_EintHandler(), and all we need to do here is
        // clear the interrupt.  However, there is one other event to check for;
        // this interrupt is also used by the MRF24WG to signal that it has
        // hit an assert condition.  So, we check for that here.

        // if the MRF24WG has hit an assert condition
        hostInt2 = Read16BitWFRegister(WF_HOST_INTR2_REG);
        if (hostInt2 & WF_HOST_INT_MASK_MAIL_BOX_0_WRT)
        {
            // module number in upper 8 bits, assert information in lower 20 bits
            assertInfo = (((uint32_t)Read16BitWFRegister(WF_HOST_MAIL_BOX_0_MSW_REG)) << 16) |
                                     Read16BitWFRegister(WF_HOST_MAIL_BOX_0_LSW_REG);
            // signal this event
            EventEnqueue(WF_EVENT_MRF24WG_MODULE_ASSERT, assertInfo);
        }

        /* clear this interrupt */
        Write16BitWFRegister(WF_HOST_INTR2_REG, WF_HOST_INT_MASK_INT2);
    }
    /* else if got a FIFO 1 Threshold interrupt (Management Fifo).  Mgmt Rx msg ready to proces. */
    else if ((hostInt & WF_HOST_INT_MASK_FIFO_1_THRESHOLD) == WF_HOST_INT_MASK_FIFO_1_THRESHOLD)
    {
        /* clear this interrupt */
        Write8BitWFRegister(WF_HOST_INTR_REG, WF_HOST_INT_MASK_FIFO_1_THRESHOLD);

        // signal that a mgmt msg, either confirm or indicate, has been received
        // and needs to be processed
        SignalMgmtMsgRx();
    }
    /* else if got a FIFO 0 Threshold Interrupt (Data Fifo).  Data Rx msg ready to process. */
    else if ((hostInt & WF_HOST_INT_MASK_FIFO_0_THRESHOLD) == WF_HOST_INT_MASK_FIFO_0_THRESHOLD)
    {
        /* clear this interrupt */
        Write8BitWFRegister(WF_HOST_INTR_REG, WF_HOST_INT_MASK_FIFO_0_THRESHOLD);

        // signal that a data msg has been received and needs to be processed
        SignalPacketRx();
    }
    /* else got a Host interrupt that we don't handle */
    else if (hostInt) {
        /* clear this interrupt */
        Write8BitWFRegister(WF_HOST_INTR_REG, hostInt);
        WF_EintEnable();
    }
    /* we got a spurious interrupt (no bits set in register) */
    else {
        /* spurious interrupt */
        WF_EintEnable();
    }
}