This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430F5308: MSP430F5308 i2c USCI slave Transmit clock stretch issue

Part Number: MSP430F5308

Hi, 

Master:  MCP2221 microchip USB to i2c bridge.   Driver is the standard MCP Linux driver.  100khz i2c bus speed.

Slave:  MSP430F5308 @ 8mhz using the USCI peripheral and slightly modified TI sample code.

Test Equipment:  LeCroy Scope with built in i2c bus analyzer.  Ardvaark/Beagle TotalPhase I2c Packet Analyzer.   Effective resistance on the i2c pullups is roughly 2K and the edges look nice and sharp at 100khz, with the i2c waveforms just over 0v and all the way up to 3.3v.

Problem:  When the MCP2221 requests a Slave Transmit of a single 8 byte packet, there is no ACK clock generated by the MCP2221, causing the state machine to break on both sides.  Speed 100khz I2c.  8mhz F5308 clock.  

Analysis:  After extensive troubleshooting, it appears that when the MSP430 is running at 8 mhz, it requires something in the neighborhood of 8us to respond to the incoming 7 bit address +R/W, and then to release the clock (ie - we think the 430 is stretching the clock), when it does release the clock for the MCP to initiate an ACK pulse, the MCP2221 doesn't react correctly and instead of sending the ACK, just starts clocking the Data word.  We hypothesize the 8us is required by the 430 to process "is this address for me" and to interpret the R/W bit.

This only happens on a Slave Transmit, not a Slave write.  When the clock speed of the MSP430 is increased to 16 or 24mhz, the MCP generates the ACK correctly and everything works normally.  There was one observed condition with another programmers code also using the USCI, but on another family of MSP430, where the ACK pulse is 1/4 normal 100 khz pulse width, pointing us toward speeding up the MSP430 clock fixing the issue.  This code was also fixed (ie - the clock pulse returned to normal width) by increasing the 430 code speed and further substantiates the clock stretching theory. 

We ran some tests at higher clock rates on the MSP430 and if the clock speed is increased beyond 8mhz to say 16 or 24mhz, it appears that it takes less time to release the clock in roughly a time delay proportional to the clock speed increase.  This allows greater i2c speeds, however is a workaround for the MCP2221 not accepting clock stretching correctly.

Of course we are working with Microchip to see if we can reprogram the driver of the MCP2221 to play nicer with clock stretching but in the mean time:

Questions:  

1) Any idea why we see the problem on the Slave Transmit and not a Slave Receive?

2) Is the turnaround delay between the Address and the ACK dependent on purely on clock cycles on the MSP430 or is there RC/Analog/Propogation type delay we are dealing with.

3) Is there some setting or code we are missing that would make the MSP430 not insert a clock stretch delay between the R/W bit and the ACK (ie, can we speed up the time it takes for the 430 to release the bus on an I2c slave transmit ACK)? 

Thanks!  Blake

  • Blake,

    What clock is the module using (ACLCK/SMCLK/MCLK), and what frequency is that set to? Even though you have MCLK at 8MHz, you could be clocking off of ACLK at 32kHz. Can you get the setup code for the module?

    As far as seeing it in slave transmit versus receive, I'm assuming you are using a repeated Start to switch to slave transmit. If so, you maybe running into the following erratum. USCI35.
  • Hi Jace,

    Basically, we are using something very close to the sample code setup routines:

     UCB1CTL1 |= UCSWRST;     // Enable SW reset, disable P4

     UCB1CTL0 = UCMODE_3 | UCSYNC;   // I2C Slave, synchronous mode
     UCB1I2COA = SLAVE_I2C_ADDRESS;    
     UCB1CTL1 &= ~UCSWRST;     // Clear SW reset, resume operation
     UCB1IE |= UCSTPIE | UCSTTIE | UCTXIE| UCRXIE;     // Enable STT,STP,TX,RX interrupt                                 

    From a quick look at the family manual, the i2c clock appears to be selected by UCSSELx in the UCBxCTL1 register, which defaults to a 00 which seems to indicate UCLK.   However, we are in Slave mode on the 430, and 38.3.5 says:  "in slave mode, the bit clock generator is not used and the UCSSELx bits are don't care."  I can set a 10b in UCSSELx if you think it might help (moving the clock to SMCLK), but it would appear it isn't used on the slave transmit (I hope I'm wrong as this would be a super easy fix).

    Same issue with USCI35 as it looks like it just deals with master mode from what I can tell (and we are operating in slave mode).

    Thanks for your help!

  • Blake,

    Yes you are right, USCI35 for this part only affects master mode. Sorry for the confusion. Yes, in slave mode you are being clocked by the master so the clock setting wouldn't matter. Are you using any LPMs for this? It could be the LPM wake up time that's affecting you here.
  • Hi Jace,

    We removed all LPM calls so the processor is awake and running full speed at all times. Is the internal processor clock clocking the i2c state machine? If so - it would seem that 8us is a long time to decode an 'is the address for me' and decide if it is a R or W. Perhaps Germany could shed some light on how the state machine operates, as I don't particularly see any detail.
  • Blake,

    I'm a little confused on the 8us figure here as that is as much time as a clock cycle of 100kHz I2C comms. Now the time it takes for the part to identify itself can be dependent on your part clock speed. Please see screen captures below. One of an MSP430F5529LP (same USCI module and clock system) slave transmit at 1MHz DCO and the other at 8MHz DCO. (With 100kHz clock, one cycle is ~9.5us on I2C line. @8MHz DCO, this time is stretched slightly to ~12us and at 1MHz DCO its stretched to ~60us.)

    [8MHZ DCO]

    [8MHZ DCO]

    [1MHz DCO]

  • Jace,

    Interesting... So basically, what you are seeing is linear scaling (somewhat anyway) of the ACK clock stretch that the slave takes based on DCO clock speed. Kind of what we were seeing. We saw this value vary slightly between 3 processors all using the USCI. So this is normal behavior I guess. Odd that we don't see the same stretch time when the master is sending data than when the Slave is sending data back to the Master.

    The good news is that we booted up the Microchip demo board and under windows it handles the clock stretch from the slave elegantly. Under Linux it does not. This points to a Linux driver configuration issue. We are pursuing a fix on that front.

    So we should be able to solve the immediate problem, but our side would still like some type of quantization of the timing. Perhaps as simple as:

    @ 100Khz, 1mhz = 60us, 8mhz = 12us etc.

    Any ideas why the stretch differential on Slave read vs write, and should we go to the design team for some logic or try and wing it with what we have?
  • Hi Jace,

    The customer pinged me today and asked why the clock stretch on the Read but not on the Write? It would seem both read and write have to do the same Address decode. You would think it the state machine were clocked by the 8mhz clock, it would take no time at all to match them, instead of 9.5uS. Were you planning on asking any of the design team if they can provide any clarity?

    Sadly, the MCP2221 is actually a preprogramed PIC18 and so the code is off limits and configurability is almost 'nil. We are planning to change a couple of Linux timeouts, but after that, we are toast. It would be nice if we could rule out speeding up the state machine.

    Have a great weekend.
  • To close out on this thread,

    The dependency outlined in this thread can be described in the following. A Read on a slave is actually a slave writing to the master. If the slave is not ready to write to the master, it will clock stretch the line until the Txbuff is filled. Once the Txbuff is ready, it releases the line (and acknowledges) for the master will start clocking the byte to be read (slave tx’d) as soon as I gets the acknowledge. If you don’t have the clock stretch here and you could potentially not have the correct data clocked out of the Txbuff of the slave. So it’s not necessarily the reception of the address that’s taking so much time, but the readying of the byte to be read by the master.

**Attention** This is a public forum