PSoC 4M DMA Periferico a Periferico Ej. 1

Recien me llego una tarjeta de desarrollo de Cypress, la CY8CKIT-043 que trae un PSoC 4200M.
Lo primero que hice fue actualizar la versión de KitProg que trae de fabrica, esto se hace con el PSoC Programmer.
Despues cree un proyecto nuevo, elegi el dispositivo que trae la placa, que es el CY8C4247ZI-M485.

Este proyecto lee una entrada analogica con el ADC, y manda el resultado al compare value de un bloque PWM, ya lo habia hecho con un PSoC 5LP, pero el componente DMA es muy diferente entre estas dos familias.

Primero implemento el esquematico:
Esquematico
El ADC esta configurado con resolución de 8bits, sampleo continuo, rango Vss - Vdda (0 - 5V), el sample rate lo deje en 1000 que es lo más bajo que acepta el componente, terminal single y no differential, la configuración completa se puede ver en la siguiente imagen.
Configuración 1 del ADC
El ADC es de 12bits de resolución, pero se puede cambiar a 8bits o 10bits (indicado en la opción Alternate resolution de la imagen de arriba) , y el cambio de resolucion se configura en la pestaña channels. En la fila del Channel 0, columna Resolution debemos elegir ALT para configurar el ADC a 8bits.
Configuración 2 del ADC
Este ADC tiene muchas opciónes que no he usado antes, es un poco más complejo que los ADC del PSoC 5LP, además que es el unico presente en los PSoC 4.

La configuración del PWM la podemos ver a continuación.
Configuración PWM
El PWM esta configurado a 8bits, una sola salida, periodo al maximo y el valor que será destino del DMA es el CMP_Value 1.

Al final configuramos el DMA, la ventaja de este componente sobre el componente presente en los 5LP es que configuramos casi todo dentro de la ventana de ayuda del componente, al menos en este proyecto no use el DMA Wizard :D.

En la primer ventana configuramos la prioridad del canal, el número de descriptores (limitado a 2 por canal :( ) y habilitamos la terminal del trigger, esta terminal estará conectada al eoc (End of Convertion) del ADC para que la transferencia se haga cada que el ADC termine de convertir el voltaje presente en la entrada analogica.
Configuración 1 del DMA
En la pestaña Descriptor 0, como su nombre lo indica configuramos el descriptor 0 del canal.
  • Data element size: El ADC esta configurado a 8bits, por lo tanto el dato que vamos a mandar del ADC al PWM es de 8bits (1 byte).
  • Number of data elements to transfer: vamos a transferir de manera continua.
  • Source and data destination transfer width: Aqui tuve problemas, pensé que deberia ser byte to byte, pero el datasheet del ADC dice que el bus donde trabaja el ADC es de 32bits (1 word), y el tamaño del destino depende del usuario, en nuestro caso 8bits.
  • No queremos que se incremente ni la dirección de la fuente ni del destino, entonces no las habilitamos.
  • Trigger type: Un pulso que obtenemos del eoc, por lo tanto elegimos esa opción.
  • Transfer mode: un solo elemento por trigger.
  • Post completion actions: no queremos ni generar un pulso de interrupcion ni invalidar el descriptor, asi que no habilitamos nada. Si habilitamos el pulso de interrupción, se presentaria al terminar la transferencia del número de bytes que configuramos en Number of data elements to transfer.
Configuración 2 del DMA
Aqui podemos ver el datasheet del ADC donde explica la configuración en caso de ocupar DMA:
Siempre lee el Datasheet!!!

Despues de configurar todo asignamos los pines:
Asignación de pines
El LED en esta tarjeta esta en el pin P1[6], la entrada del ADC la elegi basado en la ayuda que proporciona creator, si el pin es apto nos lo indica con un cuadro verde al lado del pin.

Despues generamos la aplicación y al terminar nos vamos a escribir el main:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
#include <project.h>

int main()
{
    CyGlobalIntEnable;
    
    DMA_Start((void *)ADC_SAR_CHAN0_RESULT_PTR, (void *)PWM_COMPARE1_LSB_PTR);
    
    PWM_Start();
    ADC_Start();
    ADC_StartConvert();

    for(;;){
    }
}

/* [] END OF FILE */

Podemos ver en la linea 7 la configuracion del DMA, el primer parametro es un puntero universal o a un dato void, es la dirección de la fuente, el segundo parametro del destino. Entonces configuramos el DMA a transferir información del registro donde se guarda el resultado de la conversion del ADC y el destino es el registro del PWM donde se escribe el compare value.
En la linea 9 inicializamos el PWM, en la 10 inicializamos el ADC y en la 11 iniciamos la conversión del ADC.
Y es todo, no tenemos todo el código que generaba el DMA Wizard con los 5LP :D.

Sebastian me ayudo a terminar el proyecto y a checarlo en su kit CY8CKIT-046 que tiene un PSoC 4L, lo unico que tuvo que cambiar es el pin donde tiene el LED onboard. Lo puedes encontrar en su twitter o en Hackster.

Saludos

Comentarios

Entradas más populares de este blog

PSoC Creator Tools

sprintf en PSoC Creator 3.0 y 3.1