mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2024-12-28 20:43:36 +01:00
Key repeat events & Timer callbacks with arguments. Fixed sleep_us().
This commit is contained in:
parent
4d0794f899
commit
0a694a1cd8
25 changed files with 264 additions and 189 deletions
19
TODO
19
TODO
|
@ -9,22 +9,21 @@ Simple improvements:
|
||||||
- demo: Try 284x124 at (-60, -28) (all disadvantages)
|
- demo: Try 284x124 at (-60, -28) (all disadvantages)
|
||||||
- display: Rectangle-based drawing functions
|
- display: Rectangle-based drawing functions
|
||||||
- time: Compute CLOCKS_PER_SEC
|
- time: Compute CLOCKS_PER_SEC
|
||||||
- events: Introduce KeyRepeat events
|
|
||||||
- string: Use cmp/str to implement memchr() (assembler examples)
|
- string: Use cmp/str to implement memchr() (assembler examples)
|
||||||
- string: Do some tests for memcmp()
|
- string: Do some tests for memcmp()
|
||||||
- core: Register more interrupts (and understand their parameters)
|
- core: Register more interrupts (and understand their parameters)
|
||||||
- rtc: Take care of carry when reading time
|
- rtc: Take care of carry when reading time
|
||||||
Larger improvements:
|
Larger improvements:
|
||||||
- errno: Introduce errno and use it more or less everywhere
|
- errno: Introduce errno and use it more or less everywhere
|
||||||
- bopti: Monochrome bitmaps blending modes
|
- bopti: Monochrome bitmaps blending modes
|
||||||
- bopti: Handle partial transparency
|
- bopti: Handle partial transparency
|
||||||
- core: Implement all callbacks and a complete user API
|
- core: Implement all callbacks and a complete user API
|
||||||
* core: Better save registers
|
* core: Better save registers
|
||||||
* core: Allow return to menu
|
* core: Allow return to menu
|
||||||
- serial: Implement a driver
|
- serial: Implement a driver
|
||||||
- usb: Implement a driver
|
- usb: Implement a driver
|
||||||
- esper: Cleaner playback, synthetizing
|
- esper: Cleaner playback, synthetizing
|
||||||
- clock: Handle overclocking (relaunch clocks when overclocking)
|
- clock: Handle overclocking (relaunch clocks when overclocking)
|
||||||
|
|
||||||
Things to investigate:
|
Things to investigate:
|
||||||
- Packed bit fields alignment
|
- Packed bit fields alignment
|
||||||
|
|
|
@ -300,7 +300,7 @@ void main_menu(int *category, int *app)
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *list_tests[] = {
|
const char *list_tests[] = {
|
||||||
"Keyboard",
|
"Keyboard and events",
|
||||||
"Gray engine",
|
"Gray engine",
|
||||||
"Image rendering",
|
"Image rendering",
|
||||||
"Text rendering",
|
"Text rendering",
|
||||||
|
@ -495,6 +495,8 @@ int main(void)
|
||||||
{
|
{
|
||||||
int category, app;
|
int category, app;
|
||||||
|
|
||||||
|
sleep_ms(2000);
|
||||||
|
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
main_menu(&category, &app);
|
main_menu(&category, &app);
|
||||||
|
@ -502,7 +504,7 @@ int main(void)
|
||||||
|
|
||||||
switch((category << 8) | app)
|
switch((category << 8) | app)
|
||||||
{
|
{
|
||||||
case 0x0101: test_keyboard(); break;
|
case 0x0101: test_keyboard_events(); break;
|
||||||
case 0x0102: test_gray(); break;
|
case 0x0102: test_gray(); break;
|
||||||
case 0x0103: test_bopti(); break;
|
case 0x0103: test_bopti(); break;
|
||||||
case 0x0104: test_tales(); break;
|
case 0x0104: test_tales(); break;
|
||||||
|
|
|
@ -46,10 +46,10 @@ void print(int x, int y, const char *format, ...);
|
||||||
//---
|
//---
|
||||||
|
|
||||||
/*
|
/*
|
||||||
test_keyboard()
|
test_keyboard_events()
|
||||||
Displays a real-time multigetkey() and the keyboard state.
|
Real-time keyboard management with events.
|
||||||
*/
|
*/
|
||||||
void test_keyboard(void);
|
void test_keyboard_events(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
test_gray()
|
test_gray()
|
||||||
|
|
|
@ -2,13 +2,9 @@
|
||||||
#include <display.h>
|
#include <display.h>
|
||||||
#include <keyboard.h>
|
#include <keyboard.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <events.h>
|
||||||
|
|
||||||
/*
|
static void draw_keyboard(volatile uint8_t *state)
|
||||||
test_keyboard()
|
|
||||||
Displays a real-time multigetkey() and the keyboard state.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void draw(volatile unsigned char *state)
|
|
||||||
{
|
{
|
||||||
int i, j, k, l;
|
int i, j, k, l;
|
||||||
int x, y;
|
int x, y;
|
||||||
|
@ -22,12 +18,16 @@ static void draw(volatile unsigned char *state)
|
||||||
if(i == 4 && j == 5) continue;
|
if(i == 4 && j == 5) continue;
|
||||||
|
|
||||||
x = 5 * j + 1;
|
x = 5 * j + 1;
|
||||||
y = 61 - 5 * i;
|
y = 59 - 5 * i;
|
||||||
|
|
||||||
|
// Space for the horizontal line.
|
||||||
|
y += 3 * (i < 7);
|
||||||
|
|
||||||
// Moving the [AC/ON] key.
|
// Moving the [AC/ON] key.
|
||||||
if(!i) x = 5 * (5) + 1, y = 61 - 5 * (4);
|
if(!i) x = 5 * (5) + 1, y = 61 - 5 * (4) + 1;
|
||||||
|
|
||||||
// Drawing a filled shape when the key is pressed.
|
// Drawing a filled shape when the key is pressed.
|
||||||
if(state[i] & (128 >> j))
|
if(state[i] & (0x80 >> j))
|
||||||
{
|
{
|
||||||
for(k = -2; k <= 2; k++) for(l = -2; l <= 2; l++)
|
for(k = -2; k <= 2; k++) for(l = -2; l <= 2; l++)
|
||||||
if(abs(k) + abs(l) <= 2)
|
if(abs(k) + abs(l) <= 2)
|
||||||
|
@ -40,9 +40,55 @@ static void draw(volatile unsigned char *state)
|
||||||
if(k || l) dpixel(x + k, y + l, Color_Black);
|
if(k || l) dpixel(x + k, y + l, Color_Black);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Binding the arrow keys together for a more visual thing.
|
||||||
|
dpixel(28, 19, Color_Black); dpixel(29, 19, Color_Black);
|
||||||
|
dpixel(28, 24, Color_Black); dpixel(29, 24, Color_Black);
|
||||||
|
dpixel(26, 21, Color_Black); dpixel(26, 22, Color_Black);
|
||||||
|
dpixel(31, 21, Color_Black); dpixel(31, 22, Color_Black);
|
||||||
|
|
||||||
|
// An horizontal line to separate parts of the keyboard.
|
||||||
|
dline(5, 28, 32, 28, Color_Black);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_keyboard(void)
|
typedef struct {
|
||||||
|
event_type_t type;
|
||||||
|
int key;
|
||||||
|
int repeats;
|
||||||
|
|
||||||
|
} enhanced_event_t;
|
||||||
|
|
||||||
|
static void push_history(enhanced_event_t *history, int size, event_t event)
|
||||||
|
{
|
||||||
|
#define event_eq(x, y) ((x).type == (y).type && (x).key == (y).key)
|
||||||
|
|
||||||
|
// Determining where the history ends.
|
||||||
|
int length = 0;
|
||||||
|
while(length < size && history[length].type != ET_None) length++;
|
||||||
|
|
||||||
|
// Checking if the previous event is being repeated.
|
||||||
|
if(length > 0 && event_eq(history[length - 1], event))
|
||||||
|
{
|
||||||
|
history[length - 1].repeats++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Making up some space if required.
|
||||||
|
if(length == size)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < size - 1; i++) history[i] = history[i + 1];
|
||||||
|
length = size - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adding a new entry to the history.
|
||||||
|
history[length].type = event.type;
|
||||||
|
history[length].key = event.key;
|
||||||
|
history[length].repeats = 1;
|
||||||
|
|
||||||
|
#undef event_eq
|
||||||
|
}
|
||||||
|
|
||||||
|
static void draw_events(enhanced_event_t *history, int size)
|
||||||
{
|
{
|
||||||
const char *key_names[] = {
|
const char *key_names[] = {
|
||||||
"F1", "F2", "F3", "F4", "F5", "F6",
|
"F1", "F2", "F3", "F4", "F5", "F6",
|
||||||
|
@ -55,28 +101,41 @@ void test_keyboard(void)
|
||||||
"1", "2", "3", "+", "-", NULL,
|
"1", "2", "3", "+", "-", NULL,
|
||||||
"0", ".", "\x08", "(-)", "EXE", NULL
|
"0", ".", "\x08", "(-)", "EXE", NULL
|
||||||
};
|
};
|
||||||
|
const char *event_names[] = {
|
||||||
|
"None ", "User ", "Press", "Rept.", "Rel. "
|
||||||
|
};
|
||||||
|
|
||||||
volatile unsigned char *state = keystate();
|
for(int i = 0; i < size && history[i].type != ET_None; i++)
|
||||||
int keys[4] = { 0 };
|
{
|
||||||
int i;
|
print(8, 3 + i, "%s %s", event_names[history[i].type],
|
||||||
|
key_names[keyid(history[i].key)]);
|
||||||
|
if(history[i].repeats > 1)
|
||||||
|
print(19, 3 + i, "%d", history[i].repeats);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
test_keyboard_events()
|
||||||
|
Real-time keyboard management with events.
|
||||||
|
*/
|
||||||
|
void test_keyboard_events(void)
|
||||||
|
{
|
||||||
|
enhanced_event_t history[5];
|
||||||
|
int history_size = 5;
|
||||||
|
event_t event;
|
||||||
|
|
||||||
|
for(int i = 0; i < history_size; i++) history[i].type = ET_None;
|
||||||
|
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
dclear();
|
dclear();
|
||||||
locate(1, 1, "Keyboard driver");
|
locate(1, 1, "Keyboard and events");
|
||||||
locate(8, 3, "Pressed keys:");
|
draw_keyboard(keystate());
|
||||||
draw(state);
|
draw_events(history, history_size);
|
||||||
|
|
||||||
if(keys[0] == KEY_NONE) locate(9, 4, ":None");
|
|
||||||
else for(i = 0; i < 4 && keys[i] != KEY_NONE; i++)
|
|
||||||
{
|
|
||||||
locate( 9, i + 4, ":");
|
|
||||||
locate(10, i + 4, key_names[keyid(keys[i])]);
|
|
||||||
}
|
|
||||||
|
|
||||||
dupdate();
|
dupdate();
|
||||||
|
|
||||||
multigetkey(keys, 4, 1);
|
event = waitevent();
|
||||||
if(keys[0] == KEY_EXIT && keys[1] == KEY_NONE) break;
|
if(event.type == ET_KeyPress && event.key == KEY_EXIT) break;
|
||||||
|
push_history(history, history_size, event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ static void timing_timer(void)
|
||||||
|
|
||||||
static void timing_start(void)
|
static void timing_start(void)
|
||||||
{
|
{
|
||||||
timer_start(TIMER_USER, 64, Clock_Hz, timing_timer, 0);
|
timer_start(TIMER_USER, 64, Clock_Hz, timing_timer, NULL, 0);
|
||||||
rtc_cb_edit(cb_id, RTCFreq_64Hz, timing_rtc);
|
rtc_cb_edit(cb_id, RTCFreq_64Hz, timing_rtc);
|
||||||
|
|
||||||
elapsed_timer = 0;
|
elapsed_timer = 0;
|
||||||
|
|
|
@ -9,15 +9,11 @@
|
||||||
#ifndef _EVENTS_H
|
#ifndef _EVENTS_H
|
||||||
#define _EVENTS_H
|
#define _EVENTS_H
|
||||||
|
|
||||||
//---
|
|
||||||
// Type definitions.
|
|
||||||
//---
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
enum EventType
|
event_type_t
|
||||||
Something user programs will surely use most often.
|
Something user programs will surely use most often.
|
||||||
*/
|
*/
|
||||||
enum EventType
|
typedef enum
|
||||||
{
|
{
|
||||||
EventType_None = 0,
|
EventType_None = 0,
|
||||||
ET_None = EventType_None,
|
ET_None = EventType_None,
|
||||||
|
@ -28,27 +24,32 @@ enum EventType
|
||||||
EventType_KeyPressed = 2,
|
EventType_KeyPressed = 2,
|
||||||
ET_KeyPress = EventType_KeyPressed,
|
ET_KeyPress = EventType_KeyPressed,
|
||||||
|
|
||||||
EventType_KeyReleased = 3,
|
EventType_KeyRepeated = 3,
|
||||||
|
ET_KeyRepeat = EventType_KeyRepeated,
|
||||||
|
|
||||||
|
EventType_KeyReleased = 4,
|
||||||
ET_KeyRel = EventType_KeyReleased,
|
ET_KeyRel = EventType_KeyReleased,
|
||||||
};
|
|
||||||
|
} event_type_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
struct Event
|
event_t
|
||||||
Wake up, something's going on. The union member that holds information
|
Wake up, something's going on. The union member that holds information
|
||||||
about the event is implicitly defined by the type attribute.
|
about the event is implicitly defined by the type attribute.
|
||||||
*/
|
*/
|
||||||
struct Event
|
typedef struct
|
||||||
{
|
{
|
||||||
enum EventType type;
|
event_type_t type;
|
||||||
|
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
// For ET_User.
|
// For ET_User.
|
||||||
void *data;
|
void *data;
|
||||||
// For ET_KeyPress and ET_KeyRel.
|
// For ET_KeyPress, ET_KeyRepeat and ET_KeyRel.
|
||||||
int key;
|
int key;
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
} event_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -64,21 +65,21 @@ struct Event
|
||||||
allowed.
|
allowed.
|
||||||
Returns non-zero on error.
|
Returns non-zero on error.
|
||||||
*/
|
*/
|
||||||
int event_push(struct Event event);
|
int event_push(event_t event);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
getevent()
|
waitevent()
|
||||||
Returns the next event. If no one is available, waits for something to
|
Returns the next event. If no one is available, waits for something to
|
||||||
happen. This function uses low-level sleep and should be preferred to
|
happen. This function uses low-level sleep and should be preferred to
|
||||||
active waiting using loops.
|
active waiting using loops.
|
||||||
*/
|
*/
|
||||||
struct Event getevent(void);
|
event_t waitevent(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
pollevent()
|
pollevent()
|
||||||
Returns the next event. If no one is available, returns an event whose
|
Returns the next event. If no one is available, returns an event whose
|
||||||
type is ET_None. This function always returns immediately.
|
type is ET_None. This function always returns immediately.
|
||||||
*/
|
*/
|
||||||
struct Event pollevent(void);
|
event_t pollevent(void);
|
||||||
|
|
||||||
#endif // _EVENTS_H
|
#endif // _EVENTS_H
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
like any other queue. Trying to add an event when the queue is full
|
like any other queue. Trying to add an event when the queue is full
|
||||||
fails, and the operation is ignored.
|
fails, and the operation is ignored.
|
||||||
*/
|
*/
|
||||||
extern volatile struct Event event_queue[];
|
extern volatile event_t event_queue[];
|
||||||
extern volatile int queue_start;
|
extern volatile int queue_start;
|
||||||
extern volatile int queue_size;
|
extern volatile int queue_size;
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#include <clock.h>
|
#include <clock.h>
|
||||||
|
|
||||||
// Keyboard variables.
|
// Keyboard variables.
|
||||||
extern volatile unsigned char keyboard_state[10];
|
extern volatile uint8_t keyboard_state[10];
|
||||||
extern volatile int interrupt_flag;
|
extern volatile int interrupt_flag;
|
||||||
|
|
||||||
// Key statistics.
|
// Key statistics.
|
||||||
|
@ -19,7 +19,7 @@ extern unsigned cb_id;
|
||||||
getPressedKey()
|
getPressedKey()
|
||||||
Finds a pressed key in the keyboard state and returns it.
|
Finds a pressed key in the keyboard state and returns it.
|
||||||
*/
|
*/
|
||||||
int getPressedKey(volatile unsigned char *keyboard_state);
|
int getPressedKey(volatile uint8_t *keyboard_state);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
getPressedKeys()
|
getPressedKeys()
|
||||||
|
@ -28,7 +28,13 @@ int getPressedKey(volatile unsigned char *keyboard_state);
|
||||||
WARNING: keyboard artifacts make this function read as pressed keys
|
WARNING: keyboard artifacts make this function read as pressed keys
|
||||||
that aren't (typically, LEFT + DOWN + SHIFT => ALPHA).
|
that aren't (typically, LEFT + DOWN + SHIFT => ALPHA).
|
||||||
*/
|
*/
|
||||||
int getPressedKeys(volatile unsigned char *keyboard_state, int *keys,
|
int getPressedKeys(volatile uint8_t *keyboard_state, int *keys, int count);
|
||||||
int count);
|
|
||||||
|
/*
|
||||||
|
keyboard_updateState()
|
||||||
|
Updates the keyboard state.
|
||||||
|
*/
|
||||||
|
void keyboard_updateState_7705(volatile uint8_t *state);
|
||||||
|
void keyboard_updateState_7305(volatile uint8_t *state);
|
||||||
|
|
||||||
#endif // _INTERNALS_KEYBOARD_H
|
#endif // _INTERNALS_KEYBOARD_H
|
||||||
|
|
|
@ -7,7 +7,8 @@
|
||||||
*/
|
*/
|
||||||
struct Timer
|
struct Timer
|
||||||
{
|
{
|
||||||
void (*callback)(void);
|
void *callback;
|
||||||
|
void *data;
|
||||||
int repeats;
|
int repeats;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#ifndef _KEYBOARD_H
|
#ifndef _KEYBOARD_H
|
||||||
#define _KEYBOARD_H 1
|
#define _KEYBOARD_H 1
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
#include <rtc.h>
|
#include <rtc.h>
|
||||||
|
|
||||||
//---
|
//---
|
||||||
|
@ -232,7 +233,7 @@ int keylast(int *repeat_count);
|
||||||
functions, but the buffer data is very volatile. Therefore, data
|
functions, but the buffer data is very volatile. Therefore, data
|
||||||
written to the buffer could be replaced anytime.
|
written to the buffer could be replaced anytime.
|
||||||
*/
|
*/
|
||||||
volatile unsigned char *keystate(void);
|
volatile uint8_t *keystate(void);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -268,37 +269,4 @@ int keychar(int key);
|
||||||
*/
|
*/
|
||||||
enum KeyType keytype(int key);
|
enum KeyType keytype(int key);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//---
|
|
||||||
// Internal API.
|
|
||||||
// Reference here for documentation purposes only. Do not call.
|
|
||||||
//---
|
|
||||||
|
|
||||||
/*
|
|
||||||
keyboard_interrupt()
|
|
||||||
Notifies the keyboard module that an interrupt request has been issued,
|
|
||||||
and updates the keyboard state.
|
|
||||||
*/
|
|
||||||
void keyboard_interrupt(void);
|
|
||||||
|
|
||||||
/*
|
|
||||||
keyboard_updateState()
|
|
||||||
Updates the keyboard state.
|
|
||||||
*/
|
|
||||||
void keyboard_updateState_7705(volatile unsigned char *state);
|
|
||||||
void keyboard_updateState_7305(volatile unsigned char *state);
|
|
||||||
|
|
||||||
/*
|
|
||||||
keyboard_init()
|
|
||||||
Starts the keyboard timer.
|
|
||||||
*/
|
|
||||||
void keyboard_init(void) __attribute__((constructor));
|
|
||||||
|
|
||||||
/*
|
|
||||||
keyboard_quit()
|
|
||||||
Stops the keyboard timer.
|
|
||||||
*/
|
|
||||||
void keyboard_quit(void) __attribute__((destructor));
|
|
||||||
|
|
||||||
#endif // _KEYBOARD_H
|
#endif // _KEYBOARD_H
|
||||||
|
|
|
@ -48,17 +48,22 @@
|
||||||
not running the gray engine.
|
not running the gray engine.
|
||||||
Unit names are defined in the clock.h header and must be one of the
|
Unit names are defined in the clock.h header and must be one of the
|
||||||
following:
|
following:
|
||||||
- Clock_us (microseconds)
|
- Clock_us (microseconds)
|
||||||
- Clock_ms (milliseconds)
|
- Clock_ms (milliseconds)
|
||||||
- Clock_s (seconds)
|
- Clock_s (seconds)
|
||||||
- Clock_Hz (hertz)
|
- Clock_Hz (hertz)
|
||||||
- Clock_kHz (kilohertz)
|
- Clock_kHz (kilohertz)
|
||||||
- Clock_MHz (megahertz)
|
- Clock_MHz (megahertz)
|
||||||
The number of repeats may to set to 0. In this case, the timer will not
|
The number of repeats may to set to 0. In this case, the timer will not
|
||||||
stop until timer_stop() is explicitly called.
|
stop until timer_stop() is explicitly called.
|
||||||
|
The callback is expected to be a function of the following type:
|
||||||
|
- void callback(void) if data == NULL
|
||||||
|
- void callback(void *data) if data is non-NULL
|
||||||
|
In the latter case, the data pointer will be passed as argument to the
|
||||||
|
callback function.
|
||||||
*/
|
*/
|
||||||
void timer_start(int timer, int delay_or_frequency, enum ClockUnit unit,
|
void timer_start(int timer, int delay_or_frequency, enum ClockUnit unit,
|
||||||
void (*callback)(void), int repeats);
|
void *callback, void *data, int repeats);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
timer_start2()
|
timer_start2()
|
||||||
|
@ -71,8 +76,8 @@ void timer_start(int timer, int delay_or_frequency, enum ClockUnit unit,
|
||||||
- TIMER_Po_256
|
- TIMER_Po_256
|
||||||
- TIMER_TCLK
|
- TIMER_TCLK
|
||||||
*/
|
*/
|
||||||
void timer_start2(int timer, int delay, int prescaler, void (*callback)(void),
|
void timer_start2(int timer, int delay, int prescaler, void *callback,
|
||||||
int repeats);
|
void *data, int repeats);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
timer_stop()
|
timer_stop()
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <rtc.h>
|
#include <rtc.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <mpu.h>
|
#include <mpu.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
static clock_config_t conf = {
|
static clock_config_t conf = {
|
||||||
.FLL = -1, .PLL = -1,
|
.FLL = -1, .PLL = -1,
|
||||||
|
@ -21,27 +22,36 @@ static clock_config_t conf = {
|
||||||
int clock_setting(int duration, enum ClockUnit unit)
|
int clock_setting(int duration, enum ClockUnit unit)
|
||||||
{
|
{
|
||||||
if(conf.Pphi_f <= 0) return -1;
|
if(conf.Pphi_f <= 0) return -1;
|
||||||
int f = conf.Pphi_f >> 2;
|
uint64_t f = conf.Pphi_f >> 2;
|
||||||
|
uint64_t result;
|
||||||
|
|
||||||
switch(unit)
|
switch(unit)
|
||||||
{
|
{
|
||||||
case Clock_us:
|
case Clock_us:
|
||||||
return (duration * f) / 1000000;
|
result = (duration * f) / 1000000;
|
||||||
|
break;
|
||||||
case Clock_ms:
|
case Clock_ms:
|
||||||
return (duration * f) / 1000;
|
result = (duration * f) / 1000;
|
||||||
|
break;
|
||||||
case Clock_s:
|
case Clock_s:
|
||||||
return (duration * f);
|
result = (duration * f);
|
||||||
|
break;
|
||||||
|
|
||||||
case Clock_Hz:
|
case Clock_Hz:
|
||||||
return f / duration;
|
result = f / duration;
|
||||||
|
break;
|
||||||
case Clock_kHz:
|
case Clock_kHz:
|
||||||
return f / (duration * 1000);
|
result = f / (duration * 1000);
|
||||||
|
break;
|
||||||
case Clock_MHz:
|
case Clock_MHz:
|
||||||
return f / (duration * 1000000);
|
result = f / (duration * 1000000);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return (result > 0xffffffff) ? (0xffffffff) : (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -60,7 +70,7 @@ clock_config_t clock_config(void)
|
||||||
void sleep(void)
|
void sleep(void)
|
||||||
{
|
{
|
||||||
__asm__(
|
__asm__(
|
||||||
"sleep\n\t"
|
"sleep"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,10 +81,9 @@ void sleep(void)
|
||||||
than requested.
|
than requested.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static volatile int sleep_done = 0;
|
static void sleep_callback(void *flag)
|
||||||
static void sleep_callback(void)
|
|
||||||
{
|
{
|
||||||
sleep_done = 1;
|
*((int *)flag) = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sleep_ms(int ms_delay)
|
void sleep_ms(int ms_delay)
|
||||||
|
@ -83,8 +92,10 @@ void sleep_ms(int ms_delay)
|
||||||
}
|
}
|
||||||
void sleep_us(int us_delay)
|
void sleep_us(int us_delay)
|
||||||
{
|
{
|
||||||
sleep_done = 0;
|
volatile int sleep_done = 0;
|
||||||
timer_start(TIMER_USER, us_delay, Clock_us, sleep_callback, 1);
|
timer_start(TIMER_USER, us_delay, Clock_us, sleep_callback,
|
||||||
|
(void *)&sleep_done, 1);
|
||||||
|
|
||||||
do sleep();
|
do sleep();
|
||||||
while(!sleep_done);
|
while(!sleep_done);
|
||||||
}
|
}
|
||||||
|
@ -133,6 +144,7 @@ void clock_measure(void)
|
||||||
tmu->TCR.CKEG = 0;
|
tmu->TCR.CKEG = 0;
|
||||||
|
|
||||||
timers[TIMER_USER].callback = NULL;
|
timers[TIMER_USER].callback = NULL;
|
||||||
|
timers[TIMER_USER].data = NULL;
|
||||||
timers[TIMER_USER].repeats = 0;
|
timers[TIMER_USER].repeats = 0;
|
||||||
|
|
||||||
cb_id_7705 = rtc_cb_add(RTCFreq_256Hz, clock_measure_7705, 0);
|
cb_id_7705 = rtc_cb_add(RTCFreq_256Hz, clock_measure_7705, 0);
|
||||||
|
|
|
@ -7,9 +7,9 @@
|
||||||
Returns the next event. If no one is available, returns an event whose
|
Returns the next event. If no one is available, returns an event whose
|
||||||
type is ET_None. This function always returns immediately.
|
type is ET_None. This function always returns immediately.
|
||||||
*/
|
*/
|
||||||
struct Event pollevent(void)
|
event_t pollevent(void)
|
||||||
{
|
{
|
||||||
struct Event event = {
|
event_t event = {
|
||||||
.type = ET_None
|
.type = ET_None
|
||||||
};
|
};
|
||||||
if(queue_size <= 0) return event;
|
if(queue_size <= 0) return event;
|
||||||
|
@ -24,14 +24,14 @@ struct Event pollevent(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
getevent()
|
waitevent()
|
||||||
Returns the next event. If no one is available, waits for something to
|
Returns the next event. If no one is available, waits for something to
|
||||||
happen. This function uses low-level sleep and should be preferred to
|
happen. This function uses low-level sleep and should be preferred to
|
||||||
active waiting using loops.
|
active waiting using loops.
|
||||||
*/
|
*/
|
||||||
struct Event getevent(void)
|
event_t waitevent(void)
|
||||||
{
|
{
|
||||||
struct Event event;
|
event_t event;
|
||||||
|
|
||||||
while((event = pollevent()).type == ET_None) sleep();
|
while((event = pollevent()).type == ET_None) sleep();
|
||||||
return event;
|
return event;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include <internals/events.h>
|
#include <internals/events.h>
|
||||||
#include <events.h>
|
#include <events.h>
|
||||||
|
|
||||||
volatile struct Event event_queue[EVENTS_QUEUE_SIZE];
|
volatile event_t event_queue[EVENTS_QUEUE_SIZE];
|
||||||
volatile int queue_start = 0;
|
volatile int queue_start = 0;
|
||||||
volatile int queue_size = 0;
|
volatile int queue_size = 0;
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ volatile int queue_size = 0;
|
||||||
or pollevent() later. Pushing ET_None events is not allowed.
|
or pollevent() later. Pushing ET_None events is not allowed.
|
||||||
Returns non-zero on error.
|
Returns non-zero on error.
|
||||||
*/
|
*/
|
||||||
int event_push(struct Event event)
|
int event_push(event_t event)
|
||||||
{
|
{
|
||||||
if(queue_size >= EVENTS_QUEUE_SIZE) return 1;
|
if(queue_size >= EVENTS_QUEUE_SIZE) return 1;
|
||||||
if(event.type == ET_None) return 2;
|
if(event.type == ET_None) return 2;
|
||||||
|
|
|
@ -68,7 +68,8 @@ void gray_start(void)
|
||||||
{
|
{
|
||||||
if(runs) return;
|
if(runs) return;
|
||||||
|
|
||||||
timer_start2(TIMER_GRAY, delays[0], GRAY_PRESCALER, gray_interrupt, 0);
|
timer_start2(TIMER_GRAY, delays[0], GRAY_PRESCALER, gray_interrupt,
|
||||||
|
NULL, 0);
|
||||||
current &= 1;
|
current &= 1;
|
||||||
runs = 1;
|
runs = 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
getPressedKey()
|
getPressedKey()
|
||||||
Finds a pressed key in the keyboard state and returns it.
|
Finds a pressed key in the keyboard state and returns it.
|
||||||
*/
|
*/
|
||||||
int getPressedKey(volatile unsigned char *keyboard_state)
|
int getPressedKey(volatile uint8_t *keyboard_state)
|
||||||
{
|
{
|
||||||
int row = 1, column = 0;
|
int row = 1, column = 0;
|
||||||
int state;
|
int state;
|
||||||
|
|
|
@ -5,8 +5,7 @@
|
||||||
Find 'count' pressed keys in the keyboard state and fills the 'keys'
|
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 actually-pressed keys found.
|
||||||
*/
|
*/
|
||||||
int getPressedKeys(volatile unsigned char *keyboard_state, int *keys,
|
int getPressedKeys(volatile uint8_t *keyboard_state, int *keys, int count)
|
||||||
int count)
|
|
||||||
{
|
{
|
||||||
int row = 1, column;
|
int row = 1, column;
|
||||||
int found = 0, actually_pressed;
|
int found = 0, actually_pressed;
|
||||||
|
|
|
@ -25,7 +25,7 @@ int getkey(void)
|
||||||
If max_cycles is non-zero and positive, getkey_opt() will return
|
If max_cycles is non-zero and positive, getkey_opt() will return
|
||||||
KEY_NOEVENT if no event occurs during max_cycle analysis.
|
KEY_NOEVENT if no event occurs during max_cycle analysis.
|
||||||
*/
|
*/
|
||||||
void getkey_opt_wait(int *cycles)
|
static void getkey_opt_wait(int *cycles)
|
||||||
{
|
{
|
||||||
while(!interrupt_flag) sleep();
|
while(!interrupt_flag) sleep();
|
||||||
interrupt_flag = 0;
|
interrupt_flag = 0;
|
||||||
|
@ -34,7 +34,7 @@ void getkey_opt_wait(int *cycles)
|
||||||
}
|
}
|
||||||
int getkey_opt(enum GetkeyOpt options, int cycles)
|
int getkey_opt(enum GetkeyOpt options, int cycles)
|
||||||
{
|
{
|
||||||
struct Event event;
|
event_t event;
|
||||||
int modifier = 0;
|
int modifier = 0;
|
||||||
static int event_ref = 0;
|
static int event_ref = 0;
|
||||||
|
|
||||||
|
@ -120,19 +120,3 @@ int getkey_opt(enum GetkeyOpt options, int cycles)
|
||||||
event_ref = 0;
|
event_ref = 0;
|
||||||
return KEY_NONE;
|
return KEY_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
int getkey_opt(enum GetkeyOpt options, int max_cycles)
|
|
||||||
{
|
|
||||||
while(max_cycles != 0)
|
|
||||||
{
|
|
||||||
// Handling "new key" events.
|
|
||||||
|
|
||||||
// Handling key repetitions.
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// When no key was pressed during the given delay...
|
|
||||||
return KEY_NOEVENT;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
//---
|
//---
|
||||||
|
|
||||||
// These ones get modified by interrupts.
|
// These ones get modified by interrupts.
|
||||||
volatile unsigned char keyboard_state[10] = { 0 };
|
volatile uint8_t keyboard_state[10] = { 0 };
|
||||||
volatile int interrupt_flag = 0;
|
volatile int interrupt_flag = 0;
|
||||||
|
|
||||||
// Key statistics.
|
// Key statistics.
|
||||||
|
@ -28,16 +28,25 @@ unsigned cb_id;
|
||||||
|
|
||||||
static void push_press(int keycode)
|
static void push_press(int keycode)
|
||||||
{
|
{
|
||||||
struct Event event = {
|
event_t event = {
|
||||||
.type = ET_KeyPress,
|
.type = ET_KeyPress,
|
||||||
.key = keycode,
|
.key = keycode,
|
||||||
};
|
};
|
||||||
event_push(event);
|
event_push(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void push_repeat(int keycode)
|
||||||
|
{
|
||||||
|
event_t event = {
|
||||||
|
.type = ET_KeyRepeat,
|
||||||
|
.key = keycode,
|
||||||
|
};
|
||||||
|
event_push(event);
|
||||||
|
}
|
||||||
|
|
||||||
static void push_release(int keycode)
|
static void push_release(int keycode)
|
||||||
{
|
{
|
||||||
struct Event event = {
|
event_t event = {
|
||||||
.type = ET_KeyRel,
|
.type = ET_KeyRel,
|
||||||
.key = keycode,
|
.key = keycode,
|
||||||
};
|
};
|
||||||
|
@ -51,7 +60,7 @@ static void push_release(int keycode)
|
||||||
*/
|
*/
|
||||||
void keyboard_interrupt(void)
|
void keyboard_interrupt(void)
|
||||||
{
|
{
|
||||||
unsigned char state[10] = { 0 };
|
uint8_t state[10] = { 0 };
|
||||||
|
|
||||||
isSH3() ? keyboard_updateState_7705(state)
|
isSH3() ? keyboard_updateState_7705(state)
|
||||||
: keyboard_updateState_7305(state)
|
: keyboard_updateState_7305(state)
|
||||||
|
@ -61,8 +70,8 @@ void keyboard_interrupt(void)
|
||||||
// AC/ON.
|
// AC/ON.
|
||||||
if(keyboard_state[0] ^ state[0])
|
if(keyboard_state[0] ^ state[0])
|
||||||
{
|
{
|
||||||
unsigned char pressed = ~keyboard_state[0] & state[0];
|
uint8_t pressed = ~keyboard_state[0] & state[0];
|
||||||
unsigned char released = keyboard_state[0] & ~state[0];
|
uint8_t released = keyboard_state[0] & ~state[0];
|
||||||
|
|
||||||
if(pressed & 1) push_press(KEY_AC_ON);
|
if(pressed & 1) push_press(KEY_AC_ON);
|
||||||
if(released & 1) push_release(KEY_AC_ON);
|
if(released & 1) push_release(KEY_AC_ON);
|
||||||
|
@ -71,19 +80,22 @@ void keyboard_interrupt(void)
|
||||||
|
|
||||||
for(int row = 1; row <= 9; row++)
|
for(int row = 1; row <= 9; row++)
|
||||||
{
|
{
|
||||||
unsigned char pressed = ~keyboard_state[row] & state[row];
|
uint8_t pressed = ~keyboard_state[row] & state[row];
|
||||||
unsigned char released = keyboard_state[row] & ~state[row];
|
uint8_t repeated = keyboard_state[row] & state[row];
|
||||||
|
uint8_t released = keyboard_state[row] & ~state[row];
|
||||||
keyboard_state[row] = state[row];
|
keyboard_state[row] = state[row];
|
||||||
|
|
||||||
// Fasten this a bit.
|
// Fasten this a bit.
|
||||||
if(!pressed && !released) continue;
|
if(!(pressed | repeated | released)) continue;
|
||||||
|
|
||||||
for(int column = 0; column < 8; column++)
|
for(int column = 0; column < 8; column++)
|
||||||
{
|
{
|
||||||
if(pressed & 1) push_press ((column << 4) | row);
|
if(pressed & 1) push_press ((column << 4) | row);
|
||||||
|
if(repeated & 1) push_repeat ((column << 4) | row);
|
||||||
if(released & 1) push_release((column << 4) | row);
|
if(released & 1) push_release((column << 4) | row);
|
||||||
|
|
||||||
pressed >>= 1;
|
pressed >>= 1;
|
||||||
|
repeated >>= 1;
|
||||||
released >>= 1;
|
released >>= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -95,7 +107,7 @@ void keyboard_interrupt(void)
|
||||||
keyboard_init()
|
keyboard_init()
|
||||||
Starts the keyboard timer.
|
Starts the keyboard timer.
|
||||||
*/
|
*/
|
||||||
void keyboard_init(void)
|
__attribute__((constructor)) void keyboard_init(void)
|
||||||
{
|
{
|
||||||
cb_id = rtc_cb_add(RTCFreq_16Hz, keyboard_interrupt, 0);
|
cb_id = rtc_cb_add(RTCFreq_16Hz, keyboard_interrupt, 0);
|
||||||
}
|
}
|
||||||
|
@ -114,7 +126,7 @@ void keyboard_setFrequency(enum KeyboardFrequency frequency)
|
||||||
keyboard_quit()
|
keyboard_quit()
|
||||||
Stops the keyboard timer.
|
Stops the keyboard timer.
|
||||||
*/
|
*/
|
||||||
void keyboard_quit(void)
|
__attribute__((destructor)) void keyboard_quit(void)
|
||||||
{
|
{
|
||||||
rtc_cb_end(cb_id);
|
rtc_cb_end(cb_id);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ int keylast(int *repeat_count)
|
||||||
Returns the address of the keyboard state array. The returned address
|
Returns the address of the keyboard state array. The returned address
|
||||||
is the handler's buffer, therefore it contains volatile data.
|
is the handler's buffer, therefore it contains volatile data.
|
||||||
*/
|
*/
|
||||||
volatile unsigned char *keystate(void)
|
volatile uint8_t *keystate(void)
|
||||||
{
|
{
|
||||||
return keyboard_state;
|
return keyboard_state;
|
||||||
}
|
}
|
||||||
|
|
|
@ -136,7 +136,7 @@ static int krow(int row)
|
||||||
keyboard_updateState()
|
keyboard_updateState()
|
||||||
Updates the keyboard state.
|
Updates the keyboard state.
|
||||||
*/
|
*/
|
||||||
void keyboard_updateState_7305(volatile unsigned char *keyboard_state)
|
void keyboard_updateState_7305(volatile uint8_t *keyboard_state)
|
||||||
{
|
{
|
||||||
for(int i = 0; i < 10; i++) keyboard_state[i] = krow(i);
|
for(int i = 0; i < 10; i++) keyboard_state[i] = krow(i);
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,7 +129,7 @@ static int krow(int row)
|
||||||
keyboard_updateState()
|
keyboard_updateState()
|
||||||
Updates the keyboard state.
|
Updates the keyboard state.
|
||||||
*/
|
*/
|
||||||
void keyboard_updateState_7705(volatile unsigned char *keyboard_state)
|
void keyboard_updateState_7705(volatile uint8_t *keyboard_state)
|
||||||
{
|
{
|
||||||
for(int i = 0; i < 10; i++) keyboard_state[i] = krow(i);
|
for(int i = 0; i < 10; i++) keyboard_state[i] = krow(i);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include <keyboard.h>
|
#include <keyboard.h>
|
||||||
#include <internals/keyboard.h>
|
#include <internals/keyboard.h>
|
||||||
|
#include <events.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
multigetkey()
|
multigetkey()
|
||||||
|
@ -12,23 +13,28 @@
|
||||||
Setting count = 3 is generally safe.
|
Setting count = 3 is generally safe.
|
||||||
The function returns after 'max_cycles' if no key is pressed.
|
The function returns after 'max_cycles' if no key is pressed.
|
||||||
*/
|
*/
|
||||||
void multigetkey(int *keys, int count, int max_cycles)
|
static void multigetkey_wait(int *cycles)
|
||||||
{
|
{
|
||||||
int number;
|
while(!interrupt_flag) sleep();
|
||||||
|
interrupt_flag = 0;
|
||||||
|
|
||||||
if(!max_cycles) max_cycles = -1;
|
if(*cycles > 0) (*cycles)--;
|
||||||
|
}
|
||||||
|
void multigetkey(int *keys, int count, int cycles)
|
||||||
|
{
|
||||||
|
event_t event;
|
||||||
|
int number = 0;
|
||||||
|
|
||||||
while(max_cycles != 0)
|
if(count <= 0) return;
|
||||||
|
if(cycles <= 0) cycles = -1;
|
||||||
|
|
||||||
|
while(cycles != 0)
|
||||||
{
|
{
|
||||||
while(!interrupt_flag) sleep();
|
|
||||||
interrupt_flag = 0;
|
|
||||||
if(max_cycles > 0) max_cycles--;
|
|
||||||
|
|
||||||
number = getPressedKeys(keyboard_state, keys, count);
|
number = getPressedKeys(keyboard_state, keys, count);
|
||||||
|
|
||||||
// We need to update the last key data, in case multigetkey()
|
// We want to update the last key data when multigetkey()
|
||||||
// returns a single key, and getkey() is called a short time
|
// returns a single key, because getkey() could be called a
|
||||||
// after. Otherwise getkey() could re-send an event for this
|
// short time after we return, and send a new event for this
|
||||||
// key.
|
// key.
|
||||||
if(number == 1)
|
if(number == 1)
|
||||||
{
|
{
|
||||||
|
@ -37,10 +43,12 @@ void multigetkey(int *keys, int count, int max_cycles)
|
||||||
last_events = 0;
|
last_events = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(number) return;
|
if(number) break;
|
||||||
|
multigetkey_wait(&cycles);
|
||||||
}
|
}
|
||||||
|
|
||||||
// When no key was pressed during the given delay... (no need to fill
|
do event = pollevent();
|
||||||
// the array, it has already been done by getPressedKeys()).
|
while(event.type != ET_None);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,11 @@
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
struct Timer timers[3] = { { NULL, 0 }, { NULL, 0 }, { NULL, 0 } };
|
struct Timer timers[3] = {
|
||||||
|
{ .callback = NULL, .data = NULL, .repeats = 0 },
|
||||||
|
{ .callback = NULL, .data = NULL, .repeats = 0 },
|
||||||
|
{ .callback = NULL, .data = NULL, .repeats = 0 },
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
timer_interrupt()
|
timer_interrupt()
|
||||||
|
@ -15,7 +19,20 @@ void timer_interrupt(int timer)
|
||||||
timer_get(timer, &tmu, NULL);
|
timer_get(timer, &tmu, NULL);
|
||||||
|
|
||||||
tmu->TCR.UNF = 0;
|
tmu->TCR.UNF = 0;
|
||||||
if(timers[timer].callback) timers[timer].callback();
|
|
||||||
|
if(timers[timer].callback)
|
||||||
|
{
|
||||||
|
if(timers[timer].data)
|
||||||
|
{
|
||||||
|
void (*fun)(void *data) = timers[timer].callback;
|
||||||
|
fun(timers[timer].data);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
void (*fun)(void) = timers[timer].callback;
|
||||||
|
fun();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Reducing the number of repetitions left, if not infinite.
|
// Reducing the number of repetitions left, if not infinite.
|
||||||
if(!timers[timer].repeats) return;
|
if(!timers[timer].repeats) return;
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
timer_start2()
|
timer_start2()
|
||||||
Configures and starts a time using a clock count and a prescaler.
|
Configures and starts a time using a clock count and a prescaler.
|
||||||
*/
|
*/
|
||||||
void timer_start2(int timer, int delay, int prescaler, void (*callback)(void),
|
void timer_start2(int timer, int delay, int prescaler, void *callback,
|
||||||
int repeats)
|
void *data, int repeats)
|
||||||
{
|
{
|
||||||
volatile struct mod_tmu *tmu;
|
volatile struct mod_tmu *tmu;
|
||||||
volatile unsigned char *tstr;
|
volatile unsigned char *tstr;
|
||||||
|
@ -27,8 +27,9 @@ void timer_start2(int timer, int delay, int prescaler, void (*callback)(void),
|
||||||
tmu->TCR.CKEG = 0;
|
tmu->TCR.CKEG = 0;
|
||||||
|
|
||||||
// Loading the structure information.
|
// Loading the structure information.
|
||||||
timers[timer].callback = callback;
|
timers[timer].callback = callback;
|
||||||
timers[timer].repeats = repeats;
|
timers[timer].data = data;
|
||||||
|
timers[timer].repeats = repeats;
|
||||||
|
|
||||||
// Starting the timer.
|
// Starting the timer.
|
||||||
*tstr |= byte;
|
*tstr |= byte;
|
||||||
|
@ -39,9 +40,9 @@ void timer_start2(int timer, int delay, int prescaler, void (*callback)(void),
|
||||||
Configures and starts a timer using a delay, or a frequency, and the
|
Configures and starts a timer using a delay, or a frequency, and the
|
||||||
associated unit.
|
associated unit.
|
||||||
*/
|
*/
|
||||||
void timer_start(int timer, int delay, enum ClockUnit unit,
|
void timer_start(int timer, int delay, enum ClockUnit unit, void *callback,
|
||||||
void (*callback)(void), int repeats)
|
void *data, int repeats)
|
||||||
{
|
{
|
||||||
timer_start2(timer, clock_setting(delay, unit), TIMER_Po_4, callback,
|
timer_start2(timer, clock_setting(delay, unit), TIMER_Po_4, callback,
|
||||||
repeats);
|
data, repeats);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue