Visualizzazione post con etichetta XMega. Mostra tutti i post
Visualizzazione post con etichetta XMega. Mostra tutti i post

martedì 25 giugno 2013

Programmare gli XMega tramite USB con Atmel FLIP ed Atmel Studio

Vediamo in questo articolo come programmare il nostro microcontrollore tramite il programma Atmel FLIP.

atmelusb

La nostra scheda di sviluppo EWS ATXMega32A4U contiene un bootloader compatibile con il protocollo FLIP USB DFU (descritto dall’Application Note AVR4023) che permette la programmazione tramite interfaccia USB senza la necessità di programmatori aggiuntivi.

Una nota per gli appassionati della piattaforma Arduino: anche su Arduino Uno e Mega2560 è presente il bootloader USB sul chip Atmega8U2 che è possibile aggiornare con FLIP (http://arduino.cc/en/Hacking/DFUProgramming8U2).

Prima di tutto installiamo il programma Atmel FLIP e colleghiamo la nostra scheda di sviluppo tramite USB. Tenendo premuto il pulsante SW2 (PC3) premiamo adesso il pulsante SW1 (RST) per effettuare il reset. Rilasciamo prima il pulsante di reset e dopo qualche istante il pulsante SW2.

Se abbiamo un micro XMega non appartenente alla serie A4U o C4 possiamo utilizzare di default altri pin secondo la seguente tabella tratta dall’Application Note AVR1916 che spiega nel dettaglio tutta la procedura:

table

Alternativamente è possibile ricompilare e ricaricare il bootloader tramite un programmatore per impostare un pin a piacimento scaricando i sorgenti del bootloader da http://www.atmel.com/Images/AVR1916.zip

All’avvio il bootloader controllerà (nel nostro caso con un ATXMega32A4U) se il pin PC3 è collegato a massa, quindi se il pulsante SW2 è premuto e in tal caso avvierà l’esecuzione del DFU (Device Firmware Upgrade) ed inizierà l’enumerazione USB del dispositivo che permetterà la programmazione da pc.

Aprendo Atmel Flip possiamo scegliere il nostro Device dal menù Device / Select dopodiché possiamo aprire la comunicazione USB tramite il menù Settings / Communication / USB e scegliendo il pulsante Open dalla finestra di dialogo che ci verrà presentata.

open

Per velocizzare le operazioni in alternativa è possibile utilizzare i primi due pulsanti grafici.

flip

Siamo adesso pronti a caricare il nostro programma che possiamo compilare tramite il menù Build/Build Solution di Atmel Studio una volta aperto il progetto. Scegliamo adesso in Atmel FLIP la voce File / Load HEX file.. ed indichiamo il file con estensione .hex appena generato, in genere è presente nella cartella col nome della configurazione scelta (Debug o Release) come ad esempio HelloASF\HelloASF\Debug\HelloASF.hex per il progetto HelloASF.

Verifichiamo che nel gruppo Operations Flow siano marcate tutte le spunte per una programmazione completa e facciamo click su Run, se tutto è andato a buon fine i pallini diventeranno tutti verdi e cliccando su Start Application (con la spunta Reset abilitata) il nostro codice inizierà a prendere vita.

Programmiamo il dispositivo direttamente da Atmel Studio

La guida in linea di Flip presenta qualche problema di compatibilità con Chrome ed è consigliato l’utilizzo di Internet Explorer, al suo interno sono presenti tutti i dettagli relativi al programma Flip, a BatchIsp, una utility a linea di comando in grado di svolgere tutte le operazioni di FLIP ed alla Atmel's ISP functions library, una serie di DLL per chi volesse scrivere un proprio programma per la programmazione ISP, sia Flip sia BatchIsp utilizzano questa libreria per il loro funzionamento.

Alle successive programmazioni Flip si ricorderà del device impostato ma sarà necessario ogni volta indicare il file da caricare, aprire la connessione USB, premere Run e Start Application, un procedimento non molto agile soprattutto in quelle occasioni in cui è necessario compilare e caricare molte volte il firmware per la verifica della correttezza del programma.

Utilizzando BatchISP è possibile rendere più agile la programmazione dei nostri dispositivi senza neppure uscire da Atmel Studio creando un apposito menù e pulsante. Purtroppo nativamente Atmel Studio non supporta ancora la programmazione tramite USB ma vediamo come rimediare.

Apriamo Atmel Studio, scegliamo Tools / External Tools ed inseriamo le seguenti informazioni:

Title: Upload with Atmel &FLIP
Command: C:\Program Files\Atmel\Flip 3.4.7\bin\batchisp.exe
Arguments: -device atxmega32a4u -hardware usb -operation erase f memory FLASH blankcheck loadbuffer "$(TargetPath)" program verify start reset 0

ext

Dove il percorso del programma BatchIsp ed il modello di microcontrollore dovrà corrispondere a quello utilizzato

Seguendo la guida è possibile modificare i parametri passati al programma per evitare ad esempio l’avvio automatico del firmware dopo l’upload o la sua verifica se non desiderata.

E’ possibile adesso aggiungere il pulsante del comando Upload with Atmel FLIP appena creato scegliendo External Command 1 nella finestra di dialogo Add Command presente in Tools/Customize/Commands e scegliendo la toolbar Device and Debugger

addcmd

Il risultato sarà molto più pratico, un comando accessibile sia da menù che da barra degli strumenti che in un click effettuerà la cancellazione della memoria Flash, l’upload del firmware ed il successivo reset sulla nostra scheda di sviluppo.

vs

Ad upload terminato tramite la finestra Output sarà possibile verificare il corretto svolgimento delle operazioni

output

Buona programmazione.. in un colpo di click

giovedì 20 giugno 2013

Prestazioni XMega in modalità Debug e Release

Atmel Studio, che ricordiamo essere una shell di Visual Studio personalizzata da Atmel, permette di gestire diverse configurazioni all’interno di uno stesso progetto.
Ogni configurazione imposta diversi parametri del compilatore e del linker, normalmente troviamo già pronte le configurazioni Debug e Release.
Vediamo superficialmente alcune differenze a livello prestazionale su un XMega32A4U a 32 MHz:











Istruzioni (all’interno di un ciclo continuo) Debug Release
ioport_set_pin_level(PORTA1, LOW);
ioport_set_pin_level(PORTA1, HIGH);
208.3 KHz8.333 MHz
PORTA.OUTSET = PIN1_bm;
PORTA.OUTCLR = PIN1_bm;
3.571 MHz8.333 MHz
PORTA.OUTTGL = PIN1_bm;
3.125 MHz6.250 MHz

A prima vista, noncuranti della configurazione impostata che normalmente è Debug, l’utilizzo delle API IOPORT potrebbe sembrare molto più lento rispetto alla manipolazione diretta dei registri.

Semplicemente passando alla configurazione Release si otterranno però performance molto simili, in alcuni casi quasi 40 volte superiori alla configurazione Debug.

debug_release

Come curiosità per i lettori che utilizzano la scheda Arduino, su un ATMega328P a 16 MHz utilizzando le istruzioni
void setup() {                
  noInterrupts();
  DDRB = B00000001;
  while(true)
  {
    PORTB = B00000001; 
    PORTB = B00000000; 
  }
}
void loop() {
}

è possibile ottenere una frequenza di 4.000 MHz che cala ad 1.064 MHz (con lunghe pause tra un onda quadra e la successiva) se il ciclo avviene all’interno della funzione loop() a causa del maggiore overhead presente nella chiamata alla funzione loop().


void setup() {                
  noInterrupts();
  DDRB = B00000001;
}
void loop() {
  PORTB = B00000001; 
  PORTB = B00000000;
}

mercoledì 19 giugno 2013

XMega I/O

Gli XMega (in realtà il vero nome è ATXMega ma utilizzerò XMega per brevità) sono i microcontrollori fratelli maggiori degli ATMega, familiari anche agli utenti della piattaforma Arduino.



Approcciarsi utilizzando il C inizialmente può però sembrare difficile, ad esempio un compito semplice come "alzare un pin" può essere svolto in più modi:
- Utilizzando direttamente i registri del microcontrollore
- Utilizzando il framework ASF
  - API GPIO
  - API IOPORT

Il framework ASF permette un livello di astrazione maggiore, internamente manipola i registri del microcontrollore che sono la strada maestra per la sua programmazione ma richiedono spesso un'approfondita conoscenza del datasheet.

I "nuovi" spesso cercando in internet rimangono confusi dalla molteplicità di istruzioni che trovano per svolgere la solita azione, in questo caso possono trovare ben tre "set" di istruzioni diverse, alcune addirittura con diverse varianti.

Tralasciando le API GPIO che sono deprecate vediamo un esempio con entrambi gli approcci.

Supponiamo di voler impostare come uscita, alzare ed abbassare il pin 1 della PORT A

Utilizzando i registri:

PORTA.DIRSET = PIN1_bm;   // set pin to output
PORTA.OUTSET = PIN1_bm;   // set to high
PORTA.OUTCLR = PIN1_bm;   // set to low

Utilizzando ASF (API IOPORT):

#define PORTA1 IOPORT_CREATE_PIN(PORTA,1)      // create a pin name alias
ioport_init();                                 // initialize IOPORT
ioport_set_pin_dir(PORTA1, IOPORT_DIR_OUTPUT); // set pin to output
ioport_set_pin_level(PORTA1, HIGH);            // set to high
ioport_set_pin_level(PORTA1, LOW);             // set to low

Entrambi gli approcci hanno vantaggi e svantaggi tipici della programmazione a basso livello contro una programmazione di livello maggiore.


La sintassi tramite i registri è molto diversa rispetto alla famiglia ATMega dove erano presenti ad esempio i registri DDRx e PORTx, è però meglio organizzata tramite delle strutture accessibili tramite una sintassi PORTx.REGISTER dove REGISTER è il registro della porta che si vuole impostare e può essere per esempio sull’ATXMega32A4U uno dei seguenti valori (tratto dal file header iox32a4u.h)


port structure


Un ulteriore vantaggio di questa sintassi è senza ombra di dubbio l’intellisense dell’ambiente Atmel Studio che alla pressione del punto ci proporrà visualmente uno dei possibili registri


intellisense


Per chi si trovasse male con la sintassi col punto può optare per utilizzare l’underscore al suo posto, ad esempio potrà scrivere in maniera equivalente

PORTA_DIRSET = PIN1_bm;
PORTA_OUTSET = PIN1_bm;
PORTA_OUTCLR = PIN1_bm;

ricordando però che non potrà utilizzare un #define per impostare la sola porta come ad esempio è possibile con la sintassi con le strutture:


#define MYPORT PORTA   
MYPORT.DIRSET = PIN1_bm;


Il prezzo da pagare per questa ulteriore flessibilità (utilizza del punto o dell’underscore) è un’ulteriore confusione per i novizi che troveranno quindi molti modi per gestire i pin. Una volta consci delle molteplici possibilità non si avranno però problemi.


Aggiungo come nota al codice ASF che quasi tutte le API hanno una funzione nomeAPI_init() che deve essere chiamata prima dell'utilizzo delle restanti funzioni.

Per chi volesse valutare o iniziare a programmare gli XMega personalmente consiglio di partire dalla libreria ASF che ha buona parte delle API corredate da una documentazione minimale ma con un'ottima sezione Quick Start che permette di fare i primi passi in tempi molto brevi, per IOPORT il link è http://asf.atmel.com/docs/latest/xmegaau/html/ioport_quickstart.html, accessibile anche da ASF Explorer direttamente dall'interno di Atmel Studio