Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

AVR 8 bit: unsigned integer e FPU SW emulation

Raccolta di codici sorgenti

Moderatore: Foto UtentePaolino

0
voti

[41] Re: AVR 8 bit: unsigned integer e FPU SW emulation

Messaggioda Foto UtenteGioArca67 » 1 dic 2021, 20:57

GioArca67 ha scritto:ma lo SHL non mi compilava ...

MI sa che ora ho capito perché, senza LL mi limitava a 31 gli spostamenti...
Avatar utente
Foto UtenteGioArca67
3.576 4 5 9
Master
Master
 
Messaggi: 3428
Iscritto il: 12 mar 2021, 9:36

0
voti

[42] Re: AVR 8 bit: unsigned integer e FPU SW emulation

Messaggioda Foto Utentegvee » 2 dic 2021, 17:26

Dunque, ho fatto la prova con l' AVR8, il tutto con avr-gcc e avr-libc.

Codice: Seleziona tutto
avr-gcc -v
Using built-in specs.
Reading specs from /usr/lib/gcc/avr/5.4.0/device-specs/specs-avr2
COLLECT_GCC=/usr/bin/avr-gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/avr/5.4.0/lto-wrapper
Target: avr
Configured with: ../gcc/configure -v --enable-languages=c,c++ --prefix=/usr/lib --infodir=/usr/share/info --mandir=/usr/share/man --bindir=/usr/bin --libexecdir=/usr/lib --libdir=/usr/lib --enable-shared --with-system-zlib --enable-long-long --enable-nls --without-included-gettext --disable-libssp --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=avr CFLAGS='-g -O2 -fdebug-prefix-map=/build/gcc-avr-5.4.0+Atmel3.6.1=. -fstack-protector-strong -Wformat ' CPPFLAGS='-Wdate-time -D_FORTIFY_SOURCE=2' CXXFLAGS='-g -O2 -fdebug-prefix-map=/build/gcc-avr-5.4.0+Atmel3.6.1=. -fstack-protector-strong -Wformat ' FCFLAGS='-g -O2 -fdebug-prefix-map=/build/gcc-avr-5.4.0+Atmel3.6.1=. -fstack-protector-strong' FFLAGS='-g -O2 -fdebug-prefix-map=/build/gcc-avr-5.4.0+Atmel3.6.1=. -fstack-protector-strong' GCJFLAGS='-g -O2 -fdebug-prefix-map=/build/gcc-avr-5.4.0+Atmel3.6.1=. -fstack-protector-strong' LDFLAGS=-Wl,-z,relro OBJCFLAGS='-g -O2 -fdebug-prefix-map=/build/gcc-avr-5.4.0+Atmel3.6.1=. -fstack-protector-strong -Wformat ' OBJCXXFLAGS='-g -O2 -fdebug-prefix-map=/build/gcc-avr-5.4.0+Atmel3.6.1=. -fstack-protector-strong -Wformat '
Thread model: single
gcc version 5.4.0 (GCC)


che è poi la versione del repo di Debian 10.

1) Invio all' AVR8 il valore della frequenza in Hz (senza parte decimale) alla UART (quindi per 10 MHz da putty/screen invio 10000000).
2) L'AVR8 riceve, calcola il valore numerico da array char a floar, moltiplica per il coefficiente (float)

M = \left . \frac{2^{32}} {f_\text{clk}} \right |_{f_\text{clk} = 180}

e successivamente invia come risposta il valore della FTW in hesadecimale (array di caratteri).

I risultati coincidono con un programmino di test in C su Linux locale applicando la conversione a float, quindi per il momento sono abbastanza soddisfatto anche perché non riscontro un ritardo "tartaruga" nel ricevere il risultato.. Però con precisione doppia (double) sarebbe meglio.

In questa versione di avr-gcc, la dimensione di float e double è la stessa quindi il risultato non cambia nell'usare uno o l'altro.

Cercerò di compilare manualmente avr-gcc v10 per fare le prove con il double.
Appena riesco faccio un update.

O_/
Avatar utente
Foto Utentegvee
1.060 2 7
Stabilizzato
Stabilizzato
 
Messaggi: 381
Iscritto il: 11 feb 2018, 20:34

0
voti

[43] Re: AVR 8 bit: unsigned integer e FPU SW emulation

Messaggioda Foto UtenteGioArca67 » 2 dic 2021, 17:47

Ottimo.
In che tipo di dato immagazzini quanto ricevi dalla seriale?
Hai provato a reinviarlo indietro per vedere casa esattamente viene "capito" dall'AVR8?
Se invii una frequenza con scostamento di pochi Hz la tuning Word cambia?

Ma se invii in Hz (10000000) perché dividi per 180 e non per 180000000?
Avatar utente
Foto UtenteGioArca67
3.576 4 5 9
Master
Master
 
Messaggi: 3428
Iscritto il: 12 mar 2021, 9:36

0
voti

[44] Re: AVR 8 bit: unsigned integer e FPU SW emulation

Messaggioda Foto Utentegvee » 2 dic 2021, 18:12

GioArca67 ha scritto:In che tipo di dato immagazzini quanto ricevi dalla seriale?

Metto tutto dentro un array di caratteri di 8 elementi: ad ogni carattere ricevuto salvo nell'indice a proposito e poi applico la conversione.

GioArca67 ha scritto:Hai provato a reinviarlo indietro per vedere casa esattamente viene "capito" dall'AVR8?

Sì. :ok:

GioArca67 ha scritto:Se invii una frequenza con scostamento di pochi Hz la tuning Word cambia?

Sì, con 1 Hz di differenza :ok:

GioArca67 ha scritto:Ma se invii in Hz (10000000) perché dividi per 180 e non per 180000000?

Perché nel calcolo di M la frequenza è in MHz. OK potrei fare altrimenti, però per il momento è una prova di inizio..
Avatar utente
Foto Utentegvee
1.060 2 7
Stabilizzato
Stabilizzato
 
Messaggi: 381
Iscritto il: 11 feb 2018, 20:34

0
voti

[45] Re: AVR 8 bit: unsigned integer e FPU SW emulation

Messaggioda Foto UtenteGuidoB » 3 dic 2021, 3:34

Basandomi su quanto accennato alla fine dell'intervento 21, ho provato a calcolare \Delta_\phi spezzando gli uint32_t in due parti da 16 bit, in modo che moltiplicandole non ci sia overflow su 32 bit.

L'algoritmo in C è questo. L'ho buttato giù di fretta, se serve lo spiego più in dettaglio.

La precisione di calcolo è di 64 bit (19 cifre decimali significative contro i double a 64 bit che ne hanno 15), anche se poi il risultato viene restituito su 32 bit.
È utile se non si hanno a disposizione né i double a 64 bit né gli uint64_t.

Codice: Seleziona tutto
// M0 = 2^32/(180*10^6) = 23.8609294222222222....
// M  = M0 * 2^27 = 3202559735.019.. = 0xBEE3 2EF7 (Still fits into an uint32_t).

#define MH 0xBEE3
#define ML 0x2EF7

// function deltaPhi works for frequencies up to 134 MHz
uint32_t deltaPhi(uint32_t frequencyHz)
{
  uint32_t res, tmp, carry, f, fh, fl;
 
  f   =  frequencyHz << 5 // Still fits into an uint32_t.
  // We multiplied factor M0 by 2^27 and frequencyHz by 2^5. Overall, we multiplied by 2^32.
 
  fh  =  f >> 16;
  fl  =  f & 0xFFFF;
 
  res =  fl * MH + ((fl * ML) >> 16); // There cannot be carry in this sum; check by substituting the factors with their maximum values (0xFFFF)
  tmp =  res;
  res += fh * ML; // No carry in this sum since 0xBEE3 + 0x2EF7 <= 0x10001, but I left the carry code in case the M constant is changed.
 
  if (res < tmp)
  {
    // Carry above 32 bits in the sum
    carry = 1 << 16;
  }
  else
  {
    // No carry
    carry = 0;
  }
 
  res = fh * MH + carry + ((res + (1 << 15)) >> 16); // 1 << 15 is added to round to the nearest integer.
 
  return res;
}
Big fan of ƎlectroYou!       Ausili per disabili e anziani su ƎlectroYou
Caratteri utili: À È É Ì Ò Ó Ù α β γ δ ε η θ λ μ π ρ σ τ φ ω Ω º ª ² ³ √ ∛ ∜ ₀ ₁ ₂ ₃ ₄ ₅ ₆ ∃ ∄ ∆ ∈ ∉ ± ∓ ∾ ≃ ≈ ≠ ≤ ≥
Avatar utente
Foto UtenteGuidoB
17,3k 7 12 13
G.Master EY
G.Master EY
 
Messaggi: 2660
Iscritto il: 3 mar 2011, 16:48
Località: Madrid

0
voti

[46] Re: AVR 8 bit: unsigned integer e FPU SW emulation

Messaggioda Foto UtenteGioArca67 » 3 dic 2021, 8:10

Avevo pensato alla stessa cosa.
Stavo elaborando anche altro.
.
La formula è f/180*2^32
Ora 180=3( ?% )*3( ?% ) * 2 ( :D shift) * 10 ( posizione della virgola)
E *2^32 è uno shift
Quindi serve essenzialmente dividere per 9 (o per 3) mantenendo la dovuta precisione.

Poi l'OP ha detto di essere sulla strada, quindi ho messo da parte.
Avatar utente
Foto UtenteGioArca67
3.576 4 5 9
Master
Master
 
Messaggi: 3428
Iscritto il: 12 mar 2021, 9:36

0
voti

[47] Re: AVR 8 bit: unsigned integer e FPU SW emulation

Messaggioda Foto Utentegvee » 3 dic 2021, 16:17

Provato con gcc 11.2 a precisione doppia compilato manualmente, specificando la precisione nelle opzioni di compilazione:

Codice: Seleziona tutto
--with-double=64 --with-long-double=64


Il codice di test è lo stesso codice di ieri pero con double (ma non mi dire :mrgreen:).

Funziona perfettamente ! :-)

Ecco i valori calcolati delle FTW per 10 MHz, 10.00000004 MHz e 10.00000008 MHz, 50 MHz, 32.768 kHz, 0.42 Hz, 0.08 Hz:
Codice: Seleziona tutto
10000000.000 => 0x0e38e38e
10000000.040 => 0x0e38e38f
10000000.080 => 0x0e38e390
50000000.000 => 0x471c71c7
00032768.000 => 0x000bee33
00000000.042 => 0x00000001
00000000.080 => 0x00000002


I cui valori di frequenza secondo le FTW calcolate da AVR8 sono rispettivamente (calcolati on Octave), in Hz:
Codice: Seleziona tutto
    9999999.990687
   10000000.032596
   10000000.074506
   49999999.995343
      32768.002711
          0.041910
          0.083819


:-)
Avatar utente
Foto Utentegvee
1.060 2 7
Stabilizzato
Stabilizzato
 
Messaggi: 381
Iscritto il: 11 feb 2018, 20:34

0
voti

[48] Re: AVR 8 bit: unsigned integer e FPU SW emulation

Messaggioda Foto Utentexyz » 3 dic 2021, 17:46

gvee ha scritto:
Codice: Seleziona tutto
--with-double=64 --with-long-double=64


La prossima volta che aggiornerò e compilerò i toolchain per gli AVR abiliterò anch'io questa opzione.
Avatar utente
Foto Utentexyz
6.834 2 4 6
G.Master EY
G.Master EY
 
Messaggi: 1760
Iscritto il: 5 dic 2009, 18:37
Località: Italy Turin

Precedente

Torna a Firmware e programmazione

Chi c’è in linea

Visitano il forum: Nessuno e 5 ospiti