From fd74076bb869b33dd3a5494ca905bba7fb555b79 Mon Sep 17 00:00:00 2001 From: Reinout Meliesie Date: Mon, 25 Aug 2025 20:12:34 +0200 Subject: [PATCH] Switch project to GNU Make + VS Code --- .gitignore | 3 + kulifuli-arduino.code-workspace | 10 +++ kulifuli-arduino.ino | 95 ------------------------ makefile | 126 ++++++++++++++++++++++++++++++++ src/main.cpp | 103 ++++++++++++++++++++++++++ 5 files changed, 242 insertions(+), 95 deletions(-) create mode 100644 .gitignore create mode 100644 kulifuli-arduino.code-workspace delete mode 100644 kulifuli-arduino.ino create mode 100644 makefile create mode 100644 src/main.cpp diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8f11f84 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/build +/lib +/local.make diff --git a/kulifuli-arduino.code-workspace b/kulifuli-arduino.code-workspace new file mode 100644 index 0000000..41025d4 --- /dev/null +++ b/kulifuli-arduino.code-workspace @@ -0,0 +1,10 @@ +{ + "folders": [ + { + "path": "." + } + ], + "settings": { + "makefile.configureOnOpen": true + } +} \ No newline at end of file diff --git a/kulifuli-arduino.ino b/kulifuli-arduino.ino deleted file mode 100644 index 7c86fa1..0000000 --- a/kulifuli-arduino.ino +++ /dev/null @@ -1,95 +0,0 @@ -#include "Arduino.h" - - -void setup () { - Serial . begin (9600) ; - - - // 122Hz @ 50% on pin 3 using T/C0 - - pinMode ( 3 , OUTPUT ) ; // 0C0B is connected to pin 3 - - TCCR0A = - 0 << COM0A1 | - 0 << COM0A0 | - 1 << COM0B1 | - 0 << COM0B0 | - 1 << WGM01 | - 1 << WGM00 ; - - TCCR0B = - 1 << WGM02 | - 1 << CS02 | - 0 << CS01 | - 1 << CS00 ; - - OCR0A = 127 ; - OCR0B = 63 ; - - - // 25kHz @ variable duty cycle on pins 9 and 10 using T/C1 - - pinMode ( 9 , OUTPUT ) ; // 0C1A is connected to pin 9 - pinMode ( 10 , OUTPUT ) ; // 0C1B is connected to pin 10 - - TCCR1A = - 1 << COM1A1 | - 0 << COM1A0 | - 1 << COM1B1 | - 0 << COM1B0 | - 0 << COM1C1 | - 0 << COM1C0 | - 1 << WGM11 | - 0 << WGM10 ; - - TCCR1B = - 1 << WGM13 | - 1 << WGM12 | - 0 << CS12 | - 1 << CS11 | - 0 << CS10 ; - - ICR1H = 0 ; - ICR1L = 79 ; - - OCR1AH = 0 ; - OCR1AL = 39 ; - OCR1BH = 0 ; - OCR1BL = 39 ; -} - - -// Sequence is 188 92 136 14 154 39 154 139 {duty-cycle} - -int seqPos = 0 ; - -void loop () { - if ( Serial . available () ) { - int input = Serial . read () ; - - // In order to avoid serial writes by software other than kulifuli-host messing things up, - // we check for a specific sequence of 8 bytes before the byte that contains the new duty cycle - if ( - seqPos == 0 && input == 188 || - seqPos == 1 && input == 92 || - seqPos == 2 && input == 136 || - seqPos == 3 && input == 14 || - seqPos == 4 && input == 154 || - seqPos == 5 && input == 39 || - seqPos == 6 && input == 154 || - seqPos == 7 && input == 139 - ) { - // Advance in the sequence - seqPos ++ ; - } else if ( seqPos == 8 ) { - // Sequence completed, `input` is the new duty cycle - OCR1AL = input ; - OCR1BL = input ; - Serial . write (input) ; - seqPos = 0 ; - } else { - // Reset sequence progress - seqPos = 0 ; - } - } -} diff --git a/makefile b/makefile new file mode 100644 index 0000000..c176fa2 --- /dev/null +++ b/makefile @@ -0,0 +1,126 @@ +include local.make + + +arduino_packages = ~/.arduino15/packages/arduino +arduino_lib = $(arduino_packages)/hardware/avr/1.8.6 + + +# Flags +debug = -g +lto = -flto +mcu = -mmcu=atmega32u4 +optimization = -O3 +macros = \ + -D F_CPU=16000000L \ + -D ARDUINO=10607 \ + -D ARDUINO_AVR_MICRO \ + -D ARDUINO_ARCH_AVR \ + -D USB_PRODUCT='"Arduino Micro"' \ + -D USB_MANUFACTURER='"Unknown"' \ + -D USB_VID=0x2341 \ + -D USB_PID=0x8037 +header_locations = \ + -I $(arduino_lib)/cores/arduino \ + -I $(arduino_lib)/variants/micro + +# Flag sets +c_flags = $(debug) $(lto) $(mcu) $(optimization) $(macros) $(header_locations) \ + -std=gnu11 \ + -ffunction-sections \ + -fdata-sections \ + -fno-fat-lto-objects +cplusplus_flags = $(debug) $(lto) $(mcu) $(optimization) $(macros) $(header_locations) \ + -std=gnu++11 \ + -ffunction-sections \ + -fdata-sections \ + -fpermissive \ + -fno-exceptions \ + -fno-threadsafe-statics \ + -Wno-error=narrowing +assembly_flags = $(debug) $(lto) $(mcu) $(macros) $(header_locations) +linking_flags = $(debug) $(lto) $(mcu) $(optimization) \ + -fuse-linker-plugin \ + -Wl,--gc-sections \ + -lm + + +build/kulifuli-cpp.o : src/main.cpp + mkdir -p build + avr-g++ -c $(cplusplus_flags) -o $@ $< + +build/arduino-lib/%-cpp.o : $(arduino_lib)/cores/arduino/%.cpp + mkdir -p build/arduino-lib + avr-g++ -c $(cplusplus_flags) -o $@ $< + +build/arduino-lib/%-c.o : $(arduino_lib)/cores/arduino/%.c + mkdir -p build/arduino-lib + avr-gcc -c $(c_flags) -o $@ $< + +build/arduino-lib/%-s.o : $(arduino_lib)/cores/arduino/%.S + mkdir -p build/arduino-lib + avr-gcc -c $(assembly_flags) -x assembler-with-cpp -o $@ $< + +core_objects = $(addprefix build/arduino-lib/, \ + abi-cpp.o \ + CDC-cpp.o \ + HardwareSerial-cpp.o \ + HardwareSerial1-cpp.o \ + new-cpp.o \ + PluggableUSB-cpp.o \ + Print-cpp.o \ + Stream-cpp.o \ + USBCore-cpp.o \ + WMath-cpp.o \ + WString-cpp.o \ + hooks-c.o \ + WInterrupts-c.o \ + wiring_analog-c.o \ + wiring_digital-c.o \ + wiring_pulse-c.o \ + wiring_shift-c.o \ + wiring-c.o \ + wiring_pulse-s.o \ +) + +build/arduino-lib/core.a : $(core_objects) + avr-gcc-ar rcs $@ $^ + +# The order of the prerequisites is significant here for GCC +build/kulifuli.elf : build/kulifuli-cpp.o build/arduino-lib/core.a + avr-gcc $(linking_flags) -o $@ $^ + +build/kulifuli.eep : build/kulifuli.elf + avr-objcopy \ + --output-target=ihex \ + --only-section=.eeprom \ + --set-section-flags=.eeprom=alloc,load \ + --no-change-warnings \ + --change-section-lma .eeprom=0 \ + $< $@ + +build/kulifuli.hex : build/kulifuli.elf + avr-objcopy \ + --output-target=ihex \ + --remove-section=.eeprom \ + $< $@ + + +.PHONY : build +build : build/kulifuli.eep build/kulifuli.hex + +.PHONY : upload +upload : build/kulifuli.hex + stty --file=$(arduino_serial_port) speed 1200 > /dev/null + sleep 1 + avrdude \ + --part atmega32u4 \ + --programmer avr109 \ + --memory flash:w:build/kulifuli.hex:i \ + --noverify-memory \ + --noerase \ + --port $(arduino_serial_port) \ + --baud 57600 + +.PHONY : clean +clean : + rm -rf build/* diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..d9e551f --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,103 @@ +#include "Arduino.h" + + +void set_up_fooler () { + // 122Hz @ 50% on pin 3 using T/C0 + + pinMode ( 3 , OUTPUT ) ; // 0C0B is connected to pin 3 + + TCCR0A = + 0 << COM0A1 | + 0 << COM0A0 | + 1 << COM0B1 | + 0 << COM0B0 | + 1 << WGM01 | + 1 << WGM00 ; + + TCCR0B = + 1 << WGM02 | + 1 << CS02 | + 0 << CS01 | + 1 << CS00 ; + + OCR0A = 127 ; + OCR0B = 63 ; +} + +void set_up_cooler () { + // 25kHz @ variable duty cycle (initially 50%) on pins 9 and 10 using T/C1 + + pinMode ( 9 , OUTPUT ) ; // 0C1A is connected to pin 9 + pinMode ( 10 , OUTPUT ) ; // 0C1B is connected to pin 10 + + TCCR1A = + 1 << COM1A1 | + 0 << COM1A0 | + 1 << COM1B1 | + 0 << COM1B0 | + 0 << COM1C1 | + 0 << COM1C0 | + 1 << WGM11 | + 0 << WGM10 ; + + TCCR1B = + 1 << WGM13 | + 1 << WGM12 | + 0 << CS12 | + 1 << CS11 | + 0 << CS10 ; + + ICR1H = 0 ; + ICR1L = 79 ; + + OCR1AH = 0 ; + OCR1AL = 39 ; + OCR1BH = 0 ; + OCR1BL = 39 ; +} + +void set_cooler_duty_cycle ( int duty_cycle ) { + OCR1AL = duty_cycle ; + OCR1BL = duty_cycle ; +} + +int main () { + init () ; + USBDevice . attach () ; + + Serial . begin (9600) ; + set_up_fooler () ; + set_up_cooler () ; + + int seqPos = 0 ; + while (true) { + if ( Serial . available () ) { + int input = Serial . read () ; + + // In order to avoid serial writes by software other than kulifuli-host messing things up, + // we check for a specific sequence of 8 bytes before the byte that contains the new duty cycle + if ( + seqPos == 0 && input == 188 || + seqPos == 1 && input == 92 || + seqPos == 2 && input == 136 || + seqPos == 3 && input == 14 || + seqPos == 4 && input == 154 || + seqPos == 5 && input == 39 || + seqPos == 6 && input == 154 || + seqPos == 7 && input == 139 + ) { + // Advance in the sequence + seqPos ++ ; + } else if ( seqPos == 8 ) { + // Sequence completed, `input` is the new duty cycle + set_cooler_duty_cycle (input) ; + // Write back the value as confirmation + Serial . write (input) ; + seqPos = 0 ; + } else { + // Reset sequence progress + seqPos = 0 ; + } + } + } +}