cc253x: DMA Changes

- Fixed DMA irq flag clearing
- Added a dma_reset helper

See Pull Request #18
This commit is contained in:
Philippe Rétornaz 2012-08-03 16:08:07 +02:00 committed by George Oikonomou
parent 898bd07810
commit eabaa0c8e4
3 changed files with 31 additions and 4 deletions

View file

@ -67,4 +67,29 @@ dma_associate_process(struct process * p, uint8_t c)
dma_callback[c] = p; dma_callback[c] = p;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/*
* Reset a channel to idle state. As per cc253x datasheet section 8.1,
* we must reconfigure the channel to trigger source 0 between each
* reconfiguration.
*/
void
dma_reset(uint8_t c)
{
static __xdata uint8_t dummy;
if(c >= DMA_CHANNEL_COUNT) {
return;
}
DMA_ABORT(c);
dma_conf[c].src_h = (uint16_t) &dummy >> 8;
dma_conf[c].src_l = (uint16_t) &dummy;
dma_conf[c].dst_h = (uint16_t) &dummy >> 8;
dma_conf[c].dst_l = (uint16_t) &dummy;
dma_conf[c].len_h = 0;
dma_conf[c].len_l = 1;
dma_conf[c].wtt = DMA_BLOCK;
dma_conf[c].inc_prio = DMA_PRIO_GUARANTEED;
DMA_TRIGGER(c); // The operation order is important
DMA_ARM(c);
while(DMAARM & (1 << c));
}
#endif #endif

View file

@ -12,6 +12,7 @@
#ifndef __DMA_H #ifndef __DMA_H
#define __DMA_H #define __DMA_H
#include "cc253x.h" #include "cc253x.h"
#include "sfr-bits.h"
/* DMA triggers */ /* DMA triggers */
#define DMA_T_NONE 0 /* None, DMAREQ.DMAREQx bits start transfer */ #define DMA_T_NONE 0 /* None, DMAREQ.DMAREQx bits start transfer */
@ -133,12 +134,13 @@ extern dma_config_t dma_conf[DMA_CHANNEL_COUNT];
*/ */
#define DMA_STATUS(c) (DMAIRQ &(1 << c)) #define DMA_STATUS(c) (DMAIRQ &(1 << c))
/* Abort Ongoing DMA Transfers on Channel C */ /* Abort Ongoing DMA Transfers on Channel C */
#define DMA_ABORT(c) (DMAARM = ABORT | (1 << c)) #define DMA_ABORT(c) (DMAARM = DMAARM_ABORT | (1 << c))
#define DMA_ABORT_ALL() (DMAARM = 0x9F) /* Abort ALL Ongoing DMA Transfers */ #define DMA_ABORT_ALL() (DMAARM = 0x9F) /* Abort ALL Ongoing DMA Transfers */
/* Functions Declarations */ /* Functions Declarations */
void dma_init(void); void dma_init(void);
void dma_associate_process (struct process * p, uint8_t c); void dma_associate_process (struct process * p, uint8_t c);
void dma_reset(uint8_t c);
/* Only link the ISR when DMA_ON is .... on */ /* Only link the ISR when DMA_ON is .... on */
#if DMA_ON #if DMA_ON

View file

@ -47,21 +47,21 @@ dma_isr(void) __interrupt (DMA_VECTOR)
DMAIF = 0; DMAIF = 0;
#ifdef HAVE_RF_DMA #ifdef HAVE_RF_DMA
if((DMAIRQ & 1) != 0) { if((DMAIRQ & 1) != 0) {
DMAIRQ &= ~1; DMAIRQ = ~1;
DMAARM=0x81; DMAARM=0x81;
rf_dma_callback_isr(); rf_dma_callback_isr();
} }
#endif #endif
#ifdef SPI_DMA_RX #ifdef SPI_DMA_RX
if((DMAIRQ & 0x08) != 0) { if((DMAIRQ & 0x08) != 0) {
DMAIRQ &= ~(1 << 3); DMAIRQ = ~(1 << 3);
spi_rx_dma_callback(); spi_rx_dma_callback();
} }
#endif #endif
#if DMA_ON #if DMA_ON
for(i = 0; i < DMA_CHANNEL_COUNT; i++) { for(i = 0; i < DMA_CHANNEL_COUNT; i++) {
if((DMAIRQ & (1 << i)) != 0) { if((DMAIRQ & (1 << i)) != 0) {
DMAIRQ &= ~(1 << i); DMAIRQ = ~(1 << i);
if(dma_callback[i] != 0) { if(dma_callback[i] != 0) {
process_poll(dma_callback[i]); process_poll(dma_callback[i]);
} }