Good day,
I am running into a problem with PGA308 when programming OTP memory. All OTP registers return 0xFF. The system is powered off of 5V power supply the entire time.
Here are my calibration steps:
1) Run calibration loop in Software Lock mode - no problem. Here is the function that I am implemented for that:
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) Loop also polls the PGA over I2C, and as soon as we hit the mid-range readout, I want to write calibration values into OTP.
3) Writing in to OTP looks as following:
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); }
Here is the implementation of 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); }
What I observe is that the OTP BSY bit never sets, and when I read OTP back all I get is 0xFF. I have confirmed with the logic analyzer that I am not writing 0xFFs at all.
What am I doing wrong? I also attached schematics snippet for your reference. Thanks!