LPC82x ADC+DMA

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

LPC82x ADC+DMA

3,692 Views
tiagofernandes
Contributor III

Hello,

 

I'm trying to use the ADC+DMA to read 8 adc channels (not sequential (channel 2,3,4,5,6,7,8 and 9)) and save your values to the DMA to reduce the number of interruptions. For this I search in NXP community and on the internet and I found some people that uses this approach. I tried to testing this approachs, for be capable of read one adc and write in the dma (this is the first test that I'm trying to implement the ADC+DMA) but I have a problem, when I read the value saved in the DMA the value is always 0, even with different voltagens in the channel input. Then let my code, does anyone know tell me what am I doing wrong?

 

Best Regards,

Tiago

 

void DMA_IRQHandler(void)

{

  // Clear DMA interrupt for the channel

  Chip_DMA_ClearActiveIntAChannel(LPC_DMA, DMA_CH0);

}

 

init_adc+dma()

{

 

//disable pull up and pull down

Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_IOCON);

Chip_IOCON_PinSetMode(LPC_IOCON, IOCON_PIO6, PIN_MODE_INACTIVE);

Chip_IOCON_PinSetMode(LPC_IOCON, IOCON_PIO14, PIN_MODE_INACTIVE);

Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_IOCON);

 

  //init adc

  Chip_ADC_Init(LPC_ADC, 0);

  Chip_ADC_StartCalibration(LPC_ADC);

  while (!(Chip_ADC_IsCalibrationDone(LPC_ADC))) {

  }

  Chip_ADC_SetClockRate(LPC_ADC, ADC_MAX_SAMPLE_RATE);

  Chip_ADC_SetDivider(LPC_ADC,0);

 

  Chip_ADC_SetupSequencer(LPC_ADC, ADC_SEQA_IDX,

  (ADC_SEQ_CTRL_CHANSEL(1) //| ADC_SEQ_CTRL_CHANSEL(2)

  //| ADC_SEQ_CTRL_CHANSEL(3) | ADC_SEQ_CTRL_CHANSEL(4)

  |ADC_SEQ_CTRL_BURST

  | ADC_SEQ_CTRL_MODE_EOS));

 

  Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_SWM);

  Chip_SWM_DisableFixedPin(SWM_FIXED_VDDCMP);

  Chip_SWM_DisableFixedPin(SWM_FIXED_ACMP_I3);

  Chip_SWM_DisableFixedPin(SWM_FIXED_ACMP_I4);

  /* Configure the SWM for P0-6 as the input for the ADC1 */

  Chip_SWM_EnableFixedPin(SWM_FIXED_ADC1);

  //Chip_SWM_EnableFixedPin(SWM_FIXED_ADC2);

  /* Disable the clock to the Switch Matrix to save power */

  Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_SWM);

 

  /* Clear all pending interrupts */

  Chip_ADC_ClearFlags(LPC_ADC, Chip_ADC_GetFlags(LPC_ADC));

 

  Chip_ADC_EnableInt(LPC_ADC, (ADC_INTEN_SEQA_ENABLE

  //| ADC_INTEN_OVRRUN_ENABLE

  ));

 

  //NVIC_EnableIRQ(ADC_SEQA_IRQn);

  /* Enable sequencer */

  Chip_ADC_EnableSequencer(LPC_ADC, ADC_SEQA_IDX);

 

  // Setup DMA for ADC

  /* DMA initialization - enable DMA clocking and reset DMA if needed */

  Chip_DMA_Init(LPC_DMA);

  /* Enable DMA controller and use driver provided DMA table for current descriptors */

  Chip_DMA_Enable(LPC_DMA);

  Chip_DMA_SetSRAMBase(LPC_DMA, DMA_ADDR(Chip_DMA_Table));

 

  Chip_DMA_EnableChannel(LPC_DMA, DMA_CH0);

  Chip_DMA_EnableIntChannel(LPC_DMA, DMA_CH0);

 

  Chip_DMA_SetupChannelConfig(LPC_DMA, DMA_CH0,

  (DMA_CFG_HWTRIGEN

  | DMA_CFG_TRIGTYPE_EDGE | DMA_CFG_TRIGPOL_HIGH

  | DMA_CFG_TRIGBURST_BURST | DMA_CFG_BURSTPOWER_1

  //| SRCBURSTWRAP

  | DMA_CFG_CHPRIORITY(0)));

 

  // Attempt to use ADC SEQA to trigger DMA xfer

  Chip_DMATRIGMUX_SetInputTrig(LPC_DMATRIGMUX, DMA_CH0, DMATRIG_ADC_SEQA_IRQ);

 

  /* DMA descriptor for peripheral to memory operation - note that addresses must

  be the END address for src and destination, not the starting address.

  DMA operations moves from end to start. */

  dmaDescA.source = DMA_ADDR(&(LPC_ADC->DR[adc_channel])); //adc_channel=1

  dmaDescA.dest = DMA_ADDR(&adc_buffer[SIZE_BUFFER_1 - 1]);     //SIZE_BUFFER_1=1;  uint16_t adc_buffer//

  dmaDescA.next = DMA_ADDR(0);

 

  // Enable DMA interrupt. Will be invoked at end of DMA transfer.

  NVIC_EnableIRQ(DMA_IRQn);

 

  /* Setup transfer descriptor and validate it */

  Chip_DMA_SetupTranChannel(LPC_DMA, DMA_CH0, &dmaDescA);

  Chip_DMA_SetValidChannel(LPC_DMA, DMA_CH0);

 

  // Setup data transfer and hardware trigger

  Chip_DMA_SetupChannelTransfer(LPC_DMA, DMA_CH0, (

  DMA_XFERCFG_CFGVALID

  | DMA_XFERCFG_RELOAD

  | DMA_XFERCFG_SETINTA

  //| DMA_XFERCFG_SWTRIG

  | DMA_XFERCFG_WIDTH_16

  | DMA_XFERCFG_SRCINC_0 // do not increment source - I want read from the adc and save always in the same memory position

  | DMA_XFERCFG_DSTINC_0 // do not increment dst

  | DMA_XFERCFG_XFERCOUNT(SIZE_BUFFER_1)));

 

  Chip_ADC_ClearFlags(LPC_ADC, Chip_ADC_GetFlags(LPC_ADC));

}

 

main()

{

 

     //print the data from the DMA

     //put only the 12bits of the adc

     for (i = 0; i < SIZE_BUFFER_1; i++) {    

            adc_buffer[i] >>= 4;

       }

     //send data

       for (i = 0; i < SIZE_BUFFER_1; i++) {

          print_data(adc_buffer[i] );  //send to UART the data from the DMA  

       }

 

}

Labels (1)
0 Kudos
17 Replies

2,526 Views
tiagofernandes
Contributor III

Hello,

I'm able to read ADC to DMA, however only can do this one time. I disable the DMA interrupt, because like I want always read the values from the adc, the microcontroller will be always in the interrupt, so I disable. However I just can read from the ADC one time, it looks the microcontroler, after one time disable the DMA channel, however I look in the code and I saw that I'm not disable (I'm not doing this command in anywhere Chip_DMA_ClearActiveIntAChannel(LPC_DMA, DMA_CH0);). I also verify if the trigger of the ADC to the DMA it's working and in really is correct, always after a full sequence adc occurs an trigger from the adc. What I'm possible doing wrong?

Other test that I do was in a while(1)/ for(); the DMA example of Memory to memory, which work if I at each iteration of a while() or for() made 

Chip_DMA_SetupChannelTransfer(LPC_DMA, DMA_CH0,

  (DMA_XFERCFG_CFGVALID | DMA_XFERCFG_RELOAD

  | DMA_XFERCFG_SETINTA //| DMA_XFERCFG_SWTRIG - this is enable posteriorly

  | DMA_XFERCFG_WIDTH_32 | DMA_XFERCFG_SRCINC_1

  | DMA_XFERCFG_DSTINC_1

  | DMA_XFERCFG_XFERCOUNT(SIZE_BUFFERS)));

There are any way to haven't to constantly set up the DMA configs, ie there is some form of DMA store the configuration values​​? I ask this because I was doing some tests and found that at the end of a DMA conversion, teh configuration values ​​were all different from the initial setup.

Best Regards,

Tiago

0 Kudos

2,526 Views
kurtmirdell
Contributor II

I don't understand in which order the different values are put in adc_buffer. Are the correct values the first or the last?

There is no buffering in the ADC, so if you are only doing one ADC sequence I can't see where the 8 values should come from.

I  suggest debug outputs to an oscilloscope to see when different things happens. Another way if you don't have any scope is to read a timer to get the time when things happens.

Best regards

Kurt Mirdell

0 Kudos

2,526 Views
tiagofernandes
Contributor III

Hello Kurt,

The values in the adc_buffer depends of the address that I give in this line

dmaDesc(A/B/C).dest = DMA_ADDR(&adc_buffer[(1/2/3) - 1]);

The values cant be in both ways.

Like you said with with only one ADC sequence I should have only 1 value come from, however I think that the 8 values cames from the following line:

DMA_XFERCFG_XFERCOUNT(DMA_BUFFER_SIZE));

However if I use a value of DMA_BUFFER_SIZE < 8 the program not work.

Best Regards,

Tiago

0 Kudos

2,526 Views
tiagofernandes
Contributor III

Hello Kurt,

I tried read all ADC sequence with one DMA "box", however if I have more than 3 channels not work. Did you know what causing this problem?

Other question, did you know how can I read from the ADC to DMA in a while(1)? For just one set of read is working to more not work.

Best regards,

Tiago

0 Kudos

2,526 Views
kurtmirdell
Contributor II

If you are running the ADC in single sequence mode, it will just run one sequence after triggering. The results you are seeing looks like that.

The zeroes you are seeing are probably from start-up initiation. Put something else there before starting to verify that.

What I think you need to do is to restart the ADC. You can't do it with ADC interrupt. The ADC can either do DMA or interrupt, not both. One possible way would be to let one DMA channel do one-word transfers, and let that channel restart the ADC either through interrupt or by hardware triggering of another DMA-channel. The easy way would be to run the ADC in burst mode, and stop it when DMA transfers are ready.


From my understanding, when the ADC is doing one sequence, it is making one conversion on all selected channels, but not simultaneously, they are done one after the other with results stored in channel registers. When transfer result with DMA,, you can either have the mode bit in the ADC sequence register set to 0, and then you get one DMA request for each conversion, or if the mode bit is 1, you get one DMA request at the end of the sequence. If you are running the ADC in burst mode, it will repeat the sequence until interrupted.

I would imagine that with mode bit set to 1, you could use this single request to trigger multiple DMA transfers, each from one ADC result register. Then this will happen simultaneously (the DMA channels will arbitrate the bus and do the transfer in priority order) I have not tested this approach.

With the mode bit set to 0, you will get DMA requests when each conversion is ready. You should then use the global data register and one DMA channel. I have used this method and it seems to work.

Best regards

Kurt

0 Kudos

2,526 Views
tiagofernandes
Contributor III

Hello,

The order of the zeros (with destination not increment, and with 3 DMA "Box") are

adc_buffer[i]:  0

adc_buffer[i]:  0

adc_buffer[i]:  0

adc_buffer[i]:  0

adc_buffer[i]:  0

adc_buffer[i]:  0

adc_buffer[i]:  0

adc_buffer[i]:  value ch1

adc_buffer[i]:  0                                                                      

adc_buffer[i]:  0                                                   

adc_buffer[i]:  0                                                                 

adc_buffer[i]:  0                                                                   

adc_buffer[i]:  0                                                                     

adc_buffer[i]:  0                                                                     

adc_buffer[i]:  0                                                                       

adc_buffer[i]:  value ch2                                                                 

adc_buffer[i]:  0                                                                     

adc_buffer[i]:  0                                                                

adc_buffer[i]:  0                                                                 

adc_buffer[i]:  0                                                                     

adc_buffer[i]:  0                                                                 

adc_buffer[i]:  0                                                                    

adc_buffer[i]:  0                                                                   

adc_buffer[i]:  value ch3

 

If I increment the destination source (in the DMA) I have 8 equal values to the ch1,more 8 same values to ch2 and 8 values to the ch3. I say, this to try to explain you than I think that I don't need to restart the ADC, because I have values from the beginning. I tried what you said, to read all values of the channels to one DMA "box" and the values are save without a specific order (the order of the adc to read is ch1, ch2, ch3... and the order in the DMA are almost randomly).

I will try the option of using the mode bit set 0, and then I will report my results.

Best Regards,

Tiago

0 Kudos

2,526 Views
tiagofernandes
Contributor III

Hello Kurt,

So you tell me that I need to ativate the ADC interrupt, with previous configuration with multiple ADC channels, and ativate the sequence in the DMA interruption or have in the DMA the destination mode selected to increment, and the burst mode ative?

Before doing this example code I tried to read multiple channels just to one DMA "box", and only the first ADC channel as his value saved in the DMA memory, that why I separate the DMA "box".

Best Regards,

Tiago

0 Kudos

2,526 Views
kurtmirdell
Contributor II

You don't need to select all channels in a sequence, you can skip some. They will be done in order.

About speed, the ADC will just sample one channel at a time. It will not sampler faster because you are reading the separate data registers.

I think the basic problem is that the ADC sequence is just running once. To avoid restarting the ADC, you will have to run the ADC in burst mode.

Best regards

Kurt

0 Kudos

2,526 Views
kurtmirdell
Contributor II

Dear Tiago,

I think you should use the ADC Global data register instead. Then one DMA channel can read all converted channels from the same address.

If you do 32-bit transfers from the ADC, you will also in the high 16 bits get information about channel number, if conversion was valid and if there was an overrun. That can give you some insight what is happening.

You can do one sequence with 3 conversions, a one-channel DMA transfer for 3 words and restart the sequence 8 times.

Or you can run the ADC in burst mode. The problem with burst mode is that hardware triggering is not possible, and that you have to stop burst mode when you are ready.

To get exact timing, I have "solved" this problem by letting the SCT trigger the DMA to do a one-word transfer to the ADC control register to start the ADC sequence. It would have been better if the ADC was hardware triggerable in burst mode.

Hope that helps.

Best regards

Kurt Mirdell

0 Kudos

2,526 Views
tiagofernandes
Contributor III

Hello Kurt,

Thanks for answering.  I do like this because in the future I will not have all channels in sequence (ch1, ch2 ch3....) but with jumps (ch1, ch2, ch4, ch6, ch7....). Relatively to use the ADC Global data register, I will have problems with the speed that I need to sample. You said that I transfer 3 words and restart sequence 8 times. How can I reduce this value from 8 times just to one? I think that in the code is the following configuration.

Chip_DMA_SetupChannelTransfer(LPC_DMA, DMA_CH0, (

  DMA_XFERCFG_CFGVALID  // Channel descriptor is considered valid

  | DMA_XFERCFG_RELOAD  // Causes DMA to move to next descriptor when complete

  | DMA_XFERCFG_SETINTA // DMA Interrupt A (A vs B can be read in ISR)

  | DMA_XFERCFG_WIDTH_16 // 8,16,32 bits allowed

  | DMA_XFERCFG_SRCINC_0 // do not increment source

  | DMA_XFERCFG_DSTINC_0 // increment dst by widthx1

  | DMA_XFERCFG_XFERCOUNT(DMA_BUFFER_SIZE)));      <<<--------------------this line

And if is this line, I have problem with values <8.

Best regards,

Tiago

0 Kudos

2,526 Views
kurtmirdell
Contributor II

I am just now working on software that is using DMA transfer from ADC. I have it working, but when checking, I start to wondering why.

It looks like you need to set DMA_XFERCFG_SWTRIG.

However. if you read the documentation in UM10800, you get the feeling that you should not set this bit.

From page 181:

If a channel is configured with the SWTRIG bit equal to 0, the channel can be later

triggered either by hardware or software. Software triggering is accomplished by writing a

1 to the appropriate bit in the SETTRIG register. Hardware triggering requires setup of the

HWTRIGEN, TRIGPOL, TRIGTYPE, and TRIGBURST fields in the CFG register for the

related channel. When a channel is initially set up, the SWTRIG bit in the XFERCFG

register can be set, causing the transfer to begin immediately.

Once triggered, transfer on a channel will be paced by DMA requests if the

PERIPHREQEN bit in the related CFG register is set. Otherwise, the transfer will proceed

at full speed.

I have tested with the ADC set up for a sequence with 2 channels and DMA for 32 bit data transfer from SEQA_GDAT. Nothing happens if you don't set SWTRIG. The XFERCOUNT field in the XFERCFG register for the channel is not counting down. With only difference that SWTRIG is set, the DMA transfers data that looks correct with alternating channels number for each word, XFERCOUNT field is counting down to 0x3ff.

To me it looks like SWTRIG will activate the DMA channel, but not actually do any transfer. When there are hardware triggers from the ADC, the DMA transfer is made. Has it anything to do with edge triggering?

I would appreciate a comment from anybody at NXP about this.

My suggestion is that you remove the comment in your code segment

// Setup data transfer and hardware trigger

  Chip_DMA_SetupChannelTransfer(LPC_DMA, DMA_CH0, (

  DMA_XFERCFG_CFGVALID

  | DMA_XFERCFG_RELOAD

  | DMA_XFERCFG_SETINTA

  //| DMA_XFERCFG_SWTRIG  <- remove the comment

  | DMA_XFERCFG_WIDTH_16

  | DMA_XFERCFG_SRCINC_0 // do not increment source - I want read from the adc and save always in the same memory position

  | DMA_XFERCFG_DSTINC_0 // do not increment dst

  | DMA_XFERCFG_XFERCOUNT(SIZE_BUFFER_1)));

Best regards

Kurt Mirdell

0 Kudos

2,526 Views
tiagofernandes
Contributor III

Hello Kurt,

Thanks for the answer. Sorry for my late, but in the last days I can't comming to the forum. I tried like you said, to uncomment the DMA_XFERCFG_SWTRIG  and the result as the same, value is always 0. You also say that have tried to data with 32bits, you can show your example?

Best regards,

Tiago

0 Kudos

2,526 Views
tiagofernandes
Contributor III

Hello,

I build a new code based an example that I found in the web, and with the information of the problems presented here, and now I'm able to read from multiple ADC, however, and it's possible to see in the following code, I read from 3 channels and the output is something like:

-value ch1 (correct value)

-value ch2 (correct value)

-value ch3 (correct value)

- 0 ......

-0 (until have 24 readings)

How can I remove the zeros who are more?

In the following code (the code that present the previous output) if I have a DMA_BUFFER_SIZE value <8 the program not work, because it just have one interrupt of the DMA, if the value is >=8 works fine (for that I see from the examples provided from the nxo and the user manuel this value need to be multiple of other value). What I'm doing wrong and what I need to configure to have only a measure from each ADC ch, and not 8 or more measures. The ADC code is the same as presented in previous posts.

Best Regards,

Tiago

// Setup DMA for ADC

  /* DMA initialization - enable DMA clocking and reset DMA if needed */

  Chip_DMA_Init(LPC_DMA);

  /* Enable DMA controller and use driver provided DMA table for current descriptors */

  Chip_DMA_Enable(LPC_DMA);

  Chip_DMA_SetSRAMBase(LPC_DMA, DMA_ADDR(Chip_DMA_Table));

  /* Setup channel 0 for the following configuration:

  - High channel priority

  - Interrupt A fires on descriptor completion */

  Chip_DMA_EnableChannel(LPC_DMA, DMA_CH0);

  Chip_DMA_EnableIntChannel(LPC_DMA, DMA_CH0);

  Chip_DMA_SetupChannelConfig(LPC_DMA, DMA_CH0,

  (DMA_CFG_HWTRIGEN

  | DMA_CFG_TRIGTYPE_EDGE

  | DMA_CFG_TRIGPOL_HIGH

  | DMA_CFG_TRIGBURST_BURST

  | DMA_CFG_BURSTPOWER_1

  | DMA_CFG_CHPRIORITY(0)

  ));

  // Attempt to use ADC SEQA to trigger DMA xfer

  Chip_DMATRIGMUX_SetInputTrig(LPC_DMATRIGMUX, DMA_CH0, DMATRIG_ADC_SEQA_IRQ);

  dmaDescC.xfercfg = (

  DMA_XFERCFG_CFGVALID  // Channel descriptor is considered valid

  | DMA_XFERCFG_SETINTA // DMA Interrupt A (A vs B can be read in ISR)

  | DMA_XFERCFG_WIDTH_16 // 8,16,32 bits allowed

  | DMA_XFERCFG_SRCINC_0 // do not increment source

  | DMA_XFERCFG_DSTINC_0 // do not increment dst by widthx1

  | DMA_XFERCFG_XFERCOUNT(DMA_BUFFER_SIZE));

  dmaDescC.source = DMA_ADDR((&LPC_ADC->DR[ADC_CHANNEL+2]));

  dmaDescC.dest = DMA_ADDR(&adc_buffer[3 - 1]);     //the adc_buffer is an array of uint16_t adc_buffer[DMA_BUFFER_SIZE * num_buff] where num_buff = 3;

  dmaDescC.next = DMA_ADDR(0); // no more descriptors

  dmaDescB.xfercfg = (

  DMA_XFERCFG_CFGVALID  // Channel descriptor is considered valid

  | DMA_XFERCFG_RELOAD  // Causes DMA to move to next descriptor when complete

  | DMA_XFERCFG_SETINTA // DMA Interrupt A (A vs B can be read in ISR)

  | DMA_XFERCFG_WIDTH_16 // 8,16,32 bits allowed

  | DMA_XFERCFG_SRCINC_0 // do not increment source

  | DMA_XFERCFG_DSTINC_0 // increment dst by widthx1

  | DMA_XFERCFG_XFERCOUNT(DMA_BUFFER_SIZE));

  dmaDescB.source = DMA_ADDR((&LPC_ADC->DR[ADC_CHANNEL+1]));

  dmaDescB.dest = DMA_ADDR(&adc_buffer[2 - 1]);     //the adc_buffer is an array of uint16_t adc_buffer[DMA_BUFFER_SIZE * num_buff] where num_buff = 3;

  dmaDescB.next = (uint32_t) & dmaDescC;

  // ADC data register is source of DMA

  dmaDescA.source = DMA_ADDR((&LPC_ADC->DR[ADC_CHANNEL]));

  dmaDescA.dest = DMA_ADDR(&adc_buffer[1- 1]);     //the adc_buffer is an array of uint16_t adc_buffer[DMA_BUFFER_SIZE * num_buff] where num_buff = 3;

  dmaDescA.next = (uint32_t) & dmaDescB;

  // Enable DMA interrupt. Will be invoked at end of DMA transfer.

  NVIC_EnableIRQ(DMA_IRQn);

  /* Setup transfer descriptor and validate it */

  Chip_DMA_SetupTranChannel(LPC_DMA, DMA_CH0, &dmaDescA);

  Chip_DMA_SetValidChannel(LPC_DMA, DMA_CH0);

  // Setup data transfer and hardware trigger

  Chip_DMA_SetupChannelTransfer(LPC_DMA, DMA_CH0, (

  DMA_XFERCFG_CFGVALID  // Channel descriptor is considered valid

  | DMA_XFERCFG_RELOAD  // Causes DMA to move to next descriptor when complete

  | DMA_XFERCFG_SETINTA // DMA Interrupt A (A vs B can be read in ISR)

  | DMA_XFERCFG_WIDTH_16 // 8,16,32 bits allowed

  | DMA_XFERCFG_SRCINC_0 // do not increment source

  | DMA_XFERCFG_DSTINC_0 // increment dst by widthx1

  | DMA_XFERCFG_XFERCOUNT(DMA_BUFFER_SIZE)));

     Config_SCT();

  dmaBlockCount = 0;     //this variable is incremmented in the DMA interrupt each time that occur  one

  while (dmaBlockCount < num_buff) {          //this is where the program fails (when DMA_BUFFER_SIZE<8) because only occur one DMA  interrupt

  __WFI();

  }

  Chip_SCT_DeInit(LPC_SCT);

  Chip_ADC_DeInit(LPC_ADC);

  NVIC_DisableIRQ(DMA_IRQn);

  // 12 bit ADC data in range 0 - 4095

  for (i = 0; i < DMA_BUFFER_SIZE * num_buff; i++) {          //num_buff = 3 = number of ADC channels

  adc_buffer[i] >>= 4;

  }

  // Output ADC values to UART.

  for (i = 0; i < DMA_BUFFER_SIZE * num_buff; i++) {

          print(adc_buffer[i]);

0 Kudos

2,526 Views
kurtmirdell
Contributor II

I don't see where you trigger the ADC.

0 Kudos

2,526 Views
tiagofernandes
Contributor III

Hello,

Thanks for answer to my question. Do you mean where I use this command "Chip_ADC_StartSequencer(LPC_ADC, ADC_SEQA_IDX);"? If you are referring to this command is in the SysTick_Handler() that active, if not can you tell me what you mean by trigger the ADC?

Best Regards,

Tiago

0 Kudos

2,526 Views
kurtmirdell
Contributor II

It was to start the sequence. If you are doing that in SysTick, then it is OK. Is it done once?

I suggest that you check if the problem is that the ADC has not made any conversion or if the problem is that the DMA doesn't do the transfer.

Best regards

0 Kudos

2,526 Views
tiagofernandes
Contributor III

Hello Kurt,

Like you said I use the start sequence in the SysTick that have a period of 10ms.

If I made a example only with the ADC (I need to enable the NVIC for the adc), the value read is correct (correspond to the value in the input), when I tried with ADC+DMA the value is always 0 (for this test, ADC+DMA, I disable the NVIC for the ADC, like you can see in the previous code). Based in this results I think the problem is in the DMA, but I don't know how I can resolve this.

Best Regards,

Tiago

0 Kudos