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.

PGA460: EEPROM CRC value

Part Number: PGA460

Tool/software:

Hello all,

I am trying to develop a library for PGA460 to use with STM32F302 in a meteo station prototype.

This station has 3x PGA460, each connected to a different UART port. I am able to communicate with the sensor but my issue is that when I read the measurement result I am getting first byte as 0x40 for diagnostic.

I am powering the PGA460 from 8V/500ma, I use UTR_1440K_TT_R as transducer connected to PGA with a  750317161, the schematic is shown below.

My debug output is below, Can some one help me understand whey the EEPROM CRC in EEPROM is different from the calculated one?

Also after EEPROM burn and power cycle my settings are not preserved, this is not a big deal as I can set them at each reset but it will be nice to understand.

Sensor 0: Initializing Communication...
Sensor 0: Threshold Level Set to 25%.
Sensor 0: Threshold Written Successfully.
Sensor 0: EEPROM Control Register (EE_CTRL) = 0x00
Sensor 0: Ultrasonic Command 0 Executed Successfully!
Sensor 0: Frequency Diagnostic = 41.67 kHz
Sensor 0: Ultrasonic Command 0 Executed Successfully!
Sensor 0: Decay Period Diagnostic = 4080.00 us
Sensor 0: Temperature (C) Data: 32.00
Sensor 0: Die Temperature = 32.00 C
Sensor 0: Noise Level Data: 23.00
Sensor 0: Noise Level = 23 (8-bit raw)
Sensor 0: EEPROM Bulk Write Data (45 bytes):
0x55 0x0C 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x9D 0xEE 0xEF 0x2D 0xB9 0xEF 0xDC 0x03 0x32 0x80
0x08 0x12 0x32 0x32 0x00 0x33 0xEE 0x3C 0x8F 0x00 0x00 0x05 0x05 0x97
-------------------------------------------------------------------
Sensor 0: Bulk Write to Volatile Memory Successful!
Sensor 0: EEPROM Bulk Read Successful!
Sensor 0: EEPROM Read-Back Data (45 bytes):
0x40 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x9D 0xEE 0xEF 0x2D 0xB9 0xEF 0xDC 0x03 0x32 0x80 0x08
0x12 0x32 0x32 0x00 0x33 0xEE 0x3C 0x8F 0x00 0x00 0x05 0x05 0x63
Sensor 0: EEPROM Data Verified Successfully!
Sensor 0: EEPROM CRC Mismatch! Expected 0xA3, Read 0x63
Sensor 0: EEPROM Check failed.
Sensor 0: TVG Bulk Write Successful!


Sensor 1: Initializing Communication...
Sensor 1: Threshold Level Set to 25%.
Sensor 1: Threshold Written Successfully.
Sensor 1: EEPROM Control Register (EE_CTRL) = 0x00
Sensor 1: Ultrasonic Command 0 Executed Successfully!
Sensor 1: Frequency Diagnostic = 41.67 kHz
Sensor 1: Ultrasonic Command 0 Executed Successfully!
Sensor 1: Decay Period Diagnostic = 4080.00 us
Sensor 1: Temperature (C) Data: 28.67
Sensor 1: Die Temperature = 28.67 C
Sensor 1: Noise Level Data: 16.00
Sensor 1: Noise Level = 16 (8-bit raw)
Sensor 1: EEPROM Bulk Write Data (45 bytes):
0x55 0x0C 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x9D 0xEE 0xEF 0x2D 0xB9 0xEF 0xDC 0x03 0x32 0x80
0x08 0x12 0x32 0x32 0x00 0x33 0xEE 0x3C 0x8F 0x00 0x00 0x05 0x05 0x97
-------------------------------------------------------------------
Sensor 1: Bulk Write to Volatile Memory Successful!
Sensor 1: EEPROM Bulk Read Successful!
Sensor 1: EEPROM Read-Back Data (45 bytes):
0x40 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x9D 0xEE 0xEF 0x2D 0xB9 0xEF 0xDC 0x03 0x32 0x80 0x08
0x12 0x32 0x32 0x00 0x33 0xEE 0x3C 0x8F 0x00 0x00 0x05 0x05 0x63
Sensor 1: EEPROM Data Verified Successfully!
Sensor 1: EEPROM CRC Mismatch! Expected 0xA3, Read 0x63
Sensor 1: EEPROM Check failed.
Sensor 1: TVG Bulk Write Successful!


Sensor 2: Initializing Communication...
Sensor 2: Threshold Level Set to 25%.
Sensor 2: Threshold Written Successfully.
Sensor 2: EEPROM Control Register (EE_CTRL) = 0x00
Sensor 2: Ultrasonic Command 0 Executed Successfully!
Sensor 2: Frequency Diagnostic = 40.82 kHz
Sensor 2: Ultrasonic Command 0 Executed Successfully!
Sensor 2: Decay Period Diagnostic = 4080.00 us
Sensor 2: Temperature (C) Data: 30.67
Sensor 2: Die Temperature = 30.67 C
Sensor 2: Noise Level Data: 21.00
Sensor 2: Noise Level = 21 (8-bit raw)
Sensor 2: EEPROM Bulk Write Data (45 bytes):
0x55 0x0C 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x9D 0xEE 0xEF 0x2D 0xB9 0xEF 0xDC 0x03 0x32 0x80
0x08 0x12 0x32 0x32 0x00 0x33 0xEE 0x3C 0x8F 0x00 0x00 0x05 0x05 0x97
-------------------------------------------------------------------
Sensor 2: Bulk Write to Volatile Memory Successful!
Sensor 2: EEPROM Bulk Read Successful!
Sensor 2: EEPROM Read-Back Data (45 bytes):
0x40 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x9D 0xEE 0xEF 0x2D 0xB9 0xEF 0xDC 0x03 0x32 0x80 0x08
0x12 0x32 0x32 0x00 0x33 0xEE 0x3C 0x8F 0x00 0x00 0x05 0x05 0x63
Sensor 2: EEPROM Data Verified Successfully!
Sensor 2: EEPROM CRC Mismatch! Expected 0xA3, Read 0x63
Sensor 2: EEPROM Check failed.
Sensor 2: TVG Bulk Write Successful!


PGA460 Initialization Complete.


Sensor 0: Ultrasonic Command 0 Executed Successfully!
Sensor 0: Echo Data Dump Diagnostic Error! Code: 64
Sensor 0: Echo Data Dump (130 bytes): 0x40 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xF4 0xE4 0xD4 0xC8 0xBC 0xBC 0xD0 0xF8 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0x05Sensor 0: Ultrasonic Command 0 Executed Successfully!
PGA_OBJ_DATA_SIZE 6!
Sensor 0, Obj 1 - Distance: 11.24 m, Width: 4080 us, Amplitude: 191


Sensor 1: Ultrasonic Command 0 Executed Successfully!
Sensor 1: Echo Data Dump Diagnostic Error! Code: 64
Sensor 1: Echo Data Dump (130 bytes): 0x40 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFC 0xDC 0xBC 0xA4 0x90 0x80 0x78 0x74 0x80 0x98 0xBC 0xEC 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xC3Sensor 1: Ultrasonic Command 0 Executed Successfully!
PGA_OBJ_DATA_SIZE 6!
Sensor 1, Obj 1 - Distance: 11.24 m, Width: 4080 us, Amplitude: 191


Sensor 2: Ultrasonic Command 0 Executed Successfully!
Sensor 2: Echo Data Dump Diagnostic Error! Code: 64
Sensor 2: Echo Data Dump (130 bytes): 0x40 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xE4 0xCC 0xBC 0xB0 0xA8
0xA4 0x9C 0x98 0x98 0x98 0x9C 0xA0 0xA4 0xA4 0xA4 0xA0 0x98 0x84 0x84 0xA8 0xE4
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xF1Sensor 2: Ultrasonic Command 0 Executed Successfully!
PGA_OBJ_DATA_SIZE 6!
Sensor 2, Obj 1 - Distance: 11.24 m, Width: 4080 us, Amplitude: 191

Thank you for your support.

  • Hi Ion,

    Thank you for posting to the Sensors forum!

    Can some one help me understand whey the EEPROM CRC in EEPROM is different from the calculated one?

    Are you able to share how you are calculating CRC?

    Also after EEPROM burn and power cycle my settings are not preserved, this is not a big deal as I can set them at each reset but it will be nice to understand.

    Just as a sanity check, to burn the EEPROM, are you following the steps mentioned in section 7.6.1 of the datasheet:

    To program the EEPROM, follow these steps:

    1. Send an EEPROM program command using UART or TCI with a unique unlock pattern on 4-bits. The program bit is set to 0 in register 0x40. The unlock passcode is 0x Dh.
    2. Immediately send the same UART or TCI command with the program bit set to 1.
    3. If any other command is issued after the unlock code (Step 1), the EEPROM program is initiated. Also, if the unlock command in Step 1 is not correct, the EEPROM is not programmed. The EEPROM is locked again automatically after each program command

    Best,

    ~Alicia

  • Hello Alicia,

    Thank you for your reply, below are the answers to your questions:

    1. CheckSum function

    // Helper function to calculate checksum for a data frame
    static uint8_t PGA460_CalculateChecksum(const uint8_t *data, uint8_t len) {
    uint16_t carry = 0;
    for (uint8_t i = 0; i < len; i++) {
    carry += data[i];
    if (carry > 0xFF) {
    carry -= 255;
    }
    }
    carry = ~carry & 0xFF;
    return (uint8_t)carry;
    }

    2. The burned is called from the init function at the end

    // Function to initialize 3x PGA460 sensors
    HAL_StatusTypeDef PGA460_Init(void) {
    UART_HandleTypeDef *uartPorts[ULTRASONIC_SENSOR_COUNT] = { &huart1, &huart4, &huart5 };

    for (uint8_t i = 0; i < ULTRASONIC_SENSOR_COUNT; i++) {
    myUltraSonicArray[i].PGA460_Data = transducer;
    memcpy(&myUltraSonicArray[i].PGA460_Data.P1_THR_0, &THRESHOLD_50[0], 32); // Copy threshold settings
    myUltraSonicArray[i].uartPort = uartPorts[i];

    // **Step 1: Check Sensor Status**
    if (PGA460_CheckStatus(i) != HAL_OK) {
    DEBUG("Sensor %d: Sensor check failed. Skipping initialization.\n", i);
    return HAL_ERROR;
    }
    // **Step 2: Write Threshold to Clear THR_CRC_ERR**
    if (PGA460_SetThresholdLevel(i, PGA460_TRH_75) != HAL_OK) {
    DEBUG("Sensor %d: Threshold Write Failed!\n", i);
    return HAL_ERROR;
    }
    DEBUG("Sensor %d: Threshold Written Successfully.\n", i);

    // **Step 3: Read EEPROM Control Register**
    PGA460_RegisterRead(i, REG_EE_CTRL, &myUltraSonicArray[i].PGA460_Data.EE_CNTRL.Val.Value);
    DEBUG("Sensor %d: EEPROM Control Register (EE_CTRL) = 0x%02X\n", i, myUltraSonicArray[i].PGA460_Data.EE_CNTRL.Val.Value);

    // **Step 4: Run System Diagnostics**
    float diagValue = 0.0;
    if (PGA460_GetSystemDiagnostics(i, 1, 0, &diagValue) == HAL_OK) {
    DEBUG("Sensor %d: Frequency Diagnostic = %.2f kHz\n", i, diagValue);
    } else {
    DEBUG("Sensor %d: Frequency Diagnostic Failed!\n", i);
    }

    if (PGA460_GetSystemDiagnostics(i, 1, 1, &diagValue) == HAL_OK) {
    DEBUG("Sensor %d: Decay Period Diagnostic = %.2f us\n", i, diagValue);
    } else {
    DEBUG("Sensor %d: Decay Period Diagnostic Failed!\n", i);
    }

    // **Step 5: Read Temperature & Noise Level**
    float temperature = PGA460_ReadTemperatureOrNoise(i, PGA460_CMD_GET_TEMP);
    if (temperature != PGA460_TEMP_ERR) {
    DEBUG("Sensor %d: Die Temperature = %.2f C\n", i, temperature);
    } else {
    DEBUG("Sensor %d: Temperature Read Failed!\n", i);
    }

    float noiseLevel = PGA460_ReadTemperatureOrNoise(i, PGA460_CMD_GET_NOISE);
    if (noiseLevel != PGA460_TEMP_ERR) {
    DEBUG("Sensor %d: Noise Level = %.0f (8-bit raw)\n", i, noiseLevel);
    } else {
    DEBUG("Sensor %d: Noise Level Read Failed!\n", i);
    }

    // **Step 6: Bulk Write EEPROM (Transducer Settings)**
    if (PGA460_EEPROMBulkWrite(i) != HAL_OK) {
    DEBUG("Sensor %d: EEPROM Bulk Write failed.\n", i);
    return HAL_ERROR;
    }
    if (PGA460_VerifyEEPROM(i) != HAL_OK) {
    DEBUG("Sensor %d: EEPROM Check failed.\n", i);
    //return HAL_ERROR;
    }

    // **Step 7: Configure Time-Varying Gain (TVG)**
    if (PGA460_InitTimeVaryingGain(i, PGA460_GAIN_58_90dB, PGA460_TVG_75_PERCENT) != HAL_OK) {
    DEBUG("Sensor %d: TVG Bulk Write failed.\n", i);
    //return HAL_ERROR;
    }

    // **Step 8: Burn EEPROM (Optional - If Settings Need to Persist)**
    // if (PGA460_BurnEEPROM(i) != HAL_OK) {
    // DEBUG("Sensor %d: BurnEEPROM failed.\n", i);
    // return HAL_ERROR;
    // }
    DEBUG("\n\n");
    }

    DEBUG("PGA460 Initialization Complete.\n");
    return HAL_OK;
    }

    And the burn function is 

    HAL_StatusTypeDef PGA460_BurnEEPROM(uint8_t sensorID) {
    uint8_t burnStatus;

    // Step 1: Unlock EEPROM (Write 0x68 to REG_EE_CTRL)
    if (PGA460_RegisterWrite(sensorID, REG_EE_CTRL, PGA460_UNLOCK_EEPROM) != HAL_OK) {
    DEBUG("Sensor %d: EEPROM Unlock Failed at Step 1!\n", sensorID);
    return HAL_ERROR;
    }

    // With or withou delay I get the same result
    HAL_Delay(1); // Required minimal delay

    // Step 2: Program EEPROM (Write 0x69 to REG_EE_CTRL)
    if (PGA460_RegisterWrite(sensorID, REG_EE_CTRL, PGA460_LOCK_EEPROM) != HAL_OK) {
    DEBUG("Sensor %d: EEPROM Burn Command Failed at Step 2!\n", sensorID);
    return HAL_ERROR;
    }
    HAL_Delay(1000); // Wait for EEPROM programming to complete

    // Step 3: Verify EEPROM Burn Success (Read REG_EE_CTRL)
    if (PGA460_RegisterRead(sensorID, REG_EE_CTRL, &burnStatus) != HAL_OK) {
    DEBUG("Sensor %d: Failed to Read EE_CTRL after EEPROM Burn!\n", sensorID);
    return HAL_ERROR;
    }

    // Step 4: Check EE_PGRM_OK (Bit 2)
    if (burnStatus & 0x04) {
    DEBUG("Sensor %d: EEPROM Burn Successful! EE_CTRL = 0x%02X\n", sensorID, burnStatus);
    return HAL_OK;
    } else {
    DEBUG("Sensor %d: EEPROM Burn Failed! EE_CTRL = 0x%02X\n", sensorID, burnStatus);
    return HAL_ERROR;
    }
    }

    I use these functions to read/write single registers

    HAL_StatusTypeDef PGA460_CheckStatus(const uint8_t sensorID) {
    // Read both status registers (0x4C and 0x4D) and store directly in myUltraSonicArray
    if (PGA460_RegisterRead(sensorID, REG_DEV_STAT0, (uint8_t *)&myUltraSonicArray[sensorID].PGA460_Data.DEV_STAT0) == HAL_OK &&
    PGA460_RegisterRead(sensorID, REG_DEV_STAT1, (uint8_t *)&myUltraSonicArray[sensorID].PGA460_Data.DEV_STAT1) == HAL_OK) {
    return HAL_OK;
    }
    DEBUG("Sensor %d: Communication error! Could not read status registers.\n", (int)sensorID);
    return HAL_ERROR;
    }

    // Function to read a register from the PGA460
    HAL_StatusTypeDef PGA460_RegisterRead(const uint8_t sensorID, const uint8_t regAddr, uint8_t *regValue) {
    uint8_t frame[4] = {PGA460_SYNC, PGA460_CMD_REGISTER_READ, regAddr, 0x00};
    frame[3] = PGA460_CalculateChecksum(&frame[1], 3);

    if (HAL_UART_Transmit(myUltraSonicArray[sensorID].uartPort, frame, 4, UART_TIMEOUT) != HAL_OK) {
    DEBUG("Sensor %d: Register Read Transmission Failed! Address 0x%02X\n", sensorID, regAddr);
    return HAL_ERROR;
    }

    uint8_t response[3];
    if (HAL_UART_Receive(myUltraSonicArray[sensorID].uartPort, response, 3, UART_TIMEOUT) != HAL_OK) {
    DEBUG("Sensor %d: Register Read Failed! Address 0x%02X\n", sensorID, regAddr);
    return HAL_ERROR;
    }

    *regValue = response[1];
    return HAL_OK;
    }

    // Function to write a register on the PGA460
    HAL_StatusTypeDef PGA460_RegisterWrite(const uint8_t sensorID, const uint8_t regAddr, const uint8_t regValue) {
    uint8_t frame[5] = {PGA460_SYNC, PGA460_CMD_REGISTER_WRITE, regAddr, regValue, 0x00};
    frame[4] = PGA460_CalculateChecksum(&frame[1], 4);

    if (HAL_UART_Transmit(myUltraSonicArray[sensorID].uartPort, frame, 5, UART_TIMEOUT) != HAL_OK) {
    DEBUG("Sensor %d: Register Write Transmission Failed! Address 0x%02X\n", sensorID, regAddr);
    return HAL_ERROR;
    }

    return HAL_OK;
    }

  • Hi Ion,

    I will need some time to look at this and will try to get back to you early next week.

    Best,

    ~Alicia