Beispiel #1
0
/* Function:
    void SYS_DMA_ChannelTransferAdd
    (
        SYS_DMA_CHANNEL_HANDLE handle,
        const void *srcAddr, size_t srcSize
        const void *destAddr, size_t destSize,
        size_t cellSize
    )

  Summary:
    Adds a data transfer to a DMA channel and Enables the channel to start
    data transfer.

  Description:
    This function adds a data transfer characteristics for a DMA channel. The
    The source and the destination addresses, source and destination lengths,
    The number of bytes transferred per cell event are set. It also enables
    the channel to start data transfer.

    If the requesting client registered an event callback with the service,
    the service will issue a SYS_DMA_TRANSFER_EVENT_COMPLETE or
    SYS_DMA_TRANSFER_EVENT_ABORT  event if the transfered was processed
    successfully of SYS_DMA_TRANSFER_EVENT_ERROR event if the transfer was not
    processed successfully.

  Remarks:
    None.
*/
void SYS_DMA_ChannelTransferAdd
(
    SYS_DMA_CHANNEL_HANDLE handle,
    const void *srcAddr, size_t srcSize,
    const void *destAddr, size_t destSize,
    size_t cellSize
)
{
    SYS_DMA_CHANNEL_OBJECT *chanObj;
    DMA_CHANNEL channelNumber;

    chanObj = (SYS_DMA_CHANNEL_OBJECT *) handle;
    channelNumber = (chanObj  - (SYS_DMA_CHANNEL_OBJECT *) &gSysDMAChannelObj[0]);

    /* Set the transfer paramteters */
    PLIB_DMA_ChannelXSourceStartAddressSet(DMA_ID_0, channelNumber, (uint32_t) srcAddr);
    PLIB_DMA_ChannelXSourceSizeSet(DMA_ID_0, channelNumber, (uint16_t) srcSize);
    PLIB_DMA_ChannelXDestinationStartAddressSet(DMA_ID_0, channelNumber,(uint32_t) destAddr);
    PLIB_DMA_ChannelXDestinationSizeSet(DMA_ID_0, channelNumber, (uint16_t) destSize);
    PLIB_DMA_ChannelXCellSizeSet(DMA_ID_0, channelNumber,(uint16_t) cellSize);

    /* Enable the channel */
    PLIB_DMA_ChannelXEnable(DMA_ID_0, channelNumber);
    return;
}
Beispiel #2
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 #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();
    }
}