Bit banging IEC EEPROM: scrive bene, ma solo se il primo bit non è impostato


9

Attualmente sto lavorando a un progetto EEPROM I2C usando il bit banging per guidare le linee SDA e SCL.

La mia funzione di lettura funziona bene ma ogni volta che scrivo qualsiasi byte con un "1" iniziale, rileggo sempre FF; anche se il byte è stato programmato con qualcos'altro prima. Il comando "0" è perfetto. Non è la mia routine di lettura; come posso vedere dall'ambito, restituisce FF.

Sto cercando suggerimenti sul perché questo potrebbe essere. C'è qualche ovvio che potrei perdere che potrebbe causare il problema? [Non riesco a pubblicare il codice - società riservata ... :(]

Ogni forma d'onda che guardo soddisfa esattamente le specifiche. Sto disaccoppiando la EEPROM. I miei pull up sono 2.2k quindi all'interno delle specifiche. Sto registrando un clock a circa 500 Hz in questo prototipo. Il chip sta inviando ACK a ciascuno dei miei byte in modo da riconoscerli. Ma non funziona ...

Sto usando un Microchip 24LC256 .

Algoritmo di scrittura semplificato per un byte:

wait
SDA low
SCL low
wait
for each bit
    if bit is set:   SDA high
    if bit is unset: SDA low
    wait
    SCL high
    wait
    wait
    SCL low
    wait
wait
SDA high 
SCL high
wait
wait
check ACK status
SDA low
SCL low
wait
return ACK status

Algoritmo di lettura semplificato per un byte:

wait
SCL low
SDA high
for each bit (8 bits)
    SCL high
    wait
    wait
    SCL low
    wait
    check and store received bit
    wait
do a NACK or ACK depending on if it is the last byte

1
@Justin - Penso che stia dicendo che scrivere il valore 0x7F su qualsiasi indirizzo funziona, ma scrivere 0x80 su qualsiasi indirizzo non funziona.
Rocketmagnet,

1
È roba del genere che mi fa odiare I2C.
Rocketmagnet

1
Ho un'intuizione folle. Nel tuo per ogni codice di bit, stai inavvertitamente estendendo il segno con un'operazione di spostamento a destra? Se sei il tuo leader alla fine ti lascerà con un 0xFF dopo 7 turni.
vicatcu,

3
L'ironia, qui, è il codice "riservato dell'azienda". È prezioso per loro. Tutti gli altri qui condividono il codice che funziona. Ciò che distingue il codice di questa azienda dagli altri è che non funziona.
Gbarry,

2
È difficile immaginare perché un'azienda abbia un disperato bisogno di mantenere confidenziale un po 'di codice I2C. C'è così tanto in giro su Internet.
Rocketmagnet

Risposte:


4

Stai leggendo i dati dopo che l'orologio è di nuovo basso. Dovrai farlo tra alzare l'orologio e abbassarlo. Dopo che l'orologio è basso, lo slave può cambiare la linea di dati, non mentre è alto.

inserisci qui la descrizione dell'immagine

Quindi la lettura dovrebbe essere così:

wait
SCL low
SDA high
for each bit (8 bits)
    SCL high                      <--------
    wait
    check and store received bit  <--------
    wait
    SCL low                       <--------
    wait
    wait
do a NACK or ACK depending on if it is the last byte

È un buon punto; Lo aggiusterò. Tuttavia, i miei dati vengono ancora visualizzati come tutti (FF) sul mio ambito, quindi la mia lettura non può essere il problema ... :(
Thomas O

3

Il problema alla fine si è rivelato che stavo inviando inavvertitamente una condizione di STOP in alcune condizioni a causa della tempistica alterata. Ho rinunciato a usare l'oscilloscopio e ho tirato fuori l'analizzatore logico, e sono stato in grado di risolvere il problema in 15 minuti poiché ha evidenziato lo STOP che non avrebbe dovuto essere lì. Sceglierò a chi dare la grazia in base alla risposta più utile. Grazie per tutte le soluzioni.


Sono contento di averlo risolto "verifica i tempi di scrittura"

3
Ti ho detto che questo sarebbe stato risolto osservando la forma d'onda.
Rocketmagnet

@Rocketmagnet Ho sempre guardato la forma d'onda, ma non l'avevo mai notato prima.
Thomas O

Sì, ma non ha mostrato noi la forma d'onda, nonostante noi ripetutamente chiedendo per essa. Avresti potuto risolvere questo problema giorni fa.
Rocketmagnet

@Rocket - Sono d'accordo. Vorrei avere una fotocamera disponibile al momento. Il Tek DPO che stavo usando aveva un floppy drive ma nessun floppy. Avrei pubblicato una foto se avessi potuto.
Thomas O

2

OK, l'oscilloscopio dimostra che il 1 ° byte proveniente dal PIC è errato, quindi non è la funzione di lettura PIC.

Hai verificato che il tempo di scrittura è OK alla fine della ricezione?

Questo fallisce in entrambe le modalità di seguito?

- Byte mode sequential
- Page mode Sequential

La specifica mostra "Il bit più significativo (MSB)" b7 "viene inviato per primo" Ciò coincide anche quando b7 = 1 viene letto nuovamente l'intero byte come FF. Quindi o non è scritto e cancellato (condizione di errore) solo quando b7 = 1, oppure legge male come FF indipendentemente dal contenuto precedente. Poiché ogni scrittura ha una larghezza pari a un byte prima della scrittura, potrebbe comunque essere una scrittura errata o una lettura errata o la tempistica del 1 ° byte è diversa.

Suggerimento: verificare il segnale PTC durante una scrittura / lettura per garantire il normale funzionamento. inserisci qui la descrizione dell'immagine

C'è un'opzione di usare un clock esterno per cronometrare la lunghezza di un ciclo E / W usando PTC. Hai provato a usarlo?

tempo di ciclo tE / W

  • oscillatore interno 7ms tip
  • orologio esterno 4 ~ 10 ms min ~ max

Supera questi criteri?


1

Sembra che potrebbero essere un paio di cose:

  1. Cos'altro c'è sull'autobus? Potrebbe esserci un conflitto di bus con un altro dispositivo che viene tenuto in reset o non inizializzato?
  2. Stai cambiando correttamente la direzione del pin I / O? Se funziona correttamente nel caso di output, potresti aver inavvertitamente dimenticato di cambiare la direzione del pin da inserire e leggerai sempre 0xFF. Il pin potrebbe essere lasciato come uscita che guida il bus mentre si sta leggendo da esso.
  3. Hai dei pull-up interni sul pin stesso e / o sulle linee I / O? I microcontrollori di solito forniscono un intervallo di resistenza e non un valore fisso. Potresti voler disabilitare i pull-up sul micro e usare solo quelli discreti sul bus in quanto puoi ottenere una resistenza al pull-up più precisa dai componenti discreti.
  4. Polarità dell'orologio - Sei sicuro di misurare sul bordo / fase a destra tra l'orologio / i dati? È possibile che si stia rilevando ciò che si adatta perfettamente all'ambito, ma se la fase è fuori linea, la EEPROM vedrà solo 0xFFs (e molto probabilmente restituirebbe lo stesso poiché probabilmente è un comando / condizione non valido).

1. Solo EEPROM e MCU. 2. Sì, credo di sì, poiché la EEPROM è in grado di contenere l'SDA / SCL. 3. Ci sono 2,2k 5% pull up sulla scheda adiacente alla EEPROM.
Thomas O

per # 2, sei sicuro che la EEPROM sia quella che tiene il bus in basso. La EEPROM presenta delle condizioni nel foglio dati in cui restituirà tutti 0xFFi messaggi? Vedi anche le mie modifiche sopra.
Gioele B

# 4. La EEPROM sta "ACK" nelle mie richieste e funziona con alcune parole, ma non tutte.
Thomas O

0

Ho presentato questo come un commento sopra, ma la mia fiducia nella risposta è cresciuta tranquillamente nei profondi recessi della mia mente, quindi lo sto promuovendo per una risposta.

Ho la pazzesca idea che si tratti quasi certamente di un bug software di basso livello relativo alla firma di alcune variabili. Nel tuo per ogni codice di bit, stai inavvertitamente estendendo il segno con un'operazione di spostamento a destra? Se sei il tuo leader alla fine ti lascerà con un 0xFF dopo 7 turni.

Steven ha accennato a ciò in un commento, ma hai assistito alla santità delle tue operazioni di scrittura su un osilloscopio o pensi solo che funzionino sulla base della metà dei rilievi che sembrano belli? Se non hai provato a guardare l'operazione di scrittura del valore 0xAA, potrebbe essere una buona cosa provare.

Se riesci a fornire il codice effettivo del tuo ciclo interno e le dichiarazioni delle variabili associate, potremmo essere in grado di individuare un bug.


Le mie scritture sono buone; Posso vederlo sul campo di applicazione. Un'altra stranezza: gli indirizzi con i principali MSB sono a posto. Solo i dati causano problemi! Penso di pubblicare presto il codice.
Thomas O

1
A supporto di questa risposta: se questo è il codice C, cambia tutte le dichiarazioni "char" in "unsigned char" e riprova.
Wouter van Ooijen,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.