Home
Accesso / Registrazione
 di 

Convertitore automatico di baud rate utilizzando ATTiny2313

Convertitore automatico baud rate utilizzando ATTiny2313

Sprite_tm riesce a scoprire il baud rate utilizzando un ATtiny2313 e la scheda FT232. Il firmware assume 8 bits di dati, nessuna parità e 1 bit di stop (8N1). Questo è molto utilizzato tra le porte seriali e quindi dovrebbe funzionare bene, anche se alcuni dispositivi utilizzano diverse configurazioni. Rilasciato sotto GPLv3, il software è fornito in formato esadecimale (codice macchina)

Lo schema della scheda è molto semplice. L'hardware UART dell'ATTiny232 è collegato all'FT232, che fornisce alimentazione all'ATTiny2313. Gli unici componenti restanti sono un condensatore e un cristallo. Non è possibile fa partire l'ATTiny senza dei condensatori sui "crystal pin" ed i 20 MHZ ad un Vcc di 3.3V ma il nostro progettista non ha mai avuto problemi. La CTS-line "dice" al PC di aspettare con l'invio di altri bit fino a che il dispositivo ha inviato i precedenti.

convertitore automatico ATTiny2313

Il software utilizza un timer a 16-bit. Il timer 1 esegue la temporizzazione principale e questo timer a 16 bit viene esteso a 32bits, in modo che il firmware possa rilevare anche baudrates più bassi di 110 baud. La funzionalità "input capture" di questo timer è utilizzata per misurare quanto tempo il segnale ricevuto è basso. Il suo interrupt è utilizzato per avviare la routine UART che riceve un byte quando l'autobauding è riuscito. Il timer viene usato anche per mandare i segnali al dispositivo quando un byte è ricevuto dal PC.

Se vuoi hackerare un'apparecchiatura con microprocessore, la prima cosa che di solito dovresti fare dopo aver distrutto il case ed aver identificato tutti i frammenti è cercare una porta seriale. Nonostante il tipo di apparecchiatura (a base Linux, WinCE, qualche modello di RTOS forse persino senza SO), la maggioranza di essi ha una porta seriale destinata al debugging.

La maggior parte di queste porte presentano anche delle info utili persino con firmware non-debug, così risulta un modo facile e simpatico per imparare di più sul dispositivo. Trovare la porta seriale può essere, tuttavia, un po' problematico. Dopo avere trovato i pin giusti, hai ancora bisogno di sapere su quale "rate" opera il baudrate. Questo di solito significa provare ogni singolo rate sul PC ricevente finché non sei fortunato. Avere un oscilloscopio digitale può semplificare un po’ le cose, ma anche se ne possiedi uno, non è divertente accenderlo e tentare di dedurre il baudrate da una traccia che si riesce a catturare. Come puoi aver dedotto dal resto del mio sito, ho sezionato la mia parte di apparecchiature in passato.

/*
Firmware for an auto-baudrate-detector and -convertor implemented in an
ATTiny2313.
(C) 2009 Jeroen Domburg
*/

#include "io.h"
#include "uart.h"
#include "timer.h"

#include "avr/interrupt.h"
#include "util/delay.h"
#include <stdio.h>

//Sort tickBuff, from smallest to largest.
static void sortList(void) {
	//Plain ole bubble sort, on so little values that shouldn't take too long :)
	char swapped=1;
	long t;
	while (swapped) {
		swapped=0;
		for (char x=0; x<TICKBUFFLEN-1; x++) {
			if (tickBuff[(int)x]>tickBuff[(int)x+1]) {
				t=tickBuff[(int)x+1];
				tickBuff[(int)x+1]=tickBuff[(int)x];
				tickBuff[(int)x]=t;
				swapped=1;
			}
		}
	}
	//Ok, done :)
}

//Calculate 1/baudrate from the contents of tickBuff.
static long calculateDelay(void) {
	unsigned long proposedDelay;
	unsigned long finalDelayAcc=0;
	//Ok, tickBuff is now filled. Sort it first.
	sortList();
	//Sanity check:
	//The largest time measured can be at most 9 bit-times
	//(1 startbit + 8 zero-valued databits). Refuse if this
	//isn't true by a long shot. (take 15x for a good margin)
	if ((tickBuff[0]*15)<tickBuff[TICKBUFFLEN-1]) return -1;
	//Take the smallest value as the initial proposed delay.
	finalDelayAcc=tickBuff[0];
	proposedDelay=tickBuff[0];
	//Now, figure out the delay.
	for (char x=1; x<TICKBUFFLEN; x++) {
		unsigned long rest=tickBuff[(int)x];
		char n=0;
		while (rest>proposedDelay) {
			n++;
			rest-=proposedDelay;
		}
		//Round up -> if tickbuff=proposedDelay*4.6, n=5.
		if (rest>(proposedDelay/2)) n++;
		
		//Ok, we now know how many bit-times the delay was. We can
		//derive a better bit-time estimation from that. Add that estimation
		//to the accumulative estimations.
		finalDelayAcc+=(tickBuff[(int)x]/n);
	
		//Calculate the new proposed delay
		proposedDelay=finalDelayAcc/(x+1);
	}
	//Ok, proposedDelay now is the best estimate of bit-time we have.
	return proposedDelay;
}

int main(void) {
	initIo();
	timerInit();
	sei();
	while (1) { //eternal loop
		
		//Do autobaud.
		tickPos=0; //Reset tickBuff pointer so tickBuff will be filled by ICP int
		//Sleep until we've collected TICKBUFFLEN samples.
		while (tickPos!=TICKBUFFLEN) ;
		//Ok, samples are in. Calculate delay.
		long delay=calculateDelay();
		if (delay!=-1) { //Only if calculation succeeded.
			long baudRate=F_CPU/(unsigned long)delay;
			//Tell user the baudrate.
			serialPutChar('<');
			serialPutInt(baudRate);
			serialPutChar('B');
			serialPutChar('>');
			serialPutChar('\r');
			serialPutChar('\n');
			uartBase=delay;
			
			//Ok, we're synced. Wait till it's probable we're out of sync
			//(much rx errors) and then resync.
			//Until then, just re-send everything we receive.
			do {
				//Reset error & char counter
				swUartRxErrs=0;	swUartRxChars=0;
				//Wait for 8 chars
				while (swUartRxChars<8) {
					if (uartShouldRecv) {
						//We should receive :)
						int b=swUartRecv();
						uartShouldRecv=0;
						swUartRxChars++;
						if (b==-1) {
							//Error in reception :/
							swUartRxErrs++;
						} else {
							//Reception OK :)
							serialPutChar(b);
						}
					}
				}
				//If more than 2 errors in the 8 bytes, resync.
			} while (swUartRxErrs<3);
		}
	}
}

La procedura per la maggior parte di esse includeva la routine descritta sopra per trovare i parametri corretti di porta seriale. Dopo avere fatto ciò per l’ennesima volta , ho deciso di voler automatizzare il processo: se io stesso potessi dedurre il baudrate usando solamente il mio PC o un oscilloscopio, non c'è nessuna ragione per cui un microcontroller non potrebbe fare lo stesso.

Questo progetto e' veramente molto interessante ed utile. La funzionalita' di auto-detect del baud-rate su linea seriale e' generalmente disponibile solo su strumentazione di fascia medio-alta, ma questo progetto consente praticamente a tutti di beneficiare di questa comoda feature.

 

 

Scrivi un commento all'articolo esprimendo la tua opinione sul tema, chiedendo eventuali spiegazioni e/o approfondimenti e contribuendo allo sviluppo dell'argomento proposto. Verranno accettati solo commenti a tema con l'argomento dell'articolo stesso. Commenti NON a tema dovranno essere necessariamente inseriti nel Forum creando un "nuovo argomento di discussione". Per commentare devi accedere al Blog
ritratto di Fabrizio87

Un ottimo progettino, Mario

Un ottimo progettino,

Mario personalmente preferisco il metodo dell'oscilloscopio,
o ancora più semplice con l'analizzatore di Stati logici,
e spesso per conto suo e trova la velocità di trasmissione.

per cosa riguarda provare Le porte debug non è tanto difficile visto che la maggior parte dei costruttori usano JTAG per programmare i loro componenti, si può esportare quella porta per fare ingegneria inversa sul dispositivo semplicemente scaricare su firmware

 

 

Login   
 Twitter Facebook LinkedIn Youtube Google RSS

Chi è online

Ci sono attualmente 8 utenti e 69 visitatori collegati.

Ultimi Commenti