Skip to content
Snippets Groups Projects
Unverified Commit b6206e83 authored by Birte Kristina Friesel's avatar Birte Kristina Friesel
Browse files

Add Bad Apple on ATMega2560 (not working very well)

Looks like these devices can only use the lower 64 kB as PROGMEM, so the
whole exercise is kinda pointless. Also inflate() is slow af.
parent 0d6dfd6e
No related branches found
No related tags found
No related merge requests found
Pipeline #94 failed
# Copyright 2020 Birte Kristina Friesel
#
# SPDX-License-Identifier: CC0-1.0
prompt "Bad Apple on ATMega2560 + SSD1306 128x32 OLED"
depends on arch_atmega2560
depends on meta_driver_timer
depends on driver_ssd1306 && driver_ssd1306_mode_horizontal
depends on lib_inflate && lib_inflate_lut
depends on !loop
depends on !wakeup
# vim:ft=make
#
# Copyright 2020 Birte Kristina Friesel
#
# SPDX-License-Identifier: CC0-1.0
#!/bin/sh
# [size=WxH] ./convert.sh <file> -r <frame rate> [additional ffmpeg args]
set -eu
mkdir -p tmp
ffmpeg -i "$@" tmp/frame%4d.png
parallel mogrify -resize "${size:-128x32}" -threshold 50% -- tmp/*.png
echo "#include <avr/pgmspace.h>" > frames.cc
echo "const unsigned char frame_rate = $3;" >> frames.cc
./frames-to-cc tmp/*.png >> frames.cc
rm -rf tmp
#!/usr/bin/env python3
from PIL import Image
import os
import sys
import zlib
buf_w, buf_h = map(int, os.getenv("size", "128x32").split("x"))
def load_image(filename):
im = Image.open(filename)
w, h = im.size
buf = [0 for i in range(buf_w * buf_h // 8)]
for y in range(min(h, buf_h)):
for x in range(min(w, buf_w)):
if im.getpixel((x, y)):
buf[(y // 8) * buf_w + x] |= 1 << (y % 8)
return buf
for i in range(1, len(sys.argv) - 2):
buf = load_image(sys.argv[i])
c_buf = ",".join(map(str, buf))
z_buf = zlib.compress(bytes(buf), 9)
z_buf = z_buf[2:-4]
out_buf = ",".join(map(str, z_buf))
print(f"unsigned char const PROGMEM frame{i:04d}[] = {{ {len(z_buf)}, {out_buf} }};")
frames = list()
for i in range(1, len(sys.argv) - 2):
frames.append(f"frame{i:04d}")
prefix = "const unsigned char* const frames[] PROGMEM = {"
postfix = "};"
print(prefix + ", ".join(frames) + postfix)
Source diff could not be displayed: it is too large. Options to address this: view the blob.
/*
* Copyright 2020 Birte Kristina Friesel
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include "arch.h"
#include "driver/gpio.h"
#include "driver/stdout.h"
#include "driver/i2c.h"
#include "driver/ssd1306.h"
#include "lib/inflate.h"
#include "driver/timer.h"
volatile unsigned char timer_done = 0;
#include "frames.cc"
/*
* fgrep 'PROGMEM frame' frames.cc | while read line; do echo $line | tr -cd , | wc -c; done | sort -n
* set buffer size to maximum number + 1.
*/
unsigned char deflate_buf[160];
unsigned char img_buf[(SSD1306_WIDTH * SSD1306_HEIGHT / 8)];
int main(void)
{
unsigned int i = 0, j = 0;
unsigned char line, frame_len;
unsigned char *frame;
arch.setup();
gpio.setup();
kout.setup();
i2c.setup();
ssd1306.init();
timer.setup_hz(frame_rate);
timer_done = 0;
timer.start(1);
while (1) {
for (i = 0; i < (sizeof(frames) / sizeof(frames[0])); i++) {
frame = (unsigned char *)pgm_read_ptr(&frames[i]);
frame_len = (unsigned char)pgm_read_byte(&frame[0]);
for (j = 0; j < frame_len; j++) {
deflate_buf[j] = (unsigned char)pgm_read_byte(&frame[j+1]);
}
inflate(deflate_buf, frame_len + 4, img_buf, sizeof(img_buf));
while (!timer_done) {
arch.idle();
}
timer.stop();
timer_done = 0;
timer.start(1);
ssd1306.showImage(img_buf, SSD1306_WIDTH * SSD1306_HEIGHT / 8);
}
}
return 0;
}
ON_TIMER_INTERRUPT_head
timer_done = 1;
ON_TIMER_INTERRUPT_tail
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment