/***************************************************************************** * 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; }
/***************************************************************************** * FUNCTION: WaitForRawMoveComplete * * RETURNS: Number of bytes that were overlayed (not always applicable) * * PARAMS: * rawId - RAW ID * * NOTES: Waits for a RAW move to complete. *****************************************************************************/ static UINT16 WaitForRawMoveComplete(UINT8 rawId) { UINT8 rawIntMask; UINT16 byteCount; UINT8 regId; BOOL intDisabled; #if defined(WF_DEBUG) UINT32 startTickCount; UINT32 maxAllowedTicks; #endif /* create mask to check against for Raw Move complete interrupt for either RAW0 or RAW1 */ if (rawId <= RAW_ID_1) { /* will be either raw 0 or raw 1 */ rawIntMask = (rawId == RAW_ID_0)?WF_HOST_INT_MASK_RAW_0_INT_0:WF_HOST_INT_MASK_RAW_1_INT_0; } else { /* will be INTR2 bit in host register, signifying RAW2, RAW3, or RAW4 */ rawIntMask = WF_HOST_INT_MASK_INT2; } /* These variables are shared with the ISR so need to be careful when setting them. the WFEintHandler() 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 guranteed that the ISR won't touch RawMoveState.rawInterrupt and RawMoveState.waitingForRawMoveCompleteInterrupt. */ RawMoveState.rawInterrupt = 0; RawMoveState.waitingForRawMoveCompleteInterrupt = TRUE; // save state of external interrupt here intDisabled = WF_EintIsDisabled(); // if external interrupt is disabled, enable it because we need it for the while(1) loop to exit if(intDisabled) { WF_EintEnable(); } else if(WF_EintIsPending()) { WF_EintEnable(); } #if defined(WF_DEBUG) // Before we enter the while loop, get the tick timer count and save it maxAllowedTicks = TICKS_PER_SECOND / 2; /* 500 ms timeout */ startTickCount = (UINT32)TickGet(); #endif while (1) { /* if received an external interrupt that signalled the RAW Move */ /* completed then break out of this loop */ if(RawMoveState.rawInterrupt & rawIntMask) { break; } #if defined(WF_DEBUG) /* If timed out waiting for RAW Move complete than lock up */ if (TickGet() - startTickCount >= maxAllowedTicks) { WF_ASSERT(FALSE); } #endif } /* end while */ /* if interrupt was enabled by us here, we should disable it now that we're finished */ if(intDisabled) { WF_EintDisable(); } /* read the byte count and return it */ regId = g_RawCtrl1Reg[rawId]; byteCount = Read16BitWFRegister(regId); return ( byteCount ); }
/***************************************************************************** * FUNCTION: WaitForRawMoveComplete * * RETURNS: Number of bytes that were overlayed (not always applicable) * * PARAMS: * rawId - RAW ID * * NOTES: Waits for a RAW move to complete. *****************************************************************************/ static uint16_t WaitForRawMoveComplete(uint8_t rawId) { uint8_t rawIntMask; uint16_t byteCount; uint8_t regId; bool intDisabled; #if defined(SYS_DEBUG_ENABLE) SYS_TICK startTickCount; SYS_TICK maxAllowedTicks; #endif /* create mask to check against for Raw Move complete interrupt for either RAW0 or RAW1 */ rawIntMask = (rawId == RAW_ID_0)?WF_HOST_INT_MASK_RAW_0_INT_0:WF_HOST_INT_MASK_RAW_1_INT_0; /* These variables are shared with the ISR so need to be careful when setting them. the WFEintHandler() 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 guranteed that the ISR won't touch RawMoveState.rawInterrupt and RawMoveState.waitingForRawMoveCompleteInterrupt. */ RawMoveState.rawInterrupt = 0; RawMoveState.waitingForRawMoveCompleteInterrupt = true; // save state of external interrupt here intDisabled = WF_EintIsDisabled(); // if external interrupt is disabled, enable it because we need it for the while(1) loop to exit if(intDisabled) { WF_EintEnable(); } else if(WF_EintIsPending()) { WF_EintEnable(); } #if defined(SYS_DEBUG_ENABLE) // Before we enter the while loop, get the tick timer count and save it maxAllowedTicks = SYS_TICK_TicksPerSecondGet() / 2; /* 500 ms timeout */ startTickCount = SYS_TICK_Get(); #endif while (1) { /* if received an external interrupt that signalled the RAW Move */ /* completed then break out of this loop */ if(RawMoveState.rawInterrupt & rawIntMask) { break; } #if defined(SYS_DEBUG_ENABLE) /* If timed out waiting for RAW Move complete than lock up */ #if defined (__C30__) uint32_t x = 0; T2CON &= 0x7FFF; // Temporary Workaround for 16 bit device Timer23 read issue x = SYS_TICK_Get(); T2CON |= 0x8000; if ((x - startTickCount) >= maxAllowedTicks) { SYS_ASSERT(false, ""); } #else if (SYS_TICK_Get() - startTickCount >= maxAllowedTicks) { SYS_ASSERT(false, ""); } #endif #endif } /* end while */ /* if interrupt was enabled by us here, we should disable it now that we're finished */ if(intDisabled) { WF_EintDisable(); } /* read the byte count and return it */ regId = (rawId == RAW_ID_0)?WF_HOST_RAW0_CTRL1_REG:WF_HOST_RAW1_CTRL1_REG; byteCount = Read16BitWFRegister(regId); return ( byteCount ); }
void IspSpiDMA_Rx(uint8_t *pbuf,uint16_t length) { bool intDisabled; unsigned char txTrash[3000]; // pbuf points to uint8_t array of data to be received from MRF // length indicates number of bytes to read intDisabled = WF_EintIsDisabled(); WF_EintDisable(); IEC1CLR=0x00030000; // disable DMA channel 0&1 interrupts IFS1CLR=0x00030000; // clear existing DMA channel 0&1 interrupt flag PLIB_DMA_Enable(0); // DMACONSET=0x00008000; // enable the DMA controller PLIB_DMA_ChannelXPrioritySelect(0,DMA_CHANNEL_0, DMA_CHANNEL_PRIORITY_3);//DCH0CONSET = 0x3; // channel off, pri 3, no chaining PLIB_DMA_ChannelXChainDisable(0,DMA_CHANNEL_0); PLIB_DMA_ChannelXPrioritySelect(0,DMA_CHANNEL_1, DMA_CHANNEL_PRIORITY_2);// DCH1CONSET = 0x03;//0x62; PLIB_DMA_ChannelXChainEnable(0,DMA_CHANNEL_1); DCH0ECONCLR=0xFFFFFFFF; // no start or stop irq?s, no pattern match DCH1ECONCLR=0xFFFFFFFF; // no start or stop irq?s, no pattern match // program the transfer PLIB_DMA_ChannelXSourceStartAddressSet (0,DMA_CHANNEL_0, ((unsigned long int)txTrash) & 0x1FFFFFFFL); PLIB_DMA_ChannelXDestinationStartAddressSet(0,DMA_CHANNEL_1, ((unsigned long int)pbuf) & 0x1FFFFFFFL); if( MRF24W_SPI_CHN == 1) { PLIB_DMA_ChannelXDestinationStartAddressSet(0,DMA_CHANNEL_0, ((unsigned long int)&SPI1BUF) & 0x1FFFFFFFL); PLIB_DMA_ChannelXSourceStartAddressSet (0,DMA_CHANNEL_1, ((unsigned long int)&SPI1BUF) & 0x1FFFFFFFL); } else if( MRF24W_SPI_CHN == 2) { PLIB_DMA_ChannelXDestinationStartAddressSet(0,DMA_CHANNEL_0, ((unsigned long int)&SPI2BUF) & 0x1FFFFFFFL); PLIB_DMA_ChannelXSourceStartAddressSet (0,DMA_CHANNEL_1, ((unsigned long int)&SPI2BUF) & 0x1FFFFFFFL); } PLIB_DMA_ChannelXSourceSizeSet (0,DMA_CHANNEL_0,length); PLIB_DMA_ChannelXDestinationSizeSet(0,DMA_CHANNEL_0,1 ); PLIB_DMA_ChannelXCellSizeSet (0,DMA_CHANNEL_0,1 ); PLIB_DMA_ChannelXSourceSizeSet (0,DMA_CHANNEL_1,1); PLIB_DMA_ChannelXDestinationSizeSet(0,DMA_CHANNEL_1,length); PLIB_DMA_ChannelXCellSizeSet (0,DMA_CHANNEL_1,1 ); DCH0INTCLR=0x00ff00ff; // clear existing events, disable all interrupts DCH1INTCLR=0x00ff00ff; // clear existing events, disable all interrupts // initiate a transfer PLIB_DMA_ChannelXStartIRQSet(0, DMA_CHANNEL_0, DMA_TRIGGER_SPI_1_TRANSMIT); PLIB_DMA_ChannelXTriggerEnable(0, DMA_CHANNEL_0, DMA_CHANNEL_TRIGGER_TRANSFER_START); PLIB_DMA_ChannelXStartIRQSet(0, DMA_CHANNEL_1, DMA_TRIGGER_SPI_1_RECEIVE); PLIB_DMA_ChannelXTriggerEnable(0, DMA_CHANNEL_1, DMA_CHANNEL_TRIGGER_TRANSFER_START); PLIB_DMA_ChannelXEnable(0,DMA_CHANNEL_0); PLIB_DMA_ChannelXEnable(0,DMA_CHANNEL_1); // DCH0ECONSET=0x00000080; // set CFORCE to 1 // do something else // poll to see that the transfer was done while(true) { register int pollCnt; // use a poll counter. // continuously polling the DMA controller in a tight // loop would affect the performance of the DMA transfer int dma0Flags=DCH0INT; int dma1Flags = DCH1INT; if((dma0Flags&0xb)&&(dma1Flags&0xb)) { // one of CHERIF (DCHxINT<0>), CHTAIF (DCHxINT<1>) // or CHBCIF (DCHxINT<3>) flags set break; // transfer completed } pollCnt=length<<1; // use an adjusted value here while(pollCnt--); // wait before reading again the DMA controller } PLIB_DMA_Disable(0); if(!intDisabled) { WF_EintEnable(); } }
/***************************************************************************** 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: WaitForRawMoveComplete * * RETURNS: Number of bytes that were overlayed (not always applicable) * * PARAMS: * rawId - RAW ID * * NOTES: Waits for a RAW move to complete. *****************************************************************************/ static uint16_t WaitForRawMoveComplete(uint8_t rawId) { uint8_t rawIntMask; uint16_t byteCount; uint8_t regId; #if defined(WF_DEBUG) uint32_t startTickCount; uint32_t maxAllowedTicks; #endif /* create mask to check against for Raw Move complete interrupt for either RAW0 or RAW1 */ rawIntMask = (rawId == RAW_ID_0) ? WF_HOST_INT_MASK_RAW_0_INT_0:WF_HOST_INT_MASK_RAW_1_INT_0; /* These variables are shared with the ISR so need to be careful when setting them. the WFEintHandler() 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 guranteed that the ISR won't touch RawMoveState.rawInterrupt and RawMoveState.waitingForRawMoveCompleteInterrupt. */ RawMoveState.rawInterrupt = 0; RawMoveState.waitingForRawMoveCompleteInterrupt = true; WF_EintEnable(); #if defined(WF_DEBUG) // Before we enter the while loop, get the tick timer count and save it maxAllowedTicks = TICKS_PER_SECOND / 2; /* 500 ms timeout */ startTickCount = (uint32_t)TickGet(); #endif while (1) { /* if received an external interrupt that signalled the RAW Move */ /* completed then break out of this loop */ if (RawMoveState.rawInterrupt & rawIntMask) { break; } #if defined(WF_DEBUG) /* If timed out waiting for RAW Move complete than lock up */ if (TickGet() - startTickCount >= maxAllowedTicks) { WF_ASSERT(false); } #endif } /* end while */ /* if interrupt was enabled by us here, we should disable it now that we're finished */ if (gIntDisabled) { WF_EintDisable(); } /* read the byte count and return it */ regId = (rawId == RAW_ID_0) ? WF_HOST_RAW0_CTRL1_REG:WF_HOST_RAW1_CTRL1_REG; byteCount = Read16BitWFRegister(regId); return ( byteCount ); }