5P49V60 OUT0 dropout and OTP Programming

In my design, I'm using a 19.2MHz crystal and outputting a variety of clocks at 1.8V. I don't have a lot of choice of the 19.2MHz--it's required by the CPU I'm clocking on OUT0.

A 19.2MHz crystal requires reprogramming the feedback divider from defaults to keep the VCO within limits (and if you don't do this, the frequency will skew with time and temperature and the math for computing a specific output frequency is not at all correct). Committing the new feedback divider seems to require triggering "calibration_start" (register 0x1c, bit D7). This causes OUT0 to drop out while calibration is running. As I'm using OUT0 to clock the CPU which is sending I2C commands to do the recalibration, the dropout will actually cause the CPU to hang until a power cycle.

 The oscilloscope showing this dropout on OUT0 after triggering calibration_start.

My questions:

1) Is there any way to prevent the dropout on OUT0 and still correct the feedback divider?

Assuming I must OTP program to avoid this... Step 1 of OTP Programming says "Connect all VDD pins to a single 3.3V". 

2) Is 3.3V actually necessary to program? VDDD/VDDA and all VDDOs in my design are 1.8V. 

3) Is it possible to just run 3.3V to VDDA/VDDD instead of "all VDD pins"? I do not want to run 3.3V to the VDDO clock outputs which are connected to inputs that can only take 1.8V.

4) Is there a test fixture I can purchase to program these devices before placing them in-circuit? I know you have a custom service, but I use this chip for a wide variety of designs and do not want them all pre-programmed for just one project.

Thanks in advance!

Parents Reply Children
  • I meant test fixture in terms of a socket in which I could insert a chip, program it, and remove it. 

  • FA,

    we have duplicated your issue and our engineering team is looking into this.

  • FA,

    please try this:.

    1. Calibrate the device and read back the calibration value.
    2. Force the calibration override.
    3. Change the feedback divider. Check if the output remains stable.

    If this doesn't solve the issue please submit a support ticket and include:

    1) provide their configuration file

    2) Detailed information of your original configuration and the new configuration.

  • Register 0x99 is where the auto-calibration results are stored. The selected band is available in 0x99[7:3] once 0x99[2] is 1.

  • Can you provide a more detailed step-by-step guide? Doing step 1`causes it to drop out which prevents me from getting to 2 and 3 as your team have reproduced. Unless they're asking me to do try something different. Also, it's not clear to me how I force the calibration override.

    Finally, if you have any information on the other questions asked in this thread, (#2-#4 above), I'd appreciate it. Thanks!

  • FA,

    I am going to check with Engineering to see if they have any suggestions.

  • >> Is there any way to prevent the dropout on OUT0 and still correct the feedback divider?

    The customer wants to adjust the output frequency by changing the APLL feedback divider, to compensate for shifts in the crystal frequency. A better way to do this is to adjust the crystal load capacitance.

    Register 0x12[7:2] = register 0x13[7:2] = 0 → CL=4.5pF → 100MHz output is 100.008731MHz (100MHz + 87.31ppm)

    Register 0x12[7:2] = register 0x13[7:2] = 63 → CL=11.4pF → 100MHz output is 99.991842MHz (100MHz - 81.58ppm)

    Writing registers 0x12 and 0x13 does not interrupt the outputs (including the reference output). Also note that the reference output frequency will change by the same ppm as the other outputs when adjusting CL. When adjusting the APLL feedback divider only OUT1 to OUT4 frequencies will change.

    Note that it is the I2C_Global_Reset that interrupts the outputs, which Timing Commander automatically does when writing register changes to the device. The customer can change CL (0x12 and 0x13) and the APLL feedback divider (0x17 .. 0x1b) by writing to these registers only. To do so from Timing Commander, turn off the “Write changes to the chip immediately“ option, then use the “Write this register to the chip” button for the specific registers to be written. This will write only those register to the chip, without performing an I2C_Global_Reset (register 0x76[5]).

    >> Is 3.3V actually necessary to program? VDDD/VDDA and all VDDOs in my design are 1.8V.

    3.3V on VDDD/VDDA is necessary for OTP writes. It is not needed for register writes, which works fine at 1.8V.

    >> Is it possible to just run 3.3V to VDDA/VDDD instead of "all VDD pins"?

    Yes. VDDD and VDDA should be the same voltage. The VDDO* output driver supplies may be 1.8V to 3.3V independent of VDDD/VDDA and each other. (All supplies must be powered by at least 1.8V for successful power-on-reset.)

    >> Is there a test fixture I can purchase to program these devices before placing them in-circuit?

    Yes, the VC6E-PROG programmer board may be used for 5P49V6965, 5P49V6975 and 5P49V60.

    [5P49V6965-PROG - Programming Kit for VersaClock® 6E | Renesas|https://www.renesas.com/us/en/products/clocks-timing/clock-generation/programmable-clocks/5p49v6965-prog-programming-kit-versaclock-6e]

    (If the customer has a 5P49V5901 programmer board, that should also work to program 5P49V60 parts – [EVKVC5-59xxPROG - Programmer Board for VersaClock® 5 - 5P49V59xx | Renesas|https://www.renesas.com/us/en/products/clocks-timing/clock-generation/programmable-clocks/evkvc5-59xxprog-programmer-board-versaclock-5-5p49v59xx])

    The programmer board works equally well for register programming and OTP programming

    While I recommend the customer adjust the CL value instead, this is in answer to the last customer question:

    >> Can you provide a more detailed step-by-step guide? Doing step 1`causes it to drop out which prevents me from getting to 2 and 3 as your team have reproduced. Unless they're asking me to do try something different. Also, it's not clear to me how I force the calibration override.

    AN-912 VersaClock 5 and VersaClock 6 In-System Programming (renesas.com)

    The process is the same for VersaClock5 (5P49V590x), VersaClock6 (5P49V690x) and VersaClock6E (5P49V60, 5P49V696x 5P49V697x).

    I’ve not seen a VCO calibration causing the I2C connection to be disrupted. Perhaps the customer can clarify “drop out”.

  • I'll switch this to a trouble ticket. This last response is completely confused and several steps backwards from the line you were following earlier.

    1) I do not want to change the ppm, I need to change the the feedback divider for a crystal other than the default 25MHz. 

    2) The dropout is clearly shown by the oscilloscope output in this post.

    3) It is not the i2c reset that causes the dropout, it is the calibration.

    4) I need the step-by-step guide on how to "calibrate the device and readback", "force calibration override", then "change the feedback divider" without causing the dropout.

    All that being said, the pointer to the Programming Kit and notes about the VDD for OTP is exactly answering my other questions. Thanks for pursuing that.

    FYI: This has been assigned ticket #379571

  • Hi Michael,

    This answer wasn't right, but it ended up being resolved by you and the team in the trouble ticket (ticket 379571). I don't want to repost your final instructions there without permission. With your permission, I will post here, or feel free to do so yourself. 

  • Recommended sequence:
    1.    Set 0x6F[1] (PLL_Lock_Bypass) to 1.
    2.    Toggle 0x1C[7] (Calibration_Start) (to 0 and back to 1).
    3.    Monitor 0x99[2] (Calibration_Done), wait for 1.
    4.    Monitor 0x9D[7] (PLL_Lock), wait for 1.
    5.    Reset 0x6F[1] (PLL_Lock_Bypass) to 0.
    >> What is the penalty of "lock bypass"?
    Register bit 0x6F[1] is a test register to control the state of the outputs while the APLL is not locked. It does not control the APLL.

    import ftdi_mpsse  			  					            #Import the module
    import time
     
    import sys
     
    #if len(sys.argv) > 1:
    #    select_config = int(sys.argv[1])
    #else:
    #    select_config = 0
    
    i2c = ftdi_mpsse.i2c(serial_number='A')  					#Connect to the FTDI chip
    
    
    ## Device address 0xD0  1101 0000 => 7-bit 0x68
    ## Device address 0xD4  1101 0100 => 7-bit 0x6A     VC6E
    ## Device address 0xA0  1010 0000 => 7-bit 0x50
    ## Device address 0xAA  1010 1010 => 7-bit 0x55     ProXO
    ## Device address 0xB6  1011 0110 => 7-bit 0x5B     ClockMatrix
    
    i2c.ReadAtOffset(0x6A, 0x00, 2, offset_size=1, disable_restart=0)   # Dummy read, else first read starts incorrectly, cause unknown
    
    
    print('         00   01   02   03   04   05   06   07   08   09   0A   0B   0C   0D   0E   0F')
    print('0x00 :' + ''.join([' 0x{:02X}'.format(ord(x)) for x in i2c.ReadAtOffset(0x6A, 0x00, 16, offset_size=1, disable_restart=0)]))
    print('0x10 :' + ''.join([' 0x{:02X}'.format(ord(x)) for x in i2c.ReadAtOffset(0x6A, 0x10, 16, offset_size=1, disable_restart=0)]))
    print('0x20 :' + ''.join([' 0x{:02X}'.format(ord(x)) for x in i2c.ReadAtOffset(0x6A, 0x20, 16, offset_size=1, disable_restart=0)]))
    print('0x30 :' + ''.join([' 0x{:02X}'.format(ord(x)) for x in i2c.ReadAtOffset(0x6A, 0x30, 16, offset_size=1, disable_restart=0)]))
    print('0x40 :' + ''.join([' 0x{:02X}'.format(ord(x)) for x in i2c.ReadAtOffset(0x6A, 0x40, 16, offset_size=1, disable_restart=0)]))
    print('0x50 :' + ''.join([' 0x{:02X}'.format(ord(x)) for x in i2c.ReadAtOffset(0x6A, 0x50, 16, offset_size=1, disable_restart=0)]))
    print('0x60 :' + ''.join([' 0x{:02X}'.format(ord(x)) for x in i2c.ReadAtOffset(0x6A, 0x60, 16, offset_size=1, disable_restart=0)]))
    print('0x70 :' + ''.join([' 0x{:02X}'.format(ord(x)) for x in i2c.ReadAtOffset(0x6A, 0x70, 16, offset_size=1, disable_restart=0)]))
    print('0x80 :' + ''.join([' 0x{:02X}'.format(ord(x)) for x in i2c.ReadAtOffset(0x6A, 0x80, 16, offset_size=1, disable_restart=0)]))
    print('0x90 :' + ''.join([' 0x{:02X}'.format(ord(x)) for x in i2c.ReadAtOffset(0x6A, 0x90, 16, offset_size=1, disable_restart=0)]))
    
    
    print('Read starting Calibration results register 0x99')
    reg99 = ord(i2c.ReadAtOffset(0x6A, 0x99, 1, offset_size=1, disable_restart=0))
    print('reg99 was 0x{:02X}'.format(reg99) )
    
    
    print('Set register 0x6F[1] (PLL_Lock_Bypass) to 1')
    reg6F = ord(i2c.ReadAtOffset(0x6A, 0x6F, 1, offset_size=1, disable_restart=0))
    print('reg6F was 0x{:02X}'.format(reg6F) )
    reg6F = reg6F | 0x01
    print('reg6F set 0x{:02X}'.format(reg6F) )
    i2c.WriteAtOffset(0x6A, offset=0x6F , data=chr(reg6F), offset_size=1)
    reg6F = ord(i2c.ReadAtOffset(0x6A, 0x6F, 1, offset_size=1, disable_restart=0))
    print('reg6F now 0x{:02X}'.format(reg6F) )
    
    
    print('Toggle register 0x1C[7] (Calibration_Start)')
    reg1C = ord(i2c.ReadAtOffset(0x6A, 0x1C, 1, offset_size=1, disable_restart=0))
    print('reg1C was 0x{:02X}'.format(reg1C) )
    reg1C = reg1C & 0x7F
    print('reg1C set 0x{:02X}'.format(reg1C) )
    i2c.WriteAtOffset(0x6A, offset=0x1C , data=chr(reg1C), offset_size=1)
    reg1C = ord(i2c.ReadAtOffset(0x6A, 0x1C, 1, offset_size=1, disable_restart=0))
    print('reg1C now 0x{:02X}'.format(reg1C) )
    reg1C = reg1C | 0x80
    print('reg1C set 0x{:02X}'.format(reg1C) )
    i2c.WriteAtOffset(0x6A, offset=0x1C , data=chr(reg1C), offset_size=1)
    reg1C = ord(i2c.ReadAtOffset(0x6A, 0x1C, 1, offset_size=1, disable_restart=0))
    print('reg1C now 0x{:02X}'.format(reg1C) )
    
    
    print('Read register 0x99[2] (Calibration_Done) status bit')
    reg99 = ord(i2c.ReadAtOffset(0x6A, 0x99, 1, offset_size=1, disable_restart=0))
    cal_status = (reg99 & 0x04) >> 2
    while (cal_status == 0):
        print('.')
        time.sleep(0.01)
        reg99 = ord(i2c.ReadAtOffset(0x6A, 0x99, 1, offset_size=1, disable_restart=0))
        cal_status = (reg99 & 0x04) >> 2
    
    reg99 = ord(i2c.ReadAtOffset(0x6A, 0x99, 1, offset_size=1, disable_restart=0))
    print('reg99 is now 0x{:02X}'.format(reg99) )
    print('Calibration_Done = {}'.format(cal_status))
    
    
    print('Read register 0x9D[7] (PLL_Lock) status bit')
    reg9D = ord(i2c.ReadAtOffset(0x6A, 0x9D, 1, offset_size=1, disable_restart=0))
    lock_status = (reg9D & 0x80) >> 7
    while (lock_status == 0):
        print('.')
        time.sleep(0.01)
        reg9D = ord(i2c.ReadAtOffset(0x6A, 0x9D, 1, offset_size=1, disable_restart=0))
        lock_status = (reg9D & 0x80) >> 7
    
    reg9D = ord(i2c.ReadAtOffset(0x6A, 0x9D, 1, offset_size=1, disable_restart=0))
    print('reg9D is now 0x{:02X}'.format(reg9D) )
    print('PLL_Lock = {}'.format(lock_status))
    
    
    print('Reset register 0x6F[1] (PLL_Lock_Bypass) to 0')
    reg6F = ord(i2c.ReadAtOffset(0x6A, 0x6F, 1, offset_size=1, disable_restart=0))
    print('reg6F was 0x{:02X}'.format(reg6F) )
    reg6F = reg6F & 0xFE
    print('reg6F set 0x{:02X}'.format(reg6F) )
    i2c.WriteAtOffset(0x6A, offset=0x6F , data=chr(reg6F), offset_size=1)
    reg6F = ord(i2c.ReadAtOffset(0x6A, 0x6F, 1, offset_size=1, disable_restart=0))
    print('reg6F now 0x{:02X}'.format(reg6F) )
    time.sleep(0.1)
    
    
    #print('Config %d' % select_config)
    print('         00   01   02   03   04   05   06   07   08   09   0A   0B   0C   0D   0E   0F')
    print('0x00 :' + ''.join([' 0x{:02X}'.format(ord(x)) for x in i2c.ReadAtOffset(0x6A, 0x00, 16, offset_size=1, disable_restart=0)]))
    print('0x10 :' + ''.join([' 0x{:02X}'.format(ord(x)) for x in i2c.ReadAtOffset(0x6A, 0x10, 16, offset_size=1, disable_restart=0)]))
    print('0x20 :' + ''.join([' 0x{:02X}'.format(ord(x)) for x in i2c.ReadAtOffset(0x6A, 0x20, 16, offset_size=1, disable_restart=0)]))
    print('0x30 :' + ''.join([' 0x{:02X}'.format(ord(x)) for x in i2c.ReadAtOffset(0x6A, 0x30, 16, offset_size=1, disable_restart=0)]))
    print('0x40 :' + ''.join([' 0x{:02X}'.format(ord(x)) for x in i2c.ReadAtOffset(0x6A, 0x40, 16, offset_size=1, disable_restart=0)]))
    print('0x50 :' + ''.join([' 0x{:02X}'.format(ord(x)) for x in i2c.ReadAtOffset(0x6A, 0x50, 16, offset_size=1, disable_restart=0)]))
    print('0x60 :' + ''.join([' 0x{:02X}'.format(ord(x)) for x in i2c.ReadAtOffset(0x6A, 0x60, 16, offset_size=1, disable_restart=0)]))
    print('0x70 :' + ''.join([' 0x{:02X}'.format(ord(x)) for x in i2c.ReadAtOffset(0x6A, 0x70, 16, offset_size=1, disable_restart=0)]))
    print('0x80 :' + ''.join([' 0x{:02X}'.format(ord(x)) for x in i2c.ReadAtOffset(0x6A, 0x80, 16, offset_size=1, disable_restart=0)]))
    print('0x90 :' + ''.join([' 0x{:02X}'.format(ord(x)) for x in i2c.ReadAtOffset(0x6A, 0x90, 16, offset_size=1, disable_restart=0)]))