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.

[参考译文] PGA308:OTP 存储器未编程

Guru**** 2468460 points
Other Parts Discussed in Thread: PGA308, PGA308EVM

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/amplifiers-group/amplifiers/f/amplifiers-forum/1011676/pga308-otp-memory-does-not-program

器件型号:PGA308

你好、  

对 OTP 存储器进行编程时、遇到 PGA308问题。 所有 OTP 寄存器返回0xFF。 系统在整个过程中都由5V 电源供电。

以下是我的校准步骤:  

1) 1) 在软件锁定模式下运行校准循环-没问题。 以下是我为此实现的函数:  


    void calRunInRam(int8_t coarse_offset)
    {
        uint16_t cfg0 = 0x0000;
        cfg0 = cfg0 | PGA308_OUTPUT_GAIN__2 << 13; //Output gain in the D[15:13]
        cfg0 = cfg0 | (0 << 12); // Input mux in D12
        cfg0 = cfg0 | PGA308_INPUT_GAIN__200 << 8; // Input gain in D[11:8]
        if (coarse_offset < 0){
            cfg0 = cfg0 | 0x80 | abs(coarse_offset); // Offset in D[7:0]
        } else {
            cfg0 = cfg0 | abs(coarse_offset); // Offset in D[7:0]
        }

        bankValues[PGA308_REG__ZDAC] = 0x0000;
        bankValues[PGA308_REG__GDAC] = 0x4000;
        bankValues[PGA308_REG__CFG0] = cfg0;
        bankValues[PGA308_REG__CFG1] = 0x1780;
        //bankValues[PGA308_REG__CFG2] = 0x0C00; // for 5V system
        bankValues[PGA308_REG__CFG2] = 0x0800; // for 3V system
        bankValues[PGA308_REG__CHKS] = calculateChecksum(bankValues, 5);
        
        // Enter Software Lock Mode
        writeRAMReg(PGA308_REG__SFTC, PGA308_SFTC__SWL_SOFTLOCK);

        // Write stored registers
        writeRAMReg(PGA308_REG__ZDAC, bankValues[PGA308_REG__ZDAC]);
        writeRAMReg(PGA308_REG__GDAC, bankValues[PGA308_REG__GDAC]);
        writeRAMReg(PGA308_REG__CFG0, bankValues[PGA308_REG__CFG0]);
        writeRAMReg(PGA308_REG__CFG1, bankValues[PGA308_REG__CFG1]);
        writeRAMReg(PGA308_REG__CFG2, bankValues[PGA308_REG__CFG2]);
        writeRAMReg(PGA308_REG__CHKS, bankValues[PGA308_REG__CHKS]);
    }

2) 2) Loop 也会通过 I2C 轮询 PGA、一旦我们达到中程读取值、我想将校准值写入 OTP。

3) 3)写入 OTP 如下:

    void calSaveIntoOTPMem(int8_t coarse_offset)
    {
        // Enter standalone mode
        
        writeRAMReg(PGA308_REG__SFTC, 0x0000);
        writeRAMReg(PGA308_REG__OTPS, 0x8000); // OTP EN
        readRAMReg(PGA308_REG__OTPS);

        //lets write all the registers first

        writeOTPReg(PGA308_BANK__U1, PGA308_REG__ZDAC, bankValues[PGA308_REG__ZDAC]);
        writeOTPReg(PGA308_BANK__U1, PGA308_REG__GDAC, bankValues[PGA308_REG__GDAC]);
        writeOTPReg(PGA308_BANK__U1, PGA308_REG__CFG0, bankValues[PGA308_REG__CFG0]);
        writeOTPReg(PGA308_BANK__U1, PGA308_REG__CFG1, bankValues[PGA308_REG__CFG1]);
        writeOTPReg(PGA308_BANK__U1, PGA308_REG__CFG2, bankValues[PGA308_REG__CFG2]);
        writeOTPReg(PGA308_BANK__U1, PGA308_REG__CHKS, bankValues[PGA308_REG__CHKS]);

        writeOTPReg(PGA308_BANK__FTEST, PGA308_OTP_REG_BSEL1, 0x0001);
            
        writeRAMReg(PGA308_REG__OTPS, 0x0000); // OTP EN
        writeRAMReg(PGA308_REG__SFTC, 0x0000);
        delay(3);
        
        //lets confirm all the registers by reading them
        readRAMReg(PGA308_REG__SFTC);
        readRAMReg(PGA308_REG__OTPS);
        readOTPReg(PGA308_BANK__FTEST, PGA308_OTP_REG_BSEL3);
        readOTPReg(PGA308_BANK__U3, PGA308_REG__ZDAC);
        readOTPReg(PGA308_BANK__U3, PGA308_REG__GDAC);
        readOTPReg(PGA308_BANK__U3, PGA308_REG__CFG0);
        readOTPReg(PGA308_BANK__U3, PGA308_REG__CFG1);
        readOTPReg(PGA308_BANK__U3, PGA308_REG__CFG2);
        readOTPReg(PGA308_BANK__U3, PGA308_REG__CHKS);
    }

以下是 writeOTPReg 的实现:

    void kickOneWire()
    {
        Serial1.write(PGA308_SYNC);
        Serial1.flush();
    }

    void writeRAMReg(uint8_t ptr, uint16_t value)
    {
        kickOneWire();
        uint8_t buf[3];

        buf[0] = PGA308_ACCESS_RAM | PGA308_ACCESS_WRITE | ptr;
        buf[1] = value & 0xFF;
        buf[2] = value >> 8;
        
        Serial1.write(buf,3);
        Serial1.flush();
    }

    void writeOTPReg(uint8_t bank_ptr, uint8_t reg_ptr, uint16_t value)
    {
        kickOneWire();

        uint8_t buf[4];

        // Transfer sync, addr and data
        buf[0] = PGA308_ACCESS_OTP | PGA308_ACCESS_WRITE | (bank_ptr << 3) | reg_ptr;
        buf[1] = value & 0xFF;
        buf[2] = value >> 8;
        
        Serial1.write(buf,3);
        Serial1.flush();
                readRAMReg(PGA308_REG__OTPS);
        delay(4); //mandatory 3ms delay white OTP is being written
                readRAMReg(PGA308_REG__OTPS);
    }

我观察到 OTP BSY 位永远不会置位、当我读回 OTP 时、我得到的全部为0xFF。 我已通过逻辑分析仪确认我根本不写入0xFFs。

我出了什么问题? 我还附上了原理图片段供您参考。 谢谢!

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Dmitrii、

    我正在研究这一点、但我有几个有关您设置的基本启动问题、因为我不想做出任何假设。

    1.只是为了确认、您在对器件进行编程时使用的是5V 电源、而不是原理图中显示的3.3V 电源? 如果器件电源低于~4.5V、OTP 将无法编程。
    2.您是使用 PGA308EVM 进行编程、还是使用外部终端/不同的软件和硬件?
    3、1W 线路上是否有未在原理图中显示的上拉电阻器、如果有、其值是多少?
    4.您是否在从未使用过 OTP 的全新 PGA308器件上进行了测试?

    还有其他一些问题。

    5.您是否能够确认正在为 CHKS 寄存器计算正确的校验和?
    6.在软件锁定模式下写入 RAM 寄存器后,您是否能够成功读回这些寄存器,以验证它们是否被正确写入?
    7.您是否能够确认设备已成功退出软件锁定模式? OTP EN 位是否确实设置为高电平?

    谢谢、

    Jon

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 JMAC、  

    感谢后续问题。 答案如下:  

    1.是的、在 VS 和 VREF、VCLAMP 上使用~4.98V 电压并用于电桥偏置、而不是原理图上所示的 VDD_3V3。

    2、3。 我使用的是5V Arduino 兼容板、具有两个可形成同相开漏输出的 PFET、上拉值为4.7K。

    4、是的、我已经在两个板上进行了测试、其中一个板从未进行过编程。 两者都表现出类似的行为、在有充分理由这样做之前、我不想再多砖型板。 我已经尝试对不同的用户组进行编程、相同的行为仍然存在。  

    5.使用用户指南的值检查了我的校验和实现-看起来正确。 但我想问题发生在较早的时候、因为寄存器似乎永远不会写入正确的值。

    6.是的、读取 RAM 寄存器工作正常。  

    7.当我尝试对 OTP 进行编程时、OTP EN 位确实是高电平。  我还将介绍逻辑分析仪的布线。 我观察到的问题是 OTP BSY 永远不会被置位。 模拟波形位于底部、供您检查波形和电压电平。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Dmitrii、

    感谢您确认您的设置详细信息并分享波形。 从硬件角度来看、电路配置似乎是正确的。

    您是否可以在软件锁定模式下尝试运行 OTP 脚本? 也就是说、在写入 OTP 存储器(calSaveIntoOTPMem 脚本中的第5行)之前、不要进入独立模式、而是等待写入完成后进入独立模式(正如您在该脚本的第21行上所做的那样)。

    谢谢、

    Jon

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Dmitrii、

    您是否能够在软件锁定模式下成功对 OTP 寄存器进行编程? EVM 的源代码中有一条注释、提示用户可能需要处于此模式才能成功执行 OTP 写入序列、尽管这一点并不特别清楚。 如果这不能解决问题、请告知我、我可以查看其他解决方案。

    谢谢、

    Jon