Beispiel #1
0
int main(void)
{
    /* Disable JTAG to free up PORTA pins */
    DDPCONbits.JTAGEN = 0;

    /* Set the lower 8 bits of PORTA as output (for Explorer-16 LEDs),
       clear the bits to ensure there is no mismatch when they are toggled */
    PLIB_PORTS_DirectionOutputSet(PORTS_ID_0, PORT_CHANNEL_A, (PORTS_DATA_MASK)0x00FF);
    PLIB_PORTS_Clear(PORTS_ID_0, PORT_CHANNEL_A, (PORTS_DATA_MASK)0x00FF);

    /* Enable the DMA module */
    PLIB_DMA_Enable(DMA_ID_0);

    /* Channel is continuously enabled */
    PLIB_DMA_ChannelXAutoEnable(DMA_ID_0, DMA_CHANNEL_0);

    /* Set the source and destinaton addresses (addresses are converted from virtual to physical) */
    PLIB_DMA_ChannelXSourceStartAddressSet(DMA_ID_0, DMA_CHANNEL_0, (uint32_t)LED_pattern);
    PLIB_DMA_ChannelXDestinationStartAddressSet(DMA_ID_0, DMA_CHANNEL_0, (uint32_t)&LATA);

    /* Set the source and destination sizes */
    PLIB_DMA_ChannelXSourceSizeSet(DMA_ID_0, DMA_CHANNEL_0, sizeof(LED_pattern));
    PLIB_DMA_ChannelXDestinationSizeSet(DMA_ID_0, DMA_CHANNEL_0, 1);

    /* Set the number of bytes per transfer */
    PLIB_DMA_ChannelXCellSizeSet(DMA_ID_0, DMA_CHANNEL_0, 1);

    /* DMA transfer to start on Timer 1 interrupt */
    PLIB_DMA_ChannelXTriggerEnable(DMA_ID_0, DMA_CHANNEL_0, DMA_CHANNEL_TRIGGER_TRANSFER_START);
    PLIB_DMA_ChannelXStartIRQSet(DMA_ID_0, DMA_CHANNEL_0, DMA_TRIGGER_TIMER_1);

    /* Setup Timer 1 to trigger an interrupt 10 times a second */
    PLIB_TMR_ClockSourceSelect(TMR_ID_1, TMR_CLOCK_SOURCE_PERIPHERAL_CLOCK);
    PLIB_TMR_PrescaleSelect(TMR_ID_1, TMR_PRESCALE_VALUE_256);
    PLIB_TMR_Counter16BitClear(TMR_ID_1);
    PLIB_TMR_Period16BitSet(TMR_ID_1, 3906);

    /* Enable the Timer 1 interrupt source, set its priority level to 2, set
       its subpriority level to 0 */
    PLIB_INT_SourceEnable(INT_ID_0, INT_SOURCE_TIMER_1);
    PLIB_INT_VectorPrioritySet(INT_ID_0, INT_VECTOR_T1, INT_PRIORITY_LEVEL2);
    PLIB_INT_VectorSubPrioritySet(INT_ID_0, INT_VECTOR_T1, INT_SUBPRIORITY_LEVEL0);

    /* Enable multi-vectored interrupts, enable the generation of interrupts to the CPU */
    PLIB_INT_MultiVectorSelect(INT_ID_0);
    PLIB_INT_Enable(INT_ID_0);

    /* Enable DMA channel 0 */
    PLIB_DMA_ChannelXEnable(DMA_ID_0, DMA_CHANNEL_0);

    /* Start Timer 1 */
    PLIB_TMR_Start(TMR_ID_1);

    /* Stuck in this loop, waiting for interrupts to occur */
    while (1);

    /* Program should not go here during normal operation */
    return EXIT_FAILURE;
}
Beispiel #2
0
/* Function:
    SYS_MODULE_OBJ SYS_DMA_Initialize(const SYS_MODULE_INIT * const init)

  Summary:
    Initializes and Enables the DMA Controller.

  Description:
    This function Enables the DMA module. Enable/Disable stop in idle mode
    feature based on the passed parameter value.

    This routine initializes the DMA module making it ready for clients to
    open and use it. The initialization data is specified by the init parameter.

  Remarks:
    This routine must be called before any other DMA systems service routines
    are called.

    Not all features are available on all micro-controllers.
*/
SYS_MODULE_OBJ SYS_DMA_Initialize(const SYS_MODULE_INIT * const init)
{
    SYS_DMA_INIT *initp;
    uint8_t chanIndex;
    SYS_DMA_CHANNEL_OBJECT *chanObj;


    /* Validate the init object */
    if ((SYS_MODULE_INIT *)NULL == init)
    {
        SYS_ASSERT(false, "Invalid Init Object");
        return SYS_MODULE_OBJ_INVALID;
    }

    initp = (SYS_DMA_INIT *)init;

    /* Enable/disable the stop in idle mode feature. */
#if defined (PLIB_DMA_ExistsStopInIdle)
    if(true == PLIB_DMA_ExistsStopInIdle(DMA_ID_0))
    {
        if(SYS_DMA_SIDL_DISABLE == initp->sidl)
        {
            PLIB_DMA_StopInIdleDisable(DMA_ID_0);
        }
        else if(SYS_DMA_SIDL_ENABLE == initp->sidl)
        {
            PLIB_DMA_StopInIdleEnable(DMA_ID_0);
        }
    }
#endif
    /* Enable the DMA module */
    PLIB_DMA_Enable(DMA_ID_0);

    /* Initialize the available channel objects */
    chanObj             =   (SYS_DMA_CHANNEL_OBJECT *)&gSysDMAChannelObj[0];
    for(chanIndex = 0; chanIndex < SYS_DMA_CHANNEL_COUNT; chanIndex++)
    {
        chanObj->inUse          =    false;
        chanObj->pEventCallBack =    NULL;
        chanObj->hClientArg     =    0;
        chanObj->errorInfo      =    SYS_DMA_ERROR_NONE;
        chanObj                 =    chanObj + 1;
        /* Initializing all channel priorities as 0 */
        PLIB_DMA_ChannelXPrioritySelect(DMA_ID_0, chanIndex, chanIndex);
    }

    /* Return the object structure */
    return ((SYS_MODULE_OBJ) initp);
}
Beispiel #3
0
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();
    }
}