diff --git a/.gitignore b/.gitignore index 0157077..2c4bf08 100644 --- a/.gitignore +++ b/.gitignore @@ -256,3 +256,4 @@ cython_debug/ # PyPI configuration file .pypirc +pyupdi-env/ \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..a45ecdc --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,37 @@ +cmake_minimum_required(VERSION 3.13) + +# Project +project(lezyne-rear-light-firmware C) + +# MCU and clock +set(MCU attiny202) +set(F_CPU 5000000UL) # 5 MHz + +# Toolchain executables +set(CMAKE_SYSTEM_NAME Generic) +set(CMAKE_C_COMPILER avr-gcc) +set(OBJCOPY avr-objcopy) + +# Compiler flags +set(CMAKE_C_FLAGS "-mmcu=${MCU} -DF_CPU=${F_CPU} -Os -Wall") + +# Sources +add_executable(main.elf main.c) + +# HEX file +add_custom_command( + OUTPUT main.hex + COMMAND ${OBJCOPY} -O ihex -R .eeprom main.elf main.hex + DEPENDS main.elf +) + +# BIN file +add_custom_command( + OUTPUT main.bin + COMMAND ${OBJCOPY} -O binary -R .eeprom main.elf main.bin + DEPENDS main.elf +) + +# Targets +add_custom_target(hex ALL DEPENDS main.hex) +add_custom_target(bin ALL DEPENDS main.bin) diff --git a/README.md b/README.md index 747ff62..ece524c 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,86 @@ # lezyne-rear-light-firmware -Open firmware for Lezyne bike rear lights based on ATTINY202 \ No newline at end of file +Open firmware for Lezyne bike rear lights based on ATTINY202 + +This repository contains a minimal firmware as a **C project** for the ATtiny202 microcontroller using **GCC**, **CMake**, and **VS Code**. It also includes instructions for programming the chip using an **FT232 USB-UART adapter** via the UPDI interface with `pymcuprog`. + +--- + +## Table of Contents + +- [Dependencies](#dependencies) +- [Setup Build Environment](#setup-build-environment) +- [Building the Project](#building-the-project) +- [Flashing the Firmware](#flashing-the-firmware) +- [Reading Flash Content](#reading-flash-content) +- [Hardware Setup](#hardware-setup) +- [License](#license) + +--- + +## Dependencies + +Ensure the following tools are installed on your system: + +- **GCC AVR toolchain** (supports ATtiny 0/1-series) + ```bash + sudo zypper install avr-gcc avr-libc + ``` +- **CMake** + ```bash + sudo zypper install cmake + ``` +- **Python 3, pip and venv** + ```bash + sudo zypper install python3 python3-pip python3-venv + ``` +- **VS Code** (optional but recommended) +- **CMake Tools extension** for VS Code + +## Setup Build Environment +1. Clone the repository: + ```bash + git clone https://git.mosad.xyz/localhorst/lezyne-rear-light-firmware + cd lezyne-rear-light-firmware + ``` +2. Configure the CMake project: + - Open the folder in VS Code. + - Select the AVR-GCC kit in the bottom blue bar. + - Run CMake: Configure (from command palette) if it doesn't auto-run. + +## Building the Project +1. Press F7 or Ctrl+Shift+B to build. +2. Output files are generated in the 'build/' folder: +- main.elf → ELF executable +- main.hex → HEX file (flashable) +- main.bin → BIN file + +## Flashing the Firmware +Hardware: FT232 USB-UART adapter connected to UPDI with a 4.7 kΩ resistor. +1. Create and activate a Python virtual environment: + ```bash + python3 -m venv pyupdi-env + source pyupdi-env/bin/activate + ``` +2. Install pymcuprog inside the environment: + ```bash + pip install pymcuprog + ``` +3. Verify installation: + ```bash + pymcuprog --version + ``` +4. Flash using pymcuprog: + ```bash + pymcuprog -t uart -u /dev/ttyUSB0 -d attiny202 write -f build/main.hex + ``` +## Hardware Setup (FT232 → ATtiny202 UPDI) + ```bash + FT232 TX ----[4.7kΩ]---- UPDI (pin 6) + FT232 GND --------------- GND + VCC -------------------- VCC (3.3V or 5V, must match FT232 logic) + ``` + +## License + +This project is licensed under the MIT License. See [LICENSE](./LICENSE) for details. \ No newline at end of file diff --git a/main.c b/main.c new file mode 100644 index 0000000..2fc3bc1 --- /dev/null +++ b/main.c @@ -0,0 +1,14 @@ +#define F_CPU 5000000UL // 5 MHz +#include +#include + +int main(void) { + // Configure PA3 as output (Pin 7 on ATTINY202-SSN) + VPORTA.DIR |= (1 << 3); + + + while (1) { + VPORTA.OUT ^= (1 << 3); // toggle PA3 + _delay_ms(500); + } +}