Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions .github/workflows/avr32-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: AVR32 firmware build

on:
push:
pull_request:
workflow_dispatch:

permissions:
contents: read

env:
TOOLCHAIN_REPO: cozycactus/avr32-toolchain-macos-arm64
TOOLCHAIN_TAG: v2026.06.03
TOOLCHAIN_ARCHIVE: avr32-tools-src-macos-arm64-20260603.tar.gz
ATMEL_HEADERS_VERSION: 6.1.3.1475

jobs:
avr32:
name: Build SDR Widget with avr32-gcc
runs-on: macos-26

steps:
- name: Check out repository
uses: actions/checkout@v4

- name: Install host dependencies
run: brew install libusb

- name: Download AVR32 toolchain
env:
GH_TOKEN: ${{ github.token }}
run: |
gh release download "$TOOLCHAIN_TAG" \
--repo "$TOOLCHAIN_REPO" \
--pattern "$TOOLCHAIN_ARCHIVE" \
--pattern "$TOOLCHAIN_ARCHIVE.sha256"
expected="$(awk '{print $1}' "$TOOLCHAIN_ARCHIVE.sha256")"
actual="$(shasum -a 256 "$TOOLCHAIN_ARCHIVE" | awk '{print $1}')"
test "$actual" = "$expected"
mkdir -p toolchain
tar -xzf "$TOOLCHAIN_ARCHIVE" -C toolchain

- name: Download Atmel headers
run: |
toolchain_root="$PWD/toolchain/avr32-tools-src"
headers_zip="atmel-headers-${ATMEL_HEADERS_VERSION}.zip"
mkdir -p "$toolchain_root/downloads" "$toolchain_root/atmel-headers"
curl -L \
"https://ww1.microchip.com/downloads/archive/${headers_zip}" \
-o "$toolchain_root/downloads/${headers_zip}"
unzip -q -o "$toolchain_root/downloads/${headers_zip}" \
-d "$toolchain_root/atmel-headers"

- name: Build firmware and host control tool
run: |
toolchain_root="$PWD/toolchain/avr32-tools-src"
export PATH="$toolchain_root/bin:$PATH"
avr32-gcc --version
make clean
make all AVR32_TOOLCHAIN="$toolchain_root"
9 changes: 8 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@
##
## assumes that you've set the AVR32BIN environment
## to point to the directory containing avr32-gcc
HOST_CC ?= gcc
PKG_CONFIG ?= pkg-config
LIBUSB_CFLAGS ?= $(shell $(PKG_CONFIG) --variable=includedir libusb-1.0 2>/dev/null | sed 's|^|-I|')
LIBUSB_LIBS ?= $(shell $(PKG_CONFIG) --libs libusb-1.0 2>/dev/null || echo -lusb-1.0)
HOST_CFLAGS ?=
HOST_LDFLAGS ?=

all:: Release/widget.elf widget-control

Release/widget.elf::
Expand All @@ -19,7 +26,7 @@ sdr-widget::
CFLAGS=-DFEATURE_DEFAULT_BOARD=feature_board_widget ./make-widget

widget-control: widget-control.c src/features.h
gcc -o widget-control widget-control.c -lusb-1.0
$(HOST_CC) $(HOST_CFLAGS) $(LIBUSB_CFLAGS) -o widget-control widget-control.c $(HOST_LDFLAGS) $(LIBUSB_LIBS)

clean::
cd Release && make clean
Expand Down
20 changes: 20 additions & 0 deletions makefile.defs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Local build settings. This file is included by Release/makefile.
AVR32_TOOLCHAIN ?=

ifeq ($(strip $(ATMEL_HEADERS)),)
ifneq ($(strip $(AVR32_TOOLCHAIN)),)
ATMEL_HEADERS := $(firstword $(wildcard $(AVR32_TOOLCHAIN)/atmel-headers/atmel-headers-*))
endif
endif

ifneq ($(strip $(ATMEL_HEADERS)),)
CFLAGS += -I$(ATMEL_HEADERS)
ASFLAGS += -I$(ATMEL_HEADERS)
export CPATH := $(ATMEL_HEADERS):$(CPATH)
endif

OBJS += ./src/newlib_compat.o

src/newlib_compat.o: ../src/newlib_compat.c
@echo Compile $(CFLAGS) $<
@avr32-gcc $(CFLAGS) -O2 -fdata-sections -Wall -c -fmessage-length=0 -ffunction-sections -o"$@" "$<"
5 changes: 5 additions & 0 deletions src/newlib_compat.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
int _isatty(int file)
{
(void)file;
return 0;
}
22 changes: 15 additions & 7 deletions widget-control.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ const char usage[] = {

int verbose = 0;

int finish(int return_value);

/*
** features
*/
Expand Down Expand Up @@ -123,7 +125,7 @@ int find_feature_value(int index, char *value) {
char *usb_serial_id = NULL;
libusb_device_handle *usb_handle;
char *usb_device = "none";
char usb_data[1024];
unsigned char usb_data[1024];
unsigned int usb_timeout = 2000;


Expand Down Expand Up @@ -188,13 +190,15 @@ libusb_device_handle *find_device(int list_all) {
libusb_close(h);
continue;
}
unsigned char serialId[1024];
if ((status = libusb_get_string_descriptor_ascii(h, desc.iSerialNumber, serialId, sizeof(serialId))) <= 0) {
if (verbose)
if (status == 0)
char serialId[1024];
if ((status = libusb_get_string_descriptor_ascii(h, desc.iSerialNumber, (unsigned char *)serialId, sizeof(serialId))) <= 0) {
if (verbose) {
if (status == 0) {
fprintf(stderr, "find_device: libusb_get_string_descriptor_ascii(%04x:%04x, ...) returned 0 bytes", desc.idVendor, desc.idProduct);
else
} else {
fprintf(stderr, "find_device: libusb_get_string_descriptor_ascii(%04x:%04x, ...) failed: %s", desc.idVendor, desc.idProduct, error_string(status));
}
}
libusb_release_interface(h, 0);
libusb_close(h);
continue;
Expand Down Expand Up @@ -430,7 +434,11 @@ int set_nvram(int argc, char *argv[]) {
fprintf(stderr, "widget-control: wrong number (%d) of features specified, should be %d features to set\n", argc, true_feature_end_index);
exit(1);
}
features = (uint8_t *)calloc(true_feature_major_index, sizeof(uint8_t));
features = (uint8_t *)calloc(true_feature_end_index, sizeof(uint8_t));
if (features == NULL) {
fprintf(stderr, "widget-control: unable to allocate feature values\n");
exit(finish(1));
}
for (i = true_feature_minor_index+1; i < true_feature_end_index; i += 1) {
j = find_feature_value(i, argv[i]);
if (j >= first_value(i) && j <= last_value(i)) {
Expand Down