Timing for burning fuses in RT106x

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Timing for burning fuses in RT106x

Jump to solution
2,659 Views
carstengroen
Senior Contributor II

Looking at this question: How to burn BT_FUSE_SEL on RT1050 

there is some code that should enable burning of the BT_FUSE_SEL and FORCE_INTERNAL_BOOT fuses. However, when I try and do the re-calculation for ipg_clk of 150 MHz, I stumpled upon what I think is an error in the original code ?

I have a feeling that the timings above are not correct (or, very likely, I'm misunderstanding the numbers/calculations) ?

From the comments in the code from the link above, they are calculated for ipg_clk of 132 MHz, but if I calculate the resulting timing values using formulas in the Users Manual for 132 MHz also,

I get the following:

// Value at the start of line is [xx] which is number of nS at 132 MHz
     // Timing values at 132 MHz: 
     //      int timing = OCOTP_TIMING_STROBE_PROG(1325) | OCOTP_TIMING_RELAX(2) | OCOTP_TIMING_STROBE_READ(11) | OCOTP_TIMING_WAIT(24); // ipg_clk=132MHz, Calculation described at Chapter 22.4.3 OTP Read/Write Timing Parameters
     //
     //
     // [189]     WAIT = tSP_RD=(WAIT+1)/ipg_clk_freq, should be >= 150 ns
     // [22.7]     RELAX = tSP_PGM=tHP_PGM=(RELAX+1)/ipg_clk_freq, should be >= 100ns
     // [7818]     STROBE_PROG = tPGM = [(STROBE_PROG+1) – 2×(RELAX_PROG+1)] / ipg_clk_freq (The tPGM should be configured within the range of 9000 ns < tPGM < 11000 ns, while its recommended value is 10000 ns)
     // [30.3]     STROBE_READ = tRD= [(STROBE_READ+1) – 2×(RELAX_READ+1)] / ipg_clk_freq (The tRD is required to be larger than 40 ns)
     //
     // [30.7]     TIMING2.RELAX_READ = (RELAX_READ+1) / ipg_clk_freq, should be >= 10 ns.
     // [1113]     TIMING2.RELAX_PROG = tSP_PG_AVDD = tHP_PG_AVDD = (RELAX_PROG+1)/ipg_clk_freq, should be >= 1000 ns.
     // At default, RELAX_READ is 0x03 (3) and RELAX_PROG is 0x92 (146)
     //



Using the numbers above, I get:

189 nS for the WAIT (must be >= 150 nS) so ok.

22.7 nS for the RELAX (must be >= 100 nS) so NOT ok

7818 nS for the STROBE_PROG (must be >9000 and <11000) so NOT ok

30.3 nS for STROBE_READ (must be > 40 nS) so NOT ok.

I have checked the RELAX_READ and RELAX_PROG in TIMING2 register, and they are 3 and 146.

Am I totally mis-calculating this, or is there something wrong in the original code ?

1 Solution
2,211 Views
mali
Contributor III

Hi Carsten, you are absolutely right, my values of thread https://community.nxp.com/message/1097911?commentID=1097911&et=watches.email.thread#comment-1097911 are not longer correct since they have changed the value tRELAX from >16,2ns to >=100ns in reference manual. As I calculated the values, I used i.MX RT1050 Processor Reference Manual Rev 0.

The values concerning refenence manual Rev.2 (if I have calculated them correctly) should be:

    //TIMING_WAIT = 150ns * 132MHz - 1 = 18,8 => 19
    //RELAX = 100ns * 132MHz - 1 = 12,2 => 13
    //RELAX_READ = 10ns * 132MHz -1 = 0,32 => 1
    //RELAX_PROG = 1000ns * 132MHz - 1 = 131
    //STROBE_PROG = 10us * 132MHz + 2 * (RELAX_PROG + 1) - 1 = 10us * 132MHz + 2 * (131 + 1) - 1 = 1583
    //STROBE_READ = 40ns * 132MHz + 2 * (RELAX_READ + 1) - 1 = 40ns * 132MHz + 2 * (1 + 1) - 1 = 8,28 => 9
  int timing = OCOTP_TIMING_STROBE_PROG(1583) | OCOTP_TIMING_RELAX(13) | OCOTP_TIMING_STROBE_READ(9) |OCOTP_TIMING_WAIT(19); //ipg_clk=132MHz, Calculation described at Chapter 22.4.3 (Rev.2) OTP Read/Write Timing Parameters

Please let me know if you are getting same results.

Best regards

Martin

View solution in original post

4 Replies
2,211 Views
carstengroen
Senior Contributor II

Anyone ?

0 Kudos
2,212 Views
mali
Contributor III

Hi Carsten, you are absolutely right, my values of thread https://community.nxp.com/message/1097911?commentID=1097911&et=watches.email.thread#comment-1097911 are not longer correct since they have changed the value tRELAX from >16,2ns to >=100ns in reference manual. As I calculated the values, I used i.MX RT1050 Processor Reference Manual Rev 0.

The values concerning refenence manual Rev.2 (if I have calculated them correctly) should be:

    //TIMING_WAIT = 150ns * 132MHz - 1 = 18,8 => 19
    //RELAX = 100ns * 132MHz - 1 = 12,2 => 13
    //RELAX_READ = 10ns * 132MHz -1 = 0,32 => 1
    //RELAX_PROG = 1000ns * 132MHz - 1 = 131
    //STROBE_PROG = 10us * 132MHz + 2 * (RELAX_PROG + 1) - 1 = 10us * 132MHz + 2 * (131 + 1) - 1 = 1583
    //STROBE_READ = 40ns * 132MHz + 2 * (RELAX_READ + 1) - 1 = 40ns * 132MHz + 2 * (1 + 1) - 1 = 8,28 => 9
  int timing = OCOTP_TIMING_STROBE_PROG(1583) | OCOTP_TIMING_RELAX(13) | OCOTP_TIMING_STROBE_READ(9) |OCOTP_TIMING_WAIT(19); //ipg_clk=132MHz, Calculation described at Chapter 22.4.3 (Rev.2) OTP Read/Write Timing Parameters

Please let me know if you are getting same results.

Best regards

Martin

2,211 Views
carstengroen
Senior Contributor II

Thanks a lot Martin!

I was afraid I was seriously mistaken, happy I was not wrong Smiley Happy

I confirm the numbers above from you, fits perfectly with mine also.

I have changed my comments to this:

     // Write Fuses, burn BT_FUSE_SEL (disable BT_CFG_xx pins) and burn FORCE_INTERNAL_BOOT (so that BOOT_MODE0 and BOOT_MODE1 inputs does not matter any more)
     //
     // Value at the start of line is [xx] which is number of nS at 132 MHz
     // Timing values at 132 MHz: 
     // int timing = OCOTP_TIMING_STROBE_PROG(1583) | OCOTP_TIMING_RELAX(13) | OCOTP_TIMING_STROBE_READ(9) |OCOTP_TIMING_WAIT(19); //ipg_clk=132MHz, Calculation described at Chapter 22.4.3 (Rev.2) OTP Read/Write Timing Parameters
     //
     //
     // [151]     WAIT = tSP_RD=(WAIT+1)/ipg_clk_freq, should be >= 150 ns
     // [106]     RELAX = tSP_PGM=tHP_PGM=(RELAX+1)/ipg_clk_freq, should be >= 100ns
     // [10015]     STROBE_PROG = tPGM = [(STROBE_PROG+1) – 2×(RELAX_PROG+1)] / ipg_clk_freq (The tPGM should be configured within the range of 9000 ns < tPGM < 11000 ns, while its recommended value is 10000 ns)
     // [45]          STROBE_READ = tRD= [(STROBE_READ+1) – 2×(RELAX_READ+1)] / ipg_clk_freq (The tRD is required to be larger than 40 ns)
     //
     // [15.2]     TIMING2.RELAX_READ = (RELAX_READ+1) / ipg_clk_freq, should be >= 10 ns.
     // [1000]     TIMING2.RELAX_PROG = tSP_PG_AVDD = tHP_PG_AVDD = (RELAX_PROG+1)/ipg_clk_freq, should be >= 1000 ns.
     
     // In TIMING2, RELAX_READ is set to 0x01 (1) and RELAX_PROG is 0x92 (131)
     // (At default, RELAX_READ is 0x03 (3) and RELAX_PROG is 0x92 (146))
     //

I will update the numbers for 150 MHz ipg_clk shortly and give it a try (once I get some extra boards manufactured so I don't risk messing my testboard up Smiley Wink)

Thanks a lot!

0 Kudos
2,211 Views
carstengroen
Senior Contributor II

Just to wrap this up, this is the code I currently use:

//------------------------------------------------------------------------------
// Burn BT_FUSE_SEL and FORCE_INTERNAL_BOOT fuses
//------------------------------------------------------------------------------
void setFuses(void) {
 // Write Fuses, burn BT_FUSE_SEL (disable BT_CFG_xx pins) and burn FORCE_INTERNAL_BOOT (so that BOOT_MODE0 and BOOT_MODE1 inputs does not matter any more)
 //
 // Value at the start of line is [xx] which is number of nS at 132 MHz with the timing values below

 // [151] WAIT = tSP_RD=(WAIT+1)/ipg_clk_freq, should be >= 150 ns
 // [106] RELAX = tSP_PGM=tHP_PGM=(RELAX+1)/ipg_clk_freq, should be >= 100ns
 // [10015] STROBE_PROG = tPGM = [(STROBE_PROG+1) – 2×(RELAX_PROG+1)] / ipg_clk_freq (The tPGM should be configured within the range of 9000 ns < tPGM < 11000 ns, while its recommended value is 10000 ns)
 // [45]  STROBE_READ = tRD= [(STROBE_READ+1) – 2×(RELAX_READ+1)] / ipg_clk_freq (The tRD is required to be larger than 40 ns)
 //
 // [15.2] TIMING2.RELAX_READ = (RELAX_READ+1) / ipg_clk_freq, should be >= 10 ns.
 // [1000] TIMING2.RELAX_PROG = tSP_PG_AVDD = tHP_PG_AVDD = (RELAX_PROG+1)/ipg_clk_freq, should be >= 1000 ns.
 
 // In TIMING2, RELAX_READ is set to 0x01 (1) and RELAX_PROG is 0x92 (131)
 // (At default, RELAX_READ is 0x03 (3) and RELAX_PROG is 0x92 (146))
 // For 132 MHz:
 // TIMING_WAIT = 150ns * 132MHz - 1 = 18,8 => 19
    // RELAX = 100ns * 132MHz - 1 = 12,2 => 13
    // RELAX_READ = 10ns * 132MHz -1 = 0,32 => 1
    // RELAX_PROG = 1000ns * 132MHz - 1 = 131
    // STROBE_PROG = 10us * 132MHz + 2 * (RELAX_PROG + 1) - 1 = 10us * 132MHz + 2 * (131 + 1) - 1 = 1583
    // STROBE_READ = 40ns * 132MHz + 2 * (RELAX_READ + 1) - 1 = 40ns * 132MHz + 2 * (1 + 1) - 1 = 8,28 => 9
 //
 // For 150 MHz:
 // TIMING_WAIT = 150ns * 150MHz - 1 = 21,5 => 22
    // RELAX = 100ns * 150MHz - 1 = 14,0 => 14
    // RELAX_READ = 10ns * 150MHz - 1 = 0,5 => 1
    // RELAX_PROG = 1000ns * 150MHz - 1 = 149
    // STROBE_PROG = 10us * 150MHz + 2 * (RELAX_PROG + 1) - 1 = 10us * 150MHz + 2 * (131 + 1) - 1 = 1763
    // STROBE_READ = 40ns * 150MHz + 2 * (RELAX_READ + 1) - 1 = 40ns * 150MHz + 2 * (1 + 1) - 1 = 11,0 => 11
 //
 // If BT_FUSE_SEL (bit 4) is not set already then burn it (and FORCE_INTERNAL_BOOT)
 if (!(SRC->SBMR2 & SRC_SBMR2_BT_FUSE_SEL_MASK)) {
  //
  // Based on ipg_clk = 132 MHz => 1/f = 7.576 nS
  int timing = OCOTP_TIMING_STROBE_PROG(1583) | OCOTP_TIMING_RELAX(13) | OCOTP_TIMING_STROBE_READ(9) | OCOTP_TIMING_WAIT(19); //ipg_clk=132MHz, Calculation described at Chapter 22.4.3 (Rev.2) OTP Read/Write Timing Parameters
  int timing2 = OCOTP_TIMING2_RELAX_READ(1) | OCOTP_TIMING2_RELAX_PROG(131);
  //
  // Based on ipg_clk = 150 MHz => 1/f = 6.67 nS
  // int timing = OCOTP_TIMING_STROBE_PROG(1763) | OCOTP_TIMING_RELAX(14) | OCOTP_TIMING_STROBE_READ(11) | OCOTP_TIMING_WAIT(22); // ipg_clk=150MHz, Calculation described at Chapter 22.4.3 OTP Read/Write Timing Parameters
  // int timing2 = OCOTP_TIMING2_RELAX_READ(1) | OCOTP_TIMING2_RELAX_PROG(131);
  // 
  OCOTP->TIMING = timing;
  OCOTP->TIMING2 = timing2;
  while ((OCOTP->CTRL & (1<<OCOTP_CTRL_BUSY_SHIFT)) || (OCOTP->CTRL & (1<<OCOTP_CTRL_ERROR_SHIFT))); // Check that HW_OCOTP_CTRL[BUSY] and HW_OCOTP_CTRL[ERROR]are clear
  int ocotp_ctrl = OCOTP->CTRL;
  ocotp_ctrl &= ~OCOTP_CTRL_ADDR_MASK;
  ocotp_ctrl |= OCOTP_CTRL_ADDR(6); // Set address 6
  ocotp_ctrl &= ~OCOTP_CTRL_WR_UNLOCK_MASK ;
  ocotp_ctrl |= OCOTP_CTRL_WR_UNLOCK(0x3E77); // WR_UNLOCK sequence
  OCOTP->CTRL = ocotp_ctrl; // Write ADDR and unlock
  //OCOTP->DATA = (long)((1<<4)|(1<<16));// burn both BT_FUSE_SEL (1<<4) and FORCE_INTERNAL_BOOT (1<<16)
  OCOTP->DATA = (long)((1<<4));// burn only BT_FUSE_SEL (1<<4)
 }
}