mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2024-12-28 04:23:36 +01:00
Proper RTC callback system. Moved keyboard to RTC (saves a timer). Reduced use of 7705.h / 7305.h.
This commit is contained in:
parent
d80de5683b
commit
98fdbbc333
26 changed files with 351 additions and 639 deletions
4
TODO
4
TODO
|
@ -2,12 +2,11 @@ Bugs to fix:
|
|||
- Left-vram overflow when rendering text
|
||||
- A few key hits ignored after leaving the application (could not reproduce)
|
||||
- Lost keyboard control at startup (could not reproduce)
|
||||
- Back-light issues
|
||||
- Back-light issues (0xa400012c on SH3, 0xa4050138 on SH4)
|
||||
|
||||
Simple improvements:
|
||||
- bopti: Monochrome bitmaps blending modes
|
||||
- bopti: Partial transparency
|
||||
- clock: Compute clock frequencies
|
||||
- demo: Try 284x124 at (-60, -28) (all disadvantages)
|
||||
- display: Rectangle-based drawing functions
|
||||
- tales: Test all font encodings
|
||||
|
@ -19,6 +18,7 @@ Simple improvements:
|
|||
Modules to implement:
|
||||
- Serial communication
|
||||
- Sound playback and synthesizing
|
||||
- Handle errors within errno
|
||||
|
||||
Things to investigate:
|
||||
- Packed bit fields alignment
|
||||
|
|
|
@ -288,7 +288,7 @@ void main_menu(int *category, int *app)
|
|||
// Quite a few things to declare...
|
||||
//---
|
||||
|
||||
extern Image res_opt_menu_start;
|
||||
extern Image res_opt_menu;
|
||||
|
||||
const char *mpu, *mpu_names[] = {
|
||||
"Unknown",
|
||||
|
@ -374,7 +374,7 @@ void main_menu(int *category, int *app)
|
|||
print(1, 1, "Tab %d", tab);
|
||||
break;
|
||||
}
|
||||
dimage(0, 56, &res_opt_menu_start);
|
||||
dimage(0, 56, &res_opt_menu);
|
||||
|
||||
if(list)
|
||||
{
|
||||
|
|
|
@ -53,28 +53,28 @@ static void getxy(Image *img, int *x, int *y)
|
|||
|
||||
static Image *select(Image *current)
|
||||
{
|
||||
extern Image res_bopti_thumbs_start;
|
||||
extern Image res_bopti_thumbs;
|
||||
extern Image
|
||||
res_items_start,
|
||||
res_sprites_start,
|
||||
res_swords_start,
|
||||
res_zelda_start,
|
||||
res_isometric_start;
|
||||
res_items,
|
||||
res_sprites,
|
||||
res_swords,
|
||||
res_zelda,
|
||||
res_isometric;
|
||||
|
||||
struct {
|
||||
Image *img;
|
||||
const char *name;
|
||||
const char *info;
|
||||
} images[] = {
|
||||
{ &res_items_start, "Items", "Gray" },
|
||||
{ &res_sprites_start, "Sprites", "Gray" },
|
||||
{ &res_swords_start, "Swords", "Gray Alpha" },
|
||||
{ &res_zelda_start, "Zelda", "Mono" },
|
||||
{ &res_isometric_start, "Isometric", "Mono Alpha" },
|
||||
{ &res_items, "Items", "Gray" },
|
||||
{ &res_sprites, "Sprites", "Gray" },
|
||||
{ &res_swords, "Swords", "Gray Alpha" },
|
||||
{ &res_zelda, "Zelda", "Mono" },
|
||||
{ &res_isometric, "Isometric", "Mono Alpha" },
|
||||
{ NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
Image *thumbs = &res_bopti_thumbs_start;
|
||||
Image *thumbs = &res_bopti_thumbs;
|
||||
int items = 0;
|
||||
static int row = 0;
|
||||
int leave = 1, i;
|
||||
|
@ -134,7 +134,7 @@ static Image *select(Image *current)
|
|||
|
||||
void test_bopti(void)
|
||||
{
|
||||
extern Image res_opt_bitmap_start;
|
||||
extern Image res_opt_bitmap;
|
||||
Image *img = NULL;
|
||||
|
||||
int leave = 1;
|
||||
|
@ -152,7 +152,7 @@ void test_bopti(void)
|
|||
if(img) gimage(x, y, img);
|
||||
|
||||
gclear_area(0, 55, 127, 63);
|
||||
gimage(0, 56, &res_opt_bitmap_start);
|
||||
gimage(0, 56, &res_opt_bitmap);
|
||||
gupdate();
|
||||
}
|
||||
else if(img)
|
||||
|
@ -164,7 +164,7 @@ void test_bopti(void)
|
|||
if(img) dimage(x, y, img);
|
||||
|
||||
dclear_area(0, 55, 127, 63);
|
||||
dimage(0, 56, &res_opt_bitmap_start);
|
||||
dimage(0, 56, &res_opt_bitmap);
|
||||
dupdate();
|
||||
}
|
||||
else
|
||||
|
@ -174,7 +174,7 @@ void test_bopti(void)
|
|||
dclear();
|
||||
locate(3, 3, "No image selected");
|
||||
|
||||
dimage(0, 56, &res_opt_bitmap_start);
|
||||
dimage(0, 56, &res_opt_bitmap);
|
||||
dupdate();
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
static void draw(int delay1, int delay2, int selected)
|
||||
{
|
||||
extern Image res_opt_gray_start;
|
||||
extern Image res_opt_gray;
|
||||
unsigned int *vl = gray_lightVRAM();
|
||||
unsigned int *vd = gray_darkVRAM();
|
||||
|
||||
|
@ -36,7 +36,7 @@ static void draw(int delay1, int delay2, int selected)
|
|||
|
||||
locate(3, selected ? 6 : 4, "\x02");
|
||||
|
||||
gimage(0, 56, &res_opt_gray_start);
|
||||
gimage(0, 56, &res_opt_gray);
|
||||
gupdate();
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
static void draw(struct RTCTime time)
|
||||
{
|
||||
extern Image res_rtc_segments_start;
|
||||
extern Image res_rtc_segments;
|
||||
|
||||
const char *days[7] = {
|
||||
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
|
||||
|
@ -38,7 +38,7 @@ static void draw(struct RTCTime time)
|
|||
digits[5] = time.seconds % 10;
|
||||
|
||||
// Drawing digits.
|
||||
for(i = 0; i < 6; i++) dimage_part(x[i], 8, &res_rtc_segments_start,
|
||||
for(i = 0; i < 6; i++) dimage_part(x[i], 8, &res_rtc_segments,
|
||||
12 * digits[i], 0, 11, 19);
|
||||
// Drawing ':' between pairs of digits.
|
||||
for(i = 0; i < 16; i++) dpixel(47 + 32 * (i >= 8) + (i & 1),
|
||||
|
@ -52,13 +52,13 @@ static void draw(struct RTCTime time)
|
|||
|
||||
static void callback(void)
|
||||
{
|
||||
extern Image res_opt_rtc_start;
|
||||
extern Image res_opt_rtc;
|
||||
struct RTCTime time = rtc_getTime();
|
||||
time.year += 1900;
|
||||
|
||||
dclear();
|
||||
draw(time);
|
||||
dimage_part(0, 56, &res_opt_rtc_start, 0, 0, 19, 8);
|
||||
dimage_part(0, 56, &res_opt_rtc, 0, 0, 19, 8);
|
||||
dupdate();
|
||||
}
|
||||
|
||||
|
@ -116,8 +116,8 @@ static void set_region(struct RTCTime *time, int region, int value)
|
|||
|
||||
static void set(void)
|
||||
{
|
||||
extern Image res_opt_rtc_start;
|
||||
Image *opt = &res_opt_rtc_start;
|
||||
extern Image res_opt_rtc;
|
||||
Image *opt = &res_opt_rtc;
|
||||
|
||||
struct {
|
||||
int x, y;
|
||||
|
@ -239,9 +239,9 @@ static void set(void)
|
|||
|
||||
void test_rtc(void)
|
||||
{
|
||||
int key;
|
||||
int key, cb_id;
|
||||
|
||||
rtc_setCallback(callback, RTCFreq_1Hz);
|
||||
cb_id = rtc_cb_add(RTCFreq_1Hz, callback, 0);
|
||||
callback();
|
||||
|
||||
while(1)
|
||||
|
@ -250,13 +250,13 @@ void test_rtc(void)
|
|||
|
||||
if(key == KEY_EXIT) break;
|
||||
if(key == KEY_F1)
|
||||
{
|
||||
rtc_setCallback(NULL, RTCFreq_1Hz);
|
||||
{
|
||||
rtc_cb_edit(cb_id, RTCFreq_None, NULL);
|
||||
set();
|
||||
callback();
|
||||
rtc_setCallback(callback, RTCFreq_1Hz);
|
||||
rtc_cb_edit(cb_id, RTCFreq_1Hz, callback);
|
||||
}
|
||||
}
|
||||
|
||||
rtc_setCallback(NULL, RTCFreq_1Hz);
|
||||
rtc_cb_end(cb_id);
|
||||
}
|
||||
|
|
|
@ -12,13 +12,13 @@
|
|||
|
||||
static Font *select(Font *current)
|
||||
{
|
||||
extern Font res_font_modern_start;
|
||||
extern Font res_font_modern;
|
||||
struct {
|
||||
Font *font;
|
||||
const char *name;
|
||||
} fonts[] = {
|
||||
{ NULL, "gint default" },
|
||||
{ &res_font_modern_start, "Modern" },
|
||||
{ NULL, "gint default" },
|
||||
{ &res_font_modern, "Modern" },
|
||||
};
|
||||
int font_number = 2;
|
||||
|
||||
|
@ -82,7 +82,7 @@ void test_tales(void)
|
|||
{
|
||||
enum Color colors[] = { Color_Black, Color_Dark, Color_Light,
|
||||
Color_White, Color_Invert };
|
||||
extern Image res_opt_tales_start;
|
||||
extern Image res_opt_tales;
|
||||
Font *font = NULL;
|
||||
|
||||
int black_bg = 0;
|
||||
|
@ -116,7 +116,7 @@ void test_tales(void)
|
|||
gtext(2, 2 + i * height, str);
|
||||
}
|
||||
|
||||
gimage(0, 56, &res_opt_tales_start);
|
||||
gimage(0, 56, &res_opt_tales);
|
||||
|
||||
x = 45 + 8 * color;
|
||||
gline(x, 57, x + 5, 57, Color_Black);
|
||||
|
|
|
@ -21,6 +21,7 @@ static struct ClockConfig conf;
|
|||
|
||||
static volatile int elapsed_timer = -1;
|
||||
static volatile int elapsed_rtc = -1;
|
||||
static int cb_id = -1;
|
||||
|
||||
static void timing_rtc(void)
|
||||
{
|
||||
|
@ -36,7 +37,7 @@ static void timing_start(void)
|
|||
{
|
||||
timer_start(TIMER_USER, clock_setting(16, Clock_Hz), TIMER_Po_4,
|
||||
timing_timer, 0);
|
||||
rtc_setCallback(timing_rtc, RTCFreq_16Hz);
|
||||
rtc_cb_edit(cb_id, RTCFreq_16Hz, timing_rtc);
|
||||
|
||||
elapsed_timer = 0;
|
||||
elapsed_rtc = 0;
|
||||
|
@ -54,8 +55,8 @@ static void timing_start(void)
|
|||
*/
|
||||
static void small_text(int x, int y, const char *text, int alignment)
|
||||
{
|
||||
extern Image res_clock_chars_start;
|
||||
Image *chars = &res_clock_chars_start;
|
||||
extern Image res_clock_chars;
|
||||
Image *chars = &res_clock_chars;
|
||||
const char *table = "0123456789kMHz*/";
|
||||
|
||||
if(alignment) x -= 2 * strlen(text) - 1, y -= 2;
|
||||
|
@ -75,27 +76,15 @@ static void small_text(int x, int y, const char *text, int alignment)
|
|||
/*
|
||||
getFreq()
|
||||
Prints the given frequency in a string on the form:
|
||||
|
||||
332kHz
|
||||
<-><->
|
||||
3 3
|
||||
|
||||
There are 1, 2 or 3 characters for the value, and 2 or 3
|
||||
characters for the unit. The string is compacted.
|
||||
*/
|
||||
void getFreq(char *str, int freq)
|
||||
{
|
||||
if(freq < 1000)
|
||||
{
|
||||
sprintf(str, "%dHz", freq);
|
||||
return;
|
||||
}
|
||||
if(freq < 1000000)
|
||||
{
|
||||
sprintf(str, "%dkHz", (freq + 500) / 1000);
|
||||
return;
|
||||
}
|
||||
sprintf(str, "%dMHz", (freq + 500000) / 1000000);
|
||||
if(freq < 1000) sprintf(str, "%dHz", freq);
|
||||
else if(freq < 1000000) sprintf(str, "%dkHz", (freq + 500) / 1000);
|
||||
else sprintf(str, "%dMHz", (freq + 500000) / 1000000);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -140,14 +129,14 @@ static void display_freq(int x, int y, int freq)
|
|||
*/
|
||||
static void draw(int tab)
|
||||
{
|
||||
extern Image res_opt_timer_start;
|
||||
extern Image res_clock_7705_start;
|
||||
extern Image res_clock_7305_start;
|
||||
extern Image res_opt_timer;
|
||||
extern Image res_clock_7705;
|
||||
extern Image res_clock_7305;
|
||||
|
||||
char buffer[16];
|
||||
|
||||
dclear();
|
||||
dimage(0, 56, &res_opt_timer_start);
|
||||
dimage(0, 56, &res_opt_timer);
|
||||
|
||||
if(!tab)
|
||||
{
|
||||
|
@ -161,7 +150,7 @@ static void draw(int tab)
|
|||
|
||||
if(isSH3())
|
||||
{
|
||||
dimage(64, 0, &res_clock_7705_start);
|
||||
dimage(64, 0, &res_clock_7705);
|
||||
|
||||
getFreq(buffer, conf.CKIO_f);
|
||||
small_text(84, 16, buffer, 1);
|
||||
|
@ -186,7 +175,7 @@ static void draw(int tab)
|
|||
}
|
||||
else
|
||||
{
|
||||
dimage(64, 0, &res_clock_7305_start);
|
||||
dimage(64, 0, &res_clock_7305);
|
||||
|
||||
getFreq(buffer, conf.RTCCLK_f);
|
||||
small_text(84, 14, buffer, 1);
|
||||
|
@ -207,27 +196,26 @@ static void draw(int tab)
|
|||
}
|
||||
else
|
||||
{
|
||||
int timer = elapsed_timer, rtc = elapsed_rtc; // just in case
|
||||
|
||||
locate(1, 1, "Timer/RTC comparison");
|
||||
|
||||
locate(2, 3, "Timer");
|
||||
if(elapsed_timer >= 0) print(12, 3, "%04x", elapsed_timer);
|
||||
if(timer >= 0) print(12, 3, "%04x", timer);
|
||||
else locate(12, 3, "...");
|
||||
|
||||
locate(2, 4, "RTC");
|
||||
if(elapsed_rtc >= 0) print(12, 4, "%04x", elapsed_rtc);
|
||||
if(rtc >= 0) print(12, 4, "%04x", rtc);
|
||||
else locate(12, 4, "...");
|
||||
|
||||
// We define the accuracy of the timer as the square of the
|
||||
// ratio between the two counters.
|
||||
// We define the accuracy of the timer as the ratio between the
|
||||
// two counters.
|
||||
locate(2, 5, "Accuracy");
|
||||
if(elapsed_rtc > 0 && elapsed_timer > 0)
|
||||
if(rtc > 0 && timer > 0)
|
||||
{
|
||||
int ratio;
|
||||
if(elapsed_timer <= elapsed_rtc)
|
||||
ratio = (10000 * elapsed_timer) / elapsed_rtc;
|
||||
else
|
||||
ratio = (10000 * elapsed_rtc) / elapsed_timer;
|
||||
ratio = (ratio * ratio) / 10000;
|
||||
if(timer <= rtc) ratio = (10000 * timer) / rtc;
|
||||
else ratio = (10000 * rtc) / timer;
|
||||
|
||||
print(12, 5, "%d.%02d %%", ratio / 100, ratio % 100);
|
||||
}
|
||||
|
@ -258,7 +246,7 @@ void test_timer(void)
|
|||
|
||||
elapsed_timer = -1;
|
||||
elapsed_rtc = -1;
|
||||
rtc_setCallback(timing_start, RTCFreq_16Hz);
|
||||
cb_id = rtc_cb_add(RTCFreq_16Hz, timing_start, 0);
|
||||
|
||||
text_configure(NULL, Color_Black);
|
||||
|
||||
|
@ -270,7 +258,7 @@ void test_timer(void)
|
|||
{
|
||||
case KEY_EXIT:
|
||||
timer_stop(TIMER_USER);
|
||||
rtc_setCallback(NULL, RTCFreq_1Hz);
|
||||
rtc_cb_end(cb_id);
|
||||
return;
|
||||
|
||||
case KEY_F1:
|
||||
|
|
189
include/7305.h
189
include/7305.h
|
@ -12,194 +12,6 @@
|
|||
#pragma pack(push, 1)
|
||||
#define gap(n) unsigned: n << 3
|
||||
|
||||
|
||||
|
||||
//---
|
||||
// Real-time clock.
|
||||
//---
|
||||
|
||||
struct _st_rtc
|
||||
{
|
||||
unsigned char const R64CNT;
|
||||
gap(1);
|
||||
|
||||
union {
|
||||
unsigned char BYTE;
|
||||
struct {
|
||||
unsigned :1;
|
||||
unsigned TENS :3;
|
||||
unsigned ONES :4;
|
||||
};
|
||||
} RSECCNT;
|
||||
gap(1);
|
||||
|
||||
union {
|
||||
unsigned char BYTE;
|
||||
struct {
|
||||
unsigned :1;
|
||||
unsigned TENS :3;
|
||||
unsigned ONES :4;
|
||||
};
|
||||
} RMINCNT;
|
||||
gap(1);
|
||||
|
||||
union {
|
||||
unsigned char BYTE;
|
||||
struct {
|
||||
unsigned :2;
|
||||
unsigned TENS :2;
|
||||
unsigned ONES :4;
|
||||
};
|
||||
} RHRCNT;
|
||||
gap(1);
|
||||
|
||||
// 0=Sunday, 1=Monday, ..., 6=Saturday, 7=Reserved (prohibited).
|
||||
unsigned char RWKCNT;
|
||||
gap(1);
|
||||
|
||||
union {
|
||||
unsigned char BYTE;
|
||||
struct {
|
||||
unsigned :2;
|
||||
unsigned TENS :2;
|
||||
unsigned ONES :4;
|
||||
};
|
||||
} RDAYCNT;
|
||||
gap(1);
|
||||
|
||||
union {
|
||||
unsigned char BYTE;
|
||||
struct {
|
||||
unsigned :3;
|
||||
unsigned TENS :1;
|
||||
unsigned ONES :4;
|
||||
};
|
||||
} RMONCNT;
|
||||
gap(1);
|
||||
|
||||
union {
|
||||
unsigned short WORD;
|
||||
struct {
|
||||
unsigned THOUSANDS :4;
|
||||
unsigned HUNDREDS :4;
|
||||
unsigned TENS :4;
|
||||
unsigned ONES :4;
|
||||
};
|
||||
} RYRCNT;
|
||||
|
||||
union {
|
||||
unsigned char BYTE;
|
||||
struct {
|
||||
unsigned ENB :1;
|
||||
unsigned TENS :3;
|
||||
unsigned ONES :4;
|
||||
};
|
||||
} RSECAR;
|
||||
gap(1);
|
||||
|
||||
union {
|
||||
unsigned char BYTE;
|
||||
struct {
|
||||
unsigned ENB :1;
|
||||
unsigned TENS :3;
|
||||
unsigned ONES :4;
|
||||
};
|
||||
} RMINAR;
|
||||
gap(1);
|
||||
|
||||
union {
|
||||
unsigned char BYTE;
|
||||
struct {
|
||||
unsigned ENB :1;
|
||||
unsigned :1;
|
||||
unsigned TENS :2;
|
||||
unsigned ONES :4;
|
||||
};
|
||||
} RHRAR;
|
||||
gap(1);
|
||||
|
||||
union {
|
||||
unsigned char BYTE;
|
||||
struct {
|
||||
unsigned ENB :1;
|
||||
unsigned :4;
|
||||
// See RTC.RDAYCNT for day encoding.
|
||||
unsigned DAY :3;
|
||||
};
|
||||
} RWKAR;
|
||||
gap(1);
|
||||
|
||||
union {
|
||||
unsigned char BYTE;
|
||||
struct {
|
||||
unsigned ENB :1;
|
||||
unsigned :1;
|
||||
unsigned TENS :2;
|
||||
unsigned ONES :4;
|
||||
};
|
||||
} RDAYAR;
|
||||
gap(1);
|
||||
|
||||
union {
|
||||
unsigned char BYTE;
|
||||
struct {
|
||||
unsigned ENB :1;
|
||||
unsigned :2;
|
||||
unsigned TENS :1;
|
||||
unsigned ONES :4;
|
||||
};
|
||||
} RMONAR;
|
||||
gap(1);
|
||||
|
||||
union {
|
||||
unsigned char BYTE;
|
||||
struct {
|
||||
unsigned CF :1;
|
||||
unsigned :2;
|
||||
unsigned CIE :1;
|
||||
unsigned AIE :1;
|
||||
unsigned :2;
|
||||
unsigned AF :1;
|
||||
};
|
||||
} RCR1;
|
||||
gap(1);
|
||||
|
||||
union {
|
||||
unsigned char BYTE;
|
||||
struct {
|
||||
unsigned PEF :1;
|
||||
unsigned PES :3;
|
||||
unsigned :1;
|
||||
unsigned ADJ :1;
|
||||
unsigned RESET :1;
|
||||
unsigned START :1;
|
||||
};
|
||||
} RCR2;
|
||||
gap(1);
|
||||
|
||||
union {
|
||||
unsigned short WORD;
|
||||
struct {
|
||||
unsigned THOUSANDS :4;
|
||||
unsigned HUNDREDS :4;
|
||||
unsigned TENS :4;
|
||||
unsigned ONES :4;
|
||||
};
|
||||
} RYRAR;
|
||||
gap(2);
|
||||
|
||||
union {
|
||||
unsigned char BYTE;
|
||||
struct {
|
||||
unsigned ENB :1;
|
||||
unsigned :7;
|
||||
};
|
||||
} RCR3;
|
||||
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
|
||||
//---
|
||||
// Interrupt controller, part 1.
|
||||
//---
|
||||
|
@ -854,7 +666,6 @@ struct _st_intx
|
|||
|
||||
|
||||
|
||||
#define RTC (*(volatile struct _st_rtc *)0xa413fec0)
|
||||
#define INTC (*(volatile struct _st_intc *)0xa4140000)
|
||||
#define INTX (*(volatile struct _st_intx *)0xa4080000)
|
||||
|
||||
|
|
197
include/7705.h
197
include/7705.h
|
@ -247,198 +247,6 @@ struct st_pn { /* struct PN */
|
|||
} DR; /* */
|
||||
}; /* */
|
||||
|
||||
struct st_rtc { /* struct RTC */
|
||||
unsigned char R64CNT; /* R64CNT */
|
||||
char wk1; /* */
|
||||
union { /* RSECCNT */
|
||||
unsigned char BYTE; /* Byte Access */
|
||||
struct { /* Bit Access */
|
||||
unsigned char :1; /* */
|
||||
unsigned char S10:3; /* 10sec */
|
||||
unsigned char S1 :4; /* 1sec */
|
||||
} BIT; /* */
|
||||
} RSECCNT; /* */
|
||||
char wk2; /* */
|
||||
union { /* RMINCNT */
|
||||
unsigned char BYTE; /* Byte Access */
|
||||
struct { /* Bit Access */
|
||||
unsigned char :1; /* */
|
||||
unsigned char M10:3; /* 10min */
|
||||
unsigned char M1 :4; /* 1min */
|
||||
} BIT; /* */
|
||||
} RMINCNT; /* */
|
||||
char wk3; /* */
|
||||
union { /* RHRCNT */
|
||||
unsigned char BYTE; /* Byte Access */
|
||||
struct { /* Bit Access */
|
||||
unsigned char :2; /* */
|
||||
unsigned char H10:2; /* 10sec */
|
||||
unsigned char H1 :4; /* 1sec */
|
||||
} BIT; /* */
|
||||
} RHRCNT; /* */
|
||||
char wk4; /* */
|
||||
union { /* RWKCNT */
|
||||
unsigned char BYTE; /* Byte Access */
|
||||
struct { /* Bit Access */
|
||||
unsigned char :5; /* */
|
||||
unsigned char WK:3; /* week */
|
||||
} BIT; /* */
|
||||
} RWKCNT; /* */
|
||||
char wk5; /* */
|
||||
union { /* RDAYCNT */
|
||||
unsigned char BYTE; /* Byte Access */
|
||||
struct { /* Bit Access */
|
||||
unsigned char :2; /* */
|
||||
unsigned char D10:2; /* 10day */
|
||||
unsigned char D1 :4; /* 1day */
|
||||
} BIT; /* */
|
||||
} RDAYCNT; /* */
|
||||
char wk6; /* */
|
||||
union { /* RMONCNT */
|
||||
unsigned char BYTE; /* Byte Access */
|
||||
struct { /* Bit Access */
|
||||
unsigned char :3; /* */
|
||||
unsigned char M10:1; /* 10mon */
|
||||
unsigned char M1 :4; /* 1mon */
|
||||
} BIT; /* */
|
||||
} RMONCNT; /* */
|
||||
char wk7; /* */
|
||||
union { /* RYRCNT */
|
||||
unsigned short WORD; /* Word Access */
|
||||
struct { /* Bit Access */
|
||||
unsigned short Y1000:4; /* 1000year */
|
||||
unsigned short Y100 :4; /* 100year */
|
||||
unsigned short Y10 :4; /* 10year */
|
||||
unsigned short Y1 :4; /* 1year */
|
||||
} BIT; /* */
|
||||
} RYRCNT; /* */
|
||||
union { /* RSECAR */
|
||||
unsigned char BYTE; /* Byte Access */
|
||||
struct { /* Bit Access */
|
||||
unsigned char ENB:1; /* ENB */
|
||||
unsigned char S10:3; /* 10sec */
|
||||
unsigned char S1 :4; /* 1sec */
|
||||
} BIT; /* */
|
||||
} RSECAR; /* */
|
||||
char wk8; /* */
|
||||
union { /* RMINAR */
|
||||
unsigned char BYTE; /* Byte Access */
|
||||
struct { /* Bit Access */
|
||||
unsigned char ENB:1; /* ENB */
|
||||
unsigned char M10:3; /* 10min */
|
||||
unsigned char M1 :4; /* 1min */
|
||||
} BIT; /* */
|
||||
} RMINAR; /* */
|
||||
char wk9; /* */
|
||||
union { /* RHRAR */
|
||||
unsigned char BYTE; /* Byte Access */
|
||||
struct { /* Bit Access */
|
||||
unsigned char ENB:1; /* ENB */
|
||||
unsigned char :1; /* */
|
||||
unsigned char H10:2; /* 10sec */
|
||||
unsigned char H1 :4; /* 1sec */
|
||||
} BIT; /* */
|
||||
} RHRAR; /* */
|
||||
char wk10; /* */
|
||||
union { /* RWKAR */
|
||||
unsigned char BYTE; /* Byte Access */
|
||||
struct { /* Bit Access */
|
||||
unsigned char ENB:1; /* ENB */
|
||||
unsigned char :4; /* */
|
||||
unsigned char WK :3; /* week */
|
||||
} BIT; /* */
|
||||
} RWKAR; /* */
|
||||
char wk11; /* */
|
||||
union { /* RDAYAR */
|
||||
unsigned char BYTE; /* Byte Access */
|
||||
struct { /* Bit Access */
|
||||
unsigned char ENB:1; /* ENB */
|
||||
unsigned char :1; /* */
|
||||
unsigned char D10:2; /* 10day */
|
||||
unsigned char D1 :4; /* 1day */
|
||||
} BIT; /* */
|
||||
} RDAYAR; /* */
|
||||
char wk12; /* */
|
||||
union { /* RMONAR */
|
||||
unsigned char BYTE; /* Byte Access */
|
||||
struct { /* Bit Access */
|
||||
unsigned char ENB:1; /* ENB */
|
||||
unsigned char :2; /* */
|
||||
unsigned char M10:1; /* 10mon */
|
||||
unsigned char M1 :4; /* 1mon */
|
||||
} BIT; /* */
|
||||
} RMONAR; /* */
|
||||
char wk13; /* */
|
||||
union { /* RCR1 */
|
||||
unsigned char BYTE; /* Byte Access */
|
||||
struct { /* Bit Access */
|
||||
unsigned char CF :1; /* CF */
|
||||
unsigned char :2; /* */
|
||||
unsigned char CIE:1; /* CIE */
|
||||
unsigned char AIE:1; /* AIE */
|
||||
unsigned char :2; /* */
|
||||
unsigned char AF :1; /* AF */
|
||||
} BIT; /* */
|
||||
} RCR1; /* */
|
||||
char wk14; /* */
|
||||
union { /* RCR2 */
|
||||
unsigned char BYTE; /* Byte Access */
|
||||
struct { /* Bit Access */
|
||||
unsigned char PEF :1; /* PEF */
|
||||
unsigned char PES :3; /* PES */
|
||||
unsigned char RTCEN:1; /* RTCEN */
|
||||
unsigned char ADJ :1; /* ADJ */
|
||||
unsigned char RESET:1; /* RESET */
|
||||
unsigned char START:1; /* START */
|
||||
} BIT; /* */
|
||||
} RCR2; /* */
|
||||
};
|
||||
|
||||
struct st_tmu { /* struct TMU */
|
||||
union { /* TSTR */
|
||||
unsigned char BYTE; /* Byte Access */
|
||||
struct { /* Bit Access */
|
||||
unsigned char :5; /* */
|
||||
unsigned char STR2:1; /* STR2 */
|
||||
unsigned char STR1:1; /* STR1 */
|
||||
unsigned char STR0:1; /* STR0 */
|
||||
} BIT; /* */
|
||||
} TSTR; /* */
|
||||
}; /* */
|
||||
struct st_tmu0 { /* struct TMU0 */
|
||||
unsigned int TCOR; /* TCOR */
|
||||
unsigned int TCNT; /* TCNT */
|
||||
union { /* TCR */
|
||||
unsigned short WORD; /* Word Access */
|
||||
struct { /* Bit Access */
|
||||
unsigned short :7; /* */
|
||||
unsigned short UNF :1; /* UNF */
|
||||
unsigned short :2; /* */
|
||||
unsigned short UNIE:1; /* UNIE */
|
||||
unsigned short CKEG:2; /* CKEG */
|
||||
unsigned short TPSC:3; /* TPSC */
|
||||
} BIT; /* */
|
||||
} TCR; /* */
|
||||
}; /* */
|
||||
struct st_tmu2 { /* struct TMU2 */
|
||||
unsigned int TCOR; /* TCOR */
|
||||
unsigned int TCNT; /* TCNT */
|
||||
union { /* TCR */
|
||||
unsigned short WORD; /* Word Access */
|
||||
struct {
|
||||
unsigned short :6;
|
||||
unsigned short ICPF:1;
|
||||
unsigned short UNF :1;
|
||||
unsigned short ICPE:2;
|
||||
unsigned short UNIE:1;
|
||||
unsigned short CKEG:2;
|
||||
unsigned short TPSC:3;
|
||||
} BIT;
|
||||
} TCR;
|
||||
char wk[2];
|
||||
unsigned int TCPR;
|
||||
};
|
||||
|
||||
struct st_usb { /* struct USB */
|
||||
union { /* UCLKCR */
|
||||
unsigned char BYTE; /* Byte Access */
|
||||
|
@ -1262,7 +1070,6 @@ union un_stbcr2 {
|
|||
|
||||
#define CPG (*(volatile struct st_cpg *)0xffffff80)
|
||||
#define WDT (*(volatile struct st_wdt *)0xffffff84)
|
||||
#define RTC (*(volatile struct st_rtc *)0xfffffec0)
|
||||
#define INTC (*(volatile struct st_intc *)0xfffffee0)
|
||||
#define INTX (*(volatile struct st_intx *)0xa4000000)
|
||||
#define PA (*(volatile struct st_pa *)0xa4000120)
|
||||
|
@ -1279,10 +1086,6 @@ union un_stbcr2 {
|
|||
#define SCP (*(volatile struct st_scp *)0xa4000136)
|
||||
#define PM (*(volatile struct st_pm *)0xa4000138)
|
||||
#define PN (*(volatile struct st_pn *)0xa400013a)
|
||||
#define TMU (*(volatile struct st_tmu *)0xfffffe92)
|
||||
#define TMU0 (*(volatile struct st_tmu0 *)0xfffffe94)
|
||||
#define TMU1 (*(volatile struct st_tmu0 *)0xfffffea0)
|
||||
#define TMU2 (*(volatile struct st_tmu2 *)0xfffffeac)
|
||||
#define USB (*(volatile struct st_usb *)0xa40a0008)
|
||||
#define SCIF0 (*(volatile struct st_scif *)0xa4400000)
|
||||
#define SCIF2 (*(volatile struct st_scif *)0xa4410000)
|
||||
|
|
|
@ -7,6 +7,9 @@
|
|||
//
|
||||
//---
|
||||
|
||||
#ifndef _CLOCK_H
|
||||
#define _CLOCK_H
|
||||
|
||||
//---
|
||||
// Some type declarations.
|
||||
//---
|
||||
|
@ -121,3 +124,5 @@ void clock_measure(void);
|
|||
Waits until the measurements are finished. This may be immediate.
|
||||
*/
|
||||
void clock_measure_end(void);
|
||||
|
||||
#endif // _CLOCK_H
|
||||
|
|
|
@ -11,6 +11,9 @@ extern volatile int interrupt_flag;
|
|||
extern int repeat_first, repeat_next;
|
||||
extern int last_key, last_repeats, last_events;
|
||||
|
||||
// RTC callback id.
|
||||
extern unsigned cb_id;
|
||||
|
||||
/*
|
||||
sleep()
|
||||
Puts the CPU into sleep until an interrupt request is accepted.
|
||||
|
@ -26,7 +29,9 @@ int getPressedKey(volatile unsigned char *keyboard_state);
|
|||
/*
|
||||
getPressedKeys()
|
||||
Find 'count' pressed keys in the keyboard state and fills the 'keys'
|
||||
array. Returns the number of actually-pressed keys found.
|
||||
array. Returns the number of keys found.
|
||||
WARNING: keyboard artifacts make this function read as pressed keys
|
||||
that aren't (typically, LEFT + DOWN + SHIFT => ALPHA).
|
||||
*/
|
||||
int getPressedKeys(volatile unsigned char *keyboard_state, int *keys,
|
||||
int count);
|
||||
|
|
|
@ -1,6 +1,27 @@
|
|||
#ifndef _INTERNALS_RTC_H
|
||||
#define _INTERNALS_RTC_H 1
|
||||
|
||||
#include <rtc.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#define RTC_CB_ARRAY_SIZE 5
|
||||
|
||||
/*
|
||||
struct rtc_cb
|
||||
An RTC callback.
|
||||
*/
|
||||
struct rtc_cb
|
||||
{
|
||||
enum RTCFrequency freq;
|
||||
int id;
|
||||
|
||||
void (*callback)(void);
|
||||
int repeats;
|
||||
};
|
||||
|
||||
// The callback array.
|
||||
struct rtc_cb cb_array[RTC_CB_ARRAY_SIZE];
|
||||
|
||||
/*
|
||||
struct mod_rtc
|
||||
This structure describes the arrangement of RTC register in the memory.
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
#ifndef _KEYBOARD_H
|
||||
#define _KEYBOARD_H 1
|
||||
|
||||
#include <rtc.h>
|
||||
|
||||
//---
|
||||
// Keycodes and related.
|
||||
//---
|
||||
|
@ -89,6 +91,21 @@
|
|||
#define KEY_NONE 0x00
|
||||
#define KEY_NOEVENT 0xff
|
||||
|
||||
/*
|
||||
enum KeyboardFrequency
|
||||
Possible values for the keyboard frequency.
|
||||
*/
|
||||
enum KeyboardFrequency
|
||||
{
|
||||
KeyboardFreq_500mHz = RTCFreq_500mHz,
|
||||
KeyboardFreq_1Hz = RTCFreq_1Hz,
|
||||
KeyboardFreq_2Hz = RTCFreq_2Hz,
|
||||
KeyboardFreq_4Hz = RTCFreq_4Hz,
|
||||
KeyboardFreq_16Hz = RTCFreq_16Hz,
|
||||
KeyboardFreq_64Hz = RTCFreq_64Hz,
|
||||
KeyboardFreq_256Hz = RTCFreq_256Hz,
|
||||
};
|
||||
|
||||
|
||||
|
||||
//---
|
||||
|
@ -97,15 +114,12 @@
|
|||
|
||||
/*
|
||||
keyboard_setFrequency()
|
||||
Sets the keyboard frequency. The default frequency is 32 Hz. The unit
|
||||
for the argument is Hz. Very few applications will need to change this
|
||||
setting.
|
||||
The actual frequency is guaranteed to be greater than the argument.
|
||||
Be aware that you will miss key hits at low frequencies. At higher
|
||||
frequencies, you will lose important execution power.
|
||||
Sets the keyboard frequency. The default frequency is 16 Hz. Very few
|
||||
applications will need to change this setting.
|
||||
At low frequencies, you will miss key hits. At high frequencies, you
|
||||
may lose execution power.
|
||||
*/
|
||||
// Currently not implemented.
|
||||
// void keyboard_setFrequency(int frequency);
|
||||
void keyboard_setFrequency(enum KeyboardFrequency frequency);
|
||||
|
||||
/*
|
||||
keyboard_setRepeatRate()
|
||||
|
|
|
@ -62,22 +62,39 @@ enum RTCFrequency
|
|||
RTCFreq_16Hz = 3,
|
||||
RTCFreq_64Hz = 2,
|
||||
RTCFreq_256Hz = 1,
|
||||
RTCFreq_None = 0,
|
||||
};
|
||||
|
||||
/*
|
||||
rtc_setCallback()
|
||||
Sets the callback function for the real-time clock interrupt. If
|
||||
frequency is non-zero, the clock frequency is set to the given value.
|
||||
Set the callback to NULL to deactivate an existing callback.
|
||||
rtc_cb_add()
|
||||
Registers a new callback for the RTC. Returns the callback id on
|
||||
success (positive integer), or one of the following error codes:
|
||||
-1 Array is full
|
||||
-2 Invalid parameter
|
||||
The number of repeats may be set to 0, in which case the callback is
|
||||
called indefinitely unless the user calls rtc_cb_end().
|
||||
*/
|
||||
void rtc_setCallback(void (*callback)(void), enum RTCFrequency frequency);
|
||||
int rtc_cb_add(enum RTCFrequency freq, void (*function)(void), int repeats);
|
||||
|
||||
/*
|
||||
rtc_getCallback()
|
||||
Returns the callback function. If frequency is non-NULL, it is set to
|
||||
the current frequency value.
|
||||
rtc_cb_end()
|
||||
Removes the callback with the given id (as returned by rtc_cb_add())
|
||||
from the callback array.
|
||||
*/
|
||||
void (*rtc_getCallback(enum RTCFrequency *frequency))(void);
|
||||
void rtc_cb_end(int id);
|
||||
|
||||
/*
|
||||
rtc_cb_edit()
|
||||
Changes information related to a callback. This function returns 0 on
|
||||
success, or one of the following error codes:
|
||||
-1 Callback does not exist
|
||||
-2 Invalid parameters
|
||||
This function never removes a callback. Call rtc_cb_end() for this. One
|
||||
can set the function to NULL or the frequency to RTCFreq_None to
|
||||
temporarily disable the callback.
|
||||
*/
|
||||
int rtc_cb_edit(int id, enum RTCFrequency new_freq,
|
||||
void (*new_function)(void));
|
||||
|
||||
|
||||
|
||||
|
@ -95,17 +112,10 @@ void rtc_interrupt_7705(void) __attribute__((section(".gint.int")));
|
|||
void rtc_interrupt_7305(void) __attribute__((section(".gint.int")));
|
||||
|
||||
/*
|
||||
rtc_setFrequency()
|
||||
Sets the RTC interrupt frequency and enables interrupts.
|
||||
rtc_cb_interrupt()
|
||||
Handles an RTC interrupt. Calls the RTC callbacks if necessary, and
|
||||
updates the repeat counts.
|
||||
*/
|
||||
void rtc_setFrequency_7705(enum RTCFrequency frequency);
|
||||
void rtc_setFrequency_7305(enum RTCFrequency frequency);
|
||||
|
||||
/*
|
||||
rtc_getFrequency()
|
||||
Returns the RTC interrupt frequency.
|
||||
*/
|
||||
enum RTCFrequency rtc_getFrequency_7705(void);
|
||||
enum RTCFrequency rtc_getFrequency_7305(void);
|
||||
void rtc_cb_interrupt(void);
|
||||
|
||||
#endif // _RTC_H
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#ifndef _TIMER_H
|
||||
#define _TIMER_H 1
|
||||
|
||||
#include <clock.h>
|
||||
|
||||
//---
|
||||
// Constants.
|
||||
//---
|
||||
|
|
|
@ -121,6 +121,7 @@ void sleep_us(int us_delay)
|
|||
// Indicates whether the measurements are finished.
|
||||
static volatile int clock_measure_done = 0;
|
||||
// Once again SH7705 and SH7305 need different methods...
|
||||
static int cb_id_7705 = -1;
|
||||
static void clock_measure_7705();
|
||||
static void clock_compute_7305();
|
||||
|
||||
|
@ -136,9 +137,8 @@ void clock_measure(void)
|
|||
{
|
||||
// We prepare the timer manually, without starting it, so that
|
||||
// we only have to push the running bit to start it when the
|
||||
// measurements begin. This might look of little effect but the
|
||||
// timer configuration time (lost from the measurement) would
|
||||
// make the precision no more than 97-98%.
|
||||
// measurements begin. This might look of little effect but it
|
||||
// makes the precision jump from ~97% to more than 99%.
|
||||
volatile struct mod_tmu *tmu;
|
||||
timer_get(TIMER_USER, &tmu, NULL);
|
||||
|
||||
|
@ -153,7 +153,7 @@ void clock_measure(void)
|
|||
timers[TIMER_USER].callback = NULL;
|
||||
timers[TIMER_USER].repeats = 0;
|
||||
|
||||
rtc_setCallback(clock_measure_7705, RTCFreq_256Hz);
|
||||
cb_id_7705 = rtc_cb_add(RTCFreq_256Hz, clock_measure_7705, 0);
|
||||
}
|
||||
|
||||
// On SH7305, assuming clock mode 3, we can compute the clock
|
||||
|
@ -261,7 +261,7 @@ static void clock_measure_7705_finalize(int elapsed)
|
|||
static void clock_measure_7705_callback(void)
|
||||
{
|
||||
timer_stop(TIMER_USER);
|
||||
rtc_setCallback(NULL, RTCFreq_1Hz);
|
||||
rtc_cb_end(cb_id_7705);
|
||||
|
||||
volatile struct mod_tmu *tmu;
|
||||
timer_get(TIMER_USER, &tmu, NULL);
|
||||
|
@ -284,5 +284,5 @@ static void clock_measure_7705(void)
|
|||
timer_get(TIMER_USER, NULL, &tstr);
|
||||
|
||||
*tstr |= (1 << TIMER_USER);
|
||||
rtc_setCallback(clock_measure_7705_callback, RTCFreq_256Hz);
|
||||
rtc_cb_edit(cb_id_7705, RTCFreq_256Hz, clock_measure_7705_callback);
|
||||
}
|
||||
|
|
|
@ -31,6 +31,12 @@ _free:
|
|||
nop
|
||||
1: .long 0xacc
|
||||
|
||||
_realloc:
|
||||
mov.l syscall_table, r2
|
||||
mov.l 1f, r0
|
||||
jmp @r2
|
||||
nop
|
||||
1: .long 0xe6d
|
||||
|
||||
|
||||
.align 4
|
||||
|
|
|
@ -1,18 +1,7 @@
|
|||
#include <internals/keyboard.h>
|
||||
#include <keyboard.h>
|
||||
#include <clock.h>
|
||||
#include <timer.h>
|
||||
|
||||
/*
|
||||
keyboard_setFrequency()
|
||||
Sets the keyboard frequency (in Hz).
|
||||
*/
|
||||
void keyboard_setFrequency(int frequency)
|
||||
{
|
||||
int setting = clock_setting(frequency, Clock_Hz);
|
||||
if(setting <= 0) return;
|
||||
timer_reload(TIMER_KEYBOARD, setting);
|
||||
}
|
||||
#include <rtc.h>
|
||||
|
||||
/*
|
||||
keyboard_setRepeatRate()
|
||||
|
|
|
@ -17,6 +17,10 @@ volatile int interrupt_flag = 0;
|
|||
int repeat_first = 10, repeat_next = 2;
|
||||
int last_key = KEY_NONE, last_repeats = 0, last_events = 0;
|
||||
|
||||
// RTC callback id.
|
||||
unsigned cb_id;
|
||||
|
||||
|
||||
|
||||
//---
|
||||
// Interrupt management.
|
||||
|
@ -43,8 +47,17 @@ void keyboard_interrupt(void)
|
|||
*/
|
||||
void keyboard_init(void)
|
||||
{
|
||||
int delay = clock_setting(16, Clock_Hz);
|
||||
timer_start(TIMER_KEYBOARD, delay, TIMER_Po_4, keyboard_interrupt, 0);
|
||||
cb_id = rtc_cb_add(RTCFreq_16Hz, keyboard_interrupt, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
keyboard_setFrequency()
|
||||
Sets the keyboard frequency.
|
||||
*/
|
||||
void keyboard_setFrequency(enum KeyboardFrequency frequency)
|
||||
{
|
||||
if(frequency < 1 || frequency > 7) return;
|
||||
rtc_cb_edit(cb_id, frequency, keyboard_interrupt);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -53,5 +66,5 @@ void keyboard_init(void)
|
|||
*/
|
||||
void keyboard_quit(void)
|
||||
{
|
||||
timer_stop(TIMER_KEYBOARD);
|
||||
rtc_cb_end(cb_id);
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
//---
|
||||
|
||||
#include <internals/gint.h>
|
||||
#include <internals/rtc.h>
|
||||
#include <gint.h>
|
||||
#include <timer.h>
|
||||
#include <7305.h>
|
||||
|
@ -194,18 +195,22 @@ static void gint_priority_unlock_7305(void)
|
|||
|
||||
void gint_setup_7305(void)
|
||||
{
|
||||
volatile struct mod_rtc *RTC = RTC_SH7305;
|
||||
|
||||
gint_priority_lock_7305();
|
||||
|
||||
// Saving the RTC configuration.
|
||||
rcr2 = RTC.RCR2.BYTE;
|
||||
rcr2 = RTC->RCR2.BYTE;
|
||||
// Disabling RTC interrupts by default.
|
||||
RTC.RCR2.BYTE = 0x09;
|
||||
RTC->RCR2.BYTE = 0x09;
|
||||
}
|
||||
|
||||
void gint_stop_7305(void)
|
||||
{
|
||||
volatile struct mod_rtc *RTC = RTC_SH7305;
|
||||
|
||||
gint_priority_unlock_7305();
|
||||
|
||||
// Restoring the RTC configuration.
|
||||
RTC.RCR2.BYTE = rcr2;
|
||||
RTC->RCR2.BYTE = rcr2;
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
//---
|
||||
|
||||
#include <internals/gint.h>
|
||||
#include <internals/rtc.h>
|
||||
#include <gint.h>
|
||||
#include <timer.h>
|
||||
#include <7705.h>
|
||||
|
@ -165,18 +166,22 @@ static void gint_priority_unlock_7705(void)
|
|||
|
||||
void gint_setup_7705(void)
|
||||
{
|
||||
volatile struct mod_rtc *RTC = RTC_SH7705;
|
||||
|
||||
gint_priority_lock_7705();
|
||||
|
||||
// Saving the RTC configuration.
|
||||
rcr2 = RTC.RCR2.BYTE;
|
||||
rcr2 = RTC->RCR2.BYTE;
|
||||
// Disabling RTC interrupts by default.
|
||||
RTC.RCR2.BYTE = 0x09;
|
||||
RTC->RCR2.BYTE = 0x09;
|
||||
}
|
||||
|
||||
void gint_stop_7705(void)
|
||||
{
|
||||
volatile struct mod_rtc *RTC = RTC_SH7705;
|
||||
|
||||
gint_priority_unlock_7705();
|
||||
|
||||
// Restoring the RTC configuration.
|
||||
RTC.RCR2.BYTE = rcr2;
|
||||
RTC->RCR2.BYTE = rcr2;
|
||||
}
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
#include <7305.h>
|
||||
#include <rtc.h>
|
||||
|
||||
//---
|
||||
// Various MPU-dependent procedures.
|
||||
//---
|
||||
|
||||
/*
|
||||
rtc_setFrequency()
|
||||
Sets the RTC interrupt frequency and enables interrupts.
|
||||
*/
|
||||
void rtc_setFrequency_7305(enum RTCFrequency frequency)
|
||||
{
|
||||
if(frequency < 1 || frequency > 7) return;
|
||||
RTC.RCR2.BYTE = (frequency << 4) | 0x09;
|
||||
}
|
||||
|
||||
/*
|
||||
rtc_getFrequency()
|
||||
Returns the RTC interrupt frequency.
|
||||
*/
|
||||
enum RTCFrequency rtc_getFrequency_7305(void)
|
||||
{
|
||||
return (RTC.RCR2.BYTE & 0x70) >> 4;
|
||||
}
|
||||
|
||||
/*
|
||||
rtc_interrupt()
|
||||
Handles an RTC interrupt by calling the callback.
|
||||
*/
|
||||
void rtc_interrupt_7305(void)
|
||||
{
|
||||
RTC.RCR2.PEF = 0;
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
#include <7705.h>
|
||||
#include <rtc.h>
|
||||
|
||||
//---
|
||||
// Various MPU-dependent procedures.
|
||||
//---
|
||||
|
||||
/*
|
||||
rtc_setFrequency()
|
||||
Sets the RTC interrupt frequency and enables interrupts.
|
||||
*/
|
||||
void rtc_setFrequency_7705(enum RTCFrequency frequency)
|
||||
{
|
||||
if(frequency < 1 || frequency > 7) return;
|
||||
RTC.RCR2.BYTE = (frequency << 4) | 0x09;
|
||||
}
|
||||
|
||||
/*
|
||||
rtc_getFrequency()
|
||||
Returns the RTC interrupt frequency.
|
||||
*/
|
||||
enum RTCFrequency rtc_getFrequency_7705(void)
|
||||
{
|
||||
return (RTC.RCR2.BYTE & 0x70) >> 4;
|
||||
}
|
||||
|
||||
/*
|
||||
rtc_interrupt()
|
||||
Handles an RTC interrupt by calling the callback.
|
||||
*/
|
||||
void rtc_interrupt_7705(void)
|
||||
{
|
||||
RTC.RCR2.BIT.PEF = 0;
|
||||
}
|
151
src/rtc/rtc_callback.c
Normal file
151
src/rtc/rtc_callback.c
Normal file
|
@ -0,0 +1,151 @@
|
|||
#include <internals/rtc.h>
|
||||
#include <rtc.h>
|
||||
#include <mpu.h>
|
||||
|
||||
// Array holding callback informations.
|
||||
struct rtc_cb cb_array[RTC_CB_ARRAY_SIZE] = { 0 };
|
||||
// Callback identifier (unique).
|
||||
static int unique_id = 1;
|
||||
// Current RTC interrupt frequency.
|
||||
static enum RTCFrequency rtc_freq = RTCFreq_None;
|
||||
// 256-Hz tick count. This counter is stopped when no callback is registered.
|
||||
static unsigned elapsed256 = 0;
|
||||
|
||||
/*
|
||||
rtc_cb_update()
|
||||
After successful registration or deletion of a callback, updates the
|
||||
RTC interrupt frequency stored in register RCR2. After update, the
|
||||
interrupt frequency is high enough to handle all callbacks, but nothing
|
||||
more (so that no time is wasted handling interrupts that occur too
|
||||
often).
|
||||
*/
|
||||
static void rtc_cb_update(void)
|
||||
{
|
||||
enum RTCFrequency max = RTCFreq_None;
|
||||
int n;
|
||||
|
||||
for(n = 0; n < RTC_CB_ARRAY_SIZE; n++) if(cb_array[n].id)
|
||||
{
|
||||
if(!max || (cb_array[n].freq && cb_array[n].freq < max))
|
||||
max = cb_array[n].freq;
|
||||
}
|
||||
|
||||
if(rtc_freq == max) return;
|
||||
rtc_freq = max;
|
||||
|
||||
volatile struct mod_rtc *RTC = isSH3() ? RTC_SH7705 : RTC_SH7305;
|
||||
RTC->RCR2.BYTE = (rtc_freq << 4) | 0x09;
|
||||
}
|
||||
|
||||
/*
|
||||
rtc_cb_add()
|
||||
Registers a new callback for the RTC. Returns the callback id on
|
||||
success (positive integer), or one of the following error codes:
|
||||
-1 Array is full
|
||||
-2 Invalid parameter
|
||||
The number of repeats may be set to 0, in which case the callback is
|
||||
called indefinitely unless the user calls rtc_cb_end().
|
||||
*/
|
||||
int rtc_cb_add(enum RTCFrequency freq, void (*function)(void), int repeats)
|
||||
{
|
||||
int n = 0;
|
||||
if(freq == RTCFreq_None || !function || repeats < 0) return -2;
|
||||
|
||||
while(n < RTC_CB_ARRAY_SIZE && cb_array[n].id) n++;
|
||||
if(n >= RTC_CB_ARRAY_SIZE) return -1;
|
||||
|
||||
cb_array[n].freq = freq;
|
||||
cb_array[n].callback = function;
|
||||
cb_array[n].repeats = repeats;
|
||||
cb_array[n].id = unique_id++;
|
||||
|
||||
rtc_cb_update();
|
||||
|
||||
return cb_array[n].id;
|
||||
}
|
||||
|
||||
/*
|
||||
rtc_cb_end()
|
||||
Removes the callback with the given id (as returned by rtc_cb_add())
|
||||
from the callback array.
|
||||
*/
|
||||
void rtc_cb_end(int id)
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
while(n < RTC_CB_ARRAY_SIZE && cb_array[n].id != id) n++;
|
||||
if(n >= RTC_CB_ARRAY_SIZE) return;
|
||||
|
||||
cb_array[n].id = 0;
|
||||
cb_array[n].freq = RTCFreq_None;
|
||||
cb_array[n].callback = NULL;
|
||||
cb_array[n].repeats = 0;
|
||||
|
||||
rtc_cb_update();
|
||||
}
|
||||
|
||||
/*
|
||||
rtc_cb_edit()
|
||||
Changes information related to a callback. This function returns 0 on
|
||||
success, or one of the following error codes:
|
||||
-1 Callback does not exist
|
||||
-2 Invalid parameters
|
||||
This function never removes a callback. Call rtc_cb_end() for this.
|
||||
*/
|
||||
int rtc_cb_edit(int id, enum RTCFrequency new_freq,
|
||||
void (*new_function)(void))
|
||||
{
|
||||
if(new_freq < 0 || new_freq > 7) return -2;
|
||||
int n = 0;
|
||||
|
||||
while(n < RTC_CB_ARRAY_SIZE && cb_array[n].id != id) n++;
|
||||
if(n >= RTC_CB_ARRAY_SIZE) return -1;
|
||||
|
||||
cb_array[n].freq = new_freq;
|
||||
cb_array[n].callback = new_function;
|
||||
rtc_cb_update();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
rtc_cb_interrupt()
|
||||
Handles an RTC interrupt. Calls the RTC callbacks if necessary, and
|
||||
updates the repeat counts.
|
||||
*/
|
||||
void rtc_cb_interrupt(void)
|
||||
{
|
||||
int n;
|
||||
|
||||
int scales[] = {
|
||||
1, // 256 Hz
|
||||
4, // 64 Hz
|
||||
16, // 16 Hz
|
||||
64, // 4 Hz
|
||||
128, // 2 Hz
|
||||
256, // 1 Hz
|
||||
512, // 0.5 Hz
|
||||
};
|
||||
// Adding to elapsed256 the number of 256-Hz ticks that correspond to
|
||||
// the current interrupt frequency, and rounding the result to a
|
||||
// multiple of this tick number.
|
||||
elapsed256 = (elapsed256 + scales[rtc_freq]) & ~(scales[rtc_freq] - 1);
|
||||
|
||||
for(n = 0; n < RTC_CB_ARRAY_SIZE; n++)
|
||||
{
|
||||
struct rtc_cb *cb = &cb_array[n];
|
||||
if(!cb->id || !cb->freq) continue;
|
||||
|
||||
// Only execute callback when the number of elapsed 256-Hz
|
||||
// ticks reach a multiple that correspond to the callback
|
||||
// frequency.
|
||||
if(elapsed256 & (scales[cb->freq] - 1)) continue;
|
||||
|
||||
if(cb->callback) (*cb->callback)();
|
||||
if(cb->repeats)
|
||||
{
|
||||
if(cb->repeats == 1) rtc_cb_end(cb->id);
|
||||
else cb->repeats--;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,63 +1,15 @@
|
|||
#include <internals/rtc.h>
|
||||
#include <rtc.h>
|
||||
#include <mpu.h>
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
static void (*rtc_callback)(void) = NULL;
|
||||
|
||||
//---
|
||||
// Callback API.
|
||||
//---
|
||||
|
||||
/*
|
||||
rtc_setCallback()
|
||||
Sets the callback function for the real-time clock interrupt. If
|
||||
frequency is non-NULL, the clock frequency is set to the given value.
|
||||
*/
|
||||
void rtc_setCallback(void (*callback)(void), enum RTCFrequency frequency)
|
||||
{
|
||||
rtc_callback = callback;
|
||||
if(frequency < 1 || frequency > 7) return;
|
||||
|
||||
if(isSH3())
|
||||
rtc_setFrequency_7705(frequency);
|
||||
else
|
||||
rtc_setFrequency_7305(frequency);
|
||||
}
|
||||
|
||||
/*
|
||||
rtc_getCallback()
|
||||
Returns the callback function. If frequency is non-NULL, it is set to
|
||||
the current frequency value.
|
||||
*/
|
||||
void (*rtc_getCallback(enum RTCFrequency *frequency))(void)
|
||||
{
|
||||
if(!frequency) return rtc_callback;
|
||||
|
||||
if(isSH3())
|
||||
*frequency = rtc_getFrequency_7705();
|
||||
else
|
||||
*frequency = rtc_getFrequency_7305();
|
||||
|
||||
return rtc_callback;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//---
|
||||
// Interrupt management.
|
||||
//---
|
||||
|
||||
/*
|
||||
rtc_interrupt()
|
||||
Handles an RTC interrupt by calling the callback.
|
||||
*/
|
||||
void rtc_interrupt(void)
|
||||
{
|
||||
if(rtc_callback) (*rtc_callback)();
|
||||
rtc_cb_interrupt();
|
||||
|
||||
if(isSH3())
|
||||
rtc_interrupt_7705();
|
||||
else
|
||||
rtc_interrupt_7305();
|
||||
volatile struct mod_rtc *RTC = isSH3() ? RTC_SH7705 : RTC_SH7305;
|
||||
RTC->RCR2.PEF = 0;
|
||||
}
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
*/
|
||||
void text_configure(struct Font *next_font, enum Color next_color)
|
||||
{
|
||||
extern Font gint_font_system_start;
|
||||
extern Font gint_font_system;
|
||||
if(next_font) font = next_font;
|
||||
else font = &gint_font_system_start;
|
||||
else font = &gint_font_system;
|
||||
|
||||
color = next_color;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue