Menu

I2C and processor speed

2020-01-10
2020-01-14
  • David Stephenson

    I use quite a lot of I2C 16x2 lcd displays. They all have the ST7032 controller.
    I have spent a few hours trying to work out why my newer displays were not working.
    Turns out that the newer ones will not work with the processor running at 1MHz (older ones have no problem).
    Putting the processor up to 4 MHz sloves the problem.
    Strange as the displays are all from Midas MCCOG21605 and all calm to have a ST7032 controller.
    Anyway something to watch out for.

     
  • JANIS

    JANIS - 2020-01-11

    And what is the solution? Are you looking for a display that has a processor higher than 1MHz? I have no experience yet, but I am thinking of building something soon.

     
  • Anobium

    Anobium - 2020-01-11

    Yes, I had lots of questions like this.

    AVR or PIC?
    What chip family specifically?
    Software or Hardware I2C?
    I2C or i2c2? or both?
    If a K42 or K-Mode Hardware I2C what were the setting in PPS? and the port attributes?
    Operating voltage of the chip?
    Operating voltage of the I2C data clock?
    Any level shifter involved?
    What was the resistors used?
    Using the Great Cow BASIC LCD type? LCD_IO 10 or 12?
    Standard LCD command set via I2C, or, you own command set?
    any used of #DEFINE LCD_SPEED FAST or SLOW?

    I am sure Bill will have more questions as he is updating LCD.h at the moment. And, he know the library very well.

     
  • David Stephenson

    16F18326, HI2C2. The code is below.

    #chip 16F18326,4
    #config RSTOSC=hfint1, MCLRE=Off, WDTE=off, boren=off
    unlockpps
                SSP2CLKPPS = 0x0015    'RC5 > SCK2
                RC5PPS = 0x001A    'SCK2 > RC5 (bi-directional)
                RC4PPS = 0x001B    'SDA2 > RC4
                SSP2DATPPS = 0x0014    'RC4 > SDA2 (bi-directional)
                lockpps
    #define hi2c2_BAUD_RATE 400
    #define hi2c2_DATA PORTC.4
    #define hi2c2_CLOCK PORTC.5
    Dir hi2c2_DATA in
    Dir hi2c2_CLOCK in
    hi2c2Mode Master
    WPUC=B'00110000' 'wpu for i2C
    

    As I said the strange thing is that it works for the displays I bought some time ago at 1MHz, but the newer ones seem to need a higher processor clock rate(4 MHz - as shown above).
    And yes for short connections <30 cm the WPU is sufficient for the pull-ups.
    Both the chip and display are running on 2xAA so nominally 3V.
    I use my own routines to initialize the display and write to the screen. The screen just uses (almost) standard ASCII so it is easy.

     
  • William Roth

    William Roth - 2020-01-11

    Looks like the manufacturer changed the silicon. Midas says the display uses "ST7032i or equivalent". I am guessing you got some "equivalents."

     
  • David Stephenson

    I've been looking at the datasheet and it would seem that the baud rate is generated from the Fosc.
    So maybe I have been lucky to get it to work at all using Fosc=1MHz and baud rate 400 kHz.
    I've tried reducing the baud rate to 100 kHz and everything works with Fosc=1 MHz.
    I had been assuming that the MSSP module had its own oscillator and it would seem I was wrong.
    Is this something that should go in the documentation?

     
  • David Stephenson

    I've had a look at the ASM generated.
    With Fosc=1 MHz, Baud rate 100, SSP2ADD=1.
    with Fosc=1MHz, baud rate 400, SSP2ADD=127.
    SSPxADD=1 should give a baud rate of 125 kHz and SSPxADD=127 baud rate 2 kHz.
    So the problem seems that for unrealistic values of Fosc the value assigned to SSPxADD is erroneous.
    Maybe there should be a compiler warning with Fosc=x , max baud rate is x/4 and set SSPxADD to a value of 0 for all these cases.

     
  • Anobium

    Anobium - 2020-01-12

    I am not understanding.

    As I have taken the code you posted above. It does not compile as you have a mix of I2C and I2C2. Is this the cause?

    This compiles. For the purpose of trying to understand the SPPADD I am ignore PPS.

    #chip 16F18326,4
    
    #define hi2c_BAUD_RATE 400
    #define hi2c_DATA PORTC.4
    #define hi2c_CLOCK PORTC.5
    Dir hi2c_DATA in
    Dir hi2c_CLOCK in
    hi2cMode Master
    

    Using this as the basline code, as this compiles. What is the SPPADD issue?

     
  • Anobium

    Anobium - 2020-01-12

    So, may I ask you create a list of test cases so I can understand the issue?

    A simple table of frequencies and the expected outcomes for the registers it what is needed to sort this for all.

     
  • Anobium

    Anobium - 2020-01-12

    I can already see what is happening in terms of the register not being set correctly

    For the following code what should SSPxADD be?

    #chip 16F18326,1
    
    #define hi2c_BAUD_RATE 400
    #define hi2c_DATA PORTC.4
    #define hi2c_CLOCK PORTC.5
    Dir hi2c_DATA in
    Dir hi2c_CLOCK in
    hi2cMode Master
    

    I would the same for SSPxADD for all clock ranges in a table, so, I can sort the root cause.

     
    • Anobium

      Anobium - 2020-01-12

      The table will answer these questions. As I am assuming these to be the test conditions that are missing.

      If the calculated value of SSPxADD = 0 then the clock speed is too slow
      If the calculated value of SSPxADD >127 then the clock speed is too high

       
  • Anobium

    Anobium - 2020-01-12

    OK. I need help. I based my previous post on the code.....

    There is a further potential error in the set of SSPxADD. For some reason the calculated value is ADD 127 which only takes the bottom 7 bits. Should the the test be?

    If the calculated value of SSPxADD = 0 then the clock speed is too slow
    If the calculated value of SSPxADD >255 then the clock speed is too high

    Help please. The table of data will answer these questions.

     
  • Anobium

    Anobium - 2020-01-12

    I have updated the libraries here.

    Change the method to calculate SSPxADD and a second change of setting the regiser SSPxADD.

    I need the table of test data to see if I have broken something.

     
  • David Stephenson

    Not sure what you need. The problem as I see it is if I am daft enough to specify a baud rate of 400kHz and have Fosc at 1MHz - it can't be done the best that can be managed is with SSPxADD set to zero giving a baud rate of 250kHz. Problem is for these impossible cases the compiler was setting SSPxADD to a large value making the baud rate too slow for some of my devices.

    Notice when I set baud rate to 100kHz with Fosc=1MHz the value given to SSPxADD =1 which gives the nearest possible baud rate of 125kHz - which is as correct as you can get.

    I think there needs to be a compiler warning when impossible parameters are being used (like the one you get when you use wait 1us with Fosc at 1MHz).
    SSPxADD needs to be set to zero to get the fastest possible baud rate for the impossible cases.
    I have written the code (in QB64) the line that checks whether SSPxADD is >1 is what is needed - we don't need it to roll back to 255. (note in QB64 \ is integer division)

    baud = 400000
    fosc = 1000000
    SSpxadd = fosc \ (baud * 4)
    IF SSpxadd > 1 THEN SSpxadd = SSpxadd - 1
    PRINT SSpxadd
    baudout = fosc / (4 * (SSpxadd + 1))
    PRINT baudout
    

    This may not work as it finds the nearest baud rate to the one specified and may give rates higher than 400 kHz.
    Perhaps
    IF baudout>baud then SSPxADD=SSPxADD+1
    I'm now going to see if I can find the code in the GCBasic files

     
  • Anobium

    Anobium - 2020-01-13

    I have updated the libraries here.

    I have resolved. I will publish.

    Will you test it?

    I have revised the script to handle the situation and I have removed the mask. I dont know what th mask is doing.

     

    Last edit: Anobium 2020-01-13
  • David Stephenson

    I have edited the HI2C2.h file...

    HI2C2_BAUD_TEMP = int((ChipMhz * 1000000)/(4000 * HI2C2_BAUD_RATE))
    if HI2C2_baud_temp>0 then hi2c2_baud_temp=hi2c2_baud_temp - 1

    This prevents hi2c2_baud_rate becoming -1 and so presumably becoming 255.
    Looking at the datasheet I'm a bit worried about having SSP2ADD=0, but it seems to work (and is better than being 255)
    Yes I'm also not sure why there is the AND 127, and the units of the frequencies are weird.

     
  • Anobium

    Anobium - 2020-01-13

    I have edited also. I have update the repository. :-(

    Will you please test?

     
  • David Stephenson

    Yes it works. I think I may go with a baud rate of 100kHz in future as it would seem that slower than expected is not a problem (it seems that I had been running at 2kHz and I had not noticed until last week).
    Could there also be a problem with SPI baud rates?

     
  • Anobium

    Anobium - 2020-01-13

    David... I may have resolved. Will you please test?

     
  • Anobium

    Anobium - 2020-01-14

    David. I did my own testing. Cheers.

    Well the results are in. The caculation in the libraries are correct. I validate for frequencies of the chip against i2C desired frequencies. I measure then compared the Great Cow BASIC caluclated value against MPLAB-X values.

    The test program is shown below. I have truly updated the library to resolve out of bounds conditions and today I have improved to ensure the new error messages issued by the compiler correct.

      #chip 16F18326,32
      #include "C:\GCB@Syn\GreatCowBasic\Include\lowlevel\hwi2c2.h"
      unlockpps
                  SSP2CLKPPS = 0x0015    'RC5 > SCK2
                  RC5PPS = 0x001A    'SCK2 > RC5 (bi-directional)
                  RC4PPS = 0x001B    'SDA2 > RC4
                  SSP2DATPPS = 0x0014    'RC4 > SDA2 (bi-directional)
                  lockpps
      #define hi2c2_BAUD_RATE 100
      #define hi2c2_DATA PORTC.4
      #define hi2c2_CLOCK PORTC.5
      Dir hi2c2_DATA in
      Dir hi2c2_CLOCK in
      hi2c2Mode Master
      WPUC=B'00110000' 'wpu for i2C
    
      do
    
        HI2C2Start
        repeat 256
        HI2C2Send 0x55
        end Repeat
        HI2C2Stop
    
      loop
    

    The digram shows the results.

    The fact is the calcs are correct as these match MPLAB-X, however, imperical testing clearly shows the frequency is alway slower. This is a question you could ask of Microchip.

    Hopefully, this resolves the issue.

     

    Last edit: Anobium 2020-01-14
  • Anobium

    Anobium - 2020-01-14

    The diagram shows the results:

    The TOP left BLOCK. 'Desired I2C2 of 100' and then below the actaul measured frequency of the CLOCK signal. Note the new library now correctly will not try to set the clock @ 0.25 by issuing a warning.

    The TOP left BLOCK. 'Desired I2C2 of 400' and then below the actaul measured frequency of the CLOCK signal. Note the new library now correctly will not try to set the clock @ 1,0, 0,5 or 0.25 by issuing a warning.

    In the column labelled SSPxADD is the calculated values by Great Cow BASIC of the desired fequencies, and, these match the frequencies calculated in Excel and by MPLAB-IDE (not populated but they are the same),

    I ahve also show the UI from MPLAB-IDE where the chip clock frequency is 32mhz, the desired I2C is 400kHz and the value to get that frequencies is 0x13 or d19. Same as Great Cow BASIC.

     
  • Anobium

    Anobium - 2020-01-14

    I have updated the libraries. I will release in the next release, or, if someone want to play. Just ask.

    Changes.

    1. Added  compiler orrection for out of bounds conditions where the SSPxADD could be set incorrectly
    2. Added  compiler orrection for out of bounds conditions where the SSPxADD could be set incorrectly where value 0, 1 and 3 are not supported
    3. Corrected masking error where SSPxADD was masked with 127
    4. Added  compiler error message to I2C2 and not I2C when using I2C2 
    5. Added  compiler error message to I2C and not I2C2 when using I2C
    6. Added  compiler test to  issue an error message SSPxADD is calculated greater then 255
    
     

    Last edit: Anobium 2020-01-14
  • David Stephenson

    Excellent. It's amazing how these small errors go unnoticed for so long.
    I frequently had issues with I2C intializing (had to keep cycling the power until it finally worked) so maybe this was the problem.

     

Log in to post a comment.