mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2024-12-28 04:23:36 +01:00
Displayed keyboard state in test [1]. Implemented some API for user RTC interrupt management.
This commit is contained in:
parent
9725c2819a
commit
e1a51dae21
18 changed files with 301 additions and 79 deletions
4
TODO
4
TODO
|
@ -1,9 +1,11 @@
|
|||
- multi-getkey repeats (if possible, which doesn't seem likely)
|
||||
- getkey() may unwantedly repeat a key if it was triggered for multigetkey()
|
||||
|
||||
- write and test gray engine
|
||||
- full rtc driver (time)
|
||||
- callbacks and complete user API
|
||||
|
||||
- exhaustive save for setjmp()
|
||||
- registers that need to be saved when configuring gint
|
||||
|
||||
_ 7305.h
|
||||
_ libc
|
||||
|
|
40
ginttest.c
40
ginttest.c
|
@ -17,7 +17,7 @@ void print_clear(void)
|
|||
{
|
||||
char *empty_line = " ";
|
||||
int i = 0;
|
||||
while(i < 8) print(empty_line, 0, i++);
|
||||
while(i < 8) __Print(empty_line, 0, i++);
|
||||
}
|
||||
void print(const char *str, int x, int y)
|
||||
{
|
||||
|
@ -66,30 +66,38 @@ void print_hexa(unsigned int n, int digits, int x, int y)
|
|||
|
||||
/*
|
||||
Keyboard tests.
|
||||
The user timer reproduces the parameters of the keyboard timer.
|
||||
*/
|
||||
|
||||
void keyboard_test_timer(void)
|
||||
{
|
||||
volatile unsigned char *state = keystate();
|
||||
|
||||
print_bin(state[0], 0, 1);
|
||||
print_bin(state[1], 0, 2);
|
||||
print_bin(state[2], 0, 3);
|
||||
print_bin(state[3], 0, 4);
|
||||
print_bin(state[4], 0, 5);
|
||||
|
||||
print_bin(state[5], 9, 1);
|
||||
print_bin(state[6], 9, 2);
|
||||
print_bin(state[7], 9, 3);
|
||||
print_bin(state[8], 9, 4);
|
||||
print_bin(state[9], 9, 5);
|
||||
}
|
||||
|
||||
void keyboard_test(void)
|
||||
{
|
||||
/*
|
||||
print_bin(keyboard_state[0], 0, 2);
|
||||
print_bin(keyboard_state[1], 0, 3);
|
||||
print_bin(keyboard_state[2], 0, 4);
|
||||
print_bin(keyboard_state[3], 0, 5);
|
||||
print_bin(keyboard_state[4], 0, 6);
|
||||
|
||||
print_bin(keyboard_state[5], 9, 2);
|
||||
print_bin(keyboard_state[6], 9, 3);
|
||||
print_bin(keyboard_state[7], 9, 4);
|
||||
print_bin(keyboard_state[8], 9, 5);
|
||||
print_bin(keyboard_state[9], 9, 6);
|
||||
*/
|
||||
|
||||
int x = 0;
|
||||
char str[3];
|
||||
int keys[4] = { 0 };
|
||||
int i;
|
||||
|
||||
timer_start(TIMER_USER, 1700, TIMER_Po_256, keyboard_test_timer, 0);
|
||||
|
||||
print_clear();
|
||||
print("Keyboard state:", 0, 0);
|
||||
print("multi-getkey ^^", 6, 7);
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
@ -114,6 +122,8 @@ void keyboard_test(void)
|
|||
|
||||
#undef hexa
|
||||
}
|
||||
|
||||
timer_stop(TIMER_USER);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
BIN
ginttest.g1a
BIN
ginttest.g1a
Binary file not shown.
BIN
icon.bmp
BIN
icon.bmp
Binary file not shown.
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
|
@ -35,6 +35,12 @@ enum BlendingMode
|
|||
Blend_Checker = 0x10,
|
||||
};
|
||||
|
||||
/*
|
||||
enum ImageFormat
|
||||
Describes the various image formats available. Colors may be encoded
|
||||
as monochrome (1 layer) or gray (2 layers). Whatever the color map, any
|
||||
bitmap may also have an additional alpha layer.
|
||||
*/
|
||||
enum ImageFormat
|
||||
{
|
||||
ImageFormat_Mono = 0x01,
|
||||
|
@ -45,6 +51,13 @@ enum ImageFormat
|
|||
ImageFormat_ColorMask = 0x0f,
|
||||
};
|
||||
|
||||
/*
|
||||
struct Image
|
||||
This structure holds information about a bitmap encoded with fxconv.
|
||||
Data is accessed using longword operations, which *requires* many
|
||||
sizes to be multiples of 4 (structure alignment, data alignment, layer
|
||||
size, ...).
|
||||
*/
|
||||
struct Image
|
||||
{
|
||||
unsigned char width;
|
||||
|
@ -57,11 +70,12 @@ struct Image
|
|||
const unsigned char __attribute__((aligned(4))) data[];
|
||||
|
||||
} __attribute__((aligned(4)));
|
||||
|
||||
// Useful shorthand for user code.
|
||||
typedef struct Image Image;
|
||||
|
||||
|
||||
|
||||
// A few other constants.
|
||||
#define DISPLAY_WIDTH 128
|
||||
#define DISPLAY_HEIGHT 64
|
||||
|
||||
|
@ -73,18 +87,31 @@ typedef struct Image Image;
|
|||
|
||||
/*
|
||||
display_getLocalVRAM()
|
||||
Returns the local video ram. This address should not be used directly
|
||||
when running the gray engine.
|
||||
Returns the local video ram. This function always return the same
|
||||
address.
|
||||
The buffer returned by this function should not be used directly when
|
||||
running the gray engine.
|
||||
|
||||
@return Video ram address of the monochrome display module.
|
||||
*/
|
||||
void *display_getLocalVRAM(void);
|
||||
|
||||
/*
|
||||
display_getCurrentVRAM()
|
||||
Returns the current video ram. This function usually returns the
|
||||
parameter of the last call to display_useVRAM(), unless the gray engine
|
||||
is running (in which case the result is undefined). Returns the local
|
||||
vram address by default.
|
||||
*/
|
||||
void *display_getCurrentVRAM(void);
|
||||
|
||||
/*
|
||||
display_useVRAM()
|
||||
Changes the current video ram address. Expects a *4-aligned* 1024-byte
|
||||
buffer.
|
||||
Do not use this function while running the gray engine.
|
||||
Changes the current video ram address. The argument *MUST* be a
|
||||
4-aligned 1024 buffer ; otherwise any drawing operation will crash the
|
||||
program.
|
||||
This function will most likely have no effect when running the gray
|
||||
engine.
|
||||
|
||||
@arg New video ram address.
|
||||
*/
|
||||
|
@ -169,7 +196,7 @@ void dline(int x1, int y1, int x2, int y2, enum Color color);
|
|||
|
||||
/*
|
||||
dimage()
|
||||
Displays an image in the vram.
|
||||
Displays an image in the vram. Does a real lot of optimization.
|
||||
|
||||
@arg image
|
||||
@arg x
|
||||
|
|
|
@ -22,19 +22,38 @@ unsigned int gint_getVBR(void);
|
|||
*/
|
||||
unsigned int gint_systemVBR(void);
|
||||
|
||||
/*
|
||||
enum RTCFrequency
|
||||
Describes the possible frequencies available for the real-time clock
|
||||
interrupt.
|
||||
*/
|
||||
enum RTCFrequency
|
||||
{
|
||||
RTCFreq_500mHz = 7,
|
||||
RTCFreq_1Hz = 6,
|
||||
RTCFreq_2Hz = 5,
|
||||
RTCFreq_4Hz = 4,
|
||||
RTCFreq_16Hz = 3,
|
||||
RTCFreq_64Hz = 2,
|
||||
RTCFreq_256Hz = 1,
|
||||
};
|
||||
|
||||
/*
|
||||
gint_setRTCCallback()
|
||||
Sets the callback function for the real-time clock interrupt. If
|
||||
frequency is non-NULL, the clock frequency is set to the given value.
|
||||
|
||||
@arg callback Callback function.
|
||||
@arg frequency Interrupt frequency.
|
||||
*/
|
||||
void gint_setRTCCallback(void (*callback)(void), enum GintFrequency frequency);
|
||||
void gint_setRTCCallback(void (*callback)(void), enum RTCFrequency frequency);
|
||||
|
||||
/*
|
||||
gint_getRTCCallback()
|
||||
Returns the callback function. If frequency is non-NULL, it is set to
|
||||
the current frequency value.
|
||||
*/
|
||||
void (*(gint_getRTCCallback)(void))(enum GintFrequency *frequency);
|
||||
void (*gint_getRTCCallback(enum RTCFrequency *frequency))(void);
|
||||
|
||||
|
||||
|
||||
|
@ -89,12 +108,28 @@ void gint_stop_7305(void);
|
|||
gint()
|
||||
Handles interrupts.
|
||||
*/
|
||||
void gint(void) __attribute__((
|
||||
section(".gint.int.entry"),
|
||||
interrupt_handler
|
||||
));
|
||||
void gint_7705(void) __attribute__((section(".gint.int")));
|
||||
void gint_7305(void) __attribute__((section(".gint.int")));
|
||||
void gint(void) __attribute__((section(".gint.int.entry"),
|
||||
interrupt_handler));
|
||||
void gint_7705(void) __attribute__((section(".gint.int")));
|
||||
void gint_7305(void) __attribute__((section(".gint.int")));
|
||||
|
||||
/*
|
||||
gint_setRTCFrequency()
|
||||
Sets the RTC interrupt frequency and enables interrupts.
|
||||
|
||||
@arg frequency
|
||||
*/
|
||||
void gint_setRTCFrequency_7705(enum RTCFrequency frequency);
|
||||
void gint_setRTCFrequency_7305(enum RTCFrequency frequency);
|
||||
|
||||
/*
|
||||
gint_getRTCFrequency()
|
||||
Returns the RTC interrupt frequency.
|
||||
|
||||
@return RTC interrupt frequency.
|
||||
*/
|
||||
enum RTCFrequency gint_getRTCFrequency_7705(void);
|
||||
enum RTCFrequency gint_getRTCFrequency_7305(void);
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -49,4 +49,17 @@ extern enum MPU MPU_CURRENT;
|
|||
*/
|
||||
enum MPU getMPU(void);
|
||||
|
||||
|
||||
|
||||
//---
|
||||
// Internal API.
|
||||
// Referenced here for documentation purposes only. Do not call.
|
||||
//---
|
||||
|
||||
/*
|
||||
mpu_init()
|
||||
Determines the MPU type and stores the result into MPU_CURRENT.
|
||||
*/
|
||||
void mpu_init(void) __attribute__((constructor));
|
||||
|
||||
#endif // _MPU_H
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#ifndef _SCREEN_H
|
||||
#define _SCREEN_H 1
|
||||
|
||||
//---
|
||||
// Public API.
|
||||
//---
|
||||
|
||||
/*
|
||||
screen_display()
|
||||
Displays contents on the full screen. Expects a 1024-byte buffer.
|
||||
|
|
|
@ -17,7 +17,7 @@ typedef unsigned int jmp_buf[16];
|
|||
|
||||
@arg env Empty jump buffer.
|
||||
*/
|
||||
int setjmp(jmp_buf env);
|
||||
int setjmp(jmp_buf env);
|
||||
|
||||
/*
|
||||
longjmp()
|
||||
|
@ -26,6 +26,6 @@ int setjmp(jmp_buf env);
|
|||
@arg env Jump buffer configure with setjmp().
|
||||
@arg value setjmp() will return this integer after the jump.
|
||||
*/
|
||||
void longjmp(jmp_buf env, int value);
|
||||
void longjmp(jmp_buf env, int value);
|
||||
|
||||
#endif // _SETJMP_H
|
||||
|
|
BIN
libc.a
BIN
libc.a
Binary file not shown.
BIN
libgint.a
BIN
libgint.a
Binary file not shown.
|
@ -41,7 +41,7 @@ static int *vram = local_vram;
|
|||
|
||||
|
||||
//---
|
||||
// Local helper functions.
|
||||
// Local functions.
|
||||
//---
|
||||
|
||||
/*
|
||||
|
@ -115,14 +115,25 @@ static void getmasks(int x1, int x2, unsigned int *masks)
|
|||
//---
|
||||
|
||||
/*
|
||||
display_getVRAM()
|
||||
Returns the current video ram.
|
||||
display_getLocalVRAM()
|
||||
Returns the local video ram.
|
||||
|
||||
@return Video ram address.
|
||||
*/
|
||||
void *display_getLocalVRAM(void)
|
||||
{
|
||||
return (void*)local_vram;
|
||||
return (void *)local_vram;
|
||||
}
|
||||
|
||||
/*
|
||||
display_getCurrentVRAM()
|
||||
Returns the current vido ram.
|
||||
|
||||
@return Video ram address.
|
||||
*/
|
||||
void *display_getCurrentVRAM(void)
|
||||
{
|
||||
return (void *)vram;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -370,7 +381,7 @@ void dline(int x1, int y1, int x2, int y2, enum Color color)
|
|||
// the same : get a part of the image in an operator, shift it depending
|
||||
// on the drawing x-coordinate, compute a mask that indicates which bits
|
||||
// of the operator contain information, and modify a vram long using the
|
||||
// operator.
|
||||
// operator and the mask.
|
||||
//---
|
||||
|
||||
/*
|
||||
|
|
39
src/gint.c
39
src/gint.c
|
@ -1,6 +1,7 @@
|
|||
#include <gint.h>
|
||||
#include <mpu.h>
|
||||
#include <gray.h>
|
||||
#include <stddef.h>
|
||||
|
||||
//---
|
||||
// Local variables.
|
||||
|
@ -10,6 +11,8 @@ static unsigned int
|
|||
new_vbr,
|
||||
sys_vbr;
|
||||
|
||||
static void (*rtc_callback)(void) = NULL;
|
||||
|
||||
|
||||
|
||||
//---
|
||||
|
@ -60,6 +63,42 @@ unsigned int gint_systemVBR(void)
|
|||
return sys_vbr;
|
||||
}
|
||||
|
||||
/*
|
||||
gint_setRTCCallback()
|
||||
Sets the callback function for the real-time clock interrupt. If
|
||||
frequency is non-NULL, the clock frequency is set to the given value.
|
||||
|
||||
@arg callback Callback function.
|
||||
@arg frequency Interrupt frequency.
|
||||
*/
|
||||
void gint_setRTCCallback(void (*callback)(void), enum RTCFrequency frequency)
|
||||
{
|
||||
if(frequency < 1 || frequency > 7) return;
|
||||
rtc_callback = callback;
|
||||
|
||||
if(isSH3())
|
||||
gint_setRTCFrequency_7705(frequency);
|
||||
else
|
||||
gint_setRTCFrequency_7305(frequency);
|
||||
}
|
||||
|
||||
/*
|
||||
gint_getRTCCallback()
|
||||
Returns the callback function. If frequency is non-NULL, it is set to
|
||||
the current frequency value.
|
||||
*/
|
||||
void (*gint_getRTCCallback(enum RTCFrequency *frequency))(void)
|
||||
{
|
||||
if(!frequency) return rtc_callback;
|
||||
|
||||
if(isSH3())
|
||||
*frequency = gint_getRTCFrequency_7705();
|
||||
else
|
||||
*frequency = gint_getRTCFrequency_7305();
|
||||
|
||||
return rtc_callback;
|
||||
}
|
||||
|
||||
/*
|
||||
gint()
|
||||
Handles interrupts.
|
||||
|
|
|
@ -15,6 +15,35 @@
|
|||
|
||||
|
||||
|
||||
//---
|
||||
// Various MPU-dependent procedures.
|
||||
//---
|
||||
|
||||
/*
|
||||
gint_setRTCFrequency()
|
||||
Sets the RTC interrupt frequency and enables interrupts.
|
||||
|
||||
@arg frequency
|
||||
*/
|
||||
void gint_setRTCFrequency_7305(enum RTCFrequency frequency)
|
||||
{
|
||||
if(frequency < 1 || frequency > 7) return;
|
||||
RTC.RCR2.BYTE = (frequency << 4) | 0x09;
|
||||
}
|
||||
|
||||
/*
|
||||
gint_getRTCFrequency()
|
||||
Returns the RTC interrupt frequency.
|
||||
|
||||
@return RTC interrupt frequency.
|
||||
*/
|
||||
enum RTCFrequency gint_getRTCFrequency_7305(void)
|
||||
{
|
||||
return (RTC.RCR2.BYTE & 0x70) >> 4;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//---
|
||||
// Keyboard management.
|
||||
//---
|
||||
|
@ -272,15 +301,16 @@ void gint_setup_7305(void)
|
|||
{
|
||||
gint_priority_lock_7305();
|
||||
|
||||
// Configuring the RTC to have a 16-Hz keyboard.
|
||||
// Saving the RTC configuration.
|
||||
rcr2 = RTC.RCR2.BYTE;
|
||||
RTC.RCR2.BYTE = 0x39;
|
||||
// Disabling RTC interrupts by default.
|
||||
RTC.RCR2.BYTE = 0x09;
|
||||
}
|
||||
|
||||
void gint_stop_7305(void)
|
||||
{
|
||||
gint_priority_unlock_7305();
|
||||
|
||||
// Stopping the RTC interrupt.
|
||||
// Restoring the RTC configuration.
|
||||
RTC.RCR2.BYTE = rcr2;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,35 @@
|
|||
|
||||
|
||||
|
||||
//---
|
||||
// Various MPU-dependent procedures.
|
||||
//---
|
||||
|
||||
/*
|
||||
gint_setRTCFrequency()
|
||||
Sets the RTC interrupt frequency and enables interrupts.
|
||||
|
||||
@arg frequency
|
||||
*/
|
||||
void gint_setRTCFrequency_7705(enum RTCFrequency frequency)
|
||||
{
|
||||
if(frequency < 1 || frequency > 7) return;
|
||||
RTC.RCR2.BYTE = (frequency << 4) | 0x09;
|
||||
}
|
||||
|
||||
/*
|
||||
gint_getRTCFrequency()
|
||||
Returns the RTC interrupt frequency.
|
||||
|
||||
@return RTC interrupt frequency.
|
||||
*/
|
||||
enum RTCFrequency gint_getRTCFrequency_7705(void)
|
||||
{
|
||||
return (RTC.RCR2.BYTE & 0x70) >> 4;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//---
|
||||
// Keyboard management.
|
||||
//---
|
||||
|
@ -22,7 +51,7 @@
|
|||
/*
|
||||
kdelay()
|
||||
Used to be a low-level sleep using the watchdog, as in the system. This
|
||||
way seems ok at least, and it doesn't create column effects as for
|
||||
way seems OK at least, and it doesn't create column effects as for
|
||||
SH7305.
|
||||
*/
|
||||
static void kdelay(void)
|
||||
|
@ -181,6 +210,7 @@ void gint_7705(void)
|
|||
//---
|
||||
|
||||
static unsigned short iprs[8];
|
||||
static unsigned char rcr2;
|
||||
|
||||
static void gint_priority_lock_7705(void)
|
||||
{
|
||||
|
@ -230,11 +260,16 @@ void gint_setup_7705(void)
|
|||
{
|
||||
gint_priority_lock_7705();
|
||||
|
||||
// Configuring the RTC to have a 16-Hz keyboard.
|
||||
RTC.RCR2.BYTE = 0x39;
|
||||
// Saving the RTC configuration.
|
||||
rcr2 = RTC.RCR2.BYTE;
|
||||
// Disabling RTC interrupts by default.
|
||||
RTC.RCR2.BYTE = 0x09;
|
||||
}
|
||||
|
||||
void gint_stop_7705(void)
|
||||
{
|
||||
gint_priority_unlock_7705();
|
||||
|
||||
// Restoring the RTC configuration.
|
||||
RTC.RCR2.BYTE = rcr2;
|
||||
}
|
||||
|
|
|
@ -214,7 +214,7 @@ int keylast(int *repeat_count)
|
|||
/*
|
||||
keystate()
|
||||
Returns the address of the keyboard state array. The returned address
|
||||
if the handler's buffer, therefore it contains volatile data.
|
||||
is the handler's buffer, therefore it contains volatile data.
|
||||
|
||||
@return 10-byte keyboard state buffer.
|
||||
*/
|
||||
|
|
12
src/mpu.c
12
src/mpu.c
|
@ -63,13 +63,13 @@ enum MPU getMPU(void)
|
|||
return MPU_Unknown;
|
||||
}
|
||||
|
||||
static void mpu_init(void)
|
||||
__attribute__((
|
||||
section(".pretext"),
|
||||
constructor
|
||||
));
|
||||
|
||||
static void mpu_init(void)
|
||||
|
||||
/*
|
||||
mpu_init()
|
||||
Determines the MPU type and stores the result into MPU_CURRENT.
|
||||
*/
|
||||
void mpu_init(void)
|
||||
{
|
||||
MPU_CURRENT = getMPU();
|
||||
}
|
||||
|
|
72
src/timer.c
72
src/timer.c
|
@ -2,9 +2,14 @@
|
|||
#include <mpu.h>
|
||||
#include <stddef.h>
|
||||
|
||||
//---
|
||||
// Internal declarations.
|
||||
// Timer structure and running information (callbacks, repeats etc.)
|
||||
//---
|
||||
|
||||
/*
|
||||
struct Timer
|
||||
This structure handles a running timer information.
|
||||
This structure holds information for a running timer.
|
||||
*/
|
||||
struct Timer
|
||||
{
|
||||
|
@ -17,7 +22,8 @@ static struct Timer timers[3] = { { NULL, 0 }, { NULL, 0 }, { NULL, 0 } };
|
|||
|
||||
/*
|
||||
struct mod_tmu
|
||||
This structure allows access to a timer using its address.
|
||||
This structure holds information about the timer unit (peripheral
|
||||
module) registers.
|
||||
*/
|
||||
struct mod_tmu
|
||||
{
|
||||
|
@ -48,6 +54,10 @@ struct mod_tmu
|
|||
|
||||
|
||||
|
||||
//---
|
||||
// Internal API.
|
||||
//---
|
||||
|
||||
/*
|
||||
timer_get()
|
||||
|
||||
|
@ -57,7 +67,7 @@ struct mod_tmu
|
|||
@arg tmu mod_tmu structure pointer address.
|
||||
@arg tstr mod_tstr structure pointer address.
|
||||
*/
|
||||
void timer_get(int timer, struct mod_tmu **tmu, unsigned char **tstr)
|
||||
static void timer_get(int timer, struct mod_tmu **tmu, unsigned char **tstr)
|
||||
{
|
||||
// Using SH7705 information for SH-3-based MPUs.
|
||||
if(MPU_CURRENT == MPU_SH7337 || MPU_CURRENT == MPU_SH7355)
|
||||
|
@ -76,6 +86,37 @@ void timer_get(int timer, struct mod_tmu **tmu, unsigned char **tstr)
|
|||
if(tmu) *tmu += timer;
|
||||
}
|
||||
|
||||
/*
|
||||
timer_interrupt()
|
||||
Handles the interrupt for the given timer.
|
||||
|
||||
@timer Timer that generated the interrupt.
|
||||
*/
|
||||
void timer_interrupt(int timer)
|
||||
{
|
||||
// Getting the timer address.
|
||||
struct mod_tmu *tmu;
|
||||
timer_get(timer, &tmu, NULL);
|
||||
|
||||
// Resetting the interrupt flag.
|
||||
(*tmu).TCR.UNF = 0;
|
||||
|
||||
// Calling the callback function.
|
||||
if(timers[timer].callback) timers[timer].callback();
|
||||
|
||||
// Reducing the number of repetitions left, if not infinite.
|
||||
if(!timers[timer].repetitions) return;
|
||||
// And stopping it if necessary.
|
||||
if(timers[timer].repetitions == 1) timer_stop(timer);
|
||||
else timers[timer].repetitions--;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//---
|
||||
// Public API.
|
||||
//---
|
||||
|
||||
/*
|
||||
timer_start()
|
||||
Configures and starts a timer.
|
||||
|
@ -135,28 +176,3 @@ void timer_stop(int timer)
|
|||
// Stopping the timer.
|
||||
*tstr &= ~byte;
|
||||
}
|
||||
|
||||
/*
|
||||
timer_interrupt()
|
||||
Handles the interrupt for the given timer.
|
||||
|
||||
@timer Timer that generated the interrupt.
|
||||
*/
|
||||
void timer_interrupt(int timer)
|
||||
{
|
||||
// Getting the timer address.
|
||||
struct mod_tmu *tmu;
|
||||
timer_get(timer, &tmu, NULL);
|
||||
|
||||
// Resetting the interrupt flag.
|
||||
(*tmu).TCR.UNF = 0;
|
||||
|
||||
// Calling the callback function.
|
||||
if(timers[timer].callback) timers[timer].callback();
|
||||
|
||||
// Reducing the number of repetitions left, if not infinite.
|
||||
if(!timers[timer].repetitions) return;
|
||||
// And stopping it if necessary.
|
||||
if(timers[timer].repetitions == 1) timer_stop(timer);
|
||||
else timers[timer].repetitions--;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue