Go-cyacd v1.0.0 - Library for programming Cypress/Infineon PSoC microcontrollers

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.ReadWriter for 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!