Saltar al contenido

Programación ARM de ATMEL sin ASF

Solución:

La arquitectura ARM es sustancialmente diferente a la de AVR, pero aún tiene acceso a cualquier registro interno operando en su dirección.

El camino AVR

Con AVR, habría establecido la dirección de un pin utilizando el registro DDRx, que se definió para usted siempre que incluyera “io.h” y definiera su nombre de MCU antes de esta inclusión (o lo pasara como una opción de compilador) .

Detrás de escena, “io.h” luego incluyó todo lo que necesitabas para ese MCU. Para el ATmega328p, esto habría sido “iom328p.h” donde puede encontrar definiciones para cada registro, como …

#define DDRB _SFR_IO8(0x04)
#define DDB0 0
#define DDB1 1
#define DDB2 2
// ... and so on

Si sigue investigando, encontrará que la macro _SFR_IO8 () (definida en “sfr_defs.h”) agrega un desplazamiento a esta dirección, y eso es todo. Ahora tienes una buena macro. DDRB que le otorga acceso a la Registro de dirección de datos de Puerto B.

// Set Pin B1 as an output
DDRB = _BV(PB1);

El estilo (Atmel) ARM

Los chips de numerosos proveedores contienen núcleos de procesador ARM. los samd21 (lista de productos) es una familia de chips de Atmel con una CPU ARM Cortex-M0 +. Esta misma CPU podría estar en chips de Microchip (que ahora es dueño de Atmel), TI, STMicro, etc. Cada CPU compartirá algunas cosas como NVIC, SCB y MTB, y cada proveedor puede construir alrededor del núcleo como quiera.

En el caso de Atmel, tienen un conjunto de paquetes que contienen definiciones, scripts y código de inicio para cada uno de sus chips, similares a los que se usan con AVR, pero mucho más complicados. Si usa Atmel Studio, incluirá automáticamente los archivos de encabezado correctos para su MCU; sin embargo, también puede descargar estos paquetes e incluir manualmente lo que necesita. Tenga cuidado, es un laberinto de código duplicado, nombres de archivos repetidos y directorios extrañamente anidados.

Una vez que se incluye el encabezado raíz correcto (como “samd21.h”), nuevamente tiene acceso a los registros, pero están organizados de manera un poco diferente. Echando un vistazo a la hoja de datos de SAMD21, vemos que los pines se manejan con el PUERTO periférico. Desde el PUERTO root, registros como DIR, FUERA, y EN se puede utilizar para establecer la dirección, establecer la salida o leer la entrada.

Navegación por los registros ARM de Atmel

Entonces, ¿cómo accedemos a estos registros? Recuerde, en el código C, estos registros son en realidad solo punteros a alguna dirección. Atmel proporcionó dos formas, la primera utiliza una serie de estructuras, uniones y enumeraciones:

// Set Pin A1 as an output
PORT->Group[0].DIR.reg = PORT_PA01;

También puede direccionar bits individuales en un registro usando los campos de bits:

// Set Drive Strength to max on Pin A1
PORT->Group[0].PINCFG[1].bit.DRVSTR = 1;

Si no le gusta este método, aún puede acceder directamente a los registros de esta manera:

// Set Pin A1 as an output
REG_PORT_DIR0 = PORT_PA01;

Nota 1 – al igual que un chip AVR típico, hay varios PUERTOS. En el caso del SAMD21, hay puertos A y B. El puerto A se designa como Grupo 0 mientras que el puerto B se designa como Grupo 1; por eso:

PORT->Group[0].DIR.reg = PORT_PA01;   // Port A: Group[0].DIR

o

REG_PORT_DIR0 = PORT_PA01;   // PortA : DIR0

Nota 2 – En lugar de establecer el DIR registrarse directamente, Atmel proporciona DIRSET, DIRCLR, y DIRTGL para permitir actualizaciones inmediatas a este registro sin requerir el típico leer-modificar-escribir operaciones (| =, & =, etc). Hay accesos directos similares disponibles para muchos registros de periféricos.

Nota 3 – Toda esta información se encuentra en la hoja de datos, pero puede ser abrumadora. Incluso si no desea usar ASF o Atmel Studio (yo personalmente no lo hago), puede ser muy útil abrir un proyecto básico con el chip que desea usar para ver ejemplos de cómo acceder a los registros o configurar periféricos. Atmel Studio también tiene una buena función de autocompletar para las definiciones, por lo que si comienza a escribir “PUERTO”, aparecerán opciones para la siguiente declaración válida. Hay muchos nombres para recordar aquí, por lo que es extremadamente valioso.

Un ejemplo practico

El SAMD21 tiene periféricos conocidos como SERCOM que se puede configurar como USART, I2C o SPI. ¡El samd21g18 tiene 6 de ellos! Eso es genial, pero la forma predeterminada de acceder a los registros es la siguiente:

SERCOM0->USART.CTRLA.reg |= SERCOM_USART_CTRLA_ENABLE;
SERCOM1->SPI.CTRLA.reg |= SERCOM_SPI_CTRLA_ENABLE;

o

REG_SERCOM0_USART_CTRLA |= SERCOM_USART_CTRLA_ENABLE;
REG_SERCOM1_SPI.CTRLA |= SERCOM_SPI_CTRLA_ENABLE;

Esto es bastante fácil, pero dificulta la creación de una biblioteca genérica para usar el SERCOM sin usar macros extrañas para asignar un número [0,5] al SERCOM desea utilizar.

Para evitar esto, puede crear una matriz de SERCOMs usando un par de valores definidos que Atmel proporcionó en los encabezados “samd21.h”.

Sercom * const SERCOM[SERCOM_INST_NUM] = SERCOM_INSTS;

Ahora, podemos acceder a los SERCOM usando código genérico y funciones que pasan el número de instancia de SERCOM como una variable:

static inline void
USART__enable (uint_fast8_t instance) {
   SERCOM[instance]->USART.CTRLA.reg |= SERCOM_USART_CTRLA_ENABLE;
}
// ...
USART__enable(0);
USART__enable(1);

Conclusión

Para realmente entender estas cosas (especialmente si desea escribir una guía para otros), deberá dedicar un tiempo a leer la hoja de datos de algunos chips ARM de Atmel, revisar el código generado en Atmel Studio usando ASF y profundizar en los archivos de encabezado de instancia, pio y componente incluidos para un chip en los paquetes Atmel.

Nota 4 – La documentación de Atmel no es completa ni fácil de entender inicialmente. Por ejemplo, ¿sabía que puede acceder al PUERTO periférico directamente para algunas acciones, como configurar o borrar el FUERA bits usando el PORT_IOBUS? Se menciona, pero no se analiza realmente en la hoja de datos. Si comprende la arquitectura del bus MCU, habrá obtenido esta información de los diagramas de bloques. Aquí tienes un ejemplo de por qué es importante:

PORT vs PORT_IOBUS

El objetivo de este ejemplo es mostrar cuánto más rápido el PORT_IOBUS las operaciones tienen lugar que el PUERTO operaciones. No hay retrasos en el código, solo llamadas consecutivas a OUTTGL. Algunas cosas solo se pueden descubrir experimentando o aprendiendo de aquellos que ya lo han hecho.

Aquí hay una excelente publicación en línea sobre la programación de Atmel ARM sin ASF.

Los periféricos de un procesador Atmel ARM son bastante diferentes a los del AVR. Si bien tienen las mismas capacidades básicas, la interfaz de programación es muy diferente. Creo que sería posible crear una capa de software que imitara el método del programa AVR, pero terminaría siendo mucho código.

El único procesador Atmel ARM con el que estoy familiarizado es el SAM D21, que estoy usando en un proyecto actual. Si bien mi objetivo no era que pareciera un AVR desde el punto de vista de la programación, encontré que el ASF era muy engorroso de usar. Terminé creando mis propias rutinas para configurar y controlar los diversos periféricos, pero aproveché los archivos de encabezado de periféricos que se pueden encontrar en cualquier proyecto ASF de ejemplo. Para un proyecto de ejemplo SAM D21, estos archivos de encabezado se pueden encontrar en src/ASF/SAM0/utils/cmsis/samd21/include/. Este directorio contiene los siguientes archivos / subdirectorios:

  • root – archivos de encabezado para todos los modelos SAMD21
  • component – archivos de encabezado para cada periférico compatible con SAMD21
  • instance – archivos de encabezado específicos para cada instancia periférica (por ejemplo, 6 archivos sercom)
  • pio – definición de todos los bits de E / S disponibles para cada modelo SAMD21

Asumiría que otros procesadores Atmel ARM usan una estructura similar.

ASF está escrito en C, pero como solo estoy usando los archivos de encabezado, no he tenido ningún problema con mi aplicación C ++.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)


Tags : /

Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *