Skip to content

Commit

Permalink
animation: timing with TMOS scheduler
Browse files Browse the repository at this point in the history
  • Loading branch information
kienvo committed Jul 28, 2024
1 parent 0fb86ee commit 2f98dba
Show file tree
Hide file tree
Showing 5 changed files with 169 additions and 56 deletions.
29 changes: 18 additions & 11 deletions src/animation.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
#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))
Expand Down Expand Up @@ -349,14 +352,23 @@ void ani_snowflake(bm_t *bm, uint16_t *fb)

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 c = mod(bm->anim_step++, frames);
still(bm, fb, c);
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)
{
still(bm, fb, 0);
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)
Expand Down Expand Up @@ -428,11 +440,9 @@ void ani_picture(bm_t *bm, uint16_t *fb)
picture(bm, fb, bm->anim_step, frame);
}

void ani_marque(bm_t *bm, uint16_t *fb)
void ani_marque(bm_t *bm, uint16_t *fb, int step)
{
int tpl = 0b000100010001;
static int step;
step++;

int i;
for (i = 0 ; i < LED_COLS - 1; i++) {
Expand All @@ -447,11 +457,8 @@ void ani_marque(bm_t *bm, uint16_t *fb)

}

void ani_flash_toggle(bm_t *bm, uint16_t *fb)
void ani_flash(bm_t *bm, uint16_t *fb, int step)
{
static int tog;
if (tog) {
if (!(step % 2))
fb_fill(fb, 0);
}
tog = !tog;
}
4 changes: 2 additions & 2 deletions src/animation.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ 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);
void ani_flash_toggle(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__ */
14 changes: 12 additions & 2 deletions src/ble/peripheral.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
9 changes: 6 additions & 3 deletions src/ble/setup.h
Original file line number Diff line number Diff line change
@@ -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__ */
169 changes: 131 additions & 38 deletions src/main.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "CH58x_common.h"
#include "CH58x_sys.h"
#include "CH58xBLE_LIB.h"

#include "leddrv.h"
#include "button.h"
Expand Down Expand Up @@ -27,8 +28,25 @@ enum MODES {
POWER_OFF,
MODES_COUNT,
};

#define BRIGHTNESS_LEVELS (4)

#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;

Expand Down Expand Up @@ -88,16 +106,122 @@ 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();
}

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;
Expand Down Expand Up @@ -149,44 +273,13 @@ int main()
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);
}
handle_mode_transition();

bm_t *bm = bmlist_current();
if ((LEGACY_GET_ANIMATION(bm->modes)) == LEFT) {
ani_scroll_x(bm, fb, 0);
} else if ((LEGACY_GET_ANIMATION(bm->modes)) == RIGHT) {
ani_scroll_x(bm, fb, 1);
} else if ((LEGACY_GET_ANIMATION(bm->modes)) == UP) {
ani_scroll_up(bm, fb);
} else if ((LEGACY_GET_ANIMATION(bm->modes)) == DOWN) {
ani_scroll_down(bm, fb);
} else if ((LEGACY_GET_ANIMATION(bm->modes)) == SNOWFLAKE) {
ani_snowflake(bm, fb);
} else if ((LEGACY_GET_ANIMATION(bm->modes)) == PICTURE) {
ani_picture(bm, fb);
} else if ((LEGACY_GET_ANIMATION(bm->modes)) == ANIMATION) {
ani_animation(bm, fb);
} else if ((LEGACY_GET_ANIMATION(bm->modes)) == LASER) {
ani_laser(bm, fb);
}
ble_setup();

if (bm->is_flash) {
ani_flash_toggle(bm, fb);
}
if (bm->is_marquee) {
ani_marque(bm, fb);
}
DelayMs(300);
}
spawn_tasks();
while (1) {
handle_mode_transition();
TMOS_SystemProcess();
}
}

__INTERRUPT
Expand Down

0 comments on commit 2f98dba

Please sign in to comment.