DMA Y ADC

620 views
Skip to first unread message

alemmat

unread,
Apr 23, 2012, 7:53:49 PM4/23/12
to Embebidos32
Hola a todos, como les va?
Ultimamente estuve
aprendiendo a usar el adc y el dma del lpc1769.Estoy teniendo un par
de dificultades en poner a funcionar al dma del micro, el primer
problema es que no estoy logrando generar una interrupcion, pero el
registro del dma DMA RAW INTERRUPT TERMINAL COUNT STATUS REGISTER
(este registro hace referencia a un canal que termino una
transferencia y esta solicitando una interrupcion).Por lo cual la
conclusion que estoy sacando es que el canal dma que estoy usando
trata de generar la interrupicion pero esta faltando algo para que
esta se haga efectiva.Estoy leyendo el manual del lpc1769 y no
encuentro nada.

Les dejo el las funciones de inicializacion de adc y del dma.
Estoy mas que agradecido si alguien me da un mano.

void ADCInit( uint32_t ADC_Clk )
{


LPC_PINCON->PINSEL1 = 0x00054000; //solo activo el canal 0 del adc
en el puerto 0

LPC_PINCON->PINMODE1 = 0x00054000;//desactivo el pull-up y el pull-
down del pin 23 del puerto 0 que lo comparte con el adc

LPC_SC->PCONP |= (1 << 12);//energizo el adc

LPC_SC->PCLKSEL0 |= 1<<25; //divido el cpu clock por 2,en este caso
es de 100mhz y al adc le llega 50mhz

LPC_ADC->ADCR = 0x32ff; // con el byte mas baja activo los canales
del adc (en este caso el 0,1 y 2)
// y con el byte mas alto divido el clock
que le llega al adc 50+1 veces
// o sea que el adc_clock es 50mhz/
51=980khz y si tengo en cuenta que el adc
// tarda 65 adc_clock en realizar una
convercion el tiempo estimado seria 63 65
// micro segundos entre converciones

LPC_ADC->ADCR |= 1<<21; //energizo al adc

/* If POLLING, no need to do the following */
LPC_ADC->ADINTEN = 0x1FF; /* Enable all interrupts */

//NVIC_EnableIRQ(ADC_IRQn);

LPC_ADC->ADCR |= 1<<16;
}




void DMA_INIT(void)
{

LPC_SC->PCONP |= 1<<29;

LPC_GPDMACH0->DMACCConfig = 0;

LPC_GPDMA->DMACConfig |= 1 << 0; // enable DMA



LPC_GPDMA->DMACSync |= 1 << 0;

LPC_GPDMA->DMACIntErrClr |= 0xff;
LPC_GPDMA->DMACIntTCClear |= 0xff;

LPC_GPDMACH0->DMACCDestAddr = 0x2007c000;
LPC_GPDMACH0->DMACCSrcAddr = (uint32_t) &(LPC_ADC->ADDR0);
LPC_GPDMACH0->DMACCLLI = 0;

LPC_GPDMACH0->DMACCControl = 200 | ( 1 << 27 )
| ( 1 << 12 ) | ( 1 << 19 )
| ( 1 << 15 ) | ( 1 << 31 );

LPC_GPDMACH0->DMACCConfig |= ( 1 << 3 ) | ( 1 << 12 );

LPC_GPDMACH0->DMACCConfig &= ~( 1 << 15 );

LPC_GPDMACH0->DMACCConfig |= 1; //enable ch0

NVIC_EnableIRQ(DMA_IRQn);
}

jorge tammela

unread,
Apr 23, 2012, 8:15:53 PM4/23/12
to Embebidos32
Me olvide de agregar algo que la tranferencia se hace,pero solo transfiere el primer canal del adc y al canal de dma lo setee para que que brust siza fuera de 4 word.

MartinchoII

unread,
May 7, 2012, 7:38:35 PM5/7/12
to embeb...@googlegroups.com


Estimado, realmente todavía no se usar las interrupciones, estoy haciendo por consulta las lecturas.
No sé si lo resolviste. Yo tengo otro problema, estoy usando el ADC y el DAC, el DA pone los datos y los vuelve a convertir el AD.
El problema es que no funcionan juntos, use los ejemplos de LPC, pero ambos usan el PIO1_2. Así que ahí hay una incompatibilidad.
No se mucho de esto, recién empiezo, y menos de la función PINSEL nose como se usan las mascaras. Probé con la que utilizaste en el ejemplo, supuse que iba a andar.
Uso el AD0 y el p0.26 para el DAC.
Agradezco cualquier ayuda.

Martin.





Message has been deleted

jorge tammela

unread,
May 8, 2012, 9:06:26 AM5/8/12
to embeb...@googlegroups.com
pasame el codigo y lo pruebo

El 7 de mayo de 2012 20:39, MartinchoII <mdel...@gmail.com> escribió:


Estimado, realmente todavía no se usar las interrupciones, estoy haciendo por consulta las lecturas.
No sé si lo resolviste. Yo tengo otro problema, estoy usando el ADC y el DAC, el DA pone los datos y los vuelve a convertir el AD.
El problema es que no funcionan juntos, use los ejemplos de LPC, pero ambos usan el PIO1_2. Así que ahí hay una incompatibilidad.
No se mucho de esto, recién empiezo, y menos de la función PINSEL nose como se usan las mascaras. Probé con la que utilizaste en el ejemplo, supuse que iba a andar.
Uso el AD0 y el p0.26 para el DAC.
Agradezco cualquier ayuda.

Martin


-- Recibiste este mensaje porque estás suscripto al Grupo Google Embebidos32. Para postear en este grupo, escribe un email a embeb...@googlegroups.com. Para des-suscribirte, envía un email a embebidos32...@googlegroups.com. Para más opciones, visita el sitio del grupo en https://groups.google.com/d/forum/embebidos32?hl=es

MartinchoII

unread,
May 8, 2012, 10:27:12 AM5/8/12
to embeb...@googlegroups.com
 Estimado Jorge,

Gracias por la rapida respuesta,los codigos estan todos sacados de ejemplos.

Para inicializar el ADC uso esto:

void ADCInit( uint32_t ADC_Clk )
{
  uint32_t i, pclkdiv, pclk;

  /* Enable CLOCK into ADC controller */

  LPC_SC->PCONP |= (1 << 12);

 //  ESTO ESTABA EN EL EJEMPLO ORIGINAL

/*
// all the related pins are set to ADC inputs, AD0.0~7
  LPC_PINCON->PINSEL0 &= ~0x000000F0;    //P0.2~3, A0.6~7, function 10
  LPC_PINCON->PINSEL0 |= 0x000000A0;
  LPC_PINCON->PINSEL1 &= ~0x003FC000;    // P0.23~26, A0.0~3, function 01
  LPC_PINCON->PINSEL1 |= 0x00154000;
  LPC_PINCON->PINSEL3 |= 0xF0000000;    // P1.30~31, A0.4~5, function 11

// No pull-up no pull-down (function 10) on these ADC pins.
  LPC_PINCON->PINMODE0 &= ~0x000000F0;
  LPC_PINCON->PINMODE0 |= 0x000000A0;
  LPC_PINCON->PINMODE1 &= ~0x003FC000;
  LPC_PINCON->PINMODE1 |= 0x002A8000;
  LPC_PINCON->PINMODE3 &= ~0xF0000000;
  LPC_PINCON->PINMODE3 |= 0xA0000000;
 */


// Esta es la inicializacion de pinsel que saque de tu codigo, el resto lo deje igual que antes

  LPC_PINCON->PINSEL1 = 0x00054000;     
  LPC_PINCON->PINMODE1 = 0x00054000;

//

  /* By default, the PCLKSELx value is zero, thus, the PCLK for
  all the peripherals is 1/4 of the SystemFrequency. */
  /* Bit 24~25 is for ADC */
  pclkdiv = (LPC_SC->PCLKSEL0 >> 24) & 0x03;
  switch ( pclkdiv )
  {
    case 0x00:
    default:
      pclk = SystemFrequency/4;
    break;
    case 0x01:
      pclk = SystemFrequency;
    break;
    case 0x02:
      pclk = SystemFrequency/2;
    break;
    case 0x03:
      pclk = SystemFrequency/8;
    break;
  }

  LPC_ADC->CR = ( 0x00 << 0 ) |  /* SEL=1,select channel 0~7 on ADC0 */
        ( ( pclk  / ADC_Clk - 1 ) << 8 ) |  /* CLKDIV = Fpclk / ADC_Clk - 1 */
        ( 0 << 16 ) |         /* BURST = 0, no BURST, software controlled */
        ( 0 << 17 ) |          /* CLKS = 0, 11 clocks/10 bits */
        ( 1 << 21 ) |          /* PDN = 1, normal operation */
        ( 0 << 24 ) |          /* START = 0 A/D conversion stops */
        ( 0 << 27 );        /* EDGE = 0 (CAP/MAT singal falling,trigger A/D conversion) */

  return;
}

LEO AD:

/*****************************************************************************
** Function name:        ADCRead
*****************************************************************************/

uint32_t ADCRead( uint8_t channelNum )
{
  uint32_t regVal, ADC_Data;


  LPC_ADC->CR &= 0xFFFFFF00; //start ADC
  LPC_ADC->CR |= (1 << 24) | (1 << channelNum);   


  while ( 1 )            // wait until end of A/D convert
  {
    regVal = LPC_ADC->DR[channelNum];// read result of A/D conversion
    if ( regVal & ADC_DONE )
    {
      break;
    }
  }   
  LPC_ADC->CR &= 0xF8FFFFFF;    /* stop ADC now */   
  if ( regVal & ADC_OVERRUN )    /* save data when it's not overrun, otherwise, return zero */
  {
    return ( 0 );
  }
  ADC_Data = ( regVal >> 4 ) & 0xFFF;
  return ( ADC_Data );    /* return A/D conversion value */
}

Y el DAC lo inicializo asi:

void DACInit( void )
{
//    LPC_PINCON->PINSEL1 = 0x00000000;
  /* setup the related pin to DAC output */
  LPC_PINCON->PINSEL1 = 0x00200000;    /* set p0.26 to DAC output */  
   
  LPC_DAC->CNTVAL = 0x00FF;
  LPC_DAC->CTRL = (0x1<<1)|(0x1<<2);     
  return;
}

Y EL DAC LO LEO CON :

LPC_DAC->CR = (sound[i] << 6) | DAC_BIAS;


En caso que quieras te paso todo, pero lo tengo muy desprolijo lo deberia organizar. Yo creo que el problema esta en las inicializaciones. Algo que con los dos ejemplos juntos no termina de andar. De todos modos mas que usar el AD0 necesito el AD5 (PIO1_4) que tampoco se como inicializar.

Desde ya muchas gracias!
Martin.

jorge tammela

unread,
May 8, 2012, 9:55:16 PM5/8/12
to embeb...@googlegroups.com
 dame unos dias que voy atratar de armar un task con lo que me pasates


2012/5/8 MartinchoII <mdel...@gmail.com>

-- Recibiste este mensaje porque estás suscripto al Grupo Google Embebidos32. Para postear en este grupo, escribe un email a embeb...@googlegroups.com. Para des-suscribirte, envía un email a embebidos32...@googlegroups.com. Para más opciones, visita el sitio del grupo en https://groups.google.com/d/forum/embebidos32?hl=es

MartinchoII

unread,
May 14, 2012, 6:04:57 PM5/14/12
to embeb...@googlegroups.com

Gracias por la molestia, no pude contestar antes, estuve probando otras cosas pero sin resultado.
Aunque sea necesitaria saber como funcionan los registros, o como usar la configuracion para cada uno individual. O donde puedo encontrarlo. Estuve leyendo el manual, la verdad que no puedo entenderlo todavia.
Me queda una cosa por probar y si no funciona estoy nuevamente en 0.
Encontre un foro http://mbed.org/forum/mbed/topic/1798/?page=1#comment-10009 ahi hablan del DMA y AD fijate si te puede servir algo de ahi para lo tuyo.
Desde ya muchas gracias.
Martin.



Reply all
Reply to author
Forward
0 new messages