--- /dev/null
+/*
+ * Copyright (c) 2008, Titanium Mirror, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universität Berlin nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Header definitions for the BQ2403X charge controller chip family. Only the
+ * BQ2403X was considered when building this component.
+ *
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+#ifndef BQ2403X_H
+#define BQ2403X_H
+
+/* Conversion table, BQSTATX to charge state:
+ *
+ * Name BQSTAT1 BQSTAT2 Value Desired
+ * ----------------------------------------------
+ * Not charging 1 1 3 0
+ * Precharge 0 0 0 1
+ * Fast charge 0 1 1 2
+ * Charge done 1 0 2 3
+ */
+
+/* Conversion table, XXPGn to power state:
+ *
+ * Name ACPGn USBPGn Value Desired
+ * ----------------------------------------
+ * On Battery 1 1 3 0
+ * USB power 1 0 2 1
+ * AC power 0 1 1 2
+ * Both AC+USB 0 0 0 3
+ */
+
+typedef enum {
+ /* Charge part of the state variable */
+ BQ2403X_CHG_NONE = 0,
+ BQ2403X_CHG_PRE,
+ BQ2403X_CHG_FAST,
+ BQ2403X_CHG_DONE,
+ BQ2403X_CHG_MASK = 3,
+
+ /* Power part of the state variable */
+ BQ2403X_PWR_BATT = 0,
+ BQ2403X_PWR_USB = 0x10,
+ BQ2403X_PWR_AC = 0x20,
+ BQ2403X_PWR_BOTH = 0x30,
+ BQ2403X_PWR_MASK = 0x30,
+} bq2403x_state_t;
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2008, Titanium Mirror, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universität Berlin nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * HIL interface for the BQ2403X charge controller chip.
+ *
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+#include "BQ2403X.h"
+
+interface BQ2403X {
+ /**
+ * Get the current charge controller state.
+ */
+ async command bq2403x_state_t getState();
+
+ /**
+ * @returns The charge portion of the current state.
+ */
+ async command bq2403x_state_t getCharge();
+
+ /**
+ * @returns The power portion of the current state.
+ */
+ async command bq2403x_state_t getPower();
+
+ /**
+ * @returns TRUE if the battery is charging
+ */
+ async command bool isCharging();
+
+ /**
+ * @returns TRUE if no external power. Same as getPower() == 0.
+ */
+ async command bool battOnly();
+
+ /**
+ * Enable notifications from the charge controller via <t>change()</t>.
+ */
+ async command void enable();
+
+ /**
+ * Disnable notifications from the charge controller via <t>change()</t>.
+ */
+ async command void disable();
+
+ /**
+ * Signalled any time the state of the BQ2403X charge controller changes when
+ * the controller is <t>enable()</t>'d. A deglitch mechanism must be
+ * implemented by the provider, as a charge controller on AC or USB and with
+ * no battery attached will tend to "flash" between two states.
+ *
+ * @param current The current state of the charge controller.
+ * @param last The state of the charge controller at last query.
+ */
+ async event void change(bq2403x_state_t current, bq2403x_state_t last);
+}
--- /dev/null
+/*
+ * Copyright (c) 2008, Titanium Mirror, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universität Berlin nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * HIL implementation for the BQ2403X charge controller chip family.
+ *
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+#include "BQ2403X.h"
+
+configuration BQ2403XC {
+ provides interface BQ2403X;
+}
+implementation {
+ components BQ2403XP;
+ BQ2403X = BQ2403XP;
+
+ components MainC;
+ MainC.SoftwareInit -> BQ2403XP.Init;
+
+ components BQ2403XPinsC as PinsC;
+ BQ2403XP.BQstat1 -> PinsC.BQstat1;
+ BQ2403XP.BQstat2 -> PinsC.BQstat2;
+ BQ2403XP.ACPGn -> PinsC.ACPGn;
+ BQ2403XP.USBPGn -> PinsC.USBPGn;
+ BQ2403XP.IntBQstat1 -> PinsC.IntBQstat1;
+ BQ2403XP.IntBQstat2 -> PinsC.IntBQstat2;
+ BQ2403XP.IntACPGn -> PinsC.IntACPGn;
+ BQ2403XP.IntUSBPGn -> PinsC.IntUSBPGn;
+
+ components new TimerMilliC();
+ BQ2403XP.Timer -> TimerMilliC;
+}
--- /dev/null
+/*
+ * Copyright (c) 2008, Titanium Mirror, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universität Berlin nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * HIL implementation for the BQ2403X charge controller chip family.
+ *
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+#include "BQ2403X.h"
+
+module BQ2403XP {
+ provides {
+ interface BQ2403X;
+ interface Init;
+ }
+ uses {
+ interface GeneralIO as BQstat1;
+ interface GeneralIO as BQstat2;
+ interface GeneralIO as ACPGn;
+ interface GeneralIO as USBPGn;
+
+ interface GpioInterrupt as IntBQstat1;
+ interface GpioInterrupt as IntBQstat2;
+ interface GpioInterrupt as IntACPGn;
+ interface GpioInterrupt as IntUSBPGn;
+
+ interface Timer<TMilli>;
+ }
+}
+implementation {
+ const static unsigned DELAY = 256; /* 1/4 sec in binary milliseconds */
+ bool enabled;
+ uint8_t state;
+ uint8_t lastState;
+
+ uint8_t bits2charge()
+ {
+ /* Conversion table:
+ * Name BQstat1 BQstat2 Value Desired
+ * ----------------------------------------------
+ * Not charging 1 1 3 0
+ * Precharge 0 0 0 1
+ * Fast charge 0 1 1 2
+ * Charge done 1 0 2 3
+ */
+ return ((call BQstat1.get() << 1) + call BQstat2.get() + 1) & 0x3;
+ }
+
+ uint8_t bits2power()
+ {
+ /* Conversion table:
+ * Name ACPGn USBPGn Value Desired
+ * ----------------------------------------
+ * On Battery 1 1 3 0
+ * USB power 1 0 2 1
+ * AC power 0 1 1 2
+ * Both AC+USB 0 0 0 3
+ */
+ return ~((call ACPGn.get() << 5) + (call USBPGn.get() << 4)) & 0x30;
+ }
+
+ void setInt()
+ {
+ /* Too many race conditions. Implement IO pins as toggles w/deglitch.
+ * Or, poll. Best solution is probably to interrupt on state change then
+ * poll a bit later to deal with deglitch.
+ */
+ if (call BQstat1.get())
+ call IntBQstat1.enableFallingEdge();
+ else
+ call IntBQstat1.enableRisingEdge();
+ if (call BQstat2.get())
+ call IntBQstat2.enableFallingEdge();
+ else
+ call IntBQstat2.enableRisingEdge();
+ if (call ACPGn.get())
+ call IntACPGn.enableFallingEdge();
+ else
+ call IntACPGn.enableRisingEdge();
+ if (call USBPGn.get())
+ call IntUSBPGn.enableFallingEdge();
+ else
+ call IntUSBPGn.enableRisingEdge();
+ }
+
+ void unsetInt()
+ {
+ call IntBQstat1.disable();
+ call IntBQstat2.disable();
+ call IntACPGn.disable();
+ call IntUSBPGn.disable();
+ }
+
+ void update()
+ {
+ atomic {
+ state = bits2power() + bits2charge();
+ setInt();
+ }
+ }
+
+ command error_t Init.init()
+ {
+ call BQstat1.makeInput();
+ call BQstat2.makeInput();
+ call ACPGn.makeInput();
+ call USBPGn.makeInput();
+
+ update();
+ lastState = state;
+ return SUCCESS;
+ }
+
+ async command void BQ2403X.enable()
+ {
+ atomic {
+ enabled = TRUE;
+ setInt();
+ }
+ }
+
+ async command void BQ2403X.disable()
+ {
+ atomic {
+ enabled = FALSE;
+ unsetInt();
+ }
+ }
+
+ async command bq2403x_state_t BQ2403X.getState()
+ {
+ return state;
+ }
+
+ async command bq2403x_state_t BQ2403X.getCharge()
+ {
+ return state & BQ2403X_CHG_MASK;
+ }
+
+ async command bq2403x_state_t BQ2403X.getPower()
+ {
+ return state & BQ2403X_PWR_MASK;
+ }
+
+ async command bool BQ2403X.isCharging()
+ {
+ return (state + 1) & 0x2;
+ }
+
+ async command bool BQ2403X.battOnly()
+ {
+ return call BQ2403X.getPower() == 0;
+ }
+
+ task void signalChange()
+ {
+ bq2403x_state_t cstate;
+
+ atomic cstate = state;
+ signal BQ2403X.change(cstate, lastState);
+ lastState = cstate;
+ }
+
+ task void startTimer()
+ {
+ call Timer.startOneShot(DELAY);
+ }
+
+ async event void IntBQstat1.fired()
+ {
+ post startTimer();
+ }
+
+ async event void IntBQstat2.fired()
+ {
+ post startTimer();
+ }
+
+ async event void IntACPGn.fired()
+ {
+ post startTimer();
+ }
+
+ async event void IntUSBPGn.fired()
+ {
+ post startTimer();
+ }
+
+ event void Timer.fired()
+ {
+ atomic {
+ update();
+ if (enabled)
+ post signalChange();
+ }
+ }
+
+ default async event void BQ2403X.change(bq2403x_state_t current,
+ bq2403x_state_t last) {}
+}