676 lines
16 KiB
C++
676 lines
16 KiB
C++
/*******************************************************************************
|
|
* Copyright (C) Dean Miller
|
|
* All rights reserved.
|
|
*
|
|
* This program is open source software: you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License as published
|
|
* by the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
* 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 HOLDER 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.
|
|
******************************************************************************/
|
|
|
|
#include "qpcpp.h"
|
|
#include "qp_extras.h"
|
|
|
|
#include "hsm_id.h"
|
|
#include "System.h"
|
|
#include "event.h"
|
|
|
|
#include "RegisterMap.h"
|
|
|
|
#if CONFIG_POWER_SENSE || CONFIG_TEMP_SENSOR
|
|
#include "bsp_adc.h"
|
|
#if CONFIG_POWER_SENSE
|
|
#include "bsp_gpio.h"
|
|
#include "bsp_neopix.h"
|
|
#endif
|
|
#endif
|
|
|
|
#include "bsp_sercom.h"
|
|
|
|
Q_DEFINE_THIS_FILE
|
|
|
|
using namespace FW;
|
|
|
|
System::System() :
|
|
QActive((QStateHandler)&System::InitialPseudoState),
|
|
m_id(SYSTEM), m_name("SYSTEM")
|
|
#if CONFIG_POWER_SENSE
|
|
,m_powerSenseTimer(this, SYSTEM_POWER_SENSE_TIMER)
|
|
,m_powerSenseBlinkTimer(this, SYSTEM_POWER_SENSE_BLINK)
|
|
#endif
|
|
#if CONFIG_I2C_SLAVE
|
|
,m_I2CSlaveOutFifo(m_I2CSlaveOutFifoStor, I2C_SLAVE_OUT_FIFO_ORDER),
|
|
m_I2CSlaveInFifo(m_I2CSlaveInFifoStor, I2C_SLAVE_IN_FIFO_ORDER)
|
|
#endif
|
|
|
|
#if CONFIG_SPI_SLAVE
|
|
,m_SPISlaveOutFifo(m_SPISlaveOutFifoStor, SPI_SLAVE_OUT_FIFO_ORDER),
|
|
m_SPISlaveInFifo(m_SPISlaveInFifoStor, SPI_SLAVE_IN_FIFO_ORDER)
|
|
#endif
|
|
|
|
#if CONFIG_USB
|
|
,m_USBOutFifo(m_USBOutFifoStor, USB_OUT_FIFO_ORDER),
|
|
m_USBInFifo(m_USBInFifoStor, USB_IN_FIFO_ORDER)
|
|
#endif
|
|
|
|
#if CONFIG_SERCOM0
|
|
,m_sercom0RxFifo(m_sercom0RxFifoStor, SERCOM_FIFO_ORDER)
|
|
#endif
|
|
|
|
#if CONFIG_SERCOM1
|
|
,m_sercom1RxFifo(m_sercom1RxFifoStor, SERCOM_FIFO_ORDER)
|
|
#endif
|
|
|
|
#if CONFIG_SERCOM2
|
|
,m_sercom2RxFifo(m_sercom2RxFifoStor, SERCOM_FIFO_ORDER)
|
|
#endif
|
|
|
|
#if CONFIG_SERCOM5
|
|
,m_sercom5RxFifo(m_sercom5RxFifoStor, SERCOM_FIFO_ORDER)
|
|
#endif
|
|
|
|
#if CONFIG_DAP
|
|
,m_DAPRxFifo(m_DAPRxFifoStor, DAP_FIFO_ORDER)
|
|
#endif
|
|
|
|
#if CONFIG_KEYPAD
|
|
,m_keypadFifo(m_keypadFifoStor, KEYPAD_FIFO_ORDER)
|
|
#endif
|
|
{}
|
|
|
|
QState System::InitialPseudoState(System * const me, QEvt const * const e) {
|
|
(void)e;
|
|
//me->m_deferQueue.init(me->m_deferQueueStor, ARRAY_COUNT(me->m_deferQueueStor));
|
|
|
|
me->subscribe(SYSTEM_START_REQ);
|
|
me->subscribe(SYSTEM_STOP_REQ);
|
|
#if CONFIG_POWER_SENSE
|
|
me->subscribe(SYSTEM_POWER_SENSE_TIMER);
|
|
me->subscribe(SYSTEM_POWER_SENSE_BLINK);
|
|
#endif
|
|
me->subscribe(SYSTEM_DONE);
|
|
me->subscribe(SYSTEM_FAIL);
|
|
|
|
#if CONFIG_I2C_SLAVE
|
|
me->subscribe(I2C_SLAVE_START_CFM);
|
|
me->subscribe(I2C_SLAVE_STOP_CFM);
|
|
#endif
|
|
|
|
#if CONFIG_SPI_SLAVE
|
|
me->subscribe(SPI_SLAVE_START_CFM);
|
|
me->subscribe(SPI_SLAVE_STOP_CFM);
|
|
#endif
|
|
|
|
#if CONFIG_SERCOM0 || CONFIG_SERCOM1 || CONFIG_SERCOM2 || CONFIG_SERCOM3 || CONFIG_SERCOM4 || CONFIG_SERCOM5
|
|
me->subscribe(SERCOM_START_CFM);
|
|
me->subscribe(SERCOM_STOP_CFM);
|
|
#endif
|
|
|
|
#if CONFIG_ADC
|
|
me->subscribe(ADC_START_CFM);
|
|
me->subscribe(ADC_STOP_CFM);
|
|
#endif
|
|
|
|
#if CONFIG_TIMER
|
|
me->subscribe(TIMER_START_CFM);
|
|
me->subscribe(TIMER_STOP_CFM);
|
|
#endif
|
|
|
|
#if CONFIG_DAC
|
|
me->subscribe(DAC_START_CFM);
|
|
me->subscribe(DAC_STOP_CFM);
|
|
#endif
|
|
|
|
me->subscribe(DELEGATE_START_CFM);
|
|
me->subscribe(DELEGATE_STOP_CFM);
|
|
|
|
#if CONFIG_INTERRUPT
|
|
me->subscribe(INTERRUPT_START_CFM);
|
|
me->subscribe(INTERRUPT_STOP_CFM);
|
|
#endif
|
|
|
|
#if CONFIG_DAP
|
|
me->subscribe(DAP_START_CFM);
|
|
me->subscribe(DAP_STOP_CFM);
|
|
#endif
|
|
|
|
#if CONFIG_NEOPIXEL
|
|
me->subscribe(NEOPIXEL_START_CFM);
|
|
me->subscribe(NEOPIXEL_STOP_CFM);
|
|
#endif
|
|
|
|
#if CONFIG_USB
|
|
me->subscribe(USB_START_CFM);
|
|
me->subscribe(USB_STOP_CFM);
|
|
#endif
|
|
|
|
#if CONFIG_TOUCH
|
|
me->subscribe(TOUCH_START_CFM);
|
|
me->subscribe(TOUCH_STOP_CFM);
|
|
#endif
|
|
|
|
#if CONFIG_KEYPAD
|
|
me->subscribe(KEYPAD_START_CFM);
|
|
me->subscribe(KEYPAD_STOP_CFM);
|
|
#endif
|
|
|
|
#if CONFIG_ENCODER
|
|
me->subscribe(ENCODER_START_CFM);
|
|
me->subscribe(ENCODER_STOP_CFM);
|
|
#endif
|
|
|
|
return Q_TRAN(&System::Root);
|
|
}
|
|
|
|
QState System::Root(System * const me, QEvt const * const e) {
|
|
QState status;
|
|
switch (e->sig) {
|
|
case Q_ENTRY_SIG: {
|
|
LOG_EVENT(e);
|
|
status = Q_HANDLED();
|
|
break;
|
|
}
|
|
case Q_EXIT_SIG: {
|
|
LOG_EVENT(e);
|
|
status = Q_HANDLED();
|
|
break;
|
|
}
|
|
case Q_INIT_SIG: {
|
|
status = Q_TRAN(&System::Stopped);
|
|
break;
|
|
}
|
|
case SYSTEM_STOP_REQ: {
|
|
LOG_EVENT(e);
|
|
status = Q_TRAN(&System::Stopping);
|
|
break;
|
|
}
|
|
default: {
|
|
status = Q_SUPER(&QHsm::top);
|
|
break;
|
|
}
|
|
}
|
|
return status;
|
|
}
|
|
|
|
QState System::Stopped(System * const me, QEvt const * const e) {
|
|
QState status;
|
|
switch (e->sig) {
|
|
case Q_ENTRY_SIG: {
|
|
LOG_EVENT(e);
|
|
status = Q_HANDLED();
|
|
break;
|
|
}
|
|
case Q_EXIT_SIG: {
|
|
LOG_EVENT(e);
|
|
status = Q_HANDLED();
|
|
break;
|
|
}
|
|
case SYSTEM_STOP_REQ: {
|
|
LOG_EVENT(e);
|
|
Evt const &req = EVT_CAST(*e);
|
|
Evt *evt = new SystemStopCfm(req.GetSeq(), ERROR_SUCCESS);
|
|
QF::PUBLISH(evt, me);
|
|
status = Q_HANDLED();
|
|
break;
|
|
}
|
|
case SYSTEM_START_REQ: {
|
|
LOG_EVENT(e);
|
|
status = Q_TRAN(&System::Starting);
|
|
break;
|
|
}
|
|
default: {
|
|
status = Q_SUPER(&System::Root);
|
|
break;
|
|
}
|
|
}
|
|
return status;
|
|
}
|
|
|
|
QState System::Stopping(System * const me, QEvt const * const e) {
|
|
QState status;
|
|
switch (e->sig) {
|
|
case Q_ENTRY_SIG: {
|
|
LOG_EVENT(e);
|
|
me->m_cfmCount = 0;
|
|
|
|
Evt *evt = new Evt(DELEGATE_STOP_REQ);
|
|
QF::PUBLISH(evt, me);
|
|
|
|
#if CONFIG_INTERRUPT
|
|
evt = new Evt(INTERRUPT_STOP_REQ);
|
|
QF::PUBLISH(evt, me);
|
|
#endif
|
|
|
|
#if CONFIG_I2C_SLAVE
|
|
evt = new Evt(I2C_SLAVE_STOP_REQ);
|
|
QF::PUBLISH(evt, me);
|
|
#endif
|
|
|
|
#if CONFIG_SPI_SLAVE
|
|
evt = new Evt(SPI_SLAVE_STOP_REQ);
|
|
QF::PUBLISH(evt, me);
|
|
#endif
|
|
|
|
#if CONFIG_DAC
|
|
evt = new Evt(DAC_STOP_REQ);
|
|
QF::PUBLISH(evt, me);
|
|
#endif
|
|
|
|
#if CONFIG_ADC
|
|
evt = new Evt(ADC_STOP_REQ);
|
|
QF::PUBLISH(evt, me);
|
|
#endif
|
|
|
|
#if CONFIG_TIMER
|
|
evt = new Evt(TIMER_STOP_REQ);
|
|
QF::PUBLISH(evt, me);
|
|
#endif
|
|
|
|
//TODO: this should be broken out target specific sercoms
|
|
#if CONFIG_SERCOM0
|
|
evt = new Evt(SERCOM_STOP_REQ);
|
|
QF::PUBLISH(evt, me);
|
|
#endif
|
|
|
|
#if CONFIG_SERCOM1
|
|
evt = new Evt(SERCOM_STOP_REQ);
|
|
QF::PUBLISH(evt, me);
|
|
#endif
|
|
|
|
#if CONFIG_SERCOM2
|
|
evt = new Evt(SERCOM_STOP_REQ);
|
|
QF::PUBLISH(evt, me);
|
|
#endif
|
|
|
|
#if CONFIG_SERCOM5
|
|
evt = new Evt(SERCOM_STOP_REQ);
|
|
QF::PUBLISH(evt, me);
|
|
#endif
|
|
|
|
#if CONFIG_DAP
|
|
evt = new Evt(DAP_STOP_REQ);
|
|
QF::PUBLISH(evt, me);
|
|
#endif
|
|
|
|
#if CONFIG_NEOPIXEL
|
|
evt = new Evt(NEOPIXEL_STOP_REQ);
|
|
QF::PUBLISH(evt, me);
|
|
#endif
|
|
|
|
#if CONFIG_USB
|
|
evt = new Evt(USB_STOP_REQ);
|
|
QF::PUBLISH(evt, me);
|
|
#endif
|
|
|
|
#if CONFIG_TOUCH
|
|
evt = new Evt(TOUCH_STOP_REQ);
|
|
QF::PUBLISH(evt, me);
|
|
#endif
|
|
|
|
#if CONFIG_KEYPAD
|
|
evt = new Evt(KEYPAD_STOP_REQ);
|
|
QF::PUBLISH(evt, me);
|
|
#endif
|
|
|
|
#if CONFIG_ENCODER
|
|
evt = new Evt(ENCODER_STOP_REQ);
|
|
QF::PUBLISH(evt, me);
|
|
#endif
|
|
|
|
status = Q_HANDLED();
|
|
break;
|
|
}
|
|
case Q_EXIT_SIG: {
|
|
LOG_EVENT(e);
|
|
status = Q_HANDLED();
|
|
break;
|
|
}
|
|
|
|
case ADC_STOP_CFM:
|
|
case DAC_STOP_CFM:
|
|
case TIMER_STOP_CFM:
|
|
case SERCOM_STOP_CFM:
|
|
case I2C_SLAVE_STOP_CFM:
|
|
case SPI_SLAVE_STOP_CFM:
|
|
case INTERRUPT_STOP_CFM:
|
|
case DAP_STOP_CFM:
|
|
case NEOPIXEL_STOP_CFM:
|
|
case USB_STOP_CFM:
|
|
case TOUCH_STOP_CFM:
|
|
case KEYPAD_STOP_CFM:
|
|
case ENCODER_STOP_CFM:
|
|
case DELEGATE_STOP_CFM: {
|
|
LOG_EVENT(e);
|
|
me->HandleCfm(ERROR_EVT_CAST(*e), CONFIG_NUM_AO);
|
|
status = Q_HANDLED();
|
|
break;
|
|
}
|
|
|
|
case SYSTEM_FAIL:
|
|
Q_ASSERT(0);
|
|
status = Q_HANDLED();
|
|
break;
|
|
case SYSTEM_DONE: {
|
|
LOG_EVENT(e);
|
|
Evt *evt = new SystemStartReq(me->m_nextSequence++);
|
|
me->postLIFO(evt);
|
|
status = Q_TRAN(&System::Stopped);
|
|
break;
|
|
}
|
|
default: {
|
|
status = Q_SUPER(&System::Root);
|
|
break;
|
|
}
|
|
}
|
|
return status;
|
|
}
|
|
|
|
QState System::Starting(System * const me, QEvt const * const e) {
|
|
QState status;
|
|
switch (e->sig) {
|
|
case Q_ENTRY_SIG: {
|
|
LOG_EVENT(e);
|
|
me->m_cfmCount = 0;
|
|
|
|
//start objects
|
|
Evt *evt = new Evt(DELEGATE_START_REQ);
|
|
QF::PUBLISH(evt, me);
|
|
|
|
#if CONFIG_INTERRUPT
|
|
evt = new Evt(INTERRUPT_START_REQ);
|
|
QF::PUBLISH(evt, me);
|
|
#endif
|
|
|
|
#if CONFIG_I2C_SLAVE
|
|
evt = new I2CSlaveStartReq(&me->m_I2CSlaveOutFifo, &me->m_I2CSlaveInFifo);
|
|
QF::PUBLISH(evt, me);
|
|
#endif
|
|
|
|
#if CONFIG_SPI_SLAVE
|
|
evt = new SPISlaveStartReq(&me->m_SPISlaveOutFifo, &me->m_SPISlaveInFifo);
|
|
QF::PUBLISH(evt, me);
|
|
#endif
|
|
|
|
#if CONFIG_DAC
|
|
evt = new Evt(DAC_START_REQ);
|
|
QF::PUBLISH(evt, me);
|
|
#endif
|
|
|
|
#if CONFIG_ADC
|
|
evt = new Evt(ADC_START_REQ);
|
|
QF::PUBLISH(evt, me);
|
|
#endif
|
|
|
|
#if CONFIG_TIMER
|
|
evt = new Evt(TIMER_START_REQ);
|
|
QF::PUBLISH(evt, me);
|
|
#endif
|
|
|
|
//TODO: this should be broken out target specific sercoms
|
|
#if CONFIG_SERCOM0
|
|
evt = new SercomStartReq(&me->m_sercom0RxFifo);
|
|
QF::PUBLISH(evt, me);
|
|
#endif
|
|
|
|
#if CONFIG_SERCOM1
|
|
evt = new SercomStartReq(&me->m_sercom1RxFifo);
|
|
QF::PUBLISH(evt, me);
|
|
#endif
|
|
|
|
#if CONFIG_SERCOM2
|
|
evt = new SercomStartReq(&me->m_sercom2RxFifo);
|
|
QF::PUBLISH(evt, me);
|
|
#endif
|
|
|
|
#if CONFIG_SERCOM5
|
|
evt = new SercomStartReq(&me->m_sercom5RxFifo);
|
|
QF::PUBLISH(evt, me);
|
|
#endif
|
|
|
|
#if CONFIG_DAP
|
|
evt = new DAPStartReq(&me->m_DAPRxFifo);
|
|
QF::PUBLISH(evt, me);
|
|
#endif
|
|
|
|
#if CONFIG_NEOPIXEL
|
|
evt = new Evt(NEOPIXEL_START_REQ);
|
|
QF::PUBLISH(evt, me);
|
|
#endif
|
|
|
|
#if CONFIG_USB
|
|
evt = new USBStartReq(&me->m_USBOutFifo, &me->m_USBInFifo);
|
|
QF::PUBLISH(evt, me);
|
|
#endif
|
|
|
|
#if CONFIG_TOUCH
|
|
evt = new Evt(TOUCH_START_REQ);
|
|
QF::PUBLISH(evt, me);
|
|
#endif
|
|
|
|
#if CONFIG_KEYPAD
|
|
evt = new KeypadStartReq(&me->m_keypadFifo);
|
|
QF::PUBLISH(evt, me);
|
|
#endif
|
|
|
|
#if CONFIG_ENCODER
|
|
evt = new Evt(ENCODER_START_REQ);
|
|
QF::PUBLISH(evt, me);
|
|
#endif
|
|
|
|
#if CONFIG_POWER_SENSE
|
|
gpio_init(PORTA, CONFIG_POWER_SENSE_NEOPIX_PIN, 1);
|
|
uint32_t color = 0;
|
|
neopix_show_800k(CONFIG_POWER_SENSE_NEOPIX_PIN, (uint8_t *)&color, 4);
|
|
adc_init();
|
|
pinPeripheral(CONFIG_POWER_SENSE_ADC_PIN, 1);
|
|
#elif CONFIG_TEMP_SENSOR
|
|
adc_init();
|
|
#endif
|
|
|
|
#if CONFIG_TEMP_SENSOR
|
|
init_temp();
|
|
#endif
|
|
|
|
status = Q_HANDLED();
|
|
break;
|
|
}
|
|
case Q_EXIT_SIG: {
|
|
LOG_EVENT(e);
|
|
//me->m_stateTimer.disarm();
|
|
status = Q_HANDLED();
|
|
break;
|
|
}
|
|
|
|
case ADC_START_CFM:
|
|
case TIMER_START_CFM:
|
|
case DAC_START_CFM:
|
|
case SERCOM_START_CFM:
|
|
case I2C_SLAVE_START_CFM:
|
|
case SPI_SLAVE_START_CFM:
|
|
case INTERRUPT_START_CFM:
|
|
case DAP_START_CFM:
|
|
case NEOPIXEL_START_CFM:
|
|
case USB_START_CFM:
|
|
case TOUCH_START_CFM:
|
|
case KEYPAD_START_CFM:
|
|
case ENCODER_START_CFM:
|
|
case DELEGATE_START_CFM: {
|
|
LOG_EVENT(e);
|
|
me->HandleCfm(ERROR_EVT_CAST(*e), CONFIG_NUM_AO);
|
|
status = Q_HANDLED();
|
|
break;
|
|
}
|
|
|
|
case SYSTEM_FAIL:
|
|
//TODO:
|
|
|
|
case SYSTEM_DONE: {
|
|
LOG_EVENT(e);
|
|
Evt *evt = new SystemStartCfm(me->m_savedInSeq, ERROR_SUCCESS);
|
|
QF::PUBLISH(evt, me);
|
|
status = Q_TRAN(&System::Started);
|
|
break;
|
|
}
|
|
default: {
|
|
status = Q_SUPER(&System::Root);
|
|
break;
|
|
}
|
|
}
|
|
return status;
|
|
}
|
|
|
|
QState System::Started(System * const me, QEvt const * const e) {
|
|
QState status;
|
|
switch (e->sig) {
|
|
case Q_ENTRY_SIG: {
|
|
LOG_EVENT(e);
|
|
#if CONFIG_POWER_SENSE
|
|
me->m_powerSenseTimer.armX(1000, 1000);
|
|
#endif
|
|
status = Q_HANDLED();
|
|
break;
|
|
}
|
|
case Q_INIT_SIG: {
|
|
status = Q_TRAN(&System::Idle);
|
|
break;
|
|
}
|
|
case Q_EXIT_SIG: {
|
|
LOG_EVENT(e);
|
|
#if CONFIG_POWER_SENSE
|
|
me->m_powerSenseTimer.disarm();
|
|
#endif
|
|
status = Q_HANDLED();
|
|
break;
|
|
}
|
|
default: {
|
|
status = Q_SUPER(&System::Root);
|
|
break;
|
|
}
|
|
}
|
|
return status;
|
|
}
|
|
|
|
QState System::Idle(System * const me, QEvt const * const e) {
|
|
QState status;
|
|
switch (e->sig) {
|
|
case Q_ENTRY_SIG: {
|
|
LOG_EVENT(e);
|
|
|
|
#if CONFIG_POWER_SENSE
|
|
uint32_t color = 0x000004;
|
|
neopix_show_800k(CONFIG_POWER_SENSE_NEOPIX_PIN, (uint8_t *)&color, 4);
|
|
#endif
|
|
status = Q_HANDLED();
|
|
break;
|
|
}
|
|
#if CONFIG_POWER_SENSE
|
|
case SYSTEM_POWER_SENSE_TIMER: {
|
|
LOG_EVENT(e);
|
|
|
|
uint16_t vsense = adc_read(CONFIG_POWER_SENSE_ADC_CHANNEL);
|
|
|
|
if(vsense >= CONFIG_POWER_SENSE_HI_THRESH || vsense <= CONFIG_POWER_SENSE_LO_THRESH)
|
|
status = Q_TRAN(&System::Conflicted);
|
|
else
|
|
status = Q_HANDLED();
|
|
|
|
break;
|
|
}
|
|
#endif
|
|
case Q_EXIT_SIG: {
|
|
LOG_EVENT(e);
|
|
status = Q_HANDLED();
|
|
break;
|
|
}
|
|
default: {
|
|
status = Q_SUPER(&System::Started);
|
|
break;
|
|
}
|
|
}
|
|
return status;
|
|
}
|
|
|
|
QState System::Conflicted(System * const me, QEvt const * const e) {
|
|
QState status;
|
|
switch (e->sig) {
|
|
case Q_ENTRY_SIG: {
|
|
LOG_EVENT(e);
|
|
#if CONFIG_POWER_SENSE
|
|
me->m_powerSenseBlinkTimer.armX(100, 100);
|
|
#endif
|
|
status = Q_HANDLED();
|
|
break;
|
|
}
|
|
case Q_EXIT_SIG: {
|
|
LOG_EVENT(e);
|
|
#if CONFIG_POWER_SENSE
|
|
me->m_powerSenseBlinkTimer.disarm();
|
|
#endif
|
|
status = Q_HANDLED();
|
|
break;
|
|
}
|
|
#if CONFIG_POWER_SENSE
|
|
case SYSTEM_POWER_SENSE_TIMER: {
|
|
LOG_EVENT(e);
|
|
|
|
uint16_t vsense = adc_read(CONFIG_POWER_SENSE_ADC_CHANNEL);
|
|
|
|
if(vsense < CONFIG_POWER_SENSE_HI_THRESH && vsense > CONFIG_POWER_SENSE_LO_THRESH)
|
|
status = Q_TRAN(&System::Idle);
|
|
else
|
|
status = Q_HANDLED();
|
|
|
|
break;
|
|
}
|
|
case SYSTEM_POWER_SENSE_BLINK: {
|
|
LOG_EVENT(e);
|
|
me->m_powerSenseLEDState = (me->m_powerSenseLEDState + 1) % 30;
|
|
uint32_t color = 0;
|
|
if(me->m_powerSenseLEDState % 2 && me->m_powerSenseLEDState < 12){
|
|
color = 0x002000;
|
|
}
|
|
neopix_show_800k(CONFIG_POWER_SENSE_NEOPIX_PIN, (uint8_t *)&color, 4);
|
|
status = Q_HANDLED();
|
|
break;
|
|
}
|
|
#endif
|
|
default: {
|
|
status = Q_SUPER(&System::Started);
|
|
break;
|
|
}
|
|
}
|
|
return status;
|
|
}
|
|
|
|
void System::HandleCfm(ErrorEvt const &e, uint8_t expectedCnt) {
|
|
if (e.GetError() == ERROR_SUCCESS) {
|
|
// TODO - Compare seqeuence number.
|
|
if(++m_cfmCount == expectedCnt) {
|
|
Evt *evt = new Evt(SYSTEM_DONE);
|
|
postLIFO(evt);
|
|
}
|
|
} else {
|
|
Evt *evt = new SystemFail(e.GetError(), e.GetReason());
|
|
postLIFO(evt);
|
|
}
|
|
}
|
|
|