EmbeddedRelated.com
Forums

Problem with I2C

Started by galapogos December 2, 2006
Paul Carpenter wrote:
> On 6 Dec, in article > <1165400403.987854.72700@16g2000cwy.googlegroups.com> > goister@gmail.com "galapogos" wrote: > > >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), > ..... > >> >> >> 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. > > > >I interfaced a microchip I2C EEPROM to the master ASIC, and then > >triggered the master to request the 16byte data from the EEPROM. I'm > >not sure what's in the EEPROM but it appears to be all 0xFFs. Anyway, > >the timing diagram is exactly like the ASIC's datasheet says. Here's > >the sequence: > > You are getting 0xFF which shows > > a) The EEPROM is erased > b) The hardware and wiring works > c) You can see that the transactions can be done. > d) You have a reference for REAL that matches what should happen.
Cool, it means at least that works
> >1) Master(ASIC) sends start bit and device address and WRITE direction > >bit(0xa0) > >2) Slave(EEPROM) ACKs > >3) Master sends word address(0x00) > >4) Slave ACKs > >5) Master sends another start bit and device address and READ direction > >bit(0xa1) > >6) Slave ACKs > >7) Slave sends 1 byte of data(0xFF) > >8) Master ACKs > >9) Repeat 7-8 until all 16 bytes have been received > >10) Master(?) sends NOACK and stop bit > > > >This also corresponds with the EEPROM's datasheet timing diagram so I > >assume this is the correct handshaking protocol to follow. > > Yes that is correct. > > >I refered to the I2C bus specification 2.1(Jan 2000) trying to find > >this handshaking protocol, and this seems to be a "combined format" for > >serial EEPROMs. > > > >I then tried to access the EEPROM with my MCU set as a master. I was > >able to get all the way to step 6, but after that, my MCU was still in > >master transmitter mode rather than master receiver mode. I have to set > >the master to transmit mode for it to send the 2nd device address in > >step 5. I thought that the direction bit sent in step 5 would reset the > >MCU to be in receiver mode but it didn't. Therefore I'm unable to > >continue on to step 7. In fact, I had to hack things up quite a bit to > > NO direction changes YOU must code, I would suggest when you are sending > a READ address (last bit of address = 1), after the ACK then YOU must change > the direction.
How do I detect this though. I send the READ address at interrupt n, but I expect the ACK at interrupt n+1, so I would need some way of detecting something at n+1 to change direction, and the address is long gone by then so I can't detect. Other than using the global counter or some other global variable I can't think of a way to do so.
> >even get it working till step 6. For example, I didn't know how to > >correctly detect when to restart in step 5, so I detected this by > >having a global interrupt counter and restarting when the counter is a > >certain value. > > You send the start condition using the controller to send a start then > the Read address. When your MCU is master you do not detect it you > generate it.
I think you misunderstood me. I know when conceptually to start and restart, and I'm doing this in main(). However, in my ISR, I do a bunch of status bit detection to determine what I should do at any given time. On my restart, when I'm sending the READ address in main(), I have to keep my status as a master transmitter since I'm sending the READ address to the master. However, I think because of this, at the end of the ACK for the READ address, I'm still going into the isr code section for master transmitter, which is to send more data. Instead, I should be going into the master receive code section where the serial buffer is free to accept incoming data. Makes sense? Or am I thinking of it totally the wrong way?
> >I'm sure there must be a proper way of detecting when to restart but I > >can't figure out how. As far as my MCU goes, it still thinks it's in > >master transmitter mode after sending the device/word address, so I > >don't know how to tell it to restart at that point. > > You do the following steps > > generate a start coindition > transmit the read address, > get ACK > Change mode to receive > Receive bytes > last byte Set NOACK > Send Stop
Aren't you missing the 1st start condition? i.e. 1) generate start condition 2) transmit WRITE address 3) get ACK 4) transmit word address 5) get ACK 6) generate restart 7) transmit READ address 8) receive ACK 9) receive bytes 10) last byte set NOACK, send stop(automatic) Like I said, I'm doing fine until step 5. I can do step 7, but then I fall into the wrong code segment inside my ISR(master transmitter instead of master receiver), and I'm not sure where exactly I can change my control/status bit to receive. What I'm thinking is I can't change it at the start of step 7 since I'm still transmitting, but the next point I can change it is in in the ISR after step 8, and that's too late since I'm already supposed to be in receive mode in that stage right? I can't change it in the ISR after step 8 since my ISR wouldn't know that the READ address was previously sent. All it knows about the outside world is what the MCU status bits reveal, which are the following bits: MST - master or slave TRX - transmit or receive AL - arbitration lost AAS - slave address match AD0 - GENERAL CALL address match BB - bus free PIN - serial interrupt cancel What else can I do to detect that my previous transmission was a "transmit READ address"?
> >Is it so hard to handle the handshaking for every MCU or am I just > >unlucky to be working with a Toshiba? > > I think it is more to do with understanding of I2C and which end is > transmitting at what stage.
Perhaps. I do appreciate your help, and sorry if I seem like a total noob(that's coz I am), but I do hope I can understand this whole thingamajig soon!
On 6 Dec, in article
     <1165420492.448953.97930@79g2000cws.googlegroups.com>
     goister@gmail.com "galapogos" wrote:

>Paul Carpenter wrote: >> On 6 Dec, in article >> <1165401830.130900.269240@80g2000cwy.googlegroups.com> >> goister@gmail.com "galapogos" wrote: >> >Paul Carpenter wrote: >> >> On 5 Dec, in article >> >> <1165369825.395623.117700@n67g2000cwd.googlegroups.com> >> >> goister@gmail.com "galapogos" wrote: >> >> >Paul Carpenter wrote: >> >> >> On 4 Dec, in article >> >> >> <1165304918.361673.137080@16g2000cwy.googlegroups.com> >> >> >> goister@gmail.com "galapogos" wrote: >> >> >> >galapogos wrote: >> ..... >> >> >> First *ASSUMPTION* the first data byte of the 16 data bytes to send >> >> >> should be 0x80 ? >> >> > >> >> >No, it is 0x00 to 0x10 in sequence. 0x80 isn't part of the data array >> >> >at all. In fact, I tried sending dummy constants but I always get 0x80 >> >> >instead. >> >> >> >> Are you sending a block of 16 bytes or 16 single byte read equences? >> > >> >I enter the MCU's ISR after each ACK sent/received. Each time I enter >> >the ISR I send or receive 1 byte, so I guess I'm sending 16 single byte >> >sequences? >> >> No you are sending a block of 16 bytes. Just that I2C is slower than >> the MCU. >> >> 16 single byte reads would have an address sequence for each byte read >> of one byte. > >OK > >> >> Check when changing to send first byte you change to transmit and have >> >> set up everything and be sure it is in transmit mode before writing data >> >> to controller. >> > >> >Actually I'm not even sure if I can even change the transmit direction >> >on the fly. The control register that the transmit direction is at is >> >shared with the status register, so within my ISR, I check to see if >> >it's in transmit mode. If it is, then I'll send data, if not I'll >> >receive. It's really up to the hardware to tell me if it's in transmit >> >or receive mode AFAIK. >> >> No it is up to you to change direction once you have acked the read address >> being received. > >So at the interrupt after the read address when i have something like >junk = buffer, i should do a if (junk = address) { change direction } ?
if( address & 1 ) /* Read address*/ { Change direction to transmit } if( stop &#4294967295;&#4294967295; restart ) { Change direction back to receive /* idle as receive */ } -- 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
On 6 Dec, in article
     <1165421691.608742.42950@l12g2000cwl.googlegroups.com>
     goister@gmail.com "galapogos" wrote:

>Paul Carpenter wrote: >> On 6 Dec, in article >> <1165400403.987854.72700@16g2000cwy.googlegroups.com> >> goister@gmail.com "galapogos" wrote:
....
>> >I then tried to access the EEPROM with my MCU set as a master. I was >> >able to get all the way to step 6, but after that, my MCU was still in >> >master transmitter mode rather than master receiver mode. I have to set >> >the master to transmit mode for it to send the 2nd device address in >> >step 5. I thought that the direction bit sent in step 5 would reset the >> >MCU to be in receiver mode but it didn't. Therefore I'm unable to >> >continue on to step 7. In fact, I had to hack things up quite a bit to >> >> NO direction changes YOU must code, I would suggest when you are sending >> a READ address (last bit of address = 1), after the ACK then YOU must change >> the direction. > >How do I detect this though. I send the READ address at interrupt n, >but I expect the ACK at interrupt n+1, so I would need some way of >detecting something at n+1 to change direction, and the address is long >gone by then so I can't detect. Other than using the global counter or >some other global variable I can't think of a way to do so.
Either from main program flow or knowing how many bytes are being sent/received. You must have some form of state knowledge, even if your higher level code is waiting for interupts to complete. I assume you have some form of flag for how many bytes received. The data in the data register at addressed or ACK time should be the address including a READ/WRITE bit to set flow for next bytes. Most people run with simple functions and state variables, so they know that they are receiving an I2C address, having done that note what type of address and action accordingly. Unless your MCU is very busy doing other things I would in this case test first using code that monitors an interupt flag to signify you have been Addressed as Slave, then drop to a linear function to test things first as in If I2C address write mode Read 'n' bytes of EEPROM internal address SEND ACK Read 'n' bytes of write data Send ACK (if anytime stop or start detected exit) else switch mode to transmit send data byte Wait for ACK/NOACK if ACK repeat send data if NACK wait for stop/start condition (if anytime stop or start detected switch to receive mode exit) The waits, sends and receive would be functions. get it working this way first then look at ways to put it into an interupt function with state variables about next state, current state, count of bytes if known. Starting with interupt functions for I2C is probably trying to run before you can walk. If you are master you should know from your program flow what you are trying to achieve. Write as a bunch of linear calls and code to test handling of I2C controller first, start as master talking to EEPROM to write a byte, then reset the address and read the byte back.
>> >even get it working till step 6. For example, I didn't know how to >> >correctly detect when to restart in step 5, so I detected this by >> >having a global interrupt counter and restarting when the counter is a >> >certain value. >> >> You send the start condition using the controller to send a start then >> the Read address. When your MCU is master you do not detect it you >> generate it. > >I think you misunderstood me. I know when conceptually to start and >restart, and I'm doing this in main(). However, in my ISR, I do a bunch >of status bit detection to determine what I should do at any given >time. > >On my restart, when I'm sending the READ address in main(), I have to >keep my status as a master transmitter since I'm sending the READ >address to the master. However, I think because of this, at the end of >the ACK for the READ address, I'm still going into the isr code section >for master transmitter, which is to send more data. Instead, I should >be going into the master receive code section where the serial buffer >is free to accept incoming data. Makes sense? Or am I thinking of it >totally the wrong way?
You need to determine as a aslave from the LRB (Last received bit) or a flag when as master that you have sent a read or write address I think you are expecting too much from a simple I2C controller, all the ones I have seen expect a lot of control software and state variables, especially for timeouts and other error trapping.
>> >I'm sure there must be a proper way of detecting when to restart but I >> >can't figure out how. As far as my MCU goes, it still thinks it's in >> >master transmitter mode after sending the device/word address, so I >> >don't know how to tell it to restart at that point. >> >> You do the following steps >> >> generate a start coindition >> transmit the read address, >> get ACK >> Change mode to receive >> Receive bytes >> last byte Set NOACK >> Send Stop > >Aren't you missing the 1st start condition? i.e.
No I was talking about after the first Write transaction. The Toshiba manual does have sections on generating restarts (may not be well written but it is there).. If detecting as a slave see the manual and BB bit for start/stop detection. ....
>Like I said, I'm doing fine until step 5. I can do step 7, but then I >fall into the wrong code segment inside my ISR(master transmitter >instead of master receiver), and I'm not sure where exactly I can >change my control/status bit to receive. What I'm thinking is I can't >change it at the start of step 7 since I'm still transmitting, but the >next point I can change it is in in the ISR after step 8, and that's >too late since I'm already supposed to be in receive mode in that stage >right? I can't change it in the ISR after step 8 since my ISR wouldn't >know that the READ address was previously sent. All it knows about the >outside world is what the MCU status bits reveal, which are the
Whatever you do you will need some way of tracking either as a master talking to EEPROM, or as a slave emulating a EEPROM what type of transaction you are doing. probably what state you are in as well (waiting ack, receiving byte, receiving address, idle....).
>following bits: >MST - master or slave >TRX - transmit or receive >AL - arbitration lost >AAS - slave address match >AD0 - GENERAL CALL address match >BB - bus free >PIN - serial interrupt cancel >What else can I do to detect that my previous transmission was a >"transmit READ address"?
The data in the data register when slave, and from your programme as a master you will have the Address used or status somwhere. Before ACK stage as slave LRB in status register will tell you as well. See manual for TMP91CP27U Table 3.11.1 .
>> >Is it so hard to handle the handshaking for every MCU or am I just >> >unlucky to be working with a Toshiba? >> >> I think it is more to do with understanding of I2C and which end is >> transmitting at what stage. > >Perhaps. I do appreciate your help, and sorry if I seem like a total >noob(that's coz I am), but I do hope I can understand this whole >thingamajig soon!
I would start as linear code first of all to prove the methods of controlling the I2C controller, get that working then ARCHIVE it as a reference then look at creating interupt driven code. Slave I2C devices are relatively easy in hardware but more complicated in software controlled situations. -- 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 6 Dec, in article > <1165421691.608742.42950@l12g2000cwl.googlegroups.com> > goister@gmail.com "galapogos" wrote: > > >Paul Carpenter wrote: > >> On 6 Dec, in article > >> <1165400403.987854.72700@16g2000cwy.googlegroups.com> > >> goister@gmail.com "galapogos" wrote: > .... > >> >I then tried to access the EEPROM with my MCU set as a master. I was > >> >able to get all the way to step 6, but after that, my MCU was still in > >> >master transmitter mode rather than master receiver mode. I have to set > >> >the master to transmit mode for it to send the 2nd device address in > >> >step 5. I thought that the direction bit sent in step 5 would reset the > >> >MCU to be in receiver mode but it didn't. Therefore I'm unable to > >> >continue on to step 7. In fact, I had to hack things up quite a bit to > >> > >> NO direction changes YOU must code, I would suggest when you are sending > >> a READ address (last bit of address = 1), after the ACK then YOU must change > >> the direction. > > > >How do I detect this though. I send the READ address at interrupt n, > >but I expect the ACK at interrupt n+1, so I would need some way of > >detecting something at n+1 to change direction, and the address is long > >gone by then so I can't detect. Other than using the global counter or > >some other global variable I can't think of a way to do so. > > Either from main program flow or knowing how many bytes are being > sent/received. You must have some form of state knowledge, even if your > higher level code is waiting for interupts to complete. I assume you have > some form of flag for how many bytes received. The data in the data > register at addressed or ACK time should be the address including a > READ/WRITE bit to set flow for next bytes. > > Most people run with simple functions and state variables, so they know > that they are receiving an I2C address, having done that note what type > of address and action accordingly. > > Unless your MCU is very busy doing other things I would in this case > test first using code that monitors an interupt flag to signify you have > been Addressed as Slave, then drop to a linear function to test things > first as in > > If I2C address write mode > Read 'n' bytes of EEPROM internal address > SEND ACK > Read 'n' bytes of write data > Send ACK > (if anytime stop or start detected exit) > else > switch mode to transmit > send data byte > Wait for ACK/NOACK > if ACK repeat send data > if NACK wait for stop/start condition > (if anytime stop or start detected > switch to receive mode > exit) > > The waits, sends and receive would be functions. get it working this way > first then look at ways to put it into an interupt function with state > variables about next state, current state, count of bytes if known.
Is the above program flow for the MCU emulating as a slave EEPROM to the master ASIC? I was trying to get the MCU working as a master to an external slave EEPROM to get things working since I thought it would be easier. The above program flow doesn't make sense in this context.
> Starting with interupt functions for I2C is probably trying to run before > you can walk.
I thought interrupts would be easier since the interrupts are well defined(occurs after every ACK), but I'll see if I can do it polling style.
> If you are master you should know from your program flow what you are > trying to achieve. Write as a bunch of linear calls and code to test > handling of I2C controller first, start as master talking to EEPROM > to write a byte, then reset the address and read the byte back. > > >> >even get it working till step 6. For example, I didn't know how to > >> >correctly detect when to restart in step 5, so I detected this by > >> >having a global interrupt counter and restarting when the counter is a > >> >certain value. > >> > >> You send the start condition using the controller to send a start then > >> the Read address. When your MCU is master you do not detect it you > >> generate it. > > > >I think you misunderstood me. I know when conceptually to start and > >restart, and I'm doing this in main(). However, in my ISR, I do a bunch > >of status bit detection to determine what I should do at any given > >time. > > > >On my restart, when I'm sending the READ address in main(), I have to > >keep my status as a master transmitter since I'm sending the READ > >address to the master. However, I think because of this, at the end of > >the ACK for the READ address, I'm still going into the isr code section > >for master transmitter, which is to send more data. Instead, I should > >be going into the master receive code section where the serial buffer > >is free to accept incoming data. Makes sense? Or am I thinking of it > >totally the wrong way? > > You need to determine as a aslave from the LRB (Last received bit) or > a flag when as master that you have sent a read or write address I think > you are expecting too much from a simple I2C controller, all the ones > I have seen expect a lot of control software and state variables, especially > for timeouts and other error trapping. > > >> >I'm sure there must be a proper way of detecting when to restart but I > >> >can't figure out how. As far as my MCU goes, it still thinks it's in > >> >master transmitter mode after sending the device/word address, so I > >> >don't know how to tell it to restart at that point. > >> > >> You do the following steps > >> > >> generate a start coindition > >> transmit the read address, > >> get ACK > >> Change mode to receive > >> Receive bytes > >> last byte Set NOACK > >> Send Stop > > > >Aren't you missing the 1st start condition? i.e. > > No I was talking about after the first Write transaction. The Toshiba > manual does have sections on generating restarts (may not be well written > but it is there).. > > If detecting as a slave see the manual and BB bit for start/stop detection. > > .... > >Like I said, I'm doing fine until step 5. I can do step 7, but then I > >fall into the wrong code segment inside my ISR(master transmitter > >instead of master receiver), and I'm not sure where exactly I can > >change my control/status bit to receive. What I'm thinking is I can't > >change it at the start of step 7 since I'm still transmitting, but the > >next point I can change it is in in the ISR after step 8, and that's > >too late since I'm already supposed to be in receive mode in that stage > >right? I can't change it in the ISR after step 8 since my ISR wouldn't > >know that the READ address was previously sent. All it knows about the > >outside world is what the MCU status bits reveal, which are the > > Whatever you do you will need some way of tracking either as a master > talking to EEPROM, or as a slave emulating a EEPROM what type of > transaction you are doing. probably what state you are in as well > (waiting ack, receiving byte, receiving address, idle....).
I am having trouble with the MCU as a master talking to a slave EEPROM. I added a volatile i2c global state variable and tracking/changing it as the program runs, and I was again stuck at the point when the READ address is sent. If I try to change the direction from transmit to receive at that point, for some reason the MCU stops generating a clock and hence I don't receive anything from the EEPROM. I tried reading the buffer to a temp variable as well as pulling the PIN high. These did not work, contrary to Fig 3.11.15 of the datasheet where it claims that when TRX=0, setting PIN to 1 will cause the MCU to output a serial clock pulse to the SCL to transfer new 1-word of data. In fact, even if I set the TRX bit to what it already is, SCL becomes HIGH all the way. It seems like I can't even touch the TRX bit at all! Now if I leave the TRX bit alone, SCL continues pumping, but the MCU is in master transmitter mode and will pump the buffer to SDA, which isn't what I want if I want to read from the EEPROM.
> >following bits: > >MST - master or slave > >TRX - transmit or receive > >AL - arbitration lost > >AAS - slave address match > >AD0 - GENERAL CALL address match > >BB - bus free > >PIN - serial interrupt cancel > >What else can I do to detect that my previous transmission was a > >"transmit READ address"? > > The data in the data register when slave, and from your programme > as a master you will have the Address used or status somwhere. > Before ACK stage as slave LRB in status register will tell you as well. > See manual for TMP91CP27U Table 3.11.1 . >
galapogos wrote:
> Paul Carpenter wrote: > > On 6 Dec, in article > > <1165421691.608742.42950@l12g2000cwl.googlegroups.com> > > goister@gmail.com "galapogos" wrote: > > > > >Paul Carpenter wrote: > > >> On 6 Dec, in article > > >> <1165400403.987854.72700@16g2000cwy.googlegroups.com> > > >> goister@gmail.com "galapogos" wrote: > > .... > > >> >I then tried to access the EEPROM with my MCU set as a master. I was > > >> >able to get all the way to step 6, but after that, my MCU was still in > > >> >master transmitter mode rather than master receiver mode. I have to set > > >> >the master to transmit mode for it to send the 2nd device address in > > >> >step 5. I thought that the direction bit sent in step 5 would reset the > > >> >MCU to be in receiver mode but it didn't. Therefore I'm unable to > > >> >continue on to step 7. In fact, I had to hack things up quite a bit to > > >> > > >> NO direction changes YOU must code, I would suggest when you are sending > > >> a READ address (last bit of address = 1), after the ACK then YOU must change > > >> the direction. > > > > > >How do I detect this though. I send the READ address at interrupt n, > > >but I expect the ACK at interrupt n+1, so I would need some way of > > >detecting something at n+1 to change direction, and the address is long > > >gone by then so I can't detect. Other than using the global counter or > > >some other global variable I can't think of a way to do so. > > > > Either from main program flow or knowing how many bytes are being > > sent/received. You must have some form of state knowledge, even if your > > higher level code is waiting for interupts to complete. I assume you have > > some form of flag for how many bytes received. The data in the data > > register at addressed or ACK time should be the address including a > > READ/WRITE bit to set flow for next bytes. > > > > Most people run with simple functions and state variables, so they know > > that they are receiving an I2C address, having done that note what type > > of address and action accordingly. > > > > Unless your MCU is very busy doing other things I would in this case > > test first using code that monitors an interupt flag to signify you have > > been Addressed as Slave, then drop to a linear function to test things > > first as in > > > > If I2C address write mode > > Read 'n' bytes of EEPROM internal address > > SEND ACK > > Read 'n' bytes of write data > > Send ACK > > (if anytime stop or start detected exit) > > else > > switch mode to transmit > > send data byte > > Wait for ACK/NOACK > > if ACK repeat send data > > if NACK wait for stop/start condition > > (if anytime stop or start detected > > switch to receive mode > > exit) > > > > The waits, sends and receive would be functions. get it working this way > > first then look at ways to put it into an interupt function with state > > variables about next state, current state, count of bytes if known. > > Is the above program flow for the MCU emulating as a slave EEPROM to > the master ASIC? I was trying to get the MCU working as a master to an > external slave EEPROM to get things working since I thought it would be > easier. The above program flow doesn't make sense in this context. > > > Starting with interupt functions for I2C is probably trying to run before > > you can walk. > > I thought interrupts would be easier since the interrupts are well > defined(occurs after every ACK), but I'll see if I can do it polling > style. > > > If you are master you should know from your program flow what you are > > trying to achieve. Write as a bunch of linear calls and code to test > > handling of I2C controller first, start as master talking to EEPROM > > to write a byte, then reset the address and read the byte back. > > > > >> >even get it working till step 6. For example, I didn't know how to > > >> >correctly detect when to restart in step 5, so I detected this by > > >> >having a global interrupt counter and restarting when the counter is a > > >> >certain value. > > >> > > >> You send the start condition using the controller to send a start then > > >> the Read address. When your MCU is master you do not detect it you > > >> generate it. > > > > > >I think you misunderstood me. I know when conceptually to start and > > >restart, and I'm doing this in main(). However, in my ISR, I do a bunch > > >of status bit detection to determine what I should do at any given > > >time. > > > > > >On my restart, when I'm sending the READ address in main(), I have to > > >keep my status as a master transmitter since I'm sending the READ > > >address to the master. However, I think because of this, at the end of > > >the ACK for the READ address, I'm still going into the isr code section > > >for master transmitter, which is to send more data. Instead, I should > > >be going into the master receive code section where the serial buffer > > >is free to accept incoming data. Makes sense? Or am I thinking of it > > >totally the wrong way? > > > > You need to determine as a aslave from the LRB (Last received bit) or > > a flag when as master that you have sent a read or write address I think > > you are expecting too much from a simple I2C controller, all the ones > > I have seen expect a lot of control software and state variables, especially > > for timeouts and other error trapping. > > > > >> >I'm sure there must be a proper way of detecting when to restart but I > > >> >can't figure out how. As far as my MCU goes, it still thinks it's in > > >> >master transmitter mode after sending the device/word address, so I > > >> >don't know how to tell it to restart at that point. > > >> > > >> You do the following steps > > >> > > >> generate a start coindition > > >> transmit the read address, > > >> get ACK > > >> Change mode to receive > > >> Receive bytes > > >> last byte Set NOACK > > >> Send Stop > > > > > >Aren't you missing the 1st start condition? i.e. > > > > No I was talking about after the first Write transaction. The Toshiba > > manual does have sections on generating restarts (may not be well written > > but it is there).. > > > > If detecting as a slave see the manual and BB bit for start/stop detection. > > > > .... > > >Like I said, I'm doing fine until step 5. I can do step 7, but then I > > >fall into the wrong code segment inside my ISR(master transmitter > > >instead of master receiver), and I'm not sure where exactly I can > > >change my control/status bit to receive. What I'm thinking is I can't > > >change it at the start of step 7 since I'm still transmitting, but the > > >next point I can change it is in in the ISR after step 8, and that's > > >too late since I'm already supposed to be in receive mode in that stage > > >right? I can't change it in the ISR after step 8 since my ISR wouldn't > > >know that the READ address was previously sent. All it knows about the > > >outside world is what the MCU status bits reveal, which are the > > > > Whatever you do you will need some way of tracking either as a master > > talking to EEPROM, or as a slave emulating a EEPROM what type of > > transaction you are doing. probably what state you are in as well > > (waiting ack, receiving byte, receiving address, idle....). > > I am having trouble with the MCU as a master talking to a slave EEPROM. > I added a volatile i2c global state variable and tracking/changing it > as the program runs, and I was again stuck at the point when the READ > address is sent. If I try to change the direction from transmit to > receive at that point, for some reason the MCU stops generating a clock > and hence I don't receive anything from the EEPROM. I tried reading the > buffer to a temp variable as well as pulling the PIN high. These did > not work, contrary to Fig 3.11.15 of the datasheet where it claims that > when TRX=0, setting PIN to 1 will cause the MCU to output a serial > clock pulse to the SCL to transfer new 1-word of data. In fact, even if > I set the TRX bit to what it already is, SCL becomes HIGH all the way. > It seems like I can't even touch the TRX bit at all! > > Now if I leave the TRX bit alone, SCL continues pumping, but the MCU is > in master transmitter mode and will pump the buffer to SDA, which isn't > what I want if I want to read from the EEPROM.
I tried coding it linear style rather than using interrupts, and again I'm getting stuck after the restart, right after the read address is sent by the MCU to the EEPROM. Whenever I modify the TRX bit, SCL will stop. I looked at the restart documentation, and it says that after a restart I should generate a new start condition by following 3.11.6(2) under Master. In that section it states the steps that I should follow to generate a start bit. This is identical to the first start bit that I generated, and consists of the following instructions SBI0CR1 |= 0x10; // set SBI0CR1<ACK> to 1 SBI0DBR = 0xa1; // send READ address SBI0CR2 = BIN_11111000; // write "1" to MST, TRX, BB, PIN That section also states that "when an interrupt request generate, the <TRX> is changed according to the direction bit only when an acknowledge signal is returned from the slave device." This seems to suggest that TRX changes are automatic rather than me changing it. I verified that I'm indeed getting an ACK from the slave by looking at my logic analyzer timing waveform as well as checking that the LRB right after the read address is sent is "0". Since I'm getting an ACK and my direction bit is 1, why isn't TRX being reset to 0? Is there a bug with my emulator or am I misunderstanding the datasheet?
galapogos wrote:
> galapogos wrote: > > Paul Carpenter wrote: > > > On 6 Dec, in article > > > <1165421691.608742.42950@l12g2000cwl.googlegroups.com> > > > goister@gmail.com "galapogos" wrote: > > > > > > >Paul Carpenter wrote: > > > >> On 6 Dec, in article > > > >> <1165400403.987854.72700@16g2000cwy.googlegroups.com> > > > >> goister@gmail.com "galapogos" wrote: > > > .... > > > >> >I then tried to access the EEPROM with my MCU set as a master. I was > > > >> >able to get all the way to step 6, but after that, my MCU was still in > > > >> >master transmitter mode rather than master receiver mode. I have to set > > > >> >the master to transmit mode for it to send the 2nd device address in > > > >> >step 5. I thought that the direction bit sent in step 5 would reset the > > > >> >MCU to be in receiver mode but it didn't. Therefore I'm unable to > > > >> >continue on to step 7. In fact, I had to hack things up quite a bit to > > > >> > > > >> NO direction changes YOU must code, I would suggest when you are sending > > > >> a READ address (last bit of address = 1), after the ACK then YOU must change > > > >> the direction. > > > > > > > >How do I detect this though. I send the READ address at interrupt n, > > > >but I expect the ACK at interrupt n+1, so I would need some way of > > > >detecting something at n+1 to change direction, and the address is long > > > >gone by then so I can't detect. Other than using the global counter or > > > >some other global variable I can't think of a way to do so. > > > > > > Either from main program flow or knowing how many bytes are being > > > sent/received. You must have some form of state knowledge, even if your > > > higher level code is waiting for interupts to complete. I assume you have > > > some form of flag for how many bytes received. The data in the data > > > register at addressed or ACK time should be the address including a > > > READ/WRITE bit to set flow for next bytes. > > > > > > Most people run with simple functions and state variables, so they know > > > that they are receiving an I2C address, having done that note what type > > > of address and action accordingly. > > > > > > Unless your MCU is very busy doing other things I would in this case > > > test first using code that monitors an interupt flag to signify you have > > > been Addressed as Slave, then drop to a linear function to test things > > > first as in > > > > > > If I2C address write mode > > > Read 'n' bytes of EEPROM internal address > > > SEND ACK > > > Read 'n' bytes of write data > > > Send ACK > > > (if anytime stop or start detected exit) > > > else > > > switch mode to transmit > > > send data byte > > > Wait for ACK/NOACK > > > if ACK repeat send data > > > if NACK wait for stop/start condition > > > (if anytime stop or start detected > > > switch to receive mode > > > exit) > > > > > > The waits, sends and receive would be functions. get it working this way > > > first then look at ways to put it into an interupt function with state > > > variables about next state, current state, count of bytes if known. > > > > Is the above program flow for the MCU emulating as a slave EEPROM to > > the master ASIC? I was trying to get the MCU working as a master to an > > external slave EEPROM to get things working since I thought it would be > > easier. The above program flow doesn't make sense in this context. > > > > > Starting with interupt functions for I2C is probably trying to run before > > > you can walk. > > > > I thought interrupts would be easier since the interrupts are well > > defined(occurs after every ACK), but I'll see if I can do it polling > > style. > > > > > If you are master you should know from your program flow what you are > > > trying to achieve. Write as a bunch of linear calls and code to test > > > handling of I2C controller first, start as master talking to EEPROM > > > to write a byte, then reset the address and read the byte back. > > > > > > >> >even get it working till step 6. For example, I didn't know how to > > > >> >correctly detect when to restart in step 5, so I detected this by > > > >> >having a global interrupt counter and restarting when the counter is a > > > >> >certain value. > > > >> > > > >> You send the start condition using the controller to send a start then > > > >> the Read address. When your MCU is master you do not detect it you > > > >> generate it. > > > > > > > >I think you misunderstood me. I know when conceptually to start and > > > >restart, and I'm doing this in main(). However, in my ISR, I do a bunch > > > >of status bit detection to determine what I should do at any given > > > >time. > > > > > > > >On my restart, when I'm sending the READ address in main(), I have to > > > >keep my status as a master transmitter since I'm sending the READ > > > >address to the master. However, I think because of this, at the end of > > > >the ACK for the READ address, I'm still going into the isr code section > > > >for master transmitter, which is to send more data. Instead, I should > > > >be going into the master receive code section where the serial buffer > > > >is free to accept incoming data. Makes sense? Or am I thinking of it > > > >totally the wrong way? > > > > > > You need to determine as a aslave from the LRB (Last received bit) or > > > a flag when as master that you have sent a read or write address I think > > > you are expecting too much from a simple I2C controller, all the ones > > > I have seen expect a lot of control software and state variables, especially > > > for timeouts and other error trapping. > > > > > > >> >I'm sure there must be a proper way of detecting when to restart but I > > > >> >can't figure out how. As far as my MCU goes, it still thinks it's in > > > >> >master transmitter mode after sending the device/word address, so I > > > >> >don't know how to tell it to restart at that point. > > > >> > > > >> You do the following steps > > > >> > > > >> generate a start coindition > > > >> transmit the read address, > > > >> get ACK > > > >> Change mode to receive > > > >> Receive bytes > > > >> last byte Set NOACK > > > >> Send Stop > > > > > > > >Aren't you missing the 1st start condition? i.e. > > > > > > No I was talking about after the first Write transaction. The Toshiba > > > manual does have sections on generating restarts (may not be well written > > > but it is there).. > > > > > > If detecting as a slave see the manual and BB bit for start/stop detection. > > > > > > .... > > > >Like I said, I'm doing fine until step 5. I can do step 7, but then I > > > >fall into the wrong code segment inside my ISR(master transmitter > > > >instead of master receiver), and I'm not sure where exactly I can > > > >change my control/status bit to receive. What I'm thinking is I can't > > > >change it at the start of step 7 since I'm still transmitting, but the > > > >next point I can change it is in in the ISR after step 8, and that's > > > >too late since I'm already supposed to be in receive mode in that stage > > > >right? I can't change it in the ISR after step 8 since my ISR wouldn't > > > >know that the READ address was previously sent. All it knows about the > > > >outside world is what the MCU status bits reveal, which are the > > > > > > Whatever you do you will need some way of tracking either as a master > > > talking to EEPROM, or as a slave emulating a EEPROM what type of > > > transaction you are doing. probably what state you are in as well > > > (waiting ack, receiving byte, receiving address, idle....). > > > > I am having trouble with the MCU as a master talking to a slave EEPROM. > > I added a volatile i2c global state variable and tracking/changing it > > as the program runs, and I was again stuck at the point when the READ > > address is sent. If I try to change the direction from transmit to > > receive at that point, for some reason the MCU stops generating a clock > > and hence I don't receive anything from the EEPROM. I tried reading the > > buffer to a temp variable as well as pulling the PIN high. These did > > not work, contrary to Fig 3.11.15 of the datasheet where it claims that > > when TRX=0, setting PIN to 1 will cause the MCU to output a serial > > clock pulse to the SCL to transfer new 1-word of data. In fact, even if > > I set the TRX bit to what it already is, SCL becomes HIGH all the way. > > It seems like I can't even touch the TRX bit at all! > > > > Now if I leave the TRX bit alone, SCL continues pumping, but the MCU is > > in master transmitter mode and will pump the buffer to SDA, which isn't > > what I want if I want to read from the EEPROM. > > I tried coding it linear style rather than using interrupts, and again > I'm getting stuck after the restart, right after the read address is > sent by the MCU to the EEPROM. Whenever I modify the TRX bit, SCL will > stop. I looked at the restart documentation, and it says that after a > restart I should generate a new start condition by following 3.11.6(2) > under Master. In that section it states the steps that I should follow > to generate a start bit. This is identical to the first start bit that > I generated, and consists of the following instructions > > SBI0CR1 |= 0x10; // set SBI0CR1<ACK> to 1 > SBI0DBR = 0xa1; // send READ address > SBI0CR2 = BIN_11111000; // write "1" to MST, TRX, BB, PIN > > That section also states that "when an interrupt request generate, the > <TRX> is changed according to the direction bit only when an > acknowledge signal is returned from the slave device." This seems to > suggest that TRX changes are automatic rather than me changing it. I > verified that I'm indeed getting an ACK from the slave by looking at my > logic analyzer timing waveform as well as checking that the LRB right > after the read address is sent is "0". Since I'm getting an ACK and my > direction bit is 1, why isn't TRX being reset to 0? Is there a bug with > my emulator or am I misunderstanding the datasheet?
I wish there was a way to edit posts, but anyway, after getting stuck in the above situation, I decided to give linear coding a go with the MCU as the slave and the ASIC as the master. After going at it a few times, I actually managed to get the MCU to send data to the ASIC! I didn't even use any state flags or byte count. The handshaking sequence is hardcoded as per the expected timing diagram, and the how many bytes is determined by checking the LRB status bit. Also, I didn't even need to change the TRX bit after the 2nd device address is sent by the ASIC. As I suspected, the MCU does this automatically, presumably by checking the 8th(direction) bit of the transmission and seeing if it's a 1 or a 0. I don't know why this doesn't work when the MCU is in master mode though. In any case, the current code, though lengthy and messy, is sufficient for my application, but I will probably try and clean it up and make it more general purpose rather than hard coded, and maybe implement it with interrupts. I noticed that in the ASIC's datasheet as well as the logic analyzer, after the transmission is done and the ASIC sends its STOP bit, the SCL line is kept low, therefore the bus is not freed. Is this weird or normal? It doesn't really matter in this case I guess since there are only 2 devices on the bus and only 1 transaction being performed. I also noticed that between the end of every MCU ACK and the start of every data byte sent, there is a glitch on the SDA line where it goes to HIGH for a very short period of time(<half a clock period) and then comes down again(if the data bit is 0). According to the I2C specs the data on the SDA line must be stable during the HIGH period of the clock, so does that mean that this glitch is ok since it only occurs for a part of the LOW period of the clock?
On 6 Dec, in article
     <1165461838.962328.84100@l12g2000cwl.googlegroups.com>
     goister@gmail.com "galapogos" wrote:

>Paul Carpenter wrote: >> On 6 Dec, in article >> <1165421691.608742.42950@l12g2000cwl.googlegroups.com> >> goister@gmail.com "galapogos" wrote:
...
>I am having trouble with the MCU as a master talking to a slave EEPROM. >I added a volatile i2c global state variable and tracking/changing it >as the program runs, and I was again stuck at the point when the READ >address is sent. If I try to change the direction from transmit to >receive at that point, for some reason the MCU stops generating a clock >and hence I don't receive anything from the EEPROM. I tried reading the >buffer to a temp variable as well as pulling the PIN high. These did >not work, contrary to Fig 3.11.15 of the datasheet where it claims that >when TRX=0, setting PIN to 1 will cause the MCU to output a serial >clock pulse to the SCL to transfer new 1-word of data. In fact, even if >I set the TRX bit to what it already is, SCL becomes HIGH all the way. >It seems like I can't even touch the TRX bit at all!
That sounds like you are changing the Master/Slave bit as well, even temporarily changing a controller from Master to Slave and back again will screw things up. Make sure you bit manipulations are doing what you think they are doing, even if you have to keep a memory copy of what was last written to the device.
>Now if I leave the TRX bit alone, SCL continues pumping, but the MCU is >in master transmitter mode and will pump the buffer to SDA, which isn't >what I want if I want to read from the EEPROM.
I still think you are (even unintentionally changing the Master/Slave bit) that is the most likely reason that will stop 'clocks', actually probably resetting controller to idle state (waiting for start).
>> >following bits: >> >MST - master or slave >> >TRX - transmit or receive >> >AL - arbitration lost >> >AAS - slave address match >> >AD0 - GENERAL CALL address match >> >BB - bus free >> >PIN - serial interrupt cancel >> >What else can I do to detect that my previous transmission was a >> >"transmit READ address"?
-- 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
On 6 Dec, in article
     <1165465416.997980.78380@80g2000cwy.googlegroups.com>
     goister@gmail.com "galapogos" wrote:

>galapogos wrote: >> Paul Carpenter wrote: >> > On 6 Dec, in article >> > <1165421691.608742.42950@l12g2000cwl.googlegroups.com> >> > goister@gmail.com "galapogos" wrote: >> > >> > >Paul Carpenter wrote: >> > >> On 6 Dec, in article >> > >> <1165400403.987854.72700@16g2000cwy.googlegroups.com> >> > >> goister@gmail.com "galapogos" wrote: >> > .... >> > >> >I then tried to access the EEPROM with my MCU set as a master. I was >> > >> >able to get all the way to step 6, but after that, my MCU was still in
...
>I tried coding it linear style rather than using interrupts, and again >I'm getting stuck after the restart, right after the read address is >sent by the MCU to the EEPROM. Whenever I modify the TRX bit, SCL will >stop. I looked at the restart documentation, and it says that after a >restart I should generate a new start condition by following 3.11.6(2) >under Master. In that section it states the steps that I should follow >to generate a start bit. This is identical to the first start bit that >I generated, and consists of the following instructions > >SBI0CR1 |= 0x10; // set SBI0CR1<ACK> to 1 >SBI0DBR = 0xa1; // send READ address
So you have sent the read address here to the register, then IMMEDIATELY issue a start condition. The data will not have been shifted out of the register to the bus. You need to wait for the PIN and other status bit changes to indicate the address has been sent and check the ACK bit, BEfore doing a RESTART. Your processor is executing instructions many times faster than the bit rate of I2C.
>SBI0CR2 = BIN_11111000; // write "1" to MST, TRX, BB, PIN > >That section also states that "when an interrupt request generate, the ><TRX> is changed according to the direction bit only when an >acknowledge signal is returned from the slave device." This seems to >suggest that TRX changes are automatic rather than me changing it. I
NO NO it says it will change depending on the direction bit (in the register) and that it changes AFTER the ACK bit from a slave has been received. You change the bit but the direction is read at ACK time. The important thing is YOU have to change the bits direction. The other important things is to do it at the RIGHT time, and WAIT for things to happen, and receive status bits back.
>verified that I'm indeed getting an ACK from the slave by looking at my >logic analyzer timing waveform as well as checking that the LRB right >after the read address is sent is "0". Since I'm getting an ACK and my >direction bit is 1, why isn't TRX being reset to 0? Is there a bug with >my emulator or am I misunderstanding the datasheet?
I have never come across an I2C controller that changes direction, without being instructed to, from software. -- 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 6 Dec, in article > <1165465416.997980.78380@80g2000cwy.googlegroups.com> > goister@gmail.com "galapogos" wrote: > > >galapogos wrote: > >> Paul Carpenter wrote: > >> > On 6 Dec, in article > >> > <1165421691.608742.42950@l12g2000cwl.googlegroups.com> > >> > goister@gmail.com "galapogos" wrote: > >> > > >> > >Paul Carpenter wrote: > >> > >> On 6 Dec, in article > >> > >> <1165400403.987854.72700@16g2000cwy.googlegroups.com> > >> > >> goister@gmail.com "galapogos" wrote: > >> > .... > >> > >> >I then tried to access the EEPROM with my MCU set as a master. I was > >> > >> >able to get all the way to step 6, but after that, my MCU was still in > ... > > >I tried coding it linear style rather than using interrupts, and again > >I'm getting stuck after the restart, right after the read address is > >sent by the MCU to the EEPROM. Whenever I modify the TRX bit, SCL will > >stop. I looked at the restart documentation, and it says that after a > >restart I should generate a new start condition by following 3.11.6(2) > >under Master. In that section it states the steps that I should follow > >to generate a start bit. This is identical to the first start bit that > >I generated, and consists of the following instructions > > > >SBI0CR1 |= 0x10; // set SBI0CR1<ACK> to 1 > >SBI0DBR = 0xa1; // send READ address > > So you have sent the read address here to the register, then > IMMEDIATELY issue a start condition. The data will not have been > shifted out of the register to the bus. > > You need to wait for the PIN and other status bit changes to indicate > the address has been sent and check the ACK bit, BEfore doing a RESTART. > > Your processor is executing instructions many times faster than the bit > rate of I2C.
Hmm, I didn't think of that. I was even worried that fetching the data from an array and putting it in SBI0DBR would be too slow. Anyway, the datasheet says the following regarding START condition generation: Check a bus free status(when <BB> = 0)Set the SBI0CR1<ACK> to 1 and specify a slave address and direction bit to be transmitted to the SBI0DBR. When SBI0CR2<BB> = 0, the start condition is generated by writing 1111 to SBI0CR2<MST, TRX, BB, PIN>. It doesn't say anything about any delay between setting SBDI0DBR and writing 1111 to SBI0CR2<MST, TRX, BB, PIN>., only that I should check BB, which I already have. I don't understand what you mean by waiting for the status bits to change to indicate the address has been sent and check the ACK bit. If the read address has been sent and the slave's ACK has been received, I'm already 1 byte ahead of the RESTART aren't I? I think the whole point of setting those bits the 1111 is to trigger the sending of the read address. From my understanding no bits will change until I change those bits, so I can't be waiting for them to change when I'm supposed to change them?
> >SBI0CR2 = BIN_11111000; // write "1" to MST, TRX, BB, PIN > > > >That section also states that "when an interrupt request generate, the > ><TRX> is changed according to the direction bit only when an > >acknowledge signal is returned from the slave device." This seems to > >suggest that TRX changes are automatic rather than me changing it. I > > NO NO it says it will change depending on the direction bit (in the register) > and that it changes AFTER the ACK bit from a slave has been received.
Hmm isn't that what I said? So say I write the read address/direction bit of 0xA1 into SBI0DBR(the register/buffer), the address will be 1010000b and the direction bit is 1(read). When the slave ACKs this, TRX will change depending to 0 since direction bit is 1(doesn't seem to happen)? Or when the slave ACKs this(and PIN goes to 0), I must change TRX to 0(tried this but didn't work)?
> You change the bit but the direction is read at ACK time.
I change the TRX bit? Why is the direction read at all if I'm the one who changes the TRX?
> The important thing is YOU have to change the bits direction. > > The other important things is to do it at the RIGHT time, and WAIT > for things to happen, and receive status bits back.
So when is the right time, and what things do I have to wait for? I'm really confused about this part. I don't have my code with me right now but here's the sequence of events that I can think of for a restart when a master MCU is addressing a slave EEPROM: 1) Wait for bus to be free(<BB> = 0) 2) Set <ACK> to 1 3) Set SBI0DBR to read address(0xA1) 4) Write 1111 to <MST, TRX, BB, PIN> 5) Wait for PIN to be 0(indicating ACK/NACK received) 6) Read SBI0DBR to data array 7) Wait for PIN to be 0 8) Back to 6 until all bytes have been received If I'm understanding you correctly, somewhere along the line between steps 4 and 6 I have to change TRX to 0 to make the MCU a receiver? When exactly do I need to do so and what conditions do I have to wait for? <MST, BB> are both 1 throughout the transmission, and <PIN> changes to 0 only when I get an ACK/NACK, so those won't indicate anything. TRX is what I'm supposed to change so I can't wait on that. I can't think of any other status bits that will indicate when I need to set TRX to 0.