working mode switch with text scroll

multi-mode
Ondřej Hruška 8 years ago
parent 7af5f0e35e
commit dbd2d6a7ea
  1. 7
      f103-ledmatrix.pro
  2. 108
      project/font.h
  3. 112
      project/main.c
  4. 10
      project/mode_audio.c
  5. 2
      project/mode_audio.h
  6. 59
      project/scrolltext.c
  7. 10
      project/scrolltext.h

@ -91,7 +91,9 @@ HEADERS += \
lib/cmsis/DSP_Lib/Include/core_cmFunc.h \
lib/cmsis/DSP_Lib/Include/core_cmInstr.h \
lib/cmsis/DSP_Lib/Include/core_cmSimd.h \
project/mode_audio.h
project/mode_audio.h \
project/font.h \
project/scrolltext.h
SOURCES += \
lib/cmsis/core_cm3.c \
@ -422,7 +424,8 @@ SOURCES += \
lib/cmsis/DSP_Lib/Source/TransformFunctions/arm_rfft_init_q31.c \
lib/cmsis/DSP_Lib/Source/TransformFunctions/arm_rfft_q15.c \
lib/cmsis/DSP_Lib/Source/TransformFunctions/arm_rfft_q31.c \
project/mode_audio.c
project/mode_audio.c \
project/scrolltext.c
DISTFILES += \
style.astylerc \

@ -0,0 +1,108 @@
#ifndef FONT_H
#define FONT_H
#define FONT_MIN ' '
#define FONT_MAX '~'
#define FONT_WIDTH 6
const unsigned char font[96][6] = {
{0x00,0x00,0x00,0x00,0x00,0x00}, //
{0x5c,0x00,0x00,0x00,0x00,0x00}, // !
{0x06,0x00,0x06,0x00,0x00,0x00}, // "
{0x28,0x7c,0x28,0x7c,0x28,0x00}, // #
{0x5c,0x54,0xfe,0x54,0x74,0x00}, // $
{0x44,0x20,0x10,0x08,0x44,0x00}, // %
{0x28,0x54,0x54,0x20,0x50,0x00}, // &
{0x06,0x00,0x00,0x00,0x00,0x00}, // '
{0x38,0x44,0x00,0x00,0x00,0x00}, // (
{0x44,0x38,0x00,0x00,0x00,0x00}, // )
{0x02,0x07,0x02,0x00,0x00,0x00}, // *
{0x10,0x10,0x7c,0x10,0x10,0x00}, // +
{0xc0,0x00,0x00,0x00,0x00,0x00}, // ,
{0x10,0x10,0x10,0x10,0x10,0x00}, // -
{0x40,0x00,0x00,0x00,0x00,0x00}, // .
{0x60,0x10,0x0c,0x00,0x00,0x00}, // /
{0x7c,0x64,0x54,0x4c,0x7c,0x00}, // 0
{0x48,0x7c,0x40,0x00,0x00,0x00}, // 1
{0x64,0x54,0x54,0x54,0x48,0x00}, // 2
{0x44,0x54,0x54,0x54,0x6c,0x00}, // 3
{0x3c,0x20,0x70,0x20,0x20,0x00}, // 4
{0x5c,0x54,0x54,0x54,0x24,0x00}, // 5
{0x7c,0x54,0x54,0x54,0x74,0x00}, // 6
{0x04,0x04,0x64,0x14,0x0c,0x00}, // 7
{0x7c,0x54,0x54,0x54,0x7c,0x00}, // 8
{0x5c,0x54,0x54,0x54,0x7c,0x00}, // 9
{0x44,0x00,0x00,0x00,0x00,0x00}, // :
{0xc4,0x00,0x00,0x00,0x00,0x00}, // ;
{0x10,0x28,0x44,0x00,0x00,0x00}, // <
{0x28,0x28,0x28,0x28,0x28,0x00}, // =
{0x44,0x28,0x10,0x00,0x00,0x00}, // >
{0x08,0x04,0x54,0x08,0x00,0x00}, // ?
{0x7c,0x44,0x54,0x54,0x5c,0x00}, // @
{0x7c,0x24,0x24,0x24,0x7c,0x00}, // A
{0x7c,0x54,0x54,0x54,0x6c,0x00}, // B
{0x7c,0x44,0x44,0x44,0x44,0x00}, // C
{0x7c,0x44,0x44,0x44,0x38,0x00}, // D
{0x7c,0x54,0x54,0x54,0x44,0x00}, // E
{0x7c,0x14,0x14,0x14,0x04,0x00}, // F
{0x7c,0x44,0x44,0x54,0x74,0x00}, // G
{0x7c,0x10,0x10,0x10,0x7c,0x00}, // H
{0x44,0x44,0x7c,0x44,0x44,0x00}, // I
{0x60,0x40,0x40,0x44,0x7c,0x00}, // J
{0x7c,0x10,0x10,0x28,0x44,0x00}, // K
{0x7c,0x40,0x40,0x40,0x40,0x00}, // L
{0x7c,0x08,0x10,0x08,0x7c,0x00}, // M
{0x7c,0x08,0x10,0x20,0x7c,0x00}, // N
{0x38,0x44,0x44,0x44,0x38,0x00}, // O
{0x7c,0x14,0x14,0x14,0x08,0x00}, // P
{0x3c,0x24,0x64,0x24,0x3c,0x00}, // Q
{0x7c,0x14,0x14,0x14,0x68,0x00}, // R
{0x5c,0x54,0x54,0x54,0x74,0x00}, // S
{0x04,0x04,0x7c,0x04,0x04,0x00}, // T
{0x7c,0x40,0x40,0x40,0x7c,0x00}, // U
{0x0c,0x30,0x40,0x30,0x0c,0x00}, // V
{0x3c,0x40,0x30,0x40,0x3c,0x00}, // W
{0x44,0x28,0x10,0x28,0x44,0x00}, // X
{0x0c,0x10,0x60,0x10,0x0c,0x00}, // Y
{0x44,0x64,0x54,0x4c,0x44,0x00}, // Z
{0x7c,0x44,0x00,0x00,0x00,0x00}, // [
{0x0c,0x10,0x60,0x00,0x00,0x00}, // "\"
{0x44,0x7c,0x00,0x00,0x00,0x00}, // ]
{0x00,0x01,0x00,0x01,0x00,0x00}, // ^
{0x40,0x40,0x40,0x40,0x40,0x40}, // _
{0x00,0x01,0x00,0x00,0x00,0x00}, // `
{0x7c,0x24,0x24,0x24,0x7c,0x00}, // a
{0x7c,0x54,0x54,0x54,0x6c,0x00}, // b
{0x7c,0x44,0x44,0x44,0x44,0x00}, // c
{0x7c,0x44,0x44,0x44,0x38,0x00}, // d
{0x7c,0x54,0x54,0x54,0x44,0x00}, // e
{0x7c,0x14,0x14,0x14,0x04,0x00}, // f
{0x7c,0x44,0x44,0x54,0x74,0x00}, // g
{0x7c,0x10,0x10,0x10,0x7c,0x00}, // h
{0x44,0x44,0x7c,0x44,0x44,0x00}, // i
{0x60,0x40,0x40,0x44,0x7c,0x00}, // j
{0x7c,0x10,0x10,0x28,0x44,0x00}, // k
{0x7c,0x40,0x40,0x40,0x40,0x00}, // l
{0x7c,0x08,0x10,0x08,0x7c,0x00}, // m
{0x7c,0x08,0x10,0x20,0x7c,0x00}, // n
{0x38,0x44,0x44,0x44,0x38,0x00}, // o
{0x7c,0x14,0x14,0x14,0x08,0x00}, // p
{0x3c,0x24,0x64,0x24,0x3c,0x00}, // q
{0x7c,0x14,0x14,0x14,0x68,0x00}, // r
{0x5c,0x54,0x54,0x54,0x74,0x00}, // s
{0x04,0x04,0x7c,0x04,0x04,0x00}, // t
{0x7c,0x40,0x40,0x40,0x7c,0x00}, // u
{0x0c,0x30,0x40,0x30,0x0c,0x00}, // v
{0x3c,0x40,0x30,0x40,0x3c,0x00}, // w
{0x44,0x28,0x10,0x28,0x44,0x00}, // x
{0x0c,0x10,0x60,0x10,0x0c,0x00}, // y
{0x44,0x64,0x54,0x4c,0x44,0x00}, // z
{0x10,0x7c,0x44,0x00,0x00,0x00}, // {
{0x6c,0x00,0x00,0x00,0x00,0x00}, // |
{0x44,0x7c,0x10,0x00,0x00,0x00}, // }
{0x02,0x01,0x02,0x01,0x00,0x00}, // ~
{0x00,0x00,0x00,0x00,0x00,0x00}
};
#endif // FONT_H

@ -18,18 +18,84 @@
#include "arm_math.h"
#include "mode_audio.h"
#include "scrolltext.h"
/** Functional mode */
typedef enum {
MODE_AUDIO,
MODE_LIFE,
MODE_SNAKE,
MODE_END,
} GameMode;
static void poll_subsystems(void);
static void gamepad_rx(ComIface *iface);
static void boot_animation(void);
static void switch_mode(void *unused); // circle b/w modes
static void activate_mode(void); // activate currently selected mode
static task_pid_t capture_task_id;
static void boot_animation(void)
static GameMode app_mode;
static void switch_mode(void *unused)
{
// Boot animation (for FFT)
for(int i = 0; i < 16; i++) {
dmtx_set(dmtx, i, 0, 1);
(void)unused;
if (++app_mode == MODE_END) {
app_mode = 0;
}
activate_mode();
}
#define SCROLL_STEP 20
static void activate_mode(void)
{
// --- Audio FFT mode ---
if (app_mode == MODE_AUDIO) {
info("MODE: Audio");
scrolltext("Audio FFT", SCROLL_STEP);
audio_mode_active = true;
enable_periodic_task(capture_task_id, true);
} else {
audio_mode_active = false;
enable_periodic_task(capture_task_id, false);
}
// --- Game Of Life ---
if (app_mode == MODE_LIFE) {
info("MODE: Life");
scrolltext("Game of Life", SCROLL_STEP);
dmtx_clear(dmtx);
dmtx_set(dmtx, 5, 5, 1);
dmtx_show(dmtx);
delay_ms(25);
//
} else {
//
}
// --- Snake Minigame ---
if (app_mode == MODE_SNAKE) {
info("MODE: Snake");
scrolltext("Snake", SCROLL_STEP);
dmtx_clear(dmtx);
dmtx_set(dmtx, 13, 13, 1);
dmtx_show(dmtx);
//
} else {
//
}
}
@ -42,11 +108,10 @@ int main(void)
banner_info("(c) Ondrej Hruska, 2016");
boot_animation();
gamepad_iface->rx_callback = gamepad_rx;
//debug_iface->rx_callback = rx_char;
capture_task_id = add_periodic_task(capture_audio, NULL, 10, false);
ms_time_t last;
while (1) {
if (ms_loop_elapsed(&last, 500)) {
@ -80,18 +145,31 @@ static void poll_subsystems(void)
}
//static void rx_char(ComIface *iface)
//{
// uint8_t ch;
// while(com_rx(iface, &ch)) {
// if (ch == 'p') {
// info("PRINT_NEXT");
// print_next_fft = true;
// }
// }
//}
static void boot_animation(void)
{
// Boot animation (for FFT)
for(int i = 0; i < 16; i++) {
dmtx_set(dmtx, i, 0, 1);
dmtx_show(dmtx);
delay_ms(25);
}
}
static void gamepad_rx(ComIface *iface)
{
uint8_t ch;
while(com_rx(iface, &ch)) {
// com_tx(debug_iface, ch);
// com_tx(debug_iface, '\n');
/* SELECT */
if (ch == 'I') {
tq_post(switch_mode, NULL);
}
}
}
//void dlnk_rx(SBMP_Datagram *dg)
//{

@ -4,6 +4,8 @@
#include "dotmatrix.h"
bool audio_mode_active = true;
static volatile bool capture_pending = false;
static volatile bool print_next_fft = false;
@ -59,7 +61,12 @@ void DMA1_Channel1_IRQHandler(void)
TIM_Cmd(TIM3, DISABLE);
ADC_DMACmd(ADC1, DISABLE);
tq_post(audio_capture_done, NULL);
if (audio_mode_active) {
tq_post(audio_capture_done, NULL);
} else {
// unset 'pending'
capture_pending = false;
}
}
@ -143,6 +150,7 @@ void capture_audio(void *unused)
{
(void)unused;
if (capture_pending) return;
if (! audio_mode_active) return;
capture_pending = true;

@ -3,6 +3,8 @@
#include "main.h"
extern bool audio_mode_active;
void capture_audio(void *unused);
#endif // MODE_AUDIO_H

@ -0,0 +1,59 @@
#include "scrolltext.h"
#include "font.h"
#include "com/debug.h"
static void printtext(const char *text, int x, int y)
{
dmtx_clear(dmtx);
dmtx_show(dmtx);
int totalX = 0;
for (int textX = 0; textX < (int)strlen(text); textX++) {
uint8_t ch = (uint8_t)text[textX];
if (ch < FONT_MIN) ch = '?';
if (ch > FONT_MAX) ch = '?';
ch -= ' '; // normalize for font table
if (ch == 0) { // space
totalX += 3;
continue;
}
// one letter
uint8_t blanks = 0;
// skip empty space on right
for (int charX = FONT_WIDTH-1; charX >= 0; charX--) {
uint8_t col = font[ch][charX];
if (col == 0x00) {
blanks++;
} else {
break;
}
}
for (int charX = 0; charX < FONT_WIDTH - blanks; charX++) {
uint8_t col = font[ch][charX];
for (int charY = 0; charY < 8; charY++) {
dmtx_set(dmtx, x + totalX, y + 8 - charY, (col >> charY) & 1);
}
totalX++;
}
totalX++; // gap
}
dmtx_show(dmtx);
}
void scrolltext(const char *text, ms_time_t step)
{
(void)step;
for (int i = 0; i < (int)strlen(text)*FONT_WIDTH + 15; i++) {
if (i > 0) delay_ms(step);
printtext(text, 15-i, 4);
}
}

@ -0,0 +1,10 @@
#ifndef SCROLLTEXT_H
#define SCROLLTEXT_H
#include "main.h"
#include "dotmatrix.h"
#include "utils/timebase.h"
void scrolltext(const char *text, ms_time_t step);
#endif // SCROLLTEXT_H
Loading…
Cancel
Save