/** * \file * Driver for the cc2430 DMA controller. Can be assigned to any bank * * \author * Original: Martti Huttunen * Port: Zach Shelby * Further Modifications: * George Oikonomou * */ #include "contiki.h" #include "dev/dma.h" #include "cc253x.h" #if DMA_ON struct dma_config dma_conf[DMA_CHANNEL_COUNT]; /* DMA Descriptors */ struct process * dma_callback[DMA_CHANNEL_COUNT]; /*---------------------------------------------------------------------------*/ void dma_init(void) { uint16_t tmp_ptr; memset(dma_conf, 0, 4 * sizeof(dma_config_t)); for(tmp_ptr = 0; tmp_ptr < DMA_CHANNEL_COUNT; tmp_ptr++) { dma_callback[tmp_ptr] = 0; } /* The address of the descriptor for Channel 0 is configured separately */ tmp_ptr = (uint16_t) &(dma_conf[0]); DMA0CFGH = tmp_ptr >> 8; DMA0CFGL = tmp_ptr; /* * Descriptors for Channels 1-4 must be consecutive in RAM. * We write the address of the 1st one to the register and the rest are * derived by the SoC */ #if (DMA_CHANNEL_COUNT > 1) tmp_ptr = (uint16_t) &(dma_conf[1]); DMA1CFGH = tmp_ptr >> 8; DMA1CFGL = tmp_ptr; #endif IEN1_DMAIE = 1; /* Enable DMA interrupts */ } /*---------------------------------------------------------------------------*/ /* * Associate process p with DMA channel c. When a transfer on that channel * completes, the ISR will poll this process. */ void dma_associate_process(struct process * p, uint8_t c) { if((!c) || (c >= DMA_CHANNEL_COUNT)) { return; } if(p) { dma_conf[c].inc_prio |= 8; /* Enable interrupt generation */ IEN1_DMAIE = 1; /* Make sure DMA interrupts are acknowledged */ } dma_callback[c] = p; } /*---------------------------------------------------------------------------*/ #endif