Consulta sobre ejemplo de ADC/DAC en EDU-CIAA

727 views
Skip to first unread message

jel...@gmail.com

unread,
Dec 10, 2015, 5:36:07 PM12/10/15
to Embebidos32
Hola! Me estoy iniciando con la placa edu-ciaa y quería hacerles algunas consultas porque quiero entender mejor como funciona el ejemplo sobre el uso del adc y el dac.
No tengo experiencia en el uso de RTOS, por lo que estos días estuve leyendo sobre OSEK-OS. Lo que pude interpretar del ejemplo es que la tarea que lee el ADC y escribe en el DAC se ejecuta cada 1ms. Es correcto?
Cómo podría hacer si quiero muestrear a una frecuencia mayor?
También veo que en el archivo .oil hay varias rutinas de interrupción definidas (adc0, adc1 y para el dma), pero en el archivo .c no veo que se usen. Cómo debería hacer si quiero utilizarlas?
Pido disculpas si es una pregunta muy básica, pero ando medio perdido con este tema.
Muchas gracias.

jel...@gmail.com

unread,
Dec 11, 2015, 12:24:32 PM12/11/15
to Embebidos32
Bueno, estuve probando con la placa, un generador de funciones y un osciloscopio, y efectivamente el  período de muestreo es de 1ms.
Lo que me gustaría poder hacer es disminuir ese tiempo para poder aumentar la frecuencia de muestro, y también saber como usar la rutina de interrupción por conversión del ADC.

Pablo Ridolfi

unread,
Dec 11, 2015, 12:30:40 PM12/11/15
to Embebidos32
Tenés que trabajar en el driver del ADC:
Lamentablemente yo no trabajé en este driver y no estoy al tanto de cómo está implementado (solo le hice una pequeña corrección), pero el código está bastante claro así que no debería ser difícil adaptarlo a tus requerimientos.




--
-- 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
---
Has recibido este mensaje porque estás suscrito al grupo "Embebidos32" de Grupos de Google.
Para anular la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a embebidos32...@googlegroups.com.
Para acceder a más opciones, visita https://groups.google.com/d/optout.

martin ribelotta

unread,
Dec 11, 2015, 12:36:38 PM12/11/15
to embeb...@googlegroups.com
Por lo que veo, hay una IOCTRL para ponerle la frecuencia de sampleo:
ciaaPOSIX_IOCTL_SET_SAMPLE_RATE

Y por lo que veo, el ejemplo es bastante explicito (casi pornográfico)
al respecto:
https://github.com/ciaa/Firmware/blob/master/examples/adc_dac/src/adc_dac.c#L159


El día 11 de diciembre de 2015, 14:30, Pablo Ridolfi
<pablor...@gmail.com> escribió:

jel...@gmail.com

unread,
Dec 11, 2015, 1:11:57 PM12/11/15
to Embebidos32
Eso lo veo. Mi pregunta viene porque más allá de la frecuencia que se configure ahí, la tarea que lee el ADC y escribe en el DAC se ejecuta cada 1ms. O por lo menos eso es lo que entiendo con lo que estuve leyendo sobre el RTOS.

martin ribelotta

unread,
Dec 11, 2015, 1:35:54 PM12/11/15
to embeb...@googlegroups.com
Generalmente es mala idea interrumpir en cada dato del ADC y generar
un nuevo dato del DAC,
Lo que normalmente se hace, es llenar un buffer, procesarlo y escupir
(con un timer, DMA o, como en este caso, el propio control del DAC) la
ristra de datos.
En todo caso, habria que cambirle la frecuencia a la tarea y procesar
menos datos.
Generalmente, el buffer de procesamiento se calcula en base a los SPS
(samples per second) entrantes y salientes (teniendo en cuenta si tu
procesamiento reduce o aumenta los SPS de salida)

En concreto que es lo que queres hacer?

Juan Manuel Cruz Beaufrere

unread,
Dec 11, 2015, 1:38:05 PM12/11/15
to embeb...@googlegroups.com
Son amores distintos, por lo pronto olvidate del RTOS y concentrate en definir qué necesitas de la conversión.

Definiendo qué necesitas podes configurar ambos conversores para que se manejen por interrupciones y con la ayuda del controlador de DMA para almacenar/recuperar muestras.

Pero como te dijo Pablo tenes que meterle mano a los drivers.

Ing. Juan Manuel Cruz
Profesor Adjunto - Seminario de Sistemas Embebidos

Laboratorio de Sistemas Embebidos | Facultad de Ingeniería - UBA
Paseo Colón 950
[C1063ACV] Buenos Aires. Argentina
Tel [54 11] 4343 0893 / 0092 | Int
E-mail:
juanmanuelc...@gmail.com
Visítenos en:
http://laboratorios.fi.uba.ar/lse/

jel...@gmail.com

unread,
Dec 11, 2015, 2:05:03 PM12/11/15
to Embebidos32
Si, lo que normalmente hago es usar un timer para tomar muestras con el ADC, por eso quería saber como debería hacer cambiar la frecuencia de ejecución de la tarea.

En primer lugar lo que quiero hacer es muestrear una señal de frecuencia mayor a la que me permite el ejemplo, para después sacar las muestras por el DAC, y una vez que sepa como modificar la frecuencia de muestreo, agregaría otras cosas, como un buffer para almacenar los datos y aplicar algún procesamiento sobre la señal.
Por ahora no estoy tratando de hacer nada muy específico, solo familiarizarme con el uso de la edu-ciaa y sus periféricos.
Gracias por las respuestas.


El viernes, 11 de diciembre de 2015, 15:38:05 (UTC-3), juanmanuelcruzbeaufrere escribió:
Son amores distintos, por lo pronto olvidate del RTOS y concentrate en definir qué necesitas de la conversión.

Definiendo qué necesitas podes configurar ambos conversores para que se manejen por interrupciones y con la ayuda del controlador de DMA para almacenar/recuperar muestras.

Pero como te dijo Pablo tenes que meterle mano a los drivers.

Ing. Juan Manuel Cruz
Profesor Adjunto - Seminario de Sistemas Embebidos

Laboratorio de Sistemas Embebidos | Facultad de Ingeniería - UBA
Paseo Colón 950

[C1063ACV] Buenos Aires. Argentina
Tel [54 11] 4343 0893 / 0092 | Int

Juan Manuel Cruz Beaufrere

unread,
Dec 11, 2015, 2:20:48 PM12/11/15
to embeb...@googlegroups.com
Para familiarizarte con los periféricos de ese micro lo que te conviene es descargar la librería LPCOpen (https://www.lpcware.com/content/nxpfile/lpcopen-software-development-platform-lpc43xx-packages), descomprimirla y ver lo ejemplos de conversión AD y conversión DA, en ellos c/conversor está manejado de todos los modos posibles (encuesta, interrupciones o DMA).

Mi recomendación es que tomes las definiciones y código del ejemplo de CAD, que lo pegues en el ejemplo baremetal de la CIA y que adecues las definiciones al hardware de la EDU-CIAA-NXP.

Que luego hagas lo propio con el CDA y que finalmente vincules ambos periféricos.
dac.c
adc.c

martin ribelotta

unread,
Dec 11, 2015, 2:25:22 PM12/11/15
to embeb...@googlegroups.com
Por las dudas, te dejo el repo que hice con la ultima LPCOpen para el
IDE de la CIAA:
https://github.com/martinribelotta/ciaa_lpcopen_bare
Ni bien llege a casa los pruebo con el ultimo CIAA-IDE a ver que onda,
peor la idea general es importar toda la carpeta como un proyeccto
Makefile y luego editar el Makefile principal con el proyecto que
queres trabajar

El día 11 de diciembre de 2015, 16:20, Juan Manuel Cruz Beaufrere
<juanmanuelc...@gmail.com> escribió:
>> E-mail: juanmanuelc...@gmail.com

Mariano Cerdeiro

unread,
Dec 11, 2015, 2:40:16 PM12/11/15
to embebidos32
Hola,

en mi opinion lo bueno de usar el Firmware es independizarce del HW. El driver implementa las inteerrupciones que estas buscando:
https://github.com/ciaa/Firmware/blob/master/modules/drivers/cortexM4/lpc43xx/lpc4337/src/ciaaDriverAio.c#L600

en tu codigo vos haces un read y lees lo que hay en el buffer de lectura. El drier adc funciona como uno serial, podes recibir x datos.

Si te fijas esto se hace en
https://github.com/ciaa/Firmware/blob/master/modules/drivers/cortexM4/lpc43xx/lpc4337/src/ciaaDriverAio.c#L593

Respecto a la tarea de 1ms esa no tiene nada que ver con el sample rate, sino es cada cuanto lees los datos. el buffer de entrada serial son 256 bytes asique podes calcular cada cuanto a lo sumo debes leer los datos.

Para cambiar la tarea de 1ms a otro tiempo tenes que usar las alarmas del rtos. El periodo esta configurado en
https://github.com/ciaa/Firmware/blob/master/examples/adc_dac/etc/adc_dac.oil#L78 También se podria hacer en el codigo fuente, podes mirar el ejemplo de blinking que lo hace en el codigo c el seteo de la alarma.

Y ahora que decis me parece se nos escapo un error en el ejemplo.
https://github.com/ciaa/Firmware/blob/master/examples/adc_dac/src/adc_dac.c#L162

está mal esta linea ya que la tarea igual se ejecuta cada 1ms, y el comentario también es incorrecto, ahora lo modifico :)

Saludos.
Mariano.-

Para obtener más opciones, visita https://groups.google.com/d/optout.

martin ribelotta

unread,
Dec 11, 2015, 3:22:55 PM12/11/15
to embeb...@googlegroups.com
Ok, ahi entiendo un poco mejor el asunto.
Fijate que con el OSEK solo tenes que setearle la frec. de muestreo a
ambos y meter tu codigo en la tarea de procezamiento.

TASK(Analogic)
{
uint16_t hr_ciaaDac[1024;
/* Read ADC. */
ciaaPOSIX_read(fd_adc, &hr_ciaaDac, sizeof(hr_ciaaDac));
/* Procesar el array hr_ciaaDac */
ciaaPOSIX_write(fd_dac, &hr_ciaaDac, sizeof(hr_ciaaDac));
TerminateTask();
}

Y luego ajustar el tiempo de ejecución de la tarea.
@Mariano: No hay alguna manera de hacer esto sin un timer? Por
ejemplo, por finalización de DMA???? Es lo primero que se me ocurre.
>> E-mail: juanmanuelc...@gmail.com

Mariano Cerdeiro

unread,
Dec 11, 2015, 3:32:12 PM12/11/15
to embebidos32
Hola Martin,

si obviamente hay otras formas... :) hoy no maneja dma el driver, si se configura se podria tener una isr y activar una tarea desde la isr que indica que el buffer esta lleno o algo asi.

tambien creo hay un bug en el driver ya que si el buffer circular del driver le queda un numero impar de bytes se pierde un solo byte etnonces se desfaza todo. :( pero no estoy seguro. nos falta definitivamente mucho en testing :) :(

saludos.
Mariano.-


Para obtener más opciones, visita https://groups.google.com/d/optout.

martin ribelotta

unread,
Dec 11, 2015, 3:45:11 PM12/11/15
to embeb...@googlegroups.com
El día 11 de diciembre de 2015, 17:31, Mariano Cerdeiro
<mcer...@gmail.com> escribió:
> Hola Martin,
>
> si obviamente hay otras formas... :) hoy no maneja dma el driver, si se
> configura se podria tener una isr y activar una tarea desde la isr que
> indica que el buffer esta lleno o algo asi.
>
Una cosa que me queda en el tintero es porque no activar eventos desde
las ISR a bajo nivel así nos evitamos escribir codigo de ISR no
portable (desgraciadamente, esto nos obligaria a definir eventos
dependientes de los subsistemas)

> tambien creo hay un bug en el driver ya que si el buffer circular del driver
> le queda un numero impar de bytes se pierde un solo byte etnonces se desfaza
> todo. :( pero no estoy seguro. nos falta definitivamente mucho en testing :)
> :(
>
Igual el laburo es bueno! hay que darle para adelante nomas!

Mariano Cerdeiro

unread,
Dec 11, 2015, 3:51:32 PM12/11/15
to embebidos32
Creo que depende de la arq. que se arme, si quien lo hace le interesa la portabilidad se logra. ya que el codigo de la isr es menor. El mayor se implementa en la tarea y listo.

El firmware ya hace eso, en general pero no tiene hoy el posix la posibilidad de callback cuando pasa algo y por eso no se puede. igualmente el driver tampoco soporta dma.

igualmente creo para la gran mayoria de los casos lo impl. alcanza y para esos especificos en los que no se puede extender :)

los tests es un tema que nos queda mucho por hacer. y ojo ya hay muchisimo para ser un proyecto open source. pero hay mucho por recorrer.

Saludos.
Mariano.-
Message has been deleted

Juan Lopez

unread,
Dec 11, 2015, 9:37:54 PM12/11/15
to Embebidos32, mcer...@gmail.com
Gracias a todos por las respuestas, voy a tratar de digerir toda la información.
Mariano, por lo que leí en tu introducción a OSEK-OS, en la CIAA 1 tick es 1ms. Cómo tendría que hacer para que el período de la tarea sea menor a ese 1ms? Por ejemplo, si quisiera que la tarea se ejecutara cada 100us.

Mariano Cerdeiro

unread,
Dec 12, 2015, 5:21:39 AM12/12/15
to Juan Lopez, Embebidos32
Hola Juan,

en OSEK-OS lamentablmente no esta definido cuanto tiempo es un Tick, es dependiente de la plataforma... :( En el FreeOSEK del CIAA-Firmware decidimos hacer 1 Tick = 1 ms por tema de portabilidad. Por ello no es posible hacer una alarma más rápida que ello sin modificar el RTOS... :(

Igualmente en mi opinion habria que pensar realmente si se quiere activar en un SE una tarea más de mil veces por segundo. Creo debe haber soluciones mejores. una tarea tiene bastante overhead y ejecutarla tantas veces es matar al procesador.

Tal vez para proceasr algo asi lo que más convenga es una interrupción. Y si es a una frequencia muy alta una de categoria 1 que es transparente al RTOS, osea es una interrupción como si no hubiese RTOS y fuese un baremetal. Claro en estas interrupciones no se pueden usar las apis del RTOS pero tienen el menor overhead, solo lo que necesite el procesador. :)

Se entiende la idea?

Saludos.
Mariano.-

Juan Lopez

unread,
Dec 12, 2015, 7:32:41 AM12/12/15
to Embebidos32, juanml...@gmail.com, mcer...@gmail.com
Claro, entiendo, es una pérdida de recursos innecesaria.
Entonces si quisiera usar interrupciones tendría que configurar los registros del micro y agregar la rutina de interrupción en el archivo adc_dac.c, no?

Mariano Cerdeiro

unread,
Dec 12, 2015, 7:50:45 AM12/12/15
to Juan Lopez, Embebidos32
Hola Juan,

depende, si queres extender el driver si, pero por lo que entendi lo que queres es tener una interrupcion por ende eso lo haria en tu codigo. Podes hacerlo como vos quieras eso.

Podes fijarte en el pdf que mande hace un rato a emb32. El capitulo 7 es de interrupciones. Hay muy poco que saber del tema, solo que tenes que indicarlas con ISR(Name) y Name es como están declaradas en el oil.

obviamente debes inlcuir os.h.

Saludos.
Mariano.-

Juan Cecconi

unread,
Dec 12, 2015, 7:53:15 AM12/12/15
to embebidos32, Juan Lopez

La.mayoría de los ejemplos si no todos usan alguna interrupción. Fijate el código y la configuración del .oil para tener como base!
Saludos

jel...@gmail.com

unread,
Dec 14, 2015, 5:22:56 PM12/14/15
to Embebidos32, juanml...@gmail.com
Bueno, pude combinar los ejemplos compartidos por El Ruso (gracias!) del lpcopen del ADC y el DAC y correrlos en la CIAA (en el del ADC hay un pequeño problema que al principio hay unas definiciones que dependen de la placa que se use, y faltaba agregar la edu-ciaa, pero una vez que la agregué salió andando). Esto funcionó perfecto.
Con respecto al CIAA-Firmware sigo con problemas. Quería agregar un evento en la rutina de recepción del ADC que se activara una vez que se recibieran X cantidad de datos e hiciera correr una tarea en la cual se pueda procesar los datos y sacarlos por el DAC, pero no funciona.
Estoy usando el handler que está en el archivo ciaaDriverAio.c, pero no se si están bien esto. Tampoco se si estoy definiendo bien los eventos :P, así que voy a seguir leyendo más sobre el tema.

martin ribelotta

unread,
Dec 14, 2015, 6:00:28 PM12/14/15
to embeb...@googlegroups.com
El día 14 de diciembre de 2015, 19:22, <jel...@gmail.com> escribió:
> Bueno, pude combinar los ejemplos compartidos por El Ruso (gracias!) del
> lpcopen del ADC y el DAC y correrlos en la CIAA (en el del ADC hay un
> pequeño problema que al principio hay unas definiciones que dependen de la
> placa que se use, y faltaba agregar la edu-ciaa, pero una vez que la agregué
> salió andando). Esto funcionó perfecto.
Armate un pull recuest así ponemos ese ejemplo a andar en el firmware LPCOpen.
Acá esta como se hace:
https://help.github.com/articles/using-pull-requests/
https://help.github.com/articles/creating-a-pull-request/

jel...@gmail.com

unread,
Dec 15, 2015, 7:14:49 AM12/15/15
to Embebidos32
Ok, después veo los links y lo hago.
Lo que no probé del ejemplo es la parte de la UART; se la saqué para probar los del ADC nada más.
Reply all
Reply to author
Forward
0 new messages