diff options
| -rw-r--r-- | include/arch/arduino-nano/driver/gpio.h | 23 | ||||
| -rw-r--r-- | include/driver/soft_i2c.h | 2 | ||||
| -rw-r--r-- | include/lib/pixelfont/pixeloperator.h | 2 | ||||
| -rw-r--r-- | include/lib/pixelfont/pixeloperator_mirrored.h | 2 | ||||
| -rw-r--r-- | include/lib/pixelfont/terminus16.h | 2 | ||||
| -rw-r--r-- | include/lib/pixelfont/terminus24.h | 2 | ||||
| -rw-r--r-- | src/app/forced-convection/.config | 101 | ||||
| -rw-r--r-- | src/app/forced-convection/Kconfig | 6 | ||||
| -rw-r--r-- | src/app/forced-convection/Makefile.inc | 9 | ||||
| -rw-r--r-- | src/app/forced-convection/main.cc | 169 | ||||
| -rw-r--r-- | src/arch/arduino-nano/Makefile.inc | 1 | ||||
| -rw-r--r-- | src/arch/atmega2560/Makefile.inc | 1 | ||||
| -rw-r--r-- | src/driver/soft_i2c.cc | 4 | ||||
| -rw-r--r-- | src/object/framebuffer.cc | 6 |
14 files changed, 323 insertions, 7 deletions
diff --git a/include/arch/arduino-nano/driver/gpio.h b/include/arch/arduino-nano/driver/gpio.h index eba3fad..becc16b 100644 --- a/include/arch/arduino-nano/driver/gpio.h +++ b/include/arch/arduino-nano/driver/gpio.h @@ -41,6 +41,29 @@ class GPIO { pd7 = 31 }; + enum ArduinoPin : unsigned char { + rx0 = pd0, + tx1 = pd1, + d2 = pd2, + d3 = pd3, + d4 = pd4, + d5 = pd5, + d6 = pd6, + d7 = pd7, + d8 = pb0, + d9 = pb1, + d10 = pb2, + d11 = pb3, + d12 = pb4, + a0 = pc0, + a1 = pc1, + a2 = pc2, + a3 = pc3, + a4 = pc4, + a5 = pc5, + rst = pc6 + }; + inline void setup() { DDRB = _BV(PB5); } diff --git a/include/driver/soft_i2c.h b/include/driver/soft_i2c.h index a5da1f6..15784d9 100644 --- a/include/driver/soft_i2c.h +++ b/include/driver/soft_i2c.h @@ -37,6 +37,8 @@ class SoftI2C { #ifndef DRIVER_HARDWARE_I2C extern SoftI2C i2c; +#else +extern SoftI2C softi2c; #endif #endif diff --git a/include/lib/pixelfont/pixeloperator.h b/include/lib/pixelfont/pixeloperator.h index 30f5154..dc1c7d2 100644 --- a/include/lib/pixelfont/pixeloperator.h +++ b/include/lib/pixelfont/pixeloperator.h @@ -9,7 +9,7 @@ * SPDX-License-Identifier: CC0-1.0 */ -#ifdef MULTIPASS_ARCH_arduino_nano +#ifdef HAVE_PROGMEM #include <avr/pgmspace.h> #define GLYPH_ATTR PROGMEM #else diff --git a/include/lib/pixelfont/pixeloperator_mirrored.h b/include/lib/pixelfont/pixeloperator_mirrored.h index 149015c..817d843 100644 --- a/include/lib/pixelfont/pixeloperator_mirrored.h +++ b/include/lib/pixelfont/pixeloperator_mirrored.h @@ -9,7 +9,7 @@ * SPDX-License-Identifier: CC0-1.0 */ -#ifdef MULTIPASS_ARCH_arduino_nano +#ifdef HAVE_PROGMEM #include <avr/pgmspace.h> #define GLYPH_ATTR PROGMEM #else diff --git a/include/lib/pixelfont/terminus16.h b/include/lib/pixelfont/terminus16.h index e63fba8..d84a328 100644 --- a/include/lib/pixelfont/terminus16.h +++ b/include/lib/pixelfont/terminus16.h @@ -8,7 +8,7 @@ * SPDX-License-Identifier: OFL-1.1 */ -#ifdef MULTIPASS_ARCH_arduino_nano +#ifdef HAVE_PROGMEM #include <avr/pgmspace.h> #define GLYPH_ATTR PROGMEM #else diff --git a/include/lib/pixelfont/terminus24.h b/include/lib/pixelfont/terminus24.h index cd4a785..3a285e1 100644 --- a/include/lib/pixelfont/terminus24.h +++ b/include/lib/pixelfont/terminus24.h @@ -8,7 +8,7 @@ * SPDX-License-Identifier: OFL-1.1 */ -#ifdef MULTIPASS_ARCH_arduino_nano +#ifdef HAVE_PROGMEM #include <avr/pgmspace.h> #define GLYPH_ATTR PROGMEM #else diff --git a/src/app/forced-convection/.config b/src/app/forced-convection/.config new file mode 100644 index 0000000..b8305be --- /dev/null +++ b/src/app/forced-convection/.config @@ -0,0 +1,101 @@ +# +# Automatically generated file; DO NOT EDIT. +# Configuration +# + +# +# System +# +CONFIG_loop=y +# CONFIG_wakeup is not set +# CONFIG_aspectc is not set +CONFIG_i2c_freq=100000 +CONFIG_framebuffer=y +# CONFIG_framebuffer_in_text_segment is not set +CONFIG_framebuffer_width=128 +CONFIG_framebuffer_height=32 + +# +# Libraries +# +# CONFIG_lib_inflate is not set +# CONFIG_arch_arduino_nano is not set +CONFIG_arch_arduino_uno=y +# CONFIG_arch_atmega2560 is not set +# CONFIG_arch_blinkenrocket is not set +# CONFIG_arch_infineon_tc299_mock is not set +# CONFIG_arch_infineon_tc397_mock is not set +# CONFIG_arch_lm4f120h5qr_stellaris is not set +# CONFIG_arch_lora32u4ii is not set +# CONFIG_arch_msp430fr5969lp is not set +# CONFIG_arch_msp430fr5994lp is not set +# CONFIG_arch_posix is not set +# CONFIG_arch_rm46l8lp is not set +# CONFIG_arch_stm32f103c8t6 is not set +# CONFIG_arch_stm32f446re_nucleo is not set +# CONFIG_arch_stm32f746zg_nucleo is not set +# CONFIG_arch_stm32h747i_disco is not set +# CONFIG_arch_tc1796_triboard is not set +CONFIG_arch="arduino-uno" + +# +# Arduino Uno Configuration +# +CONFIG_arch_arduino_uno_cpufreq=16000000 +CONFIG_arch_arduino_uno_driver_adc=y +CONFIG_arch_arduino_uno_driver_i2c=y +# CONFIG_arch_arduino_uno_driver_neopixel is not set +# CONFIG_arch_arduino_uno_driver_spi is not set +# CONFIG_arch_arduino_uno_driver_stdin is not set +# CONFIG_arch_arduino_uno_driver_timer is not set +# CONFIG_arch_arduino_uno_driver_dmx is not set +# CONFIG_app_datalogger is not set +CONFIG_app_forced_convection=y +# CONFIG_app_ledblink is not set +# CONFIG_app_lora32u4ii is not set +# CONFIG_app_sdtest is not set +# CONFIG_app_ssd1306_128x32_bad_apple is not set +# CONFIG_app_ssd1306test is not set +CONFIG_app="forced-convection" +CONFIG_meta_driver_adc=y +CONFIG_meta_driver_hardware_i2c=y +CONFIG_meta_driver_i2c=y + +# +# Drivers +# +# CONFIG_driver_ads111x is not set +# CONFIG_driver_am2320 is not set +# CONFIG_driver_bme280 is not set +# CONFIG_driver_bme680 is not set +# CONFIG_driver_ccs811 is not set +# CONFIG_driver_ds2482 is not set +# CONFIG_driver_eeprom24lc64 is not set +# CONFIG_driver_hdc1080 is not set +CONFIG_driver_lm75=y +# CONFIG_driver_max44006 is not set +# CONFIG_driver_max44009 is not set +# CONFIG_driver_mmsimple is not set +# CONFIG_driver_mmsubstate is not set +# CONFIG_driver_mpu9250 is not set +# CONFIG_driver_s5851a is not set +# CONFIG_driver_scd4x is not set +# CONFIG_driver_sen5x is not set +# CONFIG_driver_sen66 is not set +# CONFIG_driver_veml6075 is not set +CONFIG_driver_ssd1306=y +CONFIG_driver_ssd1306_width=128 +CONFIG_driver_ssd1306_height=32 +CONFIG_driver_ssd1306_mode_vertical=y +# CONFIG_driver_ssd1306_mode_horizontal is not set +CONFIG_driver_ssd1306_i2c_name="softi2c" +# CONFIG_driver_tsl2591 is not set +CONFIG_driver_softi2c=y + +# +# SoftI2C Configuration +# +CONFIG_driver_softi2c_scl="a1" +CONFIG_driver_softi2c_sda="a0" +# CONFIG_driver_softi2c_pullup_none is not set +CONFIG_driver_softi2c_pullup_dynamic_internal=y diff --git a/src/app/forced-convection/Kconfig b/src/app/forced-convection/Kconfig new file mode 100644 index 0000000..157728d --- /dev/null +++ b/src/app/forced-convection/Kconfig @@ -0,0 +1,6 @@ +# Copyright 2026 Birte Kristina Friesel +# +# SPDX-License-Identifier: CC0-1.0 + +prompt "Forced Convection" +depends on loop && !wakeup diff --git a/src/app/forced-convection/Makefile.inc b/src/app/forced-convection/Makefile.inc new file mode 100644 index 0000000..538ac69 --- /dev/null +++ b/src/app/forced-convection/Makefile.inc @@ -0,0 +1,9 @@ +# vim:ft=make +# +# Copyright 2026 Birte Kristina Friesel +# +# SPDX-License-Identifier: CC0-1.0 + +ifdef app + loop = 1 +endif diff --git a/src/app/forced-convection/main.cc b/src/app/forced-convection/main.cc new file mode 100644 index 0000000..052e3fc --- /dev/null +++ b/src/app/forced-convection/main.cc @@ -0,0 +1,169 @@ +/* + * Copyright 2026 Birte Kristina Friesel + * + * SPDX-License-Identifier: BSD-2-Clause + */ +#include "arch.h" +#include "driver/adc.h" +#include "driver/gpio.h" +#include "driver/stdout.h" +#include "driver/i2c.h" +#include "driver/soft_i2c.h" +#include "driver/lm75.h" +#include "driver/ssd1306.h" +#include "lib/pixelfont/pixeloperator_mirrored.h" +#include "object/framebuffer.h" + + +#define shift_ser GPIO::d8 +#define shift_clk GPIO::d4 +#define shift_latch GPIO::d12 +#define shift_en GPIO::d7 + +#define PWM1 OCR2A +#define PWM2 OCR2B +#define PWM3 OCR0A +#define PWM4 OCR0B + +#define PWM1_EN _BV(5) +#define PWM2_EN _BV(3) +#define PWM3_EN _BV(0) +#define PWM4_EN _BV(7) + +unsigned char graph[88]; +unsigned char graph_offset = 0; + +void loop(void) +{ + static int seconds = 0; + static int fan_speed = 0; + gpio.led_on(0); + float temp = lm75.getTemp(); + + if (temp < 25) { + PWM1 = 0; + PWM2 = 0; + PWM3 = 0; + PWM4 = 0; + TCCR0A = 0; + TCCR2A = 0; + TCCR0B = 0; + TCCR2B = 0; + fan_speed = 0; + } + else if (temp >= 30) { + PWM1 = 255; + PWM2 = 255; + PWM3 = 255; + PWM4 = 255; + TCCR0A = _BV(COM0A1) | _BV(COM0B1) | _BV(WGM01) | _BV(WGM00); + TCCR2A = _BV(COM2A1) | _BV(COM2B1) | _BV(WGM21) | _BV(WGM20); + TCCR0B = _BV(CS00); + TCCR2B = _BV(CS20); + fan_speed = 100; + } + + if (seconds++ == 60) { + if (temp < 20) { + graph[graph_offset ] = 0; + } + else if (temp > 40) { + graph[graph_offset ] = 31; + } + else { + graph[graph_offset] = (temp - 20) * 1.5; + } + seconds = 0; + graph_offset = (graph_offset + 1) % (sizeof(graph) / sizeof(graph[0])); + } + + uint16_t vcc = adc.getVCC_mV() - 200; + + fb.clear(); + fb.setFont(pixeloperator_mirrored); + fb.setPos(88, 0); + fb << temp << "c"; + fb.setPos(88, 16); + fb << vcc/1000 << "." << (vcc%1000)/100 << (vcc%100)/10 << "V"; + fb.setPos(88, 24); + fb << fan_speed << "%"; + + for (unsigned char i = 0; i < (sizeof(graph) / sizeof(graph[0])); i++) { + unsigned char column_value = graph[(graph_offset + i) % (sizeof(graph) / sizeof(graph[0]))]; + fb.data[i*4 + 3 - (column_value/8)] = 1 << ( 7 - column_value%8); + } + ssd1306.showImage(fb.data, fb.width * fb.height / 8); + + kout << "temperature_celsius: "; + kout.printf_float(temp); + kout << endl; + gpio.led_off(0); +} + +int main(void) +{ + arch.setup(); + gpio.setup(); + kout.setup(); + + gpio.led_on(0); + + /* + * Ensure that the SSD1306 OLED display gets a clean reset / power cycle + */ + + gpio.output(GPIO::a2, 0); + gpio.output(GPIO::a3, 0); + + arch.delay_ms(50); + + gpio.write(GPIO::a2, 1); + gpio.write(GPIO::a3, 0); + + arch.delay_ms(50); + + if (i2c.setup() != 0) { + kout << "I2C setup FAILED" << endl; + return 1; + } + kout << "I2C setup OK" << endl; + + if (softi2c.setup() != 0) { + kout << "SoftI2C setup FAILED" << endl; + return 1; + } + kout << "SoftI2C setup OK" << endl; + + lm75.setOS(30); + lm75.setHyst(25); + ssd1306.init(); + + fb.setFont(pixeloperator_mirrored); + + gpio.output(shift_ser, 0); + gpio.output(shift_clk, 0); + gpio.output(shift_latch, 0); + gpio.output(shift_en, 0); + + gpio.output(GPIO::pd3, 0); // OC2B - D3 + gpio.output(GPIO::pd5, 0); // OC0B - D5 + gpio.output(GPIO::pd6, 0); // OC0A - D6 + gpio.output(GPIO::pb3, 0); // OC2A - D11 + + // m4a m2a m1a m1b m2b m3a m4b m3b + uint8_t shift_out = 0b10101001; + + for (unsigned int i = 0; i < 8; i++) { + gpio.write(shift_ser, shift_out & (1<<i)); + gpio.write(shift_clk, 1); + gpio.write(shift_clk, 0); + } + gpio.write(shift_latch, 1); + gpio.write(shift_latch, 0); + + gpio.led_off(0); + + arch.idle_loop(); + + return 0; +} diff --git a/src/arch/arduino-nano/Makefile.inc b/src/arch/arduino-nano/Makefile.inc index 2313d18..f6fb416 100644 --- a/src/arch/arduino-nano/Makefile.inc +++ b/src/arch/arduino-nano/Makefile.inc @@ -22,6 +22,7 @@ cpu_freq ?= 16000000 COMMON_FLAGS += -Werror=overflow COMMON_FLAGS += -mmcu=${MCU} -DMULTIPASS_ARCH_arduino_nano COMMON_FLAGS += -DF_CPU=${cpu_freq}UL +COMMON_FLAGS += -DHAVE_PROGMEM ifeq (${stack_usage}, ) COMMON_FLAGS += -flto diff --git a/src/arch/atmega2560/Makefile.inc b/src/arch/atmega2560/Makefile.inc index 6d82a1c..a8cfb42 100644 --- a/src/arch/atmega2560/Makefile.inc +++ b/src/arch/atmega2560/Makefile.inc @@ -17,6 +17,7 @@ cpu_freq ?= 16000000 COMMON_FLAGS += -Werror=overflow COMMON_FLAGS += -mmcu=${MCU} -DMULTIPASS_ARCH_atmega2560 COMMON_FLAGS += -DF_CPU=${cpu_freq}UL +COMMON_FLAGS += -DHAVE_PROGMEM ifeq (${stack_usage}, ) COMMON_FLAGS += -flto diff --git a/src/driver/soft_i2c.cc b/src/driver/soft_i2c.cc index 7369b2d..7bf030f 100644 --- a/src/driver/soft_i2c.cc +++ b/src/driver/soft_i2c.cc @@ -239,4 +239,8 @@ ON_TIMER_INTERRUPT_tail SoftI2C i2c(GPIO::CONFIG_driver_softi2c_sda, GPIO::CONFIG_driver_softi2c_scl); +#else + +SoftI2C softi2c(GPIO::CONFIG_driver_softi2c_sda, GPIO::CONFIG_driver_softi2c_scl); + #endif /* !DRIVER_HARDWARE_I2C */ diff --git a/src/object/framebuffer.cc b/src/object/framebuffer.cc index e7b914d..a3848ef 100644 --- a/src/object/framebuffer.cc +++ b/src/object/framebuffer.cc @@ -1,6 +1,6 @@ #include "object/framebuffer.h" -#ifdef MULTIPASS_ARCH_arduino_nano +#ifdef HAVE_PROGMEM #include <avr/pgmspace.h> #endif @@ -119,7 +119,7 @@ void Framebuffer::put(char c) if ((c < 32) || (c > 126)) { c = '?'; } -#ifdef MULTIPASS_ARCH_arduino_nano +#ifdef HAVE_PROGMEM uint8_t *glyph_addr = (uint8_t *)pgm_read_ptr(&font[c - 32]); const unsigned char glyph_w = pgm_read_byte(&glyph_addr[0]); #else @@ -136,7 +136,7 @@ void Framebuffer::put(char c) for (unsigned char i = 0; i < glyph_w; i++) { unsigned char x = i / fontSize; unsigned char y = i % fontSize; -#ifdef MULTIPASS_ARCH_arduino_nano +#ifdef HAVE_PROGMEM data[(height/8) * (fontX + x) + fontY/8 + y] = pgm_read_byte(&glyph_addr[i+1]); #else data[(height/8) * (fontX + x) + fontY/8 + y] = glyph[i+1]; |
