viernes, 27 de junio de 2014

MASTER SPI CON DMA – ATXMEGA

 

En este post mostraré como usar el DMA para quitarle carga al CPU y acelerar las transferencias del SPI en modo master.
Debemos tener en cuenta que según el manual de los XMEGA esto no es posible. “No es posible” ya que no hay un evento que pueda disparar la transferencia de datos, solo existe el evento de recepción de datos ( DMA_CH_TRIGSRC_SPIC_gc  para el SPI C).

Pero gracias a que el DMA tiene cuatro canales y que se puede establecer prioridades de los cuatro canales es que se puede implementar la transferencia por SPI usando el DMA.



image

Rx y Tx son los vectores a transmitir y recibir.

Habilitamos el DMA y establecemos la prioridad de los canales. La prioridad debe ser establecida ya que el CH0(Rx) y CH1(Tx) serán usados con el mismo evento, y debemos sacar el datos recibido antes de enviar el nuevo dato.


image


Configuramos el CH0 para recibir los datos por el SPIC. Los datos recibimos se guardan en Rx.


image

Configuramos el CH1 para transmitir los datos por el SPIC. Los datos trasmitidos se sacaran de Tx. Rx y Tx deben ser de la misma longitud. Pero TRFCNT se configura con un dato menos(desde Tx[1] hasta Tx[12]) ya que Tx[0] se usara para disparar la transferencia.



image

Se configura los pines MISO, MOSI, SCK y SS. Tambien Configuramos el SPI.


image

Habilitamos los canales CH0 y CH1.


image

Ponemos el SS a cero.
Ponemos el primer dato a transmitir (Tx[0]) en el registro de datos. Esto dispara la transmisión de todos los datos. Cuando termine de salir el primer dato también debería haber llegado el primer dato y esto activara la transferencia del DMA. Gracias a la prioridad establecida al inicio, primero en CH0 guardara el dato recibido y luego el CH1 pondrá en el registro de salida el nuevo dato a enviar.
Esto continuara hasta que se reciban todos los bytes.
Se espera a que termine la transmisión y ponemos SS a uno.


image

Arriba se muestra la imagen de SCK y MOSI.

Lo mostrado arriba funciona, pero personalmente no me gusta el tiempo de retardo que existe entre byte y byte. Al parecer esto se debe a que el SPI solo tiene un buffer.


image

Esto se puede apreciar con mejor claridad en la imagen anterior, y esto puede reducir la velocidad efectiva del SPI.



Para evitar este problema la solución puede ser usar el USART en modo MASTER SPI. Tener en cuenta que en este modo si se hay dos eventos para disparar la transmisión y recepción.

Aquí el código:

- La primera parte es la misma.

image

Se configura el CH0 para recibir los datos, para ellos se usa el evento RXC.


image

Mediante CH1 se transmitirá los datos de Tx. Se usará la evento DRE.


image

Se configura los pines Tx, Rx y SCK, también el USART en modo MASTER SPI y se habilita la Transmisión y Recepción.


image

Ponemos el SS a cero y habilitamos CH0 y CH1 del DMA.
Se espera a que termine la transmisión y ponemos SS a uno

Ahora, y gracias a los tres niveles de buffer del USART, ya no veremos retardos entre la salida de bytes.

image


Bueno, espero esto les ayude.

Hasta pronto !.

No hay comentarios:

Publicar un comentario