Problem with HSADC and GPDMA

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

Problem with HSADC and GPDMA

1,554件の閲覧回数
lpcware
NXP Employee
NXP Employee
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
ラベル(1)
2 返答(返信)

1,078件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Vandar501 on Wed Jan 27 01:50:53 MST 2016
OK Problem solve,

I have to use Linked List's. The Problem was 0x0 under LLI. So I used the LLI type in the gpdma_18xx_43xx.h and created a single Linked List. After that I wrote the adresse of this LLI in the CH[ch_no].LLI Register. Now the DMA-Transfer never stops.

0 件の賞賛
返信

1,078件の閲覧回数
jungjaekim
Contributor I

Thanks to your post. I tried to operating HSADC and DMA using LPC-link2 but i've not worked them. So, can you post how to fix the LLI and a total code?

In addition, What is the setDMAMUX(); ?

please give me some info.

0 件の賞賛
返信