?? stereo_headset_buttons.c
字號:
/*
This file was autogenerated by buttonparse
*/
#include "stereo_headset_buttons.h"
#include <pio.h>
#include <app/message/system_message.h>
#include <panic.h>
#include <ps.h>
#include <stdlib.h>
enum { internal_timer_message = 0, double_press_timer, pio_external_changed };
static InternalState encode(uint32 pressed)
{
switch(pressed)
{
case (1UL<<6) : return sUP;
case (1UL<<5) : return sDOWN;
case (1UL<<3) : return sMFB;
case (1UL<<7) : return sPLAY_PAUSE;
case (1UL<<8) : return sFORWARD;
case (1UL<<10) : return sBACKWARD;
case (1UL<<8)|(1UL<<10) : return sFORWARD_BACKWARD;
default : return Unknown;
}
}
typedef struct
{
unsigned release:1;
unsigned double_tap:1;
unsigned timeout:15;
MessageId id;
} EnterMessage;
/* Messages sent on state entry */
static const EnterMessage enter_messages_sUP[] = { { 0, 0, 0, BUTTON_VOL_UP } };
static const EnterMessage enter_messages_sDOWN[] = { { 0, 0, 0, BUTTON_VOL_DOWN } };
static const EnterMessage enter_messages_sMFB[] = { { 0, 0, 0, BUTTON_MFB_PRESS },
{ 1, 0, 0, BUTTON_MFB_SHORT } };
static const EnterMessage enter_messages_sPLAY_PAUSE[] = { { 0, 0, 0, BUTTON_PLAY_PAUSE_PRESS },
{ 1, 0, 0, BUTTON_PLAY_PAUSE_SHORT },
{ 0, 1, 200, BUTTON_PLAY_PAUSE_DOUBLE } };
static const EnterMessage enter_messages_sFORWARD[] = { { 0, 0, 0, BUTTON_FORWARD_PRESS },
{ 1, 0, 0, BUTTON_FORWARD_RELEASE } };
static const EnterMessage enter_messages_sBACKWARD[] = { { 0, 0, 0, BUTTON_BACKWARD_PRESS },
{ 1, 0, 0, BUTTON_BACKWARD_RELEASE } };
static const struct
{
uint16 count; const EnterMessage *send;
} enter_messages[] = {
{ 1, enter_messages_sUP },
{ 1, enter_messages_sDOWN },
{ 2, enter_messages_sMFB },
{ 3, enter_messages_sPLAY_PAUSE },
{ 2, enter_messages_sFORWARD },
{ 2, enter_messages_sBACKWARD },
{ 0, 0 }
};
static void send_enter_messages(PioState *pioState, InternalState state)
{
uint16 init_count = enter_messages[state].count;
uint16 count = init_count;
const EnterMessage *p = enter_messages[state].send;
while(count--)
{
if (p->double_tap)
{
if (pioState->double_press == state)
{
if (MessageCancelAll(&pioState->task, double_press_timer))
{
pioState->store_held = Unknown;
MessageSend(pioState->client, p->id, 0);
}
else
MessageSendLater(&pioState->task, double_press_timer, 0, p->timeout);
}
else
{
pioState->double_press = state;
(void) MessageCancelAll(&pioState->task, double_press_timer);
MessageSendLater(&pioState->task, double_press_timer, 0, p->timeout);
}
}
else
if (!p->release)
MessageSend(pioState->client, p->id, 0);
else
{
pioState->store_held = state;
pioState->store_count = init_count - (count + 1);
}
p++;
}
}
/* Timed messages to be sent to the client */
typedef struct
{
unsigned repeat:1;
unsigned msec:15; /* Limit to 32767ms. Sounds reasonable. */
unsigned msecRepeat:15;
unsigned release:1;
MessageId id;
} TimedMessage;
static const TimedMessage timed_messages_sUP[] =
{
{ 1, 500, 0, 0, BUTTON_VOL_UP }
};
static const TimedMessage timed_messages_sDOWN[] =
{
{ 1, 500, 0, 0, BUTTON_VOL_DOWN }
};
static const TimedMessage timed_messages_sMFB[] =
{
{ 0, 2000, 0, 0, BUTTON_MFB_LONG_HELD },
{ 0, 2000, 0, 1, BUTTON_MFB_LONG_RELEASE },
{ 0, 5000, 0, 0, BUTTON_MFB_VERY_LONG }
};
static const TimedMessage timed_messages_sPLAY_PAUSE[] =
{
{ 0, 2000, 0, 0, BUTTON_PLAY_PAUSE_LONG }
};
static const TimedMessage timed_messages_sFORWARD_BACKWARD[] =
{
{ 0, 10000, 0, 0, BUTTON_FORWARD_BACKWARD_HELD }
};
static const struct
{
uint16 count;
const TimedMessage *send;
} timed_messages[] =
{
{ 1, timed_messages_sUP },
{ 1, timed_messages_sDOWN },
{ 3, timed_messages_sMFB },
{ 1, timed_messages_sPLAY_PAUSE },
{ 0, 0 },
{ 0, 0 },
{ 1, timed_messages_sFORWARD_BACKWARD }
};
static void send_timed_message(PioState *pioState, const TimedMessage *p, int hold_repeat)
{
const TimedMessage **m = (const TimedMessage **) PanicNull(malloc(sizeof(const TimedMessage *)));
*m = p;
if (hold_repeat)
MessageSendLater(&pioState->task, internal_timer_message, m, p->msecRepeat);
else
MessageSendLater(&pioState->task, internal_timer_message, m, p->msec);
}
static void send_timed_messages(PioState *pioState, InternalState state)
{
uint16 count = timed_messages[state].count;
const TimedMessage *p = timed_messages[state].send;
while(count--) send_timed_message(pioState, p++, 0);
}
static void pioChanged(Task task, PioState *pioState, uint16 pio_bits, uint16 external_bits)
{
InternalState next;
uint16 raw_bits = 0;
uint32 mState = pio_bits | (uint32)external_bits << 16;
mState &= ~ (1<<13|1<<15);
raw_bits = (pio_bits & (1<<13|1<<15));
if (raw_bits != pioState->pio_raw_bits)
{
PIO_RAW_T *message = malloc(sizeof(PIO_RAW_T));
message->pio = raw_bits;
MessageSend(pioState->client, PIO_RAW, message);
pioState->pio_raw_bits = raw_bits;
}
next = encode(mState);
if ((pioState->store_held != Unknown) && (next != pioState->store_held))
{
uint32 changed = mState ^ pioState->store_bits;
uint32 released = changed & pioState->store_bits;
if (released == pioState->store_bits)
{
const EnterMessage *p = enter_messages[pioState->store_held].send;
MessageSend(pioState->client, p[pioState->store_count].id, 0);
}
pioState->store_held = Unknown;
}
if (pioState->timed_id)
{
MessageSend(pioState->client, pioState->timed_id, 0);
pioState->timed_id = 0;
}
(void) MessageCancelAll(task, internal_timer_message);
if(next != Unknown)
{
send_enter_messages(pioState, next);
send_timed_messages(pioState, next);
}
pioState->store_bits = mState;
pioState->pio_bits = pio_bits;
pioState->external_bits = external_bits;
}
typedef struct { uint16 xor; uint16 and;} PioExternalMessage;
static void pioHandler(Task task, MessageId id, Message data)
{
PioState *pioState = (PioState *) task;
switch(id)
{
case internal_timer_message:
{
const TimedMessage **m = (const TimedMessage **) data;
const TimedMessage *p = *m;
if (p->release)
pioState->timed_id = p->id;
else
{
MessageSend(pioState->client, p->id, 0);
pioState->timed_id = 0;
}
pioState->store_held = Unknown;
if(p->repeat)
{
if(p->msecRepeat)
send_timed_message(pioState, p, 1);
else
send_timed_message(pioState, p, 0);
}
}
break;
case MESSAGE_PIO_CHANGED:
{
const MessagePioChanged *m = (const MessagePioChanged *)data;
pioChanged(task, pioState, m->state^pioState->pskey_wakeup, pioState->external_bits);
}
break;
case pio_external_changed:
{
const PioExternalMessage *m = (const PioExternalMessage *)data;
pioChanged(task, pioState, pioState->pio_bits, m->xor ^ (pioState->external_bits & ~m->and));
}
break;
case double_press_timer:
default:
break;
}
}
void pioExternal(PioState *pioState, uint16 external_and, uint16 external_xor)
{
PioExternalMessage *m = malloc(sizeof(PioExternalMessage));
m->xor = external_xor;
m->and = external_and;
MessageSend(&pioState->task, pio_external_changed, m);
}
void pioInit(PioState *pioState, Task client)
{
MessagePioChanged *m = malloc(sizeof(MessagePioChanged));
uint16 pio_get = PioGet();
uint16 pskey_wakeup = 0xFFFF;
PsFullRetrieve(PSKEY_PIO_WAKEUP_STATE, &pskey_wakeup, sizeof(pskey_wakeup));
pskey_wakeup = ~pskey_wakeup;
pioState->task.handler = pioHandler;
pioState->client = client;
pioState->store_held = Unknown;
pioState->double_press = Unknown;
pioState->store_count = 0;
pioState->store_bits = 0;
pioState->pio_bits = 0;
pioState->external_bits = 0;
pioState->timed_id = 0;
pioState->pskey_wakeup = pskey_wakeup;
(void) MessagePioTask(&pioState->task);
PioDebounce((1<<3)|(1<<5)|(1<<6)|(1<<7)|(1<<8)|(1<<10)|(1<<13)|(1<<15), 2, 20);
pioState->pio_raw_bits = ~(pio_get^pskey_wakeup) & ((1<<13)|(1<<15));
m->state = pio_get & ((1<<3)|(1<<5)|(1<<6)|(1<<7)|(1<<8)|(1<<10)|(1<<13)|(1<<15));
m->time = 0;
MessageSend(&pioState->task, MESSAGE_PIO_CHANGED, m);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -