Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • derf/multipass
1 result
Show changes
Showing
with 1802 additions and 10 deletions
...@@ -54,8 +54,8 @@ features; the remainder of this README covers details. ...@@ -54,8 +54,8 @@ features; the remainder of this README covers details.
| MSP430FR5969 | 16 MHz | 48 (64) KiB FRAM | 2 KiB SRAM | I²C, SPI, UART, DMX, ADC | | MSP430FR5969 | 16 MHz | 48 (64) KiB FRAM | 2 KiB SRAM | I²C, SPI, UART, DMX, ADC |
| MSP430FR5994 | 16 MHz | 48 (256) KiB FRAM | 4 (8) KiB SRAM | I²C, SPI, UART, DMX, ADC | | MSP430FR5994 | 16 MHz | 48 (256) KiB FRAM | 4 (8) KiB SRAM | I²C, SPI, UART, DMX, ADC |
| RM46L852 (Cortex-R4F) | 160 MHz | 1.25 MiB Flash | 192 KiB SRAM | | | RM46L852 (Cortex-R4F) | 160 MHz | 1.25 MiB Flash | 192 KiB SRAM | |
| STM32F446RE (Cortex-M4) | 168 MHz | 512 KiB Flash | 128 KiB SRAM | | | STM32F446RE (Cortex-M4) | 168 MHz | 512 KiB Flash | 128 KiB SRAM | I²C |
| STM32F746ZG (Cortex-M7) | 216 MHz | 1 MiB Flash | 320 KiB SRAM | | | STM32F746ZG (Cortex-M7) | 216 MHz | 1 MiB Flash | 320 KiB SRAM | I²C |
| POSIX | – | – | – | I²C | | POSIX | – | – | – | I²C |
## Supported Architectures ## Supported Architectures
...@@ -131,6 +131,7 @@ Peripheral communication: ...@@ -131,6 +131,7 @@ Peripheral communication:
Peripheral communication: Peripheral communication:
* UART output on USART2 * UART output on USART2
* I²C on I2C1 muxed to PB8 / PB9
### STM32F746ZG (NUCLEO-F746ZG) ### STM32F746ZG (NUCLEO-F746ZG)
...@@ -139,6 +140,7 @@ Preliminary support, timers may be incorrect. ...@@ -139,6 +140,7 @@ Preliminary support, timers may be incorrect.
Peripheral communication: Peripheral communication:
* UART output on USART3 * UART output on USART3
* I²C on I2C1 muxed to PB8 / PB9
### POSIX ### POSIX
......
...@@ -26,7 +26,9 @@ class Counter { ...@@ -26,7 +26,9 @@ class Counter {
overflow = 0; overflow = 0;
TA2CTL = TASSEL__SMCLK | ID__1 | MC__CONTINUOUS; TA2CTL = TASSEL__SMCLK | ID__1 | MC__CONTINUOUS;
TA2EX0 = 0; TA2EX0 = 0;
TA2CTL |= TACLR | TAIE; TA2CTL |= TACLR;
asm volatile("nop");
TA2CTL |= TAIE;
asm volatile("nop"); asm volatile("nop");
__eint(); __eint();
asm volatile("nop"); asm volatile("nop");
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
class StandardInput { class StandardInput {
private: private:
StandardInput(const StandardInput &copy); StandardInput(const StandardInput &copy);
static unsigned char const bufsize = 16; static unsigned char const bufsize = 32;
char buffer[bufsize]; char buffer[bufsize];
volatile unsigned char write_pos; volatile unsigned char write_pos;
unsigned char read_pos; unsigned char read_pos;
......
...@@ -59,11 +59,11 @@ class Timer { ...@@ -59,11 +59,11 @@ class Timer {
inline void setup_hz(uint16_t const frequency) { inline void setup_hz(uint16_t const frequency) {
TA0CTL = TASSEL__SMCLK | _TA0_MAIN_DIV; TA0CTL = TASSEL__SMCLK | _TA0_MAIN_DIV;
if (frequency < 32) { if (frequency < 32) {
// 2 MHz base // 250 kHz base
TA0EX0 = 7; TA0EX0 = 7;
TA0CCR0 = 250000UL / frequency; TA0CCR0 = 250000UL / frequency;
} else { } else {
// 250 kHz base // 2 MHz base
TA0EX0 = 0; TA0EX0 = 0;
TA0CCR0 = 2000000UL / frequency; TA0CCR0 = 2000000UL / frequency;
} }
......
/*
* Copyright 2024 Birte Kristina Friesel
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#ifndef I2C_H
#define I2C_H
class I2C {
private:
I2C(const I2C &copy);
public:
I2C () {}
signed char setup();
signed char xmit(unsigned char address,
unsigned char tx_len, unsigned char *tx_buf,
unsigned char rx_len, unsigned char *rx_buf);
};
extern I2C i2c;
#endif
/*
* Copyright 2024 Birte Kristina Friesel
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#ifndef I2C_H
#define I2C_H
class I2C {
private:
I2C(const I2C &copy);
public:
I2C () {}
signed char setup();
signed char xmit(unsigned char address,
unsigned char tx_len, unsigned char *tx_buf,
unsigned char rx_len, unsigned char *rx_buf);
};
extern I2C i2c;
#endif
# Copyright 2020 Birte Kristina Friesel
#
# SPDX-License-Identifier: CC0-1.0
prompt "Bad Apple on STM32F4 + SSD1306 128x64 LCD"
depends on arch_stm32f446re_nucleo
#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
ifdef app
override arch_drivers += i2c,timer
CONFIG_driver_ssd1306 = y
COMMON_FLAGS += -DCONFIG_driver_ssd1306
CONFIG_driver_ssd1306_width = 128
CONFIG_driver_ssd1306_height = 64
CONFIG_lib_inflate = y
CONFIG_lib_inflate_lut = y
CONFIG_arch_msp430fr5994lp_large_mode = y
endif
#!/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:-128x64}" -threshold 50% -- tmp/*.png
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", "128x64").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, 3):
buf = (
load_image(sys.argv[i])
+ load_image(sys.argv[i + 1])
+ load_image(sys.argv[i + 2])
)
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'__attribute__((section(".text"))) unsigned char const frame{i:04d}[] = {{ {out_buf} }};'
)
frames = list()
for i in range(1, len(sys.argv) - 2, 3):
frames.append(f"(unsigned char*)frame{i:04d}")
prefix = '__attribute__((section(".text"))) unsigned char* const frames[] = {'
postfix = "};"
print(prefix + ", ".join(frames) + postfix)
This diff is collapsed.
/*
* Copyright 2024 Birte Kristina Friesel
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include "arch.h"
#include "driver/gpio.h"
#include "driver/stdout.h"
#if defined(CONFIG_meta_driver_hardware_i2c)
#include "driver/i2c.h"
#elif defined(CONFIG_driver_softi2c)
#include "driver/soft_i2c.h"
#endif
#include "driver/ssd1306.h"
#include "lib/inflate.h"
//#include "driver/timer.h"
//volatile unsigned char timer_done = 0;
#include "frames.cc"
unsigned char img_buf[(SSD1306_WIDTH * SSD1306_HEIGHT / 8) * 3];
int main(void)
{
unsigned int i = 0;
unsigned char line;
arch.setup();
gpio.setup();
kout.setup();
i2c.setup();
ssd1306.init();
//timer.setup_hz(frame_rate);
while (1) {
for (i = 0; i < (sizeof(frames) / sizeof(frames[0])); i++) {
//timer_done = 0;
//timer.start(1);
ssd1306.showImage(img_buf + (SSD1306_WIDTH * SSD1306_HEIGHT / 8 * 2), SSD1306_WIDTH * SSD1306_HEIGHT / 8);
arch.delay_ms(15);
gpio.led_on(0);
inflate(frames[i], sizeof(img_buf), img_buf, sizeof(img_buf));
gpio.led_off(0);
//while (!timer_done) {
// arch.idle();
// }
// timer.stop();
// timer_done = 0;
// timer.start(1);
ssd1306.showImage(img_buf + (SSD1306_WIDTH * SSD1306_HEIGHT / 8 * 0), SSD1306_WIDTH * SSD1306_HEIGHT / 8);
arch.delay_ms(20);
// while (!timer_done) {
// arch.idle();
// }
// timer.stop();
// timer_done = 0;
// timer.start(1);
ssd1306.showImage(img_buf + (SSD1306_WIDTH * SSD1306_HEIGHT / 8 * 1), SSD1306_WIDTH * SSD1306_HEIGHT / 8);
arch.delay_ms(20);
// while (!timer_done) {
// arch.idle();
// }
// timer.stop();
}
}
return 0;
}
//ON_TIMER_INTERRUPT_head
// timer_done = 1;
//ON_TIMER_INTERRUPT_tail
...@@ -4,12 +4,15 @@ ...@@ -4,12 +4,15 @@
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
#include "arch.h" #include "arch.h"
#include "driver/gpio.h"
#include "driver/stdout.h" #include "driver/stdout.h"
#if defined(CONFIG_meta_driver_hardware_i2c) #if defined(CONFIG_meta_driver_hardware_i2c)
#include "driver/i2c.h" #include "driver/i2c.h"
#elif defined(CONFIG_driver_softi2c) #elif defined(CONFIG_driver_softi2c)
#include "driver/soft_i2c.h" #include "driver/soft_i2c.h"
#endif #endif
#include "driver/ssd1306.h" #include "driver/ssd1306.h"
#include "object/framebuffer.h" #include "object/framebuffer.h"
#include "lib/pixelfont/pixeloperator_mirrored.h" #include "lib/pixelfont/pixeloperator_mirrored.h"
...@@ -25,6 +28,7 @@ void loop(void) ...@@ -25,6 +28,7 @@ void loop(void)
int main(void) int main(void)
{ {
arch.setup(); arch.setup();
gpio.setup();
kout.setup(); kout.setup();
i2c.setup(); i2c.setup();
ssd1306.init(); ssd1306.init();
......
# Copyright 2020 Birte Kristina Friesel # Copyright 2024 Birte Kristina Friesel
# #
# SPDX-License-Identifier: CC0-1.0 # SPDX-License-Identifier: CC0-1.0
config arch_stm32f446re_nucleo_driver_counter config arch_stm32f446re_nucleo_driver_counter
bool "Cycle Counter" bool "Cycle Counter"
select meta_driver_counter select meta_driver_counter
config arch_stm32f446re_nucleo_driver_i2c
bool "I²C on PB[89]"
help
SDA: PB9 (CN5 D14)
SCL: PB8 (CN5 D15)
select meta_driver_hardware_i2c
select meta_driver_i2c
config arch_stm32f446re_nucleo_driver_i2c_fast_mode
bool "Fast Mode (400 kHz)"
depends on arch_stm32f446re_nucleo_driver_i2c
#config arch_stm32f446re_nucleo_driver_timer #config arch_stm32f446re_nucleo_driver_timer
#bool "Timer with Interrupts" #bool "Timer with Interrupts"
#select meta_driver_timer #select meta_driver_timer
......
...@@ -55,6 +55,10 @@ ifdef CONFIG_arch_stm32f446re_nucleo_driver_counter ...@@ -55,6 +55,10 @@ ifdef CONFIG_arch_stm32f446re_nucleo_driver_counter
CXX_TARGETS += src/arch/stm32f446re-nucleo/driver/counter.cc CXX_TARGETS += src/arch/stm32f446re-nucleo/driver/counter.cc
endif endif
ifdef CONFIG_arch_stm32f446re_nucleo_driver_i2c
CXX_TARGETS += src/arch/stm32f446re-nucleo/driver/i2c.cc
endif
#ifdef CONFIG_arch_stm32f446re_nucleo_driver_timer #ifdef CONFIG_arch_stm32f446re_nucleo_driver_timer
# CXX_TARGETS += src/arch/stm32f446re-nucleo/driver/timer.cc # CXX_TARGETS += src/arch/stm32f446re-nucleo/driver/timer.cc
#endif #endif
......
/*
* Copyright 2024 Birte Kristina Friesel
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include "driver/i2c.h"
#include "arch.h"
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/i2c.h>
signed char I2C::setup()
{
rcc_periph_clock_enable(RCC_I2C1);
gpio_set_af(GPIOB, GPIO_AF4, GPIO8 | GPIO9);
gpio_set_output_options(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_2MHZ, GPIO8|GPIO9);
gpio_mode_setup(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO8 | GPIO9);
i2c_peripheral_disable(I2C1);
#ifdef CONFIG_arch_stm32f446re_nucleo_driver_i2c_fast_mode
i2c_set_speed(I2C1, i2c_speed_fm_400k, rcc_apb1_frequency / 1000000);
#else
i2c_set_speed(I2C1, i2c_speed_sm_100k, rcc_apb1_frequency / 1000000);
#endif
i2c_set_standard_mode(I2C1);
i2c_peripheral_enable(I2C1);
return 0;
}
signed char I2C::xmit(unsigned char address,
unsigned char tx_len, unsigned char *tx_buf,
unsigned char rx_len, unsigned char *rx_buf)
{
i2c_transfer7(I2C1, address, tx_buf, tx_len, rx_buf, rx_len);
return 0;
}
I2C i2c;
...@@ -8,3 +8,15 @@ select meta_driver_counter ...@@ -8,3 +8,15 @@ select meta_driver_counter
config arch_stm32f746zg_nucleo_driver_uptime config arch_stm32f746zg_nucleo_driver_uptime
bool "Uptime Counter" bool "Uptime Counter"
select meta_driver_uptime select meta_driver_uptime
config arch_stm32f746zg_nucleo_driver_i2c
bool "I²C on PB[89]"
help
SDA: PB9 (CN7 D14)
SCL: PB8 (CN7 D15)
select meta_driver_hardware_i2c
select meta_driver_i2c
config arch_stm32f746zg_nucleo_driver_i2c_fast_mode
bool "Fast Mode (400 kHz)"
depends on arch_stm32f746zg_nucleo_driver_i2c
...@@ -51,9 +51,9 @@ ifdef CONFIG_arch_stm32f746zg_nucleo_driver_counter ...@@ -51,9 +51,9 @@ ifdef CONFIG_arch_stm32f746zg_nucleo_driver_counter
CXX_TARGETS += src/arch/stm32f746zg-nucleo/driver/counter.cc CXX_TARGETS += src/arch/stm32f746zg-nucleo/driver/counter.cc
endif endif
#ifdef CONFIG_arch_stm32f746zg_nucleo_driver_i2c ifdef CONFIG_arch_stm32f746zg_nucleo_driver_i2c
# CXX_TARGETS += src/arch/stm32f746zg-nucleo/driver/i2c.cc CXX_TARGETS += src/arch/stm32f746zg-nucleo/driver/i2c.cc
#endif endif
#ifdef CONFIG_arch_stm32f746zg_nucleo_driver_timer #ifdef CONFIG_arch_stm32f746zg_nucleo_driver_timer
# CXX_TARGETS += src/arch/stm32f746zg-nucleo/driver/timer.cc # CXX_TARGETS += src/arch/stm32f746zg-nucleo/driver/timer.cc
......
/*
* Copyright 2024 Birte Kristina Friesel
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include "driver/i2c.h"
#include "arch.h"
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/i2c.h>
signed char I2C::setup()
{
rcc_periph_clock_enable(RCC_I2C1);
gpio_set_af(GPIOB, GPIO_AF4, GPIO8 | GPIO9);
gpio_set_output_options(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_2MHZ, GPIO8|GPIO9);
gpio_mode_setup(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO8 | GPIO9);
i2c_peripheral_disable(I2C1);
#ifdef CONFIG_arch_stm32f746zg_nucleo_driver_i2c_fast_mode
i2c_set_speed(I2C1, i2c_speed_fm_400k, rcc_apb1_frequency / 1000000);
#else
i2c_set_speed(I2C1, i2c_speed_sm_100k, rcc_apb1_frequency / 1000000);
#endif
i2c_peripheral_enable(I2C1);
return 0;
}
signed char I2C::xmit(unsigned char address,
unsigned char tx_len, unsigned char *tx_buf,
unsigned char rx_len, unsigned char *rx_buf)
{
i2c_transfer7(I2C1, address, tx_buf, tx_len, rx_buf, rx_len);
return 0;
}
I2C i2c;