Menu

18F25K20 I2C TO Si570

Help
2015-05-22
2015-05-28
  • Charles R. Veres

    I am trying to use an 18F25K20 to send I2C to a Si570 digitally controlled oscillator. It doesn't work. The clock and data lines reside low and flicker high. I know that is backwards for I2C. Can one of you gentlemen tell me what I am doing wrong?

    'Set chip model:
    #chip 18F25k20, 16 'at 16 MHz
    'Switch Low-Volt-Programming:
    #config LVP = Off

    'Set internal clock speed to 16 MHz:
    Set IRCF0 = 1
    Set IRCF1 = 1
    Set IRCF2 = 1

    Dim REGISTER as Byte
    Dim DATUM as Byte
    Dim ADDRESS as Byte

    Let ADDRESS = 0b10101010 'address 85 decimal, sending.

    'Set the pin direction to output:
    ' (PORTC.4 = Pin 15 on PIC18F25k20 portc.3 = pin 14.)
    Dir PORTC Out

    #define I2C_MODE Master
    #define I2C_DATA PORTC.4 'this pin has 5k1 resistor to +3.3 volts.
    #define I2C_CLOCK PORTC.3 'this pin has 5k1 resistor to +3.3 volts.

    ANSEL = 0
    ANSELH = 0
    SSPEN = 0

    'Main routine
    Start:

    Let REGISTER = 137 'freezing the output
    Let DATUM = 0b00010000 'the freezing bit
    Gosub SendI2C

    Let REGISTER = 7
    Let DATUM = 0b001000001 ' HS_DIV and part of N1
    Gosub SendI2C

    Let REGISTER = 8
    Let DATUM = 0b0100010 ' end of N1 and beginning RFREQ
    Gosub SendI2C

    Let REGISTER = 9 'more RFREQ
    Let DATUM = 0xBC
    Gosub SendI2C

    Let REGISTER = 10 'more RFREQ
    Let DATUM = 0x01
    Gosub SendI2C

    Let REGISTER = 11 'more RFREQ
    Let DATUM = 0x1E
    Gosub SENDI2C

    Let REGISTER = 12 'the last of RFREQ
    Let DATUM = 0xB8
    Gosub SENDI2C

    Let REGISTER = 137 'thawing output
    LET DATUM = 0b00000000
    Gosub SENDI2C

    Let REGISTER = 135 'asserting new frequency
    Let DATUM = 0b01000000
    Gosub SENDI2C

    Wait 1000 ms 'repeat once a second for scope test.

    Goto Start 'jump back to the start of the program

    'main line ends here

    SendI2C: ' label to start i2c sending subroutine

    I2CStart

    I2CSend ADDRESS,FALSE 'writing to slave at 85 decimal.

    I2CSend REGISTER,FALSE 'sending register addy within Si570

    I2CSend DATUM,FALSE

    I2CStop

    wait 5 mS ' this delay vital for Si570 to digest info.

    RETURN

    Thanks in advance,
    Chip

     

    Last edit: Charles R. Veres 2015-05-22
    • Charles R. Veres

      Mr. Anobium:

      I didn't post a schematic because it is so simple. The data line on the PIC goes to the data line on the oscillator. The clock line on the PIC goes to the clock line on the oscillator. Each of these is pulled up to 3.3 volts with a 5100 ohm resistor.

      Looking with a scope, the pulses are nice and square, but apparently upside down. One expects an I2C line to stay high and then flicker downward when data is sent. These seem to be doing the opposite.

      Chip

       
  • Anobium

    Anobium - 2015-05-22

    Can post a circuit diagram?

    Do you have any pull ups? See http://www.robot-electronics.co.uk/acatalog/I2C_Tutorial.html

     
  • Anobium

    Anobium - 2015-05-25

    Most odd. I do not know. Pulled low? But, the resistors should pull high.

    Can I ask? What version of GCB and the Release of your GCB code? Is this the latest build? I am wondering if you have old version of i2c.h.

    @Anyone .. help us get to bottom of this one. :-)

     
  • William Roth

    William Roth - 2015-05-25

    Hi,
    Here are some observations and some questions.

    1. There should be no need to set the OSCCON bits to set
       the frequency.  Why are these being set?
    
    2. There is no need to DIM variables as BYTE.  Variables
       are byte by default. But this will not hurt anything
    
    3. What is the purpose for clearing ANSEL?  Is this
       necessary?
    
    4. Why is entire port C set as Output?
    
    5. "SENDI2C" is a label and not a proper sub. Normally a
        sub is created as follows:
    
        SUB Name (options)       
           do stuff
           do stuff
        end sub
    
        Why are you using a label and return as a sub?  
        Does this really work?
    
    6.  What Version of GCB are you using? (Important) 
        Please do not ignore this question.
    
    7.  Make double sure that the 5K1 pullup resistors go to 3.3v
        and not to ground.
    
     

    Last edit: William Roth 2015-05-25
  • Charles R. Veres

    Thank you gentlemen. I am using version 0.9 dated 11/5/2014.
    The IRCF bits are set as the regular way to set the internal oscillator on a 18F25K20.
    ANSEL & ANSELH are cleared because I'm not using any analog inputs.
    PortC is set as output because if I set it to input I get no result at all.
    Tomorrow when I get to work I'll try not declaring it either way.
    SENDI2C is supposed to be a subroutine. It's written funny because I fouled up.
    I will correct it immediately, that could be the problem.
    The pull up resistors certainly go to +3.3 VDC.
    Thank you again.

    Chip

     
  • Anobium

    Anobium - 2015-05-25

    Please ugrade your GCB. This is really critical so we can help you.

    See here, https://sourceforge.net/projects/gcbasic/ and select Download

     
  • Charles R. Veres

    Okay, I updated to version 0.94. That immediately fixed the problem with the "upside down" lines. So we are making progress. I also connected a Bus Pirate to it and used its native I2C mode as well as its logic analyzer mode. The problems now seem limited to the stop character. When the data line rises to form the stop pulse, it puts a glitch in the timing pulse and splits the timing pulse in two. I tried a power filter capacitor right at the chip, but it didn't help.

    Chip V.

     
  • Anobium

    Anobium - 2015-05-26

    ummm. Does it work?

    I have not seen any glitches.

    Try increasing the I2C timings by changing from the defaults (defaults are shown below).

    ~~~~

    define I2C_BIT_DELAY 2 us 'width of data bit on SDA

    define I2C_CLOCK_DELAY 1 us 'width of clock pulse on SCL

    define I2C_END_DELAY 1 us 'interval between clock pulses

     

    Last edit: Anobium 2015-05-26
  • Anobium

    Anobium - 2015-05-26

    A logic trace is not showing a glitch.

     
  • Anobium

    Anobium - 2015-05-26

    Scope is not showing a glitch.

     
    • Anobium

      Anobium - 2015-05-26

      A better trace.

       
  • Charles R. Veres

    Slowing down helps. Just caught another error in my program. More tomorrow.

    Chip V.

     
  • Charles R. Veres

    Gentlemen:

    My latest effort is below. As you can clearly see in the subroutine, it is supposed to send groups of three bytes out the I2C port. Problem is, it randomly drops one of the three bytes. Can anybody see what is wrong?

    'Set chip model:
    #chip 18F25k20, 16 'at 16 MHz
    'Switch Low-Volt-Programming:
    #config LVP = Off
    #config MCLR = Off

    'Set internal clock speed to 16 MHz:
    Set IRCF0 = 1
    Set IRCF1 = 1
    Set IRCF2 = 1

    Dim REGISTER as Byte
    Dim DATUM as Byte
    Dim ADDRESS as Byte

    Let ADDRESS = 0b10101010 'address 85 decimal, sending.

    #define I2C_MODE Master
    #define I2C_DATA PORTC.4 'this pin has 5k1 resistor to +3.3 volts.
    #define I2C_CLOCK PORTC.3 'this pin has 5k1 resistor to +3.3 volts.

    #define I2C_BIT_DELAY 4 uS
    #define I2C_CLOCK_DELAY 2 uS
    #define I2C_END_DELAY 2 uS

    wait 5 mS 'time to do the defines?

    'Main routine
    Start:

    Let REGISTER = 137 'freezing the output
    Let DATUM = 0b00010000 'the freezing bit
    SENDI2C

    Let REGISTER = 7
    Let DATUM = 0b00100010 ' HS_DIV and part of N1
    SENDI2C

    Let REGISTER = 8
    Let DATUM = 0b01000010 ' end of N1 and beginning RFREQ
    SENDI2C

    Let REGISTER = 9 'more RFREQ
    Let DATUM = 0xBC
    SENDI2C

    Let REGISTER = 10 'more RFREQ
    Let DATUM = 0x01
    SENDI2C

    Let REGISTER = 11 'more RFREQ
    Let DATUM = 0x1E
    SENDI2C

    Let REGISTER = 12 'the last of RFREQ
    Let DATUM = 0xB8
    SENDI2C

    Let REGISTER = 137 'thawing output
    LET DATUM = 0b00000000
    SENDI2C

    Let REGISTER = 135 'asserting new frequency
    Let DATUM = 0b01000000
    SENDI2C

    Wait 1000 ms 'repeat once a second for scope test.

    Goto Start 'jump back to the start of the program

    'main line ends here

    sub SENDI2C ' label to start i2c sending subroutine

    I2CStart
    I2CSend ADDRESS 'writing to slave at 85 decimal.
    I2CSend REGISTER 'sending register addy within Si570
    I2CSend DATUM
    I2CStop

    wait 5 mS ' this delay vital for Si570 to digest info.

    end sub
    end

     
  • Anobium

    Anobium - 2015-05-27

    Post the datasheet of the target device - I need to see the protocol.

    Just for fun test the attachment please. you may need to edit but I quickly created. It is you code! I called it the wrong name.

     
  • Charles R. Veres

    https://www.silabs.com/.../si570.pdf

    Is the data sheet for the Si570.

     
  • Anobium

    Anobium - 2015-05-27

    ok. I review it.

    try the code I posted - ensure you check every parameter passed to the sub! :-)

     
  • Charles R. Veres

    Trying the code you posted - no joy so far. It rapidly sends the address byte over and over again. Trying to debug.

    Chip V.

     
  • Anobium

    Anobium - 2015-05-27

    I just spotted I put 139 not 137 as the parameter. Did you change that?

     
    • Charles R. Veres

      I changed that, but still no help. Don't let the 570 datasheet make you too crazy. It is a true model of unclarity.

      Chip

       
  • Anobium

    Anobium - 2015-05-27

    😃

    Can you post any traces? Do you have any analysis tools?

     
  • Charles R. Veres

    I just found out that the Si570, when oscillating, interferes with its own I2C communications. I'm working on a setup to shut off the output while I set a new frequency. That will do fine for my application.

     
  • Charles R. Veres

    Thank you Evan and William. Together we prevailed. Working code below:

    ' Program sets Si570 to 100 MHz for calibration.
    'Set chip model:
    #chip 18F25k20,16 'at 16 MHz
    'Switch Low-Volt-Programming:
    #config LVP = Off
    #config MCLR = Off

    'Set internal clock speed to 16 MHz:
    Set IRCF0 = 1
    Set IRCF1 = 1
    Set IRCF2 = 1

    Dim REGISTER as Byte
    Dim DATUM as Byte
    Dim ADDRESS as Byte

    Let ADDRESS = 0b10101010 'address 85 decimal, sending.

    #define I2C_MODE Master
    #define I2C_DATA PORTC.4 'this pin has 5k1 resistor to +3.3 volts.
    #define I2C_CLOCK PORTC.3 'this pin has 5k1 resistor to +3.3 volts.

    #define I2C_BIT_DELAY 5 uS
    #define I2C_CLOCK_DELAY 3 uS
    #define I2C_END_DELAY 3 uS

    wait 5 mS 'time to do the defines?

    'Main routine
    do

    portc.2 = 0 'Shut off output. Connect to Si570 OE
    wait 1 mS 'waiting for quiet

    Let REGISTER = 137 'freezing the output
    Let DATUM = 0b00010000 'the freezing bit
    SENDI2C

    Let REGISTER = 7
    Let DATUM = 0b00100010 ' HS_DIV and part of N1
    SENDI2C

    Let REGISTER = 8
    Let DATUM = 0b01000010 ' end of N1 and beginning RFREQ
    SENDI2C

    Let REGISTER = 9 'more RFREQ
    Let DATUM = 0xBC
    SENDI2C

    Let REGISTER = 10 'more RFREQ
    Let DATUM = 0x01
    SENDI2C

    Let REGISTER = 11 'more RFREQ
    Let DATUM = 0x1E
    SENDI2C

    Let REGISTER = 12 'the last of RFREQ
    Let DATUM = 0xB8
    SENDI2C

    Let REGISTER = 137 'thawing output
    LET DATUM = 0b00000000
    SENDI2C

    Let REGISTER = 135 'asserting new frequency
    Let DATUM = 0b01000000
    SENDI2C

    portc.2 = 1 'starting the oscillator

    Wait 1000 ms 'repeat once a second for scope test.

    loop 'jump back to the start of the program

    'main line ends here

    sub SENDI2C ' label to start i2c sending subroutine

    I2CStart
    I2CSend ADDRESS 'writing to slave at 85 decimal.wait 20 uS
    I2CSend REGISTER 'sending register addy within Si570wait 20 uS
    I2CSend DATUM
    I2CStop

    wait 4 mS ' this delay vital for Si570 to digest info.

    end sub
    end

     
  • Anobium

    Anobium - 2015-05-28

    Well done - the delay fixed it?

     
  • Charles R. Veres

    It seems that the key factors in the solution were 1. Compile with version 0.94 2. Slow down the I2C pulses as shown 3. Shut off the Si570 while sending I2C so it doesn't interfere with itself.

    Chip

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.