EmbeddedRelated.com
Forums
Memfault Beyond the Launch

Problem with I2C

Started by galapogos December 2, 2006
Michael N. Moran wrote:
> galapogos wrote: > > > Yes, this is exactly what the master IC is doing, so the master's doing > > it correctly. The internal EEPROM word address is a dummy address of > > 0x00 > > Does the slave EEPROM require 8bit or 16 bit addresses?
Based on the master's datasheet, probably an 8bit address, since the master only provide an 8bit word address. I'm emulating the slave EEPROM with an MCU, so I'm guessing I'm free to support any word size as long as my ISR is written in such a way to support it.

On Dec 4, 7:20 am, "galapogos" <gois...@gmail.com> wrote:
> Dan Henry wrote: > > On 3 Dec 2006 01:46:16 -0800, "galapogos" <gois...@gmail.com> wrote: > > > >Dan Henry wrote: > > >> On 1 Dec 2006 21:32:30 -0800, "galapogos" <gois...@gmail.com> wrote: > > > >> >Hi, > > >> >I'm trying to interface a Toshiba 16bit MCU with another IC(call this > > >> >IC2), > > > >> More commonly known as the "master". > > >Yup, IC2 is the master receiver in the data transaction > > > >> >with the MCU being a slave transmitter. > > > ===SNIP=== > > > >> >IC2 hence immediately sends the > > >> >device address again, and only this time does the MCU ACK it. > > > >> More evidence that one or the other end is not initializing properly. > > > ===SNIP=== > > > >> It's hard to provide meaningful feedback regarding these low level > > >> details without knowing what MCU you are using and seeing your code. > > > >The MCU that I'm using is a Toshiba tmp91cp27ug. It's part of Toshiba's > > >16bit TLCS-900/L1 series. > > > Although I've now taken a glance at the datashtte, It's hard to > > provide meaningful feedback regarding these low level details without > > seeing your code. > > > You did say above that you are initializing to slave transmitter mode. > > I assume that to mean that SBIOCR2<TRX>=1. I would think you'd want > > to initialize the slave to be a receiver first (SBIOCR2<TRX>=0), then > > let the hardware control TRX like it says in 3.11.5(6). > My ISR is basically implementing that table in the datasheet. Based on > the status register bits I'm following what the table says, but as you > can probably tell the english isn't very good and I'm having trouble > understanding some of the details. Also, either SBIOCR1 or CR2 also > doubles as SBIOSR, so it's both read and write. So you're saying I > should treat SBIOCR2<TRX> as a status bit rather than a control bit?
No, I'm saying that when you write to SBIOCR2 to configure the I2C subsystem as a slave, that you initialize it as a receiver, not a transmitter. That means the initial SBIOCR2 value should have the TRX bit 0, not 1.
galapogos wrote:
> Michael N. Moran wrote: > >>galapogos wrote: >> >> >>>Yes, this is exactly what the master IC is doing, so the master's doing >>>it correctly. The internal EEPROM word address is a dummy address of >>>0x00 >> >>Does the slave EEPROM require 8bit or 16 bit addresses? > > > Based on the master's datasheet, probably an 8bit address, since the > master only provide an 8bit word address.
Oh. I clearly haven't been reading very carefully. I assumed your MCU was the master. Since your master is fixed, I guess you get to do what it wants :-) However, with the "probably" it doesn't sound like you know what it wants.
> I'm emulating the slave > EEPROM with an MCU, so I'm guessing I'm free to support any word size > as long as my ISR is written in such a way to support it.
Word size? IIRC, I2C only transfers bytes, but I suppose you can consider consecutive bytes a "word". Either way, it seems to me that you need to do what the master expects and are not really "free to support any word size", though I realize that you may mean that you *can* support any word size required. -- Michael N. Moran (h) 770 516 7918 5009 Old Field Ct. (c) 678 521 5460 Kennesaw, GA, USA 30144 http://mnmoran.org "So often times it happens, that we live our lives in chains and we never even know we have the key." The Eagles, "Already Gone" The Beatles were wrong: 1 & 1 & 1 is 1
On 4 Dec, in article
     <1165241872.242041.197340@73g2000cwn.googlegroups.com>
     goister@gmail.com "galapogos" wrote:
>Paul Carpenter wrote: >> On 3 Dec, in article >> <1165156279.424918.206910@j72g2000cwa.googlegroups.com> >> goister@gmail.com "galapogos" wrote: >> >Paul Carpenter wrote: >> >> On 3 Dec, in article >> >> <1165139176.102811.13110@16g2000cwy.googlegroups.com> >> >> goister@gmail.com "galapogos" wrote: >> >> >Dan Henry wrote: >> >> >> On 1 Dec 2006 21:32:30 -0800, "galapogos" <goister@gmail.com> wrote: >> >> >> >> >> >> >Hi, >> >> >> >I'm trying to interface a Toshiba 16bit MCU with another IC(call this >> >> >> >IC2),
.....
>> Can you forget the word 'dummy' it is NOT a dummy address. The EEPROM has >> lots of locations so which location to read is sent as an address from your >> ASIC to say WHICH location to READ (or write). So the address is an actual >> real address INSIDE the EEPROM. I have seen 256byte to 64kbyte EEPROMs used. >> >> The resent address is how the ASIC talks to the EEPROM and is determined >> by the EEPROM specification, read that datasheet, as that is what you >> are trying to emulate in your MCU and software. >> >> IT is *important* you understand how the EEPROM works. Then you can >> understand what the I2C transactions are, so you can get your >> software to emulate the EEPROM. > >Well, I'm simply following what the datasheet calls it. The master IC's >datasheet refers to the word address as a dummy word address, hence I >call it as such. I do understand that you have to address any memory(in >this case an EEPROM) with an actual physical address. In this case that >address is 0x00 if I'm understanding the datasheet properly.
If you do not always read the correct address, then your EEPROM may as well just be a register with one value, or a full EEPROM with just one value.
>> ... >> >> Put an actual EEPROM on the ASIC and do a detailed analysis of the timing >> >> of the I2C transactions that occur, and you may well find the ASIC is >> >> getting away with working. Note what rise and fall times you have, all > timing >> >> of ALL high and low states. Until you have done this the rest is > meaningless. >> >> Have you or are you going to do this it is important to realise what is >> actually happening, so you can then check it against what your software >> results are. Then you can confirm your software is working correctly. > >I haven't dont this yet since I have no access to the setup over the >weekend. I'm not sure if I can get an I2C compatible EEPROM either, but >I'll try. Meanwhile I'll have to keep working with what I have.
I2C EEPROMs are easily available and not difficult to add. Without double checking the real situation you will not be sure when things are working. ...
>> >> >> It's hard to provide meaningful feedback regarding these low level >> >> >> details without knowing what MCU you are using and seeing your code. >> >> > >> >> >The MCU that I'm using is a Toshiba tmp91cp27ug. It's part of Toshiba's >> >> >16bit TLCS-900/L1 series.
....
>> >> Is the data sheet easily available on the web? >> > >> >Yes, it is available at >> >http://www.semicon.toshiba.co.jp/openb2b/websearch/productDetails.jsp?partKey >=TM >> >P91CP27UG+%232 >> >> Will see if I can get it later. > >Thanks!
...
>> >> What is your code for handling the I2C functions? >> >> >> >> I strongly suspect your code for this. >> > >> >Yup I'm pretty sure it's my code too since this is the first time I'm >> >writing I2C code. I'm just not sure what's wrong, or even what I need >> >to do. Basically what I'm doing is I have an initI2C function that >> >initializes the SFRs to the desired values(8bit word, ACK generation, >> >slave transmitter operation mode, setting of the slave address, etc), >> >and then I have a serial interrupt service routine that checks the >> >various status bits and decides what to do in each case. >> >> You have an understanding problem here, hence the data corruption. >> >> Sequence in ROUGH OUTLINE >> >> Init controller (slave address, ACk generation >> SLAVE RECEIVER mode) >> >> Interupt routine >> Address decode WRITE (ASIC writes to EEPROM) >> Leave in RECEIVER mode and receive all bytes and >> action first 'n' bytes as address to 'write' to >> (EEPROM internal address) you will need a volatile >> to store the pseudo address pointer. >> Any further bytes you will have to store in you EEPROM >> emulation (if the ASIC does writes). >> Stop >> End transaction >> READ no ack >> END transaction >> Start/Repeated start >> Stay in slave Receiver >> >> Address decode READ (ASIC reads from EEPROM) >> Set mode SLAVE TRANSMITTER >> For subsequent data bytes >> Send byte pointed to by pseudo address pointer >> Increment psudo address transmitter >> >> Error conditions >> END transaction and set some error flag in your software >> >> How you determine end of I2C transaction and signal to your software >> depends on many other attributes. >> >> You are reading 0xFF mainly because you are transmitting when you should >> be receiving! > >You mean the master IC is transmitting rather than the MCU? I don't >think that's possible since it's a fixed function ASIC. My MCU is >supposed to be the one transmitting, but I'm not getting any interrupts >for me to put any data into the serial buffer for sending.
You have not understood I2C or your setup. You are trying to make an EEPROM emulator which is a SLAVE device. Your ASIC access the EEPROM so it is MASTER device. On I2C a MASTER device CONTROLS the bus and transactions Master device SENDS I2C address (SLAVE RECEIVES) A good Master device then RECEIVES the ACK bit (SLAVE SENDS) If I2C address includes write bit = 0 (WRITE condition) Master device SENDS I2C data (SLAVE RECEIVES) A good Master device then RECEIVES the ACK bit (SLAVE SENDS) Repeat until all bytes SENT. If I2C address is for READ condition Master devices SENDS I2C clock to clock data OUT of SLAVE (now in transmitter mode) (SLAVE SENDS) Master devices SENDS I2C data of ACK bit (SLAVE RECEIVES) - except on LAST byte Repeat until all bytes SENT. Slave devices (like EEPROMs) spend the majority of their time in RECEIVE mode, listening for addresses and data to be written TO the slave device they ONLY chnage to transmitters when READING data OUT of the slave device. For your MCU it MUST be in receiver mode to receive the I2C SDA line INTO its shift register for listening to addresses or for data WRITTEN to the device. Then change to transmit mode to connect the shift register OUTPUT to the I2C SDA line (and enable arbitration circuitry). Why do I know this because I have done various I2C devices onto systems over the years and I am currently doing a similar thing for an ASIC, mine will probably end up in a CPLD. That is because the circumstances of this application will mean it is easier to do that way. -- Paul Carpenter | paul@pcserviceselectronics.co.uk <http://www.pcserviceselectronics.co.uk/> PC Services <http://www.gnuh8.org.uk/> GNU H8 & mailing list info <http://www.badweb.org.uk/> For those web sites you hate
Paul Carpenter wrote:
> On 4 Dec, in article > <1165241872.242041.197340@73g2000cwn.googlegroups.com> > goister@gmail.com "galapogos" wrote: > >Paul Carpenter wrote: > >> On 3 Dec, in article > >> <1165156279.424918.206910@j72g2000cwa.googlegroups.com> > >> goister@gmail.com "galapogos" wrote: > >> >Paul Carpenter wrote: > >> >> On 3 Dec, in article > >> >> <1165139176.102811.13110@16g2000cwy.googlegroups.com> > >> >> goister@gmail.com "galapogos" wrote: > >> >> >Dan Henry wrote: > >> >> >> On 1 Dec 2006 21:32:30 -0800, "galapogos" <goister@gmail.com> wrote: > >> >> >> > >> >> >> >Hi, > >> >> >> >I'm trying to interface a Toshiba 16bit MCU with another IC(call this > >> >> >> >IC2), > ..... > >> Can you forget the word 'dummy' it is NOT a dummy address. The EEPROM has > >> lots of locations so which location to read is sent as an address from your > >> ASIC to say WHICH location to READ (or write). So the address is an actual > >> real address INSIDE the EEPROM. I have seen 256byte to 64kbyte EEPROMs used. > >> > >> The resent address is how the ASIC talks to the EEPROM and is determined > >> by the EEPROM specification, read that datasheet, as that is what you > >> are trying to emulate in your MCU and software. > >> > >> IT is *important* you understand how the EEPROM works. Then you can > >> understand what the I2C transactions are, so you can get your > >> software to emulate the EEPROM. > > > >Well, I'm simply following what the datasheet calls it. The master IC's > >datasheet refers to the word address as a dummy word address, hence I > >call it as such. I do understand that you have to address any memory(in > >this case an EEPROM) with an actual physical address. In this case that > >address is 0x00 if I'm understanding the datasheet properly. > > If you do not always read the correct address, then your EEPROM may as well > just be a register with one value, or a full EEPROM with just one value. > > >> ... > >> >> Put an actual EEPROM on the ASIC and do a detailed analysis of the timing > >> >> of the I2C transactions that occur, and you may well find the ASIC is > >> >> getting away with working. Note what rise and fall times you have, all > > timing > >> >> of ALL high and low states. Until you have done this the rest is > > meaningless. > >> > >> Have you or are you going to do this it is important to realise what is > >> actually happening, so you can then check it against what your software > >> results are. Then you can confirm your software is working correctly. > > > >I haven't dont this yet since I have no access to the setup over the > >weekend. I'm not sure if I can get an I2C compatible EEPROM either, but > >I'll try. Meanwhile I'll have to keep working with what I have. > > I2C EEPROMs are easily available and not difficult to add. Without double > checking the real situation you will not be sure when things are working. > > ... > >> >> >> It's hard to provide meaningful feedback regarding these low level > >> >> >> details without knowing what MCU you are using and seeing your code. > >> >> > > >> >> >The MCU that I'm using is a Toshiba tmp91cp27ug. It's part of Toshiba's > >> >> >16bit TLCS-900/L1 series. > .... > >> >> Is the data sheet easily available on the web? > >> > > >> >Yes, it is available at > >> >http://www.semicon.toshiba.co.jp/openb2b/websearch/productDetails.jsp?partKey > >=TM > >> >P91CP27UG+%232 > >> > >> Will see if I can get it later. > > > >Thanks! > > ... > >> >> What is your code for handling the I2C functions? > >> >> > >> >> I strongly suspect your code for this. > >> > > >> >Yup I'm pretty sure it's my code too since this is the first time I'm > >> >writing I2C code. I'm just not sure what's wrong, or even what I need > >> >to do. Basically what I'm doing is I have an initI2C function that > >> >initializes the SFRs to the desired values(8bit word, ACK generation, > >> >slave transmitter operation mode, setting of the slave address, etc), > >> >and then I have a serial interrupt service routine that checks the > >> >various status bits and decides what to do in each case. > >> > >> You have an understanding problem here, hence the data corruption. > >> > >> Sequence in ROUGH OUTLINE > >> > >> Init controller (slave address, ACk generation > >> SLAVE RECEIVER mode) > >> > >> Interupt routine > >> Address decode WRITE (ASIC writes to EEPROM) > >> Leave in RECEIVER mode and receive all bytes and > >> action first 'n' bytes as address to 'write' to > >> (EEPROM internal address) you will need a volatile > >> to store the pseudo address pointer. > >> Any further bytes you will have to store in you EEPROM > >> emulation (if the ASIC does writes). > >> Stop > >> End transaction > >> READ no ack > >> END transaction > >> Start/Repeated start > >> Stay in slave Receiver > >> > >> Address decode READ (ASIC reads from EEPROM) > >> Set mode SLAVE TRANSMITTER > >> For subsequent data bytes > >> Send byte pointed to by pseudo address pointer > >> Increment psudo address transmitter > >> > >> Error conditions > >> END transaction and set some error flag in your software > >> > >> How you determine end of I2C transaction and signal to your software > >> depends on many other attributes. > >> > >> You are reading 0xFF mainly because you are transmitting when you should > >> be receiving! > > > >You mean the master IC is transmitting rather than the MCU? I don't > >think that's possible since it's a fixed function ASIC. My MCU is > >supposed to be the one transmitting, but I'm not getting any interrupts > >for me to put any data into the serial buffer for sending. > > You have not understood I2C or your setup. > > You are trying to make an EEPROM emulator which is a SLAVE device. > > Your ASIC access the EEPROM so it is MASTER device. > > On I2C a MASTER device CONTROLS the bus and transactions > > Master device SENDS I2C address (SLAVE RECEIVES) > A good Master device then RECEIVES the ACK bit (SLAVE SENDS) > > If I2C address includes write bit = 0 (WRITE condition) > Master device SENDS I2C data (SLAVE RECEIVES) > A good Master device then RECEIVES the ACK bit (SLAVE SENDS) > Repeat until all bytes SENT. > > If I2C address is for READ condition > Master devices SENDS I2C clock to clock data OUT > of SLAVE (now in transmitter mode) (SLAVE SENDS) > Master devices SENDS I2C data of ACK bit (SLAVE RECEIVES) > - except on LAST byte > Repeat until all bytes SENT.
I understand all the way up to here.
> Slave devices (like EEPROMs) spend the majority of their time in RECEIVE > mode, listening for addresses and data to be written TO the slave device > they ONLY chnage to transmitters when READING data OUT of the slave device. > > For your MCU it MUST be in receiver mode to receive the I2C SDA line > INTO its shift register for listening to addresses or for data WRITTEN > to the device. Then change to transmit mode to connect the shift register > OUTPUT to the I2C SDA line (and enable arbitration circuitry).
OK, this means that like what Dan said previously I should initialize my MCU as a slave receiver initially rather than a slave transmitter. That might explain why the first device address is not acknowledged?
On 4 Dec, in article
     <1165253652.590662.58080@79g2000cws.googlegroups.com>
     goister@gmail.com "galapogos" wrote:

>Paul Carpenter wrote:
....
>> You are trying to make an EEPROM emulator which is a SLAVE device. >> >> Your ASIC access the EEPROM so it is MASTER device. >> >> On I2C a MASTER device CONTROLS the bus and transactions >> >> Master device SENDS I2C address (SLAVE RECEIVES) >> A good Master device then RECEIVES the ACK bit (SLAVE SENDS) >> >> If I2C address includes write bit = 0 (WRITE condition) >> Master device SENDS I2C data (SLAVE RECEIVES) >> A good Master device then RECEIVES the ACK bit (SLAVE SENDS) >> Repeat until all bytes SENT. >> >> If I2C address is for READ condition >> Master devices SENDS I2C clock to clock data OUT >> of SLAVE (now in transmitter mode) (SLAVE SENDS) >> Master devices SENDS I2C data of ACK bit (SLAVE RECEIVES) >> - except on LAST byte >> Repeat until all bytes SENT. > >I understand all the way up to here. > >> Slave devices (like EEPROMs) spend the majority of their time in RECEIVE >> mode, listening for addresses and data to be written TO the slave device >> they ONLY chnage to transmitters when READING data OUT of the slave device. >> >> For your MCU it MUST be in receiver mode to receive the I2C SDA line >> INTO its shift register for listening to addresses or for data WRITTEN >> to the device. Then change to transmit mode to connect the shift register >> OUTPUT to the I2C SDA line (and enable arbitration circuitry). > >OK, this means that like what Dan said previously I should initialize >my MCU as a slave receiver initially rather than a slave transmitter. >That might explain why the first device address is not acknowledged?
Yes. you only switch to transmit mode at the point in time when you need to send a byte (actually READING out) data. Then you switch back again to receive mode. Just like the bits above, when it says (SLAVE RECEIVES) the slave is in receive mode. Ack bits should be handled by your software setting ack bit generation for address acknowledge so the hardware does it for you. As to whether your ASIC does anything with ACK bits, depends on the ASIC, having seen some that ignore incoming ACKs and always set ACK bit sending to '1' regardless of what it should be. That is why Dan and me are saying you are transmitting when you should be receiving. -- Paul Carpenter | paul@pcserviceselectronics.co.uk <http://www.pcserviceselectronics.co.uk/> PC Services <http://www.gnuh8.org.uk/> GNU H8 & mailing list info <http://www.badweb.org.uk/> For those web sites you hate
Paul Carpenter wrote:
> On 4 Dec, in article > <1165253652.590662.58080@79g2000cws.googlegroups.com> > goister@gmail.com "galapogos" wrote: > > >Paul Carpenter wrote: > .... > >> You are trying to make an EEPROM emulator which is a SLAVE device. > >> > >> Your ASIC access the EEPROM so it is MASTER device. > >> > >> On I2C a MASTER device CONTROLS the bus and transactions > >> > >> Master device SENDS I2C address (SLAVE RECEIVES) > >> A good Master device then RECEIVES the ACK bit (SLAVE SENDS) > >> > >> If I2C address includes write bit = 0 (WRITE condition) > >> Master device SENDS I2C data (SLAVE RECEIVES) > >> A good Master device then RECEIVES the ACK bit (SLAVE SENDS) > >> Repeat until all bytes SENT. > >> > >> If I2C address is for READ condition > >> Master devices SENDS I2C clock to clock data OUT > >> of SLAVE (now in transmitter mode) (SLAVE SENDS) > >> Master devices SENDS I2C data of ACK bit (SLAVE RECEIVES) > >> - except on LAST byte > >> Repeat until all bytes SENT. > > > >I understand all the way up to here. > > > >> Slave devices (like EEPROMs) spend the majority of their time in RECEIVE > >> mode, listening for addresses and data to be written TO the slave device > >> they ONLY chnage to transmitters when READING data OUT of the slave device. > >> > >> For your MCU it MUST be in receiver mode to receive the I2C SDA line > >> INTO its shift register for listening to addresses or for data WRITTEN > >> to the device. Then change to transmit mode to connect the shift register > >> OUTPUT to the I2C SDA line (and enable arbitration circuitry). > > > >OK, this means that like what Dan said previously I should initialize > >my MCU as a slave receiver initially rather than a slave transmitter. > >That might explain why the first device address is not acknowledged? > > Yes. you only switch to transmit mode at the point in time when you > need to send a byte (actually READING out) data. Then you switch back > again to receive mode. Just like the bits above, when it says > (SLAVE RECEIVES) the slave is in receive mode. > > Ack bits should be handled by your software setting ack bit generation > for address acknowledge so the hardware does it for you. As to whether > your ASIC does anything with ACK bits, depends on the ASIC, having seen > some that ignore incoming ACKs and always set ACK bit sending to '1' > regardless of what it should be. > > That is why Dan and me are saying you are transmitting when you should > be receiving.
Cool. I initialized my MCU to a slave receiver and now it acknowledges the first device address, so there's no resending. I also managed to get the MCU to interrupt on all subsequent data bytes, but I'm still not able to send the correct data over. The data is either 0x80 of 0xfd
Dan Henry wrote:
> On 3 Dec 2006 01:46:16 -0800, "galapogos" <goister@gmail.com> wrote: > > > > >Dan Henry wrote: > >> On 1 Dec 2006 21:32:30 -0800, "galapogos" <goister@gmail.com> wrote: > >> > >> >Hi, > >> >I'm trying to interface a Toshiba 16bit MCU with another IC(call this > >> >IC2), > >> > >> More commonly known as the "master". > >Yup, IC2 is the master receiver in the data transaction > > > >> >with the MCU being a slave transmitter. > > ===SNIP=== > > >> >IC2 hence immediately sends the > >> >device address again, and only this time does the MCU ACK it. > >> > >> More evidence that one or the other end is not initializing properly. > > ===SNIP=== > > >> It's hard to provide meaningful feedback regarding these low level > >> details without knowing what MCU you are using and seeing your code. > > > >The MCU that I'm using is a Toshiba tmp91cp27ug. It's part of Toshiba's > >16bit TLCS-900/L1 series. > > Although I've now taken a glance at the datashtte, It's hard to > provide meaningful feedback regarding these low level details without > seeing your code. > > You did say above that you are initializing to slave transmitter mode. > I assume that to mean that SBIOCR2<TRX>=1. I would think you'd want > to initialize the slave to be a receiver first (SBIOCR2<TRX>=0), then > let the hardware control TRX like it says in 3.11.5(6).
Here's my current pseudo code: initI2C() { P6FC = 0x06; // set P61/62 to SDA/SCL function P6CR = 0x06; // set P61/62 to output IOP6 = 0x06; // set P61/62 to high SBI0BR1 = 0x80; // enable I2C I2C0AR = 0xa0; // 7bit slave address of MCU(1010000b) SBI0CR1 = 0x10; // Serial bus interface control register 1 SBI0CR2 = 0x18; // Serial bus interface control register 2 SBI0BR0 = 0x00; INTES2RTC = 0x04; // enable INTSBI interrupt, priority level 4 index = 0; // index into the data } ISR() { if (SBI0SR_TRX == 0) { if ( (SBI0SR_AL == 0) && (SBI0SR_AAS == 0) ) { SBI0CR1 &= ~SBI0CR1_BC; junk = SBI0DBR; } else { junk = SBI0DBR; } } else { if ( SBI0SR_AAS && (SBI0SR_AD0 == 0) ) { SBI0CR1 &= ~SBI0CR1_BC; // sets word size as 8bits SBI0DBR = data[index++]; } else if ( (SBI0SR_AL == 0) && (SBI0SR_AAS == 0) && (SBI0SR_AD0 == 0) ) { if (SBI0SR_LRB) { SBI0CR2 |= SBI0CR2_PIN; // pull PIN high SBI0CR2 &= ~SBI0CR2_TRX; // reset TRX } else { SBI0CR1 &= ~SBI0CR1_BC; // sets word size as 8bits SBI0DBR = data[index++]; } } } } }
Michael N. Moran wrote:
> galapogos wrote: > > Michael N. Moran wrote: > > > >>galapogos wrote: > >> > >> > >>>Yes, this is exactly what the master IC is doing, so the master's doing > >>>it correctly. The internal EEPROM word address is a dummy address of > >>>0x00 > >> > >>Does the slave EEPROM require 8bit or 16 bit addresses? > > > > > > Based on the master's datasheet, probably an 8bit address, since the > > master only provide an 8bit word address. > > Oh. I clearly haven't been reading very carefully. I assumed > your MCU was the master. > > Since your master is fixed, I guess you get to do what it wants :-) > However, with the "probably" it doesn't sound like you know what > it wants.
Actually I know what the master wants, because in its datasheet there is the exact waveform/timing diagram, and I'm matching that against my output on the logic analyzer. The master actually provides an 8bit word address.
> > I'm emulating the slave > > EEPROM with an MCU, so I'm guessing I'm free to support any word size > > as long as my ISR is written in such a way to support it. > > Word size? IIRC, I2C only transfers bytes, but I suppose you > can consider consecutive bytes a "word". Either way, it seems to > me that you need to do what the master expects and are not > really "free to support any word size", though I realize that > you may mean that you *can* support any word size required.
Yup that's what I meant. I can support any word size required but in this case I have to adhere to the master which provides an 8bit word address.
galapogos wrote:
> Paul Carpenter wrote: > > On 4 Dec, in article > > <1165253652.590662.58080@79g2000cws.googlegroups.com> > > goister@gmail.com "galapogos" wrote: > > > > >Paul Carpenter wrote: > > .... > > >> You are trying to make an EEPROM emulator which is a SLAVE device. > > >> > > >> Your ASIC access the EEPROM so it is MASTER device. > > >> > > >> On I2C a MASTER device CONTROLS the bus and transactions > > >> > > >> Master device SENDS I2C address (SLAVE RECEIVES) > > >> A good Master device then RECEIVES the ACK bit (SLAVE SENDS) > > >> > > >> If I2C address includes write bit = 0 (WRITE condition) > > >> Master device SENDS I2C data (SLAVE RECEIVES) > > >> A good Master device then RECEIVES the ACK bit (SLAVE SENDS) > > >> Repeat until all bytes SENT. > > >> > > >> If I2C address is for READ condition > > >> Master devices SENDS I2C clock to clock data OUT > > >> of SLAVE (now in transmitter mode) (SLAVE SENDS) > > >> Master devices SENDS I2C data of ACK bit (SLAVE RECEIVES) > > >> - except on LAST byte > > >> Repeat until all bytes SENT. > > > > > >I understand all the way up to here. > > > > > >> Slave devices (like EEPROMs) spend the majority of their time in RECEIVE > > >> mode, listening for addresses and data to be written TO the slave device > > >> they ONLY chnage to transmitters when READING data OUT of the slave device. > > >> > > >> For your MCU it MUST be in receiver mode to receive the I2C SDA line > > >> INTO its shift register for listening to addresses or for data WRITTEN > > >> to the device. Then change to transmit mode to connect the shift register > > >> OUTPUT to the I2C SDA line (and enable arbitration circuitry). > > > > > >OK, this means that like what Dan said previously I should initialize > > >my MCU as a slave receiver initially rather than a slave transmitter. > > >That might explain why the first device address is not acknowledged? > > > > Yes. you only switch to transmit mode at the point in time when you > > need to send a byte (actually READING out) data. Then you switch back > > again to receive mode. Just like the bits above, when it says > > (SLAVE RECEIVES) the slave is in receive mode. > > > > Ack bits should be handled by your software setting ack bit generation > > for address acknowledge so the hardware does it for you. As to whether > > your ASIC does anything with ACK bits, depends on the ASIC, having seen > > some that ignore incoming ACKs and always set ACK bit sending to '1' > > regardless of what it should be. > > > > That is why Dan and me are saying you are transmitting when you should > > be receiving. > > Cool. I initialized my MCU to a slave receiver and now it acknowledges > the first device address, so there's no resending. I also managed to > get the MCU to interrupt on all subsequent data bytes, but I'm still > not able to send the correct data over. The data is either 0x80 of 0xfd
OK scratch that. The data that is sent is actually always 0x80, and I'm not sure why that's the case. I'm sending 16 bytes of data over to the master, and the initial handshaking is all fine until I actually send data over by writing my data to my serial buffer SBI0DBR, but when I immediately copy this data over to another junk variable, it reads 0x80, and according to my logic analyzer waveform, it is also 0x80, so it looks like the MCU is indeed sending whatever is in the buffer, but the buffer isn't being updated with what I actually want to send...

Memfault Beyond the Launch