diff --git a/SDPPython/prototype3/chip.py b/SDPPython/prototype3/chip.py new file mode 100644 index 0000000..f108118 --- /dev/null +++ b/SDPPython/prototype3/chip.py @@ -0,0 +1,130 @@ +import json +import serial +class IC74Series: + def __init__(self, chip_number, logic_type,n,TruthTable=[],pin_count=14, description=None, pin_config=None): + """ + Initializes a 74 series IC chip. + + :param chip_number: The number associated with the IC (e.g., '7400', '74138'). + :param logic_type: Type of logic gate/function the IC performs (e.g., 'NAND', 'Multiplexer'). + :param pin_count: Number of pins on the chip, defaults to 14 for most 74 series ICs. + :param description: Optional description of the IC's function. + :param pin_config: A dictionary mapping each pin to its type (input, output, VCC, ground). + """ + self.chip_number = chip_number + self.logic_type = logic_type + self.pin_count = pin_count + self.inputn = n + self.TruthTable = TruthTable + self.description = description if description else "No description provided." + self.pin_config = pin_config if pin_config else {} + + def set_pin(self, pin_number, pin_type): + """ + Sets the type of a specific pin (input, output, VCC, or ground). + + :param pin_number: The pin number (1-based index). + :param pin_type: The type of the pin ('input', 'output', 'VCC', 'ground'). + """ + if 1 <= pin_number <= self.pin_count: + self.pin_config[pin_number] = pin_type + else: + raise ValueError(f"Invalid pin number. This IC has {self.pin_count} pins.") + + def get_pin(self, pin_number): + """ + Returns the type of a specific pin. + + :param pin_number: The pin number (1-based index). + :return: The type of the pin ('input', 'output', 'VCC', or 'ground') or 'not configured'. + """ + return self.pin_config.get(pin_number, "not configured") + + def get_details(self): + """ + Returns the details of the IC as a string. + """ + return f"74{self.chip_number} IC - Logic Type: {self.logic_type}, Pins: {self.pin_count}, Description: {self.description}" + + def pin_configuration(self): + """ + Returns a formatted string with the pin configuration. + """ + config_str = f"Pin Configuration for 74{self.chip_number}:\n" + for pin in range(1, self.pin_count + 1): + pin_type = self.get_pin(pin) + config_str += f"Pin {pin}: {pin_type}\n" + return config_str + + def is_standard_pin_count(self): + """ + Checks if the IC has a standard pin count of 14. + """ + return self.pin_count == 14 + + def __str__(self): + return f"74{self.chip_number} ({self.logic_type})" + + def pin_configuration_json(self): + """ + Returns the pin configuration as a JSON string. + """ + config = { + "chip_number": self.chip_number, + "logic_type": self.logic_type, + "pin_count": self.pin_count, + "description": self.description, + "pins": self.pin_config + } + return json.dumps(config) + + def send_pin_configuration(self, uart_port, baudrate=250000): + """ + Sends the pin configuration as a JSON string over UART. + + :param uart_port: The UART port (e.g., 'COM3' on Windows or '/dev/ttyUSB0' on Linux). + :param baudrate: The baudrate for UART communication. + """ + json_data = self.pin_configuration_json() + #print("JSON Data to be sent:", json_data) + #raw_bytes = json_data.encode('utf-8') + #hex_bytes = [f"{byte:02x}" for byte in raw_bytes] # Convert bytes to hex + #print("Raw Bytes (Hex) to be sent:", ' '.join(hex_bytes)) # Print hex bytes as a space-separated string + with serial.Serial(uart_port, baudrate, timeout=10000000) as ser: + ser.write(json_data.encode('utf-8')) + print(f"Sent JSON data over UART: {json_data}") + def set_truth_table(self,outputs): + self.TruthTable=binary_number_list(self.inputn,outputs) + + def print_truth_tale(self): + print(f"Chip: {self.chip_number}") + print(f"Logic type: {self.logic_type}") + print("INPUT BITS|OUTPUT BITS") + for entry in self.TruthTable: + print(f" {entry[0]} {entry[1]}") + +def binary_number_list(bits,outputs): + list = [] + bits = int(bits) + for number in range(0,(2**bits)): + bitslist = separate_bits(number,bits) + list.append([bitslist,outputs[number]]) + return list + +def separate_bits(num, n): + bits = [(num >> i) & 1 for i in range(n)] # Extract each bit + return bits[::-1] # Return in correct order + +def find_input_pins(ic): + n = ic.inputn + + inputpins = [] + temp = [] + for pin in range(1,ic.pin_count+1): + print("PIN NUMBER IS: ", pin, ic.get_pin(pin)) + if(ic.get_pin(pin) == "input"): + temp.append(pin) + if len(temp) == n: + inputpins.append(temp) + temp=[] + return inputpins \ No newline at end of file diff --git a/SDPPython/prototype3/circuits/test.txt b/SDPPython/prototype3/circuits/test.txt new file mode 100644 index 0000000..b10fa1d --- /dev/null +++ b/SDPPython/prototype3/circuits/test.txt @@ -0,0 +1,20 @@ +Chip Number: 00 +Logic Type: NAND +Number of Inputs: 2 +Description: Quad 2-input NAND gate +Truth Table: [1,1,1,0] +Pin Count: 14 +1: INPUT +2: INPUT +3: OUTPUT +4: INPUT +5: INPUT +6: OUTPUT +7: GND +8: OUTPUT +9: INPUT +10: INPUT +11: OUTPUT +12: INPUT +13: INPUT +14: VCC \ No newline at end of file diff --git a/SDPPython/prototype3/prototype3.py b/SDPPython/prototype3/prototype3.py new file mode 100644 index 0000000..72f8579 --- /dev/null +++ b/SDPPython/prototype3/prototype3.py @@ -0,0 +1,174 @@ +import tkinter as tk +from tkinter import ttk, filedialog +import os +import json + +# dictionary to store dropdown variables and status labels for each pin +dropdown_vars = {} +status_labels = {} + +# folder path, default is None until user selects one +folder_path = None + +def option_selected(pin_num): + print(f"Selected for Pin {pin_num}: {dropdown_vars[pin_num].get()}") + +def select_folder(): + global folder_path + # open a dialog to select a folder and update the folder path + folder_path = filedialog.askdirectory(initialdir=".", title="Select Circuit Folder") + if folder_path: + print(f"Selected folder: {folder_path}") + display_label.config(text="Folder selected.", fg="green") + +def get_file_names(folder_path): + try: + # get only files (not directories) in the specified folder + return [f for f in os.listdir(folder_path) if os.path.isfile(os.path.join(folder_path, f))] + except FileNotFoundError: + print("The specified folder was not found.") + return [] + +def generate_pin_fields(): + if folder_path is None: + display_label.config(text="No folder selected. Please select a folder.", fg="red") + return + + try: + file_names = get_file_names(folder_path) + if not file_names: + display_label.config(text="No files found in the folder.", fg="red") + return + + num_pins = int(pin_entry.get()) + + # clears pin fields if any + for widget in pin_canvas_frame.winfo_children(): + widget.destroy() + dropdown_vars.clear() + status_labels.clear() + + # generates the fields for each pin + for i in range(1, num_pins + 1): + tk.Label(pin_canvas_frame, text=f"Pin {i}").grid(row=i, column=0, padx=5, pady=5) + + dropdown_var = tk.StringVar() + dropdown_vars[i] = dropdown_var # store variable for each pin in dict + + dropdown = ttk.Combobox(pin_canvas_frame, textvariable=dropdown_var, state="readonly") + dropdown['values'] = file_names + dropdown.grid(row=i, column=1, padx=5, pady=5) + dropdown.bind("<>", lambda e, pin_num=i: option_selected(pin_num)) + + # status label for each dropdown + status_label = tk.Label(pin_canvas_frame, text="", font=("Arial", 10)) + status_label.grid(row=i, column=2, padx=10, pady=5) + status_labels[i] = status_label # store status label for each pin in dict + + pin_canvas_frame.update_idletasks() + pin_canvas.config(scrollregion=pin_canvas.bbox("all")) + display_label.config(text="") + + except ValueError: + display_label.config(text="Please enter a valid number of pins.", fg="red") + +# function to send selected file for specific pin number +def send(pin_num): + selected_file = dropdown_vars[pin_num].get() + file_path = os.path.join(folder_path, selected_file) + + circuit_data = {} + try: + with open(file_path, 'r') as file: + for line in file: + # Split each line by ":" + key, value = line.strip().split(":") + key = key.strip() + value = value.strip() + + # Add parsed data to dictionary + circuit_data[key] = value + + # convert dictionary to JSON format + circuit_json = json.dumps(circuit_data, indent=2) + print(f"JSON for Pin {pin_num}:\n{circuit_json}") + + # usb_send(circuit_json) or smth + + except Exception as e: + print(f"An error occurred while reading {selected_file}: {e}") + + + # simulate sending and recieving and turning it into True or False + return pin_num % 2 == 0 + +def check_circit(): + if folder_path is None: + display_label.config(text="No folder selected. Please select a folder.", fg="red") + return + + status_list = [] + for pin_num in range(1, len(dropdown_vars) + 1): + if dropdown_vars[pin_num].get() =='': + status_list.append('empty') + else: + result = send(pin_num) + status_list.append(result) + + # update statuses based on results + display_results(status_list) + +# function to change display if circuit works or not +# needs list of True or False from logic check +def display_results(status_list): + for i in range(len(status_list)): + if status_list[i] == 'empty': + status_labels[i+1].config(text="Please select a circuit", fg="orange") + elif status_list[i]: + status_labels[i+1].config(text="Circuit works", fg="green") + else: + status_labels[i+1].config(text="Circuit does not work", fg="red") + +root = tk.Tk() +root.title("Circuit GUI Prototype") + +# input for the number of pins +pin_label = tk.Label(root, text="Number of Pins:") +pin_label.grid(row=0, column=0, padx=10, pady=10) +pin_entry = tk.Entry(root) +pin_entry.grid(row=0, column=1, padx=10, pady=10) + +generate_button = tk.Button(root, text="Generate Pins", command=generate_pin_fields) +generate_button.grid(row=0, column=2, padx=10, pady=10) + +# frame to hold the canvas and scrollbar +container = tk.Frame(root) +container.grid(row=1, column=0, columnspan=3, padx=10, pady=10) + +pin_canvas = tk.Canvas(container, width=400, height=400) +pin_canvas.grid(row=0, column=0) + +# scrollbar for the canvas +scrollbar = tk.Scrollbar(container, orient="vertical", command=pin_canvas.yview) +scrollbar.grid(row=0, column=1, sticky="ns") +pin_canvas.config(yscrollcommand=scrollbar.set) + +# frame inside the canvas to hold pin fields +pin_canvas_frame = tk.Frame(pin_canvas) +pin_canvas.create_window((0, 0), window=pin_canvas_frame, anchor="nw") + +# display label +display_label = tk.Label(root, text="", font=("Arial", 14)) +display_label.grid(row=2, column=0, columnspan=3, padx=10, pady=10) + +# buttons +button1 = tk.Button(root, text="Check", command=check_circit) +button1.grid(row=3, column=0, padx=10) + +button2 = tk.Button(root, text="Select Folder", command=select_folder) +button2.grid(row=3, column=1, padx=10) + +button3 = tk.Button(root, text="Button 3") +button3.grid(row=3, column=2, padx=10) + +root.mainloop()