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!

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.