Skip to content
Permalink
Browse files
Timer driver implemented. Focus screen waits two seconds using interf…
…ace to driver.
  • Loading branch information
cr1901 committed Sep 21, 2014
1 parent a65d0dd commit dbc08e8790a040f5c0a547899d77d3ec7aae3ecf
Show file tree
Hide file tree
Showing 5 changed files with 160 additions and 34 deletions.
@@ -6,23 +6,39 @@

#define MAX_NUM_TIMERS 32

typedef struct timer_observer
{
void (* notify_fcn)(volatile void *);
volatile void * target_data;
}TIMER_OBSERVER;

/* typedef struct timer_subject
{
}TIMER_SUBJECT; */

typedef struct comparator
{
unsigned char ticks_elapsed;
unsigned char ticks_target;
TIMER_OBSERVER notifier;
int in_use;
unsigned short ticks_elapsed;
unsigned short ticks_target;
}COMPARATOR;

typedef enum vb_timer_gran


/* For now, changing the timer granularity is impossible on demand. */
/* typedef enum vb_timer_gran
{
VB_TIMER_20_MICRO,
VB_TIMER_100_MICRO
}VB_TIMER_GRAN;
}VB_TIMER_GRAN; */


void set_physical_timer_granularity(VB_TIMER_GRAN gran);
void set_interrupt_granularity(unsigned short target_ticks);
COMPARATOR * add_timer_to_pool(unsigned char target_ticks);
int remove_timer_from_pool(COMPARATOR *);
/* void set_physical_timer_granularity(VB_TIMER_GRAN gran);
void set_interrupt_granularity(unsigned short target_ticks); */
int set_timer_to_inuse(unsigned short target_ticks, void (*)(volatile void *), volatile void *);
void unset_timer_from_inuse(int index);
void bind_tim_vector();
void init_timer_hw();
void stop_timer_and_int();
@@ -1,10 +1,10 @@
#ifndef TIMER_H
#define TIMER_H
#ifndef TIMERIF_H
#define TIMERIF_H

typedef void * timer_handle_t;
typedef int timer_handle_t;
typedef void * tick_count_t;

timer_handle_t request_timer(short centiseconds);
timer_handle_t request_timer(short centiseconds, void (*)(volatile void *), volatile void *);
int timer_expired(timer_handle_t t_ptr);
timer_handle_t restart_timer(timer_handle_t t_ptr);
void remove_timer(timer_handle_t t_ptr);
@@ -15,5 +15,5 @@ void stop_timer_driver();
short difftick(tick_count_t end, tick_count_t begin); */


#endif /* #ifndef TIMER_H */
#endif /* #ifndef TIMERIF_H */

@@ -2,40 +2,121 @@

#include "backend/timedriv.h"




static unsigned long in_use_index;
//static unsigned long in_use_index;
static COMPARATOR timer_array[MAX_NUM_TIMERS];

static int precise_timer_on;
unsigned char precise_timer_int_cnt = 0;
/* static int precise_timer_on;
unsigned char precise_timer_int_cnt = 0; */

static void timer_handler();
static void clear_comparators();
static void run_inuse_comparators();
static int find_free_comparator();
//static void run_callbacks();

void bind_tim_vector()
{
tim_vector = (unsigned long) timer_handler;
}


void timer_handler()
static void timer_handler()
{
//if(precise_timer_on)
//{
precise_timer_int_cnt++;
//precise_timer_int_cnt++;
//}

run_inuse_comparators();

/* Run one frame of sound driver here. */

/* Run other observers if necessary? Or keep in
run_inuse_comparators()? */

/* VB manual recommends this. */
HW_REGS[TCR] &= ~TIMER_INT;
HW_REGS[TCR] |= TIMER_ZCLR;
HW_REGS[TCR] |= TIMER_INT;
}

static void clear_comparators()
{
register int count;
for(count = 0; count < MAX_NUM_TIMERS; count++)
{
timer_array[count].in_use = 0;
}
}

static void run_inuse_comparators()
{
register int count;
for(count = 0; count < MAX_NUM_TIMERS; count++)
{
if(timer_array[count].in_use)
{
timer_array[count].ticks_elapsed++;
if(timer_array[count].ticks_elapsed > timer_array[count].ticks_target)
{
timer_array[count].ticks_elapsed = 0;

/* If the desired time has elapsed, modify the target
data using the callback. */
timer_array[count].notifier.notify_fcn( \
timer_array[count].notifier.target_data);
}
}
}
}



static int find_free_comparator()
{
register int count = 0;
/* We need to find a timer that is not currently in use. */

while(count < MAX_NUM_TIMERS && timer_array[count++].in_use)
{
/* That's the whole loop :D. */
}

return (count < MAX_NUM_TIMERS) ? count : -1;
}


/* This should be "atomic" in the sense that the timer is not "in use" until
after all data is set up. */
int set_timer_to_inuse(unsigned short target_ticks, void (* callback)(volatile void *), volatile void * data)
{
int index;

/* We need to find a timer that is not currently in use. */
if((index = find_free_comparator()) >= 0)
{
timer_array[index].ticks_target = target_ticks;
timer_array[index].ticks_elapsed = 0;
timer_array[index].notifier.target_data = data;
timer_array[index].notifier.notify_fcn = callback;
timer_array[index].in_use = 1;
}

return index;
}

void unset_timer_from_inuse(int index)
{
timer_array[index].in_use = 0;

}

/* Required because the interrupt vectors for VB are embedded into the
stub crt0. */
void bind_tim_vector()
{
tim_vector = (unsigned long) timer_handler;
}


void init_timer_hw()
{
clear_comparators(); /* Makes sure nothing is in use. */

/* Timer interrupt will fire once every 10ms. */
HW_REGS[THR] = 0; /* Initial timer counter is 0xFFFF. However, the
hardware will reload the timer with 0x0000 during the next tick.
@@ -47,5 +128,4 @@ void init_timer_hw()
void stop_timer_and_int()
{
HW_REGS[TCR] &= ~(TIMER_ENB | TIMER_INT);

}
@@ -3,7 +3,9 @@
//#include "graphics/cross.h"
#include "assets/graphics/focscrn.h"
#include "assets/graphics/font_pc.h"

#include "gamectl.h"
#include "intrface/timerif.h"

#define ASCII_BIAS 0x30
#define CENTER_X(_m) ((48 - _m) >> 1)
@@ -17,13 +19,18 @@ static void load_ipdfoc_scr();
static void fade_and_wait();
static void print_message(const char * message, short bg_no, short x_pos, short y_pos, short font_bias);

static void set_true(volatile void *);

extern unsigned char precise_timer_int_cnt;
//static void print_center_message(const char * message, short bg_no, short y_pos, unsigned short msg_len);

/* The first thing that the user will see. */
void focus_screen_mainproc()
{

timer_handle_t wait_timer;
volatile int two_seconds_passed = 0; /* I wonder if this is undefined
behavior... as long as the variable doesn't go out of scope while the
timer's in effect, I should be okay... */


//setmem((void*)BGMap(0), 0x00, 0x2000); /* Just use the zeroth char for all tiles */
@@ -32,7 +39,14 @@ void focus_screen_mainproc()
/* Give time for mirrors to adjust... */

load_warning_scr();
fade_and_wait();
vbDisplayShow();

/* Failure of this function is grounds for halting the program! */
wait_timer = request_timer(200, set_true, &two_seconds_passed);
while(!(two_seconds_passed && vbPadKeyDown()));
vbDisplayHide();
remove_timer(wait_timer);

load_ipdfoc_scr();
fade_and_wait();
//vbDisplayOn();
@@ -116,17 +130,23 @@ void fade_and_wait()
{
//vbFXFadeIn(3);
vbDisplayShow();
while(!vbPadKeyDown())
{
(* (short *)(BGMap(0) + 27)) = (short) precise_timer_int_cnt;
}
while(!vbPadKeyDown());
vbDisplayHide();
//vbFXFadeOut(3);
}

void set_true(volatile void * flag)
{
(* (volatile int *) flag) = 1;
}



/* Limited to one segment... for now, anyway. */
/* No support for newlines, autowrapping... yet. */
/* Assumes: Display is off. */

/* Todo: turn into a text-box routine. */
void print_message(const char * message, short bg_no, short x_pos, short y_pos, short font_bias)
{
unsigned short count;
@@ -7,6 +7,16 @@
} */

timer_handle_t request_timer(short centiseconds, void (* callback)(volatile void *), volatile void * input_data)
{
return set_timer_to_inuse(centiseconds, callback, input_data);
}

void remove_timer(timer_handle_t t_handle)
{
unset_timer_from_inuse(t_handle);
}

void init_timer_driver()
{
bind_tim_vector();

0 comments on commit dbc08e8

Please sign in to comment.