{"id":29714905,"url":"https://github.com/jjsch-dev/picoswitool","last_synced_at":"2025-07-24T04:34:19.676Z","repository":{"id":293751005,"uuid":"984815033","full_name":"jjsch-dev/PicoSWITool","owner":"jjsch-dev","description":"Firmware tool for testing SWI EEPROM emulators on Raspberry Pi Pico","archived":false,"fork":false,"pushed_at":"2025-05-16T23:49:41.000Z","size":723,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-17T00:25:08.012Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jjsch-dev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-05-16T14:52:36.000Z","updated_at":"2025-05-16T23:49:45.000Z","dependencies_parsed_at":"2025-05-17T08:01:39.327Z","dependency_job_id":null,"html_url":"https://github.com/jjsch-dev/PicoSWITool","commit_stats":null,"previous_names":["jjsch-dev/picoswitool"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/jjsch-dev/PicoSWITool","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jjsch-dev%2FPicoSWITool","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jjsch-dev%2FPicoSWITool/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jjsch-dev%2FPicoSWITool/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jjsch-dev%2FPicoSWITool/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jjsch-dev","download_url":"https://codeload.github.com/jjsch-dev/PicoSWITool/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jjsch-dev%2FPicoSWITool/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266792952,"owners_count":23984839,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-24T02:00:09.469Z","response_time":99,"last_error":null,"robots_txt_status":null,"robots_txt_updated_at":null,"robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-07-24T04:34:16.856Z","updated_at":"2025-07-24T04:34:19.666Z","avatar_url":"https://github.com/jjsch-dev.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ⚙️ PicoSWITool\n\nA firmware tool 🛠️ for testing SWI (Single-Wire Interface) EEPROM emulators, specifically designed for the AT21CS11. This tool runs on Raspberry Pi Pico boards (RP2350 and RP2040) and facilitates sending commands and receiving responses to verify the functionality of an EEPROM emulation.\n\n## 📑 Table of Contents\n\n* [✨ Features](#features)\n* [💾 Hardware Requirements](#hardware-requirements)\n* [💻 Software Requirements](#software-requirements)\n* [🛠️ Installation](#installation)\n    * [Prerequisites](#prerequisites)\n    * [1\\. Fetch the Pico SDK](#1-fetch-the-pico-sdk)\n    * [2\\. Set the `PICO_SDK_PATH` Environment Variable](#2-set-the-pico_sdk_path-environment-variable)\n    * [3\\. Clone \u0026 Build the PicoSWITool Project](#3-clone--build-the-picoswitool-project)\n    * [4\\. Flashing the UF2 File to Your Raspberry Pi Pico](#4-flashing-the-uf2-file-to-your-raspberry-pi-pico)\n* [💡 Usage](#usage)\n    * [JSON Command Format](#json-command-format)\n    * [Command Details](#command-details)\n* [💡 Examples of Use](#examples-of-use)\n* [⚙️ Implementation Details](#implementation-details)\n* [⏱️ Timing](#timing)\n* [📜 License](#license)\n* [🤝 Contributing](#contributing)\n* [✍️ Author](#author)\n\n\u003ca name=\"features\"\u003e\u003c/a\u003e\n## ✨ Features\n\n* Sends commands to an SWI EEPROM emulator.\n* Receives and parses responses.\n* Supports various AT21CS11 commands (discovery, read/write, etc.).\n* Utilizes the RP2350's dual-core architecture for efficient timing and USB communication.\n* Communicates via USB serial using JSON commands.\n* Provides feedback via JSON responses.\n* Provides a command-line interface via USB serial to interact with the EEPROM.\n\n---\n\n\u003ca name=\"hardware-requirements\"\u003e\u003c/a\u003e\n## 💾 Hardware Requirements\n\n* Raspberry Pi Pico 2 (RP2350) or Raspberry Pi Pico (RP2040)\n\n\u003cimg src=\"images/pico2_over_emulator.png\" alt=\"Pico 2 RP2350\"\u003e\n\n* Device with an AT21CS11 SWI EEPROM interface or an [emulator](https://github.com/jjsch-dev/at21cs11-eeprom-emulator/) of it.\n\n---\n\n\u003ca name=\"software-requirements\"\u003e\u003c/a\u003e\n## 💻 Software Requirements\n\n* Raspberry Pi Pico [SDK](https://github.com/raspberrypi/pico-sdk)\n* ARM GCC compiler [Toolchain](https://developer.arm.com/Tools%20and%20Software/GNU%20Toolchain)\n\n\u003ca name=\"installation\"\u003e\u003c/a\u003e\n## 🛠️ Installation\n\nThis guide outlines the steps to set up the development environment and build the PicoSWITool project on Ubuntu 24.04.\n\n### Prerequisites\n\nOn Ubuntu 24.04, install the required packages:\n\n```bash\nsudo apt update\nsudo apt install -y \\\n    git cmake build-essential libstdc++-arm-none-eabi-newlib \\\n    gcc-arm-none-eabi python3-pip python3-venv\n```\n* `git`, `cmake`, `build-essential`: For cloning the repository and building the CMake project.\n\n* `gcc-arm-none-eabi` \u0026 `libstdc++-arm-none-eabi-newlib`: The ARM GCC compiler and C library necessary for building firmware for the Raspberry Pi Pico.\n\n* `python3-pip` \u0026 `python3-venv`: Required by the Pico SDK's build system.\n\n### 1\\. Fetch the Pico SDK\n\nThe Raspberry Pi Pico SDK provides the necessary libraries and build tools.\n\n```bash\n# Choose your workspace directory (you can adjust this path)\ncd ~/development\n```\n\n```bash\n# Clone the Pico SDK repository from GitHub\ngit clone [https://github.com/raspberrypi/pico-sdk.git](https://github.com/raspberrypi/pico-sdk.git)\ncd pico-sdk\n```\n\n```bash\n# Initialize and update the submodules within the Pico SDK\ngit submodule update --init\n```\n\n### 2\\. Set the `PICO_SDK_PATH` Environment Variable\n\nCMake needs to know the location of the Pico SDK. You need to set the `PICO_SDK_PATH` environment variable. It's recommended to add this to your shell startup file (e.g., `~/.bashrc` for Bash) so it's set automatically in new terminal sessions.\n\nTo add the `PICO_SDK_PATH`, you can use the `echo` command:\n\n```bash\necho \"export PICO_SDK_PATH=~/development/pico-sdk\" \u003e\u003e ~/.bashrc\n```\n\nAfter adding this line, you need to reload your shell configuration or apply the change to your current session by sourcing the `~/.bashrc` file:\n\n```bash\nsource ~/.bashrc\n```\n\nTo verify that the variable is set correctly, run:\n\n```bash\necho $PICO_SDK_PATH\n```\n\nIt should output the path to your Pico SDK directory (`~/development/pico-sdk`).\n\n### 3\\. Clone \u0026 Build the PicoSWITool Project\n\nNow, you can clone and build the PicoSWITool project.\n\n```bash\n# Go back to your workspace\ncd ~/development\n```\n\n```bash\n# Clone the PicoSWITool repository from GitHub\ngit clone https://github.com/jjsch-dev/PicoSWITool.git\n```\n\n```bash\n# Navigate into the project directory\ncd PicoSWITool\n```\n\n```bash\n# Create a build directory and enter it\nmkdir build \u0026\u0026 cd build\n```\n\n```bash\n# Configure the build for your Raspberry Pi Pico board:\n# For the original Pico 2 (RP2350, 150 MHz Cortex-M33 - Note: Check your specific board)\ncmake -DPICO_BOARD=pico2 ..\n```\n```bash\n# Or for the Raspberry Pi Pico 2 (RP2040, 125 MHz Cortex-M0+)\n# cmake -DPICO_BOARD=pico ..\n```\n\n```bash\n# Or for the Raspberry Pi Pico W / Pico H (RP2040 with wireless)\n# cmake -DPICO_BOARD=pico_w ..\n```\n\n```bash\n# Build the project using multiple parallel jobs for faster compilation.\n# '$(nproc)' will automatically be replaced by the number of CPU cores\\.\nmake -j$(nproc)\n```\n\nIf the build is successful, you should see output similar to:\n\n```bash\n[100%] Built target pico_swi_tool\n```\n\nThe firmware file (`pico_swi_tool.uf2`) will be located in the `build` directory.\n\n### 4\\. Flashing the UF2 File to Your Raspberry Pi Pico\n\nTo run the firmware on your Pico:\n\n1.  Connect your Raspberry Pi Pico to your computer via USB while holding down the **BOOTSEL** button on the Pico board.\n2.  The Pico will enumerate as a USB mass storage device (usually named `RPI-RP2`).\n3.  **Choose the appropriate UF2 file for your Pico board and copy it to the `RPI-RP2` drive:**\n    * **Raspberry Pi Pico (RP2040):** You can download the pre-built UF2 file [here](bin/pico1_swi_tool.uf2). Copy `pico1_swi_tool.uf2` to the `RPI-RP2` drive.\n    * **Raspberry Pi Pico 2 (RP2350):** You can download the pre-built UF2 file [here](bin/pico2_swi_tool.uf2). Copy `pico2_swi_tool.uf2` to the `RPI-RP2` drive.\n    *(Note: If you built the project yourself, the UF2 file will also be available in the `build/` directory as `pico_swi_tool.uf2`.)*\n4.  Once the copy is complete, the board will automatically reboot and start running your firmware.\n\n### Troubleshooting\n\n* **`PICO_SDK_PATH` not set:** Double-check that the `export PICO_SDK_PATH=...` line in your shell startup file correctly points to the location where you cloned the Pico SDK. Ensure you have sourced the file or restarted your terminal.\n* **Compiler errors about missing headers:** Verify the output of the `cmake` command. It should indicate the board configuration being used (e.g., \"Using board configuration from .../boards/pico.h\" or \"boards/pico2.h\"). If it's not finding the board configuration, there might be an issue with the `PICO_SDK_PATH` or the `cmake` command itself.\n* **Performance/timing off (for Pico 2):** If you are using a Raspberry Pi Pico 2 (RP2350 with Cortex-M33), ensure you configured the build with the appropriate `-DPICO_BOARD` flag (e.g., `-DPICO_BOARD=pico2`). Also, be aware that timing-sensitive code might need adjustments for the different core speed.\n\nWith these steps, you should have a fully set up development environment and be able to build and flash the PicoSWITool firmware to your Raspberry Pi Pico.\n\n---\n\n\u003ca name=\"usage\"\u003e\u003c/a\u003e\n## 💡 Usage\n\nThe tool communicates via USB serial. Send JSON-formatted commands to the Pico, and it will respond with JSON-formatted responses.\n\n### JSON Command Format\n\nCommands are sent as JSON objects with a `\"command\"` field and any necessary data fields.\n\n### Command Details\n\nHere's a breakdown of the supported commands:\n\n#### 🔍 `discoveryResponse`\nPerforms the SWI EEPROM discovery response sequence. This command triggers a series of pin toggles on the Pico to simulate the EEPROM's response to a discovery request. The master device (your testing setup) typically sends a general bus call after a reset to identify any connected devices on the SWI bus. If a device is present, it should send the ACK sequence.\n\n* Command:\n```json\n{\"command\": \"discoveryResponse\"}\n```\n* Response: \n```json\n{\"status\": \"success\", \"command\": \"discoveryResponse\", \"response\": \"ACK\"} or \n{\"status\": \"success\", \"command\": \"discoveryResponse\", \"response\": \"NACK\"}\n```\n### ➡️ `txByte`\nTransmits a single byte to the SWI EEPROM emulator. This command sends the provided byte bit-by-bit, utilizing specific functions (`tx_one()` or `tx_zero()`) to represent each bit's value on the SWI bus. After the byte transmission is complete, the tool reads the response from the emulator, which should be an ACK (acknowledgement) indicating successful reception or a NACK (not acknowledgement) indicating an error.\n\n* Command:\n```json \n{\"command\": \"txByte\", \"data\": \"0x55\"}\n(Replace \"0x55\" with the byte value to transmit in hexadecimal format.)\n```\n* Response: \n```json\n{\"status\": \"success\", \"command\": \"txByte\", \"response\": \"ACK\"} or \n{\"status\": \"success\", \"command\": \"txByte\", \"response\": \"NACK\"}\n```\n\n### ⬅️ `rxByte`\nReceives a single byte from the SWI EEPROM emulator. This command reads 8 consecutive bits from the SWI bus, utilizing a bit reading function (`read_bit()`). The function handles the necessary pin toggling and precise timing required by the SWI protocol to correctly sample each bit from the EEPROM interface. These 8 bits are then combined to form the received byte, which is included in the response.\n\n* Command: \n```json\n{\"command\": \"rxByte\"}\n```\n* Response: \n```json\n{\"status\": \"success\", \"command\": \"rxByte\", \"response\": \"0xYY\"} \n(where 0xYY is the received byte)\n```\n\n###  🆔 `manufacturerId`\nRetrieves the manufacturer and device identification code from the SWI EEPROM emulator. The response provides a unique code, such as `0x00D200` for the AT21CS01 or `0x00D380` for the AT21CS11. This command internally uses a sequence of lower-level SWI operations, including discovery, byte transmission (`txByte`), and byte reception (`rxByte`), to construct the necessary communication to obtain this ID. A response of zero typically indicates an error or that no device responded.\n\n* Command: \n```json\n{\"command\": \"manufacturerId\", \"dev_addr\": \"0x00\"}\n```\n* Response: \n```json\n{\"status\": \"success\", \"command\": \"manufacturerId\", \"response\": \"0x00XXXX\"} \n(e.g., 0x00D200 for AT21CS01, 0x00D380 for AT21CS11) or \n{\"status\":\"error\",\"command\":\"manufacturerId\",\"response\":\"Error: Manufacturer ID is zero\"}\n```\n\n###  📚 `readBlock`\nReads a block of data from the SWI EEPROM emulator. This command retrieves a specified number of bytes from the EEPROM, starting at a given address. It performs several checks and operations to ensure reliable data retrieval:\n\n* **Address Validation:** It verifies that the requested memory block (defined by the starting address and length) does not exceed the valid memory range of the EEPROM (0-127 in this example).\n* **Presence Check:** It initiates an EEPROM discovery sequence to confirm that the EEPROM emulator is present and responding on the SWI bus.\n* **Verified Reading:** It employs a verified read procedure, where each byte is read from the EEPROM multiple times to ensure data integrity.\n\n* `dev_addr`: The device address for EEPROM access.\n* `start_addr`: The starting address in the EEPROM (0-127).\n* `len`: The number of bytes to read.\n\nThe command returns the requested block of data.\n\n* Command: \n```json\n{\"command\": \"readBlock\", \"dev_addr\": \"0x00\", \"start_addr\": \"0x00\", \"len\": \"0x10\"}\n```\n* Response: \n```json\n{\"status\":\"success\",\"command\":\"readBlock\",\"response\":[\"0xXX\", \"0xXX\", ...]}\n```\n---\n\n\u003ca name=\"examples-of-use\"\u003e\u003c/a\u003e\n## 💡 Examples of Use\n\nThis section demonstrates how to interact with the PicoSWITool using JSON commands via the USB serial interface.\n\n### Discovery Response Example\n\nThe `discoveryResponse` command tests the EEPROM emulator's response to a discovery sequence.\n\n**Scenario:** Sending a discovery command to the PicoSWITool.\n\n**Command Sent (via USB Serial):**\n\n```json\n{\"command\": \"discoveryResponse\"}\n```\n\n**Observed Responses (in Arduino IDE 2.0 Serial Monitor):**\n\n![discoveryCmd](images/tty_discovery_cmd.png)\n\nThe PicoSWITool sends a reset pulse (approx. 150µs). The emulator's reply might be:\n\n**Negative Acknowledge (NACK):**\n\nThe oscilloscope capture below shows the reset pulse generated by the Pico and the NACK:\n\n![rigolNack](images/Rigol_discovery_nack.png)\n\n```json\n{\"status\": \"success\", \"command\": \"discoveryResponse\", \"response\": \"NACK\"}\n```\n\nThis indicates the emulator did not acknowledge the discovery request.\n\n**Acknowledge (ACK):**\n\nThe oscilloscope capture below shows the reset pulse generated by the Pico and the ACK:\n![rigolAck](images/Rigol_discovery_ack.png)\n\n```json\n{\"status\": \"success\", \"command\": \"discoveryResponse\", \"response\": \"ACK\"}\n```\n\nSending `{\"command\": \"discoveryResponse\"}` repeatedly helps test the emulator's reliability.\n\n---\n\n### Manufacturer ID Example\n\nThe `manufacturerId` command retrieves the unique identification code of the connected EEPROM emulator. This example demonstrates sending the command and interpreting a typical response.\n\n**Scenario:** Requesting the manufacturer and device ID of the EEPROM emulator.\n\n**Command Sent (via USB Serial):**\n\n```json\n{\"command\": \"manufacturerId\", \"dev_addr\": \"0x00\"}\n```\n\n**Observed Response (in Arduino IDE 2.0 Serial Monitor - as seen in image):**\n\n\u003cimg src=\"images/tyy_mnuf_id.png\" alt=\"manufId\"\u003e\n\nThe PicoSWITool will send a sequence of SWI commands to the EEPROM emulator to retrieve its ID. A successful response will look similar to this:\n\n```json\n{\"status\": \"success\", \"command\": \"manufacturerId\", \"response\": \"0x00D380\"}\n```\n\nIn this example, the response `0x00D380` indicates an AT21CS11 EEPROM device. The oscilloscope capture in Image likely shows the low-level SWI communication occurring during this command execution.\n\n![rigolManufId](images/Rigol_manuf_id.png)\n\n**Interpreting the Response:**\n\n* The `response` field contains the manufacturer and device ID.\n* `0x00D200` typically identifies an AT21CS01 EEPROM.\n* `0x00D380` typically identifies an AT21CS11 EEPROM.\n* A response of `{\"status\":\"error\",\"command\":\"manufacturerId\",\"response\":\"Error: Manufacturer ID is zero\"}` or a similar error message indicates that the command failed or the device did not respond correctly.\n\nThis example illustrates how to use the `manufacturerId` command and interpret the returned identification code.\n\n---\n\n### Read Block Example\n\nThe `readBlock` command allows you to read a sequence of bytes from a specified memory address in the EEPROM emulator. This example demonstrates how to request a block of data and interpret the response.\n\n**Scenario:** Reading 16 bytes (0x10) starting from address 0x00 of the EEPROM emulator on device address 0x00.\n\n**Command Sent (via USB Serial):**\n\n```json\n{\"command\": \"readBlock\", \"dev_addr\": \"0x00\", \"start_addr\": \"0x00\", \"len\": \"0x10\"}\n```\n\n**Observed Response (in Arduino IDE 2.0 Serial Monitor - as seen in Image):**\n\n![readBlock](images/tty_read_block.png)\n\nThe PicoSWITool will send a sequence of SWI commands to the EEPROM emulator to read the requested block of data. A successful response will contain an array of hexadecimal byte values:\n\n```json\n{\"status\":\"success\",\"command\":\"readBlock\",\"response\":[\"0x02\", \"0x20\", \"0x00\", \"0x1D\", \"0xCE\", \"0xCF\", \"0x03\", \"0x66\", \"0x30\", \"0x30\", \"0x31\", \"0x30\", \"0x39\", \"0x34\", \"0x32\", \"0x2D\"]}\n```\n\nThe `response` field is an array where each element represents a byte read from the EEPROM, in the order of the requested addresses. The oscilloscope capture in Image likely shows the low-level SWI communication occurring during the execution of this command, including address transmission and data reception.\n\n\u003cimg src=\"images/RigolReadBlock.png\" alt=\"RigolReadBlock\"\u003e\n\n**Interpreting the Response:**\n\nIn this example, the PicoSWITool successfully read 16 bytes starting from address `0x00`. The returned array contains these 16 bytes in hexadecimal format. You can compare these values to the expected data in your EEPROM emulator.\n\nThis example illustrates how to use the `readBlock` command to retrieve a contiguous block of data for verification.\n\n---\n\n\u003ca name=\"implementation-details\"\u003e\u003c/a\u003e\n## ⚙️ Implementation Details\n\n* The project is built using the Raspberry Pi Pico 2 SDK and targets the RP2350 microcontroller.\n* **⏱️ Timing Considerations:**\n    * While the Raspberry Pi Pico's PIO (Programmable Input/Output) units 🕹️ offer the capability to generate precise bit-bang timing, this project utilizes software-based delays ⏳ for greater flexibility during testing. This allows for easier adjustment of timing parameters to accommodate different EEPROM devices or emulation scenarios.\n    * Precise timing is achieved on Core 1 using the `soft_delay_us()` function ⚙️. This function employs cycle counting to introduce delays in microseconds, taking into account the Pico's clock speed.\n    * The delay is calculated based on the following:\n        * For the Pico 2 (150 MHz), each CPU cycle is approximately 6.67 ns.\n        * For the Pico 1 (125 MHz), each CPU cycle is approximately 8 ns.\n    * The `soft_delay_us()` function includes a calibration constant (currently -7) that may need to be fine-tuned 🛠️ for specific hardware setups to achieve the most accurate timing.\n* **Dual-Core Operation:**\n    * Core 0 handles the USB communication ↔️ and parsing of JSON commands.\n    * Core 1 is dedicated to the precise timing required for the SWI communication, using the `multicore_fifo_push_blocking()` and `multicore_fifo_pop_blocking()` functions for inter-core communication.\n    * The decision to offload low-level SWI tasks to Core 1 was made to **minimize the risk of IRQ interruptions** that could disrupt critical timing. For example, during command execution:\n      ```c\n      uint32_t irq_status = save_and_disable_interrupts();\n      switch (cmd) {\n          case TX_BYTE:\n              ack = tx_byte(data);\n              break;\n          case DISCOVERY:\n              ack = discovery_response();\n              break;\n          case RX_BYTE:\n              ack = rx_byte(data);\n              break;\n          default:\n              ack = 0xFF;  // Unknown command error.\n              break;\n      }\n      restore_interrupts(irq_status);\n      ```\n      *Disabling interrupts during these sections ensures accurate signal timing for reliable SWI emulation.*\n* **SWI Emulation:** The SWI communication is implemented using open-drain GPIO control 🔌. The `sio_set_high()` function sets the GPIO pin to input mode (high), and `sio_set_low()` sets it to output mode (low).\n* **JSON Parsing:** The [jsmn](https://github.com/zserge/jsmn) library — a lightweight, minimalistic JSON parser in C — is used to parse incoming JSON commands 🧾. The `jsoneq()` function is used to compare JSON tokens.\n* **Building:** The `CMakeLists.txt` file 🧱 defines the build process, including setting compiler flags and linking libraries.\n\n---\n\n\u003ca name=\"timing\"\u003e\u003c/a\u003e\n## ⏱️ Timing\n\nThe code includes timing constants optimized for SWI communication. These constants may need to be adjusted based on the specific EEPROM device or emulator being used. The code defines different timing presets (Prusa, Atmel Standard, Atmel High Speed).\n```c\n#define T_PRUSA_LOW1_US   2\n#define T_PRUSA_LOW0_US   10\n#define T_PRUSA_RD_US     1\n// ...\n```\n\n---\n\n\u003ca name=\"license\"\u003e\u003c/a\u003e\n## 📜 License\n\n[MIT License](LICENSE) – © jjsch-dev (2025)\n\nYou can freely use and modify this code as long as you include the original license.\n\n\u003ca name=\"contributing\"\u003e\u003c/a\u003e\n## 🧑‍💻 Contributing\n\nFor contributions or improvements:\n- Fork the project\n- Create a new branch\n- Submit a pull request\n\nOr open issues or feature requests directly on the repository.\n\n---\n\n\u003ca name=\"author\"\u003e\u003c/a\u003e\n## 📬 Contact \u0026 Credits\n\n- **Author**: jjsch-dev  \n- **Repository**: [GitHub Link](https://github.com/jjsch-dev/PicoSWITool)\n\n---\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjjsch-dev%2Fpicoswitool","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjjsch-dev%2Fpicoswitool","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjjsch-dev%2Fpicoswitool/lists"}