实例介绍
【实例截图】
/*
This file was autogenerated by ButtonParsePro
*/
#include "source_buttons.h"
#include <pio.h>
#include <app/message/system_message.h>
#include <panic.h>
#include <ps.h>
#include <stdlib.h>
#include <charger.h>
#include <psu.h>
/* Pio bits that trigger messages */
#define MSG_BITS (BUTTON_PAIR_CONNECT|BUTTON_POWER|CHARGER)
/* Pio masks that requires map before use it */
#define PIO_MAP_MASK ((uint32)(0x1FFFE000))
/* Pio bits that trigger a raw message */
#define RAW_BITS 0
/* Charger to local PIO map defines */
#define MAP_BUTTON_POWER 23
#define MAP_CHARGER 22
/* Mask of bits mapped to CHARGER events */
#define CHG_MASK (1UL<<MAP_CHARGER|1UL<<MAP_BUTTON_POWER)
/* Mask of bits mapped to External PIO events */
#define EXT_MASK 0
static const PioActionMessage action_table[] =
{
{
BUTTON_PAIR_CONNECT,
BUTTON_PAIR_CONNECT,
HELD,
2000,
0,
BUTTON_MSG_ENTER_PAIRING_MODE
},
{
BUTTON_PAIR_CONNECT,
BUTTON_PAIR_CONNECT,
HELD,
7000,
0,
BUTTON_MSG_RESET_PAIRED_DEVICE_LIST
},
{
BUTTON_POWER,
BUTTON_POWER,
HELD,
2000,
0,
BUTTON_MSG_ON_OFF_HELD
},
{
CHARGER,
CHARGER,
ENTER,
0,
0,
CHARGER_CONNECTED
},
{
BUTTON_PAIR_CONNECT,
BUTTON_PAIR_CONNECT,
RELEASE,
0,
0,
BUTTON_MSG_CONNECT
},
{
BUTTON_POWER,
BUTTON_POWER,
RELEASE,
0,
0,
BUTTON_MSG_ON_OFF_RELEASE
},
{
CHARGER,
CHARGER,
RELEASE,
0,
0,
CHARGER_DISCONNECTED
}
};
/* Task messages */
enum
{
internal_held_timer_message,
internal_repeat_timer_message,
internal_held_release_timer_message,
internal_double_timer_message,
pio_external_message
};
static void enterAction(
PioState *piostate,
const PioActionMessage *pam,
pio_bits_t pio_bits
)
{
/* If all the bits, for the msg, are 'on', and at least one of those bits,
* was just turned on, then ...
*/
if ( pam->bits == (pio_bits & pam->mask) )
{
/* A new enter action cancels any existing repeat timer */
(void) MessageCancelAll(
&piostate->task,
internal_repeat_timer_message
);
MessageSend(piostate->client, pam->message, 0);
/* if there is a repeat on this action, start the repeat timer */
if (pam->repeat)
{
piostate->stored.repeat = pam;
MessageSendLater(
&piostate->task,
internal_repeat_timer_message,
0,
pam->repeat
);
}
else
piostate->stored.repeat = 0;
}
/* if any of the bits are turned off and there is a repeat timer,
* cancel it and clear the stored PAM
*/
else if (
pam->repeat &&
piostate->stored.repeat == pam &&
pam->bits == (piostate->stored.pio_bits & pam->mask) &&
pam->bits != (pio_bits & pam->mask)
)
{
(void) MessageCancelAll(
&piostate->task,
internal_repeat_timer_message
);
piostate->stored.repeat = 0;
}
}
/* There can be 1 held action/messages on the same PIO */
static void heldAction(
PioState *piostate,
const PioActionMessage *pam,
pio_bits_t pio_bits
)
{
/* If all the PIO, for the msg, are 'on'... */
if ( pam->bits == (pio_bits & pam->mask) )
{
/* Send a pointer to this PAM as part of the timer message so that it
* can be handled when the timeout expired
*/
const PioActionMessage **m =
(const PioActionMessage **) PanicNull(
malloc(sizeof(const PioActionMessage *))
);
*m = pam;
MessageSendLater(
&piostate->task,
internal_held_timer_message,
m,
pam->timeout
);
}
/* If any of the bits are turned off...
*/
else if (
pam->bits == (piostate->stored.pio_bits & pam->mask) &&
pam->bits != (pio_bits & pam->mask)
)
{
/* Cancel any active held or repeat timers. */
if (!MessageCancelAll(&piostate->task, internal_held_timer_message))
{
(void) MessageCancelAll(
&piostate->task,
internal_repeat_timer_message
);
}
}
}
static void pioChanged(Task task, PioState *piostate, pio_bits_t pio_bits)
{
pio_bits_t changed = piostate->stored.pio_bits ^ pio_bits;
/* If any of the msg bits have changed... */
if (changed & MSG_BITS)
{
/* Go through the action table to determine what action to do &
* message may need to be sent.
*/
const PioActionMessage *pam;
/* Only interested in the pio bits that trigger messages. */
pio_bits_t pio_msg_bits = pio_bits & MSG_BITS;
for (
pam = action_table;
pam != &(action_table[
sizeof(action_table)/sizeof(PioActionMessage)
]);
pam
)
{
if (changed & pam->mask)
{
switch (pam->action)
{
case ENTER:
enterAction(piostate, pam, pio_msg_bits);
break;
case RELEASE:
/* Only a release if the PIO were previously on and now
* have been turned off, and a release message was not
* to be supressed
*/
if (pam->bits == (piostate->stored.pio_bits & pam->mask)
&& pam->bits != (pio_msg_bits & pam->mask)
&& ( pam->bits != (
piostate->stored.pio_release_disabled & pam->mask ))
)
{
MessageSend(piostate->client, pam->message, 0);
}
/* Re-enable Release messages for the next release action */
piostate->stored.pio_release_disabled &= ~(pam->bits);
break;
case HELD:
heldAction(piostate, pam, pio_msg_bits);
break;
default:
break;
}
}
}
}
/* store the bits previously reported */
piostate->stored.pio_bits = pio_bits;
}
static void pioHandler(Task task, MessageId id, Message data)
{
PioState *piostate = (PioState *) task;
switch(id)
{
case MESSAGE_PIO_CHANGED:
{
const MessagePioChanged *mpc = (const MessagePioChanged *)data;
/* Only change the actual PIO bits. Xor with pskey_wakeup
* for pio that are active low not active high
*/
pio_bits_t pio_bits =
(piostate->stored.pio_bits & (CHG_MASK|EXT_MASK)) |
(mpc->state ^ piostate->stored.pskey_wakeup) |
(((uint32)mpc->state16to31) << 16);
pioChanged(task, piostate, pio_bits);
}
break;
case MESSAGE_CHARGER_CHANGED:
{
const MessageChargerChanged *m =
(const MessageChargerChanged *)data;
pio_bits_t pio_bits =
((uint32)m->charger_connected<<MAP_CHARGER) |
((uint32)m->vreg_en_high<<MAP_BUTTON_POWER) |
(piostate->stored.pio_bits & ~CHG_MASK);
pioChanged(task, piostate, pio_bits);
}
break;
/* If a pio has been HELD for the timeout required, then
* send the message stored.
*/
case internal_held_timer_message:
{
const PioActionMessage **m = (const PioActionMessage**) data;
const PioActionMessage *pam = *m;
MessageSend(
piostate->client,
pam->message,
0
);
/* Cancel any existing repeat timer that may be running */
(void) MessageCancelAll(
&piostate->task,
internal_repeat_timer_message
);
/* Now that a held message has been issued, suppress future
release messages*/
piostate->stored.pio_release_disabled |= pam->bits;
/* If there is a repeat action start the repeat on
* this message and store the PAM.
*/
if (pam->repeat)
{
MessageSendLater(
&piostate->task,
internal_repeat_timer_message,
0,
pam->repeat
);
piostate->stored.repeat = pam;
}
}
break;
case internal_repeat_timer_message:
if (piostate->stored.repeat)
{
MessageSend(
piostate->client,
(piostate->stored.repeat)->message,
0
);
/* Start the repeat timer again */
MessageSendLater(
&piostate->task,
internal_repeat_timer_message,
0,
(piostate->stored.repeat)->repeat
);
}
break;
default:
break;
}
}
void pioInit(PioState *piostate, Task client)
{
MessagePioChanged *mpc = malloc(sizeof(MessagePioChanged));
uint32 pio_val = PioGet32();
uint16 pskey_wakeup = 0;
MessageChargerChanged *mcc = malloc(sizeof(MessageChargerChanged));
bool vreg_en = PsuGetVregEn();
bool chgr_en;
{
charger_status status = ChargerStatus();
if (
status == TRICKLE_CHARGE ||
status == FAST_CHARGE ||
status == STANDBY
)
chgr_en = TRUE;
else
chgr_en = FALSE;
}
piostate->task.handler = pioHandler;
piostate->client = client;
/* Retrieve the PIO Deep Sleep wake up state PS Key. which indicates
* the state that a PIO must be in to wake the chip from deep sleep.
* This therefore also indicates if a PIO is reversed in effect e.g
* active low instead of active high.
* The default is all PIO are active high e.g. 0xFFFF.
*/
{
uint16 pskey_val = 0xFFFF;
PsFullRetrieve(PSKEY_PIO_WAKEUP_STATE, &pskey_val, sizeof(pskey_val));
pskey_wakeup = pskey_wakeup | ~pskey_val;
}
PsFullRetrieve(PSKEY_PIO_WAKEUP_STATE, &pskey_wakeup, sizeof(pskey_wakeup));
pskey_wakeup = ~pskey_wakeup;
/* Set the initial pio states for the task. */
piostate->stored.pskey_wakeup = pskey_wakeup;
piostate->stored.pio_bits = (pio_val ^ pskey_wakeup) & (RAW_BITS);
/* Initalise PAM stored states to 0. */
piostate->stored.held_release = 0;
piostate->stored.double_tap = 0;
piostate->stored.repeat = 0;
piostate->stored.pio_release_disabled = 0;
/* Set the Pio Task handler to this button handler. */
(void) MessagePioTask(&piostate->task);
/* If the message button has been mapped by firmware, panic it.*/
if(PioGetMapPins32() & MSG_BITS)
{
Panic();
}
/* Map some message PIOs */
if(PIO_MAP_MASK & MSG_BITS)
{
PioSetMapPins32((PIO_MAP_MASK & MSG_BITS), (PIO_MAP_MASK & MSG_BITS));
}
/* Set the Debounce for all pio - Message bits and Raw bits.
* Exclude PIO bits that are mapped to charger or ext messages
*/
if (
PioDebounce32(
(uint32)(RAW_BITS|MSG_BITS)^(CHG_MASK|EXT_MASK),
1,
0
)
)
{
Panic();
/* If the result is not zero (0) then a PIO that cannot be used
* as an input has been defined in the PioDebounce32() call.
* The PioDebounce will not have been set in this case so
* the VM application is panicked.
*/
}
/* Set the Message Charger handler (VGEN and CHG) to this button
* handler.
*/
(void) MessageChargerTask(&piostate->task);
/* Set the Debounce for all Charger events. */
ChargerDebounce((CHARGER_VREG_EVENT|CHARGER_CONNECT_EVENT), 1, 0);
/* Send an intial message to indicate pio status */
mpc->state = (uint16)(pio_val & (RAW_BITS|MSG_BITS));
mpc->state16to31 = (uint16)((pio_val & (RAW_BITS|MSG_BITS)) >> 16);
mpc->time = 0;
MessageSend(&piostate->task, MESSAGE_PIO_CHANGED, mpc);
/* Send an inital message to indicate charger status */
mcc->charger_connected = chgr_en;
mcc->vreg_en_high = vreg_en;
MessageSend(&piostate->task, MESSAGE_CHARGER_CHANGED, mcc);
}
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明
网友评论
我要评论