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(); } }
void SYS_DMA_ChannelSetup ( SYS_DMA_CHANNEL_HANDLE handle, SYS_DMA_CHANNEL_OP_MODE modeEnable, DMA_TRIGGER_SOURCE eventSrc ) { SYS_DMA_CHANNEL_OBJECT *chanObj; DMA_CHANNEL channelNumber; chanObj = (SYS_DMA_CHANNEL_OBJECT *) handle; channelNumber = (chanObj - (SYS_DMA_CHANNEL_OBJECT *) &gSysDMAChannelObj[0]); /* Setup the channel modes */ /* Basic mode, nothing specifically needs to be set */ if(SYS_DMA_CHANNEL_OP_MODE_BASIC & modeEnable) { /* Do nothing */ ; } /* Pattern match Abort */ if(SYS_DMA_CHANNEL_OP_MODE_MATCH_ABORT & modeEnable) { PLIB_DMA_ChannelXTriggerEnable( DMA_ID_0, channelNumber, DMA_CHANNEL_TRIGGER_PATTERN_MATCH_ABORT); } /* Channel chaining mode */ if(SYS_DMA_CHANNEL_OP_MODE_CHAIN_HIGH & modeEnable) { PLIB_DMA_ChannelXChainEnable( DMA_ID_0, channelNumber); PLIB_DMA_ChannelXChainToHigher(DMA_ID_0, channelNumber); PLIB_DMA_ChannelXDisabledEnablesEvents(DMA_ID_0, channelNumber); } else if(SYS_DMA_CHANNEL_OP_MODE_CHAIN_LOW & modeEnable) { PLIB_DMA_ChannelXChainEnable( DMA_ID_0, channelNumber); PLIB_DMA_ChannelXChainToLower(DMA_ID_0, channelNumber); PLIB_DMA_ChannelXDisabledEnablesEvents(DMA_ID_0, channelNumber); } else { ; } /* Auto Enable mode */ if(SYS_DMA_CHANNEL_OP_MODE_AUTO & modeEnable) { PLIB_DMA_ChannelXAutoEnable( DMA_ID_0, channelNumber); } /* CRC Enable */ if(SYS_DMA_CHANNEL_OP_MODE_CRC & modeEnable) { PLIB_DMA_CRCEnable( DMA_ID_0); } /* Setup the DMA Trigger Source and Enable it */ if(DMA_TRIGGER_SOURCE_NONE == eventSrc) { /* This is polling mode of Implementation */ PLIB_DMA_ChannelXINTSourceEnable(DMA_ID_0, channelNumber, DMA_INT_BLOCK_TRANSFER_COMPLETE); PLIB_DMA_ChannelXINTSourceEnable(DMA_ID_0, channelNumber, DMA_INT_ADDRESS_ERROR); } else { PLIB_DMA_ChannelXStartIRQSet( DMA_ID_0, channelNumber, eventSrc); PLIB_DMA_ChannelXTriggerEnable( DMA_ID_0, channelNumber, DMA_CHANNEL_TRIGGER_TRANSFER_START); /* We need to notify the user on the completion of a transfer request. * Setting the DMA block completion transfer interrupt. */ PLIB_DMA_ChannelXINTSourceEnable(DMA_ID_0, channelNumber, DMA_INT_BLOCK_TRANSFER_COMPLETE); PLIB_DMA_ChannelXINTSourceEnable(DMA_ID_0, channelNumber, DMA_INT_ADDRESS_ERROR); } return; }