Hi everyone,
I’m pleased to announce the v1.0.0 release of go-cyacd, a pure Go library for programming Cypress/Infineon PSoC microcontrollers via their bootloader
protocol.
Background
PSoC (Programmable System-on-Chip) devices from Cypress/Infineon are widely used in industrial automation, IoT, and embedded systems. These devices
support firmware updates through a bootloader protocol, but existing tools are primarily C-based and tightly coupled to specific hardware
implementations.
I needed a solution that could:
- Work with any communication channel (USB HID, UART, SPI, network, etc.)
- Integrate cleanly into Go applications
- Be testable without physical hardware
- Follow Go idioms and best practices
Design
The library follows a clean separation of concerns:
Protocol Layer (protocol package)
- Command frame builders
- Response parsers
- Checksum calculations
- Conforms to Infineon AN60317 v1.30 specification
Parser Layer (cyacd package)
- Parses .cyacd firmware files
- Supports both standard and hybrid (Intel HEX prefix) formats
- Validates file structure and checksums
Programming Layer (bootloader package)
- High-level programmer API
- Takes any
io.ReadWriterfor hardware abstraction - Progress callbacks, context support, configurable options
- Structured error types for better error handling
Example Usage
package main
import (
"context"
"fmt"
"time"
"github.com/moffa90/go-cyacd/bootloader"
"github.com/moffa90/go-cyacd/cyacd"
)
func main() {
// Hardware abstraction - you provide any io.ReadWriter
device := openDevice() // Your implementation
// Parse firmware file
fw, err := cyacd.Parse("firmware.cyacd")
if err != nil {
panic(err)
}
// Configure programmer with options
prog := bootloader.New(device,
bootloader.WithTimeout(30*time.Second),
bootloader.WithProgressCallback(func(p bootloader.Progress) {
fmt.Printf("Progress: %.1f%% [%s]\n",
p.Percentage, p.Phase)
}),
)
// Program with context support
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
defer cancel()
if err := prog.Program(ctx, fw, bootloaderKey); err != nil {
panic(err)
}
fmt.Println("Programming complete!")
}
Key Features
- Zero dependencies - Only Go standard library
- Hardware independent - io.ReadWriter interface for any transport
- Context support - Proper cancellation and timeout handling
- Progress tracking - Real-time callbacks during programming operations
- Mock device - Test without hardware (see examples)
- Comprehensive error handling - Structured error types with context
- Full protocol support - All 11 bootloader commands implemented
Technical Decisions
Some design choices I’d like to highlight:
Hardware abstraction via io.ReadWriter
This allows the library to work with any transport without platform-specific code. Users implement Read/Write for their hardware, and the library
handles the protocol.
Functional options pattern
Configuration uses functional options (WithTimeout, WithRetries, etc.) for clean, extensible API without breaking changes.
Progress as a value type
Progress callbacks receive a Progress struct (not pointer) with all state, making it safe for concurrent use.
Resources
The repository includes comprehensive documentation, 4 working examples (including a mock device), and detailed protocol documentation.
Installation
go get github.com/moffa90/go-cyacd@v1.0.0
Feedback Welcome
I’d appreciate feedback on:
- API design and ergonomics
- Documentation clarity
- Use cases I might have missed
- Testing approaches (I’m using table-driven tests extensively)
Also happy to discuss protocol implementation details or design decisions.
Thanks for reading!