Add animations (#15)
* animation: add xbm animations * refactor: correct framebuffer terminology * animation: add animations and effect * animation: timing with TMOS scheduler
This commit is contained in:
committed by
GitHub
parent
f5874d6073
commit
c95faf32a6
@@ -45,8 +45,8 @@ The "mode" bytes are a combination of two 4 bit values. The high nibble describe
|
||||
| 0x02 | scroll up |
|
||||
| 0x03 | scroll down |
|
||||
| 0x04 | fixed |
|
||||
| 0x05 | "snowflake" |
|
||||
| 0x06 | "picture" |
|
||||
| 0x07 | "animation" |
|
||||
| 0x05 | "animation" |
|
||||
| 0x06 | "snowflake" |
|
||||
| 0x07 | "picture" |
|
||||
| 0x08 | "laser" |
|
||||
|
||||
|
||||
6
Makefile
6
Makefile
@@ -51,7 +51,7 @@ CH5xx_ble_firmware_library/RVMSIS/core_riscv.c \
|
||||
src/main.c \
|
||||
src/leddrv.c \
|
||||
src/button.c \
|
||||
src/fb.c \
|
||||
src/bmlist.c \
|
||||
src/ble/profile/legacy.c \
|
||||
src/ble/profile/devinfo.c \
|
||||
src/ble/setup.c \
|
||||
@@ -64,6 +64,10 @@ src/usb/debug.c \
|
||||
src/usb/dev.c \
|
||||
src/usb/composite/hiddev.c \
|
||||
src/usb/composite/cdc-serial.c \
|
||||
src/xbm.c \
|
||||
src/resource.c \
|
||||
src/animation.c \
|
||||
|
||||
|
||||
# ASM sources
|
||||
ASM_SOURCES = \
|
||||
|
||||
464
src/animation.c
Normal file
464
src/animation.c
Normal file
@@ -0,0 +1,464 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "xbm.h"
|
||||
#include "leddrv.h"
|
||||
#include "bmlist.h"
|
||||
|
||||
#define ANI_ANIMATION_STEPS (5) // steps
|
||||
#define ANI_FIXED_STEPS (LED_COLS) // steps
|
||||
|
||||
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
|
||||
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
|
||||
#define ALIGN(x, range) (((x % (range))>0)*(range) + (x / (range)) * (range))
|
||||
|
||||
// Shift left on positive and right on negative n
|
||||
#define SIGNED_SHIFT(reg, n) ((n) >= 0) ? (reg) >> (n) : (reg) << abs(n)
|
||||
|
||||
int mod(int a, int b)
|
||||
{
|
||||
int r = a % b;
|
||||
return r < 0 ? r + b : r;
|
||||
}
|
||||
|
||||
void fb_fill(uint16_t *fb, uint16_t v)
|
||||
{
|
||||
for (int i = 0; i < LED_COLS; i++) {
|
||||
fb[i] = v;
|
||||
}
|
||||
}
|
||||
|
||||
int ani_xbm_next_frame(xbm_t *xbm, uint16_t *fb, int col, int row)
|
||||
{
|
||||
static int i;
|
||||
|
||||
xbm_t frame;
|
||||
if (extract_frame(xbm, &frame, i) == NULL) {
|
||||
i = 0;
|
||||
return i;
|
||||
}
|
||||
xbm2fb(&frame, fb, col, row);
|
||||
|
||||
return ++i;
|
||||
}
|
||||
|
||||
int ani_xbm_scroll_up(xbm_t *xbm, int vh,
|
||||
uint16_t *fb, int col, int row)
|
||||
{
|
||||
static int i;
|
||||
|
||||
xbm_t frame;
|
||||
if (xbm_croph(xbm, &frame, i, i + vh) == NULL) {
|
||||
i = 0;
|
||||
return i;
|
||||
}
|
||||
xbm2fb(&frame, fb, col, row);
|
||||
|
||||
return ++i;
|
||||
}
|
||||
|
||||
static int scroll_pt_next(xbm_t *xbm, int vh, int pt,
|
||||
uint16_t *fb, int col, int row)
|
||||
{
|
||||
static int i;
|
||||
xbm_t frame;
|
||||
|
||||
if (i >= pt) {
|
||||
i = 0;
|
||||
return i;
|
||||
}
|
||||
if (xbm_croph(xbm, &frame, 0, i + (vh -pt)) == NULL) {
|
||||
i = 0;
|
||||
return i;
|
||||
}
|
||||
xbm2fb(&frame, fb, col, row +pt -i);
|
||||
|
||||
return ++i;
|
||||
}
|
||||
|
||||
static int scroll_pb_next( xbm_t *xbm, int vh, int pb,
|
||||
uint16_t *fb, int col, int row)
|
||||
{
|
||||
static int i;
|
||||
xbm_t frame;
|
||||
|
||||
if (i >= pb) {
|
||||
i = 0;
|
||||
return i;
|
||||
}
|
||||
if (xbm_croph(xbm, &frame, xbm->h - (vh -1 -i), xbm->h) == NULL) {
|
||||
i = 0;
|
||||
return i;
|
||||
}
|
||||
xbm2fb(&frame, fb, col, row);
|
||||
|
||||
return ++i;
|
||||
}
|
||||
|
||||
int ani_xbm_scrollup_pad( xbm_t *xbm, int vh, int pt, int pb,
|
||||
uint16_t *fb, int col, int row)
|
||||
{
|
||||
static int i;
|
||||
|
||||
if (i == 0)
|
||||
i = 1;
|
||||
if (i == 1 && scroll_pt_next(xbm, vh, pt, fb, col, row) == 0) {
|
||||
i = 2;
|
||||
}
|
||||
if (i == 2 && ani_xbm_scroll_up(xbm, vh, fb, col, row) == 0) {
|
||||
i = 3;
|
||||
}
|
||||
if (i == 3 && scroll_pb_next(xbm, vh, pb, fb, col, row) == 0) {
|
||||
i = 0;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
/**
|
||||
* Infinite scroll up
|
||||
*/
|
||||
int ani_xbm_scrollup_inf(xbm_t *xbm, uint16_t *fb,
|
||||
int vh, int col, int row)
|
||||
{
|
||||
static int i, r;
|
||||
|
||||
xbm_t frame, frame_circle;
|
||||
if (xbm_croph(xbm, &frame, i, i +vh) == NULL) {
|
||||
|
||||
xbm_croph(xbm, &frame, i +r, i -1 +vh);
|
||||
xbm_croph(xbm, &frame_circle, 0, r);
|
||||
|
||||
xbm2fb(&frame, fb, col, row);
|
||||
xbm2fb_dirty(&frame_circle, fb, col, row +vh -r);
|
||||
|
||||
r++;
|
||||
if (r >= vh) {
|
||||
i = 0;
|
||||
r = 0;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
xbm2fb(&frame, fb, col, row);
|
||||
|
||||
return ++i;
|
||||
}
|
||||
|
||||
void ani_scroll_x(bm_t *bm, uint16_t *fb, int dir)
|
||||
{
|
||||
int x = mod(bm->anim_step, bm->width + LED_COLS) - LED_COLS;
|
||||
bm->anim_step += (dir) ? -1 : 1;
|
||||
|
||||
for (int i = 0; i < LED_COLS; i++) {
|
||||
if (i + x >= bm->width) {
|
||||
fb[i] = 0;
|
||||
continue;
|
||||
}
|
||||
fb[i] = (i + x) >= 0 ? bm->buf[i + x] : 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ani_scroll_left(bm_t *bm, uint16_t *fb)
|
||||
{
|
||||
ani_scroll_x(bm, fb, 0);
|
||||
}
|
||||
|
||||
void ani_scroll_right(bm_t *bm, uint16_t *fb)
|
||||
{
|
||||
ani_scroll_x(bm, fb, 1);
|
||||
}
|
||||
|
||||
void ani_shift_y(bm_t *bm, uint16_t *fb, int y, int frame)
|
||||
{
|
||||
frame *= LED_COLS;
|
||||
|
||||
int size = MIN(LED_COLS, bm->width);
|
||||
int i = 0;
|
||||
for (; i < size; i++) {
|
||||
if ((frame + i) >= bm->width)
|
||||
break;
|
||||
fb[i] = SIGNED_SHIFT(bm->buf[frame + i], y);
|
||||
}
|
||||
for (; i < LED_COLS; i++)
|
||||
fb[i] = 0;
|
||||
}
|
||||
|
||||
void ani_scroll_y(bm_t *bm, uint16_t *fb)
|
||||
{
|
||||
int frame_steps = LED_ROWS * 3; // in-still-out
|
||||
int frames = ALIGN(bm->width, LED_COLS) / LED_COLS;
|
||||
int frame = mod(bm->anim_step, frame_steps*frames)/frame_steps;
|
||||
|
||||
int y = mod(bm->anim_step, frame_steps);
|
||||
|
||||
if (y < LED_ROWS) { // Scrolling up (in)
|
||||
ani_shift_y(bm, fb, y - LED_ROWS, frame);
|
||||
} else if (y < LED_ROWS * 2) { // Stay still
|
||||
ani_shift_y(bm, fb, 0, frame);
|
||||
} else { // Scrolling up (out)
|
||||
ani_shift_y(bm, fb, y - LED_ROWS * 2, frame);
|
||||
}
|
||||
}
|
||||
|
||||
void ani_scroll_up(bm_t *bm, uint16_t *fb)
|
||||
{
|
||||
ani_scroll_y(bm, fb);
|
||||
bm->anim_step++;
|
||||
}
|
||||
|
||||
void ani_scroll_down(bm_t *bm, uint16_t *fb)
|
||||
{
|
||||
ani_scroll_y(bm, fb);
|
||||
bm->anim_step--;
|
||||
}
|
||||
|
||||
static void laser_in(bm_t *bm, uint16_t *fb, int step, int frame)
|
||||
{
|
||||
int c = mod(step, LED_COLS);
|
||||
frame *= LED_COLS;
|
||||
|
||||
int i = 0;
|
||||
for (; i < c; i++) {
|
||||
fb[i] = (frame + i < bm->width) ? bm->buf[frame + i] : 0;
|
||||
}
|
||||
for (; i < MIN(LED_COLS, bm->width - frame); i++) {
|
||||
fb[i] = bm->buf[frame + c];
|
||||
}
|
||||
for (; i < LED_COLS; i++) {
|
||||
fb[i] = (frame + c < bm->width) ? bm->buf[frame + c] : 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void laser_out(bm_t *bm, uint16_t *fb, int step, int frame)
|
||||
{
|
||||
int c = mod(step, LED_COLS);
|
||||
frame *= LED_COLS;
|
||||
|
||||
int i = 0;
|
||||
for (; i < c; i++) {
|
||||
fb[i] = (frame + c < bm->width) ? bm->buf[frame + c] : 0;
|
||||
}
|
||||
for (; i < MIN(LED_COLS, bm->width - frame); i++) {
|
||||
fb[i] = bm->buf[frame + i];
|
||||
}
|
||||
for (; i < LED_COLS; i++) {
|
||||
fb[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void still(bm_t *bm, uint16_t *fb, int frame)
|
||||
{
|
||||
int i = frame * LED_COLS;
|
||||
int j = 0;
|
||||
for (; j < LED_COLS; j++) {
|
||||
if (i >= bm->width)
|
||||
break;
|
||||
fb[j] = bm->buf[i];
|
||||
i++;
|
||||
}
|
||||
for (; j< LED_COLS; j++) {
|
||||
fb[j] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ani_laser(bm_t *bm, uint16_t *fb)
|
||||
{
|
||||
int frame_steps = LED_COLS * 3; // in-still-out
|
||||
int frames = ALIGN(bm->width, LED_COLS) / LED_COLS;
|
||||
int frame = mod(bm->anim_step, frame_steps*frames)/frame_steps;
|
||||
|
||||
int c = mod(bm->anim_step, frame_steps);
|
||||
bm->anim_step++;
|
||||
|
||||
if (c < LED_COLS)
|
||||
laser_in(bm, fb, c - LED_COLS, frame);
|
||||
else if (c < LED_COLS * 2)
|
||||
still(bm, fb, frame);
|
||||
else
|
||||
laser_out(bm, fb, c - LED_COLS * 2, frame);
|
||||
}
|
||||
|
||||
static uint32_t b16dialate(uint16_t w, int from, int to)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
int i = 0, j = from;
|
||||
for (; i < from; i++) {
|
||||
ret |= (w & (1 << i));
|
||||
}
|
||||
for (; i < to; i++, j += 2) {
|
||||
ret |= ((w & (1 << i)) >> i) << j;
|
||||
}
|
||||
for (; i < 16; i++, j++) {
|
||||
ret |= ((w & (1 << i)) >> i) << j;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void snowflake_in(bm_t *bm, uint16_t *fb, int step, int frame)
|
||||
{
|
||||
int y = mod(step, LED_ROWS*2) - LED_ROWS;
|
||||
frame *= LED_COLS;
|
||||
|
||||
int size = MIN(LED_COLS, bm->width - frame);
|
||||
int i = 0;
|
||||
for (; i < size; i++) {
|
||||
if (y < 0) {
|
||||
fb[i] = SIGNED_SHIFT(b16dialate(bm->buf[frame + i], 0, LED_ROWS),
|
||||
LED_ROWS - y);
|
||||
} else
|
||||
fb[i] = SIGNED_SHIFT(b16dialate(bm->buf[frame + i], 0, LED_ROWS - y),
|
||||
(LED_ROWS - y));
|
||||
}
|
||||
for (; i < LED_COLS; i++) {
|
||||
fb[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void snowflake_out(bm_t *bm, uint16_t *fb, int step, int frame)
|
||||
{
|
||||
int y = mod(step, LED_ROWS*2) - LED_ROWS;
|
||||
frame *= LED_COLS;
|
||||
|
||||
int size = MIN(LED_COLS, bm->width - frame);
|
||||
int i = 0;
|
||||
for (; i < size; i++) {
|
||||
if (y <= 0) {
|
||||
fb[i] = SIGNED_SHIFT(b16dialate(bm->buf[frame + i], 0, LED_ROWS),
|
||||
y);
|
||||
} else {
|
||||
fb[i] = b16dialate(bm->buf[frame + i], y, LED_ROWS);
|
||||
}
|
||||
}
|
||||
for (; i < LED_COLS; i++) {
|
||||
fb[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ani_snowflake(bm_t *bm, uint16_t *fb)
|
||||
{
|
||||
int frame_steps = LED_ROWS * 6; // in-still-out, each costs 2xLED_ROWS step
|
||||
int frames = ALIGN(bm->width, LED_COLS) / LED_COLS;
|
||||
int frame = mod(bm->anim_step, frame_steps*frames)/frame_steps;
|
||||
|
||||
int c = mod(bm->anim_step, frame_steps);
|
||||
bm->anim_step++;
|
||||
|
||||
if (c < LED_ROWS * 2) {
|
||||
snowflake_in(bm, fb, c - LED_ROWS * 2, frame);
|
||||
} else if (c <= LED_ROWS * 4) {
|
||||
still(bm, fb, frame);
|
||||
} else {
|
||||
snowflake_out(bm, fb, -(c - LED_ROWS * 4), frame);
|
||||
}
|
||||
}
|
||||
|
||||
void ani_animation(bm_t *bm, uint16_t *fb)
|
||||
{
|
||||
int frame_steps = ANI_ANIMATION_STEPS;
|
||||
int frames = ALIGN(bm->width, LED_COLS) / LED_COLS;
|
||||
int frame = mod(bm->anim_step, frame_steps*frames)/frame_steps;
|
||||
|
||||
bm->anim_step++;
|
||||
|
||||
still(bm, fb, frame);
|
||||
}
|
||||
|
||||
void ani_fixed(bm_t *bm, uint16_t *fb)
|
||||
{
|
||||
int frame_steps = ANI_FIXED_STEPS;
|
||||
int frames = ALIGN(bm->width, LED_COLS) / LED_COLS;
|
||||
int frame = mod(bm->anim_step, frame_steps*frames)/frame_steps;
|
||||
|
||||
bm->anim_step++;
|
||||
still(bm, fb, frame);
|
||||
}
|
||||
|
||||
static void picture(bm_t *bm, uint16_t *fb, int step, int frame)
|
||||
{
|
||||
int hc = LED_COLS / 2;
|
||||
int range = mod(step - 1, LED_COLS);
|
||||
|
||||
if (range > LED_COLS/2) {
|
||||
still(bm, fb, frame);
|
||||
return;
|
||||
}
|
||||
|
||||
frame *= LED_COLS;
|
||||
int i = 0;
|
||||
for (; i <= range; i++) {
|
||||
fb[hc + i - 1] = (hc + i - 1 + frame >= bm->width) ?
|
||||
0 : bm->buf[hc + i - 1 + frame];
|
||||
fb[hc - i] = (hc - i + frame >= bm->width) ?
|
||||
0 : bm->buf[hc - i + frame];
|
||||
}
|
||||
|
||||
if (i >= LED_COLS)
|
||||
return;
|
||||
fb[hc + i - 1] = -1;
|
||||
fb[hc - i] = -1;
|
||||
|
||||
for (i++; i< LED_COLS; i++) {
|
||||
fb[hc + i - 1] = 0;
|
||||
fb[hc - i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void picture_out(bm_t *bm, uint16_t *fb, int step)
|
||||
{
|
||||
int hc = LED_COLS / 2;
|
||||
|
||||
if (step > hc)
|
||||
return;
|
||||
|
||||
int range = step;
|
||||
int i = 0;
|
||||
for (; i <= range; i++) {
|
||||
fb[hc + i - 1] = 0;
|
||||
fb[hc - i] = 0;
|
||||
}
|
||||
if (i >= LED_COLS)
|
||||
return;
|
||||
fb[hc + i - 1] = -1;
|
||||
fb[hc - i] = -1;
|
||||
}
|
||||
|
||||
void ani_picture(bm_t *bm, uint16_t *fb)
|
||||
{
|
||||
int last_steps = LED_COLS / 2;
|
||||
int frame_steps = LED_COLS;
|
||||
int frames = ALIGN(bm->width, LED_COLS) / LED_COLS + 1;
|
||||
int frame = mod(bm->anim_step, frame_steps*frames)/frame_steps;
|
||||
bm->anim_step++;
|
||||
|
||||
if (frame == frames - 1) {
|
||||
picture_out(bm, fb, mod(bm->anim_step, LED_COLS) );
|
||||
|
||||
/* picture_out() costs only half LED_COLS */
|
||||
if (mod(bm->anim_step, LED_COLS) >= last_steps) {
|
||||
bm->anim_step = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
picture(bm, fb, bm->anim_step, frame);
|
||||
}
|
||||
|
||||
void ani_marque(bm_t *bm, uint16_t *fb, int step)
|
||||
{
|
||||
int tpl = 0b000100010001;
|
||||
|
||||
int i;
|
||||
for (i = 0 ; i < LED_COLS - 1; i++) {
|
||||
fb[i] = fb[i] & ~((1 << (LED_ROWS - 1)) | 1);
|
||||
|
||||
fb[i] |= !!(tpl & (1 << ((step + i) % 4)) );
|
||||
fb[i] |= !!(tpl & (1 << mod(-step + i - 2, 4))) << (LED_ROWS - 1);
|
||||
}
|
||||
|
||||
fb[0] = tpl << (step % 4);
|
||||
fb[LED_COLS - 1] = tpl >> ((step + 3) % 4);
|
||||
|
||||
}
|
||||
|
||||
void ani_flash(bm_t *bm, uint16_t *fb, int step)
|
||||
{
|
||||
if (!(step % 2))
|
||||
fb_fill(fb, 0);
|
||||
}
|
||||
34
src/animation.h
Normal file
34
src/animation.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#ifndef __ANIMATION_H__
|
||||
#define __ANIMATION_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "xbm.h"
|
||||
|
||||
int ani_xbm_next_frame(xbm_t *xbm, uint16_t *fb, int col, int row);
|
||||
int ani_xbm_scroll_up(xbm_t *xbm, int vh, uint16_t *fb, int col, int row);
|
||||
int ani_xbm_scrollup_pad( xbm_t *xbm, int vh, int pt, int pb,
|
||||
uint16_t *fb, int col, int row);
|
||||
int ani_xbm_scrollup_inf(xbm_t *xbm, uint16_t *fb,
|
||||
int vh, int col, int row);
|
||||
|
||||
void fb_fill(uint16_t *fb, uint16_t v);
|
||||
void ani_shift_y(bm_t *bm, uint16_t *fb, int dir, int frame);
|
||||
|
||||
void ani_scroll_x(bm_t *bm, uint16_t *fb, int dir);
|
||||
void ani_scroll_y(bm_t *bm, uint16_t *fb);
|
||||
|
||||
void ani_scroll_left(bm_t *bm, uint16_t *fb);
|
||||
void ani_scroll_right(bm_t *bm, uint16_t *fb);
|
||||
void ani_scroll_up(bm_t *bm, uint16_t *fb);
|
||||
void ani_scroll_down(bm_t *bm, uint16_t *fb);
|
||||
void ani_fixed(bm_t *bm, uint16_t *fb);
|
||||
void ani_laser(bm_t *bm, uint16_t *fb);
|
||||
void ani_snowflake(bm_t *bm, uint16_t *fb);
|
||||
void ani_animation(bm_t *bm, uint16_t *fb);
|
||||
void ani_picture(bm_t *bm, uint16_t *fb);
|
||||
|
||||
void ani_marque(bm_t *bm, uint16_t *fb, int step);
|
||||
void ani_flash(bm_t *bm, uint16_t *fb, int step);
|
||||
|
||||
#endif /* __ANIMATION_H__ */
|
||||
@@ -198,16 +198,26 @@ static uint16 peripheral_task(uint8 task_id, uint16 events)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ble_enable_advertise()
|
||||
{
|
||||
uint8 e = TRUE;
|
||||
GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8), &e);
|
||||
}
|
||||
|
||||
void ble_disable_advertise()
|
||||
{
|
||||
uint8 e = FALSE;
|
||||
GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8), &e);
|
||||
}
|
||||
|
||||
static void gap_init()
|
||||
{
|
||||
GAPRole_PeripheralInit();
|
||||
|
||||
static uint8 initial_advertising_enable = TRUE;
|
||||
static uint16 desired_min_interval = 6;
|
||||
static uint16 desired_max_interval = 500;
|
||||
|
||||
// Set the GAP Role Parameters
|
||||
GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8), &initial_advertising_enable);
|
||||
GAPRole_SetParameter(GAPROLE_SCAN_RSP_DATA, sizeof(scanRspData), scanRspData);
|
||||
GAPRole_SetParameter(GAPROLE_ADVERT_DATA, sizeof(advertData), advertData);
|
||||
GAPRole_SetParameter(GAPROLE_MIN_CONN_INTERVAL, sizeof(uint16), &desired_min_interval);
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
#ifndef __HAL_H__
|
||||
#define __HAL_H__
|
||||
#ifndef __BLE_SETUP_H__
|
||||
#define __BLE_SETUP_H__
|
||||
|
||||
void tmos_clockInit(void);
|
||||
void ble_hardwareInit(void);
|
||||
void peripheral_init(void);
|
||||
|
||||
#endif /* __HAL_H__ */
|
||||
void ble_enable_advertise();
|
||||
void ble_disable_advertise();
|
||||
|
||||
#endif /* __BLE_SETUP_H__ */
|
||||
|
||||
85
src/bmlist.c
Normal file
85
src/bmlist.c
Normal file
@@ -0,0 +1,85 @@
|
||||
#include "bmlist.h"
|
||||
#include <memory.h>
|
||||
|
||||
volatile static bm_t *current, *head, *tail;
|
||||
|
||||
static void bm_add(bm_t *new, bm_t *prev, bm_t *next)
|
||||
{
|
||||
next->prev = new;
|
||||
new->next = next;
|
||||
new->prev = prev;
|
||||
prev->next = new;
|
||||
}
|
||||
|
||||
bm_t *bmlist_insert(bm_t *at, bm_t *new)
|
||||
{
|
||||
bm_add(new, at, at->next);
|
||||
return new;
|
||||
}
|
||||
|
||||
bm_t *bmlist_append(bm_t *new)
|
||||
{
|
||||
bmlist_insert(tail, new);
|
||||
tail = new;
|
||||
return new;
|
||||
}
|
||||
|
||||
bm_t *bmlist_gonext()
|
||||
{
|
||||
current = current->next;
|
||||
current->anim_step = 0;
|
||||
return current;
|
||||
}
|
||||
|
||||
bm_t *bmlist_goprev()
|
||||
{
|
||||
current = current->prev;
|
||||
current->anim_step = 0;
|
||||
return current;
|
||||
}
|
||||
|
||||
bm_t *bmlist_gohead()
|
||||
{
|
||||
current = head;
|
||||
current->anim_step = 0;
|
||||
return current;
|
||||
}
|
||||
|
||||
bm_t *bmlist_current()
|
||||
{
|
||||
return current;
|
||||
}
|
||||
|
||||
static void list_del(bm_t *prev, bm_t *next)
|
||||
{
|
||||
prev->next = next;
|
||||
next->prev = prev;
|
||||
}
|
||||
|
||||
bm_t *bmlist_drop(bm_t *bm)
|
||||
{
|
||||
list_del(bm->prev, bm->next);
|
||||
return bm->next;
|
||||
}
|
||||
|
||||
bm_t *bm_new(uint16_t width)
|
||||
{
|
||||
bm_t *bm = malloc(sizeof(bm_t));
|
||||
memset(bm, 0, sizeof(bm_t));
|
||||
|
||||
bm->width = width;
|
||||
bm->buf = malloc(width * sizeof(uint16_t));
|
||||
memset(bm->buf, 0, width * sizeof(uint16_t));
|
||||
|
||||
bm->next = bm;
|
||||
bm->prev = bm;
|
||||
|
||||
return bm;
|
||||
}
|
||||
|
||||
void bmlist_init(uint16_t first_bm_width)
|
||||
{
|
||||
current = bm_new(first_bm_width);
|
||||
head = current;
|
||||
tail = current;
|
||||
}
|
||||
41
src/bmlist.h
Normal file
41
src/bmlist.h
Normal file
@@ -0,0 +1,41 @@
|
||||
#ifndef __BMLIST_H__
|
||||
#define __BMLIST_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct bm_st {
|
||||
uint16_t *buf;
|
||||
uint16_t width;
|
||||
uint8_t modes;
|
||||
int is_flash;
|
||||
int is_marquee;
|
||||
// TODO: feat: Brightness for each bm
|
||||
int brightness;
|
||||
// TODO: feat: Timeout for each bm to switch to next bm
|
||||
uint32_t timeout; // zero mean no timeout
|
||||
uint32_t anim_step; // Animation step, zero means restart animation
|
||||
|
||||
struct bm_st *next;
|
||||
struct bm_st *prev;
|
||||
} bm_t;
|
||||
|
||||
bm_t *bm_new(uint16_t width);
|
||||
static inline void bm_free(bm_t *bm)
|
||||
{
|
||||
free(bm->buf);
|
||||
free(bm);
|
||||
}
|
||||
|
||||
bm_t *bmlist_insert(bm_t *at, bm_t *new);
|
||||
bm_t *bmlist_append(bm_t *new);
|
||||
bm_t *bmlist_drop(bm_t *bm);
|
||||
|
||||
bm_t *bmlist_gonext();
|
||||
bm_t *bmlist_goprev() ;
|
||||
bm_t *bmlist_gohead();
|
||||
bm_t *bmlist_current();
|
||||
|
||||
void bmlist_init(uint16_t first_bm_width);
|
||||
|
||||
#endif /* __BMLIST_H__ */
|
||||
54
src/data.c
54
src/data.c
@@ -24,33 +24,47 @@ uint32_t data_flatSave(uint8_t *data, uint32_t len)
|
||||
return EEPROM_WRITE(0, data, len);
|
||||
}
|
||||
|
||||
data_legacy_t *data_get_header(int read_anyway)
|
||||
{
|
||||
static data_legacy_t *cache;
|
||||
|
||||
if (cache == NULL) {
|
||||
cache = malloc(sizeof(data_legacy_t));
|
||||
read_anyway = 1;
|
||||
}
|
||||
|
||||
if (read_anyway) {
|
||||
EEPROM_READ(0, cache, LEGACY_HEADER_SIZE);
|
||||
}
|
||||
return cache;
|
||||
}
|
||||
|
||||
uint16_t data_flash2newmem(uint8_t **chunk, uint32_t n)
|
||||
{
|
||||
data_legacy_t header;
|
||||
EEPROM_READ(0, &header, LEGACY_HEADER_SIZE);
|
||||
data_legacy_t *header = data_get_header(0);
|
||||
|
||||
uint16_t size = bswap16(header.sizes[n]) * LED_ROWS;
|
||||
uint16_t size = bswap16(header->sizes[n]) * LED_ROWS;
|
||||
if (size == 0)
|
||||
return 0;
|
||||
|
||||
uint16_t offs = LEGACY_HEADER_SIZE
|
||||
+ bigendian16_sum(header.sizes, n) * LED_ROWS;
|
||||
+ bigendian16_sum(header->sizes, n) * LED_ROWS;
|
||||
|
||||
*chunk = malloc(size);
|
||||
EEPROM_READ(offs, *chunk, size);
|
||||
return size;
|
||||
}
|
||||
|
||||
static void __chunk2buffer(uint16_t *fb, uint8_t *chunk, int col)
|
||||
static void __chunk2buffer(uint16_t *bm, uint8_t *chunk, int col)
|
||||
{
|
||||
uint16_t tmpfb[8] = {0};
|
||||
uint16_t tmpbm[8] = {0};
|
||||
for (int i=0; i<8; i++) {
|
||||
for (int j=0; j<11; j++) {
|
||||
tmpfb[i] |= ((chunk[j] >> (7-i)) & 0x01) << j;
|
||||
tmpbm[i] |= ((chunk[j] >> (7-i)) & 0x01) << j;
|
||||
}
|
||||
}
|
||||
for (int i=0; i<8; i++) {
|
||||
fb[col+i] = tmpfb[i];
|
||||
bm[col+i] = tmpbm[i];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,24 +75,32 @@ void chunk2buffer(uint8_t *chunk, uint16_t size, uint16_t *buf)
|
||||
}
|
||||
}
|
||||
|
||||
void chunk2fb(uint8_t *chunk, uint16_t size, fb_t *fb)
|
||||
void chunk2bm(uint8_t *chunk, uint16_t size, bm_t *bm)
|
||||
{
|
||||
chunk2buffer(chunk, size, fb->buf);
|
||||
chunk2buffer(chunk, size, bm->buf);
|
||||
}
|
||||
|
||||
fb_t *chunk2newfb(uint8_t *chunk, uint16_t size)
|
||||
bm_t *chunk2newbm(uint8_t *chunk, uint16_t size)
|
||||
{
|
||||
fb_t *fb = fb_new((size*8)/11);
|
||||
chunk2fb(chunk, size, fb);
|
||||
return fb;
|
||||
bm_t *bm = bm_new((size*8)/11);
|
||||
chunk2bm(chunk, size, bm);
|
||||
return bm;
|
||||
}
|
||||
|
||||
fb_t *flash2newfb(uint32_t n)
|
||||
bm_t *flash2newbm(uint32_t n)
|
||||
{
|
||||
uint8_t *buf;
|
||||
uint16_t size = data_flash2newmem(&buf, n);
|
||||
if (size == 0)
|
||||
return NULL;
|
||||
return chunk2newfb(buf, size);
|
||||
|
||||
bm_t *bm = chunk2newbm(buf, size);
|
||||
data_legacy_t *header = data_get_header(0);
|
||||
|
||||
bm->is_flash = (header->flash & (1 << n)) != 0;
|
||||
bm->is_marquee = (header->marquee & (1 << n)) != 0;
|
||||
bm->modes = header->modes[n];
|
||||
|
||||
free(buf);
|
||||
return bm;
|
||||
}
|
||||
|
||||
28
src/data.h
28
src/data.h
@@ -3,10 +3,10 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "fb.h"
|
||||
#include "bmlist.h"
|
||||
|
||||
typedef struct {
|
||||
uint8_t header[6];
|
||||
uint8_t header[6]; // magic
|
||||
uint8_t flash;
|
||||
uint8_t marquee;
|
||||
uint8_t modes[8];
|
||||
@@ -24,6 +24,20 @@ typedef struct {
|
||||
|
||||
#define LEGACY_TRANSFER_WIDTH (16)
|
||||
#define LEGACY_HEADER_SIZE (sizeof(data_legacy_t) - sizeof(uint8_t *))
|
||||
#define LEGACY_GET_SPEED(mode) ((mode) >> 4)
|
||||
#define LEGACY_GET_ANIMATION(mode) ((mode) & 0x0F)
|
||||
|
||||
enum ANIMATION_MODES {
|
||||
LEFT = 0,
|
||||
RIGHT,
|
||||
UP,
|
||||
DOWN,
|
||||
FIXED,
|
||||
ANIMATION,
|
||||
SNOWFLAKE,
|
||||
PICTURE,
|
||||
LASER,
|
||||
};
|
||||
|
||||
static inline uint16_t bswap16(uint16_t i) {
|
||||
return (i >> 8) | (i << 8);
|
||||
@@ -33,10 +47,12 @@ uint32_t bigendian16_sum(uint16_t *s, int len);
|
||||
uint32_t data_flatSave(uint8_t *data, uint32_t len);
|
||||
uint16_t data_flash2newmem(uint8_t **chunk, uint32_t n);
|
||||
|
||||
void chunk2buffer(uint8_t *chunk, uint16_t size, uint16_t *buf);
|
||||
void chunk2fb(uint8_t *chunk, uint16_t size, fb_t *fb);
|
||||
data_legacy_t *data_get_header(int read_anyway);
|
||||
|
||||
fb_t *chunk2newfb(uint8_t *chunk, uint16_t size);
|
||||
fb_t *flash2newfb(uint32_t n);
|
||||
void chunk2buffer(uint8_t *chunk, uint16_t size, uint16_t *buf);
|
||||
void chunk2bm(uint8_t *chunk, uint16_t size, bm_t *bm);
|
||||
|
||||
bm_t *chunk2newbm(uint8_t *chunk, uint16_t size);
|
||||
bm_t *flash2newbm(uint32_t n);
|
||||
|
||||
#endif /* __DATA_H__ */
|
||||
|
||||
87
src/fb.c
87
src/fb.c
@@ -1,87 +0,0 @@
|
||||
#include "fb.h"
|
||||
#include <memory.h>
|
||||
|
||||
volatile static fb_t *current, *head, *tail;
|
||||
|
||||
static void fb_add(fb_t *new, fb_t *prev, fb_t *next)
|
||||
{
|
||||
next->prev = new;
|
||||
new->next = next;
|
||||
new->prev = prev;
|
||||
prev->next = new;
|
||||
}
|
||||
|
||||
fb_t *fblist_insert(fb_t *at, fb_t *new)
|
||||
{
|
||||
fb_add(new, at, at->next);
|
||||
return new;
|
||||
}
|
||||
|
||||
fb_t *fblist_append(fb_t *new)
|
||||
{
|
||||
fblist_insert(tail, new);
|
||||
tail = new;
|
||||
return new;
|
||||
}
|
||||
|
||||
fb_t *fblist_gonext()
|
||||
{
|
||||
current = current->next;
|
||||
current->scroll = 0;
|
||||
return current;
|
||||
}
|
||||
|
||||
fb_t *fblist_goprev()
|
||||
{
|
||||
current = current->prev;
|
||||
current->scroll = 0;
|
||||
return current;
|
||||
}
|
||||
|
||||
fb_t *fblist_gohead()
|
||||
{
|
||||
current = head;
|
||||
current->scroll = 0;
|
||||
return current;
|
||||
}
|
||||
|
||||
fb_t *fblist_currentfb()
|
||||
{
|
||||
return current;
|
||||
}
|
||||
|
||||
static void list_del(fb_t *prev, fb_t *next)
|
||||
{
|
||||
prev->next = next;
|
||||
next->prev = prev;
|
||||
}
|
||||
|
||||
fb_t *fblist_drop(fb_t *fb)
|
||||
{
|
||||
list_del(fb->prev, fb->next);
|
||||
return fb->next;
|
||||
}
|
||||
|
||||
fb_t *fb_new(uint16_t width)
|
||||
{
|
||||
fb_t *fb = malloc(sizeof(fb_t));
|
||||
memset(fb, 0, sizeof(fb_t));
|
||||
|
||||
fb->width = width;
|
||||
fb->buf = malloc(width * sizeof(uint16_t));
|
||||
memset(fb->buf, 0, width * sizeof(uint16_t));
|
||||
|
||||
fb->modes = FIXED;
|
||||
|
||||
fb->next = fb;
|
||||
fb->prev = fb;
|
||||
|
||||
return fb;
|
||||
}
|
||||
|
||||
void fblist_init(uint16_t first_fb_width)
|
||||
{
|
||||
current = fb_new(first_fb_width);
|
||||
head = current;
|
||||
tail = current;
|
||||
}
|
||||
53
src/fb.h
53
src/fb.h
@@ -1,53 +0,0 @@
|
||||
#ifndef __FB_H__
|
||||
#define __FB_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
enum ANIMATION_MODES {
|
||||
LEFT = 0,
|
||||
RIGHT,
|
||||
UP,
|
||||
DOWN,
|
||||
FIXED,
|
||||
SNOWFLAKE,
|
||||
PICTURE,
|
||||
ANIMATION,
|
||||
LASER,
|
||||
};
|
||||
|
||||
typedef struct fb_st {
|
||||
uint16_t *buf;
|
||||
uint16_t width;
|
||||
uint8_t modes;
|
||||
int is_flash;
|
||||
int is_marquee;
|
||||
// TODO: feat: Brightness for each fb
|
||||
int brightness;
|
||||
// TODO: feat: Timeout for each fb to switch to next fb
|
||||
uint32_t timeout; // zero mean no timeout
|
||||
uint16_t scroll;
|
||||
|
||||
struct fb_st *next;
|
||||
struct fb_st *prev;
|
||||
} fb_t;
|
||||
|
||||
fb_t *fb_new(uint16_t width);
|
||||
static inline void fb_free(fb_t *fb)
|
||||
{
|
||||
free((fb)->buf);
|
||||
free((fb));
|
||||
}
|
||||
|
||||
fb_t *fblist_insert(fb_t *at, fb_t *new);
|
||||
fb_t *fblist_append(fb_t *new);
|
||||
fb_t *fblist_drop(fb_t *fb);
|
||||
|
||||
fb_t *fblist_gonext();
|
||||
fb_t *fblist_goprev() ;
|
||||
fb_t *fblist_gohead();
|
||||
fb_t *fblist_currentfb();
|
||||
|
||||
void fblist_init(uint16_t first_fb_width);
|
||||
|
||||
#endif /* __FB_H__ */
|
||||
206
src/main.c
206
src/main.c
@@ -1,9 +1,13 @@
|
||||
#include "CH58x_common.h"
|
||||
#include "CH58x_sys.h"
|
||||
#include "CH58xBLE_LIB.h"
|
||||
|
||||
#include "leddrv.h"
|
||||
#include "button.h"
|
||||
#include "fb.h"
|
||||
#include "bmlist.h"
|
||||
#include "resource.h"
|
||||
#include "animation.h"
|
||||
|
||||
#include "power.h"
|
||||
#include "data.h"
|
||||
|
||||
@@ -12,8 +16,6 @@
|
||||
|
||||
#include "usb/usb.h"
|
||||
|
||||
#define FB_WIDTH (LED_COLS * 4)
|
||||
#define SCROLL_IRATIO (16)
|
||||
#define SCAN_F (2000)
|
||||
#define SCAN_T (FREQ_SYS / SCAN_F)
|
||||
|
||||
@@ -28,9 +30,27 @@ enum MODES {
|
||||
POWER_OFF,
|
||||
MODES_COUNT,
|
||||
};
|
||||
|
||||
#define BRIGHTNESS_LEVELS (4)
|
||||
|
||||
volatile int mode, brightness;
|
||||
#define ANI_BASE_SPEED_T (200000) // uS
|
||||
#define ANI_MARQUE_SPEED_T (100000) // uS
|
||||
#define ANI_FLASH_SPEED_T (500000) // uS
|
||||
#define SCAN_BOOTLD_BTN_SPEED_T (200000) // uS
|
||||
#define ANI_SPEED_STRATEGY(speed_level) \
|
||||
(ANI_BASE_SPEED_T - ((speed_level) \
|
||||
* ANI_BASE_SPEED_T / 8))
|
||||
|
||||
#define ANI_NEXT_STEP (1 << 0)
|
||||
#define ANI_MARQUE (1 << 1)
|
||||
#define ANI_FLASH (1 << 2)
|
||||
#define SCAN_BOOTLD_BTN (1 << 3)
|
||||
#define BLE_NEXT_STEP (1 << 4)
|
||||
|
||||
static tmosTaskID common_taskid = INVALID_TASK_ID ;
|
||||
|
||||
volatile uint16_t fb[LED_COLS] = {0};
|
||||
volatile int mode, brightness = 0;
|
||||
|
||||
__HIGH_CODE
|
||||
static void change_brightness()
|
||||
@@ -46,26 +66,30 @@ static void change_mode()
|
||||
}
|
||||
|
||||
__HIGH_CODE
|
||||
static void fb_transition()
|
||||
static void bm_transition()
|
||||
{
|
||||
fblist_gonext();
|
||||
bmlist_gonext();
|
||||
}
|
||||
void play_splash(xbm_t *xbm, int col, int row)
|
||||
{
|
||||
while (ani_xbm_scrollup_pad(xbm, 11, 11, 11, fb, 0, 0) != 0) {
|
||||
DelayMs(30);
|
||||
}
|
||||
}
|
||||
|
||||
void draw_testfb()
|
||||
void load_bmlist()
|
||||
{
|
||||
|
||||
fb_t *curr_fb = fblist_currentfb();
|
||||
bm_t *curr_bm = bmlist_current();
|
||||
|
||||
for (int i=0; i<8; i++) {
|
||||
fb_t *fb = flash2newfb(i);
|
||||
if (fb == NULL)
|
||||
bm_t *bm = flash2newbm(i);
|
||||
if (bm == NULL)
|
||||
continue;
|
||||
fb->modes = LEFT;
|
||||
fblist_append(fb);
|
||||
bmlist_append(bm);
|
||||
}
|
||||
fblist_gonext();
|
||||
bmlist_gonext();
|
||||
|
||||
fblist_drop(curr_fb);
|
||||
bmlist_drop(curr_bm);
|
||||
}
|
||||
|
||||
void poweroff()
|
||||
@@ -84,12 +108,98 @@ void poweroff()
|
||||
LowPower_Shutdown(0);
|
||||
}
|
||||
|
||||
void ble_start()
|
||||
static uint16_t common_tasks(tmosTaskID task_id, uint16_t events)
|
||||
{
|
||||
static int marque_step, flash_step;
|
||||
|
||||
if(events & SYS_EVENT_MSG) {
|
||||
uint8 *pMsg = tmos_msg_receive(common_taskid);
|
||||
if(pMsg != NULL)
|
||||
{
|
||||
tmos_msg_deallocate(pMsg);
|
||||
}
|
||||
return (events ^ SYS_EVENT_MSG);
|
||||
}
|
||||
|
||||
if(events & ANI_NEXT_STEP) {
|
||||
|
||||
static void (*animations[])(bm_t *bm, uint16_t *fb) = {
|
||||
ani_scroll_left,
|
||||
ani_scroll_right,
|
||||
ani_scroll_up,
|
||||
ani_scroll_down,
|
||||
ani_fixed,
|
||||
ani_animation,
|
||||
ani_snowflake,
|
||||
ani_picture,
|
||||
ani_laser
|
||||
};
|
||||
|
||||
bm_t *bm = bmlist_current();
|
||||
if (animations[LEGACY_GET_ANIMATION(bm->modes)])
|
||||
animations[LEGACY_GET_ANIMATION(bm->modes)](bm, fb);
|
||||
|
||||
if (bm->is_flash) {
|
||||
ani_flash(bm, fb, flash_step);
|
||||
}
|
||||
if (bm->is_marquee) {
|
||||
ani_marque(bm, fb, marque_step);
|
||||
}
|
||||
|
||||
uint32_t t = ANI_SPEED_STRATEGY(LEGACY_GET_SPEED(bm->modes));
|
||||
tmos_start_task(common_taskid, ANI_NEXT_STEP, t / 625);
|
||||
|
||||
return events ^ ANI_NEXT_STEP;
|
||||
}
|
||||
|
||||
if (events & ANI_MARQUE) {
|
||||
bm_t *bm = bmlist_current();
|
||||
marque_step++;
|
||||
if (bm->is_marquee) {
|
||||
ani_marque(bm, fb, marque_step);
|
||||
}
|
||||
|
||||
return events ^ ANI_MARQUE;
|
||||
}
|
||||
|
||||
if (events & SCAN_BOOTLD_BTN) {
|
||||
static uint32_t hold;
|
||||
hold = isPressed(KEY2) ? hold + 1 : 0;
|
||||
if (hold > 10) {
|
||||
reset_jump();
|
||||
}
|
||||
|
||||
return events ^ SCAN_BOOTLD_BTN;
|
||||
}
|
||||
|
||||
if (events & ANI_FLASH) {
|
||||
bm_t *bm = bmlist_current();
|
||||
flash_step++;
|
||||
|
||||
if (bm->is_flash) {
|
||||
ani_flash(bm, fb, flash_step);
|
||||
}
|
||||
/* After flash is applied, it will potentialy overwrite the marque
|
||||
effect after it just wrote, results in flickering. So here apply the
|
||||
marque effect again */
|
||||
if (bm->is_marquee) {
|
||||
ani_marque(bm, fb, marque_step);
|
||||
}
|
||||
|
||||
return events ^ ANI_FLASH;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ble_setup()
|
||||
{
|
||||
ble_hardwareInit();
|
||||
tmos_clockInit();
|
||||
|
||||
peripheral_init();
|
||||
ble_disable_advertise();
|
||||
|
||||
devInfo_registerService();
|
||||
legacy_registerService();
|
||||
}
|
||||
@@ -128,6 +238,26 @@ static void usb_receive(uint8_t *buf, uint16_t len)
|
||||
}
|
||||
}
|
||||
|
||||
void spawn_tasks()
|
||||
{
|
||||
common_taskid = TMOS_ProcessEventRegister(common_tasks);
|
||||
|
||||
tmos_start_reload_task(common_taskid, ANI_MARQUE, ANI_MARQUE_SPEED_T / 625);
|
||||
tmos_start_reload_task(common_taskid, ANI_FLASH, ANI_FLASH_SPEED_T / 625);
|
||||
tmos_start_reload_task(common_taskid, SCAN_BOOTLD_BTN,
|
||||
SCAN_BOOTLD_BTN_SPEED_T / 625);
|
||||
tmos_start_task(common_taskid, ANI_NEXT_STEP, 500000 / 625);
|
||||
}
|
||||
|
||||
void ble_start()
|
||||
{
|
||||
ble_enable_advertise();
|
||||
|
||||
tmos_stop_task(common_taskid, ANI_NEXT_STEP);
|
||||
tmos_stop_task(common_taskid, ANI_MARQUE);
|
||||
tmos_stop_task(common_taskid, ANI_FLASH);
|
||||
}
|
||||
|
||||
void handle_mode_transition()
|
||||
{
|
||||
static int prev_mode;
|
||||
@@ -136,10 +266,10 @@ void handle_mode_transition()
|
||||
switch (mode)
|
||||
{
|
||||
case DOWNLOAD:
|
||||
// Disable fb transition while in download mode
|
||||
// Disable bitmap transition while in download mode
|
||||
btn_onOnePress(KEY2, NULL);
|
||||
|
||||
// Take control of the current fb to display
|
||||
// Take control of the current bitmap to display
|
||||
// the Bluetooth animation
|
||||
ble_start();
|
||||
while (mode == DOWNLOAD) {
|
||||
@@ -184,26 +314,24 @@ int main()
|
||||
TMR0_ITCfg(ENABLE, TMR0_3_IT_CYC_END);
|
||||
PFIC_EnableIRQ(TMR0_IRQn);
|
||||
|
||||
fblist_init(FB_WIDTH);
|
||||
bmlist_init(LED_COLS * 4);
|
||||
|
||||
play_splash(&splash, 0, 0);
|
||||
|
||||
draw_testfb();
|
||||
load_bmlist();
|
||||
|
||||
btn_init();
|
||||
btn_onOnePress(KEY1, change_mode);
|
||||
btn_onOnePress(KEY2, fb_transition);
|
||||
btn_onOnePress(KEY2, bm_transition);
|
||||
btn_onLongPress(KEY1, change_brightness);
|
||||
|
||||
while (1) {
|
||||
uint32_t i = 0;
|
||||
while (isPressed(KEY2)) {
|
||||
i++;
|
||||
if (i>10) {
|
||||
reset_jump();
|
||||
}
|
||||
DelayMs(200);
|
||||
}
|
||||
ble_setup();
|
||||
|
||||
spawn_tasks();
|
||||
while (1) {
|
||||
handle_mode_transition();
|
||||
}
|
||||
TMOS_SystemProcess();
|
||||
}
|
||||
}
|
||||
|
||||
__INTERRUPT
|
||||
@@ -213,30 +341,16 @@ void TMR0_IRQHandler(void)
|
||||
static int i;
|
||||
|
||||
if (TMR0_GetITFlag(TMR0_3_IT_CYC_END)) {
|
||||
|
||||
fb_t *fb = fblist_currentfb();
|
||||
i += 1;
|
||||
if (i >= LED_COLS) {
|
||||
i = 0;
|
||||
if ((fb->modes & 0x0f) == LEFT) {
|
||||
fb->scroll++;
|
||||
if (fb->scroll >= (fb->width-LED_COLS)*SCROLL_IRATIO) {
|
||||
fb->scroll = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (i % 2) {
|
||||
if ((brightness + 1) % 2)
|
||||
leds_releaseall();
|
||||
} else {
|
||||
if (i + fb->scroll/SCROLL_IRATIO >= fb->width) {
|
||||
leds_releaseall();
|
||||
return;
|
||||
}
|
||||
led_write2dcol(i/2,
|
||||
fb->buf[i+ fb->scroll/SCROLL_IRATIO],
|
||||
fb->buf[i+ fb->scroll/SCROLL_IRATIO + 1]);
|
||||
led_write2dcol(i/2, fb[i], fb[i + 1]);
|
||||
}
|
||||
|
||||
TMR0_ClearITFlag(TMR0_3_IT_CYC_END);
|
||||
|
||||
Reference in New Issue
Block a user