lpcware

Problem with HSADC and GPDMA

Discussion created by lpcware Employee on Jun 15, 2016
Latest reply on Aug 18, 2017 by jungjae kim
Content originally posted in LPCWare by Vandar501 on Wed Jan 20 11:39:23 MST 2016
Hello everyone,

I want to use the HSADC with GPDMA (LPC4370) for transfer constantly a 16 sample burst from FIFO to a Buffer. So far the HSADC collect Samples and put them in the FIFO and the FIFO_FULL Flag appears so the DMA transfer data to the buffer. But after this first transfer the DMA stops and the HSADC continues sampling new data. I thought the Problem was that the FIFO_FULL Flag won't reset so the DMA can't get a new request. So I tried to reset the FIFO_FULL FLAG manually but nothing happens. It actually happens that the FIFO_FULL and FIFO_EMPTY Flag are set at the same time after the first transfer is complete.
I searched the whole Forum for Information about this Topic and I found this:

Laptool VADC
and
hsadc.c

But still I don't figure out the Problem.

This are my Configurations for HSADC and DMA:


//Initialize DMA
NVIC_DisableIRQ(DMA_IRQn);
LPC_GPDMA->CH[0].CONFIG = 0;

//Clear all interrupts on Channel 0
LPC_GPDMA->INTERRCLR  = 0x1;
LPC_GPDMA->INTTCCLEAR = 0x1;

//Setting Muxing for DMA
setDMAMUX();

//Programming the DMA Controller

//Enabling the DMA-Controller
LPC_GPDMA->CONFIG = 0x01;
while ( !(LPC_GPDMA->CONFIG & 0x01) );

//Find an inactive DMA-Channel with the highest priority
uint8_t ch_no = Chip_GPDMA_GetFreeChannel(LPC_GPDMA,0);

//Setting Source and Destination Adress, LLI-Option and Transfer Size
LPC_GPDMA->CH[ch_no].SRCADDR = (uint32_t) &LPC_ADCHS->FIFO_OUTPUT[0];
LPC_GPDMA->CH[ch_no].DESTADDR = (uint32_t) &buffer;
LPC_GPDMA->CH[ch_no].LLI =    0x0;
LPC_GPDMA->CH[ch_no].CONTROL=   (0x8 << 1 )//Transfer size
  | (0x3 << 12)//Source burst size
  | (0x3 << 15)//Destination burst size
  | (0x2 << 18)//Source transfer width
  | (0x2 << 21)//Destination transfer width
  | (0x1 << 24)//Source AHB master select
  | (0x0 << 25)//Destination AHB master select
  | (0x0 << 26)//Source increment
  | (0x1 << 27)//Destination increment
/*note*/  | (0x1 << 31);//Terminal count interrupt enable bit


//Setting Source Peripheral, Setting Transfer-type, Flow Control
LPC_GPDMA->CH[ch_no].CONFIG =  (0x8 << 1 )//Source peripheral
| (0x0 << 6 )//Destination peripheral
| (0x2 << 11)//Flow control and transfer type
| (0x1 << 14)//Interrupt error mask
| (0x1 << 15);//Terminal count interrupt mask

//Enable Interrupt for DMA
NVIC_EnableIRQ(DMA_IRQn);

//Enable Channel
LPC_GPDMA->CH[ch_no].CONFIG |= (0x1 << 0);





//initialize HSADC Clock
hsadc_init();

/* Show the actual HSADC clock rate */
freqHSADC = Chip_HSADC_GetBaseClockRate(LPC_ADCHS);
DEBUGOUT("HSADC sampling rate = %dKHz\r\n\n\n", freqHSADC / 1000);

//disable attenuator on AI_1
SET_PIN(PIN_ATT_AI1_5K,0);
SET_PIN(PIN_ATT_AI1_10K,0);

//Reset all Interrupts
NVIC_DisableIRQ(ADCHS_IRQn);
LPC_ADCHS->INTS[0].CLR_EN = 0x7f; // disable Interrupt0
LPC_ADCHS->INTS[0].CLR_STAT = 0x7f; // clear Interrupt-Status
while(LPC_ADCHS->INTS[0].STATUS & 0x7d); // wait for status to clear, have to exclude FIFO_EMPTY (bit 1)
LPC_ADCHS->INTS[1].CLR_EN = 0x7f;
LPC_ADCHS->INTS[1].CLR_STAT = 0x7f;
while(LPC_ADCHS->INTS[1].STATUS & 0x7d); // wait for status to clear, have to exclude FIFO_EMPTY (bit 1)

// Make sure the HSADC is not powered down
LPC_ADCHS->POWER_DOWN = (0<<0);        /* PD_CTRL:      0=disable power down, 1=enable power down */

// Clear FIFO
LPC_ADCHS->FLUSH = 1;

// FIFO Settings      0= 1 sample packed into 32 bit, 1= 2 samples packed into 32 bit */
LPC_ADCHS->FIFO_CFG =
(0x0<<0) |        /* UNPACKED */
(0x8<<1);  /* FIFO_LEVEL */

LPC_ADCHS->DSCR_STS =
      (0<<0) |       /* ACT_TABLE:        0=table 0 is active, 1=table 1 is active */
      (0<<1);        /* ACT_DESCRIPTOR:   ID of the descriptor that is active */

// Select both positive and negative DC biasing for input 2
Chip_HSADC_SetACDCBias(LPC_ADCHS, 2, HSADC_CHANNEL_DCBIAS, HSADC_CHANNEL_NODCBIAS);

LPC_ADCHS->THR[0] = 0x000 << 0 | 0xFFF << 16;//Default
LPC_ADCHS->THR[1] = 0x000 << 0 | 0xFFF << 16;//Default


LPC_ADCHS->CONFIG =  /* configuration register */
    (1<<0) |      /* TRIGGER_MASK:     0=triggers off, 1=SW trigger, 2=EXT trigger, 3=both triggers */
    (0<<2) |        /* TRIGGER_MODE:     0=rising, 1=falling, 2=low, 3=high external trigger */
    (0<<4) |        /* TRIGGER_SYNC:     0=no sync, 1=sync external trigger input */
    (0<<5) |        /* CHANNEL_ID_EN:    0=don't add, 1=add channel id to FIFO output data */
    (0x90<<6);      /* RECOVERY_TIME:    ADC recovery time from power down, default is 0x90 */

/* Setup data format for 2's complement and update clock settings. This function
   should be called whenever a clock change is made to the HSADC */
Chip_HSADC_SetPowerSpeed(LPC_ADCHS, false);

LPC_ADCHS->DESCRIPTOR[0][0] =
      (2<<0) |       /* CHANNEL_NR:    0=convert input 0, 1=convert input 1, ..., 5=convert input 5 */
      (0<<3) |       /* HALT:          0=continue with next descriptor after this one, 1=halt after this and restart at a new trigger */
      (0<4) |        /* INTERRUPT:     1=raise interrupt when ADC result is available */
      (0<<5) |       /* POWER_DOWN:    1=power down after this conversion */
      (1<<6) |       /* BRANCH:        0=continue with next descriptor (wraps around after top) */
                     /*                1=branch to the first descriptor in this table */
                     /*                2=swap tables and branch to the first descriptor of the new table */
                     /*                3=reserved (do not store sample). continue with next descriptor (wraps around the top) */
      (0x95<<8)  |   /* MATCH_VALUE:   Evaluate this descriptor when descriptor timer value is equal to match value */
      (0<<22) |   /* THRESHOLD_SEL: 0=no comparison, 1=THR_A, 2=THR_B */
      (1<<24) |      /* RESET_TIME:    1=reset descriptor timer */
      (0<<31);     /* UPDATE_TABLE:  1=update table with all 8 descriptors of this table */



//Enable HSADC power
Chip_HSADC_EnablePower(LPC_ADCHS);

// Enable interrupts
NVIC_EnableIRQ(ADCHS_IRQn);

Chip_HSADC_UpdateDescTable(LPC_ADCHS, 0);

//clear interrupt stats
Chip_HSADC_ClearIntStatus(LPC_ADCHS, 0, Chip_HSADC_GetEnabledInts(LPC_ADCHS, 0));

Chip_HSADC_EnableInts(LPC_ADCHS, 0 ,(HSADC_INT0_DSCR_DONE | HSADC_INT0_FIFO_FULL));

//start HSADC
Chip_HSADC_SWTrigger(LPC_ADCHS);


I hope someone can help.

Regards

Outcomes