Search code examples
c++embeddedmicrocontrollerfirmware

Validation of Latch LS374 data


I'm using LS374 Latch, and I have two of them. I have captured the data that goes into the latch, and that outputs from the latch, at clock signal. I recorded the data from logic analyzer that goes to and out to the latches into a text file. I wrote a small C++ program that checks if the latch is working probably or not. here is my sample processing code, IOWR is clock signal to LS374

The problem is I get some time slices that latch are incorrect, as shown in the figure is my approach correct of validating the data ? enter image description here

MVP:

#include <iostream>
#include <iomanip>
#include <vector>
#include <sstream>
#include <fstream>
#include <string>

using namespace std;

struct Data {
    double time;
    int latchA1, latchCS1, latchCS2;
    int D0, D1, D2, D3;
    int IOWR;
    int MPC_A1, MPC_CS1, MPC_CS2;
    int MPC_D0, MPC_D1, MPC_D2, MPC_D3;
};

// Function to load data from a text file
vector<Data> loadData(const string& filename) {
    vector<Data> dataList;
    ifstream file(filename);

    if (!file.is_open()) {
        cerr << "Error opening file." << endl;
        return dataList;
    }

    string line;
    while (getline(file, line)) {
        stringstream ss(line);
        Data data;
        char comma;
        ss >> data.time >> comma
            >> data.latchA1 >> comma
            >> data.latchCS1 >> comma
            >> data.latchCS2 >> comma
            >> data.D0 >> comma
            >> data.D1 >> comma
            >> data.D2 >> comma
            >> data.D3 >> comma
            >> data.IOWR >> comma
            >> data.MPC_A1 >> comma
            >> data.MPC_CS1 >> comma
            >> data.MPC_CS2 >> comma
            >> data.MPC_D0 >> comma
            >> data.MPC_D1 >> comma
            >> data.MPC_D2 >> comma
            >> data.MPC_D3;
        dataList.push_back(data);
    }

    file.close();
    return dataList;
}

// Function to combine Qs (Latch Outputs) into a single hex value
string combineQsToHex(const Data& data) {
    // Combine Latch outputs into an 8-bit value
    int latchOutput = (data.latchA1 << 6) | (data.latchCS1 << 5) | (data.latchCS2 << 4) | (data.D0 << 3) | (data.D1 << 2) | (data.D2 << 1) | data.D3;
    stringstream ss;
    ss << hex << setw(2) << setfill('0') << latchOutput;
    return ss.str();
}

// Function to combine Ds (MPC Inputs) into a single hex value
string combineDsToHex(const Data& data) {
    // Combine MPC inputs into an 8-bit value
    int mpcInput = (data.MPC_A1 << 6) | (data.MPC_CS1 << 5) | (data.MPC_CS2 << 4) | (data.MPC_D0 << 3) | (data.MPC_D1 << 2) | (data.MPC_D2 << 1) | data.MPC_D3;
    stringstream ss;
    ss << hex << setw(2) << setfill('0') << mpcInput;
    return ss.str();
}

// Function to print hex data
void printHexData(const Data& data) {
    cout << "Time: " << fixed << setprecision(10) << data.time << "s\t";
    cout << "Latch Output (Hex): 0x" << combineQsToHex(data) << "\t";
    cout << "MPC Input (Hex): 0x" << combineDsToHex(data) << endl;
}

// Function to process latch data
void processLatchData(const vector<Data>& dataList) {
    bool lastIOWRWas1 = false;
    bool transitionDetected = false;

    for (const auto& data : dataList) {
        if (data.IOWR == 0 && lastIOWRWas1 && !transitionDetected) {
            // Detected transition from 1 to 0
            transitionDetected = true;
        }
        else if (data.IOWR == 1 && transitionDetected) {
            // Detected transition from 0 to 1
            string latchHex = combineQsToHex(data);
            string mpcHex = combineDsToHex(data);
            if (latchHex == mpcHex) {
                printHexData(data);
            }
            else {
                cout << "Incorrect latch at time: " << fixed << setprecision(10) << data.time << "s" << endl;
                printHexData(data);
            }
            transitionDetected = false; // Reset the transition detection flag
        }
        lastIOWRWas1 = (data.IOWR == 1);
    }
}

int main() {
    string filename = "data.txt";  // Specify your filename here
    vector<Data> dataList = loadData(filename);

    if (dataList.empty()) {
        cerr << "No data to process." << endl;
        return 1;
    }

    processLatchData(dataList);

    return 0;
}

Sample Data file:

https://www.mediafire.com/file/7uwi4ur1d6iosn5/30.07.2024+without+internal+lcd2.rar/file


Solution

  • According to the datasheet Qn is valid and stable when both /OC and CLK are low. It is not clear what signal you are using for /OC, but you are reading the Q data when CLK is high which is clearly incorrect. truth table

    You need to acquire the D data on CLK 0->1 and the Q data On CLK 1->0

    By capturing Q on the rising clock, you are in a device propagation race condition dependent on the asynchronous sampling of the logic analyser. The propagation time D to Q on a clock edge is 15 to 28 nanoseconds, so reading Q on the clock edge is not going to work reliably.