mma8451q accelerometer

Oggigiorno ogni dispositivo “mobile” come smartphone tablet etc, dispone di accelerometri interni che possono fornire informazioni riguardo all’orientamento del dispositivo oppure la forza G alla quale il dispositivo è sottosposto. Da questo ne derivano funzioni come “contapassi”, comandi attivati con lo “shake” l’orientamento dello schermo eccetera.

orientamento accelerometro

Ma prima di utilizzarlo è necessario capire esattamente come funziona. Immaginate di appoggiare su di un tavolo perfettamente piano (in bolla, come si dice dalle mie parti) il dispositivo. A questo punto esso, se la tavola è perfettamente ferma e piana, è soggetto alla sola forza di gravità, che va dall’alto verso il basso. Questa forza è un’accelerazione costante, di 9,81m/s verso il basso, il che equivale ad 1G: il dispositivo a riposo quindi, indicherà +1G lungo l’asse che punta verso il centro della Terra. Se indica +1G sull’asse Z, significa che è steso, mentre se indica +1G sull’asse X o sull’asse Y, vuol dire che è stato appoggiato sul tavolo su uno o l’altro lato. Chiaramente vanno calcolati anche i punti intermedi: ad esempio, se tenessi fermo il dispositivo su di uno spigolo ma perfettamente verticale, questo indicherebbe 0,70G su un asse e 0,70G sull’altro! (si, non va dimezzato ma calcolato con il seno o coseno del vettore) Se invece lo mantenessi sullo spigolo inclinandolo anche in profondità, parte dell’accelerazione sarebbe letta anche dall’asse Z (caso non illustrato in figura).

zero-gravity-flight

Tralasciando l’inclinazione, se tenendo ben stretto il dispositivo lo spostate velocemente verso il basso, assecondando la forza di gravità, per un breve periodo probabilmente indicherà 0G. Il dispositivo non rileva più l’accelerazione dovuta alla forza di gravità perché la state assecondando, quindi si trova effettivamente in assenza di peso, un pò come i voli a gravità zero organizzati dalla Nasa, dove un aereo viene appositamente pilotato in picchiata per ottenere il medesimo effetto.

Ma come fa un dispositivo miniaturizzzato di questo tipo a rilevare le accelerazioni sui vari assi? Un ingrandimento di un estratto dal documento tecnico può chiarirci le idee:

chip accelerometer details

In poche parole il microchip al suo interno dispone di microscopiche lamelle in grado di flettere quando il dispositivo viene sottoposto ad un’accelerazione, anche quella di gravità: immaginatele “pendere verso il basso”. Muovendosi, si allontanano o si avvicinando alla loro superficie di riferimento, variando così la capacità elettrica tra le due superfici, esattamente come avviene in un normale condensatore variabile meccanico. Replicando lo stesso meccanismo per tutti e 3 gli assi che descrivono lo spazio tridimensionale, possiamo ottenere tutte le informazioni che ci servono per ricavare la direzione e l’intensità del vettore della forza che sta agendo sul dispositivo.

12756-00

Prendiamo ad esempio questa “breakout board” con il piccolissimo accelerometro smd montato a bordo. I pin di uscita, comodamente distribuiti con passo 2.54, sono abbastanza chiari: GND, +3.3V, SCL e SDA per l’interfaccia I2C. Una volta collegati i rispettivi pin alla vostra board di controllo, ed appositamente settata l’interfaccia I2C a seconda del vostro editor, possiamo iniziare a comunicare con il dispositivo!

Prima di tutto, nel mio caso usando CodeWarrior e Processor Expert, ho settato la comunicazione I2C:

Immagine

Notare che ho settato la frequenza di SCL sotto i 100khz, nonostante sia possibile salire fino a 400khz, per non aver problemi di sorta.

Successivamente ho creato due semplici funzioni per inviare e ricevere byte al dispositivo (l’indirizzo standard è 0x77) utilizzando la funzione interrupt del driver I2C, il quale resetta un flag terminata la rispettiva operazione di invio o ricezione dati:

// due interrupt utilizzati per confermare
// quando è possibile terminare la comunicazione
void I2C2_OnReceiveData(void)
{
	DataReceivedFlg = TRUE; /* Set DataReceivedFlg flag */
}

void I2C2_OnTransmitData(void)
{
	 DataTransmittedFlg = TRUE; /* Set DataTransmittedFlg flag */
}


// leggo uno o più registri da device
void I2C_ReadReg(char regaddr, char *data, short dataSize) {
  char res;
  word ret;
 
  // setto il puntatore al registro desiderato
  res = I2C2_SendBlock(&regaddr, 1U, &ret);
  
  // attendo fino al termine della trasmissione dati
  while (!DataTransmittedFlg) {} /* Wait until data is sent */
  DataTransmittedFlg = FALSE;
 
  // leggo il numero di byte richiesti
  res = I2C2_RecvBlock(data, dataSize, &ret);
  
  // attendo fino al termine della trasmissione
  while (!DataReceivedFlg) {} /* Wait until data is received received */
  DataReceivedFlg = FALSE;
  
  // termino la comunicazione  
  I2C2_SendStop();
}

// scrivo un byte in un registro
void I2C_WriteReg(char regaddr, char val) {
  char buf[2], res;
  word ret;

  buf[0] = regaddr; // indirizzo del registro da scrivere
  buf[1] = val;     // valore da scrivere nel registro
  res = I2C2_SendBlock(&buf, 2U, &ret); // trasmetto i due byte
  
  // attendo il termine della trasmissione
  while (!DataTransmittedFlg) {} 
  DataTransmittedFlg = FALSE;
  
  // chiudo la comunicazione
  I2C2_SendStop(); 
}

Ora che abbiamo semplificato il tutto creando due funzioni per comunicare con il dispositivo, possiamo inizializzarlo e per far ciò ho analizzato il datasheet ricavando quanto segue:

// setto ad 1 il bit di reset
I2C_WriteReg(0x2B, 0x40); 

// attendo finché il reset non è completato
while (reg_data & 0x40) 
{
	I2C_ReadReg(0x2B, &reg_data, 1);
}

// disablito fast-mode per ottenere risultato a 14bit
I2C_WriteReg(0x2A, 0x02);
// setto il range a 4g
I2C_WriteReg(0x0E, 0x02;
// alta risoluzione
I2C_WriteReg(0x2B, 0x02);
// attiva l'accelerometro (riquadro giallo nella tabella registri)
I2C_WriteReg(0x2A, 0x01);

Il dispositivo è stato inizializzato con il range +-4G, quindi, sempre da datasheet verifico che devo dividere il valore grezzo (RAW) letto per 2048:

accelerometer range

// definisco alcune variabili
#include "math.h" //necessario per la funzione abs()  
float g_x, g_y, g_z, g_dir;

//leggo i 6 byte con le informazioni per i 3 assi
I2C_ReadReg(0x01, &xyz, 6);

// unisco gli 8bit del primo carattere
// con i successivi 6bit del secondo carattere
g_x= (((xyz[0]<<8) | xyz[1])>>2)/2048;
g_y= (((xyz[2]<<8) | xyz[3])>>2)/2048;
g_z= (((xyz[4]<<8) | xyz[5])>>2)/2048;

// con questa serie di condizioni stimo
// un possibile orientamento del dispositivo
if ((abs(g_z) < 5) && (g_x > 5) && (abs(g_y) < 4)) { g_dir = 1; } 
if ((abs(g_z) < 5) && (g_x < -5) && (abs(g_y) < 4)) { g_dir = 2; }
if ((abs(g_z) < 5) && (g_y > 5) && (abs(g_x) < 4)) { g_dir = 3; } 
if ((abs(g_z) < 5) && (g_y < -5) && (abs(g_x) < 4)) { g_dir = 4; }

A questo punto in g_x, g_y, g_z trovo il valore numerico float dell’accelerazione per asse in G, esempio “1.0”. Mentre in g_dir trovo la rotazione dell’orientamento consigliata per un eventuale schermo, i cui quattro valori corrispondono a 0, 90, 180, 270 gradi. Questa ultima serie di condizioni l’ho estratta da un documento tecnico.

working glc riccardo maestri

Partendo dalla necessità di sviluppare uno strumentino da pannello per visualizzare grafici e valori numerici con caratteri di varie dimensioni, ho rinunciato al classico LCD con standard HD44780 per utiizzare invece un pannello “grafico” ovvero con la possibilità di settare un pixel alla volta. Se vi interessa l’argomento vi consiglio davvero di comprenderne a fondo la logica di funzionamento, così potrete creare liberamente effetti grafici performanti adattandoli alle vostre esigenze.

Scegliendo che prodotto acquistare, vanno considerate diverse cose:

  • Il tipo di connettore
  • Il tipo di controller
  • La dimensione in pixel
  • Il colore della retroilluminazione
  • La tensione di contrasto dell’LCD

Riassumendo brevemente questi parametri, ho scelto un prodotto che avesse dei fori sullo stampato a passo standard 2.54mm, così da poter agevolmente saldare dei cavetti/connettori e rendere il tutto flessibile come primo prototipo.

Come controller ho scelto il KS0108, perché cercando online ho trovato molta documentazione ed informazioni sul suo funzionamento nel dettaglio.

Per la dimensione in pixel la mia scelta è ricaduta nel 128×64, il quale internamente è suddiviso in due controller separati ma con le stesse connessioni: inviando l’informazione al primo controller potete lavorare sul riquadro 64×64 pixel in alto, mentre con il secondo controller lavorate sul 64x64px in basso. avessi acquistato un 192×64 pixel avrei trovato tre controller separati. In realtà la gestione è più semplice di quello che pensate, lo vedrete più sotto.

Io non utilizzerò la retroilluminazione perché devo mantenere i consumi bassissimi, ma verificando nel datasheet ad esempio la retroilluminazione bianca consuma molto meno rispetto ad altri colori (tuttavia la vita in ore sembra minore!): da tenere in considerazione.

Come ultimo punto, parlando della tensione di regolazione del contrasto, alcuni LCD richiedono una tensione negativa: diventa una grossa noia perché non è facile ottenere una tensione negativa con una scheda prototipo se non avete i componenti necessari a disposizione, inotre non mi sembrava il caso impegnare un alimentatore da banco solo per ottenere la tensione negativa in questione. Il modello che ho scelto, nonostante abbia questa peculiarità, è provviso di un convertitore DC/DC interno in grado di fornire le tensione negativa necessaria: è sufficiente collegarlo con un trimmer al pin del contrasto ed il gioco è fatto… In realtà ho avuto qualche noia con il contrasto perché ho scoperto -dopo una minuziosa e noiosissima ricerca- che il pin di reset non va collegato a VCC direttamente: va invece utilizzata una resistenza di pull-up da almeno 10kohm per limitare la corrente.

Avendo a disposizione diverse FRDM_KL25Z, che utilizzo come programmatori per micro ARM, ho deciso di sfruttarne una per pilotare il display grafico in questione. Come spiegato in questo articolo KL25Z come programmatore OpenSDA ho prima di tutto preparato la board in modo tale da poterla programmare agevolmente via USB (con il jumper J6 inserito per collegare il clock SDA con il clock del micro della scheda!).

Prima di connettere l’LCD alla board ho verificato nel dettaglio di che connessioni si tratta e come potete notare sono tutti pilotabili con I/O digitali, quindi molto semplice:

  • CS1, CS2: abilitano il controller 1 oppure il controller 2, cioè le due metà dello schermo utilizzabili;
  • DB0-DB7: vanno abililtati per descrivere il byte di dati in uscita verso l’LCD;
  • EN: pin di Enable, il quale avvisa il controller in uso di considerare valido il byte descritto sui pin DB0-DB7;
  • RW/DI: indicano al controller che tipo di operazione voglio effettuare (lettura, scrittura, comando);
  • RST: pin di reset del micro, deve restare a livello alto per mantenere i controller attivi;
  • Vee: contrasto dell’LCD, va collegato con apposito trimmer, vedesi schema più sotto.

Poi ho connesso l’LCD alla board controllando lo schematico della stessa in quanto alcuni pin del micro potrebbero essere open drain/collector (in quel caso per ottenere un livello logico alto è necessario per forza aggiungere un pull-up) oppure come nel caso del pin “PTD1” essere in comune con il LED RGB montato sulla scheda… Direi da evitare se possibile.

Graphical LCD pin diagram

In questo schema potete vedere tutte le connessioni necessarie, ma tenete ben presente la resistenza di pull-up sul pin RST. Mi raccomando: prima di alimentare il tutto assicuratevi di non superare la tensione indicata dal datasheet e di aver collegato correttamente i pin, altrimenti rischiate di compromettere irrimediabilmente i controller! A questo punto non mi resta che buttar giù un pò di codice! Senza entrare nel dettaglio specifico di Codewarrior con compilatore gcc-arm, vi spiego piuttosto come comunicare correttamente con il controller KS0108 così sarete in grado di utilizzarlo indipendentemente dal linguaggio,compilatore o micro utilizzato.

Visto che prima di tutto i controller vanno inizializzati, e per farlo dobbiamo dobbiamo inviare loro dei comandi, prepariamoci prima di tutto il codice necessario per inviare un byte all’LCD.

Nel mio caso, utilizzando CodeWarrior, setto i pin in ProcessorExpert indirizzandoli come indicato nello schema più sopra, e preparo due funzioni per impostarli come uscite e gestire i livelli logici come necessario.

// questa funzione setta tutti i pin I/O relativi ai bit D0-D7 come uscite
void DATA_DIR_OUT() {
	LCD_D0_SetOutput();
	LCD_D1_SetOutput();
	LCD_D2_SetOutput();
	LCD_D3_SetOutput();
	LCD_D4_SetOutput();
	LCD_D5_SetOutput();
	LCD_D6_SetOutput();
	LCD_D7_SetOutput();
}

// questa funzione suddivide il byte da trasmettere in singoli bit
// e setta a livello alto o basso i pin corrispondenti DB0-DB7
void WR_DATA(char lcddata) {
	
	LCD_D0_PutVal((lcddata) >> 1);
	LCD_D1_PutVal((lcddata >> 1) & 1);
	LCD_D2_PutVal((lcddata >> 2) & 1);
	LCD_D3_PutVal((lcddata >> 3) & 1);
	LCD_D4_PutVal((lcddata >> 4) & 1);
	LCD_D5_PutVal((lcddata >> 5) & 1);
	LCD_D6_PutVal((lcddata >> 6) & 1);
	LCD_D7_PutVal((lcddata >> 7) & 1);
}

// manda un semplice impulso sul pin EN
void send_enable() {
	LCD_EN_SetVal();
	Delay100us(1); // delay di 1 microsecondo
	LCD_EN_ClrVal();
}

// seleziona il controller
//    0               1
// CS1 = 1         CS1 = 0
// CS2 = 0         CS2 = 0
void ChipSelect(bool chip)
{   
      if (chip == 0)
      {
            LCD_CS2_ClrVal();
            LCD_CS1_SetVal();
      }
      if (chip == 1)
      {
            LCD_CS1_ClrVal();
            LCD_CS2_SetVal();
      }
}

glcd output bits
Il risultato è di trasmettere il byte bit per bit distribuendolo sui pin DB7-DB0. Questa viene chiamata normalmente trasmissione parallela. Oltre a trasmettere il bit però è anche necessario indicare al controller quali sono le mie intenzioni. Sfogliando il datasheet dell’GLCD ho trovato tutte le informazioni necessarie al driving dei controller.
control bits e data bits
Ho tolto da questo schema tutte le altre funzioni per concentrarci sulla funzione più importante, quella per attivare il pannello “Display on/off” e sulla funzione per scrivere un byte “Write data”. Inoltre ho suddiviso per colore i bit di controllo dai bit dati, rispettando i colori dello schema elettrico. Manca il pin di Enable, “EN” perché quest’ultimo è molto semplice: prima si preparano i bit di controllo ed il bit dati, poi si da un piccolo impulso con il bit EN per dire all’LCD “ok sono pronto, ascoltami”.

Ricapitolando, per attivare il display devo settare RW a 0, DI a 0, ed inviare il BYTE “3F” seguito da un impulso di ENABLE:

void InitDisplay(void)
{
	DATA_DIR_OUT();
	LCD_DI_ClrVal();
	LCD_RW_ClrVal();
	WR_DATA(0x3F);
        ChipSelect(0);
}

Se ora volessimo accendere un pixel sullo schermo, sarebbe sufficiente mandare un byte di dati. Ma un attimo… un byte? E se io volessi accendere un solo bit? Giusto, ma di questo ne parleremo dopo. La domanda ora è: dove comparirebbe questo pixel? Non abbiamo creato nessuna funzione per il posizionamento del “cursore” di scrittura. Torniamo quindi al datasheet ed aggiungiamo qualche dettaglio alla tabella delle funzioni:

ks0108 goto xy istructions

Quindi abbiamo un comando chiamato set page che corrisponde all’asse X, ed un comando set address che corrisponde all’asse Y. Entrambi sembrano lavorare con RW e DI a zero, però mentre set address va da 0 a 63, set page va solo da 0 a 7 (zero compreso, quindi solo 8 posizioni): questo perché sull’asse X scriviamo 8 bit alla volta, ovvero il nostro byte! Ovvio che quindi non serviranno 64 posizioni, bensì 64/8, ovvero 8.

Allora preparariamo le nostre funzioni di posizionamento e di scrittura di un byte:

// selezione della pagina (asse X diviso in 8 byte)
void PageSelect(unsigned char page)
{
        // setto RW e DI come da tabella
	LCD_RW_ClrVal();
	LCD_DI_ClrVal();
        // unisco (B8) ovvero 10111 come da tabella
        // con i 3 bit del numero di pagina e li invio all'LCD
	WR_DATA(0xB8 | page);
	send_enable();
}

// selezione della riga (asse y diviso in 64 punti)
void RowSelect(unsigned char row)
{
        // setto RW e DI come da tabella
	LCD_RW_ClrVal();
	LCD_DI_ClrVal();
	WR_DATA(0x40 | row);
	send_enable();
}

// questa funzione invia un byte al controller attualmente attivo
void WriteByte(char chardata)
{
DATA_DIR_OUT(); // setto pin DB0-DB7 come uscite
LCD_RW_ClrVal(); // RW a livello logico 0
LCD_DI_SetVal(); // DI a livello logico 1
Delay100us(1); // attendo 1uS per la ricezione del comando
WR_DATA(chardata); // setto bit per bit le uscite
send_enable();
}

Fatto questo non ci resta che provare a mandare un primo byte allo schermo, nella posizione 0,0px, modificando il main in questo modo:

InitDisplay(void);  // inizializzo display
ChipSelect(0);      // selezioni chip 0
PageSelect(0);      // x = 0
RowSelect(0);       // y = 0
WriteByte(0xFF);    // accendo 8 pixel di fila
while(1);           // ciclo infinito di attesa

Se avete fatto tutto correttamente, vi apparirà una linea di 8px. Cambiando 0xFF con ad esempio 0x01 si accenderà un solo pixel, mentre 0xAA alterna pixel acceso con pixel spento. Potete anche provare a cambiare i valori di PageSelect e RowSelect, per vedere che effetto fa sul posizionamento dei pixel.

glcd byte sent

Da questo iniziale risultato è possibile partire per sviluppare tutte le funzioni grafiche come la scrittura di caratteri oppure la visualizzazione di immagini bitmap, ma di questo ne parlerò in un secondo articolo!

20160428_144620

Trasformare la freedom board KL25z in una USBDM Debugger interface permette di ottenere un programmatore per varie MCU Freescale o altri dispositivi compatibili (vedi qui)

  • RS08
  • HCS08,
  • HC12,
  • Coldfire V1-4 microcontrollers
  • MC56F800xx Digital Signal Controllers (very limited range of devices).
  • Kinetis ARM-cortex

E’ necessario prima di tutto preparare l’hardware come mostrato nel precedente articolo riguardante la KL25Z come programmatore OpenSDA (vedi qui). Preparata la board con le modifiche necessarie, non installate OpenSda, ma seguite i seguenti passi:

Scaricate i driver USBDM al seguente link:

opensda

Quando avete installato i drivers, scaricate a questo link (verificate sia l’ultima versione) il software relativo ad USBDM:

download programs

Avviate il setup e durante la procedura assicuratevi di abilitare l’installazione dei componenti relativi al vostro ambiente di sviluppo (nel mio caso Codewarrior 10.6.4) e anche del programmatore Stand-alone, che preferisco come semplicità, o come piano B in caso l’ambiente di sviluppo non riesca ad integrare i plugin necessari:

setup

Completato il setup non vi resta che preparare la vostra FRDM-KL25Z per aggiornarla all’applicazione USBDM Debug. Sfogliate la cartella di default per l’installazione del software sul vostro pc, troverete “PGO” ed al suo interno la cartella creata dall’ultimo setup USBDM. All’interno di quest’ultima entrate nella cartella “FlashImages” e quindi “MKxx”, riferito alla famiglia del micro nella board. Sul mio pc il percorso completo è “C:\Program Files (x86)\pgo\USBDM 4.12.1.70\FlashImages\MKxx”.

All’interno di questa cartella troveremo il file “OpenSDAvX.X.bin” dove la X sta ad indicare la versione disponibile al momento. Tenete questo file a portata di mano!

usbdm flash application

E’ giunto il momento di collegare la board al computer con un cavetto usb, tenendo premuto il tasto di reset un secondo o due, questa si avvierà in modalità bootloader e vi comparirà come periferica di archiviazione di massa usb (Bootloader). Se avete internet attivo, aprendo il file “sda_info.htm” potete verificare le versioni di bootloader e app attualmente caricate nella flash. Noi comunque andremo ad aggiornare tutto quanto, per trasformare la board in un programmatore “semi-universale” via SWD.

20160426_152446

Infatti, non vi resta che caricare il file “OpenSDAvX.X.bin” nella periferica di archiviazione di massa, attendere qualche secondo, poi sconnettere e riconnettere il dispositivo. A questo punto, come conferma di avvenuto aggiornamento del firmware, windows vi avviserà che “è stato rilevato un nuovo hardware”: saranno caricati automaticamente i drivers relativi ad USBDM, ed il dispositivo verrà riconosciuto come programmatore da Codewarrior e dal programmatore stand-alone sviluppato per USBDM.

Fate attenzione: con Windows 7  e Windows 10 per motivi ancora ignoti non sono riuscito ad aggiornare il firmware della board come da ultimo passaggio, però avevo a disposizione un computer con Windows XP ed in quel caso ha funzionato immediatamente. Questo passaggio va fatto solo una volta quindi ad oggi non ho approfondito ulteriorimente il problema.

Per verificare se funziona tutto, potete collegare il connettore SWD alla board che volete programmare ed avviare il programmatore stand-alone (nel mio pc è in “C:\Program Files (x86)\pgo\USBDM 4.12.1.70\UsbdmFlashProgrammer.exe”):

stand alone usbdm flash programmer test

Prima di tutto, dalla scheda “Interface” tramite il tasto “Detect” ho verificato il corretto riconoscimento della board KL25Z rilevata come programmatore SWD. Successivamente, nella scheda “Target” (immagine più a destra) tramite il tasto “Detect Chip” eseguo una veloce verifica del dispositivo che ho connesso via SWD. Riconosce correttamente il mio micro ed il suo ID!

Tuttavia, inizialmente non fu così semplice, in quanto il micro “MKV10” non veniva riconosciuto, essendo presente nella lista ma non completamente configurato. Ho tentato di configurarlo manualmente inserendo tutti i parametri come da datasheet, ma senza successo. Ho deciso così di contattare direttamente lo sviluppatore di USBDM Peter O’Donoghue, il quale stava casualmente affrontando lo stesso problema: così in meno di 24h ne siamo venuti a capo ed ora funziona perfettamente! Sicuramente, con micro meno recenti o con più fortuna non avrete lo stesso mio inconveniente.

Alla prossima!

Trovate altri riferimenti a questo link:
https://mcuoneclipse.com/2013/04/27/debug-external-processors-with-usbdm-and-freedom-board/

frdm-kl25z

20160426_155241Dovendo sviluppare un progetto con i micro Freescale della serie Kinetis, ho cercato nella rete quali fossero i programmatori più adatti utilizzando il protocollo SWD (Serial Wire Debug). I costosi programmatori della P&E Micro non mi hanno ingolosito particolarmente, così ho preferito la classica soluzione per smanettoni: ho scoperto infatti che è possibile trasformare la FRDM-KL25Z (una piattaforma demo che costa meno di 20€!) in un veloce ed economico programmatore con OpenSDA.

Io l’ho ordinata da rs-components (vedi a questo link) che spedisce in 24h, così il giorno dopo ho potuto lavorarci immediatamente. Osservando lo schema elettrico, è necessario tagliare la pista che mantiene in corto il jumper J11, in modo da separare il clock del micro a bordo della scheda dal clock della cpu che intendete programmare tramite la connessione SWD:

cut

Io l’ho fatto in modo un pò barbaro ma veloce, inserendo tuttavia un jumper in modo da poter ripristinare la connessione in caso volessi programmare nuovamente il micro a bordo della scheda.

20160426_152316

Preparatevi alcuni file: è necessario scaricare dal sito P&E Micro (clicca qui) i drivers per OpenSDA ed il firmware per aggiornare la vostra KL25Z. Installate prima di tutto i drivers P&E Micro se non sono già presenti sul vostro computer, poi estraete dallo zip “firmware apps” il firmware MSD-DEBUG relativo alla KL25z e tenetelo a portata di mano!

download

E’ giunto il momento di collegare la board al computer con un cavetto usb, tenendo premuto il tasto di reset un secondo o due, questa si avvierà in modalità bootloader e vi comparirà come periferica di archiviazione di massa usb (Bootloader). Se avete internet attivo, aprendo il file “sda_info.htm” potete verificare le versioni di bootloader e app attualmente caricate nella flash. Noi comunque andremo ad aggiornare tutto quanto, per trasformare la board in un programmatore.

20160426_152446

Quindi non vi resta che caricare il file “MSD-DEBUG-FRDM-KL25Z_Pemicro_v***.SDA” nella periferica di archiviazione di massa, attendere qualche secondo, poi sconnettere e riconnettere il dispositivo. A questo punto, come conferma di avvenuto aggiornamento del firmware, windows vi avviserà che “è stato rilevato un nuovo hardware”: saranno caricati automaticamente i drivers relativi all’OpenSDA, ed il dispositivo verrà riconosciuto come programmatore da Codewarrior.

Fate attenzione: con Windows 7  e Windows 10 per motivi ancora ignoti non sono riuscito ad aggiornare il firmware della board come da ultimo passaggio, però avevo a disposizione un computer con Windows XP ed in quel caso ha funzionato immediatamente. Questo passaggio va fatto solo una volta quindi ad oggi non ho approfondito ulteriorimente il problema.

Il connettore SWD, che come mio solito ho utilizzato in modo piuttosto “barbaro” è il J6.

programming connector

 

error-17926

L’unica pecca di questa soluzione è il firmware OpenSDA, il quale verifica il target della CPU e se tentate di programmare un micro diverso dal 25Z Codewarrior vi restituirà un antipatico messaggio di errore. Tuttavia, avendo la necessità di programmare un micro di famiglia diversa, ho trovato comunque una soluzione, anche se mi ci è voluto più tempo! La inserirò a breve nel prossimo aggiornamento!