1. 首页
  2. 课程学习
  3. C++/C
  4. csr8670音频发射器.doc

csr8670音频发射器.doc

上传者: 2022-07-18 06:21:55上传 .DOC文件 1.23 MB 热度 14次

CSR867x — CSR8670平台开发调试经验.doc

/*

This file was autogenerated by ButtonParsePro

*/

#include "source_buttons.h"

#include

#include

#include

#include

#include

#include

#include

/* 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<

/* 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<

((uint32)m->vreg_en_high<

(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);

}

用户评论